summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Android.bp1
-rw-r--r--core/java/android/app/WallpaperManager.java24
-rw-r--r--core/java/android/content/pm/flags.aconfig8
-rw-r--r--core/java/android/content/pm/multiuser.aconfig7
-rw-r--r--core/java/android/provider/Settings.java6
-rw-r--r--core/java/com/android/internal/foldables/FoldLockSettingAvailabilityProvider.java40
-rw-r--r--core/sysprop/Android.bp7
-rw-r--r--core/sysprop/FoldLockBehaviorProperties.sysprop24
-rw-r--r--core/sysprop/api/com.android.sysprop.foldlockbehavior-current.txt0
-rw-r--r--core/sysprop/api/com.android.sysprop.foldlockbehavior-latest.txt9
-rw-r--r--packages/SettingsProvider/src/android/provider/settings/backup/SecureSettings.java1
-rw-r--r--packages/SettingsProvider/src/android/provider/settings/validators/SecureSettingsValidators.java1
-rw-r--r--packages/SystemUI/src/com/android/keyguard/KeyguardSecurityContainer.java3
-rw-r--r--packages/SystemUI/src/com/android/systemui/flags/Flags.kt2
-rw-r--r--packages/SystemUI/src/com/android/systemui/qs/tileimpl/QSTileImpl.java2
-rw-r--r--packages/SystemUI/src/com/android/systemui/volume/VolumeDialogImpl.java14
-rw-r--r--packages/SystemUI/src/com/android/systemui/volume/dagger/VolumeModule.java7
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/volume/VolumeDialogImplTest.java21
-rw-r--r--services/core/java/com/android/server/Watchdog.java49
-rw-r--r--services/core/java/com/android/server/display/DisplayManagerService.java8
-rw-r--r--services/core/java/com/android/server/utils/FoldSettingProvider.java14
-rw-r--r--services/core/java/com/android/server/wallpaper/WallpaperManagerService.java17
-rw-r--r--services/tests/displayservicetests/src/com/android/server/display/DisplayPowerController2Test.java7
-rw-r--r--services/tests/displayservicetests/src/com/android/server/display/DisplayPowerControllerTest.java7
-rw-r--r--services/tests/mockingservicestests/src/com/android/server/utils/FoldSettingProviderTest.java22
25 files changed, 227 insertions, 74 deletions
diff --git a/Android.bp b/Android.bp
index 4c44974a84d6..b1b332a9a2b5 100644
--- a/Android.bp
+++ b/Android.bp
@@ -389,6 +389,7 @@ java_defaults {
static_libs: [
"android.hardware.common.fmq-V1-java",
"bouncycastle-repackaged-unbundled",
+ "com.android.sysprop.foldlockbehavior",
"framework-internal-utils",
// If MimeMap ever becomes its own APEX, then this dependency would need to be removed
// in favor of an API stubs dependency in java_library "framework" below.
diff --git a/core/java/android/app/WallpaperManager.java b/core/java/android/app/WallpaperManager.java
index fce5e4f1fd21..e7a5b72eafc5 100644
--- a/core/java/android/app/WallpaperManager.java
+++ b/core/java/android/app/WallpaperManager.java
@@ -1759,12 +1759,17 @@ public class WallpaperManager {
/**
* Returns the information about the home screen wallpaper if its current wallpaper is a live
- * wallpaper component. Otherwise, if the wallpaper is a static image or is not set, this
- * returns null.
+ * wallpaper component. Otherwise, if the wallpaper is a static image or is not set, or if the
+ * the caller doesn't have the appropriate permissions, this returns {@code null}.
*
* <p>
- * In order to use this, apps should declare a {@code <queries>} tag with the action
- * {@code "android.service.wallpaper.WallpaperService"}. Otherwise,
+ * Before Android U, this method requires the
+ * {@link android.Manifest.permission#QUERY_ALL_PACKAGES} permission.
+ * </p>
+ *
+ * <p>
+ * Starting from Android U, In order to use this, apps should declare a {@code <queries>} tag
+ * with the action {@code "android.service.wallpaper.WallpaperService"}. Otherwise,
* this method will return {@code null} if the caller doesn't otherwise have
* <a href="{@docRoot}training/package-visibility">visibility</a> of the wallpaper package.
* </p>
@@ -1780,8 +1785,15 @@ public class WallpaperManager {
/**
* Returns the information about the designated wallpaper if its current wallpaper is a live
- * wallpaper component. Otherwise, if the wallpaper is a static image or is not set, this
- * returns null.
+ * wallpaper component. Otherwise, if the wallpaper is a static image or is not set, or if the
+ * the caller doesn't have the appropriate permissions, this returns {@code null}.
+ *
+ * <p>
+ * In order to use this, apps should declare a {@code <queries>} tag
+ * with the action {@code "android.service.wallpaper.WallpaperService"}. Otherwise,
+ * this method will return {@code null} if the caller doesn't otherwise have
+ * <a href="{@docRoot}training/package-visibility">visibility</a> of the wallpaper package.
+ * </p>
*
* @param which Specifies wallpaper to request (home or lock).
* @param userId Owner of the wallpaper.
diff --git a/core/java/android/content/pm/flags.aconfig b/core/java/android/content/pm/flags.aconfig
index b5efe588e63b..b054d38e59dc 100644
--- a/core/java/android/content/pm/flags.aconfig
+++ b/core/java/android/content/pm/flags.aconfig
@@ -27,3 +27,11 @@ flag {
description: "Feature flag to improve stopped state enforcement"
bug: "296644915"
}
+
+flag {
+ name: "nullable_data_dir"
+ namespace: "package_manager_service"
+ description: "Feature flag to allow ApplicationInfo.dataDir to be null."
+ bug: "302587814"
+ is_fixed_read_only: true
+}
diff --git a/core/java/android/content/pm/multiuser.aconfig b/core/java/android/content/pm/multiuser.aconfig
index 07ff7be00114..ea0f049cece3 100644
--- a/core/java/android/content/pm/multiuser.aconfig
+++ b/core/java/android/content/pm/multiuser.aconfig
@@ -6,3 +6,10 @@ flag {
description: "Save guest and device policy global restrictions on the SYSTEM user's XML file."
bug: "301067944"
}
+
+flag {
+ name: "bind_wallpaper_service_on_its_own_thread_during_a_user_switch"
+ namespace: "multiuser"
+ description: "Bind wallpaper service on its own thread instead of system_server's main handler during a user switch."
+ bug: "302100344"
+}
diff --git a/core/java/android/provider/Settings.java b/core/java/android/provider/Settings.java
index f40232b266d0..d09f0a831f30 100644
--- a/core/java/android/provider/Settings.java
+++ b/core/java/android/provider/Settings.java
@@ -11147,12 +11147,6 @@ public final class Settings {
public static final String BLUETOOTH_ON_WHILE_DRIVING = "bluetooth_on_while_driving";
/**
- * Volume dialog timeout in ms.
- * @hide
- */
- public static final String VOLUME_DIALOG_DISMISS_TIMEOUT = "volume_dialog_dismiss_timeout";
-
- /**
* What behavior should be invoked when the volume hush gesture is triggered
* One of VOLUME_HUSH_OFF, VOLUME_HUSH_VIBRATE, VOLUME_HUSH_MUTE.
*
diff --git a/core/java/com/android/internal/foldables/FoldLockSettingAvailabilityProvider.java b/core/java/com/android/internal/foldables/FoldLockSettingAvailabilityProvider.java
new file mode 100644
index 000000000000..4e3888a9e92d
--- /dev/null
+++ b/core/java/com/android/internal/foldables/FoldLockSettingAvailabilityProvider.java
@@ -0,0 +1,40 @@
+/*
+ * Copyright (C) 2023 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.internal.foldables;
+
+import android.content.res.Resources;
+import android.sysprop.FoldLockBehaviorProperties;
+
+import com.android.internal.R;
+
+/**
+ * Wrapper class to access {@link FoldLockBehaviorProperties} and also assists with testing
+ */
+public class FoldLockSettingAvailabilityProvider {
+
+ boolean mFoldLockBehaviorResourceValue;
+
+ public FoldLockSettingAvailabilityProvider(Resources resources) {
+ mFoldLockBehaviorResourceValue = resources.getBoolean(
+ R.bool.config_fold_lock_behavior);
+ }
+
+ public boolean isFoldLockBehaviorAvailable() {
+ return mFoldLockBehaviorResourceValue
+ && FoldLockBehaviorProperties.fold_lock_setting_enabled().orElse(false);
+ }
+}
diff --git a/core/sysprop/Android.bp b/core/sysprop/Android.bp
index f89099e5630d..512a2eb20abb 100644
--- a/core/sysprop/Android.bp
+++ b/core/sysprop/Android.bp
@@ -36,3 +36,10 @@ sysprop_library {
api_packages: ["android.sysprop"],
vendor_available: false,
}
+
+sysprop_library {
+ name: "com.android.sysprop.foldlockbehavior",
+ srcs: ["FoldLockBehaviorProperties.sysprop"],
+ property_owner: "Platform",
+ api_packages: ["android.sysprop"],
+}
diff --git a/core/sysprop/FoldLockBehaviorProperties.sysprop b/core/sysprop/FoldLockBehaviorProperties.sysprop
new file mode 100644
index 000000000000..d337954ff2a0
--- /dev/null
+++ b/core/sysprop/FoldLockBehaviorProperties.sysprop
@@ -0,0 +1,24 @@
+# Copyright (C) 2023 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.
+
+module: "android.sysprop.FoldLockBehaviorProperties"
+owner: Platform
+
+prop {
+ api_name: "fold_lock_setting_enabled"
+ type: Boolean
+ prop_name: "persist.fold_lock_setting_enabled"
+ scope: Internal
+ access: Readonly
+}
diff --git a/core/sysprop/api/com.android.sysprop.foldlockbehavior-current.txt b/core/sysprop/api/com.android.sysprop.foldlockbehavior-current.txt
new file mode 100644
index 000000000000..e69de29bb2d1
--- /dev/null
+++ b/core/sysprop/api/com.android.sysprop.foldlockbehavior-current.txt
diff --git a/core/sysprop/api/com.android.sysprop.foldlockbehavior-latest.txt b/core/sysprop/api/com.android.sysprop.foldlockbehavior-latest.txt
new file mode 100644
index 000000000000..13274708a20f
--- /dev/null
+++ b/core/sysprop/api/com.android.sysprop.foldlockbehavior-latest.txt
@@ -0,0 +1,9 @@
+props {
+ module: "android.sysprop.FoldLockBehaviorProperties"
+ prop {
+ api_name: "fold_lock_setting_enabled"
+ type: Boolean
+ prop_name: "persist.fold_lock_setting_enabled"
+ scope: Internal
+ }
+}
diff --git a/packages/SettingsProvider/src/android/provider/settings/backup/SecureSettings.java b/packages/SettingsProvider/src/android/provider/settings/backup/SecureSettings.java
index f6f75de1f24e..91d2d1bb58e5 100644
--- a/packages/SettingsProvider/src/android/provider/settings/backup/SecureSettings.java
+++ b/packages/SettingsProvider/src/android/provider/settings/backup/SecureSettings.java
@@ -143,7 +143,6 @@ public class SecureSettings {
Settings.Secure.SCREENSAVER_ACTIVATE_ON_SLEEP,
Settings.Secure.SCREENSAVER_HOME_CONTROLS_ENABLED,
Settings.Secure.SHOW_FIRST_CRASH_DIALOG_DEV_OPTION,
- Settings.Secure.VOLUME_DIALOG_DISMISS_TIMEOUT,
Settings.Secure.VOLUME_HUSH_GESTURE,
Settings.Secure.MANUAL_RINGER_TOGGLE_COUNT,
Settings.Secure.LOW_POWER_WARNING_ACKNOWLEDGED,
diff --git a/packages/SettingsProvider/src/android/provider/settings/validators/SecureSettingsValidators.java b/packages/SettingsProvider/src/android/provider/settings/validators/SecureSettingsValidators.java
index 8d13f01f1d03..bec144766438 100644
--- a/packages/SettingsProvider/src/android/provider/settings/validators/SecureSettingsValidators.java
+++ b/packages/SettingsProvider/src/android/provider/settings/validators/SecureSettingsValidators.java
@@ -212,7 +212,6 @@ public class SecureSettingsValidators {
VALIDATORS.put(Secure.SCREENSAVER_ACTIVATE_ON_SLEEP, BOOLEAN_VALIDATOR);
VALIDATORS.put(Secure.SCREENSAVER_HOME_CONTROLS_ENABLED, BOOLEAN_VALIDATOR);
VALIDATORS.put(Secure.SHOW_FIRST_CRASH_DIALOG_DEV_OPTION, BOOLEAN_VALIDATOR);
- VALIDATORS.put(Secure.VOLUME_DIALOG_DISMISS_TIMEOUT, NON_NEGATIVE_INTEGER_VALIDATOR);
VALIDATORS.put(Secure.VOLUME_HUSH_GESTURE, NON_NEGATIVE_INTEGER_VALIDATOR);
VALIDATORS.put(
Secure.ENABLED_NOTIFICATION_LISTENERS,
diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardSecurityContainer.java b/packages/SystemUI/src/com/android/keyguard/KeyguardSecurityContainer.java
index f7a4d47be800..a8bf229eb991 100644
--- a/packages/SystemUI/src/com/android/keyguard/KeyguardSecurityContainer.java
+++ b/packages/SystemUI/src/com/android/keyguard/KeyguardSecurityContainer.java
@@ -97,9 +97,9 @@ import com.android.keyguard.KeyguardSecurityModel.SecurityMode;
import com.android.settingslib.Utils;
import com.android.settingslib.drawable.CircleFramedDrawable;
import com.android.systemui.Gefingerpoken;
-import com.android.systemui.res.R;
import com.android.systemui.classifier.FalsingA11yDelegate;
import com.android.systemui.plugins.FalsingManager;
+import com.android.systemui.res.R;
import com.android.systemui.shade.TouchLogger;
import com.android.systemui.shared.system.SysUiStatsLog;
import com.android.systemui.statusbar.policy.BaseUserSwitcherAdapter;
@@ -1191,6 +1191,7 @@ public class KeyguardSecurityContainer extends ConstraintLayout {
mPopup.setOnItemClickListener((parent, view, pos, id) -> {
if (mFalsingManager.isFalseTap(LOW_PENALTY)) return;
if (!view.isEnabled()) return;
+ if (mPopup == null) return;
// Subtract one for the header
UserRecord user = adapter.getItem(pos - 1);
if (user.isManageUsers || user.isAddSupervisedUser) {
diff --git a/packages/SystemUI/src/com/android/systemui/flags/Flags.kt b/packages/SystemUI/src/com/android/systemui/flags/Flags.kt
index a00c3b5ae38e..dd6093d25b75 100644
--- a/packages/SystemUI/src/com/android/systemui/flags/Flags.kt
+++ b/packages/SystemUI/src/com/android/systemui/flags/Flags.kt
@@ -115,7 +115,7 @@ object Flags {
// TODO(b/292213543): Tracking Bug
@JvmField
val NOTIFICATION_GROUP_EXPANSION_CHANGE =
- unreleasedFlag("notification_group_expansion_change")
+ unreleasedFlag("notification_group_expansion_change", teamfood = true)
// TODO(b/301955929)
@JvmField
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tileimpl/QSTileImpl.java b/packages/SystemUI/src/com/android/systemui/qs/tileimpl/QSTileImpl.java
index 70df09d0876b..69fe46aa9009 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tileimpl/QSTileImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/tileimpl/QSTileImpl.java
@@ -83,7 +83,7 @@ import java.util.ArrayList;
*/
public abstract class QSTileImpl<TState extends State> implements QSTile, LifecycleOwner, Dumpable {
protected final String TAG = "Tile." + getClass().getSimpleName();
- protected static final boolean DEBUG = Log.isLoggable("Tile", Log.DEBUG);
+ protected final boolean DEBUG = Log.isLoggable("Tile", Log.DEBUG);
private static final long DEFAULT_STALE_TIMEOUT = 10 * DateUtils.MINUTE_IN_MILLIS;
protected static final Object ARG_SHOW_TRANSIENT_ENABLING = new Object();
diff --git a/packages/SystemUI/src/com/android/systemui/volume/VolumeDialogImpl.java b/packages/SystemUI/src/com/android/systemui/volume/VolumeDialogImpl.java
index 3c6d90dc08d2..727d649c8118 100644
--- a/packages/SystemUI/src/com/android/systemui/volume/VolumeDialogImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/volume/VolumeDialogImpl.java
@@ -135,7 +135,6 @@ import com.android.systemui.statusbar.policy.DevicePostureController;
import com.android.systemui.statusbar.policy.DeviceProvisionedController;
import com.android.systemui.util.AlphaTintDrawableWrapper;
import com.android.systemui.util.RoundedCornerProgressDrawable;
-import com.android.systemui.util.settings.SecureSettings;
import java.io.PrintWriter;
import java.util.ArrayList;
@@ -305,8 +304,6 @@ public class VolumeDialogImpl implements VolumeDialog, Dumpable,
private @DevicePostureController.DevicePostureInt int mDevicePosture;
private int mOrientation;
private final FeatureFlags mFeatureFlags;
- private final SecureSettings mSecureSettings;
- private int mDialogTimeoutMillis;
public VolumeDialogImpl(
Context context,
@@ -323,8 +320,7 @@ public class VolumeDialogImpl implements VolumeDialog, Dumpable,
DevicePostureController devicePostureController,
Looper looper,
DumpManager dumpManager,
- FeatureFlags featureFlags,
- SecureSettings secureSettings) {
+ FeatureFlags featureFlags) {
mFeatureFlags = featureFlags;
mContext =
new ContextThemeWrapper(context, R.style.volume_dialog_theme);
@@ -355,8 +351,6 @@ public class VolumeDialogImpl implements VolumeDialog, Dumpable,
mUseBackgroundBlur =
mContext.getResources().getBoolean(R.bool.config_volumeDialogUseBackgroundBlur);
mInteractionJankMonitor = interactionJankMonitor;
- mSecureSettings = secureSettings;
- mDialogTimeoutMillis = DIALOG_TIMEOUT_MILLIS;
dumpManager.registerDumpable("VolumeDialogImpl", this);
@@ -521,8 +515,6 @@ public class VolumeDialogImpl implements VolumeDialog, Dumpable,
mDialog.setContentView(R.layout.volume_dialog);
mDialogView = mDialog.findViewById(R.id.volume_dialog);
mDialogView.setAlpha(0);
- mDialogTimeoutMillis = mSecureSettings.getInt(Settings.Secure.VOLUME_DIALOG_DISMISS_TIMEOUT,
- DIALOG_TIMEOUT_MILLIS);
mDialog.setCanceledOnTouchOutside(true);
mDialog.setOnShowListener(dialog -> {
mDialogView.getViewTreeObserver().addOnComputeInternalInsetsListener(this);
@@ -535,7 +527,7 @@ public class VolumeDialogImpl implements VolumeDialog, Dumpable,
.alpha(1)
.translationX(0)
.setDuration(mDialogShowAnimationDurationMs)
- .setListener(getJankListener(getDialogView(), TYPE_SHOW, mDialogTimeoutMillis))
+ .setListener(getJankListener(getDialogView(), TYPE_SHOW, DIALOG_TIMEOUT_MILLIS))
.setInterpolator(new SystemUIInterpolators.LogDecelerateInterpolator())
.withEndAction(() -> {
if (!Prefs.getBoolean(mContext, Prefs.Key.TOUCHED_RINGER_TOGGLE, false)) {
@@ -1522,7 +1514,7 @@ public class VolumeDialogImpl implements VolumeDialog, Dumpable,
AccessibilityManager.FLAG_CONTENT_TEXT
| AccessibilityManager.FLAG_CONTENT_CONTROLS);
}
- return mAccessibilityMgr.getRecommendedTimeoutMillis(mDialogTimeoutMillis,
+ return mAccessibilityMgr.getRecommendedTimeoutMillis(DIALOG_TIMEOUT_MILLIS,
AccessibilityManager.FLAG_CONTENT_CONTROLS);
}
diff --git a/packages/SystemUI/src/com/android/systemui/volume/dagger/VolumeModule.java b/packages/SystemUI/src/com/android/systemui/volume/dagger/VolumeModule.java
index 624691b19704..cc9f3e14216e 100644
--- a/packages/SystemUI/src/com/android/systemui/volume/dagger/VolumeModule.java
+++ b/packages/SystemUI/src/com/android/systemui/volume/dagger/VolumeModule.java
@@ -31,7 +31,6 @@ import com.android.systemui.statusbar.policy.AccessibilityManagerWrapper;
import com.android.systemui.statusbar.policy.ConfigurationController;
import com.android.systemui.statusbar.policy.DevicePostureController;
import com.android.systemui.statusbar.policy.DeviceProvisionedController;
-import com.android.systemui.util.settings.SecureSettings;
import com.android.systemui.volume.CsdWarningDialog;
import com.android.systemui.volume.VolumeComponent;
import com.android.systemui.volume.VolumeDialogComponent;
@@ -64,8 +63,7 @@ public interface VolumeModule {
CsdWarningDialog.Factory csdFactory,
DevicePostureController devicePostureController,
DumpManager dumpManager,
- FeatureFlags featureFlags,
- SecureSettings secureSettings) {
+ FeatureFlags featureFlags) {
VolumeDialogImpl impl = new VolumeDialogImpl(
context,
volumeDialogController,
@@ -81,8 +79,7 @@ public interface VolumeModule {
devicePostureController,
Looper.getMainLooper(),
dumpManager,
- featureFlags,
- secureSettings);
+ featureFlags);
impl.setStreamImportant(AudioManager.STREAM_SYSTEM, false);
impl.setAutomute(true);
impl.setSilentMode(false);
diff --git a/packages/SystemUI/tests/src/com/android/systemui/volume/VolumeDialogImplTest.java b/packages/SystemUI/tests/src/com/android/systemui/volume/VolumeDialogImplTest.java
index daf88773780e..28fc5db150b7 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/volume/VolumeDialogImplTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/volume/VolumeDialogImplTest.java
@@ -42,7 +42,6 @@ import android.app.KeyguardManager;
import android.content.res.Configuration;
import android.media.AudioManager;
import android.os.SystemClock;
-import android.provider.Settings;
import android.testing.AndroidTestingRunner;
import android.testing.TestableLooper;
import android.util.Log;
@@ -71,7 +70,6 @@ import com.android.systemui.statusbar.policy.ConfigurationController;
import com.android.systemui.statusbar.policy.DevicePostureController;
import com.android.systemui.statusbar.policy.DeviceProvisionedController;
import com.android.systemui.statusbar.policy.FakeConfigurationController;
-import com.android.systemui.util.settings.FakeSettings;
import org.junit.After;
import org.junit.Before;
@@ -136,8 +134,6 @@ public class VolumeDialogImplTest extends SysuiTestCase {
private FakeFeatureFlags mFeatureFlags;
private int mLongestHideShowAnimationDuration = 250;
- private FakeSettings mSecureSettings;
-
@Rule
public final AnimatorTestRule mAnimatorTestRule = new AnimatorTestRule();
@@ -166,8 +162,6 @@ public class VolumeDialogImplTest extends SysuiTestCase {
mFeatureFlags = new FakeFeatureFlags();
- mSecureSettings = new FakeSettings();
-
mDialog = new VolumeDialogImpl(
getContext(),
mVolumeDialogController,
@@ -183,8 +177,7 @@ public class VolumeDialogImplTest extends SysuiTestCase {
mPostureController,
mTestableLooper.getLooper(),
mDumpManager,
- mFeatureFlags,
- mSecureSettings);
+ mFeatureFlags);
mDialog.init(0, null);
State state = createShellState();
mDialog.onStateChangedH(state);
@@ -249,18 +242,6 @@ public class VolumeDialogImplTest extends SysuiTestCase {
}
@Test
- public void testSetTimeoutValue_ComputeTimeout() {
- mSecureSettings.putInt(Settings.Secure.VOLUME_DIALOG_DISMISS_TIMEOUT, 7000);
- Mockito.reset(mAccessibilityMgr);
- mDialog.init(0, null);
- mDialog.rescheduleTimeoutH();
- verify(mAccessibilityMgr).getRecommendedTimeoutMillis(
- 7000,
- AccessibilityManager.FLAG_CONTENT_CONTROLS);
- }
-
-
- @Test
public void testComputeTimeout_tooltip() {
Mockito.reset(mAccessibilityMgr);
mDialog.showCaptionsTooltip();
diff --git a/services/core/java/com/android/server/Watchdog.java b/services/core/java/com/android/server/Watchdog.java
index e17424bac6b3..6e984bb4bb7b 100644
--- a/services/core/java/com/android/server/Watchdog.java
+++ b/services/core/java/com/android/server/Watchdog.java
@@ -250,6 +250,7 @@ public class Watchdog implements Dumpable {
private Monitor mCurrentMonitor;
private long mStartTimeMillis;
private int mPauseCount;
+ private long mOneOffTimeoutMillis;
HandlerChecker(Handler handler, String name) {
mHandler = handler;
@@ -269,7 +270,13 @@ public class Watchdog implements Dumpable {
* @param handlerCheckerTimeoutMillis the timeout to use for this run
*/
public void scheduleCheckLocked(long handlerCheckerTimeoutMillis) {
- mWaitMaxMillis = handlerCheckerTimeoutMillis;
+ if (mOneOffTimeoutMillis > 0) {
+ mWaitMaxMillis = mOneOffTimeoutMillis;
+ mOneOffTimeoutMillis = 0;
+ } else {
+ mWaitMaxMillis = handlerCheckerTimeoutMillis;
+ }
+
if (mCompleted) {
// Safe to update monitors in queue, Handler is not in the middle of work
mMonitors.addAll(mMonitorQueue);
@@ -352,6 +359,23 @@ public class Watchdog implements Dumpable {
}
}
+ /**
+ * Sets the timeout of the HandlerChecker for one run.
+ *
+ * <p>The current run will be ignored and the next run will be set to this timeout.
+ *
+ * <p>If a one off timeout is already set, the maximum timeout will be used.
+ */
+ public void setOneOffTimeoutLocked(int temporaryTimeoutMillis, String reason) {
+ mOneOffTimeoutMillis = Math.max(temporaryTimeoutMillis, mOneOffTimeoutMillis);
+ // Mark as completed, because there's a chance we called this after the watchog
+ // thread loop called Object#wait after 'WAITED_HALF'. In that case we want to ensure
+ // the next call to #getCompletionStateLocked for this checker returns 'COMPLETED'
+ mCompleted = true;
+ Slog.i(TAG, "Extending timeout of HandlerChecker: " + mName + " for reason: "
+ + reason + ". New timeout: " + mOneOffTimeoutMillis);
+ }
+
/** Pause the HandlerChecker. */
public void pauseLocked(String reason) {
mPauseCount++;
@@ -598,6 +622,27 @@ public class Watchdog implements Dumpable {
}
}
+ /**
+ * Sets a one-off timeout for the next run of the watchdog for this thread. This is useful
+ * to run a slow operation on one of the monitored thread.
+ *
+ * <p>After the next run, the timeout will go back to the default value.
+ *
+ * <p>If the current thread has not been added to the Watchdog, this call is a no-op.
+ *
+ * <p>If a one-off timeout for the current thread is already, the max value will be used.
+ */
+ public void setOneOffTimeoutForCurrentThread(int oneOffTimeoutMillis, String reason) {
+ synchronized (mLock) {
+ for (HandlerCheckerAndTimeout hc : mHandlerCheckers) {
+ HandlerChecker checker = hc.checker();
+ if (Thread.currentThread().equals(checker.getThread())) {
+ checker.setOneOffTimeoutLocked(oneOffTimeoutMillis, reason);
+ }
+ }
+ }
+ }
+
/**
* Pauses Watchdog action for the currently running thread. Useful before executing long running
* operations that could falsely trigger the watchdog. Each call to this will require a matching
@@ -609,7 +654,7 @@ public class Watchdog implements Dumpable {
* adds another pause and will require an additional {@link #resumeCurrentThread} to resume.
*
* <p>Note: Use with care, as any deadlocks on the current thread will be undetected until all
- * pauses have been resumed.
+ * pauses have been resumed. Prefer to use #setOneOffTimeoutForCurrentThread.
*/
public void pauseWatchingCurrentThread(String reason) {
synchronized (mLock) {
diff --git a/services/core/java/com/android/server/display/DisplayManagerService.java b/services/core/java/com/android/server/display/DisplayManagerService.java
index e942c1711088..d372f3031b81 100644
--- a/services/core/java/com/android/server/display/DisplayManagerService.java
+++ b/services/core/java/com/android/server/display/DisplayManagerService.java
@@ -142,6 +142,7 @@ import android.window.ScreenCapture;
import com.android.internal.annotations.GuardedBy;
import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.display.BrightnessSynchronizer;
+import com.android.internal.foldables.FoldLockSettingAvailabilityProvider;
import com.android.internal.os.BackgroundThread;
import com.android.internal.util.ArrayUtils;
import com.android.internal.util.DumpUtils;
@@ -548,6 +549,9 @@ public final class DisplayManagerService extends SystemService {
@VisibleForTesting
DisplayManagerService(Context context, Injector injector) {
super(context);
+ FoldSettingProvider foldSettingProvider = new FoldSettingProvider(context,
+ new SettingsWrapper(),
+ new FoldLockSettingAvailabilityProvider(context.getResources()));
mInjector = injector;
mContext = context;
mFlags = injector.getFlags();
@@ -555,8 +559,8 @@ public final class DisplayManagerService extends SystemService {
mUiHandler = UiThread.getHandler();
mDisplayDeviceRepo = new DisplayDeviceRepository(mSyncRoot, mPersistentDataStore);
mLogicalDisplayMapper = new LogicalDisplayMapper(mContext,
- new FoldSettingProvider(mContext, new SettingsWrapper()), mDisplayDeviceRepo,
- new LogicalDisplayListener(), mSyncRoot, mHandler, mFlags);
+ foldSettingProvider,
+ mDisplayDeviceRepo, new LogicalDisplayListener(), mSyncRoot, mHandler, mFlags);
mDisplayModeDirector = new DisplayModeDirector(context, mHandler, mFlags);
mBrightnessSynchronizer = new BrightnessSynchronizer(mContext);
Resources resources = mContext.getResources();
diff --git a/services/core/java/com/android/server/utils/FoldSettingProvider.java b/services/core/java/com/android/server/utils/FoldSettingProvider.java
index d62628b73019..552343ab56a3 100644
--- a/services/core/java/com/android/server/utils/FoldSettingProvider.java
+++ b/services/core/java/com/android/server/utils/FoldSettingProvider.java
@@ -22,7 +22,7 @@ import android.os.UserHandle;
import android.provider.Settings;
import android.util.Log;
-import com.android.internal.R;
+import com.android.internal.foldables.FoldLockSettingAvailabilityProvider;
import com.android.internal.util.SettingsWrapper;
import java.util.Set;
@@ -51,14 +51,14 @@ public class FoldSettingProvider {
private static final String TAG = "FoldSettingProvider";
private final ContentResolver mContentResolver;
- private final boolean mIsFoldLockBehaviorAvailable;
private final SettingsWrapper mSettingsWrapper;
+ private final FoldLockSettingAvailabilityProvider mFoldLockSettingAvailabilityProvider;
- public FoldSettingProvider(Context context, SettingsWrapper settingsWrapper) {
+ public FoldSettingProvider(Context context, SettingsWrapper settingsWrapper,
+ FoldLockSettingAvailabilityProvider foldLockSettingAvailabilityProvider) {
mContentResolver = context.getContentResolver();
mSettingsWrapper = settingsWrapper;
- mIsFoldLockBehaviorAvailable = context.getResources().getBoolean(
- R.bool.config_fold_lock_behavior);
+ mFoldLockSettingAvailabilityProvider = foldLockSettingAvailabilityProvider;
}
/**
@@ -83,7 +83,9 @@ public class FoldSettingProvider {
}
private String getFoldSettingValue() {
- if (!mIsFoldLockBehaviorAvailable) {
+ boolean isFoldLockBehaviorAvailable =
+ mFoldLockSettingAvailabilityProvider.isFoldLockBehaviorAvailable();
+ if (!isFoldLockBehaviorAvailable) {
return SETTING_VALUE_DEFAULT;
}
String foldSettingValue = mSettingsWrapper.getStringForUser(
diff --git a/services/core/java/com/android/server/wallpaper/WallpaperManagerService.java b/services/core/java/com/android/server/wallpaper/WallpaperManagerService.java
index 4c525e902b88..01ea33f1aecd 100644
--- a/services/core/java/com/android/server/wallpaper/WallpaperManagerService.java
+++ b/services/core/java/com/android/server/wallpaper/WallpaperManagerService.java
@@ -28,6 +28,7 @@ import static android.os.ParcelFileDescriptor.MODE_CREATE;
import static android.os.ParcelFileDescriptor.MODE_READ_ONLY;
import static android.os.ParcelFileDescriptor.MODE_READ_WRITE;
import static android.os.ParcelFileDescriptor.MODE_TRUNCATE;
+import static android.os.Process.THREAD_PRIORITY_FOREGROUND;
import static android.view.Display.DEFAULT_DISPLAY;
import static android.view.WindowManager.LayoutParams.TYPE_WALLPAPER;
@@ -74,6 +75,7 @@ import android.graphics.BitmapFactory;
import android.graphics.Rect;
import android.graphics.RectF;
import android.hardware.display.DisplayManager;
+import android.multiuser.Flags;
import android.os.Binder;
import android.os.Bundle;
import android.os.FileObserver;
@@ -114,6 +116,7 @@ import com.android.internal.util.DumpUtils;
import com.android.server.EventLogTags;
import com.android.server.FgThread;
import com.android.server.LocalServices;
+import com.android.server.ServiceThread;
import com.android.server.SystemService;
import com.android.server.pm.UserManagerInternal;
import com.android.server.utils.TimingsTraceAndSlog;
@@ -132,6 +135,7 @@ import java.util.Arrays;
import java.util.List;
import java.util.Map;
import java.util.Objects;
+import java.util.concurrent.atomic.AtomicBoolean;
import java.util.function.Consumer;
import java.util.function.Predicate;
@@ -746,6 +750,8 @@ public class WallpaperManagerService extends IWallpaperManager.Stub
}
private final Context mContext;
+ private final AtomicBoolean mIsInitialBinding = new AtomicBoolean(true);
+ private final ServiceThread mHandlerThread;
private final WindowManagerInternal mWindowManagerInternal;
private final PackageManagerInternal mPackageManagerInternal;
private final IPackageManager mIPackageManager;
@@ -1619,6 +1625,12 @@ public class WallpaperManagerService extends IWallpaperManager.Stub
public WallpaperManagerService(Context context) {
if (DEBUG) Slog.v(TAG, "WallpaperService startup");
mContext = context;
+ if (Flags.bindWallpaperServiceOnItsOwnThreadDuringAUserSwitch()) {
+ mHandlerThread = new ServiceThread(TAG, THREAD_PRIORITY_FOREGROUND, true /*allowIo*/);
+ mHandlerThread.start();
+ } else {
+ mHandlerThread = null;
+ }
mShuttingDown = false;
mImageWallpaper = ComponentName.unflattenFromString(
context.getResources().getString(R.string.image_wallpaper_component));
@@ -3652,7 +3664,10 @@ public class WallpaperManagerService extends IWallpaperManager.Stub
com.android.internal.R.bool.config_wallpaperTopApp)) {
bindFlags |= Context.BIND_SCHEDULE_LIKE_TOP_APP;
}
- boolean bindSuccess = mContext.bindServiceAsUser(intent, newConn, bindFlags,
+ Handler handler = Flags.bindWallpaperServiceOnItsOwnThreadDuringAUserSwitch()
+ && !mIsInitialBinding.compareAndSet(true, false)
+ ? mHandlerThread.getThreadHandler() : mContext.getMainThreadHandler();
+ boolean bindSuccess = mContext.bindServiceAsUser(intent, newConn, bindFlags, handler,
new UserHandle(serviceUserId));
if (!bindSuccess) {
String msg = "Unable to bind service: " + componentName;
diff --git a/services/tests/displayservicetests/src/com/android/server/display/DisplayPowerController2Test.java b/services/tests/displayservicetests/src/com/android/server/display/DisplayPowerController2Test.java
index dca69eb6dd98..8b54d6d22c2b 100644
--- a/services/tests/displayservicetests/src/com/android/server/display/DisplayPowerController2Test.java
+++ b/services/tests/displayservicetests/src/com/android/server/display/DisplayPowerController2Test.java
@@ -38,6 +38,7 @@ import static org.mockito.Mockito.spy;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.when;
+import android.app.ActivityManager;
import android.content.Context;
import android.content.res.Resources;
import android.hardware.Sensor;
@@ -158,6 +159,7 @@ public final class DisplayPowerController2Test {
.setStrictness(Strictness.LENIENT)
.spyStatic(SystemProperties.class)
.spyStatic(BatteryStatsService.class)
+ .spyStatic(ActivityManager.class)
.build();
@Rule
@@ -182,9 +184,14 @@ public final class DisplayPowerController2Test {
mContext.addMockSystemService(PowerManager.class, mPowerManagerMock);
+ mContext.getOrCreateTestableResources().addOverride(
+ com.android.internal.R.bool.config_displayColorFadeDisabled, false);
+
doAnswer((Answer<Void>) invocationOnMock -> null).when(() ->
SystemProperties.set(anyString(), any()));
doAnswer((Answer<Void>) invocationOnMock -> null).when(BatteryStatsService::getService);
+ doAnswer((Answer<Boolean>) invocationOnMock -> false)
+ .when(ActivityManager::isLowRamDeviceStatic);
setUpSensors();
mHolder = createDisplayPowerController(DISPLAY_ID, UNIQUE_ID);
diff --git a/services/tests/displayservicetests/src/com/android/server/display/DisplayPowerControllerTest.java b/services/tests/displayservicetests/src/com/android/server/display/DisplayPowerControllerTest.java
index edaa1d5013bf..37ee23f38b14 100644
--- a/services/tests/displayservicetests/src/com/android/server/display/DisplayPowerControllerTest.java
+++ b/services/tests/displayservicetests/src/com/android/server/display/DisplayPowerControllerTest.java
@@ -38,6 +38,7 @@ import static org.mockito.Mockito.spy;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.when;
+import android.app.ActivityManager;
import android.content.Context;
import android.content.res.Resources;
import android.hardware.Sensor;
@@ -158,6 +159,7 @@ public final class DisplayPowerControllerTest {
.setStrictness(Strictness.LENIENT)
.spyStatic(SystemProperties.class)
.spyStatic(BatteryStatsService.class)
+ .spyStatic(ActivityManager.class)
.build();
@Rule
@@ -186,9 +188,14 @@ public final class DisplayPowerControllerTest {
mContext.addMockSystemService(PowerManager.class, mPowerManagerMock);
+ mContext.getOrCreateTestableResources().addOverride(
+ com.android.internal.R.bool.config_displayColorFadeDisabled, false);
+
doAnswer((Answer<Void>) invocationOnMock -> null).when(() ->
SystemProperties.set(anyString(), any()));
doAnswer((Answer<Void>) invocationOnMock -> null).when(BatteryStatsService::getService);
+ doAnswer((Answer<Boolean>) invocationOnMock -> false)
+ .when(ActivityManager::isLowRamDeviceStatic);
setUpSensors();
mHolder = createDisplayPowerController(DISPLAY_ID, UNIQUE_ID);
diff --git a/services/tests/mockingservicestests/src/com/android/server/utils/FoldSettingProviderTest.java b/services/tests/mockingservicestests/src/com/android/server/utils/FoldSettingProviderTest.java
index 3514276ccb5b..4c4e9dfe0b98 100644
--- a/services/tests/mockingservicestests/src/com/android/server/utils/FoldSettingProviderTest.java
+++ b/services/tests/mockingservicestests/src/com/android/server/utils/FoldSettingProviderTest.java
@@ -27,13 +27,12 @@ import static org.mockito.Mockito.when;
import android.content.ContentResolver;
import android.content.Context;
-import android.content.res.Resources;
import android.os.UserHandle;
import android.provider.Settings;
import androidx.test.platform.app.InstrumentationRegistry;
-import com.android.internal.R;
+import com.android.internal.foldables.FoldLockSettingAvailabilityProvider;
import com.android.internal.util.SettingsWrapper;
import org.junit.Before;
@@ -48,9 +47,9 @@ public class FoldSettingProviderTest {
@Mock
private Context mContext;
@Mock
- private Resources mResources;
- @Mock
private SettingsWrapper mSettingsWrapper;
+ @Mock
+ private FoldLockSettingAvailabilityProvider mFoldLockSettingAvailabilityProvider;
private ContentResolver mContentResolver;
private FoldSettingProvider mFoldSettingProvider;
@@ -61,17 +60,18 @@ public class FoldSettingProviderTest {
mContentResolver =
InstrumentationRegistry.getInstrumentation().getContext().getContentResolver();
when(mContext.getContentResolver()).thenReturn(mContentResolver);
- when(mContext.getResources()).thenReturn(mResources);
setFoldLockBehaviorAvailability(true);
- mFoldSettingProvider = new FoldSettingProvider(mContext, mSettingsWrapper);
+ mFoldSettingProvider = new FoldSettingProvider(mContext, mSettingsWrapper,
+ mFoldLockSettingAvailabilityProvider);
}
@Test
public void foldSettingNotAvailable_returnDefaultSetting() {
setFoldLockBehaviorAvailability(false);
setFoldLockBehaviorSettingValue(SETTING_VALUE_STAY_AWAKE_ON_FOLD);
- mFoldSettingProvider = new FoldSettingProvider(mContext, mSettingsWrapper);
+ mFoldSettingProvider = new FoldSettingProvider(mContext, mSettingsWrapper,
+ mFoldLockSettingAvailabilityProvider);
boolean shouldSelectiveStayAwakeOnFold =
mFoldSettingProvider.shouldSelectiveStayAwakeOnFold();
@@ -83,7 +83,8 @@ public class FoldSettingProviderTest {
public void foldSettingNotAvailable_notReturnStayAwakeOnFoldTrue() {
setFoldLockBehaviorAvailability(false);
setFoldLockBehaviorSettingValue(SETTING_VALUE_STAY_AWAKE_ON_FOLD);
- mFoldSettingProvider = new FoldSettingProvider(mContext, mSettingsWrapper);
+ mFoldSettingProvider = new FoldSettingProvider(mContext, mSettingsWrapper,
+ mFoldLockSettingAvailabilityProvider);
boolean shouldStayAwakeOnFold = mFoldSettingProvider.shouldStayAwakeOnFold();
@@ -94,7 +95,8 @@ public class FoldSettingProviderTest {
public void foldSettingNotAvailable_notReturnSleepOnFoldTrue() {
setFoldLockBehaviorAvailability(false);
setFoldLockBehaviorSettingValue(SETTING_VALUE_SLEEP_ON_FOLD);
- mFoldSettingProvider = new FoldSettingProvider(mContext, mSettingsWrapper);
+ mFoldSettingProvider = new FoldSettingProvider(mContext, mSettingsWrapper,
+ mFoldLockSettingAvailabilityProvider);
boolean shouldSleepOnFold = mFoldSettingProvider.shouldSleepOnFold();
@@ -131,7 +133,7 @@ public class FoldSettingProviderTest {
}
private void setFoldLockBehaviorAvailability(boolean isFoldLockBehaviorEnabled) {
- when(mResources.getBoolean(R.bool.config_fold_lock_behavior)).thenReturn(
+ when(mFoldLockSettingAvailabilityProvider.isFoldLockBehaviorAvailable()).thenReturn(
isFoldLockBehaviorEnabled);
}