summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Android.bp20
-rw-r--r--apex/media/framework/api/current.txt3
-rw-r--r--apex/media/framework/java/android/media/MediaParser.java16
-rw-r--r--apex/permission/framework/Android.bp4
-rw-r--r--api/current.txt34
-rwxr-xr-xapi/system-current.txt29
-rw-r--r--core/java/android/content/pm/DataLoaderParams.java22
-rw-r--r--core/java/android/content/pm/DataLoaderParamsParcel.aidl2
-rw-r--r--core/java/android/content/pm/NamedParcelFileDescriptor.aidl28
-rw-r--r--core/java/android/net/ConnectivityManager.java30
-rw-r--r--core/java/android/net/NetworkAgent.java135
-rw-r--r--core/java/android/net/NetworkAgentConfig.java3
-rw-r--r--core/java/android/net/NetworkRequest.java2
-rw-r--r--core/java/android/net/SocketKeepalive.java10
-rw-r--r--core/java/android/os/IVibratorService.aidl2
-rw-r--r--core/java/android/os/SystemVibrator.java11
-rw-r--r--core/java/android/os/VibrationEffect.java12
-rw-r--r--core/java/android/os/Vibrator.java94
-rw-r--r--core/java/android/provider/Settings.java17
-rw-r--r--core/java/android/service/dataloader/DataLoaderService.java11
-rw-r--r--core/proto/android/providers/settings/secure.proto2
-rw-r--r--core/res/res/values/config.xml3
-rw-r--r--core/res/res/values/symbols.xml3
-rw-r--r--core/tests/coretests/src/android/widget/EditorCursorDragTest.java1
-rw-r--r--media/java/android/media/AudioDeviceInfo.java4
-rw-r--r--media/java/android/media/AudioManager.java8
-rw-r--r--media/java/android/media/AudioMetadata.java95
-rw-r--r--media/java/android/media/AudioMetadataMap.java59
-rw-r--r--media/java/android/media/AudioMetadataReadMap.java81
-rw-r--r--media/java/android/media/AudioTrack.java101
-rw-r--r--packages/SettingsProvider/src/android/provider/settings/backup/SecureSettings.java2
-rw-r--r--packages/SettingsProvider/src/android/provider/settings/validators/SecureSettingsValidators.java6
-rw-r--r--packages/SettingsProvider/src/com/android/providers/settings/SettingsProtoDumpUtil.java4
-rw-r--r--packages/Shell/src/com/android/shell/BugreportProgressService.java4
-rw-r--r--packages/SystemUI/res/values-television/dimens.xml20
-rw-r--r--packages/SystemUI/res/values-television/styles.xml5
-rw-r--r--packages/SystemUI/res/values/dimens.xml3
-rw-r--r--packages/SystemUI/res/values/styles.xml3
-rw-r--r--packages/SystemUI/src/com/android/systemui/bubbles/BadgedImageView.java115
-rw-r--r--packages/SystemUI/src/com/android/systemui/bubbles/Bubble.java13
-rw-r--r--packages/SystemUI/src/com/android/systemui/bubbles/BubbleController.java8
-rw-r--r--packages/SystemUI/src/com/android/systemui/bubbles/BubbleData.java2
-rw-r--r--packages/SystemUI/src/com/android/systemui/bubbles/BubbleOverflow.java2
-rw-r--r--packages/SystemUI/src/com/android/systemui/bubbles/BubbleOverflowActivity.java2
-rw-r--r--packages/SystemUI/src/com/android/systemui/bubbles/BubbleStackView.java39
-rw-r--r--packages/SystemUI/src/com/android/systemui/bubbles/animation/StackAnimationController.java2
-rw-r--r--packages/SystemUI/src/com/android/systemui/globalactions/GlobalActionsImpl.java8
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/policy/BatteryControllerImpl.java6
-rw-r--r--services/core/java/com/android/server/PackageWatchdog.java13
-rw-r--r--services/core/java/com/android/server/VibratorService.java17
-rwxr-xr-xservices/core/java/com/android/server/notification/NotificationManagerService.java27
-rw-r--r--services/core/java/com/android/server/pm/PackageInstallerSession.java3
-rw-r--r--services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java6
-rw-r--r--services/incremental/IncrementalService.cpp1
-rw-r--r--services/tests/servicestests/src/com/android/server/MountServiceTests.java279
-rw-r--r--tests/PackageWatchdog/src/com/android/server/PackageWatchdogTest.java22
-rw-r--r--wifi/Android.bp1
57 files changed, 697 insertions, 758 deletions
diff --git a/Android.bp b/Android.bp
index 7f4cd849ab77..6653bd44966b 100644
--- a/Android.bp
+++ b/Android.bp
@@ -577,25 +577,6 @@ platform_compat_config {
src: ":framework-annotation-proc",
}
-// A library including just UnsupportedAppUsage.java classes.
-//
-// Provided for target so that libraries can use it without depending on
-// the whole of framework or the core platform API.
-//
-// Built for host so that the annotation processor can also use this annotation.
-java_library {
- name: "unsupportedappusage-annotation",
- host_supported: true,
- srcs: [
- "core/java/android/annotation/IntDef.java",
- ],
- static_libs: [
- "art.module.api.annotations",
- ],
-
- sdk_version: "core_current",
-}
-
// A temporary build target that is conditionally included on the bootclasspath if
// android.test.base library has been removed and which provides support for
// maintaining backwards compatibility for APKs that target pre-P and depend on
@@ -971,7 +952,6 @@ filegroup {
"core/java/android/content/pm/InstallationFileLocation.aidl",
"core/java/android/content/pm/IDataLoaderStatusListener.aidl",
"core/java/android/content/pm/IPackageInstallerSessionFileSystemConnector.aidl",
- "core/java/android/content/pm/NamedParcelFileDescriptor.aidl",
],
path: "core/java",
}
diff --git a/apex/media/framework/api/current.txt b/apex/media/framework/api/current.txt
index 839fb5143196..9cec748e7b8e 100644
--- a/apex/media/framework/api/current.txt
+++ b/apex/media/framework/api/current.txt
@@ -29,7 +29,7 @@ package android.media {
method public boolean advance(@NonNull android.media.MediaParser.SeekableInputReader) throws java.io.IOException;
method @NonNull public static android.media.MediaParser create(@NonNull android.media.MediaParser.OutputConsumer, @NonNull java.lang.String...);
method @NonNull public static android.media.MediaParser createByName(@NonNull String, @NonNull android.media.MediaParser.OutputConsumer);
- method @Nullable public String getParserName();
+ method @NonNull public String getParserName();
method @NonNull public static java.util.List<java.lang.String> getParserNames(@NonNull android.media.MediaFormat);
method public void release();
method public void seek(@NonNull android.media.MediaParser.SeekPoint);
@@ -65,6 +65,7 @@ package android.media {
field public static final String PARSER_NAME_OGG = "android.media.mediaparser.OggParser";
field public static final String PARSER_NAME_PS = "android.media.mediaparser.PsParser";
field public static final String PARSER_NAME_TS = "android.media.mediaparser.TsParser";
+ field public static final String PARSER_NAME_UNKNOWN = "android.media.mediaparser.UNKNOWN";
field public static final String PARSER_NAME_WAV = "android.media.mediaparser.WavParser";
}
diff --git a/apex/media/framework/java/android/media/MediaParser.java b/apex/media/framework/java/android/media/MediaParser.java
index 5f86ed621084..c0e3d55b45a6 100644
--- a/apex/media/framework/java/android/media/MediaParser.java
+++ b/apex/media/framework/java/android/media/MediaParser.java
@@ -452,6 +452,7 @@ public final class MediaParser {
@StringDef(
prefix = {"PARSER_NAME_"},
value = {
+ PARSER_NAME_UNKNOWN,
PARSER_NAME_MATROSKA,
PARSER_NAME_FMP4,
PARSER_NAME_MP4,
@@ -469,6 +470,7 @@ public final class MediaParser {
})
public @interface ParserName {}
+ public static final String PARSER_NAME_UNKNOWN = "android.media.mediaparser.UNKNOWN";
public static final String PARSER_NAME_MATROSKA = "android.media.mediaparser.MatroskaParser";
public static final String PARSER_NAME_FMP4 = "android.media.mediaparser.FragmentedMp4Parser";
public static final String PARSER_NAME_MP4 = "android.media.mediaparser.Mp4Parser";
@@ -836,14 +838,14 @@ public final class MediaParser {
* Returns the name of the backing parser implementation.
*
* <p>If this instance was creating using {@link #createByName}, the provided name is returned.
- * If this instance was created using {@link #create}, this method will return null until the
- * first call to {@link #advance}, after which the name of the backing parser implementation is
- * returned.
+ * If this instance was created using {@link #create}, this method will return {@link
+ * #PARSER_NAME_UNKNOWN} until the first call to {@link #advance}, after which the name of the
+ * backing parser implementation is returned.
*
* @return The name of the backing parser implementation, or null if the backing parser
* implementation has not yet been selected.
*/
- @Nullable
+ @NonNull
@ParserName
public String getParserName() {
return mExtractorName;
@@ -880,7 +882,7 @@ public final class MediaParser {
// TODO: Apply parameters when creating extractor instances.
if (mExtractor == null) {
- if (mExtractorName != null) {
+ if (!mExtractorName.equals(PARSER_NAME_UNKNOWN)) {
mExtractor = EXTRACTOR_FACTORIES_BY_NAME.get(mExtractorName).createInstance();
mExtractor.init(new ExtractorOutputAdapter());
} else {
@@ -974,9 +976,7 @@ public final class MediaParser {
mParserParameters = new HashMap<>();
mOutputConsumer = outputConsumer;
mParserNamesPool = parserNamesPool;
- if (!sniff) {
- mExtractorName = parserNamesPool[0];
- }
+ mExtractorName = sniff ? PARSER_NAME_UNKNOWN : parserNamesPool[0];
mPositionHolder = new PositionHolder();
mDataSource = new InputReadingDataSource();
removePendingSeek();
diff --git a/apex/permission/framework/Android.bp b/apex/permission/framework/Android.bp
index 3fefeb51aa11..793247e88614 100644
--- a/apex/permission/framework/Android.bp
+++ b/apex/permission/framework/Android.bp
@@ -31,6 +31,10 @@ java_library {
"com.android.permission",
"test_com.android.permission",
],
+ permitted_packages: [
+ "android.permission",
+ "android.app.role",
+ ],
hostdex: true,
installable: true,
visibility: [
diff --git a/api/current.txt b/api/current.txt
index aca06fe4d3a6..07dba53884dd 100644
--- a/api/current.txt
+++ b/api/current.txt
@@ -24357,7 +24357,7 @@ package android.media {
}
public final class AudioMetadata {
- method @NonNull public static android.media.AudioMetadata.Map createMap();
+ method @NonNull public static android.media.AudioMetadataMap createMap();
}
public static class AudioMetadata.Format {
@@ -24375,16 +24375,16 @@ package android.media {
method @NonNull public Class<T> getValueClass();
}
- public static interface AudioMetadata.Map extends android.media.AudioMetadata.ReadMap {
+ public interface AudioMetadataMap extends android.media.AudioMetadataReadMap {
method @Nullable public <T> T remove(@NonNull android.media.AudioMetadata.Key<T>);
method @Nullable public <T> T set(@NonNull android.media.AudioMetadata.Key<T>, @NonNull T);
}
- public static interface AudioMetadata.ReadMap {
+ public interface AudioMetadataReadMap {
method public <T> boolean containsKey(@NonNull android.media.AudioMetadata.Key<T>);
- method @NonNull public android.media.AudioMetadata.Map dup();
+ method @NonNull public android.media.AudioMetadataMap dup();
method @Nullable public <T> T get(@NonNull android.media.AudioMetadata.Key<T>);
- method public int size();
+ method @IntRange(from=0) public int size();
}
public final class AudioPlaybackCaptureConfiguration {
@@ -24699,7 +24699,7 @@ package android.media {
}
public static interface AudioTrack.OnCodecFormatChangedListener {
- method public void onCodecFormatChanged(@NonNull android.media.AudioTrack, @Nullable android.media.AudioMetadata.ReadMap);
+ method public void onCodecFormatChanged(@NonNull android.media.AudioTrack, @Nullable android.media.AudioMetadataReadMap);
}
public static interface AudioTrack.OnPlaybackPositionUpdateListener {
@@ -26400,7 +26400,7 @@ package android.media {
method public boolean advance(@NonNull android.media.MediaParser.SeekableInputReader) throws java.io.IOException;
method @NonNull public static android.media.MediaParser create(@NonNull android.media.MediaParser.OutputConsumer, @NonNull java.lang.String...);
method @NonNull public static android.media.MediaParser createByName(@NonNull String, @NonNull android.media.MediaParser.OutputConsumer);
- method @Nullable public String getParserName();
+ method @NonNull public String getParserName();
method @NonNull public static java.util.List<java.lang.String> getParserNames(@NonNull android.media.MediaFormat);
method public void release();
method public void seek(@NonNull android.media.MediaParser.SeekPoint);
@@ -26436,6 +26436,7 @@ package android.media {
field public static final String PARSER_NAME_OGG = "android.media.mediaparser.OggParser";
field public static final String PARSER_NAME_PS = "android.media.mediaparser.PsParser";
field public static final String PARSER_NAME_TS = "android.media.mediaparser.TsParser";
+ field public static final String PARSER_NAME_UNKNOWN = "android.media.mediaparser.UNKNOWN";
field public static final String PARSER_NAME_WAV = "android.media.mediaparser.WavParser";
}
@@ -30347,6 +30348,7 @@ package android.net {
method @Nullable public android.net.NetworkSpecifier getNetworkSpecifier();
method public boolean hasCapability(int);
method public boolean hasTransport(int);
+ method public boolean satisfiedBy(@Nullable android.net.NetworkCapabilities);
method public void writeToParcel(android.os.Parcel, int);
field @NonNull public static final android.os.Parcelable.Creator<android.net.NetworkRequest> CREATOR;
}
@@ -37145,11 +37147,10 @@ package android.os {
field public static final int EFFECT_TICK = 2; // 0x2
}
- public static class VibrationEffect.Composition {
- ctor public VibrationEffect.Composition();
- method @Nullable public android.os.VibrationEffect.Composition addPrimitive(int);
- method @Nullable public android.os.VibrationEffect.Composition addPrimitive(int, @FloatRange(from=0.0f, to=1.0f) float);
- method @Nullable public android.os.VibrationEffect.Composition addPrimitive(int, @FloatRange(from=0.0f, to=1.0f) float, @IntRange(from=0) int);
+ public static final class VibrationEffect.Composition {
+ method @NonNull public android.os.VibrationEffect.Composition addPrimitive(int);
+ method @NonNull public android.os.VibrationEffect.Composition addPrimitive(int, @FloatRange(from=0.0f, to=1.0f) float);
+ method @NonNull public android.os.VibrationEffect.Composition addPrimitive(int, @FloatRange(from=0.0f, to=1.0f) float, @IntRange(from=0) int);
method @NonNull public android.os.VibrationEffect compose();
field public static final int PRIMITIVE_CLICK = 1; // 0x1
field public static final int PRIMITIVE_QUICK_FALL = 6; // 0x6
@@ -37159,9 +37160,9 @@ package android.os {
}
public abstract class Vibrator {
- method @Nullable public Boolean areAllEffectsSupported(@NonNull int...);
- method public boolean areAllPrimitivesSupported(@NonNull int...);
- method @Nullable public boolean[] areEffectsSupported(@NonNull int...);
+ method public final int areAllEffectsSupported(@NonNull int...);
+ method public final boolean areAllPrimitivesSupported(@NonNull int...);
+ method @NonNull public int[] areEffectsSupported(@NonNull int...);
method @NonNull public boolean[] arePrimitivesSupported(@NonNull int...);
method @RequiresPermission(android.Manifest.permission.VIBRATE) public abstract void cancel();
method public abstract boolean hasAmplitudeControl();
@@ -37172,6 +37173,9 @@ package android.os {
method @Deprecated @RequiresPermission(android.Manifest.permission.VIBRATE) public void vibrate(long[], int, android.media.AudioAttributes);
method @RequiresPermission(android.Manifest.permission.VIBRATE) public void vibrate(android.os.VibrationEffect);
method @RequiresPermission(android.Manifest.permission.VIBRATE) public void vibrate(android.os.VibrationEffect, android.media.AudioAttributes);
+ field public static final int VIBRATION_EFFECT_SUPPORT_NO = 2; // 0x2
+ field public static final int VIBRATION_EFFECT_SUPPORT_UNKNOWN = 0; // 0x0
+ field public static final int VIBRATION_EFFECT_SUPPORT_YES = 1; // 0x1
}
public class WorkSource implements android.os.Parcelable {
diff --git a/api/system-current.txt b/api/system-current.txt
index e5fd4d39e758..38c265bd50b3 100755
--- a/api/system-current.txt
+++ b/api/system-current.txt
@@ -4178,11 +4178,11 @@ package android.media {
method @RequiresPermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING) public void addOnPreferredDeviceForStrategyChangedListener(@NonNull java.util.concurrent.Executor, @NonNull android.media.AudioManager.OnPreferredDeviceForStrategyChangedListener) throws java.lang.SecurityException;
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 @IntRange(from=0) public int getAdditionalOutputDeviceDelay(@NonNull android.media.AudioDeviceInfo);
+ method @IntRange(from=0) public long getAdditionalOutputDeviceDelay(@NonNull android.media.AudioDeviceInfo);
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 @NonNull @RequiresPermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING) public java.util.List<android.media.AudioDeviceAttributes> getDevicesForAttributes(@NonNull android.media.AudioAttributes);
- method @IntRange(from=0) public int getMaxAdditionalOutputDeviceDelay(@NonNull android.media.AudioDeviceInfo);
+ method @IntRange(from=0) public long getMaxAdditionalOutputDeviceDelay(@NonNull android.media.AudioDeviceInfo);
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 @Nullable @RequiresPermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING) public android.media.AudioDeviceAttributes getPreferredDeviceForStrategy(@NonNull android.media.audiopolicy.AudioProductStrategy);
@@ -4197,7 +4197,7 @@ package android.media {
method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public int requestAudioFocus(android.media.AudioManager.OnAudioFocusChangeListener, @NonNull android.media.AudioAttributes, int, int) throws java.lang.IllegalArgumentException;
method @Deprecated @RequiresPermission(anyOf={android.Manifest.permission.MODIFY_PHONE_STATE, android.Manifest.permission.MODIFY_AUDIO_ROUTING}) public int requestAudioFocus(android.media.AudioManager.OnAudioFocusChangeListener, @NonNull android.media.AudioAttributes, int, int, android.media.audiopolicy.AudioPolicy) throws java.lang.IllegalArgumentException;
method @RequiresPermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING) public int requestAudioFocus(@NonNull android.media.AudioFocusRequest, @Nullable android.media.audiopolicy.AudioPolicy);
- method @RequiresPermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING) public boolean setAdditionalOutputDeviceDelay(@NonNull android.media.AudioDeviceInfo, @IntRange(from=0) int);
+ method @RequiresPermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING) public boolean setAdditionalOutputDeviceDelay(@NonNull android.media.AudioDeviceInfo, @IntRange(from=0) long);
method public void setAudioServerStateCallback(@NonNull java.util.concurrent.Executor, @NonNull android.media.AudioManager.AudioServerStateCallback);
method @RequiresPermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING) public void setFocusRequestResult(@NonNull android.media.AudioFocusInfo, int, @NonNull android.media.audiopolicy.AudioPolicy);
method @RequiresPermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING) public boolean setPreferredDeviceForStrategy(@NonNull android.media.audiopolicy.AudioProductStrategy, @NonNull android.media.AudioDeviceAttributes);
@@ -4272,17 +4272,11 @@ package android.media {
}
public static class AudioTrack.TunerConfiguration {
+ ctor @RequiresPermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING) public AudioTrack.TunerConfiguration(@IntRange(from=1) int, @IntRange(from=1) int);
method @IntRange(from=1) @RequiresPermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING) public int getContentId();
method @IntRange(from=1) @RequiresPermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING) public int getSyncId();
}
- public static class AudioTrack.TunerConfiguration.Builder {
- ctor public AudioTrack.TunerConfiguration.Builder();
- method @NonNull @RequiresPermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING) public android.media.AudioTrack.TunerConfiguration build();
- method @NonNull @RequiresPermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING) public android.media.AudioTrack.TunerConfiguration.Builder setContentId(@IntRange(from=1) int);
- method @NonNull @RequiresPermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING) public android.media.AudioTrack.TunerConfiguration.Builder setSyncId(@IntRange(from=1) int);
- }
-
public class HwAudioSource {
method public boolean isPlaying();
method public void start();
@@ -6210,14 +6204,14 @@ package android.net {
method public void onRemoveKeepalivePacketFilter(int);
method public void onSaveAcceptUnvalidated(boolean);
method public void onSignalStrengthThresholdsUpdated(@NonNull int[]);
- method public void onStartSocketKeepalive(int, int, @NonNull android.net.KeepalivePacketData);
+ method public void onStartSocketKeepalive(int, @IntRange(from=10, to=3600) int, @NonNull android.net.KeepalivePacketData);
method public void onStopSocketKeepalive(int);
- method public void onValidationStatus(int, @Nullable String);
+ method public void onValidationStatus(int, @Nullable android.net.Uri);
method @NonNull public android.net.Network register();
- method public void sendLinkProperties(@NonNull android.net.LinkProperties);
- method public void sendNetworkCapabilities(@NonNull android.net.NetworkCapabilities);
- method public void sendNetworkScore(int);
- method public void sendSocketKeepaliveEvent(int, int);
+ method public final void sendLinkProperties(@NonNull android.net.LinkProperties);
+ method public final void sendNetworkCapabilities(@NonNull android.net.NetworkCapabilities);
+ method public final void sendNetworkScore(@IntRange(from=0, to=99) int);
+ method public final void sendSocketKeepaliveEvent(int, int);
method public void setConnected();
method public void unregister();
field public static final int VALIDATION_STATUS_NOT_VALID = 2; // 0x2
@@ -6235,7 +6229,7 @@ package android.net {
field @NonNull public static final android.os.Parcelable.Creator<android.net.NetworkAgentConfig> CREATOR;
}
- public static class NetworkAgentConfig.Builder {
+ public static final class NetworkAgentConfig.Builder {
ctor public NetworkAgentConfig.Builder();
method @NonNull public android.net.NetworkAgentConfig build();
method @NonNull public android.net.NetworkAgentConfig.Builder setExplicitlySelected(boolean);
@@ -6303,7 +6297,6 @@ package android.net {
public class NetworkRequest implements android.os.Parcelable {
method @Nullable public String getRequestorPackageName();
method public int getRequestorUid();
- method public boolean satisfiedBy(@Nullable android.net.NetworkCapabilities);
}
public static class NetworkRequest.Builder {
diff --git a/core/java/android/content/pm/DataLoaderParams.java b/core/java/android/content/pm/DataLoaderParams.java
index 99c0907f1844..a791026d44cd 100644
--- a/core/java/android/content/pm/DataLoaderParams.java
+++ b/core/java/android/content/pm/DataLoaderParams.java
@@ -17,12 +17,8 @@
package android.content.pm;
import android.annotation.NonNull;
-import android.annotation.Nullable;
import android.annotation.SystemApi;
import android.content.ComponentName;
-import android.os.ParcelFileDescriptor;
-
-import java.util.Map;
/**
* This class represents the parameters used to configure a Data Loader.
@@ -44,7 +40,7 @@ public class DataLoaderParams {
*/
public static final @NonNull DataLoaderParams forStreaming(@NonNull ComponentName componentName,
@NonNull String arguments) {
- return new DataLoaderParams(DataLoaderType.STREAMING, componentName, arguments, null);
+ return new DataLoaderParams(DataLoaderType.STREAMING, componentName, arguments);
}
/**
@@ -55,29 +51,17 @@ public class DataLoaderParams {
*/
public static final @NonNull DataLoaderParams forIncremental(
@NonNull ComponentName componentName, @NonNull String arguments) {
- return new DataLoaderParams(DataLoaderType.INCREMENTAL, componentName, arguments, null);
+ return new DataLoaderParams(DataLoaderType.INCREMENTAL, componentName, arguments);
}
/** @hide */
public DataLoaderParams(@NonNull @DataLoaderType int type, @NonNull ComponentName componentName,
- @NonNull String arguments, @Nullable Map<String, ParcelFileDescriptor> namedFds) {
+ @NonNull String arguments) {
DataLoaderParamsParcel data = new DataLoaderParamsParcel();
data.type = type;
data.packageName = componentName.getPackageName();
data.className = componentName.getClassName();
data.arguments = arguments;
- if (namedFds == null || namedFds.isEmpty()) {
- data.dynamicArgs = new NamedParcelFileDescriptor[0];
- } else {
- data.dynamicArgs = new NamedParcelFileDescriptor[namedFds.size()];
- int i = 0;
- for (Map.Entry<String, ParcelFileDescriptor> namedFd : namedFds.entrySet()) {
- data.dynamicArgs[i] = new NamedParcelFileDescriptor();
- data.dynamicArgs[i].name = namedFd.getKey();
- data.dynamicArgs[i].fd = namedFd.getValue();
- i += 1;
- }
- }
mData = data;
}
diff --git a/core/java/android/content/pm/DataLoaderParamsParcel.aidl b/core/java/android/content/pm/DataLoaderParamsParcel.aidl
index e05843b4d4e9..d40012fd5718 100644
--- a/core/java/android/content/pm/DataLoaderParamsParcel.aidl
+++ b/core/java/android/content/pm/DataLoaderParamsParcel.aidl
@@ -17,7 +17,6 @@
package android.content.pm;
import android.content.pm.DataLoaderType;
-import android.content.pm.NamedParcelFileDescriptor;
/**
* Class for holding data loader configuration parameters.
@@ -28,5 +27,4 @@ parcelable DataLoaderParamsParcel {
@utf8InCpp String packageName;
@utf8InCpp String className;
@utf8InCpp String arguments;
- NamedParcelFileDescriptor[] dynamicArgs;
}
diff --git a/core/java/android/content/pm/NamedParcelFileDescriptor.aidl b/core/java/android/content/pm/NamedParcelFileDescriptor.aidl
deleted file mode 100644
index 68dd5f54654b..000000000000
--- a/core/java/android/content/pm/NamedParcelFileDescriptor.aidl
+++ /dev/null
@@ -1,28 +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.content.pm;
-
-import android.os.ParcelFileDescriptor;
-
-/**
- * A named ParcelFileDescriptor.
- * @hide
- */
-parcelable NamedParcelFileDescriptor {
- @utf8InCpp String name;
- ParcelFileDescriptor fd;
-}
diff --git a/core/java/android/net/ConnectivityManager.java b/core/java/android/net/ConnectivityManager.java
index 2a323e5ec97d..7332ede0b997 100644
--- a/core/java/android/net/ConnectivityManager.java
+++ b/core/java/android/net/ConnectivityManager.java
@@ -705,6 +705,36 @@ public class ConnectivityManager {
@Deprecated
public static final int TYPE_TEST = 18; // TODO: Remove this once NetworkTypes are unused.
+ /**
+ * @deprecated Use {@link NetworkCapabilities} instead.
+ * @hide
+ */
+ @Deprecated
+ @Retention(RetentionPolicy.SOURCE)
+ @IntDef(prefix = { "TYPE_" }, value = {
+ TYPE_NONE,
+ TYPE_MOBILE,
+ TYPE_WIFI,
+ TYPE_MOBILE_MMS,
+ TYPE_MOBILE_SUPL,
+ TYPE_MOBILE_DUN,
+ TYPE_MOBILE_HIPRI,
+ TYPE_WIMAX,
+ TYPE_BLUETOOTH,
+ TYPE_DUMMY,
+ TYPE_ETHERNET,
+ TYPE_MOBILE_FOTA,
+ TYPE_MOBILE_IMS,
+ TYPE_MOBILE_CBS,
+ TYPE_WIFI_P2P,
+ TYPE_MOBILE_IA,
+ TYPE_MOBILE_EMERGENCY,
+ TYPE_PROXY,
+ TYPE_VPN,
+ TYPE_TEST
+ })
+ public @interface LegacyNetworkType {}
+
// Deprecated constants for return values of startUsingNetworkFeature. They used to live
// in com.android.internal.telephony.PhoneConstants until they were made inaccessible.
private static final int DEPRECATED_PHONE_CONSTANT_APN_ALREADY_ACTIVE = 0;
diff --git a/core/java/android/net/NetworkAgent.java b/core/java/android/net/NetworkAgent.java
index 5c754a1b9733..8119df921745 100644
--- a/core/java/android/net/NetworkAgent.java
+++ b/core/java/android/net/NetworkAgent.java
@@ -16,6 +16,8 @@
package android.net;
+import android.annotation.IntDef;
+import android.annotation.IntRange;
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.annotation.SystemApi;
@@ -32,18 +34,52 @@ import android.util.Log;
import com.android.internal.util.AsyncChannel;
import com.android.internal.util.Protocol;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
import java.util.ArrayList;
import java.util.Objects;
import java.util.concurrent.atomic.AtomicBoolean;
/**
- * A Utility class for handling for communicating between bearer-specific
+ * A utility class for handling for communicating between bearer-specific
* code and ConnectivityService.
*
+ * An agent manages the life cycle of a network. A network starts its
+ * life cycle when {@link register} is called on NetworkAgent. The network
+ * is then connecting. When full L3 connectivity has been established,
+ * the agent shoud call {@link setConnected} to inform the system that
+ * this network is ready to use. When the network disconnects its life
+ * ends and the agent should call {@link unregister}, at which point the
+ * system will clean up and free resources.
+ * Any reconnection becomes a new logical network, so after a network
+ * is disconnected the agent cannot be used any more. Network providers
+ * should create a new NetworkAgent instance to handle new connections.
+ *
* A bearer may have more than one NetworkAgent if it can simultaneously
* support separate networks (IMS / Internet / MMS Apns on cellular, or
* perhaps connections with different SSID or P2P for Wi-Fi).
*
+ * This class supports methods to start and stop sending keepalive packets.
+ * Keepalive packets are typically sent at periodic intervals over a network
+ * with NAT when there is no other traffic to avoid the network forcefully
+ * closing the connection. NetworkAgents that manage technologies that
+ * have hardware support for keepalive should implement the related
+ * methods to save battery life. NetworkAgent that cannot get support
+ * without waking up the CPU should not, as this would be prohibitive in
+ * terms of battery - these agents should simply not override the related
+ * methods, which results in the implementation returning
+ * {@link SocketKeepalive.ERROR_UNSUPPORTED} as appropriate.
+ *
+ * Keepalive packets need to be sent at relatively frequent intervals
+ * (a few seconds to a few minutes). As the contents of keepalive packets
+ * depend on the current network status, hardware needs to be configured
+ * to send them and has a limited amount of memory to do so. The HAL
+ * formalizes this as slots that an implementation can configure to send
+ * the correct packets. Devices typically have a small number of slots
+ * per radio technology, and the specific number of slots for each
+ * technology is specified in configuration files.
+ * {@see SocketKeepalive} for details.
+ *
* @hide
*/
@SystemApi
@@ -65,7 +101,7 @@ public abstract class NetworkAgent {
private final String LOG_TAG;
private static final boolean DBG = true;
private static final boolean VDBG = false;
- private final ArrayList<Message>mPreConnectedQueue = new ArrayList<Message>();
+ private final ArrayList<Message> mPreConnectedQueue = new ArrayList<Message>();
private volatile long mLastBwRefreshTime = 0;
private static final long BW_REFRESH_MIN_WIN_MS = 500;
private boolean mBandwidthUpdateScheduled = false;
@@ -74,6 +110,8 @@ public abstract class NetworkAgent {
// into the internal API of ConnectivityService.
@NonNull
private NetworkInfo mNetworkInfo;
+ @NonNull
+ private final Object mRegisterLock = new Object();
/**
* The ID of the {@link NetworkProvider} that created this object, or
@@ -158,6 +196,14 @@ public abstract class NetworkAgent {
*/
public static final int VALIDATION_STATUS_NOT_VALID = 2;
+ /** @hide */
+ @Retention(RetentionPolicy.SOURCE)
+ @IntDef(prefix = { "VALIDATION_STATUS_" }, value = {
+ VALIDATION_STATUS_VALID,
+ VALIDATION_STATUS_NOT_VALID
+ })
+ public @interface ValidationStatus {}
+
// TODO: remove.
/** @hide */
public static final int VALID_NETWORK = 1;
@@ -202,7 +248,7 @@ public abstract class NetworkAgent {
* Sent by ConnectivityService to the NetworkAgent to request that the specified packet be sent
* periodically on the given interval.
*
- * arg1 = the slot number of the keepalive to start
+ * arg1 = the hardware slot number of the keepalive to start
* arg2 = interval in seconds
* obj = KeepalivePacketData object describing the data to be sent
*
@@ -214,7 +260,7 @@ public abstract class NetworkAgent {
/**
* Requests that the specified keepalive packet be stopped.
*
- * arg1 = slot number of the keepalive to stop.
+ * arg1 = hardware slot number of the keepalive to stop.
*
* Also used internally by ConnectivityService / KeepaliveTracker, with different semantics.
* @hide
@@ -229,7 +275,7 @@ public abstract class NetworkAgent {
* This is also sent by KeepaliveTracker to the app's {@link SocketKeepalive},
* so that the app's {@link SocketKeepalive.Callback} methods can be called.
*
- * arg1 = slot number of the keepalive
+ * arg1 = hardware slot number of the keepalive
* arg2 = error code
* @hide
*/
@@ -259,7 +305,7 @@ public abstract class NetworkAgent {
* remote site will send ACK packets in response to the keepalive packets, the firmware also
* needs to be configured to properly filter the ACKs to prevent the system from waking up.
* This does not happen with UDP, so this message is TCP-specific.
- * arg1 = slot number of the keepalive to filter for.
+ * arg1 = hardware slot number of the keepalive to filter for.
* obj = the keepalive packet to send repeatedly.
* @hide
*/
@@ -268,7 +314,7 @@ public abstract class NetworkAgent {
/**
* Sent by the KeepaliveTracker to NetworkAgent to remove a packet filter. See
* {@link #CMD_ADD_KEEPALIVE_PACKET_FILTER}.
- * arg1 = slot number of the keepalive packet filter to remove.
+ * arg1 = hardware slot number of the keepalive packet filter to remove.
* @hide
*/
public static final int CMD_REMOVE_KEEPALIVE_PACKET_FILTER = BASE + 17;
@@ -441,7 +487,15 @@ public abstract class NetworkAgent {
+ (msg.arg1 == VALID_NETWORK ? "VALID, " : "INVALID, ")
+ redirectUrl);
}
- onValidationStatus(msg.arg1 /* status */, redirectUrl);
+ Uri uri = null;
+ try {
+ if (null != redirectUrl) {
+ uri = Uri.parse(redirectUrl);
+ }
+ } catch (Exception e) {
+ Log.wtf(LOG_TAG, "Surprising URI : " + redirectUrl, e);
+ }
+ onValidationStatus(msg.arg1 /* status */, uri);
break;
}
case CMD_SAVE_ACCEPT_UNVALIDATED: {
@@ -489,19 +543,29 @@ public abstract class NetworkAgent {
/**
* Register this network agent with ConnectivityService.
+ *
+ * This method can only be called once per network agent.
+ *
* @return the Network associated with this network agent (which can also be obtained later
* by calling getNetwork() on this agent).
+ * @throws IllegalStateException thrown by the system server if this network agent is
+ * already registered.
*/
@NonNull
public Network register() {
if (VDBG) log("Registering NetworkAgent");
final ConnectivityManager cm = (ConnectivityManager) mInitialConfiguration.context
.getSystemService(Context.CONNECTIVITY_SERVICE);
- mNetwork = cm.registerNetworkAgent(new Messenger(mHandler),
- new NetworkInfo(mInitialConfiguration.info),
- mInitialConfiguration.properties, mInitialConfiguration.capabilities,
- mInitialConfiguration.score, mInitialConfiguration.config, providerId);
- mInitialConfiguration = null; // All this memory can now be GC'd
+ synchronized (mRegisterLock) {
+ if (mNetwork != null) {
+ throw new IllegalStateException("Agent already registered");
+ }
+ mNetwork = cm.registerNetworkAgent(new Messenger(mHandler),
+ new NetworkInfo(mInitialConfiguration.info),
+ mInitialConfiguration.properties, mInitialConfiguration.capabilities,
+ mInitialConfiguration.score, mInitialConfiguration.config, providerId);
+ mInitialConfiguration = null; // All this memory can now be GC'd
+ }
return mNetwork;
}
@@ -544,13 +608,14 @@ public abstract class NetworkAgent {
* Must be called by the agent when the network's {@link LinkProperties} change.
* @param linkProperties the new LinkProperties.
*/
- public void sendLinkProperties(@NonNull LinkProperties linkProperties) {
+ public final void sendLinkProperties(@NonNull LinkProperties linkProperties) {
Objects.requireNonNull(linkProperties);
queueOrSendMessage(EVENT_NETWORK_PROPERTIES_CHANGED, new LinkProperties(linkProperties));
}
/**
* Inform ConnectivityService that this agent has now connected.
+ * Call {@link #unregister} to disconnect.
*/
public void setConnected() {
if (mIsLegacy) {
@@ -569,8 +634,7 @@ public abstract class NetworkAgent {
*/
public void unregister() {
if (mIsLegacy) {
- throw new UnsupportedOperationException(
- "Legacy agents can't call unregister.");
+ throw new UnsupportedOperationException("Legacy agents can't call unregister.");
}
mNetworkInfo.setDetailedState(NetworkInfo.DetailedState.DISCONNECTED, null, null);
queueOrSendMessage(EVENT_NETWORK_INFO_CHANGED, mNetworkInfo);
@@ -626,7 +690,7 @@ public abstract class NetworkAgent {
* @hide TODO: expose something better.
*/
@UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023)
- public void sendNetworkInfo(NetworkInfo networkInfo) {
+ public final void sendNetworkInfo(NetworkInfo networkInfo) {
if (!mIsLegacy) {
throw new UnsupportedOperationException("Only legacy agents can call sendNetworkInfo.");
}
@@ -637,7 +701,7 @@ public abstract class NetworkAgent {
* Must be called by the agent when the network's {@link NetworkCapabilities} change.
* @param networkCapabilities the new NetworkCapabilities.
*/
- public void sendNetworkCapabilities(@NonNull NetworkCapabilities networkCapabilities) {
+ public final void sendNetworkCapabilities(@NonNull NetworkCapabilities networkCapabilities) {
Objects.requireNonNull(networkCapabilities);
mBandwidthUpdatePending.set(false);
mLastBwRefreshTime = System.currentTimeMillis();
@@ -647,9 +711,10 @@ public abstract class NetworkAgent {
/**
* Must be called by the agent to update the score of this network.
- * @param score the new score.
+ *
+ * @param score the new score, between 0 and 99.
*/
- public void sendNetworkScore(int score) {
+ public final void sendNetworkScore(@IntRange(from = 0, to = 99) int score) {
if (score < 0) {
throw new IllegalArgumentException("Score must be >= 0");
}
@@ -737,11 +802,11 @@ public abstract class NetworkAgent {
* subsequent attempts to validate connectivity that fail.
*
* @param status one of {@code VALIDATION_STATUS_VALID} or {@code VALIDATION_STATUS_NOT_VALID}.
- * @param redirectUrl If Internet connectivity is being redirected (e.g., on a captive portal),
+ * @param redirectUri If Internet connectivity is being redirected (e.g., on a captive portal),
* this is the destination the probes are being redirected to, otherwise {@code null}.
*/
- public void onValidationStatus(int status, @Nullable String redirectUrl) {
- networkStatus(status, redirectUrl);
+ public void onValidationStatus(@ValidationStatus int status, @Nullable Uri redirectUri) {
+ networkStatus(status, redirectUri.toString());
}
/** @hide TODO delete once subclasses have moved to onValidationStatus */
protected void networkStatus(int status, String redirectUrl) {
@@ -770,7 +835,12 @@ public abstract class NetworkAgent {
* @param intervalSeconds the interval between packets
* @param packet the packet to send.
*/
- public void onStartSocketKeepalive(int slot, int intervalSeconds,
+ // seconds is from SocketKeepalive.MIN_INTERVAL_SEC to MAX_INTERVAL_SEC, but these should
+ // not be exposed as constants because they may change in the future (API guideline 4.8)
+ // and should have getters if exposed at all. Getters can't be used in the annotation,
+ // so the values unfortunately need to be copied.
+ public void onStartSocketKeepalive(int slot,
+ @IntRange(from = 10, to = 3600) int intervalSeconds,
@NonNull KeepalivePacketData packet) {
Message msg = mHandler.obtainMessage(CMD_START_SOCKET_KEEPALIVE, slot, intervalSeconds,
packet);
@@ -801,9 +871,11 @@ public abstract class NetworkAgent {
* Must be called by the agent when a socket keepalive event occurs.
*
* @param slot the hardware slot on which the event occurred.
- * @param event the event that occurred.
+ * @param event the event that occurred, as one of the SocketKeepalive.ERROR_*
+ * or SocketKeepalive.SUCCESS constants.
*/
- public void sendSocketKeepaliveEvent(int slot, int event) {
+ public final void sendSocketKeepaliveEvent(int slot,
+ @SocketKeepalive.KeepaliveEvent int event) {
queueOrSendMessage(EVENT_SOCKET_KEEPALIVE, slot, event);
}
/** @hide TODO delete once callers have moved to sendSocketKeepaliveEvent */
@@ -845,9 +917,18 @@ public abstract class NetworkAgent {
}
/**
- * Called by ConnectivityService to inform this network transport of signal strength thresholds
+ * Called by ConnectivityService to inform this network agent of signal strength thresholds
* that when crossed should trigger a system wakeup and a NetworkCapabilities update.
*
+ * When the system updates the list of thresholds that should wake up the CPU for a
+ * given agent it will call this method on the agent. The agent that implement this
+ * should implement it in hardware so as to ensure the CPU will be woken up on breach.
+ * Agents are expected to react to a breach by sending an updated NetworkCapabilities
+ * object with the appropriate signal strength to sendNetworkCapabilities.
+ *
+ * The specific units are bearer-dependent. See details on the units and requests in
+ * {@link NetworkCapabilities.Builder#setSignalStrength}.
+ *
* @param thresholds the array of thresholds that should trigger wakeups.
*/
public void onSignalStrengthThresholdsUpdated(@NonNull int[] thresholds) {
diff --git a/core/java/android/net/NetworkAgentConfig.java b/core/java/android/net/NetworkAgentConfig.java
index ca9328a713f0..fee868a93be4 100644
--- a/core/java/android/net/NetworkAgentConfig.java
+++ b/core/java/android/net/NetworkAgentConfig.java
@@ -155,6 +155,7 @@ public final class NetworkAgentConfig implements Parcelable {
/**
* @return the legacy type
*/
+ @ConnectivityManager.LegacyNetworkType
public int getLegacyType() {
return legacyType;
}
@@ -206,7 +207,7 @@ public final class NetworkAgentConfig implements Parcelable {
/**
* Builder class to facilitate constructing {@link NetworkAgentConfig} objects.
*/
- public static class Builder {
+ public static final class Builder {
private final NetworkAgentConfig mConfig = new NetworkAgentConfig();
/**
diff --git a/core/java/android/net/NetworkRequest.java b/core/java/android/net/NetworkRequest.java
index 964f13f39ec6..798856d13b1d 100644
--- a/core/java/android/net/NetworkRequest.java
+++ b/core/java/android/net/NetworkRequest.java
@@ -473,9 +473,7 @@ public class NetworkRequest implements Parcelable {
*
* @param nc Capabilities that should satisfy this NetworkRequest. null capabilities do not
* satisfy any request.
- * @hide
*/
- @SystemApi
public boolean satisfiedBy(@Nullable NetworkCapabilities nc) {
return networkCapabilities.satisfiedByNetworkCapabilities(nc);
}
diff --git a/core/java/android/net/SocketKeepalive.java b/core/java/android/net/SocketKeepalive.java
index fc9a8f63c131..8ff8f4c48c32 100644
--- a/core/java/android/net/SocketKeepalive.java
+++ b/core/java/android/net/SocketKeepalive.java
@@ -109,6 +109,16 @@ public abstract class SocketKeepalive implements AutoCloseable {
})
public @interface ErrorCode {}
+ /** @hide */
+ @Retention(RetentionPolicy.SOURCE)
+ @IntDef(value = {
+ SUCCESS,
+ ERROR_INVALID_LENGTH,
+ ERROR_UNSUPPORTED,
+ ERROR_INSUFFICIENT_RESOURCES
+ })
+ public @interface KeepaliveEvent {}
+
/**
* The minimum interval in seconds between keepalive packet transmissions.
*
diff --git a/core/java/android/os/IVibratorService.aidl b/core/java/android/os/IVibratorService.aidl
index 84013e7ebc88..615ae6593330 100644
--- a/core/java/android/os/IVibratorService.aidl
+++ b/core/java/android/os/IVibratorService.aidl
@@ -28,7 +28,7 @@ interface IVibratorService
boolean registerVibratorStateListener(in IVibratorStateListener listener);
boolean unregisterVibratorStateListener(in IVibratorStateListener listener);
boolean hasAmplitudeControl();
- boolean[] areEffectsSupported(in int[] effectIds);
+ int[] areEffectsSupported(in int[] effectIds);
boolean[] arePrimitivesSupported(in int[] primitiveIds);
boolean setAlwaysOnEffect(int uid, String opPkg, int alwaysOnId, in VibrationEffect effect,
in VibrationAttributes attributes);
diff --git a/core/java/android/os/SystemVibrator.java b/core/java/android/os/SystemVibrator.java
index da20c7f2ae70..2dba8dce62da 100644
--- a/core/java/android/os/SystemVibrator.java
+++ b/core/java/android/os/SystemVibrator.java
@@ -21,12 +21,13 @@ import android.annotation.NonNull;
import android.compat.annotation.UnsupportedAppUsage;
import android.content.Context;
import android.media.AudioAttributes;
-import android.os.IVibratorStateListener;
import android.util.ArrayMap;
import android.util.Log;
+
import com.android.internal.annotations.GuardedBy;
-import java.util.concurrent.Executor;
+
import java.util.Objects;
+import java.util.concurrent.Executor;
/**
* Vibrator implementation that controls the main system vibrator.
@@ -238,13 +239,13 @@ public class SystemVibrator extends Vibrator {
}
@Override
- public boolean[] areEffectsSupported(@VibrationEffect.EffectType int... effectIds) {
+ public int[] areEffectsSupported(@VibrationEffect.EffectType int... effectIds) {
try {
return mService.areEffectsSupported(effectIds);
} catch (RemoteException e) {
Log.w(TAG, "Failed to query effect support");
+ throw e.rethrowAsRuntimeException();
}
- return new boolean[effectIds.length];
}
@Override
@@ -254,8 +255,8 @@ public class SystemVibrator extends Vibrator {
return mService.arePrimitivesSupported(primitiveIds);
} catch (RemoteException e) {
Log.w(TAG, "Failed to query effect support");
+ throw e.rethrowAsRuntimeException();
}
- return new boolean[primitiveIds.length];
}
diff --git a/core/java/android/os/VibrationEffect.java b/core/java/android/os/VibrationEffect.java
index aa89b515adc6..ca861577ab37 100644
--- a/core/java/android/os/VibrationEffect.java
+++ b/core/java/android/os/VibrationEffect.java
@@ -961,7 +961,7 @@ public abstract class VibrationEffect implements Parcelable {
*
* @see VibrationEffect#startComposition()
*/
- public static class Composition {
+ public static final class Composition {
/** @hide */
@IntDef(prefix = { "PRIMITIVE_" }, value = {
PRIMITIVE_CLICK,
@@ -1020,6 +1020,8 @@ public abstract class VibrationEffect implements Parcelable {
private ArrayList<PrimitiveEffect> mEffects = new ArrayList<>();
+ Composition() { }
+
/**
* Add a haptic primitive to the end of the current composition.
*
@@ -1030,7 +1032,7 @@ public abstract class VibrationEffect implements Parcelable {
*
* @return The {@link Composition} object to enable adding multiple primitives in one chain.
*/
- @Nullable
+ @NonNull
public Composition addPrimitive(@Primitive int primitiveId) {
addPrimitive(primitiveId, /*scale*/ 1.0f, /*delay*/ 0);
return this;
@@ -1046,7 +1048,7 @@ public abstract class VibrationEffect implements Parcelable {
*
* @return The {@link Composition} object to enable adding multiple primitives in one chain.
*/
- @Nullable
+ @NonNull
public Composition addPrimitive(@Primitive int primitiveId,
@FloatRange(from = 0f, to = 1f) float scale) {
addPrimitive(primitiveId, scale, /*delay*/ 0);
@@ -1058,11 +1060,11 @@ public abstract class VibrationEffect implements Parcelable {
*
* @param primitiveId The primitive to add
* @param scale The scale to apply to the intensity of the primitive.
- * @param delay The amount of time, in milliseconds, to wait before playing the prior
+ * @param delay The amount of time, in milliseconds, to wait between playing the prior
* primitive and this one
* @return The {@link Composition} object to enable adding multiple primitives in one chain.
*/
- @Nullable
+ @NonNull
public Composition addPrimitive(@Primitive int primitiveId,
@FloatRange(from = 0f, to = 1f) float scale, @IntRange(from = 0) int delay) {
mEffects.add(new PrimitiveEffect(checkPrimitive(primitiveId), scale, delay));
diff --git a/core/java/android/os/Vibrator.java b/core/java/android/os/Vibrator.java
index d4da7a84d2a1..86d009e8607e 100644
--- a/core/java/android/os/Vibrator.java
+++ b/core/java/android/os/Vibrator.java
@@ -32,6 +32,7 @@ import android.util.Log;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
+import java.util.Arrays;
import java.util.concurrent.Executor;
/**
@@ -72,6 +73,37 @@ public abstract class Vibrator {
*/
public static final int VIBRATION_INTENSITY_HIGH = 3;
+ /**
+ * Vibration effect support: unknown
+ *
+ * The hardware doesn't report it's supported effects, so we can't determine whether the
+ * effect is supported or not.
+ */
+ public static final int VIBRATION_EFFECT_SUPPORT_UNKNOWN = 0;
+
+ /**
+ * Vibration effect support: supported
+ *
+ * This effect is supported by the underlying hardware.
+ */
+ public static final int VIBRATION_EFFECT_SUPPORT_YES = 1;
+
+ /**
+ * Vibration effect support: unsupported
+ *
+ * This effect is <b>not</b> supported by the underlying hardware.
+ */
+ public static final int VIBRATION_EFFECT_SUPPORT_NO = 2;
+
+ /** @hide */
+ @Retention(RetentionPolicy.SOURCE)
+ @IntDef(prefix = {"VIBRATION_EFFECT_SUPPORT_"}, value = {
+ VIBRATION_EFFECT_SUPPORT_UNKNOWN,
+ VIBRATION_EFFECT_SUPPORT_YES,
+ VIBRATION_EFFECT_SUPPORT_NO,
+ })
+ public @interface VibrationEffectSupport {}
+
/** @hide */
@Retention(RetentionPolicy.SOURCE)
@IntDef(prefix = {"VIBRATION_INTENSITY_"}, value = {
@@ -318,47 +350,61 @@ public abstract class Vibrator {
/**
* Query whether the vibrator supports the given effects.
*
- * If the returned array is {@code null}, the hardware doesn't support querying its supported
- * effects. It may support any or all effects, but there's no way to programmatically know
- * whether a {@link #vibrate} call will be successful.
+ * Not all hardware reports its effect capabilities, so the system may not necessarily know
+ * whether an effect is supported or not.
*
- * If the returned array is non-null, then it will be the same length as the query array and
- * the value at a given index will contain whether the effect at that same index in the
- * querying array is supported or not.
+ * The returned array will be the same length as the query array and the value at a given index
+ * will contain {@link #VIBRATION_EFFECT_SUPPORT_YES} if the effect at that same index in the
+ * querying array is supported, {@link #VIBRATION_EFFECT_SUPPORT_NO} if it isn't supported, or
+ * {@link #VIBRATION_EFFECT_SUPPORT_UNKNOWN} if the system can't determine whether it's
+ * supported or not.
*
* @param effectIds Which effects to query for.
- * @return Whether the effects are supported. Null when the hardware doesn't tell us what it
- * supports.
+ * @return An array containing the systems current knowledge about whether the given effects
+ * are supported or not.
*/
- @Nullable
- public boolean[] areEffectsSupported(
+ @NonNull
+ @VibrationEffectSupport
+ public int[] areEffectsSupported(
@NonNull @VibrationEffect.EffectType int... effectIds) {
- return new boolean[effectIds.length];
+ final int[] support = new int[effectIds.length];
+ Arrays.fill(support, VIBRATION_EFFECT_SUPPORT_NO);
+ return support;
}
/**
* Query whether the vibrator supports all of the given effects.
*
- * If the result is {@code null}, the hardware doesn't support querying its supported
- * effects. It may support any or all effects, but there's no way to programmatically know
- * whether a {@link #vibrate} call will be successful.
+ * Not all hardware reports its effect capabilities, so the system may not necessarily know
+ * whether an effect is supported or not.
*
- * If the returned array is non-null, then it will return whether all of the effects are
+ * If the result is {@link #VIBRATION_EFFECT_SUPPORT_YES}, all effects in the query are
* supported by the hardware.
*
+ * If the result is {@link #VIBRATION_EFFECT_SUPPORT_NO}, at least one of the effects in the
+ * query is not supported.
+ *
+ * If the result is {@link #VIBRATION_EFFECT_SUPPORT_UNKNOWN}, the system doesn't know whether
+ * all of the effects are supported. It may support any or all of the queried effects,
+ * but there's no way to programmatically know whether a {@link #vibrate} call will successfully
+ * cause a vibration. It's guaranteed, however, that none of the queried effects are
+ * definitively unsupported by the hardware.
+ *
* @param effectIds Which effects to query for.
- * @return Whether the effects are supported. {@code null} when the hardware doesn't tell us
- * what it supports.
+ * @return Whether all of the effects are supported.
*/
- @Nullable
- public Boolean areAllEffectsSupported(
+ @VibrationEffectSupport
+ public final int areAllEffectsSupported(
@NonNull @VibrationEffect.EffectType int... effectIds) {
- for (boolean supported : areEffectsSupported(effectIds)) {
- if (!supported) {
- return false;
+ int support = VIBRATION_EFFECT_SUPPORT_YES;
+ for (int supported : areEffectsSupported(effectIds)) {
+ if (supported == VIBRATION_EFFECT_SUPPORT_NO) {
+ return VIBRATION_EFFECT_SUPPORT_NO;
+ } else if (supported == VIBRATION_EFFECT_SUPPORT_UNKNOWN) {
+ support = VIBRATION_EFFECT_SUPPORT_UNKNOWN;
}
}
- return true;
+ return support;
}
@@ -384,7 +430,7 @@ public abstract class Vibrator {
* @param primitiveIds Which primitives to query for.
* @return Whether primitives effects are supported.
*/
- public boolean areAllPrimitivesSupported(
+ public final boolean areAllPrimitivesSupported(
@NonNull @VibrationEffect.Composition.Primitive int... primitiveIds) {
for (boolean supported : arePrimitivesSupported(primitiveIds)) {
if (!supported) {
diff --git a/core/java/android/provider/Settings.java b/core/java/android/provider/Settings.java
index bbcb9d9249af..d2a03f0ff166 100644
--- a/core/java/android/provider/Settings.java
+++ b/core/java/android/provider/Settings.java
@@ -6589,11 +6589,9 @@ public final class Settings {
"accessibility_shortcut_target_service";
/**
- * Setting specifying the accessibility services, accessibility shortcut targets,
- * or features to be toggled via the accessibility button in the navigation bar.
- *
- * <p> This is a colon-separated string list which contains the flattened
- * {@link ComponentName} and the class name of a system class implementing a supported
+ * Setting specifying the accessibility service or feature to be toggled via the
+ * accessibility button in the navigation bar. This is either a flattened
+ * {@link ComponentName} or the class name of a system class implementing a supported
* accessibility feature.
* @hide
*/
@@ -6602,15 +6600,14 @@ public final class Settings {
/**
* Setting specifying the accessibility services, accessibility shortcut targets,
- * or features to be toggled via the long press accessibility button in the navigation bar.
+ * or features to be toggled via the accessibility button in the navigation bar.
*
* <p> This is a colon-separated string list which contains the flattened
* {@link ComponentName} and the class name of a system class implementing a supported
* accessibility feature.
* @hide
*/
- public static final String ACCESSIBILITY_BUTTON_LONG_PRESS_TARGETS =
- "accessibility_button_long_press_targets";
+ public static final String ACCESSIBILITY_BUTTON_TARGETS = "accessibility_button_targets";
/**
* The system class name of magnification controller which is a target to be toggled via
@@ -6775,8 +6772,8 @@ public final class Settings {
* zoom in the display content and is targeted to low vision users. The current
* magnification scale is controlled by {@link #ACCESSIBILITY_DISPLAY_MAGNIFICATION_SCALE}.
*
- * @deprecated Use {@link #ACCESSIBILITY_BUTTON_TARGET_COMPONENT} instead.
- * {@link #ACCESSIBILITY_BUTTON_TARGET_COMPONENT} holds the magnification system class name
+ * @deprecated Use {@link #ACCESSIBILITY_BUTTON_TARGETS} instead.
+ * {@link #ACCESSIBILITY_BUTTON_TARGETS} holds the magnification system class name
* when navigation bar magnification is enabled.
* @hide
*/
diff --git a/core/java/android/service/dataloader/DataLoaderService.java b/core/java/android/service/dataloader/DataLoaderService.java
index 0170726b31d6..c047dc0d07c7 100644
--- a/core/java/android/service/dataloader/DataLoaderService.java
+++ b/core/java/android/service/dataloader/DataLoaderService.java
@@ -29,7 +29,6 @@ import android.content.pm.IDataLoader;
import android.content.pm.IDataLoaderStatusListener;
import android.content.pm.InstallationFile;
import android.content.pm.InstallationFileParcel;
-import android.content.pm.NamedParcelFileDescriptor;
import android.os.IBinder;
import android.os.ParcelFileDescriptor;
import android.util.ExceptionUtils;
@@ -133,16 +132,6 @@ public abstract class DataLoaderService extends Service {
}
}
}
- if (params.dynamicArgs != null) {
- NamedParcelFileDescriptor[] fds = params.dynamicArgs;
- for (NamedParcelFileDescriptor nfd : fds) {
- try {
- nfd.fd.close();
- } catch (IOException e) {
- Slog.e(TAG, "Failed to close DynamicArgs parcel file descriptor " + e);
- }
- }
- }
}
}
diff --git a/core/proto/android/providers/settings/secure.proto b/core/proto/android/providers/settings/secure.proto
index a3313b21131d..d09273cdd369 100644
--- a/core/proto/android/providers/settings/secure.proto
+++ b/core/proto/android/providers/settings/secure.proto
@@ -77,7 +77,7 @@ message SecureSettingsProto {
optional SettingProto interactive_ui_timeout_ms = 33 [ (android.privacy).dest = DEST_AUTOMATIC ];
// Settings for magnification mode
optional SettingProto accessibility_magnification_mode = 34 [ (android.privacy).dest = DEST_AUTOMATIC ];
- optional SettingProto button_long_press_targets = 35 [ (android.privacy).dest = DEST_AUTOMATIC ];
+ optional SettingProto button_targets = 35 [ (android.privacy).dest = DEST_AUTOMATIC ];
}
optional Accessibility accessibility = 2;
diff --git a/core/res/res/values/config.xml b/core/res/res/values/config.xml
index e3a73377e365..28dcc2fdb573 100644
--- a/core/res/res/values/config.xml
+++ b/core/res/res/values/config.xml
@@ -4424,4 +4424,7 @@
<!-- Set to true to enable the user switcher on the keyguard. -->
<bool name="config_keyguardUserSwitcher">false</bool>
+ <!-- Set to true to make assistant show in front of the dream/screensaver. -->
+ <bool name="config_assistantOnTopOfDream">false</bool>
+
</resources>
diff --git a/core/res/res/values/symbols.xml b/core/res/res/values/symbols.xml
index 22caf4c2a37d..646ffabedb8d 100644
--- a/core/res/res/values/symbols.xml
+++ b/core/res/res/values/symbols.xml
@@ -3953,4 +3953,7 @@
<!-- Set to true to enable the user switcher on the keyguard. -->
<java-symbol type="bool" name="config_keyguardUserSwitcher" />
+
+ <!-- Set to true to make assistant show in front of the dream/screensaver. -->
+ <java-symbol type="bool" name="config_assistantOnTopOfDream"/>
</resources>
diff --git a/core/tests/coretests/src/android/widget/EditorCursorDragTest.java b/core/tests/coretests/src/android/widget/EditorCursorDragTest.java
index 9a93dbf67d33..4bfffd72d835 100644
--- a/core/tests/coretests/src/android/widget/EditorCursorDragTest.java
+++ b/core/tests/coretests/src/android/widget/EditorCursorDragTest.java
@@ -494,6 +494,7 @@ public class EditorCursorDragTest {
simulateDrag(tv, events, true);
}
+ @Suppress // b/152574363
@Test
public void testLineChangeSlop() throws Throwable {
TextView tv = mActivity.findViewById(R.id.textview);
diff --git a/media/java/android/media/AudioDeviceInfo.java b/media/java/android/media/AudioDeviceInfo.java
index 9950f05560d7..db2a1e8b6e7c 100644
--- a/media/java/android/media/AudioDeviceInfo.java
+++ b/media/java/android/media/AudioDeviceInfo.java
@@ -432,7 +432,7 @@ public final class AudioDeviceInfo {
* @return An array of supported encapsulation modes for the device. This
* may be an empty array if no encapsulation modes are supported.
*/
- public @NonNull int[] getEncapsulationModes() {
+ public @NonNull @AudioTrack.EncapsulationMode int[] getEncapsulationModes() {
// Implement a getter in r-dev or r-tv-dev as needed.
return new int[0]; // be careful of returning a copy of any internal data.
}
@@ -451,7 +451,7 @@ public final class AudioDeviceInfo {
* @return An array of supported encapsulation metadata types for the device. This
* may be an empty array if no metadata types are supported.
*/
- public @NonNull int[] getEncapsulationMetadataTypes() {
+ public @NonNull @AudioTrack.EncapsulationMetadataType int[] getEncapsulationMetadataTypes() {
// Implement a getter in r-dev or r-tv-dev as needed.
return new int[0]; // be careful of returning a copy of any internal data.
}
diff --git a/media/java/android/media/AudioManager.java b/media/java/android/media/AudioManager.java
index fffdd683f22c..ba8f7e60e268 100644
--- a/media/java/android/media/AudioManager.java
+++ b/media/java/android/media/AudioManager.java
@@ -4769,7 +4769,7 @@ public class AudioManager {
* opened on that device.
*
* @param device an instance of {@link AudioDeviceInfo} returned from {@link getDevices()}.
- * @param delayMs delay in milliseconds desired. This should be in range of {@code 0}
+ * @param delayMillis delay in milliseconds desired. This should be in range of {@code 0}
* to the value returned by {@link #getMaxAdditionalOutputDeviceDelay()}.
* @return true if successful, false if the device does not support output device delay
* or the delay is not in range of {@link #getMaxAdditionalOutputDeviceDelay()}.
@@ -4777,7 +4777,7 @@ public class AudioManager {
@SystemApi
@RequiresPermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING)
public boolean setAdditionalOutputDeviceDelay(
- @NonNull AudioDeviceInfo device, @IntRange(from = 0) int delayMs) {
+ @NonNull AudioDeviceInfo device, @IntRange(from = 0) long delayMillis) {
Objects.requireNonNull(device);
// Implement the setter in r-dev or r-tv-dev as needed.
return false;
@@ -4793,7 +4793,7 @@ public class AudioManager {
*/
@SystemApi
@IntRange(from = 0)
- public int getAdditionalOutputDeviceDelay(@NonNull AudioDeviceInfo device) {
+ public long getAdditionalOutputDeviceDelay(@NonNull AudioDeviceInfo device) {
Objects.requireNonNull(device);
// Implement the getter in r-dev or r-tv-dev as needed.
return 0;
@@ -4811,7 +4811,7 @@ public class AudioManager {
*/
@SystemApi
@IntRange(from = 0)
- public int getMaxAdditionalOutputDeviceDelay(@NonNull AudioDeviceInfo device) {
+ public long getMaxAdditionalOutputDeviceDelay(@NonNull AudioDeviceInfo device) {
Objects.requireNonNull(device);
// Implement the getter in r-dev or r-tv-dev as needed.
return 0;
diff --git a/media/java/android/media/AudioMetadata.java b/media/java/android/media/AudioMetadata.java
index 1a9517cafdde..c91ff0d099cf 100644
--- a/media/java/android/media/AudioMetadata.java
+++ b/media/java/android/media/AudioMetadata.java
@@ -79,96 +79,11 @@ public final class AudioMetadata {
}
/**
- * A read only {@code Map} interface of {@link Key} value pairs.
- *
- * <p>Using a {@link Key} interface, the map looks up the corresponding value.</p>
- */
- public interface ReadMap {
- /**
- * Returns true if the key exists in the map.
- *
- * @param key interface for requesting the value.
- * @param <T> type of value.
- * @return true if key exists in the Map.
- */
- <T> boolean containsKey(@NonNull Key<T> key);
-
- /**
- * Returns a copy of the map.
- *
- * This is intended for safe conversion between a {@link ReadMap}
- * interface and a {@link Map} interface.
- * Currently only simple objects are used for key values which
- * means a shallow copy is sufficient.
- *
- * @return a Map copied from the existing map.
- */
- @NonNull
- Map dup(); // lint checker doesn't like clone().
-
- /**
- * Returns the value associated with the key.
- *
- * @param key interface for requesting the value.
- * @param <T> type of value.
- * @return returns the value of associated with key or null if it doesn't exist.
- */
- @Nullable
- <T> T get(@NonNull Key<T> key);
-
- /**
- * Returns a {@code Set} of keys associated with the map.
- * @hide
- */
- @NonNull
- Set<Key<?>> keySet();
-
- /**
- * Returns the number of elements in the map.
- */
- int size();
- }
-
- /**
- * A writeable {@link Map} interface of {@link Key} value pairs.
- * This interface is not guaranteed to be thread-safe
- * unless the supplier for the {@code Map} states it as thread safe.
- */
- // TODO: Create a wrapper like java.util.Collections.synchronizedMap?
- public interface Map extends ReadMap {
- /**
- * Removes the value associated with the key.
- * @param key interface for storing the value.
- * @param <T> type of value.
- * @return the value of the key, null if it doesn't exist.
- */
- @Nullable
- <T> T remove(@NonNull Key<T> key);
-
- /**
- * Sets a value for the key.
- *
- * @param key interface for storing the value.
- * @param <T> type of value.
- * @param value a non-null value of type T.
- * @return the previous value associated with key or null if it doesn't exist.
- */
- // See automatic Kotlin overloading for Java interoperability.
- // https://kotlinlang.org/docs/reference/java-interop.html#operators
- // See also Kotlin set for overloaded operator indexing.
- // https://kotlinlang.org/docs/reference/operator-overloading.html#indexed
- // Also the Kotlin mutable-list set.
- // https://kotlinlang.org/api/latest/jvm/stdlib/kotlin.collections/-mutable-list/set.html
- @Nullable
- <T> T set(@NonNull Key<T> key, @NonNull T value);
- }
-
- /**
- * Creates a {@link Map} suitable for adding keys.
- * @return an empty {@link Map} instance.
+ * Creates a {@link AudioMetadataMap} suitable for adding keys.
+ * @return an empty {@link AudioMetadataMap} instance.
*/
@NonNull
- public static Map createMap() {
+ public static AudioMetadataMap createMap() {
return new BaseMap();
}
@@ -339,7 +254,7 @@ public final class AudioMetadata {
* It is possible to require the keys to be of a certain class
* before allowing a set or get operation.
*/
- public static class BaseMap implements Map {
+ public static class BaseMap implements AudioMetadataMap {
@Override
public <T> boolean containsKey(@NonNull Key<T> key) {
Pair<Key<?>, Object> valuePair = mHashMap.get(pairFromKey(key));
@@ -348,7 +263,7 @@ public final class AudioMetadata {
@Override
@NonNull
- public Map dup() {
+ public AudioMetadataMap dup() {
BaseMap map = new BaseMap();
map.mHashMap.putAll(this.mHashMap);
return map;
diff --git a/media/java/android/media/AudioMetadataMap.java b/media/java/android/media/AudioMetadataMap.java
new file mode 100644
index 000000000000..196193174754
--- /dev/null
+++ b/media/java/android/media/AudioMetadataMap.java
@@ -0,0 +1,59 @@
+/*
+ * Copyright (C) 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.media;
+
+import android.annotation.NonNull;
+import android.annotation.Nullable;
+
+/**
+ * AudioMetadataMap is a writeable {@code Map}-style
+ * interface of {@link AudioMetadata.Key} value pairs.
+ * This interface is not guaranteed to be thread-safe
+ * unless the underlying implementation for the {@code AudioMetadataMap}
+ * states it as thread safe.
+ *
+ * {@see AudioMetadataReadMap}
+ */
+// TODO: Create a wrapper like java.util.Collections.synchronizedMap?
+
+public interface AudioMetadataMap extends AudioMetadataReadMap {
+ /**
+ * Removes the value associated with the key.
+ * @param key interface for storing the value.
+ * @param <T> type of value.
+ * @return the value of the key, null if it doesn't exist.
+ */
+ @Nullable
+ <T> T remove(@NonNull AudioMetadata.Key<T> key);
+
+ /**
+ * Sets a value for the key.
+ *
+ * @param key interface for storing the value.
+ * @param <T> type of value.
+ * @param value a non-null value of type T.
+ * @return the previous value associated with key or null if it doesn't exist.
+ */
+ // See automatic Kotlin overloading for Java interoperability.
+ // https://kotlinlang.org/docs/reference/java-interop.html#operators
+ // See also Kotlin set for overloaded operator indexing.
+ // https://kotlinlang.org/docs/reference/operator-overloading.html#indexed
+ // Also the Kotlin mutable-list set.
+ // https://kotlinlang.org/api/latest/jvm/stdlib/kotlin.collections/-mutable-list/set.html
+ @Nullable
+ <T> T set(@NonNull AudioMetadata.Key<T> key, @NonNull T value);
+}
diff --git a/media/java/android/media/AudioMetadataReadMap.java b/media/java/android/media/AudioMetadataReadMap.java
new file mode 100644
index 000000000000..e74242a292d4
--- /dev/null
+++ b/media/java/android/media/AudioMetadataReadMap.java
@@ -0,0 +1,81 @@
+/*
+ * Copyright (C) 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.media;
+
+import android.annotation.IntRange;
+import android.annotation.NonNull;
+import android.annotation.Nullable;
+
+import java.util.Set;
+
+/**
+ * A read only {@code Map}-style interface of {@link AudioMetadata.Key} value pairs used
+ * for {@link AudioMetadata}.
+ *
+ * <p>Using a {@link AudioMetadata.Key} interface,
+ * this map looks up the corresponding value.
+ * Read-only maps are thread-safe for lookup, but the underlying object
+ * values may need their own thread protection if mutable.</p>
+ *
+ * {@see AudioMetadataMap}
+ */
+public interface AudioMetadataReadMap {
+ /**
+ * Returns true if the key exists in the map.
+ *
+ * @param key interface for requesting the value.
+ * @param <T> type of value.
+ * @return true if key exists in the Map.
+ */
+ <T> boolean containsKey(@NonNull AudioMetadata.Key<T> key);
+
+ /**
+ * Returns a copy of the map.
+ *
+ * This is intended for safe conversion between a {@link AudioMetadataReadMap}
+ * interface and a {@link AudioMetadataMap} interface.
+ * Currently only simple objects are used for key values which
+ * means a shallow copy is sufficient.
+ *
+ * @return a Map copied from the existing map.
+ */
+ @NonNull
+ AudioMetadataMap dup(); // lint checker doesn't like clone().
+
+ /**
+ * Returns the value associated with the key.
+ *
+ * @param key interface for requesting the value.
+ * @param <T> type of value.
+ * @return returns the value of associated with key or null if it doesn't exist.
+ */
+ @Nullable
+ <T> T get(@NonNull AudioMetadata.Key<T> key);
+
+ /**
+ * Returns a {@code Set} of keys associated with the map.
+ * @hide
+ */
+ @NonNull
+ Set<AudioMetadata.Key<?>> keySet();
+
+ /**
+ * Returns the number of elements in the map.
+ */
+ @IntRange(from = 0)
+ int size();
+}
diff --git a/media/java/android/media/AudioTrack.java b/media/java/android/media/AudioTrack.java
index d17e42996726..1d229b80cb2c 100644
--- a/media/java/android/media/AudioTrack.java
+++ b/media/java/android/media/AudioTrack.java
@@ -918,7 +918,29 @@ public class AudioTrack extends PlayerBase
private final int mContentId;
private final int mSyncId;
- private TunerConfiguration(int contentId, int syncId) {
+ /**
+ * Constructs a TunerConfiguration instance for use in {@link AudioTrack.Builder}
+ *
+ * @param contentId selects the audio stream to use.
+ * The contentId may be obtained from
+ * {@link android.media.tv.tuner.filter.Filter#getId()}.
+ * This is always a positive number.
+ * @param syncId selects the clock to use for synchronization
+ * of audio with other streams such as video.
+ * The syncId may be obtained from
+ * {@link android.media.tv.tuner.Tuner#getAvSyncHwId()}.
+ * This is always a positive number.
+ */
+ @RequiresPermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING)
+ public TunerConfiguration(
+ @IntRange(from = 1) int contentId, @IntRange(from = 1)int syncId) {
+ if (contentId < 1) {
+ throw new IllegalArgumentException(
+ "contentId " + contentId + " must be positive");
+ }
+ if (syncId < 1) {
+ throw new IllegalArgumentException("syncId " + syncId + " must be positive");
+ }
mContentId = contentId;
mSyncId = syncId;
}
@@ -938,73 +960,6 @@ public class AudioTrack extends PlayerBase
public @IntRange(from = 1) int getSyncId() {
return mSyncId; // The Builder ensures this is > 0.
}
-
- /**
- * Builder class for {@link AudioTrack.TunerConfiguration} objects.
- */
- public static class Builder {
- private int mContentId;
- private int mSyncId;
-
- /**
- * Sets the contentId from the Tuner filter.
- *
- * @param contentId selects the audio stream to use.
- * The contentId may be obtained from
- * {@link android.media.tv.tuner.filter.Filter#getId()}.
- * This is always a positive number.
- *
- * @return the same Builder instance.
- */
- @RequiresPermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING)
- public @NonNull Builder setContentId(@IntRange(from = 1) int contentId) {
- if (contentId < 1) {
- throw new IllegalArgumentException(
- "contentId " + contentId + " must be positive");
- }
- mContentId = contentId;
- return this;
- }
-
- /**
- * Sets the syncId from the Tuner filter.
- *
- * @param syncId selects the clock to use for synchronization
- * of audio with other streams such as video.
- * The syncId may be obtained from
- * {@link android.media.tv.tuner.Tuner#getAvSyncHwId()}.
- * This is always a positive number.
- *
- * @return the same Builder instance.
- */
- @RequiresPermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING)
- public @NonNull Builder setSyncId(@IntRange(from = 1) int syncId) {
- if (syncId < 1) {
- throw new IllegalArgumentException("syncId " + syncId + " must be positive");
- }
- mSyncId = syncId;
- return this;
- }
-
- /**
- * Builds a {@link AudioTrack.TunerConfiguration} instance initialized with
- * the parameters set on this {@code Builder}.
- *
- * @return a new successfully initialized {@link AudioTrack.TunerConfiguration}.
- * @throws UnsupportedOperationException if the parameters set on the
- * {@code Builder} are incompatible.
- */
- @RequiresPermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING)
- public @NonNull TunerConfiguration build() {
- if (mContentId < 1 || mSyncId < 1) {
- throw new UnsupportedOperationException(
- "mContentId " + mContentId
- + " mSyncId " + mSyncId
- + " must be set");
- }
- return new TunerConfiguration(mContentId, mSyncId);
- }
- }
}
/**
@@ -3673,7 +3628,7 @@ public class AudioTrack extends PlayerBase
// OnCodecFormatChangedListener notifications uses an instance
// of ListenerList to manage its listeners.
- private final Utils.ListenerList<AudioMetadata.ReadMap> mCodecFormatChangedListeners =
+ private final Utils.ListenerList<AudioMetadataReadMap> mCodecFormatChangedListeners =
new Utils.ListenerList();
/**
@@ -3684,13 +3639,13 @@ public class AudioTrack extends PlayerBase
* Called when the compressed codec format changes.
*
* @param audioTrack is the {@code AudioTrack} instance associated with the codec.
- * @param info is a {@link AudioMetadata.ReadMap} of values which contains decoded format
+ * @param info is a {@link AudioMetadataReadMap} of values which contains decoded format
* changes reported by the codec. Not all hardware
* codecs indicate codec format changes. Acceptable keys are taken from
* {@code AudioMetadata.Format.KEY_*} range, with the associated value type.
*/
void onCodecFormatChanged(
- @NonNull AudioTrack audioTrack, @Nullable AudioMetadata.ReadMap info);
+ @NonNull AudioTrack audioTrack, @Nullable AudioMetadataReadMap info);
}
/**
@@ -3708,7 +3663,7 @@ public class AudioTrack extends PlayerBase
mCodecFormatChangedListeners.add(
listener, /* key for removal */
executor,
- (int eventCode, AudioMetadata.ReadMap readMap) -> {
+ (int eventCode, AudioMetadataReadMap readMap) -> {
// eventCode is unused by this implementation.
listener.onCodecFormatChanged(this, readMap);
}
@@ -4067,7 +4022,7 @@ public class AudioTrack extends PlayerBase
ByteBuffer buffer = (ByteBuffer) obj;
buffer.order(ByteOrder.nativeOrder());
buffer.rewind();
- AudioMetadata.ReadMap audioMetaData = AudioMetadata.fromByteBuffer(buffer);
+ AudioMetadataReadMap audioMetaData = AudioMetadata.fromByteBuffer(buffer);
if (audioMetaData == null) {
Log.e(TAG, "Unable to get audio metadata from byte buffer");
return;
diff --git a/packages/SettingsProvider/src/android/provider/settings/backup/SecureSettings.java b/packages/SettingsProvider/src/android/provider/settings/backup/SecureSettings.java
index d320df9c24ba..3c0ddc4b65c5 100644
--- a/packages/SettingsProvider/src/android/provider/settings/backup/SecureSettings.java
+++ b/packages/SettingsProvider/src/android/provider/settings/backup/SecureSettings.java
@@ -163,6 +163,6 @@ public class SecureSettings {
Settings.Secure.AWARE_TAP_PAUSE_TOUCH_COUNT,
Settings.Secure.PEOPLE_STRIP,
Settings.Secure.ACCESSIBILITY_MAGNIFICATION_MODE,
- Settings.Secure.ACCESSIBILITY_BUTTON_LONG_PRESS_TARGETS,
+ Settings.Secure.ACCESSIBILITY_BUTTON_TARGETS,
};
}
diff --git a/packages/SettingsProvider/src/android/provider/settings/validators/SecureSettingsValidators.java b/packages/SettingsProvider/src/android/provider/settings/validators/SecureSettingsValidators.java
index 8801a9c32a36..3e64a378bc6a 100644
--- a/packages/SettingsProvider/src/android/provider/settings/validators/SecureSettingsValidators.java
+++ b/packages/SettingsProvider/src/android/provider/settings/validators/SecureSettingsValidators.java
@@ -78,9 +78,7 @@ public class SecureSettingsValidators {
ACCESSIBILITY_SHORTCUT_TARGET_LIST_VALIDATOR);
// technically either ComponentName or class name, but there's proper value
// validation at callsites, so allow any non-null string
- VALIDATORS.put(
- Secure.ACCESSIBILITY_BUTTON_TARGET_COMPONENT,
- ACCESSIBILITY_SHORTCUT_TARGET_LIST_VALIDATOR);
+ VALIDATORS.put(Secure.ACCESSIBILITY_BUTTON_TARGET_COMPONENT, value -> value != null);
VALIDATORS.put(Secure.ACCESSIBILITY_SHORTCUT_DIALOG_SHOWN, BOOLEAN_VALIDATOR);
VALIDATORS.put(Secure.ACCESSIBILITY_SHORTCUT_ON_LOCK_SCREEN, BOOLEAN_VALIDATOR);
VALIDATORS.put(Secure.ACCESSIBILITY_HIGH_TEXT_CONTRAST_ENABLED, BOOLEAN_VALIDATOR);
@@ -248,7 +246,7 @@ public class SecureSettingsValidators {
Secure.ACCESSIBILITY_MAGNIFICATION_MODE_FULLSCREEN,
Secure.ACCESSIBILITY_MAGNIFICATION_MODE_WINDOW));
VALIDATORS.put(
- Secure.ACCESSIBILITY_BUTTON_LONG_PRESS_TARGETS,
+ Secure.ACCESSIBILITY_BUTTON_TARGETS,
ACCESSIBILITY_SHORTCUT_TARGET_LIST_VALIDATOR);
}
}
diff --git a/packages/SettingsProvider/src/com/android/providers/settings/SettingsProtoDumpUtil.java b/packages/SettingsProvider/src/com/android/providers/settings/SettingsProtoDumpUtil.java
index b22caf0edc66..6fba15f5381f 100644
--- a/packages/SettingsProvider/src/com/android/providers/settings/SettingsProtoDumpUtil.java
+++ b/packages/SettingsProvider/src/com/android/providers/settings/SettingsProtoDumpUtil.java
@@ -1811,8 +1811,8 @@ class SettingsProtoDumpUtil {
Settings.Secure.ACCESSIBILITY_MAGNIFICATION_MODE,
SecureSettingsProto.Accessibility.ACCESSIBILITY_MAGNIFICATION_MODE);
dumpSetting(s, p,
- Settings.Secure.ACCESSIBILITY_BUTTON_LONG_PRESS_TARGETS,
- SecureSettingsProto.Accessibility.BUTTON_LONG_PRESS_TARGETS);
+ Settings.Secure.ACCESSIBILITY_BUTTON_TARGETS,
+ SecureSettingsProto.Accessibility.BUTTON_TARGETS);
p.end(accessibilityToken);
final long adaptiveSleepToken = p.start(SecureSettingsProto.ADAPTIVE_SLEEP);
diff --git a/packages/Shell/src/com/android/shell/BugreportProgressService.java b/packages/Shell/src/com/android/shell/BugreportProgressService.java
index 0ae00e1ac8b5..a1376c3203f5 100644
--- a/packages/Shell/src/com/android/shell/BugreportProgressService.java
+++ b/packages/Shell/src/com/android/shell/BugreportProgressService.java
@@ -1808,13 +1808,13 @@ public class BugreportProgressService extends Service {
* Current value of progress (in percentage) of the bugreport generation as
* displayed by the UI.
*/
- AtomicInteger progress;
+ AtomicInteger progress = new AtomicInteger(0);
/**
* Last value of progress (in percentage) of the bugreport generation for which
* system notification was updated.
*/
- AtomicInteger lastProgress;
+ AtomicInteger lastProgress = new AtomicInteger(0);
/**
* Time of the last progress update.
diff --git a/packages/SystemUI/res/values-television/dimens.xml b/packages/SystemUI/res/values-television/dimens.xml
new file mode 100644
index 000000000000..6da0c693f389
--- /dev/null
+++ b/packages/SystemUI/res/values-television/dimens.xml
@@ -0,0 +1,20 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ ~ Copyright (C) 2020 The Android Open Source Project
+ ~
+ ~ Licensed under the Apache License, Version 2.0 (the "License");
+ ~ you may not use this file except in compliance with the License.
+ ~ You may obtain a copy of the License at
+ ~
+ ~ http://www.apache.org/licenses/LICENSE-2.0
+ ~
+ ~ Unless required by applicable law or agreed to in writing, software
+ ~ distributed under the License is distributed on an "AS IS" BASIS,
+ ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ ~ See the License for the specific language governing permissions and
+ ~ limitations under the License
+ -->
+<resources>
+ <!-- Opacity at which the background for the shutdown UI will be drawn. -->
+ <item name="shutdown_scrim_behind_alpha" format="float" type="dimen">1.0</item>
+</resources> \ No newline at end of file
diff --git a/packages/SystemUI/res/values-television/styles.xml b/packages/SystemUI/res/values-television/styles.xml
index b59f0072b8c3..b01c5d88e3b3 100644
--- a/packages/SystemUI/res/values-television/styles.xml
+++ b/packages/SystemUI/res/values-television/styles.xml
@@ -17,4 +17,9 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android">
<style name="Theme.SystemUI.Dialog" parent="@android:style/Theme.DeviceDefault.Dialog" />
<style name="Theme.SystemUI.Dialog.Alert" parent="@*android:style/Theme.DeviceDefault.Dialog.Alert" />
+
+ <style name="Animation.ShutdownUi">
+ <item name="android:windowEnterAnimation">@null</item>
+ <item name="android:windowExitAnimation">@null</item>
+ </style>
</resources>
diff --git a/packages/SystemUI/res/values/dimens.xml b/packages/SystemUI/res/values/dimens.xml
index ee7f5230145e..864442ecd0c5 100644
--- a/packages/SystemUI/res/values/dimens.xml
+++ b/packages/SystemUI/res/values/dimens.xml
@@ -1266,4 +1266,7 @@
<dimen name="screenrecord_status_icon_radius">5dp</dimen>
<dimen name="kg_user_switcher_text_size">16sp</dimen>
+
+ <!-- Opacity at which the background for the shutdown UI will be drawn. -->
+ <item name="shutdown_scrim_behind_alpha" format="float" type="dimen">0.95</item>
</resources>
diff --git a/packages/SystemUI/res/values/styles.xml b/packages/SystemUI/res/values/styles.xml
index 1233d4dc73e7..9f1e63e0aa27 100644
--- a/packages/SystemUI/res/values/styles.xml
+++ b/packages/SystemUI/res/values/styles.xml
@@ -305,6 +305,9 @@
<item name="android:windowExitAnimation">@null</item>
</style>
+ <style name="Animation.ShutdownUi" parent="@android:style/Animation.Toast">
+ </style>
+
<!-- Standard animations for hiding and showing the status bar. -->
<style name="Animation.StatusBar">
</style>
diff --git a/packages/SystemUI/src/com/android/systemui/bubbles/BadgedImageView.java b/packages/SystemUI/src/com/android/systemui/bubbles/BadgedImageView.java
index a1cb7f61ad04..0b59ebcd57e9 100644
--- a/packages/SystemUI/src/com/android/systemui/bubbles/BadgedImageView.java
+++ b/packages/SystemUI/src/com/android/systemui/bubbles/BadgedImageView.java
@@ -28,6 +28,8 @@ import com.android.launcher3.icons.DotRenderer;
import com.android.systemui.Interpolators;
import com.android.systemui.R;
+import java.util.EnumSet;
+
/**
* View that displays an adaptive icon with an app-badge and a dot.
*
@@ -42,12 +44,27 @@ public class BadgedImageView extends ImageView {
/** Same as value in Launcher3 IconShape */
public static final int DEFAULT_PATH_SIZE = 100;
- static final int DOT_STATE_DEFAULT = 0;
- static final int DOT_STATE_SUPPRESSED_FOR_FLYOUT = 1;
- static final int DOT_STATE_ANIMATING = 2;
+ /**
+ * Flags that suppress the visibility of the 'new' dot, for one reason or another. If any of
+ * these flags are set, the dot will not be shown even if {@link Bubble#showDot()} returns true.
+ */
+ enum SuppressionFlag {
+ // Suppressed because the flyout is visible - it will morph into the dot via animation.
+ FLYOUT_VISIBLE,
+ // Suppressed because this bubble is behind others in the collapsed stack.
+ BEHIND_STACK,
+ }
- // Flyout gets shown before the dot
- private int mCurrentDotState = DOT_STATE_SUPPRESSED_FOR_FLYOUT;
+ /**
+ * Start by suppressing the dot because the flyout is visible - most bubbles are added with a
+ * flyout, so this is a reasonable default.
+ */
+ private final EnumSet<SuppressionFlag> mDotSuppressionFlags =
+ EnumSet.of(SuppressionFlag.FLYOUT_VISIBLE);
+
+ private float mDotScale = 0f;
+ private float mAnimatingToDotScale = 0f;
+ private boolean mDotIsAnimating = false;
private BubbleViewProvider mBubble;
@@ -57,8 +74,6 @@ public class BadgedImageView extends ImageView {
private boolean mOnLeft;
private int mDotColor;
- private float mDotScale = 0f;
- private boolean mDotDrawn;
private Rect mTempBounds = new Rect();
@@ -88,23 +103,21 @@ public class BadgedImageView extends ImageView {
/**
* Updates the view with provided info.
*/
- public void update(BubbleViewProvider bubble) {
+ public void setRenderedBubble(BubbleViewProvider bubble) {
mBubble = bubble;
setImageBitmap(bubble.getBadgedImage());
- setDotState(DOT_STATE_SUPPRESSED_FOR_FLYOUT);
mDotColor = bubble.getDotColor();
drawDot(bubble.getDotPath());
- animateDot();
}
@Override
public void onDraw(Canvas canvas) {
super.onDraw(canvas);
- if (isDotHidden()) {
- mDotDrawn = false;
+
+ if (!shouldDrawDot()) {
return;
}
- mDotDrawn = mDotScale > 0.1f;
+
getDrawingRect(mTempBounds);
mDrawParams.color = mDotColor;
@@ -115,23 +128,33 @@ public class BadgedImageView extends ImageView {
mDotRenderer.draw(canvas, mDrawParams);
}
- /**
- * Sets the dot state, does not animate changes.
- */
- void setDotState(int state) {
- mCurrentDotState = state;
- if (state == DOT_STATE_SUPPRESSED_FOR_FLYOUT || state == DOT_STATE_DEFAULT) {
- mDotScale = mBubble.showDot() ? 1f : 0f;
- invalidate();
+ /** Adds a dot suppression flag, updating dot visibility if needed. */
+ void addDotSuppressionFlag(SuppressionFlag flag) {
+ if (mDotSuppressionFlags.add(flag)) {
+ // Update dot visibility, and animate out if we're now behind the stack.
+ updateDotVisibility(flag == SuppressionFlag.BEHIND_STACK /* animate */);
}
}
- /**
- * Whether the dot should be hidden based on current dot state.
- */
- private boolean isDotHidden() {
- return (mCurrentDotState == DOT_STATE_DEFAULT && !mBubble.showDot())
- || mCurrentDotState == DOT_STATE_SUPPRESSED_FOR_FLYOUT;
+ /** Removes a dot suppression flag, updating dot visibility if needed. */
+ void removeDotSuppressionFlag(SuppressionFlag flag) {
+ if (mDotSuppressionFlags.remove(flag)) {
+ // Update dot visibility, animating if we're no longer behind the stack.
+ updateDotVisibility(flag == SuppressionFlag.BEHIND_STACK);
+ }
+ }
+
+ /** Updates the visibility of the dot, animating if requested. */
+ void updateDotVisibility(boolean animate) {
+ final float targetScale = shouldDrawDot() ? 1f : 0f;
+
+ if (animate) {
+ animateDotScale(targetScale, null /* after */);
+ } else {
+ mDotScale = targetScale;
+ mAnimatingToDotScale = targetScale;
+ invalidate();
+ }
}
/**
@@ -194,11 +217,11 @@ public class BadgedImageView extends ImageView {
}
/** Sets the position of the 'new' dot, animating it out and back in if requested. */
- void setDotPosition(boolean onLeft, boolean animate) {
- if (animate && onLeft != getDotOnLeft() && !isDotHidden()) {
- animateDot(false /* showDot */, () -> {
+ void setDotPositionOnLeft(boolean onLeft, boolean animate) {
+ if (animate && onLeft != getDotOnLeft() && shouldDrawDot()) {
+ animateDotScale(0f /* showDot */, () -> {
setDotOnLeft(onLeft);
- animateDot(true /* showDot */, null);
+ animateDotScale(1.0f, null /* after */);
});
} else {
setDotOnLeft(onLeft);
@@ -209,28 +232,34 @@ public class BadgedImageView extends ImageView {
return getDotOnLeft();
}
- /** Changes the dot's visibility to match the bubble view's state. */
- void animateDot() {
- if (mCurrentDotState == DOT_STATE_DEFAULT) {
- animateDot(mBubble.showDot(), null);
- }
+ /** Whether to draw the dot in onDraw(). */
+ private boolean shouldDrawDot() {
+ // Always render the dot if it's animating, since it could be animating out. Otherwise, show
+ // it if the bubble wants to show it, and we aren't suppressing it.
+ return mDotIsAnimating || (mBubble.showDot() && mDotSuppressionFlags.isEmpty());
}
/**
- * Animates the dot to show or hide.
+ * Animates the dot to the given scale, running the optional callback when the animation ends.
*/
- private void animateDot(boolean showDot, Runnable after) {
- if (mDotDrawn == showDot) {
- // State is consistent, do nothing.
+ private void animateDotScale(float toScale, @Nullable Runnable after) {
+ mDotIsAnimating = true;
+
+ // Don't restart the animation if we're already animating to the given value.
+ if (mAnimatingToDotScale == toScale || !shouldDrawDot()) {
+ mDotIsAnimating = false;
return;
}
- setDotState(DOT_STATE_ANIMATING);
+ mAnimatingToDotScale = toScale;
+
+ final boolean showDot = toScale > 0f;
// Do NOT wait until after animation ends to setShowDot
// to avoid overriding more recent showDot states.
clearAnimation();
- animate().setDuration(200)
+ animate()
+ .setDuration(200)
.setInterpolator(Interpolators.FAST_OUT_SLOW_IN)
.setUpdateListener((valueAnimator) -> {
float fraction = valueAnimator.getAnimatedFraction();
@@ -238,7 +267,7 @@ public class BadgedImageView extends ImageView {
setDotScale(fraction);
}).withEndAction(() -> {
setDotScale(showDot ? 1f : 0f);
- setDotState(DOT_STATE_DEFAULT);
+ mDotIsAnimating = false;
if (after != null) {
after.run();
}
diff --git a/packages/SystemUI/src/com/android/systemui/bubbles/Bubble.java b/packages/SystemUI/src/com/android/systemui/bubbles/Bubble.java
index 726a7dd111d7..afa3164cbd38 100644
--- a/packages/SystemUI/src/com/android/systemui/bubbles/Bubble.java
+++ b/packages/SystemUI/src/com/android/systemui/bubbles/Bubble.java
@@ -247,7 +247,7 @@ class Bubble implements BubbleViewProvider {
mExpandedView.update(/* bubble */ this);
}
if (mIconView != null) {
- mIconView.update(/* bubble */ this);
+ mIconView.setRenderedBubble(/* bubble */ this);
}
}
@@ -306,7 +306,7 @@ class Bubble implements BubbleViewProvider {
void markAsAccessedAt(long lastAccessedMillis) {
mLastAccessed = lastAccessedMillis;
setSuppressNotification(true);
- setShowDot(false /* show */, true /* animate */);
+ setShowDot(false /* show */);
}
/**
@@ -346,12 +346,11 @@ class Bubble implements BubbleViewProvider {
/**
* Sets whether the bubble for this notification should show a dot indicating updated content.
*/
- void setShowDot(boolean showDot, boolean animate) {
+ void setShowDot(boolean showDot) {
mShowBubbleUpdateDot = showDot;
- if (animate && mIconView != null) {
- mIconView.animateDot();
- } else if (mIconView != null) {
- mIconView.invalidate();
+
+ if (mIconView != null) {
+ mIconView.updateDotVisibility(true /* animate */);
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/bubbles/BubbleController.java b/packages/SystemUI/src/com/android/systemui/bubbles/BubbleController.java
index 01c2faa62403..9d885fd3c207 100644
--- a/packages/SystemUI/src/com/android/systemui/bubbles/BubbleController.java
+++ b/packages/SystemUI/src/com/android/systemui/bubbles/BubbleController.java
@@ -331,14 +331,14 @@ public class BubbleController implements ConfigurationController.ConfigurationLi
@Override
public void onZenChanged(int zen) {
for (Bubble b : mBubbleData.getBubbles()) {
- b.setShowDot(b.showInShade(), true /* animate */);
+ b.setShowDot(b.showInShade());
}
}
@Override
public void onConfigChanged(ZenModeConfig config) {
for (Bubble b : mBubbleData.getBubbles()) {
- b.setShowDot(b.showInShade(), true /* animate */);
+ b.setShowDot(b.showInShade());
}
}
});
@@ -1101,7 +1101,7 @@ public class BubbleController implements ConfigurationController.ConfigurationLi
} else if (interceptBubbleDismissal) {
Bubble bubble = mBubbleData.getBubbleWithKey(entry.getKey());
bubble.setSuppressNotification(true);
- bubble.setShowDot(false /* show */, true /* animate */);
+ bubble.setShowDot(false /* show */);
} else {
return false;
}
@@ -1141,7 +1141,7 @@ public class BubbleController implements ConfigurationController.ConfigurationLi
Bubble bubbleChild = mBubbleData.getBubbleWithKey(child.getKey());
mNotificationGroupManager.onEntryRemoved(bubbleChild.getEntry());
bubbleChild.setSuppressNotification(true);
- bubbleChild.setShowDot(false /* show */, true /* animate */);
+ bubbleChild.setShowDot(false /* show */);
} else {
// non-bubbled children can be removed
for (NotifCallback cb : mCallbacks) {
diff --git a/packages/SystemUI/src/com/android/systemui/bubbles/BubbleData.java b/packages/SystemUI/src/com/android/systemui/bubbles/BubbleData.java
index 2bd15188b7d3..1c69594469c1 100644
--- a/packages/SystemUI/src/com/android/systemui/bubbles/BubbleData.java
+++ b/packages/SystemUI/src/com/android/systemui/bubbles/BubbleData.java
@@ -288,7 +288,7 @@ public class BubbleData {
boolean isBubbleExpandedAndSelected = mExpanded && mSelectedBubble == bubble;
boolean suppress = isBubbleExpandedAndSelected || !showInShade || !bubble.showInShade();
bubble.setSuppressNotification(suppress);
- bubble.setShowDot(!isBubbleExpandedAndSelected /* show */, true /* animate */);
+ bubble.setShowDot(!isBubbleExpandedAndSelected /* show */);
dispatchPendingChanges();
}
diff --git a/packages/SystemUI/src/com/android/systemui/bubbles/BubbleOverflow.java b/packages/SystemUI/src/com/android/systemui/bubbles/BubbleOverflow.java
index 4fb2d0881ede..13669a68defa 100644
--- a/packages/SystemUI/src/com/android/systemui/bubbles/BubbleOverflow.java
+++ b/packages/SystemUI/src/com/android/systemui/bubbles/BubbleOverflow.java
@@ -112,7 +112,7 @@ public class BubbleOverflow implements BubbleViewProvider {
mPath.transform(matrix);
mOverflowBtn.setVisibility(GONE);
- mOverflowBtn.update(this);
+ mOverflowBtn.setRenderedBubble(this);
}
ImageView getBtn() {
diff --git a/packages/SystemUI/src/com/android/systemui/bubbles/BubbleOverflowActivity.java b/packages/SystemUI/src/com/android/systemui/bubbles/BubbleOverflowActivity.java
index b65198595095..2231d11b7bc2 100644
--- a/packages/SystemUI/src/com/android/systemui/bubbles/BubbleOverflowActivity.java
+++ b/packages/SystemUI/src/com/android/systemui/bubbles/BubbleOverflowActivity.java
@@ -183,7 +183,7 @@ class BubbleOverflowAdapter extends RecyclerView.Adapter<BubbleOverflowAdapter.V
public void onBindViewHolder(ViewHolder vh, int index) {
Bubble b = mBubbles.get(index);
- vh.iconView.update(b);
+ vh.iconView.setRenderedBubble(b);
vh.iconView.setOnClickListener(view -> {
mBubbles.remove(b);
notifyDataSetChanged();
diff --git a/packages/SystemUI/src/com/android/systemui/bubbles/BubbleStackView.java b/packages/SystemUI/src/com/android/systemui/bubbles/BubbleStackView.java
index 7191a203ea8c..4b036812dbed 100644
--- a/packages/SystemUI/src/com/android/systemui/bubbles/BubbleStackView.java
+++ b/packages/SystemUI/src/com/android/systemui/bubbles/BubbleStackView.java
@@ -22,8 +22,6 @@ import static android.view.ViewGroup.LayoutParams.WRAP_CONTENT;
import static com.android.systemui.Interpolators.FAST_OUT_SLOW_IN;
import static com.android.systemui.Prefs.Key.HAS_SEEN_BUBBLES_EDUCATION;
import static com.android.systemui.Prefs.Key.HAS_SEEN_BUBBLES_MANAGE_EDUCATION;
-import static com.android.systemui.bubbles.BadgedImageView.DOT_STATE_DEFAULT;
-import static com.android.systemui.bubbles.BadgedImageView.DOT_STATE_SUPPRESSED_FOR_FLYOUT;
import static com.android.systemui.bubbles.BubbleDebugConfig.DEBUG_BUBBLE_STACK_VIEW;
import static com.android.systemui.bubbles.BubbleDebugConfig.DEBUG_USER_EDUCATION;
import static com.android.systemui.bubbles.BubbleDebugConfig.TAG_BUBBLES;
@@ -226,7 +224,7 @@ public class BubbleStackView extends FrameLayout {
private boolean mIsExpanded;
/** Whether the stack is currently on the left side of the screen, or animating there. */
- private boolean mStackOnLeftOrWillBe = false;
+ private boolean mStackOnLeftOrWillBe = true;
/** Whether a touch gesture, such as a stack/bubble drag or flyout drag, is in progress. */
private boolean mIsGestureInProgress = false;
@@ -936,9 +934,13 @@ public class BubbleStackView extends FrameLayout {
mStackOnLeftOrWillBe = mStackAnimationController.isStackOnLeftSide();
}
+ if (bubble.getIconView() == null) {
+ return;
+ }
+
// Set the dot position to the opposite of the side the stack is resting on, since the stack
// resting slightly off-screen would result in the dot also being off-screen.
- bubble.getIconView().setDotPosition(
+ bubble.getIconView().setDotPositionOnLeft(
!mStackOnLeftOrWillBe /* onLeft */, false /* animate */);
mBubbleContainer.addView(bubble.getIconView(), 0,
@@ -1698,7 +1700,7 @@ public class BubbleStackView extends FrameLayout {
|| mBubbleToExpandAfterFlyoutCollapse != null
|| bubbleView == null) {
if (bubbleView != null) {
- bubbleView.setDotState(DOT_STATE_DEFAULT);
+ bubbleView.removeDotSuppressionFlag(BadgedImageView.SuppressionFlag.FLYOUT_VISIBLE);
}
// Skip the message if none exists, we're expanded or animating expansion, or we're
// about to expand a bubble from the previous tapped flyout, or if bubble view is null.
@@ -1717,12 +1719,16 @@ public class BubbleStackView extends FrameLayout {
mBubbleData.setExpanded(true);
mBubbleToExpandAfterFlyoutCollapse = null;
}
- bubbleView.setDotState(DOT_STATE_DEFAULT);
+
+ // Stop suppressing the dot now that the flyout has morphed into the dot.
+ bubbleView.removeDotSuppressionFlag(
+ BadgedImageView.SuppressionFlag.FLYOUT_VISIBLE);
};
mFlyout.setVisibility(INVISIBLE);
- // Don't show the dot when we're animating the flyout
- bubbleView.setDotState(DOT_STATE_SUPPRESSED_FOR_FLYOUT);
+ // Suppress the dot when we are animating the flyout.
+ bubbleView.addDotSuppressionFlag(
+ BadgedImageView.SuppressionFlag.FLYOUT_VISIBLE);
// Start flyout expansion. Post in case layout isn't complete and getWidth returns 0.
post(() -> {
@@ -1743,6 +1749,11 @@ public class BubbleStackView extends FrameLayout {
};
mFlyout.postDelayed(mAnimateInFlyout, 200);
};
+
+ if (bubble.getIconView() == null) {
+ return;
+ }
+
mFlyout.setupFlyoutStartingAsDot(flyoutMessage,
mStackAnimationController.getStackPosition(), getWidth(),
mStackAnimationController.isStackOnLeftSide(),
@@ -1877,9 +1888,19 @@ public class BubbleStackView extends FrameLayout {
for (int i = 0; i < bubbleCount; i++) {
BadgedImageView bv = (BadgedImageView) mBubbleContainer.getChildAt(i);
bv.setZ((mMaxBubbles * mBubbleElevation) - i);
+
// If the dot is on the left, and so is the stack, we need to change the dot position.
if (bv.getDotPositionOnLeft() == mStackOnLeftOrWillBe) {
- bv.setDotPosition(!mStackOnLeftOrWillBe, animate);
+ bv.setDotPositionOnLeft(!mStackOnLeftOrWillBe, animate);
+ }
+
+ if (!mIsExpanded && i > 0) {
+ // If we're collapsed and this bubble is behind other bubbles, suppress its dot.
+ bv.addDotSuppressionFlag(
+ BadgedImageView.SuppressionFlag.BEHIND_STACK);
+ } else {
+ bv.removeDotSuppressionFlag(
+ BadgedImageView.SuppressionFlag.BEHIND_STACK);
}
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/bubbles/animation/StackAnimationController.java b/packages/SystemUI/src/com/android/systemui/bubbles/animation/StackAnimationController.java
index 7ee162e03dbc..00de8b4a51b8 100644
--- a/packages/SystemUI/src/com/android/systemui/bubbles/animation/StackAnimationController.java
+++ b/packages/SystemUI/src/com/android/systemui/bubbles/animation/StackAnimationController.java
@@ -287,7 +287,7 @@ public class StackAnimationController extends
/** Whether the stack is on the left side of the screen. */
public boolean isStackOnLeftSide() {
if (mLayout == null || !isStackPositionSet()) {
- return false;
+ return true; // Default to left, which is where it starts by default.
}
float stackCenter = mStackPosition.x + mBubbleBitmapSize / 2;
diff --git a/packages/SystemUI/src/com/android/systemui/globalactions/GlobalActionsImpl.java b/packages/SystemUI/src/com/android/systemui/globalactions/GlobalActionsImpl.java
index 12955a153360..ce29859f12ca 100644
--- a/packages/SystemUI/src/com/android/systemui/globalactions/GlobalActionsImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/globalactions/GlobalActionsImpl.java
@@ -49,8 +49,6 @@ import dagger.Lazy;
public class GlobalActionsImpl implements GlobalActions, CommandQueue.Callbacks {
- private static final float SHUTDOWN_SCRIM_ALPHA = 0.95f;
-
private final Context mContext;
private final Lazy<GlobalActionsDialog> mGlobalActionsDialogLazy;
private final KeyguardStateController mKeyguardStateController;
@@ -124,7 +122,7 @@ public class GlobalActionsImpl implements GlobalActions, CommandQueue.Callbacks
| WindowManager.LayoutParams.FLAG_WATCH_OUTSIDE_TOUCH
| WindowManager.LayoutParams.FLAG_HARDWARE_ACCELERATED);
window.setBackgroundDrawable(background);
- window.setWindowAnimations(R.style.Animation_Toast);
+ window.setWindowAnimations(com.android.systemui.R.style.Animation_ShutdownUi);
d.setContentView(R.layout.shutdown_dialog);
d.setCancelable(false);
@@ -153,7 +151,9 @@ public class GlobalActionsImpl implements GlobalActions, CommandQueue.Callbacks
mBlurUtils.applyBlur(d.getWindow().getDecorView().getViewRootImpl(),
mBlurUtils.blurRadiusOfRatio(1));
} else {
- background.setAlpha((int) (SHUTDOWN_SCRIM_ALPHA * 255));
+ float backgroundAlpha = mContext.getResources().getFloat(
+ com.android.systemui.R.dimen.shutdown_scrim_behind_alpha);
+ background.setAlpha((int) (backgroundAlpha * 255));
}
d.show();
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/BatteryControllerImpl.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/BatteryControllerImpl.java
index 496bf68e67a5..bf5900ff24bb 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/BatteryControllerImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/BatteryControllerImpl.java
@@ -67,9 +67,9 @@ public class BatteryControllerImpl extends BroadcastReceiver implements BatteryC
private final Handler mBgHandler;
protected final Context mContext;
- private int mLevel;
- private boolean mPluggedIn;
- private boolean mCharging;
+ protected int mLevel;
+ protected boolean mPluggedIn;
+ protected boolean mCharging;
private boolean mCharged;
private boolean mPowerSave;
private boolean mAodPowerSave;
diff --git a/services/core/java/com/android/server/PackageWatchdog.java b/services/core/java/com/android/server/PackageWatchdog.java
index 41a104c5d4dc..d9e7c3851906 100644
--- a/services/core/java/com/android/server/PackageWatchdog.java
+++ b/services/core/java/com/android/server/PackageWatchdog.java
@@ -1062,7 +1062,12 @@ public class PackageWatchdog {
public void updatePackagesLocked(List<MonitoredPackage> packages) {
for (int pIndex = 0; pIndex < packages.size(); pIndex++) {
MonitoredPackage p = packages.get(pIndex);
- this.packages.put(p.getName(), p);
+ MonitoredPackage existingPackage = this.packages.get(p.getName());
+ if (existingPackage != null) {
+ existingPackage.updateHealthCheckDuration(p.mDurationMs);
+ } else {
+ this.packages.put(p.getName(), p);
+ }
}
}
@@ -1331,6 +1336,12 @@ public class PackageWatchdog {
return updateHealthCheckStateLocked();
}
+ /** Explicitly update the monitoring duration of the package. */
+ @GuardedBy("mLock")
+ public void updateHealthCheckDuration(long newDurationMs) {
+ mDurationMs = newDurationMs;
+ }
+
/**
* Marks the health check as passed and transitions to {@link HealthCheckState.PASSED}
* if not yet {@link HealthCheckState.FAILED}.
diff --git a/services/core/java/com/android/server/VibratorService.java b/services/core/java/com/android/server/VibratorService.java
index dd9cc641f2dd..ac4a42ca7024 100644
--- a/services/core/java/com/android/server/VibratorService.java
+++ b/services/core/java/com/android/server/VibratorService.java
@@ -605,15 +605,16 @@ public class VibratorService extends IVibratorService.Stub
}
@Override // Binder call
- public boolean[] areEffectsSupported(int[] effectIds) {
- // Return null to indicate that the HAL doesn't actually tell us what effects are
- // supported.
+ public int[] areEffectsSupported(int[] effectIds) {
+ int[] supported = new int[effectIds.length];
if (mSupportedEffects == null) {
- return null;
- }
- boolean[] supported = new boolean[effectIds.length];
- for (int i = 0; i < effectIds.length; i++) {
- supported[i] = mSupportedEffects.contains(effectIds[i]);
+ Arrays.fill(supported, Vibrator.VIBRATION_EFFECT_SUPPORT_UNKNOWN);
+ } else {
+ for (int i = 0; i < effectIds.length; i++) {
+ supported[i] = mSupportedEffects.contains(effectIds[i])
+ ? Vibrator.VIBRATION_EFFECT_SUPPORT_YES
+ : Vibrator.VIBRATION_EFFECT_SUPPORT_NO;
+ }
}
return supported;
}
diff --git a/services/core/java/com/android/server/notification/NotificationManagerService.java b/services/core/java/com/android/server/notification/NotificationManagerService.java
index 31dc09416ac8..87061e1d488c 100755
--- a/services/core/java/com/android/server/notification/NotificationManagerService.java
+++ b/services/core/java/com/android/server/notification/NotificationManagerService.java
@@ -107,6 +107,7 @@ import android.annotation.CallbackExecutor;
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.annotation.RequiresPermission;
+import android.annotation.UserIdInt;
import android.annotation.WorkerThread;
import android.app.ActivityManager;
import android.app.ActivityManagerInternal;
@@ -2842,20 +2843,18 @@ public class NotificationManagerService extends SystemService {
record = mToastQueue.get(index);
record.update(duration);
} else {
- // Limit the number of toasts that any given package except the android
- // package can enqueue. Prevents DOS attacks and deals with leaks.
- if (!isSystemToast) {
- int count = 0;
- final int N = mToastQueue.size();
- for (int i = 0; i < N; i++) {
- final ToastRecord r = mToastQueue.get(i);
- if (r.pkg.equals(pkg)) {
- count++;
- if (count >= MAX_PACKAGE_NOTIFICATIONS) {
- Slog.e(TAG, "Package has already posted " + count
- + " toasts. Not showing more. Package=" + pkg);
- return;
- }
+ // Limit the number of toasts that any given package can enqueue.
+ // Prevents DOS attacks and deals with leaks.
+ int count = 0;
+ final int N = mToastQueue.size();
+ for (int i = 0; i < N; i++) {
+ final ToastRecord r = mToastQueue.get(i);
+ if (r.pkg.equals(pkg)) {
+ count++;
+ if (count >= MAX_PACKAGE_NOTIFICATIONS) {
+ Slog.e(TAG, "Package has already posted " + count
+ + " toasts. Not showing more. Package=" + pkg);
+ return;
}
}
}
diff --git a/services/core/java/com/android/server/pm/PackageInstallerSession.java b/services/core/java/com/android/server/pm/PackageInstallerSession.java
index 42ed20654a2c..1248ec01e020 100644
--- a/services/core/java/com/android/server/pm/PackageInstallerSession.java
+++ b/services/core/java/com/android/server/pm/PackageInstallerSession.java
@@ -3245,8 +3245,7 @@ public class PackageInstallerSession extends IPackageInstallerSession.Stub {
new ComponentName(
readStringAttribute(in, ATTR_DATALOADER_PACKAGE_NAME),
readStringAttribute(in, ATTR_DATALOADER_CLASS_NAME)),
- readStringAttribute(in, ATTR_DATALOADER_ARGUMENTS),
- null);
+ readStringAttribute(in, ATTR_DATALOADER_ARGUMENTS));
}
final File appIconFile = buildAppIconFile(sessionId, sessionsDir);
diff --git a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java
index e304bca4553c..3ddee29366c7 100644
--- a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java
+++ b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java
@@ -15742,9 +15742,11 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager {
}
}
+ final int suspendedState = suspended
+ ? PERSONAL_APPS_SUSPENDED_EXPLICITLY
+ : PERSONAL_APPS_NOT_SUSPENDED;
mInjector.binderWithCleanCallingIdentity(
- () -> applyPersonalAppsSuspension(
- callingUserId, PERSONAL_APPS_SUSPENDED_EXPLICITLY));
+ () -> applyPersonalAppsSuspension(callingUserId, suspendedState));
DevicePolicyEventLogger
.createEvent(DevicePolicyEnums.SET_PERSONAL_APPS_SUSPENDED)
diff --git a/services/incremental/IncrementalService.cpp b/services/incremental/IncrementalService.cpp
index ed85b931c08e..ae27c7aabdda 100644
--- a/services/incremental/IncrementalService.cpp
+++ b/services/incremental/IncrementalService.cpp
@@ -286,7 +286,6 @@ void IncrementalService::onDump(int fd) {
dprintf(fd, "\t\t\tpackageName: %s\n", params.packageName.c_str());
dprintf(fd, "\t\t\tclassName: %s\n", params.className.c_str());
dprintf(fd, "\t\t\targuments: %s\n", params.arguments.c_str());
- dprintf(fd, "\t\t\tdynamicArgs: %d\n", int(params.dynamicArgs.size()));
}
dprintf(fd, "\t\tstorages (%d):\n", int(mnt.storages.size()));
for (auto&& [storageId, storage] : mnt.storages) {
diff --git a/services/tests/servicestests/src/com/android/server/MountServiceTests.java b/services/tests/servicestests/src/com/android/server/MountServiceTests.java
deleted file mode 100644
index b1b31744c88b..000000000000
--- a/services/tests/servicestests/src/com/android/server/MountServiceTests.java
+++ /dev/null
@@ -1,279 +0,0 @@
-/*
- * Copyright (C) 2010 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 android.content.Context;
-import android.content.res.Resources;
-import android.content.res.Resources.NotFoundException;
-import android.os.FileUtils;
-import android.os.storage.OnObbStateChangeListener;
-import android.os.storage.StorageManager;
-import android.test.AndroidTestCase;
-import android.test.ComparisonFailure;
-import android.test.suitebuilder.annotation.LargeTest;
-import android.util.Log;
-
-import com.android.frameworks.servicestests.R;
-
-import java.io.File;
-import java.io.InputStream;
-
-public class MountServiceTests extends AndroidTestCase {
- private static final String TAG = "MountServiceTests";
-
- private static final long MAX_WAIT_TIME = 25*1000;
- private static final long WAIT_TIME_INCR = 5*1000;
-
- private static final String OBB_MOUNT_PREFIX = "/mnt/obb/";
-
- private static void assertStartsWith(String message, String prefix, String actual) {
- if (!actual.startsWith(prefix)) {
- throw new ComparisonFailure(message, prefix, actual);
- }
- }
-
- private static class ObbObserver extends OnObbStateChangeListener {
- private String path;
-
- public int state = -1;
- boolean done = false;
-
- @Override
- public void onObbStateChange(String path, int state) {
- Log.d(TAG, "Received message. path=" + path + ", state=" + state);
- synchronized (this) {
- this.path = path;
- this.state = state;
- done = true;
- notifyAll();
- }
- }
-
- public String getPath() {
- assertTrue("Expected ObbObserver to have received a state change.", done);
- return path;
- }
-
- public int getState() {
- assertTrue("Expected ObbObserver to have received a state change.", done);
- return state;
- }
-
- public void reset() {
- this.path = null;
- this.state = -1;
- done = false;
- }
-
- public boolean isDone() {
- return done;
- }
-
- public boolean waitForCompletion() {
- long waitTime = 0;
- synchronized (this) {
- while (!isDone() && waitTime < MAX_WAIT_TIME) {
- try {
- wait(WAIT_TIME_INCR);
- waitTime += WAIT_TIME_INCR;
- } catch (InterruptedException e) {
- Log.i(TAG, "Interrupted during sleep", e);
- }
- }
- }
-
- return isDone();
- }
- }
-
- private File getFilePath(String name) {
- final File filesDir = mContext.getFilesDir();
- final File outFile = new File(filesDir, name);
- return outFile;
- }
-
- private void copyRawToFile(int rawResId, File outFile) {
- Resources res = mContext.getResources();
- InputStream is = null;
- try {
- is = res.openRawResource(rawResId);
- } catch (NotFoundException e) {
- fail("Failed to load resource with id: " + rawResId);
- }
- FileUtils.setPermissions(outFile.getPath(), FileUtils.S_IRWXU | FileUtils.S_IRWXG
- | FileUtils.S_IRWXO, -1, -1);
- assertTrue(FileUtils.copyToFile(is, outFile));
- FileUtils.setPermissions(outFile.getPath(), FileUtils.S_IRWXU | FileUtils.S_IRWXG
- | FileUtils.S_IRWXO, -1, -1);
- }
-
- private StorageManager getStorageManager() {
- return (StorageManager) getContext().getSystemService(Context.STORAGE_SERVICE);
- }
-
- private void mountObb(StorageManager sm, final int resource, final File file,
- int expectedState) {
- copyRawToFile(resource, file);
-
- final ObbObserver observer = new ObbObserver();
- assertTrue("mountObb call on " + file.getPath() + " should succeed",
- sm.mountObb(file.getPath(), null, observer));
-
- assertTrue("Mount should have completed",
- observer.waitForCompletion());
-
- if (expectedState == OnObbStateChangeListener.MOUNTED) {
- assertTrue("OBB should be mounted", sm.isObbMounted(file.getPath()));
- }
-
- assertEquals("Actual file and resolved file should be the same",
- file.getPath(), observer.getPath());
-
- assertEquals(expectedState, observer.getState());
- }
-
- private ObbObserver mountObbWithoutWait(final StorageManager sm, final int resource,
- final File file) {
- copyRawToFile(resource, file);
-
- final ObbObserver observer = new ObbObserver();
- assertTrue("mountObb call on " + file.getPath() + " should succeed", sm.mountObb(file
- .getPath(), null, observer));
-
- return observer;
- }
-
- private void waitForObbActionCompletion(final StorageManager sm, final File file,
- final ObbObserver observer, int expectedState, boolean checkPath) {
- assertTrue("Mount should have completed", observer.waitForCompletion());
-
- assertTrue("OBB should be mounted", sm.isObbMounted(file.getPath()));
-
- if (checkPath) {
- assertEquals("Actual file and resolved file should be the same", file.getPath(),
- observer.getPath());
- }
-
- assertEquals(expectedState, observer.getState());
- }
-
- private String checkMountedPath(final StorageManager sm, final File file) {
- final String mountPath = sm.getMountedObbPath(file.getPath());
- assertStartsWith("Path should be in " + OBB_MOUNT_PREFIX,
- OBB_MOUNT_PREFIX,
- mountPath);
- return mountPath;
- }
-
- private void unmountObb(final StorageManager sm, final File file, int expectedState) {
- final ObbObserver observer = new ObbObserver();
-
- assertTrue("unmountObb call on test1.obb should succeed",
- sm.unmountObb(file.getPath(), false, observer));
-
- assertTrue("Unmount should have completed",
- observer.waitForCompletion());
-
- assertEquals(expectedState, observer.getState());
-
- if (expectedState == OnObbStateChangeListener.UNMOUNTED) {
- assertFalse("OBB should not be mounted", sm.isObbMounted(file.getPath()));
- }
- }
-
- @LargeTest
- public void testMountAndUnmountObbNormal() {
- StorageManager sm = getStorageManager();
-
- final File outFile = getFilePath("test1.obb");
-
- mountObb(sm, R.raw.test1, outFile, OnObbStateChangeListener.MOUNTED);
-
- mountObb(sm, R.raw.test1, outFile, OnObbStateChangeListener.ERROR_ALREADY_MOUNTED);
-
- final String mountPath = checkMountedPath(sm, outFile);
- final File mountDir = new File(mountPath);
-
- assertTrue("OBB mounted path should be a directory",
- mountDir.isDirectory());
-
- unmountObb(sm, outFile, OnObbStateChangeListener.UNMOUNTED);
- }
-
- @LargeTest
- public void testAttemptMountNonObb() {
- StorageManager sm = getStorageManager();
-
- final File outFile = getFilePath("test1_nosig.obb");
-
- try {
- mountObb(sm, R.raw.test1_nosig, outFile, OnObbStateChangeListener.ERROR_INTERNAL);
- fail("mountObb should've failed with an exception");
- } catch (IllegalArgumentException e) {
- // Expected
- }
-
- assertFalse("OBB should not be mounted",
- sm.isObbMounted(outFile.getPath()));
-
- assertNull("OBB's mounted path should be null",
- sm.getMountedObbPath(outFile.getPath()));
- }
-
- @LargeTest
- public void testAttemptMountObbWrongPackage() {
- StorageManager sm = getStorageManager();
-
- final File outFile = getFilePath("test1_wrongpackage.obb");
-
- mountObb(sm, R.raw.test1_wrongpackage, outFile,
- OnObbStateChangeListener.ERROR_PERMISSION_DENIED);
-
- assertFalse("OBB should not be mounted",
- sm.isObbMounted(outFile.getPath()));
-
- assertNull("OBB's mounted path should be null",
- sm.getMountedObbPath(outFile.getPath()));
- }
-
- @LargeTest
- public void testMountAndUnmountTwoObbs() {
- StorageManager sm = getStorageManager();
-
- final File file1 = getFilePath("test1.obb");
- final File file2 = getFilePath("test2.obb");
-
- ObbObserver oo1 = mountObbWithoutWait(sm, R.raw.test1, file1);
- ObbObserver oo2 = mountObbWithoutWait(sm, R.raw.test1, file2);
-
- Log.d(TAG, "Waiting for OBB #1 to complete mount");
- waitForObbActionCompletion(sm, file1, oo1, OnObbStateChangeListener.MOUNTED, false);
- Log.d(TAG, "Waiting for OBB #2 to complete mount");
- waitForObbActionCompletion(sm, file2, oo2, OnObbStateChangeListener.MOUNTED, false);
-
- final String mountPath1 = checkMountedPath(sm, file1);
- final File mountDir1 = new File(mountPath1);
- assertTrue("OBB mounted path should be a directory", mountDir1.isDirectory());
-
- final String mountPath2 = checkMountedPath(sm, file2);
- final File mountDir2 = new File(mountPath2);
- assertTrue("OBB mounted path should be a directory", mountDir2.isDirectory());
-
- unmountObb(sm, file1, OnObbStateChangeListener.UNMOUNTED);
- unmountObb(sm, file2, OnObbStateChangeListener.UNMOUNTED);
- }
-}
diff --git a/tests/PackageWatchdog/src/com/android/server/PackageWatchdogTest.java b/tests/PackageWatchdog/src/com/android/server/PackageWatchdogTest.java
index 2957192ecf0f..d011dbbbe5db 100644
--- a/tests/PackageWatchdog/src/com/android/server/PackageWatchdogTest.java
+++ b/tests/PackageWatchdog/src/com/android/server/PackageWatchdogTest.java
@@ -1123,6 +1123,28 @@ public class PackageWatchdogTest {
assertThat(testController.getSyncRequests()).isEqualTo(expectedSyncRequests);
}
+ /**
+ * Ensure that the failure history of a package is preserved when making duplicate calls to
+ * observe the package.
+ */
+ @Test
+ public void testFailureHistoryIsPreserved() {
+ PackageWatchdog watchdog = createWatchdog();
+ TestObserver observer = new TestObserver(OBSERVER_NAME_1);
+ watchdog.startObservingHealth(observer, List.of(APP_A), SHORT_DURATION);
+ for (int i = 0; i < PackageWatchdog.DEFAULT_TRIGGER_FAILURE_COUNT - 1; i++) {
+ watchdog.onPackageFailure(List.of(new VersionedPackage(APP_A, VERSION_CODE)),
+ PackageWatchdog.FAILURE_REASON_UNKNOWN);
+ }
+ mTestLooper.dispatchAll();
+ assertThat(observer.mMitigatedPackages).isEmpty();
+ watchdog.startObservingHealth(observer, List.of(APP_A), LONG_DURATION);
+ watchdog.onPackageFailure(List.of(new VersionedPackage(APP_A, VERSION_CODE)),
+ PackageWatchdog.FAILURE_REASON_UNKNOWN);
+ mTestLooper.dispatchAll();
+ assertThat(observer.mMitigatedPackages).isEqualTo(List.of(APP_A));
+ }
+
private void adoptShellPermissions(String... permissions) {
InstrumentationRegistry
.getInstrumentation()
diff --git a/wifi/Android.bp b/wifi/Android.bp
index d0f1a26f7dbf..614786193a18 100644
--- a/wifi/Android.bp
+++ b/wifi/Android.bp
@@ -81,7 +81,6 @@ java_library {
libs: [
"framework-annotations-lib",
"unsupportedappusage", // for android.compat.annotation.UnsupportedAppUsage
- "unsupportedappusage-annotation", // for dalvik.annotation.compat.UnsupportedAppUsage
"framework-telephony-stubs",
],
srcs: [