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 
46 import java.text.NumberFormat;
47 import java.util.List;
48 
49 /**
50  * Dialog Fragment to show action dialog for each anomaly
51  */
52 public class BatteryTipDialogFragment extends InstrumentedDialogFragment implements
53         DialogInterface.OnClickListener {
54 
55     private static final String ARG_BATTERY_TIP = "battery_tip";
56     private static final String ARG_METRICS_KEY = "metrics_key";
57     private static final double CHARGE_LIMIT_LEVEL = 0.8f;
58 
59     @VisibleForTesting
60     BatteryTip mBatteryTip;
61     @VisibleForTesting
62     int mMetricsKey;
63 
newInstance(BatteryTip batteryTip, int metricsKey)64     public static BatteryTipDialogFragment newInstance(BatteryTip batteryTip, int metricsKey) {
65         BatteryTipDialogFragment dialogFragment = new BatteryTipDialogFragment();
66 
67         Bundle args = new Bundle(1);
68         args.putParcelable(ARG_BATTERY_TIP, batteryTip);
69         args.putInt(ARG_METRICS_KEY, metricsKey);
70         dialogFragment.setArguments(args);
71 
72         return dialogFragment;
73     }
74 
75     @Override
onCreateDialog(Bundle savedInstanceState)76     public Dialog onCreateDialog(Bundle savedInstanceState) {
77         final Bundle bundle = getArguments();
78         final Context context = getContext();
79 
80         mBatteryTip = bundle.getParcelable(ARG_BATTERY_TIP);
81         mMetricsKey = bundle.getInt(ARG_METRICS_KEY);
82 
83         switch (mBatteryTip.getType()) {
84             case BatteryTip.TipType.SUMMARY:
85                 return new AlertDialog.Builder(context)
86                         .setMessage(R.string.battery_tip_dialog_summary_message)
87                         .setPositiveButton(android.R.string.ok, null)
88                         .create();
89             case BatteryTip.TipType.HIGH_DEVICE_USAGE:
90                 final HighUsageTip highUsageTip = (HighUsageTip) mBatteryTip;
91                 final RecyclerView view = (RecyclerView) LayoutInflater.from(context).inflate(
92                         R.layout.recycler_view,
93                         null);
94                 view.setLayoutManager(new LinearLayoutManager(context));
95                 view.setAdapter(new HighUsageAdapter(context,
96                         highUsageTip.getHighUsageAppList()));
97 
98                 return new AlertDialog.Builder(context)
99                         .setMessage(getString(R.string.battery_tip_dialog_message,
100                                 highUsageTip.getHighUsageAppList().size()))
101                         .setView(view)
102                         .setPositiveButton(android.R.string.ok, null)
103                         .create();
104             case BatteryTip.TipType.APP_RESTRICTION:
105                 final RestrictAppTip restrictAppTip = (RestrictAppTip) mBatteryTip;
106                 final List<AppInfo> restrictedAppList = restrictAppTip.getRestrictAppList();
107                 final int num = restrictedAppList.size();
108                 final CharSequence appLabel = Utils.getApplicationLabel(context,
109                         restrictedAppList.get(0).packageName);
110 
111                 final AlertDialog.Builder builder = new AlertDialog.Builder(context)
112                         .setTitle(context.getResources().getQuantityString(
113                                 R.plurals.battery_tip_restrict_app_dialog_title, num, num))
114                         .setPositiveButton(R.string.battery_tip_restrict_app_dialog_ok, this)
115                         .setNegativeButton(android.R.string.cancel, null);
116                 if (num == 1) {
117                     builder.setMessage(
118                             getString(R.string.battery_tip_restrict_app_dialog_message, appLabel));
119                 } else if (num <= 5) {
120                     builder.setMessage(
121                             getString(
122                                     R.string.battery_tip_restrict_apps_less_than_5_dialog_message));
123                     final RecyclerView restrictionView = (RecyclerView) LayoutInflater.from(
124                             context).inflate(R.layout.recycler_view, null);
125                     restrictionView.setLayoutManager(new LinearLayoutManager(context));
126                     restrictionView.setAdapter(new HighUsageAdapter(context, restrictedAppList));
127                     builder.setView(restrictionView);
128                 } else {
129                     builder.setMessage(context.getString(
130                             R.string.battery_tip_restrict_apps_more_than_5_dialog_message,
131                             restrictAppTip.getRestrictAppsString(context)));
132                 }
133 
134                 return builder.create();
135             case BatteryTip.TipType.REMOVE_APP_RESTRICTION:
136                 final UnrestrictAppTip unrestrictAppTip = (UnrestrictAppTip) mBatteryTip;
137                 final CharSequence name = Utils.getApplicationLabel(context,
138                         unrestrictAppTip.getPackageName());
139 
140                 return new AlertDialog.Builder(context)
141                         .setTitle(getString(R.string.battery_tip_unrestrict_app_dialog_title))
142                         .setMessage(R.string.battery_tip_unrestrict_app_dialog_message)
143                         .setPositiveButton(R.string.battery_tip_unrestrict_app_dialog_ok, this)
144                         .setNegativeButton(R.string.battery_tip_unrestrict_app_dialog_cancel, null)
145                         .create();
146             case BatteryTip.TipType.BATTERY_DEFENDER:
147                 mMetricsFeatureProvider.action(context,
148                         SettingsEnums.ACTION_TIP_BATTERY_DEFENDER, mMetricsKey);
149                 final String percentage =
150                         NumberFormat.getPercentInstance().format(CHARGE_LIMIT_LEVEL);
151                 final String message = context.getString(
152                         R.string.battery_tip_limited_temporarily_dialog_msg, percentage);
153                 final boolean isPluggedIn = isPluggedIn();
154                 final AlertDialog.Builder dialogBuilder =
155                         new AlertDialog.Builder(context)
156                                 .setTitle(R.string.battery_tip_limited_temporarily_title)
157                                 .setMessage(message);
158                 if (isPluggedIn) {
159                     dialogBuilder
160                             .setPositiveButton(
161                                     R.string.battery_tip_limited_temporarily_dialog_resume_charge,
162                                     this)
163                             .setNegativeButton(R.string.okay, null);
164                 } else {
165                     dialogBuilder.setPositiveButton(R.string.okay, null);
166                 }
167                 return dialogBuilder.create();
168             default:
169                 throw new IllegalArgumentException("unknown type " + mBatteryTip.getType());
170         }
171     }
172 
173     @Override
getMetricsCategory()174     public int getMetricsCategory() {
175         return SettingsEnums.FUELGAUGE_BATTERY_TIP_DIALOG;
176     }
177 
178     @Override
onClick(DialogInterface dialog, int which)179     public void onClick(DialogInterface dialog, int which) {
180         final BatteryTipListener lsn = (BatteryTipListener) getTargetFragment();
181         if (lsn == null) {
182             return;
183         }
184         final BatteryTipAction action = BatteryTipUtils.getActionForBatteryTip(mBatteryTip,
185                 (SettingsActivity) getActivity(),
186                 (InstrumentedPreferenceFragment) getTargetFragment());
187         if (action != null) {
188             action.handlePositiveAction(mMetricsKey);
189         }
190         lsn.onBatteryTipHandled(mBatteryTip);
191     }
192 
isPluggedIn()193     private boolean isPluggedIn() {
194         final Intent batteryIntent = getContext().registerReceiver(null /* receiver */,
195                 new IntentFilter(Intent.ACTION_BATTERY_CHANGED));
196         return batteryIntent != null && batteryIntent.getIntExtra(
197                 BatteryManager.EXTRA_PLUGGED, 0) != 0;
198     }
199 
200 }
201