diff --git a/core/java/android/app/ActivityManagerInternal.java b/core/java/android/app/ActivityManagerInternal.java index c491eea7a674a..2ce55219506fd 100644 --- a/core/java/android/app/ActivityManagerInternal.java +++ b/core/java/android/app/ActivityManagerInternal.java @@ -429,11 +429,17 @@ public abstract class ActivityManagerInternal { int userId, int[] appIdWhitelist); /** - * Add or delete uid from the ActivityManagerService PendingStartActivityUids list. + * Add uid to the ActivityManagerService PendingStartActivityUids list. * @param uid uid - * @param pending add to the list if true, delete from list if false. + * @param pid pid of the ProcessRecord that is pending top. */ - public abstract void updatePendingTopUid(int uid, boolean pending); + public abstract void addPendingTopUid(int uid, int pid); + + /** + * Delete uid from the ActivityManagerService PendingStartActivityUids list. + * @param uid uid + */ + public abstract void deletePendingTopUid(int uid); /** * Is the uid in ActivityManagerService PendingStartActivityUids list? diff --git a/services/core/java/com/android/server/am/ActivityManagerService.java b/services/core/java/com/android/server/am/ActivityManagerService.java index caaa8371af53f..933dc99a43f01 100644 --- a/services/core/java/com/android/server/am/ActivityManagerService.java +++ b/services/core/java/com/android/server/am/ActivityManagerService.java @@ -28,6 +28,7 @@ import static android.app.ActivityManager.INSTR_FLAG_DISABLE_TEST_API_CHECKS; import static android.app.ActivityManager.INSTR_FLAG_MOUNT_EXTERNAL_STORAGE_FULL; import static android.app.ActivityManager.PROCESS_STATE_LAST_ACTIVITY; import static android.app.ActivityManager.PROCESS_STATE_NONEXISTENT; +import static android.app.ActivityManager.PROCESS_STATE_TOP; import static android.app.ActivityManagerInternal.ALLOW_FULL_ONLY; import static android.app.ActivityManagerInternal.ALLOW_NON_FULL; import static android.app.AppOpsManager.OP_NONE; @@ -299,7 +300,6 @@ import android.util.PrintWriterPrinter; import android.util.Slog; import android.util.SparseArray; import android.util.SparseIntArray; -import android.util.SparseLongArray; import android.util.TimeUtils; import android.util.proto.ProtoOutputStream; import android.util.proto.ProtoUtils; @@ -421,7 +421,6 @@ public class ActivityManagerService extends IActivityManager.Stub * Priority we boost main thread and RT of top app to. */ public static final int TOP_APP_PRIORITY_BOOST = -10; - private static final String SYSTEM_PROPERTY_DEVICE_PROVISIONED = "persist.sys.device_provisioned"; @@ -823,45 +822,7 @@ public class ActivityManagerService extends IActivityManager.Stub } } - /** - * While starting activity, WindowManager posts a runnable to DisplayThread to updateOomAdj. - * The latency of the thread switch could cause client app failure when the app is checking - * {@link #isUidActive} before updateOomAdj is done. - * - * Use PendingStartActivityUids to save uid after WindowManager start activity and before - * updateOomAdj is done. - * - *
NOTE: This object is protected by its own lock, NOT the global activity manager lock! - */ - final PendingStartActivityUids mPendingStartActivityUidsLocked = new PendingStartActivityUids(); - final class PendingStartActivityUids { - // Key is uid, value is SystemClock.elapsedRealtime() when the key is added. - private final SparseLongArray mPendingUids = new SparseLongArray(); - - void add(int uid) { - if (mPendingUids.indexOfKey(uid) < 0) { - mPendingUids.put(uid, SystemClock.elapsedRealtime()); - } - } - - void delete(int uid) { - if (mPendingUids.indexOfKey(uid) >= 0) { - long delay = SystemClock.elapsedRealtime() - mPendingUids.get(uid); - if (delay >= 1000) { - Slog.wtf(TAG, - "PendingStartActivityUids startActivity to updateOomAdj delay:" - + delay + "ms," - + " uid:" + uid - + " packageName:" + Settings.getPackageNameForUid(mContext, uid)); - } - mPendingUids.delete(uid); - } - } - - boolean isPendingTopUid(int uid) { - return mPendingUids.indexOfKey(uid) >= 0; - } - } + private final PendingStartActivityUids mPendingStartActivityUids; /** * Puts the process record in the map. @@ -2585,6 +2546,7 @@ public class ActivityManagerService extends IActivityManager.Stub mFactoryTest = FACTORY_TEST_OFF; mUgmInternal = LocalServices.getService(UriGrantsManagerInternal.class); mInternal = new LocalService(); + mPendingStartActivityUids = new PendingStartActivityUids(mContext); } // Note: This method is invoked on the main thread but may need to attach various @@ -2742,6 +2704,7 @@ public class ActivityManagerService extends IActivityManager.Stub } mInternal = new LocalService(); + mPendingStartActivityUids = new PendingStartActivityUids(mContext); } public void setSystemServiceManager(SystemServiceManager mgr) { @@ -6093,9 +6056,18 @@ public class ActivityManagerService extends IActivityManager.Stub synchronized (mPidsSelfLocked) { for (int i = 0; i < pids.length; i++) { ProcessRecord pr = mPidsSelfLocked.get(pids[i]); - states[i] = (pr == null) ? PROCESS_STATE_NONEXISTENT : pr.getCurProcState(); - if (scores != null) { - scores[i] = (pr == null) ? ProcessList.INVALID_ADJ : pr.curAdj; + if (pr != null) { + final boolean isPendingTop = + mPendingStartActivityUids.isPendingTopPid(pr.uid, pids[i]); + states[i] = isPendingTop ? PROCESS_STATE_TOP : pr.getCurProcState(); + if (scores != null) { + scores[i] = isPendingTop ? ProcessList.FOREGROUND_APP_ADJ : pr.curAdj; + } + } else { + states[i] = PROCESS_STATE_NONEXISTENT; + if (scores != null) { + scores[i] = ProcessList.INVALID_ADJ; + } } } } @@ -8839,15 +8811,7 @@ public class ActivityManagerService extends IActivityManager.Stub return true; } } - - if (mInternal.isPendingTopUid(uid)) { - Slog.wtf(TAG, "PendingStartActivityUids isUidActive false but" - + " isPendingTopUid true, uid:" + uid - + " callingPackage:" + callingPackage); - return true; - } else { - return false; - } + return mInternal.isPendingTopUid(uid); } boolean isUidActiveLocked(int uid) { @@ -19731,22 +19695,18 @@ public class ActivityManagerService extends IActivityManager.Stub } @Override - public void updatePendingTopUid(int uid, boolean pending) { - synchronized (mPendingStartActivityUidsLocked) { - if (pending) { - mPendingStartActivityUidsLocked.add(uid); - } else { - mPendingStartActivityUidsLocked.delete(uid); - } - } + public void addPendingTopUid(int uid, int pid) { + mPendingStartActivityUids.add(uid, pid); + } + @Override + public void deletePendingTopUid(int uid) { + mPendingStartActivityUids.delete(uid); } @Override public boolean isPendingTopUid(int uid) { - synchronized (mPendingStartActivityUidsLocked) { - return mPendingStartActivityUidsLocked.isPendingTopUid(uid); - } + return mPendingStartActivityUids.isPendingTopUid(uid); } } diff --git a/services/core/java/com/android/server/am/OomAdjuster.java b/services/core/java/com/android/server/am/OomAdjuster.java index 14c5b2cb12b22..03ff3d0e09781 100644 --- a/services/core/java/com/android/server/am/OomAdjuster.java +++ b/services/core/java/com/android/server/am/OomAdjuster.java @@ -951,7 +951,7 @@ public final class OomAdjuster { mService.mServices.foregroundServiceProcStateChangedLocked(uidRec); } } - mService.mInternal.updatePendingTopUid(uidRec.uid, false); + mService.mInternal.deletePendingTopUid(uidRec.uid); } if (mLocalPowerManager != null) { mLocalPowerManager.finishUidChanges(); diff --git a/services/core/java/com/android/server/am/PendingStartActivityUids.java b/services/core/java/com/android/server/am/PendingStartActivityUids.java new file mode 100644 index 0000000000000..0ed99fedf23d5 --- /dev/null +++ b/services/core/java/com/android/server/am/PendingStartActivityUids.java @@ -0,0 +1,80 @@ +/* + * Copyright (C) 2020 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.server.am; + +import android.content.Context; +import android.os.SystemClock; +import android.provider.Settings; +import android.util.Pair; +import android.util.Slog; +import android.util.SparseArray; + +/** + * While starting activity, WindowManager posts a runnable to DisplayThread to updateOomAdj. + * The latency of the thread switch could cause client app failure when the app is checking + * {@link ActivityManagerService#isUidActive} before updateOomAdj is done. + * + * Use PendingStartActivityUids to save uid after WindowManager start activity and before + * updateOomAdj is done. + * + *
NOTE: This object is protected by its own lock, NOT the global activity manager lock!
+ */
+final class PendingStartActivityUids {
+ static final String TAG = ActivityManagerService.TAG;
+
+ // Key is uid, value is Pair of pid and SystemClock.elapsedRealtime() when the
+ // uid is added.
+ private final SparseArray