• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 static android.provider.Settings.ACTION_WEBVIEW_SETTINGS;
20 
21 import android.app.Activity;
22 import android.app.settings.SettingsEnums;
23 import android.content.Context;
24 import android.content.Intent;
25 import android.content.pm.ApplicationInfo;
26 import android.content.pm.PackageInfo;
27 import android.content.pm.PackageItemInfo;
28 import android.content.pm.PackageManager;
29 import android.os.UserManager;
30 import android.text.TextUtils;
31 import android.webkit.UserPackage;
32 
33 import androidx.annotation.VisibleForTesting;
34 
35 import com.android.settings.R;
36 import com.android.settings.applications.defaultapps.DefaultAppPickerFragment;
37 import com.android.settingslib.applications.DefaultAppInfo;
38 
39 import java.util.ArrayList;
40 import java.util.List;
41 
42 public class WebViewAppPicker extends DefaultAppPickerFragment {
43     private WebViewUpdateServiceWrapper mWebViewUpdateServiceWrapper;
44 
getWebViewUpdateServiceWrapper()45     private WebViewUpdateServiceWrapper getWebViewUpdateServiceWrapper() {
46         if (mWebViewUpdateServiceWrapper == null) {
47             setWebViewUpdateServiceWrapper(createDefaultWebViewUpdateServiceWrapper());
48         }
49         return mWebViewUpdateServiceWrapper;
50     }
51 
52     @Override
onAttach(Context context)53     public void onAttach(Context context) {
54         super.onAttach(context);
55 
56         if (!mUserManager.isAdminUser()) {
57             getActivity().finish();
58         }
59     }
60 
61     @Override
getPreferenceScreenResId()62     protected int getPreferenceScreenResId() {
63         return R.xml.webview_app_settings;
64     }
65 
66     @Override
getCandidates()67     protected List<DefaultAppInfo> getCandidates() {
68         final List<DefaultAppInfo> packageInfoList = new ArrayList<DefaultAppInfo>();
69         final Context context = getContext();
70         final WebViewUpdateServiceWrapper webViewUpdateService = getWebViewUpdateServiceWrapper();
71         final List<ApplicationInfo> pkgs =
72                 webViewUpdateService.getValidWebViewApplicationInfos(context);
73         for (ApplicationInfo ai : pkgs) {
74             packageInfoList.add(createDefaultAppInfo(context, mPm, ai,
75                     getDisabledReason(webViewUpdateService, context, ai.packageName)));
76         }
77         return packageInfoList;
78     }
79 
80     @Override
getDefaultKey()81     protected String getDefaultKey() {
82         PackageInfo currentPackage = getWebViewUpdateServiceWrapper().getCurrentWebViewPackage();
83         return currentPackage == null ? null : currentPackage.packageName;
84     }
85 
setDefaultKey(String key)86     protected boolean setDefaultKey(String key) {
87         boolean success = getWebViewUpdateServiceWrapper().setWebViewProvider(key);
88         return success;
89     }
90 
91     @Override
onSelectionPerformed(boolean success)92     protected void onSelectionPerformed(boolean success) {
93         if (success) {
94             Activity activity = getActivity();
95             Intent intent = activity == null ? null : activity.getIntent();
96             if (intent != null && ACTION_WEBVIEW_SETTINGS.equals(intent.getAction())) {
97                 // If this was started through ACTION_WEBVIEW_SETTINGS then return once we have
98                 // chosen a new package.
99                 getActivity().finish();
100             }
101         } else {
102             getWebViewUpdateServiceWrapper().showInvalidChoiceToast(getActivity());
103             updateCandidates();
104         }
105     }
106 
createDefaultWebViewUpdateServiceWrapper()107     private WebViewUpdateServiceWrapper createDefaultWebViewUpdateServiceWrapper() {
108         return new WebViewUpdateServiceWrapper();
109     }
110 
111     @VisibleForTesting
setWebViewUpdateServiceWrapper(WebViewUpdateServiceWrapper wvusWrapper)112     void setWebViewUpdateServiceWrapper(WebViewUpdateServiceWrapper wvusWrapper) {
113         mWebViewUpdateServiceWrapper = wvusWrapper;
114     }
115 
116     @Override
getMetricsCategory()117     public int getMetricsCategory() {
118         return SettingsEnums.WEBVIEW_IMPLEMENTATION;
119     }
120 
121     private static class WebViewAppInfo extends DefaultAppInfo {
WebViewAppInfo(Context context, PackageManager pm, int userId, PackageItemInfo packageItemInfo, String summary, boolean enabled)122         public WebViewAppInfo(Context context, PackageManager pm, int userId,
123                 PackageItemInfo packageItemInfo, String summary, boolean enabled) {
124             super(context, pm, userId, packageItemInfo, summary, enabled);
125         }
126 
127         @Override
loadLabel()128         public CharSequence loadLabel() {
129             String versionName = "";
130             try {
131                 versionName = mPm.getPackageInfo(packageItemInfo.packageName, 0).versionName;
132             } catch (PackageManager.NameNotFoundException e) {
133             }
134             return String.format("%s %s", super.loadLabel(), versionName);
135         }
136     }
137 
138 
139     @VisibleForTesting
createDefaultAppInfo(Context context, PackageManager pm, PackageItemInfo packageItemInfo, String disabledReason)140     DefaultAppInfo createDefaultAppInfo(Context context, PackageManager pm,
141             PackageItemInfo packageItemInfo, String disabledReason) {
142         return new WebViewAppInfo(context, pm, mUserId, packageItemInfo, disabledReason,
143                 TextUtils.isEmpty(disabledReason) /* enabled */);
144     }
145 
146     /**
147      * Returns the reason why a package cannot be used as WebView implementation.
148      * This is either because of it being disabled, uninstalled, or hidden for any user.
149      */
150     @VisibleForTesting
getDisabledReason(WebViewUpdateServiceWrapper webviewUpdateServiceWrapper, Context context, String packageName)151     String getDisabledReason(WebViewUpdateServiceWrapper webviewUpdateServiceWrapper,
152             Context context, String packageName) {
153         UserManager userManager = context.getSystemService(UserManager.class);
154         List<UserPackage> userPackages =
155                 webviewUpdateServiceWrapper.getPackageInfosAllUsers(context, packageName);
156         for (UserPackage userPackage : userPackages) {
157             if (!userPackage.isInstalledPackage()) {
158                 // Package uninstalled/hidden
159                 return context.getString(
160                         R.string.webview_uninstalled_for_user,
161                         userManager.getUserInfo(userPackage.getUser().getIdentifier()).name);
162             } else if (!userPackage.isEnabledPackage()) {
163                 // Package disabled
164                 return context.getString(
165                         R.string.webview_disabled_for_user,
166                         userManager.getUserInfo(userPackage.getUser().getIdentifier()).name);
167             }
168         }
169         return null;
170     }
171 }
172