1 /*
2  * Copyright (C) 2017 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 com.android.settings.webview;
18 
19 import android.content.Context;
20 import android.content.pm.ApplicationInfo;
21 import android.content.pm.PackageInfo;
22 import android.content.pm.PackageManager;
23 import android.util.Log;
24 import android.webkit.IWebViewUpdateService;
25 import android.webkit.UserPackage;
26 import android.webkit.WebViewFactory;
27 import android.webkit.WebViewProviderInfo;
28 import android.webkit.WebViewUpdateManager;
29 import android.widget.Toast;
30 
31 import androidx.annotation.Nullable;
32 
33 import java.util.ArrayList;
34 import java.util.List;
35 
36 public class WebViewUpdateServiceWrapper {
37     private static final String TAG = "WVUSWrapper";
38 
WebViewUpdateServiceWrapper()39     public WebViewUpdateServiceWrapper() {
40     }
41 
42     /**
43      * Fetch the package currently used as WebView implementation.
44      */
getCurrentWebViewPackage()45     public PackageInfo getCurrentWebViewPackage() {
46         try {
47             if (android.webkit.Flags.updateServiceIpcWrapper()) {
48                 return WebViewUpdateManager.getInstance().getCurrentWebViewPackage();
49             } else {
50                 return WebViewFactory.getUpdateService().getCurrentWebViewPackage();
51             }
52         } catch (Exception e) {
53             Log.e(TAG, e.toString());
54         }
55         return null;
56     }
57 
58     /**
59      * Fetches ApplicationInfo objects for all currently valid WebView packages.
60      * A WebView package is considered valid if it can be used as a WebView implementation. The
61      * validity of a package is not dependent on whether the package is installed/enabled.
62      */
getValidWebViewApplicationInfos(Context context)63     public List<ApplicationInfo> getValidWebViewApplicationInfos(Context context) {
64         WebViewProviderInfo[] providers = null;
65         try {
66             if (android.webkit.Flags.updateServiceIpcWrapper()) {
67                 providers = context.getSystemService(WebViewUpdateManager.class)
68                         .getValidWebViewPackages();
69             } else {
70                 providers = WebViewFactory.getUpdateService().getValidWebViewPackages();
71             }
72         } catch (Exception e) {
73         }
74         List<ApplicationInfo> pkgs = new ArrayList<>();
75         for (WebViewProviderInfo provider : providers) {
76             try {
77                 pkgs.add(context.getPackageManager().getApplicationInfo(
78                         provider.packageName, PACKAGE_FLAGS));
79             } catch (PackageManager.NameNotFoundException e) {
80             }
81         }
82         return pkgs;
83     }
84 
85     /**
86      * Change WebView provider to {@param packageName}.
87      *
88      * @return whether the change succeeded.
89      */
setWebViewProvider(String packageName)90     public boolean setWebViewProvider(String packageName) {
91         try {
92             if (android.webkit.Flags.updateServiceIpcWrapper()) {
93                 return packageName.equals(
94                         WebViewUpdateManager.getInstance().changeProviderAndSetting(packageName));
95             } else {
96                 return packageName.equals(
97                         WebViewFactory.getUpdateService().changeProviderAndSetting(packageName));
98             }
99         } catch (Exception e) {
100             Log.e(TAG, "Exception when trying to change provider to " + packageName, e);
101         }
102         return false;
103     }
104 
105     /**
106      * Fetch PackageInfos for the package named {@param packageName} for all users on the device.
107      */
getPackageInfosAllUsers(Context context, String packageName)108     public List<UserPackage> getPackageInfosAllUsers(Context context, String packageName) {
109         return UserPackage.getPackageInfosAllUsers(context, packageName, PACKAGE_FLAGS);
110     }
111 
112     /**
113      * Show a toast to explain the chosen package can no longer be chosen.
114      */
showInvalidChoiceToast(Context context)115     public void showInvalidChoiceToast(Context context) {
116         // The user chose a package that became invalid since the list was last updated,
117         // show a Toast to explain the situation.
118         Toast toast = Toast.makeText(context,
119                 com.android.settingslib.R.string.select_webview_provider_toast_text,
120                 Toast.LENGTH_SHORT);
121         toast.show();
122     }
123 
124     /**
125      * Fetch the package name of the default WebView provider.
126      */
127     @Nullable
getDefaultWebViewPackageName()128     public String getDefaultWebViewPackageName() {
129         WebViewProviderInfo provider = null;
130         try {
131             if (android.webkit.Flags.updateServiceIpcWrapper()) {
132                 WebViewUpdateManager manager = WebViewUpdateManager.getInstance();
133                 if (manager != null) {
134                     provider = manager.getDefaultWebViewPackage();
135                 }
136             } else {
137                 IWebViewUpdateService service = WebViewFactory.getUpdateService();
138                 if (service != null) {
139                     provider = service.getDefaultWebViewPackage();
140                 }
141             }
142         } catch (Exception e) {
143             Log.e(TAG, "Exception when trying to fetch default WebView package Name", e);
144         }
145         return provider != null ? provider.packageName : null;
146     }
147 
148     static final int PACKAGE_FLAGS = PackageManager.MATCH_ANY_USER;
149 }
150