diff options
author | yusufo <yusufo@chromium.org> | 2015-12-18 10:19:36 -0800 |
---|---|---|
committer | Commit bot <commit-bot@chromium.org> | 2015-12-18 18:20:24 +0000 |
commit | fdf17ed2da4f4554400c25993aa688cb9355c004 (patch) | |
tree | ba52b8e2ba567330bea1fbaf42c525ed85f9c234 | |
parent | f910b1af241f8d79e28035ce167b8d626457e333 (diff) | |
download | chromium_src-fdf17ed2da4f4554400c25993aa688cb9355c004.zip chromium_src-fdf17ed2da4f4554400c25993aa688cb9355c004.tar.gz chromium_src-fdf17ed2da4f4554400c25993aa688cb9355c004.tar.bz2 |
Pull the Activity context from WindowAndroid if possible
WebView uses ContentViewCore's context for displaying dialogs and
wraps it at construction time. This change makes sure that if there
is an activity that can be reached through WindowAndroid, we use
that as the context inside ColorChooser. Also make sure if there is no activity, we
dont attempt to create a color chooser and try to show it.
Update ActivityWindowAndroid to take a Context type so
that in Android WebView, the activity context can remain wrapped.
BUG=550410, 570429
Review URL: https://codereview.chromium.org/1528733002
Cr-Commit-Position: refs/heads/master@{#366125}
6 files changed, 45 insertions, 33 deletions
diff --git a/android_webview/java/src/org/chromium/android_webview/AwContents.java b/android_webview/java/src/org/chromium/android_webview/AwContents.java index 8ecc734..2352b57 100644 --- a/android_webview/java/src/org/chromium/android_webview/AwContents.java +++ b/android_webview/java/src/org/chromium/android_webview/AwContents.java @@ -925,28 +925,28 @@ public class AwContents implements SmartClipProvider, } } private static WindowAndroidWrapper sCachedWindowAndroid; - private static WeakHashMap<Activity, WindowAndroidWrapper> sActivityWindowMap; + private static WeakHashMap<Context, WindowAndroidWrapper> sActivityContextWindowMap; // getWindowAndroid is only called on UI thread, so there are no threading issues with lazy // initialization. @SuppressFBWarnings("LI_LAZY_INIT_STATIC") private static WindowAndroidWrapper getWindowAndroid(Context context) { // TODO(boliu): WebView does not currently initialize ApplicationStatus, crbug.com/470582. - Activity activity = ContentViewCore.activityFromContext(context); - if (activity == null) { + boolean contextWrapsActivity = activityFromContext(context) != null; + if (!contextWrapsActivity) { if (sCachedWindowAndroid == null) { sCachedWindowAndroid = new WindowAndroidWrapper(new WindowAndroid(context)); } return sCachedWindowAndroid; } - if (sActivityWindowMap == null) sActivityWindowMap = new WeakHashMap<>(); - WindowAndroidWrapper activityWindowAndroid = sActivityWindowMap.get(activity); + if (sActivityContextWindowMap == null) sActivityContextWindowMap = new WeakHashMap<>(); + WindowAndroidWrapper activityWindowAndroid = sActivityContextWindowMap.get(context); if (activityWindowAndroid == null) { final boolean listenToActivityState = false; activityWindowAndroid = new WindowAndroidWrapper( - new ActivityWindowAndroid(activity, listenToActivityState)); - sActivityWindowMap.put(activity, activityWindowAndroid); + new ActivityWindowAndroid(context, listenToActivityState)); + sActivityContextWindowMap.put(context, activityWindowAndroid); } return activityWindowAndroid; } @@ -1208,7 +1208,7 @@ public class AwContents implements SmartClipProvider, } public static Activity activityFromContext(Context context) { - return ContentViewCore.activityFromContext(context); + return WindowAndroid.activityFromContext(context); } /** * Disables contents of JS-to-Java bridge objects to be inspectable using @@ -2256,7 +2256,7 @@ public class AwContents implements SmartClipProvider, intent.putExtra(Intent.EXTRA_PROCESS_TEXT_READONLY, true); } - if (ContentViewCore.activityFromContext(mContext) == null) { + if (WindowAndroid.activityFromContext(mContext) == null) { mContext.startActivity(intent); return; } diff --git a/components/web_contents_delegate_android/android/java/src/org/chromium/components/web_contents_delegate_android/ColorChooserAndroid.java b/components/web_contents_delegate_android/android/java/src/org/chromium/components/web_contents_delegate_android/ColorChooserAndroid.java index 207fee2..25f5f62 100644 --- a/components/web_contents_delegate_android/android/java/src/org/chromium/components/web_contents_delegate_android/ColorChooserAndroid.java +++ b/components/web_contents_delegate_android/android/java/src/org/chromium/components/web_contents_delegate_android/ColorChooserAndroid.java @@ -12,6 +12,7 @@ import org.chromium.content.browser.ContentViewCore; import org.chromium.ui.ColorPickerDialog; import org.chromium.ui.ColorSuggestion; import org.chromium.ui.OnColorChangedListener; +import org.chromium.ui.base.WindowAndroid; /** * ColorChooserAndroid communicates with the java ColorPickerDialog and the @@ -51,8 +52,11 @@ public class ColorChooserAndroid { ContentViewCore contentViewCore, int initialColor, ColorSuggestion[] suggestions) { + if (contentViewCore.getWindowAndroid() == null) return null; + Context windowContext = contentViewCore.getWindowAndroid().getContext().get(); + if (WindowAndroid.activityFromContext(windowContext) == null) return null; ColorChooserAndroid chooser = new ColorChooserAndroid(nativeColorChooserAndroid, - contentViewCore.getContext(), initialColor, suggestions); + windowContext, initialColor, suggestions); chooser.openColorChooser(); return chooser; } diff --git a/content/public/android/java/src/org/chromium/content/browser/ContentVideoView.java b/content/public/android/java/src/org/chromium/content/browser/ContentVideoView.java index 76db5cb..52e00d0 100644 --- a/content/public/android/java/src/org/chromium/content/browser/ContentVideoView.java +++ b/content/public/android/java/src/org/chromium/content/browser/ContentVideoView.java @@ -26,6 +26,7 @@ import org.chromium.base.Log; import org.chromium.base.ThreadUtils; import org.chromium.base.annotations.CalledByNative; import org.chromium.base.annotations.JNINamespace; +import org.chromium.ui.base.WindowAndroid; /** * This class implements accelerated fullscreen video playback using surface view. @@ -227,7 +228,7 @@ public class ContentVideoView extends FrameLayout mCurrentState = STATE_ERROR; - if (ContentViewCore.activityFromContext(getContext()) == null) { + if (WindowAndroid.activityFromContext(getContext()) == null) { Log.w(TAG, "Unable to show alert dialog because it requires an activity context"); return; } diff --git a/content/public/android/java/src/org/chromium/content/browser/ContentViewCore.java b/content/public/android/java/src/org/chromium/content/browser/ContentViewCore.java index b7bbcf4..7147b93 100644 --- a/content/public/android/java/src/org/chromium/content/browser/ContentViewCore.java +++ b/content/public/android/java/src/org/chromium/content/browser/ContentViewCore.java @@ -12,7 +12,6 @@ import android.app.assist.AssistStructure.ViewNode; import android.content.ClipboardManager; import android.content.ContentResolver; import android.content.Context; -import android.content.ContextWrapper; import android.content.Intent; import android.content.pm.PackageManager; import android.content.res.Configuration; @@ -433,22 +432,6 @@ public class ContentViewCore implements AccessibilityStateChangeListener, Screen public void onSmartClipDataExtracted(String text, String html, Rect clipRect); } - /** - * Cast from Context to Activity taking ContextWrapper into account. - */ - public static Activity activityFromContext(Context context) { - // Only retrieve the base context if the supplied context is a ContextWrapper but not - // an Activity, given that Activity is already a subclass of ContextWrapper. - if (context instanceof Activity) { - return ((Activity) context); - } else if (context instanceof ContextWrapper) { - context = ((ContextWrapper) context).getBaseContext(); - return activityFromContext(context); - } else { - return null; - } - } - private final Context mContext; private ViewGroup mContainerView; private InternalAccessDelegate mContainerViewInternals; diff --git a/ui/android/java/src/org/chromium/ui/base/ActivityWindowAndroid.java b/ui/android/java/src/org/chromium/ui/base/ActivityWindowAndroid.java index 615b0ab..3993815 100644 --- a/ui/android/java/src/org/chromium/ui/base/ActivityWindowAndroid.java +++ b/ui/android/java/src/org/chromium/ui/base/ActivityWindowAndroid.java @@ -7,6 +7,7 @@ package org.chromium.ui.base; import android.app.Activity; import android.app.PendingIntent; import android.content.ActivityNotFoundException; +import android.content.Context; import android.content.Intent; import android.content.IntentSender.SendIntentException; import android.content.SharedPreferences; @@ -52,8 +53,8 @@ public class ActivityWindowAndroid * indicate their activity state listening preference. * @param activity The activity associated with the WindowAndroid. */ - public ActivityWindowAndroid(Activity activity) { - this(activity, true); + public ActivityWindowAndroid(Context context) { + this(context, true); } /** @@ -61,8 +62,12 @@ public class ActivityWindowAndroid * @param activity The activity associated with the WindowAndroid. * @param listenToActivityState Whether to listen to activity state changes. */ - public ActivityWindowAndroid(Activity activity, boolean listenToActivityState) { - super(activity); + public ActivityWindowAndroid(Context context, boolean listenToActivityState) { + super(context); + Activity activity = activityFromContext(context); + if (activity == null) { + throw new IllegalArgumentException("Context is not and does not wrap an Activity"); + } mHandler = new Handler(); mOutstandingPermissionRequests = new SparseArray<PermissionCallback>(); if (listenToActivityState) { @@ -207,7 +212,7 @@ public class ActivityWindowAndroid @Override public WeakReference<Activity> getActivity() { - return new WeakReference<Activity>((Activity) getContext().get()); + return new WeakReference<Activity>(activityFromContext(getContext().get())); } @Override diff --git a/ui/android/java/src/org/chromium/ui/base/WindowAndroid.java b/ui/android/java/src/org/chromium/ui/base/WindowAndroid.java index 658d0be..25951fb 100644 --- a/ui/android/java/src/org/chromium/ui/base/WindowAndroid.java +++ b/ui/android/java/src/org/chromium/ui/base/WindowAndroid.java @@ -12,6 +12,7 @@ import android.app.Activity; import android.app.PendingIntent; import android.content.ContentResolver; import android.content.Context; +import android.content.ContextWrapper; import android.content.Intent; import android.content.pm.PackageManager; import android.os.Build; @@ -125,6 +126,24 @@ public class WindowAndroid { }; /** + * Extract the activity if the given Context either is or wraps one. + * Only retrieve the base context if the supplied context is a {@link ContextWrapper} but not + * an Activity, given that Activity is already a subclass of ContextWrapper. + * @param context The context to check. + * @return The {@link Activity} that is extracted through the given Context. + */ + public static Activity activityFromContext(Context context) { + if (context instanceof Activity) { + return ((Activity) context); + } else if (context instanceof ContextWrapper) { + context = ((ContextWrapper) context).getBaseContext(); + return activityFromContext(context); + } else { + return null; + } + } + + /** * @return true if onVSync handler is executing. * * @see org.chromium.ui.VSyncMonitor#isInsideVSync() |