1 /* 2 * Copyright (C) 2023 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.batteryusage; 18 19 import android.app.settings.SettingsEnums; 20 import android.content.Context; 21 import android.text.TextUtils; 22 23 import androidx.preference.PreferenceScreen; 24 25 import com.android.internal.annotations.VisibleForTesting; 26 import com.android.settings.core.BasePreferenceController; 27 import com.android.settings.overlay.FeatureFactory; 28 import com.android.settingslib.core.instrumentation.MetricsFeatureProvider; 29 30 /** Controls the update for battery tips card */ 31 public class BatteryTipsController extends BasePreferenceController { 32 33 private static final String TAG = "BatteryTipsController"; 34 private static final String ROOT_PREFERENCE_KEY = "battery_tips_category"; 35 private static final String CARD_PREFERENCE_KEY = "battery_tips_card"; 36 37 private final MetricsFeatureProvider mMetricsFeatureProvider; 38 39 /** A callback listener for the battery tips is confirmed. */ 40 interface OnAnomalyConfirmListener { 41 /** The callback function for the battery tips is confirmed. */ onAnomalyConfirm()42 void onAnomalyConfirm(); 43 } 44 45 /** A callback listener for the battery tips is rejected. */ 46 interface OnAnomalyRejectListener { 47 /** The callback function for the battery tips is rejected. */ onAnomalyReject()48 void onAnomalyReject(); 49 } 50 51 private OnAnomalyConfirmListener mOnAnomalyConfirmListener; 52 private OnAnomalyRejectListener mOnAnomalyRejectListener; 53 54 @VisibleForTesting 55 BatteryTipsCardPreference mCardPreference; 56 @VisibleForTesting 57 AnomalyEventWrapper mAnomalyEventWrapper = null; 58 @VisibleForTesting 59 Boolean mIsAcceptable = false; 60 BatteryTipsController(Context context)61 public BatteryTipsController(Context context) { 62 super(context, ROOT_PREFERENCE_KEY); 63 final FeatureFactory featureFactory = FeatureFactory.getFactory(context); 64 mMetricsFeatureProvider = featureFactory.getMetricsFeatureProvider(); 65 } 66 67 @Override getAvailabilityStatus()68 public int getAvailabilityStatus() { 69 return AVAILABLE; 70 } 71 72 @Override displayPreference(PreferenceScreen screen)73 public void displayPreference(PreferenceScreen screen) { 74 super.displayPreference(screen); 75 mCardPreference = screen.findPreference(CARD_PREFERENCE_KEY); 76 } 77 setOnAnomalyConfirmListener(OnAnomalyConfirmListener listener)78 void setOnAnomalyConfirmListener(OnAnomalyConfirmListener listener) { 79 mOnAnomalyConfirmListener = listener; 80 } 81 setOnAnomalyRejectListener(OnAnomalyRejectListener listener)82 void setOnAnomalyRejectListener(OnAnomalyRejectListener listener) { 83 mOnAnomalyRejectListener = listener; 84 } 85 acceptTipsCard()86 void acceptTipsCard() { 87 if (mAnomalyEventWrapper == null || !mIsAcceptable) { 88 return; 89 } 90 // For anomaly events with same record key, dismissed until next time full charged. 91 final String dismissRecordKey = mAnomalyEventWrapper.getDismissRecordKey(); 92 if (!TextUtils.isEmpty(dismissRecordKey)) { 93 DatabaseUtils.setDismissedPowerAnomalyKeys(mContext, dismissRecordKey); 94 } 95 mCardPreference.setVisible(false); 96 mMetricsFeatureProvider.action( 97 mContext, SettingsEnums.ACTION_BATTERY_TIPS_CARD_ACCEPT, 98 mAnomalyEventWrapper.getEventId()); 99 } 100 handleBatteryTipsCardUpdated( AnomalyEventWrapper anomalyEventWrapper, boolean isAcceptable)101 void handleBatteryTipsCardUpdated( 102 AnomalyEventWrapper anomalyEventWrapper, boolean isAcceptable) { 103 mAnomalyEventWrapper = anomalyEventWrapper; 104 mIsAcceptable = isAcceptable; 105 if (mAnomalyEventWrapper == null) { 106 mCardPreference.setVisible(false); 107 return; 108 } 109 110 // Get card preference strings and navigate fragment info 111 final String eventId = mAnomalyEventWrapper.getEventId(); 112 113 // Update card & buttons preference 114 if (!mAnomalyEventWrapper.updateTipsCardPreference(mCardPreference)) { 115 mCardPreference.setVisible(false); 116 return; 117 } 118 119 // Set battery tips card listener 120 mCardPreference.setOnConfirmListener(() -> { 121 mCardPreference.setVisible(false); 122 if (mOnAnomalyConfirmListener != null) { 123 mOnAnomalyConfirmListener.onAnomalyConfirm(); 124 } else if (mAnomalyEventWrapper.launchSubSetting()) { 125 mMetricsFeatureProvider.action( 126 mContext, SettingsEnums.ACTION_BATTERY_TIPS_CARD_ACCEPT, eventId); 127 } 128 }); 129 mCardPreference.setOnRejectListener(() -> { 130 mCardPreference.setVisible(false); 131 if (mOnAnomalyRejectListener != null) { 132 mOnAnomalyRejectListener.onAnomalyReject(); 133 } 134 // For anomaly events with same record key, dismissed until next time full charged. 135 final String dismissRecordKey = mAnomalyEventWrapper.getDismissRecordKey(); 136 if (!TextUtils.isEmpty(dismissRecordKey)) { 137 DatabaseUtils.setDismissedPowerAnomalyKeys(mContext, dismissRecordKey); 138 } 139 mMetricsFeatureProvider.action( 140 mContext, SettingsEnums.ACTION_BATTERY_TIPS_CARD_DISMISS, eventId); 141 }); 142 143 mCardPreference.setVisible(true); 144 mMetricsFeatureProvider.action( 145 mContext, SettingsEnums.ACTION_BATTERY_TIPS_CARD_SHOW, eventId); 146 } 147 } 148