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

Commit 6a2481a6 authored by Hui Yu's avatar Hui Yu Committed by Automerger Merge Worker
Browse files

Merge "Add uid to PendingStartActivityUids when activity resumed." into rvc-dev am: c05fd22c

Original change: https://googleplex-android-review.googlesource.com/c/platform/frameworks/base/+/11723113

Change-Id: I01438c66ca66a7a074033cc29d1cf7d437d2bf19
parents c6162efa c05fd22c
Loading
Loading
Loading
Loading
+9 −3
Original line number Diff line number Diff line
@@ -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?
+24 −64
Original line number Diff line number Diff line
@@ -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.
     *
     * <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;
        }
    }
    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 (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] = (pr == null) ? ProcessList.INVALID_ADJ : pr.curAdj;
                        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);
        }
    }
+1 −1
Original line number Diff line number Diff line
@@ -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();
+80 −0
Original line number Diff line number Diff line
/*
 * 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.
 *
 * <p>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<Pair<Integer, Long>> mPendingUids = new SparseArray();
    private Context mContext;

    PendingStartActivityUids(Context context) {
        mContext = context;
    }

    synchronized void add(int uid, int pid) {
        if (mPendingUids.get(uid) == null) {
            mPendingUids.put(uid, new Pair<>(pid, SystemClock.elapsedRealtime()));
        }
    }

    synchronized void delete(int uid) {
        final Pair<Integer, Long> pendingPid = mPendingUids.get(uid);
        if (pendingPid != null) {
            final long delay = SystemClock.elapsedRealtime() - pendingPid.second;
            if (delay >= 1000 /*ms*/) {
                Slog.i(TAG,
                        "PendingStartActivityUids startActivity to updateOomAdj delay:"
                                + delay + "ms," + " uid:" + uid + " packageName:"
                                + Settings.getPackageNameForUid(mContext, uid));
            }
            mPendingUids.delete(uid);
        }
    }

    synchronized boolean isPendingTopPid(int uid, int pid) {
        final Pair<Integer, Long> pendingPid = mPendingUids.get(uid);
        if (pendingPid != null) {
            return pendingPid.first == pid;
        } else {
            return false;
        }
    }

    synchronized boolean isPendingTopUid(int uid) {
        return mPendingUids.get(uid) != null;
    }
}
 No newline at end of file
+1 −18
Original line number Diff line number Diff line
@@ -521,7 +521,6 @@ public class AppOpsService extends IAppOpsService.Stub {
        public boolean hasForegroundWatchers;

        public long lastTimeShowDebugToast;
        public long lastTimePendingTopUid;

        public UidState(int uid) {
            this.uid = uid;
@@ -545,7 +544,6 @@ public class AppOpsService extends IAppOpsService.Stub {
                    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.
@@ -611,7 +609,6 @@ public class AppOpsService extends IAppOpsService.Stub {
                    case OP_CAMERA:
                        if (mActivityManagerInternal != null
                                && mActivityManagerInternal.isPendingTopUid(uid)) {
                            maybeLogPendingTopUid(op, mode);
                            return MODE_ALLOWED;
                        } else if ((capability & PROCESS_CAPABILITY_FOREGROUND_CAMERA) != 0) {
                            return MODE_ALLOWED;
@@ -629,7 +626,6 @@ public class AppOpsService extends IAppOpsService.Stub {
                    case OP_RECORD_AUDIO:
                        if (mActivityManagerInternal != null
                                && mActivityManagerInternal.isPendingTopUid(uid)) {
                            maybeLogPendingTopUid(op, mode);
                            return MODE_ALLOWED;
                        } else if ((capability & PROCESS_CAPABILITY_FOREGROUND_MICROPHONE) != 0) {
                            return MODE_ALLOWED;
@@ -709,7 +705,7 @@ public class AppOpsService extends IAppOpsService.Stub {
            if (mode == DEBUG_FGS_ALLOW_WHILE_IN_USE && state != UID_STATE_FOREGROUND_SERVICE) {
                return;
            }
            final long now = System.currentTimeMillis();
            final long now = SystemClock.elapsedRealtime();
            if (lastTimeShowDebugToast == 0 ||  now - lastTimeShowDebugToast > 600000) {
                lastTimeShowDebugToast = now;
                mHandler.sendMessage(PooledLambda.obtainMessage(
@@ -717,19 +713,6 @@ 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> {
Loading