Merge changes Idfd40156,Ic903fc25
* changes:
Make user-switch transitions customizable
Add support for custom user-switch UI
diff --git a/core/java/android/app/Notification.java b/core/java/android/app/Notification.java
index 40b0906..ed12d06 100644
--- a/core/java/android/app/Notification.java
+++ b/core/java/android/app/Notification.java
@@ -4428,9 +4428,15 @@
// mN.mLargeIcon
// 2. !mBigLargeIconSet -> mN.mLargeIcon applies
Icon oldLargeIcon = null;
+ Bitmap largeIconLegacy = null;
if (mBigLargeIconSet) {
oldLargeIcon = mBuilder.mN.mLargeIcon;
mBuilder.mN.mLargeIcon = mBigLargeIcon;
+ // The legacy largeIcon might not allow us to clear the image, as it's taken in
+ // replacement if the other one is null. Because we're restoring these legacy icons
+ // for old listeners, this is in general non-null.
+ largeIconLegacy = mBuilder.mN.largeIcon;
+ mBuilder.mN.largeIcon = null;
}
RemoteViews contentView = getStandardView(mBuilder.getBigPictureLayoutResource());
@@ -4442,6 +4448,7 @@
if (mBigLargeIconSet) {
mBuilder.mN.mLargeIcon = oldLargeIcon;
+ mBuilder.mN.largeIcon = largeIconLegacy;
}
contentView.setImageViewBitmap(R.id.big_picture, mPicture);
diff --git a/core/java/android/view/WindowManager.java b/core/java/android/view/WindowManager.java
index fe24230..1b37ed4 100644
--- a/core/java/android/view/WindowManager.java
+++ b/core/java/android/view/WindowManager.java
@@ -636,7 +636,7 @@
/**
* Window type: shares similar characteristics with {@link #TYPE_DREAM}. The layer is
- * reserved for screenshot region selection.
+ * reserved for screenshot region selection. These windows must not take input focus.
* @hide
*/
public static final int TYPE_SCREENSHOT = FIRST_SYSTEM_WINDOW + 36;
diff --git a/core/res/res/color/watch_switch_thumb_color_material.xml b/core/res/res/color/watch_switch_thumb_color_material.xml
index d4796a0..f78d9b62 100644
--- a/core/res/res/color/watch_switch_thumb_color_material.xml
+++ b/core/res/res/color/watch_switch_thumb_color_material.xml
@@ -10,9 +10,9 @@
See the License for the specific language governing permissions and
limitations under the License.
-->
-
<selector xmlns:android="http://schemas.android.com/apk/res/android">
- <item android:color="?android:colorButtonNormal" android:state_enabled="false" />
- <item android:color="?android:colorControlActivated" android:state_checked="true" />
- <item android:color="?android:colorButtonNormal" />
-</selector>
\ No newline at end of file
+ <item android:color="?attr/colorButtonNormal" android:alpha="?attr/disabledAlpha"
+ android:state_enabled="false" />
+ <item android:color="?attr/colorControlActivated" android:state_checked="true" />
+ <item android:color="?attr/colorButtonNormal" />
+</selector>
diff --git a/core/res/res/color/watch_switch_track_color_material.xml b/core/res/res/color/watch_switch_track_color_material.xml
new file mode 100644
index 0000000..402a536
--- /dev/null
+++ b/core/res/res/color/watch_switch_track_color_material.xml
@@ -0,0 +1,21 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- 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.
+-->
+<!-- Used for the background of switch track for watch switch preference. -->
+<selector xmlns:android="http://schemas.android.com/apk/res/android">
+ <item android:state_enabled="false"
+ android:alpha="0.4" android:color="?attr/colorPrimary" />
+ <item android:color="?attr/colorPrimary" />
+</selector>
diff --git a/core/res/res/layout-watch/preference_widget_switch.xml b/core/res/res/layout-watch/preference_widget_switch.xml
index 37d0c6b..ffc00b4 100644
--- a/core/res/res/layout-watch/preference_widget_switch.xml
+++ b/core/res/res/layout-watch/preference_widget_switch.xml
@@ -24,7 +24,7 @@
android:thumb="@drawable/watch_switch_thumb_material_anim"
android:thumbTint="@color/watch_switch_thumb_color_material"
android:track="@drawable/watch_switch_track_material"
- android:trackTint="?android:colorPrimary"
+ android:trackTint="@color/watch_switch_track_color_material"
android:focusable="false"
android:clickable="false"
android:background="@null" />
diff --git a/packages/Keyguard/res/layout/keyguard_password_view.xml b/packages/Keyguard/res/layout/keyguard_password_view.xml
index 7d45017..29c93d5 100644
--- a/packages/Keyguard/res/layout/keyguard_password_view.xml
+++ b/packages/Keyguard/res/layout/keyguard_password_view.xml
@@ -26,7 +26,6 @@
androidprv:layout_maxWidth="@dimen/keyguard_security_width"
androidprv:layout_maxHeight="@dimen/keyguard_security_height"
android:gravity="bottom"
- android:contentDescription="@string/keyguard_accessibility_password_unlock"
>
<Space
diff --git a/packages/Keyguard/res/layout/keyguard_pin_view.xml b/packages/Keyguard/res/layout/keyguard_pin_view.xml
index d3fb982..e75f3c15 100644
--- a/packages/Keyguard/res/layout/keyguard_pin_view.xml
+++ b/packages/Keyguard/res/layout/keyguard_pin_view.xml
@@ -26,7 +26,6 @@
androidprv:layout_maxWidth="@dimen/keyguard_security_width"
androidprv:layout_maxHeight="@dimen/keyguard_security_max_height"
android:orientation="vertical"
- android:contentDescription="@string/keyguard_accessibility_pin_unlock"
>
<include layout="@layout/keyguard_message_area"
android:layout_width="match_parent"
diff --git a/packages/Keyguard/res/values/strings.xml b/packages/Keyguard/res/values/strings.xml
index 09fec81..ff689aa 100644
--- a/packages/Keyguard/res/values/strings.xml
+++ b/packages/Keyguard/res/values/strings.xml
@@ -103,15 +103,6 @@
<!-- Time format strings for fall-back clock widget -->
<string name="keyguard_widget_24_hours_format" translatable="false">kk\uee01mm</string>
- <string name="keyguard_accessibility_pattern_unlock">Pattern unlock.</string>
- <!-- Accessibility description of the pin lock. [CHAR_LIMIT=none] -->
- <string name="keyguard_accessibility_pin_unlock">Pin unlock.</string>
- <!-- Accessibility description of the password lock. [CHAR_LIMIT=none] -->
- <string name="keyguard_accessibility_password_unlock">Password unlock.</string>
- <!-- Accessibility description of the unlock pattern area. [CHAR_LIMIT=none] -->
- <string name="keyguard_accessibility_pattern_area" msgid="7679891324509597904">Pattern area.</string>
- <!-- Accessibility description of the unlock slide area. [CHAR_LIMIT=none] -->
- <string name="keyguard_accessibility_slide_area">Slide area.</string>
<!-- Accessibility description of the PIN password view. [CHAR_LIMIT=none] -->
<string name="keyguard_accessibility_pin_area">PIN area</string>
<!-- Accessibility description of the SIM PIN password view. [CHAR_LIMIT=none] -->
diff --git a/packages/SystemUI/res/layout/volume_dialog.xml b/packages/SystemUI/res/layout/volume_dialog.xml
index f3a7acc..b3ff5d6 100644
--- a/packages/SystemUI/res/layout/volume_dialog.xml
+++ b/packages/SystemUI/res/layout/volume_dialog.xml
@@ -33,6 +33,7 @@
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:paddingEnd="@dimen/volume_button_size"
+ android:paddingTop="@dimen/volume_dialog_collapsed_padding_top"
android:orientation="vertical" >
<View android:id="@+id/spacer"
android:layout_width="match_parent"
diff --git a/packages/SystemUI/res/values-bs-rBA/strings.xml b/packages/SystemUI/res/values-bs-rBA/strings.xml
index 50e7410..22cdd7d 100644
--- a/packages/SystemUI/res/values-bs-rBA/strings.xml
+++ b/packages/SystemUI/res/values-bs-rBA/strings.xml
@@ -61,11 +61,11 @@
<string name="label_view" msgid="6304565553218192990">"Prikaži"</string>
<string name="always_use_device" msgid="1450287437017315906">"Koristiti kao zadanu opciju za ovaj USB uređaj"</string>
<string name="always_use_accessory" msgid="1210954576979621596">"Koristiti kao zadanu opciju za ovaj USB uređaj"</string>
- <string name="usb_debugging_title" msgid="4513918393387141949">"Omogućiti otklanjanje grešaka preko USB-a?"</string>
+ <string name="usb_debugging_title" msgid="4513918393387141949">"Omogućiti otklanjanje grešaka putem uređaja spojenog na USB?"</string>
<string name="usb_debugging_message" msgid="2220143855912376496">"RSA otisak prsta za otključavanje računara je: \n<xliff:g id="FINGERPRINT">%1$s</xliff:g>"</string>
<string name="usb_debugging_always" msgid="303335496705863070">"Uvijek dozvoli sa ovog računara"</string>
- <string name="usb_debugging_secondary_user_title" msgid="6353808721761220421">"Uklanjanje pogreški putem USB-a nije dozvoljeno"</string>
- <string name="usb_debugging_secondary_user_message" msgid="8572228137833020196">"Korisnik koji je trenutno prijavljen na uređaju ne može uključiti opciju za otklanjanje grešaka koristeći USB. Da biste koristili ovu funkciju prebacite se na korisnika administratora."</string>
+ <string name="usb_debugging_secondary_user_title" msgid="6353808721761220421">"Otklanjanje grešaka putem uređaja spojenog na USB nije dozvoljeno"</string>
+ <string name="usb_debugging_secondary_user_message" msgid="8572228137833020196">"Korisnik koji je trenutno prijavljen na uređaju ne može uključiti opciju za otklanjanje grešaka putem uređaja spojenog na USB. Da biste koristili ovu funkciju prebacite se na korisnika administratora."</string>
<string name="compat_mode_on" msgid="6623839244840638213">"Uvećaj prikaz na ekran"</string>
<string name="compat_mode_off" msgid="4434467572461327898">"Razvuci prikaz na ekran"</string>
<string name="screenshot_saving_ticker" msgid="7403652894056693515">"Spašavanje snimka ekrana..."</string>
diff --git a/packages/SystemUI/res/values/dimens.xml b/packages/SystemUI/res/values/dimens.xml
index d378f0d..549d50e 100644
--- a/packages/SystemUI/res/values/dimens.xml
+++ b/packages/SystemUI/res/values/dimens.xml
@@ -57,6 +57,9 @@
<!-- The amount to scale each of the status bar icons by. A value of 1 means no scaling. -->
<item name="status_bar_icon_scale_factor" format="float" type="dimen">1.0</item>
+ <!-- max height of a notification such that the content can still fade out when closing -->
+ <dimen name="max_notification_fadeout_height">100dp</dimen>
+
<!-- End margin for the RSSI status icon of a device connected via bluetooth. -->
<dimen name="status_bar_connected_device_signal_margin_end">16dp</dimen>
@@ -559,6 +562,7 @@
<!-- Volume dialog root view bottom margin, at rest -->
<dimen name="volume_dialog_margin_bottom">4dp</dimen>
+ <dimen name="volume_dialog_collapsed_padding_top">8dp</dimen>
<dimen name="volume_dialog_expanded_spacer">14dp</dimen>
<dimen name="volume_dialog_padding_end">40dp</dimen>
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/ActivatableNotificationView.java b/packages/SystemUI/src/com/android/systemui/statusbar/ActivatableNotificationView.java
index 9afb384..e35ef44 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/ActivatableNotificationView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/ActivatableNotificationView.java
@@ -744,6 +744,7 @@
}
if (!mWasCancelled) {
enableAppearDrawing(false);
+ onAppearAnimationFinished(isAppearing);
}
}
@@ -760,6 +761,9 @@
mAppearAnimator.start();
}
+ protected void onAppearAnimationFinished(boolean wasAppearing) {
+ }
+
private void cancelAppearAnimation() {
if (mAppearAnimator != null) {
mAppearAnimator.cancel();
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/ExpandableNotificationRow.java b/packages/SystemUI/src/com/android/systemui/statusbar/ExpandableNotificationRow.java
index 58d402b..02fdd3f 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/ExpandableNotificationRow.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/ExpandableNotificationRow.java
@@ -598,7 +598,7 @@
}
private NotificationHeaderView getVisibleNotificationHeader() {
- if (mIsSummaryWithChildren) {
+ if (mIsSummaryWithChildren && !mShowingPublic) {
return mChildrenContainer.getHeaderView();
}
return getShowingLayout().getVisibleNotificationHeader();
@@ -1442,13 +1442,30 @@
@Override
protected View getContentView() {
- if (mIsSummaryWithChildren) {
+ if (mIsSummaryWithChildren && !mShowingPublic) {
return mChildrenContainer;
}
return getShowingLayout();
}
@Override
+ protected void onAppearAnimationFinished(boolean wasAppearing) {
+ super.onAppearAnimationFinished(wasAppearing);
+ if (wasAppearing) {
+ // During the animation the visible view might have changed, so let's make sure all
+ // alphas are reset
+ if (mChildrenContainer != null) {
+ mChildrenContainer.setAlpha(1.0f);
+ mChildrenContainer.setLayerType(LAYER_TYPE_NONE, null);
+ }
+ mPrivateLayout.setAlpha(1.0f);
+ mPrivateLayout.setLayerType(LAYER_TYPE_NONE, null);
+ mPublicLayout.setAlpha(1.0f);
+ mPublicLayout.setLayerType(LAYER_TYPE_NONE, null);
+ }
+ }
+
+ @Override
public int getExtraBottomPadding() {
if (mIsSummaryWithChildren && isGroupExpanded()) {
return mIncreasedPaddingBetweenElements;
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelView.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelView.java
index 8658111..f27f8f5 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelView.java
@@ -189,6 +189,7 @@
private boolean mExpandingFromHeadsUp;
private boolean mCollapsedOnDown;
private int mPositionMinSideMargin;
+ private int mMaxFadeoutHeight;
private int mLastOrientation = -1;
private boolean mClosingWithAlphaFadeOut;
private boolean mHeadsUpAnimatingAway;
@@ -278,6 +279,8 @@
R.dimen.qs_falsing_threshold);
mPositionMinSideMargin = getResources().getDimensionPixelSize(
R.dimen.notification_panel_min_side_margin);
+ mMaxFadeoutHeight = getResources().getDimensionPixelSize(
+ R.dimen.max_notification_fadeout_height);
}
public void updateResources() {
@@ -552,7 +555,9 @@
protected void flingToHeight(float vel, boolean expand, float target,
float collapseSpeedUpFactor, boolean expandBecauseOfFalsing) {
mHeadsUpTouchHelper.notifyFling(!expand);
- setClosingWithAlphaFadeout(!expand && getFadeoutAlpha() == 1.0f);
+ setClosingWithAlphaFadeout(!expand
+ && mNotificationStackScroller.getFirstChildIntrinsicHeight() <= mMaxFadeoutHeight
+ && getFadeoutAlpha() == 1.0f);
super.flingToHeight(vel, expand, target, collapseSpeedUpFactor, expandBecauseOfFalsing);
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java
index dd856ef..e95cc6b 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java
@@ -1614,7 +1614,7 @@
&& !mNotificationPanel.isTracking() && !mNotificationPanel.isQsExpanded()) {
if (mState == StatusBarState.SHADE) {
animateCollapsePanels();
- } else if (mState == StatusBarState.SHADE_LOCKED) {
+ } else if (mState == StatusBarState.SHADE_LOCKED && !isCollapsing()) {
goToKeyguard();
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/stack/NotificationStackScrollLayout.java b/packages/SystemUI/src/com/android/systemui/statusbar/stack/NotificationStackScrollLayout.java
index 43336a0..c54e4b5 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/stack/NotificationStackScrollLayout.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/stack/NotificationStackScrollLayout.java
@@ -701,7 +701,7 @@
*/
private float getExpandTranslationStart() {
int startPosition = mTrackingHeadsUp || mHeadsUpManager.hasPinnedHeadsUp()
- ? 0 : -getFirstChildMinHeight();
+ ? 0 : -getFirstChildIntrinsicHeight();
return startPosition - mTopPadding;
}
@@ -2011,7 +2011,7 @@
bottom = Math.min(bottom, getHeight());
}
} else {
- top = (int) (mTopPadding + mStackTranslation);
+ top = mTopPadding;
bottom = top;
}
if (mPhoneStatusBar.getBarState() != StatusBarState.KEYGUARD) {
@@ -2142,17 +2142,17 @@
}
public int getLayoutMinHeight() {
- int firstChildMinHeight = getFirstChildMinHeight();
+ int firstChildMinHeight = getFirstChildIntrinsicHeight();
return Math.min(firstChildMinHeight + mBottomStackPeekSize + mBottomStackSlowDownHeight,
mMaxLayoutHeight - mTopPadding);
}
- private int getFirstChildMinHeight() {
+ public int getFirstChildIntrinsicHeight() {
final ExpandableView firstChild = getFirstChildNotGone();
int firstChildMinHeight = firstChild != null
? firstChild.getIntrinsicHeight()
: mEmptyShadeView != null
- ? mEmptyShadeView.getMinHeight()
+ ? mEmptyShadeView.getIntrinsicHeight()
: mCollapsedSize;
if (mOwnScrollY > 0) {
firstChildMinHeight = Math.max(firstChildMinHeight - mOwnScrollY, mCollapsedSize);
diff --git a/services/core/java/com/android/server/am/ActivityStack.java b/services/core/java/com/android/server/am/ActivityStack.java
index 9cae382..edc165a 100644
--- a/services/core/java/com/android/server/am/ActivityStack.java
+++ b/services/core/java/com/android/server/am/ActivityStack.java
@@ -1003,7 +1003,7 @@
if (DEBUG_PAUSE) Slog.v(TAG_PAUSE, "Sleep needs to pause " + mResumedActivity);
if (DEBUG_USER_LEAVING) Slog.v(TAG_USER_LEAVING,
"Sleep => pause with userLeaving=false");
- startPausingLocked(false, true, false, false);
+ startPausingLocked(false, true, null, false);
return true;
}
if (mPausingActivity != null) {
@@ -1081,15 +1081,16 @@
* @param userLeaving True if this should result in an onUserLeaving to the current activity.
* @param uiSleeping True if this is happening with the user interface going to sleep (the
* screen turning off).
- * @param resuming True if this is being called as part of resuming the top activity, so
- * we shouldn't try to instigate a resume here.
+ * @param resuming The activity we are currently trying to resume or null if this is not being
+ * called as part of resuming the top activity, so we shouldn't try to instigate
+ * a resume here if not null.
* @param dontWait True if the caller does not want to wait for the pause to complete. If
* set to true, we will immediately complete the pause here before returning.
* @return Returns true if an activity now is in the PAUSING state, and we are waiting for
* it to tell us when it is done.
*/
- final boolean startPausingLocked(boolean userLeaving, boolean uiSleeping, boolean resuming,
- boolean dontWait) {
+ final boolean startPausingLocked(boolean userLeaving, boolean uiSleeping,
+ ActivityRecord resuming, boolean dontWait) {
if (mPausingActivity != null) {
Slog.wtf(TAG, "Going to pause when pause is already pending for " + mPausingActivity
+ " state=" + mPausingActivity.state);
@@ -1097,12 +1098,12 @@
// Avoid recursion among check for sleep and complete pause during sleeping.
// Because activity will be paused immediately after resume, just let pause
// be completed by the order of activity paused from clients.
- completePauseLocked(false);
+ completePauseLocked(false, resuming);
}
}
ActivityRecord prev = mResumedActivity;
if (prev == null) {
- if (!resuming) {
+ if (resuming == null) {
Slog.wtf(TAG, "Trying to pause when nothing is resumed");
mStackSupervisor.resumeFocusedStackTopActivityLocked();
}
@@ -1175,7 +1176,7 @@
if (dontWait) {
// If the caller said they don't want to wait for the pause, then complete
// the pause now.
- completePauseLocked(false);
+ completePauseLocked(false, resuming);
return false;
} else {
@@ -1194,7 +1195,7 @@
// This activity failed to schedule the
// pause, so just treat it as being paused now.
if (DEBUG_PAUSE) Slog.v(TAG_PAUSE, "Activity not running, resuming next.");
- if (!resuming) {
+ if (resuming == null) {
mStackSupervisor.resumeFocusedStackTopActivityLocked();
}
return false;
@@ -1211,7 +1212,7 @@
if (mPausingActivity == r) {
if (DEBUG_STATES) Slog.v(TAG_STATES, "Moving to PAUSED: " + r
+ (timeout ? " (due to timeout)" : " (pause complete)"));
- completePauseLocked(true);
+ completePauseLocked(true, null);
return;
} else {
EventLog.writeEvent(EventLogTags.AM_FAILED_TO_PAUSE,
@@ -1282,7 +1283,7 @@
}
}
- private void completePauseLocked(boolean resumeNext) {
+ private void completePauseLocked(boolean resumeNext, ActivityRecord resuming) {
ActivityRecord prev = mPausingActivity;
if (DEBUG_PAUSE) Slog.v(TAG_PAUSE, "Complete pause: " + prev);
@@ -1374,7 +1375,7 @@
mStackSupervisor.mAppVisibilitiesChangedSinceLastPause = false;
}
- mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
+ mStackSupervisor.ensureActivitiesVisibleLocked(resuming, 0, !PRESERVE_WINDOWS);
}
private void addToStopping(ActivityRecord r, boolean immediate) {
@@ -2335,11 +2336,11 @@
// We need to start pausing the current activity so the top one can be resumed...
final boolean dontWaitForPause = (next.info.flags & FLAG_RESUME_WHILE_PAUSING) != 0;
- boolean pausing = mStackSupervisor.pauseBackStacks(userLeaving, true, dontWaitForPause);
+ boolean pausing = mStackSupervisor.pauseBackStacks(userLeaving, next, dontWaitForPause);
if (mResumedActivity != null) {
if (DEBUG_STATES) Slog.d(TAG_STATES,
"resumeTopActivityLocked: Pausing " + mResumedActivity);
- pausing |= startPausingLocked(userLeaving, false, true, dontWaitForPause);
+ pausing |= startPausingLocked(userLeaving, false, next, dontWaitForPause);
}
if (pausing) {
if (DEBUG_SWITCH || DEBUG_STATES) Slog.v(TAG_STATES,
@@ -3581,7 +3582,7 @@
if (DEBUG_PAUSE) Slog.v(TAG_PAUSE, "Finish needs to pause: " + r);
if (DEBUG_USER_LEAVING) Slog.v(TAG_USER_LEAVING,
"finish() => pause with userLeaving=false");
- startPausingLocked(false, false, false, false);
+ startPausingLocked(false, false, null, false);
}
if (endTask) {
@@ -3884,8 +3885,7 @@
r.finishLaunchTickingLocked();
}
- private void removeActivityFromHistoryLocked(
- ActivityRecord r, TaskRecord oldTop, String reason) {
+ private void removeActivityFromHistoryLocked(ActivityRecord r, String reason) {
mStackSupervisor.removeChildActivityContainers(r);
finishActivityResultsLocked(r, Activity.RESULT_CANCELED, null);
r.makeFinishingLocked();
@@ -3904,11 +3904,10 @@
validateAppTokensLocked();
}
final TaskRecord task = r.task;
- final TaskRecord topTask = oldTop != null ? oldTop : topTask();
if (task != null && task.removeActivity(r)) {
if (DEBUG_STACK) Slog.i(TAG_STACK,
"removeActivityFromHistoryLocked: last activity removed from " + this);
- if (mStackSupervisor.isFocusedStack(this) && task == topTask &&
+ if (mStackSupervisor.isFocusedStack(this) && task == topTask() &&
task.isOverHomeStack()) {
mStackSupervisor.moveHomeStackTaskToTop(task.getTaskToReturnTo(), reason);
}
@@ -4044,12 +4043,6 @@
boolean removedFromHistory = false;
- // If the activity is finishing, it's no longer considered in topRunningActivityLocked,
- // and cleanUpActivityLocked() may change focus to another activity (or task).
- // Get the current top task now, as removeActivityFromHistoryLocked() below need this
- // to decide whether to return to home stack after removal.
- final TaskRecord topTask = topTask();
-
cleanUpActivityLocked(r, false, false);
final boolean hadApp = r.app != null;
@@ -4084,8 +4077,7 @@
// up.
//Slog.w(TAG, "Exception thrown during finish", e);
if (r.finishing) {
- removeActivityFromHistoryLocked(
- r, topTask, reason + " exceptionInScheduleDestroy");
+ removeActivityFromHistoryLocked(r, reason + " exceptionInScheduleDestroy");
removedFromHistory = true;
skipDestroy = true;
}
@@ -4116,7 +4108,7 @@
} else {
// remove this record from the history.
if (r.finishing) {
- removeActivityFromHistoryLocked(r, topTask, reason + " hadNoApp");
+ removeActivityFromHistoryLocked(r, reason + " hadNoApp");
removedFromHistory = true;
} else {
if (DEBUG_STATES) Slog.v(TAG_STATES, "Moving to DESTROYED: " + r + " (no app)");
@@ -4147,7 +4139,7 @@
if (isInStackLocked(r) != null) {
if (r.state == ActivityState.DESTROYING) {
cleanUpActivityLocked(r, true, false);
- removeActivityFromHistoryLocked(r, null, reason);
+ removeActivityFromHistoryLocked(r, reason);
}
}
mStackSupervisor.resumeFocusedStackTopActivityLocked();
@@ -4305,7 +4297,7 @@
}
cleanUpActivityLocked(r, true, true);
if (remove) {
- removeActivityFromHistoryLocked(r, null, "appDied");
+ removeActivityFromHistoryLocked(r, "appDied");
}
}
}
diff --git a/services/core/java/com/android/server/am/ActivityStackSupervisor.java b/services/core/java/com/android/server/am/ActivityStackSupervisor.java
index 8f05aa3..271483e 100644
--- a/services/core/java/com/android/server/am/ActivityStackSupervisor.java
+++ b/services/core/java/com/android/server/am/ActivityStackSupervisor.java
@@ -920,9 +920,12 @@
/**
* Pause all activities in either all of the stacks or just the back stacks.
* @param userLeaving Passed to pauseActivity() to indicate whether to call onUserLeaving().
+ * @param resuming The resuming activity.
+ * @param dontWait The resuming activity isn't going to wait for all activities to be paused
+ * before resuming.
* @return true if any activity was paused as a result of this call.
*/
- boolean pauseBackStacks(boolean userLeaving, boolean resuming, boolean dontWait) {
+ boolean pauseBackStacks(boolean userLeaving, ActivityRecord resuming, boolean dontWait) {
boolean someActivityPaused = false;
for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
@@ -961,7 +964,7 @@
}
void pauseChildStacks(ActivityRecord parent, boolean userLeaving, boolean uiSleeping,
- boolean resuming, boolean dontWait) {
+ ActivityRecord resuming, boolean dontWait) {
// TODO: Put all stacks in supervisor and iterate through them instead.
for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
@@ -4230,7 +4233,7 @@
mContainerState = CONTAINER_STATE_NO_SURFACE;
((VirtualActivityDisplay) mActivityDisplay).setSurface(null);
if (mStack.mPausingActivity == null && mStack.mResumedActivity != null) {
- mStack.startPausingLocked(false, true, false, false);
+ mStack.startPausingLocked(false, true, null, false);
}
}
diff --git a/services/core/java/com/android/server/policy/PhoneWindowManager.java b/services/core/java/com/android/server/policy/PhoneWindowManager.java
index c1b5102..60fbabf 100644
--- a/services/core/java/com/android/server/policy/PhoneWindowManager.java
+++ b/services/core/java/com/android/server/policy/PhoneWindowManager.java
@@ -2310,6 +2310,9 @@
attrs.privateFlags &= ~WindowManager.LayoutParams.PRIVATE_FLAG_KEYGUARD;
}
break;
+ case TYPE_SCREENSHOT:
+ attrs.flags |= WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE;
+ break;
}
if (attrs.type != TYPE_STATUS_BAR) {
diff --git a/services/core/java/com/android/server/wm/AppWindowToken.java b/services/core/java/com/android/server/wm/AppWindowToken.java
index 47f435f..c78e94b 100644
--- a/services/core/java/com/android/server/wm/AppWindowToken.java
+++ b/services/core/java/com/android/server/wm/AppWindowToken.java
@@ -73,9 +73,6 @@
// Non-null only for application tokens.
final IApplicationToken appToken;
- // All of the windows and child windows that are included in this
- // application token. Note this list is NOT sorted!
- private final WindowList allAppWindows = new WindowList();
@NonNull final AppWindowAnimator mAppAnimator;
final boolean voiceInteraction;
@@ -163,9 +160,9 @@
}
void sendAppVisibilityToClients() {
- final int N = allAppWindows.size();
+ final int N = windows.size();
for (int i=0; i<N; i++) {
- WindowState win = allAppWindows.get(i);
+ WindowState win = windows.get(i);
if (win == startingWindow && clientHidden) {
// Don't hide the starting window.
continue;
@@ -180,8 +177,8 @@
}
void setVisibleBeforeClientHidden() {
- for (int i = allAppWindows.size() - 1; i >= 0; i--) {
- final WindowState w = allAppWindows.get(i);
+ for (int i = windows.size() - 1; i >= 0; i--) {
+ final WindowState w = windows.get(i);
w.setVisibleBeforeClientHidden();
}
}
@@ -217,9 +214,9 @@
if (DEBUG_VISIBILITY) Slog.v(TAG,
"Update reported visibility: " + this);
- final int N = allAppWindows.size();
+ final int N = windows.size();
for (int i=0; i<N; i++) {
- WindowState win = allAppWindows.get(i);
+ WindowState win = windows.get(i);
if (win == startingWindow || win.mAppFreezing
|| win.mViewVisibility != View.VISIBLE
|| win.mAttrs.type == TYPE_APPLICATION_STARTING
@@ -330,9 +327,9 @@
changed = true;
}
- final int windowsCount = allAppWindows.size();
+ final int windowsCount = windows.size();
for (int i = 0; i < windowsCount; i++) {
- final WindowState win = allAppWindows.get(i);
+ final WindowState win = windows.get(i);
if (win == startingWindow) {
// Starting window that's exiting will be removed when the animation finishes.
// Mark all relevant flags for that onExitAnimationDone will proceed all the way
@@ -406,8 +403,8 @@
delayed = true;
}
- for (int i = allAppWindows.size() - 1; i >= 0 && !delayed; i--) {
- if (allAppWindows.get(i).mWinAnimator.isWindowAnimationSet()) {
+ for (int i = windows.size() - 1; i >= 0 && !delayed; i--) {
+ if (windows.get(i).mWinAnimator.isWindowAnimationSet()) {
delayed = true;
}
}
@@ -434,10 +431,10 @@
WindowState findMainWindow() {
WindowState candidate = null;
- int j = allAppWindows.size();
+ int j = windows.size();
while (j > 0) {
j--;
- WindowState win = allAppWindows.get(j);
+ WindowState win = windows.get(j);
if (win.mAttrs.type == WindowManager.LayoutParams.TYPE_BASE_APPLICATION
|| win.mAttrs.type == WindowManager.LayoutParams.TYPE_APPLICATION_STARTING) {
// In cases where there are multiple windows, we prefer the non-exiting window. This
@@ -458,9 +455,9 @@
}
boolean isVisible() {
- final int N = allAppWindows.size();
+ final int N = windows.size();
for (int i=0; i<N; i++) {
- WindowState win = allAppWindows.get(i);
+ WindowState win = windows.get(i);
// If we're animating with a saved surface, we're already visible.
// Return true so that the alpha doesn't get cleared.
if (!win.mAppFreezing
@@ -476,8 +473,8 @@
}
boolean isVisibleForUser() {
- for (int j = allAppWindows.size() - 1; j >= 0; j--) {
- final WindowState w = allAppWindows.get(j);
+ for (int j = windows.size() - 1; j >= 0; j--) {
+ final WindowState w = windows.get(j);
if (!w.isHiddenFromUserLocked()) {
return true;
}
@@ -501,8 +498,8 @@
}
void clearAnimatingFlags() {
- for (int i = allAppWindows.size() - 1; i >= 0; i--) {
- final WindowState win = allAppWindows.get(i);
+ for (int i = windows.size() - 1; i >= 0; i--) {
+ final WindowState win = windows.get(i);
// We don't want to clear it out for windows that get replaced, because the
// animation depends on the flag to remove the replaced window.
//
@@ -540,7 +537,7 @@
*/
private void destroySurfaces(boolean cleanupOnResume) {
- final ArrayList<WindowState> allWindows = (ArrayList<WindowState>) allAppWindows.clone();
+ final ArrayList<WindowState> allWindows = (ArrayList<WindowState>) windows.clone();
final DisplayContentList displayList = new DisplayContentList();
for (int i = allWindows.size() - 1; i >= 0; i--) {
final WindowState win = allWindows.get(i);
@@ -620,8 +617,8 @@
}
boolean canRestoreSurfaces() {
- for (int i = allAppWindows.size() -1; i >= 0; i--) {
- final WindowState w = allAppWindows.get(i);
+ for (int i = windows.size() -1; i >= 0; i--) {
+ final WindowState w = windows.get(i);
if (w.canRestoreSurface()) {
return true;
}
@@ -630,8 +627,8 @@
}
void clearVisibleBeforeClientHidden() {
- for (int i = allAppWindows.size() - 1; i >= 0; i--) {
- final WindowState w = allAppWindows.get(i);
+ for (int i = windows.size() - 1; i >= 0; i--) {
+ final WindowState w = windows.get(i);
w.clearVisibleBeforeClientHidden();
}
}
@@ -641,8 +638,8 @@
* animating with saved surface.
*/
boolean isAnimatingInvisibleWithSavedSurface() {
- for (int i = allAppWindows.size() - 1; i >= 0; i--) {
- final WindowState w = allAppWindows.get(i);
+ for (int i = windows.size() - 1; i >= 0; i--) {
+ final WindowState w = windows.get(i);
if (w.isAnimatingInvisibleWithSavedSurface()) {
return true;
}
@@ -655,8 +652,8 @@
* with a saved surface, and mark them destroying.
*/
void stopUsingSavedSurfaceLocked() {
- for (int i = allAppWindows.size() - 1; i >= 0; i--) {
- final WindowState w = allAppWindows.get(i);
+ for (int i = windows.size() - 1; i >= 0; i--) {
+ final WindowState w = windows.get(i);
if (w.isAnimatingInvisibleWithSavedSurface()) {
if (DEBUG_APP_TRANSITIONS || DEBUG_ANIM) Slog.d(TAG,
"stopUsingSavedSurfaceLocked: " + w);
@@ -670,8 +667,8 @@
}
void markSavedSurfaceExiting() {
- for (int i = allAppWindows.size() - 1; i >= 0; i--) {
- final WindowState w = allAppWindows.get(i);
+ for (int i = windows.size() - 1; i >= 0; i--) {
+ final WindowState w = windows.get(i);
if (w.isAnimatingInvisibleWithSavedSurface()) {
w.mAnimatingExit = true;
w.mWinAnimator.mAnimating = true;
@@ -687,8 +684,8 @@
// Check if we have enough drawn windows to mark allDrawn= true.
int numInteresting = 0;
int numDrawn = 0;
- for (int i = allAppWindows.size() - 1; i >= 0; i--) {
- WindowState w = allAppWindows.get(i);
+ for (int i = windows.size() - 1; i >= 0; i--) {
+ WindowState w = windows.get(i);
if (w != startingWindow && !w.mAppDied && w.wasVisibleBeforeClientHidden()
&& (!mAppAnimator.freezingScreen || !w.mAppFreezing)) {
numInteresting++;
@@ -715,8 +712,8 @@
}
void destroySavedSurfaces() {
- for (int i = allAppWindows.size() - 1; i >= 0; i--) {
- WindowState win = allAppWindows.get(i);
+ for (int i = windows.size() - 1; i >= 0; i--) {
+ WindowState win = windows.get(i);
win.destroySavedSurface();
}
}
@@ -728,40 +725,19 @@
}
@Override
- void removeAllWindows() {
- for (int winNdx = allAppWindows.size() - 1; winNdx >= 0;
- // removeWindowLocked at bottom of loop may remove multiple entries from
- // allAppWindows if the window to be removed has child windows. It also may
- // not remove any windows from allAppWindows at all if win is exiting and
- // currently animating away. This ensures that winNdx is monotonically decreasing
- // and never beyond allAppWindows bounds.
- winNdx = Math.min(winNdx - 1, allAppWindows.size() - 1)) {
- WindowState win = allAppWindows.get(winNdx);
- if (DEBUG_WINDOW_MOVEMENT) {
- Slog.w(TAG, "removeAllWindows: removing win=" + win);
- }
-
- mService.removeWindowLocked(win);
- }
- allAppWindows.clear();
- windows.clear();
- }
-
- @Override
void removeWindow(WindowState win) {
super.removeWindow(win);
- allAppWindows.remove(win);
-
+ // TODO: Something smells about the code below...Is there a better way?
if (startingWindow == win) {
if (DEBUG_STARTING_WINDOW) Slog.v(TAG_WM, "Notify removed startingWindow " + win);
mService.scheduleRemoveStartingWindowLocked(this);
- } else if (allAppWindows.size() == 0 && startingData != null) {
+ } else if (windows.size() == 0 && startingData != null) {
// If this is the last window and we had requested a starting transition window,
// well there is no point now.
if (DEBUG_STARTING_WINDOW) Slog.v(TAG_WM, "Nulling last startingWindow");
startingData = null;
- } else if (allAppWindows.size() == 1 && startingView != null) {
+ } else if (windows.size() == 1 && startingView != null) {
// If this is the last window except for a starting transition window,
// we need to get rid of the starting transition.
mService.scheduleRemoveStartingWindowLocked(this);
@@ -769,28 +745,27 @@
}
void removeAllDeadWindows() {
- for (int winNdx = allAppWindows.size() - 1; winNdx >= 0;
- // removeWindowLocked at bottom of loop may remove multiple entries from
- // allAppWindows if the window to be removed has child windows. It also may
- // not remove any windows from allAppWindows at all if win is exiting and
+ for (int winNdx = windows.size() - 1; winNdx >= 0;
+ // WindowState#removeIfPossible() at bottom of loop may remove multiple entries from
+ // windows if the window to be removed has child windows. It also may
+ // not remove any windows from windows at all if win is exiting and
// currently animating away. This ensures that winNdx is monotonically decreasing
- // and never beyond allAppWindows bounds.
- winNdx = Math.min(winNdx - 1, allAppWindows.size() - 1)) {
- WindowState win = allAppWindows.get(winNdx);
+ // and never beyond windows bounds.
+ winNdx = Math.min(winNdx - 1, windows.size() - 1)) {
+ WindowState win = windows.get(winNdx);
if (win.mAppDied) {
- if (DEBUG_WINDOW_MOVEMENT || DEBUG_ADD_REMOVE) {
- Slog.w(TAG, "removeAllDeadWindows: " + win);
- }
+ if (DEBUG_WINDOW_MOVEMENT || DEBUG_ADD_REMOVE) Slog.w(TAG,
+ "removeAllDeadWindows: " + win);
// Set mDestroying, we don't want any animation or delayed removal here.
win.mDestroying = true;
- mService.removeWindowLocked(win);
+ win.removeIfPossible();
}
}
}
boolean hasWindowsAlive() {
- for (int i = allAppWindows.size() - 1; i >= 0; i--) {
- if (!allAppWindows.get(i).mAppDied) {
+ for (int i = windows.size() - 1; i >= 0; i--) {
+ if (!windows.get(i).mAppDied) {
return true;
}
}
@@ -801,8 +776,8 @@
if (DEBUG_ADD_REMOVE) Slog.d(TAG_WM,
"Marking app token " + this + " with replacing windows.");
- for (int i = allAppWindows.size() - 1; i >= 0; i--) {
- final WindowState w = allAppWindows.get(i);
+ for (int i = windows.size() - 1; i >= 0; i--) {
+ final WindowState w = windows.get(i);
w.setReplacing(animate);
}
if (animate) {
@@ -818,8 +793,8 @@
void setReplacingChildren() {
if (DEBUG_ADD_REMOVE) Slog.d(TAG_WM, "Marking app token " + this
+ " with replacing child windows.");
- for (int i = allAppWindows.size() - 1; i >= 0; i--) {
- final WindowState w = allAppWindows.get(i);
+ for (int i = windows.size() - 1; i >= 0; i--) {
+ final WindowState w = windows.get(i);
if (w.shouldBeReplacedWithChildren()) {
w.setReplacing(false /* animate */);
}
@@ -830,15 +805,15 @@
if (DEBUG_ADD_REMOVE) Slog.d(TAG_WM,
"Resetting app token " + this + " of replacing window marks.");
- for (int i = allAppWindows.size() - 1; i >= 0; i--) {
- final WindowState w = allAppWindows.get(i);
+ for (int i = windows.size() - 1; i >= 0; i--) {
+ final WindowState w = windows.get(i);
w.resetReplacing();
}
}
void requestUpdateWallpaperIfNeeded() {
- for (int i = allAppWindows.size() - 1; i >= 0; i--) {
- final WindowState w = allAppWindows.get(i);
+ for (int i = windows.size() - 1; i >= 0; i--) {
+ final WindowState w = windows.get(i);
w.requestUpdateWallpaperIfNeeded();
}
}
@@ -873,28 +848,26 @@
mPendingRelaunchCount = 0;
}
+ @Override
void addWindow(WindowState w) {
- if (allAppWindows.contains(w)) {
- return;
- }
+ super.addWindow(w);
- for (int i = allAppWindows.size() - 1; i >= 0; i--) {
- WindowState candidate = allAppWindows.get(i);
- if (candidate.mWillReplaceWindow && candidate.mReplacingWindow == null &&
- candidate.getWindowTag().toString().equals(w.getWindowTag().toString())) {
+ for (int i = windows.size() - 1; i >= 0; i--) {
+ final WindowState candidate = windows.get(i);
+ if (candidate.mWillReplaceWindow && candidate.mReplacingWindow == null
+ && candidate.getWindowTag().toString().equals(w.getWindowTag().toString())) {
+
candidate.mReplacingWindow = w;
w.mSkipEnterAnimationForSeamlessReplacement = !candidate.mAnimateReplacingWindow;
-
// if we got a replacement window, reset the timeout to give drawing more time
mService.scheduleReplacingWindowTimeouts(this);
}
}
- allAppWindows.add(w);
}
boolean waitingForReplacement() {
- for (int i = allAppWindows.size() -1; i >= 0; i--) {
- WindowState candidate = allAppWindows.get(i);
+ for (int i = windows.size() - 1; i >= 0; i--) {
+ WindowState candidate = windows.get(i);
if (candidate.mWillReplaceWindow) {
return true;
}
@@ -903,15 +876,14 @@
}
void clearTimedoutReplacesLocked() {
- for (int i = allAppWindows.size() - 1; i >= 0;
- // removeWindowLocked at bottom of loop may remove multiple entries from
- // allAppWindows if the window to be removed has child windows. It also may
- // not remove any windows from allAppWindows at all if win is exiting and
- // currently animating away. This ensures that winNdx is monotonically decreasing
- // and never beyond allAppWindows bounds.
- i = Math.min(i - 1, allAppWindows.size() - 1)) {
- WindowState candidate = allAppWindows.get(i);
- if (candidate.mWillReplaceWindow == false) {
+ for (int i = windows.size() - 1; i >= 0;
+ // WindowState#remove() at bottom of loop may remove multiple entries from windows if
+ // the window to be removed has child windows. It also may not remove any windows from
+ // windows at all if win is exiting and currently animating away. This ensures that
+ // winNdx is monotonically decreasing and never beyond windows bounds.
+ i = Math.min(i - 1, windows.size() - 1)) {
+ final WindowState candidate = windows.get(i);
+ if (!candidate.mWillReplaceWindow) {
continue;
}
candidate.mWillReplaceWindow = false;
@@ -919,7 +891,7 @@
candidate.mReplacingWindow.mSkipEnterAnimationForSeamlessReplacement = false;
}
// Since the window already timed out, remove it immediately now.
- // Use WindowState#remove() instead of removeWindowLocked(), as the latter
+ // Use WindowState#remove() instead of WindowState#removeIfPossible(), as the latter
// delays removal on certain conditions, which will leave the stale window in the
// stack and marked mWillReplaceWindow=false, so the window will never be removed.
candidate.remove();
@@ -962,8 +934,8 @@
if (!mFrozenMergedConfig.isEmpty()) {
mFrozenMergedConfig.remove();
}
- for (int i = allAppWindows.size() - 1; i >= 0; i--) {
- final WindowState win = allAppWindows.get(i);
+ for (int i = windows.size() - 1; i >= 0; i--) {
+ final WindowState win = windows.get(i);
if (!win.mHasSurface) {
continue;
}
@@ -1007,49 +979,14 @@
}
void resetJustMovedInStack() {
- for (int i = allAppWindows.size() - 1; i >= 0; i--) {
- allAppWindows.get(i).resetJustMovedInStack();
+ for (int i = windows.size() - 1; i >= 0; i--) {
+ windows.get(i).resetJustMovedInStack();
}
}
- @Override
- int adjustAnimLayer(int adj) {
- int highestAnimLayer = super.adjustAnimLayer(adj);
-
- final int windowCount = allAppWindows.size();
-
- for (int i = 0; i < windowCount; i++) {
- final WindowState w = allAppWindows.get(i);
- w.adjustAnimLayer(adj);
-
- final int animLayer = w.mWinAnimator.mAnimLayer;
- if (DEBUG_LAYERS) Slog.v(TAG, "Updating layer " + w + ": " + animLayer);
- if (animLayer > highestAnimLayer) {
- highestAnimLayer = animLayer;
- }
- if (w == mService.mInputMethodTarget && !mService.mInputMethodTargetWaitingAnim) {
- mService.mLayersController.setInputMethodAnimLayerAdjustment(adj);
- }
- }
-
- return highestAnimLayer;
- }
-
- @Override
- int getHighestAnimLayer() {
- int layer = super.getHighestAnimLayer();
- for (int j = 0; j < allAppWindows.size(); j++) {
- final WindowState win = allAppWindows.get(j);
- if (win.mWinAnimator.mAnimLayer > layer) {
- layer = win.mWinAnimator.mAnimLayer;
- }
- }
- return layer;
- }
-
void setWaitingForDrawnIfResizingChanged() {
- for (int i = allAppWindows.size() - 1; i >= 0; --i) {
- final WindowState win = allAppWindows.get(i);
+ for (int i = windows.size() - 1; i >= 0; --i) {
+ final WindowState win = windows.get(i);
if (win.isDragResizeChanged()) {
mService.mWaitingForDrawn.add(win);
}
@@ -1062,8 +999,8 @@
// destroy all saved surfaces here.
destroySavedSurfaces();
- for (int winNdx = allAppWindows.size() - 1; winNdx >= 0; --winNdx) {
- final WindowState win = allAppWindows.get(winNdx);
+ for (int winNdx = windows.size() - 1; winNdx >= 0; --winNdx) {
+ final WindowState win = windows.get(winNdx);
if (win.mHasSurface && !resizingWindows.contains(win)) {
if (DEBUG_RESIZE) Slog.d(TAG, "resizeWindows: Resizing " + win);
resizingWindows.add(win);
@@ -1092,33 +1029,33 @@
}
void moveWindows() {
- for (int winNdx = allAppWindows.size() - 1; winNdx >= 0; --winNdx) {
- final WindowState win = allAppWindows.get(winNdx);
+ for (int winNdx = windows.size() - 1; winNdx >= 0; --winNdx) {
+ final WindowState win = windows.get(winNdx);
if (DEBUG_RESIZE) Slog.d(TAG, "moveWindows: Moving " + win);
win.mMovedByResize = true;
}
}
void notifyMovedInStack() {
- for (int winNdx = allAppWindows.size() - 1; winNdx >= 0; --winNdx) {
- final WindowState win = allAppWindows.get(winNdx);
+ for (int winNdx = windows.size() - 1; winNdx >= 0; --winNdx) {
+ final WindowState win = windows.get(winNdx);
win.notifyMovedInStack();
}
}
void resetDragResizingChangeReported() {
- for (int winNdx = allAppWindows.size() - 1; winNdx >= 0; --winNdx) {
- final WindowState win = allAppWindows.get(winNdx);
+ for (int winNdx = windows.size() - 1; winNdx >= 0; --winNdx) {
+ final WindowState win = windows.get(winNdx);
win.resetDragResizingChangeReported();
}
}
void detachDisplay() {
boolean doAnotherLayoutPass = false;
- for (int winNdx = allAppWindows.size() - 1; winNdx >= 0; --winNdx) {
+ for (int winNdx = windows.size() - 1; winNdx >= 0; --winNdx) {
// We are in the middle of changing the state of displays/stacks/tasks. We need
// to finish that, before we let layout interfere with it.
- mService.removeWindowLocked(allAppWindows.get(winNdx));
+ windows.get(winNdx).removeIfPossible();
doAnotherLayoutPass = true;
}
if (doAnotherLayoutPass) {
@@ -1127,8 +1064,8 @@
}
void forceWindowsScaleableInTransaction(boolean force) {
- for (int winNdx = allAppWindows.size() - 1; winNdx >= 0; --winNdx) {
- final WindowStateAnimator winAnimator = allAppWindows.get(winNdx).mWinAnimator;
+ for (int winNdx = windows.size() - 1; winNdx >= 0; --winNdx) {
+ final WindowStateAnimator winAnimator = windows.get(winNdx).mWinAnimator;
if (winAnimator == null || !winAnimator.hasSurface()) {
continue;
}
@@ -1137,8 +1074,8 @@
}
boolean isAnimating() {
- for (int winNdx = allAppWindows.size() - 1; winNdx >= 0; --winNdx) {
- final WindowStateAnimator winAnimator = allAppWindows.get(winNdx).mWinAnimator;
+ for (int winNdx = windows.size() - 1; winNdx >= 0; --winNdx) {
+ final WindowStateAnimator winAnimator = windows.get(winNdx).mWinAnimator;
if (winAnimator.isAnimationSet() || winAnimator.mWin.mAnimatingExit) {
return true;
}
@@ -1148,8 +1085,8 @@
void setAppLayoutChanges(int changes, String reason, int displayId) {
final WindowAnimator windowAnimator = mAppAnimator.mAnimator;
- for (int i = allAppWindows.size() - 1; i >= 0; i--) {
- if (displayId == allAppWindows.get(i).getDisplayId()) {
+ for (int i = windows.size() - 1; i >= 0; i--) {
+ if (displayId == windows.get(i).getDisplayId()) {
windowAnimator.setPendingLayoutChanges(displayId, changes);
if (DEBUG_LAYOUT_REPEATS) {
mService.mWindowPlacerLocked.debugLayoutRepeats(
@@ -1161,8 +1098,8 @@
}
void removeReplacedWindowIfNeeded(WindowState replacement) {
- for (int i = allAppWindows.size() - 1; i >= 0; i--) {
- final WindowState win = allAppWindows.get(i);
+ for (int i = windows.size() - 1; i >= 0; i--) {
+ final WindowState win = windows.get(i);
if (win.mWillReplaceWindow && win.mReplacingWindow == replacement
&& replacement.hasDrawnLw()) {
replacement.mSkipEnterAnimationForSeamlessReplacement = false;
@@ -1185,9 +1122,9 @@
mService.mH.sendEmptyMessageDelayed(H.APP_FREEZE_TIMEOUT, 2000);
}
}
- final int count = allAppWindows.size();
+ final int count = windows.size();
for (int i = 0; i < count; i++) {
- final WindowState w = allAppWindows.get(i);
+ final WindowState w = windows.get(i);
w.mAppFreezing = true;
}
}
@@ -1198,10 +1135,10 @@
return;
}
if (DEBUG_ORIENTATION) Slog.v(TAG_WM, "Clear freezing of " + this + " force=" + force);
- final int count = allAppWindows.size();
+ final int count = windows.size();
boolean unfrozeWindows = false;
for (int i = 0; i < count; i++) {
- final WindowState w = allAppWindows.get(i);
+ final WindowState w = windows.get(i);
if (w.mAppFreezing) {
w.mAppFreezing = false;
if (w.mHasSurface && !w.mOrientationChanging
@@ -1260,7 +1197,6 @@
fromToken.startingWindow = null;
fromToken.startingMoved = true;
tStartingWindow.mToken = this;
- tStartingWindow.mRootToken = this;
tStartingWindow.mAppToken = this;
if (DEBUG_WINDOW_MOVEMENT || DEBUG_ADD_REMOVE || DEBUG_STARTING_WINDOW) Slog.v(TAG_WM,
@@ -1270,8 +1206,7 @@
if (DEBUG_ADD_REMOVE) Slog.v(TAG_WM,
"Removing starting " + tStartingWindow + " from " + fromToken);
fromToken.removeWindow(tStartingWindow);
- fromToken.allAppWindows.remove(tStartingWindow);
- addWindowToList(tStartingWindow);
+ addWindow(tStartingWindow);
// Propagate other interesting state between the tokens. If the old token is displayed,
// we should immediately force the new one to be displayed. If it is animating, we need
@@ -1331,25 +1266,19 @@
}
int getWindowsCount() {
- return allAppWindows.size();
+ return windows.size();
}
void setAllAppWinAnimators() {
final ArrayList<WindowStateAnimator> allAppWinAnimators = mAppAnimator.mAllAppWinAnimators;
allAppWinAnimators.clear();
- final int windowsCount = allAppWindows.size();
+ final int windowsCount = windows.size();
for (int j = 0; j < windowsCount; j++) {
- allAppWinAnimators.add(allAppWindows.get(j).mWinAnimator);
+ allAppWinAnimators.add(windows.get(j).mWinAnimator);
}
}
- /** Returns true if the app token windows list is empty. */
- @Override
- boolean isEmpty() {
- return allAppWindows.isEmpty();
- }
-
@Override
AppWindowToken asAppWindowToken() {
// I am an app window token!
@@ -1362,9 +1291,6 @@
if (appToken != null) {
pw.print(prefix); pw.print("app=true voiceInteraction="); pw.println(voiceInteraction);
}
- if (allAppWindows.size() > 0) {
- pw.print(prefix); pw.print("allAppWindows="); pw.println(allAppWindows);
- }
pw.print(prefix); pw.print("task="); pw.println(mTask);
pw.print(prefix); pw.print(" appFullscreen="); pw.print(appFullscreen);
pw.print(" requestedOrientation="); pw.println(requestedOrientation);
diff --git a/services/core/java/com/android/server/wm/InputMonitor.java b/services/core/java/com/android/server/wm/InputMonitor.java
index 00781c5..b9c55a5 100644
--- a/services/core/java/com/android/server/wm/InputMonitor.java
+++ b/services/core/java/com/android/server/wm/InputMonitor.java
@@ -87,7 +87,7 @@
WindowState windowState = (WindowState) inputWindowHandle.windowState;
if (windowState != null) {
Slog.i(TAG_WM, "WINDOW DIED " + windowState);
- mService.removeWindowLocked(windowState);
+ windowState.removeIfPossible();
}
}
}
diff --git a/services/core/java/com/android/server/wm/WindowAnimator.java b/services/core/java/com/android/server/wm/WindowAnimator.java
index dee9cc3..6515fbd 100644
--- a/services/core/java/com/android/server/wm/WindowAnimator.java
+++ b/services/core/java/com/android/server/wm/WindowAnimator.java
@@ -363,7 +363,7 @@
+ " destroying=" + win.mDestroying
+ " parentHidden=" + win.isParentWindowHidden()
+ " vis=" + win.mViewVisibility
- + " hidden=" + win.mRootToken.hidden
+ + " hidden=" + win.mToken.hidden
+ " anim=" + win.mWinAnimator.mAnimation);
} else if (canBeForceHidden) {
if (shouldBeForceHidden) {
diff --git a/services/core/java/com/android/server/wm/WindowManagerService.java b/services/core/java/com/android/server/wm/WindowManagerService.java
index 74c5968..8f7896e 100644
--- a/services/core/java/com/android/server/wm/WindowManagerService.java
+++ b/services/core/java/com/android/server/wm/WindowManagerService.java
@@ -1270,12 +1270,12 @@
moveInputMethodDialogsLocked(pos + 1);
return;
}
- win.mToken.addWindowToList(win);
+ win.mToken.addWindow(win);
moveInputMethodDialogsLocked(pos);
}
private void reAddWindowToListInOrderLocked(WindowState win) {
- win.mToken.addWindowToList(win);
+ win.mToken.addWindow(win);
// This is a hack to get all of the child windows added as well at the right position. Child
// windows should be rare and this case should be rare, so it shouldn't be that big a deal.
WindowList windows = win.getWindowList();
@@ -1284,7 +1284,7 @@
if (DEBUG_WINDOW_MOVEMENT) Slog.v(TAG_WM, "ReAdd removing from " + wpos + ": " + win);
windows.remove(wpos);
mWindowsChanged = true;
- win.reAddWindowLocked(wpos);
+ win.reAddWindow(wpos);
}
}
@@ -1326,7 +1326,7 @@
if (DEBUG_INPUT_METHOD) Slog.v(TAG_WM, "Adding " + N + " dialogs at pos=" + pos);
for (int i=0; i<N; i++) {
WindowState win = dialogs.get(i);
- pos = win.reAddWindowLocked(pos);
+ pos = win.reAddWindow(pos);
}
if (DEBUG_INPUT_METHOD) {
Slog.v(TAG_WM, "Final window list:");
@@ -1405,7 +1405,7 @@
Slog.v(TAG_WM, "List after removing with new pos " + imPos + ":");
logWindowList(windows, " ");
}
- imWin.reAddWindowLocked(imPos);
+ imWin.reAddWindow(imPos);
if (DEBUG_INPUT_METHOD) {
Slog.v(TAG_WM, "List after moving IM to " + imPos + ":");
logWindowList(windows, " ");
@@ -1462,7 +1462,7 @@
}
boolean reportNewConfig = false;
- WindowState attachedWindow = null;
+ WindowState parentWindow = null;
long origId;
final int type = attrs.type;
@@ -1489,14 +1489,14 @@
}
if (type >= FIRST_SUB_WINDOW && type <= LAST_SUB_WINDOW) {
- attachedWindow = windowForClientLocked(null, attrs.token, false);
- if (attachedWindow == null) {
+ parentWindow = windowForClientLocked(null, attrs.token, false);
+ if (parentWindow == null) {
Slog.w(TAG_WM, "Attempted to add window with token that is not a window: "
+ attrs.token + ". Aborting.");
return WindowManagerGlobal.ADD_BAD_SUBWINDOW_TOKEN;
}
- if (attachedWindow.mAttrs.type >= FIRST_SUB_WINDOW
- && attachedWindow.mAttrs.type <= LAST_SUB_WINDOW) {
+ if (parentWindow.mAttrs.type >= FIRST_SUB_WINDOW
+ && parentWindow.mAttrs.type <= LAST_SUB_WINDOW) {
Slog.w(TAG_WM, "Attempted to add window with token that is a sub-window: "
+ attrs.token + ". Aborting.");
return WindowManagerGlobal.ADD_BAD_SUBWINDOW_TOKEN;
@@ -1508,46 +1508,52 @@
return WindowManagerGlobal.ADD_PERMISSION_DENIED;
}
- WindowToken token = mTokenMap.get(attrs.token);
AppWindowToken atoken = null;
+ final boolean hasParent = parentWindow != null;
+ // Use existing parent window token for child windows since they go in the same token
+ // as there parent window so we can apply the same policy on them.
+ WindowToken token = mTokenMap.get(hasParent ? parentWindow.mAttrs.token : attrs.token);
+ // If this is a child window, we want to apply the same type checking rules as the
+ // parent window type.
+ final int rootType = hasParent ? parentWindow.mAttrs.type : type;
if (token == null) {
- if (type >= FIRST_APPLICATION_WINDOW && type <= LAST_APPLICATION_WINDOW) {
+ if (rootType >= FIRST_APPLICATION_WINDOW && rootType <= LAST_APPLICATION_WINDOW) {
Slog.w(TAG_WM, "Attempted to add application window with unknown token "
+ attrs.token + ". Aborting.");
return WindowManagerGlobal.ADD_BAD_APP_TOKEN;
}
- if (type == TYPE_INPUT_METHOD) {
+ if (rootType == TYPE_INPUT_METHOD) {
Slog.w(TAG_WM, "Attempted to add input method window with unknown token "
+ attrs.token + ". Aborting.");
return WindowManagerGlobal.ADD_BAD_APP_TOKEN;
}
- if (type == TYPE_VOICE_INTERACTION) {
+ if (rootType == TYPE_VOICE_INTERACTION) {
Slog.w(TAG_WM, "Attempted to add voice interaction window with unknown token "
+ attrs.token + ". Aborting.");
return WindowManagerGlobal.ADD_BAD_APP_TOKEN;
}
- if (type == TYPE_WALLPAPER) {
+ if (rootType == TYPE_WALLPAPER) {
Slog.w(TAG_WM, "Attempted to add wallpaper window with unknown token "
+ attrs.token + ". Aborting.");
return WindowManagerGlobal.ADD_BAD_APP_TOKEN;
}
- if (type == TYPE_DREAM) {
+ if (rootType == TYPE_DREAM) {
Slog.w(TAG_WM, "Attempted to add Dream window with unknown token "
+ attrs.token + ". Aborting.");
return WindowManagerGlobal.ADD_BAD_APP_TOKEN;
}
- if (type == TYPE_QS_DIALOG) {
+ if (rootType == TYPE_QS_DIALOG) {
Slog.w(TAG_WM, "Attempted to add QS dialog window with unknown token "
+ attrs.token + ". Aborting.");
return WindowManagerGlobal.ADD_BAD_APP_TOKEN;
}
- if (type == TYPE_ACCESSIBILITY_OVERLAY) {
+ if (rootType == TYPE_ACCESSIBILITY_OVERLAY) {
Slog.w(TAG_WM, "Attempted to add Accessibility overlay window with unknown token "
+ attrs.token + ". Aborting.");
return WindowManagerGlobal.ADD_BAD_APP_TOKEN;
}
token = new WindowToken(this, attrs.token, -1, false);
- } else if (type >= FIRST_APPLICATION_WINDOW && type <= LAST_APPLICATION_WINDOW) {
+ } else if (rootType >= FIRST_APPLICATION_WINDOW && rootType <= LAST_APPLICATION_WINDOW) {
atoken = token.asAppWindowToken();
if (atoken == null) {
Slog.w(TAG_WM, "Attempted to add window with non-application token "
@@ -1558,57 +1564,57 @@
+ token + ". Aborting.");
return WindowManagerGlobal.ADD_APP_EXITING;
}
- if (type == TYPE_APPLICATION_STARTING && atoken.firstWindowDrawn) {
+ if (rootType == TYPE_APPLICATION_STARTING && atoken.firstWindowDrawn) {
// No need for this guy!
if (DEBUG_STARTING_WINDOW || localLOGV) Slog.v(
TAG_WM, "**** NO NEED TO START: " + attrs.getTitle());
return WindowManagerGlobal.ADD_STARTING_NOT_NEEDED;
}
- } else if (type == TYPE_INPUT_METHOD) {
+ } else if (rootType == TYPE_INPUT_METHOD) {
if (token.windowType != TYPE_INPUT_METHOD) {
Slog.w(TAG_WM, "Attempted to add input method window with bad token "
+ attrs.token + ". Aborting.");
return WindowManagerGlobal.ADD_BAD_APP_TOKEN;
}
- } else if (type == TYPE_VOICE_INTERACTION) {
+ } else if (rootType == TYPE_VOICE_INTERACTION) {
if (token.windowType != TYPE_VOICE_INTERACTION) {
Slog.w(TAG_WM, "Attempted to add voice interaction window with bad token "
+ attrs.token + ". Aborting.");
return WindowManagerGlobal.ADD_BAD_APP_TOKEN;
}
- } else if (type == TYPE_WALLPAPER) {
+ } else if (rootType == TYPE_WALLPAPER) {
if (token.windowType != TYPE_WALLPAPER) {
Slog.w(TAG_WM, "Attempted to add wallpaper window with bad token "
+ attrs.token + ". Aborting.");
return WindowManagerGlobal.ADD_BAD_APP_TOKEN;
}
- } else if (type == TYPE_DREAM) {
+ } else if (rootType == TYPE_DREAM) {
if (token.windowType != TYPE_DREAM) {
Slog.w(TAG_WM, "Attempted to add Dream window with bad token "
+ attrs.token + ". Aborting.");
return WindowManagerGlobal.ADD_BAD_APP_TOKEN;
}
- } else if (type == TYPE_ACCESSIBILITY_OVERLAY) {
+ } else if (rootType == TYPE_ACCESSIBILITY_OVERLAY) {
if (token.windowType != TYPE_ACCESSIBILITY_OVERLAY) {
Slog.w(TAG_WM, "Attempted to add Accessibility overlay window with bad token "
+ attrs.token + ". Aborting.");
return WindowManagerGlobal.ADD_BAD_APP_TOKEN;
}
- } else if (type == TYPE_QS_DIALOG) {
+ } else if (rootType == TYPE_QS_DIALOG) {
if (token.windowType != TYPE_QS_DIALOG) {
Slog.w(TAG_WM, "Attempted to add QS dialog window with bad token "
+ attrs.token + ". Aborting.");
return WindowManagerGlobal.ADD_BAD_APP_TOKEN;
}
} else if (token.asAppWindowToken() != null) {
- Slog.w(TAG_WM, "Non-null appWindowToken for system window of type=" + type);
+ Slog.w(TAG_WM, "Non-null appWindowToken for system window of rootType=" + rootType);
// It is not valid to use an app token with other system types; we will
// instead make a new token for it (as if null had been passed in for the token).
attrs.token = null;
token = new WindowToken(this, null, -1, false);
}
- WindowState win = new WindowState(this, session, client, token, attachedWindow,
+ WindowState win = new WindowState(this, session, client, token, parentWindow,
appOp[0], seq, attrs, viewVisibility, displayContent, session.mUid);
if (win.mDeathRecipient == null) {
// Client has apparently died, so there is no reason to
@@ -1674,11 +1680,11 @@
imMayMove = false;
} else if (type == TYPE_INPUT_METHOD_DIALOG) {
mInputMethodDialogs.add(win);
- win.mToken.addWindowToList(win);
+ win.mToken.addWindow(win);
moveInputMethodDialogsLocked(findDesiredInputMethodWindowIndexLocked(true));
imMayMove = false;
} else {
- win.mToken.addWindowToList(win);
+ win.mToken.addWindow(win);
if (type == TYPE_WALLPAPER) {
mWallpaperControllerLocked.clearLastWallpaperTimeoutTime();
displayContent.pendingLayoutChanges |= FINISH_LAYOUT_REDO_WALLPAPER;
@@ -1873,14 +1879,10 @@
if (win == null) {
return;
}
- removeWindowLocked(win);
+ win.removeIfPossible();
}
}
- void removeWindowLocked(WindowState win) {
- win.removeIfPossible(false /*keepVisibleDeadWindow*/);
- }
-
/**
* Performs some centralized bookkeeping clean-up on the window that is being removed.
* NOTE: Should only be called from {@link WindowState#remove()}
@@ -8220,16 +8222,13 @@
// Internals
// -------------------------------------------------------------
- final WindowState windowForClientLocked(Session session, IWindow client,
- boolean throwOnError) {
+ final WindowState windowForClientLocked(Session session, IWindow client, boolean throwOnError) {
return windowForClientLocked(session, client.asBinder(), throwOnError);
}
- final WindowState windowForClientLocked(Session session, IBinder client,
- boolean throwOnError) {
+ final WindowState windowForClientLocked(Session session, IBinder client, boolean throwOnError) {
WindowState win = mWindowMap.get(client);
- if (localLOGV) Slog.v(
- TAG_WM, "Looking up client " + client + ": " + win);
+ if (localLOGV) Slog.v(TAG_WM, "Looking up client " + client + ": " + win);
if (win == null) {
RuntimeException ex = new IllegalArgumentException(
"Requested window " + client + " does not exist");
@@ -8289,15 +8288,13 @@
i++;
}
- // Keep whatever windows were below the app windows still below,
- // by skipping them.
+ // Keep whatever windows were below the app windows still below, by skipping them.
lastBelow++;
i = lastBelow;
- // First add all of the exiting app tokens... these are no longer
- // in the main app list, but still have windows shown. We put them
- // in the back because now that the animation is over we no longer
- // will care about them.
+ // First add all of the exiting app tokens... these are no longer in the main app list,
+ // but still have windows shown. We put them in the back because now that the animation is
+ // over we no longer will care about them.
final ArrayList<TaskStack> stacks = displayContent.getStacks();
final int numStacks = stacks.size();
for (int stackNdx = 0; stackNdx < numStacks; ++stackNdx) {
diff --git a/services/core/java/com/android/server/wm/WindowState.java b/services/core/java/com/android/server/wm/WindowState.java
index d9836a8..546498a 100644
--- a/services/core/java/com/android/server/wm/WindowState.java
+++ b/services/core/java/com/android/server/wm/WindowState.java
@@ -165,7 +165,7 @@
final int mOwnerUid;
final IWindowId mWindowId;
WindowToken mToken;
- WindowToken mRootToken;
+ // The same object as mToken if this is an app window and null for non-app windows.
AppWindowToken mAppToken;
// mAttrs.flags is tested in animation without being locked. If the bits tested are ever
@@ -554,6 +554,7 @@
mClient = c;
mAppOp = appOp;
mToken = token;
+ mAppToken = mToken.asAppWindowToken();
mOwnerUid = ownerId;
mWindowId = new IWindowId.Stub() {
@Override
@@ -627,8 +628,6 @@
}
mIsFloatingLayer = mIsImWindow || mIsWallpaper;
- mRootToken = getTopParentWindow().mToken;
- mAppToken = mRootToken.asAppWindowToken();
if (mAppToken != null) {
final DisplayContent appDisplay = getDisplayContent();
mNotOnAppsDisplay = displayContent != appDisplay;
@@ -1192,14 +1191,14 @@
*/
@Override
public boolean isVisibleOrBehindKeyguardLw() {
- if (mRootToken.waitingToShow && mService.mAppTransition.isTransitionSet()) {
+ if (mToken.waitingToShow && mService.mAppTransition.isTransitionSet()) {
return false;
}
final AppWindowToken atoken = mAppToken;
final boolean animating = atoken != null && atoken.mAppAnimator.animation != null;
return mHasSurface && !mDestroying && !mAnimatingExit
&& (atoken == null ? mPolicyVisibility : !atoken.hiddenRequested)
- && ((!isParentWindowHidden() && mViewVisibility == View.VISIBLE && !mRootToken.hidden)
+ && ((!isParentWindowHidden() && mViewVisibility == View.VISIBLE && !mToken.hidden)
|| mWinAnimator.mAnimation != null || animating);
}
@@ -1217,7 +1216,7 @@
* not the pending requested hidden state.
*/
boolean isVisibleNow() {
- return (!mRootToken.hidden || mAttrs.type == TYPE_APPLICATION_STARTING)
+ return (!mToken.hidden || mAttrs.type == TYPE_APPLICATION_STARTING)
&& isVisibleUnchecked();
}
@@ -1299,11 +1298,11 @@
* of a transition that has not yet been started.
*/
boolean isReadyForDisplay() {
- if (mRootToken.waitingToShow && mService.mAppTransition.isTransitionSet()) {
+ if (mToken.waitingToShow && mService.mAppTransition.isTransitionSet()) {
return false;
}
return mHasSurface && mPolicyVisibility && !mDestroying
- && ((!isParentWindowHidden() && mViewVisibility == View.VISIBLE && !mRootToken.hidden)
+ && ((!isParentWindowHidden() && mViewVisibility == View.VISIBLE && !mToken.hidden)
|| mWinAnimator.mAnimation != null
|| ((mAppToken != null) && (mAppToken.mAppAnimator.animation != null)));
}
@@ -1313,7 +1312,7 @@
* to the keyguard.
*/
boolean isReadyForDisplayIgnoringKeyguard() {
- if (mRootToken.waitingToShow && mService.mAppTransition.isTransitionSet()) {
+ if (mToken.waitingToShow && mService.mAppTransition.isTransitionSet()) {
return false;
}
final AppWindowToken atoken = mAppToken;
@@ -1323,7 +1322,7 @@
return false;
}
return mHasSurface && !mDestroying
- && ((!isParentWindowHidden() && mViewVisibility == View.VISIBLE && !mRootToken.hidden)
+ && ((!isParentWindowHidden() && mViewVisibility == View.VISIBLE && !mToken.hidden)
|| mWinAnimator.mAnimation != null
|| ((atoken != null) && (atoken.mAppAnimator.animation != null)
&& !mWinAnimator.isDummyAnimation()));
@@ -1357,7 +1356,7 @@
final AppWindowToken atoken = mAppToken;
return mViewVisibility == View.GONE
|| !mRelayoutCalled
- || (atoken == null && mRootToken.hidden)
+ || (atoken == null && mToken.hidden)
|| (atoken != null && atoken.hiddenRequested)
|| isParentWindowHidden()
|| (mAnimatingExit && !isAnimatingLw())
@@ -1487,6 +1486,10 @@
mService.postWindowRemoveCleanupLocked(this);
}
+ void removeIfPossible() {
+ removeIfPossible(false /*keepVisibleDeadWindow*/);
+ }
+
void removeIfPossible(boolean keepVisibleDeadWindow) {
mWindowRemovalAllowed = true;
if (DEBUG_ADD_REMOVE) Slog.v(TAG,
@@ -1950,7 +1953,7 @@
}
} else if (mHasSurface) {
Slog.e(TAG, "!!! LEAK !!! Window removed but surface still valid.");
- mService.removeWindowLocked(WindowState.this);
+ WindowState.this.removeIfPossible();
}
}
} catch (IllegalArgumentException ex) {
@@ -2728,7 +2731,6 @@
}
if (dumpAll) {
pw.print(prefix); pw.print("mToken="); pw.println(mToken);
- pw.print(prefix); pw.print("mRootToken="); pw.println(mRootToken);
if (mAppToken != null) {
pw.print(prefix); pw.print("mAppToken="); pw.println(mAppToken);
pw.print(prefix); pw.print(" isAnimatingWithSavedSurface()=");
@@ -3020,7 +3022,7 @@
/** Returns the topmost parent window if this is a child of another window, else this. */
WindowState getTopParentWindow() {
WindowState w = this;
- while (w.mIsChildWindow) {
+ while (w != null && w.mIsChildWindow) {
w = w.getParentWindow();
}
return w;
@@ -3215,7 +3217,7 @@
// TODO: come-up with a better name for this method that represents what it does.
// Or, it is probably not going to matter anyways if we are successful in getting rid of
// the WindowList concept.
- int reAddWindowLocked(int index) {
+ int reAddWindow(int index) {
final WindowList windows = getWindowList();
// Adding child windows relies on child windows being ordered by mSubLayer using
// {@link #sWindowSubLayerComparator}.
diff --git a/services/core/java/com/android/server/wm/WindowSurfacePlacer.java b/services/core/java/com/android/server/wm/WindowSurfacePlacer.java
index 25709c5..c26c078 100644
--- a/services/core/java/com/android/server/wm/WindowSurfacePlacer.java
+++ b/services/core/java/com/android/server/wm/WindowSurfacePlacer.java
@@ -956,13 +956,13 @@
if (gone) Slog.v(TAG, " GONE: mViewVisibility="
+ win.mViewVisibility + " mRelayoutCalled="
+ win.mRelayoutCalled + " hidden="
- + win.mRootToken.hidden + " hiddenRequested="
+ + win.mToken.hidden + " hiddenRequested="
+ (atoken != null && atoken.hiddenRequested)
+ " parentHidden=" + win.isParentWindowHidden());
else Slog.v(TAG, " VIS: mViewVisibility="
+ win.mViewVisibility + " mRelayoutCalled="
+ win.mRelayoutCalled + " hidden="
- + win.mRootToken.hidden + " hiddenRequested="
+ + win.mToken.hidden + " hiddenRequested="
+ (atoken != null && atoken.hiddenRequested)
+ " parentHidden=" + win.isParentWindowHidden());
}
diff --git a/services/core/java/com/android/server/wm/WindowToken.java b/services/core/java/com/android/server/wm/WindowToken.java
index 7ed16f5..00e71f2 100644
--- a/services/core/java/com/android/server/wm/WindowToken.java
+++ b/services/core/java/com/android/server/wm/WindowToken.java
@@ -16,6 +16,7 @@
package com.android.server.wm;
+import android.annotation.CallSuper;
import android.os.Bundle;
import android.os.Debug;
import android.os.IBinder;
@@ -95,10 +96,16 @@
}
void removeAllWindows() {
- for (int winNdx = windows.size() - 1; winNdx >= 0; --winNdx) {
+ for (int winNdx = windows.size() - 1; winNdx >= 0;
+ // WindowState#removeIfPossible() at bottom of loop may remove multiple entries from
+ // allAppWindows if the window to be removed has child windows. It also may not
+ // remove any windows from allAppWindows at all if win is exiting and currently
+ // animating away. This ensures that winNdx is monotonically decreasing and never
+ // beyond allAppWindows bounds.
+ winNdx = Math.min(winNdx - 1, windows.size() - 1)) {
WindowState win = windows.get(winNdx);
if (DEBUG_WINDOW_MOVEMENT) Slog.w(TAG_WM, "removeAllWindows: removing win=" + win);
- win.mService.removeWindowLocked(win);
+ win.removeIfPossible();
}
windows.clear();
}
@@ -157,6 +164,9 @@
if (animLayer > highestAnimLayer) {
highestAnimLayer = animLayer;
}
+ if (w == mService.mInputMethodTarget && !mService.mInputMethodTargetWaitingAnim) {
+ mService.mLayersController.setInputMethodAnimLayerAdjustment(adj);
+ }
}
return highestAnimLayer;
}
@@ -258,8 +268,7 @@
}
}
- // TODO: Rename to addWindow when conflict with AppWindowToken is resolved. The call below.
- void addWindowToList(final WindowState win) {
+ void addWindow(final WindowState win) {
if (DEBUG_FOCUS) Slog.d(TAG_WM, "addWindow: win=" + win + " Callers=" + Debug.getCallers(5));
if (!win.isChildWindow()) {
@@ -276,11 +285,6 @@
} else {
addChildWindow(win);
}
-
- final AppWindowToken appToken = win.mAppToken;
- if (appToken != null) {
- appToken.addWindow(win);
- }
}
private int addAppWindow(final WindowState win) {
@@ -451,10 +455,20 @@
final int count = windows.size();
for (int i = 0; i < count; i++) {
final WindowState win = windows.get(i);
+ if (win.isChildWindow()) {
+ // The WindowState.reAddWindow below already takes care of re-adding the
+ // child windows for any parent window in this token. This is a side effect of
+ // ensuring child windows are in the same WindowToken as their parent window.
+ //
+ // TODO: Can be removed once WindowToken no longer contains child windows. i.e it is
+ // using WindowContainer which uses the hierarchy to access child windows through
+ // their parent window.
+ continue;
+ }
final DisplayContent winDisplayContent = win.getDisplayContent();
if (winDisplayContent == displayContent || winDisplayContent == null) {
win.mDisplayContent = displayContent;
- index = win.reAddWindowLocked(index);
+ index = win.reAddWindow(index);
}
}
return index;
@@ -486,6 +500,7 @@
return null;
}
+ @CallSuper
void removeWindow(WindowState win) {
windows.remove(win);
}