Merge "Revert "Fix issue in attached layouting"" into qt-dev
diff --git a/Android.bp b/Android.bp
index 6a85f62..c3025e8 100644
--- a/Android.bp
+++ b/Android.bp
@@ -480,10 +480,7 @@
"media/java/android/media/IMediaHTTPConnection.aidl",
"media/java/android/media/IMediaHTTPService.aidl",
"media/java/android/media/IMediaResourceMonitor.aidl",
- "media/java/android/media/IMediaRoute2Callback.aidl",
- "media/java/android/media/IMediaRoute2Provider.aidl",
"media/java/android/media/IMediaRouterClient.aidl",
- "media/java/android/media/IMediaRouter2ManagerClient.aidl",
"media/java/android/media/IMediaRouterService.aidl",
"media/java/android/media/IMediaScannerListener.aidl",
"media/java/android/media/IMediaScannerService.aidl",
@@ -1836,4 +1833,4 @@
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 ccfc0f5..34ba3fc 100644
--- a/api/current.txt
+++ b/api/current.txt
@@ -734,6 +734,7 @@
field public static final int iconTintMode = 16844127; // 0x101055f
field public static final int iconifiedByDefault = 16843514; // 0x10102fa
field public static final int id = 16842960; // 0x10100d0
+ field public static final int identifier = 16844204; // 0x10105ac
field public static final int ignoreGravity = 16843263; // 0x10101ff
field public static final int imageButtonStyle = 16842866; // 0x1010072
field public static final int imageWellStyle = 16842867; // 0x1010073
@@ -9000,7 +9001,7 @@
method @Nullable public byte[] getManufacturerSpecificData(int);
method public java.util.Map<android.os.ParcelUuid,byte[]> getServiceData();
method @Nullable public byte[] getServiceData(android.os.ParcelUuid);
- method @Nullable public java.util.List<android.os.ParcelUuid> getServiceSolicitationUuids();
+ method @NonNull public java.util.List<android.os.ParcelUuid> getServiceSolicitationUuids();
method public java.util.List<android.os.ParcelUuid> getServiceUuids();
method public int getTxPowerLevel();
}
@@ -10085,6 +10086,7 @@
method public int getFlags();
method @Nullable public float[] getFloatArrayExtra(String);
method public float getFloatExtra(String, float);
+ method @Nullable public String getIdentifier();
method @Nullable public int[] getIntArrayExtra(String);
method public int getIntExtra(String, int);
method @Nullable public java.util.ArrayList<java.lang.Integer> getIntegerArrayListExtra(String);
@@ -10168,6 +10170,7 @@
method @NonNull public android.content.Intent setDataAndTypeAndNormalize(@NonNull android.net.Uri, @Nullable String);
method public void setExtrasClassLoader(@Nullable ClassLoader);
method @NonNull public android.content.Intent setFlags(int);
+ method @NonNull public android.content.Intent setIdentifier(@Nullable String);
method @NonNull public android.content.Intent setPackage(@Nullable String);
method public void setSelector(@Nullable android.content.Intent);
method public void setSourceBounds(@Nullable android.graphics.Rect);
@@ -10428,6 +10431,7 @@
field public static final int FILL_IN_CLIP_DATA = 128; // 0x80
field public static final int FILL_IN_COMPONENT = 8; // 0x8
field public static final int FILL_IN_DATA = 2; // 0x2
+ field public static final int FILL_IN_IDENTIFIER = 256; // 0x100
field public static final int FILL_IN_PACKAGE = 16; // 0x10
field public static final int FILL_IN_SELECTOR = 64; // 0x40
field public static final int FILL_IN_SOURCE_BOUNDS = 32; // 0x20
@@ -23041,6 +23045,7 @@
public final class AudioAttributes implements android.os.Parcelable {
method public boolean areHapticChannelsMuted();
method public int describeContents();
+ method public int getAllowedCapturePolicy();
method public int getContentType();
method public int getFlags();
method public int getUsage();
@@ -23246,6 +23251,7 @@
method public int generateAudioSessionId();
method @NonNull public java.util.List<android.media.AudioPlaybackConfiguration> getActivePlaybackConfigurations();
method @NonNull public java.util.List<android.media.AudioRecordingConfiguration> getActiveRecordingConfigurations();
+ method public int getAllowedCapturePolicy();
method public android.media.AudioDeviceInfo[] getDevices(int);
method public java.util.List<android.media.MicrophoneInfo> getMicrophones() throws java.io.IOException;
method public int getMode();
@@ -23418,6 +23424,10 @@
}
public final class AudioPlaybackCaptureConfiguration {
+ method @NonNull public int[] getExcludeUids();
+ method @NonNull public int[] getExcludeUsages();
+ method @NonNull public int[] getMatchingUids();
+ method @NonNull public int[] getMatchingUsages();
method @NonNull public android.media.projection.MediaProjection getMediaProjection();
}
@@ -23776,27 +23786,6 @@
field public static final int QUALITY_MEDIUM = 1; // 0x1
}
- public class DataSourceDesc {
- method public long getEndPosition();
- 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
- }
-
- public static final class DataSourceDesc.Builder {
- ctor public DataSourceDesc.Builder();
- ctor public DataSourceDesc.Builder(@Nullable android.media.DataSourceDesc);
- method @NonNull public android.media.DataSourceDesc build();
- method @NonNull public android.media.DataSourceDesc.Builder setDataSource(@NonNull android.net.Uri);
- method @NonNull public android.media.DataSourceDesc.Builder setDataSource(@NonNull android.net.Uri, @Nullable java.util.Map<java.lang.String,java.lang.String>, @Nullable java.util.List<java.net.HttpCookie>);
- method @NonNull public android.media.DataSourceDesc.Builder setDataSource(@NonNull android.os.ParcelFileDescriptor);
- method @NonNull public android.media.DataSourceDesc.Builder setDataSource(@NonNull android.os.ParcelFileDescriptor, long, long);
- method @NonNull public android.media.DataSourceDesc.Builder setEndPosition(long);
- method @NonNull public android.media.DataSourceDesc.Builder setMediaId(@Nullable String);
- method @NonNull public android.media.DataSourceDesc.Builder setStartPosition(long);
- }
-
public final class DeniedByServerException extends android.media.MediaDrmException {
ctor public DeniedByServerException(String);
}
@@ -24663,8 +24652,6 @@
}
public class MediaController2 implements java.lang.AutoCloseable {
- ctor public MediaController2(@NonNull android.content.Context, @NonNull android.media.Session2Token);
- ctor public MediaController2(@NonNull android.content.Context, @NonNull android.media.Session2Token, @NonNull java.util.concurrent.Executor, @NonNull android.media.MediaController2.ControllerCallback);
method public void cancelSessionCommand(@NonNull Object);
method public void close();
method @Nullable public android.media.Session2Token getConnectedSessionToken();
@@ -24672,6 +24659,13 @@
method @NonNull public Object sendSessionCommand(@NonNull android.media.Session2Command, @Nullable android.os.Bundle);
}
+ public static final class MediaController2.Builder {
+ ctor public MediaController2.Builder(@NonNull android.content.Context, @NonNull android.media.Session2Token);
+ method @NonNull public android.media.MediaController2 build();
+ method @NonNull public android.media.MediaController2.Builder setConnectionHints(@NonNull android.os.Bundle);
+ method @NonNull public android.media.MediaController2.Builder setControllerCallback(@NonNull java.util.concurrent.Executor, @NonNull android.media.MediaController2.ControllerCallback);
+ }
+
public abstract static class MediaController2.ControllerCallback {
ctor public MediaController2.ControllerCallback();
method public void onCommandResult(@NonNull android.media.MediaController2, @NonNull Object, @NonNull android.media.Session2Command, @NonNull android.media.Session2Command.Result);
@@ -25555,225 +25549,6 @@
field public static final int MEDIA_TRACK_TYPE_VIDEO = 1; // 0x1
}
- public class MediaPlayer2 implements android.media.AudioRouting java.lang.AutoCloseable {
- 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 @NonNull public Object clearNextDataSources();
- method public void clearPendingCommands();
- method public void close();
- method @NonNull public Object deselectTrack(@NonNull android.media.MediaPlayer2.TrackInfo);
- method @NonNull public Object deselectTrack(@NonNull android.media.DataSourceDesc, @NonNull android.media.MediaPlayer2.TrackInfo);
- method @NonNull public android.media.AudioAttributes getAudioAttributes();
- method public int getAudioSessionId();
- method public long getBufferedPosition();
- method public long getBufferedPosition(@NonNull android.media.DataSourceDesc);
- method @Nullable public android.media.DataSourceDesc getCurrentDataSource();
- method public long getCurrentPosition();
- method public long getDuration();
- method public long getDuration(@NonNull android.media.DataSourceDesc);
- method public float getMaxPlayerVolume();
- method @Nullable public android.os.PersistableBundle getMetrics();
- method @NonNull public android.media.PlaybackParams getPlaybackParams();
- method public float getPlayerVolume();
- method @Nullable public android.media.AudioDeviceInfo getPreferredDevice();
- method @Nullable public android.media.AudioDeviceInfo getRoutedDevice();
- method @Nullable public android.media.MediaPlayer2.TrackInfo getSelectedTrack(int);
- method @Nullable public android.media.MediaPlayer2.TrackInfo getSelectedTrack(@NonNull android.media.DataSourceDesc, int);
- method public int getState();
- method @NonNull public android.media.SyncParams getSyncParams();
- 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 @NonNull public android.util.Size getVideoSize();
- method public boolean isLooping();
- 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(@NonNull android.media.AudioRouting.OnRoutingChangedListener);
- method public void reset();
- method @NonNull public Object seekTo(long);
- method @NonNull public Object seekTo(long, int);
- method @NonNull public Object selectTrack(@NonNull android.media.MediaPlayer2.TrackInfo);
- method @NonNull public Object selectTrack(@NonNull android.media.DataSourceDesc, @NonNull android.media.MediaPlayer2.TrackInfo);
- 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 @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
- field public static final int CALL_COMPLETED_LOOP_CURRENT = 3; // 0x3
- field public static final int CALL_COMPLETED_PAUSE = 4; // 0x4
- field public static final int CALL_COMPLETED_PLAY = 5; // 0x5
- field public static final int CALL_COMPLETED_PREPARE = 6; // 0x6
- field public static final int CALL_COMPLETED_SEEK_TO = 14; // 0xe
- field public static final int CALL_COMPLETED_SELECT_TRACK = 15; // 0xf
- field public static final int CALL_COMPLETED_SET_AUDIO_ATTRIBUTES = 16; // 0x10
- field public static final int CALL_COMPLETED_SET_AUDIO_SESSION_ID = 17; // 0x11
- field public static final int CALL_COMPLETED_SET_AUX_EFFECT_SEND_LEVEL = 18; // 0x12
- field public static final int CALL_COMPLETED_SET_DATA_SOURCE = 19; // 0x13
- field public static final int CALL_COMPLETED_SET_DISPLAY = 33; // 0x21
- field public static final int CALL_COMPLETED_SET_NEXT_DATA_SOURCE = 22; // 0x16
- field public static final int CALL_COMPLETED_SET_NEXT_DATA_SOURCES = 23; // 0x17
- field public static final int CALL_COMPLETED_SET_PLAYBACK_PARAMS = 24; // 0x18
- field public static final int CALL_COMPLETED_SET_PLAYER_VOLUME = 26; // 0x1a
- field public static final int CALL_COMPLETED_SET_SCREEN_ON_WHILE_PLAYING = 35; // 0x23
- field public static final int CALL_COMPLETED_SET_SURFACE = 27; // 0x1b
- field public static final int CALL_COMPLETED_SET_SYNC_PARAMS = 28; // 0x1c
- field public static final int CALL_COMPLETED_SET_WAKE_LOCK = 34; // 0x22
- field public static final int CALL_COMPLETED_SKIP_TO_NEXT = 29; // 0x1d
- field public static final int CALL_STATUS_BAD_VALUE = 2; // 0x2
- field public static final int CALL_STATUS_ERROR_IO = 4; // 0x4
- field public static final int CALL_STATUS_ERROR_UNKNOWN = -2147483648; // 0x80000000
- field public static final int CALL_STATUS_INVALID_OPERATION = 1; // 0x1
- field public static final int CALL_STATUS_NO_DRM_SCHEME = 6; // 0x6
- field public static final int CALL_STATUS_NO_ERROR = 0; // 0x0
- field public static final int CALL_STATUS_PERMISSION_DENIED = 3; // 0x3
- field public static final int CALL_STATUS_SKIPPED = 5; // 0x5
- field public static final int MEDIA_ERROR_IO = -1004; // 0xfffffc14
- field public static final int MEDIA_ERROR_MALFORMED = -1007; // 0xfffffc11
- field public static final int MEDIA_ERROR_NOT_VALID_FOR_PROGRESSIVE_PLAYBACK = 200; // 0xc8
- field public static final int MEDIA_ERROR_TIMED_OUT = -110; // 0xffffff92
- field public static final int MEDIA_ERROR_UNKNOWN = 1; // 0x1
- field public static final int MEDIA_ERROR_UNSUPPORTED = -1010; // 0xfffffc0e
- field public static final int MEDIA_INFO_AUDIO_NOT_PLAYING = 804; // 0x324
- field public static final int MEDIA_INFO_AUDIO_RENDERING_START = 4; // 0x4
- field public static final int MEDIA_INFO_BAD_INTERLEAVING = 800; // 0x320
- field public static final int MEDIA_INFO_BUFFERING_END = 702; // 0x2be
- field public static final int MEDIA_INFO_BUFFERING_START = 701; // 0x2bd
- field public static final int MEDIA_INFO_BUFFERING_UPDATE = 704; // 0x2c0
- field public static final int MEDIA_INFO_DATA_SOURCE_END = 5; // 0x5
- field public static final int MEDIA_INFO_DATA_SOURCE_LIST_END = 6; // 0x6
- field public static final int MEDIA_INFO_DATA_SOURCE_REPEAT = 7; // 0x7
- field public static final int MEDIA_INFO_DATA_SOURCE_START = 2; // 0x2
- field public static final int MEDIA_INFO_METADATA_UPDATE = 802; // 0x322
- field public static final int MEDIA_INFO_NOT_SEEKABLE = 801; // 0x321
- field public static final int MEDIA_INFO_PREPARED = 100; // 0x64
- field public static final int MEDIA_INFO_SUBTITLE_TIMED_OUT = 902; // 0x386
- field public static final int MEDIA_INFO_UNKNOWN = 1; // 0x1
- field public static final int MEDIA_INFO_UNSUPPORTED_SUBTITLE = 901; // 0x385
- field public static final int MEDIA_INFO_VIDEO_NOT_PLAYING = 805; // 0x325
- field public static final int MEDIA_INFO_VIDEO_RENDERING_START = 3; // 0x3
- field public static final int MEDIA_INFO_VIDEO_TRACK_LAGGING = 700; // 0x2bc
- field public static final int PLAYER_STATE_ERROR = 1005; // 0x3ed
- field public static final int PLAYER_STATE_IDLE = 1001; // 0x3e9
- field public static final int PLAYER_STATE_PAUSED = 1003; // 0x3eb
- field public static final int PLAYER_STATE_PLAYING = 1004; // 0x3ec
- field public static final int PLAYER_STATE_PREPARED = 1002; // 0x3ea
- field public static final int PREPARE_DRM_STATUS_KEY_EXCHANGE_ERROR = 7; // 0x7
- field public static final int PREPARE_DRM_STATUS_PREPARATION_ERROR = 3; // 0x3
- field public static final int PREPARE_DRM_STATUS_PROVISIONING_NETWORK_ERROR = 1; // 0x1
- field public static final int PREPARE_DRM_STATUS_PROVISIONING_SERVER_ERROR = 2; // 0x2
- field public static final int PREPARE_DRM_STATUS_RESOURCE_BUSY = 5; // 0x5
- field public static final int PREPARE_DRM_STATUS_RESTORE_ERROR = 6; // 0x6
- field public static final int PREPARE_DRM_STATUS_SUCCESS = 0; // 0x0
- field public static final int PREPARE_DRM_STATUS_UNSUPPORTED_SCHEME = 4; // 0x4
- field public static final int SEEK_CLOSEST = 3; // 0x3
- field public static final int SEEK_CLOSEST_SYNC = 2; // 0x2
- field public static final int SEEK_NEXT_SYNC = 1; // 0x1
- field public static final int SEEK_PREVIOUS_SYNC = 0; // 0x0
- }
-
- public abstract static class MediaPlayer2.DrmEventCallback {
- ctor public MediaPlayer2.DrmEventCallback();
- method public void onDrmConfig(@NonNull android.media.MediaPlayer2, @NonNull android.media.DataSourceDesc, @NonNull android.media.MediaDrm);
- method @Nullable public abstract android.media.MediaPlayer2.DrmPreparationInfo onDrmInfo(@NonNull android.media.MediaPlayer2, @NonNull android.media.DataSourceDesc, @NonNull android.media.MediaPlayer2.DrmInfo);
- method @NonNull public abstract byte[] onDrmKeyRequest(@NonNull android.media.MediaPlayer2, @NonNull android.media.DataSourceDesc, @NonNull android.media.MediaDrm.KeyRequest);
- method public void onDrmPrepared(@NonNull android.media.MediaPlayer2, @NonNull android.media.DataSourceDesc, int, @Nullable byte[]);
- }
-
- public static final class MediaPlayer2.DrmInfo {
- method @NonNull public java.util.Map<java.util.UUID,byte[]> getPssh();
- method @NonNull public java.util.List<java.util.UUID> getSupportedSchemes();
- }
-
- public static final class MediaPlayer2.DrmPreparationInfo {
- method @Nullable public byte[] getInitData();
- method @Nullable public byte[] getKeySetId();
- method public int getKeyType();
- method @Nullable public String getMimeType();
- method @Nullable public java.util.Map<java.lang.String,java.lang.String> getOptionalParameters();
- method @NonNull public java.util.UUID getUuid();
- }
-
- public static final class MediaPlayer2.DrmPreparationInfo.Builder {
- ctor public MediaPlayer2.DrmPreparationInfo.Builder(@NonNull java.util.UUID);
- method @NonNull public android.media.MediaPlayer2.DrmPreparationInfo build();
- method @NonNull public android.media.MediaPlayer2.DrmPreparationInfo.Builder setInitData(@Nullable byte[]);
- method @NonNull public android.media.MediaPlayer2.DrmPreparationInfo.Builder setKeySetId(@Nullable byte[]);
- method @NonNull public android.media.MediaPlayer2.DrmPreparationInfo.Builder setKeyType(int);
- method @NonNull public android.media.MediaPlayer2.DrmPreparationInfo.Builder setMimeType(@Nullable String);
- method @NonNull public android.media.MediaPlayer2.DrmPreparationInfo.Builder setOptionalParameters(@Nullable java.util.Map<java.lang.String,java.lang.String>);
- }
-
- public static class MediaPlayer2.EventCallback {
- ctor public MediaPlayer2.EventCallback();
- method public void onCallCompleted(@NonNull android.media.MediaPlayer2, @NonNull android.media.DataSourceDesc, int, int);
- method public void onCommandLabelReached(@NonNull android.media.MediaPlayer2, @NonNull Object);
- method public void onError(@NonNull android.media.MediaPlayer2, @NonNull android.media.DataSourceDesc, int, int);
- method public void onInfo(@NonNull android.media.MediaPlayer2, @NonNull android.media.DataSourceDesc, int, int);
- method public void onMediaTimeDiscontinuity(@NonNull android.media.MediaPlayer2, @NonNull android.media.DataSourceDesc, @NonNull android.media.MediaTimestamp);
- method public void onSubtitleData(@NonNull android.media.MediaPlayer2, @NonNull android.media.DataSourceDesc, @NonNull android.media.MediaPlayer2.SubtitleData);
- method public void onTimedMetaDataAvailable(@NonNull android.media.MediaPlayer2, @NonNull android.media.DataSourceDesc, @NonNull android.media.TimedMetaData);
- method public void onVideoSizeChanged(@NonNull android.media.MediaPlayer2, @NonNull android.media.DataSourceDesc, @NonNull android.util.Size);
- }
-
- public static final class MediaPlayer2.MetricsConstants {
- field public static final String CODEC_AUDIO = "android.media.mediaplayer.audio.codec";
- field public static final String CODEC_VIDEO = "android.media.mediaplayer.video.codec";
- field public static final String DURATION = "android.media.mediaplayer.durationMs";
- field public static final String ERRORS = "android.media.mediaplayer.err";
- field public static final String ERROR_CODE = "android.media.mediaplayer.errcode";
- field public static final String FRAMES = "android.media.mediaplayer.frames";
- field public static final String FRAMES_DROPPED = "android.media.mediaplayer.dropped";
- field public static final String HEIGHT = "android.media.mediaplayer.height";
- field public static final String MIME_TYPE_AUDIO = "android.media.mediaplayer.audio.mime";
- field public static final String MIME_TYPE_VIDEO = "android.media.mediaplayer.video.mime";
- field public static final String PLAYING = "android.media.mediaplayer.playingMs";
- field public static final String WIDTH = "android.media.mediaplayer.width";
- }
-
- public static final class MediaPlayer2.NoDrmSchemeException extends android.media.MediaDrmException {
- ctor public MediaPlayer2.NoDrmSchemeException(@Nullable String);
- }
-
- public static final class MediaPlayer2.SubtitleData {
- method @NonNull public byte[] getData();
- method public long getDurationUs();
- method public long getStartTimeUs();
- method @NonNull public android.media.MediaPlayer2.TrackInfo getTrackInfo();
- }
-
- public static class MediaPlayer2.TrackInfo {
- method @Nullable public android.media.MediaFormat getFormat();
- method @NonNull 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
- field public static final int MEDIA_TRACK_TYPE_SUBTITLE = 4; // 0x4
- field public static final int MEDIA_TRACK_TYPE_UNKNOWN = 0; // 0x0
- field public static final int MEDIA_TRACK_TYPE_VIDEO = 1; // 0x1
- }
-
public class MediaRecorder implements android.media.AudioRecordingMonitor android.media.AudioRouting android.media.MicrophoneDirection {
ctor public MediaRecorder();
method public void addOnRoutingChangedListener(android.media.AudioRouting.OnRoutingChangedListener, android.os.Handler);
@@ -26080,6 +25855,7 @@
}
public static final class MediaSession2.ControllerInfo {
+ method @NonNull public android.os.Bundle getConnectionHints();
method @NonNull public String getPackageName();
method @NonNull public android.media.session.MediaSessionManager.RemoteUserInfo getRemoteUserInfo();
method public int getUid();
@@ -26099,7 +25875,7 @@
method public final void addSession(@NonNull android.media.MediaSession2);
method @NonNull public final java.util.List<android.media.MediaSession2> getSessions();
method @CallSuper @Nullable public android.os.IBinder onBind(@NonNull android.content.Intent);
- method @NonNull public abstract android.media.MediaSession2 onGetPrimarySession();
+ method @Nullable public abstract android.media.MediaSession2 onGetSession(@NonNull android.media.MediaSession2.ControllerInfo);
method @Nullable public abstract android.media.MediaSession2Service.MediaNotification onUpdateNotification(@NonNull android.media.MediaSession2);
method public final void removeSession(@NonNull android.media.MediaSession2);
field public static final String SERVICE_INTERFACE = "android.media.MediaSession2Service";
@@ -28756,10 +28532,13 @@
public final class DnsResolver {
method @NonNull public static android.net.DnsResolver getInstance();
- method public <T> void query(@Nullable android.net.Network, @NonNull byte[], int, @NonNull java.util.concurrent.Executor, @Nullable android.os.CancellationSignal, @NonNull android.net.DnsResolver.AnswerCallback<T>);
- method public <T> void query(@Nullable android.net.Network, @NonNull String, int, int, int, @NonNull java.util.concurrent.Executor, @Nullable android.os.CancellationSignal, @NonNull android.net.DnsResolver.AnswerCallback<T>);
- method public void query(@Nullable android.net.Network, @NonNull String, int, @NonNull java.util.concurrent.Executor, @Nullable android.os.CancellationSignal, @NonNull android.net.DnsResolver.InetAddressAnswerCallback);
+ method public void query(@Nullable android.net.Network, @NonNull String, int, @NonNull java.util.concurrent.Executor, @Nullable android.os.CancellationSignal, @NonNull android.net.DnsResolver.Callback<? super java.util.List<java.net.InetAddress>>);
+ method public void query(@Nullable android.net.Network, @NonNull String, int, int, @NonNull java.util.concurrent.Executor, @Nullable android.os.CancellationSignal, @NonNull android.net.DnsResolver.Callback<? super java.util.List<java.net.InetAddress>>);
+ method public void rawQuery(@Nullable android.net.Network, @NonNull byte[], int, @NonNull java.util.concurrent.Executor, @Nullable android.os.CancellationSignal, @NonNull android.net.DnsResolver.Callback<? super byte[]>);
+ method public void rawQuery(@Nullable android.net.Network, @NonNull String, int, int, int, @NonNull java.util.concurrent.Executor, @Nullable android.os.CancellationSignal, @NonNull android.net.DnsResolver.Callback<? super byte[]>);
field public static final int CLASS_IN = 1; // 0x1
+ field public static final int ERROR_PARSE = 0; // 0x0
+ field public static final int ERROR_SYSTEM = 1; // 0x1
field public static final int FLAG_EMPTY = 0; // 0x0
field public static final int FLAG_NO_CACHE_LOOKUP = 4; // 0x4
field public static final int FLAG_NO_CACHE_STORE = 2; // 0x2
@@ -28768,23 +28547,13 @@
field public static final int TYPE_AAAA = 28; // 0x1c
}
- public abstract static class DnsResolver.AnswerCallback<T> {
- ctor public DnsResolver.AnswerCallback(@NonNull android.net.DnsResolver.AnswerParser<T>);
- method public abstract void onAnswer(@NonNull T);
- method public abstract void onParseException(@NonNull android.net.ParseException);
- method public abstract void onQueryException(@NonNull android.system.ErrnoException);
+ public static interface DnsResolver.Callback<T> {
+ method public void onAnswer(@NonNull T, int);
+ method public void onError(@NonNull android.net.DnsResolver.DnsException);
}
- public static interface DnsResolver.AnswerParser<T> {
- method @NonNull public T parse(@NonNull byte[]) throws android.net.ParseException;
- }
-
- public abstract static class DnsResolver.InetAddressAnswerCallback extends android.net.DnsResolver.AnswerCallback<java.util.List<java.net.InetAddress>> {
- ctor public DnsResolver.InetAddressAnswerCallback();
- }
-
- public abstract static class DnsResolver.RawAnswerCallback extends android.net.DnsResolver.AnswerCallback<byte[]> {
- ctor public DnsResolver.RawAnswerCallback();
+ public static class DnsResolver.DnsException extends java.lang.Exception {
+ field public final int code;
}
public class InetAddresses {
@@ -29110,8 +28879,6 @@
}
public class ParseException extends java.lang.RuntimeException {
- ctor public ParseException(@NonNull String);
- ctor public ParseException(@NonNull String, @NonNull Throwable);
field public String response;
}
@@ -38591,7 +38358,6 @@
field public static final String ARTIST_KEY = "artist_key";
field public static final String BOOKMARK = "bookmark";
field public static final String COMPOSER = "composer";
- field public static final String DURATION = "duration";
field public static final String IS_ALARM = "is_alarm";
field public static final String IS_AUDIOBOOK = "is_audiobook";
field public static final String IS_MUSIC = "is_music";
@@ -38674,7 +38440,6 @@
}
public static interface MediaStore.DownloadColumns extends android.provider.MediaStore.MediaColumns {
- field public static final String DESCRIPTION = "description";
field public static final String DOWNLOAD_URI = "download_uri";
field public static final String REFERER_URI = "referer_uri";
}
@@ -38709,16 +38474,11 @@
}
public static interface MediaStore.Images.ImageColumns extends android.provider.MediaStore.MediaColumns {
- field public static final String BUCKET_DISPLAY_NAME = "bucket_display_name";
- field public static final String BUCKET_ID = "bucket_id";
- field public static final String DATE_TAKEN = "datetaken";
field public static final String DESCRIPTION = "description";
- field public static final String GROUP_ID = "group_id";
field public static final String IS_PRIVATE = "isprivate";
field @Deprecated public static final String LATITUDE = "latitude";
field @Deprecated public static final String LONGITUDE = "longitude";
field @Deprecated public static final String MINI_THUMB_MAGIC = "mini_thumb_magic";
- field public static final String ORIENTATION = "orientation";
field @Deprecated public static final String PICASA_ID = "picasa_id";
}
@@ -38762,16 +38522,22 @@
}
public static interface MediaStore.MediaColumns extends android.provider.BaseColumns {
+ field public static final String BUCKET_DISPLAY_NAME = "bucket_display_name";
+ field public static final String BUCKET_ID = "bucket_id";
field @Deprecated public static final String DATA = "_data";
field public static final String DATE_ADDED = "date_added";
field public static final String DATE_EXPIRES = "date_expires";
field public static final String DATE_MODIFIED = "date_modified";
+ field public static final String DATE_TAKEN = "datetaken";
field public static final String DISPLAY_NAME = "_display_name";
field public static final String DOCUMENT_ID = "document_id";
+ field public static final String DURATION = "duration";
+ field public static final String GROUP_ID = "group_id";
field public static final String HEIGHT = "height";
field public static final String INSTANCE_ID = "instance_id";
field public static final String IS_PENDING = "is_pending";
field public static final String MIME_TYPE = "mime_type";
+ field public static final String ORIENTATION = "orientation";
field public static final String ORIGINAL_DOCUMENT_ID = "original_document_id";
field public static final String OWNER_PACKAGE_NAME = "owner_package_name";
field public static final String RELATIVE_PATH = "relative_path";
@@ -38820,13 +38586,8 @@
field public static final String ALBUM = "album";
field public static final String ARTIST = "artist";
field public static final String BOOKMARK = "bookmark";
- field public static final String BUCKET_DISPLAY_NAME = "bucket_display_name";
- field public static final String BUCKET_ID = "bucket_id";
field public static final String CATEGORY = "category";
- field public static final String DATE_TAKEN = "datetaken";
field public static final String DESCRIPTION = "description";
- field public static final String DURATION = "duration";
- field public static final String GROUP_ID = "group_id";
field public static final String IS_PRIVATE = "isprivate";
field public static final String LANGUAGE = "language";
field @Deprecated public static final String LATITUDE = "latitude";
@@ -39335,7 +39096,7 @@
field @Deprecated public static final String BEARER = "bearer";
field public static final String CARRIER_ENABLED = "carrier_enabled";
field public static final String CARRIER_ID = "carrier_id";
- field public static final android.net.Uri CONTENT_URI;
+ field @NonNull public static final android.net.Uri CONTENT_URI;
field public static final String CURRENT = "current";
field public static final String DEFAULT_SORT_ORDER = "name ASC";
field @Deprecated public static final String MCC = "mcc";
@@ -39354,7 +39115,7 @@
field public static final String PROXY = "proxy";
field public static final String ROAMING_PROTOCOL = "roaming_protocol";
field public static final String SERVER = "server";
- field public static final android.net.Uri SIM_APN_URI;
+ field @NonNull public static final android.net.Uri SIM_APN_URI;
field public static final String SUBSCRIPTION_ID = "sub_id";
field public static final String TYPE = "type";
field public static final String USER = "user";
@@ -48577,7 +48338,6 @@
method public static boolean logEvent(int);
method public static boolean logStart(int);
method public static boolean logStop(int);
- method public static void write(int, @NonNull java.lang.Object...);
}
public class StringBuilderPrinter implements android.util.Printer {
@@ -54023,7 +53783,7 @@
method public int getEnd();
method @NonNull public String getEntity(int);
method public int getEntityCount();
- method public android.os.Bundle getExtras();
+ method @NonNull public android.os.Bundle getExtras();
method public int getStart();
method public void writeToParcel(android.os.Parcel, int);
field @NonNull public static final android.os.Parcelable.Creator<android.view.textclassifier.TextLinks.TextLink> CREATOR;
diff --git a/api/removed.txt b/api/removed.txt
index 70ff50e..8836326 100644
--- a/api/removed.txt
+++ b/api/removed.txt
@@ -522,6 +522,22 @@
method @Deprecated public static void untrash(@NonNull android.content.Context, @NonNull android.net.Uri);
}
+ public static interface MediaStore.Audio.AudioColumns extends android.provider.MediaStore.MediaColumns {
+ field public static final String DURATION = "duration";
+ }
+
+ public static interface MediaStore.DownloadColumns extends android.provider.MediaStore.MediaColumns {
+ field @Deprecated public static final String DESCRIPTION = "description";
+ }
+
+ public static interface MediaStore.Images.ImageColumns extends android.provider.MediaStore.MediaColumns {
+ field public static final String BUCKET_DISPLAY_NAME = "bucket_display_name";
+ field public static final String BUCKET_ID = "bucket_id";
+ field public static final String DATE_TAKEN = "datetaken";
+ field public static final String GROUP_ID = "group_id";
+ field public static final String ORIENTATION = "orientation";
+ }
+
public static interface MediaStore.MediaColumns extends android.provider.BaseColumns {
field @Deprecated public static final String HASH = "_hash";
field @Deprecated public static final String IS_TRASHED = "is_trashed";
@@ -546,6 +562,14 @@
method @NonNull public android.net.Uri publish();
}
+ public static interface MediaStore.Video.VideoColumns extends android.provider.MediaStore.MediaColumns {
+ field public static final String BUCKET_DISPLAY_NAME = "bucket_display_name";
+ field public static final String BUCKET_ID = "bucket_id";
+ field public static final String DATE_TAKEN = "datetaken";
+ field public static final String DURATION = "duration";
+ field public static final String GROUP_ID = "group_id";
+ }
+
public static final class Settings.Global extends android.provider.Settings.NameValueTable {
field @Deprecated public static final String CONTACT_METADATA_SYNC = "contact_metadata_sync";
}
diff --git a/api/system-current.txt b/api/system-current.txt
index 026ce09..ae27daf 100644
--- a/api/system-current.txt
+++ b/api/system-current.txt
@@ -254,8 +254,6 @@
field public static final int config_defaultAssistant = 17039393; // 0x1040021
field public static final int config_defaultBrowser = 17039394; // 0x1040022
field public static final int config_defaultDialer = 17039395; // 0x1040023
- field public static final int config_defaultGallery = 17039398; // 0x1040026
- field public static final int config_defaultMusic = 17039397; // 0x1040025
field public static final int config_defaultSms = 17039396; // 0x1040024
field public static final int config_feedbackIntentExtraKey = 17039391; // 0x104001f
field public static final int config_feedbackIntentNameKey = 17039392; // 0x1040020
@@ -564,6 +562,7 @@
method @Deprecated @RequiresPermission(allOf={android.Manifest.permission.DUMP, android.Manifest.permission.PACKAGE_USAGE_STATS}) public boolean addConfiguration(long, byte[]);
method @Deprecated @Nullable @RequiresPermission(allOf={android.Manifest.permission.DUMP, android.Manifest.permission.PACKAGE_USAGE_STATS}) public byte[] getData(long);
method @Deprecated @Nullable @RequiresPermission(allOf={android.Manifest.permission.DUMP, android.Manifest.permission.PACKAGE_USAGE_STATS}) public byte[] getMetadata();
+ method @RequiresPermission(allOf={android.Manifest.permission.DUMP, android.Manifest.permission.PACKAGE_USAGE_STATS}) public long[] getRegisteredExperimentIds() throws android.app.StatsManager.StatsUnavailableException;
method @RequiresPermission(allOf={android.Manifest.permission.DUMP, android.Manifest.permission.PACKAGE_USAGE_STATS}) public byte[] getReports(long) throws android.app.StatsManager.StatsUnavailableException;
method @RequiresPermission(allOf={android.Manifest.permission.DUMP, android.Manifest.permission.PACKAGE_USAGE_STATS}) public byte[] getStatsMetadata() throws android.app.StatsManager.StatsUnavailableException;
method @RequiresPermission(allOf={android.Manifest.permission.DUMP, android.Manifest.permission.PACKAGE_USAGE_STATS}) public void removeConfig(long) throws android.app.StatsManager.StatsUnavailableException;
@@ -1217,7 +1216,6 @@
method public int getUsageSource();
method @RequiresPermission(allOf={android.Manifest.permission.SUSPEND_APPS, android.Manifest.permission.OBSERVE_APP_USAGE}) public void registerAppUsageLimitObserver(int, @NonNull String[], @NonNull java.time.Duration, @NonNull java.time.Duration, @Nullable android.app.PendingIntent);
method @RequiresPermission(android.Manifest.permission.OBSERVE_APP_USAGE) public void registerAppUsageObserver(int, @NonNull String[], long, @NonNull java.util.concurrent.TimeUnit, @NonNull android.app.PendingIntent);
- method @Deprecated @RequiresPermission(android.Manifest.permission.OBSERVE_APP_USAGE) public void registerUsageSessionObserver(int, @NonNull String[], long, @NonNull java.util.concurrent.TimeUnit, long, @NonNull java.util.concurrent.TimeUnit, @NonNull android.app.PendingIntent, @Nullable android.app.PendingIntent);
method @RequiresPermission(android.Manifest.permission.OBSERVE_APP_USAGE) public void registerUsageSessionObserver(int, @NonNull String[], @NonNull java.time.Duration, @NonNull java.time.Duration, @NonNull android.app.PendingIntent, @Nullable android.app.PendingIntent);
method public void reportUsageStart(@NonNull android.app.Activity, @NonNull String);
method public void reportUsageStart(@NonNull android.app.Activity, @NonNull String, long);
@@ -2004,15 +2002,15 @@
public final class HdmiControlManager {
method @RequiresPermission(android.Manifest.permission.HDMI_CEC) public void addHotplugEventListener(android.hardware.hdmi.HdmiControlManager.HotplugEventListener);
method @Nullable public android.hardware.hdmi.HdmiClient getClient(int);
- method @Nullable public java.util.List<android.hardware.hdmi.HdmiDeviceInfo> getConnectedDevicesList();
+ method @NonNull public java.util.List<android.hardware.hdmi.HdmiDeviceInfo> getConnectedDevices();
method public int getPhysicalAddress();
method @Nullable public android.hardware.hdmi.HdmiPlaybackClient getPlaybackClient();
method @Nullable public android.hardware.hdmi.HdmiSwitchClient getSwitchClient();
method @Nullable public android.hardware.hdmi.HdmiTvClient getTvClient();
- method public boolean isRemoteDeviceConnected(@NonNull android.hardware.hdmi.HdmiDeviceInfo);
- method public void powerOffRemoteDevice(@NonNull android.hardware.hdmi.HdmiDeviceInfo);
+ method public boolean isDeviceConnected(@NonNull android.hardware.hdmi.HdmiDeviceInfo);
+ method public void powerOffDevice(@NonNull android.hardware.hdmi.HdmiDeviceInfo);
method @RequiresPermission(android.Manifest.permission.HDMI_CEC) public void removeHotplugEventListener(android.hardware.hdmi.HdmiControlManager.HotplugEventListener);
- method public void requestRemoteDeviceToBecomeActiveSource(@NonNull android.hardware.hdmi.HdmiDeviceInfo);
+ method public void setActiveSource(@NonNull android.hardware.hdmi.HdmiDeviceInfo);
method @RequiresPermission(android.Manifest.permission.HDMI_CEC) public void setStandbyMode(boolean);
field public static final String ACTION_OSD_MESSAGE = "android.hardware.hdmi.action.OSD_MESSAGE";
field public static final int AVR_VOLUME_MUTED = 101; // 0x65
@@ -3498,8 +3496,8 @@
method @Deprecated public int abandonAudioFocus(android.media.AudioManager.OnAudioFocusChangeListener, android.media.AudioAttributes);
method public void clearAudioServerStateCallback();
method @RequiresPermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING) public int dispatchAudioFocusChange(@NonNull android.media.AudioFocusInfo, int, @NonNull android.media.audiopolicy.AudioPolicy);
- method @NonNull @RequiresPermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING) public android.media.audiopolicy.AudioProductStrategies getAudioProductStrategies();
- method @NonNull @RequiresPermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING) public android.media.audiopolicy.AudioVolumeGroups getAudioVolumeGroups();
+ method @NonNull @RequiresPermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING) public static java.util.List<android.media.audiopolicy.AudioProductStrategy> getAudioProductStrategies();
+ method @NonNull @RequiresPermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING) public static java.util.List<android.media.audiopolicy.AudioVolumeGroup> getAudioVolumeGroups();
method @IntRange(from=0) @RequiresPermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING) public int getMaxVolumeIndexForAttributes(@NonNull android.media.AudioAttributes);
method @IntRange(from=0) @RequiresPermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING) public int getMinVolumeIndexForAttributes(@NonNull android.media.AudioAttributes);
method @IntRange(from=0) @RequiresPermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING) public int getVolumeIndexForAttributes(@NonNull android.media.AudioAttributes);
@@ -3674,31 +3672,13 @@
method public void setAudioPolicyStatusListener(android.media.audiopolicy.AudioPolicy.AudioPolicyStatusListener);
method @NonNull public android.media.audiopolicy.AudioPolicy.Builder setAudioPolicyVolumeCallback(@NonNull android.media.audiopolicy.AudioPolicy.AudioPolicyVolumeCallback);
method @NonNull public android.media.audiopolicy.AudioPolicy.Builder setIsAudioFocusPolicy(boolean);
- method @NonNull public android.media.audiopolicy.AudioPolicy.Builder setIsTestFocusPolicy(boolean);
method @NonNull public android.media.audiopolicy.AudioPolicy.Builder setLooper(@NonNull android.os.Looper) throws java.lang.IllegalArgumentException;
}
- public final class AudioProductStrategies implements java.lang.Iterable<android.media.audiopolicy.AudioProductStrategy> android.os.Parcelable {
- ctor public AudioProductStrategies();
- method public int describeContents();
- method @NonNull public android.media.AudioAttributes getAudioAttributesForLegacyStreamType(int);
- method @NonNull public android.media.AudioAttributes getAudioAttributesForProductStrategy(@NonNull android.media.audiopolicy.AudioProductStrategy);
- method @Nullable public android.media.audiopolicy.AudioProductStrategy getById(int);
- method public int getLegacyStreamTypeForAudioAttributes(@NonNull android.media.AudioAttributes);
- method @Nullable public android.media.audiopolicy.AudioProductStrategy getProductStrategyForAudioAttributes(@NonNull android.media.AudioAttributes);
- method public int getVolumeGroupIdForAttributes(@NonNull android.media.AudioAttributes);
- method public int getVolumeGroupIdForLegacyStreamType(int);
- method @NonNull public java.util.Iterator<android.media.audiopolicy.AudioProductStrategy> iterator();
- method public int size();
- method public void writeToParcel(@NonNull android.os.Parcel, int);
- field @NonNull public static final android.os.Parcelable.Creator<android.media.audiopolicy.AudioProductStrategies> CREATOR;
- }
-
public final class AudioProductStrategy implements android.os.Parcelable {
method public int describeContents();
method @NonNull public android.media.AudioAttributes getAudioAttributes();
method public int getId();
- method @NonNull public String name();
method public void writeToParcel(@NonNull android.os.Parcel, int);
field @NonNull public static final android.os.Parcelable.Creator<android.media.audiopolicy.AudioProductStrategy> CREATOR;
}
@@ -3711,16 +3691,6 @@
method @NonNull public String name();
method public void writeToParcel(@NonNull android.os.Parcel, int);
field public static final android.os.Parcelable.Creator<android.media.audiopolicy.AudioVolumeGroup> CREATOR;
- }
-
- public final class AudioVolumeGroups implements java.lang.Iterable<android.media.audiopolicy.AudioVolumeGroup> android.os.Parcelable {
- ctor public AudioVolumeGroups();
- method public int describeContents();
- method @Nullable public android.media.audiopolicy.AudioVolumeGroup getById(int);
- method @NonNull public java.util.Iterator<android.media.audiopolicy.AudioVolumeGroup> iterator();
- method public int size();
- method public void writeToParcel(@NonNull android.os.Parcel, int);
- field public static final android.os.Parcelable.Creator<android.media.audiopolicy.AudioVolumeGroups> CREATOR;
field public static final int DEFAULT_VOLUME_GROUP = -1; // 0xffffffff
}
@@ -6816,7 +6786,7 @@
public abstract class TextClassifierService extends android.app.Service {
ctor public TextClassifierService();
- method public static android.view.textclassifier.TextClassifier getDefaultTextClassifierImplementation(@NonNull android.content.Context);
+ method @NonNull public static android.view.textclassifier.TextClassifier getDefaultTextClassifierImplementation(@NonNull android.content.Context);
method @Deprecated public final android.view.textclassifier.TextClassifier getLocalTextClassifier();
method @Nullable public final android.os.IBinder onBind(android.content.Intent);
method @MainThread public abstract void onClassifyText(@Nullable android.view.textclassifier.TextClassificationSessionId, @NonNull android.view.textclassifier.TextClassification.Request, @NonNull android.os.CancellationSignal, @NonNull android.service.textclassifier.TextClassifierService.Callback<android.view.textclassifier.TextClassification>);
@@ -7234,6 +7204,7 @@
}
public static final class CarrierRestrictionRules.Builder {
+ ctor public 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>);
@@ -9488,22 +9459,6 @@
method public static void writeRaw(@NonNull byte[], int);
}
- public class StatsLogAtoms {
- field public static final int PERMISSION_GRANT_REQUEST_RESULT_REPORTED = 170; // 0xaa
- field public static final int PERMISSION_GRANT_REQUEST_RESULT_REPORTED__RESULT__AUTO_DENIED = 8; // 0x8
- field public static final int PERMISSION_GRANT_REQUEST_RESULT_REPORTED__RESULT__AUTO_GRANTED = 5; // 0x5
- field public static final int PERMISSION_GRANT_REQUEST_RESULT_REPORTED__RESULT__IGNORED = 1; // 0x1
- field public static final int PERMISSION_GRANT_REQUEST_RESULT_REPORTED__RESULT__IGNORED_POLICY_FIXED = 3; // 0x3
- field public static final int PERMISSION_GRANT_REQUEST_RESULT_REPORTED__RESULT__IGNORED_RESTRICTED_PERMISSION = 9; // 0x9
- field public static final int PERMISSION_GRANT_REQUEST_RESULT_REPORTED__RESULT__IGNORED_USER_FIXED = 2; // 0x2
- field public static final int PERMISSION_GRANT_REQUEST_RESULT_REPORTED__RESULT__USER_DENIED = 6; // 0x6
- field public static final int PERMISSION_GRANT_REQUEST_RESULT_REPORTED__RESULT__USER_DENIED_WITH_PREJUDICE = 7; // 0x7
- field public static final int PERMISSION_GRANT_REQUEST_RESULT_REPORTED__RESULT__USER_GRANTED = 4; // 0x4
- }
-
- @java.lang.annotation.Retention(java.lang.annotation.RetentionPolicy.SOURCE) @IntDef(prefix="PERMISSION_GRANT_REQUEST_RESULT_REPORTED__RESULT__", value={android.util.StatsLogAtoms.PERMISSION_GRANT_REQUEST_RESULT_REPORTED__RESULT__IGNORED, android.util.StatsLogAtoms.PERMISSION_GRANT_REQUEST_RESULT_REPORTED__RESULT__IGNORED_USER_FIXED, android.util.StatsLogAtoms.PERMISSION_GRANT_REQUEST_RESULT_REPORTED__RESULT__IGNORED_POLICY_FIXED, android.util.StatsLogAtoms.PERMISSION_GRANT_REQUEST_RESULT_REPORTED__RESULT__USER_GRANTED, android.util.StatsLogAtoms.PERMISSION_GRANT_REQUEST_RESULT_REPORTED__RESULT__AUTO_GRANTED, android.util.StatsLogAtoms.PERMISSION_GRANT_REQUEST_RESULT_REPORTED__RESULT__USER_DENIED, android.util.StatsLogAtoms.PERMISSION_GRANT_REQUEST_RESULT_REPORTED__RESULT__USER_DENIED_WITH_PREJUDICE, android.util.StatsLogAtoms.PERMISSION_GRANT_REQUEST_RESULT_REPORTED__RESULT__AUTO_DENIED}) public static @interface StatsLogAtoms.PermissionGrantRequestResultReported_Result {
- }
-
}
package android.view {
diff --git a/api/system-removed.txt b/api/system-removed.txt
index 162f212..5d74e17 100644
--- a/api/system-removed.txt
+++ b/api/system-removed.txt
@@ -60,6 +60,18 @@
}
+package android.hardware.hdmi {
+
+ public final class HdmiControlManager {
+ method @Deprecated public java.util.List<android.hardware.hdmi.HdmiDeviceInfo> getConnectedDevicesList();
+ method @Deprecated public boolean isRemoteDeviceConnected(@NonNull android.hardware.hdmi.HdmiDeviceInfo);
+ method @Deprecated public void powerOffRemoteDevice(@NonNull android.hardware.hdmi.HdmiDeviceInfo);
+ method @Deprecated public void powerOnRemoteDevice(android.hardware.hdmi.HdmiDeviceInfo);
+ method @Deprecated public void requestRemoteDeviceToBecomeActiveSource(@NonNull android.hardware.hdmi.HdmiDeviceInfo);
+ }
+
+}
+
package android.location {
public class LocationManager {
diff --git a/api/test-current.txt b/api/test-current.txt
index ac44dca..d37b45e 100644
--- a/api/test-current.txt
+++ b/api/test-current.txt
@@ -1074,6 +1074,19 @@
package android.media {
+ public final class AudioFocusInfo implements android.os.Parcelable {
+ method public int describeContents();
+ method @NonNull public android.media.AudioAttributes getAttributes();
+ method @NonNull public String getClientId();
+ method public int getClientUid();
+ method public int getFlags();
+ method public int getGainRequest();
+ method public int getLossReceived();
+ method @NonNull public String getPackageName();
+ method public void writeToParcel(android.os.Parcel, int);
+ field @NonNull public static final android.os.Parcelable.Creator<android.media.AudioFocusInfo> CREATOR;
+ }
+
public final class AudioFocusRequest {
method @Nullable public android.media.AudioManager.OnAudioFocusChangeListener getOnAudioFocusChangeListener();
}
@@ -1085,6 +1098,14 @@
method public static boolean isEncodingLinearPcm(int);
}
+ public class AudioManager {
+ method @RequiresPermission("android.permission.MODIFY_AUDIO_ROUTING") public int dispatchAudioFocusChange(@NonNull android.media.AudioFocusInfo, int, @NonNull android.media.audiopolicy.AudioPolicy);
+ method @RequiresPermission("android.permission.MODIFY_AUDIO_ROUTING") public int registerAudioPolicy(@NonNull android.media.audiopolicy.AudioPolicy);
+ method @RequiresPermission("android.permission.MODIFY_AUDIO_ROUTING") public void setFocusRequestResult(@NonNull android.media.AudioFocusInfo, int, @NonNull android.media.audiopolicy.AudioPolicy);
+ method @RequiresPermission("android.permission.MODIFY_AUDIO_ROUTING") public void unregisterAudioPolicy(@NonNull android.media.audiopolicy.AudioPolicy);
+ method @RequiresPermission("android.permission.MODIFY_AUDIO_ROUTING") public void unregisterAudioPolicyAsync(@NonNull android.media.audiopolicy.AudioPolicy);
+ }
+
public static final class AudioRecord.MetricsConstants {
field public static final String ATTRIBUTES = "android.media.audiorecord.attributes";
field public static final String CHANNEL_MASK = "android.media.audiorecord.channelMask";
@@ -1124,13 +1145,6 @@
method public android.media.BufferingParams.Builder setResumePlaybackMarkMs(int);
}
- public class FileDataSourceDesc extends android.media.DataSourceDesc {
- method public long getLength();
- method public long getOffset();
- method @NonNull public android.os.ParcelFileDescriptor getParcelFileDescriptor();
- field public static final long FD_LENGTH_UNKNOWN = 576460752303423487L; // 0x7ffffffffffffffL
- }
-
public static final class MediaCodecInfo.VideoCapabilities.PerformancePoint {
ctor public MediaCodecInfo.VideoCapabilities.PerformancePoint(int, int, int, int, @NonNull android.util.Size);
ctor public MediaCodecInfo.VideoCapabilities.PerformancePoint(@NonNull android.media.MediaCodecInfo.VideoCapabilities.PerformancePoint, @NonNull android.util.Size);
@@ -1139,28 +1153,11 @@
method public int getMaxMacroBlocks();
}
- public class MediaPlayer2 implements android.media.AudioRouting java.lang.AutoCloseable {
- 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 @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;
- method public void setDrmPropertyString(@NonNull android.media.DataSourceDesc, @NonNull String, @NonNull String) throws android.media.MediaPlayer2.NoDrmSchemeException;
- }
-
public final class PlaybackParams implements android.os.Parcelable {
method public int getAudioStretchMode();
method public android.media.PlaybackParams setAudioStretchMode(int);
}
- public class UriDataSourceDesc extends android.media.DataSourceDesc {
- 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 final class VolumeShaper.Configuration.Builder {
method @NonNull public android.media.VolumeShaper.Configuration.Builder setOptionFlags(int);
}
@@ -1202,6 +1199,91 @@
}
+package android.media.audiopolicy {
+
+ public class AudioMix {
+ method public int getMixState();
+ field public static final int MIX_STATE_DISABLED = -1; // 0xffffffff
+ field public static final int MIX_STATE_IDLE = 0; // 0x0
+ field public static final int MIX_STATE_MIXING = 1; // 0x1
+ field public static final int ROUTE_FLAG_LOOP_BACK = 2; // 0x2
+ field public static final int ROUTE_FLAG_RENDER = 1; // 0x1
+ }
+
+ public static class AudioMix.Builder {
+ ctor public AudioMix.Builder(android.media.audiopolicy.AudioMixingRule) throws java.lang.IllegalArgumentException;
+ method public android.media.audiopolicy.AudioMix build() throws java.lang.IllegalArgumentException;
+ method public android.media.audiopolicy.AudioMix.Builder setDevice(@NonNull android.media.AudioDeviceInfo) throws java.lang.IllegalArgumentException;
+ method public android.media.audiopolicy.AudioMix.Builder setFormat(android.media.AudioFormat) throws java.lang.IllegalArgumentException;
+ method public android.media.audiopolicy.AudioMix.Builder setRouteFlags(int) throws java.lang.IllegalArgumentException;
+ }
+
+ public class AudioMixingRule {
+ field public static final int RULE_MATCH_ATTRIBUTE_CAPTURE_PRESET = 2; // 0x2
+ field public static final int RULE_MATCH_ATTRIBUTE_USAGE = 1; // 0x1
+ field public static final int RULE_MATCH_UID = 4; // 0x4
+ }
+
+ public static class AudioMixingRule.Builder {
+ ctor public AudioMixingRule.Builder();
+ method public android.media.audiopolicy.AudioMixingRule.Builder addMixRule(int, Object) throws java.lang.IllegalArgumentException;
+ method public android.media.audiopolicy.AudioMixingRule.Builder addRule(android.media.AudioAttributes, int) throws java.lang.IllegalArgumentException;
+ method @NonNull public android.media.audiopolicy.AudioMixingRule.Builder allowPrivilegedPlaybackCapture(boolean);
+ method public android.media.audiopolicy.AudioMixingRule build();
+ method public android.media.audiopolicy.AudioMixingRule.Builder excludeMixRule(int, Object) throws java.lang.IllegalArgumentException;
+ method public android.media.audiopolicy.AudioMixingRule.Builder excludeRule(android.media.AudioAttributes, int) throws java.lang.IllegalArgumentException;
+ }
+
+ public class AudioPolicy {
+ method public int attachMixes(@NonNull java.util.List<android.media.audiopolicy.AudioMix>);
+ method public android.media.AudioRecord createAudioRecordSink(android.media.audiopolicy.AudioMix) throws java.lang.IllegalArgumentException;
+ method public android.media.AudioTrack createAudioTrackSource(android.media.audiopolicy.AudioMix) throws java.lang.IllegalArgumentException;
+ method public int detachMixes(@NonNull java.util.List<android.media.audiopolicy.AudioMix>);
+ method public int getFocusDuckingBehavior();
+ method public int getStatus();
+ method public int setFocusDuckingBehavior(int) throws java.lang.IllegalArgumentException, java.lang.IllegalStateException;
+ method public void setRegistration(String);
+ method public String toLogFriendlyString();
+ field public static final int FOCUS_POLICY_DUCKING_DEFAULT = 0; // 0x0
+ field public static final int FOCUS_POLICY_DUCKING_IN_APP = 0; // 0x0
+ field public static final int FOCUS_POLICY_DUCKING_IN_POLICY = 1; // 0x1
+ field public static final int POLICY_STATUS_REGISTERED = 2; // 0x2
+ field public static final int POLICY_STATUS_UNREGISTERED = 1; // 0x1
+ }
+
+ public abstract static class AudioPolicy.AudioPolicyFocusListener {
+ ctor public AudioPolicy.AudioPolicyFocusListener();
+ method public void onAudioFocusAbandon(android.media.AudioFocusInfo);
+ method public void onAudioFocusGrant(android.media.AudioFocusInfo, int);
+ method public void onAudioFocusLoss(android.media.AudioFocusInfo, boolean);
+ method public void onAudioFocusRequest(android.media.AudioFocusInfo, int);
+ }
+
+ public abstract static class AudioPolicy.AudioPolicyStatusListener {
+ ctor public AudioPolicy.AudioPolicyStatusListener();
+ method public void onMixStateUpdate(android.media.audiopolicy.AudioMix);
+ method public void onStatusChange();
+ }
+
+ public abstract static class AudioPolicy.AudioPolicyVolumeCallback {
+ ctor public AudioPolicy.AudioPolicyVolumeCallback();
+ method public void onVolumeAdjustment(int);
+ }
+
+ public static class AudioPolicy.Builder {
+ ctor public AudioPolicy.Builder(android.content.Context);
+ method @NonNull public android.media.audiopolicy.AudioPolicy.Builder addMix(@NonNull android.media.audiopolicy.AudioMix) throws java.lang.IllegalArgumentException;
+ method @NonNull public android.media.audiopolicy.AudioPolicy build();
+ method public void setAudioPolicyFocusListener(android.media.audiopolicy.AudioPolicy.AudioPolicyFocusListener);
+ method public void setAudioPolicyStatusListener(android.media.audiopolicy.AudioPolicy.AudioPolicyStatusListener);
+ method @NonNull public android.media.audiopolicy.AudioPolicy.Builder setAudioPolicyVolumeCallback(@NonNull android.media.audiopolicy.AudioPolicy.AudioPolicyVolumeCallback);
+ method @NonNull public android.media.audiopolicy.AudioPolicy.Builder setIsAudioFocusPolicy(boolean);
+ method @NonNull public android.media.audiopolicy.AudioPolicy.Builder setIsTestFocusPolicy(boolean);
+ method @NonNull public android.media.audiopolicy.AudioPolicy.Builder setLooper(@NonNull android.os.Looper) throws java.lang.IllegalArgumentException;
+ }
+
+}
+
package android.metrics {
public class LogMaker {
diff --git a/cmds/statsd/src/atoms.proto b/cmds/statsd/src/atoms.proto
index e577b6d..55d3fba 100644
--- a/cmds/statsd/src/atoms.proto
+++ b/cmds/statsd/src/atoms.proto
@@ -257,7 +257,8 @@
BluetoothSmpPairingEventReported bluetooth_smp_pairing_event_reported = 167;
ScreenTimeoutExtensionReported screen_timeout_extension_reported = 168;
ProcessStartTime process_start_time = 169;
- PermissionGrantRequestResultReported permission_grant_request_result_reported = 170;
+ PermissionGrantRequestResultReported permission_grant_request_result_reported =
+ 170 [(log_from_module) = "permissioncontroller"];
BluetoothSocketConnectionStateChanged bluetooth_socket_connection_state_changed = 171;
DeviceIdentifierAccessDenied device_identifier_access_denied = 172;
BubbleDeveloperErrorReported bubble_developer_error_reported = 173;
@@ -278,7 +279,7 @@
}
// Pulled events will start at field 10000.
- // Next: 10058
+ // Next: 10059
oneof pulled {
WifiBytesTransfer wifi_bytes_transfer = 10000;
WifiBytesTransferByFgBg wifi_bytes_transfer_by_fg_bg = 10001;
@@ -338,6 +339,7 @@
GpuStatsAppInfo gpu_stats_app_info = 10055;
SystemIonHeapSize system_ion_heap_size = 10056;
AppsOnExternalStorageInfo apps_on_external_storage_info = 10057;
+ FaceSettings face_settings = 10058;
}
// DO NOT USE field numbers above 100,000 in AOSP.
@@ -5583,6 +5585,7 @@
SWIPE_LEFT = 13;
SWIPE_RIGHT = 14;
STACK_EXPANDED = 15;
+ FLYOUT = 16;
}
optional Action action = 6;
@@ -5924,3 +5927,23 @@
// The name of the package that is installed on the external storage.
optional string package_name = 2;
}
+
+/**
+ * Logs the settings related to Face.
+ * Logged from:
+ * frameworks/base/services/core/java/com/android/server/stats
+ */
+message FaceSettings {
+ // Whether or not face unlock is allowed on Keyguard.
+ optional bool unlock_keyguard_enabled = 1;
+ // Whether or not face unlock dismisses the Keyguard.
+ optional bool unlock_dismisses_keyguard = 2;
+ // Whether or not face unlock requires attention.
+ optional bool unlock_attention_required = 3;
+ // Whether or not face unlock is allowed for apps (through BiometricPrompt).
+ optional bool unlock_app_enabled = 4;
+ // Whether or not face unlock always requires user confirmation.
+ optional bool unlock_always_require_confirmation = 5;
+ // Whether or not a diverse set of poses are required during enrollment.
+ optional bool unlock_diversity_required = 6;
+}
diff --git a/cmds/statsd/src/external/StatsPullerManager.cpp b/cmds/statsd/src/external/StatsPullerManager.cpp
index d6411a7..51839c4 100644
--- a/cmds/statsd/src/external/StatsPullerManager.cpp
+++ b/cmds/statsd/src/external/StatsPullerManager.cpp
@@ -254,6 +254,9 @@
// AppsOnExternalStorageInfo
{android::util::APPS_ON_EXTERNAL_STORAGE_INFO,
{.puller = new StatsCompanionServicePuller(android::util::APPS_ON_EXTERNAL_STORAGE_INFO)}},
+ // Face Settings
+ {android::util::FACE_SETTINGS,
+ {.puller = new StatsCompanionServicePuller(android::util::FACE_SETTINGS)}},
};
StatsPullerManager::StatsPullerManager() : mNextPullTimeNs(NO_ALARM_UPDATE) {
diff --git a/core/java/android/app/ActivityManager.java b/core/java/android/app/ActivityManager.java
index 4f388a4..cf4ef20 100644
--- a/core/java/android/app/ActivityManager.java
+++ b/core/java/android/app/ActivityManager.java
@@ -1838,17 +1838,17 @@
private final float mScale;
private final int mSystemUiVisibility;
private final boolean mIsTranslucent;
-
- // TODO(b/116112787) TaskSnapshot must also book keep the color space from hardware bitmap
- // when created.
- private final ColorSpace mColorSpace = ColorSpace.get(ColorSpace.Named.SRGB);
+ // Must be one of the named color spaces, otherwise, always use SRGB color space.
+ private final ColorSpace mColorSpace;
public TaskSnapshot(@NonNull ComponentName topActivityComponent, GraphicBuffer snapshot,
- int orientation, Rect contentInsets, boolean reducedResolution, float scale,
- boolean isRealSnapshot, int windowingMode, int systemUiVisibility,
- boolean isTranslucent) {
+ @NonNull ColorSpace colorSpace, int orientation, Rect contentInsets,
+ boolean reducedResolution, float scale, boolean isRealSnapshot, int windowingMode,
+ int systemUiVisibility, boolean isTranslucent) {
mTopActivityComponent = topActivityComponent;
mSnapshot = snapshot;
+ mColorSpace = colorSpace.getId() < 0
+ ? ColorSpace.get(ColorSpace.Named.SRGB) : colorSpace;
mOrientation = orientation;
mContentInsets = new Rect(contentInsets);
mReducedResolution = reducedResolution;
@@ -1862,6 +1862,10 @@
private TaskSnapshot(Parcel source) {
mTopActivityComponent = ComponentName.readFromParcel(source);
mSnapshot = source.readParcelable(null /* classLoader */);
+ int colorSpaceId = source.readInt();
+ mColorSpace = colorSpaceId >= 0
+ ? ColorSpace.get(ColorSpace.Named.values()[colorSpaceId])
+ : ColorSpace.get(ColorSpace.Named.SRGB);
mOrientation = source.readInt();
mContentInsets = source.readParcelable(null /* classLoader */);
mReducedResolution = source.readBoolean();
@@ -1968,6 +1972,7 @@
public void writeToParcel(Parcel dest, int flags) {
ComponentName.writeToParcel(mTopActivityComponent, dest);
dest.writeParcelable(mSnapshot, 0);
+ dest.writeInt(mColorSpace.getId());
dest.writeInt(mOrientation);
dest.writeParcelable(mContentInsets, 0);
dest.writeBoolean(mReducedResolution);
@@ -1985,6 +1990,7 @@
return "TaskSnapshot{"
+ " mTopActivityComponent=" + mTopActivityComponent.flattenToShortString()
+ " mSnapshot=" + mSnapshot + " (" + width + "x" + height + ")"
+ + " mColorSpace=" + mColorSpace.toString()
+ " mOrientation=" + mOrientation
+ " mContentInsets=" + mContentInsets.toShortString()
+ " mReducedResolution=" + mReducedResolution + " mScale=" + mScale
diff --git a/core/java/android/app/ActivityThread.java b/core/java/android/app/ActivityThread.java
index b6e5754..143361f 100644
--- a/core/java/android/app/ActivityThread.java
+++ b/core/java/android/app/ActivityThread.java
@@ -224,6 +224,12 @@
private static final boolean DEBUG_PROVIDER = false;
public static final boolean DEBUG_ORDER = false;
private static final long MIN_TIME_BETWEEN_GCS = 5*1000;
+ /**
+ * The delay to release the provider when it has no more references. It reduces the number of
+ * transactions for acquiring and releasing provider if the client accesses the provider
+ * frequently in a short time.
+ */
+ private static final long CONTENT_PROVIDER_RETAIN_TIME = 1000;
private static final int SQLITE_MEM_RELEASED_EVENT_LOG_TAG = 75003;
/** Type for IActivityManager.serviceDoneExecuting: anonymous operation */
@@ -6498,16 +6504,13 @@
if (!prc.removePending) {
// Schedule the actual remove asynchronously, since we don't know the context
// this will be called in.
- // TODO: it would be nice to post a delayed message, so
- // if we come back and need the same provider quickly
- // we will still have it available.
if (DEBUG_PROVIDER) {
Slog.v(TAG, "releaseProvider: Enqueueing pending removal - "
+ prc.holder.info.name);
}
prc.removePending = true;
Message msg = mH.obtainMessage(H.REMOVE_PROVIDER, prc);
- mH.sendMessage(msg);
+ mH.sendMessageDelayed(msg, CONTENT_PROVIDER_RETAIN_TIME);
} else {
Slog.w(TAG, "Duplicate remove pending of provider " + prc.holder.info.name);
}
diff --git a/core/java/android/app/AppOpsManager.java b/core/java/android/app/AppOpsManager.java
index 15982a7..6f92244 100644
--- a/core/java/android/app/AppOpsManager.java
+++ b/core/java/android/app/AppOpsManager.java
@@ -38,7 +38,6 @@
import android.os.Process;
import android.os.RemoteCallback;
import android.os.RemoteException;
-import android.os.SystemProperties;
import android.os.UserManager;
import android.util.ArrayMap;
import android.util.LongSparseArray;
@@ -5209,7 +5208,6 @@
* @hide
*/
public int noteProxyOpNoThrow(int op, String proxiedPackageName, int proxiedUid) {
- logOperationIfNeeded(op, mContext.getOpPackageName(), proxiedPackageName);
try {
return mService.noteProxyOperation(op, Process.myUid(), mContext.getOpPackageName(),
proxiedUid, proxiedPackageName);
@@ -5238,7 +5236,6 @@
*/
@UnsupportedAppUsage
public int noteOpNoThrow(int op, int uid, String packageName) {
- logOperationIfNeeded(op, packageName, null);
try {
return mService.noteOperation(op, uid, packageName);
} catch (RemoteException e) {
@@ -5346,7 +5343,6 @@
* @hide
*/
public int startOpNoThrow(int op, int uid, String packageName, boolean startIfModeDefault) {
- logOperationIfNeeded(op, packageName, null);
try {
return mService.startOperation(getToken(mService), op, uid, packageName,
startIfModeDefault);
@@ -5363,7 +5359,6 @@
* @hide
*/
public void finishOp(int op, int uid, String packageName) {
- logOperationIfNeeded(op, packageName, null);
try {
mService.finishOperation(getToken(mService), op, uid, packageName);
} catch (RemoteException e) {
@@ -5703,45 +5698,4 @@
return AppOpsManager.MODE_DEFAULT;
}
-
- private static void logOperationIfNeeded(int op, String callingPackage, String proxiedPackage) {
- // Check if debug logging propety is enabled.
- if (!SystemProperties.getBoolean(DEBUG_LOGGING_ENABLE_PROP, false)) {
- return;
- }
- // Check if this package should be logged.
- String packages = SystemProperties.get(DEBUG_LOGGING_PACKAGES_PROP, "");
- if (!"".equals(packages) && callingPackage != null) {
- boolean found = false;
- for (String pkg : packages.split(",")) {
- if (callingPackage.equals(pkg)) {
- found = true;
- break;
- }
- }
- if (!found) {
- return;
- }
- }
- String opStr = opToName(op);
- // Check if this app op should be logged
- String logOps = SystemProperties.get(DEBUG_LOGGING_OPS_PROP, "");
- if (!"".equals(logOps)) {
- boolean found = false;
- for (String logOp : logOps.split(",")) {
- if (opStr.equals(logOp)) {
- found = true;
- break;
- }
- }
- if (!found) {
- return;
- }
- }
-
- // Log a stack trace
- Exception here = new Exception("HERE!");
- android.util.Log.i(DEBUG_LOGGING_TAG, "Note operation package= " + callingPackage
- + " proxied= " + proxiedPackage + " op= " + opStr, here);
- }
}
diff --git a/core/java/android/app/IActivityManager.aidl b/core/java/android/app/IActivityManager.aidl
index 1785d2a..48ca716 100644
--- a/core/java/android/app/IActivityManager.aidl
+++ b/core/java/android/app/IActivityManager.aidl
@@ -223,7 +223,7 @@
void enterSafeMode();
void noteWakeupAlarm(in IIntentSender sender, in WorkSource workSource, int sourceUid,
in String sourcePkg, in String tag);
- void removeContentProvider(in IBinder connection, boolean stable);
+ oneway void removeContentProvider(in IBinder connection, boolean stable);
@UnsupportedAppUsage
void setRequestedOrientation(in IBinder token, int requestedOrientation);
void unbindFinished(in IBinder token, in Intent service, boolean doRebind);
diff --git a/core/java/android/app/StatsManager.java b/core/java/android/app/StatsManager.java
index 2e14d03..e6682d6 100644
--- a/core/java/android/app/StatsManager.java
+++ b/core/java/android/app/StatsManager.java
@@ -414,7 +414,6 @@
* Returns the experiments IDs registered with statsd, or an empty array if there aren't any.
*
* @throws StatsUnavailableException if unsuccessful due to failing to connect to stats service
- * @hide
*/
@RequiresPermission(allOf = {DUMP, PACKAGE_USAGE_STATS})
public long[] getRegisteredExperimentIds()
diff --git a/core/java/android/app/usage/UsageStatsManager.java b/core/java/android/app/usage/UsageStatsManager.java
index eb1ea90..f8dc20e 100644
--- a/core/java/android/app/usage/UsageStatsManager.java
+++ b/core/java/android/app/usage/UsageStatsManager.java
@@ -678,29 +678,6 @@
}
}
-
- /**
- * @deprecated use {@link #registerUsageSessionObserver(int, String[], Duration, Duration,
- * PendingIntent, PendingIntent)}.
- *
- * @hide
- */
- @Deprecated
- @SystemApi
- @RequiresPermission(android.Manifest.permission.OBSERVE_APP_USAGE)
- // STOPSHIP b/128455269: remove this method
- public void registerUsageSessionObserver(int sessionObserverId,
- @NonNull String[] observedEntities, long timeLimit, @NonNull TimeUnit timeUnit,
- long sessionThresholdTime, @NonNull TimeUnit sessionThresholdTimeUnit,
- @NonNull PendingIntent limitReachedCallbackIntent,
- @Nullable PendingIntent sessionEndCallbackIntent) {
- final Duration timeLimitDuration = Duration.ofMillis(timeUnit.toMillis(timeLimit));
- final Duration sessionThresholdDuration =
- Duration.ofMillis(sessionThresholdTimeUnit.toMillis(sessionThresholdTime));
- registerUsageSessionObserver(sessionObserverId, observedEntities, timeLimitDuration,
- sessionThresholdDuration, limitReachedCallbackIntent, sessionEndCallbackIntent);
- }
-
/**
* Register a usage session observer that receives a callback on the provided {@code
* limitReachedCallbackIntent} when the sum of usages of apps and tokens in the {@code
diff --git a/core/java/android/bluetooth/le/ScanRecord.java b/core/java/android/bluetooth/le/ScanRecord.java
index 2174255..30868bf 100644
--- a/core/java/android/bluetooth/le/ScanRecord.java
+++ b/core/java/android/bluetooth/le/ScanRecord.java
@@ -16,6 +16,7 @@
package android.bluetooth.le;
+import android.annotation.NonNull;
import android.annotation.Nullable;
import android.annotation.UnsupportedAppUsage;
import android.bluetooth.BluetoothUuid;
@@ -97,7 +98,7 @@
* Returns a list of service solicitation UUIDs within the advertisement that are used to
* identify the Bluetooth GATT services.
*/
- @Nullable
+ @NonNull
public List<ParcelUuid> getServiceSolicitationUuids() {
return mServiceSolicitationUuids;
}
@@ -297,9 +298,6 @@
if (serviceUuids.isEmpty()) {
serviceUuids = null;
}
- if (serviceSolicitationUuids.isEmpty()) {
- serviceSolicitationUuids = null;
- }
return new ScanRecord(serviceUuids, serviceSolicitationUuids, manufacturerData,
serviceData, advertiseFlag, txPowerLevel, localName, scanRecord);
} catch (Exception e) {
diff --git a/core/java/android/content/Intent.java b/core/java/android/content/Intent.java
index 8628d32..e66cd31 100644
--- a/core/java/android/content/Intent.java
+++ b/core/java/android/content/Intent.java
@@ -643,6 +643,7 @@
private static final String ATTR_CATEGORY = "category";
private static final String TAG_EXTRA = "extra";
private static final String ATTR_TYPE = "type";
+ private static final String ATTR_IDENTIFIER = "ident";
private static final String ATTR_COMPONENT = "component";
private static final String ATTR_DATA = "data";
private static final String ATTR_FLAGS = "flags";
@@ -6314,6 +6315,7 @@
private String mAction;
private Uri mData;
private String mType;
+ private String mIdentifier;
private String mPackage;
private ComponentName mComponent;
private int mFlags;
@@ -6359,6 +6361,7 @@
this.mAction = o.mAction;
this.mData = o.mData;
this.mType = o.mType;
+ this.mIdentifier = o.mIdentifier;
this.mPackage = o.mPackage;
this.mComponent = o.mComponent;
@@ -6678,6 +6681,11 @@
intent.mType = value;
}
+ // identifier
+ else if (uri.startsWith("identifier=", i)) {
+ intent.mIdentifier = value;
+ }
+
// launch flags
else if (uri.startsWith("launchFlags=", i)) {
intent.mFlags = Integer.decode(value).intValue();
@@ -7017,6 +7025,12 @@
hasIntentInfo = true;
}
break;
+ case "-i":
+ intent.setIdentifier(cmd.getNextArgRequired());
+ if (intent == baseIntent) {
+ hasIntentInfo = true;
+ }
+ break;
case "-c":
intent.addCategory(cmd.getNextArgRequired());
if (intent == baseIntent) {
@@ -7375,7 +7389,7 @@
public static void printIntentArgsHelp(PrintWriter pw, String prefix) {
final String[] lines = new String[] {
"<INTENT> specifications include these flags and arguments:",
- " [-a <ACTION>] [-d <DATA_URI>] [-t <MIME_TYPE>]",
+ " [-a <ACTION>] [-d <DATA_URI>] [-t <MIME_TYPE>] [-i <IDENTIFIER>]",
" [-c <CATEGORY> [-c <CATEGORY>] ...]",
" [-n <COMPONENT_NAME>]",
" [-e|--es <EXTRA_KEY> <EXTRA_STRING_VALUE> ...]",
@@ -7557,6 +7571,18 @@
}
/**
+ * Retrieve the identifier for this Intent. If non-null, this is an arbitrary identity
+ * of the Intent to distinguish it from other Intents.
+ *
+ * @return The identifier of this intent or null if none is specified.
+ *
+ * @see #setIdentifier
+ */
+ public @Nullable String getIdentifier() {
+ return mIdentifier;
+ }
+
+ /**
* Check if a category exists in the intent.
*
* @param category The category to check.
@@ -8576,6 +8602,28 @@
}
/**
+ * Set an identifier for this Intent. If set, this provides a unique identity for this Intent,
+ * allowing it to be unique from other Intents that would otherwise look the same. In
+ * particular, this will be used by {@link #filterEquals(Intent)} to determine if two
+ * Intents are the same as with other fields like {@link #setAction}. However, unlike those
+ * fields, the identifier is <em>never</em> used for matching against an {@link IntentFilter};
+ * it is as if the identifier has not been set on the Intent.
+ *
+ * @param identifier The identifier for this Intent. The contents of the string have no
+ * meaning to the system, except whether they are exactly the same as
+ * another identifier.
+ *
+ * @return Returns the same Intent object, for chaining multiple calls
+ * into a single statement.
+ *
+ * @see #getIdentifier
+ */
+ public @NonNull Intent setIdentifier(@Nullable String identifier) {
+ mIdentifier = identifier;
+ return this;
+ }
+
+ /**
* Add a new category to the intent. Categories provide additional detail
* about the action the intent performs. When resolving an intent, only
* activities that provide <em>all</em> of the requested categories will be
@@ -9693,6 +9741,12 @@
public static final int FILL_IN_CLIP_DATA = 1<<7;
/**
+ * Use with {@link #fillIn} to allow the current identifier value to be
+ * overwritten, even if it is already set.
+ */
+ public static final int FILL_IN_IDENTIFIER = 1<<8;
+
+ /**
* Copy the contents of <var>other</var> in to this object, but only
* where fields are not defined by this object. For purposes of a field
* being defined, the following pieces of data in the Intent are
@@ -9702,6 +9756,7 @@
* <li> action, as set by {@link #setAction}.
* <li> data Uri and MIME type, as set by {@link #setData(Uri)},
* {@link #setType(String)}, or {@link #setDataAndType(Uri, String)}.
+ * <li> identifier, as set by {@link #setIdentifier}.
* <li> categories, as set by {@link #addCategory}.
* <li> package, as set by {@link #setPackage}.
* <li> component, as set by {@link #setComponent(ComponentName)} or
@@ -9713,8 +9768,8 @@
* </ul>
*
* <p>In addition, you can use the {@link #FILL_IN_ACTION},
- * {@link #FILL_IN_DATA}, {@link #FILL_IN_CATEGORIES}, {@link #FILL_IN_PACKAGE},
- * {@link #FILL_IN_COMPONENT}, {@link #FILL_IN_SOURCE_BOUNDS},
+ * {@link #FILL_IN_DATA}, {@link #FILL_IN_IDENTIFIER}, {@link #FILL_IN_CATEGORIES},
+ * {@link #FILL_IN_PACKAGE}, {@link #FILL_IN_COMPONENT}, {@link #FILL_IN_SOURCE_BOUNDS},
* {@link #FILL_IN_SELECTOR}, and {@link #FILL_IN_CLIP_DATA} to override
* the restriction where the corresponding field will not be replaced if
* it is already set.
@@ -9758,6 +9813,11 @@
changes |= FILL_IN_DATA;
mayHaveCopiedUris = true;
}
+ if (other.mIdentifier != null
+ && (mIdentifier == null || (flags&FILL_IN_IDENTIFIER) != 0)) {
+ mIdentifier = other.mIdentifier;
+ changes |= FILL_IN_IDENTIFIER;
+ }
if (other.mCategories != null
&& (mCategories == null || (flags&FILL_IN_CATEGORIES) != 0)) {
if (other.mCategories != null) {
@@ -9871,9 +9931,11 @@
/**
* Determine if two intents are the same for the purposes of intent
- * resolution (filtering). That is, if their action, data, type,
+ * resolution (filtering). That is, if their action, data, type, identity,
* class, and categories are the same. This does <em>not</em> compare
- * any extra data included in the intents.
+ * any extra data included in the intents. Note that technically when actually
+ * matching against an {@link IntentFilter} the identifier is ignored, while here
+ * it is directly compared for equality like the other fields.
*
* @param other The other Intent to compare against.
*
@@ -9887,6 +9949,7 @@
if (!Objects.equals(this.mAction, other.mAction)) return false;
if (!Objects.equals(this.mData, other.mData)) return false;
if (!Objects.equals(this.mType, other.mType)) return false;
+ if (!Objects.equals(this.mIdentifier, other.mIdentifier)) return false;
if (!Objects.equals(this.mPackage, other.mPackage)) return false;
if (!Objects.equals(this.mComponent, other.mComponent)) return false;
if (!Objects.equals(this.mCategories, other.mCategories)) return false;
@@ -9913,6 +9976,9 @@
if (mType != null) {
code += mType.hashCode();
}
+ if (mIdentifier != null) {
+ code += mIdentifier.hashCode();
+ }
if (mPackage != null) {
code += mPackage.hashCode();
}
@@ -10005,6 +10071,13 @@
first = false;
b.append("typ=").append(mType);
}
+ if (mIdentifier != null) {
+ if (!first) {
+ b.append(' ');
+ }
+ first = false;
+ b.append("id=").append(mIdentifier);
+ }
if (mFlags != 0) {
if (!first) {
b.append(' ');
@@ -10276,6 +10349,9 @@
if (mType != null) {
uri.append("type=").append(Uri.encode(mType, "/")).append(';');
}
+ if (mIdentifier != null) {
+ uri.append("identifier=").append(Uri.encode(mIdentifier, "/")).append(';');
+ }
if (mFlags != 0) {
uri.append("launchFlags=0x").append(Integer.toHexString(mFlags)).append(';');
}
@@ -10326,6 +10402,7 @@
out.writeString(mAction);
Uri.writeToParcel(out, mData);
out.writeString(mType);
+ out.writeString(mIdentifier);
out.writeInt(mFlags);
out.writeString(mPackage);
ComponentName.writeToParcel(mComponent, out);
@@ -10383,6 +10460,7 @@
setAction(in.readString());
mData = Uri.CREATOR.createFromParcel(in);
mType = in.readString();
+ mIdentifier = in.readString();
mFlags = in.readInt();
mPackage = in.readString();
mComponent = ComponentName.readFromParcel(in);
@@ -10445,6 +10523,8 @@
String mimeType = sa.getString(com.android.internal.R.styleable.Intent_mimeType);
intent.setDataAndType(data != null ? Uri.parse(data) : null, mimeType);
+ intent.setIdentifier(sa.getString(com.android.internal.R.styleable.Intent_identifier));
+
String packageName = sa.getString(com.android.internal.R.styleable.Intent_targetPackage);
String className = sa.getString(com.android.internal.R.styleable.Intent_targetClass);
if (packageName != null && className != null) {
@@ -10499,6 +10579,9 @@
if (mType != null) {
out.attribute(null, ATTR_TYPE, mType);
}
+ if (mIdentifier != null) {
+ out.attribute(null, ATTR_IDENTIFIER, mIdentifier);
+ }
if (mComponent != null) {
out.attribute(null, ATTR_COMPONENT, mComponent.flattenToShortString());
}
@@ -10529,6 +10612,8 @@
intent.setData(Uri.parse(attrValue));
} else if (ATTR_TYPE.equals(attrName)) {
intent.setType(attrValue);
+ } else if (ATTR_IDENTIFIER.equals(attrName)) {
+ intent.setIdentifier(attrValue);
} else if (ATTR_COMPONENT.equals(attrName)) {
intent.setComponent(ComponentName.unflattenFromString(attrValue));
} else if (ATTR_FLAGS.equals(attrName)) {
diff --git a/core/java/android/content/pm/PackageInstaller.java b/core/java/android/content/pm/PackageInstaller.java
index 6c72a9a..6ce6828 100644
--- a/core/java/android/content/pm/PackageInstaller.java
+++ b/core/java/android/content/pm/PackageInstaller.java
@@ -841,13 +841,12 @@
* installation (for example, the same split name), the APK in this session
* will replace the existing APK.
* <p>
- * In such a case that multiple packages need to be commited simultaneously,
+ * In such a case that multiple packages need to be committed simultaneously,
* multiple sessions can be referenced by a single multi-package session.
* This session is created with no package name and calling
- * {@link SessionParams#setMultiPackage()} with {@code true}. The
- * individual session IDs can be added with {@link #addChildSessionId(int)}
- * and commit of the multi-package session will result in all child sessions
- * being committed atomically.
+ * {@link SessionParams#setMultiPackage()}. The individual session IDs can be
+ * added with {@link #addChildSessionId(int)} and commit of the multi-package
+ * session will result in all child sessions being committed atomically.
*/
public static class Session implements Closeable {
/** {@hide} */
diff --git a/core/java/android/hardware/camera2/CameraMetadata.java b/core/java/android/hardware/camera2/CameraMetadata.java
index 9e0ee58..d3575c0 100644
--- a/core/java/android/hardware/camera2/CameraMetadata.java
+++ b/core/java/android/hardware/camera2/CameraMetadata.java
@@ -1252,6 +1252,7 @@
* fire the flash for flash power metering during precapture, and then fire the flash
* for the final capture, if a flash is available on the device and the AE mode is set to
* enable the flash.</p>
+ * <p>Devices that initially shipped with Android version {@link android.os.Build.VERSION_CODES#Q Q} or newer will not include any LEGACY-level devices.</p>
*
* @see CaptureRequest#CONTROL_AE_PRECAPTURE_TRIGGER
* @see CameraCharacteristics#REQUEST_AVAILABLE_CAPABILITIES
diff --git a/core/java/android/hardware/face/FaceManager.java b/core/java/android/hardware/face/FaceManager.java
index 6035f40..7349f0c 100644
--- a/core/java/android/hardware/face/FaceManager.java
+++ b/core/java/android/hardware/face/FaceManager.java
@@ -93,8 +93,8 @@
}
@Override // binder call
- public void onAuthenticationSucceeded(long deviceId, Face face) {
- mHandler.obtainMessage(MSG_AUTHENTICATION_SUCCEEDED, face).sendToTarget();
+ public void onAuthenticationSucceeded(long deviceId, Face face, int userId) {
+ mHandler.obtainMessage(MSG_AUTHENTICATION_SUCCEEDED, userId, 0, face).sendToTarget();
}
@Override // binder call
@@ -168,6 +168,44 @@
@RequiresPermission(USE_BIOMETRIC_INTERNAL)
public void authenticate(@Nullable CryptoObject crypto, @Nullable CancellationSignal cancel,
int flags, @NonNull AuthenticationCallback callback, @Nullable Handler handler) {
+ authenticate(crypto, cancel, flags, callback, handler, mContext.getUserId());
+ }
+
+ /**
+ * Use the provided handler thread for events.
+ */
+ private void useHandler(Handler handler) {
+ if (handler != null) {
+ mHandler = new MyHandler(handler.getLooper());
+ } else if (mHandler.getLooper() != mContext.getMainLooper()) {
+ mHandler = new MyHandler(mContext.getMainLooper());
+ }
+ }
+
+ /**
+ * Request authentication of a crypto object. This call operates the face recognition hardware
+ * and starts capturing images. It terminates when
+ * {@link AuthenticationCallback#onAuthenticationError(int, CharSequence)} or
+ * {@link AuthenticationCallback#onAuthenticationSucceeded(AuthenticationResult)} is called, at
+ * which point the object is no longer valid. The operation can be canceled by using the
+ * provided cancel object.
+ *
+ * @param crypto object associated with the call or null if none required.
+ * @param cancel an object that can be used to cancel authentication
+ * @param flags optional flags; should be 0
+ * @param callback an object to receive authentication events
+ * @param handler an optional handler to handle callback events
+ * @param userId userId to authenticate for
+ * @throws IllegalArgumentException if the crypto operation is not supported or is not backed
+ * by
+ * <a href="{@docRoot}training/articles/keystore.html">Android
+ * Keystore facility</a>.
+ * @throws IllegalStateException if the crypto primitive is not initialized.
+ * @hide
+ */
+ public void authenticate(@Nullable CryptoObject crypto, @Nullable CancellationSignal cancel,
+ int flags, @NonNull AuthenticationCallback callback, @Nullable Handler handler,
+ int userId) {
if (callback == null) {
throw new IllegalArgumentException("Must supply an authentication callback");
}
@@ -187,7 +225,7 @@
mAuthenticationCallback = callback;
mCryptoObject = crypto;
long sessionId = crypto != null ? crypto.getOpId() : 0;
- mService.authenticate(mToken, sessionId, mContext.getUserId(), mServiceReceiver,
+ mService.authenticate(mToken, sessionId, userId, mServiceReceiver,
flags, mContext.getOpPackageName());
} catch (RemoteException e) {
Log.w(TAG, "Remote exception while authenticating: ", e);
@@ -196,24 +234,13 @@
// try again later.
callback.onAuthenticationError(FACE_ERROR_HW_UNAVAILABLE,
getErrorString(mContext, FACE_ERROR_HW_UNAVAILABLE,
- 0 /* vendorCode */));
+ 0 /* vendorCode */));
}
}
}
}
/**
- * Use the provided handler thread for events.
- */
- private void useHandler(Handler handler) {
- if (handler != null) {
- mHandler = new MyHandler(handler.getLooper());
- } else if (mHandler.getLooper() != mContext.getMainLooper()) {
- mHandler = new MyHandler(mContext.getMainLooper());
- }
- }
-
- /**
* Request face authentication enrollment. This call operates the face authentication hardware
* and starts capturing images. Progress will be indicated by callbacks to the
* {@link EnrollmentCallback} object. It terminates when
diff --git a/core/java/android/hardware/face/IFaceServiceReceiver.aidl b/core/java/android/hardware/face/IFaceServiceReceiver.aidl
index 2176902..10f9c43 100644
--- a/core/java/android/hardware/face/IFaceServiceReceiver.aidl
+++ b/core/java/android/hardware/face/IFaceServiceReceiver.aidl
@@ -24,7 +24,7 @@
oneway interface IFaceServiceReceiver {
void onEnrollResult(long deviceId, int faceId, int remaining);
void onAcquired(long deviceId, int acquiredInfo, int vendorCode);
- void onAuthenticationSucceeded(long deviceId, in Face face);
+ void onAuthenticationSucceeded(long deviceId, in Face face, int userId);
void onAuthenticationFailed(long deviceId);
void onError(long deviceId, int error, int vendorCode);
void onRemoved(long deviceId, int faceId, int remaining);
diff --git a/core/java/android/hardware/hdmi/HdmiControlManager.java b/core/java/android/hardware/hdmi/HdmiControlManager.java
index aff385d..d05ba79 100644
--- a/core/java/android/hardware/hdmi/HdmiControlManager.java
+++ b/core/java/android/hardware/hdmi/HdmiControlManager.java
@@ -428,17 +428,33 @@
}
/**
- * Get a snapshot of the real-time status of the remote devices.
+ * Get a snapshot of the real-time status of the devices on the CEC bus.
*
- * <p>This only applies to devices with multiple HDMI inputs.
+ * <p>This only applies to devices with switch functionality, which are devices with one
+ * or more than one HDMI inputs.
*
- * @return a list of {@link HdmiDeviceInfo} of the connected CEC devices. An empty
- * list will be returned if there is none.
+ * @return a list of {@link HdmiDeviceInfo} of the connected CEC devices on the CEC bus. An
+ * empty list will be returned if there is none.
*
* @hide
*/
+ @NonNull
@SystemApi
- @Nullable
+ public List<HdmiDeviceInfo> getConnectedDevices() {
+ try {
+ return mService.getDeviceList();
+ } catch (RemoteException e) {
+ throw e.rethrowFromSystemServer();
+ }
+ }
+
+ /**
+ * @removed
+ * @hide
+ * @deprecated Please use {@link #getConnectedDevices()} instead.
+ */
+ @Deprecated
+ @SystemApi
public List<HdmiDeviceInfo> getConnectedDevicesList() {
try {
return mService.getDeviceList();
@@ -448,7 +464,8 @@
}
/**
- * Power off the target device by sending CEC commands.
+ * Power off the target device by sending CEC commands. Note that this device can't be the
+ * current device itself.
*
* <p>The target device info can be obtained by calling {@link #getConnectedDevicesList()}.
*
@@ -457,6 +474,23 @@
* @hide
*/
@SystemApi
+ public void powerOffDevice(@NonNull HdmiDeviceInfo deviceInfo) {
+ Preconditions.checkNotNull(deviceInfo);
+ try {
+ mService.powerOffRemoteDevice(
+ deviceInfo.getLogicalAddress(), deviceInfo.getDevicePowerStatus());
+ } catch (RemoteException e) {
+ throw e.rethrowFromSystemServer();
+ }
+ }
+
+ /**
+ * @removed
+ * @hide
+ * @deprecated Please use {@link #powerOffDevice(deviceInfo)} instead.
+ */
+ @Deprecated
+ @SystemApi
public void powerOffRemoteDevice(@NonNull HdmiDeviceInfo deviceInfo) {
Preconditions.checkNotNull(deviceInfo);
try {
@@ -468,7 +502,8 @@
}
/**
- * Power on the target device by sending CEC commands.
+ * Power on the target device by sending CEC commands. Note that this device can't be the
+ * current device itself.
*
* <p>The target device info can be obtained by calling {@link #getConnectedDevicesList()}.
*
@@ -476,6 +511,23 @@
*
* @hide
*/
+ public void powerOnDevice(HdmiDeviceInfo deviceInfo) {
+ Preconditions.checkNotNull(deviceInfo);
+ try {
+ mService.powerOnRemoteDevice(
+ deviceInfo.getLogicalAddress(), deviceInfo.getDevicePowerStatus());
+ } catch (RemoteException e) {
+ throw e.rethrowFromSystemServer();
+ }
+ }
+
+ /**
+ * @removed
+ * @hide
+ * @deprecated Please use {@link #powerOnDevice(deviceInfo)} instead.
+ */
+ @Deprecated
+ @SystemApi
public void powerOnRemoteDevice(HdmiDeviceInfo deviceInfo) {
Preconditions.checkNotNull(deviceInfo);
try {
@@ -487,15 +539,35 @@
}
/**
- * Request the target device to be the new Active Source by sending CEC commands.
+ * Request the target device to be the new Active Source by sending CEC commands. Note that
+ * this device can't be the current device itself.
*
* <p>The target device info can be obtained by calling {@link #getConnectedDevicesList()}.
*
+ * <p>If the target device responds to the command, the users should see the target device
+ * streaming on their TVs.
+ *
* @param deviceInfo HdmiDeviceInfo of the target device
*
* @hide
*/
@SystemApi
+ public void setActiveSource(@NonNull HdmiDeviceInfo deviceInfo) {
+ Preconditions.checkNotNull(deviceInfo);
+ try {
+ mService.askRemoteDeviceToBecomeActiveSource(deviceInfo.getPhysicalAddress());
+ } catch (RemoteException e) {
+ throw e.rethrowFromSystemServer();
+ }
+ }
+
+ /**
+ * @removed
+ * @hide
+ * @deprecated Please use {@link #setActiveSource(deviceInfo)} instead.
+ */
+ @Deprecated
+ @SystemApi
public void requestRemoteDeviceToBecomeActiveSource(@NonNull HdmiDeviceInfo deviceInfo) {
Preconditions.checkNotNull(deviceInfo);
try {
@@ -556,7 +628,7 @@
}
/**
- * Check if the target remote device is connected to the current device.
+ * Check if the target device is connected to the current device.
*
* <p>The API also returns true if the current device is the target.
*
@@ -567,6 +639,27 @@
* @hide
*/
@SystemApi
+ public boolean isDeviceConnected(@NonNull HdmiDeviceInfo targetDevice) {
+ Preconditions.checkNotNull(targetDevice);
+ mPhysicalAddress = getPhysicalAddress();
+ if (mPhysicalAddress == INVALID_PHYSICAL_ADDRESS) {
+ return false;
+ }
+ int targetPhysicalAddress = targetDevice.getPhysicalAddress();
+ if (targetPhysicalAddress == INVALID_PHYSICAL_ADDRESS) {
+ return false;
+ }
+ return HdmiUtils.getLocalPortFromPhysicalAddress(targetPhysicalAddress, mPhysicalAddress)
+ != HdmiUtils.TARGET_NOT_UNDER_LOCAL_DEVICE;
+ }
+
+ /**
+ * @removed
+ * @hide
+ * @deprecated Please use {@link #isDeviceConnected(targetDevice)} instead.
+ */
+ @Deprecated
+ @SystemApi
public boolean isRemoteDeviceConnected(@NonNull HdmiDeviceInfo targetDevice) {
Preconditions.checkNotNull(targetDevice);
mPhysicalAddress = getPhysicalAddress();
diff --git a/core/java/android/net/DnsResolver.java b/core/java/android/net/DnsResolver.java
index 06c32c6..b6c4fe2 100644
--- a/core/java/android/net/DnsResolver.java
+++ b/core/java/android/net/DnsResolver.java
@@ -93,6 +93,23 @@
public static final int FLAG_NO_CACHE_STORE = 1 << 1;
public static final int FLAG_NO_CACHE_LOOKUP = 1 << 2;
+ @IntDef(prefix = { "ERROR_" }, value = {
+ ERROR_PARSE,
+ ERROR_SYSTEM
+ })
+ @Retention(RetentionPolicy.SOURCE)
+ @interface DnsError {}
+ /**
+ * Indicates that there was an error parsing the response the query.
+ * The cause of this error is available via getCause() and is a ParseException.
+ */
+ public static final int ERROR_PARSE = 0;
+ /**
+ * Indicates that there was an error sending the query.
+ * The cause of this error is available via getCause() and is an ErrnoException.
+ */
+ public static final int ERROR_SYSTEM = 1;
+
private static final int NETID_UNSET = 0;
private static final DnsResolver sInstance = new DnsResolver();
@@ -107,97 +124,57 @@
private DnsResolver() {}
/**
- * Answer parser for parsing raw answers
+ * Base interface for answer callbacks
*
- * @param <T> The type of the parsed answer
+ * @param <T> The type of the answer
*/
- public interface AnswerParser<T> {
- /**
- * Creates a <T> answer by parsing the given raw answer.
- *
- * @param rawAnswer the raw answer to be parsed
- * @return a parsed <T> answer
- * @throws ParseException if parsing failed
- */
- @NonNull T parse(@NonNull byte[] rawAnswer) throws ParseException;
- }
-
- /**
- * Base class for answer callbacks
- *
- * @param <T> The type of the parsed answer
- */
- public abstract static class AnswerCallback<T> {
- /** @hide */
- public final AnswerParser<T> parser;
-
- public AnswerCallback(@NonNull AnswerParser<T> parser) {
- this.parser = parser;
- };
-
+ public interface Callback<T> {
/**
* Success response to
- * {@link android.net.DnsResolver#query query()}.
+ * {@link android.net.DnsResolver#query query()} or
+ * {@link android.net.DnsResolver#rawQuery rawQuery()}.
*
* Invoked when the answer to a query was successfully parsed.
*
- * @param answer parsed answer to the query.
+ * @param answer <T> answer to the query.
+ * @param rcode The response code in the DNS response.
*
* {@see android.net.DnsResolver#query query()}
*/
- public abstract void onAnswer(@NonNull T answer);
-
+ void onAnswer(@NonNull T answer, int rcode);
/**
* Error response to
- * {@link android.net.DnsResolver#query query()}.
+ * {@link android.net.DnsResolver#query query()} or
+ * {@link android.net.DnsResolver#rawQuery rawQuery()}.
*
* Invoked when there is no valid answer to
* {@link android.net.DnsResolver#query query()}
+ * {@link android.net.DnsResolver#rawQuery rawQuery()}.
*
- * @param exception a {@link ParseException} object with additional
+ * @param error a {@link DnsException} object with additional
* detail regarding the failure
*/
- public abstract void onParseException(@NonNull ParseException exception);
-
- /**
- * Error response to
- * {@link android.net.DnsResolver#query query()}.
- *
- * Invoked if an error happens when
- * issuing the DNS query or receiving the result.
- * {@link android.net.DnsResolver#query query()}
- *
- * @param exception an {@link ErrnoException} object with additional detail
- * regarding the failure
- */
- public abstract void onQueryException(@NonNull ErrnoException exception);
+ void onError(@NonNull DnsException error);
}
/**
- * Callback for receiving raw answers
+ * Class to represent DNS error
*/
- public abstract static class RawAnswerCallback extends AnswerCallback<byte[]> {
- public RawAnswerCallback() {
- super(rawAnswer -> rawAnswer);
- }
- }
+ public static class DnsException extends Exception {
+ /**
+ * DNS error code as one of the ERROR_* constants
+ */
+ @DnsError public final int code;
- /**
- * Callback for receiving parsed {@link InetAddress} answers
- *
- * Note that if the answer does not contain any IP addresses,
- * onAnswer will be called with an empty list.
- */
- public abstract static class InetAddressAnswerCallback
- extends AnswerCallback<List<InetAddress>> {
- public InetAddressAnswerCallback() {
- super(rawAnswer -> new DnsAddressAnswer(rawAnswer).getAddresses());
+ DnsException(@DnsError int code, @Nullable Throwable cause) {
+ super(cause);
+ this.code = code;
}
}
/**
* Send a raw DNS query.
- * The answer will be provided asynchronously through the provided {@link AnswerCallback}.
+ * The answer will be provided asynchronously through the provided {@link Callback}.
*
* @param network {@link Network} specifying which network to query on.
* {@code null} for query on default network.
@@ -206,13 +183,13 @@
* @param executor The {@link Executor} that the callback should be executed on.
* @param cancellationSignal used by the caller to signal if the query should be
* cancelled. May be {@code null}.
- * @param callback an {@link AnswerCallback} which will be called to notify the caller
+ * @param callback a {@link Callback} which will be called to notify the caller
* of the result of dns query.
*/
- public <T> void query(@Nullable Network network, @NonNull byte[] query, @QueryFlag int flags,
+ public void rawQuery(@Nullable Network network, @NonNull byte[] query, @QueryFlag int flags,
@NonNull @CallbackExecutor Executor executor,
@Nullable CancellationSignal cancellationSignal,
- @NonNull AnswerCallback<T> callback) {
+ @NonNull Callback<? super byte[]> callback) {
if (cancellationSignal != null && cancellationSignal.isCanceled()) {
return;
}
@@ -222,9 +199,7 @@
queryfd = resNetworkSend((network != null
? network.netId : NETID_UNSET), query, query.length, flags);
} catch (ErrnoException e) {
- executor.execute(() -> {
- callback.onQueryException(e);
- });
+ executor.execute(() -> callback.onError(new DnsException(ERROR_SYSTEM, e)));
return;
}
@@ -237,7 +212,7 @@
/**
* Send a DNS query with the specified name, class and query type.
- * The answer will be provided asynchronously through the provided {@link AnswerCallback}.
+ * The answer will be provided asynchronously through the provided {@link Callback}.
*
* @param network {@link Network} specifying which network to query on.
* {@code null} for query on default network.
@@ -248,14 +223,14 @@
* @param executor The {@link Executor} that the callback should be executed on.
* @param cancellationSignal used by the caller to signal if the query should be
* cancelled. May be {@code null}.
- * @param callback an {@link AnswerCallback} which will be called to notify the caller
+ * @param callback a {@link Callback} which will be called to notify the caller
* of the result of dns query.
*/
- public <T> void query(@Nullable Network network, @NonNull String domain,
+ public void rawQuery(@Nullable Network network, @NonNull String domain,
@QueryClass int nsClass, @QueryType int nsType, @QueryFlag int flags,
@NonNull @CallbackExecutor Executor executor,
@Nullable CancellationSignal cancellationSignal,
- @NonNull AnswerCallback<T> callback) {
+ @NonNull Callback<? super byte[]> callback) {
if (cancellationSignal != null && cancellationSignal.isCanceled()) {
return;
}
@@ -265,9 +240,7 @@
queryfd = resNetworkQuery((network != null
? network.netId : NETID_UNSET), domain, nsClass, nsType, flags);
} catch (ErrnoException e) {
- executor.execute(() -> {
- callback.onQueryException(e);
- });
+ executor.execute(() -> callback.onError(new DnsException(ERROR_SYSTEM, e)));
return;
}
synchronized (lock) {
@@ -277,27 +250,28 @@
}
}
- private class InetAddressAnswerAccumulator extends InetAddressAnswerCallback {
+ private class InetAddressAnswerAccumulator implements Callback<byte[]> {
private final List<InetAddress> mAllAnswers;
- private ParseException mParseException;
- private ErrnoException mErrnoException;
- private final InetAddressAnswerCallback mUserCallback;
+ private int mRcode;
+ private DnsException mDnsException;
+ private final Callback<? super List<InetAddress>> mUserCallback;
private final int mTargetAnswerCount;
private int mReceivedAnswerCount = 0;
- InetAddressAnswerAccumulator(int size, @NonNull InetAddressAnswerCallback callback) {
+ InetAddressAnswerAccumulator(int size,
+ @NonNull Callback<? super List<InetAddress>> callback) {
mTargetAnswerCount = size;
mAllAnswers = new ArrayList<>();
mUserCallback = callback;
}
- private boolean maybeReportException() {
- if (mErrnoException != null) {
- mUserCallback.onQueryException(mErrnoException);
+ private boolean maybeReportError() {
+ if (mRcode != 0) {
+ mUserCallback.onAnswer(mAllAnswers, mRcode);
return true;
}
- if (mParseException != null) {
- mUserCallback.onParseException(mParseException);
+ if (mDnsException != null) {
+ mUserCallback.onError(mDnsException);
return true;
}
return false;
@@ -305,34 +279,43 @@
private void maybeReportAnswer() {
if (++mReceivedAnswerCount != mTargetAnswerCount) return;
- if (mAllAnswers.isEmpty() && maybeReportException()) return;
+ if (mAllAnswers.isEmpty() && maybeReportError()) return;
// TODO: Do RFC6724 sort.
- mUserCallback.onAnswer(mAllAnswers);
+ mUserCallback.onAnswer(mAllAnswers, mRcode);
}
@Override
- public void onAnswer(@NonNull List<InetAddress> answer) {
- mAllAnswers.addAll(answer);
+ public void onAnswer(@NonNull byte[] answer, int rcode) {
+ // If at least one query succeeded, return an rcode of 0.
+ // Otherwise, arbitrarily return the first rcode received.
+ if (mReceivedAnswerCount == 0 || rcode == 0) {
+ mRcode = rcode;
+ }
+ try {
+ mAllAnswers.addAll(new DnsAddressAnswer(answer).getAddresses());
+ } catch (ParseException e) {
+ mDnsException = new DnsException(ERROR_PARSE, e);
+ }
maybeReportAnswer();
}
@Override
- public void onParseException(@NonNull ParseException e) {
- mParseException = e;
- maybeReportAnswer();
- }
-
- @Override
- public void onQueryException(@NonNull ErrnoException e) {
- mErrnoException = e;
+ public void onError(@NonNull DnsException error) {
+ mDnsException = error;
maybeReportAnswer();
}
}
/**
- * Send a DNS query with the specified name, get back a set of InetAddresses asynchronously.
- * The answer will be provided asynchronously through the provided
- * {@link InetAddressAnswerCallback}.
+ * Send a DNS query with the specified name on a network with both IPv4 and IPv6,
+ * get back a set of InetAddresses asynchronously.
+ *
+ * This method will examine the connection ability on given network, and query IPv4
+ * and IPv6 if connection is available.
+ *
+ * If at least one query succeeded with valid answer, rcode will be 0
+ *
+ * The answer will be provided asynchronously through the provided {@link Callback}.
*
* @param network {@link Network} specifying which network to query on.
* {@code null} for query on default network.
@@ -341,13 +324,13 @@
* @param executor The {@link Executor} that the callback should be executed on.
* @param cancellationSignal used by the caller to signal if the query should be
* cancelled. May be {@code null}.
- * @param callback an {@link InetAddressAnswerCallback} which will be called to notify the
+ * @param callback a {@link Callback} which will be called to notify the
* caller of the result of dns query.
*/
public void query(@Nullable Network network, @NonNull String domain, @QueryFlag int flags,
@NonNull @CallbackExecutor Executor executor,
@Nullable CancellationSignal cancellationSignal,
- @NonNull InetAddressAnswerCallback callback) {
+ @NonNull Callback<? super List<InetAddress>> callback) {
if (cancellationSignal != null && cancellationSignal.isCanceled()) {
return;
}
@@ -365,9 +348,7 @@
v6fd = resNetworkQuery((network != null
? network.netId : NETID_UNSET), domain, CLASS_IN, TYPE_AAAA, flags);
} catch (ErrnoException e) {
- executor.execute(() -> {
- callback.onQueryException(e);
- });
+ executor.execute(() -> callback.onError(new DnsException(ERROR_SYSTEM, e)));
return;
}
queryCount++;
@@ -377,7 +358,9 @@
// Avoiding gateways drop packets if queries are sent too close together
try {
Thread.sleep(SLEEP_TIME_MS);
- } catch (InterruptedException ex) { }
+ } catch (InterruptedException ex) {
+ Thread.currentThread().interrupt();
+ }
if (queryIpv4) {
try {
@@ -385,9 +368,7 @@
? network.netId : NETID_UNSET), domain, CLASS_IN, TYPE_A, flags);
} catch (ErrnoException e) {
if (queryIpv6) resNetworkCancel(v6fd); // Closes fd, marks it invalid.
- executor.execute(() -> {
- callback.onQueryException(e);
- });
+ executor.execute(() -> callback.onError(new DnsException(ERROR_SYSTEM, e)));
return;
}
queryCount++;
@@ -413,34 +394,89 @@
}
}
- private <T> void registerFDListener(@NonNull Executor executor,
- @NonNull FileDescriptor queryfd, @NonNull AnswerCallback<T> answerCallback,
+ /**
+ * Send a DNS query with the specified name and query type, get back a set of
+ * InetAddresses asynchronously.
+ *
+ * The answer will be provided asynchronously through the provided {@link Callback}.
+ *
+ * @param network {@link Network} specifying which network to query on.
+ * {@code null} for query on default network.
+ * @param domain domain name to query
+ * @param nsType dns resource record (RR) type as one of the TYPE_* constants
+ * @param flags flags as a combination of the FLAGS_* constants
+ * @param executor The {@link Executor} that the callback should be executed on.
+ * @param cancellationSignal used by the caller to signal if the query should be
+ * cancelled. May be {@code null}.
+ * @param callback a {@link Callback} which will be called to notify the caller
+ * of the result of dns query.
+ */
+ public void query(@Nullable Network network, @NonNull String domain,
+ @QueryType int nsType, @QueryFlag int flags,
+ @NonNull @CallbackExecutor Executor executor,
+ @Nullable CancellationSignal cancellationSignal,
+ @NonNull Callback<? super List<InetAddress>> callback) {
+ if (cancellationSignal != null && cancellationSignal.isCanceled()) {
+ return;
+ }
+ final Object lock = new Object();
+ final FileDescriptor queryfd;
+ try {
+ queryfd = resNetworkQuery((network != null
+ ? network.netId : NETID_UNSET), domain, CLASS_IN, nsType, flags);
+ } catch (ErrnoException e) {
+ executor.execute(() -> callback.onError(new DnsException(ERROR_SYSTEM, e)));
+ return;
+ }
+ final InetAddressAnswerAccumulator accumulator =
+ new InetAddressAnswerAccumulator(1, callback);
+ synchronized (lock) {
+ registerFDListener(executor, queryfd, accumulator, cancellationSignal, lock);
+ if (cancellationSignal == null) return;
+ addCancellationSignal(cancellationSignal, queryfd, lock);
+ }
+ }
+
+ /**
+ * Class to retrieve DNS response
+ *
+ * @hide
+ */
+ public static final class DnsResponse {
+ public final @NonNull byte[] answerbuf;
+ public final int rcode;
+ public DnsResponse(@NonNull byte[] answerbuf, int rcode) {
+ this.answerbuf = answerbuf;
+ this.rcode = rcode;
+ }
+ }
+
+ private void registerFDListener(@NonNull Executor executor,
+ @NonNull FileDescriptor queryfd, @NonNull Callback<? super byte[]> answerCallback,
@Nullable CancellationSignal cancellationSignal, @NonNull Object lock) {
Looper.getMainLooper().getQueue().addOnFileDescriptorEventListener(
queryfd,
FD_EVENTS,
(fd, events) -> {
executor.execute(() -> {
+ DnsResponse resp = null;
+ ErrnoException exception = null;
synchronized (lock) {
if (cancellationSignal != null && cancellationSignal.isCanceled()) {
return;
}
- byte[] answerbuf = null;
try {
- answerbuf = resNetworkResult(fd); // Closes fd, marks it invalid.
+ resp = resNetworkResult(fd); // Closes fd, marks it invalid.
} catch (ErrnoException e) {
Log.e(TAG, "resNetworkResult:" + e.toString());
- answerCallback.onQueryException(e);
- return;
- }
-
- try {
- answerCallback.onAnswer(
- answerCallback.parser.parse(answerbuf));
- } catch (ParseException e) {
- answerCallback.onParseException(e);
+ exception = e;
}
}
+ if (exception != null) {
+ answerCallback.onError(new DnsException(ERROR_SYSTEM, exception));
+ return;
+ }
+ answerCallback.onAnswer(resp.answerbuf, resp.rcode);
});
// Unregister this fd listener
return 0;
diff --git a/core/java/android/net/NetworkUtils.java b/core/java/android/net/NetworkUtils.java
index db87c97..c06a132 100644
--- a/core/java/android/net/NetworkUtils.java
+++ b/core/java/android/net/NetworkUtils.java
@@ -145,9 +145,10 @@
/**
* DNS resolver series jni method.
* Read a result for the query associated with the {@code fd}.
- * @return a byte array containing blob answer
+ * @return DnsResponse containing blob answer and rcode
*/
- public static native byte[] resNetworkResult(FileDescriptor fd) throws ErrnoException;
+ public static native DnsResolver.DnsResponse resNetworkResult(FileDescriptor fd)
+ throws ErrnoException;
/**
* DNS resolver series jni method.
diff --git a/core/java/android/net/ParseException.java b/core/java/android/net/ParseException.java
index 9d4727a..bcfdd7e 100644
--- a/core/java/android/net/ParseException.java
+++ b/core/java/android/net/ParseException.java
@@ -25,12 +25,12 @@
public class ParseException extends RuntimeException {
public String response;
- public ParseException(@NonNull String response) {
+ ParseException(@NonNull String response) {
super(response);
this.response = response;
}
- public ParseException(@NonNull String response, @NonNull Throwable cause) {
+ ParseException(@NonNull String response, @NonNull Throwable cause) {
super(response, cause);
this.response = response;
}
diff --git a/core/java/android/preference/SeekBarVolumizer.java b/core/java/android/preference/SeekBarVolumizer.java
index 847b8e4..02f9925 100644
--- a/core/java/android/preference/SeekBarVolumizer.java
+++ b/core/java/android/preference/SeekBarVolumizer.java
@@ -16,6 +16,7 @@
package android.preference;
+import android.annotation.NonNull;
import android.annotation.UnsupportedAppUsage;
import android.app.NotificationManager;
import android.content.BroadcastReceiver;
@@ -27,8 +28,8 @@
import android.media.AudioManager;
import android.media.Ringtone;
import android.media.RingtoneManager;
-import android.media.audiopolicy.AudioProductStrategies;
-import android.media.audiopolicy.AudioVolumeGroups;
+import android.media.audiopolicy.AudioProductStrategy;
+import android.media.audiopolicy.AudioVolumeGroup;
import android.net.Uri;
import android.os.Handler;
import android.os.HandlerThread;
@@ -67,7 +68,6 @@
private static final int MSG_GROUP_VOLUME_CHANGED = 1;
private final Handler mVolumeHandler = new VolumeHandler();
- private final AudioProductStrategies mAudioProductStrategies;
private AudioAttributes mAttributes;
private int mVolumeGroupId;
@@ -161,11 +161,9 @@
}
mZenMode = mNotificationManager.getZenMode();
- mAudioProductStrategies = mAudioManager.getAudioProductStrategies();
- if (mAudioProductStrategies.size() > 0) {
- mVolumeGroupId = mAudioProductStrategies.getVolumeGroupIdForLegacyStreamType(
- mStreamType);
- mAttributes = mAudioProductStrategies.getAudioAttributesForLegacyStreamType(
+ if (hasAudioProductStrategies()) {
+ mVolumeGroupId = getVolumeGroupIdForLegacyStreamType(mStreamType);
+ mAttributes = getAudioAttributesForLegacyStreamType(
mStreamType);
}
@@ -190,6 +188,40 @@
mDefaultUri = defaultUri;
}
+ private boolean hasAudioProductStrategies() {
+ return AudioManager.getAudioProductStrategies().size() > 0;
+ }
+
+ private int getVolumeGroupIdForLegacyStreamType(int streamType) {
+ for (final AudioProductStrategy productStrategy :
+ AudioManager.getAudioProductStrategies()) {
+ int volumeGroupId = productStrategy.getVolumeGroupIdForLegacyStreamType(streamType);
+ if (volumeGroupId != AudioVolumeGroup.DEFAULT_VOLUME_GROUP) {
+ return volumeGroupId;
+ }
+ }
+
+ return AudioManager.getAudioProductStrategies().stream()
+ .map(strategy -> strategy.getVolumeGroupIdForAudioAttributes(
+ AudioProductStrategy.sDefaultAttributes))
+ .filter(volumeGroupId -> volumeGroupId != AudioVolumeGroup.DEFAULT_VOLUME_GROUP)
+ .findFirst()
+ .orElse(AudioVolumeGroup.DEFAULT_VOLUME_GROUP);
+ }
+
+ private @NonNull AudioAttributes getAudioAttributesForLegacyStreamType(int streamType) {
+ for (final AudioProductStrategy productStrategy :
+ AudioManager.getAudioProductStrategies()) {
+ AudioAttributes aa = productStrategy.getAudioAttributesForLegacyStreamType(streamType);
+ if (aa != null) {
+ return aa;
+ }
+ }
+ return new AudioAttributes.Builder()
+ .setContentType(AudioAttributes.CONTENT_TYPE_UNKNOWN)
+ .setUsage(AudioAttributes.USAGE_UNKNOWN).build();
+ }
+
private static boolean isNotificationOrRing(int stream) {
return stream == AudioManager.STREAM_RING || stream == AudioManager.STREAM_NOTIFICATION;
}
@@ -329,7 +361,7 @@
postStopSample();
mContext.getContentResolver().unregisterContentObserver(mVolumeObserver);
mReceiver.setListening(false);
- if (mAudioProductStrategies.size() > 0) {
+ if (hasAudioProductStrategies()) {
unregisterVolumeGroupCb();
}
mSeekBar.setOnSeekBarChangeListener(null);
@@ -349,7 +381,7 @@
System.getUriFor(System.VOLUME_SETTINGS_INT[mStreamType]),
false, mVolumeObserver);
mReceiver.setListening(true);
- if (mAudioProductStrategies.size() > 0) {
+ if (hasAudioProductStrategies()) {
registerVolumeGroupCb();
}
}
@@ -507,7 +539,7 @@
if (AudioManager.VOLUME_CHANGED_ACTION.equals(action)) {
int streamType = intent.getIntExtra(AudioManager.EXTRA_VOLUME_STREAM_TYPE, -1);
int streamValue = intent.getIntExtra(AudioManager.EXTRA_VOLUME_STREAM_VALUE, -1);
- if (mAudioProductStrategies.size() == 0) {
+ if (hasAudioProductStrategies()) {
updateVolumeSlider(streamType, streamValue);
}
} else if (AudioManager.INTERNAL_RINGER_MODE_CHANGED_ACTION.equals(action)) {
@@ -519,13 +551,12 @@
}
} else if (AudioManager.STREAM_DEVICES_CHANGED_ACTION.equals(action)) {
int streamType = intent.getIntExtra(AudioManager.EXTRA_VOLUME_STREAM_TYPE, -1);
- if (mAudioProductStrategies.size() == 0) {
+ if (hasAudioProductStrategies()) {
int streamVolume = mAudioManager.getStreamVolume(streamType);
updateVolumeSlider(streamType, streamVolume);
} else {
- int volumeGroup = mAudioProductStrategies.getVolumeGroupIdForLegacyStreamType(
- streamType);
- if (volumeGroup != AudioVolumeGroups.DEFAULT_VOLUME_GROUP
+ int volumeGroup = getVolumeGroupIdForLegacyStreamType(streamType);
+ if (volumeGroup != AudioVolumeGroup.DEFAULT_VOLUME_GROUP
&& volumeGroup == mVolumeGroupId) {
int streamVolume = mAudioManager.getStreamVolume(streamType);
updateVolumeSlider(streamType, streamVolume);
@@ -558,14 +589,14 @@
}
private void registerVolumeGroupCb() {
- if (mVolumeGroupId != AudioVolumeGroups.DEFAULT_VOLUME_GROUP) {
+ if (mVolumeGroupId != AudioVolumeGroup.DEFAULT_VOLUME_GROUP) {
mAudioManager.registerVolumeGroupCallback(Runnable::run, mVolumeGroupCallback);
mLastProgress = mAudioManager.getVolumeIndexForAttributes(mAttributes);
}
}
private void unregisterVolumeGroupCb() {
- if (mVolumeGroupId != AudioVolumeGroups.DEFAULT_VOLUME_GROUP) {
+ if (mVolumeGroupId != AudioVolumeGroup.DEFAULT_VOLUME_GROUP) {
mAudioManager.unregisterVolumeGroupCallback(mVolumeGroupCallback);
}
}
@@ -578,7 +609,7 @@
case MSG_GROUP_VOLUME_CHANGED:
int group = (int) args.arg1;
if (mVolumeGroupId != group
- || mVolumeGroupId == AudioVolumeGroups.DEFAULT_VOLUME_GROUP) {
+ || mVolumeGroupId == AudioVolumeGroup.DEFAULT_VOLUME_GROUP) {
return;
}
updateSlider();
diff --git a/core/java/android/provider/MediaStore.java b/core/java/android/provider/MediaStore.java
index da19d59..bff8328 100644
--- a/core/java/android/provider/MediaStore.java
+++ b/core/java/android/provider/MediaStore.java
@@ -31,7 +31,6 @@
import android.app.Activity;
import android.app.AppGlobals;
import android.content.ClipData;
-import android.content.ContentInterface;
import android.content.ContentProviderClient;
import android.content.ContentResolver;
import android.content.ContentUris;
@@ -968,6 +967,13 @@
public static final String DATE_MODIFIED = "date_modified";
/**
+ * The time the media item was taken.
+ */
+ @CurrentTimeMillisLong
+ @Column(value = Cursor.FIELD_TYPE_INTEGER, readOnly = true)
+ public static final String DATE_TAKEN = "datetaken";
+
+ /**
* The MIME type of the media item.
* <p>
* This is typically defined based on the file extension of the media
@@ -1117,6 +1123,38 @@
public static final String SECONDARY_DIRECTORY = "secondary_directory";
/**
+ * The primary bucket ID of this media item. This can be useful to
+ * present the user a first-level clustering of related media items.
+ * This is a read-only column that is automatically computed.
+ */
+ @Column(value = Cursor.FIELD_TYPE_INTEGER, readOnly = true)
+ public static final String BUCKET_ID = "bucket_id";
+
+ /**
+ * The primary bucket display name of this media item. This can be
+ * useful to present the user a first-level clustering of related
+ * media items. This is a read-only column that is automatically
+ * computed.
+ */
+ @Column(value = Cursor.FIELD_TYPE_STRING, readOnly = true)
+ public static final String BUCKET_DISPLAY_NAME = "bucket_display_name";
+
+ /**
+ * The group ID of this media item. This can be useful to present
+ * the user a grouping of related media items, such a burst of
+ * images, or a {@code JPG} and {@code DNG} version of the same
+ * image.
+ * <p>
+ * This is a read-only column that is automatically computed based
+ * on the first portion of the filename. For example,
+ * {@code IMG1024.BURST001.JPG} and {@code IMG1024.BURST002.JPG}
+ * will have the same {@link #GROUP_ID} because the first portion of
+ * their filenames is identical.
+ */
+ @Column(value = Cursor.FIELD_TYPE_INTEGER, readOnly = true)
+ public static final String GROUP_ID = "group_id";
+
+ /**
* The "document ID" GUID as defined by the <em>XMP Media
* Management</em> standard, extracted from any XMP metadata contained
* within this media item. The value is {@code null} when no metadata
@@ -1152,6 +1190,20 @@
*/
@Column(value = Cursor.FIELD_TYPE_STRING, readOnly = true)
public static final String ORIGINAL_DOCUMENT_ID = "original_document_id";
+
+ /**
+ * The duration of the media item.
+ */
+ @DurationMillisLong
+ @Column(value = Cursor.FIELD_TYPE_INTEGER, readOnly = true)
+ public static final String DURATION = "duration";
+
+ /**
+ * The orientation for the media item, expressed in degrees. For
+ * example, 0, 90, 180, or 270 degrees.
+ */
+ @Column(value = Cursor.FIELD_TYPE_INTEGER, readOnly = true)
+ public static final String ORIENTATION = "orientation";
}
/**
@@ -1357,7 +1409,10 @@
/**
* The description of the download.
+ *
+ * @removed
*/
+ @Deprecated
@Column(Cursor.FIELD_TYPE_STRING)
String DESCRIPTION = "description";
}
@@ -1573,18 +1628,9 @@
@Column(value = Cursor.FIELD_TYPE_FLOAT, readOnly = true)
public static final String LONGITUDE = "longitude";
- /**
- * The time the media item was taken.
- */
- @CurrentTimeMillisLong
- @Column(value = Cursor.FIELD_TYPE_INTEGER, readOnly = true)
+ /** @removed promoted to parent interface */
public static final String DATE_TAKEN = "datetaken";
-
- /**
- * The orientation for the image expressed as degrees.
- * Only degrees 0, 90, 180, 270 will work.
- */
- @Column(value = Cursor.FIELD_TYPE_INTEGER, readOnly = true)
+ /** @removed promoted to parent interface */
public static final String ORIENTATION = "orientation";
/**
@@ -1598,36 +1644,11 @@
@Column(Cursor.FIELD_TYPE_INTEGER)
public static final String MINI_THUMB_MAGIC = "mini_thumb_magic";
- /**
- * The primary bucket ID of this media item. This can be useful to
- * present the user a first-level clustering of related media items.
- * This is a read-only column that is automatically computed.
- */
- @Column(value = Cursor.FIELD_TYPE_INTEGER, readOnly = true)
+ /** @removed promoted to parent interface */
public static final String BUCKET_ID = "bucket_id";
-
- /**
- * The primary bucket display name of this media item. This can be
- * useful to present the user a first-level clustering of related
- * media items. This is a read-only column that is automatically
- * computed.
- */
- @Column(value = Cursor.FIELD_TYPE_STRING, readOnly = true)
+ /** @removed promoted to parent interface */
public static final String BUCKET_DISPLAY_NAME = "bucket_display_name";
-
- /**
- * The group ID of this media item. This can be useful to present
- * the user a grouping of related media items, such a burst of
- * images, or a {@code JPG} and {@code DNG} version of the same
- * image.
- * <p>
- * This is a read-only column that is automatically computed based
- * on the first portion of the filename. For example,
- * {@code IMG1024.BURST001.JPG} and {@code IMG1024.BURST002.JPG}
- * will have the same {@link #GROUP_ID} because the first portion of
- * their filenames is identical.
- */
- @Column(value = Cursor.FIELD_TYPE_INTEGER, readOnly = true)
+ /** @removed promoted to parent interface */
public static final String GROUP_ID = "group_id";
}
@@ -2048,11 +2069,7 @@
@Column(value = Cursor.FIELD_TYPE_STRING, readOnly = true)
public static final String TITLE_KEY = "title_key";
- /**
- * The duration of the audio item.
- */
- @DurationMillisLong
- @Column(value = Cursor.FIELD_TYPE_INTEGER, readOnly = true)
+ /** @removed promoted to parent interface */
public static final String DURATION = "duration";
/**
@@ -2885,12 +2902,7 @@
* Video metadata columns.
*/
public interface VideoColumns extends MediaColumns {
-
- /**
- * The duration of the video item.
- */
- @DurationMillisLong
- @Column(value = Cursor.FIELD_TYPE_INTEGER, readOnly = true)
+ /** @removed promoted to parent interface */
public static final String DURATION = "duration";
/**
@@ -2965,11 +2977,7 @@
@Column(value = Cursor.FIELD_TYPE_FLOAT, readOnly = true)
public static final String LONGITUDE = "longitude";
- /**
- * The time the media item was taken.
- */
- @CurrentTimeMillisLong
- @Column(value = Cursor.FIELD_TYPE_INTEGER, readOnly = true)
+ /** @removed promoted to parent interface */
public static final String DATE_TAKEN = "datetaken";
/**
@@ -2983,36 +2991,11 @@
@Column(Cursor.FIELD_TYPE_INTEGER)
public static final String MINI_THUMB_MAGIC = "mini_thumb_magic";
- /**
- * The primary bucket ID of this media item. This can be useful to
- * present the user a first-level clustering of related media items.
- * This is a read-only column that is automatically computed.
- */
- @Column(value = Cursor.FIELD_TYPE_INTEGER, readOnly = true)
+ /** @removed promoted to parent interface */
public static final String BUCKET_ID = "bucket_id";
-
- /**
- * The primary bucket display name of this media item. This can be
- * useful to present the user a first-level clustering of related
- * media items. This is a read-only column that is automatically
- * computed.
- */
- @Column(value = Cursor.FIELD_TYPE_STRING, readOnly = true)
+ /** @removed promoted to parent interface */
public static final String BUCKET_DISPLAY_NAME = "bucket_display_name";
-
- /**
- * The group ID of this media item. This can be useful to present
- * the user a grouping of related media items, such a burst of
- * images, or a {@code JPG} and {@code DNG} version of the same
- * image.
- * <p>
- * This is a read-only column that is automatically computed based
- * on the first portion of the filename. For example,
- * {@code IMG1024.BURST001.JPG} and {@code IMG1024.BURST002.JPG}
- * will have the same {@link #GROUP_ID} because the first portion of
- * their filenames is identical.
- */
- @Column(value = Cursor.FIELD_TYPE_INTEGER, readOnly = true)
+ /** @removed promoted to parent interface */
public static final String GROUP_ID = "group_id";
/**
diff --git a/core/java/android/service/textclassifier/TextClassifierService.java b/core/java/android/service/textclassifier/TextClassifierService.java
index 4088ce8..30c4e90 100644
--- a/core/java/android/service/textclassifier/TextClassifierService.java
+++ b/core/java/android/service/textclassifier/TextClassifierService.java
@@ -358,6 +358,7 @@
/**
* Returns the platform's default TextClassifier implementation.
*/
+ @NonNull
public static TextClassifier getDefaultTextClassifierImplementation(@NonNull Context context) {
final TextClassificationManager tcm =
context.getSystemService(TextClassificationManager.class);
diff --git a/core/java/android/util/StatsLog.java b/core/java/android/util/StatsLog.java
index 9da29c0..cfc092c 100644
--- a/core/java/android/util/StatsLog.java
+++ b/core/java/android/util/StatsLog.java
@@ -187,21 +187,6 @@
}
/**
- * Add a log to the stats log.
- *
- * @param id The id of the atom
- * @param params The parameters of the atom's message.
- */
- public static void write(int id, @NonNull Object... params) {
- switch (id) {
- case PERMISSION_GRANT_REQUEST_RESULT_REPORTED:
- write(id, (long) params[0], (int) params[1], (String) params[2], (String) params[3],
- (boolean) params[4], (int) params[5]);
- break;
- }
- }
-
- /**
* Write an event to stats log using the raw format.
*
* @param buffer The encoded buffer of data to write..
diff --git a/core/java/android/util/StatsLogAtoms.java b/core/java/android/util/StatsLogAtoms.java
deleted file mode 100644
index 4780cb5..0000000
--- a/core/java/android/util/StatsLogAtoms.java
+++ /dev/null
@@ -1,122 +0,0 @@
-/*
- * Copyright (C) 2019 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.util;
-
-import static java.lang.annotation.RetentionPolicy.SOURCE;
-
-import android.annotation.IntDef;
-import android.annotation.SystemApi;
-
-import java.lang.annotation.Retention;
-
-/**
- * Exposed stats logs atom ids.
- *
- * @hide
- */
-@SystemApi
-public class StatsLogAtoms {
- private StatsLogAtoms() {
- }
-
- /**
- * Information about a permission grant request
- *
- * Usage: {@code StatsLog.write(PERMISSION_GRANT_REQUEST_RESULT_REPORTED, long request_id,
- * int requesting_uid, String requesting_package_name, String permission_name,
- * boolean is_implicit, @PermissionGrantRequestResultReported_Result int result)}
- */
- public static final int PERMISSION_GRANT_REQUEST_RESULT_REPORTED =
- StatsLogInternal.PERMISSION_GRANT_REQUEST_RESULT_REPORTED;
-
- @Retention(SOURCE)
- @IntDef(prefix = "PERMISSION_GRANT_REQUEST_RESULT_REPORTED__RESULT__",
- value = {PERMISSION_GRANT_REQUEST_RESULT_REPORTED__RESULT__IGNORED,
- PERMISSION_GRANT_REQUEST_RESULT_REPORTED__RESULT__IGNORED_USER_FIXED,
- PERMISSION_GRANT_REQUEST_RESULT_REPORTED__RESULT__IGNORED_POLICY_FIXED,
- PERMISSION_GRANT_REQUEST_RESULT_REPORTED__RESULT__USER_GRANTED,
- PERMISSION_GRANT_REQUEST_RESULT_REPORTED__RESULT__AUTO_GRANTED,
- PERMISSION_GRANT_REQUEST_RESULT_REPORTED__RESULT__USER_DENIED,
- PERMISSION_GRANT_REQUEST_RESULT_REPORTED__RESULT__USER_DENIED_WITH_PREJUDICE,
- PERMISSION_GRANT_REQUEST_RESULT_REPORTED__RESULT__AUTO_DENIED})
- public @interface PermissionGrantRequestResultReported_Result {}
-
- /**
- * Possible value of {@link PermissionGrantRequestResultReported_Result}:
- * permission request was ignored
- */
- public static final int PERMISSION_GRANT_REQUEST_RESULT_REPORTED__RESULT__IGNORED =
- StatsLogInternal.PERMISSION_GRANT_REQUEST_RESULT_REPORTED__RESULT__IGNORED;
-
- /**
- * Possible value of {@link PermissionGrantRequestResultReported_Result}:
- * permission request was ignored because it was user fixed
- */
- public static final int PERMISSION_GRANT_REQUEST_RESULT_REPORTED__RESULT__IGNORED_USER_FIXED =
- StatsLogInternal.PERMISSION_GRANT_REQUEST_RESULT_REPORTED__RESULT__IGNORED_USER_FIXED;
-
- /**
- * Possible value of {@link PermissionGrantRequestResultReported_Result}:
- * permission request was ignored because it was policy fixed
- */
- public static final int PERMISSION_GRANT_REQUEST_RESULT_REPORTED__RESULT__IGNORED_POLICY_FIXED =
- StatsLogInternal.PERMISSION_GRANT_REQUEST_RESULT_REPORTED__RESULT__IGNORED_POLICY_FIXED;
-
- /**
- * Possible value of {@link PermissionGrantRequestResultReported_Result}:
- * permission request was ignored because it was restricted
- */
- public static final int PERMISSION_GRANT_REQUEST_RESULT_REPORTED__RESULT__IGNORED_RESTRICTED_PERMISSION =
- StatsLogInternal.PERMISSION_GRANT_REQUEST_RESULT_REPORTED__RESULT__IGNORED_RESTRICTED_PERMISSION;
-
- /**
- * Possible value of {@link PermissionGrantRequestResultReported_Result}:
- * permission was granted by user action
- */
- public static final int PERMISSION_GRANT_REQUEST_RESULT_REPORTED__RESULT__USER_GRANTED =
- StatsLogInternal.PERMISSION_GRANT_REQUEST_RESULT_REPORTED__RESULT__USER_GRANTED;
-
- /**
- * Possible value of {@link PermissionGrantRequestResultReported_Result}:
- * permission was automatically granted
- */
- public static final int PERMISSION_GRANT_REQUEST_RESULT_REPORTED__RESULT__AUTO_GRANTED =
- StatsLogInternal.PERMISSION_GRANT_REQUEST_RESULT_REPORTED__RESULT__AUTO_GRANTED;
-
- /**
- * Possible value of {@link PermissionGrantRequestResultReported_Result}:
- * permission was denied by user action
- */
- public static final int PERMISSION_GRANT_REQUEST_RESULT_REPORTED__RESULT__USER_DENIED =
- StatsLogInternal.PERMISSION_GRANT_REQUEST_RESULT_REPORTED__RESULT__USER_DENIED;
-
- /**
- * Possible value of {@link PermissionGrantRequestResultReported_Result}:
- * permission was denied with prejudice by the user
- */
- public static final int
- PERMISSION_GRANT_REQUEST_RESULT_REPORTED__RESULT__USER_DENIED_WITH_PREJUDICE =
- StatsLogInternal
- .PERMISSION_GRANT_REQUEST_RESULT_REPORTED__RESULT__USER_DENIED_WITH_PREJUDICE;
-
- /**
- * Possible value of {@link PermissionGrantRequestResultReported_Result}:
- * permission was automatically denied
- */
- public static final int PERMISSION_GRANT_REQUEST_RESULT_REPORTED__RESULT__AUTO_DENIED =
- StatsLogInternal.PERMISSION_GRANT_REQUEST_RESULT_REPORTED__RESULT__AUTO_DENIED;
-}
diff --git a/core/java/android/view/InputMonitor.java b/core/java/android/view/InputMonitor.java
index 693f287..bbd27dc 100644
--- a/core/java/android/view/InputMonitor.java
+++ b/core/java/android/view/InputMonitor.java
@@ -22,6 +22,13 @@
import android.os.RemoteException;
/**
+ * An {@code InputMonitor} allows privileged applications and components to monitor streams of
+ * {@link InputEvent}s without having to be the designated recipient for the event.
+ *
+ * For example, focus dispatched events would normally only go to the focused window on the
+ * targeted display, but an {@code InputMonitor} will also receive a copy of that event if they're
+ * registered to monitor that type of event on the targeted display.
+ *
* @hide
*/
public final class InputMonitor implements Parcelable {
diff --git a/core/java/android/view/SurfaceControl.java b/core/java/android/view/SurfaceControl.java
index b5ad908..d67c884 100644
--- a/core/java/android/view/SurfaceControl.java
+++ b/core/java/android/view/SurfaceControl.java
@@ -90,8 +90,8 @@
private static native ScreenshotGraphicBuffer nativeScreenshot(IBinder displayToken,
Rect sourceCrop, int width, int height, boolean useIdentityTransform, int rotation,
boolean captureSecureLayers);
- private static native ScreenshotGraphicBuffer nativeCaptureLayers(IBinder layerHandleToken,
- Rect sourceCrop, float frameScale, IBinder[] excludeLayers);
+ private static native ScreenshotGraphicBuffer nativeCaptureLayers(IBinder displayToken,
+ IBinder layerHandleToken, Rect sourceCrop, float frameScale, IBinder[] excludeLayers);
private static native long nativeCreateTransaction();
private static native long nativeGetNativeTransactionFinalizer();
@@ -1998,7 +1998,8 @@
*/
public static ScreenshotGraphicBuffer captureLayers(IBinder layerHandleToken, Rect sourceCrop,
float frameScale) {
- return nativeCaptureLayers(layerHandleToken, sourceCrop, frameScale, null);
+ final IBinder displayToken = SurfaceControl.getInternalDisplayToken();
+ return nativeCaptureLayers(displayToken, layerHandleToken, sourceCrop, frameScale, null);
}
/**
@@ -2007,7 +2008,8 @@
*/
public static ScreenshotGraphicBuffer captureLayersExcluding(IBinder layerHandleToken,
Rect sourceCrop, float frameScale, IBinder[] exclude) {
- return nativeCaptureLayers(layerHandleToken, sourceCrop, frameScale, exclude);
+ final IBinder displayToken = SurfaceControl.getInternalDisplayToken();
+ return nativeCaptureLayers(displayToken, layerHandleToken, sourceCrop, frameScale, exclude);
}
/**
diff --git a/core/java/android/view/textclassifier/TextLinks.java b/core/java/android/view/textclassifier/TextLinks.java
index 66a72f9..f3e0dc1 100644
--- a/core/java/android/view/textclassifier/TextLinks.java
+++ b/core/java/android/view/textclassifier/TextLinks.java
@@ -281,6 +281,7 @@
/**
* Returns a bundle containing custom data related to this TextLink.
*/
+ @NonNull
public Bundle getExtras() {
return mExtras;
}
diff --git a/core/java/android/widget/RelativeLayout.java b/core/java/android/widget/RelativeLayout.java
index 37bed65..4c32f03 100644
--- a/core/java/android/widget/RelativeLayout.java
+++ b/core/java/android/widget/RelativeLayout.java
@@ -21,6 +21,7 @@
import android.annotation.NonNull;
import android.annotation.UnsupportedAppUsage;
import android.content.Context;
+import android.content.res.ResourceId;
import android.content.res.TypedArray;
import android.graphics.Rect;
import android.os.Build;
@@ -1991,7 +1992,7 @@
// dependencies for a specific set of rules
for (int j = 0; j < rulesCount; j++) {
final int rule = rules[rulesFilter[j]];
- if (rule > 0) {
+ if (ResourceId.isValid(rule)) {
// The node this node depends on
final Node dependency = keyNodes.get(rule);
// Skip unknowns and self dependencies
diff --git a/core/java/com/android/internal/app/ChooserActivity.java b/core/java/com/android/internal/app/ChooserActivity.java
index b51f808..4d4fe03 100644
--- a/core/java/com/android/internal/app/ChooserActivity.java
+++ b/core/java/com/android/internal/app/ChooserActivity.java
@@ -101,9 +101,7 @@
import android.widget.AbsListView;
import android.widget.BaseAdapter;
import android.widget.ImageView;
-import android.widget.LinearLayout;
import android.widget.ListView;
-import android.widget.Space;
import android.widget.TextView;
import android.widget.Toast;
@@ -1429,11 +1427,9 @@
}
private void updateAlphabeticalList() {
- if (getDisplayList().size() > MAX_RANKED_TARGETS) {
- mSortedList.clear();
- mSortedList.addAll(getDisplayList());
- Collections.sort(mSortedList, new AzInfoComparator(ChooserActivity.this));
- }
+ mSortedList.clear();
+ mSortedList.addAll(getDisplayList());
+ Collections.sort(mSortedList, new AzInfoComparator(ChooserActivity.this));
}
/**
@@ -1604,7 +1600,7 @@
private final Intent mFillInIntent;
private final int mFillInFlags;
private final float mModifiedScore;
- private boolean mIsSuspended;
+ private boolean mIsSuspended = false;
SelectableTargetInfo(DisplayResolveInfo sourceInfo, ChooserTarget chooserTarget,
float modifiedScore) {
@@ -1619,6 +1615,8 @@
final PackageManager pm = getPackageManager();
mBadgeIcon = pm.getApplicationIcon(ai.applicationInfo);
mBadgeContentDescription = pm.getApplicationLabel(ai.applicationInfo);
+ mIsSuspended =
+ (ai.applicationInfo.flags & ApplicationInfo.FLAG_SUSPENDED) != 0;
}
}
}
@@ -1633,8 +1631,6 @@
mFillInIntent = null;
mFillInFlags = 0;
- ApplicationInfo ai = sourceInfo.getResolveInfo().activityInfo.applicationInfo;
- mIsSuspended = (ai.flags & ApplicationInfo.FLAG_SUSPENDED) != 0;
}
private SelectableTargetInfo(SelectableTargetInfo other, Intent fillInIntent, int flags) {
@@ -1836,7 +1832,7 @@
return;
}
- if (mChooserRowAdapter.calculateMaxTargetsPerRow(right - left)
+ if (mChooserRowAdapter.calculateChooserTargetWidth(right - left)
|| mAdapterView.getAdapter() == null) {
mAdapterView.setAdapter(mChooserRowAdapter);
@@ -2049,12 +2045,13 @@
@Override
public int getUnfilteredCount() {
int appTargets = super.getUnfilteredCount();
- if (appTargets > MAX_RANKED_TARGETS) {
- appTargets = appTargets + MAX_RANKED_TARGETS;
+ if (appTargets > getMaxRankedTargets()) {
+ appTargets = appTargets + getMaxRankedTargets();
}
return appTargets + getSelectableServiceTargetCount() + getCallerTargetCount();
}
+
public int getCallerTargetCount() {
return Math.min(mCallerTargets.size(), MAX_SUGGESTED_APP_TARGETS);
}
@@ -2082,14 +2079,17 @@
int getAlphaTargetCount() {
int standardCount = super.getCount();
- return standardCount > MAX_RANKED_TARGETS ? standardCount : 0;
+ return standardCount > getMaxRankedTargets() ? standardCount : 0;
}
int getRankedTargetCount() {
- int spacesAvailable = MAX_RANKED_TARGETS - getCallerTargetCount();
+ int spacesAvailable = getMaxRankedTargets() - getCallerTargetCount();
return Math.min(spacesAvailable, super.getCount());
}
+ private int getMaxRankedTargets() {
+ return mChooserRowAdapter == null ? 4 : mChooserRowAdapter.getMaxTargetsPerRow();
+ }
public int getPositionTargetType(int position) {
int offset = 0;
@@ -2325,9 +2325,9 @@
class ChooserRowAdapter extends BaseAdapter {
private ChooserListAdapter mChooserListAdapter;
private final LayoutInflater mLayoutInflater;
- private int mCalculatedMaxTargetsPerRow = MAX_TARGETS_PER_ROW_LANDSCAPE;
private DirectShareViewHolder mDirectShareViewHolder;
+ private int mChooserTargetWidth = 0;
private static final int VIEW_TYPE_DIRECT_SHARE = 0;
private static final int VIEW_TYPE_NORMAL = 1;
@@ -2356,25 +2356,23 @@
}
/**
- * Determine how many targets can comfortably fit in a single row.
+ * Calculate the chooser target width to maximize space per item
*
* @param width The new row width to use for recalculation
- * @return true if the numbers of targets per row has changed
+ * @return true if the view width has changed
*/
- public boolean calculateMaxTargetsPerRow(int width) {
- int targetWidth = getResources().getDimensionPixelSize(
+ public boolean calculateChooserTargetWidth(int width) {
+ int targetMinWidth = getResources().getDimensionPixelSize(
R.dimen.chooser_target_width);
- if (targetWidth == 0 || width == 0) {
+ if (width == 0) {
return false;
}
- int margin = getResources().getDimensionPixelSize(
- R.dimen.chooser_edge_margin_normal);
-
- int newCount = (width - margin * 2) / targetWidth;
- if (newCount != mCalculatedMaxTargetsPerRow) {
- mCalculatedMaxTargetsPerRow = newCount;
+ int targetWidth = width / getMaxTargetsPerRow();
+ int newWidth = Math.max(targetWidth, targetMinWidth);
+ if (newWidth != mChooserTargetWidth) {
+ mChooserTargetWidth = newWidth;
return true;
}
@@ -2388,7 +2386,7 @@
maxTargets = MAX_TARGETS_PER_ROW_LANDSCAPE;
}
- return Math.min(maxTargets, mCalculatedMaxTargetsPerRow);
+ return maxTargets;
}
@Override
@@ -2498,6 +2496,8 @@
private RowViewHolder loadViewsIntoRow(RowViewHolder holder) {
final int spec = MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED);
+ final int exactSpec = MeasureSpec.makeMeasureSpec(mChooserTargetWidth,
+ MeasureSpec.EXACTLY);
int columnCount = holder.getColumnCount();
final boolean isDirectShare = holder instanceof DirectShareViewHolder;
@@ -2533,20 +2533,20 @@
}
// Force height to be a given so we don't have visual disruption during scaling.
- v.measure(spec, spec);
- setViewHeight(v, v.getMeasuredHeight());
+ v.measure(exactSpec, spec);
+ setViewBounds(v, v.getMeasuredWidth(), v.getMeasuredHeight());
}
final ViewGroup viewGroup = holder.getViewGroup();
// Pre-measure and fix height so we can scale later.
holder.measure();
- setViewHeight(viewGroup, holder.getMeasuredRowHeight());
+ setViewBounds(viewGroup, LayoutParams.MATCH_PARENT, holder.getMeasuredRowHeight());
if (isDirectShare) {
DirectShareViewHolder dsvh = (DirectShareViewHolder) holder;
- setViewHeight(dsvh.getRow(0), dsvh.getMinRowHeight());
- setViewHeight(dsvh.getRow(1), dsvh.getMinRowHeight());
+ setViewBounds(dsvh.getRow(0), LayoutParams.MATCH_PARENT, dsvh.getMinRowHeight());
+ setViewBounds(dsvh.getRow(1), LayoutParams.MATCH_PARENT, dsvh.getMinRowHeight());
}
viewGroup.setTag(holder);
@@ -2554,13 +2554,14 @@
return holder;
}
- private void setViewHeight(View view, int heightPx) {
+ private void setViewBounds(View view, int widthPx, int heightPx) {
LayoutParams lp = view.getLayoutParams();
if (lp == null) {
- lp = new LayoutParams(LayoutParams.MATCH_PARENT, heightPx);
+ lp = new LayoutParams(widthPx, heightPx);
view.setLayoutParams(lp);
} else {
lp.height = heightPx;
+ lp.width = widthPx;
}
}
@@ -2712,11 +2713,6 @@
return mMeasuredRowHeight;
}
- protected void addSpacer(ViewGroup row) {
- row.addView(new Space(ChooserActivity.this),
- new LinearLayout.LayoutParams(0, 0, 1));
- }
-
public void setItemIndex(int itemIndex, int listIndex) {
mItemIndices[itemIndex] = listIndex;
}
@@ -2756,10 +2752,6 @@
mRow.addView(v);
mCells[index] = v;
- if (index != (mCells.length - 1)) {
- addSpacer(mRow);
- }
-
return mRow;
}
@@ -2794,10 +2786,6 @@
row.addView(v);
mCells[index] = v;
- if (index % mCellCountPerRow != (mCellCountPerRow - 1)) {
- addSpacer(row);
- }
-
return row;
}
diff --git a/core/java/com/android/internal/app/SimpleIconFactory.java b/core/java/com/android/internal/app/SimpleIconFactory.java
index a85485d..2484109 100644
--- a/core/java/com/android/internal/app/SimpleIconFactory.java
+++ b/core/java/com/android/internal/app/SimpleIconFactory.java
@@ -34,6 +34,8 @@
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.PaintFlagsDrawFilter;
+import android.graphics.PorterDuff;
+import android.graphics.PorterDuffXfermode;
import android.graphics.Rect;
import android.graphics.RectF;
import android.graphics.drawable.AdaptiveIconDrawable;
@@ -56,7 +58,7 @@
/**
* @deprecated Use the Launcher3 Iconloaderlib at packages/apps/Launcher3/iconloaderlib. This class
* is a temporary fork of Iconloader. It combines all necessary methods to render app icons that are
- * possibly badged. It is intended to be used only by Sharesheet for the Q release.
+ * possibly badged. It is intended to be used only by Sharesheet for the Q release with custom code.
*/
@Deprecated
public class SimpleIconFactory {
@@ -202,6 +204,7 @@
/**
* Creates bitmap using the source drawable and flattened pre-rendered app icon.
* The bitmap is visually normalized with other icons and has enough spacing to add shadow.
+ * This is custom functionality added to Iconloaderlib that will need to be ported.
*
* @param icon source of the icon associated with a user that has no badge
* @param renderedAppIcon pre-rendered app icon to use as a badge, likely the output
@@ -212,34 +215,70 @@
*/
@Deprecated
Bitmap createAppBadgedIconBitmap(@Nullable Drawable icon, Bitmap renderedAppIcon) {
- // Flatten the passed in icon
- float [] scale = new float[1];
-
// If no icon is provided use the system default
if (icon == null) {
icon = getFullResDefaultActivityIcon(mFillResIconDpi);
}
- icon = normalizeAndWrapToAdaptiveIcon(icon, null, scale);
- Bitmap bitmap = createIconBitmap(icon, scale[0]);
- if (icon instanceof AdaptiveIconDrawable) {
- mCanvas.setBitmap(bitmap);
- recreateIcon(Bitmap.createBitmap(bitmap), mCanvas);
- mCanvas.setBitmap(null);
+
+ // Direct share icons cannot be adaptive, most will arrive as bitmaps. To get reliable
+ // presentation, force all DS icons to be circular. Scale DS image so it completely fills.
+ int w = icon.getIntrinsicWidth();
+ int h = icon.getIntrinsicHeight();
+ float scale = 1;
+ if (h > w && w > 0) {
+ scale = (float) h / w;
+ } else if (w > h && h > 0) {
+ scale = (float) w / h;
+ }
+ Bitmap bitmap = createIconBitmap(icon, scale);
+ bitmap = maskBitmapToCircle(bitmap);
+ icon = new BitmapDrawable(mContext.getResources(), bitmap);
+
+ // We now have a circular masked and scaled icon, inset and apply shadow
+ scale = getScale(icon, null);
+ bitmap = createIconBitmap(icon, scale);
+
+ mCanvas.setBitmap(bitmap);
+ recreateIcon(Bitmap.createBitmap(bitmap), mCanvas);
+
+ if (renderedAppIcon != null) {
+ // Now scale down and apply the badge to the bottom right corner of the flattened icon
+ renderedAppIcon = Bitmap.createScaledBitmap(renderedAppIcon, mBadgeBitmapSize,
+ mBadgeBitmapSize, false);
+
+ // Paint the provided badge on top of the flattened icon
+ mCanvas.drawBitmap(renderedAppIcon, mIconBitmapSize - mBadgeBitmapSize,
+ mIconBitmapSize - mBadgeBitmapSize, null);
}
- // Now scale down and apply the badge to the bottom right corner of the flattened icon
- renderedAppIcon = Bitmap.createScaledBitmap(renderedAppIcon, mBadgeBitmapSize,
- mBadgeBitmapSize, false);
-
- // Paint the provided badge on top of the flattened icon
- mCanvas.setBitmap(bitmap);
- mCanvas.drawBitmap(renderedAppIcon, mIconBitmapSize - mBadgeBitmapSize,
- mIconBitmapSize - mBadgeBitmapSize, null);
mCanvas.setBitmap(null);
return bitmap;
}
+ private Bitmap maskBitmapToCircle(Bitmap bitmap) {
+ final Bitmap output = Bitmap.createBitmap(bitmap.getWidth(),
+ bitmap.getHeight(), Bitmap.Config.ARGB_8888);
+ final Canvas canvas = new Canvas(output);
+ final Paint paint = new Paint();
+ paint.setAntiAlias(true);
+
+ // Draw mask
+ paint.setColor(0xffffffff);
+ canvas.drawARGB(0, 0, 0, 0);
+ canvas.drawCircle(bitmap.getWidth() / 2f,
+ bitmap.getHeight() / 2f,
+ bitmap.getWidth() / 2f - 1 /* -1 to avoid circles with flat sides */,
+ paint);
+
+ // Draw masked bitmap
+ paint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.SRC_IN));
+ final Rect rect = new Rect(0, 0, bitmap.getWidth(), bitmap.getHeight());
+ canvas.drawBitmap(bitmap, rect, rect, paint);
+
+ return output;
+ }
+
private static Drawable getFullResDefaultActivityIcon(int iconDpi) {
return Resources.getSystem().getDrawableForDensity(android.R.mipmap.sym_def_app_icon,
iconDpi);
diff --git a/core/java/com/android/internal/content/FileSystemProvider.java b/core/java/com/android/internal/content/FileSystemProvider.java
index 18c4b46..a7244a7 100644
--- a/core/java/com/android/internal/content/FileSystemProvider.java
+++ b/core/java/com/android/internal/content/FileSystemProvider.java
@@ -332,33 +332,11 @@
}
private void moveInMediaStore(@Nullable File oldVisibleFile, @Nullable File newVisibleFile) {
- // visibleFolders are null if we're moving a document in external thumb drive or SD card.
- //
- // They should be all null or not null at the same time. File#renameTo() doesn't work across
- // volumes so an exception will be thrown before calling this method.
- if (oldVisibleFile != null && newVisibleFile != null) {
- final long token = Binder.clearCallingIdentity();
-
- try {
- final ContentResolver resolver = getContext().getContentResolver();
- final Uri externalUri = newVisibleFile.isDirectory()
- ? MediaStore.Files.getDirectoryUri("external")
- : MediaStore.Files.getContentUri("external");
-
- ContentValues values = new ContentValues();
- values.put(MediaStore.Files.FileColumns.DATA, newVisibleFile.getAbsolutePath());
-
- // Logic borrowed from MtpDatabase.
- // note - we are relying on a special case in MediaProvider.update() to update
- // the paths for all children in the case where this is a directory.
- final String path = oldVisibleFile.getAbsolutePath();
- resolver.update(externalUri,
- values,
- "_data LIKE ? AND lower(_data)=lower(?)",
- new String[]{path, path});
- } finally {
- Binder.restoreCallingIdentity(token);
- }
+ if (oldVisibleFile != null) {
+ MediaStore.scanFile(getContext(), oldVisibleFile);
+ }
+ if (newVisibleFile != null) {
+ MediaStore.scanFile(getContext(), newVisibleFile);
}
}
diff --git a/core/java/com/android/internal/os/Zygote.java b/core/java/com/android/internal/os/Zygote.java
index afdeb1b..a295bd2 100644
--- a/core/java/com/android/internal/os/Zygote.java
+++ b/core/java/com/android/internal/os/Zygote.java
@@ -566,7 +566,18 @@
System.exit(-1);
} finally {
IoUtils.closeQuietly(sessionSocket);
- IoUtils.closeQuietly(usapPoolSocket);
+
+ try {
+ // This socket is closed using Os.close due to an issue with the implementation of
+ // LocalSocketImp.close. Because the raw FD is created by init and then loaded from
+ // an environment variable (as opposed to being created by the LocalSocketImpl
+ // itself) the current implementation will not actually close the underlying FD.
+ //
+ // See b/130309968 for discussion of this issue.
+ Os.close(usapPoolSocket.getFileDescriptor());
+ } catch (ErrnoException ex) {
+ Log.e("USAP", "Failed to close USAP pool socket: " + ex.getMessage());
+ }
}
try {
diff --git a/core/java/com/android/internal/policy/DecorView.java b/core/java/com/android/internal/policy/DecorView.java
index d945e13..32fce8f 100644
--- a/core/java/com/android/internal/policy/DecorView.java
+++ b/core/java/com/android/internal/policy/DecorView.java
@@ -630,7 +630,7 @@
drawingBounds.bottom -= framePadding.bottom - frameOffsets.bottom;
}
- Drawable bg = getBackground();
+ Drawable bg = super.getBackground();
if (bg != null) {
bg.setBounds(drawingBounds);
}
@@ -1238,6 +1238,11 @@
mLastOriginalBackgroundDrawable = mOriginalBackgroundDrawable;
}
+ @Override
+ public Drawable getBackground() {
+ return mOriginalBackgroundDrawable;
+ }
+
private int calculateStatusBarColor() {
return calculateBarColor(mWindow.getAttributes().flags, FLAG_TRANSLUCENT_STATUS,
mSemiTransparentBarColor, mWindow.mStatusBarColor,
diff --git a/core/jni/AndroidRuntime.cpp b/core/jni/AndroidRuntime.cpp
index b6ee0fe..f266502 100644
--- a/core/jni/AndroidRuntime.cpp
+++ b/core/jni/AndroidRuntime.cpp
@@ -678,6 +678,7 @@
char lockProfThresholdBuf[sizeof("-Xlockprofthreshold:")-1 + PROPERTY_VALUE_MAX];
char nativeBridgeLibrary[sizeof("-XX:NativeBridge=") + PROPERTY_VALUE_MAX];
char cpuAbiListBuf[sizeof("--cpu-abilist=") + PROPERTY_VALUE_MAX];
+ char corePlatformApiPolicyBuf[sizeof("-Xcore-platform-api-policy:") + PROPERTY_VALUE_MAX];
char methodTraceFileBuf[sizeof("-Xmethod-trace-file:") + PROPERTY_VALUE_MAX];
char methodTraceFileSizeBuf[sizeof("-Xmethod-trace-file-size:") + PROPERTY_VALUE_MAX];
std::string fingerprintBuf;
@@ -1024,6 +1025,16 @@
addOption("--generate-mini-debug-info");
}
+ // If set, the property below can be used to enable core platform API violation reporting.
+ property_get("persist.debug.dalvik.vm.core_platform_api_policy", propBuf, "");
+ if (propBuf[0] != '\0') {
+ snprintf(corePlatformApiPolicyBuf,
+ sizeof(corePlatformApiPolicyBuf),
+ "-Xcore-platform-api-policy:%s",
+ propBuf);
+ addOption(corePlatformApiPolicyBuf);
+ }
+
/*
* Retrieve the build fingerprint and provide it to the runtime. That way, ANR dumps will
* contain the fingerprint and can be parsed.
diff --git a/core/jni/android_media_AudioProductStrategies.cpp b/core/jni/android_media_AudioProductStrategies.cpp
index 822b74a..17a02b2 100644
--- a/core/jni/android_media_AudioProductStrategies.cpp
+++ b/core/jni/android_media_AudioProductStrategies.cpp
@@ -39,7 +39,7 @@
using namespace android;
// ----------------------------------------------------------------------------
-static const char* const kClassPathName = "android/media/audiopolicy/AudioProductStrategies";
+static const char* const kClassPathName = "android/media/audiopolicy/AudioProductStrategy";
static const char* const kAudioProductStrategyClassPathName =
"android/media/audiopolicy/AudioProductStrategy";
@@ -194,34 +194,12 @@
return jStatus;
}
-static jint
-android_media_AudioSystem_getProductStrategyFromAudioAttributes(JNIEnv *env, jobject clazz,
- jobject jAudioAttributes)
-{
- JNIAudioAttributeHelper::UniqueAaPtr attributes = JNIAudioAttributeHelper::makeUnique();
- jint jStatus = JNIAudioAttributeHelper::nativeFromJava(env,
- jAudioAttributes,
- attributes.get());
- if (jStatus != (jint)AUDIO_JAVA_SUCCESS) {
- return jStatus;
- }
- product_strategy_t psId;
- status_t status = AudioSystem::getProductStrategyFromAudioAttributes(
- AudioAttributes(*attributes.get()), psId);
- if (status != NO_ERROR) {
- return nativeToJavaStatus(status);
- }
- return psId;
-}
-
/*
* JNI registration.
*/
static const JNINativeMethod gMethods[] = {
{"native_list_audio_product_strategies", "(Ljava/util/ArrayList;)I",
(void *)android_media_AudioSystem_listAudioProductStrategies},
- {"native_get_product_strategies_from_audio_attributes", "(Landroid/media/AudioAttributes;)I",
- (void *)android_media_AudioSystem_getProductStrategyFromAudioAttributes},
};
int register_android_media_AudioProductStrategies(JNIEnv *env)
diff --git a/core/jni/android_media_AudioVolumeGroups.cpp b/core/jni/android_media_AudioVolumeGroups.cpp
index 64f0c1e..7098451 100644
--- a/core/jni/android_media_AudioVolumeGroups.cpp
+++ b/core/jni/android_media_AudioVolumeGroups.cpp
@@ -39,7 +39,7 @@
using namespace android;
// ----------------------------------------------------------------------------
-static const char* const kClassPathName = "android/media/audiopolicy/AudioVolumeGroups";
+static const char* const kClassPathName = "android/media/audiopolicy/AudioVolumeGroup";
static const char* const kAudioVolumeGroupClassPathName =
"android/media/audiopolicy/AudioVolumeGroup";
diff --git a/core/jni/android_net_NetUtils.cpp b/core/jni/android_net_NetUtils.cpp
index dd754f3..28c59db 100644
--- a/core/jni/android_net_NetUtils.cpp
+++ b/core/jni/android_net_NetUtils.cpp
@@ -270,7 +270,7 @@
return jniCreateFileDescriptor(env, fd);
}
-static jbyteArray android_net_utils_resNetworkResult(JNIEnv *env, jobject thiz, jobject javaFd) {
+static jobject android_net_utils_resNetworkResult(JNIEnv *env, jobject thiz, jobject javaFd) {
int fd = jniGetFDFromFileDescriptor(env, javaFd);
int rcode;
std::vector<uint8_t> buf(MAXPACKETSIZE, 0);
@@ -291,7 +291,10 @@
reinterpret_cast<jbyte*>(buf.data()));
}
- return answer;
+ jclass class_DnsResponse = env->FindClass("android/net/DnsResolver$DnsResponse");
+ jmethodID ctor = env->GetMethodID(class_DnsResponse, "<init>", "([BI)V");
+
+ return env->NewObject(class_DnsResponse, ctor, answer, rcode);
}
static void android_net_utils_resNetworkCancel(JNIEnv *env, jobject thiz, jobject javaFd) {
@@ -354,7 +357,7 @@
{ "setupRaSocket", "(Ljava/io/FileDescriptor;I)V", (void*) android_net_utils_setupRaSocket },
{ "resNetworkSend", "(I[BII)Ljava/io/FileDescriptor;", (void*) android_net_utils_resNetworkSend },
{ "resNetworkQuery", "(ILjava/lang/String;III)Ljava/io/FileDescriptor;", (void*) android_net_utils_resNetworkQuery },
- { "resNetworkResult", "(Ljava/io/FileDescriptor;)[B", (void*) android_net_utils_resNetworkResult },
+ { "resNetworkResult", "(Ljava/io/FileDescriptor;)Landroid/net/DnsResolver$DnsResponse;", (void*) android_net_utils_resNetworkResult },
{ "resNetworkCancel", "(Ljava/io/FileDescriptor;)V", (void*) android_net_utils_resNetworkCancel },
};
diff --git a/core/jni/android_view_SurfaceControl.cpp b/core/jni/android_view_SurfaceControl.cpp
index 3135c62..c0b31e4 100644
--- a/core/jni/android_view_SurfaceControl.cpp
+++ b/core/jni/android_view_SurfaceControl.cpp
@@ -271,8 +271,9 @@
capturedSecureLayers);
}
-static jobject nativeCaptureLayers(JNIEnv* env, jclass clazz, jobject layerHandleToken,
- jobject sourceCropObj, jfloat frameScale, jobjectArray excludeArray) {
+static jobject nativeCaptureLayers(JNIEnv* env, jclass clazz, jobject displayTokenObj,
+ jobject layerHandleToken, jobject sourceCropObj, jfloat frameScale,
+ jobjectArray excludeArray) {
sp<IBinder> layerHandle = ibinderForJavaObject(env, layerHandleToken);
if (layerHandle == NULL) {
@@ -301,7 +302,12 @@
}
sp<GraphicBuffer> buffer;
- const ui::Dataspace dataspace = ui::Dataspace::V0_SRGB;
+ ui::Dataspace dataspace = ui::Dataspace::V0_SRGB;
+ sp<IBinder> displayToken = ibinderForJavaObject(env, displayTokenObj);
+ if (displayToken != nullptr) {
+ const ui::ColorMode colorMode = SurfaceComposerClient::getActiveColorMode(displayToken);
+ dataspace = pickDataspaceFromColorMode(colorMode);
+ }
status_t res = ScreenshotClient::captureChildLayers(layerHandle, dataspace,
ui::PixelFormat::RGBA_8888, sourceCrop,
excludeHandles, frameScale, &buffer);
@@ -1373,7 +1379,8 @@
"Landroid/view/SurfaceControl$ScreenshotGraphicBuffer;",
(void*)nativeScreenshot },
{"nativeCaptureLayers",
- "(Landroid/os/IBinder;Landroid/graphics/Rect;F[Landroid/os/IBinder;)"
+ "(Landroid/os/IBinder;Landroid/os/IBinder;Landroid/graphics/Rect;"
+ "F[Landroid/os/IBinder;)"
"Landroid/view/SurfaceControl$ScreenshotGraphicBuffer;",
(void*)nativeCaptureLayers },
{"nativeSetInputWindowInfo", "(JJLandroid/view/InputWindowHandle;)V",
diff --git a/core/proto/android/stats/devicepolicy/device_policy_enums.proto b/core/proto/android/stats/devicepolicy/device_policy_enums.proto
index 589a6a7..0db7424 100644
--- a/core/proto/android/stats/devicepolicy/device_policy_enums.proto
+++ b/core/proto/android/stats/devicepolicy/device_policy_enums.proto
@@ -145,4 +145,8 @@
ESTABLISH_VPN = 118;
SET_NETWORK_LOGGING_ENABLED = 119;
RETRIEVE_NETWORK_LOGS = 120;
+ PROVISIONING_PREPARE_TOTAL_TIME_MS = 121;
+ PROVISIONING_PREPARE_STARTED = 122;
+ PROVISIONING_PREPARE_COMPLETED = 123;
+ PROVISIONING_FLOW_TYPE = 124;
}
diff --git a/core/res/res/layout/chooser_grid.xml b/core/res/res/layout/chooser_grid.xml
index 1f80417..68c62a6 100644
--- a/core/res/res/layout/chooser_grid.xml
+++ b/core/res/res/layout/chooser_grid.xml
@@ -32,11 +32,11 @@
<ImageView
android:id="@+id/drag"
- android:layout_width="32dp"
+ android:layout_width="24dp"
android:layout_height="4dp"
android:src="@drawable/ic_drag_handle"
android:clickable="true"
- android:layout_marginTop="@dimen/chooser_view_spacing"
+ android:layout_marginTop="@dimen/chooser_edge_margin_thin"
android:tint="@color/lighter_gray"
android:layout_centerHorizontal="true"
android:layout_alignParentTop="true" />
@@ -61,8 +61,9 @@
android:layout_width="wrap_content"
android:textAppearance="?attr/textAppearanceMedium"
android:textSize="20sp"
+ android:textColor="?attr/textColorPrimary"
android:gravity="center"
- android:paddingTop="@dimen/chooser_view_spacing"
+ android:paddingTop="@dimen/chooser_edge_margin_thin"
android:paddingBottom="@dimen/chooser_view_spacing"
android:paddingLeft="24dp"
android:paddingRight="24dp"
diff --git a/core/res/res/layout/chooser_grid_preview_text.xml b/core/res/res/layout/chooser_grid_preview_text.xml
index 6abf57a..3c9ffdb 100644
--- a/core/res/res/layout/chooser_grid_preview_text.xml
+++ b/core/res/res/layout/chooser_grid_preview_text.xml
@@ -43,16 +43,18 @@
android:layout_gravity="center_vertical"
android:ellipsize="end"
android:gravity="start|top"
- android:paddingRight="24dp"
+ android:paddingRight="@dimen/chooser_view_spacing"
android:maxLines="2"/>
- <Button
+ <ImageButton
android:id="@+id/copy_button"
- android:layout_width="24dp"
- android:layout_height="24dp"
+ android:layout_width="48dp"
+ android:layout_height="48dp"
+ android:padding="12dp"
android:gravity="center"
android:layout_gravity="center_vertical"
- android:foreground="@drawable/ic_content_copy_gm2"
+ android:src="@drawable/ic_content_copy_gm2"
android:clickable="true"
+ android:contentDescription="@string/copy"
android:background="?attr/selectableItemBackgroundBorderless"/>
</LinearLayout>
@@ -63,8 +65,8 @@
android:layout_height="wrap_content"
android:layout_gravity="center"
android:orientation="horizontal"
- android:layout_marginLeft="@dimen/chooser_edge_margin_thin"
- android:layout_marginRight="@dimen/chooser_edge_margin_thin"
+ android:layout_marginLeft="@dimen/chooser_edge_margin_normal"
+ android:layout_marginRight="@dimen/chooser_edge_margin_normal"
android:minHeight="80dp"
android:background="@drawable/chooser_content_preview_rounded"
android:id="@+id/content_preview_title_layout">
@@ -87,7 +89,7 @@
android:layout_gravity="center_vertical"
android:ellipsize="end"
android:maxLines="2"
- android:textAppearance="?attr/textAppearanceMedium"/>
+ android:textSize="20sp"/>
</LinearLayout>
</LinearLayout>
diff --git a/core/res/res/layout/chooser_row.xml b/core/res/res/layout/chooser_row.xml
index 742d7eed..f5814c3 100644
--- a/core/res/res/layout/chooser_row.xml
+++ b/core/res/res/layout/chooser_row.xml
@@ -20,9 +20,7 @@
android:orientation="horizontal"
android:layout_width="match_parent"
android:layout_height="100dp"
- android:gravity="start|top"
- android:paddingStart="@dimen/chooser_edge_margin_normal"
- android:paddingEnd="@dimen/chooser_edge_margin_normal">
+ android:gravity="start|top">
<TextView
android:id="@+id/chooser_row_text_option"
android:layout_width="match_parent"
diff --git a/core/res/res/layout/resolve_grid_item.xml b/core/res/res/layout/resolve_grid_item.xml
index 7065149..256d94e 100644
--- a/core/res/res/layout/resolve_grid_item.xml
+++ b/core/res/res/layout/resolve_grid_item.xml
@@ -24,8 +24,8 @@
android:gravity="center"
android:paddingTop="24dp"
android:paddingBottom="8dp"
- android:paddingLeft="2dp"
- android:paddingRight="2dp"
+ android:paddingLeft="12dp"
+ android:paddingRight="12dp"
android:focusable="true"
android:background="?attr/selectableItemBackgroundBorderless">
@@ -45,7 +45,6 @@
android:textAppearance="?attr/textAppearanceSmall"
android:textColor="?attr/textColorPrimary"
android:textSize="14sp"
- android:fontFamily="sans-serif-condensed"
android:gravity="top|center_horizontal"
android:lines="1"
android:ellipsize="end" />
@@ -54,6 +53,7 @@
<TextView android:id="@android:id/text2"
android:textAppearance="?android:attr/textAppearanceSmall"
android:textSize="12sp"
+ android:textColor="?attr/textColorSecondary"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:lines="1"
diff --git a/core/res/res/values/attrs_manifest.xml b/core/res/res/values/attrs_manifest.xml
index 47c243c..bfa57e4 100644
--- a/core/res/res/values/attrs_manifest.xml
+++ b/core/res/res/values/attrs_manifest.xml
@@ -1684,18 +1684,27 @@
This flag is turned on by default. <em>This attribute is usable only by system apps.
</em> -->
<attr name="allowClearUserDataOnFailedRestore"/>
- <!-- If {@code true} the app's non sensitive audio can be capture by other apps with
- {@code AudioPlaybackCaptureConfiguration} and a {@code MediaProjection}.
+ <!-- If {@code true} the app's non sensitive audio can be captured by other apps with
+ {@link android.media.AudioPlaybackCaptureConfiguration} and a
+ {@link android.media.projection.MediaProjection}.
+
+ If {@code false} the audio played by the application will never be captured by non
+ system apps. It is equivalent to limiting
+ {@link android.media.AudioManager#setAllowedCapturePolicy(int)} to
+ {@link android.media.AudioAttributes#ALLOW_CAPTURE_BY_SYSTEM}.
<p>
Non sensitive audio is defined as audio whose {@code AttributeUsage} is
{@code USAGE_UNKNOWN}), {@code USAGE_MEDIA}) or {@code USAGE_GAME}).
- All other usages (eg. {@code USAGE_VOICE_COMMUNICATION}) will not be captured.
+ All other usages like {@code USAGE_VOICE_COMMUNICATION} will not be captured.
<p>
The default value is:
- {@code true} for apps with targetSdkVersion >= 29 (Q).
- {@code false} for apps with targetSdkVersion < 29.
+
+ <p>
+ See {@link android.media.AudioPlaybackCaptureConfiguration} for more detail.
-->
<attr name="allowAudioPlaybackCapture" format="boolean" />
<!-- If {@code true} this app allows shared/external storage media to be
@@ -2814,6 +2823,9 @@
case-sensitive, unlike formal RFC MIME types. As a result,
MIME types here should always use lower case letters.</em></p> -->
<attr name="mimeType" />
+ <!-- The identifier to assign to the intent, as per
+ {@link android.content.Intent#setIdentifier Intent.setIdentifier()}. -->
+ <attr name="identifier" format="string" />
<!-- The package part of the ComponentName to assign to the Intent, as per
{@link android.content.Intent#setComponent Intent.setComponent()}. -->
<attr name="targetPackage" />
diff --git a/core/res/res/values/config.xml b/core/res/res/values/config.xml
index f27f34a..edcc057 100644
--- a/core/res/res/values/config.xml
+++ b/core/res/res/values/config.xml
@@ -745,6 +745,10 @@
<!-- XXXXXX END OF RESOURCES USING WRONG NAMING CONVENTION -->
+ <!-- If this is true, notification effects will be played by the notification server.
+ When false, car notification effects will be handled elsewhere. -->
+ <bool name="config_enableServerNotificationEffectsForAutomotive">false</bool>
+
<!-- If this is true, the screen will come on when you unplug usb/power/whatever. -->
<bool name="config_unplugTurnsOnScreen">false</bool>
@@ -1971,10 +1975,6 @@
<bool name="config_showDefaultEmergency">false</bool>
<!-- Whether the default home settings should be shown. -->
<bool name="config_showDefaultHome">true</bool>
- <!-- The name of the package that will hold the music role by default. -->
- <string name="config_defaultMusic" translatable="false">com.android.music</string>
- <!-- The name of the package that will hold the gallery role by default. -->
- <string name="config_defaultGallery" translatable="false">com.android.gallery3d</string>
<!-- Enable/disable default bluetooth profiles:
HSP_AG, ObexObjectPush, Audio, NAP -->
diff --git a/core/res/res/values/dimens.xml b/core/res/res/values/dimens.xml
index 02cbc2e..b81db15 100644
--- a/core/res/res/values/dimens.xml
+++ b/core/res/res/values/dimens.xml
@@ -728,6 +728,6 @@
<dimen name="chooser_preview_width">-1px</dimen>
<dimen name="resolver_icon_size">42dp</dimen>
<dimen name="resolver_badge_size">18dp</dimen>
- <dimen name="chooser_target_width">76dp</dimen>
+ <dimen name="chooser_target_width">90dp</dimen>
<dimen name="chooser_max_collapsed_height">288dp</dimen>
</resources>
diff --git a/core/res/res/values/public.xml b/core/res/res/values/public.xml
index 626518c..9a8c754 100644
--- a/core/res/res/values/public.xml
+++ b/core/res/res/values/public.xml
@@ -2945,6 +2945,7 @@
<public name="allowExternalStorageSandbox"/>
<public name="ensuringStatusBarContrastWhenTransparent" />
<public name="ensuringNavigationBarContrastWhenTransparent" />
+ <public name="identifier" />
</public-group>
<public-group type="drawable" first-id="0x010800b4">
@@ -2987,10 +2988,6 @@
<public name="config_defaultDialer" />
<!-- @hide @SystemApi -->
<public name="config_defaultSms" />
- <!-- @hide @SystemApi -->
- <public name="config_defaultMusic" />
- <!-- @hide @SystemApi -->
- <public name="config_defaultGallery" />
</public-group>
<public-group type="bool" first-id="0x01110000">
diff --git a/core/res/res/values/strings.xml b/core/res/res/values/strings.xml
index f8a2ac9..4bd2cc75 100644
--- a/core/res/res/values/strings.xml
+++ b/core/res/res/values/strings.xml
@@ -1521,10 +1521,10 @@
<string name="face_acquired_too_high">Move phone higher.</string>
<!-- Message shown during face acquisition when the user is too low relatively to sensor [CHAR LIMIT=50] -->
<string name="face_acquired_too_low">Move phone lower.</string>
- <!-- Message shown during face acquisition when the user is too right relatively to sensor [CHAR LIMIT=50] -->
- <string name="face_acquired_too_right">Move phone to the right.</string>
- <!-- Message shown during face acquisition when the user is too left relatively to sensor [CHAR LIMIT=50] -->
- <string name="face_acquired_too_left">Move phone to the left.</string>
+ <!-- Message shown during face acquisition when only the right part of the user's face was detected [CHAR LIMIT=50] -->
+ <string name="face_acquired_too_right">Move phone to the left.</string>
+ <!-- Message shown during face acquisition when only the left part of the user's face was detected [CHAR LIMIT=50] -->
+ <string name="face_acquired_too_left">Move phone to the right.</string>
<!-- Message shown during face acquisition when the user is not front facing the sensor [CHAR LIMIT=50] -->
<string name="face_acquired_poor_gaze">Look at the screen with your eyes open.</string>
<!-- Message shown during face acquisition when the user is not detected [CHAR LIMIT=50] -->
diff --git a/core/res/res/values/symbols.xml b/core/res/res/values/symbols.xml
index e9ce6ac..da2f890 100644
--- a/core/res/res/values/symbols.xml
+++ b/core/res/res/values/symbols.xml
@@ -1910,6 +1910,7 @@
<java-symbol type="array" name="config_testLocationProviders" />
<java-symbol type="array" name="config_defaultNotificationVibePattern" />
<java-symbol type="array" name="config_notificationFallbackVibePattern" />
+ <java-symbol type="bool" name="config_enableServerNotificationEffectsForAutomotive" />
<java-symbol type="bool" name="config_useAttentionLight" />
<java-symbol type="bool" name="config_adaptive_sleep_available" />
<java-symbol type="bool" name="config_animateScreenLights" />
@@ -3751,4 +3752,9 @@
<!-- For DropBox -->
<java-symbol type="integer" name="config_dropboxLowPriorityBroadcastRateLimitPeriod" />
<java-symbol type="array" name="config_dropboxLowPriorityTags" />
+
+ <!-- For Privacy Type -->
+ <java-symbol type="drawable" name="perm_group_camera" />
+ <java-symbol type="drawable" name="perm_group_location" />
+ <java-symbol type="drawable" name="perm_group_microphone" />
</resources>
diff --git a/core/tests/overlaytests/host/src/com/android/server/om/hosttest/InstallOverlayTests.java b/core/tests/overlaytests/host/src/com/android/server/om/hosttest/InstallOverlayTests.java
index 99b6421..267cb36 100644
--- a/core/tests/overlaytests/host/src/com/android/server/om/hosttest/InstallOverlayTests.java
+++ b/core/tests/overlaytests/host/src/com/android/server/om/hosttest/InstallOverlayTests.java
@@ -163,6 +163,20 @@
assertTrue(overlayManagerContainsPackage(APP_OVERLAY_PACKAGE_NAME));
}
+ @Test
+ public void changesPersistedWhenUninstallingDisabledOverlay() throws Exception {
+ getDevice().enableAdbRoot();
+ assertFalse(getDevice().executeShellCommand("cat /data/system/overlays.xml")
+ .contains(APP_OVERLAY_PACKAGE_NAME));
+ installPackage("OverlayHostTests_AppOverlayV1.apk");
+ assertTrue(getDevice().executeShellCommand("cat /data/system/overlays.xml")
+ .contains(APP_OVERLAY_PACKAGE_NAME));
+ uninstallPackage(APP_OVERLAY_PACKAGE_NAME);
+ delay();
+ assertFalse(getDevice().executeShellCommand("cat /data/system/overlays.xml")
+ .contains(APP_OVERLAY_PACKAGE_NAME));
+ }
+
private void delay() {
try {
Thread.sleep(1000);
diff --git a/libs/hwui/Properties.cpp b/libs/hwui/Properties.cpp
index 9b1f259..9998854 100644
--- a/libs/hwui/Properties.cpp
+++ b/libs/hwui/Properties.cpp
@@ -17,8 +17,8 @@
#include "Properties.h"
#include "Debug.h"
#include "DeviceInfo.h"
-#include "SkTraceEventCommon.h"
#include "HWUIProperties.sysprop.h"
+#include "SkTraceEventCommon.h"
#include <algorithm>
#include <cstdlib>
@@ -67,7 +67,7 @@
bool Properties::isolatedProcess = false;
int Properties::contextPriority = 0;
-int Properties::defaultRenderAhead = 0;
+uint32_t Properties::defaultRenderAhead = 0;
static int property_get_int(const char* key, int defaultValue) {
char buf[PROPERTY_VALUE_MAX] = {
@@ -130,12 +130,9 @@
enableForceDarkSupport = property_get_bool(PROPERTY_ENABLE_FORCE_DARK, true);
- defaultRenderAhead = std::max(0, std::min(2, property_get_int(PROPERTY_RENDERAHEAD,
- render_ahead().value_or(0))));
-
- if (defaultRenderAhead && sRenderPipelineType == RenderPipelineType::SkiaVulkan) {
- ALOGW("hwui.render_ahead of %d ignored because pipeline is skiavk", defaultRenderAhead);
- }
+ defaultRenderAhead =
+ std::max(0u, std::min(2u, static_cast<uint32_t>(property_get_int(
+ PROPERTY_RENDERAHEAD, render_ahead().value_or(0)))));
return (prevDebugLayersUpdates != debugLayersUpdates) || (prevDebugOverdraw != debugOverdraw);
}
diff --git a/libs/hwui/Properties.h b/libs/hwui/Properties.h
index 3e91c63..3105e58 100644
--- a/libs/hwui/Properties.h
+++ b/libs/hwui/Properties.h
@@ -253,7 +253,7 @@
ANDROID_API static int contextPriority;
- static int defaultRenderAhead;
+ static uint32_t defaultRenderAhead;
private:
static ProfileType sProfileType;
diff --git a/libs/hwui/pipeline/skia/ShaderCache.cpp b/libs/hwui/pipeline/skia/ShaderCache.cpp
index 8508274..66aa8c2 100644
--- a/libs/hwui/pipeline/skia/ShaderCache.cpp
+++ b/libs/hwui/pipeline/skia/ShaderCache.cpp
@@ -15,6 +15,7 @@
*/
#include "ShaderCache.h"
+#include <GrContext.h>
#include <log/log.h>
#include <openssl/sha.h>
#include <algorithm>
@@ -23,7 +24,6 @@
#include "FileBlobCache.h"
#include "Properties.h"
#include "utils/TraceUtils.h"
-#include <GrContext.h>
namespace android {
namespace uirenderer {
diff --git a/libs/hwui/pipeline/skia/SkiaOpenGLPipeline.cpp b/libs/hwui/pipeline/skia/SkiaOpenGLPipeline.cpp
index 570e895..9248ead 100644
--- a/libs/hwui/pipeline/skia/SkiaOpenGLPipeline.cpp
+++ b/libs/hwui/pipeline/skia/SkiaOpenGLPipeline.cpp
@@ -101,7 +101,7 @@
SkiaPipeline::updateLighting(lightGeometry, lightInfo);
renderFrame(*layerUpdateQueue, dirty, renderNodes, opaque, contentDrawBounds, surface,
- SkMatrix::I());
+ SkMatrix::I());
layerUpdateQueue->clear();
// Draw visual debugging features
@@ -156,8 +156,23 @@
}
}
+static void setBufferCount(ANativeWindow* window, uint32_t extraBuffers) {
+ int query_value;
+ int err = window->query(window, NATIVE_WINDOW_MIN_UNDEQUEUED_BUFFERS, &query_value);
+ if (err != 0 || query_value < 0) {
+ ALOGE("window->query failed: %s (%d) value=%d", strerror(-err), err, query_value);
+ return;
+ }
+ auto min_undequeued_buffers = static_cast<uint32_t>(query_value);
+
+ int bufferCount = min_undequeued_buffers + 2 + extraBuffers;
+ ALOGD("Setting buffer count to %d, min_undequeued %u, extraBuffers %u",
+ bufferCount, min_undequeued_buffers, extraBuffers);
+ native_window_set_buffer_count(window, bufferCount);
+}
+
bool SkiaOpenGLPipeline::setSurface(ANativeWindow* surface, SwapBehavior swapBehavior,
- ColorMode colorMode) {
+ ColorMode colorMode, uint32_t extraBuffers) {
if (mEglSurface != EGL_NO_SURFACE) {
mEglManager.destroySurface(mEglSurface);
mEglSurface = EGL_NO_SURFACE;
@@ -177,6 +192,7 @@
if (mEglSurface != EGL_NO_SURFACE) {
const bool preserveBuffer = (swapBehavior != SwapBehavior::kSwap_discardBuffer);
mBufferPreserved = mEglManager.setPreserveBuffer(mEglSurface, preserveBuffer);
+ setBufferCount(surface, extraBuffers);
return true;
}
diff --git a/libs/hwui/pipeline/skia/SkiaOpenGLPipeline.h b/libs/hwui/pipeline/skia/SkiaOpenGLPipeline.h
index 6692922..3fe0f92 100644
--- a/libs/hwui/pipeline/skia/SkiaOpenGLPipeline.h
+++ b/libs/hwui/pipeline/skia/SkiaOpenGLPipeline.h
@@ -44,7 +44,7 @@
FrameInfo* currentFrameInfo, bool* requireSwap) override;
DeferredLayerUpdater* createTextureLayer() override;
bool setSurface(ANativeWindow* surface, renderthread::SwapBehavior swapBehavior,
- renderthread::ColorMode colorMode) override;
+ renderthread::ColorMode colorMode, uint32_t extraBuffers) override;
void onStop() override;
bool isSurfaceReady() override;
bool isContextReady() override;
diff --git a/libs/hwui/pipeline/skia/SkiaPipeline.cpp b/libs/hwui/pipeline/skia/SkiaPipeline.cpp
index 721a115..ccc1701 100644
--- a/libs/hwui/pipeline/skia/SkiaPipeline.cpp
+++ b/libs/hwui/pipeline/skia/SkiaPipeline.cpp
@@ -250,8 +250,9 @@
}
if (mCaptureSequence > 0 || mPictureCapturedCallback) {
mRecorder.reset(new SkPictureRecorder());
- SkCanvas* pictureCanvas = mRecorder->beginRecording(surface->width(), surface->height(), nullptr,
- SkPictureRecorder::kPlaybackDrawPicture_RecordFlag);
+ SkCanvas* pictureCanvas =
+ mRecorder->beginRecording(surface->width(), surface->height(), nullptr,
+ SkPictureRecorder::kPlaybackDrawPicture_RecordFlag);
mNwayCanvas = std::make_unique<SkNWayCanvas>(surface->width(), surface->height());
mNwayCanvas->addCanvas(surface->getCanvas());
mNwayCanvas->addCanvas(pictureCanvas);
@@ -276,8 +277,7 @@
if (1 == mCaptureSequence) {
savePictureAsync(data, mCapturedFile);
} else {
- savePictureAsync(data,
- mCapturedFile + "_" + std::to_string(mCaptureSequence));
+ savePictureAsync(data, mCapturedFile + "_" + std::to_string(mCaptureSequence));
}
mCaptureSequence--;
}
@@ -327,7 +327,7 @@
auto& props = node.properties();
return Rect(props.getLeft(), props.getTop(), props.getRight(), props.getBottom());
}
-}
+} // namespace
void SkiaPipeline::renderFrameImpl(const LayerUpdateQueue& layers, const SkRect& clip,
const std::vector<sp<RenderNode>>& nodes, bool opaque,
@@ -464,10 +464,20 @@
// (3) Requires RGBA colors (instead of BGRA).
static const uint32_t kOverdrawColors[2][6] = {
{
- 0x00000000, 0x00000000, 0x2f2f0000, 0x2f002f00, 0x3f00003f, 0x7f00007f,
+ 0x00000000,
+ 0x00000000,
+ 0x2f2f0000,
+ 0x2f002f00,
+ 0x3f00003f,
+ 0x7f00007f,
},
{
- 0x00000000, 0x00000000, 0x2f2f0000, 0x4f004f4f, 0x5f50335f, 0x7f00007f,
+ 0x00000000,
+ 0x00000000,
+ 0x2f2f0000,
+ 0x4f004f4f,
+ 0x5f50335f,
+ 0x7f00007f,
},
};
diff --git a/libs/hwui/pipeline/skia/SkiaRecordingCanvas.cpp b/libs/hwui/pipeline/skia/SkiaRecordingCanvas.cpp
index d945635..5a47a29 100644
--- a/libs/hwui/pipeline/skia/SkiaRecordingCanvas.cpp
+++ b/libs/hwui/pipeline/skia/SkiaRecordingCanvas.cpp
@@ -142,8 +142,7 @@
void SkiaRecordingCanvas::drawWebViewFunctor(int functor) {
FunctorDrawable* functorDrawable;
if (Properties::getRenderPipelineType() == RenderPipelineType::SkiaVulkan) {
- functorDrawable =
- mDisplayList->allocateDrawable<VkFunctorDrawable>(functor, asSkCanvas());
+ functorDrawable = mDisplayList->allocateDrawable<VkFunctorDrawable>(functor, asSkCanvas());
} else {
functorDrawable = mDisplayList->allocateDrawable<GLFunctorDrawable>(functor, asSkCanvas());
}
diff --git a/libs/hwui/pipeline/skia/SkiaVulkanPipeline.cpp b/libs/hwui/pipeline/skia/SkiaVulkanPipeline.cpp
index edde6d3..e8cb219 100644
--- a/libs/hwui/pipeline/skia/SkiaVulkanPipeline.cpp
+++ b/libs/hwui/pipeline/skia/SkiaVulkanPipeline.cpp
@@ -18,12 +18,12 @@
#include "DeferredLayerUpdater.h"
#include "Readback.h"
+#include "ShaderCache.h"
#include "SkiaPipeline.h"
#include "SkiaProfileRenderer.h"
#include "VkInteropFunctorDrawable.h"
#include "renderstate/RenderState.h"
#include "renderthread/Frame.h"
-#include "ShaderCache.h"
#include <SkSurface.h>
#include <SkTypes.h>
@@ -70,8 +70,8 @@
return false;
}
SkiaPipeline::updateLighting(lightGeometry, lightInfo);
- renderFrame(*layerUpdateQueue, dirty, renderNodes, opaque, contentDrawBounds,
- backBuffer, mVkSurface->getCurrentPreTransform());
+ renderFrame(*layerUpdateQueue, dirty, renderNodes, opaque, contentDrawBounds, backBuffer,
+ mVkSurface->getCurrentPreTransform());
ShaderCache::get().onVkFrameFlushed(mRenderThread.getGrContext());
layerUpdateQueue->clear();
@@ -116,7 +116,7 @@
void SkiaVulkanPipeline::onStop() {}
bool SkiaVulkanPipeline::setSurface(ANativeWindow* surface, SwapBehavior swapBehavior,
- ColorMode colorMode) {
+ ColorMode colorMode, uint32_t extraBuffers) {
if (mVkSurface) {
mVkManager.destroySurface(mVkSurface);
mVkSurface = nullptr;
@@ -125,8 +125,9 @@
setSurfaceColorProperties(colorMode);
if (surface) {
mRenderThread.requireVkContext();
- mVkSurface = mVkManager.createSurface(surface, colorMode, mSurfaceColorSpace,
- mSurfaceColorType, mRenderThread.getGrContext());
+ mVkSurface =
+ mVkManager.createSurface(surface, colorMode, mSurfaceColorSpace, mSurfaceColorType,
+ mRenderThread.getGrContext(), extraBuffers);
}
return mVkSurface != nullptr;
diff --git a/libs/hwui/pipeline/skia/SkiaVulkanPipeline.h b/libs/hwui/pipeline/skia/SkiaVulkanPipeline.h
index 77a7ab1..3173478 100644
--- a/libs/hwui/pipeline/skia/SkiaVulkanPipeline.h
+++ b/libs/hwui/pipeline/skia/SkiaVulkanPipeline.h
@@ -43,7 +43,7 @@
FrameInfo* currentFrameInfo, bool* requireSwap) override;
DeferredLayerUpdater* createTextureLayer() override;
bool setSurface(ANativeWindow* surface, renderthread::SwapBehavior swapBehavior,
- renderthread::ColorMode colorMode) override;
+ renderthread::ColorMode colorMode, uint32_t extraBuffers) override;
void onStop() override;
bool isSurfaceReady() override;
bool isContextReady() override;
diff --git a/libs/hwui/pipeline/skia/VkFunctorDrawable.cpp b/libs/hwui/pipeline/skia/VkFunctorDrawable.cpp
index 1b9e53b..1127926 100644
--- a/libs/hwui/pipeline/skia/VkFunctorDrawable.cpp
+++ b/libs/hwui/pipeline/skia/VkFunctorDrawable.cpp
@@ -17,16 +17,16 @@
#include "VkFunctorDrawable.h"
#include <private/hwui/DrawVkInfo.h>
-#include "renderthread/VulkanManager.h"
-#include "renderthread/RenderThread.h"
-#include <SkAndroidFrameworkUtils.h>
#include <GrBackendDrawableInfo.h>
+#include <SkAndroidFrameworkUtils.h>
#include <SkImage.h>
#include <utils/Color.h>
#include <utils/Trace.h>
#include <utils/TraceUtils.h>
#include <vk/GrVkTypes.h>
#include <thread>
+#include "renderthread/RenderThread.h"
+#include "renderthread/VulkanManager.h"
#include "thread/ThreadBase.h"
#include "utils/TimeUtils.h"
@@ -64,13 +64,13 @@
SkMatrix44 mat4(mMatrix);
VkFunctorDrawParams params{
- .width = mImageInfo.width(),
- .height = mImageInfo.height(),
- .color_space_ptr = mImageInfo.colorSpace(),
- .clip_left = mClip.fLeft,
- .clip_top = mClip.fTop,
- .clip_right = mClip.fRight,
- .clip_bottom = mClip.fBottom,
+ .width = mImageInfo.width(),
+ .height = mImageInfo.height(),
+ .color_space_ptr = mImageInfo.colorSpace(),
+ .clip_left = mClip.fLeft,
+ .clip_top = mClip.fTop,
+ .clip_right = mClip.fRight,
+ .clip_bottom = mClip.fBottom,
};
mat4.asColMajorf(¶ms.transform[0]);
params.secondary_command_buffer = vulkan_info.fSecondaryCommandBuffer;
@@ -87,8 +87,7 @@
vulkan_info.fDrawBounds->extent.height = mClip.fBottom - mClip.fTop;
}
-VkFunctorDrawable::~VkFunctorDrawable() {
-}
+VkFunctorDrawable::~VkFunctorDrawable() {}
void VkFunctorDrawable::onDraw(SkCanvas* canvas) {
// "canvas" is either SkNWayCanvas created by SkiaPipeline::tryCapture (SKP capture use case) or
@@ -106,9 +105,8 @@
SkCanvas* gpuCanvas = SkAndroidFrameworkUtils::getBaseWrappedCanvas(canvas);
// Enforce "canvas" must be an AlphaFilterCanvas. For GPU canvas, the call should come from
// onSnapGpuDrawHandler.
- LOG_ALWAYS_FATAL_IF(
- gpuCanvas == canvas,
- "VkFunctorDrawable::onDraw() should not be called with a GPU canvas!");
+ LOG_ALWAYS_FATAL_IF(gpuCanvas == canvas,
+ "VkFunctorDrawable::onDraw() should not be called with a GPU canvas!");
// This will invoke onSnapGpuDrawHandler and regular draw flow.
gpuCanvas->drawDrawable(this);
diff --git a/libs/hwui/renderthread/CacheManager.cpp b/libs/hwui/renderthread/CacheManager.cpp
index 8b02c11..a31081c 100644
--- a/libs/hwui/renderthread/CacheManager.cpp
+++ b/libs/hwui/renderthread/CacheManager.cpp
@@ -21,17 +21,16 @@
#include "RenderThread.h"
#include "pipeline/skia/ShaderCache.h"
#include "pipeline/skia/SkiaMemoryTracer.h"
-#include "Properties.h"
#include "renderstate/RenderState.h"
#include "thread/CommonPool.h"
#include <GrContextOptions.h>
#include <SkExecutor.h>
#include <SkGraphics.h>
+#include <SkMathPriv.h>
#include <gui/Surface.h>
#include <math.h>
#include <set>
-#include <SkMathPriv.h>
namespace android {
namespace uirenderer {
@@ -79,14 +78,13 @@
class CommonPoolExecutor : public SkExecutor {
public:
- virtual void add(std::function<void(void)> func) override {
- CommonPool::post(std::move(func));
- }
+ virtual void add(std::function<void(void)> func) override { CommonPool::post(std::move(func)); }
};
static CommonPoolExecutor sDefaultExecutor;
-void CacheManager::configureContext(GrContextOptions* contextOptions, const void* identity, ssize_t size) {
+void CacheManager::configureContext(GrContextOptions* contextOptions, const void* identity,
+ ssize_t size) {
contextOptions->fAllowPathMaskCaching = true;
// This sets the maximum size for a single texture atlas in the GPU font cache. If necessary,
@@ -180,7 +178,8 @@
}
const char* layerType = Properties::getRenderPipelineType() == RenderPipelineType::SkiaGL
- ? "GlLayer" : "VkLayer";
+ ? "GlLayer"
+ : "VkLayer";
size_t layerMemoryTotal = 0;
for (std::set<Layer*>::iterator it = renderState->mActiveLayers.begin();
it != renderState->mActiveLayers.end(); it++) {
diff --git a/libs/hwui/renderthread/CanvasContext.cpp b/libs/hwui/renderthread/CanvasContext.cpp
index 4808d68..1b3bd30 100644
--- a/libs/hwui/renderthread/CanvasContext.cpp
+++ b/libs/hwui/renderthread/CanvasContext.cpp
@@ -17,6 +17,7 @@
#include "CanvasContext.h"
#include <GpuMemoryTracker.h>
+#include "../Properties.h"
#include "AnimationContext.h"
#include "EglManager.h"
#include "Frame.h"
@@ -31,7 +32,6 @@
#include "utils/GLUtils.h"
#include "utils/TimeUtils.h"
#include "utils/TraceUtils.h"
-#include "../Properties.h"
#include <cutils/properties.h>
#include <private/hwui/DrawGlInfo.h>
@@ -153,7 +153,8 @@
}
ColorMode colorMode = mWideColorGamut ? ColorMode::WideColorGamut : ColorMode::SRGB;
- bool hasSurface = mRenderPipeline->setSurface(mNativeSurface.get(), mSwapBehavior, colorMode);
+ bool hasSurface = mRenderPipeline->setSurface(mNativeSurface.get(), mSwapBehavior, colorMode,
+ mRenderAheadDepth);
mFrameNumber = -1;
@@ -298,7 +299,7 @@
mAnimationContext->startFrame(info.mode);
mRenderPipeline->onPrepareTree();
- for (const sp<RenderNode> &node : mRenderNodes) {
+ for (const sp<RenderNode>& node : mRenderNodes) {
// Only the primary target node will be drawn full - all other nodes would get drawn in
// real time mode. In case of a window, the primary node is the window content and the other
// node(s) are non client / filler nodes.
@@ -322,7 +323,7 @@
if (CC_LIKELY(mSwapHistory.size() && !Properties::forceDrawFrame)) {
nsecs_t latestVsync = mRenderThread.timeLord().latestVsync();
- SwapHistory &lastSwap = mSwapHistory.back();
+ SwapHistory& lastSwap = mSwapHistory.back();
nsecs_t vsyncDelta = std::abs(lastSwap.vsyncTime - latestVsync);
// The slight fudge-factor is to deal with cases where
// the vsync was estimated due to being slow handling the signal.
@@ -405,8 +406,7 @@
SkRect dirty;
mDamageAccumulator.finish(&dirty);
- if (dirty.isEmpty() && Properties::skipEmptyFrames
- && !surfaceRequiresRedraw()) {
+ if (dirty.isEmpty() && Properties::skipEmptyFrames && !surfaceRequiresRedraw()) {
mCurrentFrameInfo->addFlag(FrameInfoFlags::SkippedFrame);
return;
}
@@ -416,21 +416,21 @@
Frame frame = mRenderPipeline->getFrame();
SkRect windowDirty = computeDirtyRect(frame, &dirty);
+ if (mRenderAheadDepth) {
+ auto presentTime =
+ mCurrentFrameInfo->get(FrameInfoIndex::Vsync) +
+ (mRenderThread.timeLord().frameIntervalNanos() * (mRenderAheadDepth + 1));
+ native_window_set_buffers_timestamp(mNativeSurface.get(), presentTime);
+ }
bool drew = mRenderPipeline->draw(frame, windowDirty, dirty, mLightGeometry, &mLayerUpdateQueue,
- mContentDrawBounds, mOpaque, mLightInfo,
- mRenderNodes, &(profiler()));
+ mContentDrawBounds, mOpaque, mLightInfo, mRenderNodes,
+ &(profiler()));
int64_t frameCompleteNr = mFrameCompleteCallbacks.size() ? getFrameNumber() : -1;
waitOnFences();
- if (mRenderAheadDepth) {
- auto presentTime = mCurrentFrameInfo->get(FrameInfoIndex::Vsync) +
- (mRenderThread.timeLord().frameIntervalNanos() * (mRenderAheadDepth + 1));
- native_window_set_buffers_timestamp(mNativeSurface.get(), presentTime);
- }
-
bool requireSwap = false;
bool didSwap =
mRenderPipeline->swapBuffers(frame, drew, windowDirty, mCurrentFrameInfo, &requireSwap);
@@ -645,21 +645,13 @@
}
void CanvasContext::applyRenderAheadSettings() {
- if (Properties::getRenderPipelineType() == RenderPipelineType::SkiaVulkan) {
- // TODO: Fix SkiaVulkan's assumptions on buffer counts. And SIGBUS crashes.
- mRenderAheadDepth = 0;
- return;
- }
- if (mNativeSurface) {
- native_window_set_buffer_count(mNativeSurface.get(), 3 + mRenderAheadDepth);
- if (!mRenderAheadDepth) {
- native_window_set_buffers_timestamp(mNativeSurface.get(), NATIVE_WINDOW_TIMESTAMP_AUTO);
- }
+ if (mNativeSurface && !mRenderAheadDepth) {
+ native_window_set_buffers_timestamp(mNativeSurface.get(), NATIVE_WINDOW_TIMESTAMP_AUTO);
}
}
-void CanvasContext::setRenderAheadDepth(int renderAhead) {
- if (renderAhead < 0 || renderAhead > 2 || renderAhead == mRenderAheadDepth) {
+void CanvasContext::setRenderAheadDepth(uint32_t renderAhead) {
+ if (renderAhead > 2 || renderAhead == mRenderAheadDepth || mNativeSurface) {
return;
}
mRenderAheadDepth = renderAhead;
diff --git a/libs/hwui/renderthread/CanvasContext.h b/libs/hwui/renderthread/CanvasContext.h
index 4a3119a..0bd080d 100644
--- a/libs/hwui/renderthread/CanvasContext.h
+++ b/libs/hwui/renderthread/CanvasContext.h
@@ -17,15 +17,15 @@
#pragma once
#include "DamageAccumulator.h"
-#include "Lighting.h"
#include "FrameInfo.h"
#include "FrameInfoVisualizer.h"
#include "FrameMetricsReporter.h"
#include "IContextFactory.h"
#include "IRenderPipeline.h"
#include "LayerUpdateQueue.h"
-#include "RenderNode.h"
+#include "Lighting.h"
#include "ReliableSurface.h"
+#include "RenderNode.h"
#include "renderthread/RenderTask.h"
#include "renderthread/RenderThread.h"
@@ -37,10 +37,10 @@
#include <utils/Functor.h>
#include <functional>
+#include <future>
#include <set>
#include <string>
#include <vector>
-#include <future>
namespace android {
namespace uirenderer {
@@ -187,9 +187,7 @@
mRenderPipeline->setPictureCapturedCallback(callback);
}
- void setForceDark(bool enable) {
- mUseForceDark = enable;
- }
+ void setForceDark(bool enable) { mUseForceDark = enable; }
bool useForceDark() {
// The force-dark override has the highest priority, followed by the disable setting
@@ -204,7 +202,8 @@
return mUseForceDark;
}
- void setRenderAheadDepth(int renderAhead);
+ // Must be called before setSurface
+ void setRenderAheadDepth(uint32_t renderAhead);
private:
CanvasContext(RenderThread& thread, bool translucent, RenderNode* rootRenderNode,
@@ -238,7 +237,7 @@
// painted onto its surface.
bool mIsDirty = false;
SwapBehavior mSwapBehavior = SwapBehavior::kSwap_default;
- int mRenderAheadDepth = 0;
+ uint32_t mRenderAheadDepth = 0;
struct SwapHistory {
SkRect damage;
nsecs_t vsyncTime;
diff --git a/libs/hwui/renderthread/DrawFrameTask.cpp b/libs/hwui/renderthread/DrawFrameTask.cpp
index 51eeab7..91dc3bc 100644
--- a/libs/hwui/renderthread/DrawFrameTask.cpp
+++ b/libs/hwui/renderthread/DrawFrameTask.cpp
@@ -109,9 +109,8 @@
// Even if we aren't drawing this vsync pulse the next frame number will still be accurate
if (CC_UNLIKELY(callback)) {
- context->enqueueFrameWork([callback, frameNr = context->getFrameNumber()]() {
- callback(frameNr);
- });
+ context->enqueueFrameWork(
+ [callback, frameNr = context->getFrameNumber()]() { callback(frameNr); });
}
if (CC_LIKELY(canDrawThisFrame)) {
diff --git a/libs/hwui/renderthread/EglManager.cpp b/libs/hwui/renderthread/EglManager.cpp
index 2cc3f36..1d55334 100644
--- a/libs/hwui/renderthread/EglManager.cpp
+++ b/libs/hwui/renderthread/EglManager.cpp
@@ -29,10 +29,10 @@
#include <EGL/eglext.h>
#include <GLES/gl.h>
+#include <gui/Surface.h>
+#include <system/window.h>
#include <string>
#include <vector>
-#include <system/window.h>
-#include <gui/Surface.h>
#define GLES_VERSION 2
@@ -171,8 +171,7 @@
EGL_NONE};
EGLConfig config = EGL_NO_CONFIG_KHR;
EGLint numConfigs = 1;
- if (!eglChooseConfig(display, attribs, &config, numConfigs, &numConfigs) ||
- numConfigs != 1) {
+ if (!eglChooseConfig(display, attribs, &config, numConfigs, &numConfigs) || numConfigs != 1) {
return EGL_NO_CONFIG_KHR;
}
return config;
@@ -203,8 +202,7 @@
EGL_NONE};
EGLConfig config = EGL_NO_CONFIG_KHR;
EGLint numConfigs = 1;
- if (!eglChooseConfig(display, attribs, &config, numConfigs, &numConfigs) ||
- numConfigs != 1) {
+ if (!eglChooseConfig(display, attribs, &config, numConfigs, &numConfigs) || numConfigs != 1) {
return EGL_NO_CONFIG_KHR;
}
return config;
@@ -262,7 +260,7 @@
mEglConfigWideGamut = loadFP16Config(mEglDisplay, mSwapBehavior);
if (mEglConfigWideGamut == EGL_NO_CONFIG_KHR) {
ALOGE("Device claims wide gamut support, cannot find matching config, error = %s",
- eglErrorString());
+ eglErrorString());
EglExtensions.pixelFormatFloat = false;
}
} else if (wideColorType == SkColorType::kN32_SkColorType) {
@@ -350,7 +348,7 @@
EGLSurface surface = eglCreateWindowSurface(
mEglDisplay, wideColorGamut ? mEglConfigWideGamut : mEglConfig, window, attribs);
if (surface == EGL_NO_SURFACE) {
- return Error<EGLint> { eglGetError() };
+ return Error<EGLint>{eglGetError()};
}
if (mSwapBehavior != SwapBehavior::Preserved) {
@@ -525,12 +523,8 @@
ALOGE("EglManager::fenceWait: error dup'ing fence fd: %d", errno);
return -errno;
}
- EGLint attribs[] = {
- EGL_SYNC_NATIVE_FENCE_FD_ANDROID, fenceFd,
- EGL_NONE
- };
- EGLSyncKHR sync = eglCreateSyncKHR(mEglDisplay,
- EGL_SYNC_NATIVE_FENCE_ANDROID, attribs);
+ EGLint attribs[] = {EGL_SYNC_NATIVE_FENCE_FD_ANDROID, fenceFd, EGL_NONE};
+ EGLSyncKHR sync = eglCreateSyncKHR(mEglDisplay, EGL_SYNC_NATIVE_FENCE_ANDROID, attribs);
if (sync == EGL_NO_SYNC_KHR) {
close(fenceFd);
ALOGE("EglManager::fenceWait: error creating EGL fence: %#x", eglGetError());
@@ -559,18 +553,16 @@
}
status_t EglManager::createReleaseFence(bool useFenceSync, EGLSyncKHR* eglFence,
- sp<Fence>& nativeFence) {
+ sp<Fence>& nativeFence) {
if (!hasEglContext()) {
ALOGE("EglManager::createReleaseFence: EGLDisplay not initialized");
return INVALID_OPERATION;
}
if (SyncFeatures::getInstance().useNativeFenceSync()) {
- EGLSyncKHR sync = eglCreateSyncKHR(mEglDisplay,
- EGL_SYNC_NATIVE_FENCE_ANDROID, nullptr);
+ EGLSyncKHR sync = eglCreateSyncKHR(mEglDisplay, EGL_SYNC_NATIVE_FENCE_ANDROID, nullptr);
if (sync == EGL_NO_SYNC_KHR) {
- ALOGE("EglManager::createReleaseFence: error creating EGL fence: %#x",
- eglGetError());
+ ALOGE("EglManager::createReleaseFence: error creating EGL fence: %#x", eglGetError());
return UNKNOWN_ERROR;
}
glFlush();
@@ -578,7 +570,8 @@
eglDestroySyncKHR(mEglDisplay, sync);
if (fenceFd == EGL_NO_NATIVE_FENCE_FD_ANDROID) {
ALOGE("EglManager::createReleaseFence: error dup'ing native fence "
- "fd: %#x", eglGetError());
+ "fd: %#x",
+ eglGetError());
return UNKNOWN_ERROR;
}
nativeFence = new Fence(fenceFd);
@@ -592,7 +585,7 @@
EGLint result = eglClientWaitSyncKHR(mEglDisplay, *eglFence, 0, 1000000000);
if (result == EGL_FALSE) {
ALOGE("EglManager::createReleaseFence: error waiting for previous fence: %#x",
- eglGetError());
+ eglGetError());
return UNKNOWN_ERROR;
} else if (result == EGL_TIMEOUT_EXPIRED_KHR) {
ALOGE("EglManager::createReleaseFence: timeout waiting for previous fence");
diff --git a/libs/hwui/renderthread/IRenderPipeline.h b/libs/hwui/renderthread/IRenderPipeline.h
index 0502eb8..3b81014 100644
--- a/libs/hwui/renderthread/IRenderPipeline.h
+++ b/libs/hwui/renderthread/IRenderPipeline.h
@@ -66,8 +66,8 @@
virtual bool swapBuffers(const Frame& frame, bool drew, const SkRect& screenDirty,
FrameInfo* currentFrameInfo, bool* requireSwap) = 0;
virtual DeferredLayerUpdater* createTextureLayer() = 0;
- virtual bool setSurface(ANativeWindow* window, SwapBehavior swapBehavior,
- ColorMode colorMode) = 0;
+ virtual bool setSurface(ANativeWindow* window, SwapBehavior swapBehavior, ColorMode colorMode,
+ uint32_t extraBuffers) = 0;
virtual void onStop() = 0;
virtual bool isSurfaceReady() = 0;
virtual bool isContextReady() = 0;
diff --git a/libs/hwui/renderthread/ReliableSurface.cpp b/libs/hwui/renderthread/ReliableSurface.cpp
index 6f2b9df..b9410c2 100644
--- a/libs/hwui/renderthread/ReliableSurface.cpp
+++ b/libs/hwui/renderthread/ReliableSurface.cpp
@@ -34,13 +34,13 @@
// Make warnings happy
SurfaceExposer() = delete;
- using Surface::setBufferCount;
- using Surface::setSwapInterval;
- using Surface::dequeueBuffer;
- using Surface::queueBuffer;
using Surface::cancelBuffer;
+ using Surface::dequeueBuffer;
using Surface::lockBuffer_DEPRECATED;
using Surface::perform;
+ using Surface::queueBuffer;
+ using Surface::setBufferCount;
+ using Surface::setSwapInterval;
};
#define callProtected(surface, func, ...) ((*surface).*&SurfaceExposer::func)(__VA_ARGS__)
diff --git a/libs/hwui/renderthread/RenderProxy.cpp b/libs/hwui/renderthread/RenderProxy.cpp
index b58bab1..1a1b9da 100644
--- a/libs/hwui/renderthread/RenderProxy.cpp
+++ b/libs/hwui/renderthread/RenderProxy.cpp
@@ -84,7 +84,7 @@
void RenderProxy::setSurface(const sp<Surface>& surface) {
mRenderThread.queue().post(
- [ this, surf = surface ]() mutable { mContext->setSurface(std::move(surf)); });
+ [this, surf = surface]() mutable { mContext->setSurface(std::move(surf)); });
}
void RenderProxy::allocateBuffers() {
@@ -251,7 +251,7 @@
void RenderProxy::setProcessStatsBuffer(int fd) {
auto& rt = RenderThread::getInstance();
- rt.queue().post([&rt, fd = dup(fd) ]() {
+ rt.queue().post([&rt, fd = dup(fd)]() {
rt.globalProfileData().switchStorageToAshmem(fd);
close(fd);
});
@@ -285,7 +285,7 @@
void RenderProxy::setPictureCapturedCallback(
const std::function<void(sk_sp<SkPicture>&&)>& callback) {
mRenderThread.queue().post(
- [ this, cb = callback ]() { mContext->setPictureCapturedCallback(cb); });
+ [this, cb = callback]() { mContext->setPictureCapturedCallback(cb); });
}
void RenderProxy::setFrameCallback(std::function<void(int64_t)>&& callback) {
@@ -297,13 +297,13 @@
}
void RenderProxy::addFrameMetricsObserver(FrameMetricsObserver* observerPtr) {
- mRenderThread.queue().post([ this, observer = sp{observerPtr} ]() {
+ mRenderThread.queue().post([this, observer = sp{observerPtr}]() {
mContext->addFrameMetricsObserver(observer.get());
});
}
void RenderProxy::removeFrameMetricsObserver(FrameMetricsObserver* observerPtr) {
- mRenderThread.queue().post([ this, observer = sp{observerPtr} ]() {
+ mRenderThread.queue().post([this, observer = sp{observerPtr}]() {
mContext->removeFrameMetricsObserver(observer.get());
});
}
@@ -313,9 +313,8 @@
}
void RenderProxy::setRenderAheadDepth(int renderAhead) {
- mRenderThread.queue().post([ context = mContext, renderAhead ] {
- context->setRenderAheadDepth(renderAhead);
- });
+ mRenderThread.queue().post(
+ [context = mContext, renderAhead] { context->setRenderAheadDepth(renderAhead); });
}
int RenderProxy::copySurfaceInto(sp<Surface>& surface, int left, int top, int right, int bottom,
@@ -393,9 +392,7 @@
void RenderProxy::preload() {
// Create RenderThread object and start the thread. Then preload Vulkan/EGL driver.
auto& thread = RenderThread::getInstance();
- thread.queue().post([&thread]() {
- thread.preload();
- });
+ thread.queue().post([&thread]() { thread.preload(); });
}
} /* namespace renderthread */
diff --git a/libs/hwui/renderthread/RenderThread.cpp b/libs/hwui/renderthread/RenderThread.cpp
index b76e49c..eca7d88 100644
--- a/libs/hwui/renderthread/RenderThread.cpp
+++ b/libs/hwui/renderthread/RenderThread.cpp
@@ -16,6 +16,7 @@
#include "RenderThread.h"
+#include "../HardwareBitmapUploader.h"
#include "CanvasContext.h"
#include "DeviceInfo.h"
#include "EglManager.h"
@@ -29,7 +30,6 @@
#include "utils/FatVector.h"
#include "utils/TimeUtils.h"
#include "utils/TraceUtils.h"
-#include "../HardwareBitmapUploader.h"
#ifdef HWUI_GLES_WRAP_ENABLED
#include "debug/GlesDriver.h"
@@ -410,9 +410,7 @@
void RenderThread::preload() {
// EGL driver is always preloaded only if HWUI renders with GL.
if (Properties::getRenderPipelineType() == RenderPipelineType::SkiaGL) {
- std::thread eglInitThread([]() {
- eglGetDisplay(EGL_DEFAULT_DISPLAY);
- });
+ std::thread eglInitThread([]() { eglGetDisplay(EGL_DEFAULT_DISPLAY); });
eglInitThread.detach();
} else {
requireVkContext();
diff --git a/libs/hwui/renderthread/RenderThread.h b/libs/hwui/renderthread/RenderThread.h
index 5f43b48..6bb26fd 100644
--- a/libs/hwui/renderthread/RenderThread.h
+++ b/libs/hwui/renderthread/RenderThread.h
@@ -22,8 +22,8 @@
#include "../JankTracker.h"
#include "CacheManager.h"
#include "TimeLord.h"
-#include "thread/ThreadBase.h"
#include "WebViewFunctorManager.h"
+#include "thread/ThreadBase.h"
#include "utils/TimeUtils.h"
#include <GrContext.h>
diff --git a/libs/hwui/renderthread/VulkanManager.cpp b/libs/hwui/renderthread/VulkanManager.cpp
index 4011329..5edf330 100644
--- a/libs/hwui/renderthread/VulkanManager.cpp
+++ b/libs/hwui/renderthread/VulkanManager.cpp
@@ -29,7 +29,6 @@
#include <GrBackendSurface.h>
#include <GrContext.h>
#include <GrTypes.h>
-#include <GrTypes.h>
#include <vk/GrVkExtensions.h>
#include <vk/GrVkTypes.h>
@@ -43,7 +42,7 @@
// so we can get access to the pNext for the next struct.
struct CommonVulkanHeader {
VkStructureType sType;
- void* pNext;
+ void* pNext;
};
void* pNext = features.pNext;
@@ -94,13 +93,13 @@
VkResult err;
constexpr VkApplicationInfo app_info = {
- VK_STRUCTURE_TYPE_APPLICATION_INFO, // sType
- nullptr, // pNext
- "android framework", // pApplicationName
- 0, // applicationVersion
- "android framework", // pEngineName
- 0, // engineVerison
- mAPIVersion, // apiVersion
+ VK_STRUCTURE_TYPE_APPLICATION_INFO, // sType
+ nullptr, // pNext
+ "android framework", // pApplicationName
+ 0, // applicationVersion
+ "android framework", // pEngineName
+ 0, // engineVerison
+ mAPIVersion, // apiVersion
};
{
@@ -128,14 +127,14 @@
}
const VkInstanceCreateInfo instance_create = {
- VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO, // sType
- nullptr, // pNext
- 0, // flags
- &app_info, // pApplicationInfo
- 0, // enabledLayerNameCount
- nullptr, // ppEnabledLayerNames
- (uint32_t) mInstanceExtensions.size(), // enabledExtensionNameCount
- mInstanceExtensions.data(), // ppEnabledExtensionNames
+ VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO, // sType
+ nullptr, // pNext
+ 0, // flags
+ &app_info, // pApplicationInfo
+ 0, // enabledLayerNameCount
+ nullptr, // ppEnabledLayerNames
+ (uint32_t)mInstanceExtensions.size(), // enabledExtensionNameCount
+ mInstanceExtensions.data(), // ppEnabledExtensionNames
};
GET_PROC(CreateInstance);
@@ -200,11 +199,11 @@
{
uint32_t extensionCount = 0;
err = mEnumerateDeviceExtensionProperties(mPhysicalDevice, nullptr, &extensionCount,
- nullptr);
+ nullptr);
LOG_ALWAYS_FATAL_IF(VK_SUCCESS != err);
mDeviceExtensionsOwner.resize(extensionCount);
err = mEnumerateDeviceExtensionProperties(mPhysicalDevice, nullptr, &extensionCount,
- mDeviceExtensionsOwner.data());
+ mDeviceExtensionsOwner.data());
LOG_ALWAYS_FATAL_IF(VK_SUCCESS != err);
bool hasKHRSwapchainExtension = false;
for (const VkExtensionProperties& extension : mDeviceExtensionsOwner) {
@@ -216,7 +215,7 @@
LOG_ALWAYS_FATAL_IF(!hasKHRSwapchainExtension);
}
- auto getProc = [] (const char* proc_name, VkInstance instance, VkDevice device) {
+ auto getProc = [](const char* proc_name, VkInstance instance, VkDevice device) {
if (device != VK_NULL_HANDLE) {
return vkGetDeviceProcAddr(device, proc_name);
}
@@ -224,7 +223,8 @@
};
grExtensions.init(getProc, mInstance, mPhysicalDevice, mInstanceExtensions.size(),
- mInstanceExtensions.data(), mDeviceExtensions.size(), mDeviceExtensions.data());
+ mInstanceExtensions.data(), mDeviceExtensions.size(),
+ mDeviceExtensions.data());
LOG_ALWAYS_FATAL_IF(!grExtensions.hasExtension(VK_KHR_EXTERNAL_SEMAPHORE_FD_EXTENSION_NAME, 1));
@@ -237,7 +237,7 @@
if (grExtensions.hasExtension(VK_EXT_BLEND_OPERATION_ADVANCED_EXTENSION_NAME, 2)) {
VkPhysicalDeviceBlendOperationAdvancedFeaturesEXT* blend;
- blend = (VkPhysicalDeviceBlendOperationAdvancedFeaturesEXT*) malloc(
+ blend = (VkPhysicalDeviceBlendOperationAdvancedFeaturesEXT*)malloc(
sizeof(VkPhysicalDeviceBlendOperationAdvancedFeaturesEXT));
LOG_ALWAYS_FATAL_IF(!blend);
blend->sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_BLEND_OPERATION_ADVANCED_FEATURES_EXT;
@@ -247,7 +247,7 @@
}
VkPhysicalDeviceSamplerYcbcrConversionFeatures* ycbcrFeature;
- ycbcrFeature = (VkPhysicalDeviceSamplerYcbcrConversionFeatures*) malloc(
+ ycbcrFeature = (VkPhysicalDeviceSamplerYcbcrConversionFeatures*)malloc(
sizeof(VkPhysicalDeviceSamplerYcbcrConversionFeatures));
LOG_ALWAYS_FATAL_IF(!ycbcrFeature);
ycbcrFeature->sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SAMPLER_YCBCR_CONVERSION_FEATURES;
@@ -261,17 +261,17 @@
// and we can't depend on it on all platforms
features.features.robustBufferAccess = VK_FALSE;
- float queuePriorities[1] = { 0.0 };
+ float queuePriorities[1] = {0.0};
void* queueNextPtr = nullptr;
VkDeviceQueueGlobalPriorityCreateInfoEXT queuePriorityCreateInfo;
- if (Properties::contextPriority != 0
- && grExtensions.hasExtension(VK_EXT_GLOBAL_PRIORITY_EXTENSION_NAME, 2)) {
+ if (Properties::contextPriority != 0 &&
+ grExtensions.hasExtension(VK_EXT_GLOBAL_PRIORITY_EXTENSION_NAME, 2)) {
memset(&queuePriorityCreateInfo, 0, sizeof(VkDeviceQueueGlobalPriorityCreateInfoEXT));
queuePriorityCreateInfo.sType =
- VK_STRUCTURE_TYPE_DEVICE_QUEUE_GLOBAL_PRIORITY_CREATE_INFO_EXT;
+ VK_STRUCTURE_TYPE_DEVICE_QUEUE_GLOBAL_PRIORITY_CREATE_INFO_EXT;
queuePriorityCreateInfo.pNext = nullptr;
switch (Properties::contextPriority) {
case EGL_CONTEXT_PRIORITY_LOW_IMG:
@@ -285,41 +285,40 @@
break;
default:
LOG_ALWAYS_FATAL("Unsupported context priority");
- }
- queueNextPtr = &queuePriorityCreateInfo;
+ }
+ queueNextPtr = &queuePriorityCreateInfo;
}
const VkDeviceQueueCreateInfo queueInfo[2] = {
- {
- VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO, // sType
- queueNextPtr, // pNext
- 0, // VkDeviceQueueCreateFlags
- mGraphicsQueueIndex, // queueFamilyIndex
- 1, // queueCount
- queuePriorities, // pQueuePriorities
- },
- {
- VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO, // sType
- queueNextPtr, // pNext
- 0, // VkDeviceQueueCreateFlags
- mPresentQueueIndex, // queueFamilyIndex
- 1, // queueCount
- queuePriorities, // pQueuePriorities
- }
- };
+ {
+ VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO, // sType
+ queueNextPtr, // pNext
+ 0, // VkDeviceQueueCreateFlags
+ mGraphicsQueueIndex, // queueFamilyIndex
+ 1, // queueCount
+ queuePriorities, // pQueuePriorities
+ },
+ {
+ VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO, // sType
+ queueNextPtr, // pNext
+ 0, // VkDeviceQueueCreateFlags
+ mPresentQueueIndex, // queueFamilyIndex
+ 1, // queueCount
+ queuePriorities, // pQueuePriorities
+ }};
uint32_t queueInfoCount = (mPresentQueueIndex != mGraphicsQueueIndex) ? 2 : 1;
const VkDeviceCreateInfo deviceInfo = {
- VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO, // sType
- &features, // pNext
- 0, // VkDeviceCreateFlags
- queueInfoCount, // queueCreateInfoCount
- queueInfo, // pQueueCreateInfos
- 0, // layerCount
- nullptr, // ppEnabledLayerNames
- (uint32_t) mDeviceExtensions.size(), // extensionCount
- mDeviceExtensions.data(), // ppEnabledExtensionNames
- nullptr, // ppEnabledFeatures
+ VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO, // sType
+ &features, // pNext
+ 0, // VkDeviceCreateFlags
+ queueInfoCount, // queueCreateInfoCount
+ queueInfo, // pQueueCreateInfos
+ 0, // layerCount
+ nullptr, // ppEnabledLayerNames
+ (uint32_t)mDeviceExtensions.size(), // extensionCount
+ mDeviceExtensions.data(), // ppEnabledExtensionNames
+ nullptr, // ppEnabledFeatures
};
LOG_ALWAYS_FATAL_IF(mCreateDevice(mPhysicalDevice, &deviceInfo, nullptr, &mDevice));
@@ -371,8 +370,8 @@
// this needs to be on the render queue
commandPoolInfo.queueFamilyIndex = mGraphicsQueueIndex;
commandPoolInfo.flags = VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT;
- SkDEBUGCODE(VkResult res =) mCreateCommandPool(mDevice, &commandPoolInfo, nullptr,
- &mCommandPool);
+ SkDEBUGCODE(VkResult res =)
+ mCreateCommandPool(mDevice, &commandPoolInfo, nullptr, &mCommandPool);
SkASSERT(VK_SUCCESS == res);
}
LOG_ALWAYS_FATAL_IF(mCommandPool == VK_NULL_HANDLE);
@@ -391,7 +390,7 @@
}
sk_sp<GrContext> VulkanManager::createContext(const GrContextOptions& options) {
- auto getProc = [] (const char* proc_name, VkInstance instance, VkDevice device) {
+ auto getProc = [](const char* proc_name, VkInstance instance, VkDevice device) {
if (device != VK_NULL_HANDLE) {
return vkGetDeviceProcAddr(device, proc_name);
}
@@ -431,7 +430,6 @@
}
Frame VulkanManager::dequeueNextBuffer(VulkanSurface* surface) {
-
VulkanSurface::NativeBufferInfo* bufferInfo = surface->dequeueNativeBuffer();
if (bufferInfo == nullptr) {
@@ -480,7 +478,7 @@
bufferInfo->skSurface->wait(1, &backendSemaphore);
// The following flush blocks the GPU immediately instead of waiting for other
// drawing ops. It seems dequeue_fence is not respected otherwise.
- //TODO: remove the flush after finding why backendSemaphore is not working.
+ // TODO: remove the flush after finding why backendSemaphore is not working.
bufferInfo->skSurface->flush();
}
}
@@ -557,15 +555,15 @@
VulkanSurface* VulkanManager::createSurface(ANativeWindow* window, ColorMode colorMode,
sk_sp<SkColorSpace> surfaceColorSpace,
- SkColorType surfaceColorType,
- GrContext* grContext) {
+ SkColorType surfaceColorType, GrContext* grContext,
+ uint32_t extraBuffers) {
LOG_ALWAYS_FATAL_IF(!hasVkContext(), "Not initialized");
if (!window) {
return nullptr;
}
return VulkanSurface::Create(window, colorMode, surfaceColorType, surfaceColorSpace, grContext,
- *this);
+ *this, extraBuffers);
}
bool VulkanManager::setupDummyCommandBuffer() {
diff --git a/libs/hwui/renderthread/VulkanManager.h b/libs/hwui/renderthread/VulkanManager.h
index a7a43cc..1a3a0e4 100644
--- a/libs/hwui/renderthread/VulkanManager.h
+++ b/libs/hwui/renderthread/VulkanManager.h
@@ -18,16 +18,16 @@
#define VULKANMANAGER_H
#if !defined(VK_USE_PLATFORM_ANDROID_KHR)
-# define VK_USE_PLATFORM_ANDROID_KHR
+#define VK_USE_PLATFORM_ANDROID_KHR
#endif
#include <vulkan/vulkan.h>
#include <GrContextOptions.h>
-#include <vk/GrVkExtensions.h>
#include <SkSurface.h>
#include <ui/Fence.h>
#include <utils/StrongPointer.h>
#include <vk/GrVkBackendContext.h>
+#include <vk/GrVkExtensions.h>
#include "Frame.h"
#include "IRenderPipeline.h"
#include "VulkanSurface.h"
@@ -59,8 +59,8 @@
// Create and destroy functions for wrapping an ANativeWindow in a VulkanSurface
VulkanSurface* createSurface(ANativeWindow* window, ColorMode colorMode,
sk_sp<SkColorSpace> surfaceColorSpace,
- SkColorType surfaceColorType,
- GrContext* grContext);
+ SkColorType surfaceColorType, GrContext* grContext,
+ uint32_t extraBuffers);
void destroySurface(VulkanSurface* surface);
Frame dequeueNextBuffer(VulkanSurface* surface);
diff --git a/libs/hwui/renderthread/VulkanSurface.cpp b/libs/hwui/renderthread/VulkanSurface.cpp
index be78b69..32815fe 100644
--- a/libs/hwui/renderthread/VulkanSurface.cpp
+++ b/libs/hwui/renderthread/VulkanSurface.cpp
@@ -16,12 +16,12 @@
#include "VulkanSurface.h"
-#include <algorithm>
#include <SkSurface.h>
+#include <algorithm>
#include "VulkanManager.h"
-#include "utils/TraceUtils.h"
#include "utils/Color.h"
+#include "utils/TraceUtils.h"
namespace android {
namespace uirenderer {
@@ -31,10 +31,9 @@
// For now, only support pure rotations, not flip or flip-and-rotate, until we have
// more time to test them and build sample code. As far as I know we never actually
// use anything besides pure rotations anyway.
- return transform == 0
- || transform == NATIVE_WINDOW_TRANSFORM_ROT_90
- || transform == NATIVE_WINDOW_TRANSFORM_ROT_180
- || transform == NATIVE_WINDOW_TRANSFORM_ROT_270;
+ return transform == 0 || transform == NATIVE_WINDOW_TRANSFORM_ROT_90 ||
+ transform == NATIVE_WINDOW_TRANSFORM_ROT_180 ||
+ transform == NATIVE_WINDOW_TRANSFORM_ROT_270;
}
static int InvertTransform(int transform) {
@@ -85,16 +84,16 @@
}
void VulkanSurface::ComputeWindowSizeAndTransform(WindowInfo* windowInfo, const SkISize& minSize,
- const SkISize& maxSize) {
+ const SkISize& maxSize) {
SkISize& windowSize = windowInfo->size;
// clamp width & height to handle currentExtent of -1 and protect us from broken hints
- if (windowSize.width() < minSize.width() || windowSize.width() > maxSize.width()
- || windowSize.height() < minSize.height() || windowSize.height() > maxSize.height()) {
+ if (windowSize.width() < minSize.width() || windowSize.width() > maxSize.width() ||
+ windowSize.height() < minSize.height() || windowSize.height() > maxSize.height()) {
int width = std::min(maxSize.width(), std::max(minSize.width(), windowSize.width()));
int height = std::min(maxSize.height(), std::max(minSize.height(), windowSize.height()));
- ALOGE("Invalid Window Dimensions [%d, %d]; clamping to [%d, %d]",
- windowSize.width(), windowSize.height(), width, height);
+ ALOGE("Invalid Window Dimensions [%d, %d]; clamping to [%d, %d]", windowSize.width(),
+ windowSize.height(), width, height);
windowSize.set(width, height);
}
@@ -145,12 +144,8 @@
public:
VkSurfaceAutoDeleter(VkInstance instance, VkSurfaceKHR surface,
PFN_vkDestroySurfaceKHR destroySurfaceKHR)
- : mInstance(instance)
- , mSurface(surface)
- , mDestroySurfaceKHR(destroySurfaceKHR) {}
- ~VkSurfaceAutoDeleter() {
- destroy();
- }
+ : mInstance(instance), mSurface(surface), mDestroySurfaceKHR(destroySurfaceKHR) {}
+ ~VkSurfaceAutoDeleter() { destroy(); }
void destroy() {
if (mSurface != VK_NULL_HANDLE) {
@@ -166,9 +161,9 @@
};
VulkanSurface* VulkanSurface::Create(ANativeWindow* window, ColorMode colorMode,
- SkColorType colorType, sk_sp<SkColorSpace> colorSpace,
- GrContext* grContext, const VulkanManager& vkManager) {
-
+ SkColorType colorType, sk_sp<SkColorSpace> colorSpace,
+ GrContext* grContext, const VulkanManager& vkManager,
+ uint32_t extraBuffers) {
VkAndroidSurfaceCreateInfoKHR surfaceCreateInfo;
memset(&surfaceCreateInfo, 0, sizeof(VkAndroidSurfaceCreateInfoKHR));
surfaceCreateInfo.sType = VK_STRUCTURE_TYPE_ANDROID_SURFACE_CREATE_INFO_KHR;
@@ -188,10 +183,11 @@
vkManager.mDestroySurfaceKHR);
SkDEBUGCODE(VkBool32 supported; res = vkManager.mGetPhysicalDeviceSurfaceSupportKHR(
- vkManager.mPhysicalDevice, vkManager.mPresentQueueIndex, vkSurface, &supported);
- // All physical devices and queue families on Android must be capable of
- // presentation with any native window.
- SkASSERT(VK_SUCCESS == res && supported););
+ vkManager.mPhysicalDevice, vkManager.mPresentQueueIndex,
+ vkSurface, &supported);
+ // All physical devices and queue families on Android must be capable of
+ // presentation with any native window.
+ SkASSERT(VK_SUCCESS == res && supported););
// check for capabilities
VkSurfaceCapabilitiesKHR caps;
@@ -225,14 +221,13 @@
int query_value;
int err = window->query(window, NATIVE_WINDOW_MIN_UNDEQUEUED_BUFFERS, &query_value);
if (err != 0 || query_value < 0) {
- ALOGE("window->query failed: %s (%d) value=%d", strerror(-err), err,
- query_value);
+ ALOGE("window->query failed: %s (%d) value=%d", strerror(-err), err, query_value);
return nullptr;
}
auto min_undequeued_buffers = static_cast<uint32_t>(query_value);
- windowInfo.bufferCount = min_undequeued_buffers
- + std::max(VulkanSurface::sTargetBufferCount, caps.minImageCount);
+ windowInfo.bufferCount = min_undequeued_buffers +
+ std::max(sTargetBufferCount + extraBuffers, caps.minImageCount);
if (caps.maxImageCount > 0 && windowInfo.bufferCount > caps.maxImageCount) {
// Application must settle for fewer images than desired:
windowInfo.bufferCount = caps.maxImageCount;
@@ -241,8 +236,7 @@
// Currently Skia requires the images to be color attachments and support all transfer
// operations.
VkImageUsageFlags usageFlags = VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT |
- VK_IMAGE_USAGE_SAMPLED_BIT |
- VK_IMAGE_USAGE_TRANSFER_SRC_BIT |
+ VK_IMAGE_USAGE_SAMPLED_BIT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT |
VK_IMAGE_USAGE_TRANSFER_DST_BIT;
LOG_ALWAYS_FATAL_IF((caps.supportedUsageFlags & usageFlags) != usageFlags);
@@ -336,7 +330,8 @@
err = native_window_set_buffers_data_space(window, windowInfo.dataspace);
if (err != 0) {
ALOGE("VulkanSurface::UpdateWindow() native_window_set_buffers_data_space(%d) "
- "failed: %s (%d)", windowInfo.dataspace, strerror(-err), err);
+ "failed: %s (%d)",
+ windowInfo.dataspace, strerror(-err), err);
return false;
}
@@ -344,7 +339,8 @@
err = native_window_set_buffers_dimensions(window, size.width(), size.height());
if (err != 0) {
ALOGE("VulkanSurface::UpdateWindow() native_window_set_buffers_dimensions(%d,%d) "
- "failed: %s (%d)", size.width(), size.height(), strerror(-err), err);
+ "failed: %s (%d)",
+ size.width(), size.height(), strerror(-err), err);
return false;
}
@@ -357,7 +353,8 @@
err = native_window_set_buffers_transform(window, InvertTransform(windowInfo.transform));
if (err != 0) {
ALOGE("VulkanSurface::UpdateWindow() native_window_set_buffers_transform(%d) "
- "failed: %s (%d)", windowInfo.transform, strerror(-err), err);
+ "failed: %s (%d)",
+ windowInfo.transform, strerror(-err), err);
return false;
}
@@ -366,7 +363,8 @@
err = native_window_set_scaling_mode(window, NATIVE_WINDOW_SCALING_MODE_FREEZE);
if (err != 0) {
ALOGE("VulkanSurface::UpdateWindow() native_window_set_scaling_mode(SCALE_TO_WINDOW) "
- "failed: %s (%d)", strerror(-err), err);
+ "failed: %s (%d)",
+ strerror(-err), err);
return false;
}
@@ -388,12 +386,12 @@
}
VulkanSurface::VulkanSurface(ANativeWindow* window, const WindowInfo& windowInfo,
- SkISize minWindowSize, SkISize maxWindowSize, GrContext* grContext)
+ SkISize minWindowSize, SkISize maxWindowSize, GrContext* grContext)
: mNativeWindow(window)
, mWindowInfo(windowInfo)
, mGrContext(grContext)
, mMinWindowSize(minWindowSize)
- , mMaxWindowSize(maxWindowSize) { }
+ , mMaxWindowSize(maxWindowSize) {}
VulkanSurface::~VulkanSurface() {
releaseBuffers();
@@ -436,8 +434,7 @@
// value at the end of the function if everything dequeued correctly.
mCurrentBufferInfo = nullptr;
-
- //check if the native window has been resized or rotated and update accordingly
+ // check if the native window has been resized or rotated and update accordingly
SkISize newSize = SkISize::MakeEmpty();
int transformHint = 0;
mNativeWindow->query(mNativeWindow.get(), NATIVE_WINDOW_WIDTH, &newSize.fWidth);
@@ -457,8 +454,8 @@
newWindowInfo.actualSize.height());
if (err != 0) {
ALOGE("native_window_set_buffers_dimensions(%d,%d) failed: %s (%d)",
- newWindowInfo.actualSize.width(),
- newWindowInfo.actualSize.height(), strerror(-err), err);
+ newWindowInfo.actualSize.width(), newWindowInfo.actualSize.height(),
+ strerror(-err), err);
return nullptr;
}
// reset the NativeBufferInfo (including SkSurface) associated with the old buffers. The
@@ -469,7 +466,7 @@
if (newWindowInfo.transform != mWindowInfo.transform) {
err = native_window_set_buffers_transform(mNativeWindow.get(),
- InvertTransform(newWindowInfo.transform));
+ InvertTransform(newWindowInfo.transform));
if (err != 0) {
ALOGE("native_window_set_buffers_transform(%d) failed: %s (%d)",
newWindowInfo.transform, strerror(-err), err);
@@ -512,11 +509,9 @@
VulkanSurface::NativeBufferInfo* bufferInfo = &mNativeBuffers[idx];
if (bufferInfo->skSurface.get() == nullptr) {
- bufferInfo->skSurface =
- SkSurface::MakeFromAHardwareBuffer(mGrContext,
- ANativeWindowBuffer_getHardwareBuffer(bufferInfo->buffer.get()),
- kTopLeft_GrSurfaceOrigin, DataSpaceToColorSpace(mWindowInfo.dataspace),
- nullptr);
+ bufferInfo->skSurface = SkSurface::MakeFromAHardwareBuffer(
+ mGrContext, ANativeWindowBuffer_getHardwareBuffer(bufferInfo->buffer.get()),
+ kTopLeft_GrSurfaceOrigin, DataSpaceToColorSpace(mWindowInfo.dataspace), nullptr);
if (bufferInfo->skSurface.get() == nullptr) {
ALOGE("SkSurface::MakeFromAHardwareBuffer failed");
mNativeWindow->cancelBuffer(mNativeWindow.get(), buffer, fence_fd);
diff --git a/libs/hwui/renderthread/VulkanSurface.h b/libs/hwui/renderthread/VulkanSurface.h
index 305483f..b7af596 100644
--- a/libs/hwui/renderthread/VulkanSurface.h
+++ b/libs/hwui/renderthread/VulkanSurface.h
@@ -19,8 +19,8 @@
#include <system/window.h>
#include <vulkan/vulkan.h>
-#include <SkSize.h>
#include <SkRefCnt.h>
+#include <SkSize.h>
#include "IRenderPipeline.h"
@@ -34,12 +34,9 @@
class VulkanSurface {
public:
- static VulkanSurface* Create(ANativeWindow* window,
- ColorMode colorMode,
- SkColorType colorType,
- sk_sp<SkColorSpace> colorSpace,
- GrContext* grContext,
- const VulkanManager& vkManager);
+ static VulkanSurface* Create(ANativeWindow* window, ColorMode colorMode, SkColorType colorType,
+ sk_sp<SkColorSpace> colorSpace, GrContext* grContext,
+ const VulkanManager& vkManager, uint32_t extraBuffers);
~VulkanSurface();
sk_sp<SkSurface> getCurrentSkSurface() {
@@ -104,15 +101,10 @@
SkMatrix preTransform;
};
- VulkanSurface(ANativeWindow* window,
- const WindowInfo& windowInfo,
- SkISize minWindowSize,
- SkISize maxWindowSize,
- GrContext* grContext);
- static bool UpdateWindow(ANativeWindow* window,
- const WindowInfo& windowInfo);
- static void ComputeWindowSizeAndTransform(WindowInfo* windowInfo,
- const SkISize& minSize,
+ VulkanSurface(ANativeWindow* window, const WindowInfo& windowInfo, SkISize minWindowSize,
+ SkISize maxWindowSize, GrContext* grContext);
+ static bool UpdateWindow(ANativeWindow* window, const WindowInfo& windowInfo);
+ static void ComputeWindowSizeAndTransform(WindowInfo* windowInfo, const SkISize& minSize,
const SkISize& maxSize);
void releaseBuffers();
diff --git a/libs/hwui/tests/unit/SkiaPipelineTests.cpp b/libs/hwui/tests/unit/SkiaPipelineTests.cpp
index e86cf42..a671bda 100644
--- a/libs/hwui/tests/unit/SkiaPipelineTests.cpp
+++ b/libs/hwui/tests/unit/SkiaPipelineTests.cpp
@@ -31,6 +31,9 @@
#include "renderthread/CanvasContext.h"
#include "tests/common/TestUtils.h"
+#include <gui/BufferItemConsumer.h>
+#include <gui/Surface.h>
+
using namespace android;
using namespace android::uirenderer;
using namespace android::uirenderer::renderthread;
@@ -421,10 +424,20 @@
EXPECT_EQ(1, surface->canvas()->mDrawCounter);
}
+static sp<Surface> createDummySurface() {
+ sp<IGraphicBufferProducer> producer;
+ sp<IGraphicBufferConsumer> consumer;
+ BufferQueue::createBufferQueue(&producer, &consumer);
+ producer->setMaxDequeuedBufferCount(1);
+ producer->setAsyncMode(true);
+ return new Surface(producer);
+}
+
RENDERTHREAD_SKIA_PIPELINE_TEST(SkiaPipeline, context_lost) {
+ auto surface = createDummySurface();
auto pipeline = std::make_unique<SkiaOpenGLPipeline>(renderThread);
EXPECT_FALSE(pipeline->isSurfaceReady());
- EXPECT_TRUE(pipeline->setSurface((Surface*)0x01, SwapBehavior::kSwap_default, ColorMode::SRGB));
+ EXPECT_TRUE(pipeline->setSurface(surface.get(), SwapBehavior::kSwap_default, ColorMode::SRGB, 0));
EXPECT_TRUE(pipeline->isSurfaceReady());
renderThread.destroyRenderingContext();
EXPECT_FALSE(pipeline->isSurfaceReady());
diff --git a/location/java/android/location/GnssStatus.java b/location/java/android/location/GnssStatus.java
index ce464b7..211a0cb 100644
--- a/location/java/android/location/GnssStatus.java
+++ b/location/java/android/location/GnssStatus.java
@@ -17,6 +17,7 @@
package android.location;
import android.annotation.IntDef;
+import android.annotation.NonNull;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
@@ -44,6 +45,8 @@
public static final int CONSTELLATION_GALILEO = 6;
/** Constellation type constant for IRNSS. */
public static final int CONSTELLATION_IRNSS = 7;
+ /** @hide */
+ public static final int CONSTELLATION_COUNT = 8;
/** @hide */
public static final int GNSS_SV_FLAGS_NONE = 0;
@@ -251,4 +254,36 @@
public float getCarrierFrequencyHz(int satIndex) {
return mCarrierFrequencies[satIndex];
}
+
+ /**
+ * Returns the string representation of a constellation type. For example,
+ * {@link #CONSTELLATION_GPS} is represented by the string GPS.
+ *
+ * @param constellationType the constellation type.
+ * @return the string representation.
+ * @hide
+ */
+ @NonNull
+ public static String constellationTypeToString(@ConstellationType int constellationType) {
+ switch (constellationType) {
+ case CONSTELLATION_UNKNOWN:
+ return "UNKNOWN";
+ case CONSTELLATION_GPS:
+ return "GPS";
+ case CONSTELLATION_SBAS:
+ return "SBAS";
+ case CONSTELLATION_GLONASS:
+ return "GLONASS";
+ case CONSTELLATION_QZSS:
+ return "QZSS";
+ case CONSTELLATION_BEIDOU:
+ return "BEIDOU";
+ case CONSTELLATION_GALILEO:
+ return "GALILEO";
+ case CONSTELLATION_IRNSS:
+ return "IRNSS";
+ default:
+ return Integer.toString(constellationType);
+ }
+ }
}
diff --git a/location/java/com/android/internal/location/gnssmetrics/GnssMetrics.java b/location/java/com/android/internal/location/gnssmetrics/GnssMetrics.java
index 057a4ae..7823971 100644
--- a/location/java/com/android/internal/location/gnssmetrics/GnssMetrics.java
+++ b/location/java/com/android/internal/location/gnssmetrics/GnssMetrics.java
@@ -16,26 +16,26 @@
package com.android.internal.location.gnssmetrics;
+import android.location.GnssStatus;
import android.os.SystemClock;
-import android.os.connectivity.GpsBatteryStats;
import android.os.SystemProperties;
-
+import android.os.connectivity.GpsBatteryStats;
import android.server.location.ServerLocationProtoEnums;
-
import android.text.format.DateUtils;
import android.util.Base64;
import android.util.Log;
import android.util.StatsLog;
import android.util.TimeUtils;
-import java.util.Arrays;
-
import com.android.internal.app.IBatteryStats;
import com.android.internal.location.nano.GnssLogsProto.GnssLog;
import com.android.internal.location.nano.GnssLogsProto.PowerMetrics;
+import java.util.Arrays;
+
/**
* GnssMetrics: Is used for logging GNSS metrics
+ *
* @hide
*/
public class GnssMetrics {
@@ -66,6 +66,11 @@
/* GNSS power metrics */
private GnssPowerMetrics mGnssPowerMetrics;
+ /**
+ * A boolean array indicating whether the constellation types have been used in fix.
+ */
+ private boolean[] mConstellationTypes;
+
/** Constructor */
public GnssMetrics(IBatteryStats stats) {
mGnssPowerMetrics = new GnssPowerMetrics(stats);
@@ -156,6 +161,18 @@
return;
}
+
+ /**
+ * Logs that a constellation type has been observed.
+ */
+ public void logConstellationType(int constellationType) {
+ if (constellationType >= mConstellationTypes.length) {
+ Log.e(TAG, "Constellation type " + constellationType + " is not valid.");
+ return;
+ }
+ mConstellationTypes[constellationType] = true;
+ }
+
/**
* Dumps GNSS metrics as a proto string
* @return
@@ -232,6 +249,13 @@
s.append(" Top 4 Avg CN0 standard deviation (dB-Hz): ").append(
topFourAverageCn0Statistics.getStandardDeviation()).append("\n");
}
+ s.append(" Used-in-fix constellation types: ");
+ for (int i = 0; i < mConstellationTypes.length; i++) {
+ if (mConstellationTypes[i]) {
+ s.append(GnssStatus.constellationTypeToString(i)).append(" ");
+ }
+ }
+ s.append("\n");
s.append("GNSS_KPI_END").append("\n");
GpsBatteryStats stats = mGnssPowerMetrics.getGpsBatteryStats();
if (stats != null) {
@@ -320,9 +344,15 @@
timeToFirstFixSecStatistics.reset();
positionAccuracyMeterStatistics.reset();
topFourAverageCn0Statistics.reset();
+ resetConstellationTypes();
return;
}
+ /** Resets {@link #mConstellationTypes} as an all-false boolean array. */
+ public void resetConstellationTypes() {
+ mConstellationTypes = new boolean[GnssStatus.CONSTELLATION_COUNT];
+ }
+
/* Class for handling GNSS power related metrics */
private class GnssPowerMetrics {
diff --git a/media/apex/java/android/media/DataSourceDesc.java b/media/apex/java/android/media/DataSourceDesc.java
index d00ff2a..9a9c74a 100644
--- a/media/apex/java/android/media/DataSourceDesc.java
+++ b/media/apex/java/android/media/DataSourceDesc.java
@@ -34,6 +34,8 @@
*
* Used by {@link MediaPlayer2#setDataSource}, {@link MediaPlayer2#setNextDataSource} and
* {@link MediaPlayer2#setNextDataSources} to set data source for playback.
+ *
+ * @hide
*/
public class DataSourceDesc {
// intentionally less than long.MAX_VALUE
diff --git a/media/apex/java/android/media/FileDataSourceDesc.java b/media/apex/java/android/media/FileDataSourceDesc.java
index feb67e1..2aa2cb7 100644
--- a/media/apex/java/android/media/FileDataSourceDesc.java
+++ b/media/apex/java/android/media/FileDataSourceDesc.java
@@ -17,7 +17,6 @@
package android.media;
import android.annotation.NonNull;
-import android.annotation.TestApi;
import android.os.ParcelFileDescriptor;
import android.util.Log;
@@ -32,7 +31,6 @@
* <p>Users should use {@link Builder} to create {@link FileDataSourceDesc}.
* @hide
*/
-@TestApi
public class FileDataSourceDesc extends DataSourceDesc {
private static final String TAG = "FileDataSourceDesc";
diff --git a/media/apex/java/android/media/MediaConstants.java b/media/apex/java/android/media/MediaConstants.java
index 776c1ba..ce10889 100644
--- a/media/apex/java/android/media/MediaConstants.java
+++ b/media/apex/java/android/media/MediaConstants.java
@@ -28,6 +28,7 @@
static final String KEY_ALLOWED_COMMANDS = "android.media.key.ALLOWED_COMMANDS";
static final String KEY_PLAYBACK_ACTIVE = "android.media.key.PLAYBACK_ACTIVE";
static final String KEY_TOKEN_EXTRAS = "android.media.key.TOKEN_EXTRAS";
+ static final String KEY_CONNECTION_HINTS = "android.media.key.CONNECTION_HINTS";
private MediaConstants() {
}
diff --git a/media/apex/java/android/media/MediaController2.java b/media/apex/java/android/media/MediaController2.java
index 1e8438e..fb4e6ac 100644
--- a/media/apex/java/android/media/MediaController2.java
+++ b/media/apex/java/android/media/MediaController2.java
@@ -17,6 +17,7 @@
package android.media;
import static android.media.MediaConstants.KEY_ALLOWED_COMMANDS;
+import static android.media.MediaConstants.KEY_CONNECTION_HINTS;
import static android.media.MediaConstants.KEY_PACKAGE_NAME;
import static android.media.MediaConstants.KEY_PID;
import static android.media.MediaConstants.KEY_PLAYBACK_ACTIVE;
@@ -91,24 +92,16 @@
* Create a {@link MediaController2} from the {@link Session2Token}.
* This connects to the session and may wake up the service if it's not available.
*
- * @param context Context
+ * @param context context
* @param token token to connect to
- */
- public MediaController2(@NonNull Context context, @NonNull Session2Token token) {
- this(context, token, context.getMainExecutor(), new ControllerCallback() {});
- }
-
- /**
- * Create a {@link MediaController2} from the {@link Session2Token}.
- * This connects to the session and may wake up the service if it's not available.
- *
- * @param context Context
- * @param token token to connect to
+ * @param connectionHints a session-specific argument to send to the session when connecting.
+ * The contents of this bundle may affect the connection result.
* @param executor executor to run callbacks on.
* @param callback controller callback to receive changes in.
*/
- public MediaController2(@NonNull Context context, @NonNull Session2Token token,
- @NonNull Executor executor, @NonNull ControllerCallback callback) {
+ MediaController2(@NonNull Context context, @NonNull Session2Token token,
+ @Nullable Bundle connectionHints, @NonNull Executor executor,
+ @NonNull ControllerCallback callback) {
if (context == null) {
throw new IllegalArgumentException("context shouldn't be null");
}
@@ -130,9 +123,9 @@
boolean connectRequested;
if (token.getType() == TYPE_SESSION) {
mServiceConnection = null;
- connectRequested = requestConnectToSession();
+ connectRequested = requestConnectToSession(connectionHints);
} else {
- mServiceConnection = new SessionServiceConnection();
+ mServiceConnection = new SessionServiceConnection(connectionHints);
connectRequested = requestConnectToService();
}
if (!connectRequested) {
@@ -350,16 +343,17 @@
}
}
- private Bundle createConnectionRequest() {
+ private Bundle createConnectionRequest(@Nullable Bundle connectionHints) {
Bundle connectionRequest = new Bundle();
connectionRequest.putString(KEY_PACKAGE_NAME, mContext.getPackageName());
connectionRequest.putInt(KEY_PID, Process.myPid());
+ connectionRequest.putBundle(KEY_CONNECTION_HINTS, connectionHints);
return connectionRequest;
}
- private boolean requestConnectToSession() {
+ private boolean requestConnectToSession(@Nullable Bundle connectionHints) {
Session2Link sessionBinder = mSessionToken.getSessionLink();
- Bundle connectionRequest = createConnectionRequest();
+ Bundle connectionRequest = createConnectionRequest(connectionHints);
try {
sessionBinder.connect(mControllerStub, getNextSeqNumber(), connectionRequest);
} catch (RuntimeException e) {
@@ -402,6 +396,93 @@
}
/**
+ * Builder for {@link MediaController2}.
+ * <p>
+ * Any incoming event from the {@link MediaSession2} will be handled on the callback
+ * executor. If it's not set, {@link Context#getMainExecutor()} will be used by default.
+ */
+ public static final class Builder {
+ private Context mContext;
+ private Session2Token mToken;
+ private Bundle mConnectionHints;
+ private Executor mCallbackExecutor;
+ private ControllerCallback mCallback;
+
+ /**
+ * Creates a builder for {@link MediaController2}.
+ *
+ * @param context context
+ * @param token token of the session to connect to
+ */
+ public Builder(@NonNull Context context, @NonNull Session2Token token) {
+ if (context == null) {
+ throw new IllegalArgumentException("context shouldn't be null");
+ }
+ if (token == null) {
+ throw new IllegalArgumentException("token shouldn't be null");
+ }
+ mContext = context;
+ mToken = token;
+ }
+
+ /**
+ * Set the connection hints for the controller.
+ * <p>
+ * {@code connectionHints} is a session-specific argument to send to the session when
+ * connecting. The contents of this bundle may affect the connection result.
+ *
+ * @param connectionHints a bundle which contains the connection hints
+ * @return The Builder to allow chaining
+ */
+ @NonNull
+ public Builder setConnectionHints(@NonNull Bundle connectionHints) {
+ if (connectionHints == null) {
+ throw new IllegalArgumentException("connectionHints shouldn't be null");
+ }
+ mConnectionHints = new Bundle(connectionHints);
+ return this;
+ }
+
+ /**
+ * Set callback for the controller and its executor.
+ *
+ * @param executor callback executor
+ * @param callback session callback.
+ * @return The Builder to allow chaining
+ */
+ @NonNull
+ public Builder setControllerCallback(@NonNull Executor executor,
+ @NonNull ControllerCallback callback) {
+ if (executor == null) {
+ throw new IllegalArgumentException("executor shouldn't be null");
+ }
+ if (callback == null) {
+ throw new IllegalArgumentException("callback shouldn't be null");
+ }
+ mCallbackExecutor = executor;
+ mCallback = callback;
+ return this;
+ }
+
+ /**
+ * Build {@link MediaController2}.
+ *
+ * @return a new controller
+ */
+ @NonNull
+ public MediaController2 build() {
+ if (mCallbackExecutor == null) {
+ mCallbackExecutor = mContext.getMainExecutor();
+ }
+ if (mCallback == null) {
+ mCallback = new ControllerCallback() {};
+ }
+ return new MediaController2(
+ mContext, mToken, mConnectionHints, mCallbackExecutor, mCallback);
+ }
+ }
+
+ /**
* Interface for listening to change in activeness of the {@link MediaSession2}.
* <p>
* This API is not generally intended for third party application developers.
@@ -469,7 +550,10 @@
// This will be called on the main thread.
private class SessionServiceConnection implements ServiceConnection {
- SessionServiceConnection() {
+ private final Bundle mConnectionHints;
+
+ SessionServiceConnection(@Nullable Bundle connectionHints) {
+ mConnectionHints = connectionHints;
}
@Override
@@ -491,7 +575,7 @@
Log.wtf(TAG, "Service interface is missing.");
return;
}
- Bundle connectionRequest = createConnectionRequest();
+ Bundle connectionRequest = createConnectionRequest(mConnectionHints);
iService.connect(mControllerStub, getNextSeqNumber(), connectionRequest);
connectRequested = true;
} catch (RemoteException e) {
diff --git a/media/apex/java/android/media/MediaPlayer2.java b/media/apex/java/android/media/MediaPlayer2.java
index 72c18f6..614d737 100644
--- a/media/apex/java/android/media/MediaPlayer2.java
+++ b/media/apex/java/android/media/MediaPlayer2.java
@@ -273,6 +273,8 @@
* Then check the <code>status</code> parameter. The value {@link #CALL_STATUS_NO_ERROR} indicates a
* successful transition. Any other value will be an error. Call {@link #getState()} to
* determine the current state. </p>
+ *
+ * @hide
*/
public class MediaPlayer2 implements AutoCloseable, AudioRouting {
static {
diff --git a/media/apex/java/android/media/MediaSession2.java b/media/apex/java/android/media/MediaSession2.java
index a900d87..6b56ae0 100644
--- a/media/apex/java/android/media/MediaSession2.java
+++ b/media/apex/java/android/media/MediaSession2.java
@@ -17,6 +17,7 @@
package android.media;
import static android.media.MediaConstants.KEY_ALLOWED_COMMANDS;
+import static android.media.MediaConstants.KEY_CONNECTION_HINTS;
import static android.media.MediaConstants.KEY_PACKAGE_NAME;
import static android.media.MediaConstants.KEY_PID;
import static android.media.MediaConstants.KEY_PLAYBACK_ACTIVE;
@@ -308,8 +309,11 @@
String callingPkg = connectionRequest.getString(KEY_PACKAGE_NAME);
RemoteUserInfo remoteUserInfo = new RemoteUserInfo(callingPkg, callingPid, callingUid);
- final ControllerInfo controllerInfo = new ControllerInfo(remoteUserInfo,
- mSessionManager.isTrustedForMediaControl(remoteUserInfo), controller);
+ final ControllerInfo controllerInfo = new ControllerInfo(
+ remoteUserInfo,
+ mSessionManager.isTrustedForMediaControl(remoteUserInfo),
+ controller,
+ connectionRequest.getBundle(KEY_CONNECTION_HINTS));
mCallbackExecutor.execute(() -> {
boolean connected = false;
try {
@@ -568,6 +572,7 @@
private final RemoteUserInfo mRemoteUserInfo;
private final boolean mIsTrusted;
private final Controller2Link mControllerBinder;
+ private final Bundle mConnectionHints;
private final Object mLock = new Object();
//@GuardedBy("mLock")
private int mNextSeqNumber;
@@ -583,12 +588,16 @@
* @param remoteUserInfo remote user info
* @param trusted {@code true} if trusted, {@code false} otherwise
* @param controllerBinder Controller2Link for the connected controller.
+ * @param connectionHints a session-specific argument sent from the controller for the
+ * connection. The contents of this bundle may affect the
+ * connection result.
*/
ControllerInfo(@NonNull RemoteUserInfo remoteUserInfo, boolean trusted,
- @Nullable Controller2Link controllerBinder) {
+ @Nullable Controller2Link controllerBinder, @Nullable Bundle connectionHints) {
mRemoteUserInfo = remoteUserInfo;
mIsTrusted = trusted;
mControllerBinder = controllerBinder;
+ mConnectionHints = connectionHints;
mPendingCommands = new ArrayMap<>();
mRequestedCommandSeqNumbers = new ArraySet<>();
}
@@ -617,6 +626,14 @@
}
/**
+ * @return connection hints sent from controller, or {@link Bundle#EMPTY} if none.
+ */
+ @NonNull
+ public Bundle getConnectionHints() {
+ return mConnectionHints == null ? Bundle.EMPTY : new Bundle(mConnectionHints);
+ }
+
+ /**
* Return if the controller has granted {@code android.permission.MEDIA_CONTENT_CONTROL} or
* has a enabled notification listener so can be trusted to accept connection and incoming
* command request.
diff --git a/media/apex/java/android/media/MediaSession2Service.java b/media/apex/java/android/media/MediaSession2Service.java
index 5bb746a..28ead99 100644
--- a/media/apex/java/android/media/MediaSession2Service.java
+++ b/media/apex/java/android/media/MediaSession2Service.java
@@ -16,6 +16,10 @@
package android.media;
+import static android.media.MediaConstants.KEY_CONNECTION_HINTS;
+import static android.media.MediaConstants.KEY_PACKAGE_NAME;
+import static android.media.MediaConstants.KEY_PID;
+
import android.annotation.CallSuper;
import android.annotation.NonNull;
import android.annotation.Nullable;
@@ -24,6 +28,9 @@
import android.app.Service;
import android.content.Context;
import android.content.Intent;
+import android.media.MediaSession2.ControllerInfo;
+import android.media.session.MediaSessionManager;
+import android.media.session.MediaSessionManager.RemoteUserInfo;
import android.os.Binder;
import android.os.Bundle;
import android.os.Handler;
@@ -70,6 +77,8 @@
//@GuardedBy("mLock")
private NotificationManager mNotificationManager;
//@GuardedBy("mLock")
+ private MediaSessionManager mMediaSessionManager;
+ //@GuardedBy("mLock")
private Intent mStartSelfIntent;
//@GuardedBy("mLock")
private Map<String, MediaSession2> mSessions = new ArrayMap<>();
@@ -93,6 +102,8 @@
mStartSelfIntent = new Intent(this, this.getClass());
mNotificationManager =
(NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
+ mMediaSessionManager =
+ (MediaSessionManager) getSystemService(Context.MEDIA_SESSION_SERVICE);
}
}
@@ -132,34 +143,22 @@
/**
* Called when a {@link MediaController2} is created with the this service's
- * {@link Session2Token}. Return the primary session for telling the controller which session to
- * connect.
- * <p>
- * Primary session is the highest priority session that this service manages. Here are some
- * recommendations of the primary session.
- * <ol>
- * <li>When there's no {@link MediaSession2}, create and return a new session. Resume the
- * playback that the app has the lastly played with the new session. The behavior is what
- * framework expects when the framework sends key events to the service.</li>
- * <li>When there's multiple {@link MediaSession2}s, pick the session that has the lastly
- * started the playback. This is the same way as the framework prioritize sessions to receive
- * media key events.</li>
- * </ol>
+ * {@link Session2Token}. Return the session for telling the controller which session to
+ * connect. Return {@code null} to reject the connection from this controller.
* <p>
* Session returned here will be added to this service automatically. You don't need to call
* {@link #addSession(MediaSession2)} for that.
* <p>
- * Session service will accept or reject the connection with the
- * {@link MediaSession2.SessionCallback} in the session returned here.
- * <p>
* This method is always called on the main thread.
*
- * @return a new session
+ * @param controllerInfo information of the controller which is trying to connect.
+ * @return a {@link MediaSession2} instance for the controller to connect to, or {@code null}
+ * to reject connection
* @see MediaSession2.Builder
* @see #getSessions()
*/
- @NonNull
- public abstract MediaSession2 onGetPrimarySession();
+ @Nullable
+ public abstract MediaSession2 onGetSession(@NonNull ControllerInfo controllerInfo);
/**
* Called when notification UI needs update. Override this method to show or cancel your own
@@ -251,6 +250,16 @@
}
/**
+ * Returns the {@link MediaSessionManager}.
+ */
+ @NonNull
+ MediaSessionManager getMediaSessionManager() {
+ synchronized (mLock) {
+ return mMediaSessionManager;
+ }
+ }
+
+ /**
* Called by registered {@link MediaSession2.ForegroundServiceEventCallback}
*
* @param session session with change
@@ -365,8 +374,33 @@
Log.d(TAG, "Handling incoming connection request from the"
+ " controller, controller=" + caller + ", uid=" + uid);
}
+
+ String callingPkg = connectionRequest.getString(KEY_PACKAGE_NAME);
+ // The Binder.getCallingPid() can be 0 for an oneway call from the
+ // remote process. If it's the case, use PID from the connectionRequest.
+ RemoteUserInfo remoteUserInfo = new RemoteUserInfo(
+ callingPkg,
+ pid == 0 ? connectionRequest.getInt(KEY_PID) : pid,
+ uid);
+ final ControllerInfo controllerInfo = new ControllerInfo(
+ remoteUserInfo,
+ service.getMediaSessionManager()
+ .isTrustedForMediaControl(remoteUserInfo),
+ caller,
+ connectionRequest.getBundle(KEY_CONNECTION_HINTS));
+
final MediaSession2 session;
- session = service.onGetPrimarySession();
+ session = service.onGetSession(controllerInfo);
+
+ if (session == null) {
+ if (DEBUG) {
+ Log.d(TAG, "Rejecting incoming connection request from the"
+ + " controller, controller=" + caller + ", uid=" + uid);
+ }
+ // Note: Trusted controllers also can be rejected according to the
+ // service implementation.
+ return;
+ }
service.addSession(session);
shouldNotifyDisconnected = false;
session.onConnect(caller, pid, uid, seq, connectionRequest);
@@ -377,8 +411,7 @@
// Trick to call onDisconnected() in one place.
if (shouldNotifyDisconnected) {
if (DEBUG) {
- Log.d(TAG, "Service has destroyed prematurely."
- + " Rejecting connection");
+ Log.d(TAG, "Notifying the controller of its disconnection");
}
try {
caller.notifyDisconnected(0);
diff --git a/media/apex/java/android/media/UriDataSourceDesc.java b/media/apex/java/android/media/UriDataSourceDesc.java
index eaedf1e..adf7a7d 100644
--- a/media/apex/java/android/media/UriDataSourceDesc.java
+++ b/media/apex/java/android/media/UriDataSourceDesc.java
@@ -18,7 +18,6 @@
import android.annotation.NonNull;
import android.annotation.Nullable;
-import android.annotation.TestApi;
import android.net.Uri;
import java.net.HttpCookie;
@@ -36,7 +35,6 @@
* <p>Users should use {@link Builder} to change {@link UriDataSourceDesc}.
* @hide
*/
-@TestApi
public class UriDataSourceDesc extends DataSourceDesc {
private Uri mUri;
private Map<String, String> mHeader;
diff --git a/media/java/android/media/AudioAttributes.java b/media/java/android/media/AudioAttributes.java
index 9d4bce7..e655460 100644
--- a/media/java/android/media/AudioAttributes.java
+++ b/media/java/android/media/AudioAttributes.java
@@ -20,7 +20,7 @@
import android.annotation.NonNull;
import android.annotation.SystemApi;
import android.annotation.UnsupportedAppUsage;
-import android.media.audiopolicy.AudioProductStrategies;
+import android.media.audiopolicy.AudioProductStrategy;
import android.os.Build;
import android.os.Bundle;
import android.os.Parcel;
@@ -535,6 +535,23 @@
}
/**
+ * Return the capture policy.
+ * @return the capture policy set by {@link Builder#setAllowedCapturePolicy(int)} or
+ * the default if it was not called.
+ */
+ @CapturePolicy
+ public int getAllowedCapturePolicy() {
+ if ((mFlags & FLAG_NO_SYSTEM_CAPTURE) == FLAG_NO_SYSTEM_CAPTURE) {
+ return ALLOW_CAPTURE_BY_NONE;
+ }
+ if ((mFlags & FLAG_NO_MEDIA_PROJECTION) == FLAG_NO_MEDIA_PROJECTION) {
+ return ALLOW_CAPTURE_BY_SYSTEM;
+ }
+ return ALLOW_CAPTURE_BY_ALL;
+ }
+
+
+ /**
* Builder class for {@link AudioAttributes} objects.
* <p> Here is an example where <code>Builder</code> is used to define the
* {@link AudioAttributes} to be used by a new <code>AudioTrack</code> instance:
@@ -696,12 +713,19 @@
}
/**
- * Specifying if audio may or may not be captured by other apps or the system.
+ * Specifies weather the audio may or may not be captured by other apps or the system.
*
* The default is {@link AudioAttributes#ALLOW_CAPTURE_BY_ALL}.
*
- * Note that an application can also set its global policy, in which case the most
- * restrictive policy is always applied.
+ * There are multiple ways to set this policy:
+ * - for each tracks independently, with this method
+ * - application wide at runtime, with {@link AudioManager#setAllowedCapturePolicy(int)}
+ * - application wide at build time, see {@code allowAudioPlaybackCapture} in the
+ * application manifest.
+ * The most restrictive policy is always applied.
+ *
+ * See {@link AudioPlaybackCaptureConfiguration} for more details on the restrictions
+ * which audio signals can be captured.
*
* @param capturePolicy one of
* {@link #ALLOW_CAPTURE_BY_ALL},
@@ -783,9 +807,10 @@
*/
@UnsupportedAppUsage
public Builder setInternalLegacyStreamType(int streamType) {
- final AudioProductStrategies ps = new AudioProductStrategies();
- if (ps.size() > 0) {
- AudioAttributes attributes = ps.getAudioAttributesForLegacyStreamType(streamType);
+ if (AudioProductStrategy.getAudioProductStrategies().size() > 0) {
+ AudioAttributes attributes =
+ AudioProductStrategy.getAudioAttributesForStrategyWithLegacyStreamType(
+ streamType);
if (attributes != null) {
return new Builder(attributes);
}
@@ -1165,9 +1190,8 @@
AudioSystem.STREAM_MUSIC : AudioSystem.STREAM_TTS;
}
- final AudioProductStrategies ps = new AudioProductStrategies();
- if (ps.size() > 0) {
- return ps.getLegacyStreamTypeForAudioAttributes(aa);
+ if (AudioProductStrategy.getAudioProductStrategies().size() > 0) {
+ return AudioProductStrategy.getLegacyStreamTypeForStrategyWithAudioAttributes(aa);
}
// usage to stream type mapping
switch (aa.getUsage()) {
diff --git a/media/java/android/media/AudioFocusInfo.java b/media/java/android/media/AudioFocusInfo.java
index 3aaa7df..ee89509 100644
--- a/media/java/android/media/AudioFocusInfo.java
+++ b/media/java/android/media/AudioFocusInfo.java
@@ -18,6 +18,7 @@
import android.annotation.NonNull;
import android.annotation.SystemApi;
+import android.annotation.TestApi;
import android.os.Parcel;
import android.os.Parcelable;
@@ -27,6 +28,7 @@
* @hide
* A class to encapsulate information about an audio focus owner or request.
*/
+@TestApi
@SystemApi
public final class AudioFocusInfo implements Parcelable {
diff --git a/media/java/android/media/AudioManager.java b/media/java/android/media/AudioManager.java
index a5a4092..8831265 100644
--- a/media/java/android/media/AudioManager.java
+++ b/media/java/android/media/AudioManager.java
@@ -26,6 +26,7 @@
import android.annotation.SuppressLint;
import android.annotation.SystemApi;
import android.annotation.SystemService;
+import android.annotation.TestApi;
import android.annotation.UnsupportedAppUsage;
import android.app.NotificationManager;
import android.app.PendingIntent;
@@ -37,9 +38,9 @@
import android.content.Intent;
import android.media.audiopolicy.AudioPolicy;
import android.media.audiopolicy.AudioPolicy.AudioPolicyFocusListener;
-import android.media.audiopolicy.AudioProductStrategies;
+import android.media.audiopolicy.AudioProductStrategy;
+import android.media.audiopolicy.AudioVolumeGroup;
import android.media.audiopolicy.AudioVolumeGroupChangeHandler;
-import android.media.audiopolicy.AudioVolumeGroups;
import android.media.projection.MediaProjection;
import android.media.session.MediaController;
import android.media.session.MediaSession;
@@ -1483,12 +1484,21 @@
}
/**
- * Specifying if this audio may or may not be captured by other apps or the system.
+ * Specifies wheather the audio played by this app may or may not be captured by other apps or
+ * the system.
*
* The default is {@link AudioAttributes#ALLOW_CAPTURE_BY_ALL}.
*
- * Note that each audio track can also set its policy, in which case the most
- * restrictive policy is always applied.
+ * There are multiple ways to set this policy:
+ * - for each tracks independently, see
+ * {@link AudioAttributes.Builder#setAllowedCapturePolicy(int)}
+ * - application wide at runtime, with this method
+ * - application wide at build time, see {@code allowAudioPlaybackCapture} in the application
+ * manifest.
+ * The most restrictive policy is always applied.
+ *
+ * See {@link AudioPlaybackCaptureConfiguration} for more details on the restrictions
+ * which audio signals can be captured.
*
* @param capturePolicy one of
* {@link AudioAttributes#ALLOW_CAPTURE_BY_ALL},
@@ -1503,7 +1513,22 @@
int result = AudioSystem.setAllowedCapturePolicy(Process.myUid(), flags);
if (result != AudioSystem.AUDIO_STATUS_OK) {
Log.e(TAG, "Could not setAllowedCapturePolicy: " + result);
+ return;
}
+ mCapturePolicy = capturePolicy;
+ }
+
+ @AudioAttributes.CapturePolicy
+ private int mCapturePolicy = AudioAttributes.ALLOW_CAPTURE_BY_ALL;
+
+ /**
+ * Return the capture policy.
+ * @return the capture policy set by {@link #setAllowedCapturePolicy(int)} or
+ * the default if it was not called.
+ */
+ @AudioAttributes.CapturePolicy
+ public int getAllowedCapturePolicy() {
+ return mCapturePolicy;
}
//====================================================================
@@ -3026,6 +3051,7 @@
* @param requestResult the result to the focus request to be passed to the requester
* @param ap a valid registered {@link AudioPolicy} configured as a focus policy.
*/
+ @TestApi
@SystemApi
@RequiresPermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING)
public void setFocusRequestResult(@NonNull AudioFocusInfo afi,
@@ -3065,6 +3091,7 @@
* if there was an error sending the request.
* @throws NullPointerException if the {@link AudioFocusInfo} or {@link AudioPolicy} are null.
*/
+ @TestApi
@SystemApi
@RequiresPermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING)
public int dispatchAudioFocusChange(@NonNull AudioFocusInfo afi, int focusChange,
@@ -3327,6 +3354,7 @@
* {@link android.Manifest.permission#MODIFY_AUDIO_ROUTING} permission,
* {@link #SUCCESS} otherwise.
*/
+ @TestApi
@SystemApi
@RequiresPermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING)
public int registerAudioPolicy(@NonNull AudioPolicy policy) {
@@ -3361,6 +3389,7 @@
* Unregisters an {@link AudioPolicy} asynchronously.
* @param policy the non-null {@link AudioPolicy} to unregister.
*/
+ @TestApi
@SystemApi
@RequiresPermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING)
public void unregisterAudioPolicyAsync(@NonNull AudioPolicy policy) {
@@ -3387,6 +3416,7 @@
* associated with mixes of this policy.
* @param policy the non-null {@link AudioPolicy} to unregister.
*/
+ @TestApi
@SystemApi
@RequiresPermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING)
public void unregisterAudioPolicy(@NonNull AudioPolicy policy) {
@@ -5406,8 +5436,9 @@
* {@see android.media.audiopolicy.AudioProductStrategy} objects.
*/
@SystemApi
+ @NonNull
@RequiresPermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING)
- public @NonNull AudioProductStrategies getAudioProductStrategies() {
+ public static List<AudioProductStrategy> getAudioProductStrategies() {
final IAudioService service = getService();
try {
return service.getAudioProductStrategies();
@@ -5421,15 +5452,16 @@
* Introspection API to retrieve audio volume groups.
* When implementing {Car|Oem}AudioManager, use this method to retrieve the collection of
* audio volume groups.
- * @return a (possibly zero-length) array of
- * {@see android.media.audiopolicy.AudioVolumeGroups} objects.
+ * @return a (possibly zero-length) List of
+ * {@see android.media.audiopolicy.AudioVolumeGroup} objects.
*/
@SystemApi
+ @NonNull
@RequiresPermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING)
- public @NonNull AudioVolumeGroups getAudioVolumeGroups() {
+ public static List<AudioVolumeGroup> getAudioVolumeGroups() {
final IAudioService service = getService();
try {
- return service.listAudioVolumeGroups();
+ return service.getAudioVolumeGroups();
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
}
diff --git a/media/java/android/media/AudioPlaybackCaptureConfiguration.java b/media/java/android/media/AudioPlaybackCaptureConfiguration.java
index bcaef03..fe5005a 100644
--- a/media/java/android/media/AudioPlaybackCaptureConfiguration.java
+++ b/media/java/android/media/AudioPlaybackCaptureConfiguration.java
@@ -20,26 +20,35 @@
import android.media.AudioAttributes.AttributeUsage;
import android.media.audiopolicy.AudioMix;
import android.media.audiopolicy.AudioMixingRule;
+import android.media.audiopolicy.AudioMixingRule.AudioMixMatchCriterion;
import android.media.projection.MediaProjection;
import android.os.RemoteException;
import com.android.internal.util.Preconditions;
+import java.util.function.ToIntFunction;
+
/**
* Configuration for capturing audio played by other apps.
*
- * Only the following audio can be captured:
- * - usage MUST be {@link AudioAttributes#USAGE_UNKNOWN} or {@link AudioAttributes#USAGE_GAME}
+ * When capturing audio signals played by other apps (and yours),
+ * you will only capture a mix of the audio signals played by players
+ * (such as AudioTrack or MediaPlayer) which present the following characteristics:
+ * - the usage value MUST be {@link AudioAttributes#USAGE_UNKNOWN} or
+ * {@link AudioAttributes#USAGE_GAME}
* or {@link AudioAttributes#USAGE_MEDIA}. All other usages CAN NOT be captured.
- * - audio attributes MUST have its ${@link AudioAttributes.Builder#setAllowedCapturePolicy}
- * to {@link AudioAttributes#ALLOW_CAPTURE_BY_ALL}.
- * - played by apps that MUST be in the same user profile as the capturing app
- * (eg work profile can not capture user profile apps and vice-versa).
- * - played by apps for which the attribute allowAudioPlaybackCapture in their manifest
+ * - AND the capture policy set by their app (with ${@link AudioManager#setAllowedCapturePolicy})
+ * or on each player (with ${@link AudioAttributes.Builder#setAllowedCapturePolicy}) is
+ * {@link AudioAttributes#ALLOW_CAPTURE_BY_ALL}, whichever is the most strict.
+ * - AND their app attribute allowAudioPlaybackCapture in their manifest
* MUST either be:
* * set to "true"
- * * not set, and their targetSdkVersion MUST be equal or higher to
+ * * not set, and their {@code targetSdkVersion} MUST be equal or higher to
* {@link android.os.Build.VERSION_CODES#Q}.
+ * Ie. Apps that do not target at least Android Q must explicitly opt-in to be captured by a
+ * MediaProjection.
+ * - AND their apps MUST be in the same user profile as your app
+ * (eg work profile can not capture user profile apps and vice-versa).
*
* <p>An example for creating a capture configuration for capturing all media playback:
*
@@ -77,6 +86,39 @@
return mProjection;
}
+ /** @return the usages passed to {@link Builder#addMatchingUsage(int)}. */
+ @AttributeUsage
+ public @NonNull int[] getMatchingUsages() {
+ return getIntPredicates(AudioMixingRule.RULE_MATCH_ATTRIBUTE_USAGE,
+ criterion -> criterion.getAudioAttributes().getUsage());
+ }
+
+ /** @return the UIDs passed to {@link Builder#addMatchingUid(int)}. */
+ public @NonNull int[] getMatchingUids() {
+ return getIntPredicates(AudioMixingRule.RULE_MATCH_UID,
+ criterion -> criterion.getIntProp());
+ }
+
+ /** @return the usages passed to {@link Builder#excludeUsage(int)}. */
+ @AttributeUsage
+ public @NonNull int[] getExcludeUsages() {
+ return getIntPredicates(AudioMixingRule.RULE_EXCLUDE_ATTRIBUTE_USAGE,
+ criterion -> criterion.getAudioAttributes().getUsage());
+ }
+
+ /** @return the UIDs passed to {@link Builder#excludeUid(int)}. */
+ public @NonNull int[] getExcludeUids() {
+ return getIntPredicates(AudioMixingRule.RULE_EXCLUDE_UID,
+ criterion -> criterion.getIntProp());
+ }
+
+ private int[] getIntPredicates(int rule,
+ ToIntFunction<AudioMixMatchCriterion> getPredicate) {
+ return mAudioMixingRule.getCriteria().stream()
+ .filter(criterion -> criterion.getRule() == rule)
+ .mapToInt(getPredicate)
+ .toArray();
+ }
/**
* Returns a mix that routes audio back into the app while still playing it from the speakers.
diff --git a/media/java/android/media/IAudioService.aidl b/media/java/android/media/IAudioService.aidl
index 980cb04..eddbee4 100644
--- a/media/java/android/media/IAudioService.aidl
+++ b/media/java/android/media/IAudioService.aidl
@@ -33,8 +33,8 @@
import android.media.PlayerBase;
import android.media.VolumePolicy;
import android.media.audiopolicy.AudioPolicyConfig;
-import android.media.audiopolicy.AudioProductStrategies;
-import android.media.audiopolicy.AudioVolumeGroups;
+import android.media.audiopolicy.AudioProductStrategy;
+import android.media.audiopolicy.AudioVolumeGroup;
import android.media.audiopolicy.IAudioPolicyCallback;
import android.media.projection.IMediaProjection;
import android.net.Uri;
@@ -86,7 +86,7 @@
@UnsupportedAppUsage
int getStreamMaxVolume(int streamType);
- AudioVolumeGroups listAudioVolumeGroups();
+ List<AudioVolumeGroup> getAudioVolumeGroups();
void setVolumeIndexForAttributes(in AudioAttributes aa, int index, int flags, String callingPackage);
@@ -98,7 +98,7 @@
int getLastAudibleStreamVolume(int streamType);
- AudioProductStrategies getAudioProductStrategies();
+ List<AudioProductStrategy> getAudioProductStrategies();
void setMicrophoneMute(boolean on, String callingPackage, int userId);
diff --git a/media/java/android/media/IMediaRoute2Callback.aidl b/media/java/android/media/IMediaRoute2Callback.aidl
deleted file mode 100644
index f03c8ab..0000000
--- a/media/java/android/media/IMediaRoute2Callback.aidl
+++ /dev/null
@@ -1,24 +0,0 @@
-/*
- * Copyright 2019 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.media;
-
-/**
- * @hide
- */
-oneway interface IMediaRoute2Callback {
- void onRouteSelected(int uid, String routeId);
-}
diff --git a/media/java/android/media/IMediaRoute2Provider.aidl b/media/java/android/media/IMediaRoute2Provider.aidl
deleted file mode 100644
index b97dcc5..0000000
--- a/media/java/android/media/IMediaRoute2Provider.aidl
+++ /dev/null
@@ -1,27 +0,0 @@
-/*
- * Copyright 2019 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.media;
-
-import android.media.IMediaRoute2Callback;
-
-/**
- * {@hide}
- */
-oneway interface IMediaRoute2Provider {
- void setCallback(IMediaRoute2Callback callback);
- void selectRoute(int uid, String id);
-}
diff --git a/media/java/android/media/IMediaRouter2ManagerClient.aidl b/media/java/android/media/IMediaRouter2ManagerClient.aidl
deleted file mode 100644
index 234551b..0000000
--- a/media/java/android/media/IMediaRouter2ManagerClient.aidl
+++ /dev/null
@@ -1,25 +0,0 @@
-/*
- * Copyright 2019 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.media;
-
-/**
- * {@hide}
- */
-oneway interface IMediaRouter2ManagerClient {
- void onRouteSelected(int uid, String routeId);
- void onControlCategoriesChanged(int uid, in List<String> categories);
-}
diff --git a/media/java/android/media/IMediaRouterService.aidl b/media/java/android/media/IMediaRouterService.aidl
index 59f1d0d..3308fc9 100644
--- a/media/java/android/media/IMediaRouterService.aidl
+++ b/media/java/android/media/IMediaRouterService.aidl
@@ -17,7 +17,6 @@
package android.media;
import android.media.IMediaRouterClient;
-import android.media.IMediaRouter2ManagerClient;
import android.media.MediaRouterClientState;
/**
@@ -30,15 +29,8 @@
MediaRouterClientState getState(IMediaRouterClient client);
boolean isPlaybackActive(IMediaRouterClient client);
- void setControlCategories(IMediaRouterClient client, in List<String> categories);
void setDiscoveryRequest(IMediaRouterClient client, int routeTypes, boolean activeScan);
void setSelectedRoute(IMediaRouterClient client, String routeId, boolean explicit);
void requestSetVolume(IMediaRouterClient client, String routeId, int volume);
void requestUpdateVolume(IMediaRouterClient client, String routeId, int direction);
-
- void registerManagerAsUser(IMediaRouter2ManagerClient callback,
- String packageName, int userId);
- void unregisterManager(IMediaRouter2ManagerClient callback);
- void setRemoteRoute(IMediaRouter2ManagerClient callback,
- int uid, String routeId, boolean explicit);
}
diff --git a/media/java/android/media/MediaRoute2ProviderService.java b/media/java/android/media/MediaRoute2ProviderService.java
deleted file mode 100644
index 04ddc30..0000000
--- a/media/java/android/media/MediaRoute2ProviderService.java
+++ /dev/null
@@ -1,108 +0,0 @@
-/*
- * Copyright 2019 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.media;
-
-import static com.android.internal.util.function.pooled.PooledLambda.obtainMessage;
-
-import android.app.Service;
-import android.content.Intent;
-import android.os.Handler;
-import android.os.IBinder;
-import android.os.Looper;
-import android.os.RemoteException;
-import android.util.Log;
-
-/**
- * @hide
- */
-public abstract class MediaRoute2ProviderService extends Service {
- private static final String TAG = "MediaRouteProviderSrv";
-
- public static final String SERVICE_INTERFACE = "android.media.MediaRoute2ProviderService";
-
- private final Handler mHandler;
- private ProviderStub mStub;
- private IMediaRoute2Callback mCallback;
-
- public MediaRoute2ProviderService() {
- mHandler = new Handler(Looper.getMainLooper());
- }
-
- @Override
- public IBinder onBind(Intent intent) {
- if (SERVICE_INTERFACE.equals(intent.getAction())) {
- if (mStub == null) {
- mStub = new ProviderStub();
- }
- return mStub;
- }
- return null;
- }
-
- /**
- * Called when selectRoute is called on a route of the provider.
- *
- * @param uid The target application uid
- * @param routeId The id of the target route
- */
- public abstract void onSelect(int uid, String routeId);
-
- /**
- * Updates provider info from selected route and appliation.
- *
- * TODO: When provider descriptor is defined, this should update the descriptor correctly.
- *
- * @param uid
- * @param routeId
- */
- public void updateProvider(int uid, String routeId) {
- if (mCallback != null) {
- try {
- //TODO: After publishState() is fully implemented, delete this.
- mCallback.onRouteSelected(uid, routeId);
- } catch (RemoteException ex) {
- Log.d(TAG, "Failed to update provider");
- }
- }
- publishState();
- }
-
- void setCallback(IMediaRoute2Callback callback) {
- mCallback = callback;
- publishState();
- }
-
- void publishState() {
- //TODO: Send provider descriptor to the MediaRouterService
- }
-
- final class ProviderStub extends IMediaRoute2Provider.Stub {
- ProviderStub() { }
-
- @Override
- public void setCallback(IMediaRoute2Callback callback) {
- mHandler.sendMessage(obtainMessage(MediaRoute2ProviderService::setCallback,
- MediaRoute2ProviderService.this, callback));
- }
-
- @Override
- public void selectRoute(int uid, String id) {
- mHandler.sendMessage(obtainMessage(MediaRoute2ProviderService::onSelect,
- MediaRoute2ProviderService.this, uid, id));
- }
- }
-}
diff --git a/media/java/android/media/MediaRouter.java b/media/java/android/media/MediaRouter.java
index 5a89d8c..3444e92 100644
--- a/media/java/android/media/MediaRouter.java
+++ b/media/java/android/media/MediaRouter.java
@@ -347,17 +347,6 @@
return mDisplayService.getDisplays(DisplayManager.DISPLAY_CATEGORY_PRESENTATION);
}
- void setControlCategories(List<String> categories) {
- if (mClient != null) {
- try {
- mMediaRouterService.setControlCategories(mClient,
- categories);
- } catch (RemoteException ex) {
- Log.e(TAG, "Unable to set control categories.", ex);
- }
- }
- }
-
private void updatePresentationDisplays(int changedDisplayId) {
final int count = mRoutes.size();
for (int i = 0; i < count; i++) {
@@ -930,25 +919,6 @@
return -1;
}
- //TODO: Remove @hide when it is ready.
- //TODO: Provide pre-defined categories for app developers.
- /**
- * Sets control categories of the client application.
- * Control categories can be used to filter out media routes
- * that don't correspond with the client application.
- * The only routes that match any of the categories will be shown on other applications.
- *
- * @hide
- * @param categories Categories to set
- */
- public void setControlCategories(@NonNull List<String> categories) {
- if (categories == null) {
- throw new IllegalArgumentException("Categories must not be null");
- }
- sStatic.setControlCategories(categories);
- }
-
-
/**
* Select the specified route to use for output of the given media types.
* <p class="note">
diff --git a/media/java/android/media/MediaRouter2Manager.java b/media/java/android/media/MediaRouter2Manager.java
deleted file mode 100644
index ac5958e..0000000
--- a/media/java/android/media/MediaRouter2Manager.java
+++ /dev/null
@@ -1,241 +0,0 @@
-/*
- * Copyright 2019 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.media;
-
-import static com.android.internal.util.function.pooled.PooledLambda.obtainMessage;
-
-import android.annotation.CallbackExecutor;
-import android.annotation.NonNull;
-import android.content.Context;
-import android.os.Handler;
-import android.os.RemoteException;
-import android.os.ServiceManager;
-import android.os.UserHandle;
-import android.util.Log;
-
-import com.android.internal.annotations.GuardedBy;
-
-import java.util.ArrayList;
-import java.util.List;
-import java.util.concurrent.Executor;
-
-/**
- * @hide
- */
-public class MediaRouter2Manager {
- private static final String TAG = "MediaRouter2Manager";
- private static final Object sLock = new Object();
-
- @GuardedBy("sLock")
- private static MediaRouter2Manager sInstance;
-
- final String mPackageName;
-
- private Context mContext;
- private Client mClient;
- private final IMediaRouterService mMediaRouterService;
- final Handler mHandler;
-
- @GuardedBy("sLock")
- final ArrayList<CallbackRecord> mCallbacks = new ArrayList<>();
-
- /**
- * Gets an instance of media router manager that controls media route of other apps.
- * @param context
- * @return
- */
- public static MediaRouter2Manager getInstance(@NonNull Context context) {
- if (context == null) {
- throw new IllegalArgumentException("context must not be null");
- }
- synchronized (sLock) {
- if (sInstance == null) {
- sInstance = new MediaRouter2Manager(context);
- }
- return sInstance;
- }
- }
-
- private MediaRouter2Manager(Context context) {
- mContext = context.getApplicationContext();
- mMediaRouterService = IMediaRouterService.Stub.asInterface(
- ServiceManager.getService(Context.MEDIA_ROUTER_SERVICE));
- mPackageName = mContext.getPackageName();
- mHandler = new Handler(context.getMainLooper());
- }
-
- /**
- * Registers a callback to listen route info.
- *
- * @param executor The executor that runs the callback.
- * @param callback The callback to add.
- */
- public void addCallback(@NonNull @CallbackExecutor Executor executor,
- @NonNull Callback callback) {
-
- if (executor == null) {
- throw new IllegalArgumentException("executor must not be null");
- }
- if (callback == null) {
- throw new IllegalArgumentException("callback must not be null");
- }
-
- synchronized (sLock) {
- final int index = findCallbackRecord(callback);
- if (index >= 0) {
- Log.w(TAG, "Ignore adding the same callback twice.");
- return;
- }
- if (mCallbacks.size() == 0) {
- Client client = new Client();
- try {
- mMediaRouterService.registerManagerAsUser(client, mPackageName,
- UserHandle.myUserId());
- mClient = client;
- } catch (RemoteException ex) {
- Log.e(TAG, "Unable to register media router manager.", ex);
- }
- }
- mCallbacks.add(new CallbackRecord(executor, callback));
- }
- }
-
- /**
- * Removes the specified callback.
- *
- * @param callback The callback to remove.
- */
- public void removeCallback(@NonNull Callback callback) {
- if (callback == null) {
- throw new IllegalArgumentException("callback must not be null");
- }
-
- synchronized (sLock) {
- final int index = findCallbackRecord(callback);
- if (index < 0) {
- Log.w(TAG, "Ignore removing unknown callback. " + callback);
- return;
- }
- mCallbacks.remove(index);
- if (mCallbacks.size() == 0 && mClient != null) {
- try {
- mMediaRouterService.unregisterManager(mClient);
- } catch (RemoteException ex) {
- Log.e(TAG, "Unable to unregister media router manager", ex);
- }
- mClient = null;
- }
- }
- }
-
- private int findCallbackRecord(Callback callback) {
- final int count = mCallbacks.size();
- for (int i = 0; i < count; i++) {
- if (mCallbacks.get(i).mCallback == callback) {
- return i;
- }
- }
- return -1;
- }
-
- /**
- * Selects media route for the specified application uid.
- *
- * @param uid The uid of the application that should change it's media route.
- * @param routeId The id of the route to select
- */
- public void selectRoute(int uid, String routeId) {
- if (mClient != null) {
- try {
- mMediaRouterService.setRemoteRoute(mClient, uid, routeId, /* explicit= */true);
- } catch (RemoteException ex) {
- Log.e(TAG, "Unable to select media route", ex);
- }
- }
- }
-
- /**
- * Unselects media route for the specified application uid.
- *
- * @param uid The uid of the application that should stop routing.
- */
- public void unselectRoute(int uid) {
- if (mClient != null) {
- try {
- mMediaRouterService.setRemoteRoute(mClient, uid, null, /* explicit= */ true);
- } catch (RemoteException ex) {
- Log.e(TAG, "Unable to select media route", ex);
- }
- }
- }
-
- void notifyRouteSelected(int uid, String routeId) {
- for (CallbackRecord record : mCallbacks) {
- record.mExecutor.execute(() -> record.mCallback.onRouteSelected(uid, routeId));
- }
- }
-
- void notifyControlCategoriesChanged(int uid, List<String> categories) {
- for (CallbackRecord record : mCallbacks) {
- record.mExecutor.execute(
- () -> record.mCallback.onControlCategoriesChanged(uid, categories));
- }
- }
-
- /**
- * Interface for receiving events about media routing changes.
- */
- public abstract static class Callback {
- /**
- * Called when a route is selected for some application uid.
- * @param uid
- * @param routeId
- */
- public abstract void onRouteSelected(int uid, String routeId);
-
- /**
- * Called when the control categories of an application is changed.
- * @param uid the uid of the app that changed control categories
- * @param categories the changed categories
- */
- public abstract void onControlCategoriesChanged(int uid, List<String> categories);
- }
-
- final class CallbackRecord {
- public final Executor mExecutor;
- public final Callback mCallback;
-
- CallbackRecord(Executor executor, Callback callback) {
- mExecutor = executor;
- mCallback = callback;
- }
- }
-
- class Client extends IMediaRouter2ManagerClient.Stub {
- @Override
- public void onRouteSelected(int uid, String routeId) {
- mHandler.sendMessage(obtainMessage(MediaRouter2Manager::notifyRouteSelected,
- MediaRouter2Manager.this, uid, routeId));
- }
-
- @Override
- public void onControlCategoriesChanged(int uid, List<String> categories) {
- mHandler.sendMessage(obtainMessage(MediaRouter2Manager::notifyControlCategoriesChanged,
- MediaRouter2Manager.this, uid, categories));
- }
- }
-}
diff --git a/media/java/android/media/audiopolicy/AudioMix.java b/media/java/android/media/audiopolicy/AudioMix.java
index 09f17c0..2f03d26 100644
--- a/media/java/android/media/audiopolicy/AudioMix.java
+++ b/media/java/android/media/audiopolicy/AudioMix.java
@@ -19,6 +19,7 @@
import android.annotation.IntDef;
import android.annotation.NonNull;
import android.annotation.SystemApi;
+import android.annotation.TestApi;
import android.annotation.UnsupportedAppUsage;
import android.media.AudioDeviceInfo;
import android.media.AudioFormat;
@@ -31,6 +32,7 @@
/**
* @hide
*/
+@TestApi
@SystemApi
public class AudioMix {
diff --git a/media/java/android/media/audiopolicy/AudioMixingRule.java b/media/java/android/media/audiopolicy/AudioMixingRule.java
index 947b06c..ed2fdae 100644
--- a/media/java/android/media/audiopolicy/AudioMixingRule.java
+++ b/media/java/android/media/audiopolicy/AudioMixingRule.java
@@ -18,6 +18,7 @@
import android.annotation.NonNull;
import android.annotation.SystemApi;
+import android.annotation.TestApi;
import android.annotation.UnsupportedAppUsage;
import android.media.AudioAttributes;
import android.os.Parcel;
@@ -41,6 +42,7 @@
* .build();
* </pre>
*/
+@TestApi
@SystemApi
public class AudioMixingRule {
@@ -92,7 +94,8 @@
public static final int RULE_EXCLUDE_UID =
RULE_EXCLUSION_MASK | RULE_MATCH_UID;
- static final class AudioMixMatchCriterion {
+ /** @hide */
+ public static final class AudioMixMatchCriterion {
@UnsupportedAppUsage
final AudioAttributes mAttr;
@UnsupportedAppUsage
@@ -137,6 +140,10 @@
dest.writeInt(-1);
}
}
+
+ public AudioAttributes getAudioAttributes() { return mAttr; }
+ public int getIntProp() { return mIntProp; }
+ public int getRule() { return mRule; }
}
boolean isAffectingUsage(int usage) {
@@ -163,7 +170,8 @@
int getTargetMixType() { return mTargetMixType; }
@UnsupportedAppUsage
private final ArrayList<AudioMixMatchCriterion> mCriteria;
- ArrayList<AudioMixMatchCriterion> getCriteria() { return mCriteria; }
+ /** @hide */
+ public ArrayList<AudioMixMatchCriterion> getCriteria() { return mCriteria; }
@UnsupportedAppUsage
private boolean mAllowPrivilegedPlaybackCapture = false;
diff --git a/media/java/android/media/audiopolicy/AudioPolicy.java b/media/java/android/media/audiopolicy/AudioPolicy.java
index 00f6013..1cd60f7 100644
--- a/media/java/android/media/audiopolicy/AudioPolicy.java
+++ b/media/java/android/media/audiopolicy/AudioPolicy.java
@@ -20,6 +20,7 @@
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.annotation.SystemApi;
+import android.annotation.TestApi;
import android.app.ActivityManager;
import android.content.Context;
import android.content.pm.PackageManager;
@@ -55,6 +56,7 @@
* @hide
* AudioPolicy provides access to the management of audio routing and audio focus.
*/
+@TestApi
@SystemApi
public class AudioPolicy {
@@ -237,6 +239,7 @@
}
/**
+ * @hide
* Test method to declare whether this audio focus policy is for test purposes only.
* Having a test policy registered will disable the current focus policy and replace it
* with this test policy. When unregistered, the previous focus policy will be restored.
@@ -245,6 +248,7 @@
* @param isTestFocusPolicy true if the focus policy to register is for testing purposes.
* @return the same Builder instance
*/
+ @TestApi
@NonNull
public Builder setIsTestFocusPolicy(boolean isTestFocusPolicy) {
mIsTestFocusPolicy = isTestFocusPolicy;
diff --git a/media/java/android/media/audiopolicy/AudioProductStrategies.aidl b/media/java/android/media/audiopolicy/AudioProductStrategies.aidl
deleted file mode 100644
index bec11bc..0000000
--- a/media/java/android/media/audiopolicy/AudioProductStrategies.aidl
+++ /dev/null
@@ -1,18 +0,0 @@
-/* Copyright 2018, The Android Open Source Project
-**
-** Licensed under the Apache License, Version 2.0 (the "License");
-** you may not use this file except in compliance with the License.
-** You may obtain a copy of the License at
-**
-** http://www.apache.org/licenses/LICENSE-2.0
-**
-** Unless required by applicable law or agreed to in writing, software
-** distributed under the License is distributed on an "AS IS" BASIS,
-** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-** See the License for the specific language governing permissions and
-** limitations under the License.
-*/
-
-package android.media.audiopolicy;
-
-parcelable AudioProductStrategies;
diff --git a/media/java/android/media/audiopolicy/AudioProductStrategies.java b/media/java/android/media/audiopolicy/AudioProductStrategies.java
deleted file mode 100644
index c305b68..0000000
--- a/media/java/android/media/audiopolicy/AudioProductStrategies.java
+++ /dev/null
@@ -1,277 +0,0 @@
-/*
- * Copyright (C) 2018 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.media.audiopolicy;
-
-import android.annotation.NonNull;
-import android.annotation.Nullable;
-import android.annotation.SystemApi;
-import android.media.AudioAttributes;
-import android.media.AudioSystem;
-import android.os.Parcel;
-import android.os.Parcelable;
-import android.util.Log;
-
-import com.android.internal.util.Preconditions;
-
-import java.util.ArrayList;
-import java.util.Iterator;
-
-/**
- * @hide
- * A class to encapsulate a collection of {@link AudioProductStrategy}.
- * Provides helper functions to easily retrieve the {@link AudioAttributes} for a given product
- * strategy or legacy stream type.
- */
-@SystemApi
-public final class AudioProductStrategies implements Iterable<AudioProductStrategy>, Parcelable {
-
- private final ArrayList<AudioProductStrategy> mAudioProductStrategyList;
-
- private static final String TAG = "AudioProductStrategies";
-
- public AudioProductStrategies() {
- ArrayList<AudioProductStrategy> apsList = new ArrayList<AudioProductStrategy>();
- int status = native_list_audio_product_strategies(apsList);
- if (status != AudioSystem.SUCCESS) {
- Log.w(TAG, ": createAudioProductStrategies failed");
- }
- mAudioProductStrategyList = apsList;
- }
-
- private AudioProductStrategies(ArrayList<AudioProductStrategy> audioProductStrategy) {
- mAudioProductStrategyList = audioProductStrategy;
- }
-
- /**
- * @hide
- * @return number of {@link AudioProductStrategy} objects
- */
- @SystemApi
- public int size() {
- return mAudioProductStrategyList.size();
- }
-
- /**
- * @hide
- * @return the matching {@link AudioProductStrategy} objects with the given id,
- * null object if not found.
- */
- @SystemApi
- public @Nullable AudioProductStrategy getById(int productStrategyId) {
- for (final AudioProductStrategy avg : this) {
- if (avg.getId() == productStrategyId) {
- return avg;
- }
- }
- Log.e(TAG, ": invalid product strategy id: " + productStrategyId + " requested");
- return null;
- }
-
- /**
- * Returns an {@link Iterator}
- */
- @Override
- public @NonNull Iterator<AudioProductStrategy> iterator() {
- return mAudioProductStrategyList.iterator();
- }
-
- @Override
- public boolean equals(@Nullable Object o) {
- if (this == o) return true;
- if (o == null || getClass() != o.getClass()) return false;
-
- AudioProductStrategies that = (AudioProductStrategies) o;
-
- return mAudioProductStrategyList.equals(that.mAudioProductStrategyList);
- }
-
- /**
- * @hide
- * @param aps {@link AudioProductStrategy} (which is the generalisation of Car Audio Usage /
- * legacy routing_strategy linked to {@link AudioAttributes#getUsage()} )
- * @return the {@link AudioAttributes} relevant for the given product strategy.
- * If none is found, it builds the default attributes.
- * TODO: shall the helper collection be able to identify the platform default?
- */
- @SystemApi
- @NonNull
- public AudioAttributes getAudioAttributesForProductStrategy(@NonNull AudioProductStrategy aps) {
- Preconditions.checkNotNull(aps, "AudioProductStrategy must not be null");
- for (final AudioProductStrategy audioProductStrategy : this) {
- if (audioProductStrategy.equals(aps)) {
- return audioProductStrategy.getAudioAttributes();
- }
- }
- return new AudioAttributes.Builder()
- .setContentType(AudioAttributes.CONTENT_TYPE_UNKNOWN)
- .setUsage(AudioAttributes.USAGE_UNKNOWN).build();
- }
-
- /**
- * @hide
- * @param streamType legacy stream type used for volume operation only
- * @return the {@link AudioAttributes} relevant for the given streamType.
- * If none is found, it builds the default attributes.
- */
- @SystemApi
- public @NonNull AudioAttributes getAudioAttributesForLegacyStreamType(int streamType) {
- for (final AudioProductStrategy productStrategy : this) {
- AudioAttributes aa = productStrategy.getAudioAttributesForLegacyStreamType(streamType);
- if (aa != null) {
- return aa;
- }
- }
- return new AudioAttributes.Builder()
- .setContentType(AudioAttributes.CONTENT_TYPE_UNKNOWN)
- .setUsage(AudioAttributes.USAGE_UNKNOWN).build();
- }
-
- /**
- * @hide
- * @param aa the {@link AudioAttributes} for which stream type is requested
- * @return the legacy stream type relevant for the given {@link AudioAttributes}.
- * If the product strategy is not associated to any stream, it returns
- * {@link AudioSystem#STREAM_MUSIC}.
- * If no product strategy supports the stream type, it returns
- * {@link AudioSystem#STREAM_MUSIC}.
- */
- @SystemApi
- public int getLegacyStreamTypeForAudioAttributes(@NonNull AudioAttributes aa) {
- Preconditions.checkNotNull(aa, "AudioAttributes must not be null");
- for (final AudioProductStrategy productStrategy : this) {
- if (productStrategy.supportsAudioAttributes(aa)) {
- int streamType = productStrategy.getLegacyStreamTypeForAudioAttributes(aa);
- if (streamType == AudioSystem.STREAM_DEFAULT) {
- Log.w(TAG, "Attributes " + aa.toString() + " ported by strategy "
- + productStrategy.name() + " has no stream type associated, "
- + "DO NOT USE STREAM TO CONTROL THE VOLUME");
- return AudioSystem.STREAM_MUSIC;
- }
- return streamType;
- }
- }
- return AudioSystem.STREAM_MUSIC;
- }
-
- /**
- * @hide
- * @param aa the {@link AudioAttributes} to be considered
- * @return {@link AudioProductStrategy} supporting the given {@link AudioAttributes}.
- * null is returned if no match with given attributes.
- */
- @SystemApi
- @Nullable
- public AudioProductStrategy getProductStrategyForAudioAttributes(@NonNull AudioAttributes aa) {
- Preconditions.checkNotNull(aa, "attributes must not be null");
- int productStrategyId = native_get_product_strategies_from_audio_attributes(aa);
- if (productStrategyId < 0) {
- Log.w(TAG, "no strategy found for Attributes " + aa.toString());
- return null;
- }
- return getById(productStrategyId);
- }
-
- /**
- * @hide
- * @param attributes the {@link AudioAttributes} to be considered
- * @return volume group associated to the given {@link AudioAttributes}.
- * If no group supports the given {@link AudioAttributes}, it returns the volume group
- * for the default attributes.
- * If no group supports the default attributes, it returns {@link #DEFAULT_VOLUME_GROUP}
- */
- @SystemApi
- public int getVolumeGroupIdForAttributes(@NonNull AudioAttributes attributes) {
- Preconditions.checkNotNull(attributes, "attributes must not be null");
- int volumeGroupId = getVolumeGroupIdForAttributesInt(attributes);
- if (volumeGroupId != AudioVolumeGroups.DEFAULT_VOLUME_GROUP) {
- return volumeGroupId;
- }
- // The default volume group is the one hosted by default product strategy, i.e.
- // supporting Default Attributes
- return getVolumeGroupIdForAttributesInt(AudioProductStrategy.sDefaultAttributes);
- }
-
- /**
- * @hide
- * @param streamType to be considered
- * @return volume group associated to the given stream type.
- */
- @SystemApi
- public int getVolumeGroupIdForLegacyStreamType(int streamType) {
- for (final AudioProductStrategy productStrategy : this) {
- int volumeGroupId = productStrategy.getVolumeGroupIdForLegacyStreamType(streamType);
- if (volumeGroupId != AudioVolumeGroups.DEFAULT_VOLUME_GROUP) {
- return volumeGroupId;
- }
- }
- // The default volume group is the one hosted by default product strategy, i.e.
- // supporting Default Attributes
- return getVolumeGroupIdForAttributesInt(AudioProductStrategy.sDefaultAttributes);
- }
-
- @Override
- public int describeContents() {
- return 0;
- }
-
- @Override
- public void writeToParcel(@NonNull Parcel dest, int flags) {
- dest.writeInt(size());
- for (final AudioProductStrategy productStrategy : this) {
- productStrategy.writeToParcel(dest, flags);
- }
- }
-
- /**
- * @param attributes to be considered
- * @return volume group associated to the given {@link AudioAttributes}.
- */
- private int getVolumeGroupIdForAttributesInt(@NonNull AudioAttributes attributes) {
- Preconditions.checkNotNull(attributes, "attributes must not be null");
- for (final AudioProductStrategy productStrategy : this) {
- int volumeGroupId = productStrategy.getVolumeGroupIdForAudioAttributes(attributes);
- if (volumeGroupId != AudioVolumeGroups.DEFAULT_VOLUME_GROUP) {
- return volumeGroupId;
- }
- }
- return AudioVolumeGroups.DEFAULT_VOLUME_GROUP;
- }
-
- public static final @android.annotation.NonNull Parcelable.Creator<AudioProductStrategies> CREATOR =
- new Parcelable.Creator<AudioProductStrategies>() {
- @Override
- public AudioProductStrategies createFromParcel(@NonNull Parcel in) {
- ArrayList<AudioProductStrategy> apsList = new ArrayList<AudioProductStrategy>();
- int size = in.readInt();
- for (int index = 0; index < size; index++) {
- apsList.add(AudioProductStrategy.CREATOR.createFromParcel(in));
- }
- return new AudioProductStrategies(apsList);
- }
-
- @Override
- public @NonNull AudioProductStrategies[] newArray(int size) {
- return new AudioProductStrategies[size];
- }
- };
-
- private static native int native_list_audio_product_strategies(
- ArrayList<AudioProductStrategy> strategies);
-
- private static native int native_get_product_strategies_from_audio_attributes(
- AudioAttributes attributes);
-}
diff --git a/media/java/android/media/audiopolicy/AudioProductStrategy.java b/media/java/android/media/audiopolicy/AudioProductStrategy.java
index c1c255f..9ac9411 100644
--- a/media/java/android/media/audiopolicy/AudioProductStrategy.java
+++ b/media/java/android/media/audiopolicy/AudioProductStrategy.java
@@ -25,9 +25,14 @@
import android.os.Parcel;
import android.os.Parcelable;
import android.text.TextUtils;
+import android.util.Log;
+import com.android.internal.annotations.GuardedBy;
import com.android.internal.util.Preconditions;
+import java.util.ArrayList;
+import java.util.List;
+
/**
* @hide
* A class to encapsulate a collection of attributes associated to a given product strategy
@@ -41,6 +46,9 @@
*/
public static final int DEFAULT_GROUP = -1;
+
+ private static final String TAG = "AudioProductStrategy";
+
private final AudioAttributesGroup[] mAudioAttributesGroups;
private final String mName;
/**
@@ -51,6 +59,86 @@
*/
private int mId;
+ private static final Object sLock = new Object();
+
+ @GuardedBy("sLock")
+ private static List<AudioProductStrategy> sAudioProductStrategies;
+
+ /**
+ * @hide
+ * @return the list of AudioProductStrategy discovered from platform configuration file.
+ */
+ @NonNull
+ public static List<AudioProductStrategy> getAudioProductStrategies() {
+ if (sAudioProductStrategies == null) {
+ synchronized (sLock) {
+ if (sAudioProductStrategies == null) {
+ sAudioProductStrategies = initializeAudioProductStrategies();
+ }
+ }
+ }
+ return sAudioProductStrategies;
+ }
+
+ /**
+ * @hide
+ * @param streamType to match against AudioProductStrategy
+ * @return the AudioAttributes for the first strategy found with the associated stream type
+ * If no match is found, returns AudioAttributes with unknown content_type and usage
+ */
+ @NonNull
+ public static AudioAttributes getAudioAttributesForStrategyWithLegacyStreamType(
+ int streamType) {
+ for (final AudioProductStrategy productStrategy :
+ AudioProductStrategy.getAudioProductStrategies()) {
+ AudioAttributes aa = productStrategy.getAudioAttributesForLegacyStreamType(streamType);
+ if (aa != null) {
+ return aa;
+ }
+ }
+ return new AudioAttributes.Builder()
+ .setContentType(AudioAttributes.CONTENT_TYPE_UNKNOWN)
+ .setUsage(AudioAttributes.USAGE_UNKNOWN).build();
+ }
+
+ /**
+ * @hide
+ * @param audioAttributes to identify AudioProductStrategy with
+ * @return legacy stream type associated with matched AudioProductStrategy
+ * Defaults to STREAM_MUSIC if no match is found, or if matches is STREAM_DEFAULT
+ */
+ public static int getLegacyStreamTypeForStrategyWithAudioAttributes(
+ @NonNull AudioAttributes audioAttributes) {
+ Preconditions.checkNotNull(audioAttributes, "AudioAttributes must not be null");
+ for (final AudioProductStrategy productStrategy :
+ AudioProductStrategy.getAudioProductStrategies()) {
+ if (productStrategy.supportsAudioAttributes(audioAttributes)) {
+ int streamType = productStrategy.getLegacyStreamTypeForAudioAttributes(
+ audioAttributes);
+ if (streamType == AudioSystem.STREAM_DEFAULT) {
+ Log.w(TAG, "Attributes " + audioAttributes.toString() + " ported by strategy "
+ + productStrategy.getId() + " has no stream type associated, "
+ + "DO NOT USE STREAM TO CONTROL THE VOLUME");
+ return AudioSystem.STREAM_MUSIC;
+ }
+ return streamType;
+ }
+ }
+ return AudioSystem.STREAM_MUSIC;
+ }
+
+ private static List<AudioProductStrategy> initializeAudioProductStrategies() {
+ ArrayList<AudioProductStrategy> apsList = new ArrayList<AudioProductStrategy>();
+ int status = native_list_audio_product_strategies(apsList);
+ if (status != AudioSystem.SUCCESS) {
+ Log.w(TAG, ": initializeAudioProductStrategies failed");
+ }
+ return apsList;
+ }
+
+ private static native int native_list_audio_product_strategies(
+ ArrayList<AudioProductStrategy> strategies);
+
@Override
public boolean equals(@Nullable Object o) {
if (this == o) return true;
@@ -65,8 +153,7 @@
/**
* @param name of the product strategy
* @param id of the product strategy
- * @param audioAttributes {@link AudioAttributes} associated to the given product strategy
- * @param legacyStreamTypes associated to the given product strategy.
+ * @param aag {@link AudioAttributesGroup} associated to the given product strategy
*/
private AudioProductStrategy(@NonNull String name, int id,
@NonNull AudioAttributesGroup[] aag) {
@@ -79,15 +166,6 @@
/**
* @hide
- * @return human-readable name of this product strategy, which is similar to a usage
- */
- @SystemApi
- public @NonNull String name() {
- return mName;
- }
-
- /**
- * @hide
* @return the product strategy ID (which is the generalisation of Car Audio Usage / legacy
* routing_strategy linked to {@link AudioAttributes#getUsage()}).
*/
@@ -158,7 +236,7 @@
* @hide
* @param streamType legacy stream type used for volume operation only
* @return the volume group id relevant for the given streamType.
- * If none is found, {@link AudioVolumeGroups#DEFAULT_VOLUME_GROUP} is returned.
+ * If none is found, {@link AudioVolumeGroup#DEFAULT_VOLUME_GROUP} is returned.
*/
public int getVolumeGroupIdForLegacyStreamType(int streamType) {
for (final AudioAttributesGroup aag : mAudioAttributesGroups) {
@@ -166,14 +244,14 @@
return aag.getVolumeGroupId();
}
}
- return AudioVolumeGroups.DEFAULT_VOLUME_GROUP;
+ return AudioVolumeGroup.DEFAULT_VOLUME_GROUP;
}
/**
* @hide
* @param aa the {@link AudioAttributes} to be considered
* @return the volume group id associated with the given audio attributes if found,
- * {@link AudioVolumeGroups#DEFAULT_VOLUME_GROUP} otherwise.
+ * {@link AudioVolumeGroup#DEFAULT_VOLUME_GROUP} otherwise.
*/
public int getVolumeGroupIdForAudioAttributes(@NonNull AudioAttributes aa) {
Preconditions.checkNotNull(aa, "AudioAttributes must not be null");
@@ -182,7 +260,7 @@
return aag.getVolumeGroupId();
}
}
- return AudioVolumeGroups.DEFAULT_VOLUME_GROUP;
+ return AudioVolumeGroup.DEFAULT_VOLUME_GROUP;
}
@Override
@@ -200,7 +278,8 @@
}
}
- public static final @android.annotation.NonNull Parcelable.Creator<AudioProductStrategy> CREATOR =
+ @NonNull
+ public static final Parcelable.Creator<AudioProductStrategy> CREATOR =
new Parcelable.Creator<AudioProductStrategy>() {
@Override
public AudioProductStrategy createFromParcel(@NonNull Parcel in) {
diff --git a/media/java/android/media/audiopolicy/AudioVolumeGroup.java b/media/java/android/media/audiopolicy/AudioVolumeGroup.java
index b60947f..79be922 100644
--- a/media/java/android/media/audiopolicy/AudioVolumeGroup.java
+++ b/media/java/android/media/audiopolicy/AudioVolumeGroup.java
@@ -19,11 +19,15 @@
import android.annotation.NonNull;
import android.annotation.SystemApi;
import android.media.AudioAttributes;
+import android.media.AudioSystem;
import android.os.Parcel;
import android.os.Parcelable;
+import android.util.Log;
+import com.android.internal.annotations.GuardedBy;
import com.android.internal.util.Preconditions;
+import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
@@ -34,6 +38,12 @@
*/
@SystemApi
public final class AudioVolumeGroup implements Parcelable {
+ private static final String TAG = "AudioVolumeGroup";
+ /**
+ * Volume group value to use when introspection API fails.
+ */
+ public static final int DEFAULT_VOLUME_GROUP = -1;
+
/**
* Unique identifier of a volume group.
*/
@@ -46,10 +56,43 @@
private final AudioAttributes[] mAudioAttributes;
private int[] mLegacyStreamTypes;
+ private static final Object sLock = new Object();
+
+ @GuardedBy("sLock")
+ private static List<AudioVolumeGroup> sAudioVolumeGroups;
+
+ /**
+ * @hide
+ * @return the List of AudioVolumeGroup discovered from platform configuration file.
+ */
+ @NonNull
+ public static List<AudioVolumeGroup> getAudioVolumeGroups() {
+ if (sAudioVolumeGroups == null) {
+ synchronized (sLock) {
+ if (sAudioVolumeGroups == null) {
+ sAudioVolumeGroups = initializeAudioVolumeGroups();
+ }
+ }
+ }
+ return sAudioVolumeGroups;
+ }
+
+ private static List<AudioVolumeGroup> initializeAudioVolumeGroups() {
+ ArrayList<AudioVolumeGroup> avgList = new ArrayList<>();
+ int status = native_list_audio_volume_groups(avgList);
+ if (status != AudioSystem.SUCCESS) {
+ Log.w(TAG, ": listAudioVolumeGroups failed");
+ }
+ return avgList;
+ }
+
+ private static native int native_list_audio_volume_groups(
+ ArrayList<AudioVolumeGroup> groups);
+
/**
* @param name of the volume group
* @param id of the volume group
- * @param followers {@link AudioProductStrategies} strategy following this volume group
+ * @param legacyStreamTypes of volume group
*/
AudioVolumeGroup(@NonNull String name, int id,
@NonNull AudioAttributes[] audioAttributes,
diff --git a/media/java/android/media/audiopolicy/AudioVolumeGroups.aidl b/media/java/android/media/audiopolicy/AudioVolumeGroups.aidl
deleted file mode 100644
index 918cac3..0000000
--- a/media/java/android/media/audiopolicy/AudioVolumeGroups.aidl
+++ /dev/null
@@ -1,18 +0,0 @@
-/* Copyright 2018, The Android Open Source Project
-**
-** Licensed under the Apache License, Version 2.0 (the "License");
-** you may not use this file except in compliance with the License.
-** You may obtain a copy of the License at
-**
-** http://www.apache.org/licenses/LICENSE-2.0
-**
-** Unless required by applicable law or agreed to in writing, software
-** distributed under the License is distributed on an "AS IS" BASIS,
-** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-** See the License for the specific language governing permissions and
-** limitations under the License.
-*/
-
-package android.media.audiopolicy;
-
-parcelable AudioVolumeGroups;
diff --git a/media/java/android/media/audiopolicy/AudioVolumeGroups.java b/media/java/android/media/audiopolicy/AudioVolumeGroups.java
deleted file mode 100644
index 2e56f84..0000000
--- a/media/java/android/media/audiopolicy/AudioVolumeGroups.java
+++ /dev/null
@@ -1,135 +0,0 @@
-/*
- * Copyright (C) 2018 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.media.audiopolicy;
-
-import android.annotation.NonNull;
-import android.annotation.Nullable;
-import android.annotation.SystemApi;
-import android.media.AudioSystem;
-import android.os.Parcel;
-import android.os.Parcelable;
-import android.util.Log;
-
-import com.android.internal.util.Preconditions;
-
-import java.util.ArrayList;
-import java.util.Iterator;
-
-/**
- * @hide
- * A class to encapsulate a collection of {@link AudioVolumeGroup}.
- */
-@SystemApi
-public final class AudioVolumeGroups implements Iterable<AudioVolumeGroup>, Parcelable {
-
- private final ArrayList<AudioVolumeGroup> mAudioVolumeGroupList;
-
- private static final String TAG = "AudioVolumeGroups";
-
- /**
- * Volume group value to use when introspection API fails.
- */
- public static final int DEFAULT_VOLUME_GROUP = -1;
-
- public AudioVolumeGroups() {
- ArrayList<AudioVolumeGroup> avgList = new ArrayList<AudioVolumeGroup>();
- int status = native_list_audio_volume_groups(avgList);
- if (status != AudioSystem.SUCCESS) {
- Log.w(TAG, ": listAudioVolumeGroups failed");
- }
- mAudioVolumeGroupList = avgList;
- }
-
- private AudioVolumeGroups(@NonNull ArrayList<AudioVolumeGroup> audioVolumeGroupList) {
- Preconditions.checkNotNull(audioVolumeGroupList, "audioVolumeGroupList must not be null");
- mAudioVolumeGroupList = audioVolumeGroupList;
- }
-
- /**
- * @return number of {@link AudioProductStrategy} objects
- */
- public int size() {
- return mAudioVolumeGroupList.size();
- }
-
- /**
- * Returns an {@link Iterator}
- */
- @Override
- public @NonNull Iterator<AudioVolumeGroup> iterator() {
- return mAudioVolumeGroupList.iterator();
- }
-
- @Override
- public boolean equals(@NonNull Object o) {
- if (this == o) return true;
- if (o == null || getClass() != o.getClass()) return false;
-
- AudioVolumeGroups that = (AudioVolumeGroups) o;
-
- return mAudioVolumeGroupList.equals(that.mAudioVolumeGroupList);
- }
-
- /**
- * @return the matching {@link AudioVolumeGroup} objects with the given id,
- * null object if not found.
- */
- public @Nullable AudioVolumeGroup getById(int volumeGroupId) {
- for (final AudioVolumeGroup avg : this) {
- if (avg.getId() == volumeGroupId) {
- return avg;
- }
- }
- Log.e(TAG, ": invalid volume group id: " + volumeGroupId + " requested");
- return null;
- }
-
- @Override
- public int describeContents() {
- return 0;
- }
-
- @Override
- public void writeToParcel(@NonNull Parcel dest, int flags) {
- dest.writeInt(size());
- for (final AudioVolumeGroup volumeGroup : this) {
- volumeGroup.writeToParcel(dest, flags);
- }
- }
-
- private static native int native_list_audio_volume_groups(
- ArrayList<AudioVolumeGroup> groups);
-
- public static final Parcelable.Creator<AudioVolumeGroups> CREATOR =
- new Parcelable.Creator<AudioVolumeGroups>() {
- @Override
- public @NonNull AudioVolumeGroups createFromParcel(@NonNull Parcel in) {
- Preconditions.checkNotNull(in, "in Parcel must not be null");
- ArrayList<AudioVolumeGroup> avgList = new ArrayList<AudioVolumeGroup>();
- int size = in.readInt();
- for (int index = 0; index < size; index++) {
- avgList.add(AudioVolumeGroup.CREATOR.createFromParcel(in));
- }
- return new AudioVolumeGroups(avgList);
- }
-
- @Override
- public @NonNull AudioVolumeGroups[] newArray(int size) {
- return new AudioVolumeGroups[size];
- }
- };
-}
diff --git a/media/tests/MediaRouteProvider/Android.bp b/media/tests/MediaRouteProvider/Android.bp
deleted file mode 100644
index da42824..0000000
--- a/media/tests/MediaRouteProvider/Android.bp
+++ /dev/null
@@ -1,18 +0,0 @@
-android_test {
- name: "mediarouteprovider",
-
- srcs: ["**/*.java"],
-
- libs: [
- "android.test.runner",
- "android.test.base",
- ],
-
- static_libs: [
- "android-support-test",
- "mockito-target-minus-junit4",
- ],
-
- platform_apis: true,
- certificate: "platform",
-}
\ No newline at end of file
diff --git a/media/tests/MediaRouteProvider/AndroidManifest.xml b/media/tests/MediaRouteProvider/AndroidManifest.xml
deleted file mode 100644
index 489a621..0000000
--- a/media/tests/MediaRouteProvider/AndroidManifest.xml
+++ /dev/null
@@ -1,30 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright 2019 The Android Open Source Project
-
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
--->
-
-<manifest xmlns:android="http://schemas.android.com/apk/res/android"
- package="com.android.mediarouteprovider.example">
-
- <application android:label="@string/app_name">
- <uses-library android:name="android.test.runner" />
- <service android:name=".SampleMediaRoute2ProviderService"
- android:label="@string/app_name"
- android:exported="true">
- <intent-filter>
- <action android:name="android.media.MediaRoute2ProviderService" />
- </intent-filter>
- </service>
- </application>
-</manifest>
diff --git a/media/tests/MediaRouteProvider/res/values/strings.xml b/media/tests/MediaRouteProvider/res/values/strings.xml
deleted file mode 100644
index bb97064..0000000
--- a/media/tests/MediaRouteProvider/res/values/strings.xml
+++ /dev/null
@@ -1,5 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<resources>
- <!-- name of the app [CHAR LIMIT=25]-->
- <string name="app_name">SampleMediaRouteProvider</string>
-</resources>
\ No newline at end of file
diff --git a/media/tests/MediaRouteProvider/src/com/android/mediarouteprovider/example/SampleMediaRoute2ProviderService.java b/media/tests/MediaRouteProvider/src/com/android/mediarouteprovider/example/SampleMediaRoute2ProviderService.java
deleted file mode 100644
index 22fbd85..0000000
--- a/media/tests/MediaRouteProvider/src/com/android/mediarouteprovider/example/SampleMediaRoute2ProviderService.java
+++ /dev/null
@@ -1,33 +0,0 @@
-/*
- * Copyright 2019 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.mediarouteprovider.example;
-
-import android.content.Intent;
-import android.media.MediaRoute2ProviderService;
-import android.os.IBinder;
-
-public class SampleMediaRoute2ProviderService extends MediaRoute2ProviderService {
- @Override
- public IBinder onBind(Intent intent) {
- return super.onBind(intent);
- }
-
- @Override
- public void onSelect(int uid, String routeId) {
- updateProvider(uid, routeId);
- }
-}
diff --git a/media/tests/MediaRouter/Android.bp b/media/tests/MediaRouter/Android.bp
deleted file mode 100644
index 611b25a..0000000
--- a/media/tests/MediaRouter/Android.bp
+++ /dev/null
@@ -1,18 +0,0 @@
-android_test {
- name: "mediaroutertest",
-
- srcs: ["**/*.java"],
-
- libs: [
- "android.test.runner",
- "android.test.base",
- ],
-
- static_libs: [
- "android-support-test",
- "mockito-target-minus-junit4",
- ],
-
- platform_apis: true,
- certificate: "platform",
-}
\ No newline at end of file
diff --git a/media/tests/MediaRouter/AndroidManifest.xml b/media/tests/MediaRouter/AndroidManifest.xml
deleted file mode 100644
index a34a264..0000000
--- a/media/tests/MediaRouter/AndroidManifest.xml
+++ /dev/null
@@ -1,29 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright 2019 The Android Open Source Project
-
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
--->
-
-<manifest xmlns:android="http://schemas.android.com/apk/res/android"
- package="com.android.mediaroutertest">
-
- <uses-permission android:name="android.permission.CONTROL_MEDIA_ROUTE" />
-
- <application android:label="@string/app_name">
- <uses-library android:name="android.test.runner" />
- </application>
-
- <instrumentation android:name="android.support.test.runner.AndroidJUnitRunner"
- android:targetPackage="com.android.mediaroutertest"
- android:label="MediaRouter Tests"/>
-</manifest>
diff --git a/media/tests/MediaRouter/AndroidTest.xml b/media/tests/MediaRouter/AndroidTest.xml
deleted file mode 100644
index 1301062..0000000
--- a/media/tests/MediaRouter/AndroidTest.xml
+++ /dev/null
@@ -1,16 +0,0 @@
-<configuration description="Runs sample instrumentation test.">
- <target_preparer class="com.android.tradefed.targetprep.TestFilePushSetup"/>
- <target_preparer class="com.android.tradefed.targetprep.TestAppInstallSetup">
- <option name="test-file-name" value="mediaroutertest.apk"/>
- </target_preparer>
- <target_preparer class="com.android.tradefed.targetprep.PushFilePreparer"/>
- <target_preparer class="com.android.tradefed.targetprep.RunCommandTargetPreparer"/>
- <option name="test-suite-tag" value="apct"/>
- <option name="test-tag" value="MediaRouterTest"/>
-
- <test class="com.android.tradefed.testtype.AndroidJUnitTest">
- <option name="package" value="com.android.mediaroutertest"/>
- <option name="runner" value="android.support.test.runner.AndroidJUnitRunner" />
- <option name="hidden-api-checks" value="false"/>
- </test>
-</configuration>
diff --git a/media/tests/MediaRouter/res/values/strings.xml b/media/tests/MediaRouter/res/values/strings.xml
deleted file mode 100644
index 0737020..0000000
--- a/media/tests/MediaRouter/res/values/strings.xml
+++ /dev/null
@@ -1,5 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<resources>
- <!-- name of the app [CHAR LIMIT=25]-->
- <string name="app_name">mediaRouterTest</string>
-</resources>
\ No newline at end of file
diff --git a/media/tests/MediaRouter/src/com/android/mediaroutertest/MediaRouterManagerTest.java b/media/tests/MediaRouter/src/com/android/mediaroutertest/MediaRouterManagerTest.java
deleted file mode 100644
index a4bde65..0000000
--- a/media/tests/MediaRouter/src/com/android/mediaroutertest/MediaRouterManagerTest.java
+++ /dev/null
@@ -1,110 +0,0 @@
-/*
- * Copyright 2019 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.mediaroutertest;
-
-import static org.mockito.Mockito.after;
-import static org.mockito.Mockito.any;
-import static org.mockito.Mockito.eq;
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.timeout;
-import static org.mockito.Mockito.verify;
-
-import android.content.Context;
-import android.media.MediaRouter;
-import android.media.MediaRouter2Manager;
-import android.support.test.InstrumentationRegistry;
-import android.support.test.filters.SmallTest;
-import android.support.test.runner.AndroidJUnit4;
-
-import org.junit.Before;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-
-import java.util.ArrayList;
-import java.util.List;
-import java.util.concurrent.Executor;
-import java.util.concurrent.SynchronousQueue;
-import java.util.concurrent.ThreadPoolExecutor;
-import java.util.concurrent.TimeUnit;
-
-@RunWith(AndroidJUnit4.class)
-@SmallTest
-public class MediaRouterManagerTest {
- private static final String TAG = "MediaRouterManagerTest";
-
- private static final int TARGET_UID = 109992;
- private static final String ROUTE_1 = "MediaRoute1";
-
- private static final int AWAIT_MS = 1000;
- private static final int TIMEOUT_MS = 1000;
-
- private Context mContext;
- private MediaRouter2Manager mManager;
- private MediaRouter mRouter;
- private Executor mExecutor;
-
- private static final List<String> TEST_CONTROL_CATEGORIES = new ArrayList();
- private static final String CONTROL_CATEGORY_1 = "android.media.mediarouter.MEDIA1";
- private static final String CONTROL_CATEGORY_2 = "android.media.mediarouter.MEDIA2";
- static {
- TEST_CONTROL_CATEGORIES.add(CONTROL_CATEGORY_1);
- TEST_CONTROL_CATEGORIES.add(CONTROL_CATEGORY_2);
- }
-
- @Before
- public void setUp() throws Exception {
- mContext = InstrumentationRegistry.getTargetContext();
- mManager = MediaRouter2Manager.getInstance(mContext);
- mRouter = (MediaRouter) mContext.getSystemService(Context.MEDIA_ROUTER_SERVICE);
- mExecutor = new ThreadPoolExecutor(
- 1, 20, 3, TimeUnit.SECONDS,
- new SynchronousQueue<Runnable>());
- }
-
- @Test
- public void transferTest() throws Exception {
- MediaRouter2Manager.Callback mockCallback = mock(MediaRouter2Manager.Callback.class);
-
- mManager.addCallback(mExecutor, mockCallback);
-
- verify(mockCallback, after(AWAIT_MS).never())
- .onRouteSelected(eq(TARGET_UID), any(String.class));
-
- mManager.selectRoute(TARGET_UID, ROUTE_1);
- verify(mockCallback, timeout(TIMEOUT_MS)).onRouteSelected(TARGET_UID, ROUTE_1);
-
- mManager.removeCallback(mockCallback);
- }
-
- @Test
- public void controlCategoryTest() throws Exception {
- final int uid = android.os.Process.myUid();
-
- MediaRouter2Manager.Callback mockCallback = mock(MediaRouter2Manager.Callback.class);
- mManager.addCallback(mExecutor, mockCallback);
-
- verify(mockCallback, after(AWAIT_MS).never()).onControlCategoriesChanged(eq(uid),
- any(List.class));
-
- mRouter.setControlCategories(TEST_CONTROL_CATEGORIES);
- verify(mockCallback, timeout(TIMEOUT_MS).atLeastOnce())
- .onControlCategoriesChanged(uid, TEST_CONTROL_CATEGORIES);
-
- mManager.removeCallback(mockCallback);
- }
-
-}
diff --git a/packages/CarSystemUI/src/com/android/systemui/statusbar/car/CarStatusBar.java b/packages/CarSystemUI/src/com/android/systemui/statusbar/car/CarStatusBar.java
index 44e8874..efebfc2 100644
--- a/packages/CarSystemUI/src/com/android/systemui/statusbar/car/CarStatusBar.java
+++ b/packages/CarSystemUI/src/com/android/systemui/statusbar/car/CarStatusBar.java
@@ -16,6 +16,7 @@
package com.android.systemui.statusbar.car;
+import android.annotation.Nullable;
import android.app.ActivityManager;
import android.app.ActivityTaskManager;
import android.car.drivingstate.CarDrivingStateEvent;
@@ -39,6 +40,7 @@
import com.android.car.notification.NotificationClickHandlerFactory;
import com.android.car.notification.NotificationViewController;
import com.android.car.notification.PreprocessingManager;
+import com.android.internal.statusbar.RegisterStatusBarResult;
import com.android.keyguard.KeyguardUpdateMonitor;
import com.android.systemui.BatteryMeterView;
import com.android.systemui.CarSystemUIFactory;
@@ -259,8 +261,8 @@
@Override
- protected void makeStatusBarView() {
- super.makeStatusBarView();
+ protected void makeStatusBarView(@Nullable RegisterStatusBarResult result) {
+ super.makeStatusBarView(result);
mHvacController = new HvacController(mContext);
CarSystemUIFactory factory = SystemUIFactory.getInstance();
@@ -432,7 +434,7 @@
}
@Override
- protected void createNavigationBar() {
+ protected void createNavigationBar(@Nullable RegisterStatusBarResult result) {
mShowBottom = mContext.getResources().getBoolean(R.bool.config_enableBottomNavigationBar);
mShowLeft = mContext.getResources().getBoolean(R.bool.config_enableLeftNavigationBar);
mShowRight = mContext.getResources().getBoolean(R.bool.config_enableRightNavigationBar);
@@ -443,7 +445,7 @@
// There has been a car customized nav bar on the default display, so just create nav bars
// on external displays.
- mNavigationBarController.createNavigationBars(false /* includeDefaultDisplay */);
+ mNavigationBarController.createNavigationBars(false /* includeDefaultDisplay */, result);
}
private void buildNavBarContent() {
diff --git a/packages/PackageInstaller/TEST_MAPPING b/packages/PackageInstaller/TEST_MAPPING
new file mode 100644
index 0000000..42aa47c
--- /dev/null
+++ b/packages/PackageInstaller/TEST_MAPPING
@@ -0,0 +1,24 @@
+{
+ "presubmit": [
+ {
+ "name": "CtsPackageInstallTestCases",
+ "options": [
+ {
+ "exclude-annotation": "android.platform.test.annotations.AppModeInstant"
+ }
+ ]
+ },
+ {
+ "name": "CtsNoPermissionTestCases"
+ },
+ {
+ "name": "CtsNoPermissionTestCases25"
+ },
+ {
+ "name": "CtsPackageInstallerTapjackingTestCases"
+ },
+ {
+ "name": "CtsPackageUninstallTestCases"
+ }
+ ]
+}
\ No newline at end of file
diff --git a/packages/PackageInstaller/src/com/android/packageinstaller/InstallInstalling.java b/packages/PackageInstaller/src/com/android/packageinstaller/InstallInstalling.java
index cee4666..93f24f7 100755
--- a/packages/PackageInstaller/src/com/android/packageinstaller/InstallInstalling.java
+++ b/packages/PackageInstaller/src/com/android/packageinstaller/InstallInstalling.java
@@ -83,28 +83,6 @@
ApplicationInfo appInfo = getIntent()
.getParcelableExtra(PackageUtil.INTENT_ATTR_APPLICATION_INFO);
mPackageURI = getIntent().getData();
- final File sourceFile = new File(mPackageURI.getPath());
- PackageUtil.AppSnippet as = PackageUtil.getAppSnippet(this, appInfo, sourceFile);
-
- mAlert.setIcon(as.icon);
- mAlert.setTitle(as.label);
- mAlert.setView(R.layout.install_content_view);
- mAlert.setButton(DialogInterface.BUTTON_NEGATIVE, getString(R.string.cancel),
- (ignored, ignored2) -> {
- if (mInstallingTask != null) {
- mInstallingTask.cancel(true);
- }
-
- if (mSessionId > 0) {
- getPackageManager().getPackageInstaller().abandonSession(mSessionId);
- mSessionId = 0;
- }
-
- setResult(RESULT_CANCELED);
- finish();
- }, null);
- setupAlert();
- requireViewById(R.id.installing).setVisibility(View.VISIBLE);
if ("package".equals(mPackageURI.getScheme())) {
try {
@@ -114,6 +92,29 @@
launchFailure(PackageManager.INSTALL_FAILED_INTERNAL_ERROR, null);
}
} else {
+ final File sourceFile = new File(mPackageURI.getPath());
+ PackageUtil.AppSnippet as = PackageUtil.getAppSnippet(this, appInfo, sourceFile);
+
+ mAlert.setIcon(as.icon);
+ mAlert.setTitle(as.label);
+ mAlert.setView(R.layout.install_content_view);
+ mAlert.setButton(DialogInterface.BUTTON_NEGATIVE, getString(R.string.cancel),
+ (ignored, ignored2) -> {
+ if (mInstallingTask != null) {
+ mInstallingTask.cancel(true);
+ }
+
+ if (mSessionId > 0) {
+ getPackageManager().getPackageInstaller().abandonSession(mSessionId);
+ mSessionId = 0;
+ }
+
+ setResult(RESULT_CANCELED);
+ finish();
+ }, null);
+ setupAlert();
+ requireViewById(R.id.installing).setVisibility(View.VISIBLE);
+
if (savedInstanceState != null) {
mSessionId = savedInstanceState.getInt(SESSION_ID);
mInstallId = savedInstanceState.getInt(INSTALL_ID);
diff --git a/packages/PackageInstaller/src/com/android/packageinstaller/InstallStart.java b/packages/PackageInstaller/src/com/android/packageinstaller/InstallStart.java
index f2de9ec..881f4b1 100644
--- a/packages/PackageInstaller/src/com/android/packageinstaller/InstallStart.java
+++ b/packages/PackageInstaller/src/com/android/packageinstaller/InstallStart.java
@@ -109,8 +109,8 @@
} else {
Uri packageUri = intent.getData();
- if (packageUri != null && (packageUri.getScheme().equals(ContentResolver.SCHEME_FILE)
- || packageUri.getScheme().equals(ContentResolver.SCHEME_CONTENT))) {
+ if (packageUri != null && packageUri.getScheme().equals(
+ ContentResolver.SCHEME_CONTENT)) {
// [IMPORTANT] This path is deprecated, but should still work. Only necessary
// features should be added.
diff --git a/packages/SettingsLib/src/com/android/settingslib/graph/ThemedBatteryDrawable.kt b/packages/SettingsLib/src/com/android/settingslib/graph/ThemedBatteryDrawable.kt
index 239b1d4..eff02d2 100644
--- a/packages/SettingsLib/src/com/android/settingslib/graph/ThemedBatteryDrawable.kt
+++ b/packages/SettingsLib/src/com/android/settingslib/graph/ThemedBatteryDrawable.kt
@@ -173,6 +173,7 @@
}
override fun draw(c: Canvas) {
+ c.saveLayer(null, null)
unifiedPath.reset()
levelPath.reset()
levelRect.set(fillRect)
@@ -243,6 +244,7 @@
// And draw the plus sign on top of the fill
c.drawPath(scaledPlus, errorPaint)
}
+ c.restore()
}
private fun batteryColorForLevel(level: Int): Int {
diff --git a/packages/SettingsLib/src/com/android/settingslib/users/UserManagerHelper.java b/packages/SettingsLib/src/com/android/settingslib/users/UserManagerHelper.java
deleted file mode 100644
index 4c45a75..0000000
--- a/packages/SettingsLib/src/com/android/settingslib/users/UserManagerHelper.java
+++ /dev/null
@@ -1,499 +0,0 @@
-/*
- * Copyright (C) 2018 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License
- */
-
-package com.android.settingslib.users;
-
-import android.app.ActivityManager;
-import android.content.BroadcastReceiver;
-import android.content.Context;
-import android.content.Intent;
-import android.content.IntentFilter;
-import android.content.pm.UserInfo;
-import android.graphics.Bitmap;
-import android.graphics.drawable.BitmapDrawable;
-import android.graphics.drawable.Drawable;
-import android.os.SystemProperties;
-import android.os.UserHandle;
-import android.os.UserManager;
-import android.util.Log;
-
-import com.android.internal.util.UserIcons;
-
-import java.util.Iterator;
-import java.util.List;
-
-/**
- * Helper class for managing users, providing methods for removing, adding and switching users.
- *
- * @deprecated - Do not use
- */
-@Deprecated
-public final class UserManagerHelper {
- private static final String TAG = "UserManagerHelper";
- private static final String HEADLESS_SYSTEM_USER = "android.car.systemuser.headless";
- private final Context mContext;
- private final UserManager mUserManager;
- private final ActivityManager mActivityManager;
- private OnUsersUpdateListener mUpdateListener;
- private final BroadcastReceiver mUserChangeReceiver = new BroadcastReceiver() {
- @Override
- public void onReceive(Context context, Intent intent) {
- mUpdateListener.onUsersUpdate();
- }
- };
-
- public UserManagerHelper(Context context) {
- mContext = context;
- mUserManager = (UserManager) mContext.getSystemService(Context.USER_SERVICE);
- mActivityManager = (ActivityManager) mContext.getSystemService(Context.ACTIVITY_SERVICE);
- }
-
- /**
- * Registers a listener for updates to all users - removing, adding users or changing user info.
- *
- * @param listener Instance of {@link OnUsersUpdateListener}.
- */
- public void registerOnUsersUpdateListener(OnUsersUpdateListener listener) {
- mUpdateListener = listener;
- registerReceiver();
- }
-
- /**
- * Unregisters listener by unregistering {@code BroadcastReceiver}.
- */
- public void unregisterOnUsersUpdateListener() {
- unregisterReceiver();
- }
-
- /**
- * Returns {@code true} if the system is in the headless user 0 model.
- *
- * @return {@boolean true} if headless system user.
- */
- public boolean isHeadlessSystemUser() {
- return SystemProperties.getBoolean(HEADLESS_SYSTEM_USER, false);
- }
-
- /**
- * Gets UserInfo for the foreground user.
- *
- * Concept of foreground user is relevant for the multi-user deployment. Foreground user
- * corresponds to the currently "logged in" user.
- *
- * @return {@link UserInfo} for the foreground user.
- */
- public UserInfo getForegroundUserInfo() {
- return mUserManager.getUserInfo(getForegroundUserId());
- }
-
- /**
- * @return Id of the foreground user.
- */
- public int getForegroundUserId() {
- return mActivityManager.getCurrentUser();
- }
-
- /**
- * Gets UserInfo for the user running the caller process.
- *
- * Differentiation between foreground user and current process user is relevant for multi-user
- * deployments.
- *
- * Some multi-user aware components (like SystemUI) might run as a singleton - one component
- * for all users. Current process user is then always the same for that component, even when
- * the foreground user changes.
- *
- * @return {@link UserInfo} for the user running the current process.
- */
- public UserInfo getCurrentProcessUserInfo() {
- return mUserManager.getUserInfo(getCurrentProcessUserId());
- }
-
- /**
- * @return Id for the user running the current process.
- */
- public int getCurrentProcessUserId() {
- return UserHandle.myUserId();
- }
-
- /**
- * Gets all the other users on the system that are not the user running the current process.
- *
- * @return List of {@code UserInfo} for each user that is not the user running the process.
- */
- public List<UserInfo> getAllUsersExcludesCurrentProcessUser() {
- return getAllUsersExceptUser(getCurrentProcessUserId());
- }
-
- /**
- * Gets all the existing users on the system that are not the currently running as the
- * foreground user.
- *
- * @return List of {@code UserInfo} for each user that is not the foreground user.
- */
- public List<UserInfo> getAllUsersExcludesForegroundUser() {
- return getAllUsersExceptUser(getForegroundUserId());
- }
-
- /**
- * Gets all the other users on the system that are not the system user.
- *
- * @return List of {@code UserInfo} for each user that is not the system user.
- */
- public List<UserInfo> getAllUsersExcludesSystemUser() {
- return getAllUsersExceptUser(UserHandle.USER_SYSTEM);
- }
-
- /**
- * Get all the users except the one with userId passed in.
- *
- * @param userId of the user not to be returned.
- * @return All users other than user with userId.
- */
- public List<UserInfo> getAllUsersExceptUser(int userId) {
- List<UserInfo> others = mUserManager.getUsers(/* excludeDying= */true);
-
- for (Iterator<UserInfo> iterator = others.iterator(); iterator.hasNext(); ) {
- UserInfo userInfo = iterator.next();
- if (userInfo.id == userId) {
- // Remove user with userId from the list.
- iterator.remove();
- }
- }
- return others;
- }
-
- /**
- * Gets all the users on the system that are not currently being removed.
- */
- public List<UserInfo> getAllUsers() {
- if (isHeadlessSystemUser()) {
- return getAllUsersExcludesSystemUser();
- }
- return mUserManager.getUsers(/* excludeDying= */true);
- }
-
- // User information accessors
-
- /**
- * Checks whether the user is system user (admin).
- *
- * @param userInfo User to check against system user.
- * @return {@code true} if system user, {@code false} otherwise.
- */
- public boolean userIsSystemUser(UserInfo userInfo) {
- return userInfo.id == UserHandle.USER_SYSTEM;
- }
-
- /**
- * Returns whether this user can be removed from the system.
- *
- * @param userInfo User to be removed
- * @return {@code true} if they can be removed, {@code false} otherwise.
- */
- public boolean userCanBeRemoved(UserInfo userInfo) {
- return !userIsSystemUser(userInfo);
- }
-
- /**
- * Checks whether passed in user is the foreground user.
- *
- * @param userInfo User to check.
- * @return {@code true} if foreground user, {@code false} otherwise.
- */
- public boolean userIsForegroundUser(UserInfo userInfo) {
- return getForegroundUserId() == userInfo.id;
- }
-
- /**
- * Checks whether passed in user is the user that's running the current process.
- *
- * @param userInfo User to check.
- * @return {@code true} if user running the process, {@code false} otherwise.
- */
- public boolean userIsRunningCurrentProcess(UserInfo userInfo) {
- return getCurrentProcessUserId() == userInfo.id;
- }
-
- // Foreground user information accessors.
-
- /**
- * Checks if the foreground user is a guest user.
- */
- public boolean foregroundUserIsGuestUser() {
- return getForegroundUserInfo().isGuest();
- }
-
- /**
- * Return whether the foreground user has a restriction.
- *
- * @param restriction Restriction to check. Should be a UserManager.* restriction.
- * @return Whether that restriction exists for the foreground user.
- */
- public boolean foregroundUserHasUserRestriction(String restriction) {
- return mUserManager.hasUserRestriction(restriction, getForegroundUserInfo().getUserHandle());
- }
-
- /**
- * Checks if the foreground user can add new users.
- */
- public boolean foregroundUserCanAddUsers() {
- return !foregroundUserHasUserRestriction(UserManager.DISALLOW_ADD_USER);
- }
-
- // Current process user information accessors
-
- /**
- * Checks if the calling app is running in a demo user.
- */
- public boolean currentProcessRunningAsDemoUser() {
- return mUserManager.isDemoUser();
- }
-
- /**
- * Checks if the calling app is running as a guest user.
- */
- public boolean currentProcessRunningAsGuestUser() {
- return mUserManager.isGuestUser();
- }
-
- /**
- * Checks whether this process is running under the system user.
- */
- public boolean currentProcessRunningAsSystemUser() {
- return mUserManager.isSystemUser();
- }
-
- // Current process user restriction accessors
-
- /**
- * Return whether the user running the current process has a restriction.
- *
- * @param restriction Restriction to check. Should be a UserManager.* restriction.
- * @return Whether that restriction exists for the user running the process.
- */
- public boolean currentProcessHasUserRestriction(String restriction) {
- return mUserManager.hasUserRestriction(restriction);
- }
-
- /**
- * Checks if the user running the current process can add new users.
- */
- public boolean currentProcessCanAddUsers() {
- return !currentProcessHasUserRestriction(UserManager.DISALLOW_ADD_USER);
- }
-
- /**
- * Checks if the user running the current process can remove users.
- */
- public boolean currentProcessCanRemoveUsers() {
- return !currentProcessHasUserRestriction(UserManager.DISALLOW_REMOVE_USER);
- }
-
- /**
- * Checks if the user running the current process is allowed to switch to another user.
- */
- public boolean currentProcessCanSwitchUsers() {
- return !currentProcessHasUserRestriction(UserManager.DISALLOW_USER_SWITCH);
- }
-
- /**
- * Checks if the current process user can modify accounts. Demo and Guest users cannot modify
- * accounts even if the DISALLOW_MODIFY_ACCOUNTS restriction is not applied.
- */
- public boolean currentProcessCanModifyAccounts() {
- return !currentProcessHasUserRestriction(UserManager.DISALLOW_MODIFY_ACCOUNTS)
- && !currentProcessRunningAsDemoUser()
- && !currentProcessRunningAsGuestUser();
- }
-
- // User actions
-
- /**
- * Creates a new user on the system.
- *
- * @param userName Name to give to the newly created user.
- * @return Newly created user.
- */
- public UserInfo createNewUser(String userName) {
- UserInfo user = mUserManager.createUser(userName, 0 /* flags */);
- if (user == null) {
- // Couldn't create user, most likely because there are too many, but we haven't
- // been able to reload the list yet.
- Log.w(TAG, "can't create user.");
- return null;
- }
- assignDefaultIcon(user);
- return user;
- }
-
- /**
- * Tries to remove the user that's passed in. System user cannot be removed.
- * If the user to be removed is user currently running the process,
- * it switches to the system user first, and then removes the user.
- *
- * @param userInfo User to be removed
- * @return {@code true} if user is successfully removed, {@code false} otherwise.
- */
- public boolean removeUser(UserInfo userInfo) {
- if (userIsSystemUser(userInfo)) {
- Log.w(TAG, "User " + userInfo.id + " is system user, could not be removed.");
- return false;
- }
-
- if (userInfo.id == getCurrentProcessUserId()) {
- switchToUserId(UserHandle.USER_SYSTEM);
- }
-
- return mUserManager.removeUser(userInfo.id);
- }
-
- /**
- * Switches (logs in) to another user.
- *
- * @param userInfo User to switch to.
- */
- public void switchToUser(UserInfo userInfo) {
- if (userInfo.id == getForegroundUserId()) {
- return;
- }
-
- switchToUserId(userInfo.id);
- }
-
- /**
- * Creates a new guest session and switches into the guest session.
- *
- * @param guestName Username for the guest user.
- */
- public void startNewGuestSession(String guestName) {
- UserInfo guest = mUserManager.createGuest(mContext, guestName);
- if (guest == null) {
- // Couldn't create user, most likely because there are too many, but we haven't
- // been able to reload the list yet.
- Log.w(TAG, "can't create user.");
- return;
- }
- assignDefaultIcon(guest);
- switchToUserId(guest.id);
- }
-
- /**
- * Gets an icon for the user.
- *
- * @param userInfo User for which we want to get the icon.
- * @return a Bitmap for the icon
- */
- public Bitmap getUserIcon(UserInfo userInfo) {
- Bitmap picture = mUserManager.getUserIcon(userInfo.id);
-
- if (picture == null) {
- return assignDefaultIcon(userInfo);
- }
-
- return picture;
- }
-
- /**
- * Method for scaling a Bitmap icon to a desirable size.
- *
- * @param icon Bitmap to scale.
- * @param desiredSize Wanted size for the icon.
- * @return Drawable for the icon, scaled to the new size.
- */
- public Drawable scaleUserIcon(Bitmap icon, int desiredSize) {
- Bitmap scaledIcon = Bitmap.createScaledBitmap(
- icon, desiredSize, desiredSize, true /* filter */);
- return new BitmapDrawable(mContext.getResources(), scaledIcon);
- }
-
- /**
- * Sets new Username for the user.
- *
- * @param user User whose name should be changed.
- * @param name New username.
- */
- public void setUserName(UserInfo user, String name) {
- mUserManager.setUserName(user.id, name);
- }
-
- /**
- * Gets a bitmap representing the user's default avatar.
- *
- * @param userInfo User whose avatar should be returned.
- * @return Default user icon
- */
- public Bitmap getUserDefaultIcon(UserInfo userInfo) {
- return UserIcons.convertToBitmap(
- UserIcons.getDefaultUserIcon(mContext.getResources(), userInfo.id, false));
- }
-
- /**
- * Gets a bitmap representing the default icon for a Guest user.
- *
- * @return Degault guest icon
- */
- public Bitmap getGuestDefaultIcon() {
- return UserIcons.convertToBitmap(UserIcons.getDefaultUserIcon(
- mContext.getResources(), UserHandle.USER_NULL, false));
- }
-
- private void registerReceiver() {
- IntentFilter filter = new IntentFilter();
- filter.addAction(Intent.ACTION_USER_REMOVED);
- filter.addAction(Intent.ACTION_USER_ADDED);
- filter.addAction(Intent.ACTION_USER_INFO_CHANGED);
- filter.addAction(Intent.ACTION_USER_SWITCHED);
- filter.addAction(Intent.ACTION_USER_STOPPED);
- filter.addAction(Intent.ACTION_USER_UNLOCKED);
- mContext.registerReceiverAsUser(mUserChangeReceiver, UserHandle.ALL, filter, null, null);
- }
-
- /**
- * Assigns a default icon to a user according to the user's id.
- *
- * @param userInfo User to assign a default icon to.
- * @return Bitmap that has been assigned to the user.
- */
- private Bitmap assignDefaultIcon(UserInfo userInfo) {
- Bitmap bitmap = userInfo.isGuest() ? getGuestDefaultIcon() : getUserDefaultIcon(userInfo);
- mUserManager.setUserIcon(userInfo.id, bitmap);
- return bitmap;
- }
-
- private void switchToUserId(int id) {
- try {
- mActivityManager.switchUser(id);
- } catch (Exception e) {
- Log.e(TAG, "Couldn't switch user.", e);
- }
- }
-
- private void unregisterReceiver() {
- mContext.unregisterReceiver(mUserChangeReceiver);
- }
-
- /**
- * Interface for listeners that want to register for receiving updates to changes to the users
- * on the system including removing and adding users, and changing user info.
- */
- public interface OnUsersUpdateListener {
- /**
- * Method that will get called when users list has been changed.
- */
- void onUsersUpdate();
- }
-}
diff --git a/packages/SettingsLib/tests/integ/src/com/android/settingslib/users/UserManagerHelperTest.java b/packages/SettingsLib/tests/integ/src/com/android/settingslib/users/UserManagerHelperTest.java
deleted file mode 100644
index 46557d3..0000000
--- a/packages/SettingsLib/tests/integ/src/com/android/settingslib/users/UserManagerHelperTest.java
+++ /dev/null
@@ -1,332 +0,0 @@
-/*
- * Copyright (C) 2018 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License
- */
-
-package com.android.settingslib.users;
-
-import static com.google.common.truth.Truth.assertThat;
-
-import static org.mockito.Mockito.verify;
-import static org.mockito.Mockito.when;
-
-import android.app.ActivityManager;
-import android.content.BroadcastReceiver;
-import android.content.Context;
-import android.content.Intent;
-import android.content.IntentFilter;
-import android.content.pm.UserInfo;
-import android.graphics.Bitmap;
-import android.graphics.drawable.Drawable;
-import android.os.Handler;
-import android.os.UserHandle;
-import android.os.UserManager;
-
-import androidx.test.InstrumentationRegistry;
-import androidx.test.runner.AndroidJUnit4;
-
-import org.junit.Before;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.mockito.ArgumentCaptor;
-import org.mockito.Mock;
-import org.mockito.MockitoAnnotations;
-
-import java.util.ArrayList;
-import java.util.List;
-
-@RunWith(AndroidJUnit4.class)
-public class UserManagerHelperTest {
- @Mock
- private Context mContext;
- @Mock
- private UserManager mUserManager;
- @Mock
- private ActivityManager mActivityManager;
- @Mock
- private UserManagerHelper.OnUsersUpdateListener mTestListener;
-
- private UserManagerHelper mHelper;
- private UserInfo mCurrentProcessUser;
- private UserInfo mSystemUser;
-
- @Before
- public void setUp() throws Exception {
- MockitoAnnotations.initMocks(this);
- when(mContext.getSystemService(Context.USER_SERVICE)).thenReturn(mUserManager);
- when(mContext.getSystemService(Context.ACTIVITY_SERVICE)).thenReturn(mActivityManager);
- when(mContext.getResources())
- .thenReturn(InstrumentationRegistry.getTargetContext().getResources());
- mHelper = new UserManagerHelper(mContext);
-
- mCurrentProcessUser = createUserInfoForId(UserHandle.myUserId());
- mSystemUser = createUserInfoForId(UserHandle.USER_SYSTEM);
- when(mUserManager.getUserInfo(UserHandle.myUserId())).thenReturn(mCurrentProcessUser);
- }
-
- @Test
- public void userIsSystemUser() {
- UserInfo testInfo = new UserInfo();
-
- testInfo.id = UserHandle.USER_SYSTEM;
- assertThat(mHelper.userIsSystemUser(testInfo)).isTrue();
-
- testInfo.id = UserHandle.USER_SYSTEM + 2; // Make it different than system id.
- assertThat(mHelper.userIsSystemUser(testInfo)).isFalse();
- }
-
- @Test
- public void getAllUsersExcludesSystemUser() {
- UserInfo otherUser1 = createUserInfoForId(10);
- UserInfo otherUser2 = createUserInfoForId(11);
- UserInfo otherUser3 = createUserInfoForId(12);
-
- List<UserInfo> testUsers = new ArrayList<>();
- testUsers.add(otherUser1);
- testUsers.add(otherUser2);
- testUsers.add(mSystemUser);
- testUsers.add(otherUser3);
-
- when(mUserManager.getUsers(true)).thenReturn(testUsers);
-
- // Should return 3 users that don't have SYSTEM USER id.
- assertThat(mHelper.getAllUsersExcludesSystemUser()).hasSize(3);
- assertThat(mHelper.getAllUsersExcludesSystemUser())
- .containsExactly(otherUser1, otherUser2, otherUser3);
- }
-
- @Test
- public void getAllUsersExceptUser() {
- UserInfo user1 = createUserInfoForId(10);
- UserInfo user2 = createUserInfoForId(10);
- UserInfo user3 = createUserInfoForId(12);
-
- List<UserInfo> testUsers = new ArrayList<>();
- testUsers.add(user1);
- testUsers.add(user2);
- testUsers.add(user3);
-
- when(mUserManager.getUsers(true)).thenReturn(new ArrayList<>(testUsers));
-
- // Should return all 3 users.
- assertThat(mHelper.getAllUsersExceptUser(9).size()).isEqualTo(3);
-
- // Should return only user 12.
- assertThat(mHelper.getAllUsersExceptUser(10).size()).isEqualTo(1);
- assertThat(mHelper.getAllUsersExceptUser(10)).contains(user3);
-
- when(mUserManager.getUsers(true)).thenReturn(new ArrayList<>(testUsers));
-
- // Should drop user 12.
- assertThat(mHelper.getAllUsersExceptUser(12).size()).isEqualTo(2);
- assertThat(mHelper.getAllUsersExceptUser(12)).contains(user1);
- assertThat(mHelper.getAllUsersExceptUser(12)).contains(user2);
- }
-
- @Test
- public void getAllUsers() {
- int currentUser = UserHandle.myUserId();
-
- UserInfo otherUser1 = createUserInfoForId(currentUser + 1);
- UserInfo otherUser2 = createUserInfoForId(currentUser - 1);
- UserInfo otherUser3 = createUserInfoForId(currentUser + 2);
-
- List<UserInfo> testUsers = new ArrayList<>();
- testUsers.add(otherUser1);
- testUsers.add(otherUser2);
- testUsers.add(mCurrentProcessUser);
- testUsers.add(otherUser3);
-
- when(mUserManager.getUsers(true)).thenReturn(testUsers);
-
- assertThat(mHelper.getAllUsers().size()).isEqualTo(4);
- assertThat(mHelper.getAllUsers())
- .containsExactly(mCurrentProcessUser, otherUser1, otherUser2, otherUser3);
- }
-
- @Test
- public void userCanBeRemoved() {
- UserInfo testInfo = new UserInfo();
-
- // System user cannot be removed.
- testInfo.id = UserHandle.USER_SYSTEM;
- assertThat(mHelper.userCanBeRemoved(testInfo)).isFalse();
-
- testInfo.id = UserHandle.USER_SYSTEM + 2; // Make it different than system id.
- assertThat(mHelper.userCanBeRemoved(testInfo)).isTrue();
- }
-
- @Test
- public void currentProcessCanAddUsers() {
- when(mUserManager.hasUserRestriction(UserManager.DISALLOW_ADD_USER)).thenReturn(false);
- assertThat(mHelper.currentProcessCanAddUsers()).isTrue();
-
- when(mUserManager.hasUserRestriction(UserManager.DISALLOW_ADD_USER)).thenReturn(true);
- assertThat(mHelper.currentProcessCanAddUsers()).isFalse();
- }
-
- @Test
- public void currentProcessCanRemoveUsers() {
- when(mUserManager.hasUserRestriction(UserManager.DISALLOW_REMOVE_USER)).thenReturn(false);
- assertThat(mHelper.currentProcessCanRemoveUsers()).isTrue();
-
- when(mUserManager.hasUserRestriction(UserManager.DISALLOW_REMOVE_USER)).thenReturn(true);
- assertThat(mHelper.currentProcessCanRemoveUsers()).isFalse();
- }
-
- @Test
- public void currentProcessCanSwitchUsers() {
- when(mUserManager.hasUserRestriction(UserManager.DISALLOW_USER_SWITCH)).thenReturn(false);
- assertThat(mHelper.currentProcessCanSwitchUsers()).isTrue();
-
- when(mUserManager.hasUserRestriction(UserManager.DISALLOW_USER_SWITCH)).thenReturn(true);
- assertThat(mHelper.currentProcessCanSwitchUsers()).isFalse();
- }
-
- @Test
- public void currentProcessRunningAsGuestCannotModifyAccounts() {
- assertThat(mHelper.currentProcessCanModifyAccounts()).isTrue();
-
- when(mUserManager.isGuestUser()).thenReturn(true);
- assertThat(mHelper.currentProcessCanModifyAccounts()).isFalse();
- }
-
- @Test
- public void currentProcessRunningAsDemoUserCannotModifyAccounts() {
- assertThat(mHelper.currentProcessCanModifyAccounts()).isTrue();
-
- when(mUserManager.isDemoUser()).thenReturn(true);
- assertThat(mHelper.currentProcessCanModifyAccounts()).isFalse();
- }
-
- @Test
- public void currentProcessWithDisallowModifyAccountsRestrictionCannotModifyAccounts() {
- assertThat(mHelper.currentProcessCanModifyAccounts()).isTrue();
-
- when(mUserManager.hasUserRestriction(UserManager.DISALLOW_MODIFY_ACCOUNTS))
- .thenReturn(true);
- assertThat(mHelper.currentProcessCanModifyAccounts()).isFalse();
- }
-
- @Test
- public void createNewUser() {
- // Verify createUser on UserManager gets called.
- mHelper.createNewUser("Test User");
- verify(mUserManager).createUser("Test User", 0);
-
- when(mUserManager.createUser("Test User", 0)).thenReturn(null);
- assertThat(mHelper.createNewUser("Test User")).isNull();
-
- UserInfo newUser = new UserInfo();
- newUser.name = "Test User";
- when(mUserManager.createUser("Test User", 0)).thenReturn(newUser);
- assertThat(mHelper.createNewUser("Test User")).isEqualTo(newUser);
- }
-
- @Test
- public void removeUser() {
- // Cannot remove system user.
- assertThat(mHelper.removeUser(mSystemUser)).isFalse();
-
- // Removing non-current, non-system user, simply calls removeUser.
- UserInfo userToRemove = createUserInfoForId(mCurrentProcessUser.id + 2);
-
- mHelper.removeUser(userToRemove);
- verify(mUserManager).removeUser(mCurrentProcessUser.id + 2);
- }
-
- @Test
- public void startNewGuestSession() {
- mHelper.startNewGuestSession("Test Guest");
- verify(mUserManager).createGuest(mContext, "Test Guest");
-
- UserInfo guestInfo = new UserInfo(21, "Test Guest", UserInfo.FLAG_GUEST);
- when(mUserManager.createGuest(mContext, "Test Guest")).thenReturn(guestInfo);
- mHelper.startNewGuestSession("Test Guest");
- verify(mActivityManager).switchUser(21);
- }
-
- @Test
- public void getUserIcon() {
- mHelper.getUserIcon(mCurrentProcessUser);
- verify(mUserManager).getUserIcon(mCurrentProcessUser.id);
- }
-
- @Test
- public void scaleUserIcon() {
- Bitmap fakeIcon = Bitmap.createBitmap(100, 100, Bitmap.Config.ARGB_8888);
- Drawable scaledIcon = mHelper.scaleUserIcon(fakeIcon, 300);
- assertThat(scaledIcon.getIntrinsicWidth()).isEqualTo(300);
- assertThat(scaledIcon.getIntrinsicHeight()).isEqualTo(300);
- }
-
- @Test
- public void setUserName() {
- UserInfo testInfo = createUserInfoForId(mCurrentProcessUser.id + 3);
- mHelper.setUserName(testInfo, "New Test Name");
- verify(mUserManager).setUserName(mCurrentProcessUser.id + 3, "New Test Name");
- }
-
- @Test
- public void registerUserChangeReceiver() {
- mHelper.registerOnUsersUpdateListener(mTestListener);
-
- ArgumentCaptor<BroadcastReceiver> receiverCaptor =
- ArgumentCaptor.forClass(BroadcastReceiver.class);
- ArgumentCaptor<UserHandle> handleCaptor = ArgumentCaptor.forClass(UserHandle.class);
- ArgumentCaptor<IntentFilter> filterCaptor = ArgumentCaptor.forClass(IntentFilter.class);
- ArgumentCaptor<String> permissionCaptor = ArgumentCaptor.forClass(String.class);
- ArgumentCaptor<Handler> handlerCaptor = ArgumentCaptor.forClass(Handler.class);
-
- verify(mContext).registerReceiverAsUser(
- receiverCaptor.capture(),
- handleCaptor.capture(),
- filterCaptor.capture(),
- permissionCaptor.capture(),
- handlerCaptor.capture());
-
- // Verify we're listening to Intents from ALL users.
- assertThat(handleCaptor.getValue()).isEqualTo(UserHandle.ALL);
-
- // Verify the presence of each intent in the filter.
- // Verify the exact number of filters. Every time a new intent is added, this test should
- // get updated.
- assertThat(filterCaptor.getValue().countActions()).isEqualTo(6);
- assertThat(filterCaptor.getValue().hasAction(Intent.ACTION_USER_REMOVED)).isTrue();
- assertThat(filterCaptor.getValue().hasAction(Intent.ACTION_USER_ADDED)).isTrue();
- assertThat(filterCaptor.getValue().hasAction(Intent.ACTION_USER_INFO_CHANGED)).isTrue();
- assertThat(filterCaptor.getValue().hasAction(Intent.ACTION_USER_SWITCHED)).isTrue();
- assertThat(filterCaptor.getValue().hasAction(Intent.ACTION_USER_STOPPED)).isTrue();
- assertThat(filterCaptor.getValue().hasAction(Intent.ACTION_USER_UNLOCKED)).isTrue();
-
-
- // Verify that calling the receiver calls the listener.
- receiverCaptor.getValue().onReceive(mContext, new Intent());
- verify(mTestListener).onUsersUpdate();
-
- assertThat(permissionCaptor.getValue()).isNull();
- assertThat(handlerCaptor.getValue()).isNull();
-
-
- // Unregister the receiver.
- mHelper.unregisterOnUsersUpdateListener();
- verify(mContext).unregisterReceiver(receiverCaptor.getValue());
- }
-
- private UserInfo createUserInfoForId(int id) {
- UserInfo userInfo = new UserInfo();
- userInfo.id = id;
- return userInfo;
- }
-}
diff --git a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/users/UserManagerHelperRoboTest.java b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/users/UserManagerHelperRoboTest.java
deleted file mode 100644
index 83cc39a..0000000
--- a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/users/UserManagerHelperRoboTest.java
+++ /dev/null
@@ -1,218 +0,0 @@
-/*
- * Copyright (C) 2018 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.settingslib.users;
-
-import static com.google.common.truth.Truth.assertThat;
-
-import static org.mockito.Mockito.verify;
-import static org.mockito.Mockito.when;
-
-import android.app.ActivityManager;
-import android.content.Context;
-import android.content.pm.UserInfo;
-import android.os.UserHandle;
-import android.os.UserManager;
-
-import com.android.settingslib.testutils.shadow.ShadowActivityManager;
-
-import org.junit.After;
-import org.junit.Before;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.mockito.Mock;
-import org.mockito.MockitoAnnotations;
-import org.robolectric.RobolectricTestRunner;
-import org.robolectric.RuntimeEnvironment;
-import org.robolectric.annotation.Config;
-import org.robolectric.annotation.Implementation;
-import org.robolectric.annotation.Implements;
-import org.robolectric.annotation.Resetter;
-
-import java.util.ArrayList;
-import java.util.List;
-
-@RunWith(RobolectricTestRunner.class)
-@Config(shadows = { ShadowActivityManager.class, UserManagerHelperRoboTest.ShadowUserHandle.class})
-public class UserManagerHelperRoboTest {
- @Mock
- private Context mContext;
- @Mock
- private UserManager mUserManager;
-
- private UserManagerHelper mHelper;
-
- @Before
- public void setUpMocksAndUserManagerHelper() {
- MockitoAnnotations.initMocks(this);
- when(mContext.getSystemService(Context.USER_SERVICE)).thenReturn(mUserManager);
- when(mContext.getSystemService(Context.ACTIVITY_SERVICE)).thenReturn(
- RuntimeEnvironment.application.getSystemService(ActivityManager.class));
- mHelper = new UserManagerHelper(mContext);
- }
-
- @After
- public void tearDown() {
- ShadowActivityManager.getShadow().reset();
- }
-
- @Test
- public void getForegroundUserId() {
- ShadowActivityManager.setCurrentUser(15);
- assertThat(mHelper.getForegroundUserId()).isEqualTo(15);
- }
-
- @Test
- public void getForegroundUserInfo() {
- ShadowActivityManager.setCurrentUser(17);
- when(mUserManager.getUserInfo(ActivityManager.getCurrentUser()))
- .thenReturn(createUserInfoForId(ActivityManager.getCurrentUser()));
- assertThat(mHelper.getForegroundUserInfo().id).isEqualTo(17);
- }
-
- @Test
- public void getCurrentProcessUserId() {
- ShadowUserHandle.setUid(11);
- assertThat(mHelper.getCurrentProcessUserId()).isEqualTo(11);
- }
-
- @Test
- public void getCurrentProcessUserInfo() {
- ShadowUserHandle.setUid(12);
- when(mUserManager.getUserInfo(UserHandle.myUserId()))
- .thenReturn(createUserInfoForId(UserHandle.myUserId()));
- assertThat(mHelper.getCurrentProcessUserInfo().id).isEqualTo(12);
- }
-
- @Test
- public void getAllUsersExcludesCurrentProcessUser() {
- ShadowUserHandle.setUid(12);
- UserInfo currentProcessUser = createUserInfoForId(12);
-
- UserInfo otherUser1 = createUserInfoForId(13);
- UserInfo otherUser2 = createUserInfoForId(11);
- UserInfo otherUser3 = createUserInfoForId(14);
-
- List<UserInfo> testUsers = new ArrayList<>();
- testUsers.add(otherUser1);
- testUsers.add(otherUser2);
- testUsers.add(currentProcessUser);
- testUsers.add(otherUser3);
-
- when(mUserManager.getUsers(true)).thenReturn(testUsers);
-
- // Should return 3 users that don't have currentProcessUser id.
- assertThat(mHelper.getAllUsersExcludesCurrentProcessUser()).hasSize(3);
- assertThat(mHelper.getAllUsersExcludesCurrentProcessUser())
- .containsExactly(otherUser1, otherUser2, otherUser3);
- }
-
- @Test
- public void getAllUsersExcludesForegroundUser() {
- ShadowActivityManager.setCurrentUser(17);
- UserInfo foregroundUser = createUserInfoForId(17);
-
- UserInfo otherUser1 = createUserInfoForId(11);
- UserInfo otherUser2 = createUserInfoForId(18);
- UserInfo otherUser3 = createUserInfoForId(16);
-
- List<UserInfo> testUsers = new ArrayList<>();
- testUsers.add(otherUser1);
- testUsers.add(otherUser2);
- testUsers.add(foregroundUser);
- testUsers.add(otherUser3);
-
- when(mUserManager.getUsers(true)).thenReturn(testUsers);
-
- // Should return 3 users that don't have foregroundUser id.
- assertThat(mHelper.getAllUsersExcludesForegroundUser()).hasSize(3);
- assertThat(mHelper.getAllUsersExcludesForegroundUser())
- .containsExactly(otherUser1, otherUser2, otherUser3);
- }
-
- @Test
- public void userIsForegroundUser() {
- ShadowActivityManager.setCurrentUser(10);
- assertThat(mHelper.userIsForegroundUser(createUserInfoForId(10))).isTrue();
- assertThat(mHelper.userIsForegroundUser(createUserInfoForId(11))).isFalse();
-
- ShadowActivityManager.setCurrentUser(11);
- assertThat(mHelper.userIsForegroundUser(createUserInfoForId(11))).isTrue();
- }
-
- @Test
- public void userIsRunningCurrentProcess() {
- ShadowUserHandle.setUid(10);
- assertThat(mHelper.userIsRunningCurrentProcess(createUserInfoForId(10))).isTrue();
- assertThat(mHelper.userIsRunningCurrentProcess(createUserInfoForId(11))).isFalse();
-
- ShadowUserHandle.setUid(11);
- assertThat(mHelper.userIsRunningCurrentProcess(createUserInfoForId(11))).isTrue();
- }
-
- @Test
- public void removingCurrentProcessUserSwitchesToSystemUser() {
- // Set currentProcess user to be user 10.
- ShadowUserHandle.setUid(10);
-
- // Removing a currentProcess user, calls "switch" to system user
- mHelper.removeUser(createUserInfoForId(10));
- assertThat(ShadowActivityManager.getShadow().getSwitchUserCalled()).isTrue();
- assertThat(ShadowActivityManager.getShadow().getUserSwitchedTo()).isEqualTo(0);
-
- verify(mUserManager).removeUser(10);
- }
-
- @Test
- public void switchToUser() {
- ShadowActivityManager.setCurrentUser(20);
-
- // Switching to foreground user doesn't do anything.
- mHelper.switchToUser(createUserInfoForId(20));
- assertThat(ShadowActivityManager.getShadow().getSwitchUserCalled()).isFalse();
-
- // Switching to non-foreground user, simply calls switchUser.
- UserInfo userToSwitchTo = new UserInfo(22, "Test User", 0);
- mHelper.switchToUser(userToSwitchTo);
- assertThat(ShadowActivityManager.getShadow().getSwitchUserCalled()).isTrue();
- assertThat(ShadowActivityManager.getShadow().getUserSwitchedTo()).isEqualTo(22);
- }
-
- private UserInfo createUserInfoForId(int id) {
- UserInfo userInfo = new UserInfo();
- userInfo.id = id;
- return userInfo;
- }
-
- @Implements(UserHandle.class)
- public static class ShadowUserHandle {
- private static int sUid = 0; // SYSTEM by default
-
- public static void setUid(int uid) {
- sUid = uid;
- }
-
- @Implementation
- public static int myUserId() {
- return sUid;
- }
-
- @Resetter
- public static void reset() {
- sUid = 0;
- }
- }
-}
diff --git a/packages/SystemUI/res/layout/ongoing_privacy_chip.xml b/packages/SystemUI/res/layout/ongoing_privacy_chip.xml
index b16e062..49c16be 100644
--- a/packages/SystemUI/res/layout/ongoing_privacy_chip.xml
+++ b/packages/SystemUI/res/layout/ongoing_privacy_chip.xml
@@ -23,21 +23,20 @@
android:layout_width="wrap_content"
android:layout_marginLeft="@dimen/ongoing_appops_chip_margin"
android:layout_marginRight="@dimen/ongoing_appops_chip_margin"
- android:layout_gravity="center_vertical|start"
+ android:layout_gravity="center_vertical|end"
android:gravity="center_vertical"
android:orientation="horizontal"
- android:focusable="true">
+ android:focusable="true" >
<FrameLayout
android:id="@+id/background"
android:layout_height="@dimen/ongoing_appops_chip_height"
- android:layout_width="wrap_content"
- >
+ android:minWidth="48dp"
+ android:layout_width="wrap_content" >
<LinearLayout
android:id="@+id/icons_container"
android:layout_height="match_parent"
android:layout_width="wrap_content"
- android:layout_gravity="center"
android:gravity="center_vertical"
/>
</FrameLayout>
diff --git a/packages/SystemUI/res/values/dimens.xml b/packages/SystemUI/res/values/dimens.xml
index 74924fb..bfdb218 100644
--- a/packages/SystemUI/res/values/dimens.xml
+++ b/packages/SystemUI/res/values/dimens.xml
@@ -1044,7 +1044,7 @@
<!-- Margin between icons of Ongoing App Ops chip when QS-->
<dimen name="ongoing_appops_chip_icon_margin_expanded">2dp</dimen>
<!-- Icon size of Ongoing App Ops chip -->
- <dimen name="ongoing_appops_chip_icon_size">@*android:dimen/status_bar_icon_size</dimen>
+ <dimen name="ongoing_appops_chip_icon_size">@dimen/status_bar_icon_drawing_size</dimen>
<!-- Radius of Ongoing App Ops chip corners -->
<dimen name="ongoing_appops_chip_bg_corner_radius">16dp</dimen>
diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardUpdateMonitor.java b/packages/SystemUI/src/com/android/keyguard/KeyguardUpdateMonitor.java
index fa39ccd..fd55708 100644
--- a/packages/SystemUI/src/com/android/keyguard/KeyguardUpdateMonitor.java
+++ b/packages/SystemUI/src/com/android/keyguard/KeyguardUpdateMonitor.java
@@ -1665,7 +1665,7 @@
}
mFaceCancelSignal = new CancellationSignal();
mFaceManager.authenticate(null, mFaceCancelSignal, 0,
- mFaceAuthenticationCallback, null);
+ mFaceAuthenticationCallback, null, userId);
setFaceRunningState(BIOMETRIC_STATE_RUNNING);
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/BatteryMeterView.java b/packages/SystemUI/src/com/android/systemui/BatteryMeterView.java
index 329b001..6c1d1f9 100644
--- a/packages/SystemUI/src/com/android/systemui/BatteryMeterView.java
+++ b/packages/SystemUI/src/com/android/systemui/BatteryMeterView.java
@@ -180,10 +180,6 @@
setClipChildren(false);
setClipToPadding(false);
Dependency.get(ConfigurationController.class).observe(viewAttachLifecycle(this), this);
-
- // Needed for PorderDuff.Mode.CLEAR operations to work properly, but redraws don't happen
- // enough to justify a hardware layer.
- setLayerType(LAYER_TYPE_SOFTWARE, null);
}
private void setupLayoutTransition() {
@@ -405,10 +401,10 @@
|| mShowPercentMode == MODE_ON || mShowPercentMode == MODE_ESTIMATE) {
if (!showing) {
mBatteryPercentView = loadPercentView();
- if (mTextColor != 0) mBatteryPercentView.setTextColor(mTextColor);
if (mPercentageStyleId != 0) { // Only set if specified as attribute
mBatteryPercentView.setTextAppearance(mPercentageStyleId);
}
+ if (mTextColor != 0) mBatteryPercentView.setTextColor(mTextColor);
updatePercentText();
addView(mBatteryPercentView,
new ViewGroup.LayoutParams(
diff --git a/packages/SystemUI/src/com/android/systemui/Dependency.java b/packages/SystemUI/src/com/android/systemui/Dependency.java
index 70f2cce..a421940 100644
--- a/packages/SystemUI/src/com/android/systemui/Dependency.java
+++ b/packages/SystemUI/src/com/android/systemui/Dependency.java
@@ -293,6 +293,7 @@
@Inject Lazy<DevicePolicyManagerWrapper> mDevicePolicyManagerWrapper;
@Inject Lazy<PackageManagerWrapper> mPackageManagerWrapper;
@Inject Lazy<SensorPrivacyController> mSensorPrivacyController;
+ @Inject Lazy<DumpController> mDumpController;
@Inject
public Dependency() {
@@ -464,7 +465,7 @@
mProviders.put(DevicePolicyManagerWrapper.class, mDevicePolicyManagerWrapper::get);
mProviders.put(PackageManagerWrapper.class, mPackageManagerWrapper::get);
mProviders.put(SensorPrivacyController.class, mSensorPrivacyController::get);
-
+ mProviders.put(DumpController.class, mDumpController::get);
// TODO(b/118592525): to support multi-display , we start to add something which is
// per-display, while others may be global. I think it's time to add
@@ -478,6 +479,11 @@
@Override
public synchronized void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
super.dump(fd, pw, args);
+
+ // Make sure that the DumpController gets added to mDependencies, as they are only added
+ // with Dependency#get.
+ getDependency(DumpController.class);
+
pw.println("Dumping existing controllers:");
mDependencies.values().stream().filter(obj -> obj instanceof Dumpable)
.forEach(o -> ((Dumpable) o).dump(fd, pw, args));
diff --git a/packages/SystemUI/src/com/android/systemui/DumpController.kt b/packages/SystemUI/src/com/android/systemui/DumpController.kt
new file mode 100644
index 0000000..646abb5
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/DumpController.kt
@@ -0,0 +1,86 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License
+ */
+
+package com.android.systemui
+
+import android.util.Log
+import androidx.annotation.GuardedBy
+import com.android.internal.util.Preconditions
+import java.io.FileDescriptor
+import java.io.PrintWriter
+import java.lang.ref.WeakReference
+import javax.inject.Inject
+import javax.inject.Singleton
+
+// TODO: Move all Dumpable dependencies to use DumpController
+/**
+ * Controller that allows any [Dumpable] to subscribe and be dumped along with other SystemUI
+ * dependencies.
+ */
+@Singleton
+class DumpController @Inject constructor() : Dumpable {
+
+ companion object {
+ private const val TAG = "DumpController"
+ private const val DEBUG = false
+ }
+
+ @GuardedBy("listeners")
+ private val listeners = mutableListOf<WeakReference<Dumpable>>()
+ val numListeners: Int
+ get() = listeners.size
+
+ /**
+ * Adds a [Dumpable] listener to be dumped. It will only be added if it is not already tracked.
+ *
+ * @param listener the [Dumpable] to be added
+ */
+ fun addListener(listener: Dumpable) {
+ Preconditions.checkNotNull(listener, "The listener to be added cannot be null")
+ if (DEBUG) Log.v(TAG, "*** register callback for $listener")
+ synchronized<Unit>(listeners) {
+ if (listeners.any { it.get() == listener }) {
+ if (DEBUG) {
+ Log.e(TAG, "Object tried to add another callback")
+ }
+ } else {
+ listeners.add(WeakReference(listener))
+ }
+ }
+ }
+
+ /**
+ * Removes a listener from the list of elements to be dumped.
+ *
+ * @param listener the [Dumpable] to be removed.
+ */
+ fun removeListener(listener: Dumpable) {
+ if (DEBUG) Log.v(TAG, "*** unregister callback for $listener")
+ synchronized(listeners) {
+ listeners.removeAll { it.get() == listener || it.get() == null }
+ }
+ }
+
+ /**
+ * Dump all the [Dumpable] registered with the controller
+ */
+ override fun dump(fd: FileDescriptor?, pw: PrintWriter, args: Array<String>?) {
+ pw.println("DumpController state:")
+ synchronized(listeners) {
+ listeners.forEach { it.get()?.dump(fd, pw, args) }
+ }
+ }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/bubbles/BubbleStackView.java b/packages/SystemUI/src/com/android/systemui/bubbles/BubbleStackView.java
index 686edad..424cd55 100644
--- a/packages/SystemUI/src/com/android/systemui/bubbles/BubbleStackView.java
+++ b/packages/SystemUI/src/com/android/systemui/bubbles/BubbleStackView.java
@@ -926,6 +926,7 @@
mFlyout.removeCallbacks(mHideFlyout);
mFlyout.postDelayed(mHideFlyout, FLYOUT_HIDE_AFTER);
});
+ logBubbleEvent(bubble, StatsLog.BUBBLE_UICHANGED__ACTION__FLYOUT);
}
}
@@ -1097,7 +1098,8 @@
* @param action the user interaction enum.
*/
private void logBubbleEvent(@Nullable Bubble bubble, int action) {
- if (bubble == null) {
+ if (bubble == null || bubble.entry == null
+ || bubble.entry.notification == null) {
StatsLog.write(StatsLog.BUBBLE_UI_CHANGED,
null /* package name */,
null /* notification channel */,
diff --git a/packages/SystemUI/src/com/android/systemui/glwallpaper/ImageGLWallpaper.java b/packages/SystemUI/src/com/android/systemui/glwallpaper/ImageGLWallpaper.java
index 21406e5..d935466 100644
--- a/packages/SystemUI/src/com/android/systemui/glwallpaper/ImageGLWallpaper.java
+++ b/packages/SystemUI/src/com/android/systemui/glwallpaper/ImageGLWallpaper.java
@@ -34,7 +34,6 @@
import android.graphics.Bitmap;
import android.opengl.GLUtils;
-import android.os.Build;
import android.util.Log;
import java.nio.ByteBuffer;
@@ -196,58 +195,76 @@
glUniform1i(mUniTexture, 0);
}
+ /**
+ * This method adjust s(x-axis), t(y-axis) texture coordinates
+ * to prevent the wallpaper from being stretched.
+ * The adjustment happens if either the width or height of the bitmap is larger than
+ * corresponding size of the surface.
+ * If both width and height are larger than corresponding size of the surface,
+ * the adjustment will happen at both s, t side.
+ *
+ * @param bitmapWidth The width of the bitmap.
+ * @param bitmapHeight The height of the bitmap.
+ * @param surfaceWidth The width of the surface.
+ * @param surfaceHeight The height of the surface.
+ * @param xOffset The offset amount along s axis.
+ * @param yOffset The offset amount along t axis.
+ */
void adjustTextureCoordinates(int bitmapWidth, int bitmapHeight,
int surfaceWidth, int surfaceHeight, float xOffset, float yOffset) {
- float ratioW = 1f;
- float ratioH = 1f;
- float rX = 0f;
- float rY = 0f;
- float[] coordinates = null;
+ float[] coordinates = TEXTURES.clone();
- final boolean adjustWidth = bitmapWidth > surfaceWidth;
- final boolean adjustHeight = bitmapHeight > surfaceHeight;
-
- if (adjustWidth || adjustHeight) {
- coordinates = TEXTURES.clone();
- }
-
- if (adjustWidth) {
- float x = (float) Math.round((bitmapWidth - surfaceWidth) * xOffset) / bitmapWidth;
- ratioW = (float) surfaceWidth / bitmapWidth;
- float referenceX = x + ratioW > 1f ? 1f - ratioW : x;
+ if (bitmapWidth > surfaceWidth) {
+ // Calculate the new s pos in pixels.
+ float pixelS = (float) Math.round((bitmapWidth - surfaceWidth) * xOffset);
+ // Calculate the s pos in texture coordinate.
+ float coordinateS = pixelS / bitmapWidth;
+ // Calculate the percentage occupied by the surface width in bitmap width.
+ float surfacePercentageW = (float) surfaceWidth / bitmapWidth;
+ // Need also consider the case if bitmap height is smaller than surface height.
+ if (bitmapHeight < surfaceHeight) {
+ // We will narrow the surface percentage to keep aspect ratio.
+ surfacePercentageW *= (float) bitmapHeight / surfaceHeight;
+ }
+ // Determine the final s pos, also limit the legal s pos to prevent from out of range.
+ float s = coordinateS + surfacePercentageW > 1f ? 1f - surfacePercentageW : coordinateS;
+ // Traverse the s pos in texture coordinates array and adjust the s pos accordingly.
for (int i = 0; i < coordinates.length; i += 2) {
+ // indices 2, 4 and 6 are the end of s coordinates.
if (i == 2 || i == 4 || i == 6) {
- coordinates[i] = Math.min(1f, referenceX + ratioW);
+ coordinates[i] = Math.min(1f, s + surfacePercentageW);
} else {
- coordinates[i] = referenceX;
+ coordinates[i] = s;
}
}
- rX = referenceX;
}
-
- if (adjustHeight) {
- float y = (float) Math.round((bitmapHeight - surfaceHeight) * yOffset) / bitmapHeight;
- ratioH = (float) surfaceHeight / bitmapHeight;
- float referenceY = y + ratioH > 1f ? 1f - ratioH : y;
+ if (bitmapHeight > surfaceHeight) {
+ // Calculate the new t pos in pixels.
+ float pixelT = (float) Math.round((bitmapHeight - surfaceHeight) * yOffset);
+ // Calculate the t pos in texture coordinate.
+ float coordinateT = pixelT / bitmapHeight;
+ // Calculate the percentage occupied by the surface height in bitmap height.
+ float surfacePercentageH = (float) surfaceHeight / bitmapHeight;
+ // Need also consider the case if bitmap width is smaller than surface width.
+ if (bitmapWidth < surfaceWidth) {
+ // We will narrow the surface percentage to keep aspect ratio.
+ surfacePercentageH *= (float) bitmapWidth / surfaceWidth;
+ }
+ // Determine the final t pos, also limit the legal t pos to prevent from out of range.
+ float t = coordinateT + surfacePercentageH > 1f ? 1f - surfacePercentageH : coordinateT;
+ // Traverse the t pos in texture coordinates array and adjust the t pos accordingly.
for (int i = 1; i < coordinates.length; i += 2) {
+ // indices 1, 3 and 11 are the end of t coordinates.
if (i == 1 || i == 3 || i == 11) {
- coordinates[i] = Math.min(1f, referenceY + ratioH);
+ coordinates[i] = Math.min(1f, t + surfacePercentageH);
} else {
- coordinates[i] = referenceY;
+ coordinates[i] = t;
}
}
- rY = referenceY;
}
- if (adjustWidth || adjustHeight) {
- if (Build.IS_DEBUGGABLE) {
- Log.d(TAG, "adjustTextureCoordinates: sW=" + surfaceWidth + ", sH=" + surfaceHeight
- + ", bW=" + bitmapWidth + ", bH=" + bitmapHeight
- + ", rW=" + ratioW + ", rH=" + ratioH + ", rX=" + rX + ", rY=" + rY);
- }
- mTextureBuffer.put(coordinates);
- mTextureBuffer.position(0);
- }
+ mTextureBuffer.put(coordinates);
+ mTextureBuffer.position(0);
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/privacy/OngoingPrivacyChip.kt b/packages/SystemUI/src/com/android/systemui/privacy/OngoingPrivacyChip.kt
index 23742c0..a5a915b 100644
--- a/packages/SystemUI/src/com/android/systemui/privacy/OngoingPrivacyChip.kt
+++ b/packages/SystemUI/src/com/android/systemui/privacy/OngoingPrivacyChip.kt
@@ -16,13 +16,12 @@
import android.content.Context
import android.util.AttributeSet
+import android.view.Gravity
import android.view.ViewGroup
import android.widget.FrameLayout
import android.widget.ImageView
import android.widget.LinearLayout
-import com.android.systemui.Dependency
import com.android.systemui.R
-import com.android.systemui.statusbar.policy.KeyguardMonitor
class OngoingPrivacyChip @JvmOverloads constructor(
context: Context,
@@ -51,8 +50,7 @@
updateView()
}
}
- @Suppress("DEPRECATION")
- private val keyguardMonitor = Dependency.get(KeyguardMonitor::class.java)
+
var builder = PrivacyDialogBuilder(context, emptyList<PrivacyItem>())
var privacyList = emptyList<PrivacyItem>()
set(value) {
@@ -94,14 +92,16 @@
if (!privacyList.isEmpty()) {
generateContentDescription()
setIcons(builder, iconsContainer)
+ val lp = iconsContainer.layoutParams as FrameLayout.LayoutParams
+ lp.gravity = Gravity.CENTER_VERTICAL or
+ (if (expanded) Gravity.CENTER_HORIZONTAL else Gravity.END)
+ iconsContainer.layoutParams = lp
} else {
iconsContainer.removeAllViews()
}
requestLayout()
}
- private fun amISecure() = keyguardMonitor.isShowing && keyguardMonitor.isSecure
-
private fun generateContentDescription() {
val typesText = builder.joinTypes()
contentDescription = context.getString(
diff --git a/packages/SystemUI/src/com/android/systemui/privacy/PrivacyItem.kt b/packages/SystemUI/src/com/android/systemui/privacy/PrivacyItem.kt
index 3f581c4d..2909424 100644
--- a/packages/SystemUI/src/com/android/systemui/privacy/PrivacyItem.kt
+++ b/packages/SystemUI/src/com/android/systemui/privacy/PrivacyItem.kt
@@ -24,10 +24,14 @@
typealias Privacy = PrivacyType
-enum class PrivacyType(val nameId: Int, val iconId: Int) {
- TYPE_CAMERA(R.string.privacy_type_camera, R.drawable.stat_sys_camera),
- TYPE_MICROPHONE(R.string.privacy_type_microphone, R.drawable.stat_sys_mic_none),
- TYPE_LOCATION(R.string.privacy_type_location, R.drawable.stat_sys_location);
+enum class PrivacyType(private val nameId: Int, val iconId: Int) {
+ // This is uses the icons used by the corresponding permission groups in the AndroidManifest
+ TYPE_CAMERA(R.string.privacy_type_camera,
+ com.android.internal.R.drawable.perm_group_camera),
+ TYPE_MICROPHONE(R.string.privacy_type_microphone,
+ com.android.internal.R.drawable.perm_group_microphone),
+ TYPE_LOCATION(R.string.privacy_type_location,
+ com.android.internal.R.drawable.perm_group_location);
fun getName(context: Context) = context.resources.getString(nameId)
diff --git a/packages/SystemUI/src/com/android/systemui/qs/PagedTileLayout.java b/packages/SystemUI/src/com/android/systemui/qs/PagedTileLayout.java
index bb159a9..ebc3a6a 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/PagedTileLayout.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/PagedTileLayout.java
@@ -91,6 +91,7 @@
if (mLayoutOrientation != newConfig.orientation) {
mLayoutOrientation = newConfig.orientation;
setCurrentItem(0, false);
+ mPageToRestore = 0;
}
}
@@ -101,6 +102,7 @@
mLayoutDirection = layoutDirection;
setAdapter(mAdapter);
setCurrentItem(0, false);
+ mPageToRestore = 0;
}
}
@@ -112,6 +114,17 @@
super.setCurrentItem(item, smoothScroll);
}
+ /**
+ * Obtains the current page number respecting RTL
+ */
+ private int getCurrentPageNumber() {
+ int page = getCurrentItem();
+ if (mLayoutDirection == LAYOUT_DIRECTION_RTL) {
+ page = mPages.size() - 1 - page;
+ }
+ return page;
+ }
+
@Override
public void setListening(boolean listening) {
if (mListening == listening) return;
@@ -199,7 +212,7 @@
// marquee. This will ensure that accessibility doesn't announce the TYPE_VIEW_SELECTED
// event on any of the children.
setImportantForAccessibility(View.IMPORTANT_FOR_ACCESSIBILITY_NO_HIDE_DESCENDANTS);
- int currentItem = isLayoutRtl() ? mPages.size() - 1 - getCurrentItem() : getCurrentItem();
+ int currentItem = getCurrentPageNumber();
for (int i = 0; i < mPages.size(); i++) {
mPages.get(i).setSelected(i == currentItem ? selected : false);
}
@@ -328,7 +341,7 @@
public int getNumVisibleTiles() {
if (mPages.size() == 0) return 0;
- TilePage currentPage = mPages.get(getCurrentItem());
+ TilePage currentPage = mPages.get(getCurrentPageNumber());
return currentPage.mRecords.size();
}
diff --git a/packages/SystemUI/src/com/android/systemui/qs/QSAnimator.java b/packages/SystemUI/src/com/android/systemui/qs/QSAnimator.java
index 8e77851..ec2feba8 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/QSAnimator.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/QSAnimator.java
@@ -213,7 +213,11 @@
} else { // These tiles disappear when expanding
firstPageBuilder.addFloat(quickTileView, "alpha", 1, 0);
translationYBuilder.addFloat(quickTileView, "translationY", 0, yDiff);
- translationXBuilder.addFloat(quickTileView, "translationX", 0, xDiff + width);
+
+ // xDiff is negative here and this makes it "more" negative
+ final int translationX = mQsPanel.isLayoutRtl() ? xDiff - width : xDiff + width;
+ translationXBuilder.addFloat(quickTileView, "translationX", 0,
+ translationX);
}
mQuickQsViews.add(tileView.getIconWithBackground());
diff --git a/packages/SystemUI/src/com/android/systemui/recents/OverviewProxyService.java b/packages/SystemUI/src/com/android/systemui/recents/OverviewProxyService.java
index 00aef9a..72559f5 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/OverviewProxyService.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/OverviewProxyService.java
@@ -498,7 +498,7 @@
mSysUiStateFlags = 0;
mSysUiStateFlags |= ActivityManagerWrapper.getInstance().isScreenPinningActive()
? SYSUI_STATE_SCREEN_PINNING : 0;
- mSysUiStateFlags |= (navBarFragment == null || !navBarFragment.isNavBarWindowVisible())
+ mSysUiStateFlags |= (navBarFragment != null && !navBarFragment.isNavBarWindowVisible())
? SYSUI_STATE_NAV_BAR_HIDDEN : 0;
mSysUiStateFlags |= panelExpanded
? SYSUI_STATE_NOTIFICATION_PANEL_EXPANDED : 0;
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/NavigationBarController.java b/packages/SystemUI/src/com/android/systemui/statusbar/NavigationBarController.java
index c833ded..907b3ad 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/NavigationBarController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/NavigationBarController.java
@@ -33,6 +33,7 @@
import android.view.WindowManagerGlobal;
import com.android.internal.annotations.VisibleForTesting;
+import com.android.internal.statusbar.RegisterStatusBarResult;
import com.android.systemui.Dependency;
import com.android.systemui.plugins.DarkIconDispatcher;
import com.android.systemui.statusbar.CommandQueue.Callbacks;
@@ -81,7 +82,7 @@
@Override
public void onDisplayReady(int displayId) {
Display display = mDisplayManager.getDisplay(displayId);
- createNavigationBar(display);
+ createNavigationBar(display, null);
}
// TODO(b/117478341): I use {@code includeDefaultDisplay} to make this method compatible to
@@ -91,11 +92,12 @@
*
* @param includeDefaultDisplay {@code true} to create navigation bar on default display.
*/
- public void createNavigationBars(final boolean includeDefaultDisplay) {
+ public void createNavigationBars(final boolean includeDefaultDisplay,
+ RegisterStatusBarResult result) {
Display[] displays = mDisplayManager.getDisplays();
for (Display display : displays) {
if (includeDefaultDisplay || display.getDisplayId() != DEFAULT_DISPLAY) {
- createNavigationBar(display);
+ createNavigationBar(display, result);
}
}
}
@@ -107,7 +109,7 @@
* @param display the display to add navigation bar on.
*/
@VisibleForTesting
- void createNavigationBar(Display display) {
+ void createNavigationBar(Display display, RegisterStatusBarResult result) {
if (display == null) {
return;
}
@@ -151,6 +153,12 @@
navBar.setAutoHideController(autoHideController);
navBar.setSystemUiVisibility(View.SYSTEM_UI_FLAG_VISIBLE);
mNavigationBars.append(displayId, navBar);
+
+ if (result != null) {
+ navBar.setImeWindowStatus(display.getDisplayId(), result.mImeToken,
+ result.mImeWindowVis, result.mImeBackDisposition,
+ result.mShowImeSwitcher);
+ }
});
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/wrapper/NotificationMediaTemplateViewWrapper.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/wrapper/NotificationMediaTemplateViewWrapper.java
index 99f5874..b54de5a 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/wrapper/NotificationMediaTemplateViewWrapper.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/wrapper/NotificationMediaTemplateViewWrapper.java
@@ -90,6 +90,8 @@
@Override
public void onPlaybackStateChanged(PlaybackState state) {
if (state.getState() != PlaybackState.STATE_PLAYING) {
+ // Update the UI once, in case playback info changed while we were paused
+ mUpdatePlaybackUi.run();
clearTimer();
} else if (mSeekBarTimer == null) {
startTimer();
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarFragment.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarFragment.java
index 591b1b4..9eecdb9 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarFragment.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarFragment.java
@@ -316,6 +316,7 @@
if (savedInstanceState != null) {
mNavigationBarView.getLightTransitionsController().restoreState(savedInstanceState);
}
+ mNavigationBarView.setNavigationIconHints(mNavigationIconHints);
prepareNavigationBarView();
checkNavBarModes();
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelView.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelView.java
index 0e9264b..dd957b4 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelView.java
@@ -1709,7 +1709,8 @@
min = Math.max(min, minHeight);
}
int maxHeight;
- if (mQsExpandImmediate || mQsExpanded || mIsExpanding && mQsExpandedWhenExpandingStarted) {
+ if (mQsExpandImmediate || mQsExpanded || mIsExpanding && mQsExpandedWhenExpandingStarted
+ || mPulsing) {
maxHeight = calculatePanelHeightQsExpanded();
} else {
maxHeight = calculatePanelHeightShade();
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java
index aaaf3ed..9fccf91 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java
@@ -660,7 +660,6 @@
mDisplayId = mDisplay.getDisplayId();
updateDisplaySize();
- Resources res = mContext.getResources();
mVibrateOnOpening = mContext.getResources().getBoolean(
R.bool.config_vibrateOnIconAnimation);
mVibratorHelper = Dependency.get(VibratorHelper.class);
@@ -696,7 +695,7 @@
ex.rethrowFromSystemServer();
}
- createAndAddWindows();
+ createAndAddWindows(result);
// Make sure we always have the most current wallpaper info.
IntentFilter wallpaperChangedFilter = new IntentFilter(Intent.ACTION_WALLPAPER_CHANGED);
@@ -778,7 +777,7 @@
// ================================================================================
// Constructing the view
// ================================================================================
- protected void makeStatusBarView() {
+ protected void makeStatusBarView(@Nullable RegisterStatusBarResult result) {
final Context context = mContext;
updateDisplaySize(); // populates mDisplayMetrics
updateResources();
@@ -871,7 +870,7 @@
mNotificationLogger.setHeadsUpManager(mHeadsUpManager);
putComponent(HeadsUpManager.class, mHeadsUpManager);
- createNavigationBar();
+ createNavigationBar(result);
if (ENABLE_LOCKSCREEN_WALLPAPER) {
mLockscreenWallpaper = new LockscreenWallpaper(mContext, this, mHandler);
@@ -1118,8 +1117,8 @@
// TODO(b/117478341): This was left such that CarStatusBar can override this method.
// Try to remove this.
- protected void createNavigationBar() {
- mNavigationBarController.createNavigationBars(true /* includeDefaultDisplay */);
+ protected void createNavigationBar(@Nullable RegisterStatusBarResult result) {
+ mNavigationBarController.createNavigationBars(true /* includeDefaultDisplay */, result);
}
/**
@@ -2401,12 +2400,8 @@
pw.println(BarTransitions.modeToString(transitions.getMode()));
}
- public void createAndAddWindows() {
- addStatusBarWindow();
- }
-
- private void addStatusBarWindow() {
- makeStatusBarView();
+ public void createAndAddWindows(@Nullable RegisterStatusBarResult result) {
+ makeStatusBarView(result);
mStatusBarWindowController = Dependency.get(StatusBarWindowController.class);
mStatusBarWindowController.add(mStatusBarWindow, getStatusBarHeight());
}
diff --git a/packages/SystemUI/src/com/android/systemui/theme/ThemeOverlayManager.java b/packages/SystemUI/src/com/android/systemui/theme/ThemeOverlayManager.java
index 1a9fd53..51ae70b 100644
--- a/packages/SystemUI/src/com/android/systemui/theme/ThemeOverlayManager.java
+++ b/packages/SystemUI/src/com/android/systemui/theme/ThemeOverlayManager.java
@@ -23,9 +23,11 @@
import androidx.annotation.VisibleForTesting;
+import com.google.android.collect.Lists;
import com.google.android.collect.Sets;
import java.util.ArrayList;
+import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
@@ -62,15 +64,18 @@
static final String OVERLAY_CATEGORY_ICON_LAUNCHER =
"android.theme.customization.icon_pack.launcher";
- /* All theme customization categories used by the system. */
- static final Set<String> THEME_CATEGORIES = Sets.newHashSet(
- OVERLAY_CATEGORY_COLOR,
- OVERLAY_CATEGORY_FONT,
+ /*
+ * All theme customization categories used by the system, in order that they should be applied,
+ * starts with launcher and grouped by target package.
+ */
+ static final List<String> THEME_CATEGORIES = Lists.newArrayList(
+ OVERLAY_CATEGORY_ICON_LAUNCHER,
OVERLAY_CATEGORY_SHAPE,
+ OVERLAY_CATEGORY_FONT,
+ OVERLAY_CATEGORY_COLOR,
OVERLAY_CATEGORY_ICON_ANDROID,
OVERLAY_CATEGORY_ICON_SYSUI,
- OVERLAY_CATEGORY_ICON_SETTINGS,
- OVERLAY_CATEGORY_ICON_LAUNCHER);
+ OVERLAY_CATEGORY_ICON_SETTINGS);
/* Categories that need to applied to the current user as well as the system user. */
@VisibleForTesting
@@ -115,29 +120,30 @@
*/
void applyCurrentUserOverlays(
Map<String, String> categoryToPackage, Set<UserHandle> userHandles) {
- final Map<Boolean, List<String>> categorySplit = THEME_CATEGORIES.stream().collect(
- Collectors.partitioningBy((category) -> categoryToPackage.containsKey(category)));
- final List<String> overlayCategoriesToEnable = categorySplit.get(true);
- final List<String> overlayCategoriesToDisable = categorySplit.get(false);
-
// Disable all overlays that have not been specified in the user setting.
- final List<OverlayInfo> overlays = new ArrayList<>();
- overlayCategoriesToDisable.stream()
+ final Set<String> overlayCategoriesToDisable = new HashSet<>(THEME_CATEGORIES);
+ overlayCategoriesToDisable.removeAll(categoryToPackage.keySet());
+ final Set<String> targetPackagesToQuery = overlayCategoriesToDisable.stream()
.map(category -> mCategoryToTargetPackage.get(category))
- .collect(Collectors.toSet())
- .forEach(targetPackage -> overlays.addAll(mOverlayManager
- .getOverlayInfosForTarget(targetPackage, UserHandle.SYSTEM)));
- overlays.stream()
+ .collect(Collectors.toSet());
+ final List<OverlayInfo> overlays = new ArrayList<>();
+ targetPackagesToQuery.forEach(targetPackage -> overlays.addAll(mOverlayManager
+ .getOverlayInfosForTarget(targetPackage, UserHandle.SYSTEM)));
+ final Map<String, String> overlaysToDisable = overlays.stream()
.filter(o ->
mTargetPackageToCategories.get(o.targetPackageName).contains(o.category))
.filter(o -> overlayCategoriesToDisable.contains(o.category))
.filter(o -> o.isEnabled())
- .forEach(o -> setEnabled(o.packageName, o.category, userHandles, false));
+ .collect(Collectors.toMap((o) -> o.category, (o) -> o.packageName));
-
- // Enable all overlays specified in the user setting.
- overlayCategoriesToEnable.forEach((category) ->
- setEnabled(categoryToPackage.get(category), category, userHandles, true));
+ // Toggle overlays in the order of THEME_CATEGORIES.
+ for (String category : THEME_CATEGORIES) {
+ if (categoryToPackage.containsKey(category)) {
+ setEnabled(categoryToPackage.get(category), category, userHandles, true);
+ } else if (overlaysToDisable.containsKey(category)) {
+ setEnabled(overlaysToDisable.get(category), category, userHandles, false);
+ }
+ }
}
private void setEnabled(
diff --git a/packages/SystemUI/tests/src/com/android/keyguard/KeyguardUpdateMonitorTest.java b/packages/SystemUI/tests/src/com/android/keyguard/KeyguardUpdateMonitorTest.java
index ffe3ece..6bed43e 100644
--- a/packages/SystemUI/tests/src/com/android/keyguard/KeyguardUpdateMonitorTest.java
+++ b/packages/SystemUI/tests/src/com/android/keyguard/KeyguardUpdateMonitorTest.java
@@ -288,7 +288,7 @@
mKeyguardUpdateMonitor.sendKeyguardBouncerChanged(true);
mTestableLooper.processAllMessages();
- verify(mFaceManager).authenticate(any(), any(), anyInt(), any(), any());
+ verify(mFaceManager).authenticate(any(), any(), anyInt(), any(), any(), anyInt());
verify(mFaceManager).isHardwareDetected();
verify(mFaceManager).hasEnrolledTemplates(anyInt());
}
@@ -298,7 +298,7 @@
mKeyguardUpdateMonitor.dispatchStartedWakingUp();
mTestableLooper.processAllMessages();
mKeyguardUpdateMonitor.onKeyguardVisibilityChanged(true);
- verify(mFaceManager).authenticate(any(), any(), anyInt(), any(), any());
+ verify(mFaceManager).authenticate(any(), any(), anyInt(), any(), any(), anyInt());
}
@Test
@@ -317,7 +317,7 @@
mKeyguardUpdateMonitor.setKeyguardOccluded(true);
mKeyguardUpdateMonitor.setAssistantVisible(true);
- verify(mFaceManager).authenticate(any(), any(), anyInt(), any(), any());
+ verify(mFaceManager).authenticate(any(), any(), anyInt(), any(), any(), anyInt());
}
@Test
diff --git a/packages/SystemUI/tests/src/com/android/systemui/DumpControllerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/DumpControllerTest.kt
new file mode 100644
index 0000000..cca35ca
--- /dev/null
+++ b/packages/SystemUI/tests/src/com/android/systemui/DumpControllerTest.kt
@@ -0,0 +1,90 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License
+ */
+
+package com.android.systemui
+
+import android.testing.AndroidTestingRunner
+import androidx.test.filters.SmallTest
+import org.junit.Assert.assertEquals
+import org.junit.Before
+import org.junit.Test
+import org.junit.runner.RunWith
+import org.mockito.ArgumentMatchers.any
+import org.mockito.Mock
+import org.mockito.Mockito.never
+import org.mockito.Mockito.verify
+import org.mockito.MockitoAnnotations
+import java.io.FileDescriptor
+import java.io.PrintWriter
+
+@RunWith(AndroidTestingRunner::class)
+@SmallTest
+class DumpControllerTest : SysuiTestCase() {
+
+ private lateinit var controller: DumpController
+ @Mock private lateinit var callback1: Dumpable
+ @Mock private lateinit var callback2: Dumpable
+ @Mock private lateinit var fd: FileDescriptor
+ @Mock private lateinit var pw: PrintWriter
+ private val args = emptyArray<String>()
+
+ @Before
+ fun setUp() {
+ MockitoAnnotations.initMocks(this)
+
+ controller = DumpController()
+// Debug.waitForDebugger()
+ }
+
+ @Test
+ fun testListenerOnlyAddedOnce() {
+ controller.apply {
+ addListener(callback1)
+ addListener(callback1)
+ }
+ assertEquals(1, controller.numListeners)
+
+ controller.dump(fd, pw, args)
+ verify(callback1 /* only once */).dump(fd, pw, args)
+ }
+
+ @Test
+ fun testListenersCalledOnDump() {
+ controller.apply {
+ addListener(callback1)
+ addListener(callback2)
+ }
+
+ controller.dump(fd, pw, args)
+
+ verify(callback1 /* only once */).dump(fd, pw, args)
+ verify(callback2 /* only once */).dump(fd, pw, args)
+ }
+
+ @Test
+ fun testRemoveListener() {
+ controller.apply {
+ addListener(callback1)
+ addListener(callback2)
+ removeListener(callback1)
+ }
+
+ controller.dump(fd, pw, args)
+
+ verify(callback1, never()).dump(any(), any(), any())
+ verify(callback2 /* only once */).dump(fd, pw, args)
+ }
+}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/NavigationBarControllerTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/NavigationBarControllerTest.java
index 34a726d..7d2ccdc 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/NavigationBarControllerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/NavigationBarControllerTest.java
@@ -96,21 +96,21 @@
@Test
public void testCreateNavigationBarsIncludeDefaultTrue() {
initializeDisplayManager();
- doNothing().when(mNavigationBarController).createNavigationBar(any());
+ doNothing().when(mNavigationBarController).createNavigationBar(any(), any());
- mNavigationBarController.createNavigationBars(true);
+ mNavigationBarController.createNavigationBars(true, null);
- verify(mNavigationBarController).createNavigationBar(any(Display.class));
+ verify(mNavigationBarController).createNavigationBar(any(Display.class), any());
}
@Test
public void testCreateNavigationBarsIncludeDefaultFalse() {
initializeDisplayManager();
- doNothing().when(mNavigationBarController).createNavigationBar(any());
+ doNothing().when(mNavigationBarController).createNavigationBar(any(), any());
- mNavigationBarController.createNavigationBars(false);
+ mNavigationBarController.createNavigationBars(false, null);
- verify(mNavigationBarController, never()).createNavigationBar(any());
+ verify(mNavigationBarController, never()).createNavigationBar(any(), any());
}
private void initializeDisplayManager() {
diff --git a/packages/SystemUI/tests/src/com/android/systemui/theme/ThemeOverlayManagerTest.java b/packages/SystemUI/tests/src/com/android/systemui/theme/ThemeOverlayManagerTest.java
index da039a4..a904704 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/theme/ThemeOverlayManagerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/theme/ThemeOverlayManagerTest.java
@@ -51,7 +51,9 @@
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
+import org.mockito.InOrder;
import org.mockito.Mock;
+import org.mockito.Mockito;
import org.mockito.MockitoAnnotations;
import java.util.HashMap;
@@ -134,6 +136,17 @@
}
@Test
+ public void allCategoriesSpecified_enabledInOrder() {
+ mManager.applyCurrentUserOverlays(ALL_CATEGORIES_MAP, TEST_USER_HANDLES);
+
+ InOrder inOrder = Mockito.inOrder(mOverlayManager);
+ for (String category : THEME_CATEGORIES) {
+ inOrder.verify(mOverlayManager)
+ .setEnabledExclusiveInCategory(ALL_CATEGORIES_MAP.get(category), TEST_USER);
+ }
+ }
+
+ @Test
public void allCategoriesSpecified_sysuiCategoriesAlsoAppliedToSysuiUser() {
mManager.applyCurrentUserOverlays(ALL_CATEGORIES_MAP, TEST_USER_HANDLES);
diff --git a/packages/overlays/IconPackCircularLauncherOverlay/res/drawable/ic_clear.xml b/packages/overlays/IconPackCircularLauncherOverlay/res/drawable/ic_clear.xml
deleted file mode 100644
index 59af013..0000000
--- a/packages/overlays/IconPackCircularLauncherOverlay/res/drawable/ic_clear.xml
+++ /dev/null
@@ -1,31 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
- Copyright (C) 2019 The Android Open Source Project
-
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
--->
-<vector xmlns:android="http://schemas.android.com/apk/res/android"
- android:height="24dp"
- android:viewportHeight="24"
- android:viewportWidth="24"
- android:width="24dp" >
- <path
- android:fillColor="#000000"
- android:pathData="M9,20h6c1.66,0,3-1.34,3-3V6h0.5c0.41,0,0.75-0.34,0.75-0.75S18.91,4.5,18.5,4.5H18h-3l-1-1h-4l-1,1H6H5.5 c-0.41,0-0.75,0.34-0.75,0.75S5.09,6,5.5,6H6v11C6,18.66,7.34,20,9,20z M16.5,6v11c0,0.83-0.67,1.5-1.5,1.5H9 c-0.83,0-1.5-0.67-1.5-1.5V6H16.5z" />
- <path
- android:fillColor="#000000"
- android:pathData="M13.97,16c0.41,0,0.75-0.34,0.75-0.75v-6.5c0-0.41-0.34-0.75-0.75-0.75s-0.75,0.34-0.75,0.75v6.5 C13.22,15.66,13.55,16,13.97,16z" />
- <path
- android:fillColor="#000000"
- android:pathData="M10,16c0.41,0,0.75-0.34,0.75-0.75v-6.5C10.75,8.34,10.41,8,10,8S9.25,8.34,9.25,8.75v6.5C9.25,15.66,9.59,16,10,16z" />
-</vector>
\ No newline at end of file
diff --git a/packages/overlays/IconPackCircularLauncherOverlay/res/drawable/ic_corp.xml b/packages/overlays/IconPackCircularLauncherOverlay/res/drawable/ic_corp.xml
index b6f7777..798907c 100644
--- a/packages/overlays/IconPackCircularLauncherOverlay/res/drawable/ic_corp.xml
+++ b/packages/overlays/IconPackCircularLauncherOverlay/res/drawable/ic_corp.xml
@@ -16,10 +16,10 @@
-->
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:height="24dp"
- android:viewportHeight="24"
+ android:viewportHeight="24" android:tint="?android:attr/textColorHint"
android:viewportWidth="24"
android:width="24dp" >
<path
- android:fillColor="#000000"
+ android:fillColor="@android:color/white"
android:pathData="M16,4c0-1.1-0.9-2-2-2h-4C8.9,2,8,2.9,8,4v2H2v12c0,1.66,1.34,3,3,3h14c1.66,0,3-1.34,3-3V6h-6V4z M9.5,4 c0-0.28,0.22-0.5,0.5-0.5h4c0.28,0,0.5,0.22,0.5,0.5v2h-5V4z M20.5,7.5V18c0,0.83-0.67,1.5-1.5,1.5H5c-0.83,0-1.5-0.67-1.5-1.5V7.5 H20.5z" />
</vector>
\ No newline at end of file
diff --git a/packages/overlays/IconPackCircularLauncherOverlay/res/drawable/ic_drag_handle.xml b/packages/overlays/IconPackCircularLauncherOverlay/res/drawable/ic_drag_handle.xml
new file mode 100644
index 0000000..a7ab99e
--- /dev/null
+++ b/packages/overlays/IconPackCircularLauncherOverlay/res/drawable/ic_drag_handle.xml
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2019 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+ android:width="24dp"
+ android:height="24dp"
+ android:viewportWidth="24"
+ android:viewportHeight="24" android:tint="?android:attr/textColorHint">
+
+ <path
+ android:fillColor="@android:color/white"
+ android:pathData="M4.75,10.5h14.5c0.41,0,0.75-0.34,0.75-0.75S19.66,9,19.25,9H4.75C4.34,9,4,9.34,4,9.75S4.34,10.5,4.75,10.5z" />
+ <path
+ android:fillColor="@android:color/white"
+ android:pathData="M4.75,15h14.5c0.41,0,0.75-0.34,0.75-0.75s-0.34-0.75-0.75-0.75H4.75C4.34,13.5,4,13.84,4,14.25S4.34,15,4.75,15z" />
+</vector>
\ No newline at end of file
diff --git a/packages/overlays/IconPackCircularLauncherOverlay/res/drawable/ic_hourglass_top.xml b/packages/overlays/IconPackCircularLauncherOverlay/res/drawable/ic_hourglass_top.xml
new file mode 100644
index 0000000..8160e68
--- /dev/null
+++ b/packages/overlays/IconPackCircularLauncherOverlay/res/drawable/ic_hourglass_top.xml
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2019 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+ android:width="24dp"
+ android:height="24dp"
+ android:viewportWidth="24"
+ android:viewportHeight="24" android:tint="?android:attr/textColorPrimary">
+
+ <path
+ android:fillColor="@android:color/white"
+ android:pathData="M7,6.8c0,2.23,1.22,4.16,3.02,5.2C8.22,13.04,7,14.97,7,17.2V22h10v-4.8c0-2.23-1.22-4.16-3.02-5.2
+C15.78,10.96,17,9.03,17,6.8V2H7V6.8z
+M15.5,17.2v3.3h-7v-3.3c0-1.6,0.87-3.1,2.26-3.9L12,12.59l1.24,0.71
+C14.63,14.1,15.5,15.6,15.5,17.2z" />
+</vector>
\ No newline at end of file
diff --git a/packages/overlays/IconPackCircularLauncherOverlay/res/drawable/ic_info_no_shadow.xml b/packages/overlays/IconPackCircularLauncherOverlay/res/drawable/ic_info_no_shadow.xml
index 7bd6028..82924bb 100644
--- a/packages/overlays/IconPackCircularLauncherOverlay/res/drawable/ic_info_no_shadow.xml
+++ b/packages/overlays/IconPackCircularLauncherOverlay/res/drawable/ic_info_no_shadow.xml
@@ -16,16 +16,16 @@
-->
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:height="24dp"
- android:viewportHeight="24"
+ android:viewportHeight="24" android:tint="?android:attr/textColorPrimary"
android:viewportWidth="24"
android:width="24dp" >
<path
- android:fillColor="#000000"
+ android:fillColor="@android:color/white"
android:pathData="M11.99,2C6.47,2,2,6.48,2,12c0,5.52,4.47,10,9.99,10C17.52,22,22,17.52,22,12C22,6.48,17.52,2,11.99,2z M11.99,20.5 c-4.68,0-8.49-3.81-8.49-8.5c0-4.69,3.81-8.5,8.49-8.5c4.69,0,8.51,3.81,8.51,8.5C20.5,16.69,16.68,20.5,11.99,20.5z" />
<path
- android:fillColor="#000000"
+ android:fillColor="@android:color/white"
android:pathData="M12,10.5c-0.41,0-0.75,0.34-0.75,0.75v5c0,0.41,0.34,0.75,0.75,0.75s0.75-0.34,0.75-0.75v-5 C12.75,10.84,12.41,10.5,12,10.5z" />
<path
- android:fillColor="#000000"
+ android:fillColor="@android:color/white"
android:pathData="M 12 7 C 12.5522847498 7 13 7.44771525017 13 8 C 13 8.55228474983 12.5522847498 9 12 9 C 11.4477152502 9 11 8.55228474983 11 8 C 11 7.44771525017 11.4477152502 7 12 7 Z" />
</vector>
\ No newline at end of file
diff --git a/packages/overlays/IconPackCircularLauncherOverlay/res/drawable/ic_wallpaper.xml b/packages/overlays/IconPackCircularLauncherOverlay/res/drawable/ic_palette.xml
similarity index 87%
rename from packages/overlays/IconPackCircularLauncherOverlay/res/drawable/ic_wallpaper.xml
rename to packages/overlays/IconPackCircularLauncherOverlay/res/drawable/ic_palette.xml
index e58c7b8..964955b 100644
--- a/packages/overlays/IconPackCircularLauncherOverlay/res/drawable/ic_wallpaper.xml
+++ b/packages/overlays/IconPackCircularLauncherOverlay/res/drawable/ic_palette.xml
@@ -16,7 +16,7 @@
-->
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:height="24dp"
- android:viewportHeight="24"
+ android:viewportHeight="24" android:tint="?android:attr/textColorPrimary"
android:viewportWidth="24"
android:width="24dp" >
<group
@@ -26,20 +26,20 @@
android:translateX="2.000000"
android:translateY="2.000000" >
<path
- android:fillColor="#000000"
+ android:fillColor="@android:color/white"
android:pathData="M-109-356.5c4.69,0,8.5,3.36,8.5,7.5c0,2.48-2.02,4.5-4.5,4.5h-1.77c-1.1,0-2,0.9-2,2 c0,0.45,0.16,0.89,0.46,1.27l0.02,0.02l0.02,0.02c0.17,0.2,0.27,0.44,0.27,0.68c0,0.55-0.45,1-1,1c-4.69,0-8.5-3.81-8.5-8.5 S-113.69-356.5-109-356.5 M-109-358c-5.51,0-10,4.49-10,10s4.49,10,10,10c1.38,0,2.5-1.12,2.5-2.5c0-0.61-0.23-1.2-0.64-1.67 c-0.08-0.1-0.13-0.21-0.13-0.33c0-0.28,0.22-0.5,0.5-0.5h1.77c3.31,0,6-2.69,6-6C-99-353.96-103.49-358-109-358L-109-358z" />
</group>
</group>
<path
- android:fillColor="#000000"
+ android:fillColor="@android:color/white"
android:pathData="M 6.5 10 C 7.32842712475 10 8 10.6715728753 8 11.5 C 8 12.3284271247 7.32842712475 13 6.5 13 C 5.67157287525 13 5 12.3284271247 5 11.5 C 5 10.6715728753 5.67157287525 10 6.5 10 Z" />
<path
- android:fillColor="#000000"
+ android:fillColor="@android:color/white"
android:pathData="M 9.5 6 C 10.3284271247 6 11 6.67157287525 11 7.5 C 11 8.32842712475 10.3284271247 9 9.5 9 C 8.67157287525 9 8 8.32842712475 8 7.5 C 8 6.67157287525 8.67157287525 6 9.5 6 Z" />
<path
- android:fillColor="#000000"
+ android:fillColor="@android:color/white"
android:pathData="M 14.5 6 C 15.3284271247 6 16 6.67157287525 16 7.5 C 16 8.32842712475 15.3284271247 9 14.5 9 C 13.6715728753 9 13 8.32842712475 13 7.5 C 13 6.67157287525 13.6715728753 6 14.5 6 Z" />
<path
- android:fillColor="#000000"
+ android:fillColor="@android:color/white"
android:pathData="M 17.5 10 C 18.3284271247 10 19 10.6715728753 19 11.5 C 19 12.3284271247 18.3284271247 13 17.5 13 C 16.6715728753 13 16 12.3284271247 16 11.5 C 16 10.6715728753 16.6715728753 10 17.5 10 Z" />
</vector>
\ No newline at end of file
diff --git a/packages/overlays/IconPackCircularLauncherOverlay/res/drawable/ic_pin.xml b/packages/overlays/IconPackCircularLauncherOverlay/res/drawable/ic_pin.xml
new file mode 100644
index 0000000..35c0b81
--- /dev/null
+++ b/packages/overlays/IconPackCircularLauncherOverlay/res/drawable/ic_pin.xml
@@ -0,0 +1,29 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2019 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+ android:width="24dp"
+ android:height="24dp"
+ android:viewportWidth="24"
+ android:viewportHeight="24" android:tint="?android:attr/textColorPrimary">
+
+ <path
+ android:fillColor="@android:color/white"
+ android:pathData="M4.63,14.62C4.24,15.21,4.66,16,5.37,16h5.88c0,0,0,0,0,0v6.25c0,0.41,0.34,0.75,0.75,0.75s0.75-0.34,0.75-0.75V16
+c0,0,0,0,0,0h5.84c0.71,0,1.13-0.79,0.74-1.38c-0.84-1.25-1.99-2.26-3.33-2.95V4.5h1.23c0.41,0,0.75-0.34,0.75-0.75
+S17.65,3,17.23,3H6.73C6.32,3,5.98,3.34,5.98,3.75S6.32,4.5,6.73,4.5H8v7.15C6.64,12.34,5.48,13.36,4.63,14.62z
+M14.5,4.5v8.08
+L15.32,13c0.75,0.39,1.43,0.89,2,1.5H6.64c0.58-0.61,1.27-1.12,2.03-1.51l0.82-0.42V4.5H14.5z" />
+</vector>
\ No newline at end of file
diff --git a/packages/overlays/IconPackCircularLauncherOverlay/res/drawable/ic_remove_no_shadow.xml b/packages/overlays/IconPackCircularLauncherOverlay/res/drawable/ic_remove_no_shadow.xml
index 458223d..5fa740d 100644
--- a/packages/overlays/IconPackCircularLauncherOverlay/res/drawable/ic_remove_no_shadow.xml
+++ b/packages/overlays/IconPackCircularLauncherOverlay/res/drawable/ic_remove_no_shadow.xml
@@ -16,10 +16,10 @@
-->
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:height="24dp"
- android:viewportHeight="24"
+ android:viewportHeight="24" android:tint="?android:attr/textColorPrimary"
android:viewportWidth="24"
android:width="24dp" >
<path
- android:fillColor="#000000"
+ android:fillColor="@android:color/white"
android:pathData="M3.97,20.03c0.15,0.15,0.34,0.22,0.53,0.22s0.38-0.07,0.53-0.22L12,13.06l6.97,6.97c0.15,0.15,0.34,0.22,0.53,0.22 s0.38-0.07,0.53-0.22c0.29-0.29,0.29-0.77,0-1.06L13.06,12l6.97-6.97c0.29-0.29,0.29-0.77,0-1.06s-0.77-0.29-1.06,0L12,10.94 L5.03,3.97c-0.29-0.29-0.77-0.29-1.06,0s-0.29,0.77,0,1.06L10.94,12l-6.97,6.97C3.68,19.26,3.68,19.74,3.97,20.03z" />
</vector>
\ No newline at end of file
diff --git a/packages/overlays/IconPackCircularLauncherOverlay/res/drawable/ic_setting.xml b/packages/overlays/IconPackCircularLauncherOverlay/res/drawable/ic_setting.xml
index abb1b54..afa0a15 100644
--- a/packages/overlays/IconPackCircularLauncherOverlay/res/drawable/ic_setting.xml
+++ b/packages/overlays/IconPackCircularLauncherOverlay/res/drawable/ic_setting.xml
@@ -16,10 +16,10 @@
-->
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:height="24dp"
- android:viewportHeight="24"
+ android:viewportHeight="24" android:tint="?android:attr/textColorPrimary"
android:viewportWidth="24"
android:width="24dp" >
<path
- android:fillColor="#000000"
+ android:fillColor="@android:color/white"
android:pathData="M12,8.5c-1.93,0-3.5,1.57-3.5,3.5s1.57,3.5,3.5,3.5c1.93,0,3.5-1.57,3.5-3.5S13.93,8.5,12,8.5z M12,14c-1.1,0-2-0.9-2-2 s0.9-2,2-2c1.1,0,2,0.9,2,2S13.1,14,12,14z M21.29,13.9l-1.83-1.05c-0.3-0.17-0.49-0.49-0.48-0.84v-0.01 c0-0.35,0.18-0.67,0.48-0.84l1.83-1.05c0.48-0.28,0.64-0.89,0.37-1.37l-2-3.46c-0.19-0.32-0.52-0.5-0.87-0.5 c-0.17,0-0.34,0.04-0.5,0.13l-1.84,1.06c-0.14,0.08-0.29,0.12-0.45,0.12c-0.17,0-0.35-0.05-0.5-0.14c0,0-0.01,0-0.01-0.01 C15.2,5.77,15,5.47,15,5.12V3c0-0.55-0.45-1-1-1h-4C9.45,2,9,2.45,9,3v2.12c0,0.34-0.2,0.65-0.5,0.82c0,0-0.01,0-0.01,0.01 c-0.16,0.09-0.33,0.14-0.5,0.14c-0.15,0-0.31-0.04-0.45-0.12L5.71,4.9c-0.16-0.09-0.33-0.13-0.5-0.13c-0.35,0-0.68,0.18-0.87,0.5 l-2,3.46C2.06,9.21,2.23,9.82,2.71,10.1l1.83,1.05c0.3,0.17,0.49,0.49,0.48,0.84v0.01c0,0.35-0.18,0.67-0.48,0.84L2.71,13.9 c-0.48,0.28-0.64,0.89-0.37,1.37l2,3.46c0.19,0.32,0.52,0.5,0.87,0.5c0.17,0,0.34-0.04,0.5-0.13l1.84-1.06 c0.14-0.08,0.29-0.12,0.45-0.12c0.17,0,0.35,0.05,0.5,0.14c0,0,0.01,0,0.01,0.01C8.8,18.23,9,18.53,9,18.88V21c0,0.55,0.45,1,1,1h4 c0.55,0,1-0.45,1-1v-2.12c0-0.34,0.2-0.65,0.5-0.82c0,0,0.01,0,0.01-0.01c0.16-0.09,0.33-0.14,0.5-0.14c0.15,0,0.31,0.04,0.45,0.12 l1.84,1.06c0.16,0.09,0.33,0.13,0.5,0.13c0.35,0,0.68-0.18,0.87-0.5l2-3.46C21.94,14.79,21.77,14.18,21.29,13.9z M18.61,17.55 l-1.41-0.81c-0.36-0.21-0.78-0.32-1.2-0.32c-0.43,0-0.86,0.12-1.25,0.34c-0.77,0.44-1.25,1.25-1.25,2.12v1.62h-3v-1.62 c0-0.87-0.48-1.68-1.26-2.12c-0.38-0.22-0.81-0.33-1.25-0.33c-0.42,0-0.84,0.11-1.2,0.32l-1.41,0.81l-1.5-2.6l1.39-0.8 c0.76-0.44,1.24-1.26,1.23-2.15c0-0.88-0.47-1.7-1.23-2.14l-1.39-0.8l1.5-2.6L6.8,7.26c0.36,0.21,0.78,0.32,1.2,0.32 c0.43,0,0.86-0.12,1.25-0.34c0.77-0.44,1.25-1.25,1.25-2.12V3.5h3v1.62c0,0.87,0.48,1.68,1.26,2.12c0.38,0.22,0.81,0.33,1.25,0.33 c0.42,0,0.84-0.11,1.2-0.32l1.41-0.81l1.5,2.6l-1.39,0.8c-0.76,0.44-1.24,1.26-1.23,2.15c0,0.88,0.47,1.7,1.23,2.14l1.39,0.8 L18.61,17.55z" />
</vector>
\ No newline at end of file
diff --git a/packages/overlays/IconPackCircularLauncherOverlay/res/drawable/ic_smartspace_preferences.xml b/packages/overlays/IconPackCircularLauncherOverlay/res/drawable/ic_smartspace_preferences.xml
index f588c16..b7d31a2 100644
--- a/packages/overlays/IconPackCircularLauncherOverlay/res/drawable/ic_smartspace_preferences.xml
+++ b/packages/overlays/IconPackCircularLauncherOverlay/res/drawable/ic_smartspace_preferences.xml
@@ -16,10 +16,10 @@
-->
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:height="24dp"
- android:viewportHeight="24"
+ android:viewportHeight="24" android:tint="?android:attr/textColorPrimary"
android:viewportWidth="24"
android:width="24dp" >
<path
- android:fillColor="#000000"
+ android:fillColor="@android:color/white"
android:pathData="M15.08,8.01c-0.39-0.39-0.91-0.59-1.42-0.59c-0.51,0-1.02,0.2-1.41,0.59L0.59,19.67l3.75,3.75l11.66-11.66 c0.78-0.78,0.78-2.04,0.01-2.82L15.08,8.01z M4.34,21.29l-1.63-1.63l7.45-7.45l1.63,1.63L4.34,21.29z M14.93,10.7l-2.09,2.09 l-1.63-1.63l2.09-2.09c0.13-0.13,0.28-0.15,0.35-0.15c0.08,0,0.23,0.02,0.36,0.15l0.92,0.93C15.13,10.18,15.13,10.5,14.93,10.7z M17.67,5.25h1.08v1.08c0,0.41,0.34,0.75,0.75,0.75s0.75-0.34,0.75-0.75V5.25h1.08c0.41,0,0.75-0.34,0.75-0.75 s-0.34-0.75-0.75-0.75h-1.08V2.67c0-0.41-0.34-0.75-0.75-0.75s-0.75,0.34-0.75,0.75v1.08h-1.08c-0.41,0-0.75,0.34-0.75,0.75 S17.26,5.25,17.67,5.25z M5.67,5.25h1.08v1.08c0,0.41,0.34,0.75,0.75,0.75s0.75-0.34,0.75-0.75V5.25h1.08 c0.41,0,0.75-0.34,0.75-0.75S9.74,3.75,9.33,3.75H8.25V2.67c0-0.41-0.34-0.75-0.75-0.75S6.75,2.26,6.75,2.67v1.08H5.67 c-0.41,0-0.75,0.34-0.75,0.75S5.26,5.25,5.67,5.25z M21.33,15.75h-1.08v-1.08c0-0.41-0.34-0.75-0.75-0.75s-0.75,0.34-0.75,0.75 v1.08h-1.08c-0.41,0-0.75,0.34-0.75,0.75s0.34,0.75,0.75,0.75h1.08v1.08c0,0.41,0.34,0.75,0.75,0.75s0.75-0.34,0.75-0.75v-1.08 h1.08c0.41,0,0.75-0.34,0.75-0.75S21.74,15.75,21.33,15.75z" />
</vector>
\ No newline at end of file
diff --git a/packages/overlays/IconPackCircularLauncherOverlay/res/drawable/ic_split_screen.xml b/packages/overlays/IconPackCircularLauncherOverlay/res/drawable/ic_split_screen.xml
index 081f2d8..649e555 100644
--- a/packages/overlays/IconPackCircularLauncherOverlay/res/drawable/ic_split_screen.xml
+++ b/packages/overlays/IconPackCircularLauncherOverlay/res/drawable/ic_split_screen.xml
@@ -16,13 +16,13 @@
-->
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:height="24dp"
- android:viewportHeight="24"
+ android:viewportHeight="24" android:tint="?android:attr/textColorPrimary"
android:viewportWidth="24"
android:width="24dp" >
<path
- android:fillColor="#000000"
+ android:fillColor="@android:color/white"
android:pathData="M4,6v3c0,1.1,0.9,2,2,2h12c1.1,0,2-0.9,2-2V6c0-1.1-0.9-2-2-2H6C4.9,4,4,4.9,4,6z M18.5,6v3c0,0.28-0.22,0.5-0.5,0.5H6 C5.72,9.5,5.5,9.28,5.5,9V6c0-0.28,0.22-0.5,0.5-0.5h12C18.28,5.5,18.5,5.72,18.5,6z" />
<path
- android:fillColor="#000000"
+ android:fillColor="@android:color/white"
android:pathData="M4,18c0,1.1,0.9,2,2,2h12c1.1,0,2-0.9,2-2v-3c0-1.1-0.9-2-2-2H6c-1.1,0-2,0.9-2,2V18z M5.5,15c0-0.28,0.22-0.5,0.5-0.5h12 c0.28,0,0.5,0.22,0.5,0.5v3c0,0.28-0.22,0.5-0.5,0.5H6c-0.28,0-0.5-0.22-0.5-0.5V15z" />
</vector>
\ No newline at end of file
diff --git a/packages/overlays/IconPackCircularLauncherOverlay/res/drawable/ic_warning.xml b/packages/overlays/IconPackCircularLauncherOverlay/res/drawable/ic_warning.xml
index f9e7423..e78ae9a 100644
--- a/packages/overlays/IconPackCircularLauncherOverlay/res/drawable/ic_warning.xml
+++ b/packages/overlays/IconPackCircularLauncherOverlay/res/drawable/ic_warning.xml
@@ -16,16 +16,16 @@
-->
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:height="24dp"
- android:viewportHeight="24"
+ android:viewportHeight="24" android:tint="?android:attr/textColorPrimary"
android:viewportWidth="24"
android:width="24dp" >
<path
- android:fillColor="#000000"
+ android:fillColor="@android:color/white"
android:pathData="M4.47,21h15.06c1.54,0,2.5-1.67,1.73-3L13.73,4.99c-0.39-0.67-1.06-1-1.73-1s-1.35,0.33-1.73,1L2.74,18 C1.97,19.33,2.93,21,4.47,21z M4.04,18.75l7.53-13.01c0.13-0.22,0.33-0.25,0.43-0.25s0.31,0.03,0.43,0.25l7.53,13.01 c0.13,0.22,0.05,0.41,0,0.5c-0.05,0.09-0.18,0.25-0.43,0.25H4.47c-0.25,0-0.38-0.16-0.43-0.25C3.98,19.16,3.91,18.97,4.04,18.75z" />
<path
- android:fillColor="#000000"
+ android:fillColor="@android:color/white"
android:pathData="M12,14.75c0.41,0,0.75-0.34,0.75-0.75V9.75C12.75,9.33,12.41,9,12,9s-0.75,0.34-0.75,0.75V14 C11.25,14.41,11.59,14.75,12,14.75z" />
<path
- android:fillColor="#000000"
+ android:fillColor="@android:color/white"
android:pathData="M 12 16 C 12.5522847498 16 13 16.4477152502 13 17 C 13 17.5522847498 12.5522847498 18 12 18 C 11.4477152502 18 11 17.5522847498 11 17 C 11 16.4477152502 11.4477152502 16 12 16 Z" />
</vector>
\ No newline at end of file
diff --git a/packages/overlays/IconPackCircularLauncherOverlay/res/drawable/ic_widget.xml b/packages/overlays/IconPackCircularLauncherOverlay/res/drawable/ic_widget.xml
index 6069818..c3bc349 100644
--- a/packages/overlays/IconPackCircularLauncherOverlay/res/drawable/ic_widget.xml
+++ b/packages/overlays/IconPackCircularLauncherOverlay/res/drawable/ic_widget.xml
@@ -16,19 +16,19 @@
-->
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:height="24dp"
- android:viewportHeight="24"
+ android:viewportHeight="24" android:tint="?android:attr/textColorPrimary"
android:viewportWidth="24"
android:width="24dp" >
<path
- android:fillColor="#000000"
+ android:fillColor="@android:color/white"
android:pathData="M11,5c0-1.1-0.9-2-2-2H5C3.9,3,3,3.9,3,5v4c0,1.1,0.9,2,2,2h4c1.1,0,2-0.9,2-2V5z M9.5,9c0,0.28-0.22,0.5-0.5,0.5H5 C4.72,9.5,4.5,9.28,4.5,9V5c0-0.28,0.22-0.5,0.5-0.5h4c0.28,0,0.5,0.22,0.5,0.5V9z" />
<path
- android:fillColor="#000000"
+ android:fillColor="@android:color/white"
android:pathData="M9,13H5c-1.1,0-2,0.9-2,2v4c0,1.1,0.9,2,2,2h4c1.1,0,2-0.9,2-2v-4C11,13.9,10.1,13,9,13z M9.5,19c0,0.28-0.22,0.5-0.5,0.5 H5c-0.28,0-0.5-0.22-0.5-0.5v-4c0-0.28,0.22-0.5,0.5-0.5h4c0.28,0,0.5,0.22,0.5,0.5V19z" />
<path
- android:fillColor="#000000"
+ android:fillColor="@android:color/white"
android:pathData="M19,13h-4c-1.1,0-2,0.9-2,2v4c0,1.1,0.9,2,2,2h4c1.1,0,2-0.9,2-2v-4C21,13.9,20.1,13,19,13z M19.5,19 c0,0.28-0.22,0.5-0.5,0.5h-4c-0.28,0-0.5-0.22-0.5-0.5v-4c0-0.28,0.22-0.5,0.5-0.5h4c0.28,0,0.5,0.22,0.5,0.5V19z" />
<path
- android:fillColor="#000000"
+ android:fillColor="@android:color/white"
android:pathData="M18.41,2.76c-0.39-0.39-0.9-0.59-1.41-0.59s-1.02,0.2-1.41,0.59l-2.83,2.83c-0.78,0.78-0.78,2.05,0,2.83l2.83,2.83 c0.39,0.39,0.9,0.59,1.41,0.59s1.02-0.2,1.41-0.59l2.83-2.83c0.78-0.78,0.78-2.05,0-2.83L18.41,2.76z M20.18,7.35l-2.83,2.83 c-0.13,0.13-0.28,0.15-0.35,0.15s-0.23-0.02-0.35-0.15l-2.83-2.83C13.69,7.23,13.67,7.08,13.67,7s0.02-0.23,0.15-0.35l2.83-2.83 c0.13-0.13,0.28-0.15,0.35-0.15s0.23,0.02,0.35,0.15l2.83,2.83c0.13,0.13,0.15,0.28,0.15,0.35S20.31,7.23,20.18,7.35z" />
</vector>
\ No newline at end of file
diff --git a/packages/overlays/IconPackFilledLauncherOverlay/res/drawable/ic_clear.xml b/packages/overlays/IconPackFilledLauncherOverlay/res/drawable/ic_clear.xml
deleted file mode 100644
index 49e7f1d..0000000
--- a/packages/overlays/IconPackFilledLauncherOverlay/res/drawable/ic_clear.xml
+++ /dev/null
@@ -1,31 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
- Copyright (C) 2019 The Android Open Source Project
-
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
--->
-<vector xmlns:android="http://schemas.android.com/apk/res/android"
- android:height="24dp"
- android:viewportHeight="24"
- android:viewportWidth="24"
- android:width="24dp" >
- <path
- android:fillColor="#000000"
- android:pathData="M20,4h-1h-4c0-0.55-0.45-1-1-1h-4C9.45,3,9,3.45,9,4H5H4C3.59,4,3.25,4.34,3.25,4.75S3.59,5.5,4,5.5h1V18 c0,1.66,1.34,3,3,3h8c1.66,0,3-1.34,3-3V5.5h1c0.41,0,0.75-0.34,0.75-0.75S20.41,4,20,4z M17.5,18c0,0.83-0.67,1.5-1.5,1.5H8 c-0.83,0-1.5-0.67-1.5-1.5V5.5h11V18z" />
- <path
- android:fillColor="#000000"
- android:pathData="M14.25,8c-0.41,0-0.75,0.34-0.75,0.75v7.5c0,0.41,0.34,0.75,0.75,0.75S15,16.66,15,16.25v-7.5C15,8.34,14.66,8,14.25,8z" />
- <path
- android:fillColor="#000000"
- android:pathData="M9.75,8C9.34,8,9,8.34,9,8.75v7.5C9,16.66,9.34,17,9.75,17s0.75-0.34,0.75-0.75v-7.5C10.5,8.34,10.16,8,9.75,8z" />
-</vector>
\ No newline at end of file
diff --git a/packages/overlays/IconPackFilledLauncherOverlay/res/drawable/ic_corp.xml b/packages/overlays/IconPackFilledLauncherOverlay/res/drawable/ic_corp.xml
index f7b7f77..76d8882 100644
--- a/packages/overlays/IconPackFilledLauncherOverlay/res/drawable/ic_corp.xml
+++ b/packages/overlays/IconPackFilledLauncherOverlay/res/drawable/ic_corp.xml
@@ -16,10 +16,10 @@
-->
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:height="24dp"
- android:viewportHeight="24"
+ android:viewportHeight="24" android:tint="?android:attr/textColorHint"
android:viewportWidth="24"
android:width="24dp" >
<path
- android:fillColor="#000000"
- android:pathData="M20,6h-4V4c0-1.1-0.9-2-2-2h-4C8.9,2,8,2.9,8,4v2H4C2.9,6,2,6.9,2,8v11c0,1.1,0.9,2,2,2h16c1.1,0,2-0.9,2-2V8 C22,6.9,21.1,6,20,6z M9.5,4c0-0.28,0.22-0.5,0.5-0.5h4c0.28,0,0.5,0.22,0.5,0.5v2h-5V4z M20.5,19c0,0.28-0.22,0.5-0.5,0.5H4 c-0.28,0-0.5-0.22-0.5-0.5V8c0-0.28,0.22-0.5,0.5-0.5h16c0.28,0,0.5,0.22,0.5,0.5V19z" />
+ android:fillColor="@android:color/white"
+ android:pathData="M20,6h-4V4c0-1.11-0.89-2-2-2h-4C8.89,2,8,2.89,8,4v2H4C2.89,6,2.01,6.89,2.01,8L2,19c0,1.11,0.89,2,2,2h16 c1.11,0,2-0.89,2-2V8C22,6.89,21.11,6,20,6z M14,6h-4V4h4V6z" />
</vector>
\ No newline at end of file
diff --git a/packages/overlays/IconPackFilledLauncherOverlay/res/drawable/ic_drag_handle.xml b/packages/overlays/IconPackFilledLauncherOverlay/res/drawable/ic_drag_handle.xml
new file mode 100644
index 0000000..3117ae1
--- /dev/null
+++ b/packages/overlays/IconPackFilledLauncherOverlay/res/drawable/ic_drag_handle.xml
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2019 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+ android:width="24dp"
+ android:height="24dp"
+ android:viewportWidth="24"
+ android:viewportHeight="24" android:tint="?android:attr/textColorHint">
+
+ <path
+ android:fillColor="@android:color/white"
+ android:pathData="M19,13H5c-0.55,0-1,0.45-1,1s0.45,1,1,1h14c0.55,0,1-0.45,1-1S19.55,13,19,13z" />
+ <path
+ android:fillColor="@android:color/white"
+ android:pathData="M19,9H5c-0.55,0-1,0.45-1,1s0.45,1,1,1h14c0.55,0,1-0.45,1-1S19.55,9,19,9z" />
+</vector>
\ No newline at end of file
diff --git a/packages/overlays/IconPackFilledLauncherOverlay/res/drawable/ic_hourglass_top.xml b/packages/overlays/IconPackFilledLauncherOverlay/res/drawable/ic_hourglass_top.xml
new file mode 100644
index 0000000..b389e4b
--- /dev/null
+++ b/packages/overlays/IconPackFilledLauncherOverlay/res/drawable/ic_hourglass_top.xml
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2019 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+ android:width="24dp"
+ android:height="24dp"
+ android:viewportWidth="24"
+ android:viewportHeight="24" android:tint="?android:attr/textColorPrimary">
+
+ <path
+ android:fillColor="@android:color/white"
+ android:pathData="M17,2H7C6.45,2,6,2.45,6,3l0.01,3.75c0,0.79,0.32,1.55,0.87,2.11L10,12l-3.12,3.12c-0.56,0.56-0.87,1.32-0.88,2.11L6,21
+c0,0.55,0.45,1,1,1h10c0.55,0,1-0.45,1-1v-3.77c0-0.8-0.32-1.56-0.88-2.12L14,12l3.12-3.13C17.68,8.31,18,7.54,18,6.75V3
+C18,2.45,17.55,2,17,2z
+M15.71,16.21c0.19,0.19,0.29,0.44,0.29,0.71V20H8v-3.09c0-0.27,0.11-0.52,0.29-0.71L12,12.5L15.71,16.21z" />
+</vector>
\ No newline at end of file
diff --git a/packages/overlays/IconPackFilledLauncherOverlay/res/drawable/ic_info_no_shadow.xml b/packages/overlays/IconPackFilledLauncherOverlay/res/drawable/ic_info_no_shadow.xml
index 6c9c732..f50fa2b 100644
--- a/packages/overlays/IconPackFilledLauncherOverlay/res/drawable/ic_info_no_shadow.xml
+++ b/packages/overlays/IconPackFilledLauncherOverlay/res/drawable/ic_info_no_shadow.xml
@@ -16,16 +16,10 @@
-->
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:height="24dp"
- android:viewportHeight="24"
+ android:viewportHeight="24" android:tint="?android:attr/textColorPrimary"
android:viewportWidth="24"
android:width="24dp" >
<path
- android:fillColor="#000000"
- android:pathData="M4.92,4.94c-3.9,3.91-3.9,10.24,0.01,14.14s10.24,3.9,14.14-0.01C20.95,17.2,22,14.65,22,12c0-2.65-1.06-5.19-2.93-7.07 C15.16,1.03,8.83,1.03,4.92,4.94z M18,18c-1.6,1.59-3.76,2.48-6.02,2.48c-4.69-0.01-8.49-3.83-8.48-8.52 c0.01-4.69,3.83-8.49,8.52-8.48c4.69,0.01,8.49,3.83,8.48,8.52C20.49,14.25,19.6,16.41,18,18z" />
- <path
- android:fillColor="#000000"
- android:pathData="M 12 7 C 12.5522847498 7 13 7.44771525017 13 8 C 13 8.55228474983 12.5522847498 9 12 9 C 11.4477152502 9 11 8.55228474983 11 8 C 11 7.44771525017 11.4477152502 7 12 7 Z" />
- <path
- android:fillColor="#000000"
- android:pathData="M12,10.5c-0.41,0-0.75,0.34-0.75,0.75v5c0,0.41,0.34,0.75,0.75,0.75s0.75-0.34,0.75-0.75v-5 C12.75,10.84,12.41,10.5,12,10.5z" />
+ android:fillColor="@android:color/white"
+ android:pathData="M12,2C6.48,2,2,6.48,2,12c0,5.52,4.48,10,10,10s10-4.48,10-10C22,6.48,17.52,2,12,2z M13,17c0,0.55-0.45,1-1,1s-1-0.45-1-1 v-5c0-0.55,0.45-1,1-1s1,0.45,1,1V17z M12,9.25c-0.69,0-1.25-0.56-1.25-1.25S11.31,6.75,12,6.75S13.25,7.31,13.25,8 S12.69,9.25,12,9.25z" />
</vector>
\ No newline at end of file
diff --git a/packages/overlays/IconPackRoundedLauncherOverlay/res/drawable/ic_wallpaper.xml b/packages/overlays/IconPackFilledLauncherOverlay/res/drawable/ic_palette.xml
similarity index 90%
rename from packages/overlays/IconPackRoundedLauncherOverlay/res/drawable/ic_wallpaper.xml
rename to packages/overlays/IconPackFilledLauncherOverlay/res/drawable/ic_palette.xml
index 880b2abc..e9a89ec 100644
--- a/packages/overlays/IconPackRoundedLauncherOverlay/res/drawable/ic_wallpaper.xml
+++ b/packages/overlays/IconPackFilledLauncherOverlay/res/drawable/ic_palette.xml
@@ -16,10 +16,10 @@
-->
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:height="24dp"
- android:viewportHeight="24"
+ android:viewportHeight="24" android:tint="?android:attr/textColorPrimary"
android:viewportWidth="24"
android:width="24dp" >
<path
- android:fillColor="#000000"
+ android:fillColor="@android:color/white"
android:pathData="M12,2C6.49,2,2,6.49,2,12s4.49,10,10,10c1.38,0,2.5-1.12,2.5-2.5c0-0.61-0.23-1.2-0.64-1.67c-0.08-0.1-0.13-0.21-0.13-0.33 c0-0.28,0.22-0.5,0.5-0.5H16c3.31,0,6-2.69,6-6C22,6.04,17.51,2,12,2z M6.5,13C5.67,13,5,12.33,5,11.5S5.67,10,6.5,10 S8,10.67,8,11.5S7.33,13,6.5,13z M9.5,9C8.67,9,8,8.33,8,7.5S8.67,6,9.5,6S11,6.67,11,7.5S10.33,9,9.5,9z M14.5,9 C13.67,9,13,8.33,13,7.5S13.67,6,14.5,6S16,6.67,16,7.5S15.33,9,14.5,9z M17.5,13c-0.83,0-1.5-0.67-1.5-1.5s0.67-1.5,1.5-1.5 s1.5,0.67,1.5,1.5S18.33,13,17.5,13z" />
</vector>
\ No newline at end of file
diff --git a/packages/overlays/IconPackFilledLauncherOverlay/res/drawable/ic_pin.xml b/packages/overlays/IconPackFilledLauncherOverlay/res/drawable/ic_pin.xml
new file mode 100644
index 0000000..698f718
--- /dev/null
+++ b/packages/overlays/IconPackFilledLauncherOverlay/res/drawable/ic_pin.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2019 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+ android:width="24dp"
+ android:height="24dp"
+ android:viewportWidth="24"
+ android:viewportHeight="24" android:tint="?android:attr/textColorPrimary">
+
+ <path
+ android:fillColor="@android:color/white"
+ android:pathData="M5.71,14.29C5.08,14.92,5.52,16,6.41,16H11v6c0,0.55,0.45,1,1,1s1-0.45,1-1v-6h4.59c0.89,0,1.34-1.08,0.71-1.71L16,12V5
+h0.5c0.55,0,1-0.45,1-1s-0.45-1-1-1h-9c-0.55,0-1,0.45-1,1s0.45,1,1,1H8v7L5.71,14.29z" />
+</vector>
\ No newline at end of file
diff --git a/packages/overlays/IconPackFilledLauncherOverlay/res/drawable/ic_remove_no_shadow.xml b/packages/overlays/IconPackFilledLauncherOverlay/res/drawable/ic_remove_no_shadow.xml
index 82c2a31..b3288d9 100644
--- a/packages/overlays/IconPackFilledLauncherOverlay/res/drawable/ic_remove_no_shadow.xml
+++ b/packages/overlays/IconPackFilledLauncherOverlay/res/drawable/ic_remove_no_shadow.xml
@@ -16,10 +16,10 @@
-->
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:height="24dp"
- android:viewportHeight="24"
+ android:viewportHeight="24" android:tint="?android:attr/textColorPrimary"
android:viewportWidth="24"
android:width="24dp" >
<path
- android:fillColor="#000000"
- android:pathData="M5.22,18.78C5.37,18.93,5.56,19,5.75,19s0.38-0.07,0.53-0.22L12,13.06l5.72,5.72c0.15,0.15,0.34,0.22,0.53,0.22 s0.38-0.07,0.53-0.22c0.29-0.29,0.29-0.77,0-1.06L13.06,12l5.72-5.72c0.29-0.29,0.29-0.77,0-1.06s-0.77-0.29-1.06,0L12,10.94 L6.28,5.22c-0.29-0.29-0.77-0.29-1.06,0s-0.29,0.77,0,1.06L10.94,12l-5.72,5.72C4.93,18.01,4.93,18.49,5.22,18.78z" />
+ android:fillColor="@android:color/white"
+ android:pathData="M5.7,18.3c0.39,0.39,1.02,0.39,1.41,0L12,13.41l4.89,4.89c0.39,0.39,1.02,0.39,1.41,0s0.39-1.02,0-1.41L13.41,12l4.89-4.89 c0.38-0.38,0.38-1.02,0-1.4c-0.39-0.39-1.02-0.39-1.41,0c0,0,0,0,0,0L12,10.59L7.11,5.7c-0.39-0.39-1.02-0.39-1.41,0 s-0.39,1.02,0,1.41L10.59,12L5.7,16.89C5.31,17.28,5.31,17.91,5.7,18.3z" />
</vector>
\ No newline at end of file
diff --git a/packages/overlays/IconPackFilledLauncherOverlay/res/drawable/ic_setting.xml b/packages/overlays/IconPackFilledLauncherOverlay/res/drawable/ic_setting.xml
index c4c5eaa..513633b 100644
--- a/packages/overlays/IconPackFilledLauncherOverlay/res/drawable/ic_setting.xml
+++ b/packages/overlays/IconPackFilledLauncherOverlay/res/drawable/ic_setting.xml
@@ -16,13 +16,10 @@
-->
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:height="24dp"
- android:viewportHeight="24"
+ android:viewportHeight="24" android:tint="?android:attr/textColorPrimary"
android:viewportWidth="24"
android:width="24dp" >
<path
- android:fillColor="#000000"
- android:pathData="M2.43,15.45l1.79,3.09c0.25,0.45,0.74,0.73,1.25,0.73c0.17,0,0.35-0.03,0.52-0.09l1.76-0.7c0.25,0.17,0.51,0.31,0.77,0.45 l0.26,1.84c0.09,0.71,0.69,1.24,1.42,1.24h3.61c0.72,0,1.33-0.53,1.43-1.19l0.26-1.86c0.25-0.14,0.51-0.28,0.76-0.45l1.76,0.7 c0.17,0.07,0.35,0.1,0.53,0.1c0.5,0,0.98-0.27,1.23-0.72l1.82-3.14c0.34-0.61,0.19-1.38-0.36-1.82l-1.48-1.16 c0.01-0.15,0.02-0.29,0.02-0.45s-0.01-0.3-0.02-0.45l1.48-1.16c0.55-0.43,0.7-1.19,0.35-1.84l-1.8-3.1 c-0.25-0.45-0.74-0.73-1.26-0.73c-0.17,0-0.35,0.03-0.52,0.09l-1.76,0.7c-0.25-0.17-0.51-0.31-0.77-0.45l-0.26-1.84 c-0.09-0.71-0.69-1.24-1.42-1.24h-3.61c-0.71,0-1.32,0.54-1.41,1.22L8.52,5.09C8.26,5.23,8.01,5.37,7.75,5.54L5.99,4.83 c-0.17-0.07-0.35-0.1-0.52-0.1c-0.5,0-0.98,0.27-1.22,0.72L2.43,8.55c-0.36,0.61-0.21,1.4,0.36,1.84l1.48,1.16 C4.27,11.7,4.26,11.85,4.26,12c0,0.16,0.01,0.3,0.02,0.45l-1.49,1.16C2.24,14.04,2.09,14.8,2.43,15.45z M5.2,13.63l0.63-0.49 l-0.05-0.79c-0.01-0.11-0.01-0.58,0-0.7l0.05-0.79L5.2,10.37L3.77,9.25l1.74-3l1.69,0.68l0.73,0.29l0.66-0.43 c0.19-0.13,0.4-0.25,0.65-0.38l0.67-0.36L10,5.3l0.25-1.79h3.48l0.26,1.8l0.11,0.76l0.69,0.36c0.23,0.12,0.44,0.24,0.64,0.37 l0.65,0.43l0.72-0.29l1.7-0.68l1.75,3.02l-1.43,1.12l-0.62,0.49l0.05,0.79c0.01,0.11,0.01,0.58,0,0.7l-0.05,0.79l0.62,0.49 l1.43,1.12l-1.74,3.02l-1.69-0.68l-0.72-0.29l-0.65,0.43c-0.19,0.13-0.4,0.25-0.65,0.38l-0.67,0.36l-0.11,0.75l-0.25,1.77h-3.5 L10,18.71l-0.11-0.76l-0.69-0.36c-0.23-0.12-0.44-0.24-0.64-0.37l-0.65-0.43l-0.72,0.29L5.5,17.76l-1.73-3.01L5.2,13.63z" />
- <path
- android:fillColor="#000000"
- android:pathData="M12,16c2.21,0,4-1.79,4-4s-1.79-4-4-4c-2.21,0-4,1.79-4,4S9.79,16,12,16z M12,9.5c1.38,0,2.5,1.12,2.5,2.5 s-1.12,2.5-2.5,2.5c-1.38,0-2.5-1.12-2.5-2.5S10.62,9.5,12,9.5z" />
+ android:fillColor="@android:color/white"
+ android:pathData="M21.64,8.39l-1.6-2.76c-0.28-0.48-0.88-0.7-1.36-0.5l-2.14,0.91c-0.48-0.37-1.01-0.68-1.57-0.92l-0.27-2.2 C14.64,2.4,14.14,2,13.59,2h-3.18C9.86,2,9.36,2.4,9.3,2.92L9.04,5.11c-0.57,0.24-1.1,0.55-1.58,0.92L5.32,5.12 c-0.48-0.2-1.08,0.02-1.36,0.5l-1.6,2.76C2.08,8.86,2.18,9.48,2.6,9.8l1.94,1.45C4.51,11.49,4.5,11.74,4.5,12s0.01,0.51,0.04,0.76 L2.6,14.2c-0.42,0.31-0.52,0.94-0.24,1.41l1.6,2.76c0.28,0.48,0.88,0.7,1.36,0.5l2.14-0.91c0.48,0.37,1.01,0.68,1.57,0.92 l0.27,2.19C9.36,21.6,9.86,22,10.41,22h3.18c0.55,0,1.04-0.4,1.11-0.92l0.27-2.19c0.56-0.24,1.09-0.55,1.57-0.92l2.14,0.91 c0.48,0.2,1.08-0.02,1.36-0.5l1.6-2.76c0.28-0.48,0.18-1.1-0.24-1.42l-1.94-1.45c0.03-0.25,0.04-0.5,0.04-0.76 s-0.01-0.51-0.04-0.76L21.4,9.8C21.82,9.49,21.92,8.86,21.64,8.39z M12,15.5c-1.93,0-3.5-1.57-3.5-3.5s1.57-3.5,3.5-3.5 s3.5,1.57,3.5,3.5S13.93,15.5,12,15.5z" />
</vector>
\ No newline at end of file
diff --git a/packages/overlays/IconPackFilledLauncherOverlay/res/drawable/ic_smartspace_preferences.xml b/packages/overlays/IconPackFilledLauncherOverlay/res/drawable/ic_smartspace_preferences.xml
index 790248a..4ca2967 100644
--- a/packages/overlays/IconPackFilledLauncherOverlay/res/drawable/ic_smartspace_preferences.xml
+++ b/packages/overlays/IconPackFilledLauncherOverlay/res/drawable/ic_smartspace_preferences.xml
@@ -16,10 +16,16 @@
-->
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:height="24dp"
- android:viewportHeight="24"
+ android:viewportHeight="24" android:tint="?android:attr/textColorPrimary"
android:viewportWidth="24"
android:width="24dp" >
<path
- android:fillColor="#000000"
- android:pathData="M14.38,7.3C14.18,7.1,13.92,7,13.66,7c-0.26,0-0.51,0.1-0.71,0.29L1.29,18.96c-0.39,0.39-0.39,1.02,0,1.41l2.34,2.34 C3.82,22.9,4.08,23,4.34,23s0.51-0.1,0.71-0.29L16.7,11.05c0.39-0.39,0.39-1.02,0-1.41L14.38,7.3z M4.34,21.29l-1.63-1.63 l7.45-7.45l1.63,1.63L4.34,21.29z M12.84,12.78l-1.63-1.63l2.45-2.45l1.62,1.64L12.84,12.78z M17.75,5.25h1v1 C18.75,6.66,19.09,7,19.5,7s0.75-0.34,0.75-0.75v-1h1C21.66,5.25,22,4.91,22,4.5s-0.34-0.75-0.75-0.75h-1v-1 C20.25,2.34,19.91,2,19.5,2s-0.75,0.34-0.75,0.75v1h-1C17.34,3.75,17,4.09,17,4.5S17.34,5.25,17.75,5.25z M5.75,5.25h1v1 C6.75,6.66,7.09,7,7.5,7s0.75-0.34,0.75-0.75v-1h1C9.66,5.25,10,4.91,10,4.5S9.66,3.75,9.25,3.75h-1v-1C8.25,2.34,7.91,2,7.5,2 S6.75,2.34,6.75,2.75v1h-1C5.34,3.75,5,4.09,5,4.5S5.34,5.25,5.75,5.25z M21.25,15.75h-1v-1c0-0.41-0.34-0.75-0.75-0.75 s-0.75,0.34-0.75,0.75v1h-1c-0.41,0-0.75,0.34-0.75,0.75s0.34,0.75,0.75,0.75h1v1c0,0.41,0.34,0.75,0.75,0.75s0.75-0.34,0.75-0.75 v-1h1c0.41,0,0.75-0.34,0.75-0.75S21.66,15.75,21.25,15.75z" />
+ android:fillColor="@android:color/white"
+ android:pathData="M21.23,2.43L19.5,3.4l-1.73-0.97c-0.22-0.12-0.46,0.12-0.34,0.34L18.4,4.5l-0.97,1.73c-0.12,0.22,0.12,0.46,0.34,0.34 L19.5,5.6l1.73,0.97c0.22,0.12,0.46-0.12,0.34-0.34L20.6,4.5l0.97-1.73C21.69,2.55,21.45,2.31,21.23,2.43z M14.37,7.29 c-0.39-0.39-1.02-0.39-1.41,0L1.29,18.96c-0.39,0.39-0.39,1.02,0,1.41l2.34,2.34c0.39,0.39,1.02,0.39,1.41,0L16.7,11.05 c0.39-0.39,0.39-1.02,0-1.41L14.37,7.29z M13.34,12.78l-2.12-2.12l2.44-2.44l2.12,2.12L13.34,12.78z" />
+ <path
+ android:fillColor="@android:color/white"
+ android:pathData="M21.23,14.43L19.5,15.4l-1.73-0.97c-0.22-0.12-0.46,0.12-0.34,0.34l0.97,1.73l-0.97,1.73c-0.12,0.22,0.12,0.46,0.34,0.34 l1.73-0.97l1.73,0.97c0.22,0.12,0.46-0.12,0.34-0.34L20.6,16.5l0.97-1.73C21.69,14.55,21.45,14.31,21.23,14.43z" />
+ <path
+ android:fillColor="@android:color/white"
+ android:pathData="M9.23,2.43L7.5,3.4L5.77,2.43C5.55,2.31,5.31,2.55,5.43,2.77L6.4,4.5L5.43,6.23C5.31,6.45,5.55,6.69,5.77,6.57L7.5,5.6 l1.73,0.97c0.22,0.12,0.46-0.12,0.34-0.34L8.6,4.5l0.97-1.73C9.69,2.55,9.45,2.31,9.23,2.43z" />
</vector>
\ No newline at end of file
diff --git a/packages/overlays/IconPackFilledLauncherOverlay/res/drawable/ic_split_screen.xml b/packages/overlays/IconPackFilledLauncherOverlay/res/drawable/ic_split_screen.xml
index 013b40f..6eddf3d 100644
--- a/packages/overlays/IconPackFilledLauncherOverlay/res/drawable/ic_split_screen.xml
+++ b/packages/overlays/IconPackFilledLauncherOverlay/res/drawable/ic_split_screen.xml
@@ -16,13 +16,13 @@
-->
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:height="24dp"
- android:viewportHeight="24"
+ android:viewportHeight="24" android:tint="?android:attr/textColorPrimary"
android:viewportWidth="24"
android:width="24dp" >
<path
- android:fillColor="#000000"
- android:pathData="M5,11h14c0.55,0,1-0.45,1-1V4c0-0.55-0.45-1-1-1H5C4.45,3,4,3.45,4,4v6C4,10.55,4.45,11,5,11z M5.5,4.5h13v5h-13V4.5z" />
+ android:fillColor="@android:color/white"
+ android:pathData="M18,2H6C4.9,2,4,2.9,4,4v5c0,1.1,0.9,2,2,2h12c1.1,0,2-0.9,2-2V4C20,2.9,19.1,2,18,2z" />
<path
- android:fillColor="#000000"
- android:pathData="M4,20c0,0.55,0.45,1,1,1h14c0.55,0,1-0.45,1-1v-6c0-0.55-0.45-1-1-1H5c-0.55,0-1,0.45-1,1V20z M5.5,14.5h13v5h-13V14.5z" />
+ android:fillColor="@android:color/white"
+ android:pathData="M18,13H6c-1.1,0-2,0.9-2,2v5c0,1.1,0.9,2,2,2h12c1.1,0,2-0.9,2-2v-5C20,13.9,19.1,13,18,13z" />
</vector>
\ No newline at end of file
diff --git a/packages/overlays/IconPackFilledLauncherOverlay/res/drawable/ic_wallpaper.xml b/packages/overlays/IconPackFilledLauncherOverlay/res/drawable/ic_wallpaper.xml
deleted file mode 100644
index e58c7b8..0000000
--- a/packages/overlays/IconPackFilledLauncherOverlay/res/drawable/ic_wallpaper.xml
+++ /dev/null
@@ -1,45 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
- Copyright (C) 2019 The Android Open Source Project
-
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
--->
-<vector xmlns:android="http://schemas.android.com/apk/res/android"
- android:height="24dp"
- android:viewportHeight="24"
- android:viewportWidth="24"
- android:width="24dp" >
- <group
- android:translateX="119.000000"
- android:translateY="358.000000" >
- <group
- android:translateX="2.000000"
- android:translateY="2.000000" >
- <path
- android:fillColor="#000000"
- android:pathData="M-109-356.5c4.69,0,8.5,3.36,8.5,7.5c0,2.48-2.02,4.5-4.5,4.5h-1.77c-1.1,0-2,0.9-2,2 c0,0.45,0.16,0.89,0.46,1.27l0.02,0.02l0.02,0.02c0.17,0.2,0.27,0.44,0.27,0.68c0,0.55-0.45,1-1,1c-4.69,0-8.5-3.81-8.5-8.5 S-113.69-356.5-109-356.5 M-109-358c-5.51,0-10,4.49-10,10s4.49,10,10,10c1.38,0,2.5-1.12,2.5-2.5c0-0.61-0.23-1.2-0.64-1.67 c-0.08-0.1-0.13-0.21-0.13-0.33c0-0.28,0.22-0.5,0.5-0.5h1.77c3.31,0,6-2.69,6-6C-99-353.96-103.49-358-109-358L-109-358z" />
- </group>
- </group>
- <path
- android:fillColor="#000000"
- android:pathData="M 6.5 10 C 7.32842712475 10 8 10.6715728753 8 11.5 C 8 12.3284271247 7.32842712475 13 6.5 13 C 5.67157287525 13 5 12.3284271247 5 11.5 C 5 10.6715728753 5.67157287525 10 6.5 10 Z" />
- <path
- android:fillColor="#000000"
- android:pathData="M 9.5 6 C 10.3284271247 6 11 6.67157287525 11 7.5 C 11 8.32842712475 10.3284271247 9 9.5 9 C 8.67157287525 9 8 8.32842712475 8 7.5 C 8 6.67157287525 8.67157287525 6 9.5 6 Z" />
- <path
- android:fillColor="#000000"
- android:pathData="M 14.5 6 C 15.3284271247 6 16 6.67157287525 16 7.5 C 16 8.32842712475 15.3284271247 9 14.5 9 C 13.6715728753 9 13 8.32842712475 13 7.5 C 13 6.67157287525 13.6715728753 6 14.5 6 Z" />
- <path
- android:fillColor="#000000"
- android:pathData="M 17.5 10 C 18.3284271247 10 19 10.6715728753 19 11.5 C 19 12.3284271247 18.3284271247 13 17.5 13 C 16.6715728753 13 16 12.3284271247 16 11.5 C 16 10.6715728753 16.6715728753 10 17.5 10 Z" />
-</vector>
\ No newline at end of file
diff --git a/packages/overlays/IconPackFilledLauncherOverlay/res/drawable/ic_warning.xml b/packages/overlays/IconPackFilledLauncherOverlay/res/drawable/ic_warning.xml
index 4af8a37..4198759 100644
--- a/packages/overlays/IconPackFilledLauncherOverlay/res/drawable/ic_warning.xml
+++ b/packages/overlays/IconPackFilledLauncherOverlay/res/drawable/ic_warning.xml
@@ -16,16 +16,10 @@
-->
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:height="24dp"
- android:viewportHeight="24"
+ android:viewportHeight="24" android:tint="?android:attr/textColorPrimary"
android:viewportWidth="24"
android:width="24dp" >
<path
- android:fillColor="#000000"
- android:pathData="M4.47,21h15.06c1.54,0,2.5-1.67,1.73-3L13.73,4.99c-0.39-0.67-1.06-1-1.73-1s-1.35,0.33-1.73,1L2.74,18 C1.97,19.33,2.93,21,4.47,21z M4.04,18.75l7.53-13.01c0.13-0.22,0.33-0.25,0.43-0.25s0.31,0.03,0.43,0.25l7.53,13.01 c0.13,0.22,0.05,0.41,0,0.5c-0.05,0.09-0.18,0.25-0.43,0.25H4.47c-0.25,0-0.38-0.16-0.43-0.25C3.98,19.16,3.91,18.97,4.04,18.75z" />
- <path
- android:fillColor="#000000"
- android:pathData="M12,14.5c0.41,0,0.75-0.34,0.75-0.75v-4C12.75,9.33,12.41,9,12,9s-0.75,0.34-0.75,0.75v4C11.25,14.16,11.59,14.5,12,14.5z" />
- <path
- android:fillColor="#000000"
- android:pathData="M 12 16 C 12.5522847498 16 13 16.4477152502 13 17 C 13 17.5522847498 12.5522847498 18 12 18 C 11.4477152502 18 11 17.5522847498 11 17 C 11 16.4477152502 11.4477152502 16 12 16 Z" />
+ android:fillColor="@android:color/white"
+ android:pathData="M12.87,3.49c-0.39-0.67-1.35-0.67-1.73,0l-9.27,16C1.48,20.17,1.96,21,2.73,21h18.53c0.77,0,1.25-0.83,0.87-1.5L12.87,3.49 z M11,10c0-0.55,0.45-1,1-1s1,0.45,1,1v3c0,0.55-0.45,1-1,1s-1-0.45-1-1V10z M12,18.25c-0.69,0-1.25-0.56-1.25-1.25 s0.56-1.25,1.25-1.25s1.25,0.56,1.25,1.25S12.69,18.25,12,18.25z" />
</vector>
\ No newline at end of file
diff --git a/packages/overlays/IconPackFilledLauncherOverlay/res/drawable/ic_widget.xml b/packages/overlays/IconPackFilledLauncherOverlay/res/drawable/ic_widget.xml
index 7cbf7f1..7316c02d5 100644
--- a/packages/overlays/IconPackFilledLauncherOverlay/res/drawable/ic_widget.xml
+++ b/packages/overlays/IconPackFilledLauncherOverlay/res/drawable/ic_widget.xml
@@ -16,19 +16,19 @@
-->
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:height="24dp"
- android:viewportHeight="24"
+ android:viewportHeight="24" android:tint="?android:attr/textColorPrimary"
android:viewportWidth="24"
android:width="24dp" >
<path
- android:fillColor="#000000"
- android:pathData="M10,3H4C3.45,3,3,3.45,3,4v6c0,0.55,0.45,1,1,1h6c0.55,0,1-0.45,1-1V4C11,3.45,10.55,3,10,3z M9.5,9.5h-5v-5h5V9.5z" />
+ android:fillColor="@android:color/white"
+ android:pathData="M17.7,2.3c-0.4-0.4-1-0.4-1.4,0l-4,4c-0.4,0.4-0.4,1,0,1.4l4,4c0.4,0.4,1,0.4,1.4,0l4-4c0.4-0.4,0.4-1,0-1.4L17.7,2.3z" />
<path
- android:fillColor="#000000"
- android:pathData="M10,13H4c-0.55,0-1,0.45-1,1v6c0,0.55,0.45,1,1,1h6c0.55,0,1-0.45,1-1v-6C11,13.45,10.55,13,10,13z M9.5,19.5h-5v-5h5 V19.5z" />
+ android:fillColor="@android:color/white"
+ android:pathData="M11,4c0-0.5-0.4-1-1-1H4C3.5,3,3,3.5,3,4v6c0,0.6,0.5,1,1,1h6c0.6,0,1-0.4,1-1V4z" />
<path
- android:fillColor="#000000"
- android:pathData="M20,13h-6c-0.55,0-1,0.45-1,1v6c0,0.55,0.45,1,1,1h6c0.55,0,1-0.45,1-1v-6C21,13.45,20.55,13,20,13z M19.5,19.5h-5v-5h5 V19.5z" />
+ android:fillColor="@android:color/white"
+ android:pathData="M20,21c0.5,0,1-0.5,1-1v-6c0-0.6-0.5-1-1-1h-6c-0.6,0-1,0.4-1,1v6c0,0.5,0.4,1,1,1H20z" />
<path
- android:fillColor="#000000"
- android:pathData="M21.95,6.29l-4.24-4.24c-0.2-0.2-0.45-0.29-0.71-0.29s-0.51,0.1-0.71,0.29l-4.24,4.24c-0.39,0.39-0.39,1.02,0,1.41 l4.24,4.24c0.2,0.2,0.45,0.29,0.71,0.29s0.51-0.1,0.71-0.29l4.24-4.24C22.34,7.32,22.34,6.68,21.95,6.29z M17,10.54L13.46,7 L17,3.46L20.54,7L17,10.54z" />
+ android:fillColor="@android:color/white"
+ android:pathData="M10,13H4c-0.5,0-1,0.4-1,1v6c0,0.5,0.5,1,1,1h6c0.6,0,1-0.5,1-1v-6C11,13.4,10.6,13,10,13z" />
</vector>
\ No newline at end of file
diff --git a/packages/overlays/IconPackRoundedLauncherOverlay/res/drawable/ic_clear.xml b/packages/overlays/IconPackRoundedLauncherOverlay/res/drawable/ic_clear.xml
deleted file mode 100644
index d04eb1f..0000000
--- a/packages/overlays/IconPackRoundedLauncherOverlay/res/drawable/ic_clear.xml
+++ /dev/null
@@ -1,28 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
- Copyright (C) 2019 The Android Open Source Project
-
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
--->
-<vector xmlns:android="http://schemas.android.com/apk/res/android"
- android:height="24dp"
- android:viewportHeight="24"
- android:viewportWidth="24"
- android:width="24dp" >
- <path
- android:fillColor="#000000"
- android:pathData="M18,4h-2.5l-0.71-0.71C14.61,3.11,14.35,3,14.09,3H9.9C9.64,3,9.38,3.11,9.2,3.29L8.49,4h-2.5c-0.55,0-1,0.45-1,1 s0.45,1,1,1h12c0.55,0,1-0.45,1-1C19,4.45,18.55,4,18,4z" />
- <path
- android:fillColor="#000000"
- android:pathData="M6,19c0,1.1,0.9,2,2,2h8c1.1,0,2-0.9,2-2V7H6V19z" />
-</vector>
\ No newline at end of file
diff --git a/packages/overlays/IconPackRoundedLauncherOverlay/res/drawable/ic_corp.xml b/packages/overlays/IconPackRoundedLauncherOverlay/res/drawable/ic_corp.xml
index ed39543..dccc23c 100644
--- a/packages/overlays/IconPackRoundedLauncherOverlay/res/drawable/ic_corp.xml
+++ b/packages/overlays/IconPackRoundedLauncherOverlay/res/drawable/ic_corp.xml
@@ -16,10 +16,10 @@
-->
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:height="24dp"
- android:viewportHeight="24"
+ android:viewportHeight="24" android:tint="?android:attr/textColorHint"
android:viewportWidth="24"
android:width="24dp" >
<path
- android:fillColor="#000000"
- android:pathData="M20,6h-4V4c0-1.11-0.89-2-2-2h-4C8.89,2,8,2.89,8,4v2H4C2.89,6,2.01,6.89,2.01,8L2,19c0,1.11,0.89,2,2,2h16 c1.11,0,2-0.89,2-2V8C22,6.89,21.11,6,20,6z M14,6h-4V4h4V6z" />
+ android:fillColor="@android:color/white"
+ android:pathData="M20,6h-4V4c0-1.1-0.9-2-2-2h-4C8.9,2,8,2.9,8,4v2H4C2.9,6,2,6.9,2,8v11c0,1.1,0.9,2,2,2h16c1.1,0,2-0.9,2-2V8 C22,6.9,21.1,6,20,6z M9.5,4c0-0.28,0.22-0.5,0.5-0.5h4c0.28,0,0.5,0.22,0.5,0.5v2h-5V4z M20.5,19c0,0.28-0.22,0.5-0.5,0.5H4 c-0.28,0-0.5-0.22-0.5-0.5V8c0-0.28,0.22-0.5,0.5-0.5h16c0.28,0,0.5,0.22,0.5,0.5V19z" />
</vector>
\ No newline at end of file
diff --git a/packages/overlays/IconPackRoundedLauncherOverlay/res/drawable/ic_drag_handle.xml b/packages/overlays/IconPackRoundedLauncherOverlay/res/drawable/ic_drag_handle.xml
new file mode 100644
index 0000000..68c0a80
--- /dev/null
+++ b/packages/overlays/IconPackRoundedLauncherOverlay/res/drawable/ic_drag_handle.xml
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2019 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+ android:width="24dp"
+ android:height="24dp"
+ android:viewportWidth="24"
+ android:viewportHeight="24" android:tint="?android:attr/textColorHint">
+
+ <path
+ android:fillColor="@android:color/white"
+ android:pathData="M5.75,10.5h12.5c0.41,0,0.75-0.34,0.75-0.75S18.66,9,18.25,9H5.75C5.34,9,5,9.34,5,9.75S5.34,10.5,5.75,10.5z" />
+ <path
+ android:fillColor="@android:color/white"
+ android:pathData="M18.25,13.5H5.75C5.34,13.5,5,13.84,5,14.25S5.34,15,5.75,15h12.5c0.41,0,0.75-0.34,0.75-0.75S18.66,13.5,18.25,13.5z" />
+</vector>
\ No newline at end of file
diff --git a/packages/overlays/IconPackRoundedLauncherOverlay/res/drawable/ic_hourglass_top.xml b/packages/overlays/IconPackRoundedLauncherOverlay/res/drawable/ic_hourglass_top.xml
new file mode 100644
index 0000000..0fd3229
--- /dev/null
+++ b/packages/overlays/IconPackRoundedLauncherOverlay/res/drawable/ic_hourglass_top.xml
@@ -0,0 +1,29 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2019 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+ android:width="24dp"
+ android:height="24dp"
+ android:viewportWidth="24"
+ android:viewportHeight="24" android:tint="?android:attr/textColorPrimary">
+
+ <path
+ android:fillColor="@android:color/white"
+ android:pathData="M16,3H8C7.45,3,7,3.45,7,4v1.93v0c0,0.33,0.03,0.66,0.1,0.98c0.19,0.96,0.66,1.85,1.37,2.56L11,12l-2.54,2.54
+C7.53,15.47,7,16.74,7,18.07V20c0,0.55,0.45,1,1,1h8c0.55,0,1-0.45,1-1v-1.93c0-1.33-0.53-2.6-1.46-3.54L13,12l2.54-2.54
+c0.7-0.7,1.18-1.59,1.37-2.56C16.97,6.59,17,6.26,17,5.93v0V4C17,3.45,16.55,3,16,3z
+M14.47,15.6c0.66,0.66,1.03,1.54,1.03,2.47
+v1.43h-7v-1.43c0-0.93,0.36-1.81,1.03-2.47L12,13.12L14.47,15.6z" />
+</vector>
\ No newline at end of file
diff --git a/packages/overlays/IconPackRoundedLauncherOverlay/res/drawable/ic_info_no_shadow.xml b/packages/overlays/IconPackRoundedLauncherOverlay/res/drawable/ic_info_no_shadow.xml
index dfa17d6..f799d40 100644
--- a/packages/overlays/IconPackRoundedLauncherOverlay/res/drawable/ic_info_no_shadow.xml
+++ b/packages/overlays/IconPackRoundedLauncherOverlay/res/drawable/ic_info_no_shadow.xml
@@ -16,10 +16,16 @@
-->
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:height="24dp"
- android:viewportHeight="24"
+ android:viewportHeight="24" android:tint="?android:attr/textColorPrimary"
android:viewportWidth="24"
android:width="24dp" >
<path
- android:fillColor="#000000"
- android:pathData="M12,2C6.48,2,2,6.48,2,12c0,5.52,4.48,10,10,10s10-4.48,10-10C22,6.48,17.52,2,12,2z M13,17c0,0.55-0.45,1-1,1s-1-0.45-1-1 v-5c0-0.55,0.45-1,1-1s1,0.45,1,1V17z M12,9.25c-0.69,0-1.25-0.56-1.25-1.25S11.31,6.75,12,6.75S13.25,7.31,13.25,8 S12.69,9.25,12,9.25z" />
+ android:fillColor="@android:color/white"
+ android:pathData="M4.92,4.94c-3.9,3.91-3.9,10.24,0.01,14.14s10.24,3.9,14.14-0.01C20.95,17.2,22,14.65,22,12c0-2.65-1.06-5.19-2.93-7.07 C15.16,1.03,8.83,1.03,4.92,4.94z M18,18c-1.6,1.59-3.76,2.48-6.02,2.48c-4.69-0.01-8.49-3.83-8.48-8.52 c0.01-4.69,3.83-8.49,8.52-8.48c4.69,0.01,8.49,3.83,8.48,8.52C20.49,14.25,19.6,16.41,18,18z" />
+ <path
+ android:fillColor="@android:color/white"
+ android:pathData="M 12 7 C 12.5522847498 7 13 7.44771525017 13 8 C 13 8.55228474983 12.5522847498 9 12 9 C 11.4477152502 9 11 8.55228474983 11 8 C 11 7.44771525017 11.4477152502 7 12 7 Z" />
+ <path
+ android:fillColor="@android:color/white"
+ android:pathData="M12,10.5c-0.41,0-0.75,0.34-0.75,0.75v5c0,0.41,0.34,0.75,0.75,0.75s0.75-0.34,0.75-0.75v-5 C12.75,10.84,12.41,10.5,12,10.5z" />
</vector>
\ No newline at end of file
diff --git a/packages/overlays/IconPackCircularLauncherOverlay/res/drawable/ic_wallpaper.xml b/packages/overlays/IconPackRoundedLauncherOverlay/res/drawable/ic_palette.xml
similarity index 87%
copy from packages/overlays/IconPackCircularLauncherOverlay/res/drawable/ic_wallpaper.xml
copy to packages/overlays/IconPackRoundedLauncherOverlay/res/drawable/ic_palette.xml
index e58c7b8..964955b 100644
--- a/packages/overlays/IconPackCircularLauncherOverlay/res/drawable/ic_wallpaper.xml
+++ b/packages/overlays/IconPackRoundedLauncherOverlay/res/drawable/ic_palette.xml
@@ -16,7 +16,7 @@
-->
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:height="24dp"
- android:viewportHeight="24"
+ android:viewportHeight="24" android:tint="?android:attr/textColorPrimary"
android:viewportWidth="24"
android:width="24dp" >
<group
@@ -26,20 +26,20 @@
android:translateX="2.000000"
android:translateY="2.000000" >
<path
- android:fillColor="#000000"
+ android:fillColor="@android:color/white"
android:pathData="M-109-356.5c4.69,0,8.5,3.36,8.5,7.5c0,2.48-2.02,4.5-4.5,4.5h-1.77c-1.1,0-2,0.9-2,2 c0,0.45,0.16,0.89,0.46,1.27l0.02,0.02l0.02,0.02c0.17,0.2,0.27,0.44,0.27,0.68c0,0.55-0.45,1-1,1c-4.69,0-8.5-3.81-8.5-8.5 S-113.69-356.5-109-356.5 M-109-358c-5.51,0-10,4.49-10,10s4.49,10,10,10c1.38,0,2.5-1.12,2.5-2.5c0-0.61-0.23-1.2-0.64-1.67 c-0.08-0.1-0.13-0.21-0.13-0.33c0-0.28,0.22-0.5,0.5-0.5h1.77c3.31,0,6-2.69,6-6C-99-353.96-103.49-358-109-358L-109-358z" />
</group>
</group>
<path
- android:fillColor="#000000"
+ android:fillColor="@android:color/white"
android:pathData="M 6.5 10 C 7.32842712475 10 8 10.6715728753 8 11.5 C 8 12.3284271247 7.32842712475 13 6.5 13 C 5.67157287525 13 5 12.3284271247 5 11.5 C 5 10.6715728753 5.67157287525 10 6.5 10 Z" />
<path
- android:fillColor="#000000"
+ android:fillColor="@android:color/white"
android:pathData="M 9.5 6 C 10.3284271247 6 11 6.67157287525 11 7.5 C 11 8.32842712475 10.3284271247 9 9.5 9 C 8.67157287525 9 8 8.32842712475 8 7.5 C 8 6.67157287525 8.67157287525 6 9.5 6 Z" />
<path
- android:fillColor="#000000"
+ android:fillColor="@android:color/white"
android:pathData="M 14.5 6 C 15.3284271247 6 16 6.67157287525 16 7.5 C 16 8.32842712475 15.3284271247 9 14.5 9 C 13.6715728753 9 13 8.32842712475 13 7.5 C 13 6.67157287525 13.6715728753 6 14.5 6 Z" />
<path
- android:fillColor="#000000"
+ android:fillColor="@android:color/white"
android:pathData="M 17.5 10 C 18.3284271247 10 19 10.6715728753 19 11.5 C 19 12.3284271247 18.3284271247 13 17.5 13 C 16.6715728753 13 16 12.3284271247 16 11.5 C 16 10.6715728753 16.6715728753 10 17.5 10 Z" />
</vector>
\ No newline at end of file
diff --git a/packages/overlays/IconPackRoundedLauncherOverlay/res/drawable/ic_pin.xml b/packages/overlays/IconPackRoundedLauncherOverlay/res/drawable/ic_pin.xml
new file mode 100644
index 0000000..f1bf5c3
--- /dev/null
+++ b/packages/overlays/IconPackRoundedLauncherOverlay/res/drawable/ic_pin.xml
@@ -0,0 +1,29 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2019 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+ android:width="24dp"
+ android:height="24dp"
+ android:viewportWidth="24"
+ android:viewportHeight="24" android:tint="?android:attr/textColorPrimary">
+
+ <path
+ android:fillColor="@android:color/white"
+ android:pathData="M5.71,14.29C5.08,14.92,5.53,16,6.42,16h4.83v6.25c0,0.41,0.34,0.75,0.75,0.75s0.75-0.34,0.75-0.75V16h4.84
+c0.89,0,1.34-1.08,0.71-1.71L16,12V4.5h1.23c0.41,0,0.75-0.34,0.75-0.75S17.65,3,17.23,3H16H8H6.73C6.32,3,5.98,3.34,5.98,3.75
+S6.32,4.5,6.73,4.5H8V12L5.71,14.29z
+M14.5,4.5V12c0,0.4,0.16,0.78,0.44,1.06l1.44,1.44H7.62l1.44-1.44C9.34,12.78,9.5,12.4,9.5,12
+V4.5H14.5z" />
+</vector>
\ No newline at end of file
diff --git a/packages/overlays/IconPackRoundedLauncherOverlay/res/drawable/ic_remove_no_shadow.xml b/packages/overlays/IconPackRoundedLauncherOverlay/res/drawable/ic_remove_no_shadow.xml
index 22401a1..864a047 100644
--- a/packages/overlays/IconPackRoundedLauncherOverlay/res/drawable/ic_remove_no_shadow.xml
+++ b/packages/overlays/IconPackRoundedLauncherOverlay/res/drawable/ic_remove_no_shadow.xml
@@ -16,10 +16,10 @@
-->
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:height="24dp"
- android:viewportHeight="24"
+ android:viewportHeight="24" android:tint="?android:attr/textColorPrimary"
android:viewportWidth="24"
android:width="24dp" >
<path
- android:fillColor="#000000"
- android:pathData="M5.7,18.3c0.39,0.39,1.02,0.39,1.41,0L12,13.41l4.89,4.89c0.39,0.39,1.02,0.39,1.41,0s0.39-1.02,0-1.41L13.41,12l4.89-4.89 c0.38-0.38,0.38-1.02,0-1.4c-0.39-0.39-1.02-0.39-1.41,0c0,0,0,0,0,0L12,10.59L7.11,5.7c-0.39-0.39-1.02-0.39-1.41,0 s-0.39,1.02,0,1.41L10.59,12L5.7,16.89C5.31,17.28,5.31,17.91,5.7,18.3z" />
+ android:fillColor="@android:color/white"
+ android:pathData="M5.22,18.78C5.37,18.93,5.56,19,5.75,19s0.38-0.07,0.53-0.22L12,13.06l5.72,5.72c0.15,0.15,0.34,0.22,0.53,0.22 s0.38-0.07,0.53-0.22c0.29-0.29,0.29-0.77,0-1.06L13.06,12l5.72-5.72c0.29-0.29,0.29-0.77,0-1.06s-0.77-0.29-1.06,0L12,10.94 L6.28,5.22c-0.29-0.29-0.77-0.29-1.06,0s-0.29,0.77,0,1.06L10.94,12l-5.72,5.72C4.93,18.01,4.93,18.49,5.22,18.78z" />
</vector>
\ No newline at end of file
diff --git a/packages/overlays/IconPackRoundedLauncherOverlay/res/drawable/ic_setting.xml b/packages/overlays/IconPackRoundedLauncherOverlay/res/drawable/ic_setting.xml
index b4f0478..6ff3144 100644
--- a/packages/overlays/IconPackRoundedLauncherOverlay/res/drawable/ic_setting.xml
+++ b/packages/overlays/IconPackRoundedLauncherOverlay/res/drawable/ic_setting.xml
@@ -16,10 +16,13 @@
-->
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:height="24dp"
- android:viewportHeight="24"
+ android:viewportHeight="24" android:tint="?android:attr/textColorPrimary"
android:viewportWidth="24"
android:width="24dp" >
<path
- android:fillColor="#000000"
- android:pathData="M21.64,8.39l-1.6-2.76c-0.28-0.48-0.88-0.7-1.36-0.5l-2.14,0.91c-0.48-0.37-1.01-0.68-1.57-0.92l-0.27-2.2 C14.64,2.4,14.14,2,13.59,2h-3.18C9.86,2,9.36,2.4,9.3,2.92L9.04,5.11c-0.57,0.24-1.1,0.55-1.58,0.92L5.32,5.12 c-0.48-0.2-1.08,0.02-1.36,0.5l-1.6,2.76C2.08,8.86,2.18,9.48,2.6,9.8l1.94,1.45C4.51,11.49,4.5,11.74,4.5,12s0.01,0.51,0.04,0.76 L2.6,14.2c-0.42,0.31-0.52,0.94-0.24,1.41l1.6,2.76c0.28,0.48,0.88,0.7,1.36,0.5l2.14-0.91c0.48,0.37,1.01,0.68,1.57,0.92 l0.27,2.19C9.36,21.6,9.86,22,10.41,22h3.18c0.55,0,1.04-0.4,1.11-0.92l0.27-2.19c0.56-0.24,1.09-0.55,1.57-0.92l2.14,0.91 c0.48,0.2,1.08-0.02,1.36-0.5l1.6-2.76c0.28-0.48,0.18-1.1-0.24-1.42l-1.94-1.45c0.03-0.25,0.04-0.5,0.04-0.76 s-0.01-0.51-0.04-0.76L21.4,9.8C21.82,9.49,21.92,8.86,21.64,8.39z M12,15.5c-1.93,0-3.5-1.57-3.5-3.5s1.57-3.5,3.5-3.5 s3.5,1.57,3.5,3.5S13.93,15.5,12,15.5z" />
+ android:fillColor="@android:color/white"
+ android:pathData="M2.43,15.45l1.79,3.09c0.25,0.45,0.74,0.73,1.25,0.73c0.17,0,0.35-0.03,0.52-0.09l1.76-0.7c0.25,0.17,0.51,0.31,0.77,0.45 l0.26,1.84c0.09,0.71,0.69,1.24,1.42,1.24h3.61c0.72,0,1.33-0.53,1.43-1.19l0.26-1.86c0.25-0.14,0.51-0.28,0.76-0.45l1.76,0.7 c0.17,0.07,0.35,0.1,0.53,0.1c0.5,0,0.98-0.27,1.23-0.72l1.82-3.14c0.34-0.61,0.19-1.38-0.36-1.82l-1.48-1.16 c0.01-0.15,0.02-0.29,0.02-0.45s-0.01-0.3-0.02-0.45l1.48-1.16c0.55-0.43,0.7-1.19,0.35-1.84l-1.8-3.1 c-0.25-0.45-0.74-0.73-1.26-0.73c-0.17,0-0.35,0.03-0.52,0.09l-1.76,0.7c-0.25-0.17-0.51-0.31-0.77-0.45l-0.26-1.84 c-0.09-0.71-0.69-1.24-1.42-1.24h-3.61c-0.71,0-1.32,0.54-1.41,1.22L8.52,5.09C8.26,5.23,8.01,5.37,7.75,5.54L5.99,4.83 c-0.17-0.07-0.35-0.1-0.52-0.1c-0.5,0-0.98,0.27-1.22,0.72L2.43,8.55c-0.36,0.61-0.21,1.4,0.36,1.84l1.48,1.16 C4.27,11.7,4.26,11.85,4.26,12c0,0.16,0.01,0.3,0.02,0.45l-1.49,1.16C2.24,14.04,2.09,14.8,2.43,15.45z M5.2,13.63l0.63-0.49 l-0.05-0.79c-0.01-0.11-0.01-0.58,0-0.7l0.05-0.79L5.2,10.37L3.77,9.25l1.74-3l1.69,0.68l0.73,0.29l0.66-0.43 c0.19-0.13,0.4-0.25,0.65-0.38l0.67-0.36L10,5.3l0.25-1.79h3.48l0.26,1.8l0.11,0.76l0.69,0.36c0.23,0.12,0.44,0.24,0.64,0.37 l0.65,0.43l0.72-0.29l1.7-0.68l1.75,3.02l-1.43,1.12l-0.62,0.49l0.05,0.79c0.01,0.11,0.01,0.58,0,0.7l-0.05,0.79l0.62,0.49 l1.43,1.12l-1.74,3.02l-1.69-0.68l-0.72-0.29l-0.65,0.43c-0.19,0.13-0.4,0.25-0.65,0.38l-0.67,0.36l-0.11,0.75l-0.25,1.77h-3.5 L10,18.71l-0.11-0.76l-0.69-0.36c-0.23-0.12-0.44-0.24-0.64-0.37l-0.65-0.43l-0.72,0.29L5.5,17.76l-1.73-3.01L5.2,13.63z" />
+ <path
+ android:fillColor="@android:color/white"
+ android:pathData="M12,16c2.21,0,4-1.79,4-4s-1.79-4-4-4c-2.21,0-4,1.79-4,4S9.79,16,12,16z M12,9.5c1.38,0,2.5,1.12,2.5,2.5 s-1.12,2.5-2.5,2.5c-1.38,0-2.5-1.12-2.5-2.5S10.62,9.5,12,9.5z" />
</vector>
\ No newline at end of file
diff --git a/packages/overlays/IconPackRoundedLauncherOverlay/res/drawable/ic_smartspace_preferences.xml b/packages/overlays/IconPackRoundedLauncherOverlay/res/drawable/ic_smartspace_preferences.xml
index 57ae91f..3cc9e51 100644
--- a/packages/overlays/IconPackRoundedLauncherOverlay/res/drawable/ic_smartspace_preferences.xml
+++ b/packages/overlays/IconPackRoundedLauncherOverlay/res/drawable/ic_smartspace_preferences.xml
@@ -16,16 +16,10 @@
-->
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:height="24dp"
- android:viewportHeight="24"
+ android:viewportHeight="24" android:tint="?android:attr/textColorPrimary"
android:viewportWidth="24"
android:width="24dp" >
<path
- android:fillColor="#000000"
- android:pathData="M21.23,2.43L19.5,3.4l-1.73-0.97c-0.22-0.12-0.46,0.12-0.34,0.34L18.4,4.5l-0.97,1.73c-0.12,0.22,0.12,0.46,0.34,0.34 L19.5,5.6l1.73,0.97c0.22,0.12,0.46-0.12,0.34-0.34L20.6,4.5l0.97-1.73C21.69,2.55,21.45,2.31,21.23,2.43z M14.37,7.29 c-0.39-0.39-1.02-0.39-1.41,0L1.29,18.96c-0.39,0.39-0.39,1.02,0,1.41l2.34,2.34c0.39,0.39,1.02,0.39,1.41,0L16.7,11.05 c0.39-0.39,0.39-1.02,0-1.41L14.37,7.29z M13.34,12.78l-2.12-2.12l2.44-2.44l2.12,2.12L13.34,12.78z" />
- <path
- android:fillColor="#000000"
- android:pathData="M21.23,14.43L19.5,15.4l-1.73-0.97c-0.22-0.12-0.46,0.12-0.34,0.34l0.97,1.73l-0.97,1.73c-0.12,0.22,0.12,0.46,0.34,0.34 l1.73-0.97l1.73,0.97c0.22,0.12,0.46-0.12,0.34-0.34L20.6,16.5l0.97-1.73C21.69,14.55,21.45,14.31,21.23,14.43z" />
- <path
- android:fillColor="#000000"
- android:pathData="M9.23,2.43L7.5,3.4L5.77,2.43C5.55,2.31,5.31,2.55,5.43,2.77L6.4,4.5L5.43,6.23C5.31,6.45,5.55,6.69,5.77,6.57L7.5,5.6 l1.73,0.97c0.22,0.12,0.46-0.12,0.34-0.34L8.6,4.5l0.97-1.73C9.69,2.55,9.45,2.31,9.23,2.43z" />
+ android:fillColor="@android:color/white"
+ android:pathData="M14.38,7.3C14.18,7.1,13.92,7,13.66,7c-0.26,0-0.51,0.1-0.71,0.29L1.29,18.96c-0.39,0.39-0.39,1.02,0,1.41l2.34,2.34 C3.82,22.9,4.08,23,4.34,23s0.51-0.1,0.71-0.29L16.7,11.05c0.39-0.39,0.39-1.02,0-1.41L14.38,7.3z M4.34,21.29l-1.63-1.63 l7.45-7.45l1.63,1.63L4.34,21.29z M12.84,12.78l-1.63-1.63l2.45-2.45l1.62,1.64L12.84,12.78z M17.75,5.25h1v1 C18.75,6.66,19.09,7,19.5,7s0.75-0.34,0.75-0.75v-1h1C21.66,5.25,22,4.91,22,4.5s-0.34-0.75-0.75-0.75h-1v-1 C20.25,2.34,19.91,2,19.5,2s-0.75,0.34-0.75,0.75v1h-1C17.34,3.75,17,4.09,17,4.5S17.34,5.25,17.75,5.25z M5.75,5.25h1v1 C6.75,6.66,7.09,7,7.5,7s0.75-0.34,0.75-0.75v-1h1C9.66,5.25,10,4.91,10,4.5S9.66,3.75,9.25,3.75h-1v-1C8.25,2.34,7.91,2,7.5,2 S6.75,2.34,6.75,2.75v1h-1C5.34,3.75,5,4.09,5,4.5S5.34,5.25,5.75,5.25z M21.25,15.75h-1v-1c0-0.41-0.34-0.75-0.75-0.75 s-0.75,0.34-0.75,0.75v1h-1c-0.41,0-0.75,0.34-0.75,0.75s0.34,0.75,0.75,0.75h1v1c0,0.41,0.34,0.75,0.75,0.75s0.75-0.34,0.75-0.75 v-1h1c0.41,0,0.75-0.34,0.75-0.75S21.66,15.75,21.25,15.75z" />
</vector>
\ No newline at end of file
diff --git a/packages/overlays/IconPackRoundedLauncherOverlay/res/drawable/ic_split_screen.xml b/packages/overlays/IconPackRoundedLauncherOverlay/res/drawable/ic_split_screen.xml
index dc3bd95..aaf4900 100644
--- a/packages/overlays/IconPackRoundedLauncherOverlay/res/drawable/ic_split_screen.xml
+++ b/packages/overlays/IconPackRoundedLauncherOverlay/res/drawable/ic_split_screen.xml
@@ -16,13 +16,13 @@
-->
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:height="24dp"
- android:viewportHeight="24"
+ android:viewportHeight="24" android:tint="?android:attr/textColorPrimary"
android:viewportWidth="24"
android:width="24dp" >
<path
- android:fillColor="#000000"
- android:pathData="M18,2H6C4.9,2,4,2.9,4,4v5c0,1.1,0.9,2,2,2h12c1.1,0,2-0.9,2-2V4C20,2.9,19.1,2,18,2z" />
+ android:fillColor="@android:color/white"
+ android:pathData="M5,11h14c0.55,0,1-0.45,1-1V4c0-0.55-0.45-1-1-1H5C4.45,3,4,3.45,4,4v6C4,10.55,4.45,11,5,11z M5.5,4.5h13v5h-13V4.5z" />
<path
- android:fillColor="#000000"
- android:pathData="M18,13H6c-1.1,0-2,0.9-2,2v5c0,1.1,0.9,2,2,2h12c1.1,0,2-0.9,2-2v-5C20,13.9,19.1,13,18,13z" />
+ android:fillColor="@android:color/white"
+ android:pathData="M4,20c0,0.55,0.45,1,1,1h14c0.55,0,1-0.45,1-1v-6c0-0.55-0.45-1-1-1H5c-0.55,0-1,0.45-1,1V20z M5.5,14.5h13v5h-13V14.5z" />
</vector>
\ No newline at end of file
diff --git a/packages/overlays/IconPackRoundedLauncherOverlay/res/drawable/ic_warning.xml b/packages/overlays/IconPackRoundedLauncherOverlay/res/drawable/ic_warning.xml
index 184714c..63d7b78 100644
--- a/packages/overlays/IconPackRoundedLauncherOverlay/res/drawable/ic_warning.xml
+++ b/packages/overlays/IconPackRoundedLauncherOverlay/res/drawable/ic_warning.xml
@@ -16,10 +16,16 @@
-->
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:height="24dp"
- android:viewportHeight="24"
+ android:viewportHeight="24" android:tint="?android:attr/textColorPrimary"
android:viewportWidth="24"
android:width="24dp" >
<path
- android:fillColor="#000000"
- android:pathData="M12.87,3.49c-0.39-0.67-1.35-0.67-1.73,0l-9.27,16C1.48,20.17,1.96,21,2.73,21h18.53c0.77,0,1.25-0.83,0.87-1.5L12.87,3.49 z M11,10c0-0.55,0.45-1,1-1s1,0.45,1,1v3c0,0.55-0.45,1-1,1s-1-0.45-1-1V10z M12,18.25c-0.69,0-1.25-0.56-1.25-1.25 s0.56-1.25,1.25-1.25s1.25,0.56,1.25,1.25S12.69,18.25,12,18.25z" />
+ android:fillColor="@android:color/white"
+ android:pathData="M4.47,21h15.06c1.54,0,2.5-1.67,1.73-3L13.73,4.99c-0.39-0.67-1.06-1-1.73-1s-1.35,0.33-1.73,1L2.74,18 C1.97,19.33,2.93,21,4.47,21z M4.04,18.75l7.53-13.01c0.13-0.22,0.33-0.25,0.43-0.25s0.31,0.03,0.43,0.25l7.53,13.01 c0.13,0.22,0.05,0.41,0,0.5c-0.05,0.09-0.18,0.25-0.43,0.25H4.47c-0.25,0-0.38-0.16-0.43-0.25C3.98,19.16,3.91,18.97,4.04,18.75z" />
+ <path
+ android:fillColor="@android:color/white"
+ android:pathData="M12,14.5c0.41,0,0.75-0.34,0.75-0.75v-4C12.75,9.33,12.41,9,12,9s-0.75,0.34-0.75,0.75v4C11.25,14.16,11.59,14.5,12,14.5z" />
+ <path
+ android:fillColor="@android:color/white"
+ android:pathData="M 12 16 C 12.5522847498 16 13 16.4477152502 13 17 C 13 17.5522847498 12.5522847498 18 12 18 C 11.4477152502 18 11 17.5522847498 11 17 C 11 16.4477152502 11.4477152502 16 12 16 Z" />
</vector>
\ No newline at end of file
diff --git a/packages/overlays/IconPackRoundedLauncherOverlay/res/drawable/ic_widget.xml b/packages/overlays/IconPackRoundedLauncherOverlay/res/drawable/ic_widget.xml
index ca09fc9..df3a9fd 100644
--- a/packages/overlays/IconPackRoundedLauncherOverlay/res/drawable/ic_widget.xml
+++ b/packages/overlays/IconPackRoundedLauncherOverlay/res/drawable/ic_widget.xml
@@ -16,19 +16,19 @@
-->
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:height="24dp"
- android:viewportHeight="24"
+ android:viewportHeight="24" android:tint="?android:attr/textColorPrimary"
android:viewportWidth="24"
android:width="24dp" >
<path
- android:fillColor="#000000"
- android:pathData="M17.7,2.3c-0.4-0.4-1-0.4-1.4,0l-4,4c-0.4,0.4-0.4,1,0,1.4l4,4c0.4,0.4,1,0.4,1.4,0l4-4c0.4-0.4,0.4-1,0-1.4L17.7,2.3z" />
+ android:fillColor="@android:color/white"
+ android:pathData="M10,3H4C3.45,3,3,3.45,3,4v6c0,0.55,0.45,1,1,1h6c0.55,0,1-0.45,1-1V4C11,3.45,10.55,3,10,3z M9.5,9.5h-5v-5h5V9.5z" />
<path
- android:fillColor="#000000"
- android:pathData="M11,4c0-0.5-0.4-1-1-1H4C3.5,3,3,3.5,3,4v6c0,0.6,0.5,1,1,1h6c0.6,0,1-0.4,1-1V4z" />
+ android:fillColor="@android:color/white"
+ android:pathData="M10,13H4c-0.55,0-1,0.45-1,1v6c0,0.55,0.45,1,1,1h6c0.55,0,1-0.45,1-1v-6C11,13.45,10.55,13,10,13z M9.5,19.5h-5v-5h5 V19.5z" />
<path
- android:fillColor="#000000"
- android:pathData="M20,21c0.5,0,1-0.5,1-1v-6c0-0.6-0.5-1-1-1h-6c-0.6,0-1,0.4-1,1v6c0,0.5,0.4,1,1,1H20z" />
+ android:fillColor="@android:color/white"
+ android:pathData="M20,13h-6c-0.55,0-1,0.45-1,1v6c0,0.55,0.45,1,1,1h6c0.55,0,1-0.45,1-1v-6C21,13.45,20.55,13,20,13z M19.5,19.5h-5v-5h5 V19.5z" />
<path
- android:fillColor="#000000"
- android:pathData="M10,13H4c-0.5,0-1,0.4-1,1v6c0,0.5,0.5,1,1,1h6c0.6,0,1-0.5,1-1v-6C11,13.4,10.6,13,10,13z" />
+ android:fillColor="@android:color/white"
+ android:pathData="M21.95,6.29l-4.24-4.24c-0.2-0.2-0.45-0.29-0.71-0.29s-0.51,0.1-0.71,0.29l-4.24,4.24c-0.39,0.39-0.39,1.02,0,1.41 l4.24,4.24c0.2,0.2,0.45,0.29,0.71,0.29s0.51-0.1,0.71-0.29l4.24-4.24C22.34,7.32,22.34,6.68,21.95,6.29z M17,10.54L13.46,7 L17,3.46L20.54,7L17,10.54z" />
</vector>
\ No newline at end of file
diff --git a/services/core/java/com/android/server/DeviceIdleController.java b/services/core/java/com/android/server/DeviceIdleController.java
index 833faa6..52a4218 100644
--- a/services/core/java/com/android/server/DeviceIdleController.java
+++ b/services/core/java/com/android/server/DeviceIdleController.java
@@ -1399,8 +1399,8 @@
} break;
case MSG_TEMP_APP_WHITELIST_TIMEOUT: {
// TODO: What is keeping the device awake at this point? Does it need to be?
- int uid = msg.arg1;
- checkTempAppWhitelistTimeout(uid);
+ int appId = msg.arg1;
+ checkTempAppWhitelistTimeout(appId);
} break;
case MSG_REPORT_MAINTENANCE_ACTIVITY: {
// TODO: What is keeping the device awake at this point? Does it need to be?
@@ -1656,9 +1656,9 @@
}
// duration in milliseconds
- public void addPowerSaveTempWhitelistAppDirect(int appId, long duration, boolean sync,
+ public void addPowerSaveTempWhitelistAppDirect(int uid, long duration, boolean sync,
String reason) {
- addPowerSaveTempWhitelistAppDirectInternal(0, appId, duration, sync, reason);
+ addPowerSaveTempWhitelistAppDirectInternal(0, uid, duration, sync, reason);
}
// duration in milliseconds
@@ -2357,8 +2357,7 @@
long duration, int userId, boolean sync, String reason) {
try {
int uid = getContext().getPackageManager().getPackageUidAsUser(packageName, userId);
- int appId = UserHandle.getAppId(uid);
- addPowerSaveTempWhitelistAppDirectInternal(callingUid, appId, duration, sync, reason);
+ addPowerSaveTempWhitelistAppDirectInternal(callingUid, uid, duration, sync, reason);
} catch (NameNotFoundException e) {
}
}
@@ -2367,10 +2366,11 @@
* Adds an app to the temporary whitelist and resets the endTime for granting the
* app an exemption to access network and acquire wakelocks.
*/
- void addPowerSaveTempWhitelistAppDirectInternal(int callingUid, int appId,
+ void addPowerSaveTempWhitelistAppDirectInternal(int callingUid, int uid,
long duration, boolean sync, String reason) {
final long timeNow = SystemClock.elapsedRealtime();
boolean informWhitelistChanged = false;
+ int appId = UserHandle.getAppId(uid);
synchronized (this) {
int callingAppId = UserHandle.getAppId(callingUid);
if (callingAppId >= Process.FIRST_APPLICATION_UID) {
@@ -2395,7 +2395,7 @@
// No pending timeout for the app id, post a delayed message
try {
mBatteryStats.noteEvent(BatteryStats.HistoryItem.EVENT_TEMP_WHITELIST_START,
- reason, appId);
+ reason, uid);
} catch (RemoteException e) {
}
postTempActiveTimeoutMessage(appId, duration);
@@ -2440,34 +2440,34 @@
}
}
- private void postTempActiveTimeoutMessage(int uid, long delay) {
+ private void postTempActiveTimeoutMessage(int appId, long delay) {
if (DEBUG) {
- Slog.d(TAG, "postTempActiveTimeoutMessage: uid=" + uid + ", delay=" + delay);
+ Slog.d(TAG, "postTempActiveTimeoutMessage: appId=" + appId + ", delay=" + delay);
}
- mHandler.sendMessageDelayed(mHandler.obtainMessage(MSG_TEMP_APP_WHITELIST_TIMEOUT, uid, 0),
- delay);
+ mHandler.sendMessageDelayed(
+ mHandler.obtainMessage(MSG_TEMP_APP_WHITELIST_TIMEOUT, appId, 0), delay);
}
- void checkTempAppWhitelistTimeout(int uid) {
+ void checkTempAppWhitelistTimeout(int appId) {
final long timeNow = SystemClock.elapsedRealtime();
if (DEBUG) {
- Slog.d(TAG, "checkTempAppWhitelistTimeout: uid=" + uid + ", timeNow=" + timeNow);
+ Slog.d(TAG, "checkTempAppWhitelistTimeout: appId=" + appId + ", timeNow=" + timeNow);
}
synchronized (this) {
- Pair<MutableLong, String> entry = mTempWhitelistAppIdEndTimes.get(uid);
+ Pair<MutableLong, String> entry = mTempWhitelistAppIdEndTimes.get(appId);
if (entry == null) {
// Nothing to do
return;
}
if (timeNow >= entry.first.value) {
- mTempWhitelistAppIdEndTimes.delete(uid);
- onAppRemovedFromTempWhitelistLocked(uid, entry.second);
+ mTempWhitelistAppIdEndTimes.delete(appId);
+ onAppRemovedFromTempWhitelistLocked(appId, entry.second);
} else {
// Need more time
if (DEBUG) {
- Slog.d(TAG, "Time to remove UID " + uid + ": " + entry.first.value);
+ Slog.d(TAG, "Time to remove AppId " + appId + ": " + entry.first.value);
}
- postTempActiveTimeoutMessage(uid, entry.first.value - timeNow);
+ postTempActiveTimeoutMessage(appId, entry.first.value - timeNow);
}
}
}
diff --git a/services/core/java/com/android/server/DynamicSystemService.java b/services/core/java/com/android/server/DynamicSystemService.java
index f1882c5..9d979a6 100644
--- a/services/core/java/com/android/server/DynamicSystemService.java
+++ b/services/core/java/com/android/server/DynamicSystemService.java
@@ -18,16 +18,23 @@
import android.content.Context;
import android.content.pm.PackageManager;
+import android.gsi.GsiInstallParams;
import android.gsi.GsiProgress;
import android.gsi.IGsiService;
+import android.os.Environment;
import android.os.IBinder;
import android.os.IBinder.DeathRecipient;
import android.os.RemoteException;
import android.os.ServiceManager;
import android.os.SystemProperties;
+import android.os.UserHandle;
import android.os.image.IDynamicSystemService;
+import android.os.storage.StorageManager;
+import android.os.storage.StorageVolume;
import android.util.Slog;
+import java.io.File;
+
/**
* DynamicSystemService implements IDynamicSystemService. It provides permission check before
* passing requests to gsid
@@ -36,7 +43,7 @@
private static final String TAG = "DynamicSystemService";
private static final String NO_SERVICE_ERROR = "no gsiservice";
private static final int GSID_ROUGH_TIMEOUT_MS = 8192;
-
+ private static final String PATH_DEFAULT = "/data/gsi";
private Context mContext;
private volatile IGsiService mGsiService;
@@ -105,7 +112,32 @@
@Override
public boolean startInstallation(long systemSize, long userdataSize) throws RemoteException {
- return getGsiService().startGsiInstall(systemSize, userdataSize, true) == 0;
+ // priority from high to low: sysprop -> sdcard -> /data
+ String path = SystemProperties.get("os.aot.path");
+ if (path.isEmpty()) {
+ final int userId = UserHandle.myUserId();
+ final StorageVolume[] volumes =
+ StorageManager.getVolumeList(userId, StorageManager.FLAG_FOR_WRITE);
+ for (StorageVolume volume : volumes) {
+ if (volume.isEmulated()) continue;
+ if (!volume.isRemovable()) continue;
+ if (!Environment.MEDIA_MOUNTED.equals(volume.getState())) continue;
+ File sdCard = volume.getPathFile();
+ if (sdCard.isDirectory()) {
+ path = sdCard.getPath();
+ break;
+ }
+ }
+ if (path.isEmpty()) {
+ path = PATH_DEFAULT;
+ }
+ Slog.i(TAG, "startInstallation -> " + path);
+ }
+ GsiInstallParams installParams = new GsiInstallParams();
+ installParams.installDir = path;
+ installParams.gsiSize = systemSize;
+ installParams.userdataSize = userdataSize;
+ return getGsiService().beginGsiInstall(installParams) == 0;
}
@Override
diff --git a/services/core/java/com/android/server/StorageManagerService.java b/services/core/java/com/android/server/StorageManagerService.java
index da9cffa..382fdec 100644
--- a/services/core/java/com/android/server/StorageManagerService.java
+++ b/services/core/java/com/android/server/StorageManagerService.java
@@ -1693,9 +1693,6 @@
// Always remember the new state we just booted with
writeSettingsLocked();
}
-
- // Execute special logic to recover certain devices
- recoverFrom128872367();
}
}
@@ -1756,69 +1753,6 @@
return maxTime;
}
- /**
- * In b/128872367 we lost all app-ops on devices in the wild. This logic
- * attempts to detect and recover from this by granting
- * {@link AppOpsManager#OP_LEGACY_STORAGE} to any apps installed before
- * isolated storage was enabled.
- */
- private void recoverFrom128872367() {
- // We're interested in packages that were installed or updated between
- // 1/1/2014 and 12/17/2018
- final long START_TIMESTAMP = 1388534400000L;
- final long END_TIMESTAMP = 1545004800000L;
-
- final PackageManager pm = mContext.getPackageManager();
- final AppOpsManager appOps = mContext.getSystemService(AppOpsManager.class);
- final UserManagerInternal um = LocalServices.getService(UserManagerInternal.class);
-
- boolean activeDuringWindow = false;
- List<PackageInfo> pendingHolders = new ArrayList<>();
-
- for (int userId : um.getUserIds()) {
- final List<PackageInfo> pkgs = pm.getInstalledPackagesAsUser(MATCH_UNINSTALLED_PACKAGES
- | MATCH_DIRECT_BOOT_AWARE | MATCH_DIRECT_BOOT_UNAWARE, userId);
- for (PackageInfo pkg : pkgs) {
- // Determine if any apps on this device had been installed or
- // updated during the period where the feature was disabled
- activeDuringWindow |= (pkg.firstInstallTime > START_TIMESTAMP
- && pkg.firstInstallTime < END_TIMESTAMP);
- activeDuringWindow |= (pkg.lastUpdateTime > START_TIMESTAMP
- && pkg.lastUpdateTime < END_TIMESTAMP);
-
- // This app should hold legacy op if they were installed before
- // the cutoff; we only check the end boundary here so that
- // include system apps, which are always installed on 1/1/2009.
- final boolean shouldHold = (pkg.firstInstallTime < END_TIMESTAMP);
- final boolean doesHold = (appOps.checkOpNoThrow(OP_LEGACY_STORAGE,
- pkg.applicationInfo.uid,
- pkg.applicationInfo.packageName) == MODE_ALLOWED);
-
- if (doesHold) {
- Slog.d(TAG, "Found " + pkg + " holding legacy op; skipping recovery");
- return;
- } else if (shouldHold) {
- Slog.d(TAG, "Found " + pkg + " that should hold legacy op");
- pendingHolders.add(pkg);
- }
- }
- }
-
- if (!activeDuringWindow) {
- Slog.d(TAG, "No packages were active during the time window; skipping grants");
- return;
- }
-
- // If we made it this far, nobody actually holds the legacy op, which
- // means we probably lost the database, and we should grant the op to
- // all the apps we identified.
- for (PackageInfo pkg : pendingHolders) {
- appOps.setMode(AppOpsManager.OP_LEGACY_STORAGE,
- pkg.applicationInfo.uid,
- pkg.applicationInfo.packageName, AppOpsManager.MODE_ALLOWED);
- }
- }
-
private void systemReady() {
LocalServices.getService(ActivityTaskManagerInternal.class)
.registerScreenObserver(this);
diff --git a/services/core/java/com/android/server/ThreadPriorityBooster.java b/services/core/java/com/android/server/ThreadPriorityBooster.java
index f74a4385..dab6bc4 100644
--- a/services/core/java/com/android/server/ThreadPriorityBooster.java
+++ b/services/core/java/com/android/server/ThreadPriorityBooster.java
@@ -26,6 +26,7 @@
public class ThreadPriorityBooster {
private static final boolean ENABLE_LOCK_GUARD = false;
+ private static final int PRIORITY_NOT_ADJUSTED = Integer.MAX_VALUE;
private volatile int mBoostToPriority;
private final int mLockGuardIndex;
@@ -42,13 +43,12 @@
}
public void boost() {
- final int tid = myTid();
final PriorityState state = mThreadState.get();
if (state.regionCounter == 0) {
- final int prevPriority = getThreadPriority(tid);
- state.prevPriority = prevPriority;
+ final int prevPriority = getThreadPriority(state.tid);
if (prevPriority > mBoostToPriority) {
- setThreadPriority(tid, mBoostToPriority);
+ setThreadPriority(state.tid, mBoostToPriority);
+ state.prevPriority = prevPriority;
}
}
state.regionCounter++;
@@ -60,11 +60,9 @@
public void reset() {
final PriorityState state = mThreadState.get();
state.regionCounter--;
- if (state.regionCounter == 0) {
- final int currentPriority = getThreadPriority(myTid());
- if (state.prevPriority != currentPriority) {
- setThreadPriority(myTid(), state.prevPriority);
- }
+ if (state.regionCounter == 0 && state.prevPriority != PRIORITY_NOT_ADJUSTED) {
+ setThreadPriority(state.tid, state.prevPriority);
+ state.prevPriority = PRIORITY_NOT_ADJUSTED;
}
}
@@ -78,16 +76,16 @@
// variable immediately.
mBoostToPriority = priority;
final PriorityState state = mThreadState.get();
- final int tid = myTid();
if (state.regionCounter != 0) {
- final int prevPriority = getThreadPriority(tid);
+ final int prevPriority = getThreadPriority(state.tid);
if (prevPriority != priority) {
- setThreadPriority(tid, priority);
+ setThreadPriority(state.tid, priority);
}
}
}
private static class PriorityState {
+ final int tid = myTid();
/**
* Acts as counter for number of synchronized region that needs to acquire 'this' as a lock
@@ -99,6 +97,6 @@
/**
* The thread's previous priority before boosting.
*/
- int prevPriority;
+ int prevPriority = PRIORITY_NOT_ADJUSTED;
}
-}
\ No newline at end of file
+}
diff --git a/services/core/java/com/android/server/am/ActiveServices.java b/services/core/java/com/android/server/am/ActiveServices.java
index f0982d3..4ec90ba 100644
--- a/services/core/java/com/android/server/am/ActiveServices.java
+++ b/services/core/java/com/android/server/am/ActiveServices.java
@@ -2117,6 +2117,12 @@
Slog.w(TAG, "Service lookup failed: " + msg);
return new ServiceLookupResult(null, msg);
}
+
+ // Store the defining packageName and uid, as they might be changed in
+ // the ApplicationInfo for external services (which run with the package name
+ // and uid of the caller).
+ String definingPackageName = sInfo.applicationInfo.packageName;
+ int definingUid = sInfo.applicationInfo.uid;
if ((sInfo.flags & ServiceInfo.FLAG_EXTERNAL_SERVICE) != 0) {
if (isBindExternal) {
if (!sInfo.exported) {
@@ -2175,8 +2181,8 @@
sInfo.applicationInfo.uid, name.getPackageName(),
name.getClassName());
}
- r = new ServiceRecord(mAm, ss, className, name, filter, sInfo,
- callingFromFg, res);
+ r = new ServiceRecord(mAm, ss, className, name, definingPackageName,
+ definingUid, filter, sInfo, callingFromFg, res);
res.setService(r);
smap.mServicesByInstanceName.put(name, r);
smap.mServicesByIntent.put(filter, r);
@@ -2557,7 +2563,7 @@
final boolean isolated = (r.serviceInfo.flags&ServiceInfo.FLAG_ISOLATED_PROCESS) != 0;
final String procName = r.processName;
- String hostingType = "service";
+ HostingRecord hostingRecord = new HostingRecord("service", r.instanceName);
ProcessRecord app;
if (!isolated) {
@@ -2588,10 +2594,11 @@
app = r.isolatedProc;
if (WebViewZygote.isMultiprocessEnabled()
&& r.serviceInfo.packageName.equals(WebViewZygote.getPackageName())) {
- hostingType = "webview_service";
+ hostingRecord = HostingRecord.byWebviewZygote(r.instanceName);
}
if ((r.serviceInfo.flags & ServiceInfo.FLAG_USE_APP_ZYGOTE) != 0) {
- hostingType = "app_zygote";
+ hostingRecord = HostingRecord.byAppZygote(r.instanceName, r.definingPackageName,
+ r.definingUid);
}
}
@@ -2599,7 +2606,7 @@
// to be executed when the app comes up.
if (app == null && !permissionsReviewRequired) {
if ((app=mAm.startProcessLocked(procName, r.appInfo, true, intentFlags,
- hostingType, r.instanceName, false, isolated, false)) == null) {
+ hostingRecord, false, isolated, false)) == null) {
String msg = "Unable to launch app "
+ r.appInfo.packageName + "/"
+ r.appInfo.uid + " for service "
diff --git a/services/core/java/com/android/server/am/ActivityManagerService.java b/services/core/java/com/android/server/am/ActivityManagerService.java
index 0b9e3bb..3b6b404 100644
--- a/services/core/java/com/android/server/am/ActivityManagerService.java
+++ b/services/core/java/com/android/server/am/ActivityManagerService.java
@@ -1498,6 +1498,7 @@
private ParcelFileDescriptor[] mLifeMonitorFds;
+ static final HostingRecord sNullHostingRecord = new HostingRecord(null);
/**
* Used to notify activity lifecycle events.
*/
@@ -1963,7 +1964,7 @@
ProcessRecord app = mProcessList.newProcessRecordLocked(info, info.processName,
false,
0,
- false);
+ new HostingRecord("system"));
app.setPersistent(true);
app.pid = MY_PID;
app.getWindowProcessController().setPid(MY_PID);
@@ -2894,8 +2895,9 @@
info.seInfoUser = SELinuxUtil.COMPLETE_STR;
info.targetSdkVersion = Build.VERSION.SDK_INT;
ProcessRecord proc = mProcessList.startProcessLocked(processName, info /* info */,
- false /* knownToBeDead */, 0 /* intentFlags */, "" /* hostingType */,
- null /* hostingName */, true /* allowWhileBooting */, true /* isolated */,
+ false /* knownToBeDead */, 0 /* intentFlags */,
+ sNullHostingRecord /* hostingRecord */,
+ true /* allowWhileBooting */, true /* isolated */,
uid, true /* keepIfLarge */, abiOverride, entryPoint, entryPointArgs,
crashHandler);
return proc != null;
@@ -2905,11 +2907,10 @@
@GuardedBy("this")
final ProcessRecord startProcessLocked(String processName,
ApplicationInfo info, boolean knownToBeDead, int intentFlags,
- String hostingType, ComponentName hostingName, boolean allowWhileBooting,
+ HostingRecord hostingRecord, boolean allowWhileBooting,
boolean isolated, boolean keepIfLarge) {
return mProcessList.startProcessLocked(processName, info, knownToBeDead, intentFlags,
- hostingType,
- hostingName, allowWhileBooting, isolated, 0 /* isolatedUid */, keepIfLarge,
+ hostingRecord, allowWhileBooting, isolated, 0 /* isolatedUid */, keepIfLarge,
null /* ABI override */, null /* entryPoint */, null /* entryPointArgs */,
null /* crashHandler */);
}
@@ -4692,7 +4693,8 @@
app.deathRecipient = adr;
} catch (RemoteException e) {
app.resetPackageList(mProcessStats);
- mProcessList.startProcessLocked(app, "link fail", processName);
+ mProcessList.startProcessLocked(app,
+ new HostingRecord("link fail", processName));
return false;
}
@@ -4931,7 +4933,7 @@
app.resetPackageList(mProcessStats);
app.unlinkDeathRecipient();
- mProcessList.startProcessLocked(app, "bind fail", processName);
+ mProcessList.startProcessLocked(app, new HostingRecord("bind-fail", processName));
return false;
}
@@ -5013,8 +5015,8 @@
app.startTime,
(int) (bindApplicationTimeMillis - app.startTime),
(int) (SystemClock.elapsedRealtime() - app.startTime),
- app.hostingType,
- (app.hostingNameStr != null ? app.hostingNameStr : ""));
+ app.hostingRecord.getType(),
+ (app.hostingRecord.getName() != null ? app.hostingRecord.getName() : ""));
return true;
}
@@ -5123,7 +5125,7 @@
for (int ip=0; ip<NP; ip++) {
if (DEBUG_PROCESSES) Slog.v(TAG_PROCESSES, "Starting process on hold: "
+ procs.get(ip));
- mProcessList.startProcessLocked(procs.get(ip), "on-hold", null);
+ mProcessList.startProcessLocked(procs.get(ip), new HostingRecord("on-hold"));
}
}
if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL) {
@@ -6915,9 +6917,10 @@
} else {
checkTime(startTime, "getContentProviderImpl: before start process");
proc = startProcessLocked(cpi.processName,
- cpr.appInfo, false, 0, "content provider",
+ cpr.appInfo, false, 0,
+ new HostingRecord("content provider",
new ComponentName(cpi.applicationInfo.packageName,
- cpi.name), false, false, false);
+ cpi.name)), false, false, false);
checkTime(startTime, "getContentProviderImpl: after start process");
if (proc == null) {
Slog.w(TAG, "Unable to launch app "
@@ -7638,7 +7641,9 @@
}
if (app == null) {
- app = mProcessList.newProcessRecordLocked(info, customProcess, isolated, 0, false);
+ app = mProcessList.newProcessRecordLocked(info, customProcess, isolated, 0,
+ new HostingRecord("added application",
+ customProcess != null ? customProcess : info.processName));
mProcessList.updateLruProcessLocked(app, false, null);
updateOomAdjLocked();
}
@@ -7659,9 +7664,9 @@
}
if (app.thread == null && mPersistentStartingProcesses.indexOf(app) < 0) {
mPersistentStartingProcesses.add(app);
- mProcessList.startProcessLocked(app, "added application",
- customProcess != null ? customProcess : app.processName, disableHiddenApiChecks,
- mountExtStorageFull, abiOverride);
+ mProcessList.startProcessLocked(app, new HostingRecord("added application",
+ customProcess != null ? customProcess : app.processName),
+ disableHiddenApiChecks, mountExtStorageFull, abiOverride);
}
return app;
@@ -13611,7 +13616,8 @@
}
mProcessList.addProcessNameLocked(app);
app.pendingStart = false;
- mProcessList.startProcessLocked(app, "restart", app.processName);
+ mProcessList.startProcessLocked(app,
+ new HostingRecord("restart", app.processName));
return true;
} else if (app.pid > 0 && app.pid != MY_PID) {
// Goodbye!
@@ -13952,9 +13958,12 @@
(backupMode == ApplicationThreadConstants.BACKUP_MODE_INCREMENTAL)
? new ComponentName(app.packageName, app.backupAgentName)
: new ComponentName("android", "FullBackupAgent");
+
// startProcessLocked() returns existing proc's record if it's already running
ProcessRecord proc = startProcessLocked(app.processName, app,
- false, 0, "backup", hostingName, false, false, false);
+ false, 0,
+ new HostingRecord("backup", hostingName),
+ false, false, false);
if (proc == null) {
Slog.e(TAG, "Unable to start backup agent process " + r);
return false;
@@ -18163,8 +18172,9 @@
}
synchronized (ActivityManagerService.this) {
startProcessLocked(processName, info, knownToBeDead, 0 /* intentFlags */,
- hostingType, hostingName, false /* allowWhileBooting */,
- false /* isolated */, true /* keepIfLarge */);
+ new HostingRecord(hostingType, hostingName),
+ false /* allowWhileBooting */, false /* isolated */,
+ true /* keepIfLarge */);
}
} finally {
Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
diff --git a/services/core/java/com/android/server/am/ActivityManagerShellCommand.java b/services/core/java/com/android/server/am/ActivityManagerShellCommand.java
index d1379b6..cba9674 100644
--- a/services/core/java/com/android/server/am/ActivityManagerShellCommand.java
+++ b/services/core/java/com/android/server/am/ActivityManagerShellCommand.java
@@ -826,7 +826,7 @@
return -1;
}
}
- process = getNextArg();
+ process = getNextArgRequired();
} else {
// Compatibility with old syntax: process is specified first.
process = cmd;
@@ -2998,15 +2998,22 @@
pw.println(" start: start tracing IPC transactions.");
pw.println(" stop: stop tracing IPC transactions and dump the results to file.");
pw.println(" --dump-file <FILE>: Specify the file the trace should be dumped to.");
- pw.println(" profile [start|stop] [--user <USER_ID> current] [--sampling INTERVAL]");
- pw.println(" [--streaming] <PROCESS> <FILE>");
- pw.println(" Start and stop profiler on a process. The given <PROCESS> argument");
+ pw.println(" profile start [--user <USER_ID> current]");
+ pw.println(" [--sampling INTERVAL | --streaming] <PROCESS> <FILE>");
+ pw.println(" Start profiler on a process. The given <PROCESS> argument");
pw.println(" may be either a process name or pid. Options are:");
pw.println(" --user <USER_ID> | current: When supplying a process name,");
- pw.println(" specify user of process to profile; uses current user if not specified.");
+ pw.println(" specify user of process to profile; uses current user if not");
+ pw.println(" specified.");
pw.println(" --sampling INTERVAL: use sample profiling with INTERVAL microseconds");
- pw.println(" between samples");
- pw.println(" --streaming: stream the profiling output to the specified file");
+ pw.println(" between samples.");
+ pw.println(" --streaming: stream the profiling output to the specified file.");
+ pw.println(" profile stop [--user <USER_ID> current] <PROCESS>");
+ pw.println(" Stop profiler on a process. The given <PROCESS> argument");
+ pw.println(" may be either a process name or pid. Options are:");
+ pw.println(" --user <USER_ID> | current: When supplying a process name,");
+ pw.println(" specify user of process to profile; uses current user if not");
+ pw.println(" specified.");
pw.println(" dumpheap [--user <USER_ID> current] [-n] [-g] <PROCESS> <FILE>");
pw.println(" Dump the heap of a process. The given <PROCESS> argument may");
pw.println(" be either a process name or pid. Options are:");
diff --git a/services/core/java/com/android/server/am/BroadcastQueue.java b/services/core/java/com/android/server/am/BroadcastQueue.java
index 4bfbb78..3c57c3b 100644
--- a/services/core/java/com/android/server/am/BroadcastQueue.java
+++ b/services/core/java/com/android/server/am/BroadcastQueue.java
@@ -1623,7 +1623,7 @@
if ((r.curApp=mService.startProcessLocked(targetProcess,
info.activityInfo.applicationInfo, true,
r.intent.getFlags() | Intent.FLAG_FROM_BACKGROUND,
- "broadcast", r.curComponent,
+ new HostingRecord("broadcast", r.curComponent),
(r.intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0, false, false))
== null) {
// Ah, this recipient is unavailable. Finish it if necessary,
diff --git a/services/core/java/com/android/server/am/HostingRecord.java b/services/core/java/com/android/server/am/HostingRecord.java
new file mode 100644
index 0000000..784dde1
--- /dev/null
+++ b/services/core/java/com/android/server/am/HostingRecord.java
@@ -0,0 +1,149 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.server.am;
+
+import android.content.ComponentName;
+
+/**
+ * This class describes various information required to start a process.
+ *
+ * The {@code mHostingType} field describes the reason why we started a process, and
+ * is only used for logging and stats.
+ *
+ * The {@code mHostingName} field describes the Component for which we are starting the
+ * process, and is only used for logging and stats.
+ *
+ * The {@code mHostingZygote} field describes from which Zygote the new process should be spawned.
+ *
+ * {@code mDefiningPackageName} contains the packageName of the package that defines the
+ * component we want to start; this can be different from the packageName and uid in the
+ * ApplicationInfo that we're creating the process with, in case the service is a
+ * {@link android.content.Context#BIND_EXTERNAL_SERVICE} service. In that case, the packageName
+ * and uid in the ApplicationInfo will be set to those of the caller, not of the defining package.
+ *
+ * {@code mDefiningUid} contains the uid of the application that defines the component we want to
+ * start; this can be different from the packageName and uid in the ApplicationInfo that we're
+ * creating the process with, in case the service is a
+ * {@link android.content.Context#BIND_EXTERNAL_SERVICE} service. In that case, the packageName
+ * and uid in the ApplicationInfo will be set to those of the caller, not of the defining package.
+ *
+ */
+
+public final class HostingRecord {
+ private static final int REGULAR_ZYGOTE = 0;
+ private static final int WEBVIEW_ZYGOTE = 1;
+ private static final int APP_ZYGOTE = 2;
+
+ private final String mHostingType;
+ private final String mHostingName;
+ private final int mHostingZygote;
+ private final String mDefiningPackageName;
+ private final int mDefiningUid;
+
+ public HostingRecord(String hostingType) {
+ this(hostingType, null, REGULAR_ZYGOTE, null, -1);
+ }
+
+ public HostingRecord(String hostingType, ComponentName hostingName) {
+ this(hostingType, hostingName, REGULAR_ZYGOTE);
+ }
+
+ public HostingRecord(String hostingType, String hostingName) {
+ this(hostingType, hostingName, REGULAR_ZYGOTE);
+ }
+
+ private HostingRecord(String hostingType, ComponentName hostingName, int hostingZygote) {
+ this(hostingType, hostingName.toShortString(), hostingZygote);
+ }
+
+ private HostingRecord(String hostingType, String hostingName, int hostingZygote) {
+ this(hostingType, hostingName, hostingZygote, null, -1);
+ }
+
+ private HostingRecord(String hostingType, String hostingName, int hostingZygote,
+ String definingPackageName, int definingUid) {
+ mHostingType = hostingType;
+ mHostingName = hostingName;
+ mHostingZygote = hostingZygote;
+ mDefiningPackageName = definingPackageName;
+ mDefiningUid = definingUid;
+ }
+
+ public String getType() {
+ return mHostingType;
+ }
+
+ public String getName() {
+ return mHostingName;
+ }
+
+ /**
+ * Returns the UID of the package defining the component we want to start. Only valid
+ * when {@link #usesAppZygote()} returns true.
+ *
+ * @return the UID of the hosting application
+ */
+ public int getDefiningUid() {
+ return mDefiningUid;
+ }
+
+ /**
+ * Returns the packageName of the package defining the component we want to start. Only valid
+ * when {@link #usesAppZygote()} returns true.
+ *
+ * @return the packageName of the hosting application
+ */
+ public String getDefiningPackageName() {
+ return mDefiningPackageName;
+ }
+
+ /**
+ * Creates a HostingRecord for a process that must spawn from the webview zygote
+ * @param hostingName name of the component to be hosted in this process
+ * @return The constructed HostingRecord
+ */
+ public static HostingRecord byWebviewZygote(ComponentName hostingName) {
+ return new HostingRecord("", hostingName.toShortString(), WEBVIEW_ZYGOTE);
+ }
+
+ /**
+ * Creates a HostingRecord for a process that must spawn from the application zygote
+ * @param hostingName name of the component to be hosted in this process
+ * @param definingPackageName name of the package defining the service
+ * @param definingUid uid of the package defining the service
+ * @return The constructed HostingRecord
+ */
+ public static HostingRecord byAppZygote(ComponentName hostingName, String definingPackageName,
+ int definingUid) {
+ return new HostingRecord("", hostingName.toShortString(), APP_ZYGOTE,
+ definingPackageName, definingUid);
+ }
+
+ /**
+ * @return whether the process should spawn from the application zygote
+ */
+ public boolean usesAppZygote() {
+ return mHostingZygote == APP_ZYGOTE;
+ }
+
+ /**
+ * @return whether the process should spawn from the webview zygote
+ */
+ public boolean usesWebviewZygote() {
+ return mHostingZygote == WEBVIEW_ZYGOTE;
+ }
+}
diff --git a/services/core/java/com/android/server/am/ProcessList.java b/services/core/java/com/android/server/am/ProcessList.java
index 9780a7f..0a926f9 100644
--- a/services/core/java/com/android/server/am/ProcessList.java
+++ b/services/core/java/com/android/server/am/ProcessList.java
@@ -454,13 +454,13 @@
}
@GuardedBy("ProcessList.this.mService")
- IsolatedUidRange getIsolatedUidRangeLocked(ApplicationInfo info) {
- return mAppRanges.get(info.processName, info.uid);
+ IsolatedUidRange getIsolatedUidRangeLocked(String processName, int uid) {
+ return mAppRanges.get(processName, uid);
}
@GuardedBy("ProcessList.this.mService")
- IsolatedUidRange getOrCreateIsolatedUidRangeLocked(ApplicationInfo info) {
- IsolatedUidRange range = getIsolatedUidRangeLocked(info);
+ IsolatedUidRange getOrCreateIsolatedUidRangeLocked(String processName, int uid) {
+ IsolatedUidRange range = getIsolatedUidRangeLocked(processName, uid);
if (range == null) {
int uidRangeIndex = mAvailableUidRanges.nextSetBit(0);
if (uidRangeIndex < 0) {
@@ -470,7 +470,7 @@
mAvailableUidRanges.clear(uidRangeIndex);
int actualUid = mFirstUid + uidRangeIndex * mNumUidsPerRange;
range = new IsolatedUidRange(actualUid, actualUid + mNumUidsPerRange - 1);
- mAppRanges.put(info.processName, info.uid, range);
+ mAppRanges.put(processName, uid, range);
}
return range;
}
@@ -1427,14 +1427,13 @@
/**
* @return {@code true} if process start is successful, false otherwise.
* @param app
- * @param hostingType
- * @param hostingNameStr
+ * @param hostingRecord
* @param disableHiddenApiChecks
* @param abiOverride
*/
@GuardedBy("mService")
- boolean startProcessLocked(ProcessRecord app, String hostingType,
- String hostingNameStr, boolean disableHiddenApiChecks, boolean mountExtStorageFull,
+ boolean startProcessLocked(ProcessRecord app, HostingRecord hostingRecord,
+ boolean disableHiddenApiChecks, boolean mountExtStorageFull,
String abiOverride) {
if (app.pendingStart) {
return true;
@@ -1625,7 +1624,7 @@
// the PID of the new process, or else throw a RuntimeException.
final String entryPoint = "android.app.ActivityThread";
- return startProcessLocked(hostingType, hostingNameStr, entryPoint, app, uid, gids,
+ return startProcessLocked(hostingRecord, entryPoint, app, uid, gids,
runtimeFlags, mountExternal, seInfo, requiredAbi, instructionSet, invokeWith,
startTime);
} catch (RuntimeException e) {
@@ -1644,7 +1643,7 @@
}
@GuardedBy("mService")
- boolean startProcessLocked(String hostingType, String hostingNameStr,
+ boolean startProcessLocked(HostingRecord hostingRecord,
String entryPoint,
ProcessRecord app, int uid, int[] gids, int runtimeFlags, int mountExternal,
String seInfo, String requiredAbi, String instructionSet, String invokeWith,
@@ -1654,7 +1653,7 @@
app.removed = false;
app.killed = false;
final long startSeq = app.startSeq = ++mProcStartSeqCounter;
- app.setStartParams(uid, hostingType, hostingNameStr, seInfo, startTime);
+ app.setStartParams(uid, hostingRecord, seInfo, startTime);
if (mService.mConstants.FLAG_PROCESS_START_ASYNC) {
if (DEBUG_PROCESSES) Slog.i(TAG_PROCESSES,
"Posting procStart msg for " + app.toShortString());
@@ -1672,7 +1671,7 @@
|| SystemProperties.get("wrap." + app.processName) != null);
mPendingStarts.put(startSeq, app);
}
- final Process.ProcessStartResult startResult = startProcess(app.hostingType,
+ final Process.ProcessStartResult startResult = startProcess(app.hostingRecord,
entryPoint, app, app.startUid, gids, runtimeFlags, mountExternal,
app.seInfo, requiredAbi, instructionSet, invokeWith, app.startTime);
synchronized (mService) {
@@ -1693,7 +1692,7 @@
return true;
} else {
try {
- final Process.ProcessStartResult startResult = startProcess(hostingType,
+ final Process.ProcessStartResult startResult = startProcess(hostingRecord,
entryPoint, app,
uid, gids, runtimeFlags, mountExternal, seInfo, requiredAbi, instructionSet,
invokeWith, startTime);
@@ -1727,12 +1726,14 @@
private void removeProcessFromAppZygoteLocked(final ProcessRecord app) {
// Free the isolated uid for this process
final IsolatedUidRange appUidRange =
- mAppIsolatedUidRangeAllocator.getIsolatedUidRangeLocked(app.info);
+ mAppIsolatedUidRangeAllocator.getIsolatedUidRangeLocked(app.info.processName,
+ app.hostingRecord.getDefiningUid());
if (appUidRange != null) {
appUidRange.freeIsolatedUidLocked(app.uid);
}
- final AppZygote appZygote = mAppZygotes.get(app.info.processName, app.info.uid);
+ final AppZygote appZygote = mAppZygotes.get(app.info.processName,
+ app.hostingRecord.getDefiningUid());
if (appZygote != null) {
ArrayList<ProcessRecord> zygoteProcesses = mAppZygoteProcesses.get(appZygote);
zygoteProcesses.remove(app);
@@ -1753,21 +1754,40 @@
private AppZygote createAppZygoteForProcessIfNeeded(final ProcessRecord app) {
synchronized (mService) {
- AppZygote appZygote = mAppZygotes.get(app.info.processName, app.info.uid);
+ // The UID for the app zygote should be the UID of the application hosting
+ // the service.
+ final int uid = app.hostingRecord.getDefiningUid();
+ AppZygote appZygote = mAppZygotes.get(app.info.processName, uid);
final ArrayList<ProcessRecord> zygoteProcessList;
if (appZygote == null) {
+ if (DEBUG_PROCESSES) {
+ Slog.d(TAG_PROCESSES, "Creating new app zygote.");
+ }
final IsolatedUidRange uidRange =
- mAppIsolatedUidRangeAllocator.getIsolatedUidRangeLocked(app.info);
- final int userId = UserHandle.getUserId(app.info.uid);
+ mAppIsolatedUidRangeAllocator.getIsolatedUidRangeLocked(
+ app.info.processName, app.hostingRecord.getDefiningUid());
+ final int userId = UserHandle.getUserId(uid);
// Create the app-zygote and provide it with the UID-range it's allowed
// to setresuid/setresgid to.
final int firstUid = UserHandle.getUid(userId, uidRange.mFirstUid);
final int lastUid = UserHandle.getUid(userId, uidRange.mLastUid);
- appZygote = new AppZygote(app.info, app.info.uid, firstUid, lastUid);
- mAppZygotes.put(app.info.processName, app.info.uid, appZygote);
+ ApplicationInfo appInfo = new ApplicationInfo(app.info);
+ // If this was an external service, the package name and uid in the passed in
+ // ApplicationInfo have been changed to match those of the calling package;
+ // that is not what we want for the AppZygote though, which needs to have the
+ // packageName and uid of the defining application. This is because the
+ // preloading only makes sense in the context of the defining application,
+ // not the calling one.
+ appInfo.packageName = app.hostingRecord.getDefiningPackageName();
+ appInfo.uid = uid;
+ appZygote = new AppZygote(appInfo, uid, firstUid, lastUid);
+ mAppZygotes.put(app.info.processName, uid, appZygote);
zygoteProcessList = new ArrayList<ProcessRecord>();
mAppZygoteProcesses.put(appZygote, zygoteProcessList);
} else {
+ if (DEBUG_PROCESSES) {
+ Slog.d(TAG_PROCESSES, "Reusing existing app zygote.");
+ }
mService.mHandler.removeMessages(KILL_APP_ZYGOTE_MSG, appZygote);
zygoteProcessList = mAppZygoteProcesses.get(appZygote);
}
@@ -1781,7 +1801,7 @@
}
}
- private Process.ProcessStartResult startProcess(String hostingType, String entryPoint,
+ private Process.ProcessStartResult startProcess(HostingRecord hostingRecord, String entryPoint,
ProcessRecord app, int uid, int[] gids, int runtimeFlags, int mountExternal,
String seInfo, String requiredAbi, String instructionSet, String invokeWith,
long startTime) {
@@ -1797,7 +1817,7 @@
app.processName);
checkSlow(startTime, "startProcess: asking zygote to start proc");
final Process.ProcessStartResult startResult;
- if (hostingType.equals("webview_service")) {
+ if (hostingRecord.usesWebviewZygote()) {
startResult = startWebView(entryPoint,
app.processName, uid, uid, gids, runtimeFlags, mountExternal,
app.info.targetSdkVersion, seInfo, requiredAbi, instructionSet,
@@ -1805,7 +1825,7 @@
packageNames, sandboxId,
new String[] {PROC_START_SEQ_IDENT + app.startSeq},
useSystemGraphicsDriver);
- } else if (hostingType.equals("app_zygote")) {
+ } else if (hostingRecord.usesAppZygote()) {
final AppZygote appZygote = createAppZygoteForProcessIfNeeded(app);
startResult = appZygote.getProcess().start(entryPoint,
@@ -1832,21 +1852,20 @@
}
@GuardedBy("mService")
- final void startProcessLocked(ProcessRecord app,
- String hostingType, String hostingNameStr) {
- startProcessLocked(app, hostingType, hostingNameStr, null /* abiOverride */);
+ final void startProcessLocked(ProcessRecord app, HostingRecord hostingRecord) {
+ startProcessLocked(app, hostingRecord, null /* abiOverride */);
}
@GuardedBy("mService")
- final boolean startProcessLocked(ProcessRecord app,
- String hostingType, String hostingNameStr, String abiOverride) {
- return startProcessLocked(app, hostingType, hostingNameStr,
+ final boolean startProcessLocked(ProcessRecord app, HostingRecord hostingRecord,
+ String abiOverride) {
+ return startProcessLocked(app, hostingRecord,
false /* disableHiddenApiChecks */, false /* mountExtStorageFull */, abiOverride);
}
@GuardedBy("mService")
final ProcessRecord startProcessLocked(String processName, ApplicationInfo info,
- boolean knownToBeDead, int intentFlags, String hostingType, ComponentName hostingName,
+ boolean knownToBeDead, int intentFlags, HostingRecord hostingRecord,
boolean allowWhileBooting, boolean isolated, int isolatedUid, boolean keepIfLarge,
String abiOverride, String entryPoint, String[] entryPointArgs, Runnable crashHandler) {
long startTime = SystemClock.elapsedRealtime();
@@ -1916,13 +1935,9 @@
checkSlow(startTime, "startProcess: done killing old proc");
}
- String hostingNameStr = hostingName != null
- ? hostingName.flattenToShortString() : null;
-
if (app == null) {
- final boolean fromAppZygote = "app_zygote".equals(hostingType);
checkSlow(startTime, "startProcess: creating new process record");
- app = newProcessRecordLocked(info, processName, isolated, isolatedUid, fromAppZygote);
+ app = newProcessRecordLocked(info, processName, isolated, isolatedUid, hostingRecord);
if (app == null) {
Slog.w(TAG, "Failed making new process record for "
+ processName + "/" + info.uid + " isolated=" + isolated);
@@ -1953,8 +1968,7 @@
}
checkSlow(startTime, "startProcess: stepping in to startProcess");
- final boolean success = startProcessLocked(app, hostingType, hostingNameStr,
- abiOverride);
+ final boolean success = startProcessLocked(app, hostingRecord, abiOverride);
checkSlow(startTime, "startProcess: done starting proc!");
return success ? app : null;
}
@@ -2015,8 +2029,8 @@
EventLog.writeEvent(EventLogTags.AM_PROC_START,
UserHandle.getUserId(app.startUid), pid, app.startUid,
- app.processName, app.hostingType,
- app.hostingNameStr != null ? app.hostingNameStr : "");
+ app.processName, app.hostingRecord.getType(),
+ app.hostingRecord.getName() != null ? app.hostingRecord.getName() : "");
try {
AppGlobals.getPackageManager().logAppProcessStartIfNeeded(app.processName, app.uid,
@@ -2044,10 +2058,10 @@
buf.append("]");
}
buf.append(" for ");
- buf.append(app.hostingType);
- if (app.hostingNameStr != null) {
+ buf.append(app.hostingRecord.getType());
+ if (app.hostingRecord.getName() != null) {
buf.append(" ");
- buf.append(app.hostingNameStr);
+ buf.append(app.hostingRecord.getName());
}
mService.reportUidInfoMessageLocked(TAG, buf.toString(), app.startUid);
app.setPid(pid);
@@ -2307,24 +2321,25 @@
@GuardedBy("mService")
private IsolatedUidRange getOrCreateIsolatedUidRangeLocked(ApplicationInfo info,
- boolean fromAppZygote) {
- if (!fromAppZygote) {
+ HostingRecord hostingRecord) {
+ if (hostingRecord == null || !hostingRecord.usesAppZygote()) {
// Allocate an isolated UID from the global range
return mGlobalIsolatedUids;
} else {
- return mAppIsolatedUidRangeAllocator.getOrCreateIsolatedUidRangeLocked(info);
+ return mAppIsolatedUidRangeAllocator.getOrCreateIsolatedUidRangeLocked(
+ info.processName, hostingRecord.getDefiningUid());
}
}
@GuardedBy("mService")
final ProcessRecord newProcessRecordLocked(ApplicationInfo info, String customProcess,
- boolean isolated, int isolatedUid, boolean fromAppZygote) {
+ boolean isolated, int isolatedUid, HostingRecord hostingRecord) {
String proc = customProcess != null ? customProcess : info.processName;
final int userId = UserHandle.getUserId(info.uid);
int uid = info.uid;
if (isolated) {
if (isolatedUid == 0) {
- IsolatedUidRange uidRange = getOrCreateIsolatedUidRangeLocked(info, fromAppZygote);
+ IsolatedUidRange uidRange = getOrCreateIsolatedUidRangeLocked(info, hostingRecord);
if (uidRange == null) {
return null;
}
diff --git a/services/core/java/com/android/server/am/ProcessRecord.java b/services/core/java/com/android/server/am/ProcessRecord.java
index ce13cd8..933f41c 100644
--- a/services/core/java/com/android/server/am/ProcessRecord.java
+++ b/services/core/java/com/android/server/am/ProcessRecord.java
@@ -301,18 +301,16 @@
boolean whitelistManager;
// Params used in starting this process.
- String hostingType;
- String hostingNameStr;
+ HostingRecord hostingRecord;
String seInfo;
long startTime;
// This will be same as {@link #uid} usually except for some apps used during factory testing.
int startUid;
- void setStartParams(int startUid, String hostingType, String hostingNameStr, String seInfo,
+ void setStartParams(int startUid, HostingRecord hostingRecord, String seInfo,
long startTime) {
this.startUid = startUid;
- this.hostingType = hostingType;
- this.hostingNameStr = hostingNameStr;
+ this.hostingRecord = hostingRecord;
this.seInfo = seInfo;
this.startTime = startTime;
}
@@ -878,13 +876,6 @@
return null;
}
- @Override
- public void addPackage(String pkg, long versionCode) {
- synchronized (mService) {
- addPackage(pkg, versionCode, mService.mProcessStats);
- }
- }
-
/*
* Return true if package has been added false if not
*/
@@ -1302,15 +1293,13 @@
}
@Override
- public void updateProcessInfo(boolean updateServiceConnectionActivities, boolean updateLru,
- boolean activityChange, boolean updateOomAdj) {
+ public void updateProcessInfo(boolean updateServiceConnectionActivities, boolean activityChange,
+ boolean updateOomAdj) {
synchronized (mService) {
if (updateServiceConnectionActivities) {
mService.mServices.updateServiceConnectionActivitiesLocked(this);
}
- if (updateLru) {
- mService.mProcessList.updateLruProcessLocked(this, activityChange, null);
- }
+ mService.mProcessList.updateLruProcessLocked(this, activityChange, null /* client */);
if (updateOomAdj) {
mService.updateOomAdjLocked();
}
@@ -1332,19 +1321,20 @@
}
@Override
- public void clearWaitingToKill() {
+ public void onStartActivity(int topProcessState, boolean setProfileProc, String packageName,
+ long versionCode) {
synchronized (mService) {
waitingToKill = null;
- }
- }
-
- @Override
- public void onStartActivity(int topProcessState, boolean setProfileProc) {
- synchronized (mService) {
if (setProfileProc) {
mService.mProfileData.setProfileProc(this);
}
+ if (packageName != null) {
+ addPackage(packageName, versionCode, mService.mProcessStats);
+ }
+ // Update oom adj first, we don't want the additional states are involved in this round.
+ updateProcessInfo(false /* updateServiceConnectionActivities */,
+ true /* activityChange */, true /* updateOomAdj */);
hasShownUi = true;
setPendingUiClean(true);
forceProcessStateUpTo(topProcessState);
diff --git a/services/core/java/com/android/server/am/ServiceRecord.java b/services/core/java/com/android/server/am/ServiceRecord.java
index 217fd6d..27c62d0 100644
--- a/services/core/java/com/android/server/am/ServiceRecord.java
+++ b/services/core/java/com/android/server/am/ServiceRecord.java
@@ -73,6 +73,10 @@
final ComponentName name; // service component.
final ComponentName instanceName; // service component's per-instance name.
final String shortInstanceName; // instanceName.flattenToShortString().
+ final String definingPackageName;
+ // Can be different from appInfo.packageName for external services
+ final int definingUid;
+ // Can be different from appInfo.uid for external services
final Intent.FilterComparison intent;
// original intent used to find service.
final ServiceInfo serviceInfo;
@@ -474,7 +478,7 @@
ServiceRecord(ActivityManagerService ams,
BatteryStatsImpl.Uid.Pkg.Serv servStats, ComponentName name,
- ComponentName instanceName,
+ ComponentName instanceName, String definingPackageName, int definingUid,
Intent.FilterComparison intent, ServiceInfo sInfo, boolean callerIsFg,
Runnable restarter) {
this.ams = ams;
@@ -482,6 +486,8 @@
this.name = name;
this.instanceName = instanceName;
shortInstanceName = instanceName.flattenToShortString();
+ this.definingPackageName = definingPackageName;
+ this.definingUid = definingUid;
this.intent = intent;
serviceInfo = sInfo;
appInfo = sInfo.applicationInfo;
diff --git a/services/core/java/com/android/server/appop/AppOpsService.java b/services/core/java/com/android/server/appop/AppOpsService.java
index 4c3bb8c..873cadb 100644
--- a/services/core/java/com/android/server/appop/AppOpsService.java
+++ b/services/core/java/com/android/server/appop/AppOpsService.java
@@ -220,7 +220,8 @@
* global Settings. Any access to this class or its fields should be done while
* holding the AppOpsService lock.
*/
- private final class Constants extends ContentObserver {
+ @VisibleForTesting
+ final class Constants extends ContentObserver {
// Key names stored in the settings value.
private static final String KEY_TOP_STATE_SETTLE_TIME = "top_state_settle_time";
private static final String KEY_FG_SERVICE_STATE_SETTLE_TIME
@@ -305,7 +306,8 @@
}
}
- private final Constants mConstants;
+ @VisibleForTesting
+ final Constants mConstants;
@VisibleForTesting
static final class UidState {
diff --git a/services/core/java/com/android/server/audio/AudioDeviceBroker.java b/services/core/java/com/android/server/audio/AudioDeviceBroker.java
index b774647..44c1715 100644
--- a/services/core/java/com/android/server/audio/AudioDeviceBroker.java
+++ b/services/core/java/com/android/server/audio/AudioDeviceBroker.java
@@ -406,6 +406,10 @@
mAudioService.checkVolumeCecOnHdmiConnection(state, caller);
}
+ /*package*/ boolean hasAudioFocusUsers() {
+ return mAudioService.hasAudioFocusUsers();
+ }
+
//---------------------------------------------------------------------
// Message handling on behalf of helper classes
/*package*/ void postBroadcastScoConnectionState(int state) {
diff --git a/services/core/java/com/android/server/audio/AudioDeviceInventory.java b/services/core/java/com/android/server/audio/AudioDeviceInventory.java
index 7750bfe..91b51b4 100644
--- a/services/core/java/com/android/server/audio/AudioDeviceInventory.java
+++ b/services/core/java/com/android/server/audio/AudioDeviceInventory.java
@@ -819,11 +819,12 @@
if (((device == musicDevice) || mDeviceBroker.isInCommunication())
&& (device == devices) && !mDeviceBroker.hasMediaDynamicPolicy()
&& ((musicDevice & AudioSystem.DEVICE_OUT_REMOTE_SUBMIX) == 0)) {
- if (!AudioSystem.isStreamActive(AudioSystem.STREAM_MUSIC, 0 /*not looking in past*/)) {
+ if (!AudioSystem.isStreamActive(AudioSystem.STREAM_MUSIC, 0 /*not looking in past*/)
+ && !mDeviceBroker.hasAudioFocusUsers()) {
// no media playback, not a "becoming noisy" situation, otherwise it could cause
// the pausing of some apps that are playing remotely
AudioService.sDeviceLogger.log((new AudioEventLogger.StringEvent(
- "dropping ACTION_AUDIO_BECOMING_NOISY, no media playback")).printLog(TAG));
+ "dropping ACTION_AUDIO_BECOMING_NOISY")).printLog(TAG));
return 0;
}
mDeviceBroker.postBroadcastBecomingNoisy();
diff --git a/services/core/java/com/android/server/audio/AudioService.java b/services/core/java/com/android/server/audio/AudioService.java
index d58888a..70af907 100644
--- a/services/core/java/com/android/server/audio/AudioService.java
+++ b/services/core/java/com/android/server/audio/AudioService.java
@@ -90,9 +90,8 @@
import android.media.audiopolicy.AudioMix;
import android.media.audiopolicy.AudioPolicy;
import android.media.audiopolicy.AudioPolicyConfig;
-import android.media.audiopolicy.AudioProductStrategies;
+import android.media.audiopolicy.AudioProductStrategy;
import android.media.audiopolicy.AudioVolumeGroup;
-import android.media.audiopolicy.AudioVolumeGroups;
import android.media.audiopolicy.IAudioPolicyCallback;
import android.media.projection.IMediaProjection;
import android.media.projection.IMediaProjectionManager;
@@ -281,11 +280,6 @@
private SettingsObserver mSettingsObserver;
- /** @see AudioProductStrategies */
- private static AudioProductStrategies sAudioProductStrategies;
- /** @see AudioVolumeGroups */
- private static AudioVolumeGroups sAudioVolumeGroups;
-
private int mMode = AudioSystem.MODE_NORMAL;
// protects mRingerMode
private final Object mSettingsLock = new Object();
@@ -636,19 +630,17 @@
mVibrator = (Vibrator) context.getSystemService(Context.VIBRATOR_SERVICE);
mHasVibrator = mVibrator == null ? false : mVibrator.hasVibrator();
- sAudioProductStrategies = new AudioProductStrategies();
- sAudioVolumeGroups = new AudioVolumeGroups();
-
// Initialize volume
// Priority 1 - Android Property
// Priority 2 - Audio Policy Service
// Priority 3 - Default Value
- if (sAudioProductStrategies.size() > 0) {
+ if (AudioProductStrategy.getAudioProductStrategies().size() > 0) {
int numStreamTypes = AudioSystem.getNumStreamTypes();
for (int streamType = numStreamTypes - 1; streamType >= 0; streamType--) {
AudioAttributes attr =
- sAudioProductStrategies.getAudioAttributesForLegacyStreamType(streamType);
+ AudioProductStrategy.getAudioAttributesForStrategyWithLegacyStreamType(
+ streamType);
int maxVolume = AudioSystem.getMaxVolumeIndexForAttributes(attr);
if (maxVolume != -1) {
MAX_STREAM_VOLUME[streamType] = maxVolume;
@@ -1023,19 +1015,21 @@
}
/**
- * @return the {@link android.media.audiopolicy.AudioProductStrategies} discovered from the
+ * @return the {@link android.media.audiopolicy.AudioProductStrategy} discovered from the
* platform configuration file.
*/
- public @NonNull AudioProductStrategies getAudioProductStrategies() {
- return sAudioProductStrategies;
+ @NonNull
+ public List<AudioProductStrategy> getAudioProductStrategies() {
+ return AudioProductStrategy.getAudioProductStrategies();
}
/**
- * @return the {@link android.media.audiopolicy.AudioVolumeGroups} discovered from the
+ * @return the List of {@link android.media.audiopolicy.AudioVolumeGroup} discovered from the
* platform configuration file.
*/
- public @NonNull AudioVolumeGroups listAudioVolumeGroups() {
- return sAudioVolumeGroups;
+ @NonNull
+ public List<AudioVolumeGroup> getAudioVolumeGroups() {
+ return AudioVolumeGroup.getAudioVolumeGroups();
}
private void checkAllAliasStreamVolumes() {
@@ -1529,9 +1523,11 @@
+ ", flags=" + flags + ", caller=" + caller
+ ", volControlStream=" + mVolumeControlStream
+ ", userSelect=" + mUserSelectedVolumeControlStream);
- sVolumeLogger.log(new VolumeEvent(VolumeEvent.VOL_ADJUST_SUGG_VOL, suggestedStreamType,
- direction/*val1*/, flags/*val2*/, new StringBuilder(callingPackage)
- .append("/").append(caller).append(" uid:").append(uid).toString()));
+ if (direction != AudioManager.ADJUST_SAME) {
+ sVolumeLogger.log(new VolumeEvent(VolumeEvent.VOL_ADJUST_SUGG_VOL, suggestedStreamType,
+ direction/*val1*/, flags/*val2*/, new StringBuilder(callingPackage)
+ .append("/").append(caller).append(" uid:").append(uid).toString()));
+ }
final int streamType;
synchronized (mForceControlStreamLock) {
// Request lock in case mVolumeControlStream is changed by other thread.
@@ -1947,15 +1943,15 @@
enforceModifyAudioRoutingPermission();
Preconditions.checkNotNull(attr, "attr must not be null");
// @todo not hold the caller context, post message
- int stream = sAudioProductStrategies.getLegacyStreamTypeForAudioAttributes(attr);
+ int stream = AudioProductStrategy.getLegacyStreamTypeForStrategyWithAudioAttributes(attr);
final int device = getDeviceForStream(stream);
int oldIndex = AudioSystem.getVolumeIndexForAttributes(attr, device);
AudioSystem.setVolumeIndexForAttributes(attr, index, device);
- final int volumeGroup = sAudioProductStrategies.getVolumeGroupIdForAttributes(attr);
- final AudioVolumeGroup avg = sAudioVolumeGroups.getById(volumeGroup);
+ final int volumeGroup = getVolumeGroupIdForAttributes(attr);
+ final AudioVolumeGroup avg = getAudioVolumeGroupById(volumeGroup);
if (avg == null) {
return;
}
@@ -1965,11 +1961,23 @@
}
}
+ @Nullable
+ private AudioVolumeGroup getAudioVolumeGroupById(int volumeGroupId) {
+ for (final AudioVolumeGroup avg : AudioVolumeGroup.getAudioVolumeGroups()) {
+ if (avg.getId() == volumeGroupId) {
+ return avg;
+ }
+ }
+
+ Log.e(TAG, ": invalid volume group id: " + volumeGroupId + " requested");
+ return null;
+ }
+
/** @see AudioManager#getVolumeIndexForAttributes(attr) */
public int getVolumeIndexForAttributes(@NonNull AudioAttributes attr) {
enforceModifyAudioRoutingPermission();
Preconditions.checkNotNull(attr, "attr must not be null");
- int stream = sAudioProductStrategies.getLegacyStreamTypeForAudioAttributes(attr);
+ int stream = AudioProductStrategy.getLegacyStreamTypeForStrategyWithAudioAttributes(attr);
final int device = getDeviceForStream(stream);
return AudioSystem.getVolumeIndexForAttributes(attr, device);
@@ -2144,6 +2152,32 @@
sendVolumeUpdate(streamType, oldIndex, index, flags);
}
+
+
+ private int getVolumeGroupIdForAttributes(@NonNull AudioAttributes attributes) {
+ Preconditions.checkNotNull(attributes, "attributes must not be null");
+ int volumeGroupId = getVolumeGroupIdForAttributesInt(attributes);
+ if (volumeGroupId != AudioVolumeGroup.DEFAULT_VOLUME_GROUP) {
+ return volumeGroupId;
+ }
+ // The default volume group is the one hosted by default product strategy, i.e.
+ // supporting Default Attributes
+ return getVolumeGroupIdForAttributesInt(AudioProductStrategy.sDefaultAttributes);
+ }
+
+ private int getVolumeGroupIdForAttributesInt(@NonNull AudioAttributes attributes) {
+ Preconditions.checkNotNull(attributes, "attributes must not be null");
+ for (final AudioProductStrategy productStrategy :
+ AudioProductStrategy.getAudioProductStrategies()) {
+ int volumeGroupId = productStrategy.getVolumeGroupIdForAudioAttributes(attributes);
+ if (volumeGroupId != AudioVolumeGroup.DEFAULT_VOLUME_GROUP) {
+ return volumeGroupId;
+ }
+ }
+ return AudioVolumeGroup.DEFAULT_VOLUME_GROUP;
+ }
+
+
// No ringer or zen muted stream volumes can be changed unless it'll exit dnd
private boolean volumeAdjustmentAllowedByDnd(int streamTypeAlias, int flags) {
switch (mNm.getZenMode()) {
@@ -5546,6 +5580,10 @@
return mMediaFocusControl.getFocusRampTimeMs(focusGain, attr);
}
+ /*package*/ boolean hasAudioFocusUsers() {
+ return mMediaFocusControl.hasAudioFocusUsers();
+ }
+
//==========================================================================================
private boolean readCameraSoundForced() {
return SystemProperties.getBoolean("audio.camerasound.force", false) ||
@@ -6288,6 +6326,11 @@
@Override
public void adjustStreamVolumeForUid(int streamType, int direction, int flags,
String callingPackage, int uid) {
+ if (direction != AudioManager.ADJUST_SAME) {
+ sVolumeLogger.log(new VolumeEvent(VolumeEvent.VOL_ADJUST_VOL_UID, streamType,
+ direction/*val1*/, flags/*val2*/, new StringBuilder(callingPackage)
+ .append(" uid:").append(uid).toString()));
+ }
adjustStreamVolume(streamType, direction, flags, callingPackage,
callingPackage, uid);
}
diff --git a/services/core/java/com/android/server/audio/AudioServiceEvents.java b/services/core/java/com/android/server/audio/AudioServiceEvents.java
index 7ccb45e..d999217 100644
--- a/services/core/java/com/android/server/audio/AudioServiceEvents.java
+++ b/services/core/java/com/android/server/audio/AudioServiceEvents.java
@@ -94,6 +94,7 @@
static final int VOL_SET_STREAM_VOL = 2;
static final int VOL_SET_HEARING_AID_VOL = 3;
static final int VOL_SET_AVRCP_VOL = 4;
+ static final int VOL_ADJUST_VOL_UID = 5;
final int mOp;
final int mStream;
@@ -160,6 +161,13 @@
return new StringBuilder("setAvrcpVolume:")
.append(" index:").append(mVal1)
.toString();
+ case VOL_ADJUST_VOL_UID:
+ return new StringBuilder("adjustStreamVolumeForUid(stream:")
+ .append(AudioSystem.streamToString(mStream))
+ .append(" dir:").append(AudioManager.adjustToString(mVal1))
+ .append(" flags:0x").append(Integer.toHexString(mVal2))
+ .append(") from ").append(mCaller)
+ .toString();
default: return new StringBuilder("FIXME invalid op:").append(mOp).toString();
}
}
diff --git a/services/core/java/com/android/server/audio/MediaFocusControl.java b/services/core/java/com/android/server/audio/MediaFocusControl.java
index 1e58b45..5c93071 100644
--- a/services/core/java/com/android/server/audio/MediaFocusControl.java
+++ b/services/core/java/com/android/server/audio/MediaFocusControl.java
@@ -162,6 +162,12 @@
}
}
+ /*package*/ boolean hasAudioFocusUsers() {
+ synchronized (mAudioFocusLock) {
+ return !mFocusStack.empty();
+ }
+ }
+
/**
* Discard the current audio focus owner.
* Notify top of audio focus stack that it lost focus (regardless of possibility to reassign
diff --git a/services/core/java/com/android/server/biometrics/AuthenticationClient.java b/services/core/java/com/android/server/biometrics/AuthenticationClient.java
index b2c5c05..91da7af 100644
--- a/services/core/java/com/android/server/biometrics/AuthenticationClient.java
+++ b/services/core/java/com/android/server/biometrics/AuthenticationClient.java
@@ -134,7 +134,8 @@
+ ", Owner: " + getOwnerString()
+ ", isBP: " + isBiometricPrompt()
+ ", listener: " + listener
- + ", requireConfirmation: " + mRequireConfirmation);
+ + ", requireConfirmation: " + mRequireConfirmation
+ + ", user: " + getTargetUserId());
if (authenticated) {
mAlreadyDone = true;
diff --git a/services/core/java/com/android/server/biometrics/face/FaceService.java b/services/core/java/com/android/server/biometrics/face/FaceService.java
index aa52621..e218c6b 100644
--- a/services/core/java/com/android/server/biometrics/face/FaceService.java
+++ b/services/core/java/com/android/server/biometrics/face/FaceService.java
@@ -42,14 +42,13 @@
import android.os.Build;
import android.os.Environment;
import android.os.IBinder;
+import android.os.NativeHandle;
import android.os.RemoteException;
import android.os.SELinux;
import android.os.SystemProperties;
import android.os.UserHandle;
import android.os.UserManager;
-import android.service.restricted_image.RestrictedImageProto;
-import android.service.restricted_image.RestrictedImageSetProto;
-import android.service.restricted_image.RestrictedImagesDumpProto;
+import android.provider.Settings;
import android.util.Slog;
import android.util.proto.ProtoOutputStream;
@@ -70,8 +69,11 @@
import java.io.File;
import java.io.FileDescriptor;
+import java.io.FileOutputStream;
+import java.io.IOException;
import java.io.PrintWriter;
import java.util.ArrayList;
+import java.util.Arrays;
import java.util.List;
/**
@@ -286,8 +288,8 @@
final long ident = Binder.clearCallingIdentity();
try {
- if (args.length == 1 && "--restricted_image".equals(args[0])) {
- dumpRestrictedImage(fd);
+ if (args.length > 1 && "--hal".equals(args[0])) {
+ dumpHal(fd, Arrays.copyOfRange(args, 1, args.length, args.getClass()));
} else if (args.length > 0 && "--proto".equals(args[0])) {
dumpProto(fd);
} else {
@@ -546,7 +548,8 @@
throws RemoteException {
if (mFaceServiceReceiver != null) {
if (biometric == null || biometric instanceof Face) {
- mFaceServiceReceiver.onAuthenticationSucceeded(deviceId, (Face)biometric);
+ mFaceServiceReceiver.onAuthenticationSucceeded(deviceId, (Face) biometric,
+ userId);
} else {
Slog.e(TAG, "onAuthenticationSucceeded received non-face biometric");
}
@@ -1078,7 +1081,7 @@
mCryptoPerformanceMap.clear();
}
- private void dumpRestrictedImage(FileDescriptor fd) {
+ private void dumpHal(FileDescriptor fd, String[] args) {
// WARNING: CDD restricts image data from leaving TEE unencrypted on
// production devices:
// [C-1-10] MUST not allow unencrypted access to identifiable biometric
@@ -1099,59 +1102,28 @@
return;
}
- final ProtoOutputStream proto = new ProtoOutputStream(fd);
-
- final long setToken = proto.start(RestrictedImagesDumpProto.SETS);
-
- // Name of the service
- proto.write(RestrictedImageSetProto.CATEGORY, "face");
-
- // Individual images
- for (int i = 0; i < 5; i++) {
- final long imageToken = proto.start(RestrictedImageSetProto.IMAGES);
- proto.write(RestrictedImageProto.MIME_TYPE, "image/png");
- proto.write(RestrictedImageProto.IMAGE_DATA, new byte[] {
- // png image data
- -119, 80, 78, 71, 13, 10, 26, 10,
- 0, 0, 0, 13, 73, 72, 68, 82,
- 0, 0, 0, 100, 0, 0, 0, 100,
- 1, 3, 0, 0, 0, 74, 44, 7,
- 23, 0, 0, 0, 4, 103, 65, 77,
- 65, 0, 0, -79, -113, 11, -4, 97,
- 5, 0, 0, 0, 1, 115, 82, 71,
- 66, 0, -82, -50, 28, -23, 0, 0,
- 0, 6, 80, 76, 84, 69, -1, -1,
- -1, 0, 0, 0, 85, -62, -45, 126,
- 0, 0, 0, -115, 73, 68, 65, 84,
- 56, -53, -19, -46, -79, 17, -128, 32,
- 12, 5, -48, 120, 22, -106, -116, -32,
- 40, -84, 101, -121, -93, 57, 10, 35,
- 88, 82, 112, 126, 3, -60, 104, 6,
- -112, 70, 127, -59, -69, -53, 29, 33,
- -127, -24, 79, -49, -52, -15, 41, 36,
- 34, -105, 85, 124, -14, 88, 27, 6,
- 28, 68, 1, 82, 62, 22, -95, -108,
- 55, -95, 40, -9, -110, -12, 98, -107,
- 76, -41, -105, -62, -50, 111, -60, 46,
- -14, -4, 24, -89, 42, -103, 16, 63,
- -72, -11, -15, 48, -62, 102, -44, 102,
- -73, -56, 56, -21, -128, 92, -70, -124,
- 117, -46, -67, -77, 82, 80, 121, -44,
- -56, 116, 93, -45, -90, -5, -29, -24,
- -83, -75, 52, -34, 55, -22, 102, -21,
- -105, -124, -23, 71, 87, -7, -25, -59,
- -100, -73, -92, -122, -7, -109, -49, -80,
- -89, 0, 0, 0, 0, 73, 69, 78,
- 68, -82, 66, 96, -126
- });
- // proto.write(RestrictedImageProto.METADATA, flattened_protobuf);
- proto.end(imageToken);
+ // The debug method takes two file descriptors. The first is for text
+ // output, which we will drop. The second is for binary data, which
+ // will be the protobuf data.
+ final IBiometricsFace daemon = getFaceDaemon();
+ if (daemon != null) {
+ FileOutputStream devnull = null;
+ try {
+ devnull = new FileOutputStream("/dev/null");
+ final NativeHandle handle = new NativeHandle(
+ new FileDescriptor[] { devnull.getFD(), fd },
+ new int[0], false);
+ daemon.debug(handle, new ArrayList<String>(Arrays.asList(args)));
+ } catch (IOException | RemoteException ex) {
+ Slog.d(TAG, "error while reading face debugging data", ex);
+ } finally {
+ if (devnull != null) {
+ try {
+ devnull.close();
+ } catch (IOException ex) {
+ }
+ }
+ }
}
-
- // Face service metadata
- // proto.write(RestrictedImageSetProto.METADATA, flattened_protobuf);
-
- proto.end(setToken);
- proto.flush();
}
}
diff --git a/services/core/java/com/android/server/incident/IncidentCompanionService.java b/services/core/java/com/android/server/incident/IncidentCompanionService.java
index 9989c1a..87fe785 100644
--- a/services/core/java/com/android/server/incident/IncidentCompanionService.java
+++ b/services/core/java/com/android/server/incident/IncidentCompanionService.java
@@ -55,7 +55,8 @@
* Dump argument for proxying restricted image dumps to the services
* listed in the config.
*/
- private static String[] RESTRICTED_IMAGE_DUMP_ARGS = new String[] { "--restricted_image" };
+ private static String[] RESTRICTED_IMAGE_DUMP_ARGS = new String[] {
+ "--hal", "--restricted_image" };
/**
* The two permissions, for sendBroadcastAsUserMultiplePermissions.
diff --git a/services/core/java/com/android/server/input/InputManagerService.java b/services/core/java/com/android/server/input/InputManagerService.java
index cec4d69..75b9705 100644
--- a/services/core/java/com/android/server/input/InputManagerService.java
+++ b/services/core/java/com/android/server/input/InputManagerService.java
@@ -523,11 +523,17 @@
}
- InputChannel[] inputChannels = InputChannel.openInputChannelPair(inputChannelName);
- InputMonitorHost host = new InputMonitorHost(inputChannels[0]);
- inputChannels[0].setToken(host.asBinder());
- nativeRegisterInputMonitor(mPtr, inputChannels[0], displayId, true /*isGestureMonitor*/);
- return new InputMonitor(inputChannelName, inputChannels[1], host);
+ final long ident = Binder.clearCallingIdentity();
+ try {
+ InputChannel[] inputChannels = InputChannel.openInputChannelPair(inputChannelName);
+ InputMonitorHost host = new InputMonitorHost(inputChannels[0]);
+ inputChannels[0].setToken(host.asBinder());
+ nativeRegisterInputMonitor(mPtr, inputChannels[0], displayId,
+ true /*isGestureMonitor*/);
+ return new InputMonitor(inputChannelName, inputChannels[1], host);
+ } finally {
+ Binder.restoreCallingIdentity(ident);
+ }
}
/**
diff --git a/services/core/java/com/android/server/inputmethod/InputMethodManagerService.java b/services/core/java/com/android/server/inputmethod/InputMethodManagerService.java
index e88d62f..3c97c39 100644
--- a/services/core/java/com/android/server/inputmethod/InputMethodManagerService.java
+++ b/services/core/java/com/android/server/inputmethod/InputMethodManagerService.java
@@ -4710,10 +4710,10 @@
@ShellCommandResult
private int handleShellCommandEnableDisableInputMethod(
@NonNull ShellCommand shellCommand, boolean enabled) {
+ final int userIdToBeResolved = handleOptionsForCommandsThatOnlyHaveUserOption(shellCommand);
final String imeId = shellCommand.getNextArgRequired();
final PrintWriter out = shellCommand.getOutPrintWriter();
final PrintWriter error = shellCommand.getErrPrintWriter();
- final int userIdToBeResolved = handleOptionsForCommandsThatOnlyHaveUserOption(shellCommand);
synchronized (mMethodMap) {
final int[] userIds = InputMethodUtils.resolveUserId(userIdToBeResolved,
mSettings.getCurrentUserId(), shellCommand.getErrPrintWriter());
@@ -4733,6 +4733,10 @@
*
* <p>You cannot use this helper method if the command has other options.</p>
*
+ * <p>CAVEAT: This method must be called only once before any other
+ * {@link ShellCommand#getNextArg()} and {@link ShellCommand#getNextArgRequired()} for the
+ * main arguments.</p>
+ *
* @param shellCommand {@link ShellCommand} from which options should be obtained.
* @return User ID to be resolved. {@link UserHandle#CURRENT} if not specified.
*/
@@ -4819,10 +4823,10 @@
@BinderThread
@ShellCommandResult
private int handleShellCommandSetInputMethod(@NonNull ShellCommand shellCommand) {
+ final int userIdToBeResolved = handleOptionsForCommandsThatOnlyHaveUserOption(shellCommand);
final String imeId = shellCommand.getNextArgRequired();
final PrintWriter out = shellCommand.getOutPrintWriter();
final PrintWriter error = shellCommand.getErrPrintWriter();
- final int userIdToBeResolved = handleOptionsForCommandsThatOnlyHaveUserOption(shellCommand);
synchronized (mMethodMap) {
final int[] userIds = InputMethodUtils.resolveUserId(userIdToBeResolved,
mSettings.getCurrentUserId(), shellCommand.getErrPrintWriter());
@@ -4864,7 +4868,7 @@
out.print("Input method ");
out.print(imeId);
out.print(" selected for user #");
- error.println(userId);
+ out.println(userId);
}
}
}
diff --git a/services/core/java/com/android/server/location/GnssLocationProvider.java b/services/core/java/com/android/server/location/GnssLocationProvider.java
index e28f89c..96fc6ec 100644
--- a/services/core/java/com/android/server/location/GnssLocationProvider.java
+++ b/services/core/java/com/android/server/location/GnssLocationProvider.java
@@ -495,6 +495,7 @@
@Override
public void onUpdateSatelliteBlacklist(int[] constellations, int[] svids) {
mHandler.post(() -> mGnssConfiguration.setSatelliteBlacklist(constellations, svids));
+ mGnssMetrics.resetConstellationTypes();
}
private void subscriptionOrCarrierConfigChanged(Context context) {
@@ -1443,6 +1444,13 @@
GnssStatus.GNSS_SV_FLAGS_HAS_CARRIER_FREQUENCY) == 0
? "" : "F"));
}
+
+ if ((info.mSvidWithFlags[i] & GnssStatus.GNSS_SV_FLAGS_USED_IN_FIX) != 0) {
+ int constellationType =
+ (info.mSvidWithFlags[i] >> GnssStatus.CONSTELLATION_TYPE_SHIFT_WIDTH)
+ & GnssStatus.CONSTELLATION_TYPE_MASK;
+ mGnssMetrics.logConstellationType(constellationType);
+ }
}
if (usedInFixCount > 0) {
meanCn0 /= usedInFixCount;
diff --git a/services/core/java/com/android/server/locksettings/PasswordSlotManager.java b/services/core/java/com/android/server/locksettings/PasswordSlotManager.java
index 686ae2b..5cbd237 100644
--- a/services/core/java/com/android/server/locksettings/PasswordSlotManager.java
+++ b/services/core/java/com/android/server/locksettings/PasswordSlotManager.java
@@ -52,10 +52,12 @@
// This maps each used password slot to the OS image that created it. Password slots are
// integer keys/indices into secure storage. The OS image is recorded as a string. The factory
// image is "host" and GSIs are "gsi<N>" where N >= 1.
- private final Map<Integer, String> mSlotMap;
+ private Map<Integer, String> mSlotMap;
+
+ // Cache the active slots until loadSlotMap() is called.
+ private Set<Integer> mActiveSlots;
public PasswordSlotManager() {
- mSlotMap = loadSlotMap();
}
@VisibleForTesting
@@ -74,6 +76,11 @@
* @throws RuntimeException
*/
public void refreshActiveSlots(Set<Integer> activeSlots) throws RuntimeException {
+ if (mSlotMap == null) {
+ mActiveSlots = new HashSet<Integer>(activeSlots);
+ return;
+ }
+
// Update which slots are owned by the current image.
final HashSet<Integer> slotsToDelete = new HashSet<Integer>();
for (Map.Entry<Integer, String> entry : mSlotMap.entrySet()) {
@@ -100,6 +107,7 @@
* @throws RuntimeException
*/
public void markSlotInUse(int slot) throws RuntimeException {
+ ensureSlotMapLoaded();
if (mSlotMap.containsKey(slot) && !mSlotMap.get(slot).equals(getMode())) {
throw new RuntimeException("password slot " + slot + " is not available");
}
@@ -113,6 +121,7 @@
* @throws RuntimeException
*/
public void markSlotDeleted(int slot) throws RuntimeException {
+ ensureSlotMapLoaded();
if (mSlotMap.containsKey(slot) && mSlotMap.get(slot) != getMode()) {
throw new RuntimeException("password slot " + slot + " cannot be deleted");
}
@@ -126,6 +135,7 @@
* @return Integer set of all used slots.
*/
public Set<Integer> getUsedSlots() {
+ ensureSlotMapLoaded();
return Collections.unmodifiableSet(mSlotMap.keySet());
}
@@ -167,8 +177,21 @@
return new HashMap<Integer, String>();
}
+ private void ensureSlotMapLoaded() {
+ if (mSlotMap == null) {
+ mSlotMap = loadSlotMap();
+ if (mActiveSlots != null) {
+ refreshActiveSlots(mActiveSlots);
+ mActiveSlots = null;
+ }
+ }
+ }
+
@VisibleForTesting
protected void saveSlotMap(OutputStream stream) throws IOException {
+ if (mSlotMap == null) {
+ return;
+ }
final Properties props = new Properties();
for (Map.Entry<Integer, String> entry : mSlotMap.entrySet()) {
props.setProperty(entry.getKey().toString(), entry.getValue());
@@ -177,6 +200,9 @@
}
private void saveSlotMap() {
+ if (mSlotMap == null) {
+ return;
+ }
if (!getSlotMapFile().getParentFile().exists()) {
Slog.w(TAG, "Not saving slot map, " + getSlotMapDir() + " does not exist");
return;
diff --git a/services/core/java/com/android/server/media/AudioPlayerStateMonitor.java b/services/core/java/com/android/server/media/AudioPlayerStateMonitor.java
index 603d7cf..eb706d7 100644
--- a/services/core/java/com/android/server/media/AudioPlayerStateMonitor.java
+++ b/services/core/java/com/android/server/media/AudioPlayerStateMonitor.java
@@ -142,7 +142,8 @@
/**
* Returns the sorted list of UIDs that have had active audio playback. (i.e. playing an
- * audio/video) The UID whose audio playback becomes active at the last comes first.
+ * audio/video) The UID whose audio is currently playing comes first, then the UID whose audio
+ * playback becomes active at the last comes next.
*/
public IntArray getSortedAudioPlaybackClientUids() {
IntArray sortedAudioPlaybackClientUids = new IntArray();
@@ -253,6 +254,26 @@
mSortedAudioPlaybackClientUids.add(0, uid);
}
}
+
+ if (mActiveAudioUids.size() > 0
+ && !mActiveAudioUids.contains(mSortedAudioPlaybackClientUids.get(0))) {
+ int firstActiveUid = -1;
+ int firatActiveUidIndex = -1;
+ for (int i = 1; i < mSortedAudioPlaybackClientUids.size(); ++i) {
+ int uid = mSortedAudioPlaybackClientUids.get(i);
+ if (mActiveAudioUids.contains(uid)) {
+ firatActiveUidIndex = i;
+ firstActiveUid = uid;
+ break;
+ }
+ }
+ for (int i = firatActiveUidIndex; i > 0; --i) {
+ mSortedAudioPlaybackClientUids.set(i,
+ mSortedAudioPlaybackClientUids.get(i - 1));
+ }
+ mSortedAudioPlaybackClientUids.set(0, firstActiveUid);
+ }
+
// Notify the active state change of audio players.
for (AudioPlaybackConfiguration config : configs) {
final int pii = config.getPlayerInterfaceId();
diff --git a/services/core/java/com/android/server/media/MediaRoute2ProviderProxy.java b/services/core/java/com/android/server/media/MediaRoute2ProviderProxy.java
deleted file mode 100644
index d284c60..0000000
--- a/services/core/java/com/android/server/media/MediaRoute2ProviderProxy.java
+++ /dev/null
@@ -1,341 +0,0 @@
-/*
- * Copyright 2019 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.server.media;
-
-import android.content.ComponentName;
-import android.content.Context;
-import android.content.Intent;
-import android.content.ServiceConnection;
-import android.media.IMediaRoute2Callback;
-import android.media.IMediaRoute2Provider;
-import android.media.MediaRoute2ProviderService;
-import android.os.Handler;
-import android.os.IBinder;
-import android.os.IBinder.DeathRecipient;
-import android.os.RemoteException;
-import android.os.UserHandle;
-import android.util.Log;
-import android.util.Slog;
-
-import java.io.PrintWriter;
-import java.lang.ref.WeakReference;
-
-/**
- * Maintains a connection to a particular media route provider service.
- */
-final class MediaRoute2ProviderProxy implements ServiceConnection {
- private static final String TAG = "MediaRoute2ProviderProxy";
- private static final boolean DEBUG = Log.isLoggable(TAG, Log.DEBUG);
-
- private final Context mContext;
- private final ComponentName mComponentName;
- private final int mUserId;
- private final Handler mHandler;
-
- private Callback mCallback;
-
- // Selected Route info
- public int mSelectedUid;
- public String mSelectedRouteId;
-
- // Connection state
- private boolean mRunning;
- private boolean mBound;
- private Connection mActiveConnection;
- private boolean mConnectionReady;
-
- MediaRoute2ProviderProxy(Context context, ComponentName componentName, int userId) {
- mContext = context;
- mComponentName = componentName;
- mUserId = userId;
- mHandler = new Handler();
- }
-
- public void dump(PrintWriter pw, String prefix) {
- pw.println(prefix + "Proxy");
- pw.println(prefix + " mUserId=" + mUserId);
- pw.println(prefix + " mRunning=" + mRunning);
- pw.println(prefix + " mBound=" + mBound);
- pw.println(prefix + " mActiveConnection=" + mActiveConnection);
- pw.println(prefix + " mConnectionReady=" + mConnectionReady);
- }
-
- public void setCallback(Callback callback) {
- mCallback = callback;
- }
-
- public void setSelectedRoute(int uid, String routeId) {
- if (mConnectionReady) {
- mActiveConnection.selectRoute(uid, routeId);
- updateBinding();
- }
- }
-
- public boolean hasComponentName(String packageName, String className) {
- return mComponentName.getPackageName().equals(packageName)
- && mComponentName.getClassName().equals(className);
- }
-
- public String getFlattenedComponentName() {
- return mComponentName.flattenToShortString();
- }
-
- public void start() {
- if (!mRunning) {
- if (DEBUG) {
- Slog.d(TAG, this + ": Starting");
- }
-
- mRunning = true;
- updateBinding();
- }
- }
-
- public void stop() {
- if (mRunning) {
- if (DEBUG) {
- Slog.d(TAG, this + ": Stopping");
- }
-
- mRunning = false;
- updateBinding();
- }
- }
-
- public void rebindIfDisconnected() {
- if (mActiveConnection == null && shouldBind()) {
- unbind();
- bind();
- }
- }
-
- private void updateBinding() {
- if (shouldBind()) {
- bind();
- } else {
- unbind();
- }
- }
-
- private boolean shouldBind() {
- //TODO: binding could be delayed until it's necessary.
- if (mRunning) {
- return true;
- }
- return false;
- }
-
- private void bind() {
- if (!mBound) {
- if (DEBUG) {
- Slog.d(TAG, this + ": Binding");
- }
-
- Intent service = new Intent(MediaRoute2ProviderService.SERVICE_INTERFACE);
- service.setComponent(mComponentName);
- try {
- mBound = mContext.bindServiceAsUser(service, this,
- Context.BIND_AUTO_CREATE | Context.BIND_FOREGROUND_SERVICE,
- new UserHandle(mUserId));
- if (!mBound && DEBUG) {
- Slog.d(TAG, this + ": Bind failed");
- }
- } catch (SecurityException ex) {
- if (DEBUG) {
- Slog.d(TAG, this + ": Bind failed", ex);
- }
- }
- }
- }
-
- private void unbind() {
- if (mBound) {
- if (DEBUG) {
- Slog.d(TAG, this + ": Unbinding");
- }
-
- mBound = false;
- disconnect();
- mContext.unbindService(this);
- }
- }
-
- @Override
- public void onServiceConnected(ComponentName name, IBinder service) {
- if (DEBUG) {
- Slog.d(TAG, this + ": Connected");
- }
-
- if (mBound) {
- disconnect();
-
- IMediaRoute2Provider provider = IMediaRoute2Provider.Stub.asInterface(service);
- if (provider != null) {
- Connection connection = new Connection(provider);
- if (connection.register()) {
- mActiveConnection = connection;
- } else {
- if (DEBUG) {
- Slog.d(TAG, this + ": Registration failed");
- }
- }
- } else {
- Slog.e(TAG, this + ": Service returned invalid remote display provider binder");
- }
- }
- }
-
- @Override
- public void onServiceDisconnected(ComponentName name) {
- if (DEBUG) {
- Slog.d(TAG, this + ": Service disconnected");
- }
- disconnect();
- }
-
- private void onConnectionReady(Connection connection) {
- if (mActiveConnection == connection) {
- mConnectionReady = true;
- }
- }
-
- private void onConnectionDied(Connection connection) {
- if (mActiveConnection == connection) {
- if (DEBUG) {
- Slog.d(TAG, this + ": Service connection died");
- }
- disconnect();
- }
- }
-
- private void onRouteSelected(Connection connection, int uid, String routeId) {
- mSelectedUid = uid;
- mSelectedRouteId = routeId;
-
- if (mActiveConnection == connection) {
- if (DEBUG) {
- Slog.d(TAG, this + ": State changed ");
- }
- mHandler.post(mStateChanged);
- }
- }
-
- private void disconnect() {
- if (mActiveConnection != null) {
- mConnectionReady = false;
- mActiveConnection.dispose();
- mActiveConnection = null;
- }
- }
-
- @Override
- public String toString() {
- return "Service connection " + mComponentName.flattenToShortString();
- }
-
- private final Runnable mStateChanged = new Runnable() {
- @Override
- public void run() {
- if (mCallback != null) {
- mCallback.onProviderStateChanged(MediaRoute2ProviderProxy.this);
- }
- }
- };
-
- public interface Callback {
- void onProviderStateChanged(MediaRoute2ProviderProxy provider);
- }
-
- private final class Connection implements DeathRecipient {
- private final IMediaRoute2Provider mProvider;
- private final ProviderCallback mCallback;
-
- Connection(IMediaRoute2Provider provider) {
- mProvider = provider;
- mCallback = new ProviderCallback(this);
- }
-
- public boolean register() {
- try {
- mProvider.asBinder().linkToDeath(this, 0);
- mProvider.setCallback(mCallback);
- mHandler.post(new Runnable() {
- @Override
- public void run() {
- onConnectionReady(Connection.this);
- }
- });
- return true;
- } catch (RemoteException ex) {
- binderDied();
- }
- return false;
- }
-
- public void dispose() {
- mProvider.asBinder().unlinkToDeath(this, 0);
- mCallback.dispose();
- }
-
- public void selectRoute(int uid, String id) {
- try {
- mProvider.selectRoute(uid, id);
- } catch (RemoteException ex) {
- Slog.e(TAG, "Failed to deliver request to set discovery mode.", ex);
- }
- }
-
- @Override
- public void binderDied() {
- mHandler.post(new Runnable() {
- @Override
- public void run() {
- onConnectionDied(Connection.this);
- }
- });
- }
-
- void postRouteSelected(int uid, String routeId) {
- mHandler.post(new Runnable() {
- @Override
- public void run() {
- onRouteSelected(Connection.this, uid, routeId);
- }
- });
- }
- }
-
- private static final class ProviderCallback extends IMediaRoute2Callback.Stub {
- private final WeakReference<Connection> mConnectionRef;
-
- ProviderCallback(Connection connection) {
- mConnectionRef = new WeakReference<Connection>(connection);
- }
-
- public void dispose() {
- mConnectionRef.clear();
- }
-
- @Override
- public void onRouteSelected(int uid, String routeId) throws RemoteException {
- Connection connection = mConnectionRef.get();
- if (connection != null) {
- connection.postRouteSelected(uid, routeId);
- }
- }
- }
-}
diff --git a/services/core/java/com/android/server/media/MediaRoute2ProviderWatcher.java b/services/core/java/com/android/server/media/MediaRoute2ProviderWatcher.java
deleted file mode 100644
index 08d8c58..0000000
--- a/services/core/java/com/android/server/media/MediaRoute2ProviderWatcher.java
+++ /dev/null
@@ -1,176 +0,0 @@
-/*
- * Copyright 2019 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.server.media;
-
-import android.content.BroadcastReceiver;
-import android.content.ComponentName;
-import android.content.Context;
-import android.content.Intent;
-import android.content.IntentFilter;
-import android.content.pm.PackageManager;
-import android.content.pm.ResolveInfo;
-import android.content.pm.ServiceInfo;
-import android.media.MediaRoute2ProviderService;
-import android.os.Handler;
-import android.os.UserHandle;
-import android.util.Log;
-import android.util.Slog;
-
-import java.io.PrintWriter;
-import java.util.ArrayList;
-import java.util.Collections;
-
-/**
- */
-final class MediaRoute2ProviderWatcher {
- private static final String TAG = "MediaRouteProvider"; // max. 23 chars
- private static final boolean DEBUG = Log.isLoggable(TAG, Log.DEBUG);
-
- private final Context mContext;
- private final Callback mCallback;
- private final Handler mHandler;
- private final int mUserId;
- private final PackageManager mPackageManager;
-
- private final ArrayList<MediaRoute2ProviderProxy> mProviders = new ArrayList<>();
- private boolean mRunning;
-
- MediaRoute2ProviderWatcher(Context context,
- Callback callback, Handler handler, int userId) {
- mContext = context;
- mCallback = callback;
- mHandler = handler;
- mUserId = userId;
- mPackageManager = context.getPackageManager();
- }
-
- public void dump(PrintWriter pw, String prefix) {
- pw.println(prefix + "Watcher");
- pw.println(prefix + " mUserId=" + mUserId);
- pw.println(prefix + " mRunning=" + mRunning);
- pw.println(prefix + " mProviders.size()=" + mProviders.size());
- }
-
- public void start() {
- if (!mRunning) {
- mRunning = true;
-
- IntentFilter filter = new IntentFilter();
- filter.addAction(Intent.ACTION_PACKAGE_ADDED);
- filter.addAction(Intent.ACTION_PACKAGE_REMOVED);
- filter.addAction(Intent.ACTION_PACKAGE_CHANGED);
- filter.addAction(Intent.ACTION_PACKAGE_REPLACED);
- filter.addAction(Intent.ACTION_PACKAGE_RESTARTED);
- filter.addDataScheme("package");
- mContext.registerReceiverAsUser(mScanPackagesReceiver,
- new UserHandle(mUserId), filter, null, mHandler);
-
- // Scan packages.
- // Also has the side-effect of restarting providers if needed.
- mHandler.post(mScanPackagesRunnable);
- }
- }
-
- public void stop() {
- if (mRunning) {
- mRunning = false;
-
- mContext.unregisterReceiver(mScanPackagesReceiver);
- mHandler.removeCallbacks(mScanPackagesRunnable);
-
- // Stop all providers.
- for (int i = mProviders.size() - 1; i >= 0; i--) {
- mProviders.get(i).stop();
- }
- }
- }
-
- private void scanPackages() {
- if (!mRunning) {
- return;
- }
-
- // Add providers for all new services.
- // Reorder the list so that providers left at the end will be the ones to remove.
- int targetIndex = 0;
- Intent intent = new Intent(MediaRoute2ProviderService.SERVICE_INTERFACE);
- for (ResolveInfo resolveInfo : mPackageManager.queryIntentServicesAsUser(
- intent, 0, mUserId)) {
- ServiceInfo serviceInfo = resolveInfo.serviceInfo;
- if (serviceInfo != null) {
- int sourceIndex = findProvider(serviceInfo.packageName, serviceInfo.name);
- if (sourceIndex < 0) {
- MediaRoute2ProviderProxy provider =
- new MediaRoute2ProviderProxy(mContext,
- new ComponentName(serviceInfo.packageName, serviceInfo.name),
- mUserId);
- provider.start();
- mProviders.add(targetIndex++, provider);
- mCallback.addProvider(provider);
- } else if (sourceIndex >= targetIndex) {
- MediaRoute2ProviderProxy provider = mProviders.get(sourceIndex);
- provider.start(); // restart the provider if needed
- provider.rebindIfDisconnected();
- Collections.swap(mProviders, sourceIndex, targetIndex++);
- }
- }
- }
-
- // Remove providers for missing services.
- if (targetIndex < mProviders.size()) {
- for (int i = mProviders.size() - 1; i >= targetIndex; i--) {
- MediaRoute2ProviderProxy provider = mProviders.get(i);
- mCallback.removeProvider(provider);
- mProviders.remove(provider);
- provider.stop();
- }
- }
- }
-
- private int findProvider(String packageName, String className) {
- int count = mProviders.size();
- for (int i = 0; i < count; i++) {
- MediaRoute2ProviderProxy provider = mProviders.get(i);
- if (provider.hasComponentName(packageName, className)) {
- return i;
- }
- }
- return -1;
- }
-
- private final BroadcastReceiver mScanPackagesReceiver = new BroadcastReceiver() {
- @Override
- public void onReceive(Context context, Intent intent) {
- if (DEBUG) {
- Slog.d(TAG, "Received package manager broadcast: " + intent);
- }
- scanPackages();
- }
- };
-
- private final Runnable mScanPackagesRunnable = new Runnable() {
- @Override
- public void run() {
- scanPackages();
- }
- };
-
- public interface Callback {
- void addProvider(MediaRoute2ProviderProxy provider);
- void removeProvider(MediaRoute2ProviderProxy provider);
- }
-}
diff --git a/services/core/java/com/android/server/media/MediaRouterService.java b/services/core/java/com/android/server/media/MediaRouterService.java
index a43533f..23d3ce0 100644
--- a/services/core/java/com/android/server/media/MediaRouterService.java
+++ b/services/core/java/com/android/server/media/MediaRouterService.java
@@ -30,7 +30,6 @@
import android.media.AudioSystem;
import android.media.IAudioRoutesObserver;
import android.media.IAudioService;
-import android.media.IMediaRouter2ManagerClient;
import android.media.IMediaRouterClient;
import android.media.IMediaRouterService;
import android.media.MediaRouter;
@@ -50,7 +49,6 @@
import android.util.ArrayMap;
import android.util.IntArray;
import android.util.Log;
-import android.util.Pair;
import android.util.Slog;
import android.util.SparseArray;
import android.util.TimeUtils;
@@ -98,7 +96,6 @@
private final Object mLock = new Object();
private final SparseArray<UserRecord> mUserRecords = new SparseArray<>();
private final ArrayMap<IBinder, ClientRecord> mAllClientRecords = new ArrayMap<>();
- private final ArrayMap<IBinder, ManagerRecord> mAllManagerRecords = new ArrayMap<>();
private int mCurrentUserId = -1;
private final IAudioService mAudioService;
private final AudioPlayerStateMonitor mAudioPlayerStateMonitor;
@@ -307,22 +304,6 @@
// Binder call
@Override
- public void setControlCategories(IMediaRouterClient client, List<String> categories) {
- if (client == null) {
- throw new IllegalArgumentException("client must not be null");
- }
- final long token = Binder.clearCallingIdentity();
- try {
- synchronized (mLock) {
- setControlCategoriesLocked(client, categories);
- }
- } finally {
- Binder.restoreCallingIdentity(token);
- }
- }
-
- // Binder call
- @Override
public void setDiscoveryRequest(IMediaRouterClient client,
int routeTypes, boolean activeScan) {
if (client == null) {
@@ -421,65 +402,6 @@
}
}
- // Binder call
- @Override
- public void registerManagerAsUser(IMediaRouter2ManagerClient client,
- String packageName, int userId) {
- if (client == null) {
- throw new IllegalArgumentException("client must not be null");
- }
- //TODO: should check permission
- final boolean trusted = true;
-
- final int uid = Binder.getCallingUid();
- if (!validatePackageName(uid, packageName)) {
- throw new SecurityException("packageName must match the calling uid");
- }
-
- final int pid = Binder.getCallingPid();
- final int resolvedUserId = ActivityManager.handleIncomingUser(pid, uid, userId,
- false /*allowAll*/, true /*requireFull*/, "registerManagerAsUser", packageName);
- final long token = Binder.clearCallingIdentity();
- try {
- synchronized (mLock) {
- registerManagerLocked(client, uid, pid, packageName, resolvedUserId, trusted);
- }
- } finally {
- Binder.restoreCallingIdentity(token);
- }
- }
-
- // Binder call
- @Override
- public void unregisterManager(IMediaRouter2ManagerClient client) {
- if (client == null) {
- throw new IllegalArgumentException("client must not be null");
- }
-
- final long token = Binder.clearCallingIdentity();
- try {
- synchronized (mLock) {
- unregisterManagerLocked(client, false);
- }
- } finally {
- Binder.restoreCallingIdentity(token);
- }
- }
-
- // Binder call
- @Override
- public void setRemoteRoute(IMediaRouter2ManagerClient client,
- int uid, String routeId, boolean explicit) {
- final long token = Binder.clearCallingIdentity();
- try {
- synchronized (mLock) {
- setRemoteRouteLocked(client, uid, routeId, explicit);
- }
- } finally {
- Binder.restoreCallingIdentity(token);
- }
- }
-
void restoreBluetoothA2dp() {
try {
boolean a2dpOn;
@@ -551,12 +473,6 @@
}
}
- void clientDied(ManagerRecord managerRecord) {
- synchronized (mLock) {
- unregisterManagerLocked(managerRecord.mClient, true);
- }
- }
-
private void registerClientLocked(IMediaRouterClient client,
int uid, int pid, String packageName, int userId, boolean trusted) {
final IBinder binder = client.asBinder();
@@ -604,17 +520,6 @@
return null;
}
- private void setControlCategoriesLocked(IMediaRouterClient client, List<String> categories) {
- final IBinder binder = client.asBinder();
- ClientRecord clientRecord = mAllClientRecords.get(binder);
-
- if (clientRecord != null) {
- clientRecord.mControlCategories = categories;
- clientRecord.mUserRecord.mHandler.obtainMessage(
- UserHandler.MSG_UPDATE_CLIENT_USAGE, clientRecord).sendToTarget();
- }
- }
-
private void setDiscoveryRequestLocked(IMediaRouterClient client,
int routeTypes, boolean activeScan) {
final IBinder binder = client.asBinder();
@@ -668,63 +573,6 @@
}
}
- private void registerManagerLocked(IMediaRouter2ManagerClient client,
- int uid, int pid, String packageName, int userId, boolean trusted) {
- final IBinder binder = client.asBinder();
- ManagerRecord managerRecord = mAllManagerRecords.get(binder);
- if (managerRecord == null) {
- boolean newUser = false;
- UserRecord userRecord = mUserRecords.get(userId);
- if (userRecord == null) {
- userRecord = new UserRecord(userId);
- newUser = true;
- }
- managerRecord = new ManagerRecord(userRecord, client, uid, pid, packageName, trusted);
- try {
- binder.linkToDeath(managerRecord, 0);
- } catch (RemoteException ex) {
- throw new RuntimeException("Media router client died prematurely.", ex);
- }
-
- if (newUser) {
- mUserRecords.put(userId, userRecord);
- initializeUserLocked(userRecord);
- }
-
- userRecord.mManagerRecords.add(managerRecord);
- mAllManagerRecords.put(binder, managerRecord);
-
- // send client usage to manager
- final int clientCount = userRecord.mClientRecords.size();
- for (int i = 0; i < clientCount; i++) {
- userRecord.mHandler.obtainMessage(UserHandler.MSG_UPDATE_CLIENT_USAGE,
- userRecord.mClientRecords.get(i)).sendToTarget();
- }
- }
- }
-
- private void unregisterManagerLocked(IMediaRouter2ManagerClient client, boolean died) {
- ManagerRecord clientRecord = mAllManagerRecords.remove(client.asBinder());
- if (clientRecord != null) {
- UserRecord userRecord = clientRecord.mUserRecord;
- userRecord.mManagerRecords.remove(clientRecord);
- clientRecord.dispose();
- disposeUserIfNeededLocked(userRecord); // since client removed from user
- }
- }
-
- private void setRemoteRouteLocked(IMediaRouter2ManagerClient client,
- int uid, String routeId, boolean explicit) {
- ManagerRecord managerRecord = mAllManagerRecords.get(client.asBinder());
- if (managerRecord != null) {
- if (explicit && managerRecord.mTrusted) {
- Pair<Integer, String> obj = new Pair<>(uid, routeId);
- managerRecord.mUserRecord.mHandler.obtainMessage(
- UserHandler.MSG_SELECT_REMOTE_ROUTE, obj).sendToTarget();
- }
- }
- }
-
private void requestSetVolumeLocked(IMediaRouterClient client,
String routeId, int volume) {
final IBinder binder = client.asBinder();
@@ -817,46 +665,6 @@
}
}
- final class ManagerRecord implements DeathRecipient {
- public final UserRecord mUserRecord;
- public final IMediaRouter2ManagerClient mClient;
- public final int mUid;
- public final int mPid;
- public final String mPackageName;
- public final boolean mTrusted;
-
- ManagerRecord(UserRecord userRecord, IMediaRouter2ManagerClient client,
- int uid, int pid, String packageName, boolean trusted) {
- mUserRecord = userRecord;
- mClient = client;
- mUid = uid;
- mPid = pid;
- mPackageName = packageName;
- mTrusted = trusted;
- }
-
- public void dispose() {
- mClient.asBinder().unlinkToDeath(this, 0);
- }
-
- @Override
- public void binderDied() {
- clientDied(this);
- }
-
- public void dump(PrintWriter pw, String prefix) {
- pw.println(prefix + this);
-
- final String indent = prefix + " ";
- pw.println(indent + "mTrusted=" + mTrusted);
- }
-
- @Override
- public String toString() {
- return "Client " + mPackageName + " (pid " + mPid + ")";
- }
- }
-
/**
* Information about a particular client of the media router.
* The contents of this object is guarded by mLock.
@@ -868,7 +676,6 @@
public final int mPid;
public final String mPackageName;
public final boolean mTrusted;
- public List<String> mControlCategories;
public int mRouteTypes;
public boolean mActiveScan;
@@ -919,8 +726,7 @@
*/
final class UserRecord {
public final int mUserId;
- public final ArrayList<ClientRecord> mClientRecords = new ArrayList<>();
- public final ArrayList<ManagerRecord> mManagerRecords = new ArrayList<>();
+ public final ArrayList<ClientRecord> mClientRecords = new ArrayList<ClientRecord>();
public final UserHandler mHandler;
public MediaRouterClientState mRouterState;
@@ -975,9 +781,7 @@
*/
static final class UserHandler extends Handler
implements RemoteDisplayProviderWatcher.Callback,
- RemoteDisplayProviderProxy.Callback,
- MediaRoute2ProviderWatcher.Callback,
- MediaRoute2ProviderProxy.Callback {
+ RemoteDisplayProviderProxy.Callback {
public static final int MSG_START = 1;
public static final int MSG_STOP = 2;
public static final int MSG_UPDATE_DISCOVERY_REQUEST = 3;
@@ -988,9 +792,6 @@
private static final int MSG_UPDATE_CLIENT_STATE = 8;
private static final int MSG_CONNECTION_TIMED_OUT = 9;
- private static final int MSG_SELECT_REMOTE_ROUTE = 10;
- private static final int MSG_UPDATE_CLIENT_USAGE = 11;
-
private static final int TIMEOUT_REASON_NOT_AVAILABLE = 1;
private static final int TIMEOUT_REASON_CONNECTION_LOST = 2;
private static final int TIMEOUT_REASON_WAITING_FOR_CONNECTING = 3;
@@ -1006,17 +807,11 @@
private final MediaRouterService mService;
private final UserRecord mUserRecord;
private final RemoteDisplayProviderWatcher mWatcher;
- private final MediaRoute2ProviderWatcher mMediaWatcher;
-
private final ArrayList<ProviderRecord> mProviderRecords =
new ArrayList<ProviderRecord>();
private final ArrayList<IMediaRouterClient> mTempClients =
new ArrayList<IMediaRouterClient>();
- private final ArrayList<MediaRoute2ProviderProxy> mMediaProviders =
- new ArrayList<>();
- private final ArrayList<IMediaRouter2ManagerClient> mTempManagers = new ArrayList<>();
-
private boolean mRunning;
private int mDiscoveryMode = RemoteDisplayState.DISCOVERY_MODE_NONE;
private RouteRecord mSelectedRouteRecord;
@@ -1031,8 +826,6 @@
mUserRecord = userRecord;
mWatcher = new RemoteDisplayProviderWatcher(service.mContext, this,
this, mUserRecord.mUserId);
- mMediaWatcher = new MediaRoute2ProviderWatcher(service.mContext, this,
- this, mUserRecord.mUserId);
}
@Override
@@ -1074,15 +867,6 @@
connectionTimedOut();
break;
}
- case MSG_SELECT_REMOTE_ROUTE: {
- Pair<Integer, String> obj = (Pair<Integer, String>) msg.obj;
- selectRemoteRoute(obj.first, obj.second);
- break;
- }
- case MSG_UPDATE_CLIENT_USAGE: {
- updateClientUsage((ClientRecord) msg.obj);
- break;
- }
}
}
@@ -1114,7 +898,6 @@
if (!mRunning) {
mRunning = true;
mWatcher.start(); // also starts all providers
- mMediaWatcher.start();
}
}
@@ -1123,7 +906,6 @@
mRunning = false;
unselectSelectedRoute();
mWatcher.stop(); // also stops all providers
- mMediaWatcher.stop();
}
}
@@ -1255,26 +1037,6 @@
}
}
- @Override
- public void addProvider(MediaRoute2ProviderProxy provider) {
- provider.setCallback(this);
- mMediaProviders.add(provider);
- }
-
- @Override
- public void removeProvider(MediaRoute2ProviderProxy provider) {
- mMediaProviders.remove(provider);
- }
-
- @Override
- public void onProviderStateChanged(MediaRoute2ProviderProxy provider) {
- updateProvider(provider);
- }
-
- private void updateProvider(MediaRoute2ProviderProxy provider) {
- scheduleUpdateClientState();
- }
-
/**
* This function is called whenever the state of the selected route may have changed.
* It checks the state and updates timeouts or unselects the route as appropriate.
@@ -1385,17 +1147,6 @@
unselectSelectedRoute();
}
- private void selectRemoteRoute(int uid, String routeId) {
- if (routeId != null) {
- final int providerCount = mMediaProviders.size();
-
- //TODO: should find proper provider (currently assumes a single provider)
- for (int i = 0; i < providerCount; ++i) {
- mMediaProviders.get(i).setSelectedRoute(uid, routeId);
- }
- }
- }
-
private void scheduleUpdateClientState() {
if (!mClientStateUpdateScheduled) {
mClientStateUpdateScheduled = true;
@@ -1413,15 +1164,6 @@
mProviderRecords.get(i).appendClientState(routerState);
}
- //TODO: send provider info
- int selectedUid = 0;
- String selectedRouteId = null;
- final int mediaCount = mMediaProviders.size();
- for (int i = 0; i < mediaCount; i++) {
- selectedUid = mMediaProviders.get(i).mSelectedUid;
- selectedRouteId = mMediaProviders.get(i).mSelectedRouteId;
- }
-
try {
synchronized (mService.mLock) {
// Update the UserRecord.
@@ -1432,11 +1174,6 @@
for (int i = 0; i < count; i++) {
mTempClients.add(mUserRecord.mClientRecords.get(i).mClient);
}
-
- final int count2 = mUserRecord.mManagerRecords.size();
- for (int i = 0; i < count2; i++) {
- mTempManagers.add(mUserRecord.mManagerRecords.get(i).mClient);
- }
}
// Notify all clients (outside of the lock).
@@ -1448,39 +1185,9 @@
Slog.w(TAG, "Failed to call onStateChanged. Client probably died.");
}
}
- //TODO: Call proper callbacks when provider descriptor is implemented.
- final int count2 = mTempManagers.size();
- for (int i = 0; i < count2; i++) {
- try {
- mTempManagers.get(i).onRouteSelected(selectedUid, selectedRouteId);
- } catch (RemoteException ex) {
- Slog.w(TAG, "Failed to call onStateChanged. Manager probably died.", ex);
- }
- }
} finally {
// Clear the list in preparation for the next time.
mTempClients.clear();
- mTempManagers.clear();
- }
- }
-
- private void updateClientUsage(ClientRecord clientRecord) {
- List<IMediaRouter2ManagerClient> managers = new ArrayList<>();
- synchronized (mService.mLock) {
- final int count = mUserRecord.mManagerRecords.size();
- for (int i = 0; i < count; i++) {
- managers.add(mUserRecord.mManagerRecords.get(i).mClient);
- }
- }
- final int count = managers.size();
- for (int i = 0; i < count; i++) {
- try {
- managers.get(i).onControlCategoriesChanged(clientRecord.mUid,
- clientRecord.mControlCategories);
- } catch (RemoteException ex) {
- Slog.w(TAG, "Failed to call onControlCategoriesChanged. "
- + "Manager probably died.", ex);
- }
}
}
@@ -1867,5 +1574,4 @@
}
}
}
-
}
diff --git a/services/core/java/com/android/server/media/MediaSessionServiceImpl.java b/services/core/java/com/android/server/media/MediaSessionServiceImpl.java
index de36dea..a5f2217 100644
--- a/services/core/java/com/android/server/media/MediaSessionServiceImpl.java
+++ b/services/core/java/com/android/server/media/MediaSessionServiceImpl.java
@@ -171,7 +171,7 @@
mAudioPlayerStateMonitor = AudioPlayerStateMonitor.getInstance(mContext);
mAudioPlayerStateMonitor.registerListener(
(config, isRemoved) -> {
- if (isRemoved || !config.isActive() || config.getPlayerType()
+ if (config.getPlayerType()
== AudioPlaybackConfiguration.PLAYER_TYPE_JAM_SOUNDPOOL) {
return;
}
@@ -1037,8 +1037,9 @@
// it's closed.
// TODO: Keep controller as well for better readability
// because the GC behavior isn't straightforward.
- MediaController2 controller = new MediaController2(mContext, sessionToken,
- new HandlerExecutor(mHandler), callback);
+ MediaController2 controller = new MediaController2.Builder(mContext, sessionToken)
+ .setControllerCallback(new HandlerExecutor(mHandler), callback)
+ .build();
} finally {
Binder.restoreCallingIdentity(token);
}
diff --git a/services/core/java/com/android/server/notification/NotificationManagerService.java b/services/core/java/com/android/server/notification/NotificationManagerService.java
index 7f1b25ca..ee2e4f5 100644
--- a/services/core/java/com/android/server/notification/NotificationManagerService.java
+++ b/services/core/java/com/android/server/notification/NotificationManagerService.java
@@ -455,6 +455,7 @@
private int mAutoGroupAtCount;
private boolean mIsTelevision;
private boolean mIsAutomotive;
+ private boolean mNotificationEffectsEnabledForAutomotive;
private MetricsLogger mMetricsLogger;
private TriPredicate<String, Integer, String> mAllowedManagedServicePackages;
@@ -1686,6 +1687,8 @@
mIsAutomotive =
mPackageManagerClient.hasSystemFeature(PackageManager.FEATURE_AUTOMOTIVE, 0);
+ mNotificationEffectsEnabledForAutomotive =
+ resources.getBoolean(R.bool.config_enableServerNotificationEffectsForAutomotive);
mPreferencesHelper.lockChannelsForOEM(getContext().getResources().getStringArray(
com.android.internal.R.array.config_nonBlockableNotificationPackages));
@@ -5560,6 +5563,9 @@
@VisibleForTesting
@GuardedBy("mNotificationLock")
void buzzBeepBlinkLocked(NotificationRecord record) {
+ if (mIsAutomotive && !mNotificationEffectsEnabledForAutomotive) {
+ return;
+ }
boolean buzz = false;
boolean beep = false;
boolean blink = false;
diff --git a/services/core/java/com/android/server/om/OverlayManagerServiceImpl.java b/services/core/java/com/android/server/om/OverlayManagerServiceImpl.java
index ec53e98..3a84b1e 100644
--- a/services/core/java/com/android/server/om/OverlayManagerServiceImpl.java
+++ b/services/core/java/com/android/server/om/OverlayManagerServiceImpl.java
@@ -452,10 +452,7 @@
final OverlayInfo overlayInfo = mSettings.getOverlayInfo(packageName, userId);
if (mSettings.remove(packageName, userId)) {
removeIdmapIfPossible(overlayInfo);
- if (overlayInfo.isEnabled()) {
- // Only trigger updates if the overlay was enabled.
- mListener.onOverlaysChanged(overlayInfo.targetPackageName, userId);
- }
+ mListener.onOverlaysChanged(overlayInfo.targetPackageName, userId);
}
} catch (OverlayManagerSettings.BadKeyException e) {
Slog.e(TAG, "failed to remove overlay", e);
diff --git a/services/core/java/com/android/server/pm/PackageInstallerService.java b/services/core/java/com/android/server/pm/PackageInstallerService.java
index 7f48970..e6313d9 100644
--- a/services/core/java/com/android/server/pm/PackageInstallerService.java
+++ b/services/core/java/com/android/server/pm/PackageInstallerService.java
@@ -813,7 +813,7 @@
@Override
public void uninstall(VersionedPackage versionedPackage, String callerPackageName, int flags,
- IntentSender statusReceiver, int userId) throws RemoteException {
+ IntentSender statusReceiver, int userId) {
final int callingUid = Binder.getCallingUid();
mPermissionManager.enforceCrossUserPermission(callingUid, userId, true, true, "uninstall");
if ((callingUid != Process.SHELL_UID) && (callingUid != Process.ROOT_UID)) {
@@ -952,6 +952,9 @@
@Override
public void onUserActionRequired(Intent intent) {
+ if (mTarget == null) {
+ return;
+ }
final Intent fillIn = new Intent();
fillIn.putExtra(PackageInstaller.EXTRA_PACKAGE_NAME, mPackageName);
fillIn.putExtra(PackageInstaller.EXTRA_STATUS,
@@ -972,6 +975,9 @@
SystemMessage.NOTE_PACKAGE_STATE,
mNotification);
}
+ if (mTarget == null) {
+ return;
+ }
final Intent fillIn = new Intent();
fillIn.putExtra(PackageInstaller.EXTRA_PACKAGE_NAME, mPackageName);
fillIn.putExtra(PackageInstaller.EXTRA_STATUS,
diff --git a/services/core/java/com/android/server/pm/PackageManagerService.java b/services/core/java/com/android/server/pm/PackageManagerService.java
index c68974b..7b418b5 100644
--- a/services/core/java/com/android/server/pm/PackageManagerService.java
+++ b/services/core/java/com/android/server/pm/PackageManagerService.java
@@ -1990,31 +1990,31 @@
// Work that needs to happen on first install within each user
if (firstUserIds != null && firstUserIds.length > 0) {
- synchronized (mPackages) {
- for (int userId : firstUserIds) {
- // If this app is a browser and it's newly-installed for some
- // users, clear any default-browser state in those users. The
- // app's nature doesn't depend on the user, so we can just check
- // its browser nature in any user and generalize.
- if (packageIsBrowser(packageName, userId)) {
- // If this browser is restored from user's backup, do not clear
- // default-browser state for this user
+ for (int userId : firstUserIds) {
+ // If this app is a browser and it's newly-installed for some
+ // users, clear any default-browser state in those users. The
+ // app's nature doesn't depend on the user, so we can just check
+ // its browser nature in any user and generalize.
+ if (packageIsBrowser(packageName, userId)) {
+ // If this browser is restored from user's backup, do not clear
+ // default-browser state for this user
+ synchronized (mPackages) {
final PackageSetting pkgSetting = mSettings.mPackages.get(packageName);
if (pkgSetting.getInstallReason(userId)
!= PackageManager.INSTALL_REASON_DEVICE_RESTORE) {
setDefaultBrowserAsyncLPw(null, userId);
}
}
-
- // We may also need to apply pending (restored) runtime permission grants
- // within these users.
- mPermissionManager.restoreDelayedRuntimePermissions(packageName,
- UserHandle.of(userId));
-
- // Persistent preferred activity might have came into effect due to this
- // install.
- updateDefaultHomeLPw(userId);
}
+
+ // We may also need to apply pending (restored) runtime permission grants
+ // within these users.
+ mPermissionManager.restoreDelayedRuntimePermissions(packageName,
+ UserHandle.of(userId));
+
+ // Persistent preferred activity might have came into effect due to this
+ // install.
+ updateDefaultHomeNotLocked(userId);
}
}
@@ -5158,7 +5158,7 @@
getPackagesUsingSharedLibraryLPr(libInfo, flags, userId),
(libInfo.getDependencies() == null
? null
- : new ArrayList(libInfo.getDependencies())));
+ : new ArrayList<>(libInfo.getDependencies())));
if (result == null) {
result = new ArrayList<>();
@@ -6475,8 +6475,8 @@
final List<ResolveInfo> query = queryIntentActivitiesInternal(intent, resolvedType, flags,
userId);
// Find any earlier preferred or last chosen entries and nuke them
- findPreferredActivity(intent, resolvedType,
- flags, query, 0, false, true, false, userId);
+ findPreferredActivityNotLocked(
+ intent, resolvedType, flags, query, 0, false, true, false, userId);
// Add the new activity as the last chosen for this filter
addPreferredActivityInternal(filter, match, null, activity, false, userId,
"Setting last chosen");
@@ -6491,8 +6491,8 @@
if (DEBUG_PREFERRED) Log.v(TAG, "Querying last chosen activity for " + intent);
final List<ResolveInfo> query = queryIntentActivitiesInternal(intent, resolvedType, flags,
userId);
- return findPreferredActivity(intent, resolvedType, flags, query, 0,
- false, false, false, userId);
+ return findPreferredActivityNotLocked(
+ intent, resolvedType, flags, query, 0, false, false, false, userId);
}
/**
@@ -6605,7 +6605,7 @@
}
// If we have saved a preference for a preferred activity for
// this Intent, use that.
- ResolveInfo ri = findPreferredActivity(intent, resolvedType,
+ ResolveInfo ri = findPreferredActivityNotLocked(intent, resolvedType,
flags, query, r0.priority, true, false, debug, userId);
if (ri != null) {
return ri;
@@ -6744,9 +6744,14 @@
}
// TODO: handle preferred activities missing while user has amnesia
- ResolveInfo findPreferredActivity(Intent intent, String resolvedType, int flags,
+ /** <b>must not hold {@link #mPackages}</b> */
+ ResolveInfo findPreferredActivityNotLocked(Intent intent, String resolvedType, int flags,
List<ResolveInfo> query, int priority, boolean always,
boolean removeMatches, boolean debug, int userId) {
+ if (Thread.holdsLock(mPackages)) {
+ Slog.wtf(TAG, "Calling thread " + Thread.currentThread().getName()
+ + " is holding mPackages", new Throwable());
+ }
if (!sUserManager.exists(userId)) return null;
final int callingUid = Binder.getCallingUid();
// Do NOT hold the packages lock; this calls up into the settings provider which
@@ -18599,10 +18604,10 @@
int removedAppId = -1;
// writer
- synchronized (mPackages) {
- boolean installedStateChanged = false;
- if (deletedPs != null) {
- if ((flags&PackageManager.DELETE_KEEP_DATA) == 0) {
+ boolean installedStateChanged = false;
+ if (deletedPs != null) {
+ if ((flags & PackageManager.DELETE_KEEP_DATA) == 0) {
+ synchronized (mPackages) {
clearIntentFilterVerificationsLPw(deletedPs.name, UserHandle.USER_ALL);
clearDefaultBrowserIfNeeded(packageName);
mSettings.mKeySetManagerService.removeAppKeySetDataLPw(packageName);
@@ -18633,26 +18638,34 @@
}
}
}
- clearPackagePreferredActivitiesLPw(deletedPs.name, UserHandle.USER_ALL);
}
- // make sure to preserve per-user disabled state if this removal was just
- // a downgrade of a system app to the factory package
- if (allUserHandles != null && outInfo != null && outInfo.origUsers != null) {
- if (DEBUG_REMOVE) {
- Slog.d(TAG, "Propagating install state across downgrade");
- }
- for (int userId : allUserHandles) {
- final boolean installed = ArrayUtils.contains(outInfo.origUsers, userId);
- if (DEBUG_REMOVE) {
- Slog.d(TAG, " user " + userId + " => " + installed);
- }
- if (installed != deletedPs.getInstalled(userId)) {
- installedStateChanged = true;
- }
- deletedPs.setInstalled(installed, userId);
- }
+ final SparseBooleanArray changedUsers = new SparseBooleanArray();
+ clearPackagePreferredActivitiesLPw(
+ deletedPs.name, changedUsers, UserHandle.USER_ALL);
+ if (changedUsers.size() > 0) {
+ updateDefaultHomeNotLocked(changedUsers);
+ postPreferredActivityChangedBroadcast(UserHandle.USER_ALL);
}
}
+ // make sure to preserve per-user disabled state if this removal was just
+ // a downgrade of a system app to the factory package
+ if (allUserHandles != null && outInfo != null && outInfo.origUsers != null) {
+ if (DEBUG_REMOVE) {
+ Slog.d(TAG, "Propagating install state across downgrade");
+ }
+ for (int userId : allUserHandles) {
+ final boolean installed = ArrayUtils.contains(outInfo.origUsers, userId);
+ if (DEBUG_REMOVE) {
+ Slog.d(TAG, " user " + userId + " => " + installed);
+ }
+ if (installed != deletedPs.getInstalled(userId)) {
+ installedStateChanged = true;
+ }
+ deletedPs.setInstalled(installed, userId);
+ }
+ }
+ }
+ synchronized (mPackages) {
// can downgrade to reader
if (writeSettings) {
// Save settings now
@@ -19138,22 +19151,22 @@
final UserHandle user = action.user;
final int flags = action.flags;
final boolean systemApp = isSystemApp(ps);
- synchronized (mPackages) {
- if (ps.parentPackageName != null
- && (!systemApp || (flags & PackageManager.DELETE_SYSTEM_APP) != 0)) {
- if (DEBUG_REMOVE) {
- Slog.d(TAG, "Uninstalled child package:" + packageName + " for user:"
- + ((user == null) ? UserHandle.USER_ALL : user));
- }
- final int removedUserId = (user != null) ? user.getIdentifier()
- : UserHandle.USER_ALL;
+ if (ps.parentPackageName != null
+ && (!systemApp || (flags & PackageManager.DELETE_SYSTEM_APP) != 0)) {
+ if (DEBUG_REMOVE) {
+ Slog.d(TAG, "Uninstalled child package:" + packageName + " for user:"
+ + ((user == null) ? UserHandle.USER_ALL : user));
+ }
+ final int removedUserId = (user != null) ? user.getIdentifier()
+ : UserHandle.USER_ALL;
- clearPackageStateForUserLIF(ps, removedUserId, outInfo, flags);
+ clearPackageStateForUserLIF(ps, removedUserId, outInfo, flags);
+ synchronized (mPackages) {
markPackageUninstalledForUserLPw(ps, user);
scheduleWritePackageRestrictionsLocked(user);
- return;
}
+ return;
}
final int userId = user == null ? UserHandle.USER_ALL : user.getIdentifier();
@@ -19167,6 +19180,7 @@
// its data. If this is a system app, we only allow this to happen if
// they have set the special DELETE_SYSTEM_APP which requests different
// semantics than normal for uninstalling system apps.
+ final boolean clearPackageStateAndReturn;
synchronized (mPackages) {
markPackageUninstalledForUserLPw(ps, user);
if (!systemApp) {
@@ -19177,15 +19191,14 @@
// we need to do is clear this user's data and save that
// it is uninstalled.
if (DEBUG_REMOVE) Slog.d(TAG, "Still installed by other users");
- clearPackageStateForUserLIF(ps, userId, outInfo, flags);
- scheduleWritePackageRestrictionsLocked(user);
- return;
+ clearPackageStateAndReturn = true;
} else {
// We need to set it back to 'installed' so the uninstall
// broadcasts will be sent correctly.
if (DEBUG_REMOVE) Slog.d(TAG, "Not installed by other users, full delete");
ps.setInstalled(true, userId);
mSettings.writeKernelMappingLPr(ps);
+ clearPackageStateAndReturn = false;
}
} else {
// This is a system app, so we assume that the
@@ -19193,11 +19206,16 @@
// we need to do is clear this user's data and save that
// it is uninstalled.
if (DEBUG_REMOVE) Slog.d(TAG, "Deleting system app");
- clearPackageStateForUserLIF(ps, userId, outInfo, flags);
- scheduleWritePackageRestrictionsLocked(user);
- return;
+ clearPackageStateAndReturn = true;
}
}
+ if (clearPackageStateAndReturn) {
+ clearPackageStateForUserLIF(ps, userId, outInfo, flags);
+ synchronized (mPackages) {
+ scheduleWritePackageRestrictionsLocked(user);
+ }
+ return;
+ }
}
// If we are deleting a composite package for all users, keep track
@@ -19330,10 +19348,17 @@
destroyAppDataLIF(pkg, nextUserId,
StorageManager.FLAG_STORAGE_DE | StorageManager.FLAG_STORAGE_CE);
clearDefaultBrowserIfNeededForUser(ps.name, nextUserId);
- synchronized (mPackages) {
- if (clearPackagePreferredActivitiesLPw(ps.name, nextUserId)) {
+ removeKeystoreDataIfNeeded(nextUserId, ps.appId);
+ final SparseBooleanArray changedUsers = new SparseBooleanArray();
+ clearPackagePreferredActivitiesLPw(ps.name, changedUsers, nextUserId);
+ if (changedUsers.size() > 0) {
+ updateDefaultHomeNotLocked(changedUsers);
+ postPreferredActivityChangedBroadcast(nextUserId);
+ synchronized (mPackages) {
scheduleWritePackageRestrictionsLocked(nextUserId);
}
+ }
+ synchronized (mPackages) {
resetUserChangesToRuntimePermissionsAndFlagsLPw(ps, nextUserId);
}
// Also delete contributed media, when requested
@@ -19796,33 +19821,34 @@
int callingUid = Binder.getCallingUid();
mPermissionManager.enforceCrossUserPermission(callingUid, userId,
true /* requireFullPermission */, false /* checkShell */, "add preferred activity");
+ if (mContext.checkCallingOrSelfPermission(
+ android.Manifest.permission.SET_PREFERRED_APPLICATIONS)
+ != PackageManager.PERMISSION_GRANTED) {
+ if (getUidTargetSdkVersionLockedLPr(callingUid)
+ < Build.VERSION_CODES.FROYO) {
+ Slog.w(TAG, "Ignoring addPreferredActivity() from uid "
+ + callingUid);
+ return;
+ }
+ mContext.enforceCallingOrSelfPermission(
+ android.Manifest.permission.SET_PREFERRED_APPLICATIONS, null);
+ }
if (filter.countActions() == 0) {
Slog.w(TAG, "Cannot set a preferred activity with no filter actions");
return;
}
- synchronized (mPackages) {
- if (mContext.checkCallingOrSelfPermission(
- android.Manifest.permission.SET_PREFERRED_APPLICATIONS)
- != PackageManager.PERMISSION_GRANTED) {
- if (getUidTargetSdkVersionLockedLPr(callingUid)
- < Build.VERSION_CODES.FROYO) {
- Slog.w(TAG, "Ignoring addPreferredActivity() from uid "
- + callingUid);
- return;
- }
- mContext.enforceCallingOrSelfPermission(
- android.Manifest.permission.SET_PREFERRED_APPLICATIONS, null);
- }
-
- PreferredIntentResolver pir = mSettings.editPreferredActivitiesLPw(userId);
+ if (DEBUG_PREFERRED) {
Slog.i(TAG, opname + " activity " + activity.flattenToShortString() + " for user "
+ userId + ":");
filter.dump(new LogPrinter(Log.INFO, TAG), " ");
+ }
+ if (!updateDefaultHomeNotLocked(userId)) {
+ postPreferredActivityChangedBroadcast(userId);
+ }
+ synchronized (mPackages) {
+ final PreferredIntentResolver pir = mSettings.editPreferredActivitiesLPw(userId);
pir.addFilter(new PreferredActivity(filter, match, set, activity, always));
scheduleWritePackageRestrictionsLocked(userId);
- if (!updateDefaultHomeLPw(userId)) {
- postPreferredActivityChangedBroadcast(userId);
- }
}
}
@@ -19963,25 +19989,24 @@
&& filterAppAccessLPr(ps, callingUid, UserHandle.getUserId(callingUid))) {
return;
}
- int user = UserHandle.getCallingUserId();
- if (clearPackagePreferredActivitiesLPw(packageName, user)) {
- scheduleWritePackageRestrictionsLocked(user);
+ }
+ int callingUserId = UserHandle.getCallingUserId();
+ final SparseBooleanArray changedUsers = new SparseBooleanArray();
+ clearPackagePreferredActivitiesLPw(packageName, changedUsers, callingUserId);
+ if (changedUsers.size() > 0) {
+ updateDefaultHomeNotLocked(changedUsers);
+ postPreferredActivityChangedBroadcast(callingUserId);
+ synchronized (mPackages) {
+ scheduleWritePackageRestrictionsLocked(callingUserId);
}
}
}
/** This method takes a specific user id as well as UserHandle.USER_ALL. */
@GuardedBy("mPackages")
- boolean clearPackagePreferredActivitiesLPw(String packageName, int userId) {
- return clearPackagePreferredActivitiesLPw(packageName, false, userId);
- }
-
- /** This method takes a specific user id as well as UserHandle.USER_ALL. */
- @GuardedBy("mPackages")
- private boolean clearPackagePreferredActivitiesLPw(String packageName,
- boolean skipUpdateDefaultHome, int userId) {
+ private void clearPackagePreferredActivitiesLPw(String packageName,
+ @NonNull SparseBooleanArray outUserChanged, int userId) {
ArrayList<PreferredActivity> removed = null;
- boolean changed = false;
for (int i=0; i<mSettings.mPreferredActivities.size(); i++) {
final int thisUserId = mSettings.mPreferredActivities.keyAt(i);
PreferredIntentResolver pir = mSettings.mPreferredActivities.valueAt(i);
@@ -20007,16 +20032,9 @@
PreferredActivity pa = removed.get(j);
pir.removeFilter(pa);
}
- changed = true;
- if (!skipUpdateDefaultHome) {
- updateDefaultHomeLPw(thisUserId);
- }
+ outUserChanged.setValueAt(thisUserId, true);
}
}
- if (changed) {
- postPreferredActivityChangedBroadcast(userId);
- }
- return changed;
}
/** This method takes a specific user id as well as UserHandle.USER_ALL. */
@@ -20069,21 +20087,27 @@
final long identity = Binder.clearCallingIdentity();
// writer
try {
+ final SparseBooleanArray changedUsers = new SparseBooleanArray();
+ clearPackagePreferredActivitiesLPw(null, changedUsers, userId);
+ if (changedUsers.size() > 0) {
+ postPreferredActivityChangedBroadcast(userId);
+ }
synchronized (mPackages) {
- clearPackagePreferredActivitiesLPw(null, true, userId);
mSettings.applyDefaultPreferredAppsLPw(userId);
- updateDefaultHomeLPw(userId);
- // TODO: We have to reset the default SMS and Phone. This requires
- // significant refactoring to keep all default apps in the package
- // manager (cleaner but more work) or have the services provide
- // callbacks to the package manager to request a default app reset.
- setDefaultBrowserPackageName(null, userId);
clearIntentFilterVerificationsLPw(userId);
primeDomainVerificationsLPw(userId);
resetUserChangesToRuntimePermissionsAndFlagsLPw(userId);
+ }
+ updateDefaultHomeNotLocked(userId);
+ // TODO: We have to reset the default SMS and Phone. This requires
+ // significant refactoring to keep all default apps in the package
+ // manager (cleaner but more work) or have the services provide
+ // callbacks to the package manager to request a default app reset.
+ setDefaultBrowserPackageName(null, userId);
+ resetNetworkPolicies(userId);
+ synchronized (mPackages) {
scheduleWritePackageRestrictionsLocked(userId);
}
- resetNetworkPolicies(userId);
} finally {
Binder.restoreCallingIdentity(identity);
}
@@ -20133,15 +20157,17 @@
Slog.w(TAG, "Cannot set a preferred activity with no filter actions");
return;
}
- synchronized (mPackages) {
- Slog.i(TAG, "Adding persistent preferred activity " + activity + " for user " + userId +
- ":");
+ if (DEBUG_PREFERRED) {
+ Slog.i(TAG, "Adding persistent preferred activity " + activity
+ + " for user " + userId + ":");
filter.dump(new LogPrinter(Log.INFO, TAG), " ");
+ }
+ updateDefaultHomeNotLocked(userId);
+ postPreferredActivityChangedBroadcast(userId);
+ synchronized (mPackages) {
mSettings.editPersistentPreferredActivitiesLPw(userId).addFilter(
new PersistentPreferredActivity(filter, activity));
scheduleWritePackageRestrictionsLocked(userId);
- postPreferredActivityChangedBroadcast(userId);
- updateDefaultHomeLPw(userId);
}
}
@@ -20181,11 +20207,12 @@
changed = true;
}
}
-
- if (changed) {
+ }
+ if (changed) {
+ updateDefaultHomeNotLocked(userId);
+ postPreferredActivityChangedBroadcast(userId);
+ synchronized (mPackages) {
scheduleWritePackageRestrictionsLocked(userId);
- postPreferredActivityChangedBroadcast(userId);
- updateDefaultHomeLPw(userId);
}
}
}
@@ -20273,8 +20300,8 @@
(readParser, readUserId) -> {
synchronized (mPackages) {
mSettings.readPreferredActivitiesLPw(readParser, readUserId);
- updateDefaultHomeLPw(readUserId);
}
+ updateDefaultHomeNotLocked(readUserId);
});
} catch (Exception e) {
if (DEBUG_BACKUP) {
@@ -20601,29 +20628,55 @@
return null;
}
+ /** <b>must not hold {@link #mPackages}</b> */
+ private void updateDefaultHomeNotLocked(SparseBooleanArray userIds) {
+ if (Thread.holdsLock(mPackages)) {
+ Slog.wtf(TAG, "Calling thread " + Thread.currentThread().getName()
+ + " is holding mPackages", new Throwable());
+ }
+ for (int i = userIds.size() - 1; i >= 0; --i) {
+ final int userId = userIds.keyAt(i);
+ updateDefaultHomeNotLocked(userId);
+ }
+ }
+
/**
+ * <b>must not hold {@link #mPackages}</b>
+ *
* @return Whether the ACTION_PREFERRED_ACTIVITY_CHANGED broadcast has been scheduled.
*/
- private boolean updateDefaultHomeLPw(int userId) {
- Intent intent = getHomeIntent();
- List<ResolveInfo> resolveInfos = queryIntentActivitiesInternal(intent, null,
+ private boolean updateDefaultHomeNotLocked(int userId) {
+ if (Thread.holdsLock(mPackages)) {
+ Slog.wtf(TAG, "Calling thread " + Thread.currentThread().getName()
+ + " is holding mPackages", new Throwable());
+ }
+ final Intent intent = getHomeIntent();
+ final List<ResolveInfo> resolveInfos = queryIntentActivitiesInternal(intent, null,
PackageManager.GET_META_DATA, userId);
- ResolveInfo preferredResolveInfo = findPreferredActivity(intent, null, 0, resolveInfos,
- 0, true, false, false, userId);
- String packageName = preferredResolveInfo != null
+ final ResolveInfo preferredResolveInfo = findPreferredActivityNotLocked(
+ intent, null, 0, resolveInfos, 0, true, false, false, userId);
+ final String packageName = preferredResolveInfo != null
&& preferredResolveInfo.activityInfo != null
? preferredResolveInfo.activityInfo.packageName : null;
- String currentPackageName = mDefaultHomeProvider.getDefaultHome(userId);
+ final PackageManagerInternal.DefaultHomeProvider provider;
+ synchronized (mPackages) {
+ provider = mDefaultHomeProvider;
+ }
+ if (provider == null) {
+ Slog.e(TAG, "Default home provider has not been set");
+ return false;
+ }
+ final String currentPackageName = provider.getDefaultHome(userId);
if (TextUtils.equals(currentPackageName, packageName)) {
return false;
}
- String[] callingPackages = getPackagesForUid(Binder.getCallingUid());
+ final String[] callingPackages = getPackagesForUid(Binder.getCallingUid());
if (callingPackages != null && ArrayUtils.contains(callingPackages,
mRequiredPermissionControllerPackage)) {
// PermissionController manages default home directly.
return false;
}
- mDefaultHomeProvider.setDefaultHomeAsync(packageName, userId, (successful) -> {
+ provider.setDefaultHomeAsync(packageName, userId, (successful) -> {
if (successful) {
postPreferredActivityChangedBroadcast(userId);
}
@@ -23720,9 +23773,7 @@
}
return ((appInfo.isSystemApp() ? IPackageManagerNative.LOCATION_SYSTEM : 0)
| (appInfo.isVendor() ? IPackageManagerNative.LOCATION_VENDOR : 0)
- | (appInfo.isProduct() ? IPackageManagerNative.LOCATION_PRODUCT : 0)
- | (appInfo.isProductServices()
- ? IPackageManagerNative.LOCATION_PRODUCT_SERVICES : 0));
+ | (appInfo.isProduct() ? IPackageManagerNative.LOCATION_PRODUCT : 0));
}
}
diff --git a/services/core/java/com/android/server/pm/StagingManager.java b/services/core/java/com/android/server/pm/StagingManager.java
index 72d5438..803ab2d 100644
--- a/services/core/java/com/android/server/pm/StagingManager.java
+++ b/services/core/java/com/android/server/pm/StagingManager.java
@@ -261,13 +261,13 @@
if (storageManager.supportsCheckpoint()) {
storageManager.startCheckpoint(1 /* numRetries */);
}
- } catch (RemoteException e) {
+ } catch (Exception e) { // TODO(b/130190815) make a RemoteException again
// While StorageManager lives in the same process, the native implementation
// it calls through lives in 'vold'; so, this call can fail if 'vold' isn't
// reachable.
// Since we can live without filesystem checkpointing, just warn in this case
// and continue.
- Slog.w(TAG, "Could not start filesystem checkpoint.");
+ Slog.w(TAG, "Could not start filesystem checkpoint:", e);
}
session.setStagedSessionReady();
diff --git a/services/core/java/com/android/server/stats/StatsCompanionService.java b/services/core/java/com/android/server/stats/StatsCompanionService.java
index 96924c04..10ed88f 100644
--- a/services/core/java/com/android/server/stats/StatsCompanionService.java
+++ b/services/core/java/com/android/server/stats/StatsCompanionService.java
@@ -92,6 +92,7 @@
import android.os.storage.DiskInfo;
import android.os.storage.StorageManager;
import android.os.storage.VolumeInfo;
+import android.provider.Settings;
import android.stats.storage.StorageEnums;
import android.telephony.ModemActivityInfo;
import android.telephony.TelephonyManager;
@@ -2057,6 +2058,40 @@
}
}
+ private void pullFaceSettings(int tagId, long elapsedNanos, long wallClockNanos,
+ List<StatsLogEventWrapper> pulledData) {
+ long callingToken = Binder.clearCallingIdentity();
+ try {
+ List<UserInfo> users = mContext.getSystemService(UserManager.class).getUsers();
+ int numUsers = users.size();
+ for (int userNum = 0; userNum < numUsers; userNum++) {
+ int userId = users.get(userNum).getUserHandle().getIdentifier();
+
+ StatsLogEventWrapper e =
+ new StatsLogEventWrapper(tagId, elapsedNanos, wallClockNanos);
+ e.writeBoolean(Settings.Secure.getIntForUser(mContext.getContentResolver(),
+ Settings.Secure.FACE_UNLOCK_KEYGUARD_ENABLED, 1,
+ userId) != 0);
+ e.writeBoolean(Settings.Secure.getIntForUser(mContext.getContentResolver(),
+ Settings.Secure.FACE_UNLOCK_DISMISSES_KEYGUARD,
+ 0, userId) != 0);
+ e.writeBoolean(Settings.Secure.getIntForUser(mContext.getContentResolver(),
+ Settings.Secure.FACE_UNLOCK_ATTENTION_REQUIRED, 1,
+ userId) != 0);
+ e.writeBoolean(Settings.Secure.getIntForUser(mContext.getContentResolver(),
+ Settings.Secure.FACE_UNLOCK_APP_ENABLED, 1,
+ userId) != 0);
+ e.writeBoolean(Settings.Secure.getIntForUser(mContext.getContentResolver(),
+ Settings.Secure.FACE_UNLOCK_ALWAYS_REQUIRE_CONFIRMATION, 0,
+ userId) != 0);
+
+ pulledData.add(e);
+ }
+ } finally {
+ Binder.restoreCallingIdentity(callingToken);
+ }
+ }
+
/**
* Pulls various data.
*/
@@ -2261,6 +2296,10 @@
pullAppsOnExternalStorageInfo(tagId, elapsedNanos, wallClockNanos, ret);
break;
}
+ case StatsLog.FACE_SETTINGS: {
+ pullFaceSettings(tagId, elapsedNanos, wallClockNanos, ret);
+ break;
+ }
default:
Slog.w(TAG, "No such tagId data as " + tagId);
return null;
diff --git a/services/core/java/com/android/server/wm/ActivityMetricsLogger.java b/services/core/java/com/android/server/wm/ActivityMetricsLogger.java
index d916e39..10afbef 100644
--- a/services/core/java/com/android/server/wm/ActivityMetricsLogger.java
+++ b/services/core/java/com/android/server/wm/ActivityMetricsLogger.java
@@ -26,20 +26,6 @@
import static com.android.internal.logging.nano.MetricsProto.MetricsEvent.APP_TRANSITION_REPORTED_DRAWN_MS;
import static com.android.internal.logging.nano.MetricsProto.MetricsEvent.APP_TRANSITION_STARTING_WINDOW_DELAY_MS;
import static com.android.internal.logging.nano.MetricsProto.MetricsEvent.APP_TRANSITION_WINDOWS_DRAWN_DELAY_MS;
-import static com.android.internal.logging.nano.MetricsProto.MetricsEvent.FIELD_ACTIVITY_RECORD_FLAGS;
-import static com.android.internal.logging.nano.MetricsProto.MetricsEvent.FIELD_ACTIVITY_RECORD_IS_FULLSCREEN;
-import static com.android.internal.logging.nano.MetricsProto.MetricsEvent.FIELD_ACTIVITY_RECORD_IS_NO_DISPLAY;
-import static com.android.internal.logging.nano.MetricsProto.MetricsEvent.FIELD_ACTIVITY_RECORD_IS_VISIBLE;
-import static com.android.internal.logging.nano.MetricsProto.MetricsEvent.FIELD_ACTIVITY_RECORD_IS_VISIBLE_IGNORING_KEYGUARD;
-import static com.android.internal.logging.nano.MetricsProto.MetricsEvent.FIELD_ACTIVITY_RECORD_LAUNCH_MODE;
-import static com.android.internal.logging.nano.MetricsProto.MetricsEvent.FIELD_ACTIVITY_RECORD_MILLIS_SINCE_LAST_LAUNCH;
-import static com.android.internal.logging.nano.MetricsProto.MetricsEvent.FIELD_ACTIVITY_RECORD_MILLIS_SINCE_LAST_VISIBLE;
-import static com.android.internal.logging.nano.MetricsProto.MetricsEvent.FIELD_ACTIVITY_RECORD_PROCESS_NAME;
-import static com.android.internal.logging.nano.MetricsProto.MetricsEvent.FIELD_ACTIVITY_RECORD_REAL_ACTIVITY;
-import static com.android.internal.logging.nano.MetricsProto.MetricsEvent.FIELD_ACTIVITY_RECORD_RESULT_TO_PKG_NAME;
-import static com.android.internal.logging.nano.MetricsProto.MetricsEvent.FIELD_ACTIVITY_RECORD_RESULT_TO_SHORT_COMPONENT_NAME;
-import static com.android.internal.logging.nano.MetricsProto.MetricsEvent.FIELD_ACTIVITY_RECORD_SHORT_COMPONENT_NAME;
-import static com.android.internal.logging.nano.MetricsProto.MetricsEvent.FIELD_ACTIVITY_RECORD_TARGET_ACTIVITY;
import static com.android.internal.logging.nano.MetricsProto.MetricsEvent.FIELD_CALLING_PACKAGE_NAME;
import static com.android.internal.logging.nano.MetricsProto.MetricsEvent.FIELD_CALLING_UID;
import static com.android.internal.logging.nano.MetricsProto.MetricsEvent.FIELD_CALLING_UID_HAS_ANY_VISIBLE_WINDOW;
@@ -62,12 +48,7 @@
import static com.android.internal.logging.nano.MetricsProto.MetricsEvent.FIELD_REAL_CALLING_UID;
import static com.android.internal.logging.nano.MetricsProto.MetricsEvent.FIELD_REAL_CALLING_UID_HAS_ANY_VISIBLE_WINDOW;
import static com.android.internal.logging.nano.MetricsProto.MetricsEvent.FIELD_REAL_CALLING_UID_PROC_STATE;
-import static com.android.internal.logging.nano.MetricsProto.MetricsEvent.FIELD_TARGET_PACKAGE_NAME;
import static com.android.internal.logging.nano.MetricsProto.MetricsEvent.FIELD_TARGET_SHORT_COMPONENT_NAME;
-import static com.android.internal.logging.nano.MetricsProto.MetricsEvent.FIELD_TARGET_UID;
-import static com.android.internal.logging.nano.MetricsProto.MetricsEvent.FIELD_TARGET_UID_HAS_ANY_VISIBLE_WINDOW;
-import static com.android.internal.logging.nano.MetricsProto.MetricsEvent.FIELD_TARGET_UID_PROC_STATE;
-import static com.android.internal.logging.nano.MetricsProto.MetricsEvent.FIELD_TARGET_WHITELIST_TAG;
import static com.android.internal.logging.nano.MetricsProto.MetricsEvent.PACKAGE_OPTIMIZATION_COMPILATION_FILTER;
import static com.android.internal.logging.nano.MetricsProto.MetricsEvent.PACKAGE_OPTIMIZATION_COMPILATION_REASON;
import static com.android.internal.logging.nano.MetricsProto.MetricsEvent.TYPE_TRANSITION_COLD_LAUNCH;
@@ -671,6 +652,11 @@
final WindowingModeTransitionInfo info = mWindowingModeTransitionInfo.valueAt(index);
final int type = getTransitionType(info);
if (type == INVALID_TRANSITION_TYPE) {
+ if (DEBUG_METRICS) {
+ Slog.i(TAG, "invalid transition type"
+ + " processRunning=" + info.currentTransitionProcessRunning
+ + " startResult=" + info.startResult);
+ }
return;
}
@@ -921,7 +907,10 @@
} else if (info.startResult == START_TASK_TO_FRONT) {
return TYPE_TRANSITION_HOT_LAUNCH;
}
- } else if (info.startResult == START_SUCCESS) {
+ } else if (info.startResult == START_SUCCESS
+ || (info.startResult == START_TASK_TO_FRONT)) {
+ // TaskRecord may still exist when cold launching an activity and the start
+ // result will be set to START_TASK_TO_FRONT. Treat this as a COLD launch.
return TYPE_TRANSITION_COLD_LAUNCH;
}
return INVALID_TRANSITION_TYPE;
diff --git a/services/core/java/com/android/server/wm/ActivityStack.java b/services/core/java/com/android/server/wm/ActivityStack.java
index 419f5be..76b0351 100644
--- a/services/core/java/com/android/server/wm/ActivityStack.java
+++ b/services/core/java/com/android/server/wm/ActivityStack.java
@@ -2753,7 +2753,7 @@
// happens to be sitting towards the end.
if (next.attachedToProcess()) {
next.app.updateProcessInfo(false /* updateServiceConnectionActivities */,
- true /* updateLru */, true /* activityChange */, false /* updateOomAdj */);
+ true /* activityChange */, false /* updateOomAdj */);
}
if (lastResumed != null) {
lastResumed.setWillCloseOrEnterPip(true);
@@ -2903,7 +2903,7 @@
next.setState(RESUMED, "resumeTopActivityInnerLocked");
next.app.updateProcessInfo(false /* updateServiceConnectionActivities */,
- true /* updateLru */, true /* activityChange */, true /* updateOomAdj */);
+ true /* activityChange */, true /* updateOomAdj */);
updateLRUListLocked(next);
// Have the window manager re-evaluate the orientation of
@@ -4600,7 +4600,8 @@
// Update any services we are bound to that might care about whether
// their client may have activities.
// No longer have activities, so update LRU list and oom adj.
- r.app.updateProcessInfo(true, true, false, true);
+ r.app.updateProcessInfo(true /* updateServiceConnectionActivities */,
+ false /* activityChange */, true /* updateOomAdj */);
}
}
diff --git a/services/core/java/com/android/server/wm/ActivityStackSupervisor.java b/services/core/java/com/android/server/wm/ActivityStackSupervisor.java
index a9d76a6..5790a1b 100644
--- a/services/core/java/com/android/server/wm/ActivityStackSupervisor.java
+++ b/services/core/java/com/android/server/wm/ActivityStackSupervisor.java
@@ -769,14 +769,12 @@
+ " old=" + r.app + " new=" + proc);
}
- proc.clearWaitingToKill();
r.launchCount++;
r.lastLaunchTime = SystemClock.uptimeMillis();
if (DEBUG_ALL) Slog.v(TAG, "Launching: " + r);
proc.addActivityIfNeeded(r);
- proc.updateProcessInfo(false, true, true, true);
final LockTaskController lockTaskController = mService.getLockTaskController();
if (task.mLockTaskAuth == LOCK_TASK_AUTH_LAUNCHABLE
@@ -814,7 +812,6 @@
r.forceNewConfig = false;
mService.getAppWarningsLocked().onStartActivity(r);
r.compat = mService.compatibilityInfoForPackageLocked(r.info.applicationInfo);
- ProfilerInfo profilerInfo = proc.onStartActivity(mService.mTopProcessState);
// Because we could be starting an Activity in the system process this may not go
// across a Binder interface which would create a new Configuration. Consequently
@@ -840,7 +837,7 @@
mergedConfiguration.getOverrideConfiguration(), r.compat,
r.launchedFromPackage, task.voiceInteractor, proc.getReportedProcState(),
r.icicle, r.persistentState, results, newIntents,
- dc.isNextTransitionForward(), profilerInfo));
+ dc.isNextTransitionForward(), proc.createProfilerInfoIfNeeded()));
// Set desired final state.
final ActivityLifecycleItem lifecycleItem;
@@ -910,6 +907,9 @@
"Moving to PAUSED: " + r + " (starting in paused state)");
r.setState(PAUSED, "realStartActivityLocked");
}
+ // Perform OOM scoring after the activity state is set, so the process can be updated with
+ // the latest state.
+ proc.onStartActivity(mService.mTopProcessState, r.info);
// Launch the new version setup screen if needed. We do this -after-
// launching the initial activity (that is, home), so that it can have
@@ -960,13 +960,6 @@
boolean knownToBeDead = false;
if (wpc != null && wpc.hasThread()) {
try {
- if ((r.info.flags & ActivityInfo.FLAG_MULTIPROCESS) == 0
- || !"android".equals(r.info.packageName)) {
- // Don't add this if it is a platform component that is marked to run in
- // multiple processes, because this is actually part of the framework so doesn't
- // make sense to track as a separate apk in the process.
- wpc.addPackage(r.info.packageName, r.info.applicationInfo.longVersionCode);
- }
realStartActivityLocked(r, wpc, andResume, checkConfig);
return;
} catch (RemoteException e) {
diff --git a/services/core/java/com/android/server/wm/ActivityStarter.java b/services/core/java/com/android/server/wm/ActivityStarter.java
index 473a875..8957444 100644
--- a/services/core/java/com/android/server/wm/ActivityStarter.java
+++ b/services/core/java/com/android/server/wm/ActivityStarter.java
@@ -937,7 +937,7 @@
|| callingUid == Process.NFC_UID) {
return false;
}
- // don't abort if the callingUid is in the foreground or is a persistent system process
+ // don't abort if the callingUid has a visible window or is a persistent system process
final int callingUidProcState = mService.getUidState(callingUid);
final boolean callingUidHasAnyVisibleWindow =
mService.mWindowManager.mRoot.isAnyNonToastWindowVisibleForUid(callingUid);
@@ -946,7 +946,7 @@
|| callingUidProcState == ActivityManager.PROCESS_STATE_BOUND_TOP;
final boolean isCallingUidPersistentSystemProcess = (callingUid == Process.SYSTEM_UID)
|| callingUidProcState <= ActivityManager.PROCESS_STATE_PERSISTENT_UI;
- if (isCallingUidForeground || isCallingUidPersistentSystemProcess) {
+ if (callingUidHasAnyVisibleWindow || isCallingUidPersistentSystemProcess) {
return false;
}
// take realCallingUid into consideration
@@ -965,8 +965,8 @@
: (realCallingUid == Process.SYSTEM_UID)
|| realCallingUidProcState <= ActivityManager.PROCESS_STATE_PERSISTENT_UI;
if (realCallingUid != callingUid) {
- // don't abort if the realCallingUid is in the foreground and callingUid isn't
- if (isRealCallingUidForeground) {
+ // don't abort if the realCallingUid has a visible window
+ if (realCallingUidHasAnyVisibleWindow) {
return false;
}
// if the realCallingUid is a persistent system process, abort if the IntentSender
@@ -988,10 +988,6 @@
callerApp = mService.getProcessController(realCallingPid, realCallingUid);
}
if (callerApp != null) {
- // don't abort if the callerApp has any visible activity
- if (callerApp.hasForegroundActivities()) {
- return false;
- }
// don't abort if the callerApp is instrumenting with background activity starts privs
if (callerApp.isInstrumentingWithBackgroundActivityStartPrivileges()) {
return false;
@@ -1061,8 +1057,7 @@
final ArraySet<Integer> boundClientUids = callerApp.getBoundClientUids();
for (int i = boundClientUids.size() - 1; i >= 0; --i) {
final int uid = boundClientUids.valueAt(i);
- if (mService.mWindowManager.mRoot.isAnyNonToastWindowVisibleForUid(uid)
- || mService.getUidState(uid) == ActivityManager.PROCESS_STATE_TOP) {
+ if (mService.isUidForeground(uid)) {
return true;
}
}
diff --git a/services/core/java/com/android/server/wm/ActivityTaskManagerInternal.java b/services/core/java/com/android/server/wm/ActivityTaskManagerInternal.java
index 7d25466..48aee20 100644
--- a/services/core/java/com/android/server/wm/ActivityTaskManagerInternal.java
+++ b/services/core/java/com/android/server/wm/ActivityTaskManagerInternal.java
@@ -503,7 +503,7 @@
public abstract ActivityManager.TaskSnapshot getTaskSnapshot(int taskId,
boolean reducedResolution);
- /** Returns true if uid has a visible window or its process is in a top state. */
+ /** Returns true if uid is considered foreground for activity start purposes. */
public abstract boolean isUidForeground(int uid);
/**
diff --git a/services/core/java/com/android/server/wm/ActivityTaskManagerService.java b/services/core/java/com/android/server/wm/ActivityTaskManagerService.java
index b424904..76774d7 100644
--- a/services/core/java/com/android/server/wm/ActivityTaskManagerService.java
+++ b/services/core/java/com/android/server/wm/ActivityTaskManagerService.java
@@ -5872,8 +5872,8 @@
}
boolean isUidForeground(int uid) {
- return (getUidState(uid) == ActivityManager.PROCESS_STATE_TOP)
- || mWindowManager.mRoot.isAnyNonToastWindowVisibleForUid(uid);
+ // A uid is considered to be foreground if it has a visible non-toast window.
+ return mWindowManager.mRoot.isAnyNonToastWindowVisibleForUid(uid);
}
boolean isDeviceOwner(int uid) {
@@ -6480,9 +6480,10 @@
*/
@Override
public void onImeWindowSetOnDisplay(final int pid, final int displayId) {
- // Update display configuration for IME process only when Single-client IME window
- // moving to another display.
- if (!InputMethodSystemProperty.MULTI_CLIENT_IME_ENABLED) return;
+ // Don't update process-level configuration for Multi-Client IME process since other
+ // IMEs on other displays will also receive this configuration change due to IME
+ // services use the same application config/context.
+ if (InputMethodSystemProperty.MULTI_CLIENT_IME_ENABLED) return;
if (pid == MY_PID || pid < 0) {
if (DEBUG_CONFIGURATION) {
diff --git a/services/core/java/com/android/server/wm/AppTaskImpl.java b/services/core/java/com/android/server/wm/AppTaskImpl.java
index e967a92f..78f1e69 100644
--- a/services/core/java/com/android/server/wm/AppTaskImpl.java
+++ b/services/core/java/com/android/server/wm/AppTaskImpl.java
@@ -106,6 +106,10 @@
final long origId = Binder.clearCallingIdentity();
try {
synchronized (mService.mGlobalLock) {
+ if (!mService.checkAppSwitchAllowedLocked(callingPid, callingUid, -1, -1,
+ "Move to front")) {
+ return;
+ }
WindowProcessController callerApp = null;
if (appThread != null) {
callerApp = mService.getProcessController(appThread);
diff --git a/services/core/java/com/android/server/wm/RootWindowContainer.java b/services/core/java/com/android/server/wm/RootWindowContainer.java
index 1ca31f1..f9fd541 100644
--- a/services/core/java/com/android/server/wm/RootWindowContainer.java
+++ b/services/core/java/com/android/server/wm/RootWindowContainer.java
@@ -314,9 +314,10 @@
* Returns true if the callingUid has any non-toast window currently visible to the user.
*/
boolean isAnyNonToastWindowVisibleForUid(int callingUid) {
- return forAllWindows(w -> {
- return w.getOwningUid() == callingUid && w.isVisible() && w.mAttrs.type != TYPE_TOAST;
- }, true /* traverseTopToBottom */);
+ return forAllWindows(w ->
+ w.getOwningUid() == callingUid && w.mAttrs.type != TYPE_TOAST
+ && w.isVisibleNow(),
+ true /* traverseTopToBottom */);
}
/**
diff --git a/services/core/java/com/android/server/wm/TaskSnapshotController.java b/services/core/java/com/android/server/wm/TaskSnapshotController.java
index f31416c..432ca33 100644
--- a/services/core/java/com/android/server/wm/TaskSnapshotController.java
+++ b/services/core/java/com/android/server/wm/TaskSnapshotController.java
@@ -292,9 +292,9 @@
}
final boolean isWindowTranslucent = mainWindow.getAttrs().format != PixelFormat.OPAQUE;
return new TaskSnapshot(appWindowToken.mActivityComponent, buffer,
- appWindowToken.getConfiguration().orientation, getInsets(mainWindow),
- isLowRamDevice /* reduced */, scaleFraction /* scale */, true /* isRealSnapshot */,
- task.getWindowingMode(), getSystemUiVisibility(task),
+ screenshotBuffer.getColorSpace(), appWindowToken.getConfiguration().orientation,
+ getInsets(mainWindow), isLowRamDevice /* reduced */, scaleFraction /* scale */,
+ true /* isRealSnapshot */, task.getWindowingMode(), getSystemUiVisibility(task),
!appWindowToken.fillsParent() || isWindowTranslucent);
}
@@ -383,10 +383,10 @@
// Note, the app theme snapshot is never translucent because we enforce a non-translucent
// color above
return new TaskSnapshot(topChild.mActivityComponent, hwBitmap.createGraphicBufferHandle(),
- topChild.getConfiguration().orientation, mainWindow.getStableInsets(),
- ActivityManager.isLowRamDeviceStatic() /* reduced */, 1.0f /* scale */,
- false /* isRealSnapshot */, task.getWindowingMode(), getSystemUiVisibility(task),
- false);
+ hwBitmap.getColorSpace(), topChild.getConfiguration().orientation,
+ mainWindow.getStableInsets(), ActivityManager.isLowRamDeviceStatic() /* reduced */,
+ 1.0f /* scale */, false /* isRealSnapshot */, task.getWindowingMode(),
+ getSystemUiVisibility(task), false);
}
/**
diff --git a/services/core/java/com/android/server/wm/TaskSnapshotLoader.java b/services/core/java/com/android/server/wm/TaskSnapshotLoader.java
index d30843b..f7b8945 100644
--- a/services/core/java/com/android/server/wm/TaskSnapshotLoader.java
+++ b/services/core/java/com/android/server/wm/TaskSnapshotLoader.java
@@ -89,7 +89,8 @@
}
ComponentName topActivityComponent = ComponentName.unflattenFromString(
proto.topActivityComponent);
- return new TaskSnapshot(topActivityComponent, buffer, proto.orientation,
+ return new TaskSnapshot(topActivityComponent, buffer, bitmap.getColorSpace(),
+ proto.orientation,
new Rect(proto.insetLeft, proto.insetTop, proto.insetRight, proto.insetBottom),
reducedResolution, reducedResolution ? mPersister.getReducedScale() : 1f,
proto.isRealSnapshot, proto.windowingMode, proto.systemUiVisibility,
diff --git a/services/core/java/com/android/server/wm/WindowManagerService.java b/services/core/java/com/android/server/wm/WindowManagerService.java
index ce496f4..8ed2a15 100644
--- a/services/core/java/com/android/server/wm/WindowManagerService.java
+++ b/services/core/java/com/android/server/wm/WindowManagerService.java
@@ -2107,7 +2107,7 @@
if (shouldRelayout) {
Trace.traceBegin(TRACE_TAG_WINDOW_MANAGER, "relayoutWindow: viewVisibility_1");
- result = win.relayoutVisibleWindow(result, attrChanges, oldVisibility);
+ result = win.relayoutVisibleWindow(result, attrChanges);
try {
result = createSurfaceControl(outSurfaceControl, result, win, winAnimator);
diff --git a/services/core/java/com/android/server/wm/WindowProcessController.java b/services/core/java/com/android/server/wm/WindowProcessController.java
index 33561d3a..4ca35f7 100644
--- a/services/core/java/com/android/server/wm/WindowProcessController.java
+++ b/services/core/java/com/android/server/wm/WindowProcessController.java
@@ -44,6 +44,7 @@
import android.app.ProfilerInfo;
import android.app.servertransaction.ConfigurationChangeItem;
import android.content.Intent;
+import android.content.pm.ActivityInfo;
import android.content.pm.ApplicationInfo;
import android.content.res.Configuration;
import android.os.Message;
@@ -771,13 +772,12 @@
WindowProcessListener::clearProfilerIfNeeded, mListener));
}
- void updateProcessInfo(boolean updateServiceConnectionActivities, boolean updateLru,
- boolean activityChange, boolean updateOomAdj) {
+ void updateProcessInfo(boolean updateServiceConnectionActivities, boolean activityChange,
+ boolean updateOomAdj) {
if (mListener == null) return;
// Posting on handler so WM lock isn't held when we call into AM.
final Message m = PooledLambda.obtainMessage(WindowProcessListener::updateProcessInfo,
- mListener, updateServiceConnectionActivities, updateLru, activityChange,
- updateOomAdj);
+ mListener, updateServiceConnectionActivities, activityChange, updateOomAdj);
mAtm.mH.sendMessage(m);
}
@@ -801,53 +801,44 @@
return mListener == null ? false : mListener.isRemoved();
}
- void clearWaitingToKill() {
- if (mListener == null) return;
- // Posting on handler so WM lock isn't held when we call into AM.
- final Message m = PooledLambda.obtainMessage(
- WindowProcessListener::clearWaitingToKill, mListener);
- mAtm.mH.sendMessage(m);
+ private boolean shouldSetProfileProc() {
+ return mAtm.mProfileApp != null && mAtm.mProfileApp.equals(mName)
+ && (mAtm.mProfileProc == null || mAtm.mProfileProc == this);
}
- void addPackage(String pkg, long versionCode) {
- if (mListener == null) return;
- // Posting on handler so WM lock isn't held when we call into AM.
- final Message m = PooledLambda.obtainMessage(
- WindowProcessListener::addPackage, mListener, pkg, versionCode);
- mAtm.mH.sendMessage(m);
- }
-
- ProfilerInfo onStartActivity(int topProcessState) {
- ProfilerInfo profilerInfo = null;
- boolean setProfileProc = false;
- if (mAtm.mProfileApp != null
- && mAtm.mProfileApp.equals(mName)) {
- if (mAtm.mProfileProc == null || mAtm.mProfileProc == this) {
- setProfileProc = true;
- final ProfilerInfo profilerInfoSvc = mAtm.mProfilerInfo;
- if (profilerInfoSvc != null && profilerInfoSvc.profileFile != null) {
- if (profilerInfoSvc.profileFd != null) {
- try {
- profilerInfoSvc.profileFd = profilerInfoSvc.profileFd.dup();
- } catch (IOException e) {
- profilerInfoSvc.closeFd();
- }
- }
-
- profilerInfo = new ProfilerInfo(profilerInfoSvc);
- }
+ ProfilerInfo createProfilerInfoIfNeeded() {
+ final ProfilerInfo currentProfilerInfo = mAtm.mProfilerInfo;
+ if (currentProfilerInfo == null || currentProfilerInfo.profileFile == null
+ || !shouldSetProfileProc()) {
+ return null;
+ }
+ if (currentProfilerInfo.profileFd != null) {
+ try {
+ currentProfilerInfo.profileFd = currentProfilerInfo.profileFd.dup();
+ } catch (IOException e) {
+ currentProfilerInfo.closeFd();
}
}
+ return new ProfilerInfo(currentProfilerInfo);
+ }
-
- if (mListener != null) {
- // Posting on handler so WM lock isn't held when we call into AM.
- final Message m = PooledLambda.obtainMessage(WindowProcessListener::onStartActivity,
- mListener, topProcessState, setProfileProc);
- mAtm.mH.sendMessage(m);
+ void onStartActivity(int topProcessState, ActivityInfo info) {
+ if (mListener == null) return;
+ String packageName = null;
+ if ((info.flags & ActivityInfo.FLAG_MULTIPROCESS) == 0
+ || !"android".equals(info.packageName)) {
+ // Don't add this if it is a platform component that is marked to run in multiple
+ // processes, because this is actually part of the framework so doesn't make sense
+ // to track as a separate apk in the process.
+ packageName = info.packageName;
}
-
- return profilerInfo;
+ // Posting the message at the front of queue so WM lock isn't held when we call into AM,
+ // and the process state of starting activity can be updated quicker which will give it a
+ // higher scheduling group.
+ final Message m = PooledLambda.obtainMessage(WindowProcessListener::onStartActivity,
+ mListener, topProcessState, shouldSetProfileProc(), packageName,
+ info.applicationInfo.longVersionCode);
+ mAtm.mH.sendMessageAtFrontOfQueue(m);
}
public void appDied() {
diff --git a/services/core/java/com/android/server/wm/WindowProcessListener.java b/services/core/java/com/android/server/wm/WindowProcessListener.java
index d732e4e..527d54a 100644
--- a/services/core/java/com/android/server/wm/WindowProcessListener.java
+++ b/services/core/java/com/android/server/wm/WindowProcessListener.java
@@ -41,8 +41,8 @@
void setPendingUiCleanAndForceProcessStateUpTo(int newState);
/** Update the process information. */
- void updateProcessInfo(boolean updateServiceConnectionActivities, boolean updateLru,
- boolean activityChange, boolean updateOomAdj);
+ void updateProcessInfo(boolean updateServiceConnectionActivities, boolean activityChange,
+ boolean updateOomAdj);
/**
* Returns true if the process is removed and we should completely clean up the related records
@@ -53,14 +53,9 @@
/** Returns the total time (in milliseconds) spent executing in both user and system code. */
long getCpuTime();
- /** Clears the waiting to kill reason for this process. */
- void clearWaitingToKill();
-
- /** Adds the package to the process. */
- void addPackage(String pkg, long versionCode);
-
/** Called when we are in the process on starting an activity. */
- void onStartActivity(int topProcessState, boolean setProfileProc);
+ void onStartActivity(int topProcessState, boolean setProfileProc, String packageName,
+ long versionCode);
/** App died :(...oh well */
void appDied();
diff --git a/services/core/java/com/android/server/wm/WindowState.java b/services/core/java/com/android/server/wm/WindowState.java
index 08ade37..d990e6c 100644
--- a/services/core/java/com/android/server/wm/WindowState.java
+++ b/services/core/java/com/android/server/wm/WindowState.java
@@ -4446,7 +4446,7 @@
return !mLastSurfaceInsets.equals(mAttrs.surfaceInsets);
}
- int relayoutVisibleWindow(int result, int attrChanges, int oldVisibility) {
+ int relayoutVisibleWindow(int result, int attrChanges) {
final boolean wasVisible = isVisibleLw();
result |= (!wasVisible || !isDrawnLw()) ? RELAYOUT_RES_FIRST_TIME : 0;
@@ -4466,7 +4466,7 @@
mDestroying = false;
mWmService.mDestroySurface.remove(this);
}
- if (oldVisibility == View.GONE) {
+ if (!wasVisible) {
mWinAnimator.mEnterAnimationPending = true;
}
diff --git a/services/core/jni/com_android_server_location_GnssLocationProvider.cpp b/services/core/jni/com_android_server_location_GnssLocationProvider.cpp
index 73e9bf0..b470ec7 100644
--- a/services/core/jni/com_android_server_location_GnssLocationProvider.cpp
+++ b/services/core/jni/com_android_server_location_GnssLocationProvider.cpp
@@ -1693,7 +1693,7 @@
// 1.1@IGnss can be paired {1.0, 1.1}@IGnssMeasurement
// 1.0@IGnss is paired with 1.0@IGnssMeasurement
gnssMeasurementIface = nullptr;
- if (gnssHal_V2_0 != nullptr && gnssMeasurementIface == nullptr) {
+ if (gnssHal_V2_0 != nullptr) {
auto gnssMeasurement = gnssHal_V2_0->getExtensionGnssMeasurement_2_0();
if (!gnssMeasurement.isOk()) {
ALOGD("Unable to get a handle to GnssMeasurement_V2_0");
@@ -1730,6 +1730,10 @@
}
}
+ // Allow all causal combinations between IGnss.hal and IGnssDebug.hal. That means,
+ // 2.0@IGnss can be paired with {1.0, 2.0}@IGnssDebug
+ // 1.0@IGnss is paired with 1.0@IGnssDebug
+ gnssDebugIface = nullptr;
if (gnssHal_V2_0 != nullptr) {
auto gnssDebug = gnssHal_V2_0->getExtensionGnssDebug_2_0();
if (!gnssDebug.isOk()) {
@@ -1738,7 +1742,8 @@
gnssDebugIface_V2_0 = gnssDebug;
gnssDebugIface = gnssDebugIface_V2_0;
}
- } else {
+ }
+ if (gnssDebugIface == nullptr) {
auto gnssDebug = gnssHal->getExtensionGnssDebug();
if (!gnssDebug.isOk()) {
ALOGD("Unable to get a handle to GnssDebug");
diff --git a/services/devicepolicy/java/com/android/server/devicepolicy/AbUpdateInstaller.java b/services/devicepolicy/java/com/android/server/devicepolicy/AbUpdateInstaller.java
index d5cfab9..5acf83a 100644
--- a/services/devicepolicy/java/com/android/server/devicepolicy/AbUpdateInstaller.java
+++ b/services/devicepolicy/java/com/android/server/devicepolicy/AbUpdateInstaller.java
@@ -194,8 +194,17 @@
}
UpdateEngine updateEngine = buildBoundUpdateEngine();
- updateEngine.applyPayload(
- updatePath, mOffsetForUpdate, mSizeForUpdate, headerKeyValuePairs);
+ try {
+ updateEngine.applyPayload(
+ updatePath, mOffsetForUpdate, mSizeForUpdate, headerKeyValuePairs);
+ } catch (Exception e) {
+ // Prevent an automatic restart when an update is already being processed
+ // (http://b/124106342).
+ Log.w(UpdateInstaller.TAG, "Failed to install update from file.", e);
+ notifyCallbackOnError(
+ InstallSystemUpdateCallback.UPDATE_ERROR_UNKNOWN,
+ "Failed to install update from file.");
+ }
}
private boolean updateStateForPayload() throws IOException {
diff --git a/services/tests/servicestests/src/com/android/server/ThreadPriorityBoosterTest.java b/services/tests/servicestests/src/com/android/server/ThreadPriorityBoosterTest.java
new file mode 100644
index 0000000..b4e9ff7
--- /dev/null
+++ b/services/tests/servicestests/src/com/android/server/ThreadPriorityBoosterTest.java
@@ -0,0 +1,97 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.server;
+
+import static android.os.Process.getThreadPriority;
+import static android.os.Process.myTid;
+import static android.os.Process.setThreadPriority;
+
+import static org.junit.Assert.assertEquals;
+
+import android.os.Process;
+import android.platform.test.annotations.Presubmit;
+
+import androidx.test.filters.SmallTest;
+
+import org.junit.Test;
+
+/**
+ * Tests for {@link ThreadPriorityBooster}.
+ * Build/Install/Run:
+ * atest FrameworksServicesTests:ThreadPriorityBoosterTest
+ */
+@SmallTest
+@Presubmit
+public class ThreadPriorityBoosterTest {
+ private static final int PRIORITY_BOOST = Process.THREAD_PRIORITY_FOREGROUND;
+ private static final int PRIORITY_BOOST_MORE = Process.THREAD_PRIORITY_DISPLAY;
+
+ private final ThreadPriorityBooster mBooster = new ThreadPriorityBooster(PRIORITY_BOOST,
+ 0 /* lockGuardIndex */);
+
+ @Test
+ public void testThreadPriorityBooster() {
+ joinNewThread(() -> {
+ final int origPriority = Process.THREAD_PRIORITY_DEFAULT;
+ setThreadPriority(origPriority);
+
+ boost(() -> {
+ assertThreadPriority(PRIORITY_BOOST);
+ boost(() -> {
+ // Inside the boost region, the priority should also apply to current thread.
+ mBooster.setBoostToPriority(PRIORITY_BOOST_MORE);
+ assertThreadPriority(PRIORITY_BOOST_MORE);
+ });
+ // It is still in the boost region so the set priority should be kept.
+ assertThreadPriority(PRIORITY_BOOST_MORE);
+
+ joinNewThread(() -> boost(() -> assertThreadPriority(PRIORITY_BOOST_MORE)));
+ });
+ // The priority should be restored after leaving the boost region.
+ assertThreadPriority(origPriority);
+
+ // It doesn't apply to current thread because outside of the boost region, but the boost
+ // in other threads will use the set priority.
+ mBooster.setBoostToPriority(PRIORITY_BOOST);
+ joinNewThread(() -> boost(() -> assertThreadPriority(PRIORITY_BOOST)));
+
+ assertThreadPriority(origPriority);
+ });
+ }
+
+ private static void assertThreadPriority(int expectedPriority) {
+ assertEquals(expectedPriority, getThreadPriority(myTid()));
+ }
+
+ private static void joinNewThread(Runnable action) {
+ final Thread thread = new Thread(action);
+ thread.start();
+ try {
+ thread.join();
+ } catch (InterruptedException ignored) {
+ }
+ }
+
+ private void boost(Runnable action) {
+ try {
+ mBooster.boost();
+ action.run();
+ } finally {
+ mBooster.reset();
+ }
+ }
+}
diff --git a/services/tests/servicestests/src/com/android/server/am/ActivityManagerServiceTest.java b/services/tests/servicestests/src/com/android/server/am/ActivityManagerServiceTest.java
index 4e21fd0c..3df6976 100644
--- a/services/tests/servicestests/src/com/android/server/am/ActivityManagerServiceTest.java
+++ b/services/tests/servicestests/src/com/android/server/am/ActivityManagerServiceTest.java
@@ -322,7 +322,8 @@
ApplicationInfo appInfo = new ApplicationInfo();
appInfo.processName = "com.android.test.app";
appInfo.uid = 10000;
- final IsolatedUidRange range = allocator.getOrCreateIsolatedUidRangeLocked(appInfo);
+ final IsolatedUidRange range = allocator.getOrCreateIsolatedUidRangeLocked(
+ appInfo.processName, appInfo.uid);
validateAppZygoteIsolatedUidRange(range);
verifyIsolatedUidAllocator(range);
@@ -330,7 +331,8 @@
ApplicationInfo appInfo2 = new ApplicationInfo();
appInfo2.processName = "com.android.test.app2";
appInfo2.uid = 10001;
- IsolatedUidRange range2 = allocator.getOrCreateIsolatedUidRangeLocked(appInfo2);
+ IsolatedUidRange range2 = allocator.getOrCreateIsolatedUidRangeLocked(
+ appInfo2.processName, appInfo2.uid);
validateAppZygoteIsolatedUidRange(range2);
verifyIsolatedUidAllocator(range2);
@@ -339,7 +341,7 @@
// Free range, reallocate and verify
allocator.freeUidRangeLocked(appInfo2);
- range2 = allocator.getOrCreateIsolatedUidRangeLocked(appInfo2);
+ range2 = allocator.getOrCreateIsolatedUidRangeLocked(appInfo2.processName, appInfo2.uid);
validateAppZygoteIsolatedUidRange(range2);
verifyUidRangesNoOverlap(range, range2);
verifyIsolatedUidAllocator(range2);
@@ -354,7 +356,8 @@
appInfo = new ApplicationInfo();
appInfo.uid = 10000 + i;
appInfo.processName = "com.android.test.app" + Integer.toString(i);
- IsolatedUidRange uidRange = allocator.getOrCreateIsolatedUidRangeLocked(appInfo);
+ IsolatedUidRange uidRange = allocator.getOrCreateIsolatedUidRangeLocked(
+ appInfo.processName, appInfo.uid);
validateAppZygoteIsolatedUidRange(uidRange);
verifyIsolatedUidAllocator(uidRange);
}
@@ -363,7 +366,8 @@
appInfo = new ApplicationInfo();
appInfo.uid = 9000;
appInfo.processName = "com.android.test.app.failed";
- IsolatedUidRange failedRange = allocator.getOrCreateIsolatedUidRangeLocked(appInfo);
+ IsolatedUidRange failedRange = allocator.getOrCreateIsolatedUidRangeLocked(
+ appInfo.processName, appInfo.uid);
assertNull(failedRange);
}
diff --git a/services/tests/servicestests/src/com/android/server/appop/AppOpsServiceTest.java b/services/tests/servicestests/src/com/android/server/appop/AppOpsServiceTest.java
index 36f84d0..c42a718 100644
--- a/services/tests/servicestests/src/com/android/server/appop/AppOpsServiceTest.java
+++ b/services/tests/servicestests/src/com/android/server/appop/AppOpsServiceTest.java
@@ -15,8 +15,11 @@
*/
package com.android.server.appop;
+import static android.app.ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE;
+import static android.app.ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE_LOCATION;
import static android.app.AppOpsManager.MODE_ALLOWED;
import static android.app.AppOpsManager.MODE_ERRORED;
+import static android.app.AppOpsManager.MODE_FOREGROUND;
import static android.app.AppOpsManager.OP_COARSE_LOCATION;
import static android.app.AppOpsManager.OP_READ_SMS;
import static android.app.AppOpsManager.OP_WIFI_SCAN;
@@ -25,6 +28,7 @@
import static com.google.common.truth.Truth.assertThat;
import static com.google.common.truth.Truth.assertWithMessage;
+import android.app.ActivityManager;
import android.app.AppOpsManager.OpEntry;
import android.app.AppOpsManager.PackageOps;
import android.content.Context;
@@ -37,6 +41,7 @@
import androidx.test.runner.AndroidJUnit4;
import com.android.server.appop.AppOpsService;
+
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
@@ -222,6 +227,108 @@
assertThat(getLoggedOps()).isNull();
}
+ private void setupProcStateTests() {
+ // For the location proc state tests
+ mAppOpsService.setMode(OP_COARSE_LOCATION, mMyUid, mMyPackageName, MODE_FOREGROUND);
+ mAppOpsService.mConstants.FG_SERVICE_STATE_SETTLE_TIME = 0;
+ mAppOpsService.mConstants.TOP_STATE_SETTLE_TIME = 0;
+ mAppOpsService.mConstants.BG_STATE_SETTLE_TIME = 0;
+ }
+
+ @Test
+ public void testUidProcStateChange_cachedToTopToCached() throws Exception {
+ setupProcStateTests();
+
+ mAppOpsService.updateUidProcState(mMyUid, ActivityManager.PROCESS_STATE_CACHED_EMPTY);
+ assertThat(mAppOpsService.noteOperation(OP_COARSE_LOCATION, mMyUid, mMyPackageName))
+ .isNotEqualTo(MODE_ALLOWED);
+
+ mAppOpsService.updateUidProcState(mMyUid, ActivityManager.PROCESS_STATE_TOP);
+ assertThat(mAppOpsService.noteOperation(OP_COARSE_LOCATION, mMyUid, mMyPackageName))
+ .isEqualTo(MODE_ALLOWED);
+
+ mAppOpsService.updateUidProcState(mMyUid, ActivityManager.PROCESS_STATE_CACHED_EMPTY);
+ // Second time to make sure that settle time is overcome
+ Thread.sleep(50);
+ mAppOpsService.updateUidProcState(mMyUid, ActivityManager.PROCESS_STATE_CACHED_EMPTY);
+ assertThat(mAppOpsService.noteOperation(OP_COARSE_LOCATION, mMyUid, mMyPackageName))
+ .isNotEqualTo(MODE_ALLOWED);
+ }
+
+ @Test
+ public void testUidProcStateChange_cachedToFgs() throws Exception {
+ setupProcStateTests();
+
+ mAppOpsService.updateUidProcState(mMyUid, ActivityManager.PROCESS_STATE_CACHED_EMPTY);
+ assertThat(mAppOpsService.noteOperation(OP_COARSE_LOCATION, mMyUid, mMyPackageName))
+ .isNotEqualTo(MODE_ALLOWED);
+
+ mAppOpsService.updateUidProcState(mMyUid, PROCESS_STATE_FOREGROUND_SERVICE);
+ assertThat(mAppOpsService.noteOperation(OP_COARSE_LOCATION, mMyUid, mMyPackageName))
+ .isNotEqualTo(MODE_ALLOWED);
+ }
+
+ @Test
+ public void testUidProcStateChange_cachedToFgsLocation() throws Exception {
+ setupProcStateTests();
+
+ mAppOpsService.updateUidProcState(mMyUid, ActivityManager.PROCESS_STATE_CACHED_EMPTY);
+ assertThat(mAppOpsService.noteOperation(OP_COARSE_LOCATION, mMyUid, mMyPackageName))
+ .isNotEqualTo(MODE_ALLOWED);
+
+ mAppOpsService.updateUidProcState(mMyUid,
+ PROCESS_STATE_FOREGROUND_SERVICE_LOCATION);
+ assertThat(mAppOpsService.noteOperation(OP_COARSE_LOCATION, mMyUid, mMyPackageName))
+ .isEqualTo(MODE_ALLOWED);
+ }
+
+ @Test
+ public void testUidProcStateChange_topToFgs() throws Exception {
+ setupProcStateTests();
+
+ mAppOpsService.updateUidProcState(mMyUid, ActivityManager.PROCESS_STATE_CACHED_EMPTY);
+ assertThat(mAppOpsService.noteOperation(OP_COARSE_LOCATION, mMyUid, mMyPackageName))
+ .isNotEqualTo(MODE_ALLOWED);
+
+ mAppOpsService.updateUidProcState(mMyUid, ActivityManager.PROCESS_STATE_TOP);
+ assertThat(mAppOpsService.noteOperation(OP_COARSE_LOCATION, mMyUid, mMyPackageName))
+ .isEqualTo(MODE_ALLOWED);
+
+ mAppOpsService.updateUidProcState(mMyUid, PROCESS_STATE_FOREGROUND_SERVICE);
+ // Second time to make sure that settle time is overcome
+ Thread.sleep(50);
+ mAppOpsService.updateUidProcState(mMyUid, PROCESS_STATE_FOREGROUND_SERVICE);
+ assertThat(mAppOpsService.noteOperation(OP_COARSE_LOCATION, mMyUid, mMyPackageName))
+ .isNotEqualTo(MODE_ALLOWED);
+ }
+
+ @Test
+ public void testUidProcStateChange_topToFgsLocationToFgs() throws Exception {
+ setupProcStateTests();
+
+ mAppOpsService.updateUidProcState(mMyUid, ActivityManager.PROCESS_STATE_CACHED_EMPTY);
+ assertThat(mAppOpsService.noteOperation(OP_COARSE_LOCATION, mMyUid, mMyPackageName))
+ .isNotEqualTo(MODE_ALLOWED);
+
+ mAppOpsService.updateUidProcState(mMyUid, ActivityManager.PROCESS_STATE_TOP);
+ assertThat(mAppOpsService.noteOperation(OP_COARSE_LOCATION, mMyUid, mMyPackageName))
+ .isEqualTo(MODE_ALLOWED);
+
+ mAppOpsService.updateUidProcState(mMyUid, PROCESS_STATE_FOREGROUND_SERVICE_LOCATION);
+ // Second time to make sure that settle time is overcome
+ Thread.sleep(50);
+ mAppOpsService.updateUidProcState(mMyUid, PROCESS_STATE_FOREGROUND_SERVICE_LOCATION);
+ assertThat(mAppOpsService.noteOperation(OP_COARSE_LOCATION, mMyUid, mMyPackageName))
+ .isEqualTo(MODE_ALLOWED);
+
+ mAppOpsService.updateUidProcState(mMyUid, PROCESS_STATE_FOREGROUND_SERVICE);
+ // Second time to make sure that settle time is overcome
+ Thread.sleep(50);
+ mAppOpsService.updateUidProcState(mMyUid, PROCESS_STATE_FOREGROUND_SERVICE);
+ assertThat(mAppOpsService.noteOperation(OP_COARSE_LOCATION, mMyUid, mMyPackageName))
+ .isNotEqualTo(MODE_ALLOWED);
+ }
+
private List<PackageOps> getLoggedOps() {
return mAppOpsService.getOpsForPackage(mMyUid, mMyPackageName, null /* all ops */);
}
diff --git a/services/tests/uiservicestests/src/com/android/server/notification/BuzzBeepBlinkTest.java b/services/tests/uiservicestests/src/com/android/server/notification/BuzzBeepBlinkTest.java
index 6be2c2e..49ee8b3 100644
--- a/services/tests/uiservicestests/src/com/android/server/notification/BuzzBeepBlinkTest.java
+++ b/services/tests/uiservicestests/src/com/android/server/notification/BuzzBeepBlinkTest.java
@@ -48,8 +48,8 @@
import android.app.Notification.Builder;
import android.app.NotificationChannel;
import android.app.NotificationManager;
-import android.content.Context;
import android.content.pm.PackageManager;
+import android.content.res.Resources;
import android.graphics.Color;
import android.media.AudioAttributes;
import android.media.AudioManager;
@@ -63,6 +63,7 @@
import android.service.notification.NotificationListenerService;
import android.service.notification.StatusBarNotification;
import android.test.suitebuilder.annotation.SmallTest;
+import android.testing.TestableContext;
import android.view.accessibility.AccessibilityEvent;
import android.view.accessibility.AccessibilityManager;
import android.view.accessibility.IAccessibilityManager;
@@ -70,6 +71,7 @@
import androidx.test.runner.AndroidJUnit4;
+import com.android.internal.R;
import com.android.internal.util.IntPair;
import com.android.server.UiServiceTestCase;
import com.android.server.lights.Light;
@@ -86,6 +88,7 @@
@RunWith(AndroidJUnit4.class)
public class BuzzBeepBlinkTest extends UiServiceTestCase {
+ private TestableContext mContext = spy(getContext());
@Mock AudioManager mAudioManager;
@Mock Vibrator mVibrator;
@Mock android.media.IRingtonePlayer mRingtonePlayer;
@@ -96,6 +99,8 @@
NotificationUsageStats mUsageStats;
@Mock
IAccessibilityManager mAccessibilityService;
+ @Mock
+ Resources mResources;
private NotificationManagerService mService;
private String mPkg = "com.android.server.notification";
@@ -145,7 +150,7 @@
verify(mAccessibilityService).addClient(any(IAccessibilityManagerClient.class), anyInt());
assertTrue(accessibilityManager.isEnabled());
- mService = spy(new NotificationManagerService(getContext()));
+ mService = spy(new NotificationManagerService(mContext));
mService.setAudioManager(mAudioManager);
mService.setVibrator(mVibrator);
mService.setSystemReady(true);
@@ -275,7 +280,7 @@
boolean isLeanback) {
NotificationChannel channel =
new NotificationChannel("test", "test", IMPORTANCE_HIGH);
- final Builder builder = new Builder(getContext())
+ final Builder builder = new Builder(mContext)
.setContentTitle("foo")
.setSmallIcon(android.R.drawable.sym_def_app_icon)
.setPriority(Notification.PRIORITY_HIGH)
@@ -321,15 +326,14 @@
n.flags |= Notification.FLAG_INSISTENT;
}
- Context context = spy(getContext());
- PackageManager packageManager = spy(context.getPackageManager());
- when(context.getPackageManager()).thenReturn(packageManager);
+ PackageManager packageManager = spy(mContext.getPackageManager());
+ when(mContext.getPackageManager()).thenReturn(packageManager);
when(packageManager.hasSystemFeature(PackageManager.FEATURE_LEANBACK))
.thenReturn(isLeanback);
StatusBarNotification sbn = new StatusBarNotification(mPkg, mPkg, id, mTag, mUid,
mPid, n, mUser, null, System.currentTimeMillis());
- NotificationRecord r = new NotificationRecord(context, sbn, channel);
+ NotificationRecord r = new NotificationRecord(mContext, sbn, channel);
mService.addNotification(r);
return r;
}
@@ -455,7 +459,25 @@
}
@Test
- public void testNoBeepForImportanceDefaultInAutomotive() throws Exception {
+ public void testNoBeepForAutomotiveIfEffectsDisabled() throws Exception {
+ when(mContext.getResources()).thenReturn(mResources);
+ when(mResources.getBoolean(R.bool.config_enableServerNotificationEffectsForAutomotive))
+ .thenReturn(false);
+ mService.setIsAutomotive(true);
+
+ NotificationRecord r = getBeepyNotification();
+
+ mService.buzzBeepBlinkLocked(r);
+
+ verifyNeverBeep();
+ assertFalse(r.isInterruptive());
+ }
+
+ @Test
+ public void testNoBeepForImportanceDefaultInAutomotiveIfEffectsEnabled() throws Exception {
+ when(mContext.getResources()).thenReturn(mResources);
+ when(mResources.getBoolean(R.bool.config_enableServerNotificationEffectsForAutomotive))
+ .thenReturn(true);
mService.setIsAutomotive(true);
NotificationRecord r = getBeepyNotification();
@@ -468,7 +490,10 @@
}
@Test
- public void testBeepForImportanceHighInAutomotive() throws Exception {
+ public void testBeepForImportanceHighInAutomotiveIfEffectsEnabled() throws Exception {
+ when(mContext.getResources()).thenReturn(mResources);
+ when(mResources.getBoolean(R.bool.config_enableServerNotificationEffectsForAutomotive))
+ .thenReturn(true);
mService.setIsAutomotive(true);
NotificationRecord r = getBeepyNotification();
@@ -1015,12 +1040,12 @@
public void testEmptyUriSoundTreatedAsNoSound() throws Exception {
NotificationChannel channel = new NotificationChannel("test", "test", IMPORTANCE_HIGH);
channel.setSound(Uri.EMPTY, null);
- final Notification n = new Builder(getContext(), "test")
+ final Notification n = new Builder(mContext, "test")
.setSmallIcon(android.R.drawable.sym_def_app_icon).build();
StatusBarNotification sbn = new StatusBarNotification(mPkg, mPkg, 0, mTag, mUid,
mPid, n, mUser, null, System.currentTimeMillis());
- NotificationRecord r = new NotificationRecord(getContext(), sbn, channel);
+ NotificationRecord r = new NotificationRecord(mContext, sbn, channel);
mService.addNotification(r);
mService.buzzBeepBlinkLocked(r);
@@ -1069,13 +1094,13 @@
@Test
public void testCrossUserSoundMuted() throws Exception {
- final Notification n = new Builder(getContext(), "test")
+ final Notification n = new Builder(mContext, "test")
.setSmallIcon(android.R.drawable.sym_def_app_icon).build();
int userId = mUser.getIdentifier() + 1;
StatusBarNotification sbn = new StatusBarNotification(mPkg, mPkg, 0, mTag, mUid,
mPid, n, UserHandle.of(userId), null, System.currentTimeMillis());
- NotificationRecord r = new NotificationRecord(getContext(), sbn,
+ NotificationRecord r = new NotificationRecord(mContext, sbn,
new NotificationChannel("test", "test", IMPORTANCE_HIGH));
mService.buzzBeepBlinkLocked(r);
diff --git a/services/tests/wmtests/src/com/android/server/wm/ActivityStarterTests.java b/services/tests/wmtests/src/com/android/server/wm/ActivityStarterTests.java
index 44aa55d..45d5219 100644
--- a/services/tests/wmtests/src/com/android/server/wm/ActivityStarterTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/ActivityStarterTests.java
@@ -577,12 +577,27 @@
UNIMPORTANT_UID, false, PROCESS_STATE_TOP + 1,
UNIMPORTANT_UID2, false, PROCESS_STATE_TOP + 1,
false, false, false, false, false, false);
+ runAndVerifyBackgroundActivityStartsSubtest(
+ "disallowed_callingUidProcessStateTop_aborted", true,
+ UNIMPORTANT_UID, false, PROCESS_STATE_TOP,
+ UNIMPORTANT_UID2, false, PROCESS_STATE_TOP + 1,
+ false, false, false, false, false, false);
+ runAndVerifyBackgroundActivityStartsSubtest(
+ "disallowed_realCallingUidProcessStateTop_aborted", true,
+ UNIMPORTANT_UID, false, PROCESS_STATE_TOP + 1,
+ UNIMPORTANT_UID2, false, PROCESS_STATE_TOP,
+ false, false, false, false, false, false);
+ runAndVerifyBackgroundActivityStartsSubtest(
+ "disallowed_hasForegroundActivities_aborted", true,
+ UNIMPORTANT_UID, false, PROCESS_STATE_TOP + 1,
+ UNIMPORTANT_UID2, false, PROCESS_STATE_TOP + 1,
+ true, false, false, false, false, false);
}
/**
* This test ensures that supported usecases aren't aborted when background starts are
* disallowed.
- * The scenarios each have only one condidion that makes them supported.
+ * The scenarios each have only one condition that makes them supported.
*/
@Test
public void testBackgroundActivityStartsDisallowed_supportedStartsNotAborted() {
@@ -606,26 +621,11 @@
UNIMPORTANT_UID2, false, PROCESS_STATE_TOP + 1,
false, false, false, false, false, false);
runAndVerifyBackgroundActivityStartsSubtest(
- "disallowed_callingUidProcessStateTop_notAborted", false,
- UNIMPORTANT_UID, false, PROCESS_STATE_TOP,
- UNIMPORTANT_UID2, false, PROCESS_STATE_TOP + 1,
- false, false, false, false, false, false);
- runAndVerifyBackgroundActivityStartsSubtest(
"disallowed_realCallingUidHasVisibleWindow_notAborted", false,
UNIMPORTANT_UID, false, PROCESS_STATE_TOP + 1,
UNIMPORTANT_UID2, true, PROCESS_STATE_TOP + 1,
false, false, false, false, false, false);
runAndVerifyBackgroundActivityStartsSubtest(
- "disallowed_realCallingUidProcessStateTop_notAborted", false,
- UNIMPORTANT_UID, false, PROCESS_STATE_TOP + 1,
- UNIMPORTANT_UID2, false, PROCESS_STATE_TOP,
- false, false, false, false, false, false);
- runAndVerifyBackgroundActivityStartsSubtest(
- "disallowed_hasForegroundActivities_notAborted", false,
- UNIMPORTANT_UID, false, PROCESS_STATE_TOP + 1,
- UNIMPORTANT_UID2, false, PROCESS_STATE_TOP + 1,
- true, false, false, false, false, false);
- runAndVerifyBackgroundActivityStartsSubtest(
"disallowed_callerIsRecents_notAborted", false,
UNIMPORTANT_UID, false, PROCESS_STATE_TOP + 1,
UNIMPORTANT_UID2, false, PROCESS_STATE_TOP + 1,
diff --git a/services/tests/wmtests/src/com/android/server/wm/AppWindowTokenTests.java b/services/tests/wmtests/src/com/android/server/wm/AppWindowTokenTests.java
index c4009df..ca3f684 100644
--- a/services/tests/wmtests/src/com/android/server/wm/AppWindowTokenTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/AppWindowTokenTests.java
@@ -52,6 +52,7 @@
import android.view.Surface;
import android.view.WindowManager;
+import androidx.test.filters.FlakyTest;
import androidx.test.filters.SmallTest;
import org.junit.Before;
@@ -383,6 +384,7 @@
}
@Test
+ @FlakyTest(bugId = 130392471)
public void testAddRemoveRace() {
// There was once a race condition between adding and removing starting windows
for (int i = 0; i < 1000; i++) {
diff --git a/services/tests/wmtests/src/com/android/server/wm/AssistDataRequesterTest.java b/services/tests/wmtests/src/com/android/server/wm/AssistDataRequesterTest.java
index 329af95..bb574ce 100644
--- a/services/tests/wmtests/src/com/android/server/wm/AssistDataRequesterTest.java
+++ b/services/tests/wmtests/src/com/android/server/wm/AssistDataRequesterTest.java
@@ -48,6 +48,7 @@
import android.util.Log;
import android.view.IWindowManager;
+import androidx.test.filters.FlakyTest;
import androidx.test.filters.MediumTest;
import com.android.server.am.AssistDataRequester;
@@ -150,6 +151,7 @@
}
@Test
+ @FlakyTest(bugId = 130388718)
public void testRequestData() throws Exception {
setupMocks(CURRENT_ACTIVITY_ASSIST_ALLOWED, CALLER_ASSIST_STRUCTURE_ALLOWED,
CALLER_ASSIST_SCREENSHOT_ALLOWED);
@@ -250,6 +252,7 @@
}
@Test
+ @FlakyTest(bugId = 130388718)
public void testNoFetchScreenshots_expectNoScreenshotCallbacks() throws Exception {
setupMocks(CURRENT_ACTIVITY_ASSIST_ALLOWED, CALLER_ASSIST_STRUCTURE_ALLOWED,
CALLER_ASSIST_SCREENSHOT_ALLOWED);
@@ -260,6 +263,7 @@
}
@Test
+ @FlakyTest(bugId = 130388718)
public void testDisallowAssistScreenshot_expectNullScreenshotCallback() throws Exception {
setupMocks(CURRENT_ACTIVITY_ASSIST_ALLOWED, CALLER_ASSIST_STRUCTURE_ALLOWED,
!CALLER_ASSIST_SCREENSHOT_ALLOWED);
diff --git a/services/tests/wmtests/src/com/android/server/wm/RootWindowContainerTests.java b/services/tests/wmtests/src/com/android/server/wm/RootWindowContainerTests.java
index 35a8ec3..263f650 100644
--- a/services/tests/wmtests/src/com/android/server/wm/RootWindowContainerTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/RootWindowContainerTests.java
@@ -50,8 +50,8 @@
toastyToast.mHasSurface = true;
app.mHasSurface = true;
- assertTrue(toastyToast.isVisible());
- assertTrue(app.isVisible());
+ assertTrue(toastyToast.isVisibleNow());
+ assertTrue(app.isVisibleNow());
assertTrue(mWm.mRoot.isAnyNonToastWindowVisibleForUid(FAKE_CALLING_UID));
}
@@ -60,7 +60,7 @@
final WindowState toastyToast = createWindow(null, TYPE_TOAST, "toast", FAKE_CALLING_UID);
toastyToast.mHasSurface = true;
- assertTrue(toastyToast.isVisible());
+ assertTrue(toastyToast.isVisibleNow());
assertFalse(mWm.mRoot.isAnyNonToastWindowVisibleForUid(FAKE_CALLING_UID));
}
@@ -69,8 +69,8 @@
final WindowState topBar = createWindow(null, TYPE_STATUS_BAR, "topBar", FAKE_CALLING_UID);
final WindowState app = createWindow(null, TYPE_APPLICATION, "app", FAKE_CALLING_UID);
- assertFalse(topBar.isVisible());
- assertFalse(app.isVisible());
+ assertFalse(topBar.isVisibleNow());
+ assertFalse(app.isVisibleNow());
assertFalse(mWm.mRoot.isAnyNonToastWindowVisibleForUid(FAKE_CALLING_UID));
}
diff --git a/services/tests/wmtests/src/com/android/server/wm/TaskSnapshotPersisterTestBase.java b/services/tests/wmtests/src/com/android/server/wm/TaskSnapshotPersisterTestBase.java
index d29e3fa..c3b0a67 100644
--- a/services/tests/wmtests/src/com/android/server/wm/TaskSnapshotPersisterTestBase.java
+++ b/services/tests/wmtests/src/com/android/server/wm/TaskSnapshotPersisterTestBase.java
@@ -27,6 +27,7 @@
import android.content.ComponentName;
import android.graphics.Canvas;
import android.graphics.Color;
+import android.graphics.ColorSpace;
import android.graphics.GraphicBuffer;
import android.graphics.PixelFormat;
import android.graphics.Rect;
@@ -127,8 +128,9 @@
Canvas c = buffer.lockCanvas();
c.drawColor(Color.RED);
buffer.unlockCanvasAndPost(c);
- return new TaskSnapshot(new ComponentName("", ""), buffer, ORIENTATION_PORTRAIT,
- TEST_INSETS, mScale < 1f /* reducedResolution */, mScale, mIsRealSnapshot,
+ return new TaskSnapshot(new ComponentName("", ""), buffer,
+ ColorSpace.get(ColorSpace.Named.SRGB), ORIENTATION_PORTRAIT, TEST_INSETS,
+ mScale < 1f /* reducedResolution */, mScale, mIsRealSnapshot,
mWindowingMode, mSystemUiVisibility, mIsTranslucent);
}
}
diff --git a/services/tests/wmtests/src/com/android/server/wm/TaskSnapshotSurfaceTest.java b/services/tests/wmtests/src/com/android/server/wm/TaskSnapshotSurfaceTest.java
index cb6dc6d..4ca01ec 100644
--- a/services/tests/wmtests/src/com/android/server/wm/TaskSnapshotSurfaceTest.java
+++ b/services/tests/wmtests/src/com/android/server/wm/TaskSnapshotSurfaceTest.java
@@ -35,6 +35,7 @@
import android.content.ComponentName;
import android.graphics.Canvas;
import android.graphics.Color;
+import android.graphics.ColorSpace;
import android.graphics.GraphicBuffer;
import android.graphics.PixelFormat;
import android.graphics.Rect;
@@ -64,8 +65,9 @@
final GraphicBuffer buffer = GraphicBuffer.create(width, height, PixelFormat.RGBA_8888,
GraphicBuffer.USAGE_SW_READ_RARELY | GraphicBuffer.USAGE_SW_WRITE_NEVER);
final TaskSnapshot snapshot = new TaskSnapshot(new ComponentName("", ""), buffer,
- ORIENTATION_PORTRAIT, contentInsets, false, 1.0f, true /* isRealSnapshot */,
- WINDOWING_MODE_FULLSCREEN, 0 /* systemUiVisibility */, false /* isTranslucent */);
+ ColorSpace.get(ColorSpace.Named.SRGB), ORIENTATION_PORTRAIT, contentInsets, false,
+ 1.0f, true /* isRealSnapshot */, WINDOWING_MODE_FULLSCREEN,
+ 0 /* systemUiVisibility */, false /* isTranslucent */);
mSurface = new TaskSnapshotSurface(mWm, new Window(), new SurfaceControl(), snapshot, "Test",
createTaskDescription(Color.WHITE, Color.RED, Color.BLUE), sysuiVis, windowFlags, 0,
taskBounds, ORIENTATION_PORTRAIT);
diff --git a/services/tests/wmtests/src/com/android/server/wm/TaskStackChangedListenerTest.java b/services/tests/wmtests/src/com/android/server/wm/TaskStackChangedListenerTest.java
index 9722d2c..62247d8 100644
--- a/services/tests/wmtests/src/com/android/server/wm/TaskStackChangedListenerTest.java
+++ b/services/tests/wmtests/src/com/android/server/wm/TaskStackChangedListenerTest.java
@@ -39,6 +39,7 @@
import android.support.test.uiautomator.UiDevice;
import android.text.TextUtils;
+import androidx.test.filters.FlakyTest;
import androidx.test.filters.MediumTest;
import com.android.internal.annotations.GuardedBy;
@@ -78,6 +79,7 @@
@Test
@Presubmit
+ @FlakyTest(bugId = 130388819)
public void testTaskStackChanged_afterFinish() throws Exception {
registerTaskStackChangedListener(new TaskStackListener() {
@Override
@@ -159,6 +161,7 @@
*/
@Test
@Presubmit
+ @FlakyTest(bugId = 130388819)
public void testTaskChangeCallBacks() throws Exception {
final Object[] params = new Object[2];
final CountDownLatch taskCreatedLaunchLatch = new CountDownLatch(1);
diff --git a/services/tests/wmtests/src/com/android/server/wm/WindowFrameTests.java b/services/tests/wmtests/src/com/android/server/wm/WindowFrameTests.java
index 78fca0f..06bcdf8 100644
--- a/services/tests/wmtests/src/com/android/server/wm/WindowFrameTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/WindowFrameTests.java
@@ -36,6 +36,7 @@
import android.view.IWindow;
import android.view.WindowManager;
+import androidx.test.filters.FlakyTest;
import androidx.test.filters.SmallTest;
import com.android.server.wm.utils.WmDisplayCutout;
@@ -323,6 +324,7 @@
}
@Test
+ @FlakyTest(bugId = 130388666)
public void testCalculatePolicyCrop() {
final FrameTestWindowState w = createWindow(MATCH_PARENT, MATCH_PARENT);
w.mAttrs.gravity = Gravity.LEFT | Gravity.TOP;
@@ -423,6 +425,7 @@
}
@Test
+ @FlakyTest(bugId = 130388666)
public void testDisplayCutout() {
// Regular fullscreen task and window
WindowState w = createWindow(MATCH_PARENT, MATCH_PARENT);
@@ -446,6 +449,7 @@
}
@Test
+ @FlakyTest(bugId = 130388666)
public void testDisplayCutout_tempDisplayedBounds() {
// Regular fullscreen task and window
WindowState w = createWindow(MATCH_PARENT, MATCH_PARENT);
diff --git a/telephony/java/android/provider/Telephony.java b/telephony/java/android/provider/Telephony.java
index 2d8a8cb..037e475 100644
--- a/telephony/java/android/provider/Telephony.java
+++ b/telephony/java/android/provider/Telephony.java
@@ -3394,6 +3394,7 @@
* {@link SubscriptionManager#getDefaultSubscriptionId()}. To specify subId for MSIM,
* use {@link Uri#withAppendedPath(Uri, String)} to append with subscription id.
*/
+ @NonNull
public static final Uri CONTENT_URI = Uri.parse("content://telephony/carriers");
/**
@@ -3406,6 +3407,7 @@
* {@link SubscriptionManager#getDefaultSubscriptionId()}. To specify subId for MSIM,
* use {@link Uri#withAppendedPath(Uri, String)} to append with subscription id.
*/
+ @NonNull
public static final Uri SIM_APN_URI = Uri.parse(
"content://telephony/carriers/sim_apn_list");
diff --git a/telephony/java/android/telephony/CarrierConfigManager.java b/telephony/java/android/telephony/CarrierConfigManager.java
index 9f6528b..d2f88bb 100755
--- a/telephony/java/android/telephony/CarrierConfigManager.java
+++ b/telephony/java/android/telephony/CarrierConfigManager.java
@@ -2804,7 +2804,7 @@
* @hide
*/
public static final String KEY_SUBSCRIPTION_GROUP_UUID_STRING =
- "key_subscription_group_uuid_string";
+ "subscription_group_uuid_string";
/**
* A boolean property indicating whether this subscription should be managed as an opportunistic
@@ -2819,7 +2819,7 @@
* @hide
*/
public static final String KEY_IS_OPPORTUNISTIC_SUBSCRIPTION_BOOL =
- "key_is_opportunistic_subscription_bool";
+ "is_opportunistic_subscription_bool";
/**
* A list of 4 GSM RSSI thresholds above which a signal level is considered POOR,
diff --git a/telephony/java/android/telephony/CarrierRestrictionRules.java b/telephony/java/android/telephony/CarrierRestrictionRules.java
index 78623e7..950ae6c 100644
--- a/telephony/java/android/telephony/CarrierRestrictionRules.java
+++ b/telephony/java/android/telephony/CarrierRestrictionRules.java
@@ -336,7 +336,6 @@
public static final class Builder {
private final CarrierRestrictionRules mRules;
- /** {@hide} */
public Builder() {
mRules = new CarrierRestrictionRules();
}