diff options
115 files changed, 931 insertions, 1702 deletions
diff --git a/api/current.txt b/api/current.txt index 34ba3fcdf175..e1dbae7a14c3 100644 --- a/api/current.txt +++ b/api/current.txt @@ -224,6 +224,7 @@ package android { field public static final int __removed3 = 16844187; // 0x101059b field public static final int __removed4 = 16844188; // 0x101059c field public static final int __removed5 = 16844189; // 0x101059d + field public static final int __removed6 = 16844182; // 0x1010596 field public static final int absListViewStyle = 16842858; // 0x101006a field public static final int accessibilityEventTypes = 16843648; // 0x1010380 field public static final int accessibilityFeedbackType = 16843650; // 0x1010382 @@ -750,7 +751,6 @@ package android { field public static final int immersive = 16843456; // 0x10102c0 field public static final int importantForAccessibility = 16843690; // 0x10103aa field public static final int importantForAutofill = 16844120; // 0x1010558 - field public static final int importantForContentCapture = 16844182; // 0x1010596 field public static final int inAnimation = 16843127; // 0x1010177 field public static final int includeFontPadding = 16843103; // 0x101015f field public static final int includeInGlobalSearch = 16843374; // 0x101026e @@ -6235,14 +6235,14 @@ package android.app { } public class TaskInfo { - field public android.content.ComponentName baseActivity; - field public android.content.Intent baseIntent; + field @Nullable public android.content.ComponentName baseActivity; + field @NonNull public android.content.Intent baseIntent; field public boolean isRunning; field public int numActivities; - field public android.content.ComponentName origActivity; - field public android.app.ActivityManager.TaskDescription taskDescription; + field @Nullable public android.content.ComponentName origActivity; + field @Nullable public android.app.ActivityManager.TaskDescription taskDescription; field public int taskId; - field public android.content.ComponentName topActivity; + field @Nullable public android.content.ComponentName topActivity; } public class TaskStackBuilder { @@ -25138,25 +25138,6 @@ package android.media { field public static final int TYPE_STRING = 4; // 0x4 } - public final class MediaItem2 implements android.os.Parcelable { - method public int describeContents(); - method public long getEndPosition(); - method @Nullable public android.media.MediaMetadata getMetadata(); - method public long getStartPosition(); - method public void setMetadata(@Nullable android.media.MediaMetadata); - method public void writeToParcel(android.os.Parcel, int); - field @NonNull public static final android.os.Parcelable.Creator<android.media.MediaItem2> CREATOR; - field public static final long POSITION_UNKNOWN = 576460752303423487L; // 0x7ffffffffffffffL - } - - public static final class MediaItem2.Builder { - ctor public MediaItem2.Builder(); - method @NonNull public android.media.MediaItem2 build(); - method @NonNull public android.media.MediaItem2.Builder setEndPosition(long); - method @NonNull public android.media.MediaItem2.Builder setMetadata(@Nullable android.media.MediaMetadata); - method @NonNull public android.media.MediaItem2.Builder setStartPosition(long); - } - public final class MediaMetadata implements android.os.Parcelable { method public boolean containsKey(String); method public int describeContents(); @@ -47818,6 +47799,10 @@ package android.util { method public boolean equals(android.util.DisplayMetrics); method public void setTo(android.util.DisplayMetrics); method public void setToDefaults(); + field public static final int DENSITY_140 = 140; // 0x8c + field public static final int DENSITY_180 = 180; // 0xb4 + field public static final int DENSITY_200 = 200; // 0xc8 + field public static final int DENSITY_220 = 220; // 0xdc field public static final int DENSITY_260 = 260; // 0x104 field public static final int DENSITY_280 = 280; // 0x118 field public static final int DENSITY_300 = 300; // 0x12c @@ -50201,7 +50186,6 @@ package android.view { method @android.view.ViewDebug.CapturedViewProperty @IdRes public int getId(); method @android.view.ViewDebug.ExportedProperty(category="accessibility", mapping={@android.view.ViewDebug.IntToString(from=android.view.View.IMPORTANT_FOR_ACCESSIBILITY_AUTO, to="auto"), @android.view.ViewDebug.IntToString(from=android.view.View.IMPORTANT_FOR_ACCESSIBILITY_YES, to="yes"), @android.view.ViewDebug.IntToString(from=android.view.View.IMPORTANT_FOR_ACCESSIBILITY_NO, to="no"), @android.view.ViewDebug.IntToString(from=android.view.View.IMPORTANT_FOR_ACCESSIBILITY_NO_HIDE_DESCENDANTS, to="noHideDescendants")}) public int getImportantForAccessibility(); method @android.view.ViewDebug.ExportedProperty(mapping={@android.view.ViewDebug.IntToString(from=android.view.View.IMPORTANT_FOR_AUTOFILL_AUTO, to="auto"), @android.view.ViewDebug.IntToString(from=android.view.View.IMPORTANT_FOR_AUTOFILL_YES, to="yes"), @android.view.ViewDebug.IntToString(from=android.view.View.IMPORTANT_FOR_AUTOFILL_NO, to="no"), @android.view.ViewDebug.IntToString(from=android.view.View.IMPORTANT_FOR_AUTOFILL_YES_EXCLUDE_DESCENDANTS, to="yesExcludeDescendants"), @android.view.ViewDebug.IntToString(from=android.view.View.IMPORTANT_FOR_AUTOFILL_NO_EXCLUDE_DESCENDANTS, to="noExcludeDescendants")}) public int getImportantForAutofill(); - method @android.view.ViewDebug.ExportedProperty(mapping={@android.view.ViewDebug.IntToString(from=android.view.View.IMPORTANT_FOR_CONTENT_CAPTURE_AUTO, to="auto"), @android.view.ViewDebug.IntToString(from=android.view.View.IMPORTANT_FOR_CONTENT_CAPTURE_YES, to="yes"), @android.view.ViewDebug.IntToString(from=android.view.View.IMPORTANT_FOR_CONTENT_CAPTURE_NO, to="no"), @android.view.ViewDebug.IntToString(from=android.view.View.IMPORTANT_FOR_CONTENT_CAPTURE_YES_EXCLUDE_DESCENDANTS, to="yesExcludeDescendants"), @android.view.ViewDebug.IntToString(from=android.view.View.IMPORTANT_FOR_CONTENT_CAPTURE_NO_EXCLUDE_DESCENDANTS, to="noExcludeDescendants")}) public int getImportantForContentCapture(); method public boolean getKeepScreenOn(); method public android.view.KeyEvent.DispatcherState getKeyDispatcherState(); method @android.view.ViewDebug.ExportedProperty(category="accessibility") @IdRes public int getLabelFor(); @@ -50342,7 +50326,6 @@ package android.view { method @android.view.ViewDebug.ExportedProperty public boolean isHovered(); method public boolean isImportantForAccessibility(); method public final boolean isImportantForAutofill(); - method public final boolean isImportantForContentCapture(); method public boolean isInEditMode(); method public boolean isInLayout(); method @android.view.ViewDebug.ExportedProperty public boolean isInTouchMode(); @@ -50417,7 +50400,6 @@ package android.view { method @CallSuper public void onPopulateAccessibilityEvent(android.view.accessibility.AccessibilityEvent); method public void onProvideAutofillStructure(android.view.ViewStructure, int); method public void onProvideAutofillVirtualStructure(android.view.ViewStructure, int); - method public void onProvideContentCaptureStructure(@NonNull android.view.ViewStructure, int); method public void onProvideStructure(android.view.ViewStructure); method public void onProvideVirtualStructure(android.view.ViewStructure); method public android.view.PointerIcon onResolvePointerIcon(android.view.MotionEvent, int); @@ -50543,7 +50525,6 @@ package android.view { method public void setId(@IdRes int); method public void setImportantForAccessibility(int); method public void setImportantForAutofill(int); - method public void setImportantForContentCapture(int); method public void setKeepScreenOn(boolean); method public void setKeyboardNavigationCluster(boolean); method public void setLabelFor(@IdRes int); @@ -50722,11 +50703,6 @@ package android.view { field public static final int IMPORTANT_FOR_AUTOFILL_NO_EXCLUDE_DESCENDANTS = 8; // 0x8 field public static final int IMPORTANT_FOR_AUTOFILL_YES = 1; // 0x1 field public static final int IMPORTANT_FOR_AUTOFILL_YES_EXCLUDE_DESCENDANTS = 4; // 0x4 - field public static final int IMPORTANT_FOR_CONTENT_CAPTURE_AUTO = 0; // 0x0 - field public static final int IMPORTANT_FOR_CONTENT_CAPTURE_NO = 2; // 0x2 - field public static final int IMPORTANT_FOR_CONTENT_CAPTURE_NO_EXCLUDE_DESCENDANTS = 8; // 0x8 - field public static final int IMPORTANT_FOR_CONTENT_CAPTURE_YES = 1; // 0x1 - field public static final int IMPORTANT_FOR_CONTENT_CAPTURE_YES_EXCLUDE_DESCENDANTS = 4; // 0x4 field public static final int INVISIBLE = 4; // 0x4 field public static final int KEEP_SCREEN_ON = 67108864; // 0x4000000 field public static final int LAYER_TYPE_HARDWARE = 2; // 0x2 @@ -52834,7 +52810,7 @@ package android.view.contentcapture { method @Nullable public java.util.Set<android.view.contentcapture.ContentCaptureCondition> getContentCaptureConditions(); method @Nullable public android.content.ComponentName getServiceComponentName(); method public boolean isContentCaptureEnabled(); - method public void removeUserData(@NonNull android.view.contentcapture.UserDataRemovalRequest); + method public void removeData(@NonNull android.view.contentcapture.DataRemovalRequest); method public void setContentCaptureEnabled(boolean); } @@ -52845,6 +52821,7 @@ package android.view.contentcapture { method @Nullable public final android.view.contentcapture.ContentCaptureContext getContentCaptureContext(); method @NonNull public final android.view.contentcapture.ContentCaptureSessionId getContentCaptureSessionId(); method @NonNull public android.view.autofill.AutofillId newAutofillId(@NonNull android.view.autofill.AutofillId, long); + method @NonNull public final android.view.ViewStructure newViewStructure(@NonNull android.view.View); method @NonNull public final android.view.ViewStructure newVirtualViewStructure(@NonNull android.view.autofill.AutofillId, long); method public final void notifyViewAppeared(@NonNull android.view.ViewStructure); method public final void notifyViewDisappeared(@NonNull android.view.autofill.AutofillId); @@ -52859,24 +52836,24 @@ package android.view.contentcapture { field @NonNull public static final android.os.Parcelable.Creator<android.view.contentcapture.ContentCaptureSessionId> CREATOR; } - public final class UserDataRemovalRequest implements android.os.Parcelable { + public final class DataRemovalRequest implements android.os.Parcelable { method public int describeContents(); - method @NonNull public java.util.List<android.view.contentcapture.UserDataRemovalRequest.LocusIdRequest> getLocusIdRequests(); + method @NonNull public java.util.List<android.view.contentcapture.DataRemovalRequest.LocusIdRequest> getLocusIdRequests(); method @NonNull public String getPackageName(); method public boolean isForEverything(); method public void writeToParcel(android.os.Parcel, int); - field @NonNull public static final android.os.Parcelable.Creator<android.view.contentcapture.UserDataRemovalRequest> CREATOR; + field @NonNull public static final android.os.Parcelable.Creator<android.view.contentcapture.DataRemovalRequest> CREATOR; field public static final int FLAG_IS_PREFIX = 1; // 0x1 } - public static final class UserDataRemovalRequest.Builder { - ctor public UserDataRemovalRequest.Builder(); - method @NonNull public android.view.contentcapture.UserDataRemovalRequest.Builder addLocusId(@NonNull android.content.LocusId, int); - method @NonNull public android.view.contentcapture.UserDataRemovalRequest build(); - method @NonNull public android.view.contentcapture.UserDataRemovalRequest.Builder forEverything(); + public static final class DataRemovalRequest.Builder { + ctor public DataRemovalRequest.Builder(); + method @NonNull public android.view.contentcapture.DataRemovalRequest.Builder addLocusId(@NonNull android.content.LocusId, int); + method @NonNull public android.view.contentcapture.DataRemovalRequest build(); + method @NonNull public android.view.contentcapture.DataRemovalRequest.Builder forEverything(); } - public final class UserDataRemovalRequest.LocusIdRequest { + public final class DataRemovalRequest.LocusIdRequest { method @NonNull public int getFlags(); method @NonNull public android.content.LocusId getLocusId(); } @@ -53426,6 +53403,7 @@ package android.view.textclassifier { method public int describeContents(); method @Nullable public String getCallingPackageName(); method @NonNull public java.util.List<android.view.textclassifier.ConversationActions.Message> getConversation(); + method @NonNull public android.os.Bundle getExtras(); method @Nullable public java.util.List<java.lang.String> getHints(); method @IntRange(from=0xffffffff) public int getMaxSuggestions(); method @NonNull public android.view.textclassifier.TextClassifier.EntityConfig getTypeConfig(); @@ -53438,6 +53416,7 @@ package android.view.textclassifier { public static final class ConversationActions.Request.Builder { ctor public ConversationActions.Request.Builder(@NonNull java.util.List<android.view.textclassifier.ConversationActions.Message>); method @NonNull public android.view.textclassifier.ConversationActions.Request build(); + method @NonNull public android.view.textclassifier.ConversationActions.Request.Builder setExtras(@Nullable android.os.Bundle); method @NonNull public android.view.textclassifier.ConversationActions.Request.Builder setHints(@Nullable java.util.List<java.lang.String>); method @NonNull public android.view.textclassifier.ConversationActions.Request.Builder setMaxSuggestions(@IntRange(from=0xffffffff) int); method @NonNull public android.view.textclassifier.ConversationActions.Request.Builder setTypeConfig(@Nullable android.view.textclassifier.TextClassifier.EntityConfig); diff --git a/api/system-current.txt b/api/system-current.txt index ae27daf53ede..d15d00682817 100644 --- a/api/system-current.txt +++ b/api/system-current.txt @@ -1092,12 +1092,11 @@ package android.app.prediction { } public static final class AppTarget.Builder { - ctor public AppTarget.Builder(@NonNull android.app.prediction.AppTargetId); + ctor public AppTarget.Builder(@NonNull android.app.prediction.AppTargetId, @NonNull String, @NonNull android.os.UserHandle); + ctor public AppTarget.Builder(@NonNull android.app.prediction.AppTargetId, @NonNull android.content.pm.ShortcutInfo); method @NonNull public android.app.prediction.AppTarget build(); method @NonNull public android.app.prediction.AppTarget.Builder setClassName(@NonNull String); method @NonNull public android.app.prediction.AppTarget.Builder setRank(@IntRange(from=0) int); - method @NonNull public android.app.prediction.AppTarget.Builder setTarget(@NonNull String, @NonNull android.os.UserHandle); - method @NonNull public android.app.prediction.AppTarget.Builder setTarget(@NonNull android.content.pm.ShortcutInfo); } public final class AppTargetEvent implements android.os.Parcelable { @@ -5822,7 +5821,6 @@ package android.provider { public final class DeviceConfig { method @RequiresPermission(android.Manifest.permission.READ_DEVICE_CONFIG) public static void addOnPropertiesChangedListener(@NonNull String, @NonNull java.util.concurrent.Executor, @NonNull android.provider.DeviceConfig.OnPropertiesChangedListener); - method @RequiresPermission(android.Manifest.permission.READ_DEVICE_CONFIG) public static void addOnPropertyChangedListener(@NonNull String, @NonNull java.util.concurrent.Executor, @NonNull android.provider.DeviceConfig.OnPropertyChangedListener); method @RequiresPermission(android.Manifest.permission.READ_DEVICE_CONFIG) public static boolean getBoolean(@NonNull String, @NonNull String, boolean); method @RequiresPermission(android.Manifest.permission.READ_DEVICE_CONFIG) public static float getFloat(@NonNull String, @NonNull String, float); method @RequiresPermission(android.Manifest.permission.READ_DEVICE_CONFIG) public static int getInt(@NonNull String, @NonNull String, int); @@ -5830,7 +5828,6 @@ package android.provider { method @RequiresPermission(android.Manifest.permission.READ_DEVICE_CONFIG) public static String getProperty(@NonNull String, @NonNull String); method @RequiresPermission(android.Manifest.permission.READ_DEVICE_CONFIG) public static String getString(@NonNull String, @NonNull String, @Nullable String); method public static void removeOnPropertiesChangedListener(@NonNull android.provider.DeviceConfig.OnPropertiesChangedListener); - method public static void removeOnPropertyChangedListener(@NonNull android.provider.DeviceConfig.OnPropertyChangedListener); method @RequiresPermission(android.Manifest.permission.WRITE_DEVICE_CONFIG) public static void resetToDefaults(int, @Nullable String); method @RequiresPermission(android.Manifest.permission.WRITE_DEVICE_CONFIG) public static boolean setProperty(@NonNull String, @NonNull String, @Nullable String, boolean); field public static final String NAMESPACE_ACTIVITY_MANAGER = "activity_manager"; @@ -5863,10 +5860,6 @@ package android.provider { method public void onPropertiesChanged(@NonNull android.provider.DeviceConfig.Properties); } - public static interface DeviceConfig.OnPropertyChangedListener { - method public void onPropertyChanged(@NonNull String, @NonNull String, @Nullable String); - } - public static class DeviceConfig.Properties { method public boolean getBoolean(@NonNull String, boolean); method public float getFloat(@NonNull String, float); @@ -6274,7 +6267,6 @@ package android.service.attention { public abstract class AttentionService extends android.app.Service { ctor public AttentionService(); - method public final void disableSelf(); method @Nullable public final android.os.IBinder onBind(@NonNull android.content.Intent); method public abstract void onCancelAttentionCheck(@NonNull android.service.attention.AttentionService.AttentionCallback); method public abstract void onCheckAttention(@NonNull android.service.attention.AttentionService.AttentionCallback); @@ -6395,9 +6387,9 @@ package android.service.contentcapture { method public void onConnected(); method public void onContentCaptureEvent(@NonNull android.view.contentcapture.ContentCaptureSessionId, @NonNull android.view.contentcapture.ContentCaptureEvent); method public void onCreateContentCaptureSession(@NonNull android.view.contentcapture.ContentCaptureContext, @NonNull android.view.contentcapture.ContentCaptureSessionId); + method public void onDataRemovalRequest(@NonNull android.view.contentcapture.DataRemovalRequest); method public void onDestroyContentCaptureSession(@NonNull android.view.contentcapture.ContentCaptureSessionId); method public void onDisconnected(); - method public void onUserDataRemovalRequest(@NonNull android.view.contentcapture.UserDataRemovalRequest); method public final void setContentCaptureConditions(@NonNull String, @Nullable java.util.Set<android.view.contentcapture.ContentCaptureCondition>); method public final void setContentCaptureWhitelist(@Nullable java.util.Set<java.lang.String>, @Nullable java.util.Set<android.content.ComponentName>); field public static final String SERVICE_INTERFACE = "android.service.contentcapture.ContentCaptureService"; @@ -6497,7 +6489,7 @@ package android.service.euicc { ctor public EuiccService(); method @CallSuper public android.os.IBinder onBind(android.content.Intent); method public abstract int onDeleteSubscription(int, String); - method public abstract android.service.euicc.DownloadSubscriptionResult onDownloadSubscription(int, @NonNull android.telephony.euicc.DownloadableSubscription, boolean, boolean, @Nullable android.os.Bundle); + method public android.service.euicc.DownloadSubscriptionResult onDownloadSubscription(int, @NonNull android.telephony.euicc.DownloadableSubscription, boolean, boolean, @Nullable android.os.Bundle); method @Deprecated public int onDownloadSubscription(int, @NonNull android.telephony.euicc.DownloadableSubscription, boolean, boolean); method public abstract int onEraseSubscriptions(int); method public abstract android.service.euicc.GetDefaultDownloadableSubscriptionListResult onGetDefaultDownloadableSubscriptionList(int, boolean); diff --git a/api/system-removed.txt b/api/system-removed.txt index 5d74e17de756..8f7112266457 100644 --- a/api/system-removed.txt +++ b/api/system-removed.txt @@ -125,6 +125,19 @@ package android.os { } +package android.provider { + + public final class DeviceConfig { + method @RequiresPermission(android.Manifest.permission.READ_DEVICE_CONFIG) public static void addOnPropertyChangedListener(@NonNull String, @NonNull java.util.concurrent.Executor, @NonNull android.provider.DeviceConfig.OnPropertyChangedListener); + method public static void removeOnPropertyChangedListener(@NonNull android.provider.DeviceConfig.OnPropertyChangedListener); + } + + public static interface DeviceConfig.OnPropertyChangedListener { + method public void onPropertyChanged(@NonNull String, @NonNull String, @Nullable String); + } + +} + package android.service.notification { public abstract class NotificationListenerService extends android.app.Service { diff --git a/api/test-current.txt b/api/test-current.txt index d37b45e79731..811ad43b5a9e 100644 --- a/api/test-current.txt +++ b/api/test-current.txt @@ -498,12 +498,11 @@ package android.app.prediction { } public static final class AppTarget.Builder { - ctor public AppTarget.Builder(@NonNull android.app.prediction.AppTargetId); + ctor public AppTarget.Builder(@NonNull android.app.prediction.AppTargetId, @NonNull String, @NonNull android.os.UserHandle); + ctor public AppTarget.Builder(@NonNull android.app.prediction.AppTargetId, @NonNull android.content.pm.ShortcutInfo); method @NonNull public android.app.prediction.AppTarget build(); method @NonNull public android.app.prediction.AppTarget.Builder setClassName(@NonNull String); method @NonNull public android.app.prediction.AppTarget.Builder setRank(@IntRange(from=0) int); - method @NonNull public android.app.prediction.AppTarget.Builder setTarget(@NonNull String, @NonNull android.os.UserHandle); - method @NonNull public android.app.prediction.AppTarget.Builder setTarget(@NonNull android.content.pm.ShortcutInfo); } public final class AppTargetEvent implements android.os.Parcelable { @@ -1100,6 +1099,7 @@ package android.media { public class AudioManager { method @RequiresPermission("android.permission.MODIFY_AUDIO_ROUTING") public int dispatchAudioFocusChange(@NonNull android.media.AudioFocusInfo, int, @NonNull android.media.audiopolicy.AudioPolicy); + method public boolean hasRegisteredDynamicPolicy(); method @RequiresPermission("android.permission.MODIFY_AUDIO_ROUTING") public int registerAudioPolicy(@NonNull android.media.audiopolicy.AudioPolicy); method @RequiresPermission("android.permission.MODIFY_AUDIO_ROUTING") public void setFocusRequestResult(@NonNull android.media.AudioFocusInfo, int, @NonNull android.media.audiopolicy.AudioPolicy); method @RequiresPermission("android.permission.MODIFY_AUDIO_ROUTING") public void unregisterAudioPolicy(@NonNull android.media.audiopolicy.AudioPolicy); @@ -2212,7 +2212,6 @@ package android.provider { public final class DeviceConfig { method @RequiresPermission("android.permission.READ_DEVICE_CONFIG") public static void addOnPropertiesChangedListener(@NonNull String, @NonNull java.util.concurrent.Executor, @NonNull android.provider.DeviceConfig.OnPropertiesChangedListener); - method @RequiresPermission("android.permission.READ_DEVICE_CONFIG") public static void addOnPropertyChangedListener(@NonNull String, @NonNull java.util.concurrent.Executor, @NonNull android.provider.DeviceConfig.OnPropertyChangedListener); method @RequiresPermission("android.permission.READ_DEVICE_CONFIG") public static boolean getBoolean(@NonNull String, @NonNull String, boolean); method @RequiresPermission("android.permission.READ_DEVICE_CONFIG") public static float getFloat(@NonNull String, @NonNull String, float); method @RequiresPermission("android.permission.READ_DEVICE_CONFIG") public static int getInt(@NonNull String, @NonNull String, int); @@ -2220,7 +2219,6 @@ package android.provider { method @RequiresPermission("android.permission.READ_DEVICE_CONFIG") public static String getProperty(@NonNull String, @NonNull String); method @RequiresPermission("android.permission.READ_DEVICE_CONFIG") public static String getString(@NonNull String, @NonNull String, @Nullable String); method public static void removeOnPropertiesChangedListener(@NonNull android.provider.DeviceConfig.OnPropertiesChangedListener); - method public static void removeOnPropertyChangedListener(@NonNull android.provider.DeviceConfig.OnPropertyChangedListener); method @RequiresPermission(android.Manifest.permission.WRITE_DEVICE_CONFIG) public static void resetToDefaults(int, @Nullable String); method @RequiresPermission(android.Manifest.permission.WRITE_DEVICE_CONFIG) public static boolean setProperty(@NonNull String, @NonNull String, @Nullable String, boolean); field public static final String NAMESPACE_AUTOFILL = "autofill"; @@ -2234,10 +2232,6 @@ package android.provider { method public void onPropertiesChanged(@NonNull android.provider.DeviceConfig.Properties); } - public static interface DeviceConfig.OnPropertyChangedListener { - method public void onPropertyChanged(@NonNull String, @NonNull String, @Nullable String); - } - public static class DeviceConfig.Properties { method public boolean getBoolean(@NonNull String, boolean); method public float getFloat(@NonNull String, float); @@ -2551,9 +2545,9 @@ package android.service.contentcapture { method public void onConnected(); method public void onContentCaptureEvent(@NonNull android.view.contentcapture.ContentCaptureSessionId, @NonNull android.view.contentcapture.ContentCaptureEvent); method public void onCreateContentCaptureSession(@NonNull android.view.contentcapture.ContentCaptureContext, @NonNull android.view.contentcapture.ContentCaptureSessionId); + method public void onDataRemovalRequest(@NonNull android.view.contentcapture.DataRemovalRequest); method public void onDestroyContentCaptureSession(@NonNull android.view.contentcapture.ContentCaptureSessionId); method public void onDisconnected(); - method public void onUserDataRemovalRequest(@NonNull android.view.contentcapture.UserDataRemovalRequest); method public final void setContentCaptureConditions(@NonNull String, @Nullable java.util.Set<android.view.contentcapture.ContentCaptureCondition>); method public final void setContentCaptureWhitelist(@Nullable java.util.Set<java.lang.String>, @Nullable java.util.Set<android.content.ComponentName>); field public static final String SERVICE_INTERFACE = "android.service.contentcapture.ContentCaptureService"; diff --git a/api/test-removed.txt b/api/test-removed.txt index d802177e249b..83a5708a2eb3 100644 --- a/api/test-removed.txt +++ b/api/test-removed.txt @@ -1 +1,14 @@ // Signature format: 2.0 +package android.provider { + + public final class DeviceConfig { + method @RequiresPermission("android.permission.READ_DEVICE_CONFIG") public static void addOnPropertyChangedListener(@NonNull String, @NonNull java.util.concurrent.Executor, @NonNull android.provider.DeviceConfig.OnPropertyChangedListener); + method public static void removeOnPropertyChangedListener(@NonNull android.provider.DeviceConfig.OnPropertyChangedListener); + } + + public static interface DeviceConfig.OnPropertyChangedListener { + method public void onPropertyChanged(@NonNull String, @NonNull String, @Nullable String); + } + +} + diff --git a/cmds/idmap2/idmap2/Create.cpp b/cmds/idmap2/idmap2/Create.cpp index 47617e045c12..bb8d92737563 100644 --- a/cmds/idmap2/idmap2/Create.cpp +++ b/cmds/idmap2/idmap2/Create.cpp @@ -16,6 +16,7 @@ #include <sys/stat.h> // umask #include <sys/types.h> // umask + #include <fstream> #include <memory> #include <ostream> diff --git a/cmds/idmap2/idmap2/Lookup.cpp b/cmds/idmap2/idmap2/Lookup.cpp index 677c6fa155dd..b7ae9d090cee 100644 --- a/cmds/idmap2/idmap2/Lookup.cpp +++ b/cmds/idmap2/idmap2/Lookup.cpp @@ -31,15 +31,14 @@ #include "androidfw/ResourceUtils.h" #include "androidfw/StringPiece.h" #include "androidfw/Util.h" -#include "utils/String16.h" -#include "utils/String8.h" - #include "idmap2/CommandLineOptions.h" #include "idmap2/Idmap.h" #include "idmap2/Result.h" #include "idmap2/SysTrace.h" #include "idmap2/Xml.h" #include "idmap2/ZipFile.h" +#include "utils/String16.h" +#include "utils/String8.h" using android::ApkAssets; using android::ApkAssetsCookie; diff --git a/cmds/idmap2/idmap2/Main.cpp b/cmds/idmap2/idmap2/Main.cpp index d8867fe8f497..87949085cf1d 100644 --- a/cmds/idmap2/idmap2/Main.cpp +++ b/cmds/idmap2/idmap2/Main.cpp @@ -23,12 +23,11 @@ #include <string> #include <vector> +#include "Commands.h" #include "idmap2/CommandLineOptions.h" #include "idmap2/Result.h" #include "idmap2/SysTrace.h" -#include "Commands.h" - using android::idmap2::CommandLineOptions; using android::idmap2::Result; using android::idmap2::Unit; diff --git a/cmds/idmap2/idmap2/Scan.cpp b/cmds/idmap2/idmap2/Scan.cpp index 55b1003c38af..fa9a77aa69c6 100644 --- a/cmds/idmap2/idmap2/Scan.cpp +++ b/cmds/idmap2/idmap2/Scan.cpp @@ -15,6 +15,7 @@ */ #include <dirent.h> + #include <fstream> #include <memory> #include <ostream> @@ -24,8 +25,8 @@ #include <utility> #include <vector> +#include "Commands.h" #include "android-base/properties.h" - #include "idmap2/CommandLineOptions.h" #include "idmap2/FileUtils.h" #include "idmap2/Idmap.h" @@ -35,8 +36,6 @@ #include "idmap2/Xml.h" #include "idmap2/ZipFile.h" -#include "Commands.h" - using android::idmap2::CommandLineOptions; using android::idmap2::Error; using android::idmap2::Idmap; @@ -211,7 +210,9 @@ Result<Unit> Scan(const std::vector<std::string>& args) { const auto create_ok = Create(create_args); if (!create_ok) { - return Error(create_ok.GetError(), "failed to create idmap"); + LOG(WARNING) << "failed to create idmap for overlay apk path \"" << overlay.apk_path + << "\": " << create_ok.GetError().GetMessage(); + continue; } } diff --git a/cmds/idmap2/idmap2d/Idmap2Service.cpp b/cmds/idmap2/idmap2d/Idmap2Service.cpp index 4f653796ce3f..8ee79f61520a 100644 --- a/cmds/idmap2/idmap2d/Idmap2Service.cpp +++ b/cmds/idmap2/idmap2d/Idmap2Service.cpp @@ -14,6 +14,8 @@ * limitations under the License. */ +#include "idmap2d/Idmap2Service.h" + #include <sys/stat.h> // umask #include <sys/types.h> // umask #include <unistd.h> @@ -28,15 +30,12 @@ #include "android-base/macros.h" #include "android-base/stringprintf.h" #include "binder/IPCThreadState.h" -#include "utils/String8.h" - #include "idmap2/BinaryStreamVisitor.h" #include "idmap2/FileUtils.h" #include "idmap2/Idmap.h" #include "idmap2/Policies.h" #include "idmap2/SysTrace.h" - -#include "idmap2d/Idmap2Service.h" +#include "utils/String8.h" using android::IPCThreadState; using android::binder::Status; diff --git a/cmds/idmap2/idmap2d/Main.cpp b/cmds/idmap2/idmap2d/Main.cpp index 4393dcc130ec..2707049fa677 100644 --- a/cmds/idmap2/idmap2d/Main.cpp +++ b/cmds/idmap2/idmap2d/Main.cpp @@ -21,13 +21,11 @@ #include <binder/ProcessState.h> #include <cstdlib> // EXIT_{FAILURE,SUCCESS} - #include <iostream> #include <sstream> -#include "android-base/macros.h" - #include "Idmap2Service.h" +#include "android-base/macros.h" using android::BinderService; using android::IPCThreadState; diff --git a/cmds/idmap2/include/idmap2/Idmap.h b/cmds/idmap2/include/idmap2/Idmap.h index 5cc0664b2bed..ebbb5ffc989d 100644 --- a/cmds/idmap2/include/idmap2/Idmap.h +++ b/cmds/idmap2/include/idmap2/Idmap.h @@ -52,11 +52,9 @@ #include <vector> #include "android-base/macros.h" - #include "androidfw/ApkAssets.h" #include "androidfw/ResourceTypes.h" #include "androidfw/StringPiece.h" - #include "idmap2/Policies.h" namespace android::idmap2 { diff --git a/cmds/idmap2/include/idmap2/Policies.h b/cmds/idmap2/include/idmap2/Policies.h index cd76b84ccc0a..90c698cc6e49 100644 --- a/cmds/idmap2/include/idmap2/Policies.h +++ b/cmds/idmap2/include/idmap2/Policies.h @@ -17,11 +17,10 @@ #include <string> #include <vector> +#include "Result.h" #include "androidfw/ResourceTypes.h" #include "androidfw/StringPiece.h" -#include "Result.h" - #ifndef IDMAP2_INCLUDE_IDMAP2_POLICIES_H_ #define IDMAP2_INCLUDE_IDMAP2_POLICIES_H_ diff --git a/cmds/idmap2/include/idmap2/PrettyPrintVisitor.h b/cmds/idmap2/include/idmap2/PrettyPrintVisitor.h index c388f4b94251..5111bb2eaab2 100644 --- a/cmds/idmap2/include/idmap2/PrettyPrintVisitor.h +++ b/cmds/idmap2/include/idmap2/PrettyPrintVisitor.h @@ -21,7 +21,6 @@ #include <memory> #include "androidfw/AssetManager2.h" - #include "idmap2/Idmap.h" namespace android { diff --git a/cmds/idmap2/include/idmap2/RawPrintVisitor.h b/cmds/idmap2/include/idmap2/RawPrintVisitor.h index 7e33b3b06fc3..2e543d4fabdd 100644 --- a/cmds/idmap2/include/idmap2/RawPrintVisitor.h +++ b/cmds/idmap2/include/idmap2/RawPrintVisitor.h @@ -22,7 +22,6 @@ #include <string> #include "androidfw/AssetManager2.h" - #include "idmap2/Idmap.h" namespace android { diff --git a/cmds/idmap2/include/idmap2/ResourceUtils.h b/cmds/idmap2/include/idmap2/ResourceUtils.h index 1d81c486d504..8797a788dd1d 100644 --- a/cmds/idmap2/include/idmap2/ResourceUtils.h +++ b/cmds/idmap2/include/idmap2/ResourceUtils.h @@ -21,7 +21,6 @@ #include <string> #include "androidfw/AssetManager2.h" - #include "idmap2/Idmap.h" #include "idmap2/Result.h" #include "idmap2/ZipFile.h" diff --git a/cmds/idmap2/libidmap2/BinaryStreamVisitor.cpp b/cmds/idmap2/libidmap2/BinaryStreamVisitor.cpp index 96513283ac51..dee2d219cbe1 100644 --- a/cmds/idmap2/libidmap2/BinaryStreamVisitor.cpp +++ b/cmds/idmap2/libidmap2/BinaryStreamVisitor.cpp @@ -14,14 +14,14 @@ * limitations under the License. */ +#include "idmap2/BinaryStreamVisitor.h" + #include <algorithm> #include <cstring> #include <string> #include "android-base/macros.h" -#include "idmap2/BinaryStreamVisitor.h" - namespace android::idmap2 { void BinaryStreamVisitor::Write16(uint16_t value) { diff --git a/cmds/idmap2/libidmap2/CommandLineOptions.cpp b/cmds/idmap2/libidmap2/CommandLineOptions.cpp index d5fd2ce38b11..5b0ae92df887 100644 --- a/cmds/idmap2/libidmap2/CommandLineOptions.cpp +++ b/cmds/idmap2/libidmap2/CommandLineOptions.cpp @@ -14,6 +14,8 @@ * limitations under the License. */ +#include "idmap2/CommandLineOptions.h" + #include <algorithm> #include <iomanip> #include <iostream> @@ -24,8 +26,6 @@ #include <vector> #include "android-base/macros.h" - -#include "idmap2/CommandLineOptions.h" #include "idmap2/Result.h" namespace android::idmap2 { diff --git a/cmds/idmap2/libidmap2/FileUtils.cpp b/cmds/idmap2/libidmap2/FileUtils.cpp index a9b68cd6d5d5..3e8e32989a09 100644 --- a/cmds/idmap2/libidmap2/FileUtils.cpp +++ b/cmds/idmap2/libidmap2/FileUtils.cpp @@ -14,6 +14,8 @@ * limitations under the License. */ +#include "idmap2/FileUtils.h" + #include <dirent.h> #include <sys/types.h> #include <unistd.h> @@ -33,8 +35,6 @@ #include "android-base/stringprintf.h" #include "private/android_filesystem_config.h" -#include "idmap2/FileUtils.h" - namespace android::idmap2::utils { std::unique_ptr<std::vector<std::string>> FindFiles(const std::string& root, bool recurse, diff --git a/cmds/idmap2/libidmap2/Idmap.cpp b/cmds/idmap2/libidmap2/Idmap.cpp index 49470b4f4e95..aec1a6fc2bae 100644 --- a/cmds/idmap2/libidmap2/Idmap.cpp +++ b/cmds/idmap2/libidmap2/Idmap.cpp @@ -14,6 +14,8 @@ * limitations under the License. */ +#include "idmap2/Idmap.h" + #include <algorithm> #include <iostream> #include <iterator> @@ -28,14 +30,12 @@ #include "android-base/macros.h" #include "android-base/stringprintf.h" #include "androidfw/AssetManager2.h" -#include "utils/String16.h" -#include "utils/String8.h" - -#include "idmap2/Idmap.h" #include "idmap2/ResourceUtils.h" #include "idmap2/Result.h" #include "idmap2/SysTrace.h" #include "idmap2/ZipFile.h" +#include "utils/String16.h" +#include "utils/String8.h" namespace android::idmap2 { diff --git a/cmds/idmap2/libidmap2/Policies.cpp b/cmds/idmap2/libidmap2/Policies.cpp index 7c4555633fd2..0a0cecf13932 100644 --- a/cmds/idmap2/libidmap2/Policies.cpp +++ b/cmds/idmap2/libidmap2/Policies.cpp @@ -14,15 +14,15 @@ * limitations under the License. */ +#include "idmap2/Policies.h" + #include <iterator> #include <map> #include <string> #include <vector> #include "androidfw/ResourceTypes.h" - #include "idmap2/Idmap.h" -#include "idmap2/Policies.h" #include "idmap2/Result.h" namespace android::idmap2 { diff --git a/cmds/idmap2/libidmap2/PrettyPrintVisitor.cpp b/cmds/idmap2/libidmap2/PrettyPrintVisitor.cpp index fc9677994fc0..fbf2c777be9a 100644 --- a/cmds/idmap2/libidmap2/PrettyPrintVisitor.cpp +++ b/cmds/idmap2/libidmap2/PrettyPrintVisitor.cpp @@ -14,13 +14,13 @@ * limitations under the License. */ +#include "idmap2/PrettyPrintVisitor.h" + #include <string> #include "android-base/macros.h" #include "android-base/stringprintf.h" #include "androidfw/ApkAssets.h" - -#include "idmap2/PrettyPrintVisitor.h" #include "idmap2/ResourceUtils.h" #include "idmap2/Result.h" diff --git a/cmds/idmap2/libidmap2/RawPrintVisitor.cpp b/cmds/idmap2/libidmap2/RawPrintVisitor.cpp index 1149c905a178..dd14fd47aea8 100644 --- a/cmds/idmap2/libidmap2/RawPrintVisitor.cpp +++ b/cmds/idmap2/libidmap2/RawPrintVisitor.cpp @@ -14,14 +14,14 @@ * limitations under the License. */ +#include "idmap2/RawPrintVisitor.h" + #include <cstdarg> #include <string> #include "android-base/macros.h" #include "android-base/stringprintf.h" #include "androidfw/ApkAssets.h" - -#include "idmap2/RawPrintVisitor.h" #include "idmap2/ResourceUtils.h" #include "idmap2/Result.h" diff --git a/cmds/idmap2/libidmap2/ResourceUtils.cpp b/cmds/idmap2/libidmap2/ResourceUtils.cpp index a24836da7f3a..71ba3f0f1ac2 100644 --- a/cmds/idmap2/libidmap2/ResourceUtils.cpp +++ b/cmds/idmap2/libidmap2/ResourceUtils.cpp @@ -14,13 +14,13 @@ * limitations under the License. */ +#include "idmap2/ResourceUtils.h" + #include <memory> #include <string> #include "androidfw/StringPiece.h" #include "androidfw/Util.h" - -#include "idmap2/ResourceUtils.h" #include "idmap2/Result.h" #include "idmap2/Xml.h" #include "idmap2/ZipFile.h" diff --git a/cmds/idmap2/libidmap2/Result.cpp b/cmds/idmap2/libidmap2/Result.cpp index 471dab2e0411..1eac25f1b955 100644 --- a/cmds/idmap2/libidmap2/Result.cpp +++ b/cmds/idmap2/libidmap2/Result.cpp @@ -14,12 +14,12 @@ * limitations under the License. */ +#include "idmap2/Result.h" + #include <cstdarg> #include "android-base/stringprintf.h" -#include "idmap2/Result.h" - namespace android::idmap2 { // NOLINTNEXTLINE(cert-dcl50-cpp) diff --git a/cmds/idmap2/libidmap2/Xml.cpp b/cmds/idmap2/libidmap2/Xml.cpp index 0075a922d676..264586829c47 100644 --- a/cmds/idmap2/libidmap2/Xml.cpp +++ b/cmds/idmap2/libidmap2/Xml.cpp @@ -14,13 +14,13 @@ * limitations under the License. */ +#include "idmap2/Xml.h" + #include <map> #include <memory> #include <string> #include <utility> -#include "idmap2/Xml.h" - namespace android::idmap2 { std::unique_ptr<const Xml> Xml::Create(const uint8_t* data, size_t size, bool copyData) { diff --git a/cmds/idmap2/libidmap2/ZipFile.cpp b/cmds/idmap2/libidmap2/ZipFile.cpp index 0f0732466256..812fd6eacbf9 100644 --- a/cmds/idmap2/libidmap2/ZipFile.cpp +++ b/cmds/idmap2/libidmap2/ZipFile.cpp @@ -14,11 +14,12 @@ * limitations under the License. */ +#include "idmap2/ZipFile.h" + #include <memory> #include <string> #include "idmap2/Result.h" -#include "idmap2/ZipFile.h" namespace android::idmap2 { diff --git a/cmds/idmap2/tests/BinaryStreamVisitorTests.cpp b/cmds/idmap2/tests/BinaryStreamVisitorTests.cpp index 9a5b6331cb20..9cdc86ca181a 100644 --- a/cmds/idmap2/tests/BinaryStreamVisitorTests.cpp +++ b/cmds/idmap2/tests/BinaryStreamVisitorTests.cpp @@ -19,17 +19,14 @@ #include <string> #include <utility> -#include "gmock/gmock.h" -#include "gtest/gtest.h" - +#include "TestHelpers.h" #include "androidfw/ApkAssets.h" #include "androidfw/Idmap.h" - +#include "gmock/gmock.h" +#include "gtest/gtest.h" #include "idmap2/BinaryStreamVisitor.h" #include "idmap2/Idmap.h" -#include "TestHelpers.h" - using ::testing::NotNull; namespace android::idmap2 { diff --git a/cmds/idmap2/tests/CommandLineOptionsTests.cpp b/cmds/idmap2/tests/CommandLineOptionsTests.cpp index d567af64b16a..6e83fc9abdb1 100644 --- a/cmds/idmap2/tests/CommandLineOptionsTests.cpp +++ b/cmds/idmap2/tests/CommandLineOptionsTests.cpp @@ -25,19 +25,16 @@ #include <string> #include <vector> -#include "gmock/gmock.h" -#include "gtest/gtest.h" - +#include "TestHelpers.h" #include "android-base/file.h" #include "androidfw/ApkAssets.h" #include "androidfw/Idmap.h" #include "androidfw/LoadedArsc.h" - +#include "gmock/gmock.h" +#include "gtest/gtest.h" #include "idmap2/CommandLineOptions.h" #include "idmap2/Idmap.h" -#include "TestHelpers.h" - namespace android::idmap2 { TEST(CommandLineOptionsTests, Flag) { diff --git a/cmds/idmap2/tests/FileUtilsTests.cpp b/cmds/idmap2/tests/FileUtilsTests.cpp index 34a0097b0316..f4a306e41e32 100644 --- a/cmds/idmap2/tests/FileUtilsTests.cpp +++ b/cmds/idmap2/tests/FileUtilsTests.cpp @@ -15,19 +15,17 @@ */ #include <dirent.h> + #include <set> #include <string> -#include "gmock/gmock.h" -#include "gtest/gtest.h" - +#include "TestHelpers.h" #include "android-base/macros.h" #include "android-base/stringprintf.h" -#include "private/android_filesystem_config.h" - +#include "gmock/gmock.h" +#include "gtest/gtest.h" #include "idmap2/FileUtils.h" - -#include "TestHelpers.h" +#include "private/android_filesystem_config.h" using ::testing::NotNull; diff --git a/cmds/idmap2/tests/Idmap2BinaryTests.cpp b/cmds/idmap2/tests/Idmap2BinaryTests.cpp index 91bc4ddb397f..c18744ccb2d5 100644 --- a/cmds/idmap2/tests/Idmap2BinaryTests.cpp +++ b/cmds/idmap2/tests/Idmap2BinaryTests.cpp @@ -34,16 +34,13 @@ #include <string> #include <vector> +#include "TestHelpers.h" +#include "androidfw/PosixUtils.h" #include "gmock/gmock.h" #include "gtest/gtest.h" - -#include "androidfw/PosixUtils.h" -#include "private/android_filesystem_config.h" - #include "idmap2/FileUtils.h" #include "idmap2/Idmap.h" - -#include "TestHelpers.h" +#include "private/android_filesystem_config.h" using ::android::util::ExecuteBinary; using ::testing::NotNull; @@ -264,6 +261,24 @@ TEST_F(Idmap2BinaryTests, Scan) { ASSERT_THAT(result, NotNull()); ASSERT_EQ(result->status, EXIT_SUCCESS) << result->stderr; ASSERT_EQ(result->stdout, ""); + + // the signature idmap failing to generate should not cause scanning to fail + // clang-format off + result = ExecuteBinary({"idmap2", + "scan", + "--input-directory", GetTestDataPath(), + "--recursive", + "--target-package-name", "test.target", + "--target-apk-path", GetTargetApkPath(), + "--output-directory", GetTempDirPath(), + "--override-policy", "public"}); + // clang-format on + ASSERT_THAT(result, NotNull()); + ASSERT_EQ(result->status, EXIT_SUCCESS) << result->stderr; + ASSERT_EQ(result->stdout, expected.str()); + unlink(idmap_static_no_name_path.c_str()); + unlink(idmap_static_2_path.c_str()); + unlink(idmap_static_1_path.c_str()); } TEST_F(Idmap2BinaryTests, Lookup) { diff --git a/cmds/idmap2/tests/IdmapTests.cpp b/cmds/idmap2/tests/IdmapTests.cpp index 621f50337aa3..90fe9a79bd1f 100644 --- a/cmds/idmap2/tests/IdmapTests.cpp +++ b/cmds/idmap2/tests/IdmapTests.cpp @@ -15,7 +15,6 @@ */ #include <cstdio> // fclose - #include <fstream> #include <memory> #include <sstream> @@ -23,18 +22,15 @@ #include <utility> #include <vector> -#include "gmock/gmock.h" -#include "gtest/gtest.h" - +#include "TestHelpers.h" #include "android-base/macros.h" #include "androidfw/ApkAssets.h" - +#include "gmock/gmock.h" +#include "gtest/gtest.h" #include "idmap2/BinaryStreamVisitor.h" #include "idmap2/CommandLineOptions.h" #include "idmap2/Idmap.h" -#include "TestHelpers.h" - using ::testing::IsNull; using ::testing::NotNull; diff --git a/cmds/idmap2/tests/Main.cpp b/cmds/idmap2/tests/Main.cpp index 2b13fed8d60d..3e753e974465 100644 --- a/cmds/idmap2/tests/Main.cpp +++ b/cmds/idmap2/tests/Main.cpp @@ -16,12 +16,10 @@ #include <string> +#include "TestHelpers.h" #include "android-base/file.h" - #include "gtest/gtest.h" -#include "TestHelpers.h" - namespace android::idmap2 { std::string GetTestDataPath() { diff --git a/cmds/idmap2/tests/PoliciesTests.cpp b/cmds/idmap2/tests/PoliciesTests.cpp index a76da533cdcb..e30da76ddd98 100644 --- a/cmds/idmap2/tests/PoliciesTests.cpp +++ b/cmds/idmap2/tests/PoliciesTests.cpp @@ -16,9 +16,8 @@ #include <string> -#include "gtest/gtest.h" - #include "TestHelpers.h" +#include "gtest/gtest.h" #include "idmap2/Policies.h" using android::idmap2::PolicyBitmask; diff --git a/cmds/idmap2/tests/PrettyPrintVisitorTests.cpp b/cmds/idmap2/tests/PrettyPrintVisitorTests.cpp index 27a3880f67b6..c41250457678 100644 --- a/cmds/idmap2/tests/PrettyPrintVisitorTests.cpp +++ b/cmds/idmap2/tests/PrettyPrintVisitorTests.cpp @@ -18,18 +18,15 @@ #include <sstream> #include <string> -#include "gmock/gmock.h" -#include "gtest/gtest.h" - +#include "TestHelpers.h" #include "androidfw/ApkAssets.h" #include "androidfw/Idmap.h" - +#include "gmock/gmock.h" +#include "gtest/gtest.h" #include "idmap2/Idmap.h" #include "idmap2/Policies.h" #include "idmap2/PrettyPrintVisitor.h" -#include "TestHelpers.h" - using ::testing::NotNull; using android::ApkAssets; diff --git a/cmds/idmap2/tests/RawPrintVisitorTests.cpp b/cmds/idmap2/tests/RawPrintVisitorTests.cpp index 7372148f0f0e..64518fdf8dee 100644 --- a/cmds/idmap2/tests/RawPrintVisitorTests.cpp +++ b/cmds/idmap2/tests/RawPrintVisitorTests.cpp @@ -19,14 +19,12 @@ #include <sstream> #include <string> +#include "TestHelpers.h" #include "gmock/gmock.h" #include "gtest/gtest.h" - #include "idmap2/Idmap.h" #include "idmap2/RawPrintVisitor.h" -#include "TestHelpers.h" - using ::testing::NotNull; namespace android::idmap2 { diff --git a/cmds/idmap2/tests/ResourceUtilsTests.cpp b/cmds/idmap2/tests/ResourceUtilsTests.cpp index ad78685646b4..9ed807ccd8f9 100644 --- a/cmds/idmap2/tests/ResourceUtilsTests.cpp +++ b/cmds/idmap2/tests/ResourceUtilsTests.cpp @@ -17,15 +17,13 @@ #include <memory> #include <string> +#include "TestHelpers.h" +#include "androidfw/ApkAssets.h" #include "gmock/gmock.h" #include "gtest/gtest.h" - -#include "androidfw/ApkAssets.h" #include "idmap2/ResourceUtils.h" #include "idmap2/Result.h" -#include "TestHelpers.h" - using ::testing::NotNull; namespace android::idmap2 { diff --git a/cmds/idmap2/tests/ResultTests.cpp b/cmds/idmap2/tests/ResultTests.cpp index 5f4daed521c0..cbced0ae32fb 100644 --- a/cmds/idmap2/tests/ResultTests.cpp +++ b/cmds/idmap2/tests/ResultTests.cpp @@ -20,7 +20,6 @@ #include "gmock/gmock.h" #include "gtest/gtest.h" - #include "idmap2/Result.h" namespace android::idmap2 { diff --git a/cmds/idmap2/tests/TestHelpers.h b/cmds/idmap2/tests/TestHelpers.h index 45525a5b7657..adea3293534d 100644 --- a/cmds/idmap2/tests/TestHelpers.h +++ b/cmds/idmap2/tests/TestHelpers.h @@ -19,6 +19,9 @@ #include <string> +#include "gmock/gmock.h" +#include "gtest/gtest.h" + namespace android::idmap2 { const unsigned char idmap_raw_data[] = { diff --git a/cmds/idmap2/tests/XmlTests.cpp b/cmds/idmap2/tests/XmlTests.cpp index fe79d8f2c5a9..df63211a9209 100644 --- a/cmds/idmap2/tests/XmlTests.cpp +++ b/cmds/idmap2/tests/XmlTests.cpp @@ -16,13 +16,11 @@ #include <cstdio> // fclose -#include "idmap2/Xml.h" -#include "idmap2/ZipFile.h" - +#include "TestHelpers.h" #include "gmock/gmock.h" #include "gtest/gtest.h" - -#include "TestHelpers.h" +#include "idmap2/Xml.h" +#include "idmap2/ZipFile.h" using ::testing::IsNull; using ::testing::NotNull; diff --git a/cmds/idmap2/tests/ZipFileTests.cpp b/cmds/idmap2/tests/ZipFileTests.cpp index 79be43ce0e42..3fca43621945 100644 --- a/cmds/idmap2/tests/ZipFileTests.cpp +++ b/cmds/idmap2/tests/ZipFileTests.cpp @@ -17,13 +17,11 @@ #include <cstdio> // fclose #include <string> -#include "idmap2/Result.h" -#include "idmap2/ZipFile.h" - +#include "TestHelpers.h" #include "gmock/gmock.h" #include "gtest/gtest.h" - -#include "TestHelpers.h" +#include "idmap2/Result.h" +#include "idmap2/ZipFile.h" using ::testing::IsNull; using ::testing::NotNull; diff --git a/cmds/idmap2/tests/data/signature-overlay/AndroidManifest.xml b/cmds/idmap2/tests/data/signature-overlay/AndroidManifest.xml index 9e6a4536cb51..5df0bea555b1 100644 --- a/cmds/idmap2/tests/data/signature-overlay/AndroidManifest.xml +++ b/cmds/idmap2/tests/data/signature-overlay/AndroidManifest.xml @@ -19,5 +19,7 @@ <application android:hasCode="false"/> <overlay android:targetPackage="test.target" - android:targetName="TestResources"/> + android:targetName="TestResources" + android:isStatic="true" + android:priority="10"/> </manifest> diff --git a/cmds/idmap2/tests/data/signature-overlay/signature-overlay.apk b/cmds/idmap2/tests/data/signature-overlay/signature-overlay.apk Binary files differindex b2c490dcbb90..51e19de082ed 100644 --- a/cmds/idmap2/tests/data/signature-overlay/signature-overlay.apk +++ b/cmds/idmap2/tests/data/signature-overlay/signature-overlay.apk diff --git a/core/java/android/app/TaskInfo.java b/core/java/android/app/TaskInfo.java index dd00e5a74382..de64db9def64 100644 --- a/core/java/android/app/TaskInfo.java +++ b/core/java/android/app/TaskInfo.java @@ -16,6 +16,8 @@ package android.app; +import android.annotation.NonNull; +import android.annotation.Nullable; import android.annotation.UnsupportedAppUsage; import android.content.ComponentName; import android.content.Intent; @@ -58,23 +60,27 @@ public class TaskInfo { * The base intent of the task (generally the intent that launched the task). This intent can * be used to relaunch the task (if it is no longer running) or brought to the front if it is. */ + @NonNull public Intent baseIntent; /** * The component of the first activity in the task, can be considered the "application" of this * task. */ + @Nullable public ComponentName baseActivity; /** * The component of the top activity in the task, currently showing to the user. */ + @Nullable public ComponentName topActivity; /** * The component of the target activity if this task was started from an activity alias. * Otherwise, this is null. */ + @Nullable public ComponentName origActivity; /** @@ -82,6 +88,7 @@ public class TaskInfo { * alias). * @hide */ + @Nullable public ComponentName realActivity; /** @@ -106,6 +113,7 @@ public class TaskInfo { * The recent activity values for the highest activity in the stack to have set the values. * {@link Activity#setTaskDescription(android.app.ActivityManager.TaskDescription)}. */ + @Nullable public ActivityManager.TaskDescription taskDescription; /** @@ -126,6 +134,7 @@ public class TaskInfo { * The current configuration of the task. * @hide */ + @NonNull @UnsupportedAppUsage public final Configuration configuration = new Configuration(); diff --git a/core/java/android/app/prediction/AppTarget.java b/core/java/android/app/prediction/AppTarget.java index ed45b2f45383..4704661c2b24 100644 --- a/core/java/android/app/prediction/AppTarget.java +++ b/core/java/android/app/prediction/AppTarget.java @@ -204,24 +204,49 @@ public final class AppTarget implements Parcelable { private int mRank; /** - * @param id A unique id for this launchable target. + * @deprecated Use the other Builder constructors. * @hide */ - @SystemApi - @TestApi + @Deprecated public Builder(@NonNull AppTargetId id) { mId = id; } /** - * Sets the target to be an app. - * - * @param packageName PackageName of the app + * @param id A unique id for this launchable target. + * @param packageName PackageName of the target. * @param user The UserHandle of the user which this target belongs to. - * - * @throws IllegalArgumentException is the target is already set + * @hide + */ + @SystemApi + @TestApi + public Builder(@NonNull AppTargetId id, @NonNull String packageName, + @NonNull UserHandle user) { + mId = Preconditions.checkNotNull(id); + mPackageName = Preconditions.checkNotNull(packageName); + mUser = Preconditions.checkNotNull(user); + } + + /** + * @param id A unique id for this launchable target. + * @param info The ShortcutInfo that represents this launchable target. + * @hide + */ + @SystemApi + @TestApi + public Builder(@NonNull AppTargetId id, @NonNull ShortcutInfo info) { + mId = Preconditions.checkNotNull(id); + mShortcutInfo = Preconditions.checkNotNull(info); + mPackageName = info.getPackage(); + mUser = info.getUserHandle(); + } + + /** + * @deprecated Use the appropriate constructor. + * @hide */ @NonNull + @Deprecated public Builder setTarget(@NonNull String packageName, @NonNull UserHandle user) { if (mPackageName != null) { throw new IllegalArgumentException("Target is already set"); @@ -232,11 +257,11 @@ public final class AppTarget implements Parcelable { } /** - * Sets the target to be a ShortcutInfo. - * - * @throws IllegalArgumentException is the target is already set + * @deprecated Use the appropriate constructor. + * @hide */ @NonNull + @Deprecated public Builder setTarget(@NonNull ShortcutInfo info) { setTarget(info.getPackage(), info.getUserHandle()); mShortcutInfo = Preconditions.checkNotNull(info); @@ -244,7 +269,7 @@ public final class AppTarget implements Parcelable { } /** - * Sets the className for the target + * Sets the className for the target. */ @NonNull public Builder setClassName(@NonNull String className) { @@ -253,7 +278,7 @@ public final class AppTarget implements Parcelable { } /** - * Sets the rank of the for the target. + * Sets the rank of the target. */ @NonNull public Builder setRank(@IntRange(from = 0) int rank) { @@ -274,7 +299,7 @@ public final class AppTarget implements Parcelable { @NonNull public AppTarget build() { if (mPackageName == null) { - throw new IllegalStateException("No target set"); + throw new IllegalStateException("No target is set"); } return new AppTarget(mId, mPackageName, mUser, mShortcutInfo, mClassName, mRank); } diff --git a/core/java/android/attention/AttentionManagerInternal.java b/core/java/android/attention/AttentionManagerInternal.java index fa3d3b8dea0c..941e9e2ecce5 100644 --- a/core/java/android/attention/AttentionManagerInternal.java +++ b/core/java/android/attention/AttentionManagerInternal.java @@ -46,13 +46,6 @@ public abstract class AttentionManagerInternal { */ public abstract void cancelAttentionCheck(AttentionCallbackInternal callback); - /** - * Disables the dependants. - * - * Example: called if the service does not have sufficient permissions to perform the task. - */ - public abstract void disableSelf(); - /** Internal interface for attention callback. */ public abstract static class AttentionCallbackInternal { /** diff --git a/core/java/android/content/ContentProviderOperation.java b/core/java/android/content/ContentProviderOperation.java index a41b5d3fb781..a646e49f4f61 100644 --- a/core/java/android/content/ContentProviderOperation.java +++ b/core/java/android/content/ContentProviderOperation.java @@ -17,7 +17,6 @@ package android.content; import android.annotation.UnsupportedAppUsage; -import android.content.ContentProvider; import android.database.Cursor; import android.net.Uri; import android.os.Parcel; @@ -59,6 +58,7 @@ public class ContentProviderOperation implements Parcelable { private final ContentValues mValuesBackReferences; private final Map<Integer, Integer> mSelectionArgsBackReferences; private final boolean mYieldAllowed; + private final boolean mFailureAllowed; private final static String TAG = "ContentProviderOperation"; @@ -76,6 +76,7 @@ public class ContentProviderOperation implements Parcelable { mSelectionArgsBackReferences = builder.mSelectionArgsBackReferences; mValuesBackReferences = builder.mValuesBackReferences; mYieldAllowed = builder.mYieldAllowed; + mFailureAllowed = builder.mFailureAllowed; } private ContentProviderOperation(Parcel source) { @@ -98,6 +99,7 @@ public class ContentProviderOperation implements Parcelable { } } mYieldAllowed = source.readInt() != 0; + mFailureAllowed = source.readInt() != 0; } /** @hide */ @@ -111,6 +113,7 @@ public class ContentProviderOperation implements Parcelable { mSelectionArgsBackReferences = cpo.mSelectionArgsBackReferences; mValuesBackReferences = cpo.mValuesBackReferences; mYieldAllowed = cpo.mYieldAllowed; + mFailureAllowed = cpo.mFailureAllowed; } public void writeToParcel(Parcel dest, int flags) { @@ -157,6 +160,7 @@ public class ContentProviderOperation implements Parcelable { dest.writeInt(0); } dest.writeInt(mYieldAllowed ? 1 : 0); + dest.writeInt(mFailureAllowed ? 1 : 0); } /** @@ -212,6 +216,11 @@ public class ContentProviderOperation implements Parcelable { return mYieldAllowed; } + /** {@hide} */ + public boolean isFailureAllowed() { + return mFailureAllowed; + } + /** @hide exposed for unit tests */ @UnsupportedAppUsage public int getType() { @@ -274,6 +283,14 @@ public class ContentProviderOperation implements Parcelable { return mType == TYPE_ASSERT; } + private ContentProviderResult fail(String msg) throws OperationApplicationException { + if (mFailureAllowed) { + return new ContentProviderResult(msg); + } else { + throw new OperationApplicationException(msg); + } + } + /** * Applies this operation using the given provider. The backRefs array is used to resolve any * back references that were requested using @@ -297,7 +314,8 @@ public class ContentProviderOperation implements Parcelable { if (mType == TYPE_INSERT) { Uri newUri = provider.insert(mUri, values); if (newUri == null) { - throw new OperationApplicationException("insert failed"); + Log.e(TAG, this.toString()); + return fail("Insert into " + mUri + " returned no result"); } return new ContentProviderResult(newUri); } @@ -329,7 +347,7 @@ public class ContentProviderOperation implements Parcelable { if (!TextUtils.equals(cursorValue, expectedValue)) { // Throw exception when expected values don't match Log.e(TAG, this.toString()); - throw new OperationApplicationException("Found value " + cursorValue + return fail("Found value " + cursorValue + " when expected " + expectedValue + " for column " + projection[i]); } @@ -346,7 +364,7 @@ public class ContentProviderOperation implements Parcelable { if (mExpectedCount != null && mExpectedCount != numRows) { Log.e(TAG, this.toString()); - throw new OperationApplicationException("wrong number of rows: " + numRows); + return fail("Expected " + mExpectedCount + " rows but actual " + numRows); } return new ContentProviderResult(numRows); @@ -491,6 +509,7 @@ public class ContentProviderOperation implements Parcelable { private ContentValues mValuesBackReferences; private Map<Integer, Integer> mSelectionArgsBackReferences; private boolean mYieldAllowed; + private boolean mFailureAllowed; /** Create a {@link Builder} of a given type. The uri must not be null. */ private Builder(int type, Uri uri) { @@ -683,5 +702,11 @@ public class ContentProviderOperation implements Parcelable { mYieldAllowed = yieldAllowed; return this; } + + /** {@hide} */ + public Builder withFailureAllowed(boolean failureAllowed) { + mFailureAllowed = failureAllowed; + return this; + } } } diff --git a/core/java/android/content/ContentProviderResult.java b/core/java/android/content/ContentProviderResult.java index d90173ceb3cd..b3010116a115 100644 --- a/core/java/android/content/ContentProviderResult.java +++ b/core/java/android/content/ContentProviderResult.java @@ -16,10 +16,11 @@ package android.content; -import android.content.ContentProvider; import android.net.Uri; -import android.os.Parcelable; import android.os.Parcel; +import android.os.Parcelable; + +import com.android.internal.util.Preconditions; /** * Contains the result of the application of a {@link ContentProviderOperation}. It is guaranteed @@ -28,26 +29,44 @@ import android.os.Parcel; public class ContentProviderResult implements Parcelable { public final Uri uri; public final Integer count; + /** {@hide} */ + public final String failure; public ContentProviderResult(Uri uri) { - if (uri == null) throw new IllegalArgumentException("uri must not be null"); - this.uri = uri; - this.count = null; + this(Preconditions.checkNotNull(uri), null, null); } public ContentProviderResult(int count) { + this(null, count, null); + } + + /** {@hide} */ + public ContentProviderResult(String failure) { + this(null, null, failure); + } + + /** {@hide} */ + public ContentProviderResult(Uri uri, Integer count, String failure) { + this.uri = uri; this.count = count; - this.uri = null; + this.failure = failure; } public ContentProviderResult(Parcel source) { - int type = source.readInt(); - if (type == 1) { - count = source.readInt(); + if (source.readInt() != 0) { + uri = Uri.CREATOR.createFromParcel(source); + } else { uri = null; + } + if (source.readInt() != 0) { + count = source.readInt(); } else { count = null; - uri = Uri.CREATOR.createFromParcel(source); + } + if (source.readInt() != 0) { + failure = source.readString(); + } else { + failure = null; } } @@ -55,37 +74,63 @@ public class ContentProviderResult implements Parcelable { public ContentProviderResult(ContentProviderResult cpr, int userId) { uri = ContentProvider.maybeAddUserId(cpr.uri, userId); count = cpr.count; + failure = cpr.failure; } + @Override public void writeToParcel(Parcel dest, int flags) { - if (uri == null) { + if (uri != null) { + dest.writeInt(1); + uri.writeToParcel(dest, flags); + } else { + dest.writeInt(0); + } + if (count != null) { dest.writeInt(1); dest.writeInt(count); } else { - dest.writeInt(2); - uri.writeToParcel(dest, 0); + dest.writeInt(0); + } + if (failure != null) { + dest.writeInt(1); + dest.writeString(failure); + } else { + dest.writeInt(0); } } + @Override public int describeContents() { return 0; } public static final @android.annotation.NonNull Creator<ContentProviderResult> CREATOR = new Creator<ContentProviderResult>() { + @Override public ContentProviderResult createFromParcel(Parcel source) { return new ContentProviderResult(source); } + @Override public ContentProviderResult[] newArray(int size) { return new ContentProviderResult[size]; } }; + @Override public String toString() { + final StringBuilder sb = new StringBuilder("ContentProviderResult("); + if (uri != null) { + sb.append("uri=" + uri + " "); + } + if (count != null) { + sb.append("count=" + count + " "); + } if (uri != null) { - return "ContentProviderResult(uri=" + uri.toString() + ")"; + sb.append("failure=" + failure + " "); } - return "ContentProviderResult(count=" + count + ")"; + sb.deleteCharAt(sb.length() - 1); + sb.append(")"); + return sb.toString(); } } diff --git a/core/java/android/provider/DeviceConfig.java b/core/java/android/provider/DeviceConfig.java index 166de3fde741..6c498c736854 100644 --- a/core/java/android/provider/DeviceConfig.java +++ b/core/java/android/provider/DeviceConfig.java @@ -493,6 +493,7 @@ public final class DeviceConfig { * @param onPropertyChangedListener The listener to add. * @hide * @see #removeOnPropertyChangedListener(OnPropertyChangedListener) + * @removed */ @SystemApi @TestApi @@ -569,6 +570,7 @@ public final class DeviceConfig { * @param onPropertyChangedListener The listener to remove. * @hide * @see #addOnPropertyChangedListener(String, Executor, OnPropertyChangedListener) + * @removed */ @SystemApi @TestApi @@ -737,6 +739,7 @@ public final class DeviceConfig { * Override {@link #onPropertyChanged(String, String, String)} to handle callbacks for changes. * * @hide + * @removed */ @SystemApi @TestApi diff --git a/core/java/android/service/attention/AttentionService.java b/core/java/android/service/attention/AttentionService.java index 6172ce501590..49ab5db74b87 100644 --- a/core/java/android/service/attention/AttentionService.java +++ b/core/java/android/service/attention/AttentionService.java @@ -21,13 +21,11 @@ import android.annotation.NonNull; import android.annotation.Nullable; import android.annotation.SystemApi; import android.app.Service; -import android.attention.AttentionManagerInternal; import android.content.Intent; import android.os.IBinder; import android.os.RemoteException; import com.android.internal.util.Preconditions; -import com.android.server.LocalServices; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; @@ -132,19 +130,6 @@ public abstract class AttentionService extends Service { } /** - * Disables the dependants. - * - * Example: called if the service does not have sufficient permissions to perform the task. - */ - public final void disableSelf() { - AttentionManagerInternal attentionManager = LocalServices.getService( - AttentionManagerInternal.class); - if (attentionManager != null) { - attentionManager.disableSelf(); - } - } - - /** * Checks the user attention and calls into the provided callback. * * @param callback the callback to return the result to diff --git a/core/java/android/service/contentcapture/ContentCaptureService.java b/core/java/android/service/contentcapture/ContentCaptureService.java index 5be73b92fbc0..d8614a9d66af 100644 --- a/core/java/android/service/contentcapture/ContentCaptureService.java +++ b/core/java/android/service/contentcapture/ContentCaptureService.java @@ -46,9 +46,9 @@ import android.view.contentcapture.ContentCaptureEvent; import android.view.contentcapture.ContentCaptureManager; import android.view.contentcapture.ContentCaptureSession; import android.view.contentcapture.ContentCaptureSessionId; +import android.view.contentcapture.DataRemovalRequest; import android.view.contentcapture.IContentCaptureDirectManager; import android.view.contentcapture.MainContentCaptureSession; -import android.view.contentcapture.UserDataRemovalRequest; import com.android.internal.os.IResultReceiver; @@ -138,7 +138,7 @@ public abstract class ContentCaptureService extends Service { } @Override - public void onUserDataRemovalRequest(UserDataRemovalRequest request) { + public void onDataRemovalRequest(DataRemovalRequest request) { mHandler.sendMessage( obtainMessage(ContentCaptureService::handleOnUserDataRemovalRequest, ContentCaptureService.this, request)); @@ -288,12 +288,12 @@ public abstract class ContentCaptureService extends Service { } /** - * Notifies the service that the app requested to remove data associated with the user. + * Notifies the service that the app requested to remove content capture data. * - * @param request the user data requested to be removed + * @param request the content capture data requested to be removed */ - public void onUserDataRemovalRequest(@NonNull UserDataRemovalRequest request) { - if (sVerbose) Log.v(TAG, "onUserDataRemovalRequest()"); + public void onDataRemovalRequest(@NonNull DataRemovalRequest request) { + if (sVerbose) Log.v(TAG, "onDataRemovalRequest()"); } /** @@ -449,8 +449,8 @@ public abstract class ContentCaptureService extends Service { onDestroyContentCaptureSession(new ContentCaptureSessionId(sessionId)); } - private void handleOnUserDataRemovalRequest(@NonNull UserDataRemovalRequest request) { - onUserDataRemovalRequest(request); + private void handleOnUserDataRemovalRequest(@NonNull DataRemovalRequest request) { + onDataRemovalRequest(request); } private void handleOnActivityEvent(@NonNull ActivityEvent event) { diff --git a/core/java/android/service/contentcapture/IContentCaptureService.aidl b/core/java/android/service/contentcapture/IContentCaptureService.aidl index 03e1b7857837..a7578af94004 100644 --- a/core/java/android/service/contentcapture/IContentCaptureService.aidl +++ b/core/java/android/service/contentcapture/IContentCaptureService.aidl @@ -21,7 +21,7 @@ import android.os.IBinder; import android.service.contentcapture.ActivityEvent; import android.service.contentcapture.SnapshotData; import android.view.contentcapture.ContentCaptureContext; -import android.view.contentcapture.UserDataRemovalRequest; +import android.view.contentcapture.DataRemovalRequest; import com.android.internal.os.IResultReceiver; @@ -39,6 +39,6 @@ oneway interface IContentCaptureService { in IResultReceiver clientReceiver, int initialState); void onSessionFinished(int sessionId); void onActivitySnapshot(int sessionId, in SnapshotData snapshotData); - void onUserDataRemovalRequest(in UserDataRemovalRequest request); + void onDataRemovalRequest(in DataRemovalRequest request); void onActivityEvent(in ActivityEvent event); } diff --git a/core/java/android/service/euicc/EuiccService.java b/core/java/android/service/euicc/EuiccService.java index 2288106d8351..d2f22bfac84a 100644 --- a/core/java/android/service/euicc/EuiccService.java +++ b/core/java/android/service/euicc/EuiccService.java @@ -418,12 +418,15 @@ public abstract class EuiccService extends Service { * bit map, and original the card Id. The result code may be one of the predefined * {@code RESULT_} constants or any implementation-specific code starting with * {@link #RESULT_FIRST_USER}. The resolvable error bit map can be either 0 or values - * defined in {@code RESOLVABLE_ERROR_}. + * defined in {@code RESOLVABLE_ERROR_}. A subclass should override this method. Otherwise, + * this method does nothing and returns null by default. * @see android.telephony.euicc.EuiccManager#downloadSubscription */ - public abstract DownloadSubscriptionResult onDownloadSubscription(int slotId, + public DownloadSubscriptionResult onDownloadSubscription(int slotId, @NonNull DownloadableSubscription subscription, boolean switchAfterDownload, - boolean forceDeactivateSim, @Nullable Bundle resolvedBundle); + boolean forceDeactivateSim, @Nullable Bundle resolvedBundle) { + return null; + } /** * Download the given subscription. @@ -439,14 +442,14 @@ public abstract class EuiccService extends Service { * constants or any implementation-specific code starting with {@link #RESULT_FIRST_USER}. * @see android.telephony.euicc.EuiccManager#downloadSubscription * - * @deprecated From Q, please use the above - * {@link #onDownloadSubscription(int, DownloadableSubscription, boolean, boolean, Bundle)}. + * @deprecated From Q, a subclass should use and override the above + * {@link #onDownloadSubscription(int, DownloadableSubscription, boolean, boolean, Bundle)}. The + * default return value for this one is Integer.MIN_VALUE. */ @Deprecated public @Result int onDownloadSubscription(int slotId, @NonNull DownloadableSubscription subscription, boolean switchAfterDownload, boolean forceDeactivateSim) { - throw new UnsupportedOperationException("onDownloadSubscription(int, " - + "DownloadableSubscription, boolean, boolean) is deprecated."); + return Integer.MIN_VALUE; } /** diff --git a/core/java/android/service/voice/VoiceInteractionSession.java b/core/java/android/service/voice/VoiceInteractionSession.java index 6f274477431f..5b5f3b843c50 100644 --- a/core/java/android/service/voice/VoiceInteractionSession.java +++ b/core/java/android/service/voice/VoiceInteractionSession.java @@ -123,7 +123,7 @@ public class VoiceInteractionSession implements KeyEvent.Callback, ComponentCall /** * Flag for use with {@link #onShow}: indicates that the voice interaction service was invoked - * from an Android automotive system Ui. + * from an Android automotive system UI. */ public static final int SHOW_SOURCE_AUTOMOTIVE_SYSTEM_UI = 1 << 7; diff --git a/core/java/android/util/DisplayMetrics.java b/core/java/android/util/DisplayMetrics.java index f2747cf426fa..1bcfc05224ca 100755 --- a/core/java/android/util/DisplayMetrics.java +++ b/core/java/android/util/DisplayMetrics.java @@ -34,11 +34,32 @@ public class DisplayMetrics { public static final int DENSITY_LOW = 120; /** + * Intermediate density for screens that sit between {@link #DENSITY_LOW} (120dpi) and + * {@link #DENSITY_MEDIUM} (160dpi). This is not a density that applications should target, + * instead relying on the system to scale their {@link #DENSITY_MEDIUM} assets for them. + */ + public static final int DENSITY_140 = 140; + + /** * Standard quantized DPI for medium-density screens. */ public static final int DENSITY_MEDIUM = 160; /** + * Intermediate density for screens that sit between {@link #DENSITY_MEDIUM} (160dpi) and + * {@link #DENSITY_HIGH} (240dpi). This is not a density that applications should target, + * instead relying on the system to scale their {@link #DENSITY_HIGH} assets for them. + */ + public static final int DENSITY_180 = 180; + + /** + * Intermediate density for screens that sit between {@link #DENSITY_MEDIUM} (160dpi) and + * {@link #DENSITY_HIGH} (240dpi). This is not a density that applications should target, + * instead relying on the system to scale their {@link #DENSITY_HIGH} assets for them. + */ + public static final int DENSITY_200 = 200; + + /** * This is a secondary density, added for some common screen configurations. * It is recommended that applications not generally target this as a first * class density -- that is, don't supply specific graphics for this @@ -58,6 +79,13 @@ public class DisplayMetrics { public static final int DENSITY_TV = 213; /** + * Intermediate density for screens that sit between {@link #DENSITY_MEDIUM} (160dpi) and + * {@link #DENSITY_HIGH} (240dpi). This is not a density that applications should target, + * instead relying on the system to scale their {@link #DENSITY_HIGH} assets for them. + */ + public static final int DENSITY_220 = 220; + + /** * Standard quantized DPI for high-density screens. */ public static final int DENSITY_HIGH = 240; diff --git a/core/java/android/view/ScaleGestureDetector.java b/core/java/android/view/ScaleGestureDetector.java index 7c69cfde2b9e..1d721516a979 100644 --- a/core/java/android/view/ScaleGestureDetector.java +++ b/core/java/android/view/ScaleGestureDetector.java @@ -551,7 +551,7 @@ public class ScaleGestureDetector { (mEventBeforeOrAboveStartingGestureEvent && (mCurrSpan < mPrevSpan)) || (!mEventBeforeOrAboveStartingGestureEvent && (mCurrSpan > mPrevSpan)); final float spanDiff = (Math.abs(1 - (mCurrSpan / mPrevSpan)) * SCALE_FACTOR); - return mPrevSpan <= 0 ? 1 : scaleUp ? (1 + spanDiff) : (1 - spanDiff); + return mPrevSpan <= mSpanSlop ? 1 : scaleUp ? (1 + spanDiff) : (1 - spanDiff); } return mPrevSpan > 0 ? mCurrSpan / mPrevSpan : 1; } diff --git a/core/java/android/view/View.java b/core/java/android/view/View.java index 51bcbbdb7e7d..c3a94655d7d5 100644 --- a/core/java/android/view/View.java +++ b/core/java/android/view/View.java @@ -1377,59 +1377,6 @@ public class View implements Drawable.Callback, KeyEvent.Callback, */ public static final int AUTOFILL_FLAG_INCLUDE_NOT_IMPORTANT_VIEWS = 0x1; - /** @hide */ - @IntDef(prefix = { "IMPORTANT_FOR_CONTENT_CAPTURE_" }, value = { - IMPORTANT_FOR_CONTENT_CAPTURE_AUTO, - IMPORTANT_FOR_CONTENT_CAPTURE_YES, - IMPORTANT_FOR_CONTENT_CAPTURE_NO, - IMPORTANT_FOR_CONTENT_CAPTURE_YES_EXCLUDE_DESCENDANTS, - IMPORTANT_FOR_CONTENT_CAPTURE_NO_EXCLUDE_DESCENDANTS - }) - @Retention(RetentionPolicy.SOURCE) - public @interface ContentCaptureImportance {} - - /** - * Automatically determine whether a view is important for content capture. - * - * @see #isImportantForContentCapture() - * @see #setImportantForContentCapture(int) - */ - public static final int IMPORTANT_FOR_CONTENT_CAPTURE_AUTO = 0x0; - - /** - * The view is important for content capture, and its children (if any) will be traversed. - * - * @see #isImportantForContentCapture() - * @see #setImportantForContentCapture(int) - */ - public static final int IMPORTANT_FOR_CONTENT_CAPTURE_YES = 0x1; - - /** - * The view is not important for content capture, but its children (if any) will be traversed. - * - * @see #isImportantForContentCapture() - * @see #setImportantForContentCapture(int) - */ - public static final int IMPORTANT_FOR_CONTENT_CAPTURE_NO = 0x2; - - /** - * The view is important for content capture, but its children (if any) will not be traversed. - * - * @see #isImportantForContentCapture() - * @see #setImportantForContentCapture(int) - */ - public static final int IMPORTANT_FOR_CONTENT_CAPTURE_YES_EXCLUDE_DESCENDANTS = 0x4; - - /** - * The view is not important for content capture, and its children (if any) will not be - * traversed. - * - * @see #isImportantForContentCapture() - * @see #setImportantForContentCapture(int) - */ - public static final int IMPORTANT_FOR_CONTENT_CAPTURE_NO_EXCLUDE_DESCENDANTS = 0x8; - - /** * This view is enabled. Interpretation varies by subclass. * Use with ENABLED_MASK when calling setFlags. @@ -3402,55 +3349,6 @@ public class View implements Drawable.Callback, KeyEvent.Callback, /* End of masks for mPrivateFlags3 */ - /* - * Masks for mPrivateFlags4, as generated by dumpFlags(): - * - * |-------|-------|-------|-------| - * 1111 PFLAG4_IMPORTANT_FOR_CONTENT_CAPTURE_MASK - * 1 PFLAG4_NOTIFIED_CONTENT_CAPTURE_APPEARED - * 1 PFLAG4_NOTIFIED_CONTENT_CAPTURE_DISAPPEARED - * 1 PFLAG4_CONTENT_CAPTURE_IMPORTANCE_IS_CACHED - * 1 PFLAG4_CONTENT_CAPTURE_IMPORTANCE_CACHED_VALUE - * 11 PFLAG4_CONTENT_CAPTURE_IMPORTANCE_MASK - * |-------|-------|-------|-------| - */ - - /** - * Mask for obtaining the bits which specify how to determine - * whether a view is important for autofill. - * - * <p>NOTE: the important for content capture values were the first flags added and are set in - * the rightmost position, so we don't need to shift them - */ - private static final int PFLAG4_IMPORTANT_FOR_CONTENT_CAPTURE_MASK = - IMPORTANT_FOR_CONTENT_CAPTURE_AUTO | IMPORTANT_FOR_CONTENT_CAPTURE_YES - | IMPORTANT_FOR_CONTENT_CAPTURE_NO - | IMPORTANT_FOR_CONTENT_CAPTURE_YES_EXCLUDE_DESCENDANTS - | IMPORTANT_FOR_CONTENT_CAPTURE_NO_EXCLUDE_DESCENDANTS; - - /* - * Variables used to control when the IntelligenceManager.notifyNodeAdded()/removed() methods - * should be called. - * - * The idea is to call notifyAppeared() after the view is layout and visible, then call - * notifyDisappeared() when it's gone (without known when it was removed from the parent). - */ - private static final int PFLAG4_NOTIFIED_CONTENT_CAPTURE_APPEARED = 0x10; - private static final int PFLAG4_NOTIFIED_CONTENT_CAPTURE_DISAPPEARED = 0x20; - - /* - * Flags used to cache the value returned by isImportantForContentCapture while the view - * hierarchy is being traversed. - */ - private static final int PFLAG4_CONTENT_CAPTURE_IMPORTANCE_IS_CACHED = 0x40; - private static final int PFLAG4_CONTENT_CAPTURE_IMPORTANCE_CACHED_VALUE = 0x80; - - private static final int PFLAG4_CONTENT_CAPTURE_IMPORTANCE_MASK = - PFLAG4_CONTENT_CAPTURE_IMPORTANCE_IS_CACHED - | PFLAG4_CONTENT_CAPTURE_IMPORTANCE_CACHED_VALUE; - - /* End of masks for mPrivateFlags4 */ - /** @hide */ protected static final int VIEW_STRUCTURE_FOR_ASSIST = 0; /** @hide */ @@ -4074,8 +3972,6 @@ public class View implements Drawable.Callback, KeyEvent.Callback, @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 129147060) int mPrivateFlags3; - private int mPrivateFlags4; - /** * This view's request for the visibility of the status bar. * @hide @@ -5808,11 +5704,6 @@ public class View implements Drawable.Callback, KeyEvent.Callback, setImportantForAutofill(a.getInt(attr, IMPORTANT_FOR_AUTOFILL_AUTO)); } break; - case R.styleable.View_importantForContentCapture: - if (a.peekValue(attr) != null) { - setImportantForContentCapture(a.getInt(attr, - IMPORTANT_FOR_CONTENT_CAPTURE_AUTO)); - } case R.styleable.View_defaultFocusHighlightEnabled: if (a.peekValue(attr) != null) { setDefaultFocusHighlightEnabled(a.getBoolean(attr, true)); @@ -8532,62 +8423,6 @@ public class View implements Drawable.Callback, KeyEvent.Callback, onProvideStructure(structure, VIEW_STRUCTURE_FOR_AUTOFILL, flags); } - /** - * Populates a {@link ViewStructure} for content capture. - * - * <p>This method is called after a view is that is eligible for content capture - * (for example, if it {@link #isImportantForAutofill()}, an intelligence service is enabled for - * the user, and the activity rendering the view is enabled for content capture) is laid out and - * is visible. - * - * <p>The populated structure is then passed to the service through - * {@link ContentCaptureSession#notifyViewAppeared(ViewStructure)}. - * - * <p><b>Note: </b>views that manage a virtual structure under this view must populate just - * the node representing this view and return right away, then asynchronously report (not - * necessarily in the UI thread) when the children nodes appear, disappear or have their text - * changed by calling - * {@link ContentCaptureSession#notifyViewAppeared(ViewStructure)}, - * {@link ContentCaptureSession#notifyViewDisappeared(AutofillId)}, and - * {@link ContentCaptureSession#notifyViewTextChanged(AutofillId, CharSequence)} - * respectively. The structure for the a child must be created using - * {@link ContentCaptureSession#newVirtualViewStructure(AutofillId, long)}, and the - * {@code autofillId} for a child can be obtained either through - * {@code childStructure.getAutofillId()} or - * {@link ContentCaptureSession#newAutofillId(AutofillId, long)}. - * - * <p>When the virtual view hierarchy represents a web page, you should also: - * - * <ul> - * <li>Call {@link ContentCaptureManager#getContentCaptureConditions()} to infer content - * capture events should be generate for that URL. - * <li>Create a new {@link ContentCaptureSession} child for every HTML element that - * renders a new URL (like an {@code IFRAME}) and use that session to notify events from - * that subtree. - * </ul> - * - * <p><b>Note: </b>the following methods of the {@code structure} will be ignored: - * <ul> - * <li>{@link ViewStructure#setChildCount(int)} - * <li>{@link ViewStructure#addChildCount(int)} - * <li>{@link ViewStructure#getChildCount()} - * <li>{@link ViewStructure#newChild(int)} - * <li>{@link ViewStructure#asyncNewChild(int)} - * <li>{@link ViewStructure#asyncCommit()} - * <li>{@link ViewStructure#setWebDomain(String)} - * <li>{@link ViewStructure#newHtmlInfoBuilder(String)} - * <li>{@link ViewStructure#setHtmlInfo(android.view.ViewStructure.HtmlInfo)} - * <li>{@link ViewStructure#setDataIsSensitive(boolean)} - * <li>{@link ViewStructure#setAlpha(float)} - * <li>{@link ViewStructure#setElevation(float)} - * <li>{@link ViewStructure#setTransformation(Matrix)} - * - * </ul> - */ - public void onProvideContentCaptureStructure(@NonNull ViewStructure structure, int flags) { - onProvideStructure(structure, VIEW_STRUCTURE_FOR_CONTENT_CAPTURE, flags); - } - /** @hide */ protected void onProvideStructure(@NonNull ViewStructure structure, @ViewStructureType int viewFor, int flags) { @@ -9225,265 +9060,6 @@ public class View implements Drawable.Callback, KeyEvent.Callback, } /** - * Gets the mode for determining whether this view is important for content capture. - * - * <p>See {@link #setImportantForContentCapture(int)} and - * {@link #isImportantForContentCapture()} for more info about this mode. - * - * @return {@link #IMPORTANT_FOR_CONTENT_CAPTURE_AUTO} by default, or value passed to - * {@link #setImportantForContentCapture(int)}. - * - * @attr ref android.R.styleable#View_importantForContentCapture - */ - @ViewDebug.ExportedProperty(mapping = { - @ViewDebug.IntToString(from = IMPORTANT_FOR_CONTENT_CAPTURE_AUTO, to = "auto"), - @ViewDebug.IntToString(from = IMPORTANT_FOR_CONTENT_CAPTURE_YES, to = "yes"), - @ViewDebug.IntToString(from = IMPORTANT_FOR_CONTENT_CAPTURE_NO, to = "no"), - @ViewDebug.IntToString(from = IMPORTANT_FOR_CONTENT_CAPTURE_YES_EXCLUDE_DESCENDANTS, - to = "yesExcludeDescendants"), - @ViewDebug.IntToString(from = IMPORTANT_FOR_CONTENT_CAPTURE_NO_EXCLUDE_DESCENDANTS, - to = "noExcludeDescendants")}) - @InspectableProperty(enumMapping = { - @EnumEntry(value = IMPORTANT_FOR_CONTENT_CAPTURE_AUTO, name = "auto"), - @EnumEntry(value = IMPORTANT_FOR_CONTENT_CAPTURE_YES, name = "yes"), - @EnumEntry(value = IMPORTANT_FOR_CONTENT_CAPTURE_NO, name = "no"), - @EnumEntry(value = IMPORTANT_FOR_CONTENT_CAPTURE_YES_EXCLUDE_DESCENDANTS, - name = "yesExcludeDescendants"), - @EnumEntry(value = IMPORTANT_FOR_CONTENT_CAPTURE_NO_EXCLUDE_DESCENDANTS, - name = "noExcludeDescendants"), - }) - public @ContentCaptureImportance int getImportantForContentCapture() { - // NOTE: the important for content capture values were the first flags added and are set in - // the rightmost position, so we don't need to shift them - return mPrivateFlags4 & PFLAG4_IMPORTANT_FOR_CONTENT_CAPTURE_MASK; - } - - /** - * Sets the mode for determining whether this view is considered important for content capture. - * - * <p>The platform determines the importance for autofill automatically but you - * can use this method to customize the behavior. Typically, a view that provides text should - * be marked as {@link #IMPORTANT_FOR_CONTENT_CAPTURE_YES}. - * - * @param mode {@link #IMPORTANT_FOR_CONTENT_CAPTURE_AUTO}, - * {@link #IMPORTANT_FOR_CONTENT_CAPTURE_YES}, {@link #IMPORTANT_FOR_CONTENT_CAPTURE_NO}, - * {@link #IMPORTANT_FOR_CONTENT_CAPTURE_YES_EXCLUDE_DESCENDANTS}, - * or {@link #IMPORTANT_FOR_CONTENT_CAPTURE_NO_EXCLUDE_DESCENDANTS}. - * - * @attr ref android.R.styleable#View_importantForContentCapture - */ - public void setImportantForContentCapture(@ContentCaptureImportance int mode) { - // Reset first - mPrivateFlags4 &= ~PFLAG4_IMPORTANT_FOR_CONTENT_CAPTURE_MASK; - // Then set again - // NOTE: the important for content capture values were the first flags added and are set in - // the rightmost position, so we don't need to shift them - mPrivateFlags4 |= (mode & PFLAG4_IMPORTANT_FOR_CONTENT_CAPTURE_MASK); - } - - /** - * Hints the Android System whether this view is considered important for content capture, based - * on the value explicitly set by {@link #setImportantForContentCapture(int)} and heuristics - * when it's {@link #IMPORTANT_FOR_CONTENT_CAPTURE_AUTO}. - * - * <p>See {@link ContentCaptureManager} for more info about content capture. - * - * @return whether the view is considered important for content capture. - * - * @see #setImportantForContentCapture(int) - * @see #IMPORTANT_FOR_CONTENT_CAPTURE_AUTO - * @see #IMPORTANT_FOR_CONTENT_CAPTURE_YES - * @see #IMPORTANT_FOR_CONTENT_CAPTURE_NO - * @see #IMPORTANT_FOR_CONTENT_CAPTURE_YES_EXCLUDE_DESCENDANTS - * @see #IMPORTANT_FOR_CONTENT_CAPTURE_NO_EXCLUDE_DESCENDANTS - */ - public final boolean isImportantForContentCapture() { - boolean isImportant; - if ((mPrivateFlags4 & PFLAG4_CONTENT_CAPTURE_IMPORTANCE_IS_CACHED) != 0) { - isImportant = (mPrivateFlags4 & PFLAG4_CONTENT_CAPTURE_IMPORTANCE_CACHED_VALUE) != 0; - return isImportant; - } - - isImportant = calculateIsImportantForContentCapture(); - - mPrivateFlags4 &= ~PFLAG4_CONTENT_CAPTURE_IMPORTANCE_CACHED_VALUE; - if (isImportant) { - mPrivateFlags4 |= PFLAG4_CONTENT_CAPTURE_IMPORTANCE_CACHED_VALUE; - } - mPrivateFlags4 |= PFLAG4_CONTENT_CAPTURE_IMPORTANCE_IS_CACHED; - return isImportant; - } - - /** - * Calculates whether the flag is important for content capture so it can be used by - * {@link #isImportantForContentCapture()} while the tree is traversed. - */ - private boolean calculateIsImportantForContentCapture() { - // Check parent mode to ensure we're important - ViewParent parent = mParent; - while (parent instanceof View) { - final int parentImportance = ((View) parent).getImportantForContentCapture(); - if (parentImportance == IMPORTANT_FOR_CONTENT_CAPTURE_NO_EXCLUDE_DESCENDANTS - || parentImportance == IMPORTANT_FOR_CONTENT_CAPTURE_YES_EXCLUDE_DESCENDANTS) { - if (Log.isLoggable(CONTENT_CAPTURE_LOG_TAG, Log.VERBOSE)) { - Log.v(CONTENT_CAPTURE_LOG_TAG, "View (" + this + ") is not important for " - + "content capture because parent " + parent + "'s importance is " - + parentImportance); - } - return false; - } - parent = parent.getParent(); - } - - final int importance = getImportantForContentCapture(); - - // First, check the explicit states. - if (importance == IMPORTANT_FOR_CONTENT_CAPTURE_YES_EXCLUDE_DESCENDANTS - || importance == IMPORTANT_FOR_CONTENT_CAPTURE_YES) { - return true; - } - if (importance == IMPORTANT_FOR_CONTENT_CAPTURE_NO_EXCLUDE_DESCENDANTS - || importance == IMPORTANT_FOR_CONTENT_CAPTURE_NO) { - if (Log.isLoggable(CONTENT_CAPTURE_LOG_TAG, Log.VERBOSE)) { - Log.v(CONTENT_CAPTURE_LOG_TAG, "View (" + this + ") is not important for content " - + "capture because its importance is " + importance); - } - return false; - } - - // Then use some heuristics to handle AUTO. - if (importance != IMPORTANT_FOR_CONTENT_CAPTURE_AUTO) { - Log.w(CONTENT_CAPTURE_LOG_TAG, "invalid content capture importance (" + importance - + " on view " + this); - return false; - } - - // View group is important if at least one children also is - if (this instanceof ViewGroup) { - final ViewGroup group = (ViewGroup) this; - for (int i = 0; i < group.getChildCount(); i++) { - final View child = group.getChildAt(i); - if (child.isImportantForContentCapture()) { - return true; - } - } - } - - // If the app developer explicitly set hints or autofill hintsfor it, it's important. - if (getAutofillHints() != null) { - return true; - } - - // Otherwise, assume it's not important... - return false; - } - - /** - * Helper used to notify the {@link ContentCaptureManager} when the view is removed or - * added, based on whether it's laid out and visible, and without knowing if the parent removed - * it from the view hierarchy. - * - * <p>This method is called from many places (visibility changed, view laid out, view attached - * or detached to/from window, etc...) and hence must contain the logic to call the manager, as - * described below: - * - * <ol> - * <li>It should only be called when content capture is enabled for the view. - * <li>It must call viewAppeared() before viewDisappeared() - * <li>viewAppearead() can only be called when the view is visible and laidout - * <li>It should not call the same event twice. - * </ol> - */ - private void notifyAppearedOrDisappearedForContentCaptureIfNeeded(boolean appeared) { - AttachInfo ai = mAttachInfo; - // Skip it while the view is being laided out for the first time - if (ai != null && !ai.mReadyForContentCaptureUpdates) return; - - if (Trace.isTagEnabled(Trace.TRACE_TAG_VIEW)) { - Trace.traceBegin(Trace.TRACE_TAG_VIEW, - "notifyContentCapture(" + appeared + ") for " + getClass().getSimpleName()); - } - try { - notifyAppearedOrDisappearedForContentCaptureIfNeededNoTrace(appeared); - } finally { - Trace.traceEnd(Trace.TRACE_TAG_VIEW); - } - } - - private void notifyAppearedOrDisappearedForContentCaptureIfNeededNoTrace(boolean appeared) { - AttachInfo ai = mAttachInfo; - - // First check if context has client, so it saves a service lookup when it doesn't - if (mContext.getContentCaptureOptions() == null) return; - - // Then check if it's enabled in the context... - final ContentCaptureManager ccm = ai != null ? ai.getContentCaptureManager(mContext) - : mContext.getSystemService(ContentCaptureManager.class); - if (ccm == null || !ccm.isContentCaptureEnabled()) return; - - // ... and finally at the view level - // NOTE: isImportantForContentCapture() is more expensive than cm.isContentCaptureEnabled() - if (!isImportantForContentCapture()) return; - - ContentCaptureSession session = getContentCaptureSession(); - if (session == null) return; - - if (appeared) { - if (!isLaidOut() || getVisibility() != VISIBLE - || (mPrivateFlags4 & PFLAG4_NOTIFIED_CONTENT_CAPTURE_APPEARED) != 0) { - if (DEBUG_CONTENT_CAPTURE) { - Log.v(CONTENT_CAPTURE_LOG_TAG, "Ignoring 'appeared' on " + this + ": laid=" - + isLaidOut() + ", visibleToUser=" + isVisibleToUser() - + ", visible=" + (getVisibility() == VISIBLE) - + ": alreadyNotifiedAppeared=" + ((mPrivateFlags4 - & PFLAG4_NOTIFIED_CONTENT_CAPTURE_APPEARED) != 0) - + ", alreadyNotifiedDisappeared=" + ((mPrivateFlags4 - & PFLAG4_NOTIFIED_CONTENT_CAPTURE_DISAPPEARED) != 0)); - } - return; - } - setNotifiedContentCaptureAppeared(); - - if (ai != null) { - ai.delayNotifyContentCaptureEvent(session, this, appeared); - } else { - if (DEBUG_CONTENT_CAPTURE) { - Log.w(CONTENT_CAPTURE_LOG_TAG, "no AttachInfo on appeared for " + this); - } - } - } else { - if ((mPrivateFlags4 & PFLAG4_NOTIFIED_CONTENT_CAPTURE_APPEARED) == 0 - || (mPrivateFlags4 & PFLAG4_NOTIFIED_CONTENT_CAPTURE_DISAPPEARED) != 0) { - if (DEBUG_CONTENT_CAPTURE) { - Log.v(CONTENT_CAPTURE_LOG_TAG, "Ignoring 'disappeared' on " + this + ": laid=" - + isLaidOut() + ", visibleToUser=" + isVisibleToUser() - + ", visible=" + (getVisibility() == VISIBLE) - + ": alreadyNotifiedAppeared=" + ((mPrivateFlags4 - & PFLAG4_NOTIFIED_CONTENT_CAPTURE_APPEARED) != 0) - + ", alreadyNotifiedDisappeared=" + ((mPrivateFlags4 - & PFLAG4_NOTIFIED_CONTENT_CAPTURE_DISAPPEARED) != 0)); - } - return; - } - mPrivateFlags4 |= PFLAG4_NOTIFIED_CONTENT_CAPTURE_DISAPPEARED; - mPrivateFlags4 &= ~PFLAG4_NOTIFIED_CONTENT_CAPTURE_APPEARED; - - if (ai != null) { - ai.delayNotifyContentCaptureEvent(session, this, appeared); - } else { - if (DEBUG_CONTENT_CAPTURE) { - Log.v(CONTENT_CAPTURE_LOG_TAG, "no AttachInfo on disappeared for " + this); - } - } - } - } - - private void setNotifiedContentCaptureAppeared() { - mPrivateFlags4 |= PFLAG4_NOTIFIED_CONTENT_CAPTURE_APPEARED; - mPrivateFlags4 &= ~PFLAG4_NOTIFIED_CONTENT_CAPTURE_DISAPPEARED; - } - - /** * Sets the (optional) {@link ContentCaptureSession} associated with this view. * * <p>This method should be called when you need to associate a {@link ContentCaptureContext} to @@ -9739,68 +9315,6 @@ public class View implements Drawable.Callback, KeyEvent.Callback, } /** - * Dispatches the initial content capture events for a view structure. - * - * @hide - */ - public void dispatchInitialProvideContentCaptureStructure() { - AttachInfo ai = mAttachInfo; - if (ai == null) { - Log.w(CONTENT_CAPTURE_LOG_TAG, - "dispatchProvideContentCaptureStructure(): no AttachInfo for " + this); - return; - } - ContentCaptureManager ccm = ai.mContentCaptureManager; - if (ccm == null) { - Log.w(CONTENT_CAPTURE_LOG_TAG, "dispatchProvideContentCaptureStructure(): " - + "no ContentCaptureManager for " + this); - return; - } - - // We must set it before checkign if the view itself is important, because it might - // initially not be (for example, if it's empty), although that might change later (for - // example, if important views are added) - ai.mReadyForContentCaptureUpdates = true; - - if (!isImportantForContentCapture()) { - if (Log.isLoggable(CONTENT_CAPTURE_LOG_TAG, Log.DEBUG)) { - Log.d(CONTENT_CAPTURE_LOG_TAG, - "dispatchProvideContentCaptureStructure(): decorView is not important"); - } - return; - } - - ai.mContentCaptureManager = ccm; - - ContentCaptureSession session = getContentCaptureSession(); - if (session == null) { - if (Log.isLoggable(CONTENT_CAPTURE_LOG_TAG, Log.DEBUG)) { - Log.d(CONTENT_CAPTURE_LOG_TAG, - "dispatchProvideContentCaptureStructure(): no session for " + this); - } - return; - } - - session.internalNotifyViewTreeEvent(/* started= */ true); - try { - dispatchProvideContentCaptureStructure(); - } finally { - session.internalNotifyViewTreeEvent(/* started= */ false); - } - } - - /** @hide */ - void dispatchProvideContentCaptureStructure() { - ContentCaptureSession session = getContentCaptureSession(); - if (session != null) { - ViewStructure structure = session.newViewStructure(this); - onProvideContentCaptureStructure(structure, /* flags= */ 0); - setNotifiedContentCaptureAppeared(); - session.notifyViewAppeared(structure); - } - } - - /** * @see #onInitializeAccessibilityNodeInfo(AccessibilityNodeInfo) * * Note: Called from the default {@link AccessibilityDelegate}. @@ -13753,7 +13267,6 @@ public class View implements Drawable.Callback, KeyEvent.Callback, public void dispatchStartTemporaryDetach() { mPrivateFlags3 |= PFLAG3_TEMPORARY_DETACH; notifyEnterOrExitForAutoFillIfNeeded(false); - notifyAppearedOrDisappearedForContentCaptureIfNeeded(false); onStartTemporaryDetach(); } @@ -13780,7 +13293,6 @@ public class View implements Drawable.Callback, KeyEvent.Callback, notifyFocusChangeToInputMethodManager(true /* hasFocus */); } notifyEnterOrExitForAutoFillIfNeeded(true); - notifyAppearedOrDisappearedForContentCaptureIfNeeded(true); } /** @@ -14372,8 +13884,6 @@ public class View implements Drawable.Callback, KeyEvent.Callback, : AccessibilityEvent.CONTENT_CHANGE_TYPE_PANE_DISAPPEARED); } } - - notifyAppearedOrDisappearedForContentCaptureIfNeeded(isVisible); } /** @@ -18069,7 +17579,6 @@ public class View implements Drawable.Callback, KeyEvent.Callback, } // Reset content capture caches - mPrivateFlags4 &= ~PFLAG4_CONTENT_CAPTURE_IMPORTANCE_MASK; mCachedContentCaptureSession = null; if ((mPrivateFlags & (PFLAG_DRAWN | PFLAG_HAS_BOUNDS)) == (PFLAG_DRAWN | PFLAG_HAS_BOUNDS) @@ -20079,7 +19588,6 @@ public class View implements Drawable.Callback, KeyEvent.Callback, needGlobalAttributesUpdate(false); notifyEnterOrExitForAutoFillIfNeeded(true); - notifyAppearedOrDisappearedForContentCaptureIfNeeded(true); } @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P) @@ -20129,7 +19637,6 @@ public class View implements Drawable.Callback, KeyEvent.Callback, } notifyEnterOrExitForAutoFillIfNeeded(false); - notifyAppearedOrDisappearedForContentCaptureIfNeeded(false); } /** @@ -22442,8 +21949,6 @@ public class View implements Drawable.Callback, KeyEvent.Callback, mPrivateFlags3 &= ~PFLAG3_NOTIFY_AUTOFILL_ENTER_ON_LAYOUT; notifyEnterOrExitForAutoFillIfNeeded(true); } - - notifyAppearedOrDisappearedForContentCaptureIfNeeded(true); } private boolean hasParentWantsFocus() { @@ -28650,23 +28155,6 @@ public class View implements Drawable.Callback, KeyEvent.Callback, View mTooltipHost; /** - * The initial structure has been reported so the view is ready to report updates. - */ - boolean mReadyForContentCaptureUpdates; - - /** - * Map(keyed by session) of content capture events that need to be notified after the view - * hierarchy is traversed: value is either the view itself for appearead events, or its - * autofill id for disappeared. - */ - SparseArray<ArrayList<Object>> mContentCaptureEvents; - - /** - * Cached reference to the {@link ContentCaptureManager}. - */ - ContentCaptureManager mContentCaptureManager; - - /** * Creates a new set of attachment information with the specified * events handler and thread. * @@ -28684,31 +28172,6 @@ public class View implements Drawable.Callback, KeyEvent.Callback, mRootCallbacks = effectPlayer; mTreeObserver = new ViewTreeObserver(context); } - - private void delayNotifyContentCaptureEvent(@NonNull ContentCaptureSession session, - @NonNull View view, boolean appeared) { - if (mContentCaptureEvents == null) { - // Most of the time there will be just one session, so intial capacity is 1 - mContentCaptureEvents = new SparseArray<>(1); - } - int sessionId = session.getId(); - // TODO: life would be much easier if we provided a MultiMap implementation somwhere... - ArrayList<Object> events = mContentCaptureEvents.get(sessionId); - if (events == null) { - events = new ArrayList<>(); - mContentCaptureEvents.put(sessionId, events); - } - events.add(appeared ? view : view.getAutofillId()); - } - - @Nullable - ContentCaptureManager getContentCaptureManager(@NonNull Context context) { - if (mContentCaptureManager != null) { - return mContentCaptureManager; - } - mContentCaptureManager = context.getSystemService(ContentCaptureManager.class); - return mContentCaptureManager; - } } /** diff --git a/core/java/android/view/ViewGroup.java b/core/java/android/view/ViewGroup.java index 937bd1b34e61..d362024ed525 100644 --- a/core/java/android/view/ViewGroup.java +++ b/core/java/android/view/ViewGroup.java @@ -3606,7 +3606,7 @@ public abstract class ViewGroup extends View implements ViewParent, ViewManager return; } - final ChildListForAutoFillOrContentCapture children = getChildrenForAutofill(flags); + final ChildListForAutofill children = getChildrenForAutofill(flags); final int childrenCount = children.size(); structure.setChildCount(childrenCount); for (int i = 0; i < childrenCount; i++) { @@ -3617,30 +3617,14 @@ public abstract class ViewGroup extends View implements ViewParent, ViewManager children.recycle(); } - /** @hide */ - @Override - public void dispatchProvideContentCaptureStructure() { - super.dispatchProvideContentCaptureStructure(); - - if (!isLaidOut()) return; - - final ChildListForAutoFillOrContentCapture children = getChildrenForContentCapture(); - final int childrenCount = children.size(); - for (int i = 0; i < childrenCount; i++) { - final View child = children.get(i); - child.dispatchProvideContentCaptureStructure(); - } - children.recycle(); - } - /** * Gets the children for autofill. Children for autofill are the first * level descendants that are important for autofill. The returned * child list object is pooled and the caller must recycle it once done. * @hide */ - private @NonNull ChildListForAutoFillOrContentCapture getChildrenForAutofill( + private @NonNull ChildListForAutofill getChildrenForAutofill( @AutofillFlags int flags) { - final ChildListForAutoFillOrContentCapture children = ChildListForAutoFillOrContentCapture + final ChildListForAutofill children = ChildListForAutofill .obtain(); populateChildrenForAutofill(children, flags); return children; @@ -3668,34 +3652,6 @@ public abstract class ViewGroup extends View implements ViewParent, ViewManager } } - private @NonNull ChildListForAutoFillOrContentCapture getChildrenForContentCapture() { - final ChildListForAutoFillOrContentCapture children = ChildListForAutoFillOrContentCapture - .obtain(); - populateChildrenForContentCapture(children); - return children; - } - - /** @hide */ - private void populateChildrenForContentCapture(ArrayList<View> list) { - final int childrenCount = mChildrenCount; - if (childrenCount <= 0) { - return; - } - final ArrayList<View> preorderedList = buildOrderedChildList(); - final boolean customOrder = preorderedList == null - && isChildrenDrawingOrderEnabled(); - for (int i = 0; i < childrenCount; i++) { - final int childIndex = getAndVerifyPreorderedIndex(childrenCount, i, customOrder); - final View child = (preorderedList == null) - ? mChildren[childIndex] : preorderedList.get(childIndex); - if (child.isImportantForContentCapture()) { - list.add(child); - } else if (child instanceof ViewGroup) { - ((ViewGroup) child).populateChildrenForContentCapture(list); - } - } - } - private static View getAndVerifyPreorderedView(ArrayList<View> preorderedList, View[] children, int childIndex) { final View child; @@ -8678,16 +8634,16 @@ public abstract class ViewGroup extends View implements ViewParent, ViewManager /** * Pooled class that to hold the children for autifill. */ - private static class ChildListForAutoFillOrContentCapture extends ArrayList<View> { + private static class ChildListForAutofill extends ArrayList<View> { private static final int MAX_POOL_SIZE = 32; - private static final Pools.SimplePool<ChildListForAutoFillOrContentCapture> sPool = + private static final Pools.SimplePool<ChildListForAutofill> sPool = new Pools.SimplePool<>(MAX_POOL_SIZE); - public static ChildListForAutoFillOrContentCapture obtain() { - ChildListForAutoFillOrContentCapture list = sPool.acquire(); + public static ChildListForAutofill obtain() { + ChildListForAutofill list = sPool.acquire(); if (list == null) { - list = new ChildListForAutoFillOrContentCapture(); + list = new ChildListForAutofill(); } return list; } diff --git a/core/java/android/view/ViewRootImpl.java b/core/java/android/view/ViewRootImpl.java index f3b7ad5e557c..5ca70ba9a575 100644 --- a/core/java/android/view/ViewRootImpl.java +++ b/core/java/android/view/ViewRootImpl.java @@ -105,11 +105,7 @@ import android.view.accessibility.IAccessibilityInteractionConnection; import android.view.accessibility.IAccessibilityInteractionConnectionCallback; import android.view.animation.AccelerateDecelerateInterpolator; import android.view.animation.Interpolator; -import android.view.autofill.AutofillId; import android.view.autofill.AutofillManager; -import android.view.contentcapture.ContentCaptureManager; -import android.view.contentcapture.ContentCaptureSession; -import android.view.contentcapture.MainContentCaptureSession; import android.view.inputmethod.InputMethodManager; import android.widget.Scroller; @@ -224,21 +220,6 @@ public final class ViewRootImpl implements ViewParent, */ static final int MAX_TRACKBALL_DELAY = 250; - /** - * Initial value for {@link #mContentCaptureEnabled}. - */ - private static final int CONTENT_CAPTURE_ENABLED_NOT_CHECKED = 0; - - /** - * Value for {@link #mContentCaptureEnabled} when it was checked and set to {@code true}. - */ - private static final int CONTENT_CAPTURE_ENABLED_TRUE = 1; - - /** - * Value for {@link #mContentCaptureEnabled} when it was checked and set to {@code false}. - */ - private static final int CONTENT_CAPTURE_ENABLED_FALSE = 2; - @UnsupportedAppUsage static final ThreadLocal<HandlerActionQueue> sRunQueues = new ThreadLocal<HandlerActionQueue>(); @@ -435,10 +416,6 @@ public final class ViewRootImpl implements ViewParent, boolean mLayoutRequested; boolean mFirst; - @Nullable - int mContentCaptureEnabled = CONTENT_CAPTURE_ENABLED_NOT_CHECKED; - boolean mPerformContentCapture; - boolean mReportNextDraw; boolean mFullRedrawNeeded; boolean mNewSurfaceNeeded; @@ -637,7 +614,6 @@ public final class ViewRootImpl implements ViewParent, mTransparentRegion = new Region(); mPreviousTransparentRegion = new Region(); mFirst = true; // true for the first time the view is added - mPerformContentCapture = true; // also true for the first time the view is added mAdded = false; mAttachInfo = new View.AttachInfo(mWindowSession, mWindow, display, this, mHandler, this, context); @@ -2787,55 +2763,9 @@ public final class ViewRootImpl implements ViewParent, } } - if (mAttachInfo.mContentCaptureEvents != null) { - notifyContentCatpureEvents(); - } - mIsInTraversal = false; } - private void notifyContentCatpureEvents() { - Trace.traceBegin(Trace.TRACE_TAG_VIEW, "notifyContentCaptureEvents"); - try { - MainContentCaptureSession mainSession = mAttachInfo.mContentCaptureManager - .getMainContentCaptureSession(); - for (int i = 0; i < mAttachInfo.mContentCaptureEvents.size(); i++) { - int sessionId = mAttachInfo.mContentCaptureEvents.keyAt(i); - mainSession.notifyViewTreeEvent(sessionId, /* started= */ true); - ArrayList<Object> events = mAttachInfo.mContentCaptureEvents - .valueAt(i); - for_each_event: for (int j = 0; j < events.size(); j++) { - Object event = events.get(j); - if (event instanceof AutofillId) { - mainSession.notifyViewDisappeared(sessionId, (AutofillId) event); - } else if (event instanceof View) { - View view = (View) event; - ContentCaptureSession session = view.getContentCaptureSession(); - if (session == null) { - Log.w(mTag, "no content capture session on view: " + view); - continue for_each_event; - } - int actualId = session.getId(); - if (actualId != sessionId) { - Log.w(mTag, "content capture session mismatch for view (" + view - + "): was " + sessionId + " before, it's " + actualId + " now"); - continue for_each_event; - } - ViewStructure structure = session.newViewStructure(view); - view.onProvideContentCaptureStructure(structure, /* flags= */ 0); - session.notifyViewAppeared(structure); - } else { - Log.w(mTag, "invalid content capture event: " + event); - } - } - mainSession.notifyViewTreeEvent(sessionId, /* started= */ false); - } - mAttachInfo.mContentCaptureEvents = null; - } finally { - Trace.traceEnd(Trace.TRACE_TAG_VIEW); - } - } - private void notifySurfaceDestroyed() { mSurfaceHolder.ungetCallbacks(); SurfaceHolder.Callback[] callbacks = mSurfaceHolder.getCallbacks(); @@ -2966,13 +2896,6 @@ public final class ViewRootImpl implements ViewParent, } } mFirstInputStage.onWindowFocusChanged(hasWindowFocus); - - // NOTE: there's no view visibility (appeared / disapparead) events when the windows focus - // is lost, so we don't need to to force a flush - there might be other events such as - // text changes, but these should be flushed independently. - if (hasWindowFocus) { - handleContentCaptureFlush(); - } } private void fireAccessibilityFocusEventIfHasFocusedNode() { @@ -3539,86 +3462,6 @@ public final class ViewRootImpl implements ViewParent, pendingDrawFinished(); } } - if (mPerformContentCapture) { - performContentCaptureInitialReport(); - } - } - - /** - * Checks (and caches) if content capture is enabled for this context. - */ - private boolean isContentCaptureEnabled() { - switch (mContentCaptureEnabled) { - case CONTENT_CAPTURE_ENABLED_TRUE: - return true; - case CONTENT_CAPTURE_ENABLED_FALSE: - return false; - case CONTENT_CAPTURE_ENABLED_NOT_CHECKED: - final boolean reallyEnabled = isContentCaptureReallyEnabled(); - mContentCaptureEnabled = reallyEnabled ? CONTENT_CAPTURE_ENABLED_TRUE - : CONTENT_CAPTURE_ENABLED_FALSE; - return reallyEnabled; - default: - Log.w(TAG, "isContentCaptureEnabled(): invalid state " + mContentCaptureEnabled); - return false; - } - - } - - /** - * Checks (without caching) if content capture is enabled for this context. - */ - private boolean isContentCaptureReallyEnabled() { - // First check if context supports it, so it saves a service lookup when it doesn't - if (mContext.getContentCaptureOptions() == null) return false; - - final ContentCaptureManager ccm = mAttachInfo.getContentCaptureManager(mContext); - // Then check if it's enabled in the contex itself. - if (ccm == null || !ccm.isContentCaptureEnabled()) return false; - - return true; - } - - private void performContentCaptureInitialReport() { - mPerformContentCapture = false; // One-time offer! - final View rootView = mView; - if (DEBUG_CONTENT_CAPTURE) { - Log.v(mTag, "performContentCaptureInitialReport() on " + rootView); - } - if (Trace.isTagEnabled(Trace.TRACE_TAG_VIEW)) { - Trace.traceBegin(Trace.TRACE_TAG_VIEW, "dispatchContentCapture() for " - + getClass().getSimpleName()); - } - try { - if (!isContentCaptureEnabled()) return; - - // Content capture is a go! - rootView.dispatchInitialProvideContentCaptureStructure(); - } finally { - Trace.traceEnd(Trace.TRACE_TAG_VIEW); - } - } - - private void handleContentCaptureFlush() { - if (DEBUG_CONTENT_CAPTURE) { - Log.v(mTag, "handleContentCaptureFlush()"); - } - if (Trace.isTagEnabled(Trace.TRACE_TAG_VIEW)) { - Trace.traceBegin(Trace.TRACE_TAG_VIEW, "flushContentCapture for " - + getClass().getSimpleName()); - } - try { - if (!isContentCaptureEnabled()) return; - - final ContentCaptureManager ccm = mAttachInfo.mContentCaptureManager; - if (ccm == null) { - Log.w(TAG, "No ContentCapture on AttachInfo"); - return; - } - ccm.flush(ContentCaptureSession.FLUSH_REASON_VIEW_ROOT_ENTERED); - } finally { - Trace.traceEnd(Trace.TRACE_TAG_VIEW); - } } private boolean draw(boolean fullRedrawNeeded) { diff --git a/core/java/android/view/contentcapture/ContentCaptureManager.java b/core/java/android/view/contentcapture/ContentCaptureManager.java index 253935680cb8..7a6e2adfcaa4 100644 --- a/core/java/android/view/contentcapture/ContentCaptureManager.java +++ b/core/java/android/view/contentcapture/ContentCaptureManager.java @@ -191,8 +191,8 @@ import java.util.Set; * * <p>If your view provides its own virtual hierarchy (for example, if it's a browser that draws * the HTML using {@link Canvas} or native libraries in a different render process), then the view - * is also responsible to notify the session when the virtual elements appear and disappear - see - * {@link View#onProvideContentCaptureStructure(ViewStructure, int)} for more info. + * is also responsible to notify the session when the virtual elements appear and disappear - + * see {@link ContentCaptureSession#newViewStructure(View)} for more info. */ @SystemService(Context.CONTENT_CAPTURE_MANAGER_SERVICE) public final class ContentCaptureManager { @@ -578,16 +578,15 @@ public final class ContentCaptureManager { } /** - * Called by the app to request the content capture service to remove user-data associated with - * some context. + * Called by the app to remove content capture data associated with some context. * - * @param request object specifying what user data should be removed. + * @param request object specifying what data should be removed. */ - public void removeUserData(@NonNull UserDataRemovalRequest request) { + public void removeData(@NonNull DataRemovalRequest request) { Preconditions.checkNotNull(request); try { - mService.removeUserData(request); + mService.removeData(request); } catch (RemoteException e) { e.rethrowFromSystemServer(); } diff --git a/core/java/android/view/contentcapture/ContentCaptureSession.java b/core/java/android/view/contentcapture/ContentCaptureSession.java index 7761038f8af1..17a1fb405321 100644 --- a/core/java/android/view/contentcapture/ContentCaptureSession.java +++ b/core/java/android/view/contentcapture/ContentCaptureSession.java @@ -356,10 +356,6 @@ public abstract class ContentCaptureSession implements AutoCloseable { /** * Notifies the Content Capture Service that a node has been added to the view structure. * - * <p>Typically called "manually" by views that handle their own virtual view hierarchy, or - * automatically by the Android System for views that return {@code true} on - * {@link View#onProvideContentCaptureStructure(ViewStructure, int)}. - * * @param node node that has been added. */ public final void notifyViewAppeared(@NonNull ViewStructure node) { @@ -378,9 +374,6 @@ public abstract class ContentCaptureSession implements AutoCloseable { /** * Notifies the Content Capture Service that a node has been removed from the view structure. * - * <p>Typically called "manually" by views that handle their own virtual view hierarchy, or - * automatically by the Android System for standard views. - * * @param id id of the node that has been removed. */ public final void notifyViewDisappeared(@NonNull AutofillId id) { @@ -441,7 +434,46 @@ public abstract class ContentCaptureSession implements AutoCloseable { /** * Creates a {@link ViewStructure} for a "standard" view. * - * @hide + * <p>This method should be called after a visible view is laid out; the view then must populate + * the structure and pass it to {@link #notifyViewAppeared(ViewStructure)}. + * + * <b>Note: </b>views that manage a virtual structure under this view must populate just the + * node representing this view and return right away, then asynchronously report (not + * necessarily in the UI thread) when the children nodes appear, disappear or have their text + * changed by calling {@link ContentCaptureSession#notifyViewAppeared(ViewStructure)}, + * {@link ContentCaptureSession#notifyViewDisappeared(AutofillId)}, and + * {@link ContentCaptureSession#notifyViewTextChanged(AutofillId, CharSequence)} respectively. + * The structure for the a child must be created using + * {@link ContentCaptureSession#newVirtualViewStructure(AutofillId, long)}, and the + * {@code autofillId} for a child can be obtained either through + * {@code childStructure.getAutofillId()} or + * {@link ContentCaptureSession#newAutofillId(AutofillId, long)}. + * + * <p>When the virtual view hierarchy represents a web page, you should also: + * + * <ul> + * <li>Call {@link ContentCaptureManager#getContentCaptureConditions()} to infer content capture + * events should be generate for that URL. + * <li>Create a new {@link ContentCaptureSession} child for every HTML element that renders a + * new URL (like an {@code IFRAME}) and use that session to notify events from that subtree. + * </ul> + * + * <p><b>Note: </b>the following methods of the {@code structure} will be ignored: + * <ul> + * <li>{@link ViewStructure#setChildCount(int)} + * <li>{@link ViewStructure#addChildCount(int)} + * <li>{@link ViewStructure#getChildCount()} + * <li>{@link ViewStructure#newChild(int)} + * <li>{@link ViewStructure#asyncNewChild(int)} + * <li>{@link ViewStructure#asyncCommit()} + * <li>{@link ViewStructure#setWebDomain(String)} + * <li>{@link ViewStructure#newHtmlInfoBuilder(String)} + * <li>{@link ViewStructure#setHtmlInfo(android.view.ViewStructure.HtmlInfo)} + * <li>{@link ViewStructure#setDataIsSensitive(boolean)} + * <li>{@link ViewStructure#setAlpha(float)} + * <li>{@link ViewStructure#setElevation(float)} + * <li>{@link ViewStructure#setTransformation(android.graphics.Matrix)} + * </ul> */ @NonNull public final ViewStructure newViewStructure(@NonNull View view) { diff --git a/core/java/android/view/contentcapture/UserDataRemovalRequest.aidl b/core/java/android/view/contentcapture/DataRemovalRequest.aidl index fbe47e08ea7c..c89d222d159f 100644 --- a/core/java/android/view/contentcapture/UserDataRemovalRequest.aidl +++ b/core/java/android/view/contentcapture/DataRemovalRequest.aidl @@ -16,4 +16,4 @@ package android.view.contentcapture; -parcelable UserDataRemovalRequest; +parcelable DataRemovalRequest; diff --git a/core/java/android/view/contentcapture/UserDataRemovalRequest.java b/core/java/android/view/contentcapture/DataRemovalRequest.java index 3e1e4abaa84c..3792846bea71 100644 --- a/core/java/android/view/contentcapture/UserDataRemovalRequest.java +++ b/core/java/android/view/contentcapture/DataRemovalRequest.java @@ -31,14 +31,12 @@ import java.util.ArrayList; import java.util.List; /** - * Class used by apps to request the Content Capture service to remove user-data associated with - * some context. + * Class used by apps to remove content capture data associated with {@link LocusId LocusIds}. */ -public final class UserDataRemovalRequest implements Parcelable { +public final class DataRemovalRequest implements Parcelable { /** - * When set, service should use the {@link LocusId#getId()} as prefix for the data to be - * removed. + * When set, the {@link LocusId#getId()} is the prefix for the data to be removed. */ public static final int FLAG_IS_PREFIX = 0x1; @@ -54,7 +52,7 @@ public final class UserDataRemovalRequest implements Parcelable { private final boolean mForEverything; private ArrayList<LocusIdRequest> mLocusIdRequests; - private UserDataRemovalRequest(@NonNull Builder builder) { + private DataRemovalRequest(@NonNull Builder builder) { mPackageName = ActivityThread.currentActivityThread().getApplication().getPackageName(); mForEverything = builder.mForEverything; if (builder.mLocusIds != null) { @@ -67,7 +65,7 @@ public final class UserDataRemovalRequest implements Parcelable { } } - private UserDataRemovalRequest(@NonNull Parcel parcel) { + private DataRemovalRequest(@NonNull Parcel parcel) { mPackageName = parcel.readString(); mForEverything = parcel.readBoolean(); if (!mForEverything) { @@ -89,7 +87,7 @@ public final class UserDataRemovalRequest implements Parcelable { } /** - * Checks if app is requesting to remove all user data associated with its package. + * Checks if app is requesting to remove content capture data associated with its package. */ public boolean isForEverything() { return mForEverything; @@ -104,7 +102,7 @@ public final class UserDataRemovalRequest implements Parcelable { } /** - * Builder for {@link UserDataRemovalRequest} objects. + * Builder for {@link DataRemovalRequest} objects. */ public static final class Builder { @@ -115,7 +113,7 @@ public final class UserDataRemovalRequest implements Parcelable { private boolean mDestroyed; /** - * Requests servive to remove all user data associated with the app's package. + * Requests to remove all content capture data associated with the app's package. * * @return this builder */ @@ -132,7 +130,7 @@ public final class UserDataRemovalRequest implements Parcelable { * Request service to remove data associated with a given {@link LocusId}. * * @param locusId the {@link LocusId} being requested to be removed. - * @param flags either {@link UserDataRemovalRequest#FLAG_IS_PREFIX} or {@code 0} + * @param flags either {@link DataRemovalRequest#FLAG_IS_PREFIX} or {@code 0} * * @return this builder */ @@ -154,17 +152,17 @@ public final class UserDataRemovalRequest implements Parcelable { } /** - * Builds the {@link UserDataRemovalRequest}. + * Builds the {@link DataRemovalRequest}. */ @NonNull - public UserDataRemovalRequest build() { + public DataRemovalRequest build() { throwIfDestroyed(); Preconditions.checkState(mForEverything || mLocusIds != null, "must call either #forEverything() or add one #addLocusId()"); mDestroyed = true; - return new UserDataRemovalRequest(this); + return new DataRemovalRequest(this); } private void throwIfDestroyed() { @@ -192,19 +190,19 @@ public final class UserDataRemovalRequest implements Parcelable { } } - public static final @android.annotation.NonNull Parcelable.Creator<UserDataRemovalRequest> CREATOR = - new Parcelable.Creator<UserDataRemovalRequest>() { + public static final @android.annotation.NonNull Parcelable.Creator<DataRemovalRequest> CREATOR = + new Parcelable.Creator<DataRemovalRequest>() { @Override @NonNull - public UserDataRemovalRequest createFromParcel(Parcel parcel) { - return new UserDataRemovalRequest(parcel); + public DataRemovalRequest createFromParcel(Parcel parcel) { + return new DataRemovalRequest(parcel); } @Override @NonNull - public UserDataRemovalRequest[] newArray(int size) { - return new UserDataRemovalRequest[size]; + public DataRemovalRequest[] newArray(int size) { + return new DataRemovalRequest[size]; } }; @@ -231,7 +229,7 @@ public final class UserDataRemovalRequest implements Parcelable { /** * Gets the flags associates with request. * - * @return either {@link UserDataRemovalRequest#FLAG_IS_PREFIX} or {@code 0}. + * @return either {@link DataRemovalRequest#FLAG_IS_PREFIX} or {@code 0}. */ @NonNull public @Flags int getFlags() { diff --git a/core/java/android/view/contentcapture/IContentCaptureManager.aidl b/core/java/android/view/contentcapture/IContentCaptureManager.aidl index 7335073c59e0..ced941744387 100644 --- a/core/java/android/view/contentcapture/IContentCaptureManager.aidl +++ b/core/java/android/view/contentcapture/IContentCaptureManager.aidl @@ -19,7 +19,7 @@ package android.view.contentcapture; import android.content.ComponentName; import android.view.contentcapture.ContentCaptureContext; import android.view.contentcapture.ContentCaptureEvent; -import android.view.contentcapture.UserDataRemovalRequest; +import android.view.contentcapture.DataRemovalRequest; import android.os.IBinder; import com.android.internal.os.IResultReceiver; @@ -59,9 +59,9 @@ oneway interface IContentCaptureManager { void getServiceComponentName(in IResultReceiver result); /** - * Requests the removal of user data for the calling user. + * Requests the removal of content capture data for the calling user. */ - void removeUserData(in UserDataRemovalRequest request); + void removeData(in DataRemovalRequest request); /** * Returns whether the content capture feature is enabled for the calling user. diff --git a/core/java/android/view/textclassifier/ConversationActions.java b/core/java/android/view/textclassifier/ConversationActions.java index b408129231e7..f2fa67d58839 100644 --- a/core/java/android/view/textclassifier/ConversationActions.java +++ b/core/java/android/view/textclassifier/ConversationActions.java @@ -316,16 +316,20 @@ public final class ConversationActions implements Parcelable { private final List<String> mHints; @Nullable private String mCallingPackageName; + @NonNull + private Bundle mExtras; private Request( @NonNull List<Message> conversation, @NonNull TextClassifier.EntityConfig typeConfig, int maxSuggestions, - @Nullable @Hint List<String> hints) { + @Nullable @Hint List<String> hints, + @NonNull Bundle extras) { mConversation = Preconditions.checkNotNull(conversation); mTypeConfig = Preconditions.checkNotNull(typeConfig); mMaxSuggestions = maxSuggestions; mHints = hints; + mExtras = extras; } private static Request readFromParcel(Parcel in) { @@ -336,12 +340,13 @@ public final class ConversationActions implements Parcelable { List<String> hints = new ArrayList<>(); in.readStringList(hints); String callingPackageName = in.readString(); - + Bundle extras = in.readBundle(); Request request = new Request( conversation, typeConfig, maxSuggestions, - hints); + hints, + extras); request.setCallingPackageName(callingPackageName); return request; } @@ -353,6 +358,7 @@ public final class ConversationActions implements Parcelable { parcel.writeInt(mMaxSuggestions); parcel.writeStringList(mHints); parcel.writeString(mCallingPackageName); + parcel.writeBundle(mExtras); } @Override @@ -421,6 +427,16 @@ public final class ConversationActions implements Parcelable { return mCallingPackageName; } + /** + * Returns the extended data related to this request. + * + * <p><b>NOTE: </b>Do not modify this bundle. + */ + @NonNull + public Bundle getExtras() { + return mExtras; + } + /** Builder object to construct the {@link Request} object. */ public static final class Builder { @NonNull @@ -431,6 +447,8 @@ public final class ConversationActions implements Parcelable { @Nullable @Hint private List<String> mHints; + @Nullable + private Bundle mExtras; /** * Constructs a builder. @@ -469,6 +487,13 @@ public final class ConversationActions implements Parcelable { return this; } + /** Sets a set of extended data to the request. */ + @NonNull + public Builder setExtras(@Nullable Bundle bundle) { + mExtras = bundle; + return this; + } + /** Builds the {@link Request} object. */ @NonNull public Request build() { @@ -480,7 +505,8 @@ public final class ConversationActions implements Parcelable { mMaxSuggestions, mHints == null ? Collections.emptyList() - : Collections.unmodifiableList(mHints)); + : Collections.unmodifiableList(mHints), + mExtras == null ? Bundle.EMPTY : mExtras); } } } diff --git a/core/java/android/webkit/WebView.java b/core/java/android/webkit/WebView.java index 26dba45666fc..137b67c6e63e 100644 --- a/core/java/android/webkit/WebView.java +++ b/core/java/android/webkit/WebView.java @@ -413,9 +413,6 @@ public class WebView extends AbsoluteLayout if (getImportantForAutofill() == IMPORTANT_FOR_AUTOFILL_AUTO) { setImportantForAutofill(IMPORTANT_FOR_AUTOFILL_YES); } - if (getImportantForContentCapture() == IMPORTANT_FOR_CONTENT_CAPTURE_AUTO) { - setImportantForContentCapture(IMPORTANT_FOR_CONTENT_CAPTURE_YES); - } if (context == null) { throw new IllegalArgumentException("Invalid context argument"); @@ -2799,11 +2796,6 @@ public class WebView extends AbsoluteLayout } @Override - public void onProvideContentCaptureStructure(ViewStructure structure, int flags) { - mProvider.getViewDelegate().onProvideContentCaptureStructure(structure, flags); - } - - @Override public void autofill(SparseArray<AutofillValue>values) { mProvider.getViewDelegate().autofill(values); } diff --git a/core/java/android/widget/AdapterView.java b/core/java/android/widget/AdapterView.java index c55f7d654548..c3bb9a0201d0 100644 --- a/core/java/android/widget/AdapterView.java +++ b/core/java/android/widget/AdapterView.java @@ -1318,8 +1318,7 @@ public abstract class AdapterView<T extends Adapter> extends ViewGroup { @ViewStructureType int viewFor, int flags) { super.onProvideStructure(structure, viewFor, flags); - if (viewFor == VIEW_STRUCTURE_FOR_AUTOFILL - || viewFor == VIEW_STRUCTURE_FOR_CONTENT_CAPTURE) { + if (viewFor == VIEW_STRUCTURE_FOR_AUTOFILL) { final Adapter adapter = getAdapter(); if (adapter == null) return; diff --git a/core/java/android/widget/TextView.java b/core/java/android/widget/TextView.java index a961783dab7c..618b05f8cb00 100644 --- a/core/java/android/widget/TextView.java +++ b/core/java/android/widget/TextView.java @@ -161,8 +161,6 @@ import android.view.accessibility.AccessibilityNodeInfo; import android.view.animation.AnimationUtils; import android.view.autofill.AutofillManager; import android.view.autofill.AutofillValue; -import android.view.contentcapture.ContentCaptureManager; -import android.view.contentcapture.ContentCaptureSession; import android.view.inputmethod.BaseInputConnection; import android.view.inputmethod.CompletionInfo; import android.view.inputmethod.CorrectionInfo; @@ -978,9 +976,6 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener if (getImportantForAutofill() == IMPORTANT_FOR_AUTOFILL_AUTO) { setImportantForAutofill(IMPORTANT_FOR_AUTOFILL_YES); } - if (getImportantForContentCapture() == IMPORTANT_FOR_CONTENT_CAPTURE_AUTO) { - setImportantForContentCapture(IMPORTANT_FOR_CONTENT_CAPTURE_YES); - } setTextInternal(""); @@ -10520,8 +10515,7 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener } /** - * Notify managers (such as {@link AutofillManager} and {@link ContentCaptureManager}) that are - * interested on text changes. + * Notify managers (such as {@link AutofillManager}) that are interested in text changes. */ private void notifyListeningManagersAfterTextChanged() { @@ -10537,22 +10531,6 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener afm.notifyValueChanged(TextView.this); } } - - // TODO(b/121045053): should use a flag / boolean to keep status of SHOWN / HIDDEN instead - // of using isLaidout(), so it's not called in cases where it's laid out but a - // notifyAppeared was not sent. - - // ContentCapture - if (isLaidOut() && isImportantForContentCapture() && isTextEditable()) { - final ContentCaptureManager cm = mContext.getSystemService(ContentCaptureManager.class); - if (cm != null && cm.isContentCaptureEnabled()) { - final ContentCaptureSession session = getContentCaptureSession(); - if (session != null) { - // TODO(b/111276913): pass flags when edited by user / add CTS test - session.notifyViewTextChanged(getAutofillId(), getText()); - } - } - } } private boolean isAutofillable() { @@ -11386,8 +11364,7 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener final boolean isPassword = hasPasswordTransformationMethod() || isPasswordInputType(getInputType()); - if (viewFor == VIEW_STRUCTURE_FOR_AUTOFILL - || viewFor == VIEW_STRUCTURE_FOR_CONTENT_CAPTURE) { + if (viewFor == VIEW_STRUCTURE_FOR_AUTOFILL) { if (viewFor == VIEW_STRUCTURE_FOR_AUTOFILL) { structure.setDataIsSensitive(!mTextSetFromXmlOrResourceId); } @@ -11403,12 +11380,8 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener } } - if (!isPassword || viewFor == VIEW_STRUCTURE_FOR_AUTOFILL - || viewFor == VIEW_STRUCTURE_FOR_CONTENT_CAPTURE) { + if (!isPassword || viewFor == VIEW_STRUCTURE_FOR_AUTOFILL) { if (mLayout == null) { - if (viewFor == VIEW_STRUCTURE_FOR_CONTENT_CAPTURE) { - Log.w(LOG_TAG, "onProvideContentCaptureStructure(): calling assumeLayout()"); - } assumeLayout(); } Layout layout = mLayout; @@ -11496,8 +11469,7 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener } } - if (viewFor == VIEW_STRUCTURE_FOR_ASSIST - || viewFor == VIEW_STRUCTURE_FOR_CONTENT_CAPTURE) { + if (viewFor == VIEW_STRUCTURE_FOR_ASSIST) { // Extract style information that applies to the TextView as a whole. int style = 0; int typefaceStyle = getTypefaceStyle(); @@ -11525,8 +11497,7 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener structure.setTextStyle(getTextSize(), getCurrentTextColor(), AssistStructure.ViewNode.TEXT_COLOR_UNDEFINED /* bgColor */, style); } - if (viewFor == VIEW_STRUCTURE_FOR_AUTOFILL - || viewFor == VIEW_STRUCTURE_FOR_CONTENT_CAPTURE) { + if (viewFor == VIEW_STRUCTURE_FOR_AUTOFILL) { structure.setMinTextEms(getMinEms()); structure.setMaxTextEms(getMaxEms()); int maxLength = -1; diff --git a/core/java/com/android/internal/app/ChooserActivity.java b/core/java/com/android/internal/app/ChooserActivity.java index 4d4fe0397791..1597ab735680 100644 --- a/core/java/com/android/internal/app/ChooserActivity.java +++ b/core/java/com/android/internal/app/ChooserActivity.java @@ -24,6 +24,7 @@ import android.animation.AnimatorSet; import android.animation.ObjectAnimator; import android.animation.ValueAnimator; import android.annotation.IntDef; +import android.annotation.Nullable; import android.app.Activity; import android.app.ActivityManager; import android.app.prediction.AppPredictionContext; @@ -131,6 +132,7 @@ import java.util.List; public class ChooserActivity extends ResolverActivity { private static final String TAG = "ChooserActivity"; + /** * Boolean extra to change the following behavior: Normally, ChooserActivity finishes itself * in onStop when launched in a new task. If this extra is set to true, we do not finish @@ -141,7 +143,6 @@ public class ChooserActivity extends ResolverActivity { private static final boolean DEBUG = false; - /** * If {@link #USE_SHORTCUT_MANAGER_FOR_DIRECT_TARGETS} and this is set to true, * {@link AppPredictionManager} will be queried for direct share targets. @@ -433,18 +434,8 @@ public class ChooserActivity extends ResolverActivity { .addTaggedData(MetricsEvent.FIELD_SHARESHEET_MIMETYPE, target.getType()) .addTaggedData(MetricsEvent.FIELD_TIME_TO_APP_TARGETS, systemCost)); - if (USE_PREDICTION_MANAGER_FOR_DIRECT_TARGETS) { - final IntentFilter filter = getTargetIntentFilter(); - Bundle extras = new Bundle(); - extras.putParcelable(APP_PREDICTION_INTENT_FILTER_KEY, filter); - AppPredictionManager appPredictionManager = - getSystemService(AppPredictionManager.class); - mAppPredictor = appPredictionManager.createAppPredictionSession( - new AppPredictionContext.Builder(this) - .setPredictedTargetCount(APP_PREDICTION_SHARE_TARGET_QUERY_PACKAGE_LIMIT) - .setUiSurface(APP_PREDICTION_SHARE_UI_SURFACE) - .setExtras(extras) - .build()); + AppPredictor appPredictor = getAppPredictorForDirectShareIfEnabled(); + if (appPredictor != null) { mAppPredictorCallback = resultList -> { if (isFinishing() || isDestroyed()) { return; @@ -467,8 +458,10 @@ public class ChooserActivity extends ResolverActivity { appTarget.getPackageName(), appTarget.getClassName()))); } sendShareShortcutInfoList(shareShortcutInfos, driList); + sendShortcutManagerShareTargetResultCompleted(); }; - mAppPredictor.registerPredictionUpdates(this.getMainExecutor(), mAppPredictorCallback); + appPredictor + .registerPredictionUpdates(this.getMainExecutor(), mAppPredictorCallback); } mChooserRowLayer = getResources().getDrawable(R.drawable.chooser_row_layer_list, null); @@ -872,7 +865,7 @@ public class ChooserActivity extends ResolverActivity { mChooserHandler.removeMessages(LIST_VIEW_UPDATE_MESSAGE); mChooserHandler.removeMessages(CHOOSER_TARGET_SERVICE_WATCHDOG_TIMEOUT); mChooserHandler.removeMessages(CHOOSER_TARGET_SERVICE_RESULT); - if (USE_PREDICTION_MANAGER_FOR_DIRECT_TARGETS) { + if (mAppPredictor != null) { mAppPredictor.unregisterPredictionUpdates(mAppPredictorCallback); mAppPredictor.destroy(); } @@ -1205,10 +1198,12 @@ public class ChooserActivity extends ResolverActivity { } private void queryDirectShareTargets(ChooserListAdapter adapter) { - if (USE_PREDICTION_MANAGER_FOR_DIRECT_TARGETS) { - mAppPredictor.requestPredictionUpdate(); + AppPredictor appPredictor = getAppPredictorForDirectShareIfEnabled(); + if (appPredictor != null) { + appPredictor.requestPredictionUpdate(); return; } + // Default to just querying ShortcutManager if AppPredictor not present. final IntentFilter filter = getTargetIntentFilter(); if (filter == null) { return; @@ -1248,12 +1243,16 @@ public class ChooserActivity extends ResolverActivity { } if (resultMessageSent) { - final Message msg = Message.obtain(); - msg.what = SHORTCUT_MANAGER_SHARE_TARGET_RESULT_COMPLETED; - mChooserHandler.sendMessage(msg); + sendShortcutManagerShareTargetResultCompleted(); } } + private void sendShortcutManagerShareTargetResultCompleted() { + final Message msg = Message.obtain(); + msg.what = SHORTCUT_MANAGER_SHARE_TARGET_RESULT_COMPLETED; + mChooserHandler.sendMessage(msg); + } + private ChooserTarget convertToChooserTarget(ShortcutManager.ShareShortcutInfo shareShortcut) { ShortcutInfo shortcutInfo = shareShortcut.getShortcutInfo(); Bundle extras = new Bundle(); @@ -1309,9 +1308,7 @@ public class ChooserActivity extends ResolverActivity { void updateModelAndChooserCounts(TargetInfo info) { if (info != null) { - if (USE_PREDICTION_MANAGER_FOR_DIRECT_TARGETS) { - sendClickToAppPredictor(info); - } + sendClickToAppPredictor(info); final ResolveInfo ri = info.getResolveInfo(); Intent targetIntent = getTargetIntent(); if (ri != null && ri.activityInfo != null && targetIntent != null) { @@ -1332,6 +1329,10 @@ public class ChooserActivity extends ResolverActivity { } private void sendClickToAppPredictor(TargetInfo targetInfo) { + AppPredictor appPredictor = getAppPredictorForDirectShareIfEnabled(); + if (appPredictor == null) { + return; + } if (!(targetInfo instanceof ChooserTargetInfo)) { return; } @@ -1345,15 +1346,44 @@ public class ChooserActivity extends ResolverActivity { if (shortcutId == null) { return; } - mAppPredictor.notifyAppTargetEvent( + appPredictor.notifyAppTargetEvent( new AppTargetEvent.Builder( - new AppTarget.Builder(new AppTargetId(shortcutId)) - .setTarget(componentName.getPackageName(), getUser()) + // TODO(b/124404997) Send full shortcut info, not just Id with AppTargetId. + new AppTarget.Builder(new AppTargetId(shortcutId), + componentName.getPackageName(), getUser()) .setClassName(componentName.getClassName()) .build(), - AppTargetEvent.ACTION_LAUNCH - ).setLaunchLocation(LAUNCH_LOCATON_DIRECT_SHARE) - .build()); + AppTargetEvent.ACTION_LAUNCH) + .setLaunchLocation(LAUNCH_LOCATON_DIRECT_SHARE) + .build()); + } + + @Nullable + private AppPredictor getAppPredictor() { + if (mAppPredictor == null + && getPackageManager().getAppPredictionServicePackageName() != null) { + final IntentFilter filter = getTargetIntentFilter(); + Bundle extras = new Bundle(); + extras.putParcelable(APP_PREDICTION_INTENT_FILTER_KEY, filter); + AppPredictionContext appPredictionContext = new AppPredictionContext.Builder(this) + .setUiSurface(APP_PREDICTION_SHARE_UI_SURFACE) + .setPredictedTargetCount(APP_PREDICTION_SHARE_TARGET_QUERY_PACKAGE_LIMIT) + .setExtras(extras) + .build(); + AppPredictionManager appPredictionManager + = getSystemService(AppPredictionManager.class); + mAppPredictor = appPredictionManager.createAppPredictionSession(appPredictionContext); + } + return mAppPredictor; + } + + /** + * This will return an app predictor if it is enabled for direct share sorting + * and if one exists. Otherwise, it returns null. + */ + @Nullable + private AppPredictor getAppPredictorForDirectShareIfEnabled() { + return USE_PREDICTION_MANAGER_FOR_DIRECT_TARGETS ? getAppPredictor() : null; } void onRefinementResult(TargetInfo selectedTarget, Intent matchingIntent) { @@ -2014,7 +2044,8 @@ public class ChooserActivity extends ResolverActivity { } } - if (USE_SHORTCUT_MANAGER_FOR_DIRECT_TARGETS) { + if (USE_SHORTCUT_MANAGER_FOR_DIRECT_TARGETS + || USE_PREDICTION_MANAGER_FOR_DIRECT_TARGETS) { if (DEBUG) { Log.d(TAG, "querying direct share targets from ShortcutManager"); } @@ -2242,7 +2273,7 @@ public class ChooserActivity extends ResolverActivity { return CALLER_TARGET_SCORE_BOOST; } - if (USE_PREDICTION_MANAGER_FOR_DIRECT_TARGETS) { + if (getAppPredictorForDirectShareIfEnabled() != null) { return SHORTCUT_TARGET_SCORE_BOOST; } diff --git a/core/res/res/values/attrs.xml b/core/res/res/values/attrs.xml index ed8f2c196b72..ab9a298f3060 100644 --- a/core/res/res/values/attrs.xml +++ b/core/res/res/values/attrs.xml @@ -2485,24 +2485,7 @@ <flag name="noExcludeDescendants" value="0x8" /> </attr> - <!-- Hints the Android System whether the view node associated with this View should be - use for content capture purposes. --> - <attr name="importantForContentCapture"> - <!-- Let the Android System use its heuristics to determine if the view is important for content capture. --> - <flag name="auto" value="0" /> - <!-- Hint the Android System that this view is important for content capture, - and its children (if any) will be traversed.. --> - <flag name="yes" value="0x1" /> - <!-- Hint the Android System that this view is *not* important for content capture, - but its children (if any) will be traversed.. --> - <flag name="no" value="0x2" /> - <!-- Hint the Android System that this view is important for content capture, - but its children (if any) will not be traversed. --> - <flag name="yesExcludeDescendants" value="0x4" /> - <!-- Hint the Android System that this view is *not* important for content capture, - and its children (if any) will not be traversed. --> - <flag name="noExcludeDescendants" value="0x8" /> - </attr> + <attr name="__removed6" /> <!-- Boolean that controls whether a view can take focus while in touch mode. If this is true for a view, that view can gain focus when clicked on, and can keep diff --git a/core/res/res/values/config.xml b/core/res/res/values/config.xml index edcc0572cb2e..526818949b3d 100644 --- a/core/res/res/values/config.xml +++ b/core/res/res/values/config.xml @@ -745,10 +745,6 @@ <!-- XXXXXX END OF RESOURCES USING WRONG NAMING CONVENTION --> - <!-- If this is true, notification effects will be played by the notification server. - When false, car notification effects will be handled elsewhere. --> - <bool name="config_enableServerNotificationEffectsForAutomotive">false</bool> - <!-- If this is true, the screen will come on when you unplug usb/power/whatever. --> <bool name="config_unplugTurnsOnScreen">false</bool> diff --git a/core/res/res/values/public.xml b/core/res/res/values/public.xml index 9a8c754cf197..b7d61c8f8d39 100644 --- a/core/res/res/values/public.xml +++ b/core/res/res/values/public.xml @@ -2922,7 +2922,7 @@ <public name="settingsSliceUri" /> <public name="shell" /> <public name="interactiveUiTimeout" /> - <public name="importantForContentCapture" /> + <public name="__removed6" /> <public name="supportsMultipleDisplays" /> <public name="useAppZygote" /> <public name="__removed1" /> diff --git a/core/res/res/values/symbols.xml b/core/res/res/values/symbols.xml index da2f89083fef..94b5da6baa07 100644 --- a/core/res/res/values/symbols.xml +++ b/core/res/res/values/symbols.xml @@ -1910,7 +1910,6 @@ <java-symbol type="array" name="config_testLocationProviders" /> <java-symbol type="array" name="config_defaultNotificationVibePattern" /> <java-symbol type="array" name="config_notificationFallbackVibePattern" /> - <java-symbol type="bool" name="config_enableServerNotificationEffectsForAutomotive" /> <java-symbol type="bool" name="config_useAttentionLight" /> <java-symbol type="bool" name="config_adaptive_sleep_available" /> <java-symbol type="bool" name="config_animateScreenLights" /> diff --git a/core/tests/coretests/src/android/view/contentcapture/ContentCaptureManagerTest.java b/core/tests/coretests/src/android/view/contentcapture/ContentCaptureManagerTest.java index cd885e0b9bcf..7c255c9168cc 100644 --- a/core/tests/coretests/src/android/view/contentcapture/ContentCaptureManagerTest.java +++ b/core/tests/coretests/src/android/view/contentcapture/ContentCaptureManagerTest.java @@ -47,6 +47,6 @@ public class ContentCaptureManagerTest { @Test public void testRemoveUserData_invalid() { - assertThrows(NullPointerException.class, () -> mManager.removeUserData(null)); + assertThrows(NullPointerException.class, () -> mManager.removeData(null)); } } diff --git a/core/tests/coretests/src/com/android/internal/app/ChooserActivityTest.java b/core/tests/coretests/src/com/android/internal/app/ChooserActivityTest.java index 00b4a225c55f..ac039dddb66c 100644 --- a/core/tests/coretests/src/com/android/internal/app/ChooserActivityTest.java +++ b/core/tests/coretests/src/com/android/internal/app/ChooserActivityTest.java @@ -42,6 +42,7 @@ import android.content.ClipboardManager; import android.content.ComponentName; import android.content.Context; import android.content.Intent; +import android.content.pm.PackageManager; import android.content.pm.ResolveInfo; import android.database.Cursor; import android.graphics.Bitmap; @@ -53,7 +54,6 @@ import android.metrics.LogMaker; import android.net.Uri; import android.service.chooser.ChooserTarget; -import androidx.test.ext.junit.runners.AndroidJUnit4; import androidx.test.platform.app.InstrumentationRegistry; import androidx.test.rule.ActivityTestRule; @@ -62,10 +62,14 @@ import com.android.internal.app.ResolverActivity.ResolvedComponentInfo; import com.android.internal.logging.MetricsLogger; import com.android.internal.logging.nano.MetricsProto.MetricsEvent; +import java.util.Arrays; +import java.util.Collection; +import java.util.function.Function; import org.junit.Before; import org.junit.Rule; import org.junit.Test; import org.junit.runner.RunWith; +import org.junit.runners.Parameterized; import org.mockito.ArgumentCaptor; import org.mockito.Mockito; @@ -75,21 +79,48 @@ import java.util.List; /** * Chooser activity instrumentation tests */ -@RunWith(AndroidJUnit4.class) +@RunWith(Parameterized.class) public class ChooserActivityTest { + private static final Function<PackageManager, PackageManager> DEFAULT_PM = pm -> pm; + private static final Function<PackageManager, PackageManager> NO_APP_PREDICTION_SERVICE_PM = + pm -> { + PackageManager mock = Mockito.spy(pm); + when(mock.getAppPredictionServicePackageName()).thenReturn(null); + return mock; + }; + + @Parameterized.Parameters + public static Collection packageManagers() { + return Arrays.asList(new Object[][] { + {0, "Default PackageManager", DEFAULT_PM}, + {1, "No App Prediction Service", NO_APP_PREDICTION_SERVICE_PM} + }); + } + private static final int CONTENT_PREVIEW_IMAGE = 1; private static final int CONTENT_PREVIEW_FILE = 2; private static final int CONTENT_PREVIEW_TEXT = 3; + private Function<PackageManager, PackageManager> mPackageManagerOverride; + private int mTestNum; @Rule public ActivityTestRule<ChooserWrapperActivity> mActivityRule = new ActivityTestRule<>(ChooserWrapperActivity.class, false, false); + public ChooserActivityTest( + int testNum, + String testName, + Function<PackageManager, PackageManager> packageManagerOverride) { + mPackageManagerOverride = packageManagerOverride; + mTestNum = testNum; + } + @Before public void cleanOverrideData() { sOverrides.reset(); + sOverrides.createPackageManager = mPackageManagerOverride; } @Test diff --git a/libs/hwui/renderthread/ReliableSurface.cpp b/libs/hwui/renderthread/ReliableSurface.cpp index b9410c24366f..ad1fc4921781 100644 --- a/libs/hwui/renderthread/ReliableSurface.cpp +++ b/libs/hwui/renderthread/ReliableSurface.cpp @@ -300,17 +300,9 @@ int ReliableSurface::hook_perform(ANativeWindow* window, int operation, ...) { int result = callProtected(getWrapped(window), perform, operation, args); va_end(args); - switch (operation) { - case NATIVE_WINDOW_SET_BUFFERS_FORMAT: - case NATIVE_WINDOW_SET_USAGE: - case NATIVE_WINDOW_SET_USAGE64: - va_start(args, operation); - getSelf(window)->perform(operation, args); - va_end(args); - break; - default: - break; - } + va_start(args, operation); + getSelf(window)->perform(operation, args); + va_end(args); return result; } diff --git a/libs/hwui/renderthread/VulkanSurface.cpp b/libs/hwui/renderthread/VulkanSurface.cpp index 32815fe652a3..df6b9ed2cdcb 100644 --- a/libs/hwui/renderthread/VulkanSurface.cpp +++ b/libs/hwui/renderthread/VulkanSurface.cpp @@ -525,19 +525,19 @@ VulkanSurface::NativeBufferInfo* VulkanSurface::dequeueNativeBuffer() { bool VulkanSurface::presentCurrentBuffer(const SkRect& dirtyRect, int semaphoreFd) { if (!dirtyRect.isEmpty()) { - SkRect transformedRect; - mWindowInfo.preTransform.mapRect(&transformedRect, dirtyRect); - SkIRect transformedIRect; - transformedRect.roundOut(&transformedIRect); - transformedIRect.intersect(0, 0, mWindowInfo.size.fWidth, mWindowInfo.size.fHeight); + // native_window_set_surface_damage takes a rectangle in prerotated space + // with a bottom-left origin. That is, top > bottom. + // The dirtyRect is also in prerotated space, so we just need to switch it to + // a bottom-left origin space. - // map to bottom-left coordinate system + SkIRect irect; + dirtyRect.roundOut(&irect); android_native_rect_t aRect; - aRect.left = transformedIRect.x(); - aRect.top = mWindowInfo.size.fHeight - (transformedIRect.y() + transformedIRect.height()); - aRect.right = aRect.left + transformedIRect.width(); - aRect.bottom = aRect.top - transformedIRect.height(); + aRect.left = irect.left(); + aRect.top = logicalHeight() - irect.top(); + aRect.right = irect.right(); + aRect.bottom = logicalHeight() - irect.bottom(); int err = native_window_set_surface_damage(mNativeWindow.get(), &aRect, 1); ALOGE_IF(err != 0, "native_window_set_surface_damage failed: %s (%d)", strerror(-err), err); diff --git a/media/Android.bp b/media/Android.bp index 8746046c220d..5b7b26cef27a 100644 --- a/media/Android.bp +++ b/media/Android.bp @@ -64,7 +64,6 @@ filegroup { "apex/java/android/media/IMediaSession2Service.aidl", "apex/java/android/media/MediaConstants.java", "apex/java/android/media/MediaController2.java", - "apex/java/android/media/MediaItem2.java", "apex/java/android/media/MediaSession2.java", "apex/java/android/media/MediaSession2Service.java", "apex/java/android/media/Session2Command.java", diff --git a/media/apex/java/android/media/MediaItem2.java b/media/apex/java/android/media/MediaItem2.java deleted file mode 100644 index ff0d43e41350..000000000000 --- a/media/apex/java/android/media/MediaItem2.java +++ /dev/null @@ -1,310 +0,0 @@ -/* - * Copyright 2018 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 android.media; - -import static android.media.MediaMetadata.METADATA_KEY_MEDIA_ID; - -import android.annotation.NonNull; -import android.annotation.Nullable; -import android.os.Parcel; -import android.os.Parcelable; -import android.text.TextUtils; -import android.util.Log; -import android.util.Pair; - -import com.android.internal.annotations.GuardedBy; - -import java.util.ArrayList; -import java.util.List; -import java.util.concurrent.Executor; - -/** - * A class with information on a single media item with the metadata information. - * <p> - * This API is not generally intended for third party application developers. - * Use the <a href="{@docRoot}jetpack/androidx.html">AndroidX</a> - * <a href="{@docRoot}reference/androidx/media2/package-summary.html">Media2 Library</a> - * for consistent behavior across all devices. - * <p> - */ -public final class MediaItem2 implements Parcelable { - private static final String TAG = "MediaItem2"; - - // intentionally less than long.MAX_VALUE. - // Declare this first to avoid 'illegal forward reference'. - static final long LONG_MAX = 0x7ffffffffffffffL; - - /** - * Used when a position is unknown. - * - * @see #getEndPosition() - */ - public static final long POSITION_UNKNOWN = LONG_MAX; - - public static final @android.annotation.NonNull Parcelable.Creator<MediaItem2> CREATOR = - new Parcelable.Creator<MediaItem2>() { - @Override - public MediaItem2 createFromParcel(Parcel in) { - return new MediaItem2(in); - } - - @Override - public MediaItem2[] newArray(int size) { - return new MediaItem2[size]; - } - }; - - private static final long UNKNOWN_TIME = -1; - - private final long mStartPositionMs; - private final long mEndPositionMs; - - private final Object mLock = new Object(); - - @GuardedBy("mLock") - private MediaMetadata mMetadata; - @GuardedBy("mLock") - private final List<Pair<OnMetadataChangedListener, Executor>> mListeners = new ArrayList<>(); - - /** - * Used by {@link MediaItem2.Builder}. - */ - // Note: Needs to be protected when we want to allow 3rd party player to define customized - // MediaItem2. - @SuppressWarnings("WeakerAccess") /* synthetic access */ - MediaItem2(Builder builder) { - this(builder.mMetadata, builder.mStartPositionMs, builder.mEndPositionMs); - } - - /** - * Used by Parcelable.Creator. - */ - // Note: Needs to be protected when we want to allow 3rd party player to define customized - // MediaItem2. - @SuppressWarnings("WeakerAccess") /* synthetic access */ - MediaItem2(Parcel in) { - this(in.readParcelable(MediaItem2.class.getClassLoader()), in.readLong(), in.readLong()); - } - - @SuppressWarnings("WeakerAccess") /* synthetic access */ - MediaItem2(MediaItem2 item) { - this(item.mMetadata, item.mStartPositionMs, item.mEndPositionMs); - } - - @SuppressWarnings("WeakerAccess") /* synthetic access */ - MediaItem2(@Nullable MediaMetadata metadata, long startPositionMs, long endPositionMs) { - if (startPositionMs > endPositionMs) { - throw new IllegalArgumentException("Illegal start/end position: " - + startPositionMs + " : " + endPositionMs); - } - if (metadata != null && metadata.containsKey(MediaMetadata.METADATA_KEY_DURATION)) { - long durationMs = metadata.getLong(MediaMetadata.METADATA_KEY_DURATION); - if (durationMs != UNKNOWN_TIME && endPositionMs != POSITION_UNKNOWN - && endPositionMs > durationMs) { - throw new IllegalArgumentException("endPositionMs shouldn't be greater than" - + " duration in the metdata, endPositionMs=" + endPositionMs - + ", durationMs=" + durationMs); - } - } - mMetadata = metadata; - mStartPositionMs = startPositionMs; - mEndPositionMs = endPositionMs; - } - - @Override - public String toString() { - final StringBuilder sb = new StringBuilder(getClass().getSimpleName()); - synchronized (mLock) { - sb.append("{mMetadata=").append(mMetadata); - sb.append(", mStartPositionMs=").append(mStartPositionMs); - sb.append(", mEndPositionMs=").append(mEndPositionMs); - sb.append('}'); - } - return sb.toString(); - } - - /** - * Sets metadata. If the metadata is not {@code null}, its id should be matched with this - * instance's media id. - * - * @param metadata metadata to update - * @see MediaMetadata#METADATA_KEY_MEDIA_ID - */ - public void setMetadata(@Nullable MediaMetadata metadata) { - List<Pair<OnMetadataChangedListener, Executor>> listeners = new ArrayList<>(); - synchronized (mLock) { - if (mMetadata != null && metadata != null - && !TextUtils.equals(getMediaId(), metadata.getString(METADATA_KEY_MEDIA_ID))) { - Log.d(TAG, "MediaItem2's media ID shouldn't be changed"); - return; - } - mMetadata = metadata; - listeners.addAll(mListeners); - } - - for (Pair<OnMetadataChangedListener, Executor> pair : listeners) { - final OnMetadataChangedListener listener = pair.first; - pair.second.execute(new Runnable() { - @Override - public void run() { - listener.onMetadataChanged(MediaItem2.this); - } - }); - } - } - - /** - * Gets the metadata of the media. - * - * @return metadata from the session - */ - public @Nullable MediaMetadata getMetadata() { - synchronized (mLock) { - return mMetadata; - } - } - - /** - * Return the position in milliseconds at which the playback will start. - * @return the position in milliseconds at which the playback will start - */ - public long getStartPosition() { - return mStartPositionMs; - } - - /** - * Return the position in milliseconds at which the playback will end. - * {@link #POSITION_UNKNOWN} means ending at the end of source content. - * @return the position in milliseconds at which the playback will end - */ - public long getEndPosition() { - return mEndPositionMs; - } - - @Override - public int describeContents() { - return 0; - } - - @Override - public void writeToParcel(Parcel dest, int flags) { - dest.writeParcelable(mMetadata, 0); - dest.writeLong(mStartPositionMs); - dest.writeLong(mEndPositionMs); - } - - /** - * Gets the media id for this item. If it's not {@code null}, it's a persistent unique key - * for the underlying media content. - * - * @return media Id from the session - */ - @Nullable String getMediaId() { - synchronized (mLock) { - return mMetadata != null - ? mMetadata.getString(METADATA_KEY_MEDIA_ID) : null; - } - } - - void addOnMetadataChangedListener(Executor executor, OnMetadataChangedListener listener) { - synchronized (mLock) { - for (Pair<OnMetadataChangedListener, Executor> pair : mListeners) { - if (pair.first == listener) { - return; - } - } - mListeners.add(new Pair<>(listener, executor)); - } - } - - void removeOnMetadataChangedListener(OnMetadataChangedListener listener) { - synchronized (mLock) { - for (int i = mListeners.size() - 1; i >= 0; i--) { - if (mListeners.get(i).first == listener) { - mListeners.remove(i); - return; - } - } - } - } - - /** - * Builder for {@link MediaItem2}. - */ - public static final class Builder { - @SuppressWarnings("WeakerAccess") /* synthetic access */ - MediaMetadata mMetadata; - @SuppressWarnings("WeakerAccess") /* synthetic access */ - long mStartPositionMs = 0; - @SuppressWarnings("WeakerAccess") /* synthetic access */ - long mEndPositionMs = POSITION_UNKNOWN; - - /** - * Set the metadata of this instance. {@code null} for unset. - * - * @param metadata metadata - * @return this instance for chaining - */ - public @NonNull Builder setMetadata(@Nullable MediaMetadata metadata) { - mMetadata = metadata; - return this; - } - - /** - * Sets the start position in milliseconds at which the playback will start. - * Any negative number is treated as 0. - * - * @param position the start position in milliseconds at which the playback will start - * @return the same Builder instance. - */ - public @NonNull Builder setStartPosition(long position) { - if (position < 0) { - position = 0; - } - mStartPositionMs = position; - return this; - } - - /** - * Sets the end position in milliseconds at which the playback will end. - * Any negative number is treated as maximum length of the media item. - * - * @param position the end position in milliseconds at which the playback will end - * @return the same Builder instance. - */ - public @NonNull Builder setEndPosition(long position) { - if (position < 0) { - position = POSITION_UNKNOWN; - } - mEndPositionMs = position; - return this; - } - - /** - * Build {@link MediaItem2}. - * - * @return a new {@link MediaItem2}. - */ - public @NonNull MediaItem2 build() { - return new MediaItem2(this); - } - } - - interface OnMetadataChangedListener { - void onMetadataChanged(MediaItem2 item); - } -} diff --git a/media/java/android/media/AudioManager.java b/media/java/android/media/AudioManager.java index 88312658bb2c..d3471378b9d9 100644 --- a/media/java/android/media/AudioManager.java +++ b/media/java/android/media/AudioManager.java @@ -3431,6 +3431,20 @@ public class AudioManager { } } + /** + * @hide + * @return true if an AudioPolicy was previously registered + */ + @TestApi + public boolean hasRegisteredDynamicPolicy() { + final IAudioService service = getService(); + try { + return service.hasRegisteredDynamicPolicy(); + } catch (RemoteException e) { + throw e.rethrowFromSystemServer(); + } + } + //==================================================================== // Notification of playback activity & playback configuration /** diff --git a/media/java/android/media/AudioTrack.java b/media/java/android/media/AudioTrack.java index 790e189e9109..d9d614f7ead4 100644 --- a/media/java/android/media/AudioTrack.java +++ b/media/java/android/media/AudioTrack.java @@ -975,13 +975,9 @@ public class AudioTrack extends PlayerBase throw new UnsupportedOperationException( "Offload and low latency modes are incompatible"); } - if (mAttributes.getUsage() != AudioAttributes.USAGE_MEDIA) { - throw new UnsupportedOperationException( - "Cannot create AudioTrack, offload requires USAGE_MEDIA"); - } if (!AudioSystem.isOffloadSupported(mFormat, mAttributes)) { throw new UnsupportedOperationException( - "Cannot create AudioTrack, offload format not supported"); + "Cannot create AudioTrack, offload format / attributes not supported"); } } diff --git a/media/java/android/media/IAudioService.aidl b/media/java/android/media/IAudioService.aidl index eddbee46252e..85de00a2a989 100644 --- a/media/java/android/media/IAudioService.aidl +++ b/media/java/android/media/IAudioService.aidl @@ -211,6 +211,8 @@ interface IAudioService { void setVolumePolicy(in VolumePolicy policy); + boolean hasRegisteredDynamicPolicy(); + void registerRecordingCallback(in IRecordingConfigDispatcher rcdb); oneway void unregisterRecordingCallback(in IRecordingConfigDispatcher rcdb); diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardUpdateMonitor.java b/packages/SystemUI/src/com/android/keyguard/KeyguardUpdateMonitor.java index fd557083aefd..1d19fecac8c9 100644 --- a/packages/SystemUI/src/com/android/keyguard/KeyguardUpdateMonitor.java +++ b/packages/SystemUI/src/com/android/keyguard/KeyguardUpdateMonitor.java @@ -665,9 +665,9 @@ public class KeyguardUpdateMonitor implements TrustManager.TrustListener { boolean wasRunning = mFingerprintRunningState == BIOMETRIC_STATE_RUNNING; boolean isRunning = fingerprintRunningState == BIOMETRIC_STATE_RUNNING; mFingerprintRunningState = fingerprintRunningState; - if (DEBUG) Log.v(TAG, "Fingerprint State: " + mFingerprintRunningState); + Log.d(TAG, "fingerprintRunningState: " + mFingerprintRunningState); // Clients of KeyguardUpdateMonitor don't care about the internal state about the - // asynchronousness of the cancel cycle. So only notify them if the actualy running state + // asynchronousness of the cancel cycle. So only notify them if the actually running state // has changed. if (wasRunning != isRunning) { notifyFingerprintRunningStateChanged(); @@ -818,9 +818,9 @@ public class KeyguardUpdateMonitor implements TrustManager.TrustListener { boolean wasRunning = mFaceRunningState == BIOMETRIC_STATE_RUNNING; boolean isRunning = faceRunningState == BIOMETRIC_STATE_RUNNING; mFaceRunningState = faceRunningState; - if (DEBUG) Log.v(TAG, "Face State: " + mFaceRunningState); + Log.d(TAG, "faceRunningState: " + mFaceRunningState); // Clients of KeyguardUpdateMonitor don't care about the internal state or about the - // asynchronousness of the cancel cycle. So only notify them if the actualy running state + // asynchronousness of the cancel cycle. So only notify them if the actually running state // has changed. if (wasRunning != isRunning) { notifyFaceRunningStateChanged(); @@ -2045,7 +2045,7 @@ public class KeyguardUpdateMonitor implements TrustManager.TrustListener { */ public void onKeyguardVisibilityChanged(boolean showing) { checkIsHandlerThread(); - if (DEBUG) Log.d(TAG, "onKeyguardVisibilityChanged(" + showing + ")"); + Log.d(TAG, "onKeyguardVisibilityChanged(" + showing + ")"); mKeyguardIsVisible = showing; for (int i = 0; i < mCallbacks.size(); i++) { KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get(); diff --git a/packages/SystemUI/src/com/android/systemui/recents/OverviewProxyService.java b/packages/SystemUI/src/com/android/systemui/recents/OverviewProxyService.java index 72559f56aaa1..56dbe2b2cd99 100644 --- a/packages/SystemUI/src/com/android/systemui/recents/OverviewProxyService.java +++ b/packages/SystemUI/src/com/android/systemui/recents/OverviewProxyService.java @@ -608,6 +608,7 @@ public class OverviewProxyService implements CallbackController<OverviewProxyLis mConnectionCallbacks.add(listener); listener.onConnectionChanged(mOverviewProxy != null); listener.onInteractionFlagsChanged(mInteractionFlags); + listener.onBackButtonAlphaChanged(mBackButtonAlpha, false); } @Override diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/NavigationBarController.java b/packages/SystemUI/src/com/android/systemui/statusbar/NavigationBarController.java index 907b3ad08c8c..85848cafbfcb 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/NavigationBarController.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/NavigationBarController.java @@ -151,7 +151,7 @@ public class NavigationBarController implements Callbacks { ? Dependency.get(AutoHideController.class) : new AutoHideController(context, mHandler); navBar.setAutoHideController(autoHideController); - navBar.setSystemUiVisibility(View.SYSTEM_UI_FLAG_VISIBLE); + navBar.restoreSystemUiVisibilityState(); mNavigationBars.append(displayId, navBar); if (result != null) { diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/ButtonDispatcher.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/ButtonDispatcher.java index 4ced702f479e..959342b27b56 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/ButtonDispatcher.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/ButtonDispatcher.java @@ -141,6 +141,11 @@ public class ButtonDispatcher { public void setVisibility(int visibility) { if (mVisibility == visibility) return; + if (mFadeAnimator != null) { + mFadeAnimator.cancel(); + mFadeAnimator = null; + } + mVisibility = visibility; final int N = mViews.size(); for (int i = 0; i < N; i++) { diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarFragment.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarFragment.java index 9eecdb924448..4d2b56c5e81a 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarFragment.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarFragment.java @@ -123,6 +123,7 @@ public class NavigationBarFragment extends LifecycleFragment implements Callback private static final boolean DEBUG = false; private static final String EXTRA_DISABLE_STATE = "disabled_state"; private static final String EXTRA_DISABLE2_STATE = "disabled2_state"; + private static final String EXTRA_SYSTEM_UI_VISIBILITY = "system_ui_visibility"; /** Allow some time inbetween the long press for back and recents. */ private static final int LOCK_TO_APP_GESTURE_TOLERENCE = 200; @@ -156,7 +157,7 @@ public class NavigationBarFragment extends LifecycleFragment implements Callback private Locale mLocale; private int mLayoutDirection; - private int mSystemUiVisibility; + private int mSystemUiVisibility = View.SYSTEM_UI_FLAG_VISIBLE; private LightBarController mLightBarController; private AutoHideController mAutoHideController; @@ -277,6 +278,7 @@ public class NavigationBarFragment extends LifecycleFragment implements Callback if (savedInstanceState != null) { mDisabledFlags1 = savedInstanceState.getInt(EXTRA_DISABLE_STATE, 0); mDisabledFlags2 = savedInstanceState.getInt(EXTRA_DISABLE2_STATE, 0); + mSystemUiVisibility = savedInstanceState.getInt(EXTRA_SYSTEM_UI_VISIBILITY, 0); } mAccessibilityManagerWrapper.addCallback(mAccessibilityListener); @@ -363,6 +365,7 @@ public class NavigationBarFragment extends LifecycleFragment implements Callback super.onSaveInstanceState(outState); outState.putInt(EXTRA_DISABLE_STATE, mDisabledFlags1); outState.putInt(EXTRA_DISABLE2_STATE, mDisabledFlags2); + outState.putInt(EXTRA_SYSTEM_UI_VISIBILITY, mSystemUiVisibility); if (mNavigationBarView != null) { mNavigationBarView.getLightTransitionsController().saveState(outState); } @@ -492,13 +495,8 @@ public class NavigationBarFragment extends LifecycleFragment implements Callback } } - /** - * Sets System UI flags to {@link NavigationBarFragment}. - * - * @see View#setSystemUiVisibility(int) - */ - public void setSystemUiVisibility(int systemUiVisibility) { - mSystemUiVisibility = systemUiVisibility; + /** Restores the System UI flags saved state to {@link NavigationBarFragment}. */ + public void restoreSystemUiVisibilityState() { final int barMode = computeBarMode(0, mSystemUiVisibility); if (barMode != -1) { mNavigationBarMode = barMode; diff --git a/services/accessibility/java/com/android/server/accessibility/MotionEventInjector.java b/services/accessibility/java/com/android/server/accessibility/MotionEventInjector.java index 46e3226bb751..7b6a12822faa 100644 --- a/services/accessibility/java/com/android/server/accessibility/MotionEventInjector.java +++ b/services/accessibility/java/com/android/server/accessibility/MotionEventInjector.java @@ -111,6 +111,15 @@ public class MotionEventInjector extends BaseEventStreamTransformation implement @Override public void onMotionEvent(MotionEvent event, MotionEvent rawEvent, int policyFlags) { + // MotionEventInjector would cancel any injected gesture when any MotionEvent arrives. + // For user using an external device to control the pointer movement, it's almost + // impossible to perform the gestures. Any slightly unintended movement results in the + // cancellation of the gesture. + if ((event.isFromSource(InputDevice.SOURCE_MOUSE) + && event.getActionMasked() == MotionEvent.ACTION_HOVER_MOVE) + && mOpenGesturesInProgress.get(EVENT_SOURCE, false)) { + return; + } cancelAnyPendingInjectedEvents(); sendMotionEventToNext(event, rawEvent, policyFlags); } diff --git a/services/contentcapture/java/com/android/server/contentcapture/ContentCaptureManagerService.java b/services/contentcapture/java/com/android/server/contentcapture/ContentCaptureManagerService.java index 757c2dc7f6f1..7f411d83b34b 100644 --- a/services/contentcapture/java/com/android/server/contentcapture/ContentCaptureManagerService.java +++ b/services/contentcapture/java/com/android/server/contentcapture/ContentCaptureManagerService.java @@ -60,8 +60,8 @@ import android.util.SparseBooleanArray; import android.view.contentcapture.ContentCaptureCondition; import android.view.contentcapture.ContentCaptureHelper; import android.view.contentcapture.ContentCaptureManager; +import android.view.contentcapture.DataRemovalRequest; import android.view.contentcapture.IContentCaptureManager; -import android.view.contentcapture.UserDataRemovalRequest; import com.android.internal.annotations.GuardedBy; import com.android.internal.infra.AbstractRemoteService; @@ -583,14 +583,14 @@ public final class ContentCaptureManagerService extends } @Override - public void removeUserData(@NonNull UserDataRemovalRequest request) { + public void removeData(@NonNull DataRemovalRequest request) { Preconditions.checkNotNull(request); assertCalledByPackageOwner(request.getPackageName()); final int userId = UserHandle.getCallingUserId(); synchronized (mLock) { final ContentCapturePerUserService service = getServiceForUserLocked(userId); - service.removeUserDataLocked(request); + service.removeDataLocked(request); } } diff --git a/services/contentcapture/java/com/android/server/contentcapture/ContentCapturePerUserService.java b/services/contentcapture/java/com/android/server/contentcapture/ContentCapturePerUserService.java index 564952697250..b4a1f381f7ff 100644 --- a/services/contentcapture/java/com/android/server/contentcapture/ContentCapturePerUserService.java +++ b/services/contentcapture/java/com/android/server/contentcapture/ContentCapturePerUserService.java @@ -57,7 +57,7 @@ import android.util.ArraySet; import android.util.Slog; import android.util.SparseArray; import android.view.contentcapture.ContentCaptureCondition; -import android.view.contentcapture.UserDataRemovalRequest; +import android.view.contentcapture.DataRemovalRequest; import com.android.internal.annotations.GuardedBy; import com.android.internal.infra.WhitelistHelper; @@ -343,12 +343,12 @@ final class ContentCapturePerUserService } @GuardedBy("mLock") - public void removeUserDataLocked(@NonNull UserDataRemovalRequest request) { + public void removeDataLocked(@NonNull DataRemovalRequest request) { if (!isEnabledLocked()) { return; } assertCallerLocked(request.getPackageName()); - mRemoteService.onUserDataRemovalRequest(request); + mRemoteService.onDataRemovalRequest(request); } @GuardedBy("mLock") diff --git a/services/contentcapture/java/com/android/server/contentcapture/RemoteContentCaptureService.java b/services/contentcapture/java/com/android/server/contentcapture/RemoteContentCaptureService.java index 3fa3fdf6d36e..2171033c5a28 100644 --- a/services/contentcapture/java/com/android/server/contentcapture/RemoteContentCaptureService.java +++ b/services/contentcapture/java/com/android/server/contentcapture/RemoteContentCaptureService.java @@ -29,7 +29,7 @@ import android.service.contentcapture.IContentCaptureServiceCallback; import android.service.contentcapture.SnapshotData; import android.util.Slog; import android.view.contentcapture.ContentCaptureContext; -import android.view.contentcapture.UserDataRemovalRequest; +import android.view.contentcapture.DataRemovalRequest; import com.android.internal.infra.AbstractMultiplePendingRequestsRemoteService; import com.android.internal.os.IResultReceiver; @@ -120,10 +120,10 @@ final class RemoteContentCaptureService } /** - * Called by {@link ContentCaptureServerSession} to request removal of user data. + * Called by {@link ContentCaptureServerSession} to request removal of content capture data. */ - public void onUserDataRemovalRequest(@NonNull UserDataRemovalRequest request) { - scheduleAsyncRequest((s) -> s.onUserDataRemovalRequest(request)); + public void onDataRemovalRequest(@NonNull DataRemovalRequest request) { + scheduleAsyncRequest((s) -> s.onDataRemovalRequest(request)); } /** diff --git a/services/core/java/com/android/server/BluetoothService.java b/services/core/java/com/android/server/BluetoothService.java index 6018f008054c..5c5b477352b1 100644 --- a/services/core/java/com/android/server/BluetoothService.java +++ b/services/core/java/com/android/server/BluetoothService.java @@ -18,11 +18,10 @@ package com.android.server; import android.bluetooth.BluetoothAdapter; import android.content.Context; -import android.os.SystemProperties; -class BluetoothService extends SystemService { - private static final String HEADLESS_SYSTEM_USER = "android.car.systemuser.headless"; +import com.android.internal.os.RoSystemProperties; +class BluetoothService extends SystemService { private BluetoothManagerService mBluetoothManagerService; private boolean mInitialized = false; @@ -48,7 +47,7 @@ class BluetoothService extends SystemService { publishBinderService(BluetoothAdapter.BLUETOOTH_MANAGER_SERVICE, mBluetoothManagerService); } else if (phase == SystemService.PHASE_ACTIVITY_MANAGER_READY && - !SystemProperties.getBoolean(HEADLESS_SYSTEM_USER, false)) { + !RoSystemProperties.MULTIUSER_HEADLESS_SYSTEM_USER) { initialize(); } } diff --git a/services/core/java/com/android/server/attention/AttentionManagerService.java b/services/core/java/com/android/server/attention/AttentionManagerService.java index 3dbea0d1978e..411dd794d1bd 100644 --- a/services/core/java/com/android/server/attention/AttentionManagerService.java +++ b/services/core/java/com/android/server/attention/AttentionManagerService.java @@ -17,7 +17,6 @@ package com.android.server.attention; import static android.provider.DeviceConfig.NAMESPACE_ATTENTION_MANAGER_SERVICE; -import static android.provider.Settings.System.ADAPTIVE_SLEEP; import static android.service.attention.AttentionService.ATTENTION_FAILURE_CANCELLED; import static android.service.attention.AttentionService.ATTENTION_FAILURE_UNKNOWN; @@ -47,7 +46,6 @@ import android.os.RemoteException; import android.os.SystemClock; import android.os.UserHandle; import android.provider.DeviceConfig; -import android.provider.Settings; import android.service.attention.AttentionService; import android.service.attention.AttentionService.AttentionFailureCodes; import android.service.attention.AttentionService.AttentionSuccessCodes; @@ -275,19 +273,6 @@ public class AttentionManagerService extends SystemService { } } - /** Disables service dependants. */ - private void disableSelf() { - final long identity = Binder.clearCallingIdentity(); - try { - if (DEBUG) { - Slog.d(LOG_TAG, "Disabling self."); - } - Settings.System.putInt(mContext.getContentResolver(), ADAPTIVE_SLEEP, 0); - } finally { - Binder.restoreCallingIdentity(identity); - } - } - @GuardedBy("mLock") private void freeIfInactiveLocked() { // If we are called here, it means someone used the API again - reset the timer then. @@ -418,11 +403,6 @@ public class AttentionManagerService extends SystemService { public void cancelAttentionCheck(AttentionCallbackInternal callbackInternal) { AttentionManagerService.this.cancelAttentionCheck(callbackInternal); } - - @Override - public void disableSelf() { - AttentionManagerService.this.disableSelf(); - } } private static final class AttentionCheckCache { diff --git a/services/core/java/com/android/server/audio/AudioService.java b/services/core/java/com/android/server/audio/AudioService.java index 70af907f66a7..aee08bb09401 100644 --- a/services/core/java/com/android/server/audio/AudioService.java +++ b/services/core/java/com/android/server/audio/AudioService.java @@ -6671,6 +6671,13 @@ public class AudioService extends IAudioService.Stub return AudioManager.SUCCESS; } + /** see AudioManager.hasRegisteredDynamicPolicy */ + public boolean hasRegisteredDynamicPolicy() { + synchronized (mAudioPolicies) { + return !mAudioPolicies.isEmpty(); + } + } + private final Object mExtVolumeControllerLock = new Object(); private IAudioPolicyCallback mExtVolumeController; private void setExtVolumeController(IAudioPolicyCallback apc) { diff --git a/services/core/java/com/android/server/notification/NotificationManagerService.java b/services/core/java/com/android/server/notification/NotificationManagerService.java index ee2e4f573fb9..7f1b25ca3ca3 100644 --- a/services/core/java/com/android/server/notification/NotificationManagerService.java +++ b/services/core/java/com/android/server/notification/NotificationManagerService.java @@ -455,7 +455,6 @@ public class NotificationManagerService extends SystemService { private int mAutoGroupAtCount; private boolean mIsTelevision; private boolean mIsAutomotive; - private boolean mNotificationEffectsEnabledForAutomotive; private MetricsLogger mMetricsLogger; private TriPredicate<String, Integer, String> mAllowedManagedServicePackages; @@ -1687,8 +1686,6 @@ public class NotificationManagerService extends SystemService { mIsAutomotive = mPackageManagerClient.hasSystemFeature(PackageManager.FEATURE_AUTOMOTIVE, 0); - mNotificationEffectsEnabledForAutomotive = - resources.getBoolean(R.bool.config_enableServerNotificationEffectsForAutomotive); mPreferencesHelper.lockChannelsForOEM(getContext().getResources().getStringArray( com.android.internal.R.array.config_nonBlockableNotificationPackages)); @@ -5563,9 +5560,6 @@ public class NotificationManagerService extends SystemService { @VisibleForTesting @GuardedBy("mNotificationLock") void buzzBeepBlinkLocked(NotificationRecord record) { - if (mIsAutomotive && !mNotificationEffectsEnabledForAutomotive) { - return; - } boolean buzz = false; boolean beep = false; boolean blink = false; diff --git a/services/core/java/com/android/server/pm/PackageManagerService.java b/services/core/java/com/android/server/pm/PackageManagerService.java index 7b418b51957c..d2b1e8f7151d 100644 --- a/services/core/java/com/android/server/pm/PackageManagerService.java +++ b/services/core/java/com/android/server/pm/PackageManagerService.java @@ -20752,8 +20752,16 @@ public class PackageManagerService extends IPackageManager.Stub } @Override - public String getAttentionServicePackageName() { - return mContext.getString(R.string.config_defaultAttentionService); + public @Nullable String getAttentionServicePackageName() { + final String flattenedComponentName = + mContext.getString(R.string.config_defaultAttentionService); + if (flattenedComponentName != null) { + ComponentName componentName = ComponentName.unflattenFromString(flattenedComponentName); + if (componentName != null && componentName.getPackageName() != null) { + return componentName.getPackageName(); + } + } + return null; } private @Nullable String getDocumenterPackageName() { diff --git a/services/core/java/com/android/server/power/AttentionDetector.java b/services/core/java/com/android/server/power/AttentionDetector.java index d9d21babe210..5e829b2d6067 100644 --- a/services/core/java/com/android/server/power/AttentionDetector.java +++ b/services/core/java/com/android/server/power/AttentionDetector.java @@ -16,9 +16,14 @@ package com.android.server.power; +import static android.provider.Settings.System.ADAPTIVE_SLEEP; + +import android.Manifest; import android.attention.AttentionManagerInternal; import android.attention.AttentionManagerInternal.AttentionCallbackInternal; +import android.content.ContentResolver; import android.content.Context; +import android.content.pm.PackageManager; import android.database.ContentObserver; import android.os.Handler; import android.os.PowerManager; @@ -83,6 +88,12 @@ public class AttentionDetector { @VisibleForTesting protected AttentionManagerInternal mAttentionManager; + @VisibleForTesting + protected PackageManager mPackageManager; + + @VisibleForTesting + protected ContentResolver mContentResolver; + /** * Current wakefulness of the device. {@see PowerManagerInternal} */ @@ -137,6 +148,8 @@ public class AttentionDetector { public void systemReady(Context context) { updateEnabledFromSettings(context); + mPackageManager = context.getPackageManager(); + mContentResolver = context.getContentResolver(); mAttentionManager = LocalServices.getService(AttentionManagerInternal.class); mMaximumExtensionMillis = context.getResources().getInteger( com.android.internal.R.integer.config_attentionMaximumExtension); @@ -162,6 +175,11 @@ public class AttentionDetector { return nextScreenDimming; } + if (!serviceHasSufficientPermissions()) { + Settings.System.putInt(mContentResolver, ADAPTIVE_SLEEP, 0); + return nextScreenDimming; + } + final long now = SystemClock.uptimeMillis(); final long whenToCheck = nextScreenDimming - getAttentionTimeout(); final long whenToStopExtending = mLastUserActivityTime + mMaximumExtensionMillis; @@ -263,6 +281,18 @@ public class AttentionDetector { return mAttentionManager != null && mAttentionManager.isAttentionServiceSupported(); } + /** + * Returns {@code true} if the attention service has sufficient permissions, disables the + * depending features otherwise. + */ + @VisibleForTesting + boolean serviceHasSufficientPermissions() { + final String attentionPackage = mPackageManager.getAttentionServicePackageName(); + return attentionPackage != null && mPackageManager.checkPermission( + Manifest.permission.CAMERA, attentionPackage) + == PackageManager.PERMISSION_GRANTED; + } + public void dump(PrintWriter pw) { pw.print("AttentionDetector:"); pw.print(" mMaximumExtensionMillis=" + mMaximumExtensionMillis); diff --git a/services/core/java/com/android/server/wm/ActivityStartController.java b/services/core/java/com/android/server/wm/ActivityStartController.java index b287a0b011e7..7eac07c47741 100644 --- a/services/core/java/com/android/server/wm/ActivityStartController.java +++ b/services/core/java/com/android/server/wm/ActivityStartController.java @@ -457,7 +457,7 @@ public class ActivityStartController { "pendingActivityLaunch"); try { starter.startResolvedActivity(pal.r, pal.sourceRecord, null, null, pal.startFlags, - resume, pal.r.pendingOptions, null, null /* outRecords */); + resume, pal.r.pendingOptions, null); } catch (Exception e) { Slog.e(TAG, "Exception during pending activity launch pal=" + pal, e); pal.sendErrorResult(e.getMessage()); diff --git a/services/core/java/com/android/server/wm/ActivityStarter.java b/services/core/java/com/android/server/wm/ActivityStarter.java index 895744424ee1..9fa13146e57e 100644 --- a/services/core/java/com/android/server/wm/ActivityStarter.java +++ b/services/core/java/com/android/server/wm/ActivityStarter.java @@ -544,11 +544,17 @@ class ActivityStarter { */ int startResolvedActivity(final ActivityRecord r, ActivityRecord sourceRecord, IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor, - int startFlags, boolean doResume, ActivityOptions options, TaskRecord inTask, - ActivityRecord[] outActivity) { + int startFlags, boolean doResume, ActivityOptions options, TaskRecord inTask) { try { - return startActivity(r, sourceRecord, voiceSession, voiceInteractor, startFlags, - doResume, options, inTask, outActivity); + mSupervisor.getActivityMetricsLogger().notifyActivityLaunching(r.intent); + mLastStartReason = "startResolvedActivity"; + mLastStartActivityTimeMs = System.currentTimeMillis(); + mLastStartActivityRecord[0] = r; + mLastStartActivityResult = startActivity(r, sourceRecord, voiceSession, voiceInteractor, + startFlags, doResume, options, inTask, mLastStartActivityRecord); + mSupervisor.getActivityMetricsLogger().notifyActivityLaunched(mLastStartActivityResult, + mLastStartActivityRecord[0]); + return mLastStartActivityResult; } finally { onExecutionComplete(); } diff --git a/services/core/java/com/android/server/wm/Dimmer.java b/services/core/java/com/android/server/wm/Dimmer.java index 4bd8cab05700..a7a793fa8d34 100644 --- a/services/core/java/com/android/server/wm/Dimmer.java +++ b/services/core/java/com/android/server/wm/Dimmer.java @@ -41,7 +41,7 @@ class Dimmer { private static final int DEFAULT_DIM_ANIM_DURATION = 200; private class DimAnimatable implements SurfaceAnimator.Animatable { - private final SurfaceControl mDimLayer; + private SurfaceControl mDimLayer; private DimAnimatable(SurfaceControl dimLayer) { mDimLayer = dimLayer; @@ -100,6 +100,11 @@ class Dimmer { // See getSurfaceWidth() above for explanation. return mHost.getSurfaceHeight(); } + + void removeSurface() { + getPendingTransaction().remove(mDimLayer); + mDimLayer = null; + } } @VisibleForTesting @@ -129,8 +134,7 @@ class Dimmer { final DimAnimatable dimAnimatable = new DimAnimatable(dimLayer); mSurfaceAnimator = new SurfaceAnimator(dimAnimatable, () -> { if (!mDimming) { - dimAnimatable.getPendingTransaction().remove(mDimLayer); - mDimLayer = null; + dimAnimatable.removeSurface(); } }, mHost.mWmService); } diff --git a/services/core/java/com/android/server/wm/ImmersiveModeConfirmation.java b/services/core/java/com/android/server/wm/ImmersiveModeConfirmation.java index 3d20501222b6..d774dc3fd2f1 100644 --- a/services/core/java/com/android/server/wm/ImmersiveModeConfirmation.java +++ b/services/core/java/com/android/server/wm/ImmersiveModeConfirmation.java @@ -90,8 +90,6 @@ public class ImmersiveModeConfirmation { mShowDelayMs = getNavBarExitDuration() * 3; mPanicThresholdMs = context.getResources() .getInteger(R.integer.config_immersive_mode_confirmation_panic); - mWindowManager = (WindowManager) - mContext.getSystemService(Context.WINDOW_SERVICE); mVrModeEnabled = vrModeEnabled; } @@ -177,7 +175,7 @@ public class ImmersiveModeConfirmation { private void handleHide() { if (mClingWindow != null) { if (DEBUG) Slog.d(TAG, "Hiding immersive mode confirmation"); - mWindowManager.removeView(mClingWindow); + getWindowManager().removeView(mClingWindow); mClingWindow = null; } } @@ -275,7 +273,7 @@ public class ImmersiveModeConfirmation { super.onAttachedToWindow(); DisplayMetrics metrics = new DisplayMetrics(); - mWindowManager.getDefaultDisplay().getMetrics(metrics); + getWindowManager().getDefaultDisplay().getMetrics(metrics); float density = metrics.density; getViewTreeObserver().addOnComputeInternalInsetsListener(mInsetsListener); @@ -341,6 +339,19 @@ public class ImmersiveModeConfirmation { } } + /** + * DO HOLD THE WINDOW MANAGER LOCK WHEN CALLING THIS METHOD + * The reason why we add this method is to avoid the deadlock of WMG->WMS and WMS->WMG + * when ImmersiveModeConfirmation object is created. + */ + private WindowManager getWindowManager() { + if (mWindowManager == null) { + mWindowManager = (WindowManager) + mContext.getSystemService(Context.WINDOW_SERVICE); + } + return mWindowManager; + } + private void handleShow() { if (DEBUG) Slog.d(TAG, "Showing immersive mode confirmation"); @@ -352,7 +363,7 @@ public class ImmersiveModeConfirmation { // show the confirmation WindowManager.LayoutParams lp = getClingWindowLayoutParams(); - mWindowManager.addView(mClingWindow, lp); + getWindowManager().addView(mClingWindow, lp); } private final Runnable mConfirm = new Runnable() { diff --git a/services/core/java/com/android/server/wm/RecentTasks.java b/services/core/java/com/android/server/wm/RecentTasks.java index d6c7b21e16b2..7dcbedf811c2 100644 --- a/services/core/java/com/android/server/wm/RecentTasks.java +++ b/services/core/java/com/android/server/wm/RecentTasks.java @@ -60,7 +60,6 @@ import android.os.Bundle; import android.os.Environment; import android.os.IBinder; import android.os.RemoteException; -import android.os.SystemClock; import android.os.SystemProperties; import android.os.UserHandle; import android.text.TextUtils; @@ -185,7 +184,6 @@ class RecentTasks { // front. Newly created tasks, or tasks that are removed from the list will continue to change // the list. This does not affect affiliated tasks. private boolean mFreezeTaskListReordering; - private long mFreezeTaskListReorderingTime; private long mFreezeTaskListTimeoutMs = FREEZE_TASK_LIST_TIMEOUT_MS; // Mainly to avoid object recreation on multiple calls. @@ -220,6 +218,9 @@ class RecentTasks { } }; + private final Runnable mResetFreezeTaskListOnTimeoutRunnable = + this::resetFreezeTaskListReorderingOnTimeout; + @VisibleForTesting RecentTasks(ActivityTaskManagerService service, TaskPersister taskPersister) { mService = service; @@ -255,8 +256,7 @@ class RecentTasks { } @VisibleForTesting - void setFreezeTaskListTimeoutParams(long reorderingTime, long timeoutMs) { - mFreezeTaskListReorderingTime = reorderingTime; + void setFreezeTaskListTimeout(long timeoutMs) { mFreezeTaskListTimeoutMs = timeoutMs; } @@ -272,7 +272,8 @@ class RecentTasks { // Always update the reordering time when this is called to ensure that the timeout // is reset mFreezeTaskListReordering = true; - mFreezeTaskListReorderingTime = SystemClock.elapsedRealtime(); + mService.mH.removeCallbacks(mResetFreezeTaskListOnTimeoutRunnable); + mService.mH.postDelayed(mResetFreezeTaskListOnTimeoutRunnable, mFreezeTaskListTimeoutMs); } /** @@ -286,6 +287,7 @@ class RecentTasks { // Once we end freezing the task list, reset the existing task order to the stable state mFreezeTaskListReordering = false; + mService.mH.removeCallbacks(mResetFreezeTaskListOnTimeoutRunnable); // If the top task is provided, then restore the top task to the front of the list if (topTask != null) { @@ -295,6 +297,8 @@ class RecentTasks { // Resume trimming tasks trimInactiveRecentTasks(); + + mService.getTaskChangeNotificationController().notifyTaskStackChanged(); } /** @@ -302,13 +306,8 @@ class RecentTasks { * before we need to iterate the task list in order (either for purposes of returning the list * to SystemUI or if we need to trim tasks in order) */ + @VisibleForTesting void resetFreezeTaskListReorderingOnTimeout() { - // Unfreeze the recent task list if the time heuristic has passed - if (mFreezeTaskListReorderingTime - > (SystemClock.elapsedRealtime() - mFreezeTaskListTimeoutMs)) { - return; - } - final ActivityStack focusedStack = mService.getTopDisplayFocusedStack(); final TaskRecord topTask = focusedStack != null ? focusedStack.topTask() @@ -875,9 +874,6 @@ class RecentTasks { final Set<Integer> includedUsers = getProfileIds(userId); includedUsers.add(Integer.valueOf(userId)); - // Check if the frozen task list has timed out - resetFreezeTaskListReorderingOnTimeout(); - final ArrayList<ActivityManager.RecentTaskInfo> res = new ArrayList<>(); final int size = mTasks.size(); int numVisibleTasks = 0; @@ -1654,8 +1650,8 @@ class RecentTasks { pw.println("mRecentsUid=" + mRecentsUid); pw.println("mRecentsComponent=" + mRecentsComponent); pw.println("mFreezeTaskListReordering=" + mFreezeTaskListReordering); - pw.println("mFreezeTaskListReorderingTime (time since)=" - + (SystemClock.elapsedRealtime() - mFreezeTaskListReorderingTime) + "ms"); + pw.println("mFreezeTaskListReorderingPendingTimeout=" + + mService.mH.hasCallbacks(mResetFreezeTaskListOnTimeoutRunnable)); if (mTasks.isEmpty()) { return; } diff --git a/services/core/java/com/android/server/wm/SurfaceAnimator.java b/services/core/java/com/android/server/wm/SurfaceAnimator.java index 33d952e80a6b..b3b41b733cdb 100644 --- a/services/core/java/com/android/server/wm/SurfaceAnimator.java +++ b/services/core/java/com/android/server/wm/SurfaceAnimator.java @@ -286,8 +286,12 @@ class SurfaceAnimator { final boolean destroy = mLeash != null && surface != null && parent != null; if (destroy) { if (DEBUG_ANIM) Slog.i(TAG, "Reparenting to original parent"); - t.reparent(surface, parent); - scheduleAnim = true; + // We shouldn't really need these isValid checks but we do + // b/130364451 + if (surface.isValid() && parent.isValid()) { + t.reparent(surface, parent); + scheduleAnim = true; + } } mService.mAnimationTransferMap.remove(mAnimation); if (mLeash != null && destroyLeash) { diff --git a/services/tests/mockingservicestests/AndroidManifest.xml b/services/tests/mockingservicestests/AndroidManifest.xml index c9aa63153a5d..32d7d026ff10 100644 --- a/services/tests/mockingservicestests/AndroidManifest.xml +++ b/services/tests/mockingservicestests/AndroidManifest.xml @@ -17,6 +17,8 @@ <manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.android.frameworks.mockingservicestests"> + <uses-permission android:name="android.permission.CHANGE_CONFIGURATION" /> + <uses-permission android:name="android.permission.HARDWARE_TEST"/> <uses-permission android:name="android.permission.INTERACT_ACROSS_USERS_FULL" /> <application android:testOnly="true" diff --git a/services/tests/servicestests/src/com/android/server/display/color/DisplayTransformManagerTest.java b/services/tests/mockingservicestests/src/com/android/server/display/color/DisplayTransformManagerTest.java index fc74c972ed83..73b3b8b1ce3c 100644 --- a/services/tests/servicestests/src/com/android/server/display/color/DisplayTransformManagerTest.java +++ b/services/tests/mockingservicestests/src/com/android/server/display/color/DisplayTransformManagerTest.java @@ -16,87 +16,119 @@ package com.android.server.display.color; +import static com.android.dx.mockito.inline.extended.ExtendedMockito.anyString; +import static com.android.dx.mockito.inline.extended.ExtendedMockito.doAnswer; import static com.android.server.display.color.DisplayTransformManager.LEVEL_COLOR_MATRIX_NIGHT_DISPLAY; import static com.android.server.display.color.DisplayTransformManager.PERSISTENT_PROPERTY_DISPLAY_COLOR; import static com.android.server.display.color.DisplayTransformManager.PERSISTENT_PROPERTY_SATURATION; import static com.google.common.truth.Truth.assertThat; +import static org.mockito.ArgumentMatchers.any; + import android.hardware.display.ColorDisplayManager; import android.os.SystemProperties; import androidx.test.runner.AndroidJUnit4; +import com.android.dx.mockito.inline.extended.ExtendedMockito; + +import org.junit.After; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; +import org.mockito.MockitoSession; +import org.mockito.quality.Strictness; +import org.mockito.stubbing.Answer; + +import java.util.HashMap; @RunWith(AndroidJUnit4.class) public class DisplayTransformManagerTest { + private MockitoSession mSession; private DisplayTransformManager mDtm; private float[] mNightDisplayMatrix; + private HashMap<String, String> mSystemProperties; @Before public void setUp() { mDtm = new DisplayTransformManager(); mNightDisplayMatrix = mDtm.getColorMatrix(LEVEL_COLOR_MATRIX_NIGHT_DISPLAY); - SystemProperties.set(PERSISTENT_PROPERTY_DISPLAY_COLOR, null); - SystemProperties.set(PERSISTENT_PROPERTY_SATURATION, null); + mSession = ExtendedMockito.mockitoSession() + .initMocks(this) + .strictness(Strictness.LENIENT) + .spyStatic(SystemProperties.class) + .startMocking(); + mSystemProperties = new HashMap<>(); + + doAnswer((Answer<Void>) invocationOnMock -> { + mSystemProperties.put(invocationOnMock.getArgument(0), + invocationOnMock.getArgument(1)); + return null; + } + ).when(() -> SystemProperties.set(anyString(), any())); + } + + @After + public void tearDown() throws Exception { + mSession.finishMocking(); + mSystemProperties.clear(); } @Test public void setColorMode_natural() { mDtm.setColorMode(ColorDisplayManager.COLOR_MODE_NATURAL, mNightDisplayMatrix); - assertThat(SystemProperties.get(PERSISTENT_PROPERTY_DISPLAY_COLOR, null)) + assertThat(mSystemProperties.get(PERSISTENT_PROPERTY_DISPLAY_COLOR)) .isEqualTo("0" /* managed */); - assertThat(SystemProperties.get(PERSISTENT_PROPERTY_SATURATION, null)) + assertThat(mSystemProperties.get(PERSISTENT_PROPERTY_SATURATION)) .isEqualTo("1.0" /* natural */); } @Test public void setColorMode_boosted() { mDtm.setColorMode(ColorDisplayManager.COLOR_MODE_BOOSTED, mNightDisplayMatrix); - assertThat(SystemProperties.get(PERSISTENT_PROPERTY_DISPLAY_COLOR, null)) + + assertThat(mSystemProperties.get(PERSISTENT_PROPERTY_DISPLAY_COLOR)) .isEqualTo("0" /* managed */); - assertThat(SystemProperties.get(PERSISTENT_PROPERTY_SATURATION, null)) + assertThat(mSystemProperties.get(PERSISTENT_PROPERTY_SATURATION)) .isEqualTo("1.1" /* boosted */); } @Test public void setColorMode_saturated() { mDtm.setColorMode(ColorDisplayManager.COLOR_MODE_SATURATED, mNightDisplayMatrix); - assertThat(SystemProperties.get(PERSISTENT_PROPERTY_DISPLAY_COLOR, null)) + assertThat(mSystemProperties.get(PERSISTENT_PROPERTY_DISPLAY_COLOR)) .isEqualTo("1" /* unmanaged */); - assertThat(SystemProperties.get(PERSISTENT_PROPERTY_SATURATION, null)) + assertThat(mSystemProperties.get(PERSISTENT_PROPERTY_SATURATION)) .isEqualTo("1.0" /* natural */); } @Test public void setColorMode_automatic() { mDtm.setColorMode(ColorDisplayManager.COLOR_MODE_AUTOMATIC, mNightDisplayMatrix); - assertThat(SystemProperties.get(PERSISTENT_PROPERTY_DISPLAY_COLOR, null)) + assertThat(mSystemProperties.get(PERSISTENT_PROPERTY_DISPLAY_COLOR)) .isEqualTo("2" /* enhanced */); - assertThat(SystemProperties.get(PERSISTENT_PROPERTY_SATURATION, null)) + assertThat(mSystemProperties.get(PERSISTENT_PROPERTY_SATURATION)) .isEqualTo("1.0" /* natural */); } @Test public void setColorMode_vendor() { mDtm.setColorMode(0x100, mNightDisplayMatrix); - assertThat(SystemProperties.get(PERSISTENT_PROPERTY_DISPLAY_COLOR, null)) + assertThat(mSystemProperties.get(PERSISTENT_PROPERTY_DISPLAY_COLOR)) .isEqualTo(Integer.toString(0x100) /* pass-through */); - assertThat(SystemProperties.get(PERSISTENT_PROPERTY_SATURATION, null)) - .isEqualTo("1.0" /* default */); + assertThat(mSystemProperties.get(PERSISTENT_PROPERTY_SATURATION)) + .isEqualTo("1.0" /* natural */); } @Test public void setColorMode_outOfBounds() { mDtm.setColorMode(0x50, mNightDisplayMatrix); - assertThat(SystemProperties.get(PERSISTENT_PROPERTY_DISPLAY_COLOR, null)) - .isEqualTo("" /* default */); - assertThat(SystemProperties.get(PERSISTENT_PROPERTY_SATURATION, null)) - .isEqualTo("" /* default */); + assertThat(mSystemProperties.get(PERSISTENT_PROPERTY_DISPLAY_COLOR)) + .isEqualTo(null); + assertThat(mSystemProperties.get(PERSISTENT_PROPERTY_SATURATION)) + .isEqualTo(null); } } diff --git a/services/tests/servicestests/src/com/android/server/accessibility/MotionEventInjectorTest.java b/services/tests/servicestests/src/com/android/server/accessibility/MotionEventInjectorTest.java index 2cba9d022866..2977414fb302 100644 --- a/services/tests/servicestests/src/com/android/server/accessibility/MotionEventInjectorTest.java +++ b/services/tests/servicestests/src/com/android/server/accessibility/MotionEventInjectorTest.java @@ -17,6 +17,7 @@ package com.android.server.accessibility; import static android.view.MotionEvent.ACTION_DOWN; +import static android.view.MotionEvent.ACTION_HOVER_MOVE; import static android.view.MotionEvent.ACTION_UP; import static android.view.WindowManagerPolicyConstants.FLAG_PASS_TO_USER; @@ -116,6 +117,7 @@ public class MotionEventInjectorTest { MotionEvent mClickDownEvent; MotionEvent mClickUpEvent; + MotionEvent mHoverMoveEvent; ArgumentCaptor<MotionEvent> mCaptor1 = ArgumentCaptor.forClass(MotionEvent.class); ArgumentCaptor<MotionEvent> mCaptor2 = ArgumentCaptor.forClass(MotionEvent.class); @@ -152,6 +154,10 @@ public class MotionEventInjectorTest { CLICK_POINT.y, 0); mClickUpEvent.setSource(InputDevice.SOURCE_TOUCHSCREEN); + mHoverMoveEvent = MotionEvent.obtain(0, 0, ACTION_HOVER_MOVE, CLICK_POINT.x, CLICK_POINT.y, + 0); + mHoverMoveEvent.setSource(InputDevice.SOURCE_MOUSE); + mIsLineStart = allOf(IS_ACTION_DOWN, isAtPoint(LINE_START), hasStandardInitialization(), hasTimeFromDown(0)); mIsLineMiddle = allOf(IS_ACTION_MOVE, isAtPoint(LINE_END), hasStandardInitialization(), @@ -301,6 +307,23 @@ public class MotionEventInjectorTest { } @Test + public void + testOnMotionEvents_fromMouseWithInjectedGestureInProgress_shouldNotCancelAndPassReal() + throws RemoteException { + EventStreamTransformation next = attachMockNext(mMotionEventInjector); + injectEventsSync(mLineList, mServiceInterface, LINE_SEQUENCE); + mMessageCapturingHandler.sendOneMessage(); // Send a motion event + mMotionEventInjector.onMotionEvent(mHoverMoveEvent, mHoverMoveEvent, 0); + mMessageCapturingHandler.sendAllMessages(); + + verify(next, times(3)).onMotionEvent(mCaptor1.capture(), mCaptor2.capture(), anyInt()); + assertThat(mCaptor1.getAllValues().get(0), mIsLineStart); + assertThat(mCaptor1.getAllValues().get(1), mIsLineMiddle); + assertThat(mCaptor1.getAllValues().get(2), mIsLineEnd); + verify(mServiceInterface).onPerformGestureResult(LINE_SEQUENCE, true); + } + + @Test public void testOnMotionEvents_closedInjectedGestureInProgress_shouldOnlyNotifyAndPassReal() throws RemoteException { EventStreamTransformation next = attachMockNext(mMotionEventInjector); diff --git a/services/tests/servicestests/src/com/android/server/power/AttentionDetectorTest.java b/services/tests/servicestests/src/com/android/server/power/AttentionDetectorTest.java index 5de41ea5e7d1..4de00f7b5565 100644 --- a/services/tests/servicestests/src/com/android/server/power/AttentionDetectorTest.java +++ b/services/tests/servicestests/src/com/android/server/power/AttentionDetectorTest.java @@ -29,6 +29,7 @@ import static org.mockito.Mockito.when; import android.attention.AttentionManagerInternal; import android.attention.AttentionManagerInternal.AttentionCallbackInternal; +import android.content.pm.PackageManager; import android.os.PowerManager; import android.os.PowerManagerInternal; import android.os.SystemClock; @@ -49,6 +50,8 @@ import org.mockito.MockitoAnnotations; public class AttentionDetectorTest extends AndroidTestCase { @Mock + private PackageManager mPackageManager; + @Mock private AttentionManagerInternal mAttentionManagerInternal; @Mock private Runnable mOnUserAttention; @@ -60,6 +63,9 @@ public class AttentionDetectorTest extends AndroidTestCase { @Before public void setUp() { MockitoAnnotations.initMocks(this); + when(mPackageManager.getAttentionServicePackageName()).thenReturn("com.google.android.as"); + when(mPackageManager.checkPermission(any(), any())).thenReturn( + PackageManager.PERMISSION_GRANTED); when(mAttentionManagerInternal.checkAttention(anyLong(), any())) .thenReturn(true); mAttentionDetector = new TestableAttentionDetector(); @@ -108,6 +114,27 @@ public class AttentionDetectorTest extends AndroidTestCase { } @Test + public void testOnUserActivity_doesntCheckIfNotSufficientPermissions() { + when(mPackageManager.checkPermission(any(), any())).thenReturn( + PackageManager.PERMISSION_DENIED); + + long when = registerAttention(); + verify(mAttentionManagerInternal, never()).checkAttention(anyLong(), any()); + assertThat(mNextDimming).isEqualTo(when); + } + + @Test + public void testOnUserActivity_disablesSettingIfNotSufficientPermissions() { + when(mPackageManager.checkPermission(any(), any())).thenReturn( + PackageManager.PERMISSION_DENIED); + + registerAttention(); + boolean enabled = Settings.System.getIntForUser(getContext().getContentResolver(), + Settings.System.ADAPTIVE_SLEEP, 0, UserHandle.USER_CURRENT) == 1; + assertFalse(enabled); + } + + @Test public void testOnUserActivity_doesntCrashIfNoAttentionService() { mAttentionManagerInternal = null; registerAttention(); @@ -211,6 +238,8 @@ public class AttentionDetectorTest extends AndroidTestCase { TestableAttentionDetector() { super(AttentionDetectorTest.this.mOnUserAttention, new Object()); mAttentionManager = mAttentionManagerInternal; + mPackageManager = AttentionDetectorTest.this.mPackageManager; + mContentResolver = getContext().getContentResolver(); mMaximumExtensionMillis = 10000L; } diff --git a/services/tests/uiservicestests/src/com/android/server/notification/BuzzBeepBlinkTest.java b/services/tests/uiservicestests/src/com/android/server/notification/BuzzBeepBlinkTest.java index 49ee8b3bba19..6be2c2e8c59e 100644 --- a/services/tests/uiservicestests/src/com/android/server/notification/BuzzBeepBlinkTest.java +++ b/services/tests/uiservicestests/src/com/android/server/notification/BuzzBeepBlinkTest.java @@ -48,8 +48,8 @@ import android.app.Notification; import android.app.Notification.Builder; import android.app.NotificationChannel; import android.app.NotificationManager; +import android.content.Context; import android.content.pm.PackageManager; -import android.content.res.Resources; import android.graphics.Color; import android.media.AudioAttributes; import android.media.AudioManager; @@ -63,7 +63,6 @@ import android.provider.Settings; import android.service.notification.NotificationListenerService; import android.service.notification.StatusBarNotification; import android.test.suitebuilder.annotation.SmallTest; -import android.testing.TestableContext; import android.view.accessibility.AccessibilityEvent; import android.view.accessibility.AccessibilityManager; import android.view.accessibility.IAccessibilityManager; @@ -71,7 +70,6 @@ import android.view.accessibility.IAccessibilityManagerClient; import androidx.test.runner.AndroidJUnit4; -import com.android.internal.R; import com.android.internal.util.IntPair; import com.android.server.UiServiceTestCase; import com.android.server.lights.Light; @@ -88,7 +86,6 @@ import org.mockito.MockitoAnnotations; @RunWith(AndroidJUnit4.class) public class BuzzBeepBlinkTest extends UiServiceTestCase { - private TestableContext mContext = spy(getContext()); @Mock AudioManager mAudioManager; @Mock Vibrator mVibrator; @Mock android.media.IRingtonePlayer mRingtonePlayer; @@ -99,8 +96,6 @@ public class BuzzBeepBlinkTest extends UiServiceTestCase { NotificationUsageStats mUsageStats; @Mock IAccessibilityManager mAccessibilityService; - @Mock - Resources mResources; private NotificationManagerService mService; private String mPkg = "com.android.server.notification"; @@ -150,7 +145,7 @@ public class BuzzBeepBlinkTest extends UiServiceTestCase { verify(mAccessibilityService).addClient(any(IAccessibilityManagerClient.class), anyInt()); assertTrue(accessibilityManager.isEnabled()); - mService = spy(new NotificationManagerService(mContext)); + mService = spy(new NotificationManagerService(getContext())); mService.setAudioManager(mAudioManager); mService.setVibrator(mVibrator); mService.setSystemReady(true); @@ -280,7 +275,7 @@ public class BuzzBeepBlinkTest extends UiServiceTestCase { boolean isLeanback) { NotificationChannel channel = new NotificationChannel("test", "test", IMPORTANCE_HIGH); - final Builder builder = new Builder(mContext) + final Builder builder = new Builder(getContext()) .setContentTitle("foo") .setSmallIcon(android.R.drawable.sym_def_app_icon) .setPriority(Notification.PRIORITY_HIGH) @@ -326,14 +321,15 @@ public class BuzzBeepBlinkTest extends UiServiceTestCase { n.flags |= Notification.FLAG_INSISTENT; } - PackageManager packageManager = spy(mContext.getPackageManager()); - when(mContext.getPackageManager()).thenReturn(packageManager); + Context context = spy(getContext()); + PackageManager packageManager = spy(context.getPackageManager()); + when(context.getPackageManager()).thenReturn(packageManager); when(packageManager.hasSystemFeature(PackageManager.FEATURE_LEANBACK)) .thenReturn(isLeanback); StatusBarNotification sbn = new StatusBarNotification(mPkg, mPkg, id, mTag, mUid, mPid, n, mUser, null, System.currentTimeMillis()); - NotificationRecord r = new NotificationRecord(mContext, sbn, channel); + NotificationRecord r = new NotificationRecord(context, sbn, channel); mService.addNotification(r); return r; } @@ -459,25 +455,7 @@ public class BuzzBeepBlinkTest extends UiServiceTestCase { } @Test - public void testNoBeepForAutomotiveIfEffectsDisabled() throws Exception { - when(mContext.getResources()).thenReturn(mResources); - when(mResources.getBoolean(R.bool.config_enableServerNotificationEffectsForAutomotive)) - .thenReturn(false); - mService.setIsAutomotive(true); - - NotificationRecord r = getBeepyNotification(); - - mService.buzzBeepBlinkLocked(r); - - verifyNeverBeep(); - assertFalse(r.isInterruptive()); - } - - @Test - public void testNoBeepForImportanceDefaultInAutomotiveIfEffectsEnabled() throws Exception { - when(mContext.getResources()).thenReturn(mResources); - when(mResources.getBoolean(R.bool.config_enableServerNotificationEffectsForAutomotive)) - .thenReturn(true); + public void testNoBeepForImportanceDefaultInAutomotive() throws Exception { mService.setIsAutomotive(true); NotificationRecord r = getBeepyNotification(); @@ -490,10 +468,7 @@ public class BuzzBeepBlinkTest extends UiServiceTestCase { } @Test - public void testBeepForImportanceHighInAutomotiveIfEffectsEnabled() throws Exception { - when(mContext.getResources()).thenReturn(mResources); - when(mResources.getBoolean(R.bool.config_enableServerNotificationEffectsForAutomotive)) - .thenReturn(true); + public void testBeepForImportanceHighInAutomotive() throws Exception { mService.setIsAutomotive(true); NotificationRecord r = getBeepyNotification(); @@ -1040,12 +1015,12 @@ public class BuzzBeepBlinkTest extends UiServiceTestCase { public void testEmptyUriSoundTreatedAsNoSound() throws Exception { NotificationChannel channel = new NotificationChannel("test", "test", IMPORTANCE_HIGH); channel.setSound(Uri.EMPTY, null); - final Notification n = new Builder(mContext, "test") + final Notification n = new Builder(getContext(), "test") .setSmallIcon(android.R.drawable.sym_def_app_icon).build(); StatusBarNotification sbn = new StatusBarNotification(mPkg, mPkg, 0, mTag, mUid, mPid, n, mUser, null, System.currentTimeMillis()); - NotificationRecord r = new NotificationRecord(mContext, sbn, channel); + NotificationRecord r = new NotificationRecord(getContext(), sbn, channel); mService.addNotification(r); mService.buzzBeepBlinkLocked(r); @@ -1094,13 +1069,13 @@ public class BuzzBeepBlinkTest extends UiServiceTestCase { @Test public void testCrossUserSoundMuted() throws Exception { - final Notification n = new Builder(mContext, "test") + final Notification n = new Builder(getContext(), "test") .setSmallIcon(android.R.drawable.sym_def_app_icon).build(); int userId = mUser.getIdentifier() + 1; StatusBarNotification sbn = new StatusBarNotification(mPkg, mPkg, 0, mTag, mUid, mPid, n, UserHandle.of(userId), null, System.currentTimeMillis()); - NotificationRecord r = new NotificationRecord(mContext, sbn, + NotificationRecord r = new NotificationRecord(getContext(), sbn, new NotificationChannel("test", "test", IMPORTANCE_HIGH)); mService.buzzBeepBlinkLocked(r); diff --git a/services/tests/wmtests/src/com/android/server/wm/ActivityStartControllerTests.java b/services/tests/wmtests/src/com/android/server/wm/ActivityStartControllerTests.java index 96db38b14ad5..a7bbe6e4cf02 100644 --- a/services/tests/wmtests/src/com/android/server/wm/ActivityStartControllerTests.java +++ b/services/tests/wmtests/src/com/android/server/wm/ActivityStartControllerTests.java @@ -87,7 +87,7 @@ public class ActivityStartControllerTests extends ActivityTestsBase { mController.doPendingActivityLaunches(resume); verify(mStarter, times(1)).startResolvedActivity(eq(activity), eq(source), eq(null), - eq(null), eq(startFlags), eq(resume), eq(null), eq(null), eq(null)); + eq(null), eq(startFlags), eq(resume), eq(null), eq(null)); } diff --git a/services/tests/wmtests/src/com/android/server/wm/RecentTasksTest.java b/services/tests/wmtests/src/com/android/server/wm/RecentTasksTest.java index af048586b425..3392bc43e568 100644 --- a/services/tests/wmtests/src/com/android/server/wm/RecentTasksTest.java +++ b/services/tests/wmtests/src/com/android/server/wm/RecentTasksTest.java @@ -712,7 +712,6 @@ public class RecentTasksTest extends ActivityTestsBase { mRecentTasks.add(mTasks.get(4)); // Freeze the list - long freezeTime = SystemClock.elapsedRealtime(); mRecentTasks.setFreezeTaskListReordering(); assertTrue(mRecentTasks.isFreezeTaskListReorderingSet()); @@ -720,13 +719,11 @@ public class RecentTasksTest extends ActivityTestsBase { mRecentTasks.add(mTasks.get(2)); mRecentTasks.add(mTasks.get(1)); - // Override the freeze timeout params to simulate the timeout (simulate the freeze at 100ms - // ago with a timeout of 1ms) - mRecentTasks.setFreezeTaskListTimeoutParams(freezeTime - 100, 1); - ActivityStack stack = mTasks.get(2).getStack(); stack.moveToFront("", mTasks.get(2)); doReturn(stack).when(mTestService.mRootActivityContainer).getTopDisplayFocusedStack(); + + // Simulate the reset from the timeout mRecentTasks.resetFreezeTaskListReorderingOnTimeout(); assertFalse(mRecentTasks.isFreezeTaskListReorderingSet()); diff --git a/telecomm/java/android/telecom/InCallService.java b/telecomm/java/android/telecom/InCallService.java index cbcd40f15583..ebfa3a15639a 100644 --- a/telecomm/java/android/telecom/InCallService.java +++ b/telecomm/java/android/telecom/InCallService.java @@ -41,26 +41,12 @@ import java.util.List; /** * This service is implemented by an app that wishes to provide functionality for managing * phone calls. - * <p> - * There are three types of apps which Telecom can bind to when there exists a live (active or - * incoming) call: - * <ol> - * <li>Default Dialer/Phone app - the default dialer/phone app is one which provides the - * in-call user interface while the device is in a call. A device is bundled with a system - * provided default dialer/phone app. The user may choose a single app to take over this role - * from the system app.</li> - * <li>Default Car-mode Dialer/Phone app - the default car-mode dialer/phone app is one which - * provides the in-call user interface while the device is in a call and the device is in car - * mode. The user may choose a single app to fill this role.</li> - * <li>Call Companion app - a call companion app is one which provides no user interface itself, - * but exposes call information to another display surface, such as a wearable device. The - * user may choose multiple apps to fill this role.</li> - * </ol> - * <p> - * Apps which wish to fulfill one of the above roles use the {@link android.app.role.RoleManager} - * to request that they fill the desired role. - * * <h2>Becoming the Default Phone App</h2> + * The default dialer/phone app is one which provides the in-call user interface while the device is + * in a call. A device is bundled with a system provided default dialer/phone app. The user may + * choose a single app to take over this role from the system app. An app which wishes to fulfill + * one this role uses the {@code android.app.role.RoleManager} to request that they fill the role. + * <p> * An app filling the role of the default phone app provides a user interface while the device is in * a call, and the device is not in car mode. * <p> @@ -193,47 +179,6 @@ import java.util.List; * notificationManager.notify(YOUR_CHANNEL_ID, YOUR_TAG, YOUR_ID, builder.build()); * }</pre> * <p> - * <h2>Becoming the Default Car-mode Phone App</h2> - * An app filling the role of the default car-mode dialer/phone app provides a user interface while - * the device is in a call, and in car mode. See - * {@link android.app.UiModeManager#ACTION_ENTER_CAR_MODE} for more information about car mode. - * When the device is in car mode, Telecom binds to the default car-mode dialer/phone app instead - * of the usual dialer/phone app. - * <p> - * Similar to the requirements for becoming the default dialer/phone app, your app must declare a - * manifest entry for its {@link InCallService} implementation. Your manifest entry should ensure - * the following conditions are met: - * <ul> - * <li>Do NOT declare the {@link TelecomManager#METADATA_IN_CALL_SERVICE_UI} metadata.</li> - * <li>Set the {@link TelecomManager#METADATA_IN_CALL_SERVICE_CAR_MODE_UI} metadata to - * {@code true}<li> - * <li>Your app must request the permission - * {@link android.Manifest.permission.CALL_COMPANION_APP}.</li> - * </ul> - * <p> - * Your app should request to fill the role {@code android.app.role.CAR_MODE_DIALER} in order to - * become the default (see <a href="#requestRole">above</a> for how to request your app fills this - * role). - * - * <h2>Becoming a Call Companion App</h2> - * An app which fills the companion app role does not directly provide a user interface while the - * device is in a call. Instead, it is typically used to relay information about calls to another - * display surface, such as a wearable device. - * <p> - * Similar to the requirements for becoming the default dialer/phone app, your app must declare a - * manifest entry for its {@link InCallService} implementation. Your manifest entry should - * ensure the following conditions are met: - * <ul> - * <li>Do NOT declare the {@link TelecomManager#METADATA_IN_CALL_SERVICE_UI} metadata.</li> - * <li>Do NOT declare the {@link TelecomManager#METADATA_IN_CALL_SERVICE_CAR_MODE_UI} - * metadata.</li> - * <li>Your app must request the permission - * {@link android.Manifest.permission.CALL_COMPANION_APP}.</li> - * </ul> - * <p> - * Your app should request to fill the role {@code android.app.role.CALL_COMPANION} in order to - * become a call companion app (see <a href="#requestRole">above</a> for how to request your app - * fills this role). */ public abstract class InCallService extends Service { diff --git a/telecomm/java/android/telecom/TelecomManager.java b/telecomm/java/android/telecom/TelecomManager.java index 391d788cfe72..db6319871540 100644 --- a/telecomm/java/android/telecom/TelecomManager.java +++ b/telecomm/java/android/telecom/TelecomManager.java @@ -16,7 +16,6 @@ package android.telecom; import android.Manifest; import android.annotation.IntDef; -import android.annotation.NonNull; import android.annotation.Nullable; import android.annotation.RequiresPermission; import android.annotation.SuppressAutoDoc; @@ -497,6 +496,9 @@ public class TelecomManager { * Dialer implementations (see {@link #getDefaultDialerPackage()}) which would also like to * override the system provided ringing should set this meta-data to {@code true} in the * manifest registration of their {@link InCallService}. + * <p> + * When {@code true}, it is the {@link InCallService}'s responsibility to play a ringtone for + * all incoming calls. */ public static final String METADATA_IN_CALL_SERVICE_RINGING = "android.telecom.IN_CALL_SERVICE_RINGING"; @@ -1495,8 +1497,21 @@ public class TelecomManager { /** * Silences the ringer if a ringing call exists. - * - * Requires permission: {@link android.Manifest.permission#MODIFY_PHONE_STATE} + * <p> + * This method can only be relied upon to stop the ringtone for a call if the ringtone has + * already started playing. It is intended to handle use-cases such as silencing a ringing call + * when the user presses the volume button during ringing. + * <p> + * If this method is called prior to when the ringtone begins playing, the ringtone will not be + * silenced. As such it is not intended as a means to avoid playing of a ringtone. + * <p> + * A dialer app which wants to have more control over ringtone playing should declare + * {@link TelecomManager#METADATA_IN_CALL_SERVICE_RINGING} in the manifest entry for their + * {@link InCallService} implementation to indicate that the app wants to be responsible for + * playing the ringtone for all incoming calls. + * <p> + * Requires permission: {@link android.Manifest.permission#MODIFY_PHONE_STATE} or that the + * app fills the dialer role (see {@link #getDefaultDialerPackage()}). */ @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public void silenceRinger() { diff --git a/telephony/java/android/telephony/SubscriptionInfo.java b/telephony/java/android/telephony/SubscriptionInfo.java index cf15b92ae640..c57f9e63f9db 100644 --- a/telephony/java/android/telephony/SubscriptionInfo.java +++ b/telephony/java/android/telephony/SubscriptionInfo.java @@ -39,6 +39,7 @@ import android.util.DisplayMetrics; import android.util.Log; import java.util.Arrays; +import java.util.Collections; import java.util.List; import java.util.Objects; @@ -123,6 +124,16 @@ public class SubscriptionInfo implements Parcelable { private String mMnc; /** + * EHPLMNs associated with the subscription + */ + private String[] mEhplmns; + + /** + * HPLMNs associated with the subscription + */ + private String[] mHplmns; + + /** * ISO Country code for the subscription's provider */ private String mCountryIso; @@ -316,6 +327,14 @@ public class SubscriptionInfo implements Parcelable { } /** + * @hide + */ + public void setAssociatedPlmns(String[] ehplmns, String[] hplmns) { + mEhplmns = ehplmns; + mHplmns = hplmns; + } + + /** * Creates and returns an icon {@code Bitmap} to represent this {@code SubscriptionInfo} in a * user interface. * @@ -467,6 +486,20 @@ public class SubscriptionInfo implements Parcelable { } /** + * @hide + */ + public List<String> getEhplmns() { + return mEhplmns == null ? Collections.emptyList() : Arrays.asList(mEhplmns); + } + + /** + * @hide + */ + public List<String> getHplmns() { + return mHplmns == null ? Collections.emptyList() : Arrays.asList(mHplmns); + } + + /** * @return the profile class of this subscription. * @hide */ @@ -600,7 +633,7 @@ public class SubscriptionInfo implements Parcelable { String mcc = source.readString(); String mnc = source.readString(); String countryIso = source.readString(); - Bitmap iconBitmap = Bitmap.CREATOR.createFromParcel(source); + Bitmap iconBitmap = source.readParcelable(Bitmap.class.getClassLoader()); boolean isEmbedded = source.readBoolean(); UiccAccessRule[] accessRules = source.createTypedArray(UiccAccessRule.CREATOR); String cardString = source.readString(); @@ -611,11 +644,15 @@ public class SubscriptionInfo implements Parcelable { int carrierid = source.readInt(); int profileClass = source.readInt(); int subType = source.readInt(); - - return new SubscriptionInfo(id, iccId, simSlotIndex, displayName, carrierName, - nameSource, iconTint, number, dataRoaming, iconBitmap, mcc, mnc, countryIso, - isEmbedded, accessRules, cardString, cardId, isOpportunistic, groupUUID, - isGroupDisabled, carrierid, profileClass, subType); + String[] ehplmns = source.readStringArray(); + String[] hplmns = source.readStringArray(); + + SubscriptionInfo info = new SubscriptionInfo(id, iccId, simSlotIndex, displayName, + carrierName, nameSource, iconTint, number, dataRoaming, iconBitmap, mcc, mnc, + countryIso, isEmbedded, accessRules, cardString, cardId, isOpportunistic, + groupUUID, isGroupDisabled, carrierid, profileClass, subType); + info.setAssociatedPlmns(ehplmns, hplmns); + return info; } @Override @@ -638,7 +675,7 @@ public class SubscriptionInfo implements Parcelable { dest.writeString(mMcc); dest.writeString(mMnc); dest.writeString(mCountryIso); - mIconBitmap.writeToParcel(dest, flags); + dest.writeParcelable(mIconBitmap, flags); dest.writeBoolean(mIsEmbedded); dest.writeTypedArray(mAccessRules, flags); dest.writeString(mCardString); @@ -649,6 +686,8 @@ public class SubscriptionInfo implements Parcelable { dest.writeInt(mCarrierId); dest.writeInt(mProfileClass); dest.writeInt(mSubscriptionType); + dest.writeStringArray(mEhplmns); + dest.writeStringArray(mHplmns); } @Override @@ -686,6 +725,8 @@ public class SubscriptionInfo implements Parcelable { + " isOpportunistic " + mIsOpportunistic + " mGroupUUID=" + mGroupUUID + " mIsGroupDisabled=" + mIsGroupDisabled + " profileClass=" + mProfileClass + + " ehplmns = " + Arrays.toString(mEhplmns) + + " hplmns = " + Arrays.toString(mHplmns) + " subscriptionType=" + mSubscriptionType + "}"; } @@ -729,6 +770,8 @@ public class SubscriptionInfo implements Parcelable { && TextUtils.equals(mDisplayName, toCompare.mDisplayName) && TextUtils.equals(mCarrierName, toCompare.mCarrierName) && Arrays.equals(mAccessRules, toCompare.mAccessRules) - && mProfileClass == toCompare.mProfileClass; + && mProfileClass == toCompare.mProfileClass + && Arrays.equals(mEhplmns, toCompare.mEhplmns) + && Arrays.equals(mHplmns, toCompare.mHplmns); } } diff --git a/telephony/java/android/telephony/SubscriptionManager.java b/telephony/java/android/telephony/SubscriptionManager.java index 0c6341111029..0808adf26aef 100644 --- a/telephony/java/android/telephony/SubscriptionManager.java +++ b/telephony/java/android/telephony/SubscriptionManager.java @@ -458,6 +458,18 @@ public class SubscriptionManager { public static final String CARRIER_ID = "carrier_id"; /** + * @hide A comma-separated list of EHPLMNs associated with the subscription + * <P>Type: TEXT (String)</P> + */ + public static final String EHPLMNS = "ehplmns"; + + /** + * @hide A comma-separated list of HPLMNs associated with the subscription + * <P>Type: TEXT (String)</P> + */ + public static final String HPLMNS = "hplmns"; + + /** * TelephonyProvider column name for the MCC associated with a SIM, stored as a string. * <P>Type: TEXT (String)</P> * @hide diff --git a/telephony/java/android/telephony/TelephonyManager.java b/telephony/java/android/telephony/TelephonyManager.java index 0d3bc1db831f..2bd4f8f336fd 100644 --- a/telephony/java/android/telephony/TelephonyManager.java +++ b/telephony/java/android/telephony/TelephonyManager.java @@ -10376,10 +10376,10 @@ public class TelephonyManager { * <p>Requires permission {@link android.Manifest.permission#READ_PHONE_STATE} or the calling * app has carrier privileges (see {@link #hasCarrierPrivileges}). * - * @return Map including the key as the active subscription ID (Note: if there is no active + * @return Map including the keys as the active subscription IDs (Note: if there is no active * subscription, the key is {@link SubscriptionManager#getDefaultSubscriptionId}) and the value - * as the list of {@link EmergencyNumber}; null if this information is not available; or throw - * a SecurityException if the caller does not have the permission. + * as the list of {@link EmergencyNumber}; empty Map if this information is not available; + * or throw a SecurityException if the caller does not have the permission. */ @RequiresPermission(android.Manifest.permission.READ_PHONE_STATE) @NonNull @@ -10429,10 +10429,10 @@ public class TelephonyManager { * <li>{@link EmergencyNumber#EMERGENCY_SERVICE_CATEGORY_MIEC} </li> * <li>{@link EmergencyNumber#EMERGENCY_SERVICE_CATEGORY_AIEC} </li> * </ol> - * @return Map including the key as the active subscription ID (Note: if there is no active + * @return Map including the keys as the active subscription IDs (Note: if there is no active * subscription, the key is {@link SubscriptionManager#getDefaultSubscriptionId}) and the value - * as the list of {@link EmergencyNumber}; null if this information is not available; or throw - * a SecurityException if the caller does not have the permission. + * as the list of {@link EmergencyNumber}; empty Map if this information is not available; + * or throw a SecurityException if the caller does not have the permission. */ @RequiresPermission(android.Manifest.permission.READ_PHONE_STATE) @NonNull |