Home | History | Annotate | Download | only in fuelgauge
      1 /*
      2  * Copyright (C) 2018 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.fuelgauge;
     18 
     19 import android.content.Context;
     20 import android.content.pm.ApplicationInfo;
     21 import android.content.pm.PackageManager;
     22 import android.os.Bundle;
     23 import android.os.UserHandle;
     24 import android.support.v7.preference.CheckBoxPreference;
     25 import android.support.v7.preference.Preference;
     26 import android.support.v7.preference.PreferenceGroup;
     27 import android.util.IconDrawableFactory;
     28 
     29 import com.android.internal.annotations.VisibleForTesting;
     30 import com.android.internal.logging.nano.MetricsProto;
     31 import com.android.settings.R;
     32 import com.android.settings.Utils;
     33 import com.android.settings.core.InstrumentedPreferenceFragment;
     34 import com.android.settings.core.SubSettingLauncher;
     35 import com.android.settings.dashboard.DashboardFragment;
     36 import com.android.settings.fuelgauge.batterytip.AppInfo;
     37 import com.android.settings.fuelgauge.batterytip.BatteryTipDialogFragment;
     38 import com.android.settings.fuelgauge.batterytip.BatteryTipPreferenceController;
     39 import com.android.settings.fuelgauge.batterytip.tips.BatteryTip;
     40 import com.android.settings.fuelgauge.batterytip.tips.RestrictAppTip;
     41 import com.android.settings.fuelgauge.batterytip.tips.UnrestrictAppTip;
     42 import com.android.settings.widget.AppCheckBoxPreference;
     43 import com.android.settingslib.core.AbstractPreferenceController;
     44 import com.android.settingslib.widget.FooterPreferenceMixin;
     45 
     46 import java.util.List;
     47 
     48 /**
     49  * Fragment to show a list of anomaly apps, where user could handle these anomalies
     50  */
     51 public class RestrictedAppDetails extends DashboardFragment implements
     52         BatteryTipPreferenceController.BatteryTipListener {
     53 
     54     public static final String TAG = "RestrictedAppDetails";
     55 
     56     @VisibleForTesting
     57     static final String EXTRA_APP_INFO_LIST = "app_info_list";
     58     private static final String KEY_PREF_RESTRICTED_APP_LIST = "restrict_app_list";
     59 
     60     @VisibleForTesting
     61     List<AppInfo> mAppInfos;
     62     @VisibleForTesting
     63     IconDrawableFactory mIconDrawableFactory;
     64     @VisibleForTesting
     65     PreferenceGroup mRestrictedAppListGroup;
     66     @VisibleForTesting
     67     BatteryUtils mBatteryUtils;
     68     @VisibleForTesting
     69     PackageManager mPackageManager;
     70     private final FooterPreferenceMixin mFooterPreferenceMixin =
     71             new FooterPreferenceMixin(this, getLifecycle());
     72 
     73     public static void startRestrictedAppDetails(InstrumentedPreferenceFragment fragment,
     74             List<AppInfo> appInfos) {
     75         final Bundle args = new Bundle();
     76         args.putParcelableList(EXTRA_APP_INFO_LIST, appInfos);
     77 
     78         new SubSettingLauncher(fragment.getContext())
     79                 .setDestination(RestrictedAppDetails.class.getName())
     80                 .setArguments(args)
     81                 .setTitle(R.string.restricted_app_title)
     82                 .setSourceMetricsCategory(fragment.getMetricsCategory())
     83                 .launch();
     84     }
     85 
     86     @Override
     87     public void onCreate(Bundle icicle) {
     88         super.onCreate(icicle);
     89         final Context context = getContext();
     90 
     91         mFooterPreferenceMixin.createFooterPreference().setTitle(
     92                 R.string.restricted_app_detail_footer);
     93         mRestrictedAppListGroup = (PreferenceGroup) findPreference(KEY_PREF_RESTRICTED_APP_LIST);
     94         mAppInfos = getArguments().getParcelableArrayList(EXTRA_APP_INFO_LIST);
     95         mPackageManager = context.getPackageManager();
     96         mIconDrawableFactory = IconDrawableFactory.newInstance(context);
     97         mBatteryUtils = BatteryUtils.getInstance(context);
     98 
     99         refreshUi();
    100     }
    101 
    102     @Override
    103     public boolean onPreferenceTreeClick(Preference preference) {
    104 
    105         return super.onPreferenceTreeClick(preference);
    106     }
    107 
    108     @Override
    109     protected String getLogTag() {
    110         return TAG;
    111     }
    112 
    113     @Override
    114     protected int getPreferenceScreenResId() {
    115         return R.xml.restricted_apps_detail;
    116     }
    117 
    118     @Override
    119     protected List<AbstractPreferenceController> createPreferenceControllers(Context context) {
    120         return null;
    121     }
    122 
    123     @Override
    124     public int getMetricsCategory() {
    125         return MetricsProto.MetricsEvent.FUELGAUGE_RESTRICTED_APP_DETAILS;
    126     }
    127 
    128     @Override
    129     public int getHelpResource() {
    130         return R.string.help_uri_restricted_apps;
    131     }
    132 
    133     @VisibleForTesting
    134     void refreshUi() {
    135         mRestrictedAppListGroup.removeAll();
    136         final Context context = getPrefContext();
    137 
    138         for (int i = 0, size = mAppInfos.size(); i < size; i++) {
    139             final CheckBoxPreference checkBoxPreference = new AppCheckBoxPreference(context);
    140             final AppInfo appInfo = mAppInfos.get(i);
    141             try {
    142                 final ApplicationInfo applicationInfo = mPackageManager.getApplicationInfoAsUser(
    143                         appInfo.packageName, 0 /* flags */, UserHandle.getUserId(appInfo.uid));
    144                 checkBoxPreference.setChecked(
    145                         mBatteryUtils.isForceAppStandbyEnabled(appInfo.uid, appInfo.packageName));
    146                 checkBoxPreference.setTitle(mPackageManager.getApplicationLabel(applicationInfo));
    147                 checkBoxPreference.setIcon(
    148                         Utils.getBadgedIcon(mIconDrawableFactory, mPackageManager,
    149                                 appInfo.packageName,
    150                                 UserHandle.getUserId(appInfo.uid)));
    151                 checkBoxPreference.setKey(getKeyFromAppInfo(appInfo));
    152                 checkBoxPreference.setOnPreferenceChangeListener((pref, value) -> {
    153                     final BatteryTipDialogFragment fragment = createDialogFragment(appInfo,
    154                             (Boolean) value);
    155                     fragment.setTargetFragment(this, 0 /* requestCode */);
    156                     fragment.show(getFragmentManager(), TAG);
    157 
    158                     return false;
    159                 });
    160                 mRestrictedAppListGroup.addPreference(checkBoxPreference);
    161             } catch (PackageManager.NameNotFoundException e) {
    162                 e.printStackTrace();
    163             }
    164         }
    165     }
    166 
    167     @Override
    168     public void onBatteryTipHandled(BatteryTip batteryTip) {
    169         final AppInfo appInfo;
    170         final boolean isRestricted = batteryTip instanceof RestrictAppTip;
    171         if (isRestricted) {
    172             appInfo = ((RestrictAppTip) batteryTip).getRestrictAppList().get(0);
    173         } else {
    174             appInfo = ((UnrestrictAppTip) batteryTip).getUnrestrictAppInfo();
    175         }
    176 
    177         CheckBoxPreference preference = (CheckBoxPreference) mRestrictedAppListGroup
    178                 .findPreference(getKeyFromAppInfo(appInfo));
    179         if (preference != null) {
    180             preference.setChecked(isRestricted);
    181         }
    182     }
    183 
    184     @VisibleForTesting
    185     BatteryTipDialogFragment createDialogFragment(AppInfo appInfo, boolean toRestrict) {
    186         final BatteryTip batteryTip = toRestrict
    187                 ? new RestrictAppTip(BatteryTip.StateType.NEW, appInfo)
    188                 : new UnrestrictAppTip(BatteryTip.StateType.NEW, appInfo);
    189 
    190         return BatteryTipDialogFragment.newInstance(
    191                 batteryTip, getMetricsCategory());
    192     }
    193 
    194     @VisibleForTesting
    195     String getKeyFromAppInfo(AppInfo appInfo) {
    196         return appInfo.uid + "," + appInfo.packageName;
    197     }
    198 }
    199