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.compat.annotation.UnsupportedAppUsage; 26 import android.content.Context; 27 import android.content.pm.ApplicationInfo; 28 import android.content.res.Resources; 29 import android.graphics.Canvas; 30 import android.graphics.RecordingCanvas; 31 import android.os.SystemProperties; 32 import android.os.Trace; 33 import android.util.SparseArray; 34 import android.view.View; 35 import android.view.ViewRootImpl; 36 37 import com.android.internal.util.ArrayUtils; 38 39 /** 40 * Delegate used by the WebView provider implementation to access 41 * the required framework functionality needed to implement a {@link WebView}. 42 * 43 * @hide 44 */ 45 @SystemApi 46 public final class WebViewDelegate { 47 48 @UnsupportedAppUsage WebViewDelegate()49 /* package */ WebViewDelegate() { } 50 51 /** 52 * Listener that gets notified whenever tracing has been enabled/disabled. 53 */ 54 public interface OnTraceEnabledChangeListener { onTraceEnabledChange(boolean enabled)55 void onTraceEnabledChange(boolean enabled); 56 } 57 58 /** 59 * Register a callback to be invoked when tracing for the WebView component has been 60 * enabled/disabled. 61 */ setOnTraceEnabledChangeListener(final OnTraceEnabledChangeListener listener)62 public void setOnTraceEnabledChangeListener(final OnTraceEnabledChangeListener listener) { 63 SystemProperties.addChangeCallback(new Runnable() { 64 @Override 65 public void run() { 66 listener.onTraceEnabledChange(isTraceTagEnabled()); 67 } 68 }); 69 } 70 71 /** 72 * Returns {@code true} if the WebView trace tag is enabled and {@code false} otherwise. 73 */ isTraceTagEnabled()74 public boolean isTraceTagEnabled() { 75 return Trace.isTagEnabled(Trace.TRACE_TAG_WEBVIEW); 76 } 77 78 /** 79 * Throws {@link UnsupportedOperationException} 80 * @deprecated Use {@link #drawWebViewFunctor(Canvas, int)} 81 */ 82 @Deprecated canInvokeDrawGlFunctor(View containerView)83 public boolean canInvokeDrawGlFunctor(View containerView) { 84 throw new UnsupportedOperationException(); 85 } 86 87 /** 88 * Throws {@link UnsupportedOperationException} 89 * @deprecated Use {@link #drawWebViewFunctor(Canvas, int)} 90 */ 91 @Deprecated invokeDrawGlFunctor(View containerView, long nativeDrawGLFunctor, boolean waitForCompletion)92 public void invokeDrawGlFunctor(View containerView, long nativeDrawGLFunctor, 93 boolean waitForCompletion) { 94 throw new UnsupportedOperationException(); 95 } 96 97 /** 98 * Throws {@link UnsupportedOperationException} 99 * @deprecated Use {@link #drawWebViewFunctor(Canvas, int)} 100 */ 101 @Deprecated callDrawGlFunction(Canvas canvas, long nativeDrawGLFunctor)102 public void callDrawGlFunction(Canvas canvas, long nativeDrawGLFunctor) { 103 throw new UnsupportedOperationException(); 104 } 105 106 /** 107 * Throws {@link UnsupportedOperationException} 108 * @deprecated Use {@link #drawWebViewFunctor(Canvas, int)} 109 */ 110 @Deprecated callDrawGlFunction(@onNull Canvas canvas, long nativeDrawGLFunctor, @Nullable Runnable releasedRunnable)111 public void callDrawGlFunction(@NonNull Canvas canvas, long nativeDrawGLFunctor, 112 @Nullable Runnable releasedRunnable) { 113 throw new UnsupportedOperationException(); 114 } 115 116 /** 117 * Call webview draw functor. See API in draw_fn.h. 118 * @param canvas a {@link RecordingCanvas}. 119 * @param functor created by AwDrawFn_CreateFunctor in draw_fn.h. 120 */ drawWebViewFunctor(@onNull Canvas canvas, int functor)121 public void drawWebViewFunctor(@NonNull Canvas canvas, int functor) { 122 if (!(canvas instanceof RecordingCanvas)) { 123 // Canvas#isHardwareAccelerated() is only true for subclasses of RecordingCanvas. 124 throw new IllegalArgumentException(canvas.getClass().getName() 125 + " is not a RecordingCanvas canvas"); 126 } 127 ((RecordingCanvas) canvas).drawWebViewFunctor(functor); 128 } 129 130 /** 131 * Detaches the draw GL functor. 132 * 133 * @param nativeDrawGLFunctor the pointer to the native functor that implements 134 * system/core/include/utils/Functor.h 135 * @deprecated Use {@link #drawWebViewFunctor(Canvas, int)} 136 */ 137 @Deprecated detachDrawGlFunctor(View containerView, long nativeDrawGLFunctor)138 public void detachDrawGlFunctor(View containerView, long nativeDrawGLFunctor) { 139 if (Flags.mainlineApis()) { 140 throw new UnsupportedOperationException(); 141 } else { 142 ViewRootImpl viewRootImpl = containerView.getViewRootImpl(); 143 if (nativeDrawGLFunctor != 0 && viewRootImpl != null) { 144 viewRootImpl.detachFunctor(nativeDrawGLFunctor); 145 } 146 } 147 } 148 149 /** 150 * Returns the package id of the given {@code packageName}. 151 */ getPackageId(Resources resources, String packageName)152 public int getPackageId(Resources resources, String packageName) { 153 SparseArray<String> packageIdentifiers = 154 resources.getAssets().getAssignedPackageIdentifiers(); 155 for (int i = 0; i < packageIdentifiers.size(); i++) { 156 final String name = packageIdentifiers.valueAt(i); 157 158 if (packageName.equals(name)) { 159 return packageIdentifiers.keyAt(i); 160 } 161 } 162 throw new RuntimeException("Package not found: " + packageName); 163 } 164 165 /** 166 * Returns the application which is embedding the WebView. 167 */ getApplication()168 public Application getApplication() { 169 return ActivityThread.currentApplication(); 170 } 171 172 /** 173 * Returns the error string for the given {@code errorCode}. 174 */ getErrorString(Context context, int errorCode)175 public String getErrorString(Context context, int errorCode) { 176 return LegacyErrorStrings.getString(errorCode, context); 177 } 178 179 /** 180 * Adds the WebView asset path to {@link android.content.res.AssetManager}. 181 * If {@link android.content.res.Flags#FLAG_REGISTER_RESOURCE_PATHS} is enabled, this function 182 * will be a no-op because the asset paths appending work will only be handled by 183 * {@link android.content.res.Resources#registerResourcePaths(String, ApplicationInfo)}, 184 * otherwise it behaves the old way. 185 */ addWebViewAssetPath(Context context)186 public void addWebViewAssetPath(Context context) { 187 if (android.content.res.Flags.registerResourcePaths()) { 188 return; 189 } 190 191 final String[] newAssetPaths = 192 WebViewFactory.getLoadedPackageInfo().applicationInfo.getAllApkPaths(); 193 final ApplicationInfo appInfo = context.getApplicationInfo(); 194 195 // Build the new library asset path list. 196 String[] newLibAssets = appInfo.sharedLibraryFiles; 197 for (String newAssetPath : newAssetPaths) { 198 newLibAssets = ArrayUtils.appendElement(String.class, newLibAssets, newAssetPath); 199 } 200 201 if (newLibAssets != appInfo.sharedLibraryFiles) { 202 // Update the ApplicationInfo object with the new list. 203 // We know this will persist and future Resources created via ResourcesManager 204 // will include the shared library because this ApplicationInfo comes from the 205 // underlying LoadedApk in ContextImpl, which does not change during the life of the 206 // application. 207 appInfo.sharedLibraryFiles = newLibAssets; 208 209 // Update existing Resources with the WebView library. 210 ResourcesManager.getInstance().appendLibAssetsForMainAssetPath( 211 appInfo.getBaseResourcePath(), newAssetPaths); 212 } 213 } 214 215 /** 216 * Returns whether WebView should run in multiprocess mode. 217 */ isMultiProcessEnabled()218 public boolean isMultiProcessEnabled() { 219 return true; 220 } 221 222 /** 223 * Returns the data directory suffix to use, or null for none. 224 */ getDataDirectorySuffix()225 public String getDataDirectorySuffix() { 226 return WebViewFactory.getDataDirectorySuffix(); 227 } 228 229 /** 230 * Get the timestamps at which various WebView startup events occurred in this process. 231 * This method must be called on the same thread where the 232 * WebViewChromiumFactoryProvider#create method was invoked. 233 */ 234 @NonNull getStartupTimestamps()235 public WebViewFactory.StartupTimestamps getStartupTimestamps() { 236 return WebViewFactory.getStartupTimestamps(); 237 } 238 } 239