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