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
17package android.webkit;
18
19import android.annotation.SystemApi;
20import android.app.ActivityThread;
21import android.app.Application;
22import android.content.Context;
23import android.content.res.Resources;
24import android.graphics.Canvas;
25import android.os.SystemProperties;
26import android.os.Trace;
27import android.util.SparseArray;
28import android.view.DisplayListCanvas;
29import android.view.View;
30import android.view.ViewRootImpl;
31
32/**
33 * Delegate used by the WebView provider implementation to access
34 * the required framework functionality needed to implement a {@link WebView}.
35 *
36 * @hide
37 */
38@SystemApi
39public final class WebViewDelegate {
40
41    /* package */ WebViewDelegate() { }
42
43    /**
44     * Listener that gets notified whenever tracing has been enabled/disabled.
45     */
46    public interface OnTraceEnabledChangeListener {
47        void onTraceEnabledChange(boolean enabled);
48    }
49
50    /**
51     * Register a callback to be invoked when tracing for the WebView component has been
52     * enabled/disabled.
53     */
54    public void setOnTraceEnabledChangeListener(final OnTraceEnabledChangeListener listener) {
55        SystemProperties.addChangeCallback(new Runnable() {
56            @Override
57            public void run() {
58                listener.onTraceEnabledChange(isTraceTagEnabled());
59            }
60        });
61    }
62
63    /**
64     * Returns true if the WebView trace tag is enabled and false otherwise.
65     */
66    public boolean isTraceTagEnabled() {
67        return Trace.isTagEnabled(Trace.TRACE_TAG_WEBVIEW);
68    }
69
70    /**
71     * Returns true if the draw GL functor can be invoked (see {@link #invokeDrawGlFunctor})
72     * and false otherwise.
73     */
74    public boolean canInvokeDrawGlFunctor(View containerView) {
75        ViewRootImpl viewRootImpl = containerView.getViewRootImpl();
76         // viewRootImpl can be null during teardown when window is leaked.
77        return viewRootImpl != null;
78    }
79
80    /**
81     * Invokes the draw GL functor. If waitForCompletion is false the functor
82     * may be invoked asynchronously.
83     *
84     * @param nativeDrawGLFunctor the pointer to the native functor that implements
85     *        system/core/include/utils/Functor.h
86     */
87    public void invokeDrawGlFunctor(View containerView, long nativeDrawGLFunctor,
88            boolean waitForCompletion) {
89        ViewRootImpl viewRootImpl = containerView.getViewRootImpl();
90        viewRootImpl.invokeFunctor(nativeDrawGLFunctor, waitForCompletion);
91    }
92
93    /**
94     * Calls the function specified with the nativeDrawGLFunctor functor pointer. This
95     * functionality is used by the WebView for calling into their renderer from the
96     * framework display lists.
97     *
98     * @param canvas a hardware accelerated canvas (see {@link Canvas#isHardwareAccelerated()})
99     * @param nativeDrawGLFunctor the pointer to the native functor that implements
100     *        system/core/include/utils/Functor.h
101     * @throws IllegalArgumentException if the canvas is not hardware accelerated
102     */
103    public void callDrawGlFunction(Canvas canvas, long nativeDrawGLFunctor) {
104        if (!(canvas instanceof DisplayListCanvas)) {
105            // Canvas#isHardwareAccelerated() is only true for subclasses of HardwareCanvas.
106            throw new IllegalArgumentException(canvas.getClass().getName()
107                    + " is not a DisplayList canvas");
108        }
109        ((DisplayListCanvas) canvas).callDrawGLFunction2(nativeDrawGLFunctor);
110    }
111
112    /**
113     * Detaches the draw GL functor.
114     *
115     * @param nativeDrawGLFunctor the pointer to the native functor that implements
116     *        system/core/include/utils/Functor.h
117     */
118    public void detachDrawGlFunctor(View containerView, long nativeDrawGLFunctor) {
119        ViewRootImpl viewRootImpl = containerView.getViewRootImpl();
120        if (nativeDrawGLFunctor != 0 && viewRootImpl != null) {
121            viewRootImpl.detachFunctor(nativeDrawGLFunctor);
122        }
123    }
124
125    /**
126     * Returns the package id of the given {@code packageName}.
127     */
128    public int getPackageId(Resources resources, String packageName) {
129        SparseArray<String> packageIdentifiers =
130                resources.getAssets().getAssignedPackageIdentifiers();
131        for (int i = 0; i < packageIdentifiers.size(); i++) {
132            final String name = packageIdentifiers.valueAt(i);
133
134            if (packageName.equals(name)) {
135                return packageIdentifiers.keyAt(i);
136            }
137        }
138        throw new RuntimeException("Package not found: " + packageName);
139    }
140
141    /**
142     * Returns the application which is embedding the WebView.
143     */
144    public Application getApplication() {
145        return ActivityThread.currentApplication();
146    }
147
148    /**
149     * Returns the error string for the given {@code errorCode}.
150     */
151    public String getErrorString(Context context, int errorCode) {
152        return LegacyErrorStrings.getString(errorCode, context);
153    }
154
155    /**
156     * Adds the WebView asset path to {@link android.content.res.AssetManager}.
157     */
158    public void addWebViewAssetPath(Context context) {
159        context.getAssets().addAssetPath(
160                WebViewFactory.getLoadedPackageInfo().applicationInfo.sourceDir);
161    }
162}
163