1 /* 2 * Copyright (C) 2010 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 package android.cts.util; 18 19 import android.content.Context; 20 import android.content.pm.PackageManager; 21 22 /** 23 * Utilities to enable the android.webkit.* CTS tests (and others that rely on a functioning 24 * android.webkit.WebView implementation) to determine whether a functioning WebView is present 25 * on the device or not. 26 * 27 * Test cases that require android.webkit.* classes should wrap their first usage of WebView in a 28 * try catch block, and pass any exception that is thrown to 29 * NullWebViewUtils.determineIfWebViewAvailable. The return value of 30 * NullWebViewUtils.isWebViewAvailable will then determine if the test should expect to be able to 31 * use a WebView. 32 */ 33 public class NullWebViewUtils { 34 35 private static boolean sWebViewUnavailable; 36 37 /** 38 * @param context Current Activity context, used to query the PackageManager. 39 * @param t An exception thrown by trying to invoke android.webkit.* APIs. 40 */ determineIfWebViewAvailable(Context context, Throwable t)41 public static void determineIfWebViewAvailable(Context context, Throwable t) { 42 sWebViewUnavailable = !hasWebViewFeature(context) && checkCauseWasUnsupportedOperation(t); 43 } 44 45 /** 46 * After calling determineIfWebViewAvailable, this returns whether a WebView is available on the 47 * device and wheter the test can rely on it. 48 * @return True iff. PackageManager determined that there is no WebView on the device and the 49 * exception thrown from android.webkit.* was UnsupportedOperationException. 50 */ isWebViewAvailable()51 public static boolean isWebViewAvailable() { 52 return !sWebViewUnavailable; 53 } 54 hasWebViewFeature(Context context)55 private static boolean hasWebViewFeature(Context context) { 56 // Query the system property that determins if there is a functional WebView on the device. 57 PackageManager pm = context.getPackageManager(); 58 return pm.hasSystemFeature(PackageManager.FEATURE_WEBVIEW); 59 } 60 checkCauseWasUnsupportedOperation(Throwable t)61 private static boolean checkCauseWasUnsupportedOperation(Throwable t) { 62 if (t == null) return false; 63 while (t.getCause() != null) { 64 t = t.getCause(); 65 } 66 return t instanceof UnsupportedOperationException; 67 } 68 69 /** 70 * Some CTS tests (by design) first use android.webkit.* from a background thread. This helper 71 * allows the test to catch the UnsupportedOperationException from that background thread, and 72 * then query the result from the test main thread. 73 */ 74 public static class NullWebViewFromThreadExceptionHandler 75 implements Thread.UncaughtExceptionHandler { 76 private Throwable mPendingException; 77 78 @Override uncaughtException(Thread t, Throwable e)79 public void uncaughtException(Thread t, Throwable e) { 80 mPendingException = e; 81 } 82 isWebViewAvailable(Context context)83 public boolean isWebViewAvailable(Context context) { 84 return hasWebViewFeature(context) || 85 !checkCauseWasUnsupportedOperation(mPendingException); 86 } 87 } 88 }