Android Sprd省電力管理(6)アプリスタンバイ休止状態の最適化

スタンバイ休止状態を最適化すると、アプリケーションがシステムのスリープを防止する時間が短縮され、スタンバイの消費電力が削減されます。これは、アプリケーションの最大保持時間を制限する、アプリケーションのウェイクロック保持ロックの最適化です。

ではAndroidのSPRDの省電力管理(5)アプリのスタンバイネットワーク管理アイドルモードに入るときの話、それはPowerController.javaのnotifyChanged()メソッドを呼び出します

    private void notifyChanged() {
        if (DEBUG) Slog.d(TAG, "- notifyChanged() E -");
 
        for (int i = 0; i < mHelpers.size(); i++) {
            PowerSaveHelper helper = mHelpers.get(i);
            helper.applyConstrain();
        }
    }

WakelockConstraintHelperはPowerSaveHelperを継承します

WakelockConstraintHelper.java-> applyConstrain()

    @Override
    void applyConstrain() {

        for (int index=mNewWakeLockAppListForUsers.size()-1; index>=0; index--) {
            ArrayMap<String, Integer> mNewWakeLockAppList = mNewWakeLockAppListForUsers.valueAt(index);

            for (int i=0;i<mNewWakeLockAppList.size();i++) {
                try {
                    if (DEBUG) Slog.d(TAG, "packageName:" + mNewWakeLockAppList.keyAt(i)
                        + " uid:" + mNewWakeLockAppList.valueAt(i) + " constrained Wake Lock");
                    // Notify PowerManager to disable the wake lock of this app
                    notifyAppWakeLockConstrainedStateChanged(mNewWakeLockAppList.valueAt(i), true);
                    updateAppWakeLockConstrainedState(mNewWakeLockAppList.keyAt(i), true, mNewWakeLockAppList.valueAt(i));
                } catch (Exception e) {
                    // fall through
                }
            }
            mNewWakeLockAppList.clear();

        }
    }

WakelockConstraintHelper.java-> notifyAppWakeLockConstrainedStateChanged()

    // wrap API for PowerManagerInternal
    private void notifyAppWakeLockConstrainedStateChanged(int uid, boolean constrained) {
        if (DEBUG) Slog.d(TAG, "notifyAppWakeLockConstrainedStateChanged() E uid:" + uid + " constrained:" + constrained);
        if (mLocalPowerManager != null) {
            mLocalPowerManager.updateUidProcWakeLockDisabledState(uid, constrained);
        }
    }

PowerManagerInternalは抽象クラスです。PowerManagerServiceの内部クラスLocalServiceはPowerManagerInternalを継承します

PowerManagerService.java-> LocalService-> updateUidProcWakeLockDisabledState()

        @Override
        public void updateUidProcWakeLockDisabledState(int uid, boolean disabled) {
            mPowerControllerHelper.updateUidProcWakeLockDisabledState(uid, disabled);
        }

PowerManagerService.java-> updateUidProcWakeLockDisabledState()

        public void updateUidProcWakeLockDisabledState(int uid, boolean disabled) {
            synchronized (mLock) {
                int index = mWakeLockDisabledApplist.indexOf(uid);
                if (disabled) {
                    if (index < 0)
                        mWakeLockDisabledApplist.add(uid);
                } else {
                    if (index >= 0)
                        mWakeLockDisabledApplist.remove(index);
                }
                updateWakeLockDisabledStatesLocked();
            }
        }

PowerManagerService.java-> updateWakeLockDisabledStatesLocked()

    private void updateWakeLockDisabledStatesLocked() {
        boolean changed = false;
        final int numWakeLocks = mWakeLocks.size();
        for (int i = 0; i < numWakeLocks; i++) {
            final WakeLock wakeLock = mWakeLocks.get(i);
            if ((wakeLock.mFlags & PowerManager.WAKE_LOCK_LEVEL_MASK)
                    == PowerManager.PARTIAL_WAKE_LOCK) {
                if (setWakeLockDisabledStateLocked(wakeLock)) {
                    changed = true;
                    if (wakeLock.mDisabled) {
                        // This wake lock is no longer being respected.
                        notifyWakeLockReleasedLocked(wakeLock);
                    } else {
                        notifyWakeLockAcquiredLocked(wakeLock);
                    }
                }
            }
        }
        if (changed) {
            mDirty |= DIRTY_WAKE_LOCKS;
            updatePowerStateLocked();
        }
    }

PowerManagerService.java-> setWakeLockDisabledStateLocked()

    private boolean setWakeLockDisabledStateLocked(WakeLock wakeLock) {
        if ((wakeLock.mFlags & PowerManager.WAKE_LOCK_LEVEL_MASK)
                == PowerManager.PARTIAL_WAKE_LOCK) {
            boolean disabled = false;
            final int appid = UserHandle.getAppId(wakeLock.mOwnerUid);
            if (appid >= Process.FIRST_APPLICATION_UID) {
                // Cached inactive processes are never allowed to hold wake locks.
                if (mConstants.NO_CACHED_WAKE_LOCKS) {
                    disabled = !wakeLock.mUidState.mActive &&
                            wakeLock.mUidState.mProcState
                                    != ActivityManager.PROCESS_STATE_NONEXISTENT &&
                            wakeLock.mUidState.mProcState > ActivityManager.PROCESS_STATE_RECEIVER;
                }
                if (mDeviceIdleMode) {
                    // If we are in idle mode, we will also ignore all partial wake locks that are
                    // for application uids that are not whitelisted.
                    final UidState state = wakeLock.mUidState;
                    if (Arrays.binarySearch(mDeviceIdleWhitelist, appid) < 0 &&
                            Arrays.binarySearch(mDeviceIdleTempWhitelist, appid) < 0 &&
                            state.mProcState != ActivityManager.PROCESS_STATE_NONEXISTENT &&
                            state.mProcState > ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE) {
                        disabled = true;
                    }
                }
            }

            // NOTE: Bug #627645 low power Feature BEG-->
            // if wake lock is not disable by DeviceIdle
            // check if is disabled by mWakeLockDisablelist
            if (!disabled) {
                disabled = mPowerControllerHelper.shouldWakeLockDisabledLocked(wakeLock);
            }
            // <-- NOTE: Bug #627645 low power Feature END

            if (wakeLock.mDisabled != disabled) {
                wakeLock.mDisabled = disabled;
                return true;
            }
        }
        return false;
    }

wakeLock mDisabledをtrueに設定してから、notifyWakeLockReleasedLockedを呼び出して、関連する統計情報を電力統計サービスに通知します。

PowerManagerService.java-> notifyWakeLockReleasedLocked()

    private void notifyWakeLockReleasedLocked(WakeLock wakeLock) {
        if (mSystemReady && wakeLock.mNotifiedAcquired) {
            wakeLock.mNotifiedAcquired = false;
            wakeLock.mAcquireTime = 0;
            mNotifier.onWakeLockReleased(wakeLock.mFlags, wakeLock.mTag,
                    wakeLock.mPackageName, wakeLock.mOwnerUid, wakeLock.mOwnerPid,
                    wakeLock.mWorkSource, wakeLock.mHistoryTag);
            notifyWakeLockLongFinishedLocked(wakeLock);


            // NOTE: Bug #627645 low power Feature BEG-->
            // notify listeners
            mPowerControllerHelper.notifyWakeLockReleasedLocked(wakeLock);
            // <-- NOTE: Bug #627645 low power Feature END
        }
    }

PowerManagerService.java-> notifyWakeLockReleasedLocked()

        public void notifyWakeLockReleasedLocked(WakeLock wakeLock) {

            // if Audio release a wakelock notify listeners
            if ((wakeLock.mFlags & PowerManager.WAKE_LOCK_LEVEL_MASK) == PowerManager.PARTIAL_WAKE_LOCK
                && Process.AUDIOSERVER_UID == wakeLock.mOwnerUid) {
                if (mPowerControllerInternalCallback != null) {
                    mPowerControllerInternalCallback.onWakeLockReleased(wakeLock.mTag, wakeLock.mPackageName,
                        wakeLock.mOwnerUid, wakeLock.mOwnerPid, wakeLock.mWorkSource);
                }
            }
        }

onWakeLockReleased()は、PowerManagerInternal.javaの内部インターフェイスPowerControllerInternalCallbackのメソッドです。

WakelockConstraintHelperの内部クラスWakeLockObserverは、PowerManagerInternal.PowerControllerInternalCallbackを実装します。

        @Override
        public void onWakeLockReleased(String tag, String packageName,
            int ownerUid, int ownerPid, WorkSource workSource) {
            noteAudioWakeLockReleased(tag, packageName, ownerUid, ownerPid, workSource);
        }

WakelockConstraintHelper.java-> noteAudioWakeLockReleased()

    private void noteAudioWakeLockReleased(String tag, String packageName,
        int ownerUid, int ownerPid, WorkSource workSource) {

        // only care about the workSource
        if (!AUDIO_PACKAGE_NAME.equals(packageName) || Process.AUDIOSERVER_UID != ownerUid) return;

        if (DEBUG) Slog.d(TAG, "noteAudioWakeLockReleased: tag: " + tag);

        if (isAudioIn(tag)) {
            mHandler.sendMessage(mHandler.obtainMessage(MSG_AUDIOIN_WAKELOCK_RELEASED));
        } else if (isAudioOut(tag)) {
            WakeLockInfo wakeLockInfo = new WakeLockInfo(tag, packageName, ownerUid, workSource);
            mHandler.sendMessage(mHandler.obtainMessage(MSG_AUDIOOUT_WAKELOCK_RELEASED, wakeLockInfo));
        }

    }

 

おすすめ

転載: blog.csdn.net/liu362732346/article/details/86509279