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

Commit 3a3f8225 authored by Salvador Martinez's avatar Salvador Martinez
Browse files

Show notification when routine battery mode activates

We don't want users to get confused if they turn on routine
battery mode and forget. So we show a notification that tells them
why it was turned on to avoid confusion.

Test: trigger early warning via adb and see notification
Bug: 111450127
Change-Id: I62d6fc945d6c7d89f0950e02ebd2cfa0b3ed9423
parent 72efe39d
Loading
Loading
Loading
Loading
+25 −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.
-->
<vector xmlns:android="http://schemas.android.com/apk/res/android"
        android:width="24dp"
        android:height="24dp"
        android:viewportWidth="24.0"
        android:viewportHeight="24.0"
        android:tint="?android:attr/colorControlNormal">
    <path
        android:fillColor="#FF000000"
        android:pathData="M15.67,4H14V2h-4v2H8.33C7.6,4 7,4.6 7,5.33v15.33C7,21.4 7.6,22 8.33,22h7.33c0.74,0 1.34,-0.6 1.34,-1.33V5.33C17,4.6 16.4,4 15.67,4z"/>
</vector>
+9 −0
Original line number Diff line number Diff line
@@ -5238,6 +5238,15 @@
    <!-- Content description of the overlay icon in the notification. [CHAR LIMIT=NONE] -->
    <string name="notification_appops_overlay_active">displaying over other apps on your screen</string>

    <!-- Dynamic mode battery saver strings -->
    <!-- The user visible name of the notification channel for the routine mode battery saver fyi notification [CHAR_LIMIT=80]-->
    <string name="dynamic_mode_notification_channel_name">Routine Mode info notification</string>
    <!-- Title of notification letting users know why battery saver was turned on automatically [CHAR_LIMIT=NONE]-->
    <string name="dynamic_mode_notification_title">Battery may run out before usual charge</string>
    <!-- Summary of notification letting users know why battery saver was turned on automatically [CHAR_LIMIT=NONE]-->
    <string name="dynamic_mode_notification_summary">Battery Saver activated to extend battery life</string>


    <!-- Strings for car -->
    <!-- String displayed when loading a user in the car [CHAR LIMIT=30] -->
    <string name="car_loading_profile">Loading</string>
+5 −0
Original line number Diff line number Diff line
@@ -3519,4 +3519,9 @@

  <!-- For Secondary Launcher -->
  <java-symbol type="string" name="config_secondaryHomeComponent" />
  
  <java-symbol type="string" name="dynamic_mode_notification_channel_name" />
  <java-symbol type="string" name="dynamic_mode_notification_title" />
  <java-symbol type="string" name="dynamic_mode_notification_summary" />
  <java-symbol type="drawable" name="ic_battery" />
</resources>
+54 −0
Original line number Diff line number Diff line
@@ -15,8 +15,14 @@
 */
package com.android.server.power.batterysaver;

import android.app.Notification;
import android.app.NotificationChannel;
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.content.ContentResolver;
import android.content.Context;
import android.content.Intent;
import android.content.res.Resources;
import android.database.ContentObserver;
import android.os.Handler;
import android.os.PowerManager;
@@ -26,6 +32,7 @@ import android.provider.Settings.Global;
import android.util.Slog;
import android.util.proto.ProtoOutputStream;

import com.android.internal.R;
import com.android.internal.annotations.GuardedBy;
import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.os.BackgroundThread;
@@ -46,6 +53,8 @@ import java.io.PrintWriter;
 */
public class BatterySaverStateMachine {
    private static final String TAG = "BatterySaverStateMachine";
    private static final String DYNAMIC_MODE_NOTIF_CHANNEL_ID = "dynamic_mode_notification";
    private static final int DYNAMIC_MODE_NOTIFICATION_ID = 1992;
    private final Object mLock;

    private static final boolean DEBUG = BatterySaverPolicy.DEBUG;
@@ -484,6 +493,13 @@ public class BatterySaverStateMachine {
        }
        mBatterySaverController.enableBatterySaver(enable, intReason);

        // Handle triggering the notification to show/hide when appropriate
        if (intReason == BatterySaverController.REASON_DYNAMIC_POWER_SAVINGS_AUTOMATIC_ON) {
            runOnBgThread(this::triggerDynamicModeNotification);
        } else if (!enable) {
            runOnBgThread(this::hideDynamicModeNotification);
        }

        if (DEBUG) {
            Slog.d(TAG, "Battery saver: Enabled=" + enable
                    + " manual=" + manual
@@ -491,6 +507,44 @@ public class BatterySaverStateMachine {
        }
    }

    private void triggerDynamicModeNotification() {
        NotificationManager manager = mContext.getSystemService(NotificationManager.class);
        ensureNotificationChannelExists(manager);

        manager.notify(DYNAMIC_MODE_NOTIFICATION_ID, buildNotification());
    }

    private void ensureNotificationChannelExists(NotificationManager manager) {
        NotificationChannel channel = new NotificationChannel(
                DYNAMIC_MODE_NOTIF_CHANNEL_ID,
                mContext.getText(
                        R.string.dynamic_mode_notification_channel_name),
                NotificationManager.IMPORTANCE_DEFAULT);
        channel.setSound(null, null);
        manager.createNotificationChannel(channel);
    }

    private Notification buildNotification() {
        Resources res = mContext.getResources();
        Intent intent = new Intent(Intent.ACTION_POWER_USAGE_SUMMARY);
        intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK);
        PendingIntent batterySaverIntent = PendingIntent.getActivity(
                mContext, 0 /* requestCode */, intent, PendingIntent.FLAG_UPDATE_CURRENT);

        return new Notification.Builder(mContext, DYNAMIC_MODE_NOTIF_CHANNEL_ID)
                .setSmallIcon(R.drawable.ic_battery)
                .setContentTitle(res.getString(R.string.dynamic_mode_notification_title))
                .setContentText(res.getString(R.string.dynamic_mode_notification_summary))
                .setContentIntent(batterySaverIntent)
                .setOnlyAlertOnce(true)
                .build();
    }

    private void hideDynamicModeNotification() {
        NotificationManager manager = mContext.getSystemService(NotificationManager.class);
        manager.cancel(DYNAMIC_MODE_NOTIFICATION_ID);
    }

    @GuardedBy("mLock")
    private void updateSnoozingLocked(boolean snoozing, String reason) {
        if (mBatterySaverSnoozing == snoozing) {
+1 −1

File changed.

Contains only whitespace changes.