Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit e2ed46e9 authored by TreeHugger Robot's avatar TreeHugger Robot Committed by Android (Google) Code Review
Browse files

Merge "Add Battery slice in Contextual Settings Homepage"

parents a4c516fe 60f6a25a
Loading
Loading
Loading
Loading
+48 −43
Original line number Diff line number Diff line
@@ -148,6 +148,20 @@ public class BatteryInfo {
        new AsyncTask<Void, Void, BatteryInfo>() {
            @Override
            protected BatteryInfo doInBackground(Void... params) {
                return getBatteryInfo(context, statsHelper, shortString);
            }

            @Override
            protected void onPostExecute(BatteryInfo batteryInfo) {
                final long startTime = System.currentTimeMillis();
                callback.onBatteryInfoLoaded(batteryInfo);
                BatteryUtils.logRuntime(LOG_TAG, "time for callback", startTime);
            }
        }.execute();
    }

    public static BatteryInfo getBatteryInfo(final Context context,
            final BatteryStatsHelper statsHelper, boolean shortString) {
        final BatteryStats stats;
        final long batteryStatsTime = System.currentTimeMillis();
        if (statsHelper == null) {
@@ -166,10 +180,10 @@ public class BatteryInfo {
        final long elapsedRealtimeUs =
                PowerUtil.convertMsToUs(SystemClock.elapsedRealtime());

                Intent batteryBroadcast = context.registerReceiver(null,
        final Intent batteryBroadcast = context.registerReceiver(null,
                new IntentFilter(Intent.ACTION_BATTERY_CHANGED));
        // 0 means we are discharging, anything else means charging
                boolean discharging =
        final boolean discharging =
                batteryBroadcast.getIntExtra(BatteryManager.EXTRA_PLUGGED, -1) == 0;

        if (discharging && provider != null
@@ -182,9 +196,9 @@ public class BatteryInfo {
                        estimate, elapsedRealtimeUs, shortString);
            }
        }
                long prediction = discharging
        final long prediction = discharging
                ? stats.computeBatteryTimeRemaining(elapsedRealtimeUs) : 0;
                Estimate estimate = new Estimate(
        final Estimate estimate = new Estimate(
                PowerUtil.convertUsToMs(prediction),
                false, /* isBasedOnUsage */
                Estimate.AVERAGE_TIME_TO_DISCHARGE_UNKNOWN);
@@ -193,15 +207,6 @@ public class BatteryInfo {
                estimate, elapsedRealtimeUs, shortString);
    }

            @Override
            protected void onPostExecute(BatteryInfo batteryInfo) {
                final long startTime = System.currentTimeMillis();
                callback.onBatteryInfoLoaded(batteryInfo);
                BatteryUtils.logRuntime(LOG_TAG, "time for callback", startTime);
            }
        }.execute();
    }

    @WorkerThread
    public static BatteryInfo getBatteryInfoOld(Context context, Intent batteryBroadcast,
            BatteryStats stats, long elapsedRealtimeUs, boolean shortString) {
+10 −11
Original line number Diff line number Diff line
@@ -32,6 +32,7 @@ import androidx.annotation.NonNull;
import androidx.annotation.VisibleForTesting;
import androidx.slice.Slice;

import com.android.settings.homepage.deviceinfo.BatterySlice;
import com.android.settings.homepage.deviceinfo.DataUsageSlice;
import com.android.settings.homepage.deviceinfo.DeviceInfoSlice;
import com.android.settingslib.utils.AsyncLoaderCompat;
@@ -101,17 +102,15 @@ public class CardContentLoader extends AsyncLoaderCompat<List<ContextualCard>> {
                    .setCardType(ContextualCard.CardType.SLICE)
                    .setIsHalfWidth(false)
                    .build());
            //TODO(b/115971399): Will change following values of SliceUri and Name
            // after landing these slice cards.
//            add(new ContextualCard.Builder()
//                    .setSliceUri("content://com.android.settings.slices/battery_card")
//                    .setName(packageName + "/" + "battery_card")
//                    .setPackageName(packageName)
//                    .setRankingScore(rankingScore)
//                    .setAppVersion(appVersionCode)
//                    .setCardType(ContextualCard.CardType.SLICE)
//                    .setIsHalfWidth(true)
//                    .build());
            add(new ContextualCard.Builder()
                    .setSliceUri(BatterySlice.BATTERY_CARD_URI)
                    .setName(BatterySlice.PATH_BATTERY_INFO)
                    .setPackageName(packageName)
                    .setRankingScore(rankingScore)
                    .setAppVersion(appVersionCode)
                    .setCardType(ContextualCard.CardType.SLICE)
                    .setIsHalfWidth(false)
                    .build());
            add(new ContextualCard.Builder()
                    .setSliceUri(DeviceInfoSlice.DEVICE_INFO_CARD_URI)
                    .setName(DeviceInfoSlice.PATH_DEVICE_INFO)
+7 −0
Original line number Diff line number Diff line
@@ -20,6 +20,7 @@ import static android.provider.SettingsSlicesContract.KEY_WIFI;

import android.annotation.Nullable;

import com.android.settings.homepage.deviceinfo.BatterySlice;
import com.android.settings.homepage.deviceinfo.DataUsageSlice;
import com.android.settings.homepage.deviceinfo.DeviceInfoSlice;
import com.android.settings.homepage.deviceinfo.StorageSlice;
@@ -63,12 +64,18 @@ public class SettingsContextualCardProvider extends ContextualCardProvider {
                        .setSliceUri(EmergencyInfoSlice.EMERGENCY_INFO_CARD_URI.toString())
                        .setCardName(EmergencyInfoSlice.PATH_EMERGENCY_INFO_CARD)
                        .build();
        final ContextualCard batteryInfoCard =
                ContextualCard.newBuilder()
                        .setSliceUri(BatterySlice.BATTERY_CARD_URI.toSafeString())
                        .setCardName(BatterySlice.PATH_BATTERY_INFO)
                        .build();
        final ContextualCardList cards = ContextualCardList.newBuilder()
                .addCard(wifiCard)
                .addCard(dataUsageCard)
                .addCard(deviceInfoCard)
                .addCard(storageInfoCard)
                .addCard(emergencyInfoCard)
                .addCard(batteryInfoCard)
                .build();

        return cards;
+156 −0
Original line number Diff line number Diff line
/*
 * 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.deviceinfo;

import android.app.PendingIntent;
import android.content.ContentResolver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.net.Uri;
import android.os.PowerManager;

import androidx.annotation.VisibleForTesting;
import androidx.core.graphics.drawable.IconCompat;
import androidx.slice.Slice;
import androidx.slice.builders.ListBuilder;
import androidx.slice.builders.SliceAction;

import com.android.internal.logging.nano.MetricsProto;
import com.android.settings.R;
import com.android.settings.SubSettings;
import com.android.settings.Utils;
import com.android.settings.fuelgauge.BatteryInfo;
import com.android.settings.fuelgauge.PowerUsageSummary;
import com.android.settings.slices.CustomSliceable;
import com.android.settings.slices.SettingsSliceProvider;
import com.android.settings.slices.SliceBuilderUtils;

/**
 * Utility class to build a Battery Slice, and handle all associated actions.
 */
public class BatterySlice implements CustomSliceable {
    private static final String TAG = "BatterySlice";

    /**
     * The path denotes the unique name of battery slice.
     */
    public static final String PATH_BATTERY_INFO = "battery_card";

    /**
     * Backing Uri for the Battery Slice.
     */
    public static final Uri BATTERY_CARD_URI = new Uri.Builder()
            .scheme(ContentResolver.SCHEME_CONTENT)
            .authority(SettingsSliceProvider.SLICE_AUTHORITY)
            .appendPath(PATH_BATTERY_INFO)
            .build();

    private final Context mContext;

    private BatteryInfo mBatteryInfo;
    private boolean mIsBatteryInfoLoading;

    public BatterySlice(Context context) {
        mContext = context;
    }

    /**
     * Return a {@link BatterySlice} bound to {@link #BATTERY_CARD_URI}
     */
    @Override
    public Slice getSlice() {
        if (mBatteryInfo == null) {
            mIsBatteryInfoLoading = true;
            loadBatteryInfo();
        }
        final IconCompat icon = IconCompat.createWithResource(mContext,
                R.drawable.ic_settings_battery);
        final CharSequence title = mContext.getText(R.string.power_usage_summary_title);
        final SliceAction primarySliceAction = new SliceAction(getPrimaryAction(), icon, title);
        final Slice slice = new ListBuilder(mContext, BATTERY_CARD_URI, ListBuilder.INFINITY)
                .setAccentColor(Utils.getColorAccentDefaultColor(mContext))
                .setHeader(new ListBuilder.HeaderBuilder().setTitle(title))
                .addRow(new ListBuilder.RowBuilder()
                        .setTitle(getBatteryPercentString(), mIsBatteryInfoLoading)
                        .setSubtitle(getSummary(), mIsBatteryInfoLoading)
                        .setPrimaryAction(primarySliceAction))
                .build();
        mBatteryInfo = null;
        mIsBatteryInfoLoading = false;
        return slice;
    }

    @Override
    public Uri getUri() {
        return BATTERY_CARD_URI;
    }

    @Override
    public void onNotifyChange(Intent intent) {

    }

    @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_INFO).build();
        return SliceBuilderUtils.buildSearchResultPageIntent(mContext,
                PowerUsageSummary.class.getName(), PATH_BATTERY_INFO, screenTitle,
                MetricsProto.MetricsEvent.SLICE)
                .setClassName(mContext.getPackageName(), SubSettings.class.getName())
                .setData(contentUri);
    }

    @Override
    public IntentFilter getIntentFilter() {
        final IntentFilter intentFilter = new IntentFilter();
        intentFilter.addAction(PowerManager.ACTION_POWER_SAVE_MODE_CHANGED);
        intentFilter.addAction(Intent.ACTION_POWER_CONNECTED);
        intentFilter.addAction(Intent.ACTION_POWER_DISCONNECTED);
        intentFilter.addAction(Intent.ACTION_BATTERY_LEVEL_CHANGED);
        return intentFilter;
    }

    @VisibleForTesting
    void loadBatteryInfo() {
        BatteryInfo.getBatteryInfo(mContext, info -> {
            mBatteryInfo = info;
            mContext.getContentResolver().notifyChange(getUri(), null);
        }, true);
    }

    @VisibleForTesting
    CharSequence getBatteryPercentString() {
        return mBatteryInfo == null ? null : mBatteryInfo.batteryPercentString;
    }

    @VisibleForTesting
    CharSequence getSummary() {
        if (mBatteryInfo == null) {
            return null;
        }
        return mBatteryInfo.remainingLabel == null ? mBatteryInfo.statusLabel
                : mBatteryInfo.remainingLabel;
    }

    private PendingIntent getPrimaryAction() {
        final Intent intent = getIntent();
        return PendingIntent.getActivity(mContext, 0 /* requestCode */,
                intent, 0 /* flags */);
    }
}
 No newline at end of file
+13 −3
Original line number Diff line number Diff line
@@ -20,12 +20,14 @@ import android.content.Context;
import android.net.Uri;
import android.util.ArrayMap;

import com.android.settings.homepage.deviceinfo.BatterySlice;
import com.android.settings.homepage.deviceinfo.DataUsageSlice;
import com.android.settings.homepage.deviceinfo.DeviceInfoSlice;
import com.android.settings.homepage.deviceinfo.StorageSlice;
import com.android.settings.wifi.WifiSlice;

import java.util.Map;
import java.util.WeakHashMap;

/**
 * Manages custom {@link androidx.slice.Slice Slices}, which are all Slices not backed by
@@ -39,10 +41,12 @@ public class CustomSliceManager {
    protected final Map<Uri, Class<? extends CustomSliceable>> mUriMap;

    private final Context mContext;
    private final Map<Uri, CustomSliceable> mSliceableCache;

    public CustomSliceManager(Context context) {
        mContext = context.getApplicationContext();
        mUriMap = new ArrayMap<>();
        mSliceableCache = new WeakHashMap<>();
        addSlices();
    }

@@ -53,13 +57,18 @@ public class CustomSliceManager {
     * the only thing that should be needed to create the object.
     */
    public CustomSliceable getSliceableFromUri(Uri uri) {
        final Class clazz = mUriMap.get(uri);
        if (mSliceableCache.containsKey(uri)) {
            return mSliceableCache.get(uri);
        }

        final Class clazz = mUriMap.get(uri);
        if (clazz == null) {
            throw new IllegalArgumentException("No Slice found for uri: " + uri);
        }

        return CustomSliceable.createInstance(mContext, clazz);
        final CustomSliceable sliceable = CustomSliceable.createInstance(mContext, clazz);
        mSliceableCache.put(uri, sliceable);
        return sliceable;
    }

    /**
@@ -93,5 +102,6 @@ public class CustomSliceManager {
        mUriMap.put(DataUsageSlice.DATA_USAGE_CARD_URI, DataUsageSlice.class);
        mUriMap.put(DeviceInfoSlice.DEVICE_INFO_CARD_URI, DeviceInfoSlice.class);
        mUriMap.put(StorageSlice.STORAGE_CARD_URI, StorageSlice.class);
        mUriMap.put(BatterySlice.BATTERY_CARD_URI, BatterySlice.class);
    }
}
Loading