diff options
| -rw-r--r-- | core/java/android/view/WindowManager.java | 15 | ||||
| -rw-r--r-- | core/java/android/widget/Toast.java | 9 | ||||
| -rw-r--r-- | services/core/java/com/android/server/wm/WindowManagerService.java | 19 | 
3 files changed, 41 insertions, 2 deletions
diff --git a/core/java/android/view/WindowManager.java b/core/java/android/view/WindowManager.java index a3a40eb33589..89e146b3fed8 100644 --- a/core/java/android/view/WindowManager.java +++ b/core/java/android/view/WindowManager.java @@ -1726,6 +1726,16 @@ public interface WindowManager extends ViewManager {           */          public CharSequence accessibilityTitle; +        /** +         * Sets a timeout in milliseconds before which the window will be removed +         * by the window manager. Useful for transient notifications like toasts +         * so we don't have to rely on client cooperation to ensure the window +         * is removed. Must be specified at window creation time. +         * +         * @hide +         */ +        public long removeTimeoutMilliseconds = -1; +          public LayoutParams() {              super(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT);              type = TYPE_APPLICATION; @@ -1846,6 +1856,7 @@ public interface WindowManager extends ViewManager {              out.writeInt(needsMenuKey);              out.writeInt(accessibilityIdOfAnchor);              TextUtils.writeToParcel(accessibilityTitle, out, parcelableFlags); +            out.writeLong(removeTimeoutMilliseconds);          }          public static final Parcelable.Creator<LayoutParams> CREATOR @@ -1899,6 +1910,7 @@ public interface WindowManager extends ViewManager {              needsMenuKey = in.readInt();              accessibilityIdOfAnchor = in.readInt();              accessibilityTitle = TextUtils.CHAR_SEQUENCE_CREATOR.createFromParcel(in); +            removeTimeoutMilliseconds = in.readLong();          }          @SuppressWarnings({"PointlessBitwiseExpression"}) @@ -2119,6 +2131,9 @@ public interface WindowManager extends ViewManager {                  changes |= ACCESSIBILITY_TITLE_CHANGED;              } +            // This can't change, it's only set at window creation time. +            removeTimeoutMilliseconds = o.removeTimeoutMilliseconds; +              return changes;          } diff --git a/core/java/android/widget/Toast.java b/core/java/android/widget/Toast.java index 207f675945e0..77626754264f 100644 --- a/core/java/android/widget/Toast.java +++ b/core/java/android/widget/Toast.java @@ -163,6 +163,7 @@ public class Toast {       */      public void setDuration(@Duration int duration) {          mDuration = duration; +        mTN.mDuration = duration;      }      /** @@ -342,7 +343,7 @@ public class Toast {          };          private final WindowManager.LayoutParams mParams = new WindowManager.LayoutParams(); -        final Handler mHandler = new Handler();     +        final Handler mHandler = new Handler();          int mGravity;          int mX, mY; @@ -352,9 +353,13 @@ public class Toast {          View mView;          View mNextView; +        int mDuration;          WindowManager mWM; +        static final long SHORT_DURATION_TIMEOUT = 5000; +        static final long LONG_DURATION_TIMEOUT = 1000; +          TN() {              // XXX This should be changed to use a Dialog, with a Theme.Toast              // defined that sets up the layout params appropriately. @@ -417,6 +422,8 @@ public class Toast {                  mParams.verticalMargin = mVerticalMargin;                  mParams.horizontalMargin = mHorizontalMargin;                  mParams.packageName = packageName; +                mParams.removeTimeoutMilliseconds = mDuration == +                    Toast.LENGTH_LONG ? LONG_DURATION_TIMEOUT : SHORT_DURATION_TIMEOUT;                  if (mView.getParent() != null) {                      if (localLOGV) Log.v(TAG, "REMOVE! " + mView + " in " + this);                      mWM.removeView(mView); diff --git a/services/core/java/com/android/server/wm/WindowManagerService.java b/services/core/java/com/android/server/wm/WindowManagerService.java index 0a0f0f099061..57dc97a514f5 100644 --- a/services/core/java/com/android/server/wm/WindowManagerService.java +++ b/services/core/java/com/android/server/wm/WindowManagerService.java @@ -2107,6 +2107,11 @@ public class WindowManagerService extends IWindowManager.Stub              if (win.isVisibleOrAdding() && updateOrientationFromAppTokensLocked(false)) {                  reportNewConfig = true;              } +            if (attrs.removeTimeoutMilliseconds > 0) { +                mH.sendMessageDelayed( +                        mH.obtainMessage(H.WINDOW_REMOVE_TIMEOUT, win), +                        attrs.removeTimeoutMilliseconds); +            }          }          if (reportNewConfig) { @@ -7788,8 +7793,8 @@ public class WindowManagerService extends IWindowManager.Stub          public static final int NOTIFY_APP_TRANSITION_CANCELLED = 48;          public static final int NOTIFY_APP_TRANSITION_FINISHED = 49;          public static final int NOTIFY_STARTING_WINDOW_DRAWN = 50; -          public static final int UPDATE_ANIMATION_SCALE = 51; +        public static final int WINDOW_REMOVE_TIMEOUT = 52;          /**           * Used to denote that an integer field in a message will not be used. @@ -8402,6 +8407,18 @@ public class WindowManagerService extends IWindowManager.Stub                      mAmInternal.notifyStartingWindowDrawn();                  }                  break; +                case WINDOW_REMOVE_TIMEOUT: { +                    final WindowState window = (WindowState) msg.obj; +                    synchronized(mWindowMap) { +                        // It's counterintuitive that we check that "mWindowRemovalAllowed" +                        // is false. But in fact if it's true, it means a remove has already +                        // been requested and we better just not do anything. +                        if (!window.mRemoved && !window.mWindowRemovalAllowed) { +                            removeWindowLocked(window); +                        } +                    } +                } +                break;              }              if (DEBUG_WINDOW_TRACE) {                  Slog.v(TAG_WM, "handleMessage: exit");  |