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.batterytip;
18 
19 import android.app.Dialog;
20 import android.app.settings.SettingsEnums;
21 import android.content.Context;
22 import android.content.DialogInterface;
23 import android.content.Intent;
24 import android.content.IntentFilter;
25 import android.os.BatteryManager;
26 import android.os.Bundle;
27 import android.view.LayoutInflater;
28 
29 import androidx.annotation.VisibleForTesting;
30 import androidx.appcompat.app.AlertDialog;
31 import androidx.recyclerview.widget.LinearLayoutManager;
32 import androidx.recyclerview.widget.RecyclerView;
33 
34 import com.android.settings.R;
35 import com.android.settings.SettingsActivity;
36 import com.android.settings.Utils;
37 import com.android.settings.core.InstrumentedPreferenceFragment;
38 import com.android.settings.core.instrumentation.InstrumentedDialogFragment;
39 import com.android.settings.fuelgauge.batterytip.BatteryTipPreferenceController.BatteryTipListener;
40 import com.android.settings.fuelgauge.batterytip.actions.BatteryTipAction;
41 import com.android.settings.fuelgauge.batterytip.tips.BatteryTip;
42 import com.android.settings.fuelgauge.batterytip.tips.HighUsageTip;
43 import com.android.settings.fuelgauge.batterytip.tips.RestrictAppTip;
44 import com.android.settings.fuelgauge.batterytip.tips.UnrestrictAppTip;
45 import com.android.settingslib.utils.StringUtil;
46 
47 import java.util.List;
48 
49 /** Dialog Fragment to show action dialog for each anomaly */
50 public class BatteryTipDialogFragment extends InstrumentedDialogFragment
51         implements DialogInterface.OnClickListener {
52 
53     private static final String ARG_BATTERY_TIP = "battery_tip";
54     private static final String ARG_METRICS_KEY = "metrics_key";
55 
56     @VisibleForTesting BatteryTip mBatteryTip;
57     @VisibleForTesting int mMetricsKey;
58 
newInstance(BatteryTip batteryTip, int metricsKey)59     public static BatteryTipDialogFragment newInstance(BatteryTip batteryTip, int metricsKey) {
60         BatteryTipDialogFragment dialogFragment = new BatteryTipDialogFragment();
61 
62         Bundle args = new Bundle(1);
63         args.putParcelable(ARG_BATTERY_TIP, batteryTip);
64         args.putInt(ARG_METRICS_KEY, metricsKey);
65         dialogFragment.setArguments(args);
66 
67         return dialogFragment;
68     }
69 
70     @Override
onCreateDialog(Bundle savedInstanceState)71     public Dialog onCreateDialog(Bundle savedInstanceState) {
72         final Bundle bundle = getArguments();
73         final Context context = getContext();
74 
75         mBatteryTip = bundle.getParcelable(ARG_BATTERY_TIP);
76         mMetricsKey = bundle.getInt(ARG_METRICS_KEY);
77 
78         switch (mBatteryTip.getType()) {
79             case BatteryTip.TipType.SUMMARY:
80                 return new AlertDialog.Builder(context)
81                         .setMessage(R.string.battery_tip_dialog_summary_message)
82                         .setPositiveButton(android.R.string.ok, null)
83                         .create();
84             case BatteryTip.TipType.HIGH_DEVICE_USAGE:
85                 final HighUsageTip highUsageTip = (HighUsageTip) mBatteryTip;
86                 final RecyclerView view =
87                         (RecyclerView)
88                                 LayoutInflater.from(context).inflate(R.layout.recycler_view, null);
89                 view.setLayoutManager(new LinearLayoutManager(context));
90                 view.setAdapter(new HighUsageAdapter(context, highUsageTip.getHighUsageAppList()));
91 
92                 return new AlertDialog.Builder(context)
93                         .setMessage(
94                                 getString(
95                                         R.string.battery_tip_dialog_message,
96                                         highUsageTip.getHighUsageAppList().size()))
97                         .setView(view)
98                         .setPositiveButton(android.R.string.ok, null)
99                         .create();
100             case BatteryTip.TipType.APP_RESTRICTION:
101                 final RestrictAppTip restrictAppTip = (RestrictAppTip) mBatteryTip;
102                 final List<AppInfo> restrictedAppList = restrictAppTip.getRestrictAppList();
103                 final int num = restrictedAppList.size();
104                 final CharSequence appLabel =
105                         Utils.getApplicationLabel(context, restrictedAppList.get(0).packageName);
106 
107                 final AlertDialog.Builder builder =
108                         new AlertDialog.Builder(context)
109                                 .setTitle(
110                                         StringUtil.getIcuPluralsString(
111                                                 context,
112                                                 num,
113                                                 R.string.battery_tip_restrict_app_dialog_title))
114                                 .setPositiveButton(
115                                         R.string.battery_tip_restrict_app_dialog_ok, this)
116                                 .setNegativeButton(android.R.string.cancel, null);
117                 if (num == 1) {
118                     builder.setMessage(
119                             getString(R.string.battery_tip_restrict_app_dialog_message, appLabel));
120                 } else if (num <= 5) {
121                     builder.setMessage(
122                             getString(
123                                     R.string.battery_tip_restrict_apps_less_than_5_dialog_message));
124                     final RecyclerView restrictionView =
125                             (RecyclerView)
126                                     LayoutInflater.from(context)
127                                             .inflate(R.layout.recycler_view, null);
128                     restrictionView.setLayoutManager(new LinearLayoutManager(context));
129                     restrictionView.setAdapter(new HighUsageAdapter(context, restrictedAppList));
130                     builder.setView(restrictionView);
131                 } else {
132                     builder.setMessage(
133                             context.getString(
134                                     R.string.battery_tip_restrict_apps_more_than_5_dialog_message,
135                                     restrictAppTip.getRestrictAppsString(context)));
136                 }
137 
138                 return builder.create();
139             case BatteryTip.TipType.REMOVE_APP_RESTRICTION:
140                 final UnrestrictAppTip unrestrictAppTip = (UnrestrictAppTip) mBatteryTip;
141                 final CharSequence name =
142                         Utils.getApplicationLabel(context, unrestrictAppTip.getPackageName());
143 
144                 return new AlertDialog.Builder(context)
145                         .setTitle(getString(R.string.battery_tip_unrestrict_app_dialog_title))
146                         .setMessage(R.string.battery_tip_unrestrict_app_dialog_message)
147                         .setPositiveButton(R.string.battery_tip_unrestrict_app_dialog_ok, this)
148                         .setNegativeButton(R.string.battery_tip_unrestrict_app_dialog_cancel, null)
149                         .create();
150             default:
151                 throw new IllegalArgumentException("unknown type " + mBatteryTip.getType());
152         }
153     }
154 
155     @Override
getMetricsCategory()156     public int getMetricsCategory() {
157         return SettingsEnums.FUELGAUGE_BATTERY_TIP_DIALOG;
158     }
159 
160     @Override
onClick(DialogInterface dialog, int which)161     public void onClick(DialogInterface dialog, int which) {
162         final BatteryTipListener lsn = (BatteryTipListener) getTargetFragment();
163         if (lsn == null) {
164             return;
165         }
166         final BatteryTipAction action =
167                 BatteryTipUtils.getActionForBatteryTip(
168                         mBatteryTip,
169                         (SettingsActivity) getActivity(),
170                         (InstrumentedPreferenceFragment) getTargetFragment());
171         if (action != null) {
172             action.handlePositiveAction(mMetricsKey);
173         }
174         lsn.onBatteryTipHandled(mBatteryTip);
175     }
176 
isPluggedIn()177     private boolean isPluggedIn() {
178         final Intent batteryIntent =
179                 getContext()
180                         .registerReceiver(
181                                 null /* receiver */,
182                                 new IntentFilter(Intent.ACTION_BATTERY_CHANGED));
183         return batteryIntent != null
184                 && batteryIntent.getIntExtra(BatteryManager.EXTRA_PLUGGED, 0) != 0;
185     }
186 }
187