| /* | |
| * Copyright (C) 2017 The Android Open Source Project | |
| * | |
| * Licensed under the Apache License, Version 2.0 (the "License"); | |
| * you may not use this file except in compliance with the License. | |
| * You may obtain a copy of the License at | |
| * | |
| * http://www.apache.org/licenses/LICENSE-2.0 | |
| * | |
| * Unless required by applicable law or agreed to in writing, software | |
| * distributed under the License is distributed on an "AS IS" BASIS, | |
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | |
| * See the License for the specific language governing permissions and | |
| * limitations under the License. | |
| */ | |
| package com.android.settings.webview; | |
| import static android.provider.Settings.ACTION_WEBVIEW_SETTINGS; | |
| import android.app.Activity; | |
| import android.app.settings.SettingsEnums; | |
| import android.content.Context; | |
| import android.content.Intent; | |
| import android.content.pm.ApplicationInfo; | |
| import android.content.pm.PackageInfo; | |
| import android.content.pm.PackageItemInfo; | |
| import android.content.pm.PackageManager; | |
| import android.text.TextUtils; | |
| import android.webkit.UserPackage; | |
| import androidx.annotation.VisibleForTesting; | |
| import com.android.settings.R; | |
| import com.android.settings.applications.defaultapps.DefaultAppPickerFragment; | |
| import com.android.settingslib.applications.DefaultAppInfo; | |
| import java.util.ArrayList; | |
| import java.util.List; | |
| public class WebViewAppPicker extends DefaultAppPickerFragment { | |
| private WebViewUpdateServiceWrapper mWebViewUpdateServiceWrapper; | |
| private WebViewUpdateServiceWrapper getWebViewUpdateServiceWrapper() { | |
| if (mWebViewUpdateServiceWrapper == null) { | |
| setWebViewUpdateServiceWrapper(createDefaultWebViewUpdateServiceWrapper()); | |
| } | |
| return mWebViewUpdateServiceWrapper; | |
| } | |
| @Override | |
| public void onAttach(Context context) { | |
| super.onAttach(context); | |
| if (!mUserManager.isAdminUser()) { | |
| getActivity().finish(); | |
| } | |
| } | |
| @Override | |
| protected int getPreferenceScreenResId() { | |
| return R.xml.webview_app_settings; | |
| } | |
| @Override | |
| protected List<DefaultAppInfo> getCandidates() { | |
| final List<DefaultAppInfo> packageInfoList = new ArrayList<DefaultAppInfo>(); | |
| final Context context = getContext(); | |
| final WebViewUpdateServiceWrapper webViewUpdateService = getWebViewUpdateServiceWrapper(); | |
| final List<ApplicationInfo> pkgs = | |
| webViewUpdateService.getValidWebViewApplicationInfos(context); | |
| for (ApplicationInfo ai : pkgs) { | |
| packageInfoList.add(createDefaultAppInfo(context, mPm, ai, | |
| getDisabledReason(webViewUpdateService, context, ai.packageName))); | |
| } | |
| return packageInfoList; | |
| } | |
| @Override | |
| protected String getDefaultKey() { | |
| PackageInfo currentPackage = getWebViewUpdateServiceWrapper().getCurrentWebViewPackage(); | |
| return currentPackage == null ? null : currentPackage.packageName; | |
| } | |
| protected boolean setDefaultKey(String key) { | |
| boolean success = getWebViewUpdateServiceWrapper().setWebViewProvider(key); | |
| return success; | |
| } | |
| @Override | |
| protected void onSelectionPerformed(boolean success) { | |
| if (success) { | |
| Activity activity = getActivity(); | |
| Intent intent = activity == null ? null : activity.getIntent(); | |
| if (intent != null && ACTION_WEBVIEW_SETTINGS.equals(intent.getAction())) { | |
| // If this was started through ACTION_WEBVIEW_SETTINGS then return once we have | |
| // chosen a new package. | |
| getActivity().finish(); | |
| } | |
| } else { | |
| getWebViewUpdateServiceWrapper().showInvalidChoiceToast(getActivity()); | |
| updateCandidates(); | |
| } | |
| } | |
| private WebViewUpdateServiceWrapper createDefaultWebViewUpdateServiceWrapper() { | |
| return new WebViewUpdateServiceWrapper(); | |
| } | |
| @VisibleForTesting | |
| void setWebViewUpdateServiceWrapper(WebViewUpdateServiceWrapper wvusWrapper) { | |
| mWebViewUpdateServiceWrapper = wvusWrapper; | |
| } | |
| @Override | |
| public int getMetricsCategory() { | |
| return SettingsEnums.WEBVIEW_IMPLEMENTATION; | |
| } | |
| private static class WebViewAppInfo extends DefaultAppInfo { | |
| public WebViewAppInfo(Context context, PackageManager pm, int userId, | |
| PackageItemInfo packageItemInfo, String summary, boolean enabled) { | |
| super(context, pm, userId, packageItemInfo, summary, enabled); | |
| } | |
| @Override | |
| public CharSequence loadLabel() { | |
| String versionName = ""; | |
| try { | |
| versionName = mPm.getPackageInfo(packageItemInfo.packageName, 0).versionName; | |
| } catch (PackageManager.NameNotFoundException e) { | |
| } | |
| return String.format("%s %s", super.loadLabel(), versionName); | |
| } | |
| } | |
| @VisibleForTesting | |
| DefaultAppInfo createDefaultAppInfo(Context context, PackageManager pm, | |
| PackageItemInfo packageItemInfo, String disabledReason) { | |
| return new WebViewAppInfo(context, pm, mUserId, packageItemInfo, disabledReason, | |
| TextUtils.isEmpty(disabledReason) /* enabled */); | |
| } | |
| /** | |
| * Returns the reason why a package cannot be used as WebView implementation. | |
| * This is either because of it being disabled, uninstalled, or hidden for any user. | |
| */ | |
| @VisibleForTesting | |
| String getDisabledReason(WebViewUpdateServiceWrapper webviewUpdateServiceWrapper, | |
| Context context, String packageName) { | |
| List<UserPackage> userPackages = | |
| webviewUpdateServiceWrapper.getPackageInfosAllUsers(context, packageName); | |
| for (UserPackage userPackage : userPackages) { | |
| if (!userPackage.isInstalledPackage()) { | |
| // Package uninstalled/hidden | |
| return context.getString( | |
| R.string.webview_uninstalled_for_user, userPackage.getUserInfo().name); | |
| } else if (!userPackage.isEnabledPackage()) { | |
| // Package disabled | |
| return context.getString( | |
| R.string.webview_disabled_for_user, userPackage.getUserInfo().name); | |
| } | |
| } | |
| return null; | |
| } | |
| } |