Merge "Add BatteryFix Slice"
This commit is contained in:
@@ -26,6 +26,7 @@ import androidx.annotation.IntDef;
|
||||
import androidx.annotation.VisibleForTesting;
|
||||
|
||||
import com.android.settings.Utils;
|
||||
import com.android.settings.homepage.contextualcards.slices.BatteryFixSlice;
|
||||
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
@@ -115,6 +116,6 @@ public class BatteryBroadcastReceiver extends BroadcastReceiver {
|
||||
mBatteryListener.onBatteryChanged(BatteryUpdateType.BATTERY_SAVER);
|
||||
}
|
||||
}
|
||||
BatteryFixSlice.updateBatteryTipAvailabilityCache(mContext);
|
||||
}
|
||||
|
||||
}
|
@@ -21,6 +21,7 @@ import static android.provider.SettingsSlicesContract.KEY_WIFI;
|
||||
import android.annotation.Nullable;
|
||||
|
||||
import com.android.settings.homepage.contextualcards.deviceinfo.BatterySlice;
|
||||
import com.android.settings.homepage.contextualcards.slices.BatteryFixSlice;
|
||||
import com.android.settings.homepage.contextualcards.slices.ConnectedDeviceSlice;
|
||||
import com.android.settings.homepage.contextualcards.slices.LowStorageSlice;
|
||||
import com.android.settings.intelligence.ContextualCardProto.ContextualCard;
|
||||
@@ -61,11 +62,18 @@ public class SettingsContextualCardProvider extends ContextualCardProvider {
|
||||
.setCardName(LowStorageSlice.PATH_LOW_STORAGE)
|
||||
.setCardCategory(ContextualCard.Category.IMPORTANT)
|
||||
.build();
|
||||
final ContextualCard batteryFixCard =
|
||||
ContextualCard.newBuilder()
|
||||
.setSliceUri(BatteryFixSlice.BATTERY_FIX_URI.toString())
|
||||
.setCardName(BatteryFixSlice.PATH_BATTERY_FIX)
|
||||
.setCardCategory(ContextualCard.Category.IMPORTANT)
|
||||
.build();
|
||||
final ContextualCardList cards = ContextualCardList.newBuilder()
|
||||
.addCard(wifiCard)
|
||||
.addCard(batteryInfoCard)
|
||||
.addCard(connectedDeviceCard)
|
||||
.addCard(lowStorageCard)
|
||||
.addCard(batteryFixCard)
|
||||
.build();
|
||||
|
||||
return cards;
|
||||
|
@@ -0,0 +1,224 @@
|
||||
/*
|
||||
* Copyright (C) 2018 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.android.settings.homepage.contextualcards.slices;
|
||||
|
||||
import static android.content.Context.MODE_PRIVATE;
|
||||
|
||||
import android.app.PendingIntent;
|
||||
import android.content.ContentResolver;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.content.SharedPreferences;
|
||||
import android.net.Uri;
|
||||
|
||||
import androidx.annotation.VisibleForTesting;
|
||||
import androidx.annotation.WorkerThread;
|
||||
import androidx.core.graphics.drawable.IconCompat;
|
||||
import androidx.slice.Slice;
|
||||
import androidx.slice.builders.ListBuilder;
|
||||
import androidx.slice.builders.ListBuilder.RowBuilder;
|
||||
import androidx.slice.builders.SliceAction;
|
||||
|
||||
import com.android.internal.logging.nano.MetricsProto;
|
||||
import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
|
||||
import com.android.internal.os.BatteryStatsHelper;
|
||||
import com.android.settings.R;
|
||||
import com.android.settings.SubSettings;
|
||||
import com.android.settings.Utils;
|
||||
import com.android.settings.fuelgauge.BatteryStatsHelperLoader;
|
||||
import com.android.settings.fuelgauge.PowerUsageSummary;
|
||||
import com.android.settings.fuelgauge.batterytip.BatteryTipLoader;
|
||||
import com.android.settings.fuelgauge.batterytip.tips.BatteryTip;
|
||||
import com.android.settings.slices.CustomSliceable;
|
||||
import com.android.settings.slices.SettingsSliceProvider;
|
||||
import com.android.settings.slices.SliceBackgroundWorker;
|
||||
import com.android.settings.slices.SliceBuilderUtils;
|
||||
import com.android.settingslib.utils.ThreadUtils;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public class BatteryFixSlice implements CustomSliceable {
|
||||
|
||||
/**
|
||||
* Unique name of Battery Fix Slice.
|
||||
*/
|
||||
public static final String PATH_BATTERY_FIX = "battery_fix";
|
||||
|
||||
/**
|
||||
* Uri for Battery Fix Slice.
|
||||
*/
|
||||
public static final Uri BATTERY_FIX_URI = new Uri.Builder()
|
||||
.scheme(ContentResolver.SCHEME_CONTENT)
|
||||
.authority(SettingsSliceProvider.SLICE_AUTHORITY)
|
||||
.appendPath(PATH_BATTERY_FIX)
|
||||
.build();
|
||||
|
||||
@VisibleForTesting
|
||||
static final String PREFS = "battery_fix_prefs";
|
||||
@VisibleForTesting
|
||||
static final String KEY_CURRENT_TIPS_TYPE = "current_tip_type";
|
||||
|
||||
private static final String TAG = "BatteryFixSlice";
|
||||
|
||||
private final Context mContext;
|
||||
|
||||
public BatteryFixSlice(Context context) {
|
||||
mContext = context;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Uri getUri() {
|
||||
return BATTERY_FIX_URI;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return a Slice bound to {@link #BATTERY_FIX_URI}.
|
||||
*/
|
||||
@Override
|
||||
public Slice getSlice() {
|
||||
IconCompat icon;
|
||||
SliceAction primaryAction;
|
||||
Slice slice = null;
|
||||
|
||||
// TipType.SUMMARY is battery good
|
||||
if (readBatteryTipAvailabilityCache(mContext) == BatteryTip.TipType.SUMMARY) {
|
||||
return null;
|
||||
}
|
||||
|
||||
final List<BatteryTip> batteryTips = SliceBackgroundWorker.getInstance(mContext,
|
||||
this).getResults();
|
||||
|
||||
if (batteryTips != null) {
|
||||
for (BatteryTip batteryTip : batteryTips) {
|
||||
if (batteryTip.getState() != BatteryTip.StateType.INVISIBLE) {
|
||||
icon = IconCompat.createWithResource(mContext, batteryTip.getIconId());
|
||||
primaryAction = new SliceAction(getPrimaryAction(),
|
||||
icon,
|
||||
batteryTip.getTitle(mContext));
|
||||
slice = new ListBuilder(mContext, BATTERY_FIX_URI, ListBuilder.INFINITY)
|
||||
.setAccentColor(Utils.getColorAccentDefaultColor(mContext))
|
||||
.addRow(new RowBuilder()
|
||||
.setTitle(batteryTip.getTitle(mContext))
|
||||
.setSubtitle(batteryTip.getSummary(mContext))
|
||||
.setPrimaryAction(primaryAction)
|
||||
.addEndItem(icon, ListBuilder.ICON_IMAGE))
|
||||
.build();
|
||||
break;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
icon = IconCompat.createWithResource(mContext,
|
||||
R.drawable.ic_battery_status_good_24dp);
|
||||
final String title = mContext.getString(R.string.power_usage_summary_title);
|
||||
primaryAction = new SliceAction(getPrimaryAction(), icon, title);
|
||||
slice = new ListBuilder(mContext, BATTERY_FIX_URI, ListBuilder.INFINITY)
|
||||
.setAccentColor(Utils.getColorAccentDefaultColor(mContext))
|
||||
.addRow(new RowBuilder()
|
||||
.setTitle(title)
|
||||
.setPrimaryAction(primaryAction)
|
||||
.addEndItem(icon, ListBuilder.ICON_IMAGE))
|
||||
.build();
|
||||
}
|
||||
return slice;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Intent getIntent() {
|
||||
final String screenTitle = mContext.getText(R.string.power_usage_summary_title)
|
||||
.toString();
|
||||
final Uri contentUri = new Uri.Builder().appendPath(PATH_BATTERY_FIX).build();
|
||||
|
||||
return SliceBuilderUtils.buildSearchResultPageIntent(mContext,
|
||||
PowerUsageSummary.class.getName(), PATH_BATTERY_FIX,
|
||||
screenTitle,
|
||||
MetricsProto.MetricsEvent.SLICE)
|
||||
.setClassName(mContext.getPackageName(), SubSettings.class.getName())
|
||||
.setData(contentUri);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onNotifyChange(Intent intent) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public Class getBackgroundWorkerClass() {
|
||||
return BatteryTipWorker.class;
|
||||
}
|
||||
|
||||
private PendingIntent getPrimaryAction() {
|
||||
final Intent intent = getIntent();
|
||||
return PendingIntent.getActivity(mContext, 0 /* requestCode */, intent, 0 /* flags */);
|
||||
}
|
||||
|
||||
// TODO(b/114807643): we should find a better way to get current battery tip type quickly
|
||||
// Now we save battery tip type to shared preference when battery level changes
|
||||
public static void updateBatteryTipAvailabilityCache(Context context) {
|
||||
ThreadUtils.postOnBackgroundThread(() -> {
|
||||
refreshBatteryTips(context);
|
||||
});
|
||||
}
|
||||
|
||||
@VisibleForTesting
|
||||
static int readBatteryTipAvailabilityCache(Context context) {
|
||||
final SharedPreferences prefs = context.getSharedPreferences(PREFS, MODE_PRIVATE);
|
||||
return prefs.getInt(KEY_CURRENT_TIPS_TYPE, BatteryTip.TipType.SUMMARY);
|
||||
}
|
||||
|
||||
@WorkerThread
|
||||
private static List<BatteryTip> refreshBatteryTips(Context context) {
|
||||
final BatteryStatsHelperLoader statsLoader = new BatteryStatsHelperLoader(context);
|
||||
final BatteryStatsHelper statsHelper = statsLoader.loadInBackground();
|
||||
final BatteryTipLoader loader = new BatteryTipLoader(context, statsHelper);
|
||||
final List<BatteryTip> batteryTips = loader.loadInBackground();
|
||||
for (BatteryTip batteryTip : batteryTips) {
|
||||
if (batteryTip.getState() != BatteryTip.StateType.INVISIBLE) {
|
||||
SharedPreferences.Editor editor = context.getSharedPreferences(PREFS,
|
||||
MODE_PRIVATE).edit();
|
||||
editor.putInt(KEY_CURRENT_TIPS_TYPE, batteryTip.getType());
|
||||
editor.apply();
|
||||
break;
|
||||
}
|
||||
}
|
||||
return batteryTips;
|
||||
}
|
||||
|
||||
public static class BatteryTipWorker extends SliceBackgroundWorker<BatteryTip> {
|
||||
|
||||
private final Context mContext;
|
||||
|
||||
public BatteryTipWorker(Context context, Uri uri) {
|
||||
super(context, uri);
|
||||
mContext = context;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onSlicePinned() {
|
||||
ThreadUtils.postOnBackgroundThread(() -> {
|
||||
final List<BatteryTip> batteryTips = refreshBatteryTips(mContext);
|
||||
updateResults(batteryTips);
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onSliceUnpinned() {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void close() {
|
||||
}
|
||||
}
|
||||
}
|
@@ -20,10 +20,13 @@ import android.content.Context;
|
||||
import android.net.Uri;
|
||||
import android.util.ArrayMap;
|
||||
|
||||
import androidx.annotation.VisibleForTesting;
|
||||
|
||||
import com.android.settings.homepage.contextualcards.deviceinfo.BatterySlice;
|
||||
import com.android.settings.homepage.contextualcards.deviceinfo.DataUsageSlice;
|
||||
import com.android.settings.homepage.contextualcards.deviceinfo.DeviceInfoSlice;
|
||||
import com.android.settings.homepage.contextualcards.deviceinfo.StorageSlice;
|
||||
import com.android.settings.homepage.contextualcards.slices.BatteryFixSlice;
|
||||
import com.android.settings.homepage.contextualcards.slices.ConnectedDeviceSlice;
|
||||
import com.android.settings.homepage.contextualcards.slices.LowStorageSlice;
|
||||
import com.android.settings.wifi.WifiSlice;
|
||||
@@ -34,13 +37,11 @@ import java.util.WeakHashMap;
|
||||
/**
|
||||
* Manages custom {@link androidx.slice.Slice Slices}, which are all Slices not backed by
|
||||
* preferences.
|
||||
* <p>
|
||||
* By default, all Slices in Settings should be built by a
|
||||
* </p>
|
||||
*/
|
||||
public class CustomSliceManager {
|
||||
|
||||
protected final Map<Uri, Class<? extends CustomSliceable>> mUriMap;
|
||||
@VisibleForTesting
|
||||
final Map<Uri, Class<? extends CustomSliceable>> mUriMap;
|
||||
|
||||
private final Context mContext;
|
||||
private final Map<Uri, CustomSliceable> mSliceableCache;
|
||||
@@ -107,5 +108,6 @@ public class CustomSliceManager {
|
||||
mUriMap.put(BatterySlice.BATTERY_CARD_URI, BatterySlice.class);
|
||||
mUriMap.put(ConnectedDeviceSlice.CONNECTED_DEVICE_URI, ConnectedDeviceSlice.class);
|
||||
mUriMap.put(LowStorageSlice.LOW_STORAGE_URI, LowStorageSlice.class);
|
||||
mUriMap.put(BatteryFixSlice.BATTERY_FIX_URI, BatteryFixSlice.class);
|
||||
}
|
||||
}
|
||||
|
Reference in New Issue
Block a user