Merge "Add log metric for Grayscale conditional"
diff --git a/Android.bp b/Android.bp
index 4b22f9e..c97ee3d 100644
--- a/Android.bp
+++ b/Android.bp
@@ -1788,3 +1788,10 @@
],
}
+// Creates an index of AIDL methods; used for adding UnsupportedAppUsage
+// annotations to private apis
+aidl_mapping {
+ name: "framework-aidl-mappings",
+ srcs: [":framework-defaults"],
+ output: "framework-aidl-mappings.txt"
+}
\ No newline at end of file
diff --git a/api/current.txt b/api/current.txt
index 6474cb8..21c2999 100644
--- a/api/current.txt
+++ b/api/current.txt
@@ -4277,7 +4277,8 @@
method public void stopWatchingMode(android.app.AppOpsManager.OnOpChangedListener);
method public int unsafeCheckOp(String, int, String);
method public int unsafeCheckOpNoThrow(String, int, String);
- method public int unsafeCheckOpRaw(String, int, String);
+ method public int unsafeCheckOpRaw(@NonNull String, int, String);
+ method public int unsafeCheckOpRawNoThrow(@NonNull String, int, @NonNull String);
field public static final int MODE_ALLOWED = 0; // 0x0
field public static final int MODE_DEFAULT = 3; // 0x3
field public static final int MODE_ERRORED = 2; // 0x2
@@ -16796,6 +16797,7 @@
public abstract static class CameraManager.AvailabilityCallback {
ctor public CameraManager.AvailabilityCallback();
+ method public void onCameraAccessPrioritiesChanged();
method public void onCameraAvailable(@NonNull String);
method public void onCameraUnavailable(@NonNull String);
}
@@ -23689,18 +23691,18 @@
public abstract static class AudioTrack.StreamEventCallback {
ctor public AudioTrack.StreamEventCallback();
- method public void onDataRequest(@NonNull android.media.AudioTrack, int);
+ method public void onDataRequest(@NonNull android.media.AudioTrack, @IntRange(from=0) int);
method public void onPresentationEnded(@NonNull android.media.AudioTrack);
method public void onTearDown(@NonNull android.media.AudioTrack);
}
public class CallbackDataSourceDesc extends android.media.DataSourceDesc {
- method public android.media.DataSourceCallback getDataSourceCallback();
+ method @NonNull public android.media.DataSourceCallback getDataSourceCallback();
}
public static class CallbackDataSourceDesc.Builder extends android.media.DataSourceDesc.BuilderBase<android.media.CallbackDataSourceDesc.Builder> {
ctor public CallbackDataSourceDesc.Builder();
- ctor public CallbackDataSourceDesc.Builder(android.media.CallbackDataSourceDesc);
+ ctor public CallbackDataSourceDesc.Builder(@Nullable android.media.CallbackDataSourceDesc);
method @NonNull public android.media.CallbackDataSourceDesc build();
method @NonNull public android.media.CallbackDataSourceDesc.Builder setDataSource(@NonNull android.media.DataSourceCallback);
}
@@ -23760,12 +23762,12 @@
public abstract class DataSourceCallback implements java.io.Closeable {
ctor public DataSourceCallback();
method public abstract long getSize() throws java.io.IOException;
- method public abstract int readAt(long, byte[], int, int) throws java.io.IOException;
+ method public abstract int readAt(long, @NonNull byte[], int, int) throws java.io.IOException;
}
public class DataSourceDesc {
method public long getEndPosition();
- method public String getMediaId();
+ method @Nullable public String getMediaId();
method public long getStartPosition();
field public static final long LONG_MAX_TIME_MS = 576460752303423L; // 0x20c49ba5e353fL
field public static final long POSITION_UNKNOWN = 576460752303423L; // 0x20c49ba5e353fL
@@ -23773,7 +23775,7 @@
protected static class DataSourceDesc.BuilderBase<T extends android.media.DataSourceDesc.BuilderBase> {
method @NonNull public T setEndPosition(long);
- method @NonNull public T setMediaId(String);
+ method @NonNull public T setMediaId(@Nullable String);
method @NonNull public T setStartPosition(long);
}
@@ -23982,13 +23984,13 @@
public class FileDataSourceDesc extends android.media.DataSourceDesc {
method public long getLength();
method public long getOffset();
- method public android.os.ParcelFileDescriptor getParcelFileDescriptor();
+ method @NonNull public android.os.ParcelFileDescriptor getParcelFileDescriptor();
field public static final long FD_LENGTH_UNKNOWN = 576460752303423487L; // 0x7ffffffffffffffL
}
public static class FileDataSourceDesc.Builder extends android.media.DataSourceDesc.BuilderBase<android.media.FileDataSourceDesc.Builder> {
ctor public FileDataSourceDesc.Builder();
- ctor public FileDataSourceDesc.Builder(android.media.FileDataSourceDesc);
+ ctor public FileDataSourceDesc.Builder(@Nullable android.media.FileDataSourceDesc);
method @NonNull public android.media.FileDataSourceDesc build();
method @NonNull public android.media.FileDataSourceDesc.Builder setDataSource(@NonNull android.os.ParcelFileDescriptor);
method @NonNull public android.media.FileDataSourceDesc.Builder setDataSource(@NonNull android.os.ParcelFileDescriptor, long, long);
@@ -25540,16 +25542,16 @@
}
public class MediaPlayer2 implements android.media.AudioRouting java.lang.AutoCloseable {
- ctor public MediaPlayer2(android.content.Context);
- method public void addOnRoutingChangedListener(android.media.AudioRouting.OnRoutingChangedListener, android.os.Handler);
- method public Object attachAuxEffect(int);
+ ctor public MediaPlayer2(@NonNull android.content.Context);
+ method public void addOnRoutingChangedListener(@NonNull android.media.AudioRouting.OnRoutingChangedListener, @Nullable android.os.Handler);
+ method @NonNull public Object attachAuxEffect(int);
method public boolean cancelCommand(@NonNull Object);
method public void clearDrmEventCallback();
- method public Object clearNextDataSources();
+ method @NonNull public Object clearNextDataSources();
method public void clearPendingCommands();
method public void close();
- method public Object deselectTrack(int);
- method public Object deselectTrack(@NonNull android.media.DataSourceDesc, int);
+ method @NonNull public Object deselectTrack(int);
+ method @NonNull public Object deselectTrack(@NonNull android.media.DataSourceDesc, int);
method @NonNull public android.media.AudioAttributes getAudioAttributes();
method public int getAudioSessionId();
method public long getBufferedPosition();
@@ -25559,11 +25561,11 @@
method public long getDuration();
method public long getDuration(@NonNull android.media.DataSourceDesc);
method public float getMaxPlayerVolume();
- method public android.os.PersistableBundle getMetrics();
+ method @Nullable public android.os.PersistableBundle getMetrics();
method @NonNull public android.media.PlaybackParams getPlaybackParams();
method public float getPlayerVolume();
- method public android.media.AudioDeviceInfo getPreferredDevice();
- method public android.media.AudioDeviceInfo getRoutedDevice();
+ method @Nullable public android.media.AudioDeviceInfo getPreferredDevice();
+ method @Nullable public android.media.AudioDeviceInfo getRoutedDevice();
method public int getSelectedTrack(int);
method public int getSelectedTrack(@NonNull android.media.DataSourceDesc, int);
method public int getState();
@@ -25571,37 +25573,37 @@
method @Nullable public android.media.MediaTimestamp getTimestamp();
method @NonNull public java.util.List<android.media.MediaPlayer2.TrackInfo> getTrackInfo();
method @NonNull public java.util.List<android.media.MediaPlayer2.TrackInfo> getTrackInfo(@NonNull android.media.DataSourceDesc);
- method public android.util.Size getVideoSize();
+ method @NonNull public android.util.Size getVideoSize();
method public boolean isLooping();
- method public Object loopCurrent(boolean);
- method public Object notifyWhenCommandLabelReached(@NonNull Object);
- method public Object pause();
- method public Object play();
- method public Object prepare();
+ method @NonNull public Object loopCurrent(boolean);
+ method @NonNull public Object notifyWhenCommandLabelReached(@NonNull Object);
+ method @NonNull public Object pause();
+ method @NonNull public Object play();
+ method @NonNull public Object prepare();
method public void registerEventCallback(@NonNull java.util.concurrent.Executor, @NonNull android.media.MediaPlayer2.EventCallback);
- method public void removeOnRoutingChangedListener(android.media.AudioRouting.OnRoutingChangedListener);
+ method public void removeOnRoutingChangedListener(@NonNull android.media.AudioRouting.OnRoutingChangedListener);
method public void reset();
- method public Object seekTo(long);
- method public Object seekTo(long, int);
- method public Object selectTrack(int);
- method public Object selectTrack(@NonNull android.media.DataSourceDesc, int);
- method public Object setAudioAttributes(@NonNull android.media.AudioAttributes);
- method public Object setAudioSessionId(int);
- method public Object setAuxEffectSendLevel(float);
- method public Object setDataSource(@NonNull android.media.DataSourceDesc);
- method public Object setDisplay(android.view.SurfaceHolder);
+ method @NonNull public Object seekTo(long);
+ method @NonNull public Object seekTo(long, int);
+ method @NonNull public Object selectTrack(int);
+ method @NonNull public Object selectTrack(@NonNull android.media.DataSourceDesc, int);
+ method @NonNull public Object setAudioAttributes(@NonNull android.media.AudioAttributes);
+ method @NonNull public Object setAudioSessionId(int);
+ method @NonNull public Object setAuxEffectSendLevel(float);
+ method @NonNull public Object setDataSource(@NonNull android.media.DataSourceDesc);
+ method @NonNull public Object setDisplay(@Nullable android.view.SurfaceHolder);
method public void setDrmEventCallback(@NonNull java.util.concurrent.Executor, @NonNull android.media.MediaPlayer2.DrmEventCallback);
- method public Object setNextDataSource(@NonNull android.media.DataSourceDesc);
- method public Object setNextDataSources(@NonNull java.util.List<android.media.DataSourceDesc>);
- method public Object setPlaybackParams(@NonNull android.media.PlaybackParams);
- method public Object setPlayerVolume(float);
- method public boolean setPreferredDevice(android.media.AudioDeviceInfo);
- method public Object setScreenOnWhilePlaying(boolean);
- method public Object setSurface(android.view.Surface);
- method public Object setSyncParams(@NonNull android.media.SyncParams);
- method public Object setWakeLock(@NonNull android.os.PowerManager.WakeLock);
- method public Object skipToNext();
- method public void unregisterEventCallback(android.media.MediaPlayer2.EventCallback);
+ method @NonNull public Object setNextDataSource(@NonNull android.media.DataSourceDesc);
+ method @NonNull public Object setNextDataSources(@NonNull java.util.List<android.media.DataSourceDesc>);
+ method @NonNull public Object setPlaybackParams(@NonNull android.media.PlaybackParams);
+ method @NonNull public Object setPlayerVolume(float);
+ method public boolean setPreferredDevice(@Nullable android.media.AudioDeviceInfo);
+ method @NonNull public Object setScreenOnWhilePlaying(boolean);
+ method @NonNull public Object setSurface(@Nullable android.view.Surface);
+ method @NonNull public Object setSyncParams(@NonNull android.media.SyncParams);
+ method @NonNull public Object setWakeLock(@NonNull android.os.PowerManager.WakeLock);
+ method @NonNull public Object skipToNext();
+ method public void unregisterEventCallback(@NonNull android.media.MediaPlayer2.EventCallback);
field public static final int CALL_COMPLETED_ATTACH_AUX_EFFECT = 1; // 0x1
field public static final int CALL_COMPLETED_CLEAR_NEXT_DATA_SOURCES = 30; // 0x1e
field public static final int CALL_COMPLETED_DESELECT_TRACK = 2; // 0x2
@@ -25736,8 +25738,8 @@
}
public static class MediaPlayer2.TrackInfo {
- method public android.media.MediaFormat getFormat();
- method public String getLanguage();
+ method @Nullable public android.media.MediaFormat getFormat();
+ method @Nullable public String getLanguage();
method public int getTrackType();
field public static final int MEDIA_TRACK_TYPE_AUDIO = 2; // 0x2
field public static final int MEDIA_TRACK_TYPE_METADATA = 5; // 0x5
@@ -26617,15 +26619,15 @@
}
public class UriDataSourceDesc extends android.media.DataSourceDesc {
- method public android.content.Context getContext();
- method public java.util.List<java.net.HttpCookie> getCookies();
- method public java.util.Map<java.lang.String,java.lang.String> getHeaders();
- method public android.net.Uri getUri();
+ method @NonNull public android.content.Context getContext();
+ method @Nullable public java.util.List<java.net.HttpCookie> getCookies();
+ method @Nullable public java.util.Map<java.lang.String,java.lang.String> getHeaders();
+ method @NonNull public android.net.Uri getUri();
}
public static class UriDataSourceDesc.Builder extends android.media.DataSourceDesc.BuilderBase<android.media.UriDataSourceDesc.Builder> {
ctor public UriDataSourceDesc.Builder();
- ctor public UriDataSourceDesc.Builder(android.media.UriDataSourceDesc);
+ ctor public UriDataSourceDesc.Builder(@Nullable android.media.UriDataSourceDesc);
method @NonNull public android.media.UriDataSourceDesc build();
method @NonNull public android.media.UriDataSourceDesc.Builder setDataSource(@NonNull android.content.Context, @NonNull android.net.Uri);
method @NonNull public android.media.UriDataSourceDesc.Builder setDataSource(@NonNull android.content.Context, @NonNull android.net.Uri, @Nullable java.util.Map<java.lang.String,java.lang.String>, @Nullable java.util.List<java.net.HttpCookie>);
@@ -28980,6 +28982,7 @@
field public static final int NET_CAPABILITY_IA = 7; // 0x7
field public static final int NET_CAPABILITY_IMS = 4; // 0x4
field public static final int NET_CAPABILITY_INTERNET = 12; // 0xc
+ field public static final int NET_CAPABILITY_MCX = 23; // 0x17
field public static final int NET_CAPABILITY_MMS = 0; // 0x0
field public static final int NET_CAPABILITY_NOT_CONGESTED = 20; // 0x14
field public static final int NET_CAPABILITY_NOT_METERED = 11; // 0xb
@@ -45470,6 +45473,7 @@
field public static final int TYPE_HIPRI = 16; // 0x10
field public static final int TYPE_IA = 256; // 0x100
field public static final int TYPE_IMS = 64; // 0x40
+ field public static final int TYPE_MCX = 1024; // 0x400
field public static final int TYPE_MMS = 2; // 0x2
field public static final int TYPE_SUPL = 4; // 0x4
}
@@ -45559,7 +45563,7 @@
}
public class EuiccManager {
- method public android.telephony.euicc.EuiccManager createForCardId(int);
+ method @NonNull public android.telephony.euicc.EuiccManager createForCardId(int);
method @RequiresPermission("android.permission.WRITE_EMBEDDED_SUBSCRIPTIONS") public void deleteSubscription(int, android.app.PendingIntent);
method @RequiresPermission("android.permission.WRITE_EMBEDDED_SUBSCRIPTIONS") public void downloadSubscription(android.telephony.euicc.DownloadableSubscription, boolean, android.app.PendingIntent);
method @Nullable public String getEid();
diff --git a/api/system-current.txt b/api/system-current.txt
index bcedee0..375ce91 100644
--- a/api/system-current.txt
+++ b/api/system-current.txt
@@ -362,27 +362,34 @@
field public static final String OPSTR_WRITE_ICC_SMS = "android:write_icc_sms";
field public static final String OPSTR_WRITE_SMS = "android:write_sms";
field public static final String OPSTR_WRITE_WALLPAPER = "android:write_wallpaper";
- field public static final int UID_STATE_BACKGROUND = 5; // 0x5
- field public static final int UID_STATE_CACHED = 6; // 0x6
- field public static final int UID_STATE_FOREGROUND = 4; // 0x4
- field public static final int UID_STATE_FOREGROUND_SERVICE = 3; // 0x3
- field public static final int UID_STATE_FOREGROUND_SERVICE_LOCATION = 2; // 0x2
- field public static final int UID_STATE_PERSISTENT = 0; // 0x0
- field public static final int UID_STATE_TOP = 1; // 0x1
+ field public static final int OP_FLAGS_ALL = 31; // 0x1f
+ field public static final int OP_FLAGS_ALL_TRUSTED = 13; // 0xd
+ field public static final int OP_FLAG_SELF = 1; // 0x1
+ field public static final int OP_FLAG_TRUSTED_PROXIED = 8; // 0x8
+ field public static final int OP_FLAG_TRUSTED_PROXY = 2; // 0x2
+ field public static final int OP_FLAG_UNTRUSTED_PROXIED = 16; // 0x10
+ field public static final int OP_FLAG_UNTRUSTED_PROXY = 4; // 0x4
+ field public static final int UID_STATE_BACKGROUND = 600; // 0x258
+ field public static final int UID_STATE_CACHED = 700; // 0x2bc
+ field public static final int UID_STATE_FOREGROUND = 500; // 0x1f4
+ field public static final int UID_STATE_FOREGROUND_SERVICE = 400; // 0x190
+ field public static final int UID_STATE_FOREGROUND_SERVICE_LOCATION = 300; // 0x12c
+ field public static final int UID_STATE_PERSISTENT = 100; // 0x64
+ field public static final int UID_STATE_TOP = 200; // 0xc8
}
public static final class AppOpsManager.HistoricalOp implements android.os.Parcelable {
method public int describeContents();
- method public long getAccessCount(int);
- method public long getAccessDuration(int);
- method public long getBackgroundAccessCount();
- method public long getBackgroundAccessDuration();
- method public long getBackgroundRejectCount();
- method public long getForegroundAccessCount();
- method public long getForegroundAccessDuration();
- method public long getForegroundRejectCount();
+ method public long getAccessCount(int, int, int);
+ method public long getAccessDuration(int, int, int);
+ method public long getBackgroundAccessCount(int);
+ method public long getBackgroundAccessDuration(int);
+ method public long getBackgroundRejectCount(int);
+ method public long getForegroundAccessCount(int);
+ method public long getForegroundAccessDuration(int);
+ method public long getForegroundRejectCount(int);
method @NonNull public String getOpName();
- method public long getRejectCount(int);
+ method public long getRejectCount(int, int, int);
method public void writeToParcel(android.os.Parcel, int);
field @NonNull public static final android.os.Parcelable.Creator<android.app.AppOpsManager.HistoricalOp> CREATOR;
}
@@ -404,6 +411,7 @@
public static final class AppOpsManager.HistoricalOpsRequest.Builder {
ctor public AppOpsManager.HistoricalOpsRequest.Builder(long, long);
method @NonNull public android.app.AppOpsManager.HistoricalOpsRequest build();
+ method @NonNull public android.app.AppOpsManager.HistoricalOpsRequest.Builder setFlags(int);
method @NonNull public android.app.AppOpsManager.HistoricalOpsRequest.Builder setOpNames(@Nullable java.util.List<java.lang.String>);
method @NonNull public android.app.AppOpsManager.HistoricalOpsRequest.Builder setPackageName(@Nullable String);
method @NonNull public android.app.AppOpsManager.HistoricalOpsRequest.Builder setUid(int);
@@ -431,17 +439,24 @@
public static final class AppOpsManager.OpEntry implements android.os.Parcelable {
method public int describeContents();
- method public int getDuration();
- method public long getLastAccessBackgroundTime();
- method public long getLastAccessForegroundTime();
- method public long getLastAccessTime();
- method public long getLastRejectBackgroundTime();
- method public long getLastRejectForegroundTime();
- method public long getLastRejectTime();
+ method public long getDuration();
+ method public long getLastAccessBackgroundTime(int);
+ method public long getLastAccessForegroundTime(int);
+ method public long getLastAccessTime(int);
+ method public long getLastAccessTime(int, int, int);
+ method public long getLastBackgroundDuration(int);
+ method public long getLastDuration(int, int, int);
+ method public long getLastForegroundDuration(int);
+ method public long getLastRejectBackgroundTime(int);
+ method public long getLastRejectForegroundTime(int);
+ method public long getLastRejectTime(int);
+ method public long getLastRejectTime(int, int, int);
method public int getMode();
- method public String getOpStr();
- method public String getProxyPackageName();
+ method @NonNull public String getOpStr();
+ method @Nullable public String getProxyPackageName();
+ method @Nullable public String getProxyPackageName(int, int);
method public int getProxyUid();
+ method public int getProxyUid(int, int);
method public boolean isRunning();
method public void writeToParcel(android.os.Parcel, int);
field @NonNull public static final android.os.Parcelable.Creator<android.app.AppOpsManager.OpEntry> CREATOR;
@@ -450,7 +465,7 @@
public static final class AppOpsManager.PackageOps implements android.os.Parcelable {
method public int describeContents();
method public java.util.List<android.app.AppOpsManager.OpEntry> getOps();
- method public String getPackageName();
+ method @NonNull public String getPackageName();
method public int getUid();
method public void writeToParcel(android.os.Parcel, int);
field @NonNull public static final android.os.Parcelable.Creator<android.app.AppOpsManager.PackageOps> CREATOR;
@@ -936,7 +951,7 @@
public final class ClassificationsRequest implements android.os.Parcelable {
method public int describeContents();
- method @Nullable public android.os.Bundle getExtras();
+ method @NonNull public android.os.Bundle getExtras();
method @NonNull public java.util.List<android.app.contentsuggestions.ContentSelection> getSelections();
method public void writeToParcel(android.os.Parcel, int);
field @NonNull public static final android.os.Parcelable.Creator<android.app.contentsuggestions.ClassificationsRequest> CREATOR;
@@ -944,8 +959,8 @@
public static final class ClassificationsRequest.Builder {
ctor public ClassificationsRequest.Builder(@NonNull java.util.List<android.app.contentsuggestions.ContentSelection>);
- method public android.app.contentsuggestions.ClassificationsRequest build();
- method public android.app.contentsuggestions.ClassificationsRequest.Builder setExtras(@NonNull android.os.Bundle);
+ method @NonNull public android.app.contentsuggestions.ClassificationsRequest build();
+ method @NonNull public android.app.contentsuggestions.ClassificationsRequest.Builder setExtras(@NonNull android.os.Bundle);
}
public final class ContentClassification implements android.os.Parcelable {
@@ -983,7 +998,7 @@
public final class SelectionsRequest implements android.os.Parcelable {
method public int describeContents();
- method @Nullable public android.os.Bundle getExtras();
+ method @NonNull public android.os.Bundle getExtras();
method @Nullable public android.graphics.Point getInterestPoint();
method public int getTaskId();
method public void writeToParcel(android.os.Parcel, int);
@@ -992,9 +1007,9 @@
public static final class SelectionsRequest.Builder {
ctor public SelectionsRequest.Builder(int);
- method public android.app.contentsuggestions.SelectionsRequest build();
- method public android.app.contentsuggestions.SelectionsRequest.Builder setExtras(@NonNull android.os.Bundle);
- method public android.app.contentsuggestions.SelectionsRequest.Builder setInterestPoint(@NonNull android.graphics.Point);
+ method @NonNull public android.app.contentsuggestions.SelectionsRequest build();
+ method @NonNull public android.app.contentsuggestions.SelectionsRequest.Builder setExtras(@NonNull android.os.Bundle);
+ method @NonNull public android.app.contentsuggestions.SelectionsRequest.Builder setInterestPoint(@NonNull android.graphics.Point);
}
}
@@ -3538,7 +3553,7 @@
field public static final int RADIO_TUNER = 1998; // 0x7ce
}
- public static class MediaTimestamp.Builder {
+ public static final class MediaTimestamp.Builder {
ctor public MediaTimestamp.Builder();
ctor public MediaTimestamp.Builder(@NonNull android.media.MediaTimestamp);
method @NonNull public android.media.MediaTimestamp build();
@@ -3554,14 +3569,14 @@
method public void stop();
}
- public static class SubtitleData.Builder {
+ public static final class SubtitleData.Builder {
ctor public SubtitleData.Builder();
ctor public SubtitleData.Builder(@NonNull android.media.SubtitleData);
method @NonNull public android.media.SubtitleData build();
method @NonNull public android.media.SubtitleData.Builder setSubtitleData(int, long, long, @NonNull byte[]);
}
- public static class TimedMetaData.Builder {
+ public static final class TimedMetaData.Builder {
ctor public TimedMetaData.Builder();
ctor public TimedMetaData.Builder(@NonNull android.media.TimedMetaData);
method @NonNull public android.media.TimedMetaData build();
@@ -5692,7 +5707,7 @@
}
public final class RuntimePermissionPresentationInfo implements android.os.Parcelable {
- ctor public RuntimePermissionPresentationInfo(CharSequence, boolean, boolean);
+ ctor public RuntimePermissionPresentationInfo(@NonNull CharSequence, boolean, boolean);
method public int describeContents();
method @NonNull public CharSequence getLabel();
method public boolean isGranted();
@@ -5836,19 +5851,17 @@
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(String, String, String, boolean);
field public static final String NAMESPACE_ACTIVITY_MANAGER = "activity_manager";
+ field public static final String NAMESPACE_ACTIVITY_MANAGER_NATIVE_BOOT = "activity_manager_native_boot";
field public static final String NAMESPACE_AUTOFILL = "autofill";
field public static final String NAMESPACE_CONTENT_CAPTURE = "content_capture";
field public static final String NAMESPACE_GAME_DRIVER = "game_driver";
field public static final String NAMESPACE_INPUT_NATIVE_BOOT = "input_native_boot";
+ field public static final String NAMESPACE_MEDIA_NATIVE = "media_native";
field public static final String NAMESPACE_NETD_NATIVE = "netd_native";
+ field public static final String NAMESPACE_RUNTIME_NATIVE_BOOT = "runtime_native_boot";
field public static final String NAMESPACE_SYSTEMUI = "systemui";
}
- public static interface DeviceConfig.ActivityManagerNativeBoot {
- field public static final String NAMESPACE = "activity_manager_native_boot";
- field public static final String OFFLOAD_QUEUE_ENABLED = "offload_queue_enabled";
- }
-
public static interface DeviceConfig.AttentionManagerService {
field public static final String COMPONENT_NAME = "component_name";
field public static final String NAMESPACE = "attention_manager_service";
@@ -5867,10 +5880,6 @@
field public static final String NAMESPACE = "intelligence_attention";
}
- public static interface DeviceConfig.MediaNative {
- field public static final String NAMESPACE = "media_native";
- }
-
public static interface DeviceConfig.OnPropertyChangedListener {
method public void onPropertyChanged(String, String, String);
}
@@ -5897,10 +5906,6 @@
field public static final String NAMESPACE = "runtime_native";
}
- public static interface DeviceConfig.RuntimeNativeBoot {
- field public static final String NAMESPACE = "runtime_native_boot";
- }
-
public static interface DeviceConfig.Scheduler {
field public static final String ENABLE_FAST_METRICS_COLLECTION = "enable_fast_metrics_collection";
field public static final String NAMESPACE = "scheduler";
@@ -6418,8 +6423,8 @@
public abstract class ApnService extends android.app.Service {
ctor public ApnService();
- method public android.os.IBinder onBind(android.content.Intent);
- method @WorkerThread public abstract java.util.List<android.content.ContentValues> onRestoreApns(int);
+ method @NonNull public android.os.IBinder onBind(@Nullable android.content.Intent);
+ method @WorkerThread @NonNull public abstract java.util.List<android.content.ContentValues> onRestoreApns(int);
}
}
@@ -7091,12 +7096,12 @@
field public static final int WWAN = 1; // 0x1
}
- public class CallAttributes implements android.os.Parcelable {
- ctor public CallAttributes(android.telephony.PreciseCallState, int, android.telephony.CallQuality);
+ public final class CallAttributes implements android.os.Parcelable {
+ ctor public CallAttributes(@NonNull android.telephony.PreciseCallState, int, @NonNull android.telephony.CallQuality);
method public int describeContents();
- method public android.telephony.CallQuality getCallQuality();
+ method @NonNull public android.telephony.CallQuality getCallQuality();
method public int getNetworkType();
- method public android.telephony.PreciseCallState getPreciseCallState();
+ method @NonNull public android.telephony.PreciseCallState getPreciseCallState();
method public void writeToParcel(android.os.Parcel, int);
field @NonNull public static final android.os.Parcelable.Creator<android.telephony.CallAttributes> CREATOR;
}
@@ -7133,13 +7138,13 @@
}
public final class CarrierRestrictionRules implements android.os.Parcelable {
+ method @NonNull public java.util.List<java.lang.Boolean> areCarrierIdentifiersAllowed(@NonNull java.util.List<android.service.carrier.CarrierIdentifier>);
method public int describeContents();
method @NonNull public java.util.List<android.service.carrier.CarrierIdentifier> getAllowedCarriers();
method public int getDefaultCarrierRestriction();
method @NonNull public java.util.List<android.service.carrier.CarrierIdentifier> getExcludedCarriers();
method public int getMultiSimPolicy();
method public boolean isAllCarriersAllowed();
- method public java.util.List<java.lang.Boolean> isCarrierIdentifiersAllowed(@NonNull java.util.List<android.service.carrier.CarrierIdentifier>);
method public void writeToParcel(android.os.Parcel, int);
field public static final int CARRIER_RESTRICTION_DEFAULT_ALLOWED = 1; // 0x1
field public static final int CARRIER_RESTRICTION_DEFAULT_NOT_ALLOWED = 0; // 0x0
@@ -7148,13 +7153,13 @@
field public static final int MULTISIM_POLICY_ONE_VALID_SIM_MUST_BE_PRESENT = 1; // 0x1
}
- public static class CarrierRestrictionRules.Builder {
- method public android.telephony.CarrierRestrictionRules build();
- method public android.telephony.CarrierRestrictionRules.Builder setAllCarriersAllowed();
- method public android.telephony.CarrierRestrictionRules.Builder setAllowedCarriers(java.util.List<android.service.carrier.CarrierIdentifier>);
- method public android.telephony.CarrierRestrictionRules.Builder setDefaultCarrierRestriction(int);
- method public android.telephony.CarrierRestrictionRules.Builder setExcludedCarriers(java.util.List<android.service.carrier.CarrierIdentifier>);
- method public android.telephony.CarrierRestrictionRules.Builder setMultiSimPolicy(int);
+ public static final class CarrierRestrictionRules.Builder {
+ method @NonNull public android.telephony.CarrierRestrictionRules build();
+ method @NonNull public android.telephony.CarrierRestrictionRules.Builder setAllCarriersAllowed();
+ method @NonNull public android.telephony.CarrierRestrictionRules.Builder setAllowedCarriers(@NonNull java.util.List<android.service.carrier.CarrierIdentifier>);
+ method @NonNull public android.telephony.CarrierRestrictionRules.Builder setDefaultCarrierRestriction(int);
+ method @NonNull public android.telephony.CarrierRestrictionRules.Builder setExcludedCarriers(@NonNull java.util.List<android.service.carrier.CarrierIdentifier>);
+ method @NonNull public android.telephony.CarrierRestrictionRules.Builder setMultiSimPolicy(int);
}
public final class DataFailCause {
@@ -8420,7 +8425,7 @@
}
public class ImsCallSessionListener {
- method public void callQualityChanged(android.telephony.CallQuality);
+ method public void callQualityChanged(@NonNull android.telephony.CallQuality);
method public void callSessionConferenceExtendFailed(android.telephony.ims.ImsReasonInfo);
method public void callSessionConferenceExtendReceived(android.telephony.ims.stub.ImsCallSessionImplBase, android.telephony.ims.ImsCallProfile);
method public void callSessionConferenceExtended(android.telephony.ims.stub.ImsCallSessionImplBase, android.telephony.ims.ImsCallProfile);
@@ -9348,7 +9353,7 @@
method public static void logFileOperationFailure(int, int);
method public static void logFilePick(int, long, int, boolean, int, int, int);
method public static void logInvalidScopedAccessRequest(int);
- method public static void logPickerLaunchedFrom(String);
+ method public static void logPickerLaunchedFrom(@Nullable String);
method public static void logRootVisited(int, int);
method public static void logSearchMode(int);
method public static void logSearchType(int);
diff --git a/api/test-current.txt b/api/test-current.txt
index d016c11..684524e 100644
--- a/api/test-current.txt
+++ b/api/test-current.txt
@@ -193,29 +193,36 @@
field public static final String OPSTR_WRITE_SMS = "android:write_sms";
field public static final String OPSTR_WRITE_WALLPAPER = "android:write_wallpaper";
field public static final int OP_COARSE_LOCATION = 0; // 0x0
+ field public static final int OP_FLAGS_ALL = 31; // 0x1f
+ field public static final int OP_FLAG_SELF = 1; // 0x1
+ field public static final int OP_FLAG_TRUSTED_PROXIED = 8; // 0x8
+ field public static final int OP_FLAG_TRUSTED_PROXY = 2; // 0x2
+ field public static final int OP_FLAG_UNTRUSTED_PROXIED = 16; // 0x10
+ field public static final int OP_FLAG_UNTRUSTED_PROXY = 4; // 0x4
field public static final int OP_RECORD_AUDIO = 27; // 0x1b
+ field public static final int OP_START_FOREGROUND = 76; // 0x4c
field public static final int OP_SYSTEM_ALERT_WINDOW = 24; // 0x18
- field public static final int UID_STATE_BACKGROUND = 5; // 0x5
- field public static final int UID_STATE_CACHED = 6; // 0x6
- field public static final int UID_STATE_FOREGROUND = 4; // 0x4
- field public static final int UID_STATE_FOREGROUND_SERVICE = 3; // 0x3
- field public static final int UID_STATE_FOREGROUND_SERVICE_LOCATION = 2; // 0x2
- field public static final int UID_STATE_PERSISTENT = 0; // 0x0
- field public static final int UID_STATE_TOP = 1; // 0x1
+ field public static final int UID_STATE_BACKGROUND = 600; // 0x258
+ field public static final int UID_STATE_CACHED = 700; // 0x2bc
+ field public static final int UID_STATE_FOREGROUND = 500; // 0x1f4
+ field public static final int UID_STATE_FOREGROUND_SERVICE = 400; // 0x190
+ field public static final int UID_STATE_FOREGROUND_SERVICE_LOCATION = 300; // 0x12c
+ field public static final int UID_STATE_PERSISTENT = 100; // 0x64
+ field public static final int UID_STATE_TOP = 200; // 0xc8
}
public static final class AppOpsManager.HistoricalOp implements android.os.Parcelable {
method public int describeContents();
- method public long getAccessCount(int);
- method public long getAccessDuration(int);
- method public long getBackgroundAccessCount();
- method public long getBackgroundAccessDuration();
- method public long getBackgroundRejectCount();
- method public long getForegroundAccessCount();
- method public long getForegroundAccessDuration();
- method public long getForegroundRejectCount();
+ method public long getAccessCount(int, int, int);
+ method public long getAccessDuration(int, int, int);
+ method public long getBackgroundAccessCount(int);
+ method public long getBackgroundAccessDuration(int);
+ method public long getBackgroundRejectCount(int);
+ method public long getForegroundAccessCount(int);
+ method public long getForegroundAccessDuration(int);
+ method public long getForegroundRejectCount(int);
method @NonNull public String getOpName();
- method public long getRejectCount(int);
+ method public long getRejectCount(int, int, int);
method public void writeToParcel(android.os.Parcel, int);
field @NonNull public static final android.os.Parcelable.Creator<android.app.AppOpsManager.HistoricalOp> CREATOR;
}
@@ -228,9 +235,9 @@
method public int getUidCount();
method @Nullable public android.app.AppOpsManager.HistoricalUidOps getUidOps(int);
method @NonNull public android.app.AppOpsManager.HistoricalUidOps getUidOpsAt(int);
- method public void increaseAccessCount(int, int, @NonNull String, int, long);
- method public void increaseAccessDuration(int, int, @NonNull String, int, long);
- method public void increaseRejectCount(int, int, @NonNull String, int, long);
+ method public void increaseAccessCount(int, int, @NonNull String, int, int, long);
+ method public void increaseAccessDuration(int, int, @NonNull String, int, int, long);
+ method public void increaseRejectCount(int, int, @NonNull String, int, int, long);
method public void offsetBeginAndEndTime(long);
method public void writeToParcel(android.os.Parcel, int);
field @NonNull public static final android.os.Parcelable.Creator<android.app.AppOpsManager.HistoricalOps> CREATOR;
@@ -242,6 +249,7 @@
public static final class AppOpsManager.HistoricalOpsRequest.Builder {
ctor public AppOpsManager.HistoricalOpsRequest.Builder(long, long);
method @NonNull public android.app.AppOpsManager.HistoricalOpsRequest build();
+ method @NonNull public android.app.AppOpsManager.HistoricalOpsRequest.Builder setFlags(int);
method @NonNull public android.app.AppOpsManager.HistoricalOpsRequest.Builder setOpNames(@Nullable java.util.List<java.lang.String>);
method @NonNull public android.app.AppOpsManager.HistoricalOpsRequest.Builder setPackageName(@Nullable String);
method @NonNull public android.app.AppOpsManager.HistoricalOpsRequest.Builder setUid(int);
@@ -271,6 +279,31 @@
method public void onOpActiveChanged(int, int, String, boolean);
}
+ public static final class AppOpsManager.OpEntry implements android.os.Parcelable {
+ method public int describeContents();
+ method public long getDuration();
+ method public long getLastAccessBackgroundTime(int);
+ method public long getLastAccessForegroundTime(int);
+ method public long getLastAccessTime(int);
+ method public long getLastAccessTime(int, int, int);
+ method public long getLastBackgroundDuration(int);
+ method public long getLastDuration(int, int, int);
+ method public long getLastForegroundDuration(int);
+ method public long getLastRejectBackgroundTime(int);
+ method public long getLastRejectForegroundTime(int);
+ method public long getLastRejectTime(int);
+ method public long getLastRejectTime(int, int, int);
+ method public int getMode();
+ method @NonNull public String getOpStr();
+ method @Nullable public String getProxyPackageName();
+ method @Nullable public String getProxyPackageName(int, int);
+ method public int getProxyUid();
+ method public int getProxyUid(int, int);
+ method public boolean isRunning();
+ method public void writeToParcel(android.os.Parcel, int);
+ field @NonNull public static final android.os.Parcelable.Creator<android.app.AppOpsManager.OpEntry> CREATOR;
+ }
+
public class DownloadManager {
field public static final String COLUMN_MEDIASTORE_URI = "mediastore_uri";
}
@@ -978,7 +1011,7 @@
method public android.media.MediaPlayer2.DrmInfo getDrmInfo(@NonNull android.media.DataSourceDesc);
method public android.media.MediaDrm.KeyRequest getDrmKeyRequest(@NonNull android.media.DataSourceDesc, @Nullable byte[], @Nullable byte[], @Nullable String, int, @Nullable java.util.Map<java.lang.String,java.lang.String>) throws android.media.MediaPlayer2.NoDrmSchemeException;
method public String getDrmPropertyString(@NonNull android.media.DataSourceDesc, @NonNull String) throws android.media.MediaPlayer2.NoDrmSchemeException;
- method public Object prepareDrm(@NonNull android.media.DataSourceDesc, @NonNull java.util.UUID);
+ method @NonNull public Object prepareDrm(@NonNull android.media.DataSourceDesc, @NonNull java.util.UUID);
method public byte[] provideDrmKeyResponse(@NonNull android.media.DataSourceDesc, @Nullable byte[], @NonNull byte[]) throws android.media.DeniedByServerException, android.media.MediaPlayer2.NoDrmSchemeException;
method public void releaseDrm(@NonNull android.media.DataSourceDesc) throws android.media.MediaPlayer2.NoDrmSchemeException;
method public void restoreDrmKeys(@NonNull android.media.DataSourceDesc, @NonNull byte[]) throws android.media.MediaPlayer2.NoDrmSchemeException;
@@ -2732,6 +2765,10 @@
field public static final int CALLBACK_ANIMATION = 1; // 0x1
}
+ public final class Display {
+ method public boolean hasAccess(int);
+ }
+
public class FocusFinder {
method public static void sort(android.view.View[], int, int, android.view.ViewGroup, boolean);
}
@@ -2996,7 +3033,7 @@
method public abstract String value();
}
- @java.lang.annotation.Retention(java.lang.annotation.RetentionPolicy.SOURCE) @java.lang.annotation.Target({java.lang.annotation.ElementType.METHOD}) public @interface InspectableProperty {
+ @java.lang.annotation.Retention(java.lang.annotation.RetentionPolicy.SOURCE) @java.lang.annotation.Target({java.lang.annotation.ElementType.METHOD, java.lang.annotation.ElementType.FIELD}) public @interface InspectableProperty {
method public abstract int attributeId() default android.content.res.Resources.ID_NULL;
method public abstract android.view.inspector.InspectableProperty.EnumMap[] enumMapping() default {};
method public abstract android.view.inspector.InspectableProperty.FlagMap[] flagMapping() default {};
diff --git a/core/java/android/app/AppOpsManager.java b/core/java/android/app/AppOpsManager.java
index 5bf7ef5..91df05f 100644
--- a/core/java/android/app/AppOpsManager.java
+++ b/core/java/android/app/AppOpsManager.java
@@ -43,6 +43,8 @@
import android.os.UserManager;
import android.provider.Settings;
import android.util.ArrayMap;
+import android.util.LongSparseArray;
+import android.util.LongSparseLongArray;
import android.util.SparseArray;
import com.android.internal.annotations.GuardedBy;
@@ -55,8 +57,10 @@
import com.android.internal.util.ArrayUtils;
import com.android.internal.util.Preconditions;
+import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.ArrayList;
@@ -64,9 +68,11 @@
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
+import java.util.Objects;
import java.util.concurrent.Executor;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.function.Consumer;
+import java.util.function.Supplier;
/**
* API for interacting with "application operation" tracking.
@@ -227,7 +233,7 @@
/** @hide */
@Retention(RetentionPolicy.SOURCE)
- @IntDef(flag = true, prefix = { "UID_STATE_" }, value = {
+ @IntDef(prefix = { "UID_STATE_" }, value = {
UID_STATE_PERSISTENT,
UID_STATE_TOP,
UID_STATE_FOREGROUND_SERVICE_LOCATION,
@@ -239,78 +245,322 @@
public @interface UidState {}
/**
- * Invalid UID state.
- * @hide
- */
- public static final int UID_STATE_INVALID = -1;
-
- /**
- * Metrics about an op when its uid is persistent.
+ * Uid state: The UID is a foreground persistent app.
* @hide
*/
@TestApi
@SystemApi
- public static final int UID_STATE_PERSISTENT = 0;
+ public static final int UID_STATE_PERSISTENT = 100;
/**
- * Metrics about an op when its uid is at the top.
+ * Uid state: The UID is top foreground app.
* @hide
*/
@TestApi
@SystemApi
- public static final int UID_STATE_TOP = 1;
+ public static final int UID_STATE_TOP = 200;
/**
- * Metrics about an op when its uid is running a foreground service with location type.
+ * Uid state: The UID is running a foreground service of location type.
* @hide
*/
@TestApi
@SystemApi
- public static final int UID_STATE_FOREGROUND_SERVICE_LOCATION = 2;
+ public static final int UID_STATE_FOREGROUND_SERVICE_LOCATION = 300;
/**
- * Metrics about an op when its uid is running a foreground service.
+ * Uid state: The UID is running a foreground service.
* @hide
*/
@TestApi
@SystemApi
- public static final int UID_STATE_FOREGROUND_SERVICE = 3;
+ public static final int UID_STATE_FOREGROUND_SERVICE = 400;
/**
- * Last UID state in which we don't restrict what an op can do.
+ * The max, which is min priority, UID state for which any app op
+ * would be considered as performed in the foreground.
* @hide
*/
- public static final int UID_STATE_LAST_NON_RESTRICTED = UID_STATE_FOREGROUND_SERVICE_LOCATION;
+ public static final int UID_STATE_MAX_LAST_NON_RESTRICTED = UID_STATE_FOREGROUND_SERVICE;
/**
- * Metrics about an op when its uid is in the foreground for any other reasons.
+ * Uid state: The UID is a foreground app.
* @hide
*/
@TestApi
@SystemApi
- public static final int UID_STATE_FOREGROUND = 4;
+ public static final int UID_STATE_FOREGROUND = 500;
/**
- * Metrics about an op when its uid is in the background for any reason.
+ * Uid state: The UID is a background app.
* @hide
*/
@TestApi
@SystemApi
- public static final int UID_STATE_BACKGROUND = 5;
+ public static final int UID_STATE_BACKGROUND = 600;
/**
- * Metrics about an op when its uid is cached.
+ * Uid state: The UID is a cached app.
* @hide
*/
@TestApi
@SystemApi
- public static final int UID_STATE_CACHED = 6;
+ public static final int UID_STATE_CACHED = 700;
/**
- * Number of uid states we track.
+ * Uid state: The UID state with the highest priority.
* @hide
*/
- public static final int _NUM_UID_STATE = 7;
+ public static final int MAX_PRIORITY_UID_STATE = UID_STATE_PERSISTENT;
+
+ /**
+ * Uid state: The UID state with the lowest priority.
+ * @hide
+ */
+ public static final int MIN_PRIORITY_UID_STATE = UID_STATE_CACHED;
+
+ /**
+ * Resolves the first unrestricted state given an app op. Location is
+ * special as we want to allow its access only if a dedicated location
+ * foreground service is running. For other ops we consider any foreground
+ * service as a foreground state.
+ *
+ * @param op The op to resolve.
+ * @return The last restricted UID state.
+ *
+ * @hide
+ */
+ public static int resolveFirstUnrestrictedUidState(int op) {
+ switch (op) {
+ case OP_FINE_LOCATION:
+ case OP_COARSE_LOCATION: {
+ return UID_STATE_FOREGROUND_SERVICE_LOCATION;
+ }
+ }
+ return UID_STATE_FOREGROUND_SERVICE;
+ }
+
+ /**
+ * Resolves the last restricted state given an app op. Location is
+ * special as we want to allow its access only if a dedicated location
+ * foreground service is running. For other ops we consider any foreground
+ * service as a foreground state.
+ *
+ * @param op The op to resolve.
+ * @return The last restricted UID state.
+ *
+ * @hide
+ */
+ public static int resolveLastRestrictedUidState(int op) {
+ switch (op) {
+ case OP_FINE_LOCATION:
+ case OP_COARSE_LOCATION: {
+ return UID_STATE_FOREGROUND_SERVICE;
+ }
+ }
+ return UID_STATE_FOREGROUND;
+ }
+
+ /** @hide Note: Keep these sorted */
+ public static final int[] UID_STATES = {
+ UID_STATE_PERSISTENT,
+ UID_STATE_TOP,
+ UID_STATE_FOREGROUND_SERVICE_LOCATION,
+ UID_STATE_FOREGROUND_SERVICE,
+ UID_STATE_FOREGROUND,
+ UID_STATE_BACKGROUND,
+ UID_STATE_CACHED
+ };
+
+ /** @hide */
+ public static String getUidStateName(@UidState int uidState) {
+ switch (uidState) {
+ case UID_STATE_PERSISTENT:
+ return "pers";
+ case UID_STATE_TOP:
+ return "top";
+ case UID_STATE_FOREGROUND_SERVICE_LOCATION:
+ return "fgsvcl";
+ case UID_STATE_FOREGROUND_SERVICE:
+ return "fgsvc";
+ case UID_STATE_FOREGROUND:
+ return "fg";
+ case UID_STATE_BACKGROUND:
+ return "bg";
+ case UID_STATE_CACHED:
+ return "cch";
+ default:
+ return "unknown";
+ }
+ }
+
+ /**
+ * Flag: non proxy operations. These are operations
+ * performed on behalf of the app itself and not on behalf of
+ * another one.
+ *
+ * @hide
+ */
+ @TestApi
+ @SystemApi
+ public static final int OP_FLAG_SELF = 0x1;
+
+ /**
+ * Flag: trusted proxy operations. These are operations
+ * performed on behalf of another app by a trusted app.
+ * Which is work a trusted app blames on another app.
+ *
+ * @hide
+ */
+ @TestApi
+ @SystemApi
+ public static final int OP_FLAG_TRUSTED_PROXY = 0x2;
+
+ /**
+ * Flag: untrusted proxy operations. These are operations
+ * performed on behalf of another app by an untrusted app.
+ * Which is work an untrusted app blames on another app.
+ *
+ * @hide
+ */
+ @TestApi
+ @SystemApi
+ public static final int OP_FLAG_UNTRUSTED_PROXY = 0x4;
+
+ /**
+ * Flag: trusted proxied operations. These are operations
+ * performed by a trusted other app on behalf of an app.
+ * Which is work an app was blamed for by a trusted app.
+ *
+ * @hide
+ */
+ @TestApi
+ @SystemApi
+ public static final int OP_FLAG_TRUSTED_PROXIED = 0x8;
+
+ /**
+ * Flag: untrusted proxied operations. These are operations
+ * performed by an untrusted other app on behalf of an app.
+ * Which is work an app was blamed for by an untrusted app.
+ *
+ * @hide
+ */
+ @TestApi
+ @SystemApi
+ public static final int OP_FLAG_UNTRUSTED_PROXIED = 0x10;
+
+ /**
+ * Flags: all operations. These include operations matched
+ * by {@link #OP_FLAG_SELF}, {@link #OP_FLAG_TRUSTED_PROXIED},
+ * {@link #OP_FLAG_UNTRUSTED_PROXIED}, {@link #OP_FLAG_TRUSTED_PROXIED},
+ * {@link #OP_FLAG_UNTRUSTED_PROXIED}.
+ *
+ * @hide
+ */
+ @TestApi
+ @SystemApi
+ public static final int OP_FLAGS_ALL =
+ OP_FLAG_SELF
+ | OP_FLAG_TRUSTED_PROXY
+ | OP_FLAG_UNTRUSTED_PROXY
+ | OP_FLAG_TRUSTED_PROXIED
+ | OP_FLAG_UNTRUSTED_PROXIED;
+
+ /**
+ * Flags: all trusted operations which is ones either the app did {@link #OP_FLAG_SELF},
+ * or it was blamed for by a trusted app {@link #OP_FLAG_TRUSTED_PROXIED}, or ones the
+ * app if untrusted blamed on other apps {@link #OP_FLAG_UNTRUSTED_PROXY}.
+ *
+ * @hide
+ */
+ @SystemApi
+ public static final int OP_FLAGS_ALL_TRUSTED = AppOpsManager.OP_FLAG_SELF
+ | AppOpsManager.OP_FLAG_UNTRUSTED_PROXY
+ | AppOpsManager.OP_FLAG_TRUSTED_PROXIED;
+
+ /** @hide */
+ @Retention(RetentionPolicy.SOURCE)
+ @IntDef(flag = true, prefix = { "FLAG_" }, value = {
+ OP_FLAG_SELF,
+ OP_FLAG_TRUSTED_PROXY,
+ OP_FLAG_UNTRUSTED_PROXY,
+ OP_FLAG_TRUSTED_PROXIED,
+ OP_FLAG_UNTRUSTED_PROXIED
+ })
+ public @interface OpFlags {}
+
+
+ /** @hide */
+ public static final String getFlagName(@OpFlags int flag) {
+ switch (flag) {
+ case OP_FLAG_SELF:
+ return "s";
+ case OP_FLAG_TRUSTED_PROXY:
+ return "tp";
+ case OP_FLAG_UNTRUSTED_PROXY:
+ return "up";
+ case OP_FLAG_TRUSTED_PROXIED:
+ return "tpd";
+ case OP_FLAG_UNTRUSTED_PROXIED:
+ return "upd";
+ default:
+ return "unknown";
+ }
+ }
+
+ private static final int UID_STATE_OFFSET = 31;
+ private static final int FLAGS_MASK = 0xFFFFFFFF;
+
+ /**
+ * Key for a data bucket storing app op state. The bucket
+ * is composed of the uid state and state flags. This way
+ * we can query data for given uid state and a set of flags where
+ * the flags control which type of data to get. For example,
+ * one can get the ops an app did on behalf of other apps
+ * while in the background.
+ *
+ * @hide
+ */
+ @Retention(RetentionPolicy.SOURCE)
+ @Target({ElementType.METHOD, ElementType.PARAMETER, ElementType.FIELD})
+ public @interface DataBucketKey {
+ }
+
+ /** @hide */
+ public static String keyToString(@DataBucketKey long key) {
+ final int uidState = extractUidStateFromKey(key);
+ final int flags = extractFlagsFromKey(key);
+ return "[" + getUidStateName(uidState) + "-" + flagsToString(flags) + "]";
+ }
+
+ /** @hide */
+ public static @DataBucketKey long makeKey(@UidState int uidState, @OpFlags int flags) {
+ return ((long) uidState << UID_STATE_OFFSET) | flags;
+ }
+
+ /** @hide */
+ public static int extractUidStateFromKey(@DataBucketKey long key) {
+ return (int) (key >> UID_STATE_OFFSET);
+ }
+
+ /** @hide */
+ public static int extractFlagsFromKey(@DataBucketKey long key) {
+ return (int) (key & FLAGS_MASK);
+ }
+
+ /** @hide */
+ public static String flagsToString(@OpFlags int flags) {
+ final StringBuilder flagsBuilder = new StringBuilder();
+ while (flags != 0) {
+ final int flag = 1 << Integer.numberOfTrailingZeros(flags);
+ flags &= ~flag;
+ if (flagsBuilder.length() > 0) {
+ flagsBuilder.append('|');
+ }
+ flagsBuilder.append(getFlagName(flag));
+ }
+ return flagsBuilder.toString();
+ }
// when adding one of these:
// - increment _NUM_OP
@@ -551,7 +801,7 @@
@UnsupportedAppUsage
public static final int OP_MANAGE_IPSEC_TUNNELS = 75;
/** @hide Any app start foreground service. */
- @UnsupportedAppUsage
+ @TestApi
public static final int OP_START_FOREGROUND = 76;
/** @hide */
@UnsupportedAppUsage
@@ -1947,14 +2197,23 @@
mEntries = entries;
}
- public String getPackageName() {
+ /**
+ * @return The name of the package.
+ */
+ public @NonNull String getPackageName() {
return mPackageName;
}
+ /**
+ * @return The uid of the package.
+ */
public int getUid() {
return mUid;
}
+ /**
+ * @return The ops of the package.
+ */
public List<OpEntry> getOps() {
return mEntries;
}
@@ -1999,57 +2258,59 @@
* Class holding the information about one unique operation of an application.
* @hide
*/
+ @TestApi
+ @Immutable
@SystemApi
public static final class OpEntry implements Parcelable {
private final int mOp;
- private final @Mode int mMode;
- private final long[] mTimes;
- private final long[] mRejectTimes;
- private final int mDuration;
- private final int mProxyUid;
private final boolean mRunning;
- private final String mProxyPackageName;
+ private final @Mode int mMode;
+ private final @Nullable LongSparseLongArray mAccessTimes;
+ private final @Nullable LongSparseLongArray mRejectTimes;
+ private final @Nullable LongSparseLongArray mDurations;
+ private final @Nullable LongSparseLongArray mProxyUids;
+ private final @Nullable LongSparseArray<String> mProxyPackageNames;
/**
* @hide
*/
- public OpEntry(int op, @Mode int mode, long time, long rejectTime, int duration,
- int proxyUid, String proxyPackage) {
+ public OpEntry(int op, boolean running, @Mode int mode,
+ @Nullable LongSparseLongArray accessTimes, @Nullable LongSparseLongArray rejectTimes,
+ @Nullable LongSparseLongArray durations, @Nullable LongSparseLongArray proxyUids,
+ @Nullable LongSparseArray<String> proxyPackageNames) {
mOp = op;
- mMode = mode;
- mTimes = new long[_NUM_UID_STATE];
- mRejectTimes = new long[_NUM_UID_STATE];
- mTimes[0] = time;
- mRejectTimes[0] = rejectTime;
- mDuration = duration;
- mRunning = duration == -1;
- mProxyUid = proxyUid;
- mProxyPackageName = proxyPackage;
- }
-
- /**
- * @hide
- */
- public OpEntry(int op, @Mode int mode, long[] times, long[] rejectTimes, int duration,
- boolean running, int proxyUid, String proxyPackage) {
- mOp = op;
- mMode = mode;
- mTimes = new long[_NUM_UID_STATE];
- mRejectTimes = new long[_NUM_UID_STATE];
- System.arraycopy(times, 0, mTimes, 0, _NUM_UID_STATE);
- System.arraycopy(rejectTimes, 0, mRejectTimes, 0, _NUM_UID_STATE);
- mDuration = duration;
mRunning = running;
- mProxyUid = proxyUid;
- mProxyPackageName = proxyPackage;
+ mMode = mode;
+ mAccessTimes = accessTimes;
+ mRejectTimes = rejectTimes;
+ mDurations = durations;
+ mProxyUids = proxyUids;
+ mProxyPackageNames = proxyPackageNames;
}
/**
* @hide
*/
- public OpEntry(int op, @Mode int mode, long[] times, long[] rejectTimes, int duration,
- int proxyUid, String proxyPackage) {
- this(op, mode, times, rejectTimes, duration, duration == -1, proxyUid, proxyPackage);
+ public OpEntry(int op, @Mode int mode) {
+ mOp = op;
+ mMode = mode;
+ mRunning = false;
+ mAccessTimes = null;
+ mRejectTimes = null;
+ mDurations = null;
+ mProxyUids = null;
+ mProxyPackageNames = null;
+ }
+
+ /**
+ * Returns all keys for which we have mapped state in any of the data buckets -
+ * access time, reject time, duration.
+ * @hide */
+ public @Nullable LongSparseArray<Object> collectKeys() {
+ LongSparseArray<Object> result = AppOpsManager.collectKeys(mAccessTimes, null);
+ result = AppOpsManager.collectKeys(mRejectTimes, result);
+ result = AppOpsManager.collectKeys(mDurations, result);
+ return result;
}
/**
@@ -2061,14 +2322,14 @@
}
/**
- * Return this entry's op string name, such as {@link #OPSTR_COARSE_LOCATION}.
+ * @return This entry's op string name, such as {@link #OPSTR_COARSE_LOCATION}.
*/
- public String getOpStr() {
+ public @NonNull String getOpStr() {
return sOpToString[mOp];
}
/**
- * Return this entry's current mode, such as {@link #MODE_ALLOWED}.
+ * @return this entry's current mode, such as {@link #MODE_ALLOWED}.
*/
public @Mode int getMode() {
return mMode;
@@ -2079,89 +2340,331 @@
*/
@UnsupportedAppUsage
public long getTime() {
- return maxTime(mTimes, 0, _NUM_UID_STATE);
+ return getLastAccessTime(OP_FLAGS_ALL);
}
/**
- * Return the last wall clock time this op was accessed by the app.
+ * Return the last wall clock time in milliseconds this op was accessed.
+ *
+ * @param flags The flags which are any combination of
+ * {@link #OP_FLAG_SELF}, {@link #OP_FLAG_TRUSTED_PROXY},
+ * {@link #OP_FLAG_UNTRUSTED_PROXY}, {@link #OP_FLAG_TRUSTED_PROXIED},
+ * {@link #OP_FLAG_UNTRUSTED_PROXIED}. You can use {@link #OP_FLAGS_ALL}
+ * for any flag.
+ * @return the last access time in milliseconds since
+ * epoch start (January 1, 1970 00:00:00.000 GMT - Gregorian).
+ *
+ * @see #getLastAccessForegroundTime(int)
+ * @see #getLastAccessBackgroundTime(int)
+ * @see #getLastAccessTime(int, int, int)
*/
- public long getLastAccessTime() {
- return maxTime(mTimes, 0, _NUM_UID_STATE);
+ public long getLastAccessTime(@OpFlags int flags) {
+ return maxForFlagsInStates(mAccessTimes, MAX_PRIORITY_UID_STATE,
+ MIN_PRIORITY_UID_STATE, flags);
}
/**
- * Return the last wall clock time this op was accessed by the app while in the foreground.
+ * Return the last wall clock time in milliseconds this op was accessed
+ * by the app while in the foreground.
+ *
+ * @param flags The flags which are any combination of
+ * {@link #OP_FLAG_SELF}, {@link #OP_FLAG_TRUSTED_PROXY},
+ * {@link #OP_FLAG_UNTRUSTED_PROXY}, {@link #OP_FLAG_TRUSTED_PROXIED},
+ * {@link #OP_FLAG_UNTRUSTED_PROXIED}. You can use {@link #OP_FLAGS_ALL}
+ * for any flag.
+ * @return the last foreground access time in milliseconds since
+ * epoch start (January 1, 1970 00:00:00.000 GMT - Gregorian).
+ *
+ * @see #getLastAccessBackgroundTime(int)
+ * @see #getLastAccessTime(int)
+ * @see #getLastAccessTime(int, int, int)
*/
- public long getLastAccessForegroundTime() {
- return maxTime(mTimes, UID_STATE_PERSISTENT, UID_STATE_LAST_NON_RESTRICTED + 1);
+ public long getLastAccessForegroundTime(@OpFlags int flags) {
+ return maxForFlagsInStates(mAccessTimes, MAX_PRIORITY_UID_STATE,
+ resolveFirstUnrestrictedUidState(mOp), flags);
}
/**
- * Return the last wall clock time this op was accessed by the app while in the background.
+ * Return the last wall clock time in milliseconds this op was accessed
+ * by the app while in the background.
+ *
+ * @param flags The flags which are any combination of
+ * {@link #OP_FLAG_SELF}, {@link #OP_FLAG_TRUSTED_PROXY},
+ * {@link #OP_FLAG_UNTRUSTED_PROXY}, {@link #OP_FLAG_TRUSTED_PROXIED},
+ * {@link #OP_FLAG_UNTRUSTED_PROXIED}. You can use {@link #OP_FLAGS_ALL}
+ * for any flag.
+ * @return the last foreground access time in milliseconds since
+ * epoch start (January 1, 1970 00:00:00.000 GMT - Gregorian).
+ *
+ * @see #getLastAccessForegroundTime(int)
+ * @see #getLastAccessTime(int)
+ * @see #getLastAccessTime(int, int, int)
*/
- public long getLastAccessBackgroundTime() {
- return maxTime(mTimes, UID_STATE_LAST_NON_RESTRICTED + 1, _NUM_UID_STATE);
+ public long getLastAccessBackgroundTime(@OpFlags int flags) {
+ return maxForFlagsInStates(mAccessTimes, resolveLastRestrictedUidState(mOp),
+ MIN_PRIORITY_UID_STATE, flags);
}
/**
- * @hide
+ * Return the last wall clock time in milliseconds this op was accessed
+ * by the app for a given range of UID states.
+ *
+ * @param fromUidState The UID state for which to query. Could be one of
+ * {@link #UID_STATE_PERSISTENT}, {@link #UID_STATE_TOP},
+ * {@link #UID_STATE_FOREGROUND_SERVICE}, {@link #UID_STATE_FOREGROUND},
+ * {@link #UID_STATE_BACKGROUND}, {@link #UID_STATE_CACHED}.
+ * @param toUidState The UID state for which to query.
+ * @param flags The flags which are any combination of
+ * {@link #OP_FLAG_SELF}, {@link #OP_FLAG_TRUSTED_PROXY},
+ * {@link #OP_FLAG_UNTRUSTED_PROXY}, {@link #OP_FLAG_TRUSTED_PROXIED},
+ * {@link #OP_FLAG_UNTRUSTED_PROXIED}. You can use {@link #OP_FLAGS_ALL}
+ * for any flag.
+ *
+ * @return the last foreground access time in milliseconds since
+ * epoch start (January 1, 1970 00:00:00.000 GMT - Gregorian).
+ *
+ * @see #getLastAccessForegroundTime(int)
+ * @see #getLastAccessBackgroundTime(int)
+ * @see #getLastAccessTime(int)
*/
- public long getLastTimeFor(int uidState) {
- return mTimes[uidState];
+ public long getLastAccessTime(@UidState int fromUidState, @UidState int toUidState,
+ @OpFlags int flags) {
+ return maxForFlagsInStates(mAccessTimes, fromUidState, toUidState, flags);
}
/**
* @hide
*/
public long getRejectTime() {
- return maxTime(mRejectTimes, 0, _NUM_UID_STATE);
+ return getLastRejectTime(OP_FLAGS_ALL);
}
/**
- * Return the last wall clock time the app made an attempt to access this op but
- * was rejected.
+ * Return the last wall clock time in milliseconds the app made an attempt
+ * to access this op but was rejected.
+ *
+ * @param flags The flags which are any combination of
+ * {@link #OP_FLAG_SELF}, {@link #OP_FLAG_TRUSTED_PROXY},
+ * {@link #OP_FLAG_UNTRUSTED_PROXY}, {@link #OP_FLAG_TRUSTED_PROXIED},
+ * {@link #OP_FLAG_UNTRUSTED_PROXIED}. You can use {@link #OP_FLAGS_ALL}
+ * for any flag.
+ * @return the last reject time in milliseconds since
+ * epoch start (January 1, 1970 00:00:00.000 GMT - Gregorian).
+ *
+ * @see #getLastRejectBackgroundTime(int)
+ * @see #getLastRejectForegroundTime(int)
+ * @see #getLastRejectTime(int, int, int)
*/
- public long getLastRejectTime() {
- return maxTime(mRejectTimes, 0, _NUM_UID_STATE);
+ public long getLastRejectTime(@OpFlags int flags) {
+ return maxForFlagsInStates(mRejectTimes, MAX_PRIORITY_UID_STATE,
+ MIN_PRIORITY_UID_STATE, flags);
}
/**
- * Return the last wall clock time the app made an attempt to access this op while in
- * the foreground but was rejected.
+ * Return the last wall clock time in milliseconds the app made an attempt
+ * to access this op while in the foreground but was rejected.
+ *
+ * @param flags The flags which are any combination of
+ * {@link #OP_FLAG_SELF}, {@link #OP_FLAG_TRUSTED_PROXY},
+ * {@link #OP_FLAG_UNTRUSTED_PROXY}, {@link #OP_FLAG_TRUSTED_PROXIED},
+ * {@link #OP_FLAG_UNTRUSTED_PROXIED}. You can use {@link #OP_FLAGS_ALL}
+ * for any flag.
+ * @return the last foreground reject time in milliseconds since
+ * epoch start (January 1, 1970 00:00:00.000 GMT - Gregorian).
+ *
+ * @see #getLastRejectBackgroundTime(int)
+ * @see #getLastRejectTime(int, int, int)
+ * @see #getLastRejectTime(int)
*/
- public long getLastRejectForegroundTime() {
- return maxTime(mRejectTimes, UID_STATE_PERSISTENT, UID_STATE_LAST_NON_RESTRICTED + 1);
+ public long getLastRejectForegroundTime(@OpFlags int flags) {
+ return maxForFlagsInStates(mRejectTimes, MAX_PRIORITY_UID_STATE,
+ resolveFirstUnrestrictedUidState(mOp), flags);
}
/**
- * Return the last wall clock time the app made an attempt to access this op while in
- * the background but was rejected.
+ * Return the last wall clock time in milliseconds the app made an attempt
+ * to access this op while in the background but was rejected.
+ *
+ * @param flags The flags which are any combination of
+ * {@link #OP_FLAG_SELF}, {@link #OP_FLAG_TRUSTED_PROXY},
+ * {@link #OP_FLAG_UNTRUSTED_PROXY}, {@link #OP_FLAG_TRUSTED_PROXIED},
+ * {@link #OP_FLAG_UNTRUSTED_PROXIED}. You can use {@link #OP_FLAGS_ALL}
+ * for any flag.
+ * @return the last background reject time in milliseconds since
+ * epoch start (January 1, 1970 00:00:00.000 GMT - Gregorian).
+ *
+ * @see #getLastRejectForegroundTime(int)
+ * @see #getLastRejectTime(int, int, int)
+ * @see #getLastRejectTime(int)
*/
- public long getLastRejectBackgroundTime() {
- return maxTime(mRejectTimes, UID_STATE_LAST_NON_RESTRICTED + 1, _NUM_UID_STATE);
+ public long getLastRejectBackgroundTime(@OpFlags int flags) {
+ return maxForFlagsInStates(mRejectTimes, resolveLastRestrictedUidState(mOp),
+ MIN_PRIORITY_UID_STATE, flags);
}
/**
- * @hide
+ * Return the last wall clock time state in milliseconds the app made an
+ * attempt to access this op for a given range of UID states.
+ *
+ * @param fromUidState The UID state from which to query. Could be one of
+ * {@link #UID_STATE_PERSISTENT}, {@link #UID_STATE_TOP},
+ * {@link #UID_STATE_FOREGROUND_SERVICE}, {@link #UID_STATE_FOREGROUND},
+ * {@link #UID_STATE_BACKGROUND}, {@link #UID_STATE_CACHED}.
+ * @param toUidState The UID state to which to query.
+ * @param flags The flags which are any combination of
+ * {@link #OP_FLAG_SELF}, {@link #OP_FLAG_TRUSTED_PROXY},
+ * {@link #OP_FLAG_UNTRUSTED_PROXY}, {@link #OP_FLAG_TRUSTED_PROXIED},
+ * {@link #OP_FLAG_UNTRUSTED_PROXIED}. You can use {@link #OP_FLAGS_ALL}
+ * for any flag.
+ * @return the last foreground access time in milliseconds since
+ * epoch start (January 1, 1970 00:00:00.000 GMT - Gregorian).
+ *
+ * @see #getLastRejectForegroundTime(int)
+ * @see #getLastRejectBackgroundTime(int)
+ * @see #getLastRejectTime(int)
*/
- public long getLastRejectTimeFor(int uidState) {
- return mRejectTimes[uidState];
+ public long getLastRejectTime(@UidState int fromUidState, @UidState int toUidState,
+ @OpFlags int flags) {
+ return maxForFlagsInStates(mRejectTimes, fromUidState, toUidState, flags);
}
+ /**
+ * @return Whether the operation is running.
+ */
public boolean isRunning() {
return mRunning;
}
- public int getDuration() {
- return mDuration;
+ /**
+ * @return The duration of the operation in milliseconds.
+ */
+ public long getDuration() {
+ return getLastDuration(MAX_PRIORITY_UID_STATE, MIN_PRIORITY_UID_STATE, OP_FLAGS_ALL);
}
+ /**
+ * Return the duration in milliseconds the app accessed this op while
+ * in the foreground.
+ *
+ * @param flags The flags which are any combination of
+ * {@link #OP_FLAG_SELF}, {@link #OP_FLAG_TRUSTED_PROXY},
+ * {@link #OP_FLAG_UNTRUSTED_PROXY}, {@link #OP_FLAG_TRUSTED_PROXIED},
+ * {@link #OP_FLAG_UNTRUSTED_PROXIED}. You can use {@link #OP_FLAGS_ALL}
+ * for any flag.
+ * @return the foreground access duration in milliseconds.
+ *
+ * @see #getLastBackgroundDuration(int)
+ * @see #getLastDuration(int, int, int)
+ */
+ public long getLastForegroundDuration(@OpFlags int flags) {
+ return sumForFlagsInStates(mDurations, MAX_PRIORITY_UID_STATE,
+ resolveFirstUnrestrictedUidState(mOp), flags);
+ }
+
+ /**
+ * Return the duration in milliseconds the app accessed this op while
+ * in the background.
+ *
+ * @param flags The flags which are any combination of
+ * {@link #OP_FLAG_SELF}, {@link #OP_FLAG_TRUSTED_PROXY},
+ * {@link #OP_FLAG_UNTRUSTED_PROXY}, {@link #OP_FLAG_TRUSTED_PROXIED},
+ * {@link #OP_FLAG_UNTRUSTED_PROXIED}. You can use {@link #OP_FLAGS_ALL}
+ * for any flag.
+ * @return the background access duration in milliseconds.
+ *
+ * @see #getLastForegroundDuration(int)
+ * @see #getLastDuration(int, int, int)
+ */
+ public long getLastBackgroundDuration(@OpFlags int flags) {
+ return sumForFlagsInStates(mDurations, resolveLastRestrictedUidState(mOp),
+ MIN_PRIORITY_UID_STATE, flags);
+ }
+
+ /**
+ * Return the duration in milliseconds the app accessed this op for
+ * a given range of UID states.
+ *
+ * @param fromUidState The UID state for which to query. Could be one of
+ * {@link #UID_STATE_PERSISTENT}, {@link #UID_STATE_TOP},
+ * {@link #UID_STATE_FOREGROUND_SERVICE}, {@link #UID_STATE_FOREGROUND},
+ * {@link #UID_STATE_BACKGROUND}, {@link #UID_STATE_CACHED}.
+ * @param toUidState The UID state for which to query.
+ * @param flags The flags which are any combination of
+ * {@link #OP_FLAG_SELF}, {@link #OP_FLAG_TRUSTED_PROXY},
+ * {@link #OP_FLAG_UNTRUSTED_PROXY}, {@link #OP_FLAG_TRUSTED_PROXIED},
+ * {@link #OP_FLAG_UNTRUSTED_PROXIED}. You can use {@link #OP_FLAGS_ALL}
+ * for any flag.
+ * @return the access duration in milliseconds.
+ */
+ public long getLastDuration(@UidState int fromUidState, @UidState int toUidState,
+ @OpFlags int flags) {
+ return sumForFlagsInStates(mDurations, fromUidState, toUidState, flags);
+ }
+
+ /**
+ * Gets the UID of the app that performed the op on behalf of this app and
+ * as a result blamed the op on this app or {@link Process#INVALID_UID} if
+ * there is no proxy.
+ *
+ * @return The proxy UID.
+ */
public int getProxyUid() {
- return mProxyUid;
+ return (int) findFirstNonNegativeForFlagsInStates(mDurations,
+ MAX_PRIORITY_UID_STATE, MIN_PRIORITY_UID_STATE, OP_FLAGS_ALL);
}
- public String getProxyPackageName() {
- return mProxyPackageName;
+ /**
+ * Gets the UID of the app that performed the op on behalf of this app and
+ * as a result blamed the op on this app or {@link Process#INVALID_UID} if
+ * there is no proxy.
+ *
+ * @param uidState The UID state for which to query. Could be one of
+ * {@link #UID_STATE_PERSISTENT}, {@link #UID_STATE_TOP},
+ * {@link #UID_STATE_FOREGROUND_SERVICE}, {@link #UID_STATE_FOREGROUND},
+ * {@link #UID_STATE_BACKGROUND}, {@link #UID_STATE_CACHED}.
+ * @param flags The flags which are any combination of
+ * {@link #OP_FLAG_SELF}, {@link #OP_FLAG_TRUSTED_PROXY},
+ * {@link #OP_FLAG_UNTRUSTED_PROXY}, {@link #OP_FLAG_TRUSTED_PROXIED},
+ * {@link #OP_FLAG_UNTRUSTED_PROXIED}. You can use {@link #OP_FLAGS_ALL}
+ * for any flag.
+ *
+ * @return The proxy UID.
+ */
+ public int getProxyUid(@UidState int uidState, @OpFlags int flags) {
+ return (int) findFirstNonNegativeForFlagsInStates(mDurations,
+ uidState, uidState, flags);
+ }
+
+ /**
+ * Gets the package name of the app that performed the op on behalf of this
+ * app and as a result blamed the op on this app or {@code null}
+ * if there is no proxy.
+ *
+ * @return The proxy package name.
+ */
+ public @Nullable String getProxyPackageName() {
+ return findFirstNonNullForFlagsInStates(mProxyPackageNames, MAX_PRIORITY_UID_STATE,
+ MIN_PRIORITY_UID_STATE, OP_FLAGS_ALL);
+ }
+
+ /**
+ * Gets the package name of the app that performed the op on behalf of this
+ * app and as a result blamed the op on this app for a UID state or
+ * {@code null} if there is no proxy.
+ *
+ * @param uidState The UID state for which to query. Could be one of
+ * {@link #UID_STATE_PERSISTENT}, {@link #UID_STATE_TOP},
+ * {@link #UID_STATE_FOREGROUND_SERVICE}, {@link #UID_STATE_FOREGROUND},
+ * {@link #UID_STATE_BACKGROUND}, {@link #UID_STATE_CACHED}.
+ * @param flags The flags which are any combination of
+ * {@link #OP_FLAG_SELF}, {@link #OP_FLAG_TRUSTED_PROXY},
+ * {@link #OP_FLAG_UNTRUSTED_PROXY}, {@link #OP_FLAG_TRUSTED_PROXIED},
+ * {@link #OP_FLAG_UNTRUSTED_PROXIED}. You can use {@link #OP_FLAGS_ALL}
+ * for any flag.
+ * @return The proxy package name.
+ */
+ public @Nullable String getProxyPackageName(@UidState int uidState, @OpFlags int flags) {
+ return findFirstNonNullForFlagsInStates(mProxyPackageNames, uidState, uidState, flags);
}
@Override
@@ -2173,23 +2676,23 @@
public void writeToParcel(Parcel dest, int flags) {
dest.writeInt(mOp);
dest.writeInt(mMode);
- dest.writeLongArray(mTimes);
- dest.writeLongArray(mRejectTimes);
- dest.writeInt(mDuration);
dest.writeBoolean(mRunning);
- dest.writeInt(mProxyUid);
- dest.writeString(mProxyPackageName);
+ writeLongSparseLongArrayToParcel(mAccessTimes, dest);
+ writeLongSparseLongArrayToParcel(mRejectTimes, dest);
+ writeLongSparseLongArrayToParcel(mDurations, dest);
+ writeLongSparseLongArrayToParcel(mProxyUids, dest);
+ writeLongSparseStringArrayToParcel(mProxyPackageNames, dest);
}
OpEntry(Parcel source) {
mOp = source.readInt();
mMode = source.readInt();
- mTimes = source.createLongArray();
- mRejectTimes = source.createLongArray();
- mDuration = source.readInt();
mRunning = source.readBoolean();
- mProxyUid = source.readInt();
- mProxyPackageName = source.readString();
+ mAccessTimes = readLongSparseLongArrayFromParcel(source);
+ mRejectTimes = readLongSparseLongArrayFromParcel(source);
+ mDurations = readLongSparseLongArrayFromParcel(source);
+ mProxyUids = readLongSparseLongArrayFromParcel(source);
+ mProxyPackageNames = readLongSparseStringArrayFromParcel(source);
}
public static final @android.annotation.NonNull Creator<OpEntry> CREATOR = new Creator<OpEntry>() {
@@ -2226,14 +2729,17 @@
private final @Nullable List<String> mOpNames;
private final long mBeginTimeMillis;
private final long mEndTimeMillis;
+ private final @OpFlags int mFlags;
private HistoricalOpsRequest(int uid, @Nullable String packageName,
- @Nullable List<String> opNames, long beginTimeMillis, long endTimeMillis) {
+ @Nullable List<String> opNames, long beginTimeMillis, long endTimeMillis,
+ @OpFlags int flags) {
mUid = uid;
mPackageName = packageName;
mOpNames = opNames;
mBeginTimeMillis = beginTimeMillis;
mEndTimeMillis = endTimeMillis;
+ mFlags = flags;
}
/**
@@ -2249,6 +2755,7 @@
private @Nullable List<String> mOpNames;
private final long mBeginTimeMillis;
private final long mEndTimeMillis;
+ private @OpFlags int mFlags = OP_FLAGS_ALL;
/**
* Creates a new builder.
@@ -2311,11 +2818,28 @@
}
/**
+ * Sets the op flags to query for. The flags specify the type of
+ * op data being queried.
+ *
+ * @param flags The flags which are any combination of
+ * {@link #OP_FLAG_SELF}, {@link #OP_FLAG_TRUSTED_PROXY},
+ * {@link #OP_FLAG_UNTRUSTED_PROXY}, {@link #OP_FLAG_TRUSTED_PROXIED},
+ * {@link #OP_FLAG_UNTRUSTED_PROXIED}. You can use {@link #OP_FLAGS_ALL}
+ * for any flag.
+ * @return This builder.
+ */
+ public @NonNull Builder setFlags(@OpFlags int flags) {
+ Preconditions.checkFlagsArgument(flags, OP_FLAGS_ALL);
+ mFlags = flags;
+ return this;
+ }
+
+ /**
* @return a new {@link HistoricalOpsRequest}.
*/
public @NonNull HistoricalOpsRequest build() {
return new HistoricalOpsRequest(mUid, mPackageName, mOpNames,
- mBeginTimeMillis, mEndTimeMillis);
+ mBeginTimeMillis, mEndTimeMillis, mFlags);
}
}
}
@@ -2521,25 +3045,25 @@
/** @hide */
@TestApi
public void increaseAccessCount(int opCode, int uid, @NonNull String packageName,
- @UidState int uidState, long increment) {
+ @UidState int uidState, @OpFlags int flags, long increment) {
getOrCreateHistoricalUidOps(uid).increaseAccessCount(opCode,
- packageName, uidState, increment);
+ packageName, uidState, flags, increment);
}
/** @hide */
@TestApi
public void increaseRejectCount(int opCode, int uid, @NonNull String packageName,
- @UidState int uidState, long increment) {
+ @UidState int uidState, @OpFlags int flags, long increment) {
getOrCreateHistoricalUidOps(uid).increaseRejectCount(opCode,
- packageName, uidState, increment);
+ packageName, uidState, flags, increment);
}
/** @hide */
@TestApi
public void increaseAccessDuration(int opCode, int uid, @NonNull String packageName,
- @UidState int uidState, long increment) {
+ @UidState int uidState, @OpFlags int flags, long increment) {
getOrCreateHistoricalUidOps(uid).increaseAccessDuration(opCode,
- packageName, uidState, increment);
+ packageName, uidState, flags, increment);
}
/** @hide */
@@ -2834,21 +3358,21 @@
}
private void increaseAccessCount(int opCode, @NonNull String packageName,
- @UidState int uidState, long increment) {
+ @UidState int uidState, @OpFlags int flags, long increment) {
getOrCreateHistoricalPackageOps(packageName).increaseAccessCount(
- opCode, uidState, increment);
+ opCode, uidState, flags, increment);
}
private void increaseRejectCount(int opCode, @NonNull String packageName,
- @UidState int uidState, long increment) {
+ @UidState int uidState, @OpFlags int flags, long increment) {
getOrCreateHistoricalPackageOps(packageName).increaseRejectCount(
- opCode, uidState, increment);
+ opCode, uidState, flags, increment);
}
private void increaseAccessDuration(int opCode, @NonNull String packageName,
- @UidState int uidState, long increment) {
+ @UidState int uidState, @OpFlags int flags, long increment) {
getOrCreateHistoricalPackageOps(packageName).increaseAccessDuration(
- opCode, uidState, increment);
+ opCode, uidState, flags, increment);
}
/**
@@ -3070,16 +3594,19 @@
return true;
}
- private void increaseAccessCount(int opCode, @UidState int uidState, long increment) {
- getOrCreateHistoricalOp(opCode).increaseAccessCount(uidState, increment);
+ private void increaseAccessCount(int opCode, @UidState int uidState,
+ @OpFlags int flags, long increment) {
+ getOrCreateHistoricalOp(opCode).increaseAccessCount(uidState, flags, increment);
}
- private void increaseRejectCount(int opCode, @UidState int uidState, long increment) {
- getOrCreateHistoricalOp(opCode).increaseRejectCount(uidState, increment);
+ private void increaseRejectCount(int opCode, @UidState int uidState,
+ @OpFlags int flags, long increment) {
+ getOrCreateHistoricalOp(opCode).increaseRejectCount(uidState, flags, increment);
}
- private void increaseAccessDuration(int opCode, @UidState int uidState, long increment) {
- getOrCreateHistoricalOp(opCode).increaseAccessDuration(uidState, increment);
+ private void increaseAccessDuration(int opCode, @UidState int uidState,
+ @OpFlags int flags, long increment) {
+ getOrCreateHistoricalOp(opCode).increaseAccessDuration(uidState, flags, increment);
}
/**
@@ -3095,7 +3622,6 @@
* Gets number historical app ops.
*
* @return The number historical app ops.
- *
* @see #getOpAt(int)
*/
public int getOpCount() {
@@ -3109,9 +3635,7 @@
* Gets the historical op at a given index.
*
* @param index The index to lookup.
- *
* @return The op at the given index.
- *
* @see #getOpCount()
*/
public @NonNull HistoricalOp getOpAt(int index) {
@@ -3125,7 +3649,6 @@
* Gets the historical entry for a given op name.
*
* @param opName The op name.
- *
* @return The historical entry for that op name.
*/
public @Nullable HistoricalOp getOp(@NonNull String opName) {
@@ -3219,39 +3742,33 @@
@SystemApi
public static final class HistoricalOp implements Parcelable {
private final int mOp;
- private @Nullable long[] mAccessCount;
- private @Nullable long[] mRejectCount;
- private @Nullable long[] mAccessDuration;
+ private @Nullable LongSparseLongArray mAccessCount;
+ private @Nullable LongSparseLongArray mRejectCount;
+ private @Nullable LongSparseLongArray mAccessDuration;
/** @hide */
public HistoricalOp(int op) {
mOp = op;
- mAccessCount = new long[_NUM_UID_STATE];
- mRejectCount = new long[_NUM_UID_STATE];
- mAccessDuration = new long[_NUM_UID_STATE];
}
private HistoricalOp(@NonNull HistoricalOp other) {
mOp = other.mOp;
if (other.mAccessCount != null) {
- System.arraycopy(other.mAccessCount, 0, getOrCreateAccessCount(),
- 0, other.mAccessCount.length);
+ mAccessCount = other.mAccessCount.clone();
}
if (other.mRejectCount != null) {
- System.arraycopy(other.mRejectCount, 0, getOrCreateRejectCount(),
- 0, other.mRejectCount.length);
+ mRejectCount = other.mRejectCount.clone();
}
if (other.mAccessDuration != null) {
- System.arraycopy(other.mAccessDuration, 0, getOrCreateAccessDuration(),
- 0, other.mAccessDuration.length);
+ mAccessDuration = other.mAccessDuration.clone();
}
}
private HistoricalOp(@NonNull Parcel parcel) {
mOp = parcel.readInt();
- mAccessCount = parcel.createLongArray();
- mRejectCount = parcel.createLongArray();
- mAccessDuration = parcel.createLongArray();
+ mAccessCount = readLongSparseLongArrayFromParcel(parcel);
+ mRejectCount = readLongSparseLongArrayFromParcel(parcel);
+ mAccessDuration = readLongSparseLongArrayFromParcel(parcel);
}
private void filter(double scaleFactor) {
@@ -3266,90 +3783,64 @@
&& !hasData(mAccessDuration);
}
- private boolean hasData(@NonNull long[] array) {
- for (long value : array) {
- if (value != 0) {
- return true;
- }
- }
- return false;
+ private boolean hasData(@NonNull LongSparseLongArray array) {
+ return (array != null && array.size() > 0);
}
private @Nullable HistoricalOp splice(double fractionToRemove) {
- HistoricalOp splice = null;
- if (mAccessCount != null) {
- for (int i = 0; i < _NUM_UID_STATE; i++) {
- final long spliceAccessCount = Math.round(
- mAccessCount[i] * fractionToRemove);
- if (spliceAccessCount > 0) {
- if (splice == null) {
- splice = new HistoricalOp(mOp);
- }
- splice.getOrCreateAccessCount()[i] = spliceAccessCount;
- mAccessCount[i] -= spliceAccessCount;
- }
- }
- }
-
- if (mRejectCount != null) {
- for (int i = 0; i < _NUM_UID_STATE; i++) {
- final long spliceRejectCount = Math.round(
- mRejectCount[i] * fractionToRemove);
-
- if (spliceRejectCount > 0) {
- if (splice == null) {
- splice = new HistoricalOp(mOp);
- }
- splice.getOrCreateRejectCount()[i] = spliceRejectCount;
- mRejectCount[i] -= spliceRejectCount;
- }
- }
- }
-
- if (mAccessDuration != null) {
- for (int i = 0; i < _NUM_UID_STATE; i++) {
- final long spliceAccessDuration = Math.round(
- mAccessDuration[i] * fractionToRemove);
- if (spliceAccessDuration > 0) {
- if (splice == null) {
- splice = new HistoricalOp(mOp);
- }
- splice.getOrCreateAccessDuration()[i] = spliceAccessDuration;
- mAccessDuration[i] -= spliceAccessDuration;
- }
- }
- }
+ final HistoricalOp splice = new HistoricalOp(mOp);
+ splice(mAccessCount, splice::getOrCreateAccessCount, fractionToRemove);
+ splice(mRejectCount, splice::getOrCreateRejectCount, fractionToRemove);
+ splice(mAccessDuration, splice::getOrCreateAccessDuration, fractionToRemove);
return splice;
}
+ private static void splice(@Nullable LongSparseLongArray sourceContainer,
+ @NonNull Supplier<LongSparseLongArray> destContainerProvider,
+ double fractionToRemove) {
+ if (sourceContainer != null) {
+ final int size = sourceContainer.size();
+ for (int i = 0; i < size; i++) {
+ final long key = sourceContainer.keyAt(i);
+ final long value = sourceContainer.valueAt(i);
+ final long removedFraction = Math.round(value * fractionToRemove);
+ if (removedFraction > 0) {
+ destContainerProvider.get().put(key, removedFraction);
+ sourceContainer.put(key, value - removedFraction);
+ }
+ }
+ }
+ }
+
private void merge(@NonNull HistoricalOp other) {
- if (other.mAccessCount != null) {
- for (int i = 0; i < _NUM_UID_STATE; i++) {
- getOrCreateAccessCount()[i] += other.mAccessCount[i];
- }
- }
- if (other.mRejectCount != null) {
- for (int i = 0; i < _NUM_UID_STATE; i++) {
- getOrCreateRejectCount()[i] += other.mRejectCount[i];
- }
- }
- if (other.mAccessDuration != null) {
- for (int i = 0; i < _NUM_UID_STATE; i++) {
- getOrCreateAccessDuration()[i] += other.mAccessDuration[i];
- }
- }
+ merge(this::getOrCreateAccessCount, other.mAccessCount);
+ merge(this::getOrCreateRejectCount, other.mRejectCount);
+ merge(this::getOrCreateAccessDuration, other.mAccessDuration);
}
- private void increaseAccessCount(@UidState int uidState, long increment) {
- getOrCreateAccessCount()[uidState] += increment;
+ private void increaseAccessCount(@UidState int uidState, @OpFlags int flags,
+ long increment) {
+ increaseCount(getOrCreateAccessCount(), uidState, flags, increment);
}
- private void increaseRejectCount(@UidState int uidState, long increment) {
- getOrCreateRejectCount()[uidState] += increment;
+ private void increaseRejectCount(@UidState int uidState, @OpFlags int flags,
+ long increment) {
+ increaseCount(getOrCreateRejectCount(), uidState, flags, increment);
}
- private void increaseAccessDuration(@UidState int uidState, long increment) {
- getOrCreateAccessDuration()[uidState] += increment;
+ private void increaseAccessDuration(@UidState int uidState, @OpFlags int flags,
+ long increment) {
+ increaseCount(getOrCreateAccessDuration(), uidState, flags, increment);
+ }
+
+ private void increaseCount(@NonNull LongSparseLongArray counts,
+ @UidState int uidState, @OpFlags int flags, long increment) {
+ while (flags != 0) {
+ final int flag = 1 << Integer.numberOfTrailingZeros(flags);
+ flags &= ~flag;
+ final long key = makeKey(uidState, flag);
+ counts.put(key, counts.get(key) + increment);
+ }
}
/**
@@ -3369,154 +3860,186 @@
/**
* Gets the number times the op was accessed (performed) in the foreground.
*
+ * @param flags The flags which are any combination of
+ * {@link #OP_FLAG_SELF}, {@link #OP_FLAG_TRUSTED_PROXY},
+ * {@link #OP_FLAG_UNTRUSTED_PROXY}, {@link #OP_FLAG_TRUSTED_PROXIED},
+ * {@link #OP_FLAG_UNTRUSTED_PROXIED}. You can use {@link #OP_FLAGS_ALL}
+ * for any flag.
* @return The times the op was accessed in the foreground.
*
- * @see #getBackgroundAccessCount()
- * @see #getAccessCount(int)
+ * @see #getBackgroundAccessCount(int)
+ * @see #getAccessCount(int, int, int)
*/
- public long getForegroundAccessCount() {
- if (mAccessCount == null) {
- return 0;
- }
- return sum(mAccessCount, UID_STATE_PERSISTENT, UID_STATE_LAST_NON_RESTRICTED + 1);
+ public long getForegroundAccessCount(@OpFlags int flags) {
+ return sumForFlagsInStates(mAccessCount, MAX_PRIORITY_UID_STATE,
+ resolveFirstUnrestrictedUidState(mOp), flags);
}
/**
* Gets the number times the op was accessed (performed) in the background.
*
+ * @param flags The flags which are any combination of
+ * {@link #OP_FLAG_SELF}, {@link #OP_FLAG_TRUSTED_PROXY},
+ * {@link #OP_FLAG_UNTRUSTED_PROXY}, {@link #OP_FLAG_TRUSTED_PROXIED},
+ * {@link #OP_FLAG_UNTRUSTED_PROXIED}. You can use {@link #OP_FLAGS_ALL}
+ * for any flag.
* @return The times the op was accessed in the background.
*
- * @see #getForegroundAccessCount()
- * @see #getAccessCount(int)
+ * @see #getForegroundAccessCount(int)
+ * @see #getAccessCount(int, int, int)
*/
- public long getBackgroundAccessCount() {
- if (mAccessCount == null) {
- return 0;
- }
- return sum(mAccessCount, UID_STATE_LAST_NON_RESTRICTED + 1, _NUM_UID_STATE);
+ public long getBackgroundAccessCount(@OpFlags int flags) {
+ return sumForFlagsInStates(mAccessCount, resolveLastRestrictedUidState(mOp),
+ MIN_PRIORITY_UID_STATE, flags);
}
/**
- * Gets the number times the op was accessed (performed) for a given uid state.
+ * Gets the number times the op was accessed (performed) for a
+ * range of uid states.
*
- * @param uidState The UID state for which to query. Could be one of
+ * @param fromUidState The UID state from which to query. Could be one of
* {@link #UID_STATE_PERSISTENT}, {@link #UID_STATE_TOP},
* {@link #UID_STATE_FOREGROUND_SERVICE_LOCATION},
* {@link #UID_STATE_FOREGROUND_SERVICE}, {@link #UID_STATE_FOREGROUND},
* {@link #UID_STATE_BACKGROUND}, {@link #UID_STATE_CACHED}.
+ * @param toUidState The UID state to which to query.
+ * @param flags The flags which are any combination of
+ * {@link #OP_FLAG_SELF}, {@link #OP_FLAG_TRUSTED_PROXY},
+ * {@link #OP_FLAG_UNTRUSTED_PROXY}, {@link #OP_FLAG_TRUSTED_PROXIED},
+ * {@link #OP_FLAG_UNTRUSTED_PROXIED}. You can use {@link #OP_FLAGS_ALL}
+ * for any flag.
*
* @return The times the op was accessed for the given UID state.
*
- * @see #getForegroundAccessCount()
- * @see #getBackgroundAccessCount()
+ * @see #getForegroundAccessCount(int)
+ * @see #getBackgroundAccessCount(int)
*/
- public long getAccessCount(@UidState int uidState) {
- if (mAccessCount == null) {
- return 0;
- }
- return mAccessCount[uidState];
+ public long getAccessCount(@UidState int fromUidState, @UidState int toUidState,
+ @OpFlags int flags) {
+ return sumForFlagsInStates(mAccessCount, fromUidState, toUidState, flags);
}
/**
* Gets the number times the op was rejected in the foreground.
*
+ * @param flags The flags which are any combination of
+ * {@link #OP_FLAG_SELF}, {@link #OP_FLAG_TRUSTED_PROXY},
+ * {@link #OP_FLAG_UNTRUSTED_PROXY}, {@link #OP_FLAG_TRUSTED_PROXIED},
+ * {@link #OP_FLAG_UNTRUSTED_PROXIED}. You can use {@link #OP_FLAGS_ALL}
+ * for any flag.
* @return The times the op was rejected in the foreground.
*
- * @see #getBackgroundRejectCount()
- * @see #getRejectCount(int)
+ * @see #getBackgroundRejectCount(int)
+ * @see #getRejectCount(int, int, int)
*/
- public long getForegroundRejectCount() {
- if (mRejectCount == null) {
- return 0;
- }
- return sum(mRejectCount, UID_STATE_PERSISTENT, UID_STATE_LAST_NON_RESTRICTED + 1);
+ public long getForegroundRejectCount(@OpFlags int flags) {
+ return sumForFlagsInStates(mRejectCount, MAX_PRIORITY_UID_STATE,
+ resolveFirstUnrestrictedUidState(mOp), flags);
}
/**
* Gets the number times the op was rejected in the background.
*
+ * @param flags The flags which are any combination of
+ * {@link #OP_FLAG_SELF}, {@link #OP_FLAG_TRUSTED_PROXY},
+ * {@link #OP_FLAG_UNTRUSTED_PROXY}, {@link #OP_FLAG_TRUSTED_PROXIED},
+ * {@link #OP_FLAG_UNTRUSTED_PROXIED}. You can use {@link #OP_FLAGS_ALL}
+ * for any flag.
* @return The times the op was rejected in the background.
*
- * @see #getForegroundRejectCount()
- * @see #getRejectCount(int)
+ * @see #getForegroundRejectCount(int)
+ * @see #getRejectCount(int, int, int)
*/
- public long getBackgroundRejectCount() {
- if (mRejectCount == null) {
- return 0;
- }
- return sum(mRejectCount, UID_STATE_LAST_NON_RESTRICTED + 1, _NUM_UID_STATE);
+ public long getBackgroundRejectCount(@OpFlags int flags) {
+ return sumForFlagsInStates(mRejectCount, resolveLastRestrictedUidState(mOp),
+ MIN_PRIORITY_UID_STATE, flags);
}
/**
- * Gets the number times the op was rejected for a given uid state.
+ * Gets the number times the op was rejected for a given range of UID states.
*
- * @param uidState The UID state for which to query. Could be one of
+ * @param fromUidState The UID state from which to query. Could be one of
* {@link #UID_STATE_PERSISTENT}, {@link #UID_STATE_TOP},
* {@link #UID_STATE_FOREGROUND_SERVICE_LOCATION},
* {@link #UID_STATE_FOREGROUND_SERVICE}, {@link #UID_STATE_FOREGROUND},
* {@link #UID_STATE_BACKGROUND}, {@link #UID_STATE_CACHED}.
+ * @param toUidState The UID state to which to query.
+ * @param flags The flags which are any combination of
+ * {@link #OP_FLAG_SELF}, {@link #OP_FLAG_TRUSTED_PROXY},
+ * {@link #OP_FLAG_UNTRUSTED_PROXY}, {@link #OP_FLAG_TRUSTED_PROXIED},
+ * {@link #OP_FLAG_UNTRUSTED_PROXIED}. You can use {@link #OP_FLAGS_ALL}
+ * for any flag.
*
* @return The times the op was rejected for the given UID state.
*
- * @see #getForegroundRejectCount()
- * @see #getBackgroundRejectCount()
+ * @see #getForegroundRejectCount(int)
+ * @see #getBackgroundRejectCount(int)
*/
- public long getRejectCount(@UidState int uidState) {
- if (mRejectCount == null) {
- return 0;
- }
- return mRejectCount[uidState];
+ public long getRejectCount(@UidState int fromUidState, @UidState int toUidState,
+ @OpFlags int flags) {
+ return sumForFlagsInStates(mRejectCount, fromUidState, toUidState, flags);
}
/**
* Gets the total duration the app op was accessed (performed) in the foreground.
*
+ * @param flags The flags which are any combination of
+ * {@link #OP_FLAG_SELF}, {@link #OP_FLAG_TRUSTED_PROXY},
+ * {@link #OP_FLAG_UNTRUSTED_PROXY}, {@link #OP_FLAG_TRUSTED_PROXIED},
+ * {@link #OP_FLAG_UNTRUSTED_PROXIED}. You can use {@link #OP_FLAGS_ALL}
+ * for any flag.
* @return The total duration the app op was accessed in the foreground.
*
- * @see #getBackgroundAccessDuration()
- * @see #getAccessDuration(int)
+ * @see #getBackgroundAccessDuration(int)
+ * @see #getAccessDuration(int, int, int)
*/
- public long getForegroundAccessDuration() {
- if (mAccessDuration == null) {
- return 0;
- }
- return sum(mAccessDuration, UID_STATE_PERSISTENT, UID_STATE_LAST_NON_RESTRICTED + 1);
+ public long getForegroundAccessDuration(@OpFlags int flags) {
+ return sumForFlagsInStates(mAccessDuration, MAX_PRIORITY_UID_STATE,
+ resolveFirstUnrestrictedUidState(mOp), flags);
}
/**
* Gets the total duration the app op was accessed (performed) in the background.
*
+ * @param flags The flags which are any combination of
+ * {@link #OP_FLAG_SELF}, {@link #OP_FLAG_TRUSTED_PROXY},
+ * {@link #OP_FLAG_UNTRUSTED_PROXY}, {@link #OP_FLAG_TRUSTED_PROXIED},
+ * {@link #OP_FLAG_UNTRUSTED_PROXIED}. You can use {@link #OP_FLAGS_ALL}
+ * for any flag.
* @return The total duration the app op was accessed in the background.
*
- * @see #getForegroundAccessDuration()
- * @see #getAccessDuration(int)
+ * @see #getForegroundAccessDuration(int)
+ * @see #getAccessDuration(int, int, int)
*/
- public long getBackgroundAccessDuration() {
- if (mAccessDuration == null) {
- return 0;
- }
- return sum(mAccessDuration, UID_STATE_LAST_NON_RESTRICTED + 1, _NUM_UID_STATE);
+ public long getBackgroundAccessDuration(@OpFlags int flags) {
+ return sumForFlagsInStates(mAccessDuration, resolveLastRestrictedUidState(mOp),
+ MIN_PRIORITY_UID_STATE, flags);
}
/**
- * Gets the total duration the app op was accessed (performed) for a given UID state.
+ * Gets the total duration the app op was accessed (performed) for a given
+ * range of UID states.
*
- * @param uidState The UID state for which to query. Could be one of
+ * @param fromUidState The UID state from which to query. Could be one of
* {@link #UID_STATE_PERSISTENT}, {@link #UID_STATE_TOP},
* {@link #UID_STATE_FOREGROUND_SERVICE_LOCATION},
* {@link #UID_STATE_FOREGROUND_SERVICE}, {@link #UID_STATE_FOREGROUND},
* {@link #UID_STATE_BACKGROUND}, {@link #UID_STATE_CACHED}.
+ * @param toUidState The UID state from which to query.
+ * @param flags The flags which are any combination of
+ * {@link #OP_FLAG_SELF}, {@link #OP_FLAG_TRUSTED_PROXY},
+ * {@link #OP_FLAG_UNTRUSTED_PROXY}, {@link #OP_FLAG_TRUSTED_PROXIED},
+ * {@link #OP_FLAG_UNTRUSTED_PROXIED}. You can use {@link #OP_FLAGS_ALL}
+ * for any flag.
*
* @return The total duration the app op was accessed for the given UID state.
*
- * @see #getForegroundAccessDuration()
- * @see #getBackgroundAccessDuration()
+ * @see #getForegroundAccessDuration(int)
+ * @see #getBackgroundAccessDuration(int)
*/
- public long getAccessDuration(@UidState int uidState) {
- if (mAccessDuration == null) {
- return 0;
- }
- return mAccessDuration[uidState];
+ public long getAccessDuration(@UidState int fromUidState, @UidState int toUidState,
+ @OpFlags int flags) {
+ return sumForFlagsInStates(mAccessDuration, fromUidState, toUidState, flags);
}
@Override
@@ -3527,80 +4050,11 @@
@Override
public void writeToParcel(Parcel parcel, int flags) {
parcel.writeInt(mOp);
- parcel.writeLongArray(mAccessCount);
- parcel.writeLongArray(mRejectCount);
- parcel.writeLongArray(mAccessDuration);
+ writeLongSparseLongArrayToParcel(mAccessCount, parcel);
+ writeLongSparseLongArrayToParcel(mRejectCount, parcel);
+ writeLongSparseLongArrayToParcel(mAccessDuration, parcel);
}
- private void accept(@NonNull HistoricalOpsVisitor visitor) {
- visitor.visitHistoricalOp(this);
- }
-
- private @NonNull long[] getOrCreateAccessCount() {
- if (mAccessCount == null) {
- mAccessCount = new long[_NUM_UID_STATE];
- }
- return mAccessCount;
- }
-
- private @NonNull long[] getOrCreateRejectCount() {
- if (mRejectCount == null) {
- mRejectCount = new long[_NUM_UID_STATE];
- }
- return mRejectCount;
- }
-
- private @NonNull long[] getOrCreateAccessDuration() {
- if (mAccessDuration == null) {
- mAccessDuration = new long[_NUM_UID_STATE];
- }
- return mAccessDuration;
- }
-
- /**
- *
- * Computes the sum given the start and end index.
- *
- * @param counts The data array.
- * @param start The start index (inclusive)
- * @param end The end index (exclusive)
- * @return The sum.
- */
- private static long sum(@NonNull long[] counts, int start, int end) {
- long totalCount = 0;
- for (int i = start; i < end; i++) {
- totalCount += counts[i];
- }
- return totalCount;
- }
-
- /**
- * Multiplies the entries in the array with the passed in scale factor and
- * rounds the result at up 0.5 boundary.
- *
- * @param data The data to scale.
- * @param scaleFactor The scale factor.
- */
- private static void scale(@NonNull long[] data, double scaleFactor) {
- if (data != null) {
- for (int i = 0; i < _NUM_UID_STATE; i++) {
- data[i] = (long) HistoricalOps.round((double) data[i] * scaleFactor);
- }
- }
- }
-
- public static final @android.annotation.NonNull Creator<HistoricalOp> CREATOR = new Creator<HistoricalOp>() {
- @Override
- public @NonNull HistoricalOp createFromParcel(@NonNull Parcel source) {
- return new HistoricalOp(source);
- }
-
- @Override
- public @NonNull HistoricalOp[] newArray(int size) {
- return new HistoricalOp[size];
- }
- };
-
@Override
public boolean equals(Object obj) {
if (this == obj) {
@@ -3613,23 +4067,201 @@
if (mOp != other.mOp) {
return false;
}
- if (!Arrays.equals(mAccessCount, other.mAccessCount)) {
+ if (!Objects.equals(mAccessCount, other.mAccessCount)) {
return false;
}
- if (!Arrays.equals(mRejectCount, other.mRejectCount)) {
+ if (!Objects.equals(mRejectCount, other.mRejectCount)) {
return false;
}
- return Arrays.equals(mAccessDuration, other.mAccessDuration);
+ return Objects.equals(mAccessDuration, other.mAccessDuration);
}
@Override
public int hashCode() {
int result = mOp;
- result = 31 * result + Arrays.hashCode(mAccessCount);
- result = 31 * result + Arrays.hashCode(mRejectCount);
- result = 31 * result + Arrays.hashCode(mAccessDuration);
+ result = 31 * result + Objects.hashCode(mAccessCount);
+ result = 31 * result + Objects.hashCode(mRejectCount);
+ result = 31 * result + Objects.hashCode(mAccessDuration);
return result;
}
+
+ private void accept(@NonNull HistoricalOpsVisitor visitor) {
+ visitor.visitHistoricalOp(this);
+ }
+
+ private @NonNull LongSparseLongArray getOrCreateAccessCount() {
+ if (mAccessCount == null) {
+ mAccessCount = new LongSparseLongArray();
+ }
+ return mAccessCount;
+ }
+
+ private @NonNull LongSparseLongArray getOrCreateRejectCount() {
+ if (mRejectCount == null) {
+ mRejectCount = new LongSparseLongArray();
+ }
+ return mRejectCount;
+ }
+
+ private @NonNull LongSparseLongArray getOrCreateAccessDuration() {
+ if (mAccessDuration == null) {
+ mAccessDuration = new LongSparseLongArray();
+ }
+ return mAccessDuration;
+ }
+
+ /**
+ * Multiplies the entries in the array with the passed in scale factor and
+ * rounds the result at up 0.5 boundary.
+ *
+ * @param data The data to scale.
+ * @param scaleFactor The scale factor.
+ */
+ private static void scale(@NonNull LongSparseLongArray data, double scaleFactor) {
+ if (data != null) {
+ final int size = data.size();
+ for (int i = 0; i < size; i++) {
+ data.put(data.keyAt(i), (long) HistoricalOps.round(
+ (double) data.valueAt(i) * scaleFactor));
+ }
+ }
+ }
+
+ /**
+ * Merges two arrays while lazily acquiring the destination.
+ *
+ * @param thisSupplier The destination supplier.
+ * @param other The array to merge in.
+ */
+ private static void merge(@NonNull Supplier<LongSparseLongArray> thisSupplier,
+ @Nullable LongSparseLongArray other) {
+ if (other != null) {
+ final int otherSize = other.size();
+ for (int i = 0; i < otherSize; i++) {
+ final LongSparseLongArray that = thisSupplier.get();
+ final long otherKey = other.keyAt(i);
+ final long otherValue = other.valueAt(i);
+ that.put(otherKey, that.get(otherKey) + otherValue);
+ }
+ }
+ }
+
+ /** @hide */
+ public @Nullable LongSparseArray<Object> collectKeys() {
+ LongSparseArray<Object> result = AppOpsManager.collectKeys(mAccessCount,
+ null /*result*/);
+ result = AppOpsManager.collectKeys(mRejectCount, result);
+ result = AppOpsManager.collectKeys(mAccessDuration, result);
+ return result;
+ }
+
+ public static final @android.annotation.NonNull Creator<HistoricalOp> CREATOR =
+ new Creator<HistoricalOp>() {
+ @Override
+ public @NonNull HistoricalOp createFromParcel(@NonNull Parcel source) {
+ return new HistoricalOp(source);
+ }
+
+ @Override
+ public @NonNull HistoricalOp[] newArray(int size) {
+ return new HistoricalOp[size];
+ }
+ };
+ }
+
+ /**
+ * Computes the sum of the counts for the given flags in between the begin and
+ * end UID states.
+ *
+ * @param counts The data array.
+ * @param beginUidState The beginning UID state (exclusive).
+ * @param endUidState The end UID state.
+ * @param flags The UID flags.
+ * @return The sum.
+ */
+ private static long sumForFlagsInStates(@Nullable LongSparseLongArray counts,
+ @UidState int beginUidState, @UidState int endUidState, @OpFlags int flags) {
+ if (counts == null) {
+ return 0;
+ }
+ long sum = 0;
+ while (flags != 0) {
+ final int flag = 1 << Integer.numberOfTrailingZeros(flags);
+ flags &= ~flag;
+ for (int uidState : UID_STATES) {
+ if (uidState < beginUidState || uidState > endUidState) {
+ continue;
+ }
+ final long key = makeKey(uidState, flag);
+ sum += counts.get(key);
+ }
+ }
+ return sum;
+ }
+
+ /**
+ * Finds the first non-negative value for the given flags in between the begin and
+ * end UID states.
+ *
+ * @param counts The data array.
+ * @param flags The UID flags.
+ * @param beginUidState The beginning UID state (exclusive).
+ * @param endUidState The end UID state.
+ * @return The non-negative value or -1.
+ */
+ private static long findFirstNonNegativeForFlagsInStates(@Nullable LongSparseLongArray counts,
+ @OpFlags int flags, @UidState int beginUidState, @UidState int endUidState) {
+ if (counts == null) {
+ return -1;
+ }
+ while (flags != 0) {
+ final int flag = 1 << Integer.numberOfTrailingZeros(flags);
+ flags &= ~flag;
+ for (int uidState : UID_STATES) {
+ if (uidState < beginUidState || uidState > endUidState) {
+ continue;
+ }
+ final long key = makeKey(uidState, flag);
+ final long value = counts.get(key);
+ if (value >= 0) {
+ return value;
+ }
+ }
+ }
+ return -1;
+ }
+
+ /**
+ * Finds the first non-null value for the given flags in between the begin and
+ * end UID states.
+ *
+ * @param counts The data array.
+ * @param flags The UID flags.
+ * @param beginUidState The beginning UID state (exclusive).
+ * @param endUidState The end UID state.
+ * @return The non-negative value or -1.
+ */
+ private static @Nullable String findFirstNonNullForFlagsInStates(
+ @Nullable LongSparseArray<String> counts, @OpFlags int flags,
+ @UidState int beginUidState, @UidState int endUidState) {
+ if (counts == null) {
+ return null;
+ }
+ while (flags != 0) {
+ final int flag = 1 << Integer.numberOfTrailingZeros(flags);
+ flags &= ~flag;
+ for (int uidState : UID_STATES) {
+ if (uidState < beginUidState || uidState > endUidState) {
+ continue;
+ }
+ final long key = makeKey(uidState, flag);
+ final String value = counts.get(key);
+ if (value != null) {
+ return value;
+ }
+ }
+ }
+ return null;
}
/**
@@ -3800,7 +4432,7 @@
Preconditions.checkNotNull(callback, "callback cannot be null");
try {
mService.getHistoricalOps(request.mUid, request.mPackageName, request.mOpNames,
- request.mBeginTimeMillis, request.mEndTimeMillis,
+ request.mBeginTimeMillis, request.mEndTimeMillis, request.mFlags,
new RemoteCallback((result) -> {
final HistoricalOps ops = result.getParcelable(KEY_HISTORICAL_OPS);
final long identity = Binder.clearCallingIdentity();
@@ -3840,7 +4472,7 @@
try {
mService.getHistoricalOpsFromDiskRaw(request.mUid, request.mPackageName,
request.mOpNames, request.mBeginTimeMillis, request.mEndTimeMillis,
- new RemoteCallback((result) -> {
+ request.mFlags, new RemoteCallback((result) -> {
final HistoricalOps ops = result.getParcelable(KEY_HISTORICAL_OPS);
final long identity = Binder.clearCallingIdentity();
try {
@@ -4310,7 +4942,20 @@
* Like {@link #checkOp} but returns the <em>raw</em> mode associated with the op.
* Does not throw a security exception, does not translate {@link #MODE_FOREGROUND}.
*/
- public int unsafeCheckOpRaw(String op, int uid, String packageName) {
+ public int unsafeCheckOpRaw(@NonNull String op, int uid, String packageName) {
+ try {
+ return mService.checkOperationRaw(strOpToOp(op), uid, packageName);
+ } catch (RemoteException e) {
+ throw e.rethrowFromSystemServer();
+ }
+ }
+
+ /**
+ * Like {@link #unsafeCheckOpNoThrow(String, int, String)} but returns the <em>raw</em>
+ * mode associated with the op. Does not throw a security exception, does not translate
+ * {@link #MODE_FOREGROUND}.
+ */
+ public int unsafeCheckOpRawNoThrow(@NonNull String op, int uid, @NonNull String packageName) {
try {
return mService.checkOperationRaw(strOpToOp(op), uid, packageName);
} catch (RemoteException e) {
@@ -4899,16 +5544,110 @@
}
/**
- * @hide
+ * Computes the max for the given flags in between the begin and
+ * end UID states.
+ *
+ * @param counts The data array.
+ * @param flags The UID flags.
+ * @param beginUidState The beginning UID state (exclusive).
+ * @param endUidState The end UID state.
+ * @return The sum.
*/
- public static long maxTime(long[] times, int start, int end) {
- long time = 0;
- for (int i = start; i < end; i++) {
- if (times[i] > time) {
- time = times[i];
+ private static long maxForFlagsInStates(@Nullable LongSparseLongArray counts,
+ @UidState int beginUidState, @UidState int endUidState,
+ @OpFlags int flags) {
+ if (counts == null) {
+ return 0;
+ }
+ long max = 0;
+ while (flags != 0) {
+ final int flag = 1 << Integer.numberOfTrailingZeros(flags);
+ flags &= ~flag;
+ for (int uidState : UID_STATES) {
+ if (uidState < beginUidState || uidState > endUidState) {
+ continue;
+ }
+ final long key = makeKey(uidState, flag);
+ max = Math.max(max, counts.get(key));
}
}
- return time;
+ return max;
+ }
+
+
+ private static void writeLongSparseLongArrayToParcel(
+ @Nullable LongSparseLongArray array, @NonNull Parcel parcel) {
+ if (array != null) {
+ final int size = array.size();
+ parcel.writeInt(size);
+ for (int i = 0; i < size; i++) {
+ parcel.writeLong(array.keyAt(i));
+ parcel.writeLong(array.valueAt(i));
+ }
+ } else {
+ parcel.writeInt(-1);
+ }
+ }
+
+ private static @Nullable LongSparseLongArray readLongSparseLongArrayFromParcel(
+ @NonNull Parcel parcel) {
+ final int size = parcel.readInt();
+ if (size < 0) {
+ return null;
+ }
+ final LongSparseLongArray array = new LongSparseLongArray(size);
+ for (int i = 0; i < size; i++) {
+ array.append(parcel.readLong(), parcel.readLong());
+ }
+ return array;
+ }
+
+ private static void writeLongSparseStringArrayToParcel(
+ @Nullable LongSparseArray<String> array, @NonNull Parcel parcel) {
+ if (array != null) {
+ final int size = array.size();
+ parcel.writeInt(size);
+ for (int i = 0; i < size; i++) {
+ parcel.writeLong(array.keyAt(i));
+ parcel.writeString(array.valueAt(i));
+ }
+ } else {
+ parcel.writeInt(-1);
+ }
+ }
+
+ private static @Nullable LongSparseArray<String> readLongSparseStringArrayFromParcel(
+ @NonNull Parcel parcel) {
+ final int size = parcel.readInt();
+ if (size < 0) {
+ return null;
+ }
+ final LongSparseArray<String> array = new LongSparseArray<>(size);
+ for (int i = 0; i < size; i++) {
+ array.append(parcel.readLong(), parcel.readString());
+ }
+ return array;
+ }
+
+ /**
+ * Collects the keys from an array to the result creating the result if needed.
+ *
+ * @param array The array whose keys to collect.
+ * @param result The optional result store collected keys.
+ * @return The result collected keys array.
+ */
+ private static LongSparseArray<Object> collectKeys(@Nullable LongSparseLongArray array,
+ @Nullable LongSparseArray<Object> result) {
+ if (array != null) {
+ if (result == null) {
+ result = new LongSparseArray<>();
+ }
+ final int accessSize = array.size();
+ for (int i = 0; i < accessSize; i++) {
+ result.put(array.keyAt(i), null);
+ }
+ }
+ return result;
}
/** @hide */
diff --git a/core/java/android/app/TEST_MAPPING b/core/java/android/app/TEST_MAPPING
index 65859c7..ad614b1 100644
--- a/core/java/android/app/TEST_MAPPING
+++ b/core/java/android/app/TEST_MAPPING
@@ -1,18 +1,37 @@
{
- "imports": [
- {
- "path": "frameworks/base/services/core/java/com/android/server/am"
- },
- {
- "path": "frameworks/base/services/core/java/com/android/server/wm"
- }
- ],
- "presubmit": [
- {
- "name": "CtsFragmentTestCases"
- },
- {
- "name": "CtsFragmentTestCasesSdk26"
- }
- ]
+ "imports": [
+ {
+ "path": "frameworks/base/services/core/java/com/android/server/am"
+ },
+ {
+ "path": "frameworks/base/services/core/java/com/android/server/wm"
+ }
+ ],
+ "presubmit": [
+ {
+ "name": "CtsFragmentTestCases"
+ },
+ {
+ "name": "CtsFragmentTestCasesSdk26"
+ },
+ {
+ "file_patterns": ["(/|^)AppOpsManager.java"],
+ "name": "CtsAppOpsTestCases"
+ },
+ {
+ "file_patterns": ["(/|^)AppOpsManager.java"],
+ "name": "FrameworksServicesTests",
+ "options": [
+ {
+ "include-filter": "com.android.server.appop.AppOpsUpgradeTest"
+ },
+ {
+ "include-filter": "com.android.server.appop.AppOpsServiceTest"
+ },
+ {
+ "include-filter": "com.android.server.appop.AppOpsActiveWatcherTest"
+ }
+ ]
+ }
+ ]
}
diff --git a/core/java/android/app/admin/DevicePolicyManager.java b/core/java/android/app/admin/DevicePolicyManager.java
index d593ad1..efbd098 100644
--- a/core/java/android/app/admin/DevicePolicyManager.java
+++ b/core/java/android/app/admin/DevicePolicyManager.java
@@ -3153,7 +3153,7 @@
* {@link #PASSWORD_QUALITY_ALPHANUMERIC} with {@link #setPasswordQuality}.
* <p>
* On devices not supporting {@link PackageManager#FEATURE_SECURE_LOCK_SCREEN} feature, the
- * password is always treated as empty.
+ * password history length is always 0.
* <p>
* The calling device admin must have requested
* {@link DeviceAdminInfo#USES_POLICY_LIMIT_PASSWORD} to be able to call this method; if it has
@@ -3191,6 +3191,9 @@
* <p>
* To disable password expiration, a value of 0 may be used for timeout.
* <p>
+ * On devices not supporting {@link PackageManager#FEATURE_SECURE_LOCK_SCREEN} feature, the
+ * password expiration is always disabled.
+ * <p>
* The calling device admin must have requested
* {@link DeviceAdminInfo#USES_POLICY_EXPIRE_PASSWORD} to be able to call this method; if it has
* not, a security exception will be thrown.
@@ -3230,6 +3233,9 @@
* returned by {@link #getParentProfileInstance(ComponentName)} in order to retrieve
* restrictions on the parent profile.
*
+ * <p>On devices not supporting {@link PackageManager#FEATURE_SECURE_LOCK_SCREEN} feature, the
+ * password expiration is always disabled and this method always returns 0.
+ *
* @param admin The name of the admin component to check, or {@code null} to aggregate all admins.
* @return The timeout for the given admin or the minimum of all timeouts
*/
@@ -3255,6 +3261,9 @@
* returned by {@link #getParentProfileInstance(ComponentName)} in order to retrieve
* the password expiration for the parent profile.
*
+ * <p>On devices not supporting {@link PackageManager#FEATURE_SECURE_LOCK_SCREEN} feature, the
+ * password expiration is always disabled and this method always returns 0.
+ *
* @param admin The name of the admin component to check, or {@code null} to aggregate all admins.
* @return The password expiration time, in milliseconds since epoch.
*/
@@ -3279,6 +3288,9 @@
* returned by {@link #getParentProfileInstance(ComponentName)} in order to retrieve
* restrictions on the parent profile.
*
+ * <p>On devices not supporting {@link PackageManager#FEATURE_SECURE_LOCK_SCREEN} feature, the
+ * password history length is always 0.
+ *
* @param admin The name of the admin component to check, or {@code null} to aggregate
* all admins.
* @return The length of the password history
@@ -3306,7 +3318,7 @@
* Return the maximum password length that the device supports for a
* particular password quality.
* <p>On devices not supporting {@link PackageManager#FEATURE_SECURE_LOCK_SCREEN} feature, the
- * password is always empty.
+ * password is always empty and this method always returns 0.
* @param quality The quality being interrogated.
* @return Returns the maximum length that the user can enter.
*/
@@ -3362,7 +3374,7 @@
* #getParentProfileInstance}.
*
* <p>On devices not supporting {@link PackageManager#FEATURE_SECURE_LOCK_SCREEN} feature, the
- * password is always treated as empty.
+ * password is always empty and this method returns {@link #PASSWORD_COMPLEXITY_NONE}.
*
* @throws IllegalStateException if the user is not unlocked.
* @throws SecurityException if the calling application does not have the permission
@@ -3437,6 +3449,8 @@
* <p>
* The calling device admin must have requested {@link DeviceAdminInfo#USES_POLICY_WATCH_LOGIN}
* to be able to call this method; if it has not, a security exception will be thrown.
+ * <p>On devices not supporting {@link PackageManager#FEATURE_SECURE_LOCK_SCREEN} feature, the
+ * password is always empty and this method always returns 0.
*
* @return The number of times user has entered an incorrect password since the last correct
* password entry.
@@ -3503,6 +3517,8 @@
* This method can be called on the {@link DevicePolicyManager} instance returned by
* {@link #getParentProfileInstance(ComponentName)} in order to set a value on the parent
* profile.
+ * <p>On devices not supporting {@link PackageManager#FEATURE_SECURE_LOCK_SCREEN} feature, the
+ * password is always empty and this method has no effect - i.e. the policy is not set.
*
* @param admin Which {@link DeviceAdminReceiver} this request is associated with.
* @param num The number of failed password attempts at which point the device or profile will
@@ -3532,6 +3548,10 @@
* returned by {@link #getParentProfileInstance(ComponentName)} in order to retrieve
* the value for the parent profile.
*
+ * <p>On devices not supporting {@link PackageManager#FEATURE_SECURE_LOCK_SCREEN} feature, the
+ * password is always empty and this method returns a default value (0) indicating that the
+ * policy is not set.
+ *
* @param admin The name of the admin component to check, or {@code null} to aggregate
* all admins.
*/
@@ -3619,6 +3639,8 @@
* {@link android.os.Build.VERSION_CODES#N} and later for managed profiles, or for device admins
* that are not device owner or profile owner. Once set, the password cannot be changed to null
* or empty except by these admins.</em>
+ * <p>On devices not supporting {@link PackageManager#FEATURE_SECURE_LOCK_SCREEN} feature, this
+ * methods does nothing.
* <p>
* The calling device admin must have requested
* {@link DeviceAdminInfo#USES_POLICY_RESET_PASSWORD} to be able to call this method; if it has
@@ -3669,6 +3691,8 @@
* will be stored on your server and who will need access to them. Tokens may be the subject of
* legal access requests.
* </em>
+ * <p>On devices not supporting {@link PackageManager#FEATURE_SECURE_LOCK_SCREEN} feature, the
+ * reset token is not set and this method returns false.
*
* @param admin Which {@link DeviceAdminReceiver} this request is associated with.
* @param token a secure token a least 32-byte long, which must be generated by a
@@ -3693,6 +3717,10 @@
/**
* Called by a profile or device owner to revoke the current password reset token.
*
+ * <p>On devices not supporting {@link PackageManager#FEATURE_SECURE_LOCK_SCREEN} feature, this
+ * method has no effect - the reset token should not have been set in the first place - and
+ * false is returned.
+ *
* @param admin Which {@link DeviceAdminReceiver} this request is associated with.
* @return true if the operation is successful, false otherwise.
* @throws SecurityException if admin is not a device or profile owner.
@@ -3713,6 +3741,9 @@
/**
* Called by a profile or device owner to check if the current reset password token is active.
*
+ * <p>On devices not supporting {@link PackageManager#FEATURE_SECURE_LOCK_SCREEN} feature,
+ * false is always returned.
+ *
* @param admin Which {@link DeviceAdminReceiver} this request is associated with.
* @return true if the token is active, false otherwise.
* @throws SecurityException if admin is not a device or profile owner.
@@ -3748,6 +3779,8 @@
* <p>
* Calling with a {@code null} or empty password will clear any existing PIN, pattern or
* password if the current password constraints allow it.
+ * <p>On devices not supporting {@link PackageManager#FEATURE_SECURE_LOCK_SCREEN} feature,
+ * calling this methods has no effect - the password is always empty - and false is returned.
*
* @param admin Which {@link DeviceAdminReceiver} this request is associated with.
* @param password The new password for the user. {@code null} or empty clears the password.
@@ -3855,6 +3888,9 @@
* {@link #getParentProfileInstance(ComponentName)} in order to set restrictions on the parent
* profile.
*
+ * <p>On devices not supporting {@link PackageManager#FEATURE_SECURE_LOCK_SCREEN} feature,
+ * calling this methods has no effect - i.e. the timeout is not set.
+ *
* @param admin Which {@link DeviceAdminReceiver} this request is associated with.
* @param timeoutMs The new timeout in milliseconds, after which the user will have to unlock
* with strong authentication method. A value of 0 means the admin is not participating
@@ -3887,6 +3923,9 @@
* returned by {@link #getParentProfileInstance(ComponentName)} in order to retrieve
* restrictions on the parent profile.
*
+ * <p>On devices not supporting {@link PackageManager#FEATURE_SECURE_LOCK_SCREEN} feature,
+ * 0 is returned to indicate that no timeout is configured.
+ *
* @param admin The name of the admin component to check, or {@code null} to aggregate
* across all participating admins.
* @return The timeout in milliseconds or 0 if not configured for the provided admin.
@@ -6617,6 +6656,9 @@
* This method can be called on the {@link DevicePolicyManager} instance returned by
* {@link #getParentProfileInstance(ComponentName)} in order to set the configuration for
* the parent profile.
+ * <p>
+ * On devices not supporting {@link PackageManager#FEATURE_SECURE_LOCK_SCREEN} feature, calling
+ * this method has no effect - no trust agent configuration will be set.
*
* @param admin Which {@link DeviceAdminReceiver} this request is associated with.
* @param target Component name of the agent to be configured.
@@ -6646,6 +6688,9 @@
* This method can be called on the {@link DevicePolicyManager} instance returned by
* {@link #getParentProfileInstance(ComponentName)} in order to retrieve the configuration set
* on the parent profile.
+ * <p>
+ * On devices not supporting {@link PackageManager#FEATURE_SECURE_LOCK_SCREEN} feature, null is
+ * always returned.
*
* @param admin Which {@link DeviceAdminReceiver} this request is associated with. If null,
* this function returns a list of configurations for all admins that declare
diff --git a/core/java/android/app/contentsuggestions/ClassificationsRequest.java b/core/java/android/app/contentsuggestions/ClassificationsRequest.java
index 1b50015..2051a55 100644
--- a/core/java/android/app/contentsuggestions/ClassificationsRequest.java
+++ b/core/java/android/app/contentsuggestions/ClassificationsRequest.java
@@ -54,10 +54,10 @@
}
/**
- * Return the request extras or {@code null} if there are none.
+ * Return the request extras, can be an empty bundle.
*/
- public @Nullable Bundle getExtras() {
- return mExtras;
+ public @NonNull Bundle getExtras() {
+ return mExtras == null ? new Bundle() : mExtras;
}
@Override
@@ -103,7 +103,7 @@
/**
* Sets the request extras.
*/
- public Builder setExtras(@NonNull Bundle extras) {
+ public @NonNull Builder setExtras(@NonNull Bundle extras) {
mExtras = extras;
return this;
}
@@ -111,7 +111,7 @@
/**
* Builds a new request instance.
*/
- public ClassificationsRequest build() {
+ public @NonNull ClassificationsRequest build() {
return new ClassificationsRequest(mSelections, mExtras);
}
}
diff --git a/core/java/android/app/contentsuggestions/SelectionsRequest.java b/core/java/android/app/contentsuggestions/SelectionsRequest.java
index 257f98d..84f33b5 100644
--- a/core/java/android/app/contentsuggestions/SelectionsRequest.java
+++ b/core/java/android/app/contentsuggestions/SelectionsRequest.java
@@ -63,10 +63,10 @@
}
/**
- * Return the request extras or {@code null} if there aren't any.
+ * Return the request extras, may be an empty bundle if there aren't any.
*/
- public @Nullable Bundle getExtras() {
- return mExtras;
+ public @NonNull Bundle getExtras() {
+ return mExtras == null ? new Bundle() : mExtras;
}
@Override
@@ -118,7 +118,7 @@
/**
* Sets the request extras.
*/
- public Builder setExtras(@NonNull Bundle extras) {
+ public @NonNull Builder setExtras(@NonNull Bundle extras) {
mExtras = extras;
return this;
}
@@ -126,7 +126,7 @@
/**
* Sets the request interest point.
*/
- public Builder setInterestPoint(@NonNull Point interestPoint) {
+ public @NonNull Builder setInterestPoint(@NonNull Point interestPoint) {
mInterestPoint = interestPoint;
return this;
}
@@ -134,7 +134,7 @@
/**
* Builds a new request instance.
*/
- public SelectionsRequest build() {
+ public @NonNull SelectionsRequest build() {
return new SelectionsRequest(mTaskId, mInterestPoint, mExtras);
}
}
diff --git a/core/java/android/hardware/camera2/CameraManager.java b/core/java/android/hardware/camera2/CameraManager.java
index 536c2e1..23401432 100644
--- a/core/java/android/hardware/camera2/CameraManager.java
+++ b/core/java/android/hardware/camera2/CameraManager.java
@@ -678,6 +678,31 @@
public void onCameraUnavailable(@NonNull String cameraId) {
// default empty implementation
}
+
+ /**
+ * Notify registered clients about a change in the camera access priorities.
+ *
+ * <p>Notification that camera access priorities have changed and the camera may
+ * now be openable. An application that was previously denied camera access due to
+ * a higher-priority user already using the camera, or that was disconnected from an
+ * active camera session due to a higher-priority user trying to open the camera,
+ * should try to open the camera again if it still wants to use it. Note that
+ * multiple applications may receive this callback at the same time, and only one of
+ * them will succeed in opening the camera in practice, depending on exact access
+ * priority levels and timing. This method is useful in cases where multiple
+ * applications may be in the resumed state at the same time, and the user switches
+ * focus between them, or if the current camera-using application moves between
+ * full-screen and Picture-in-Picture (PiP) states. In such cases, the camera
+ * available/unavailable callbacks will not be invoked, but another application may
+ * now have higher priority for camera access than the current camera-using
+ * application.</p>
+ *
+ * <p>The default implementation of this method does nothing.</p>
+ *
+ */
+ public void onCameraAccessPrioritiesChanged() {
+ // default empty implementation
+ }
}
/**
@@ -1098,6 +1123,22 @@
}
}
+ private void postSingleAccessPriorityChangeUpdate(final AvailabilityCallback callback,
+ final Executor executor) {
+ final long ident = Binder.clearCallingIdentity();
+ try {
+ executor.execute(
+ new Runnable() {
+ @Override
+ public void run() {
+ callback.onCameraAccessPrioritiesChanged();
+ }
+ });
+ } finally {
+ Binder.restoreCallingIdentity(ident);
+ }
+ }
+
private void postSingleUpdate(final AvailabilityCallback callback, final Executor executor,
final String id, final int status) {
if (isAvailable(status)) {
@@ -1347,6 +1388,19 @@
}
}
+ @Override
+ public void onCameraAccessPrioritiesChanged() {
+ synchronized (mLock) {
+ final int callbackCount = mCallbackMap.size();
+ for (int i = 0; i < callbackCount; i++) {
+ Executor executor = mCallbackMap.valueAt(i);
+ final AvailabilityCallback callback = mCallbackMap.keyAt(i);
+
+ postSingleAccessPriorityChangeUpdate(callback, executor);
+ }
+ }
+ }
+
/**
* Try to connect to camera service after some delay if any client registered camera
* availability callback or torch status callback.
diff --git a/core/java/android/hardware/display/DisplayManagerGlobal.java b/core/java/android/hardware/display/DisplayManagerGlobal.java
index ac44fe9..ea63776 100644
--- a/core/java/android/hardware/display/DisplayManagerGlobal.java
+++ b/core/java/android/hardware/display/DisplayManagerGlobal.java
@@ -185,6 +185,21 @@
}
/**
+ * Check if specified UID's content is present on display and should be granted access to it.
+ *
+ * @param uid UID to be checked.
+ * @param displayId id of the display where presence of the content is checked.
+ * @return {@code true} if UID is present on display, {@code false} otherwise.
+ */
+ public boolean isUidPresentOnDisplay(int uid, int displayId) {
+ try {
+ return mDm.isUidPresentOnDisplay(uid, displayId);
+ } catch (RemoteException ex) {
+ throw ex.rethrowFromSystemServer();
+ }
+ }
+
+ /**
* Gets information about a logical display.
*
* The display metrics may be adjusted to provide compatibility
diff --git a/core/java/android/hardware/display/DisplayManagerInternal.java b/core/java/android/hardware/display/DisplayManagerInternal.java
index 43ea682..8231985 100644
--- a/core/java/android/hardware/display/DisplayManagerInternal.java
+++ b/core/java/android/hardware/display/DisplayManagerInternal.java
@@ -187,14 +187,6 @@
public abstract void setDisplayAccessUIDs(SparseArray<IntArray> displayAccessUIDs);
/**
- * Check if specified UID's content is present on display and should be granted access to it.
- *
- * @param uid UID to be checked.
- * @param displayId id of the display where presence of the content is checked.
- * */
- public abstract boolean isUidPresentOnDisplay(int uid, int displayId);
-
- /**
* Persist brightness slider events and ambient brightness stats.
*/
public abstract void persistBrightnessTrackerState();
diff --git a/core/java/android/hardware/display/IDisplayManager.aidl b/core/java/android/hardware/display/IDisplayManager.aidl
index edd2051..0143c91 100644
--- a/core/java/android/hardware/display/IDisplayManager.aidl
+++ b/core/java/android/hardware/display/IDisplayManager.aidl
@@ -34,6 +34,8 @@
DisplayInfo getDisplayInfo(int displayId);
int[] getDisplayIds();
+ boolean isUidPresentOnDisplay(int uid, int displayId);
+
void registerCallback(in IDisplayManagerCallback callback);
// Requires CONFIGURE_WIFI_DISPLAY permission.
diff --git a/core/java/android/net/NetworkCapabilities.java b/core/java/android/net/NetworkCapabilities.java
index a17ebcb..eb0fe33 100644
--- a/core/java/android/net/NetworkCapabilities.java
+++ b/core/java/android/net/NetworkCapabilities.java
@@ -143,6 +143,7 @@
NET_CAPABILITY_NOT_CONGESTED,
NET_CAPABILITY_NOT_SUSPENDED,
NET_CAPABILITY_OEM_PAID,
+ NET_CAPABILITY_MCX
})
public @interface NetCapability { }
@@ -297,8 +298,14 @@
@SystemApi
public static final int NET_CAPABILITY_OEM_PAID = 22;
+ /**
+ * Indicates this is a network that has the ability to reach a carrier's Mission Critical
+ * servers.
+ */
+ public static final int NET_CAPABILITY_MCX = 23;
+
private static final int MIN_NET_CAPABILITY = NET_CAPABILITY_MMS;
- private static final int MAX_NET_CAPABILITY = NET_CAPABILITY_OEM_PAID;
+ private static final int MAX_NET_CAPABILITY = NET_CAPABILITY_MCX;
/**
* Network capabilities that are expected to be mutable, i.e., can change while a particular
@@ -346,7 +353,8 @@
(1 << NET_CAPABILITY_IA) |
(1 << NET_CAPABILITY_IMS) |
(1 << NET_CAPABILITY_RCS) |
- (1 << NET_CAPABILITY_XCAP);
+ (1 << NET_CAPABILITY_XCAP) |
+ (1 << NET_CAPABILITY_MCX);
/**
* Capabilities that force network to be restricted.
@@ -1614,6 +1622,7 @@
case NET_CAPABILITY_NOT_CONGESTED: return "NOT_CONGESTED";
case NET_CAPABILITY_NOT_SUSPENDED: return "NOT_SUSPENDED";
case NET_CAPABILITY_OEM_PAID: return "OEM_PAID";
+ case NET_CAPABILITY_MCX: return "MCX";
default: return Integer.toString(capability);
}
}
diff --git a/core/java/android/permission/RuntimePermissionPresentationInfo.java b/core/java/android/permission/RuntimePermissionPresentationInfo.java
index d66789f..4fce14c 100644
--- a/core/java/android/permission/RuntimePermissionPresentationInfo.java
+++ b/core/java/android/permission/RuntimePermissionPresentationInfo.java
@@ -21,6 +21,8 @@
import android.os.Parcel;
import android.os.Parcelable;
+import com.android.internal.util.Preconditions;
+
/**
* This class contains information about how a runtime permission
* is to be presented in the UI. A single runtime permission
@@ -35,7 +37,7 @@
private static final int FLAG_GRANTED = 1 << 0;
private static final int FLAG_STANDARD = 1 << 1;
- private final CharSequence mLabel;
+ private final @NonNull CharSequence mLabel;
private final int mFlags;
/**
@@ -45,8 +47,10 @@
* @param granted Whether the permission is granted.
* @param standard Whether this is a platform-defined permission.
*/
- public RuntimePermissionPresentationInfo(CharSequence label,
+ public RuntimePermissionPresentationInfo(@NonNull CharSequence label,
boolean granted, boolean standard) {
+ Preconditions.checkNotNull(label);
+
mLabel = label;
int flags = 0;
if (granted) {
@@ -58,11 +62,6 @@
mFlags = flags;
}
- private RuntimePermissionPresentationInfo(Parcel parcel) {
- mLabel = parcel.readCharSequence();
- mFlags = parcel.readInt();
- }
-
/**
* @return Whether the permission is granted.
*/
@@ -97,10 +96,14 @@
parcel.writeInt(mFlags);
}
- public static final @android.annotation.NonNull Creator<RuntimePermissionPresentationInfo> CREATOR =
+ public static final @NonNull Creator<RuntimePermissionPresentationInfo> CREATOR =
new Creator<RuntimePermissionPresentationInfo>() {
public RuntimePermissionPresentationInfo createFromParcel(Parcel source) {
- return new RuntimePermissionPresentationInfo(source);
+ CharSequence label = source.readCharSequence();
+ int flags = source.readInt();
+
+ return new RuntimePermissionPresentationInfo(label, (flags & FLAG_GRANTED) != 0,
+ (flags & FLAG_STANDARD) != 0);
}
public RuntimePermissionPresentationInfo[] newArray(int size) {
diff --git a/core/java/android/provider/DeviceConfig.java b/core/java/android/provider/DeviceConfig.java
index 2cd3c48..5d4539c 100644
--- a/core/java/android/provider/DeviceConfig.java
+++ b/core/java/android/provider/DeviceConfig.java
@@ -64,12 +64,14 @@
public static final String NAMESPACE_ACTIVITY_MANAGER = "activity_manager";
/**
- * Namespace for all Game Driver features.
+ * Namespace for all activity manager related features that are used at the native level.
+ * These features are applied at reboot.
*
* @hide
*/
@SystemApi
- public static final String NAMESPACE_GAME_DRIVER = "game_driver";
+ public static final String NAMESPACE_ACTIVITY_MANAGER_NATIVE_BOOT =
+ "activity_manager_native_boot";
/**
* Namespace for autofill feature that provides suggestions across all apps when
@@ -92,6 +94,14 @@
public static final String NAMESPACE_CONTENT_CAPTURE = "content_capture";
/**
+ * Namespace for all Game Driver features.
+ *
+ * @hide
+ */
+ @SystemApi
+ public static final String NAMESPACE_GAME_DRIVER = "game_driver";
+
+ /**
* Namespace for all input-related features that are used at the native level.
* These features are applied at reboot.
*
@@ -101,6 +111,14 @@
public static final String NAMESPACE_INPUT_NATIVE_BOOT = "input_native_boot";
/**
+ * Namespace for all media native related features.
+ *
+ * @hide
+ */
+ @SystemApi
+ public static final String NAMESPACE_MEDIA_NATIVE = "media_native";
+
+ /**
* Namespace for all netd related features.
*
* @hide
@@ -109,6 +127,15 @@
public static final String NAMESPACE_NETD_NATIVE = "netd_native";
/**
+ * Namespace for all runtime native boot related features. Boot in this case refers to the
+ * fact that the properties only take affect after rebooting the device.
+ *
+ * @hide
+ */
+ @SystemApi
+ public static final String NAMESPACE_RUNTIME_NATIVE_BOOT = "runtime_native_boot";
+
+ /**
* Namespace for System UI related features.
*
* @hide
@@ -174,40 +201,6 @@
}
/**
- * Namespace for all runtime native boot related features. Boot in this case refers to the
- * fact that the properties only take affect after rebooting the device.
- *
- * @hide
- */
- @SystemApi
- public interface RuntimeNativeBoot {
- String NAMESPACE = "runtime_native_boot";
- }
-
- /**
- * Namespace for all media native related features.
- *
- * @hide
- */
- @SystemApi
- public interface MediaNative {
- /** The flag namespace for media native features. */
- String NAMESPACE = "media_native";
- }
-
- /**
- * Namespace for all activity manager related features that are used at the native level.
- * These features are applied at reboot.
- *
- * @hide
- */
- @SystemApi
- public interface ActivityManagerNativeBoot {
- String NAMESPACE = "activity_manager_native_boot";
- String OFFLOAD_QUEUE_ENABLED = "offload_queue_enabled";
- }
-
- /**
* Namespace for attention-based features provided by on-device machine intelligence.
*
* @hide
diff --git a/core/java/android/service/carrier/ApnService.java b/core/java/android/service/carrier/ApnService.java
index d53eb37..57e4b1b 100644
--- a/core/java/android/service/carrier/ApnService.java
+++ b/core/java/android/service/carrier/ApnService.java
@@ -16,6 +16,8 @@
package android.service.carrier;
+import android.annotation.NonNull;
+import android.annotation.Nullable;
import android.annotation.SystemApi;
import android.annotation.WorkerThread;
import android.app.Service;
@@ -60,7 +62,8 @@
};
@Override
- public IBinder onBind(Intent intent) {
+ @NonNull
+ public IBinder onBind(@Nullable Intent intent) {
return mBinder;
}
@@ -73,5 +76,6 @@
* subId.
*/
@WorkerThread
+ @NonNull
public abstract List<ContentValues> onRestoreApns(int subId);
}
diff --git a/core/java/android/util/DocumentsStatsLog.java b/core/java/android/util/DocumentsStatsLog.java
index f483944..a67bbde 100644
--- a/core/java/android/util/DocumentsStatsLog.java
+++ b/core/java/android/util/DocumentsStatsLog.java
@@ -16,6 +16,7 @@
package android.util;
+import android.annotation.Nullable;
import android.annotation.SystemApi;
import android.provider.DocumentsContract;
import android.provider.DocumentsProvider;
@@ -126,7 +127,7 @@
*
* @param packageName
*/
- public static void logPickerLaunchedFrom(String packageName) {
+ public static void logPickerLaunchedFrom(@Nullable String packageName) {
StatsLog.write(StatsLog.DOCS_UI_PICKER_LAUNCHED_FROM_REPORTED, packageName);
}
diff --git a/core/java/android/util/LongSparseArray.java b/core/java/android/util/LongSparseArray.java
index 9ba0f5d..cf49803 100644
--- a/core/java/android/util/LongSparseArray.java
+++ b/core/java/android/util/LongSparseArray.java
@@ -21,6 +21,9 @@
import libcore.util.EmptyArray;
+import java.util.Arrays;
+import java.util.Objects;
+
/**
* SparseArray mapping longs to Objects. Unlike a normal array of Objects,
* there can be gaps in the indices. It is intended to be more memory efficient
diff --git a/core/java/android/util/LongSparseLongArray.java b/core/java/android/util/LongSparseLongArray.java
index af163ac..8dcdb40 100644
--- a/core/java/android/util/LongSparseLongArray.java
+++ b/core/java/android/util/LongSparseLongArray.java
@@ -22,6 +22,8 @@
import android.annotation.UnsupportedAppUsage;
import libcore.util.EmptyArray;
+import java.util.Arrays;
+
/**
* Map of {@code long} to {@code long}. Unlike a normal array of longs, there
* can be gaps in the indices. It is intended to be more memory efficient than using a
diff --git a/core/java/android/view/Display.java b/core/java/android/view/Display.java
index dbb2071..b3d98b8 100644
--- a/core/java/android/view/Display.java
+++ b/core/java/android/view/Display.java
@@ -21,6 +21,7 @@
import android.annotation.IntDef;
import android.annotation.Nullable;
import android.annotation.RequiresPermission;
+import android.annotation.TestApi;
import android.annotation.UnsupportedAppUsage;
import android.app.KeyguardManager;
import android.content.res.CompatibilityInfo;
@@ -1096,16 +1097,19 @@
* Returns true if the specified UID has access to this display.
* @hide
*/
+ @TestApi
public boolean hasAccess(int uid) {
- return Display.hasAccess(uid, mFlags, mOwnerUid);
+ return hasAccess(uid, mFlags, mOwnerUid, mDisplayId);
}
/** @hide */
- public static boolean hasAccess(int uid, int flags, int ownerUid) {
+ public static boolean hasAccess(int uid, int flags, int ownerUid, int displayId) {
return (flags & Display.FLAG_PRIVATE) == 0
|| uid == ownerUid
|| uid == Process.SYSTEM_UID
- || uid == 0;
+ || uid == 0
+ // Check if the UID is present on given display.
+ || DisplayManagerGlobal.getInstance().isUidPresentOnDisplay(uid, displayId);
}
/**
diff --git a/core/java/android/view/DisplayInfo.java b/core/java/android/view/DisplayInfo.java
index 11ed357..2efebf6 100644
--- a/core/java/android/view/DisplayInfo.java
+++ b/core/java/android/view/DisplayInfo.java
@@ -58,6 +58,11 @@
public int type;
/**
+ * Logical display identifier.
+ */
+ public int displayId;
+
+ /**
* Display address, or null if none.
* Interpretation varies by display type.
*/
@@ -305,6 +310,7 @@
&& layerStack == other.layerStack
&& flags == other.flags
&& type == other.type
+ && displayId == other.displayId
&& Objects.equals(address, other.address)
&& Objects.equals(uniqueId, other.uniqueId)
&& appWidth == other.appWidth
@@ -346,6 +352,7 @@
layerStack = other.layerStack;
flags = other.flags;
type = other.type;
+ displayId = other.displayId;
address = other.address;
name = other.name;
uniqueId = other.uniqueId;
@@ -385,6 +392,7 @@
layerStack = source.readInt();
flags = source.readInt();
type = source.readInt();
+ displayId = source.readInt();
address = source.readParcelable(null);
name = source.readString();
appWidth = source.readInt();
@@ -432,6 +440,7 @@
dest.writeInt(layerStack);
dest.writeInt(this.flags);
dest.writeInt(type);
+ dest.writeInt(displayId);
dest.writeParcelable(address, flags);
dest.writeString(name);
dest.writeInt(appWidth);
@@ -579,7 +588,7 @@
* Returns true if the specified UID has access to this display.
*/
public boolean hasAccess(int uid) {
- return Display.hasAccess(uid, flags, ownerUid);
+ return Display.hasAccess(uid, flags, ownerUid, displayId);
}
private void getMetricsWithSize(DisplayMetrics outMetrics, CompatibilityInfo compatInfo,
@@ -610,6 +619,8 @@
StringBuilder sb = new StringBuilder();
sb.append("DisplayInfo{\"");
sb.append(name);
+ sb.append(", displayId ");
+ sb.append(displayId);
sb.append("\", uniqueId \"");
sb.append(uniqueId);
sb.append("\", app ");
diff --git a/core/java/android/view/View.java b/core/java/android/view/View.java
index 877b304..874be81 100644
--- a/core/java/android/view/View.java
+++ b/core/java/android/view/View.java
@@ -18589,7 +18589,7 @@
@FlagMap(target = FADING_EDGE_VERTICAL, name = "vertical"),
@FlagMap(target = FADING_EDGE_HORIZONTAL, name = "horizontal")
})
- int getFadingEdge() {
+ public int getFadingEdge() {
return mViewFlags & FADING_EDGE_MASK;
}
@@ -18600,7 +18600,7 @@
* @hide
*/
@InspectableProperty
- int getFadingEdgeLength() {
+ public int getFadingEdgeLength() {
if (mScrollCache != null && (mViewFlags & FADING_EDGE_MASK) != FADING_EDGE_NONE) {
return mScrollCache.fadingEdgeLength;
}
diff --git a/core/java/android/view/inspector/InspectableProperty.java b/core/java/android/view/inspector/InspectableProperty.java
index f859521..30938c1 100644
--- a/core/java/android/view/inspector/InspectableProperty.java
+++ b/core/java/android/view/inspector/InspectableProperty.java
@@ -16,6 +16,7 @@
package android.view.inspector;
+import static java.lang.annotation.ElementType.FIELD;
import static java.lang.annotation.ElementType.METHOD;
import static java.lang.annotation.ElementType.TYPE;
import static java.lang.annotation.RetentionPolicy.SOURCE;
@@ -39,7 +40,7 @@
* @see InspectionCompanion#readProperties(Object, PropertyReader)
* @hide
*/
-@Target({METHOD})
+@Target({METHOD, FIELD})
@Retention(SOURCE)
@TestApi
public @interface InspectableProperty {
diff --git a/core/java/com/android/internal/app/ChooserActivity.java b/core/java/com/android/internal/app/ChooserActivity.java
index a5a1dd9..67e0446 100644
--- a/core/java/com/android/internal/app/ChooserActivity.java
+++ b/core/java/com/android/internal/app/ChooserActivity.java
@@ -1889,11 +1889,19 @@
* Set to true to reveal all service targets at once.
*/
public void setShowServiceTargets(boolean show) {
+ // mShowServiceTargets is only flipped once to show direct share targets. But after the
+ // initial display the list can be re-sorted and the user will see the target list
+ // change. This will log the initial show and the subsequent shuffle to help us get
+ // accurate timing of the UX.
+ if (show) {
+ getMetricsLogger().write(
+ new LogMaker(MetricsEvent.ACTION_ACTIVITY_CHOOSER_SHOWN_DIRECT_TARGET)
+ .setSubtype(mShowServiceTargets ? MetricsEvent.PREVIOUSLY_VISIBLE
+ : MetricsEvent.PREVIOUSLY_HIDDEN));
+ }
if (show != mShowServiceTargets) {
mShowServiceTargets = show;
notifyDataSetChanged();
- getMetricsLogger().write(
- new LogMaker(MetricsEvent.ACTION_ACTIVITY_CHOOSER_SHOWN_DIRECT_TARGET));
}
}
diff --git a/core/java/com/android/internal/app/IAppOpsService.aidl b/core/java/com/android/internal/app/IAppOpsService.aidl
index c096961..c4af4c7 100644
--- a/core/java/com/android/internal/app/IAppOpsService.aidl
+++ b/core/java/com/android/internal/app/IAppOpsService.aidl
@@ -48,9 +48,9 @@
@UnsupportedAppUsage
List<AppOpsManager.PackageOps> getOpsForPackage(int uid, String packageName, in int[] ops);
void getHistoricalOps(int uid, String packageName, in List<String> ops, long beginTimeMillis,
- long endTimeMillis, in RemoteCallback callback);
+ long endTimeMillis, int flags, in RemoteCallback callback);
void getHistoricalOpsFromDiskRaw(int uid, String packageName, in List<String> ops,
- long beginTimeMillis, long endTimeMillis, in RemoteCallback callback);
+ long beginTimeMillis, long endTimeMillis, int flags, in RemoteCallback callback);
void offsetHistory(long duration);
void setHistoryParameters(int mode, long baseSnapshotInterval, int compressionStep);
void addHistoricalOps(in AppOpsManager.HistoricalOps ops);
diff --git a/core/java/com/android/internal/os/BinderCallsStats.java b/core/java/com/android/internal/os/BinderCallsStats.java
index bab4787..aa1e0d4 100644
--- a/core/java/com/android/internal/os/BinderCallsStats.java
+++ b/core/java/com/android/internal/os/BinderCallsStats.java
@@ -54,7 +54,7 @@
public static final int PERIODIC_SAMPLING_INTERVAL_DEFAULT = 1000;
public static final boolean DEFAULT_TRACK_SCREEN_INTERACTIVE = false;
public static final boolean DEFAULT_TRACK_DIRECT_CALLING_UID = true;
- public static final int MAX_BINDER_CALL_STATS_COUNT_DEFAULT = 5000;
+ public static final int MAX_BINDER_CALL_STATS_COUNT_DEFAULT = 1500;
private static final String DEBUG_ENTRY_PREFIX = "__DEBUG_";
private static class OverflowBinder extends Binder {}
diff --git a/core/res/res/layout/immersive_mode_cling.xml b/core/res/res/layout/immersive_mode_cling.xml
index b08b0f4..9fd615d 100644
--- a/core/res/res/layout/immersive_mode_cling.xml
+++ b/core/res/res/layout/immersive_mode_cling.xml
@@ -59,7 +59,7 @@
android:paddingStart="48dp"
android:paddingTop="40dp"
android:text="@string/immersive_cling_title"
- android:textColor="@color/primary_text_default_material_light"
+ android:textColor="@android:color/white"
android:textSize="24sp" />
<TextView
@@ -71,7 +71,7 @@
android:paddingStart="48dp"
android:paddingTop="12.6dp"
android:text="@string/immersive_cling_description"
- android:textColor="@color/primary_text_default_material_light"
+ android:textColor="@android:color/white"
android:textSize="16sp" />
<Button
@@ -89,4 +89,4 @@
android:textColor="@android:color/white"
android:textSize="14sp" />
-</RelativeLayout>
\ No newline at end of file
+</RelativeLayout>
diff --git a/core/tests/BroadcastRadioTests/Android.mk b/core/tests/BroadcastRadioTests/Android.mk
index 6b0484e..faffc4b 100644
--- a/core/tests/BroadcastRadioTests/Android.mk
+++ b/core/tests/BroadcastRadioTests/Android.mk
@@ -25,7 +25,7 @@
# LOCAL_SDK_VERSION := current
LOCAL_PRIVATE_PLATFORM_APIS := true
-LOCAL_STATIC_JAVA_LIBRARIES := compatibility-device-util androidx.test.rules testng
+LOCAL_STATIC_JAVA_LIBRARIES := compatibility-device-util-axt androidx.test.rules testng
LOCAL_JAVA_LIBRARIES := android.test.base
diff --git a/graphics/java/android/graphics/drawable/GradientDrawable.java b/graphics/java/android/graphics/drawable/GradientDrawable.java
index 6ecb621..1894e32 100644
--- a/graphics/java/android/graphics/drawable/GradientDrawable.java
+++ b/graphics/java/android/graphics/drawable/GradientDrawable.java
@@ -581,9 +581,9 @@
* The default value for this property is {@code false}.
* <p>
* <strong>Note</strong>: This property corresponds to the
- * {@code android:useLevel} attribute on the inner {@code <gradient>}
+ * {@code android:useLevel} attribute on the inner {@code <gradient>}
* tag, NOT the {@code android:useLevel} attribute on the outer
- * {@code <shape>} tag. For example,
+ * {@code <shape>} tag. For example,
* <pre>{@code
* <shape ...>
* <gradient
diff --git a/keystore/tests/Android.mk b/keystore/tests/Android.mk
index 596e5f5..99d3197 100644
--- a/keystore/tests/Android.mk
+++ b/keystore/tests/Android.mk
@@ -21,7 +21,7 @@
LOCAL_SRC_FILES := $(call all-java-files-under, src)
LOCAL_STATIC_JAVA_LIBRARIES := \
- android-support-test
+ androidx.test.rules hamcrest-library
LOCAL_PACKAGE_NAME := KeystoreTests
LOCAL_PRIVATE_PLATFORM_APIS := true
diff --git a/keystore/tests/AndroidManifest.xml b/keystore/tests/AndroidManifest.xml
index 9bf2d0c..6833cd1 100644
--- a/keystore/tests/AndroidManifest.xml
+++ b/keystore/tests/AndroidManifest.xml
@@ -20,7 +20,7 @@
<uses-library android:name="android.test.runner" />
</application>
- <instrumentation android:name="android.support.test.runner.AndroidJUnitRunner"
+ <instrumentation android:name="androidx.test.runner.AndroidJUnitRunner"
android:targetPackage="android.security.tests"
android:label="Tests for Keystore">
</instrumentation>
diff --git a/keystore/tests/src/android/security/ParcelableKeyGenParameterSpecTest.java b/keystore/tests/src/android/security/ParcelableKeyGenParameterSpecTest.java
index 32f8ec4..fca2775 100644
--- a/keystore/tests/src/android/security/ParcelableKeyGenParameterSpecTest.java
+++ b/keystore/tests/src/android/security/ParcelableKeyGenParameterSpecTest.java
@@ -22,16 +22,20 @@
import android.os.Parcel;
import android.security.keystore.KeyGenParameterSpec;
-import android.security.keystore.ParcelableKeyGenParameterSpec;
import android.security.keystore.KeyProperties;
-import android.support.test.runner.AndroidJUnit4;
+import android.security.keystore.ParcelableKeyGenParameterSpec;
+
+import androidx.test.runner.AndroidJUnit4;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
import java.math.BigInteger;
import java.security.spec.ECGenParameterSpec;
import java.security.spec.RSAKeyGenParameterSpec;
import java.util.Date;
+
import javax.security.auth.x500.X500Principal;
-import org.junit.Test;
-import org.junit.runner.RunWith;
/** Unit tests for {@link ParcelableKeyGenParameterSpec}. */
@RunWith(AndroidJUnit4.class)
diff --git a/keystore/tests/src/android/security/keystore/KeyGenParameterSpecTest.java b/keystore/tests/src/android/security/keystore/KeyGenParameterSpecTest.java
index 865cad4..b2edfd0 100644
--- a/keystore/tests/src/android/security/keystore/KeyGenParameterSpecTest.java
+++ b/keystore/tests/src/android/security/keystore/KeyGenParameterSpecTest.java
@@ -20,10 +20,12 @@
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertThat;
+import android.security.ParcelableKeyGenParameterSpecTest;
import android.security.keystore.KeyGenParameterSpec;
import android.security.keystore.KeyProperties;
-import android.security.ParcelableKeyGenParameterSpecTest;
-import android.support.test.runner.AndroidJUnit4;
+
+import androidx.test.runner.AndroidJUnit4;
+
import org.junit.Test;
import org.junit.runner.RunWith;
diff --git a/location/java/com/android/internal/location/GpsNetInitiatedHandler.java b/location/java/com/android/internal/location/GpsNetInitiatedHandler.java
index 866634e..e5fd0d3 100644
--- a/location/java/com/android/internal/location/GpsNetInitiatedHandler.java
+++ b/location/java/com/android/internal/location/GpsNetInitiatedHandler.java
@@ -118,8 +118,8 @@
static private boolean mIsHexInput = true;
// End time of emergency call, and extension, if set
- private long mCallEndElapsedRealtimeMillis = 0;
- private long mEmergencyExtensionMillis = 0;
+ private volatile long mCallEndElapsedRealtimeMillis = 0;
+ private volatile long mEmergencyExtensionMillis = 0;
public static class GpsNiNotification
{
@@ -242,8 +242,9 @@
*/
public boolean getInEmergency() {
boolean isInEmergencyExtension =
- (SystemClock.elapsedRealtime() - mCallEndElapsedRealtimeMillis) <
- mEmergencyExtensionMillis;
+ (mCallEndElapsedRealtimeMillis > 0)
+ && ((SystemClock.elapsedRealtime() - mCallEndElapsedRealtimeMillis)
+ < mEmergencyExtensionMillis);
boolean isInEmergencyCallback = mTelephonyManager.getEmergencyCallbackMode();
return mIsInEmergencyCall || isInEmergencyCallback || isInEmergencyExtension;
}
diff --git a/media/apex/java/android/media/CallbackDataSourceDesc.java b/media/apex/java/android/media/CallbackDataSourceDesc.java
index cd36414..9209ca9 100644
--- a/media/apex/java/android/media/CallbackDataSourceDesc.java
+++ b/media/apex/java/android/media/CallbackDataSourceDesc.java
@@ -17,6 +17,7 @@
package android.media;
import android.annotation.NonNull;
+import android.annotation.Nullable;
/**
* Structure of data source descriptor for sources using callback.
@@ -37,7 +38,7 @@
* Return the DataSourceCallback of this data source.
* @return the DataSourceCallback of this data source
*/
- public DataSourceCallback getDataSourceCallback() {
+ public @NonNull DataSourceCallback getDataSourceCallback() {
return mDataSourceCallback;
}
@@ -70,7 +71,7 @@
* @param dsd the {@link CallbackDataSourceDesc} object whose data will be reused
* in the new Builder.
*/
- public Builder(CallbackDataSourceDesc dsd) {
+ public Builder(@Nullable CallbackDataSourceDesc dsd) {
super(dsd);
if (dsd == null) {
return; // use default
@@ -86,6 +87,11 @@
* @return a new {@link CallbackDataSourceDesc} object
*/
public @NonNull CallbackDataSourceDesc build() {
+ if (mDataSourceCallback == null) {
+ throw new IllegalStateException(
+ "DataSourceCallback should not be null");
+ }
+
CallbackDataSourceDesc dsd = new CallbackDataSourceDesc();
super.build(dsd);
dsd.mDataSourceCallback = mDataSourceCallback;
diff --git a/media/apex/java/android/media/DataSourceCallback.java b/media/apex/java/android/media/DataSourceCallback.java
index 1afcd20..6515bd6 100644
--- a/media/apex/java/android/media/DataSourceCallback.java
+++ b/media/apex/java/android/media/DataSourceCallback.java
@@ -17,6 +17,8 @@
package android.media;
+import android.annotation.NonNull;
+
import java.io.Closeable;
import java.io.IOException;
@@ -49,7 +51,7 @@
* @throws IOException on fatal errors.
* @return the number of bytes read, or -1 if end of stream is reached.
*/
- public abstract int readAt(long position, byte[] buffer, int offset, int size)
+ public abstract int readAt(long position, @NonNull byte[] buffer, int offset, int size)
throws IOException;
/**
diff --git a/media/apex/java/android/media/DataSourceDesc.java b/media/apex/java/android/media/DataSourceDesc.java
index 7fc6f79..e6fd120 100644
--- a/media/apex/java/android/media/DataSourceDesc.java
+++ b/media/apex/java/android/media/DataSourceDesc.java
@@ -17,6 +17,7 @@
package android.media;
import android.annotation.NonNull;
+import android.annotation.Nullable;
/**
* Base class of data source descriptor.
@@ -64,7 +65,7 @@
* Return the media Id of data source.
* @return the media Id of data source
*/
- public String getMediaId() {
+ public @Nullable String getMediaId() {
return mMediaId;
}
@@ -149,7 +150,7 @@
* @param mediaId the media Id of this data source
* @return the same Builder instance.
*/
- public @NonNull T setMediaId(String mediaId) {
+ public @NonNull T setMediaId(@Nullable String mediaId) {
mMediaId = mediaId;
return (T) this;
}
diff --git a/media/apex/java/android/media/FileDataSourceDesc.java b/media/apex/java/android/media/FileDataSourceDesc.java
index e29bd00..4b70367 100644
--- a/media/apex/java/android/media/FileDataSourceDesc.java
+++ b/media/apex/java/android/media/FileDataSourceDesc.java
@@ -17,6 +17,7 @@
package android.media;
import android.annotation.NonNull;
+import android.annotation.Nullable;
import android.os.ParcelFileDescriptor;
import android.util.Log;
@@ -106,7 +107,7 @@
* Return the ParcelFileDescriptor of this data source.
* @return the ParcelFileDescriptor of this data source
*/
- public ParcelFileDescriptor getParcelFileDescriptor() {
+ public @NonNull ParcelFileDescriptor getParcelFileDescriptor() {
return mPFD;
}
@@ -159,7 +160,7 @@
* @param dsd the {@link FileDataSourceDesc} object whose data will be reused
* in the new Builder.
*/
- public Builder(FileDataSourceDesc dsd) {
+ public Builder(@Nullable FileDataSourceDesc dsd) {
super(dsd);
if (dsd == null) {
return; // use default
diff --git a/media/apex/java/android/media/MediaPlayer2.java b/media/apex/java/android/media/MediaPlayer2.java
index ef30172..f6b2031 100644
--- a/media/apex/java/android/media/MediaPlayer2.java
+++ b/media/apex/java/android/media/MediaPlayer2.java
@@ -344,7 +344,7 @@
* to free the resources. If not released, too many MediaPlayer2 instances may
* result in an exception.</p>
*/
- public MediaPlayer2(Context context) {
+ public MediaPlayer2(@NonNull Context context) {
mGuard.open("close");
mContext = context;
@@ -488,7 +488,7 @@
* @return a token which can be used to cancel the operation later with {@link #cancelCommand}.
*/
// This is an asynchronous call.
- public Object play() {
+ public @NonNull Object play() {
return addTask(new Task(CALL_COMPLETED_PLAY, false) {
@Override
void process() {
@@ -508,7 +508,7 @@
* @return a token which can be used to cancel the operation later with {@link #cancelCommand}.
*/
// This is an asynchronous call.
- public Object prepare() {
+ public @NonNull Object prepare() {
return addTask(new Task(CALL_COMPLETED_PREPARE, true) {
@Override
void process() {
@@ -524,7 +524,7 @@
* @return a token which can be used to cancel the operation later with {@link #cancelCommand}.
*/
// This is an asynchronous call.
- public Object pause() {
+ public @NonNull Object pause() {
return addTask(new Task(CALL_COMPLETED_PAUSE, false) {
@Override
void process() {
@@ -542,7 +542,7 @@
* @return a token which can be used to cancel the operation later with {@link #cancelCommand}.
*/
// This is an asynchronous call.
- public Object skipToNext() {
+ public @NonNull Object skipToNext() {
return addTask(new Task(CALL_COMPLETED_SKIP_TO_NEXT, false) {
@Override
void process() {
@@ -700,7 +700,7 @@
* @return a token which can be used to cancel the operation later with {@link #cancelCommand}.
*/
// This is an asynchronous call.
- public Object setAudioAttributes(@NonNull AudioAttributes attributes) {
+ public @NonNull Object setAudioAttributes(@NonNull AudioAttributes attributes) {
return addTask(new Task(CALL_COMPLETED_SET_AUDIO_ATTRIBUTES, false) {
@Override
void process() {
@@ -735,7 +735,7 @@
* @return a token which can be used to cancel the operation later with {@link #cancelCommand}.
*/
// This is an asynchronous call.
- public Object setDataSource(@NonNull DataSourceDesc dsd) {
+ public @NonNull Object setDataSource(@NonNull DataSourceDesc dsd) {
return addTask(new Task(CALL_COMPLETED_SET_DATA_SOURCE, false) {
@Override
void process() throws IOException {
@@ -768,7 +768,7 @@
* @return a token which can be used to cancel the operation later with {@link #cancelCommand}.
*/
// This is an asynchronous call.
- public Object setNextDataSource(@NonNull DataSourceDesc dsd) {
+ public @NonNull Object setNextDataSource(@NonNull DataSourceDesc dsd) {
return addTask(new Task(CALL_COMPLETED_SET_NEXT_DATA_SOURCE, false) {
@Override
void process() {
@@ -791,7 +791,7 @@
* @return a token which can be used to cancel the operation later with {@link #cancelCommand}.
*/
// This is an asynchronous call.
- public Object setNextDataSources(@NonNull List<DataSourceDesc> dsds) {
+ public @NonNull Object setNextDataSources(@NonNull List<DataSourceDesc> dsds) {
return addTask(new Task(CALL_COMPLETED_SET_NEXT_DATA_SOURCES, false) {
@Override
void process() {
@@ -853,7 +853,7 @@
* @return a token which can be used to cancel the operation later with {@link #cancelCommand}.
*/
// This is an asynchronous call.
- public Object clearNextDataSources() {
+ public @NonNull Object clearNextDataSources() {
return addTask(new Task(CALL_COMPLETED_CLEAR_NEXT_DATA_SOURCES, false) {
@Override
void process() {
@@ -1194,7 +1194,7 @@
* @return a token which can be used to cancel the operation later with {@link #cancelCommand}.
*/
// This is an asynchronous call.
- public Object loopCurrent(boolean loop) {
+ public @NonNull Object loopCurrent(boolean loop) {
return addTask(new Task(CALL_COMPLETED_LOOP_CURRENT, false) {
@Override
void process() {
@@ -1216,7 +1216,7 @@
* @return a token which can be used to cancel the operation later with {@link #cancelCommand}.
*/
// This is an asynchronous call.
- public Object setPlayerVolume(float volume) {
+ public @NonNull Object setPlayerVolume(float volume) {
return addTask(new Task(CALL_COMPLETED_SET_PLAYER_VOLUME, false) {
@Override
void process() {
@@ -1257,7 +1257,7 @@
* @return a token which can be used to cancel the operation later with {@link #cancelCommand}.
*/
// This is an asynchronous call.
- public Object notifyWhenCommandLabelReached(@NonNull Object label) {
+ public @NonNull Object notifyWhenCommandLabelReached(@NonNull Object label) {
return addTask(new Task(CALL_COMPLETED_NOTIFY_WHEN_COMMAND_LABEL_REACHED, false) {
@Override
void process() {
@@ -1285,7 +1285,7 @@
* @param sh the SurfaceHolder to use for video display
* @return a token which can be used to cancel the operation later with {@link #cancelCommand}.
*/
- public Object setDisplay(SurfaceHolder sh) {
+ public @NonNull Object setDisplay(@Nullable SurfaceHolder sh) {
return addTask(new Task(CALL_COMPLETED_SET_DISPLAY, false) {
@Override
void process() {
@@ -1321,7 +1321,7 @@
* @return a token which can be used to cancel the operation later with {@link #cancelCommand}.
*/
// This is an asynchronous call.
- public Object setSurface(Surface surface) {
+ public @NonNull Object setSurface(@Nullable Surface surface) {
return addTask(new Task(CALL_COMPLETED_SET_SURFACE, false) {
@Override
void process() {
@@ -1355,7 +1355,7 @@
* @see android.os.PowerManager
*/
// This is an asynchronous call.
- public Object setWakeLock(@NonNull PowerManager.WakeLock wakeLock) {
+ public @NonNull Object setWakeLock(@NonNull PowerManager.WakeLock wakeLock) {
return addTask(new Task(CALL_COMPLETED_SET_WAKE_LOCK, false) {
@Override
void process() {
@@ -1390,7 +1390,7 @@
* @return a token which can be used to cancel the operation later with {@link #cancelCommand}.
*/
// This is an asynchronous call.
- public Object setScreenOnWhilePlaying(boolean screenOn) {
+ public @NonNull Object setScreenOnWhilePlaying(boolean screenOn) {
return addTask(new Task(CALL_COMPLETED_SET_SCREEN_ON_WHILE_PLAYING, false) {
@Override
void process() {
@@ -1466,7 +1466,7 @@
*/
// This is a synchronous call.
@Override
- public boolean setPreferredDevice(AudioDeviceInfo deviceInfo) {
+ public boolean setPreferredDevice(@Nullable AudioDeviceInfo deviceInfo) {
boolean status = native_setPreferredDevice(deviceInfo);
if (status) {
synchronized (this) {
@@ -1483,7 +1483,7 @@
* is not guaranteed to correspond to the actual device being used for playback.
*/
@Override
- public AudioDeviceInfo getPreferredDevice() {
+ public @Nullable AudioDeviceInfo getPreferredDevice() {
synchronized (this) {
return mPreferredDevice;
}
@@ -1496,7 +1496,7 @@
* selected device when the player was last active.
*/
@Override
- public native AudioDeviceInfo getRoutedDevice();
+ public @Nullable native AudioDeviceInfo getRoutedDevice();
/**
* Adds an {@link AudioRouting.OnRoutingChangedListener} to receive notifications of routing
@@ -1508,8 +1508,8 @@
*/
// This is a synchronous call.
@Override
- public void addOnRoutingChangedListener(AudioRouting.OnRoutingChangedListener listener,
- Handler handler) {
+ public void addOnRoutingChangedListener(@NonNull AudioRouting.OnRoutingChangedListener listener,
+ @Nullable Handler handler) {
if (listener == null) {
throw new IllegalArgumentException("addOnRoutingChangedListener: listener is NULL");
}
@@ -1527,7 +1527,8 @@
*/
// This is a synchronous call.
@Override
- public void removeOnRoutingChangedListener(AudioRouting.OnRoutingChangedListener listener) {
+ public void removeOnRoutingChangedListener(
+ @NonNull AudioRouting.OnRoutingChangedListener listener) {
if (listener == null) {
throw new IllegalArgumentException("removeOnRoutingChangedListener: listener is NULL");
}
@@ -1547,7 +1548,7 @@
* notification {@code EventCallback.onVideoSizeChanged} when the size
* is available.
*/
- public Size getVideoSize() {
+ public @NonNull Size getVideoSize() {
return mVideoSize;
}
@@ -1560,7 +1561,7 @@
*
* Additional vendor-specific fields may also be present in the return value.
*/
- public PersistableBundle getMetrics() {
+ public @Nullable PersistableBundle getMetrics() {
PersistableBundle bundle = native_getMetrics();
return bundle;
}
@@ -1592,7 +1593,7 @@
*/
// TODO: make it public when ready
// This is an asynchronous call.
- Object setBufferingParams(@NonNull BufferingParams params) {
+ @NonNull Object setBufferingParams(@NonNull BufferingParams params) {
return addTask(new Task(CALL_COMPLETED_SET_BUFFERING_PARAMS, false) {
@Override
void process() {
@@ -1614,7 +1615,7 @@
* @return a token which can be used to cancel the operation later with {@link #cancelCommand}.
*/
// This is an asynchronous call.
- public Object setPlaybackParams(@NonNull PlaybackParams params) {
+ public @NonNull Object setPlaybackParams(@NonNull PlaybackParams params) {
return addTask(new Task(CALL_COMPLETED_SET_PLAYBACK_PARAMS, false) {
@Override
void process() {
@@ -1642,7 +1643,7 @@
* @return a token which can be used to cancel the operation later with {@link #cancelCommand}.
*/
// This is an asynchronous call.
- public Object setSyncParams(@NonNull SyncParams params) {
+ public @NonNull Object setSyncParams(@NonNull SyncParams params) {
return addTask(new Task(CALL_COMPLETED_SET_SYNC_PARAMS, false) {
@Override
void process() {
@@ -1671,7 +1672,7 @@
* @return a token which can be used to cancel the operation later with {@link #cancelCommand}.
*/
// This is an asynchronous call.
- public Object seekTo(long msec) {
+ public @NonNull Object seekTo(long msec) {
return seekTo(msec, SEEK_PREVIOUS_SYNC /* mode */);
}
@@ -1745,7 +1746,7 @@
* @return a token which can be used to cancel the operation later with {@link #cancelCommand}.
*/
// This is an asynchronous call.
- public Object seekTo(long msec, @SeekMode int mode) {
+ public @NonNull Object seekTo(long msec, @SeekMode int mode) {
return addTask(new Task(CALL_COMPLETED_SEEK_TO, true) {
@Override
void process() {
@@ -1846,7 +1847,7 @@
* @return a token which can be used to cancel the operation later with {@link #cancelCommand}.
*/
// This is an asynchronous call.
- public Object setAudioSessionId(int sessionId) {
+ public @NonNull Object setAudioSessionId(int sessionId) {
final AudioTrack dummyAudioTrack = new AudioTrack(AudioManager.STREAM_MUSIC, 44100,
AudioFormat.CHANNEL_OUT_MONO, AudioFormat.ENCODING_PCM_16BIT, 2,
AudioTrack.MODE_STATIC, sessionId);
@@ -1887,7 +1888,7 @@
* @return a token which can be used to cancel the operation later with {@link #cancelCommand}.
*/
// This is an asynchronous call.
- public Object attachAuxEffect(int effectId) {
+ public @NonNull Object attachAuxEffect(int effectId) {
return addTask(new Task(CALL_COMPLETED_ATTACH_AUX_EFFECT, false) {
@Override
void process() {
@@ -1912,7 +1913,7 @@
* @return a token which can be used to cancel the operation later with {@link #cancelCommand}.
*/
// This is an asynchronous call.
- public Object setAuxEffectSendLevel(float level) {
+ public @NonNull Object setAuxEffectSendLevel(float level) {
return addTask(new Task(CALL_COMPLETED_SET_AUX_EFFECT_SEND_LEVEL, false) {
@Override
void process() {
@@ -1984,7 +1985,7 @@
* When the language is unknown or could not be determined,
* ISO-639-2 language code, "und", is returned.
*/
- public String getLanguage() {
+ public @Nullable String getLanguage() {
String language = mFormat.getString(MediaFormat.KEY_LANGUAGE);
return language == null ? "und" : language;
}
@@ -1993,7 +1994,7 @@
* Gets the {@link MediaFormat} of the track. If the format is
* unknown or could not be determined, null is returned.
*/
- public MediaFormat getFormat() {
+ public @Nullable MediaFormat getFormat() {
if (mTrackType == MEDIA_TRACK_TYPE_TIMEDTEXT
|| mTrackType == MEDIA_TRACK_TYPE_SUBTITLE) {
return mFormat;
@@ -2201,7 +2202,7 @@
* @see MediaPlayer2#getTrackInfo()
*/
// This is an asynchronous call.
- public Object selectTrack(int index) {
+ public @NonNull Object selectTrack(int index) {
return selectTrack(getCurrentDataSource(), index);
}
@@ -2235,7 +2236,7 @@
* @see MediaPlayer2#getTrackInfo(DataSourceDesc)
*/
// This is an asynchronous call.
- public Object selectTrack(@NonNull DataSourceDesc dsd, int index) {
+ public @NonNull Object selectTrack(@NonNull DataSourceDesc dsd, int index) {
return addTask(new Task(CALL_COMPLETED_SELECT_TRACK, false) {
@Override
void process() {
@@ -2257,7 +2258,7 @@
* @see MediaPlayer2#getTrackInfo()
*/
// This is an asynchronous call.
- public Object deselectTrack(int index) {
+ public @NonNull Object deselectTrack(int index) {
return deselectTrack(getCurrentDataSource(), index);
}
@@ -2277,7 +2278,7 @@
* @see MediaPlayer2#getTrackInfo(DataSourceDesc)
*/
// This is an asynchronous call.
- public Object deselectTrack(@NonNull DataSourceDesc dsd, int index) {
+ public @NonNull Object deselectTrack(@NonNull DataSourceDesc dsd, int index) {
return addTask(new Task(CALL_COMPLETED_DESELECT_TRACK, false) {
@Override
void process() {
@@ -2928,7 +2929,7 @@
* @param eventCallback the callback to be unregistered
*/
// This is a synchronous call.
- public void unregisterEventCallback(EventCallback eventCallback) {
+ public void unregisterEventCallback(@NonNull EventCallback eventCallback) {
synchronized (mEventCbLock) {
for (Pair<Executor, EventCallback> cb : mEventCallbackRecords) {
if (cb.second == eventCallback) {
@@ -3850,7 +3851,7 @@
*/
// This is an asynchronous call.
@TestApi
- public Object prepareDrm(@NonNull DataSourceDesc dsd, @NonNull UUID uuid) {
+ public @NonNull Object prepareDrm(@NonNull DataSourceDesc dsd, @NonNull UUID uuid) {
return addTask(newPrepareDrmTask(dsd, uuid));
}
diff --git a/media/apex/java/android/media/UriDataSourceDesc.java b/media/apex/java/android/media/UriDataSourceDesc.java
index 4eb9e8d..c0b3c82 100644
--- a/media/apex/java/android/media/UriDataSourceDesc.java
+++ b/media/apex/java/android/media/UriDataSourceDesc.java
@@ -51,7 +51,7 @@
* Return the Uri of this data source.
* @return the Uri of this data source
*/
- public Uri getUri() {
+ public @NonNull Uri getUri() {
return mUri;
}
@@ -59,7 +59,7 @@
* Return the Uri headers of this data source.
* @return the Uri headers of this data source
*/
- public Map<String, String> getHeaders() {
+ public @Nullable Map<String, String> getHeaders() {
if (mHeader == null) {
return null;
}
@@ -70,7 +70,7 @@
* Return the Uri cookies of this data source.
* @return the Uri cookies of this data source
*/
- public List<HttpCookie> getCookies() {
+ public @Nullable List<HttpCookie> getCookies() {
if (mCookies == null) {
return null;
}
@@ -81,7 +81,7 @@
* Return the Context used for resolving the Uri of this data source.
* @return the Context used for resolving the Uri of this data source
*/
- public Context getContext() {
+ public @NonNull Context getContext() {
return mContext;
}
@@ -117,7 +117,7 @@
* @param dsd the {@link UriDataSourceDesc} object whose data will be reused
* in the new Builder.
*/
- public Builder(UriDataSourceDesc dsd) {
+ public Builder(@Nullable UriDataSourceDesc dsd) {
super(dsd);
if (dsd == null) {
return; // use default
@@ -136,6 +136,11 @@
* @return a new {@link UriDataSourceDesc} object
*/
public @NonNull UriDataSourceDesc build() {
+ if (mUri == null || mContext == null) {
+ throw new IllegalStateException(
+ "Uri and Context should not be null");
+ }
+
UriDataSourceDesc dsd = new UriDataSourceDesc();
super.build(dsd);
dsd.mUri = mUri;
diff --git a/media/java/android/media/AudioTrack.java b/media/java/android/media/AudioTrack.java
index 3bb696b..7cfe0dd 100644
--- a/media/java/android/media/AudioTrack.java
+++ b/media/java/android/media/AudioTrack.java
@@ -3168,7 +3168,8 @@
* @param sizeInFrames the number of frames available to write without blocking.
* Note that the frame size of a compressed stream is 1 byte.
*/
- public void onDataRequest(@NonNull AudioTrack track, int sizeInFrames) { }
+ public void onDataRequest(@NonNull AudioTrack track, @IntRange(from = 0) int sizeInFrames) {
+ }
}
/**
diff --git a/media/java/android/media/MediaTimestamp.java b/media/java/android/media/MediaTimestamp.java
index 03e454c..da3362a 100644
--- a/media/java/android/media/MediaTimestamp.java
+++ b/media/java/android/media/MediaTimestamp.java
@@ -134,7 +134,7 @@
* @hide
*/
@SystemApi
- public static class Builder {
+ public static final class Builder {
long mMediaTimeUs;
long mNanoTime;
float mClockRate = 1.0f;
diff --git a/media/java/android/media/SubtitleData.java b/media/java/android/media/SubtitleData.java
index 852babe..31622a9 100644
--- a/media/java/android/media/SubtitleData.java
+++ b/media/java/android/media/SubtitleData.java
@@ -155,7 +155,7 @@
* @hide
*/
@SystemApi
- public static class Builder {
+ public static final class Builder {
private int mTrackIndex;
private long mStartTimeUs;
private long mDurationUs;
diff --git a/media/java/android/media/TimedMetaData.java b/media/java/android/media/TimedMetaData.java
index 2a89888..990760c 100644
--- a/media/java/android/media/TimedMetaData.java
+++ b/media/java/android/media/TimedMetaData.java
@@ -104,7 +104,7 @@
* @hide
*/
@SystemApi
- public static class Builder {
+ public static final class Builder {
private long mTimestampUs;
private byte[] mMetaData = new byte[0];
diff --git a/media/tests/MediaFrameworkTest/Android.mk b/media/tests/MediaFrameworkTest/Android.mk
index fb473f0..167d255 100644
--- a/media/tests/MediaFrameworkTest/Android.mk
+++ b/media/tests/MediaFrameworkTest/Android.mk
@@ -9,7 +9,7 @@
LOCAL_STATIC_JAVA_LIBRARIES := \
mockito-target-minus-junit4 \
- android-support-test \
+ androidx.test.rules \
android-ex-camera2
LOCAL_PACKAGE_NAME := mediaframeworktest
diff --git a/media/tests/MediaFrameworkTest/AndroidManifest.xml b/media/tests/MediaFrameworkTest/AndroidManifest.xml
index e50a375..fb2d630 100644
--- a/media/tests/MediaFrameworkTest/AndroidManifest.xml
+++ b/media/tests/MediaFrameworkTest/AndroidManifest.xml
@@ -86,7 +86,7 @@
android:label="MediaFramework integration tests InstrumentationRunner">
</instrumentation>
- <instrumentation android:name="android.support.test.runner.AndroidJUnitRunner"
+ <instrumentation android:name="androidx.test.runner.AndroidJUnitRunner"
android:targetPackage="com.android.mediaframeworktest"
android:label="media framework tests">
</instrumentation>
diff --git a/media/tests/MediaFrameworkTest/AndroidTest.xml b/media/tests/MediaFrameworkTest/AndroidTest.xml
index 204959f..132028c 100644
--- a/media/tests/MediaFrameworkTest/AndroidTest.xml
+++ b/media/tests/MediaFrameworkTest/AndroidTest.xml
@@ -21,7 +21,7 @@
<option name="test-tag" value="MediaFrameworkTest" />
<test class="com.android.tradefed.testtype.AndroidJUnitTest" >
<option name="package" value="com.android.mediaframeworktest" />
- <option name="runner" value="android.support.test.runner.AndroidJUnitRunner" />
+ <option name="runner" value="androidx.test.runner.AndroidJUnitRunner" />
<option name="hidden-api-checks" value="false"/>
</test>
</configuration>
diff --git a/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/integration/CameraBinderTest.java b/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/integration/CameraBinderTest.java
index d8c975f..87a59df 100644
--- a/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/integration/CameraBinderTest.java
+++ b/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/integration/CameraBinderTest.java
@@ -309,6 +309,10 @@
Log.v(TAG, String.format("Camera %s has torch status changed to 0x%x",
cameraId, status));
}
+ @Override
+ public void onCameraAccessPrioritiesChanged() {
+ Log.v(TAG, "Camera access permission change");
+ }
}
/**
diff --git a/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/unit/MediaFileTest.java b/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/unit/MediaFileTest.java
index feac63d..701454c 100644
--- a/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/unit/MediaFileTest.java
+++ b/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/unit/MediaFileTest.java
@@ -28,7 +28,8 @@
import static org.junit.Assert.assertTrue;
import android.mtp.MtpConstants;
-import android.support.test.runner.AndroidJUnit4;
+
+import androidx.test.runner.AndroidJUnit4;
import libcore.net.MimeUtils;
diff --git a/packages/SettingsLib/src/com/android/settingslib/location/RecentLocationAccesses.java b/packages/SettingsLib/src/com/android/settingslib/location/RecentLocationAccesses.java
index 4ac3ce4..09107ce 100644
--- a/packages/SettingsLib/src/com/android/settingslib/location/RecentLocationAccesses.java
+++ b/packages/SettingsLib/src/com/android/settingslib/location/RecentLocationAccesses.java
@@ -48,6 +48,11 @@
// Keep last 24 hours of location app information.
private static final long RECENT_TIME_INTERVAL_MILLIS = DateUtils.DAY_IN_MILLIS;
+ /** The flags for querying ops that are trusted for showing in the UI. */
+ public static final int TRUSTED_STATE_FLAGS = AppOpsManager.OP_FLAG_SELF
+ | AppOpsManager.OP_FLAG_UNTRUSTED_PROXY
+ | AppOpsManager.OP_FLAG_TRUSTED_PROXIED;
+
@VisibleForTesting
static final int[] LOCATION_OPS = new int[]{
AppOpsManager.OP_FINE_LOCATION,
@@ -136,8 +141,7 @@
// Earliest time for a location access to end and still be shown in list.
long recentLocationCutoffTime = now - RECENT_TIME_INTERVAL_MILLIS;
for (AppOpsManager.OpEntry entry : entries) {
- locationAccessFinishTime = Math.max(entry.getLastAccessBackgroundTime(),
- entry.getLastAccessForegroundTime());
+ locationAccessFinishTime = entry.getLastAccessTime(TRUSTED_STATE_FLAGS);
}
// Bail out if the entry is out of date.
if (locationAccessFinishTime < recentLocationCutoffTime) {
diff --git a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/location/RecentLocationAccessesTest.java b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/location/RecentLocationAccessesTest.java
index d5b89ca..c1c5fa9 100644
--- a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/location/RecentLocationAccessesTest.java
+++ b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/location/RecentLocationAccessesTest.java
@@ -17,6 +17,7 @@
import android.os.UserHandle;
import android.os.UserManager;
+import android.util.LongSparseLongArray;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
@@ -152,11 +153,12 @@
}
private OpEntry createOpEntryWithTime(int op, long time) {
- final long[] times = new long[AppOpsManager._NUM_UID_STATE];
// Slot for background access timestamp.
- times[AppOpsManager.UID_STATE_LAST_NON_RESTRICTED + 1] = time;
- final long[] rejectTimes = new long[AppOpsManager._NUM_UID_STATE];
- return new OpEntry(op, AppOpsManager.MODE_ALLOWED, times, rejectTimes, 0 /* duration */,
- 0 /* proxyUid */, "" /* proxyPackage */);
+ final LongSparseLongArray accessTimes = new LongSparseLongArray();
+ accessTimes.put(AppOpsManager.makeKey(AppOpsManager.UID_STATE_BACKGROUND,
+ AppOpsManager.OP_FLAG_SELF), time);
+
+ return new OpEntry(op, false, AppOpsManager.MODE_ALLOWED, accessTimes, null /*durations*/,
+ null /*rejectTimes*/, null /* proxyUids */, null /* proxyPackages */);
}
}
diff --git a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/location/RecentLocationAppsTest.java b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/location/RecentLocationAppsTest.java
index 08d5367..8bd5fd2 100644
--- a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/location/RecentLocationAppsTest.java
+++ b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/location/RecentLocationAppsTest.java
@@ -17,6 +17,7 @@
import android.os.UserHandle;
import android.os.UserManager;
+import android.util.LongSparseLongArray;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
@@ -153,6 +154,13 @@
}
private OpEntry createOpEntryWithTime(int op, long time, int duration) {
- return new OpEntry(op, AppOpsManager.MODE_ALLOWED, time, 0L, duration, 0, "");
+ final LongSparseLongArray accessTimes = new LongSparseLongArray();
+ accessTimes.put(AppOpsManager.makeKey(AppOpsManager.UID_STATE_TOP,
+ AppOpsManager.OP_FLAG_SELF), time);
+ final LongSparseLongArray durations = new LongSparseLongArray();
+ durations.put(AppOpsManager.makeKey(AppOpsManager.UID_STATE_TOP,
+ AppOpsManager.OP_FLAG_SELF), duration);
+ return new OpEntry(op, false, AppOpsManager.MODE_ALLOWED, accessTimes,
+ null /*rejectTimes*/, durations, null /* proxyUids */, null /* proxyPackages */);
}
}
diff --git a/packages/SystemUI/res/layout/quick_settings_footer_dialog.xml b/packages/SystemUI/res/layout/quick_settings_footer_dialog.xml
index 5bcc1b3..b969a15 100644
--- a/packages/SystemUI/res/layout/quick_settings_footer_dialog.xml
+++ b/packages/SystemUI/res/layout/quick_settings_footer_dialog.xml
@@ -39,17 +39,14 @@
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="@string/monitoring_title_device_owned"
- style="@style/TextAppearance.DeviceManagementDialog.Title"
- android:textColor="?android:attr/textColorPrimary"
+ style="@style/DeviceManagementDialogTitle"
android:paddingBottom="@dimen/qs_footer_dialog_subtitle_padding"
/>
<TextView
android:id="@+id/device_management_warning"
android:layout_width="match_parent"
android:layout_height="wrap_content"
- android:text="@null"
- style="@android:style/TextAppearance.Material.Subhead"
- android:textColor="?android:attr/textColorPrimary"
+ android:textAppearance="@style/TextAppearance.DeviceManagementDialog.Content"
/>
</LinearLayout>
@@ -64,17 +61,14 @@
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="@string/monitoring_subtitle_ca_certificate"
- style="@style/TextAppearance.DeviceManagementDialog.Title"
- android:textColor="?android:attr/textColorPrimary"
+ style="@style/DeviceManagementDialogTitle"
android:paddingBottom="@dimen/qs_footer_dialog_subtitle_padding"
/>
<TextView
android:id="@+id/ca_certs_warning"
android:layout_width="match_parent"
android:layout_height="wrap_content"
- android:text="@null"
- style="@android:style/TextAppearance.Material.Subhead"
- android:textColor="?android:attr/textColorPrimary"
+ android:textAppearance="@style/TextAppearance.DeviceManagementDialog.Content"
/>
</LinearLayout>
@@ -89,17 +83,14 @@
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="@string/monitoring_subtitle_network_logging"
- style="@style/TextAppearance.DeviceManagementDialog.Title"
- android:textColor="?android:attr/textColorPrimary"
+ style="@style/DeviceManagementDialogTitle"
android:paddingBottom="@dimen/qs_footer_dialog_subtitle_padding"
/>
<TextView
android:id="@+id/network_logging_warning"
android:layout_width="match_parent"
android:layout_height="wrap_content"
- android:text="@null"
- style="@android:style/TextAppearance.Material.Subhead"
- android:textColor="?android:attr/textColorPrimary"
+ android:textAppearance="@style/TextAppearance.DeviceManagementDialog.Content"
/>
</LinearLayout>
@@ -114,17 +105,14 @@
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="@string/monitoring_subtitle_vpn"
- style="@style/TextAppearance.DeviceManagementDialog.Title"
- android:textColor="?android:attr/textColorPrimary"
+ style="@style/DeviceManagementDialogTitle"
android:paddingBottom="@dimen/qs_footer_dialog_subtitle_padding"
/>
<TextView
android:id="@+id/vpn_warning"
android:layout_width="match_parent"
android:layout_height="wrap_content"
- android:text="@null"
- style="@android:style/TextAppearance.Material.Subhead"
- android:textColor="?android:attr/textColorPrimary"
+ android:textAppearance="@style/TextAppearance.DeviceManagementDialog.Content"
/>
</LinearLayout>
</LinearLayout>
diff --git a/packages/SystemUI/res/layout/screen_pinning_request_text_area.xml b/packages/SystemUI/res/layout/screen_pinning_request_text_area.xml
index cdad94b..8dcddc2 100644
--- a/packages/SystemUI/res/layout/screen_pinning_request_text_area.xml
+++ b/packages/SystemUI/res/layout/screen_pinning_request_text_area.xml
@@ -31,7 +31,7 @@
android:paddingStart="48dp"
android:paddingTop="43dp"
android:text="@string/screen_pinning_title"
- android:textColor="@color/screen_pinning_primary_text"
+ android:textColor="@android:color/white"
android:textSize="24sp" />
<TextView
@@ -43,7 +43,7 @@
android:paddingStart="48dp"
android:paddingTop="12.6dp"
android:text="@string/screen_pinning_description"
- android:textColor="@color/screen_pinning_primary_text"
+ android:textColor="@android:color/white"
android:textSize="16sp" />
<Button
diff --git a/packages/SystemUI/res/values/internal.xml b/packages/SystemUI/res/values/internal.xml
index e0d3cd2..930cfce 100644
--- a/packages/SystemUI/res/values/internal.xml
+++ b/packages/SystemUI/res/values/internal.xml
@@ -18,6 +18,5 @@
<dimen name="status_bar_height">@*android:dimen/status_bar_height</dimen>
<dimen name="navigation_bar_height">@*android:dimen/navigation_bar_height</dimen>
<dimen name="navigation_bar_height_car_mode">@*android:dimen/navigation_bar_height_car_mode</dimen>
- <color name="screen_pinning_primary_text">@*android:color/primary_text_default_material_light</color>
</resources>
diff --git a/packages/SystemUI/res/values/styles.xml b/packages/SystemUI/res/values/styles.xml
index 30dbc8b..2cd2c43 100644
--- a/packages/SystemUI/res/values/styles.xml
+++ b/packages/SystemUI/res/values/styles.xml
@@ -239,10 +239,19 @@
<item name="android:fontFamily">@*android:string/config_bodyFontFamily</item>
</style>
- <style name="TextAppearance.DeviceManagementDialog.Title" parent="@android:style/TextAppearance.DeviceDefault.DialogWindowTitle">
- <item name="android:gravity">center</item>
+ <style name="TextAppearance.DeviceManagementDialog">
+ <item name="android:textColor">?android:attr/textColorPrimary</item>
</style>
+ <style name="TextAppearance.DeviceManagementDialog.Title" parent="@android:style/TextAppearance.DeviceDefault.DialogWindowTitle"/>
+
+ <style name="DeviceManagementDialogTitle">
+ <item name="android:gravity">center</item>
+ <item name="android:textAppearance">@style/TextAppearance.DeviceManagementDialog.Title</item>
+ </style>
+
+ <style name="TextAppearance.DeviceManagementDialog.Content" parent="@*android:style/TextAppearance.DeviceDefault.Subhead"/>
+
<style name="BaseBrightnessDialogContainer" parent="@style/Theme.SystemUI">
<item name="android:layout_width">match_parent</item>
<item name="android:layout_height">wrap_content</item>
diff --git a/packages/SystemUI/src/com/android/systemui/qs/customize/TileQueryHelper.java b/packages/SystemUI/src/com/android/systemui/qs/customize/TileQueryHelper.java
index 4dcacd4..7006249 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/customize/TileQueryHelper.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/customize/TileQueryHelper.java
@@ -27,6 +27,7 @@
import android.os.Build;
import android.os.Handler;
import android.provider.Settings;
+import android.service.quicksettings.Tile;
import android.service.quicksettings.TileService;
import android.text.TextUtils;
import android.util.ArraySet;
@@ -166,7 +167,8 @@
icon.mutate();
icon.setTint(mContext.getColor(android.R.color.white));
CharSequence label = info.serviceInfo.loadLabel(pm);
- addTile(spec, icon, label != null ? label.toString() : "null", appLabel);
+ createStateAndAddTile(spec, icon, label != null ? label.toString() : "null",
+ appLabel);
}
notifyTilesChanged(true);
@@ -207,9 +209,10 @@
mSpecs.add(spec);
}
- private void addTile(
+ private void createStateAndAddTile(
String spec, Drawable drawable, CharSequence label, CharSequence appLabel) {
QSTile.State state = new QSTile.State();
+ state.state = Tile.STATE_INACTIVE;
state.label = label;
state.contentDescription = label;
state.icon = new DrawableIcon(drawable);
diff --git a/packages/SystemUI/tests/src/com/android/systemui/qs/customize/TileQueryHelperTest.java b/packages/SystemUI/tests/src/com/android/systemui/qs/customize/TileQueryHelperTest.java
index 12eed78..9e226f6 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/qs/customize/TileQueryHelperTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/qs/customize/TileQueryHelperTest.java
@@ -14,12 +14,14 @@
package com.android.systemui.qs.customize;
+import static junit.framework.Assert.assertEquals;
import static junit.framework.Assert.assertTrue;
import static org.hamcrest.Matchers.equalTo;
import static org.hamcrest.Matchers.is;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertThat;
+import static org.mockito.ArgumentMatchers.anyInt;
import static org.mockito.ArgumentMatchers.anyString;
import static org.mockito.Mockito.any;
import static org.mockito.Mockito.atLeastOnce;
@@ -29,8 +31,13 @@
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
+import android.Manifest;
+import android.content.pm.ApplicationInfo;
import android.content.pm.PackageManager;
+import android.content.pm.ResolveInfo;
+import android.content.pm.ServiceInfo;
import android.provider.Settings;
+import android.service.quicksettings.Tile;
import android.testing.AndroidTestingRunner;
import android.testing.TestableLooper;
import android.testing.TestableLooper.RunWithLooper;
@@ -48,7 +55,9 @@
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
+import org.mockito.Answers;
import org.mockito.ArgumentCaptor;
+import org.mockito.Captor;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
@@ -68,6 +77,8 @@
private static final String STOCK_TILES = "wifi,dnd,cell,battery";
private static final String ALL_TILES = "wifi,dnd,nfc,cell,battery";
private static final Set<String> FACTORY_TILES = new ArraySet<>();
+ private static final String TEST_PKG = "test_pkg";
+ private static final String TEST_CLS = "test_cls";
static {
FACTORY_TILES.addAll(Arrays.asList(
@@ -82,6 +93,8 @@
private QSTileHost mQSTileHost;
@Mock
private PackageManager mPackageManager;
+ @Captor
+ private ArgumentCaptor<List<TileQueryHelper.TileInfo>> mCaptor;
private QSTile.State mState;
private TestableLooper mBGLooper;
@@ -154,8 +167,6 @@
@Test
public void testQueryTiles_correctTilesAndOrderOnlyStockTiles() {
- ArgumentCaptor<List<TileQueryHelper.TileInfo>> captor = ArgumentCaptor.forClass(List.class);
-
Settings.Secure.putString(mContext.getContentResolver(), Settings.Secure.QS_TILES,
ONLY_STOCK_TILES);
mContext.getOrCreateTestableResources().addOverride(R.string.quick_settings_tiles_stock,
@@ -166,9 +177,9 @@
mBGLooper.processAllMessages();
waitForIdleSync(Dependency.get(Dependency.MAIN_HANDLER));
- verify(mListener, atLeastOnce()).onTilesChanged(captor.capture());
+ verify(mListener, atLeastOnce()).onTilesChanged(mCaptor.capture());
List<String> specs = new ArrayList<>();
- for (TileQueryHelper.TileInfo t : captor.getValue()) {
+ for (TileQueryHelper.TileInfo t : mCaptor.getValue()) {
specs.add(t.spec);
}
String tiles = TextUtils.join(",", specs);
@@ -177,8 +188,6 @@
@Test
public void testQueryTiles_correctTilesAndOrderOtherFactoryTiles() {
- ArgumentCaptor<List<TileQueryHelper.TileInfo>> captor = ArgumentCaptor.forClass(List.class);
-
Settings.Secure.putString(mContext.getContentResolver(), Settings.Secure.QS_TILES,
CURRENT_TILES);
mContext.getOrCreateTestableResources().addOverride(R.string.quick_settings_tiles_stock,
@@ -189,9 +198,9 @@
mBGLooper.processAllMessages();
waitForIdleSync(Dependency.get(Dependency.MAIN_HANDLER));
- verify(mListener, atLeastOnce()).onTilesChanged(captor.capture());
+ verify(mListener, atLeastOnce()).onTilesChanged(mCaptor.capture());
List<String> specs = new ArrayList<>();
- for (TileQueryHelper.TileInfo t : captor.getValue()) {
+ for (TileQueryHelper.TileInfo t : mCaptor.getValue()) {
specs.add(t.spec);
}
String tiles = TextUtils.join(",", specs);
@@ -200,8 +209,6 @@
@Test
public void testQueryTiles_otherTileNotIncluded() {
- ArgumentCaptor<List<TileQueryHelper.TileInfo>> captor = ArgumentCaptor.forClass(List.class);
-
Settings.Secure.putString(mContext.getContentResolver(), Settings.Secure.QS_TILES,
WITH_OTHER_TILES);
mContext.getOrCreateTestableResources().addOverride(R.string.quick_settings_tiles_stock,
@@ -212,15 +219,44 @@
mBGLooper.processAllMessages();
waitForIdleSync(Dependency.get(Dependency.MAIN_HANDLER));
- verify(mListener, atLeastOnce()).onTilesChanged(captor.capture());
+ verify(mListener, atLeastOnce()).onTilesChanged(mCaptor.capture());
List<String> specs = new ArrayList<>();
- for (TileQueryHelper.TileInfo t : captor.getValue()) {
+ for (TileQueryHelper.TileInfo t : mCaptor.getValue()) {
specs.add(t.spec);
}
assertFalse(specs.contains("other"));
}
@Test
+ public void testThirdPartyTilesInactive() {
+ ResolveInfo resolveInfo = new ResolveInfo();
+ ServiceInfo serviceInfo = mock(ServiceInfo.class, Answers.RETURNS_MOCKS);
+ resolveInfo.serviceInfo = serviceInfo;
+ serviceInfo.packageName = TEST_PKG;
+ serviceInfo.name = TEST_CLS;
+ serviceInfo.icon = R.drawable.android;
+ serviceInfo.permission = Manifest.permission.BIND_QUICK_SETTINGS_TILE;
+ serviceInfo.applicationInfo = mock(ApplicationInfo.class, Answers.RETURNS_MOCKS);
+ serviceInfo.applicationInfo.icon = R.drawable.android;
+ List<ResolveInfo> list = new ArrayList<>();
+ list.add(resolveInfo);
+ when(mPackageManager.queryIntentServicesAsUser(any(), anyInt(), anyInt())).thenReturn(list);
+
+ Settings.Secure.putString(mContext.getContentResolver(), Settings.Secure.QS_TILES, "");
+ mContext.getOrCreateTestableResources().addOverride(R.string.quick_settings_tiles_stock,
+ "");
+
+ mTileQueryHelper.queryTiles(mQSTileHost);
+ mBGLooper.processAllMessages();
+ waitForIdleSync(Dependency.get(Dependency.MAIN_HANDLER));
+
+ verify(mListener, atLeastOnce()).onTilesChanged(mCaptor.capture());
+ List<TileQueryHelper.TileInfo> tileInfos = mCaptor.getValue();
+ assertEquals(1, tileInfos.size());
+ assertEquals(Tile.STATE_INACTIVE, tileInfos.get(0).state.state);
+ }
+
+ @Test
public void testQueryTiles_nullSetting() {
Settings.Secure.putString(mContext.getContentResolver(), Settings.Secure.QS_TILES, null);
mContext.getOrCreateTestableResources().addOverride(R.string.quick_settings_tiles_stock,
diff --git a/proto/src/metrics_constants/metrics_constants.proto b/proto/src/metrics_constants/metrics_constants.proto
index 37fdabe..0a6e923 100644
--- a/proto/src/metrics_constants/metrics_constants.proto
+++ b/proto/src/metrics_constants/metrics_constants.proto
@@ -253,6 +253,13 @@
MANAGED_PROFILE = 2;
}
+ // Subtypes for showing direct sharing targets
+ enum DirectShareTargetPreviousState {
+ PREVIOUSLY_UNKNOWN = 0;
+ PREVIOUSLY_HIDDEN = 1;
+ PREVIOUSLY_VISIBLE = 2;
+ }
+
// Known visual elements: views or controls.
enum View {
// Unknown view
diff --git a/services/core/java/com/android/server/LooperStatsService.java b/services/core/java/com/android/server/LooperStatsService.java
index b423f62..965b64b 100644
--- a/services/core/java/com/android/server/LooperStatsService.java
+++ b/services/core/java/com/android/server/LooperStatsService.java
@@ -55,7 +55,7 @@
private static final String DEBUG_SYS_LOOPER_STATS_ENABLED =
"debug.sys.looper_stats_enabled";
private static final int DEFAULT_SAMPLING_INTERVAL = 1000;
- private static final int DEFAULT_ENTRIES_SIZE_CAP = 2000;
+ private static final int DEFAULT_ENTRIES_SIZE_CAP = 1500;
private static final boolean DEFAULT_ENABLED = true;
private static final boolean DEFAULT_TRACK_SCREEN_INTERACTIVE = false;
diff --git a/services/core/java/com/android/server/StorageManagerService.java b/services/core/java/com/android/server/StorageManagerService.java
index c8e8ef8..e28d484 100644
--- a/services/core/java/com/android/server/StorageManagerService.java
+++ b/services/core/java/com/android/server/StorageManagerService.java
@@ -1727,7 +1727,8 @@
final List<AppOpsManager.PackageOps> pkgs = manager.getOpsForPackage(uid, packageName, ops);
for (AppOpsManager.PackageOps pkg : CollectionUtils.emptyIfNull(pkgs)) {
for (AppOpsManager.OpEntry op : CollectionUtils.emptyIfNull(pkg.getOps())) {
- maxTime = Math.max(maxTime, op.getLastAccessTime());
+ maxTime = Math.max(maxTime, op.getLastAccessTime(
+ AppOpsManager.OP_FLAGS_ALL_TRUSTED));
}
}
return maxTime;
diff --git a/services/core/java/com/android/server/VibratorService.java b/services/core/java/com/android/server/VibratorService.java
index 545baa0..5cca159 100644
--- a/services/core/java/com/android/server/VibratorService.java
+++ b/services/core/java/com/android/server/VibratorService.java
@@ -594,8 +594,9 @@
if (mProcStatesCache.get(uid, ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND)
> ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND
&& !vib.isNotification() && !vib.isRingtone()) {
- Slog.e(TAG, "Ignoring incoming vibration as process with uid = "
- + uid + " is background");
+ Slog.e(TAG, "Ignoring incoming vibration as process with"
+ + " uid = " + uid + " is background,"
+ + " usage = " + AudioAttributes.usageToString(vib.usageHint));
return;
}
linkVibration(vib);
diff --git a/services/core/java/com/android/server/am/SettingsToPropertiesMapper.java b/services/core/java/com/android/server/am/SettingsToPropertiesMapper.java
index 894a704..5da1ce6 100644
--- a/services/core/java/com/android/server/am/SettingsToPropertiesMapper.java
+++ b/services/core/java/com/android/server/am/SettingsToPropertiesMapper.java
@@ -78,11 +78,11 @@
// permission in the corresponding .te file your feature belongs to.
@VisibleForTesting
static final String[] sDeviceConfigScopes = new String[] {
- DeviceConfig.ActivityManagerNativeBoot.NAMESPACE,
- DeviceConfig.MediaNative.NAMESPACE,
+ DeviceConfig.NAMESPACE_ACTIVITY_MANAGER_NATIVE_BOOT,
DeviceConfig.NAMESPACE_INPUT_NATIVE_BOOT,
+ DeviceConfig.NAMESPACE_MEDIA_NATIVE,
DeviceConfig.NAMESPACE_NETD_NATIVE,
- DeviceConfig.RuntimeNativeBoot.NAMESPACE,
+ DeviceConfig.NAMESPACE_RUNTIME_NATIVE_BOOT,
DeviceConfig.RuntimeNative.NAMESPACE,
};
diff --git a/services/core/java/com/android/server/appop/AppOpsService.java b/services/core/java/com/android/server/appop/AppOpsService.java
index 70c28a8..ba7288e 100644
--- a/services/core/java/com/android/server/appop/AppOpsService.java
+++ b/services/core/java/com/android/server/appop/AppOpsService.java
@@ -16,6 +16,9 @@
package com.android.server.appop;
+import static android.app.AppOpsManager.MAX_PRIORITY_UID_STATE;
+import static android.app.AppOpsManager.MIN_PRIORITY_UID_STATE;
+import static android.app.AppOpsManager.OP_FLAGS_ALL;
import static android.app.AppOpsManager.OP_NONE;
import static android.app.AppOpsManager.OP_PLAY_AUDIO;
import static android.app.AppOpsManager.UID_STATE_BACKGROUND;
@@ -23,12 +26,12 @@
import static android.app.AppOpsManager.UID_STATE_FOREGROUND;
import static android.app.AppOpsManager.UID_STATE_FOREGROUND_SERVICE;
import static android.app.AppOpsManager.UID_STATE_FOREGROUND_SERVICE_LOCATION;
-import static android.app.AppOpsManager.UID_STATE_LAST_NON_RESTRICTED;
+import static android.app.AppOpsManager.UID_STATE_MAX_LAST_NON_RESTRICTED;
import static android.app.AppOpsManager.UID_STATE_PERSISTENT;
import static android.app.AppOpsManager.UID_STATE_TOP;
-import static android.app.AppOpsManager._NUM_UID_STATE;
import static android.app.AppOpsManager.modeToName;
import static android.app.AppOpsManager.opToName;
+import static android.app.AppOpsManager.resolveFirstUnrestrictedUidState;
import android.Manifest;
import android.annotation.NonNull;
@@ -39,6 +42,9 @@
import android.app.AppOpsManager;
import android.app.AppOpsManager.HistoricalOps;
import android.app.AppOpsManager.HistoricalOpsRequest;
+import android.app.AppOpsManager.Mode;
+import android.app.AppOpsManager.OpEntry;
+import android.app.AppOpsManager.OpFlags;
import android.app.AppOpsManagerInternal;
import android.app.AppOpsManagerInternal.CheckOpsDelegate;
import android.content.BroadcastReceiver;
@@ -76,6 +82,8 @@
import android.util.ArraySet;
import android.util.AtomicFile;
import android.util.KeyValueListParser;
+import android.util.LongSparseArray;
+import android.util.LongSparseLongArray;
import android.util.Slog;
import android.util.SparseArray;
import android.util.SparseBooleanArray;
@@ -164,36 +172,6 @@
UID_STATE_CACHED, // ActivityManager.PROCESS_STATE_NONEXISTENT
};
- static final String[] UID_STATE_NAMES = new String[] {
- "pers ", // UID_STATE_PERSISTENT
- "top ", // UID_STATE_TOP
- "fgsvcl", // UID_STATE_FOREGROUND_SERVICE_LOCATION
- "fgsvc", // UID_STATE_FOREGROUND_SERVICE
- "fg ", // UID_STATE_FOREGROUND
- "bg ", // UID_STATE_BACKGROUND
- "cch ", // UID_STATE_CACHED
- };
-
- static final String[] UID_STATE_TIME_ATTRS = new String[] {
- "tp", // UID_STATE_PERSISTENT
- "tt", // UID_STATE_TOP
- "tfsl", // UID_STATE_FOREGROUND_SERVICE_LOCATION
- "tfs", // UID_STATE_FOREGROUND_SERVICE
- "tf", // UID_STATE_FOREGROUND
- "tb", // UID_STATE_BACKGROUND
- "tc", // UID_STATE_CACHED
- };
-
- static final String[] UID_STATE_REJECT_ATTRS = new String[] {
- "rp", // UID_STATE_PERSISTENT
- "rt", // UID_STATE_TOP
- "rfsl", // UID_STATE_FOREGROUND_SERVICE_LOCATION
- "rfs", // UID_STATE_FOREGROUND_SERVICE
- "rf", // UID_STATE_FOREGROUND
- "rb", // UID_STATE_BACKGROUND
- "rc", // UID_STATE_CACHED
- };
-
Context mContext;
final AtomicFile mFile;
final Handler mHandler;
@@ -355,12 +333,14 @@
public boolean isDefault() {
return (pkgOps == null || pkgOps.isEmpty())
- && (opModes == null || opModes.size() <= 0);
+ && (opModes == null || opModes.size() <= 0)
+ && (state == UID_STATE_CACHED
+ && (pendingState == UID_STATE_CACHED));
}
- int evalMode(int mode) {
+ int evalMode(int op, int mode) {
if (mode == AppOpsManager.MODE_FOREGROUND) {
- return state <= UID_STATE_LAST_NON_RESTRICTED
+ return state <= AppOpsManager.resolveLastRestrictedUidState(op)
? AppOpsManager.MODE_ALLOWED : AppOpsManager.MODE_IGNORED;
}
return mode;
@@ -425,41 +405,121 @@
}
final static class Op {
+ int op;
+ boolean running;
final UidState uidState;
- final int uid;
- final String packageName;
- final int op;
- int proxyUid = -1;
- String proxyPackageName;
- int mode;
- int duration;
- long time[] = new long[_NUM_UID_STATE];
- long rejectTime[] = new long[_NUM_UID_STATE];
+ final @NonNull String packageName;
+
+ private @Mode int mode;
+ private @Nullable LongSparseLongArray mAccessTimes;
+ private @Nullable LongSparseLongArray mRejectTimes;
+ private @Nullable LongSparseLongArray mDurations;
+ private @Nullable LongSparseLongArray mProxyUids;
+ private @Nullable LongSparseArray<String> mProxyPackageNames;
+
int startNesting;
long startRealtime;
- Op(UidState _uidState, String _packageName, int _op) {
- uidState = _uidState;
- uid = _uidState.uid;
- packageName = _packageName;
- op = _op;
- mode = AppOpsManager.opToDefaultMode(op);
- }
-
- boolean hasAnyTime() {
- for (int i = 0; i < AppOpsManager._NUM_UID_STATE; i++) {
- if (time[i] != 0) {
- return true;
- }
- if (rejectTime[i] != 0) {
- return true;
- }
- }
- return false;
+ Op(UidState uidState, String packageName, int op) {
+ this.op = op;
+ this.uidState = uidState;
+ this.packageName = packageName;
+ this.mode = AppOpsManager.opToDefaultMode(op);
}
int getMode() {
- return uidState.evalMode(mode);
+ return mode;
+ }
+
+ int evalMode() {
+ return uidState.evalMode(op, mode);
+ }
+
+ /** @hide */
+ public void accessed(long time, int proxyUid, @Nullable String proxyPackageName,
+ @AppOpsManager.UidState int uidState, @OpFlags int flags) {
+ final long key = AppOpsManager.makeKey(uidState, flags);
+ if (mAccessTimes == null) {
+ mAccessTimes = new LongSparseLongArray();
+ }
+ mAccessTimes.put(key, time);
+ updateProxyState(key, proxyUid, proxyPackageName);
+ if (mDurations != null) {
+ mDurations.delete(key);
+ }
+ }
+
+ /** @hide */
+ public void rejected(long time, int proxyUid, @Nullable String proxyPackageName,
+ @AppOpsManager.UidState int uidState, @OpFlags int flags) {
+ final long key = AppOpsManager.makeKey(uidState, flags);
+ if (mRejectTimes == null) {
+ mRejectTimes = new LongSparseLongArray();
+ }
+ mRejectTimes.put(key, time);
+ updateProxyState(key, proxyUid, proxyPackageName);
+ if (mDurations != null) {
+ mDurations.delete(key);
+ }
+ }
+
+ /** @hide */
+ public void started(long time, @AppOpsManager.UidState int uidState, @OpFlags int flags) {
+ updateAccessTimeAndDuration(time, -1 /*duration*/, uidState, flags);
+ running = true;
+ }
+
+ /** @hide */
+ public void finished(long time, long duration, @AppOpsManager.UidState int uidState,
+ @OpFlags int flags) {
+ updateAccessTimeAndDuration(time, duration, uidState, flags);
+ running = false;
+ }
+
+ /** @hide */
+ public void running(long time, long duration, @AppOpsManager.UidState int uidState,
+ @OpFlags int flags) {
+ updateAccessTimeAndDuration(time, duration, uidState, flags);
+ }
+
+ /** @hide */
+ public void continuing(long duration, @AppOpsManager.UidState int uidState,
+ @OpFlags int flags) {
+ final long key = AppOpsManager.makeKey(uidState, flags);
+ if (mDurations == null) {
+ mDurations = new LongSparseLongArray();
+ }
+ mDurations.put(key, duration);
+ }
+
+ private void updateAccessTimeAndDuration(long time, long duration,
+ @AppOpsManager.UidState int uidState, @OpFlags int flags) {
+ final long key = AppOpsManager.makeKey(uidState, flags);
+ if (mAccessTimes == null) {
+ mAccessTimes = new LongSparseLongArray();
+ }
+ mAccessTimes.put(key, time);
+ if (mDurations == null) {
+ mDurations = new LongSparseLongArray();
+ }
+ mDurations.put(key, duration);
+ }
+
+ private void updateProxyState(long key, int proxyUid,
+ @Nullable String proxyPackageName) {
+ if (mProxyUids == null) {
+ mProxyUids = new LongSparseLongArray();
+ }
+ mProxyUids.put(key, proxyUid);
+ if (mProxyPackageNames == null) {
+ mProxyPackageNames = new LongSparseArray<>();
+ }
+ mProxyPackageNames.put(key, proxyPackageName);
+ }
+
+ boolean hasAnyTime() {
+ return (mAccessTimes != null && mAccessTimes.size() > 0)
+ || (mRejectTimes != null && mRejectTimes.size() > 0);
}
}
@@ -812,7 +872,7 @@
final int opCount = client.mStartedOps.size();
for (int j = opCount - 1; j >= 0; j--) {
final Op op = client.mStartedOps.get(j);
- if (uid == op.uid && packageName.equals(op.packageName)) {
+ if (uid == op.uidState.uid && packageName.equals(op.packageName)) {
finishOperationLocked(op, /*finishNested*/ true);
client.mStartedOps.remove(j);
if (op.startNesting <= 0) {
@@ -829,9 +889,9 @@
final int opCount = ops.size();
for (int i = 0; i < opCount; i++) {
final Op op = ops.valueAt(i);
- if (op.duration == -1) {
+ if (op.running) {
scheduleOpActiveChangedIfNeededLocked(
- op.op, op.uid, op.packageName, false);
+ op.op, op.uidState.uid, op.packageName, false);
}
}
}
@@ -854,7 +914,7 @@
if (uidState != null && uidState.pendingState != newState) {
final int oldPendingState = uidState.pendingState;
uidState.pendingState = newState;
- if (newState < uidState.state || newState <= UID_STATE_LAST_NON_RESTRICTED) {
+ if (newState < uidState.state || newState <= UID_STATE_MAX_LAST_NON_RESTRICTED) {
// We are moving to a more important state, or the new state is in the
// foreground, then always do it immediately.
commitUidPendingStateLocked(uidState);
@@ -880,8 +940,18 @@
for (int j = ops.size() - 1; j >= 0; j--) {
final Op op = ops.valueAt(j);
if (op.startNesting > 0) {
- op.time[oldPendingState] = now;
- op.time[newState] = now;
+ final long duration = SystemClock.elapsedRealtime()
+ - op.startRealtime;
+ // We don't support proxy long running ops (start/stop)
+ mHistoricalRegistry.increaseOpAccessDuration(op.op,
+ op.uidState.uid, op.packageName, oldPendingState,
+ AppOpsManager.OP_FLAG_SELF, duration);
+ // Finish the op in the old state
+ op.finished(now, duration, oldPendingState,
+ AppOpsManager.OP_FLAG_SELF);
+ // Start the op in the new state
+ op.startRealtime = now;
+ op.started(now, newState, AppOpsManager.OP_FLAG_SELF);
}
}
}
@@ -911,13 +981,7 @@
resOps = new ArrayList<>();
for (int j=0; j<pkgOps.size(); j++) {
Op curOp = pkgOps.valueAt(j);
- final boolean running = curOp.duration == -1;
- long duration = running
- ? (elapsedNow - curOp.startRealtime)
- : curOp.duration;
- resOps.add(new AppOpsManager.OpEntry(curOp.op, curOp.mode, curOp.time,
- curOp.rejectTime, (int) duration, running, curOp.proxyUid,
- curOp.proxyPackageName));
+ resOps.add(getOpEntryForResult(curOp, elapsedNow));
}
} else {
for (int j=0; j<ops.length; j++) {
@@ -926,13 +990,7 @@
if (resOps == null) {
resOps = new ArrayList<>();
}
- final boolean running = curOp.duration == -1;
- final long duration = running
- ? (elapsedNow - curOp.startRealtime)
- : curOp.duration;
- resOps.add(new AppOpsManager.OpEntry(curOp.op, curOp.mode, curOp.time,
- curOp.rejectTime, (int) duration, running, curOp.proxyUid,
- curOp.proxyPackageName));
+ resOps.add(getOpEntryForResult(curOp, elapsedNow));
}
}
}
@@ -947,8 +1005,7 @@
if (ops == null) {
resOps = new ArrayList<>();
for (int j=0; j<uidOps.size(); j++) {
- resOps.add(new AppOpsManager.OpEntry(uidOps.keyAt(j), uidOps.valueAt(j),
- 0, 0, 0, -1, null));
+ resOps.add(new OpEntry(uidOps.keyAt(j), uidOps.valueAt(j)));
}
} else {
for (int j=0; j<ops.length; j++) {
@@ -957,14 +1014,27 @@
if (resOps == null) {
resOps = new ArrayList<>();
}
- resOps.add(new AppOpsManager.OpEntry(uidOps.keyAt(index), uidOps.valueAt(index),
- 0, 0, 0, -1, null));
+ resOps.add(new OpEntry(uidOps.keyAt(j), uidOps.valueAt(j)));
}
}
}
return resOps;
}
+ private static @NonNull OpEntry getOpEntryForResult(@NonNull Op op, long elapsedNow) {
+ if (op.running) {
+ op.continuing(elapsedNow - op.startRealtime,
+ op.uidState.state, AppOpsManager.OP_FLAG_SELF);
+ }
+ final OpEntry entry = new OpEntry(op.op, op.running, op.mode,
+ op.mAccessTimes != null ? op.mAccessTimes.clone() : null,
+ op.mRejectTimes != null ? op.mRejectTimes.clone() : null,
+ op.mDurations != null ? op.mDurations.clone() : null,
+ op.mProxyUids != null ? op.mProxyUids.clone() : null,
+ op.mProxyPackageNames != null ? op.mProxyPackageNames.clone() : null);
+ return entry;
+ }
+
@Override
public List<AppOpsManager.PackageOps> getPackagesForOps(int[] ops) {
mContext.enforcePermission(android.Manifest.permission.GET_APP_OPS_STATS,
@@ -1026,13 +1096,14 @@
@Override
public void getHistoricalOps(int uid, @NonNull String packageName,
@Nullable List<String> opNames, long beginTimeMillis, long endTimeMillis,
- @NonNull RemoteCallback callback) {
+ @OpFlags int flags, @NonNull RemoteCallback callback) {
// Use the builder to validate arguments.
- final HistoricalOpsRequest request = new HistoricalOpsRequest.Builder(
+ new HistoricalOpsRequest.Builder(
beginTimeMillis, endTimeMillis)
.setUid(uid)
.setPackageName(packageName)
.setOpNames(opNames)
+ .setFlags(flags)
.build();
Preconditions.checkNotNull(callback, "callback cannot be null");
@@ -1041,79 +1112,23 @@
final String[] opNamesArray = (opNames != null)
? opNames.toArray(new String[opNames.size()]) : null;
- if (mHistoricalRegistry.getMode() == AppOpsManager.HISTORICAL_MODE_DISABLED) {
- // TODO (bug:122218838): Remove once the feature fully enabled.
- getHistoricalPackagesOpsCompat(uid, packageName, opNamesArray, beginTimeMillis,
- endTimeMillis, callback);
- } else {
- // Must not hold the appops lock
- mHistoricalRegistry.getHistoricalOps(uid, packageName, opNamesArray,
- beginTimeMillis, endTimeMillis, callback);
- }
- }
- private void getHistoricalPackagesOpsCompat(int uid, @NonNull String packageName,
- @Nullable String[] opNames, long beginTimeMillis, long endTimeMillis,
- @NonNull RemoteCallback callback) {
- synchronized (AppOpsService.this) {
- final HistoricalOps ops = new HistoricalOps(beginTimeMillis, endTimeMillis);
- if (opNames == null) {
- opNames = AppOpsManager.getOpStrs();
- }
- final int uidStateCount = mUidStates.size();
- for (int uidIdx = 0; uidIdx < uidStateCount; uidIdx++) {
- final UidState uidState = mUidStates.valueAt(uidIdx);
- if (uidState.pkgOps == null || uidState.pkgOps.isEmpty()
- || (uid != Process.INVALID_UID && uid != uidState.uid)) {
- continue;
- }
- final ArrayMap<String, Ops> packages = uidState.pkgOps;
- final int packageCount = packages.size();
- for (int pkgIdx = 0; pkgIdx < packageCount; pkgIdx++) {
- final Ops pkgOps = packages.valueAt(pkgIdx);
- if (packageName != null && !packageName.equals(pkgOps.packageName)) {
- continue;
- }
- final int opCount = opNames.length;
- for (int opIdx = 0; opIdx < opCount; opIdx++) {
- final String opName = opNames[opIdx];
- if (!ArrayUtils.contains(opNames, opName)) {
- continue;
- }
- final int opCode = AppOpsManager.strOpToOp(opName);
- final Op op = pkgOps.get(opCode);
- if (op == null) {
- continue;
- }
- final int stateCount = AppOpsManager._NUM_UID_STATE;
- for (int stateIdx = 0; stateIdx < stateCount; stateIdx++) {
- if (op.rejectTime[stateIdx] != 0) {
- ops.increaseRejectCount(opCode, uidState.uid,
- pkgOps.packageName, stateIdx, 1);
- } else if (op.time[stateIdx] != 0) {
- ops.increaseAccessCount(opCode, uidState.uid,
- pkgOps.packageName, stateIdx, 1);
- }
- }
- }
- }
- }
- final Bundle payload = new Bundle();
- payload.putParcelable(AppOpsManager.KEY_HISTORICAL_OPS, ops);
- callback.sendResult(payload);
- }
+ // Must not hold the appops lock
+ mHistoricalRegistry.getHistoricalOps(uid, packageName, opNamesArray,
+ beginTimeMillis, endTimeMillis, flags, callback);
}
@Override
public void getHistoricalOpsFromDiskRaw(int uid, @NonNull String packageName,
@Nullable List<String> opNames, long beginTimeMillis, long endTimeMillis,
- @NonNull RemoteCallback callback) {
+ @OpFlags int flags, @NonNull RemoteCallback callback) {
// Use the builder to validate arguments.
- final HistoricalOpsRequest request = new HistoricalOpsRequest.Builder(
+ new HistoricalOpsRequest.Builder(
beginTimeMillis, endTimeMillis)
.setUid(uid)
.setPackageName(packageName)
.setOpNames(opNames)
+ .setFlags(flags)
.build();
Preconditions.checkNotNull(callback, "callback cannot be null");
@@ -1125,7 +1140,7 @@
// Must not hold the appops lock
mHistoricalRegistry.getHistoricalOpsFromDiskRaw(uid, packageName, opNamesArray,
- beginTimeMillis, endTimeMillis, callback);
+ beginTimeMillis, endTimeMillis, flags, callback);
}
@Override
@@ -1172,7 +1187,7 @@
}
}
- void enforceManageAppOpsModes(int callingPid, int callingUid, int targetUid) {
+ private void enforceManageAppOpsModes(int callingPid, int callingUid, int targetUid) {
if (callingPid == Process.myPid()) {
return;
}
@@ -1316,6 +1331,8 @@
return;
}
+ boolean scheduleWrite = false;
+
int numPkgs = pkgOps.size();
for (int pkgNum = 0; pkgNum < numPkgs; pkgNum++) {
Ops ops = pkgOps.valueAt(pkgNum);
@@ -1327,14 +1344,14 @@
int defaultMode = AppOpsManager.opToDefaultMode(code);
if (op.mode != defaultMode) {
- Slog.w(TAG, "resetting app-op mode for " + AppOpsManager.opToName(code) + " of "
- + pkgOps.keyAt(pkgNum));
-
op.mode = defaultMode;
-
- scheduleWriteLocked();
+ scheduleWrite = true;
}
}
+
+ if (scheduleWrite) {
+ scheduleWriteLocked();
+ }
}
}
@@ -1544,9 +1561,10 @@
curOp.mode = AppOpsManager.opToDefaultMode(curOp.op);
changed = true;
uidChanged = true;
- callbacks = addCallbacks(callbacks, curOp.op, curOp.uid, packageName,
+ final int uid = curOp.uidState.uid;
+ callbacks = addCallbacks(callbacks, curOp.op, uid, packageName,
mOpModeWatchers.get(curOp.op));
- callbacks = addCallbacks(callbacks, curOp.op, curOp.uid, packageName,
+ callbacks = addCallbacks(callbacks, curOp.op, uid, packageName,
mPackageModeWatchers.get(packageName));
if (!curOp.hasAnyTime()) {
pkgOps.removeAt(j);
@@ -1727,6 +1745,7 @@
private int checkOperationUnchecked(int code, int uid, String packageName,
boolean raw) {
synchronized (this) {
+ checkPackage(uid, packageName);
if (isOpRestrictedLocked(uid, code, packageName)) {
return AppOpsManager.MODE_IGNORED;
}
@@ -1735,13 +1754,13 @@
if (uidState != null && uidState.opModes != null
&& uidState.opModes.indexOfKey(code) >= 0) {
final int rawMode = uidState.opModes.get(code);
- return raw ? rawMode : uidState.evalMode(rawMode);
+ return raw ? rawMode : uidState.evalMode(code, rawMode);
}
Op op = getOpLocked(code, uid, packageName, false, true, false);
if (op == null) {
return AppOpsManager.opToDefaultMode(code);
}
- return op.mode;
+ return raw ? op.mode : op.evalMode();
}
}
@@ -1855,21 +1874,32 @@
String proxyPackageName, int proxiedUid, String proxiedPackageName) {
verifyIncomingUid(proxyUid);
verifyIncomingOp(code);
+
String resolveProxyPackageName = resolvePackageName(proxyUid, proxyPackageName);
if (resolveProxyPackageName == null) {
return AppOpsManager.MODE_IGNORED;
}
+
+ final boolean isProxyTrusted = mContext.checkPermission(
+ Manifest.permission.UPDATE_APP_OPS_STATS, -1, proxyUid)
+ == PackageManager.PERMISSION_GRANTED;
+
+ final int proxyFlags = isProxyTrusted ? AppOpsManager.OP_FLAG_TRUSTED_PROXY
+ : AppOpsManager.OP_FLAG_UNTRUSTED_PROXY;
final int proxyMode = noteOperationUnchecked(code, proxyUid,
- resolveProxyPackageName, -1, null);
+ resolveProxyPackageName, Process.INVALID_UID, null, proxyFlags);
if (proxyMode != AppOpsManager.MODE_ALLOWED || Binder.getCallingUid() == proxiedUid) {
return proxyMode;
}
+
String resolveProxiedPackageName = resolvePackageName(proxiedUid, proxiedPackageName);
if (resolveProxiedPackageName == null) {
return AppOpsManager.MODE_IGNORED;
}
+ final int proxiedFlags = isProxyTrusted ? AppOpsManager.OP_FLAG_TRUSTED_PROXIED
+ : AppOpsManager.OP_FLAG_UNTRUSTED_PROXIED;
return noteOperationUnchecked(code, proxiedUid, resolveProxiedPackageName,
- proxyMode, resolveProxyPackageName);
+ proxyUid, resolveProxyPackageName, proxiedFlags);
}
@Override
@@ -1892,11 +1922,12 @@
if (resolvedPackageName == null) {
return AppOpsManager.MODE_IGNORED;
}
- return noteOperationUnchecked(code, uid, resolvedPackageName, 0, null);
+ return noteOperationUnchecked(code, uid, resolvedPackageName, Process.INVALID_UID, null,
+ AppOpsManager.OP_FLAG_SELF);
}
private int noteOperationUnchecked(int code, int uid, String packageName,
- int proxyUid, String proxyPackageName) {
+ int proxyUid, String proxyPackageName, @OpFlags int flags) {
synchronized (this) {
final Ops ops = getOpsRawLocked(uid, packageName, true /* edit */,
false /* uidMismatchExpected */);
@@ -1914,49 +1945,52 @@
return AppOpsManager.MODE_IGNORED;
}
final UidState uidState = ops.uidState;
- if (op.duration == -1) {
+ if (op.running) {
+ final OpEntry entry = new OpEntry(op.op, op.running, op.mode, op.mAccessTimes,
+ op.mRejectTimes, op.mDurations, op.mProxyUids, op.mProxyPackageNames);
Slog.w(TAG, "Noting op not finished: uid " + uid + " pkg " + packageName
- + " code " + code + " time=" + op.time[uidState.state]
- + " duration=" + op.duration);
+ + " code " + code + " time=" + entry.getLastAccessTime(uidState.state,
+ uidState.state, flags) + " duration=" + entry.getLastDuration(
+ uidState.state, uidState.state, flags));
}
- op.duration = 0;
+
final int switchCode = AppOpsManager.opToSwitch(code);
// If there is a non-default per UID policy (we set UID op mode only if
// non-default) it takes over, otherwise use the per package policy.
if (uidState.opModes != null && uidState.opModes.indexOfKey(switchCode) >= 0) {
- final int uidMode = uidState.evalMode(uidState.opModes.get(switchCode));
+ final int uidMode = uidState.evalMode(code, uidState.opModes.get(switchCode));
if (uidMode != AppOpsManager.MODE_ALLOWED) {
if (DEBUG) Slog.d(TAG, "noteOperation: uid reject #" + uidMode + " for code "
+ switchCode + " (" + code + ") uid " + uid + " package "
+ packageName);
- op.rejectTime[uidState.state] = System.currentTimeMillis();
+ op.rejected(System.currentTimeMillis(), proxyUid, proxyPackageName,
+ uidState.state, flags);
+ mHistoricalRegistry.incrementOpRejected(code, uid, packageName,
+ uidState.state, flags);
scheduleOpNotedIfNeededLocked(code, uid, packageName, uidMode);
- mHistoricalRegistry.incrementOpRejected(op.op, uid, packageName,
- uidState.state);
return uidMode;
}
} else {
final Op switchOp = switchCode != code ? getOpLocked(ops, switchCode, true) : op;
- final int mode = switchOp.getMode();
- if (mode != AppOpsManager.MODE_ALLOWED) {
+ final int mode = switchOp.evalMode();
+ if (switchOp.mode != AppOpsManager.MODE_ALLOWED) {
if (DEBUG) Slog.d(TAG, "noteOperation: reject #" + mode + " for code "
+ switchCode + " (" + code + ") uid " + uid + " package "
+ packageName);
- op.rejectTime[uidState.state] = System.currentTimeMillis();
- scheduleOpNotedIfNeededLocked(op.op, uid, packageName, mode);
- mHistoricalRegistry.incrementOpRejected(op.op, uid, packageName,
- uidState.state);
+ op.rejected(System.currentTimeMillis(), proxyUid, proxyPackageName,
+ uidState.state, flags);
+ mHistoricalRegistry.incrementOpRejected(code, uid, packageName,
+ uidState.state, flags);
+ scheduleOpNotedIfNeededLocked(code, uid, packageName, mode);
return mode;
}
}
if (DEBUG) Slog.d(TAG, "noteOperation: allowing code " + code + " uid " + uid
+ " package " + packageName);
- op.time[uidState.state] = System.currentTimeMillis();
+ op.accessed(System.currentTimeMillis(), proxyUid, proxyPackageName,
+ uidState.state, flags);
mHistoricalRegistry.incrementOpAccessedCount(op.op, uid, packageName,
- uidState.state);
- op.rejectTime[uidState.state] = 0;
- op.proxyUid = proxyUid;
- op.proxyPackageName = proxyPackageName;
+ uidState.state, flags);
scheduleOpNotedIfNeededLocked(code, uid, packageName,
AppOpsManager.MODE_ALLOWED);
return AppOpsManager.MODE_ALLOWED;
@@ -2080,29 +2114,34 @@
final UidState uidState = ops.uidState;
// If there is a non-default per UID policy (we set UID op mode only if
// non-default) it takes over, otherwise use the per package policy.
+ final int opCode = op.op;
if (uidState.opModes != null && uidState.opModes.indexOfKey(switchCode) >= 0) {
- final int uidMode = uidState.evalMode(uidState.opModes.get(switchCode));
+ final int uidMode = uidState.evalMode(code, uidState.opModes.get(switchCode));
if (uidMode != AppOpsManager.MODE_ALLOWED
&& (!startIfModeDefault || uidMode != AppOpsManager.MODE_DEFAULT)) {
if (DEBUG) Slog.d(TAG, "noteOperation: uid reject #" + uidMode + " for code "
+ switchCode + " (" + code + ") uid " + uid + " package "
+ resolvedPackageName);
- op.rejectTime[uidState.state] = System.currentTimeMillis();
- mHistoricalRegistry.incrementOpRejected(op.op, uid, packageName,
- uidState.state);
+ // We don't support proxy long running ops (start/stop)
+ op.rejected(System.currentTimeMillis(), -1 /*proxyUid*/,
+ null /*proxyPackage*/, uidState.state, AppOpsManager.OP_FLAG_SELF);
+ mHistoricalRegistry.incrementOpRejected(opCode, uid, packageName,
+ uidState.state, AppOpsManager.OP_FLAG_SELF);
return uidMode;
}
} else {
final Op switchOp = switchCode != code ? getOpLocked(ops, switchCode, true) : op;
- final int mode = switchOp.getMode();
+ final int mode = switchOp.evalMode();
if (mode != AppOpsManager.MODE_ALLOWED
&& (!startIfModeDefault || mode != AppOpsManager.MODE_DEFAULT)) {
if (DEBUG) Slog.d(TAG, "startOperation: reject #" + mode + " for code "
+ switchCode + " (" + code + ") uid " + uid + " package "
+ resolvedPackageName);
- op.rejectTime[uidState.state] = System.currentTimeMillis();
- mHistoricalRegistry.incrementOpRejected(op.op, uid, packageName,
- uidState.state);
+ // We don't support proxy long running ops (start/stop)
+ op.rejected(System.currentTimeMillis(), -1 /*proxyUid*/,
+ null /*proxyPackage*/, uidState.state, AppOpsManager.OP_FLAG_SELF);
+ mHistoricalRegistry.incrementOpRejected(opCode, uid, packageName,
+ uidState.state, AppOpsManager.OP_FLAG_SELF);
return mode;
}
}
@@ -2110,11 +2149,12 @@
+ " package " + resolvedPackageName);
if (op.startNesting == 0) {
op.startRealtime = SystemClock.elapsedRealtime();
- op.time[uidState.state] = System.currentTimeMillis();
- mHistoricalRegistry.incrementOpAccessedCount(op.op, uid, packageName,
- uidState.state);
- op.rejectTime[uidState.state] = 0;
- op.duration = -1;
+ // We don't support proxy long running ops (start/stop)
+ op.started(System.currentTimeMillis(), uidState.state,
+ AppOpsManager.OP_FLAG_SELF);
+ mHistoricalRegistry.incrementOpAccessedCount(opCode, uid, packageName,
+ uidState.state, AppOpsManager.OP_FLAG_SELF);
+
scheduleOpActiveChangedIfNeededLocked(code, uid, packageName, true);
}
op.startNesting++;
@@ -2161,7 +2201,7 @@
} finally {
Binder.restoreCallingIdentity(identity);
}
- Slog.wtf(TAG, "Operation not started: uid=" + op.uid + " pkg="
+ Slog.wtf(TAG, "Operation not started: uid=" + op.uidState.uid + " pkg="
+ op.packageName + " op=" + AppOpsManager.opToName(op.op));
return;
}
@@ -2272,16 +2312,24 @@
}
void finishOperationLocked(Op op, boolean finishNested) {
+ final int opCode = op.op;
+ final int uid = op.uidState.uid;
if (op.startNesting <= 1 || finishNested) {
if (op.startNesting == 1 || finishNested) {
- op.duration = (int)(SystemClock.elapsedRealtime() - op.startRealtime);
- mHistoricalRegistry.increaseOpAccessDuration(op.op, op.uid, op.packageName,
- op.uidState.state, op.duration);
- op.time[op.uidState.state] = System.currentTimeMillis();
+ // We don't support proxy long running ops (start/stop)
+ final long duration = SystemClock.elapsedRealtime() - op.startRealtime;
+ op.finished(System.currentTimeMillis(), duration, op.uidState.state,
+ AppOpsManager.OP_FLAG_SELF);
+ mHistoricalRegistry.increaseOpAccessDuration(opCode, uid, op.packageName,
+ op.uidState.state, AppOpsManager.OP_FLAG_SELF, duration);
} else {
- Slog.w(TAG, "Finishing op nesting under-run: uid " + op.uid + " pkg "
- + op.packageName + " code " + op.op + " time=" + op.time
- + " duration=" + op.duration + " nesting=" + op.startNesting);
+ final OpEntry entry = new OpEntry(op.op, op.running, op.mode, op.mAccessTimes,
+ op.mRejectTimes, op.mDurations, op.mProxyUids, op.mProxyPackageNames);
+ Slog.w(TAG, "Finishing op nesting under-run: uid " + uid + " pkg "
+ + op.packageName + " code " + opCode + " time="
+ + entry.getLastAccessTime(OP_FLAGS_ALL)
+ + " duration=" + entry.getLastDuration(MAX_PRIORITY_UID_STATE,
+ MIN_PRIORITY_UID_STATE, OP_FLAGS_ALL) + " nesting=" + op.startNesting);
}
if (op.startNesting >= 1) {
op.uidState.startNesting -= op.startNesting;
@@ -2311,7 +2359,7 @@
throw new IllegalArgumentException("Bad operation #" + op);
}
- private UidState getUidStateLocked(int uid, boolean edit) {
+ private @NonNull UidState getUidStateLocked(int uid, boolean edit) {
UidState uidState = mUidStates.get(uid);
if (uidState == null) {
if (!edit) {
@@ -2335,8 +2383,8 @@
}
private void commitUidPendingStateLocked(UidState uidState) {
- final boolean lastForeground = uidState.state <= UID_STATE_LAST_NON_RESTRICTED;
- final boolean nowForeground = uidState.pendingState <= UID_STATE_LAST_NON_RESTRICTED;
+ final boolean lastForeground = uidState.state <= UID_STATE_MAX_LAST_NON_RESTRICTED;
+ final boolean nowForeground = uidState.pendingState <= UID_STATE_MAX_LAST_NON_RESTRICTED;
uidState.state = uidState.pendingState;
uidState.pendingStateCommitTime = 0;
if (uidState.hasForegroundWatchers && lastForeground != nowForeground) {
@@ -2345,7 +2393,15 @@
continue;
}
final int code = uidState.foregroundOps.keyAt(fgi);
-
+ // For location ops we consider fg state only if the fg service
+ // is of location type, for all other ops any fg service will do.
+ final long resolvedLastRestrictedUidState = resolveFirstUnrestrictedUidState(code);
+ final boolean resolvedLastFg = uidState.state <= resolvedLastRestrictedUidState;
+ final boolean resolvedNowBg = uidState.pendingState
+ <= resolvedLastRestrictedUidState;
+ if (resolvedLastFg == resolvedNowBg) {
+ continue;
+ }
final ArraySet<ModeCallback> callbacks = mOpModeWatchers.get(code);
if (callbacks != null) {
for (int cbi = callbacks.size() - 1; cbi >= 0; cbi--) {
@@ -2360,8 +2416,10 @@
if (uidState.pkgOps != null) {
for (int pkgi = uidState.pkgOps.size() - 1; pkgi >= 0; pkgi--) {
final Op op = uidState.pkgOps.valueAt(pkgi).get(code);
- if (doAllPackages || (op != null
- && op.mode == AppOpsManager.MODE_FOREGROUND)) {
+ if (op == null) {
+ continue;
+ }
+ if (doAllPackages || op.mode == AppOpsManager.MODE_FOREGROUND) {
mHandler.sendMessage(PooledLambda.obtainMessage(
AppOpsService::notifyOpChanged,
this, callback, code, uidState.uid,
@@ -2651,7 +2709,7 @@
final int idx = uidState.opModes.indexOfKey(AppOpsManager.OP_RUN_IN_BACKGROUND);
if (idx >= 0) {
uidState.opModes.put(AppOpsManager.OP_RUN_ANY_IN_BACKGROUND,
- uidState.opModes.valueAt(idx));
+ uidState.opModes.valueAt(idx));
}
}
if (uidState.pkgOps == null) {
@@ -2664,7 +2722,7 @@
final Op op = ops.get(AppOpsManager.OP_RUN_IN_BACKGROUND);
if (op != null && op.mode != AppOpsManager.opToDefaultMode(op.op)) {
final Op copy = new Op(op.uidState, op.packageName,
- AppOpsManager.OP_RUN_ANY_IN_BACKGROUND);
+ AppOpsManager.OP_RUN_ANY_IN_BACKGROUND);
copy.mode = op.mode;
ops.put(AppOpsManager.OP_RUN_ANY_IN_BACKGROUND, copy);
changed = true;
@@ -2692,7 +2750,7 @@
scheduleFastWriteLocked();
}
- void readUidOps(XmlPullParser parser) throws NumberFormatException,
+ private void readUidOps(XmlPullParser parser) throws NumberFormatException,
XmlPullParserException, IOException {
final int uid = Integer.parseInt(parser.getAttributeValue(null, "n"));
int outerDepth = parser.getDepth();
@@ -2720,8 +2778,8 @@
}
}
- void readPackage(XmlPullParser parser) throws NumberFormatException,
- XmlPullParserException, IOException {
+ private void readPackage(XmlPullParser parser)
+ throws NumberFormatException, XmlPullParserException, IOException {
String pkgName = parser.getAttributeValue(null, "n");
int outerDepth = parser.getDepth();
int type;
@@ -2742,9 +2800,10 @@
}
}
- void readUid(XmlPullParser parser, String pkgName) throws NumberFormatException,
- XmlPullParserException, IOException {
+ private void readUid(XmlPullParser parser, String pkgName)
+ throws NumberFormatException, XmlPullParserException, IOException {
int uid = Integer.parseInt(parser.getAttributeValue(null, "n"));
+ final UidState uidState = getUidStateLocked(uid, true);
String isPrivilegedString = parser.getAttributeValue(null, "p");
boolean isPrivileged = false;
if (isPrivilegedString == null) {
@@ -2774,113 +2833,73 @@
if (type == XmlPullParser.END_TAG || type == XmlPullParser.TEXT) {
continue;
}
-
String tagName = parser.getName();
if (tagName.equals("op")) {
- UidState uidState = getUidStateLocked(uid, true);
- if (uidState.pkgOps == null) {
- uidState.pkgOps = new ArrayMap<>();
- }
-
- Op op = new Op(uidState, pkgName,
- Integer.parseInt(parser.getAttributeValue(null, "n")));
-
- for (int i = parser.getAttributeCount()-1; i >= 0; i--) {
- final String name = parser.getAttributeName(i);
- final String value = parser.getAttributeValue(i);
- switch (name) {
- case "m":
- op.mode = Integer.parseInt(value);
- break;
- case "d":
- op.duration = Integer.parseInt(value);
- break;
- case "pu":
- op.proxyUid = Integer.parseInt(value);
- break;
- case "pp":
- op.proxyPackageName = value;
- break;
- case "tp":
- op.time[AppOpsManager.UID_STATE_PERSISTENT] = Long.parseLong(value);
- break;
- case "tt":
- op.time[AppOpsManager.UID_STATE_TOP] = Long.parseLong(value);
- break;
- case "tfsl":
- op.time[AppOpsManager.UID_STATE_FOREGROUND_SERVICE_LOCATION] =
- Long.parseLong(value);
- break;
- case "tfs":
- op.time[AppOpsManager.UID_STATE_FOREGROUND_SERVICE] =
- Long.parseLong(value);
- break;
- case "tf":
- op.time[AppOpsManager.UID_STATE_FOREGROUND] = Long.parseLong(value);
- break;
- case "tb":
- op.time[AppOpsManager.UID_STATE_BACKGROUND] = Long.parseLong(value);
- break;
- case "tc":
- op.time[AppOpsManager.UID_STATE_CACHED] = Long.parseLong(value);
- break;
- case "rp":
- op.rejectTime[AppOpsManager.UID_STATE_PERSISTENT] =
- Long.parseLong(value);
- break;
- case "rt":
- op.rejectTime[AppOpsManager.UID_STATE_TOP] = Long.parseLong(value);
- break;
- case "rfsl":
- op.rejectTime[AppOpsManager.UID_STATE_FOREGROUND_SERVICE_LOCATION] =
- Long.parseLong(value);
- break;
- case "rfs":
- op.rejectTime[AppOpsManager.UID_STATE_FOREGROUND_SERVICE] =
- Long.parseLong(value);
- break;
- case "rf":
- op.rejectTime[AppOpsManager.UID_STATE_FOREGROUND] =
- Long.parseLong(value);
- break;
- case "rb":
- op.rejectTime[AppOpsManager.UID_STATE_BACKGROUND] =
- Long.parseLong(value);
- break;
- case "rc":
- op.rejectTime[AppOpsManager.UID_STATE_CACHED] =
- Long.parseLong(value);
- break;
- case "t":
- // Backwards compat.
- op.time[AppOpsManager.UID_STATE_TOP] = Long.parseLong(value);
- break;
- case "r":
- // Backwards compat.
- op.rejectTime[AppOpsManager.UID_STATE_TOP] = Long.parseLong(value);
- break;
- default:
- Slog.w(TAG, "Unknown attribute in 'op' tag: " + name);
- break;
- }
- }
-
- Ops ops = uidState.pkgOps.get(pkgName);
- if (ops == null) {
- ops = new Ops(pkgName, uidState, isPrivileged);
- uidState.pkgOps.put(pkgName, ops);
- }
- ops.put(op.op, op);
+ readOp(parser, uidState, pkgName, isPrivileged);
} else {
Slog.w(TAG, "Unknown element under <pkg>: "
+ parser.getName());
XmlUtils.skipCurrentTag(parser);
}
}
- UidState uidState = getUidStateLocked(uid, false);
- if (uidState != null) {
- uidState.evalForegroundOps(mOpModeWatchers);
+ uidState.evalForegroundOps(mOpModeWatchers);
+ }
+
+ private void readOp(XmlPullParser parser, @NonNull UidState uidState,
+ @NonNull String pkgName, boolean isPrivileged) throws NumberFormatException,
+ XmlPullParserException, IOException {
+ Op op = new Op(uidState, pkgName,
+ Integer.parseInt(parser.getAttributeValue(null, "n")));
+
+ final int mode = XmlUtils.readIntAttribute(parser, "m",
+ AppOpsManager.opToDefaultMode(op.op));
+ op.mode = mode;
+
+ int outerDepth = parser.getDepth();
+ int type;
+ while ((type = parser.next()) != XmlPullParser.END_DOCUMENT
+ && (type != XmlPullParser.END_TAG || parser.getDepth() > outerDepth)) {
+ if (type == XmlPullParser.END_TAG || type == XmlPullParser.TEXT) {
+ continue;
+ }
+ String tagName = parser.getName();
+ if (tagName.equals("st")) {
+ final long key = XmlUtils.readLongAttribute(parser, "n");
+
+ final int flags = AppOpsManager.extractFlagsFromKey(key);
+ final int state = AppOpsManager.extractUidStateFromKey(key);
+
+ final long accessTime = XmlUtils.readLongAttribute(parser, "t", 0);
+ final long rejectTime = XmlUtils.readLongAttribute(parser, "r", 0);
+ final long accessDuration = XmlUtils.readLongAttribute(parser, "d", 0);
+ final String proxyPkg = XmlUtils.readStringAttribute(parser, "pp");
+ final int proxyUid = XmlUtils.readIntAttribute(parser, "pu", 0);
+
+ if (accessTime > 0) {
+ op.accessed(accessTime, proxyUid, proxyPkg, state, flags);
+ }
+ if (rejectTime > 0) {
+ op.rejected(rejectTime, proxyUid, proxyPkg, state, flags);
+ }
+ if (accessDuration > 0) {
+ op.running(accessTime, accessDuration, state, flags);
+ }
+ } else {
+ Slog.w(TAG, "Unknown element under <op>: "
+ + parser.getName());
+ XmlUtils.skipCurrentTag(parser);
+ }
}
+
+ if (uidState.pkgOps == null) {
+ uidState.pkgOps = new ArrayMap<>();
+ }
+ Ops ops = uidState.pkgOps.get(pkgName);
+ if (ops == null) {
+ ops = new Ops(pkgName, uidState, isPrivileged);
+ uidState.pkgOps.put(pkgName, ops);
+ }
+ ops.put(op.op, op);
}
void writeState() {
@@ -2955,30 +2974,53 @@
if (op.getMode() != AppOpsManager.opToDefaultMode(op.getOp())) {
out.attribute(null, "m", Integer.toString(op.getMode()));
}
- for (int k = 0; k < _NUM_UID_STATE; k++) {
- final long time = op.getLastTimeFor(k);
- if (time != 0) {
- out.attribute(null, UID_STATE_TIME_ATTRS[k],
- Long.toString(time));
+
+ final LongSparseArray keys = op.collectKeys();
+ if (keys == null || keys.size() <= 0) {
+ continue;
+ }
+
+ final int keyCount = keys.size();
+ for (int k = 0; k < keyCount; k++) {
+ final long key = keys.keyAt(k);
+
+ final int uidState = AppOpsManager.extractUidStateFromKey(key);
+ final int flags = AppOpsManager.extractFlagsFromKey(key);
+
+ final long accessTime = op.getLastAccessTime(
+ uidState, uidState, flags);
+ final long rejectTime = op.getLastRejectTime(
+ uidState, uidState, flags);
+ final long accessDuration = op.getLastDuration(
+ uidState, uidState, flags);
+ final String proxyPkg = op.getProxyPackageName(uidState, flags);
+ final int proxyUid = op.getProxyUid(uidState, flags);
+
+ if (accessTime <= 0 && rejectTime <= 0 && accessDuration <= 0
+ && proxyPkg == null && proxyUid < 0) {
+ continue;
}
- final long rejectTime = op.getLastRejectTimeFor(k);
- if (rejectTime != 0) {
- out.attribute(null, UID_STATE_REJECT_ATTRS[k],
- Long.toString(rejectTime));
+
+ out.startTag(null, "st");
+ out.attribute(null, "n", Long.toString(key));
+ if (accessTime > 0) {
+ out.attribute(null, "t", Long.toString(accessTime));
}
+ if (rejectTime > 0) {
+ out.attribute(null, "r", Long.toString(rejectTime));
+ }
+ if (accessDuration > 0) {
+ out.attribute(null, "d", Long.toString(accessDuration));
+ }
+ if (proxyPkg != null) {
+ out.attribute(null, "pp", proxyPkg);
+ }
+ if (proxyUid >= 0) {
+ out.attribute(null, "pu", Integer.toString(proxyUid));
+ }
+ out.endTag(null, "st");
}
- int dur = op.getDuration();
- if (dur != 0) {
- out.attribute(null, "d", Integer.toString(dur));
- }
- int proxyUid = op.getProxyUid();
- if (proxyUid != -1) {
- out.attribute(null, "pu", Integer.toString(proxyUid));
- }
- String proxyPackageName = op.getProxyPackageName();
- if (proxyPackageName != null) {
- out.attribute(null, "pp", proxyPackageName);
- }
+
out.endTag(null, "op");
}
out.endTag(null, "uid");
@@ -3462,32 +3504,80 @@
pw.println(" Limit output to data associated with the given package name.");
pw.println(" --watchers");
pw.println(" Only output the watcher sections.");
+ pw.println(" --history");
+ pw.println(" Output the historical data.");
}
- private void dumpTimesLocked(PrintWriter pw, String firstPrefix, String prefix, long[] times,
- long now, SimpleDateFormat sdf, Date date) {
- boolean hasTime = false;
- for (int i = 0; i < _NUM_UID_STATE; i++) {
- if (times[i] != 0) {
- hasTime = true;
- break;
- }
- }
- if (!hasTime) {
+ private void dumpStatesLocked(@NonNull PrintWriter pw, @NonNull Op op,
+ long now, @NonNull SimpleDateFormat sdf, @NonNull Date date, @NonNull String prefix) {
+
+ final OpEntry entry = new OpEntry(op.op, op.running, op.mode, op.mAccessTimes,
+ op.mRejectTimes, op.mDurations, op.mProxyUids, op.mProxyPackageNames);
+
+ final LongSparseArray keys = entry.collectKeys();
+ if (keys == null || keys.size() <= 0) {
return;
}
- boolean first = true;
- for (int i = 0; i < _NUM_UID_STATE; i++) {
- if (times[i] != 0) {
- pw.print(first ? firstPrefix : prefix);
- first = false;
- pw.print(UID_STATE_NAMES[i]);
- pw.print(" = ");
- date.setTime(times[i]);
+
+ final int keyCount = keys.size();
+ for (int k = 0; k < keyCount; k++) {
+ final long key = keys.keyAt(k);
+
+ final int uidState = AppOpsManager.extractUidStateFromKey(key);
+ final int flags = AppOpsManager.extractFlagsFromKey(key);
+
+ final long accessTime = entry.getLastAccessTime(
+ uidState, uidState, flags);
+ final long rejectTime = entry.getLastRejectTime(
+ uidState, uidState, flags);
+ final long accessDuration = entry.getLastDuration(
+ uidState, uidState, flags);
+ final String proxyPkg = entry.getProxyPackageName(uidState, flags);
+ final int proxyUid = entry.getProxyUid(uidState, flags);
+
+ if (accessTime > 0) {
+ pw.print(prefix);
+ pw.print("Access: ");
+ pw.print(AppOpsManager.keyToString(key));
+ pw.print(" ");
+ date.setTime(accessTime);
pw.print(sdf.format(date));
pw.print(" (");
- TimeUtils.formatDuration(times[i]-now, pw);
- pw.println(")");
+ TimeUtils.formatDuration(accessTime - now, pw);
+ pw.print(")");
+ if (accessDuration > 0) {
+ pw.print(" duration=");
+ TimeUtils.formatDuration(accessDuration, pw);
+ }
+ if (proxyUid >= 0) {
+ pw.print(" proxy[");
+ pw.print("uid=");
+ pw.print(proxyUid);
+ pw.print(", pkg=");
+ pw.print(proxyPkg);
+ pw.print("]");
+ }
+ pw.println();
+ }
+
+ if (rejectTime > 0) {
+ pw.print(prefix);
+ pw.print("Reject: ");
+ pw.print(AppOpsManager.keyToString(key));
+ date.setTime(rejectTime);
+ pw.print(sdf.format(date));
+ pw.print(" (");
+ TimeUtils.formatDuration(rejectTime - now, pw);
+ pw.print(")");
+ if (proxyUid >= 0) {
+ pw.print(" proxy[");
+ pw.print("uid=");
+ pw.print(proxyUid);
+ pw.print(", pkg=");
+ pw.print(proxyPkg);
+ pw.print("]");
+ }
+ pw.println();
}
}
}
@@ -3501,6 +3591,7 @@
int dumpUid = Process.INVALID_UID;
int dumpMode = -1;
boolean dumpWatchers = false;
+ boolean dumpHistory = false;
if (args != null) {
for (int i=0; i<args.length; i++) {
@@ -3550,6 +3641,8 @@
}
} else if ("--watchers".equals(arg)) {
dumpWatchers = true;
+ } else if ("--history".equals(arg)) {
+ dumpHistory = true;
} else if (arg.length() > 0 && arg.charAt(0) == '-'){
pw.println("Unknown option: " + arg);
return;
@@ -3562,7 +3655,9 @@
synchronized (this) {
pw.println("Current AppOps Service state:");
- mConstants.dump(pw);
+ if (!dumpHistory && !dumpWatchers) {
+ mConstants.dump(pw);
+ }
pw.println();
final long now = System.currentTimeMillis();
final long nowElapsed = SystemClock.elapsedRealtime();
@@ -3571,7 +3666,7 @@
final Date date = new Date();
boolean needSep = false;
if (dumpOp < 0 && dumpMode < 0 && dumpPackage == null && mProfileOwners != null
- && !dumpWatchers) {
+ && !dumpWatchers && !dumpHistory) {
pw.println(" Profile owners:");
for (int poi = 0; poi < mProfileOwners.size(); poi++) {
pw.print(" User #");
@@ -3582,7 +3677,7 @@
}
pw.println();
}
- if (mOpModeWatchers.size() > 0) {
+ if (mOpModeWatchers.size() > 0 && !dumpHistory) {
boolean printedHeader = false;
for (int i=0; i<mOpModeWatchers.size(); i++) {
if (dumpOp >= 0 && dumpOp != mOpModeWatchers.keyAt(i)) {
@@ -3612,7 +3707,7 @@
}
}
}
- if (mPackageModeWatchers.size() > 0 && dumpOp < 0) {
+ if (mPackageModeWatchers.size() > 0 && dumpOp < 0 && !dumpHistory) {
boolean printedHeader = false;
for (int i=0; i<mPackageModeWatchers.size(); i++) {
if (dumpPackage != null && !dumpPackage.equals(mPackageModeWatchers.keyAt(i))) {
@@ -3632,7 +3727,7 @@
}
}
}
- if (mModeWatchers.size() > 0 && dumpOp < 0) {
+ if (mModeWatchers.size() > 0 && dumpOp < 0 && !dumpHistory) {
boolean printedHeader = false;
for (int i=0; i<mModeWatchers.size(); i++) {
final ModeCallback cb = mModeWatchers.valueAt(i);
@@ -3730,7 +3825,7 @@
pw.println(cb);
}
}
- if (mClients.size() > 0 && dumpMode < 0 && !dumpWatchers) {
+ if (mClients.size() > 0 && dumpMode < 0 && !dumpWatchers && !dumpHistory) {
needSep = true;
boolean printedHeader = false;
for (int i=0; i<mClients.size(); i++) {
@@ -3759,7 +3854,7 @@
pw.println(" Started ops:");
printedStarted = true;
}
- pw.print(" "); pw.print("uid="); pw.print(op.uid);
+ pw.print(" "); pw.print("uid="); pw.print(op.uidState.uid);
pw.print(" pkg="); pw.print(op.packageName);
pw.print(" op="); pw.println(AppOpsManager.opToName(op.op));
}
@@ -3767,7 +3862,7 @@
}
}
if (mAudioRestrictions.size() > 0 && dumpOp < 0 && dumpPackage != null
- && dumpMode < 0 && !dumpWatchers) {
+ && dumpMode < 0 && !dumpWatchers && !dumpWatchers) {
boolean printedHeader = false;
for (int o=0; o<mAudioRestrictions.size(); o++) {
final String op = AppOpsManager.opToName(mAudioRestrictions.keyAt(o));
@@ -3800,7 +3895,7 @@
final SparseIntArray opModes = uidState.opModes;
final ArrayMap<String, Ops> pkgOps = uidState.pkgOps;
- if (dumpWatchers) {
+ if (dumpWatchers || dumpHistory) {
continue;
}
if (dumpOp >= 0 || dumpPackage != null || dumpMode >= 0) {
@@ -3847,10 +3942,10 @@
pw.print(" Uid "); UserHandle.formatUid(pw, uidState.uid); pw.println(":");
pw.print(" state=");
- pw.println(UID_STATE_NAMES[uidState.state]);
+ pw.println(AppOpsManager.getUidStateName(uidState.state));
if (uidState.state != uidState.pendingState) {
pw.print(" pendingState=");
- pw.println(UID_STATE_NAMES[uidState.pendingState]);
+ pw.println(AppOpsManager.getUidStateName(uidState.pendingState));
}
if (uidState.pendingStateCommitTime != 0) {
pw.print(" pendingStateCommitTime=");
@@ -3906,7 +4001,8 @@
boolean printedPackage = false;
for (int j=0; j<ops.size(); j++) {
final Op op = ops.valueAt(j);
- if (dumpOp >= 0 && dumpOp != op.op) {
+ final int opCode = op.op;
+ if (dumpOp >= 0 && dumpOp != opCode) {
continue;
}
if (dumpMode >= 0 && dumpMode != op.mode) {
@@ -3916,32 +4012,23 @@
pw.print(" Package "); pw.print(ops.packageName); pw.println(":");
printedPackage = true;
}
- pw.print(" "); pw.print(AppOpsManager.opToName(op.op));
+ pw.print(" "); pw.print(AppOpsManager.opToName(opCode));
pw.print(" ("); pw.print(AppOpsManager.modeToName(op.mode));
- final int switchOp = AppOpsManager.opToSwitch(op.op);
- if (switchOp != op.op) {
+ final int switchOp = AppOpsManager.opToSwitch(opCode);
+ if (switchOp != opCode) {
pw.print(" / switch ");
pw.print(AppOpsManager.opToName(switchOp));
final Op switchObj = ops.get(switchOp);
- int mode = switchObj != null
- ? switchObj.mode : AppOpsManager.opToDefaultMode(switchOp);
+ int mode = switchObj != null ? switchObj.mode
+ : AppOpsManager.opToDefaultMode(switchOp);
pw.print("="); pw.print(AppOpsManager.modeToName(mode));
}
pw.println("): ");
- dumpTimesLocked(pw,
- " Access: ",
- " ", op.time, now, sdf, date);
- dumpTimesLocked(pw,
- " Reject: ",
- " ", op.rejectTime, now, sdf, date);
- if (op.duration == -1) {
+ dumpStatesLocked(pw, op, now, sdf, date, " ");
+ if (op.running) {
pw.print(" Running start at: ");
TimeUtils.formatDuration(nowElapsed-op.startRealtime, pw);
pw.println();
- } else if (op.duration != 0) {
- pw.print(" duration=");
- TimeUtils.formatDuration(op.duration, pw);
- pw.println();
}
if (op.startNesting != 0) {
pw.print(" startNesting=");
@@ -3960,7 +4047,7 @@
ClientRestrictionState restrictionState = mOpUserRestrictions.valueAt(i);
boolean printedTokenHeader = false;
- if (dumpMode >= 0 || dumpWatchers) {
+ if (dumpMode >= 0 || dumpWatchers || dumpHistory) {
continue;
}
@@ -4044,7 +4131,9 @@
}
// Must not hold the appops lock
- mHistoricalRegistry.dump(" ", pw, dumpUid, dumpPackage, dumpOp);
+ if (dumpHistory && !dumpWatchers) {
+ mHistoricalRegistry.dump(" ", pw, dumpUid, dumpPackage, dumpOp);
+ }
}
private static final class Restriction {
@@ -4158,7 +4247,7 @@
final ClientState client = mClients.valueAt(i);
for (int j = client.mStartedOps.size() - 1; j >= 0; j--) {
final Op op = client.mStartedOps.get(j);
- if (op.op == code && op.uid == uid) return true;
+ if (op.op == code && op.uidState.uid == uid) return true;
}
}
}
diff --git a/services/core/java/com/android/server/appop/HistoricalRegistry.java b/services/core/java/com/android/server/appop/HistoricalRegistry.java
index 4485a54..280bc02 100644
--- a/services/core/java/com/android/server/appop/HistoricalRegistry.java
+++ b/services/core/java/com/android/server/appop/HistoricalRegistry.java
@@ -23,6 +23,7 @@
import android.app.AppOpsManager.HistoricalOps;
import android.app.AppOpsManager.HistoricalPackageOps;
import android.app.AppOpsManager.HistoricalUidOps;
+import android.app.AppOpsManager.OpFlags;
import android.app.AppOpsManager.UidState;
import android.content.ContentResolver;
import android.database.ContentObserver;
@@ -37,6 +38,7 @@
import android.os.UserHandle;
import android.provider.Settings;
import android.util.ArraySet;
+import android.util.LongSparseArray;
import android.util.Slog;
import android.util.TimeUtils;
import android.util.Xml;
@@ -297,20 +299,20 @@
}
}
- @Nullable void getHistoricalOpsFromDiskRaw(int uid, @NonNull String packageName,
+ void getHistoricalOpsFromDiskRaw(int uid, @NonNull String packageName,
@Nullable String[] opNames, long beginTimeMillis, long endTimeMillis,
- @NonNull RemoteCallback callback) {
+ @OpFlags int flags, @NonNull RemoteCallback callback) {
final HistoricalOps result = new HistoricalOps(beginTimeMillis, endTimeMillis);
mPersistence.collectHistoricalOpsDLocked(result, uid, packageName, opNames,
- beginTimeMillis, endTimeMillis);
+ beginTimeMillis, endTimeMillis, flags);
final Bundle payload = new Bundle();
payload.putParcelable(AppOpsManager.KEY_HISTORICAL_OPS, result);
callback.sendResult(payload);
}
- @Nullable void getHistoricalOps(int uid, @NonNull String packageName,
+ void getHistoricalOps(int uid, @NonNull String packageName,
@Nullable String[] opNames, long beginTimeMillis, long endTimeMillis,
- @NonNull RemoteCallback callback) {
+ @OpFlags int flags, @NonNull RemoteCallback callback) {
final long currentTimeMillis = System.currentTimeMillis();
if (endTimeMillis == Long.MAX_VALUE) {
endTimeMillis = currentTimeMillis;
@@ -326,6 +328,8 @@
synchronized (mOnDiskLock) {
final List<HistoricalOps> pendingWrites;
final HistoricalOps currentOps;
+ boolean collectOpsFromDisk;
+
synchronized (mInMemoryLock) {
currentOps = getUpdatedPendingHistoricalOpsMLocked(currentTimeMillis);
if (!(inMemoryAdjBeginTimeMillis >= currentOps.getEndTimeMillis()
@@ -338,10 +342,11 @@
}
pendingWrites = new ArrayList<>(mPendingWrites);
mPendingWrites.clear();
+ collectOpsFromDisk = inMemoryAdjEndTimeMillis > currentOps.getEndTimeMillis();
}
// If the query was only for in-memory state - done.
- if (inMemoryAdjEndTimeMillis > currentOps.getEndTimeMillis()) {
+ if (collectOpsFromDisk) {
// If there is a write in flight we need to force it now
persistPendingHistory(pendingWrites);
// Collect persisted state.
@@ -352,7 +357,7 @@
final long onDiskAdjEndTimeMillis = Math.max(inMemoryAdjEndTimeMillis
- onDiskAndInMemoryOffsetMillis, 0);
mPersistence.collectHistoricalOpsDLocked(result, uid, packageName, opNames,
- onDiskAdjBeginTimeMillis, onDiskAdjEndTimeMillis);
+ onDiskAdjBeginTimeMillis, onDiskAdjEndTimeMillis, flags);
}
// Rebase the result time to be since epoch.
@@ -366,32 +371,31 @@
}
void incrementOpAccessedCount(int op, int uid, @NonNull String packageName,
- @UidState int uidState) {
+ @UidState int uidState, @OpFlags int flags) {
synchronized (mInMemoryLock) {
if (mMode == AppOpsManager.HISTORICAL_MODE_ENABLED_ACTIVE) {
getUpdatedPendingHistoricalOpsMLocked(System.currentTimeMillis())
- .increaseAccessCount(op, uid, packageName, uidState, 1);
-
+ .increaseAccessCount(op, uid, packageName, uidState, flags, 1);
}
}
}
void incrementOpRejected(int op, int uid, @NonNull String packageName,
- @UidState int uidState) {
+ @UidState int uidState, @OpFlags int flags) {
synchronized (mInMemoryLock) {
if (mMode == AppOpsManager.HISTORICAL_MODE_ENABLED_ACTIVE) {
getUpdatedPendingHistoricalOpsMLocked(System.currentTimeMillis())
- .increaseRejectCount(op, uid, packageName, uidState, 1);
+ .increaseRejectCount(op, uid, packageName, uidState, flags, 1);
}
}
}
void increaseOpAccessDuration(int op, int uid, @NonNull String packageName,
- @UidState int uidState, long increment) {
+ @UidState int uidState, @OpFlags int flags, long increment) {
synchronized (mInMemoryLock) {
if (mMode == AppOpsManager.HISTORICAL_MODE_ENABLED_ACTIVE) {
getUpdatedPendingHistoricalOpsMLocked(System.currentTimeMillis())
- .increaseAccessDuration(op, uid, packageName, uidState, increment);
+ .increaseAccessDuration(op, uid, packageName, uidState, flags, increment);
}
}
}
@@ -593,20 +597,20 @@
private static final String TAG_HISTORY = "history";
private static final String TAG_OPS = "ops";
private static final String TAG_UID = "uid";
- private static final String TAG_PACKAGE = "package";
+ private static final String TAG_PACKAGE = "pkg";
private static final String TAG_OP = "op";
- private static final String TAG_STATE = "state";
+ private static final String TAG_STATE = "st";
- private static final String ATTR_VERSION = "version";
- private static final String ATTR_NAME = "name";
- private static final String ATTR_ACCESS_COUNT = "accessCount";
- private static final String ATTR_REJECT_COUNT = "rejectCount";
- private static final String ATTR_ACCESS_DURATION = "accessDuration";
- private static final String ATTR_BEGIN_TIME = "beginTime";
- private static final String ATTR_END_TIME = "endTime";
- private static final String ATTR_OVERFLOW = "overflow";
+ private static final String ATTR_VERSION = "ver";
+ private static final String ATTR_NAME = "na";
+ private static final String ATTR_ACCESS_COUNT = "ac";
+ private static final String ATTR_REJECT_COUNT = "rc";
+ private static final String ATTR_ACCESS_DURATION = "du";
+ private static final String ATTR_BEGIN_TIME = "beg";
+ private static final String ATTR_END_TIME = "end";
+ private static final String ATTR_OVERFLOW = "ov";
- private static final int CURRENT_VERSION = 1;
+ private static final int CURRENT_VERSION = 2;
private final long mBaseSnapshotInterval;
private final long mIntervalCompressionMultiplier;
@@ -657,7 +661,8 @@
@Nullable List<HistoricalOps> readHistoryRawDLocked() {
return collectHistoricalOpsBaseDLocked(Process.INVALID_UID /*filterUid*/,
null /*filterPackageName*/, null /*filterOpNames*/,
- 0 /*filterBeginTimeMills*/, Long.MAX_VALUE /*filterEndTimeMills*/);
+ 0 /*filterBeginTimeMills*/, Long.MAX_VALUE /*filterEndTimeMills*/,
+ AppOpsManager.OP_FLAGS_ALL);
}
@Nullable List<HistoricalOps> readHistoryDLocked() {
@@ -697,9 +702,10 @@
private void collectHistoricalOpsDLocked(@NonNull HistoricalOps currentOps,
int filterUid, @NonNull String filterPackageName, @Nullable String[] filterOpNames,
- long filterBeingMillis, long filterEndMillis) {
+ long filterBeingMillis, long filterEndMillis, @OpFlags int filterFlags) {
final List<HistoricalOps> readOps = collectHistoricalOpsBaseDLocked(filterUid,
- filterPackageName, filterOpNames, filterBeingMillis, filterEndMillis);
+ filterPackageName, filterOpNames, filterBeingMillis, filterEndMillis,
+ filterFlags);
if (readOps != null) {
final int readCount = readOps.size();
for (int i = 0; i < readCount; i++) {
@@ -711,7 +717,7 @@
private @Nullable LinkedList<HistoricalOps> collectHistoricalOpsBaseDLocked(
int filterUid, @NonNull String filterPackageName, @Nullable String[] filterOpNames,
- long filterBeginTimeMillis, long filterEndTimeMillis) {
+ long filterBeginTimeMillis, long filterEndTimeMillis, @OpFlags int filterFlags) {
File baseDir = null;
try {
baseDir = mHistoricalAppOpsDir.startRead();
@@ -724,8 +730,8 @@
final long[] globalContentOffsetMillis = {0};
final LinkedList<HistoricalOps> ops = collectHistoricalOpsRecursiveDLocked(
baseDir, filterUid, filterPackageName, filterOpNames, filterBeginTimeMillis,
- filterEndTimeMillis, globalContentOffsetMillis, null /*outOps*/,
- 0 /*depth*/, historyFiles);
+ filterEndTimeMillis, filterFlags, globalContentOffsetMillis,
+ null /*outOps*/, 0 /*depth*/, historyFiles);
if (DEBUG) {
filesInvariant.stopTracking(baseDir);
}
@@ -741,7 +747,8 @@
private @Nullable LinkedList<HistoricalOps> collectHistoricalOpsRecursiveDLocked(
@NonNull File baseDir, int filterUid, @NonNull String filterPackageName,
@Nullable String[] filterOpNames, long filterBeginTimeMillis,
- long filterEndTimeMillis, @NonNull long[] globalContentOffsetMillis,
+ long filterEndTimeMillis, @OpFlags int filterFlags,
+ @NonNull long[] globalContentOffsetMillis,
@Nullable LinkedList<HistoricalOps> outOps, int depth,
@NonNull Set<String> historyFiles)
throws IOException, XmlPullParserException {
@@ -757,7 +764,7 @@
final List<HistoricalOps> readOps = readHistoricalOpsLocked(baseDir,
previousIntervalEndMillis, currentIntervalEndMillis, filterUid,
filterPackageName, filterOpNames, filterBeginTimeMillis, filterEndTimeMillis,
- globalContentOffsetMillis, depth, historyFiles);
+ filterFlags, globalContentOffsetMillis, depth, historyFiles);
// Empty is a special signal to stop diving
if (readOps != null && readOps.isEmpty()) {
@@ -767,7 +774,7 @@
// Collect older historical data from subsequent levels
outOps = collectHistoricalOpsRecursiveDLocked(
baseDir, filterUid, filterPackageName, filterOpNames, filterBeginTimeMillis,
- filterEndTimeMillis, globalContentOffsetMillis, outOps, depth + 1,
+ filterEndTimeMillis, filterFlags, globalContentOffsetMillis, outOps, depth + 1,
historyFiles);
// Make older historical data relative to the current historical level
@@ -836,22 +843,24 @@
previousIntervalEndMillis, currentIntervalEndMillis,
Process.INVALID_UID /*filterUid*/, null /*filterPackageName*/,
null /*filterOpNames*/, Long.MIN_VALUE /*filterBeginTimeMillis*/,
- Long.MAX_VALUE /*filterEndTimeMillis*/, null, depth,
- null /*historyFiles*/);
+ Long.MAX_VALUE /*filterEndTimeMillis*/, AppOpsManager.OP_FLAGS_ALL,
+ null, depth, null /*historyFiles*/);
if (DEBUG) {
enforceOpsWellFormed(existingOps);
}
// Offset existing ops to account for elapsed time
- final int existingOpCount = existingOps.size();
- if (existingOpCount > 0) {
- // Compute elapsed time
- final long elapsedTimeMillis = passedOps.get(passedOps.size() - 1)
+ if (existingOps != null) {
+ final int existingOpCount = existingOps.size();
+ if (existingOpCount > 0) {
+ // Compute elapsed time
+ final long elapsedTimeMillis = passedOps.get(passedOps.size() - 1)
.getEndTimeMillis();
- for (int i = 0; i < existingOpCount; i++) {
- final HistoricalOps existingOp = existingOps.get(i);
- existingOp.offsetBeginAndEndTime(elapsedTimeMillis);
+ for (int i = 0; i < existingOpCount; i++) {
+ final HistoricalOps existingOp = existingOps.get(i);
+ existingOp.offsetBeginAndEndTime(elapsedTimeMillis);
+ }
}
}
@@ -864,9 +873,10 @@
// Consolidate passed ops at the current slot duration ensuring each snapshot is
// full. To achieve this we put all passed and existing ops in a list and will
// merge them to ensure each represents a snapshot at the current granularity.
- final List<HistoricalOps> allOps = new LinkedList<>();
- allOps.addAll(passedOps);
- allOps.addAll(existingOps);
+ final List<HistoricalOps> allOps = new LinkedList<>(passedOps);
+ if (existingOps != null) {
+ allOps.addAll(existingOps);
+ }
if (DEBUG) {
enforceOpsWellFormed(allOps);
@@ -944,10 +954,10 @@
overflowedOps, oldFileNames, depth + 1);
}
- private @NonNull List<HistoricalOps> readHistoricalOpsLocked(File baseDir,
- long intervalBeginMillis, long intervalEndMillis, int filterUid,
- @Nullable String filterPackageName, @Nullable String[] filterOpNames,
- long filterBeginTimeMillis, long filterEndTimeMillis,
+ private @Nullable List<HistoricalOps> readHistoricalOpsLocked(File baseDir,
+ long intervalBeginMillis, long intervalEndMillis,
+ int filterUid, @Nullable String filterPackageName, @Nullable String[] filterOpNames,
+ long filterBeginTimeMillis, long filterEndTimeMillis, @OpFlags int filterFlags,
@Nullable long[] cumulativeOverflowMillis, int depth,
@NonNull Set<String> historyFiles)
throws IOException, XmlPullParserException {
@@ -973,12 +983,13 @@
}
}
return readHistoricalOpsLocked(file, filterUid, filterPackageName, filterOpNames,
- filterBeginTimeMillis, filterEndTimeMillis, cumulativeOverflowMillis);
+ filterBeginTimeMillis, filterEndTimeMillis, filterFlags,
+ cumulativeOverflowMillis);
}
private @Nullable List<HistoricalOps> readHistoricalOpsLocked(@NonNull File file,
int filterUid, @Nullable String filterPackageName, @Nullable String[] filterOpNames,
- long filterBeginTimeMillis, long filterEndTimeMillis,
+ long filterBeginTimeMillis, long filterEndTimeMillis, @OpFlags int filterFlags,
@Nullable long[] cumulativeOverflowMillis)
throws IOException, XmlPullParserException {
if (DEBUG) {
@@ -989,13 +1000,22 @@
final XmlPullParser parser = Xml.newPullParser();
parser.setInput(stream, StandardCharsets.UTF_8.name());
XmlUtils.beginDocument(parser, TAG_HISTORY);
+
+ // We haven't released version 1 and have more detailed
+ // accounting - just nuke the current state
+ final int version = XmlUtils.readIntAttribute(parser, ATTR_VERSION);
+ if (CURRENT_VERSION == 2 && version < CURRENT_VERSION) {
+ throw new IllegalStateException("Dropping unsupported history "
+ + "version 1 for file:" + file);
+ }
+
final long overflowMillis = XmlUtils.readLongAttribute(parser, ATTR_OVERFLOW, 0);
final int depth = parser.getDepth();
while (XmlUtils.nextElementWithin(parser, depth)) {
if (TAG_OPS.equals(parser.getName())) {
final HistoricalOps ops = readeHistoricalOpsDLocked(parser,
filterUid, filterPackageName, filterOpNames, filterBeginTimeMillis,
- filterEndTimeMillis, cumulativeOverflowMillis);
+ filterEndTimeMillis, filterFlags, cumulativeOverflowMillis);
if (ops == null) {
continue;
}
@@ -1029,7 +1049,8 @@
private @Nullable HistoricalOps readeHistoricalOpsDLocked(
@NonNull XmlPullParser parser, int filterUid, @Nullable String filterPackageName,
@Nullable String[] filterOpNames, long filterBeginTimeMillis,
- long filterEndTimeMillis, @Nullable long[] cumulativeOverflowMillis)
+ long filterEndTimeMillis, @OpFlags int filterFlags,
+ @Nullable long[] cumulativeOverflowMillis)
throws IOException, XmlPullParserException {
final long beginTimeMillis = XmlUtils.readLongAttribute(parser, ATTR_BEGIN_TIME, 0)
+ (cumulativeOverflowMillis != null ? cumulativeOverflowMillis[0] : 0);
@@ -1045,6 +1066,10 @@
}
final long filteredBeginTimeMillis = Math.max(beginTimeMillis, filterBeginTimeMillis);
final long filteredEndTimeMillis = Math.min(endTimeMillis, filterEndTimeMillis);
+ // // Keep reading as subsequent records may start matching
+ // if (filteredEndTimeMillis - filterBeginTimeMillis <= 0) {
+ // return null;
+ // }
final double filterScale = (double) (filteredEndTimeMillis - filteredBeginTimeMillis)
/ (double) (endTimeMillis - beginTimeMillis);
HistoricalOps ops = null;
@@ -1052,7 +1077,7 @@
while (XmlUtils.nextElementWithin(parser, depth)) {
if (TAG_UID.equals(parser.getName())) {
final HistoricalOps returnedOps = readHistoricalUidOpsDLocked(ops, parser,
- filterUid, filterPackageName, filterOpNames, filterScale);
+ filterUid, filterPackageName, filterOpNames, filterFlags, filterScale);
if (ops == null) {
ops = returnedOps;
}
@@ -1067,7 +1092,8 @@
private @Nullable HistoricalOps readHistoricalUidOpsDLocked(
@Nullable HistoricalOps ops, @NonNull XmlPullParser parser, int filterUid,
@Nullable String filterPackageName, @Nullable String[] filterOpNames,
- double filterScale) throws IOException, XmlPullParserException {
+ @OpFlags int filterFlags, double filterScale)
+ throws IOException, XmlPullParserException {
final int uid = XmlUtils.readIntAttribute(parser, ATTR_NAME);
if (filterUid != Process.INVALID_UID && filterUid != uid) {
XmlUtils.skipCurrentTag(parser);
@@ -1077,7 +1103,8 @@
while (XmlUtils.nextElementWithin(parser, depth)) {
if (TAG_PACKAGE.equals(parser.getName())) {
final HistoricalOps returnedOps = readHistoricalPackageOpsDLocked(ops,
- uid, parser, filterPackageName, filterOpNames, filterScale);
+ uid, parser, filterPackageName, filterOpNames, filterFlags,
+ filterScale);
if (ops == null) {
ops = returnedOps;
}
@@ -1089,7 +1116,8 @@
private @Nullable HistoricalOps readHistoricalPackageOpsDLocked(
@Nullable HistoricalOps ops, int uid, @NonNull XmlPullParser parser,
@Nullable String filterPackageName, @Nullable String[] filterOpNames,
- double filterScale) throws IOException, XmlPullParserException {
+ @OpFlags int filterFlags, double filterScale)
+ throws IOException, XmlPullParserException {
final String packageName = XmlUtils.readStringAttribute(parser, ATTR_NAME);
if (filterPackageName != null && !filterPackageName.equals(packageName)) {
XmlUtils.skipCurrentTag(parser);
@@ -1099,7 +1127,7 @@
while (XmlUtils.nextElementWithin(parser, depth)) {
if (TAG_OP.equals(parser.getName())) {
final HistoricalOps returnedOps = readHistoricalOpDLocked(ops, uid,
- packageName, parser, filterOpNames, filterScale);
+ packageName, parser, filterOpNames, filterFlags, filterScale);
if (ops == null) {
ops = returnedOps;
}
@@ -1110,7 +1138,7 @@
private @Nullable HistoricalOps readHistoricalOpDLocked(@Nullable HistoricalOps ops,
int uid, String packageName, @NonNull XmlPullParser parser,
- @Nullable String[] filterOpNames, double filterScale)
+ @Nullable String[] filterOpNames, @OpFlags int filterFlags, double filterScale)
throws IOException, XmlPullParserException {
final int op = XmlUtils.readIntAttribute(parser, ATTR_NAME);
if (filterOpNames != null && !ArrayUtils.contains(filterOpNames,
@@ -1121,8 +1149,8 @@
final int depth = parser.getDepth();
while (XmlUtils.nextElementWithin(parser, depth)) {
if (TAG_STATE.equals(parser.getName())) {
- final HistoricalOps returnedOps = readUidStateDLocked(ops, uid,
- packageName, op, parser, filterScale);
+ final HistoricalOps returnedOps = readStateDLocked(ops, uid,
+ packageName, op, parser, filterFlags, filterScale);
if (ops == null) {
ops = returnedOps;
}
@@ -1131,10 +1159,15 @@
return ops;
}
- private @Nullable HistoricalOps readUidStateDLocked(@Nullable HistoricalOps ops,
+ private @Nullable HistoricalOps readStateDLocked(@Nullable HistoricalOps ops,
int uid, String packageName, int op, @NonNull XmlPullParser parser,
- double filterScale) throws IOException {
- final int uidState = XmlUtils.readIntAttribute(parser, ATTR_NAME);
+ @OpFlags int filterFlags, double filterScale) throws IOException {
+ final long key = XmlUtils.readLongAttribute(parser, ATTR_NAME);
+ final int flags = AppOpsManager.extractFlagsFromKey(key) & filterFlags;
+ if (flags == 0) {
+ return null;
+ }
+ final int uidState = AppOpsManager.extractUidStateFromKey(key);
long accessCount = XmlUtils.readLongAttribute(parser, ATTR_ACCESS_COUNT, 0);
if (accessCount > 0) {
if (!Double.isNaN(filterScale)) {
@@ -1144,7 +1177,7 @@
if (ops == null) {
ops = new HistoricalOps(0, 0);
}
- ops.increaseAccessCount(op, uid, packageName, uidState, accessCount);
+ ops.increaseAccessCount(op, uid, packageName, uidState, flags, accessCount);
}
long rejectCount = XmlUtils.readLongAttribute(parser, ATTR_REJECT_COUNT, 0);
if (rejectCount > 0) {
@@ -1155,7 +1188,7 @@
if (ops == null) {
ops = new HistoricalOps(0, 0);
}
- ops.increaseRejectCount(op, uid, packageName, uidState, rejectCount);
+ ops.increaseRejectCount(op, uid, packageName, uidState, flags, rejectCount);
}
long accessDuration = XmlUtils.readLongAttribute(parser, ATTR_ACCESS_DURATION, 0);
if (accessDuration > 0) {
@@ -1166,7 +1199,7 @@
if (ops == null) {
ops = new HistoricalOps(0, 0);
}
- ops.increaseAccessDuration(op, uid, packageName, uidState, accessDuration);
+ ops.increaseAccessDuration(op, uid, packageName, uidState, flags, accessDuration);
}
return ops;
}
@@ -1241,24 +1274,34 @@
private void writeHistoricalOpDLocked(@NonNull HistoricalOp op,
@NonNull XmlSerializer serializer) throws IOException {
+ final LongSparseArray keys = op.collectKeys();
+ if (keys == null || keys.size() <= 0) {
+ return;
+ }
serializer.startTag(null, TAG_OP);
serializer.attribute(null, ATTR_NAME, Integer.toString(op.getOpCode()));
- for (int uidState = 0; uidState < AppOpsManager._NUM_UID_STATE; uidState++) {
- writeUidStateOnLocked(op, uidState, serializer);
+ final int keyCount = keys.size();
+ for (int i = 0; i < keyCount; i++) {
+ writeStateOnLocked(op, keys.keyAt(i), serializer);
}
serializer.endTag(null, TAG_OP);
}
- private void writeUidStateOnLocked(@NonNull HistoricalOp op, @UidState int uidState,
+ private void writeStateOnLocked(@NonNull HistoricalOp op, long key,
@NonNull XmlSerializer serializer) throws IOException {
- final long accessCount = op.getAccessCount(uidState);
- final long rejectCount = op.getRejectCount(uidState);
- final long accessDuration = op.getAccessDuration(uidState);
- if (accessCount == 0 && rejectCount == 0 && accessDuration == 0) {
+ final int uidState = AppOpsManager.extractUidStateFromKey(key);
+ final int flags = AppOpsManager.extractFlagsFromKey(key);
+
+ final long accessCount = op.getAccessCount(uidState, uidState, flags);
+ final long rejectCount = op.getRejectCount(uidState, uidState, flags);
+ final long accessDuration = op.getAccessDuration(uidState, uidState, flags);
+
+ if (accessCount <= 0 && rejectCount <= 0 && accessDuration <= 0) {
return;
}
+
serializer.startTag(null, TAG_STATE);
- serializer.attribute(null, ATTR_NAME, Integer.toString(uidState));
+ serializer.attribute(null, ATTR_NAME, Long.toString(key));
if (accessCount > 0) {
serializer.attribute(null, ATTR_ACCESS_COUNT, Long.toString(accessCount));
}
@@ -1532,24 +1575,29 @@
mWriter.print(mEntryPrefix);
mWriter.print(AppOpsManager.opToName(ops.getOpCode()));
mWriter.println(":");
- for (int uidState = 0; uidState < AppOpsManager._NUM_UID_STATE; uidState++) {
+ final LongSparseArray keys = ops.collectKeys();
+ final int keyCount = keys.size();
+ for (int i = 0; i < keyCount; i++) {
+ final long key = keys.keyAt(i);
+ final int uidState = AppOpsManager.extractUidStateFromKey(key);
+ final int flags = AppOpsManager.extractFlagsFromKey(key);
boolean printedUidState = false;
- final long accessCount = ops.getAccessCount(uidState);
+ final long accessCount = ops.getAccessCount(uidState, uidState, flags);
if (accessCount > 0) {
if (!printedUidState) {
mWriter.print(mUidStatePrefix);
- mWriter.print(AppOpsService.UID_STATE_NAMES[uidState]);
+ mWriter.print(AppOpsManager.keyToString(key));
mWriter.print(" = ");
printedUidState = true;
}
mWriter.print("access=");
mWriter.print(accessCount);
}
- final long rejectCount = ops.getRejectCount(uidState);
+ final long rejectCount = ops.getRejectCount(uidState, uidState, flags);
if (rejectCount > 0) {
if (!printedUidState) {
mWriter.print(mUidStatePrefix);
- mWriter.print(AppOpsService.UID_STATE_NAMES[uidState]);
+ mWriter.print(AppOpsManager.keyToString(key));
mWriter.print(" = ");
printedUidState = true;
} else {
@@ -1558,11 +1606,11 @@
mWriter.print("reject=");
mWriter.print(rejectCount);
}
- final long accessDuration = ops.getAccessDuration(uidState);
+ final long accessDuration = ops.getAccessDuration(uidState, uidState, flags);
if (accessDuration > 0) {
if (!printedUidState) {
mWriter.print(mUidStatePrefix);
- mWriter.print(AppOpsService.UID_STATE_NAMES[uidState]);
+ mWriter.print(AppOpsManager.keyToString(key));
mWriter.print(" = ");
printedUidState = true;
} else {
diff --git a/services/core/java/com/android/server/appop/TEST_MAPPING b/services/core/java/com/android/server/appop/TEST_MAPPING
new file mode 100644
index 0000000..f2e2782
--- /dev/null
+++ b/services/core/java/com/android/server/appop/TEST_MAPPING
@@ -0,0 +1,21 @@
+{
+ "presubmit": [
+ {
+ "name": "CtsAppOpsTestCases"
+ },
+ {
+ "name": "FrameworksServicesTests",
+ "options": [
+ {
+ "include-filter": "com.android.server.appop.AppOpsUpgradeTest"
+ },
+ {
+ "include-filter": "com.android.server.appop.AppOpsServiceTest"
+ },
+ {
+ "include-filter": "com.android.server.appop.AppOpsActiveWatcherTest"
+ }
+ ]
+ }
+ ]
+}
diff --git a/services/core/java/com/android/server/display/DisplayManagerService.java b/services/core/java/com/android/server/display/DisplayManagerService.java
index 1aaaf41..6c00da2 100644
--- a/services/core/java/com/android/server/display/DisplayManagerService.java
+++ b/services/core/java/com/android/server/display/DisplayManagerService.java
@@ -1689,8 +1689,9 @@
* Returns information about the specified logical display.
*
* @param displayId The logical display id.
- * @return The logical display info, or null if the display does not exist. The
- * returned object must be treated as immutable.
+ * @return The logical display info, return {@code null} if the display does not exist or
+ * the calling UID isn't present on the display. The returned object must be treated as
+ * immutable.
*/
@Override // Binder call
public DisplayInfo getDisplayInfo(int displayId) {
@@ -1717,6 +1718,16 @@
}
}
+ @Override // Binder call
+ public boolean isUidPresentOnDisplay(int uid, int displayId) {
+ final long token = Binder.clearCallingIdentity();
+ try {
+ return isUidPresentOnDisplayInternal(uid, displayId);
+ } finally {
+ Binder.restoreCallingIdentity(token);
+ }
+ }
+
/**
* Returns the stable device display size, in pixels.
*/
@@ -2385,11 +2396,6 @@
}
@Override
- public boolean isUidPresentOnDisplay(int uid, int displayId) {
- return isUidPresentOnDisplayInternal(uid, displayId);
- }
-
- @Override
public void persistBrightnessTrackerState() {
synchronized (mSyncRoot) {
mDisplayPowerController.persistBrightnessTrackerState();
diff --git a/services/core/java/com/android/server/display/LogicalDisplay.java b/services/core/java/com/android/server/display/LogicalDisplay.java
index 7ee8422..b21f0a7 100644
--- a/services/core/java/com/android/server/display/LogicalDisplay.java
+++ b/services/core/java/com/android/server/display/LogicalDisplay.java
@@ -301,6 +301,7 @@
boolean maskCutout =
(deviceInfo.flags & DisplayDeviceInfo.FLAG_MASK_DISPLAY_CUTOUT) != 0;
mBaseDisplayInfo.displayCutout = maskCutout ? null : deviceInfo.displayCutout;
+ mBaseDisplayInfo.displayId = mDisplayId;
mPrimaryDisplayDeviceInfo = deviceInfo;
mInfo = null;
diff --git a/services/core/java/com/android/server/location/GnssLocationProvider.java b/services/core/java/com/android/server/location/GnssLocationProvider.java
index 8e8477a..9ab9975 100644
--- a/services/core/java/com/android/server/location/GnssLocationProvider.java
+++ b/services/core/java/com/android/server/location/GnssLocationProvider.java
@@ -601,12 +601,11 @@
// while IO initialization and registration is delegated to our internal handler
// this approach is just fine because events are posted to our handler anyway
mGnssConfiguration = new GnssConfiguration(mContext);
- sendMessage(INITIALIZE_HANDLER, 0, null);
-
- // Create a GPS net-initiated handler.
+ // Create a GPS net-initiated handler (also needed by handleInitialize)
mNIHandler = new GpsNetInitiatedHandler(context,
mNetInitiatedListener,
mSuplEsEnabled);
+ sendMessage(INITIALIZE_HANDLER, 0, null);
mGnssStatusListenerHelper = new GnssStatusListenerHelper(mContext, mHandler) {
@Override
diff --git a/services/core/java/com/android/server/wm/ActivityRecord.java b/services/core/java/com/android/server/wm/ActivityRecord.java
index f70adef..1783591 100644
--- a/services/core/java/com/android/server/wm/ActivityRecord.java
+++ b/services/core/java/com/android/server/wm/ActivityRecord.java
@@ -564,11 +564,8 @@
pw.print("requestedVrComponent=");
pw.println(requestedVrComponent);
}
- final boolean waitingVisible =
- mStackSupervisor.mActivitiesWaitingForVisibleActivity.contains(this);
- if (lastVisibleTime != 0 || waitingVisible || nowVisible) {
- pw.print(prefix); pw.print("waitingVisible="); pw.print(waitingVisible);
- pw.print(" nowVisible="); pw.print(nowVisible);
+ if (lastVisibleTime != 0 || nowVisible) {
+ pw.print(prefix); pw.print(" nowVisible="); pw.print(nowVisible);
pw.print(" lastVisibleTime=");
if (lastVisibleTime == 0) pw.print("0");
else TimeUtils.formatDuration(lastVisibleTime, now, pw);
@@ -2358,27 +2355,6 @@
if (!nowVisible) {
nowVisible = true;
lastVisibleTime = SystemClock.uptimeMillis();
- if (idle || mStackSupervisor.isStoppingNoHistoryActivity()) {
- // If this activity was already idle or there is an activity that must be
- // stopped immediately after visible, then we now need to make sure we perform
- // the full stop of any activities that are waiting to do so. This is because
- // we won't do that while they are still waiting for this one to become visible.
- final int size = mStackSupervisor.mActivitiesWaitingForVisibleActivity.size();
- if (size > 0) {
- for (int i = 0; i < size; i++) {
- final ActivityRecord r =
- mStackSupervisor.mActivitiesWaitingForVisibleActivity.get(i);
- if (DEBUG_SWITCH) Log.v(TAG_SWITCH, "Was waiting for visible: " + r);
- }
- mStackSupervisor.mActivitiesWaitingForVisibleActivity.clear();
- mStackSupervisor.scheduleIdleLocked();
- }
- } else {
- // Instead of doing the full stop routine here, let's just hide any activities
- // we now can, and let them stop when the normal idle happens.
- mStackSupervisor.processStoppingActivitiesLocked(null /* idleActivity */,
- false /* remove */, true /* processPausingActivities */);
- }
mAtmService.scheduleAppGcsLocked();
}
}
@@ -2392,6 +2368,24 @@
}
}
+ void onAnimationFinished() {
+ if (mRootActivityContainer.allResumedActivitiesIdle()
+ || mStackSupervisor.isStoppingNoHistoryActivity()) {
+ // If all activities are already idle or there is an activity that must be
+ // stopped immediately after visible, then we now need to make sure we perform
+ // the full stop of this activity. This is because we won't do that while they are still
+ // waiting for the animation to finish.
+ if (mStackSupervisor.mStoppingActivities.contains(this)) {
+ mStackSupervisor.scheduleIdleLocked();
+ }
+ } else {
+ // Instead of doing the full stop routine here, let's just hide any activities
+ // we now can, and let them stop when the normal idle happens.
+ mStackSupervisor.processStoppingActivitiesLocked(null /* idleActivity */,
+ false /* remove */, true /* processPausingActivities */);
+ }
+ }
+
/**
* Called when the key dispatching to a window associated with the app window container
* timed-out.
@@ -2424,10 +2418,9 @@
}
private ActivityRecord getWaitingHistoryRecordLocked() {
- // First find the real culprit... if this activity is waiting for
- // another activity to start or has stopped, then the key dispatching
+ // First find the real culprit... if this activity has stopped, then the key dispatching
// timeout should not be caused by this.
- if (mStackSupervisor.mActivitiesWaitingForVisibleActivity.contains(this) || stopped) {
+ if (stopped) {
final ActivityStack stack = mRootActivityContainer.getTopDisplayFocusedStack();
// Try to use the one which is closest to top.
ActivityRecord r = stack.getResumedActivity();
diff --git a/services/core/java/com/android/server/wm/ActivityStack.java b/services/core/java/com/android/server/wm/ActivityStack.java
index 0b034b5..82c0e21 100644
--- a/services/core/java/com/android/server/wm/ActivityStack.java
+++ b/services/core/java/com/android/server/wm/ActivityStack.java
@@ -1807,10 +1807,6 @@
} else if (prev.hasProcess()) {
if (DEBUG_PAUSE) Slog.v(TAG_PAUSE, "Enqueue pending stop if needed: " + prev
+ " wasStopping=" + wasStopping + " visible=" + prev.visible);
- if (mStackSupervisor.mActivitiesWaitingForVisibleActivity.remove(prev)) {
- if (DEBUG_SWITCH || DEBUG_PAUSE) Slog.v(TAG_PAUSE,
- "Complete pause, no longer waiting: " + prev);
- }
if (prev.deferRelaunchUntilPaused) {
// Complete the deferred relaunch that was waiting for pause to complete.
if (DEBUG_PAUSE) Slog.v(TAG_PAUSE, "Re-launching after pause: " + prev);
@@ -1890,16 +1886,6 @@
private void addToStopping(ActivityRecord r, boolean scheduleIdle, boolean idleDelayed) {
if (!mStackSupervisor.mStoppingActivities.contains(r)) {
mStackSupervisor.mStoppingActivities.add(r);
-
- // Some activity is waiting for another activity to become visible before it's being
- // stopped, which means that we also want to wait with stopping this one to avoid
- // flickers.
- if (!mStackSupervisor.mActivitiesWaitingForVisibleActivity.isEmpty()
- && !mStackSupervisor.mActivitiesWaitingForVisibleActivity.contains(r)) {
- if (DEBUG_SWITCH) Slog.i(TAG_SWITCH, "adding to waiting visible activity=" + r
- + " existing=" + mStackSupervisor.mActivitiesWaitingForVisibleActivity);
- mStackSupervisor.mActivitiesWaitingForVisibleActivity.add(r);
- }
}
// If we already have a few activities waiting to stop, then give up
@@ -2715,7 +2701,6 @@
mStackSupervisor.mStoppingActivities.remove(next);
mStackSupervisor.mGoingToSleepActivities.remove(next);
next.sleeping = false;
- mStackSupervisor.mActivitiesWaitingForVisibleActivity.remove(next);
if (DEBUG_SWITCH) Slog.v(TAG_SWITCH, "Resuming " + next);
@@ -2724,11 +2709,6 @@
if (DEBUG_SWITCH || DEBUG_PAUSE || DEBUG_STATES) Slog.v(TAG_PAUSE,
"resumeTopActivityLocked: Skip resume: some activity pausing.");
- // Adding previous activity to the waiting visible list, or it would be stopped
- // before top activity being visible.
- if (prev != null && !next.nowVisible) {
- mStackSupervisor.mActivitiesWaitingForVisibleActivity.add(prev);
- }
return false;
}
@@ -2804,35 +2784,27 @@
mLastNoHistoryActivity = null;
}
- if (prev != null && prev != next) {
- if (!mStackSupervisor.mActivitiesWaitingForVisibleActivity.contains(prev)
- && !next.nowVisible) {
- mStackSupervisor.mActivitiesWaitingForVisibleActivity.add(prev);
+ if (prev != null && prev != next && next.nowVisible) {
+
+ // The next activity is already visible, so hide the previous
+ // activity's windows right now so we can show the new one ASAP.
+ // We only do this if the previous is finishing, which should mean
+ // it is on top of the one being resumed so hiding it quickly
+ // is good. Otherwise, we want to do the normal route of allowing
+ // the resumed activity to be shown so we can decide if the
+ // previous should actually be hidden depending on whether the
+ // new one is found to be full-screen or not.
+ if (prev.finishing) {
+ prev.setVisibility(false);
if (DEBUG_SWITCH) Slog.v(TAG_SWITCH,
- "Resuming top, waiting visible to hide: " + prev);
+ "Not waiting for visible to hide: " + prev
+ + ", nowVisible=" + next.nowVisible);
} else {
- // The next activity is already visible, so hide the previous
- // activity's windows right now so we can show the new one ASAP.
- // We only do this if the previous is finishing, which should mean
- // it is on top of the one being resumed so hiding it quickly
- // is good. Otherwise, we want to do the normal route of allowing
- // the resumed activity to be shown so we can decide if the
- // previous should actually be hidden depending on whether the
- // new one is found to be full-screen or not.
- if (prev.finishing) {
- prev.setVisibility(false);
- if (DEBUG_SWITCH) Slog.v(TAG_SWITCH,
- "Not waiting for visible to hide: " + prev + ", waitingVisible="
- + mStackSupervisor.mActivitiesWaitingForVisibleActivity.contains(prev)
- + ", nowVisible=" + next.nowVisible);
- } else {
- if (DEBUG_SWITCH) Slog.v(TAG_SWITCH,
- "Previous already visible but still waiting to hide: " + prev
- + ", waitingVisible="
- + mStackSupervisor.mActivitiesWaitingForVisibleActivity.contains(prev)
- + ", nowVisible=" + next.nowVisible);
- }
+ if (DEBUG_SWITCH) Slog.v(TAG_SWITCH,
+ "Previous already visible but still waiting to hide: " + prev
+ + ", nowVisible=" + next.nowVisible);
}
+
}
// Launching this app's activity, make sure the app is no longer
@@ -4089,9 +4061,6 @@
dc.prepareAppTransition(transit, false);
r.setVisibility(false);
dc.executeAppTransition();
- if (!mStackSupervisor.mActivitiesWaitingForVisibleActivity.contains(r)) {
- mStackSupervisor.mActivitiesWaitingForVisibleActivity.add(r);
- }
}
static final int FINISH_IMMEDIATELY = 0;
@@ -4127,7 +4096,6 @@
// make sure the record is cleaned out of other places.
mStackSupervisor.mStoppingActivities.remove(r);
mStackSupervisor.mGoingToSleepActivities.remove(r);
- mStackSupervisor.mActivitiesWaitingForVisibleActivity.remove(r);
final ActivityState prevState = r.getState();
if (DEBUG_STATES) Slog.v(TAG_STATES, "Moving to FINISHING: " + r);
@@ -4733,8 +4701,6 @@
"mStoppingActivities");
removeHistoryRecordsForAppLocked(mStackSupervisor.mGoingToSleepActivities, app,
"mGoingToSleepActivities");
- removeHistoryRecordsForAppLocked(mStackSupervisor.mActivitiesWaitingForVisibleActivity, app,
- "mActivitiesWaitingForVisibleActivity");
removeHistoryRecordsForAppLocked(mStackSupervisor.mFinishingActivities, app,
"mFinishingActivities");
diff --git a/services/core/java/com/android/server/wm/ActivityStackSupervisor.java b/services/core/java/com/android/server/wm/ActivityStackSupervisor.java
index 758a765..d1108cc 100644
--- a/services/core/java/com/android/server/wm/ActivityStackSupervisor.java
+++ b/services/core/java/com/android/server/wm/ActivityStackSupervisor.java
@@ -267,12 +267,6 @@
*/
private final SparseIntArray mCurTaskIdForUser = new SparseIntArray(20);
- /** List of activities that are waiting for a new activity to become visible before completing
- * whatever operation they are supposed to do. */
- // TODO: Remove mActivitiesWaitingForVisibleActivity list and just remove activity from
- // mStoppingActivities when something else comes up.
- final ArrayList<ActivityRecord> mActivitiesWaitingForVisibleActivity = new ArrayList<>();
-
/** List of processes waiting to find out when a specific activity becomes visible. */
private final ArrayList<WaitInfo> mWaitingForActivityVisible = new ArrayList<>();
@@ -550,7 +544,6 @@
// This could happen, for example, if we are trimming activities
// down to the max limit while they are still waiting to finish.
mFinishingActivities.remove(r);
- mActivitiesWaitingForVisibleActivity.remove(r);
for (int i = mWaitingForActivityVisible.size() - 1; i >= 0; --i) {
if (mWaitingForActivityVisible.get(i).matches(r.mActivityComponent)) {
@@ -2142,28 +2135,27 @@
final boolean nowVisible = mRootActivityContainer.allResumedActivitiesVisible();
for (int activityNdx = mStoppingActivities.size() - 1; activityNdx >= 0; --activityNdx) {
ActivityRecord s = mStoppingActivities.get(activityNdx);
- boolean waitingVisible = mActivitiesWaitingForVisibleActivity.contains(s);
+
+ final boolean animating = s.mAppWindowToken.isSelfAnimating();
+
if (DEBUG_STATES) Slog.v(TAG, "Stopping " + s + ": nowVisible=" + nowVisible
- + " waitingVisible=" + waitingVisible + " finishing=" + s.finishing);
- if (waitingVisible && nowVisible) {
- mActivitiesWaitingForVisibleActivity.remove(s);
- waitingVisible = false;
- if (s.finishing) {
- // If this activity is finishing, it is sitting on top of
- // everyone else but we now know it is no longer needed...
- // so get rid of it. Otherwise, we need to go through the
- // normal flow and hide it once we determine that it is
- // hidden by the activities in front of it.
- if (DEBUG_STATES) Slog.v(TAG, "Before stopping, can hide: " + s);
- s.setVisibility(false);
- }
+ + " animating=" + animating + " finishing=" + s.finishing);
+ if (nowVisible && s.finishing) {
+
+ // If this activity is finishing, it is sitting on top of
+ // everyone else but we now know it is no longer needed...
+ // so get rid of it. Otherwise, we need to go through the
+ // normal flow and hide it once we determine that it is
+ // hidden by the activities in front of it.
+ if (DEBUG_STATES) Slog.v(TAG, "Before stopping, can hide: " + s);
+ s.setVisibility(false);
}
if (remove) {
final ActivityStack stack = s.getActivityStack();
final boolean shouldSleepOrShutDown = stack != null
? stack.shouldSleepOrShutDownActivities()
: mService.isSleepingOrShuttingDownLocked();
- if (!waitingVisible || shouldSleepOrShutDown) {
+ if (!animating || shouldSleepOrShutDown) {
if (!processPausingActivities && s.isState(PAUSING)) {
// Defer processing pausing activities in this iteration and reschedule
// a delayed idle to reprocess it again
@@ -2178,9 +2170,6 @@
}
stops.add(s);
- // Make sure to remove it in all cases in case we entered this block with
- // shouldSleepOrShutDown
- mActivitiesWaitingForVisibleActivity.remove(s);
mStoppingActivities.remove(activityNdx);
}
}
diff --git a/services/core/java/com/android/server/wm/AppTransition.java b/services/core/java/com/android/server/wm/AppTransition.java
index 19ff438..bb5a221 100644
--- a/services/core/java/com/android/server/wm/AppTransition.java
+++ b/services/core/java/com/android/server/wm/AppTransition.java
@@ -86,6 +86,7 @@
import android.content.res.Configuration;
import android.content.res.ResourceId;
import android.content.res.Resources;
+import android.content.res.Resources.NotFoundException;
import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.Color;
@@ -123,6 +124,7 @@
import android.view.animation.TranslateAnimation;
import com.android.internal.R;
+import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.util.DumpUtils.Dump;
import com.android.internal.util.function.pooled.PooledLambda;
import com.android.server.AttributeCache;
@@ -558,19 +560,19 @@
}
resId = updateToTranslucentAnimIfNeeded(resId, transit);
if (ResourceId.isValid(resId)) {
- return AnimationUtils.loadAnimation(context, resId);
+ return loadAnimationSafely(context, resId);
}
return null;
}
- Animation loadAnimationRes(LayoutParams lp, int resId) {
+ private Animation loadAnimationRes(LayoutParams lp, int resId) {
Context context = mContext;
if (ResourceId.isValid(resId)) {
AttributeCache.Entry ent = getCachedAnimations(lp);
if (ent != null) {
context = ent.context;
}
- return AnimationUtils.loadAnimation(context, resId);
+ return loadAnimationSafely(context, resId);
}
return null;
}
@@ -579,12 +581,22 @@
if (ResourceId.isValid(resId)) {
AttributeCache.Entry ent = getCachedAnimations(packageName, resId);
if (ent != null) {
- return AnimationUtils.loadAnimation(ent.context, resId);
+ return loadAnimationSafely(ent.context, resId);
}
}
return null;
}
+ @VisibleForTesting
+ Animation loadAnimationSafely(Context context, int resId) {
+ try {
+ return AnimationUtils.loadAnimation(context, resId);
+ } catch (NotFoundException e) {
+ Slog.w(TAG, "Unable to load animation resource", e);
+ return null;
+ }
+ }
+
private int updateToTranslucentAnimIfNeeded(int anim, int transit) {
if (transit == TRANSIT_TRANSLUCENT_ACTIVITY_OPEN && anim == R.anim.activity_open_enter) {
return R.anim.activity_translucent_open_enter;
diff --git a/services/core/java/com/android/server/wm/AppWindowToken.java b/services/core/java/com/android/server/wm/AppWindowToken.java
index 78199d44..220370c 100644
--- a/services/core/java/com/android/server/wm/AppWindowToken.java
+++ b/services/core/java/com/android/server/wm/AppWindowToken.java
@@ -2784,6 +2784,8 @@
getDisplayContent().mAppTransition.notifyAppTransitionFinishedLocked(token);
scheduleAnimation();
+
+ mActivityRecord.onAnimationFinished();
}
@Override
diff --git a/services/core/java/com/android/server/wm/RootActivityContainer.java b/services/core/java/com/android/server/wm/RootActivityContainer.java
index e3beb19..e59b6d7 100644
--- a/services/core/java/com/android/server/wm/RootActivityContainer.java
+++ b/services/core/java/com/android/server/wm/RootActivityContainer.java
@@ -2016,8 +2016,7 @@
final ActivityStack stack = display.getChildAt(stackNdx);
final ActivityRecord r = stack.getResumedActivity();
if (r != null) {
- if (!r.nowVisible
- || mStackSupervisor.mActivitiesWaitingForVisibleActivity.contains(r)) {
+ if (!r.nowVisible) {
return false;
}
foundResumed = true;
@@ -2345,10 +2344,6 @@
printed |= dumpHistoryList(fd, pw, mStackSupervisor.mStoppingActivities, " ",
"Stop", false, !dumpAll,
false, dumpPackage, true, " Activities waiting to stop:", null);
- printed |= dumpHistoryList(fd, pw,
- mStackSupervisor.mActivitiesWaitingForVisibleActivity, " ", "Wait",
- false, !dumpAll, false, dumpPackage, true,
- " Activities waiting for another to become visible:", null);
printed |= dumpHistoryList(fd, pw, mStackSupervisor.mGoingToSleepActivities,
" ", "Sleep", false, !dumpAll,
false, dumpPackage, true, " Activities waiting to sleep:", null);
diff --git a/services/core/java/com/android/server/wm/WindowManagerService.java b/services/core/java/com/android/server/wm/WindowManagerService.java
index d58e204..d3f387c 100644
--- a/services/core/java/com/android/server/wm/WindowManagerService.java
+++ b/services/core/java/com/android/server/wm/WindowManagerService.java
@@ -1179,8 +1179,7 @@
+ displayId + ". Aborting.");
return WindowManagerGlobal.ADD_INVALID_DISPLAY;
}
- if (!displayContent.hasAccess(session.mUid)
- && !mDisplayManagerInternal.isUidPresentOnDisplay(session.mUid, displayId)) {
+ if (!displayContent.hasAccess(session.mUid)) {
Slog.w(TAG_WM, "Attempted to add window to a display for which the application "
+ "does not have access: " + displayId + ". Aborting.");
return WindowManagerGlobal.ADD_INVALID_DISPLAY;
diff --git a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java
index f496e81..36251f5 100644
--- a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java
+++ b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java
@@ -172,7 +172,6 @@
import android.os.IBinder;
import android.os.Looper;
import android.os.ParcelFileDescriptor;
-import android.os.ParcelableException;
import android.os.PersistableBundle;
import android.os.PowerManager;
import android.os.PowerManagerInternal;
@@ -5338,9 +5337,14 @@
*/
@Override
public long getRequiredStrongAuthTimeout(ComponentName who, int userId, boolean parent) {
- if (!mHasFeature || !mLockPatternUtils.hasSecureLockScreen()) {
+ if (!mHasFeature) {
return DevicePolicyManager.DEFAULT_STRONG_AUTH_TIMEOUT_MS;
}
+ if (!mLockPatternUtils.hasSecureLockScreen()) {
+ // No strong auth timeout on devices not supporting the
+ // {@link PackageManager#FEATURE_SECURE_LOCK_SCREEN} feature
+ return 0;
+ }
enforceFullCrossUsersPermission(userId);
synchronized (getLockObject()) {
if (who != null) {
diff --git a/services/tests/mockingservicestests/src/com/android/server/AppStateTrackerTest.java b/services/tests/mockingservicestests/src/com/android/server/AppStateTrackerTest.java
index c8e6782..d0158e0 100644
--- a/services/tests/mockingservicestests/src/com/android/server/AppStateTrackerTest.java
+++ b/services/tests/mockingservicestests/src/com/android/server/AppStateTrackerTest.java
@@ -685,10 +685,10 @@
List<OpEntry> entries = new ArrayList<>();
entries.add(new OpEntry(
AppOpsManager.OP_ACCESS_NOTIFICATIONS,
- AppOpsManager.MODE_IGNORED, 0, 0, 0, 0, null));
+ AppOpsManager.MODE_IGNORED));
entries.add(new OpEntry(
AppStateTracker.TARGET_OP,
- AppOpsManager.MODE_IGNORED, 0, 0, 0, 0, null));
+ AppOpsManager.MODE_IGNORED));
ops.add(new PackageOps(PACKAGE_1, UID_1, entries));
@@ -696,7 +696,7 @@
entries = new ArrayList<>();
entries.add(new OpEntry(
AppStateTracker.TARGET_OP,
- AppOpsManager.MODE_IGNORED, 0, 0, 0, 0, null));
+ AppOpsManager.MODE_IGNORED));
ops.add(new PackageOps(PACKAGE_2, UID_2, entries));
@@ -704,7 +704,7 @@
entries = new ArrayList<>();
entries.add(new OpEntry(
AppStateTracker.TARGET_OP,
- AppOpsManager.MODE_ALLOWED, 0, 0, 0, 0, null));
+ AppOpsManager.MODE_ALLOWED));
ops.add(new PackageOps(PACKAGE_1, UID_10_1, entries));
@@ -712,10 +712,10 @@
entries = new ArrayList<>();
entries.add(new OpEntry(
AppStateTracker.TARGET_OP,
- AppOpsManager.MODE_IGNORED, 0, 0, 0, 0, null));
+ AppOpsManager.MODE_IGNORED));
entries.add(new OpEntry(
AppOpsManager.OP_ACCESS_NOTIFICATIONS,
- AppOpsManager.MODE_IGNORED, 0, 0, 0, 0, null));
+ AppOpsManager.MODE_IGNORED));
ops.add(new PackageOps(PACKAGE_3, UID_10_3, entries));
diff --git a/services/tests/runtests.py b/services/tests/runtests.py
index f19cc5d..4c8b4ba 100755
--- a/services/tests/runtests.py
+++ b/services/tests/runtests.py
@@ -19,7 +19,7 @@
import sys
INSTRUMENTED_PACKAGE_RUNNER = ('com.android.frameworks.servicestests/'
- 'android.support.test.runner.AndroidJUnitRunner')
+ 'androidx.test.runner.AndroidJUnitRunner')
PACKAGE_WHITELIST = (
"com.android.server",
diff --git a/services/tests/servicestests/src/com/android/server/appop/AppOpsNotedWatcherTest.java b/services/tests/servicestests/src/com/android/server/appop/AppOpsNotedWatcherTest.java
index edd89f9..96f329b 100644
--- a/services/tests/servicestests/src/com/android/server/appop/AppOpsNotedWatcherTest.java
+++ b/services/tests/servicestests/src/com/android/server/appop/AppOpsNotedWatcherTest.java
@@ -45,21 +45,6 @@
private static final long NOTIFICATION_TIMEOUT_MILLIS = 5000;
- public void testWatchNotedOpsRequiresPermission() {
- // Create a mock listener
- final OnOpNotedListener listener = mock(OnOpNotedListener.class);
-
- // Try to start watching noted ops
- final AppOpsManager appOpsManager = getContext().getSystemService(AppOpsManager.class);
- try {
- appOpsManager.startWatchingNoted(new int[]{AppOpsManager.OP_FINE_LOCATION,
- AppOpsManager.OP_RECORD_AUDIO}, listener);
- fail("Watching noted ops shoudl require " + Manifest.permission.WATCH_APPOPS);
- } catch (SecurityException expected) {
- /*ignored*/
- }
- }
-
@Test
public void testWatchNotedOps() {
// Create a mock listener
diff --git a/services/tests/servicestests/src/com/android/server/appop/AppOpsUpgradeTest.java b/services/tests/servicestests/src/com/android/server/appop/AppOpsUpgradeTest.java
index eb0c627..66d2bab 100644
--- a/services/tests/servicestests/src/com/android/server/appop/AppOpsUpgradeTest.java
+++ b/services/tests/servicestests/src/com/android/server/appop/AppOpsUpgradeTest.java
@@ -107,8 +107,8 @@
}
final AppOpsService.Op _op1 = ops.get(op1);
final AppOpsService.Op _op2 = ops.get(op2);
- final int mode1 = (_op1 == null) ? defaultModeOp1 : _op1.mode;
- final int mode2 = (_op2 == null) ? defaultModeOp2 : _op2.mode;
+ final int mode1 = (_op1 == null) ? defaultModeOp1 : _op1.getMode();
+ final int mode2 = (_op2 == null) ? defaultModeOp2 : _op2.getMode();
assertEquals(mode1, mode2);
if (mode1 != defaultModeOp1) {
numberOfNonDefaultOps++;
diff --git a/services/tests/wmtests/src/com/android/server/wm/AppTransitionTests.java b/services/tests/wmtests/src/com/android/server/wm/AppTransitionTests.java
index b91f3ec..6e09167 100644
--- a/services/tests/wmtests/src/com/android/server/wm/AppTransitionTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/AppTransitionTests.java
@@ -23,29 +23,29 @@
import static android.view.WindowManager.TRANSIT_CRASHING_ACTIVITY_CLOSE;
import static android.view.WindowManager.TRANSIT_KEYGUARD_GOING_AWAY;
import static android.view.WindowManager.TRANSIT_KEYGUARD_UNOCCLUDE;
-
+import static androidx.test.platform.app.InstrumentationRegistry.getInstrumentation;
import static com.android.dx.mockito.inline.extended.ExtendedMockito.anyBoolean;
import static com.android.dx.mockito.inline.extended.ExtendedMockito.doNothing;
import static com.android.dx.mockito.inline.extended.ExtendedMockito.spyOn;
-
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertTrue;
import android.graphics.Rect;
import android.platform.test.annotations.Presubmit;
import android.view.Display;
-import androidx.test.filters.SmallTest;
-
import org.junit.Before;
import org.junit.Test;
+import androidx.test.filters.SmallTest;
+
/**
* Test class for {@link AppTransition}.
*
* Build/Install/Run:
- * atest FrameworksServicesTests:AppTransitionTests
+ * atest WmTests:AppTransitionTests
*/
@SmallTest
@Presubmit
@@ -167,4 +167,11 @@
assertFalse(dc1.mOpeningApps.contains(token1));
}
+ @Test
+ public void testLoadAnimationSafely() {
+ DisplayContent dc = createNewDisplay(Display.STATE_ON);
+ assertNull(dc.mAppTransition.loadAnimationSafely(
+ getInstrumentation().getTargetContext(), -1));
+ }
+
}
diff --git a/startop/iorap/tests/Android.bp b/startop/iorap/tests/Android.bp
index 5ac4a46..4359978 100644
--- a/startop/iorap/tests/Android.bp
+++ b/startop/iorap/tests/Android.bp
@@ -29,7 +29,7 @@
// test android dependencies
"platform-test-annotations",
- "android-support-test",
+ "androidx.test.rules",
// test framework dependencies
"mockito-target-inline-minus-junit4",
// "mockito-target-minus-junit4",
diff --git a/startop/iorap/tests/AndroidManifest.xml b/startop/iorap/tests/AndroidManifest.xml
index 99f4add..b967e72 100644
--- a/startop/iorap/tests/AndroidManifest.xml
+++ b/startop/iorap/tests/AndroidManifest.xml
@@ -22,7 +22,7 @@
<!--suppress AndroidDomInspection -->
<instrumentation
- android:name="android.support.test.runner.AndroidJUnitRunner"
+ android:name="androidx.test.runner.AndroidJUnitRunner"
android:targetPackage="com.google.android.startop.iorap.tests" />
<!--
diff --git a/startop/iorap/tests/AndroidTest.xml b/startop/iorap/tests/AndroidTest.xml
index 919154d..bcd1103 100644
--- a/startop/iorap/tests/AndroidTest.xml
+++ b/startop/iorap/tests/AndroidTest.xml
@@ -44,7 +44,7 @@
<test class="com.android.tradefed.testtype.AndroidJUnitTest" >
<option name="package" value="com.google.android.startop.iorap.tests" />
- <option name="runner" value="android.support.test.runner.AndroidJUnitRunner" />
+ <option name="runner" value="androidx.test.runner.AndroidJUnitRunner" />
</test>
</configuration>
diff --git a/startop/iorap/tests/src/com/google/android/startop/iorap/IIorapIntegrationTest.kt b/startop/iorap/tests/src/com/google/android/startop/iorap/IIorapIntegrationTest.kt
index 16dcbe2..b1e6194 100644
--- a/startop/iorap/tests/src/com/google/android/startop/iorap/IIorapIntegrationTest.kt
+++ b/startop/iorap/tests/src/com/google/android/startop/iorap/IIorapIntegrationTest.kt
@@ -14,12 +14,14 @@
package com.google.android.startop.iorap
-import android.net.Uri
import android.os.ServiceManager
-import android.support.test.filters.MediumTest
+import androidx.test.filters.MediumTest
import org.junit.Test
-import org.junit.Ignore
-import org.mockito.Mockito.*
+import org.mockito.Mockito.argThat
+import org.mockito.Mockito.eq
+import org.mockito.Mockito.inOrder
+import org.mockito.Mockito.spy
+import org.mockito.Mockito.timeout
// @Ignore("Test is disabled until iorapd is added to init and there's selinux policies for it")
@MediumTest
@@ -27,7 +29,7 @@
/**
* @throws ServiceManager.ServiceNotFoundException if iorapd service could not be found
*/
- private val iorapService : IIorap by lazy {
+ private val iorapService: IIorap by lazy {
// TODO: connect to 'iorapd.stub' which doesn't actually do any work other than reply.
IIorap.Stub.asInterface(ServiceManager.getServiceOrThrow("iorapd"))
@@ -39,7 +41,7 @@
// A dummy binder stub implementation is required to use with mockito#spy.
// Mockito overrides the methods at runtime and tracks how methods were invoked.
- open class DummyTaskListener : ITaskListener.Stub() {
+ open class DummyTaskListener : ITaskListener.Stub() {
// Note: make parameters nullable to avoid the kotlin IllegalStateExceptions
// from using the mockito matchers (eq, argThat, etc).
override fun onProgress(requestId: RequestId?, result: TaskResult?) {
@@ -49,7 +51,7 @@
}
}
- private fun testAnyMethod(func : (RequestId) -> Unit) {
+ private fun testAnyMethod(func: (RequestId) -> Unit) {
val taskListener = spy(DummyTaskListener())!!
try {
@@ -68,14 +70,13 @@
// The "stub" behavior of iorapd is that every request immediately gets a response of
// BEGAN,ONGOING,COMPLETED
- inOrder.verify(taskListener, timeout(100)).
- onProgress(eq(requestId), argThat { it!!.state == TaskResult.STATE_BEGAN })
- inOrder.verify(taskListener, timeout(100)).
- onProgress(eq(requestId), argThat { it!!.state == TaskResult.STATE_ONGOING })
- inOrder.verify(taskListener, timeout(100)).
- onComplete(eq(requestId), argThat { it!!.state == TaskResult.STATE_COMPLETED })
+ inOrder.verify(taskListener, timeout(100))
+ .onProgress(eq(requestId), argThat { it!!.state == TaskResult.STATE_BEGAN })
+ inOrder.verify(taskListener, timeout(100))
+ .onProgress(eq(requestId), argThat { it!!.state == TaskResult.STATE_ONGOING })
+ inOrder.verify(taskListener, timeout(100))
+ .onComplete(eq(requestId), argThat { it!!.state == TaskResult.STATE_COMPLETED })
inOrder.verifyNoMoreInteractions()
-
} finally {
// iorapService.setTaskListener(null)
// FIXME: null is broken, C++ side sees a non-null object.
@@ -96,7 +97,7 @@
@Test
fun testOnAppIntentEvent() {
- testAnyMethod { requestId : RequestId ->
+ testAnyMethod { requestId: RequestId ->
iorapService.onAppIntentEvent(requestId, AppIntentEvent.createDefaultIntentChanged(
ActivityInfo("dont care", "dont care"),
ActivityInfo("dont care 2", "dont care 2")))
@@ -105,7 +106,7 @@
@Test
fun testOnSystemServiceEvent() {
- testAnyMethod { requestId : RequestId ->
+ testAnyMethod { requestId: RequestId ->
iorapService.onSystemServiceEvent(requestId,
SystemServiceEvent(SystemServiceEvent.TYPE_START))
}
@@ -113,9 +114,9 @@
@Test
fun testOnSystemServiceUserEvent() {
- testAnyMethod { requestId : RequestId ->
+ testAnyMethod { requestId: RequestId ->
iorapService.onSystemServiceUserEvent(requestId,
- SystemServiceUserEvent(SystemServiceUserEvent.TYPE_START_USER,0))
+ SystemServiceUserEvent(SystemServiceUserEvent.TYPE_START_USER, 0))
}
}
}
diff --git a/startop/iorap/tests/src/com/google/android/startop/iorap/ParcelablesTest.kt b/startop/iorap/tests/src/com/google/android/startop/iorap/ParcelablesTest.kt
index 4abbb3e..8fa0cde 100644
--- a/startop/iorap/tests/src/com/google/android/startop/iorap/ParcelablesTest.kt
+++ b/startop/iorap/tests/src/com/google/android/startop/iorap/ParcelablesTest.kt
@@ -17,7 +17,7 @@
import android.net.Uri
import android.os.Parcel
import android.os.Parcelable
-import android.support.test.filters.SmallTest
+import androidx.test.filters.SmallTest
import org.junit.Test
import org.junit.runner.RunWith
import com.google.common.truth.Truth.assertThat
@@ -29,7 +29,7 @@
*/
@SmallTest
@RunWith(Parameterized::class)
-class ParcelablesTest<T : Parcelable>(private val inputData : InputData<T>) {
+class ParcelablesTest<T : Parcelable>(private val inputData: InputData<T>) {
companion object {
private val initialRequestId = RequestId.nextValueForSequence()!!
@@ -73,19 +73,19 @@
TaskResult(TaskResult.STATE_ONGOING))
)
- private fun newActivityInfo() : ActivityInfo {
+ private fun newActivityInfo(): ActivityInfo {
return ActivityInfo("some package", "some activity")
}
- private fun newActivityInfoOther() : ActivityInfo {
+ private fun newActivityInfoOther(): ActivityInfo {
return ActivityInfo("some package 2", "some activity 2")
}
- private fun newUri() : Uri {
+ private fun newUri(): Uri {
return Uri.parse("https://www.google.com")
}
- private fun cloneRequestId(requestId: RequestId) : RequestId {
+ private fun cloneRequestId(requestId: RequestId): RequestId {
val constructor = requestId::class.java.declaredConstructors[0]
constructor.isAccessible = true
return constructor.newInstance(requestId.requestId) as RequestId
@@ -108,7 +108,7 @@
@Test
fun testParcelRoundTrip() {
// calling writeToParcel and then T::CREATOR.createFromParcel would return the same data.
- val assertParcels = { it : T, data : InputData<T> ->
+ val assertParcels = { it: T, data: InputData<T> ->
val parcel = Parcel.obtain()
it.writeToParcel(parcel, 0)
parcel.setDataPosition(0) // future reads will see all previous writes.
@@ -121,7 +121,7 @@
assertParcels(inputData.validOther, inputData)
}
- data class InputData<T : Parcelable>(val valid : T, val validCopy : T, val validOther : T) {
+ data class InputData<T : Parcelable>(val valid: T, val validCopy: T, val validOther: T) {
val kls = valid.javaClass
init {
assertThat(valid).isNotSameAs(validCopy)
@@ -130,8 +130,8 @@
assertThat(validOther.javaClass).isEqualTo(valid.javaClass)
}
- fun createFromParcel(parcel : Parcel) : T {
- val field = kls.getDeclaredField("CREATOR")
+ fun createFromParcel(parcel: Parcel): T {
+ val field = kls.getDeclaredField("CREATOR")
val creator = field.get(null) as Parcelable.Creator<T>
return creator.createFromParcel(parcel)
diff --git a/startop/view_compiler/dex_builder_test/Android.bp b/startop/view_compiler/dex_builder_test/Android.bp
index ac60e96..22a3cfa 100644
--- a/startop/view_compiler/dex_builder_test/Android.bp
+++ b/startop/view_compiler/dex_builder_test/Android.bp
@@ -43,7 +43,7 @@
sdk_version: "current",
data: [":generate_dex_testcases", ":generate_compiled_layout1", ":generate_compiled_layout2"],
static_libs: [
- "android-support-test",
+ "androidx.test.rules",
"guava",
],
manifest: "AndroidManifest.xml",
diff --git a/startop/view_compiler/dex_builder_test/AndroidManifest.xml b/startop/view_compiler/dex_builder_test/AndroidManifest.xml
index 6ac5fc5..b335663 100644
--- a/startop/view_compiler/dex_builder_test/AndroidManifest.xml
+++ b/startop/view_compiler/dex_builder_test/AndroidManifest.xml
@@ -22,7 +22,7 @@
<uses-library android:name="android.test.runner" />
</application>
- <instrumentation android:name="android.support.test.runner.AndroidJUnitRunner"
+ <instrumentation android:name="androidx.test.runner.AndroidJUnitRunner"
android:targetPackage="android.startop.test"
android:label="DexBuilder Tests"/>
diff --git a/startop/view_compiler/dex_builder_test/AndroidTest.xml b/startop/view_compiler/dex_builder_test/AndroidTest.xml
index 92e2a71..82509b9 100644
--- a/startop/view_compiler/dex_builder_test/AndroidTest.xml
+++ b/startop/view_compiler/dex_builder_test/AndroidTest.xml
@@ -31,6 +31,6 @@
<test class="com.android.tradefed.testtype.AndroidJUnitTest" >
<option name="package" value="android.startop.test" />
- <option name="runner" value="android.support.test.runner.AndroidJUnitRunner" />
+ <option name="runner" value="androidx.test.runner.AndroidJUnitRunner" />
</test>
</configuration>
diff --git a/startop/view_compiler/dex_builder_test/src/android/startop/test/DexBuilderTest.java b/startop/view_compiler/dex_builder_test/src/android/startop/test/DexBuilderTest.java
index 42d4161..f7b1674 100644
--- a/startop/view_compiler/dex_builder_test/src/android/startop/test/DexBuilderTest.java
+++ b/startop/view_compiler/dex_builder_test/src/android/startop/test/DexBuilderTest.java
@@ -14,18 +14,14 @@
package android.startop.test;
-import android.content.Context;
-import android.support.test.InstrumentationRegistry;
-import com.google.common.io.ByteStreams;
-import dalvik.system.InMemoryDexClassLoader;
import dalvik.system.PathClassLoader;
-import java.io.InputStream;
-import java.lang.reflect.InvocationTargetException;
-import java.lang.reflect.Method;
-import java.nio.ByteBuffer;
+
import org.junit.Assert;
import org.junit.Test;
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+
// Adding tests here requires changes in several other places. See README.md in
// the view_compiler directory for more information.
public class DexBuilderTest {
diff --git a/startop/view_compiler/dex_builder_test/src/android/startop/test/LayoutCompilerTest.java b/startop/view_compiler/dex_builder_test/src/android/startop/test/LayoutCompilerTest.java
index a3b1b6c..3dfb20c 100644
--- a/startop/view_compiler/dex_builder_test/src/android/startop/test/LayoutCompilerTest.java
+++ b/startop/view_compiler/dex_builder_test/src/android/startop/test/LayoutCompilerTest.java
@@ -15,18 +15,15 @@
package android.startop.test;
import android.content.Context;
-import android.support.test.InstrumentationRegistry;
-import android.view.View;
-import com.google.common.io.ByteStreams;
-import dalvik.system.InMemoryDexClassLoader;
+
+import androidx.test.InstrumentationRegistry;
+
import dalvik.system.PathClassLoader;
-import java.io.InputStream;
-import java.lang.reflect.InvocationTargetException;
-import java.lang.reflect.Method;
-import java.nio.ByteBuffer;
-import org.junit.Assert;
+
import org.junit.Test;
+import java.lang.reflect.Method;
+
// Adding tests here requires changes in several other places. See README.md in
// the view_compiler directory for more information.
public class LayoutCompilerTest {
diff --git a/telephony/java/android/provider/Telephony.java b/telephony/java/android/provider/Telephony.java
index 79b7807..9d46300 100644
--- a/telephony/java/android/provider/Telephony.java
+++ b/telephony/java/android/provider/Telephony.java
@@ -1191,8 +1191,8 @@
* Broadcast Action: A debug code has been entered in the dialer. This intent is
* broadcast by the system and OEM telephony apps may need to receive these broadcasts.
* These "secret codes" are used to activate developer menus by dialing certain codes.
- * And they are of the form {@code *#*#<code>#*#*}. The intent will have the data
- * URI: {@code android_secret_code://<code>}. It is possible that a manifest
+ * And they are of the form {@code *#*#<code>#*#*}. The intent will have the data
+ * URI: {@code android_secret_code://<code>}. It is possible that a manifest
* receiver would be woken up even if it is not currently running.
*
* <p>Requires {@code android.Manifest.permission#CONTROL_INCALL_EXPERIENCE} to
diff --git a/telephony/java/android/telephony/CallAttributes.java b/telephony/java/android/telephony/CallAttributes.java
index 368f0c6..3a34005 100644
--- a/telephony/java/android/telephony/CallAttributes.java
+++ b/telephony/java/android/telephony/CallAttributes.java
@@ -16,6 +16,7 @@
package android.telephony;
+import android.annotation.NonNull;
import android.annotation.SystemApi;
import android.os.Parcel;
import android.os.Parcelable;
@@ -29,15 +30,15 @@
* @hide
*/
@SystemApi
-public class CallAttributes implements Parcelable {
+public final class CallAttributes implements Parcelable {
private PreciseCallState mPreciseCallState;
@NetworkType
private int mNetworkType; // TelephonyManager.NETWORK_TYPE_* ints
private CallQuality mCallQuality;
- public CallAttributes(PreciseCallState state, @NetworkType int networkType,
- CallQuality callQuality) {
+ public CallAttributes(@NonNull PreciseCallState state, @NetworkType int networkType,
+ @NonNull CallQuality callQuality) {
this.mPreciseCallState = state;
this.mNetworkType = networkType;
this.mCallQuality = callQuality;
@@ -59,6 +60,7 @@
/**
* Returns the {@link PreciseCallState} of the call.
*/
+ @NonNull
public PreciseCallState getPreciseCallState() {
return mPreciseCallState;
}
@@ -96,6 +98,7 @@
/**
* Returns the {#link CallQuality} of the call.
*/
+ @NonNull
public CallQuality getCallQuality() {
return mCallQuality;
}
diff --git a/telephony/java/android/telephony/CarrierRestrictionRules.java b/telephony/java/android/telephony/CarrierRestrictionRules.java
index 47ce632..78623e7 100644
--- a/telephony/java/android/telephony/CarrierRestrictionRules.java
+++ b/telephony/java/android/telephony/CarrierRestrictionRules.java
@@ -177,7 +177,8 @@
* @return a list of boolean with the same size as input, indicating if each
* {@link CarrierIdentifier} is allowed or not.
*/
- public List<Boolean> isCarrierIdentifiersAllowed(@NonNull List<CarrierIdentifier> carrierIds) {
+ public @NonNull List<Boolean> areCarrierIdentifiersAllowed(
+ @NonNull List<CarrierIdentifier> carrierIds) {
ArrayList<Boolean> result = new ArrayList<>(carrierIds.size());
// First calculate the result for each slot independently
@@ -332,7 +333,7 @@
/**
* Builder for a {@link CarrierRestrictionRules}.
*/
- public static class Builder {
+ public static final class Builder {
private final CarrierRestrictionRules mRules;
/** {@hide} */
@@ -341,14 +342,14 @@
}
/** build command */
- public CarrierRestrictionRules build() {
+ public @NonNull CarrierRestrictionRules build() {
return mRules;
}
/**
* Indicate that all carriers are allowed.
*/
- public Builder setAllCarriersAllowed() {
+ public @NonNull Builder setAllCarriersAllowed() {
mRules.mAllowedCarriers.clear();
mRules.mExcludedCarriers.clear();
mRules.mCarrierRestrictionDefault = CARRIER_RESTRICTION_DEFAULT_ALLOWED;
@@ -360,7 +361,8 @@
*
* @param allowedCarriers list of allowed carriers
*/
- public Builder setAllowedCarriers(List<CarrierIdentifier> allowedCarriers) {
+ public @NonNull Builder setAllowedCarriers(
+ @NonNull List<CarrierIdentifier> allowedCarriers) {
mRules.mAllowedCarriers = new ArrayList<CarrierIdentifier>(allowedCarriers);
return this;
}
@@ -370,7 +372,8 @@
*
* @param excludedCarriers list of excluded carriers
*/
- public Builder setExcludedCarriers(List<CarrierIdentifier> excludedCarriers) {
+ public @NonNull Builder setExcludedCarriers(
+ @NonNull List<CarrierIdentifier> excludedCarriers) {
mRules.mExcludedCarriers = new ArrayList<CarrierIdentifier>(excludedCarriers);
return this;
}
@@ -380,7 +383,7 @@
*
* @param carrierRestrictionDefault prioritized carrier list
*/
- public Builder setDefaultCarrierRestriction(
+ public @NonNull Builder setDefaultCarrierRestriction(
@CarrierRestrictionDefault int carrierRestrictionDefault) {
mRules.mCarrierRestrictionDefault = carrierRestrictionDefault;
return this;
@@ -391,7 +394,7 @@
*
* @param multiSimPolicy multi SIM policy
*/
- public Builder setMultiSimPolicy(@MultiSimPolicy int multiSimPolicy) {
+ public @NonNull Builder setMultiSimPolicy(@MultiSimPolicy int multiSimPolicy) {
mRules.mMultiSimPolicy = multiSimPolicy;
return this;
}
diff --git a/telephony/java/android/telephony/TelephonyManager.java b/telephony/java/android/telephony/TelephonyManager.java
index 79c7195..cf2b1ea 100644
--- a/telephony/java/android/telephony/TelephonyManager.java
+++ b/telephony/java/android/telephony/TelephonyManager.java
@@ -2797,8 +2797,8 @@
* (see {@link #hasCarrierPrivileges}).
* <p>
* These "secret codes" are used to activate developer menus by dialing certain codes.
- * And they are of the form {@code *#*#<code>#*#*}. The intent will have the data
- * URI: {@code android_secret_code://<code>}. It is possible that a manifest
+ * And they are of the form {@code *#*#<code>#*#*}. The intent will have the data
+ * URI: {@code android_secret_code://<code>}. It is possible that a manifest
* receiver would be woken up even if it is not currently running.
* <p>
* It is supposed to replace {@link android.provider.Telephony.Sms.Intents#SECRET_CODE_ACTION}
diff --git a/telephony/java/android/telephony/data/ApnSetting.java b/telephony/java/android/telephony/data/ApnSetting.java
index a4ed775..9d072f0 100644
--- a/telephony/java/android/telephony/data/ApnSetting.java
+++ b/telephony/java/android/telephony/data/ApnSetting.java
@@ -19,7 +19,7 @@
import android.annotation.NonNull;
import android.content.ContentValues;
import android.database.Cursor;
-import android.hardware.radio.V1_0.ApnTypes;
+import android.hardware.radio.V1_4.ApnTypes;
import android.net.Uri;
import android.os.Parcel;
import android.os.Parcelable;
@@ -79,7 +79,7 @@
* APN type for all APNs.
* @hide
*/
- public static final int TYPE_ALL = ApnTypes.ALL;
+ public static final int TYPE_ALL = ApnTypes.ALL | ApnTypes.MCX;
/** APN type for default data traffic. */
public static final int TYPE_DEFAULT = ApnTypes.DEFAULT | ApnTypes.HIPRI;
/** APN type for MMS traffic. */
@@ -103,6 +103,8 @@
* for access to carrier services in an emergency call situation.
*/
public static final int TYPE_EMERGENCY = ApnTypes.EMERGENCY;
+ /** APN type for MCX (Mission Critical Service) where X can be PTT/Video/Data */
+ public static final int TYPE_MCX = ApnTypes.MCX;
/** @hide */
@IntDef(flag = true, prefix = { "TYPE_" }, value = {
@@ -115,7 +117,8 @@
TYPE_IMS,
TYPE_CBS,
TYPE_IA,
- TYPE_EMERGENCY
+ TYPE_EMERGENCY,
+ TYPE_MCX
})
@Retention(RetentionPolicy.SOURCE)
public @interface ApnType {}
@@ -206,6 +209,7 @@
APN_TYPE_STRING_MAP.put("cbs", TYPE_CBS);
APN_TYPE_STRING_MAP.put("ia", TYPE_IA);
APN_TYPE_STRING_MAP.put("emergency", TYPE_EMERGENCY);
+ APN_TYPE_STRING_MAP.put("mcx", TYPE_MCX);
APN_TYPE_INT_MAP = new ArrayMap<Integer, String>();
APN_TYPE_INT_MAP.put(TYPE_DEFAULT, "default");
APN_TYPE_INT_MAP.put(TYPE_MMS, "mms");
@@ -217,6 +221,7 @@
APN_TYPE_INT_MAP.put(TYPE_CBS, "cbs");
APN_TYPE_INT_MAP.put(TYPE_IA, "ia");
APN_TYPE_INT_MAP.put(TYPE_EMERGENCY, "emergency");
+ APN_TYPE_INT_MAP.put(TYPE_MCX, "mcx");
PROTOCOL_STRING_MAP = new ArrayMap<String, Integer>();
PROTOCOL_STRING_MAP.put("IP", PROTOCOL_IP);
@@ -1833,7 +1838,7 @@
* {@link ApnSetting} built from this builder otherwise.
*/
public ApnSetting build() {
- if ((mApnTypeBitmask & ApnTypes.ALL) == 0 || TextUtils.isEmpty(mApnName)
+ if ((mApnTypeBitmask & TYPE_ALL) == 0 || TextUtils.isEmpty(mApnName)
|| TextUtils.isEmpty(mEntryName)) {
return null;
}
diff --git a/telephony/java/android/telephony/euicc/EuiccManager.java b/telephony/java/android/telephony/euicc/EuiccManager.java
index ad34349..afbf46d 100644
--- a/telephony/java/android/telephony/euicc/EuiccManager.java
+++ b/telephony/java/android/telephony/euicc/EuiccManager.java
@@ -17,6 +17,7 @@
import android.Manifest;
import android.annotation.IntDef;
+import android.annotation.NonNull;
import android.annotation.Nullable;
import android.annotation.RequiresPermission;
import android.annotation.SdkConstant;
@@ -429,6 +430,7 @@
*
* @return an EuiccManager that uses the given card ID for all calls.
*/
+ @NonNull
public EuiccManager createForCardId(int cardId) {
return new EuiccManager(mContext, cardId);
}
diff --git a/telephony/java/android/telephony/ims/ImsCallSessionListener.java b/telephony/java/android/telephony/ims/ImsCallSessionListener.java
index 337375a..4519a57 100644
--- a/telephony/java/android/telephony/ims/ImsCallSessionListener.java
+++ b/telephony/java/android/telephony/ims/ImsCallSessionListener.java
@@ -16,6 +16,7 @@
package android.telephony.ims;
+import android.annotation.NonNull;
import android.annotation.SystemApi;
import android.os.RemoteException;
import android.telephony.CallQuality;
@@ -619,7 +620,7 @@
*
* @param callQuality The new call quality
*/
- public void callQualityChanged(CallQuality callQuality) {
+ public void callQualityChanged(@NonNull CallQuality callQuality) {
try {
mListener.callQualityChanged(callQuality);
} catch (RemoteException e) {
diff --git a/telephony/java/com/android/internal/telephony/PhoneConstants.java b/telephony/java/com/android/internal/telephony/PhoneConstants.java
index e87d28c..d5061a3 100644
--- a/telephony/java/com/android/internal/telephony/PhoneConstants.java
+++ b/telephony/java/com/android/internal/telephony/PhoneConstants.java
@@ -141,6 +141,8 @@
/** APN type for Emergency PDN. This is not an IA apn, but is used
* for access to carrier services in an emergency call situation. */
public static final String APN_TYPE_EMERGENCY = "emergency";
+ /** APN type for Mission Critical Services */
+ public static final String APN_TYPE_MCX = "mcx";
/** Array of all APN types */
public static final String[] APN_TYPES = {APN_TYPE_DEFAULT,
APN_TYPE_MMS,
@@ -151,7 +153,8 @@
APN_TYPE_IMS,
APN_TYPE_CBS,
APN_TYPE_IA,
- APN_TYPE_EMERGENCY
+ APN_TYPE_EMERGENCY,
+ APN_TYPE_MCX
};
public static final int RIL_CARD_MAX_APPS = 8;
diff --git a/tests/ActivityManagerPerfTests/tests/Android.mk b/tests/ActivityManagerPerfTests/tests/Android.mk
index f23a665..e1f56b8 100644
--- a/tests/ActivityManagerPerfTests/tests/Android.mk
+++ b/tests/ActivityManagerPerfTests/tests/Android.mk
@@ -21,7 +21,7 @@
$(call all-java-files-under, src)
LOCAL_STATIC_JAVA_LIBRARIES := \
- android-support-test \
+ androidx.test.rules \
apct-perftests-utils \
ActivityManagerPerfTestsUtils
diff --git a/tests/ActivityManagerPerfTests/tests/AndroidManifest.xml b/tests/ActivityManagerPerfTests/tests/AndroidManifest.xml
index a1ab33a..04aef47 100644
--- a/tests/ActivityManagerPerfTests/tests/AndroidManifest.xml
+++ b/tests/ActivityManagerPerfTests/tests/AndroidManifest.xml
@@ -25,6 +25,6 @@
<uses-library android:name="android.test.runner" />
</application>
- <instrumentation android:name="android.support.test.runner.AndroidJUnitRunner"
+ <instrumentation android:name="androidx.test.runner.AndroidJUnitRunner"
android:targetPackage="com.android.frameworks.perftests.amtests"/>
</manifest>
diff --git a/tests/ActivityManagerPerfTests/tests/AndroidTest.xml b/tests/ActivityManagerPerfTests/tests/AndroidTest.xml
index ffb5404..76c40b2 100644
--- a/tests/ActivityManagerPerfTests/tests/AndroidTest.xml
+++ b/tests/ActivityManagerPerfTests/tests/AndroidTest.xml
@@ -24,6 +24,6 @@
<option name="test-tag" value="ActivityManagerPerfTests"/>
<test class="com.android.tradefed.testtype.AndroidJUnitTest">
<option name="package" value="com.android.frameworks.perftests.amtests"/>
- <option name="runner" value="android.support.test.runner.AndroidJUnitRunner"/>
+ <option name="runner" value="androidx.test.runner.AndroidJUnitRunner"/>
</test>
</configuration>
\ No newline at end of file
diff --git a/tests/ActivityManagerPerfTests/tests/src/com/android/frameworks/perftests/am/tests/BasePerfTest.java b/tests/ActivityManagerPerfTests/tests/src/com/android/frameworks/perftests/am/tests/BasePerfTest.java
index 58fb136..daff76f 100644
--- a/tests/ActivityManagerPerfTests/tests/src/com/android/frameworks/perftests/am/tests/BasePerfTest.java
+++ b/tests/ActivityManagerPerfTests/tests/src/com/android/frameworks/perftests/am/tests/BasePerfTest.java
@@ -21,7 +21,8 @@
import android.content.ServiceConnection;
import android.perftests.utils.ManualBenchmarkState;
import android.perftests.utils.PerfManualStatusReporter;
-import android.support.test.InstrumentationRegistry;
+
+import androidx.test.InstrumentationRegistry;
import com.android.frameworks.perftests.am.util.TargetPackageUtils;
import com.android.frameworks.perftests.am.util.TimeReceiver;
diff --git a/tests/ActivityManagerPerfTests/tests/src/com/android/frameworks/perftests/am/tests/BroadcastPerfTest.java b/tests/ActivityManagerPerfTests/tests/src/com/android/frameworks/perftests/am/tests/BroadcastPerfTest.java
index f7dab03..bc528d4 100644
--- a/tests/ActivityManagerPerfTests/tests/src/com/android/frameworks/perftests/am/tests/BroadcastPerfTest.java
+++ b/tests/ActivityManagerPerfTests/tests/src/com/android/frameworks/perftests/am/tests/BroadcastPerfTest.java
@@ -17,8 +17,9 @@
package com.android.frameworks.perftests.am.tests;
import android.content.Intent;
-import android.support.test.filters.LargeTest;
-import android.support.test.runner.AndroidJUnit4;
+
+import androidx.test.filters.LargeTest;
+import androidx.test.runner.AndroidJUnit4;
import com.android.frameworks.perftests.am.util.Constants;
diff --git a/tests/ActivityManagerPerfTests/tests/src/com/android/frameworks/perftests/am/tests/ContentProviderPerfTest.java b/tests/ActivityManagerPerfTests/tests/src/com/android/frameworks/perftests/am/tests/ContentProviderPerfTest.java
index 3bf56ce..8e82219 100644
--- a/tests/ActivityManagerPerfTests/tests/src/com/android/frameworks/perftests/am/tests/ContentProviderPerfTest.java
+++ b/tests/ActivityManagerPerfTests/tests/src/com/android/frameworks/perftests/am/tests/ContentProviderPerfTest.java
@@ -17,8 +17,9 @@
package com.android.frameworks.perftests.am.tests;
import android.content.ContentProviderClient;
-import android.support.test.filters.LargeTest;
-import android.support.test.runner.AndroidJUnit4;
+
+import androidx.test.filters.LargeTest;
+import androidx.test.runner.AndroidJUnit4;
import com.android.frameworks.perftests.am.util.TargetPackageUtils;
diff --git a/tests/ActivityManagerPerfTests/tests/src/com/android/frameworks/perftests/am/tests/ServiceBindPerfTest.java b/tests/ActivityManagerPerfTests/tests/src/com/android/frameworks/perftests/am/tests/ServiceBindPerfTest.java
index e1263db..996c5a5 100644
--- a/tests/ActivityManagerPerfTests/tests/src/com/android/frameworks/perftests/am/tests/ServiceBindPerfTest.java
+++ b/tests/ActivityManagerPerfTests/tests/src/com/android/frameworks/perftests/am/tests/ServiceBindPerfTest.java
@@ -21,8 +21,9 @@
import android.content.Intent;
import android.content.ServiceConnection;
import android.os.IBinder;
-import android.support.test.filters.LargeTest;
-import android.support.test.runner.AndroidJUnit4;
+
+import androidx.test.filters.LargeTest;
+import androidx.test.runner.AndroidJUnit4;
import com.android.frameworks.perftests.am.util.Constants;
import com.android.frameworks.perftests.am.util.TargetPackageUtils;
diff --git a/tests/ActivityManagerPerfTests/tests/src/com/android/frameworks/perftests/am/tests/ServiceStartPerfTest.java b/tests/ActivityManagerPerfTests/tests/src/com/android/frameworks/perftests/am/tests/ServiceStartPerfTest.java
index f05f323..ba20640 100644
--- a/tests/ActivityManagerPerfTests/tests/src/com/android/frameworks/perftests/am/tests/ServiceStartPerfTest.java
+++ b/tests/ActivityManagerPerfTests/tests/src/com/android/frameworks/perftests/am/tests/ServiceStartPerfTest.java
@@ -19,8 +19,9 @@
import android.content.ComponentName;
import android.content.Intent;
import android.content.ServiceConnection;
-import android.support.test.filters.LargeTest;
-import android.support.test.runner.AndroidJUnit4;
+
+import androidx.test.filters.LargeTest;
+import androidx.test.runner.AndroidJUnit4;
import com.android.frameworks.perftests.am.util.Constants;
import com.android.frameworks.perftests.am.util.TargetPackageUtils;
diff --git a/tests/ActivityManagerPerfTests/utils/Android.mk b/tests/ActivityManagerPerfTests/utils/Android.mk
index 60c9423..7a7471d 100644
--- a/tests/ActivityManagerPerfTests/utils/Android.mk
+++ b/tests/ActivityManagerPerfTests/utils/Android.mk
@@ -23,7 +23,7 @@
src/com/android/frameworks/perftests/am/util/ITimeReceiverCallback.aidl
LOCAL_STATIC_JAVA_LIBRARIES := \
- android-support-test \
+ androidx.test.rules \
junit \
ub-uiautomator
diff --git a/tests/ActivityManagerPerfTests/utils/src/com/android/frameworks/perftests/am/util/Utils.java b/tests/ActivityManagerPerfTests/utils/src/com/android/frameworks/perftests/am/util/Utils.java
index 67071d2..fc787ba 100644
--- a/tests/ActivityManagerPerfTests/utils/src/com/android/frameworks/perftests/am/util/Utils.java
+++ b/tests/ActivityManagerPerfTests/utils/src/com/android/frameworks/perftests/am/util/Utils.java
@@ -19,10 +19,11 @@
import android.content.Intent;
import android.os.RemoteException;
import android.os.ResultReceiver;
-import android.support.test.InstrumentationRegistry;
import android.support.test.uiautomator.UiDevice;
import android.util.Log;
+import androidx.test.InstrumentationRegistry;
+
import java.io.IOException;
public class Utils {
diff --git a/tests/AppLaunch/Android.mk b/tests/AppLaunch/Android.mk
index 1fb548b..f50bca5 100644
--- a/tests/AppLaunch/Android.mk
+++ b/tests/AppLaunch/Android.mk
@@ -12,7 +12,7 @@
LOCAL_CERTIFICATE := platform
LOCAL_JAVA_LIBRARIES := android.test.base android.test.runner
-LOCAL_STATIC_JAVA_LIBRARIES := android-support-test
+LOCAL_STATIC_JAVA_LIBRARIES := androidx.test.rules
LOCAL_COMPATIBILITY_SUITE := device-tests
diff --git a/tests/AppLaunch/src/com/android/tests/applaunch/AppLaunch.java b/tests/AppLaunch/src/com/android/tests/applaunch/AppLaunch.java
index 5ea8ff1..9d7319f 100644
--- a/tests/AppLaunch/src/com/android/tests/applaunch/AppLaunch.java
+++ b/tests/AppLaunch/src/com/android/tests/applaunch/AppLaunch.java
@@ -30,11 +30,12 @@
import android.os.ParcelFileDescriptor;
import android.os.RemoteException;
import android.os.UserHandle;
-import android.support.test.rule.logging.AtraceLogger;
import android.test.InstrumentationTestCase;
import android.test.InstrumentationTestRunner;
import android.util.Log;
+import androidx.test.rule.logging.AtraceLogger;
+
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.File;
@@ -51,6 +52,7 @@
import java.util.List;
import java.util.Map;
import java.util.Set;
+
/**
* This test is intended to measure the time it takes for the apps to start.
* Names of the applications are passed in command line, and the
diff --git a/tests/AppLaunchWear/Android.mk b/tests/AppLaunchWear/Android.mk
index 6d08366..332b680 100644
--- a/tests/AppLaunchWear/Android.mk
+++ b/tests/AppLaunchWear/Android.mk
@@ -12,7 +12,7 @@
LOCAL_CERTIFICATE := platform
LOCAL_JAVA_LIBRARIES := android.test.base android.test.runner
-LOCAL_STATIC_JAVA_LIBRARIES := android-support-test
+LOCAL_STATIC_JAVA_LIBRARIES := androidx.test.rules
LOCAL_COMPATIBILITY_SUITE := device-tests
diff --git a/tests/AppLaunchWear/src/com/android/tests/applaunch/AppLaunch.java b/tests/AppLaunchWear/src/com/android/tests/applaunch/AppLaunch.java
index d36d84e..97701c6 100644
--- a/tests/AppLaunchWear/src/com/android/tests/applaunch/AppLaunch.java
+++ b/tests/AppLaunchWear/src/com/android/tests/applaunch/AppLaunch.java
@@ -30,16 +30,16 @@
import android.os.ParcelFileDescriptor;
import android.os.RemoteException;
import android.os.UserHandle;
-import android.support.test.rule.logging.AtraceLogger;
import android.test.InstrumentationTestCase;
import android.test.InstrumentationTestRunner;
import android.util.Log;
+import androidx.test.rule.logging.AtraceLogger;
+
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileInputStream;
-import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
@@ -52,6 +52,7 @@
import java.util.List;
import java.util.Map;
import java.util.Set;
+
/**
* This test is intended to measure the time it takes for the apps to start.
* Names of the applications are passed in command line, and the
diff --git a/tests/BackgroundDexOptServiceIntegrationTests/Android.mk b/tests/BackgroundDexOptServiceIntegrationTests/Android.mk
index b10305d..f47cf96 100644
--- a/tests/BackgroundDexOptServiceIntegrationTests/Android.mk
+++ b/tests/BackgroundDexOptServiceIntegrationTests/Android.mk
@@ -24,7 +24,7 @@
LOCAL_SRC_FILES := $(call all-java-files-under, src)
LOCAL_STATIC_JAVA_LIBRARIES := \
- android-support-test \
+ androidx.test.rules \
LOCAL_PACKAGE_NAME := BackgroundDexOptServiceIntegrationTests
LOCAL_PRIVATE_PLATFORM_APIS := true
diff --git a/tests/BackgroundDexOptServiceIntegrationTests/AndroidManifest.xml b/tests/BackgroundDexOptServiceIntegrationTests/AndroidManifest.xml
index afae155..aec9f77 100644
--- a/tests/BackgroundDexOptServiceIntegrationTests/AndroidManifest.xml
+++ b/tests/BackgroundDexOptServiceIntegrationTests/AndroidManifest.xml
@@ -34,7 +34,7 @@
</application>
<instrumentation
- android:name="android.support.test.runner.AndroidJUnitRunner"
+ android:name="androidx.test.runner.AndroidJUnitRunner"
android:targetPackage="com.android.frameworks.bgdexopttest"
android:label="Integration test for BackgroundDexOptService" />
</manifest>
diff --git a/tests/BackgroundDexOptServiceIntegrationTests/AndroidTest.xml b/tests/BackgroundDexOptServiceIntegrationTests/AndroidTest.xml
index 9bb1e28..a532422 100644
--- a/tests/BackgroundDexOptServiceIntegrationTests/AndroidTest.xml
+++ b/tests/BackgroundDexOptServiceIntegrationTests/AndroidTest.xml
@@ -50,6 +50,6 @@
<option name="test-tag" value="BackgroundDexOptServiceIntegrationTests"/>
<test class="com.android.tradefed.testtype.AndroidJUnitTest">
<option name="package" value="com.android.frameworks.bgdexopttest"/>
- <option name="runner" value="android.support.test.runner.AndroidJUnitRunner"/>
+ <option name="runner" value="androidx.test.runner.AndroidJUnitRunner"/>
</test>
</configuration>
diff --git a/tests/BackgroundDexOptServiceIntegrationTests/src/com/android/server/pm/BackgroundDexOptServiceIntegrationTests.java b/tests/BackgroundDexOptServiceIntegrationTests/src/com/android/server/pm/BackgroundDexOptServiceIntegrationTests.java
index fd20f4a..7d826f7 100644
--- a/tests/BackgroundDexOptServiceIntegrationTests/src/com/android/server/pm/BackgroundDexOptServiceIntegrationTests.java
+++ b/tests/BackgroundDexOptServiceIntegrationTests/src/com/android/server/pm/BackgroundDexOptServiceIntegrationTests.java
@@ -17,17 +17,16 @@
package com.android.server.pm;
import android.app.AlarmManager;
-import android.app.UiAutomation;
import android.content.Context;
import android.os.Environment;
import android.os.ParcelFileDescriptor;
import android.os.SystemProperties;
import android.os.storage.StorageManager;
-import android.support.test.InstrumentationRegistry;
import android.util.Log;
+import androidx.test.InstrumentationRegistry;
+
import org.junit.After;
-import org.junit.AfterClass;
import org.junit.Assert;
import org.junit.Before;
import org.junit.BeforeClass;
diff --git a/tests/Camera2Tests/CameraToo/tests/Android.mk b/tests/Camera2Tests/CameraToo/tests/Android.mk
index eb8f6c3..fe4dc42 100644
--- a/tests/Camera2Tests/CameraToo/tests/Android.mk
+++ b/tests/Camera2Tests/CameraToo/tests/Android.mk
@@ -20,6 +20,6 @@
LOCAL_INSTRUMENTATION_FOR := CameraToo
LOCAL_SDK_VERSION := current
LOCAL_SRC_FILES := $(call all-java-files-under,src)
-LOCAL_STATIC_JAVA_LIBRARIES := android-support-test mockito-target-minus-junit4
+LOCAL_STATIC_JAVA_LIBRARIES := androidx.test.rules mockito-target-minus-junit4
include $(BUILD_PACKAGE)
diff --git a/tests/Camera2Tests/CameraToo/tests/AndroidManifest.xml b/tests/Camera2Tests/CameraToo/tests/AndroidManifest.xml
index 30210ba..8d35749 100644
--- a/tests/Camera2Tests/CameraToo/tests/AndroidManifest.xml
+++ b/tests/Camera2Tests/CameraToo/tests/AndroidManifest.xml
@@ -23,7 +23,7 @@
<application android:label="CameraToo">
<uses-library android:name="android.test.runner" />
</application>
- <instrumentation android:name="android.support.test.runner.AndroidJUnitRunner"
+ <instrumentation android:name="androidx.test.runner.AndroidJUnitRunner"
android:targetPackage="com.example.android.camera2.cameratoo"
android:label="CameraToo tests" />
</manifest>
diff --git a/tests/Compatibility/Android.mk b/tests/Compatibility/Android.mk
index 9c47a26..643f9eb 100644
--- a/tests/Compatibility/Android.mk
+++ b/tests/Compatibility/Android.mk
@@ -17,7 +17,7 @@
# We only want this apk build for tests.
LOCAL_MODULE_TAGS := tests
-LOCAL_STATIC_JAVA_LIBRARIES := android-support-test
+LOCAL_STATIC_JAVA_LIBRARIES := androidx.test.rules
# Include all test java files.
LOCAL_SRC_FILES := \
$(call all-java-files-under, src)
diff --git a/tests/Compatibility/src/com/android/compatibilitytest/AppCompatibility.java b/tests/Compatibility/src/com/android/compatibilitytest/AppCompatibility.java
index 95eb5c9..d683ec7 100644
--- a/tests/Compatibility/src/com/android/compatibilitytest/AppCompatibility.java
+++ b/tests/Compatibility/src/com/android/compatibilitytest/AppCompatibility.java
@@ -33,10 +33,11 @@
import android.os.DropBoxManager;
import android.os.RemoteException;
import android.os.ServiceManager;
-import android.support.test.InstrumentationRegistry;
-import android.support.test.runner.AndroidJUnit4;
import android.util.Log;
+import androidx.test.InstrumentationRegistry;
+import androidx.test.runner.AndroidJUnit4;
+
import org.junit.After;
import org.junit.Assert;
import org.junit.Before;
diff --git a/tests/Compatibility/src/com/android/compatibilitytest/AppCompatibilityRunner.java b/tests/Compatibility/src/com/android/compatibilitytest/AppCompatibilityRunner.java
index b61ec34..960ea49 100644
--- a/tests/Compatibility/src/com/android/compatibilitytest/AppCompatibilityRunner.java
+++ b/tests/Compatibility/src/com/android/compatibilitytest/AppCompatibilityRunner.java
@@ -16,7 +16,7 @@
package com.android.compatibilitytest;
-import android.support.test.runner.AndroidJUnitRunner;
+import androidx.test.runner.AndroidJUnitRunner;
// empty subclass to maintain backwards compatibility on host-side harness
public class AppCompatibilityRunner extends AndroidJUnitRunner {}
diff --git a/tests/DynamicCodeLoggerIntegrationTests/Android.mk b/tests/DynamicCodeLoggerIntegrationTests/Android.mk
index f324eb1..62c1ba8 100644
--- a/tests/DynamicCodeLoggerIntegrationTests/Android.mk
+++ b/tests/DynamicCodeLoggerIntegrationTests/Android.mk
@@ -67,7 +67,7 @@
LOCAL_SRC_FILES := $(call all-java-files-under, src/com/android/server/pm)
LOCAL_STATIC_JAVA_LIBRARIES := \
- android-support-test \
+ androidx.test.rules \
truth-prebuilt \
# Include both versions of the .so if we have 2 arch
diff --git a/tests/DynamicCodeLoggerIntegrationTests/AndroidManifest.xml b/tests/DynamicCodeLoggerIntegrationTests/AndroidManifest.xml
index 4327da2..08fac30 100644
--- a/tests/DynamicCodeLoggerIntegrationTests/AndroidManifest.xml
+++ b/tests/DynamicCodeLoggerIntegrationTests/AndroidManifest.xml
@@ -29,7 +29,7 @@
</application>
<instrumentation
- android:name="android.support.test.runner.AndroidJUnitRunner"
+ android:name="androidx.test.runner.AndroidJUnitRunner"
android:targetPackage="com.android.frameworks.dynamiccodeloggertest"
android:label="Integration test for DynamicCodeLogger" />
</manifest>
diff --git a/tests/DynamicCodeLoggerIntegrationTests/AndroidTest.xml b/tests/DynamicCodeLoggerIntegrationTests/AndroidTest.xml
index f70b9c8..f8a1ec9 100644
--- a/tests/DynamicCodeLoggerIntegrationTests/AndroidTest.xml
+++ b/tests/DynamicCodeLoggerIntegrationTests/AndroidTest.xml
@@ -24,7 +24,7 @@
<test class="com.android.tradefed.testtype.AndroidJUnitTest">
<option name="package" value="com.android.frameworks.dynamiccodeloggertest"/>
- <option name="runner" value="android.support.test.runner.AndroidJUnitRunner"/>
+ <option name="runner" value="androidx.test.runner.AndroidJUnitRunner"/>
<option name="hidden-api-checks" value="false"/>
</test>
</configuration>
diff --git a/tests/DynamicCodeLoggerIntegrationTests/src/com/android/server/pm/dex/DynamicCodeLoggerIntegrationTests.java b/tests/DynamicCodeLoggerIntegrationTests/src/com/android/server/pm/dex/DynamicCodeLoggerIntegrationTests.java
index 4f9aeea..db2f659 100644
--- a/tests/DynamicCodeLoggerIntegrationTests/src/com/android/server/pm/dex/DynamicCodeLoggerIntegrationTests.java
+++ b/tests/DynamicCodeLoggerIntegrationTests/src/com/android/server/pm/dex/DynamicCodeLoggerIntegrationTests.java
@@ -24,11 +24,12 @@
import android.os.Build;
import android.os.ParcelFileDescriptor;
import android.os.SystemClock;
-import android.support.test.InstrumentationRegistry;
-import android.support.test.filters.LargeTest;
import android.util.EventLog;
import android.util.EventLog.Event;
+import androidx.test.InstrumentationRegistry;
+import androidx.test.filters.LargeTest;
+
import dalvik.system.DexClassLoader;
import org.junit.Before;
diff --git a/tests/FlickerTests/AndroidManifest.xml b/tests/FlickerTests/AndroidManifest.xml
index ba63940..5b1a36b 100644
--- a/tests/FlickerTests/AndroidManifest.xml
+++ b/tests/FlickerTests/AndroidManifest.xml
@@ -29,7 +29,7 @@
<uses-library android:name="android.test.runner"/>
</application>
- <instrumentation android:name="android.support.test.runner.AndroidJUnitRunner"
+ <instrumentation android:name="androidx.test.runner.AndroidJUnitRunner"
android:targetPackage="com.android.server.wm.flicker"
android:label="WindowManager Flicker Tests">
</instrumentation>
diff --git a/tests/FlickerTests/lib/Android.mk b/tests/FlickerTests/lib/Android.mk
index 6a8dfe8..e438822 100644
--- a/tests/FlickerTests/lib/Android.mk
+++ b/tests/FlickerTests/lib/Android.mk
@@ -24,7 +24,7 @@
LOCAL_PRIVATE_PLATFORM_APIS := true
LOCAL_SRC_FILES := $(call all-java-files-under, src)
LOCAL_STATIC_JAVA_LIBRARIES := \
- ub-janktesthelper \
+ androidx.test.janktesthelper \
cts-amwm-util \
platformprotosnano \
layersprotosnano \
@@ -41,7 +41,7 @@
src/com/android/server/wm/flicker/WindowUtils.java
LOCAL_STATIC_JAVA_LIBRARIES := sysui-helper \
launcher-helper-lib \
- compatibility-device-util
+ compatibility-device-util-axt
include $(BUILD_STATIC_JAVA_LIBRARY)
diff --git a/tests/FlickerTests/lib/src/com/android/server/wm/flicker/AutomationUtils.java b/tests/FlickerTests/lib/src/com/android/server/wm/flicker/AutomationUtils.java
index 6306f0e..e00a247 100644
--- a/tests/FlickerTests/lib/src/com/android/server/wm/flicker/AutomationUtils.java
+++ b/tests/FlickerTests/lib/src/com/android/server/wm/flicker/AutomationUtils.java
@@ -30,7 +30,6 @@
import android.graphics.Point;
import android.graphics.Rect;
import android.os.RemoteException;
-import android.support.test.InstrumentationRegistry;
import android.support.test.launcherhelper.LauncherStrategyFactory;
import android.support.test.uiautomator.By;
import android.support.test.uiautomator.BySelector;
@@ -43,6 +42,8 @@
import android.view.View;
import android.view.ViewConfiguration;
+import androidx.test.InstrumentationRegistry;
+
/**
* Collection of UI Automation helper functions.
*/
diff --git a/tests/FlickerTests/lib/src/com/android/server/wm/flicker/TransitionRunner.java b/tests/FlickerTests/lib/src/com/android/server/wm/flicker/TransitionRunner.java
index f6e8192..0a3fe3c 100644
--- a/tests/FlickerTests/lib/src/com/android/server/wm/flicker/TransitionRunner.java
+++ b/tests/FlickerTests/lib/src/com/android/server/wm/flicker/TransitionRunner.java
@@ -18,9 +18,10 @@
import android.annotation.Nullable;
import android.support.annotation.VisibleForTesting;
-import android.support.test.InstrumentationRegistry;
import android.util.Log;
+import androidx.test.InstrumentationRegistry;
+
import com.android.server.wm.flicker.monitor.ITransitionMonitor;
import com.android.server.wm.flicker.monitor.LayersTraceMonitor;
import com.android.server.wm.flicker.monitor.ScreenRecorder;
diff --git a/tests/FlickerTests/lib/src/com/android/server/wm/flicker/WindowUtils.java b/tests/FlickerTests/lib/src/com/android/server/wm/flicker/WindowUtils.java
index 0da8761..c54396f 100644
--- a/tests/FlickerTests/lib/src/com/android/server/wm/flicker/WindowUtils.java
+++ b/tests/FlickerTests/lib/src/com/android/server/wm/flicker/WindowUtils.java
@@ -20,10 +20,11 @@
import android.content.res.Resources;
import android.graphics.Point;
import android.graphics.Rect;
-import android.support.test.InstrumentationRegistry;
import android.view.Surface;
import android.view.WindowManager;
+import androidx.test.InstrumentationRegistry;
+
/**
* Helper functions to retrieve system window sizes and positions.
*/
diff --git a/tests/FlickerTests/lib/src/com/android/server/wm/flicker/monitor/WindowAnimationFrameStatsMonitor.java b/tests/FlickerTests/lib/src/com/android/server/wm/flicker/monitor/WindowAnimationFrameStatsMonitor.java
index 717d187..3f86f0d 100644
--- a/tests/FlickerTests/lib/src/com/android/server/wm/flicker/monitor/WindowAnimationFrameStatsMonitor.java
+++ b/tests/FlickerTests/lib/src/com/android/server/wm/flicker/monitor/WindowAnimationFrameStatsMonitor.java
@@ -25,7 +25,7 @@
/**
* Monitors {@link android.view.WindowAnimationFrameStats} to detect janky frames.
*
- * Adapted from {@link android.support.test.jank.internal.WindowAnimationFrameStatsMonitorImpl}
+ * Adapted from {@link androidx.test.jank.internal.WindowAnimationFrameStatsMonitorImpl}
* using the same threshold to determine jank.
*/
public class WindowAnimationFrameStatsMonitor implements ITransitionMonitor {
diff --git a/tests/FlickerTests/lib/test/Android.mk b/tests/FlickerTests/lib/test/Android.mk
index 0e3f58d..5be89ba 100644
--- a/tests/FlickerTests/lib/test/Android.mk
+++ b/tests/FlickerTests/lib/test/Android.mk
@@ -25,7 +25,7 @@
LOCAL_SRC_FILES := $(call all-java-files-under, src)
LOCAL_JAVA_LIBRARIES := android.test.runner
LOCAL_STATIC_JAVA_LIBRARIES := \
- android-support-test \
+ androidx.test.rules \
platform-test-annotations \
truth-prebuilt \
platformprotosnano \
diff --git a/tests/FlickerTests/lib/test/AndroidManifest.xml b/tests/FlickerTests/lib/test/AndroidManifest.xml
index d30172d..6451a57 100644
--- a/tests/FlickerTests/lib/test/AndroidManifest.xml
+++ b/tests/FlickerTests/lib/test/AndroidManifest.xml
@@ -18,7 +18,7 @@
<uses-library android:name="android.test.runner"/>
</application>
- <instrumentation android:name="android.support.test.runner.AndroidJUnitRunner"
+ <instrumentation android:name="androidx.test.runner.AndroidJUnitRunner"
android:targetPackage="com.android.server.wm.flicker"
android:label="WindowManager Flicker Lib Test">
</instrumentation>
diff --git a/tests/FlickerTests/lib/test/src/com/android/server/wm/flicker/LayersTraceTest.java b/tests/FlickerTests/lib/test/src/com/android/server/wm/flicker/LayersTraceTest.java
index 42b2aca..7d77126 100644
--- a/tests/FlickerTests/lib/test/src/com/android/server/wm/flicker/LayersTraceTest.java
+++ b/tests/FlickerTests/lib/test/src/com/android/server/wm/flicker/LayersTraceTest.java
@@ -26,9 +26,10 @@
import android.content.Context;
import android.graphics.Point;
import android.graphics.Rect;
-import android.support.test.InstrumentationRegistry;
import android.view.WindowManager;
+import androidx.test.InstrumentationRegistry;
+
import org.junit.Test;
import java.util.List;
diff --git a/tests/FlickerTests/lib/test/src/com/android/server/wm/flicker/TestFileUtils.java b/tests/FlickerTests/lib/test/src/com/android/server/wm/flicker/TestFileUtils.java
index 5a24e6d..c46175c 100644
--- a/tests/FlickerTests/lib/test/src/com/android/server/wm/flicker/TestFileUtils.java
+++ b/tests/FlickerTests/lib/test/src/com/android/server/wm/flicker/TestFileUtils.java
@@ -17,7 +17,8 @@
package com.android.server.wm.flicker;
import android.content.Context;
-import android.support.test.InstrumentationRegistry;
+
+import androidx.test.InstrumentationRegistry;
import com.google.common.io.ByteStreams;
diff --git a/tests/FlickerTests/lib/test/src/com/android/server/wm/flicker/monitor/WindowAnimationFrameStatsMonitorTest.java b/tests/FlickerTests/lib/test/src/com/android/server/wm/flicker/monitor/WindowAnimationFrameStatsMonitorTest.java
index f7fa0d5..dd6fed0 100644
--- a/tests/FlickerTests/lib/test/src/com/android/server/wm/flicker/monitor/WindowAnimationFrameStatsMonitorTest.java
+++ b/tests/FlickerTests/lib/test/src/com/android/server/wm/flicker/monitor/WindowAnimationFrameStatsMonitorTest.java
@@ -18,9 +18,7 @@
import static com.android.server.wm.flicker.AutomationUtils.wakeUpAndGoToHomeScreen;
-import static com.google.common.truth.Truth.assertThat;
-
-import android.support.test.InstrumentationRegistry;
+import androidx.test.InstrumentationRegistry;
import org.junit.Before;
import org.junit.Ignore;
diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/ChangeAppRotationTest.java b/tests/FlickerTests/src/com/android/server/wm/flicker/ChangeAppRotationTest.java
index 34f4ebb..b6860cb 100644
--- a/tests/FlickerTests/src/com/android/server/wm/flicker/ChangeAppRotationTest.java
+++ b/tests/FlickerTests/src/com/android/server/wm/flicker/ChangeAppRotationTest.java
@@ -25,11 +25,12 @@
import static com.android.server.wm.flicker.WmTraceSubject.assertThat;
import android.graphics.Rect;
-import android.support.test.InstrumentationRegistry;
-import android.support.test.filters.LargeTest;
import android.util.Log;
import android.view.Surface;
+import androidx.test.InstrumentationRegistry;
+import androidx.test.filters.LargeTest;
+
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/CloseImeWindowToAppTest.java b/tests/FlickerTests/src/com/android/server/wm/flicker/CloseImeWindowToAppTest.java
index 2b62fcf..6590b86 100644
--- a/tests/FlickerTests/src/com/android/server/wm/flicker/CloseImeWindowToAppTest.java
+++ b/tests/FlickerTests/src/com/android/server/wm/flicker/CloseImeWindowToAppTest.java
@@ -20,9 +20,10 @@
import static com.android.server.wm.flicker.WindowUtils.getDisplayBounds;
import android.platform.helpers.IAppHelper;
-import android.support.test.InstrumentationRegistry;
-import android.support.test.filters.LargeTest;
-import android.support.test.runner.AndroidJUnit4;
+
+import androidx.test.InstrumentationRegistry;
+import androidx.test.filters.LargeTest;
+import androidx.test.runner.AndroidJUnit4;
import org.junit.Before;
import org.junit.Test;
diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/CloseImeWindowToHomeTest.java b/tests/FlickerTests/src/com/android/server/wm/flicker/CloseImeWindowToHomeTest.java
index 42b161f..4771b02 100644
--- a/tests/FlickerTests/src/com/android/server/wm/flicker/CloseImeWindowToHomeTest.java
+++ b/tests/FlickerTests/src/com/android/server/wm/flicker/CloseImeWindowToHomeTest.java
@@ -20,9 +20,10 @@
import static com.android.server.wm.flicker.WindowUtils.getDisplayBounds;
import android.platform.helpers.IAppHelper;
-import android.support.test.InstrumentationRegistry;
-import android.support.test.filters.LargeTest;
-import android.support.test.runner.AndroidJUnit4;
+
+import androidx.test.InstrumentationRegistry;
+import androidx.test.filters.LargeTest;
+import androidx.test.runner.AndroidJUnit4;
import org.junit.Before;
import org.junit.Test;
diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/CommonTransitions.java b/tests/FlickerTests/src/com/android/server/wm/flicker/CommonTransitions.java
index 92bb1ea..65888ac 100644
--- a/tests/FlickerTests/src/com/android/server/wm/flicker/CommonTransitions.java
+++ b/tests/FlickerTests/src/com/android/server/wm/flicker/CommonTransitions.java
@@ -30,7 +30,6 @@
import android.content.Intent;
import android.os.RemoteException;
import android.platform.helpers.IAppHelper;
-import android.support.test.InstrumentationRegistry;
import android.support.test.uiautomator.By;
import android.support.test.uiautomator.UiDevice;
import android.support.test.uiautomator.UiObject2;
@@ -38,6 +37,8 @@
import android.util.Rational;
import android.view.Surface;
+import androidx.test.InstrumentationRegistry;
+
import com.android.server.wm.flicker.TransitionRunner.TransitionBuilder;
/**
diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/DebugTest.java b/tests/FlickerTests/src/com/android/server/wm/flicker/DebugTest.java
index fec248c..61cca0d 100644
--- a/tests/FlickerTests/src/com/android/server/wm/flicker/DebugTest.java
+++ b/tests/FlickerTests/src/com/android/server/wm/flicker/DebugTest.java
@@ -17,12 +17,13 @@
package com.android.server.wm.flicker;
import android.platform.helpers.IAppHelper;
-import android.support.test.InstrumentationRegistry;
-import android.support.test.runner.AndroidJUnit4;
import android.support.test.uiautomator.UiDevice;
import android.util.Rational;
import android.view.Surface;
+import androidx.test.InstrumentationRegistry;
+import androidx.test.runner.AndroidJUnit4;
+
import org.junit.Ignore;
import org.junit.Test;
import org.junit.runner.RunWith;
diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/FlickerTestBase.java b/tests/FlickerTests/src/com/android/server/wm/flicker/FlickerTestBase.java
index 7061b23..00e11c0 100644
--- a/tests/FlickerTests/src/com/android/server/wm/flicker/FlickerTestBase.java
+++ b/tests/FlickerTests/src/com/android/server/wm/flicker/FlickerTestBase.java
@@ -21,10 +21,11 @@
import static com.google.common.truth.Truth.assertWithMessage;
import android.platform.helpers.IAppHelper;
-import android.support.test.InstrumentationRegistry;
import android.support.test.uiautomator.UiDevice;
import android.util.Log;
+import androidx.test.InstrumentationRegistry;
+
import com.android.server.wm.flicker.TransitionRunner.TransitionResult;
import org.junit.After;
diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/OpenAppColdTest.java b/tests/FlickerTests/src/com/android/server/wm/flicker/OpenAppColdTest.java
index 7e71369..7818c4e 100644
--- a/tests/FlickerTests/src/com/android/server/wm/flicker/OpenAppColdTest.java
+++ b/tests/FlickerTests/src/com/android/server/wm/flicker/OpenAppColdTest.java
@@ -20,9 +20,9 @@
import static com.android.server.wm.flicker.WindowUtils.getDisplayBounds;
import static com.android.server.wm.flicker.WmTraceSubject.assertThat;
-import android.support.test.InstrumentationRegistry;
-import android.support.test.filters.LargeTest;
-import android.support.test.runner.AndroidJUnit4;
+import androidx.test.InstrumentationRegistry;
+import androidx.test.filters.LargeTest;
+import androidx.test.runner.AndroidJUnit4;
import org.junit.Before;
import org.junit.Test;
diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/OpenAppToSplitScreenTest.java b/tests/FlickerTests/src/com/android/server/wm/flicker/OpenAppToSplitScreenTest.java
index 745569a..63018ec 100644
--- a/tests/FlickerTests/src/com/android/server/wm/flicker/OpenAppToSplitScreenTest.java
+++ b/tests/FlickerTests/src/com/android/server/wm/flicker/OpenAppToSplitScreenTest.java
@@ -19,9 +19,9 @@
import static com.android.server.wm.flicker.CommonTransitions.appToSplitScreen;
import static com.android.server.wm.flicker.WindowUtils.getDisplayBounds;
-import android.support.test.InstrumentationRegistry;
-import android.support.test.filters.LargeTest;
-import android.support.test.runner.AndroidJUnit4;
+import androidx.test.InstrumentationRegistry;
+import androidx.test.filters.LargeTest;
+import androidx.test.runner.AndroidJUnit4;
import org.junit.Before;
import org.junit.Test;
diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/OpenAppWarmTest.java b/tests/FlickerTests/src/com/android/server/wm/flicker/OpenAppWarmTest.java
index de7639d..1aba930 100644
--- a/tests/FlickerTests/src/com/android/server/wm/flicker/OpenAppWarmTest.java
+++ b/tests/FlickerTests/src/com/android/server/wm/flicker/OpenAppWarmTest.java
@@ -20,9 +20,9 @@
import static com.android.server.wm.flicker.WindowUtils.getDisplayBounds;
import static com.android.server.wm.flicker.WmTraceSubject.assertThat;
-import android.support.test.InstrumentationRegistry;
-import android.support.test.filters.LargeTest;
-import android.support.test.runner.AndroidJUnit4;
+import androidx.test.InstrumentationRegistry;
+import androidx.test.filters.LargeTest;
+import androidx.test.runner.AndroidJUnit4;
import org.junit.Before;
import org.junit.Test;
diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/OpenImeWindowTest.java b/tests/FlickerTests/src/com/android/server/wm/flicker/OpenImeWindowTest.java
index 1bd519c..a81fa8e 100644
--- a/tests/FlickerTests/src/com/android/server/wm/flicker/OpenImeWindowTest.java
+++ b/tests/FlickerTests/src/com/android/server/wm/flicker/OpenImeWindowTest.java
@@ -19,8 +19,8 @@
import static com.android.server.wm.flicker.CommonTransitions.editTextSetFocus;
import static com.android.server.wm.flicker.WindowUtils.getDisplayBounds;
-import android.support.test.filters.LargeTest;
-import android.support.test.runner.AndroidJUnit4;
+import androidx.test.filters.LargeTest;
+import androidx.test.runner.AndroidJUnit4;
import org.junit.Before;
import org.junit.Test;
diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/ResizeSplitScreenTest.java b/tests/FlickerTests/src/com/android/server/wm/flicker/ResizeSplitScreenTest.java
index 8a15cbd..50dba81 100644
--- a/tests/FlickerTests/src/com/android/server/wm/flicker/ResizeSplitScreenTest.java
+++ b/tests/FlickerTests/src/com/android/server/wm/flicker/ResizeSplitScreenTest.java
@@ -25,11 +25,12 @@
import android.graphics.Rect;
import android.platform.helpers.IAppHelper;
-import android.support.test.InstrumentationRegistry;
-import android.support.test.filters.LargeTest;
-import android.support.test.runner.AndroidJUnit4;
import android.util.Rational;
+import androidx.test.InstrumentationRegistry;
+import androidx.test.filters.LargeTest;
+import androidx.test.runner.AndroidJUnit4;
+
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/SeamlessAppRotationTest.java b/tests/FlickerTests/src/com/android/server/wm/flicker/SeamlessAppRotationTest.java
index 3eab68d..117ac5a 100644
--- a/tests/FlickerTests/src/com/android/server/wm/flicker/SeamlessAppRotationTest.java
+++ b/tests/FlickerTests/src/com/android/server/wm/flicker/SeamlessAppRotationTest.java
@@ -27,10 +27,11 @@
import android.content.Intent;
import android.graphics.Rect;
-import android.support.test.InstrumentationRegistry;
-import android.support.test.filters.LargeTest;
import android.view.Surface;
+import androidx.test.InstrumentationRegistry;
+import androidx.test.filters.LargeTest;
+
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/SplitScreenToLauncherTest.java b/tests/FlickerTests/src/com/android/server/wm/flicker/SplitScreenToLauncherTest.java
index 40bd4e9..1d30df9 100644
--- a/tests/FlickerTests/src/com/android/server/wm/flicker/SplitScreenToLauncherTest.java
+++ b/tests/FlickerTests/src/com/android/server/wm/flicker/SplitScreenToLauncherTest.java
@@ -19,10 +19,10 @@
import static com.android.server.wm.flicker.CommonTransitions.splitScreenToLauncher;
import static com.android.server.wm.flicker.WindowUtils.getDisplayBounds;
-import android.support.test.InstrumentationRegistry;
-import android.support.test.filters.FlakyTest;
-import android.support.test.filters.LargeTest;
-import android.support.test.runner.AndroidJUnit4;
+import androidx.test.InstrumentationRegistry;
+import androidx.test.filters.FlakyTest;
+import androidx.test.filters.LargeTest;
+import androidx.test.runner.AndroidJUnit4;
import org.junit.Before;
import org.junit.Test;
diff --git a/tests/Internal/Android.mk b/tests/Internal/Android.mk
index da56696..2e26ef1 100644
--- a/tests/Internal/Android.mk
+++ b/tests/Internal/Android.mk
@@ -11,7 +11,7 @@
LOCAL_JAVA_LIBRARIES := android.test.runner
LOCAL_STATIC_JAVA_LIBRARIES := junit \
- android-support-test \
+ androidx.test.rules \
mockito-target-minus-junit4
LOCAL_JAVA_RESOURCE_DIRS := res
diff --git a/tests/Internal/AndroidManifest.xml b/tests/Internal/AndroidManifest.xml
index e5a5694..c85c3b1 100644
--- a/tests/Internal/AndroidManifest.xml
+++ b/tests/Internal/AndroidManifest.xml
@@ -38,7 +38,7 @@
</service>
</application>
- <instrumentation android:name="android.support.test.runner.AndroidJUnitRunner"
+ <instrumentation android:name="androidx.test.runner.AndroidJUnitRunner"
android:targetPackage="com.android.internal.tests"
android:label="Internal Tests" />
</manifest>
diff --git a/tests/Internal/AndroidTest.xml b/tests/Internal/AndroidTest.xml
index 6531c93..7b67e9e 100644
--- a/tests/Internal/AndroidTest.xml
+++ b/tests/Internal/AndroidTest.xml
@@ -24,6 +24,6 @@
<option name="test-tag" value="InternalTests" />
<test class="com.android.tradefed.testtype.AndroidJUnitTest" >
<option name="package" value="com.android.internal.tests" />
- <option name="runner" value="android.support.test.runner.AndroidJUnitRunner" />
+ <option name="runner" value="androidx.test.runner.AndroidJUnitRunner" />
</test>
</configuration>
\ No newline at end of file
diff --git a/tests/Internal/src/android/app/WallpaperColorsTest.java b/tests/Internal/src/android/app/WallpaperColorsTest.java
index 881f628..65ff6eb 100644
--- a/tests/Internal/src/android/app/WallpaperColorsTest.java
+++ b/tests/Internal/src/android/app/WallpaperColorsTest.java
@@ -20,8 +20,9 @@
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
-import android.support.test.filters.SmallTest;
-import android.support.test.runner.AndroidJUnit4;
+
+import androidx.test.filters.SmallTest;
+import androidx.test.runner.AndroidJUnit4;
import org.junit.Assert;
import org.junit.Test;
diff --git a/tests/Internal/src/android/app/WallpaperInfoTest.java b/tests/Internal/src/android/app/WallpaperInfoTest.java
index 7f06f2c..476b991 100644
--- a/tests/Internal/src/android/app/WallpaperInfoTest.java
+++ b/tests/Internal/src/android/app/WallpaperInfoTest.java
@@ -26,9 +26,10 @@
import android.net.Uri;
import android.os.Parcel;
import android.service.wallpaper.WallpaperService;
-import android.support.test.InstrumentationRegistry;
-import android.support.test.filters.SmallTest;
-import android.support.test.runner.AndroidJUnit4;
+
+import androidx.test.InstrumentationRegistry;
+import androidx.test.filters.SmallTest;
+import androidx.test.runner.AndroidJUnit4;
import org.junit.Test;
import org.junit.runner.RunWith;
diff --git a/tests/Internal/src/android/service/wallpaper/WallpaperServiceTest.java b/tests/Internal/src/android/service/wallpaper/WallpaperServiceTest.java
index b9e282e..592aa3a 100644
--- a/tests/Internal/src/android/service/wallpaper/WallpaperServiceTest.java
+++ b/tests/Internal/src/android/service/wallpaper/WallpaperServiceTest.java
@@ -20,7 +20,7 @@
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;
-import android.support.test.filters.SmallTest;
+import androidx.test.filters.SmallTest;
import org.junit.Test;
import org.junit.runner.RunWith;
diff --git a/tests/Internal/src/com/android/internal/colorextraction/ColorExtractorTest.java b/tests/Internal/src/com/android/internal/colorextraction/ColorExtractorTest.java
index 39608a4..17fa931 100644
--- a/tests/Internal/src/com/android/internal/colorextraction/ColorExtractorTest.java
+++ b/tests/Internal/src/com/android/internal/colorextraction/ColorExtractorTest.java
@@ -27,9 +27,10 @@
import android.app.WallpaperManager;
import android.content.Context;
import android.graphics.Color;
-import android.support.test.InstrumentationRegistry;
-import android.support.test.filters.SmallTest;
-import android.support.test.runner.AndroidJUnit4;
+
+import androidx.test.InstrumentationRegistry;
+import androidx.test.filters.SmallTest;
+import androidx.test.runner.AndroidJUnit4;
import com.android.internal.colorextraction.ColorExtractor.GradientColors;
import com.android.internal.colorextraction.types.ExtractionType;
diff --git a/tests/Internal/src/com/android/internal/colorextraction/types/TonalTest.java b/tests/Internal/src/com/android/internal/colorextraction/types/TonalTest.java
index a7d5ae8..d92cfce 100644
--- a/tests/Internal/src/com/android/internal/colorextraction/types/TonalTest.java
+++ b/tests/Internal/src/com/android/internal/colorextraction/types/TonalTest.java
@@ -20,11 +20,12 @@
import android.app.WallpaperColors;
import android.graphics.Color;
-import android.support.test.InstrumentationRegistry;
-import android.support.test.filters.SmallTest;
-import android.support.test.runner.AndroidJUnit4;
import android.util.Range;
+import androidx.test.InstrumentationRegistry;
+import androidx.test.filters.SmallTest;
+import androidx.test.runner.AndroidJUnit4;
+
import com.android.internal.colorextraction.ColorExtractor.GradientColors;
import com.android.internal.graphics.ColorUtils;
diff --git a/tests/Internal/src/com/android/internal/graphics/ColorUtilsTest.java b/tests/Internal/src/com/android/internal/graphics/ColorUtilsTest.java
index 73df9a0..d0bb8e3 100644
--- a/tests/Internal/src/com/android/internal/graphics/ColorUtilsTest.java
+++ b/tests/Internal/src/com/android/internal/graphics/ColorUtilsTest.java
@@ -16,13 +16,14 @@
package com.android.internal.graphics;
+import static org.junit.Assert.assertTrue;
+
import android.graphics.Color;
-import android.support.test.filters.SmallTest;
+
+import androidx.test.filters.SmallTest;
import org.junit.Test;
-import static org.junit.Assert.assertTrue;
-
@SmallTest
public class ColorUtilsTest {
diff --git a/tests/Internal/src/com/android/internal/ml/clustering/KMeansTest.java b/tests/Internal/src/com/android/internal/ml/clustering/KMeansTest.java
index a64f8a6..540a1ec 100644
--- a/tests/Internal/src/com/android/internal/ml/clustering/KMeansTest.java
+++ b/tests/Internal/src/com/android/internal/ml/clustering/KMeansTest.java
@@ -20,8 +20,9 @@
import static org.junit.Assert.assertTrue;
import android.annotation.SuppressLint;
-import android.support.test.filters.SmallTest;
-import android.support.test.runner.AndroidJUnit4;
+
+import androidx.test.filters.SmallTest;
+import androidx.test.runner.AndroidJUnit4;
import org.junit.Assert;
import org.junit.Before;
diff --git a/tests/PackageWatchdog/Android.mk b/tests/PackageWatchdog/Android.mk
index 1c1c2a4..1e4aacc 100644
--- a/tests/PackageWatchdog/Android.mk
+++ b/tests/PackageWatchdog/Android.mk
@@ -22,7 +22,7 @@
LOCAL_STATIC_JAVA_LIBRARIES := \
junit \
frameworks-base-testutils \
- android-support-test \
+ androidx.test.rules \
services.core
LOCAL_JAVA_LIBRARIES := \
diff --git a/tests/PackageWatchdog/AndroidManifest.xml b/tests/PackageWatchdog/AndroidManifest.xml
index fa89528..540edb4 100644
--- a/tests/PackageWatchdog/AndroidManifest.xml
+++ b/tests/PackageWatchdog/AndroidManifest.xml
@@ -22,7 +22,7 @@
</application>
- <instrumentation android:name="android.support.test.runner.AndroidJUnitRunner"
+ <instrumentation android:name="androidx.test.runner.AndroidJUnitRunner"
android:targetPackage="com.android.tests.packagewatchdog"
android:label="PackageWatchdog Test"/>
</manifest>
diff --git a/tests/PackageWatchdog/src/com/android/server/PackageWatchdogTest.java b/tests/PackageWatchdog/src/com/android/server/PackageWatchdogTest.java
index 77cd62e..598f60a 100644
--- a/tests/PackageWatchdog/src/com/android/server/PackageWatchdogTest.java
+++ b/tests/PackageWatchdog/src/com/android/server/PackageWatchdogTest.java
@@ -24,7 +24,8 @@
import android.content.pm.VersionedPackage;
import android.os.test.TestLooper;
-import android.support.test.InstrumentationRegistry;
+
+import androidx.test.InstrumentationRegistry;
import com.android.server.PackageWatchdog.PackageHealthObserver;
import com.android.server.PackageWatchdog.PackageHealthObserverImpact;
diff --git a/tests/RcsTests/Android.mk b/tests/RcsTests/Android.mk
index 7b348d7..a276584 100644
--- a/tests/RcsTests/Android.mk
+++ b/tests/RcsTests/Android.mk
@@ -11,7 +11,7 @@
LOCAL_CERTIFICATE := platform
LOCAL_JAVA_LIBRARIES := android.test.runner android.test.base
-LOCAL_STATIC_JAVA_LIBRARIES := junit android-support-test mockito-target-minus-junit4 truth-prebuilt
+LOCAL_STATIC_JAVA_LIBRARIES := junit androidx.test.rules mockito-target-minus-junit4 truth-prebuilt
include $(BUILD_PACKAGE)
diff --git a/tests/RcsTests/AndroidManifest.xml b/tests/RcsTests/AndroidManifest.xml
index a7e7d47..b1706a0 100644
--- a/tests/RcsTests/AndroidManifest.xml
+++ b/tests/RcsTests/AndroidManifest.xml
@@ -6,6 +6,6 @@
<uses-library android:name="android.test.runner" />
</application>
- <instrumentation android:name="android.support.test.runner.AndroidJUnitRunner"
+ <instrumentation android:name="androidx.test.runner.AndroidJUnitRunner"
android:targetPackage="com.android.tests.rcs"/>
</manifest>
diff --git a/tests/RcsTests/src/com/android/tests/ims/RcsGroupThreadIconChangedEventTest.java b/tests/RcsTests/src/com/android/tests/ims/RcsGroupThreadIconChangedEventTest.java
index 89d32ab..e898942 100644
--- a/tests/RcsTests/src/com/android/tests/ims/RcsGroupThreadIconChangedEventTest.java
+++ b/tests/RcsTests/src/com/android/tests/ims/RcsGroupThreadIconChangedEventTest.java
@@ -19,10 +19,11 @@
import android.net.Uri;
import android.os.Parcel;
-import android.support.test.runner.AndroidJUnit4;
import android.telephony.ims.RcsGroupThreadIconChangedEvent;
import android.telephony.ims.RcsGroupThreadIconChangedEventDescriptor;
+import androidx.test.runner.AndroidJUnit4;
+
import org.junit.Test;
import org.junit.runner.RunWith;
diff --git a/tests/RcsTests/src/com/android/tests/ims/RcsGroupThreadNameChangedEventTest.java b/tests/RcsTests/src/com/android/tests/ims/RcsGroupThreadNameChangedEventTest.java
index 726b9cd..356688d 100644
--- a/tests/RcsTests/src/com/android/tests/ims/RcsGroupThreadNameChangedEventTest.java
+++ b/tests/RcsTests/src/com/android/tests/ims/RcsGroupThreadNameChangedEventTest.java
@@ -18,10 +18,11 @@
import static com.google.common.truth.Truth.assertThat;
import android.os.Parcel;
-import android.support.test.runner.AndroidJUnit4;
import android.telephony.ims.RcsGroupThreadNameChangedEvent;
import android.telephony.ims.RcsGroupThreadNameChangedEventDescriptor;
+import androidx.test.runner.AndroidJUnit4;
+
import org.junit.Test;
import org.junit.runner.RunWith;
diff --git a/tests/RcsTests/src/com/android/tests/ims/RcsGroupThreadParticipantJoinedEventTest.java b/tests/RcsTests/src/com/android/tests/ims/RcsGroupThreadParticipantJoinedEventTest.java
index a109310..572fcb8 100644
--- a/tests/RcsTests/src/com/android/tests/ims/RcsGroupThreadParticipantJoinedEventTest.java
+++ b/tests/RcsTests/src/com/android/tests/ims/RcsGroupThreadParticipantJoinedEventTest.java
@@ -18,10 +18,11 @@
import static com.google.common.truth.Truth.assertThat;
import android.os.Parcel;
-import android.support.test.runner.AndroidJUnit4;
import android.telephony.ims.RcsGroupThreadParticipantJoinedEvent;
import android.telephony.ims.RcsGroupThreadParticipantJoinedEventDescriptor;
+import androidx.test.runner.AndroidJUnit4;
+
import org.junit.Test;
import org.junit.runner.RunWith;
diff --git a/tests/RcsTests/src/com/android/tests/ims/RcsGroupThreadParticipantLeftEventTest.java b/tests/RcsTests/src/com/android/tests/ims/RcsGroupThreadParticipantLeftEventTest.java
index de2688c..038b2e8 100644
--- a/tests/RcsTests/src/com/android/tests/ims/RcsGroupThreadParticipantLeftEventTest.java
+++ b/tests/RcsTests/src/com/android/tests/ims/RcsGroupThreadParticipantLeftEventTest.java
@@ -18,10 +18,11 @@
import static com.google.common.truth.Truth.assertThat;
import android.os.Parcel;
-import android.support.test.runner.AndroidJUnit4;
import android.telephony.ims.RcsGroupThreadParticipantLeftEvent;
import android.telephony.ims.RcsGroupThreadParticipantLeftEventDescriptor;
+import androidx.test.runner.AndroidJUnit4;
+
import org.junit.Test;
import org.junit.runner.RunWith;
diff --git a/tests/RcsTests/src/com/android/tests/ims/RcsParticipantAliasChangedEventTest.java b/tests/RcsTests/src/com/android/tests/ims/RcsParticipantAliasChangedEventTest.java
index 5724054..283c71b 100644
--- a/tests/RcsTests/src/com/android/tests/ims/RcsParticipantAliasChangedEventTest.java
+++ b/tests/RcsTests/src/com/android/tests/ims/RcsParticipantAliasChangedEventTest.java
@@ -18,10 +18,11 @@
import static com.google.common.truth.Truth.assertThat;
import android.os.Parcel;
-import android.support.test.runner.AndroidJUnit4;
import android.telephony.ims.RcsParticipantAliasChangedEvent;
import android.telephony.ims.RcsParticipantAliasChangedEventDescriptor;
+import androidx.test.runner.AndroidJUnit4;
+
import org.junit.Test;
import org.junit.runner.RunWith;
diff --git a/tests/RcsTests/src/com/android/tests/ims/RcsParticipantQueryParamsTest.java b/tests/RcsTests/src/com/android/tests/ims/RcsParticipantQueryParamsTest.java
index 6361a39..2d95513 100644
--- a/tests/RcsTests/src/com/android/tests/ims/RcsParticipantQueryParamsTest.java
+++ b/tests/RcsTests/src/com/android/tests/ims/RcsParticipantQueryParamsTest.java
@@ -18,9 +18,10 @@
import static com.google.common.truth.Truth.assertThat;
import android.os.Parcel;
-import android.support.test.runner.AndroidJUnit4;
import android.telephony.ims.RcsParticipantQueryParams;
+import androidx.test.runner.AndroidJUnit4;
+
import org.junit.Test;
import org.junit.runner.RunWith;
diff --git a/tests/RcsTests/src/com/android/tests/ims/RcsThreadQueryParamsTest.java b/tests/RcsTests/src/com/android/tests/ims/RcsThreadQueryParamsTest.java
index beb4f8a..fb51bda 100644
--- a/tests/RcsTests/src/com/android/tests/ims/RcsThreadQueryParamsTest.java
+++ b/tests/RcsTests/src/com/android/tests/ims/RcsThreadQueryParamsTest.java
@@ -21,10 +21,11 @@
import static com.google.common.truth.Truth.assertThat;
import android.os.Parcel;
-import android.support.test.runner.AndroidJUnit4;
import android.telephony.ims.RcsParticipant;
import android.telephony.ims.RcsThreadQueryParams;
+import androidx.test.runner.AndroidJUnit4;
+
import org.junit.Test;
import org.junit.runner.RunWith;
diff --git a/tests/RollbackTest/Android.mk b/tests/RollbackTest/Android.mk
index db9376b..206f867 100644
--- a/tests/RollbackTest/Android.mk
+++ b/tests/RollbackTest/Android.mk
@@ -107,7 +107,7 @@
LOCAL_SRC_FILES := $(call all-java-files-under, RollbackTest/src)
LOCAL_PACKAGE_NAME := RollbackTest
LOCAL_MODULE_TAGS := tests
-LOCAL_STATIC_JAVA_LIBRARIES := android-support-test
+LOCAL_STATIC_JAVA_LIBRARIES := androidx.test.rules
LOCAL_COMPATIBILITY_SUITE := general-tests
LOCAL_JAVA_RESOURCE_FILES := \
$(ROLLBACK_TEST_APP_AV1) \
diff --git a/tests/RollbackTest/RollbackTest.xml b/tests/RollbackTest/RollbackTest.xml
index ac39f85..70cd867 100644
--- a/tests/RollbackTest/RollbackTest.xml
+++ b/tests/RollbackTest/RollbackTest.xml
@@ -20,7 +20,7 @@
</target_preparer>
<test class="com.android.tradefed.testtype.AndroidJUnitTest" >
<option name="package" value="com.android.tests.rollback" />
- <option name="runner" value="android.support.test.runner.AndroidJUnitRunner" />
+ <option name="runner" value="androidx.test.runner.AndroidJUnitRunner" />
<!-- Exclude the StagedRollbackTest tests, which needs to be specially
driven from the StagedRollbackTest host test -->
diff --git a/tests/RollbackTest/RollbackTest/AndroidManifest.xml b/tests/RollbackTest/RollbackTest/AndroidManifest.xml
index e57a768..5380dc9 100644
--- a/tests/RollbackTest/RollbackTest/AndroidManifest.xml
+++ b/tests/RollbackTest/RollbackTest/AndroidManifest.xml
@@ -24,7 +24,7 @@
</application>
- <instrumentation android:name="android.support.test.runner.AndroidJUnitRunner"
+ <instrumentation android:name="androidx.test.runner.AndroidJUnitRunner"
android:targetPackage="com.android.tests.rollback"
android:label="Rollback Test"/>
diff --git a/tests/RollbackTest/RollbackTest/src/com/android/tests/rollback/LocalIntentSender.java b/tests/RollbackTest/RollbackTest/src/com/android/tests/rollback/LocalIntentSender.java
index ddcf1da..267ef73 100644
--- a/tests/RollbackTest/RollbackTest/src/com/android/tests/rollback/LocalIntentSender.java
+++ b/tests/RollbackTest/RollbackTest/src/com/android/tests/rollback/LocalIntentSender.java
@@ -21,7 +21,8 @@
import android.content.Context;
import android.content.Intent;
import android.content.IntentSender;
-import android.support.test.InstrumentationRegistry;
+
+import androidx.test.InstrumentationRegistry;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.LinkedBlockingQueue;
diff --git a/tests/RollbackTest/RollbackTest/src/com/android/tests/rollback/RollbackBroadcastReceiver.java b/tests/RollbackTest/RollbackTest/src/com/android/tests/rollback/RollbackBroadcastReceiver.java
index e10f866..8a925b9 100644
--- a/tests/RollbackTest/RollbackTest/src/com/android/tests/rollback/RollbackBroadcastReceiver.java
+++ b/tests/RollbackTest/RollbackTest/src/com/android/tests/rollback/RollbackBroadcastReceiver.java
@@ -20,9 +20,10 @@
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
-import android.support.test.InstrumentationRegistry;
import android.util.Log;
+import androidx.test.InstrumentationRegistry;
+
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.TimeUnit;
diff --git a/tests/RollbackTest/RollbackTest/src/com/android/tests/rollback/RollbackTest.java b/tests/RollbackTest/RollbackTest/src/com/android/tests/rollback/RollbackTest.java
index a6054e8..4780f30 100644
--- a/tests/RollbackTest/RollbackTest/src/com/android/tests/rollback/RollbackTest.java
+++ b/tests/RollbackTest/RollbackTest/src/com/android/tests/rollback/RollbackTest.java
@@ -21,6 +21,11 @@
import static com.android.tests.rollback.RollbackTestUtils.getUniqueRollbackInfoForPackage;
import static com.android.tests.rollback.RollbackTestUtils.processUserData;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertNull;
+import static org.junit.Assert.fail;
+
import android.Manifest;
import android.app.ActivityManager;
import android.content.BroadcastReceiver;
@@ -31,13 +36,9 @@
import android.content.rollback.RollbackInfo;
import android.content.rollback.RollbackManager;
import android.provider.DeviceConfig;
-import android.support.test.InstrumentationRegistry;
import android.util.Log;
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertNotNull;
-import static org.junit.Assert.assertNull;
-import static org.junit.Assert.fail;
+import androidx.test.InstrumentationRegistry;
import org.junit.Test;
import org.junit.runner.RunWith;
diff --git a/tests/RollbackTest/RollbackTest/src/com/android/tests/rollback/RollbackTestUtils.java b/tests/RollbackTest/RollbackTest/src/com/android/tests/rollback/RollbackTestUtils.java
index 2f989f3..e8cbd60 100644
--- a/tests/RollbackTest/RollbackTest/src/com/android/tests/rollback/RollbackTestUtils.java
+++ b/tests/RollbackTest/RollbackTest/src/com/android/tests/rollback/RollbackTestUtils.java
@@ -16,6 +16,11 @@
package com.android.tests.rollback;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertNull;
+import static org.junit.Assert.fail;
+
import android.content.BroadcastReceiver;
import android.content.ComponentName;
import android.content.Context;
@@ -30,13 +35,9 @@
import android.content.rollback.RollbackManager;
import android.os.Handler;
import android.os.HandlerThread;
-import android.support.test.InstrumentationRegistry;
import android.util.Log;
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertNotNull;
-import static org.junit.Assert.assertNull;
-import static org.junit.Assert.fail;
+import androidx.test.InstrumentationRegistry;
import java.io.IOException;
import java.io.InputStream;
diff --git a/tests/ServiceCrashTest/Android.mk b/tests/ServiceCrashTest/Android.mk
index d1f6450..617ee7c 100644
--- a/tests/ServiceCrashTest/Android.mk
+++ b/tests/ServiceCrashTest/Android.mk
@@ -12,7 +12,7 @@
LOCAL_CERTIFICATE := platform
LOCAL_JAVA_LIBRARIES := android.test.base
-LOCAL_STATIC_JAVA_LIBRARIES := compatibility-device-util android-support-test
+LOCAL_STATIC_JAVA_LIBRARIES := compatibility-device-util-axt androidx.test.rules
include $(BUILD_PACKAGE)
diff --git a/tests/UsageStatsPerfTests/Android.mk b/tests/UsageStatsPerfTests/Android.mk
index cd29b51..4304fb0 100644
--- a/tests/UsageStatsPerfTests/Android.mk
+++ b/tests/UsageStatsPerfTests/Android.mk
@@ -21,7 +21,7 @@
$(call all-java-files-under, src)
LOCAL_STATIC_JAVA_LIBRARIES := \
- android-support-test \
+ androidx.test.rules \
apct-perftests-utils \
services.usage
diff --git a/tests/UsageStatsPerfTests/AndroidManifest.xml b/tests/UsageStatsPerfTests/AndroidManifest.xml
index 596a79c..9891548 100644
--- a/tests/UsageStatsPerfTests/AndroidManifest.xml
+++ b/tests/UsageStatsPerfTests/AndroidManifest.xml
@@ -24,6 +24,6 @@
<uses-library android:name="android.test.runner" />
</application>
- <instrumentation android:name="android.support.test.runner.AndroidJUnitRunner"
+ <instrumentation android:name="androidx.test.runner.AndroidJUnitRunner"
android:targetPackage="com.android.frameworks.perftests.usage"/>
</manifest>
diff --git a/tests/UsageStatsPerfTests/AndroidTest.xml b/tests/UsageStatsPerfTests/AndroidTest.xml
index c9b51dc..b8892eb 100644
--- a/tests/UsageStatsPerfTests/AndroidTest.xml
+++ b/tests/UsageStatsPerfTests/AndroidTest.xml
@@ -23,6 +23,6 @@
<option name="test-tag" value="UsageStatsPerfTests"/>
<test class="com.android.tradefed.testtype.AndroidJUnitTest">
<option name="package" value="com.android.frameworks.perftests.usage"/>
- <option name="runner" value="android.support.test.runner.AndroidJUnitRunner"/>
+ <option name="runner" value="androidx.test.runner.AndroidJUnitRunner"/>
</test>
</configuration>
\ No newline at end of file
diff --git a/tests/UsageStatsPerfTests/src/com/android/frameworks/perftests/usage/tests/UsageStatsDatabasePerfTest.java b/tests/UsageStatsPerfTests/src/com/android/frameworks/perftests/usage/tests/UsageStatsDatabasePerfTest.java
index e2a4c26..7d9d0d5 100644
--- a/tests/UsageStatsPerfTests/src/com/android/frameworks/perftests/usage/tests/UsageStatsDatabasePerfTest.java
+++ b/tests/UsageStatsPerfTests/src/com/android/frameworks/perftests/usage/tests/UsageStatsDatabasePerfTest.java
@@ -24,9 +24,10 @@
import android.os.SystemClock;
import android.perftests.utils.ManualBenchmarkState;
import android.perftests.utils.PerfManualStatusReporter;
-import android.support.test.InstrumentationRegistry;
-import android.support.test.filters.LargeTest;
-import android.support.test.runner.AndroidJUnit4;
+
+import androidx.test.InstrumentationRegistry;
+import androidx.test.filters.LargeTest;
+import androidx.test.runner.AndroidJUnit4;
import com.android.server.usage.IntervalStats;
import com.android.server.usage.UsageStatsDatabase;
diff --git a/tests/UsbTests/Android.mk b/tests/UsbTests/Android.mk
index 4e215cc..aef993b 100644
--- a/tests/UsbTests/Android.mk
+++ b/tests/UsbTests/Android.mk
@@ -24,7 +24,7 @@
LOCAL_STATIC_JAVA_LIBRARIES := \
frameworks-base-testutils \
- android-support-test \
+ androidx.test.rules \
mockito-target-inline-minus-junit4 \
platform-test-annotations \
services.core \
diff --git a/tests/UsbTests/AndroidManifest.xml b/tests/UsbTests/AndroidManifest.xml
index 5d60695..03d1a3e 100644
--- a/tests/UsbTests/AndroidManifest.xml
+++ b/tests/UsbTests/AndroidManifest.xml
@@ -24,7 +24,7 @@
<uses-library android:name="android.test.runner" />
</application>
- <instrumentation android:name="android.support.test.runner.AndroidJUnitRunner"
+ <instrumentation android:name="androidx.test.runner.AndroidJUnitRunner"
android:targetPackage="com.android.server.usb"
android:label="UsbTests"/>
</manifest>
diff --git a/tests/UsbTests/AndroidTest.xml b/tests/UsbTests/AndroidTest.xml
index 4affad3..e55bc98 100644
--- a/tests/UsbTests/AndroidTest.xml
+++ b/tests/UsbTests/AndroidTest.xml
@@ -24,7 +24,7 @@
<test class="com.android.tradefed.testtype.AndroidJUnitTest">
<option name="package" value="com.android.server.usb"/>
- <option name="runner" value="android.support.test.runner.AndroidJUnitRunner"/>
+ <option name="runner" value="androidx.test.runner.AndroidJUnitRunner"/>
<option name="hidden-api-checks" value="false"/>
</test>
</configuration>
diff --git a/tests/UsbTests/src/com/android/server/usb/UsbDescriptorParserTests.java b/tests/UsbTests/src/com/android/server/usb/UsbDescriptorParserTests.java
index ea027d7..89dc79c 100644
--- a/tests/UsbTests/src/com/android/server/usb/UsbDescriptorParserTests.java
+++ b/tests/UsbTests/src/com/android/server/usb/UsbDescriptorParserTests.java
@@ -16,29 +16,29 @@
package com.android.server.usb;
-import static org.junit.Assert.assertTrue;
-import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;
import android.content.Context;
import android.content.res.Resources;
import android.content.res.Resources.NotFoundException;
-import android.support.test.InstrumentationRegistry;
-import android.support.test.filters.SmallTest;
-import android.support.test.runner.AndroidJUnit4;
+
+import androidx.test.InstrumentationRegistry;
+import androidx.test.filters.SmallTest;
+import androidx.test.runner.AndroidJUnit4;
import com.android.server.usb.descriptors.UsbDescriptorParser;
-import com.android.server.usb.descriptors.UsbDeviceDescriptor;
-import com.google.common.io.ByteStreams;
-import java.io.InputStream;
-import java.io.IOException;
-import java.lang.Exception;
+import com.google.common.io.ByteStreams;
import org.junit.Test;
import org.junit.runner.RunWith;
+import java.io.IOException;
+import java.io.InputStream;
+
/**
* Tests for {@link com.android.server.usb.descriptors.UsbDescriptorParser}
*/
diff --git a/tests/UsbTests/src/com/android/server/usb/UsbHandlerTest.java b/tests/UsbTests/src/com/android/server/usb/UsbHandlerTest.java
index 4b93ca3..ca1eb70 100644
--- a/tests/UsbTests/src/com/android/server/usb/UsbHandlerTest.java
+++ b/tests/UsbTests/src/com/android/server/usb/UsbHandlerTest.java
@@ -31,11 +31,11 @@
import android.os.Handler;
import android.os.Looper;
import android.os.Message;
-import android.os.UserHandle;
import android.provider.Settings;
-import android.support.test.InstrumentationRegistry;
-import android.support.test.filters.SmallTest;
-import android.support.test.runner.AndroidJUnit4;
+
+import androidx.test.InstrumentationRegistry;
+import androidx.test.filters.SmallTest;
+import androidx.test.runner.AndroidJUnit4;
import com.android.server.FgThread;
diff --git a/tests/WindowAnimationJank/Android.mk b/tests/WindowAnimationJank/Android.mk
index 7800a80..1c2d167 100644
--- a/tests/WindowAnimationJank/Android.mk
+++ b/tests/WindowAnimationJank/Android.mk
@@ -26,7 +26,7 @@
LOCAL_STATIC_JAVA_LIBRARIES := \
ub-uiautomator \
- ub-janktesthelper \
+ androidx.test.janktesthelper \
junit
LOCAL_JAVA_LIBRARIES := android.test.base.stubs
diff --git a/tests/WindowAnimationJank/src/android/windowanimationjank/FullscreenRotationTest.java b/tests/WindowAnimationJank/src/android/windowanimationjank/FullscreenRotationTest.java
index 1fb502a..6792a8b 100644
--- a/tests/WindowAnimationJank/src/android/windowanimationjank/FullscreenRotationTest.java
+++ b/tests/WindowAnimationJank/src/android/windowanimationjank/FullscreenRotationTest.java
@@ -17,8 +17,9 @@
package android.windowanimationjank;
import android.os.Bundle;
-import android.support.test.jank.JankTest;
-import android.support.test.jank.GfxMonitor;
+
+import androidx.test.jank.GfxMonitor;
+import androidx.test.jank.JankTest;
/**
* Detect janks during screen rotation for full-screen activity. Periodically change
diff --git a/tests/WindowAnimationJank/src/android/windowanimationjank/WindowAnimationJankTestBase.java b/tests/WindowAnimationJank/src/android/windowanimationjank/WindowAnimationJankTestBase.java
index bf739fa..a8ace162 100644
--- a/tests/WindowAnimationJank/src/android/windowanimationjank/WindowAnimationJankTestBase.java
+++ b/tests/WindowAnimationJank/src/android/windowanimationjank/WindowAnimationJankTestBase.java
@@ -16,12 +16,10 @@
package android.windowanimationjank;
-import java.io.IOException;
-import java.util.StringTokenizer;
-
-import android.support.test.jank.JankTestBase;
import android.support.test.uiautomator.UiDevice;
+import androidx.test.jank.JankTestBase;
+
/**
* This adds additional system level jank monitor and its result is merged with primary monitor
* used in test.
diff --git a/tools/processors/view_inspector/src/java/android/processor/view/inspector/InspectableClassModel.java b/tools/processors/view_inspector/src/java/android/processor/view/inspector/InspectableClassModel.java
index 6f58893..ee97628 100644
--- a/tools/processors/view_inspector/src/java/android/processor/view/inspector/InspectableClassModel.java
+++ b/tools/processors/view_inspector/src/java/android/processor/view/inspector/InspectableClassModel.java
@@ -23,6 +23,7 @@
import java.util.HashMap;
import java.util.List;
import java.util.Map;
+import java.util.NoSuchElementException;
import java.util.Objects;
import java.util.Optional;
@@ -86,20 +87,98 @@
}
/**
+ * Represents a way to access a property, either a getter or a field.
+ */
+ public static final class Accessor {
+ private final String mName;
+ private final Type mType;
+
+ /**
+ * Construct an accessor for a field.
+ *
+ * @param name The name of the field
+ * @return The new accessor
+ * @see Type#FIELD
+ */
+ static Accessor ofField(String name) {
+ return new Accessor(name, Type.FIELD);
+ }
+
+ /**
+ * Construct an accessor for a getter.
+ *
+ * @param name The name of the getter
+ * @return The new accessor
+ * @see Type#GETTER
+ */
+ static Accessor ofGetter(String name) {
+ return new Accessor(name, Type.GETTER);
+ }
+
+ public Accessor(String name, Type type) {
+ mName = Objects.requireNonNull(name, "Accessor name must not be null");
+ mType = Objects.requireNonNull(type, "Accessor type must not be null");
+ }
+
+ public String getName() {
+ return mName;
+ }
+
+ public Type getType() {
+ return mType;
+ }
+
+ /**
+ * Get the invocation of this accessor.
+ *
+ * Example: {@code "getValue()"} for a getter or {@code "valueField"} for a field.
+ *
+ * @return A string representing the invocation of this accessor
+ */
+ public String invocation() {
+ switch (mType) {
+ case FIELD:
+ return mName;
+ case GETTER:
+ return String.format("%s()", mName);
+ default:
+ throw new NoSuchElementException(
+ String.format("No such accessor type %s", mType));
+ }
+ }
+
+ public enum Type {
+ /**
+ * A property accessed by a public field.
+ *
+ * @see #ofField(String)
+ */
+ FIELD,
+
+ /**
+ * A property accessed by a public getter method.
+ *
+ * @see #ofGetter(String)
+ */
+ GETTER
+ }
+ }
+
+ /**
* Model an inspectable property
*/
public static final class Property {
private final String mName;
- private final String mGetter;
+ private final Accessor mAccessor;
private final Type mType;
private boolean mAttributeIdInferrableFromR = true;
private int mAttributeId = 0;
private List<IntEnumEntry> mIntEnumEntries;
private List<IntFlagEntry> mIntFlagEntries;
- public Property(String name, String getter, Type type) {
+ public Property(String name, Accessor accessor, Type type) {
mName = Objects.requireNonNull(name, "Name must not be null");
- mGetter = Objects.requireNonNull(getter, "Getter must not be null");
+ mAccessor = Objects.requireNonNull(accessor, "Accessor must not be null");
mType = Objects.requireNonNull(type, "Type must not be null");
}
@@ -129,8 +208,8 @@
return mName;
}
- public String getGetter() {
- return mGetter;
+ public Accessor getAccessor() {
+ return mAccessor;
}
public Type getType() {
diff --git a/tools/processors/view_inspector/src/java/android/processor/view/inspector/InspectablePropertyProcessor.java b/tools/processors/view_inspector/src/java/android/processor/view/inspector/InspectablePropertyProcessor.java
index 50c79da..6305228 100644
--- a/tools/processors/view_inspector/src/java/android/processor/view/inspector/InspectablePropertyProcessor.java
+++ b/tools/processors/view_inspector/src/java/android/processor/view/inspector/InspectablePropertyProcessor.java
@@ -16,6 +16,7 @@
package android.processor.view.inspector;
+import android.processor.view.inspector.InspectableClassModel.Accessor;
import android.processor.view.inspector.InspectableClassModel.IntEnumEntry;
import android.processor.view.inspector.InspectableClassModel.IntFlagEntry;
import android.processor.view.inspector.InspectableClassModel.Property;
@@ -93,16 +94,15 @@
try {
final AnnotationMirror annotation =
mAnnotationUtils.exactlyOneMirror(mQualifiedName, element);
- final ExecutableElement getter = ensureGetter(element);
- final Property property = buildProperty(getter, annotation);
+ final Property property = buildProperty(element, annotation);
model.getProperty(property.getName()).ifPresent(p -> {
throw new ProcessingException(
String.format(
- "Property \"%s\" is already defined on #%s().",
+ "Property \"%s\" is already defined on #%s.",
p.getName(),
- p.getGetter()),
- getter,
+ p.getAccessor().invocation()),
+ element,
annotation);
});
@@ -112,6 +112,95 @@
}
}
+
+ /**
+ * Build a {@link Property} from a getter and an inspectable property annotation.
+ *
+ * @param accessor An element representing the getter or public field to build from
+ * @param annotation A mirror of an inspectable property-shaped annotation
+ * @return A property for the getter and annotation
+ * @throws ProcessingException If the supplied data is invalid and a property cannot be modeled
+ */
+ private Property buildProperty(Element accessor, AnnotationMirror annotation) {
+ final Property property;
+ final Optional<String> nameFromAnnotation = mAnnotationUtils
+ .typedValueByName("name", String.class, accessor, annotation);
+
+ validateModifiers(accessor);
+
+ switch (accessor.getKind()) {
+ case FIELD:
+ property = new Property(
+ nameFromAnnotation.orElseGet(() -> accessor.getSimpleName().toString()),
+ Accessor.ofField(accessor.getSimpleName().toString()),
+ determinePropertyType(accessor, annotation));
+ break;
+ case METHOD:
+ final ExecutableElement getter = ensureGetter(accessor);
+
+ property = new Property(
+ nameFromAnnotation.orElseGet(() -> inferPropertyNameFromGetter(getter)),
+ Accessor.ofGetter(getter.getSimpleName().toString()),
+ determinePropertyType(getter, annotation));
+ break;
+ default:
+ throw new ProcessingException(
+ String.format(
+ "Property must either be a getter method or a field, got %s.",
+ accessor.getKind()
+ ),
+ accessor,
+ annotation);
+ }
+
+ mAnnotationUtils
+ .typedValueByName("hasAttributeId", Boolean.class, accessor, annotation)
+ .ifPresent(property::setAttributeIdInferrableFromR);
+
+ mAnnotationUtils
+ .typedValueByName("attributeId", Integer.class, accessor, annotation)
+ .ifPresent(property::setAttributeId);
+
+ switch (property.getType()) {
+ case INT_ENUM:
+ property.setIntEnumEntries(processEnumMapping(accessor, annotation));
+ break;
+ case INT_FLAG:
+ property.setIntFlagEntries(processFlagMapping(accessor, annotation));
+ break;
+ }
+
+ return property;
+ }
+
+ /**
+ * Validates that an element is public, concrete, and non-static.
+ *
+ * @param element The element to check
+ * @throws ProcessingException If the element's modifiers are invalid
+ */
+ private void validateModifiers(Element element) {
+ final Set<Modifier> modifiers = element.getModifiers();
+
+ if (!modifiers.contains(Modifier.PUBLIC)) {
+ throw new ProcessingException(
+ "Property getter methods and fields must be public.",
+ element);
+ }
+
+ if (modifiers.contains(Modifier.ABSTRACT)) {
+ throw new ProcessingException(
+ "Property getter methods must not be abstract.",
+ element);
+ }
+
+ if (modifiers.contains(Modifier.STATIC)) {
+ throw new ProcessingException(
+ "Property getter methods and fields must not be static.",
+ element);
+ }
+ }
+
/**
* Check that an element is shaped like a getter.
*
@@ -127,25 +216,7 @@
}
final ExecutableElement method = (ExecutableElement) element;
- final Set<Modifier> modifiers = method.getModifiers();
- if (modifiers.contains(Modifier.PRIVATE)) {
- throw new ProcessingException(
- "Property getter methods must not be private.",
- element);
- }
-
- if (modifiers.contains(Modifier.ABSTRACT)) {
- throw new ProcessingException(
- "Property getter methods must not be abstract.",
- element);
- }
-
- if (modifiers.contains(Modifier.STATIC)) {
- throw new ProcessingException(
- "Property getter methods must not be static.",
- element);
- }
if (!method.getParameters().isEmpty()) {
throw new ProcessingException(
@@ -171,77 +242,41 @@
return method;
}
- /**
- * Build a {@link Property} from a getter and an inspectable property annotation.
- *
- * @param getter An element representing the getter to build from
- * @param annotation A mirror of an inspectable property-shaped annotation
- * @return A property for the getter and annotation
- * @throws ProcessingException If the supplied data is invalid and a property cannot be modeled
- */
- private Property buildProperty(ExecutableElement getter, AnnotationMirror annotation) {
- final String name = mAnnotationUtils
- .typedValueByName("name", String.class, getter, annotation)
- .orElseGet(() -> inferPropertyNameFromGetter(getter));
-
- final Property property = new Property(
- name,
- getter.getSimpleName().toString(),
- determinePropertyType(getter, annotation));
-
- mAnnotationUtils
- .typedValueByName("hasAttributeId", Boolean.class, getter, annotation)
- .ifPresent(property::setAttributeIdInferrableFromR);
-
- mAnnotationUtils
- .typedValueByName("attributeId", Integer.class, getter, annotation)
- .ifPresent(property::setAttributeId);
-
- switch (property.getType()) {
- case INT_ENUM:
- property.setIntEnumEntries(processEnumMapping(getter, annotation));
- break;
- case INT_FLAG:
- property.setIntFlagEntries(processFlagMapping(getter, annotation));
- break;
- }
-
- return property;
- }
/**
* Determine the property type from the annotation, return type, or context clues.
*
- * @param getter An element representing the getter to build from
+ * @param accessor An element representing the getter or field to determine the type of
* @param annotation A mirror of an inspectable property-shaped annotation
* @return The resolved property type
* @throws ProcessingException If the property type cannot be resolved or is invalid
* @see android.view.inspector.InspectableProperty#valueType()
*/
private Property.Type determinePropertyType(
- ExecutableElement getter,
+ Element accessor,
AnnotationMirror annotation) {
final String valueType = mAnnotationUtils
- .untypedValueByName("valueType", getter, annotation)
+ .untypedValueByName("valueType", accessor, annotation)
.map(Object::toString)
.orElse("INFERRED");
- final Property.Type returnType = convertReturnTypeToPropertyType(getter);
+ final Property.Type accessorType =
+ convertTypeMirrorToPropertyType(extractReturnOrFieldType(accessor), accessor);
- final boolean hasColor = hasColorAnnotation(getter);
+ final boolean hasColor = hasColorAnnotation(accessor);
final Optional<AnnotationValue> enumMapping =
mAnnotationUtils.valueByName("enumMapping", annotation);
final Optional<AnnotationValue> flagMapping =
mAnnotationUtils.valueByName("flagMapping", annotation);
- if (returnType != Property.Type.INT) {
+ if (accessorType != Property.Type.INT) {
enumMapping.ifPresent(value -> {
throw new ProcessingException(
String.format(
"Can only use enumMapping on int types, got %s.",
- returnType.toString().toLowerCase()),
- getter,
+ accessorType.toString().toLowerCase()),
+ accessor,
annotation,
value);
});
@@ -249,8 +284,8 @@
throw new ProcessingException(
String.format(
"Can only use flagMapping on int types, got %s.",
- returnType.toString().toLowerCase()),
- getter,
+ accessorType.toString().toLowerCase()),
+ accessor,
annotation,
value);
});
@@ -262,14 +297,14 @@
enumMapping.ifPresent(value -> {
throw new ProcessingException(
"Cannot use enumMapping on a color type.",
- getter,
+ accessor,
annotation,
value);
});
flagMapping.ifPresent(value -> {
throw new ProcessingException(
"Cannot use flagMapping on a color type.",
- getter,
+ accessor,
annotation,
value);
});
@@ -278,7 +313,7 @@
flagMapping.ifPresent(value -> {
throw new ProcessingException(
"Cannot use flagMapping and enumMapping simultaneously.",
- getter,
+ accessor,
annotation,
value);
});
@@ -286,12 +321,12 @@
} else if (flagMapping.isPresent()) {
return Property.Type.INT_FLAG;
} else {
- return returnType;
+ return accessorType;
}
case "NONE":
- return returnType;
+ return accessorType;
case "COLOR":
- switch (returnType) {
+ switch (accessorType) {
case COLOR:
case INT:
case LONG:
@@ -299,37 +334,58 @@
default:
throw new ProcessingException(
"Color must be a long, integer, or android.graphics.Color",
- getter,
+ accessor,
annotation);
}
case "GRAVITY":
- requirePackedIntToReturnInt("Gravity", returnType, getter, annotation);
+ requirePackedIntToBeInt("Gravity", accessorType, accessor, annotation);
return Property.Type.GRAVITY;
case "INT_ENUM":
- requirePackedIntToReturnInt("IntEnum", returnType, getter, annotation);
+ requirePackedIntToBeInt("IntEnum", accessorType, accessor, annotation);
return Property.Type.INT_ENUM;
case "INT_FLAG":
- requirePackedIntToReturnInt("IntFlag", returnType, getter, annotation);
+ requirePackedIntToBeInt("IntFlag", accessorType, accessor, annotation);
return Property.Type.INT_FLAG;
default:
throw new ProcessingException(
String.format("Unknown value type enumeration value: %s", valueType),
- getter,
+ accessor,
annotation);
}
}
/**
- * Get a property type from the return type of a getter.
+ * Get the type of a field or the return type of a method.
*
- * @param getter The getter to extract the return type of
+ * @param element The element to extract a {@link TypeMirror} from
+ * @return The return or field type of the element
+ * @throws ProcessingException If the element is not a field or a method
+ */
+ private TypeMirror extractReturnOrFieldType(Element element) {
+ switch (element.getKind()) {
+ case FIELD:
+ return element.asType();
+ case METHOD:
+ return ((ExecutableElement) element).getReturnType();
+ default:
+ throw new ProcessingException(
+ String.format(
+ "Unable to determine the type of a %s.",
+ element.getKind()),
+ element);
+ }
+ }
+
+ /**
+ * Get a property type from a type mirror
+ *
+ * @param typeMirror The type mirror to convert to a property type
+ * @param element The element to be used for exceptions
* @return The property type returned by the getter
* @throws ProcessingException If the return type is not a primitive or an object
*/
- private Property.Type convertReturnTypeToPropertyType(ExecutableElement getter) {
- final TypeMirror returnType = getter.getReturnType();
-
- switch (unboxType(returnType)) {
+ private Property.Type convertTypeMirrorToPropertyType(TypeMirror typeMirror, Element element) {
+ switch (unboxType(typeMirror)) {
case BOOLEAN:
return Property.Type.BOOLEAN;
case BYTE:
@@ -347,7 +403,7 @@
case SHORT:
return Property.Type.SHORT;
case DECLARED:
- if (isColorType(returnType)) {
+ if (isColorType(typeMirror)) {
return Property.Type.COLOR;
} else {
return Property.Type.OBJECT;
@@ -356,24 +412,24 @@
return Property.Type.OBJECT;
default:
throw new ProcessingException(
- String.format("Unsupported return type %s.", returnType),
- getter);
+ String.format("Unsupported property type %s.", typeMirror),
+ element);
}
}
/**
* Require that a value type packed into an integer be on a getter that returns an int.
*
- * @param typeName The name of the type to use in the exception
+ * @param typeName The name of the type to use in the exception
* @param returnType The return type of the getter to check
- * @param getter The getter, to use in the exception
+ * @param accessor The getter, to use in the exception
* @param annotation The annotation, to use in the exception
* @throws ProcessingException If the return type is not an int
*/
- private static void requirePackedIntToReturnInt(
+ private static void requirePackedIntToBeInt(
String typeName,
Property.Type returnType,
- ExecutableElement getter,
+ Element accessor,
AnnotationMirror annotation) {
if (returnType != Property.Type.INT) {
throw new ProcessingException(
@@ -381,7 +437,7 @@
"%s can only be defined on a method that returns int, got %s.",
typeName,
returnType.toString().toLowerCase()),
- getter,
+ accessor,
annotation);
}
}
@@ -393,21 +449,21 @@
* not considered to be annotated, nor is a {@code long} annotated with
* {@link android.annotation.ColorInt}.
*
- * @param getter The getter to query
+ * @param accessor The getter or field to query
* @return True if the getter has a color annotation, false otherwise
*/
- private boolean hasColorAnnotation(ExecutableElement getter) {
- switch (unboxType(getter.getReturnType())) {
+ private boolean hasColorAnnotation(Element accessor) {
+ switch (unboxType(extractReturnOrFieldType(accessor))) {
case INT:
for (String name : COLOR_INT_ANNOTATION_NAMES) {
- if (mAnnotationUtils.hasAnnotation(getter, name)) {
+ if (mAnnotationUtils.hasAnnotation(accessor, name)) {
return true;
}
}
return false;
case LONG:
for (String name : COLOR_LONG_ANNOTATION_NAMES) {
- if (mAnnotationUtils.hasAnnotation(getter, name)) {
+ if (mAnnotationUtils.hasAnnotation(accessor, name)) {
return true;
}
}
@@ -452,40 +508,40 @@
*
* @see android.view.inspector.IntEnumMapping
* @see android.view.inspector.InspectableProperty#enumMapping()
- * @param getter The getter of the property, used for exceptions
+ * @param accessor The accessor of the property, used for exceptions
* @param annotation The {@link android.view.inspector.InspectableProperty} annotation to
* extract enum mapping values from.
* @return A list of int enum entries, in the order specified in source
* @throws ProcessingException if mapping doesn't exist or is invalid
*/
private List<IntEnumEntry> processEnumMapping(
- ExecutableElement getter,
+ Element accessor,
AnnotationMirror annotation) {
List<AnnotationMirror> enumAnnotations = mAnnotationUtils.typedArrayValuesByName(
- "enumMapping", AnnotationMirror.class, getter, annotation);
+ "enumMapping", AnnotationMirror.class, accessor, annotation);
List<IntEnumEntry> enumEntries = new ArrayList<>(enumAnnotations.size());
if (enumAnnotations.isEmpty()) {
throw new ProcessingException(
- "Encountered an empty array for enumMapping", getter, annotation);
+ "Encountered an empty array for enumMapping", accessor, annotation);
}
for (AnnotationMirror enumAnnotation : enumAnnotations) {
final String name = mAnnotationUtils.typedValueByName(
- "name", String.class, getter, enumAnnotation)
+ "name", String.class, accessor, enumAnnotation)
.orElseThrow(() -> {
throw new ProcessingException(
"Name is required for @EnumMap",
- getter,
+ accessor,
enumAnnotation);
});
final int value = mAnnotationUtils.typedValueByName(
- "value", Integer.class, getter, enumAnnotation)
+ "value", Integer.class, accessor, enumAnnotation)
.orElseThrow(() -> {
throw new ProcessingException(
"Value is required for @EnumMap",
- getter,
+ accessor,
enumAnnotation);
});
@@ -504,45 +560,45 @@
*
* @see android.view.inspector.IntFlagMapping
* @see android.view.inspector.InspectableProperty#flagMapping()
- * @param getter The getter of the property, used for exceptions
+ * @param accessor The accessor of the property, used for exceptions
* @param annotation The {@link android.view.inspector.InspectableProperty} annotation to
* extract flag mapping values from.
* @return A list of int flags entries, in the order specified in source
* @throws ProcessingException if mapping doesn't exist or is invalid
*/
private List<IntFlagEntry> processFlagMapping(
- ExecutableElement getter,
+ Element accessor,
AnnotationMirror annotation) {
List<AnnotationMirror> flagAnnotations = mAnnotationUtils.typedArrayValuesByName(
- "flagMapping", AnnotationMirror.class, getter, annotation);
+ "flagMapping", AnnotationMirror.class, accessor, annotation);
List<IntFlagEntry> flagEntries = new ArrayList<>(flagAnnotations.size());
if (flagAnnotations.isEmpty()) {
throw new ProcessingException(
- "Encountered an empty array for flagMapping", getter, annotation);
+ "Encountered an empty array for flagMapping", accessor, annotation);
}
for (AnnotationMirror flagAnnotation : flagAnnotations) {
final String name = mAnnotationUtils.typedValueByName(
- "name", String.class, getter, flagAnnotation)
+ "name", String.class, accessor, flagAnnotation)
.orElseThrow(() -> {
throw new ProcessingException(
"Name is required for @FlagMap",
- getter,
+ accessor,
flagAnnotation);
});
final int target = mAnnotationUtils.typedValueByName(
- "target", Integer.class, getter, flagAnnotation)
+ "target", Integer.class, accessor, flagAnnotation)
.orElseThrow(() -> {
throw new ProcessingException(
"Target is required for @FlagMap",
- getter,
+ accessor,
flagAnnotation);
});
final Optional<Integer> mask = mAnnotationUtils.typedValueByName(
- "mask", Integer.class, getter, flagAnnotation);
+ "mask", Integer.class, accessor, flagAnnotation);
if (mask.isPresent()) {
flagEntries.add(new IntFlagEntry(name, target, mask.get()));
diff --git a/tools/processors/view_inspector/src/java/android/processor/view/inspector/InspectionCompanionGenerator.java b/tools/processors/view_inspector/src/java/android/processor/view/inspector/InspectionCompanionGenerator.java
index 7b04645..1ab9914 100644
--- a/tools/processors/view_inspector/src/java/android/processor/view/inspector/InspectionCompanionGenerator.java
+++ b/tools/processors/view_inspector/src/java/android/processor/view/inspector/InspectionCompanionGenerator.java
@@ -16,6 +16,7 @@
package android.processor.view.inspector;
+
import android.processor.view.inspector.InspectableClassModel.IntEnumEntry;
import android.processor.view.inspector.InspectableClassModel.IntFlagEntry;
import android.processor.view.inspector.InspectableClassModel.Property;
@@ -268,10 +269,10 @@
for (PropertyIdField propertyIdField : propertyIdFields) {
builder.addStatement(
- "propertyReader.read$L($N, node.$L())",
+ "propertyReader.read$L($N, node.$L)",
methodSuffixForPropertyType(propertyIdField.mProperty.getType()),
propertyIdField.mFieldSpec,
- propertyIdField.mProperty.getGetter());
+ propertyIdField.mProperty.getAccessor().invocation());
}
return builder.build();
diff --git a/tools/processors/view_inspector/test/java/android/processor/view/inspector/InspectionCompanionGeneratorTest.java b/tools/processors/view_inspector/test/java/android/processor/view/inspector/InspectionCompanionGeneratorTest.java
index f6d8bb0..35f0fcf 100644
--- a/tools/processors/view_inspector/test/java/android/processor/view/inspector/InspectionCompanionGeneratorTest.java
+++ b/tools/processors/view_inspector/test/java/android/processor/view/inspector/InspectionCompanionGeneratorTest.java
@@ -20,6 +20,8 @@
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.fail;
+
+import android.processor.view.inspector.InspectableClassModel.Accessor;
import android.processor.view.inspector.InspectableClassModel.IntEnumEntry;
import android.processor.view.inspector.InspectableClassModel.IntFlagEntry;
import android.processor.view.inspector.InspectableClassModel.Property;
@@ -86,7 +88,7 @@
@Test
public void testNoAttributeId() {
- final Property property = new Property(
+ final Property property = addProperty(
"noAttributeProperty",
"getNoAttributeProperty",
Property.Type.INT);
@@ -98,19 +100,18 @@
@Test
public void testSuppliedAttributeId() {
- final Property property = new Property(
+ final Property property = addProperty(
"suppliedAttributeProperty",
"getSuppliedAttributeProperty",
Property.Type.INT);
property.setAttributeId(0xdecafbad);
- mModel.putProperty(property);
assertGeneratedFileEquals("SuppliedAttributeId");
}
@Test
public void testIntEnum() {
- final Property property = new Property(
+ final Property property = addProperty(
"intEnumProperty",
"getIntEnumProperty",
Property.Type.INT_ENUM);
@@ -127,7 +128,7 @@
@Test
public void testIntFlag() {
- final Property property = new Property(
+ final Property property = addProperty(
"intFlag",
"getIntFlag",
Property.Type.INT_FLAG);
@@ -139,13 +140,21 @@
new IntFlagEntry("WARP", 0x4)
));
- mModel.putProperty(property);
-
assertGeneratedFileEquals("IntFlag");
}
+ @Test
+ public void testFieldProperty() {
+ mModel.putProperty(new Property(
+ "fieldProperty",
+ Accessor.ofField("fieldProperty"),
+ Property.Type.INT));
+
+ assertGeneratedFileEquals("FieldProperty");
+ }
+
private Property addProperty(String name, String getter, Property.Type type) {
- final Property property = new Property(name, getter, type);
+ final Property property = new Property(name, Accessor.ofGetter(getter), type);
mModel.putProperty(property);
return property;
}
diff --git a/tools/processors/view_inspector/test/resources/android/processor/view/inspector/InspectionCompanionGeneratorTest/FieldProperty.java.txt b/tools/processors/view_inspector/test/resources/android/processor/view/inspector/InspectionCompanionGeneratorTest/FieldProperty.java.txt
new file mode 100644
index 0000000..a44c43e
--- /dev/null
+++ b/tools/processors/view_inspector/test/resources/android/processor/view/inspector/InspectionCompanionGeneratorTest/FieldProperty.java.txt
@@ -0,0 +1,39 @@
+package com.android.node;
+
+import android.R;
+import android.view.inspector.InspectionCompanion;
+import android.view.inspector.PropertyMapper;
+import android.view.inspector.PropertyReader;
+import java.lang.Override;
+
+/**
+ * Inspection companion for {@link TestNode}.
+ *
+ * Generated by {@link android.processor.view.inspector.InspectionCompanionGenerator}
+ * on behalf of {@link android.processor.view.inspector.InspectionCompanionGeneratorTest}.
+ */
+public final class TestNode$$InspectionCompanion implements InspectionCompanion<TestNode> {
+ /**
+ * Set by {@link #mapProperties(PropertyMapper)} once properties have been mapped.
+ */
+ private boolean mPropertiesMapped = false;
+
+ /**
+ * Property ID of {@code fieldProperty}.
+ */
+ private int mFieldPropertyId;
+
+ @Override
+ public void mapProperties(PropertyMapper propertyMapper) {
+ mFieldPropertyId = propertyMapper.mapInt("fieldProperty", R.attr.fieldProperty);
+ mPropertiesMapped = true;
+ }
+
+ @Override
+ public void readProperties(TestNode node, PropertyReader propertyReader) {
+ if (!mPropertiesMapped) {
+ throw new InspectionCompanion.UninitializedPropertyMapException();
+ }
+ propertyReader.readInt(mFieldPropertyId, node.fieldProperty);
+ }
+}