summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--core/java/android/view/IApplicationToken.aidl5
-rw-r--r--core/java/android/view/IWindowManager.aidl55
-rw-r--r--services/core/java/com/android/server/am/ActivityManagerService.java2
-rw-r--r--services/core/java/com/android/server/am/ActivityRecord.java449
-rw-r--r--services/core/java/com/android/server/am/ActivityStack.java72
-rw-r--r--services/core/java/com/android/server/am/ActivityStackSupervisor.java14
-rw-r--r--services/core/java/com/android/server/am/TaskRecord.java5
-rw-r--r--services/core/java/com/android/server/wm/AppWindowContainerController.java526
-rw-r--r--services/core/java/com/android/server/wm/AppWindowContainerListener.java32
-rw-r--r--services/core/java/com/android/server/wm/AppWindowToken.java24
-rw-r--r--services/core/java/com/android/server/wm/InputMonitor.java18
-rw-r--r--services/core/java/com/android/server/wm/WindowContainer.java24
-rw-r--r--services/core/java/com/android/server/wm/WindowContainerController.java70
-rw-r--r--services/core/java/com/android/server/wm/WindowContainerListener.java25
-rw-r--r--services/core/java/com/android/server/wm/WindowManagerService.java551
-rw-r--r--services/tests/servicestests/src/com/android/server/wm/AppWindowContainerControllerTests.java42
-rw-r--r--services/tests/servicestests/src/com/android/server/wm/UnknownAppVisibilityControllerTest.java5
-rw-r--r--services/tests/servicestests/src/com/android/server/wm/WindowContainerControllerTests.java84
-rw-r--r--services/tests/servicestests/src/com/android/server/wm/WindowContainerTests.java40
-rw-r--r--services/tests/servicestests/src/com/android/server/wm/WindowTestsBase.java24
-rw-r--r--tests/permission/src/com/android/framework/permission/tests/WindowManagerPermissionTests.java101
-rw-r--r--tools/layoutlib/bridge/src/android/view/IWindowManagerImpl.java84
22 files changed, 1157 insertions, 1095 deletions
diff --git a/core/java/android/view/IApplicationToken.aidl b/core/java/android/view/IApplicationToken.aidl
index 633b40fb7967..b01c0ef55812 100644
--- a/core/java/android/view/IApplicationToken.aidl
+++ b/core/java/android/view/IApplicationToken.aidl
@@ -20,10 +20,5 @@ package android.view;
/** {@hide} */
interface IApplicationToken
{
- void windowsDrawn();
- void windowsVisible();
- void windowsGone();
- boolean keyDispatchingTimedOut(String reason);
- long getKeyDispatchingTimeout();
}
diff --git a/core/java/android/view/IWindowManager.aidl b/core/java/android/view/IWindowManager.aidl
index 21875fe168bc..8611d69ba94d 100644
--- a/core/java/android/view/IWindowManager.aidl
+++ b/core/java/android/view/IWindowManager.aidl
@@ -83,41 +83,9 @@ interface IWindowManager
void setOverscan(int displayId, int left, int top, int right, int bottom);
// These can only be called when holding the MANAGE_APP_TOKENS permission.
- void pauseKeyDispatching(IBinder token);
- void resumeKeyDispatching(IBinder token);
void setEventDispatching(boolean enabled);
void addWindowToken(IBinder token, int type, int displayId);
void removeWindowToken(IBinder token, int displayId);
- /**
- * Creates the object representation for the application token in the window manager and adds it
- * to the specified task Id.
- *
- * @param addPos The position to add the token to in the task.
- * @param token The token to add.
- * @param taskId The Id of the task we are adding the token to.
- * @param requestedOrientation Orientation to use.
- * @param fullscreen True if the application token is fullscreen.
- * @param showWhenLocked True if the application token should be shown when locked.
- * @param configChanges Input configuration changes.
- * @param voiceInteraction True if the token is in voice interaction mode.
- * @param launchTaskBehind True if the token is been launched from behind.
- * @param alwaysFocusable True if the app windows are always focusable regardless of the stack
- * they are in.
- * @param targetSdkVersion The application's target SDK version
- */
- void addAppToken(int addPos, IApplicationToken token, int taskId, int requestedOrientation,
- boolean fullscreen, boolean showWhenLocked, int configChanges, boolean voiceInteraction,
- boolean launchTaskBehind, boolean alwaysFocusable, int targetSdkVersion,
- int rotationAnimationHint);
- /**
- * Adds an already existing application token on the window manager side to the input task id.
- *
- * @param token The token we are adding to the input task Id.
- * @param taskId The Id of the task we are adding the token to.
- */
- void addAppToTask(IBinder token, int taskId);
- void setAppOrientation(IApplicationToken token, int requestedOrientation);
- int getAppOrientation(IApplicationToken token);
void setFocusedApp(IBinder token, boolean moveFocusNow);
void prepareAppTransition(int transit, boolean alwaysKeepCurrent);
int getPendingAppTransition();
@@ -154,20 +122,6 @@ interface IWindowManager
boolean scaleUp);
void executeAppTransition();
- /**
- * Called to set the starting window for the input token and returns true if the starting
- * window was set for the token.
- */
- boolean setAppStartingWindow(IBinder token, String pkg, int theme,
- in CompatibilityInfo compatInfo, CharSequence nonLocalizedLabel, int labelRes,
- int icon, int logo, int windowFlags, IBinder transferFrom, boolean createIfNeeded);
- void setAppVisibility(IBinder token, boolean visible);
- void notifyAppResumed(IBinder token, boolean wasStopped, boolean allowSavedSurface);
- void notifyAppStopped(IBinder token);
- void startAppFreezingScreen(IBinder token, int configChanges);
- void stopAppFreezingScreen(IBinder token, boolean force);
- void removeAppToken(IBinder token, int displayId);
-
/** Used by system ui to report that recents has shown itself. */
void endProlongedAnimations();
@@ -315,15 +269,6 @@ interface IWindowManager
boolean requestAssistScreenshot(IAssistScreenshotReceiver receiver);
/**
- * Create a screenshot of the applications currently displayed.
- *
- * @param frameScale the scale to apply to the frame, only used when width = -1 and
- * height = -1
- */
- Bitmap screenshotApplications(IBinder appToken, int displayId, int maxWidth, int maxHeight,
- float frameScale);
-
- /**
* Called by the status bar to notify Views of changes to System UI visiblity.
*/
oneway void statusBarVisibilityChanged(int visibility);
diff --git a/services/core/java/com/android/server/am/ActivityManagerService.java b/services/core/java/com/android/server/am/ActivityManagerService.java
index 66258461fe3a..9643976b5efa 100644
--- a/services/core/java/com/android/server/am/ActivityManagerService.java
+++ b/services/core/java/com/android/server/am/ActivityManagerService.java
@@ -4737,7 +4737,7 @@ public class ActivityManagerService extends IActivityManager.Stub
if (r == null) {
return ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
}
- return mWindowManager.getAppOrientation(r.appToken);
+ return r.getRequestedOrientation();
}
}
diff --git a/services/core/java/com/android/server/am/ActivityRecord.java b/services/core/java/com/android/server/am/ActivityRecord.java
index ef197002f0a7..0e4ab96cccb4 100644
--- a/services/core/java/com/android/server/am/ActivityRecord.java
+++ b/services/core/java/com/android/server/am/ActivityRecord.java
@@ -21,17 +21,26 @@ import static android.app.ActivityManager.StackId.DOCKED_STACK_ID;
import static android.app.ActivityManager.StackId.FREEFORM_WORKSPACE_STACK_ID;
import static android.app.ActivityManager.StackId.HOME_STACK_ID;
import static android.app.ActivityManager.StackId.PINNED_STACK_ID;
+import static android.content.Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS;
import static android.content.pm.ActivityInfo.CONFIG_ORIENTATION;
import static android.content.pm.ActivityInfo.CONFIG_SCREEN_LAYOUT;
import static android.content.pm.ActivityInfo.CONFIG_SCREEN_SIZE;
import static android.content.pm.ActivityInfo.CONFIG_SMALLEST_SCREEN_SIZE;
+import static android.content.pm.ActivityInfo.FLAG_EXCLUDE_FROM_RECENTS;
+import static android.content.pm.ActivityInfo.FLAG_IMMERSIVE;
+import static android.content.pm.ActivityInfo.FLAG_MULTIPROCESS;
import static android.content.pm.ActivityInfo.FLAG_SHOW_FOR_ALL_USERS;
import static android.content.pm.ActivityInfo.FLAG_ALWAYS_FOCUSABLE;
+import static android.content.pm.ActivityInfo.FLAG_STATE_NOT_NEEDED;
+import static android.content.pm.ActivityInfo.LAUNCH_MULTIPLE;
+import static android.content.pm.ActivityInfo.LAUNCH_SINGLE_TOP;
import static android.content.pm.ActivityInfo.RESIZE_MODE_FORCE_RESIZEABLE;
import static android.content.pm.ActivityInfo.RESIZE_MODE_RESIZEABLE;
import static android.content.pm.ActivityInfo.RESIZE_MODE_RESIZEABLE_AND_PIPABLE;
import static android.content.pm.ActivityInfo.RESIZE_MODE_RESIZEABLE_VIA_SDK_VERSION;
import static android.content.pm.ActivityInfo.RESIZE_MODE_UNRESIZEABLE;
+import static android.os.Build.VERSION_CODES.HONEYCOMB;
+import static android.os.Process.SYSTEM_UID;
import static android.view.Display.DEFAULT_DISPLAY;
import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_CONFIGURATION;
import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_SAVED_STATE;
@@ -92,6 +101,8 @@ import com.android.internal.util.XmlUtils;
import com.android.server.AttributeCache;
import com.android.server.am.ActivityStack.ActivityState;
import com.android.server.am.ActivityStackSupervisor.ActivityContainer;
+import com.android.server.wm.AppWindowContainerController;
+import com.android.server.wm.AppWindowContainerListener;
import java.io.File;
import java.io.IOException;
@@ -110,7 +121,7 @@ import org.xmlpull.v1.XmlSerializer;
/**
* An entry in the history stack, representing an activity.
*/
-final class ActivityRecord {
+final class ActivityRecord implements AppWindowContainerListener {
private static final String TAG = TAG_WITH_CLASS_NAME ? "ActivityRecord" : TAG_AM;
private static final String TAG_CONFIGURATION = TAG + POSTFIX_CONFIGURATION;
private static final String TAG_SAVED_STATE = TAG + POSTFIX_SAVED_STATE;
@@ -135,6 +146,7 @@ final class ActivityRecord {
final ActivityManagerService service; // owner
final IApplicationToken.Stub appToken; // window manager token
+ AppWindowContainerController mWindowContainerController;
final ActivityInfo info; // all about me
final ApplicationInfo appInfo; // information about activity's app
final int launchedFromUid; // always the uid who started the activity.
@@ -150,7 +162,7 @@ final class ActivityRecord {
final boolean stateNotNeeded; // As per ActivityInfo.flags
boolean fullscreen; // covers the full screen?
final boolean noDisplay; // activity is not displayed?
- final boolean componentSpecified; // did caller specify an explicit component?
+ private final boolean componentSpecified; // did caller specify an explicit component?
final boolean rootVoiceInteraction; // was this the root activity of a voice interaction?
static final int APPLICATION_ACTIVITY_TYPE = 0;
@@ -158,18 +170,18 @@ final class ActivityRecord {
static final int RECENTS_ACTIVITY_TYPE = 2;
int mActivityType;
- CharSequence nonLocalizedLabel; // the label information from the package mgr.
- int labelRes; // the label information from the package mgr.
- int icon; // resource identifier of activity's icon.
- int logo; // resource identifier of activity's logo.
- int theme; // resource identifier of activity's theme.
- int realTheme; // actual theme resource we will use, never 0.
- int windowFlags; // custom window flags for preview window.
+ private CharSequence nonLocalizedLabel; // the label information from the package mgr.
+ private int labelRes; // the label information from the package mgr.
+ private int icon; // resource identifier of activity's icon.
+ private int logo; // resource identifier of activity's logo.
+ private int theme; // resource identifier of activity's theme.
+ private int realTheme; // actual theme resource we will use, never 0.
+ private int windowFlags; // custom window flags for preview window.
TaskRecord task; // the task this is in.
- long createTime = System.currentTimeMillis();
+ private long createTime = System.currentTimeMillis();
long displayStartTime; // when we started launching this activity
long fullyDrawnStartTime; // when we started launching this activity
- long startTime; // last time this activity was started
+ private long startTime; // last time this activity was started
long lastVisibleTime; // last time this activity became visible
long cpuTimeAtResume; // the cpu time of host process at the time of resuming activity
long pauseTime; // last time we started pausing the activity
@@ -542,70 +554,9 @@ final class ActivityRecord {
static class Token extends IApplicationToken.Stub {
private final WeakReference<ActivityRecord> weakActivity;
- private final ActivityManagerService mService;
- Token(ActivityRecord activity, ActivityManagerService service) {
+ Token(ActivityRecord activity) {
weakActivity = new WeakReference<>(activity);
- mService = service;
- }
-
- @Override
- public void windowsDrawn() {
- synchronized (mService) {
- ActivityRecord r = tokenToActivityRecordLocked(this);
- if (r != null) {
- r.windowsDrawnLocked();
- }
- }
- }
-
- @Override
- public void windowsVisible() {
- synchronized (mService) {
- ActivityRecord r = tokenToActivityRecordLocked(this);
- if (r != null) {
- r.windowsVisibleLocked();
- }
- }
- }
-
- @Override
- public void windowsGone() {
- synchronized (mService) {
- ActivityRecord r = tokenToActivityRecordLocked(this);
- if (r != null) {
- if (DEBUG_SWITCH) Log.v(TAG_SWITCH, "windowsGone(): " + r);
- r.nowVisible = false;
- }
- }
- }
-
- @Override
- public boolean keyDispatchingTimedOut(String reason) {
- ActivityRecord r;
- ActivityRecord anrActivity;
- ProcessRecord anrApp;
- synchronized (mService) {
- r = tokenToActivityRecordLocked(this);
- if (r == null) {
- return false;
- }
- anrActivity = r.getWaitingHistoryRecordLocked();
- anrApp = r.app;
- }
- return mService.inputDispatchingTimedOut(anrApp, anrActivity, r, false, reason);
- }
-
- @Override
- public long getKeyDispatchingTimeout() {
- synchronized (mService) {
- ActivityRecord r = tokenToActivityRecordLocked(this);
- if (r == null) {
- return 0;
- }
- r = r.getWaitingHistoryRecordLocked();
- return ActivityManagerService.getInputDispatchingTimeoutLocked(r);
- }
}
private static ActivityRecord tokenToActivityRecordLocked(Token token) {
@@ -652,7 +603,7 @@ final class ActivityRecord {
ActivityStackSupervisor supervisor,
ActivityContainer container, ActivityOptions options, ActivityRecord sourceRecord) {
service = _service;
- appToken = new Token(this, service);
+ appToken = new Token(this);
info = aInfo;
launchedFromUid = _launchedFromUid;
launchedFromPackage = _launchedFromPackage;
@@ -700,97 +651,110 @@ final class ActivityRecord {
}
}
- // This starts out true, since the initial state of an activity
- // is that we have everything, and we shouldn't never consider it
- // lacking in state to be removed if it dies.
+ // This starts out true, since the initial state of an activity is that we have everything,
+ // and we shouldn't never consider it lacking in state to be removed if it dies.
haveState = true;
- if (aInfo != null) {
- // 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 (aInfo.targetActivity == null
- || (aInfo.targetActivity.equals(_intent.getComponent().getClassName())
- && (aInfo.launchMode == ActivityInfo.LAUNCH_MULTIPLE
- || aInfo.launchMode == ActivityInfo.LAUNCH_SINGLE_TOP))) {
- realActivity = _intent.getComponent();
- } else {
- realActivity = new ComponentName(aInfo.packageName, aInfo.targetActivity);
- }
- taskAffinity = aInfo.taskAffinity;
- stateNotNeeded = (aInfo.flags&
- ActivityInfo.FLAG_STATE_NOT_NEEDED) != 0;
- appInfo = aInfo.applicationInfo;
- nonLocalizedLabel = aInfo.nonLocalizedLabel;
- labelRes = aInfo.labelRes;
- if (nonLocalizedLabel == null && labelRes == 0) {
- ApplicationInfo app = aInfo.applicationInfo;
- nonLocalizedLabel = app.nonLocalizedLabel;
- labelRes = app.labelRes;
- }
- icon = aInfo.getIconResource();
- logo = aInfo.getLogoResource();
- theme = aInfo.getThemeResource();
- realTheme = theme;
- if (realTheme == 0) {
- realTheme = aInfo.applicationInfo.targetSdkVersion
- < Build.VERSION_CODES.HONEYCOMB
- ? android.R.style.Theme
- : android.R.style.Theme_Holo;
- }
- if ((aInfo.flags&ActivityInfo.FLAG_HARDWARE_ACCELERATED) != 0) {
- windowFlags |= LayoutParams.FLAG_HARDWARE_ACCELERATED;
- }
- if ((aInfo.flags&ActivityInfo.FLAG_MULTIPROCESS) != 0
- && _caller != null
- && (aInfo.applicationInfo.uid == Process.SYSTEM_UID
- || aInfo.applicationInfo.uid == _caller.info.uid)) {
- processName = _caller.processName;
- } else {
- processName = aInfo.processName;
- }
+ // 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 (aInfo.targetActivity == null
+ || (aInfo.targetActivity.equals(_intent.getComponent().getClassName())
+ && (aInfo.launchMode == LAUNCH_MULTIPLE
+ || aInfo.launchMode == LAUNCH_SINGLE_TOP))) {
+ realActivity = _intent.getComponent();
+ } else {
+ realActivity = new ComponentName(aInfo.packageName, aInfo.targetActivity);
+ }
+ taskAffinity = aInfo.taskAffinity;
+ stateNotNeeded = (aInfo.flags & FLAG_STATE_NOT_NEEDED) != 0;
+ appInfo = aInfo.applicationInfo;
+ nonLocalizedLabel = aInfo.nonLocalizedLabel;
+ labelRes = aInfo.labelRes;
+ if (nonLocalizedLabel == null && labelRes == 0) {
+ ApplicationInfo app = aInfo.applicationInfo;
+ nonLocalizedLabel = app.nonLocalizedLabel;
+ labelRes = app.labelRes;
+ }
+ icon = aInfo.getIconResource();
+ logo = aInfo.getLogoResource();
+ theme = aInfo.getThemeResource();
+ realTheme = theme;
+ if (realTheme == 0) {
+ realTheme = aInfo.applicationInfo.targetSdkVersion < HONEYCOMB
+ ? android.R.style.Theme : android.R.style.Theme_Holo;
+ }
+ if ((aInfo.flags & ActivityInfo.FLAG_HARDWARE_ACCELERATED) != 0) {
+ windowFlags |= LayoutParams.FLAG_HARDWARE_ACCELERATED;
+ }
+ if ((aInfo.flags & FLAG_MULTIPROCESS) != 0 && _caller != null
+ && (aInfo.applicationInfo.uid == SYSTEM_UID
+ || aInfo.applicationInfo.uid == _caller.info.uid)) {
+ processName = _caller.processName;
+ } else {
+ processName = aInfo.processName;
+ }
- if (intent != null && (aInfo.flags & ActivityInfo.FLAG_EXCLUDE_FROM_RECENTS) != 0) {
- intent.addFlags(Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
- }
+ if ((aInfo.flags & FLAG_EXCLUDE_FROM_RECENTS) != 0) {
+ intent.addFlags(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, userId);
+ final boolean translucent = ent != null && (ent.array.getBoolean(
+ com.android.internal.R.styleable.Window_windowIsTranslucent, false)
+ || (!ent.array.hasValue(
+ com.android.internal.R.styleable.Window_windowIsTranslucent)
+ && ent.array.getBoolean(
+ com.android.internal.R.styleable.Window_windowSwipeToDismiss,
+ false)));
+ fullscreen = ent != null && !ent.array.getBoolean(
+ com.android.internal.R.styleable.Window_windowIsFloating, false) && !translucent;
+ noDisplay = ent != null && ent.array.getBoolean(
+ com.android.internal.R.styleable.Window_windowNoDisplay, false);
+
+ setActivityType(_componentSpecified, _launchedFromUid, _intent, sourceRecord);
+
+ immersive = (aInfo.flags & FLAG_IMMERSIVE) != 0;
+
+ requestedVrComponent = (aInfo.requestedVrComponent == null) ?
+ null : ComponentName.unflattenFromString(aInfo.requestedVrComponent);
+ }
+
+ void createWindowContainer() {
+ if (mWindowContainerController != null) {
+ throw new IllegalArgumentException("Window container=" + mWindowContainerController
+ + " already created for r=" + this);
- packageName = aInfo.applicationInfo.packageName;
- launchMode = aInfo.launchMode;
-
- AttributeCache.Entry ent = AttributeCache.instance().get(packageName,
- realTheme, com.android.internal.R.styleable.Window, userId);
- final boolean translucent = ent != null && (ent.array.getBoolean(
- com.android.internal.R.styleable.Window_windowIsTranslucent, false)
- || (!ent.array.hasValue(
- com.android.internal.R.styleable.Window_windowIsTranslucent)
- && ent.array.getBoolean(
- com.android.internal.R.styleable.Window_windowSwipeToDismiss,
- false)));
- fullscreen = ent != null && !ent.array.getBoolean(
- com.android.internal.R.styleable.Window_windowIsFloating, false)
- && !translucent;
- noDisplay = ent != null && ent.array.getBoolean(
- com.android.internal.R.styleable.Window_windowNoDisplay, false);
-
- setActivityType(_componentSpecified, _launchedFromUid, _intent, sourceRecord);
-
- immersive = (aInfo.flags & ActivityInfo.FLAG_IMMERSIVE) != 0;
-
- requestedVrComponent = (aInfo.requestedVrComponent == null) ?
- null : ComponentName.unflattenFromString(aInfo.requestedVrComponent);
- } else {
- realActivity = null;
- taskAffinity = null;
- stateNotNeeded = false;
- appInfo = null;
- processName = null;
- packageName = null;
- fullscreen = true;
- noDisplay = false;
- mActivityType = APPLICATION_ACTIVITY_TYPE;
- immersive = false;
- requestedVrComponent = null;
}
+
+ inHistory = true;
+
+ task.updateOverrideConfigurationFromLaunchBounds();
+
+ mWindowContainerController = new AppWindowContainerController(appToken, this, task.taskId,
+ Integer.MAX_VALUE /* add on top */, info.screenOrientation, fullscreen,
+ (info.flags & FLAG_SHOW_FOR_ALL_USERS) != 0, info.configChanges,
+ task.voiceSession != null, mLaunchTaskBehind, isAlwaysFocusable(),
+ appInfo.targetSdkVersion, mRotationAnimationHint,
+ ActivityManagerService.getInputDispatchingTimeoutLocked(this) * 1000000L);
+
+ task.addActivityToTop(this);
+
+ onOverrideConfigurationSent();
+ }
+
+ void removeWindowContainer() {
+ mWindowContainerController.removeContainer(getDisplayId());
+ }
+
+ // TODO: Remove once task record is converted to use controller in which case we can use
+ // positionChildAt()
+ void positionWindowContainerAt(int index) {
+ mWindowContainerController.positionAt(task.taskId, index);
}
private boolean isHomeIntent(Intent intent) {
@@ -890,12 +854,6 @@ final class ActivityRecord {
return true;
}
- void putInHistory() {
- if (!inHistory) {
- inHistory = true;
- }
- }
-
void takeFromHistory() {
if (inHistory) {
inHistory = false;
@@ -931,7 +889,7 @@ final class ActivityRecord {
return (info.persistableMode == ActivityInfo.PERSIST_ROOT_ONLY ||
info.persistableMode == ActivityInfo.PERSIST_ACROSS_REBOOTS) &&
(intent == null ||
- (intent.getFlags() & Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS) == 0);
+ (intent.getFlags() & FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS) == 0);
}
boolean isFocusable() {
@@ -1222,14 +1180,14 @@ final class ActivityRecord {
void pauseKeyDispatchingLocked() {
if (!keysPaused) {
keysPaused = true;
- service.mWindowManager.pauseKeyDispatching(appToken);
+ mWindowContainerController.pauseKeyDispatching();
}
}
void resumeKeyDispatchingLocked() {
if (keysPaused) {
keysPaused = false;
- service.mWindowManager.resumeKeyDispatching(appToken);
+ mWindowContainerController.resumeKeyDispatching();
}
}
@@ -1277,7 +1235,7 @@ final class ActivityRecord {
return null;
}
- final float scale;
+ float scale = 0;
if (DEBUG_SCREENSHOTS) Slog.d(TAG_SCREENSHOTS, "\tTaking screenshot");
// When this flag is set, we currently take the fullscreen screenshot of the activity but
@@ -1288,17 +1246,21 @@ final class ActivityRecord {
scale = service.mFullscreenThumbnailScale;
}
- return service.mWindowManager.screenshotApplications(appToken, DEFAULT_DISPLAY, w, h,
- scale);
+ return mWindowContainerController.screenshotApplications(getDisplayId(), w, h, scale);
}
+ void setVisibility(boolean visible) {
+ mWindowContainerController.setVisibility(visible);
+ }
+
+ // TODO: Look into merging with #setVisibility()
void setVisible(boolean newVisible) {
visible = newVisible;
if (!visible && mUpdateTaskThumbnailWhenHidden) {
updateThumbnailLocked(screenshotActivityLocked(), null /* description */);
mUpdateTaskThumbnailWhenHidden = false;
}
- service.mWindowManager.setAppVisibility(appToken, visible);
+ mWindowContainerController.setVisibility(visible);
final ArrayList<ActivityContainer> containers = mChildContainers;
for (int containerNdx = containers.size() - 1; containerNdx >= 0; --containerNdx) {
final ActivityContainer container = containers.get(containerNdx);
@@ -1307,6 +1269,14 @@ final class ActivityRecord {
mStackSupervisor.mAppVisibilitiesChangedSinceLastPause = true;
}
+ void notifyAppResumed(boolean wasStopped, boolean allowSavedSurface) {
+ mWindowContainerController.notifyAppResumed(wasStopped, allowSavedSurface);
+ }
+
+ void notifyUnknownVisibilityLaunched() {
+ mWindowContainerController.notifyUnknownVisibilityLaunched();
+ }
+
/**
* @return true if the input activity should be made visible, ignoring any effect Keyguard
* might have on the visibility
@@ -1458,6 +1428,7 @@ final class ActivityRecord {
service.notifyTaskPersisterLocked(task, false);
}
if (DEBUG_SAVED_STATE) Slog.i(TAG_SAVED_STATE, "Saving icicle of " + this + ": " + icicle);
+
if (newIcicle != null) {
// If icicle is null, this is happening due to a timeout, so we haven't really saved
// the state.
@@ -1472,7 +1443,7 @@ final class ActivityRecord {
stopped = true;
state = ActivityState.STOPPED;
- service.mWindowManager.notifyAppStopped(appToken);
+ mWindowContainerController.notifyAppStopped();
if (stack.getVisibleBehindActivity() == this) {
mStackSupervisor.requestVisibleBehindLocked(this, false /* visible */);
@@ -1536,14 +1507,14 @@ final class ActivityRecord {
public void startFreezingScreenLocked(ProcessRecord app, int configChanges) {
if (mayFreezeScreenLocked(app)) {
- service.mWindowManager.startAppFreezingScreen(appToken, configChanges);
+ mWindowContainerController.startFreezingScreen(configChanges);
}
}
public void stopFreezingScreenLocked(boolean force) {
if (force || frozenBeforeDestroy) {
frozenBeforeDestroy = false;
- service.mWindowManager.stopAppFreezingScreen(appToken, force);
+ mWindowContainerController.stopFreezingScreen(force);
}
}
@@ -1617,48 +1588,73 @@ final class ActivityRecord {
stack.mLaunchStartTime = 0;
}
- void windowsDrawnLocked() {
- mStackSupervisor.mActivityMetricsLogger.notifyWindowsDrawn();
- if (displayStartTime != 0) {
- reportLaunchTimeLocked(SystemClock.uptimeMillis());
- }
- mStackSupervisor.sendWaitingVisibleReportLocked(this);
- startTime = 0;
- finishLaunchTickingLocked();
- if (task != null) {
- task.hasBeenVisible = true;
- }
- }
-
- void windowsVisibleLocked() {
- mStackSupervisor.reportActivityVisibleLocked(this);
- if (DEBUG_SWITCH) Log.v(TAG_SWITCH, "windowsVisibleLocked(): " + this);
- if (!nowVisible) {
- nowVisible = true;
- lastVisibleTime = SystemClock.uptimeMillis();
- if (!idle) {
- // 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.
- mStackSupervisor.processStoppingActivitiesLocked(false);
- } else {
- // If this activity was already idle, then we now need to make sure we perform
- // the full stop of any activities that are waiting to do so. This is because
- // we won't do that while they are still waiting for this one to become visible.
- final int size = mStackSupervisor.mWaitingVisibleActivities.size();
- if (size > 0) {
- for (int i = 0; i < size; i++) {
- ActivityRecord r = mStackSupervisor.mWaitingVisibleActivities.get(i);
- if (DEBUG_SWITCH) Log.v(TAG_SWITCH, "Was waiting for visible: " + r);
+ @Override
+ public void onWindowsDrawn() {
+ synchronized (service) {
+ mStackSupervisor.mActivityMetricsLogger.notifyWindowsDrawn();
+ if (displayStartTime != 0) {
+ reportLaunchTimeLocked(SystemClock.uptimeMillis());
+ }
+ mStackSupervisor.sendWaitingVisibleReportLocked(this);
+ startTime = 0;
+ finishLaunchTickingLocked();
+ if (task != null) {
+ task.hasBeenVisible = true;
+ }
+ }
+ }
+
+ @Override
+ public void onWindowsVisible() {
+ synchronized (service) {
+ mStackSupervisor.reportActivityVisibleLocked(this);
+ if (DEBUG_SWITCH) Log.v(TAG_SWITCH, "windowsVisibleLocked(): " + this);
+ if (!nowVisible) {
+ nowVisible = true;
+ lastVisibleTime = SystemClock.uptimeMillis();
+ if (!idle) {
+ // 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.
+ mStackSupervisor.processStoppingActivitiesLocked(false);
+ } else {
+ // If this activity was already idle, then we now need to make sure we perform
+ // the full stop of any activities that are waiting to do so. This is because
+ // we won't do that while they are still waiting for this one to become visible.
+ final int size = mStackSupervisor.mWaitingVisibleActivities.size();
+ if (size > 0) {
+ for (int i = 0; i < size; i++) {
+ ActivityRecord r = mStackSupervisor.mWaitingVisibleActivities.get(i);
+ if (DEBUG_SWITCH) Log.v(TAG_SWITCH, "Was waiting for visible: " + r);
+ }
+ mStackSupervisor.mWaitingVisibleActivities.clear();
+ mStackSupervisor.scheduleIdleLocked();
}
- mStackSupervisor.mWaitingVisibleActivities.clear();
- mStackSupervisor.scheduleIdleLocked();
}
+ service.scheduleAppGcsLocked();
}
- service.scheduleAppGcsLocked();
}
}
- ActivityRecord getWaitingHistoryRecordLocked() {
+ @Override
+ public void onWindowsGone() {
+ synchronized (service) {
+ if (DEBUG_SWITCH) Log.v(TAG_SWITCH, "windowsGone(): " + this);
+ nowVisible = false;
+ }
+ }
+
+ @Override
+ public boolean keyDispatchingTimedOut(String reason) {
+ ActivityRecord anrActivity;
+ ProcessRecord anrApp;
+ synchronized (service) {
+ anrActivity = getWaitingHistoryRecordLocked();
+ anrApp = app;
+ }
+ return service.inputDispatchingTimedOut(anrApp, anrActivity, this, false, reason);
+ }
+
+ private ActivityRecord getWaitingHistoryRecordLocked() {
// First find the real culprit... if this activity is waiting for
// another activity to start or has stopped, then the key dispatching
// timeout should not be caused by this.
@@ -1800,25 +1796,40 @@ final class ActivityRecord {
void showStartingWindow(ActivityRecord prev, boolean createIfNeeded) {
final CompatibilityInfo compatInfo =
service.compatibilityInfoForPackageLocked(info.applicationInfo);
- final boolean shown = service.mWindowManager.setAppStartingWindow(
- appToken, packageName, theme, compatInfo, nonLocalizedLabel, labelRes, icon,
- logo, windowFlags, prev != null ? prev.appToken : null, createIfNeeded);
+ final boolean shown = mWindowContainerController.addStartingWindow(packageName, theme,
+ compatInfo, nonLocalizedLabel, labelRes, icon, logo, windowFlags,
+ prev != null ? prev.appToken : null, createIfNeeded);
if (shown) {
mStartingWindowState = STARTING_WINDOW_SHOWN;
}
}
+ void removeOrphanedStartingWindow(boolean behindFullscreenActivity) {
+ if (state == ActivityState.INITIALIZING
+ && mStartingWindowState == STARTING_WINDOW_SHOWN
+ && behindFullscreenActivity) {
+ if (DEBUG_VISIBILITY) Slog.w(TAG_VISIBILITY, "Found orphaned starting window " + this);
+ mStartingWindowState = STARTING_WINDOW_REMOVED;
+ mWindowContainerController.removeStartingWindow();
+ }
+ }
+
+ int getRequestedOrientation() {
+ return mWindowContainerController.getOrientation();
+ }
+
void setRequestedOrientation(int requestedOrientation) {
if (task != null && (!task.mFullscreen || !task.getStack().mFullscreen)) {
// Fixed screen orientation isn't supported when activities aren't in full screen mode.
return;
}
- service.mWindowManager.setAppOrientation(appToken, requestedOrientation);
final int displayId = getDisplayId();
- final Configuration config = service.mWindowManager.updateOrientationFromAppTokens(
- mStackSupervisor.getDisplayOverrideConfiguration(displayId),
- mayFreezeScreenLocked(app) ? appToken : null, displayId);
+ final Configuration displayConfig =
+ mStackSupervisor.getDisplayOverrideConfiguration(displayId);
+
+ final Configuration config = mWindowContainerController.setOrientation(requestedOrientation,
+ displayId, displayConfig, mayFreezeScreenLocked(app));
if (config != null) {
frozenBeforeDestroy = true;
if (!service.updateDisplayOverrideConfigurationLocked(config, this,
diff --git a/services/core/java/com/android/server/am/ActivityStack.java b/services/core/java/com/android/server/am/ActivityStack.java
index beeadac5d50a..ddef339caa5d 100644
--- a/services/core/java/com/android/server/am/ActivityStack.java
+++ b/services/core/java/com/android/server/am/ActivityStack.java
@@ -61,8 +61,6 @@ import static com.android.server.am.ActivityManagerDebugConfig.TAG_AM;
import static com.android.server.am.ActivityManagerDebugConfig.TAG_WITH_CLASS_NAME;
import static com.android.server.am.ActivityRecord.APPLICATION_ACTIVITY_TYPE;
import static com.android.server.am.ActivityRecord.HOME_ACTIVITY_TYPE;
-import static com.android.server.am.ActivityRecord.STARTING_WINDOW_REMOVED;
-import static com.android.server.am.ActivityRecord.STARTING_WINDOW_SHOWN;
import static com.android.server.am.ActivityStackSupervisor.FindTaskResult;
import static com.android.server.am.ActivityStackSupervisor.ON_TOP;
import static com.android.server.am.ActivityStackSupervisor.PRESERVE_WINDOWS;
@@ -2046,15 +2044,7 @@ final class ActivityStack extends ConfigurationContainer {
continue;
}
- if (r.state == ActivityState.INITIALIZING
- && r.mStartingWindowState == STARTING_WINDOW_SHOWN
- && behindFullscreenActivity) {
- if (DEBUG_VISIBILITY) Slog.w(TAG_VISIBILITY,
- "Found orphaned starting window " + r);
- r.mStartingWindowState = STARTING_WINDOW_REMOVED;
- mWindowManager.removeAppStartingWindow(r.appToken);
- }
-
+ r.removeOrphanedStartingWindow(behindFullscreenActivity);
behindFullscreenActivity |= r.fullscreen;
}
}
@@ -2287,7 +2277,7 @@ final class ActivityStack extends ConfigurationContainer {
// previous should actually be hidden depending on whether the
// new one is found to be full-screen or not.
if (prev.finishing) {
- mWindowManager.setAppVisibility(prev.appToken, false);
+ prev.setVisibility(false);
if (DEBUG_SWITCH) Slog.v(TAG_SWITCH,
"Not waiting for visible to hide: " + prev + ", waitingVisible="
+ mStackSupervisor.mWaitingVisibleActivities.contains(prev)
@@ -2329,7 +2319,7 @@ final class ActivityStack extends ConfigurationContainer {
? TRANSIT_ACTIVITY_CLOSE
: TRANSIT_TASK_CLOSE, false);
}
- mWindowManager.setAppVisibility(prev.appToken, false);
+ prev.setVisibility(false);
} else {
if (DEBUG_TRANSITION) Slog.v(TAG_TRANSITION,
"Prepare open transition: prev=" + prev);
@@ -2384,7 +2374,7 @@ final class ActivityStack extends ConfigurationContainer {
// This activity is now becoming visible.
if (!next.visible || next.stopped || lastActivityTranslucent) {
- mWindowManager.setAppVisibility(next.appToken, true);
+ next.setVisibility(true);
}
// schedule launch ticks to collect information about slow apps.
@@ -2433,7 +2423,7 @@ final class ActivityStack extends ConfigurationContainer {
mStackSupervisor.scheduleResumeTopActivities();
}
if (!next.visible || next.stopped) {
- mWindowManager.setAppVisibility(next.appToken, true);
+ next.setVisibility(true);
}
next.completeResumeLocked();
if (DEBUG_STACK) mStackSupervisor.validateTopActivitiesLocked();
@@ -2471,7 +2461,7 @@ final class ActivityStack extends ConfigurationContainer {
// Well the app will no longer be stopped.
// Clear app token stopped state in window manager if needed.
- mWindowManager.notifyAppResumed(next.appToken, next.stopped, allowSavedSurface);
+ next.notifyAppResumed(next.stopped, allowSavedSurface);
EventLog.writeEvent(EventLogTags.AM_RESUME_ACTIVITY, next.userId,
System.identityHashCode(next), next.task.taskId, next.shortComponentName);
@@ -2669,9 +2659,7 @@ final class ActivityStack extends ConfigurationContainer {
if (!startIt) {
if (DEBUG_ADD_REMOVE) Slog.i(TAG, "Adding activity " + r + " to task "
+ task, new RuntimeException("here").fillInStackTrace());
- task.addActivityToTop(r);
- r.putInHistory();
- addConfigOverride(r, task);
+ r.createWindowContainer();
ActivityOptions.abort(options);
return;
}
@@ -2682,12 +2670,10 @@ final class ActivityStack extends ConfigurationContainer {
}
}
- // Place a new activity at top of stack, so it is next to interact
- // with the user.
+ // Place a new activity at top of stack, so it is next to interact with the user.
- // If we are not placing the new activity frontmost, we do not want
- // to deliver the onUserLeaving callback to the actual frontmost
- // activity
+ // If we are not placing the new activity frontmost, we do not want to deliver the
+ // onUserLeaving callback to the actual frontmost activity
if (task == r.task && mTaskHistory.indexOf(task) != (mTaskHistory.size() - 1)) {
mStackSupervisor.mUserLeaving = false;
if (DEBUG_USER_LEAVING) Slog.v(TAG_USER_LEAVING,
@@ -2699,10 +2685,9 @@ final class ActivityStack extends ConfigurationContainer {
// Slot the activity into the history stack and proceed
if (DEBUG_ADD_REMOVE) Slog.i(TAG, "Adding activity " + r + " to stack to task " + task,
new RuntimeException("here").fillInStackTrace());
- task.addActivityToTop(r);
+ r.createWindowContainer();
task.setFrontOfTask();
- r.putInHistory();
if (!isHomeOrRecentsStack() || numActivities() > 0) {
// We want to show the starting preview window if we are
// switching to a new task, or the next activity's process is
@@ -2737,7 +2722,6 @@ final class ActivityStack extends ConfigurationContainer {
mWindowManager.prepareAppTransition(transit, keepCurTransition);
mNoAnimActivities.remove(r);
}
- addConfigOverride(r, task);
boolean doShow = true;
if (newTask) {
// Even though this activity is starting fresh, we still need
@@ -2756,7 +2740,7 @@ final class ActivityStack extends ConfigurationContainer {
if (r.mLaunchTaskBehind) {
// Don't do a starting window for mLaunchTaskBehind. More importantly make sure we
// tell WindowManager that r is visible even though it is at the back of the stack.
- mWindowManager.setAppVisibility(r.appToken, true);
+ r.setVisibility(true);
ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
} else if (SHOW_APP_STARTING_PREVIEW && doShow) {
// Figure out if we are transitioning from another activity that is
@@ -2780,7 +2764,6 @@ final class ActivityStack extends ConfigurationContainer {
} else {
// If this is the first activity, don't do any fancy animations,
// because there is nothing for it to animate on top of.
- addConfigOverride(r, task);
ActivityOptions.abort(options);
}
}
@@ -2865,8 +2848,6 @@ final class ActivityStack extends ConfigurationContainer {
+ " out to new task " + target.task);
}
- setAppTask(target, targetTask);
-
boolean noOptions = canMoveOptions;
final int start = replyChainEnd < 0 ? i : replyChainEnd;
for (int srcPos = start; srcPos >= i; --srcPos) {
@@ -2889,8 +2870,6 @@ final class ActivityStack extends ConfigurationContainer {
"Pushing next activity " + p + " out to target's task " + target.task);
p.setTask(targetTask, null);
targetTask.addActivityAtBottom(p);
-
- setAppTask(p, targetTask);
}
mWindowManager.moveTaskToBottom(targetTask.taskId);
@@ -3028,7 +3007,6 @@ final class ActivityStack extends ConfigurationContainer {
+ " callers=" + Debug.getCallers(3));
if (DEBUG_TASKS) Slog.v(TAG_TASKS, "Pulling activity " + p
+ " from " + srcPos + " in to resetting task " + task);
- setAppTask(p, task);
}
mWindowManager.moveTaskToTop(taskId);
@@ -3223,7 +3201,7 @@ final class ActivityStack extends ConfigurationContainer {
if (DEBUG_VISIBILITY) Slog.v(TAG_VISIBILITY,
"Stopping visible=" + r.visible + " for " + r);
if (!r.visible) {
- mWindowManager.setAppVisibility(r.appToken, false);
+ r.setVisibility(false);
}
EventLogTags.writeAmStopActivity(
r.userId, System.identityHashCode(r), r.shortComponentName);
@@ -3457,7 +3435,7 @@ final class ActivityStack extends ConfigurationContainer {
mWindowManager.prepareAppTransition(transit, false);
// Tell window manager to prepare for this one to be removed.
- mWindowManager.setAppVisibility(r.appToken, false);
+ r.setVisibility(false);
if (mPausingActivity == null) {
if (DEBUG_PAUSE) Slog.v(TAG_PAUSE, "Finish needs to pause: " + r);
@@ -3475,7 +3453,7 @@ final class ActivityStack extends ConfigurationContainer {
if (DEBUG_PAUSE) Slog.v(TAG_PAUSE, "Finish not pausing: " + r);
if (r.visible) {
mWindowManager.prepareAppTransition(transit, false);
- mWindowManager.setAppVisibility(r.appToken, false);
+ r.setVisibility(false);
mWindowManager.executeAppTransition();
if (!mStackSupervisor.mWaitingVisibleActivities.contains(r)) {
mStackSupervisor.mWaitingVisibleActivities.add(r);
@@ -3782,7 +3760,7 @@ final class ActivityStack extends ConfigurationContainer {
r.state = ActivityState.DESTROYED;
if (DEBUG_APP) Slog.v(TAG_APP, "Clearing app during remove for activity " + r);
r.app = null;
- mWindowManager.removeAppToken(r.appToken, r.getDisplayId());
+ r.removeWindowContainer();
final TaskRecord task = r.task;
if (task != null && task.removeActivity(r)) {
if (DEBUG_STACK) Slog.i(TAG_STACK,
@@ -4981,17 +4959,6 @@ final class ActivityStack extends ConfigurationContainer {
}
}
- void addConfigOverride(ActivityRecord r, TaskRecord task) {
- task.updateOverrideConfigurationFromLaunchBounds();
- // TODO: VI deal with activity
- mWindowManager.addAppToken(task.mActivities.indexOf(r), r.appToken,
- r.task.taskId, r.info.screenOrientation, r.fullscreen,
- (r.info.flags & FLAG_SHOW_FOR_ALL_USERS) != 0, r.info.configChanges,
- task.voiceSession != null, r.mLaunchTaskBehind, r.isAlwaysFocusable(),
- r.appInfo.targetSdkVersion, r.mRotationAnimationHint);
- r.onOverrideConfigurationSent();
- }
-
void moveToFrontAndResumeStateIfNeeded(
ActivityRecord r, boolean moveToFront, boolean setResume, String reason) {
if (!moveToFront) {
@@ -5030,7 +4997,6 @@ final class ActivityStack extends ConfigurationContainer {
r.info, r.intent, null, null, true, r.mActivityType);
r.setTask(task, null);
task.addActivityToTop(r);
- setAppTask(r, task);
mStackSupervisor.scheduleReportPictureInPictureModeChangedIfNeeded(task, prevStack);
moveToFrontAndResumeStateIfNeeded(r, wasFocused, wasResumed, "moveActivityToStack");
if (wasResumed) {
@@ -5038,12 +5004,6 @@ final class ActivityStack extends ConfigurationContainer {
}
}
- private void setAppTask(ActivityRecord r, TaskRecord task) {
- task.updateOverrideConfigurationFromLaunchBounds();
- mWindowManager.addAppToTask(r.appToken, task.taskId);
- r.onOverrideConfigurationSent();
- }
-
public int getStackId() {
return mStackId;
}
diff --git a/services/core/java/com/android/server/am/ActivityStackSupervisor.java b/services/core/java/com/android/server/am/ActivityStackSupervisor.java
index 028c57117824..8ab3ac39dd5b 100644
--- a/services/core/java/com/android/server/am/ActivityStackSupervisor.java
+++ b/services/core/java/com/android/server/am/ActivityStackSupervisor.java
@@ -33,7 +33,6 @@ import static android.app.ActivityManager.StackId.HOME_STACK_ID;
import static android.app.ActivityManager.StackId.INVALID_STACK_ID;
import static android.app.ActivityManager.StackId.LAST_STATIC_STACK_ID;
import static android.app.ActivityManager.StackId.PINNED_STACK_ID;
-import static android.app.ActivityManager.StackId.RECENTS_STACK_ID;
import static android.content.Intent.FLAG_ACTIVITY_MULTIPLE_TASK;
import static android.content.Intent.FLAG_ACTIVITY_NEW_TASK;
import static android.content.pm.PackageManager.PERMISSION_GRANTED;
@@ -179,8 +178,7 @@ import java.util.List;
import java.util.Objects;
import java.util.Set;
-public class ActivityStackSupervisor extends ConfigurationContainer
- implements DisplayListener {
+public class ActivityStackSupervisor extends ConfigurationContainer implements DisplayListener {
private static final String TAG = TAG_WITH_CLASS_NAME ? "ActivityStackSupervisor" : TAG_AM;
private static final String TAG_CONTAINERS = TAG + POSTFIX_CONTAINERS;
private static final String TAG_FOCUS = TAG + POSTFIX_FOCUS;
@@ -1204,7 +1202,7 @@ public class ActivityStackSupervisor extends ConfigurationContainer
if (andResume) {
r.startFreezingScreenLocked(app, 0);
- mWindowManager.setAppVisibility(r.appToken, true);
+ r.setVisibility(true);
// schedule launch ticks to collect information about slow apps.
r.startLaunchTickingLocked();
@@ -1227,7 +1225,7 @@ public class ActivityStackSupervisor extends ConfigurationContainer
}
if (mKeyguardController.isKeyguardLocked()) {
- mWindowManager.notifyUnknownAppVisibilityLaunched(r.appToken);
+ r.notifyUnknownVisibilityLaunched();
}
r.app = app;
@@ -2577,7 +2575,7 @@ public class ActivityStackSupervisor extends ConfigurationContainer
"Added restored task=" + task + " to stack=" + stack);
final ArrayList<ActivityRecord> activities = task.mActivities;
for (int activityNdx = activities.size() - 1; activityNdx >= 0; --activityNdx) {
- stack.addConfigOverride(activities.get(activityNdx), task);
+ activities.get(activityNdx).createWindowContainer();
}
return true;
}
@@ -3169,7 +3167,7 @@ public class ActivityStackSupervisor extends ConfigurationContainer
task.setLastThumbnailLocked(r.screenshotActivityLocked());
mRecentTasks.addLocked(task);
mService.mTaskChangeNotificationController.notifyTaskStackChanged();
- mWindowManager.setAppVisibility(r.appToken, false);
+ r.setVisibility(false);
// When launching tasks behind, update the last active time of the top task after the new
// task has been shown briefly
@@ -3360,7 +3358,7 @@ public class ActivityStackSupervisor extends ConfigurationContainer
// normal flow and hide it once we determine that it is
// hidden by the activities in front of it.
if (DEBUG_STATES) Slog.v(TAG, "Before stopping, can hide: " + s);
- mWindowManager.setAppVisibility(s.appToken, false);
+ s.setVisibility(false);
}
}
if ((!waitingVisible || mService.isSleepingOrShuttingDownLocked()) && remove) {
diff --git a/services/core/java/com/android/server/am/TaskRecord.java b/services/core/java/com/android/server/am/TaskRecord.java
index 9e28068b8b73..a17cf3b79cab 100644
--- a/services/core/java/com/android/server/am/TaskRecord.java
+++ b/services/core/java/com/android/server/am/TaskRecord.java
@@ -849,6 +849,11 @@ final class TaskRecord extends ConfigurationContainer {
if (r.isPersistable()) {
mService.notifyTaskPersisterLocked(this, false);
}
+
+ // Sync. with window manager
+ updateOverrideConfigurationFromLaunchBounds();
+ r.positionWindowContainerAt(index);
+ r.onOverrideConfigurationSent();
}
/** @return true if this was the last activity in the task */
diff --git a/services/core/java/com/android/server/wm/AppWindowContainerController.java b/services/core/java/com/android/server/wm/AppWindowContainerController.java
new file mode 100644
index 000000000000..35004c295681
--- /dev/null
+++ b/services/core/java/com/android/server/wm/AppWindowContainerController.java
@@ -0,0 +1,526 @@
+/*
+ * Copyright (C) 2016 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.wm;
+
+import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
+import static android.view.WindowManager.LayoutParams.FLAG_SHOW_WALLPAPER;
+import static com.android.server.wm.AppTransition.TRANSIT_UNSET;
+import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_ADD_REMOVE;
+import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_APP_TRANSITIONS;
+import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_ORIENTATION;
+import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_SCREENSHOT;
+import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_STARTING_WINDOW;
+import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_TOKEN_MOVEMENT;
+import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_VISIBILITY;
+import static com.android.server.wm.WindowManagerDebugConfig.TAG_WM;
+import static com.android.server.wm.WindowManagerService.H.ADD_STARTING;
+
+import android.graphics.Bitmap;
+import android.os.Trace;
+import com.android.server.AttributeCache;
+
+import android.content.res.CompatibilityInfo;
+import android.content.res.Configuration;
+import android.os.Binder;
+import android.os.Debug;
+import android.os.IBinder;
+import android.os.Message;
+import android.util.Slog;
+import android.view.IApplicationToken;
+
+/**
+ * Controller for the app window token container. This is created by activity manager to link
+ * activity records to the app window token container they use in window manager.
+ *
+ * Test class: {@link AppWindowContainerControllerTests}
+ */
+public class AppWindowContainerController
+ extends WindowContainerController<AppWindowToken, AppWindowContainerListener> {
+
+ private final IApplicationToken mToken;
+
+ private final Runnable mOnWindowsDrawn = () -> {
+ if (mListener == null) {
+ return;
+ }
+ if (DEBUG_VISIBILITY) Slog.v(TAG_WM, "Reporting drawn in "
+ + AppWindowContainerController.this.mToken);
+ mListener.onWindowsDrawn();
+ };
+
+ private final Runnable mOnWindowsVisible = () -> {
+ if (mListener == null) {
+ return;
+ }
+ if (DEBUG_VISIBILITY) Slog.v(TAG_WM, "Reporting visible in "
+ + AppWindowContainerController.this.mToken);
+ mListener.onWindowsVisible();
+ };
+
+ private final Runnable mOnWindowsGone = () -> {
+ if (mListener == null) {
+ return;
+ }
+ if (DEBUG_VISIBILITY) Slog.v(TAG_WM, "Reporting gone in "
+ + AppWindowContainerController.this.mToken);
+ mListener.onWindowsGone();
+ };
+
+ public AppWindowContainerController(IApplicationToken token,
+ AppWindowContainerListener listener, int taskId, int index, int requestedOrientation,
+ boolean fullscreen, boolean showForAllUsers, int configChanges,
+ boolean voiceInteraction, boolean launchTaskBehind, boolean alwaysFocusable,
+ int targetSdkVersion, int rotationAnimationHint, long inputDispatchingTimeoutNanos) {
+ this(token, listener, taskId, index, requestedOrientation, fullscreen, showForAllUsers,
+ configChanges, voiceInteraction, launchTaskBehind, alwaysFocusable,
+ targetSdkVersion, rotationAnimationHint, inputDispatchingTimeoutNanos,
+ WindowManagerService.getInstance());
+ }
+
+ public AppWindowContainerController(IApplicationToken token,
+ AppWindowContainerListener listener, int taskId, int index, int requestedOrientation,
+ boolean fullscreen, boolean showForAllUsers, int configChanges,
+ boolean voiceInteraction, boolean launchTaskBehind, boolean alwaysFocusable,
+ int targetSdkVersion, int rotationAnimationHint, long inputDispatchingTimeoutNanos,
+ WindowManagerService service) {
+ super(listener, service);
+ mToken = token;
+ synchronized(mWindowMap) {
+ AppWindowToken atoken = mRoot.getAppWindowToken(mToken.asBinder());
+ if (atoken != null) {
+ // TODO: Should this throw an exception instead?
+ Slog.w(TAG_WM, "Attempted to add existing app token: " + mToken);
+ return;
+ }
+
+ // TODO: Have the controller for the task passed in when task are changed to use
+ // controller.
+ final Task task = mService.mTaskIdToTask.get(taskId);
+ if (task == null) {
+ throw new IllegalArgumentException("addAppToken: invalid taskId=" + taskId);
+ }
+
+ atoken = new AppWindowToken(mService, token, voiceInteraction, task.getDisplayContent(),
+ inputDispatchingTimeoutNanos, fullscreen, showForAllUsers, targetSdkVersion,
+ requestedOrientation, rotationAnimationHint, configChanges, launchTaskBehind,
+ alwaysFocusable, this);
+ if (DEBUG_TOKEN_MOVEMENT || DEBUG_ADD_REMOVE) Slog.v(TAG_WM, "addAppToken: " + atoken
+ + " task=" + taskId + " at " + index);
+ task.addChild(atoken, index);
+ }
+ }
+
+ public void removeContainer(int displayId) {
+ final long origId = Binder.clearCallingIdentity();
+ try {
+ synchronized(mWindowMap) {
+ final DisplayContent dc = mRoot.getDisplayContent(displayId);
+ if (dc == null) {
+ Slog.w(TAG_WM, "removeAppToken: Attempted to remove binder token: "
+ + mToken + " from non-existing displayId=" + displayId);
+ return;
+ }
+ dc.removeAppToken(mToken.asBinder());
+ super.removeContainer();
+ }
+ } finally {
+ Binder.restoreCallingIdentity(origId);
+ }
+ }
+
+ // TODO: Move to task window controller when that is created and rename to positionChildAt()
+ public void positionAt(int taskId, int index) {
+ synchronized(mService.mWindowMap) {
+ if (mContainer == null) {
+ Slog.w(TAG_WM,
+ "Attempted to position of non-existing app token: " + mToken);
+ return;
+ }
+
+ // TODO: Should get the window container from this owner when the task owner stuff is
+ // hooked-up.
+ final Task task = mService.mTaskIdToTask.get(taskId);
+ if (task == null) {
+ throw new IllegalArgumentException("positionChildAt: invalid taskId=" + taskId);
+ }
+ task.addChild(mContainer, index);
+ }
+
+ }
+
+ public Configuration setOrientation(int requestedOrientation, int displayId,
+ Configuration displayConfig, boolean freezeScreenIfNeeded) {
+ synchronized(mWindowMap) {
+ if (mContainer == null) {
+ Slog.w(TAG_WM,
+ "Attempted to set orientation of non-existing app token: " + mToken);
+ return null;
+ }
+
+ mContainer.setOrientation(requestedOrientation);
+
+ final IBinder binder = freezeScreenIfNeeded ? mToken.asBinder() : null;
+ return mService.updateOrientationFromAppTokens(displayConfig, binder, displayId);
+
+ }
+ }
+
+ public int getOrientation() {
+ synchronized(mWindowMap) {
+ if (mContainer == null) {
+ return SCREEN_ORIENTATION_UNSPECIFIED;
+ }
+
+ return mContainer.getOrientationIgnoreVisibility();
+ }
+ }
+
+ public void setVisibility(boolean visible) {
+ synchronized(mWindowMap) {
+ if (mContainer == null) {
+ Slog.w(TAG_WM, "Attempted to set visibility of non-existing app token: "
+ + mToken);
+ return;
+ }
+
+ final AppWindowToken wtoken = mContainer;
+
+ if (DEBUG_APP_TRANSITIONS || DEBUG_ORIENTATION) Slog.v(TAG_WM, "setAppVisibility("
+ + mToken + ", visible=" + visible + "): " + mService.mAppTransition
+ + " hidden=" + wtoken.hidden + " hiddenRequested="
+ + wtoken.hiddenRequested + " Callers=" + Debug.getCallers(6));
+
+ mService.mOpeningApps.remove(wtoken);
+ mService.mClosingApps.remove(wtoken);
+ wtoken.waitingToShow = false;
+ wtoken.hiddenRequested = !visible;
+
+ if (!visible) {
+ // If the app is dead while it was visible, we kept its dead window on screen.
+ // Now that the app is going invisible, we can remove it. It will be restarted
+ // if made visible again.
+ wtoken.removeDeadWindows();
+ wtoken.setVisibleBeforeClientHidden();
+ } else {
+ if (!mService.mAppTransition.isTransitionSet()
+ && mService.mAppTransition.isReady()) {
+ // Add the app mOpeningApps if transition is unset but ready. This means
+ // we're doing a screen freeze, and the unfreeze will wait for all opening
+ // apps to be ready.
+ mService.mOpeningApps.add(wtoken);
+ }
+ wtoken.startingMoved = false;
+ // If the token is currently hidden (should be the common case), or has been
+ // stopped, then we need to set up to wait for its windows to be ready.
+ if (wtoken.hidden || wtoken.mAppStopped) {
+ wtoken.clearAllDrawn();
+
+ // If the app was already visible, don't reset the waitingToShow state.
+ if (wtoken.hidden) {
+ wtoken.waitingToShow = true;
+ }
+
+ if (wtoken.clientHidden) {
+ // In the case where we are making an app visible
+ // but holding off for a transition, we still need
+ // to tell the client to make its windows visible so
+ // they get drawn. Otherwise, we will wait on
+ // performing the transition until all windows have
+ // been drawn, they never will be, and we are sad.
+ wtoken.clientHidden = false;
+ wtoken.sendAppVisibilityToClients();
+ }
+ }
+ wtoken.requestUpdateWallpaperIfNeeded();
+
+ if (DEBUG_ADD_REMOVE) Slog.v(TAG_WM, "No longer Stopped: " + wtoken);
+ wtoken.mAppStopped = false;
+ }
+
+ // If we are preparing an app transition, then delay changing
+ // the visibility of this token until we execute that transition.
+ if (mService.okToDisplay() && mService.mAppTransition.isTransitionSet()) {
+ // A dummy animation is a placeholder animation which informs others that an
+ // animation is going on (in this case an application transition). If the animation
+ // was transferred from another application/animator, no dummy animator should be
+ // created since an animation is already in progress.
+ if (wtoken.mAppAnimator.usingTransferredAnimation
+ && wtoken.mAppAnimator.animation == null) {
+ Slog.wtf(TAG_WM, "Will NOT set dummy animation on: " + wtoken
+ + ", using null transferred animation!");
+ }
+ if (!wtoken.mAppAnimator.usingTransferredAnimation &&
+ (!wtoken.startingDisplayed || mService.mSkipAppTransitionAnimation)) {
+ if (DEBUG_APP_TRANSITIONS) Slog.v(
+ TAG_WM, "Setting dummy animation on: " + wtoken);
+ wtoken.mAppAnimator.setDummyAnimation();
+ }
+ wtoken.inPendingTransaction = true;
+ if (visible) {
+ mService.mOpeningApps.add(wtoken);
+ wtoken.mEnteringAnimation = true;
+ } else {
+ mService.mClosingApps.add(wtoken);
+ wtoken.mEnteringAnimation = false;
+ }
+ if (mService.mAppTransition.getAppTransition()
+ == AppTransition.TRANSIT_TASK_OPEN_BEHIND) {
+ // We're launchingBehind, add the launching activity to mOpeningApps.
+ final WindowState win =
+ mService.getDefaultDisplayContentLocked().findFocusedWindow();
+ if (win != null) {
+ final AppWindowToken focusedToken = win.mAppToken;
+ if (focusedToken != null) {
+ if (DEBUG_APP_TRANSITIONS) Slog.d(TAG_WM, "TRANSIT_TASK_OPEN_BEHIND, "
+ + " adding " + focusedToken + " to mOpeningApps");
+ // Force animation to be loaded.
+ focusedToken.hidden = true;
+ mService.mOpeningApps.add(focusedToken);
+ }
+ }
+ }
+ return;
+ }
+
+ wtoken.setVisibility(null, visible, TRANSIT_UNSET, true, wtoken.mVoiceInteraction);
+ wtoken.updateReportedVisibilityLocked();
+ }
+ }
+
+ /**
+ * Notifies that we launched an app that might be visible or not visible depending on what kind
+ * of Keyguard flags it's going to set on its windows.
+ */
+ public void notifyUnknownVisibilityLaunched() {
+ synchronized(mWindowMap) {
+ if (mContainer != null) {
+ mService.mUnknownAppVisibilityController.notifyLaunched(mContainer);
+ }
+ }
+ }
+
+ public boolean addStartingWindow(String pkg, int theme, CompatibilityInfo compatInfo,
+ CharSequence nonLocalizedLabel, int labelRes, int icon, int logo, int windowFlags,
+ IBinder transferFrom, boolean createIfNeeded) {
+ synchronized(mWindowMap) {
+ if (DEBUG_STARTING_WINDOW) Slog.v(TAG_WM, "setAppStartingWindow: token=" + mToken
+ + " pkg=" + pkg + " transferFrom=" + transferFrom);
+
+ if (mContainer == null) {
+ Slog.w(TAG_WM, "Attempted to set icon of non-existing app token: " + mToken);
+ return false;
+ }
+
+ // If the display is frozen, we won't do anything until the actual window is
+ // displayed so there is no reason to put in the starting window.
+ if (!mService.okToDisplay()) {
+ return false;
+ }
+
+ if (mContainer.startingData != null) {
+ return false;
+ }
+
+ // If this is a translucent window, then don't show a starting window -- the current
+ // effect (a full-screen opaque starting window that fades away to the real contents
+ // when it is ready) does not work for this.
+ if (DEBUG_STARTING_WINDOW) Slog.v(TAG_WM, "Checking theme of starting window: 0x"
+ + Integer.toHexString(theme));
+ if (theme != 0) {
+ AttributeCache.Entry ent = AttributeCache.instance().get(pkg, theme,
+ com.android.internal.R.styleable.Window, mService.mCurrentUserId);
+ if (ent == null) {
+ // Whoops! App doesn't exist. Um. Okay. We'll just pretend like we didn't
+ // see that.
+ return false;
+ }
+ final boolean windowIsTranslucent = ent.array.getBoolean(
+ com.android.internal.R.styleable.Window_windowIsTranslucent, false);
+ final boolean windowIsFloating = ent.array.getBoolean(
+ com.android.internal.R.styleable.Window_windowIsFloating, false);
+ final boolean windowShowWallpaper = ent.array.getBoolean(
+ com.android.internal.R.styleable.Window_windowShowWallpaper, false);
+ final boolean windowDisableStarting = ent.array.getBoolean(
+ com.android.internal.R.styleable.Window_windowDisablePreview, false);
+ if (DEBUG_STARTING_WINDOW) Slog.v(TAG_WM, "Translucent=" + windowIsTranslucent
+ + " Floating=" + windowIsFloating
+ + " ShowWallpaper=" + windowShowWallpaper);
+ if (windowIsTranslucent) {
+ return false;
+ }
+ if (windowIsFloating || windowDisableStarting) {
+ return false;
+ }
+ if (windowShowWallpaper) {
+ if (mContainer.getDisplayContent().mWallpaperController.getWallpaperTarget()
+ == null) {
+ // If this theme is requesting a wallpaper, and the wallpaper
+ // is not currently visible, then this effectively serves as
+ // an opaque window and our starting window transition animation
+ // can still work. We just need to make sure the starting window
+ // is also showing the wallpaper.
+ windowFlags |= FLAG_SHOW_WALLPAPER;
+ } else {
+ return false;
+ }
+ }
+ }
+
+ if (mContainer.transferStartingWindow(transferFrom)) {
+ return true;
+ }
+
+ // There is no existing starting window, and the caller doesn't
+ // want us to create one, so that's it!
+ if (!createIfNeeded) {
+ return false;
+ }
+
+ if (DEBUG_STARTING_WINDOW) Slog.v(TAG_WM, "Creating StartingData");
+ mContainer.startingData = new StartingData(pkg, theme, compatInfo, nonLocalizedLabel,
+ labelRes, icon, logo, windowFlags);
+ final Message m = mService.mH.obtainMessage(ADD_STARTING, mContainer);
+ // Note: we really want to do sendMessageAtFrontOfQueue() because we
+ // want to process the message ASAP, before any other queued
+ // messages.
+ if (DEBUG_STARTING_WINDOW) Slog.v(TAG_WM, "Enqueueing ADD_STARTING");
+ mService.mH.sendMessageAtFrontOfQueue(m);
+ }
+ return true;
+ }
+
+ public void removeStartingWindow() {
+ synchronized (mWindowMap) {
+ mService.scheduleRemoveStartingWindowLocked(mContainer);
+ }
+ }
+
+ public void pauseKeyDispatching() {
+ synchronized (mWindowMap) {
+ if (mContainer != null) {
+ mService.mInputMonitor.pauseDispatchingLw(mContainer);
+ }
+ }
+ }
+
+ public void resumeKeyDispatching() {
+ synchronized (mWindowMap) {
+ if (mContainer != null) {
+ mService.mInputMonitor.resumeDispatchingLw(mContainer);
+ }
+ }
+ }
+
+ public void notifyAppResumed(boolean wasStopped, boolean allowSavedSurface) {
+ synchronized(mWindowMap) {
+ if (mContainer == null) {
+ Slog.w(TAG_WM, "Attempted to notify resumed of non-existing app token: " + mToken);
+ return;
+ }
+ mContainer.notifyAppResumed(wasStopped, allowSavedSurface);
+ }
+ }
+
+ public void notifyAppStopped() {
+ synchronized(mWindowMap) {
+ if (mContainer == null) {
+ Slog.w(TAG_WM, "Attempted to notify stopped of non-existing app token: "
+ + mToken);
+ return;
+ }
+ mContainer.notifyAppStopped();
+ }
+ }
+
+ public void startFreezingScreen(int configChanges) {
+ synchronized(mWindowMap) {
+ if (configChanges == 0 && mService.okToDisplay()) {
+ if (DEBUG_ORIENTATION) Slog.v(TAG_WM, "Skipping set freeze of " + mToken);
+ return;
+ }
+
+ if (mContainer == null) {
+ Slog.w(TAG_WM,
+ "Attempted to freeze screen with non-existing app token: " + mContainer);
+ return;
+ }
+ final long origId = Binder.clearCallingIdentity();
+ mContainer.startFreezingScreen();
+ Binder.restoreCallingIdentity(origId);
+ }
+ }
+
+ public void stopFreezingScreen(boolean force) {
+ synchronized(mWindowMap) {
+ if (mContainer == null) {
+ return;
+ }
+ final long origId = Binder.clearCallingIdentity();
+ if (DEBUG_ORIENTATION) Slog.v(TAG_WM, "Clear freezing of " + mToken + ": hidden="
+ + mContainer.hidden + " freezing=" + mContainer.mAppAnimator.freezingScreen);
+ mContainer.stopFreezingScreen(true, force);
+ Binder.restoreCallingIdentity(origId);
+ }
+ }
+
+ /**
+ * Takes a snapshot of the screen. In landscape mode this grabs the whole screen.
+ * In portrait mode, it grabs the full screenshot.
+ *
+ * @param displayId the Display to take a screenshot of.
+ * @param width the width of the target bitmap
+ * @param height the height of the target bitmap
+ * @param frameScale the scale to apply to the frame, only used when width = -1 and height = -1
+ */
+ public Bitmap screenshotApplications(int displayId, int width, int height, float frameScale) {
+ try {
+ Trace.traceBegin(Trace.TRACE_TAG_WINDOW_MANAGER, "screenshotApplications");
+ final DisplayContent dc;
+ synchronized(mWindowMap) {
+ dc = mRoot.getDisplayContentOrCreate(displayId);
+ if (dc == null) {
+ if (DEBUG_SCREENSHOT) Slog.i(TAG_WM, "Screenshot of " + mToken
+ + ": returning null. No Display for displayId=" + displayId);
+ return null;
+ }
+ }
+ return dc.screenshotApplications(mToken.asBinder(), width, height,
+ false /* includeFullDisplay */, frameScale, Bitmap.Config.RGB_565,
+ false /* wallpaperOnly */);
+ } finally {
+ Trace.traceEnd(Trace.TRACE_TAG_WINDOW_MANAGER);
+ }
+ }
+
+
+ void reportWindowsDrawn() {
+ mService.mH.post(mOnWindowsDrawn);
+ }
+
+ void reportWindowsVisible() {
+ mService.mH.post(mOnWindowsVisible);
+ }
+
+ void reportWindowsGone() {
+ mService.mH.post(mOnWindowsGone);
+ }
+
+ /** Calls directly into activity manager so window manager lock shouldn't held. */
+ boolean keyDispatchingTimedOut(String reason) {
+ return mListener != null && mListener.keyDispatchingTimedOut(reason);
+ }
+}
diff --git a/services/core/java/com/android/server/wm/AppWindowContainerListener.java b/services/core/java/com/android/server/wm/AppWindowContainerListener.java
new file mode 100644
index 000000000000..12d4b2fcb132
--- /dev/null
+++ b/services/core/java/com/android/server/wm/AppWindowContainerListener.java
@@ -0,0 +1,32 @@
+/*
+ * Copyright (C) 2016 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.wm;
+
+/** Interface used by the creator of the controller to listen to changes with the container. */
+public interface AppWindowContainerListener extends WindowContainerListener {
+ /** Called when the windows associated app window container are drawn. */
+ void onWindowsDrawn();
+ /** Called when the windows associated app window container are visible. */
+ void onWindowsVisible();
+ /** Called when the windows associated app window container are no longer visible. */
+ void onWindowsGone();
+ /**
+ * Called when the key dispatching to a window associated with the app window container
+ * timed-out.
+ */
+ boolean keyDispatchingTimedOut(String reason);
+}
diff --git a/services/core/java/com/android/server/wm/AppWindowToken.java b/services/core/java/com/android/server/wm/AppWindowToken.java
index 6147885a4a2e..0a4875810aba 100644
--- a/services/core/java/com/android/server/wm/AppWindowToken.java
+++ b/services/core/java/com/android/server/wm/AppWindowToken.java
@@ -47,7 +47,6 @@ import static com.android.server.wm.WindowManagerService.UPDATE_FOCUS_NORMAL;
import static com.android.server.wm.WindowManagerService.UPDATE_FOCUS_WILL_PLACE_SURFACES;
import static com.android.server.wm.WindowManagerService.logWithStack;
-import android.content.pm.ActivityInfo;
import android.os.Debug;
import com.android.internal.util.ToBooleanFunction;
import com.android.server.input.InputApplicationHandle;
@@ -173,8 +172,10 @@ class AppWindowToken extends WindowToken implements WindowManagerService.AppFree
AppWindowToken(WindowManagerService service, IApplicationToken token, boolean voiceInteraction,
DisplayContent dc, long inputDispatchingTimeoutNanos, boolean fullscreen,
boolean showForAllUsers, int targetSdk, int orientation, int rotationAnimationHint,
- int configChanges, boolean launchTaskBehind, boolean alwaysFocusable) {
+ int configChanges, boolean launchTaskBehind, boolean alwaysFocusable,
+ AppWindowContainerController controller) {
this(service, token, voiceInteraction, dc);
+ setController(controller);
mInputDispatchingTimeoutNanos = inputDispatchingTimeoutNanos;
mFillsParent = fullscreen;
mShowForAllUsers = showForAllUsers;
@@ -251,9 +252,12 @@ class AppWindowToken extends WindowToken implements WindowManagerService.AppFree
}
if (DEBUG_VISIBILITY) Slog.v(TAG, "VIS " + this + ": interesting="
+ numInteresting + " visible=" + numVisible);
+ final AppWindowContainerController controller = getController();
if (nowDrawn != reportedDrawn) {
if (nowDrawn) {
- mService.mH.obtainMessage(H.REPORT_APPLICATION_TOKEN_DRAWN, this).sendToTarget();
+ if (controller != null) {
+ controller.reportWindowsDrawn();
+ }
}
reportedDrawn = nowDrawn;
}
@@ -261,8 +265,13 @@ class AppWindowToken extends WindowToken implements WindowManagerService.AppFree
if (DEBUG_VISIBILITY) Slog.v(TAG,
"Visibility changed in " + this + ": vis=" + nowVisible);
reportedVisible = nowVisible;
- mService.mH.obtainMessage(H.REPORT_APPLICATION_TOKEN_WINDOWS,
- nowVisible ? 1 : 0, nowGone ? 1 : 0, this).sendToTarget();
+ if (controller != null) {
+ if (nowVisible) {
+ controller.reportWindowsVisible();
+ } else {
+ controller.reportWindowsGone();
+ }
+ }
}
}
@@ -399,6 +408,11 @@ class AppWindowToken extends WindowToken implements WindowManagerService.AppFree
return StackId.canReceiveKeys(mTask.mStack.mStackId) || mAlwaysFocusable;
}
+ AppWindowContainerController getController() {
+ final WindowContainerController controller = super.getController();
+ return controller != null ? (AppWindowContainerController) controller : null;
+ }
+
@Override
boolean isVisible() {
// If the app token isn't hidden then it is considered visible and there is no need to check
diff --git a/services/core/java/com/android/server/wm/InputMonitor.java b/services/core/java/com/android/server/wm/InputMonitor.java
index 3fbe36f78112..f754775e286a 100644
--- a/services/core/java/com/android/server/wm/InputMonitor.java
+++ b/services/core/java/com/android/server/wm/InputMonitor.java
@@ -251,16 +251,14 @@ final class InputMonitor implements InputManagerService.WindowManagerCallbacks {
}
if (appWindowToken != null && appWindowToken.appToken != null) {
- try {
- // Notify the activity manager about the timeout and let it decide whether
- // to abort dispatching or keep waiting.
- boolean abort = appWindowToken.appToken.keyDispatchingTimedOut(reason);
- if (! abort) {
- // The activity manager declined to abort dispatching.
- // Wait a bit longer and timeout again later.
- return appWindowToken.mInputDispatchingTimeoutNanos;
- }
- } catch (RemoteException ex) {
+ // Notify the activity manager about the timeout and let it decide whether
+ // to abort dispatching or keep waiting.
+ final AppWindowContainerController controller = appWindowToken.getController();
+ final boolean abort = controller != null && controller.keyDispatchingTimedOut(reason);
+ if (!abort) {
+ // The activity manager declined to abort dispatching.
+ // Wait a bit longer and timeout again later.
+ return appWindowToken.mInputDispatchingTimeoutNanos;
}
} else if (windowState != null) {
try {
diff --git a/services/core/java/com/android/server/wm/WindowContainer.java b/services/core/java/com/android/server/wm/WindowContainer.java
index c9bf4fa55efd..0e6ecde0506a 100644
--- a/services/core/java/com/android/server/wm/WindowContainer.java
+++ b/services/core/java/com/android/server/wm/WindowContainer.java
@@ -75,6 +75,9 @@ class WindowContainer<E extends WindowContainer> implements Comparable<WindowCon
private final Pools.SynchronizedPool<ForAllWindowsConsumerWrapper> mConsumerWrapperPool =
new Pools.SynchronizedPool<>(3);
+ // The owner/creator for this container. No controller if null.
+ private WindowContainerController mController;
+
final protected WindowContainer getParent() {
return mParent;
}
@@ -188,6 +191,10 @@ class WindowContainer<E extends WindowContainer> implements Comparable<WindowCon
if (mParent != null) {
mParent.removeChild(this);
}
+
+ if (mController != null) {
+ setController(null);
+ }
}
/**
@@ -662,6 +669,23 @@ class WindowContainer<E extends WindowContainer> implements Comparable<WindowCon
} while (current != null);
}
+ WindowContainerController getController() {
+ return mController;
+ }
+
+ void setController(WindowContainerController controller) {
+ if (mController != null && controller != null) {
+ throw new IllegalArgumentException("Can't set controller=" + mController
+ + " for container=" + this + " Already set to=" + mController);
+ }
+ if (controller != null) {
+ controller.setContainer(this);
+ } else if (mController != null) {
+ mController.setContainer(null);
+ }
+ mController = controller;
+ }
+
/**
* Dumps the names of this container children in the input print writer indenting each
* level with the input prefix.
diff --git a/services/core/java/com/android/server/wm/WindowContainerController.java b/services/core/java/com/android/server/wm/WindowContainerController.java
new file mode 100644
index 000000000000..84ffc35b4651
--- /dev/null
+++ b/services/core/java/com/android/server/wm/WindowContainerController.java
@@ -0,0 +1,70 @@
+/*
+ * Copyright (C) 2016 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.wm;
+
+import android.os.IBinder;
+
+import java.util.HashMap;
+
+/**
+ * Class that allows the owner/creator of a {@link WindowContainer} to communicate directly with the
+ * container and make changes.
+ * Note that public calls (mostly in sub-classes) into this class are assumed to be originating from
+ * outside the window manager so the window manager lock is held and appropriate permissions are
+ * checked before calls are allowed to proceed.
+ *
+ * Test class: {@link WindowContainerControllerTests}
+ */
+class WindowContainerController<E extends WindowContainer, I extends WindowContainerListener> {
+
+ final WindowManagerService mService;
+ final RootWindowContainer mRoot;
+ final HashMap<IBinder, WindowState> mWindowMap;
+
+ // The window container this controller owns.
+ E mContainer;
+ // Interface for communicating changes back to the owner.
+ final I mListener;
+
+ WindowContainerController(I listener, WindowManagerService service) {
+ mListener = listener;
+ mService = service;
+ mRoot = mService != null ? mService.mRoot : null;
+ mWindowMap = mService != null ? mService.mWindowMap : null;
+ }
+
+ void setContainer(E container) {
+ if (mContainer != null && container != null) {
+ throw new IllegalArgumentException("Can't set container=" + container
+ + " for controller=" + this + " Already set to=" + mContainer);
+ }
+ mContainer = container;
+ }
+
+ void removeContainer() {
+ // TODO: See if most uses cases should support removeIfPossible here.
+ //mContainer.removeIfPossible();
+ if (mContainer != null) {
+ mContainer.setController(null);
+ mContainer = null;
+ }
+ }
+
+ boolean checkCallingPermission(String permission, String func) {
+ return mService.checkCallingPermission(permission, func);
+ }
+}
diff --git a/services/core/java/com/android/server/wm/WindowContainerListener.java b/services/core/java/com/android/server/wm/WindowContainerListener.java
new file mode 100644
index 000000000000..ab9d71ac2ea8
--- /dev/null
+++ b/services/core/java/com/android/server/wm/WindowContainerListener.java
@@ -0,0 +1,25 @@
+/*
+ * Copyright (C) 2016 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.wm;
+
+/**
+ * Interface used by the owner/creator of the container to listen to changes with the container.
+ * @see WindowContainerController
+ */
+public interface WindowContainerListener {
+
+}
diff --git a/services/core/java/com/android/server/wm/WindowManagerService.java b/services/core/java/com/android/server/wm/WindowManagerService.java
index f6d3881e9485..d5aa01b6a0b7 100644
--- a/services/core/java/com/android/server/wm/WindowManagerService.java
+++ b/services/core/java/com/android/server/wm/WindowManagerService.java
@@ -90,7 +90,6 @@ import android.view.DisplayInfo;
import android.view.Gravity;
import android.view.PointerIcon;
import android.view.IAppTransitionAnimationSpecsFuture;
-import android.view.IApplicationToken;
import android.view.IDockedStackListener;
import android.view.IInputFilter;
import android.view.IOnKeyguardExitResult;
@@ -133,7 +132,6 @@ import com.android.internal.view.IInputContext;
import com.android.internal.view.IInputMethodClient;
import com.android.internal.view.IInputMethodManager;
import com.android.internal.view.WindowManagerPolicyThread;
-import com.android.server.AttributeCache;
import com.android.server.DisplayThread;
import com.android.server.EventLogTags;
import com.android.server.FgThread;
@@ -228,7 +226,6 @@ import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_SCREEN_ON;
import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_STACK;
import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_STARTING_WINDOW;
import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_TASK_POSITIONING;
-import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_TOKEN_MOVEMENT;
import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_VISIBILITY;
import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_WALLPAPER_LIGHT;
import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_WINDOW_MOVEMENT;
@@ -240,7 +237,6 @@ import static com.android.server.wm.WindowManagerDebugConfig.SHOW_VERBOSE_TRANSA
import static com.android.server.wm.WindowManagerDebugConfig.TAG_KEEP_SCREEN_ON;
import static com.android.server.wm.WindowManagerDebugConfig.TAG_WITH_CLASS_NAME;
import static com.android.server.wm.WindowManagerDebugConfig.TAG_WM;
-import static java.lang.Integer.MAX_VALUE;
/** {@hide} */
public class WindowManagerService extends IWindowManager.Stub
@@ -915,16 +911,19 @@ public class WindowManagerService extends IWindowManager.Stub
void onAppFreezeTimeout();
}
- public static WindowManagerService main(final Context context,
- final InputManagerService im,
- final boolean haveInputMethods, final boolean showBootMsgs,
- final boolean onlyCore, WindowManagerPolicy policy) {
- final WindowManagerService[] holder = new WindowManagerService[1];
- DisplayThread.getHandler().runWithScissors(() -> {
- holder[0] = new WindowManagerService(context, im, haveInputMethods, showBootMsgs,
- onlyCore, policy);
- }, 0);
- return holder[0];
+ private static WindowManagerService sInstance;
+
+ static WindowManagerService getInstance() {
+ return sInstance;
+ }
+
+ public static WindowManagerService main(final Context context, final InputManagerService im,
+ final boolean haveInputMethods, final boolean showBootMsgs, final boolean onlyCore,
+ WindowManagerPolicy policy) {
+ DisplayThread.getHandler().runWithScissors(() ->
+ sInstance = new WindowManagerService(context, im, haveInputMethods, showBootMsgs,
+ onlyCore, policy), 0);
+ return sInstance;
}
private void initPolicy() {
@@ -2369,7 +2368,7 @@ public class WindowManagerService extends IWindowManager.Stub
return atoken.mAppAnimator.animation != null;
}
- private boolean checkCallingPermission(String permission, String func) {
+ boolean checkCallingPermission(String permission, String func) {
// Quick check: if the calling permission is me, it's all okay.
if (Binder.getCallingPid() == Process.myPid()) {
return true;
@@ -2442,73 +2441,6 @@ public class WindowManagerService extends IWindowManager.Stub
}
}
- @Override
- public void addAppToken(int addPos, IApplicationToken token, int taskId,
- int requestedOrientation, boolean fullscreen, boolean showForAllUsers,
- int configChanges, boolean voiceInteraction, boolean launchTaskBehind,
- boolean alwaysFocusable, int targetSdkVersion, int rotationAnimationHint) {
- if (!checkCallingPermission(MANAGE_APP_TOKENS, "addAppToken()")) {
- throw new SecurityException("Requires MANAGE_APP_TOKENS permission");
- }
-
- // Get the dispatching timeout here while we are not holding any locks so that it
- // can be cached by the AppWindowToken. The timeout value is used later by the
- // input dispatcher in code that does hold locks. If we did not cache the value
- // here we would run the chance of introducing a deadlock between the window manager
- // (which holds locks while updating the input dispatcher state) and the activity manager
- // (which holds locks while querying the application token).
- long inputDispatchingTimeoutNanos;
- try {
- inputDispatchingTimeoutNanos = token.getKeyDispatchingTimeout() * 1000000L;
- } catch (RemoteException ex) {
- Slog.w(TAG_WM, "Could not get dispatching timeout.", ex);
- inputDispatchingTimeoutNanos = DEFAULT_INPUT_DISPATCHING_TIMEOUT_NANOS;
- }
-
- synchronized(mWindowMap) {
- AppWindowToken atoken = mRoot.getAppWindowToken(token.asBinder());
- if (atoken != null) {
- Slog.w(TAG_WM, "Attempted to add existing app token: " + token);
- return;
- }
-
- Task task = mTaskIdToTask.get(taskId);
- if (task == null) {
- throw new IllegalArgumentException("addAppToken: invalid taskId=" + taskId);
- }
-
- atoken = new AppWindowToken(this, token, voiceInteraction, task.getDisplayContent(),
- inputDispatchingTimeoutNanos, fullscreen, showForAllUsers, targetSdkVersion,
- requestedOrientation, rotationAnimationHint, configChanges, launchTaskBehind,
- alwaysFocusable);
- if (DEBUG_TOKEN_MOVEMENT || DEBUG_ADD_REMOVE) Slog.v(TAG_WM, "addAppToken: " + atoken
- + " task=" + taskId + " at " + addPos);
-
- task.addChild(atoken, addPos);
- }
- }
-
- @Override
- public void addAppToTask(IBinder token, int taskId) {
- if (!checkCallingPermission(MANAGE_APP_TOKENS, "setAppTask()")) {
- throw new SecurityException("Requires MANAGE_APP_TOKENS permission");
- }
-
- synchronized(mWindowMap) {
- final AppWindowToken atoken = mRoot.getAppWindowToken(token);
- if (atoken == null) {
- Slog.w(TAG_WM, "Attempted to set task id of non-existing app token: " + token);
- return;
- }
-
- Task task = mTaskIdToTask.get(taskId);
- if (task == null) {
- throw new IllegalArgumentException("setAppTask: invalid taskId=" + taskId);
- }
- task.addChild(atoken, MAX_VALUE /* at top */);
- }
- }
-
public void addTask(int taskId, int stackId, int userId, Rect bounds,
Configuration overrideConfig, int resizeMode, boolean homeTask, boolean isOnTopLauncher,
boolean toTop, boolean showForAllUsers) {
@@ -2675,35 +2607,6 @@ public class WindowManagerService extends IWindowManager.Stub
}
}
- @Override
- public void setAppOrientation(IApplicationToken token, int requestedOrientation) {
- if (!checkCallingPermission(MANAGE_APP_TOKENS, "setAppOrientation()")) {
- throw new SecurityException("Requires MANAGE_APP_TOKENS permission");
- }
-
- synchronized(mWindowMap) {
- final AppWindowToken atoken = mRoot.getAppWindowToken(token.asBinder());
- if (atoken == null) {
- Slog.w(TAG_WM, "Attempted to set orientation of non-existing app token: " + token);
- return;
- }
-
- atoken.setOrientation(requestedOrientation);
- }
- }
-
- @Override
- public int getAppOrientation(IApplicationToken token) {
- synchronized(mWindowMap) {
- final AppWindowToken wtoken = mRoot.getAppWindowToken(token.asBinder());
- if (wtoken == null) {
- return SCREEN_ORIENTATION_UNSPECIFIED;
- }
-
- return wtoken.getOrientationIgnoreVisibility();
- }
- }
-
void setFocusTaskRegionLocked() {
final Task focusedTask = mFocusedApp != null ? mFocusedApp.mTask : null;
if (focusedTask != null) {
@@ -2912,113 +2815,6 @@ public class WindowManagerService extends IWindowManager.Stub
}
}
- @Override
- public boolean setAppStartingWindow(IBinder token, String pkg,
- int theme, CompatibilityInfo compatInfo,
- CharSequence nonLocalizedLabel, int labelRes, int icon, int logo,
- int windowFlags, IBinder transferFrom, boolean createIfNeeded) {
- if (!checkCallingPermission(MANAGE_APP_TOKENS, "setAppStartingWindow()")) {
- throw new SecurityException("Requires MANAGE_APP_TOKENS permission");
- }
-
- synchronized(mWindowMap) {
- if (DEBUG_STARTING_WINDOW) Slog.v(
- TAG_WM, "setAppStartingWindow: token=" + token + " pkg=" + pkg
- + " transferFrom=" + transferFrom);
-
- final AppWindowToken wtoken = mRoot.getAppWindowToken(token);
- if (wtoken == null) {
- Slog.w(TAG_WM, "Attempted to set icon of non-existing app token: " + token);
- return false;
- }
-
- // If the display is frozen, we won't do anything until the
- // actual window is displayed so there is no reason to put in
- // the starting window.
- if (!okToDisplay()) {
- return false;
- }
-
- if (wtoken.startingData != null) {
- return false;
- }
-
- // If this is a translucent window, then don't
- // show a starting window -- the current effect (a full-screen
- // opaque starting window that fades away to the real contents
- // when it is ready) does not work for this.
- if (DEBUG_STARTING_WINDOW) Slog.v(TAG_WM, "Checking theme of starting window: 0x"
- + Integer.toHexString(theme));
- if (theme != 0) {
- AttributeCache.Entry ent = AttributeCache.instance().get(pkg, theme,
- com.android.internal.R.styleable.Window, mCurrentUserId);
- if (ent == null) {
- // Whoops! App doesn't exist. Um. Okay. We'll just
- // pretend like we didn't see that.
- return false;
- }
- final boolean windowIsTranslucent = ent.array.getBoolean(
- com.android.internal.R.styleable.Window_windowIsTranslucent, false);
- final boolean windowIsFloating = ent.array.getBoolean(
- com.android.internal.R.styleable.Window_windowIsFloating, false);
- final boolean windowShowWallpaper = ent.array.getBoolean(
- com.android.internal.R.styleable.Window_windowShowWallpaper, false);
- final boolean windowDisableStarting = ent.array.getBoolean(
- com.android.internal.R.styleable.Window_windowDisablePreview, false);
- if (DEBUG_STARTING_WINDOW) Slog.v(TAG_WM, "Translucent=" + windowIsTranslucent
- + " Floating=" + windowIsFloating
- + " ShowWallpaper=" + windowShowWallpaper);
- if (windowIsTranslucent) {
- return false;
- }
- if (windowIsFloating || windowDisableStarting) {
- return false;
- }
- if (windowShowWallpaper) {
- if (wtoken.getDisplayContent().mWallpaperController.getWallpaperTarget()
- == null) {
- // If this theme is requesting a wallpaper, and the wallpaper
- // is not currently visible, then this effectively serves as
- // an opaque window and our starting window transition animation
- // can still work. We just need to make sure the starting window
- // is also showing the wallpaper.
- windowFlags |= FLAG_SHOW_WALLPAPER;
- } else {
- return false;
- }
- }
- }
-
- if (wtoken.transferStartingWindow(transferFrom)) {
- return true;
- }
-
- // There is no existing starting window, and the caller doesn't
- // want us to create one, so that's it!
- if (!createIfNeeded) {
- return false;
- }
-
- if (DEBUG_STARTING_WINDOW) Slog.v(TAG_WM, "Creating StartingData");
- wtoken.startingData = new StartingData(pkg, theme, compatInfo, nonLocalizedLabel,
- labelRes, icon, logo, windowFlags);
- Message m = mH.obtainMessage(H.ADD_STARTING, wtoken);
- // Note: we really want to do sendMessageAtFrontOfQueue() because we
- // want to process the message ASAP, before any other queued
- // messages.
- if (DEBUG_STARTING_WINDOW) Slog.v(TAG_WM, "Enqueueing ADD_STARTING");
- mH.sendMessageAtFrontOfQueue(m);
- }
- return true;
- }
-
- public void removeAppStartingWindow(IBinder token) {
- synchronized (mWindowMap) {
- final AppWindowToken wtoken = mRoot.getAppWindowToken(token);
- scheduleRemoveStartingWindowLocked(wtoken);
- }
- }
-
public void setAppFullscreen(IBinder token, boolean toOpaque) {
synchronized (mWindowMap) {
final AppWindowToken atoken = mRoot.getAppWindowToken(token);
@@ -3055,233 +2851,6 @@ public class WindowManagerService extends IWindowManager.Stub
}
}
- @Override
- public void notifyAppResumed(IBinder token, boolean wasStopped, boolean allowSavedSurface) {
- if (!checkCallingPermission(MANAGE_APP_TOKENS, "notifyAppResumed()")) {
- throw new SecurityException("Requires MANAGE_APP_TOKENS permission");
- }
-
- synchronized(mWindowMap) {
- final AppWindowToken wtoken = mRoot.getAppWindowToken(token);
- if (wtoken == null) {
- Slog.w(TAG_WM, "Attempted to notify resumed of non-existing app token: " + token);
- return;
- }
- wtoken.notifyAppResumed(wasStopped, allowSavedSurface);
- }
- }
-
- @Override
- public void notifyAppStopped(IBinder token) {
- if (!checkCallingPermission(MANAGE_APP_TOKENS, "notifyAppStopped()")) {
- throw new SecurityException("Requires MANAGE_APP_TOKENS permission");
- }
-
- synchronized(mWindowMap) {
- final AppWindowToken wtoken;
- wtoken = mRoot.getAppWindowToken(token);
- if (wtoken == null) {
- Slog.w(TAG_WM, "Attempted to notify stopped of non-existing app token: " + token);
- return;
- }
- wtoken.notifyAppStopped();
- }
- }
-
- @Override
- public void setAppVisibility(IBinder token, boolean visible) {
- if (!checkCallingPermission(MANAGE_APP_TOKENS, "setAppVisibility()")) {
- throw new SecurityException("Requires MANAGE_APP_TOKENS permission");
- }
-
- AppWindowToken wtoken;
-
- synchronized(mWindowMap) {
- wtoken = mRoot.getAppWindowToken(token);
- if (wtoken == null) {
- Slog.w(TAG_WM, "Attempted to set visibility of non-existing app token: " + token);
- return;
- }
-
- if (DEBUG_APP_TRANSITIONS || DEBUG_ORIENTATION) Slog.v(TAG_WM, "setAppVisibility(" +
- token + ", visible=" + visible + "): " + mAppTransition +
- " hidden=" + wtoken.hidden + " hiddenRequested=" +
- wtoken.hiddenRequested + " Callers=" + Debug.getCallers(6));
-
- mOpeningApps.remove(wtoken);
- mClosingApps.remove(wtoken);
- wtoken.waitingToShow = false;
- wtoken.hiddenRequested = !visible;
-
- if (!visible) {
- // If the app is dead while it was visible, we kept its dead window on screen.
- // Now that the app is going invisible, we can remove it. It will be restarted
- // if made visible again.
- wtoken.removeDeadWindows();
- wtoken.setVisibleBeforeClientHidden();
- } else if (visible) {
- if (!mAppTransition.isTransitionSet() && mAppTransition.isReady()) {
- // Add the app mOpeningApps if transition is unset but ready. This means
- // we're doing a screen freeze, and the unfreeze will wait for all opening
- // apps to be ready.
- mOpeningApps.add(wtoken);
- }
- wtoken.startingMoved = false;
- // If the token is currently hidden (should be the common case), or has been
- // stopped, then we need to set up to wait for its windows to be ready.
- if (wtoken.hidden || wtoken.mAppStopped) {
- wtoken.clearAllDrawn();
-
- // If the app was already visible, don't reset the waitingToShow state.
- if (wtoken.hidden) {
- wtoken.waitingToShow = true;
- }
-
- if (wtoken.clientHidden) {
- // In the case where we are making an app visible
- // but holding off for a transition, we still need
- // to tell the client to make its windows visible so
- // they get drawn. Otherwise, we will wait on
- // performing the transition until all windows have
- // been drawn, they never will be, and we are sad.
- wtoken.clientHidden = false;
- wtoken.sendAppVisibilityToClients();
- }
- }
- wtoken.requestUpdateWallpaperIfNeeded();
-
- if (DEBUG_ADD_REMOVE) Slog.v(
- TAG_WM, "No longer Stopped: " + wtoken);
- wtoken.mAppStopped = false;
- }
-
- // If we are preparing an app transition, then delay changing
- // the visibility of this token until we execute that transition.
- if (okToDisplay() && mAppTransition.isTransitionSet()) {
- // A dummy animation is a placeholder animation which informs others that an
- // animation is going on (in this case an application transition). If the animation
- // was transferred from another application/animator, no dummy animator should be
- // created since an animation is already in progress.
- if (wtoken.mAppAnimator.usingTransferredAnimation
- && wtoken.mAppAnimator.animation == null) {
- Slog.wtf(TAG_WM, "Will NOT set dummy animation on: " + wtoken
- + ", using null transfered animation!");
- }
- if (!wtoken.mAppAnimator.usingTransferredAnimation &&
- (!wtoken.startingDisplayed || mSkipAppTransitionAnimation)) {
- if (DEBUG_APP_TRANSITIONS) Slog.v(
- TAG_WM, "Setting dummy animation on: " + wtoken);
- wtoken.mAppAnimator.setDummyAnimation();
- }
- wtoken.inPendingTransaction = true;
- if (visible) {
- mOpeningApps.add(wtoken);
- wtoken.mEnteringAnimation = true;
- } else {
- mClosingApps.add(wtoken);
- wtoken.mEnteringAnimation = false;
- }
- if (mAppTransition.getAppTransition() == AppTransition.TRANSIT_TASK_OPEN_BEHIND) {
- // We're launchingBehind, add the launching activity to mOpeningApps.
- final WindowState win = getDefaultDisplayContentLocked().findFocusedWindow();
- if (win != null) {
- final AppWindowToken focusedToken = win.mAppToken;
- if (focusedToken != null) {
- if (DEBUG_APP_TRANSITIONS) Slog.d(TAG_WM, "TRANSIT_TASK_OPEN_BEHIND, " +
- " adding " + focusedToken + " to mOpeningApps");
- // Force animation to be loaded.
- focusedToken.hidden = true;
- mOpeningApps.add(focusedToken);
- }
- }
- }
- return;
- }
-
- final long origId = Binder.clearCallingIdentity();
- wtoken.setVisibility(null, visible, TRANSIT_UNSET, true, wtoken.mVoiceInteraction);
- wtoken.updateReportedVisibilityLocked();
- Binder.restoreCallingIdentity(origId);
- }
- }
-
- /**
- * Notifies that we launched an app that might be visible or not visible depending on what kind
- * of Keyguard flags it's going to set on its windows.
- */
- public void notifyUnknownAppVisibilityLaunched(IBinder token) {
- synchronized(mWindowMap) {
- AppWindowToken appWindow = mRoot.getAppWindowToken(token);
- if (appWindow != null) {
- mUnknownAppVisibilityController.notifyLaunched(appWindow);
- }
- }
- }
-
- @Override
- public void startAppFreezingScreen(IBinder token, int configChanges) {
- if (!checkCallingPermission(MANAGE_APP_TOKENS, "setAppFreezingScreen()")) {
- throw new SecurityException("Requires MANAGE_APP_TOKENS permission");
- }
-
- synchronized(mWindowMap) {
- if (configChanges == 0 && okToDisplay()) {
- if (DEBUG_ORIENTATION) Slog.v(TAG_WM, "Skipping set freeze of " + token);
- return;
- }
-
- final AppWindowToken wtoken = mRoot.getAppWindowToken(token);
- if (wtoken == null || wtoken.appToken == null) {
- Slog.w(TAG_WM, "Attempted to freeze screen with non-existing app token: " + wtoken);
- return;
- }
- final long origId = Binder.clearCallingIdentity();
- wtoken.startFreezingScreen();
- Binder.restoreCallingIdentity(origId);
- }
- }
-
- @Override
- public void stopAppFreezingScreen(IBinder token, boolean force) {
- if (!checkCallingPermission(MANAGE_APP_TOKENS, "setAppFreezingScreen()")) {
- throw new SecurityException("Requires MANAGE_APP_TOKENS permission");
- }
-
- synchronized(mWindowMap) {
- final AppWindowToken wtoken = mRoot.getAppWindowToken(token);
- if (wtoken == null || wtoken.appToken == null) {
- return;
- }
- final long origId = Binder.clearCallingIdentity();
- if (DEBUG_ORIENTATION) Slog.v(TAG_WM, "Clear freezing of " + token + ": hidden="
- + wtoken.hidden + " freezing=" + wtoken.mAppAnimator.freezingScreen);
- wtoken.stopFreezingScreen(true, force);
- Binder.restoreCallingIdentity(origId);
- }
- }
-
- @Override
- public void removeAppToken(IBinder binder, int displayId) {
- if (!checkCallingPermission(MANAGE_APP_TOKENS, "removeAppToken()")) {
- throw new SecurityException("Requires MANAGE_APP_TOKENS permission");
- }
-
- final long origId = Binder.clearCallingIdentity();
- try {
- synchronized(mWindowMap) {
- final DisplayContent dc = mRoot.getDisplayContent(displayId);
- if (dc == null) {
- Slog.w(TAG_WM, "removeAppToken: Attempted to remove binder token: " + binder
- + " from non-existing displayId=" + displayId);
- return;
- }
- dc.removeAppToken(binder);
- }
- } finally {
- Binder.restoreCallingIdentity(origId);
- }
- }
-
void scheduleRemoveStartingWindowLocked(AppWindowToken wtoken) {
if (wtoken == null) {
return;
@@ -4523,7 +4092,7 @@ public class WindowManagerService extends IWindowManager.Stub
}
try {
Trace.traceBegin(Trace.TRACE_TAG_WINDOW_MANAGER, "screenshotWallpaper");
- return screenshotApplicationsInner(null /* appToken */, DEFAULT_DISPLAY, -1 /* width */,
+ return screenshotApplications(null /* appToken */, DEFAULT_DISPLAY, -1 /* width */,
-1 /* height */, true /* includeFullDisplay */, 1f /* frameScale */,
Bitmap.Config.ARGB_8888, true /* wallpaperOnly */);
} finally {
@@ -4544,7 +4113,7 @@ public class WindowManagerService extends IWindowManager.Stub
}
FgThread.getHandler().post(() -> {
- Bitmap bm = screenshotApplicationsInner(null /* appToken */, DEFAULT_DISPLAY,
+ Bitmap bm = screenshotApplications(null /* appToken */, DEFAULT_DISPLAY,
-1 /* width */, -1 /* height */, true /* includeFullDisplay */,
1f /* frameScale */, Bitmap.Config.ARGB_8888, false /* wallpaperOnly */);
try {
@@ -4563,37 +4132,12 @@ public class WindowManagerService extends IWindowManager.Stub
* @param displayId the Display to take a screenshot of.
* @param width the width of the target bitmap
* @param height the height of the target bitmap
- * @param frameScale the scale to apply to the frame, only used when width = -1 and height = -1
- */
- @Override
- public Bitmap screenshotApplications(IBinder appToken, int displayId, int width, int height,
- float frameScale) {
- if (!checkCallingPermission(Manifest.permission.READ_FRAME_BUFFER,
- "screenshotApplications()")) {
- throw new SecurityException("Requires READ_FRAME_BUFFER permission");
- }
- try {
- Trace.traceBegin(Trace.TRACE_TAG_WINDOW_MANAGER, "screenshotApplications");
- return screenshotApplicationsInner(appToken, displayId, width, height, false,
- frameScale, Bitmap.Config.RGB_565, false);
- } finally {
- Trace.traceEnd(Trace.TRACE_TAG_WINDOW_MANAGER);
- }
- }
-
- /**
- * Takes a snapshot of the screen. In landscape mode this grabs the whole screen.
- * In portrait mode, it grabs the full screenshot.
- *
- * @param displayId the Display to take a screenshot of.
- * @param width the width of the target bitmap
- * @param height the height of the target bitmap
* @param includeFullDisplay true if the screen should not be cropped before capture
* @param frameScale the scale to apply to the frame, only used when width = -1 and height = -1
* @param config of the output bitmap
* @param wallpaperOnly true if only the wallpaper layer should be included in the screenshot
*/
- private Bitmap screenshotApplicationsInner(IBinder appToken, int displayId, int width,
+ private Bitmap screenshotApplications(IBinder appToken, int displayId, int width,
int height, boolean includeFullDisplay, float frameScale, Bitmap.Config config,
boolean wallpaperOnly) {
final DisplayContent displayContent;
@@ -5907,34 +5451,6 @@ public class WindowManagerService extends IWindowManager.Stub
private boolean mEventDispatchingEnabled;
@Override
- public void pauseKeyDispatching(IBinder binder) {
- if (!checkCallingPermission(MANAGE_APP_TOKENS, "pauseKeyDispatching()")) {
- throw new SecurityException("Requires MANAGE_APP_TOKENS permission");
- }
-
- synchronized (mWindowMap) {
- WindowToken token = mRoot.getAppWindowToken(binder);
- if (token != null) {
- mInputMonitor.pauseDispatchingLw(token);
- }
- }
- }
-
- @Override
- public void resumeKeyDispatching(IBinder binder) {
- if (!checkCallingPermission(MANAGE_APP_TOKENS, "resumeKeyDispatching()")) {
- throw new SecurityException("Requires MANAGE_APP_TOKENS permission");
- }
-
- synchronized (mWindowMap) {
- WindowToken token = mRoot.getAppWindowToken(binder);
- if (token != null) {
- mInputMonitor.resumeDispatchingLw(token);
- }
- }
- }
-
- @Override
public void setEventDispatching(boolean enabled) {
if (!checkCallingPermission(MANAGE_APP_TOKENS, "setEventDispatching()")) {
throw new SecurityException("Requires MANAGE_APP_TOKENS permission");
@@ -6065,8 +5581,6 @@ public class WindowManagerService extends IWindowManager.Stub
public static final int ADD_STARTING = 5;
public static final int REMOVE_STARTING = 6;
public static final int FINISHED_STARTING = 7;
- public static final int REPORT_APPLICATION_TOKEN_WINDOWS = 8;
- public static final int REPORT_APPLICATION_TOKEN_DRAWN = 9;
public static final int WINDOW_FREEZE_TIMEOUT = 11;
public static final int APP_TRANSITION_TIMEOUT = 13;
@@ -6328,37 +5842,6 @@ public class WindowManagerService extends IWindowManager.Stub
}
} break;
- case REPORT_APPLICATION_TOKEN_DRAWN: {
- final AppWindowToken wtoken = (AppWindowToken)msg.obj;
-
- try {
- if (DEBUG_VISIBILITY) Slog.v(
- TAG_WM, "Reporting drawn in " + wtoken);
- wtoken.appToken.windowsDrawn();
- } catch (RemoteException ex) {
- }
- } break;
-
- case REPORT_APPLICATION_TOKEN_WINDOWS: {
- final AppWindowToken wtoken = (AppWindowToken)msg.obj;
-
- boolean nowVisible = msg.arg1 != 0;
- boolean nowGone = msg.arg2 != 0;
-
- try {
- if (DEBUG_VISIBILITY) Slog.v(
- TAG_WM, "Reporting visible in " + wtoken
- + " visible=" + nowVisible
- + " gone=" + nowGone);
- if (nowVisible) {
- wtoken.appToken.windowsVisible();
- } else {
- wtoken.appToken.windowsGone();
- }
- } catch (RemoteException ex) {
- }
- } break;
-
case WINDOW_FREEZE_TIMEOUT: {
// TODO(multidisplay): Can non-default displays rotate?
synchronized (mWindowMap) {
diff --git a/services/tests/servicestests/src/com/android/server/wm/AppWindowContainerControllerTests.java b/services/tests/servicestests/src/com/android/server/wm/AppWindowContainerControllerTests.java
new file mode 100644
index 000000000000..8a962e709a24
--- /dev/null
+++ b/services/tests/servicestests/src/com/android/server/wm/AppWindowContainerControllerTests.java
@@ -0,0 +1,42 @@
+/*
+ * Copyright (C) 2017 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.wm;
+
+import org.junit.Test;
+
+import android.platform.test.annotations.Presubmit;
+import android.support.test.filters.SmallTest;
+import android.support.test.runner.AndroidJUnit4;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNull;
+import static org.junit.Assert.assertTrue;
+
+/**
+ * Test class for {@link WindowContainerController}.
+ *
+ * Build/Install/Run:
+ * bit FrameworksServicesTests:com.android.server.wm.AppWindowContainerControllerTests
+ */
+@SmallTest
+@Presubmit
+@org.junit.runner.RunWith(AndroidJUnit4.class)
+public class AppWindowContainerControllerTests extends WindowTestsBase {
+// TODO Add tests once TaskWindowContainerController is created.
+ @Test
+ public void dummyTest() throws Exception {}
+}
diff --git a/services/tests/servicestests/src/com/android/server/wm/UnknownAppVisibilityControllerTest.java b/services/tests/servicestests/src/com/android/server/wm/UnknownAppVisibilityControllerTest.java
index 07f65bd90021..612919845f92 100644
--- a/services/tests/servicestests/src/com/android/server/wm/UnknownAppVisibilityControllerTest.java
+++ b/services/tests/servicestests/src/com/android/server/wm/UnknownAppVisibilityControllerTest.java
@@ -19,7 +19,6 @@ package com.android.server.wm;
import static junit.framework.Assert.assertTrue;
import static org.mockito.Mockito.any;
import static org.mockito.Mockito.doAnswer;
-import static org.mockito.Mockito.mock;
import android.app.ActivityManagerInternal;
import android.content.Context;
@@ -27,7 +26,6 @@ import android.platform.test.annotations.Presubmit;
import android.support.test.InstrumentationRegistry;
import android.support.test.filters.SmallTest;
import android.support.test.runner.AndroidJUnit4;
-import android.view.IApplicationToken;
import com.android.server.LocalServices;
@@ -114,7 +112,6 @@ public class UnknownAppVisibilityControllerTest {
}
private AppWindowToken createAppToken() {
- return new AppWindowToken(mWm, mock(IApplicationToken.class), false,
- mWm.getDefaultDisplayContentLocked());
+ return new AppWindowToken(mWm, null, false, mWm.getDefaultDisplayContentLocked());
}
}
diff --git a/services/tests/servicestests/src/com/android/server/wm/WindowContainerControllerTests.java b/services/tests/servicestests/src/com/android/server/wm/WindowContainerControllerTests.java
new file mode 100644
index 000000000000..956735c01019
--- /dev/null
+++ b/services/tests/servicestests/src/com/android/server/wm/WindowContainerControllerTests.java
@@ -0,0 +1,84 @@
+/*
+ * Copyright (C) 2016 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.wm;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import android.platform.test.annotations.Presubmit;
+import android.support.test.filters.SmallTest;
+import android.support.test.runner.AndroidJUnit4;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNull;
+import static org.junit.Assert.assertTrue;
+
+/**
+ * Test class for {@link WindowContainerController}.
+ *
+ * Build/Install/Run:
+ * bit FrameworksServicesTests:com.android.server.wm.WindowContainerControllerTests
+ */
+@SmallTest
+@Presubmit
+@org.junit.runner.RunWith(AndroidJUnit4.class)
+public class WindowContainerControllerTests extends WindowTestsBase {
+
+ @Test
+ public void testCreation() throws Exception {
+ final WindowContainerController controller = new WindowContainerController(null, sWm);
+ final WindowContainer container = new WindowContainer();
+
+ container.setController(controller);
+ assertEquals(controller, container.getController());
+ assertEquals(controller.mContainer, container);
+ }
+
+ @Test
+ public void testSetContainer() throws Exception {
+ final WindowContainerController controller = new WindowContainerController(null, sWm);
+ final WindowContainer container = new WindowContainer();
+
+ controller.setContainer(container);
+ assertEquals(controller.mContainer, container);
+
+ // Assert we can't change the container to another one once set
+ boolean gotException = false;
+ try {
+ controller.setContainer(new WindowContainer());
+ } catch (IllegalArgumentException e) {
+ gotException = true;
+ }
+ assertTrue(gotException);
+
+ // Assert that we can set the container to null.
+ controller.setContainer(null);
+ assertNull(controller.mContainer);
+ }
+
+ @Test
+ public void testRemoveContainer() throws Exception {
+ final WindowContainerController controller = new WindowContainerController(null, sWm);
+ final WindowContainer container = new WindowContainer();
+
+ controller.setContainer(container);
+ assertEquals(controller.mContainer, container);
+
+ controller.removeContainer();
+ assertNull(controller.mContainer);
+ }
+}
diff --git a/services/tests/servicestests/src/com/android/server/wm/WindowContainerTests.java b/services/tests/servicestests/src/com/android/server/wm/WindowContainerTests.java
index 7277ba42c2da..b57329c5c701 100644
--- a/services/tests/servicestests/src/com/android/server/wm/WindowContainerTests.java
+++ b/services/tests/servicestests/src/com/android/server/wm/WindowContainerTests.java
@@ -52,7 +52,7 @@ import static org.junit.Assert.assertTrue;
@SmallTest
@Presubmit
@RunWith(AndroidJUnit4.class)
-public class WindowContainerTests {
+public class WindowContainerTests extends WindowTestsBase {
@Test
public void testCreation() throws Exception {
@@ -192,6 +192,44 @@ public class WindowContainerTests {
}
@Test
+ public void testRemoveImmediately_WithController() throws Exception {
+ final WindowContainer container = new WindowContainer();
+ final WindowContainerController controller = new WindowContainerController(null, sWm);
+
+ container.setController(controller);
+ assertEquals(controller, container.getController());
+ assertEquals(container, controller.mContainer);
+
+ container.removeImmediately();
+ assertNull(container.getController());
+ assertNull(controller.mContainer);
+ }
+
+ @Test
+ public void testSetController() throws Exception {
+ final WindowContainerController controller = new WindowContainerController(null, sWm);
+ final WindowContainer container = new WindowContainer();
+
+ container.setController(controller);
+ assertEquals(controller, container.getController());
+ assertEquals(container, controller.mContainer);
+
+ // Assert we can't change the controller to another one once set
+ boolean gotException = false;
+ try {
+ container.setController(new WindowContainerController(null, sWm));
+ } catch (IllegalArgumentException e) {
+ gotException = true;
+ }
+ assertTrue(gotException);
+
+ // Assert that we can set the controller to null.
+ container.setController(null);
+ assertNull(container.getController());
+ assertNull(controller.mContainer);
+ }
+
+ @Test
public void testPositionChildAt() throws Exception {
final TestWindowContainerBuilder builder = new TestWindowContainerBuilder();
final TestWindowContainer root = builder.setLayer(0).build();
diff --git a/services/tests/servicestests/src/com/android/server/wm/WindowTestsBase.java b/services/tests/servicestests/src/com/android/server/wm/WindowTestsBase.java
index 398568771cd7..fb3beb3c5161 100644
--- a/services/tests/servicestests/src/com/android/server/wm/WindowTestsBase.java
+++ b/services/tests/servicestests/src/com/android/server/wm/WindowTestsBase.java
@@ -44,7 +44,7 @@ import static org.mockito.Mockito.mock;
/**
* Common base class for window manager unit test classes.
*/
-public class WindowTestsBase {
+class WindowTestsBase {
static WindowManagerService sWm = null;
private final IWindow mIWindow = new TestIWindow();
private final Session mMockSession = mock(Session.class);
@@ -52,17 +52,17 @@ public class WindowTestsBase {
private static int sNextTaskId = 0;
private static boolean sOneTimeSetupDone = false;
- protected static DisplayContent sDisplayContent;
- protected static WindowLayersController sLayersController;
- protected static WindowState sWallpaperWindow;
- protected static WindowState sImeWindow;
- protected static WindowState sImeDialogWindow;
- protected static WindowState sStatusBarWindow;
- protected static WindowState sDockedDividerWindow;
- protected static WindowState sNavBarWindow;
- protected static WindowState sAppWindow;
- protected static WindowState sChildAppWindowAbove;
- protected static WindowState sChildAppWindowBelow;
+ static DisplayContent sDisplayContent;
+ static WindowLayersController sLayersController;
+ static WindowState sWallpaperWindow;
+ static WindowState sImeWindow;
+ static WindowState sImeDialogWindow;
+ static WindowState sStatusBarWindow;
+ static WindowState sDockedDividerWindow;
+ static WindowState sNavBarWindow;
+ static WindowState sAppWindow;
+ static WindowState sChildAppWindowAbove;
+ static WindowState sChildAppWindowBelow;
@Before
public void setUp() throws Exception {
diff --git a/tests/permission/src/com/android/framework/permission/tests/WindowManagerPermissionTests.java b/tests/permission/src/com/android/framework/permission/tests/WindowManagerPermissionTests.java
index 28a2cb399cd0..4aeae70ec979 100644
--- a/tests/permission/src/com/android/framework/permission/tests/WindowManagerPermissionTests.java
+++ b/tests/permission/src/com/android/framework/permission/tests/WindowManagerPermissionTests.java
@@ -43,26 +43,6 @@ public class WindowManagerPermissionTests extends TestCase {
@SmallTest
public void testMANAGE_APP_TOKENS() {
try {
- mWm.pauseKeyDispatching(null);
- fail("IWindowManager.pauseKeyDispatching did not throw SecurityException as"
- + " expected");
- } catch (SecurityException e) {
- // expected
- } catch (RemoteException e) {
- fail("Unexpected remote exception");
- }
-
- try {
- mWm.resumeKeyDispatching(null);
- fail("IWindowManager.resumeKeyDispatching did not throw SecurityException as"
- + " expected");
- } catch (SecurityException e) {
- // expected
- } catch (RemoteException e) {
- fail("Unexpected remote exception");
- }
-
- try {
mWm.setEventDispatching(true);
fail("IWindowManager.setEventDispatching did not throw SecurityException as"
+ " expected");
@@ -93,26 +73,6 @@ public class WindowManagerPermissionTests extends TestCase {
}
try {
- mWm.addAppToken(0, null, 0, 0, false, false, 0, false, false, false, 0, -1);
- fail("IWindowManager.addAppToken did not throw SecurityException as"
- + " expected");
- } catch (SecurityException e) {
- // expected
- } catch (RemoteException e) {
- fail("Unexpected remote exception");
- }
-
- try {
- mWm.addAppToTask(null, 0);
- fail("IWindowManager.setAppGroupId did not throw SecurityException as"
- + " expected");
- } catch (SecurityException e) {
- // expected
- } catch (RemoteException e) {
- fail("Unexpected remote exception");
- }
-
- try {
mWm.updateOrientationFromAppTokens(new Configuration(),
null /* freezeThisOneIfNeeded */, DEFAULT_DISPLAY);
fail("IWindowManager.updateOrientationFromAppTokens did not throw SecurityException as"
@@ -124,17 +84,6 @@ public class WindowManagerPermissionTests extends TestCase {
}
try {
- mWm.setAppOrientation(null, 0);
- mWm.addWindowToken(null, 0, DEFAULT_DISPLAY);
- fail("IWindowManager.setAppOrientation did not throw SecurityException as"
- + " expected");
- } catch (SecurityException e) {
- // expected
- } catch (RemoteException e) {
- fail("Unexpected remote exception");
- }
-
- try {
mWm.setFocusedApp(null, false);
fail("IWindowManager.setFocusedApp did not throw SecurityException as"
+ " expected");
@@ -163,56 +112,6 @@ public class WindowManagerPermissionTests extends TestCase {
} catch (RemoteException e) {
fail("Unexpected remote exception");
}
-
- try {
- mWm.setAppStartingWindow(null, "foo", 0, null, null, 0, 0, 0, 0, null, false);
- fail("IWindowManager.setAppStartingWindow did not throw SecurityException as"
- + " expected");
- } catch (SecurityException e) {
- // expected
- } catch (RemoteException e) {
- fail("Unexpected remote exception");
- }
-
- try {
- mWm.setAppVisibility(null, false);
- fail("IWindowManager.setAppVisibility did not throw SecurityException as"
- + " expected");
- } catch (SecurityException e) {
- // expected
- } catch (RemoteException e) {
- fail("Unexpected remote exception");
- }
-
- try {
- mWm.startAppFreezingScreen(null, 0);
- fail("IWindowManager.startAppFreezingScreen did not throw SecurityException as"
- + " expected");
- } catch (SecurityException e) {
- // expected
- } catch (RemoteException e) {
- fail("Unexpected remote exception");
- }
-
- try {
- mWm.stopAppFreezingScreen(null, false);
- fail("IWindowManager.stopAppFreezingScreen did not throw SecurityException as"
- + " expected");
- } catch (SecurityException e) {
- // expected
- } catch (RemoteException e) {
- fail("Unexpected remote exception");
- }
-
- try {
- mWm.removeAppToken(null, DEFAULT_DISPLAY);
- fail("IWindowManager.removeAppToken did not throw SecurityException as"
- + " expected");
- } catch (SecurityException e) {
- // expected
- } catch (RemoteException e) {
- fail("Unexpected remote exception");
- }
}
@SmallTest
diff --git a/tools/layoutlib/bridge/src/android/view/IWindowManagerImpl.java b/tools/layoutlib/bridge/src/android/view/IWindowManagerImpl.java
index 4b9815d93ac7..71c1117c036c 100644
--- a/tools/layoutlib/bridge/src/android/view/IWindowManagerImpl.java
+++ b/tools/layoutlib/bridge/src/android/view/IWindowManagerImpl.java
@@ -77,14 +77,6 @@ public class IWindowManagerImpl implements IWindowManager {
// ---- unused implementation of IWindowManager ----
@Override
- public void addAppToken(int addPos, IApplicationToken token, int taskId,
- int requestedOrientation, boolean fullscreen, boolean showWhenLocked, int configChanges,
- boolean voiceInteraction, boolean launchTaskBehind, boolean alwaysFocusable,
- int targetSdkVersion, int rotationAnimationHint) throws RemoteException {
- // TODO Auto-generated method stub
- }
-
- @Override
public void addWindowToken(IBinder arg0, int arg1, int arg2) throws RemoteException {
// TODO Auto-generated method stub
@@ -159,12 +151,6 @@ public class IWindowManagerImpl implements IWindowManager {
}
@Override
- public int getAppOrientation(IApplicationToken arg0) throws RemoteException {
- // TODO Auto-generated method stub
- return 0;
- }
-
- @Override
public int getPendingAppTransition() throws RemoteException {
// TODO Auto-generated method stub
return 0;
@@ -258,12 +244,6 @@ public class IWindowManagerImpl implements IWindowManager {
}
@Override
- public void pauseKeyDispatching(IBinder arg0) throws RemoteException {
- // TODO Auto-generated method stub
-
- }
-
- @Override
public void prepareAppTransition(int arg0, boolean arg1) throws RemoteException {
// TODO Auto-generated method stub
@@ -276,24 +256,12 @@ public class IWindowManagerImpl implements IWindowManager {
}
@Override
- public void removeAppToken(IBinder arg0, int arg1) throws RemoteException {
- // TODO Auto-generated method stub
-
- }
-
- @Override
public void removeWindowToken(IBinder arg0, int arg1) throws RemoteException {
// TODO Auto-generated method stub
}
@Override
- public void resumeKeyDispatching(IBinder arg0) throws RemoteException {
- // TODO Auto-generated method stub
-
- }
-
- @Override
public boolean requestAssistScreenshot(IAssistScreenshotReceiver receiver)
throws RemoteException {
// TODO Auto-generated method stub
@@ -301,13 +269,6 @@ public class IWindowManagerImpl implements IWindowManager {
}
@Override
- public Bitmap screenshotApplications(IBinder appToken, int displayId, int maxWidth,
- int maxHeight, float frameScale) throws RemoteException {
- // TODO Auto-generated method stub
- return null;
- }
-
- @Override
public void setAnimationScale(int arg0, float arg1) throws RemoteException {
// TODO Auto-generated method stub
@@ -325,41 +286,6 @@ public class IWindowManagerImpl implements IWindowManager {
}
@Override
- public void addAppToTask(IBinder arg0, int arg1) throws RemoteException {
- // TODO Auto-generated method stub
- }
-
- @Override
- public void setAppOrientation(IApplicationToken arg0, int arg1) throws RemoteException {
- // TODO Auto-generated method stub
- }
-
- @Override
- public boolean setAppStartingWindow(IBinder arg0, String arg1, int arg2, CompatibilityInfo arg3,
- CharSequence arg4, int arg5, int arg6, int arg7, int arg8, IBinder arg9, boolean arg10)
- throws RemoteException {
- // TODO Auto-generated method stub
- return false;
- }
-
- @Override
- public void setAppVisibility(IBinder arg0, boolean arg1) throws RemoteException {
- // TODO Auto-generated method stub
-
- }
-
- @Override
- public void notifyAppResumed(IBinder token, boolean wasStopped, boolean allowSavedSurface)
- throws RemoteException {
- // TODO Auto-generated method stub
- }
-
- @Override
- public void notifyAppStopped(IBinder token) throws RemoteException {
- // TODO Auto-generated method stub
- }
-
- @Override
public void setEventDispatching(boolean arg0) throws RemoteException {
// TODO Auto-generated method stub
}
@@ -443,11 +369,6 @@ public class IWindowManagerImpl implements IWindowManager {
}
@Override
- public void startAppFreezingScreen(IBinder arg0, int arg1) throws RemoteException {
- // TODO Auto-generated method stub
- }
-
- @Override
public boolean startViewServer(int arg0) throws RemoteException {
// TODO Auto-generated method stub
return false;
@@ -469,11 +390,6 @@ public class IWindowManagerImpl implements IWindowManager {
}
@Override
- public void stopAppFreezingScreen(IBinder arg0, boolean arg1) throws RemoteException {
- // TODO Auto-generated method stub
- }
-
- @Override
public boolean stopViewServer() throws RemoteException {
// TODO Auto-generated method stub
return false;