Merge "Fix issue #38037532: Toasts cause apps to become foreground" into oc-dev

am: 1801f688b9

Change-Id: Ib812e0357e50b5af010552d0ef18d27e071370b2
This commit is contained in:
Dianne Hackborn
2017-05-07 01:07:41 +00:00
committed by android-build-merger
6 changed files with 87 additions and 45 deletions

View File

@@ -200,7 +200,7 @@ interface IActivityManager {
void setRequestedOrientation(in IBinder token, int requestedOrientation);
int getRequestedOrientation(in IBinder token);
void unbindFinished(in IBinder token, in Intent service, boolean doRebind);
void setProcessForeground(in IBinder token, int pid, boolean isForeground);
void setProcessImportant(in IBinder token, int pid, boolean isForeground, String reason);
void setServiceForeground(in ComponentName className, in IBinder token,
int id, in Notification notification, int flags);
boolean moveActivityTaskToBack(in IBinder token, boolean nonRoot);

View File

@@ -622,6 +622,17 @@ public final class ActiveServices {
!= ActivityManager.APP_START_MODE_NORMAL) {
if (stopping == null) {
stopping = new ArrayList<>();
String compName = service.name.flattenToShortString();
EventLogTags.writeAmStopIdleService(service.appInfo.uid, compName);
StringBuilder sb = new StringBuilder(64);
sb.append("Stopping service due to app idle: ");
UserHandle.formatUid(sb, service.appInfo.uid);
sb.append(" ");
TimeUtils.formatDuration(service.createTime
- SystemClock.elapsedRealtime(), sb);
sb.append(" ");
sb.append(compName);
Slog.w(TAG, sb.toString());
stopping.add(service);
}
}

View File

@@ -812,15 +812,28 @@ public class ActivityManagerService extends IActivityManager.Stub
final SparseArray<ProcessRecord> mPidsSelfLocked = new SparseArray<ProcessRecord>();
/**
* All of the processes that have been forced to be foreground. The key
* All of the processes that have been forced to be important. The key
* is the pid of the caller who requested it (we hold a death
* link on it).
*/
abstract class ForegroundToken implements IBinder.DeathRecipient {
int pid;
IBinder token;
abstract class ImportanceToken implements IBinder.DeathRecipient {
final int pid;
final IBinder token;
final String reason;
ImportanceToken(int _pid, IBinder _token, String _reason) {
pid = _pid;
token = _token;
reason = _reason;
}
@Override
public String toString() {
return "ImportanceToken { " + Integer.toHexString(System.identityHashCode(this))
+ " " + reason + " " + pid + " " + token + " }";
}
}
final SparseArray<ForegroundToken> mForegroundProcesses = new SparseArray<ForegroundToken>();
final SparseArray<ImportanceToken> mImportantProcesses = new SparseArray<ImportanceToken>();
/**
* List of records for processes that someone had tried to start before the
@@ -6499,6 +6512,7 @@ public class ActivityManagerService extends IActivityManager.Stub
if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
"No more processes in " + old.uidRecord);
enqueueUidChangeLocked(old.uidRecord, -1, UidRecord.CHANGE_GONE);
EventLogTags.writeAmUidStopped(uid);
mActiveUids.remove(uid);
noteUidProcessState(uid, ActivityManager.PROCESS_STATE_NONEXISTENT);
}
@@ -6530,6 +6544,7 @@ public class ActivityManagerService extends IActivityManager.Stub
}
uidRec.updateHasInternetPermission();
mActiveUids.put(proc.uid, uidRec);
EventLogTags.writeAmUidRunning(uidRec.uid);
noteUidProcessState(uidRec.uid, uidRec.curProcState);
enqueueUidChangeLocked(uidRec, -1, UidRecord.CHANGE_ACTIVE);
}
@@ -6717,7 +6732,7 @@ public class ActivityManagerService extends IActivityManager.Stub
app.makeActive(thread, mProcessStats);
app.curAdj = app.setAdj = app.verifiedAdj = ProcessList.INVALID_ADJ;
app.curSchedGroup = app.setSchedGroup = ProcessList.SCHED_GROUP_DEFAULT;
app.forcingToForeground = null;
app.forcingToImportant = null;
updateProcessForegroundLocked(app, false, false);
app.hasShownUi = false;
app.debugging = false;
@@ -7717,20 +7732,20 @@ public class ActivityManagerService extends IActivityManager.Stub
}
}
void foregroundTokenDied(ForegroundToken token) {
void importanceTokenDied(ImportanceToken token) {
synchronized (ActivityManagerService.this) {
synchronized (mPidsSelfLocked) {
ForegroundToken cur
= mForegroundProcesses.get(token.pid);
ImportanceToken cur
= mImportantProcesses.get(token.pid);
if (cur != token) {
return;
}
mForegroundProcesses.remove(token.pid);
mImportantProcesses.remove(token.pid);
ProcessRecord pr = mPidsSelfLocked.get(token.pid);
if (pr == null) {
return;
}
pr.forcingToForeground = null;
pr.forcingToImportant = null;
updateProcessForegroundLocked(pr, false, false);
}
updateOomAdjLocked();
@@ -7738,9 +7753,9 @@ public class ActivityManagerService extends IActivityManager.Stub
}
@Override
public void setProcessForeground(IBinder token, int pid, boolean isForeground) {
public void setProcessImportant(IBinder token, int pid, boolean isForeground, String reason) {
enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
"setProcessForeground()");
"setProcessImportant()");
synchronized(this) {
boolean changed = false;
@@ -7750,28 +7765,26 @@ public class ActivityManagerService extends IActivityManager.Stub
Slog.w(TAG, "setProcessForeground called on unknown pid: " + pid);
return;
}
ForegroundToken oldToken = mForegroundProcesses.get(pid);
ImportanceToken oldToken = mImportantProcesses.get(pid);
if (oldToken != null) {
oldToken.token.unlinkToDeath(oldToken, 0);
mForegroundProcesses.remove(pid);
mImportantProcesses.remove(pid);
if (pr != null) {
pr.forcingToForeground = null;
pr.forcingToImportant = null;
}
changed = true;
}
if (isForeground && token != null) {
ForegroundToken newToken = new ForegroundToken() {
ImportanceToken newToken = new ImportanceToken(pid, token, reason) {
@Override
public void binderDied() {
foregroundTokenDied(this);
importanceTokenDied(this);
}
};
newToken.pid = pid;
newToken.token = token;
try {
token.linkToDeath(newToken, 0);
mForegroundProcesses.put(pid, newToken);
pr.forcingToForeground = token;
mImportantProcesses.put(pid, newToken);
pr.forcingToImportant = newToken;
changed = true;
} catch (RemoteException e) {
// If the process died while doing this, we will later
@@ -15491,12 +15504,12 @@ public class ActivityManagerService extends IActivityManager.Stub
}
}
if (mForegroundProcesses.size() > 0) {
if (mImportantProcesses.size() > 0) {
synchronized (mPidsSelfLocked) {
boolean printed = false;
for (int i=0; i<mForegroundProcesses.size(); i++) {
for (int i = 0; i< mImportantProcesses.size(); i++) {
ProcessRecord r = mPidsSelfLocked.get(
mForegroundProcesses.valueAt(i).pid);
mImportantProcesses.valueAt(i).pid);
if (dumpPackage != null && (r == null
|| !r.pkgList.containsKey(dumpPackage))) {
continue;
@@ -15508,8 +15521,8 @@ public class ActivityManagerService extends IActivityManager.Stub
printed = true;
printedAnything = true;
}
pw.print(" PID #"); pw.print(mForegroundProcesses.keyAt(i));
pw.print(": "); pw.println(mForegroundProcesses.valueAt(i));
pw.print(" PID #"); pw.print(mImportantProcesses.keyAt(i));
pw.print(": "); pw.println(mImportantProcesses.valueAt(i));
}
}
}
@@ -17780,7 +17793,7 @@ public class ActivityManagerService extends IActivityManager.Stub
app.unlinkDeathRecipient();
app.makeInactive(mProcessStats);
app.waitingToKill = null;
app.forcingToForeground = null;
app.forcingToImportant = null;
updateProcessForegroundLocked(app, false, false);
app.foregroundActivities = false;
app.hasShownUi = false;
@@ -20775,14 +20788,6 @@ public class ActivityManagerService extends IActivityManager.Stub
app.cached = false;
app.adjType = "fg-service";
schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
} else if (app.forcingToForeground != null) {
// The user is aware of this app, so make it visible.
adj = ProcessList.PERCEPTIBLE_APP_ADJ;
procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
app.cached = false;
app.adjType = "force-fg";
app.adjSource = app.forcingToForeground;
schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
} else if (app.hasOverlayUi) {
// The process is display an overlay UI.
adj = ProcessList.PERCEPTIBLE_APP_ADJ;
@@ -20793,6 +20798,21 @@ public class ActivityManagerService extends IActivityManager.Stub
}
}
if (adj > ProcessList.PERCEPTIBLE_APP_ADJ
|| procState > ActivityManager.PROCESS_STATE_TRANSIENT_BACKGROUND) {
if (app.forcingToImportant != null) {
// This is currently used for toasts... they are not interactive, and
// we don't want them to cause the app to become fully foreground (and
// thus out of background check), so we yes the best background level we can.
adj = ProcessList.PERCEPTIBLE_APP_ADJ;
procState = ActivityManager.PROCESS_STATE_TRANSIENT_BACKGROUND;
app.cached = false;
app.adjType = "force-imp";
app.adjSource = app.forcingToImportant;
schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
}
}
if (app == mHeavyWeightProcess) {
if (adj > ProcessList.HEAVY_WEIGHT_APP_ADJ) {
// We don't want to kill the current heavy-weight process.
@@ -22033,10 +22053,7 @@ public class ActivityManagerService extends IActivityManager.Stub
+ mConstants.SERVICE_USAGE_INTERACTION_TIME;
}
} else {
// If the app was being forced to the foreground, by say a Toast, then
// no need to treat it as an interaction
isInteraction = app.forcingToForeground == null
&& app.curProcState <= ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
isInteraction = app.curProcState <= ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
app.fgInteractionTime = 0;
}
if (isInteraction && (!app.reportedInteraction || (nowElapsed-app.interactionEventTime)
@@ -22574,6 +22591,7 @@ public class ActivityManagerService extends IActivityManager.Stub
} else {
if (uidRec.idle) {
uidChange = UidRecord.CHANGE_ACTIVE;
EventLogTags.writeAmUidActive(uidRec.uid);
uidRec.idle = false;
}
uidRec.lastBackgroundTime = 0;
@@ -22652,6 +22670,7 @@ public class ActivityManagerService extends IActivityManager.Stub
if (UserHandle.getAppId(uidRec.uid) == appId) {
if (userId == UserHandle.USER_ALL ||
userId == UserHandle.getUserId(uidRec.uid)) {
EventLogTags.writeAmUidIdle(uidRec.uid);
uidRec.idle = true;
Slog.w(TAG, "Idling uid " + UserHandle.formatUid(uidRec.uid)
+ " from package " + packageName + " user " + userId);
@@ -22686,6 +22705,7 @@ public class ActivityManagerService extends IActivityManager.Stub
final long bgTime = uidRec.lastBackgroundTime;
if (bgTime > 0 && !uidRec.idle) {
if (bgTime <= maxBgTime) {
EventLogTags.writeAmUidIdle(uidRec.uid);
uidRec.idle = true;
doStopUidLocked(uidRec.uid, uidRec);
} else {

View File

@@ -114,3 +114,14 @@ option java_package com.android.server.am
# UserState has changed
30051 am_user_state_changed (id|1|5),(state|1|5)
# Note when any processes of a uid have started running
30052 am_uid_running (UID|1|5)
# Note when all processes of a uid have stopped.
30053 am_uid_stopped (UID|1|5)
# Note when the state of a uid has become active.
30054 am_uid_active (UID|1|5)
# Note when the state of a uid has become idle (background check enforced).
30055 am_uid_idle (UID|1|5)
# Note when a service is being forcibly stopped because its app went idle.
30056 am_stop_idle_service (UID|1|5),(Component Name|3)

View File

@@ -135,7 +135,7 @@ final class ProcessRecord {
long interactionEventTime; // The time we sent the last interaction event
long fgInteractionTime; // When we became foreground for interaction purposes
String waitingToKill; // Process is waiting to be killed when in the bg, and reason
IBinder forcingToForeground;// Token that is forcing this process to be foreground
Object forcingToImportant; // Token that is forcing this process to be important
int adjSeq; // Sequence id for identifying oom_adj assignment cycles
int lruSeq; // Sequence id for identifying LRU update cycles
CompatibilityInfo compat; // last used compatibility mode
@@ -302,9 +302,9 @@ final class ProcessRecord {
pw.print(" hasAboveClient="); pw.print(hasAboveClient);
pw.print(" treatLikeActivity="); pw.println(treatLikeActivity);
}
if (foregroundServices || forcingToForeground != null) {
if (foregroundServices || forcingToImportant != null) {
pw.print(prefix); pw.print("foregroundServices="); pw.print(foregroundServices);
pw.print(" forcingToForeground="); pw.println(forcingToForeground);
pw.print(" forcingToImportant="); pw.println(forcingToImportant);
}
if (reportedInteraction || fgInteractionTime != 0) {
pw.print(prefix); pw.print("reportedInteraction=");

View File

@@ -3935,7 +3935,7 @@ public class NotificationManagerService extends SystemService {
}
}
try {
mAm.setProcessForeground(mForegroundToken, pid, toastCount > 0);
mAm.setProcessImportant(mForegroundToken, pid, toastCount > 0, "toast");
} catch (RemoteException e) {
// Shouldn't happen.
}