and5.1PowerManagerService深入分析(一) PMS的初始化以及低功耗模式

之前已经分析过PMS了,但是不是非常详细。

现在准备详细的分析下PMS。

一、构造函数

先看下构造函数:

    public PowerManagerService(Context context) {
        super(context);
        mContext = context;
        mHandlerThread = new ServiceThread(TAG,
                Process.THREAD_PRIORITY_DISPLAY, false /*allowIo*/);
        mHandlerThread.start();
        mHandler = new PowerManagerHandler(mHandlerThread.getLooper());//新建一个handler,并且handler的线程也是新建的

        synchronized (mLock) {
            mWakeLockSuspendBlocker = createSuspendBlockerLocked("PowerManagerService.WakeLocks");//通过JNI调用底层的wakelock函数
            mDisplaySuspendBlocker = createSuspendBlockerLocked("PowerManagerService.Display");
            mDisplaySuspendBlocker.acquire();//持锁
            mHoldingDisplaySuspendBlocker = true;
            mHalAutoSuspendModeEnabled = false;
            mHalInteractiveModeEnabled = true;

            mWakefulness = WAKEFULNESS_AWAKE;//mWakefulness 初始状态

            nativeInit();
            nativeSetAutoSuspend(false);
            nativeSetInteractive(true);
        }
    }

先看下createSuspendBlockerLocked函数

    private SuspendBlocker createSuspendBlockerLocked(String name) {
        SuspendBlocker suspendBlocker = new SuspendBlockerImpl(name);
        mSuspendBlockers.add(suspendBlocker);
        return suspendBlocker;
    }

再看下SuspendBlockerImpl 函数,其中acquire,是通过JNI

    private final class SuspendBlockerImpl implements SuspendBlocker {
        private final String mName;
        private final String mTraceName;
        private int mReferenceCount;

        public SuspendBlockerImpl(String name) {
            mName = name;
            mTraceName = "SuspendBlocker (" + name + ")";
        }

        @Override
        protected void finalize() throws Throwable {
            try {
                if (mReferenceCount != 0) {
                    Slog.wtf(TAG, "Suspend blocker \"" + mName
                            + "\" was finalized without being released!");
                    mReferenceCount = 0;
                    nativeReleaseSuspendBlocker(mName);
                    Trace.asyncTraceEnd(Trace.TRACE_TAG_POWER, mTraceName, 0);
                }
            } finally {
                super.finalize();
            }
        }

        @Override
        public void acquire() {
            synchronized (this) {
                mReferenceCount += 1;
                if (mReferenceCount == 1) {
                    if (DEBUG_SPEW) {
                        Slog.d(TAG, "Acquiring suspend blocker \"" + mName + "\".");
                    }
                    Trace.asyncTraceBegin(Trace.TRACE_TAG_POWER, mTraceName, 0);
                    nativeAcquireSuspendBlocker(mName);
                }
            }
        }
nativeAcquireSuspendBlocker将上面传下来的name,然后是PARTIAL_WAKE_LOCK类型的lock

static void nativeAcquireSuspendBlocker(JNIEnv *env, jclass clazz, jstring nameStr) {
    ScopedUtfChars name(env, nameStr);
    acquire_wake_lock(PARTIAL_WAKE_LOCK, name.c_str());
}


nativeInit也类似初始的时候写入cpu节点值。我们先看下jni

static void nativeInit(JNIEnv* env, jobject obj) {
    gPowerManagerServiceObj = env->NewGlobalRef(obj);

    status_t err = hw_get_module(POWER_HARDWARE_MODULE_ID,
            (hw_module_t const**)&gPowerModule);
    if (!err) {
        gPowerModule->init(gPowerModule);
    } else {
        ALOGE("Couldn't load %s module (%s)", POWER_HARDWARE_MODULE_ID, strerror(-err));
    }
}

我们再看下power module的初始化:

struct lc_power_module HAL_MODULE_INFO_SYM = {
    base: {
        common: {
            tag: HARDWARE_MODULE_TAG,
            module_api_version: POWER_MODULE_API_VERSION_0_2,
            hal_api_version: HARDWARE_HAL_API_VERSION,
            id: POWER_HARDWARE_MODULE_ID,
            name: "LC Power HAL",
            author: "Leadcore Technology Co.,Ltd",
            methods: &power_module_methods,
        },

        init: power_init,
        setInteractive: lc_power_set_interactive,
        powerHint: lc_power_hint,
    },
..........
};

init函数对应power_init函数

static void power_init(struct power_module *module)
{
    ALOGV("%s", __func__);
    power_init_internal(module);
}

power_init函数又调用了power_init_internal函数

void power_init_internal(struct power_module *module)
{
    char buf[MAX_LENGTH];
    int len = 0;
    struct lc_power_module *lc = (struct lc_power_module *) module;

    if (lc->power_lc_inited) {
        ALOGD_IF(lc->log_hint, "Power HAL is inited!");
        return;
    }

    char property[PROPERTY_VALUE_MAX];
    if(property_get("debug.power.loghint", property, "0") > 0) {
        if(atoi(property) == 1) {
            lc->log_hint = 1;
            ALOGI("enable power hint log!");
        }
    }

    len = sizeof(buf);
    sysfs_read("/sys/devices/system/cpu/cpu0/cpufreq/cpuinfo_max_freq", buf, &len);
    buf[len-1] = '\0';
    ALOGD_IF(lc->log_hint, "cpuinfo_max_freq %s readlen=%d", buf, len);

    if (atoi(buf) != 0) {
        lc->cpu_max_freq = atoi(buf);
    }

    if(system("set_middle_performance.sh"))
    {
        ALOGW("failed to run shell script!");
        sysfs_write("/sys/devices/system/cpu/cpu0/cpufreq/interactive/timer_rate",
                    "40000");
        sysfs_write("/sys/devices/system/cpu/cpu0/cpufreq/interactive/timer_slack",
                    "50000");
        sysfs_write("/sys/devices/system/cpu/cpu0/cpufreq/interactive/min_sample_time",
                    "40000");
        sysfs_write("/sys/devices/system/cpu/cpu0/cpufreq/interactive/above_hispeed_delay",
                    "1");
    }

    if(lc->cpu_max_freq == 1599000) {
        sysfs_write("/sys/devices/system/cpu/cpu0/cpufreq/interactive/hispeed_freq",
                    HISPEED_FREQ_1_6);
    } else if(lc->cpu_max_freq == 1807000) {
        sysfs_write("/sys/devices/system/cpu/cpu0/cpufreq/interactive/hispeed_freq",
                    HISPEED_FREQ_1_8);
    } else if(lc->cpu_max_freq == 1495000) {
        sysfs_write("/sys/devices/system/cpu/cpu0/cpufreq/interactive/hispeed_freq",
                    HISPEED_FREQ_1_5);
    } else {
        ALOGW("unknown cpu frequency %d", lc->cpu_max_freq);
    }

    sysfs_write("/sys/devices/system/cpu/cpu0/cpufreq/interactive/boostpulse_duration",
                BOOSTPULSE_DURATION);
    sysfs_write("/sys/devices/system/cpu/cpu0/cpufreq/interactive/io_is_busy", "1");
    sysfs_write("/sys/module/comip_hotplug/parameters/load_h0", "15");
    sysfs_write("/sys/module/comip_hotplug/parameters/load_h1", "30");
    sysfs_write("/sys/module/comip_hotplug/parameters/load_h2", "55");
    sysfs_write("/sys/module/comip_hotplug/parameters/load_l1", "15");
    sysfs_write("/sys/module/comip_hotplug/parameters/load_l2", "28");
    sysfs_write("/sys/module/comip_hotplug/parameters/load_l3", "50");

    sysfs_write("/sys/devices/platform/comip-hotplug/hotplug/boost_duration",
                BOOSTPULSE_DURATION_HOTPLUG);  //boost duration 1s

    lasthint = 0;
    activity_hint = 0;
    camera_hint = 0;
    ALOGD_IF(lc->log_hint, "%s done\n", __func__);
}

nativeSetInteractive也是通过JNI,最后调到这里,当然各个hardware都有自己的实现方式。这个函数里面只是在cpu的节点里面写入一些值。

static void lc_power_set_interactive(struct power_module *module, int on)
{
    char buf[100];
    int len;
    /*
     * Lower maximum frequency when screen is off.  CPU 0 and 1 share a
     * cpufreq policy.
     */
    //sysfs_write("/sys/devices/system/cpu/cpu0/cpufreq/scaling_max_freq",
    //            on ? "1599000" : "799500");
    if(on) {
        len = sizeof(buf);
        sysfs_read("/sys/devices/platform/mali.0/perf_level", buf, &len);
        buf[len-1] = '\0';

        ALOGD_IF(log_hint, "interactive on gpu pref_level %s\n", buf);
        if(atoi(buf) == 2) {
            system("set_middle_performance.sh");
        } else if(atoi(buf) == 3) {
            system("set_high_performance.sh");
        }
    } else {
        sysfs_write("/sys/devices/system/cpu/cpu0/cpufreq/interactive/timer_rate",
                    "60000");
        sysfs_write("/sys/devices/system/cpu/cpu0/cpufreq/interactive/timer_slack",
                    "50000");
        sysfs_write("/sys/devices/system/cpu/cpu0/cpufreq/interactive/min_sample_time",
                    "1");
        sysfs_write("/sys/devices/system/cpu/cpu0/cpufreq/interactive/above_hispeed_delay",
                    "1");
    }

    ALOGD("power_set_interactive: %d done\n", on);
}


二、onStart函数

下面是走onStart函数,将BinderService和localServicepublish出去,同时将自己和handler加入watchdog中。

    @Override
    public void onStart() {
        publishBinderService(Context.POWER_SERVICE, new BinderService());
        publishLocalService(PowerManagerInternal.class, new LocalService());

        Watchdog.getInstance().addMonitor(this);
        Watchdog.getInstance().addThread(mHandler);
    }


三、systemReady函数

下面走的是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数据库中值的一个观察者,一旦值有变就会调用mSettingsObserver
                    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);
            // Go.
            readConfigurationLocked();
            updateSettingsLocked();
            mDirty |= DIRTY_BATTERY_STATE;
            updatePowerStateLocked();
        }
    }

接受电池变化的广播

    private final class BatteryReceiver extends BroadcastReceiver {
        @Override
        public void onReceive(Context context, Intent intent) {
            synchronized (mLock) {
                handleBatteryStateChangedLocked();
            }
        }
    }
    private void handleBatteryStateChangedLocked() {
        mDirty |= DIRTY_BATTERY_STATE;
        updatePowerStateLocked();
    }
接受做梦的开始或者结束
    private final class DreamReceiver extends BroadcastReceiver {
        @Override
        public void onReceive(Context context, Intent intent) {
            synchronized (mLock) {
                scheduleSandmanLocked();
            }
        }
    }
    private void scheduleSandmanLocked() {
        if (!mSandmanScheduled) {
            mSandmanScheduled = true;
            Message msg = mHandler.obtainMessage(MSG_SANDMAN);
            msg.setAsynchronous(true);
            mHandler.sendMessage(msg);//通过发送消息
        }
    }
        @Override
        public void handleMessage(Message msg) {
            switch (msg.what) {
                case MSG_USER_ACTIVITY_TIMEOUT:
                    handleUserActivityTimeout();
                    break;
                case MSG_SANDMAN:
                    handleSandman();//这个函数是对做梦的处理,后面详细分析
                    break;
                case MSG_SCREEN_BRIGHTNESS_BOOST_TIMEOUT:
                    handleScreenBrightnessBoostTimeout();
                    break;
            }
        }

mSettingsObserver对Setting数据库中的一些变量进行观察,一旦变化就调这个onChange这个函数。在上面的SystemReady中已经注册了各个变量的观察。
    private final class SettingsObserver extends ContentObserver {
        public SettingsObserver(Handler handler) {
            super(handler);
        }

        @Override
        public void onChange(boolean selfChange, Uri uri) {
            synchronized (mLock) {
                handleSettingsChangedLocked();
            }
        }
    }
handleSettingsChangedLocked函数
    private void handleSettingsChangedLocked() {
        updateSettingsLocked();//更新各个设置参数
        updatePowerStateLocked();//更新power状态,后面详细分析
    }
下面看下updateSettingsLocked函数,其中的各个参数后面用到再分析

   private void updateSettingsLocked() {
        final ContentResolver resolver = mContext.getContentResolver();

        mDreamsEnabledSetting = (Settings.Secure.getIntForUser(resolver,
                Settings.Secure.SCREENSAVER_ENABLED,
                mDreamsEnabledByDefaultConfig ? 1 : 0,
                UserHandle.USER_CURRENT) != 0);
        mDreamsActivateOnSleepSetting = (Settings.Secure.getIntForUser(resolver,
                Settings.Secure.SCREENSAVER_ACTIVATE_ON_SLEEP,
                mDreamsActivatedOnSleepByDefaultConfig ? 1 : 0,
                UserHandle.USER_CURRENT) != 0);
        mDreamsActivateOnDockSetting = (Settings.Secure.getIntForUser(resolver,
                Settings.Secure.SCREENSAVER_ACTIVATE_ON_DOCK,
                mDreamsActivatedOnDockByDefaultConfig ? 1 : 0,
                UserHandle.USER_CURRENT) != 0);
        mScreenOffTimeoutSetting = Settings.System.getIntForUser(resolver,
                Settings.System.SCREEN_OFF_TIMEOUT, DEFAULT_SCREEN_OFF_TIMEOUT,//屏幕自动灭屏的一个timeout
                UserHandle.USER_CURRENT);
        mSleepTimeoutSetting = Settings.Secure.getIntForUser(resolver,
                Settings.Secure.SLEEP_TIMEOUT, DEFAULT_SLEEP_TIMEOUT,
                UserHandle.USER_CURRENT);
        mStayOnWhilePluggedInSetting = Settings.Global.getInt(resolver,
                Settings.Global.STAY_ON_WHILE_PLUGGED_IN, BatteryManager.BATTERY_PLUGGED_AC);
        mTheaterModeEnabled = Settings.Global.getInt(mContext.getContentResolver(),
                Settings.Global.THEATER_MODE_ON, 0) == 1;

        final int oldScreenBrightnessSetting = mScreenBrightnessSetting;
        mScreenBrightnessSetting = Settings.System.getIntForUser(resolver,
                Settings.System.SCREEN_BRIGHTNESS, mScreenBrightnessSettingDefault,
                UserHandle.USER_CURRENT);
        if (oldScreenBrightnessSetting != mScreenBrightnessSetting) {
            mTemporaryScreenBrightnessSettingOverride = -1;
        }

        final float oldScreenAutoBrightnessAdjustmentSetting =
                mScreenAutoBrightnessAdjustmentSetting;
        mScreenAutoBrightnessAdjustmentSetting = Settings.System.getFloatForUser(resolver,
                Settings.System.SCREEN_AUTO_BRIGHTNESS_ADJ, 0.0f,
                UserHandle.USER_CURRENT);
        if (oldScreenAutoBrightnessAdjustmentSetting != mScreenAutoBrightnessAdjustmentSetting) {
            mTemporaryScreenAutoBrightnessAdjustmentSettingOverride = Float.NaN;
        }

        mScreenBrightnessModeSetting = Settings.System.getIntForUser(resolver,
                Settings.System.SCREEN_BRIGHTNESS_MODE,
                Settings.System.SCREEN_BRIGHTNESS_MODE_MANUAL, UserHandle.USER_CURRENT);

        final boolean lowPowerModeEnabled = Settings.Global.getInt(resolver,
                Settings.Global.LOW_POWER_MODE, 0) != 0;//低功耗模式
        final boolean autoLowPowerModeConfigured = Settings.Global.getInt(resolver,//低功耗自动模式
                Settings.Global.LOW_POWER_MODE_TRIGGER_LEVEL, 0) != 0;
        if (lowPowerModeEnabled != mLowPowerModeSetting//两种模式其中一个改变了就调用updateLowPowerModeLocked函数
                || autoLowPowerModeConfigured != mAutoLowPowerModeConfigured) {
            mLowPowerModeSetting = lowPowerModeEnabled;
            mAutoLowPowerModeConfigured = autoLowPowerModeConfigured;
            updateLowPowerModeLocked();
        }

        mDirty |= DIRTY_SETTINGS;//Dirty的DIRTY_SETTINGS改变了
    }


四、省电模式

下面分析下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);
            }
        }

setLowPowerModeInternal函数,如果在充电直接返回

    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(显示通知栏等)、声音处理等。


五、继续systemReady函数

继续分析systemReady函数:

            readConfigurationLocked();//读取资源中的配置信息
            updateSettingsLocked();
            mDirty |= DIRTY_BATTERY_STATE;//修改mDirty 状态
            updatePowerStateLocked();//更新power状态
        }
    }

readConfigurationLocked函数

private void readConfigurationLocked() {
        final Resources resources = mContext.getResources();

        mDecoupleHalAutoSuspendModeFromDisplayConfig = resources.getBoolean(
                com.android.internal.R.bool.config_powerDecoupleAutoSuspendModeFromDisplay);
        mDecoupleHalInteractiveModeFromDisplayConfig = resources.getBoolean(
                com.android.internal.R.bool.config_powerDecoupleInteractiveModeFromDisplay);
        mWakeUpWhenPluggedOrUnpluggedConfig = resources.getBoolean(
                com.android.internal.R.bool.config_unplugTurnsOnScreen);
        mWakeUpWhenPluggedOrUnpluggedInTheaterModeConfig = resources.getBoolean(
                com.android.internal.R.bool.config_allowTheaterModeWakeFromUnplug);
        mSuspendWhenScreenOffDueToProximityConfig = resources.getBoolean(
                com.android.internal.R.bool.config_suspendWhenScreenOffDueToProximity);
        mDreamsSupportedConfig = resources.getBoolean(
                com.android.internal.R.bool.config_dreamsSupported);
        mDreamsEnabledByDefaultConfig = resources.getBoolean(
                com.android.internal.R.bool.config_dreamsEnabledByDefault);
        mDreamsActivatedOnSleepByDefaultConfig = resources.getBoolean(
                com.android.internal.R.bool.config_dreamsActivatedOnSleepByDefault);
        mDreamsActivatedOnDockByDefaultConfig = resources.getBoolean(
                com.android.internal.R.bool.config_dreamsActivatedOnDockByDefault);
        mDreamsEnabledOnBatteryConfig = resources.getBoolean(
                com.android.internal.R.bool.config_dreamsEnabledOnBattery);
        mDreamsBatteryLevelMinimumWhenPoweredConfig = resources.getInteger(
                com.android.internal.R.integer.config_dreamsBatteryLevelMinimumWhenPowered);
        mDreamsBatteryLevelMinimumWhenNotPoweredConfig = resources.getInteger(
                com.android.internal.R.integer.config_dreamsBatteryLevelMinimumWhenNotPowered);
        mDreamsBatteryLevelDrainCutoffConfig = resources.getInteger(
                com.android.internal.R.integer.config_dreamsBatteryLevelDrainCutoff);
        mDozeAfterScreenOffConfig = resources.getBoolean(
                com.android.internal.R.bool.config_dozeAfterScreenOff);
        mMinimumScreenOffTimeoutConfig = resources.getInteger(
                com.android.internal.R.integer.config_minimumScreenOffTimeout);
        mMaximumScreenDimDurationConfig = resources.getInteger(
                com.android.internal.R.integer.config_maximumScreenDimDuration);
        mMaximumScreenDimRatioConfig = resources.getFraction(
                com.android.internal.R.fraction.config_maximumScreenDimRatio, 1, 1);
    }
好那么pms的一些初始化工作分析完了,下面接下来分析。




  • 2
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值