Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 5b95c916 authored by Hui Yu's avatar Hui Yu Committed by Automerger Merge Worker
Browse files

Merge "Check PendingStartActivityUids list before updateOomAdj is done." into...

Merge "Check PendingStartActivityUids list before updateOomAdj is done." into rvc-dev am: 600ce540 am: 20710498

Change-Id: I763749a832be1dc404e6c6f80e40eb5446d4e067
parents 587b4e86 20710498
Loading
Loading
Loading
Loading
+13 −0
Original line number Diff line number Diff line
@@ -428,4 +428,17 @@ public abstract class ActivityManagerInternal {
            String[] requiredPermissions, boolean serialized,
            int userId, int[] appIdWhitelist);

    /**
     * Add or delete uid from the ActivityManagerService PendingStartActivityUids list.
     * @param uid uid
     * @param pending add to the list if true, delete from list if false.
     */
    public abstract void updatePendingTopUid(int uid, boolean pending);

    /**
     * Is the uid in ActivityManagerService PendingStartActivityUids list?
     * @param uid
     * @return true if exists, false otherwise.
     */
    public abstract boolean isPendingTopUid(int uid);
}
+72 −1
Original line number Diff line number Diff line
@@ -299,6 +299,7 @@ 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;
@@ -821,6 +822,46 @@ 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.
     *
     * <p>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;
        }
    }
    /**
     * Puts the process record in the map.
     * <p>NOTE: Callers should avoid acquiring the mPidsSelfLocked lock before calling this
@@ -8791,7 +8832,18 @@ public class ActivityManagerService extends IActivityManager.Stub
                    "isUidActive");
        }
        synchronized (this) {
            return isUidActiveLocked(uid);
            if (isUidActiveLocked(uid)) {
                return true;
            }
        }
        if (mInternal.isPendingTopUid(uid)) {
            Slog.wtf(TAG, "PendingStartActivityUids isUidActive false but"
                    + " isPendingTopUid true, uid:" + uid
                    + " callingPackage:" + callingPackage);
            return true;
        } else {
            return false;
        }
    }
@@ -19682,6 +19734,25 @@ public class ActivityManagerService extends IActivityManager.Stub
                return uid >= 0 && mDeviceOwnerUid == uid;
            }
        }
        @Override
        public void updatePendingTopUid(int uid, boolean pending) {
            synchronized (mPendingStartActivityUidsLocked) {
                if (pending) {
                    mPendingStartActivityUidsLocked.add(uid);
                } else {
                    mPendingStartActivityUidsLocked.delete(uid);
                }
            }
        }
        @Override
        public boolean isPendingTopUid(int uid) {
            synchronized (mPendingStartActivityUidsLocked) {
                return mPendingStartActivityUidsLocked.isPendingTopUid(uid);
            }
        }
    }
    long inputDispatchingTimedOut(int pid, final boolean aboveSystem, String reason) {
+1 −0
Original line number Diff line number Diff line
@@ -938,6 +938,7 @@ public final class OomAdjuster {
                    mService.mServices.foregroundServiceProcStateChangedLocked(uidRec);
                }
            }
            mService.mInternal.updatePendingTopUid(uidRec.uid, false);
        }
        if (mLocalPowerManager != null) {
            mLocalPowerManager.finishUidChanges();
+28 −2
Original line number Diff line number Diff line
@@ -521,6 +521,7 @@ public class AppOpsService extends IAppOpsService.Stub {
        public boolean hasForegroundWatchers;

        public long lastTimeShowDebugToast;
        public long lastTimePendingTopUid;

        public UidState(int uid) {
            this.uid = uid;
@@ -542,6 +543,10 @@ public class AppOpsService extends IAppOpsService.Stub {
            if (mode == MODE_FOREGROUND) {
                if (appWidgetVisible) {
                    return MODE_ALLOWED;
                } else if (mActivityManagerInternal != null
                        && mActivityManagerInternal.isPendingTopUid(uid)) {
                    maybeLogPendingTopUid(op, mode);
                    return MODE_ALLOWED;
                } else if (state <= UID_STATE_TOP) {
                    // process is in TOP.
                    return MODE_ALLOWED;
@@ -604,7 +609,11 @@ public class AppOpsService extends IAppOpsService.Stub {
            } else if (mode == MODE_ALLOWED) {
                switch (op) {
                    case OP_CAMERA:
                        if ((capability & PROCESS_CAPABILITY_FOREGROUND_CAMERA) != 0) {
                        if (mActivityManagerInternal != null
                                && mActivityManagerInternal.isPendingTopUid(uid)) {
                            maybeLogPendingTopUid(op, mode);
                            return MODE_ALLOWED;
                        } else if ((capability & PROCESS_CAPABILITY_FOREGROUND_CAMERA) != 0) {
                            return MODE_ALLOWED;
                        } else if ((capability
                                & DEBUG_PROCESS_CAPABILITY_FOREGROUND_CAMERA_Q) != 0) {
@@ -618,7 +627,11 @@ public class AppOpsService extends IAppOpsService.Stub {
                            return MODE_IGNORED;
                        }
                    case OP_RECORD_AUDIO:
                        if ((capability & PROCESS_CAPABILITY_FOREGROUND_MICROPHONE) != 0) {
                        if (mActivityManagerInternal != null
                                && mActivityManagerInternal.isPendingTopUid(uid)) {
                            maybeLogPendingTopUid(op, mode);
                            return MODE_ALLOWED;
                        } else if ((capability & PROCESS_CAPABILITY_FOREGROUND_MICROPHONE) != 0) {
                            return MODE_ALLOWED;
                        } else if ((capability & DEBUG_PROCESS_CAPABILITY_FOREGROUND_MICROPHONE_Q)
                                != 0) {
@@ -704,6 +717,19 @@ public class AppOpsService extends IAppOpsService.Stub {
                        mActivityManagerInternal, uid, op, mode));
            }
        }


        void maybeLogPendingTopUid(int op, int mode) {
            final long now = System.currentTimeMillis();
            if (lastTimePendingTopUid == 0 ||  now - lastTimePendingTopUid > 300000) {
                lastTimePendingTopUid = now;
                Slog.wtf(TAG, "PendingStartActivityUids evalMode, isPendingTopUid true, uid:"
                        + uid
                        + " packageName:" + Settings.getPackageNameForUid(mContext, uid)
                        + " op:" + op
                        + " mode:" + mode);
            }
        }
    }

    final static class Ops extends SparseArray<Op> {
+5 −0
Original line number Diff line number Diff line
@@ -44,6 +44,7 @@ import static com.android.server.wm.ActivityTaskManagerService.RELAUNCH_REASON_N
import android.Manifest;
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.app.ActivityManager;
import android.app.ActivityThread;
import android.app.IApplicationThread;
import android.app.ProfilerInfo;
@@ -1065,6 +1066,10 @@ public class WindowProcessController extends ConfigurationContainer<Configuratio
            // to track as a separate apk in the process.
            packageName = info.packageName;
        }
        // update ActivityManagerService.PendingStartActivityUids list.
        if (topProcessState == ActivityManager.PROCESS_STATE_TOP) {
            mAtm.mAmInternal.updatePendingTopUid(mUid, true);
        }
        // Posting the message at the front of queue so WM lock isn't held when we call into AM,
        // and the process state of starting activity can be updated quicker which will give it a
        // higher scheduling group.