Call ensureActivitiesVisibleLocked from supervisor.
- Don't call ActivityStack.ensureActivitiesVisibleLocked directly.
Instead call ActivityStackSupervisor.ensureActivitiesVisibleLocked.
- Add detecting monochrome screenshots to black screenshots.
- minor refactors.
Change-Id: I050b1cd40cacaab451f1460a77a82125a8077ff2
diff --git a/services/java/com/android/server/am/ActivityManagerService.java b/services/java/com/android/server/am/ActivityManagerService.java
index 0e2b4a4..c34b4ec 100644
--- a/services/java/com/android/server/am/ActivityManagerService.java
+++ b/services/java/com/android/server/am/ActivityManagerService.java
@@ -4597,7 +4597,7 @@
synchronized(this) {
ActivityStack stack = ActivityRecord.getStackLocked(token);
if (stack != null) {
- stack.activityResumedLocked(token);
+ ActivityRecord.activityResumedLocked(token);
}
}
Binder.restoreCallingIdentity(origId);
diff --git a/services/java/com/android/server/am/ActivityRecord.java b/services/java/com/android/server/am/ActivityRecord.java
index 88bcdab..51b9984 100644
--- a/services/java/com/android/server/am/ActivityRecord.java
+++ b/services/java/com/android/server/am/ActivityRecord.java
@@ -54,6 +54,9 @@
* An entry in the history stack, representing an activity.
*/
final class ActivityRecord {
+ static final String TAG = ActivityManagerService.TAG;
+ static final boolean DEBUG_SAVED_STATE = ActivityStackSupervisor.DEBUG_SAVED_STATE;
+
final ActivityManagerService service; // owner
final IApplicationToken.Stub appToken; // window manager token
final ActivityInfo info; // all about me
@@ -295,10 +298,7 @@
@Override public boolean keyDispatchingTimedOut() {
ActivityRecord activity = weakActivity.get();
- if (activity != null) {
- return activity.keyDispatchingTimedOut();
- }
- return false;
+ return activity != null && activity.keyDispatchingTimedOut();
}
@Override public long getKeyDispatchingTimeout() {
@@ -417,10 +417,10 @@
if (intent != null && (aInfo.flags & ActivityInfo.FLAG_EXCLUDE_FROM_RECENTS) != 0) {
intent.addFlags(Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
}
-
+
packageName = aInfo.applicationInfo.packageName;
launchMode = aInfo.launchMode;
-
+
AttributeCache.Entry ent = AttributeCache.instance().get(packageName,
realTheme, com.android.internal.R.styleable.Window);
fullscreen = ent != null && !ent.array.getBoolean(
@@ -429,30 +429,24 @@
com.android.internal.R.styleable.Window_windowIsTranslucent, false);
noDisplay = ent != null && ent.array.getBoolean(
com.android.internal.R.styleable.Window_windowNoDisplay, false);
-
- if (!_componentSpecified || _launchedFromUid == Process.myUid()
- || _launchedFromUid == 0) {
- // If we know the system has determined the component, then
- // we can consider this to be a home activity...
- if (Intent.ACTION_MAIN.equals(_intent.getAction()) &&
- _intent.hasCategory(Intent.CATEGORY_HOME) &&
- _intent.getCategories().size() == 1 &&
- _intent.getData() == null &&
- _intent.getType() == null &&
- (intent.getFlags()&Intent.FLAG_ACTIVITY_NEW_TASK) != 0 &&
- !ResolverActivity.class.getName().equals(realActivity.getClassName())) {
+
+ // If we know the system has determined the component, then
+ // we can consider this to be a home activity...
+ // Note the last check is so we don't count the resolver
+ // activity as being home... really, we don't care about
+ // doing anything special with something that comes from
+ // the core framework package.
+ isHomeActivity =
+ (!_componentSpecified || _launchedFromUid == Process.myUid()
+ || _launchedFromUid == 0) &&
+ Intent.ACTION_MAIN.equals(_intent.getAction()) &&
+ _intent.hasCategory(Intent.CATEGORY_HOME) &&
+ _intent.getCategories().size() == 1 &&
+ _intent.getData() == null &&
+ _intent.getType() == null &&
+ (intent.getFlags()&Intent.FLAG_ACTIVITY_NEW_TASK) != 0 &&
+ !ResolverActivity.class.getName().equals(realActivity.getClassName());
// This sure looks like a home activity!
- // Note the last check is so we don't count the resolver
- // activity as being home... really, we don't care about
- // doing anything special with something that comes from
- // the core framework package.
- isHomeActivity = true;
- } else {
- isHomeActivity = false;
- }
- } else {
- isHomeActivity = false;
- }
immersive = (aInfo.flags & ActivityInfo.FLAG_IMMERSIVE) != 0;
} else {
@@ -580,7 +574,7 @@
}
newIntents.add(intent);
}
-
+
/**
* Deliver a new Intent to an existing activity, so that its onNewIntent()
* method will be called at the proper time.
@@ -714,9 +708,6 @@
}
void updateThumbnail(Bitmap newThumbnail, CharSequence description) {
- if ((intent.getFlags()&Intent.FLAG_ACTIVITY_CLEAR_WHEN_TASK_RESET) != 0) {
- // This is a logical break in the task; it repre
- }
if (thumbHolder != null) {
if (newThumbnail != null) {
if (ActivityManagerService.DEBUG_THUMBNAILS) Slog.i(ActivityManagerService.TAG,
@@ -764,20 +755,20 @@
// so it is best to leave as-is.
return app != null && !app.crashing && !app.notResponding;
}
-
+
public void startFreezingScreenLocked(ProcessRecord app, int configChanges) {
if (mayFreezeScreenLocked(app)) {
service.mWindowManager.startAppFreezingScreen(appToken, configChanges);
}
}
-
+
public void stopFreezingScreenLocked(boolean force) {
if (force || frozenBeforeDestroy) {
frozenBeforeDestroy = false;
service.mWindowManager.stopAppFreezingScreen(appToken, force);
}
}
-
+
public void windowsDrawn() {
synchronized(service) {
if (launchTime != 0) {
@@ -817,7 +808,6 @@
public void windowsVisible() {
synchronized(service) {
- final ActivityStack stack = task.stack;
mStackSupervisor.reportActivityVisibleLocked(this);
if (ActivityManagerService.DEBUG_SWITCH) Log.v(
ActivityManagerService.TAG, "windowsVisible(): " + this);
@@ -858,7 +848,7 @@
ActivityManagerService.TAG, "windowsGone(): " + this);
nowVisible = false;
}
-
+
private ActivityRecord getWaitingHistoryRecordLocked() {
// First find the real culprit... if we are waiting
// for another app to start, then we have paused dispatching
@@ -876,7 +866,7 @@
r = this;
}
}
-
+
return r;
}
@@ -889,7 +879,7 @@
}
return service.inputDispatchingTimedOut(anrApp, r, this, false);
}
-
+
/** Returns the key dispatching timeout for this application token. */
public long getKeyDispatchingTimeout() {
synchronized(service) {
@@ -903,7 +893,7 @@
* currently pausing, or is resumed.
*/
public boolean isInterestingToUserLocked() {
- return visible || nowVisible || state == ActivityState.PAUSING ||
+ return visible || nowVisible || state == ActivityState.PAUSING ||
state == ActivityState.RESUMED;
}
@@ -926,6 +916,13 @@
}
}
+ static void activityResumedLocked(IBinder token) {
+ final ActivityRecord r = ActivityRecord.forToken(token);
+ if (DEBUG_SAVED_STATE) Slog.i(TAG, "Resumed activity; dropping state of: " + r);
+ r.icicle = null;
+ r.haveState = false;
+ }
+
static int getTaskForActivityLocked(IBinder token, boolean onlyRoot) {
final ActivityRecord r = ActivityRecord.forToken(token);
if (r == null) {
@@ -947,7 +944,7 @@
return null;
}
- static final ActivityStack getStackLocked(IBinder token) {
+ static ActivityStack getStackLocked(IBinder token) {
final ActivityRecord r = ActivityRecord.isInStackLocked(token);
if (r != null) {
return r.task.stack;
diff --git a/services/java/com/android/server/am/ActivityStack.java b/services/java/com/android/server/am/ActivityStack.java
index 5162319..4787a1e 100644
--- a/services/java/com/android/server/am/ActivityStack.java
+++ b/services/java/com/android/server/am/ActivityStack.java
@@ -291,8 +291,7 @@
mService.logAppTooSlow(r.app, r.pauseTime,
"pausing " + r);
}
-
- activityPausedLocked(r != null ? r.appToken : null, true);
+ activityPausedLocked(r.appToken, true);
}
} break;
case LAUNCH_TICK_MSG: {
@@ -581,7 +580,7 @@
* matters on the home stack. All other stacks are single user.
* @return whether there are any activities for the specified user.
*/
- final boolean switchUserLocked(int userId, UserStartedState uss) {
+ final boolean switchUserLocked(int userId) {
if (VALIDATE_TOKENS) {
validateAppTokensLocked();
}
@@ -592,10 +591,9 @@
// Move userId's tasks to the top.
boolean haveActivities = false;
- TaskRecord task = null;
int index = mTaskHistory.size();
for (int i = 0; i < index; ++i) {
- task = mTaskHistory.get(i);
+ TaskRecord task = mTaskHistory.get(i);
if (task.userId == userId) {
haveActivities = true;
mTaskHistory.remove(i);
@@ -840,13 +838,6 @@
}
}
- final void activityResumedLocked(IBinder token) {
- final ActivityRecord r = ActivityRecord.forToken(token);
- if (DEBUG_SAVED_STATE) Slog.i(TAG, "Resumed activity; dropping state of: " + r);
- r.icicle = null;
- r.haveState = false;
- }
-
final void activityPausedLocked(IBinder token, boolean timeout) {
if (DEBUG_PAUSE) Slog.v(
TAG, "Activity paused: token=" + token + ", timeout=" + timeout);
@@ -1065,8 +1056,7 @@
boolean showHomeBehindStack = false;
boolean behindFullscreen = !mStackSupervisor.isFrontStack(this) &&
!(forceHomeShown && isHomeStack());
- int taskNdx;
- for (taskNdx = mTaskHistory.size() - 1; taskNdx >= 0; --taskNdx) {
+ for (int taskNdx = mTaskHistory.size() - 1; taskNdx >= 0; --taskNdx) {
final ArrayList<ActivityRecord> activities = mTaskHistory.get(taskNdx).mActivities;
for (int activityNdx = activities.size() - 1; activityNdx >= 0; --activityNdx) {
final ActivityRecord r = activities.get(activityNdx);
@@ -2214,7 +2204,7 @@
// If this activity is fullscreen, set up to hide those under it.
if (DEBUG_VISBILITY) Slog.v(TAG, "Idle activity for " + res);
- ensureActivitiesVisibleLocked(null, 0);
+ mStackSupervisor.ensureActivitiesVisibleLocked(null, 0);
}
return res;
@@ -3428,7 +3418,7 @@
// activities are running, taking care of restarting this
// process.
if (hasVisibleActivities) {
- ensureActivitiesVisibleLocked(null, 0);
+ mStackSupervisor.ensureActivitiesVisibleLocked(null, 0);
}
}
}
diff --git a/services/java/com/android/server/am/ActivityStackSupervisor.java b/services/java/com/android/server/am/ActivityStackSupervisor.java
index 60b7061..69e9f76 100644
--- a/services/java/com/android/server/am/ActivityStackSupervisor.java
+++ b/services/java/com/android/server/am/ActivityStackSupervisor.java
@@ -52,6 +52,7 @@
import android.content.res.Configuration;
import android.os.Binder;
import android.os.Bundle;
+import android.os.Debug;
import android.os.Handler;
import android.os.IBinder;
import android.os.Looper;
@@ -84,6 +85,7 @@
static final boolean DEBUG_APP = DEBUG || false;
static final boolean DEBUG_SAVED_STATE = DEBUG || false;
static final boolean DEBUG_STATES = DEBUG || false;
+ static final boolean DEBUG_IDLE = DEBUG || false;
public static final int HOME_STACK_ID = 0;
@@ -347,11 +349,12 @@
+ hr.intent.getComponent().flattenToShortString(), e);
throw e;
}
- } else {
- stack.ensureActivitiesVisibleLocked(hr, null, processName, 0, false);
}
}
}
+ if (!didSomething) {
+ ensureActivitiesVisibleLocked(null, 0);
+ }
return didSomething;
}
@@ -1637,6 +1640,8 @@
ActivityRecord r = ActivityRecord.forToken(token);
if (r != null) {
+ if (DEBUG_IDLE) Slog.d(TAG, "activityIdleInternalLocked: Callers=" +
+ Debug.getCallers(4));
mHandler.removeMessages(IDLE_TIMEOUT_MSG, r);
r.finishLaunchTickingLocked();
res = r.task.stack.activityIdleInternalLocked(token, fromTimeout, config);
@@ -1996,7 +2001,7 @@
}
mStartingUsers.add(uss);
- boolean haveActivities = mHomeStack.switchUserLocked(userId, uss);
+ boolean haveActivities = mHomeStack.switchUserLocked(userId);
resumeTopActivitiesLocked();
@@ -2211,6 +2216,7 @@
}
void scheduleIdleTimeoutLocked(ActivityRecord next) {
+ if (DEBUG_IDLE) Slog.d(TAG, "scheduleIdleTimeoutLocked: Callers=" + Debug.getCallers(4));
Message msg = mHandler.obtainMessage(IDLE_TIMEOUT_MSG, next);
mHandler.sendMessageDelayed(msg, IDLE_TIMEOUT);
}
@@ -2220,6 +2226,7 @@
}
void removeTimeoutsForActivityLocked(ActivityRecord r) {
+ if (DEBUG_IDLE) Slog.d(TAG, "removeTimeoutsForActivity: Callers=" + Debug.getCallers(4));
mHandler.removeMessages(IDLE_TIMEOUT_MSG, r);
}
@@ -2243,6 +2250,8 @@
public void handleMessage(Message msg) {
switch (msg.what) {
case IDLE_TIMEOUT_MSG: {
+ if (DEBUG_IDLE) Slog.d(TAG, "handleMessage: IDLE_TIMEOUT_MSG: Callers=" +
+ Debug.getCallers(4));
if (mService.mDidDexOpt) {
mService.mDidDexOpt = false;
Message nmsg = mHandler.obtainMessage(IDLE_TIMEOUT_MSG);
diff --git a/services/java/com/android/server/wm/WindowManagerService.java b/services/java/com/android/server/wm/WindowManagerService.java
index f963f11..948d234 100644
--- a/services/java/com/android/server/wm/WindowManagerService.java
+++ b/services/java/com/android/server/wm/WindowManagerService.java
@@ -5648,14 +5648,16 @@
int[] buffer = new int[bm.getWidth() * bm.getHeight()];
bm.getPixels(buffer, 0, bm.getWidth(), 0, 0, bm.getWidth(), bm.getHeight());
boolean allBlack = true;
+ final int firstColor = buffer[0];
for (int i = 0; i < buffer.length; i++) {
- if (buffer[i] != Color.BLACK) {
+ if (buffer[i] != firstColor) {
allBlack = false;
break;
}
}
if (allBlack) {
- Slog.i(TAG, "Screenshot " + appWin + " was all black! mSurfaceLayer=" +
+ Slog.i(TAG, "Screenshot " + appWin + " was monochrome(" +
+ Integer.toHexString(firstColor) + ")! mSurfaceLayer=" +
(appWin != null ? appWin.mWinAnimator.mSurfaceLayer : "null") +
" minLayer=" + minLayer + " maxLayer=" + maxLayer);
}