From 6d89f482552067544d67716a469979769cdbe6b8 Mon Sep 17 00:00:00 2001 From: Alan Viverette Date: Fri, 5 Jan 2018 15:33:24 -0500 Subject: [PATCH] Don't end transitions on a detached window, prevent crash in WindowId A WindowId's token should never be null, but let's avoid getting into that situation in the first place. Fixes: 70015590 Test: manual, cannot reliably repro in CTS test Change-Id: I378ba9ba822ecc445d3b8de265b5ec0d20a12dd3 --- core/java/android/view/View.java | 15 ++++++++------- core/java/android/view/WindowId.java | 23 +++++++++++++---------- core/java/android/widget/PopupWindow.java | 4 +++- 3 files changed, 24 insertions(+), 18 deletions(-) diff --git a/core/java/android/view/View.java b/core/java/android/view/View.java index 2af2467588125..6e326f55b855a 100644 --- a/core/java/android/view/View.java +++ b/core/java/android/view/View.java @@ -18049,19 +18049,20 @@ public class View implements Drawable.Callback, KeyEvent.Callback, * currently attached to. */ public WindowId getWindowId() { - if (mAttachInfo == null) { + AttachInfo ai = mAttachInfo; + if (ai == null) { return null; } - if (mAttachInfo.mWindowId == null) { + if (ai.mWindowId == null) { try { - mAttachInfo.mIWindowId = mAttachInfo.mSession.getWindowId( - mAttachInfo.mWindowToken); - mAttachInfo.mWindowId = new WindowId( - mAttachInfo.mIWindowId); + ai.mIWindowId = ai.mSession.getWindowId(ai.mWindowToken); + if (ai.mIWindowId != null) { + ai.mWindowId = new WindowId(ai.mIWindowId); + } } catch (RemoteException e) { } } - return mAttachInfo.mWindowId; + return ai.mWindowId; } /** diff --git a/core/java/android/view/WindowId.java b/core/java/android/view/WindowId.java index c4cda2c70f256..12e58f14e4f90 100644 --- a/core/java/android/view/WindowId.java +++ b/core/java/android/view/WindowId.java @@ -16,6 +16,8 @@ package android.view; +import android.annotation.NonNull; +import android.annotation.Nullable; import android.os.Handler; import android.os.IBinder; import android.os.Message; @@ -35,6 +37,7 @@ import java.util.HashMap; * that doesn't allow the other process to negatively harm your window. */ public class WindowId implements Parcelable { + @NonNull private final IWindowId mToken; /** @@ -74,8 +77,7 @@ public class WindowId implements Parcelable { } }; - final HashMap mRegistrations - = new HashMap(); + final HashMap mRegistrations = new HashMap<>(); class H extends Handler { @Override @@ -163,10 +165,9 @@ public class WindowId implements Parcelable { * same package. */ @Override - public boolean equals(Object otherObj) { + public boolean equals(@Nullable Object otherObj) { if (otherObj instanceof WindowId) { - return mToken.asBinder().equals(((WindowId) otherObj) - .mToken.asBinder()); + return mToken.asBinder().equals(((WindowId) otherObj).mToken.asBinder()); } return false; } @@ -182,7 +183,7 @@ public class WindowId implements Parcelable { sb.append("IntentSender{"); sb.append(Integer.toHexString(System.identityHashCode(this))); sb.append(": "); - sb.append(mToken != null ? mToken.asBinder() : null); + sb.append(mToken.asBinder()); sb.append('}'); return sb.toString(); } @@ -195,30 +196,32 @@ public class WindowId implements Parcelable { out.writeStrongBinder(mToken.asBinder()); } - public static final Parcelable.Creator CREATOR - = new Parcelable.Creator() { + public static final Parcelable.Creator CREATOR = new Parcelable.Creator() { + @Override public WindowId createFromParcel(Parcel in) { IBinder target = in.readStrongBinder(); return target != null ? new WindowId(target) : null; } + @Override public WindowId[] newArray(int size) { return new WindowId[size]; } }; /** @hide */ + @NonNull public IWindowId getTarget() { return mToken; } /** @hide */ - public WindowId(IWindowId target) { + public WindowId(@NonNull IWindowId target) { mToken = target; } /** @hide */ - public WindowId(IBinder target) { + public WindowId(@NonNull IBinder target) { mToken = IWindowId.Stub.asInterface(target); } } diff --git a/core/java/android/widget/PopupWindow.java b/core/java/android/widget/PopupWindow.java index e91db13905826..755509c54e2e7 100644 --- a/core/java/android/widget/PopupWindow.java +++ b/core/java/android/widget/PopupWindow.java @@ -2563,7 +2563,9 @@ public class PopupWindow { public void onViewDetachedFromWindow(View v) { v.removeOnAttachStateChangeListener(this); - TransitionManager.endTransitions(PopupDecorView.this); + if (isAttachedToWindow()) { + TransitionManager.endTransitions(PopupDecorView.this); + } } };