summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--apct-tests/perftests/windowmanager/src/android/wm/RecentsAnimationPerfTest.java7
-rw-r--r--apct-tests/perftests/windowmanager/src/android/wm/RelayoutPerfTest.java5
-rw-r--r--apct-tests/perftests/windowmanager/src/android/wm/WindowManagerPerfTestBase.java24
-rw-r--r--apex/jobscheduler/service/java/com/android/server/usage/AppStandbyController.java50
-rw-r--r--cmds/statsd/src/atoms.proto242
-rw-r--r--core/java/com/android/internal/util/ScreenshotHelper.java2
-rw-r--r--packages/CarSystemUI/res/values/config.xml3
-rw-r--r--packages/CarSystemUI/src/com/android/systemui/car/userswitcher/UserSwitchTransitionViewController.java37
-rw-r--r--packages/CarSystemUI/tests/src/com/android/systemui/car/userswitcher/UserSwitchTransitionViewControllerTest.java33
-rw-r--r--packages/SystemUI/res/values/strings.xml2
-rw-r--r--packages/SystemUI/shared/src/com/android/systemui/shared/system/BlurUtils.java37
-rw-r--r--packages/SystemUI/src/com/android/keyguard/KeyguardUpdateMonitor.java36
-rw-r--r--packages/SystemUI/src/com/android/systemui/bubbles/BubbleExpandedView.java5
-rw-r--r--packages/SystemUI/src/com/android/systemui/bubbles/BubbleStackView.java11
-rw-r--r--packages/SystemUI/src/com/android/systemui/bubbles/animation/ExpandedAnimationController.java52
-rw-r--r--packages/SystemUI/src/com/android/systemui/controls/controller/ControlsBindingController.kt2
-rw-r--r--packages/SystemUI/src/com/android/systemui/controls/controller/ControlsController.kt2
-rw-r--r--packages/SystemUI/src/com/android/systemui/controls/management/ControlsListingController.kt4
-rw-r--r--packages/SystemUI/src/com/android/systemui/media/MediaDataManager.kt41
-rw-r--r--packages/SystemUI/src/com/android/systemui/media/ResumeMediaBrowser.java17
-rw-r--r--packages/SystemUI/src/com/android/systemui/qs/AutoAddTracker.java64
-rw-r--r--packages/SystemUI/src/com/android/systemui/qs/QSTileHost.java3
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/phone/AutoTileManager.java78
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationModeController.java23
-rw-r--r--packages/SystemUI/src/com/android/systemui/util/UserAwareController.kt (renamed from packages/SystemUI/src/com/android/systemui/controls/UserAwareController.kt)4
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/bubbles/BubbleControllerTest.java2
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/bubbles/NewNotifPipelineBubbleControllerTest.java2
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/qs/AutoAddTrackerTest.java32
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/AutoTileManagerTest.java157
-rw-r--r--services/accessibility/java/com/android/server/accessibility/AccessibilityServiceConnection.java4
-rw-r--r--services/core/java/com/android/server/compat/PlatformCompat.java7
-rw-r--r--services/core/java/com/android/server/locksettings/RebootEscrowManager.java8
-rw-r--r--services/core/java/com/android/server/pm/AppsFilter.java22
-rw-r--r--services/core/java/com/android/server/pm/SELinuxMMAC.java3
-rw-r--r--services/tests/servicestests/src/com/android/server/locksettings/RebootEscrowManagerTests.java26
-rw-r--r--services/tests/servicestests/src/com/android/server/pm/SELinuxMMACTest.java6
36 files changed, 925 insertions, 128 deletions
diff --git a/apct-tests/perftests/windowmanager/src/android/wm/RecentsAnimationPerfTest.java b/apct-tests/perftests/windowmanager/src/android/wm/RecentsAnimationPerfTest.java
index 1667c1658a07..6122ef254855 100644
--- a/apct-tests/perftests/windowmanager/src/android/wm/RecentsAnimationPerfTest.java
+++ b/apct-tests/perftests/windowmanager/src/android/wm/RecentsAnimationPerfTest.java
@@ -23,6 +23,7 @@ import static androidx.test.platform.app.InstrumentationRegistry.getInstrumentat
import static org.hamcrest.core.AnyOf.anyOf;
import static org.hamcrest.core.Is.is;
+import android.app.ActivityManager;
import android.app.ActivityManager.TaskSnapshot;
import android.app.ActivityTaskManager;
import android.app.IActivityTaskManager;
@@ -121,6 +122,12 @@ public class RecentsAnimationPerfTest extends WindowManagerPerfTestBase {
@AfterClass
public static void tearDownClass() {
sSetUpClassException = null;
+ try {
+ // Recents activity may stop app switches. Restore the state to avoid affecting
+ // the next test.
+ ActivityManager.resumeAppSwitches();
+ } catch (RemoteException ignored) {
+ }
sUiAutomation.dropShellPermissionIdentity();
}
diff --git a/apct-tests/perftests/windowmanager/src/android/wm/RelayoutPerfTest.java b/apct-tests/perftests/windowmanager/src/android/wm/RelayoutPerfTest.java
index 8139a2e963c5..f04e55567520 100644
--- a/apct-tests/perftests/windowmanager/src/android/wm/RelayoutPerfTest.java
+++ b/apct-tests/perftests/windowmanager/src/android/wm/RelayoutPerfTest.java
@@ -88,10 +88,7 @@ public class RelayoutPerfTest extends WindowManagerPerfTestBase {
public void testRelayout() throws Throwable {
final Activity activity = mActivityRule.getActivity();
final ContentView contentView = new ContentView(activity);
- mActivityRule.runOnUiThread(() -> {
- activity.getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
- activity.setContentView(contentView);
- });
+ mActivityRule.runOnUiThread(() -> activity.setContentView(contentView));
getInstrumentation().waitForIdleSync();
final RelayoutRunner relayoutRunner = new RelayoutRunner(activity, contentView.getWindow(),
diff --git a/apct-tests/perftests/windowmanager/src/android/wm/WindowManagerPerfTestBase.java b/apct-tests/perftests/windowmanager/src/android/wm/WindowManagerPerfTestBase.java
index 9e17e940a06b..655d2f7f8aa7 100644
--- a/apct-tests/perftests/windowmanager/src/android/wm/WindowManagerPerfTestBase.java
+++ b/apct-tests/perftests/windowmanager/src/android/wm/WindowManagerPerfTestBase.java
@@ -19,11 +19,13 @@ package android.wm;
import static androidx.test.platform.app.InstrumentationRegistry.getInstrumentation;
import android.app.Activity;
+import android.app.KeyguardManager;
import android.app.UiAutomation;
import android.content.Context;
import android.content.Intent;
import android.os.BatteryManager;
import android.os.ParcelFileDescriptor;
+import android.os.PowerManager;
import android.perftests.utils.PerfTestActivity;
import android.provider.Settings;
@@ -61,24 +63,32 @@ public class WindowManagerPerfTestBase {
@BeforeClass
public static void setUpOnce() {
final Context context = getInstrumentation().getContext();
- sOriginalStayOnWhilePluggedIn = Settings.Global.getInt(context.getContentResolver(),
+ final int stayOnWhilePluggedIn = Settings.Global.getInt(context.getContentResolver(),
Settings.Global.STAY_ON_WHILE_PLUGGED_IN, 0);
- // Keep the device awake during testing.
- setStayOnWhilePluggedIn(BatteryManager.BATTERY_PLUGGED_USB);
+ sOriginalStayOnWhilePluggedIn = -1;
+ if (stayOnWhilePluggedIn != BatteryManager.BATTERY_PLUGGED_ANY) {
+ sOriginalStayOnWhilePluggedIn = stayOnWhilePluggedIn;
+ // Keep the device awake during testing.
+ setStayOnWhilePluggedIn(BatteryManager.BATTERY_PLUGGED_ANY);
+ }
if (!BASE_OUT_PATH.exists()) {
executeShellCommand("mkdir -p " + BASE_OUT_PATH);
}
- // In order to be closer to the real use case.
- executeShellCommand("input keyevent KEYCODE_WAKEUP");
- executeShellCommand("wm dismiss-keyguard");
+ if (!context.getSystemService(PowerManager.class).isInteractive()
+ || context.getSystemService(KeyguardManager.class).isKeyguardLocked()) {
+ executeShellCommand("input keyevent KEYCODE_WAKEUP");
+ executeShellCommand("wm dismiss-keyguard");
+ }
context.startActivity(new Intent(Intent.ACTION_MAIN)
.addCategory(Intent.CATEGORY_HOME).setFlags(Intent.FLAG_ACTIVITY_NEW_TASK));
}
@AfterClass
public static void tearDownOnce() {
- setStayOnWhilePluggedIn(sOriginalStayOnWhilePluggedIn);
+ if (sOriginalStayOnWhilePluggedIn != -1) {
+ setStayOnWhilePluggedIn(sOriginalStayOnWhilePluggedIn);
+ }
}
private static void setStayOnWhilePluggedIn(int value) {
diff --git a/apex/jobscheduler/service/java/com/android/server/usage/AppStandbyController.java b/apex/jobscheduler/service/java/com/android/server/usage/AppStandbyController.java
index 280a6870a5e1..062108757349 100644
--- a/apex/jobscheduler/service/java/com/android/server/usage/AppStandbyController.java
+++ b/apex/jobscheduler/service/java/com/android/server/usage/AppStandbyController.java
@@ -233,7 +233,7 @@ public class AppStandbyController implements AppStandbyInternal {
* Set of system apps that are headless (don't have any declared activities, enabled or
* disabled). Presence in this map indicates that the app is a headless system app.
*/
- @GuardedBy("mAppIdleLock")
+ @GuardedBy("mHeadlessSystemApps")
private final ArrayMap<String, Boolean> mHeadlessSystemApps = new ArrayMap<>();
private final CountDownLatch mAdminDataAvailableLatch = new CountDownLatch(1);
@@ -447,7 +447,8 @@ public class AppStandbyController implements AppStandbyInternal {
userFileExists = mAppIdleHistory.userFileExists(UserHandle.USER_SYSTEM);
}
- loadHeadlessSystemAppCache();
+ // Offload to handler thread to avoid boottime impact.
+ mHandler.post(this::loadHeadlessSystemAppCache);
if (mPendingInitializeDefaults || !userFileExists) {
initializeDefaultsForSystemApps(UserHandle.USER_SYSTEM);
@@ -1121,7 +1122,9 @@ public class AppStandbyController implements AppStandbyInternal {
}
private boolean isHeadlessSystemApp(String packageName) {
- return mHeadlessSystemApps.containsKey(packageName);
+ synchronized (mHeadlessSystemApps) {
+ return mHeadlessSystemApps.containsKey(packageName);
+ }
}
@Override
@@ -1697,19 +1700,24 @@ public class AppStandbyController implements AppStandbyInternal {
userId);
evaluateSystemAppException(pi);
} catch (PackageManager.NameNotFoundException e) {
- mHeadlessSystemApps.remove(packageName);
+ synchronized (mHeadlessSystemApps) {
+ mHeadlessSystemApps.remove(packageName);
+ }
}
}
- private void evaluateSystemAppException(@Nullable PackageInfo pkgInfo) {
- if (pkgInfo.applicationInfo != null && pkgInfo.applicationInfo.isSystemApp()) {
- synchronized (mAppIdleLock) {
- if (pkgInfo.activities == null || pkgInfo.activities.length == 0) {
- // Headless system app.
- mHeadlessSystemApps.put(pkgInfo.packageName, true);
- } else {
- mHeadlessSystemApps.remove(pkgInfo.packageName);
- }
+ /** Returns true if the exception status changed. */
+ private boolean evaluateSystemAppException(@Nullable PackageInfo pkgInfo) {
+ if (pkgInfo == null || pkgInfo.applicationInfo == null
+ || !pkgInfo.applicationInfo.isSystemApp()) {
+ return false;
+ }
+ synchronized (mHeadlessSystemApps) {
+ if (pkgInfo.activities == null || pkgInfo.activities.length == 0) {
+ // Headless system app.
+ return mHeadlessSystemApps.put(pkgInfo.packageName, true) == null;
+ } else {
+ return mHeadlessSystemApps.remove(pkgInfo.packageName) != null;
}
}
}
@@ -1754,7 +1762,12 @@ public class AppStandbyController implements AppStandbyInternal {
UserHandle.USER_SYSTEM);
final int packageCount = packages.size();
for (int i = 0; i < packageCount; i++) {
- evaluateSystemAppException(packages.get(i));
+ PackageInfo pkgInfo = packages.get(i);
+ if (pkgInfo != null && evaluateSystemAppException(pkgInfo)) {
+ mHandler.obtainMessage(MSG_CHECK_PACKAGE_IDLE_STATE,
+ UserHandle.USER_SYSTEM, -1, pkgInfo.packageName)
+ .sendToTarget();
+ }
}
}
@@ -1852,9 +1865,12 @@ public class AppStandbyController implements AppStandbyInternal {
pw.println();
pw.println("mHeadlessSystemApps=[");
- for (int i = mHeadlessSystemApps.size() - 1; i >= 0; --i) {
- pw.print(mHeadlessSystemApps.keyAt(i));
- pw.println(",");
+ synchronized (mHeadlessSystemApps) {
+ for (int i = mHeadlessSystemApps.size() - 1; i >= 0; --i) {
+ pw.print(" ");
+ pw.print(mHeadlessSystemApps.keyAt(i));
+ pw.println(",");
+ }
}
pw.println("]");
pw.println();
diff --git a/cmds/statsd/src/atoms.proto b/cmds/statsd/src/atoms.proto
index 2bbce11da2ff..e998711ef3c0 100644
--- a/cmds/statsd/src/atoms.proto
+++ b/cmds/statsd/src/atoms.proto
@@ -470,6 +470,14 @@ message Atom {
NetworkDhcpRenewReported network_dhcp_renew_reported = 291 [(module) = "network_stack"];
NetworkValidationReported network_validation_reported = 292 [(module) = "network_stack"];
NetworkStackQuirkReported network_stack_quirk_reported = 293 [(module) = "network_stack"];
+ MediametricsAudioRecordDeviceUsageReported mediametrics_audiorecorddeviceusage_reported =
+ 294;
+ MediametricsAudioThreadDeviceUsageReported mediametrics_audiothreaddeviceusage_reported =
+ 295;
+ MediametricsAudioTrackDeviceUsageReported mediametrics_audiotrackdeviceusage_reported =
+ 296;
+ MediametricsAudioDeviceConnectionReported mediametrics_audiodeviceconnection_reported =
+ 297;
// StatsdStats tracks platform atoms with ids upto 500.
// Update StatsdStats::kMaxPushedAtomId when atom ids here approach that value.
@@ -10549,3 +10557,237 @@ message AssistantInvocationReported {
// Whether the Assistant handles were showing at the time of invocation.
optional bool assistant_handles_showing = 6;
}
+
+/**
+ * Logs when an AudioRecord finishes running on an audio device
+ *
+ * Logged from:
+ * frameworks/av/services/mediametrics/AudioAnalytics.cpp
+ */
+message MediametricsAudioRecordDeviceUsageReported {
+ // The devices connected to this AudioRecord.
+ // A string OR of various input device categories, e.g. "DEVICE1|DEVICE2".
+ // See lookup<INPUT_DEVICE>() in frameworks/av/services/mediametrics/AudioTypes.cpp
+ // See audio_device_t in system/media/audio/include/system/audio-base.h
+ optional string devices = 1;
+
+ // The name of the remote device attached to the device, typically available for USB or BT.
+ // This may be empty for a fixed device, or separated by "|" if more than one.
+ optional string device_names = 2;
+
+ // The amount of time spent in the device as measured by the active track in AudioFlinger.
+ optional int64 device_time_nanos = 3;
+
+ // The audio data format used for encoding.
+ // An enumeration from system/media/audio/include/system/audio-base.h audio_format_t
+ optional string encoding = 4;
+
+ // The client-server buffer framecount.
+ // The framecount is generally between 960 - 48000 for PCM encoding.
+ // The framecount represents raw buffer size in bytes for non-PCM encoding.
+ optional int32 frame_count = 5;
+
+ // The number of audio intervals (contiguous, continuous playbacks).
+ optional int32 interval_count = 6;
+
+ // The sample rate of the AudioRecord.
+ // A number generally between 8000-96000 (frames per second).
+ optional int32 sample_rate = 7;
+
+ // The audio input flags used to construct the AudioRecord.
+ // A string OR from system/media/audio/include/system/audio-base.h audio_input_flags_t
+ optional string flags = 8;
+
+ // The santized package name of the audio client associated with the AudioRecord.
+ // See getSanitizedPackageNameAndVersionCode() in
+ // frameworks/av/services/mediametrics/MediaMetricsService.cpp
+ optional string package_name = 9;
+
+ // The selected device id (nonzero if a non-default device is selected)
+ optional int32 selected_device_id = 10;
+
+ // The caller of the AudioRecord.
+ // See lookup<CALLER_NAME>() in frameworks/av/services/mediametrics/AudioTypes.cpp
+ optional string caller = 11;
+
+ // The audio source for AudioRecord.
+ // An enumeration from system/media/audio/include/system/audio-base.h audio_source_t
+ optional string source = 12;
+}
+
+/**
+ * Logs when an AudioThread finishes running on an audio device
+ *
+ * Logged from:
+ * frameworks/av/services/mediametrics/AudioAnalytics.cpp
+ */
+message MediametricsAudioThreadDeviceUsageReported {
+ // The devices connected to this audio thread.
+ // A string OR of various input device categories, e.g. "DEVICE1|DEVICE2".
+ // (for record threads):
+ // See lookup<INPUT_DEVICE> in frameworks/av/services/mediametrics/AudioTypes.cpp
+ // (for playback threads):
+ // See lookup<OUTPUT_DEVICE>() in frameworks/av/services/mediametrics/AudioTypes.cpp
+ // See audio_device_t in system/media/audio/include/system/audio-base.h
+ optional string devices = 1;
+
+ // The name of the remote device attached to the device, typically available for USB or BT.
+ // This may be empty for a fixed device, or separated by "|" if more than one.
+ optional string device_names = 2;
+
+ // The amount of time spent in the device as measured by the active track in AudioFlinger.
+ optional int64 device_time_nanos = 3;
+
+ // The audio data format used for encoding.
+ // An enumeration from system/media/audio/include/system/audio-base.h audio_format_t
+ optional string encoding = 4;
+
+ // The framecount of the buffer delivered to (or from) the HAL.
+ // The framecount is generally ~960 for PCM encoding.
+ // The framecount represents raw buffer size in bytes for non-PCM encoding.
+ optional int32 frame_count = 5;
+
+ // The number of audio intervals (contiguous, continuous playbacks).
+ optional int32 interval_count = 6;
+
+ // The sample rate of the audio thread.
+ // A number generally between 8000-96000 (frames per second).
+ optional int32 sample_rate = 7;
+
+ // The audio flags used to construct the thread
+ // (for record threads):
+ // A string OR from system/media/audio/include/system/audio-base.h audio_input_flags_t
+ // (for playback threads):
+ // A string OR from system/media/audio/include/system/audio-base.h audio_output_flags_t
+ optional string flags = 8;
+
+ // The number of underruns encountered for a playback thread or the
+ // number of overruns encountered for a capture thread.
+ optional int32 xruns = 9;
+
+ // The type of thread
+ // A thread type enumeration from
+ // frameworks/av/mediametrics/services/Translate.h
+ optional string type = 10;
+}
+
+/**
+ * Logs when an AudioTrack finishes running on an audio device
+ *
+ * Logged from:
+ * frameworks/av/services/mediametrics/AudioAnalytics.cpp
+ */
+message MediametricsAudioTrackDeviceUsageReported {
+ // The output devices connected to this AudioTrack.
+ // A string OR of various output device categories, e.g. "DEVICE1|DEVICE2".
+ // See lookup<OUTPUT_DEVICE>() in frameworks/av/services/mediametrics/AudioTypes.cpp
+ // See audio_device_t in system/media/audio/include/system/audio-base.h
+ optional string devices = 1;
+
+ // The name of the remote device attached to the device, typically available for USB or BT.
+ // This may be empty for a fixed device, or separated by "|" if more than one.
+ optional string device_names = 2;
+
+ // The amount of time spent in the device as measured by the active track in AudioFlinger.
+ optional int64 device_time_nanos = 3;
+
+ // The audio data format used for encoding.
+ // An enumeration from system/media/audio/include/system/audio-base.h audio_format_t
+ optional string encoding = 4;
+
+ // The client-server buffer framecount.
+ // The framecount is generally between 960 - 48000 for PCM encoding.
+ // The framecount represents raw buffer size in bytes for non-PCM encoding.
+ // A static track (see traits) may have a very large framecount.
+ optional int32 frame_count = 5;
+
+ // The number of audio intervals (contiguous, continuous playbacks).
+ optional int32 interval_count = 6;
+
+ // The sample rate of the AudioTrack.
+ // A number generally between 8000-96000 (frames per second).
+ optional int32 sample_rate = 7;
+
+ // The audio flags used to construct the AudioTrack.
+ // A string OR from system/media/audio/include/system/audio-base.h audio_output_flags_t
+ optional string flags = 8;
+
+ // The number of underruns encountered.
+ optional int32 xruns = 9;
+
+ // The santized package name of the audio client associated with the AudioTrack.
+ // See getSanitizedPackageNameAndVersionCode() in
+ // frameworks/av/services/mediametrics/MediaMetricsService.cpp
+ optional string package_name = 10;
+
+ // The latency of the last sample in the buffer in milliseconds.
+ optional float device_latency_millis = 11;
+
+ // The startup time in milliseconds from start() to sample played.
+ optional float device_startup_millis = 12;
+
+ // The average volume of the track on the device [ 0.f - 1.f ]
+ optional float device_volume = 13;
+
+ // The selected device id (nonzero if a non-default device is selected)
+ optional int32 selected_device_id = 14;
+
+ // The stream_type category for the AudioTrack.
+ // An enumeration from system/media/audio/include/system/audio-base.h audio_stream_type_t
+ optional string stream_type = 15;
+
+ // The usage for the AudioTrack.
+ // An enumeration from system/media/audio/include/system/audio-base.h audio_usage_t
+ optional string usage = 16;
+
+ // The content type of the AudioTrack.
+ // An enumeration from system/media/audio/include/system/audio-base.h audio_content_type_t
+ optional string content_type = 17;
+
+ // The caller of the AudioTrack.
+ // See lookup<CALLER_NAME>() in frameworks/av/services/mediametrics/AudioTypes.cpp
+ optional string caller = 18;
+
+ // The traits of the AudioTrack.
+ // A string OR of different traits, may be empty string.
+ // Only "static" is supported for R.
+ // See lookup<TRACK_TRAITS>() in frameworks/av/services/mediametrics/AudioTypes.cpp
+ optional string traits = 19;
+}
+
+/**
+ * Logs the status of an audio device connection attempt.
+ *
+ * Logged from:
+ * frameworks/av/services/mediametrics/AudioAnalytics.cpp
+ */
+message MediametricsAudioDeviceConnectionReported {
+ // The input devices represented by this report.
+ // A string OR of various input device categories, e.g. "DEVICE1|DEVICE2".
+ // See lookup<INPUT_DEVICE>() in frameworks/av/services/mediametrics/AudioTypes.cpp
+ // See audio_device_t in system/media/audio/include/system/audio-base.h
+ optional string input_devices = 1;
+
+ // The output devices represented by this report.
+ // A string OR of various output device categories.
+ // See lookup<OUTPUT_DEVICE>() in frameworks/av/services/mediametrics/AudioTypes.cpp
+ // See audio_device_t in system/media/audio/include/system/audio-base.h
+ optional string output_devices = 2;
+
+ // The name of the remote device attached to the device, typically available for USB or BT.
+ // This may be empty for a fixed device, or separated by "|" if more than one.
+ optional string device_names = 3;
+
+ // The result of the audio device connection.
+ // 0 indicates success: connection verified.
+ // 1 indicates unknown: connection not verified or not known if diverted properly.
+ // Other values indicate specific status.
+ // See DeviceConnectionResult in frameworks/av/services/mediametrics/AudioTypes.h
+ optional int32 result = 4;
+
+ // Average milliseconds of time to connect
+ optional float time_to_connect_millis = 5;
+
+ // Number of connections if aggregated statistics, otherwise 1.
+ optional int32 connection_count = 6;
+}
diff --git a/core/java/com/android/internal/util/ScreenshotHelper.java b/core/java/com/android/internal/util/ScreenshotHelper.java
index d0052ab01331..9bf05135c4c5 100644
--- a/core/java/com/android/internal/util/ScreenshotHelper.java
+++ b/core/java/com/android/internal/util/ScreenshotHelper.java
@@ -316,7 +316,7 @@ public class ScreenshotHelper {
};
msg.replyTo = new Messenger(h);
- if (mScreenshotConnection == null) {
+ if (mScreenshotConnection == null || mScreenshotService == null) {
final ComponentName serviceComponent = ComponentName.unflattenFromString(
mContext.getResources().getString(
com.android.internal.R.string.config_screenshotServiceComponent));
diff --git a/packages/CarSystemUI/res/values/config.xml b/packages/CarSystemUI/res/values/config.xml
index 4bf0fca445d1..cf967c02bec5 100644
--- a/packages/CarSystemUI/res/values/config.xml
+++ b/packages/CarSystemUI/res/values/config.xml
@@ -118,4 +118,7 @@
<item>com.android.systemui.car.window.SystemUIOverlayWindowManager</item>
<item>com.android.systemui.car.volume.VolumeUI</item>
</string-array>
+
+ <!-- How many milliseconds to wait before force hiding the UserSwitchTransitionView -->
+ <integer name="config_userSwitchTransitionViewShownTimeoutMs" translatable="false">5000</integer>
</resources>
diff --git a/packages/CarSystemUI/src/com/android/systemui/car/userswitcher/UserSwitchTransitionViewController.java b/packages/CarSystemUI/src/com/android/systemui/car/userswitcher/UserSwitchTransitionViewController.java
index 775ef8152ca2..45f3d342fb6e 100644
--- a/packages/CarSystemUI/src/com/android/systemui/car/userswitcher/UserSwitchTransitionViewController.java
+++ b/packages/CarSystemUI/src/com/android/systemui/car/userswitcher/UserSwitchTransitionViewController.java
@@ -23,13 +23,17 @@ import android.content.Context;
import android.content.res.Resources;
import android.graphics.Bitmap;
import android.os.Handler;
+import android.os.RemoteException;
import android.os.UserHandle;
import android.os.UserManager;
import android.provider.Settings;
+import android.util.Log;
+import android.view.IWindowManager;
import android.widget.ImageView;
import android.widget.TextView;
import com.android.internal.annotations.GuardedBy;
+import com.android.internal.annotations.VisibleForTesting;
import com.android.settingslib.drawable.CircleFramedDrawable;
import com.android.systemui.R;
import com.android.systemui.car.window.OverlayViewController;
@@ -44,13 +48,24 @@ import javax.inject.Singleton;
*/
@Singleton
public class UserSwitchTransitionViewController extends OverlayViewController {
- private static final String TAG = "UserSwitchTransitionViewController";
+ private static final String TAG = "UserSwitchTransition";
private static final String ENABLE_DEVELOPER_MESSAGE_TRUE = "true";
+ private static final boolean DEBUG = false;
private final Context mContext;
private final Handler mHandler;
private final Resources mResources;
private final UserManager mUserManager;
+ private final IWindowManager mWindowManagerService;
+ private final int mWindowShownTimeoutMs;
+ private final Runnable mWindowShownTimeoutCallback = () -> {
+ if (DEBUG) {
+ Log.w(TAG, "Window was not hidden within " + getWindowShownTimeoutMs() + " ms, so it"
+ + "was hidden by mWindowShownTimeoutCallback.");
+ }
+
+ handleHide();
+ };
@GuardedBy("this")
private boolean mShowing;
@@ -62,6 +77,7 @@ public class UserSwitchTransitionViewController extends OverlayViewController {
@Main Handler handler,
@Main Resources resources,
UserManager userManager,
+ IWindowManager windowManagerService,
OverlayViewGlobalStateController overlayViewGlobalStateController) {
super(R.id.user_switching_dialog_stub, overlayViewGlobalStateController);
@@ -70,6 +86,9 @@ public class UserSwitchTransitionViewController extends OverlayViewController {
mHandler = handler;
mResources = resources;
mUserManager = userManager;
+ mWindowManagerService = windowManagerService;
+ mWindowShownTimeoutMs = mResources.getInteger(
+ R.integer.config_userSwitchTransitionViewShownTimeoutMs);
}
/**
@@ -81,10 +100,20 @@ public class UserSwitchTransitionViewController extends OverlayViewController {
if (mPreviousUserId == newUserId || mShowing) return;
mShowing = true;
mHandler.post(() -> {
+ try {
+ mWindowManagerService.setSwitchingUser(true);
+ mWindowManagerService.lockNow(null);
+ } catch (RemoteException e) {
+ Log.e(TAG, "unable to notify window manager service regarding user switch");
+ }
+
start();
populateDialog(mPreviousUserId, newUserId);
// next time a new user is selected, this current new user will be the previous user.
mPreviousUserId = newUserId;
+ // In case the window is still showing after WINDOW_SHOWN_TIMEOUT_MS, then hide the
+ // window and log a warning message.
+ mHandler.postDelayed(mWindowShownTimeoutCallback, mWindowShownTimeoutMs);
});
}
@@ -92,6 +121,12 @@ public class UserSwitchTransitionViewController extends OverlayViewController {
if (!mShowing) return;
mShowing = false;
mHandler.post(this::stop);
+ mHandler.removeCallbacks(mWindowShownTimeoutCallback);
+ }
+
+ @VisibleForTesting
+ int getWindowShownTimeoutMs() {
+ return mWindowShownTimeoutMs;
}
private void populateDialog(@UserIdInt int previousUserId, @UserIdInt int newUserId) {
diff --git a/packages/CarSystemUI/tests/src/com/android/systemui/car/userswitcher/UserSwitchTransitionViewControllerTest.java b/packages/CarSystemUI/tests/src/com/android/systemui/car/userswitcher/UserSwitchTransitionViewControllerTest.java
index eab381c92d98..797dbf515b7e 100644
--- a/packages/CarSystemUI/tests/src/com/android/systemui/car/userswitcher/UserSwitchTransitionViewControllerTest.java
+++ b/packages/CarSystemUI/tests/src/com/android/systemui/car/userswitcher/UserSwitchTransitionViewControllerTest.java
@@ -18,6 +18,8 @@ package com.android.systemui.car.userswitcher;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.eq;
+import static org.mockito.Mockito.never;
+import static org.mockito.Mockito.reset;
import static org.mockito.Mockito.verify;
import android.content.Context;
@@ -28,6 +30,7 @@ import android.test.suitebuilder.annotation.SmallTest;
import android.testing.AndroidTestingRunner;
import android.testing.TestableLooper;
import android.testing.TestableResources;
+import android.view.IWindowManager;
import android.view.LayoutInflater;
import android.view.ViewGroup;
@@ -52,6 +55,8 @@ public class UserSwitchTransitionViewControllerTest extends SysuiTestCase {
private TestableResources mTestableResources;
@Mock
private OverlayViewGlobalStateController mOverlayViewGlobalStateController;
+ @Mock
+ private IWindowManager mWindowManagerService;
@Before
public void setUp() {
@@ -62,6 +67,7 @@ public class UserSwitchTransitionViewControllerTest extends SysuiTestCase {
Handler.getMain(),
mTestableResources.getResources(),
(UserManager) mContext.getSystemService(Context.USER_SERVICE),
+ mWindowManagerService,
mOverlayViewGlobalStateController
);
@@ -118,6 +124,29 @@ public class UserSwitchTransitionViewControllerTest extends SysuiTestCase {
any());
}
+ @Test
+ public void onWindowShownTimeoutPassed_viewNotHidden_hidesUserSwitchTransitionView() {
+ mCarUserSwitchingDialogController.handleShow(/* currentUserId= */ TEST_USER_1);
+ reset(mOverlayViewGlobalStateController);
+
+ getContext().getMainThreadHandler().postDelayed(() -> {
+ verify(mOverlayViewGlobalStateController).hideView(
+ eq(mCarUserSwitchingDialogController), any());
+ }, mCarUserSwitchingDialogController.getWindowShownTimeoutMs() + 10);
+ }
+
+ @Test
+ public void onWindowShownTimeoutPassed_viewHidden_doesNotHideUserSwitchTransitionViewAgain() {
+ mCarUserSwitchingDialogController.handleShow(/* currentUserId= */ TEST_USER_1);
+ mCarUserSwitchingDialogController.handleHide();
+ reset(mOverlayViewGlobalStateController);
+
+ getContext().getMainThreadHandler().postDelayed(() -> {
+ verify(mOverlayViewGlobalStateController, never()).hideView(
+ eq(mCarUserSwitchingDialogController), any());
+ }, mCarUserSwitchingDialogController.getWindowShownTimeoutMs() + 10);
+ }
+
private final class TestableUserSwitchTransitionViewController extends
UserSwitchTransitionViewController {
@@ -125,8 +154,10 @@ public class UserSwitchTransitionViewControllerTest extends SysuiTestCase {
TestableUserSwitchTransitionViewController(Context context, Handler handler,
Resources resources, UserManager userManager,
+ IWindowManager windowManagerService,
OverlayViewGlobalStateController overlayViewGlobalStateController) {
- super(context, handler, resources, userManager, overlayViewGlobalStateController);
+ super(context, handler, resources, userManager, windowManagerService,
+ overlayViewGlobalStateController);
mHandler = handler;
}
diff --git a/packages/SystemUI/res/values/strings.xml b/packages/SystemUI/res/values/strings.xml
index 48ff5c681853..f4141e2f2ee8 100644
--- a/packages/SystemUI/res/values/strings.xml
+++ b/packages/SystemUI/res/values/strings.xml
@@ -2640,7 +2640,7 @@
<string name="bubble_accessibility_action_move_bottom_left">Move bottom left</string>
<!-- Action in accessibility menu to move the stack of bubbles to the bottom right of the screen. [CHAR LIMIT=30]-->
<string name="bubble_accessibility_action_move_bottom_right">Move bottom right</string>
- <!-- Text used for the bubble dismiss area. Bubbles dragged to, or flung towards, this area will go away. [CHAR LIMIT=20] -->
+ <!-- Text used for the bubble dismiss area. Bubbles dragged to, or flung towards, this area will go away. [CHAR LIMIT=30] -->
<string name="bubble_dismiss_text">Dismiss bubble</string>
<!-- Button text to stop a conversation from bubbling [CHAR LIMIT=60]-->
<string name="bubbles_dont_bubble_conversation">Don\u2019t bubble conversation</string>
diff --git a/packages/SystemUI/shared/src/com/android/systemui/shared/system/BlurUtils.java b/packages/SystemUI/shared/src/com/android/systemui/shared/system/BlurUtils.java
new file mode 100644
index 000000000000..9f26d851f775
--- /dev/null
+++ b/packages/SystemUI/shared/src/com/android/systemui/shared/system/BlurUtils.java
@@ -0,0 +1,37 @@
+/*
+ * Copyright (C) 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License
+ */
+
+package com.android.systemui.shared.system;
+
+import android.app.ActivityManager;
+import android.os.SystemProperties;
+
+public abstract class BlurUtils {
+
+ private static boolean mBlurSupportedSysProp = SystemProperties
+ .getBoolean("ro.surface_flinger.supports_background_blur", false);
+ private static boolean mBlurDisabledSysProp = SystemProperties
+ .getBoolean("persist.sys.sf.disable_blurs", false);
+
+ /**
+ * If this device can render blurs.
+ *
+ * @return {@code true} when supported.
+ */
+ public static boolean supportsBlursOnWindows() {
+ return mBlurSupportedSysProp && !mBlurDisabledSysProp && ActivityManager.isHighEndGfx();
+ }
+}
diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardUpdateMonitor.java b/packages/SystemUI/src/com/android/keyguard/KeyguardUpdateMonitor.java
index 34c85877577b..7914d864da0f 100644
--- a/packages/SystemUI/src/com/android/keyguard/KeyguardUpdateMonitor.java
+++ b/packages/SystemUI/src/com/android/keyguard/KeyguardUpdateMonitor.java
@@ -79,6 +79,7 @@ import android.telephony.SubscriptionInfo;
import android.telephony.SubscriptionManager;
import android.telephony.SubscriptionManager.OnSubscriptionsChangedListener;
import android.telephony.TelephonyManager;
+import android.util.EventLog;
import android.util.Log;
import android.util.SparseArray;
import android.util.SparseBooleanArray;
@@ -1074,6 +1075,17 @@ public class KeyguardUpdateMonitor implements TrustManager.TrustListener, Dumpab
!= LockPatternUtils.StrongAuthTracker.STRONG_AUTH_NOT_REQUIRED;
}
+ private boolean isUserEncryptedOrLockdown(int userId) {
+ // Biometrics should not be started in this case. Think carefully before modifying this
+ // method, see b/79776455
+ final int strongAuth = mStrongAuthTracker.getStrongAuthForUser(userId);
+ final boolean isLockDown =
+ containsFlag(strongAuth, STRONG_AUTH_REQUIRED_AFTER_DPM_LOCK_NOW)
+ || containsFlag(strongAuth, STRONG_AUTH_REQUIRED_AFTER_USER_LOCKDOWN);
+ final boolean isEncrypted = containsFlag(strongAuth, STRONG_AUTH_REQUIRED_AFTER_BOOT);
+ return isLockDown || isEncrypted;
+ }
+
private boolean containsFlag(int haystack, int needle) {
return (haystack & needle) != 0;
}
@@ -1904,11 +1916,6 @@ public class KeyguardUpdateMonitor implements TrustManager.TrustListener, Dumpab
final boolean allowedOnBouncer =
!(mFingerprintLockedOut && mBouncer && mCredentialAttempted);
final int user = getCurrentUser();
- final int strongAuth = mStrongAuthTracker.getStrongAuthForUser(user);
- final boolean isLockDown =
- containsFlag(strongAuth, STRONG_AUTH_REQUIRED_AFTER_DPM_LOCK_NOW)
- || containsFlag(strongAuth, STRONG_AUTH_REQUIRED_AFTER_USER_LOCKDOWN);
- final boolean isEncrypted = containsFlag(strongAuth, STRONG_AUTH_REQUIRED_AFTER_BOOT);
// Only listen if this KeyguardUpdateMonitor belongs to the primary user. There is an
// instance of KeyguardUpdateMonitor for each user but KeyguardUpdateMonitor is user-aware.
@@ -1917,7 +1924,7 @@ public class KeyguardUpdateMonitor implements TrustManager.TrustListener, Dumpab
shouldListenForFingerprintAssistant() || (mKeyguardOccluded && mIsDreaming))
&& !mSwitchingUser && !isFingerprintDisabled(getCurrentUser())
&& (!mKeyguardGoingAway || !mDeviceInteractive) && mIsPrimaryUser
- && allowedOnBouncer && !isLockDown && !isEncrypted;
+ && allowedOnBouncer && !isUserEncryptedOrLockdown(user);
return shouldListen;
}
@@ -1931,11 +1938,6 @@ public class KeyguardUpdateMonitor implements TrustManager.TrustListener, Dumpab
&& !statusBarShadeLocked;
final int user = getCurrentUser();
final int strongAuth = mStrongAuthTracker.getStrongAuthForUser(user);
- final boolean isLockDown =
- containsFlag(strongAuth, STRONG_AUTH_REQUIRED_AFTER_DPM_LOCK_NOW)
- || containsFlag(strongAuth, STRONG_AUTH_REQUIRED_AFTER_USER_LOCKDOWN);
- final boolean isEncrypted =
- containsFlag(strongAuth, STRONG_AUTH_REQUIRED_AFTER_BOOT);
final boolean isTimedOut =
containsFlag(strongAuth, STRONG_AUTH_REQUIRED_AFTER_TIMEOUT);
@@ -1958,7 +1960,7 @@ public class KeyguardUpdateMonitor implements TrustManager.TrustListener, Dumpab
&& !mSwitchingUser && !isFaceDisabled(user) && becauseCannotSkipBouncer
&& !mKeyguardGoingAway && mFaceSettingEnabledForUser.get(user) && !mLockIconPressed
&& strongAuthAllowsScanning && mIsPrimaryUser
- && !mSecureCameraLaunched && !isLockDown && !isEncrypted;
+ && !mSecureCameraLaunched && !isUserEncryptedOrLockdown(user);
// Aggregate relevant fields for debug logging.
if (DEBUG_FACE || DEBUG_SPEW) {
@@ -2031,6 +2033,11 @@ public class KeyguardUpdateMonitor implements TrustManager.TrustListener, Dumpab
if (mFingerprintCancelSignal != null) {
mFingerprintCancelSignal.cancel();
}
+
+ if (isUserEncryptedOrLockdown(userId)) {
+ // If this happens, shouldListenForFingerprint() is wrong. SafetyNet for b/79776455
+ EventLog.writeEvent(0x534e4554, "79776455", "startListeningForFingerprint");
+ }
mFingerprintCancelSignal = new CancellationSignal();
mFpm.authenticate(null, mFingerprintCancelSignal, 0, mFingerprintAuthenticationCallback,
null, userId);
@@ -2049,6 +2056,11 @@ public class KeyguardUpdateMonitor implements TrustManager.TrustListener, Dumpab
if (mFaceCancelSignal != null) {
mFaceCancelSignal.cancel();
}
+
+ if (isUserEncryptedOrLockdown(userId)) {
+ // If this happens, shouldListenForFace() is wrong. SafetyNet for b/79776455
+ EventLog.writeEvent(0x534e4554, "79776455", "startListeningForFace");
+ }
mFaceCancelSignal = new CancellationSignal();
mFaceManager.authenticate(null, mFaceCancelSignal, 0,
mFaceAuthenticationCallback, null, userId);
diff --git a/packages/SystemUI/src/com/android/systemui/bubbles/BubbleExpandedView.java b/packages/SystemUI/src/com/android/systemui/bubbles/BubbleExpandedView.java
index 47e6645d347f..6dcc9dcdc63c 100644
--- a/packages/SystemUI/src/com/android/systemui/bubbles/BubbleExpandedView.java
+++ b/packages/SystemUI/src/com/android/systemui/bubbles/BubbleExpandedView.java
@@ -163,6 +163,11 @@ public class BubbleExpandedView extends LinearLayout {
Log.d(TAG, "onActivityViewReady: calling startActivity, "
+ "bubble=" + getBubbleKey());
}
+ if (mActivityView == null) {
+ mBubbleController.removeBubble(getBubbleKey(),
+ BubbleController.DISMISS_INVALID_INTENT);
+ return;
+ }
try {
if (!mIsOverflow && mBubble.usingShortcutInfo()) {
options.setApplyActivityFlagsForBubbles(true);
diff --git a/packages/SystemUI/src/com/android/systemui/bubbles/BubbleStackView.java b/packages/SystemUI/src/com/android/systemui/bubbles/BubbleStackView.java
index 015079ff900a..dd999c22e1fe 100644
--- a/packages/SystemUI/src/com/android/systemui/bubbles/BubbleStackView.java
+++ b/packages/SystemUI/src/com/android/systemui/bubbles/BubbleStackView.java
@@ -534,6 +534,8 @@ public class BubbleStackView extends FrameLayout
mMagneticTarget,
mIndividualBubbleMagnetListener);
+ hideImeFromExpandedBubble();
+
// Save the magnetized individual bubble so we can dispatch touch events to it.
mMagnetizedObject = mExpandedAnimationController.getMagnetizedBubbleDraggingOut();
} else {
@@ -1104,7 +1106,10 @@ public class BubbleStackView extends FrameLayout
}
mBubbleContainer.addView(mBubbleOverflow.getBtn(), overflowBtnIndex,
new FrameLayout.LayoutParams(WRAP_CONTENT, WRAP_CONTENT));
- mBubbleOverflow.getBtn().setOnClickListener(v -> setSelectedBubble(mBubbleOverflow));
+ mBubbleOverflow.getBtn().setOnClickListener(v -> {
+ setSelectedBubble(mBubbleOverflow);
+ showManageMenu(false);
+ });
}
/**
* Handle theme changes.
@@ -1822,6 +1827,10 @@ public class BubbleStackView extends FrameLayout
mExpandedBubble.getExpandedView().hideImeIfVisible();
}
+ // Let the expanded animation controller know that it shouldn't animate child adds/reorders
+ // since we're about to animate collapsed.
+ mExpandedAnimationController.notifyPreparingToCollapse();
+
final long startDelay =
(long) (ExpandedAnimationController.EXPAND_COLLAPSE_TARGET_ANIM_DURATION * 0.6f);
postDelayed(() -> mExpandedAnimationController.collapseBackToStack(
diff --git a/packages/SystemUI/src/com/android/systemui/bubbles/animation/ExpandedAnimationController.java b/packages/SystemUI/src/com/android/systemui/bubbles/animation/ExpandedAnimationController.java
index 86fe10dddc2c..cb8995a72dc3 100644
--- a/packages/SystemUI/src/com/android/systemui/bubbles/animation/ExpandedAnimationController.java
+++ b/packages/SystemUI/src/com/android/systemui/bubbles/animation/ExpandedAnimationController.java
@@ -92,6 +92,14 @@ public class ExpandedAnimationController
private int mScreenOrientation;
private boolean mAnimatingExpand = false;
+
+ /**
+ * Whether we are animating other Bubbles UI elements out in preparation for a call to
+ * {@link #collapseBackToStack}. If true, we won't animate bubbles in response to adds or
+ * reorders.
+ */
+ private boolean mPreparingToCollapse = false;
+
private boolean mAnimatingCollapse = false;
private @Nullable Runnable mAfterExpand;
private Runnable mAfterCollapse;
@@ -150,6 +158,7 @@ public class ExpandedAnimationController
*/
public void expandFromStack(
@Nullable Runnable after, @Nullable Runnable leadBubbleEndAction) {
+ mPreparingToCollapse = false;
mAnimatingCollapse = false;
mAnimatingExpand = true;
mAfterExpand = after;
@@ -165,9 +174,20 @@ public class ExpandedAnimationController
expandFromStack(after, null /* leadBubbleEndAction */);
}
+ /**
+ * Sets that we're animating the stack collapsed, but haven't yet called
+ * {@link #collapseBackToStack}. This will temporarily suspend animations for bubbles that are
+ * added or re-ordered, since the upcoming collapse animation will handle positioning those
+ * bubbles in the collapsed stack.
+ */
+ public void notifyPreparingToCollapse() {
+ mPreparingToCollapse = true;
+ }
+
/** Animate collapsing the bubbles back to their stacked position. */
public void collapseBackToStack(PointF collapsePoint, Runnable after) {
mAnimatingExpand = false;
+ mPreparingToCollapse = false;
mAnimatingCollapse = true;
mAfterCollapse = after;
mCollapsePoint = collapsePoint;
@@ -501,12 +521,18 @@ public class ExpandedAnimationController
startOrUpdatePathAnimation(false /* expanding */);
} else {
child.setTranslationX(getBubbleLeft(index));
- animationForChild(child)
- .translationY(
- getExpandedY() - mBubbleSizePx * ANIMATE_TRANSLATION_FACTOR, /* from */
- getExpandedY() /* to */)
- .start();
- updateBubblePositions();
+
+ // If we're preparing to collapse, don't start animations since the collapse animation
+ // will take over and animate the new bubble into the correct (stacked) position.
+ if (!mPreparingToCollapse) {
+ animationForChild(child)
+ .translationY(
+ getExpandedY()
+ - mBubbleSizePx * ANIMATE_TRANSLATION_FACTOR, /* from */
+ getExpandedY() /* to */)
+ .start();
+ updateBubblePositions();
+ }
}
}
@@ -532,12 +558,20 @@ public class ExpandedAnimationController
@Override
void onChildReordered(View child, int oldIndex, int newIndex) {
- updateBubblePositions();
+ if (mPreparingToCollapse) {
+ // If a re-order is received while we're preparing to collapse, ignore it. Once started,
+ // the collapse animation will animate all of the bubbles to their correct (stacked)
+ // position.
+ return;
+ }
- // We expect reordering during collapse, since we'll put the last selected bubble on top.
- // Update the collapse animation so they end up in the right stacked positions.
if (mAnimatingCollapse) {
+ // If a re-order is received during collapse, update the animation so that the bubbles
+ // end up in the correct (stacked) position.
startOrUpdatePathAnimation(false /* expanding */);
+ } else {
+ // Otherwise, animate the bubbles around to reflect their new order.
+ updateBubblePositions();
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/controls/controller/ControlsBindingController.kt b/packages/SystemUI/src/com/android/systemui/controls/controller/ControlsBindingController.kt
index d4d4d2a7d8fe..eed55315e836 100644
--- a/packages/SystemUI/src/com/android/systemui/controls/controller/ControlsBindingController.kt
+++ b/packages/SystemUI/src/com/android/systemui/controls/controller/ControlsBindingController.kt
@@ -20,7 +20,7 @@ import android.content.ComponentName
import android.service.controls.Control
import android.service.controls.ControlsProviderService
import android.service.controls.actions.ControlAction
-import com.android.systemui.controls.UserAwareController
+import com.android.systemui.util.UserAwareController
import java.util.function.Consumer
/**
diff --git a/packages/SystemUI/src/com/android/systemui/controls/controller/ControlsController.kt b/packages/SystemUI/src/com/android/systemui/controls/controller/ControlsController.kt
index 45ba1e6012fe..496741b1cd6f 100644
--- a/packages/SystemUI/src/com/android/systemui/controls/controller/ControlsController.kt
+++ b/packages/SystemUI/src/com/android/systemui/controls/controller/ControlsController.kt
@@ -21,7 +21,7 @@ import android.service.controls.Control
import android.service.controls.ControlsProviderService
import android.service.controls.actions.ControlAction
import com.android.systemui.controls.ControlStatus
-import com.android.systemui.controls.UserAwareController
+import com.android.systemui.util.UserAwareController
import com.android.systemui.controls.management.ControlsFavoritingActivity
import com.android.systemui.controls.ui.ControlsUiController
import java.util.function.Consumer
diff --git a/packages/SystemUI/src/com/android/systemui/controls/management/ControlsListingController.kt b/packages/SystemUI/src/com/android/systemui/controls/management/ControlsListingController.kt
index 647daccca8bd..b9f16665944f 100644
--- a/packages/SystemUI/src/com/android/systemui/controls/management/ControlsListingController.kt
+++ b/packages/SystemUI/src/com/android/systemui/controls/management/ControlsListingController.kt
@@ -18,7 +18,7 @@ package com.android.systemui.controls.management
import android.content.ComponentName
import com.android.systemui.controls.ControlsServiceInfo
-import com.android.systemui.controls.UserAwareController
+import com.android.systemui.util.UserAwareController
import com.android.systemui.statusbar.policy.CallbackController
/**
@@ -26,7 +26,7 @@ import com.android.systemui.statusbar.policy.CallbackController
*/
interface ControlsListingController :
CallbackController<ControlsListingController.ControlsListingCallback>,
- UserAwareController {
+ UserAwareController {
/**
* @return the current list of services that satisfies the [ServiceListing].
diff --git a/packages/SystemUI/src/com/android/systemui/media/MediaDataManager.kt b/packages/SystemUI/src/com/android/systemui/media/MediaDataManager.kt
index 6ea36ab3af2f..5fe39958fd67 100644
--- a/packages/SystemUI/src/com/android/systemui/media/MediaDataManager.kt
+++ b/packages/SystemUI/src/com/android/systemui/media/MediaDataManager.kt
@@ -109,6 +109,24 @@ class MediaDataManager @Inject constructor(
}
}
+ private val appChangeReceiver = object : BroadcastReceiver() {
+ override fun onReceive(context: Context, intent: Intent) {
+ when (intent.action) {
+ Intent.ACTION_PACKAGES_SUSPENDED -> {
+ val packages = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST)
+ packages?.forEach {
+ removeAllForPackage(it)
+ }
+ }
+ Intent.ACTION_PACKAGE_REMOVED, Intent.ACTION_PACKAGE_RESTARTED -> {
+ intent.data?.encodedSchemeSpecificPart?.let {
+ removeAllForPackage(it)
+ }
+ }
+ }
+ }
+ }
+
init {
mediaTimeoutListener.timeoutCallback = { token: String, timedOut: Boolean ->
setTimedOut(token, timedOut) }
@@ -129,6 +147,17 @@ class MediaDataManager @Inject constructor(
val userFilter = IntentFilter(Intent.ACTION_USER_SWITCHED)
broadcastDispatcher.registerReceiver(userChangeReceiver, userFilter, null, UserHandle.ALL)
+
+ val suspendFilter = IntentFilter(Intent.ACTION_PACKAGES_SUSPENDED)
+ broadcastDispatcher.registerReceiver(appChangeReceiver, suspendFilter, null, UserHandle.ALL)
+
+ val uninstallFilter = IntentFilter().apply {
+ addAction(Intent.ACTION_PACKAGE_REMOVED)
+ addAction(Intent.ACTION_PACKAGE_RESTARTED)
+ addDataScheme("package")
+ }
+ // BroadcastDispatcher does not allow filters with data schemes
+ context.registerReceiver(appChangeReceiver, uninstallFilter)
}
fun onNotificationAdded(key: String, sbn: StatusBarNotification) {
@@ -160,6 +189,18 @@ class MediaDataManager @Inject constructor(
mediaEntries.clear()
}
+ private fun removeAllForPackage(packageName: String) {
+ Assert.isMainThread()
+ val listenersCopy = listeners.toSet()
+ val toRemove = mediaEntries.filter { it.value.packageName == packageName }
+ toRemove.forEach {
+ mediaEntries.remove(it.key)
+ listenersCopy.forEach { listener ->
+ listener.onMediaDataRemoved(it.key)
+ }
+ }
+ }
+
private fun addResumptionControls(
desc: MediaDescription,
action: Runnable,
diff --git a/packages/SystemUI/src/com/android/systemui/media/ResumeMediaBrowser.java b/packages/SystemUI/src/com/android/systemui/media/ResumeMediaBrowser.java
index 1e9a30364607..6462f072bc74 100644
--- a/packages/SystemUI/src/com/android/systemui/media/ResumeMediaBrowser.java
+++ b/packages/SystemUI/src/com/android/systemui/media/ResumeMediaBrowser.java
@@ -135,12 +135,16 @@ public class ResumeMediaBrowser {
*/
@Override
public void onConnected() {
+ Log.d(TAG, "Service connected for " + mComponentName);
if (mMediaBrowser.isConnected()) {
- mCallback.onConnected();
- Log.d(TAG, "Service connected for " + mComponentName);
String root = mMediaBrowser.getRoot();
- mMediaBrowser.subscribe(root, mSubscriptionCallback);
+ if (!TextUtils.isEmpty(root)) {
+ mCallback.onConnected();
+ mMediaBrowser.subscribe(root, mSubscriptionCallback);
+ return;
+ }
}
+ mCallback.onError();
}
/**
@@ -193,6 +197,10 @@ public class ResumeMediaBrowser {
@Override
public void onConnected() {
Log.d(TAG, "Connected for restart " + mMediaBrowser.isConnected());
+ if (!mMediaBrowser.isConnected()) {
+ mCallback.onError();
+ return;
+ }
MediaSession.Token token = mMediaBrowser.getSessionToken();
MediaController controller = new MediaController(mContext, token);
controller.getTransportControls();
@@ -251,7 +259,8 @@ public class ResumeMediaBrowser {
@Override
public void onConnected() {
Log.d(TAG, "connected");
- if (TextUtils.isEmpty(mMediaBrowser.getRoot())) {
+ if (!mMediaBrowser.isConnected()
+ || TextUtils.isEmpty(mMediaBrowser.getRoot())) {
mCallback.onError();
} else {
mCallback.onConnected();
diff --git a/packages/SystemUI/src/com/android/systemui/qs/AutoAddTracker.java b/packages/SystemUI/src/com/android/systemui/qs/AutoAddTracker.java
index 2365e67fec2f..0a84f5ee1bb9 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/AutoAddTracker.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/AutoAddTracker.java
@@ -23,6 +23,7 @@ import static com.android.systemui.statusbar.phone.AutoTileManager.WORK;
import android.content.Context;
import android.database.ContentObserver;
import android.os.Handler;
+import android.os.UserHandle;
import android.provider.Settings.Secure;
import android.text.TextUtils;
import android.util.ArraySet;
@@ -30,6 +31,7 @@ import android.util.ArraySet;
import com.android.internal.annotations.VisibleForTesting;
import com.android.systemui.Prefs;
import com.android.systemui.Prefs.Key;
+import com.android.systemui.util.UserAwareController;
import java.util.Arrays;
import java.util.Collection;
@@ -37,7 +39,7 @@ import java.util.Collections;
import javax.inject.Inject;
-public class AutoAddTracker {
+public class AutoAddTracker implements UserAwareController {
private static final String[][] CONVERT_PREFS = {
{Key.QS_HOTSPOT_ADDED, HOTSPOT},
@@ -49,20 +51,39 @@ public class AutoAddTracker {
private final ArraySet<String> mAutoAdded;
private final Context mContext;
+ private int mUserId;
- @Inject
- public AutoAddTracker(Context context) {
+ public AutoAddTracker(Context context, int userId) {
mContext = context;
+ mUserId = userId;
mAutoAdded = new ArraySet<>(getAdded());
// TODO: remove migration code and shared preferences keys after P release
- for (String[] convertPref : CONVERT_PREFS) {
- if (Prefs.getBoolean(context, convertPref[0], false)) {
- setTileAdded(convertPref[1]);
- Prefs.remove(context, convertPref[0]);
+ if (mUserId == UserHandle.USER_SYSTEM) {
+ for (String[] convertPref : CONVERT_PREFS) {
+ if (Prefs.getBoolean(context, convertPref[0], false)) {
+ setTileAdded(convertPref[1]);
+ Prefs.remove(context, convertPref[0]);
+ }
}
}
mContext.getContentResolver().registerContentObserver(
- Secure.getUriFor(Secure.QS_AUTO_ADDED_TILES), false, mObserver);
+ Secure.getUriFor(Secure.QS_AUTO_ADDED_TILES), false, mObserver,
+ UserHandle.USER_ALL);
+ }
+
+ @Override
+ public void changeUser(UserHandle newUser) {
+ if (newUser.getIdentifier() == mUserId) {
+ return;
+ }
+ mUserId = newUser.getIdentifier();
+ mAutoAdded.clear();
+ mAutoAdded.addAll(getAdded());
+ }
+
+ @Override
+ public int getCurrentUserId() {
+ return mUserId;
}
public boolean isAdded(String tile) {
@@ -86,12 +107,13 @@ public class AutoAddTracker {
}
private void saveTiles() {
- Secure.putString(mContext.getContentResolver(), Secure.QS_AUTO_ADDED_TILES,
- TextUtils.join(",", mAutoAdded));
+ Secure.putStringForUser(mContext.getContentResolver(), Secure.QS_AUTO_ADDED_TILES,
+ TextUtils.join(",", mAutoAdded), mUserId);
}
private Collection<String> getAdded() {
- String current = Secure.getString(mContext.getContentResolver(), Secure.QS_AUTO_ADDED_TILES);
+ String current = Secure.getStringForUser(mContext.getContentResolver(),
+ Secure.QS_AUTO_ADDED_TILES, mUserId);
if (current == null) {
return Collections.emptyList();
}
@@ -102,7 +124,27 @@ public class AutoAddTracker {
protected final ContentObserver mObserver = new ContentObserver(new Handler()) {
@Override
public void onChange(boolean selfChange) {
+ mAutoAdded.clear();
mAutoAdded.addAll(getAdded());
}
};
+
+ public static class Builder {
+ private final Context mContext;
+ private int mUserId;
+
+ @Inject
+ public Builder(Context context) {
+ mContext = context;
+ }
+
+ public Builder setUserId(int userId) {
+ mUserId = userId;
+ return this;
+ }
+
+ public AutoAddTracker build() {
+ return new AutoAddTracker(mContext, mUserId);
+ }
+ }
}
diff --git a/packages/SystemUI/src/com/android/systemui/qs/QSTileHost.java b/packages/SystemUI/src/com/android/systemui/qs/QSTileHost.java
index 65d3572d04a3..858a7e2e30e0 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/QSTileHost.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/QSTileHost.java
@@ -255,6 +255,9 @@ public class QSTileHost implements QSHost, Tunable, PluginListener<QSFactory>, D
int currentUser = ActivityManager.getCurrentUser();
if (currentUser != mCurrentUser) {
mUserContext = mContext.createContextAsUser(UserHandle.of(currentUser), 0);
+ if (mAutoTiles != null) {
+ mAutoTiles.changeUser(UserHandle.of(currentUser));
+ }
}
if (tileSpecs.equals(mTileSpecs) && currentUser == mCurrentUser) return;
mTiles.entrySet().stream().filter(tile -> !tileSpecs.contains(tile.getKey())).forEach(
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/AutoTileManager.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/AutoTileManager.java
index fc8c8dbba7fd..825919f17661 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/AutoTileManager.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/AutoTileManager.java
@@ -19,6 +19,7 @@ import android.content.res.Resources;
import android.hardware.display.ColorDisplayManager;
import android.hardware.display.NightDisplayListener;
import android.os.Handler;
+import android.os.UserHandle;
import android.util.Log;
import com.android.internal.annotations.VisibleForTesting;
@@ -34,6 +35,7 @@ import com.android.systemui.statusbar.policy.DataSaverController;
import com.android.systemui.statusbar.policy.DataSaverController.Listener;
import com.android.systemui.statusbar.policy.HotspotController;
import com.android.systemui.statusbar.policy.HotspotController.Callback;
+import com.android.systemui.util.UserAwareController;
import java.util.ArrayList;
import java.util.Objects;
@@ -43,7 +45,7 @@ import javax.inject.Inject;
/**
* Manages which tiles should be automatically added to QS.
*/
-public class AutoTileManager {
+public class AutoTileManager implements UserAwareController {
private static final String TAG = "AutoTileManager";
public static final String HOTSPOT = "hotspot";
@@ -52,7 +54,9 @@ public class AutoTileManager {
public static final String WORK = "work";
public static final String NIGHT = "night";
public static final String CAST = "cast";
- public static final String SETTING_SEPARATOR = ":";
+ static final String SETTING_SEPARATOR = ":";
+
+ private UserHandle mCurrentUser;
private final Context mContext;
private final QSTileHost mHost;
@@ -66,43 +70,56 @@ public class AutoTileManager {
private final ArrayList<AutoAddSetting> mAutoAddSettingList = new ArrayList<>();
@Inject
- public AutoTileManager(Context context, AutoAddTracker autoAddTracker, QSTileHost host,
+ public AutoTileManager(Context context, AutoAddTracker.Builder autoAddTrackerBuilder,
+ QSTileHost host,
@Background Handler handler,
HotspotController hotspotController,
DataSaverController dataSaverController,
ManagedProfileController managedProfileController,
NightDisplayListener nightDisplayListener,
CastController castController) {
- mAutoTracker = autoAddTracker;
mContext = context;
mHost = host;
+ mCurrentUser = mHost.getUserContext().getUser();
+ mAutoTracker = autoAddTrackerBuilder.setUserId(mCurrentUser.getIdentifier()).build();
mHandler = handler;
mHotspotController = hotspotController;
mDataSaverController = dataSaverController;
mManagedProfileController = managedProfileController;
mNightDisplayListener = nightDisplayListener;
mCastController = castController;
+
+ populateSettingsList();
+ startControllersAndSettingsListeners();
+ }
+
+ protected void startControllersAndSettingsListeners() {
if (!mAutoTracker.isAdded(HOTSPOT)) {
- hotspotController.addCallback(mHotspotCallback);
+ mHotspotController.addCallback(mHotspotCallback);
}
if (!mAutoTracker.isAdded(SAVER)) {
- dataSaverController.addCallback(mDataSaverListener);
+ mDataSaverController.addCallback(mDataSaverListener);
}
if (!mAutoTracker.isAdded(WORK)) {
- managedProfileController.addCallback(mProfileCallback);
+ mManagedProfileController.addCallback(mProfileCallback);
}
if (!mAutoTracker.isAdded(NIGHT)
&& ColorDisplayManager.isNightDisplayAvailable(mContext)) {
- nightDisplayListener.setCallback(mNightDisplayCallback);
+ mNightDisplayListener.setCallback(mNightDisplayCallback);
}
if (!mAutoTracker.isAdded(CAST)) {
- castController.addCallback(mCastCallback);
+ mCastController.addCallback(mCastCallback);
+ }
+
+ int settingsN = mAutoAddSettingList.size();
+ for (int i = 0; i < settingsN; i++) {
+ if (!mAutoTracker.isAdded(mAutoAddSettingList.get(i).mSpec)) {
+ mAutoAddSettingList.get(i).setListening(true);
+ }
}
- populateSettingsList();
}
- public void destroy() {
- mAutoTracker.destroy();
+ protected void stopListening() {
mHotspotController.removeCallback(mHotspotCallback);
mDataSaverController.removeCallback(mDataSaverListener);
mManagedProfileController.removeCallback(mProfileCallback);
@@ -116,6 +133,11 @@ public class AutoTileManager {
}
}
+ public void destroy() {
+ stopListening();
+ mAutoTracker.destroy();
+ }
+
/**
* Populates a list with the pairs setting:spec in the config resource.
* <p>
@@ -137,17 +159,39 @@ public class AutoTileManager {
if (split.length == 2) {
String setting = split[0];
String spec = split[1];
- if (!mAutoTracker.isAdded(spec)) {
- AutoAddSetting s = new AutoAddSetting(mContext, mHandler, setting, spec);
- mAutoAddSettingList.add(s);
- s.setListening(true);
- }
+ // Populate all the settings. As they may not have been added in other users
+ AutoAddSetting s = new AutoAddSetting(mContext, mHandler, setting, spec);
+ mAutoAddSettingList.add(s);
} else {
Log.w(TAG, "Malformed item in array: " + tile);
}
}
}
+ @Override
+ public void changeUser(UserHandle newUser) {
+ if (!Thread.currentThread().equals(mHandler.getLooper().getThread())) {
+ mHandler.post(() -> changeUser(newUser));
+ return;
+ }
+ if (newUser.getIdentifier() == mCurrentUser.getIdentifier()) {
+ return;
+ }
+ stopListening();
+ mCurrentUser = newUser;
+ int settingsN = mAutoAddSettingList.size();
+ for (int i = 0; i < settingsN; i++) {
+ mAutoAddSettingList.get(i).setUserId(newUser.getIdentifier());
+ }
+ mAutoTracker.changeUser(newUser);
+ startControllersAndSettingsListeners();
+ }
+
+ @Override
+ public int getCurrentUserId() {
+ return mCurrentUser.getIdentifier();
+ }
+
public void unmarkTileAsAutoAdded(String tabSpec) {
mAutoTracker.setTileRemoved(tabSpec);
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationModeController.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationModeController.java
index daefef5e826d..c211de08cb8e 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationModeController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationModeController.java
@@ -16,14 +16,19 @@
package com.android.systemui.statusbar.phone;
+import static android.content.Intent.ACTION_OVERLAY_CHANGED;
import static android.view.WindowManagerPolicyConstants.NAV_BAR_MODE_GESTURAL;
import static android.view.WindowManagerPolicyConstants.NAV_BAR_MODE_GESTURAL_OVERLAY;
+import android.content.BroadcastReceiver;
import android.content.Context;
+import android.content.Intent;
+import android.content.IntentFilter;
import android.content.om.IOverlayManager;
import android.content.om.OverlayInfo;
import android.content.pm.PackageManager;
import android.content.res.ApkAssets;
+import android.os.PatternMatcher;
import android.os.RemoteException;
import android.os.ServiceManager;
import android.os.UserHandle;
@@ -79,6 +84,19 @@ public class NavigationModeController implements Dumpable {
}
};
+ // The primary user SysUI process doesn't get AppInfo changes from overlay package changes for
+ // the secondary user (b/158613864), so we need to update the interaction mode here as well
+ // as a fallback if we don't receive the configuration change
+ private BroadcastReceiver mReceiver = new BroadcastReceiver() {
+ @Override
+ public void onReceive(Context context, Intent intent) {
+ if (DEBUG) {
+ Log.d(TAG, "ACTION_OVERLAY_CHANGED");
+ }
+ updateCurrentInteractionMode(true /* notify */);
+ }
+ };
+
@Inject
public NavigationModeController(Context context,
@@ -92,6 +110,11 @@ public class NavigationModeController implements Dumpable {
mUiBgExecutor = uiBgExecutor;
deviceProvisionedController.addCallback(mDeviceProvisionedCallback);
+ IntentFilter overlayFilter = new IntentFilter(ACTION_OVERLAY_CHANGED);
+ overlayFilter.addDataScheme("package");
+ overlayFilter.addDataSchemeSpecificPart("android", PatternMatcher.PATTERN_LITERAL);
+ mContext.registerReceiverAsUser(mReceiver, UserHandle.ALL, overlayFilter, null, null);
+
configurationController.addCallback(new ConfigurationController.ConfigurationListener() {
@Override
public void onOverlayChanged() {
diff --git a/packages/SystemUI/src/com/android/systemui/controls/UserAwareController.kt b/packages/SystemUI/src/com/android/systemui/util/UserAwareController.kt
index d2776d27ae62..693c2708b0f7 100644
--- a/packages/SystemUI/src/com/android/systemui/controls/UserAwareController.kt
+++ b/packages/SystemUI/src/com/android/systemui/util/UserAwareController.kt
@@ -14,7 +14,7 @@
* limitations under the License.
*/
-package com.android.systemui.controls
+package com.android.systemui.util
import android.os.UserHandle
@@ -23,6 +23,8 @@ import android.os.UserHandle
* changes.
*/
interface UserAwareController {
+ @JvmDefault
fun changeUser(newUser: UserHandle) {}
+
val currentUserId: Int
} \ No newline at end of file
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 1e48b990b19d..59f8c4e329a4 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/bubbles/BubbleControllerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/bubbles/BubbleControllerTest.java
@@ -92,6 +92,7 @@ import com.android.systemui.util.FloatingContentCoordinator;
import com.google.common.collect.ImmutableList;
import org.junit.Before;
+import org.junit.Ignore;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.ArgumentCaptor;
@@ -407,6 +408,7 @@ public class BubbleControllerTest extends SysuiTestCase {
}
@Test
+ @Ignore("Currently broken.")
public void testCollapseAfterChangingExpandedBubble() {
// Mark it as a bubble and add it explicitly
mEntryListener.onPendingEntryAdded(mRow.getEntry());
diff --git a/packages/SystemUI/tests/src/com/android/systemui/bubbles/NewNotifPipelineBubbleControllerTest.java b/packages/SystemUI/tests/src/com/android/systemui/bubbles/NewNotifPipelineBubbleControllerTest.java
index 0be24729dff9..58e06b5178c6 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/bubbles/NewNotifPipelineBubbleControllerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/bubbles/NewNotifPipelineBubbleControllerTest.java
@@ -87,6 +87,7 @@ import com.android.systemui.statusbar.policy.ZenModeController;
import com.android.systemui.util.FloatingContentCoordinator;
import org.junit.Before;
+import org.junit.Ignore;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.ArgumentCaptor;
@@ -364,6 +365,7 @@ public class NewNotifPipelineBubbleControllerTest extends SysuiTestCase {
}
@Test
+ @Ignore("Currently broken.")
public void testCollapseAfterChangingExpandedBubble() {
// Mark it as a bubble and add it explicitly
mEntryListener.onEntryAdded(mRow.getEntry());
diff --git a/packages/SystemUI/tests/src/com/android/systemui/qs/AutoAddTrackerTest.java b/packages/SystemUI/tests/src/com/android/systemui/qs/AutoAddTrackerTest.java
index 0ae9461d38b1..61f5a7bdd3b7 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/qs/AutoAddTrackerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/qs/AutoAddTrackerTest.java
@@ -21,6 +21,7 @@ import static com.android.systemui.statusbar.phone.AutoTileManager.WORK;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;
+import android.os.UserHandle;
import android.provider.Settings.Secure;
import android.testing.AndroidTestingRunner;
import android.testing.TestableLooper.RunWithLooper;
@@ -40,6 +41,8 @@ import org.junit.runner.RunWith;
@SmallTest
public class AutoAddTrackerTest extends SysuiTestCase {
+ private static final int USER = 0;
+
private AutoAddTracker mAutoTracker;
@Before
@@ -51,7 +54,7 @@ public class AutoAddTrackerTest extends SysuiTestCase {
public void testMigration() {
Prefs.putBoolean(mContext, Key.QS_DATA_SAVER_ADDED, true);
Prefs.putBoolean(mContext, Key.QS_WORK_ADDED, true);
- mAutoTracker = new AutoAddTracker(mContext);
+ mAutoTracker = new AutoAddTracker(mContext, USER);
assertTrue(mAutoTracker.isAdded(SAVER));
assertTrue(mAutoTracker.isAdded(WORK));
@@ -68,7 +71,7 @@ public class AutoAddTrackerTest extends SysuiTestCase {
@Test
public void testChangeFromBackup() {
- mAutoTracker = new AutoAddTracker(mContext);
+ mAutoTracker = new AutoAddTracker(mContext, USER);
assertFalse(mAutoTracker.isAdded(SAVER));
@@ -82,7 +85,7 @@ public class AutoAddTrackerTest extends SysuiTestCase {
@Test
public void testSetAdded() {
- mAutoTracker = new AutoAddTracker(mContext);
+ mAutoTracker = new AutoAddTracker(mContext, USER);
assertFalse(mAutoTracker.isAdded(SAVER));
mAutoTracker.setTileAdded(SAVER);
@@ -94,16 +97,35 @@ public class AutoAddTrackerTest extends SysuiTestCase {
@Test
public void testPersist() {
- mAutoTracker = new AutoAddTracker(mContext);
+ mAutoTracker = new AutoAddTracker(mContext, USER);
assertFalse(mAutoTracker.isAdded(SAVER));
mAutoTracker.setTileAdded(SAVER);
mAutoTracker.destroy();
- mAutoTracker = new AutoAddTracker(mContext);
+ mAutoTracker = new AutoAddTracker(mContext, USER);
assertTrue(mAutoTracker.isAdded(SAVER));
mAutoTracker.destroy();
}
+
+ @Test
+ public void testIndependentUsers() {
+ mAutoTracker = new AutoAddTracker(mContext, USER);
+ mAutoTracker.setTileAdded(SAVER);
+
+ mAutoTracker = new AutoAddTracker(mContext, USER + 1);
+ assertFalse(mAutoTracker.isAdded(SAVER));
+ }
+
+ @Test
+ public void testChangeUser() {
+ mAutoTracker = new AutoAddTracker(mContext, USER);
+ mAutoTracker.setTileAdded(SAVER);
+
+ mAutoTracker = new AutoAddTracker(mContext, USER + 1);
+ mAutoTracker.changeUser(UserHandle.of(USER));
+ assertTrue(mAutoTracker.isAdded(SAVER));
+ }
} \ No newline at end of file
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/AutoTileManagerTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/AutoTileManagerTest.java
index 05cdd802167a..31779cdf9e71 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/AutoTileManagerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/AutoTileManagerTest.java
@@ -16,18 +16,34 @@
package com.android.systemui.statusbar.phone;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.ArgumentMatchers.anyBoolean;
+import static org.mockito.ArgumentMatchers.anyInt;
+import static org.mockito.ArgumentMatchers.isNotNull;
+import static org.mockito.ArgumentMatchers.isNull;
+import static org.mockito.Mockito.doNothing;
import static org.mockito.Mockito.doReturn;
-import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.inOrder;
import static org.mockito.Mockito.never;
+import static org.mockito.Mockito.spy;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
import android.content.ComponentName;
+import android.content.ContentResolver;
+import android.content.Context;
+import android.content.ContextWrapper;
import android.hardware.display.ColorDisplayManager;
import android.hardware.display.NightDisplayListener;
import android.os.Handler;
+import android.os.UserHandle;
import android.provider.Settings;
import android.testing.AndroidTestingRunner;
+import android.testing.TestableContentResolver;
+import android.testing.TestableContext;
import android.testing.TestableLooper;
import android.testing.TestableLooper.RunWithLooper;
@@ -38,14 +54,18 @@ import com.android.systemui.SysuiTestCase;
import com.android.systemui.qs.AutoAddTracker;
import com.android.systemui.qs.QSTileHost;
import com.android.systemui.qs.SecureSetting;
+import com.android.systemui.statusbar.phone.AutoTileManagerTest.MyContextWrapper;
import com.android.systemui.statusbar.policy.CastController;
import com.android.systemui.statusbar.policy.CastController.CastDevice;
import com.android.systemui.statusbar.policy.DataSaverController;
import com.android.systemui.statusbar.policy.HotspotController;
+import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
+import org.mockito.Answers;
+import org.mockito.InOrder;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
@@ -64,9 +84,18 @@ public class AutoTileManagerTest extends SysuiTestCase {
private static final String TEST_CUSTOM_SPEC = "custom(" + TEST_COMPONENT + ")";
private static final String SEPARATOR = AutoTileManager.SETTING_SEPARATOR;
+ private static final int USER = 0;
+
@Mock private QSTileHost mQsTileHost;
@Mock private AutoAddTracker mAutoAddTracker;
@Mock private CastController mCastController;
+ @Mock private HotspotController mHotspotController;
+ @Mock private DataSaverController mDataSaverController;
+ @Mock private ManagedProfileController mManagedProfileController;
+ @Mock private NightDisplayListener mNightDisplayListener;
+ @Mock(answer = Answers.RETURNS_SELF)
+ private AutoAddTracker.Builder mAutoAddTrackerBuilder;
+ @Mock private Context mUserContext;
private AutoTileManager mAutoTileManager;
@@ -82,20 +111,110 @@ public class AutoTileManagerTest extends SysuiTestCase {
}
);
- mAutoTileManager = createAutoTileManager();
+ when(mAutoAddTrackerBuilder.build()).thenReturn(mAutoAddTracker);
+ when(mQsTileHost.getUserContext()).thenReturn(mUserContext);
+ when(mUserContext.getUser()).thenReturn(UserHandle.of(USER));
+
+ mAutoTileManager = createAutoTileManager(new
+ MyContextWrapper(mContext));
}
- private AutoTileManager createAutoTileManager() {
- return new AutoTileManager(mContext, mAutoAddTracker, mQsTileHost,
+ @After
+ public void tearDown() {
+ mAutoTileManager.destroy();
+ }
+
+ private AutoTileManager createAutoTileManager(Context context) {
+ return new AutoTileManager(context, mAutoAddTrackerBuilder, mQsTileHost,
Handler.createAsync(TestableLooper.get(this).getLooper()),
- mock(HotspotController.class),
- mock(DataSaverController.class),
- mock(ManagedProfileController.class),
- mock(NightDisplayListener.class),
+ mHotspotController,
+ mDataSaverController,
+ mManagedProfileController,
+ mNightDisplayListener,
mCastController);
}
@Test
+ public void testChangeUserCallbacksStoppedAndStarted() throws Exception {
+ TestableLooper.get(this).runWithLooper(() ->
+ mAutoTileManager.changeUser(UserHandle.of(USER + 1))
+ );
+
+ InOrder inOrderHotspot = inOrder(mHotspotController);
+ inOrderHotspot.verify(mHotspotController).removeCallback(any());
+ inOrderHotspot.verify(mHotspotController).addCallback(any());
+
+ InOrder inOrderDataSaver = inOrder(mDataSaverController);
+ inOrderDataSaver.verify(mDataSaverController).removeCallback(any());
+ inOrderDataSaver.verify(mDataSaverController).addCallback(any());
+
+ InOrder inOrderManagedProfile = inOrder(mManagedProfileController);
+ inOrderManagedProfile.verify(mManagedProfileController).removeCallback(any());
+ inOrderManagedProfile.verify(mManagedProfileController).addCallback(any());
+
+ InOrder inOrderNightDisplay = inOrder(mNightDisplayListener);
+ inOrderNightDisplay.verify(mNightDisplayListener).setCallback(isNull());
+ inOrderNightDisplay.verify(mNightDisplayListener).setCallback(isNotNull());
+
+ InOrder inOrderCast = inOrder(mCastController);
+ inOrderCast.verify(mCastController).removeCallback(any());
+ inOrderCast.verify(mCastController).addCallback(any());
+
+ SecureSetting setting = mAutoTileManager.getSecureSettingForKey(TEST_SETTING);
+ assertEquals(USER + 1, setting.getCurrentUser());
+ assertTrue(setting.isListening());
+ }
+
+ @Test
+ public void testChangeUserSomeCallbacksNotAdded() throws Exception {
+ when(mAutoAddTracker.isAdded("hotspot")).thenReturn(true);
+ when(mAutoAddTracker.isAdded("work")).thenReturn(true);
+ when(mAutoAddTracker.isAdded("cast")).thenReturn(true);
+ when(mAutoAddTracker.isAdded(TEST_SPEC)).thenReturn(true);
+
+ TestableLooper.get(this).runWithLooper(() ->
+ mAutoTileManager.changeUser(UserHandle.of(USER + 1))
+ );
+
+ verify(mAutoAddTracker).changeUser(UserHandle.of(USER + 1));
+
+ InOrder inOrderHotspot = inOrder(mHotspotController);
+ inOrderHotspot.verify(mHotspotController).removeCallback(any());
+ inOrderHotspot.verify(mHotspotController, never()).addCallback(any());
+
+ InOrder inOrderDataSaver = inOrder(mDataSaverController);
+ inOrderDataSaver.verify(mDataSaverController).removeCallback(any());
+ inOrderDataSaver.verify(mDataSaverController).addCallback(any());
+
+ InOrder inOrderManagedProfile = inOrder(mManagedProfileController);
+ inOrderManagedProfile.verify(mManagedProfileController).removeCallback(any());
+ inOrderManagedProfile.verify(mManagedProfileController, never()).addCallback(any());
+
+ InOrder inOrderNightDisplay = inOrder(mNightDisplayListener);
+ inOrderNightDisplay.verify(mNightDisplayListener).setCallback(isNull());
+ inOrderNightDisplay.verify(mNightDisplayListener).setCallback(isNotNull());
+
+ InOrder inOrderCast = inOrder(mCastController);
+ inOrderCast.verify(mCastController).removeCallback(any());
+ inOrderCast.verify(mCastController, never()).addCallback(any());
+
+ SecureSetting setting = mAutoTileManager.getSecureSettingForKey(TEST_SETTING);
+ assertEquals(USER + 1, setting.getCurrentUser());
+ assertFalse(setting.isListening());
+ }
+
+ @Test
+ public void testGetCurrentUserId() throws Exception {
+ assertEquals(USER, mAutoTileManager.getCurrentUserId());
+
+ TestableLooper.get(this).runWithLooper(() ->
+ mAutoTileManager.changeUser(UserHandle.of(USER + 100))
+ );
+
+ assertEquals(USER + 100, mAutoTileManager.getCurrentUserId());
+ }
+
+ @Test
public void nightTileAdded_whenActivated() {
if (!ColorDisplayManager.isNightDisplayAvailable(mContext)) {
return;
@@ -213,14 +332,14 @@ public class AutoTileManagerTest extends SysuiTestCase {
public void testEmptyArray_doesNotCrash() {
mContext.getOrCreateTestableResources().addOverride(
R.array.config_quickSettingsAutoAdd, new String[0]);
- createAutoTileManager();
+ createAutoTileManager(mContext).destroy();
}
@Test
public void testMissingConfig_doesNotCrash() {
mContext.getOrCreateTestableResources().addOverride(
R.array.config_quickSettingsAutoAdd, null);
- createAutoTileManager();
+ createAutoTileManager(mContext).destroy();
}
// Will only notify if it's listening
@@ -231,4 +350,22 @@ public class AutoTileManagerTest extends SysuiTestCase {
s.onChange(false);
}
}
+
+ class MyContextWrapper extends ContextWrapper {
+
+ private TestableContentResolver mSpiedTCR;
+
+ MyContextWrapper(TestableContext context) {
+ super(context);
+ mSpiedTCR = spy(context.getContentResolver());
+ doNothing().when(mSpiedTCR).registerContentObserver(any(), anyBoolean(), any(),
+ anyInt());
+ doNothing().when(mSpiedTCR).unregisterContentObserver(any());
+ }
+
+ @Override
+ public ContentResolver getContentResolver() {
+ return mSpiedTCR;
+ }
+ }
}
diff --git a/services/accessibility/java/com/android/server/accessibility/AccessibilityServiceConnection.java b/services/accessibility/java/com/android/server/accessibility/AccessibilityServiceConnection.java
index 0f98992d1ea0..fea2e7b841e0 100644
--- a/services/accessibility/java/com/android/server/accessibility/AccessibilityServiceConnection.java
+++ b/services/accessibility/java/com/android/server/accessibility/AccessibilityServiceConnection.java
@@ -21,6 +21,7 @@ import static com.android.internal.util.function.pooled.PooledLambda.obtainMessa
import android.Manifest;
import android.accessibilityservice.AccessibilityServiceInfo;
import android.accessibilityservice.IAccessibilityServiceClient;
+import android.app.PendingIntent;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
@@ -83,7 +84,8 @@ class AccessibilityServiceConnection extends AbstractAccessibilityServiceConnect
final long identity = Binder.clearCallingIdentity();
try {
mIntent.putExtra(Intent.EXTRA_CLIENT_INTENT, mSystemSupport.getPendingIntentActivity(
- mContext, 0, new Intent(Settings.ACTION_ACCESSIBILITY_SETTINGS), 0));
+ mContext, 0, new Intent(Settings.ACTION_ACCESSIBILITY_SETTINGS),
+ PendingIntent.FLAG_IMMUTABLE));
} finally {
Binder.restoreCallingIdentity(identity);
}
diff --git a/services/core/java/com/android/server/compat/PlatformCompat.java b/services/core/java/com/android/server/compat/PlatformCompat.java
index 8ed864c71625..d7e9499cf8db 100644
--- a/services/core/java/com/android/server/compat/PlatformCompat.java
+++ b/services/core/java/com/android/server/compat/PlatformCompat.java
@@ -102,6 +102,13 @@ public class PlatformCompat extends IPlatformCompat.Stub {
@Override
public boolean isChangeEnabled(long changeId, ApplicationInfo appInfo) {
checkCompatChangeReadAndLogPermission();
+ return isChangeEnabledInternal(changeId, appInfo);
+ }
+
+ /**
+ * Internal version of the above method. Does not perform costly permission check.
+ */
+ public boolean isChangeEnabledInternal(long changeId, ApplicationInfo appInfo) {
if (mCompatConfig.isChangeEnabled(changeId, appInfo)) {
reportChange(changeId, appInfo.uid,
ChangeReporter.STATE_ENABLED);
diff --git a/services/core/java/com/android/server/locksettings/RebootEscrowManager.java b/services/core/java/com/android/server/locksettings/RebootEscrowManager.java
index 8d4efed8604b..5787f7c48138 100644
--- a/services/core/java/com/android/server/locksettings/RebootEscrowManager.java
+++ b/services/core/java/com/android/server/locksettings/RebootEscrowManager.java
@@ -26,6 +26,7 @@ import android.content.pm.UserInfo;
import android.hardware.rebootescrow.IRebootEscrow;
import android.os.RemoteException;
import android.os.ServiceManager;
+import android.os.ServiceSpecificException;
import android.os.SystemClock;
import android.os.UserManager;
import android.provider.Settings;
@@ -244,6 +245,9 @@ class RebootEscrowManager {
} catch (RemoteException e) {
Slog.w(TAG, "Could not retrieve escrow data");
return null;
+ } catch (ServiceSpecificException e) {
+ Slog.w(TAG, "Got service-specific exception: " + e.errorCode);
+ return null;
}
}
@@ -335,7 +339,7 @@ class RebootEscrowManager {
try {
rebootEscrow.storeKey(new byte[32]);
- } catch (RemoteException e) {
+ } catch (RemoteException | ServiceSpecificException e) {
Slog.w(TAG, "Could not call RebootEscrow HAL to shred key");
}
@@ -373,7 +377,7 @@ class RebootEscrowManager {
rebootEscrow.storeKey(escrowKey.getKeyBytes());
armedRebootEscrow = true;
Slog.i(TAG, "Reboot escrow key stored with RebootEscrow HAL");
- } catch (RemoteException e) {
+ } catch (RemoteException | ServiceSpecificException e) {
Slog.e(TAG, "Failed escrow secret to RebootEscrow HAL", e);
}
diff --git a/services/core/java/com/android/server/pm/AppsFilter.java b/services/core/java/com/android/server/pm/AppsFilter.java
index 4b6ee71803a7..5b9db64dd9b1 100644
--- a/services/core/java/com/android/server/pm/AppsFilter.java
+++ b/services/core/java/com/android/server/pm/AppsFilter.java
@@ -32,7 +32,6 @@ import android.content.pm.parsing.component.ParsedInstrumentation;
import android.content.pm.parsing.component.ParsedIntentInfo;
import android.content.pm.parsing.component.ParsedMainComponent;
import android.content.pm.parsing.component.ParsedProvider;
-import android.os.Binder;
import android.os.Process;
import android.os.Trace;
import android.os.UserHandle;
@@ -239,20 +238,13 @@ public class AppsFilter {
}
private void updateEnabledState(AndroidPackage pkg) {
- final long token = Binder.clearCallingIdentity();
- try {
- // TODO(b/135203078): Do not use toAppInfo
- final boolean enabled =
- mInjector.getCompatibility().isChangeEnabled(
- PackageManager.FILTER_APPLICATION_QUERY,
- pkg.toAppInfoWithoutState());
- if (enabled) {
- mDisabledPackages.remove(pkg.getPackageName());
- } else {
- mDisabledPackages.add(pkg.getPackageName());
- }
- } finally {
- Binder.restoreCallingIdentity(token);
+ // TODO(b/135203078): Do not use toAppInfo
+ final boolean enabled = mInjector.getCompatibility().isChangeEnabledInternal(
+ PackageManager.FILTER_APPLICATION_QUERY, pkg.toAppInfoWithoutState());
+ if (enabled) {
+ mDisabledPackages.remove(pkg.getPackageName());
+ } else {
+ mDisabledPackages.add(pkg.getPackageName());
}
}
diff --git a/services/core/java/com/android/server/pm/SELinuxMMAC.java b/services/core/java/com/android/server/pm/SELinuxMMAC.java
index 67e1994eac9a..fdd9636ae7b2 100644
--- a/services/core/java/com/android/server/pm/SELinuxMMAC.java
+++ b/services/core/java/com/android/server/pm/SELinuxMMAC.java
@@ -349,7 +349,8 @@ public final class SELinuxMMAC {
if ((sharedUserSetting != null) && (sharedUserSetting.packages.size() != 0)) {
return sharedUserSetting.seInfoTargetSdkVersion;
}
- if (compatibility.isChangeEnabled(SELINUX_LATEST_CHANGES, pkg.toAppInfoWithoutState())) {
+ if (compatibility.isChangeEnabledInternal(SELINUX_LATEST_CHANGES,
+ pkg.toAppInfoWithoutState())) {
return android.os.Build.VERSION_CODES.R;
}
diff --git a/services/tests/servicestests/src/com/android/server/locksettings/RebootEscrowManagerTests.java b/services/tests/servicestests/src/com/android/server/locksettings/RebootEscrowManagerTests.java
index 4127fece17bd..c4d121170624 100644
--- a/services/tests/servicestests/src/com/android/server/locksettings/RebootEscrowManagerTests.java
+++ b/services/tests/servicestests/src/com/android/server/locksettings/RebootEscrowManagerTests.java
@@ -43,6 +43,7 @@ import android.content.ContextWrapper;
import android.content.pm.UserInfo;
import android.hardware.rebootescrow.IRebootEscrow;
import android.os.RemoteException;
+import android.os.ServiceSpecificException;
import android.os.UserManager;
import android.platform.test.annotations.Presubmit;
@@ -178,6 +179,13 @@ public class RebootEscrowManagerTests {
}
@Test
+ public void clearCredentials_HalFailure_NonFatal() throws Exception {
+ doThrow(ServiceSpecificException.class).when(mRebootEscrow).storeKey(any());
+ mService.clearRebootEscrow();
+ verify(mRebootEscrow).storeKey(eq(new byte[32]));
+ }
+
+ @Test
public void armService_Success() throws Exception {
RebootEscrowListener mockListener = mock(RebootEscrowListener.class);
mService.setRebootEscrowListener(mockListener);
@@ -200,6 +208,24 @@ public class RebootEscrowManagerTests {
}
@Test
+ public void armService_HalFailure_NonFatal() throws Exception {
+ RebootEscrowListener mockListener = mock(RebootEscrowListener.class);
+ mService.setRebootEscrowListener(mockListener);
+ mService.prepareRebootEscrow();
+
+ clearInvocations(mRebootEscrow);
+ mService.callToRebootEscrowIfNeeded(PRIMARY_USER_ID, FAKE_SP_VERSION, FAKE_AUTH_TOKEN);
+ verify(mockListener).onPreparedForReboot(eq(true));
+ verify(mRebootEscrow, never()).storeKey(any());
+
+ assertNull(
+ mStorage.getString(RebootEscrowManager.REBOOT_ESCROW_ARMED_KEY, null, USER_SYSTEM));
+ doThrow(ServiceSpecificException.class).when(mRebootEscrow).storeKey(any());
+ assertFalse(mService.armRebootEscrowIfNeeded());
+ verify(mRebootEscrow).storeKey(any());
+ }
+
+ @Test
public void armService_MultipleUsers_Success() throws Exception {
RebootEscrowListener mockListener = mock(RebootEscrowListener.class);
mService.setRebootEscrowListener(mockListener);
diff --git a/services/tests/servicestests/src/com/android/server/pm/SELinuxMMACTest.java b/services/tests/servicestests/src/com/android/server/pm/SELinuxMMACTest.java
index efc1c057d8f4..a550b27a62a2 100644
--- a/services/tests/servicestests/src/com/android/server/pm/SELinuxMMACTest.java
+++ b/services/tests/servicestests/src/com/android/server/pm/SELinuxMMACTest.java
@@ -52,7 +52,7 @@ public class SELinuxMMACTest {
@Test
public void getSeInfoOptInToLatest() {
AndroidPackage pkg = makePackage(Build.VERSION_CODES.P);
- when(mMockCompatibility.isChangeEnabled(eq(SELinuxMMAC.SELINUX_LATEST_CHANGES),
+ when(mMockCompatibility.isChangeEnabledInternal(eq(SELinuxMMAC.SELINUX_LATEST_CHANGES),
argThat(argument -> argument.packageName.equals(pkg.getPackageName()))))
.thenReturn(true);
assertThat(SELinuxMMAC.getSeInfo(pkg, null, mMockCompatibility),
@@ -62,7 +62,7 @@ public class SELinuxMMACTest {
@Test
public void getSeInfoNoOptIn() {
AndroidPackage pkg = makePackage(Build.VERSION_CODES.P);
- when(mMockCompatibility.isChangeEnabled(eq(SELinuxMMAC.SELINUX_LATEST_CHANGES),
+ when(mMockCompatibility.isChangeEnabledInternal(eq(SELinuxMMAC.SELINUX_LATEST_CHANGES),
argThat(argument -> argument.packageName.equals(pkg.getPackageName()))))
.thenReturn(false);
assertThat(SELinuxMMAC.getSeInfo(pkg, null, mMockCompatibility),
@@ -72,7 +72,7 @@ public class SELinuxMMACTest {
@Test
public void getSeInfoNoOptInButAlreadyR() {
AndroidPackage pkg = makePackage(OPT_IN_VERSION);
- when(mMockCompatibility.isChangeEnabled(eq(SELinuxMMAC.SELINUX_LATEST_CHANGES),
+ when(mMockCompatibility.isChangeEnabledInternal(eq(SELinuxMMAC.SELINUX_LATEST_CHANGES),
argThat(argument -> argument.packageName.equals(pkg.getPackageName()))))
.thenReturn(false);
assertThat(SELinuxMMAC.getSeInfo(pkg, null, mMockCompatibility),