• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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.fuelgauge.batterytip;
18 
19 import android.annotation.Nullable;
20 import android.content.Context;
21 import android.os.BadParcelableException;
22 import android.os.Bundle;
23 import android.util.Log;
24 
25 import androidx.annotation.VisibleForTesting;
26 import androidx.preference.Preference;
27 import androidx.preference.PreferenceScreen;
28 
29 import com.android.settings.SettingsActivity;
30 import com.android.settings.core.BasePreferenceController;
31 import com.android.settings.core.InstrumentedPreferenceFragment;
32 import com.android.settings.fuelgauge.batterytip.actions.BatteryTipAction;
33 import com.android.settings.fuelgauge.batterytip.tips.BatteryTip;
34 import com.android.settings.overlay.FeatureFactory;
35 import com.android.settings.widget.CardPreference;
36 import com.android.settingslib.core.instrumentation.MetricsFeatureProvider;
37 
38 import java.util.HashMap;
39 import java.util.List;
40 import java.util.Map;
41 import java.util.Optional;
42 
43 /**
44  * Controller in charge of the battery tip group
45  */
46 public class BatteryTipPreferenceController extends BasePreferenceController {
47 
48     public static final String PREF_NAME = "battery_tip";
49 
50     private static final String TAG = "BatteryTipPreferenceController";
51     private static final int REQUEST_ANOMALY_ACTION = 0;
52     private static final String KEY_BATTERY_TIPS = "key_battery_tips";
53 
54     private BatteryTipListener mBatteryTipListener;
55     private List<BatteryTip> mBatteryTips;
56     private Map<String, BatteryTip> mBatteryTipMap;
57     private SettingsActivity mSettingsActivity;
58     private MetricsFeatureProvider mMetricsFeatureProvider;
59     private boolean mNeedUpdate;
60     @VisibleForTesting
61     CardPreference mCardPreference;
62     @VisibleForTesting
63     Context mPrefContext;
64     InstrumentedPreferenceFragment mFragment;
65 
BatteryTipPreferenceController(Context context, String preferenceKey)66     public BatteryTipPreferenceController(Context context, String preferenceKey) {
67         super(context, preferenceKey);
68         mBatteryTipMap = new HashMap<>();
69         mMetricsFeatureProvider = FeatureFactory.getFactory(context).getMetricsFeatureProvider();
70         mNeedUpdate = true;
71     }
72 
setActivity(SettingsActivity activity)73     public void setActivity(SettingsActivity activity) {
74         mSettingsActivity = activity;
75     }
76 
setFragment(InstrumentedPreferenceFragment fragment)77     public void setFragment(InstrumentedPreferenceFragment fragment) {
78         mFragment = fragment;
79     }
80 
setBatteryTipListener(BatteryTipListener lsn)81     public void setBatteryTipListener(BatteryTipListener lsn) {
82         mBatteryTipListener = lsn;
83     }
84 
85     @Override
getAvailabilityStatus()86     public int getAvailabilityStatus() {
87         return AVAILABLE_UNSEARCHABLE;
88     }
89 
90     @Override
displayPreference(PreferenceScreen screen)91     public void displayPreference(PreferenceScreen screen) {
92         super.displayPreference(screen);
93         mPrefContext = screen.getContext();
94         mCardPreference = screen.findPreference(getPreferenceKey());
95 
96         // Set preference as invisible since there is no default tips.
97         mCardPreference.setVisible(false);
98     }
99 
updateBatteryTips(List<BatteryTip> batteryTips)100     public void updateBatteryTips(List<BatteryTip> batteryTips) {
101         if (batteryTips == null) {
102             return;
103         }
104         mBatteryTips = batteryTips;
105         mCardPreference.setVisible(false);
106         for (int i = 0, size = batteryTips.size(); i < size; i++) {
107             final BatteryTip batteryTip = mBatteryTips.get(i);
108             batteryTip.validateCheck(mContext);
109             if (batteryTip.getState() != BatteryTip.StateType.INVISIBLE) {
110                 mCardPreference.setVisible(true);
111                 batteryTip.updatePreference(mCardPreference);
112                 mBatteryTipMap.put(mCardPreference.getKey(), batteryTip);
113                 batteryTip.log(mContext, mMetricsFeatureProvider);
114                 mNeedUpdate = batteryTip.needUpdate();
115                 break;
116             }
117         }
118     }
119 
120     @Override
handlePreferenceTreeClick(Preference preference)121     public boolean handlePreferenceTreeClick(Preference preference) {
122         final BatteryTip batteryTip = mBatteryTipMap.get(preference.getKey());
123         if (batteryTip != null) {
124             if (batteryTip.shouldShowDialog()) {
125                 BatteryTipDialogFragment dialogFragment = BatteryTipDialogFragment.newInstance(
126                         batteryTip, mFragment.getMetricsCategory());
127                 dialogFragment.setTargetFragment(mFragment, REQUEST_ANOMALY_ACTION);
128                 dialogFragment.show(mFragment.getFragmentManager(), TAG);
129             } else {
130                 final BatteryTipAction action = BatteryTipUtils.getActionForBatteryTip(batteryTip,
131                         mSettingsActivity, mFragment);
132                 if (action != null) {
133                     action.handlePositiveAction(mFragment.getMetricsCategory());
134                 }
135                 if (mBatteryTipListener != null) {
136                     mBatteryTipListener.onBatteryTipHandled(batteryTip);
137                 }
138             }
139 
140             return true;
141         }
142 
143         return super.handlePreferenceTreeClick(preference);
144     }
145 
restoreInstanceState(Bundle bundle)146     public void restoreInstanceState(Bundle bundle) {
147         if (bundle == null) {
148             return;
149         }
150         try {
151             List<BatteryTip> batteryTips = bundle.getParcelableArrayList(KEY_BATTERY_TIPS);
152             updateBatteryTips(batteryTips);
153         } catch (BadParcelableException e) {
154             Log.e(TAG, "failed to invoke restoreInstanceState()", e);
155         }
156     }
157 
saveInstanceState(Bundle bundle)158     public void saveInstanceState(Bundle bundle) {
159         if (bundle == null) {
160             return;
161         }
162         try {
163             bundle.putParcelableList(KEY_BATTERY_TIPS, mBatteryTips);
164         } catch (BadParcelableException e) {
165             Log.e(TAG, "failed to invoke saveInstanceState()", e);
166         }
167     }
168 
needUpdate()169     public boolean needUpdate() {
170         return mNeedUpdate;
171     }
172 
173     /**
174      * @return current battery tips, null if unavailable.
175      */
176     @Nullable
getCurrentBatteryTip()177     public BatteryTip getCurrentBatteryTip() {
178         if (mBatteryTips == null) {
179             return null;
180         }
181         Optional<BatteryTip> visibleBatteryTip =
182                 mBatteryTips.stream().filter(BatteryTip::isVisible).findFirst();
183         return visibleBatteryTip.orElse(null);
184     }
185 
186     /**
187      * Listener to give the control back to target fragment
188      */
189     public interface BatteryTipListener {
190         /**
191          * This method is invoked once battery tip is handled, then target fragment could do
192          * extra work.
193          *
194          * @param batteryTip that has been handled
195          */
onBatteryTipHandled(BatteryTip batteryTip)196         void onBatteryTipHandled(BatteryTip batteryTip);
197     }
198 }
199