Home | History | Annotate | Download | only in batterytip
      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.content.Context;
     20 import android.os.Bundle;
     21 import android.support.annotation.VisibleForTesting;
     22 import android.support.v7.preference.Preference;
     23 import android.support.v7.preference.PreferenceGroup;
     24 import android.support.v7.preference.PreferenceScreen;
     25 
     26 import com.android.internal.logging.nano.MetricsProto;
     27 import com.android.settings.SettingsActivity;
     28 import com.android.settings.core.BasePreferenceController;
     29 import com.android.settings.core.InstrumentedPreferenceFragment;
     30 import com.android.settings.fuelgauge.Estimate;
     31 import com.android.settings.fuelgauge.batterytip.actions.BatteryTipAction;
     32 import com.android.settings.fuelgauge.batterytip.tips.BatteryTip;
     33 import com.android.settings.fuelgauge.batterytip.tips.SummaryTip;
     34 import com.android.settings.overlay.FeatureFactory;
     35 import com.android.settingslib.core.instrumentation.MetricsFeatureProvider;
     36 
     37 import java.util.ArrayList;
     38 import java.util.HashMap;
     39 import java.util.List;
     40 import java.util.Map;
     41 
     42 /**
     43  * Controller in charge of the battery tip group
     44  */
     45 public class BatteryTipPreferenceController extends BasePreferenceController {
     46     private static final String TAG = "BatteryTipPreferenceController";
     47     private static final int REQUEST_ANOMALY_ACTION = 0;
     48     private static final String KEY_BATTERY_TIPS = "key_battery_tips";
     49 
     50     private BatteryTipListener mBatteryTipListener;
     51     private List<BatteryTip> mBatteryTips;
     52     private Map<String, BatteryTip> mBatteryTipMap;
     53     private SettingsActivity mSettingsActivity;
     54     private MetricsFeatureProvider mMetricsFeatureProvider;
     55     private boolean mNeedUpdate;
     56     @VisibleForTesting
     57     PreferenceGroup mPreferenceGroup;
     58     @VisibleForTesting
     59     Context mPrefContext;
     60     InstrumentedPreferenceFragment mFragment;
     61 
     62     public BatteryTipPreferenceController(Context context, String preferenceKey) {
     63         this(context, preferenceKey, null, null, null);
     64     }
     65 
     66     public BatteryTipPreferenceController(Context context, String preferenceKey,
     67             SettingsActivity settingsActivity, InstrumentedPreferenceFragment fragment,
     68             BatteryTipListener batteryTipListener) {
     69         super(context, preferenceKey);
     70         mBatteryTipListener = batteryTipListener;
     71         mBatteryTipMap = new HashMap<>();
     72         mFragment = fragment;
     73         mSettingsActivity = settingsActivity;
     74         mMetricsFeatureProvider = FeatureFactory.getFactory(context).getMetricsFeatureProvider();
     75         mNeedUpdate = true;
     76     }
     77 
     78     @Override
     79     public int getAvailabilityStatus() {
     80         return AVAILABLE;
     81     }
     82 
     83     @Override
     84     public void displayPreference(PreferenceScreen screen) {
     85         super.displayPreference(screen);
     86         mPrefContext = screen.getContext();
     87         mPreferenceGroup = (PreferenceGroup) screen.findPreference(getPreferenceKey());
     88 
     89         // Add summary tip in advance to avoid UI flakiness
     90         final SummaryTip summaryTip = new SummaryTip(BatteryTip.StateType.NEW,
     91                 Estimate.AVERAGE_TIME_TO_DISCHARGE_UNKNOWN);
     92         mPreferenceGroup.addPreference(summaryTip.buildPreference(mPrefContext));
     93     }
     94 
     95     public void updateBatteryTips(List<BatteryTip> batteryTips) {
     96         if (batteryTips == null) {
     97             return;
     98         }
     99         if (mBatteryTips == null) {
    100             mBatteryTips = batteryTips;
    101         } else {
    102             // mBatteryTips and batteryTips always have the same length and same sequence.
    103             for (int i = 0, size = batteryTips.size(); i < size; i++) {
    104                 mBatteryTips.get(i).updateState(batteryTips.get(i));
    105             }
    106         }
    107 
    108         mPreferenceGroup.removeAll();
    109         for (int i = 0, size = batteryTips.size(); i < size; i++) {
    110             final BatteryTip batteryTip = mBatteryTips.get(i);
    111             if (batteryTip.getState() != BatteryTip.StateType.INVISIBLE) {
    112                 final Preference preference = batteryTip.buildPreference(mPrefContext);
    113                 mBatteryTipMap.put(preference.getKey(), batteryTip);
    114                 mPreferenceGroup.addPreference(preference);
    115                 batteryTip.log(mContext, mMetricsFeatureProvider);
    116                 mNeedUpdate = batteryTip.needUpdate();
    117                 break;
    118             }
    119         }
    120     }
    121 
    122     @Override
    123     public boolean handlePreferenceTreeClick(Preference preference) {
    124         final BatteryTip batteryTip = mBatteryTipMap.get(preference.getKey());
    125         if (batteryTip != null) {
    126             if (batteryTip.shouldShowDialog()) {
    127                 BatteryTipDialogFragment dialogFragment = BatteryTipDialogFragment.newInstance(
    128                         batteryTip, mFragment.getMetricsCategory());
    129                 dialogFragment.setTargetFragment(mFragment, REQUEST_ANOMALY_ACTION);
    130                 dialogFragment.show(mFragment.getFragmentManager(), TAG);
    131             } else {
    132                 final BatteryTipAction action = BatteryTipUtils.getActionForBatteryTip(batteryTip,
    133                         mSettingsActivity, mFragment);
    134                 if (action != null) {
    135                     action.handlePositiveAction(mFragment.getMetricsCategory());
    136                 }
    137                 if (mBatteryTipListener != null) {
    138                     mBatteryTipListener.onBatteryTipHandled(batteryTip);
    139                 }
    140             }
    141 
    142             return true;
    143         }
    144 
    145         return super.handlePreferenceTreeClick(preference);
    146     }
    147 
    148     public void restoreInstanceState(Bundle bundle) {
    149         if (bundle != null) {
    150             List<BatteryTip> batteryTips = bundle.getParcelableArrayList(KEY_BATTERY_TIPS);
    151             updateBatteryTips(batteryTips);
    152         }
    153     }
    154 
    155     public void saveInstanceState(Bundle outState) {
    156         outState.putParcelableList(KEY_BATTERY_TIPS, mBatteryTips);
    157     }
    158 
    159     public boolean needUpdate() {
    160         return mNeedUpdate;
    161     }
    162 
    163     /**
    164      * Listener to give the control back to target fragment
    165      */
    166     public interface BatteryTipListener {
    167         /**
    168          * This method is invoked once battery tip is handled, then target fragment could do
    169          * extra work.
    170          *
    171          * @param batteryTip that has been handled
    172          */
    173         void onBatteryTipHandled(BatteryTip batteryTip);
    174     }
    175 }
    176