diff options
author | 2019-06-26 01:59:40 +0000 | |
---|---|---|
committer | 2019-06-26 01:59:40 +0000 | |
commit | 9c44b5224e442894305fabdaddb5fd16770cfc08 (patch) | |
tree | c08bc0b0eff699ad17a4cdad34364c1b260ac277 | |
parent | 8fe39f4a50c595413a4611b446508ccade7cd2dc (diff) | |
parent | c2c19c9a65b479a23f0cf6ef23f72b311f1b8374 (diff) |
Merge "Defer PSS collection while an activity is starting"
-rw-r--r-- | services/core/java/com/android/server/am/ActivityManagerService.java | 131 |
1 files changed, 130 insertions, 1 deletions
diff --git a/services/core/java/com/android/server/am/ActivityManagerService.java b/services/core/java/com/android/server/am/ActivityManagerService.java index f451a094e007..4222fc142fa4 100644 --- a/services/core/java/com/android/server/am/ActivityManagerService.java +++ b/services/core/java/com/android/server/am/ActivityManagerService.java @@ -272,6 +272,7 @@ import android.os.storage.IStorageManager; import android.os.storage.StorageManager; import android.provider.DeviceConfig; import android.provider.Settings; +import android.provider.DeviceConfig.Properties; import android.server.ServerProtoEnums; import android.sysprop.VoldProperties; import android.text.TextUtils; @@ -356,6 +357,7 @@ import com.android.server.uri.UriGrantsManagerInternal; import com.android.server.utils.PriorityDump; import com.android.server.utils.TimingsTraceAndSlog; import com.android.server.vr.VrManagerInternal; +import com.android.server.wm.ActivityMetricsLaunchObserver; import com.android.server.wm.ActivityServiceConnectionsHolder; import com.android.server.wm.ActivityTaskManagerInternal; import com.android.server.wm.ActivityTaskManagerService; @@ -392,6 +394,7 @@ import java.util.Set; import java.util.concurrent.CountDownLatch; import java.util.concurrent.Executor; import java.util.concurrent.atomic.AtomicBoolean; +import java.util.concurrent.atomic.AtomicInteger; import java.util.concurrent.atomic.AtomicLong; import java.util.function.BiFunction; @@ -861,6 +864,51 @@ public class ActivityManagerService extends IActivityManager.Stub */ final ArrayList<ProcessRecord> mPendingPssProcesses = new ArrayList<ProcessRecord>(); + /** + * Depth of overlapping activity-start PSS deferral notes + */ + private final AtomicInteger mActivityStartingNesting = new AtomicInteger(0); + + private final ActivityMetricsLaunchObserver mActivityLaunchObserver = + new ActivityMetricsLaunchObserver() { + @Override + public void onActivityLaunched(byte[] activity, int temperature) { + // This is safe to force to the head of the queue because it relies only + // on refcounting to track begin/end of deferrals, not on actual + // message ordering. We don't care *what* activity is being + // launched; only that we're doing so. + if (mPssDeferralTime > 0) { + final Message msg = mBgHandler.obtainMessage(DEFER_PSS_MSG); + mBgHandler.sendMessageAtFrontOfQueue(msg); + } + } + + // The other observer methods are unused + @Override + public void onIntentStarted(Intent intent) { + } + + @Override + public void onIntentFailed() { + } + + @Override + public void onActivityLaunchCancelled(byte[] abortingActivity) { + } + + @Override + public void onActivityLaunchFinished(byte[] finalActivity) { + } + }; + + /** + * How long we defer PSS gathering while activities are starting, in milliseconds. + * This is adjustable via DeviceConfig. If it is zero or negative, no PSS deferral + * is done. + */ + private volatile long mPssDeferralTime = 0; + private static final String ACTIVITY_START_PSS_DEFER_CONFIG = "activity_start_pss_defer"; + private boolean mBinderTransactionTrackingEnabled = false; /** @@ -874,6 +922,20 @@ public class ActivityManagerService extends IActivityManager.Stub */ boolean mFullPssPending = false; + /** + * Observe DeviceConfig changes to the PSS calculation interval + */ + private final DeviceConfig.OnPropertiesChangedListener mPssDelayConfigListener = + new DeviceConfig.OnPropertiesChangedListener() { + @Override + public void onPropertiesChanged(Properties properties) { + mPssDeferralTime = properties.getLong(ACTIVITY_START_PSS_DEFER_CONFIG, 0); + if (DEBUG_PSS) { + Slog.d(TAG_PSS, "Activity-start PSS delay now " + + mPssDeferralTime + " ms"); + } + } + }; /** * This is for verifying the UID report flow. @@ -1838,6 +1900,8 @@ public class ActivityManagerService extends IActivityManager.Stub } static final int COLLECT_PSS_BG_MSG = 1; + static final int DEFER_PSS_MSG = 2; + static final int STOP_DEFERRING_PSS_MSG = 3; final Handler mBgHandler = new Handler(BackgroundThread.getHandler().getLooper()) { @Override @@ -1945,6 +2009,30 @@ public class ActivityManagerService extends IActivityManager.Stub } } while (true); } + + case DEFER_PSS_MSG: { + deferPssForActivityStart(); + } break; + + case STOP_DEFERRING_PSS_MSG: { + final int nesting = mActivityStartingNesting.decrementAndGet(); + if (nesting <= 0) { + if (DEBUG_PSS) { + Slog.d(TAG_PSS, "PSS activity start deferral interval ended; now " + + nesting); + } + if (nesting < 0) { + Slog.wtf(TAG, "Activity start nesting undercount!"); + mActivityStartingNesting.incrementAndGet(); + } + } else { + if (DEBUG_PSS) { + Slog.d(TAG_PSS, "Still deferring PSS, nesting=" + nesting); + } + } + } + break; + } } }; @@ -8832,6 +8920,12 @@ public class ActivityManagerService extends IActivityManager.Stub NETWORK_ACCESS_TIMEOUT_MS, NETWORK_ACCESS_TIMEOUT_DEFAULT_MS); mHiddenApiBlacklist.registerObserver(); + final long pssDeferralMs = DeviceConfig.getLong(DeviceConfig.NAMESPACE_ACTIVITY_MANAGER, + ACTIVITY_START_PSS_DEFER_CONFIG, 0L); + DeviceConfig.addOnPropertiesChangedListener(DeviceConfig.NAMESPACE_ACTIVITY_MANAGER, + ActivityThread.currentApplication().getMainExecutor(), + mPssDelayConfigListener); + synchronized (this) { mDebugApp = mOrigDebugApp = debugApp; mWaitForDebugger = mOrigWaitForDebugger = waitForDebugger; @@ -8848,6 +8942,7 @@ public class ActivityManagerService extends IActivityManager.Stub com.android.internal.R.bool.config_multiuserDelayUserDataLocking); mWaitForNetworkTimeoutMs = waitForNetworkTimeoutMs; + mPssDeferralTime = pssDeferralMs; } } @@ -8921,6 +9016,10 @@ public class ActivityManagerService extends IActivityManager.Stub mAtmInternal.updateTopComponentForFactoryTest(); t.traceEnd(); + t.traceBegin("registerActivityLaunchObserver"); + mAtmInternal.getLaunchObserverRegistry().registerLaunchObserver(mActivityLaunchObserver); + t.traceEnd(); + t.traceBegin("watchDeviceProvisioning"); watchDeviceProvisioning(mContext); t.traceEnd(); @@ -16177,7 +16276,13 @@ public class ActivityManagerService extends IActivityManager.Stub return false; } if (mPendingPssProcesses.size() == 0) { - mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG); + final long deferral = (mPssDeferralTime > 0 && mActivityStartingNesting.get() > 0) + ? mPssDeferralTime : 0; + if (DEBUG_PSS && deferral > 0) { + Slog.d(TAG_PSS, "requestPssLocked() deferring PSS request by " + + deferral + " ms"); + } + mBgHandler.sendEmptyMessageDelayed(COLLECT_PSS_BG_MSG, deferral); } if (DEBUG_PSS) Slog.d(TAG_PSS, "Requesting pss of: " + proc); proc.pssProcState = procState; @@ -16187,6 +16292,30 @@ public class ActivityManagerService extends IActivityManager.Stub } /** + * Re-defer a posted PSS collection pass, if one exists. Assumes deferral is + * currently active policy when called. + */ + private void deferPssIfNeededLocked() { + if (mPendingPssProcesses.size() > 0) { + mBgHandler.removeMessages(COLLECT_PSS_BG_MSG); + mBgHandler.sendEmptyMessageDelayed(COLLECT_PSS_BG_MSG, mPssDeferralTime); + } + } + + private void deferPssForActivityStart() { + synchronized (ActivityManagerService.this) { + if (mPssDeferralTime > 0) { + if (DEBUG_PSS) { + Slog.d(TAG_PSS, "Deferring PSS collection for activity start"); + } + deferPssIfNeededLocked(); + mActivityStartingNesting.getAndIncrement(); + mBgHandler.sendEmptyMessageDelayed(STOP_DEFERRING_PSS_MSG, mPssDeferralTime); + } + } + } + + /** * Schedule PSS collection of all processes. */ void requestPssAllProcsLocked(long now, boolean always, boolean memLowered) { |