Merge "DO NOT MERGE Make "Want to start battery saver?" dialog better." into pi-dev

This commit is contained in:
Makoto Onuki
2018-04-25 16:58:20 +00:00
committed by Android (Google) Code Review
6 changed files with 148 additions and 6 deletions

View File

@@ -16,8 +16,6 @@
package android.app;
import com.android.internal.app.AlertController;
import android.annotation.ArrayRes;
import android.annotation.AttrRes;
import android.annotation.DrawableRes;
@@ -30,17 +28,19 @@ import android.database.Cursor;
import android.graphics.drawable.Drawable;
import android.os.Bundle;
import android.os.Message;
import android.text.Layout;
import android.text.method.MovementMethod;
import android.util.TypedValue;
import android.view.ContextThemeWrapper;
import android.view.KeyEvent;
import android.view.View;
import android.view.WindowManager;
import android.widget.AdapterView;
import android.widget.Button;
import android.widget.ListAdapter;
import android.widget.ListView;
import com.android.internal.R;
import com.android.internal.app.AlertController;
/**
* A subclass of Dialog that can display one, two or three buttons. If you only want to
@@ -54,7 +54,7 @@ import com.android.internal.R;
* </pre>
*
* <p>The AlertDialog class takes care of automatically setting
* {@link WindowManager.LayoutParams#FLAG_ALT_FOCUSABLE_IM
* {@link android.view.WindowManager.LayoutParams#FLAG_ALT_FOCUSABLE_IM
* WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM} for you based on whether
* any views in the dialog return true from {@link View#onCheckIsTextEditor()
* View.onCheckIsTextEditor()}. Generally you want this set for a Dialog
@@ -266,6 +266,17 @@ public class AlertDialog extends Dialog implements DialogInterface {
mAlert.setMessage(message);
}
/** @hide */
public void setMessageMovementMethod(MovementMethod movementMethod) {
mAlert.setMessageMovementMethod(movementMethod);
}
/** @hide */
public void setMessageHyphenationFrequency(
@Layout.HyphenationFrequency int hyphenationFrequency) {
mAlert.setMessageHyphenationFrequency(hyphenationFrequency);
}
/**
* Set the view to display in that dialog.
*/

View File

@@ -30,7 +30,10 @@ import android.database.Cursor;
import android.graphics.drawable.Drawable;
import android.os.Handler;
import android.os.Message;
import android.text.Layout;
import android.text.TextUtils;
import android.text.method.LinkMovementMethod;
import android.text.method.MovementMethod;
import android.util.AttributeSet;
import android.util.TypedValue;
import android.view.Gravity;
@@ -101,6 +104,9 @@ public class AlertController {
private ImageView mIconView;
private TextView mTitleView;
protected TextView mMessageView;
private MovementMethod mMessageMovementMethod;
@Layout.HyphenationFrequency
private Integer mMessageHyphenationFrequency;
private View mCustomTitleView;
private boolean mForceInverseBackground;
@@ -290,6 +296,21 @@ public class AlertController {
}
}
public void setMessageMovementMethod(MovementMethod movementMethod) {
mMessageMovementMethod = movementMethod;
if (mMessageView != null) {
mMessageView.setMovementMethod(movementMethod);
}
}
public void setMessageHyphenationFrequency(
@Layout.HyphenationFrequency int hyphenationFrequency) {
mMessageHyphenationFrequency = hyphenationFrequency;
if (mMessageView != null) {
mMessageView.setHyphenationFrequency(hyphenationFrequency);
}
}
/**
* Set the view resource to display in the dialog.
*/
@@ -676,6 +697,12 @@ public class AlertController {
if (mMessage != null) {
mMessageView.setText(mMessage);
if (mMessageMovementMethod != null) {
mMessageView.setMovementMethod(mMessageMovementMethod);
}
if (mMessageHyphenationFrequency != null) {
mMessageView.setHyphenationFrequency(mMessageHyphenationFrequency);
}
} else {
mMessageView.setVisibility(View.GONE);
mScrollView.removeView(mMessageView);

View File

@@ -4514,7 +4514,10 @@
<!-- Notification shown when device owner silently deletes a package [CHAR LIMIT=NONE] -->
<string name="package_deleted_device_owner">Deleted by your admin</string>
<!-- [CHAR_LIMIT=NONE] Battery saver: Feature description -->
<!-- [CHAR_LIMIT=NONE] Battery saver: Feature description, with a "learn more" link. -->
<string name="battery_saver_description_with_learn_more">To extend your battery life, Battery Saver turns off some device features and restricts apps. <annotation id="url">Learn More</annotation></string>
<!-- [CHAR_LIMIT=NONE] Battery saver: Feature description, without a "learn more" link. -->
<string name="battery_saver_description">To extend your battery life, Battery Saver turns off some device features and restricts apps.</string>
<!-- [CHAR_LIMIT=NONE] Data saver: Feature description -->

View File

@@ -3369,4 +3369,5 @@
<java-symbol type="id" name="user_loading_avatar" />
<java-symbol type="id" name="user_loading" />
<java-symbol type="string" name="battery_saver_description_with_learn_more" />
</resources>

View File

@@ -2223,4 +2223,6 @@
<!-- An action on the dialog that tells that scheduled (i.e. automatic) battery saver: user acknowledges and closes the dialog. [CHAR LIMIT=NONE]-->
<string name="auto_saver_okay_action">Got it</string>
<!-- URl of the webpage that explains battery saver. -->
<string name="help_uri_battery_saver_learn_more_link_target" translatable="false"></string>
</resources>

View File

@@ -19,17 +19,29 @@ package com.android.systemui.power;
import android.app.Notification;
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.content.ActivityNotFoundException;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.media.AudioAttributes;
import android.net.Uri;
import android.os.Handler;
import android.os.Looper;
import android.os.PowerManager;
import android.os.UserHandle;
import android.support.annotation.VisibleForTesting;
import android.text.Annotation;
import android.text.Layout;
import android.text.SpannableString;
import android.text.SpannableStringBuilder;
import android.text.TextPaint;
import android.text.TextUtils;
import android.text.method.LinkMovementMethod;
import android.text.style.URLSpan;
import android.util.Log;
import android.util.Slog;
import android.view.View;
import com.android.internal.messages.nano.SystemMessageProto.SystemMessage;
import com.android.settingslib.Utils;
@@ -42,6 +54,8 @@ import com.android.systemui.util.NotificationChannels;
import java.io.PrintWriter;
import java.text.NumberFormat;
import java.util.Locale;
import java.util.Objects;
public class PowerNotificationWarnings implements PowerUI.WarningsUI {
private static final String TAG = PowerUI.TAG + ".Notification";
@@ -87,6 +101,8 @@ public class PowerNotificationWarnings implements PowerUI.WarningsUI {
private static final String SETTINGS_ACTION_OPEN_BATTERY_SAVER_SETTING =
"android.settings.BATTERY_SAVER_SETTINGS";
private static final String BATTERY_SAVER_DESCRIPTION_URL_KEY = "url";
private static final AudioAttributes AUDIO_ATTRIBUTES = new AudioAttributes.Builder()
.setContentType(AudioAttributes.CONTENT_TYPE_SONIFICATION)
.setUsage(AudioAttributes.USAGE_ASSISTANCE_SONIFICATION)
@@ -461,7 +477,16 @@ public class PowerNotificationWarnings implements PowerUI.WarningsUI {
if (mSaverConfirmation != null) return;
final SystemUIDialog d = new SystemUIDialog(mContext);
d.setTitle(R.string.battery_saver_confirmation_title);
d.setMessage(com.android.internal.R.string.battery_saver_description);
d.setMessage(getBatterySaverDescription());
// Sad hack for http://b/78261259 and http://b/78298335. Otherwise "Battery" may be split
// into "Bat-tery".
if (isEnglishLocale()) {
d.setMessageHyphenationFrequency(Layout.HYPHENATION_FREQUENCY_NONE);
}
// We need to set LinkMovementMethod to make the link clickable.
d.setMessageMovementMethod(LinkMovementMethod.getInstance());
d.setNegativeButton(android.R.string.cancel, null);
d.setPositiveButton(R.string.battery_saver_confirmation_ok,
(dialog, which) -> setSaverMode(true, false));
@@ -471,6 +496,79 @@ public class PowerNotificationWarnings implements PowerUI.WarningsUI {
mSaverConfirmation = d;
}
private boolean isEnglishLocale() {
return Objects.equals(Locale.getDefault().getLanguage(),
Locale.ENGLISH.getLanguage());
}
/**
* Generates the message for the "want to start battery saver?" dialog with a "learn more" link.
*/
private CharSequence getBatterySaverDescription() {
final String learnMoreUrl = mContext.getText(
R.string.help_uri_battery_saver_learn_more_link_target).toString();
// If there's no link, use the string with no "learn more".
if (TextUtils.isEmpty(learnMoreUrl)) {
return mContext.getText(
com.android.internal.R.string.battery_saver_description);
}
// If we have a link, use the string with the "learn more" link.
final CharSequence rawText = mContext.getText(
com.android.internal.R.string.battery_saver_description_with_learn_more);
final SpannableString message = new SpannableString(rawText);
final SpannableStringBuilder builder = new SpannableStringBuilder(message);
// Look for the "learn more" part of the string, and set a URL span on it.
// We use a customized URLSpan to add FLAG_RECEIVER_FOREGROUND to the intent, and
// also to close the dialog.
for (Annotation annotation : message.getSpans(0, message.length(), Annotation.class)) {
final String key = annotation.getValue();
if (!BATTERY_SAVER_DESCRIPTION_URL_KEY.equals(key)) {
continue;
}
final int start = message.getSpanStart(annotation);
final int end = message.getSpanEnd(annotation);
// Replace the "learn more" with a custom URL span, with
// - No underline.
// - When clicked, close the dialog and the notification shade.
final URLSpan urlSpan = new URLSpan(learnMoreUrl) {
@Override
public void updateDrawState(TextPaint ds) {
super.updateDrawState(ds);
ds.setUnderlineText(false);
}
@Override
public void onClick(View widget) {
// Close the parent dialog.
if (mSaverConfirmation != null) {
mSaverConfirmation.dismiss();
}
// Also close the notification shade, if it's open.
mContext.sendBroadcast(
new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS)
.setFlags(Intent.FLAG_RECEIVER_FOREGROUND));
final Uri uri = Uri.parse(getURL());
Context context = widget.getContext();
Intent intent = new Intent(Intent.ACTION_VIEW, uri)
.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
try {
context.startActivity(intent);
} catch (ActivityNotFoundException e) {
Log.w(TAG, "Activity was not found for intent, " + intent.toString());
}
}
};
builder.setSpan(urlSpan, start, end, message.getSpanFlags(urlSpan));
}
return builder;
}
private void showAutoSaverEnabledConfirmation() {
if (mSaverEnabledConfirmation != null) return;