Android 6.0 PowerManagerService 一
来源:互联网 发布:java实验fan 编辑:程序博客网 时间:2024/05/16 19:01
SystemServer.java
startBootstrapServices 函数中
mPowerManagerService = mSystemServiceManager.startService(PowerManagerService.class);
SystemServer创建完PowerManagerService后,继续调用SystemReady方法,再做一些初始化的工作
mPowerManagerService.systemReady(mActivityManagerService.getAppOpsService());
PowerManagerService.java
PowerManagerService构造函数
public PowerManagerService(Context context) { super(context); mContext = context; mHandlerThread = new ServiceThread(TAG, Process.THREAD_PRIORITY_DISPLAY, false /*allowIo*/); mHandlerThread.start(); <span><span class="comment">//创建Handler,注意mHandlerThread.getLooper(),每一个线程都只有一个looper,这样消息的处理会放在这个线程中 mHandler = new PowerManagerHandler(mHandlerThread.getLooper()); synchronized (mLock) { mWakeLockSuspendBlocker = createSuspendBlockerLocked("PowerManagerService.WakeLocks");//通过JNI调用底层的wakelock函数 mDisplaySuspendBlocker = createSuspendBlockerLocked("PowerManagerService.Display"); mDisplaySuspendBlocker.acquire();//持锁防止cpu睡眠 mHoldingDisplaySuspendBlocker = true; mHalAutoSuspendModeEnabled = false; mHalInteractiveModeEnabled = true; mWakefulness = WAKEFULNESS_AWAKE;//系统正常运行状态 nativeInit(); nativeSetAutoSuspend(false); nativeSetInteractive(true); nativeSetFeature(POWER_FEATURE_DOUBLE_TAP_TO_WAKE, 0); } }
systemReady
public void systemReady(IAppOpsService appOps) { synchronized (mLock) { mSystemReady = true; mAppOps = appOps; mDreamManager = getLocalService(DreamManagerInternal.class); mDisplayManagerInternal = getLocalService(DisplayManagerInternal.class); mPolicy = getLocalService(WindowManagerPolicy.class); mBatteryManagerInternal = getLocalService(BatteryManagerInternal.class); PowerManager pm = (PowerManager) mContext.getSystemService(Context.POWER_SERVICE); mScreenBrightnessSettingMinimum = pm.getMinimumScreenBrightnessSetting(); mScreenBrightnessSettingMaximum = pm.getMaximumScreenBrightnessSetting(); mScreenBrightnessSettingDefault = pm.getDefaultScreenBrightnessSetting(); SensorManager sensorManager = new SystemSensorManager(mContext, mHandler.getLooper()); // The notifier runs on the system server's main looper so as not to interfere // with the animations and other critical functions of the power manager. mBatteryStats = BatteryStatsService.getService(); mNotifier = new Notifier(Looper.getMainLooper(), mContext, mBatteryStats, mAppOps, createSuspendBlockerLocked("PowerManagerService.Broadcasts"), mPolicy); mWirelessChargerDetector = new WirelessChargerDetector(sensorManager, createSuspendBlockerLocked("PowerManagerService.WirelessChargerDetector"), mHandler); mSettingsObserver = new SettingsObserver(mHandler); mLightsManager = getLocalService(LightsManager.class); mAttentionLight = mLightsManager.getLight(LightsManager.LIGHT_ID_ATTENTION); // Initialize display power management. mDisplayManagerInternal.initPowerManagement( mDisplayPowerCallbacks, mHandler, sensorManager); // Register for broadcasts from other components of the system. IntentFilter filter = new IntentFilter(); filter.addAction(Intent.ACTION_BATTERY_CHANGED); filter.setPriority(IntentFilter.SYSTEM_HIGH_PRIORITY); mContext.registerReceiver(new BatteryReceiver(), filter, null, mHandler); filter = new IntentFilter(); filter.addAction(Intent.ACTION_DREAMING_STARTED); filter.addAction(Intent.ACTION_DREAMING_STOPPED); mContext.registerReceiver(new DreamReceiver(), filter, null, mHandler); filter = new IntentFilter(); filter.addAction(Intent.ACTION_USER_SWITCHED); mContext.registerReceiver(new UserSwitchedReceiver(), filter, null, mHandler); filter = new IntentFilter(); filter.addAction(Intent.ACTION_DOCK_EVENT); mContext.registerReceiver(new DockReceiver(), filter, null, mHandler); // Register for settings changes. final ContentResolver resolver = mContext.getContentResolver(); resolver.registerContentObserver(Settings.Secure.getUriFor( Settings.Secure.SCREENSAVER_ENABLED), false, mSettingsObserver, UserHandle.USER_ALL); resolver.registerContentObserver(Settings.Secure.getUriFor( Settings.Secure.SCREENSAVER_ACTIVATE_ON_SLEEP), false, mSettingsObserver, UserHandle.USER_ALL); resolver.registerContentObserver(Settings.Secure.getUriFor( Settings.Secure.SCREENSAVER_ACTIVATE_ON_DOCK), false, mSettingsObserver, UserHandle.USER_ALL); resolver.registerContentObserver(Settings.System.getUriFor( Settings.System.SCREEN_OFF_TIMEOUT), false, mSettingsObserver, UserHandle.USER_ALL); resolver.registerContentObserver(Settings.Secure.getUriFor( Settings.Secure.SLEEP_TIMEOUT), false, mSettingsObserver, UserHandle.USER_ALL); resolver.registerContentObserver(Settings.Global.getUriFor( Settings.Global.STAY_ON_WHILE_PLUGGED_IN), false, mSettingsObserver, UserHandle.USER_ALL); resolver.registerContentObserver(Settings.System.getUriFor( Settings.System.SCREEN_BRIGHTNESS), false, mSettingsObserver, UserHandle.USER_ALL); resolver.registerContentObserver(Settings.System.getUriFor( Settings.System.SCREEN_BRIGHTNESS_MODE), false, mSettingsObserver, UserHandle.USER_ALL); resolver.registerContentObserver(Settings.System.getUriFor( Settings.System.SCREEN_AUTO_BRIGHTNESS_ADJ), false, mSettingsObserver, UserHandle.USER_ALL); resolver.registerContentObserver(Settings.Global.getUriFor( Settings.Global.LOW_POWER_MODE), false, mSettingsObserver, UserHandle.USER_ALL); resolver.registerContentObserver(Settings.Global.getUriFor( Settings.Global.LOW_POWER_MODE_TRIGGER_LEVEL), false, mSettingsObserver, UserHandle.USER_ALL); resolver.registerContentObserver(Settings.Global.getUriFor( Settings.Global.THEATER_MODE_ON), false, mSettingsObserver, UserHandle.USER_ALL); resolver.registerContentObserver(Settings.Secure.getUriFor( Settings.Secure.DOUBLE_TAP_TO_WAKE), false, mSettingsObserver, UserHandle.USER_ALL); // Go. readConfigurationLocked(); updateSettingsLocked(); mDirty |= DIRTY_BATTERY_STATE; updatePowerStateLocked(); } }
从在android5.1.1中,service一般都会继承一个虚类SystemService,在其中定义了两个接口onStart和onBootPhase,分别是PowerManagerService启动的时候会调用,而onBootPhase会在系统启动的各个阶段来调用,下面我们分别来看看在powerManagerService中这两个函数的实现:
@Override public void onStart() { publishBinderService(Context.POWER_SERVICE, new BinderService());//publish service publishLocalService(PowerManagerInternal.class, new LocalService());//publish local service Watchdog.getInstance().addMonitor(this); Watchdog.getInstance().addThread(mHandler); }
具体的WakeLock有几种如下:
PARTIAL_WAKE_LOCK:只保持CPU运行,屏幕和键盘光关闭。
FULL_WAKE_LOCK:都不关闭
SCREEN_BRIGHT_WAKE_LOCK:屏幕背光不关闭,键盘光关闭
SCREEN_DIM_WAKE_LOCK:屏幕背光不关闭,键盘光关闭。但是屏幕背光可以变暗
PROXIMITY_SCREEN_OFF_WAKE_LOCK当持有这种类型wakelock,当距离传感器被遮挡,屏幕将被关闭。打电话时用这个功能
acquieWakeLock
在PowerManagerService中的acquieWakeLock先要检查权限然后调用acquireWakeLockInternal接口
@Override // Binder call public void acquireWakeLock(IBinder lock, int flags, String tag, String packageName, WorkSource ws, String historyTag) { if (lock == null) { throw new IllegalArgumentException("lock must not be null"); } if (packageName == null) { throw new IllegalArgumentException("packageName must not be null"); } PowerManager.validateWakeLockParameters(flags, tag); mContext.enforceCallingOrSelfPermission(android.Manifest.permission.WAKE_LOCK, null); if ((flags & PowerManager.DOZE_WAKE_LOCK) != 0) { mContext.enforceCallingOrSelfPermission( android.Manifest.permission.DEVICE_POWER, null); } if (ws != null && ws.size() != 0) { mContext.enforceCallingOrSelfPermission( android.Manifest.permission.UPDATE_DEVICE_STATS, null); } else { ws = null; } final int uid = Binder.getCallingUid(); final int pid = Binder.getCallingPid(); final long ident = Binder.clearCallingIdentity(); try { acquireWakeLockInternal(lock, flags, tag, packageName, ws, historyTag, uid, pid); } finally { Binder.restoreCallingIdentity(ident); } }
acquireWakeLockInternal
private void acquireWakeLockInternal(IBinder lock, int flags, String tag, String packageName, WorkSource ws, String historyTag, int uid, int pid) { synchronized (mLock) { if (DEBUG_SPEW) { Slog.d(TAG, "acquireWakeLockInternal: lock=" + Objects.hashCode(lock) + ", flags=0x" + Integer.toHexString(flags) + ", tag=\"" + tag + "\", ws=" + ws + ", uid=" + uid + ", pid=" + pid); } WakeLock wakeLock; int index = findWakeLockIndexLocked(lock); boolean notifyAcquire; if (index >= 0) { wakeLock = mWakeLocks.get(index); if (!wakeLock.hasSameProperties(flags, tag, ws, uid, pid)) { // Update existing wake lock. This shouldn't happen but is harmless. notifyWakeLockChangingLocked(wakeLock, flags, tag, packageName, uid, pid, ws, historyTag); wakeLock.updateProperties(flags, tag, packageName, ws, historyTag, uid, pid); } notifyAcquire = false; } else { wakeLock = new WakeLock(lock, flags, tag, packageName, ws, historyTag, uid, pid); try { lock.linkToDeath(wakeLock, 0); } catch (RemoteException ex) { throw new IllegalArgumentException("Wake lock is already dead."); } mWakeLocks.add(wakeLock); setWakeLockDisabledStateLocked(wakeLock); notifyAcquire = true; } applyWakeLockFlagsOnAcquireLocked(wakeLock, uid);//看是否需要点亮屏幕 mDirty |= DIRTY_WAKE_LOCKS;//PowermanagerService用来记录各个状态变化的一个标志位 updatePowerStateLocked();//更新电源状态 if (notifyAcquire) { // This needs to be done last so we are sure we have acquired the // kernel wake lock. Otherwise we have a race where the system may // go to sleep between the time we start the accounting in battery // stats and when we actually get around to telling the kernel to // stay awake. notifyWakeLockAcquiredLocked(wakeLock); } } }
整个PowermanagerService都是靠一个mDirty的各个标志位来记录各个状态的变化,随后会调用一个updatePowerStateLocked来更新各个状态。
同样解锁会调用到releaseWakeLockInternalreleaseWakeLockInternal
private void releaseWakeLockInternal(IBinder lock, int flags) { synchronized (mLock) { int index = findWakeLockIndexLocked(lock); if (index < 0) { if (DEBUG_SPEW) { Slog.d(TAG, "releaseWakeLockInternal: lock=" + Objects.hashCode(lock) + " [not found], flags=0x" + Integer.toHexString(flags)); } return; } WakeLock wakeLock = mWakeLocks.get(index); if (DEBUG_SPEW) { Slog.d(TAG, "releaseWakeLockInternal: lock=" + Objects.hashCode(lock) + " [" + wakeLock.mTag + "], flags=0x" + Integer.toHexString(flags)); } if ((flags & PowerManager.RELEASE_FLAG_WAIT_FOR_NO_PROXIMITY) != 0) { mRequestWaitForNegativeProximity = true; } wakeLock.mLock.unlinkToDeath(wakeLock, 0); removeWakeLockLocked(wakeLock, index); } }
PowerManagerService中最终各个接口都会调一个函数updatePowerStateLocked,主要用来更新power的各个状态
updatePowerStateLocked
/** * Updates the global power state based on dirty bits recorded in mDirty. * * This is the main function that performs power state transitions. * We centralize them here so that we can recompute the power state completely * each time something important changes, and ensure that we do it the same * way each time. The point is to gather all of the transition logic here. */ private void updatePowerStateLocked() { if (!mSystemReady || mDirty == 0) { return; } if (!Thread.holdsLock(mLock)) { Slog.wtf(TAG, "Power manager lock was not held when calling updatePowerStateLocked"); } Trace.traceBegin(Trace.TRACE_TAG_POWER, "updatePowerState"); try { // Phase 0: Basic state updates. //更新充电的各个状态(是否充电、电池电量、充电方式、是否低电量),以及更新低功耗模式(android5.0增加的) updateIsPoweredLocked(mDirty); //更新mStayOn状态,为true,屏幕常亮 updateStayOnLocked(mDirty); updateScreenBrightnessBoostLocked(mDirty);//更新屏幕是否最亮的状态是否持续 // Phase 1: Update wakefulness. // Loop because the wake lock and user activity computations are influenced // by changes in wakefulness. final long now = SystemClock.uptimeMillis(); int dirtyPhase2 = 0; for (;;) { int dirtyPhase1 = mDirty; dirtyPhase2 |= dirtyPhase1; mDirty = 0; updateWakeLockSummaryLocked(dirtyPhase1); updateUserActivitySummaryLocked(now, dirtyPhase1); if (!updateWakefulnessLocked(dirtyPhase1)) { break; } } // Phase 2: Update display power state. //更新display状态,在displaypowercontrol中会控制亮度,灭屏等 boolean displayBecameReady = updateDisplayPowerStateLocked(dirtyPhase2); // Phase 3: Update dream state (depends on display ready signal). updateDreamLocked(dirtyPhase2, displayBecameReady);//更新梦的状态,用dreammanager控制梦,powermanagerservice中记录mWakefulness // Phase 4: Send notifications, if needed. finishWakefulnessChangeIfNeededLocked(); // Phase 5: Update suspend blocker. // Because we might release the last suspend blocker here, we need to make sure // we finished everything else first! updateSuspendBlockerLocked(); } finally { Trace.traceEnd(Trace.TRACE_TAG_POWER); } }
省电模式
updateLowPowerModeLocked
void updateLowPowerModeLocked() { if (mIsPowered && mLowPowerModeSetting) {//如果当前插着电源,并且mLowPowerModeSetting为true。也是不能开启低功耗的,将其改为fasle,存入setting if (DEBUG_SPEW) { Slog.d(TAG, "updateLowPowerModeLocked: powered, turning setting off"); } // Turn setting off if powered Settings.Global.putInt(mContext.getContentResolver(), Settings.Global.LOW_POWER_MODE, 0); mLowPowerModeSetting = false; } final boolean autoLowPowerModeEnabled = !mIsPowered && mAutoLowPowerModeConfigured//自动模式开启需要四个。没有充电、开启自动配置、mAutoLowPowerModeSnoozing为false、低电量 && !mAutoLowPowerModeSnoozing && mBatteryLevelLow; final boolean lowPowerModeEnabled = mLowPowerModeSetting || autoLowPowerModeEnabled;//主动的低电量模式只要开启,不在充电就可以了;主动模式和自动模式两者满足其一,就开启低电量模式 if (mLowPowerModeEnabled != lowPowerModeEnabled) { mLowPowerModeEnabled = lowPowerModeEnabled; powerHintInternal(POWER_HINT_LOW_POWER, lowPowerModeEnabled ? 1 : 0);//将低功耗模式,以及是否开启通过JNI,到hardware的power模块,但是我们hardware的power模块好像还不支持低功耗模式 BackgroundThread.getHandler().post(new Runnable() {//在消息线程里面处理 @Override public void run() { Intent intent = new Intent(PowerManager.ACTION_POWER_SAVE_MODE_CHANGING)//发送正在处理低功耗的广播 .putExtra(PowerManager.EXTRA_POWER_SAVE_MODE, mLowPowerModeEnabled) .addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY); mContext.sendBroadcast(intent); ArrayList<PowerManagerInternal.LowPowerModeListener> listeners; synchronized (mLock) { listeners = new ArrayList<PowerManagerInternal.LowPowerModeListener>( mLowPowerModeListeners); } for (int i=0; i<listeners.size(); i++) { listeners.get(i).onLowPowerModeChanged(lowPowerModeEnabled);//这里也是像MountService中一样是注册的各个回调,后续去看看都有谁注册了这些回调。 } intent = new Intent(PowerManager.ACTION_POWER_SAVE_MODE_CHANGED);//发送低功耗处理完了的广播 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY); mContext.sendBroadcast(intent); } }); } }
通过binder接口setPowerSaveMode设置低功耗模式
@Override // Binder call public boolean setPowerSaveMode(boolean mode) { mContext.enforceCallingOrSelfPermission( android.Manifest.permission.DEVICE_POWER, null); final long ident = Binder.clearCallingIdentity(); try { return setLowPowerModeInternal(mode); } finally { Binder.restoreCallingIdentity(ident); } }
private boolean setLowPowerModeInternal(boolean mode) { synchronized (mLock) { if (DEBUG) Slog.d(TAG, "setLowPowerModeInternal " + mode + " mIsPowered=" + mIsPowered); if (mIsPowered) { return false; } Settings.Global.putInt(mContext.getContentResolver(),//将手动模式保存 Settings.Global.LOW_POWER_MODE, mode ? 1 : 0); mLowPowerModeSetting = mode; if (mAutoLowPowerModeConfigured && mBatteryLevelLow) {//如果自动模式开启,并且低电量的时候 if (mode && mAutoLowPowerModeSnoozing) { if (DEBUG_SPEW) { Slog.d(TAG, "setLowPowerModeInternal: clearing low power mode snooze"); } mAutoLowPowerModeSnoozing = false; //这个参数为false,是自动低功耗模式开启的必要条件 } else if (!mode && !mAutoLowPowerModeSnoozing) { if (DEBUG_SPEW) { Slog.d(TAG, "setLowPowerModeInternal: snoozing low power mode"); } mAutoLowPowerModeSnoozing = true; } } updateLowPowerModeLocked();//更新低功耗模式 return true; } }
低功耗模式可以通过setPowerSaveMode接口设置,也可以通过Setting中的数据库监听来设置。
而当省电模式改变时,又有两种模式通知,一种是发广播,另一种的通知回调。上面在updateLowPowerModeLocked已经有描述。
注册回调的接口
@Override public void registerLowPowerModeObserver(LowPowerModeListener listener) { synchronized (mLock) { mLowPowerModeListeners.add(listener); } }
因为是LocalService的接口只能是SystemServer注册的。
下面我们来看看到底会通知那些服务或者应用。
1.回调通知
在NetworkPolicyManagerService会监听,进入省电模式后,网络切断。
BatteryStatsService、VibratorService、WindowManagerService(不放动画)也会处理。
2.广播通知
而广播的是GpsLocationProvider(关闭Gps),PowerUI(显示通知栏等)、声音处理等。
- Android 6.0 PowerManagerService 一
- Android 6.0 PowerManagerService状态分析
- Android 6.0 PowerManagerService 之 Display
- Android 6.0 PowerManagerService 之 updatePowerStateLocked函数
- PowerManagerService学习笔记一
- Android PowerManagerService分析
- android PowerManagerService分析
- Android7.0 PowerManagerService亮灭屏分析(一)
- Android7.0 PowerManagerService亮灭屏分析(一)
- Android Framework------之PowerManagerService的功能
- Android Framework------之PowerManagerService的功能
- Android Framework------之PowerManagerService的功能
- Android系统--PowerManagerService电源管理分析
- Android Framework------之PowerManagerService的功能
- Android PowerManagerService和PowerManager 源码分析
- Android Framework------之PowerManagerService的功能
- android——PowerManagerService源码分析
- android——PowerManagerService源码分析
- 图的储存方式
- 小程序开发补坑
- STL遍历算法 “for_each ”,“transform”
- 简单学正则表达式
- Spring中scope作用域(转)
- Android 6.0 PowerManagerService 一
- liux环境下修改mysql编码
- controller跳转另外一个controller
- makefile 详解
- 报表并发访问量大的配置
- kafa
- 最小二乘法求仿射变换参数,并剔除误差较大的点
- 反射snippet
- 正则表达式中的字符集等概念