Merge "Separate power warnings UI from state calculation."
This commit is contained in:
committed by
Android (Google) Code Review
commit
6dd48a4e54
@@ -0,0 +1,218 @@
|
||||
/*
|
||||
* Copyright (C) 2014 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.systemui.power;
|
||||
|
||||
import android.app.AlertDialog;
|
||||
import android.content.ContentResolver;
|
||||
import android.content.Context;
|
||||
import android.content.DialogInterface;
|
||||
import android.content.Intent;
|
||||
import android.media.AudioManager;
|
||||
import android.media.Ringtone;
|
||||
import android.media.RingtoneManager;
|
||||
import android.net.Uri;
|
||||
import android.os.SystemClock;
|
||||
import android.os.UserHandle;
|
||||
import android.provider.Settings;
|
||||
import android.util.Slog;
|
||||
import android.view.View;
|
||||
import android.view.WindowManager;
|
||||
import android.widget.TextView;
|
||||
|
||||
import com.android.systemui.R;
|
||||
|
||||
import java.io.PrintWriter;
|
||||
|
||||
public class PowerDialogWarnings implements PowerUI.WarningsUI {
|
||||
private static final String TAG = PowerUI.TAG + ".Dialog";
|
||||
private static final boolean DEBUG = PowerUI.DEBUG;
|
||||
|
||||
private final Context mContext;
|
||||
|
||||
private int mBatteryLevel;
|
||||
private int mBucket;
|
||||
private long mScreenOffTime;
|
||||
|
||||
private AlertDialog mInvalidChargerDialog;
|
||||
private AlertDialog mLowBatteryDialog;
|
||||
private TextView mBatteryLevelTextView;
|
||||
|
||||
public PowerDialogWarnings(Context context) {
|
||||
mContext = context;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void dump(PrintWriter pw) {
|
||||
pw.print("mInvalidChargerDialog=");
|
||||
pw.println(mInvalidChargerDialog == null ? "null" : mInvalidChargerDialog.toString());
|
||||
pw.print("mLowBatteryDialog=");
|
||||
pw.println(mLowBatteryDialog == null ? "null" : mLowBatteryDialog.toString());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void update(int batteryLevel, int bucket, long screenOffTime) {
|
||||
mBatteryLevel = batteryLevel;
|
||||
mBucket = bucket;
|
||||
mScreenOffTime = screenOffTime;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isInvalidChargerWarningShowing() {
|
||||
return mInvalidChargerDialog != null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateLowBatteryWarning() {
|
||||
if (mBatteryLevelTextView != null) {
|
||||
showLowBatteryWarning(false /*playSound*/);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void dismissLowBatteryWarning() {
|
||||
if (mLowBatteryDialog != null) {
|
||||
Slog.i(TAG, "closing low battery warning: level=" + mBatteryLevel);
|
||||
mLowBatteryDialog.dismiss();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void showLowBatteryWarning(boolean playSound) {
|
||||
Slog.i(TAG,
|
||||
((mBatteryLevelTextView == null) ? "showing" : "updating")
|
||||
+ " low battery warning: level=" + mBatteryLevel
|
||||
+ " [" + mBucket + "]");
|
||||
|
||||
CharSequence levelText = mContext.getString(
|
||||
R.string.battery_low_percent_format, mBatteryLevel);
|
||||
|
||||
if (mBatteryLevelTextView != null) {
|
||||
mBatteryLevelTextView.setText(levelText);
|
||||
} else {
|
||||
View v = View.inflate(mContext, R.layout.battery_low, null);
|
||||
mBatteryLevelTextView = (TextView)v.findViewById(R.id.level_percent);
|
||||
|
||||
mBatteryLevelTextView.setText(levelText);
|
||||
|
||||
AlertDialog.Builder b = new AlertDialog.Builder(mContext);
|
||||
b.setCancelable(true);
|
||||
b.setTitle(R.string.battery_low_title);
|
||||
b.setView(v);
|
||||
b.setIconAttribute(android.R.attr.alertDialogIcon);
|
||||
b.setPositiveButton(android.R.string.ok, null);
|
||||
|
||||
final Intent intent = new Intent(Intent.ACTION_POWER_USAGE_SUMMARY);
|
||||
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK
|
||||
| Intent.FLAG_ACTIVITY_MULTIPLE_TASK
|
||||
| Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS
|
||||
| Intent.FLAG_ACTIVITY_NO_HISTORY);
|
||||
if (intent.resolveActivity(mContext.getPackageManager()) != null) {
|
||||
b.setNegativeButton(R.string.battery_low_why,
|
||||
new DialogInterface.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(DialogInterface dialog, int which) {
|
||||
mContext.startActivityAsUser(intent, UserHandle.CURRENT);
|
||||
dismissLowBatteryWarning();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
AlertDialog d = b.create();
|
||||
d.setOnDismissListener(new DialogInterface.OnDismissListener() {
|
||||
@Override
|
||||
public void onDismiss(DialogInterface dialog) {
|
||||
mLowBatteryDialog = null;
|
||||
mBatteryLevelTextView = null;
|
||||
}
|
||||
});
|
||||
d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ALERT);
|
||||
d.getWindow().getAttributes().privateFlags |=
|
||||
WindowManager.LayoutParams.PRIVATE_FLAG_SHOW_FOR_ALL_USERS;
|
||||
d.show();
|
||||
mLowBatteryDialog = d;
|
||||
if (playSound) {
|
||||
playLowBatterySound();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void playLowBatterySound() {
|
||||
final ContentResolver cr = mContext.getContentResolver();
|
||||
|
||||
final int silenceAfter = Settings.Global.getInt(cr,
|
||||
Settings.Global.LOW_BATTERY_SOUND_TIMEOUT, 0);
|
||||
final long offTime = SystemClock.elapsedRealtime() - mScreenOffTime;
|
||||
if (silenceAfter > 0
|
||||
&& mScreenOffTime > 0
|
||||
&& offTime > silenceAfter) {
|
||||
Slog.i(TAG, "screen off too long (" + offTime + "ms, limit " + silenceAfter
|
||||
+ "ms): not waking up the user with low battery sound");
|
||||
return;
|
||||
}
|
||||
|
||||
if (DEBUG) {
|
||||
Slog.d(TAG, "playing low battery sound. pick-a-doop!"); // WOMP-WOMP is deprecated
|
||||
}
|
||||
|
||||
if (Settings.Global.getInt(cr, Settings.Global.POWER_SOUNDS_ENABLED, 1) == 1) {
|
||||
final String soundPath = Settings.Global.getString(cr,
|
||||
Settings.Global.LOW_BATTERY_SOUND);
|
||||
if (soundPath != null) {
|
||||
final Uri soundUri = Uri.parse("file://" + soundPath);
|
||||
if (soundUri != null) {
|
||||
final Ringtone sfx = RingtoneManager.getRingtone(mContext, soundUri);
|
||||
if (sfx != null) {
|
||||
sfx.setStreamType(AudioManager.STREAM_SYSTEM);
|
||||
sfx.play();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void dismissInvalidChargerWarning() {
|
||||
if (mInvalidChargerDialog != null) {
|
||||
mInvalidChargerDialog.dismiss();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void showInvalidChargerWarning() {
|
||||
Slog.d(TAG, "showing invalid charger dialog");
|
||||
|
||||
dismissLowBatteryWarning();
|
||||
|
||||
AlertDialog.Builder b = new AlertDialog.Builder(mContext);
|
||||
b.setCancelable(true);
|
||||
b.setMessage(R.string.invalid_charger);
|
||||
b.setIconAttribute(android.R.attr.alertDialogIcon);
|
||||
b.setPositiveButton(android.R.string.ok, null);
|
||||
|
||||
AlertDialog d = b.create();
|
||||
d.setOnDismissListener(new DialogInterface.OnDismissListener() {
|
||||
public void onDismiss(DialogInterface dialog) {
|
||||
mInvalidChargerDialog = null;
|
||||
mBatteryLevelTextView = null;
|
||||
}
|
||||
});
|
||||
|
||||
d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ALERT);
|
||||
d.show();
|
||||
mInvalidChargerDialog = d;
|
||||
}
|
||||
}
|
||||
@@ -16,29 +16,17 @@
|
||||
|
||||
package com.android.systemui.power;
|
||||
|
||||
import android.app.AlertDialog;
|
||||
import android.content.BroadcastReceiver;
|
||||
import android.content.ContentResolver;
|
||||
import android.content.Context;
|
||||
import android.content.DialogInterface;
|
||||
import android.content.Intent;
|
||||
import android.content.IntentFilter;
|
||||
import android.media.AudioManager;
|
||||
import android.media.Ringtone;
|
||||
import android.media.RingtoneManager;
|
||||
import android.net.Uri;
|
||||
import android.os.BatteryManager;
|
||||
import android.os.Handler;
|
||||
import android.os.PowerManager;
|
||||
import android.os.SystemClock;
|
||||
import android.os.UserHandle;
|
||||
import android.provider.Settings;
|
||||
import android.util.Slog;
|
||||
import android.view.View;
|
||||
import android.view.WindowManager;
|
||||
import android.widget.TextView;
|
||||
|
||||
import com.android.systemui.R;
|
||||
import com.android.systemui.SystemUI;
|
||||
|
||||
import java.io.FileDescriptor;
|
||||
@@ -50,19 +38,17 @@ public class PowerUI extends SystemUI {
|
||||
|
||||
static final boolean DEBUG = false;
|
||||
|
||||
Handler mHandler = new Handler();
|
||||
private WarningsUI mWarnings;
|
||||
|
||||
int mBatteryLevel = 100;
|
||||
int mBatteryStatus = BatteryManager.BATTERY_STATUS_UNKNOWN;
|
||||
int mPlugType = 0;
|
||||
int mInvalidCharger = 0;
|
||||
private final Handler mHandler = new Handler();
|
||||
|
||||
int mLowBatteryAlertCloseLevel;
|
||||
int[] mLowBatteryReminderLevels = new int[2];
|
||||
private int mBatteryLevel = 100;
|
||||
private int mBatteryStatus = BatteryManager.BATTERY_STATUS_UNKNOWN;
|
||||
private int mPlugType = 0;
|
||||
private int mInvalidCharger = 0;
|
||||
|
||||
AlertDialog mInvalidChargerDialog;
|
||||
AlertDialog mLowBatteryDialog;
|
||||
TextView mBatteryLevelTextView;
|
||||
private int mLowBatteryAlertCloseLevel;
|
||||
private final int[] mLowBatteryReminderLevels = new int[2];
|
||||
|
||||
private long mScreenOffTime = -1;
|
||||
|
||||
@@ -77,6 +63,7 @@ public class PowerUI extends SystemUI {
|
||||
|
||||
final PowerManager pm = (PowerManager) mContext.getSystemService(Context.POWER_SERVICE);
|
||||
mScreenOffTime = pm.isScreenOn() ? -1 : SystemClock.elapsedRealtime();
|
||||
mWarnings = new PowerDialogWarnings(mContext);
|
||||
|
||||
// Register for Intent broadcasts for...
|
||||
IntentFilter filter = new IntentFilter();
|
||||
@@ -145,13 +132,14 @@ public class PowerUI extends SystemUI {
|
||||
Slog.d(TAG, "plugged " + oldPlugged + " --> " + plugged);
|
||||
}
|
||||
|
||||
mWarnings.update(mBatteryLevel, bucket, mScreenOffTime);
|
||||
if (oldInvalidCharger == 0 && mInvalidCharger != 0) {
|
||||
Slog.d(TAG, "showing invalid charger warning");
|
||||
showInvalidChargerDialog();
|
||||
mWarnings.showInvalidChargerWarning();
|
||||
return;
|
||||
} else if (oldInvalidCharger != 0 && mInvalidCharger == 0) {
|
||||
dismissInvalidChargerDialog();
|
||||
} else if (mInvalidChargerDialog != null) {
|
||||
mWarnings.dismissInvalidChargerWarning();
|
||||
} else if (mWarnings.isInvalidChargerWarningShowing()) {
|
||||
// if invalid charger is showing, don't show low battery
|
||||
return;
|
||||
}
|
||||
@@ -160,16 +148,13 @@ public class PowerUI extends SystemUI {
|
||||
&& (bucket < oldBucket || oldPlugged)
|
||||
&& mBatteryStatus != BatteryManager.BATTERY_STATUS_UNKNOWN
|
||||
&& bucket < 0) {
|
||||
showLowBatteryWarning();
|
||||
|
||||
// only play SFX when the dialog comes up or the bucket changes
|
||||
if (bucket != oldBucket || oldPlugged) {
|
||||
playLowBatterySound();
|
||||
}
|
||||
final boolean playSound = bucket != oldBucket || oldPlugged;
|
||||
mWarnings.showLowBatteryWarning(playSound);
|
||||
} else if (plugged || (bucket > oldBucket && bucket > 0)) {
|
||||
dismissLowBatteryWarning();
|
||||
} else if (mBatteryLevelTextView != null) {
|
||||
showLowBatteryWarning();
|
||||
mWarnings.dismissLowBatteryWarning();
|
||||
} else {
|
||||
mWarnings.updateLowBatteryWarning();
|
||||
}
|
||||
} else if (Intent.ACTION_SCREEN_OFF.equals(action)) {
|
||||
mScreenOffTime = SystemClock.elapsedRealtime();
|
||||
@@ -181,142 +166,11 @@ public class PowerUI extends SystemUI {
|
||||
}
|
||||
};
|
||||
|
||||
void dismissLowBatteryWarning() {
|
||||
if (mLowBatteryDialog != null) {
|
||||
Slog.i(TAG, "closing low battery warning: level=" + mBatteryLevel);
|
||||
mLowBatteryDialog.dismiss();
|
||||
}
|
||||
}
|
||||
|
||||
void showLowBatteryWarning() {
|
||||
Slog.i(TAG,
|
||||
((mBatteryLevelTextView == null) ? "showing" : "updating")
|
||||
+ " low battery warning: level=" + mBatteryLevel
|
||||
+ " [" + findBatteryLevelBucket(mBatteryLevel) + "]");
|
||||
|
||||
CharSequence levelText = mContext.getString(
|
||||
R.string.battery_low_percent_format, mBatteryLevel);
|
||||
|
||||
if (mBatteryLevelTextView != null) {
|
||||
mBatteryLevelTextView.setText(levelText);
|
||||
} else {
|
||||
View v = View.inflate(mContext, R.layout.battery_low, null);
|
||||
mBatteryLevelTextView = (TextView)v.findViewById(R.id.level_percent);
|
||||
|
||||
mBatteryLevelTextView.setText(levelText);
|
||||
|
||||
AlertDialog.Builder b = new AlertDialog.Builder(mContext);
|
||||
b.setCancelable(true);
|
||||
b.setTitle(R.string.battery_low_title);
|
||||
b.setView(v);
|
||||
b.setIconAttribute(android.R.attr.alertDialogIcon);
|
||||
b.setPositiveButton(android.R.string.ok, null);
|
||||
|
||||
final Intent intent = new Intent(Intent.ACTION_POWER_USAGE_SUMMARY);
|
||||
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK
|
||||
| Intent.FLAG_ACTIVITY_MULTIPLE_TASK
|
||||
| Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS
|
||||
| Intent.FLAG_ACTIVITY_NO_HISTORY);
|
||||
if (intent.resolveActivity(mContext.getPackageManager()) != null) {
|
||||
b.setNegativeButton(R.string.battery_low_why,
|
||||
new DialogInterface.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(DialogInterface dialog, int which) {
|
||||
mContext.startActivityAsUser(intent, UserHandle.CURRENT);
|
||||
dismissLowBatteryWarning();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
AlertDialog d = b.create();
|
||||
d.setOnDismissListener(new DialogInterface.OnDismissListener() {
|
||||
@Override
|
||||
public void onDismiss(DialogInterface dialog) {
|
||||
mLowBatteryDialog = null;
|
||||
mBatteryLevelTextView = null;
|
||||
}
|
||||
});
|
||||
d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ALERT);
|
||||
d.getWindow().getAttributes().privateFlags |=
|
||||
WindowManager.LayoutParams.PRIVATE_FLAG_SHOW_FOR_ALL_USERS;
|
||||
d.show();
|
||||
mLowBatteryDialog = d;
|
||||
}
|
||||
}
|
||||
|
||||
void playLowBatterySound() {
|
||||
final ContentResolver cr = mContext.getContentResolver();
|
||||
|
||||
final int silenceAfter = Settings.Global.getInt(cr,
|
||||
Settings.Global.LOW_BATTERY_SOUND_TIMEOUT, 0);
|
||||
final long offTime = SystemClock.elapsedRealtime() - mScreenOffTime;
|
||||
if (silenceAfter > 0
|
||||
&& mScreenOffTime > 0
|
||||
&& offTime > silenceAfter) {
|
||||
Slog.i(TAG, "screen off too long (" + offTime + "ms, limit " + silenceAfter
|
||||
+ "ms): not waking up the user with low battery sound");
|
||||
return;
|
||||
}
|
||||
|
||||
if (DEBUG) {
|
||||
Slog.d(TAG, "playing low battery sound. pick-a-doop!"); // WOMP-WOMP is deprecated
|
||||
}
|
||||
|
||||
if (Settings.Global.getInt(cr, Settings.Global.POWER_SOUNDS_ENABLED, 1) == 1) {
|
||||
final String soundPath = Settings.Global.getString(cr,
|
||||
Settings.Global.LOW_BATTERY_SOUND);
|
||||
if (soundPath != null) {
|
||||
final Uri soundUri = Uri.parse("file://" + soundPath);
|
||||
if (soundUri != null) {
|
||||
final Ringtone sfx = RingtoneManager.getRingtone(mContext, soundUri);
|
||||
if (sfx != null) {
|
||||
sfx.setStreamType(AudioManager.STREAM_SYSTEM);
|
||||
sfx.play();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void dismissInvalidChargerDialog() {
|
||||
if (mInvalidChargerDialog != null) {
|
||||
mInvalidChargerDialog.dismiss();
|
||||
}
|
||||
}
|
||||
|
||||
void showInvalidChargerDialog() {
|
||||
Slog.d(TAG, "showing invalid charger dialog");
|
||||
|
||||
dismissLowBatteryWarning();
|
||||
|
||||
AlertDialog.Builder b = new AlertDialog.Builder(mContext);
|
||||
b.setCancelable(true);
|
||||
b.setMessage(R.string.invalid_charger);
|
||||
b.setIconAttribute(android.R.attr.alertDialogIcon);
|
||||
b.setPositiveButton(android.R.string.ok, null);
|
||||
|
||||
AlertDialog d = b.create();
|
||||
d.setOnDismissListener(new DialogInterface.OnDismissListener() {
|
||||
public void onDismiss(DialogInterface dialog) {
|
||||
mInvalidChargerDialog = null;
|
||||
mBatteryLevelTextView = null;
|
||||
}
|
||||
});
|
||||
|
||||
d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ALERT);
|
||||
d.show();
|
||||
mInvalidChargerDialog = d;
|
||||
}
|
||||
|
||||
public void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
|
||||
pw.print("mLowBatteryAlertCloseLevel=");
|
||||
pw.println(mLowBatteryAlertCloseLevel);
|
||||
pw.print("mLowBatteryReminderLevels=");
|
||||
pw.println(Arrays.toString(mLowBatteryReminderLevels));
|
||||
pw.print("mInvalidChargerDialog=");
|
||||
pw.println(mInvalidChargerDialog == null ? "null" : mInvalidChargerDialog.toString());
|
||||
pw.print("mLowBatteryDialog=");
|
||||
pw.println(mLowBatteryDialog == null ? "null" : mLowBatteryDialog.toString());
|
||||
pw.print("mBatteryLevel=");
|
||||
pw.println(Integer.toString(mBatteryLevel));
|
||||
pw.print("mBatteryStatus=");
|
||||
@@ -338,6 +192,18 @@ public class PowerUI extends SystemUI {
|
||||
Settings.Global.LOW_BATTERY_SOUND_TIMEOUT, 0));
|
||||
pw.print("bucket: ");
|
||||
pw.println(Integer.toString(findBatteryLevelBucket(mBatteryLevel)));
|
||||
mWarnings.dump(pw);
|
||||
}
|
||||
|
||||
public interface WarningsUI {
|
||||
void update(int batteryLevel, int bucket, long screenOffTime);
|
||||
void dismissLowBatteryWarning();
|
||||
void showLowBatteryWarning(boolean playSound);
|
||||
void dismissInvalidChargerWarning();
|
||||
void showInvalidChargerWarning();
|
||||
void updateLowBatteryWarning();
|
||||
boolean isInvalidChargerWarningShowing();
|
||||
void dump(PrintWriter pw);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user