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