1 /* 2 * Copyright (C) 2014 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.webkit; 18 19 import android.annotation.NonNull; 20 import android.annotation.Nullable; 21 import android.annotation.SystemApi; 22 import android.app.ActivityThread; 23 import android.app.Application; 24 import android.app.ResourcesManager; 25 import android.content.Context; 26 import android.content.pm.ApplicationInfo; 27 import android.content.res.Resources; 28 import android.graphics.Canvas; 29 import android.os.SystemProperties; 30 import android.os.Trace; 31 import android.util.SparseArray; 32 import android.view.DisplayListCanvas; 33 import android.view.View; 34 import android.view.ViewRootImpl; 35 36 import com.android.internal.util.ArrayUtils; 37 38 /** 39 * Delegate used by the WebView provider implementation to access 40 * the required framework functionality needed to implement a {@link WebView}. 41 * 42 * @hide 43 */ 44 @SystemApi 45 public final class WebViewDelegate { 46 47 /* package */ WebViewDelegate() { } 48 49 /** 50 * Listener that gets notified whenever tracing has been enabled/disabled. 51 */ 52 public interface OnTraceEnabledChangeListener { 53 void onTraceEnabledChange(boolean enabled); 54 } 55 56 /** 57 * Register a callback to be invoked when tracing for the WebView component has been 58 * enabled/disabled. 59 */ 60 public void setOnTraceEnabledChangeListener(final OnTraceEnabledChangeListener listener) { 61 SystemProperties.addChangeCallback(new Runnable() { 62 @Override 63 public void run() { 64 listener.onTraceEnabledChange(isTraceTagEnabled()); 65 } 66 }); 67 } 68 69 /** 70 * Returns true if the WebView trace tag is enabled and false otherwise. 71 */ 72 public boolean isTraceTagEnabled() { 73 return Trace.isTagEnabled(Trace.TRACE_TAG_WEBVIEW); 74 } 75 76 /** 77 * Returns true if the draw GL functor can be invoked (see {@link #invokeDrawGlFunctor}) 78 * and false otherwise. 79 */ 80 public boolean canInvokeDrawGlFunctor(View containerView) { 81 return true; 82 } 83 84 /** 85 * Invokes the draw GL functor. If waitForCompletion is false the functor 86 * may be invoked asynchronously. 87 * 88 * @param nativeDrawGLFunctor the pointer to the native functor that implements 89 * system/core/include/utils/Functor.h 90 */ 91 public void invokeDrawGlFunctor(View containerView, long nativeDrawGLFunctor, 92 boolean waitForCompletion) { 93 ViewRootImpl.invokeFunctor(nativeDrawGLFunctor, waitForCompletion); 94 } 95 96 /** 97 * Calls the function specified with the nativeDrawGLFunctor functor pointer. This 98 * functionality is used by the WebView for calling into their renderer from the 99 * framework display lists. 100 * 101 * @param canvas a hardware accelerated canvas (see {@link Canvas#isHardwareAccelerated()}) 102 * @param nativeDrawGLFunctor the pointer to the native functor that implements 103 * system/core/include/utils/Functor.h 104 * @throws IllegalArgumentException if the canvas is not hardware accelerated 105 */ 106 public void callDrawGlFunction(Canvas canvas, long nativeDrawGLFunctor) { 107 if (!(canvas instanceof DisplayListCanvas)) { 108 // Canvas#isHardwareAccelerated() is only true for subclasses of HardwareCanvas. 109 throw new IllegalArgumentException(canvas.getClass().getName() 110 + " is not a DisplayList canvas"); 111 } 112 ((DisplayListCanvas) canvas).drawGLFunctor2(nativeDrawGLFunctor, null); 113 } 114 115 /** 116 * Calls the function specified with the nativeDrawGLFunctor functor pointer. This 117 * functionality is used by the WebView for calling into their renderer from the 118 * framework display lists. 119 * 120 * @param canvas a hardware accelerated canvas (see {@link Canvas#isHardwareAccelerated()}) 121 * @param nativeDrawGLFunctor the pointer to the native functor that implements 122 * system/core/include/utils/Functor.h 123 * @param releasedRunnable Called when this nativeDrawGLFunctor is no longer referenced by this 124 * canvas, so is safe to be destroyed. 125 * @throws IllegalArgumentException if the canvas is not hardware accelerated 126 */ 127 public void callDrawGlFunction(@NonNull Canvas canvas, long nativeDrawGLFunctor, 128 @Nullable Runnable releasedRunnable) { 129 if (!(canvas instanceof DisplayListCanvas)) { 130 // Canvas#isHardwareAccelerated() is only true for subclasses of HardwareCanvas. 131 throw new IllegalArgumentException(canvas.getClass().getName() 132 + " is not a DisplayList canvas"); 133 } 134 ((DisplayListCanvas) canvas).drawGLFunctor2(nativeDrawGLFunctor, releasedRunnable); 135 } 136 137 /** 138 * Detaches the draw GL functor. 139 * 140 * @param nativeDrawGLFunctor the pointer to the native functor that implements 141 * system/core/include/utils/Functor.h 142 */ 143 public void detachDrawGlFunctor(View containerView, long nativeDrawGLFunctor) { 144 ViewRootImpl viewRootImpl = containerView.getViewRootImpl(); 145 if (nativeDrawGLFunctor != 0 && viewRootImpl != null) { 146 viewRootImpl.detachFunctor(nativeDrawGLFunctor); 147 } 148 } 149 150 /** 151 * Returns the package id of the given {@code packageName}. 152 */ 153 public int getPackageId(Resources resources, String packageName) { 154 SparseArray<String> packageIdentifiers = 155 resources.getAssets().getAssignedPackageIdentifiers(); 156 for (int i = 0; i < packageIdentifiers.size(); i++) { 157 final String name = packageIdentifiers.valueAt(i); 158 159 if (packageName.equals(name)) { 160 return packageIdentifiers.keyAt(i); 161 } 162 } 163 throw new RuntimeException("Package not found: " + packageName); 164 } 165 166 /** 167 * Returns the application which is embedding the WebView. 168 */ 169 public Application getApplication() { 170 return ActivityThread.currentApplication(); 171 } 172 173 /** 174 * Returns the error string for the given {@code errorCode}. 175 */ 176 public String getErrorString(Context context, int errorCode) { 177 return LegacyErrorStrings.getString(errorCode, context); 178 } 179 180 /** 181 * Adds the WebView asset path to {@link android.content.res.AssetManager}. 182 */ 183 public void addWebViewAssetPath(Context context) { 184 final String newAssetPath = WebViewFactory.getLoadedPackageInfo().applicationInfo.sourceDir; 185 186 final ApplicationInfo appInfo = context.getApplicationInfo(); 187 final String[] libs = appInfo.sharedLibraryFiles; 188 if (!ArrayUtils.contains(libs, newAssetPath)) { 189 // Build the new library asset path list. 190 final int newLibAssetsCount = 1 + (libs != null ? libs.length : 0); 191 final String[] newLibAssets = new String[newLibAssetsCount]; 192 if (libs != null) { 193 System.arraycopy(libs, 0, newLibAssets, 0, libs.length); 194 } 195 newLibAssets[newLibAssetsCount - 1] = newAssetPath; 196 197 // Update the ApplicationInfo object with the new list. 198 // We know this will persist and future Resources created via ResourcesManager 199 // will include the shared library because this ApplicationInfo comes from the 200 // underlying LoadedApk in ContextImpl, which does not change during the life of the 201 // application. 202 appInfo.sharedLibraryFiles = newLibAssets; 203 204 // Update existing Resources with the WebView library. 205 ResourcesManager.getInstance().appendLibAssetForMainAssetPath( 206 appInfo.getBaseResourcePath(), newAssetPath); 207 } 208 } 209 } 210