Unify Activity level of window hierarchy (50/n).
Make ActivityRecord extend AppWindowToken so we have a single object
for acitvities in the hierarchy.
Bug: 80414790
Test: Existing tests pass.
Change-Id: Ia7f52ef444cba88223f4e8a9586f6c12b1b5e4ea
diff --git a/services/core/java/com/android/server/wm/AppWindowToken.java b/services/core/java/com/android/server/wm/AppWindowToken.java
index 2668628..721de61 100644
--- a/services/core/java/com/android/server/wm/AppWindowToken.java
+++ b/services/core/java/com/android/server/wm/AppWindowToken.java
@@ -21,8 +21,15 @@
import static android.app.WindowConfiguration.WINDOWING_MODE_SPLIT_SCREEN_PRIMARY;
import static android.app.WindowConfiguration.WINDOWING_MODE_UNDEFINED;
import static android.content.pm.ActivityInfo.COLOR_MODE_DEFAULT;
+import static android.content.pm.ActivityInfo.FLAG_ALWAYS_FOCUSABLE;
+import static android.content.pm.ActivityInfo.FLAG_INHERIT_SHOW_WHEN_LOCKED;
+import static android.content.pm.ActivityInfo.FLAG_SHOW_FOR_ALL_USERS;
+import static android.content.pm.ActivityInfo.FLAG_TURN_SCREEN_ON;
+import static android.content.pm.ActivityInfo.LAUNCH_MULTIPLE;
+import static android.content.pm.ActivityInfo.LAUNCH_SINGLE_TOP;
import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_BEHIND;
import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_UNSET;
+import static android.os.Build.VERSION_CODES.HONEYCOMB;
import static android.os.Trace.TRACE_TAG_WINDOW_MANAGER;
import static android.view.WindowManager.LayoutParams.FLAG_DISMISS_KEYGUARD;
import static android.view.WindowManager.LayoutParams.FLAG_SECURE;
@@ -62,6 +69,9 @@
import static com.android.server.wm.AppWindowTokenProto.STARTING_WINDOW;
import static com.android.server.wm.AppWindowTokenProto.THUMBNAIL;
import static com.android.server.wm.AppWindowTokenProto.WINDOW_TOKEN;
+import static com.android.server.wm.IdentifierProto.HASH_CODE;
+import static com.android.server.wm.IdentifierProto.TITLE;
+import static com.android.server.wm.IdentifierProto.USER_ID;
import static com.android.server.wm.ProtoLogGroup.WM_DEBUG_ADD_REMOVE;
import static com.android.server.wm.ProtoLogGroup.WM_DEBUG_APP_TRANSITIONS;
import static com.android.server.wm.ProtoLogGroup.WM_DEBUG_APP_TRANSITIONS_ANIM;
@@ -84,12 +94,17 @@
import static com.android.server.wm.WindowStateAnimator.STACK_CLIP_BEFORE_ANIM;
import android.annotation.CallSuper;
+import android.annotation.Nullable;
import android.annotation.Size;
import android.app.Activity;
import android.app.ActivityManager;
+import android.app.ActivityOptions;
import android.content.ComponentName;
+import android.content.Intent;
+import android.content.pm.ActivityInfo;
import android.content.res.CompatibilityInfo;
import android.content.res.Configuration;
+import android.content.res.Resources;
import android.graphics.GraphicBuffer;
import android.graphics.PixelFormat;
import android.graphics.Point;
@@ -98,14 +113,13 @@
import android.os.Build;
import android.os.Debug;
import android.os.IBinder;
-import android.os.RemoteException;
import android.os.SystemClock;
import android.os.Trace;
+import android.os.UserHandle;
import android.util.ArraySet;
import android.util.Slog;
import android.util.proto.ProtoOutputStream;
import android.view.DisplayInfo;
-import android.view.IApplicationToken;
import android.view.InputApplicationHandle;
import android.view.RemoteAnimationAdapter;
import android.view.RemoteAnimationDefinition;
@@ -140,8 +154,8 @@
* Version of WindowToken that is specifically for a particular application (or
* really activity) that is displaying windows.
*/
-class AppWindowToken extends WindowToken implements WindowManagerService.AppFreezeListener,
- ConfigurationContainerListener {
+// TODO: Fully merge this class into ActivityRecord class since they are really the same thing...
+class AppWindowToken extends WindowToken implements WindowManagerService.AppFreezeListener {
private static final String TAG = TAG_WITH_CLASS_NAME ? "AppWindowToken" : TAG_WM;
/**
@@ -149,17 +163,36 @@
*/
@VisibleForTesting static final int Z_BOOST_BASE = 800570000;
+ final ActivityTaskManagerService mAtmService;
// Non-null only for application tokens.
- final IApplicationToken appToken;
+ // TODO: rename to mActivityToken
+ final ActivityRecord.Token appToken;
+ // All about me
+ final ActivityInfo mActivityInfo;
+ // Which user is this running for?
+ final int mUserId;
+ // The package implementing intent's component
+ // TODO: rename to mPackageName
+ final String packageName;
+ // the intent component, or target of an alias.
final ComponentName mActivityComponent;
- final boolean mVoiceInteraction;
+ boolean mVoiceInteraction;
/**
* The activity is opaque and fills the entire space of this task.
* @see WindowContainer#fillsParent()
*/
private boolean mOccludesParent;
+ // Has a wallpaper window as a background.
+ // TODO: Rename to mHasWallpaper and also see if it possible to combine this with the
+ // mOccludesParent field.
+ final boolean hasWallpaper;
+ // activity is not displayed?
+ // TODO: rename to mNoDisplay
+ @VisibleForTesting
+ boolean noDisplay;
boolean mShowForAllUsers;
+ // TODO: Make this final
int mTargetSdk;
// Flag set while reparenting to prevent actions normally triggered by an individual parent
@@ -234,10 +267,12 @@
boolean mLaunchTaskBehind;
boolean mEnteringAnimation;
- private boolean mAlwaysFocusable;
-
boolean mAppStopped;
- int mRotationAnimationHint;
+ // A hint to override the window specified rotation animation, or -1 to use the window specified
+ // value. We use this so that we can select the right animation in the cases of starting
+ // windows, where the app hasn't had time to set a value on the window.
+ int mRotationAnimationHint = -1;
+
private int mPendingRelaunchCount;
private boolean mLastContainsShowWhenLockedWindow;
@@ -261,9 +296,6 @@
private Task mLastParent;
- // TODO: Remove after unification
- ActivityRecord mActivityRecord;
-
/**
* @see #currentLaunchCanTurnScreenOn()
*/
@@ -327,6 +359,10 @@
private static final int STARTING_WINDOW_TYPE_SNAPSHOT = 1;
private static final int STARTING_WINDOW_TYPE_SPLASH_SCREEN = 2;
+ private boolean mShowWhenLocked;
+ private boolean mInheritShownWhenLocked;
+ private boolean mTurnScreenOn;
+
private AppSaturationInfo mLastAppSaturationInfo;
private final ColorDisplayService.ColorTransformController mColorTransformController =
@@ -341,23 +377,67 @@
}
});
- AppWindowToken(WindowManagerService service, IApplicationToken token,
- ComponentName activityComponent, boolean voiceInteraction, DisplayContent dc,
- long inputDispatchingTimeoutNanos, boolean fullscreen, boolean showForAllUsers,
- int targetSdk, int orientation, int rotationAnimationHint,
- boolean launchTaskBehind, boolean alwaysFocusable,
- ActivityRecord activityRecord) {
- this(service, token, activityComponent, voiceInteraction, dc, fullscreen);
- // TODO: remove after unification
- mActivityRecord = activityRecord;
- mActivityRecord.registerConfigurationChangeListener(this);
- mInputDispatchingTimeoutNanos = inputDispatchingTimeoutNanos;
- mShowForAllUsers = showForAllUsers;
- mTargetSdk = targetSdk;
- mOrientation = orientation;
- mLaunchTaskBehind = launchTaskBehind;
- mAlwaysFocusable = alwaysFocusable;
- mRotationAnimationHint = rotationAnimationHint;
+ AppWindowToken(WindowManagerService service, ActivityTaskManagerService atm,
+ ActivityRecord.Token token, ActivityInfo aInfo, ActivityOptions options, Intent intent,
+ DisplayContent dc) {
+ super(service, token != null ? token.asBinder() : null, TYPE_APPLICATION, true, dc,
+ false /* ownerCanManageAppTokens */);
+ mAtmService = atm;
+ appToken = token;
+ mActivityInfo = aInfo;
+ mUserId = UserHandle.getUserId(mActivityInfo.applicationInfo.uid);
+ packageName = mActivityInfo.applicationInfo.packageName;
+ mInputApplicationHandle = new InputApplicationHandle(appToken);
+
+ // If the class name in the intent doesn't match that of the target, this is probably an
+ // alias. We have to create a new ComponentName object to keep track of the real activity
+ // name, so that FLAG_ACTIVITY_CLEAR_TOP is handled properly.
+ if (mActivityInfo.targetActivity == null
+ || (mActivityInfo.targetActivity.equals(intent.getComponent().getClassName())
+ && (mActivityInfo.launchMode == LAUNCH_MULTIPLE
+ || mActivityInfo.launchMode == LAUNCH_SINGLE_TOP))) {
+ mActivityComponent = intent.getComponent();
+ } else {
+ mActivityComponent =
+ new ComponentName(mActivityInfo.packageName, mActivityInfo.targetActivity);
+ }
+
+ mTargetSdk = mActivityInfo.applicationInfo.targetSdkVersion;
+ mShowForAllUsers = (mActivityInfo.flags & FLAG_SHOW_FOR_ALL_USERS) != 0;
+ setOrientation(mActivityInfo.screenOrientation);
+ mRotationAnimationHint = mActivityInfo.rotationAnimation;
+
+ mShowWhenLocked = (aInfo.flags & ActivityInfo.FLAG_SHOW_WHEN_LOCKED) != 0;
+ mInheritShownWhenLocked = (aInfo.privateFlags & FLAG_INHERIT_SHOW_WHEN_LOCKED) != 0;
+ mTurnScreenOn = (aInfo.flags & FLAG_TURN_SCREEN_ON) != 0;
+
+ int realTheme = mActivityInfo.getThemeResource();
+ if (realTheme == Resources.ID_NULL) {
+ realTheme = aInfo.applicationInfo.targetSdkVersion < HONEYCOMB
+ ? android.R.style.Theme : android.R.style.Theme_Holo;
+ }
+
+ final AttributeCache.Entry ent = AttributeCache.instance().get(packageName,
+ realTheme, com.android.internal.R.styleable.Window, mUserId);
+
+ if (ent != null) {
+ mOccludesParent = !ActivityInfo.isTranslucentOrFloating(ent.array);
+ hasWallpaper = ent.array.getBoolean(R.styleable.Window_windowShowWallpaper, false);
+ noDisplay = ent.array.getBoolean(R.styleable.Window_windowNoDisplay, false);
+ } else {
+ hasWallpaper = false;
+ noDisplay = false;
+ }
+
+ if (options != null) {
+ mLaunchTaskBehind = options.getLaunchTaskBehind();
+
+ final int rotationAnimation = options.getRotationAnimationHint();
+ // Only override manifest supplied option if set.
+ if (rotationAnimation >= 0) {
+ mRotationAnimationHint = rotationAnimation;
+ }
+ }
// Application tokens start out hidden.
setHidden(true);
@@ -365,20 +445,19 @@
ColorDisplayService.ColorDisplayServiceInternal cds = LocalServices.getService(
ColorDisplayService.ColorDisplayServiceInternal.class);
- cds.attachColorTransformController(activityRecord.packageName, activityRecord.mUserId,
+ cds.attachColorTransformController(packageName, mUserId,
new WeakReference<>(mColorTransformController));
}
- AppWindowToken(WindowManagerService service, IApplicationToken token,
- ComponentName activityComponent, boolean voiceInteraction, DisplayContent dc,
- boolean fillsParent) {
- super(service, token != null ? token.asBinder() : null, TYPE_APPLICATION, true, dc,
- false /* ownerCanManageAppTokens */);
- appToken = token;
- mActivityComponent = activityComponent;
+ void onAttachToTask(boolean voiceInteraction, DisplayContent dc,
+ long inputDispatchingTimeoutNanos) {
+ mInputDispatchingTimeoutNanos = inputDispatchingTimeoutNanos;
mVoiceInteraction = voiceInteraction;
- mOccludesParent = fillsParent;
- mInputApplicationHandle = new InputApplicationHandle(appToken.asBinder());
+ onDisplayChanged(dc);
+
+ // Application tokens start out hidden.
+ setHidden(true);
+ hiddenRequested = true;
}
void onFirstWindowDrawn(WindowState win, WindowStateAnimator winAnimator) {
@@ -433,43 +512,33 @@
if (DEBUG_VISIBILITY) Slog.v(TAG, "VIS " + this + ": interesting="
+ numInteresting + " visible=" + numVisible);
if (nowDrawn != reportedDrawn) {
- if (mActivityRecord != null) {
- mActivityRecord.onWindowsDrawn(nowDrawn, SystemClock.uptimeMillis());
- }
+ onWindowsDrawn(nowDrawn, SystemClock.uptimeMillis());
reportedDrawn = nowDrawn;
}
if (nowVisible != reportedVisible) {
if (DEBUG_VISIBILITY) Slog.v(TAG,
"Visibility changed in " + this + ": vis=" + nowVisible);
reportedVisible = nowVisible;
- if (mActivityRecord != null) {
- if (nowVisible) {
- onWindowsVisible();
- } else {
- onWindowsGone();
- }
+ if (nowVisible) {
+ onWindowsVisible();
+ } else {
+ onWindowsGone();
}
}
}
- private void onWindowsGone() {
- if (mActivityRecord == null) {
- return;
- }
- if (DEBUG_VISIBILITY) {
- Slog.v(TAG_WM, "Reporting gone in " + mActivityRecord.appToken);
- }
- mActivityRecord.onWindowsGone();
+ // Mostly implemented in ActivityRecord.
+ void onWindowsDrawn(boolean drawn, long timestamp) {
}
- private void onWindowsVisible() {
- if (mActivityRecord == null) {
- return;
- }
- if (DEBUG_VISIBILITY) {
- Slog.v(TAG_WM, "Reporting visible in " + mActivityRecord.appToken);
- }
- mActivityRecord.onWindowsVisible();
+ // Mostly implemented in ActivityRecord. Keeping here for the logpoint.
+ void onWindowsGone() {
+ if (DEBUG_VISIBILITY) Slog.v(TAG_WM, "Reporting gone in " + appToken);
+ }
+
+ // Mostly implemented in ActivityRecord. Keeping here for the logpoint.
+ void onWindowsVisible() {
+ if (DEBUG_VISIBILITY) Slog.v(TAG_WM, "Reporting visible in " + appToken);
}
boolean isClientHidden() {
@@ -604,8 +673,6 @@
}
}
}
- // Changes in opening apps and closing apps may cause orientation change.
- reportDescendantOrientationChangeIfNeeded();
return;
}
@@ -762,29 +829,27 @@
}
SurfaceControl.closeTransaction();
}
-
- // Visibility changes may cause orientation request change.
- reportDescendantOrientationChangeIfNeeded();
}
return delayed;
}
- private void reportDescendantOrientationChangeIfNeeded() {
+ boolean mayFreezeScreenLocked() {
+ return false;
+ }
+
+ void reportDescendantOrientationChangeIfNeeded() {
// Orientation request is exposed only when we're visible. Therefore visibility change
// will change requested orientation. Notify upward the hierarchy ladder to adjust
// configuration. This is important to cases where activities with incompatible
// orientations launch, or user goes back from an activity of bi-orientation to an
// activity with specified orientation.
- if (mActivityRecord.getRequestedConfigurationOrientation() == getConfiguration().orientation
- || getOrientationIgnoreVisibility() == SCREEN_ORIENTATION_UNSET) {
+ if (getRequestedOrientation() == SCREEN_ORIENTATION_UNSET) {
return;
}
- final IBinder freezeToken =
- mActivityRecord.mayFreezeScreenLocked(mActivityRecord.app)
- ? mActivityRecord.appToken : null;
- onDescendantOrientationChanged(freezeToken, mActivityRecord);
+ final IBinder freezeToken = mayFreezeScreenLocked() ? appToken : null;
+ onDescendantOrientationChanged(freezeToken, this);
}
/**
@@ -834,10 +899,16 @@
return candidate;
}
+ boolean isAlwaysFocusable() {
+ return (mActivityInfo.flags & FLAG_ALWAYS_FOCUSABLE) != 0;
+ }
+
+ // TODO: Does this really need to be different from isAlwaysFocusable()? For the activity side
+ // focusable means resumeable. I guess with that in mind maybe we should rename the other
+ // method to isResumeable() or something like that.
boolean windowsAreFocusable() {
if (mTargetSdk < Build.VERSION_CODES.Q) {
- final int pid = mActivityRecord != null
- ? (mActivityRecord.app != null ? mActivityRecord.app.getPid() : 0) : 0;
+ final int pid = getPid();
final AppWindowToken topFocusedAppOfMyProcess =
mWmService.mRoot.mTopFocusedAppByProcess.get(pid);
if (topFocusedAppOfMyProcess != null && topFocusedAppOfMyProcess != this) {
@@ -846,7 +917,12 @@
return false;
}
}
- return getWindowConfiguration().canReceiveKeys() || mAlwaysFocusable;
+ return getWindowConfiguration().canReceiveKeys() || isAlwaysFocusable();
+ }
+
+ // Mostly implemented in ActivityRecord...
+ int getPid() {
+ return 0;
}
@Override
@@ -859,9 +935,6 @@
@Override
void removeImmediately() {
onRemovedFromDisplay();
- if (mActivityRecord != null) {
- mActivityRecord.unregisterConfigurationChangeListener(this);
- }
super.removeImmediately();
}
@@ -1065,7 +1138,9 @@
if (task == null) {
// It is possible we have been marked as a closing app earlier. We must remove ourselves
// from this list so we do not participate in any future animations.
- getDisplayContent().mClosingApps.remove(this);
+ if (getDisplayContent() != null) {
+ getDisplayContent().mClosingApps.remove(this);
+ }
} else if (mLastParent != null && mLastParent.mStack != null) {
task.mStack.mExitingAppTokens.remove(this);
}
@@ -1655,7 +1730,7 @@
}
/** Returns the app's preferred orientation regardless of its currently visibility state. */
- int getOrientationIgnoreVisibility() {
+ int getRequestedOrientation() {
return mOrientation;
}
@@ -1669,15 +1744,6 @@
return inSizeCompatMode() ? mSizeCompatScale : super.getSizeCompatScale();
}
- /**
- * @return Non-empty bounds if the activity has override bounds.
- * @see ActivityRecord#resolveOverrideConfiguration(Configuration)
- */
- Rect getResolvedOverrideBounds() {
- // Get bounds from resolved override configuration because it is computed with orientation.
- return getResolvedOverrideConfiguration().windowConfiguration.getBounds();
- }
-
@Override
public void onConfigurationChanged(Configuration newParentConfig) {
final int prevWinMode = getWindowingMode();
@@ -1708,7 +1774,7 @@
final int winMode = getWindowingMode();
- if (prevWinMode == winMode) {
+ if (prevWinMode == winMode || mDisplayContent == null) {
return;
}
@@ -1951,8 +2017,9 @@
}
}
+ // Mostly implemented in ActivityRecord...
boolean keyDispatchingTimedOut(String reason, int windowPid) {
- return mActivityRecord != null && mActivityRecord.keyDispatchingTimedOut(reason, windowPid);
+ return false;
}
/**
@@ -2019,9 +2086,7 @@
}
}
} else if (w.isDrawnLw()) {
- if (mActivityRecord != null) {
- mActivityRecord.onStartingWindowDrawn(SystemClock.uptimeMillis());
- }
+ onStartingWindowDrawn(SystemClock.uptimeMillis());
startingDisplayed = true;
}
}
@@ -2029,6 +2094,14 @@
return isInterestingAndDrawn;
}
+ /** Called when the starting window for this container is drawn. */
+ private void onStartingWindowDrawn(long timestamp) {
+ synchronized (mAtmService.mGlobalLock) {
+ mAtmService.mStackSupervisor.getActivityMetricsLogger().notifyStartingWindowDrawn(
+ getWindowingMode(), timestamp);
+ }
+ }
+
void layoutLetterbox(WindowState winHint) {
final WindowState w = findMainWindow();
if (w == null || winHint != null && w != winHint) {
@@ -2413,6 +2486,66 @@
return false;
}
+ void setShowWhenLocked(boolean showWhenLocked) {
+ mShowWhenLocked = showWhenLocked;
+ mAtmService.mRootActivityContainer.ensureActivitiesVisible(null /* starting */,
+ 0 /* configChanges */, false /* preserveWindows */);
+ }
+
+ void setInheritShowWhenLocked(boolean inheritShowWhenLocked) {
+ mInheritShownWhenLocked = inheritShowWhenLocked;
+ mAtmService.mRootActivityContainer.ensureActivitiesVisible(null /* starting */,
+ 0 /* configChanges */, false /* preserveWindows */);
+ }
+
+ /**
+ * @return {@code true} if the activity windowing mode is not
+ * {@link android.app.WindowConfiguration#WINDOWING_MODE_PINNED} and a) activity
+ * contains windows that have {@link LayoutParams#FLAG_SHOW_WHEN_LOCKED} set or if the
+ * activity has set {@link #mShowWhenLocked}, or b) if the activity has set
+ * {@link #mInheritShownWhenLocked} and the activity behind this satisfies the
+ * conditions a) above.
+ * Multi-windowing mode will be exited if {@code true} is returned.
+ */
+ boolean canShowWhenLocked() {
+ if (!inPinnedWindowingMode() && (mShowWhenLocked || containsShowWhenLockedWindow())) {
+ return true;
+ } else if (mInheritShownWhenLocked) {
+ final AppWindowToken r = getActivityBelow();
+ return r != null && !r.inPinnedWindowingMode() && (r.mShowWhenLocked
+ || r.containsShowWhenLockedWindow());
+ } else {
+ return false;
+ }
+ }
+
+ /**
+ * @return an {@link ActivityRecord} of the activity below this activity, or {@code null} if no
+ * such activity exists.
+ */
+ @Nullable
+ private AppWindowToken getActivityBelow() {
+ final Task task = getTask();
+ final int pos = task.mChildren.indexOf(this);
+ if (pos == -1) {
+ throw new IllegalStateException("Activity not found in its task");
+ }
+ return pos == 0 ? null : task.getChildAt(pos - 1);
+ }
+
+ void setTurnScreenOn(boolean turnScreenOn) {
+ mTurnScreenOn = turnScreenOn;
+ }
+
+ /** Mostly implemented in ActivityRecord. */
+ boolean canTurnScreenOn() {
+ return mTurnScreenOn;
+ }
+
+ boolean getTurnScreenOnFlag() {
+ return mTurnScreenOn;
+ }
+
void checkKeyguardFlagsChanged() {
final boolean containsDismissKeyguard = containsDismissKeyguardWindow();
final boolean containsShowWhenLocked = containsShowWhenLockedWindow();
@@ -2890,7 +3023,21 @@
getDisplayContent().mAppTransition.notifyAppTransitionFinishedLocked(token);
scheduleAnimation();
- mActivityRecord.onAnimationFinished();
+ if (mAtmService.mRootActivityContainer.allResumedActivitiesIdle()
+ || mAtmService.mStackSupervisor.isStoppingNoHistoryActivity()) {
+ // If all activities are already idle or there is an activity that must be
+ // stopped immediately after visible, then we now need to make sure we perform
+ // the full stop of this activity. This is because we won't do that while they are still
+ // waiting for the animation to finish.
+ if (mAtmService.mStackSupervisor.mStoppingActivities.contains(this)) {
+ mAtmService.mStackSupervisor.scheduleIdleLocked();
+ }
+ } else {
+ // Instead of doing the full stop routine here, let's just hide any activities
+ // we now can, and let them stop when the normal idle happens.
+ mAtmService.mStackSupervisor.processStoppingActivitiesLocked(null /* idleActivity */,
+ false /* remove */, true /* processPausingActivities */);
+ }
Trace.traceEnd(TRACE_TAG_WINDOW_MANAGER);
}
@@ -2957,10 +3104,13 @@
}
boolean isWaitingForTransitionStart() {
- return getDisplayContent().mAppTransition.isTransitionSet()
- && (getDisplayContent().mOpeningApps.contains(this)
- || getDisplayContent().mClosingApps.contains(this)
- || getDisplayContent().mChangingApps.contains(this));
+ final DisplayContent dc = getDisplayContent();
+ // TODO: Test for null can be removed once unification is done.
+ if (dc == null) return false;
+ return dc.mAppTransition.isTransitionSet()
+ && (dc.mOpeningApps.contains(this)
+ || dc.mClosingApps.contains(this)
+ || dc.mChangingApps.contains(this));
}
public int getTransit() {
@@ -3204,27 +3354,17 @@
}
void writeNameToProto(ProtoOutputStream proto, long fieldId) {
- if (appToken == null) {
- return;
- }
- try {
+ if (appToken != null) {
proto.write(fieldId, appToken.getName());
- } catch (RemoteException e) {
- // This shouldn't happen, but in this case fall back to outputting nothing
- Slog.e(TAG, e.toString());
}
}
- @Override
- public String toString() {
- if (stringName == null) {
- StringBuilder sb = new StringBuilder();
- sb.append("AppWindowToken{");
- sb.append(Integer.toHexString(System.identityHashCode(this)));
- sb.append(" token="); sb.append(token); sb.append('}');
- stringName = sb.toString();
- }
- return stringName + ((mIsExiting) ? " mIsExiting=" : "");
+ void writeIdentifierToProto(ProtoOutputStream proto, long fieldId) {
+ final long token = proto.start(fieldId);
+ proto.write(HASH_CODE, System.identityHashCode(this));
+ proto.write(USER_ID, mUserId);
+ proto.write(TITLE, ((ActivityRecord) this).intent.getComponent().flattenToShortString());
+ proto.end(token);
}
Rect getLetterboxInsets() {