Merge "Check PendingStartActivityUids list before updateOomAdj is done." into rvc-dev am: 600ce540ca am: 20710498ee am: 5b95c916c5
Change-Id: Ibc31718f6e0626b6190560cd25f529c512c71339
This commit is contained in:
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -938,6 +938,7 @@ public final class OomAdjuster {
|
||||
mService.mServices.foregroundServiceProcStateChangedLocked(uidRec);
|
||||
}
|
||||
}
|
||||
mService.mInternal.updatePendingTopUid(uidRec.uid, false);
|
||||
}
|
||||
if (mLocalPowerManager != null) {
|
||||
mLocalPowerManager.finishUidChanges();
|
||||
|
||||
@@ -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> {
|
||||
|
||||
@@ -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.
|
||||
|
||||
Reference in New Issue
Block a user