diff options
90 files changed, 879 insertions, 500 deletions
diff --git a/api/test-current.txt b/api/test-current.txt index 529dcf71ef6e..5741fe7e90a4 100644 --- a/api/test-current.txt +++ b/api/test-current.txt @@ -5579,7 +5579,7 @@ package android.window { method @BinderThread public void onTaskInfoChanged(@NonNull android.app.ActivityManager.RunningTaskInfo); method @BinderThread public void onTaskVanished(@NonNull android.app.ActivityManager.RunningTaskInfo); method @RequiresPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS) public final void registerOrganizer(); - method @RequiresPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS) public void setInterceptBackPressedOnTaskRoot(boolean); + method @RequiresPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS) public void setInterceptBackPressedOnTaskRoot(@NonNull android.window.WindowContainerToken, boolean); method @RequiresPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS) public static void setLaunchRoot(int, @NonNull android.window.WindowContainerToken); method @RequiresPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS) public final void unregisterOrganizer(); } diff --git a/core/java/android/app/ContextImpl.java b/core/java/android/app/ContextImpl.java index cee607fd7428..fef8d1005e29 100644 --- a/core/java/android/app/ContextImpl.java +++ b/core/java/android/app/ContextImpl.java @@ -1924,10 +1924,8 @@ class ContextImpl extends Context { @Override public Object getSystemService(String name) { if (vmIncorrectContextUseEnabled()) { - // We may override this API from outer context. - final boolean isUiContext = isUiContext() || isOuterUiContext(); // Check incorrect Context usage. - if (isUiComponent(name) && !isUiContext) { + if (isUiComponent(name) && !isSelfOrOuterUiContext()) { final String errorMessage = "Tried to access visual service " + SystemServiceRegistry.getSystemServiceClassName(name) + " from a non-visual Context:" + getOuterContext(); @@ -1944,15 +1942,17 @@ class ContextImpl extends Context { return SystemServiceRegistry.getSystemService(this, name); } - private boolean isOuterUiContext() { - return getOuterContext() != null && getOuterContext().isUiContext(); - } - @Override public String getSystemServiceName(Class<?> serviceClass) { return SystemServiceRegistry.getSystemServiceName(serviceClass); } + // TODO(b/149463653): check if we still need this method after migrating IMS to WindowContext. + private boolean isSelfOrOuterUiContext() { + // We may override outer context's isUiContext + return isUiContext() || getOuterContext() != null && getOuterContext().isUiContext(); + } + /** @hide */ @Override public boolean isUiContext() { @@ -2413,7 +2413,7 @@ class ContextImpl extends Context { context.setResources(createResources(mToken, mPackageInfo, mSplitName, overrideDisplayId, overrideConfiguration, getDisplayAdjustments(displayId).getCompatibilityInfo(), mResources.getLoaders())); - context.mIsUiContext = isUiContext() || isOuterUiContext(); + context.mIsUiContext = isSelfOrOuterUiContext(); return context; } @@ -2529,9 +2529,9 @@ class ContextImpl extends Context { @Override public Display getDisplay() { - if (!mIsSystemOrSystemUiContext && !mIsAssociatedWithDisplay) { + if (!mIsSystemOrSystemUiContext && !mIsAssociatedWithDisplay && !isSelfOrOuterUiContext()) { throw new UnsupportedOperationException("Tried to obtain display from a Context not " - + "associated with one. Only visual Contexts (such as Activity or one created " + + "associated with one. Only visual Contexts (such as Activity or one created " + "with Context#createWindowContext) or ones created with " + "Context#createDisplayContext are associated with displays. Other types of " + "Contexts are typically related to background entities and may return an " diff --git a/core/java/android/app/admin/DevicePolicyManager.java b/core/java/android/app/admin/DevicePolicyManager.java index c61426d5c172..98de85d9735d 100644 --- a/core/java/android/app/admin/DevicePolicyManager.java +++ b/core/java/android/app/admin/DevicePolicyManager.java @@ -9751,21 +9751,6 @@ public class DevicePolicyManager { } /** - * @hide - * Return if this user is a system-only user. An admin can manage a device from a system only - * user by calling {@link #ACTION_PROVISION_MANAGED_SHAREABLE_DEVICE}. - * @param admin Which device owner this request is associated with. - * @return if this user is a system-only user. - */ - public boolean isSystemOnlyUser(@NonNull ComponentName admin) { - try { - return mService.isSystemOnlyUser(admin); - } catch (RemoteException re) { - throw re.rethrowFromSystemServer(); - } - } - - /** * Called by device owner, or profile owner on organization-owned device, to get the MAC * address of the Wi-Fi device. * diff --git a/core/java/android/app/admin/IDevicePolicyManager.aidl b/core/java/android/app/admin/IDevicePolicyManager.aidl index 9c6a274ccf8c..1c7b617e6d9a 100644 --- a/core/java/android/app/admin/IDevicePolicyManager.aidl +++ b/core/java/android/app/admin/IDevicePolicyManager.aidl @@ -345,7 +345,6 @@ interface IDevicePolicyManager { void setKeepUninstalledPackages(in ComponentName admin, in String callerPackage, in List<String> packageList); List<String> getKeepUninstalledPackages(in ComponentName admin, in String callerPackage); boolean isManagedProfile(in ComponentName admin); - boolean isSystemOnlyUser(in ComponentName admin); String getWifiMacAddress(in ComponentName admin); void reboot(in ComponentName admin); diff --git a/core/java/android/companion/TEST_MAPPING b/core/java/android/companion/TEST_MAPPING new file mode 100644 index 000000000000..63f54fa35158 --- /dev/null +++ b/core/java/android/companion/TEST_MAPPING @@ -0,0 +1,12 @@ +{ + "presubmit": [ + { + "name": "CtsOsTestCases", + "options": [ + { + "include-filter": "android.os.cts.CompanionDeviceManagerTest" + } + ] + } + ] +} diff --git a/core/java/android/content/pm/PackageManager.java b/core/java/android/content/pm/PackageManager.java index da8d15af92b8..d672c6ac6c2f 100644 --- a/core/java/android/content/pm/PackageManager.java +++ b/core/java/android/content/pm/PackageManager.java @@ -788,7 +788,6 @@ public abstract class PackageManager { INSTALL_ENABLE_ROLLBACK, INSTALL_ALLOW_DOWNGRADE, INSTALL_STAGED, - INSTALL_DRY_RUN, }) @Retention(RetentionPolicy.SOURCE) public @interface InstallFlags {} @@ -966,14 +965,6 @@ public abstract class PackageManager { */ public static final int INSTALL_STAGED = 0x00200000; - /** - * Flag parameter for {@link #installPackage} to indicate that package should only be verified - * but not installed. - * - * @hide - */ - public static final int INSTALL_DRY_RUN = 0x00800000; - /** @hide */ @IntDef(flag = true, value = { DONT_KILL_APP, diff --git a/core/java/android/content/pm/RegisteredServicesCache.java b/core/java/android/content/pm/RegisteredServicesCache.java index bd909c7a3f59..192470e964e0 100644 --- a/core/java/android/content/pm/RegisteredServicesCache.java +++ b/core/java/android/content/pm/RegisteredServicesCache.java @@ -43,11 +43,11 @@ import com.android.internal.annotations.VisibleForTesting; import com.android.internal.util.ArrayUtils; import com.android.internal.util.FastXmlSerializer; -import libcore.io.IoUtils; - import com.google.android.collect.Lists; import com.google.android.collect.Maps; +import libcore.io.IoUtils; + import org.xmlpull.v1.XmlPullParser; import org.xmlpull.v1.XmlPullParserException; import org.xmlpull.v1.XmlSerializer; @@ -793,7 +793,7 @@ public abstract class RegisteredServicesCache<V> { @VisibleForTesting protected List<UserInfo> getUsers() { - return UserManager.get(mContext).getUsers(true); + return UserManager.get(mContext).getAliveUsers(); } @VisibleForTesting diff --git a/core/java/android/inputmethodservice/TEST_MAPPING b/core/java/android/inputmethodservice/TEST_MAPPING new file mode 100644 index 000000000000..0ccd75dcbdce --- /dev/null +++ b/core/java/android/inputmethodservice/TEST_MAPPING @@ -0,0 +1,7 @@ +{ + "imports": [ + { + "path": "frameworks/base/core/java/android/view/inputmethod" + } + ] +} diff --git a/core/java/android/os/UserManager.java b/core/java/android/os/UserManager.java index 81a147c68e2e..81ffefd05b19 100644 --- a/core/java/android/os/UserManager.java +++ b/core/java/android/os/UserManager.java @@ -1293,7 +1293,7 @@ public class UserManager { * in {@link UserManager} & {@link DevicePolicyManager}. * Note: This is slightly different from the real set of user restrictions listed in {@link * com.android.server.pm.UserRestrictionsUtils#USER_RESTRICTIONS}. For example - * {@link #KEY_RESTRICTIONS_PENDING} is not a real user restriction, but is a a legitimate + * {@link #KEY_RESTRICTIONS_PENDING} is not a real user restriction, but is a legitimate * value that can be passed into {@link #hasUserRestriction(String)}. * @hide */ @@ -3252,7 +3252,8 @@ public class UserManager { @SystemApi @RequiresPermission(android.Manifest.permission.MANAGE_USERS) public @NonNull List<UserHandle> getUserHandles(boolean excludeDying) { - List<UserInfo> users = getUsers(excludeDying); + List<UserInfo> users = getUsers(/* excludePartial= */ true, excludeDying, + /* excludePreCreated= */ true); List<UserHandle> result = new ArrayList<>(users.size()); for (UserInfo user : users) { result.add(user.getUserHandle()); @@ -3270,7 +3271,8 @@ public class UserManager { @SystemApi @RequiresPermission(android.Manifest.permission.MANAGE_USERS) public long[] getSerialNumbersOfUsers(boolean excludeDying) { - List<UserInfo> users = getUsers(excludeDying); + List<UserInfo> users = getUsers(/* excludePartial= */ true, excludeDying, + /* excludePreCreated= */ true); long[] result = new long[users.size()]; for (int i = 0; i < result.length; i++) { result[i] = users.get(i).serialNumber; @@ -3336,7 +3338,7 @@ public class UserManager { public boolean canAddMoreUsers() { // TODO(b/142482943): UMS has different logic, excluding Demo and Profile from counting. Why // not here? The logic is inconsistent. See UMS.canAddMoreManagedProfiles - final List<UserInfo> users = getUsers(true); + final List<UserInfo> users = getAliveUsers(); final int totalUserCount = users.size(); int aliveUserCount = 0; for (int i = 0; i < totalUserCount; i++) { @@ -4144,7 +4146,7 @@ public class UserManager { /** Returns whether there are any users (other than the current user) to which to switch. */ private boolean areThereUsersToWhichToSwitch() { - final List<UserInfo> users = getUsers(true); + final List<UserInfo> users = getAliveUsers(); if (users == null) { return false; } diff --git a/core/java/android/provider/CallLog.java b/core/java/android/provider/CallLog.java index 276f16216b4d..c3b6d8e2cfe3 100644 --- a/core/java/android/provider/CallLog.java +++ b/core/java/android/provider/CallLog.java @@ -870,7 +870,7 @@ public class CallLog { // Otherwise, insert to all other users that are running and unlocked. - final List<UserInfo> users = userManager.getUsers(true); + final List<UserInfo> users = userManager.getAliveUsers(); final int count = users.size(); for (int i = 0; i < count; i++) { diff --git a/core/java/android/provider/DocumentsProvider.java b/core/java/android/provider/DocumentsProvider.java index 327bca268a7b..d55fc511fc77 100644 --- a/core/java/android/provider/DocumentsProvider.java +++ b/core/java/android/provider/DocumentsProvider.java @@ -218,8 +218,15 @@ public abstract class DocumentsProvider extends ContentProvider { } /** {@hide} */ - private void enforceTree(Uri documentUri) { - if (isTreeUri(documentUri)) { + private void enforceTreeForExtraUris(Bundle extras) { + enforceTree(extras.getParcelable(DocumentsContract.EXTRA_URI)); + enforceTree(extras.getParcelable(DocumentsContract.EXTRA_PARENT_URI)); + enforceTree(extras.getParcelable(DocumentsContract.EXTRA_TARGET_URI)); + } + + /** {@hide} */ + private void enforceTree(@Nullable Uri documentUri) { + if (documentUri != null && isTreeUri(documentUri)) { final String parent = getTreeDocumentId(documentUri); final String child = getDocumentId(documentUri); if (Objects.equals(parent, child)) { @@ -1076,6 +1083,9 @@ public abstract class DocumentsProvider extends ContentProvider { final Context context = getContext(); final Bundle out = new Bundle(); + // If the URI is a tree URI performs some validation. + enforceTreeForExtraUris(extras); + if (METHOD_EJECT_ROOT.equals(method)) { // Given that certain system apps can hold MOUNT_UNMOUNT permission, but only apps // signed with platform signature can hold MANAGE_DOCUMENTS, we are going to check for @@ -1099,9 +1109,6 @@ public abstract class DocumentsProvider extends ContentProvider { "Requested authority " + authority + " doesn't match provider " + mAuthority); } - // If the URI is a tree URI performs some validation. - enforceTree(documentUri); - if (METHOD_IS_CHILD_DOCUMENT.equals(method)) { enforceReadPermissionInner(documentUri, getCallingPackage(), getCallingAttributionTag(), null); diff --git a/core/java/android/telephony/PhoneStateListener.java b/core/java/android/telephony/PhoneStateListener.java index b80718018652..cbc304b3293a 100644 --- a/core/java/android/telephony/PhoneStateListener.java +++ b/core/java/android/telephony/PhoneStateListener.java @@ -950,10 +950,6 @@ public class PhoneStateListener { * This method will be called when an emergency call is placed on any subscription (including * the no-SIM case), regardless of which subscription this listener was registered on. * - * This method is deprecated. Both this method and the new - * {@link #onOutgoingEmergencyCall(EmergencyNumber, int)} will be called when an outgoing - * emergency call is placed. - * * @param placedEmergencyNumber The {@link EmergencyNumber} the emergency call was placed to. * * @deprecated Use {@link #onOutgoingEmergencyCall(EmergencyNumber, int)}. @@ -972,22 +968,24 @@ public class PhoneStateListener { * This method will be called when an emergency call is placed on any subscription (including * the no-SIM case), regardless of which subscription this listener was registered on. * - * Both this method and the deprecated {@link #onOutgoingEmergencyCall(EmergencyNumber)} will be - * called when an outgoing emergency call is placed. You should only implement one of these - * methods. + * The default implementation of this method calls + * {@link #onOutgoingEmergencyCall(EmergencyNumber)} for backwards compatibility purposes. Do + * not call {@code super(...)} from within your implementation unless you want + * {@link #onOutgoingEmergencyCall(EmergencyNumber)} to be called as well. * * @param placedEmergencyNumber The {@link EmergencyNumber} the emergency call was placed to. * @param subscriptionId The subscription ID used to place the emergency call. If the * emergency call was placed without a valid subscription (e.g. when there * are no SIM cards in the device), this will be equal to * {@link SubscriptionManager#INVALID_SUBSCRIPTION_ID}. - * * @hide */ @SystemApi @TestApi public void onOutgoingEmergencyCall(@NonNull EmergencyNumber placedEmergencyNumber, int subscriptionId) { + // Default implementation for backwards compatibility + onOutgoingEmergencyCall(placedEmergencyNumber); } /** @@ -1375,10 +1373,6 @@ public class PhoneStateListener { Binder.withCleanCallingIdentity( () -> mExecutor.execute( - () -> psl.onOutgoingEmergencyCall(placedEmergencyNumber))); - - Binder.withCleanCallingIdentity( - () -> mExecutor.execute( () -> psl.onOutgoingEmergencyCall(placedEmergencyNumber, subscriptionId))); } diff --git a/core/java/android/view/inputmethod/TEST_MAPPING b/core/java/android/view/inputmethod/TEST_MAPPING new file mode 100644 index 000000000000..4b2ea1a096c8 --- /dev/null +++ b/core/java/android/view/inputmethod/TEST_MAPPING @@ -0,0 +1,18 @@ +{ + "presubmit": [ + { + "name": "CtsAutoFillServiceTestCases", + "options": [ + { + "include-filter": "android.autofillservice.cts.inline" + }, + { + "exclude-annotation": "androidx.test.filters.FlakyTest" + }, + { + "exclude-annotation": "android.platform.test.annotations.AppModeFull" + } + ] + } + ] +} diff --git a/core/java/android/window/ITaskOrganizerController.aidl b/core/java/android/window/ITaskOrganizerController.aidl index 92fa80e40caf..12b16ff6645c 100644 --- a/core/java/android/window/ITaskOrganizerController.aidl +++ b/core/java/android/window/ITaskOrganizerController.aidl @@ -60,5 +60,6 @@ interface ITaskOrganizerController { * Requests that the given task organizer is notified when back is pressed on the root activity * of one of its controlled tasks. */ - void setInterceptBackPressedOnTaskRoot(ITaskOrganizer organizer, boolean interceptBackPressed); + void setInterceptBackPressedOnTaskRoot(in WindowContainerToken task, + boolean interceptBackPressed); } diff --git a/core/java/android/window/TaskOrganizer.java b/core/java/android/window/TaskOrganizer.java index 7ec4f99ce959..38fb023a0822 100644 --- a/core/java/android/window/TaskOrganizer.java +++ b/core/java/android/window/TaskOrganizer.java @@ -149,9 +149,10 @@ public class TaskOrganizer extends WindowOrganizer { * of one of its controlled tasks. */ @RequiresPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS) - public void setInterceptBackPressedOnTaskRoot(boolean interceptBackPressed) { + public void setInterceptBackPressedOnTaskRoot(@NonNull WindowContainerToken task, + boolean interceptBackPressed) { try { - getController().setInterceptBackPressedOnTaskRoot(mInterface, interceptBackPressed); + getController().setInterceptBackPressedOnTaskRoot(task, interceptBackPressed); } catch (RemoteException e) { throw e.rethrowFromSystemServer(); } diff --git a/core/java/android/window/TaskOrganizerTaskEmbedder.java b/core/java/android/window/TaskOrganizerTaskEmbedder.java index 46c72f88e14b..eb9dfed7f644 100644 --- a/core/java/android/window/TaskOrganizerTaskEmbedder.java +++ b/core/java/android/window/TaskOrganizerTaskEmbedder.java @@ -74,7 +74,7 @@ public class TaskOrganizerTaskEmbedder extends TaskEmbedder { // windowing mode tasks. Plan is to migrate this to a wm-shell front-end when that // infrastructure is ready. // mTaskOrganizer.registerOrganizer(); - mTaskOrganizer.setInterceptBackPressedOnTaskRoot(true); + // mTaskOrganizer.setInterceptBackPressedOnTaskRoot(true); return super.onInitialize(); } diff --git a/core/jni/android_media_AudioTrack.cpp b/core/jni/android_media_AudioTrack.cpp index 5c045b65be22..7a5c38385f32 100644 --- a/core/jni/android_media_AudioTrack.cpp +++ b/core/jni/android_media_AudioTrack.cpp @@ -20,6 +20,7 @@ #include "android_media_AudioTrack.h" #include <nativehelper/JNIHelp.h> +#include <nativehelper/ScopedUtfChars.h> #include "core_jni_helpers.h" #include <utils/Log.h> @@ -251,7 +252,7 @@ static jint android_media_AudioTrack_setup(JNIEnv *env, jobject thiz, jobject we jint audioFormat, jint buffSizeInBytes, jint memoryMode, jintArray jSession, jlong nativeAudioTrack, jboolean offload, jint encapsulationMode, - jobject tunerConfiguration) { + jobject tunerConfiguration, jstring opPackageName) { ALOGV("sampleRates=%p, channel mask=%x, index mask=%x, audioFormat(Java)=%d, buffSize=%d," " nativeAudioTrack=0x%" PRIX64 ", offload=%d encapsulationMode=%d tuner=%p", jSampleRate, channelPositionMask, channelIndexMask, audioFormat, buffSizeInBytes, @@ -337,7 +338,8 @@ static jint android_media_AudioTrack_setup(JNIEnv *env, jobject thiz, jobject we } // create the native AudioTrack object - lpTrack = new AudioTrack(); + ScopedUtfChars opPackageNameStr(env, opPackageName); + lpTrack = new AudioTrack(opPackageNameStr.c_str()); // read the AudioAttributes values auto paa = JNIAudioAttributeHelper::makeUnique(); @@ -371,23 +373,24 @@ static jint android_media_AudioTrack_setup(JNIEnv *env, jobject thiz, jobject we status_t status = NO_ERROR; switch (memoryMode) { case MODE_STREAM: - status = lpTrack->set( - AUDIO_STREAM_DEFAULT,// stream type, but more info conveyed in paa (last argument) - sampleRateInHertz, - format,// word length, PCM - nativeChannelMask, - offload ? 0 : frameCount, - offload ? AUDIO_OUTPUT_FLAG_COMPRESS_OFFLOAD : AUDIO_OUTPUT_FLAG_NONE, - audioCallback, &(lpJniStorage->mCallbackData),//callback, callback data (user) - 0,// notificationFrames == 0 since not using EVENT_MORE_DATA to feed the AudioTrack - 0,// shared mem - true,// thread can call Java - sessionId,// audio session ID - offload ? AudioTrack::TRANSFER_SYNC_NOTIF_CALLBACK : AudioTrack::TRANSFER_SYNC, - offload ? &offloadInfo : NULL, - -1, -1, // default uid, pid values - paa.get()); - + status = lpTrack->set(AUDIO_STREAM_DEFAULT, // stream type, but more info conveyed + // in paa (last argument) + sampleRateInHertz, + format, // word length, PCM + nativeChannelMask, offload ? 0 : frameCount, + offload ? AUDIO_OUTPUT_FLAG_COMPRESS_OFFLOAD + : AUDIO_OUTPUT_FLAG_NONE, + audioCallback, + &(lpJniStorage->mCallbackData), // callback, callback data (user) + 0, // notificationFrames == 0 since not using EVENT_MORE_DATA + // to feed the AudioTrack + 0, // shared mem + true, // thread can call Java + sessionId, // audio session ID + offload ? AudioTrack::TRANSFER_SYNC_NOTIF_CALLBACK + : AudioTrack::TRANSFER_SYNC, + offload ? &offloadInfo : NULL, -1, -1, // default uid, pid values + paa.get()); break; case MODE_STATIC: @@ -398,22 +401,22 @@ static jint android_media_AudioTrack_setup(JNIEnv *env, jobject thiz, jobject we goto native_init_failure; } - status = lpTrack->set( - AUDIO_STREAM_DEFAULT,// stream type, but more info conveyed in paa (last argument) - sampleRateInHertz, - format,// word length, PCM - nativeChannelMask, - frameCount, - AUDIO_OUTPUT_FLAG_NONE, - audioCallback, &(lpJniStorage->mCallbackData),//callback, callback data (user)); - 0,// notificationFrames == 0 since not using EVENT_MORE_DATA to feed the AudioTrack - lpJniStorage->mMemBase,// shared mem - true,// thread can call Java - sessionId,// audio session ID - AudioTrack::TRANSFER_SHARED, - NULL, // default offloadInfo - -1, -1, // default uid, pid values - paa.get()); + status = lpTrack->set(AUDIO_STREAM_DEFAULT, // stream type, but more info conveyed + // in paa (last argument) + sampleRateInHertz, + format, // word length, PCM + nativeChannelMask, frameCount, AUDIO_OUTPUT_FLAG_NONE, + audioCallback, + &(lpJniStorage->mCallbackData), // callback, callback data (user) + 0, // notificationFrames == 0 since not using EVENT_MORE_DATA + // to feed the AudioTrack + lpJniStorage->mMemBase, // shared mem + true, // thread can call Java + sessionId, // audio session ID + AudioTrack::TRANSFER_SHARED, + NULL, // default offloadInfo + -1, -1, // default uid, pid values + paa.get()); break; default: @@ -1428,7 +1431,8 @@ static const JNINativeMethod gMethods[] = { {"native_stop", "()V", (void *)android_media_AudioTrack_stop}, {"native_pause", "()V", (void *)android_media_AudioTrack_pause}, {"native_flush", "()V", (void *)android_media_AudioTrack_flush}, - {"native_setup", "(Ljava/lang/Object;Ljava/lang/Object;[IIIIII[IJZILjava/lang/Object;)I", + {"native_setup", + "(Ljava/lang/Object;Ljava/lang/Object;[IIIIII[IJZILjava/lang/Object;Ljava/lang/String;)I", (void *)android_media_AudioTrack_setup}, {"native_finalize", "()V", (void *)android_media_AudioTrack_finalize}, {"native_release", "()V", (void *)android_media_AudioTrack_release}, diff --git a/media/java/android/media/AudioTrack.java b/media/java/android/media/AudioTrack.java index 1c0a526f536c..de2a7b2c15e3 100644 --- a/media/java/android/media/AudioTrack.java +++ b/media/java/android/media/AudioTrack.java @@ -807,7 +807,8 @@ public class AudioTrack extends PlayerBase int initResult = native_setup(new WeakReference<AudioTrack>(this), mAttributes, sampleRate, mChannelMask, mChannelIndexMask, mAudioFormat, mNativeBufferSizeInBytes, mDataLoadMode, session, 0 /*nativeTrackInJavaObj*/, - offload, encapsulationMode, tunerConfiguration); + offload, encapsulationMode, tunerConfiguration, + getCurrentOpPackageName()); if (initResult != SUCCESS) { loge("Error code "+initResult+" when initializing AudioTrack."); return; // with mState == STATE_UNINITIALIZED @@ -893,7 +894,8 @@ public class AudioTrack extends PlayerBase nativeTrackInJavaObj, false /*offload*/, ENCAPSULATION_MODE_NONE, - null /* tunerConfiguration */); + null /* tunerConfiguration */, + "" /* opPackagename */); if (initResult != SUCCESS) { loge("Error code "+initResult+" when initializing AudioTrack."); return; // with mState == STATE_UNINITIALIZED @@ -4062,7 +4064,8 @@ public class AudioTrack extends PlayerBase Object /*AudioAttributes*/ attributes, int[] sampleRate, int channelMask, int channelIndexMask, int audioFormat, int buffSizeInBytes, int mode, int[] sessionId, long nativeAudioTrack, - boolean offload, int encapsulationMode, Object tunerConfiguration); + boolean offload, int encapsulationMode, Object tunerConfiguration, + @NonNull String opPackageName); private native final void native_finalize(); diff --git a/media/java/android/media/MediaPlayer.java b/media/java/android/media/MediaPlayer.java index 49e416080041..36ae3ec75a99 100644 --- a/media/java/android/media/MediaPlayer.java +++ b/media/java/android/media/MediaPlayer.java @@ -672,7 +672,8 @@ public class MediaPlayer extends PlayerBase /* Native setup requires a weak reference to our object. * It's easier to create it here than in C++. */ - native_setup(new WeakReference<MediaPlayer>(this)); + native_setup(new WeakReference<MediaPlayer>(this), + getCurrentOpPackageName()); baseRegisterPlayer(); } @@ -2378,7 +2379,7 @@ public class MediaPlayer extends PlayerBase private native final int native_setMetadataFilter(Parcel request); private static native final void native_init(); - private native final void native_setup(Object mediaplayer_this); + private native void native_setup(Object mediaplayerThis, @NonNull String opPackageName); private native final void native_finalize(); /** diff --git a/media/java/android/media/PlayerBase.java b/media/java/android/media/PlayerBase.java index ee8f1b3eec77..df5e85edbc30 100644 --- a/media/java/android/media/PlayerBase.java +++ b/media/java/android/media/PlayerBase.java @@ -27,6 +27,7 @@ import android.os.Parcelable; import android.os.Process; import android.os.RemoteException; import android.os.ServiceManager; +import android.text.TextUtils; import android.util.Log; import com.android.internal.annotations.GuardedBy; @@ -622,4 +623,8 @@ public abstract class PlayerBase { Log.w(className, "See the documentation of " + opName + " for what to use instead with " + "android.media.AudioAttributes to qualify your playback use case"); } + + protected String getCurrentOpPackageName() { + return TextUtils.emptyIfNull(ActivityThread.currentOpPackageName()); + } } diff --git a/media/jni/android_media_MediaPlayer.cpp b/media/jni/android_media_MediaPlayer.cpp index 55aac09b0f65..bd8d2e9f77a4 100644 --- a/media/jni/android_media_MediaPlayer.cpp +++ b/media/jni/android_media_MediaPlayer.cpp @@ -33,6 +33,7 @@ #include <utils/threads.h> #include "jni.h" #include <nativehelper/JNIPlatformHelp.h> +#include <nativehelper/ScopedUtfChars.h> #include "android_runtime/AndroidRuntime.h" #include "android_runtime/android_view_Surface.h" #include "android_runtime/Log.h" @@ -944,10 +945,12 @@ android_media_MediaPlayer_native_init(JNIEnv *env) } static void -android_media_MediaPlayer_native_setup(JNIEnv *env, jobject thiz, jobject weak_this) +android_media_MediaPlayer_native_setup(JNIEnv *env, jobject thiz, jobject weak_this, + jstring opPackageName) { ALOGV("native_setup"); - sp<MediaPlayer> mp = new MediaPlayer(); + ScopedUtfChars opPackageNameStr(env, opPackageName); + sp<MediaPlayer> mp = new MediaPlayer(opPackageNameStr.c_str()); if (mp == NULL) { jniThrowException(env, "java/lang/RuntimeException", "Out of memory"); return; @@ -1403,7 +1406,7 @@ static const JNINativeMethod gMethods[] = { {"native_setMetadataFilter", "(Landroid/os/Parcel;)I", (void *)android_media_MediaPlayer_setMetadataFilter}, {"native_getMetadata", "(ZZLandroid/os/Parcel;)Z", (void *)android_media_MediaPlayer_getMetadata}, {"native_init", "()V", (void *)android_media_MediaPlayer_native_init}, - {"native_setup", "(Ljava/lang/Object;)V", (void *)android_media_MediaPlayer_native_setup}, + {"native_setup", "(Ljava/lang/Object;Ljava/lang/String;)V",(void *)android_media_MediaPlayer_native_setup}, {"native_finalize", "()V", (void *)android_media_MediaPlayer_native_finalize}, {"getAudioSessionId", "()I", (void *)android_media_MediaPlayer_get_audio_session_id}, {"setAudioSessionId", "(I)V", (void *)android_media_MediaPlayer_set_audio_session_id}, diff --git a/media/packages/BluetoothMidiService/AndroidManifest.xml b/media/packages/BluetoothMidiService/AndroidManifest.xml index b88bf2a0b2b7..fc96fd926e2d 100644 --- a/media/packages/BluetoothMidiService/AndroidManifest.xml +++ b/media/packages/BluetoothMidiService/AndroidManifest.xml @@ -19,8 +19,6 @@ <manifest xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" package="com.android.bluetoothmidiservice" - android:versionCode="1" - android:versionName="R-initial" > <uses-sdk android:minSdkVersion="29" android:targetSdkVersion="29" /> diff --git a/media/packages/BluetoothMidiService/AndroidManifestBase.xml b/media/packages/BluetoothMidiService/AndroidManifestBase.xml index ebe62b039434..bfb05469adb9 100644 --- a/media/packages/BluetoothMidiService/AndroidManifestBase.xml +++ b/media/packages/BluetoothMidiService/AndroidManifestBase.xml @@ -18,8 +18,6 @@ --> <manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.android.bluetoothmidiservice" - android:versionCode="1" - android:versionName="R-initial" > <uses-sdk android:minSdkVersion="29" android:targetSdkVersion="29" /> <application diff --git a/packages/CarSystemUI/src/com/android/systemui/car/CarDeviceProvisionedControllerImpl.java b/packages/CarSystemUI/src/com/android/systemui/car/CarDeviceProvisionedControllerImpl.java index a2ba880facfe..fef032414bb9 100644 --- a/packages/CarSystemUI/src/com/android/systemui/car/CarDeviceProvisionedControllerImpl.java +++ b/packages/CarSystemUI/src/com/android/systemui/car/CarDeviceProvisionedControllerImpl.java @@ -16,20 +16,19 @@ package com.android.systemui.car; +import android.annotation.NonNull; import android.app.ActivityManager; import android.car.settings.CarSettings; -import android.content.ContentResolver; -import android.content.Context; import android.database.ContentObserver; import android.net.Uri; import android.os.Handler; -import android.provider.Settings; -import com.android.systemui.Dependency; import com.android.systemui.broadcast.BroadcastDispatcher; import com.android.systemui.dagger.SysUISingleton; import com.android.systemui.dagger.qualifiers.Main; import com.android.systemui.statusbar.policy.DeviceProvisionedControllerImpl; +import com.android.systemui.util.settings.GlobalSettings; +import com.android.systemui.util.settings.SecureSettings; import javax.inject.Inject; @@ -40,30 +39,33 @@ import javax.inject.Inject; @SysUISingleton public class CarDeviceProvisionedControllerImpl extends DeviceProvisionedControllerImpl implements CarDeviceProvisionedController { - private static final Uri USER_SETUP_IN_PROGRESS_URI = Settings.Secure.getUriFor( - CarSettings.Secure.KEY_SETUP_WIZARD_IN_PROGRESS); - private final ContentObserver mCarSettingsObserver = new ContentObserver( - Dependency.get(Dependency.MAIN_HANDLER)) { - - @Override - public void onChange(boolean selfChange, Uri uri, int flags) { - if (USER_SETUP_IN_PROGRESS_URI.equals(uri)) { - notifyUserSetupInProgressChanged(); - } - } - }; - private final ContentResolver mContentResolver; + private final Uri mUserSetupInProgressUri; + private final ContentObserver mCarSettingsObserver; + private final Handler mMainHandler; + private final SecureSettings mSecureSettings; @Inject - public CarDeviceProvisionedControllerImpl(Context context, @Main Handler mainHandler, - BroadcastDispatcher broadcastDispatcher) { - super(context, mainHandler, broadcastDispatcher); - mContentResolver = context.getContentResolver(); + public CarDeviceProvisionedControllerImpl(@Main Handler mainHandler, + BroadcastDispatcher broadcastDispatcher, GlobalSettings globalSetting, + SecureSettings secureSettings) { + super(mainHandler, broadcastDispatcher, globalSetting, secureSettings); + mMainHandler = mainHandler; + mSecureSettings = secureSettings; + mUserSetupInProgressUri = mSecureSettings.getUriFor( + CarSettings.Secure.KEY_SETUP_WIZARD_IN_PROGRESS); + mCarSettingsObserver = new ContentObserver(mMainHandler) { + @Override + public void onChange(boolean selfChange, Uri uri, int flags) { + if (mUserSetupInProgressUri.equals(uri)) { + notifyUserSetupInProgressChanged(); + } + } + }; } @Override public boolean isUserSetupInProgress(int user) { - return Settings.Secure.getIntForUser(mContentResolver, + return mSecureSettings.getIntForUser( CarSettings.Secure.KEY_SETUP_WIZARD_IN_PROGRESS, /* def= */ 0, user) != 0; } @@ -73,7 +75,7 @@ public class CarDeviceProvisionedControllerImpl extends DeviceProvisionedControl } @Override - public void addCallback(DeviceProvisionedListener listener) { + public void addCallback(@NonNull DeviceProvisionedListener listener) { super.addCallback(listener); if (listener instanceof CarDeviceProvisionedListener) { ((CarDeviceProvisionedListener) listener).onUserSetupInProgressChanged(); @@ -82,9 +84,9 @@ public class CarDeviceProvisionedControllerImpl extends DeviceProvisionedControl @Override protected void startListening(int user) { - mContentResolver.registerContentObserver( - USER_SETUP_IN_PROGRESS_URI, /* notifyForDescendants= */ true, mCarSettingsObserver, - user); + mSecureSettings.registerContentObserverForUser( + mUserSetupInProgressUri, /* notifyForDescendants= */ true, + mCarSettingsObserver, user); // The SUW Flag observer is registered before super.startListening() so that the observer is // in place before DeviceProvisionedController starts to track user switches which avoids // an edge case where our observer gets registered twice. @@ -94,16 +96,16 @@ public class CarDeviceProvisionedControllerImpl extends DeviceProvisionedControl @Override protected void stopListening() { super.stopListening(); - mContentResolver.unregisterContentObserver(mCarSettingsObserver); + mSecureSettings.unregisterContentObserver(mCarSettingsObserver); } @Override public void onUserSwitched(int newUserId) { super.onUserSwitched(newUserId); - mContentResolver.unregisterContentObserver(mCarSettingsObserver); - mContentResolver.registerContentObserver( - USER_SETUP_IN_PROGRESS_URI, /* notifyForDescendants= */ true, mCarSettingsObserver, - newUserId); + mSecureSettings.unregisterContentObserver(mCarSettingsObserver); + mSecureSettings.registerContentObserverForUser( + mUserSetupInProgressUri, /* notifyForDescendants= */ true, + mCarSettingsObserver, newUserId); } private void notifyUserSetupInProgressChanged() { diff --git a/packages/CarSystemUI/src/com/android/systemui/car/notification/NotificationPanelViewController.java b/packages/CarSystemUI/src/com/android/systemui/car/notification/NotificationPanelViewController.java index 38e1a48ab3a7..fe4cba8e73cd 100644 --- a/packages/CarSystemUI/src/com/android/systemui/car/notification/NotificationPanelViewController.java +++ b/packages/CarSystemUI/src/com/android/systemui/car/notification/NotificationPanelViewController.java @@ -91,7 +91,6 @@ public class NotificationPanelViewController extends OverlayPanelViewController private RecyclerView mNotificationList; private NotificationViewController mNotificationViewController; - private boolean mIsTracking; private boolean mNotificationListAtEnd; private float mFirstTouchDownOnGlassPane; private boolean mNotificationListAtEndAtTimeOfTouch; @@ -306,7 +305,7 @@ public class NotificationPanelViewController extends OverlayPanelViewController mFirstTouchDownOnGlassPane = event.getRawX(); mNotificationListAtEndAtTimeOfTouch = mNotificationListAtEnd; // Reset the tracker when there is a touch down on the glass pane. - mIsTracking = false; + setIsTracking(false); // Pass the down event to gesture detector so that it knows where the touch event // started. closeGestureDetector.onTouchEvent(event); @@ -341,15 +340,15 @@ public class NotificationPanelViewController extends OverlayPanelViewController // If the card is swiping we should not allow the notification shade to close. // Hence setting mNotificationListAtEndAtTimeOfTouch to false will stop that - // for us. We are also checking for mIsTracking because while swiping the + // for us. We are also checking for isTracking() because while swiping the // notification shade to close if the user goes a bit horizontal while swiping // upwards then also this should close. - if (mIsNotificationCardSwiping && !mIsTracking) { + if (mIsNotificationCardSwiping && !isTracking()) { mNotificationListAtEndAtTimeOfTouch = false; } boolean handled = closeGestureDetector.onTouchEvent(event); - boolean isTracking = mIsTracking; + boolean isTracking = isTracking(); Rect rect = getLayout().getClipBounds(); float clippedHeight = 0; if (rect != null) { diff --git a/packages/CarSystemUI/src/com/android/systemui/car/userswitcher/UserGridRecyclerView.java b/packages/CarSystemUI/src/com/android/systemui/car/userswitcher/UserGridRecyclerView.java index 5bd8797c5349..023b5b4f5f30 100644 --- a/packages/CarSystemUI/src/com/android/systemui/car/userswitcher/UserGridRecyclerView.java +++ b/packages/CarSystemUI/src/com/android/systemui/car/userswitcher/UserGridRecyclerView.java @@ -131,7 +131,7 @@ public class UserGridRecyclerView extends RecyclerView { } private List<UserInfo> getUsersForUserGrid() { - return mUserManager.getUsers(/* excludeDying= */ true) + return mUserManager.getAliveUsers() .stream() .filter(UserInfo::supportsSwitchToByUser) .collect(Collectors.toList()); @@ -338,7 +338,7 @@ public class UserGridRecyclerView extends RecyclerView { maxSupportedUsers -= 1; } - List<UserInfo> users = mUserManager.getUsers(/* excludeDying= */ true); + List<UserInfo> users = mUserManager.getAliveUsers(); // Count all users that are managed profiles of another user. int managedProfilesCount = 0; diff --git a/packages/CarSystemUI/src/com/android/systemui/car/window/OverlayPanelViewController.java b/packages/CarSystemUI/src/com/android/systemui/car/window/OverlayPanelViewController.java index bde31f18d8fd..1b00c6301011 100644 --- a/packages/CarSystemUI/src/com/android/systemui/car/window/OverlayPanelViewController.java +++ b/packages/CarSystemUI/src/com/android/systemui/car/window/OverlayPanelViewController.java @@ -297,14 +297,17 @@ public abstract class OverlayPanelViewController extends OverlayViewController { float from = getCurrentStartPosition(rect); if (from != to) { animate(from, to, velocity, isClosing); - return; } + + // If we swipe down the notification panel all the way to the bottom of the screen + // (i.e. from == to), then we have finished animating the panel. + return; } // We will only be here if the shade is being opened programmatically or via button when // height of the layout was not calculated. - ViewTreeObserver notificationTreeObserver = getLayout().getViewTreeObserver(); - notificationTreeObserver.addOnGlobalLayoutListener( + ViewTreeObserver panelTreeObserver = getLayout().getViewTreeObserver(); + panelTreeObserver.addOnGlobalLayoutListener( new ViewTreeObserver.OnGlobalLayoutListener() { @Override public void onGlobalLayout() { @@ -507,6 +510,11 @@ public abstract class OverlayPanelViewController extends OverlayViewController { return mIsTracking; } + /** Sets whether the panel is currently tracking or not. */ + protected final void setIsTracking(boolean isTracking) { + mIsTracking = isTracking; + } + /** Returns {@code true} if the panel is currently animating. */ protected final boolean isAnimating() { return mIsAnimating; @@ -545,7 +553,7 @@ public abstract class OverlayPanelViewController extends OverlayViewController { } setPanelVisible(true); - // clips the view for the notification shade when the user scrolls to open. + // clips the view for the panel when the user scrolls to open. setViewClipBounds((int) event2.getRawY()); // Initially the scroll starts with height being zero. This checks protects from divide @@ -600,11 +608,11 @@ public abstract class OverlayPanelViewController extends OverlayViewController { boolean isInClosingDirection = mAnimateDirection * distanceY > 0; // This check is to figure out if onScroll was called while swiping the card at - // bottom of the list. At that time we should not allow notification shade to + // bottom of the panel. At that time we should not allow panel to // close. We are also checking for the upwards swipe gesture here because it is - // possible if a user is closing the notification shade and while swiping starts + // possible if a user is closing the panel and while swiping starts // to open again but does not fling. At that time we should allow the - // notification shade to close fully or else it would stuck in between. + // panel to close fully or else it would stuck in between. if (Math.abs(getLayout().getHeight() - y) > SWIPE_DOWN_MIN_DISTANCE && isInClosingDirection) { setViewClipBounds((int) y); diff --git a/packages/CompanionDeviceManager/TEST_MAPPING b/packages/CompanionDeviceManager/TEST_MAPPING new file mode 100644 index 000000000000..63f54fa35158 --- /dev/null +++ b/packages/CompanionDeviceManager/TEST_MAPPING @@ -0,0 +1,12 @@ +{ + "presubmit": [ + { + "name": "CtsOsTestCases", + "options": [ + { + "include-filter": "android.os.cts.CompanionDeviceManagerTest" + } + ] + } + ] +} diff --git a/packages/SettingsProvider/src/com/android/providers/settings/SettingsProvider.java b/packages/SettingsProvider/src/com/android/providers/settings/SettingsProvider.java index 807fbed7d8fd..9c92b464dfbb 100644 --- a/packages/SettingsProvider/src/com/android/providers/settings/SettingsProvider.java +++ b/packages/SettingsProvider/src/com/android/providers/settings/SettingsProvider.java @@ -2576,7 +2576,7 @@ public class SettingsProvider extends ContentProvider { public void syncSsaidTableOnStart() { synchronized (mLock) { // Verify that each user's packages and ssaid's are in sync. - for (UserInfo user : mUserManager.getUsers(true)) { + for (UserInfo user : mUserManager.getAliveUsers()) { // Get all uids for the user's packages. final List<PackageInfo> packages; try { @@ -3007,7 +3007,7 @@ public class SettingsProvider extends ContentProvider { final long identity = Binder.clearCallingIdentity(); try { - List<UserInfo> users = mUserManager.getUsers(true); + List<UserInfo> users = mUserManager.getAliveUsers(); final int userCount = users.size(); for (int i = 0; i < userCount; i++) { @@ -3244,7 +3244,7 @@ public class SettingsProvider extends ContentProvider { // is a singleton generation entry for the global settings which // is already incremented be the caller. final Uri uri = getNotificationUriFor(key, name); - final List<UserInfo> users = mUserManager.getUsers(/*excludeDying*/ true); + final List<UserInfo> users = mUserManager.getAliveUsers(); for (int i = 0; i < users.size(); i++) { final int userId = users.get(i).id; if (mUserManager.isUserRunning(UserHandle.of(userId))) { @@ -3255,7 +3255,7 @@ public class SettingsProvider extends ContentProvider { } private void notifyLocationChangeForRunningUsers() { - final List<UserInfo> users = mUserManager.getUsers(/*excludeDying=*/ true); + final List<UserInfo> users = mUserManager.getAliveUsers(); for (int i = 0; i < users.size(); i++) { final int userId = users.get(i).id; diff --git a/packages/SystemUI/src/com/android/systemui/SystemUIFactory.java b/packages/SystemUI/src/com/android/systemui/SystemUIFactory.java index 3d8d90f426a1..f15949977754 100644 --- a/packages/SystemUI/src/com/android/systemui/SystemUIFactory.java +++ b/packages/SystemUI/src/com/android/systemui/SystemUIFactory.java @@ -28,6 +28,7 @@ import com.android.systemui.dagger.SysUIComponent; import com.android.systemui.dagger.WMComponent; import com.android.systemui.screenshot.ScreenshotNotificationSmartActionsProvider; +import java.util.concurrent.ExecutionException; import java.util.concurrent.Executor; /** @@ -73,11 +74,16 @@ public class SystemUIFactory { public SystemUIFactory() {} - private void init(Context context) { + private void init(Context context) throws ExecutionException, InterruptedException { mRootComponent = buildGlobalRootComponent(context); + // Stand up WMComponent mWMComponent = mRootComponent.getWMComponentBuilder().build(); - // TODO: use WMComponent to pass APIs into the SysUIComponent. - mSysUIComponent = mRootComponent.getSysUIComponent().build(); + + // And finally, retrieve whatever SysUI needs from WMShell and build SysUI. + // TODO: StubAPIClass is just a placeholder. + mSysUIComponent = mRootComponent.getSysUIComponent() + .setStubAPIClass(mWMComponent.createStubAPIClass()) + .build(); // Every other part of our codebase currently relies on Dependency, so we // really need to ensure the Dependency gets initialized early on. @@ -91,10 +97,15 @@ public class SystemUIFactory { .build(); } + public GlobalRootComponent getRootComponent() { return mRootComponent; } + public WMComponent getWMComponent() { + return mWMComponent; + } + public SysUIComponent getSysUIComponent() { return mSysUIComponent; } diff --git a/packages/SystemUI/src/com/android/systemui/dagger/GlobalModule.java b/packages/SystemUI/src/com/android/systemui/dagger/GlobalModule.java index fd4a4093110f..c5dc8cccfdf4 100644 --- a/packages/SystemUI/src/com/android/systemui/dagger/GlobalModule.java +++ b/packages/SystemUI/src/com/android/systemui/dagger/GlobalModule.java @@ -16,6 +16,8 @@ package com.android.systemui.dagger; +import com.android.systemui.util.concurrency.GlobalConcurrencyModule; + import dagger.Module; /** @@ -33,6 +35,8 @@ import dagger.Module; * * Please use discretion when adding things to the global scope. */ -@Module(includes = {FrameworkServicesModule.class}) +@Module(includes = { + FrameworkServicesModule.class, + GlobalConcurrencyModule.class}) public class GlobalModule { } diff --git a/packages/SystemUI/src/com/android/systemui/dagger/GlobalRootComponent.java b/packages/SystemUI/src/com/android/systemui/dagger/GlobalRootComponent.java index 36fd3373290d..00fdf55b28e0 100644 --- a/packages/SystemUI/src/com/android/systemui/dagger/GlobalRootComponent.java +++ b/packages/SystemUI/src/com/android/systemui/dagger/GlobalRootComponent.java @@ -18,6 +18,8 @@ package com.android.systemui.dagger; import android.content.Context; +import com.android.systemui.util.concurrency.ThreadFactory; + import javax.inject.Singleton; import dagger.BindsInstance; @@ -53,4 +55,9 @@ public interface GlobalRootComponent { * Builder for a SysuiComponent. */ SysUIComponent.Builder getSysUIComponent(); + + /** + * Build a {@link ThreadFactory}. + */ + ThreadFactory createThreadFactory(); } diff --git a/packages/SystemUI/src/com/android/systemui/dagger/SysUIComponent.java b/packages/SystemUI/src/com/android/systemui/dagger/SysUIComponent.java index a8ed043c4361..2622593880ba 100644 --- a/packages/SystemUI/src/com/android/systemui/dagger/SysUIComponent.java +++ b/packages/SystemUI/src/com/android/systemui/dagger/SysUIComponent.java @@ -26,6 +26,7 @@ import com.android.systemui.pip.phone.dagger.PipModule; import com.android.systemui.statusbar.policy.ConfigurationController; import com.android.systemui.util.InjectionInflationController; +import dagger.BindsInstance; import dagger.Subcomponent; /** @@ -46,6 +47,9 @@ public interface SysUIComponent { */ @Subcomponent.Builder interface Builder { + @BindsInstance + Builder setStubAPIClass(WMComponent.StubAPIClass stubAPIClass); + SysUIComponent build(); } diff --git a/packages/SystemUI/src/com/android/systemui/dagger/SystemUIModule.java b/packages/SystemUI/src/com/android/systemui/dagger/SystemUIModule.java index 803c8e0eceec..8f4e738e5a5f 100644 --- a/packages/SystemUI/src/com/android/systemui/dagger/SystemUIModule.java +++ b/packages/SystemUI/src/com/android/systemui/dagger/SystemUIModule.java @@ -43,7 +43,7 @@ import com.android.systemui.statusbar.phone.dagger.StatusBarComponent; import com.android.systemui.statusbar.policy.HeadsUpManager; import com.android.systemui.statusbar.policy.dagger.StatusBarPolicyModule; import com.android.systemui.tuner.dagger.TunerModule; -import com.android.systemui.util.concurrency.ConcurrencyModule; +import com.android.systemui.util.concurrency.SysUIConcurrencyModule; import com.android.systemui.util.dagger.UtilModule; import com.android.systemui.util.sensors.SensorModule; import com.android.systemui.util.settings.SettingsUtilModule; @@ -63,7 +63,6 @@ import dagger.Provides; @Module(includes = { AppOpsModule.class, AssistModule.class, - ConcurrencyModule.class, ControlsModule.class, DemoModeModule.class, LogModule.class, @@ -75,6 +74,7 @@ import dagger.Provides; SettingsModule.class, SettingsUtilModule.class, StatusBarPolicyModule.class, + SysUIConcurrencyModule.class, TunerModule.class, UtilModule.class, VolumeModule.class diff --git a/packages/SystemUI/src/com/android/systemui/dagger/WMComponent.java b/packages/SystemUI/src/com/android/systemui/dagger/WMComponent.java index 929b61a3421c..ad90eff3c969 100644 --- a/packages/SystemUI/src/com/android/systemui/dagger/WMComponent.java +++ b/packages/SystemUI/src/com/android/systemui/dagger/WMComponent.java @@ -16,6 +16,8 @@ package com.android.systemui.dagger; +import javax.inject.Inject; + import dagger.Subcomponent; /** @@ -32,4 +34,19 @@ public interface WMComponent { interface Builder { WMComponent build(); } + + + /** + * Example class used for passing an API to SysUI from WMShell. + * + * TODO: Remove this once real WM classes are ready to go. + **/ + @WMSingleton + class StubAPIClass { + @Inject + StubAPIClass() {} + } + + /** Create a StubAPIClass. */ + StubAPIClass createStubAPIClass(); } diff --git a/packages/SystemUI/src/com/android/systemui/media/MediaCarouselController.kt b/packages/SystemUI/src/com/android/systemui/media/MediaCarouselController.kt index a003d8365810..e5a9ac10389f 100644 --- a/packages/SystemUI/src/com/android/systemui/media/MediaCarouselController.kt +++ b/packages/SystemUI/src/com/android/systemui/media/MediaCarouselController.kt @@ -172,7 +172,6 @@ class MediaCarouselController @Inject constructor( // This view is inactive, let's remove this! This happens e.g when dismissing / // timing out a view. We still have the data around because resumption could // be on, but we should save the resources and release this. - oldKey?.let { MediaPlayerData.removeMediaPlayer(it) } onMediaDataRemoved(key) } else { addOrUpdatePlayer(key, oldKey, data) diff --git a/packages/SystemUI/src/com/android/systemui/navigationbar/NavigationBar.java b/packages/SystemUI/src/com/android/systemui/navigationbar/NavigationBar.java index aec3543de4eb..c7e78174f474 100644 --- a/packages/SystemUI/src/com/android/systemui/navigationbar/NavigationBar.java +++ b/packages/SystemUI/src/com/android/systemui/navigationbar/NavigationBar.java @@ -662,7 +662,7 @@ public class NavigationBar implements View.OnAttachStateChangeListener, WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE | WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL | WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN - | WindowManager.LayoutParams.FLAG_SPLIT_TOUCH + | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE | WindowManager.LayoutParams.FLAG_SLIPPERY, PixelFormat.TRANSLUCENT); mOrientationParams.setTitle("SecondaryHomeHandle" + mContext.getDisplayId()); diff --git a/packages/SystemUI/src/com/android/systemui/onehanded/OneHandedTutorialHandler.java b/packages/SystemUI/src/com/android/systemui/onehanded/OneHandedTutorialHandler.java index 0354c727c92c..8ef9b092bc00 100644 --- a/packages/SystemUI/src/com/android/systemui/onehanded/OneHandedTutorialHandler.java +++ b/packages/SystemUI/src/com/android/systemui/onehanded/OneHandedTutorialHandler.java @@ -158,7 +158,9 @@ public class OneHandedTutorialHandler implements OneHandedTransitionCallback, Du final WindowManager.LayoutParams lp = new WindowManager.LayoutParams( mDisplaySize.x, mTutorialAreaHeight, 0, 0, WindowManager.LayoutParams.TYPE_NAVIGATION_BAR_PANEL, - WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN, + WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN + | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE + | WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE, PixelFormat.TRANSLUCENT); lp.gravity = Gravity.TOP | Gravity.LEFT; lp.privateFlags |= WindowManager.LayoutParams.SYSTEM_FLAG_SHOW_FOR_ALL_USERS; diff --git a/packages/SystemUI/src/com/android/systemui/screenshot/GlobalScreenshot.java b/packages/SystemUI/src/com/android/systemui/screenshot/GlobalScreenshot.java index e24fbc6cca9d..7dd4edd233bd 100644 --- a/packages/SystemUI/src/com/android/systemui/screenshot/GlobalScreenshot.java +++ b/packages/SystemUI/src/com/android/systemui/screenshot/GlobalScreenshot.java @@ -573,7 +573,12 @@ public class GlobalScreenshot implements ViewTreeObserver.OnComputeInternalInset private void saveScreenshot(Bitmap screenshot, Consumer<Uri> finisher, Rect screenRect, Insets screenInsets, boolean showFlash) { - dismissScreenshot("new screenshot requested", true); + if (mScreenshotLayout.isAttachedToWindow()) { + if (!mDismissAnimation.isRunning()) { // if we didn't already dismiss for another reason + mUiEventLogger.log(ScreenshotEvent.SCREENSHOT_REENTERED); + } + dismissScreenshot("new screenshot requested", true); + } mScreenBitmap = screenshot; diff --git a/packages/SystemUI/src/com/android/systemui/screenshot/ScreenshotEvent.java b/packages/SystemUI/src/com/android/systemui/screenshot/ScreenshotEvent.java index 6b42f2e07bc3..74e0229c4992 100644 --- a/packages/SystemUI/src/com/android/systemui/screenshot/ScreenshotEvent.java +++ b/packages/SystemUI/src/com/android/systemui/screenshot/ScreenshotEvent.java @@ -59,7 +59,9 @@ public enum ScreenshotEvent implements UiEventLogger.UiEventEnum { @UiEvent(doc = "screenshot interaction timed out") SCREENSHOT_INTERACTION_TIMEOUT(310), @UiEvent(doc = "screenshot explicitly dismissed") - SCREENSHOT_EXPLICIT_DISMISSAL(311); + SCREENSHOT_EXPLICIT_DISMISSAL(311), + @UiEvent(doc = "screenshot reentered for new screenshot") + SCREENSHOT_REENTERED(640); private final int mId; diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayout.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayout.java index 3370773df807..43c74913a493 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayout.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayout.java @@ -4990,17 +4990,29 @@ public class NotificationStackScrollLayout extends ViewGroup implements Dumpable public void removeContainerView(View v) { Assert.isMainThread(); removeView(v); + if (v instanceof ExpandableNotificationRow && !mController.isShowingEmptyShadeView()) { + mController.updateShowEmptyShadeView(); + updateFooter(); + } } @ShadeViewRefactor(RefactorComponent.SHADE_VIEW) public void addContainerView(View v) { Assert.isMainThread(); addView(v); + if (v instanceof ExpandableNotificationRow && mController.isShowingEmptyShadeView()) { + mController.updateShowEmptyShadeView(); + updateFooter(); + } } public void addContainerViewAt(View v, int index) { Assert.isMainThread(); addView(v, index); + if (v instanceof ExpandableNotificationRow && mController.isShowingEmptyShadeView()) { + mController.updateShowEmptyShadeView(); + updateFooter(); + } } @ShadeViewRefactor(RefactorComponent.SHADE_VIEW) @@ -5101,6 +5113,10 @@ public class NotificationStackScrollLayout extends ViewGroup implements Dumpable updateScrollability(); } + boolean isQsExpanded() { + return mQsExpanded; + } + @ShadeViewRefactor(RefactorComponent.SHADE_VIEW) public void setQsExpansionFraction(float qsExpansionFraction) { mQsExpansionFraction = qsExpansionFraction; diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayoutController.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayoutController.java index 70892e0f9b38..f8ee0a3b191a 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayoutController.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayoutController.java @@ -17,6 +17,7 @@ package com.android.systemui.statusbar.notification.stack; import static com.android.systemui.Dependency.ALLOW_NOTIFICATION_LONG_PRESS_NAME; +import static com.android.systemui.statusbar.StatusBarState.KEYGUARD; import android.content.res.Resources; import android.graphics.Point; @@ -117,6 +118,8 @@ public class NotificationStackScrollLayoutController { private NotificationStackScrollLayout mView; private boolean mFadeNotificationsOnDismiss; private NotificationSwipeHelper mSwipeHelper; + private boolean mShowEmptyShadeView; + private int mBarState; private final NotificationListContainerImpl mNotificationListContainer = new NotificationListContainerImpl(); @@ -127,6 +130,8 @@ public class NotificationStackScrollLayoutController { @Override public void onViewAttachedToWindow(View v) { mConfigurationController.addCallback(mConfigurationListener); + mZenModeController.addCallback(mZenModeControllerCallback); + mBarState = mStatusBarStateController.getState(); mStatusBarStateController.addCallback( mStateListener, SysuiStatusBarStateController.RANK_STACK_SCROLLER); } @@ -134,6 +139,7 @@ public class NotificationStackScrollLayoutController { @Override public void onViewDetachedFromWindow(View v) { mConfigurationController.removeCallback(mConfigurationListener); + mZenModeController.removeCallback(mZenModeControllerCallback); mStatusBarStateController.removeCallback(mStateListener); } }; @@ -154,11 +160,13 @@ public class NotificationStackScrollLayoutController { final ConfigurationListener mConfigurationListener = new ConfigurationListener() { @Override public void onDensityOrFontScaleChanged() { + updateShowEmptyShadeView(); mView.reinflateViews(); } @Override public void onOverlayChanged() { + updateShowEmptyShadeView(); mView.updateCornerRadius(); mView.reinflateViews(); } @@ -179,14 +187,15 @@ public class NotificationStackScrollLayoutController { @Override public void onStatePreChange(int oldState, int newState) { if (oldState == StatusBarState.SHADE_LOCKED - && newState == StatusBarState.KEYGUARD) { + && newState == KEYGUARD) { mView.requestAnimateEverything(); } } @Override public void onStateChanged(int newState) { - mView.setStatusBarState(newState); + mBarState = newState; + mView.setStatusBarState(mBarState); } @Override @@ -480,6 +489,14 @@ public class NotificationStackScrollLayoutController { } }; + private final ZenModeController.Callback mZenModeControllerCallback = + new ZenModeController.Callback() { + @Override + public void onZenChanged(int zen) { + updateShowEmptyShadeView(); + } + }; + @Inject public NotificationStackScrollLayoutController( @Named(ALLOW_NOTIFICATION_LONG_PRESS_NAME) boolean allowLongPress, @@ -795,6 +812,7 @@ public class NotificationStackScrollLayoutController { public void setQsExpanded(boolean expanded) { mView.setQsExpanded(expanded); + updateShowEmptyShadeView(); } public void setScrollingEnabled(boolean enabled) { @@ -903,8 +921,21 @@ public class NotificationStackScrollLayoutController { return mView.getFooterViewHeightWithPadding(); } - public void updateEmptyShadeView(boolean visible) { - mView.updateEmptyShadeView(visible, mZenModeController.areNotificationsHiddenInShade()); + /** + * Update whether we should show the empty shade view (no notifications in the shade). + * If so, send the update to our view. + */ + public void updateShowEmptyShadeView() { + mShowEmptyShadeView = mBarState != KEYGUARD + && !mView.isQsExpanded() + && mView.getVisibleNotificationCount() == 0; + mView.updateEmptyShadeView( + mShowEmptyShadeView, + mZenModeController.areNotificationsHiddenInShade()); + } + + public boolean isShowingEmptyShadeView() { + return mShowEmptyShadeView; } public void setHeadsUpAnimatingAway(boolean headsUpAnimatingAway) { diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelViewController.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelViewController.java index 1cd85e3b3cc1..ab3fac9868a8 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelViewController.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelViewController.java @@ -107,6 +107,7 @@ import com.android.systemui.statusbar.notification.PropertyAnimator; import com.android.systemui.statusbar.notification.ViewGroupFadeHelper; import com.android.systemui.statusbar.notification.collection.ListEntry; import com.android.systemui.statusbar.notification.collection.NotificationEntry; +import com.android.systemui.statusbar.notification.collection.render.ShadeViewManager; import com.android.systemui.statusbar.notification.row.ActivatableNotificationView; import com.android.systemui.statusbar.notification.row.ExpandableNotificationRow; import com.android.systemui.statusbar.notification.row.ExpandableView; @@ -120,7 +121,6 @@ import com.android.systemui.statusbar.policy.ConfigurationController; import com.android.systemui.statusbar.policy.KeyguardStateController; import com.android.systemui.statusbar.policy.KeyguardUserSwitcher; import com.android.systemui.statusbar.policy.OnHeadsUpChangedListener; -import com.android.systemui.statusbar.policy.ZenModeController; import com.android.systemui.util.InjectionInflationController; import java.io.FileDescriptor; @@ -168,9 +168,6 @@ public class NotificationPanelViewController extends PanelViewController { mOnHeadsUpChangedListener = new MyOnHeadsUpChangedListener(); private final HeightListener mHeightListener = new HeightListener(); - private final ZenModeControllerCallback - mZenModeControllerCallback = - new ZenModeControllerCallback(); private final ConfigurationListener mConfigurationListener = new ConfigurationListener(); private final StatusBarStateListener mStatusBarStateListener = new StatusBarStateListener(); private final ExpansionCallback mExpansionCallback = new ExpansionCallback(); @@ -178,7 +175,6 @@ public class NotificationPanelViewController extends PanelViewController { private final NotificationPanelView mView; private final MetricsLogger mMetricsLogger; private final ActivityManager mActivityManager; - private final ZenModeController mZenModeController; private final ConfigurationController mConfigurationController; private final FlingAnimationUtils.Builder mFlingAnimationUtilsBuilder; private final NotificationStackScrollLayoutController mNotificationStackScrollLayoutController; @@ -342,8 +338,6 @@ public class NotificationPanelViewController extends PanelViewController { private boolean mKeyguardStatusViewAnimating; private ValueAnimator mQsSizeChangeAnimator; - private boolean mShowEmptyShadeView; - private boolean mQsScrimEnabled = true; private boolean mQsTouchAboveFalsingThreshold; private int mQsFalsingThreshold; @@ -505,7 +499,7 @@ public class NotificationPanelViewController extends PanelViewController { LatencyTracker latencyTracker, PowerManager powerManager, AccessibilityManager accessibilityManager, @DisplayId int displayId, KeyguardUpdateMonitor keyguardUpdateMonitor, MetricsLogger metricsLogger, - ActivityManager activityManager, ZenModeController zenModeController, + ActivityManager activityManager, ConfigurationController configurationController, FlingAnimationUtils.Builder flingAnimationUtilsBuilder, StatusBarTouchableRegionManager statusBarTouchableRegionManager, @@ -522,7 +516,6 @@ public class NotificationPanelViewController extends PanelViewController { mView = view; mMetricsLogger = metricsLogger; mActivityManager = activityManager; - mZenModeController = zenModeController; mConfigurationController = configurationController; mFlingAnimationUtilsBuilder = flingAnimationUtilsBuilder; mMediaHierarchyManager = mediaHierarchyManager; @@ -724,8 +717,6 @@ public class NotificationPanelViewController extends PanelViewController { } private void reInflateViews() { - updateShowEmptyShadeView(); - // Re-inflate the status view group. int index = mView.indexOfChild(mKeyguardStatusView); mView.removeView(mKeyguardStatusView); @@ -1727,7 +1718,6 @@ public class NotificationPanelViewController extends PanelViewController { mNotificationStackScrollLayoutController.setScrollingEnabled( mBarState != KEYGUARD && (!mQsExpanded || mQsExpansionFromOverscroll)); - updateEmptyShadeView(); mQsNavbarScrim.setVisibility( mBarState == StatusBarState.SHADE && mQsExpanded && !mStackScrollerOverscrolling @@ -2145,7 +2135,7 @@ public class NotificationPanelViewController extends PanelViewController { // it in expanded QS state as well so we don't run into troubles when fading the view in/out // and expanding/collapsing the whole panel from/to quick settings. if (mNotificationStackScrollLayoutController.getNotGoneChildCount() == 0 - && mShowEmptyShadeView) { + && mNotificationStackScrollLayoutController.isShowingEmptyShadeView()) { notificationHeight = mNotificationStackScrollLayoutController.getEmptyShadeViewHeight(); } int maxQsHeight = mQsMaxExpansionHeight; @@ -2561,17 +2551,6 @@ public class NotificationPanelViewController extends PanelViewController { return mDozing; } - public void showEmptyShadeView(boolean emptyShadeViewVisible) { - mShowEmptyShadeView = emptyShadeViewVisible; - updateEmptyShadeView(); - } - - private void updateEmptyShadeView() { - // Hide "No notifications" in QS. - mNotificationStackScrollLayoutController.updateEmptyShadeView( - mShowEmptyShadeView && !mQsExpanded); - } - public void setQsScrimEnabled(boolean qsScrimEnabled) { boolean changed = mQsScrimEnabled != qsScrimEnabled; mQsScrimEnabled = qsScrimEnabled; @@ -3078,22 +3057,21 @@ public class NotificationPanelViewController extends PanelViewController { return mNotificationStackScrollLayoutController.hasActiveClearableNotifications(ROWS_ALL); } - private void updateShowEmptyShadeView() { - boolean - showEmptyShadeView = - mBarState != KEYGUARD && !mEntryManager.hasActiveNotifications(); - showEmptyShadeView(showEmptyShadeView); - } - public RemoteInputController.Delegate createRemoteInputDelegate() { return mNotificationStackScrollLayoutController.createDelegate(); } - void updateNotificationViews(String reason) { + /** + * Updates the notification views' sections and status bar icons. This is + * triggered by the NotificationPresenter whenever there are changes to the underlying + * notification data being displayed. In the new notification pipeline, this is handled in + * {@link ShadeViewManager}. + */ + public void updateNotificationViews(String reason) { mNotificationStackScrollLayoutController.updateSectionBoundaries(reason); mNotificationStackScrollLayoutController.updateSpeedBumpIndex(); mNotificationStackScrollLayoutController.updateFooter(); - updateShowEmptyShadeView(); + mNotificationIconAreaController.updateNotificationIcons(createVisibleEntriesList()); } @@ -3147,7 +3125,6 @@ public class NotificationPanelViewController extends PanelViewController { mNotificationStackScrollLayoutController.setStatusBar(statusBar); mNotificationStackScrollLayoutController.setGroupManager(groupManager); mNotificationStackScrollLayoutController.setShelfController(notificationShelfController); - updateShowEmptyShadeView(); mNotificationShelfController = notificationShelfController; updateMaxDisplayedNotifications(true); } @@ -3602,20 +3579,8 @@ public class NotificationPanelViewController extends PanelViewController { } } - private class ZenModeControllerCallback implements ZenModeController.Callback { - @Override - public void onZenChanged(int zen) { - updateShowEmptyShadeView(); - } - } - private class ConfigurationListener implements ConfigurationController.ConfigurationListener { @Override - public void onDensityOrFontScaleChanged() { - updateShowEmptyShadeView(); - } - - @Override public void onThemeChanged() { final int themeResId = mView.getContext().getThemeResId(); if (mThemeResId == themeResId) { @@ -3712,7 +3677,6 @@ public class NotificationPanelViewController extends PanelViewController { public void onViewAttachedToWindow(View v) { FragmentHostManager.get(mView).addTagListener(QS.TAG, mFragmentListener); mStatusBarStateController.addCallback(mStatusBarStateListener); - mZenModeController.addCallback(mZenModeControllerCallback); mConfigurationController.addCallback(mConfigurationListener); mUpdateMonitor.registerCallback(mKeyguardUpdateCallback); // Theme might have changed between inflating this view and attaching it to the @@ -3725,7 +3689,6 @@ public class NotificationPanelViewController extends PanelViewController { public void onViewDetachedFromWindow(View v) { FragmentHostManager.get(mView).removeTagListener(QS.TAG, mFragmentListener); mStatusBarStateController.removeCallback(mStatusBarStateListener); - mZenModeController.removeCallback(mZenModeControllerCallback); mConfigurationController.removeCallback(mConfigurationListener); mUpdateMonitor.removeCallback(mKeyguardUpdateCallback); } diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/DeviceProvisionedControllerImpl.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/DeviceProvisionedControllerImpl.java index 9b4e16525df2..485b1b109eb4 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/DeviceProvisionedControllerImpl.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/DeviceProvisionedControllerImpl.java @@ -15,8 +15,6 @@ package com.android.systemui.statusbar.policy; import android.app.ActivityManager; -import android.content.ContentResolver; -import android.content.Context; import android.database.ContentObserver; import android.net.Uri; import android.os.Handler; @@ -30,6 +28,8 @@ import com.android.systemui.broadcast.BroadcastDispatcher; import com.android.systemui.dagger.SysUISingleton; import com.android.systemui.dagger.qualifiers.Main; import com.android.systemui.settings.CurrentUserTracker; +import com.android.systemui.util.settings.GlobalSettings; +import com.android.systemui.util.settings.SecureSettings; import java.util.ArrayList; @@ -43,8 +43,8 @@ public class DeviceProvisionedControllerImpl extends CurrentUserTracker implemen protected static final String TAG = DeviceProvisionedControllerImpl.class.getSimpleName(); protected final ArrayList<DeviceProvisionedListener> mListeners = new ArrayList<>(); - private final ContentResolver mContentResolver; - private final Context mContext; + private final GlobalSettings mGlobalSettings; + private final SecureSettings mSecureSettings; private final Uri mDeviceProvisionedUri; private final Uri mUserSetupUri; protected final ContentObserver mSettingsObserver; @@ -52,13 +52,14 @@ public class DeviceProvisionedControllerImpl extends CurrentUserTracker implemen /** */ @Inject - public DeviceProvisionedControllerImpl(Context context, @Main Handler mainHandler, - BroadcastDispatcher broadcastDispatcher) { + public DeviceProvisionedControllerImpl(@Main Handler mainHandler, + BroadcastDispatcher broadcastDispatcher, GlobalSettings globalSettings, + SecureSettings secureSettings) { super(broadcastDispatcher); - mContext = context; - mContentResolver = context.getContentResolver(); - mDeviceProvisionedUri = Global.getUriFor(Global.DEVICE_PROVISIONED); - mUserSetupUri = Secure.getUriFor(Secure.USER_SETUP_COMPLETE); + mGlobalSettings = globalSettings; + mSecureSettings = secureSettings; + mDeviceProvisionedUri = mGlobalSettings.getUriFor(Global.DEVICE_PROVISIONED); + mUserSetupUri = mSecureSettings.getUriFor(Secure.USER_SETUP_COMPLETE); mSettingsObserver = new ContentObserver(mainHandler) { @Override public void onChange(boolean selfChange, Uri uri, int flags) { @@ -74,13 +75,12 @@ public class DeviceProvisionedControllerImpl extends CurrentUserTracker implemen @Override public boolean isDeviceProvisioned() { - return Global.getInt(mContentResolver, Global.DEVICE_PROVISIONED, 0) != 0; + return mGlobalSettings.getInt(Global.DEVICE_PROVISIONED, 0) != 0; } @Override public boolean isUserSetup(int currentUser) { - return Secure.getIntForUser(mContentResolver, Secure.USER_SETUP_COMPLETE, 0, currentUser) - != 0; + return mSecureSettings.getIntForUser(Secure.USER_SETUP_COMPLETE, 0, currentUser) != 0; } @Override @@ -107,24 +107,24 @@ public class DeviceProvisionedControllerImpl extends CurrentUserTracker implemen } protected void startListening(int user) { - mContentResolver.registerContentObserver(mDeviceProvisionedUri, true, + mGlobalSettings.registerContentObserverForUser(mDeviceProvisionedUri, true, mSettingsObserver, 0); - mContentResolver.registerContentObserver(mUserSetupUri, true, + mSecureSettings.registerContentObserverForUser(mUserSetupUri, true, mSettingsObserver, user); startTracking(); } protected void stopListening() { stopTracking(); - mContentResolver.unregisterContentObserver(mSettingsObserver); + mGlobalSettings.unregisterContentObserver(mSettingsObserver); } @Override public void onUserSwitched(int newUserId) { - mContentResolver.unregisterContentObserver(mSettingsObserver); - mContentResolver.registerContentObserver(mDeviceProvisionedUri, true, + mGlobalSettings.unregisterContentObserver(mSettingsObserver); + mGlobalSettings.registerContentObserverForUser(mDeviceProvisionedUri, true, mSettingsObserver, 0); - mContentResolver.registerContentObserver(mUserSetupUri, true, + mSecureSettings.registerContentObserverForUser(mUserSetupUri, true, mSettingsObserver, newUserId); notifyUserChanged(); } diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/UserSwitcherController.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/UserSwitcherController.java index f9ac760a3367..17fcb1dd6f1a 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/UserSwitcherController.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/UserSwitcherController.java @@ -206,7 +206,7 @@ public class UserSwitcherController implements Dumpable { @Override protected ArrayList<UserRecord> doInBackground(SparseArray<Bitmap>... params) { final SparseArray<Bitmap> bitmaps = params[0]; - List<UserInfo> infos = mUserManager.getUsers(true); + List<UserInfo> infos = mUserManager.getAliveUsers(); if (infos == null) { return null; } diff --git a/packages/SystemUI/src/com/android/systemui/util/concurrency/GlobalConcurrencyModule.java b/packages/SystemUI/src/com/android/systemui/util/concurrency/GlobalConcurrencyModule.java new file mode 100644 index 000000000000..5946af383b0f --- /dev/null +++ b/packages/SystemUI/src/com/android/systemui/util/concurrency/GlobalConcurrencyModule.java @@ -0,0 +1,70 @@ +/* + * Copyright (C) 2019 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.systemui.util.concurrency; + +import android.content.Context; +import android.os.Handler; +import android.os.Looper; + +import com.android.systemui.dagger.qualifiers.Main; + +import java.util.concurrent.Executor; + +import dagger.Binds; +import dagger.Module; +import dagger.Provides; + +/** + * Dagger Module for classes found within the concurrent package. + */ +@Module +public abstract class GlobalConcurrencyModule { + + /** + * Binds {@link ThreadFactoryImpl} to {@link ThreadFactory}. + */ + @Binds + public abstract ThreadFactory bindExecutorFactory(ThreadFactoryImpl impl); + + /** Main Looper */ + @Provides + @Main + public static Looper provideMainLooper() { + return Looper.getMainLooper(); + } + + /** + * Main Handler. + * + * Prefer the Main Executor when possible. + */ + @Provides + @Main + public static Handler provideMainHandler(@Main Looper mainLooper) { + return new Handler(mainLooper); + } + + /** + * Provide a Main-Thread Executor. + */ + @Provides + @Main + public static Executor provideMainExecutor(Context context) { + return context.getMainExecutor(); + } + +} diff --git a/packages/SystemUI/src/com/android/systemui/util/concurrency/ConcurrencyModule.java b/packages/SystemUI/src/com/android/systemui/util/concurrency/SysUIConcurrencyModule.java index 628c808aa12b..b9b20c73c5d5 100644 --- a/packages/SystemUI/src/com/android/systemui/util/concurrency/ConcurrencyModule.java +++ b/packages/SystemUI/src/com/android/systemui/util/concurrency/SysUIConcurrencyModule.java @@ -16,7 +16,6 @@ package com.android.systemui.util.concurrency; -import android.content.Context; import android.os.Handler; import android.os.HandlerThread; import android.os.Looper; @@ -31,7 +30,6 @@ import com.android.systemui.dagger.qualifiers.UiBackground; import java.util.concurrent.Executor; import java.util.concurrent.Executors; -import dagger.Binds; import dagger.Module; import dagger.Provides; @@ -39,7 +37,7 @@ import dagger.Provides; * Dagger Module for classes found within the concurrent package. */ @Module -public abstract class ConcurrencyModule { +public abstract class SysUIConcurrencyModule { /** Background Looper */ @Provides @SysUISingleton @@ -62,13 +60,6 @@ public abstract class ConcurrencyModule { return thread.getLooper(); } - /** Main Looper */ - @Provides - @Main - public static Looper provideMainLooper() { - return Looper.getMainLooper(); - } - /** * Background Handler. * @@ -81,17 +72,6 @@ public abstract class ConcurrencyModule { } /** - * Main Handler. - * - * Prefer the Main Executor when possible. - */ - @Provides - @Main - public static Handler provideMainHandler(@Main Looper mainLooper) { - return new Handler(mainLooper); - } - - /** * Provide a Background-Thread Executor by default. */ @Provides @@ -121,15 +101,6 @@ public abstract class ConcurrencyModule { } /** - * Provide a Main-Thread Executor. - */ - @Provides - @Main - public static Executor provideMainExecutor(Context context) { - return context.getMainExecutor(); - } - - /** * Provide a Background-Thread Executor by default. */ @Provides @@ -199,10 +170,4 @@ public abstract class ConcurrencyModule { public static Executor provideUiBackgroundExecutor() { return Executors.newSingleThreadExecutor(); } - - /** - * Binds {@link ThreadFactoryImpl} to {@link ThreadFactory}. - */ - @Binds - public abstract ThreadFactory bindExecutorFactory(ThreadFactoryImpl impl); } diff --git a/packages/SystemUI/src/com/android/systemui/util/settings/SettingsProxy.java b/packages/SystemUI/src/com/android/systemui/util/settings/SettingsProxy.java index 5c37f797b678..5aaf7f680d5c 100644 --- a/packages/SystemUI/src/com/android/systemui/util/settings/SettingsProxy.java +++ b/packages/SystemUI/src/com/android/systemui/util/settings/SettingsProxy.java @@ -67,7 +67,35 @@ public interface SettingsProxy { * Implicitly calls {@link #getUriFor(String)} on the passed in name. */ default void registerContentObserver(String name, ContentObserver settingsObserver) { - registerContentObserverForUser(name, settingsObserver, getUserId()); + registerContentObserver(getUriFor(name), settingsObserver); + } + + /** + * Convenience wrapper around + * {@link ContentResolver#registerContentObserver(Uri, boolean, ContentObserver)}.' + */ + default void registerContentObserver(Uri uri, ContentObserver settingsObserver) { + registerContentObserverForUser(uri, settingsObserver, getUserId()); + } + + /** + * Convenience wrapper around + * {@link ContentResolver#registerContentObserver(Uri, boolean, ContentObserver)}.' + * + * Implicitly calls {@link #getUriFor(String)} on the passed in name. + */ + default void registerContentObserver(String name, boolean notifyForDescendents, + ContentObserver settingsObserver) { + registerContentObserver(getUriFor(name), notifyForDescendents, settingsObserver); + } + + /** + * Convenience wrapper around + * {@link ContentResolver#registerContentObserver(Uri, boolean, ContentObserver)}.' + */ + default void registerContentObserver(Uri uri, boolean notifyForDescendents, + ContentObserver settingsObserver) { + registerContentObserverForUser(uri, notifyForDescendents, settingsObserver, getUserId()); } /** @@ -78,8 +106,42 @@ public interface SettingsProxy { */ default void registerContentObserverForUser( String name, ContentObserver settingsObserver, int userHandle) { + registerContentObserverForUser( + getUriFor(name), settingsObserver, userHandle); + } + + /** + * Convenience wrapper around + * {@link ContentResolver#registerContentObserver(Uri, boolean, ContentObserver, int)} + */ + default void registerContentObserverForUser( + Uri uri, ContentObserver settingsObserver, int userHandle) { + registerContentObserverForUser( + uri, false, settingsObserver, userHandle); + } + + /** + * Convenience wrapper around + * {@link ContentResolver#registerContentObserver(Uri, boolean, ContentObserver, int)} + * + * Implicitly calls {@link #getUriFor(String)} on the passed in name. + */ + default void registerContentObserverForUser( + String name, boolean notifyForDescendents, ContentObserver settingsObserver, + int userHandle) { + registerContentObserverForUser( + getUriFor(name), notifyForDescendents, settingsObserver, userHandle); + } + + /** + * Convenience wrapper around + * {@link ContentResolver#registerContentObserver(Uri, boolean, ContentObserver, int)} + */ + default void registerContentObserverForUser( + Uri uri, boolean notifyForDescendents, ContentObserver settingsObserver, + int userHandle) { getContentResolver().registerContentObserver( - getUriFor(name), false, settingsObserver, userHandle); + uri, notifyForDescendents, settingsObserver, userHandle); } /** See {@link ContentResolver#unregisterContentObserver(ContentObserver)}. */ diff --git a/packages/SystemUI/src/com/android/systemui/volume/VolumeDialogImpl.java b/packages/SystemUI/src/com/android/systemui/volume/VolumeDialogImpl.java index 51ad30ebcac6..78f83d3c09b4 100644 --- a/packages/SystemUI/src/com/android/systemui/volume/VolumeDialogImpl.java +++ b/packages/SystemUI/src/com/android/systemui/volume/VolumeDialogImpl.java @@ -49,6 +49,7 @@ import android.content.res.Resources; import android.content.res.TypedArray; import android.graphics.Color; import android.graphics.PixelFormat; +import android.graphics.Region; import android.graphics.drawable.ColorDrawable; import android.media.AudioManager; import android.media.AudioSystem; @@ -71,6 +72,7 @@ import android.view.View.AccessibilityDelegate; import android.view.ViewGroup; import android.view.ViewPropertyAnimator; import android.view.ViewStub; +import android.view.ViewTreeObserver; import android.view.Window; import android.view.WindowManager; import android.view.accessibility.AccessibilityEvent; @@ -109,7 +111,8 @@ import java.util.List; * Methods ending in "H" must be called on the (ui) handler. */ public class VolumeDialogImpl implements VolumeDialog, - ConfigurationController.ConfigurationListener { + ConfigurationController.ConfigurationListener, + ViewTreeObserver.OnComputeInternalInsetsListener { private static final String TAG = Util.logTag(VolumeDialogImpl.class); private static final long USER_ATTEMPT_GRACE_PERIOD = 1000; @@ -126,6 +129,7 @@ public class VolumeDialogImpl implements VolumeDialog, private final H mHandler = new H(); private final VolumeDialogController mController; private final DeviceProvisionedController mDeviceProvisionedController; + private final Region mTouchableRegion = new Region(); private Window mWindow; private CustomDialog mDialog; @@ -204,6 +208,33 @@ public class VolumeDialogImpl implements VolumeDialog, Dependency.get(ConfigurationController.class).removeCallback(this); } + @Override + public void onComputeInternalInsets(ViewTreeObserver.InternalInsetsInfo internalInsetsInfo) { + // Set touchable region insets on the root dialog view. This tells WindowManager that + // touches outside of this region should not be delivered to the volume window, and instead + // go to the window below. This is the only way to do this - returning false in + // onDispatchTouchEvent results in the event being ignored entirely, rather than passed to + // the next window. + internalInsetsInfo.setTouchableInsets( + ViewTreeObserver.InternalInsetsInfo.TOUCHABLE_INSETS_REGION); + + mTouchableRegion.setEmpty(); + + // Set the touchable region to the union of all child view bounds. We don't use touches on + // the volume dialog container itself, so this is fine. + for (int i = 0; i < mDialogView.getChildCount(); i++) { + final View view = mDialogView.getChildAt(i); + mTouchableRegion.op( + view.getLeft(), + view.getTop(), + view.getRight(), + view.getBottom(), + Region.Op.UNION); + } + + internalInsetsInfo.touchableRegion.set(mTouchableRegion); + } + private void initDialog() { mDialog = new CustomDialog(mContext); @@ -235,6 +266,7 @@ public class VolumeDialogImpl implements VolumeDialog, mDialogView.setAlpha(0); mDialog.setCanceledOnTouchOutside(true); mDialog.setOnShowListener(dialog -> { + mDialogView.getViewTreeObserver().addOnComputeInternalInsetsListener(this); if (!isLandscape()) mDialogView.setTranslationX(mDialogView.getWidth() / 2.0f); mDialogView.setAlpha(0); mDialogView.animate() @@ -253,6 +285,11 @@ public class VolumeDialogImpl implements VolumeDialog, .start(); }); + mDialog.setOnDismissListener(dialogInterface -> + mDialogView + .getViewTreeObserver() + .removeOnComputeInternalInsetsListener(VolumeDialogImpl.this)); + mDialogView.setOnHoverListener((v, event) -> { int action = event.getActionMasked(); mHovering = (action == MotionEvent.ACTION_HOVER_ENTER) @@ -1369,6 +1406,11 @@ public class VolumeDialogImpl implements VolumeDialog, super(context, R.style.volume_dialog_theme); } + /** + * NOTE: This will only be called for touches within the touchable region of the volume + * dialog, as returned by {@link #onComputeInternalInsets}. Other touches, even if they are + * within the bounds of the volume dialog, will fall through to the window below. + */ @Override public boolean dispatchTouchEvent(MotionEvent ev) { rescheduleTimeoutH(); @@ -1387,6 +1429,12 @@ public class VolumeDialogImpl implements VolumeDialog, mHandler.sendEmptyMessage(H.RECHECK_ALL); } + /** + * NOTE: This will be called with ACTION_OUTSIDE MotionEvents for touches that occur outside + * of the touchable region of the volume dialog (as returned by + * {@link #onComputeInternalInsets}) even if those touches occurred within the bounds of the + * volume dialog. + */ @Override public boolean onTouchEvent(MotionEvent event) { if (mShowing) { diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayoutTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayoutTest.java index 62b741c1938a..1431bcef8514 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayoutTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayoutTest.java @@ -47,9 +47,6 @@ import com.android.internal.statusbar.IStatusBarService; import com.android.systemui.ExpandHelper; import com.android.systemui.R; import com.android.systemui.SysuiTestCase; -import com.android.systemui.classifier.FalsingManagerFake; -import com.android.systemui.plugins.statusbar.NotificationMenuRowPlugin; -import com.android.systemui.plugins.statusbar.StatusBarStateController; import com.android.systemui.statusbar.EmptyShadeView; import com.android.systemui.statusbar.FeatureFlags; import com.android.systemui.statusbar.NotificationMediaManager; @@ -81,7 +78,6 @@ import com.android.systemui.statusbar.notification.row.NotificationBlockingHelpe import com.android.systemui.statusbar.notification.stack.NotificationStackScrollLayout.KeyguardBypassEnabledProvider; import com.android.systemui.statusbar.phone.HeadsUpManagerPhone; import com.android.systemui.statusbar.phone.NotificationGroupManager; -import com.android.systemui.statusbar.phone.NotificationIconAreaController; import com.android.systemui.statusbar.phone.ShadeController; import com.android.systemui.statusbar.phone.StatusBar; import com.android.systemui.util.leak.LeakDetector; @@ -128,6 +124,7 @@ public class NotificationStackScrollLayoutTest extends SysuiTestCase { @Mock private FeatureFlags mFeatureFlags; @Mock private SysuiStatusBarStateController mStatusBarStateController; @Mock private NotificationSwipeHelper mNotificationSwipeHelper; + @Mock NotificationStackScrollLayoutController mStackScrollLayoutController; private NotificationEntryManager mEntryManager; private int mOriginalInterruptionModelSetting; private UiEventLoggerFake mUiEventLoggerFake = new UiEventLoggerFake(); @@ -216,6 +213,9 @@ public class NotificationStackScrollLayoutTest extends SysuiTestCase { mStackScroller.setStatusBar(mBar); mStackScroller.setGroupManager(mGroupManager); mStackScroller.setEmptyShadeView(mEmptyShadeView); + when(mStackScrollLayoutController.getNoticationRoundessManager()) + .thenReturn(mock(NotificationRoundnessManager.class)); + mStackScroller.setController(mStackScrollLayoutController); // Stub out functionality that isn't necessary to test. doNothing().when(mBar) diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollerControllerTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollerControllerTest.java index f5d9fa07fa1c..08dd7d2cd635 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollerControllerTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollerControllerTest.java @@ -16,6 +16,9 @@ package com.android.systemui.statusbar.notification.stack; +import static com.android.systemui.statusbar.StatusBarState.KEYGUARD; +import static com.android.systemui.statusbar.StatusBarState.SHADE; + import static org.mockito.ArgumentMatchers.any; import static org.mockito.ArgumentMatchers.anyInt; import static org.mockito.ArgumentMatchers.argThat; @@ -49,7 +52,6 @@ import com.android.systemui.statusbar.notification.row.ExpandableNotificationRow import com.android.systemui.statusbar.notification.row.NotificationGutsManager; import com.android.systemui.statusbar.phone.HeadsUpManagerPhone; import com.android.systemui.statusbar.phone.KeyguardBypassController; -import com.android.systemui.statusbar.phone.LockscreenGestureLogger; import com.android.systemui.statusbar.phone.ScrimController; import com.android.systemui.statusbar.phone.StatusBar; import com.android.systemui.statusbar.policy.ConfigurationController; @@ -62,6 +64,7 @@ import org.junit.runner.RunWith; import org.mockito.Answers; import org.mockito.ArgumentCaptor; import org.mockito.ArgumentMatcher; +import org.mockito.Captor; import org.mockito.Mock; import org.mockito.MockitoAnnotations; @@ -115,6 +118,9 @@ public class NotificationStackScrollerControllerTest extends SysuiTestCase { @Mock private ScrimController mScrimController; + @Captor + ArgumentCaptor<StatusBarStateController.StateListener> mStateListenerArgumentCaptor; + private NotificationStackScrollLayoutController mController; @Before @@ -181,32 +187,49 @@ public class NotificationStackScrollerControllerTest extends SysuiTestCase { } @Test - public void testUpdateEmptyShadeView_notificationsVisible() { + public void testUpdateEmptyShadeView_notificationsVisible_zenHiding() { when(mZenModeController.areNotificationsHiddenInShade()).thenReturn(true); mController.attach(mNotificationStackScrollLayout); + verify(mSysuiStatusBarStateController).addCallback( + mStateListenerArgumentCaptor.capture(), anyInt()); + StatusBarStateController.StateListener stateListener = + mStateListenerArgumentCaptor.getValue(); - mController.updateEmptyShadeView(true /* visible */); + setupShowEmptyShadeViewState(stateListener, true); + reset(mNotificationStackScrollLayout); + mController.updateShowEmptyShadeView(); verify(mNotificationStackScrollLayout).updateEmptyShadeView( true /* visible */, + true /* notifVisibleInShade */); + + setupShowEmptyShadeViewState(stateListener, false); reset(mNotificationStackScrollLayout); - mController.updateEmptyShadeView(false /* visible */); + mController.updateShowEmptyShadeView(); verify(mNotificationStackScrollLayout).updateEmptyShadeView( false /* visible */, true /* notifVisibleInShade */); } @Test - public void testUpdateEmptyShadeView_notificationsHidden() { + public void testUpdateEmptyShadeView_notificationsHidden_zenNotHiding() { when(mZenModeController.areNotificationsHiddenInShade()).thenReturn(false); mController.attach(mNotificationStackScrollLayout); + verify(mSysuiStatusBarStateController).addCallback( + mStateListenerArgumentCaptor.capture(), anyInt()); + StatusBarStateController.StateListener stateListener = + mStateListenerArgumentCaptor.getValue(); - mController.updateEmptyShadeView(true /* visible */); + setupShowEmptyShadeViewState(stateListener, true); + reset(mNotificationStackScrollLayout); + mController.updateShowEmptyShadeView(); verify(mNotificationStackScrollLayout).updateEmptyShadeView( true /* visible */, false /* notifVisibleInShade */); + + setupShowEmptyShadeViewState(stateListener, false); reset(mNotificationStackScrollLayout); - mController.updateEmptyShadeView(false /* visible */); + mController.updateShowEmptyShadeView(); verify(mNotificationStackScrollLayout).updateEmptyShadeView( false /* visible */, false /* notifVisibleInShade */); @@ -234,15 +257,12 @@ public class NotificationStackScrollerControllerTest extends SysuiTestCase { public void testOnStatePostChange_verifyIfProfileIsPublic() { when(mNotificationLockscreenUserManager.isAnyProfilePublicMode()).thenReturn(true); - ArgumentCaptor<StatusBarStateController.StateListener> stateListenerArgumentCaptor = - ArgumentCaptor.forClass(StatusBarStateController.StateListener.class); - mController.attach(mNotificationStackScrollLayout); verify(mSysuiStatusBarStateController).addCallback( - stateListenerArgumentCaptor.capture(), anyInt()); + mStateListenerArgumentCaptor.capture(), anyInt()); StatusBarStateController.StateListener stateListener = - stateListenerArgumentCaptor.getValue(); + mStateListenerArgumentCaptor.getValue(); stateListener.onStatePostChange(); verify(mNotificationStackScrollLayout).updateSensitiveness(false, true); @@ -299,6 +319,20 @@ public class NotificationStackScrollerControllerTest extends SysuiTestCase { return argThat(new LogMatcher(category, type)); } + private void setupShowEmptyShadeViewState( + StatusBarStateController.StateListener statusBarStateListener, + boolean toShow) { + if (toShow) { + statusBarStateListener.onStateChanged(SHADE); + mController.setQsExpanded(false); + mController.getView().removeAllViews(); + } else { + statusBarStateListener.onStateChanged(KEYGUARD); + mController.setQsExpanded(true); + mController.getView().addContainerView(mock(ExpandableNotificationRow.class)); + } + } + static class LogMatcher implements ArgumentMatcher<LogMaker> { private int mCategory, mType; diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/NotificationPanelViewTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/NotificationPanelViewTest.java index 453baa5e16fd..4413ff3d9579 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/NotificationPanelViewTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/NotificationPanelViewTest.java @@ -79,7 +79,6 @@ import com.android.systemui.statusbar.notification.stack.NotificationStackScroll import com.android.systemui.statusbar.notification.stack.NotificationStackScrollLayoutController; import com.android.systemui.statusbar.policy.ConfigurationController; import com.android.systemui.statusbar.policy.KeyguardStateController; -import com.android.systemui.statusbar.policy.ZenModeController; import com.android.systemui.util.InjectionInflationController; import org.junit.Before; @@ -174,8 +173,6 @@ public class NotificationPanelViewTest extends SysuiTestCase { private KeyguardClockSwitch mKeyguardClockSwitch; private PanelViewController.TouchHandler mTouchHandler; @Mock - private ZenModeController mZenModeController; - @Mock private ConfigurationController mConfigurationController; @Mock private MediaHierarchyManager mMediaHiearchyManager; @@ -259,7 +256,7 @@ public class NotificationPanelViewTest extends SysuiTestCase { mKeyguardStateController, mStatusBarStateController, mDozeLog, mDozeParameters, mCommandQueue, mVibratorHelper, mLatencyTracker, mPowerManager, mAccessibilityManager, 0, mUpdateMonitor, - mMetricsLogger, mActivityManager, mZenModeController, mConfigurationController, + mMetricsLogger, mActivityManager, mConfigurationController, flingAnimationUtilsBuilder, mStatusBarTouchableRegionManager, mConversationNotificationManager, mMediaHiearchyManager, mBiometricUnlockController, mStatusBarKeyguardViewManager, diff --git a/services/accessibility/java/com/android/server/accessibility/gestures/MultiFingerSwipe.java b/services/accessibility/java/com/android/server/accessibility/gestures/MultiFingerSwipe.java index 07e82111d4e5..5b46cb4ab378 100644 --- a/services/accessibility/java/com/android/server/accessibility/gestures/MultiFingerSwipe.java +++ b/services/accessibility/java/com/android/server/accessibility/gestures/MultiFingerSwipe.java @@ -294,7 +294,7 @@ class MultiFingerSwipe extends GestureMatcher { + Float.toString(mGestureDetectionThresholdPixels)); } if (getState() == STATE_CLEAR) { - if (moveDelta < mTouchSlop) { + if (moveDelta < (mTargetFingerCount * mTouchSlop)) { // This still counts as a touch not a swipe. continue; } else if (mStrokeBuffers[pointerIndex].size() == 0) { diff --git a/services/accessibility/java/com/android/server/accessibility/gestures/TouchExplorer.java b/services/accessibility/java/com/android/server/accessibility/gestures/TouchExplorer.java index e9c6882afdd8..8305be393ab1 100644 --- a/services/accessibility/java/com/android/server/accessibility/gestures/TouchExplorer.java +++ b/services/accessibility/java/com/android/server/accessibility/gestures/TouchExplorer.java @@ -608,7 +608,7 @@ public class TouchExplorer extends BaseEventStreamTransformation mReceivedPointerTracker.getReceivedPointerDownY(id) - rawEvent.getY(index); final double moveDelta = Math.hypot(deltaX, deltaY); - if (moveDelta < mTouchSlop) { + if (moveDelta < (2 * mTouchSlop)) { return; } } diff --git a/services/companion/TEST_MAPPING b/services/companion/TEST_MAPPING new file mode 100644 index 000000000000..63f54fa35158 --- /dev/null +++ b/services/companion/TEST_MAPPING @@ -0,0 +1,12 @@ +{ + "presubmit": [ + { + "name": "CtsOsTestCases", + "options": [ + { + "include-filter": "android.os.cts.CompanionDeviceManagerTest" + } + ] + } + ] +} diff --git a/services/core/java/com/android/server/accounts/AccountManagerService.java b/services/core/java/com/android/server/accounts/AccountManagerService.java index 35e88eb804cb..7d81d412e369 100644 --- a/services/core/java/com/android/server/accounts/AccountManagerService.java +++ b/services/core/java/com/android/server/accounts/AccountManagerService.java @@ -2114,7 +2114,7 @@ public class AccountManagerService * Owner or system user account was renamed, rename the account for * those users with which the account was shared. */ - List<UserInfo> users = getUserManager().getUsers(true); + List<UserInfo> users = getUserManager().getAliveUsers(); for (UserInfo user : users) { if (user.isRestricted() && (user.restrictedProfileParentId == parentUserId)) { @@ -2373,7 +2373,7 @@ public class AccountManagerService int parentUserId = accounts.userId; if (canHaveProfile(parentUserId)) { // Remove from any restricted profiles that are sharing this account. - List<UserInfo> users = getUserManager().getUsers(true); + List<UserInfo> users = getUserManager().getAliveUsers(); for (UserInfo user : users) { if (user.isRestricted() && parentUserId == (user.restrictedProfileParentId)) { removeSharedAccountAsUser(account, user.id, callingUid); @@ -4267,7 +4267,7 @@ public class AccountManagerService */ @NonNull public AccountAndUser[] getAllAccounts() { - final List<UserInfo> users = getUserManager().getUsers(true); + final List<UserInfo> users = getUserManager().getAliveUsers(); final int[] userIds = new int[users.size()]; for (int i = 0; i < userIds.length; i++) { userIds[i] = users.get(i).id; diff --git a/services/core/java/com/android/server/audio/AudioService.java b/services/core/java/com/android/server/audio/AudioService.java index d59780d7f609..3f29eb5636ea 100755 --- a/services/core/java/com/android/server/audio/AudioService.java +++ b/services/core/java/com/android/server/audio/AudioService.java @@ -6528,8 +6528,8 @@ public class AudioService extends IAudioService.Stub CHECK_MODE_FOR_UID_PERIOD_MS); break; } - // For now just log the fact that an app is hogging the audio mode. - // TODO(b/160260850): remove abusive app from audio mode stack. + setModeInt(AudioSystem.MODE_NORMAL, h.getBinder(), h.getPid(), h.getUid(), + h.isPrivileged(), "MSG_CHECK_MODE_FOR_UID"); mModeLogger.log(new PhoneStateEvent(h.getPackage(), h.getPid())); } break; diff --git a/services/core/java/com/android/server/biometrics/sensors/face/Face10.java b/services/core/java/com/android/server/biometrics/sensors/face/Face10.java index 32bb2db77ddc..d9c62df3f3ea 100644 --- a/services/core/java/com/android/server/biometrics/sensors/face/Face10.java +++ b/services/core/java/com/android/server/biometrics/sensors/face/Face10.java @@ -29,7 +29,6 @@ import android.hardware.biometrics.BiometricsProtoEnums; import android.hardware.biometrics.face.V1_0.IBiometricsFace; import android.hardware.biometrics.face.V1_0.IBiometricsFaceClientCallback; import android.hardware.face.Face; -import android.hardware.face.FaceManager; import android.hardware.face.FaceSensorProperties; import android.hardware.face.IFaceServiceReceiver; import android.os.Build; @@ -383,7 +382,7 @@ class Face10 implements IHwBinder.DeathRecipient { // is safe because authenticatorIds only change when A) new template has been enrolled, // or B) all templates are removed. mHandler.post(() -> { - for (UserInfo user : UserManager.get(mContext).getUsers(true /* excludeDying */)) { + for (UserInfo user : UserManager.get(mContext).getAliveUsers()) { final int targetUserId = user.id; if (!mAuthenticatorIds.containsKey(targetUserId)) { scheduleUpdateActiveUserWithoutHandler(targetUserId); @@ -480,7 +479,8 @@ class Face10 implements IHwBinder.DeathRecipient { * notifying the previous caller that the interrupting operation is complete (e.g. the * interrupting client's challenge has been revoked, so that the interrupted client can * start retry logic if necessary). See - * {@link FaceManager.GenerateChallengeCallback#onChallengeInterruptFinished(int)} + * {@link + *android.hardware.face.FaceManager.GenerateChallengeCallback#onChallengeInterruptFinished(int)} * The only case of conflicting challenges is currently resetLockout --> enroll. So, the second * option seems better as it prioritizes the new operation, which is user-facing. */ diff --git a/services/core/java/com/android/server/biometrics/sensors/fingerprint/Fingerprint21.java b/services/core/java/com/android/server/biometrics/sensors/fingerprint/Fingerprint21.java index c5c28227fd24..3754bd748781 100644 --- a/services/core/java/com/android/server/biometrics/sensors/fingerprint/Fingerprint21.java +++ b/services/core/java/com/android/server/biometrics/sensors/fingerprint/Fingerprint21.java @@ -440,7 +440,7 @@ class Fingerprint21 implements IHwBinder.DeathRecipient { // is safe because authenticatorIds only change when A) new template has been enrolled, // or B) all templates are removed. mHandler.post(() -> { - for (UserInfo user : UserManager.get(mContext).getUsers(true /* excludeDying */)) { + for (UserInfo user : UserManager.get(mContext).getAliveUsers()) { final int targetUserId = user.id; if (!mAuthenticatorIds.containsKey(targetUserId)) { scheduleUpdateActiveUserWithoutHandler(targetUserId); diff --git a/services/core/java/com/android/server/content/SyncManager.java b/services/core/java/com/android/server/content/SyncManager.java index ec12a971e445..b33aa0a6fad3 100644 --- a/services/core/java/com/android/server/content/SyncManager.java +++ b/services/core/java/com/android/server/content/SyncManager.java @@ -367,7 +367,7 @@ public class SyncManager { } private void removeStaleAccounts() { - for (UserInfo user : mUserManager.getUsers(true)) { + for (UserInfo user : mUserManager.getAliveUsers()) { // Skip any partially created/removed users if (user.partial) continue; Account[] accountsForUser = AccountManagerService.getSingleton().getAccounts( @@ -777,7 +777,7 @@ public class SyncManager { if (!mSyncStorageEngine.shouldGrantSyncAdaptersAccountAccess()) { return; } - List<UserInfo> users = mUserManager.getUsers(true); + List<UserInfo> users = mUserManager.getAliveUsers(); final int userCount = users.size(); for (int i = 0; i < userCount; i++) { UserHandle userHandle = users.get(i).getUserHandle(); diff --git a/services/core/java/com/android/server/inputmethod/TEST_MAPPING b/services/core/java/com/android/server/inputmethod/TEST_MAPPING new file mode 100644 index 000000000000..0ccd75dcbdce --- /dev/null +++ b/services/core/java/com/android/server/inputmethod/TEST_MAPPING @@ -0,0 +1,7 @@ +{ + "imports": [ + { + "path": "frameworks/base/core/java/android/view/inputmethod" + } + ] +} diff --git a/services/core/java/com/android/server/locksettings/LockSettingsStorage.java b/services/core/java/com/android/server/locksettings/LockSettingsStorage.java index e9a05a8aa16c..715e41c62a05 100644 --- a/services/core/java/com/android/server/locksettings/LockSettingsStorage.java +++ b/services/core/java/com/android/server/locksettings/LockSettingsStorage.java @@ -746,7 +746,7 @@ class LockSettingsStorage { public void dump(IndentingPrintWriter pw) { final UserManager um = UserManager.get(mContext); - for (UserInfo user : um.getUsers(false)) { + for (UserInfo user : um.getUsers()) { File userPath = getSyntheticPasswordDirectoryForUser(user.id); pw.println(String.format("User %d [%s]:", user.id, userPath.getAbsolutePath())); pw.increaseIndent(); diff --git a/services/core/java/com/android/server/notification/ManagedServices.java b/services/core/java/com/android/server/notification/ManagedServices.java index a604625460a7..74b7bd76b047 100644 --- a/services/core/java/com/android/server/notification/ManagedServices.java +++ b/services/core/java/com/android/server/notification/ManagedServices.java @@ -1554,7 +1554,7 @@ abstract public class ManagedServices { if (!isEnabledForCurrentProfiles()) { return false; } - return this.userid == userId; + return userId == USER_ALL || userId == this.userid; } public boolean enabledAndUserMatches(int nid) { diff --git a/services/core/java/com/android/server/notification/NotificationManagerService.java b/services/core/java/com/android/server/notification/NotificationManagerService.java index 04658555f22b..12419a9fcafa 100755 --- a/services/core/java/com/android/server/notification/NotificationManagerService.java +++ b/services/core/java/com/android/server/notification/NotificationManagerService.java @@ -262,7 +262,6 @@ import com.android.server.EventLogTags; import com.android.server.IoThread; import com.android.server.LocalServices; import com.android.server.SystemService; -import com.android.server.SystemService.TargetUser; import com.android.server.UiThread; import com.android.server.lights.LightsManager; import com.android.server.lights.LogicalLight; @@ -966,8 +965,7 @@ public class NotificationManagerService extends SystemService { nv.recycle(); } reportUserInteraction(r); - mAssistants.notifyAssistantActionClicked( - r.getSbn(), actionIndex, action, generatedByAssistant); + mAssistants.notifyAssistantActionClicked(r.getSbn(), action, generatedByAssistant); } } @@ -8629,12 +8627,25 @@ public class NotificationManagerService extends SystemService { ServiceManager.getService(Context.COMPANION_DEVICE_SERVICE)); } - private boolean isVisibleToListener(StatusBarNotification sbn, ManagedServiceInfo listener) { + @VisibleForTesting + boolean isVisibleToListener(StatusBarNotification sbn, ManagedServiceInfo listener) { if (!listener.enabledAndUserMatches(sbn.getUserId())) { return false; } - // TODO: remove this for older listeners. - return true; + return isInteractionVisibleToListener(listener, sbn.getUserId()); + } + + /** + * Returns whether the given assistant should be informed about interactions on the given user. + * + * Normally an assistant would be able to see all interactions on the current user and any + * associated profiles because they are notification listeners, but since NASes have one + * instance per user, we want to filter out interactions that are not for the user that the + * given NAS is bound in. + */ + private boolean isInteractionVisibleToListener(ManagedServiceInfo info, int userId) { + boolean isAssistantService = mAssistants.isServiceTokenValidLocked(info.service); + return !isAssistantService || info.isSameUser(userId); } private boolean isPackageSuspendedForUser(String pkg, int uid) { @@ -8856,8 +8867,6 @@ public class NotificationManagerService extends SystemService { } protected void onNotificationsSeenLocked(ArrayList<NotificationRecord> records) { - // There should be only one, but it's a list, so while we enforce - // singularity elsewhere, we keep it general here, to avoid surprises. for (final ManagedServiceInfo info : NotificationAssistants.this.getServices()) { ArrayList<String> keys = new ArrayList<>(records.size()); for (NotificationRecord r : records) { @@ -8875,6 +8884,8 @@ public class NotificationManagerService extends SystemService { } protected void onPanelRevealed(int items) { + // send to all currently bounds NASes since notifications from both users will appear in + // the panel for (final ManagedServiceInfo info : NotificationAssistants.this.getServices()) { mHandler.post(() -> { final INotificationListener assistant = (INotificationListener) info.service; @@ -8888,6 +8899,8 @@ public class NotificationManagerService extends SystemService { } protected void onPanelHidden() { + // send to all currently bounds NASes since notifications from both users will appear in + // the panel for (final ManagedServiceInfo info : NotificationAssistants.this.getServices()) { mHandler.post(() -> { final INotificationListener assistant = (INotificationListener) info.service; @@ -8976,7 +8989,7 @@ public class NotificationManagerService extends SystemService { } notifyAssistantLocked( sbn, - false /* sameUserOnly */, + true /* sameUserOnly */, (assistant, sbnHolder) -> { try { assistant.onNotificationVisibilityChanged(key, isVisible); @@ -8994,7 +9007,7 @@ public class NotificationManagerService extends SystemService { final String key = sbn.getKey(); notifyAssistantLocked( sbn, - false /* sameUserOnly */, + true /* sameUserOnly */, (assistant, sbnHolder) -> { try { assistant.onNotificationExpansionChanged(key, isUserAction, isExpanded); @@ -9010,7 +9023,7 @@ public class NotificationManagerService extends SystemService { final String key = sbn.getKey(); notifyAssistantLocked( sbn, - false /* sameUserOnly */, + true /* sameUserOnly */, (assistant, sbnHolder) -> { try { assistant.onNotificationDirectReply(key); @@ -9026,7 +9039,7 @@ public class NotificationManagerService extends SystemService { final String key = sbn.getKey(); notifyAssistantLocked( sbn, - false /* sameUserOnly */, + true /* sameUserOnly */, (assistant, sbnHolder) -> { try { assistant.onSuggestedReplySent( @@ -9043,12 +9056,12 @@ public class NotificationManagerService extends SystemService { @GuardedBy("mNotificationLock") void notifyAssistantActionClicked( - final StatusBarNotification sbn, int actionIndex, Notification.Action action, + final StatusBarNotification sbn, Notification.Action action, boolean generatedByAssistant) { final String key = sbn.getKey(); notifyAssistantLocked( sbn, - false /* sameUserOnly */, + true /* sameUserOnly */, (assistant, sbnHolder) -> { try { assistant.onActionClicked( @@ -9072,7 +9085,7 @@ public class NotificationManagerService extends SystemService { final StatusBarNotification sbn, final String snoozeCriterionId) { notifyAssistantLocked( sbn, - false /* sameUserOnly */, + true /* sameUserOnly */, (assistant, sbnHolder) -> { try { assistant.onNotificationSnoozedUntilContext( @@ -9129,7 +9142,7 @@ public class NotificationManagerService extends SystemService { } protected void resetDefaultAssistantsIfNecessary() { - final List<UserInfo> activeUsers = mUm.getUsers(true); + final List<UserInfo> activeUsers = mUm.getAliveUsers(); for (UserInfo userInfo : activeUsers) { int userId = userInfo.getUserHandle().getIdentifier(); if (!hasUserSet(userId)) { @@ -9293,10 +9306,12 @@ public class NotificationManagerService extends SystemService { } public void onStatusBarIconsBehaviorChanged(boolean hideSilentStatusIcons) { + // send to all currently bounds NASes since notifications from both users will appear in + // the status bar for (final ManagedServiceInfo info : getServices()) { mHandler.post(() -> { final INotificationListener listener = (INotificationListener) info.service; - try { + try { listener.onStatusBarIconsBehaviorChanged(hideSilentStatusIcons); } catch (RemoteException ex) { Slog.e(TAG, "unable to notify listener " @@ -9470,7 +9485,8 @@ public class NotificationManagerService extends SystemService { && changedHiddenNotifications.size() > 0; for (final ManagedServiceInfo serviceInfo : getServices()) { - if (!serviceInfo.isEnabledForCurrentProfiles()) { + if (!serviceInfo.isEnabledForCurrentProfiles() || !isInteractionVisibleToListener( + serviceInfo, ActivityManager.getCurrentUser())) { continue; } @@ -9489,12 +9505,7 @@ public class NotificationManagerService extends SystemService { final NotificationRankingUpdate update = makeRankingUpdateLocked( serviceInfo); - mHandler.post(new Runnable() { - @Override - public void run() { - notifyRankingUpdate(serviceInfo, update); - } - }); + mHandler.post(() -> notifyRankingUpdate(serviceInfo, update)); } } } @@ -9502,15 +9513,11 @@ public class NotificationManagerService extends SystemService { @GuardedBy("mNotificationLock") public void notifyListenerHintsChangedLocked(final int hints) { for (final ManagedServiceInfo serviceInfo : getServices()) { - if (!serviceInfo.isEnabledForCurrentProfiles()) { + if (!serviceInfo.isEnabledForCurrentProfiles() || !isInteractionVisibleToListener( + serviceInfo, ActivityManager.getCurrentUser())) { continue; } - mHandler.post(new Runnable() { - @Override - public void run() { - notifyListenerHintsChanged(serviceInfo, hints); - } - }); + mHandler.post(() -> notifyListenerHintsChanged(serviceInfo, hints)); } } @@ -9562,15 +9569,12 @@ public class NotificationManagerService extends SystemService { public void notifyInterruptionFilterChanged(final int interruptionFilter) { for (final ManagedServiceInfo serviceInfo : getServices()) { - if (!serviceInfo.isEnabledForCurrentProfiles()) { + if (!serviceInfo.isEnabledForCurrentProfiles() || !isInteractionVisibleToListener( + serviceInfo, ActivityManager.getCurrentUser())) { continue; } - mHandler.post(new Runnable() { - @Override - public void run() { - notifyInterruptionFilterChanged(serviceInfo, interruptionFilter); - } - }); + mHandler.post( + () -> notifyInterruptionFilterChanged(serviceInfo, interruptionFilter)); } } @@ -9579,15 +9583,16 @@ public class NotificationManagerService extends SystemService { if (channel == null) { return; } - for (final ManagedServiceInfo serviceInfo : getServices()) { - if (!serviceInfo.enabledAndUserMatches(UserHandle.getCallingUserId())) { + for (final ManagedServiceInfo info : getServices()) { + if (!info.enabledAndUserMatches(UserHandle.getCallingUserId()) + || !isInteractionVisibleToListener(info, UserHandle.getCallingUserId())) { continue; } BackgroundThread.getHandler().post(() -> { - if (serviceInfo.isSystem || hasCompanionDevice(serviceInfo)) { + if (info.isSystem || hasCompanionDevice(info)) { notifyNotificationChannelChanged( - serviceInfo, pkg, user, channel, modificationType); + info, pkg, user, channel, modificationType); } }); } @@ -9599,15 +9604,16 @@ public class NotificationManagerService extends SystemService { if (group == null) { return; } - for (final ManagedServiceInfo serviceInfo : getServices()) { - if (!serviceInfo.enabledAndUserMatches(UserHandle.getCallingUserId())) { + for (final ManagedServiceInfo info : getServices()) { + if (!info.enabledAndUserMatches(UserHandle.getCallingUserId()) + || !isInteractionVisibleToListener(info, UserHandle.getCallingUserId())) { continue; } BackgroundThread.getHandler().post(() -> { - if (serviceInfo.isSystem || hasCompanionDevice(serviceInfo)) { + if (info.isSystem || hasCompanionDevice(info)) { notifyNotificationChannelGroupChanged( - serviceInfo, pkg, user, group, modificationType); + info, pkg, user, group, modificationType); } }); } @@ -9626,9 +9632,6 @@ public class NotificationManagerService extends SystemService { private void notifyRemoved(ManagedServiceInfo info, StatusBarNotification sbn, NotificationRankingUpdate rankingUpdate, NotificationStats stats, int reason) { - if (!info.enabledAndUserMatches(sbn.getUserId())) { - return; - } final INotificationListener listener = (INotificationListener) info.service; StatusBarNotificationHolder sbnHolder = new StatusBarNotificationHolder(sbn); try { diff --git a/services/core/java/com/android/server/om/OverlayManagerService.java b/services/core/java/com/android/server/om/OverlayManagerService.java index a4debc16493a..d7a1ba2a93d4 100644 --- a/services/core/java/com/android/server/om/OverlayManagerService.java +++ b/services/core/java/com/android/server/om/OverlayManagerService.java @@ -288,7 +288,7 @@ public final class OverlayManagerService extends SystemService { private void initIfNeeded() { final UserManager um = getContext().getSystemService(UserManager.class); - final List<UserInfo> users = um.getUsers(true /*excludeDying*/); + final List<UserInfo> users = um.getAliveUsers(); synchronized (mLock) { final int userCount = users.size(); for (int i = 0; i < userCount; i++) { diff --git a/services/core/java/com/android/server/pm/PackageInstallerService.java b/services/core/java/com/android/server/pm/PackageInstallerService.java index 4b246c3b330c..162bfee8848d 100644 --- a/services/core/java/com/android/server/pm/PackageInstallerService.java +++ b/services/core/java/com/android/server/pm/PackageInstallerService.java @@ -743,9 +743,8 @@ public class PackageInstallerService extends IPackageInstaller.Stub implements mStagingManager.createSession(session); } - if ((session.params.installFlags & PackageManager.INSTALL_DRY_RUN) == 0) { - mCallbacks.notifySessionCreated(session.sessionId, session.userId); - } + mCallbacks.notifySessionCreated(session.sessionId, session.userId); + writeSessionsAsync(); return sessionId; } @@ -1355,25 +1354,18 @@ public class PackageInstallerService extends IPackageInstaller.Stub implements class InternalCallback { public void onSessionBadgingChanged(PackageInstallerSession session) { - if ((session.params.installFlags & PackageManager.INSTALL_DRY_RUN) == 0) { - mCallbacks.notifySessionBadgingChanged(session.sessionId, session.userId); - } - + mCallbacks.notifySessionBadgingChanged(session.sessionId, session.userId); writeSessionsAsync(); } public void onSessionActiveChanged(PackageInstallerSession session, boolean active) { - if ((session.params.installFlags & PackageManager.INSTALL_DRY_RUN) == 0) { - mCallbacks.notifySessionActiveChanged(session.sessionId, session.userId, - active); - } + mCallbacks.notifySessionActiveChanged(session.sessionId, session.userId, + active); } public void onSessionProgressChanged(PackageInstallerSession session, float progress) { - if ((session.params.installFlags & PackageManager.INSTALL_DRY_RUN) == 0) { - mCallbacks.notifySessionProgressChanged(session.sessionId, session.userId, - progress); - } + mCallbacks.notifySessionProgressChanged(session.sessionId, session.userId, + progress); } public void onStagedSessionChanged(PackageInstallerSession session) { @@ -1389,17 +1381,13 @@ public class PackageInstallerService extends IPackageInstaller.Stub implements } public void onSessionFinished(final PackageInstallerSession session, boolean success) { - if ((session.params.installFlags & PackageManager.INSTALL_DRY_RUN) == 0) { - mCallbacks.notifySessionFinished(session.sessionId, session.userId, success); - } + mCallbacks.notifySessionFinished(session.sessionId, session.userId, success); mInstallHandler.post(new Runnable() { @Override public void run() { - if (session.isStaged()) { - if (!success) { - mStagingManager.abortSession(session); - } + if (session.isStaged() && !success) { + mStagingManager.abortSession(session); } synchronized (mSessions) { if (!session.isStaged() || !success) { diff --git a/services/core/java/com/android/server/pm/PackageInstallerSession.java b/services/core/java/com/android/server/pm/PackageInstallerSession.java index ed62362b04fb..4e429cf362b5 100644 --- a/services/core/java/com/android/server/pm/PackageInstallerSession.java +++ b/services/core/java/com/android/server/pm/PackageInstallerSession.java @@ -3306,8 +3306,7 @@ public class PackageInstallerSession extends IPackageInstallerSession.Stub { // Send broadcast to default launcher only if it's a new install // TODO(b/144270665): Secure the usage of this broadcast. final boolean isNewInstall = extras == null || !extras.getBoolean(Intent.EXTRA_REPLACING); - if (success && isNewInstall && mPm.mInstallerService.okToSendBroadcasts() - && (params.installFlags & PackageManager.INSTALL_DRY_RUN) == 0) { + if (success && isNewInstall && mPm.mInstallerService.okToSendBroadcasts()) { mPm.sendSessionCommitBroadcast(generateInfoScrubbed(true /*icon*/), userId); } diff --git a/services/core/java/com/android/server/pm/PackageManagerService.java b/services/core/java/com/android/server/pm/PackageManagerService.java index 344f9cfdbc96..ffd23788223e 100644 --- a/services/core/java/com/android/server/pm/PackageManagerService.java +++ b/services/core/java/com/android/server/pm/PackageManagerService.java @@ -14541,13 +14541,11 @@ public class PackageManagerService extends IPackageManager.Stub Log.v(TAG, "restoreAndPostInstall userId=" + userId + " package=" + res.pkg); } - // A restore should be performed at this point if (a) the install - // succeeded, (b) the operation is not an update, and (c) the new - // package has not opted out of backup participation. + // A restore should be requested at this point if (a) the install + // succeeded, (b) the operation is not an update. final boolean update = res.removedInfo != null && res.removedInfo.removedPackage != null; - boolean allowBackup = res.pkg != null && res.pkg.isAllowBackup(); - boolean doRestore = !update && allowBackup; + boolean doRestore = !update; // Set up the post-install work request bookkeeping. This will be used // and cleaned up by the post-install event handling regardless of whether diff --git a/services/core/java/com/android/server/pm/UserManagerService.java b/services/core/java/com/android/server/pm/UserManagerService.java index d137fd05f793..e44c8ab3f7f3 100644 --- a/services/core/java/com/android/server/pm/UserManagerService.java +++ b/services/core/java/com/android/server/pm/UserManagerService.java @@ -760,6 +760,8 @@ public class UserManagerService extends IUserManager.Stub { return null; } + // TODO(b/157921703): replace by getAliveUsers() or remove (so callers + // explicitly call the 3-booleans version) public @NonNull List<UserInfo> getUsers(boolean excludeDying) { return getUsers(/*excludePartial= */ true, excludeDying, /* excludePreCreated= */ true); diff --git a/services/core/java/com/android/server/slice/SliceFullAccessList.java b/services/core/java/com/android/server/slice/SliceFullAccessList.java index 6f5afa207d31..d25ddf877951 100644 --- a/services/core/java/com/android/server/slice/SliceFullAccessList.java +++ b/services/core/java/com/android/server/slice/SliceFullAccessList.java @@ -101,7 +101,7 @@ public class SliceFullAccessList { public void readXml(XmlPullParser parser) throws XmlPullParserException, IOException { // upgrade xml int xmlVersion = XmlUtils.readIntAttribute(parser, ATT_VERSION, 0); - final List<UserInfo> activeUsers = UserManager.get(mContext).getUsers(true); + final List<UserInfo> activeUsers = UserManager.get(mContext).getAliveUsers(); for (UserInfo userInfo : activeUsers) { upgradeXml(xmlVersion, userInfo.getUserHandle().getIdentifier()); } diff --git a/services/core/java/com/android/server/trust/TrustManagerService.java b/services/core/java/com/android/server/trust/TrustManagerService.java index 0c85387be695..386f390c6cb9 100644 --- a/services/core/java/com/android/server/trust/TrustManagerService.java +++ b/services/core/java/com/android/server/trust/TrustManagerService.java @@ -379,7 +379,7 @@ public class TrustManagerService extends SystemService { } private void updateTrustAll() { - List<UserInfo> userInfos = mUserManager.getUsers(true /* excludeDying */); + List<UserInfo> userInfos = mUserManager.getAliveUsers(); for (UserInfo userInfo : userInfos) { updateTrust(userInfo.id, 0); } @@ -485,7 +485,7 @@ public class TrustManagerService extends SystemService { List<UserInfo> userInfos; if (userIdOrAll == UserHandle.USER_ALL) { - userInfos = mUserManager.getUsers(true /* excludeDying */); + userInfos = mUserManager.getAliveUsers(); } else { userInfos = new ArrayList<>(); userInfos.add(mUserManager.getUserInfo(userIdOrAll)); @@ -644,7 +644,7 @@ public class TrustManagerService extends SystemService { } List<UserInfo> userInfos; if (userId == UserHandle.USER_ALL) { - userInfos = mUserManager.getUsers(true /* excludeDying */); + userInfos = mUserManager.getAliveUsers(); } else { userInfos = new ArrayList<>(); userInfos.add(mUserManager.getUserInfo(userId)); @@ -1171,7 +1171,7 @@ public class TrustManagerService extends SystemService { fout.println("disabled because the third-party apps can't run yet."); return; } - final List<UserInfo> userInfos = mUserManager.getUsers(true /* excludeDying */); + final List<UserInfo> userInfos = mUserManager.getAliveUsers(); mHandler.runWithScissors(new Runnable() { @Override public void run() { diff --git a/services/core/java/com/android/server/wm/ActivityStarter.java b/services/core/java/com/android/server/wm/ActivityStarter.java index be7a6aed7489..f206259b8fe0 100644 --- a/services/core/java/com/android/server/wm/ActivityStarter.java +++ b/services/core/java/com/android/server/wm/ActivityStarter.java @@ -1710,8 +1710,9 @@ class ActivityStarter { mRootWindowContainer.startPowerModeLaunchIfNeeded( false /* forceSend */, mStartActivity); - mTargetStack.startActivityLocked(mStartActivity, topStack.getTopNonFinishingActivity(), - newTask, mKeepCurTransition, mOptions); + mTargetStack.startActivityLocked(mStartActivity, + topStack != null ? topStack.getTopNonFinishingActivity() : null, newTask, + mKeepCurTransition, mOptions); if (mDoResume) { final ActivityRecord topTaskActivity = mStartActivity.getTask().topRunningActivityLocked(); diff --git a/services/core/java/com/android/server/wm/RootWindowContainer.java b/services/core/java/com/android/server/wm/RootWindowContainer.java index 21e30ce0a495..958adaa80378 100644 --- a/services/core/java/com/android/server/wm/RootWindowContainer.java +++ b/services/core/java/com/android/server/wm/RootWindowContainer.java @@ -2289,10 +2289,6 @@ class RootWindowContainer extends WindowContainer<DisplayContent> for (int displayNdx = getChildCount() - 1; displayNdx >= 0; --displayNdx) { final DisplayContent display = getChildAt(displayNdx); - if (display.shouldSleep()) { - continue; - } - final boolean curResult = result; boolean resumedOnDisplay = display.reduceOnAllTaskDisplayAreas( (taskDisplayArea, resumed) -> { diff --git a/services/core/java/com/android/server/wm/SurfaceAnimator.java b/services/core/java/com/android/server/wm/SurfaceAnimator.java index 33935d61ead2..7df2b407557d 100644 --- a/services/core/java/com/android/server/wm/SurfaceAnimator.java +++ b/services/core/java/com/android/server/wm/SurfaceAnimator.java @@ -26,6 +26,7 @@ import static com.android.server.wm.WindowManagerDebugConfig.TAG_WM; import android.annotation.IntDef; import android.annotation.NonNull; import android.annotation.Nullable; +import android.util.DebugUtils; import android.util.Slog; import android.util.proto.ProtoOutputStream; import android.view.SurfaceControl; @@ -429,7 +430,8 @@ class SurfaceAnimator { void dump(PrintWriter pw, String prefix) { pw.print(prefix); pw.print("mLeash="); pw.print(mLeash); - pw.print(" mAnimationType=" + mAnimationType); + pw.print(" mAnimationType=" + DebugUtils.valueToString(SurfaceAnimator.class, + "ANIMATION_TYPE_", mAnimationType)); pw.println(mAnimationStartDelayed ? " mAnimationStartDelayed=true" : ""); pw.print(prefix); pw.print("Animation: "); pw.println(mAnimation); if (mAnimation != null) { @@ -442,56 +444,56 @@ class SurfaceAnimator { * No animation is specified. * @hide */ - static final int ANIMATION_TYPE_NONE = 0; + public static final int ANIMATION_TYPE_NONE = 0; /** * Animation for an app transition. * @hide */ - static final int ANIMATION_TYPE_APP_TRANSITION = 1; + public static final int ANIMATION_TYPE_APP_TRANSITION = 1; /** * Animation for screen rotation. * @hide */ - static final int ANIMATION_TYPE_SCREEN_ROTATION = 1 << 1; + public static final int ANIMATION_TYPE_SCREEN_ROTATION = 1 << 1; /** * Animation for dimming. * @hide */ - static final int ANIMATION_TYPE_DIMMER = 1 << 2; + public static final int ANIMATION_TYPE_DIMMER = 1 << 2; /** * Animation for recent apps. * @hide */ - static final int ANIMATION_TYPE_RECENTS = 1 << 3; + public static final int ANIMATION_TYPE_RECENTS = 1 << 3; /** * Animation for a {@link WindowState} without animating the activity. * @hide */ - static final int ANIMATION_TYPE_WINDOW_ANIMATION = 1 << 4; + public static final int ANIMATION_TYPE_WINDOW_ANIMATION = 1 << 4; /** * Animation to control insets. This is actually not an animation, but is used to give the * client a leash over the system window causing insets. * @hide */ - static final int ANIMATION_TYPE_INSETS_CONTROL = 1 << 5; + public static final int ANIMATION_TYPE_INSETS_CONTROL = 1 << 5; /** * Animation when a fixed rotation transform is applied to a window token. * @hide */ - static final int ANIMATION_TYPE_FIXED_TRANSFORM = 1 << 6; + public static final int ANIMATION_TYPE_FIXED_TRANSFORM = 1 << 6; /** * Bitmask to include all animation types. This is NOT an {@link AnimationType} * @hide */ - static final int ANIMATION_TYPE_ALL = -1; + public static final int ANIMATION_TYPE_ALL = -1; /** * The type of the animation. diff --git a/services/core/java/com/android/server/wm/Task.java b/services/core/java/com/android/server/wm/Task.java index 19bf451cec05..bfaaf462ed51 100644 --- a/services/core/java/com/android/server/wm/Task.java +++ b/services/core/java/com/android/server/wm/Task.java @@ -6348,7 +6348,7 @@ class Task extends WindowContainer<WindowContainer> { return mRootWindowContainer.resumeHomeActivity(prev, reason, getDisplayArea()); } - void startActivityLocked(ActivityRecord r, ActivityRecord focusedTopActivity, + void startActivityLocked(ActivityRecord r, @Nullable ActivityRecord focusedTopActivity, boolean newTask, boolean keepCurTransition, ActivityOptions options) { Task rTask = r.getTask(); final boolean allowMoveToFront = options == null || !options.getAvoidMoveToFront(); @@ -7585,7 +7585,11 @@ class Task extends WindowContainer<WindowContainer> { // Do not sleep activities in this stack if we're marked as focused and the keyguard // is in the process of going away. if (isFocusedStackOnDisplay() - && mStackSupervisor.getKeyguardController().isKeyguardGoingAway()) { + && mStackSupervisor.getKeyguardController().isKeyguardGoingAway() + // Avoid resuming activities on secondary displays since we don't want bubble + // activities to be resumed while bubble is still collapsed. + // TODO(b/113840485): Having keyguard going away state for secondary displays. + && display.isDefaultDisplay) { return false; } diff --git a/services/core/java/com/android/server/wm/TaskOrganizerController.java b/services/core/java/com/android/server/wm/TaskOrganizerController.java index 1b779c6a0cc9..63a595e3bc17 100644 --- a/services/core/java/com/android/server/wm/TaskOrganizerController.java +++ b/services/core/java/com/android/server/wm/TaskOrganizerController.java @@ -38,6 +38,7 @@ import android.os.Binder; import android.os.IBinder; import android.os.RemoteException; import android.util.Slog; +import android.util.SparseBooleanArray; import android.view.SurfaceControl; import android.window.ITaskOrganizer; import android.window.ITaskOrganizerController; @@ -50,6 +51,7 @@ import com.android.internal.util.ArrayUtils; import java.io.PrintWriter; import java.util.ArrayList; import java.util.HashMap; +import java.util.HashSet; import java.util.LinkedList; import java.util.List; import java.util.Set; @@ -206,7 +208,6 @@ class TaskOrganizerController extends ITaskOrganizerController.Stub { private final DeathRecipient mDeathRecipient; private final ArrayList<Task> mOrganizedTasks = new ArrayList<>(); private final int mUid; - private boolean mInterceptBackPressedOnTaskRoot; TaskOrganizerState(ITaskOrganizer organizer, int uid) { final Consumer<Runnable> deferTaskOrgCallbacksConsumer = @@ -224,10 +225,6 @@ class TaskOrganizerController extends ITaskOrganizerController.Stub { mUid = uid; } - void setInterceptBackPressedOnTaskRoot(boolean interceptBackPressed) { - mInterceptBackPressedOnTaskRoot = interceptBackPressed; - } - void addTask(Task t) { if (t.mTaskAppearedSent) return; @@ -247,6 +244,7 @@ class TaskOrganizerController extends ITaskOrganizerController.Stub { mOrganizer.onTaskVanished(t); } mOrganizedTasks.remove(t); + mInterceptBackPressedOnRootTasks.remove(t.mTaskId); } void dispose() { @@ -278,6 +276,8 @@ class TaskOrganizerController extends ITaskOrganizerController.Stub { private final HashMap<IBinder, TaskOrganizerState> mTaskOrganizerStates = new HashMap<>(); private final WeakHashMap<Task, RunningTaskInfo> mLastSentTaskInfos = new WeakHashMap<>(); private final ArrayList<Task> mPendingTaskInfoChanges = new ArrayList<>(); + // Set of organized tasks (by taskId) that dispatch back pressed to their organizers + private final HashSet<Integer> mInterceptBackPressedOnRootTasks = new HashSet(); private final ActivityTaskManagerService mService; @@ -623,7 +623,7 @@ class TaskOrganizerController extends ITaskOrganizerController.Stub { } @Override - public void setInterceptBackPressedOnTaskRoot(ITaskOrganizer organizer, + public void setInterceptBackPressedOnTaskRoot(WindowContainerToken token, boolean interceptBackPressed) { enforceStackPermission("setInterceptBackPressedOnTaskRoot()"); final long origId = Binder.clearCallingIdentity(); @@ -631,9 +631,15 @@ class TaskOrganizerController extends ITaskOrganizerController.Stub { synchronized (mGlobalLock) { ProtoLog.v(WM_DEBUG_WINDOW_ORGANIZER, "Set intercept back pressed on root=%b", interceptBackPressed); - final TaskOrganizerState state = mTaskOrganizerStates.get(organizer.asBinder()); - if (state != null) { - state.setInterceptBackPressedOnTaskRoot(interceptBackPressed); + final Task task = WindowContainer.fromBinder(token.asBinder()).asTask(); + if (task == null) { + Slog.w(TAG, "Could not resolve task from token"); + return; + } + if (interceptBackPressed) { + mInterceptBackPressedOnRootTasks.add(task.mTaskId); + } else { + mInterceptBackPressedOnRootTasks.remove(task.mTaskId); } } } finally { @@ -642,15 +648,12 @@ class TaskOrganizerController extends ITaskOrganizerController.Stub { } public boolean handleInterceptBackPressedOnTaskRoot(Task task) { - if (task == null || !task.isOrganized()) { + if (task == null || !task.isOrganized() + || !mInterceptBackPressedOnRootTasks.contains(task.mTaskId)) { return false; } final TaskOrganizerState state = mTaskOrganizerStates.get(task.mTaskOrganizer.asBinder()); - if (!state.mInterceptBackPressedOnTaskRoot) { - return false; - } - state.mOrganizer.onBackPressedOnTaskRoot(task); return true; } diff --git a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java index 22e309cdc2b4..80455833a3eb 100644 --- a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java +++ b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java @@ -5782,9 +5782,6 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager { if (!mHasFeature) { return; } - final CallerIdentity identity = getCallerIdentity(); - Preconditions.checkCallAuthorization(isSystemUid(identity) || isRootUid(identity) - || hasCallingOrSelfPermission(permission.INTERACT_ACROSS_USERS_FULL)); final ActiveAdmin admin; synchronized (getLockObject()) { @@ -9438,8 +9435,7 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager { Preconditions.checkCallAuthorization(isDeviceOwner(identity)); return mInjector.binderWithCleanCallingIdentity(() -> { - final List<UserInfo> userInfos = mInjector.getUserManager().getUsers(true - /*excludeDying*/); + final List<UserInfo> userInfos = mInjector.getUserManager().getAliveUsers(); final List<UserHandle> userHandles = new ArrayList<>(); for (UserInfo userInfo : userInfos) { UserHandle userHandle = userInfo.getUserHandle(); @@ -10362,7 +10358,7 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager { private void maybeClearLockTaskPolicyLocked() { mInjector.binderWithCleanCallingIdentity(() -> { - final List<UserInfo> userInfos = mUserManager.getUsers(/*excludeDying=*/ true); + final List<UserInfo> userInfos = mUserManager.getAliveUsers(); for (int i = userInfos.size() - 1; i >= 0; i--) { int userId = userInfos.get(i).id; if (canUserUseLockTaskLocked(userId)) { @@ -10849,7 +10845,7 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager { * them. */ void updateUserSetupCompleteAndPaired() { - List<UserInfo> users = mUserManager.getUsers(true); + List<UserInfo> users = mUserManager.getAliveUsers(); final int N = users.size(); for (int i = 0; i < N; i++) { int userHandle = users.get(i).id; @@ -12052,14 +12048,6 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager { } @Override - public boolean isSystemOnlyUser(ComponentName admin) { - Objects.requireNonNull(admin, "ComponentName is null"); - final CallerIdentity identity = getCallerIdentity(admin); - Preconditions.checkCallAuthorization(isDeviceOwner(identity)); - return UserManager.isSplitSystemUser() && identity.getUserId() == UserHandle.USER_SYSTEM; - } - - @Override public void reboot(ComponentName admin) { Objects.requireNonNull(admin, "ComponentName is null"); final CallerIdentity identity = getCallerIdentity(admin); @@ -12579,7 +12567,7 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager { private boolean areAllUsersAffiliatedWithDeviceLocked() { return mInjector.binderWithCleanCallingIdentity(() -> { - final List<UserInfo> userInfos = mUserManager.getUsers(/*excludeDying=*/ true); + final List<UserInfo> userInfos = mUserManager.getAliveUsers(); for (int i = 0; i < userInfos.size(); i++) { int userId = userInfos.get(i).id; if (!isUserAffiliatedWithDeviceLocked(userId)) { @@ -13048,7 +13036,7 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager { } } else { // Caller is the device owner: Look for profile owners that it can bind to. - final List<UserInfo> userInfos = mUserManager.getUsers(/*excludeDying=*/ true); + final List<UserInfo> userInfos = mUserManager.getAliveUsers(); for (int i = 0; i < userInfos.size(); i++) { final int userId = userInfos.get(i).id; if (userId != callingUserId && canUserBindToDeviceOwnerLocked(userId)) { diff --git a/services/devicepolicy/java/com/android/server/devicepolicy/Owners.java b/services/devicepolicy/java/com/android/server/devicepolicy/Owners.java index 3cdd482ffa37..7649af4ee911 100644 --- a/services/devicepolicy/java/com/android/server/devicepolicy/Owners.java +++ b/services/devicepolicy/java/com/android/server/devicepolicy/Owners.java @@ -169,7 +169,7 @@ class Owners { // First, try to read from the legacy file. final File legacy = getLegacyConfigFile(); - final List<UserInfo> users = mUserManager.getUsers(true); + final List<UserInfo> users = mUserManager.getAliveUsers(); if (readLegacyOwnerFileLocked(legacy)) { if (DEBUG) { diff --git a/services/tests/servicestests/src/com/android/server/devicepolicy/MockSystemServices.java b/services/tests/servicestests/src/com/android/server/devicepolicy/MockSystemServices.java index b306ff091267..431cc27a6635 100644 --- a/services/tests/servicestests/src/com/android/server/devicepolicy/MockSystemServices.java +++ b/services/tests/servicestests/src/com/android/server/devicepolicy/MockSystemServices.java @@ -16,7 +16,6 @@ package com.android.server.devicepolicy; import static org.mockito.ArgumentMatchers.any; -import static org.mockito.ArgumentMatchers.anyBoolean; import static org.mockito.ArgumentMatchers.anyInt; import static org.mockito.ArgumentMatchers.eq; import static org.mockito.Mockito.RETURNS_DEEP_STUBS; @@ -236,7 +235,7 @@ public class MockSystemServices { } mUserInfos.add(uh); when(userManager.getUsers()).thenReturn(mUserInfos); - when(userManager.getUsers(anyBoolean())).thenReturn(mUserInfos); + when(userManager.getAliveUsers()).thenReturn(mUserInfos); when(userManager.isUserRunning(eq(new UserHandle(userId)))).thenReturn(true); when(userManager.getProfileParent(anyInt())).thenAnswer( invocation -> { diff --git a/services/tests/uiservicestests/src/com/android/server/notification/ManagedServicesTest.java b/services/tests/uiservicestests/src/com/android/server/notification/ManagedServicesTest.java index 99433a6603c9..d7e431f3bb51 100644 --- a/services/tests/uiservicestests/src/com/android/server/notification/ManagedServicesTest.java +++ b/services/tests/uiservicestests/src/com/android/server/notification/ManagedServicesTest.java @@ -978,6 +978,7 @@ public class ManagedServicesTest extends UiServiceTestCase { assertFalse(services.isSameUser(service, 0)); assertTrue(services.isSameUser(service, 10)); + assertTrue(services.isSameUser(service, UserHandle.USER_ALL)); } @Test diff --git a/services/tests/uiservicestests/src/com/android/server/notification/NotificationAssistantsTest.java b/services/tests/uiservicestests/src/com/android/server/notification/NotificationAssistantsTest.java index ab4dc476ff20..5796e848ff6e 100644 --- a/services/tests/uiservicestests/src/com/android/server/notification/NotificationAssistantsTest.java +++ b/services/tests/uiservicestests/src/com/android/server/notification/NotificationAssistantsTest.java @@ -103,7 +103,7 @@ public class NotificationAssistantsTest extends UiServiceTestCase { when(mUm.getUserInfo(eq(user.id))).thenReturn(user); } when(mUm.getUsers()).thenReturn(users); - when(mUm.getUsers(anyBoolean())).thenReturn(users); + when(mUm.getAliveUsers()).thenReturn(users); IntArray profileIds = new IntArray(); profileIds.add(0); profileIds.add(11); diff --git a/services/tests/uiservicestests/src/com/android/server/notification/NotificationManagerServiceTest.java b/services/tests/uiservicestests/src/com/android/server/notification/NotificationManagerServiceTest.java index 9319bea497fb..86447192a441 100755 --- a/services/tests/uiservicestests/src/com/android/server/notification/NotificationManagerServiceTest.java +++ b/services/tests/uiservicestests/src/com/android/server/notification/NotificationManagerServiceTest.java @@ -5058,7 +5058,7 @@ public class NotificationManagerServiceTest extends UiServiceTestCase { 10, 10, r.getKey(), actionIndex, action, notificationVisibility, generatedByAssistant); verify(mAssistants).notifyAssistantActionClicked( - eq(r.getSbn()), eq(actionIndex), eq(action), eq(generatedByAssistant)); + eq(r.getSbn()), eq(action), eq(generatedByAssistant)); assertEquals(1, mNotificationRecordLogger.numCalls()); assertEquals( @@ -5082,7 +5082,7 @@ public class NotificationManagerServiceTest extends UiServiceTestCase { 10, 10, r.getKey(), actionIndex, action, notificationVisibility, generatedByAssistant); verify(mAssistants).notifyAssistantActionClicked( - eq(r.getSbn()), eq(actionIndex), eq(action), eq(generatedByAssistant)); + eq(r.getSbn()), eq(action), eq(generatedByAssistant)); assertEquals(1, mNotificationRecordLogger.numCalls()); assertEquals( @@ -6948,4 +6948,63 @@ public class NotificationManagerServiceTest extends UiServiceTestCase { assertEquals(NotificationManagerService.MAX_PACKAGE_NOTIFICATIONS + 1, mService.getNotificationRecordCount()); } + + @Test + public void testIsVisibleToListener_notEnabled() { + StatusBarNotification sbn = mock(StatusBarNotification.class); + when(sbn.getUserId()).thenReturn(10); + ManagedServices.ManagedServiceInfo info = mock(ManagedServices.ManagedServiceInfo.class); + ManagedServices.ManagedServiceInfo assistant = mock(ManagedServices.ManagedServiceInfo.class); + info.userid = 10; + when(info.isSameUser(anyInt())).thenReturn(true); + when(assistant.isSameUser(anyInt())).thenReturn(true); + when(info.enabledAndUserMatches(info.userid)).thenReturn(false); + when(mAssistants.checkServiceTokenLocked(any())).thenReturn(assistant); + + assertFalse(mService.isVisibleToListener(sbn, info)); + } + + @Test + public void testIsVisibleToListener_noAssistant() { + StatusBarNotification sbn = mock(StatusBarNotification.class); + when(sbn.getUserId()).thenReturn(10); + ManagedServices.ManagedServiceInfo info = mock(ManagedServices.ManagedServiceInfo.class); + info.userid = 10; + when(info.isSameUser(anyInt())).thenReturn(true); + when(info.enabledAndUserMatches(info.userid)).thenReturn(true); + when(mAssistants.checkServiceTokenLocked(any())).thenReturn(null); + + assertTrue(mService.isVisibleToListener(sbn, info)); + } + + @Test + public void testIsVisibleToListener_assistant_differentUser() { + StatusBarNotification sbn = mock(StatusBarNotification.class); + when(sbn.getUserId()).thenReturn(10); + ManagedServices.ManagedServiceInfo info = mock(ManagedServices.ManagedServiceInfo.class); + ManagedServices.ManagedServiceInfo assistant = mock(ManagedServices.ManagedServiceInfo.class); + info.userid = 0; + when(info.isSameUser(anyInt())).thenReturn(true); + when(assistant.isSameUser(anyInt())).thenReturn(true); + when(info.enabledAndUserMatches(info.userid)).thenReturn(true); + when(mAssistants.checkServiceTokenLocked(any())).thenReturn(assistant); + + assertFalse(mService.isVisibleToListener(sbn, info)); + } + + @Test + public void testIsVisibleToListener_assistant_sameUser() { + StatusBarNotification sbn = mock(StatusBarNotification.class); + when(sbn.getUserId()).thenReturn(10); + ManagedServices.ManagedServiceInfo info = mock(ManagedServices.ManagedServiceInfo.class); + ManagedServices.ManagedServiceInfo assistant = mock(ManagedServices.ManagedServiceInfo.class); + info.userid = 10; + when(info.isSameUser(anyInt())).thenReturn(true); + when(assistant.isSameUser(anyInt())).thenReturn(true); + when(info.enabledAndUserMatches(info.userid)).thenReturn(true); + when(mAssistants.checkServiceTokenLocked(any())).thenReturn(assistant); + + assertTrue(mService.isVisibleToListener(sbn, info)); + } + } diff --git a/services/tests/wmtests/src/com/android/server/wm/ActivityStackTests.java b/services/tests/wmtests/src/com/android/server/wm/ActivityStackTests.java index e2948a724acd..4cad39762a7b 100644 --- a/services/tests/wmtests/src/com/android/server/wm/ActivityStackTests.java +++ b/services/tests/wmtests/src/com/android/server/wm/ActivityStackTests.java @@ -1202,19 +1202,22 @@ public class ActivityStackTests extends WindowTestsBase { @Test public void testShouldSleepActivities() { // When focused activity and keyguard is going away, we should not sleep regardless - // of the display state + // of the display state, but keyguard-going-away should only take effects on default + // display since there is no keyguard on secondary displays (yet). verifyShouldSleepActivities(true /* focusedStack */, true /*keyguardGoingAway*/, - true /* displaySleeping */, false /* expected*/); + true /* displaySleeping */, true /* isDefaultDisplay */, false /* expected */); + verifyShouldSleepActivities(true /* focusedStack */, true /*keyguardGoingAway*/, + true /* displaySleeping */, false /* isDefaultDisplay */, true /* expected */); // When not the focused stack, defer to display sleeping state. verifyShouldSleepActivities(false /* focusedStack */, true /*keyguardGoingAway*/, - true /* displaySleeping */, true /* expected*/); + true /* displaySleeping */, true /* isDefaultDisplay */, true /* expected */); // If keyguard is going away, defer to the display sleeping state. verifyShouldSleepActivities(true /* focusedStack */, false /*keyguardGoingAway*/, - true /* displaySleeping */, true /* expected*/); + true /* displaySleeping */, true /* isDefaultDisplay */, true /* expected */); verifyShouldSleepActivities(true /* focusedStack */, false /*keyguardGoingAway*/, - false /* displaySleeping */, false /* expected*/); + false /* displaySleeping */, true /* isDefaultDisplay */, false /* expected */); } @Test @@ -1423,9 +1426,11 @@ public class ActivityStackTests extends WindowTestsBase { } private void verifyShouldSleepActivities(boolean focusedStack, - boolean keyguardGoingAway, boolean displaySleeping, boolean expected) { + boolean keyguardGoingAway, boolean displaySleeping, boolean isDefaultDisplay, + boolean expected) { final DisplayContent display = mock(DisplayContent.class); final KeyguardController keyguardController = mSupervisor.getKeyguardController(); + display.isDefaultDisplay = isDefaultDisplay; doReturn(display).when(mStack).getDisplay(); doReturn(keyguardGoingAway).when(keyguardController).isKeyguardGoingAway(); diff --git a/services/tests/wmtests/src/com/android/server/wm/RootActivityContainerTests.java b/services/tests/wmtests/src/com/android/server/wm/RootActivityContainerTests.java index b89d16807a6e..26b0bfb1dd7c 100644 --- a/services/tests/wmtests/src/com/android/server/wm/RootActivityContainerTests.java +++ b/services/tests/wmtests/src/com/android/server/wm/RootActivityContainerTests.java @@ -915,24 +915,6 @@ public class RootActivityContainerTests extends WindowTestsBase { assertEquals(taskDisplayArea.getTopStack(), taskDisplayArea.getRootHomeTask()); } - @Test - public void testResumeFocusedStackOnSleepingDisplay() { - // Create an activity on secondary display. - final TestDisplayContent secondDisplay = addNewDisplayContentAt( - DisplayContent.POSITION_TOP); - final Task stack = secondDisplay.getDefaultTaskDisplayArea() - .createStack(WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD, true /* onTop */); - final ActivityRecord activity = new ActivityBuilder(mAtm).setStack(stack).build(); - spyOn(activity); - spyOn(stack); - - // Cannot resumed activities on secondary display if the display should sleep. - doReturn(true).when(secondDisplay).shouldSleep(); - mRootWindowContainer.resumeFocusedStacksTopActivities(); - verify(stack, never()).resumeTopActivityUncheckedLocked(any(), any()); - verify(activity, never()).makeActiveIfNeeded(any()); - } - /** * Mock {@link RootWindowContainer#resolveHomeActivity} for returning consistent activity * info for test cases. diff --git a/services/tests/wmtests/src/com/android/server/wm/WindowOrganizerTests.java b/services/tests/wmtests/src/com/android/server/wm/WindowOrganizerTests.java index 289d54e967f5..46a6a82faba5 100644 --- a/services/tests/wmtests/src/com/android/server/wm/WindowOrganizerTests.java +++ b/services/tests/wmtests/src/com/android/server/wm/WindowOrganizerTests.java @@ -930,23 +930,36 @@ public class WindowOrganizerTests extends WindowTestsBase { final Task stack = createStack(); final Task task = createTask(stack); final ActivityRecord activity = createActivityRecordInTask(stack.mDisplayContent, task); + final Task stack2 = createStack(); + final Task task2 = createTask(stack2); + final ActivityRecord activity2 = createActivityRecordInTask(stack.mDisplayContent, task2); final ITaskOrganizer organizer = registerMockOrganizer(); // Setup the task to be controlled by the MW mode organizer stack.setWindowingMode(WINDOWING_MODE_MULTI_WINDOW); + stack2.setWindowingMode(WINDOWING_MODE_MULTI_WINDOW); assertTrue(stack.isOrganized()); + assertTrue(stack2.isOrganized()); // Verify a back pressed does not call the organizer mWm.mAtmService.onBackPressedOnTaskRoot(activity.token); verify(organizer, never()).onBackPressedOnTaskRoot(any()); // Enable intercepting back - mWm.mAtmService.mTaskOrganizerController.setInterceptBackPressedOnTaskRoot(organizer, - true); + mWm.mAtmService.mTaskOrganizerController.setInterceptBackPressedOnTaskRoot( + stack.mRemoteToken.toWindowContainerToken(), true); // Verify now that the back press does call the organizer mWm.mAtmService.onBackPressedOnTaskRoot(activity.token); verify(organizer, times(1)).onBackPressedOnTaskRoot(any()); + + // Disable intercepting back + mWm.mAtmService.mTaskOrganizerController.setInterceptBackPressedOnTaskRoot( + stack.mRemoteToken.toWindowContainerToken(), false); + + // Verify now that the back press no longer calls the organizer + mWm.mAtmService.onBackPressedOnTaskRoot(activity.token); + verify(organizer, times(1)).onBackPressedOnTaskRoot(any()); } @Test diff --git a/services/usage/java/com/android/server/usage/UsageStatsService.java b/services/usage/java/com/android/server/usage/UsageStatsService.java index 81aad972898e..f151d9ca2420 100644 --- a/services/usage/java/com/android/server/usage/UsageStatsService.java +++ b/services/usage/java/com/android/server/usage/UsageStatsService.java @@ -183,6 +183,7 @@ public class UsageStatsService extends SystemService implements private static class ActivityData { private final String mTaskRootPackage; private final String mTaskRootClass; + public int lastEvent = Event.NONE; private ActivityData(String taskRootPackage, String taskRootClass) { mTaskRootPackage = taskRootPackage; mTaskRootClass = taskRootClass; @@ -785,6 +786,7 @@ public class UsageStatsService extends SystemService implements switch (event.mEventType) { case Event.ACTIVITY_RESUMED: case Event.ACTIVITY_PAUSED: + case Event.ACTIVITY_STOPPED: uid = mPackageManagerInternal.getPackageUid(event.mPackage, 0, userId); break; default: @@ -817,8 +819,10 @@ public class UsageStatsService extends SystemService implements .APP_USAGE_EVENT_OCCURRED__EVENT_TYPE__MOVE_TO_FOREGROUND); // check if this activity has already been resumed if (mVisibleActivities.get(event.mInstanceId) != null) break; - mVisibleActivities.put(event.mInstanceId, - new ActivityData(event.mTaskRootPackage, event.mTaskRootClass)); + final ActivityData resumedData = new ActivityData(event.mTaskRootPackage, + event.mTaskRootClass); + resumedData.lastEvent = Event.ACTIVITY_RESUMED; + mVisibleActivities.put(event.mInstanceId, resumedData); try { switch(mUsageSource) { case USAGE_SOURCE_CURRENT_ACTIVITY: @@ -834,16 +838,17 @@ public class UsageStatsService extends SystemService implements } break; case Event.ACTIVITY_PAUSED: - if (event.mTaskRootPackage == null) { - // Task Root info is missing. Repair the event based on previous data - final ActivityData prevData = mVisibleActivities.get(event.mInstanceId); - if (prevData == null) { - Slog.w(TAG, "Unexpected activity event reported! (" + event.mPackage - + "/" + event.mClass + " event : " + event.mEventType - + " instanceId : " + event.mInstanceId + ")"); - } else { - event.mTaskRootPackage = prevData.mTaskRootPackage; - event.mTaskRootClass = prevData.mTaskRootClass; + final ActivityData pausedData = mVisibleActivities.get(event.mInstanceId); + if (pausedData == null) { + Slog.w(TAG, "Unexpected activity event reported! (" + event.mPackage + + "/" + event.mClass + " event : " + event.mEventType + + " instanceId : " + event.mInstanceId + ")"); + } else { + pausedData.lastEvent = Event.ACTIVITY_PAUSED; + if (event.mTaskRootPackage == null) { + // Task Root info is missing. Repair the event based on previous data + event.mTaskRootPackage = pausedData.mTaskRootPackage; + event.mTaskRootClass = pausedData.mTaskRootClass; } } FrameworkStatsLog.write( @@ -866,6 +871,16 @@ public class UsageStatsService extends SystemService implements return; } + if (prevData.lastEvent != Event.ACTIVITY_PAUSED) { + FrameworkStatsLog.write( + FrameworkStatsLog.APP_USAGE_EVENT_OCCURRED, + uid, + event.mPackage, + event.mClass, + FrameworkStatsLog + .APP_USAGE_EVENT_OCCURRED__EVENT_TYPE__MOVE_TO_BACKGROUND); + } + ArraySet<String> tokens; synchronized (mUsageReporters) { tokens = mUsageReporters.removeReturnOld(event.mInstanceId); diff --git a/tests/RollbackTest/Android.bp b/tests/RollbackTest/Android.bp index 4f5a30502c91..7dd003eb9755 100644 --- a/tests/RollbackTest/Android.bp +++ b/tests/RollbackTest/Android.bp @@ -15,6 +15,7 @@ android_test { name: "RollbackTest", manifest: "RollbackTest/AndroidManifest.xml", + platform_apis: true, srcs: ["RollbackTest/src/**/*.java"], static_libs: ["androidx.test.rules", "cts-rollback-lib", "cts-install-lib"], test_suites: ["general-tests"], diff --git a/tests/RollbackTest/RollbackTest/src/com/android/tests/rollback/RollbackTest.java b/tests/RollbackTest/RollbackTest/src/com/android/tests/rollback/RollbackTest.java index de51c5ca19ed..0db2b2af7260 100644 --- a/tests/RollbackTest/RollbackTest/src/com/android/tests/rollback/RollbackTest.java +++ b/tests/RollbackTest/RollbackTest/src/com/android/tests/rollback/RollbackTest.java @@ -175,7 +175,7 @@ public class RollbackTest { assertThat(InstallUtils.getInstalledVersion(TestApp.A)).isEqualTo(1); UserManager um = (UserManager) context.getSystemService(context.USER_SERVICE); - List<Integer> userIds = um.getUsers(true) + List<Integer> userIds = um.getAliveUsers() .stream().map(user -> user.id).collect(Collectors.toList()); assertThat(InstallUtils.isOnlyInstalledForUser(TestApp.A, context.getUserId(), userIds)).isTrue(); diff --git a/wifi/java/android/net/wifi/ScanResult.java b/wifi/java/android/net/wifi/ScanResult.java index aa3a13925894..9302f78b7fca 100644 --- a/wifi/java/android/net/wifi/ScanResult.java +++ b/wifi/java/android/net/wifi/ScanResult.java @@ -81,6 +81,12 @@ public final class ScanResult implements Parcelable { public String capabilities; /** + * The interface name on which the scan result was received. + * @hide + */ + public String ifaceName; + + /** * @hide * No security protocol. */ @@ -939,6 +945,7 @@ public final class ScanResult implements Parcelable { flags = source.flags; radioChainInfos = source.radioChainInfos; this.mWifiStandard = source.mWifiStandard; + this.ifaceName = source.ifaceName; } } @@ -977,6 +984,7 @@ public final class ScanResult implements Parcelable { sb.append(", 80211mcResponder: "); sb.append(((flags & FLAG_80211mc_RESPONDER) != 0) ? "is supported" : "is not supported"); sb.append(", Radio Chain Infos: ").append(Arrays.toString(radioChainInfos)); + sb.append(", interface name: ").append(ifaceName); return sb.toString(); } @@ -1056,6 +1064,7 @@ public final class ScanResult implements Parcelable { } else { dest.writeInt(0); } + dest.writeString((ifaceName != null) ? ifaceName.toString() : ""); } /** Implement the Parcelable interface */ @@ -1134,6 +1143,7 @@ public final class ScanResult implements Parcelable { sr.radioChainInfos[i].level = in.readInt(); } } + sr.ifaceName = in.readString(); return sr; } diff --git a/wifi/tests/src/android/net/wifi/ScanResultTest.java b/wifi/tests/src/android/net/wifi/ScanResultTest.java index 5516f433070f..4a3586826de9 100644 --- a/wifi/tests/src/android/net/wifi/ScanResultTest.java +++ b/wifi/tests/src/android/net/wifi/ScanResultTest.java @@ -44,6 +44,7 @@ public class ScanResultTest { public static final long TEST_TSF = 04660l; public static final @WifiAnnotations.WifiStandard int TEST_WIFI_STANDARD = ScanResult.WIFI_STANDARD_11AC; + public static final String TEST_IFACE_NAME = "test_ifname"; /** * Frequency to channel map. This include some frequencies used outside the US. @@ -219,7 +220,7 @@ public class ScanResultTest { + "passpoint: no, ChannelBandwidth: 0, centerFreq0: 0, centerFreq1: 0, " + "standard: 11ac, " + "80211mcResponder: is not supported, " - + "Radio Chain Infos: null", scanResult.toString()); + + "Radio Chain Infos: null, interface name: test_ifname", scanResult.toString()); } /** @@ -242,7 +243,8 @@ public class ScanResultTest { + "standard: 11ac, " + "80211mcResponder: is not supported, " + "Radio Chain Infos: [RadioChainInfo: id=0, level=-45, " - + "RadioChainInfo: id=1, level=-54]", scanResult.toString()); + + "RadioChainInfo: id=1, level=-54], interface name: test_ifname", + scanResult.toString()); } /** @@ -283,6 +285,8 @@ public class ScanResultTest { result.frequency = TEST_FREQUENCY; result.timestamp = TEST_TSF; result.setWifiStandard(TEST_WIFI_STANDARD); + result.ifaceName = TEST_IFACE_NAME; + return result; } |