summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--core/java/android/content/pm/PackageParser.java14
-rw-r--r--core/java/android/provider/Settings.java64
-rw-r--r--core/res/res/values/config.xml1
-rw-r--r--core/tests/coretests/src/android/provider/SettingsBackupTest.java9
-rw-r--r--packages/SettingsLib/src/com/android/settingslib/fuelgauge/BatterySaverUtils.java3
-rw-r--r--packages/SettingsLib/src/com/android/settingslib/fuelgauge/Estimate.kt81
-rw-r--r--packages/SystemUI/src/com/android/systemui/bubbles/BubbleController.java38
-rw-r--r--packages/SystemUI/src/com/android/systemui/power/BatteryStateSnapshot.kt26
-rw-r--r--packages/SystemUI/src/com/android/systemui/power/EnhancedEstimates.java2
-rw-r--r--packages/SystemUI/src/com/android/systemui/power/EnhancedEstimatesImpl.java2
-rw-r--r--packages/SystemUI/src/com/android/systemui/power/Estimate.kt3
-rw-r--r--packages/SystemUI/src/com/android/systemui/power/PowerUI.java5
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/KeyguardAffordanceView.java10
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationInterruptionStateProvider.java18
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardBottomAreaView.java15
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelView.java1
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/policy/BatteryControllerImpl.java2
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/bubbles/BubbleControllerTest.java43
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/power/PowerUITest.java16
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/statusbar/NotificationTestHelper.java5
-rw-r--r--services/core/java/com/android/server/policy/PhoneWindowManager.java126
21 files changed, 381 insertions, 103 deletions
diff --git a/core/java/android/content/pm/PackageParser.java b/core/java/android/content/pm/PackageParser.java
index 0ea5200d202a..1784d8ad3c6c 100644
--- a/core/java/android/content/pm/PackageParser.java
+++ b/core/java/android/content/pm/PackageParser.java
@@ -8447,6 +8447,20 @@ public class PackageParser {
// Collect certificates
if ((flags & PackageManager.GET_SIGNING_CERTIFICATES) != 0) {
collectCertificates(p, apexFile, false);
+ // Keep legacy mechanism for handling signatures. While this is deprecated, it's
+ // still part of the public API and needs to be maintained
+ if (p.mSigningDetails.hasPastSigningCertificates()) {
+ // Package has included signing certificate rotation information. Return
+ // the oldest cert so that programmatic checks keep working even if unaware
+ // of key rotation.
+ pi.signatures = new Signature[1];
+ pi.signatures[0] = p.mSigningDetails.pastSigningCertificates[0];
+ } else if (p.mSigningDetails.hasSignatures()) {
+ // otherwise keep old behavior
+ int numberOfSigs = p.mSigningDetails.signatures.length;
+ pi.signatures = new Signature[numberOfSigs];
+ System.arraycopy(p.mSigningDetails.signatures, 0, pi.signatures, 0, numberOfSigs);
+ }
if (p.mSigningDetails != SigningDetails.UNKNOWN) {
// only return a valid SigningInfo if there is signing information to report
pi.signingInfo = new SigningInfo(p.mSigningDetails);
diff --git a/core/java/android/provider/Settings.java b/core/java/android/provider/Settings.java
index 83dc39e94d7a..ac59101d4090 100644
--- a/core/java/android/provider/Settings.java
+++ b/core/java/android/provider/Settings.java
@@ -12666,6 +12666,45 @@ public final class Settings {
public static final String DYNAMIC_POWER_SAVINGS_ENABLED = "dynamic_power_savings_enabled";
/**
+ * A long value indicating how much longer the system battery is estimated to last in
+ * millis. See {@link #BATTERY_ESTIMATES_LAST_UPDATE_TIME} for the last time this value
+ * was updated.
+ *
+ * @hide
+ */
+ public static final String TIME_REMAINING_ESTIMATE_MILLIS =
+ "time_remaining_estimate_millis";
+
+ /**
+ * A boolean indicating whether {@link #TIME_REMAINING_ESTIMATE_MILLIS} is based customized
+ * to the devices usage or using global models. See
+ * {@link #BATTERY_ESTIMATES_LAST_UPDATE_TIME} for the last time this value was updated.
+ *
+ * @hide
+ */
+ public static final String TIME_REMAINING_ESTIMATE_BASED_ON_USAGE =
+ "time_remaining_estimate_based_on_usage";
+
+ /**
+ * A long value indicating how long the system battery takes to deplete from 100% to 0% on
+ * average based on historical drain rates. See {@link #BATTERY_ESTIMATES_LAST_UPDATE_TIME}
+ * for the last time this value was updated.
+ *
+ * @hide
+ */
+ public static final String AVERAGE_TIME_TO_DISCHARGE = "average_time_to_discharge";
+
+ /**
+ * A long indicating the epoch time in milliseconds when
+ * {@link #TIME_REMAINING_ESTIMATE_MILLIS}, {@link #TIME_REMAINING_ESTIMATE_BASED_ON_USAGE},
+ * and {@link #AVERAGE_TIME_TO_DISCHARGE} were last updated.
+ *
+ * @hide
+ */
+ public static final String BATTERY_ESTIMATES_LAST_UPDATE_TIME =
+ "battery_estimates_last_update_time";
+
+ /**
* The max value for {@link #LOW_POWER_MODE_TRIGGER_LEVEL}. If this setting is not set
* or the value is 0, the default max will be used.
*
@@ -13531,6 +13570,28 @@ public final class Settings {
private static final Validator AWARE_ALLOWED_VALIDATOR = BOOLEAN_VALIDATOR;
/**
+ * Overrides internal R.integer.config_longPressOnPowerBehavior.
+ * Allowable values detailed in frameworks/base/core/res/res/values/config.xml.
+ * Used by PhoneWindowManager.
+ * @hide
+ */
+ public static final String POWER_BUTTON_LONG_PRESS =
+ "power_button_long_press";
+ private static final Validator POWER_BUTTON_LONG_PRESS_VALIDATOR =
+ new SettingsValidators.InclusiveIntegerRangeValidator(0, 5);
+
+ /**
+ * Overrides internal R.integer.config_veryLongPressOnPowerBehavior.
+ * Allowable values detailed in frameworks/base/core/res/res/values/config.xml.
+ * Used by PhoneWindowManager.
+ * @hide
+ */
+ public static final String POWER_BUTTON_VERY_LONG_PRESS =
+ "power_button_very_long_press";
+ private static final Validator POWER_BUTTON_VERY_LONG_PRESS_VALIDATOR =
+ new SettingsValidators.InclusiveIntegerRangeValidator(0, 1);
+
+ /**
* Settings to backup. This is here so that it's in the same place as the settings
* keys and easy to update.
*
@@ -13643,6 +13704,8 @@ public final class Settings {
WIFI_PNO_RECENCY_SORTING_ENABLED_VALIDATOR);
VALIDATORS.put(WIFI_LINK_PROBING_ENABLED, WIFI_LINK_PROBING_ENABLED_VALIDATOR);
VALIDATORS.put(AWARE_ALLOWED, AWARE_ALLOWED_VALIDATOR);
+ VALIDATORS.put(POWER_BUTTON_LONG_PRESS, POWER_BUTTON_LONG_PRESS_VALIDATOR);
+ VALIDATORS.put(POWER_BUTTON_VERY_LONG_PRESS, POWER_BUTTON_VERY_LONG_PRESS_VALIDATOR);
}
/**
@@ -14648,6 +14711,7 @@ public final class Settings {
*/
public static final String TEXT_CLASSIFIER_ACTION_MODEL_PARAMS =
"text_classifier_action_model_params";
+
}
/**
diff --git a/core/res/res/values/config.xml b/core/res/res/values/config.xml
index 9c4717b4497e..b3e94e39f30e 100644
--- a/core/res/res/values/config.xml
+++ b/core/res/res/values/config.xml
@@ -1098,6 +1098,7 @@
2 - Power off (with confirmation)
3 - Power off (without confirmation)
4 - Go to voice assist
+ 5 - Go to assistant (Settings.Secure.ASSISTANT)
-->
<integer name="config_longPressOnPowerBehavior">1</integer>
diff --git a/core/tests/coretests/src/android/provider/SettingsBackupTest.java b/core/tests/coretests/src/android/provider/SettingsBackupTest.java
index 0e94abc0dcac..a853121bac4e 100644
--- a/core/tests/coretests/src/android/provider/SettingsBackupTest.java
+++ b/core/tests/coretests/src/android/provider/SettingsBackupTest.java
@@ -130,8 +130,10 @@ public class SettingsBackupTest {
Settings.Global.AUTOFILL_MAX_PARTITIONS_SIZE,
Settings.Global.AUTOFILL_MAX_VISIBLE_DATASETS,
Settings.Global.AUTOMATIC_POWER_SAVE_MODE,
+ Settings.Global.AVERAGE_TIME_TO_DISCHARGE,
Settings.Global.BACKGROUND_ACTIVITY_STARTS_ENABLED,
Settings.Global.BATTERY_CHARGING_STATE_UPDATE_DELAY,
+ Settings.Global.BATTERY_ESTIMATES_LAST_UPDATE_TIME,
Settings.Global.BROADCAST_BG_CONSTANTS,
Settings.Global.BROADCAST_FG_CONSTANTS,
Settings.Global.BROADCAST_OFFLOAD_CONSTANTS,
@@ -462,6 +464,8 @@ public class SettingsBackupTest {
Settings.Global.TEXT_CLASSIFIER_ACTION_MODEL_PARAMS,
Settings.Global.THEATER_MODE_ON,
Settings.Global.TIME_ONLY_MODE_CONSTANTS,
+ Settings.Global.TIME_REMAINING_ESTIMATE_MILLIS,
+ Settings.Global.TIME_REMAINING_ESTIMATE_BASED_ON_USAGE,
Settings.Global.TRANSITION_ANIMATION_SCALE,
Settings.Global.TRUSTED_SOUND,
Settings.Global.TZINFO_UPDATE_CONTENT_URL,
@@ -573,7 +577,10 @@ public class SettingsBackupTest {
Settings.Global.RADIO_BUG_WAKELOCK_TIMEOUT_COUNT_THRESHOLD,
Settings.Global.RADIO_BUG_SYSTEM_ERROR_COUNT_THRESHOLD,
Settings.Global.ENABLED_SUBSCRIPTION_FOR_SLOT,
- Settings.Global.MODEM_STACK_ENABLED_FOR_SLOT);
+ Settings.Global.MODEM_STACK_ENABLED_FOR_SLOT,
+ Settings.Global.POWER_BUTTON_LONG_PRESS,
+ Settings.Global.POWER_BUTTON_VERY_LONG_PRESS);
+
private static final Set<String> BACKUP_BLACKLISTED_SECURE_SETTINGS =
newHashSet(
Settings.Secure.ACCESSIBILITY_SOFT_KEYBOARD_MODE,
diff --git a/packages/SettingsLib/src/com/android/settingslib/fuelgauge/BatterySaverUtils.java b/packages/SettingsLib/src/com/android/settingslib/fuelgauge/BatterySaverUtils.java
index fb5c16b92930..e19ac815b939 100644
--- a/packages/SettingsLib/src/com/android/settingslib/fuelgauge/BatterySaverUtils.java
+++ b/packages/SettingsLib/src/com/android/settingslib/fuelgauge/BatterySaverUtils.java
@@ -37,7 +37,8 @@ public class BatterySaverUtils {
/**
* When set to "true" the notification will be a generic confirm message instead of asking the
* user if they want to turn on battery saver. If set to false the dialog will specifically
- * talk about turning on battery saver and provide a button for taking the action.
+ * talk about battery saver without giving the option of turning it on. The only button visible
+ * will be a generic confirmation button to acknowledge the dialog.
*/
public static final String EXTRA_CONFIRM_TEXT_ONLY = "extra_confirm_only";
/**
diff --git a/packages/SettingsLib/src/com/android/settingslib/fuelgauge/Estimate.kt b/packages/SettingsLib/src/com/android/settingslib/fuelgauge/Estimate.kt
new file mode 100644
index 000000000000..ae8e1e2a60c0
--- /dev/null
+++ b/packages/SettingsLib/src/com/android/settingslib/fuelgauge/Estimate.kt
@@ -0,0 +1,81 @@
+/*
+ * Copyright (C) 2019 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.settingslib.fuelgauge
+
+import android.content.Context
+import android.provider.Settings
+import java.time.Duration
+import java.time.Instant
+
+const val AVERAGE_TIME_TO_DISCHARGE_UNKNOWN = -1
+const val ESTIMATE_MILLIS_UNKNOWN = -1
+
+class Estimate(
+ val estimateMillis: Long,
+ val isBasedOnUsage: Boolean,
+ val averageDischargeTime: Long
+) {
+ companion object {
+ /**
+ * Returns the cached estimate if it is available and fresh. Will return null if estimate is
+ * unavailable or older than 2 minutes.
+ *
+ * @param context A valid context
+ * @return An [Estimate] object with the latest battery estimates.
+ */
+ @JvmStatic
+ fun getCachedEstimateIfAvailable(context: Context): Estimate? {
+ // if time > 2 min return null or the estimate otherwise
+ val resolver = context.contentResolver
+ val lastUpdateTime = Instant.ofEpochMilli(
+ Settings.Global.getLong(
+ resolver, Settings.Global.BATTERY_ESTIMATES_LAST_UPDATE_TIME, -1))
+ return if (Duration.between(lastUpdateTime,
+ Instant.now()).compareTo(Duration.ofMinutes(2)) > 0) {
+ null
+ } else Estimate(
+ Settings.Global.getLong(resolver,
+ Settings.Global.TIME_REMAINING_ESTIMATE_MILLIS,
+ ESTIMATE_MILLIS_UNKNOWN.toLong()),
+ Settings.Global.getInt(resolver,
+ Settings.Global.TIME_REMAINING_ESTIMATE_BASED_ON_USAGE, 0) == 1,
+ Settings.Global.getLong(resolver, Settings.Global.AVERAGE_TIME_TO_DISCHARGE,
+ AVERAGE_TIME_TO_DISCHARGE_UNKNOWN.toLong()))
+ }
+
+ /**
+ * Stores an estimate to the cache along with a timestamp. Can be obtained via
+ * [.getCachedEstimateIfAvailable].
+ *
+ * @param context A valid context
+ * @param estimate the [Estimate] object to store
+ */
+ @JvmStatic
+ fun storeCachedEstimate(context: Context, estimate: Estimate) {
+ // store the estimate and update the timestamp
+ val resolver = context.contentResolver
+ Settings.Global.putLong(resolver, Settings.Global.TIME_REMAINING_ESTIMATE_MILLIS,
+ estimate.estimateMillis)
+ Settings.Global.putInt(resolver, Settings.Global.TIME_REMAINING_ESTIMATE_BASED_ON_USAGE,
+ if (estimate.isBasedOnUsage) 1 else 0)
+ Settings.Global.putLong(resolver, Settings.Global.AVERAGE_TIME_TO_DISCHARGE,
+ estimate.averageDischargeTime)
+ Settings.Global.putLong(resolver, Settings.Global.BATTERY_ESTIMATES_LAST_UPDATE_TIME,
+ System.currentTimeMillis())
+ }
+ }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/bubbles/BubbleController.java b/packages/SystemUI/src/com/android/systemui/bubbles/BubbleController.java
index 9d9c88f2c6ca..744f88d19ba3 100644
--- a/packages/SystemUI/src/com/android/systemui/bubbles/BubbleController.java
+++ b/packages/SystemUI/src/com/android/systemui/bubbles/BubbleController.java
@@ -86,7 +86,7 @@ public class BubbleController implements ConfigurationController.ConfigurationLi
@Retention(SOURCE)
@IntDef({DISMISS_USER_GESTURE, DISMISS_AGED, DISMISS_TASK_FINISHED, DISMISS_BLOCKED,
- DISMISS_NOTIF_CANCEL, DISMISS_ACCESSIBILITY_ACTION})
+ DISMISS_NOTIF_CANCEL, DISMISS_ACCESSIBILITY_ACTION, DISMISS_NO_LONGER_BUBBLE})
@interface DismissReason {}
static final int DISMISS_USER_GESTURE = 1;
@@ -95,6 +95,7 @@ public class BubbleController implements ConfigurationController.ConfigurationLi
static final int DISMISS_BLOCKED = 4;
static final int DISMISS_NOTIF_CANCEL = 5;
static final int DISMISS_ACCESSIBILITY_ACTION = 6;
+ static final int DISMISS_NO_LONGER_BUBBLE = 7;
static final int MAX_BUBBLES = 5; // TODO: actually enforce this
@@ -129,8 +130,7 @@ public class BubbleController implements ConfigurationController.ConfigurationLi
private final StatusBarWindowController mStatusBarWindowController;
private StatusBarStateListener mStatusBarStateListener;
- private final NotificationInterruptionStateProvider mNotificationInterruptionStateProvider =
- Dependency.get(NotificationInterruptionStateProvider.class);
+ private final NotificationInterruptionStateProvider mNotificationInterruptionStateProvider;
private INotificationManager mNotificationManagerService;
@@ -189,15 +189,19 @@ public class BubbleController implements ConfigurationController.ConfigurationLi
@Inject
public BubbleController(Context context, StatusBarWindowController statusBarWindowController,
- BubbleData data, ConfigurationController configurationController) {
+ BubbleData data, ConfigurationController configurationController,
+ NotificationInterruptionStateProvider interruptionStateProvider) {
this(context, statusBarWindowController, data, null /* synchronizer */,
- configurationController);
+ configurationController, interruptionStateProvider);
}
public BubbleController(Context context, StatusBarWindowController statusBarWindowController,
BubbleData data, @Nullable BubbleStackView.SurfaceSynchronizer synchronizer,
- ConfigurationController configurationController) {
+ ConfigurationController configurationController,
+ NotificationInterruptionStateProvider interruptionStateProvider) {
mContext = context;
+ mNotificationInterruptionStateProvider = interruptionStateProvider;
+
configurationController.addCallback(this /* configurationListener */);
mNotificationEntryManager = Dependency.get(NotificationEntryManager.class);
@@ -394,7 +398,7 @@ public class BubbleController implements ConfigurationController.ConfigurationLi
if (!areBubblesEnabled(mContext)) {
return;
}
- if (shouldAutoBubbleForFlags(mContext, entry) || shouldBubble(entry)) {
+ if (mNotificationInterruptionStateProvider.shouldBubbleUp(entry)) {
// TODO: handle group summaries?
updateShowInShadeForSuppressNotification(entry);
}
@@ -405,7 +409,7 @@ public class BubbleController implements ConfigurationController.ConfigurationLi
if (!areBubblesEnabled(mContext)) {
return;
}
- if (entry.isBubble() && mNotificationInterruptionStateProvider.shouldBubbleUp(entry)) {
+ if (mNotificationInterruptionStateProvider.shouldBubbleUp(entry)) {
updateBubble(entry);
}
}
@@ -415,8 +419,11 @@ public class BubbleController implements ConfigurationController.ConfigurationLi
if (!areBubblesEnabled(mContext)) {
return;
}
- if (mNotificationInterruptionStateProvider.shouldBubbleUp(entry)
- && alertAgain(entry, entry.notification.getNotification())) {
+ boolean shouldBubble = mNotificationInterruptionStateProvider.shouldBubbleUp(entry);
+ if (!shouldBubble && mBubbleData.hasBubbleWithKey(entry.key)) {
+ // It was previously a bubble but no longer a bubble -- lets remove it
+ removeBubble(entry.key, DISMISS_NO_LONGER_BUBBLE);
+ } else if (shouldBubble && alertAgain(entry, entry.notification.getNotification())) {
updateShowInShadeForSuppressNotification(entry);
entry.setBubbleDismissed(false); // updates come back as bubbles even if dismissed
updateBubble(entry);
@@ -561,17 +568,6 @@ public class BubbleController implements ConfigurationController.ConfigurationLi
}
/**
- * Whether the notification has been developer configured to bubble and is allowed by the user.
- */
- @VisibleForTesting
- protected boolean shouldBubble(NotificationEntry entry) {
- StatusBarNotification n = entry.notification;
- boolean hasOverlayIntent = n.getNotification().getBubbleMetadata() != null
- && n.getNotification().getBubbleMetadata().getIntent() != null;
- return hasOverlayIntent && entry.canBubble;
- }
-
- /**
* Whether the notification should automatically bubble or not. Gated by secure settings flags.
*/
@VisibleForTesting
diff --git a/packages/SystemUI/src/com/android/systemui/power/BatteryStateSnapshot.kt b/packages/SystemUI/src/com/android/systemui/power/BatteryStateSnapshot.kt
index 02ad0f1766bd..f73bc93ff313 100644
--- a/packages/SystemUI/src/com/android/systemui/power/BatteryStateSnapshot.kt
+++ b/packages/SystemUI/src/com/android/systemui/power/BatteryStateSnapshot.kt
@@ -15,6 +15,7 @@ data class BatteryStateSnapshot(
val severeLevelThreshold: Int,
val lowLevelThreshold: Int,
val timeRemainingMillis: Long,
+ val averageTimeToDischargeMillis: Long,
val severeThresholdMillis: Long,
val lowThresholdMillis: Long,
val isBasedOnUsage: Boolean,
@@ -39,18 +40,19 @@ data class BatteryStateSnapshot(
severeLevelThreshold: Int,
lowLevelThreshold: Int
) : this(
- batteryLevel,
- isPowerSaver,
- plugged,
- bucket,
- batteryStatus,
- severeLevelThreshold,
- lowLevelThreshold,
- NO_ESTIMATE_AVAILABLE.toLong(),
- NO_ESTIMATE_AVAILABLE.toLong(),
- NO_ESTIMATE_AVAILABLE.toLong(),
- false,
- true
+ batteryLevel,
+ isPowerSaver,
+ plugged,
+ bucket,
+ batteryStatus,
+ severeLevelThreshold,
+ lowLevelThreshold,
+ NO_ESTIMATE_AVAILABLE.toLong(),
+ NO_ESTIMATE_AVAILABLE.toLong(),
+ NO_ESTIMATE_AVAILABLE.toLong(),
+ NO_ESTIMATE_AVAILABLE.toLong(),
+ false,
+ true
) {
this.isHybrid = false
}
diff --git a/packages/SystemUI/src/com/android/systemui/power/EnhancedEstimates.java b/packages/SystemUI/src/com/android/systemui/power/EnhancedEstimates.java
index a87922792616..3b464783d009 100644
--- a/packages/SystemUI/src/com/android/systemui/power/EnhancedEstimates.java
+++ b/packages/SystemUI/src/com/android/systemui/power/EnhancedEstimates.java
@@ -1,5 +1,7 @@
package com.android.systemui.power;
+import com.android.settingslib.fuelgauge.Estimate;
+
public interface EnhancedEstimates {
/**
diff --git a/packages/SystemUI/src/com/android/systemui/power/EnhancedEstimatesImpl.java b/packages/SystemUI/src/com/android/systemui/power/EnhancedEstimatesImpl.java
index bfb809ecbf34..9b1f23aa0d0c 100644
--- a/packages/SystemUI/src/com/android/systemui/power/EnhancedEstimatesImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/power/EnhancedEstimatesImpl.java
@@ -1,5 +1,7 @@
package com.android.systemui.power;
+import com.android.settingslib.fuelgauge.Estimate;
+
public class EnhancedEstimatesImpl implements EnhancedEstimates {
@Override
diff --git a/packages/SystemUI/src/com/android/systemui/power/Estimate.kt b/packages/SystemUI/src/com/android/systemui/power/Estimate.kt
deleted file mode 100644
index dca0d45c1c9f..000000000000
--- a/packages/SystemUI/src/com/android/systemui/power/Estimate.kt
+++ /dev/null
@@ -1,3 +0,0 @@
-package com.android.systemui.power
-
-data class Estimate(val estimateMillis: Long, val isBasedOnUsage: Boolean) \ No newline at end of file
diff --git a/packages/SystemUI/src/com/android/systemui/power/PowerUI.java b/packages/SystemUI/src/com/android/systemui/power/PowerUI.java
index 25d6d940d92e..b57c053964ca 100644
--- a/packages/SystemUI/src/com/android/systemui/power/PowerUI.java
+++ b/packages/SystemUI/src/com/android/systemui/power/PowerUI.java
@@ -42,6 +42,7 @@ import android.util.Log;
import android.util.Slog;
import com.android.internal.annotations.VisibleForTesting;
+import com.android.settingslib.fuelgauge.Estimate;
import com.android.settingslib.utils.ThreadUtils;
import com.android.systemui.Dependency;
import com.android.systemui.R;
@@ -283,6 +284,7 @@ public class PowerUI extends SystemUI {
mCurrentBatteryStateSnapshot = new BatteryStateSnapshot(mBatteryLevel, isPowerSaverMode,
plugged, bucket, mBatteryStatus, mLowBatteryReminderLevels[1],
mLowBatteryReminderLevels[0], estimate.getEstimateMillis(),
+ estimate.getAverageDischargeTime(),
mEnhancedEstimates.getSevereWarningThreshold(),
mEnhancedEstimates.getLowWarningThreshold(), estimate.isBasedOnUsage(),
mEnhancedEstimates.getLowWarningEnabled());
@@ -316,7 +318,8 @@ public class PowerUI extends SystemUI {
return estimate;
}
return new Estimate(mLastBatteryStateSnapshot.getTimeRemainingMillis(),
- mLastBatteryStateSnapshot.isBasedOnUsage());
+ mLastBatteryStateSnapshot.isBasedOnUsage(),
+ mLastBatteryStateSnapshot.getAverageTimeToDischargeMillis());
}
@VisibleForTesting
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/KeyguardAffordanceView.java b/packages/SystemUI/src/com/android/systemui/statusbar/KeyguardAffordanceView.java
index 2da68249d8c4..6adaa0ddbfd2 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/KeyguardAffordanceView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/KeyguardAffordanceView.java
@@ -149,6 +149,13 @@ public class KeyguardAffordanceView extends ImageView {
updateIconColor();
}
+ /**
+ * If current drawable should be tinted.
+ */
+ public boolean shouldTint() {
+ return mShouldTint;
+ }
+
@Override
protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
super.onLayout(changed, left, top, right, bottom);
@@ -168,6 +175,9 @@ public class KeyguardAffordanceView extends ImageView {
}
public void setPreviewView(View v) {
+ if (mPreviewView == v) {
+ return;
+ }
View oldPreviewView = mPreviewView;
mPreviewView = v;
if (mPreviewView != null) {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationInterruptionStateProvider.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationInterruptionStateProvider.java
index 059c3f672b69..926d4b6a79b3 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationInterruptionStateProvider.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationInterruptionStateProvider.java
@@ -147,7 +147,14 @@ public class NotificationInterruptionStateProvider {
* @return true if the entry should bubble up, false otherwise
*/
public boolean shouldBubbleUp(NotificationEntry entry) {
- StatusBarNotification sbn = entry.notification;
+ final StatusBarNotification sbn = entry.notification;
+ if (!entry.canBubble) {
+ if (DEBUG) {
+ Log.d(TAG, "No bubble up: not allowed to bubble: " + sbn.getKey());
+ }
+ return false;
+ }
+
if (!entry.isBubble()) {
if (DEBUG) {
Log.d(TAG, "No bubble up: notification " + sbn.getKey()
@@ -156,6 +163,15 @@ public class NotificationInterruptionStateProvider {
return false;
}
+ final Notification n = sbn.getNotification();
+ if (n.getBubbleMetadata() == null || n.getBubbleMetadata().getIntent() == null) {
+ if (DEBUG) {
+ Log.d(TAG, "No bubble up: notification: " + sbn.getKey()
+ + " doesn't have valid metadata");
+ }
+ return false;
+ }
+
if (!canHeadsUpCommon(entry)) {
return false;
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardBottomAreaView.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardBottomAreaView.java
index cb64f10d9e8c..5b464a9ecd97 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardBottomAreaView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardBottomAreaView.java
@@ -337,7 +337,10 @@ public class KeyguardBottomAreaView extends FrameLayout implements View.OnClickL
private void updateRightAffordanceIcon() {
IconState state = mRightButton.getIcon();
mRightAffordanceView.setVisibility(!mDozing && state.isVisible ? View.VISIBLE : View.GONE);
- mRightAffordanceView.setImageDrawable(state.drawable, state.tint);
+ if (state.drawable != mRightAffordanceView.getDrawable()
+ || state.tint != mRightAffordanceView.shouldTint()) {
+ mRightAffordanceView.setImageDrawable(state.drawable, state.tint);
+ }
mRightAffordanceView.setContentDescription(state.contentDescription);
}
@@ -389,7 +392,10 @@ public class KeyguardBottomAreaView extends FrameLayout implements View.OnClickL
private void updateLeftAffordanceIcon() {
IconState state = mLeftButton.getIcon();
mLeftAffordanceView.setVisibility(!mDozing && state.isVisible ? View.VISIBLE : View.GONE);
- mLeftAffordanceView.setImageDrawable(state.drawable, state.tint);
+ if (state.drawable != mLeftAffordanceView.getDrawable()
+ || state.tint != mLeftAffordanceView.shouldTint()) {
+ mLeftAffordanceView.setImageDrawable(state.drawable, state.tint);
+ }
mLeftAffordanceView.setContentDescription(state.contentDescription);
}
@@ -715,11 +721,6 @@ public class KeyguardBottomAreaView extends FrameLayout implements View.OnClickL
updateLeftPreview();
}
- public void onKeyguardShowingChanged() {
- updateLeftAffordance();
- inflateCameraPreview();
- }
-
private void setRightButton(IntentButton button) {
mRightButton = button;
updateRightAffordanceIcon();
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelView.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelView.java
index 57b2ee9d893c..2207e0412949 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelView.java
@@ -1304,7 +1304,6 @@ public class NotificationPanelView extends PanelView implements
mKeyguardStatusBar.setAlpha(1f);
mKeyguardStatusBar.setVisibility(keyguardShowing ? View.VISIBLE : View.INVISIBLE);
if (keyguardShowing && oldState != mBarState) {
- mKeyguardBottomArea.onKeyguardShowingChanged();
if (mQs != null) {
mQs.hideImmediately();
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/BatteryControllerImpl.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/BatteryControllerImpl.java
index 273fa55ee9d8..fde1455b0af0 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/BatteryControllerImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/BatteryControllerImpl.java
@@ -31,10 +31,10 @@ import androidx.annotation.Nullable;
import com.android.internal.annotations.VisibleForTesting;
import com.android.settingslib.fuelgauge.BatterySaverUtils;
+import com.android.settingslib.fuelgauge.Estimate;
import com.android.settingslib.utils.PowerUtil;
import com.android.systemui.Dependency;
import com.android.systemui.power.EnhancedEstimates;
-import com.android.systemui.power.Estimate;
import java.io.FileDescriptor;
import java.io.PrintWriter;
diff --git a/packages/SystemUI/tests/src/com/android/systemui/bubbles/BubbleControllerTest.java b/packages/SystemUI/tests/src/com/android/systemui/bubbles/BubbleControllerTest.java
index 40a53571ddf0..8b0ba9448d2b 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/bubbles/BubbleControllerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/bubbles/BubbleControllerTest.java
@@ -16,6 +16,7 @@
package com.android.systemui.bubbles;
+import static android.app.Notification.FLAG_BUBBLE;
import static android.content.Intent.FLAG_ACTIVITY_NEW_TASK;
import static com.google.common.truth.Truth.assertThat;
@@ -25,6 +26,7 @@ import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;
import static org.mockito.ArgumentMatchers.anyBoolean;
import static org.mockito.Mockito.atLeastOnce;
+import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.never;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
@@ -47,15 +49,18 @@ import androidx.test.filters.SmallTest;
import com.android.systemui.R;
import com.android.systemui.SysuiTestCase;
+import com.android.systemui.statusbar.NotificationPresenter;
import com.android.systemui.statusbar.NotificationTestHelper;
import com.android.systemui.statusbar.notification.NotificationEntryListener;
import com.android.systemui.statusbar.notification.NotificationEntryManager;
+import com.android.systemui.statusbar.notification.NotificationInterruptionStateProvider;
import com.android.systemui.statusbar.notification.collection.NotificationData;
import com.android.systemui.statusbar.notification.collection.NotificationEntry;
import com.android.systemui.statusbar.notification.row.ExpandableNotificationRow;
import com.android.systemui.statusbar.phone.DozeParameters;
import com.android.systemui.statusbar.phone.StatusBarWindowController;
import com.android.systemui.statusbar.policy.ConfigurationController;
+import com.android.systemui.statusbar.policy.HeadsUpManager;
import org.junit.Before;
import org.junit.Test;
@@ -138,7 +143,7 @@ public class BubbleControllerTest extends SysuiTestCase {
// Some bubbles want to suppress notifs
Notification.BubbleMetadata suppressNotifMetadata =
- getBuilder().setSuppressInitialNotification(true).build();
+ getBuilder().setSuppressNotification(true).build();
mSuppressNotifRow = mNotificationTestHelper.createBubble(suppressNotifMetadata,
FOREGROUND_TEST_PKG_NAME);
@@ -146,9 +151,15 @@ public class BubbleControllerTest extends SysuiTestCase {
when(mNotificationEntryManager.getNotificationData()).thenReturn(mNotificationData);
when(mNotificationData.getChannel(mRow.getEntry().key)).thenReturn(mRow.getEntry().channel);
+ TestableNotificationInterruptionStateProvider interruptionStateProvider =
+ new TestableNotificationInterruptionStateProvider(mContext);
+ interruptionStateProvider.setUpWithPresenter(
+ mock(NotificationPresenter.class),
+ mock(HeadsUpManager.class),
+ mock(NotificationInterruptionStateProvider.HeadsUpSuppressor.class));
mBubbleData = new BubbleData(mContext);
mBubbleController = new TestableBubbleController(mContext, mStatusBarWindowController,
- mBubbleData, mConfigurationController);
+ mBubbleData, mConfigurationController, interruptionStateProvider);
mBubbleController.setBubbleStateChangeListener(mBubbleStateChangeListener);
mBubbleController.setExpandListener(mBubbleExpandListener);
@@ -487,12 +498,27 @@ public class BubbleControllerTest extends SysuiTestCase {
verify(mDeleteIntent, times(2)).send();
}
+ @Test
+ public void testRemoveBubble_noLongerBubbleAfterUpdate()
+ throws PendingIntent.CanceledException {
+ mBubbleController.updateBubble(mRow.getEntry());
+ assertTrue(mBubbleController.hasBubbles());
+
+ mRow.getEntry().notification.getNotification().flags &= ~FLAG_BUBBLE;
+ mEntryListener.onPreEntryUpdated(mRow.getEntry());
+
+ assertFalse(mBubbleController.hasBubbles());
+ verify(mDeleteIntent, never()).send();
+ }
+
static class TestableBubbleController extends BubbleController {
// Let's assume surfaces can be synchronized immediately.
TestableBubbleController(Context context,
StatusBarWindowController statusBarWindowController, BubbleData data,
- ConfigurationController configurationController) {
- super(context, statusBarWindowController, data, Runnable::run, configurationController);
+ ConfigurationController configurationController,
+ NotificationInterruptionStateProvider interruptionStateProvider) {
+ super(context, statusBarWindowController, data, Runnable::run,
+ configurationController, interruptionStateProvider);
}
@Override
@@ -501,6 +527,15 @@ public class BubbleControllerTest extends SysuiTestCase {
}
}
+ public static class TestableNotificationInterruptionStateProvider extends
+ NotificationInterruptionStateProvider {
+
+ public TestableNotificationInterruptionStateProvider(Context context) {
+ super(context);
+ mUseHeadsUp = true;
+ }
+ }
+
/**
* @return basic {@link android.app.Notification.BubbleMetadata.Builder}
*/
diff --git a/packages/SystemUI/tests/src/com/android/systemui/power/PowerUITest.java b/packages/SystemUI/tests/src/com/android/systemui/power/PowerUITest.java
index 5928a07487d9..161b40979e11 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/power/PowerUITest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/power/PowerUITest.java
@@ -40,6 +40,7 @@ import android.testing.TestableLooper;
import android.testing.TestableLooper.RunWithLooper;
import android.testing.TestableResources;
+import com.android.settingslib.fuelgauge.Estimate;
import com.android.systemui.R;
import com.android.systemui.SysuiTestCase;
import com.android.systemui.power.PowerUI.WarningsUI;
@@ -358,7 +359,7 @@ public class PowerUITest extends SysuiTestCase {
@Test
public void testRefreshEstimateIfNeeded_onlyQueriesEstimateOnBatteryLevelChangeOrNull() {
mPowerUI.start();
- Estimate estimate = new Estimate(BELOW_HYBRID_THRESHOLD, true);
+ Estimate estimate = new Estimate(BELOW_HYBRID_THRESHOLD, true, 0);
when(mEnhancedEstimates.isHybridNotificationEnabled()).thenReturn(true);
when(mEnhancedEstimates.getLowWarningThreshold()).thenReturn(PowerUI.THREE_HOURS_IN_MILLIS);
when(mEnhancedEstimates.getSevereWarningThreshold()).thenReturn(ONE_HOUR_MILLIS);
@@ -371,21 +372,21 @@ public class PowerUITest extends SysuiTestCase {
assertThat(refreshedEstimate.getEstimateMillis()).isEqualTo(BELOW_HYBRID_THRESHOLD);
BatteryStateSnapshot snapshot = new BatteryStateSnapshot(
BATTERY_LEVEL_10, false, false, 0, BatteryManager.BATTERY_HEALTH_GOOD,
- 0, 0, -1, 0, 0, false, true);
+ 0, 0, -1, 0, 0, 0, false, true);
mPowerUI.mLastBatteryStateSnapshot = snapshot;
// query again since the estimate was -1
- estimate = new Estimate(BELOW_SEVERE_HYBRID_THRESHOLD, true);
+ estimate = new Estimate(BELOW_SEVERE_HYBRID_THRESHOLD, true, 0);
when(mEnhancedEstimates.getEstimate()).thenReturn(estimate);
refreshedEstimate = mPowerUI.refreshEstimateIfNeeded();
assertThat(refreshedEstimate.getEstimateMillis()).isEqualTo(BELOW_SEVERE_HYBRID_THRESHOLD);
snapshot = new BatteryStateSnapshot(
BATTERY_LEVEL_10, false, false, 0, BatteryManager.BATTERY_HEALTH_GOOD, 0,
- 0, BELOW_SEVERE_HYBRID_THRESHOLD, 0, 0, false, true);
+ 0, BELOW_SEVERE_HYBRID_THRESHOLD, 0, 0, 0, false, true);
mPowerUI.mLastBatteryStateSnapshot = snapshot;
// Battery level hasn't changed, so we don't query again
- estimate = new Estimate(BELOW_HYBRID_THRESHOLD, true);
+ estimate = new Estimate(BELOW_HYBRID_THRESHOLD, true, 0);
when(mEnhancedEstimates.getEstimate()).thenReturn(estimate);
refreshedEstimate = mPowerUI.refreshEstimateIfNeeded();
assertThat(refreshedEstimate.getEstimateMillis()).isEqualTo(BELOW_SEVERE_HYBRID_THRESHOLD);
@@ -543,13 +544,14 @@ public class PowerUITest extends SysuiTestCase {
public boolean mIsBasedOnUsage = true;
public boolean mIsHybrid = true;
public boolean mIsLowLevelWarningEnabled = true;
+ private long mAverageTimeToDischargeMillis = Duration.ofHours(24).toMillis();
public BatteryStateSnapshot get() {
if (mIsHybrid) {
return new BatteryStateSnapshot(mBatteryLevel, mIsPowerSaver, mPlugged, mBucket,
mBatteryStatus, mSevereLevelThreshold, mLowLevelThreshold,
- mTimeRemainingMillis, mSevereThresholdMillis, mLowThresholdMillis,
- mIsBasedOnUsage, mIsLowLevelWarningEnabled);
+ mTimeRemainingMillis, mAverageTimeToDischargeMillis, mSevereThresholdMillis,
+ mLowThresholdMillis, mIsBasedOnUsage, mIsLowLevelWarningEnabled);
} else {
return new BatteryStateSnapshot(mBatteryLevel, mIsPowerSaver, mPlugged, mBucket,
mBatteryStatus, mSevereLevelThreshold, mLowLevelThreshold);
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/NotificationTestHelper.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/NotificationTestHelper.java
index 8cc1571b925f..e4b90c54d5b3 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/NotificationTestHelper.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/NotificationTestHelper.java
@@ -178,7 +178,10 @@ public class NotificationTestHelper {
Notification n = createNotification(false /* isGroupSummary */,
null /* groupKey */, bubbleMetadata);
n.flags |= FLAG_BUBBLE;
- return generateRow(n, pkg, UID, USER_HANDLE, 0 /* extraInflationFlags */, IMPORTANCE_HIGH);
+ ExpandableNotificationRow row = generateRow(n, pkg, UID, USER_HANDLE,
+ 0 /* extraInflationFlags */, IMPORTANCE_HIGH);
+ row.getEntry().canBubble = true;
+ return row;
}
/**
diff --git a/services/core/java/com/android/server/policy/PhoneWindowManager.java b/services/core/java/com/android/server/policy/PhoneWindowManager.java
index d0ca861d8d3b..9b4293d484bc 100644
--- a/services/core/java/com/android/server/policy/PhoneWindowManager.java
+++ b/services/core/java/com/android/server/policy/PhoneWindowManager.java
@@ -256,6 +256,7 @@ public class PhoneWindowManager implements WindowManagerPolicy {
// Whether to allow devices placed in vr headset viewers to have an alternative Home intent.
static final boolean ENABLE_VR_HEADSET_HOME_CAPTURE = true;
+ // must match: config_shortPressOnPowerBehavior in config.xml
static final int SHORT_PRESS_POWER_NOTHING = 0;
static final int SHORT_PRESS_POWER_GO_TO_SLEEP = 1;
static final int SHORT_PRESS_POWER_REALLY_GO_TO_SLEEP = 2;
@@ -263,29 +264,34 @@ public class PhoneWindowManager implements WindowManagerPolicy {
static final int SHORT_PRESS_POWER_GO_HOME = 4;
static final int SHORT_PRESS_POWER_CLOSE_IME_OR_GO_HOME = 5;
+ // must match: config_LongPressOnPowerBehavior in config.xml
static final int LONG_PRESS_POWER_NOTHING = 0;
static final int LONG_PRESS_POWER_GLOBAL_ACTIONS = 1;
static final int LONG_PRESS_POWER_SHUT_OFF = 2;
static final int LONG_PRESS_POWER_SHUT_OFF_NO_CONFIRM = 3;
static final int LONG_PRESS_POWER_GO_TO_VOICE_ASSIST = 4;
+ static final int LONG_PRESS_POWER_ASSISTANT = 5; // Settings.Secure.ASSISTANT
+ // must match: config_veryLongPresOnPowerBehavior in config.xml
static final int VERY_LONG_PRESS_POWER_NOTHING = 0;
static final int VERY_LONG_PRESS_POWER_GLOBAL_ACTIONS = 1;
+ // must match: config_doublePressOnPowerBehavior in config.xml
static final int MULTI_PRESS_POWER_NOTHING = 0;
static final int MULTI_PRESS_POWER_THEATER_MODE = 1;
static final int MULTI_PRESS_POWER_BRIGHTNESS_BOOST = 2;
+ // must match: config_longPressOnBackBehavior in config.xml
static final int LONG_PRESS_BACK_NOTHING = 0;
static final int LONG_PRESS_BACK_GO_TO_VOICE_ASSIST = 1;
- // These need to match the documentation/constant in
- // core/res/res/values/config.xml
+ // must match: config_longPressOnHomeBehavior in config.xml
static final int LONG_PRESS_HOME_NOTHING = 0;
static final int LONG_PRESS_HOME_ALL_APPS = 1;
static final int LONG_PRESS_HOME_ASSIST = 2;
static final int LAST_LONG_PRESS_HOME_BEHAVIOR = LONG_PRESS_HOME_ASSIST;
+ // must match: config_doubleTapOnHomeBehavior in config.xml
static final int DOUBLE_TAP_HOME_NOTHING = 0;
static final int DOUBLE_TAP_HOME_RECENT_SYSTEM_UI = 1;
@@ -770,6 +776,12 @@ public class PhoneWindowManager implements WindowManagerPolicy {
resolver.registerContentObserver(Settings.Secure.getUriFor(
Settings.Secure.SYSTEM_NAVIGATION_KEYS_ENABLED), false, this,
UserHandle.USER_ALL);
+ resolver.registerContentObserver(Settings.Global.getUriFor(
+ Settings.Global.POWER_BUTTON_LONG_PRESS), false, this,
+ UserHandle.USER_ALL);
+ resolver.registerContentObserver(Settings.Global.getUriFor(
+ Settings.Global.POWER_BUTTON_VERY_LONG_PRESS), false, this,
+ UserHandle.USER_ALL);
updateSettings();
}
@@ -1195,38 +1207,38 @@ public class PhoneWindowManager implements WindowManagerPolicy {
private void powerLongPress() {
final int behavior = getResolvedLongPressOnPowerBehavior();
switch (behavior) {
- case LONG_PRESS_POWER_NOTHING:
- break;
- case LONG_PRESS_POWER_GLOBAL_ACTIONS:
- mPowerKeyHandled = true;
- performHapticFeedback(HapticFeedbackConstants.LONG_PRESS, false,
- "Power - Long Press - Global Actions");
- showGlobalActionsInternal();
- break;
- case LONG_PRESS_POWER_SHUT_OFF:
- case LONG_PRESS_POWER_SHUT_OFF_NO_CONFIRM:
- mPowerKeyHandled = true;
- performHapticFeedback(HapticFeedbackConstants.LONG_PRESS, false,
- "Power - Long Press - Shut Off");
- sendCloseSystemWindows(SYSTEM_DIALOG_REASON_GLOBAL_ACTIONS);
- mWindowManagerFuncs.shutdown(behavior == LONG_PRESS_POWER_SHUT_OFF);
- break;
- case LONG_PRESS_POWER_GO_TO_VOICE_ASSIST:
- mPowerKeyHandled = true;
- performHapticFeedback(HapticFeedbackConstants.LONG_PRESS, false,
- "Power - Long Press - Go To Voice Assist");
- final boolean keyguardActive = mKeyguardDelegate == null
- ? false
- : mKeyguardDelegate.isShowing();
- if (!keyguardActive) {
- Intent intent = new Intent(Intent.ACTION_VOICE_ASSIST);
- if (mAllowStartActivityForLongPressOnPowerDuringSetup) {
- mContext.startActivityAsUser(intent, UserHandle.CURRENT_OR_SELF);
- } else {
- startActivityAsUser(intent, UserHandle.CURRENT_OR_SELF);
- }
- }
- break;
+ case LONG_PRESS_POWER_NOTHING:
+ break;
+ case LONG_PRESS_POWER_GLOBAL_ACTIONS:
+ mPowerKeyHandled = true;
+ performHapticFeedback(HapticFeedbackConstants.LONG_PRESS, false,
+ "Power - Long Press - Global Actions");
+ showGlobalActionsInternal();
+ break;
+ case LONG_PRESS_POWER_SHUT_OFF:
+ case LONG_PRESS_POWER_SHUT_OFF_NO_CONFIRM:
+ mPowerKeyHandled = true;
+ performHapticFeedback(HapticFeedbackConstants.LONG_PRESS, false,
+ "Power - Long Press - Shut Off");
+ sendCloseSystemWindows(SYSTEM_DIALOG_REASON_GLOBAL_ACTIONS);
+ mWindowManagerFuncs.shutdown(behavior == LONG_PRESS_POWER_SHUT_OFF);
+ break;
+ case LONG_PRESS_POWER_GO_TO_VOICE_ASSIST:
+ mPowerKeyHandled = true;
+ performHapticFeedback(HapticFeedbackConstants.LONG_PRESS, false,
+ "Power - Long Press - Go To Voice Assist");
+ // Some devices allow the voice assistant intent during setup (and use that intent
+ // to launch something else, like Settings). So we explicitly allow that via the
+ // config_allowStartActivityForLongPressOnPowerInSetup resource in config.xml.
+ launchVoiceAssist(mAllowStartActivityForLongPressOnPowerDuringSetup);
+ break;
+ case LONG_PRESS_POWER_ASSISTANT:
+ mPowerKeyHandled = true;
+ performHapticFeedback(HapticFeedbackConstants.LONG_PRESS, false,
+ "Power - Long Press - Go To Assistant");
+ final int powerKeyDeviceId = Integer.MIN_VALUE;
+ launchAssistAction(null, powerKeyDeviceId);
+ break;
}
}
@@ -1250,13 +1262,7 @@ public class PhoneWindowManager implements WindowManagerPolicy {
case LONG_PRESS_BACK_NOTHING:
break;
case LONG_PRESS_BACK_GO_TO_VOICE_ASSIST:
- final boolean keyguardActive = mKeyguardDelegate == null
- ? false
- : mKeyguardDelegate.isShowing();
- if (!keyguardActive) {
- Intent intent = new Intent(Intent.ACTION_VOICE_ASSIST);
- startActivityAsUser(intent, UserHandle.CURRENT_OR_SELF);
- }
+ launchVoiceAssist(false /* allowDuringSetup */);
break;
}
}
@@ -1999,6 +2005,15 @@ public class PhoneWindowManager implements WindowManagerPolicy {
mHasSoftInput = hasSoftInput;
updateRotation = true;
}
+
+ mLongPressOnPowerBehavior = Settings.Global.getInt(resolver,
+ Settings.Global.POWER_BUTTON_LONG_PRESS,
+ mContext.getResources().getInteger(
+ com.android.internal.R.integer.config_longPressOnPowerBehavior));
+ mVeryLongPressOnPowerBehavior = Settings.Global.getInt(resolver,
+ Settings.Global.POWER_BUTTON_VERY_LONG_PRESS,
+ mContext.getResources().getInteger(
+ com.android.internal.R.integer.config_veryLongPressOnPowerBehavior));
}
if (updateRotation) {
updateRotation(true);
@@ -3225,6 +3240,10 @@ public class PhoneWindowManager implements WindowManagerPolicy {
return 0;
}
+ // There are several different flavors of "assistant" that can be launched from
+ // various parts of the UI.
+
+ /** starts ACTION_SEARCH_LONG_PRESS, usually a voice search prompt */
private void launchAssistLongPressAction() {
performHapticFeedback(HapticFeedbackConstants.LONG_PRESS, false,
"Assist - Long Press");
@@ -3246,6 +3265,7 @@ public class PhoneWindowManager implements WindowManagerPolicy {
}
}
+ /** Asks the status bar to startAssist(), usually a full "assistant" interface */
private void launchAssistAction(String hint, int deviceId) {
sendCloseSystemWindows(SYSTEM_DIALOG_REASON_ASSIST);
if (!isUserSetupComplete()) {
@@ -3276,12 +3296,30 @@ public class PhoneWindowManager implements WindowManagerPolicy {
}
}
+ /** Launches ACTION_VOICE_ASSIST. Does nothing on keyguard. */
+ private void launchVoiceAssist(boolean allowDuringSetup) {
+ final boolean keyguardActive = mKeyguardDelegate == null
+ ? false
+ : mKeyguardDelegate.isShowing();
+ if (!keyguardActive) {
+ Intent intent = new Intent(Intent.ACTION_VOICE_ASSIST);
+ startActivityAsUser(intent, null, UserHandle.CURRENT_OR_SELF,
+ allowDuringSetup);
+ }
+
+ }
+
private void startActivityAsUser(Intent intent, UserHandle handle) {
startActivityAsUser(intent, null, handle);
}
private void startActivityAsUser(Intent intent, Bundle bundle, UserHandle handle) {
- if (isUserSetupComplete()) {
+ startActivityAsUser(intent, bundle, handle, false /* allowDuringSetup */);
+ }
+
+ private void startActivityAsUser(Intent intent, Bundle bundle, UserHandle handle,
+ boolean allowDuringSetup) {
+ if (allowDuringSetup || isUserSetupComplete()) {
mContext.startActivityAsUser(intent, bundle, handle);
} else {
Slog.i(TAG, "Not starting activity because user setup is in progress: " + intent);
@@ -5541,6 +5579,10 @@ public class PhoneWindowManager implements WindowManagerPolicy {
return "LONG_PRESS_POWER_SHUT_OFF";
case LONG_PRESS_POWER_SHUT_OFF_NO_CONFIRM:
return "LONG_PRESS_POWER_SHUT_OFF_NO_CONFIRM";
+ case LONG_PRESS_POWER_GO_TO_VOICE_ASSIST:
+ return "LONG_PRESS_POWER_GO_TO_VOICE_ASSIST";
+ case LONG_PRESS_POWER_ASSISTANT:
+ return "LONG_PRESS_POWER_ASSISTANT";
default:
return Integer.toString(behavior);
}