android6.0 power显示(亮度等)深入分析(二)DisplayManagerService

来源:互联网 发布:swmm模型软件 编辑:程序博客网 时间:2024/04/28 17:19

http://blog.csdn.net/kc58236582/article/details/51584381


上篇博客我们分析了,PowerManagerService和DisplayPowerController这两个类,我也提到了和android5.1的变化,把背光这块放到了DisplayManagerService中了,之前这块没有分析过,今天分析下DisplayManagerService和背光的关系。

看了DisplayManagerService的注释,发现现在所以的显示设备都放在DisplayManagerService管理,wifiDisplay,defaultDisplay(背光)。


一、DisplayManagerService注册localDisplay的适配层

我们先来看构造函数:

[cpp] view plain copy
 在CODE上查看代码片派生到我的代码片
  1. public DisplayManagerService(Context context) {  
  2.     super(context);  
  3.     mContext = context;  
  4.     mHandler = new DisplayManagerHandler(DisplayThread.get().getLooper());//消息处理  
  5.     mUiHandler = UiThread.getHandler();  
  6.     mDisplayAdapterListener = new DisplayAdapterListener();//display适配层监视器  
  7.     mSingleDisplayDemoMode = SystemProperties.getBoolean("persist.demo.singledisplay"false);  
  8.   
  9.     PowerManager pm = (PowerManager) mContext.getSystemService(Context.POWER_SERVICE);  
  10.     mGlobalDisplayBrightness = pm.getDefaultScreenBrightnessSetting();//成员变量屏幕亮度  
  11. }  

我们再来看onStart函数,publish了一个BinderService和LocalService,还有发送了一个消息。

[cpp] view plain copy
 在CODE上查看代码片派生到我的代码片
  1. @Override  
  2. public void onStart() {  
  3.     mHandler.sendEmptyMessage(MSG_REGISTER_DEFAULT_DISPLAY_ADAPTER);  
  4.   
  5.     publishBinderService(Context.DISPLAY_SERVICE, new BinderService(),  
  6.             true /*allowIsolated*/);  
  7.     publishLocalService(DisplayManagerInternal.classnew LocalService());  
  8. }  
我们看消息处理,就是调用了registerDefaultDisplayAdapter函数:

[cpp] view plain copy
 在CODE上查看代码片派生到我的代码片
  1. @Override  
  2. public void handleMessage(Message msg) {  
  3.     switch (msg.what) {  
  4.         case MSG_REGISTER_DEFAULT_DISPLAY_ADAPTER:  
  5.             registerDefaultDisplayAdapter();  
  6.             break;  

registerDefaultDisplayAdapter函数

[cpp] view plain copy
 在CODE上查看代码片派生到我的代码片
  1. private void registerDefaultDisplayAdapter() {  
  2.     // Register default display adapter.  
  3.     synchronized (mSyncRoot) {  
  4.         registerDisplayAdapterLocked(new LocalDisplayAdapter(  
  5.                 mSyncRoot, mContext, mHandler, mDisplayAdapterListener));  
  6.     }  
  7. }  

再来看看registerDisplayAdapterLocked

[cpp] view plain copy
 在CODE上查看代码片派生到我的代码片
  1. private void registerDisplayAdapterLocked(DisplayAdapter adapter) {  
  2.     mDisplayAdapters.add(adapter);  
  3.     adapter.registerLocked();  
  4. }  

这里就是register了DefaultDisplay的适配层,就是和背光相关的。在新建LocalDisplayAdapter的时候我们把mDisplayAdapterListener传过去了。


二、LocalDisplayAdapter & LocalDisplayDevice

LocalDisplayAdapter构造函数调用了父类的,而父类也就是保存了变量

[cpp] view plain copy
 在CODE上查看代码片派生到我的代码片
  1. public LocalDisplayAdapter(DisplayManagerService.SyncRoot syncRoot,  
  2.         Context context, Handler handler, Listener listener) {  
  3.     super(syncRoot, context, handler, listener, TAG);  
  4. }  

上面又紧跟着调用了registerLocked函数

[cpp] view plain copy
 在CODE上查看代码片派生到我的代码片
  1. public void registerLocked() {  
  2.     super.registerLocked();  
  3.   
  4.     mHotplugReceiver = new HotplugDisplayEventReceiver(getHandler().getLooper());  
  5.   
  6.     for (int builtInDisplayId : BUILT_IN_DISPLAY_IDS_TO_SCAN) {  
  7.         tryConnectDisplayLocked(builtInDisplayId);  
  8.     }  
  9. }  

tryConnectDisplayLocked函数,先是看传入的builtInDisplayId是否支持,一个是main,一个是hdmi的。

[cpp] view plain copy
 在CODE上查看代码片派生到我的代码片
  1. private void tryConnectDisplayLocked(int builtInDisplayId) {  
  2.     IBinder displayToken = SurfaceControl.getBuiltInDisplay(builtInDisplayId);  
  3.     if (displayToken != null) {  
  4.         SurfaceControl.PhysicalDisplayInfo[] configs =  
  5.                 SurfaceControl.getDisplayConfigs(displayToken);  
  6.         if (configs == null) {  
  7.             // There are no valid configs for this device, so we can't use it  
  8.             Slog.w(TAG, "No valid configs found for display device " +  
  9.                     builtInDisplayId);  
  10.             return;  
  11.         }  
  12.         int activeConfig = SurfaceControl.getActiveConfig(displayToken);  
  13.         if (activeConfig < 0) {  
  14.             // There is no active config, and for now we don't have the  
  15.             // policy to set one.  
  16.             Slog.w(TAG, "No active config found for display device " +  
  17.                     builtInDisplayId);  
  18.             return;  
  19.         }  
  20.         LocalDisplayDevice device = mDevices.get(builtInDisplayId);  
  21.         if (device == null) {  
  22.             // Display was added.  
  23.             device = new LocalDisplayDevice(displayToken, builtInDisplayId,  
  24.                     configs, activeConfig);  
  25.             mDevices.put(builtInDisplayId, device);  
  26.             sendDisplayDeviceEventLocked(device, DISPLAY_DEVICE_EVENT_ADDED);  
  27.         } else if (device.updatePhysicalDisplayInfoLocked(configs, activeConfig)) {  
  28.             // Display properties changed.  
  29.             sendDisplayDeviceEventLocked(device, DISPLAY_DEVICE_EVENT_CHANGED);  
  30.         }  
  31.     } else {  
  32.         // The display is no longer available. Ignore the attempt to add it.  
  33.         // If it was connected but has already been disconnected, we'll get a  
  34.         // disconnect event that will remove it from mDevices.  
  35.     }  
  36. }  

然后再去查找这个LocalDisplayDevice,如果是找到了需要更新下configs,没找到需要新建一个LocalDisplayDevice。最后都调用了sendDisplayDeviceEventLocked函数。

我们再来看LocalDisplayDevice,如果传入的是BUILT_IN_DISPLAY_ID_MAIN就是背光的,我们获取背光的Light,保存在mBackLight变量。

[cpp] view plain copy
 在CODE上查看代码片派生到我的代码片
  1. public LocalDisplayDevice(IBinder displayToken, int builtInDisplayId,  
  2.         SurfaceControl.PhysicalDisplayInfo[] physicalDisplayInfos, int activeDisplayInfo) {  
  3.     super(LocalDisplayAdapter.this, displayToken, UNIQUE_ID_PREFIX + builtInDisplayId);  
  4.     mBuiltInDisplayId = builtInDisplayId;  
  5.     updatePhysicalDisplayInfoLocked(physicalDisplayInfos, activeDisplayInfo);  
  6.     if (mBuiltInDisplayId == SurfaceControl.BUILT_IN_DISPLAY_ID_MAIN) {  
  7.         LightsManager lights = LocalServices.getService(LightsManager.class);  
  8.         mBacklight = lights.getLight(LightsManager.LIGHT_ID_BACKLIGHT);  
  9.     } else {  
  10.         mBacklight = null;  
  11.     }  
  12. }  

然后上面函数调用了sendDisplayDeviceEventLocked函数,就是调用了传入的参数DisplayAdapterListener

[cpp] view plain copy
 在CODE上查看代码片派生到我的代码片
  1. protected final void sendDisplayDeviceEventLocked(  
  2.         final DisplayDevice device, final int event) {  
  3.     mHandler.post(new Runnable() {  
  4.         @Override  
  5.         public void run() {  
  6.             mListener.onDisplayDeviceEvent(device, event);  
  7.         }  
  8.     });  
  9. }  

如果是新建就调用了handleDisplayDeviceAdded函数,

[cpp] view plain copy
 在CODE上查看代码片派生到我的代码片
  1. private final class DisplayAdapterListener implements DisplayAdapter.Listener {  
  2.     @Override  
  3.     public void onDisplayDeviceEvent(DisplayDevice device, int event) {  
  4.         switch (event) {  
  5.             case DisplayAdapter.DISPLAY_DEVICE_EVENT_ADDED:  
  6.                 handleDisplayDeviceAdded(device);  
  7.                 break;  
  8.   
  9.             case DisplayAdapter.DISPLAY_DEVICE_EVENT_CHANGED:  
  10.                 handleDisplayDeviceChanged(device);  
  11.                 break;  
  12.   
  13.             case DisplayAdapter.DISPLAY_DEVICE_EVENT_REMOVED:  
  14.                 handleDisplayDeviceRemoved(device);  
  15.                 break;  
  16.         }  
  17.     }  
  18.   
  19.     @Override  
  20.     public void onTraversalRequested() {  
  21.         synchronized (mSyncRoot) {  
  22.             scheduleTraversalLocked(false);  
  23.         }  
  24.     }  
  25. }  

我们先来看看handleDisplayDeviceAdded,最后将device保存在了mDisplayDevices中。

[cpp] view plain copy
 在CODE上查看代码片派生到我的代码片
  1. private void handleDisplayDeviceAdded(DisplayDevice device) {  
  2.     synchronized (mSyncRoot) {  
  3.         handleDisplayDeviceAddedLocked(device);  
  4.     }  
  5. }  
  6.   
  7. private void handleDisplayDeviceAddedLocked(DisplayDevice device) {  
  8.     DisplayDeviceInfo info = device.getDisplayDeviceInfoLocked();  
  9.     if (mDisplayDevices.contains(device)) {  
  10.         Slog.w(TAG, "Attempted to add already added display device: " + info);  
  11.         return;  
  12.     }  
  13.   
  14.     Slog.i(TAG, "Display device added: " + info);  
  15.     device.mDebugLastLoggedDeviceInfo = info;  
  16.   
  17.     mDisplayDevices.add(device);  
  18.     addLogicalDisplayLocked(device);  
  19.     Runnable work = updateDisplayStateLocked(device);  
  20.     if (work != null) {  
  21.         work.run();  
  22.     }  
  23.     scheduleTraversalLocked(false);  
  24. }  


三、设置背光

现在我们在上篇博客不是说背光的调制最后是在DisplayManagerService中,是在下面函数的requestGlobalDisplayStateInternal中调用的

[cpp] view plain copy
 在CODE上查看代码片派生到我的代码片
  1. public void initPowerManagement(final DisplayPowerCallbacks callbacks, Handler handler,  
  2.         SensorManager sensorManager) {  
  3.     synchronized (mSyncRoot) {  
  4.         DisplayBlanker blanker = new DisplayBlanker() {  
  5.             @Override  
  6.             public void requestDisplayState(int state, int brightness) {  
  7.                 // The order of operations is important for legacy reasons.  
  8.                 if (state == Display.STATE_OFF) {  
  9.                     requestGlobalDisplayStateInternal(state, brightness);  
  10.                 }  
  11.   
  12.                 callbacks.onDisplayStateChange(state);  
  13.   
  14.                 if (state != Display.STATE_OFF) {  
  15.                     requestGlobalDisplayStateInternal(state, brightness);  
  16.                 }  
  17.             }  
  18.         };  
  19.         mDisplayPowerController = new DisplayPowerController(  
  20.                 mContext, callbacks, handler, sensorManager, blanker);  
  21.     }  
  22. }  

我们再来看看requestGlobalDisplayStateInternal函数:

[cpp] view plain copy
 在CODE上查看代码片派生到我的代码片
  1. private void requestGlobalDisplayStateInternal(int state, int brightness) {  
  2.     if (state == Display.STATE_UNKNOWN) {  
  3.         state = Display.STATE_ON;  
  4.     }  
  5.     if (state == Display.STATE_OFF) {  
  6.         brightness = PowerManager.BRIGHTNESS_OFF;  
  7.     } else if (brightness < 0) {  
  8.         brightness = PowerManager.BRIGHTNESS_DEFAULT;  
  9.     } else if (brightness > PowerManager.BRIGHTNESS_ON) {  
  10.         brightness = PowerManager.BRIGHTNESS_ON;  
  11.     }  
  12.   
  13.     synchronized (mTempDisplayStateWorkQueue) {  
  14.         try {  
  15.             // Update the display state within the lock.  
  16.             // Note that we do not need to schedule traversals here although it  
  17.             // may happen as a side-effect of displays changing state.  
  18.             synchronized (mSyncRoot) {  
  19.                 if (mGlobalDisplayState == state  
  20.                         && mGlobalDisplayBrightness == brightness) {  
  21.                     return// no change  
  22.                 }  
  23.   
  24.                 Trace.traceBegin(Trace.TRACE_TAG_POWER, "requestGlobalDisplayState("  
  25.                         + Display.stateToString(state)  
  26.                         + ", brightness=" + brightness + ")");  
  27.                 mGlobalDisplayState = state;  
  28.                 mGlobalDisplayBrightness = brightness;  
  29.                 applyGlobalDisplayStateLocked(mTempDisplayStateWorkQueue);  
  30.             }  
  31.   
  32.             // Setting the display power state can take hundreds of milliseconds  
  33.             // to complete so we defer the most expensive part of the work until  
  34.             // after we have exited the critical section to avoid blocking other  
  35.             // threads for a long time.  
  36.             for (int i = 0; i < mTempDisplayStateWorkQueue.size(); i++) {  
  37.                 mTempDisplayStateWorkQueue.get(i).run();  
  38.             }  
  39.             Trace.traceEnd(Trace.TRACE_TAG_POWER);  
  40.         } finally {  
  41.             mTempDisplayStateWorkQueue.clear();  
  42.         }  
  43.     }  
  44. }  

再看看applyGlobalDisplayStateLocked函数,最后遍历device调用updateDisplayStateLocked函数

[cpp] view plain copy
 在CODE上查看代码片派生到我的代码片
  1. private void applyGlobalDisplayStateLocked(List<Runnable> workQueue) {  
  2.     final int count = mDisplayDevices.size();  
  3.     for (int i = 0; i < count; i++) {  
  4.         DisplayDevice device = mDisplayDevices.get(i);  
  5.         Runnable runnable = updateDisplayStateLocked(device);  
  6.         if (runnable != null) {  
  7.             workQueue.add(runnable);  
  8.         }  
  9.     }  
  10. }  

updateDisplayStateLocked函数调用device的requestDisplayStateLocked返回是Runnable,最后放在workQueue队列中

[cpp] view plain copy
 在CODE上查看代码片派生到我的代码片
  1. private Runnable updateDisplayStateLocked(DisplayDevice device) {  
  2.     // Blank or unblank the display immediately to match the state requested  
  3.     // by the display power controller (if known).  
  4.     DisplayDeviceInfo info = device.getDisplayDeviceInfoLocked();  
  5.     if ((info.flags & DisplayDeviceInfo.FLAG_NEVER_BLANK) == 0) {  
  6.         return device.requestDisplayStateLocked(mGlobalDisplayState, mGlobalDisplayBrightness);  
  7.     }  
  8.     return null;  
  9. }  

我们再来看看LocalDisplayDevice的requestDisplayStateLocked函数

[cpp] view plain copy
 在CODE上查看代码片派生到我的代码片
  1. public Runnable requestDisplayStateLocked(final int state, final int brightness) {  
  2.      // Assume that the brightness is off if the display is being turned off.  
  3.      assert state != Display.STATE_OFF || brightness == PowerManager.BRIGHTNESS_OFF;  
  4.   
  5.      final boolean stateChanged = (mState != state);  
  6.      final boolean brightnessChanged = (mBrightness != brightness) && mBacklight != null;  
  7.      if (stateChanged || brightnessChanged) {  
  8.          final int displayId = mBuiltInDisplayId;  
  9.          final IBinder token = getDisplayTokenLocked();  
  10.          final int oldState = mState;  
  11.   
  12.          if (stateChanged) {  
  13.              mState = state;// 状态  
  14.              updateDeviceInfoLocked();  
  15.          }  
  16.   
  17.          if (brightnessChanged) {  
  18.              mBrightness = brightness;//保存亮度  
  19.          }  
  20.   
  21.          // Defer actually setting the display state until after we have exited  
  22.          // the critical section since it can take hundreds of milliseconds  
  23.          // to complete.  
  24.          return new Runnable() {  
  25.              @Override  
  26.              public void run() {  
  27.                  // Exit a suspended state before making any changes.  
  28.                  int currentState = oldState;  
  29.                  if (Display.isSuspendedState(oldState)  
  30.                          || oldState == Display.STATE_UNKNOWN) {  
  31.                      if (!Display.isSuspendedState(state)) {  
  32.                          setDisplayState(state);  
  33.                          currentState = state;  
  34.                      } else if (state == Display.STATE_DOZE_SUSPEND  
  35.                              || oldState == Display.STATE_DOZE_SUSPEND) {  
  36.                          setDisplayState(Display.STATE_DOZE);  
  37.                          currentState = Display.STATE_DOZE;  
  38.                      } else {  
  39.                          return// old state and new state is off  
  40.                      }  
  41.                  }  
  42.   
  43.                  // Apply brightness changes given that we are in a non-suspended state.  
  44.                  if (brightnessChanged) {  
  45.                      setDisplayBrightness(brightness);//设置亮度  
  46.                  }  
  47.   
  48.                  // Enter the final desired state, possibly suspended.  
  49.                  if (state != currentState) {  
  50.                      setDisplayState(state);  
  51.                  }  
  52.              }  
  53.   
  54.              private void setDisplayState(int state) {  
  55.                  if (DEBUG) {  
  56.                      Slog.d(TAG, "setDisplayState("  
  57.                              + "id=" + displayId  
  58.                              + ", state=" + Display.stateToString(state) + ")");  
  59.                  }  
  60.   
  61.                  Trace.traceBegin(Trace.TRACE_TAG_POWER, "setDisplayState("  
  62.                          + "id=" + displayId  
  63.                          + ", state=" + Display.stateToString(state) + ")");  
  64.                  try {  
  65.                      final int mode = getPowerModeForState(state);  
  66.                      SurfaceControl.setDisplayPowerMode(token, mode);  
  67.                  } finally {  
  68.                      Trace.traceEnd(Trace.TRACE_TAG_POWER);  
  69.                  }  
  70.              }  
  71.   
  72.              private void setDisplayBrightness(int brightness) {  
  73.                  if (DEBUG) {  
  74.                      Slog.d(TAG, "setDisplayBrightness("  
  75.                              + "id=" + displayId + ", brightness=" + brightness + ")");  
  76.                  }  
  77.   
  78.                  Trace.traceBegin(Trace.TRACE_TAG_POWER, "setDisplayBrightness("  
  79.                          + "id=" + displayId + ", brightness=" + brightness + ")");  
  80.                  try {  
  81.                      mBacklight.setBrightness(brightness);//真正的设置背光  
  82.                  } finally {  
  83.                      Trace.traceEnd(Trace.TRACE_TAG_POWER);  
  84.                  }  
  85.              }  
  86.          };  
  87.      }  
  88.      return null;  
  89.  }  

上面函数返回一个Runnable放在workQueue,在Runnable 中会调用mBacklight.setBrightness设置背光。

之前是将Runnable接口都放在了mTempDisplayStateWorkQueue中,然后遍历调用了run函数。最后就调用到了LocalDisplayDevice的Runnable接口中设置背光了。

[cpp] view plain copy
 在CODE上查看代码片派生到我的代码片
  1. synchronized (mSyncRoot) {  
  2.     if (mGlobalDisplayState == state  
  3.             && mGlobalDisplayBrightness == brightness) {  
  4.         return// no change  
  5.     }  
  6.   
  7.     Trace.traceBegin(Trace.TRACE_TAG_POWER, "requestGlobalDisplayState("  
  8.             + Display.stateToString(state)  
  9.             + ", brightness=" + brightness + ")");  
  10.     mGlobalDisplayState = state;  
  11.     mGlobalDisplayBrightness = brightness;  
  12.     applyGlobalDisplayStateLocked(mTempDisplayStateWorkQueue);  
  13. }  
  14.   
  15. // Setting the display power state can take hundreds of milliseconds  
  16. // to complete so we defer the most expensive part of the work until  
  17. // after we have exited the critical section to avoid blocking other  
  18. // threads for a long time.  
  19. for (int i = 0; i < mTempDisplayStateWorkQueue.size(); i++) {  
  20.     mTempDisplayStateWorkQueue.get(i).run();  
  21. }  



四、背光hal层

我们先来看看LightsService

[cpp] view plain copy
 在CODE上查看代码片派生到我的代码片
  1. public class LightsService extends SystemService {  
  2.     static final String TAG = "LightsService";  
  3.     static final boolean DEBUG = false;  
  4.   
  5.     final LightImpl mLights[] = new LightImpl[LightsManager.LIGHT_ID_COUNT];  
  6.   
  7.     private final class LightImpl extends Light {  
  8.   
  9.         private LightImpl(int id) {  
  10.             mId = id;  
  11.         }  
  12.   
  13.         @Override  
  14.         public void setBrightness(int brightness) {  
  15.             setBrightness(brightness, BRIGHTNESS_MODE_USER);  
  16.         }  
  17.   
  18.         @Override  
  19.         public void setBrightness(int brightness, int brightnessMode) {  
  20.             synchronized (this) {  
  21.                 int color = brightness & 0x000000ff;  
  22.                 color = 0xff000000 | (color << 16) | (color << 8) | color;  
  23.                 setLightLocked(color, LIGHT_FLASH_NONE, 0, 0, brightnessMode);  
  24.             }  
  25.         }  

setLightLocked中最后调用了setLight_native函数。

[cpp] view plain copy
 在CODE上查看代码片派生到我的代码片
  1. private void setLightLocked(int color, int mode, int onMS, int offMS, int brightnessMode) {  
  2.     if (color != mColor || mode != mMode || onMS != mOnMS || offMS != mOffMS) {  
  3.         if (DEBUG) Slog.v(TAG, "setLight #" + mId + ": color=#"  
  4.                 + Integer.toHexString(color));  
  5.         mColor = color;  
  6.         mMode = mode;  
  7.         mOnMS = onMS;  
  8.         mOffMS = offMS;  
  9.         Trace.traceBegin(Trace.TRACE_TAG_POWER, "setLight(" + mId + ", 0x"  
  10.                 + Integer.toHexString(color) + ")");  
  11.         try {  
  12.             setLight_native(mNativePointer, mId, color, mode, onMS, offMS, brightnessMode);  
  13.         } finally {  
  14.             Trace.traceEnd(Trace.TRACE_TAG_POWER);  
  15.         }  
  16.     }  
  17. }  

setLight_native函数如下,其主要也是依赖上面传下来的ptr,作为devices的指针。

[cpp] view plain copy
 在CODE上查看代码片派生到我的代码片
  1. static void setLight_native(JNIEnv* /* env */, jobject /* clazz */, jlong ptr,  
  2.         jint light, jint colorARGB, jint flashMode, jint onMS, jint offMS, jint brightnessMode)  
  3. {  
  4.     Devices* devices = (Devices*)ptr;  
  5.     light_state_t state;  
  6.   
  7.     if (light < 0 || light >= LIGHT_COUNT || devices->lights[light] == NULL) {  
  8.         return ;  
  9.     }  
  10.   
  11.     memset(&state, 0, sizeof(light_state_t));  
  12.     state.color = colorARGB;  
  13.     state.flashMode = flashMode;  
  14.     state.flashOnMS = onMS;  
  15.     state.flashOffMS = offMS;  
  16.     state.brightnessMode = brightnessMode;  
  17.   
  18.     {  
  19.         ALOGD_IF_SLOW(50, "Excessive delay setting light");  
  20.         devices->lights[light]->set_light(devices->lights[light], &state);  
  21.     }  
  22. }  

而mNativePointer也是调用了init_native函数

[cpp] view plain copy
 在CODE上查看代码片派生到我的代码片
  1. static jlong init_native(JNIEnv* /* env */, jobject /* clazz */)  
  2. {  
  3.     int err;  
  4.     hw_module_t* module;  
  5.     Devices* devices;  
  6.       
  7.     devices = (Devices*)malloc(sizeof(Devices));  
  8.   
  9.     err = hw_get_module(LIGHTS_HARDWARE_MODULE_ID, (hw_module_t const**)&module);  
  10.     if (err == 0) {  
  11.         devices->lights[LIGHT_INDEX_BACKLIGHT]  
  12.                 = get_device(module, LIGHT_ID_BACKLIGHT);  
  13.         devices->lights[LIGHT_INDEX_KEYBOARD]  
  14.                 = get_device(module, LIGHT_ID_KEYBOARD);  
  15.         devices->lights[LIGHT_INDEX_BUTTONS]  
  16.                 = get_device(module, LIGHT_ID_BUTTONS);  
  17.         devices->lights[LIGHT_INDEX_BATTERY]  
  18.                 = get_device(module, LIGHT_ID_BATTERY);  
  19.         devices->lights[LIGHT_INDEX_NOTIFICATIONS]  
  20.                 = get_device(module, LIGHT_ID_NOTIFICATIONS);  
  21.         devices->lights[LIGHT_INDEX_ATTENTION]  
  22.                 = get_device(module, LIGHT_ID_ATTENTION);  
  23.         devices->lights[LIGHT_INDEX_BLUETOOTH]  
  24.                 = get_device(module, LIGHT_ID_BLUETOOTH);  
  25.         devices->lights[LIGHT_INDEX_WIFI]  
  26.                 = get_device(module, LIGHT_ID_WIFI);  
  27.     } else {  
  28.         memset(devices, 0, sizeof(Devices));  
  29.     }  
  30.   
  31.     return (jlong)devices;  
  32. }  

这就到驱动了,最终到hardware目录下有个lights.c文件有下面函数

[cpp] view plain copy
 在CODE上查看代码片派生到我的代码片
  1. static int open_lights(const struct hw_module_t *module, char const *name,  
  2.                         struct hw_device_t **device)  
  3. {  
  4.     int (*set_light)(struct light_device_t *dev,  
  5.         struct light_state_t const *state);  
  6.   
  7.     if (0 == strcmp(LIGHT_ID_BACKLIGHT, name))  
  8.         set_light = set_light_backlight;  
  9.     else if (0 == strcmp(LIGHT_ID_NOTIFICATIONS, name))  
  10.         set_light = set_light_leds_notifications;  
  11.     else if (0 == strcmp(LIGHT_ID_ATTENTION, name))  
  12.         set_light = set_light_leds_attention;  
  13.     else if (0 == strcmp(LIGHT_ID_BATTERY,name))  
  14.         set_light = set_light_leds_battery;  
  15.     else if (0 == strcmp(LIGHT_ID_BUTTONS,name))  
  16.         set_light = set_light_keyboard;  
  17.     else  
  18.         return -EINVAL;  
  19.   
  20.     pthread_once(&g_init, init_g_lock);  
  21.   
  22.     struct light_device_t *dev = malloc(sizeof(struct light_device_t));  
  23.     memset(dev, 0, sizeof(*dev));  
  24.   
  25.     dev->common.tag = HARDWARE_DEVICE_TAG;  
  26.     dev->common.version = 0;  
  27.     dev->common.module = (struct hw_module_t *)module;  
  28.     dev->common.close = (int (*)(struct hw_device_t *))close_lights;  
  29.     dev->set_light = set_light;  
  30.   
  31.     *device = (struct hw_device_t *)dev;  
  32.   
  33.     return 0;  
  34. }  
下面我们再来看set_light_backlight函数:

[cpp] view plain copy
 在CODE上查看代码片派生到我的代码片
  1. static int  
  2. set_light_backlight(struct light_device_t* dev,  
  3.         struct light_state_t const* state)  
  4. {  
  5.     int err = 0;  
  6.     int brightness = rgb_to_brightness(state);  
  7.     if(!dev) {  
  8.         return -1;  
  9.     }  
  10.     pthread_mutex_lock(&g_lock);  
  11.     err = write_int(LCD_FILE, brightness);  
  12.     pthread_mutex_unlock(&g_lock);  
  13.     return err;  
  14. }  

其中

[cpp] view plain copy
 在CODE上查看代码片派生到我的代码片
  1. char const*const LCD_FILE  
  2.         = "/sys/class/leds/lcd-backlight/brightness";  

这样最后设置背光就是往这个节点里面写值,我们可以看下这个节点值。

[html] view plain copy
 在CODE上查看代码片派生到我的代码片
  1. root@lte26007:/sys/class/leds/lcd-backlight # cat brightness  
  2. 102  



五、总结

这篇博客我们主要分析了,DisplayMangerService是如何设置背光节点的,以及一些hal层的代码。


0 0
原创粉丝点击