Index: android_webview/glue/java/src/com/android/webview/chromium/WebViewChromiumFactoryProvider.java |
diff --git a/android_webview/glue/java/src/com/android/webview/chromium/WebViewChromiumFactoryProvider.java b/android_webview/glue/java/src/com/android/webview/chromium/WebViewChromiumFactoryProvider.java |
index 2ef597bfab1af55fa202d279a6c2850544ddf6dd..11795ad21c7f4f24db483815af791998bf524e90 100644 |
--- a/android_webview/glue/java/src/com/android/webview/chromium/WebViewChromiumFactoryProvider.java |
+++ b/android_webview/glue/java/src/com/android/webview/chromium/WebViewChromiumFactoryProvider.java |
@@ -10,6 +10,7 @@ import android.content.ComponentCallbacks2; |
import android.content.Context; |
import android.content.Intent; |
import android.content.SharedPreferences; |
+import android.content.pm.ApplicationInfo; |
import android.content.pm.PackageInfo; |
import android.content.pm.PackageManager; |
import android.content.pm.PackageManager.NameNotFoundException; |
@@ -66,6 +67,7 @@ import org.chromium.net.NetworkChangeNotifier; |
import org.chromium.ui.base.ResourceBundle; |
import java.io.File; |
+import java.lang.reflect.InvocationTargetException; |
import java.util.Queue; |
import java.util.concurrent.Callable; |
import java.util.concurrent.ConcurrentLinkedQueue; |
@@ -199,12 +201,11 @@ public class WebViewChromiumFactoryProvider implements WebViewFactoryProvider { |
private void initialize(WebViewDelegate webViewDelegate) { |
mWebViewDelegate = webViewDelegate; |
- checkStorageIsNotDeviceProtected(mWebViewDelegate.getApplication()); |
+ Context ctx = switchToCredentialProtectedStorage( |
+ mWebViewDelegate.getApplication().getApplicationContext()); |
// WebView needs to make sure to always use the wrapped application context. |
- ContextUtils.initApplicationContext( |
- ResourcesContextWrapperFactory.get( |
- mWebViewDelegate.getApplication().getApplicationContext())); |
+ ContextUtils.initApplicationContext(ResourcesContextWrapperFactory.get(ctx)); |
if (isBuildDebuggable()) { |
// Suppress the StrictMode violation as this codepath is only hit on debuggable builds. |
@@ -253,12 +254,38 @@ public class WebViewChromiumFactoryProvider implements WebViewFactoryProvider { |
// Now safe to use WebView data directory. |
} |
- static void checkStorageIsNotDeviceProtected(Context context) { |
+ // Webview must use a CredentialEncrypted Context. If context is a CE context, then simply |
+ // return it without modification. Otherwise, create a new CE context and return that instead. |
+ static Context switchToCredentialProtectedStorage(Context context) { |
+ // For versions N+, android webview must use a CredentialEncrypted Context |
if ((Build.VERSION.CODENAME.equals("N") || Build.VERSION.SDK_INT > Build.VERSION_CODES.M) |
&& context.isDeviceProtectedStorage()) { |
- throw new IllegalArgumentException( |
- "WebView cannot be used with device protected storage"); |
+ ApplicationInfo appInfo = context.getApplicationInfo(); |
+ try { |
+ // Check the manifest flag android:defaultToDeviceProtectedStorage |
Torne
2016/09/21 12:04:18
I'm not sure there's any point in actually checkin
Nate Fischer
2016/09/22 04:21:12
Ok, I misunderstood the bug report. I've removed t
|
+ boolean defaultsToDeviceProtection = |
+ (Boolean) appInfo.getClass() |
+ .getMethod("isDefaultToDeviceProtectedStorage") |
+ .invoke(appInfo); |
+ // For system applications using the flag, attempt to use a CE context if it's |
+ // available |
+ if (defaultsToDeviceProtection) { |
+ context = context.createCredentialProtectedStorageContext(); |
+ } |
+ |
+ // If this application does not default to DE storage, or we were unable to create a |
+ // CE context |
+ if (context.isDeviceProtectedStorage()) { |
+ throw new IllegalArgumentException( |
+ "WebView cannot be used with device protected storage"); |
+ } |
+ } catch (NoSuchMethodException | InvocationTargetException | IllegalAccessException |
+ | IllegalArgumentException e) { |
+ throw new IllegalArgumentException( |
+ "WebView cannot be used with device protected storage"); |
+ } |
} |
+ return context; |
} |
private static boolean isBuildDebuggable() { |