Merge "Add userId to log messages - DO NOT MERGE" into rvc-dev
diff --git a/apex/media/framework/java/android/media/MediaParser.java b/apex/media/framework/java/android/media/MediaParser.java
index 29c48ad..0ff55da 100644
--- a/apex/media/framework/java/android/media/MediaParser.java
+++ b/apex/media/framework/java/android/media/MediaParser.java
@@ -25,6 +25,7 @@
import com.google.android.exoplayer2.C;
import com.google.android.exoplayer2.Format;
+import com.google.android.exoplayer2.ParserException;
import com.google.android.exoplayer2.extractor.DefaultExtractorInput;
import com.google.android.exoplayer2.extractor.Extractor;
import com.google.android.exoplayer2.extractor.ExtractorInput;
@@ -431,63 +432,75 @@
}
}
+ /** Thrown when an error occurs while parsing a media stream. */
+ public static final class ParsingException extends IOException {
+
+ private ParsingException(ParserException cause) {
+ super(cause);
+ }
+ }
+
// Public constants.
/**
- * Sets whether constant bitrate seeking should be enabled for exo.AdtsParser. {@code boolean}
+ * Sets whether constant bitrate seeking should be enabled for ADTS parsing. {@code boolean}
* expected. Default value is {@code false}.
*/
public static final String PARAMETER_ADTS_ENABLE_CBR_SEEKING =
- "exo.AdtsParser.enableCbrSeeking";
+ "android.media.mediaparser.adts.enableCbrSeeking";
/**
- * Sets whether constant bitrate seeking should be enabled for exo.AmrParser. {@code boolean}
+ * Sets whether constant bitrate seeking should be enabled for AMR. {@code boolean} expected.
+ * Default value is {@code false}.
+ */
+ public static final String PARAMETER_AMR_ENABLE_CBR_SEEKING =
+ "android.media.mediaparser.amr.enableCbrSeeking";
+ /**
+ * Sets whether the ID3 track should be disabled for FLAC. {@code boolean} expected. Default
+ * value is {@code false}.
+ */
+ public static final String PARAMETER_FLAC_DISABLE_ID3 =
+ "android.media.mediaparser.flac.disableId3";
+ /**
+ * Sets whether MP4 parsing should ignore edit lists. {@code boolean} expected. Default value is
+ * {@code false}.
+ */
+ public static final String PARAMETER_MP4_IGNORE_EDIT_LISTS =
+ "android.media.mediaparser.mp4.ignoreEditLists";
+ /**
+ * Sets whether MP4 parsing should ignore the tfdt box. {@code boolean} expected. Default value
+ * is {@code false}.
+ */
+ public static final String PARAMETER_MP4_IGNORE_TFDT_BOX =
+ "android.media.mediaparser.mp4.ignoreTfdtBox";
+ /**
+ * Sets whether MP4 parsing should treat all video frames as key frames. {@code boolean}
* expected. Default value is {@code false}.
*/
- public static final String PARAMETER_AMR_ENABLE_CBR_SEEKING = "exo.AmrParser.enableCbrSeeking";
+ public static final String PARAMETER_MP4_TREAT_VIDEO_FRAMES_AS_KEYFRAMES =
+ "android.media.mediaparser.mp4.treatVideoFramesAsKeyframes";
/**
- * Sets whether the ID3 track should be disabled for exo.FlacParser. {@code boolean} expected.
- * Default value is {@code false}.
- */
- public static final String PARAMETER_FLAC_DISABLE_ID3 = "exo.FlacParser.disableId3";
- /**
- * Sets whether exo.FragmentedMp4Parser should ignore edit lists. {@code boolean} expected.
- * Default value is {@code false}.
- */
- public static final String PARAMETER_FMP4_IGNORE_EDIT_LISTS =
- "exo.FragmentedMp4Parser.ignoreEditLists";
- /**
- * Sets whether exo.FragmentedMp4Parser should ignore the tfdt box. {@code boolean} expected.
- * Default value is {@code false}.
- */
- public static final String PARAMETER_FMP4_IGNORE_TFDT_BOX =
- "exo.FragmentedMp4Parser.ignoreTfdtBox";
- /**
- * Sets whether exo.FragmentedMp4Parser should treat all video frames as key frames. {@code
- * boolean} expected. Default value is {@code false}.
- */
- public static final String PARAMETER_FMP4_TREAT_VIDEO_FRAMES_AS_KEYFRAMES =
- "exo.FragmentedMp4Parser.treatVideoFramesAsKeyframes";
- /**
- * Sets whether exo.MatroskaParser should avoid seeking to the cues element. {@code boolean}
+ * Sets whether Matroska parsing should avoid seeking to the cues element. {@code boolean}
* expected. Default value is {@code false}.
*
* <p>If this flag is enabled and the cues element occurs after the first cluster, then the
* media is treated as unseekable.
*/
public static final String PARAMETER_MATROSKA_DISABLE_CUES_SEEKING =
- "exo.MatroskaParser.disableCuesSeeking";
+ "android.media.mediaparser.matroska.disableCuesSeeking";
/**
- * Sets whether the ID3 track should be disabled for exo.Mp3Parser. {@code boolean} expected.
+ * Sets whether the ID3 track should be disabled for MP3. {@code boolean} expected. Default
+ * value is {@code false}.
+ */
+ public static final String PARAMETER_MP3_DISABLE_ID3 =
+ "android.media.mediaparser.mp3.disableId3";
+ /**
+ * Sets whether constant bitrate seeking should be enabled for MP3. {@code boolean} expected.
* Default value is {@code false}.
*/
- public static final String PARAMETER_MP3_DISABLE_ID3 = "exo.Mp3Parser.disableId3";
+ public static final String PARAMETER_MP3_ENABLE_CBR_SEEKING =
+ "android.media.mediaparser.mp3.enableCbrSeeking";
/**
- * Sets whether constant bitrate seeking should be enabled for exo.Mp3Parser. {@code boolean}
- * expected. Default value is {@code false}.
- */
- public static final String PARAMETER_MP3_ENABLE_CBR_SEEKING = "exo.Mp3Parser.enableCbrSeeking";
- /**
- * Sets whether exo.Mp3Parser should generate a time-to-byte mapping. {@code boolean} expected.
+ * Sets whether MP3 parsing should generate a time-to-byte mapping. {@code boolean} expected.
* Default value is {@code false}.
*
* <p>Enabling this flag may require to scan a significant portion of the file to compute a seek
@@ -500,18 +513,13 @@
* </ul>
*/
public static final String PARAMETER_MP3_ENABLE_INDEX_SEEKING =
- "exo.Mp3Parser.enableIndexSeeking";
+ "android.media.mediaparser.mp3.enableIndexSeeking";
/**
- * Sets whether exo.Mp4Parser should ignore edit lists. {@code boolean} expected. Default value
- * is {@code false}.
- */
- public static final String PARAMETER_MP4_IGNORE_EDIT_LISTS = "exo.Mp4Parser.ignoreEditLists";
- /**
- * Sets the operation mode for exo.TsParser. {@code String} expected. Valid values are {@code
+ * Sets the operation mode for TS parsing. {@code String} expected. Valid values are {@code
* "single_pmt"}, {@code "multi_pmt"}, and {@code "hls"}. Default value is {@code "single_pmt"}.
*
- * <p>The operation modes alter the way exo.TsParser behaves so that it can handle certain kinds
- * of commonly-occurring malformed media.
+ * <p>The operation modes alter the way TS behaves so that it can handle certain kinds of
+ * commonly-occurring malformed media.
*
* <ul>
* <li>{@code "single_pmt"}: Only the first found PMT is parsed. Others are ignored, even if
@@ -520,47 +528,48 @@
* <li>{@code "hls"}: Enable {@code "single_pmt"} mode, and ignore continuity counters.
* </ul>
*/
- public static final String PARAMETER_TS_MODE = "exo.TsParser.mode";
+ public static final String PARAMETER_TS_MODE = "android.media.mediaparser.ts.mode";
/**
- * Sets whether exo.TsParser should treat samples consisting of non-IDR I slices as
- * synchronization samples (key-frames). {@code boolean} expected. Default value is {@code
- * false}.
+ * Sets whether TS should treat samples consisting of non-IDR I slices as synchronization
+ * samples (key-frames). {@code boolean} expected. Default value is {@code false}.
*/
public static final String PARAMETER_TS_ALLOW_NON_IDR_AVC_KEYFRAMES =
- "exo.TsParser.allowNonIdrAvcKeyframes";
+ "android.media.mediaparser.ts.allowNonIdrAvcKeyframes";
/**
- * Sets whether exo.TsParser should ignore AAC elementary streams. {@code boolean} expected.
+ * Sets whether TS parsing should ignore AAC elementary streams. {@code boolean} expected.
* Default value is {@code false}.
*/
- public static final String PARAMETER_TS_IGNORE_AAC_STREAM = "exo.TsParser.ignoreAacStream";
+ public static final String PARAMETER_TS_IGNORE_AAC_STREAM =
+ "android.media.mediaparser.ts.ignoreAacStream";
/**
- * Sets whether exo.TsParser should ignore AVC elementary streams. {@code boolean} expected.
+ * Sets whether TS parsing should ignore AVC elementary streams. {@code boolean} expected.
* Default value is {@code false}.
*/
- public static final String PARAMETER_TS_IGNORE_AVC_STREAM = "exo.TsParser.ignoreAvcStream";
+ public static final String PARAMETER_TS_IGNORE_AVC_STREAM =
+ "android.media.mediaparser.ts.ignoreAvcStream";
/**
- * Sets whether exo.TsParser should ignore splice information streams. {@code boolean} expected.
+ * Sets whether TS parsing should ignore splice information streams. {@code boolean} expected.
* Default value is {@code false}.
*/
public static final String PARAMETER_TS_IGNORE_SPLICE_INFO_STREAM =
- "exo.TsParser.ignoreSpliceInfoStream";
+ "android.media.mediaparser.ts.ignoreSpliceInfoStream";
/**
- * Sets whether exo.TsParser should split AVC stream into access units based on slice headers.
+ * Sets whether TS parsing should split AVC stream into access units based on slice headers.
* {@code boolean} expected. Default value is {@code false}.
*
* <p>This flag should be left disabled if the stream contains access units delimiters in order
* to avoid unnecessary computational costs.
*/
public static final String PARAMETER_TS_DETECT_ACCESS_UNITS =
- "exo.TsParser.ignoreDetectAccessUnits";
+ "android.media.mediaparser.ts.ignoreDetectAccessUnits";
/**
- * Sets whether exo.TsParser should handle HDMV DTS audio streams. {@code boolean} expected.
+ * Sets whether TS parsing should handle HDMV DTS audio streams. {@code boolean} expected.
* Default value is {@code false}.
*
* <p>Enabling this flag will disable the detection of SCTE subtitles.
*/
public static final String PARAMETER_TS_ENABLE_HDMV_DTS_AUDIO_STREAMS =
- "exo.TsParser.enableHdmvDtsAudioStreams";
+ "android.media.mediaparser.ts.enableHdmvDtsAudioStreams";
// Private constants.
@@ -768,6 +777,8 @@
int result = 0;
try {
result = mExtractor.read(mExtractorInput, mPositionHolder);
+ } catch (ParserException e) {
+ throw new ParsingException(e);
} catch (InterruptedException e) {
// TODO: Remove this exception replacement once we update the ExoPlayer version.
throw new InterruptedIOException();
@@ -1174,15 +1185,14 @@
expectedTypeByParameterName.put(PARAMETER_ADTS_ENABLE_CBR_SEEKING, Boolean.class);
expectedTypeByParameterName.put(PARAMETER_AMR_ENABLE_CBR_SEEKING, Boolean.class);
expectedTypeByParameterName.put(PARAMETER_FLAC_DISABLE_ID3, Boolean.class);
- expectedTypeByParameterName.put(PARAMETER_FMP4_IGNORE_EDIT_LISTS, Boolean.class);
- expectedTypeByParameterName.put(PARAMETER_FMP4_IGNORE_TFDT_BOX, Boolean.class);
+ expectedTypeByParameterName.put(PARAMETER_MP4_IGNORE_EDIT_LISTS, Boolean.class);
+ expectedTypeByParameterName.put(PARAMETER_MP4_IGNORE_TFDT_BOX, Boolean.class);
expectedTypeByParameterName.put(
- PARAMETER_FMP4_TREAT_VIDEO_FRAMES_AS_KEYFRAMES, Boolean.class);
+ PARAMETER_MP4_TREAT_VIDEO_FRAMES_AS_KEYFRAMES, Boolean.class);
expectedTypeByParameterName.put(PARAMETER_MATROSKA_DISABLE_CUES_SEEKING, Boolean.class);
expectedTypeByParameterName.put(PARAMETER_MP3_DISABLE_ID3, Boolean.class);
expectedTypeByParameterName.put(PARAMETER_MP3_ENABLE_CBR_SEEKING, Boolean.class);
expectedTypeByParameterName.put(PARAMETER_MP3_ENABLE_INDEX_SEEKING, Boolean.class);
- expectedTypeByParameterName.put(PARAMETER_MP4_IGNORE_EDIT_LISTS, Boolean.class);
expectedTypeByParameterName.put(PARAMETER_TS_MODE, String.class);
expectedTypeByParameterName.put(PARAMETER_TS_ALLOW_NON_IDR_AVC_KEYFRAMES, Boolean.class);
expectedTypeByParameterName.put(PARAMETER_TS_IGNORE_AAC_STREAM, Boolean.class);
diff --git a/apex/statsd/framework/Android.bp b/apex/statsd/framework/Android.bp
index 8185bb0..986682e 100644
--- a/apex/statsd/framework/Android.bp
+++ b/apex/statsd/framework/Android.bp
@@ -166,10 +166,8 @@
android_test {
name: "FrameworkStatsdTest",
- platform_apis: true,
+ sdk_version: "module_current",
srcs: [
- // TODO(b/147705194): Use framework-statsd as a lib dependency instead.
- ":framework-statsd-sources",
"test/**/*.java",
],
manifest: "test/AndroidManifest.xml",
@@ -180,6 +178,7 @@
libs: [
"android.test.runner.stubs",
"android.test.base.stubs",
+ "framework-statsd",
],
test_suites: [
"device-tests",
diff --git a/api/current.txt b/api/current.txt
index c0ab513..fb73238 100644
--- a/api/current.txt
+++ b/api/current.txt
@@ -5995,7 +5995,7 @@
method public android.service.notification.StatusBarNotification[] getActiveNotifications();
method public android.app.AutomaticZenRule getAutomaticZenRule(String);
method public java.util.Map<java.lang.String,android.app.AutomaticZenRule> getAutomaticZenRules();
- method @Nullable public android.app.NotificationManager.Policy getConsolidatedNotificationPolicy();
+ method @NonNull public android.app.NotificationManager.Policy getConsolidatedNotificationPolicy();
method public final int getCurrentInterruptionFilter();
method public int getImportance();
method public android.app.NotificationChannel getNotificationChannel(String);
@@ -11721,6 +11721,7 @@
ctor public LauncherApps.ShortcutQuery();
method public android.content.pm.LauncherApps.ShortcutQuery setActivity(@Nullable android.content.ComponentName);
method public android.content.pm.LauncherApps.ShortcutQuery setChangedSince(long);
+ method @NonNull public android.content.pm.LauncherApps.ShortcutQuery setLocusIds(@Nullable java.util.List<android.content.LocusId>);
method public android.content.pm.LauncherApps.ShortcutQuery setPackage(@Nullable String);
method public android.content.pm.LauncherApps.ShortcutQuery setQueryFlags(int);
method public android.content.pm.LauncherApps.ShortcutQuery setShortcutIds(@Nullable java.util.List<java.lang.String>);
@@ -26427,24 +26428,23 @@
method public void seek(@NonNull android.media.MediaParser.SeekPoint);
method @NonNull public android.media.MediaParser setParameter(@NonNull String, @NonNull Object);
method public boolean supportsParameter(@NonNull String);
- field public static final String PARAMETER_ADTS_ENABLE_CBR_SEEKING = "exo.AdtsParser.enableCbrSeeking";
- field public static final String PARAMETER_AMR_ENABLE_CBR_SEEKING = "exo.AmrParser.enableCbrSeeking";
- field public static final String PARAMETER_FLAC_DISABLE_ID3 = "exo.FlacParser.disableId3";
- field public static final String PARAMETER_FMP4_IGNORE_EDIT_LISTS = "exo.FragmentedMp4Parser.ignoreEditLists";
- field public static final String PARAMETER_FMP4_IGNORE_TFDT_BOX = "exo.FragmentedMp4Parser.ignoreTfdtBox";
- field public static final String PARAMETER_FMP4_TREAT_VIDEO_FRAMES_AS_KEYFRAMES = "exo.FragmentedMp4Parser.treatVideoFramesAsKeyframes";
- field public static final String PARAMETER_MATROSKA_DISABLE_CUES_SEEKING = "exo.MatroskaParser.disableCuesSeeking";
- field public static final String PARAMETER_MP3_DISABLE_ID3 = "exo.Mp3Parser.disableId3";
- field public static final String PARAMETER_MP3_ENABLE_CBR_SEEKING = "exo.Mp3Parser.enableCbrSeeking";
- field public static final String PARAMETER_MP3_ENABLE_INDEX_SEEKING = "exo.Mp3Parser.enableIndexSeeking";
- field public static final String PARAMETER_MP4_IGNORE_EDIT_LISTS = "exo.Mp4Parser.ignoreEditLists";
- field public static final String PARAMETER_TS_ALLOW_NON_IDR_AVC_KEYFRAMES = "exo.TsParser.allowNonIdrAvcKeyframes";
- field public static final String PARAMETER_TS_DETECT_ACCESS_UNITS = "exo.TsParser.ignoreDetectAccessUnits";
- field public static final String PARAMETER_TS_ENABLE_HDMV_DTS_AUDIO_STREAMS = "exo.TsParser.enableHdmvDtsAudioStreams";
- field public static final String PARAMETER_TS_IGNORE_AAC_STREAM = "exo.TsParser.ignoreAacStream";
- field public static final String PARAMETER_TS_IGNORE_AVC_STREAM = "exo.TsParser.ignoreAvcStream";
- field public static final String PARAMETER_TS_IGNORE_SPLICE_INFO_STREAM = "exo.TsParser.ignoreSpliceInfoStream";
- field public static final String PARAMETER_TS_MODE = "exo.TsParser.mode";
+ field public static final String PARAMETER_ADTS_ENABLE_CBR_SEEKING = "android.media.mediaparser.adts.enableCbrSeeking";
+ field public static final String PARAMETER_AMR_ENABLE_CBR_SEEKING = "android.media.mediaparser.amr.enableCbrSeeking";
+ field public static final String PARAMETER_FLAC_DISABLE_ID3 = "android.media.mediaparser.flac.disableId3";
+ field public static final String PARAMETER_MATROSKA_DISABLE_CUES_SEEKING = "android.media.mediaparser.matroska.disableCuesSeeking";
+ field public static final String PARAMETER_MP3_DISABLE_ID3 = "android.media.mediaparser.mp3.disableId3";
+ field public static final String PARAMETER_MP3_ENABLE_CBR_SEEKING = "android.media.mediaparser.mp3.enableCbrSeeking";
+ field public static final String PARAMETER_MP3_ENABLE_INDEX_SEEKING = "android.media.mediaparser.mp3.enableIndexSeeking";
+ field public static final String PARAMETER_MP4_IGNORE_EDIT_LISTS = "android.media.mediaparser.mp4.ignoreEditLists";
+ field public static final String PARAMETER_MP4_IGNORE_TFDT_BOX = "android.media.mediaparser.mp4.ignoreTfdtBox";
+ field public static final String PARAMETER_MP4_TREAT_VIDEO_FRAMES_AS_KEYFRAMES = "android.media.mediaparser.mp4.treatVideoFramesAsKeyframes";
+ field public static final String PARAMETER_TS_ALLOW_NON_IDR_AVC_KEYFRAMES = "android.media.mediaparser.ts.allowNonIdrAvcKeyframes";
+ field public static final String PARAMETER_TS_DETECT_ACCESS_UNITS = "android.media.mediaparser.ts.ignoreDetectAccessUnits";
+ field public static final String PARAMETER_TS_ENABLE_HDMV_DTS_AUDIO_STREAMS = "android.media.mediaparser.ts.enableHdmvDtsAudioStreams";
+ field public static final String PARAMETER_TS_IGNORE_AAC_STREAM = "android.media.mediaparser.ts.ignoreAacStream";
+ field public static final String PARAMETER_TS_IGNORE_AVC_STREAM = "android.media.mediaparser.ts.ignoreAvcStream";
+ field public static final String PARAMETER_TS_IGNORE_SPLICE_INFO_STREAM = "android.media.mediaparser.ts.ignoreSpliceInfoStream";
+ field public static final String PARAMETER_TS_MODE = "android.media.mediaparser.ts.mode";
}
public static interface MediaParser.InputReader {
@@ -26461,6 +26461,9 @@
method public void onTrackDataFound(int, @NonNull android.media.MediaParser.TrackData);
}
+ public static final class MediaParser.ParsingException extends java.io.IOException {
+ }
+
public static final class MediaParser.SeekMap {
method public long getDurationMicros();
method @NonNull public android.util.Pair<android.media.MediaParser.SeekPoint,android.media.MediaParser.SeekPoint> getSeekPoints(long);
@@ -32450,7 +32453,7 @@
method public boolean categoryAllowsForegroundPreference(String);
method @Nullable @RequiresPermission(android.Manifest.permission.NFC_PREFERRED_PAYMENT_INFO) public java.util.List<java.lang.String> getAidsForPreferredPaymentService();
method public java.util.List<java.lang.String> getAidsForService(android.content.ComponentName, String);
- method @Nullable @RequiresPermission(android.Manifest.permission.NFC_PREFERRED_PAYMENT_INFO) public String getDescriptionForPreferredPaymentService();
+ method @Nullable @RequiresPermission(android.Manifest.permission.NFC_PREFERRED_PAYMENT_INFO) public CharSequence getDescriptionForPreferredPaymentService();
method public static android.nfc.cardemulation.CardEmulation getInstance(android.nfc.NfcAdapter);
method @Nullable @RequiresPermission(android.Manifest.permission.NFC_PREFERRED_PAYMENT_INFO) public String getRouteDestinationForPreferredPaymentService();
method public int getSelectionModeForCategory(String);
@@ -48210,7 +48213,6 @@
method @Deprecated public String iccTransmitApduBasicChannel(int, int, int, int, int, String);
method @Deprecated public String iccTransmitApduLogicalChannel(int, int, int, int, int, int, String);
method public boolean isConcurrentVoiceAndDataSupported();
- method public boolean isDataCapable();
method @RequiresPermission(anyOf={android.Manifest.permission.ACCESS_NETWORK_STATE, android.Manifest.permission.MODIFY_PHONE_STATE}) public boolean isDataEnabled();
method @RequiresPermission(anyOf={android.Manifest.permission.ACCESS_NETWORK_STATE, android.Manifest.permission.READ_PHONE_STATE}) public boolean isDataRoamingEnabled();
method public boolean isEmergencyNumber(@NonNull String);
diff --git a/api/system-current.txt b/api/system-current.txt
index ab3bcc1..0fb80a2 100755
--- a/api/system-current.txt
+++ b/api/system-current.txt
@@ -148,6 +148,7 @@
field public static final String NETWORK_SETUP_WIZARD = "android.permission.NETWORK_SETUP_WIZARD";
field public static final String NETWORK_SIGNAL_STRENGTH_WAKEUP = "android.permission.NETWORK_SIGNAL_STRENGTH_WAKEUP";
field public static final String NETWORK_STACK = "android.permission.NETWORK_STACK";
+ field public static final String NETWORK_STATS_PROVIDER = "android.permission.NETWORK_STATS_PROVIDER";
field public static final String NOTIFICATION_DURING_SETUP = "android.permission.NOTIFICATION_DURING_SETUP";
field public static final String NOTIFY_TV_INPUTS = "android.permission.NOTIFY_TV_INPUTS";
field public static final String OBSERVE_APP_USAGE = "android.permission.OBSERVE_APP_USAGE";
@@ -205,7 +206,7 @@
field public static final String REVIEW_ACCESSIBILITY_SERVICES = "android.permission.REVIEW_ACCESSIBILITY_SERVICES";
field public static final String REVOKE_RUNTIME_PERMISSIONS = "android.permission.REVOKE_RUNTIME_PERMISSIONS";
field public static final String SCORE_NETWORKS = "android.permission.SCORE_NETWORKS";
- field public static final String SECURE_ELEMENT_PRIVILEGED = "android.permission.SECURE_ELEMENT_PRIVILEGED";
+ field public static final String SECURE_ELEMENT_PRIVILEGED_OPERATION = "android.permission.SECURE_ELEMENT_PRIVILEGED_OPERATION";
field public static final String SEND_DEVICE_CUSTOMIZATION_READY = "android.permission.SEND_DEVICE_CUSTOMIZATION_READY";
field public static final String SEND_SHOW_SUSPENDED_APP_DETAILS = "android.permission.SEND_SHOW_SUSPENDED_APP_DETAILS";
field public static final String SEND_SMS_NO_CONFIRMATION = "android.permission.SEND_SMS_NO_CONFIRMATION";
@@ -350,7 +351,6 @@
method @RequiresPermission(android.Manifest.permission.RESTRICTED_VR_ACCESS) public static void setPersistentVrThread(int);
method @RequiresPermission(android.Manifest.permission.MANAGE_USERS) public boolean switchUser(@NonNull android.os.UserHandle);
method public void unregisterHomeVisibilityObserver(@NonNull android.app.HomeVisibilityObserver);
- method @RequiresPermission(android.Manifest.permission.CHANGE_CONFIGURATION) public boolean updateMccMncConfiguration(@NonNull String, @NonNull String);
}
public static interface ActivityManager.OnUidImportanceListener {
@@ -1410,7 +1410,8 @@
}
public class NetworkStatsManager {
- method @NonNull @RequiresPermission(android.Manifest.permission.UPDATE_DEVICE_STATS) public android.net.netstats.provider.NetworkStatsProviderCallback registerNetworkStatsProvider(@NonNull String, @NonNull android.net.netstats.provider.AbstractNetworkStatsProvider);
+ method @NonNull @RequiresPermission(anyOf={android.Manifest.permission.NETWORK_STATS_PROVIDER, android.net.NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK}) public void registerNetworkStatsProvider(@NonNull String, @NonNull android.net.netstats.provider.NetworkStatsProvider);
+ method @NonNull @RequiresPermission(anyOf={android.Manifest.permission.NETWORK_STATS_PROVIDER, android.net.NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK}) public void unregisterNetworkStatsProvider(@NonNull android.net.netstats.provider.NetworkStatsProvider);
}
public static final class UsageEvents.Event {
@@ -2102,10 +2103,6 @@
field @NonNull public static final android.os.Parcelable.Creator<android.content.pm.LauncherApps.AppUsageLimit> CREATOR;
}
- public static class LauncherApps.ShortcutQuery {
- method @NonNull public android.content.pm.LauncherApps.ShortcutQuery setLocusIds(@Nullable java.util.List<android.content.LocusId>);
- }
-
public class PackageInstaller {
method @RequiresPermission(android.Manifest.permission.INSTALL_PACKAGES) public void setPermissionsResult(int, boolean);
field public static final int DATA_LOADER_TYPE_INCREMENTAL = 2; // 0x2
@@ -4889,16 +4886,10 @@
method @RequiresPermission(android.Manifest.permission.ACCESS_TV_TUNER) public void shareFrontendFromTuner(@NonNull android.media.tv.tuner.Tuner);
method @RequiresPermission(android.Manifest.permission.ACCESS_TV_TUNER) public int tune(@NonNull android.media.tv.tuner.frontend.FrontendSettings);
method @RequiresPermission(android.Manifest.permission.ACCESS_TV_TUNER) public void updateResourcePriority(int, int);
- }
-
- public static interface Tuner.OnResourceLostListener {
- method public void onResourceLost(@NonNull android.media.tv.tuner.Tuner);
- }
-
- public final class TunerConstants {
field public static final int INVALID_AV_SYNC_ID = -1; // 0xffffffff
field public static final int INVALID_FILTER_ID = -1; // 0xffffffff
field public static final int INVALID_STREAM_ID = 65535; // 0xffff
+ field public static final long INVALID_TIMESTAMP = -1L; // 0xffffffffffffffffL
field public static final int INVALID_TS_PID = 65535; // 0xffff
field public static final int RESULT_INVALID_ARGUMENT = 4; // 0x4
field public static final int RESULT_INVALID_STATE = 3; // 0x3
@@ -4912,6 +4903,10 @@
field public static final int SCAN_TYPE_UNDEFINED = 0; // 0x0
}
+ public static interface Tuner.OnResourceLostListener {
+ method public void onResourceLost(@NonNull android.media.tv.tuner.Tuner);
+ }
+
}
package android.media.tv.tuner.dvr {
@@ -5272,7 +5267,6 @@
method public long getSourceTime();
method public long getTimeStamp();
method public int setCurrentTimestamp(long);
- field public static final long TIMESTAMP_UNAVAILABLE = -1L; // 0xffffffffffffffffL
}
public final class TlvFilterConfiguration extends android.media.tv.tuner.filter.FilterConfiguration {
@@ -6414,14 +6408,13 @@
public final class NetworkStats implements android.os.Parcelable {
ctor public NetworkStats(long, int);
method @NonNull public android.net.NetworkStats add(@NonNull android.net.NetworkStats);
- method @NonNull public android.net.NetworkStats addValues(@NonNull android.net.NetworkStats.Entry);
+ method @NonNull public android.net.NetworkStats addEntry(@NonNull android.net.NetworkStats.Entry);
method public int describeContents();
method @NonNull public android.net.NetworkStats subtract(@NonNull android.net.NetworkStats);
method public void writeToParcel(@NonNull android.os.Parcel, int);
field @NonNull public static final android.os.Parcelable.Creator<android.net.NetworkStats> CREATOR;
field public static final int DEFAULT_NETWORK_NO = 0; // 0x0
field public static final int DEFAULT_NETWORK_YES = 1; // 0x1
- field @Nullable public static final String IFACE_ALL;
field public static final String IFACE_VT = "vt_data0";
field public static final int METERED_NO = 0; // 0x0
field public static final int METERED_YES = 1; // 0x1
@@ -6821,21 +6814,17 @@
package android.net.netstats.provider {
- public abstract class AbstractNetworkStatsProvider {
- ctor public AbstractNetworkStatsProvider();
- method public abstract void requestStatsUpdate(int);
- method public abstract void setAlert(long);
- method public abstract void setLimit(@NonNull String, long);
+ public abstract class NetworkStatsProvider {
+ ctor public NetworkStatsProvider();
+ method public void notifyAlertReached();
+ method public void notifyLimitReached();
+ method public void notifyStatsUpdated(int, @NonNull android.net.NetworkStats, @NonNull android.net.NetworkStats);
+ method public abstract void onRequestStatsUpdate(int);
+ method public abstract void onSetAlert(long);
+ method public abstract void onSetLimit(@NonNull String, long);
field public static final int QUOTA_UNLIMITED = -1; // 0xffffffff
}
- public class NetworkStatsProviderCallback {
- method public void onAlertReached();
- method public void onLimitReached();
- method public void onStatsUpdated(int, @NonNull android.net.NetworkStats, @NonNull android.net.NetworkStats);
- method public void unregister();
- }
-
}
package android.net.sip {
@@ -7459,7 +7448,15 @@
}
public final class WifiMigration {
+ method @Nullable public static java.io.InputStream convertAndRetrieveSharedConfigStoreFile(int);
+ method @Nullable public static java.io.InputStream convertAndRetrieveUserConfigStoreFile(int, @NonNull android.os.UserHandle);
method @NonNull public static android.net.wifi.WifiMigration.SettingsMigrationData loadFromSettings(@NonNull android.content.Context);
+ method public static void removeSharedConfigStoreFile(int);
+ method public static void removeUserConfigStoreFile(int, @NonNull android.os.UserHandle);
+ field public static final int STORE_FILE_SHARED_GENERAL = 0; // 0x0
+ field public static final int STORE_FILE_SHARED_SOFTAP = 1; // 0x1
+ field public static final int STORE_FILE_USER_GENERAL = 2; // 0x2
+ field public static final int STORE_FILE_USER_NETWORK_SUGGESTIONS = 3; // 0x3
}
public static final class WifiMigration.SettingsMigrationData implements android.os.Parcelable {
@@ -9352,32 +9349,6 @@
method @RequiresPermission(android.Manifest.permission.MODIFY_SETTINGS_OVERRIDEABLE_BY_RESTORE) public static boolean putString(@NonNull android.content.ContentResolver, @NonNull String, @Nullable String, boolean);
}
- public static interface Telephony.CarrierColumns extends android.provider.BaseColumns {
- field @NonNull public static final android.net.Uri CONTENT_URI;
- field public static final String EXPIRATION_TIME = "expiration_time";
- field public static final String KEY_IDENTIFIER = "key_identifier";
- field public static final String KEY_TYPE = "key_type";
- field public static final String LAST_MODIFIED = "last_modified";
- field public static final String MCC = "mcc";
- field public static final String MNC = "mnc";
- field public static final String MVNO_MATCH_DATA = "mvno_match_data";
- field public static final String MVNO_TYPE = "mvno_type";
- field public static final String PUBLIC_KEY = "public_key";
- }
-
- public static final class Telephony.CarrierId.All implements android.provider.BaseColumns {
- field public static final String APN = "apn";
- field @NonNull public static final android.net.Uri CONTENT_URI;
- field public static final String GID1 = "gid1";
- field public static final String GID2 = "gid2";
- field public static final String ICCID_PREFIX = "iccid_prefix";
- field public static final String IMSI_PREFIX_XPATTERN = "imsi_prefix_xpattern";
- field public static final String MCCMNC = "mccmnc";
- field public static final String PLMN = "plmn";
- field public static final String PRIVILEGE_ACCESS_RULE = "privilege_access_rule";
- field public static final String SPN = "spn";
- }
-
public static final class Telephony.Carriers implements android.provider.BaseColumns {
field public static final String APN_SET_ID = "apn_set_id";
field public static final int CARRIER_EDITED = 4; // 0x4
@@ -9541,7 +9512,7 @@
package android.se.omapi {
public final class Reader {
- method @RequiresPermission(android.Manifest.permission.SECURE_ELEMENT_PRIVILEGED) public boolean reset();
+ method @RequiresPermission(android.Manifest.permission.SECURE_ELEMENT_PRIVILEGED_OPERATION) public boolean reset();
}
}
@@ -10718,27 +10689,6 @@
field @NonNull public static final android.os.Parcelable.Creator<android.telephony.CallAttributes> CREATOR;
}
- public final class CallForwardingInfo implements android.os.Parcelable {
- ctor public CallForwardingInfo(int, int, @Nullable String, int);
- method public int describeContents();
- method @Nullable public String getNumber();
- method public int getReason();
- method public int getStatus();
- method public int getTimeoutSeconds();
- field @NonNull public static final android.os.Parcelable.Creator<android.telephony.CallForwardingInfo> CREATOR;
- field public static final int REASON_ALL = 4; // 0x4
- field public static final int REASON_ALL_CONDITIONAL = 5; // 0x5
- field public static final int REASON_BUSY = 1; // 0x1
- field public static final int REASON_NOT_REACHABLE = 3; // 0x3
- field public static final int REASON_NO_REPLY = 2; // 0x2
- field public static final int REASON_UNCONDITIONAL = 0; // 0x0
- field public static final int STATUS_ACTIVE = 1; // 0x1
- field public static final int STATUS_FDN_CHECK_FAILURE = 2; // 0x2
- field public static final int STATUS_INACTIVE = 0; // 0x0
- field public static final int STATUS_NOT_SUPPORTED = 4; // 0x4
- field public static final int STATUS_UNKNOWN_ERROR = 3; // 0x3
- }
-
public final class CallQuality implements android.os.Parcelable {
ctor public CallQuality(int, int, int, int, int, int, int, int, int, int, int);
ctor public CallQuality(int, int, int, int, int, int, int, int, int, int, int, boolean, boolean, boolean);
@@ -11119,7 +11069,6 @@
method public void onRadioPowerStateChanged(int);
method public void onSrvccStateChanged(int);
method public void onVoiceActivationStateChanged(int);
- field @RequiresPermission(android.Manifest.permission.LISTEN_ALWAYS_REPORTED_SIGNAL_STRENGTH) public static final int LISTEN_ALWAYS_REPORTED_SIGNAL_STRENGTH = 512; // 0x200
field @RequiresPermission("android.permission.READ_PRECISE_PHONE_STATE") public static final int LISTEN_CALL_ATTRIBUTES_CHANGED = 67108864; // 0x4000000
field @RequiresPermission(android.Manifest.permission.READ_ACTIVE_EMERGENCY_SESSION) public static final int LISTEN_OUTGOING_EMERGENCY_CALL = 268435456; // 0x10000000
field @RequiresPermission(android.Manifest.permission.READ_ACTIVE_EMERGENCY_SESSION) public static final int LISTEN_OUTGOING_EMERGENCY_SMS = 536870912; // 0x20000000
@@ -11150,7 +11099,6 @@
}
public final class PreciseDataConnectionState implements android.os.Parcelable {
- ctor public PreciseDataConnectionState(int, int, int, @NonNull String, @Nullable android.net.LinkProperties, int, @Nullable android.telephony.data.ApnSetting);
method @Deprecated @NonNull public String getDataConnectionApn();
method @Deprecated public int getDataConnectionApnTypeBitMask();
method @Deprecated public int getDataConnectionFailCause();
@@ -11502,8 +11450,6 @@
method @Deprecated @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public java.util.List<android.service.carrier.CarrierIdentifier> getAllowedCarriers(int);
method @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public long getAllowedNetworkTypes();
method @Nullable @RequiresPermission(android.Manifest.permission.INTERACT_ACROSS_USERS) public android.content.ComponentName getAndUpdateDefaultRespondViaMessageApplication();
- method @NonNull @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public android.telephony.CallForwardingInfo getCallForwarding(int);
- method @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public int getCallWaitingStatus();
method @Nullable @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public android.telephony.ImsiEncryptionInfo getCarrierInfoForImsiEncryption(int);
method public java.util.List<java.lang.String> getCarrierPackageNamesForIntent(android.content.Intent);
method public java.util.List<java.lang.String> getCarrierPackageNamesForIntentAndPhone(android.content.Intent, int);
@@ -11584,8 +11530,6 @@
method @Deprecated @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public int setAllowedCarriers(int, java.util.List<android.service.carrier.CarrierIdentifier>);
method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public boolean setAllowedNetworkTypes(long);
method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public boolean setAlwaysAllowMmsData(boolean);
- method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public boolean setCallForwarding(@NonNull android.telephony.CallForwardingInfo);
- method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public boolean setCallWaitingStatus(boolean);
method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public void setCarrierDataEnabled(boolean);
method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public int setCarrierRestrictionRules(@NonNull android.telephony.CarrierRestrictionRules);
method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public void setDataActivationState(int);
@@ -11629,10 +11573,6 @@
field public static final String ACTION_SIM_APPLICATION_STATE_CHANGED = "android.telephony.action.SIM_APPLICATION_STATE_CHANGED";
field public static final String ACTION_SIM_CARD_STATE_CHANGED = "android.telephony.action.SIM_CARD_STATE_CHANGED";
field public static final String ACTION_SIM_SLOT_STATUS_CHANGED = "android.telephony.action.SIM_SLOT_STATUS_CHANGED";
- field public static final int CALL_WAITING_STATUS_ACTIVE = 1; // 0x1
- field public static final int CALL_WAITING_STATUS_INACTIVE = 2; // 0x2
- field public static final int CALL_WAITING_STATUS_NOT_SUPPORTED = 4; // 0x4
- field public static final int CALL_WAITING_STATUS_UNKNOWN_ERROR = 3; // 0x3
field public static final int CARD_POWER_DOWN = 0; // 0x0
field public static final int CARD_POWER_UP = 1; // 0x1
field public static final int CARD_POWER_UP_PASS_THROUGH = 2; // 0x2
diff --git a/api/test-current.txt b/api/test-current.txt
index a1a652f..5bd1f89 100644
--- a/api/test-current.txt
+++ b/api/test-current.txt
@@ -83,7 +83,6 @@
method public static void resumeAppSwitches() throws android.os.RemoteException;
method @RequiresPermission(android.Manifest.permission.CHANGE_CONFIGURATION) public void scheduleApplicationInfoChanged(java.util.List<java.lang.String>, int);
method @RequiresPermission("android.permission.MANAGE_USERS") public boolean switchUser(@NonNull android.os.UserHandle);
- method @RequiresPermission(android.Manifest.permission.CHANGE_CONFIGURATION) public boolean updateMccMncConfiguration(@NonNull String, @NonNull String);
field public static final int PROCESS_CAPABILITY_ALL = 7; // 0x7
field public static final int PROCESS_CAPABILITY_ALL_EXPLICIT = 1; // 0x1
field public static final int PROCESS_CAPABILITY_ALL_IMPLICIT = 6; // 0x6
diff --git a/cmds/statsd/src/atoms.proto b/cmds/statsd/src/atoms.proto
index 713e923..1cbe150 100644
--- a/cmds/statsd/src/atoms.proto
+++ b/cmds/statsd/src/atoms.proto
@@ -398,6 +398,8 @@
256 [(module) = "framework"];
DisplayJankReported display_jank_reported = 257;
AppStandbyBucketChanged app_standby_bucket_changed = 258 [(module) = "framework"];
+ SharesheetStarted sharesheet_started = 259 [(module) = "framework"];
+ RankingSelected ranking_selected = 260 [(module) = "framework"];
SdkExtensionStatus sdk_extension_status = 354;
}
@@ -8914,3 +8916,64 @@
// UsageStatsManager.java.
optional int32 sub_reason = 5;
}
+
+/**
+* Reports a started sharesheet transaction.
+*
+* Logged from:
+* frameworks/base/core/java/com/android/internal/app/ChooserActivity.java
+*/
+message SharesheetStarted {
+ // The event_id (as for UiEventReported).
+ optional int32 event_id = 1;
+ // The calling app's package name.
+ optional string package_name = 2;
+ // An identifier to tie together multiple logs relating to the same share event
+ optional int32 instance_id = 3;
+ // The mime type of the share
+ optional string mime_type = 4;
+ // The number of direct targets the calling app is providing that will be shown.
+ optional int32 num_app_provided_direct_targets = 5;
+ // The number of app targets the calling app is providing that will be shown.
+ optional int32 num_app_provided_app_targets = 6;
+ // True if the share originates from the workprofile
+ optional bool is_workprofile = 7;
+
+ enum SharesheetPreviewType { // Constants from ChooserActivity.java
+ CONTENT_PREVIEW_IMAGE = 1; // The preview shown in the sharesheet is an image.
+ CONTENT_PREVIEW_FILE = 2; // The preview shown in the sharesheet is a file.
+ CONTENT_PREVIEW_TEXT = 3; // The preview shown in the sharesheet is text.
+ }
+ // How the sharesheet preview is presented.
+ optional SharesheetPreviewType previewType = 8;
+
+ enum ResolverActivityIntent { // Intents handled by ResolverActivity.java
+ INTENT_DEFAULT = 0;
+ INTENT_ACTION_VIEW = 1;
+ INTENT_ACTION_EDIT = 2;
+ INTENT_ACTION_SEND = 3;
+ INTENT_ACTION_SENDTO = 4;
+ INTENT_ACTION_SEND_MULTIPLE = 5;
+ INTENT_ACTION_IMAGE_CAPTURE = 6;
+ INTENT_ACTION_MAIN = 7;
+ }
+ // The intent being processed (only SEND and SEND_MULTIPLE are system sharesheet)
+ optional ResolverActivityIntent intentType = 9;
+}
+
+/**
+ * Reports a ranking selection event.
+ *
+ * Logged from:
+ * frameworks/base/core/java/com/android/internal/app/ChooserActivity.java (sharesheet)
+ */
+message RankingSelected {
+ // The event_id (as for UiEventReported).
+ optional int32 event_id = 1;
+ // The relevant app's package name (can be source or picked package).
+ optional string package_name = 2;
+ // An identifier to tie together multiple logs relating to the same share event.
+ optional int32 instance_id = 3;
+ // Which of the ranked targets got picked, default starting position 0.
+ optional int32 position_picked = 4;
+}
diff --git a/cmds/statsd/tests/metrics/ValueMetricProducer_test.cpp b/cmds/statsd/tests/metrics/ValueMetricProducer_test.cpp
index e48f378..7b0467c 100644
--- a/cmds/statsd/tests/metrics/ValueMetricProducer_test.cpp
+++ b/cmds/statsd/tests/metrics/ValueMetricProducer_test.cpp
@@ -79,420 +79,363 @@
}
}
-// TODO(b/149590301): Update these tests to use new socket schema.
-//class ValueMetricProducerTestHelper {
-//
-// public:
-// static shared_ptr<LogEvent> createEvent(int64_t eventTimeNs, int64_t value) {
-// shared_ptr<LogEvent> event = make_shared<LogEvent>(tagId, eventTimeNs);
-// event->write(tagId);
-// event->write(value);
-// event->write(value);
-// event->init();
-// return event;
-// }
-//
-// static sp<ValueMetricProducer> createValueProducerNoConditions(
-// sp<MockStatsPullerManager>& pullerManager, ValueMetric& metric) {
-// UidMap uidMap;
-// SimpleAtomMatcher atomMatcher;
-// atomMatcher.set_atom_id(tagId);
-// sp<EventMatcherWizard> eventMatcherWizard =
-// new EventMatcherWizard({new SimpleLogMatchingTracker(
-// atomMatcherId, logEventMatcherIndex, atomMatcher, uidMap)});
-// sp<MockConditionWizard> wizard = new NaggyMock<MockConditionWizard>();
-// EXPECT_CALL(*pullerManager, RegisterReceiver(tagId, _, _, _)).WillOnce(Return());
-// EXPECT_CALL(*pullerManager, UnRegisterReceiver(tagId, _)).WillRepeatedly(Return());
-//
-// sp<ValueMetricProducer> valueProducer = new ValueMetricProducer(
-// kConfigKey, metric, -1 /*-1 meaning no condition*/, wizard,
-// logEventMatcherIndex, eventMatcherWizard, tagId,
-// bucketStartTimeNs, bucketStartTimeNs, pullerManager);
-// return valueProducer;
-// }
-//
-// static sp<ValueMetricProducer> createValueProducerWithCondition(
-// sp<MockStatsPullerManager>& pullerManager, ValueMetric& metric) {
-// UidMap uidMap;
-// SimpleAtomMatcher atomMatcher;
-// atomMatcher.set_atom_id(tagId);
-// sp<EventMatcherWizard> eventMatcherWizard =
-// new EventMatcherWizard({new SimpleLogMatchingTracker(
-// atomMatcherId, logEventMatcherIndex, atomMatcher, uidMap)});
-// sp<MockConditionWizard> wizard = new NaggyMock<MockConditionWizard>();
-// EXPECT_CALL(*pullerManager, RegisterReceiver(tagId, _, _, _)).WillOnce(Return());
-// EXPECT_CALL(*pullerManager, UnRegisterReceiver(tagId, _)).WillRepeatedly(Return());
-//
-// sp<ValueMetricProducer> valueProducer =
-// new ValueMetricProducer(kConfigKey, metric, 1, wizard, logEventMatcherIndex,
-// eventMatcherWizard, tagId, bucketStartTimeNs,
-// bucketStartTimeNs, pullerManager);
-// valueProducer->mCondition = ConditionState::kFalse;
-// return valueProducer;
-// }
-//
-// static sp<ValueMetricProducer> createValueProducerWithNoInitialCondition(
-// sp<MockStatsPullerManager>& pullerManager, ValueMetric& metric) {
-// UidMap uidMap;
-// SimpleAtomMatcher atomMatcher;
-// atomMatcher.set_atom_id(tagId);
-// sp<EventMatcherWizard> eventMatcherWizard =
-// new EventMatcherWizard({new SimpleLogMatchingTracker(
-// atomMatcherId, logEventMatcherIndex, atomMatcher, uidMap)});
-// sp<MockConditionWizard> wizard = new NaggyMock<MockConditionWizard>();
-// EXPECT_CALL(*pullerManager, RegisterReceiver(tagId, _, _, _)).WillOnce(Return());
-// EXPECT_CALL(*pullerManager, UnRegisterReceiver(tagId, _)).WillRepeatedly(Return());
-//
-// sp<ValueMetricProducer> valueProducer = new ValueMetricProducer(
-// kConfigKey, metric, 1, wizard, logEventMatcherIndex, eventMatcherWizard, tagId,
-// bucketStartTimeNs, bucketStartTimeNs, pullerManager);
-// return valueProducer;
-// }
-//
-// static sp<ValueMetricProducer> createValueProducerWithState(
-// sp<MockStatsPullerManager>& pullerManager, ValueMetric& metric,
-// vector<int32_t> slicedStateAtoms,
-// unordered_map<int, unordered_map<int, int64_t>> stateGroupMap) {
-// UidMap uidMap;
-// SimpleAtomMatcher atomMatcher;
-// atomMatcher.set_atom_id(tagId);
-// sp<EventMatcherWizard> eventMatcherWizard =
-// new EventMatcherWizard({new SimpleLogMatchingTracker(
-// atomMatcherId, logEventMatcherIndex, atomMatcher, uidMap)});
-// sp<MockConditionWizard> wizard = new NaggyMock<MockConditionWizard>();
-// EXPECT_CALL(*pullerManager, RegisterReceiver(tagId, _, _, _)).WillOnce(Return());
-// EXPECT_CALL(*pullerManager, UnRegisterReceiver(tagId, _)).WillRepeatedly(Return());
-// sp<ValueMetricProducer> valueProducer = new ValueMetricProducer(
-// kConfigKey, metric, -1 /* no condition */, wizard, logEventMatcherIndex,
-// eventMatcherWizard, tagId, bucketStartTimeNs, bucketStartTimeNs, pullerManager, {},
-// {}, slicedStateAtoms, stateGroupMap);
-// return valueProducer;
-// }
-//
-// static ValueMetric createMetric() {
-// ValueMetric metric;
-// metric.set_id(metricId);
-// metric.set_bucket(ONE_MINUTE);
-// metric.mutable_value_field()->set_field(tagId);
-// metric.mutable_value_field()->add_child()->set_field(2);
-// metric.set_max_pull_delay_sec(INT_MAX);
-// return metric;
-// }
-//
-// static ValueMetric createMetricWithCondition() {
-// ValueMetric metric = ValueMetricProducerTestHelper::createMetric();
-// metric.set_condition(StringToId("SCREEN_ON"));
-// return metric;
-// }
-//
-// static ValueMetric createMetricWithState(string state) {
-// ValueMetric metric = ValueMetricProducerTestHelper::createMetric();
-// metric.add_slice_by_state(StringToId(state));
-// return metric;
-// }
-//};
-//
-///*
-// * Tests that the first bucket works correctly
-// */
-//TEST(ValueMetricProducerTest, TestCalcPreviousBucketEndTime) {
-// ValueMetric metric = ValueMetricProducerTestHelper::createMetric();
-//
-// int64_t startTimeBase = 11;
-// UidMap uidMap;
-// SimpleAtomMatcher atomMatcher;
-// atomMatcher.set_atom_id(tagId);
-// sp<EventMatcherWizard> eventMatcherWizard =
-// new EventMatcherWizard({new SimpleLogMatchingTracker(
-// atomMatcherId, logEventMatcherIndex, atomMatcher, uidMap)});
-// sp<MockConditionWizard> wizard = new NaggyMock<MockConditionWizard>();
-// sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>();
-//
-// // statsd started long ago.
-// // The metric starts in the middle of the bucket
-// ValueMetricProducer valueProducer(kConfigKey, metric, -1 /*-1 meaning no condition*/, wizard,
-// logEventMatcherIndex, eventMatcherWizard, -1, startTimeBase,
-// 22, pullerManager);
-//
-// EXPECT_EQ(startTimeBase, valueProducer.calcPreviousBucketEndTime(60 * NS_PER_SEC + 10));
-// EXPECT_EQ(startTimeBase, valueProducer.calcPreviousBucketEndTime(60 * NS_PER_SEC + 10));
-// EXPECT_EQ(60 * NS_PER_SEC + startTimeBase,
-// valueProducer.calcPreviousBucketEndTime(2 * 60 * NS_PER_SEC));
-// EXPECT_EQ(2 * 60 * NS_PER_SEC + startTimeBase,
-// valueProducer.calcPreviousBucketEndTime(3 * 60 * NS_PER_SEC));
-//}
-//
-///*
-// * Tests that the first bucket works correctly
-// */
-//TEST(ValueMetricProducerTest, TestFirstBucket) {
-// ValueMetric metric = ValueMetricProducerTestHelper::createMetric();
-//
-// UidMap uidMap;
-// SimpleAtomMatcher atomMatcher;
-// atomMatcher.set_atom_id(tagId);
-// sp<EventMatcherWizard> eventMatcherWizard =
-// new EventMatcherWizard({new SimpleLogMatchingTracker(
-// atomMatcherId, logEventMatcherIndex, atomMatcher, uidMap)});
-// sp<MockConditionWizard> wizard = new NaggyMock<MockConditionWizard>();
-// sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>();
-//
-// // statsd started long ago.
-// // The metric starts in the middle of the bucket
-// ValueMetricProducer valueProducer(kConfigKey, metric, -1 /*-1 meaning no condition*/, wizard,
-// logEventMatcherIndex, eventMatcherWizard, -1, 5,
-// 600 * NS_PER_SEC + NS_PER_SEC / 2, pullerManager);
-//
-// EXPECT_EQ(600500000000, valueProducer.mCurrentBucketStartTimeNs);
-// EXPECT_EQ(10, valueProducer.mCurrentBucketNum);
-// EXPECT_EQ(660000000005, valueProducer.getCurrentBucketEndTimeNs());
-//}
-//
-///*
-// * Tests pulled atoms with no conditions
-// */
-//TEST(ValueMetricProducerTest, TestPulledEventsNoCondition) {
-// ValueMetric metric = ValueMetricProducerTestHelper::createMetric();
-// sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>();
-// EXPECT_CALL(*pullerManager, Pull(tagId, _))
-// .WillOnce(Invoke([](int tagId, vector<std::shared_ptr<LogEvent>>* data) {
-// data->clear();
-// shared_ptr<LogEvent> event = make_shared<LogEvent>(tagId, bucketStartTimeNs);
-// event->write(tagId);
-// event->write(3);
-// event->init();
-// data->push_back(event);
-// return true;
-// }));
-//
-// sp<ValueMetricProducer> valueProducer =
-// ValueMetricProducerTestHelper::createValueProducerNoConditions(pullerManager, metric);
-//
-// vector<shared_ptr<LogEvent>> allData;
-// allData.clear();
-// shared_ptr<LogEvent> event = make_shared<LogEvent>(tagId, bucket2StartTimeNs + 1);
-// event->write(tagId);
-// event->write(11);
-// event->init();
-// allData.push_back(event);
-//
-// valueProducer->onDataPulled(allData, /** succeed */ true, bucket2StartTimeNs);
-// // has one slice
-// EXPECT_EQ(1UL, valueProducer->mCurrentSlicedBucket.size());
-// ValueMetricProducer::Interval curInterval =
-// valueProducer->mCurrentSlicedBucket.begin()->second[0];
-// ValueMetricProducer::BaseInfo curBaseInfo = valueProducer->mCurrentBaseInfo.begin()->second[0];
-//
-// EXPECT_EQ(true, curBaseInfo.hasBase);
-// EXPECT_EQ(11, curBaseInfo.base.long_value);
-// EXPECT_EQ(false, curInterval.hasValue);
-// EXPECT_EQ(8, curInterval.value.long_value);
-// EXPECT_EQ(1UL, valueProducer->mPastBuckets.size());
-// EXPECT_EQ(8, valueProducer->mPastBuckets.begin()->second[0].values[0].long_value);
-// EXPECT_EQ(bucketSizeNs, valueProducer->mPastBuckets.begin()->second[0].mConditionTrueNs);
-//
-// allData.clear();
-// event = make_shared<LogEvent>(tagId, bucket3StartTimeNs + 1);
-// event->write(tagId);
-// event->write(23);
-// event->init();
-// allData.push_back(event);
-// valueProducer->onDataPulled(allData, /** succeed */ true, bucket3StartTimeNs);
-// // has one slice
-// EXPECT_EQ(1UL, valueProducer->mCurrentSlicedBucket.size());
-// curInterval = valueProducer->mCurrentSlicedBucket.begin()->second[0];
-// curBaseInfo = valueProducer->mCurrentBaseInfo.begin()->second[0];
-//
-// EXPECT_EQ(true, curBaseInfo.hasBase);
-// EXPECT_EQ(23, curBaseInfo.base.long_value);
-// EXPECT_EQ(false, curInterval.hasValue);
-// EXPECT_EQ(12, curInterval.value.long_value);
-// EXPECT_EQ(1UL, valueProducer->mPastBuckets.size());
-// EXPECT_EQ(2UL, valueProducer->mPastBuckets.begin()->second.size());
-// EXPECT_EQ(8, valueProducer->mPastBuckets.begin()->second[0].values[0].long_value);
-// EXPECT_EQ(bucketSizeNs, valueProducer->mPastBuckets.begin()->second[0].mConditionTrueNs);
-// EXPECT_EQ(12, valueProducer->mPastBuckets.begin()->second.back().values[0].long_value);
-// EXPECT_EQ(bucketSizeNs, valueProducer->mPastBuckets.begin()->second.back().mConditionTrueNs);
-//
-// allData.clear();
-// event = make_shared<LogEvent>(tagId, bucket4StartTimeNs + 1);
-// event->write(tagId);
-// event->write(36);
-// event->init();
-// allData.push_back(event);
-// valueProducer->onDataPulled(allData, /** succeed */ true, bucket4StartTimeNs);
-// EXPECT_EQ(1UL, valueProducer->mCurrentSlicedBucket.size());
-// curInterval = valueProducer->mCurrentSlicedBucket.begin()->second[0];
-// curBaseInfo = valueProducer->mCurrentBaseInfo.begin()->second[0];
-//
-// EXPECT_EQ(true, curBaseInfo.hasBase);
-// EXPECT_EQ(36, curBaseInfo.base.long_value);
-// EXPECT_EQ(false, curInterval.hasValue);
-// EXPECT_EQ(13, curInterval.value.long_value);
-// EXPECT_EQ(1UL, valueProducer->mPastBuckets.size());
-// EXPECT_EQ(3UL, valueProducer->mPastBuckets.begin()->second.size());
-// EXPECT_EQ(8, valueProducer->mPastBuckets.begin()->second[0].values[0].long_value);
-// EXPECT_EQ(bucketSizeNs, valueProducer->mPastBuckets.begin()->second[0].mConditionTrueNs);
-// EXPECT_EQ(12, valueProducer->mPastBuckets.begin()->second[1].values[0].long_value);
-// EXPECT_EQ(bucketSizeNs, valueProducer->mPastBuckets.begin()->second[1].mConditionTrueNs);
-// EXPECT_EQ(13, valueProducer->mPastBuckets.begin()->second[2].values[0].long_value);
-// EXPECT_EQ(bucketSizeNs, valueProducer->mPastBuckets.begin()->second[2].mConditionTrueNs);
-//}
-//
-//TEST(ValueMetricProducerTest, TestPartialBucketCreated) {
-// ValueMetric metric = ValueMetricProducerTestHelper::createMetric();
-// sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>();
-// EXPECT_CALL(*pullerManager, Pull(tagId, _))
-// // Initialize bucket.
-// .WillOnce(Invoke([](int tagId, vector<std::shared_ptr<LogEvent>>* data) {
-// data->clear();
-// shared_ptr<LogEvent> event = make_shared<LogEvent>(tagId, bucketStartTimeNs + 1);
-// event->write(tagId);
-// event->write(1);
-// event->init();
-// data->push_back(event);
-// return true;
-// }))
-// // Partial bucket.
-// .WillOnce(Invoke([](int tagId, vector<std::shared_ptr<LogEvent>>* data) {
-// data->clear();
-// shared_ptr<LogEvent> event = make_shared<LogEvent>(tagId, bucket2StartTimeNs + 10);
-// event->write(tagId);
-// event->write(5);
-// event->init();
-// data->push_back(event);
-// return true;
-// }));
-//
-// sp<ValueMetricProducer> valueProducer =
-// ValueMetricProducerTestHelper::createValueProducerNoConditions(pullerManager, metric);
-//
-// // First bucket ends.
-// vector<shared_ptr<LogEvent>> allData;
-// allData.clear();
-// shared_ptr<LogEvent> event = make_shared<LogEvent>(tagId, bucket2StartTimeNs + 10);
-// event->write(tagId);
-// event->write(2);
-// event->init();
-// allData.push_back(event);
-// valueProducer->onDataPulled(allData, /** success */ true, bucket2StartTimeNs);
-//
-// // Partial buckets created in 2nd bucket.
-// valueProducer->notifyAppUpgrade(bucket2StartTimeNs + 2, "com.foo", 10000, 1);
-//
-// // One full bucket and one partial bucket.
-// EXPECT_EQ(1UL, valueProducer->mPastBuckets.size());
-// vector<ValueBucket> buckets = valueProducer->mPastBuckets.begin()->second;
-// EXPECT_EQ(2UL, buckets.size());
-// // Full bucket (2 - 1)
-// EXPECT_EQ(1, buckets[0].values[0].long_value);
-// EXPECT_EQ(bucketSizeNs, buckets[0].mConditionTrueNs);
-// // Full bucket (5 - 3)
-// EXPECT_EQ(3, buckets[1].values[0].long_value);
-// // partial bucket [bucket2StartTimeNs, bucket2StartTimeNs + 2]
-// EXPECT_EQ(2, buckets[1].mConditionTrueNs);
-//}
-//
-///*
-// * Tests pulled atoms with filtering
-// */
-//TEST(ValueMetricProducerTest, TestPulledEventsWithFiltering) {
-// ValueMetric metric = ValueMetricProducerTestHelper::createMetric();
-//
-// UidMap uidMap;
-// SimpleAtomMatcher atomMatcher;
-// atomMatcher.set_atom_id(tagId);
-// auto keyValue = atomMatcher.add_field_value_matcher();
-// keyValue->set_field(1);
-// keyValue->set_eq_int(3);
-// sp<EventMatcherWizard> eventMatcherWizard =
-// new EventMatcherWizard({new SimpleLogMatchingTracker(
-// atomMatcherId, logEventMatcherIndex, atomMatcher, uidMap)});
-// sp<MockConditionWizard> wizard = new NaggyMock<MockConditionWizard>();
-// sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>();
-// EXPECT_CALL(*pullerManager, RegisterReceiver(tagId, _, _, _)).WillOnce(Return());
-// EXPECT_CALL(*pullerManager, UnRegisterReceiver(tagId, _)).WillOnce(Return());
-// EXPECT_CALL(*pullerManager, Pull(tagId, _))
-// .WillOnce(Invoke([](int tagId, vector<std::shared_ptr<LogEvent>>* data) {
-// data->clear();
-// shared_ptr<LogEvent> event = make_shared<LogEvent>(tagId, bucketStartTimeNs);
-// event->write(3);
-// event->write(3);
-// event->init();
-// data->push_back(event);
-// return true;
-// }));
-//
-// sp<ValueMetricProducer> valueProducer = new ValueMetricProducer(
-// kConfigKey, metric, -1 /*-1 meaning no condition*/, wizard, logEventMatcherIndex,
-// eventMatcherWizard, tagId, bucketStartTimeNs, bucketStartTimeNs, pullerManager);
-//
-// vector<shared_ptr<LogEvent>> allData;
-// allData.clear();
-// shared_ptr<LogEvent> event = make_shared<LogEvent>(tagId, bucket2StartTimeNs + 1);
-// event->write(3);
-// event->write(11);
-// event->init();
-// allData.push_back(event);
-//
-// valueProducer->onDataPulled(allData, /** succeed */ true, bucket2StartTimeNs);
-// // has one slice
-// EXPECT_EQ(1UL, valueProducer->mCurrentSlicedBucket.size());
-// ValueMetricProducer::Interval curInterval =
-// valueProducer->mCurrentSlicedBucket.begin()->second[0];
-// ValueMetricProducer::BaseInfo curBaseInfo = valueProducer->mCurrentBaseInfo.begin()->second[0];
-//
-// EXPECT_EQ(true, curBaseInfo.hasBase);
-// EXPECT_EQ(11, curBaseInfo.base.long_value);
-// EXPECT_EQ(false, curInterval.hasValue);
-// EXPECT_EQ(8, curInterval.value.long_value);
-// EXPECT_EQ(1UL, valueProducer->mPastBuckets.size());
-// EXPECT_EQ(8, valueProducer->mPastBuckets.begin()->second[0].values[0].long_value);
-// EXPECT_EQ(bucketSizeNs, valueProducer->mPastBuckets.begin()->second[0].mConditionTrueNs);
-//
-// allData.clear();
-// event = make_shared<LogEvent>(tagId, bucket3StartTimeNs + 1);
-// event->write(4);
-// event->write(23);
-// event->init();
-// allData.push_back(event);
-// valueProducer->onDataPulled(allData, /** succeed */ true, bucket3StartTimeNs);
-// // No new data seen, so data has been cleared.
-// EXPECT_EQ(0UL, valueProducer->mCurrentSlicedBucket.size());
-//
-// EXPECT_EQ(true, curBaseInfo.hasBase);
-// EXPECT_EQ(11, curBaseInfo.base.long_value);
-// EXPECT_EQ(false, curInterval.hasValue);
-// EXPECT_EQ(8, curInterval.value.long_value);
-// EXPECT_EQ(1UL, valueProducer->mPastBuckets.size());
-// EXPECT_EQ(8, valueProducer->mPastBuckets.begin()->second[0].values[0].long_value);
-// EXPECT_EQ(bucketSizeNs, valueProducer->mPastBuckets.begin()->second[0].mConditionTrueNs);
-//
-// allData.clear();
-// event = make_shared<LogEvent>(tagId, bucket4StartTimeNs + 1);
-// event->write(3);
-// event->write(36);
-// event->init();
-// allData.push_back(event);
-// valueProducer->onDataPulled(allData, /** succeed */ true, bucket4StartTimeNs);
-// EXPECT_EQ(1UL, valueProducer->mCurrentSlicedBucket.size());
-// curInterval = valueProducer->mCurrentSlicedBucket.begin()->second[0];
-// curBaseInfo = valueProducer->mCurrentBaseInfo.begin()->second[0];
-//
-// // the base was reset
-// EXPECT_EQ(true, curBaseInfo.hasBase);
-// EXPECT_EQ(36, curBaseInfo.base.long_value);
-// EXPECT_EQ(false, curInterval.hasValue);
-// EXPECT_EQ(1UL, valueProducer->mPastBuckets.size());
-// EXPECT_EQ(1UL, valueProducer->mPastBuckets.begin()->second.size());
-// EXPECT_EQ(8, valueProducer->mPastBuckets.begin()->second.back().values[0].long_value);
-// EXPECT_EQ(bucketSizeNs, valueProducer->mPastBuckets.begin()->second.back().mConditionTrueNs);
-//}
-//
+class ValueMetricProducerTestHelper {
+public:
+ static sp<ValueMetricProducer> createValueProducerNoConditions(
+ sp<MockStatsPullerManager>& pullerManager, ValueMetric& metric) {
+ UidMap uidMap;
+ SimpleAtomMatcher atomMatcher;
+ atomMatcher.set_atom_id(tagId);
+ sp<EventMatcherWizard> eventMatcherWizard =
+ new EventMatcherWizard({new SimpleLogMatchingTracker(
+ atomMatcherId, logEventMatcherIndex, atomMatcher, uidMap)});
+ sp<MockConditionWizard> wizard = new NaggyMock<MockConditionWizard>();
+ EXPECT_CALL(*pullerManager, RegisterReceiver(tagId, _, _, _)).WillOnce(Return());
+ EXPECT_CALL(*pullerManager, UnRegisterReceiver(tagId, _)).WillRepeatedly(Return());
+
+ sp<ValueMetricProducer> valueProducer = new ValueMetricProducer(
+ kConfigKey, metric, -1 /*-1 meaning no condition*/, wizard, logEventMatcherIndex,
+ eventMatcherWizard, tagId, bucketStartTimeNs, bucketStartTimeNs, pullerManager);
+ return valueProducer;
+ }
+
+ static sp<ValueMetricProducer> createValueProducerWithCondition(
+ sp<MockStatsPullerManager>& pullerManager, ValueMetric& metric) {
+ UidMap uidMap;
+ SimpleAtomMatcher atomMatcher;
+ atomMatcher.set_atom_id(tagId);
+ sp<EventMatcherWizard> eventMatcherWizard =
+ new EventMatcherWizard({new SimpleLogMatchingTracker(
+ atomMatcherId, logEventMatcherIndex, atomMatcher, uidMap)});
+ sp<MockConditionWizard> wizard = new NaggyMock<MockConditionWizard>();
+ EXPECT_CALL(*pullerManager, RegisterReceiver(tagId, _, _, _)).WillOnce(Return());
+ EXPECT_CALL(*pullerManager, UnRegisterReceiver(tagId, _)).WillRepeatedly(Return());
+
+ sp<ValueMetricProducer> valueProducer = new ValueMetricProducer(
+ kConfigKey, metric, 1, wizard, logEventMatcherIndex, eventMatcherWizard, tagId,
+ bucketStartTimeNs, bucketStartTimeNs, pullerManager);
+ valueProducer->mCondition = ConditionState::kFalse;
+ return valueProducer;
+ }
+
+ static sp<ValueMetricProducer> createValueProducerWithNoInitialCondition(
+ sp<MockStatsPullerManager>& pullerManager, ValueMetric& metric) {
+ UidMap uidMap;
+ SimpleAtomMatcher atomMatcher;
+ atomMatcher.set_atom_id(tagId);
+ sp<EventMatcherWizard> eventMatcherWizard =
+ new EventMatcherWizard({new SimpleLogMatchingTracker(
+ atomMatcherId, logEventMatcherIndex, atomMatcher, uidMap)});
+ sp<MockConditionWizard> wizard = new NaggyMock<MockConditionWizard>();
+ EXPECT_CALL(*pullerManager, RegisterReceiver(tagId, _, _, _)).WillOnce(Return());
+ EXPECT_CALL(*pullerManager, UnRegisterReceiver(tagId, _)).WillRepeatedly(Return());
+
+ sp<ValueMetricProducer> valueProducer = new ValueMetricProducer(
+ kConfigKey, metric, 1, wizard, logEventMatcherIndex, eventMatcherWizard, tagId,
+ bucketStartTimeNs, bucketStartTimeNs, pullerManager);
+ return valueProducer;
+ }
+
+ static sp<ValueMetricProducer> createValueProducerWithState(
+ sp<MockStatsPullerManager>& pullerManager, ValueMetric& metric,
+ vector<int32_t> slicedStateAtoms,
+ unordered_map<int, unordered_map<int, int64_t>> stateGroupMap) {
+ UidMap uidMap;
+ SimpleAtomMatcher atomMatcher;
+ atomMatcher.set_atom_id(tagId);
+ sp<EventMatcherWizard> eventMatcherWizard =
+ new EventMatcherWizard({new SimpleLogMatchingTracker(
+ atomMatcherId, logEventMatcherIndex, atomMatcher, uidMap)});
+ sp<MockConditionWizard> wizard = new NaggyMock<MockConditionWizard>();
+ EXPECT_CALL(*pullerManager, RegisterReceiver(tagId, _, _, _)).WillOnce(Return());
+ EXPECT_CALL(*pullerManager, UnRegisterReceiver(tagId, _)).WillRepeatedly(Return());
+ sp<ValueMetricProducer> valueProducer = new ValueMetricProducer(
+ kConfigKey, metric, -1 /* no condition */, wizard, logEventMatcherIndex,
+ eventMatcherWizard, tagId, bucketStartTimeNs, bucketStartTimeNs, pullerManager, {},
+ {}, slicedStateAtoms, stateGroupMap);
+ return valueProducer;
+ }
+
+ static ValueMetric createMetric() {
+ ValueMetric metric;
+ metric.set_id(metricId);
+ metric.set_bucket(ONE_MINUTE);
+ metric.mutable_value_field()->set_field(tagId);
+ metric.mutable_value_field()->add_child()->set_field(2);
+ metric.set_max_pull_delay_sec(INT_MAX);
+ return metric;
+ }
+
+ static ValueMetric createMetricWithCondition() {
+ ValueMetric metric = ValueMetricProducerTestHelper::createMetric();
+ metric.set_condition(StringToId("SCREEN_ON"));
+ return metric;
+ }
+
+ static ValueMetric createMetricWithState(string state) {
+ ValueMetric metric = ValueMetricProducerTestHelper::createMetric();
+ metric.add_slice_by_state(StringToId(state));
+ return metric;
+ }
+};
+
+/*
+ * Tests that the first bucket works correctly
+ */
+TEST(ValueMetricProducerTest, TestCalcPreviousBucketEndTime) {
+ ValueMetric metric = ValueMetricProducerTestHelper::createMetric();
+
+ int64_t startTimeBase = 11;
+ UidMap uidMap;
+ SimpleAtomMatcher atomMatcher;
+ atomMatcher.set_atom_id(tagId);
+ sp<EventMatcherWizard> eventMatcherWizard =
+ new EventMatcherWizard({new SimpleLogMatchingTracker(
+ atomMatcherId, logEventMatcherIndex, atomMatcher, uidMap)});
+ sp<MockConditionWizard> wizard = new NaggyMock<MockConditionWizard>();
+ sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>();
+
+ // statsd started long ago.
+ // The metric starts in the middle of the bucket
+ ValueMetricProducer valueProducer(kConfigKey, metric, -1 /*-1 meaning no condition*/, wizard,
+ logEventMatcherIndex, eventMatcherWizard, -1, startTimeBase,
+ 22, pullerManager);
+
+ EXPECT_EQ(startTimeBase, valueProducer.calcPreviousBucketEndTime(60 * NS_PER_SEC + 10));
+ EXPECT_EQ(startTimeBase, valueProducer.calcPreviousBucketEndTime(60 * NS_PER_SEC + 10));
+ EXPECT_EQ(60 * NS_PER_SEC + startTimeBase,
+ valueProducer.calcPreviousBucketEndTime(2 * 60 * NS_PER_SEC));
+ EXPECT_EQ(2 * 60 * NS_PER_SEC + startTimeBase,
+ valueProducer.calcPreviousBucketEndTime(3 * 60 * NS_PER_SEC));
+}
+
+/*
+ * Tests that the first bucket works correctly
+ */
+TEST(ValueMetricProducerTest, TestFirstBucket) {
+ ValueMetric metric = ValueMetricProducerTestHelper::createMetric();
+
+ UidMap uidMap;
+ SimpleAtomMatcher atomMatcher;
+ atomMatcher.set_atom_id(tagId);
+ sp<EventMatcherWizard> eventMatcherWizard =
+ new EventMatcherWizard({new SimpleLogMatchingTracker(
+ atomMatcherId, logEventMatcherIndex, atomMatcher, uidMap)});
+ sp<MockConditionWizard> wizard = new NaggyMock<MockConditionWizard>();
+ sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>();
+
+ // statsd started long ago.
+ // The metric starts in the middle of the bucket
+ ValueMetricProducer valueProducer(kConfigKey, metric, -1 /*-1 meaning no condition*/, wizard,
+ logEventMatcherIndex, eventMatcherWizard, -1, 5,
+ 600 * NS_PER_SEC + NS_PER_SEC / 2, pullerManager);
+
+ EXPECT_EQ(600500000000, valueProducer.mCurrentBucketStartTimeNs);
+ EXPECT_EQ(10, valueProducer.mCurrentBucketNum);
+ EXPECT_EQ(660000000005, valueProducer.getCurrentBucketEndTimeNs());
+}
+
+/*
+ * Tests pulled atoms with no conditions
+ */
+TEST(ValueMetricProducerTest, TestPulledEventsNoCondition) {
+ ValueMetric metric = ValueMetricProducerTestHelper::createMetric();
+ sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>();
+ EXPECT_CALL(*pullerManager, Pull(tagId, _))
+ .WillOnce(Invoke([](int tagId, vector<std::shared_ptr<LogEvent>>* data) {
+ data->clear();
+ data->push_back(CreateRepeatedValueLogEvent(tagId, bucketStartTimeNs, 3));
+ return true;
+ }));
+
+ sp<ValueMetricProducer> valueProducer =
+ ValueMetricProducerTestHelper::createValueProducerNoConditions(pullerManager, metric);
+
+ vector<shared_ptr<LogEvent>> allData;
+ allData.clear();
+ allData.push_back(CreateRepeatedValueLogEvent(tagId, bucket2StartTimeNs + 1, 11));
+
+ valueProducer->onDataPulled(allData, /** succeed */ true, bucket2StartTimeNs);
+ // has one slice
+ EXPECT_EQ(1UL, valueProducer->mCurrentSlicedBucket.size());
+ ValueMetricProducer::Interval curInterval =
+ valueProducer->mCurrentSlicedBucket.begin()->second[0];
+ ValueMetricProducer::BaseInfo curBaseInfo = valueProducer->mCurrentBaseInfo.begin()->second[0];
+
+ EXPECT_EQ(true, curBaseInfo.hasBase);
+ EXPECT_EQ(11, curBaseInfo.base.long_value);
+ EXPECT_EQ(false, curInterval.hasValue);
+ EXPECT_EQ(8, curInterval.value.long_value);
+ EXPECT_EQ(1UL, valueProducer->mPastBuckets.size());
+ EXPECT_EQ(8, valueProducer->mPastBuckets.begin()->second[0].values[0].long_value);
+ EXPECT_EQ(bucketSizeNs, valueProducer->mPastBuckets.begin()->second[0].mConditionTrueNs);
+
+ allData.clear();
+ allData.push_back(CreateRepeatedValueLogEvent(tagId, bucket3StartTimeNs + 1, 23));
+ valueProducer->onDataPulled(allData, /** succeed */ true, bucket3StartTimeNs);
+ // has one slice
+ EXPECT_EQ(1UL, valueProducer->mCurrentSlicedBucket.size());
+ curInterval = valueProducer->mCurrentSlicedBucket.begin()->second[0];
+ curBaseInfo = valueProducer->mCurrentBaseInfo.begin()->second[0];
+
+ EXPECT_EQ(true, curBaseInfo.hasBase);
+ EXPECT_EQ(23, curBaseInfo.base.long_value);
+ EXPECT_EQ(false, curInterval.hasValue);
+ EXPECT_EQ(12, curInterval.value.long_value);
+ EXPECT_EQ(1UL, valueProducer->mPastBuckets.size());
+ EXPECT_EQ(2UL, valueProducer->mPastBuckets.begin()->second.size());
+ EXPECT_EQ(8, valueProducer->mPastBuckets.begin()->second[0].values[0].long_value);
+ EXPECT_EQ(bucketSizeNs, valueProducer->mPastBuckets.begin()->second[0].mConditionTrueNs);
+ EXPECT_EQ(12, valueProducer->mPastBuckets.begin()->second.back().values[0].long_value);
+ EXPECT_EQ(bucketSizeNs, valueProducer->mPastBuckets.begin()->second.back().mConditionTrueNs);
+
+ allData.clear();
+ allData.push_back(CreateRepeatedValueLogEvent(tagId, bucket4StartTimeNs + 1, 36));
+ valueProducer->onDataPulled(allData, /** succeed */ true, bucket4StartTimeNs);
+ EXPECT_EQ(1UL, valueProducer->mCurrentSlicedBucket.size());
+ curInterval = valueProducer->mCurrentSlicedBucket.begin()->second[0];
+ curBaseInfo = valueProducer->mCurrentBaseInfo.begin()->second[0];
+
+ EXPECT_EQ(true, curBaseInfo.hasBase);
+ EXPECT_EQ(36, curBaseInfo.base.long_value);
+ EXPECT_EQ(false, curInterval.hasValue);
+ EXPECT_EQ(13, curInterval.value.long_value);
+ EXPECT_EQ(1UL, valueProducer->mPastBuckets.size());
+ EXPECT_EQ(3UL, valueProducer->mPastBuckets.begin()->second.size());
+ EXPECT_EQ(8, valueProducer->mPastBuckets.begin()->second[0].values[0].long_value);
+ EXPECT_EQ(bucketSizeNs, valueProducer->mPastBuckets.begin()->second[0].mConditionTrueNs);
+ EXPECT_EQ(12, valueProducer->mPastBuckets.begin()->second[1].values[0].long_value);
+ EXPECT_EQ(bucketSizeNs, valueProducer->mPastBuckets.begin()->second[1].mConditionTrueNs);
+ EXPECT_EQ(13, valueProducer->mPastBuckets.begin()->second[2].values[0].long_value);
+ EXPECT_EQ(bucketSizeNs, valueProducer->mPastBuckets.begin()->second[2].mConditionTrueNs);
+}
+
+TEST(ValueMetricProducerTest, TestPartialBucketCreated) {
+ ValueMetric metric = ValueMetricProducerTestHelper::createMetric();
+ sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>();
+ EXPECT_CALL(*pullerManager, Pull(tagId, _))
+ // Initialize bucket.
+ .WillOnce(Invoke([](int tagId, vector<std::shared_ptr<LogEvent>>* data) {
+ data->clear();
+ data->push_back(CreateRepeatedValueLogEvent(tagId, bucketStartTimeNs + 1, 1));
+ return true;
+ }))
+ // Partial bucket.
+ .WillOnce(Invoke([](int tagId, vector<std::shared_ptr<LogEvent>>* data) {
+ data->clear();
+ data->push_back(CreateRepeatedValueLogEvent(tagId, bucket2StartTimeNs + 10, 5));
+ return true;
+ }));
+
+ sp<ValueMetricProducer> valueProducer =
+ ValueMetricProducerTestHelper::createValueProducerNoConditions(pullerManager, metric);
+
+ // First bucket ends.
+ vector<shared_ptr<LogEvent>> allData;
+ allData.clear();
+ allData.push_back(CreateRepeatedValueLogEvent(tagId, bucket2StartTimeNs + 10, 2));
+ valueProducer->onDataPulled(allData, /** success */ true, bucket2StartTimeNs);
+
+ // Partial buckets created in 2nd bucket.
+ valueProducer->notifyAppUpgrade(bucket2StartTimeNs + 2, "com.foo", 10000, 1);
+
+ // One full bucket and one partial bucket.
+ EXPECT_EQ(1UL, valueProducer->mPastBuckets.size());
+ vector<ValueBucket> buckets = valueProducer->mPastBuckets.begin()->second;
+ EXPECT_EQ(2UL, buckets.size());
+ // Full bucket (2 - 1)
+ EXPECT_EQ(1, buckets[0].values[0].long_value);
+ EXPECT_EQ(bucketSizeNs, buckets[0].mConditionTrueNs);
+ // Full bucket (5 - 3)
+ EXPECT_EQ(3, buckets[1].values[0].long_value);
+ // partial bucket [bucket2StartTimeNs, bucket2StartTimeNs + 2]
+ EXPECT_EQ(2, buckets[1].mConditionTrueNs);
+}
+
+/*
+ * Tests pulled atoms with filtering
+ */
+TEST(ValueMetricProducerTest, TestPulledEventsWithFiltering) {
+ ValueMetric metric = ValueMetricProducerTestHelper::createMetric();
+
+ UidMap uidMap;
+ SimpleAtomMatcher atomMatcher;
+ atomMatcher.set_atom_id(tagId);
+ auto keyValue = atomMatcher.add_field_value_matcher();
+ keyValue->set_field(1);
+ keyValue->set_eq_int(3);
+ sp<EventMatcherWizard> eventMatcherWizard =
+ new EventMatcherWizard({new SimpleLogMatchingTracker(
+ atomMatcherId, logEventMatcherIndex, atomMatcher, uidMap)});
+ sp<MockConditionWizard> wizard = new NaggyMock<MockConditionWizard>();
+ sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>();
+ EXPECT_CALL(*pullerManager, RegisterReceiver(tagId, _, _, _)).WillOnce(Return());
+ EXPECT_CALL(*pullerManager, UnRegisterReceiver(tagId, _)).WillOnce(Return());
+ EXPECT_CALL(*pullerManager, Pull(tagId, _))
+ .WillOnce(Invoke([](int tagId, vector<std::shared_ptr<LogEvent>>* data) {
+ data->clear();
+ data->push_back(CreateTwoValueLogEvent(tagId, bucketStartTimeNs, 3, 3));
+ return true;
+ }));
+
+ sp<ValueMetricProducer> valueProducer = new ValueMetricProducer(
+ kConfigKey, metric, -1 /*-1 meaning no condition*/, wizard, logEventMatcherIndex,
+ eventMatcherWizard, tagId, bucketStartTimeNs, bucketStartTimeNs, pullerManager);
+
+ vector<shared_ptr<LogEvent>> allData;
+ allData.clear();
+ allData.push_back(CreateTwoValueLogEvent(tagId, bucket2StartTimeNs + 1, 3, 11));
+
+ valueProducer->onDataPulled(allData, /** succeed */ true, bucket2StartTimeNs);
+ // has one slice
+ EXPECT_EQ(1UL, valueProducer->mCurrentSlicedBucket.size());
+ ValueMetricProducer::Interval curInterval =
+ valueProducer->mCurrentSlicedBucket.begin()->second[0];
+ ValueMetricProducer::BaseInfo curBaseInfo = valueProducer->mCurrentBaseInfo.begin()->second[0];
+
+ EXPECT_EQ(true, curBaseInfo.hasBase);
+ EXPECT_EQ(11, curBaseInfo.base.long_value);
+ EXPECT_EQ(false, curInterval.hasValue);
+ EXPECT_EQ(8, curInterval.value.long_value);
+ EXPECT_EQ(1UL, valueProducer->mPastBuckets.size());
+ EXPECT_EQ(8, valueProducer->mPastBuckets.begin()->second[0].values[0].long_value);
+ EXPECT_EQ(bucketSizeNs, valueProducer->mPastBuckets.begin()->second[0].mConditionTrueNs);
+
+ allData.clear();
+ allData.push_back(CreateTwoValueLogEvent(tagId, bucket3StartTimeNs + 1, 4, 23));
+ valueProducer->onDataPulled(allData, /** succeed */ true, bucket3StartTimeNs);
+ // No new data seen, so data has been cleared.
+ EXPECT_EQ(0UL, valueProducer->mCurrentSlicedBucket.size());
+
+ EXPECT_EQ(true, curBaseInfo.hasBase);
+ EXPECT_EQ(11, curBaseInfo.base.long_value);
+ EXPECT_EQ(false, curInterval.hasValue);
+ EXPECT_EQ(8, curInterval.value.long_value);
+ EXPECT_EQ(1UL, valueProducer->mPastBuckets.size());
+ EXPECT_EQ(8, valueProducer->mPastBuckets.begin()->second[0].values[0].long_value);
+ EXPECT_EQ(bucketSizeNs, valueProducer->mPastBuckets.begin()->second[0].mConditionTrueNs);
+
+ allData.clear();
+ allData.push_back(CreateTwoValueLogEvent(tagId, bucket4StartTimeNs + 1, 3, 36));
+ valueProducer->onDataPulled(allData, /** succeed */ true, bucket4StartTimeNs);
+ EXPECT_EQ(1UL, valueProducer->mCurrentSlicedBucket.size());
+ curInterval = valueProducer->mCurrentSlicedBucket.begin()->second[0];
+ curBaseInfo = valueProducer->mCurrentBaseInfo.begin()->second[0];
+
+ // the base was reset
+ EXPECT_EQ(true, curBaseInfo.hasBase);
+ EXPECT_EQ(36, curBaseInfo.base.long_value);
+ EXPECT_EQ(false, curInterval.hasValue);
+ EXPECT_EQ(1UL, valueProducer->mPastBuckets.size());
+ EXPECT_EQ(1UL, valueProducer->mPastBuckets.begin()->second.size());
+ EXPECT_EQ(8, valueProducer->mPastBuckets.begin()->second.back().values[0].long_value);
+ EXPECT_EQ(bucketSizeNs, valueProducer->mPastBuckets.begin()->second.back().mConditionTrueNs);
+}
+
///*
// * Tests pulled atoms with no conditions and take absolute value after reset
// */
-//TEST(ValueMetricProducerTest, TestPulledEventsTakeAbsoluteValueOnReset) {
+// TEST(ValueMetricProducerTest, TestPulledEventsTakeAbsoluteValueOnReset) {
// ValueMetric metric = ValueMetricProducerTestHelper::createMetric();
// metric.set_use_absolute_value_on_reset(true);
//
@@ -512,8 +455,9 @@
// valueProducer->onDataPulled(allData, /** succeed */ true, bucket2StartTimeNs);
// // has one slice
// EXPECT_EQ(1UL, valueProducer->mCurrentSlicedBucket.size());
-// ValueMetricProducer::Interval curInterval = valueProducer->mCurrentSlicedBucket.begin()->second[0];
-// ValueMetricProducer::BaseInfo curBaseInfo = valueProducer->mCurrentBaseInfo.begin()->second[0];
+// ValueMetricProducer::Interval curInterval =
+// valueProducer->mCurrentSlicedBucket.begin()->second[0]; ValueMetricProducer::BaseInfo
+// curBaseInfo = valueProducer->mCurrentBaseInfo.begin()->second[0];
//
// EXPECT_EQ(true, curBaseInfo.hasBase);
// EXPECT_EQ(11, curBaseInfo.base.long_value);
@@ -564,7 +508,7 @@
///*
// * Tests pulled atoms with no conditions and take zero value after reset
// */
-//TEST(ValueMetricProducerTest, TestPulledEventsTakeZeroOnReset) {
+// TEST(ValueMetricProducerTest, TestPulledEventsTakeZeroOnReset) {
// ValueMetric metric = ValueMetricProducerTestHelper::createMetric();
// sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>();
// EXPECT_CALL(*pullerManager, Pull(tagId, _)).WillOnce(Return(false));
@@ -582,8 +526,9 @@
// valueProducer->onDataPulled(allData, /** succeed */ true, bucket2StartTimeNs);
// // has one slice
// EXPECT_EQ(1UL, valueProducer->mCurrentSlicedBucket.size());
-// ValueMetricProducer::Interval curInterval = valueProducer->mCurrentSlicedBucket.begin()->second[0];
-// ValueMetricProducer::BaseInfo curBaseInfo = valueProducer->mCurrentBaseInfo.begin()->second[0];
+// ValueMetricProducer::Interval curInterval =
+// valueProducer->mCurrentSlicedBucket.begin()->second[0]; ValueMetricProducer::BaseInfo
+// curBaseInfo = valueProducer->mCurrentBaseInfo.begin()->second[0];
//
// EXPECT_EQ(true, curBaseInfo.hasBase);
// EXPECT_EQ(11, curBaseInfo.base.long_value);
@@ -628,7 +573,7 @@
///*
// * Test pulled event with non sliced condition.
// */
-//TEST(ValueMetricProducerTest, TestEventsWithNonSlicedCondition) {
+// TEST(ValueMetricProducerTest, TestEventsWithNonSlicedCondition) {
// ValueMetric metric = ValueMetricProducerTestHelper::createMetricWithCondition();
//
// sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>();
@@ -663,14 +608,16 @@
// }));
//
// sp<ValueMetricProducer> valueProducer =
-// ValueMetricProducerTestHelper::createValueProducerWithCondition(pullerManager, metric);
+// ValueMetricProducerTestHelper::createValueProducerWithCondition(pullerManager,
+// metric);
//
// valueProducer->onConditionChanged(true, bucketStartTimeNs + 8);
//
// // has one slice
// EXPECT_EQ(1UL, valueProducer->mCurrentSlicedBucket.size());
-// ValueMetricProducer::Interval curInterval = valueProducer->mCurrentSlicedBucket.begin()->second[0];
-// ValueMetricProducer::BaseInfo curBaseInfo = valueProducer->mCurrentBaseInfo.begin()->second[0];
+// ValueMetricProducer::Interval curInterval =
+// valueProducer->mCurrentSlicedBucket.begin()->second[0]; ValueMetricProducer::BaseInfo
+// curBaseInfo = valueProducer->mCurrentBaseInfo.begin()->second[0];
// // startUpdated:false sum:0 start:100
// EXPECT_EQ(true, curBaseInfo.hasBase);
// EXPECT_EQ(100, curBaseInfo.base.long_value);
@@ -711,7 +658,7 @@
// assertPastBucketValuesSingleKey(valueProducer->mPastBuckets, {10, 20}, {bucketSizeNs - 8, 1});
//}
//
-//TEST(ValueMetricProducerTest, TestPushedEventsWithUpgrade) {
+// TEST(ValueMetricProducerTest, TestPushedEventsWithUpgrade) {
// ValueMetric metric = ValueMetricProducerTestHelper::createMetric();
//
// UidMap uidMap;
@@ -723,8 +670,8 @@
// sp<MockConditionWizard> wizard = new NaggyMock<MockConditionWizard>();
// sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>();
// ValueMetricProducer valueProducer(kConfigKey, metric, -1, wizard, logEventMatcherIndex,
-// eventMatcherWizard, -1, bucketStartTimeNs, bucketStartTimeNs,
-// pullerManager);
+// eventMatcherWizard, -1, bucketStartTimeNs,
+// bucketStartTimeNs, pullerManager);
//
// shared_ptr<LogEvent> event1 = make_shared<LogEvent>(tagId, bucketStartTimeNs + 10);
// event1->write(1);
@@ -737,25 +684,21 @@
// EXPECT_EQ(1UL, valueProducer.mPastBuckets[DEFAULT_METRIC_DIMENSION_KEY].size());
// EXPECT_EQ(bucketStartTimeNs + 150, valueProducer.mCurrentBucketStartTimeNs);
//
-// shared_ptr<LogEvent> event2 = make_shared<LogEvent>(tagId, bucketStartTimeNs + 59 * NS_PER_SEC);
-// event2->write(1);
-// event2->write(10);
-// event2->init();
+// shared_ptr<LogEvent> event2 = make_shared<LogEvent>(tagId, bucketStartTimeNs + 59 *
+// NS_PER_SEC); event2->write(1); event2->write(10); event2->init();
// valueProducer.onMatchedLogEvent(1 /*log matcher index*/, *event2);
// EXPECT_EQ(1UL, valueProducer.mPastBuckets[DEFAULT_METRIC_DIMENSION_KEY].size());
// EXPECT_EQ(bucketStartTimeNs + 150, valueProducer.mCurrentBucketStartTimeNs);
//
// // Next value should create a new bucket.
-// shared_ptr<LogEvent> event3 = make_shared<LogEvent>(tagId, bucketStartTimeNs + 65 * NS_PER_SEC);
-// event3->write(1);
-// event3->write(10);
-// event3->init();
+// shared_ptr<LogEvent> event3 = make_shared<LogEvent>(tagId, bucketStartTimeNs + 65 *
+// NS_PER_SEC); event3->write(1); event3->write(10); event3->init();
// valueProducer.onMatchedLogEvent(1 /*log matcher index*/, *event3);
// EXPECT_EQ(2UL, valueProducer.mPastBuckets[DEFAULT_METRIC_DIMENSION_KEY].size());
// EXPECT_EQ(bucketStartTimeNs + bucketSizeNs, valueProducer.mCurrentBucketStartTimeNs);
//}
//
-//TEST(ValueMetricProducerTest, TestPulledValueWithUpgrade) {
+// TEST(ValueMetricProducerTest, TestPulledValueWithUpgrade) {
// ValueMetric metric = ValueMetricProducerTestHelper::createMetric();
//
// UidMap uidMap;
@@ -772,10 +715,8 @@
// .WillOnce(Return(true))
// .WillOnce(Invoke([](int tagId, vector<std::shared_ptr<LogEvent>>* data) {
// data->clear();
-// shared_ptr<LogEvent> event = make_shared<LogEvent>(tagId, bucket2StartTimeNs + 149);
-// event->write(tagId);
-// event->write(120);
-// event->init();
+// shared_ptr<LogEvent> event = make_shared<LogEvent>(tagId, bucket2StartTimeNs +
+// 149); event->write(tagId); event->write(120); event->init();
// data->push_back(event);
// return true;
// }));
@@ -814,7 +755,7 @@
// {150, bucketSizeNs - 150});
//}
//
-//TEST(ValueMetricProducerTest, TestPulledWithAppUpgradeDisabled) {
+// TEST(ValueMetricProducerTest, TestPulledWithAppUpgradeDisabled) {
// ValueMetric metric = ValueMetricProducerTestHelper::createMetric();
// metric.set_split_bucket_for_app_upgrade(false);
//
@@ -849,7 +790,7 @@
// EXPECT_EQ(bucket2StartTimeNs, valueProducer.mCurrentBucketStartTimeNs);
//}
//
-//TEST(ValueMetricProducerTest, TestPulledValueWithUpgradeWhileConditionFalse) {
+// TEST(ValueMetricProducerTest, TestPulledValueWithUpgradeWhileConditionFalse) {
// ValueMetric metric = ValueMetricProducerTestHelper::createMetricWithCondition();
//
// sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>();
@@ -865,15 +806,14 @@
// }))
// .WillOnce(Invoke([](int tagId, vector<std::shared_ptr<LogEvent>>* data) {
// data->clear();
-// shared_ptr<LogEvent> event = make_shared<LogEvent>(tagId, bucket2StartTimeNs - 100);
-// event->write(tagId);
-// event->write(120);
-// event->init();
+// shared_ptr<LogEvent> event = make_shared<LogEvent>(tagId, bucket2StartTimeNs -
+// 100); event->write(tagId); event->write(120); event->init();
// data->push_back(event);
// return true;
// }));
// sp<ValueMetricProducer> valueProducer =
-// ValueMetricProducerTestHelper::createValueProducerWithCondition(pullerManager, metric);
+// ValueMetricProducerTestHelper::createValueProducerWithCondition(pullerManager,
+// metric);
//
// valueProducer->onConditionChanged(true, bucketStartTimeNs + 1);
//
@@ -891,7 +831,7 @@
// EXPECT_FALSE(valueProducer->mCondition);
//}
//
-//TEST(ValueMetricProducerTest, TestPushedEventsWithoutCondition) {
+// TEST(ValueMetricProducerTest, TestPushedEventsWithoutCondition) {
// ValueMetric metric = ValueMetricProducerTestHelper::createMetric();
//
// UidMap uidMap;
@@ -904,8 +844,8 @@
// sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>();
//
// ValueMetricProducer valueProducer(kConfigKey, metric, -1, wizard, logEventMatcherIndex,
-// eventMatcherWizard, -1, bucketStartTimeNs, bucketStartTimeNs,
-// pullerManager);
+// eventMatcherWizard, -1, bucketStartTimeNs,
+// bucketStartTimeNs, pullerManager);
//
// shared_ptr<LogEvent> event1 = make_shared<LogEvent>(tagId, bucketStartTimeNs + 10);
// event1->write(1);
@@ -918,10 +858,10 @@
// valueProducer.onMatchedLogEvent(1 /*log matcher index*/, *event1);
// // has one slice
// EXPECT_EQ(1UL, valueProducer.mCurrentSlicedBucket.size());
-// ValueMetricProducer::Interval curInterval = valueProducer.mCurrentSlicedBucket.begin()->second[0];
-// ValueMetricProducer::BaseInfo curBaseInfo = valueProducer.mCurrentBaseInfo.begin()->second[0];
-// EXPECT_EQ(10, curInterval.value.long_value);
-// EXPECT_EQ(true, curInterval.hasValue);
+// ValueMetricProducer::Interval curInterval =
+// valueProducer.mCurrentSlicedBucket.begin()->second[0]; ValueMetricProducer::BaseInfo
+// curBaseInfo = valueProducer.mCurrentBaseInfo.begin()->second[0]; EXPECT_EQ(10,
+// curInterval.value.long_value); EXPECT_EQ(true, curInterval.hasValue);
//
// valueProducer.onMatchedLogEvent(1 /*log matcher index*/, *event2);
//
@@ -934,7 +874,7 @@
// assertPastBucketValuesSingleKey(valueProducer.mPastBuckets, {30}, {bucketSizeNs});
//}
//
-//TEST(ValueMetricProducerTest, TestPushedEventsWithCondition) {
+// TEST(ValueMetricProducerTest, TestPushedEventsWithCondition) {
// ValueMetric metric = ValueMetricProducerTestHelper::createMetric();
//
// UidMap uidMap;
@@ -947,8 +887,8 @@
// sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>();
//
// ValueMetricProducer valueProducer(kConfigKey, metric, 1, wizard, logEventMatcherIndex,
-// eventMatcherWizard, -1, bucketStartTimeNs, bucketStartTimeNs,
-// pullerManager);
+// eventMatcherWizard, -1, bucketStartTimeNs,
+// bucketStartTimeNs, pullerManager);
// valueProducer.mCondition = ConditionState::kFalse;
//
// shared_ptr<LogEvent> event1 = make_shared<LogEvent>(tagId, bucketStartTimeNs + 10);
@@ -1000,7 +940,7 @@
// assertPastBucketValuesSingleKey(valueProducer.mPastBuckets, {50}, {20});
//}
//
-//TEST(ValueMetricProducerTest, TestAnomalyDetection) {
+// TEST(ValueMetricProducerTest, TestAnomalyDetection) {
// sp<AlarmMonitor> alarmMonitor;
// Alert alert;
// alert.set_id(101);
@@ -1053,7 +993,8 @@
// event5->write(150); // value of interest
// event5->init();
// shared_ptr<LogEvent> event6
-// = make_shared<LogEvent>(tagId, bucketStartTimeNs + 3 * bucketSizeNs + 10 * NS_PER_SEC);
+// = make_shared<LogEvent>(tagId, bucketStartTimeNs + 3 * bucketSizeNs + 10 *
+// NS_PER_SEC);
// event6->write(25);
// event6->write(160); // value of interest
// event6->init();
@@ -1086,7 +1027,7 @@
//}
//
//// Test value metric no condition, the pull on bucket boundary come in time and too late
-//TEST(ValueMetricProducerTest, TestBucketBoundaryNoCondition) {
+// TEST(ValueMetricProducerTest, TestBucketBoundaryNoCondition) {
// ValueMetric metric = ValueMetricProducerTestHelper::createMetric();
// sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>();
// EXPECT_CALL(*pullerManager, Pull(tagId, _)).WillOnce(Return(true));
@@ -1107,7 +1048,8 @@
// EXPECT_EQ(1UL, valueProducer->mCurrentSlicedBucket.size());
// ValueMetricProducer::Interval curInterval =
// valueProducer->mCurrentSlicedBucket.begin()->second[0];
-// ValueMetricProducer::BaseInfo curBaseInfo = valueProducer->mCurrentBaseInfo.begin()->second[0];
+// ValueMetricProducer::BaseInfo curBaseInfo =
+// valueProducer->mCurrentBaseInfo.begin()->second[0];
//
// // startUpdated:true sum:0 start:11
// EXPECT_EQ(true, curBaseInfo.hasBase);
@@ -1158,7 +1100,7 @@
// * Test pulled event with non sliced condition. The pull on boundary come late because the alarm
// * was delivered late.
// */
-//TEST(ValueMetricProducerTest, TestBucketBoundaryWithCondition) {
+// TEST(ValueMetricProducerTest, TestBucketBoundaryWithCondition) {
// ValueMetric metric = ValueMetricProducerTestHelper::createMetricWithCondition();
//
// sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>();
@@ -1184,7 +1126,8 @@
// return true;
// }));
// sp<ValueMetricProducer> valueProducer =
-// ValueMetricProducerTestHelper::createValueProducerWithCondition(pullerManager, metric);
+// ValueMetricProducerTestHelper::createValueProducerWithCondition(pullerManager,
+// metric);
//
// valueProducer->onConditionChanged(true, bucketStartTimeNs + 8);
//
@@ -1192,8 +1135,8 @@
// EXPECT_EQ(1UL, valueProducer->mCurrentSlicedBucket.size());
// ValueMetricProducer::Interval curInterval =
// valueProducer->mCurrentSlicedBucket.begin()->second[0];
-// ValueMetricProducer::BaseInfo curBaseInfo = valueProducer->mCurrentBaseInfo.begin()->second[0];
-// EXPECT_EQ(true, curBaseInfo.hasBase);
+// ValueMetricProducer::BaseInfo curBaseInfo =
+// valueProducer->mCurrentBaseInfo.begin()->second[0]; EXPECT_EQ(true, curBaseInfo.hasBase);
// EXPECT_EQ(100, curBaseInfo.base.long_value);
// EXPECT_EQ(false, curInterval.hasValue);
// EXPECT_EQ(0UL, valueProducer->mPastBuckets.size());
@@ -1219,10 +1162,11 @@
//}
//
///*
-// * Test pulled event with non sliced condition. The pull on boundary come late, after the condition
+// * Test pulled event with non sliced condition. The pull on boundary come late, after the
+// condition
// * change to false, and then true again. This is due to alarm delivered late.
// */
-//TEST(ValueMetricProducerTest, TestBucketBoundaryWithCondition2) {
+// TEST(ValueMetricProducerTest, TestBucketBoundaryWithCondition2) {
// ValueMetric metric = ValueMetricProducerTestHelper::createMetricWithCondition();
//
// sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>();
@@ -1250,16 +1194,15 @@
// // condition becomes true again
// .WillOnce(Invoke([](int tagId, vector<std::shared_ptr<LogEvent>>* data) {
// data->clear();
-// shared_ptr<LogEvent> event = make_shared<LogEvent>(tagId, bucket2StartTimeNs + 25);
-// event->write(tagId);
-// event->write(130);
-// event->init();
+// shared_ptr<LogEvent> event = make_shared<LogEvent>(tagId, bucket2StartTimeNs +
+// 25); event->write(tagId); event->write(130); event->init();
// data->push_back(event);
// return true;
// }));
//
// sp<ValueMetricProducer> valueProducer =
-// ValueMetricProducerTestHelper::createValueProducerWithCondition(pullerManager, metric);
+// ValueMetricProducerTestHelper::createValueProducerWithCondition(pullerManager,
+// metric);
//
// valueProducer->onConditionChanged(true, bucketStartTimeNs + 8);
//
@@ -1267,7 +1210,8 @@
// EXPECT_EQ(1UL, valueProducer->mCurrentSlicedBucket.size());
// ValueMetricProducer::Interval curInterval =
// valueProducer->mCurrentSlicedBucket.begin()->second[0];
-// ValueMetricProducer::BaseInfo curBaseInfo = valueProducer->mCurrentBaseInfo.begin()->second[0];
+// ValueMetricProducer::BaseInfo curBaseInfo =
+// valueProducer->mCurrentBaseInfo.begin()->second[0];
// // startUpdated:false sum:0 start:100
// EXPECT_EQ(true, curBaseInfo.hasBase);
// EXPECT_EQ(100, curBaseInfo.base.long_value);
@@ -1313,7 +1257,7 @@
// {bucketSizeNs - 8, bucketSizeNs - 24});
//}
//
-//TEST(ValueMetricProducerTest, TestPushedAggregateMin) {
+// TEST(ValueMetricProducerTest, TestPushedAggregateMin) {
// ValueMetric metric = ValueMetricProducerTestHelper::createMetric();
// metric.set_aggregation_type(ValueMetric::MIN);
//
@@ -1327,8 +1271,8 @@
// sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>();
//
// ValueMetricProducer valueProducer(kConfigKey, metric, -1, wizard, logEventMatcherIndex,
-// eventMatcherWizard, -1, bucketStartTimeNs, bucketStartTimeNs,
-// pullerManager);
+// eventMatcherWizard, -1, bucketStartTimeNs,
+// bucketStartTimeNs, pullerManager);
//
// shared_ptr<LogEvent> event1 = make_shared<LogEvent>(tagId, bucketStartTimeNs + 10);
// event1->write(1);
@@ -1357,7 +1301,7 @@
// assertPastBucketValuesSingleKey(valueProducer.mPastBuckets, {10}, {bucketSizeNs});
//}
//
-//TEST(ValueMetricProducerTest, TestPushedAggregateMax) {
+// TEST(ValueMetricProducerTest, TestPushedAggregateMax) {
// ValueMetric metric = ValueMetricProducerTestHelper::createMetric();
// metric.set_aggregation_type(ValueMetric::MAX);
//
@@ -1371,8 +1315,8 @@
// sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>();
//
// ValueMetricProducer valueProducer(kConfigKey, metric, -1, wizard, logEventMatcherIndex,
-// eventMatcherWizard, -1, bucketStartTimeNs, bucketStartTimeNs,
-// pullerManager);
+// eventMatcherWizard, -1, bucketStartTimeNs,
+// bucketStartTimeNs, pullerManager);
//
// shared_ptr<LogEvent> event1 = make_shared<LogEvent>(tagId, bucketStartTimeNs + 10);
// event1->write(1);
@@ -1403,7 +1347,7 @@
// /* EXPECT_EQ(20, valueProducer.mPastBuckets.begin()->second.back().values[0].long_value); */
//}
//
-//TEST(ValueMetricProducerTest, TestPushedAggregateAvg) {
+// TEST(ValueMetricProducerTest, TestPushedAggregateAvg) {
// ValueMetric metric = ValueMetricProducerTestHelper::createMetric();
// metric.set_aggregation_type(ValueMetric::AVG);
//
@@ -1417,8 +1361,8 @@
// sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>();
//
// ValueMetricProducer valueProducer(kConfigKey, metric, -1, wizard, logEventMatcherIndex,
-// eventMatcherWizard, -1, bucketStartTimeNs, bucketStartTimeNs,
-// pullerManager);
+// eventMatcherWizard, -1, bucketStartTimeNs,
+// bucketStartTimeNs, pullerManager);
//
// shared_ptr<LogEvent> event1 = make_shared<LogEvent>(tagId, bucketStartTimeNs + 10);
// event1->write(1);
@@ -1449,11 +1393,12 @@
// EXPECT_EQ(1UL, valueProducer.mPastBuckets.size());
// EXPECT_EQ(1UL, valueProducer.mPastBuckets.begin()->second.size());
//
-// EXPECT_TRUE(std::abs(valueProducer.mPastBuckets.begin()->second.back().values[0].double_value -
+// EXPECT_TRUE(std::abs(valueProducer.mPastBuckets.begin()->second.back().values[0].double_value
+// -
// 12.5) < epsilon);
//}
//
-//TEST(ValueMetricProducerTest, TestPushedAggregateSum) {
+// TEST(ValueMetricProducerTest, TestPushedAggregateSum) {
// ValueMetric metric = ValueMetricProducerTestHelper::createMetric();
// metric.set_aggregation_type(ValueMetric::SUM);
//
@@ -1467,8 +1412,8 @@
// sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>();
//
// ValueMetricProducer valueProducer(kConfigKey, metric, -1, wizard, logEventMatcherIndex,
-// eventMatcherWizard, -1, bucketStartTimeNs, bucketStartTimeNs,
-// pullerManager);
+// eventMatcherWizard, -1, bucketStartTimeNs,
+// bucketStartTimeNs, pullerManager);
//
// shared_ptr<LogEvent> event1 = make_shared<LogEvent>(tagId, bucketStartTimeNs + 10);
// event1->write(1);
@@ -1497,7 +1442,7 @@
// assertPastBucketValuesSingleKey(valueProducer.mPastBuckets, {25}, {bucketSizeNs});
//}
//
-//TEST(ValueMetricProducerTest, TestSkipZeroDiffOutput) {
+// TEST(ValueMetricProducerTest, TestSkipZeroDiffOutput) {
// ValueMetric metric = ValueMetricProducerTestHelper::createMetric();
// metric.set_aggregation_type(ValueMetric::MIN);
// metric.set_use_diff(true);
@@ -1512,8 +1457,8 @@
// sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>();
//
// ValueMetricProducer valueProducer(kConfigKey, metric, -1, wizard, logEventMatcherIndex,
-// eventMatcherWizard, -1, bucketStartTimeNs, bucketStartTimeNs,
-// pullerManager);
+// eventMatcherWizard, -1, bucketStartTimeNs,
+// bucketStartTimeNs, pullerManager);
//
// shared_ptr<LogEvent> event1 = make_shared<LogEvent>(tagId, bucketStartTimeNs + 10);
// event1->write(1);
@@ -1572,7 +1517,7 @@
// assertPastBucketValuesSingleKey(valueProducer.mPastBuckets, {5}, {bucketSizeNs});
//}
//
-//TEST(ValueMetricProducerTest, TestSkipZeroDiffOutputMultiValue) {
+// TEST(ValueMetricProducerTest, TestSkipZeroDiffOutputMultiValue) {
// ValueMetric metric = ValueMetricProducerTestHelper::createMetric();
// metric.mutable_value_field()->add_child()->set_field(3);
// metric.set_aggregation_type(ValueMetric::MIN);
@@ -1588,8 +1533,8 @@
// sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>();
//
// ValueMetricProducer valueProducer(kConfigKey, metric, -1, wizard, logEventMatcherIndex,
-// eventMatcherWizard, -1, bucketStartTimeNs, bucketStartTimeNs,
-// pullerManager);
+// eventMatcherWizard, -1, bucketStartTimeNs,
+// bucketStartTimeNs, pullerManager);
//
// shared_ptr<LogEvent> event1 = make_shared<LogEvent>(tagId, bucketStartTimeNs + 10);
// event1->write(1);
@@ -1687,7 +1632,7 @@
///*
// * Tests zero default base.
// */
-//TEST(ValueMetricProducerTest, TestUseZeroDefaultBase) {
+// TEST(ValueMetricProducerTest, TestUseZeroDefaultBase) {
// ValueMetric metric = ValueMetricProducerTestHelper::createMetric();
// metric.mutable_dimensions_in_what()->set_field(tagId);
// metric.mutable_dimensions_in_what()->add_child()->set_field(1);
@@ -1774,7 +1719,7 @@
///*
// * Tests using zero default base with failed pull.
// */
-//TEST(ValueMetricProducerTest, TestUseZeroDefaultBaseWithPullFailures) {
+// TEST(ValueMetricProducerTest, TestUseZeroDefaultBaseWithPullFailures) {
// ValueMetric metric = ValueMetricProducerTestHelper::createMetric();
// metric.mutable_dimensions_in_what()->set_field(tagId);
// metric.mutable_dimensions_in_what()->add_child()->set_field(1);
@@ -1885,8 +1830,9 @@
// it2 = std::next(valueProducer->mCurrentSlicedBucket.begin());
// interval1 = it->second[0];
// interval2 = it2->second[0];
-// baseInfo1 = valueProducer->mCurrentBaseInfo.find(it->first.getDimensionKeyInWhat())->second[0];
-// baseInfo2 = valueProducer->mCurrentBaseInfo.find(it2->first.getDimensionKeyInWhat())->second[0];
+// baseInfo1 =
+// valueProducer->mCurrentBaseInfo.find(it->first.getDimensionKeyInWhat())->second[0]; baseInfo2
+// = valueProducer->mCurrentBaseInfo.find(it2->first.getDimensionKeyInWhat())->second[0];
//
// EXPECT_EQ(true, baseInfo1.hasBase);
// EXPECT_EQ(5, baseInfo1.base.long_value);
@@ -1905,7 +1851,7 @@
///*
// * Tests trim unused dimension key if no new data is seen in an entire bucket.
// */
-//TEST(ValueMetricProducerTest, TestTrimUnusedDimensionKey) {
+// TEST(ValueMetricProducerTest, TestTrimUnusedDimensionKey) {
// ValueMetric metric = ValueMetricProducerTestHelper::createMetric();
// metric.mutable_dimensions_in_what()->set_field(tagId);
// metric.mutable_dimensions_in_what()->add_child()->set_field(1);
@@ -2023,7 +1969,7 @@
// EXPECT_EQ(bucketSizeNs, iterator->second[0].mConditionTrueNs);
//}
//
-//TEST(ValueMetricProducerTest, TestResetBaseOnPullFailAfterConditionChange_EndOfBucket) {
+// TEST(ValueMetricProducerTest, TestResetBaseOnPullFailAfterConditionChange_EndOfBucket) {
// ValueMetric metric = ValueMetricProducerTestHelper::createMetricWithCondition();
//
// sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>();
@@ -2040,15 +1986,16 @@
// }));
//
// sp<ValueMetricProducer> valueProducer =
-// ValueMetricProducerTestHelper::createValueProducerWithCondition(pullerManager, metric);
+// ValueMetricProducerTestHelper::createValueProducerWithCondition(pullerManager,
+// metric);
//
// valueProducer->onConditionChanged(true, bucketStartTimeNs + 8);
// // has one slice
// EXPECT_EQ(1UL, valueProducer->mCurrentSlicedBucket.size());
// ValueMetricProducer::Interval& curInterval =
// valueProducer->mCurrentSlicedBucket.begin()->second[0];
-// ValueMetricProducer::BaseInfo& curBaseInfo = valueProducer->mCurrentBaseInfo.begin()->second[0];
-// EXPECT_EQ(true, curBaseInfo.hasBase);
+// ValueMetricProducer::BaseInfo& curBaseInfo =
+// valueProducer->mCurrentBaseInfo.begin()->second[0]; EXPECT_EQ(true, curBaseInfo.hasBase);
// EXPECT_EQ(100, curBaseInfo.base.long_value);
// EXPECT_EQ(false, curInterval.hasValue);
//
@@ -2060,7 +2007,7 @@
// EXPECT_EQ(false, valueProducer->mHasGlobalBase);
//}
//
-//TEST(ValueMetricProducerTest, TestResetBaseOnPullFailAfterConditionChange) {
+// TEST(ValueMetricProducerTest, TestResetBaseOnPullFailAfterConditionChange) {
// ValueMetric metric = ValueMetricProducerTestHelper::createMetricWithCondition();
//
// sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>();
@@ -2077,7 +2024,8 @@
// .WillOnce(Return(false));
//
// sp<ValueMetricProducer> valueProducer =
-// ValueMetricProducerTestHelper::createValueProducerWithCondition(pullerManager, metric);
+// ValueMetricProducerTestHelper::createValueProducerWithCondition(pullerManager,
+// metric);
//
// valueProducer->onConditionChanged(true, bucketStartTimeNs + 8);
//
@@ -2085,8 +2033,8 @@
// EXPECT_EQ(1UL, valueProducer->mCurrentSlicedBucket.size());
// ValueMetricProducer::Interval& curInterval =
// valueProducer->mCurrentSlicedBucket.begin()->second[0];
-// ValueMetricProducer::BaseInfo& curBaseInfo = valueProducer->mCurrentBaseInfo.begin()->second[0];
-// EXPECT_EQ(true, curBaseInfo.hasBase);
+// ValueMetricProducer::BaseInfo& curBaseInfo =
+// valueProducer->mCurrentBaseInfo.begin()->second[0]; EXPECT_EQ(true, curBaseInfo.hasBase);
// EXPECT_EQ(100, curBaseInfo.base.long_value);
// EXPECT_EQ(false, curInterval.hasValue);
// EXPECT_EQ(0UL, valueProducer->mPastBuckets.size());
@@ -2100,7 +2048,7 @@
// EXPECT_EQ(false, valueProducer->mHasGlobalBase);
//}
//
-//TEST(ValueMetricProducerTest, TestResetBaseOnPullFailBeforeConditionChange) {
+// TEST(ValueMetricProducerTest, TestResetBaseOnPullFailBeforeConditionChange) {
// ValueMetric metric = ValueMetricProducerTestHelper::createMetricWithCondition();
//
// sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>();
@@ -2125,7 +2073,8 @@
// }));
//
// sp<ValueMetricProducer> valueProducer =
-// ValueMetricProducerTestHelper::createValueProducerWithCondition(pullerManager, metric);
+// ValueMetricProducerTestHelper::createValueProducerWithCondition(pullerManager,
+// metric);
//
// // Don't directly set mCondition; the real code never does that. Go through regular code path
// // to avoid unexpected behaviors.
@@ -2138,13 +2087,13 @@
// EXPECT_EQ(1UL, valueProducer->mCurrentSlicedBucket.size());
// ValueMetricProducer::Interval& curInterval =
// valueProducer->mCurrentSlicedBucket.begin()->second[0];
-// ValueMetricProducer::BaseInfo curBaseInfo = valueProducer->mCurrentBaseInfo.begin()->second[0];
-// EXPECT_EQ(false, curBaseInfo.hasBase);
+// ValueMetricProducer::BaseInfo curBaseInfo =
+// valueProducer->mCurrentBaseInfo.begin()->second[0]; EXPECT_EQ(false, curBaseInfo.hasBase);
// EXPECT_EQ(false, curInterval.hasValue);
// EXPECT_EQ(false, valueProducer->mHasGlobalBase);
//}
//
-//TEST(ValueMetricProducerTest, TestResetBaseOnPullDelayExceeded) {
+// TEST(ValueMetricProducerTest, TestResetBaseOnPullDelayExceeded) {
// ValueMetric metric = ValueMetricProducerTestHelper::createMetric();
// metric.set_condition(StringToId("SCREEN_ON"));
// metric.set_max_pull_delay_sec(0);
@@ -2162,7 +2111,8 @@
// }));
//
// sp<ValueMetricProducer> valueProducer =
-// ValueMetricProducerTestHelper::createValueProducerWithCondition(pullerManager, metric);
+// ValueMetricProducerTestHelper::createValueProducerWithCondition(pullerManager,
+// metric);
//
// valueProducer->mCondition = ConditionState::kFalse;
//
@@ -2171,7 +2121,7 @@
// EXPECT_EQ(0UL, valueProducer->mCurrentSlicedBucket.size());
//}
//
-//TEST(ValueMetricProducerTest, TestResetBaseOnPullTooLate) {
+// TEST(ValueMetricProducerTest, TestResetBaseOnPullTooLate) {
// ValueMetric metric = ValueMetricProducerTestHelper::createMetricWithCondition();
//
// UidMap uidMap;
@@ -2196,7 +2146,7 @@
// EXPECT_EQ(0UL, valueProducer.mCurrentSlicedBucket.size());
//}
//
-//TEST(ValueMetricProducerTest, TestBaseSetOnConditionChange) {
+// TEST(ValueMetricProducerTest, TestBaseSetOnConditionChange) {
// ValueMetric metric = ValueMetricProducerTestHelper::createMetricWithCondition();
//
// sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>();
@@ -2212,7 +2162,8 @@
// }));
//
// sp<ValueMetricProducer> valueProducer =
-// ValueMetricProducerTestHelper::createValueProducerWithCondition(pullerManager, metric);
+// ValueMetricProducerTestHelper::createValueProducerWithCondition(pullerManager,
+// metric);
//
// valueProducer->mCondition = ConditionState::kFalse;
// valueProducer->mHasGlobalBase = false;
@@ -2222,8 +2173,8 @@
// EXPECT_EQ(1UL, valueProducer->mCurrentSlicedBucket.size());
// ValueMetricProducer::Interval& curInterval =
// valueProducer->mCurrentSlicedBucket.begin()->second[0];
-// ValueMetricProducer::BaseInfo curBaseInfo = valueProducer->mCurrentBaseInfo.begin()->second[0];
-// EXPECT_EQ(true, curBaseInfo.hasBase);
+// ValueMetricProducer::BaseInfo curBaseInfo =
+// valueProducer->mCurrentBaseInfo.begin()->second[0]; EXPECT_EQ(true, curBaseInfo.hasBase);
// EXPECT_EQ(100, curBaseInfo.base.long_value);
// EXPECT_EQ(false, curInterval.hasValue);
// EXPECT_EQ(true, valueProducer->mHasGlobalBase);
@@ -2232,7 +2183,7 @@
///*
// * Tests that a bucket is marked invalid when a condition change pull fails.
// */
-//TEST(ValueMetricProducerTest_BucketDrop, TestInvalidBucketWhenOneConditionFailed) {
+// TEST(ValueMetricProducerTest_BucketDrop, TestInvalidBucketWhenOneConditionFailed) {
// ValueMetric metric = ValueMetricProducerTestHelper::createMetricWithCondition();
//
// sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>();
@@ -2251,7 +2202,8 @@
// }));
//
// sp<ValueMetricProducer> valueProducer =
-// ValueMetricProducerTestHelper::createValueProducerWithCondition(pullerManager, metric);
+// ValueMetricProducerTestHelper::createValueProducerWithCondition(pullerManager,
+// metric);
//
// valueProducer->mCondition = ConditionState::kTrue;
//
@@ -2286,8 +2238,8 @@
// EXPECT_EQ(1UL, valueProducer->mCurrentSlicedBucket.size());
// ValueMetricProducer::Interval& curInterval =
// valueProducer->mCurrentSlicedBucket.begin()->second[0];
-// ValueMetricProducer::BaseInfo curBaseInfo = valueProducer->mCurrentBaseInfo.begin()->second[0];
-// EXPECT_EQ(true, curBaseInfo.hasBase);
+// ValueMetricProducer::BaseInfo curBaseInfo =
+// valueProducer->mCurrentBaseInfo.begin()->second[0]; EXPECT_EQ(true, curBaseInfo.hasBase);
// EXPECT_EQ(140, curBaseInfo.base.long_value);
// EXPECT_EQ(false, curInterval.hasValue);
// EXPECT_EQ(true, valueProducer->mHasGlobalBase);
@@ -2317,7 +2269,7 @@
///*
// * Tests that a bucket is marked invalid when the guardrail is hit.
// */
-//TEST(ValueMetricProducerTest_BucketDrop, TestInvalidBucketWhenGuardRailHit) {
+// TEST(ValueMetricProducerTest_BucketDrop, TestInvalidBucketWhenGuardRailHit) {
// ValueMetric metric = ValueMetricProducerTestHelper::createMetric();
// metric.mutable_dimensions_in_what()->set_field(tagId);
// metric.mutable_dimensions_in_what()->add_child()->set_field(1);
@@ -2339,7 +2291,8 @@
// }));
//
// sp<ValueMetricProducer> valueProducer =
-// ValueMetricProducerTestHelper::createValueProducerWithCondition(pullerManager, metric);
+// ValueMetricProducerTestHelper::createValueProducerWithCondition(pullerManager,
+// metric);
// valueProducer->mCondition = ConditionState::kFalse;
//
// valueProducer->onConditionChanged(true, bucketStartTimeNs + 2);
@@ -2385,7 +2338,7 @@
///*
// * Tests that a bucket is marked invalid when the bucket's initial pull fails.
// */
-//TEST(ValueMetricProducerTest_BucketDrop, TestInvalidBucketWhenInitialPullFailed) {
+// TEST(ValueMetricProducerTest_BucketDrop, TestInvalidBucketWhenInitialPullFailed) {
// ValueMetric metric = ValueMetricProducerTestHelper::createMetricWithCondition();
//
// sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>();
@@ -2412,7 +2365,8 @@
// }));
//
// sp<ValueMetricProducer> valueProducer =
-// ValueMetricProducerTestHelper::createValueProducerWithCondition(pullerManager, metric);
+// ValueMetricProducerTestHelper::createValueProducerWithCondition(pullerManager,
+// metric);
//
// valueProducer->mCondition = ConditionState::kTrue;
//
@@ -2445,8 +2399,8 @@
// EXPECT_EQ(1UL, valueProducer->mCurrentSlicedBucket.size());
// ValueMetricProducer::Interval& curInterval =
// valueProducer->mCurrentSlicedBucket.begin()->second[0];
-// ValueMetricProducer::BaseInfo curBaseInfo = valueProducer->mCurrentBaseInfo.begin()->second[0];
-// EXPECT_EQ(true, curBaseInfo.hasBase);
+// ValueMetricProducer::BaseInfo curBaseInfo =
+// valueProducer->mCurrentBaseInfo.begin()->second[0]; EXPECT_EQ(true, curBaseInfo.hasBase);
// EXPECT_EQ(140, curBaseInfo.base.long_value);
// EXPECT_EQ(false, curInterval.hasValue);
// EXPECT_EQ(true, valueProducer->mHasGlobalBase);
@@ -2477,7 +2431,7 @@
// * Tests that a bucket is marked invalid when the bucket's final pull fails
// * (i.e. failed pull on bucket boundary).
// */
-//TEST(ValueMetricProducerTest_BucketDrop, TestInvalidBucketWhenLastPullFailed) {
+// TEST(ValueMetricProducerTest_BucketDrop, TestInvalidBucketWhenLastPullFailed) {
// ValueMetric metric = ValueMetricProducerTestHelper::createMetricWithCondition();
//
// sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>();
@@ -2504,7 +2458,8 @@
// }));
//
// sp<ValueMetricProducer> valueProducer =
-// ValueMetricProducerTestHelper::createValueProducerWithCondition(pullerManager, metric);
+// ValueMetricProducerTestHelper::createValueProducerWithCondition(pullerManager,
+// metric);
//
// valueProducer->mCondition = ConditionState::kTrue;
//
@@ -2537,8 +2492,8 @@
// EXPECT_EQ(1UL, valueProducer->mCurrentSlicedBucket.size());
// ValueMetricProducer::Interval& curInterval =
// valueProducer->mCurrentSlicedBucket.begin()->second[0];
-// ValueMetricProducer::BaseInfo curBaseInfo = valueProducer->mCurrentBaseInfo.begin()->second[0];
-// EXPECT_EQ(false, curBaseInfo.hasBase);
+// ValueMetricProducer::BaseInfo curBaseInfo =
+// valueProducer->mCurrentBaseInfo.begin()->second[0]; EXPECT_EQ(false, curBaseInfo.hasBase);
// EXPECT_EQ(false, curInterval.hasValue);
// EXPECT_EQ(false, valueProducer->mHasGlobalBase);
//
@@ -2564,7 +2519,7 @@
// EXPECT_EQ(NanoToMillis(bucket2StartTimeNs), dropEvent.drop_time_millis());
//}
//
-//TEST(ValueMetricProducerTest, TestEmptyDataResetsBase_onDataPulled) {
+// TEST(ValueMetricProducerTest, TestEmptyDataResetsBase_onDataPulled) {
// ValueMetric metric = ValueMetricProducerTestHelper::createMetric();
// sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>();
// EXPECT_CALL(*pullerManager, Pull(tagId, _))
@@ -2605,7 +2560,7 @@
// EXPECT_EQ(1UL, valueProducer->mPastBuckets.size());
//}
//
-//TEST(ValueMetricProducerTest, TestEmptyDataResetsBase_onConditionChanged) {
+// TEST(ValueMetricProducerTest, TestEmptyDataResetsBase_onConditionChanged) {
// ValueMetric metric = ValueMetricProducerTestHelper::createMetricWithCondition();
//
// sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>();
@@ -2626,14 +2581,15 @@
// }));
//
// sp<ValueMetricProducer> valueProducer =
-// ValueMetricProducerTestHelper::createValueProducerWithCondition(pullerManager, metric);
+// ValueMetricProducerTestHelper::createValueProducerWithCondition(pullerManager,
+// metric);
//
// valueProducer->onConditionChanged(true, bucketStartTimeNs + 10);
// EXPECT_EQ(1UL, valueProducer->mCurrentSlicedBucket.size());
// ValueMetricProducer::Interval& curInterval =
// valueProducer->mCurrentSlicedBucket.begin()->second[0];
-// ValueMetricProducer::BaseInfo curBaseInfo = valueProducer->mCurrentBaseInfo.begin()->second[0];
-// EXPECT_EQ(true, curBaseInfo.hasBase);
+// ValueMetricProducer::BaseInfo curBaseInfo =
+// valueProducer->mCurrentBaseInfo.begin()->second[0]; EXPECT_EQ(true, curBaseInfo.hasBase);
// EXPECT_EQ(false, curInterval.hasValue);
// EXPECT_EQ(true, valueProducer->mHasGlobalBase);
//
@@ -2647,7 +2603,7 @@
// EXPECT_EQ(false, valueProducer->mHasGlobalBase);
//}
//
-//TEST(ValueMetricProducerTest, TestEmptyDataResetsBase_onBucketBoundary) {
+// TEST(ValueMetricProducerTest, TestEmptyDataResetsBase_onBucketBoundary) {
// ValueMetric metric = ValueMetricProducerTestHelper::createMetricWithCondition();
//
// sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>();
@@ -2682,7 +2638,8 @@
// }));
//
// sp<ValueMetricProducer> valueProducer =
-// ValueMetricProducerTestHelper::createValueProducerWithCondition(pullerManager, metric);
+// ValueMetricProducerTestHelper::createValueProducerWithCondition(pullerManager,
+// metric);
//
// valueProducer->onConditionChanged(true, bucketStartTimeNs + 10);
// valueProducer->onConditionChanged(false, bucketStartTimeNs + 11);
@@ -2690,8 +2647,8 @@
// EXPECT_EQ(1UL, valueProducer->mCurrentSlicedBucket.size());
// ValueMetricProducer::Interval& curInterval =
// valueProducer->mCurrentSlicedBucket.begin()->second[0];
-// ValueMetricProducer::BaseInfo curBaseInfo = valueProducer->mCurrentBaseInfo.begin()->second[0];
-// EXPECT_EQ(true, curBaseInfo.hasBase);
+// ValueMetricProducer::BaseInfo curBaseInfo =
+// valueProducer->mCurrentBaseInfo.begin()->second[0]; EXPECT_EQ(true, curBaseInfo.hasBase);
// EXPECT_EQ(true, curInterval.hasValue);
// EXPECT_EQ(true, valueProducer->mHasGlobalBase);
//
@@ -2712,7 +2669,7 @@
// assertPastBucketValuesSingleKey(valueProducer->mPastBuckets, {1}, {bucketSizeNs - 12 + 1});
//}
//
-//TEST(ValueMetricProducerTest, TestPartialResetOnBucketBoundaries) {
+// TEST(ValueMetricProducerTest, TestPartialResetOnBucketBoundaries) {
// ValueMetric metric = ValueMetricProducerTestHelper::createMetric();
// metric.mutable_dimensions_in_what()->set_field(tagId);
// metric.mutable_dimensions_in_what()->add_child()->set_field(1);
@@ -2733,7 +2690,8 @@
// }));
//
// sp<ValueMetricProducer> valueProducer =
-// ValueMetricProducerTestHelper::createValueProducerWithCondition(pullerManager, metric);
+// ValueMetricProducerTestHelper::createValueProducerWithCondition(pullerManager,
+// metric);
//
// valueProducer->onConditionChanged(true, bucketStartTimeNs + 10);
// EXPECT_EQ(1UL, valueProducer->mCurrentSlicedBucket.size());
@@ -2764,7 +2722,7 @@
// EXPECT_EQ(true, valueProducer->mHasGlobalBase);
//}
//
-//TEST(ValueMetricProducerTest, TestFullBucketResetWhenLastBucketInvalid) {
+// TEST(ValueMetricProducerTest, TestFullBucketResetWhenLastBucketInvalid) {
// ValueMetric metric = ValueMetricProducerTestHelper::createMetric();
//
// sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>();
@@ -2795,7 +2753,7 @@
// ASSERT_EQ(0UL, valueProducer->mCurrentFullBucket.size());
//}
//
-//TEST(ValueMetricProducerTest, TestBucketBoundariesOnConditionChange) {
+// TEST(ValueMetricProducerTest, TestBucketBoundariesOnConditionChange) {
// ValueMetric metric = ValueMetricProducerTestHelper::createMetricWithCondition();
// sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>();
// EXPECT_CALL(*pullerManager, Pull(tagId, _))
@@ -2815,7 +2773,8 @@
// }));
//
// sp<ValueMetricProducer> valueProducer =
-// ValueMetricProducerTestHelper::createValueProducerWithCondition(pullerManager, metric);
+// ValueMetricProducerTestHelper::createValueProducerWithCondition(pullerManager,
+// metric);
// valueProducer->mCondition = ConditionState::kUnknown;
//
// valueProducer->onConditionChanged(false, bucketStartTimeNs);
@@ -2841,7 +2800,7 @@
// assertPastBucketValuesSingleKey(valueProducer->mPastBuckets, {2}, {bucketSizeNs - 10});
//}
//
-//TEST(ValueMetricProducerTest, TestLateOnDataPulledWithoutDiff) {
+// TEST(ValueMetricProducerTest, TestLateOnDataPulledWithoutDiff) {
// ValueMetric metric = ValueMetricProducerTestHelper::createMetric();
// metric.set_use_diff(false);
//
@@ -2861,7 +2820,7 @@
// assertPastBucketValuesSingleKey(valueProducer->mPastBuckets, {30}, {bucketSizeNs});
//}
//
-//TEST(ValueMetricProducerTest, TestLateOnDataPulledWithDiff) {
+// TEST(ValueMetricProducerTest, TestLateOnDataPulledWithDiff) {
// ValueMetric metric = ValueMetricProducerTestHelper::createMetric();
//
// sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>();
@@ -2888,7 +2847,7 @@
// assertPastBucketValuesSingleKey(valueProducer->mPastBuckets, {19}, {bucketSizeNs});
//}
//
-//TEST(ValueMetricProducerTest, TestBucketBoundariesOnAppUpgrade) {
+// TEST(ValueMetricProducerTest, TestBucketBoundariesOnAppUpgrade) {
// ValueMetric metric = ValueMetricProducerTestHelper::createMetric();
//
// sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>();
@@ -2916,7 +2875,7 @@
// assertPastBucketValuesSingleKey(valueProducer->mPastBuckets, {9}, {bucketSizeNs});
//}
//
-//TEST(ValueMetricProducerTest, TestDataIsNotUpdatedWhenNoConditionChanged) {
+// TEST(ValueMetricProducerTest, TestDataIsNotUpdatedWhenNoConditionChanged) {
// ValueMetric metric = ValueMetricProducerTestHelper::createMetricWithCondition();
//
// sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>();
@@ -2935,7 +2894,8 @@
// }));
//
// sp<ValueMetricProducer> valueProducer =
-// ValueMetricProducerTestHelper::createValueProducerWithCondition(pullerManager, metric);
+// ValueMetricProducerTestHelper::createValueProducerWithCondition(pullerManager,
+// metric);
//
// valueProducer->onConditionChanged(true, bucketStartTimeNs + 8);
// valueProducer->onConditionChanged(false, bucketStartTimeNs + 10);
@@ -2955,7 +2915,7 @@
//}
//
//// TODO: b/145705635 fix or delete this test
-//TEST(ValueMetricProducerTest, TestBucketInvalidIfGlobalBaseIsNotSet) {
+// TEST(ValueMetricProducerTest, TestBucketInvalidIfGlobalBaseIsNotSet) {
// ValueMetric metric = ValueMetricProducerTestHelper::createMetricWithCondition();
//
// sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>();
@@ -2969,18 +2929,19 @@
// // 2nd condition change.
// .WillOnce(Invoke([](int tagId, vector<std::shared_ptr<LogEvent>>* data) {
// data->clear();
-// data->push_back(ValueMetricProducerTestHelper::createEvent(bucket2StartTimeNs, 1));
-// return true;
+// data->push_back(ValueMetricProducerTestHelper::createEvent(bucket2StartTimeNs,
+// 1)); return true;
// }))
// // 3rd condition change.
// .WillOnce(Invoke([](int tagId, vector<std::shared_ptr<LogEvent>>* data) {
// data->clear();
-// data->push_back(ValueMetricProducerTestHelper::createEvent(bucket2StartTimeNs, 1));
-// return true;
+// data->push_back(ValueMetricProducerTestHelper::createEvent(bucket2StartTimeNs,
+// 1)); return true;
// }));
//
// sp<ValueMetricProducer> valueProducer =
-// ValueMetricProducerTestHelper::createValueProducerWithCondition(pullerManager, metric);
+// ValueMetricProducerTestHelper::createValueProducerWithCondition(pullerManager,
+// metric);
// valueProducer->onConditionChanged(true, bucket2StartTimeNs + 10);
//
// vector<shared_ptr<LogEvent>> allData;
@@ -3002,7 +2963,7 @@
// assertPastBucketValuesSingleKey(valueProducer->mPastBuckets, {}, {});
//}
//
-//TEST(ValueMetricProducerTest, TestPullNeededFastDump) {
+// TEST(ValueMetricProducerTest, TestPullNeededFastDump) {
// ValueMetric metric = ValueMetricProducerTestHelper::createMetric();
//
// UidMap uidMap;
@@ -3043,7 +3004,7 @@
// EXPECT_EQ(0, report.value_metrics().data_size());
//}
//
-//TEST(ValueMetricProducerTest, TestFastDumpWithoutCurrentBucket) {
+// TEST(ValueMetricProducerTest, TestFastDumpWithoutCurrentBucket) {
// ValueMetric metric = ValueMetricProducerTestHelper::createMetric();
//
// UidMap uidMap;
@@ -3095,7 +3056,7 @@
// EXPECT_EQ(0, report.value_metrics().data(0).bucket_info(0).bucket_num());
//}
//
-//TEST(ValueMetricProducerTest, TestPullNeededNoTimeConstraints) {
+// TEST(ValueMetricProducerTest, TestPullNeededNoTimeConstraints) {
// ValueMetric metric = ValueMetricProducerTestHelper::createMetric();
//
// UidMap uidMap;
@@ -3147,7 +3108,7 @@
// EXPECT_EQ(2, report.value_metrics().data(0).bucket_info(0).values(0).value_long());
//}
//
-//TEST(ValueMetricProducerTest, TestPulledData_noDiff_withoutCondition) {
+// TEST(ValueMetricProducerTest, TestPulledData_noDiff_withoutCondition) {
// ValueMetric metric = ValueMetricProducerTestHelper::createMetric();
// metric.set_use_diff(false);
//
@@ -3163,7 +3124,7 @@
// assertPastBucketValuesSingleKey(valueProducer->mPastBuckets, {10}, {bucketSizeNs});
//}
//
-//TEST(ValueMetricProducerTest, TestPulledData_noDiff_withMultipleConditionChanges) {
+// TEST(ValueMetricProducerTest, TestPulledData_noDiff_withMultipleConditionChanges) {
// ValueMetric metric = ValueMetricProducerTestHelper::createMetricWithCondition();
// metric.set_use_diff(false);
//
@@ -3184,7 +3145,8 @@
// return true;
// }));
// sp<ValueMetricProducer> valueProducer =
-// ValueMetricProducerTestHelper::createValueProducerWithCondition(pullerManager, metric);
+// ValueMetricProducerTestHelper::createValueProducerWithCondition(pullerManager,
+// metric);
// valueProducer->mCondition = ConditionState::kFalse;
//
// valueProducer->onConditionChanged(true, bucketStartTimeNs + 8);
@@ -3193,8 +3155,8 @@
// EXPECT_EQ(1UL, valueProducer->mCurrentSlicedBucket.size());
// ValueMetricProducer::Interval curInterval =
// valueProducer->mCurrentSlicedBucket.begin()->second[0];
-// ValueMetricProducer::BaseInfo curBaseInfo = valueProducer->mCurrentBaseInfo.begin()->second[0];
-// EXPECT_EQ(false, curBaseInfo.hasBase);
+// ValueMetricProducer::BaseInfo curBaseInfo =
+// valueProducer->mCurrentBaseInfo.begin()->second[0]; EXPECT_EQ(false, curBaseInfo.hasBase);
// EXPECT_EQ(true, curInterval.hasValue);
// EXPECT_EQ(20, curInterval.value.long_value);
//
@@ -3210,7 +3172,7 @@
// EXPECT_EQ(false, curInterval.hasValue);
//}
//
-//TEST(ValueMetricProducerTest, TestPulledData_noDiff_bucketBoundaryTrue) {
+// TEST(ValueMetricProducerTest, TestPulledData_noDiff_bucketBoundaryTrue) {
// ValueMetric metric = ValueMetricProducerTestHelper::createMetricWithCondition();
// metric.set_use_diff(false);
//
@@ -3224,7 +3186,8 @@
// return true;
// }));
// sp<ValueMetricProducer> valueProducer =
-// ValueMetricProducerTestHelper::createValueProducerWithCondition(pullerManager, metric);
+// ValueMetricProducerTestHelper::createValueProducerWithCondition(pullerManager,
+// metric);
// valueProducer->mCondition = ConditionState::kFalse;
//
// valueProducer->onConditionChanged(true, bucketStartTimeNs + 8);
@@ -3237,18 +3200,19 @@
// assertPastBucketValuesSingleKey(valueProducer->mPastBuckets, {30}, {bucketSizeNs - 8});
// ValueMetricProducer::Interval curInterval =
// valueProducer->mCurrentSlicedBucket.begin()->second[0];
-// ValueMetricProducer::BaseInfo curBaseInfo = valueProducer->mCurrentBaseInfo.begin()->second[0];
-// EXPECT_EQ(false, curBaseInfo.hasBase);
+// ValueMetricProducer::BaseInfo curBaseInfo =
+// valueProducer->mCurrentBaseInfo.begin()->second[0]; EXPECT_EQ(false, curBaseInfo.hasBase);
// EXPECT_EQ(false, curInterval.hasValue);
//}
//
-//TEST(ValueMetricProducerTest, TestPulledData_noDiff_bucketBoundaryFalse) {
+// TEST(ValueMetricProducerTest, TestPulledData_noDiff_bucketBoundaryFalse) {
// ValueMetric metric = ValueMetricProducerTestHelper::createMetricWithCondition();
// metric.set_use_diff(false);
//
// sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>();
// sp<ValueMetricProducer> valueProducer =
-// ValueMetricProducerTestHelper::createValueProducerWithCondition(pullerManager, metric);
+// ValueMetricProducerTestHelper::createValueProducerWithCondition(pullerManager,
+// metric);
// valueProducer->mCondition = ConditionState::kFalse;
//
// // Now the alarm is delivered. Condition is off though.
@@ -3260,7 +3224,7 @@
// assertPastBucketValuesSingleKey(valueProducer->mPastBuckets, {}, {});
//}
//
-//TEST(ValueMetricProducerTest, TestPulledData_noDiff_withFailure) {
+// TEST(ValueMetricProducerTest, TestPulledData_noDiff_withFailure) {
// ValueMetric metric = ValueMetricProducerTestHelper::createMetricWithCondition();
// metric.set_use_diff(false);
//
@@ -3275,7 +3239,8 @@
// }))
// .WillOnce(Return(false));
// sp<ValueMetricProducer> valueProducer =
-// ValueMetricProducerTestHelper::createValueProducerWithCondition(pullerManager, metric);
+// ValueMetricProducerTestHelper::createValueProducerWithCondition(pullerManager,
+// metric);
// valueProducer->mCondition = ConditionState::kFalse;
//
// valueProducer->onConditionChanged(true, bucketStartTimeNs + 8);
@@ -3300,7 +3265,7 @@
// * - the dump latency must be FAST
// */
//
-//TEST(ValueMetricProducerTest_BucketDrop, TestInvalidBucketWhenDumpReportRequested) {
+// TEST(ValueMetricProducerTest_BucketDrop, TestInvalidBucketWhenDumpReportRequested) {
// ValueMetric metric = ValueMetricProducerTestHelper::createMetricWithCondition();
//
// sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>();
@@ -3317,7 +3282,8 @@
// }));
//
// sp<ValueMetricProducer> valueProducer =
-// ValueMetricProducerTestHelper::createValueProducerWithCondition(pullerManager, metric);
+// ValueMetricProducerTestHelper::createValueProducerWithCondition(pullerManager,
+// metric);
//
// // Condition change event.
// valueProducer->onConditionChanged(true, bucketStartTimeNs + 20);
@@ -3348,7 +3314,7 @@
// * Test that EVENT_IN_WRONG_BUCKET dump reason is logged for a late condition
// * change event (i.e. the condition change occurs in the wrong bucket).
// */
-//TEST(ValueMetricProducerTest_BucketDrop, TestInvalidBucketWhenConditionEventWrongBucket) {
+// TEST(ValueMetricProducerTest_BucketDrop, TestInvalidBucketWhenConditionEventWrongBucket) {
// ValueMetric metric = ValueMetricProducerTestHelper::createMetricWithCondition();
//
// sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>();
@@ -3365,7 +3331,8 @@
// }));
//
// sp<ValueMetricProducer> valueProducer =
-// ValueMetricProducerTestHelper::createValueProducerWithCondition(pullerManager, metric);
+// ValueMetricProducerTestHelper::createValueProducerWithCondition(pullerManager,
+// metric);
//
// // Condition change event.
// valueProducer->onConditionChanged(true, bucketStartTimeNs + 50);
@@ -3408,7 +3375,7 @@
// * Test that EVENT_IN_WRONG_BUCKET dump reason is logged for a late accumulate
// * event (i.e. the accumulate events call occurs in the wrong bucket).
// */
-//TEST(ValueMetricProducerTest_BucketDrop, TestInvalidBucketWhenAccumulateEventWrongBucket) {
+// TEST(ValueMetricProducerTest_BucketDrop, TestInvalidBucketWhenAccumulateEventWrongBucket) {
// ValueMetric metric = ValueMetricProducerTestHelper::createMetricWithCondition();
//
// sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>();
@@ -3426,16 +3393,15 @@
// // Dump report requested.
// .WillOnce(Invoke([](int tagId, vector<std::shared_ptr<LogEvent>>* data) {
// data->clear();
-// shared_ptr<LogEvent> event = make_shared<LogEvent>(tagId, bucket2StartTimeNs + 100);
-// event->write("field1");
-// event->write(15);
-// event->init();
+// shared_ptr<LogEvent> event = make_shared<LogEvent>(tagId, bucket2StartTimeNs +
+// 100); event->write("field1"); event->write(15); event->init();
// data->push_back(event);
// return true;
// }));
//
// sp<ValueMetricProducer> valueProducer =
-// ValueMetricProducerTestHelper::createValueProducerWithCondition(pullerManager, metric);
+// ValueMetricProducerTestHelper::createValueProducerWithCondition(pullerManager,
+// metric);
//
// // Condition change event.
// valueProducer->onConditionChanged(true, bucketStartTimeNs + 50);
@@ -3485,7 +3451,7 @@
// * Test that CONDITION_UNKNOWN dump reason is logged due to an unknown condition
// * when a metric is initialized.
// */
-//TEST(ValueMetricProducerTest_BucketDrop, TestInvalidBucketWhenConditionUnknown) {
+// TEST(ValueMetricProducerTest_BucketDrop, TestInvalidBucketWhenConditionUnknown) {
// ValueMetric metric = ValueMetricProducerTestHelper::createMetricWithCondition();
//
// sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>();
@@ -3503,10 +3469,8 @@
// // Dump report requested.
// .WillOnce(Invoke([](int tagId, vector<std::shared_ptr<LogEvent>>* data) {
// data->clear();
-// shared_ptr<LogEvent> event = make_shared<LogEvent>(tagId, bucketStartTimeNs + 100);
-// event->write("field1");
-// event->write(15);
-// event->init();
+// shared_ptr<LogEvent> event = make_shared<LogEvent>(tagId, bucketStartTimeNs +
+// 100); event->write("field1"); event->write(15); event->init();
// data->push_back(event);
// return true;
// }));
@@ -3545,7 +3509,7 @@
// * Test that PULL_FAILED dump reason is logged due to a pull failure in
// * #pullAndMatchEventsLocked.
// */
-//TEST(ValueMetricProducerTest_BucketDrop, TestInvalidBucketWhenPullFailed) {
+// TEST(ValueMetricProducerTest_BucketDrop, TestInvalidBucketWhenPullFailed) {
// ValueMetric metric = ValueMetricProducerTestHelper::createMetricWithCondition();
//
// sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>();
@@ -3564,7 +3528,8 @@
// .WillOnce(Return(false));
//
// sp<ValueMetricProducer> valueProducer =
-// ValueMetricProducerTestHelper::createValueProducerWithCondition(pullerManager, metric);
+// ValueMetricProducerTestHelper::createValueProducerWithCondition(pullerManager,
+// metric);
//
// // Condition change event.
// valueProducer->onConditionChanged(true, bucketStartTimeNs + 50);
@@ -3596,7 +3561,7 @@
// * Test that MULTIPLE_BUCKETS_SKIPPED dump reason is logged when a log event
// * skips over more than one bucket.
// */
-//TEST(ValueMetricProducerTest_BucketDrop, TestInvalidBucketWhenMultipleBucketsSkipped) {
+// TEST(ValueMetricProducerTest_BucketDrop, TestInvalidBucketWhenMultipleBucketsSkipped) {
// ValueMetric metric = ValueMetricProducerTestHelper::createMetricWithCondition();
//
// sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>();
@@ -3624,7 +3589,8 @@
// }));
//
// sp<ValueMetricProducer> valueProducer =
-// ValueMetricProducerTestHelper::createValueProducerWithCondition(pullerManager, metric);
+// ValueMetricProducerTestHelper::createValueProducerWithCondition(pullerManager,
+// metric);
//
// // Condition change event.
// valueProducer->onConditionChanged(true, bucketStartTimeNs + 10);
@@ -3635,7 +3601,8 @@
// // Check dump report.
// ProtoOutputStream output;
// std::set<string> strSet;
-// valueProducer->onDumpReport(bucket4StartTimeNs + 1000, true /* include recent buckets */, true,
+// valueProducer->onDumpReport(bucket4StartTimeNs + 1000, true /* include recent buckets */,
+// true,
// NO_TIME_CONSTRAINTS /* dumpLatency */, &strSet, &output);
//
// StatsLogReport report = outputStreamToProto(&output);
@@ -3658,7 +3625,7 @@
// * Test that BUCKET_TOO_SMALL dump reason is logged when a flushed bucket size
// * is smaller than the "min_bucket_size_nanos" specified in the metric config.
// */
-//TEST(ValueMetricProducerTest_BucketDrop, TestBucketDropWhenBucketTooSmall) {
+// TEST(ValueMetricProducerTest_BucketDrop, TestBucketDropWhenBucketTooSmall) {
// ValueMetric metric = ValueMetricProducerTestHelper::createMetricWithCondition();
// metric.set_min_bucket_size_nanos(10000000000); // 10 seconds
//
@@ -3687,7 +3654,8 @@
// }));
//
// sp<ValueMetricProducer> valueProducer =
-// ValueMetricProducerTestHelper::createValueProducerWithCondition(pullerManager, metric);
+// ValueMetricProducerTestHelper::createValueProducerWithCondition(pullerManager,
+// metric);
//
// // Condition change event.
// valueProducer->onConditionChanged(true, bucketStartTimeNs + 10);
@@ -3718,7 +3686,7 @@
///*
// * Test multiple bucket drop events in the same bucket.
// */
-//TEST(ValueMetricProducerTest_BucketDrop, TestMultipleBucketDropEvents) {
+// TEST(ValueMetricProducerTest_BucketDrop, TestMultipleBucketDropEvents) {
// ValueMetric metric = ValueMetricProducerTestHelper::createMetricWithCondition();
//
// sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>();
@@ -3772,7 +3740,7 @@
// * Test that the number of logged bucket drop events is capped at the maximum.
// * The maximum is currently 10 and is set in MetricProducer::maxDropEventsReached().
// */
-//TEST(ValueMetricProducerTest_BucketDrop, TestMaxBucketDropEvents) {
+// TEST(ValueMetricProducerTest_BucketDrop, TestMaxBucketDropEvents) {
// ValueMetric metric = ValueMetricProducerTestHelper::createMetricWithCondition();
//
// sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>();
@@ -3800,10 +3768,8 @@
// .WillOnce(Return(false))
// .WillOnce(Invoke([](int tagId, vector<std::shared_ptr<LogEvent>>* data) {
// data->clear();
-// shared_ptr<LogEvent> event = make_shared<LogEvent>(tagId, bucketStartTimeNs + 220);
-// event->write("field1");
-// event->write(10);
-// event->init();
+// shared_ptr<LogEvent> event = make_shared<LogEvent>(tagId, bucketStartTimeNs +
+// 220); event->write("field1"); event->write(10); event->init();
// data->push_back(event);
// return true;
// }));
@@ -3896,7 +3862,7 @@
// * - Using diff
// * - Second field is value field
// */
-//TEST(ValueMetricProducerTest, TestSlicedState) {
+// TEST(ValueMetricProducerTest, TestSlicedState) {
// // Set up ValueMetricProducer.
// ValueMetric metric = ValueMetricProducerTestHelper::createMetricWithState("SCREEN_STATE");
// sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>();
@@ -3987,7 +3953,8 @@
// EXPECT_EQ(2, it->second[0].value.long_value);
//
// // Bucket status after screen state change ON->OFF.
-// screenEvent = CreateScreenStateChangedEvent(android::view::DisplayStateEnum::DISPLAY_STATE_OFF,
+// screenEvent =
+// CreateScreenStateChangedEvent(android::view::DisplayStateEnum::DISPLAY_STATE_OFF,
// bucketStartTimeNs + 10);
// StateManager::getInstance().onLogEvent(*screenEvent);
// EXPECT_EQ(2UL, valueProducer->mCurrentSlicedBucket.size());
@@ -4067,9 +4034,10 @@
// * - Using diff
// * - Second field is value field
// */
-//TEST(ValueMetricProducerTest, TestSlicedStateWithMap) {
+// TEST(ValueMetricProducerTest, TestSlicedStateWithMap) {
// // Set up ValueMetricProducer.
-// ValueMetric metric = ValueMetricProducerTestHelper::createMetricWithState("SCREEN_STATE_ONOFF");
+// ValueMetric metric =
+// ValueMetricProducerTestHelper::createMetricWithState("SCREEN_STATE_ONOFF");
// sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>();
// EXPECT_CALL(*pullerManager, Pull(tagId, _))
// // ValueMetricProducer initialized.
@@ -4189,7 +4157,8 @@
// EXPECT_EQ(2, it->second[0].value.long_value);
//
// // Bucket status after screen state change VR->OFF.
-// screenEvent = CreateScreenStateChangedEvent(android::view::DisplayStateEnum::DISPLAY_STATE_OFF,
+// screenEvent =
+// CreateScreenStateChangedEvent(android::view::DisplayStateEnum::DISPLAY_STATE_OFF,
// bucketStartTimeNs + 15);
// StateManager::getInstance().onLogEvent(*screenEvent);
// EXPECT_EQ(2UL, valueProducer->mCurrentSlicedBucket.size());
@@ -4243,9 +4212,10 @@
// * - Using diff
// * - Second field is value field
// */
-//TEST(ValueMetricProducerTest, TestSlicedStateWithPrimaryField_WithDimensions) {
+// TEST(ValueMetricProducerTest, TestSlicedStateWithPrimaryField_WithDimensions) {
// // Set up ValueMetricProducer.
-// ValueMetric metric = ValueMetricProducerTestHelper::createMetricWithState("UID_PROCESS_STATE");
+// ValueMetric metric =
+// ValueMetricProducerTestHelper::createMetricWithState("UID_PROCESS_STATE");
// metric.mutable_dimensions_in_what()->set_field(tagId);
// metric.mutable_dimensions_in_what()->add_child()->set_field(1);
//
@@ -4311,10 +4281,8 @@
// // Uid 1 process state change from Foreground -> Background
// .WillOnce(Invoke([](int tagId, vector<std::shared_ptr<LogEvent>>* data) {
// data->clear();
-// shared_ptr<LogEvent> event = make_shared<LogEvent>(tagId, bucket2StartTimeNs + 20);
-// event->write(1 /* uid */);
-// event->write(13);
-// event->init();
+// shared_ptr<LogEvent> event = make_shared<LogEvent>(tagId, bucket2StartTimeNs +
+// 20); event->write(1 /* uid */); event->write(13); event->init();
// data->push_back(event);
//
// // This event should be skipped.
@@ -4328,10 +4296,8 @@
// // Uid 1 process state change from Background -> Foreground
// .WillOnce(Invoke([](int tagId, vector<std::shared_ptr<LogEvent>>* data) {
// data->clear();
-// shared_ptr<LogEvent> event = make_shared<LogEvent>(tagId, bucket2StartTimeNs + 40);
-// event->write(1 /* uid */);
-// event->write(17);
-// event->init();
+// shared_ptr<LogEvent> event = make_shared<LogEvent>(tagId, bucket2StartTimeNs +
+// 40); event->write(1 /* uid */); event->write(17); event->init();
// data->push_back(event);
//
// // This event should be skipped.
@@ -4345,10 +4311,8 @@
// // Dump report pull.
// .WillOnce(Invoke([](int tagId, vector<std::shared_ptr<LogEvent>>* data) {
// data->clear();
-// shared_ptr<LogEvent> event = make_shared<LogEvent>(tagId, bucket2StartTimeNs + 50);
-// event->write(2 /* uid */);
-// event->write(20);
-// event->init();
+// shared_ptr<LogEvent> event = make_shared<LogEvent>(tagId, bucket2StartTimeNs +
+// 50); event->write(2 /* uid */); event->write(20); event->init();
// data->push_back(event);
//
// event = make_shared<LogEvent>(tagId, bucket2StartTimeNs + 50);
@@ -4393,7 +4357,8 @@
//
// // Bucket status after uid 1 process state change kStateUnknown -> Foreground.
// auto uidProcessEvent = CreateUidProcessStateChangedEvent(
-// 1 /* uid */, android::app::PROCESS_STATE_IMPORTANT_FOREGROUND, bucketStartTimeNs + 20);
+// 1 /* uid */, android::app::PROCESS_STATE_IMPORTANT_FOREGROUND, bucketStartTimeNs +
+// 20);
// StateManager::getInstance().onLogEvent(*uidProcessEvent);
// EXPECT_EQ(2UL, valueProducer->mCurrentSlicedBucket.size());
// // Base for dimension key {uid 1}.
@@ -4420,7 +4385,8 @@
//
// // Bucket status after uid 2 process state change kStateUnknown -> Background.
// uidProcessEvent = CreateUidProcessStateChangedEvent(
-// 2 /* uid */, android::app::PROCESS_STATE_IMPORTANT_BACKGROUND, bucketStartTimeNs + 40);
+// 2 /* uid */, android::app::PROCESS_STATE_IMPORTANT_BACKGROUND, bucketStartTimeNs +
+// 40);
// StateManager::getInstance().onLogEvent(*uidProcessEvent);
// EXPECT_EQ(2UL, valueProducer->mCurrentSlicedBucket.size());
// // Base for dimension key {uid 1}.
@@ -4499,7 +4465,8 @@
//
// // Bucket status after uid 1 process state change from Foreground -> Background.
// uidProcessEvent = CreateUidProcessStateChangedEvent(
-// 1 /* uid */, android::app::PROCESS_STATE_IMPORTANT_BACKGROUND, bucket2StartTimeNs + 20);
+// 1 /* uid */, android::app::PROCESS_STATE_IMPORTANT_BACKGROUND, bucket2StartTimeNs +
+// 20);
// StateManager::getInstance().onLogEvent(*uidProcessEvent);
//
// EXPECT_EQ(4UL, valueProducer->mCurrentSlicedBucket.size());
@@ -4533,7 +4500,8 @@
//
// // Bucket status after uid 1 process state change Background->Foreground.
// uidProcessEvent = CreateUidProcessStateChangedEvent(
-// 1 /* uid */, android::app::PROCESS_STATE_IMPORTANT_FOREGROUND, bucket2StartTimeNs + 40);
+// 1 /* uid */, android::app::PROCESS_STATE_IMPORTANT_FOREGROUND, bucket2StartTimeNs +
+// 40);
// StateManager::getInstance().onLogEvent(*uidProcessEvent);
//
// EXPECT_EQ(5UL, valueProducer->mCurrentSlicedBucket.size());
diff --git a/cmds/statsd/tests/statsd_test_util.cpp b/cmds/statsd/tests/statsd_test_util.cpp
index e2eee03..58eeed3 100644
--- a/cmds/statsd/tests/statsd_test_util.cpp
+++ b/cmds/statsd/tests/statsd_test_util.cpp
@@ -410,6 +410,127 @@
return dimensions;
}
+shared_ptr<LogEvent> CreateTwoValueLogEvent(int atomId, int64_t eventTimeNs, int32_t value1,
+ int32_t value2) {
+ AStatsEvent* statsEvent = AStatsEvent_obtain();
+ AStatsEvent_setAtomId(statsEvent, atomId);
+ AStatsEvent_overwriteTimestamp(statsEvent, eventTimeNs);
+
+ AStatsEvent_writeInt32(statsEvent, value1);
+ AStatsEvent_writeInt32(statsEvent, value2);
+ AStatsEvent_build(statsEvent);
+
+ size_t size;
+ uint8_t* buf = AStatsEvent_getBuffer(statsEvent, &size);
+ shared_ptr<LogEvent> logEvent = std::make_shared<LogEvent>(/*uid=*/0, /*pid=*/0);
+ logEvent->parseBuffer(buf, size);
+ AStatsEvent_release(statsEvent);
+
+ return logEvent;
+}
+//
+void CreateTwoValueLogEvent(LogEvent* logEvent, int atomId, int64_t eventTimeNs, int32_t value1,
+ int32_t value2) {
+ AStatsEvent* statsEvent = AStatsEvent_obtain();
+ AStatsEvent_setAtomId(statsEvent, atomId);
+ AStatsEvent_overwriteTimestamp(statsEvent, eventTimeNs);
+
+ AStatsEvent_writeInt32(statsEvent, value1);
+ AStatsEvent_writeInt32(statsEvent, value2);
+ AStatsEvent_build(statsEvent);
+
+ size_t size;
+ uint8_t* buf = AStatsEvent_getBuffer(statsEvent, &size);
+ logEvent->parseBuffer(buf, size);
+ AStatsEvent_release(statsEvent);
+}
+
+shared_ptr<LogEvent> CreateThreeValueLogEvent(int atomId, int64_t eventTimeNs, int32_t value1,
+ int32_t value2, int32_t value3) {
+ AStatsEvent* statsEvent = AStatsEvent_obtain();
+ AStatsEvent_setAtomId(statsEvent, atomId);
+ AStatsEvent_overwriteTimestamp(statsEvent, eventTimeNs);
+
+ AStatsEvent_writeInt32(statsEvent, value1);
+ AStatsEvent_writeInt32(statsEvent, value2);
+ AStatsEvent_writeInt32(statsEvent, value3);
+ AStatsEvent_build(statsEvent);
+
+ size_t size;
+ uint8_t* buf = AStatsEvent_getBuffer(statsEvent, &size);
+ shared_ptr<LogEvent> logEvent = std::make_shared<LogEvent>(/*uid=*/0, /*pid=*/0);
+ logEvent->parseBuffer(buf, size);
+ AStatsEvent_release(statsEvent);
+
+ return logEvent;
+}
+
+void CreateThreeValueLogEvent(LogEvent* logEvent, int atomId, int64_t eventTimeNs, int32_t value1,
+ int32_t value2, int32_t value3) {
+ AStatsEvent* statsEvent = AStatsEvent_obtain();
+ AStatsEvent_setAtomId(statsEvent, atomId);
+ AStatsEvent_overwriteTimestamp(statsEvent, eventTimeNs);
+
+ AStatsEvent_writeInt32(statsEvent, value1);
+ AStatsEvent_writeInt32(statsEvent, value2);
+ AStatsEvent_writeInt32(statsEvent, value3);
+ AStatsEvent_build(statsEvent);
+
+ size_t size;
+ uint8_t* buf = AStatsEvent_getBuffer(statsEvent, &size);
+ logEvent->parseBuffer(buf, size);
+ AStatsEvent_release(statsEvent);
+}
+
+shared_ptr<LogEvent> CreateRepeatedValueLogEvent(int atomId, int64_t eventTimeNs, int32_t value) {
+ AStatsEvent* statsEvent = AStatsEvent_obtain();
+ AStatsEvent_setAtomId(statsEvent, atomId);
+ AStatsEvent_overwriteTimestamp(statsEvent, eventTimeNs);
+
+ AStatsEvent_writeInt32(statsEvent, value);
+ AStatsEvent_writeInt32(statsEvent, value);
+ AStatsEvent_build(statsEvent);
+
+ size_t size;
+ uint8_t* buf = AStatsEvent_getBuffer(statsEvent, &size);
+ shared_ptr<LogEvent> logEvent = std::make_shared<LogEvent>(/*uid=*/0, /*pid=*/0);
+ logEvent->parseBuffer(buf, size);
+ AStatsEvent_release(statsEvent);
+
+ return logEvent;
+}
+
+void CreateRepeatedValueLogEvent(LogEvent* logEvent, int atomId, int64_t eventTimeNs,
+ int32_t value) {
+ AStatsEvent* statsEvent = AStatsEvent_obtain();
+ AStatsEvent_setAtomId(statsEvent, atomId);
+ AStatsEvent_overwriteTimestamp(statsEvent, eventTimeNs);
+
+ AStatsEvent_writeInt32(statsEvent, value);
+ AStatsEvent_writeInt32(statsEvent, value);
+ AStatsEvent_build(statsEvent);
+
+ size_t size;
+ uint8_t* buf = AStatsEvent_getBuffer(statsEvent, &size);
+ logEvent->parseBuffer(buf, size);
+ AStatsEvent_release(statsEvent);
+}
+
+shared_ptr<LogEvent> CreateNoValuesLogEvent(int atomId, int64_t eventTimeNs) {
+ AStatsEvent* statsEvent = AStatsEvent_obtain();
+ AStatsEvent_setAtomId(statsEvent, atomId);
+ AStatsEvent_overwriteTimestamp(statsEvent, eventTimeNs);
+ AStatsEvent_build(statsEvent);
+
+ size_t size;
+ uint8_t* buf = AStatsEvent_getBuffer(statsEvent, &size);
+ shared_ptr<LogEvent> logEvent = std::make_shared<LogEvent>(/*uid=*/0, /*pid=*/0);
+ logEvent->parseBuffer(buf, size);
+ AStatsEvent_release(statsEvent);
+
+ return logEvent;
+}
+
std::unique_ptr<LogEvent> CreateScreenStateChangedEvent(
uint64_t timestampNs, const android::view::DisplayStateEnum state) {
AStatsEvent* statsEvent = AStatsEvent_obtain();
diff --git a/cmds/statsd/tests/statsd_test_util.h b/cmds/statsd/tests/statsd_test_util.h
index 4371015..4c25ca3 100644
--- a/cmds/statsd/tests/statsd_test_util.h
+++ b/cmds/statsd/tests/statsd_test_util.h
@@ -164,6 +164,29 @@
FieldMatcher CreateAttributionUidDimensions(const int atomId,
const std::vector<Position>& positions);
+shared_ptr<LogEvent> CreateTwoValueLogEvent(int atomId, int64_t eventTimeNs, int32_t value1,
+ int32_t value2);
+
+void CreateTwoValueLogEvent(LogEvent* logEvent, int atomId, int64_t eventTimeNs, int32_t value1,
+ int32_t value2);
+
+shared_ptr<LogEvent> CreateThreeValueLogEvent(int atomId, int64_t eventTimeNs, int32_t value1,
+ int32_t value2, int32_t value3);
+
+void CreateThreeValueLogEvent(LogEvent* logEvent, int atomId, int64_t eventTimeNs, int32_t value1,
+ int32_t value2, int32_t value3);
+
+// The repeated value log event helpers create a log event with two int fields, both
+// set to the same value. This is useful for testing metrics that are only interested
+// in the value of the second field but still need the first field to be populated.
+std::shared_ptr<LogEvent> CreateRepeatedValueLogEvent(int atomId, int64_t eventTimeNs,
+ int32_t value);
+
+void CreateRepeatedValueLogEvent(LogEvent* logEvent, int atomId, int64_t eventTimeNs,
+ int32_t value);
+
+std::shared_ptr<LogEvent> CreateNoValuesLogEvent(int atomId, int64_t eventTimeNs);
+
// Create log event for screen state changed.
std::unique_ptr<LogEvent> CreateScreenStateChangedEvent(
uint64_t timestampNs, const android::view::DisplayStateEnum state);
diff --git a/config/hiddenapi-greylist-max-q.txt b/config/hiddenapi-greylist-max-q.txt
index a895a44..4832dd1 100644
--- a/config/hiddenapi-greylist-max-q.txt
+++ b/config/hiddenapi-greylist-max-q.txt
@@ -406,7 +406,6 @@
Lcom/android/internal/R$string;->enable_explore_by_touch_warning_title:I
Lcom/android/internal/R$string;->gigabyteShort:I
Lcom/android/internal/R$string;->kilobyteShort:I
-Lcom/android/internal/R$string;->map:I
Lcom/android/internal/R$string;->megabyteShort:I
Lcom/android/internal/R$string;->notification_title:I
Lcom/android/internal/R$string;->no_matches:I
diff --git a/core/java/android/app/ActivityManager.java b/core/java/android/app/ActivityManager.java
index 1a92b75..f4ee8fa 100644
--- a/core/java/android/app/ActivityManager.java
+++ b/core/java/android/app/ActivityManager.java
@@ -1315,7 +1315,8 @@
/**
* @return The in-memory or loaded icon that represents the current state of this task.
- * @deprecated This call is no longer supported.
+ * @deprecated This call is no longer supported. The caller should keep track of any icons
+ * it sets for the task descriptions internally.
*/
@Deprecated
public Bitmap getIcon() {
@@ -4242,8 +4243,6 @@
* {@code false} otherwise.
* @hide
*/
- @SystemApi
- @TestApi
@RequiresPermission(android.Manifest.permission.CHANGE_CONFIGURATION)
public boolean updateMccMncConfiguration(@NonNull String mcc, @NonNull String mnc) {
if (mcc == null || mnc == null) {
diff --git a/core/java/android/app/NotificationManager.java b/core/java/android/app/NotificationManager.java
index cbbdf63..811b9c0 100644
--- a/core/java/android/app/NotificationManager.java
+++ b/core/java/android/app/NotificationManager.java
@@ -1015,14 +1015,15 @@
}
/**
+ * Returns the currently applied notification policy.
+ *
* <p>
- * Gets the currently applied notification policy. If {@link #getCurrentInterruptionFilter}
- * is equal to {@link #INTERRUPTION_FILTER_ALL}, then the consolidated notification policy
- * will match the default notification policy returned by {@link #getNotificationPolicy}.
+ * If {@link #getCurrentInterruptionFilter} is equal to {@link #INTERRUPTION_FILTER_ALL},
+ * then the consolidated notification policy will match the default notification policy
+ * returned by {@link #getNotificationPolicy}.
* </p>
*/
- @Nullable
- public NotificationManager.Policy getConsolidatedNotificationPolicy() {
+ public @NonNull NotificationManager.Policy getConsolidatedNotificationPolicy() {
INotificationManager service = getService();
try {
return service.getConsolidatedNotificationPolicy();
diff --git a/core/java/android/app/ResourcesManager.java b/core/java/android/app/ResourcesManager.java
index 81671c3..9f5dee9 100644
--- a/core/java/android/app/ResourcesManager.java
+++ b/core/java/android/app/ResourcesManager.java
@@ -250,28 +250,6 @@
return dm;
}
- private static void applyNonDefaultDisplayMetricsToConfiguration(
- @NonNull DisplayMetrics dm, @NonNull Configuration config) {
- config.touchscreen = Configuration.TOUCHSCREEN_NOTOUCH;
- config.densityDpi = dm.densityDpi;
- config.screenWidthDp = (int) (dm.widthPixels / dm.density);
- config.screenHeightDp = (int) (dm.heightPixels / dm.density);
- int sl = Configuration.resetScreenLayout(config.screenLayout);
- if (dm.widthPixels > dm.heightPixels) {
- config.orientation = Configuration.ORIENTATION_LANDSCAPE;
- config.screenLayout = Configuration.reduceScreenLayout(sl,
- config.screenWidthDp, config.screenHeightDp);
- } else {
- config.orientation = Configuration.ORIENTATION_PORTRAIT;
- config.screenLayout = Configuration.reduceScreenLayout(sl,
- config.screenHeightDp, config.screenWidthDp);
- }
- config.smallestScreenWidthDp = Math.min(config.screenWidthDp, config.screenHeightDp);
- config.compatScreenWidthDp = config.screenWidthDp;
- config.compatScreenHeightDp = config.screenHeightDp;
- config.compatSmallestScreenWidthDp = config.smallestScreenWidthDp;
- }
-
public boolean applyCompatConfigurationLocked(int displayDensity,
@NonNull Configuration compatConfiguration) {
if (mResCompatibilityInfo != null && !mResCompatibilityInfo.supportsScreen()) {
@@ -519,17 +497,11 @@
private Configuration generateConfig(@NonNull ResourcesKey key, @NonNull DisplayMetrics dm) {
Configuration config;
- final boolean isDefaultDisplay = (key.mDisplayId == Display.DEFAULT_DISPLAY);
final boolean hasOverrideConfig = key.hasOverrideConfiguration();
- if (!isDefaultDisplay || hasOverrideConfig) {
+ if (hasOverrideConfig) {
config = new Configuration(getConfiguration());
- if (!isDefaultDisplay) {
- applyNonDefaultDisplayMetricsToConfiguration(dm, config);
- }
- if (hasOverrideConfig) {
- config.updateFrom(key.mOverrideConfiguration);
- if (DEBUG) Slog.v(TAG, "Applied overrideConfig=" + key.mOverrideConfiguration);
- }
+ config.updateFrom(key.mOverrideConfiguration);
+ if (DEBUG) Slog.v(TAG, "Applied overrideConfig=" + key.mOverrideConfiguration);
} else {
config = getConfiguration();
}
@@ -1110,8 +1082,6 @@
+ resourcesImpl + " config to: " + config);
}
int displayId = key.mDisplayId;
- final boolean hasOverrideConfiguration = key.hasOverrideConfiguration();
- tmpConfig.setTo(config);
// Get new DisplayMetrics based on the DisplayAdjustments given to the ResourcesImpl. Update
// a copy if the CompatibilityInfo changed, because the ResourcesImpl object will handle the
@@ -1121,15 +1091,12 @@
daj = new DisplayAdjustments(daj);
daj.setCompatibilityInfo(compat);
}
- daj.setConfiguration(config);
- DisplayMetrics dm = getDisplayMetrics(displayId, daj);
- if (displayId != Display.DEFAULT_DISPLAY) {
- applyNonDefaultDisplayMetricsToConfiguration(dm, tmpConfig);
- }
-
- if (hasOverrideConfiguration) {
+ tmpConfig.setTo(config);
+ if (key.hasOverrideConfiguration()) {
tmpConfig.updateFrom(key.mOverrideConfiguration);
}
+ daj.setConfiguration(tmpConfig);
+ DisplayMetrics dm = getDisplayMetrics(displayId, daj);
resourcesImpl.updateConfiguration(tmpConfig, dm, compat);
}
diff --git a/core/java/android/app/Service.java b/core/java/android/app/Service.java
index 81396fe..dc8269f 100644
--- a/core/java/android/app/Service.java
+++ b/core/java/android/app/Service.java
@@ -34,7 +34,6 @@
import android.os.IBinder;
import android.os.RemoteException;
import android.util.Log;
-import android.view.contentcapture.ContentCaptureManager;
import java.io.FileDescriptor;
import java.io.PrintWriter;
@@ -307,8 +306,7 @@
* {@sample development/samples/ApiDemos/src/com/example/android/apis/app/MessengerServiceActivities.java
* bind}
*/
-public abstract class Service extends ContextWrapper implements ComponentCallbacks2,
- ContentCaptureManager.ContentCaptureClient {
+public abstract class Service extends ContextWrapper implements ComponentCallbacks2 {
private static final String TAG = "Service";
/**
@@ -819,16 +817,8 @@
writer.println("nothing to dump");
}
- @Override
- protected void attachBaseContext(Context newBase) {
- super.attachBaseContext(newBase);
- if (newBase != null) {
- newBase.setContentCaptureOptions(getContentCaptureOptions());
- }
- }
-
// ------------------ Internal API ------------------
-
+
/**
* @hide
*/
@@ -845,7 +835,6 @@
mActivityManager = (IActivityManager)activityManager;
mStartCompatibility = getApplicationInfo().targetSdkVersion
< Build.VERSION_CODES.ECLAIR;
- setContentCaptureOptions(application.getContentCaptureOptions());
}
/**
@@ -860,18 +849,6 @@
return mClassName;
}
- /** @hide */
- @Override
- public final ContentCaptureManager.ContentCaptureClient getContentCaptureClient() {
- return this;
- }
-
- /** @hide */
- @Override
- public final ComponentName contentCaptureClientGetComponentName() {
- return new ComponentName(this, mClassName);
- }
-
// set by the thread after the constructor and before onCreate(Bundle icicle) is called.
@UnsupportedAppUsage
private ActivityThread mThread = null;
diff --git a/core/java/android/app/usage/NetworkStatsManager.java b/core/java/android/app/usage/NetworkStatsManager.java
index 5b98188..d6e7762 100644
--- a/core/java/android/app/usage/NetworkStatsManager.java
+++ b/core/java/android/app/usage/NetworkStatsManager.java
@@ -29,10 +29,10 @@
import android.net.DataUsageRequest;
import android.net.INetworkStatsService;
import android.net.NetworkIdentity;
+import android.net.NetworkStack;
import android.net.NetworkTemplate;
-import android.net.netstats.provider.AbstractNetworkStatsProvider;
-import android.net.netstats.provider.NetworkStatsProviderCallback;
-import android.net.netstats.provider.NetworkStatsProviderWrapper;
+import android.net.netstats.provider.INetworkStatsProviderCallback;
+import android.net.netstats.provider.NetworkStatsProvider;
import android.os.Binder;
import android.os.Handler;
import android.os.Looper;
@@ -527,32 +527,53 @@
/**
* Registers a custom provider of {@link android.net.NetworkStats} to provide network statistics
- * to the system. To unregister, invoke {@link NetworkStatsProviderCallback#unregister()}.
+ * to the system. To unregister, invoke {@link #unregisterNetworkStatsProvider}.
* Note that no de-duplication of statistics between providers is performed, so each provider
- * must only report network traffic that is not being reported by any other provider.
+ * must only report network traffic that is not being reported by any other provider. Also note
+ * that the provider cannot be re-registered after unregistering.
*
* @param tag a human readable identifier of the custom network stats provider. This is only
* used for debugging.
- * @param provider the subclass of {@link AbstractNetworkStatsProvider} that needs to be
+ * @param provider the subclass of {@link NetworkStatsProvider} that needs to be
* registered to the system.
- * @return a {@link NetworkStatsProviderCallback}, which can be used to report events to the
- * system or unregister the provider.
* @hide
*/
@SystemApi
- @RequiresPermission(android.Manifest.permission.UPDATE_DEVICE_STATS)
- @NonNull public NetworkStatsProviderCallback registerNetworkStatsProvider(
+ @RequiresPermission(anyOf = {
+ android.Manifest.permission.NETWORK_STATS_PROVIDER,
+ NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK})
+ @NonNull public void registerNetworkStatsProvider(
@NonNull String tag,
- @NonNull AbstractNetworkStatsProvider provider) {
+ @NonNull NetworkStatsProvider provider) {
try {
- final NetworkStatsProviderWrapper wrapper = new NetworkStatsProviderWrapper(provider);
- return new NetworkStatsProviderCallback(
- mService.registerNetworkStatsProvider(tag, wrapper));
+ if (provider.getProviderCallbackBinder() != null) {
+ throw new IllegalArgumentException("provider is already registered");
+ }
+ final INetworkStatsProviderCallback cbBinder =
+ mService.registerNetworkStatsProvider(tag, provider.getProviderBinder());
+ provider.setProviderCallbackBinder(cbBinder);
} catch (RemoteException e) {
e.rethrowAsRuntimeException();
}
- // Unreachable code, but compiler doesn't know about it.
- return null;
+ }
+
+ /**
+ * Unregisters an instance of {@link NetworkStatsProvider}.
+ *
+ * @param provider the subclass of {@link NetworkStatsProvider} that needs to be
+ * unregistered to the system.
+ * @hide
+ */
+ @SystemApi
+ @RequiresPermission(anyOf = {
+ android.Manifest.permission.NETWORK_STATS_PROVIDER,
+ NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK})
+ @NonNull public void unregisterNetworkStatsProvider(@NonNull NetworkStatsProvider provider) {
+ try {
+ provider.getProviderCallbackBinderOrThrow().unregister();
+ } catch (RemoteException e) {
+ e.rethrowAsRuntimeException();
+ }
}
private static NetworkTemplate createTemplate(int networkType, String subscriberId) {
diff --git a/core/java/android/companion/CompanionDeviceManager.java b/core/java/android/companion/CompanionDeviceManager.java
index d4b5b1a..4bd7b05 100644
--- a/core/java/android/companion/CompanionDeviceManager.java
+++ b/core/java/android/companion/CompanionDeviceManager.java
@@ -257,11 +257,22 @@
/**
* Check if a given package was {@link #associate associated} with a device with given
- * mac address by given user.
+ * Wi-Fi MAC address for a given user.
*
- * @param packageName the package to check for
- * @param macAddress the mac address or BSSID of the device to check for
- * @param user the user to check for
+ * <p>This is a system API protected by the
+ * {@link andrioid.Manifest.permission#MANAGE_COMPANION_DEVICES} permission, that’s currently
+ * called by the Android Wi-Fi stack to determine whether user consent is required to connect
+ * to a Wi-Fi network. Devices that have been pre-registered as companion devices will not
+ * require user consent to connect.</p>
+ *
+ * <p>Note if the caller has the
+ * {@link android.Manifest.permission#COMPANION_APPROVE_WIFI_CONNECTIONS} permission, this
+ * method will return true by default.</p>
+ *
+ * @param packageName the name of the package that has the association with the companion device
+ * @param macAddress the Wi-Fi MAC address or BSSID of the companion device to check for
+ * @param user the user handle that currently hosts the package being queried for a companion
+ * device association
* @return whether a corresponding association record exists
*
* @hide
diff --git a/core/java/android/content/pm/ILauncherApps.aidl b/core/java/android/content/pm/ILauncherApps.aidl
index 8a89840..27c9cfc 100644
--- a/core/java/android/content/pm/ILauncherApps.aidl
+++ b/core/java/android/content/pm/ILauncherApps.aidl
@@ -103,4 +103,7 @@
in UserHandle user);
void uncacheShortcuts(String callingPackage, String packageName, in List<String> shortcutIds,
in UserHandle user);
+
+ String getShortcutIconUri(String callingPackage, String packageName, String shortcutId,
+ int userId);
}
diff --git a/core/java/android/content/pm/LauncherApps.java b/core/java/android/content/pm/LauncherApps.java
index 4e4897f..e73fd03 100644
--- a/core/java/android/content/pm/LauncherApps.java
+++ b/core/java/android/content/pm/LauncherApps.java
@@ -51,6 +51,7 @@
import android.graphics.drawable.BitmapDrawable;
import android.graphics.drawable.Drawable;
import android.graphics.drawable.Icon;
+import android.net.Uri;
import android.os.Build;
import android.os.Bundle;
import android.os.Handler;
@@ -67,8 +68,10 @@
import android.util.Log;
import android.util.Pair;
+import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.util.function.pooled.PooledLambda;
+import java.io.FileNotFoundException;
import java.io.IOException;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
@@ -460,10 +463,7 @@
/**
* If non-null, return only the specified shortcuts by locus ID. When setting this field,
* a package name must also be set with {@link #setPackage}.
- *
- * @hide
*/
- @SystemApi
@NonNull
public ShortcutQuery setLocusIds(@Nullable List<LocusId> locusIds) {
mLocusIds = locusIds;
@@ -1201,6 +1201,35 @@
}
/**
+ * @hide internal/unit tests only
+ */
+ @VisibleForTesting
+ public ParcelFileDescriptor getUriShortcutIconFd(@NonNull ShortcutInfo shortcut) {
+ return getUriShortcutIconFd(shortcut.getPackage(), shortcut.getId(), shortcut.getUserId());
+ }
+
+ private ParcelFileDescriptor getUriShortcutIconFd(@NonNull String packageName,
+ @NonNull String shortcutId, int userId) {
+ String uri = null;
+ try {
+ uri = mService.getShortcutIconUri(mContext.getPackageName(), packageName, shortcutId,
+ userId);
+ } catch (RemoteException e) {
+ throw e.rethrowFromSystemServer();
+ }
+
+ if (uri == null) {
+ return null;
+ }
+ try {
+ return mContext.getContentResolver().openFileDescriptor(Uri.parse(uri), "r");
+ } catch (FileNotFoundException e) {
+ Log.e(TAG, "Icon file not found: " + uri);
+ return null;
+ }
+ }
+
+ /**
* Returns the icon for this shortcut, without any badging for the profile.
*
* <p>The calling launcher application must be allowed to access the shortcut information,
@@ -1220,26 +1249,10 @@
public Drawable getShortcutIconDrawable(@NonNull ShortcutInfo shortcut, int density) {
if (shortcut.hasIconFile()) {
final ParcelFileDescriptor pfd = getShortcutIconFd(shortcut);
- if (pfd == null) {
- return null;
- }
- try {
- final Bitmap bmp = BitmapFactory.decodeFileDescriptor(pfd.getFileDescriptor());
- if (bmp != null) {
- BitmapDrawable dr = new BitmapDrawable(mContext.getResources(), bmp);
- if (shortcut.hasAdaptiveBitmap()) {
- return new AdaptiveIconDrawable(null, dr);
- } else {
- return dr;
- }
- }
- return null;
- } finally {
- try {
- pfd.close();
- } catch (IOException ignore) {
- }
- }
+ return loadDrawableFromFileDescriptor(pfd, shortcut.hasAdaptiveBitmap());
+ } else if (shortcut.hasIconUri()) {
+ final ParcelFileDescriptor pfd = getUriShortcutIconFd(shortcut);
+ return loadDrawableFromFileDescriptor(pfd, shortcut.hasAdaptiveBitmap());
} else if (shortcut.hasIconResource()) {
return loadDrawableResourceFromPackage(shortcut.getPackage(),
shortcut.getIconResourceId(), shortcut.getUserHandle(), density);
@@ -1263,6 +1276,29 @@
}
}
+ private Drawable loadDrawableFromFileDescriptor(ParcelFileDescriptor pfd, boolean adaptive) {
+ if (pfd == null) {
+ return null;
+ }
+ try {
+ final Bitmap bmp = BitmapFactory.decodeFileDescriptor(pfd.getFileDescriptor());
+ if (bmp != null) {
+ BitmapDrawable dr = new BitmapDrawable(mContext.getResources(), bmp);
+ if (adaptive) {
+ return new AdaptiveIconDrawable(null, dr);
+ } else {
+ return dr;
+ }
+ }
+ return null;
+ } finally {
+ try {
+ pfd.close();
+ } catch (IOException ignore) {
+ }
+ }
+ }
+
private Drawable loadDrawableResourceFromPackage(String packageName, int resId,
UserHandle user, int density) {
try {
diff --git a/core/java/android/content/pm/ShortcutInfo.java b/core/java/android/content/pm/ShortcutInfo.java
index af87578..8d8776f 100644
--- a/core/java/android/content/pm/ShortcutInfo.java
+++ b/core/java/android/content/pm/ShortcutInfo.java
@@ -123,6 +123,9 @@
public static final int FLAG_CACHED = 1 << 14;
/** @hide */
+ public static final int FLAG_HAS_ICON_URI = 1 << 15;
+
+ /** @hide */
@IntDef(flag = true, prefix = { "FLAG_" }, value = {
FLAG_DYNAMIC,
FLAG_PINNED,
@@ -139,6 +142,7 @@
FLAG_SHADOW,
FLAG_LONG_LIVED,
FLAG_CACHED,
+ FLAG_HAS_ICON_URI,
})
@Retention(RetentionPolicy.SOURCE)
public @interface ShortcutFlags {}
@@ -401,6 +405,9 @@
private String mIconResName;
// Internal use only.
+ private String mIconUri;
+
+ // Internal use only.
@Nullable
private String mBitmapPath;
@@ -554,6 +561,7 @@
if ((cloneFlags & CLONE_REMOVE_ICON) == 0) {
mIcon = source.mIcon;
mBitmapPath = source.mBitmapPath;
+ mIconUri = source.mIconUri;
}
mTitle = source.mTitle;
@@ -856,6 +864,7 @@
mIconResId = 0;
mIconResName = null;
mBitmapPath = null;
+ mIconUri = null;
}
if (source.mTitle != null) {
mTitle = source.mTitle;
@@ -916,6 +925,8 @@
case Icon.TYPE_RESOURCE:
case Icon.TYPE_BITMAP:
case Icon.TYPE_ADAPTIVE_BITMAP:
+ case Icon.TYPE_URI:
+ case Icon.TYPE_URI_ADAPTIVE_BITMAP:
break; // OK
default:
throw getInvalidIconException();
@@ -1792,6 +1803,15 @@
return hasFlags(FLAG_HAS_ICON_RES);
}
+ /**
+ * Return whether a shortcut's icon is provided via a URI.
+ *
+ * @hide internal/unit tests only
+ */
+ public boolean hasIconUri() {
+ return hasFlags(FLAG_HAS_ICON_URI);
+ }
+
/** @hide */
public boolean hasStringResources() {
return (mTitleResId != 0) || (mTextResId != 0) || (mDisabledMessageResId != 0);
@@ -1911,6 +1931,19 @@
return mIconResId;
}
+ /** @hide */
+ public void setIconUri(String iconUri) {
+ mIconUri = iconUri;
+ }
+
+ /**
+ * Get the Uri for the icon, valid only when {@link #hasIconUri()} } is true.
+ * @hide internal / tests only.
+ */
+ public String getIconUri() {
+ return mIconUri;
+ }
+
/**
* Bitmap path. Note this will be null even if {@link #hasIconFile()} is set when the save
* is pending. Use {@link #isIconPendingSave()} to check it.
@@ -2062,6 +2095,7 @@
mPersons = source.readParcelableArray(cl, Person.class);
mLocusId = source.readParcelable(cl);
+ mIconUri = source.readString();
}
@Override
@@ -2112,6 +2146,7 @@
dest.writeParcelableArray(mPersons, flags);
dest.writeParcelable(mLocusId, flags);
+ dest.writeString(mIconUri);
}
public static final @android.annotation.NonNull Creator<ShortcutInfo> CREATOR =
@@ -2203,6 +2238,12 @@
if (hasIconResource()) {
sb.append("Ic-r");
}
+ if (hasIconUri()) {
+ sb.append("Ic-u");
+ }
+ if (hasAdaptiveBitmap()) {
+ sb.append("Ic-a");
+ }
if (hasKeyFieldsOnly()) {
sb.append("Key");
}
@@ -2325,6 +2366,9 @@
sb.append(", bitmapPath=");
sb.append(mBitmapPath);
+
+ sb.append(", iconUri=");
+ sb.append(mIconUri);
}
if (mLocusId != null) {
@@ -2343,8 +2387,8 @@
CharSequence disabledMessage, int disabledMessageResId, String disabledMessageResName,
Set<String> categories, Intent[] intentsWithExtras, int rank, PersistableBundle extras,
long lastChangedTimestamp,
- int flags, int iconResId, String iconResName, String bitmapPath, int disabledReason,
- Person[] persons, LocusId locusId) {
+ int flags, int iconResId, String iconResName, String bitmapPath, String iconUri,
+ int disabledReason, Person[] persons, LocusId locusId) {
mUserId = userId;
mId = id;
mPackageName = packageName;
@@ -2369,6 +2413,7 @@
mIconResId = iconResId;
mIconResName = iconResName;
mBitmapPath = bitmapPath;
+ mIconUri = iconUri;
mDisabledReason = disabledReason;
mPersons = persons;
mLocusId = locusId;
diff --git a/core/java/android/content/pm/ShortcutServiceInternal.java b/core/java/android/content/pm/ShortcutServiceInternal.java
index a50ce92..435c70a 100644
--- a/core/java/android/content/pm/ShortcutServiceInternal.java
+++ b/core/java/android/content/pm/ShortcutServiceInternal.java
@@ -103,4 +103,10 @@
*/
public abstract List<ShortcutManager.ShareShortcutInfo> getShareTargets(
@NonNull String callingPackage, @NonNull IntentFilter intentFilter, int userId);
+
+ /**
+ * Returns the icon Uri of the shortcut, and grants Uri read permission to the caller.
+ */
+ public abstract String getShortcutIconUri(int launcherUserId, @NonNull String launcherPackage,
+ @NonNull String packageName, @NonNull String shortcutId, int userId);
}
diff --git a/core/java/android/hardware/SensorEvent.java b/core/java/android/hardware/SensorEvent.java
index 5fbf0da..9906331 100644
--- a/core/java/android/hardware/SensorEvent.java
+++ b/core/java/android/hardware/SensorEvent.java
@@ -657,7 +657,9 @@
public int accuracy;
/**
- * The time in nanosecond at which the event happened
+ * The time in nanoseconds at which the event happened. For a given sensor,
+ * each new sensor event should be monotonically increasing using the same
+ * time base as {@link android.os.SystemClock#elapsedRealtimeNanos()}.
*/
public long timestamp;
diff --git a/core/java/android/net/NattKeepalivePacketData.java b/core/java/android/net/NattKeepalivePacketData.java
index bd39c13..29da495 100644
--- a/core/java/android/net/NattKeepalivePacketData.java
+++ b/core/java/android/net/NattKeepalivePacketData.java
@@ -20,6 +20,7 @@
import static android.net.InvalidPacketException.ERROR_INVALID_PORT;
import android.annotation.NonNull;
+import android.annotation.Nullable;
import android.annotation.SystemApi;
import android.net.util.IpUtils;
import android.os.Parcel;
@@ -30,6 +31,7 @@
import java.net.InetAddress;
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
+import java.util.Objects;
/** @hide */
@SystemApi
@@ -121,4 +123,19 @@
return new NattKeepalivePacketData[size];
}
};
+
+ @Override
+ public boolean equals(@Nullable final Object o) {
+ if (!(o instanceof NattKeepalivePacketData)) return false;
+ final NattKeepalivePacketData other = (NattKeepalivePacketData) o;
+ return this.srcAddress.equals(other.srcAddress)
+ && this.dstAddress.equals(other.dstAddress)
+ && this.srcPort == other.srcPort
+ && this.dstPort == other.dstPort;
+ }
+
+ @Override
+ public int hashCode() {
+ return Objects.hash(srcAddress, dstAddress, srcPort, dstPort);
+ }
}
diff --git a/core/java/android/net/NetworkStats.java b/core/java/android/net/NetworkStats.java
index 2f536ff..9c1fb41 100644
--- a/core/java/android/net/NetworkStats.java
+++ b/core/java/android/net/NetworkStats.java
@@ -21,7 +21,6 @@
import android.annotation.IntDef;
import android.annotation.NonNull;
import android.annotation.Nullable;
-import android.annotation.SuppressLint;
import android.annotation.SystemApi;
import android.compat.annotation.UnsupportedAppUsage;
import android.os.Parcel;
@@ -58,9 +57,12 @@
public final class NetworkStats implements Parcelable {
private static final String TAG = "NetworkStats";
- /** {@link #iface} value when interface details unavailable. */
- @SuppressLint("CompileTimeConstant")
+ /**
+ * {@link #iface} value when interface details unavailable.
+ * @hide
+ */
@Nullable public static final String IFACE_ALL = null;
+
/**
* Virtual network interface for video telephony. This is for VT data usage counting
* purpose.
@@ -248,7 +250,13 @@
@UnsupportedAppUsage
private long[] operations;
- /** @hide */
+ /**
+ * Basic element of network statistics. Contains the number of packets and number of bytes
+ * transferred on both directions in a given set of conditions. See
+ * {@link Entry#Entry(String, int, int, int, int, int, int, long, long, long, long, long)}.
+ *
+ * @hide
+ */
@SystemApi
public static class Entry {
/** @hide */
@@ -319,6 +327,35 @@
rxBytes, rxPackets, txBytes, txPackets, operations);
}
+ /**
+ * Construct a {@link Entry} object by giving statistics of packet and byte transferred on
+ * both direction, and associated with a set of given conditions.
+ *
+ * @param iface interface name of this {@link Entry}. Or null if not specified.
+ * @param uid uid of this {@link Entry}. {@link #UID_TETHERING} if this {@link Entry} is
+ * for tethering. Or {@link #UID_ALL} if this {@link NetworkStats} is only
+ * counting iface stats.
+ * @param set usage state of this {@link Entry}. Should be one of the following
+ * values: {@link #SET_DEFAULT}, {@link #SET_FOREGROUND}.
+ * @param tag tag of this {@link Entry}.
+ * @param metered metered state of this {@link Entry}. Should be one of the following
+ * values: {link #METERED_YES}, {link #METERED_NO}.
+ * @param roaming roaming state of this {@link Entry}. Should be one of the following
+ * values: {link #ROAMING_YES}, {link #ROAMING_NO}.
+ * @param defaultNetwork default network status of this {@link Entry}. Should be one
+ * of the following values: {link #DEFAULT_NETWORK_YES},
+ * {link #DEFAULT_NETWORK_NO}.
+ * @param rxBytes Number of bytes received for this {@link Entry}. Statistics should
+ * represent the contents of IP packets, including IP headers.
+ * @param rxPackets Number of packets received for this {@link Entry}. Statistics should
+ * represent the contents of IP packets, including IP headers.
+ * @param txBytes Number of bytes transmitted for this {@link Entry}. Statistics should
+ * represent the contents of IP packets, including IP headers.
+ * @param txPackets Number of bytes transmitted for this {@link Entry}. Statistics should
+ * represent the contents of IP packets, including IP headers.
+ * @param operations count of network operations performed for this {@link Entry}. This can
+ * be used to derive bytes-per-operation.
+ */
public Entry(@Nullable String iface, int uid, @State int set, int tag,
@Meteredness int metered, @Roaming int roaming, @DefaultNetwork int defaultNetwork,
long rxBytes, long rxPackets, long txBytes, long txPackets, long operations) {
@@ -466,7 +503,7 @@
NetworkStats.Entry entry = null;
for (int i = 0; i < size; i++) {
entry = getValues(i, entry);
- clone.addEntry(entry);
+ clone.insertEntry(entry);
}
return clone;
}
@@ -493,26 +530,26 @@
/** @hide */
@VisibleForTesting
- public NetworkStats addIfaceValues(
+ public NetworkStats insertEntry(
String iface, long rxBytes, long rxPackets, long txBytes, long txPackets) {
- return addEntry(
+ return insertEntry(
iface, UID_ALL, SET_DEFAULT, TAG_NONE, rxBytes, rxPackets, txBytes, txPackets, 0L);
}
/** @hide */
@VisibleForTesting
- public NetworkStats addEntry(String iface, int uid, int set, int tag, long rxBytes,
+ public NetworkStats insertEntry(String iface, int uid, int set, int tag, long rxBytes,
long rxPackets, long txBytes, long txPackets, long operations) {
- return addEntry(new Entry(
+ return insertEntry(new Entry(
iface, uid, set, tag, rxBytes, rxPackets, txBytes, txPackets, operations));
}
/** @hide */
@VisibleForTesting
- public NetworkStats addEntry(String iface, int uid, int set, int tag, int metered, int roaming,
- int defaultNetwork, long rxBytes, long rxPackets, long txBytes, long txPackets,
- long operations) {
- return addEntry(new Entry(
+ public NetworkStats insertEntry(String iface, int uid, int set, int tag, int metered,
+ int roaming, int defaultNetwork, long rxBytes, long rxPackets, long txBytes,
+ long txPackets, long operations) {
+ return insertEntry(new Entry(
iface, uid, set, tag, metered, roaming, defaultNetwork, rxBytes, rxPackets,
txBytes, txPackets, operations));
}
@@ -522,7 +559,7 @@
* object can be recycled across multiple calls.
* @hide
*/
- public NetworkStats addEntry(Entry entry) {
+ public NetworkStats insertEntry(Entry entry) {
if (size >= capacity) {
final int newLength = Math.max(size, 10) * 3 / 2;
iface = Arrays.copyOf(iface, newLength);
@@ -665,7 +702,7 @@
entry.roaming, entry.defaultNetwork);
if (i == -1) {
// only create new entry when positive contribution
- addEntry(entry);
+ insertEntry(entry);
} else {
rxBytes[i] += entry.rxBytes;
rxPackets[i] += entry.rxPackets;
@@ -684,7 +721,7 @@
* @param entry the {@link Entry} to add.
* @return a new constructed {@link NetworkStats} object that contains the result.
*/
- public @NonNull NetworkStats addValues(@NonNull Entry entry) {
+ public @NonNull NetworkStats addEntry(@NonNull Entry entry) {
return this.clone().combineValues(entry);
}
@@ -1003,7 +1040,7 @@
entry.operations = Math.max(entry.operations, 0);
}
- result.addEntry(entry);
+ result.insertEntry(entry);
}
return result;
diff --git a/core/java/android/net/netstats/provider/AbstractNetworkStatsProvider.java b/core/java/android/net/netstats/provider/AbstractNetworkStatsProvider.java
deleted file mode 100644
index 740aa92..0000000
--- a/core/java/android/net/netstats/provider/AbstractNetworkStatsProvider.java
+++ /dev/null
@@ -1,70 +0,0 @@
-/*
- * 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.net.netstats.provider;
-
-import android.annotation.NonNull;
-import android.annotation.SystemApi;
-import android.net.NetworkStats;
-
-/**
- * A base class that allows external modules to implement a custom network statistics provider.
- * @hide
- */
-@SystemApi
-public abstract class AbstractNetworkStatsProvider {
- /**
- * A value used by {@link #setLimit} and {@link #setAlert} indicates there is no limit.
- */
- public static final int QUOTA_UNLIMITED = -1;
-
- /**
- * Called by {@code NetworkStatsService} when global polling is needed. Custom
- * implementation of providers MUST respond to it by calling
- * {@link NetworkStatsProviderCallback#onStatsUpdated} within one minute. Responding
- * later than this may cause the stats to be dropped.
- *
- * @param token a positive number identifying the new state of the system under which
- * {@link NetworkStats} have to be gathered from now on. When this is called,
- * custom implementations of providers MUST report the latest stats with the
- * previous token, under which stats were being gathered so far.
- */
- public abstract void requestStatsUpdate(int token);
-
- /**
- * Called by {@code NetworkStatsService} when setting the interface quota for the specified
- * upstream interface. When this is called, the custom implementation should block all egress
- * packets on the {@code iface} associated with the provider when {@code quotaBytes} bytes have
- * been reached, and MUST respond to it by calling
- * {@link NetworkStatsProviderCallback#onLimitReached()}.
- *
- * @param iface the interface requiring the operation.
- * @param quotaBytes the quota defined as the number of bytes, starting from zero and counting
- * from now. A value of {@link #QUOTA_UNLIMITED} indicates there is no limit.
- */
- public abstract void setLimit(@NonNull String iface, long quotaBytes);
-
- /**
- * Called by {@code NetworkStatsService} when setting the alert bytes. Custom implementations
- * MUST call {@link NetworkStatsProviderCallback#onAlertReached()} when {@code quotaBytes} bytes
- * have been reached. Unlike {@link #setLimit(String, long)}, the custom implementation should
- * not block all egress packets.
- *
- * @param quotaBytes the quota defined as the number of bytes, starting from zero and counting
- * from now. A value of {@link #QUOTA_UNLIMITED} indicates there is no alert.
- */
- public abstract void setAlert(long quotaBytes);
-}
diff --git a/core/java/android/net/netstats/provider/INetworkStatsProvider.aidl b/core/java/android/net/netstats/provider/INetworkStatsProvider.aidl
index 55b3d4e..4078b24 100644
--- a/core/java/android/net/netstats/provider/INetworkStatsProvider.aidl
+++ b/core/java/android/net/netstats/provider/INetworkStatsProvider.aidl
@@ -22,7 +22,7 @@
* @hide
*/
oneway interface INetworkStatsProvider {
- void requestStatsUpdate(int token);
- void setLimit(String iface, long quotaBytes);
- void setAlert(long quotaBytes);
+ void onRequestStatsUpdate(int token);
+ void onSetLimit(String iface, long quotaBytes);
+ void onSetAlert(long quotaBytes);
}
diff --git a/core/java/android/net/netstats/provider/INetworkStatsProviderCallback.aidl b/core/java/android/net/netstats/provider/INetworkStatsProviderCallback.aidl
index 3ea9318..bd336dd 100644
--- a/core/java/android/net/netstats/provider/INetworkStatsProviderCallback.aidl
+++ b/core/java/android/net/netstats/provider/INetworkStatsProviderCallback.aidl
@@ -24,8 +24,8 @@
* @hide
*/
oneway interface INetworkStatsProviderCallback {
- void onStatsUpdated(int token, in NetworkStats ifaceStats, in NetworkStats uidStats);
- void onAlertReached();
- void onLimitReached();
+ void notifyStatsUpdated(int token, in NetworkStats ifaceStats, in NetworkStats uidStats);
+ void notifyAlertReached();
+ void notifyLimitReached();
void unregister();
}
diff --git a/core/java/android/net/netstats/provider/NetworkStatsProvider.java b/core/java/android/net/netstats/provider/NetworkStatsProvider.java
new file mode 100644
index 0000000..7639d22
--- /dev/null
+++ b/core/java/android/net/netstats/provider/NetworkStatsProvider.java
@@ -0,0 +1,195 @@
+/*
+ * 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.net.netstats.provider;
+
+import android.annotation.NonNull;
+import android.annotation.Nullable;
+import android.annotation.SystemApi;
+import android.net.NetworkStats;
+import android.os.RemoteException;
+
+/**
+ * A base class that allows external modules to implement a custom network statistics provider.
+ * @hide
+ */
+@SystemApi
+public abstract class NetworkStatsProvider {
+ /**
+ * A value used by {@link #onSetLimit} and {@link #onSetAlert} indicates there is no limit.
+ */
+ public static final int QUOTA_UNLIMITED = -1;
+
+ @NonNull private final INetworkStatsProvider mProviderBinder =
+ new INetworkStatsProvider.Stub() {
+
+ @Override
+ public void onRequestStatsUpdate(int token) {
+ NetworkStatsProvider.this.onRequestStatsUpdate(token);
+ }
+
+ @Override
+ public void onSetLimit(String iface, long quotaBytes) {
+ NetworkStatsProvider.this.onSetLimit(iface, quotaBytes);
+ }
+
+ @Override
+ public void onSetAlert(long quotaBytes) {
+ NetworkStatsProvider.this.onSetAlert(quotaBytes);
+ }
+ };
+
+ // The binder given by the service when successfully registering. Only null before registering,
+ // never null once non-null.
+ @Nullable
+ private INetworkStatsProviderCallback mProviderCbBinder;
+
+ /**
+ * Return the binder invoked by the service and redirect function calls to the overridden
+ * methods.
+ * @hide
+ */
+ @NonNull
+ public INetworkStatsProvider getProviderBinder() {
+ return mProviderBinder;
+ }
+
+ /**
+ * Store the binder that was returned by the service when successfully registering. Note that
+ * the provider cannot be re-registered. Hence this method can only be called once per provider.
+ *
+ * @hide
+ */
+ public void setProviderCallbackBinder(@NonNull INetworkStatsProviderCallback binder) {
+ if (mProviderCbBinder != null) {
+ throw new IllegalArgumentException("provider is already registered");
+ }
+ mProviderCbBinder = binder;
+ }
+
+ /**
+ * Get the binder that was returned by the service when successfully registering. Or null if the
+ * provider was never registered.
+ *
+ * @hide
+ */
+ @Nullable
+ public INetworkStatsProviderCallback getProviderCallbackBinder() {
+ return mProviderCbBinder;
+ }
+
+ /**
+ * Get the binder that was returned by the service when successfully registering. Throw an
+ * {@link IllegalStateException} if the provider is not registered.
+ *
+ * @hide
+ */
+ @NonNull
+ public INetworkStatsProviderCallback getProviderCallbackBinderOrThrow() {
+ if (mProviderCbBinder == null) {
+ throw new IllegalStateException("the provider is not registered");
+ }
+ return mProviderCbBinder;
+ }
+
+ /**
+ * Notify the system of new network statistics.
+ *
+ * Send the network statistics recorded since the last call to {@link #notifyStatsUpdated}. Must
+ * be called as soon as possible after {@link NetworkStatsProvider#onRequestStatsUpdate(int)}
+ * being called. Responding later increases the probability stats will be dropped. The
+ * provider can also call this whenever it wants to reports new stats for any reason.
+ * Note that the system will not necessarily immediately propagate the statistics to
+ * reflect the update.
+ *
+ * @param token the token under which these stats were gathered. Providers can call this method
+ * with the current token as often as they want, until the token changes.
+ * {@see NetworkStatsProvider#onRequestStatsUpdate()}
+ * @param ifaceStats the {@link NetworkStats} per interface to be reported.
+ * The provider should not include any traffic that is already counted by
+ * kernel interface counters.
+ * @param uidStats the same stats as above, but counts {@link NetworkStats}
+ * per uid.
+ */
+ public void notifyStatsUpdated(int token, @NonNull NetworkStats ifaceStats,
+ @NonNull NetworkStats uidStats) {
+ try {
+ getProviderCallbackBinderOrThrow().notifyStatsUpdated(token, ifaceStats, uidStats);
+ } catch (RemoteException e) {
+ e.rethrowAsRuntimeException();
+ }
+ }
+
+ /**
+ * Notify system that the quota set by {@code onSetAlert} has been reached.
+ */
+ public void notifyAlertReached() {
+ try {
+ getProviderCallbackBinderOrThrow().notifyAlertReached();
+ } catch (RemoteException e) {
+ e.rethrowAsRuntimeException();
+ }
+ }
+
+ /**
+ * Notify system that the quota set by {@code onSetLimit} has been reached.
+ */
+ public void notifyLimitReached() {
+ try {
+ getProviderCallbackBinderOrThrow().notifyLimitReached();
+ } catch (RemoteException e) {
+ e.rethrowAsRuntimeException();
+ }
+ }
+
+ /**
+ * Called by {@code NetworkStatsService} when it requires to know updated stats.
+ * The provider MUST respond by calling {@link #notifyStatsUpdated} as soon as possible.
+ * Responding later increases the probability stats will be dropped. Memory allowing, the
+ * system will try to take stats into account up to one minute after calling
+ * {@link #onRequestStatsUpdate}.
+ *
+ * @param token a positive number identifying the new state of the system under which
+ * {@link NetworkStats} have to be gathered from now on. When this is called,
+ * custom implementations of providers MUST tally and report the latest stats with
+ * the previous token, under which stats were being gathered so far.
+ */
+ public abstract void onRequestStatsUpdate(int token);
+
+ /**
+ * Called by {@code NetworkStatsService} when setting the interface quota for the specified
+ * upstream interface. When this is called, the custom implementation should block all egress
+ * packets on the {@code iface} associated with the provider when {@code quotaBytes} bytes have
+ * been reached, and MUST respond to it by calling
+ * {@link NetworkStatsProvider#notifyLimitReached()}.
+ *
+ * @param iface the interface requiring the operation.
+ * @param quotaBytes the quota defined as the number of bytes, starting from zero and counting
+ * from now. A value of {@link #QUOTA_UNLIMITED} indicates there is no limit.
+ */
+ public abstract void onSetLimit(@NonNull String iface, long quotaBytes);
+
+ /**
+ * Called by {@code NetworkStatsService} when setting the alert bytes. Custom implementations
+ * MUST call {@link NetworkStatsProvider#notifyAlertReached()} when {@code quotaBytes} bytes
+ * have been reached. Unlike {@link #onSetLimit(String, long)}, the custom implementation should
+ * not block all egress packets.
+ *
+ * @param quotaBytes the quota defined as the number of bytes, starting from zero and counting
+ * from now. A value of {@link #QUOTA_UNLIMITED} indicates there is no alert.
+ */
+ public abstract void onSetAlert(long quotaBytes);
+}
diff --git a/core/java/android/net/netstats/provider/NetworkStatsProviderCallback.java b/core/java/android/net/netstats/provider/NetworkStatsProviderCallback.java
deleted file mode 100644
index e17a8ee..0000000
--- a/core/java/android/net/netstats/provider/NetworkStatsProviderCallback.java
+++ /dev/null
@@ -1,98 +0,0 @@
-/*
- * 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.net.netstats.provider;
-
-import android.annotation.NonNull;
-import android.annotation.SuppressLint;
-import android.annotation.SystemApi;
-import android.net.NetworkStats;
-import android.os.RemoteException;
-
-/**
- * A callback class that allows callers to report events to the system.
- * @hide
- */
-@SystemApi
-@SuppressLint("CallbackMethodName")
-public class NetworkStatsProviderCallback {
- @NonNull private final INetworkStatsProviderCallback mBinder;
-
- /** @hide */
- public NetworkStatsProviderCallback(@NonNull INetworkStatsProviderCallback binder) {
- mBinder = binder;
- }
-
- /**
- * Notify the system of new network statistics.
- *
- * Send the network statistics recorded since the last call to {@link #onStatsUpdated}. Must be
- * called within one minute of {@link AbstractNetworkStatsProvider#requestStatsUpdate(int)}
- * being called. The provider can also call this whenever it wants to reports new stats for any
- * reason. Note that the system will not necessarily immediately propagate the statistics to
- * reflect the update.
- *
- * @param token the token under which these stats were gathered. Providers can call this method
- * with the current token as often as they want, until the token changes.
- * {@see AbstractNetworkStatsProvider#requestStatsUpdate()}
- * @param ifaceStats the {@link NetworkStats} per interface to be reported.
- * The provider should not include any traffic that is already counted by
- * kernel interface counters.
- * @param uidStats the same stats as above, but counts {@link NetworkStats}
- * per uid.
- */
- public void onStatsUpdated(int token, @NonNull NetworkStats ifaceStats,
- @NonNull NetworkStats uidStats) {
- try {
- mBinder.onStatsUpdated(token, ifaceStats, uidStats);
- } catch (RemoteException e) {
- e.rethrowAsRuntimeException();
- }
- }
-
- /**
- * Notify system that the quota set by {@code setAlert} has been reached.
- */
- public void onAlertReached() {
- try {
- mBinder.onAlertReached();
- } catch (RemoteException e) {
- e.rethrowAsRuntimeException();
- }
- }
-
- /**
- * Notify system that the quota set by {@code setLimit} has been reached.
- */
- public void onLimitReached() {
- try {
- mBinder.onLimitReached();
- } catch (RemoteException e) {
- e.rethrowAsRuntimeException();
- }
- }
-
- /**
- * Unregister the provider and the referencing callback.
- */
- public void unregister() {
- try {
- mBinder.unregister();
- } catch (RemoteException e) {
- // Ignore error.
- }
- }
-}
diff --git a/core/java/android/net/netstats/provider/NetworkStatsProviderWrapper.java b/core/java/android/net/netstats/provider/NetworkStatsProviderWrapper.java
deleted file mode 100644
index 4bf7c9b..0000000
--- a/core/java/android/net/netstats/provider/NetworkStatsProviderWrapper.java
+++ /dev/null
@@ -1,48 +0,0 @@
-/*
- * 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.net.netstats.provider;
-
-import android.annotation.NonNull;
-
-/**
- * A wrapper class of {@link INetworkStatsProvider} that hides the binder interface from exposing
- * to outer world.
- *
- * @hide
- */
-public class NetworkStatsProviderWrapper extends INetworkStatsProvider.Stub {
- @NonNull final AbstractNetworkStatsProvider mProvider;
-
- public NetworkStatsProviderWrapper(AbstractNetworkStatsProvider provider) {
- mProvider = provider;
- }
-
- @Override
- public void requestStatsUpdate(int token) {
- mProvider.requestStatsUpdate(token);
- }
-
- @Override
- public void setLimit(@NonNull String iface, long quotaBytes) {
- mProvider.setLimit(iface, quotaBytes);
- }
-
- @Override
- public void setAlert(long quotaBytes) {
- mProvider.setAlert(quotaBytes);
- }
-}
diff --git a/core/java/android/nfc/NfcAdapter.java b/core/java/android/nfc/NfcAdapter.java
index d320f61..c61f10f 100644
--- a/core/java/android/nfc/NfcAdapter.java
+++ b/core/java/android/nfc/NfcAdapter.java
@@ -245,13 +245,25 @@
/**
* Mandatory String extra field in {@link #ACTION_PREFERRED_PAYMENT_CHANGED}
- * Indicates the condition when trigger this event.
+ * Indicates the condition when trigger this event. Possible values are:
+ * {@link #PREFERRED_PAYMENT_LOADED},
+ * {@link #PREFERRED_PAYMENT_CHANGED},
+ * {@link #PREFERRED_PAYMENT_UPDATED},
*/
public static final String EXTRA_PREFERRED_PAYMENT_CHANGED_REASON =
"android.nfc.extra.PREFERRED_PAYMENT_CHANGED_REASON";
-
+ /**
+ * Nfc is enabled and the preferred payment aids are registered.
+ */
public static final int PREFERRED_PAYMENT_LOADED = 1;
+ /**
+ * User selected another payment application as the preferred payment.
+ */
public static final int PREFERRED_PAYMENT_CHANGED = 2;
+ /**
+ * Current preferred payment has issued an update (registered/unregistered new aids or has been
+ * updated itself).
+ */
public static final int PREFERRED_PAYMENT_UPDATED = 3;
public static final int STATE_OFF = 1;
diff --git a/core/java/android/nfc/cardemulation/CardEmulation.java b/core/java/android/nfc/cardemulation/CardEmulation.java
index f1c74a6..7bf82e8 100644
--- a/core/java/android/nfc/cardemulation/CardEmulation.java
+++ b/core/java/android/nfc/cardemulation/CardEmulation.java
@@ -672,7 +672,7 @@
recoverService();
if (sService == null) {
Log.e(TAG, "Failed to recover CardEmulationService.");
- return null;
+ throw e.rethrowFromSystemServer();
}
try {
ApduServiceInfo serviceInfo =
@@ -680,7 +680,7 @@
return (serviceInfo != null ? serviceInfo.getAids() : null);
} catch (RemoteException ee) {
Log.e(TAG, "Failed to recover CardEmulationService.");
- return null;
+ throw e.rethrowFromSystemServer();
}
}
}
@@ -690,9 +690,16 @@
*
* @return The route destination secure element name of the preferred payment service.
* HCE payment: "Host"
- * OffHost payment: prefix SIM or prefix eSE string.
- * "OffHost" if the payment service does not specify secure element
- * name.
+ * OffHost payment: 1. String with prefix SIM or prefix eSE string.
+ * Ref: GSMA TS.26 - NFC Handset Requirements
+ * TS26_NFC_REQ_069: For UICC, Secure Element Name SHALL be
+ * SIM[smartcard slot]
+ * (e.g. SIM/SIM1, SIM2… SIMn).
+ * TS26_NFC_REQ_070: For embedded SE, Secure Element Name SHALL be
+ * eSE[number]
+ * (e.g. eSE/eSE1, eSE2, etc.).
+ * 2. "OffHost" if the payment service does not specify secure element
+ * name.
*/
@RequiresPermission(android.Manifest.permission.NFC_PREFERRED_PAYMENT_INFO)
@Nullable
@@ -711,7 +718,7 @@
recoverService();
if (sService == null) {
Log.e(TAG, "Failed to recover CardEmulationService.");
- return null;
+ throw e.rethrowFromSystemServer();
}
try {
ApduServiceInfo serviceInfo =
@@ -727,7 +734,7 @@
} catch (RemoteException ee) {
Log.e(TAG, "Failed to recover CardEmulationService.");
- return null;
+ throw e.rethrowFromSystemServer();
}
}
}
@@ -739,7 +746,7 @@
*/
@RequiresPermission(android.Manifest.permission.NFC_PREFERRED_PAYMENT_INFO)
@Nullable
- public String getDescriptionForPreferredPaymentService() {
+ public CharSequence getDescriptionForPreferredPaymentService() {
try {
ApduServiceInfo serviceInfo = sService.getPreferredPaymentService(mContext.getUserId());
return (serviceInfo != null ? serviceInfo.getDescription() : null);
@@ -747,7 +754,7 @@
recoverService();
if (sService == null) {
Log.e(TAG, "Failed to recover CardEmulationService.");
- return null;
+ throw e.rethrowFromSystemServer();
}
try {
ApduServiceInfo serviceInfo =
@@ -755,7 +762,7 @@
return (serviceInfo != null ? serviceInfo.getDescription() : null);
} catch (RemoteException ee) {
Log.e(TAG, "Failed to recover CardEmulationService.");
- return null;
+ throw e.rethrowFromSystemServer();
}
}
}
diff --git a/core/java/android/permission/Permissions.md b/core/java/android/permission/Permissions.md
index e62bd0a..e116dc6 100644
--- a/core/java/android/permission/Permissions.md
+++ b/core/java/android/permission/Permissions.md
@@ -49,6 +49,10 @@
to involve the user. This can be either because the API is not sensitive, or because additional
checks exist.
+Another benefit of install time permissions is that is becomes very easy to monitor which apps can
+access certain APIs. E.g. by checking which apps have the `android.permission.INTERNET` permission
+you can list all apps that are allowed to use APIs that can send data to the internet.
+
#### Defining a permission
Any package can define a permission. For that it simply adds an entry in the manifest file
@@ -591,8 +595,9 @@
### Permission restricted components
As [publicly documented](https://developer.android.com/guide/topics/permissions/overview#permission_enforcement)
-it is possible to restrict starting an activity/binding to a service by using permission. It is
-a common pattern to
+it is possible to restrict starting an activity/binding to a service by using permission.
+
+It is a common pattern to
- define a permission in the platform as `signature`
- protect a service in an app by this permission using the `android:permission` attribute of the
@@ -605,6 +610,75 @@
This does not work for app-op or runtime permissions as the way to check these permissions is
more complex than install time permissions.
+#### End-to-end A service only the system can bind to
+
+Make sure to set the `android:permission` flag for this service. As developers can forget this it is
+a good habit to check this before binding to the service. This makes sure that the services are
+implemented correctly and no random app can bind to the service.
+
+The result is that the permission is granted only to the system. It is not granted to the service's
+package, but this has no negative side-effects.
+
+##### Permission definition
+
+frameworks/base/core/res/AndroidManifest.xml:
+
+```xml
+<manifest>
+[...]
+ <permission android:name="android.permission.BIND_MY_SERVICE"
+ android:label="@string/permlab_bindMyService"
+ android:description="@string/permdesc_bindMyService"
+ android:protectionLevel="signature" />
+[...]
+</manifest>
+```
+
+##### Service definition
+
+Manifest of the service providing the functionality:
+
+```xml
+<manifest>
+ <service android:name="com.my.ServiceImpl"
+ android:permission="android.permission.BIND_MY_SERVICE">
+ <!-- add an intent filter so that the system can find this package -->
+ <intent-filter>
+ <action android:name="android.my.Service" />
+ </intent-filter>
+ </service>
+</manifest>
+```
+
+##### System server code binding to service
+
+```kotlin
+val serviceConnections = mutableListOf<ServiceConnection>()
+
+val potentialServices = context.packageManager.queryIntentServicesAsUser(
+ Intent("android.my.Service"), GET_SERVICES or GET_META_DATA, userId)
+
+for (val ri in potentialServices) {
+ val serviceComponent = ComponentName(ri.serviceInfo.packageName, ri.serviceInfo.name)
+
+ if (android.Manifest.permission.BIND_MY_SERVICE != ri.serviceInfo.permission) {
+ Slog.w(TAG, "$serviceComponent is not protected by " +
+ "${android.Manifest.permission.BIND_MY_SERVICE}")
+ continue
+ }
+
+ val newConnection = object : ServiceConnection {
+ ...
+ }
+
+ val wasBound = context.bindServiceAsUser(Intent().setComponent(serviceComponent),
+ serviceConnection, BIND_AUTO_CREATE, UserHandle.of(userId))
+ if (wasBound) {
+ serviceConnections.add(newConnection)
+ }
+}
+```
+
## Permissions for system apps
System apps need to integrate deeper with the system than regular apps. Hence they need to be
diff --git a/core/java/android/provider/Telephony.java b/core/java/android/provider/Telephony.java
index e7b360d..17e3748 100644
--- a/core/java/android/provider/Telephony.java
+++ b/core/java/android/provider/Telephony.java
@@ -1391,7 +1391,6 @@
* Base column for the table that contain Carrier Public key.
* @hide
*/
- @SystemApi
public interface CarrierColumns extends BaseColumns {
/**
@@ -4704,7 +4703,6 @@
* Contains mappings between matching rules with carrier id for all carriers.
* @hide
*/
- @SystemApi
public static final class All implements BaseColumns {
/**
diff --git a/core/java/android/se/omapi/Reader.java b/core/java/android/se/omapi/Reader.java
index 7f68d91..90c934d 100644
--- a/core/java/android/se/omapi/Reader.java
+++ b/core/java/android/se/omapi/Reader.java
@@ -160,7 +160,7 @@
* @hide
*/
@SystemApi
- @RequiresPermission(android.Manifest.permission.SECURE_ELEMENT_PRIVILEGED)
+ @RequiresPermission(android.Manifest.permission.SECURE_ELEMENT_PRIVILEGED_OPERATION)
public boolean reset() {
if (!mService.isConnected()) {
Log.e(TAG, "service is not connected");
diff --git a/core/java/android/service/autofill/InlineSuggestionRenderService.java b/core/java/android/service/autofill/InlineSuggestionRenderService.java
index f0a72c5..7fbc309 100644
--- a/core/java/android/service/autofill/InlineSuggestionRenderService.java
+++ b/core/java/android/service/autofill/InlineSuggestionRenderService.java
@@ -97,6 +97,9 @@
host.setView(suggestionRoot, lp);
suggestionRoot.setOnClickListener((v) -> {
try {
+ if (suggestionView.hasOnClickListeners()) {
+ suggestionView.callOnClick();
+ }
callback.onClick();
} catch (RemoteException e) {
Log.w(TAG, "RemoteException calling onClick()");
@@ -105,6 +108,9 @@
suggestionRoot.setOnLongClickListener((v) -> {
try {
+ if (suggestionView.hasOnLongClickListeners()) {
+ suggestionView.performLongClick();
+ }
callback.onLongClick();
} catch (RemoteException e) {
Log.w(TAG, "RemoteException calling onLongClick()");
diff --git a/core/java/android/service/autofill/InlineSuggestionRoot.java b/core/java/android/service/autofill/InlineSuggestionRoot.java
index bdcc253..6c9d36b 100644
--- a/core/java/android/service/autofill/InlineSuggestionRoot.java
+++ b/core/java/android/service/autofill/InlineSuggestionRoot.java
@@ -52,6 +52,11 @@
}
@Override
+ public boolean onInterceptTouchEvent(MotionEvent ev) {
+ return true;
+ }
+
+ @Override
@SuppressLint("ClickableViewAccessibility")
public boolean onTouchEvent(@NonNull MotionEvent event) {
switch (event.getActionMasked()) {
diff --git a/core/java/android/telephony/PhoneStateListener.java b/core/java/android/telephony/PhoneStateListener.java
index d273500..28db270 100644
--- a/core/java/android/telephony/PhoneStateListener.java
+++ b/core/java/android/telephony/PhoneStateListener.java
@@ -176,7 +176,6 @@
* @hide
*/
@RequiresPermission(android.Manifest.permission.LISTEN_ALWAYS_REPORTED_SIGNAL_STRENGTH)
- @SystemApi
public static final int LISTEN_ALWAYS_REPORTED_SIGNAL_STRENGTH = 0x00000200;
/**
diff --git a/core/java/android/util/FeatureFlagUtils.java b/core/java/android/util/FeatureFlagUtils.java
index cfbe393..4dafc0d 100644
--- a/core/java/android/util/FeatureFlagUtils.java
+++ b/core/java/android/util/FeatureFlagUtils.java
@@ -67,9 +67,9 @@
DEFAULT_FLAGS.put("settings_controller_loading_enhancement", "false");
DEFAULT_FLAGS.put("settings_conditionals", "false");
DEFAULT_FLAGS.put(NOTIF_CONVO_BYPASS_SHORTCUT_REQ, "true");
- // Disabled by default until b/148278926 is resolved. This flags guards a feature
- // introduced in R and will be removed in the next release (b/148367230).
- DEFAULT_FLAGS.put(SETTINGS_DO_NOT_RESTORE_PRESERVED, "false");
+ // This flags guards a feature introduced in R and will be removed in the next release
+ // (b/148367230).
+ DEFAULT_FLAGS.put(SETTINGS_DO_NOT_RESTORE_PRESERVED, "true");
DEFAULT_FLAGS.put("settings_tether_all_in_one", "false");
DEFAULT_FLAGS.put(SETTINGS_SCHEDULES_FLAG, "false");
diff --git a/core/java/android/util/apk/ApkSignatureSchemeV3Verifier.java b/core/java/android/util/apk/ApkSignatureSchemeV3Verifier.java
index 79eb9f6..2437af2 100644
--- a/core/java/android/util/apk/ApkSignatureSchemeV3Verifier.java
+++ b/core/java/android/util/apk/ApkSignatureSchemeV3Verifier.java
@@ -213,15 +213,24 @@
verityDigest, apk.length(), signatureInfo);
}
- if (contentDigests.containsKey(CONTENT_DIGEST_CHUNKED_SHA512)) {
- result.digest = contentDigests.get(CONTENT_DIGEST_CHUNKED_SHA512);
- } else if (contentDigests.containsKey(CONTENT_DIGEST_CHUNKED_SHA256)) {
- result.digest = contentDigests.get(CONTENT_DIGEST_CHUNKED_SHA256);
- }
+ result.digest = pickBestV3DigestForV4(contentDigests);
return result;
}
+ // Keep in sync with pickBestV3DigestForV4 in apksigner.V3SchemeVerifier.
+ private static byte[] pickBestV3DigestForV4(Map<Integer, byte[]> contentDigests) {
+ final int[] orderedContentDigestTypes =
+ {CONTENT_DIGEST_CHUNKED_SHA512, CONTENT_DIGEST_VERITY_CHUNKED_SHA256,
+ CONTENT_DIGEST_CHUNKED_SHA256};
+ for (int contentDigestType : orderedContentDigestTypes) {
+ if (contentDigests.containsKey(contentDigestType)) {
+ return contentDigests.get(contentDigestType);
+ }
+ }
+ return null;
+ }
+
private static VerifiedSigner verifySigner(
ByteBuffer signerBlock,
Map<Integer, byte[]> contentDigests,
diff --git a/core/java/android/view/Display.java b/core/java/android/view/Display.java
index 0dcb9cc..dffcafe 100644
--- a/core/java/android/view/Display.java
+++ b/core/java/android/view/Display.java
@@ -1307,6 +1307,15 @@
}
/**
+ * Returns true if the display is in active state such as {@link #STATE_ON}
+ * or {@link #STATE_VR}.
+ * @hide
+ */
+ public static boolean isActiveState(int state) {
+ return state == STATE_ON || state == STATE_VR;
+ }
+
+ /**
* A mode supported by a given display.
*
* @see Display#getSupportedModes()
diff --git a/core/java/android/view/SurfaceControl.java b/core/java/android/view/SurfaceControl.java
index 25f5609..c87808b 100644
--- a/core/java/android/view/SurfaceControl.java
+++ b/core/java/android/view/SurfaceControl.java
@@ -1960,7 +1960,7 @@
* @hide
*/
public static ScreenshotGraphicBuffer captureLayersExcluding(SurfaceControl layer,
- Rect sourceCrop, float frameScale, SurfaceControl[] exclude) {
+ Rect sourceCrop, float frameScale, int format, SurfaceControl[] exclude) {
final IBinder displayToken = SurfaceControl.getInternalDisplayToken();
long[] nativeExcludeObjects = new long[exclude.length];
for (int i = 0; i < exclude.length; i++) {
diff --git a/core/java/android/view/WindowManager.java b/core/java/android/view/WindowManager.java
index c5fa3c8..77ce5c1 100644
--- a/core/java/android/view/WindowManager.java
+++ b/core/java/android/view/WindowManager.java
@@ -89,6 +89,7 @@
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
+import java.util.Arrays;
import java.util.List;
import java.util.Objects;
@@ -2896,6 +2897,18 @@
private boolean mFitInsetsIgnoringVisibility = false;
/**
+ * {@link InsetsState.InternalInsetsType}s to be applied to the window
+ * If {@link #type} has the predefined insets (like {@link #TYPE_STATUS_BAR} or
+ * {@link #TYPE_NAVIGATION_BAR}), this field will be ignored.
+ *
+ * <p>Note: provide only one inset corresponding to the window type (like
+ * {@link InsetsState.InternalInsetsType#ITYPE_STATUS_BAR} or
+ * {@link InsetsState.InternalInsetsType#ITYPE_NAVIGATION_BAR})</p>
+ * @hide
+ */
+ public @InsetsState.InternalInsetsType int[] providesInsetsTypes;
+
+ /**
* Specifies types of insets that this window should avoid overlapping during layout.
*
* @param types which types of insets that this window should avoid. The initial value of
@@ -3116,6 +3129,12 @@
out.writeInt(mFitInsetsSides);
out.writeBoolean(mFitInsetsIgnoringVisibility);
out.writeBoolean(preferMinimalPostProcessing);
+ if (providesInsetsTypes != null) {
+ out.writeInt(providesInsetsTypes.length);
+ out.writeIntArray(providesInsetsTypes);
+ } else {
+ out.writeInt(0);
+ }
}
public static final @android.annotation.NonNull Parcelable.Creator<LayoutParams> CREATOR
@@ -3177,6 +3196,11 @@
mFitInsetsSides = in.readInt();
mFitInsetsIgnoringVisibility = in.readBoolean();
preferMinimalPostProcessing = in.readBoolean();
+ int insetsTypesLength = in.readInt();
+ if (insetsTypesLength > 0) {
+ providesInsetsTypes = new int[insetsTypesLength];
+ in.readIntArray(providesInsetsTypes);
+ }
}
@SuppressWarnings({"PointlessBitwiseExpression"})
@@ -3437,6 +3461,11 @@
changes |= LAYOUT_CHANGED;
}
+ if (!Arrays.equals(providesInsetsTypes, o.providesInsetsTypes)) {
+ providesInsetsTypes = o.providesInsetsTypes;
+ changes |= LAYOUT_CHANGED;
+ }
+
return changes;
}
@@ -3609,6 +3638,14 @@
sb.append(System.lineSeparator());
sb.append(prefix).append(" fitIgnoreVis");
}
+ if (providesInsetsTypes != null) {
+ sb.append(System.lineSeparator());
+ sb.append(prefix).append(" insetsTypes=");
+ for (int i = 0; i < providesInsetsTypes.length; ++i) {
+ if (i > 0) sb.append(' ');
+ sb.append(InsetsState.typeToString(providesInsetsTypes[i]));
+ }
+ }
sb.append('}');
return sb.toString();
diff --git a/core/java/android/view/textclassifier/TextClassificationContext.java b/core/java/android/view/textclassifier/TextClassificationContext.java
index f2323c6..5d5683f 100644
--- a/core/java/android/view/textclassifier/TextClassificationContext.java
+++ b/core/java/android/view/textclassifier/TextClassificationContext.java
@@ -31,7 +31,6 @@
*/
public final class TextClassificationContext implements Parcelable {
- // NOTE: Modify packageName only in the constructor or in setSystemTextClassifierMetadata()
private String mPackageName;
private final String mWidgetType;
@Nullable private final String mWidgetVersion;
@@ -47,7 +46,7 @@
}
/**
- * Returns the package name for the calling package.
+ * Returns the package name of the app that this context originated in.
*/
@NonNull
public String getPackageName() {
@@ -57,14 +56,10 @@
/**
* Sets the information about the {@link SystemTextClassifier} that sent this request.
*
- * <p><b>NOTE: </b>This will override the value returned in {@link getPackageName()}.
* @hide
*/
void setSystemTextClassifierMetadata(@Nullable SystemTextClassifierMetadata systemTcMetadata) {
mSystemTcMetadata = systemTcMetadata;
- if (mSystemTcMetadata != null) {
- mPackageName = mSystemTcMetadata.getCallingPackageName();
- }
}
/**
diff --git a/core/java/com/android/internal/app/ChooserActivity.java b/core/java/com/android/internal/app/ChooserActivity.java
index 3696c83..78a0ae0 100644
--- a/core/java/com/android/internal/app/ChooserActivity.java
+++ b/core/java/com/android/internal/app/ChooserActivity.java
@@ -1536,10 +1536,12 @@
labels.add(innerInfo.getResolveInfo().loadLabel(getPackageManager()));
}
f = new ResolverTargetActionsDialogFragment(mti.getDisplayLabel(), name,
- mti.getTargets(), labels);
+ mti.getTargets(), labels,
+ mChooserMultiProfilePagerAdapter.getCurrentUserHandle());
} else {
f = new ResolverTargetActionsDialogFragment(
- ti.getResolveInfo().loadLabel(getPackageManager()), name, pinned);
+ ti.getResolveInfo().loadLabel(getPackageManager()), name, pinned,
+ mChooserMultiProfilePagerAdapter.getCurrentUserHandle());
}
f.show(getFragmentManager(), TARGET_DETAILS_FRAGMENT_TAG);
diff --git a/core/java/com/android/internal/app/ResolverActivity.java b/core/java/com/android/internal/app/ResolverActivity.java
index 086a718..8e64b97 100644
--- a/core/java/com/android/internal/app/ResolverActivity.java
+++ b/core/java/com/android/internal/app/ResolverActivity.java
@@ -49,6 +49,7 @@
import android.content.pm.UserInfo;
import android.content.res.Configuration;
import android.content.res.Resources;
+import android.content.res.TypedArray;
import android.graphics.Insets;
import android.net.Uri;
import android.os.Build;
@@ -65,6 +66,7 @@
import android.text.TextUtils;
import android.util.Log;
import android.util.Slog;
+import android.util.TypedValue;
import android.view.Gravity;
import android.view.LayoutInflater;
import android.view.View;
@@ -1303,7 +1305,7 @@
Intent in = new Intent().setAction(Settings.ACTION_APPLICATION_DETAILS_SETTINGS)
.setData(Uri.fromParts("package", ri.activityInfo.packageName, null))
.addFlags(Intent.FLAG_ACTIVITY_NEW_DOCUMENT);
- startActivity(in);
+ startActivityAsUser(in, mMultiProfilePagerAdapter.getCurrentUserHandle());
}
@VisibleForTesting
@@ -1606,7 +1608,10 @@
for (int i = 0; i < tabWidget.getChildCount(); i++) {
View tabView = tabWidget.getChildAt(i);
TextView title = tabView.findViewById(android.R.id.title);
- title.setTextColor(getColor(R.color.resolver_tabs_inactive_color));
+ title.setTextAppearance(android.R.style.TextAppearance_DeviceDefault_DialogWindowTitle);
+ title.setTextColor(getAttrColor(this, android.R.attr.textColorTertiary));
+ title.setTextSize(TypedValue.COMPLEX_UNIT_PX,
+ getResources().getDimension(R.dimen.resolver_tab_text_size));
if (title.getText().equals(getString(R.string.resolver_personal_tab))) {
tabView.setContentDescription(personalContentDescription);
} else if (title.getText().equals(getString(R.string.resolver_work_tab))) {
@@ -1615,10 +1620,17 @@
}
}
+ private static int getAttrColor(Context context, int attr) {
+ TypedArray ta = context.obtainStyledAttributes(new int[]{attr});
+ int colorAccent = ta.getColor(0, 0);
+ ta.recycle();
+ return colorAccent;
+ }
+
private void updateActiveTabStyle(TabHost tabHost) {
TextView title = tabHost.getTabWidget().getChildAt(tabHost.getCurrentTab())
.findViewById(android.R.id.title);
- title.setTextColor(getColor(R.color.resolver_tabs_active_color));
+ title.setTextColor(getAttrColor(this, android.R.attr.colorAccent));
}
private void setupViewVisibilities() {
diff --git a/core/java/com/android/internal/app/ResolverTargetActionsDialogFragment.java b/core/java/com/android/internal/app/ResolverTargetActionsDialogFragment.java
index 21efc78..35d9bcd 100644
--- a/core/java/com/android/internal/app/ResolverTargetActionsDialogFragment.java
+++ b/core/java/com/android/internal/app/ResolverTargetActionsDialogFragment.java
@@ -27,6 +27,7 @@
import android.content.res.Configuration;
import android.net.Uri;
import android.os.Bundle;
+import android.os.UserHandle;
import android.provider.Settings;
import com.android.internal.R;
@@ -43,6 +44,7 @@
private static final String NAME_KEY = "componentName";
private static final String TITLE_KEY = "title";
private static final String PINNED_KEY = "pinned";
+ private static final String USER_ID_KEY = "userId";
// Sync with R.array.resolver_target_actions_* resources
private static final int TOGGLE_PIN_INDEX = 0;
@@ -56,19 +58,21 @@
}
public ResolverTargetActionsDialogFragment(CharSequence title, ComponentName name,
- boolean pinned) {
+ boolean pinned, UserHandle userHandle) {
Bundle args = new Bundle();
args.putCharSequence(TITLE_KEY, title);
args.putParcelable(NAME_KEY, name);
args.putBoolean(PINNED_KEY, pinned);
+ args.putParcelable(USER_ID_KEY, userHandle);
setArguments(args);
}
public ResolverTargetActionsDialogFragment(CharSequence title, ComponentName name,
- List<DisplayResolveInfo> targets, List<CharSequence> labels) {
+ List<DisplayResolveInfo> targets, List<CharSequence> labels, UserHandle userHandle) {
Bundle args = new Bundle();
args.putCharSequence(TITLE_KEY, title);
args.putParcelable(NAME_KEY, name);
+ args.putParcelable(USER_ID_KEY, userHandle);
mTargetInfos = targets;
mLabels = labels;
setArguments(args);
@@ -122,7 +126,8 @@
Intent in = new Intent().setAction(Settings.ACTION_APPLICATION_DETAILS_SETTINGS)
.setData(Uri.fromParts("package", name.getPackageName(), null))
.addFlags(Intent.FLAG_ACTIVITY_NEW_DOCUMENT);
- startActivity(in);
+ UserHandle userHandle = args.getParcelable(USER_ID_KEY);
+ getActivity().startActivityAsUser(in, userHandle);
}
dismiss();
}
diff --git a/core/proto/android/os/incident.proto b/core/proto/android/os/incident.proto
index d6687f0..64cf75d 100644
--- a/core/proto/android/os/incident.proto
+++ b/core/proto/android/os/incident.proto
@@ -376,8 +376,7 @@
optional bytes system_trace = 3026 [
(section).type = SECTION_FILE,
(section).args = "/data/misc/perfetto-traces/incident-trace",
- (privacy).dest = DEST_AUTOMATIC,
- (section).userdebug_and_eng_only = true
+ (privacy).dest = DEST_AUTOMATIC
];
// Dropbox entries split by tags.
diff --git a/core/proto/android/util/quotatracker.proto b/core/proto/android/util/quotatracker.proto
index 5d022ed..d98e5ee 100644
--- a/core/proto/android/util/quotatracker.proto
+++ b/core/proto/android/util/quotatracker.proto
@@ -131,93 +131,3 @@
// Next tag: 4
}
-
-// A com.android.util.quota.DurationQuotaTracker object.
-message DurationQuotaTrackerProto {
- option (.android.msg_privacy).dest = DEST_AUTOMATIC;
-
- optional QuotaTrackerProto base_quota_data = 1;
-
- message DurationLimit {
- option (.android.msg_privacy).dest = DEST_AUTOMATIC;
-
- optional CategoryProto category = 1;
- optional int64 limit_ms = 2;
- optional int64 window_size_ms = 3;
- }
- repeated DurationLimit duration_limit = 2;
-
- message ExecutionStats {
- option (.android.msg_privacy).dest = DEST_AUTOMATIC;
-
- // The time after which this record should be considered invalid (out of date), in the
- // elapsed realtime timebase.
- optional int64 expiration_time_elapsed = 1;
-
- optional int32 window_size_ms = 2;
- optional int64 duration_limit_ms = 3;
-
- // The overall session duration in the window.
- optional int64 session_duration_in_window_ms = 4;
- // The number of individual long-running events in the window.
- optional int32 event_count_in_window = 5;
-
- // The time after which the app will be under the bucket quota. This is only valid if
- // session_duration_in_window_ms >= duration_limit_ms.
- optional int64 in_quota_time_elapsed = 6;
- }
-
- message Timer {
- option (.android.msg_privacy).dest = DEST_AUTOMATIC;
-
- // True if the Timer is actively tracking long-running events.
- optional bool is_active = 1;
- // The time this timer last became active. Only valid if is_active is true.
- optional int64 start_time_elapsed = 2;
- // How many long-running events are currently running. Valid only if is_active is true.
- optional int32 event_count = 3;
- }
-
- message TimingSession {
- option (.android.msg_privacy).dest = DEST_AUTOMATIC;
-
- optional int64 start_time_elapsed = 1;
- optional int64 end_time_elapsed = 2;
- // How many events started during this session. This only count long-running events, not
- // instantaneous events.
- optional int32 event_count = 3;
- }
-
- message UptcStats {
- option (.android.msg_privacy).dest = DEST_AUTOMATIC;
-
- optional UptcProto uptc = 1;
-
- // True if the UPTC has been given free quota.
- optional bool is_quota_free = 2;
-
- optional Timer timer = 3;
-
- repeated TimingSession saved_sessions = 4;
-
- repeated ExecutionStats execution_stats = 5;
- }
- repeated UptcStats uptc_stats = 3;
-
- message ReachedQuotaAlarmListener {
- option (.android.msg_privacy).dest = DEST_AUTOMATIC;
-
- optional int64 trigger_time_elapsed = 1;
-
- message UptcTimes {
- option (.android.msg_privacy).dest = DEST_AUTOMATIC;
-
- optional UptcProto uptc = 1;
- optional int64 out_of_quota_time_elapsed = 2;
- }
- repeated UptcTimes uptc_times = 2;
- }
- optional ReachedQuotaAlarmListener reached_quota_alarm_listener = 4;
-
- // Next tag: 5
-}
diff --git a/core/res/AndroidManifest.xml b/core/res/AndroidManifest.xml
index 7a3ec95..f7400bd 100644
--- a/core/res/AndroidManifest.xml
+++ b/core/res/AndroidManifest.xml
@@ -1689,6 +1689,10 @@
<permission android:name="android.permission.NETWORK_FACTORY"
android:protectionLevel="signature" />
+ <!-- @SystemApi @hide Allows applications to access network stats provider -->
+ <permission android:name="android.permission.NETWORK_STATS_PROVIDER"
+ android:protectionLevel="signature" />
+
<!-- Allows Settings and SystemUI to call methods in Networking services
<p>Not for use by third-party or privileged applications.
@SystemApi @TestApi
@@ -1841,7 +1845,7 @@
and bypass OMAPI AccessControlEnforcer.
<p>Not for use by third-party applications.
@hide -->
- <permission android:name="android.permission.SECURE_ELEMENT_PRIVILEGED"
+ <permission android:name="android.permission.SECURE_ELEMENT_PRIVILEGED_OPERATION"
android:protectionLevel="signature|privileged" />
<!-- @deprecated This permission used to allow too broad access to sensitive methods and all its
diff --git a/core/res/res/drawable/tab_indicator_resolver.xml b/core/res/res/drawable/tab_indicator_resolver.xml
index ff16d81a..f97773e 100644
--- a/core/res/res/drawable/tab_indicator_resolver.xml
+++ b/core/res/res/drawable/tab_indicator_resolver.xml
@@ -25,7 +25,7 @@
</item>
<item android:gravity="bottom">
<shape android:shape="rectangle"
- android:tint="@color/resolver_tabs_active_color">
+ android:tint="?attr/colorAccent">
<size android:height="2dp" />
<solid android:color="@color/tab_indicator_material" />
</shape>
diff --git a/core/res/res/layout/resolver_empty_states.xml b/core/res/res/layout/resolver_empty_states.xml
index 176f289..5fdf190 100644
--- a/core/res/res/layout/resolver_empty_states.xml
+++ b/core/res/res/layout/resolver_empty_states.xml
@@ -60,7 +60,7 @@
android:background="@null"
android:fontFamily="@string/config_headlineFontFamilyMedium"
android:textSize="14sp"
- android:textColor="@color/resolver_tabs_active_color"
+ android:textColor="?attr/colorAccent"
android:layout_centerHorizontal="true" />
<ProgressBar
android:id="@+id/resolver_empty_state_progress"
@@ -71,5 +71,5 @@
android:indeterminate="true"
android:layout_centerHorizontal="true"
android:layout_below="@+id/resolver_empty_state_subtitle"
- android:indeterminateTint="@color/resolver_tabs_active_color"/>
+ android:indeterminateTint="?attr/colorAccent"/>
</RelativeLayout>
\ No newline at end of file
diff --git a/core/res/res/values-night/colors.xml b/core/res/res/values-night/colors.xml
index 7f77e6c..708b4f3 100644
--- a/core/res/res/values-night/colors.xml
+++ b/core/res/res/values-night/colors.xml
@@ -33,7 +33,6 @@
<color name="chooser_gradient_background">@color/loading_gradient_background_color_dark</color>
<color name="chooser_gradient_highlight">@color/loading_gradient_highlight_color_dark</color>
- <color name="resolver_tabs_active_color">#FF8AB4F8</color>
<color name="resolver_empty_state_text">#FFFFFF</color>
<color name="resolver_empty_state_icon">#FFFFFF</color>
</resources>
diff --git a/core/res/res/values/colors.xml b/core/res/res/values/colors.xml
index bdec096..91248f1 100644
--- a/core/res/res/values/colors.xml
+++ b/core/res/res/values/colors.xml
@@ -224,8 +224,6 @@
<!-- Resolver/Chooser -->
<color name="resolver_text_color_secondary_dark">#ffC4C6C6</color>
- <color name="resolver_tabs_active_color">#FF1A73E8</color>
- <color name="resolver_tabs_inactive_color">#FF80868B</color>
<color name="resolver_empty_state_text">#FF202124</color>
<color name="resolver_empty_state_icon">#FF5F6368</color>
</resources>
diff --git a/core/res/res/values/dimens.xml b/core/res/res/values/dimens.xml
index 15ef09c..4dedc63 100644
--- a/core/res/res/values/dimens.xml
+++ b/core/res/res/values/dimens.xml
@@ -800,6 +800,7 @@
<dimen name="resolver_empty_state_height_with_tabs">268dp</dimen>
<dimen name="resolver_max_collapsed_height">192dp</dimen>
<dimen name="resolver_max_collapsed_height_with_tabs">248dp</dimen>
+ <dimen name="resolver_tab_text_size">14sp</dimen>
<dimen name="chooser_action_button_icon_size">18dp</dimen>
diff --git a/core/res/res/values/strings.xml b/core/res/res/values/strings.xml
index f101f59..26024ed 100644
--- a/core/res/res/values/strings.xml
+++ b/core/res/res/values/strings.xml
@@ -1169,7 +1169,7 @@
<!-- Title of an application permission, listed so the user can choose whether they want to allow the application to do this. [CHAR_LIMIT=NONE] -->
<string name="permlab_cameraOpenCloseListener">Allow an application or service to receive callbacks about camera devices being opened or closed.</string>
<!-- Description of an application permission, listed so the user can choose whether they want to allow the application to do this. [CHAR_LIMIT=NONE] -->
- <string name="permdesc_cameraOpenCloseListener">This signature app can receive callbacks when any camera device is being opened (by what application package) or closed.</string>
+ <string name="permdesc_cameraOpenCloseListener">This app can receive callbacks when any camera device is being opened (by what application) or closed.</string>
<!-- Title of an application permission, listed so the user can choose whether they want to allow the application to do this. -->
<string name="permlab_vibrate">control vibration</string>
@@ -2985,72 +2985,6 @@
<!-- Title for EditText context menu [CHAR LIMIT=20] -->
<string name="editTextMenuTitle">Text actions</string>
- <!-- Label for item in the text selection menu to trigger an Email app. Should be a verb. [CHAR LIMIT=30] -->
- <string name="email">Email</string>
-
- <!-- Accessibility description for an item in the text selection menu to trigger an Email app [CHAR LIMIT=NONE] -->
- <string name="email_desc">Email selected address</string>
-
- <!-- Label for item in the text selection menu to trigger a Dialer app. Should be a verb. [CHAR LIMIT=30] -->
- <string name="dial">Call</string>
-
- <!-- Accessibility description for an item in the text selection menu to call a phone number [CHAR LIMIT=NONE] -->
- <string name="dial_desc">Call selected phone number</string>
-
- <!-- Label for item in the text selection menu to trigger a Map app. Should be a verb. [CHAR LIMIT=30] -->
- <string name="map">Map</string>
-
- <!-- Accessibility description for an item in the text selection menu to open maps for an address [CHAR LIMIT=NONE] -->
- <string name="map_desc">Locate selected address</string>
-
- <!-- Label for item in the text selection menu to trigger a Browser app. Should be a verb. [CHAR LIMIT=30] -->
- <string name="browse">Open</string>
-
- <!-- Accessibility description for an item in the text selection menu to open a URL in a browser [CHAR LIMIT=NONE] -->
- <string name="browse_desc">Open selected URL</string>
-
- <!-- Label for item in the text selection menu to trigger an SMS app. Should be a verb. [CHAR LIMIT=30] -->
- <string name="sms">Message</string>
-
- <!-- Accessibility description for an item in the text selection menu to send an SMS to a phone number [CHAR LIMIT=NONE] -->
- <string name="sms_desc">Message selected phone number</string>
-
- <!-- Label for item in the text selection menu to trigger adding a contact. Should be a verb. [CHAR LIMIT=30] -->
- <string name="add_contact">Add</string>
-
- <!-- Accessibility description for an item in the text selection menu to add the selected detail to contacts [CHAR LIMIT=NONE] -->
- <string name="add_contact_desc">Add to contacts</string>
-
- <!-- Label for item in the text selection menu to view the calendar for the selected time/date. Should be a verb. [CHAR LIMIT=30] -->
- <string name="view_calendar">View</string>
-
- <!-- Accessibility description for an item in the text selection menu to view the calendar for a date [CHAR LIMIT=NONE]-->
- <string name="view_calendar_desc">View selected time in calendar</string>
-
- <!-- Label for item in the text selection menu to create a calendar event at the selected time/date. Should be a verb. [CHAR LIMIT=30] -->
- <string name="add_calendar_event">Schedule</string>
-
- <!-- Accessibility description for an item in the text selection menu to schedule an event for a date [CHAR LIMIT=NONE] -->
- <string name="add_calendar_event_desc">Schedule event for selected time</string>
-
- <!-- Label for item in the text selection menu to track a selected flight number. Should be a verb. [CHAR LIMIT=30] -->
- <string name="view_flight">Track</string>
-
- <!-- Accessibility description for an item in the text selection menu to track a flight [CHAR LIMIT=NONE] -->
- <string name="view_flight_desc">Track selected flight</string>
-
- <!-- Label for item in the text selection menu to translate selected text with a translation app. Should be a verb. [CHAR LIMIT=30] -->
- <string name="translate">Translate</string>
-
- <!-- Accessibility description for an item in the text selection menu to translate selected text with a translation app. [CHAR LIMIT=NONE] -->
- <string name="translate_desc">Translate selected text</string>
-
- <!-- Label for item in the text selection menu to define selected text with a dictionary app. Should be a verb. [CHAR LIMIT=30] -->
- <string name="define">Define</string>
-
- <!-- Accessibility description for an item in the text selection menu to define selected text with a dictionary app. Should be a verb. [CHAR LIMIT=NONE] -->
- <string name="define_desc">Define selected text</string>
-
<!-- If the device is getting low on internal storage, a notification is shown to the user. This is the title of that notification. -->
<string name="low_internal_storage_view_title">Storage space running out</string>
<!-- If the device is getting low on internal storage, a notification is shown to the user. This is the message of that notification. -->
diff --git a/core/res/res/values/symbols.xml b/core/res/res/values/symbols.xml
index 4c0dd8d..3f48088 100644
--- a/core/res/res/values/symbols.xml
+++ b/core/res/res/values/symbols.xml
@@ -551,28 +551,6 @@
<java-symbol type="string" name="replace" />
<java-symbol type="string" name="undo" />
<java-symbol type="string" name="redo" />
- <java-symbol type="string" name="email" />
- <java-symbol type="string" name="email_desc" />
- <java-symbol type="string" name="dial" />
- <java-symbol type="string" name="dial_desc" />
- <java-symbol type="string" name="map" />
- <java-symbol type="string" name="map_desc" />
- <java-symbol type="string" name="browse" />
- <java-symbol type="string" name="browse_desc" />
- <java-symbol type="string" name="sms" />
- <java-symbol type="string" name="sms_desc" />
- <java-symbol type="string" name="add_contact" />
- <java-symbol type="string" name="add_contact_desc" />
- <java-symbol type="string" name="view_calendar" />
- <java-symbol type="string" name="view_calendar_desc" />
- <java-symbol type="string" name="add_calendar_event" />
- <java-symbol type="string" name="add_calendar_event_desc" />
- <java-symbol type="string" name="view_flight" />
- <java-symbol type="string" name="view_flight_desc" />
- <java-symbol type="string" name="translate" />
- <java-symbol type="string" name="translate_desc" />
- <java-symbol type="string" name="define" />
- <java-symbol type="string" name="define_desc" />
<java-symbol type="string" name="textSelectionCABTitle" />
<java-symbol type="string" name="BaMmi" />
<java-symbol type="string" name="CLIRDefaultOffNextCallOff" />
@@ -3906,8 +3884,6 @@
<java-symbol type="layout" name="conversation_face_pile_layout" />
<!-- Intent resolver and share sheet -->
- <java-symbol type="color" name="resolver_tabs_active_color" />
- <java-symbol type="color" name="resolver_tabs_inactive_color" />
<java-symbol type="string" name="resolver_personal_tab" />
<java-symbol type="string" name="resolver_personal_tab_accessibility" />
<java-symbol type="string" name="resolver_work_tab" />
@@ -3938,6 +3914,7 @@
<java-symbol type="dimen" name="resolver_empty_state_height_with_tabs" />
<java-symbol type="dimen" name="resolver_max_collapsed_height_with_tabs" />
<java-symbol type="bool" name="sharesheet_show_content_preview" />
+ <java-symbol type="dimen" name="resolver_tab_text_size" />
<!-- Toast message for background started foreground service while-in-use permission restriction feature -->
<java-symbol type="string" name="allow_while_in_use_permission_in_fgs" />
diff --git a/core/tests/bandwidthtests/src/com/android/bandwidthtest/BandwidthTest.java b/core/tests/bandwidthtests/src/com/android/bandwidthtest/BandwidthTest.java
index 5d42915..4b42f4ae 100644
--- a/core/tests/bandwidthtests/src/com/android/bandwidthtest/BandwidthTest.java
+++ b/core/tests/bandwidthtests/src/com/android/bandwidthtest/BandwidthTest.java
@@ -268,7 +268,7 @@
File snd_stat = new File (root_filepath + "tcp_snd");
int tx = BandwidthTestUtil.parseIntValueFromFile(snd_stat);
NetworkStats stats = new NetworkStats(SystemClock.elapsedRealtime(), 1);
- stats.addEntry(NetworkStats.IFACE_ALL, uid, NetworkStats.SET_DEFAULT,
+ stats.insertEntry(NetworkStats.IFACE_ALL, uid, NetworkStats.SET_DEFAULT,
NetworkStats.TAG_NONE, rx, 0, tx, 0, 0);
return stats;
}
diff --git a/core/tests/benchmarks/src/android/net/NetworkStatsBenchmark.java b/core/tests/benchmarks/src/android/net/NetworkStatsBenchmark.java
index 239f971..3ebe103 100644
--- a/core/tests/benchmarks/src/android/net/NetworkStatsBenchmark.java
+++ b/core/tests/benchmarks/src/android/net/NetworkStatsBenchmark.java
@@ -54,7 +54,7 @@
recycle.txBytes = 150000;
recycle.txPackets = 1500;
recycle.operations = 0;
- mNetworkStats.addEntry(recycle);
+ mNetworkStats.insertEntry(recycle);
if (recycle.set == 1) {
uid++;
}
@@ -70,7 +70,7 @@
recycle.txBytes = 180000 * mSize;
recycle.txPackets = 1200 * mSize;
recycle.operations = 0;
- mNetworkStats.addEntry(recycle);
+ mNetworkStats.insertEntry(recycle);
}
}
diff --git a/core/tests/coretests/src/android/app/activity/ActivityThreadTest.java b/core/tests/coretests/src/android/app/activity/ActivityThreadTest.java
index c328d72..90d8bab 100644
--- a/core/tests/coretests/src/android/app/activity/ActivityThreadTest.java
+++ b/core/tests/coretests/src/android/app/activity/ActivityThreadTest.java
@@ -40,7 +40,10 @@
import android.app.servertransaction.StopActivityItem;
import android.content.Intent;
import android.content.res.Configuration;
+import android.content.res.Resources;
+import android.graphics.Rect;
import android.os.IBinder;
+import android.util.DisplayMetrics;
import android.util.MergedConfiguration;
import android.view.Display;
import android.view.View;
@@ -307,6 +310,58 @@
}
@Test
+ public void testHandleConfigurationChangedDoesntOverrideActivityConfig() {
+ final TestActivity activity = mActivityTestRule.launchActivity(new Intent());
+
+ InstrumentationRegistry.getInstrumentation().runOnMainSync(() -> {
+ final Configuration oldActivityConfig =
+ new Configuration(activity.getResources().getConfiguration());
+ final DisplayMetrics oldActivityMetrics = new DisplayMetrics();
+ activity.getDisplay().getMetrics(oldActivityMetrics);
+ final Resources oldAppResources = activity.getApplication().getResources();
+ final Configuration oldAppConfig =
+ new Configuration(oldAppResources.getConfiguration());
+ final DisplayMetrics oldApplicationMetrics = new DisplayMetrics();
+ oldApplicationMetrics.setTo(oldAppResources.getDisplayMetrics());
+ assertEquals("Process config must match the top activity config by default",
+ 0, oldActivityConfig.diffPublicOnly(oldAppConfig));
+ assertEquals("Process config must match the top activity config by default",
+ oldActivityMetrics, oldApplicationMetrics);
+
+ // Update the application configuration separately from activity config
+ final Configuration newAppConfig = new Configuration(oldAppConfig);
+ newAppConfig.densityDpi += 100;
+ newAppConfig.screenHeightDp += 100;
+ final Rect newBounds = new Rect(newAppConfig.windowConfiguration.getAppBounds());
+ newBounds.bottom += 100;
+ newAppConfig.windowConfiguration.setAppBounds(newBounds);
+ newAppConfig.windowConfiguration.setBounds(newBounds);
+ newAppConfig.seq++;
+
+ final ActivityThread activityThread = activity.getActivityThread();
+ activityThread.handleConfigurationChanged(newAppConfig);
+
+ // Verify that application config update was applied, but didn't change activity config.
+ assertEquals("Activity config must not change if the process config changes",
+ oldActivityConfig, activity.getResources().getConfiguration());
+
+ final DisplayMetrics newActivityMetrics = new DisplayMetrics();
+ activity.getDisplay().getMetrics(newActivityMetrics);
+ assertEquals("Activity display size must not change if the process config changes",
+ oldActivityMetrics, newActivityMetrics);
+ final Resources newAppResources = activity.getApplication().getResources();
+ assertEquals("Application config must be updated",
+ newAppConfig, newAppResources.getConfiguration());
+ final DisplayMetrics newApplicationMetrics = new DisplayMetrics();
+ newApplicationMetrics.setTo(newAppResources.getDisplayMetrics());
+ assertNotEquals("Application display size must be updated after config update",
+ oldApplicationMetrics, newApplicationMetrics);
+ assertNotEquals("Application display size must be updated after config update",
+ newActivityMetrics, newApplicationMetrics);
+ });
+ }
+
+ @Test
public void testResumeAfterNewIntent() {
final Activity activity = mActivityTestRule.launchActivity(new Intent());
final ActivityThread activityThread = activity.getActivityThread();
diff --git a/data/etc/com.android.launcher3.xml b/data/etc/com.android.launcher3.xml
index 337e153..17d614e 100644
--- a/data/etc/com.android.launcher3.xml
+++ b/data/etc/com.android.launcher3.xml
@@ -19,5 +19,6 @@
<permission name="android.permission.BIND_APPWIDGET"/>
<permission name="android.permission.CONTROL_REMOTE_APP_TRANSITION_ANIMATIONS"/>
<permission name="android.permission.GET_ACCOUNTS_PRIVILEGED"/>
+ <permission name="android.permission.WRITE_SECURE_SETTINGS"/>
</privapp-permissions>
</permissions>
diff --git a/media/java/android/media/MediaCas.java b/media/java/android/media/MediaCas.java
index 3a771bb..ad9486c 100644
--- a/media/java/android/media/MediaCas.java
+++ b/media/java/android/media/MediaCas.java
@@ -870,16 +870,17 @@
private int getSessionResourceId() throws MediaCasException {
validateInternalStates();
- int[] sessionResourceId = new int[1];
- sessionResourceId[0] = -1;
+ int[] sessionResourceHandle = new int[1];
+ sessionResourceHandle[0] = -1;
if (mTunerResourceManager != null) {
CasSessionRequest casSessionRequest = new CasSessionRequest(mClientId, mCasSystemId);
- if (!mTunerResourceManager.requestCasSession(casSessionRequest, sessionResourceId)) {
- throw new MediaCasException.ResourceBusyException(
+ if (!mTunerResourceManager
+ .requestCasSession(casSessionRequest, sessionResourceHandle)) {
+ throw new MediaCasException.InsufficientResourceException(
"insufficient resource to Open Session");
}
}
- return sessionResourceId[0];
+ return sessionResourceHandle[0];
}
private void addSessionToResourceMap(Session session, int sessionResourceId) {
@@ -905,6 +906,10 @@
* Open a session to descramble one or more streams scrambled by the
* conditional access system.
*
+ * <p>Tuner resource manager (TRM) uses the client priority value to decide whether it is able
+ * to get cas session resource if cas session resources is limited. If the client can't get the
+ * resource, this call returns {@link MediaCasException.InsufficientResourceException }.
+ *
* @return session the newly opened session.
*
* @throws IllegalStateException if the MediaCas instance is not valid.
@@ -930,6 +935,10 @@
* Open a session with usage and scrambling information, so that descrambler can be configured
* to descramble one or more streams scrambled by the conditional access system.
*
+ * <p>Tuner resource manager (TRM) uses the client priority value to decide whether it is able
+ * to get cas session resource if cas session resources is limited. If the client can't get the
+ * resource, this call returns {@link MediaCasException.InsufficientResourceException}.
+ *
* @param sessionUsage used for the created session.
* @param scramblingMode used for the created session.
*
diff --git a/media/java/android/media/audiofx/Visualizer.java b/media/java/android/media/audiofx/Visualizer.java
index 392e8fe..a5da648 100644
--- a/media/java/android/media/audiofx/Visualizer.java
+++ b/media/java/android/media/audiofx/Visualizer.java
@@ -20,9 +20,10 @@
import android.compat.annotation.UnsupportedAppUsage;
import android.os.Handler;
import android.os.Looper;
-import android.os.Message;
import android.util.Log;
+import com.android.internal.annotations.GuardedBy;
+
import java.lang.ref.WeakReference;
/**
@@ -158,6 +159,7 @@
/**
* Indicates the state of the Visualizer instance
*/
+ @GuardedBy("mStateLock")
private int mState = STATE_UNINITIALIZED;
/**
* Lock to synchronize access to mState
@@ -166,6 +168,7 @@
/**
* System wide unique Identifier of the visualizer engine used by this Visualizer instance
*/
+ @GuardedBy("mStateLock")
@UnsupportedAppUsage
private int mId;
@@ -176,19 +179,24 @@
/**
* Handler for events coming from the native code
*/
- private NativeEventHandler mNativeEventHandler = null;
+ @GuardedBy("mListenerLock")
+ private Handler mNativeEventHandler = null;
/**
* PCM and FFT capture listener registered by client
*/
+ @GuardedBy("mListenerLock")
private OnDataCaptureListener mCaptureListener = null;
/**
* Server Died listener registered by client
*/
+ @GuardedBy("mListenerLock")
private OnServerDiedListener mServerDiedListener = null;
// accessed by native methods
- private long mNativeVisualizer;
- private long mJniData;
+ private long mNativeVisualizer; // guarded by a static lock in native code
+ private long mJniData; // set in native_setup, _release;
+ // get in native_release, _setEnabled, _setPeriodicCapture
+ // thus, effectively guarded by mStateLock
//--------------------------------------------------------------------------
// Constructor, Finalize
@@ -244,7 +252,9 @@
@Override
protected void finalize() {
- native_finalize();
+ synchronized (mStateLock) {
+ native_finalize();
+ }
}
/**
@@ -601,25 +611,28 @@
*/
public int setDataCaptureListener(OnDataCaptureListener listener,
int rate, boolean waveform, boolean fft) {
- synchronized (mListenerLock) {
- mCaptureListener = listener;
- }
if (listener == null) {
// make sure capture callback is stopped in native code
waveform = false;
fft = false;
}
- int status = native_setPeriodicCapture(rate, waveform, fft);
+ int status;
+ synchronized (mStateLock) {
+ status = native_setPeriodicCapture(rate, waveform, fft);
+ }
if (status == SUCCESS) {
- if ((listener != null) && (mNativeEventHandler == null)) {
- Looper looper;
- if ((looper = Looper.myLooper()) != null) {
- mNativeEventHandler = new NativeEventHandler(this, looper);
- } else if ((looper = Looper.getMainLooper()) != null) {
- mNativeEventHandler = new NativeEventHandler(this, looper);
- } else {
- mNativeEventHandler = null;
- status = ERROR_NO_INIT;
+ synchronized (mListenerLock) {
+ mCaptureListener = listener;
+ if ((listener != null) && (mNativeEventHandler == null)) {
+ Looper looper;
+ if ((looper = Looper.myLooper()) != null) {
+ mNativeEventHandler = new Handler(looper);
+ } else if ((looper = Looper.getMainLooper()) != null) {
+ mNativeEventHandler = new Handler(looper);
+ } else {
+ mNativeEventHandler = null;
+ status = ERROR_NO_INIT;
+ }
}
}
}
@@ -663,112 +676,61 @@
return SUCCESS;
}
- /**
- * Helper class to handle the forwarding of native events to the appropriate listeners
- */
- private class NativeEventHandler extends Handler
- {
- private Visualizer mVisualizer;
-
- public NativeEventHandler(Visualizer v, Looper looper) {
- super(looper);
- mVisualizer = v;
- }
-
- private void handleCaptureMessage(Message msg) {
- OnDataCaptureListener l = null;
- synchronized (mListenerLock) {
- l = mVisualizer.mCaptureListener;
- }
-
- if (l != null) {
- byte[] data = (byte[])msg.obj;
- int samplingRate = msg.arg1;
-
- switch(msg.what) {
- case NATIVE_EVENT_PCM_CAPTURE:
- l.onWaveFormDataCapture(mVisualizer, data, samplingRate);
- break;
- case NATIVE_EVENT_FFT_CAPTURE:
- l.onFftDataCapture(mVisualizer, data, samplingRate);
- break;
- default:
- Log.e(TAG,"Unknown native event in handleCaptureMessge: "+msg.what);
- break;
- }
- }
- }
-
- private void handleServerDiedMessage(Message msg) {
- OnServerDiedListener l = null;
- synchronized (mListenerLock) {
- l = mVisualizer.mServerDiedListener;
- }
-
- if (l != null)
- l.onServerDied();
- }
-
- @Override
- public void handleMessage(Message msg) {
- if (mVisualizer == null) {
- return;
- }
-
- switch(msg.what) {
- case NATIVE_EVENT_PCM_CAPTURE:
- case NATIVE_EVENT_FFT_CAPTURE:
- handleCaptureMessage(msg);
- break;
- case NATIVE_EVENT_SERVER_DIED:
- handleServerDiedMessage(msg);
- break;
- default:
- Log.e(TAG,"Unknown native event: "+msg.what);
- break;
- }
- }
- }
-
//---------------------------------------------------------
// Interface definitions
//--------------------
private static native final void native_init();
+ @GuardedBy("mStateLock")
private native final int native_setup(Object audioeffect_this,
int audioSession,
int[] id,
String opPackageName);
+ @GuardedBy("mStateLock")
private native final void native_finalize();
+ @GuardedBy("mStateLock")
private native final void native_release();
+ @GuardedBy("mStateLock")
private native final int native_setEnabled(boolean enabled);
+ @GuardedBy("mStateLock")
private native final boolean native_getEnabled();
+ @GuardedBy("mStateLock")
private native final int native_setCaptureSize(int size);
+ @GuardedBy("mStateLock")
private native final int native_getCaptureSize();
+ @GuardedBy("mStateLock")
private native final int native_setScalingMode(int mode);
+ @GuardedBy("mStateLock")
private native final int native_getScalingMode();
+ @GuardedBy("mStateLock")
private native final int native_setMeasurementMode(int mode);
+ @GuardedBy("mStateLock")
private native final int native_getMeasurementMode();
+ @GuardedBy("mStateLock")
private native final int native_getSamplingRate();
+ @GuardedBy("mStateLock")
private native final int native_getWaveForm(byte[] waveform);
+ @GuardedBy("mStateLock")
private native final int native_getFft(byte[] fft);
+ @GuardedBy("mStateLock")
private native final int native_getPeakRms(MeasurementPeakRms measurement);
+ @GuardedBy("mStateLock")
private native final int native_setPeriodicCapture(int rate, boolean waveForm, boolean fft);
//---------------------------------------------------------
@@ -776,17 +738,47 @@
//--------------------
@SuppressWarnings("unused")
private static void postEventFromNative(Object effect_ref,
- int what, int arg1, int arg2, Object obj) {
- Visualizer visu = (Visualizer)((WeakReference)effect_ref).get();
- if (visu == null) {
- return;
- }
+ int what, int samplingRate, byte[] data) {
+ final Visualizer visualizer = (Visualizer) ((WeakReference) effect_ref).get();
+ if (visualizer == null) return;
- if (visu.mNativeEventHandler != null) {
- Message m = visu.mNativeEventHandler.obtainMessage(what, arg1, arg2, obj);
- visu.mNativeEventHandler.sendMessage(m);
+ final Handler handler;
+ synchronized (visualizer.mListenerLock) {
+ handler = visualizer.mNativeEventHandler;
}
+ if (handler == null) return;
+ switch (what) {
+ case NATIVE_EVENT_PCM_CAPTURE:
+ case NATIVE_EVENT_FFT_CAPTURE:
+ handler.post(() -> {
+ final OnDataCaptureListener l;
+ synchronized (visualizer.mListenerLock) {
+ l = visualizer.mCaptureListener;
+ }
+ if (l != null) {
+ if (what == NATIVE_EVENT_PCM_CAPTURE) {
+ l.onWaveFormDataCapture(visualizer, data, samplingRate);
+ } else { // what == NATIVE_EVENT_FFT_CAPTURE
+ l.onFftDataCapture(visualizer, data, samplingRate);
+ }
+ }
+ });
+ break;
+ case NATIVE_EVENT_SERVER_DIED:
+ handler.post(() -> {
+ final OnServerDiedListener l;
+ synchronized (visualizer.mListenerLock) {
+ l = visualizer.mServerDiedListener;
+ }
+ if (l != null) {
+ l.onServerDied();
+ }
+ });
+ break;
+ default:
+ Log.e(TAG, "Unknown native event in postEventFromNative: " + what);
+ break;
+ }
}
}
-
diff --git a/media/java/android/media/tv/tuner/Descrambler.java b/media/java/android/media/tv/tuner/Descrambler.java
index 40add56..975604c 100644
--- a/media/java/android/media/tv/tuner/Descrambler.java
+++ b/media/java/android/media/tv/tuner/Descrambler.java
@@ -20,7 +20,7 @@
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.annotation.SystemApi;
-import android.media.tv.tuner.TunerConstants.Result;
+import android.media.tv.tuner.Tuner.Result;
import android.media.tv.tuner.filter.Filter;
import java.lang.annotation.Retention;
diff --git a/media/java/android/media/tv/tuner/Lnb.java b/media/java/android/media/tv/tuner/Lnb.java
index ea06632..525ee4d 100644
--- a/media/java/android/media/tv/tuner/Lnb.java
+++ b/media/java/android/media/tv/tuner/Lnb.java
@@ -23,7 +23,7 @@
import android.annotation.SystemApi;
import android.content.Context;
import android.hardware.tv.tuner.V1_0.Constants;
-import android.media.tv.tuner.TunerConstants.Result;
+import android.media.tv.tuner.Tuner.Result;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
diff --git a/media/java/android/media/tv/tuner/Tuner.java b/media/java/android/media/tv/tuner/Tuner.java
index 08a33f1..d24d752 100644
--- a/media/java/android/media/tv/tuner/Tuner.java
+++ b/media/java/android/media/tv/tuner/Tuner.java
@@ -26,7 +26,6 @@
import android.content.Context;
import android.hardware.tv.tuner.V1_0.Constants;
import android.media.tv.TvInputService;
-import android.media.tv.tuner.TunerConstants.Result;
import android.media.tv.tuner.dvr.DvrPlayback;
import android.media.tv.tuner.dvr.DvrRecorder;
import android.media.tv.tuner.dvr.OnPlaybackStatusChangedListener;
@@ -44,12 +43,14 @@
import android.media.tv.tuner.frontend.OnTuneEventListener;
import android.media.tv.tuner.frontend.ScanCallback;
import android.media.tv.tunerresourcemanager.ResourceClientProfile;
+import android.media.tv.tunerresourcemanager.TunerFrontendRequest;
import android.media.tv.tunerresourcemanager.TunerLnbRequest;
import android.media.tv.tunerresourcemanager.TunerResourceManager;
import android.os.Handler;
import android.os.HandlerExecutor;
import android.os.Looper;
import android.os.Message;
+import android.util.Log;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
@@ -68,6 +69,96 @@
*/
@SystemApi
public class Tuner implements AutoCloseable {
+ /**
+ * Invalid TS packet ID.
+ */
+ public static final int INVALID_TS_PID = Constants.Constant.INVALID_TS_PID;
+ /**
+ * Invalid stream ID.
+ */
+ public static final int INVALID_STREAM_ID = Constants.Constant.INVALID_STREAM_ID;
+ /**
+ * Invalid filter ID.
+ */
+ public static final int INVALID_FILTER_ID = Constants.Constant.INVALID_FILTER_ID;
+ /**
+ * Invalid AV Sync ID.
+ */
+ public static final int INVALID_AV_SYNC_ID = Constants.Constant.INVALID_AV_SYNC_ID;
+ /**
+ * Invalid timestamp.
+ *
+ * <p>Returned by {@link android.media.tv.tuner.filter.TimeFilter#getSourceTime()},
+ * {@link android.media.tv.tuner.filter.TimeFilter#getTimeStamp()}, or
+ * {@link Tuner#getAvSyncTime(int)} when the requested timestamp is not available.
+ *
+ * @see android.media.tv.tuner.filter.TimeFilter#getSourceTime()
+ * @see android.media.tv.tuner.filter.TimeFilter#getTimeStamp()
+ * @see Tuner#getAvSyncTime(int)
+ */
+ public static final long INVALID_TIMESTAMP = -1L;
+
+
+ /** @hide */
+ @IntDef(prefix = "SCAN_TYPE_", value = {SCAN_TYPE_UNDEFINED, SCAN_TYPE_AUTO, SCAN_TYPE_BLIND})
+ @Retention(RetentionPolicy.SOURCE)
+ public @interface ScanType {}
+ /**
+ * Scan type undefined.
+ */
+ public static final int SCAN_TYPE_UNDEFINED = Constants.FrontendScanType.SCAN_UNDEFINED;
+ /**
+ * Scan type auto.
+ *
+ * <p> Tuner will send {@link android.media.tv.tuner.frontend.ScanCallback#onLocked}
+ */
+ public static final int SCAN_TYPE_AUTO = Constants.FrontendScanType.SCAN_AUTO;
+ /**
+ * Blind scan.
+ *
+ * <p>Frequency range is not specified. The {@link android.media.tv.tuner.Tuner} will scan an
+ * implementation specific range.
+ */
+ public static final int SCAN_TYPE_BLIND = Constants.FrontendScanType.SCAN_BLIND;
+
+
+ /** @hide */
+ @IntDef({RESULT_SUCCESS, RESULT_UNAVAILABLE, RESULT_NOT_INITIALIZED, RESULT_INVALID_STATE,
+ RESULT_INVALID_ARGUMENT, RESULT_OUT_OF_MEMORY, RESULT_UNKNOWN_ERROR})
+ @Retention(RetentionPolicy.SOURCE)
+ public @interface Result {}
+
+ /**
+ * Operation succeeded.
+ */
+ public static final int RESULT_SUCCESS = Constants.Result.SUCCESS;
+ /**
+ * Operation failed because the corresponding resources are not available.
+ */
+ public static final int RESULT_UNAVAILABLE = Constants.Result.UNAVAILABLE;
+ /**
+ * Operation failed because the corresponding resources are not initialized.
+ */
+ public static final int RESULT_NOT_INITIALIZED = Constants.Result.NOT_INITIALIZED;
+ /**
+ * Operation failed because it's not in a valid state.
+ */
+ public static final int RESULT_INVALID_STATE = Constants.Result.INVALID_STATE;
+ /**
+ * Operation failed because there are invalid arguments.
+ */
+ public static final int RESULT_INVALID_ARGUMENT = Constants.Result.INVALID_ARGUMENT;
+ /**
+ * Memory allocation failed.
+ */
+ public static final int RESULT_OUT_OF_MEMORY = Constants.Result.OUT_OF_MEMORY;
+ /**
+ * Operation failed due to unknown errors.
+ */
+ public static final int RESULT_UNKNOWN_ERROR = Constants.Result.UNKNOWN_ERROR;
+
+
+
private static final String TAG = "MediaTvTuner";
private static final boolean DEBUG = false;
@@ -93,23 +184,27 @@
public static final int DVR_TYPE_PLAYBACK = Constants.DvrType.PLAYBACK;
static {
- System.loadLibrary("media_tv_tuner");
- nativeInit();
+ try {
+ System.loadLibrary("media_tv_tuner");
+ nativeInit();
+ } catch (UnsatisfiedLinkError e) {
+ Log.d(TAG, "tuner JNI library not found!");
+ }
}
private final Context mContext;
private final TunerResourceManager mTunerResourceManager;
private final int mClientId;
- private List<Integer> mFrontendIds;
private Frontend mFrontend;
private EventHandler mHandler;
@Nullable
private FrontendInfo mFrontendInfo;
+ private Integer mFrontendHandle;
+ private int mFrontendType = FrontendSettings.TYPE_UNDEFINED;
- private List<Integer> mLnbIds;
private Lnb mLnb;
- private Integer mLnbId;
+ private Integer mLnbHandle;
@Nullable
private OnTuneEventListener mOnTuneEventListener;
@Nullable
@@ -233,7 +328,7 @@
/**
* Native method to open frontend of the given ID.
*/
- private native Frontend nativeOpenFrontendById(int id);
+ private native Frontend nativeOpenFrontendByHandle(int handle);
private native int nativeTune(int type, FrontendSettings settings);
private native int nativeStopTune();
private native int nativeScan(int settingsType, FrontendSettings settings, int scanType);
@@ -250,7 +345,7 @@
private native TimeFilter nativeOpenTimeFilter();
private native List<Integer> nativeGetLnbIds();
- private native Lnb nativeOpenLnbById(int id);
+ private native Lnb nativeOpenLnbByHandle(int handle);
private native Lnb nativeOpenLnbByName(String name);
private native Descrambler nativeOpenDescrambler();
@@ -359,6 +454,10 @@
/**
* Tunes the frontend to using the settings given.
*
+ * <p>Tuner resource manager (TRM) uses the client priority value to decide whether it is able
+ * to get frontend resource. If the client can't get the resource, this call returns {@link
+ * Result#RESULT_UNAVAILABLE}.
+ *
* <p>
* This locks the frontend to a frequency by providing signal
* delivery information. If previous tuning isn't completed, this stop the previous tuning, and
@@ -378,7 +477,8 @@
@RequiresPermission(android.Manifest.permission.ACCESS_TV_TUNER)
@Result
public int tune(@NonNull FrontendSettings settings) {
- TunerUtils.checkTunerPermission(mContext);
+ mFrontendType = settings.getType();
+ checkResource(TunerResourceManager.TUNER_RESOURCE_TYPE_FRONTEND);
mFrontendInfo = null;
return nativeTune(settings.getType(), settings);
}
@@ -411,14 +511,15 @@
*/
@RequiresPermission(android.Manifest.permission.ACCESS_TV_TUNER)
@Result
- public int scan(@NonNull FrontendSettings settings, @TunerConstants.ScanType int scanType,
+ public int scan(@NonNull FrontendSettings settings, @ScanType int scanType,
@NonNull @CallbackExecutor Executor executor, @NonNull ScanCallback scanCallback) {
- TunerUtils.checkTunerPermission(mContext);
if (mScanCallback != null || mScanCallbackExecutor != null) {
throw new IllegalStateException(
"Scan already in progress. stopScan must be called before a new scan can be "
+ "started.");
}
+ mFrontendType = settings.getType();
+ checkResource(TunerResourceManager.TUNER_RESOURCE_TYPE_FRONTEND);
mScanCallback = scanCallback;
mScanCallbackExecutor = executor;
mFrontendInfo = null;
@@ -446,6 +547,16 @@
return retVal;
}
+ private boolean requestFrontend() {
+ int[] feId = new int[1];
+ TunerFrontendRequest request = new TunerFrontendRequest(mClientId, mFrontendType);
+ boolean granted = mTunerResourceManager.requestFrontend(request, feId);
+ if (granted) {
+ mFrontendHandle = feId[0];
+ }
+ return granted;
+ }
+
/**
* Sets Low-Noise Block downconverter (LNB) for satellite frontend.
*
@@ -498,7 +609,7 @@
public int getAvSyncHwId(@NonNull Filter filter) {
TunerUtils.checkTunerPermission(mContext);
Integer id = nativeGetAvSyncHwId(filter);
- return id == null ? TunerConstants.INVALID_AV_SYNC_ID : id;
+ return id == null ? INVALID_AV_SYNC_ID : id;
}
/**
@@ -514,7 +625,7 @@
public long getAvSyncTime(int avSyncHwId) {
TunerUtils.checkTunerPermission(mContext);
Long time = nativeGetAvSyncTime(avSyncHwId);
- return time == null ? TunerConstants.TIMESTAMP_UNAVAILABLE : time;
+ return time == null ? INVALID_TIMESTAMP : time;
}
/**
@@ -579,22 +690,6 @@
return nativeGetDemuxCapabilities();
}
- private List<Integer> getFrontendIds() {
- mFrontendIds = nativeGetFrontendIds();
- return mFrontendIds;
- }
-
- private Frontend openFrontendById(int id) {
- if (mFrontendIds == null) {
- mFrontendIds = getFrontendIds();
- }
- if (!mFrontendIds.contains(id)) {
- return null;
- }
- mFrontend = nativeOpenFrontendById(id);
- return mFrontend;
- }
-
private void onFrontendEvent(int eventType) {
if (mOnTunerEventExecutor != null && mOnTuneEventListener != null) {
mOnTunerEventExecutor.execute(() -> mOnTuneEventListener.onTuneEvent(eventType));
@@ -731,11 +826,9 @@
public Lnb openLnb(@CallbackExecutor @NonNull Executor executor, @NonNull LnbCallback cb) {
Objects.requireNonNull(executor, "executor must not be null");
Objects.requireNonNull(cb, "LnbCallback must not be null");
- TunerUtils.checkTunerPermission(mContext);
- if (mLnbId == null && !requestLnb()) {
- return null;
- }
- return nativeOpenLnbById(mLnbId);
+ checkResource(TunerResourceManager.TUNER_RESOURCE_TYPE_LNB);
+ // TODO: update JNI code for LNB handle,
+ return nativeOpenLnbByHandle(mLnbHandle);
}
/**
@@ -763,7 +856,7 @@
TunerLnbRequest request = new TunerLnbRequest(mClientId);
boolean granted = mTunerResourceManager.requestLnb(request, lnbId);
if (granted) {
- mLnbId = lnbId[0];
+ mLnbHandle = lnbId[0];
}
return granted;
}
@@ -778,22 +871,6 @@
return nativeOpenTimeFilter();
}
- private List<Integer> getLnbIds() {
- mLnbIds = nativeGetLnbIds();
- return mLnbIds;
- }
-
- private Lnb openLnbById(int id) {
- if (mLnbIds == null) {
- mLnbIds = getLnbIds();
- }
- if (!mLnbIds.contains(id)) {
- return null;
- }
- mLnb = nativeOpenLnbById(id);
- return mLnb;
- }
-
private void onLnbEvent(int eventType) {
if (mHandler != null) {
mHandler.sendMessage(mHandler.obtainMessage(MSG_ON_LNB_EVENT, eventType, 0));
@@ -857,4 +934,23 @@
DvrPlayback dvr = nativeOpenDvrPlayback(bufferSize);
return dvr;
}
+
+ private boolean checkResource(int resourceType) {
+ // TODO: demux and descrambler
+ switch (resourceType) {
+ case TunerResourceManager.TUNER_RESOURCE_TYPE_FRONTEND: {
+ if (mFrontendHandle == null && !requestFrontend()) {
+ return false;
+ }
+ break;
+ }
+ case TunerResourceManager.TUNER_RESOURCE_TYPE_LNB: {
+ if (mLnbHandle == null && !requestLnb()) {
+ return false;
+ }
+ break;
+ }
+ }
+ return true;
+ }
}
diff --git a/media/java/android/media/tv/tuner/TunerConstants.java b/media/java/android/media/tv/tuner/TunerConstants.java
deleted file mode 100644
index 6d89962..0000000
--- a/media/java/android/media/tv/tuner/TunerConstants.java
+++ /dev/null
@@ -1,122 +0,0 @@
-/*
- * Copyright 2019 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.media.tv.tuner;
-
-import android.annotation.IntDef;
-import android.annotation.SystemApi;
-import android.hardware.tv.tuner.V1_0.Constants;
-
-import java.lang.annotation.Retention;
-import java.lang.annotation.RetentionPolicy;
-
-/**
- * Constants for tuner framework.
- *
- * @hide
- */
-@SystemApi
-public final class TunerConstants {
- /**
- * Invalid TS packet ID.
- */
- public static final int INVALID_TS_PID = Constants.Constant.INVALID_TS_PID;
- /**
- * Invalid stream ID.
- */
- public static final int INVALID_STREAM_ID = Constants.Constant.INVALID_STREAM_ID;
- /**
- * Invalid filter ID.
- */
- public static final int INVALID_FILTER_ID = Constants.Constant.INVALID_FILTER_ID;
- /**
- * Invalid AV Sync ID.
- */
- public static final int INVALID_AV_SYNC_ID = Constants.Constant.INVALID_AV_SYNC_ID;
- /**
- * Timestamp is unavailable.
- *
- * <p>Returned by {@link android.media.tv.tuner.filter.TimeFilter#getSourceTime()},
- * {@link android.media.tv.tuner.filter.TimeFilter#getTimeStamp()}, or
- * {@link Tuner#getAvSyncTime(int)} when the requested timestamp is not available.
- *
- * @see android.media.tv.tuner.filter.TimeFilter#getSourceTime()
- * @see android.media.tv.tuner.filter.TimeFilter#getTimeStamp()
- * @see Tuner#getAvSyncTime(int)
- * @hide
- */
- public static final long TIMESTAMP_UNAVAILABLE = -1L;
-
- /** @hide */
- @IntDef(prefix = "SCAN_TYPE_", value = {SCAN_TYPE_UNDEFINED, SCAN_TYPE_AUTO, SCAN_TYPE_BLIND})
- @Retention(RetentionPolicy.SOURCE)
- public @interface ScanType {}
- /**
- * Scan type undefined.
- */
- public static final int SCAN_TYPE_UNDEFINED = Constants.FrontendScanType.SCAN_UNDEFINED;
- /**
- * Scan type auto.
- *
- * <p> Tuner will send {@link android.media.tv.tuner.frontend.ScanCallback#onLocked}
- */
- public static final int SCAN_TYPE_AUTO = Constants.FrontendScanType.SCAN_AUTO;
- /**
- * Blind scan.
- *
- * <p>Frequency range is not specified. The {@link android.media.tv.tuner.Tuner} will scan an
- * implementation specific range.
- */
- public static final int SCAN_TYPE_BLIND = Constants.FrontendScanType.SCAN_BLIND;
-
- /** @hide */
- @IntDef({RESULT_SUCCESS, RESULT_UNAVAILABLE, RESULT_NOT_INITIALIZED, RESULT_INVALID_STATE,
- RESULT_INVALID_ARGUMENT, RESULT_OUT_OF_MEMORY, RESULT_UNKNOWN_ERROR})
- @Retention(RetentionPolicy.SOURCE)
- public @interface Result {}
-
- /**
- * Operation succeeded.
- */
- public static final int RESULT_SUCCESS = Constants.Result.SUCCESS;
- /**
- * Operation failed because the corresponding resources are not available.
- */
- public static final int RESULT_UNAVAILABLE = Constants.Result.UNAVAILABLE;
- /**
- * Operation failed because the corresponding resources are not initialized.
- */
- public static final int RESULT_NOT_INITIALIZED = Constants.Result.NOT_INITIALIZED;
- /**
- * Operation failed because it's not in a valid state.
- */
- public static final int RESULT_INVALID_STATE = Constants.Result.INVALID_STATE;
- /**
- * Operation failed because there are invalid arguments.
- */
- public static final int RESULT_INVALID_ARGUMENT = Constants.Result.INVALID_ARGUMENT;
- /**
- * Memory allocation failed.
- */
- public static final int RESULT_OUT_OF_MEMORY = Constants.Result.OUT_OF_MEMORY;
- /**
- * Operation failed due to unknown errors.
- */
- public static final int RESULT_UNKNOWN_ERROR = Constants.Result.UNKNOWN_ERROR;
-
- private TunerConstants() {
- }
-}
diff --git a/media/java/android/media/tv/tuner/TunerUtils.java b/media/java/android/media/tv/tuner/TunerUtils.java
index 2258ee5..c3be12a 100644
--- a/media/java/android/media/tv/tuner/TunerUtils.java
+++ b/media/java/android/media/tv/tuner/TunerUtils.java
@@ -171,22 +171,22 @@
*/
@Nullable
public static void throwExceptionForResult(
- @TunerConstants.Result int r, @Nullable String msg) {
+ @Tuner.Result int r, @Nullable String msg) {
if (msg == null) {
msg = "";
}
switch (r) {
- case TunerConstants.RESULT_INVALID_ARGUMENT:
+ case Tuner.RESULT_INVALID_ARGUMENT:
throw new IllegalArgumentException(msg);
- case TunerConstants.RESULT_INVALID_STATE:
+ case Tuner.RESULT_INVALID_STATE:
throw new IllegalStateException(msg);
- case TunerConstants.RESULT_NOT_INITIALIZED:
+ case Tuner.RESULT_NOT_INITIALIZED:
throw new IllegalStateException("Invalid state: not initialized. " + msg);
- case TunerConstants.RESULT_OUT_OF_MEMORY:
+ case Tuner.RESULT_OUT_OF_MEMORY:
throw new OutOfMemoryError(msg);
- case TunerConstants.RESULT_UNAVAILABLE:
+ case Tuner.RESULT_UNAVAILABLE:
throw new IllegalStateException("Invalid state: resource unavailable. " + msg);
- case TunerConstants.RESULT_UNKNOWN_ERROR:
+ case Tuner.RESULT_UNKNOWN_ERROR:
throw new RuntimeException("Unknown error" + msg);
default:
break;
diff --git a/media/java/android/media/tv/tuner/dvr/DvrPlayback.java b/media/java/android/media/tv/tuner/dvr/DvrPlayback.java
index 37a016e..0d10d94 100644
--- a/media/java/android/media/tv/tuner/dvr/DvrPlayback.java
+++ b/media/java/android/media/tv/tuner/dvr/DvrPlayback.java
@@ -21,7 +21,7 @@
import android.annotation.NonNull;
import android.annotation.SystemApi;
import android.hardware.tv.tuner.V1_0.Constants;
-import android.media.tv.tuner.TunerConstants.Result;
+import android.media.tv.tuner.Tuner.Result;
import android.media.tv.tuner.filter.Filter;
import android.os.ParcelFileDescriptor;
diff --git a/media/java/android/media/tv/tuner/dvr/DvrRecorder.java b/media/java/android/media/tv/tuner/dvr/DvrRecorder.java
index d06356c..dbda7bb 100644
--- a/media/java/android/media/tv/tuner/dvr/DvrRecorder.java
+++ b/media/java/android/media/tv/tuner/dvr/DvrRecorder.java
@@ -19,7 +19,7 @@
import android.annotation.BytesLong;
import android.annotation.NonNull;
import android.annotation.SystemApi;
-import android.media.tv.tuner.TunerConstants.Result;
+import android.media.tv.tuner.Tuner.Result;
import android.media.tv.tuner.filter.Filter;
import android.os.ParcelFileDescriptor;
diff --git a/media/java/android/media/tv/tuner/filter/Filter.java b/media/java/android/media/tv/tuner/filter/Filter.java
index 4777fe8..8dc0622 100644
--- a/media/java/android/media/tv/tuner/filter/Filter.java
+++ b/media/java/android/media/tv/tuner/filter/Filter.java
@@ -22,7 +22,7 @@
import android.annotation.Nullable;
import android.annotation.SystemApi;
import android.hardware.tv.tuner.V1_0.Constants;
-import android.media.tv.tuner.TunerConstants.Result;
+import android.media.tv.tuner.Tuner.Result;
import android.media.tv.tuner.TunerUtils;
import java.lang.annotation.Retention;
diff --git a/media/java/android/media/tv/tuner/filter/TimeFilter.java b/media/java/android/media/tv/tuner/filter/TimeFilter.java
index 371ccc4..be0a055 100644
--- a/media/java/android/media/tv/tuner/filter/TimeFilter.java
+++ b/media/java/android/media/tv/tuner/filter/TimeFilter.java
@@ -17,8 +17,8 @@
package android.media.tv.tuner.filter;
import android.annotation.SystemApi;
-import android.media.tv.tuner.TunerConstants;
-import android.media.tv.tuner.TunerConstants.Result;
+import android.media.tv.tuner.Tuner;
+import android.media.tv.tuner.Tuner.Result;
import android.media.tv.tuner.TunerUtils;
/**
@@ -35,17 +35,6 @@
@SystemApi
public class TimeFilter implements AutoCloseable {
- /**
- * Timestamp is unavailable.
- *
- * <p>Returned by {@link #getSourceTime()} or {@link #getTimeStamp()} when the requested
- * timestamp is not available.
- *
- * @see #getSourceTime()
- * @see #getTimeStamp()
- */
- public static final long TIMESTAMP_UNAVAILABLE = -1L;
-
private native int nativeSetTimestamp(long timestamp);
private native int nativeClearTimestamp();
@@ -108,12 +97,12 @@
*
* @return current timestamp in the time filter. It's based on the 90KHz counter, and it's
* the same format as PTS (Presentation Time Stamp) defined in ISO/IEC 13818-1:2019. The
- * timestamps may or may not be related to PTS or DTS. Returns {@link #TIMESTAMP_UNAVAILABLE}
- * if the timestamp is never set.
+ * timestamps may or may not be related to PTS or DTS. Returns
+ * {@link Tuner#INVALID_TIMESTAMP} if the timestamp is never set.
*/
public long getTimeStamp() {
if (!mEnable) {
- return TIMESTAMP_UNAVAILABLE;
+ return Tuner.INVALID_TIMESTAMP;
}
return nativeGetTimestamp();
}
@@ -126,11 +115,11 @@
* @return first timestamp of incoming data stream. It's based on the 90KHz counter, and
* it's the same format as PTS (Presentation Time Stamp) defined in ISO/IEC 13818-1:2019.
* The timestamps may or may not be related to PTS or DTS. Returns
- * {@link #TIMESTAMP_UNAVAILABLE} if the timestamp is not available.
+ * {@link Tuner#INVALID_TIMESTAMP} if the timestamp is not available.
*/
public long getSourceTime() {
if (!mEnable) {
- return TIMESTAMP_UNAVAILABLE;
+ return Tuner.INVALID_TIMESTAMP;
}
return nativeGetSourceTime();
}
@@ -144,7 +133,7 @@
@Override
public void close() {
int res = nativeClose();
- if (res != TunerConstants.RESULT_SUCCESS) {
+ if (res != Tuner.RESULT_SUCCESS) {
TunerUtils.throwExceptionForResult(res, "Failed to close time filter.");
}
}
diff --git a/media/java/android/media/tv/tunerresourcemanager/TunerResourceManager.java b/media/java/android/media/tv/tunerresourcemanager/TunerResourceManager.java
index 9dddcd4..63a71e2 100644
--- a/media/java/android/media/tv/tunerresourcemanager/TunerResourceManager.java
+++ b/media/java/android/media/tv/tunerresourcemanager/TunerResourceManager.java
@@ -17,6 +17,7 @@
package android.media.tv.tunerresourcemanager;
import android.annotation.CallbackExecutor;
+import android.annotation.IntDef;
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.annotation.RequiresFeature;
@@ -27,6 +28,8 @@
import android.os.RemoteException;
import android.util.Log;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
import java.util.concurrent.Executor;
/**
@@ -61,6 +64,24 @@
private static final boolean DEBUG = Log.isLoggable(TAG, Log.DEBUG);
public static final int INVALID_RESOURCE_HANDLE = -1;
+ /**
+ * Tuner resource type to help generate resource handle
+ */
+ @IntDef({
+ TUNER_RESOURCE_TYPE_FRONTEND,
+ TUNER_RESOURCE_TYPE_DEMUX,
+ TUNER_RESOURCE_TYPE_DESCRAMBLER,
+ TUNER_RESOURCE_TYPE_LNB,
+ TUNER_RESOURCE_TYPE_CAS_SESSION,
+ })
+ @Retention(RetentionPolicy.SOURCE)
+ public @interface TunerResourceType {}
+
+ public static final int TUNER_RESOURCE_TYPE_FRONTEND = 0;
+ public static final int TUNER_RESOURCE_TYPE_DEMUX = 1;
+ public static final int TUNER_RESOURCE_TYPE_DESCRAMBLER = 2;
+ public static final int TUNER_RESOURCE_TYPE_LNB = 3;
+ public static final int TUNER_RESOURCE_TYPE_CAS_SESSION = 4;
private final ITunerResourceManager mService;
private final int mUserId;
diff --git a/media/jni/android_media_tv_Tuner.cpp b/media/jni/android_media_tv_Tuner.cpp
index a37c9e5..bbeb451 100644
--- a/media/jni/android_media_tv_Tuner.cpp
+++ b/media/jni/android_media_tv_Tuner.cpp
@@ -1410,6 +1410,10 @@
return (IDescrambler *)env->GetLongField(descrambler, gFields.descramblerContext);
}
+static uint32_t getResourceIdFromHandle(jint handle) {
+ return (handle & 0x00ff0000) >> 16;
+}
+
static DemuxPid getDemuxPid(int pidType, int pid) {
DemuxPid demuxPid;
if ((int)pidType == 1) {
@@ -1968,8 +1972,10 @@
return tuner->getFrontendIds();
}
-static jobject android_media_tv_Tuner_open_frontend_by_id(JNIEnv *env, jobject thiz, jint id) {
+static jobject android_media_tv_Tuner_open_frontend_by_handle(
+ JNIEnv *env, jobject thiz, jint handle) {
sp<JTuner> tuner = getTuner(env, thiz);
+ uint32_t id = getResourceIdFromHandle(handle);
return tuner->openFrontendById(id);
}
@@ -2045,8 +2051,9 @@
return tuner->getLnbIds();
}
-static jobject android_media_tv_Tuner_open_lnb_by_id(JNIEnv *env, jobject thiz, jint id) {
+static jobject android_media_tv_Tuner_open_lnb_by_handle(JNIEnv *env, jobject thiz, jint handle) {
sp<JTuner> tuner = getTuner(env, thiz);
+ uint32_t id = getResourceIdFromHandle(handle);
return tuner->openLnbById(id);
}
@@ -2924,8 +2931,8 @@
{ "nativeSetup", "()V", (void *)android_media_tv_Tuner_native_setup },
{ "nativeGetFrontendIds", "()Ljava/util/List;",
(void *)android_media_tv_Tuner_get_frontend_ids },
- { "nativeOpenFrontendById", "(I)Landroid/media/tv/tuner/Tuner$Frontend;",
- (void *)android_media_tv_Tuner_open_frontend_by_id },
+ { "nativeOpenFrontendByHandle", "(I)Landroid/media/tv/tuner/Tuner$Frontend;",
+ (void *)android_media_tv_Tuner_open_frontend_by_handle },
{ "nativeTune", "(ILandroid/media/tv/tuner/frontend/FrontendSettings;)I",
(void *)android_media_tv_Tuner_tune },
{ "nativeStopTune", "()I", (void *)android_media_tv_Tuner_stop_tune },
@@ -2950,8 +2957,8 @@
(void *)android_media_tv_Tuner_open_time_filter },
{ "nativeGetLnbIds", "()Ljava/util/List;",
(void *)android_media_tv_Tuner_get_lnb_ids },
- { "nativeOpenLnbById", "(I)Landroid/media/tv/tuner/Lnb;",
- (void *)android_media_tv_Tuner_open_lnb_by_id },
+ { "nativeOpenLnbByHandle", "(I)Landroid/media/tv/tuner/Lnb;",
+ (void *)android_media_tv_Tuner_open_lnb_by_handle },
{ "nativeOpenLnbByName", "(Ljava/lang/String;)Landroid/media/tv/tuner/Lnb;",
(void *)android_media_tv_Tuner_open_lnb_by_name },
{ "nativeOpenDescrambler", "()Landroid/media/tv/tuner/Descrambler;",
diff --git a/media/jni/audioeffect/android_media_Visualizer.cpp b/media/jni/audioeffect/android_media_Visualizer.cpp
index 1362433..f9a77f4 100644
--- a/media/jni/audioeffect/android_media_Visualizer.cpp
+++ b/media/jni/audioeffect/android_media_Visualizer.cpp
@@ -196,7 +196,6 @@
callbackInfo->visualizer_ref,
NATIVE_EVENT_PCM_CAPTURE,
samplingrate,
- 0,
jArray);
}
}
@@ -217,7 +216,6 @@
callbackInfo->visualizer_ref,
NATIVE_EVENT_FFT_CAPTURE,
samplingrate,
- 0,
jArray);
}
}
@@ -286,7 +284,7 @@
// Get the postEvent method
fields.midPostNativeEvent = env->GetStaticMethodID(
fields.clazzEffect,
- "postEventFromNative", "(Ljava/lang/Object;IIILjava/lang/Object;)V");
+ "postEventFromNative", "(Ljava/lang/Object;II[B)V");
if (fields.midPostNativeEvent == NULL) {
ALOGE("Can't find Visualizer.%s", "postEventFromNative");
return;
@@ -343,7 +341,7 @@
fields.midPostNativeEvent,
callbackInfo->visualizer_ref,
NATIVE_EVENT_SERVER_DIED,
- 0, 0, NULL);
+ 0, NULL);
}
}
diff --git a/packages/SettingsLib/res/drawable/ic_media_group_device.xml b/packages/SettingsLib/res/drawable/ic_media_group_device.xml
new file mode 100644
index 0000000..ba5e651
--- /dev/null
+++ b/packages/SettingsLib/res/drawable/ic_media_group_device.xml
@@ -0,0 +1,32 @@
+<!--
+ 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
+ -->
+
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+ android:width="24dp"
+ android:height="24dp"
+ android:viewportWidth="24"
+ android:viewportHeight="24"
+ android:tint="?android:attr/colorControlNormal">
+ <path
+ android:pathData="M18.2,1L9.8,1C8.81,1 8,1.81 8,2.8v14.4c0,0.99 0.81,1.79 1.8,1.79l8.4,0.01c0.99,0 1.8,-0.81 1.8,-1.8L20,2.8c0,-0.99 -0.81,-1.8 -1.8,-1.8zM14,3c1.1,0 2,0.89 2,2s-0.9,2 -2,2 -2,-0.89 -2,-2 0.9,-2 2,-2zM14,16.5c-2.21,0 -4,-1.79 -4,-4s1.79,-4 4,-4 4,1.79 4,4 -1.79,4 -4,4z"
+ android:fillColor="#000000"/>
+ <path
+ android:pathData="M14,12.5m-2.5,0a2.5,2.5 0,1 1,5 0a2.5,2.5 0,1 1,-5 0"
+ android:fillColor="#000000"/>
+ <path
+ android:pathData="M6,5H4v16c0,1.1 0.89,2 2,2h10v-2H6V5z"
+ android:fillColor="#000000"/>
+</vector>
\ No newline at end of file
diff --git a/packages/SettingsLib/res/values/strings.xml b/packages/SettingsLib/res/values/strings.xml
index 00f6bcb..a797066 100644
--- a/packages/SettingsLib/res/values/strings.xml
+++ b/packages/SettingsLib/res/values/strings.xml
@@ -1039,7 +1039,7 @@
<!-- Title for the accessibility preference to configure display color space correction. [CHAR LIMIT=NONE] -->
<string name="accessibility_display_daltonizer_preference_title">Color correction</string>
<!-- Subtitle for the accessibility preference to configure display color space correction. [CHAR LIMIT=NONE] -->
- <string name="accessibility_display_daltonizer_preference_subtitle">Color correction helps the device display more accurate colors. Color correction may be helpful for people with colorblindness.</string>
+ <string name="accessibility_display_daltonizer_preference_subtitle"><![CDATA[Color correction allows you to adjust how colors are displayed on your device]]></string>
<!-- Summary shown for color space correction preference when its value is overridden by another preference [CHAR LIMIT=35] -->
<string name="daltonizer_type_overridden">Overridden by <xliff:g id="title" example="Simulate color space">%1$s</xliff:g></string>
diff --git a/packages/SettingsLib/src/com/android/settingslib/media/InfoMediaDevice.java b/packages/SettingsLib/src/com/android/settingslib/media/InfoMediaDevice.java
index b725ba5..85fa988 100644
--- a/packages/SettingsLib/src/com/android/settingslib/media/InfoMediaDevice.java
+++ b/packages/SettingsLib/src/com/android/settingslib/media/InfoMediaDevice.java
@@ -15,11 +15,17 @@
*/
package com.android.settingslib.media;
+import static android.media.MediaRoute2Info.TYPE_GROUP;
+import static android.media.MediaRoute2Info.TYPE_REMOTE_SPEAKER;
+import static android.media.MediaRoute2Info.TYPE_REMOTE_TV;
+
import android.content.Context;
import android.graphics.drawable.Drawable;
import android.media.MediaRoute2Info;
import android.media.MediaRouter2Manager;
+import androidx.annotation.VisibleForTesting;
+
import com.android.settingslib.R;
import com.android.settingslib.bluetooth.BluetoothUtils;
@@ -51,7 +57,23 @@
public Drawable getIcon() {
//TODO(b/120669861): Return remote device icon uri once api is ready.
return BluetoothUtils.buildBtRainbowDrawable(mContext,
- mContext.getDrawable(R.drawable.ic_media_device), getId().hashCode());
+ mContext.getDrawable(getDrawableResId()), getId().hashCode());
+ }
+
+ @VisibleForTesting
+ int getDrawableResId() {
+ int resId;
+ switch (mRouteInfo.getType()) {
+ case TYPE_GROUP:
+ resId = R.drawable.ic_media_group_device;
+ break;
+ case TYPE_REMOTE_TV:
+ case TYPE_REMOTE_SPEAKER:
+ default:
+ resId = R.drawable.ic_media_device;
+ break;
+ }
+ return resId;
}
@Override
diff --git a/packages/SettingsLib/src/com/android/settingslib/media/PhoneMediaDevice.java b/packages/SettingsLib/src/com/android/settingslib/media/PhoneMediaDevice.java
index 166fbaa..af88723 100644
--- a/packages/SettingsLib/src/com/android/settingslib/media/PhoneMediaDevice.java
+++ b/packages/SettingsLib/src/com/android/settingslib/media/PhoneMediaDevice.java
@@ -15,11 +15,17 @@
*/
package com.android.settingslib.media;
+import static android.media.MediaRoute2Info.TYPE_BUILTIN_SPEAKER;
+import static android.media.MediaRoute2Info.TYPE_WIRED_HEADPHONES;
+import static android.media.MediaRoute2Info.TYPE_WIRED_HEADSET;
+
import android.content.Context;
import android.graphics.drawable.Drawable;
import android.media.MediaRoute2Info;
import android.media.MediaRouter2Manager;
+import androidx.annotation.VisibleForTesting;
+
import com.android.settingslib.R;
import com.android.settingslib.bluetooth.BluetoothUtils;
@@ -43,7 +49,18 @@
@Override
public String getName() {
- return mContext.getString(R.string.media_transfer_this_device_name);
+ CharSequence name;
+ switch (mRouteInfo.getType()) {
+ case TYPE_WIRED_HEADSET:
+ case TYPE_WIRED_HEADPHONES:
+ name = mRouteInfo.getName();
+ break;
+ case TYPE_BUILTIN_SPEAKER:
+ default:
+ name = mContext.getString(R.string.media_transfer_this_device_name);
+ break;
+ }
+ return name.toString();
}
@Override
@@ -54,7 +71,23 @@
@Override
public Drawable getIcon() {
return BluetoothUtils.buildBtRainbowDrawable(mContext,
- mContext.getDrawable(R.drawable.ic_smartphone), getId().hashCode());
+ mContext.getDrawable(getDrawableResId()), getId().hashCode());
+ }
+
+ @VisibleForTesting
+ int getDrawableResId() {
+ int resId;
+ switch (mRouteInfo.getType()) {
+ case TYPE_WIRED_HEADSET:
+ case TYPE_WIRED_HEADPHONES:
+ resId = com.android.internal.R.drawable.ic_bt_headphones_a2dp;
+ break;
+ case TYPE_BUILTIN_SPEAKER:
+ default:
+ resId = R.drawable.ic_smartphone;
+ break;
+ }
+ return resId;
}
@Override
diff --git a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/media/InfoMediaDeviceTest.java b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/media/InfoMediaDeviceTest.java
index 77a67c2..685c834 100644
--- a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/media/InfoMediaDeviceTest.java
+++ b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/media/InfoMediaDeviceTest.java
@@ -16,6 +16,10 @@
package com.android.settingslib.media;
+import static android.media.MediaRoute2Info.TYPE_GROUP;
+import static android.media.MediaRoute2Info.TYPE_REMOTE_SPEAKER;
+import static android.media.MediaRoute2Info.TYPE_REMOTE_TV;
+
import static com.google.common.truth.Truth.assertThat;
import static org.mockito.Mockito.when;
@@ -86,4 +90,19 @@
assertThat(mInfoMediaDevice.getId()).isEqualTo(TEST_ID);
}
+
+ @Test
+ public void getDrawableResId_returnCorrectResId() {
+ when(mRouteInfo.getType()).thenReturn(TYPE_REMOTE_TV);
+
+ assertThat(mInfoMediaDevice.getDrawableResId()).isEqualTo(R.drawable.ic_media_device);
+
+ when(mRouteInfo.getType()).thenReturn(TYPE_REMOTE_SPEAKER);
+
+ assertThat(mInfoMediaDevice.getDrawableResId()).isEqualTo(R.drawable.ic_media_device);
+
+ when(mRouteInfo.getType()).thenReturn(TYPE_GROUP);
+
+ assertThat(mInfoMediaDevice.getDrawableResId()).isEqualTo(R.drawable.ic_media_group_device);
+ }
}
diff --git a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/media/PhoneMediaDeviceTest.java b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/media/PhoneMediaDeviceTest.java
index db984fb..4c5cd96 100644
--- a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/media/PhoneMediaDeviceTest.java
+++ b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/media/PhoneMediaDeviceTest.java
@@ -16,15 +16,23 @@
package com.android.settingslib.media;
+import static android.media.MediaRoute2Info.TYPE_BUILTIN_SPEAKER;
+import static android.media.MediaRoute2Info.TYPE_WIRED_HEADPHONES;
+import static android.media.MediaRoute2Info.TYPE_WIRED_HEADSET;
+
import static com.google.common.truth.Truth.assertThat;
+import static org.mockito.Mockito.when;
+
import android.content.Context;
+import android.media.MediaRoute2Info;
import com.android.settingslib.R;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
+import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
import org.robolectric.RobolectricTestRunner;
import org.robolectric.RuntimeEnvironment;
@@ -32,6 +40,9 @@
@RunWith(RobolectricTestRunner.class)
public class PhoneMediaDeviceTest {
+ @Mock
+ private MediaRoute2Info mInfo;
+
private Context mContext;
private PhoneMediaDevice mPhoneMediaDevice;
@@ -41,7 +52,7 @@
mContext = RuntimeEnvironment.application;
mPhoneMediaDevice =
- new PhoneMediaDevice(mContext, null, null, null);
+ new PhoneMediaDevice(mContext, null, mInfo, null);
}
@Test
@@ -58,4 +69,42 @@
assertThat(mPhoneMediaDevice.getSummary()).isEmpty();
}
+
+ @Test
+ public void getDrawableResId_returnCorrectResId() {
+ when(mInfo.getType()).thenReturn(TYPE_WIRED_HEADPHONES);
+
+ assertThat(mPhoneMediaDevice.getDrawableResId())
+ .isEqualTo(com.android.internal.R.drawable.ic_bt_headphones_a2dp);
+
+ when(mInfo.getType()).thenReturn(TYPE_WIRED_HEADSET);
+
+ assertThat(mPhoneMediaDevice.getDrawableResId())
+ .isEqualTo(com.android.internal.R.drawable.ic_bt_headphones_a2dp);
+
+ when(mInfo.getType()).thenReturn(TYPE_BUILTIN_SPEAKER);
+
+ assertThat(mPhoneMediaDevice.getDrawableResId()).isEqualTo(R.drawable.ic_smartphone);
+ }
+
+ @Test
+ public void getName_returnCorrectName() {
+ final String deviceName = "test_name";
+
+ when(mInfo.getType()).thenReturn(TYPE_WIRED_HEADPHONES);
+ when(mInfo.getName()).thenReturn(deviceName);
+
+ assertThat(mPhoneMediaDevice.getName())
+ .isEqualTo(deviceName);
+
+ when(mInfo.getType()).thenReturn(TYPE_WIRED_HEADSET);
+
+ assertThat(mPhoneMediaDevice.getName())
+ .isEqualTo(deviceName);
+
+ when(mInfo.getType()).thenReturn(TYPE_BUILTIN_SPEAKER);
+
+ assertThat(mPhoneMediaDevice.getName())
+ .isEqualTo(mContext.getString(R.string.media_transfer_this_device_name));
+ }
}
diff --git a/packages/SystemUI/res/layout/global_screenshot.xml b/packages/SystemUI/res/layout/global_screenshot.xml
index a76f961..d506e7e 100644
--- a/packages/SystemUI/res/layout/global_screenshot.xml
+++ b/packages/SystemUI/res/layout/global_screenshot.xml
@@ -58,13 +58,15 @@
android:elevation="@dimen/screenshot_preview_elevation"
android:visibility="gone"
android:background="@drawable/screenshot_rounded_corners"
- android:adjustViewBounds="true"/>
+ android:adjustViewBounds="true"
+ android:contentDescription="@string/screenshot_preview_description"/>
<FrameLayout
android:id="@+id/global_screenshot_dismiss_button"
android:layout_width="@dimen/screenshot_dismiss_button_tappable_size"
android:layout_height="@dimen/screenshot_dismiss_button_tappable_size"
android:elevation="7dp"
- android:visibility="gone">
+ android:visibility="gone"
+ android:contentDescription="@string/screenshot_dismiss_ui_description">
<ImageView
android:layout_width="match_parent"
android:layout_height="match_parent"
diff --git a/packages/SystemUI/res/values/strings.xml b/packages/SystemUI/res/values/strings.xml
index 3543073..93bafdb 100644
--- a/packages/SystemUI/res/values/strings.xml
+++ b/packages/SystemUI/res/values/strings.xml
@@ -233,6 +233,10 @@
<!-- Notification text displayed when we fail to take a screenshot. [CHAR LIMIT=100] -->
<string name="screenshot_failed_to_capture_text">Taking screenshots isn\'t allowed by the app or
your organization</string>
+ <!-- Content description indicating that tapping a button will dismiss the screenshots UI [CHAR LIMIT=NONE] -->
+ <string name="screenshot_dismiss_ui_description">Dismiss screenshot</string>
+ <!-- Content description indicating that tapping will open an app to view/edit the screenshot. [CHAR LIMIT=NONE] -->
+ <string name="screenshot_preview_description">Open screenshot</string>
<!-- Notification title displayed for screen recording [CHAR LIMIT=50]-->
<string name="screenrecord_name">Screen Recorder</string>
diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardUpdateMonitor.java b/packages/SystemUI/src/com/android/keyguard/KeyguardUpdateMonitor.java
index 431c451..90df124 100644
--- a/packages/SystemUI/src/com/android/keyguard/KeyguardUpdateMonitor.java
+++ b/packages/SystemUI/src/com/android/keyguard/KeyguardUpdateMonitor.java
@@ -2740,6 +2740,8 @@
mBroadcastDispatcher.unregisterReceiver(mBroadcastReceiver);
mBroadcastDispatcher.unregisterReceiver(mBroadcastAllReceiver);
+
+ mHandler.removeCallbacksAndMessages(null);
}
@Override
diff --git a/packages/SystemUI/src/com/android/systemui/media/MediaControlPanel.java b/packages/SystemUI/src/com/android/systemui/media/MediaControlPanel.java
index a161d03..e208ee2 100644
--- a/packages/SystemUI/src/com/android/systemui/media/MediaControlPanel.java
+++ b/packages/SystemUI/src/com/android/systemui/media/MediaControlPanel.java
@@ -33,7 +33,6 @@
import android.media.session.MediaController;
import android.media.session.MediaSession;
import android.media.session.PlaybackState;
-import android.os.Handler;
import android.util.Log;
import android.view.KeyEvent;
import android.view.LayoutInflater;
@@ -64,6 +63,7 @@
public class MediaControlPanel implements NotificationMediaManager.MediaListener {
private static final String TAG = "MediaControlPanel";
private final NotificationMediaManager mMediaManager;
+ private final Executor mForegroundExecutor;
private final Executor mBackgroundExecutor;
private Context mContext;
@@ -102,15 +102,18 @@
* @param manager
* @param layoutId layout resource to use for this control panel
* @param actionIds resource IDs for action buttons in the layout
+ * @param foregroundExecutor foreground executor
* @param backgroundExecutor background executor, used for processing artwork
*/
public MediaControlPanel(Context context, ViewGroup parent, NotificationMediaManager manager,
- @LayoutRes int layoutId, int[] actionIds, Executor backgroundExecutor) {
+ @LayoutRes int layoutId, int[] actionIds, Executor foregroundExecutor,
+ Executor backgroundExecutor) {
mContext = context;
LayoutInflater inflater = LayoutInflater.from(mContext);
mMediaNotifView = (LinearLayout) inflater.inflate(layoutId, parent, false);
mMediaManager = manager;
mActionIds = actionIds;
+ mForegroundExecutor = foregroundExecutor;
mBackgroundExecutor = backgroundExecutor;
}
@@ -176,15 +179,17 @@
mMediaNotifView.setBackgroundTintList(ColorStateList.valueOf(mBackgroundColor));
// Click action
- mMediaNotifView.setOnClickListener(v -> {
- try {
- contentIntent.send();
- // Also close shade
- mContext.sendBroadcast(new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS));
- } catch (PendingIntent.CanceledException e) {
- Log.e(TAG, "Pending intent was canceled", e);
- }
- });
+ if (contentIntent != null) {
+ mMediaNotifView.setOnClickListener(v -> {
+ try {
+ contentIntent.send();
+ // Also close shade
+ mContext.sendBroadcast(new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS));
+ } catch (PendingIntent.CanceledException e) {
+ Log.e(TAG, "Pending intent was canceled", e);
+ }
+ });
+ }
// App icon
ImageView appIcon = mMediaNotifView.findViewById(R.id.icon);
@@ -316,7 +321,7 @@
// Now that it's resized, update the UI
final RoundedBitmapDrawable result = roundedDrawable;
- albumView.getHandler().post(() -> {
+ mForegroundExecutor.execute(() -> {
if (result != null) {
albumView.setImageDrawable(result);
albumView.setVisibility(View.VISIBLE);
@@ -335,8 +340,7 @@
if (mSeamless == null) {
return;
}
- Handler handler = mSeamless.getHandler();
- handler.post(() -> {
+ mForegroundExecutor.execute(() -> {
updateChipInternal(device);
});
}
@@ -401,12 +405,15 @@
new KeyEvent(KeyEvent.ACTION_DOWN, keyCode));
mContext.sendBroadcast(intent);
} else {
- Log.d(TAG, "No receiver to restart");
// If we don't have a receiver, try relaunching the activity instead
- try {
- mController.getSessionActivity().send();
- } catch (PendingIntent.CanceledException e) {
- Log.e(TAG, "Pending intent was canceled", e);
+ if (mController.getSessionActivity() != null) {
+ try {
+ mController.getSessionActivity().send();
+ } catch (PendingIntent.CanceledException e) {
+ Log.e(TAG, "Pending intent was canceled", e);
+ }
+ } else {
+ Log.e(TAG, "No receiver or activity to restart");
}
}
});
diff --git a/packages/SystemUI/src/com/android/systemui/pip/PipBoundsHandler.java b/packages/SystemUI/src/com/android/systemui/pip/PipBoundsHandler.java
index 88491b7..8be2502 100644
--- a/packages/SystemUI/src/com/android/systemui/pip/PipBoundsHandler.java
+++ b/packages/SystemUI/src/com/android/systemui/pip/PipBoundsHandler.java
@@ -229,8 +229,8 @@
*/
Rect getDestinationBounds(float aspectRatio, Rect bounds, Size minimalSize) {
final Rect destinationBounds;
- final Rect defaultBounds = getDefaultBounds(mReentrySnapFraction, mReentrySize);
if (bounds == null) {
+ final Rect defaultBounds = getDefaultBounds(mReentrySnapFraction, mReentrySize);
destinationBounds = new Rect(defaultBounds);
if (mReentrySnapFraction == INVALID_SNAP_FRACTION && mReentrySize == null) {
mOverrideMinimalSize = minimalSize;
diff --git a/packages/SystemUI/src/com/android/systemui/pip/phone/PipResizeGestureHandler.java b/packages/SystemUI/src/com/android/systemui/pip/phone/PipResizeGestureHandler.java
index 8fff419..25acce6 100644
--- a/packages/SystemUI/src/com/android/systemui/pip/phone/PipResizeGestureHandler.java
+++ b/packages/SystemUI/src/com/android/systemui/pip/phone/PipResizeGestureHandler.java
@@ -65,6 +65,7 @@
private final PointF mDownPoint = new PointF();
private final Point mMaxSize = new Point();
private final Point mMinSize = new Point();
+ private final Rect mLastResizeBounds = new Rect();
private final Rect mTmpBounds = new Rect();
private final int mDelta;
@@ -187,17 +188,13 @@
private void onMotionEvent(MotionEvent ev) {
int action = ev.getActionMasked();
if (action == MotionEvent.ACTION_DOWN) {
+ mLastResizeBounds.setEmpty();
mAllowGesture = isWithinTouchRegion((int) ev.getX(), (int) ev.getY());
if (mAllowGesture) {
mDownPoint.set(ev.getX(), ev.getY());
}
} else if (mAllowGesture) {
- final Rect currentPipBounds = mMotionHelper.getBounds();
- Rect newSize = TaskResizingAlgorithm.resizeDrag(ev.getX(), ev.getY(), mDownPoint.x,
- mDownPoint.y, currentPipBounds, mCtrlType, mMinSize.x, mMinSize.y, mMaxSize,
- true, true);
- mPipBoundsHandler.transformBoundsToAspectRatio(newSize);
switch (action) {
case MotionEvent.ACTION_POINTER_DOWN:
// We do not support multi touch for resizing via drag
@@ -206,11 +203,16 @@
case MotionEvent.ACTION_MOVE:
// Capture inputs
mInputMonitor.pilferPointers();
- //TODO: Actually do resize here.
+ final Rect currentPipBounds = mMotionHelper.getBounds();
+ mLastResizeBounds.set(TaskResizingAlgorithm.resizeDrag(ev.getX(), ev.getY(),
+ mDownPoint.x, mDownPoint.y, currentPipBounds, mCtrlType, mMinSize.x,
+ mMinSize.y, mMaxSize, true, true));
+ mPipBoundsHandler.transformBoundsToAspectRatio(mLastResizeBounds);
+ mPipTaskOrganizer.scheduleResizePip(mLastResizeBounds, null);
break;
case MotionEvent.ACTION_UP:
case MotionEvent.ACTION_CANCEL:
- //TODO: Finish resize operation here.
+ mPipTaskOrganizer.scheduleFinishResizePip(mLastResizeBounds);
mMotionHelper.synchronizePinnedStackBounds();
mCtrlType = CTRL_NONE;
mAllowGesture = false;
@@ -223,7 +225,7 @@
mMaxSize.set(maxX, maxY);
}
- void updateMiniSize(int minX, int minY) {
+ void updateMinSize(int minX, int minY) {
mMinSize.set(minX, minY);
}
diff --git a/packages/SystemUI/src/com/android/systemui/pip/phone/PipTouchHandler.java b/packages/SystemUI/src/com/android/systemui/pip/phone/PipTouchHandler.java
index b5fb1a9..9b67d80 100644
--- a/packages/SystemUI/src/com/android/systemui/pip/phone/PipTouchHandler.java
+++ b/packages/SystemUI/src/com/android/systemui/pip/phone/PipTouchHandler.java
@@ -42,6 +42,7 @@
import android.view.accessibility.AccessibilityNodeInfo;
import android.view.accessibility.AccessibilityWindowInfo;
+import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.os.logging.MetricsLoggerWrapper;
import com.android.systemui.R;
import com.android.systemui.pip.PipBoundsHandler;
@@ -74,7 +75,7 @@
private final Context mContext;
private final IActivityManager mActivityManager;
private final PipBoundsHandler mPipBoundsHandler;
- private final PipResizeGestureHandler mPipResizeGestureHandler;
+ private PipResizeGestureHandler mPipResizeGestureHandler;
private IPinnedStackController mPinnedStackController;
private final PipMenuActivityController mMenuController;
@@ -85,14 +86,17 @@
// The current movement bounds
private Rect mMovementBounds = new Rect();
+ // The current resized bounds, changed by user resize.
+ // This is used during expand/un-expand to save/restore the user's resized size.
+ @VisibleForTesting Rect mResizedBounds = new Rect();
// The reference inset bounds, used to determine the dismiss fraction
private Rect mInsetBounds = new Rect();
// The reference bounds used to calculate the normal/expanded target bounds
private Rect mNormalBounds = new Rect();
- private Rect mNormalMovementBounds = new Rect();
+ @VisibleForTesting Rect mNormalMovementBounds = new Rect();
private Rect mExpandedBounds = new Rect();
- private Rect mExpandedMovementBounds = new Rect();
+ @VisibleForTesting Rect mExpandedMovementBounds = new Rect();
private int mExpandedShortestEdgeSize;
// Used to workaround an issue where the WM rotation happens before we are notified, allowing
@@ -127,7 +131,7 @@
private final PipTouchState mTouchState;
private final FlingAnimationUtils mFlingAnimationUtils;
private final FloatingContentCoordinator mFloatingContentCoordinator;
- private final PipMotionHelper mMotionHelper;
+ private PipMotionHelper mMotionHelper;
private PipTouchGesture mGesture;
// Temp vars
@@ -240,14 +244,15 @@
mFloatingContentCoordinator.onContentRemoved(mMotionHelper);
}
+ mResizedBounds.setEmpty();
mPipResizeGestureHandler.onActivityUnpinned();
}
public void onPinnedStackAnimationEnded() {
// Always synchronize the motion helper bounds once PiP animations finish
mMotionHelper.synchronizePinnedStackBounds();
- mPipResizeGestureHandler.updateMiniSize(mMotionHelper.getBounds().width(),
- mMotionHelper.getBounds().height());
+ updateMovementBounds();
+ mResizedBounds.set(mMotionHelper.getBounds());
if (mShowPipMenuOnAnimationEnd) {
mMenuController.showMenu(MENU_STATE_CLOSE, mMotionHelper.getBounds(),
@@ -292,11 +297,13 @@
Size expandedSize = mSnapAlgorithm.getSizeForAspectRatio(aspectRatio,
mExpandedShortestEdgeSize, displaySize.x, displaySize.y);
mExpandedBounds.set(0, 0, expandedSize.getWidth(), expandedSize.getHeight());
- mPipResizeGestureHandler.updateMaxSize(expandedSize.getWidth(), expandedSize.getHeight());
Rect expandedMovementBounds = new Rect();
mSnapAlgorithm.getMovementBounds(mExpandedBounds, insetBounds, expandedMovementBounds,
bottomOffset);
+ mPipResizeGestureHandler.updateMinSize(mNormalBounds.width(), mNormalBounds.height());
+ mPipResizeGestureHandler.updateMaxSize(mExpandedBounds.width(), mExpandedBounds.height());
+
// The extra offset does not really affect the movement bounds, but are applied based on the
// current state (ime showing, or shelf offset) when we need to actually shift
int extraOffset = Math.max(
@@ -332,7 +339,7 @@
mExpandedMovementBounds = expandedMovementBounds;
mDisplayRotation = displayRotation;
mInsetBounds.set(insetBounds);
- updateMovementBounds(mMenuState);
+ updateMovementBounds();
mMovementBoundsExtraOffsets = extraOffset;
// If we have a deferred resize, apply it now
@@ -392,7 +399,7 @@
case MotionEvent.ACTION_UP: {
// Update the movement bounds again if the state has changed since the user started
// dragging (ie. when the IME shows)
- updateMovementBounds(mMenuState);
+ updateMovementBounds();
if (mGesture.onUp(mTouchState)) {
break;
@@ -490,9 +497,11 @@
if (menuState == MENU_STATE_FULL && mMenuState != MENU_STATE_FULL) {
// Save the current snap fraction and if we do not drag or move the PiP, then
// we store back to this snap fraction. Otherwise, we'll reset the snap
- // fraction and snap to the closest edge
- Rect expandedBounds = new Rect(mExpandedBounds);
+ // fraction and snap to the closest edge.
+ // Also save the current resized bounds so when the menu disappears, we can restore it.
if (resize) {
+ mResizedBounds.set(mMotionHelper.getBounds());
+ Rect expandedBounds = new Rect(mExpandedBounds);
mSavedSnapFraction = mMotionHelper.animateToExpandedState(expandedBounds,
mMovementBounds, mExpandedMovementBounds);
}
@@ -520,9 +529,12 @@
}
if (mDeferResizeToNormalBoundsUntilRotation == -1) {
- Rect normalBounds = new Rect(mNormalBounds);
- mMotionHelper.animateToUnexpandedState(normalBounds, mSavedSnapFraction,
- mNormalMovementBounds, mMovementBounds, false /* immediate */);
+ Rect restoreBounds = new Rect(mResizedBounds);
+ Rect restoredMovementBounds = new Rect();
+ mSnapAlgorithm.getMovementBounds(restoreBounds, mInsetBounds,
+ restoredMovementBounds, mIsImeShowing ? mImeHeight : 0);
+ mMotionHelper.animateToUnexpandedState(restoreBounds, mSavedSnapFraction,
+ restoredMovementBounds, mMovementBounds, false /* immediate */);
mSavedSnapFraction = -1f;
}
} else {
@@ -533,7 +545,7 @@
}
}
mMenuState = menuState;
- updateMovementBounds(menuState);
+ updateMovementBounds();
// If pip menu has dismissed, we should register the A11y ActionReplacingConnection for pip
// as well, or it can't handle a11y focus and pip menu can't perform any action.
onRegistrationChanged(menuState == MENU_STATE_NONE);
@@ -549,6 +561,21 @@
return mMotionHelper;
}
+ @VisibleForTesting
+ PipResizeGestureHandler getPipResizeGestureHandler() {
+ return mPipResizeGestureHandler;
+ }
+
+ @VisibleForTesting
+ void setPipResizeGestureHandler(PipResizeGestureHandler pipResizeGestureHandler) {
+ mPipResizeGestureHandler = pipResizeGestureHandler;
+ }
+
+ @VisibleForTesting
+ void setPipMotionHelper(PipMotionHelper pipMotionHelper) {
+ mMotionHelper = pipMotionHelper;
+ }
+
/**
* @return the unexpanded bounds.
*/
@@ -709,14 +736,14 @@
* Updates the current movement bounds based on whether the menu is currently visible and
* resized.
*/
- private void updateMovementBounds(int menuState) {
- boolean isMenuExpanded = menuState == MENU_STATE_FULL;
- mMovementBounds = isMenuExpanded && willResizeMenu()
- ? mExpandedMovementBounds
- : mNormalMovementBounds;
- mPipBoundsHandler.setMinEdgeSize(
- isMenuExpanded ? mExpandedShortestEdgeSize : 0);
+ private void updateMovementBounds() {
+ mSnapAlgorithm.getMovementBounds(mMotionHelper.getBounds(), mInsetBounds,
+ mMovementBounds, mIsImeShowing ? mImeHeight : 0);
mMotionHelper.setCurrentMovementBounds(mMovementBounds);
+
+ boolean isMenuExpanded = mMenuState == MENU_STATE_FULL;
+ mPipBoundsHandler.setMinEdgeSize(
+ isMenuExpanded && willResizeMenu() ? mExpandedShortestEdgeSize : 0);
}
/**
diff --git a/packages/SystemUI/src/com/android/systemui/qs/QSMediaPlayer.java b/packages/SystemUI/src/com/android/systemui/qs/QSMediaPlayer.java
index 837256b..d5e5b10 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/QSMediaPlayer.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/QSMediaPlayer.java
@@ -55,11 +55,13 @@
* @param context
* @param parent
* @param manager
+ * @param foregroundExecutor
* @param backgroundExecutor
*/
public QSMediaPlayer(Context context, ViewGroup parent, NotificationMediaManager manager,
- Executor backgroundExecutor) {
- super(context, parent, manager, R.layout.qs_media_panel, QS_ACTION_IDS, backgroundExecutor);
+ Executor foregroundExecutor, Executor backgroundExecutor) {
+ super(context, parent, manager, R.layout.qs_media_panel, QS_ACTION_IDS, foregroundExecutor,
+ backgroundExecutor);
}
/**
diff --git a/packages/SystemUI/src/com/android/systemui/qs/QSPanel.java b/packages/SystemUI/src/com/android/systemui/qs/QSPanel.java
index bf72b33..5ccf8c7 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/QSPanel.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/QSPanel.java
@@ -53,6 +53,7 @@
import com.android.systemui.R;
import com.android.systemui.broadcast.BroadcastDispatcher;
import com.android.systemui.dagger.qualifiers.Background;
+import com.android.systemui.dagger.qualifiers.Main;
import com.android.systemui.dump.DumpManager;
import com.android.systemui.plugins.qs.DetailAdapter;
import com.android.systemui.plugins.qs.QSTile;
@@ -101,6 +102,7 @@
private final ArrayList<QSMediaPlayer> mMediaPlayers = new ArrayList<>();
private final NotificationMediaManager mNotificationMediaManager;
private final LocalBluetoothManager mLocalBluetoothManager;
+ private final Executor mForegroundExecutor;
private final Executor mBackgroundExecutor;
private LocalMediaManager mLocalMediaManager;
private MediaDevice mDevice;
@@ -160,6 +162,7 @@
BroadcastDispatcher broadcastDispatcher,
QSLogger qsLogger,
NotificationMediaManager notificationMediaManager,
+ @Main Executor foregroundExecutor,
@Background Executor backgroundExecutor,
@Nullable LocalBluetoothManager localBluetoothManager
) {
@@ -168,6 +171,7 @@
mQSLogger = qsLogger;
mDumpManager = dumpManager;
mNotificationMediaManager = notificationMediaManager;
+ mForegroundExecutor = foregroundExecutor;
mBackgroundExecutor = backgroundExecutor;
mLocalBluetoothManager = localBluetoothManager;
@@ -270,7 +274,7 @@
if (player == null) {
Log.d(TAG, "creating new player");
player = new QSMediaPlayer(mContext, this, mNotificationMediaManager,
- mBackgroundExecutor);
+ mForegroundExecutor, mBackgroundExecutor);
if (player.isPlaying()) {
mMediaCarousel.addView(player.getView(), 0, lp); // add in front
diff --git a/packages/SystemUI/src/com/android/systemui/qs/QuickQSMediaPlayer.java b/packages/SystemUI/src/com/android/systemui/qs/QuickQSMediaPlayer.java
index 4512afb..0c50194 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/QuickQSMediaPlayer.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/QuickQSMediaPlayer.java
@@ -48,12 +48,13 @@
* @param context
* @param parent
* @param manager
+ * @param foregroundExecutor
* @param backgroundExecutor
*/
public QuickQSMediaPlayer(Context context, ViewGroup parent, NotificationMediaManager manager,
- Executor backgroundExecutor) {
+ Executor foregroundExecutor, Executor backgroundExecutor) {
super(context, parent, manager, R.layout.qqs_media_panel, QQS_ACTION_IDS,
- backgroundExecutor);
+ foregroundExecutor, backgroundExecutor);
}
/**
diff --git a/packages/SystemUI/src/com/android/systemui/qs/QuickQSPanel.java b/packages/SystemUI/src/com/android/systemui/qs/QuickQSPanel.java
index 6654b7a..be01d75 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/QuickQSPanel.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/QuickQSPanel.java
@@ -32,6 +32,7 @@
import com.android.systemui.R;
import com.android.systemui.broadcast.BroadcastDispatcher;
import com.android.systemui.dagger.qualifiers.Background;
+import com.android.systemui.dagger.qualifiers.Main;
import com.android.systemui.dump.DumpManager;
import com.android.systemui.plugins.qs.QSTile;
import com.android.systemui.plugins.qs.QSTile.SignalState;
@@ -79,11 +80,12 @@
BroadcastDispatcher broadcastDispatcher,
QSLogger qsLogger,
NotificationMediaManager notificationMediaManager,
+ @Main Executor foregroundExecutor,
@Background Executor backgroundExecutor,
@Nullable LocalBluetoothManager localBluetoothManager
) {
super(context, attrs, dumpManager, broadcastDispatcher, qsLogger, notificationMediaManager,
- backgroundExecutor, localBluetoothManager);
+ foregroundExecutor, backgroundExecutor, localBluetoothManager);
if (mFooter != null) {
removeView(mFooter.getView());
}
@@ -103,7 +105,7 @@
int marginSize = (int) mContext.getResources().getDimension(R.dimen.qqs_media_spacing);
mMediaPlayer = new QuickQSMediaPlayer(mContext, mHorizontalLinearLayout,
- notificationMediaManager, backgroundExecutor);
+ notificationMediaManager, foregroundExecutor, backgroundExecutor);
LayoutParams lp2 = new LayoutParams(0, LayoutParams.MATCH_PARENT, 1);
lp2.setMarginEnd(marginSize);
lp2.setMarginStart(0);
diff --git a/packages/SystemUI/src/com/android/systemui/qs/QuickStatusBarHeader.java b/packages/SystemUI/src/com/android/systemui/qs/QuickStatusBarHeader.java
index d422dd7..11b625f 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/QuickStatusBarHeader.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/QuickStatusBarHeader.java
@@ -436,6 +436,10 @@
@Override
public WindowInsets onApplyWindowInsets(WindowInsets insets) {
+ // Handle padding of QuickStatusBarHeader
+ setPadding(mRoundedCornerPadding, getPaddingTop(), mRoundedCornerPadding,
+ getPaddingBottom());
+
// Handle padding of SystemIconsView
DisplayCutout cutout = insets.getDisplayCutout();
Pair<Integer, Integer> cornerCutoutPadding = StatusBarWindowView.cornerCutoutMargins(
@@ -450,8 +454,11 @@
int statusBarPaddingRight = isLayoutRtl()
? getResources().getDimensionPixelSize(R.dimen.status_bar_padding_start)
: getResources().getDimensionPixelSize(R.dimen.status_bar_padding_end);
- mSystemIconsView.setPadding(padding.first + statusBarPaddingLeft, waterfallTopInset,
- padding.second + statusBarPaddingRight, 0);
+ mSystemIconsView.setPadding(
+ Math.max(padding.first + statusBarPaddingLeft - mRoundedCornerPadding, 0),
+ waterfallTopInset,
+ Math.max(padding.second + statusBarPaddingRight - mRoundedCornerPadding, 0),
+ 0);
return super.onApplyWindowInsets(insets);
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/VisualStabilityManager.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/VisualStabilityManager.java
index fabe3a7..b357ada 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/VisualStabilityManager.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/VisualStabilityManager.java
@@ -45,7 +45,6 @@
private final ArrayList<Callback> mCallbacks = new ArrayList<>();
private final Handler mHandler;
- private NotificationPresenter mPresenter;
private boolean mPanelExpanded;
private boolean mScreenOn;
private boolean mReorderingAllowed;
@@ -80,7 +79,6 @@
}
public void setUpWithPresenter(NotificationPresenter presenter) {
- mPresenter = presenter;
}
/**
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/GroupEntry.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/GroupEntry.java
index b960b42..2c747bd 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/GroupEntry.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/GroupEntry.java
@@ -16,6 +16,7 @@
package com.android.systemui.statusbar.notification.collection;
+import android.annotation.NonNull;
import android.annotation.Nullable;
import com.android.internal.annotations.VisibleForTesting;
@@ -51,6 +52,7 @@
return mSummary;
}
+ @NonNull
public List<NotificationEntry> getChildren() {
return mUnmodifiableChildren;
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/NotifViewBarn.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/NotifViewBarn.kt
new file mode 100644
index 0000000..e7948cd
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/NotifViewBarn.kt
@@ -0,0 +1,63 @@
+/*
+ * 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 com.android.systemui.statusbar.notification.collection
+
+import android.view.textclassifier.Log
+import com.android.systemui.statusbar.notification.stack.NotificationListItem
+import java.lang.IllegalStateException
+
+import javax.inject.Inject
+import javax.inject.Singleton
+
+/**
+ * The ViewBarn is just a map from [ListEntry] to an instance of [NotificationListItem] which is
+ * usually just an [ExpandableNotificationRow]
+ */
+@Singleton
+class NotifViewBarn @Inject constructor() {
+ private val DEBUG = false
+
+ private val rowMap = mutableMapOf<String, NotificationListItem>()
+
+ fun requireView(forEntry: ListEntry): NotificationListItem {
+ if (DEBUG) {
+ Log.d(TAG, "requireView: $forEntry.key")
+ }
+ val li = rowMap[forEntry.key]
+ if (li == null) {
+ throw IllegalStateException("No view has been registered for entry: $forEntry")
+ }
+
+ return li
+ }
+
+ fun registerViewForEntry(entry: ListEntry, view: NotificationListItem) {
+ if (DEBUG) {
+ Log.d(TAG, "registerViewForEntry: $entry.key")
+ }
+ rowMap[entry.key] = view
+ }
+
+ fun removeViewForEntry(entry: ListEntry) {
+ if (DEBUG) {
+ Log.d(TAG, "removeViewForEntry: $entry.key")
+ }
+ rowMap.remove(entry.key)
+ }
+}
+
+private const val TAG = "NotifViewBarn"
\ No newline at end of file
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/NotifViewManager.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/NotifViewManager.kt
new file mode 100644
index 0000000..0437877
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/NotifViewManager.kt
@@ -0,0 +1,200 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.statusbar.notification.collection
+
+import android.annotation.MainThread
+import android.view.ViewGroup
+
+import com.android.systemui.statusbar.FeatureFlags
+import com.android.systemui.statusbar.notification.VisualStabilityManager
+import com.android.systemui.statusbar.notification.collection.GroupEntry.ROOT_ENTRY
+import com.android.systemui.statusbar.notification.stack.NotificationListItem
+import com.android.systemui.util.Assert
+
+import java.io.FileDescriptor
+import java.io.PrintWriter
+import java.lang.IllegalStateException
+import javax.inject.Inject
+import javax.inject.Singleton
+
+/**
+ * A consumer of a Notification tree built by [ShadeListBuilder] which will update the notification
+ * presenter with the minimum operations required to make the old tree match the new one
+ */
+@MainThread
+@Singleton
+class NotifViewManager @Inject constructor(
+ private val rowRegistry: NotifViewBarn,
+ private val stabilityManager: VisualStabilityManager,
+ private val featureFlags: FeatureFlags
+) {
+ var currentNotifs = listOf<ListEntry>()
+
+ private lateinit var listContainer: SimpleNotificationListContainer
+
+ fun attach(listBuilder: ShadeListBuilder) {
+ if (featureFlags.isNewNotifPipelineRenderingEnabled) {
+ listBuilder.setOnRenderListListener { entries: List<ListEntry> ->
+ this.onNotifTreeBuilt(entries)
+ }
+ }
+ }
+
+ fun setViewConsumer(consumer: SimpleNotificationListContainer) {
+ listContainer = consumer
+ }
+
+ /**
+ * Callback for when the tree is rebuilt
+ */
+ fun onNotifTreeBuilt(notifList: List<ListEntry>) {
+ Assert.isMainThread()
+
+ /*
+ * The assumption here is that anything from the old NotificationViewHierarchyManager that
+ * is responsible for filtering is done via the NotifFilter logic. This tree we get should
+ * be *the stuff to display* +/- redacted stuff
+ */
+
+ detachRows(notifList)
+ attachRows(notifList)
+
+ currentNotifs = notifList
+ }
+
+ private fun detachRows(entries: List<ListEntry>) {
+ // To properly detach rows, we are looking to remove any view in the consumer that is not
+ // present in the incoming list.
+ //
+ // Every listItem was top-level, so it's entry's parent was ROOT_ENTRY, but now
+ // there are two possibilities:
+ //
+ // 1. It is not present in the entry list
+ // 1a. It has moved to be a child in the entry list - transfer it
+ // 1b. It is gone completely - remove it
+ // 2. It is present in the entry list - diff the children
+ getListItems(listContainer)
+ .filter {
+ // Ignore things that are showing the blocking helper
+ !it.isBlockingHelperShowing
+ }
+ .forEach { listItem ->
+ val noLongerTopLevel = listItem.entry.parent != ROOT_ENTRY
+ val becameChild = noLongerTopLevel && listItem.entry.parent != null
+
+ val idx = entries.indexOf(listItem.entry)
+
+ if (noLongerTopLevel) {
+ // Summaries won't become children; remove the whole group
+ if (listItem.isSummaryWithChildren) {
+ listItem.removeAllChildren()
+ }
+
+ if (becameChild) {
+ // Top-level element is becoming a child, don't generate an animation
+ listContainer.setChildTransferInProgress(true)
+ }
+ listContainer.removeListItem(listItem)
+ listContainer.setChildTransferInProgress(false)
+ } else if (entries[idx] is GroupEntry) {
+ // A top-level entry exists. If it's a group, diff the children
+ val groupChildren = (entries[idx] as GroupEntry).children
+ listItem.notificationChildren?.forEach { listChild ->
+ if (!groupChildren.contains(listChild.entry)) {
+ listItem.removeChildNotification(listChild)
+
+ // TODO: the old code only calls this if the notif is gone from
+ // NEM.getActiveNotificationUnfiltered(). Do we care?
+ listContainer.notifyGroupChildRemoved(
+ listChild.view, listChild.view.parent as ViewGroup)
+ }
+ }
+ }
+ }
+ }
+
+ /** Convenience method for getting a sequence of [NotificationListItem]s */
+ private fun getListItems(container: SimpleNotificationListContainer):
+ Sequence<NotificationListItem> {
+ return (0 until container.getContainerChildCount()).asSequence()
+ .map { container.getContainerChildAt(it) }
+ .filterIsInstance<NotificationListItem>()
+ }
+
+ private fun attachRows(entries: List<ListEntry>) {
+
+ var orderChanged = false
+
+ // To attach rows we can use _this one weird trick_: if the intended view to add does not
+ // have a parent, then simply add it (and its children).
+ entries.forEach { entry ->
+ val listItem = rowRegistry.requireView(entry)
+
+ if (listItem.view.parent != null) {
+ listContainer.addListItem(listItem)
+ stabilityManager.notifyViewAddition(listItem.view)
+ }
+
+ if (entry is GroupEntry) {
+ for ((idx, childEntry) in entry.children.withIndex()) {
+ val childListItem = rowRegistry.requireView(childEntry)
+ // Child hasn't been added yet. add it!
+ if (!listItem.notificationChildren.contains(childListItem)) {
+ // TODO: old code here just Log.wtf()'d here. This might wreak havoc
+ if (childListItem.view.parent != null) {
+ throw IllegalStateException("trying to add a notification child that " +
+ "already has a parent. class: " +
+ "${childListItem.view.parent?.javaClass} " +
+ "\n child: ${childListItem.view}"
+ )
+ }
+
+ listItem.addChildNotification(childListItem, idx)
+ stabilityManager.notifyViewAddition(childListItem.view)
+ listContainer.notifyGroupChildAdded(childListItem.view)
+ }
+ }
+
+ // finally after removing and adding has been performed we can apply the order
+ orderChanged = orderChanged ||
+ listItem.applyChildOrder(
+ getChildListFromParent(entry),
+ stabilityManager,
+ null /*TODO: stability callback */
+ )
+ }
+ }
+
+ if (orderChanged) {
+ listContainer.generateChildOrderChangedEvent()
+ }
+ }
+
+ private fun getChildListFromParent(parent: ListEntry): List<NotificationListItem> {
+ if (parent is GroupEntry) {
+ return parent.children.map { child -> rowRegistry.requireView(child) }
+ .toList()
+ }
+
+ return emptyList()
+ }
+
+ fun dump(fd: FileDescriptor, pw: PrintWriter, args: Array<String>) {
+ }
+}
+
+private const val TAG = "NotifViewDataSource"
\ No newline at end of file
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/ShadeListBuilder.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/ShadeListBuilder.java
index 5b73b1a..f7d6cef 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/ShadeListBuilder.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/ShadeListBuilder.java
@@ -319,7 +319,7 @@
logParentingChanges();
freeEmptyGroups();
- // Step 6: Dispatch the new list, first to any listeners and then to the view layer
+ // Step 8: Dispatch the new list, first to any listeners and then to the view layer
if (mIterationCount % 10 == 0) {
mLogger.logFinalList(mNotifList);
}
@@ -328,7 +328,7 @@
mOnRenderListListener.onRenderList(mReadOnlyNotifList);
}
- // Step 7: We're done!
+ // Step 9: We're done!
mLogger.logEndBuildList(mIterationCount);
mPipelineState.setState(STATE_IDLE);
mIterationCount++;
@@ -816,7 +816,7 @@
* @param entries A read-only view into the current notif list. Note that this list is
* backed by the live list and will change in response to new pipeline runs.
*/
- void onRenderList(List<ListEntry> entries);
+ void onRenderList(@NonNull List<ListEntry> entries);
}
private static final NotifSection sDefaultSection =
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/SimpleNotificationListContainer.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/SimpleNotificationListContainer.kt
new file mode 100644
index 0000000..2dbe555
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/SimpleNotificationListContainer.kt
@@ -0,0 +1,43 @@
+/*
+ * 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 com.android.systemui.statusbar.notification.collection
+
+import android.view.View
+import android.view.ViewGroup
+import com.android.systemui.statusbar.notification.stack.NotificationListItem
+
+/**
+ * Minimal interface of what [NotifViewManager] needs from [NotificationListContainer]
+ */
+interface SimpleNotificationListContainer {
+ /** Called to signify that a top-level element is becoming a child in the shade */
+ fun setChildTransferInProgress(b: Boolean)
+ /** Used to generate a list of [NotificationListItem] */
+ fun getContainerChildAt(i: Int): View
+ /** Similar to above */
+ fun getContainerChildCount(): Int
+ /** Remove a [NotificationListItem] from the container */
+ fun removeListItem(li: NotificationListItem)
+ /** Add a [NotificationListItem] to the container */
+ fun addListItem(li: NotificationListItem)
+ /** Allows [NotifViewManager] to notify the container about a group child removal */
+ fun notifyGroupChildRemoved(row: View, parent: ViewGroup)
+ /** Allows [NotifViewManager] to notify the container about a group child addition */
+ fun notifyGroupChildAdded(row: View)
+ /** [NotifViewManager] calls this when the order of the children changes */
+ fun generateChildOrderChangedEvent()
+}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coordinator/HeadsUpCoordinator.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coordinator/HeadsUpCoordinator.java
new file mode 100644
index 0000000..573c129
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coordinator/HeadsUpCoordinator.java
@@ -0,0 +1,171 @@
+/*
+ * 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 com.android.systemui.statusbar.notification.collection.coordinator;
+
+import static com.android.systemui.statusbar.NotificationRemoteInputManager.FORCE_REMOTE_INPUT_HISTORY;
+
+import android.annotation.Nullable;
+
+import com.android.systemui.statusbar.NotificationRemoteInputManager;
+import com.android.systemui.statusbar.notification.collection.ListEntry;
+import com.android.systemui.statusbar.notification.collection.NotifPipeline;
+import com.android.systemui.statusbar.notification.collection.NotificationEntry;
+import com.android.systemui.statusbar.notification.collection.listbuilder.pluggable.NotifPromoter;
+import com.android.systemui.statusbar.notification.collection.listbuilder.pluggable.NotifSection;
+import com.android.systemui.statusbar.notification.collection.notifcollection.NotifCollectionListener;
+import com.android.systemui.statusbar.notification.collection.notifcollection.NotifLifetimeExtender;
+import com.android.systemui.statusbar.policy.HeadsUpManager;
+import com.android.systemui.statusbar.policy.OnHeadsUpChangedListener;
+
+import java.util.Objects;
+
+import javax.inject.Inject;
+import javax.inject.Singleton;
+
+/**
+ * Coordinates heads up notification (HUN) interactions with the notification pipeline based on
+ * the HUN state reported by the {@link HeadsUpManager}. In this class we only consider one
+ * notification, in particular the {@link HeadsUpManager#getTopEntry()}, to be HeadsUpping at a
+ * time even though other notifications may be queued to heads up next.
+ *
+ * The current HUN, but not HUNs that are queued to heads up, will be:
+ * - Lifetime extended until it's no longer heads upping.
+ * - Promoted out of its group if it's a child of a group.
+ * - In the HeadsUpCoordinatorSection. Ordering is configured in {@link NotifCoordinators}.
+ * - Removed from HeadsUpManager if it's removed from the NotificationCollection.
+ *
+ * Note: The inflation callback in {@link PreparationCoordinator} handles showing HUNs.
+ */
+@Singleton
+public class HeadsUpCoordinator implements Coordinator {
+ private static final String TAG = "HeadsUpCoordinator";
+
+ private final HeadsUpManager mHeadsUpManager;
+ private final NotificationRemoteInputManager mRemoteInputManager;
+
+ // tracks the current HeadUpNotification reported by HeadsUpManager
+ private @Nullable NotificationEntry mCurrentHun;
+
+ private NotifLifetimeExtender.OnEndLifetimeExtensionCallback mEndLifetimeExtension;
+ private NotificationEntry mNotifExtendingLifetime; // notif we've extended the lifetime for
+
+ @Inject
+ public HeadsUpCoordinator(
+ HeadsUpManager headsUpManager,
+ NotificationRemoteInputManager remoteInputManager) {
+ mHeadsUpManager = headsUpManager;
+ mRemoteInputManager = remoteInputManager;
+ }
+
+ @Override
+ public void attach(NotifPipeline pipeline) {
+ mHeadsUpManager.addListener(mOnHeadsUpChangedListener);
+ pipeline.addCollectionListener(mNotifCollectionListener);
+ pipeline.addPromoter(mNotifPromoter);
+ pipeline.addNotificationLifetimeExtender(mLifetimeExtender);
+ }
+
+ @Override
+ public NotifSection getSection() {
+ return mNotifSection;
+ }
+
+ private final NotifCollectionListener mNotifCollectionListener = new NotifCollectionListener() {
+ /**
+ * Stop alerting HUNs that are removed from the notification collection
+ */
+ @Override
+ public void onEntryRemoved(NotificationEntry entry, int reason) {
+ final String entryKey = entry.getKey();
+ if (mHeadsUpManager.isAlerting(entryKey)) {
+ boolean removeImmediatelyForRemoteInput =
+ mRemoteInputManager.getController().isSpinning(entryKey)
+ && !FORCE_REMOTE_INPUT_HISTORY;
+ mHeadsUpManager.removeNotification(entry.getKey(), removeImmediatelyForRemoteInput);
+ }
+ }
+ };
+
+ private final NotifLifetimeExtender mLifetimeExtender = new NotifLifetimeExtender() {
+ @Override
+ public String getName() {
+ return TAG;
+ }
+
+ @Override
+ public void setCallback(OnEndLifetimeExtensionCallback callback) {
+ mEndLifetimeExtension = callback;
+ }
+
+ @Override
+ public boolean shouldExtendLifetime(NotificationEntry entry, int reason) {
+ boolean isShowingHun = isCurrentlyShowingHun(entry);
+ if (isShowingHun) {
+ mNotifExtendingLifetime = entry;
+ }
+ return isShowingHun;
+ }
+
+ @Override
+ public void cancelLifetimeExtension(NotificationEntry entry) {
+ if (Objects.equals(mNotifExtendingLifetime, entry)) {
+ mNotifExtendingLifetime = null;
+ }
+ }
+ };
+
+ private final NotifPromoter mNotifPromoter = new NotifPromoter(TAG) {
+ @Override
+ public boolean shouldPromoteToTopLevel(NotificationEntry entry) {
+ return isCurrentlyShowingHun(entry);
+ }
+ };
+
+ private final NotifSection mNotifSection = new NotifSection(TAG) {
+ @Override
+ public boolean isInSection(ListEntry entry) {
+ return isCurrentlyShowingHun(entry);
+ }
+ };
+
+ private final OnHeadsUpChangedListener mOnHeadsUpChangedListener =
+ new OnHeadsUpChangedListener() {
+ @Override
+ public void onHeadsUpStateChanged(NotificationEntry entry, boolean isHeadsUp) {
+ NotificationEntry newHUN = mHeadsUpManager.getTopEntry();
+ if (!Objects.equals(mCurrentHun, newHUN)) {
+ endNotifLifetimeExtension();
+ mCurrentHun = newHUN;
+ mNotifPromoter.invalidateList();
+ mNotifSection.invalidateList();
+ }
+ }
+ };
+
+ private boolean isCurrentlyShowingHun(ListEntry entry) {
+ return mCurrentHun == entry.getRepresentativeEntry();
+ }
+
+ private void endNotifLifetimeExtension() {
+ if (mNotifExtendingLifetime != null) {
+ mEndLifetimeExtension.onEndLifetimeExtension(
+ mLifetimeExtender,
+ mNotifExtendingLifetime);
+ mNotifExtendingLifetime = null;
+ }
+ }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coordinator/NotifCoordinators.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coordinator/NotifCoordinators.java
index 7a22d75..98104f8 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coordinator/NotifCoordinators.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coordinator/NotifCoordinators.java
@@ -49,6 +49,7 @@
public NotifCoordinators(
DumpManager dumpManager,
FeatureFlags featureFlags,
+ HeadsUpCoordinator headsUpCoordinator,
KeyguardCoordinator keyguardCoordinator,
RankingCoordinator rankingCoordinator,
ForegroundCoordinator foregroundCoordinator,
@@ -56,7 +57,6 @@
BubbleCoordinator bubbleCoordinator,
PreparationCoordinator preparationCoordinator) {
dumpManager.registerDumpable(TAG, this);
-
mCoordinators.add(new HideLocallyDismissedNotifsCoordinator());
mCoordinators.add(keyguardCoordinator);
mCoordinators.add(rankingCoordinator);
@@ -64,9 +64,10 @@
mCoordinators.add(deviceProvisionedCoordinator);
mCoordinators.add(bubbleCoordinator);
if (featureFlags.isNewNotifPipelineRenderingEnabled()) {
+ mCoordinators.add(headsUpCoordinator);
mCoordinators.add(preparationCoordinator);
}
- // TODO: add new Coordinators here! (b/145134683, b/112656837)
+ // TODO: add new Coordinators here! (b/112656837)
// TODO: add the sections in a particular ORDER (HeadsUp < People < Alerting)
for (Coordinator c : mCoordinators) {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coordinator/PreparationCoordinator.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coordinator/PreparationCoordinator.java
index ebecf18..742615c 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coordinator/PreparationCoordinator.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coordinator/PreparationCoordinator.java
@@ -26,13 +26,16 @@
import com.android.systemui.statusbar.notification.collection.ListEntry;
import com.android.systemui.statusbar.notification.collection.NotifInflaterImpl;
import com.android.systemui.statusbar.notification.collection.NotifPipeline;
+import com.android.systemui.statusbar.notification.collection.NotifViewBarn;
import com.android.systemui.statusbar.notification.collection.NotificationEntry;
import com.android.systemui.statusbar.notification.collection.ShadeListBuilder;
import com.android.systemui.statusbar.notification.collection.inflation.NotifInflater;
import com.android.systemui.statusbar.notification.collection.listbuilder.OnBeforeFinalizeFilterListener;
import com.android.systemui.statusbar.notification.collection.listbuilder.pluggable.NotifFilter;
import com.android.systemui.statusbar.notification.collection.notifcollection.NotifCollectionListener;
+import com.android.systemui.statusbar.notification.interruption.NotificationInterruptStateProvider;
import com.android.systemui.statusbar.notification.row.NotifInflationErrorManager;
+import com.android.systemui.statusbar.policy.HeadsUpManager;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
@@ -57,21 +60,31 @@
private final PreparationCoordinatorLogger mLogger;
private final NotifInflater mNotifInflater;
private final NotifInflationErrorManager mNotifErrorManager;
+ private final NotifViewBarn mViewBarn;
private final Map<NotificationEntry, Integer> mInflationStates = new ArrayMap<>();
private final IStatusBarService mStatusBarService;
+ private final NotificationInterruptStateProvider mNotificationInterruptStateProvider;
+ private final HeadsUpManager mHeadsUpManager;
@Inject
public PreparationCoordinator(
PreparationCoordinatorLogger logger,
NotifInflaterImpl notifInflater,
NotifInflationErrorManager errorManager,
- IStatusBarService service) {
+ NotifViewBarn viewBarn,
+ IStatusBarService service,
+ NotificationInterruptStateProvider notificationInterruptStateProvider,
+ HeadsUpManager headsUpManager
+ ) {
mLogger = logger;
mNotifInflater = notifInflater;
mNotifInflater.setInflationCallback(mInflationCallback);
mNotifErrorManager = errorManager;
mNotifErrorManager.addInflationErrorListener(mInflationErrorListener);
+ mViewBarn = viewBarn;
mStatusBarService = service;
+ mNotificationInterruptStateProvider = notificationInterruptStateProvider;
+ mHeadsUpManager = headsUpManager;
}
@Override
@@ -109,6 +122,7 @@
@Override
public void onEntryCleanUp(NotificationEntry entry) {
mInflationStates.remove(entry);
+ mViewBarn.removeViewForEntry(entry);
}
};
@@ -142,7 +156,13 @@
@Override
public void onInflationFinished(NotificationEntry entry) {
mLogger.logNotifInflated(entry.getKey());
+ mViewBarn.registerViewForEntry(entry, entry.getRow());
mInflationStates.put(entry, STATE_INFLATED);
+
+ // TODO: should eventually be moved to HeadsUpCoordinator
+ if (mNotificationInterruptStateProvider.shouldHeadsUp(entry)) {
+ mHeadsUpManager.showNotification(entry);
+ }
mNotifInflatingFilter.invalidateList();
}
};
@@ -151,6 +171,7 @@
new NotifInflationErrorManager.NotifInflationErrorListener() {
@Override
public void onNotifInflationError(NotificationEntry entry, Exception e) {
+ mViewBarn.removeViewForEntry(entry);
mInflationStates.put(entry, STATE_ERROR);
try {
final StatusBarNotification sbn = entry.getSbn();
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/init/FakePipelineConsumer.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/init/FakePipelineConsumer.java
deleted file mode 100644
index 15f312d..0000000
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/init/FakePipelineConsumer.java
+++ /dev/null
@@ -1,85 +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 com.android.systemui.statusbar.notification.collection.init;
-
-import com.android.systemui.Dumpable;
-import com.android.systemui.statusbar.notification.collection.GroupEntry;
-import com.android.systemui.statusbar.notification.collection.ListEntry;
-import com.android.systemui.statusbar.notification.collection.NotificationEntry;
-import com.android.systemui.statusbar.notification.collection.ShadeListBuilder;
-
-import java.io.FileDescriptor;
-import java.io.PrintWriter;
-import java.util.Collections;
-import java.util.List;
-
-/**
- * Temporary class that tracks the result of the list builder and dumps it to text when requested.
- *
- * Eventually, this will be something that hands off the result of the pipeline to the View layer.
- */
-public class FakePipelineConsumer implements Dumpable {
- private List<ListEntry> mEntries = Collections.emptyList();
-
- /** Attach the consumer to the pipeline. */
- public void attach(ShadeListBuilder listBuilder) {
- listBuilder.setOnRenderListListener(this::onBuildComplete);
- }
-
- private void onBuildComplete(List<ListEntry> entries) {
- mEntries = entries;
- }
-
- @Override
- public void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
- pw.println();
- pw.println("Active notif tree:");
- for (int i = 0; i < mEntries.size(); i++) {
- ListEntry entry = mEntries.get(i);
- if (entry instanceof GroupEntry) {
- GroupEntry ge = (GroupEntry) entry;
- pw.println(dumpGroup(ge, "", i));
-
- pw.println(dumpEntry(ge.getSummary(), INDENT, -1));
- for (int j = 0; j < ge.getChildren().size(); j++) {
- pw.println(dumpEntry(ge.getChildren().get(j), INDENT, j));
- }
- } else {
- pw.println(dumpEntry(entry.getRepresentativeEntry(), "", i));
- }
- }
- }
-
- private String dumpGroup(GroupEntry entry, String indent, int index) {
- return String.format(
- "%s[%d] %s (group)",
- indent,
- index,
- entry.getKey());
- }
-
- private String dumpEntry(NotificationEntry entry, String indent, int index) {
- return String.format(
- "%s[%s] %s (channel=%s)",
- indent,
- index == -1 ? "*" : Integer.toString(index),
- entry.getKey(),
- entry.getChannel() != null ? entry.getChannel().getId() : "");
- }
-
- private static final String INDENT = " ";
-}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/init/NotifPipelineInitializer.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/init/NotifPipelineInitializer.java
index 258f6d0..f150257 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/init/NotifPipelineInitializer.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/init/NotifPipelineInitializer.java
@@ -25,10 +25,12 @@
import com.android.systemui.statusbar.notification.collection.NotifCollection;
import com.android.systemui.statusbar.notification.collection.NotifInflaterImpl;
import com.android.systemui.statusbar.notification.collection.NotifPipeline;
+import com.android.systemui.statusbar.notification.collection.NotifViewManager;
import com.android.systemui.statusbar.notification.collection.ShadeListBuilder;
import com.android.systemui.statusbar.notification.collection.coalescer.GroupCoalescer;
import com.android.systemui.statusbar.notification.collection.coordinator.NotifCoordinators;
import com.android.systemui.statusbar.notification.collection.inflation.NotificationRowBinderImpl;
+import com.android.systemui.statusbar.notification.stack.NotificationListContainer;
import java.io.FileDescriptor;
import java.io.PrintWriter;
@@ -50,7 +52,7 @@
private final DumpManager mDumpManager;
private final FeatureFlags mFeatureFlags;
- private final FakePipelineConsumer mFakePipelineConsumer = new FakePipelineConsumer();
+ private final NotifViewManager mNotifViewManager;
@Inject
public NotifPipelineInitializer(
@@ -61,7 +63,8 @@
NotifCoordinators notifCoordinators,
NotifInflaterImpl notifInflater,
DumpManager dumpManager,
- FeatureFlags featureFlags) {
+ FeatureFlags featureFlags,
+ NotifViewManager notifViewManager) {
mPipelineWrapper = pipelineWrapper;
mGroupCoalescer = groupCoalescer;
mNotifCollection = notifCollection;
@@ -70,12 +73,14 @@
mDumpManager = dumpManager;
mNotifInflater = notifInflater;
mFeatureFlags = featureFlags;
+ mNotifViewManager = notifViewManager;
}
/** Hooks the new pipeline up to NotificationManager */
public void initialize(
NotificationListener notificationService,
- NotificationRowBinderImpl rowBinder) {
+ NotificationRowBinderImpl rowBinder,
+ NotificationListContainer listContainer) {
mDumpManager.registerDumpable("NotifPipeline", this);
@@ -88,7 +93,8 @@
mNotifPluggableCoordinators.attach(mPipelineWrapper);
// Wire up pipeline
- mFakePipelineConsumer.attach(mListBuilder);
+ mNotifViewManager.setViewConsumer(listContainer);
+ mNotifViewManager.attach(mListBuilder);
mListBuilder.attach(mNotifCollection);
mNotifCollection.attach(mGroupCoalescer);
mGroupCoalescer.attach(notificationService);
@@ -98,7 +104,7 @@
@Override
public void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
- mFakePipelineConsumer.dump(fd, pw, args);
+ mNotifViewManager.dump(fd, pw, args);
mNotifPluggableCoordinators.dump(fd, pw, args);
mGroupCoalescer.dump(fd, pw, args);
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/init/NotificationsControllerImpl.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/init/NotificationsControllerImpl.kt
index 8a6d5c7..7a7178c 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/init/NotificationsControllerImpl.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/init/NotificationsControllerImpl.kt
@@ -94,7 +94,10 @@
notifBindPipelineInitializer.initialize()
if (featureFlags.isNewNotifPipelineEnabled) {
- newNotifPipeline.get().initialize(notificationListener, notificationRowBinder)
+ newNotifPipeline.get().initialize(
+ notificationListener,
+ notificationRowBinder,
+ listContainer)
}
if (featureFlags.isNewNotifPipelineRenderingEnabled) {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ActivatableNotificationView.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ActivatableNotificationView.java
index ea1bdd6..b9dd974 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ActivatableNotificationView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ActivatableNotificationView.java
@@ -271,6 +271,10 @@
}
}
+ public boolean isActive() {
+ return mActivated;
+ }
+
private void startActivateAnimation(final boolean reverse) {
if (!isAttachedToWindow()) {
return;
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ActivatableNotificationViewController.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ActivatableNotificationViewController.java
index 2643ec9..2f0e433 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ActivatableNotificationViewController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ActivatableNotificationViewController.java
@@ -111,7 +111,7 @@
if (mNeedsDimming && ev.getActionMasked() == MotionEvent.ACTION_DOWN
&& mView.disallowSingleClick(ev)
&& !mAccessibilityManager.isTouchExplorationEnabled()) {
- if (!mView.isActivated()) {
+ if (!mView.isActive()) {
return true;
} else if (!mDoubleTapHelper.isWithinDoubleTapSlop(ev)) {
mBlockNextTouch = true;
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ExpandableNotificationRow.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ExpandableNotificationRow.java
index b1db5b5..5f2b256 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ExpandableNotificationRow.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ExpandableNotificationRow.java
@@ -94,6 +94,7 @@
import com.android.systemui.statusbar.notification.stack.AnimationProperties;
import com.android.systemui.statusbar.notification.stack.ExpandableViewState;
import com.android.systemui.statusbar.notification.stack.NotificationChildrenContainer;
+import com.android.systemui.statusbar.notification.stack.NotificationListItem;
import com.android.systemui.statusbar.notification.stack.NotificationStackScrollLayout;
import com.android.systemui.statusbar.notification.stack.SwipeableView;
import com.android.systemui.statusbar.phone.KeyguardBypassController;
@@ -115,7 +116,8 @@
* the group summary (which contains 1 or more child notifications).
*/
public class ExpandableNotificationRow extends ActivatableNotificationView
- implements PluginListener<NotificationMenuRowPlugin>, SwipeableView {
+ implements PluginListener<NotificationMenuRowPlugin>, SwipeableView,
+ NotificationListItem {
private static final boolean DEBUG = false;
private static final int DEFAULT_DIVIDER_ALPHA = 0x29;
@@ -666,6 +668,7 @@
layout.setHeights(minHeight, headsUpHeight, mNotificationMaxHeight);
}
+ @NonNull
public NotificationEntry getEntry() {
return mEntry;
}
@@ -767,6 +770,17 @@
row.setIsChildInGroup(true, this);
}
+ /**
+ * Same as {@link #addChildNotification(ExpandableNotificationRow, int)}, but takes a
+ * {@link NotificationListItem} instead
+ *
+ * @param childItem item
+ * @param childIndex index
+ */
+ public void addChildNotification(NotificationListItem childItem, int childIndex) {
+ addChildNotification((ExpandableNotificationRow) childItem.getView(), childIndex);
+ }
+
public void removeChildNotification(ExpandableNotificationRow row) {
if (mChildrenContainer != null) {
mChildrenContainer.removeNotification(row);
@@ -777,6 +791,11 @@
}
@Override
+ public void removeChildNotification(NotificationListItem child) {
+ removeChildNotification((ExpandableNotificationRow) child.getView());
+ }
+
+ @Override
public boolean isChildInGroup() {
return mNotificationParent != null;
}
@@ -879,7 +898,7 @@
* @param callback the callback to invoked in case it is not allowed
* @return whether the list order has changed
*/
- public boolean applyChildOrder(List<ExpandableNotificationRow> childOrder,
+ public boolean applyChildOrder(List<? extends NotificationListItem> childOrder,
VisualStabilityManager visualStabilityManager,
VisualStabilityManager.Callback callback) {
return mChildrenContainer != null && mChildrenContainer.applyChildOrder(childOrder,
@@ -1274,6 +1293,11 @@
onChildrenCountChanged();
}
+ @Override
+ public View getView() {
+ return this;
+ }
+
public void setForceUnlocked(boolean forceUnlocked) {
mForceUnlocked = forceUnlocked;
if (mIsSummaryWithChildren) {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/wrapper/NotificationConversationTemplateViewWrapper.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/wrapper/NotificationConversationTemplateViewWrapper.kt
index 1e2571b5..162786c 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/wrapper/NotificationConversationTemplateViewWrapper.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/wrapper/NotificationConversationTemplateViewWrapper.kt
@@ -40,6 +40,7 @@
private var conversationIcon: View? = null
private var conversationBadge: View? = null
private var expandButton: View? = null
+ private lateinit var expandButtonContainer: View
private var messagingLinearLayout: MessagingLinearLayout? = null
init {
@@ -56,6 +57,8 @@
com.android.internal.R.id.conversation_icon_badge)
expandButton = conversationLayout.requireViewById(
com.android.internal.R.id.expand_button)
+ expandButtonContainer = conversationLayout.requireViewById(
+ com.android.internal.R.id.expand_button_container)
}
override fun onContentUpdated(row: ExpandableNotificationRow) {
@@ -90,6 +93,14 @@
conversationLayout.updateExpandability(expandable, onClickListener)
}
+ override fun disallowSingleClick(x: Float, y: Float): Boolean {
+ if (expandButtonContainer.visibility == View.VISIBLE
+ && isOnView(expandButtonContainer, x, y)) {
+ return true
+ }
+ return super.disallowSingleClick(x, y)
+ }
+
override fun getMinLayoutHeight(): Int {
if (mActionsContainer != null && mActionsContainer.visibility != View.GONE) {
return minHeightWithActions
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/wrapper/NotificationTemplateViewWrapper.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/wrapper/NotificationTemplateViewWrapper.java
index d41f5af..2d99ab1 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/wrapper/NotificationTemplateViewWrapper.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/wrapper/NotificationTemplateViewWrapper.java
@@ -58,7 +58,6 @@
private TextView mText;
protected View mActionsContainer;
private ImageView mReplyAction;
- private Rect mTmpRect = new Rect();
private int mContentHeight;
private int mMinHeightHint;
@@ -271,18 +270,6 @@
return super.disallowSingleClick(x, y);
}
- private boolean isOnView(View view, float x, float y) {
- View searchView = (View) view.getParent();
- while (searchView != null && !(searchView instanceof ExpandableNotificationRow)) {
- searchView.getHitRect(mTmpRect);
- x -= mTmpRect.left;
- y -= mTmpRect.top;
- searchView = (View) searchView.getParent();
- }
- view.getHitRect(mTmpRect);
- return mTmpRect.contains((int) x,(int) y);
- }
-
@Override
public void onContentUpdated(ExpandableNotificationRow row) {
// Reinspect the notification. Before the super call, because the super call also updates
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/wrapper/NotificationViewWrapper.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/wrapper/NotificationViewWrapper.java
index c834e4b..46d7d93 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/wrapper/NotificationViewWrapper.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/wrapper/NotificationViewWrapper.java
@@ -24,6 +24,7 @@
import android.graphics.ColorMatrix;
import android.graphics.ColorMatrixColorFilter;
import android.graphics.Paint;
+import android.graphics.Rect;
import android.graphics.drawable.ColorDrawable;
import android.graphics.drawable.Drawable;
import android.os.Build;
@@ -49,6 +50,7 @@
protected final View mView;
protected final ExpandableNotificationRow mRow;
+ private final Rect mTmpRect = new Rect();
protected int mBackgroundColor = 0;
@@ -305,6 +307,26 @@
return false;
}
+ /**
+ * Is a given x and y coordinate on a view.
+ *
+ * @param view the view to be checked
+ * @param x the x coordinate, relative to the ExpandableNotificationRow
+ * @param y the y coordinate, relative to the ExpandableNotificationRow
+ * @return {@code true} if it is on the view
+ */
+ protected boolean isOnView(View view, float x, float y) {
+ View searchView = (View) view.getParent();
+ while (searchView != null && !(searchView instanceof ExpandableNotificationRow)) {
+ searchView.getHitRect(mTmpRect);
+ x -= mTmpRect.left;
+ y -= mTmpRect.top;
+ searchView = (View) searchView.getParent();
+ }
+ view.getHitRect(mTmpRect);
+ return mTmpRect.contains((int) x,(int) y);
+ }
+
public int getMinLayoutHeight() {
return 0;
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationChildrenContainer.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationChildrenContainer.java
index d7c88e3..2c17764 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationChildrenContainer.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationChildrenContainer.java
@@ -412,7 +412,7 @@
* @param callback
* @return whether the list order has changed
*/
- public boolean applyChildOrder(List<ExpandableNotificationRow> childOrder,
+ public boolean applyChildOrder(List<? extends NotificationListItem> childOrder,
VisualStabilityManager visualStabilityManager,
VisualStabilityManager.Callback callback) {
if (childOrder == null) {
@@ -421,7 +421,7 @@
boolean result = false;
for (int i = 0; i < mChildren.size() && i < childOrder.size(); i++) {
ExpandableNotificationRow child = mChildren.get(i);
- ExpandableNotificationRow desiredChild = childOrder.get(i);
+ ExpandableNotificationRow desiredChild = (ExpandableNotificationRow) childOrder.get(i);
if (child != desiredChild) {
if (visualStabilityManager.canReorderNotification(desiredChild)) {
mChildren.remove(desiredChild);
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationListContainer.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationListContainer.java
index 15cc72c..c4a720c 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationListContainer.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationListContainer.java
@@ -18,12 +18,14 @@
import static com.android.systemui.statusbar.notification.ActivityLaunchAnimator.ExpandAnimationParameters;
+import android.annotation.NonNull;
import android.view.View;
import android.view.ViewGroup;
import com.android.systemui.plugins.statusbar.NotificationSwipeActionHelper;
import com.android.systemui.statusbar.notification.VisibilityLocationProvider;
import com.android.systemui.statusbar.notification.collection.NotificationEntry;
+import com.android.systemui.statusbar.notification.collection.SimpleNotificationListContainer;
import com.android.systemui.statusbar.notification.logging.NotificationLogger;
import com.android.systemui.statusbar.notification.row.ExpandableNotificationRow;
import com.android.systemui.statusbar.notification.row.ExpandableView;
@@ -33,7 +35,7 @@
* notification views added and removed from it, and will manage displaying them to the user.
*/
public interface NotificationListContainer extends ExpandableView.OnHeightChangedListener,
- VisibilityLocationProvider {
+ VisibilityLocationProvider, SimpleNotificationListContainer {
/**
* Called when a child is being transferred.
@@ -186,4 +188,10 @@
}
default void setWillExpand(boolean willExpand) {};
+
+ /**
+ * Remove a list item from the container
+ * @param v the item to remove
+ */
+ void removeListItem(@NonNull NotificationListItem v);
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationListItem.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationListItem.java
new file mode 100644
index 0000000..8991abe
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationListItem.java
@@ -0,0 +1,66 @@
+/*
+ * 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 com.android.systemui.statusbar.notification.stack;
+
+import android.annotation.NonNull;
+import android.annotation.Nullable;
+import android.view.View;
+
+import com.android.systemui.statusbar.notification.VisualStabilityManager;
+import com.android.systemui.statusbar.notification.collection.NotificationEntry;
+
+import java.util.List;
+
+/**
+* A NotificationListItem is a child view of the notification list that can yield a
+* NotificationEntry when asked. I.e., it's an ExpandableNotificationRow but doesn't require us
+* to strictly rely on ExpandableNotificationRow as our consumed type
+ */
+public interface NotificationListItem {
+ /** @return entry for this item */
+ @NonNull
+ NotificationEntry getEntry();
+
+ /** @return true if the blocking helper is showing */
+ boolean isBlockingHelperShowing();
+
+ /** @return true if this list item is a summary with children */
+ boolean isSummaryWithChildren();
+
+ // This generic is kind of ugly - we should change this once the old VHM is gone
+ /** @return list of the children of this item */
+ List<? extends NotificationListItem> getNotificationChildren();
+
+ /** remove all children from this list item */
+ void removeAllChildren();
+
+ /** remove particular child */
+ void removeChildNotification(NotificationListItem child);
+
+ /** add an item as a child */
+ void addChildNotification(NotificationListItem child, int childIndex);
+
+ /** Update the order of the children with the new list */
+ boolean applyChildOrder(
+ List<? extends NotificationListItem> childOrderList,
+ VisualStabilityManager vsm,
+ @Nullable VisualStabilityManager.Callback callback);
+
+ /** return the associated view for this list item */
+ @NonNull
+ View getView();
+}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayout.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayout.java
index cfcbd88..4d4a2ded 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayout.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayout.java
@@ -3323,11 +3323,21 @@
}
@Override
+ public void notifyGroupChildRemoved(View child, ViewGroup parent) {
+ notifyGroupChildRemoved((ExpandableView) child, parent);
+ }
+
+ @Override
@ShadeViewRefactor(RefactorComponent.SHADE_VIEW)
public void notifyGroupChildAdded(ExpandableView row) {
onViewAddedInternal(row);
}
+ @Override
+ public void notifyGroupChildAdded(View view) {
+ notifyGroupChildAdded((ExpandableView) view);
+ }
+
@ShadeViewRefactor(RefactorComponent.STATE_RESOLVER)
public void setAnimationsEnabled(boolean animationsEnabled) {
mAnimationsEnabled = animationsEnabled;
@@ -5137,11 +5147,22 @@
@Override
@ShadeViewRefactor(RefactorComponent.SHADE_VIEW)
+ public void removeListItem(NotificationListItem v) {
+ removeContainerView(v.getView());
+ }
+
+ @Override
+ @ShadeViewRefactor(RefactorComponent.SHADE_VIEW)
public void addContainerView(View v) {
Assert.isMainThread();
addView(v);
}
+ @Override
+ public void addListItem(NotificationListItem v) {
+ addContainerView(v.getView());
+ }
+
@ShadeViewRefactor(RefactorComponent.SHADE_VIEW)
public void runAfterAnimationFinished(Runnable runnable) {
mAnimationFinishedRunnables.add(runnable);
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/HeadsUpTouchHelper.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/HeadsUpTouchHelper.java
index c282cb8..0b747f9 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/HeadsUpTouchHelper.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/HeadsUpTouchHelper.java
@@ -114,8 +114,9 @@
mInitialTouchY = y;
int startHeight = (int) (mPickedChild.getActualHeight()
+ mPickedChild.getTranslationY());
- mPanel.setPanelScrimMinFraction((float) startHeight
- / mPanel.getMaxPanelHeight());
+ float maxPanelHeight = mPanel.getMaxPanelHeight();
+ mPanel.setPanelScrimMinFraction(maxPanelHeight > 0f
+ ? (float) startHeight / maxPanelHeight : 0f);
mPanel.startExpandMotion(x, y, true /* startTracking */, startHeight);
mPanel.startExpandingFromPeek();
// This call needs to be after the expansion start otherwise we will get a
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationGroupManager.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationGroupManager.java
index 77337e9..ccf6707 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationGroupManager.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationGroupManager.java
@@ -398,8 +398,7 @@
NotificationGroup group = mGroupMap.get(groupKey);
//TODO: see if this can become an Entry
return group == null ? null
- : group.summary == null ? null
- : group.summary;
+ : group.summary;
}
/**
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelViewController.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelViewController.java
index c61d7bb..f9726d2 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelViewController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelViewController.java
@@ -1844,7 +1844,14 @@
} else {
maxHeight = calculatePanelHeightShade();
}
- maxHeight = Math.max(maxHeight, min);
+ maxHeight = Math.max(min, maxHeight);
+ if (maxHeight == 0) {
+ Log.wtf(TAG, "maxPanelHeight is 0. getOverExpansionAmount(): "
+ + getOverExpansionAmount() + ", calculatePanelHeightQsExpanded: "
+ + calculatePanelHeightQsExpanded() + ", calculatePanelHeightShade: "
+ + calculatePanelHeightShade() + ", mStatusBarMinHeight = "
+ + mStatusBarMinHeight + ", mQsMinExpansionHeight = " + mQsMinExpansionHeight);
+ }
return maxHeight;
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PanelBar.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PanelBar.java
index 8d8c8da..c106518 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PanelBar.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PanelBar.java
@@ -16,6 +16,8 @@
package com.android.systemui.statusbar.phone;
+import static java.lang.Float.isNaN;
+
import android.content.Context;
import android.os.Bundle;
import android.os.Parcelable;
@@ -161,6 +163,9 @@
* fraction as the panel also might be expanded if the fraction is 0
*/
public void panelExpansionChanged(float frac, boolean expanded) {
+ if (isNaN(frac)) {
+ throw new IllegalArgumentException("frac cannot be NaN");
+ }
boolean fullyClosed = true;
boolean fullyOpened = false;
if (SPEW) LOG("panelExpansionChanged: start state=%d", mState);
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBarView.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBarView.java
index e25c14c..1c1e7c4 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBarView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBarView.java
@@ -18,6 +18,8 @@
import static com.android.systemui.ScreenDecorations.DisplayCutoutView.boundsFromDirection;
+import static java.lang.Float.isNaN;
+
import android.annotation.Nullable;
import android.content.Context;
import android.content.res.Configuration;
@@ -254,6 +256,9 @@
@Override
public void panelScrimMinFractionChanged(float minFraction) {
+ if (isNaN(minFraction)) {
+ throw new IllegalArgumentException("minFraction cannot be NaN");
+ }
if (mMinFraction != minFraction) {
mMinFraction = minFraction;
updateScrimFraction();
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/HotspotControllerImpl.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/HotspotControllerImpl.java
index 7d532a8..38c165b 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/HotspotControllerImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/HotspotControllerImpl.java
@@ -65,7 +65,6 @@
new TetheringManager.TetheringEventCallback() {
@Override
public void onTetheringSupported(boolean supported) {
- super.onTetheringSupported(supported);
if (mIsTetheringSupported != supported) {
mIsTetheringSupported = supported;
fireHotspotAvailabilityChanged();
@@ -75,7 +74,6 @@
@Override
public void onTetherableInterfaceRegexpsChanged(
TetheringManager.TetheringInterfaceRegexps reg) {
- super.onTetherableInterfaceRegexpsChanged(reg);
final boolean newValue = reg.getTetherableWifiRegexs().size() != 0;
if (mHasTetherableWifiRegexs != newValue) {
mHasTetherableWifiRegexs = newValue;
diff --git a/packages/SystemUI/tests/src/com/android/systemui/SysuiTestCase.java b/packages/SystemUI/tests/src/com/android/systemui/SysuiTestCase.java
index a36f2c7..bb2eea9 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/SysuiTestCase.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/SysuiTestCase.java
@@ -31,6 +31,7 @@
import androidx.test.InstrumentationRegistry;
import com.android.keyguard.KeyguardUpdateMonitor;
+import com.android.settingslib.bluetooth.LocalBluetoothManager;
import com.android.systemui.classifier.FalsingManagerFake;
import com.android.systemui.plugins.FalsingManager;
@@ -80,6 +81,9 @@
// None of them actually need it.
mDependency.injectTestDependency(FalsingManager.class, new FalsingManagerFake());
mDependency.injectMockDependency(KeyguardUpdateMonitor.class);
+
+ // TODO: b/151614195 investigate root cause of needing this mock dependency
+ mDependency.injectMockDependency(LocalBluetoothManager.class);
}
@After
diff --git a/packages/SystemUI/tests/src/com/android/systemui/pip/phone/PipTouchHandlerTest.java b/packages/SystemUI/tests/src/com/android/systemui/pip/phone/PipTouchHandlerTest.java
new file mode 100644
index 0000000..4d7e6ae
--- /dev/null
+++ b/packages/SystemUI/tests/src/com/android/systemui/pip/phone/PipTouchHandlerTest.java
@@ -0,0 +1,170 @@
+/*
+ * 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 com.android.systemui.pip.phone;
+
+import static org.junit.Assert.assertEquals;
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.ArgumentMatchers.anyInt;
+import static org.mockito.Mockito.times;
+import static org.mockito.Mockito.verify;
+
+import android.app.IActivityManager;
+import android.app.IActivityTaskManager;
+import android.graphics.Point;
+import android.graphics.Rect;
+import android.testing.AndroidTestingRunner;
+import android.testing.TestableLooper;
+import android.util.Size;
+import android.view.DisplayInfo;
+
+import androidx.test.filters.SmallTest;
+
+import com.android.systemui.R;
+import com.android.systemui.SysuiTestCase;
+import com.android.systemui.pip.PipBoundsHandler;
+import com.android.systemui.pip.PipSnapAlgorithm;
+import com.android.systemui.pip.PipTaskOrganizer;
+import com.android.systemui.shared.system.InputConsumerController;
+import com.android.systemui.util.DeviceConfigProxy;
+import com.android.systemui.util.FloatingContentCoordinator;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.Mock;
+import org.mockito.Mockito;
+import org.mockito.MockitoAnnotations;
+
+/**
+ * Unit tests against {@link PipTouchHandler}, including but not limited to:
+ * - Update movement bounds based on new bounds
+ * - Update movement bounds based on IME/shelf
+ * - Update movement bounds to PipResizeHandler
+ */
+@RunWith(AndroidTestingRunner.class)
+@SmallTest
+@TestableLooper.RunWithLooper(setAsMainLooper = true)
+public class PipTouchHandlerTest extends SysuiTestCase {
+ private static final int ROUNDING_ERROR_MARGIN = 10;
+ private static final float DEFAULT_ASPECT_RATIO = 1f;
+ private static final Rect EMPTY_CURRENT_BOUNDS = null;
+
+ private PipTouchHandler mPipTouchHandler;
+ private DisplayInfo mDefaultDisplayInfo;
+
+ @Mock
+ private IActivityManager mActivityManager;
+
+ @Mock
+ private IActivityTaskManager mIActivityTaskManager;
+
+ @Mock
+ private PipMenuActivityController mPipMenuActivityController;
+
+ @Mock
+ private InputConsumerController mInputConsumerController;
+
+ @Mock
+ private PipBoundsHandler mPipBoundsHandler;
+
+ @Mock
+ private PipTaskOrganizer mPipTaskOrganizer;
+
+ @Mock
+ private FloatingContentCoordinator mFloatingContentCoordinator;
+
+ @Mock
+ private DeviceConfigProxy mDeviceConfigProxy;
+
+
+ private PipSnapAlgorithm mPipSnapAlgorithm;
+ private PipMotionHelper mMotionHelper;
+ private PipResizeGestureHandler mPipResizeGestureHandler;
+
+ Rect mInsetBounds;
+ Rect mMinBounds;
+ Rect mCurBounds;
+ boolean mFromImeAdjustment;
+ boolean mFromShelfAdjustment;
+ int mDisplayRotation;
+
+
+ @Before
+ public void setUp() throws Exception {
+ MockitoAnnotations.initMocks(this);
+ mPipSnapAlgorithm = new PipSnapAlgorithm(mContext);
+ mPipTouchHandler = new PipTouchHandler(mContext, mActivityManager, mIActivityTaskManager,
+ mPipMenuActivityController, mInputConsumerController, mPipBoundsHandler,
+ mPipTaskOrganizer, mFloatingContentCoordinator, mDeviceConfigProxy,
+ mPipSnapAlgorithm);
+ mMotionHelper = Mockito.spy(mPipTouchHandler.getMotionHelper());
+ mPipResizeGestureHandler = Mockito.spy(mPipTouchHandler.getPipResizeGestureHandler());
+ mPipTouchHandler.setPipMotionHelper(mMotionHelper);
+ mPipTouchHandler.setPipResizeGestureHandler(mPipResizeGestureHandler);
+
+ // Assume a display of 1000 x 1000
+ // inset of 10
+ mInsetBounds = new Rect(10, 10, 990, 990);
+ // minBounds of 100x100 bottom right corner
+ mMinBounds = new Rect(890, 890, 990, 990);
+ mCurBounds = new Rect();
+ mFromImeAdjustment = false;
+ mFromShelfAdjustment = false;
+ mDisplayRotation = 0;
+ }
+
+ @Test
+ public void updateMovementBounds_minBounds() {
+ Rect expectedMinMovementBounds = new Rect();
+ mPipSnapAlgorithm.getMovementBounds(mMinBounds, mInsetBounds, expectedMinMovementBounds, 0);
+
+ mPipTouchHandler.onMovementBoundsChanged(mInsetBounds, mMinBounds, mCurBounds,
+ mFromImeAdjustment, mFromShelfAdjustment, mDisplayRotation);
+
+ assertEquals(expectedMinMovementBounds, mPipTouchHandler.mNormalMovementBounds);
+ verify(mPipResizeGestureHandler, times(1))
+ .updateMinSize(mMinBounds.width(), mMinBounds.height());
+ }
+
+ @Test
+ public void updateMovementBounds_maxBounds() {
+ Point displaySize = new Point();
+ mContext.getDisplay().getRealSize(displaySize);
+ Size maxSize = mPipSnapAlgorithm.getSizeForAspectRatio(1,
+ mContext.getResources().getDimensionPixelSize(
+ R.dimen.pip_expanded_shortest_edge_size), displaySize.x, displaySize.y);
+ Rect maxBounds = new Rect(0, 0, maxSize.getWidth(), maxSize.getHeight());
+ Rect expectedMaxMovementBounds = new Rect();
+ mPipSnapAlgorithm.getMovementBounds(maxBounds, mInsetBounds, expectedMaxMovementBounds, 0);
+
+ mPipTouchHandler.onMovementBoundsChanged(mInsetBounds, mMinBounds, mCurBounds,
+ mFromImeAdjustment, mFromShelfAdjustment, mDisplayRotation);
+
+ assertEquals(expectedMaxMovementBounds, mPipTouchHandler.mExpandedMovementBounds);
+ verify(mPipResizeGestureHandler, times(1))
+ .updateMaxSize(maxBounds.width(), maxBounds.height());
+ }
+
+ @Test
+ public void updateMovementBounds_withImeAdjustment_movesPip() {
+ mFromImeAdjustment = true;
+ mPipTouchHandler.onMovementBoundsChanged(mInsetBounds, mMinBounds, mCurBounds,
+ mFromImeAdjustment, mFromShelfAdjustment, mDisplayRotation);
+
+ verify(mMotionHelper, times(1)).animateToOffset(any(), anyInt());
+ }
+}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/qs/QSPanelTest.java b/packages/SystemUI/tests/src/com/android/systemui/qs/QSPanelTest.java
index ac30421..dbbbaac 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/qs/QSPanelTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/qs/QSPanelTest.java
@@ -85,6 +85,8 @@
@Mock
private NotificationMediaManager mNotificationMediaManager;
@Mock
+ private Executor mForegroundExecutor;
+ @Mock
private Executor mBackgroundExecutor;
@Mock
private LocalBluetoothManager mLocalBluetoothManager;
@@ -97,7 +99,7 @@
mTestableLooper.runWithLooper(() -> {
mMetricsLogger = mDependency.injectMockDependency(MetricsLogger.class);
mQsPanel = new QSPanel(mContext, null, mDumpManager, mBroadcastDispatcher,
- mQSLogger, mNotificationMediaManager, mBackgroundExecutor,
+ mQSLogger, mNotificationMediaManager, mForegroundExecutor, mBackgroundExecutor,
mLocalBluetoothManager);
// Provides a parent with non-zero size for QSPanel
mParentView = new FrameLayout(mContext);
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/NotificationViewHierarchyManagerTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/NotificationViewHierarchyManagerTest.java
index cc5f149..83877f2 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/NotificationViewHierarchyManagerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/NotificationViewHierarchyManagerTest.java
@@ -52,6 +52,7 @@
import com.android.systemui.statusbar.notification.row.NotificationTestHelper;
import com.android.systemui.statusbar.notification.stack.ForegroundServiceSectionController;
import com.android.systemui.statusbar.notification.stack.NotificationListContainer;
+import com.android.systemui.statusbar.notification.stack.NotificationListItem;
import com.android.systemui.statusbar.phone.KeyguardBypassController;
import com.android.systemui.statusbar.phone.NotificationGroupManager;
@@ -285,9 +286,15 @@
public void notifyGroupChildAdded(ExpandableView row) {}
@Override
+ public void notifyGroupChildAdded(View v) {}
+
+ @Override
public void notifyGroupChildRemoved(ExpandableView row, ViewGroup childrenContainer) {}
@Override
+ public void notifyGroupChildRemoved(View v, ViewGroup childrenContainer) {}
+
+ @Override
public void generateAddAnimation(ExpandableView child, boolean fromMoreCard) {}
@Override
@@ -313,12 +320,22 @@
}
@Override
+ public void removeListItem(NotificationListItem li) {
+ removeContainerView(li.getView());
+ }
+
+ @Override
public void addContainerView(View v) {
mLayout.addView(v);
mRows.add(v);
}
@Override
+ public void addListItem(NotificationListItem li) {
+ addContainerView(li.getView());
+ }
+
+ @Override
public void setMaxDisplayedNotifications(int maxNotifications) {
if (mMakeReentrantCallDuringSetMaxDisplayedNotifications) {
mViewHierarchyManager.onDynamicPrivacyChanged();
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/coordinator/HeadsUpCoordinatorTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/coordinator/HeadsUpCoordinatorTest.java
new file mode 100644
index 0000000..0c109c4
--- /dev/null
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/coordinator/HeadsUpCoordinatorTest.java
@@ -0,0 +1,191 @@
+/*
+ * 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 com.android.systemui.statusbar.notification.collection.coordinator;
+
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+
+import android.testing.AndroidTestingRunner;
+import android.testing.TestableLooper;
+
+import androidx.test.filters.SmallTest;
+
+import com.android.systemui.SysuiTestCase;
+import com.android.systemui.statusbar.NotificationRemoteInputManager;
+import com.android.systemui.statusbar.RemoteInputController;
+import com.android.systemui.statusbar.notification.collection.NotifPipeline;
+import com.android.systemui.statusbar.notification.collection.NotificationEntry;
+import com.android.systemui.statusbar.notification.collection.NotificationEntryBuilder;
+import com.android.systemui.statusbar.notification.collection.listbuilder.pluggable.NotifPromoter;
+import com.android.systemui.statusbar.notification.collection.listbuilder.pluggable.NotifSection;
+import com.android.systemui.statusbar.notification.collection.notifcollection.NotifCollectionListener;
+import com.android.systemui.statusbar.notification.collection.notifcollection.NotifLifetimeExtender;
+import com.android.systemui.statusbar.policy.HeadsUpManager;
+import com.android.systemui.statusbar.policy.OnHeadsUpChangedListener;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.ArgumentCaptor;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
+
+@SmallTest
+@RunWith(AndroidTestingRunner.class)
+@TestableLooper.RunWithLooper
+public class HeadsUpCoordinatorTest extends SysuiTestCase {
+
+ private HeadsUpCoordinator mCoordinator;
+
+ // captured listeners and pluggables:
+ private NotifCollectionListener mCollectionListener;
+ private NotifPromoter mNotifPromoter;
+ private NotifLifetimeExtender mNotifLifetimeExtender;
+ private OnHeadsUpChangedListener mOnHeadsUpChangedListener;
+ private NotifSection mNotifSection;
+
+ @Mock private NotifPipeline mNotifPipeline;
+ @Mock private HeadsUpManager mHeadsUpManager;
+ @Mock private NotificationRemoteInputManager mRemoteInputManager;
+ @Mock private RemoteInputController mRemoteInputController;
+ @Mock private NotifLifetimeExtender.OnEndLifetimeExtensionCallback mEndLifetimeExtension;
+
+ private NotificationEntry mEntry;
+
+ @Before
+ public void setUp() {
+ MockitoAnnotations.initMocks(this);
+ when(mRemoteInputManager.getController()).thenReturn(mRemoteInputController);
+
+ mCoordinator = new HeadsUpCoordinator(
+ mHeadsUpManager,
+ mRemoteInputManager
+ );
+
+ mCoordinator.attach(mNotifPipeline);
+
+ // capture arguments:
+ ArgumentCaptor<NotifCollectionListener> notifCollectionCaptor =
+ ArgumentCaptor.forClass(NotifCollectionListener.class);
+ ArgumentCaptor<NotifPromoter> notifPromoterCaptor =
+ ArgumentCaptor.forClass(NotifPromoter.class);
+ ArgumentCaptor<NotifLifetimeExtender> notifLifetimeExtenderCaptor =
+ ArgumentCaptor.forClass(NotifLifetimeExtender.class);
+ ArgumentCaptor<OnHeadsUpChangedListener> headsUpChangedListenerCaptor =
+ ArgumentCaptor.forClass(OnHeadsUpChangedListener.class);
+
+ verify(mNotifPipeline).addCollectionListener(notifCollectionCaptor.capture());
+ verify(mNotifPipeline).addPromoter(notifPromoterCaptor.capture());
+ verify(mNotifPipeline).addNotificationLifetimeExtender(
+ notifLifetimeExtenderCaptor.capture());
+ verify(mHeadsUpManager).addListener(headsUpChangedListenerCaptor.capture());
+
+ mCollectionListener = notifCollectionCaptor.getValue();
+ mNotifPromoter = notifPromoterCaptor.getValue();
+ mNotifLifetimeExtender = notifLifetimeExtenderCaptor.getValue();
+ mOnHeadsUpChangedListener = headsUpChangedListenerCaptor.getValue();
+
+ mNotifSection = mCoordinator.getSection();
+ mNotifLifetimeExtender.setCallback(mEndLifetimeExtension);
+ mEntry = new NotificationEntryBuilder().build();
+ }
+
+ @Test
+ public void testPromotesCurrentHUN() {
+ // GIVEN the current HUN is set to mEntry
+ setCurrentHUN(mEntry);
+
+ // THEN only promote the current HUN, mEntry
+ assertTrue(mNotifPromoter.shouldPromoteToTopLevel(mEntry));
+ assertFalse(mNotifPromoter.shouldPromoteToTopLevel(new NotificationEntryBuilder().build()));
+ }
+
+ @Test
+ public void testIncludeInSectionCurrentHUN() {
+ // GIVEN the current HUN is set to mEntry
+ setCurrentHUN(mEntry);
+
+ // THEN only section the current HUN, mEntry
+ assertTrue(mNotifSection.isInSection(mEntry));
+ assertFalse(mNotifSection.isInSection(new NotificationEntryBuilder().build()));
+ }
+
+ @Test
+ public void testLifetimeExtendsCurrentHUN() {
+ // GIVEN there is a HUN, mEntry
+ setCurrentHUN(mEntry);
+
+ // THEN only the current HUN, mEntry, should be lifetimeExtended
+ assertTrue(mNotifLifetimeExtender.shouldExtendLifetime(mEntry, /* cancellationReason */ 0));
+ assertFalse(mNotifLifetimeExtender.shouldExtendLifetime(
+ new NotificationEntryBuilder().build(), /* cancellationReason */ 0));
+ }
+
+ @Test
+ public void testLifetimeExtensionEndsOnNewHUN() {
+ // GIVEN there was a HUN that was lifetime extended
+ setCurrentHUN(mEntry);
+ assertTrue(mNotifLifetimeExtender.shouldExtendLifetime(
+ mEntry, /* cancellation reason */ 0));
+
+ // WHEN there's a new HUN
+ NotificationEntry newHUN = new NotificationEntryBuilder().build();
+ setCurrentHUN(newHUN);
+
+ // THEN the old entry's lifetime extension should be cancelled
+ verify(mEndLifetimeExtension).onEndLifetimeExtension(mNotifLifetimeExtender, mEntry);
+ }
+
+ @Test
+ public void testLifetimeExtensionEndsOnNoHUNs() {
+ // GIVEN there was a HUN that was lifetime extended
+ setCurrentHUN(mEntry);
+ assertTrue(mNotifLifetimeExtender.shouldExtendLifetime(
+ mEntry, /* cancellation reason */ 0));
+
+ // WHEN there's no longer a HUN
+ setCurrentHUN(null);
+
+ // THEN the old entry's lifetime extension should be cancelled
+ verify(mEndLifetimeExtension).onEndLifetimeExtension(mNotifLifetimeExtender, mEntry);
+ }
+
+ @Test
+ public void testOnEntryRemovedRemovesHeadsUpNotification() {
+ // GIVEN the current HUN is mEntry
+ setCurrentHUN(mEntry);
+
+ // WHEN mEntry is removed from the notification collection
+ mCollectionListener.onEntryRemoved(mEntry, /* cancellation reason */ 0);
+ when(mRemoteInputController.isSpinning(any())).thenReturn(false);
+
+ // THEN heads up manager should remove the entry
+ verify(mHeadsUpManager).removeNotification(mEntry.getKey(), false);
+ }
+
+ private void setCurrentHUN(NotificationEntry entry) {
+ when(mHeadsUpManager.getTopEntry()).thenReturn(entry);
+ when(mHeadsUpManager.isAlerting(any())).thenReturn(false);
+ if (entry != null) {
+ when(mHeadsUpManager.isAlerting(entry.getKey())).thenReturn(true);
+ }
+ mOnHeadsUpChangedListener.onHeadsUpStateChanged(entry, entry != null);
+ }
+}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/coordinator/PreparationCoordinatorTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/coordinator/PreparationCoordinatorTest.java
index 792b4d5..8143cf5 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/coordinator/PreparationCoordinatorTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/coordinator/PreparationCoordinatorTest.java
@@ -20,8 +20,10 @@
import static org.junit.Assert.assertTrue;
import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.never;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
import android.os.RemoteException;
import android.testing.AndroidTestingRunner;
@@ -33,12 +35,15 @@
import com.android.systemui.SysuiTestCase;
import com.android.systemui.statusbar.notification.collection.NotifInflaterImpl;
import com.android.systemui.statusbar.notification.collection.NotifPipeline;
+import com.android.systemui.statusbar.notification.collection.NotifViewBarn;
import com.android.systemui.statusbar.notification.collection.NotificationEntry;
import com.android.systemui.statusbar.notification.collection.NotificationEntryBuilder;
import com.android.systemui.statusbar.notification.collection.listbuilder.OnBeforeFinalizeFilterListener;
import com.android.systemui.statusbar.notification.collection.listbuilder.pluggable.NotifFilter;
import com.android.systemui.statusbar.notification.collection.notifcollection.NotifCollectionListener;
+import com.android.systemui.statusbar.notification.interruption.NotificationInterruptStateProvider;
import com.android.systemui.statusbar.notification.row.NotifInflationErrorManager;
+import com.android.systemui.statusbar.policy.HeadsUpManager;
import org.junit.Before;
import org.junit.Test;
@@ -73,6 +78,8 @@
@Mock private NotifPipeline mNotifPipeline;
@Mock private IStatusBarService mService;
@Mock private NotifInflaterImpl mNotifInflater;
+ @Mock private NotificationInterruptStateProvider mNotificationInterruptStateProvider;
+ @Mock private HeadsUpManager mHeadsUpManager;
@Before
public void setUp() {
@@ -86,7 +93,10 @@
mock(PreparationCoordinatorLogger.class),
mNotifInflater,
mErrorManager,
- mService);
+ mock(NotifViewBarn.class),
+ mService,
+ mNotificationInterruptStateProvider,
+ mHeadsUpManager);
ArgumentCaptor<NotifFilter> filterCaptor = ArgumentCaptor.forClass(NotifFilter.class);
mCoordinator.attach(mNotifPipeline);
@@ -170,4 +180,24 @@
// THEN it isn't filtered from shade list
assertFalse(mUninflatedFilter.shouldFilterOut(mEntry, 0));
}
+
+ @Test
+ public void testShowHUNOnInflationFinished() {
+ // WHEN a notification should HUN and its inflation is finished
+ when(mNotificationInterruptStateProvider.shouldHeadsUp(mEntry)).thenReturn(true);
+ mCallback.onInflationFinished(mEntry);
+
+ // THEN we tell the HeadsUpManager to show the notification
+ verify(mHeadsUpManager).showNotification(mEntry);
+ }
+
+ @Test
+ public void testNoHUNOnInflationFinished() {
+ // WHEN a notification shouldn't HUN and its inflation is finished
+ when(mNotificationInterruptStateProvider.shouldHeadsUp(mEntry)).thenReturn(false);
+ mCallback.onInflationFinished(mEntry);
+
+ // THEN we never tell the HeadsUpManager to show the notification
+ verify(mHeadsUpManager, never()).showNotification(mEntry);
+ }
}
diff --git a/packages/Tethering/src/com/android/server/connectivity/tethering/OffloadController.java b/packages/Tethering/src/com/android/server/connectivity/tethering/OffloadController.java
index a402ffa..15cdb6a 100644
--- a/packages/Tethering/src/com/android/server/connectivity/tethering/OffloadController.java
+++ b/packages/Tethering/src/com/android/server/connectivity/tethering/OffloadController.java
@@ -39,8 +39,7 @@
import android.net.netlink.ConntrackMessage;
import android.net.netlink.NetlinkConstants;
import android.net.netlink.NetlinkSocket;
-import android.net.netstats.provider.AbstractNetworkStatsProvider;
-import android.net.netstats.provider.NetworkStatsProviderCallback;
+import android.net.netstats.provider.NetworkStatsProvider;
import android.net.util.SharedLog;
import android.os.Handler;
import android.provider.Settings;
@@ -89,8 +88,8 @@
private final Handler mHandler;
private final OffloadHardwareInterface mHwInterface;
private final ContentResolver mContentResolver;
- private final @NonNull OffloadTetheringStatsProvider mStatsProvider;
- private final @Nullable NetworkStatsProviderCallback mStatsProviderCb;
+ @Nullable
+ private final OffloadTetheringStatsProvider mStatsProvider;
private final SharedLog mLog;
private final HashMap<String, LinkProperties> mDownstreams;
private boolean mConfigInitialized;
@@ -124,19 +123,18 @@
mHandler = h;
mHwInterface = hwi;
mContentResolver = contentResolver;
- mStatsProvider = new OffloadTetheringStatsProvider();
mLog = log.forSubComponent(TAG);
mDownstreams = new HashMap<>();
mExemptPrefixes = new HashSet<>();
mLastLocalPrefixStrs = new HashSet<>();
- NetworkStatsProviderCallback providerCallback = null;
+ OffloadTetheringStatsProvider provider = new OffloadTetheringStatsProvider();
try {
- providerCallback = nsm.registerNetworkStatsProvider(
- getClass().getSimpleName(), mStatsProvider);
+ nsm.registerNetworkStatsProvider(getClass().getSimpleName(), provider);
} catch (RuntimeException e) {
Log.wtf(TAG, "Cannot register offload stats provider: " + e);
+ provider = null;
}
- mStatsProviderCb = providerCallback;
+ mStatsProvider = provider;
}
/** Start hardware offload. */
@@ -185,7 +183,7 @@
// and we need to synchronize stats and limits between
// software and hardware forwarding.
updateStatsForAllUpstreams();
- mStatsProvider.pushTetherStats();
+ if (mStatsProvider != null) mStatsProvider.pushTetherStats();
}
@Override
@@ -198,7 +196,7 @@
// limits set take into account any software tethering
// traffic that has been happening in the meantime.
updateStatsForAllUpstreams();
- mStatsProvider.pushTetherStats();
+ if (mStatsProvider != null) mStatsProvider.pushTetherStats();
// [2] (Re)Push all state.
computeAndPushLocalPrefixes(UpdateType.FORCE);
pushAllDownstreamState();
@@ -217,10 +215,12 @@
// TODO: rev the HAL so that it provides an interface name.
updateStatsForCurrentUpstream();
- mStatsProvider.pushTetherStats();
- // Push stats to service does not cause the service react to it immediately.
- // Inform the service about limit reached.
- if (mStatsProviderCb != null) mStatsProviderCb.onLimitReached();
+ if (mStatsProvider != null) {
+ mStatsProvider.pushTetherStats();
+ // Push stats to service does not cause the service react to it
+ // immediately. Inform the service about limit reached.
+ mStatsProvider.notifyLimitReached();
+ }
}
@Override
@@ -263,13 +263,17 @@
}
@VisibleForTesting
- class OffloadTetheringStatsProvider extends AbstractNetworkStatsProvider {
+ class OffloadTetheringStatsProvider extends NetworkStatsProvider {
// These stats must only ever be touched on the handler thread.
@NonNull
private NetworkStats mIfaceStats = new NetworkStats(0L, 0);
@NonNull
private NetworkStats mUidStats = new NetworkStats(0L, 0);
+ /**
+ * A helper function that collect tether stats from local hashmap. Note that this does not
+ * invoke binder call.
+ */
@VisibleForTesting
@NonNull
NetworkStats getTetherStats(@NonNull StatsType how) {
@@ -280,14 +284,14 @@
final ForwardedStats value = kv.getValue();
final Entry entry = new Entry(kv.getKey(), uid, SET_DEFAULT, TAG_NONE, METERED_NO,
ROAMING_NO, DEFAULT_NETWORK_NO, value.rxBytes, 0L, value.txBytes, 0L, 0L);
- stats = stats.addValues(entry);
+ stats = stats.addEntry(entry);
}
return stats;
}
@Override
- public void setLimit(String iface, long quotaBytes) {
+ public void onSetLimit(String iface, long quotaBytes) {
// Listen for all iface is necessary since upstream might be changed after limit
// is set.
mHandler.post(() -> {
@@ -315,13 +319,12 @@
*/
public void pushTetherStats() {
// TODO: remove the accumulated stats and report the diff from HAL directly.
- if (null == mStatsProviderCb) return;
final NetworkStats ifaceDiff =
getTetherStats(StatsType.STATS_PER_IFACE).subtract(mIfaceStats);
final NetworkStats uidDiff =
getTetherStats(StatsType.STATS_PER_UID).subtract(mUidStats);
try {
- mStatsProviderCb.onStatsUpdated(0 /* token */, ifaceDiff, uidDiff);
+ notifyStatsUpdated(0 /* token */, ifaceDiff, uidDiff);
mIfaceStats = mIfaceStats.add(ifaceDiff);
mUidStats = mUidStats.add(uidDiff);
} catch (RuntimeException e) {
@@ -330,7 +333,7 @@
}
@Override
- public void requestStatsUpdate(int token) {
+ public void onRequestStatsUpdate(int token) {
// Do not attempt to update stats by querying the offload HAL
// synchronously from a different thread than the Handler thread. http://b/64771555.
mHandler.post(() -> {
@@ -340,7 +343,7 @@
}
@Override
- public void setAlert(long quotaBytes) {
+ public void onSetAlert(long quotaBytes) {
// TODO: Ask offload HAL to notify alert without stopping traffic.
}
}
diff --git a/packages/Tethering/tests/unit/src/com/android/server/connectivity/tethering/OffloadControllerTest.java b/packages/Tethering/tests/unit/src/com/android/server/connectivity/tethering/OffloadControllerTest.java
index 7e62e5a..fe84086 100644
--- a/packages/Tethering/tests/unit/src/com/android/server/connectivity/tethering/OffloadControllerTest.java
+++ b/packages/Tethering/tests/unit/src/com/android/server/connectivity/tethering/OffloadControllerTest.java
@@ -33,6 +33,8 @@
import static com.android.testutils.MiscAssertsKt.assertThrows;
import static com.android.testutils.NetworkStatsUtilsKt.orderInsensitiveEquals;
+import static junit.framework.Assert.assertNotNull;
+
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertTrue;
import static org.mockito.ArgumentMatchers.anyInt;
@@ -61,8 +63,7 @@
import android.net.NetworkStats;
import android.net.NetworkStats.Entry;
import android.net.RouteInfo;
-import android.net.netstats.provider.AbstractNetworkStatsProvider;
-import android.net.netstats.provider.NetworkStatsProviderCallback;
+import android.net.netstats.provider.INetworkStatsProviderCallback;
import android.net.util.SharedLog;
import android.os.Handler;
import android.os.Looper;
@@ -108,12 +109,10 @@
@Mock private ApplicationInfo mApplicationInfo;
@Mock private Context mContext;
@Mock private NetworkStatsManager mStatsManager;
- @Mock private NetworkStatsProviderCallback mTetherStatsProviderCb;
+ @Mock private INetworkStatsProviderCallback mTetherStatsProviderCb;
+ private OffloadController.OffloadTetheringStatsProvider mTetherStatsProvider;
private final ArgumentCaptor<ArrayList> mStringArrayCaptor =
ArgumentCaptor.forClass(ArrayList.class);
- private final ArgumentCaptor<OffloadController.OffloadTetheringStatsProvider>
- mTetherStatsProviderCaptor =
- ArgumentCaptor.forClass(OffloadController.OffloadTetheringStatsProvider.class);
private final ArgumentCaptor<OffloadHardwareInterface.ControlCallback> mControlCallbackCaptor =
ArgumentCaptor.forClass(OffloadHardwareInterface.ControlCallback.class);
private MockContentResolver mContentResolver;
@@ -126,8 +125,6 @@
mContentResolver.addProvider(Settings.AUTHORITY, new FakeSettingsProvider());
when(mContext.getContentResolver()).thenReturn(mContentResolver);
FakeSettingsProvider.clearSettingsProvider();
- when(mStatsManager.registerNetworkStatsProvider(anyString(), any()))
- .thenReturn(mTetherStatsProviderCb);
}
@After public void tearDown() throws Exception {
@@ -154,8 +151,14 @@
private OffloadController makeOffloadController() throws Exception {
OffloadController offload = new OffloadController(new Handler(Looper.getMainLooper()),
mHardware, mContentResolver, mStatsManager, new SharedLog("test"));
+ final ArgumentCaptor<OffloadController.OffloadTetheringStatsProvider>
+ tetherStatsProviderCaptor =
+ ArgumentCaptor.forClass(OffloadController.OffloadTetheringStatsProvider.class);
verify(mStatsManager).registerNetworkStatsProvider(anyString(),
- mTetherStatsProviderCaptor.capture());
+ tetherStatsProviderCaptor.capture());
+ mTetherStatsProvider = tetherStatsProviderCaptor.getValue();
+ assertNotNull(mTetherStatsProvider);
+ mTetherStatsProvider.setProviderCallbackBinder(mTetherStatsProviderCb);
return offload;
}
@@ -413,9 +416,6 @@
final OffloadController offload = makeOffloadController();
offload.start();
- final OffloadController.OffloadTetheringStatsProvider provider =
- mTetherStatsProviderCaptor.getValue();
-
final String ethernetIface = "eth1";
final String mobileIface = "rmnet_data0";
@@ -443,15 +443,15 @@
inOrder.verify(mHardware, times(1)).getForwardedStats(eq(mobileIface));
// Verify that the fetched stats are stored.
- final NetworkStats ifaceStats = provider.getTetherStats(STATS_PER_IFACE);
- final NetworkStats uidStats = provider.getTetherStats(STATS_PER_UID);
+ final NetworkStats ifaceStats = mTetherStatsProvider.getTetherStats(STATS_PER_IFACE);
+ final NetworkStats uidStats = mTetherStatsProvider.getTetherStats(STATS_PER_UID);
final NetworkStats expectedIfaceStats = new NetworkStats(0L, 2)
- .addValues(buildTestEntry(STATS_PER_IFACE, mobileIface, 999, 99999))
- .addValues(buildTestEntry(STATS_PER_IFACE, ethernetIface, 12345, 54321));
+ .addEntry(buildTestEntry(STATS_PER_IFACE, mobileIface, 999, 99999))
+ .addEntry(buildTestEntry(STATS_PER_IFACE, ethernetIface, 12345, 54321));
final NetworkStats expectedUidStats = new NetworkStats(0L, 2)
- .addValues(buildTestEntry(STATS_PER_UID, mobileIface, 999, 99999))
- .addValues(buildTestEntry(STATS_PER_UID, ethernetIface, 12345, 54321));
+ .addEntry(buildTestEntry(STATS_PER_UID, mobileIface, 999, 99999))
+ .addEntry(buildTestEntry(STATS_PER_UID, ethernetIface, 12345, 54321));
assertTrue(orderInsensitiveEquals(expectedIfaceStats, ifaceStats));
assertTrue(orderInsensitiveEquals(expectedUidStats, uidStats));
@@ -462,13 +462,12 @@
NetworkStats.class);
// Force pushing stats update to verify the stats reported.
- provider.pushTetherStats();
- verify(mTetherStatsProviderCb, times(1)).onStatsUpdated(anyInt(),
- ifaceStatsCaptor.capture(), uidStatsCaptor.capture());
+ mTetherStatsProvider.pushTetherStats();
+ verify(mTetherStatsProviderCb, times(1))
+ .notifyStatsUpdated(anyInt(), ifaceStatsCaptor.capture(), uidStatsCaptor.capture());
assertTrue(orderInsensitiveEquals(expectedIfaceStats, ifaceStatsCaptor.getValue()));
assertTrue(orderInsensitiveEquals(expectedUidStats, uidStatsCaptor.getValue()));
-
when(mHardware.getForwardedStats(eq(ethernetIface))).thenReturn(
new ForwardedStats(100000, 100000));
offload.setUpstreamLinkProperties(null);
@@ -483,31 +482,31 @@
inOrder.verifyNoMoreInteractions();
// Verify that the stored stats is accumulated.
- final NetworkStats ifaceStatsAccu = provider.getTetherStats(STATS_PER_IFACE);
- final NetworkStats uidStatsAccu = provider.getTetherStats(STATS_PER_UID);
+ final NetworkStats ifaceStatsAccu = mTetherStatsProvider.getTetherStats(STATS_PER_IFACE);
+ final NetworkStats uidStatsAccu = mTetherStatsProvider.getTetherStats(STATS_PER_UID);
final NetworkStats expectedIfaceStatsAccu = new NetworkStats(0L, 2)
- .addValues(buildTestEntry(STATS_PER_IFACE, mobileIface, 999, 99999))
- .addValues(buildTestEntry(STATS_PER_IFACE, ethernetIface, 112345, 154321));
+ .addEntry(buildTestEntry(STATS_PER_IFACE, mobileIface, 999, 99999))
+ .addEntry(buildTestEntry(STATS_PER_IFACE, ethernetIface, 112345, 154321));
final NetworkStats expectedUidStatsAccu = new NetworkStats(0L, 2)
- .addValues(buildTestEntry(STATS_PER_UID, mobileIface, 999, 99999))
- .addValues(buildTestEntry(STATS_PER_UID, ethernetIface, 112345, 154321));
+ .addEntry(buildTestEntry(STATS_PER_UID, mobileIface, 999, 99999))
+ .addEntry(buildTestEntry(STATS_PER_UID, ethernetIface, 112345, 154321));
assertTrue(orderInsensitiveEquals(expectedIfaceStatsAccu, ifaceStatsAccu));
assertTrue(orderInsensitiveEquals(expectedUidStatsAccu, uidStatsAccu));
// Verify that only diff of stats is reported.
reset(mTetherStatsProviderCb);
- provider.pushTetherStats();
+ mTetherStatsProvider.pushTetherStats();
final NetworkStats expectedIfaceStatsDiff = new NetworkStats(0L, 2)
- .addValues(buildTestEntry(STATS_PER_IFACE, mobileIface, 0, 0))
- .addValues(buildTestEntry(STATS_PER_IFACE, ethernetIface, 100000, 100000));
+ .addEntry(buildTestEntry(STATS_PER_IFACE, mobileIface, 0, 0))
+ .addEntry(buildTestEntry(STATS_PER_IFACE, ethernetIface, 100000, 100000));
final NetworkStats expectedUidStatsDiff = new NetworkStats(0L, 2)
- .addValues(buildTestEntry(STATS_PER_UID, mobileIface, 0, 0))
- .addValues(buildTestEntry(STATS_PER_UID, ethernetIface, 100000, 100000));
- verify(mTetherStatsProviderCb, times(1)).onStatsUpdated(anyInt(),
- ifaceStatsCaptor.capture(), uidStatsCaptor.capture());
+ .addEntry(buildTestEntry(STATS_PER_UID, mobileIface, 0, 0))
+ .addEntry(buildTestEntry(STATS_PER_UID, ethernetIface, 100000, 100000));
+ verify(mTetherStatsProviderCb, times(1))
+ .notifyStatsUpdated(anyInt(), ifaceStatsCaptor.capture(), uidStatsCaptor.capture());
assertTrue(orderInsensitiveEquals(expectedIfaceStatsDiff, ifaceStatsCaptor.getValue()));
assertTrue(orderInsensitiveEquals(expectedUidStatsDiff, uidStatsCaptor.getValue()));
}
@@ -529,19 +528,18 @@
lp.setInterfaceName(ethernetIface);
offload.setUpstreamLinkProperties(lp);
- AbstractNetworkStatsProvider provider = mTetherStatsProviderCaptor.getValue();
final InOrder inOrder = inOrder(mHardware);
when(mHardware.setUpstreamParameters(any(), any(), any(), any())).thenReturn(true);
when(mHardware.setDataLimit(anyString(), anyLong())).thenReturn(true);
// Applying an interface quota to the current upstream immediately sends it to the hardware.
- provider.setLimit(ethernetIface, ethernetLimit);
+ mTetherStatsProvider.onSetLimit(ethernetIface, ethernetLimit);
waitForIdle();
inOrder.verify(mHardware).setDataLimit(ethernetIface, ethernetLimit);
inOrder.verifyNoMoreInteractions();
// Applying an interface quota to another upstream does not take any immediate action.
- provider.setLimit(mobileIface, mobileLimit);
+ mTetherStatsProvider.onSetLimit(mobileIface, mobileLimit);
waitForIdle();
inOrder.verify(mHardware, never()).setDataLimit(anyString(), anyLong());
@@ -554,7 +552,7 @@
// Setting a limit of ITetheringStatsProvider.QUOTA_UNLIMITED causes the limit to be set
// to Long.MAX_VALUE.
- provider.setLimit(mobileIface, ITetheringStatsProvider.QUOTA_UNLIMITED);
+ mTetherStatsProvider.onSetLimit(mobileIface, ITetheringStatsProvider.QUOTA_UNLIMITED);
waitForIdle();
inOrder.verify(mHardware).setDataLimit(mobileIface, Long.MAX_VALUE);
@@ -562,7 +560,7 @@
when(mHardware.setUpstreamParameters(any(), any(), any(), any())).thenReturn(false);
lp.setInterfaceName(ethernetIface);
offload.setUpstreamLinkProperties(lp);
- provider.setLimit(mobileIface, mobileLimit);
+ mTetherStatsProvider.onSetLimit(mobileIface, mobileLimit);
waitForIdle();
inOrder.verify(mHardware, never()).setDataLimit(anyString(), anyLong());
@@ -571,7 +569,7 @@
when(mHardware.setDataLimit(anyString(), anyLong())).thenReturn(false);
lp.setInterfaceName(mobileIface);
offload.setUpstreamLinkProperties(lp);
- provider.setLimit(mobileIface, mobileLimit);
+ mTetherStatsProvider.onSetLimit(mobileIface, mobileLimit);
waitForIdle();
inOrder.verify(mHardware).getForwardedStats(ethernetIface);
inOrder.verify(mHardware).stopOffloadControl();
@@ -587,7 +585,7 @@
OffloadHardwareInterface.ControlCallback callback = mControlCallbackCaptor.getValue();
callback.onStoppedLimitReached();
- verify(mTetherStatsProviderCb, times(1)).onStatsUpdated(anyInt(), any(), any());
+ verify(mTetherStatsProviderCb, times(1)).notifyStatsUpdated(anyInt(), any(), any());
}
@Test
@@ -691,7 +689,7 @@
verify(mHardware, times(1)).getForwardedStats(eq(RMNET0));
verify(mHardware, times(1)).getForwardedStats(eq(WLAN0));
// TODO: verify the exact stats reported.
- verify(mTetherStatsProviderCb, times(1)).onStatsUpdated(anyInt(), any(), any());
+ verify(mTetherStatsProviderCb, times(1)).notifyStatsUpdated(anyInt(), any(), any());
verifyNoMoreInteractions(mTetherStatsProviderCb);
verifyNoMoreInteractions(mHardware);
}
@@ -756,7 +754,7 @@
// Verify forwarded stats behaviour.
verify(mHardware, times(1)).getForwardedStats(eq(RMNET0));
verify(mHardware, times(1)).getForwardedStats(eq(WLAN0));
- verify(mTetherStatsProviderCb, times(1)).onStatsUpdated(anyInt(), any(), any());
+ verify(mTetherStatsProviderCb, times(1)).notifyStatsUpdated(anyInt(), any(), any());
verifyNoMoreInteractions(mTetherStatsProviderCb);
// TODO: verify local prefixes and downstreams are also pushed to the HAL.
diff --git a/services/core/java/com/android/server/PackageWatchdog.java b/services/core/java/com/android/server/PackageWatchdog.java
index 52a1b5a..41a104c 100644
--- a/services/core/java/com/android/server/PackageWatchdog.java
+++ b/services/core/java/com/android/server/PackageWatchdog.java
@@ -161,6 +161,9 @@
private final Runnable mSaveToFile = this::saveToFile;
private final SystemClock mSystemClock;
private final BootThreshold mBootThreshold;
+ // The set of packages that have been synced with the ExplicitHealthCheckController
+ @GuardedBy("mLock")
+ private Set<String> mRequestedHealthCheckPackages = new ArraySet<>();
@GuardedBy("mLock")
private boolean mIsPackagesReady;
// Flag to control whether explicit health checks are supported or not
@@ -174,6 +177,9 @@
// 0 if no prune is scheduled.
@GuardedBy("mLock")
private long mUptimeAtLastStateSync;
+ // If true, sync explicit health check packages with the ExplicitHealthCheckController.
+ @GuardedBy("mLock")
+ private boolean mSyncRequired = false;
@FunctionalInterface
@VisibleForTesting
@@ -249,6 +255,7 @@
*/
public void registerHealthObserver(PackageHealthObserver observer) {
synchronized (mLock) {
+ mSyncRequired = true;
ObserverInternal internalObserver = mAllObservers.get(observer.getName());
if (internalObserver != null) {
internalObserver.registeredObserver = observer;
@@ -628,17 +635,23 @@
* @see #syncRequestsAsync
*/
private void syncRequests() {
- Set<String> packages = null;
+ boolean syncRequired = false;
synchronized (mLock) {
if (mIsPackagesReady) {
- packages = getPackagesPendingHealthChecksLocked();
+ Set<String> packages = getPackagesPendingHealthChecksLocked();
+ if (!packages.equals(mRequestedHealthCheckPackages) || mSyncRequired) {
+ syncRequired = true;
+ mRequestedHealthCheckPackages = packages;
+ }
} // else, we will sync requests when packages become ready
}
// Call outside lock to avoid holding lock when calling into the controller.
- if (packages != null) {
- Slog.i(TAG, "Syncing health check requests for packages: " + packages);
- mHealthCheckController.syncRequests(packages);
+ if (syncRequired) {
+ Slog.i(TAG, "Syncing health check requests for packages: "
+ + mRequestedHealthCheckPackages);
+ mHealthCheckController.syncRequests(mRequestedHealthCheckPackages);
+ mSyncRequired = false;
}
}
diff --git a/services/core/java/com/android/server/am/ActivityManagerService.java b/services/core/java/com/android/server/am/ActivityManagerService.java
index 1c225d9..ebca1f7 100644
--- a/services/core/java/com/android/server/am/ActivityManagerService.java
+++ b/services/core/java/com/android/server/am/ActivityManagerService.java
@@ -19842,6 +19842,7 @@
void setPermissions(@Nullable String[] permissions) {
mPermissions = permissions;
+ PackageManager.invalidatePackageInfoCache();
}
@Override
diff --git a/services/core/java/com/android/server/am/BugReportHandlerUtil.java b/services/core/java/com/android/server/am/BugReportHandlerUtil.java
index ba89fce..03f4a54 100644
--- a/services/core/java/com/android/server/am/BugReportHandlerUtil.java
+++ b/services/core/java/com/android/server/am/BugReportHandlerUtil.java
@@ -16,15 +16,20 @@
package com.android.server.am;
+import static android.app.AppOpsManager.OP_NONE;
import static com.android.server.am.ActivityManagerDebugConfig.TAG_AM;
import static com.android.server.am.ActivityManagerDebugConfig.TAG_WITH_CLASS_NAME;
+import android.app.Activity;
import android.app.BroadcastOptions;
+import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.content.pm.ResolveInfo;
import android.os.Binder;
+import android.os.BugreportManager;
+import android.os.BugreportParams;
import android.os.UserHandle;
import android.provider.Settings;
import android.text.TextUtils;
@@ -110,9 +115,17 @@
options.setBackgroundActivityStartsAllowed(true);
final long identity = Binder.clearCallingIdentity();
try {
- context.sendBroadcastAsUser(intent, UserHandle.of(handlerUser),
+ // Handler app's BroadcastReceiver should call setResultCode(Activity.RESULT_OK) to
+ // let ResultBroadcastReceiver know the handler app is available.
+ context.sendOrderedBroadcastAsUser(intent,
+ UserHandle.of(handlerUser),
android.Manifest.permission.DUMP,
- options.toBundle());
+ OP_NONE, options.toBundle(),
+ new ResultBroadcastReceiver(),
+ /* scheduler= */ null,
+ Activity.RESULT_CANCELED,
+ /* initialData= */ null,
+ /* initialExtras= */ null);
} catch (RuntimeException e) {
Slog.e(TAG, "Error while trying to launch bugreport handler app.", e);
return false;
@@ -176,4 +189,19 @@
Binder.restoreCallingIdentity(identity);
}
}
+
+ private static class ResultBroadcastReceiver extends BroadcastReceiver {
+ @Override
+ public void onReceive(Context context, Intent intent) {
+ if (getResultCode() == Activity.RESULT_OK) {
+ return;
+ }
+
+ Slog.w(TAG, "Request bug report because handler app seems to be not available.");
+ BugreportManager bugreportManager = context.getSystemService(BugreportManager.class);
+ bugreportManager.requestBugreport(
+ new BugreportParams(BugreportParams.BUGREPORT_MODE_INTERACTIVE),
+ /* shareTitle= */null, /* shareDescription= */ null);
+ }
+ }
}
diff --git a/services/core/java/com/android/server/locksettings/LockSettingsService.java b/services/core/java/com/android/server/locksettings/LockSettingsService.java
index c1c3760..1b4ec8a 100644
--- a/services/core/java/com/android/server/locksettings/LockSettingsService.java
+++ b/services/core/java/com/android/server/locksettings/LockSettingsService.java
@@ -530,6 +530,11 @@
return Settings.Global.getInt(contentResolver, keyName, defaultValue);
}
+ public int settingsSecureGetInt(ContentResolver contentResolver, String keyName,
+ int defaultValue, int userId) {
+ return Settings.Secure.getIntForUser(contentResolver, keyName, defaultValue, userId);
+ }
+
public @NonNull ManagedProfilePasswordCache getManagedProfilePasswordCache() {
try {
java.security.KeyStore ks = java.security.KeyStore.getInstance("AndroidKeyStore");
@@ -1010,6 +1015,13 @@
}
}
+ private void enforceFrpResolved() {
+ if (mInjector.settingsSecureGetInt(mContext.getContentResolver(),
+ Settings.Secure.SECURE_FRP_MODE, 0, UserHandle.USER_SYSTEM) == 1) {
+ throw new SecurityException("Cannot change credential while FRP is not resolved yet");
+ }
+ }
+
private final void checkWritePermission(int userId) {
mContext.enforceCallingOrSelfPermission(PERMISSION, "LockSettingsWrite");
}
@@ -1572,6 +1584,7 @@
"This operation requires secure lock screen feature");
}
checkWritePermission(userId);
+ enforceFrpResolved();
// When changing credential for profiles with unified challenge, some callers
// will pass in empty credential while others will pass in the credential of
diff --git a/services/core/java/com/android/server/media/BluetoothRouteProvider.java b/services/core/java/com/android/server/media/BluetoothRouteProvider.java
index 265b9ad..28f8380 100644
--- a/services/core/java/com/android/server/media/BluetoothRouteProvider.java
+++ b/services/core/java/com/android/server/media/BluetoothRouteProvider.java
@@ -85,7 +85,9 @@
mListener = listener;
mAudioManager = (AudioManager) mContext.getSystemService(Context.AUDIO_SERVICE);
buildBluetoothRoutes();
+ }
+ public void start() {
mBluetoothAdapter.getProfileProxy(mContext, mProfileListener, BluetoothProfile.A2DP);
mBluetoothAdapter.getProfileProxy(mContext, mProfileListener, BluetoothProfile.HEARING_AID);
diff --git a/services/core/java/com/android/server/media/SystemMediaRoute2Provider.java b/services/core/java/com/android/server/media/SystemMediaRoute2Provider.java
index 5c97e90..c7d14e0 100644
--- a/services/core/java/com/android/server/media/SystemMediaRoute2Provider.java
+++ b/services/core/java/com/android/server/media/SystemMediaRoute2Provider.java
@@ -103,25 +103,20 @@
publishProviderState();
boolean sessionInfoChanged;
- synchronized (mLock) {
- sessionInfoChanged = updateSessionInfosIfNeededLocked();
- }
+ sessionInfoChanged = updateSessionInfosIfNeeded();
if (sessionInfoChanged) {
notifySessionInfoUpdated();
}
});
-
- mHandler.post(() -> notifyProviderState());
-
- //TODO: clean up this
- // This is required because it is not instantiated in the main thread and
- // BluetoothRoutesUpdatedListener can be called before here
- synchronized (mLock) {
- updateSessionInfosIfNeededLocked();
- }
+ updateSessionInfosIfNeeded();
mContext.registerReceiver(new VolumeChangeReceiver(),
new IntentFilter(AudioManager.VOLUME_CHANGED_ACTION));
+
+ mHandler.post(() -> {
+ mBtRouteProvider.start();
+ notifyProviderState();
+ });
}
@Override
@@ -220,35 +215,38 @@
/**
* Updates the mSessionInfo. Returns true if the session info is changed.
*/
- boolean updateSessionInfosIfNeededLocked() {
- // Prevent to execute this method before mBtRouteProvider is created.
- if (mBtRouteProvider == null) return false;
- RoutingSessionInfo oldSessionInfo = mSessionInfos.isEmpty() ? null : mSessionInfos.get(0);
+ boolean updateSessionInfosIfNeeded() {
+ synchronized (mLock) {
+ // Prevent to execute this method before mBtRouteProvider is created.
+ if (mBtRouteProvider == null) return false;
+ RoutingSessionInfo oldSessionInfo = mSessionInfos.isEmpty() ? null : mSessionInfos.get(
+ 0);
- RoutingSessionInfo.Builder builder = new RoutingSessionInfo.Builder(
- SYSTEM_SESSION_ID, "" /* clientPackageName */)
- .setSystemSession(true);
+ RoutingSessionInfo.Builder builder = new RoutingSessionInfo.Builder(
+ SYSTEM_SESSION_ID, "" /* clientPackageName */)
+ .setSystemSession(true);
- MediaRoute2Info selectedRoute = mBtRouteProvider.getSelectedRoute();
- if (selectedRoute == null) {
- selectedRoute = mDefaultRoute;
- } else {
- builder.addTransferableRoute(mDefaultRoute.getId());
- }
- mSelectedRouteId = selectedRoute.getId();
- builder.addSelectedRoute(mSelectedRouteId);
+ MediaRoute2Info selectedRoute = mBtRouteProvider.getSelectedRoute();
+ if (selectedRoute == null) {
+ selectedRoute = mDefaultRoute;
+ } else {
+ builder.addTransferableRoute(mDefaultRoute.getId());
+ }
+ mSelectedRouteId = selectedRoute.getId();
+ builder.addSelectedRoute(mSelectedRouteId);
- for (MediaRoute2Info route : mBtRouteProvider.getTransferableRoutes()) {
- builder.addTransferableRoute(route.getId());
- }
+ for (MediaRoute2Info route : mBtRouteProvider.getTransferableRoutes()) {
+ builder.addTransferableRoute(route.getId());
+ }
- RoutingSessionInfo newSessionInfo = builder.setProviderId(mUniqueId).build();
- if (Objects.equals(oldSessionInfo, newSessionInfo)) {
- return false;
- } else {
- mSessionInfos.clear();
- mSessionInfos.add(newSessionInfo);
- return true;
+ RoutingSessionInfo newSessionInfo = builder.setProviderId(mUniqueId).build();
+ if (Objects.equals(oldSessionInfo, newSessionInfo)) {
+ return false;
+ } else {
+ mSessionInfos.clear();
+ mSessionInfos.add(newSessionInfo);
+ return true;
+ }
}
}
diff --git a/services/core/java/com/android/server/net/NetworkPolicyManagerInternal.java b/services/core/java/com/android/server/net/NetworkPolicyManagerInternal.java
index 563dcf7..48f1ddb 100644
--- a/services/core/java/com/android/server/net/NetworkPolicyManagerInternal.java
+++ b/services/core/java/com/android/server/net/NetworkPolicyManagerInternal.java
@@ -21,7 +21,7 @@
import android.annotation.NonNull;
import android.net.Network;
import android.net.NetworkTemplate;
-import android.net.netstats.provider.AbstractNetworkStatsProvider;
+import android.net.netstats.provider.NetworkStatsProvider;
import android.telephony.SubscriptionPlan;
import java.util.Set;
@@ -130,8 +130,8 @@
Set<String> packageNames, int userId);
/**
- * Notifies that the specified {@link AbstractNetworkStatsProvider} has reached its quota
- * which was set through {@link AbstractNetworkStatsProvider#setLimit(String, long)}.
+ * Notifies that the specified {@link NetworkStatsProvider} has reached its quota
+ * which was set through {@link NetworkStatsProvider#onSetLimit(String, long)}.
*
* @param tag the human readable identifier of the custom network stats provider.
*/
diff --git a/services/core/java/com/android/server/net/NetworkPolicyManagerService.java b/services/core/java/com/android/server/net/NetworkPolicyManagerService.java
index 0b1c91f..caf2914 100644
--- a/services/core/java/com/android/server/net/NetworkPolicyManagerService.java
+++ b/services/core/java/com/android/server/net/NetworkPolicyManagerService.java
@@ -75,7 +75,7 @@
import static android.net.NetworkTemplate.MATCH_WIFI;
import static android.net.NetworkTemplate.buildTemplateMobileAll;
import static android.net.TrafficStats.MB_IN_BYTES;
-import static android.net.netstats.provider.AbstractNetworkStatsProvider.QUOTA_UNLIMITED;
+import static android.net.netstats.provider.NetworkStatsProvider.QUOTA_UNLIMITED;
import static android.os.Trace.TRACE_TAG_NETWORK;
import static android.provider.Settings.Global.NETPOLICY_OVERRIDE_ENABLED;
import static android.provider.Settings.Global.NETPOLICY_QUOTA_ENABLED;
diff --git a/services/core/java/com/android/server/net/NetworkStatsFactory.java b/services/core/java/com/android/server/net/NetworkStatsFactory.java
index 22b01be..75ffe35 100644
--- a/services/core/java/com/android/server/net/NetworkStatsFactory.java
+++ b/services/core/java/com/android/server/net/NetworkStatsFactory.java
@@ -229,7 +229,7 @@
entry.txPackets += reader.nextLong();
}
- stats.addEntry(entry);
+ stats.insertEntry(entry);
reader.finishLine();
}
} catch (NullPointerException|NumberFormatException e) {
@@ -279,7 +279,7 @@
entry.txBytes = reader.nextLong();
entry.txPackets = reader.nextLong();
- stats.addEntry(entry);
+ stats.insertEntry(entry);
reader.finishLine();
}
} catch (NullPointerException|NumberFormatException e) {
@@ -439,7 +439,7 @@
if ((limitIfaces == null || ArrayUtils.contains(limitIfaces, entry.iface))
&& (limitUid == UID_ALL || limitUid == entry.uid)
&& (limitTag == TAG_ALL || limitTag == entry.tag)) {
- stats.addEntry(entry);
+ stats.insertEntry(entry);
}
reader.finishLine();
diff --git a/services/core/java/com/android/server/net/NetworkStatsService.java b/services/core/java/com/android/server/net/NetworkStatsService.java
index 4504704..10136b3 100644
--- a/services/core/java/com/android/server/net/NetworkStatsService.java
+++ b/services/core/java/com/android/server/net/NetworkStatsService.java
@@ -17,6 +17,7 @@
package com.android.server.net;
import static android.Manifest.permission.ACCESS_NETWORK_STATE;
+import static android.Manifest.permission.NETWORK_STATS_PROVIDER;
import static android.Manifest.permission.READ_NETWORK_USAGE_HISTORY;
import static android.Manifest.permission.UPDATE_DEVICE_STATS;
import static android.content.Intent.ACTION_SHUTDOWN;
@@ -102,7 +103,7 @@
import android.net.TrafficStats;
import android.net.netstats.provider.INetworkStatsProvider;
import android.net.netstats.provider.INetworkStatsProviderCallback;
-import android.net.netstats.provider.NetworkStatsProviderCallback;
+import android.net.netstats.provider.NetworkStatsProvider;
import android.os.BestClock;
import android.os.Binder;
import android.os.DropBoxManager;
@@ -557,7 +558,7 @@
} catch (RemoteException e) {
// ignored; service lives in system_server
}
- invokeForAllStatsProviderCallbacks((cb) -> cb.mProvider.setAlert(mGlobalAlertBytes));
+ invokeForAllStatsProviderCallbacks((cb) -> cb.mProvider.onSetAlert(mGlobalAlertBytes));
}
@Override
@@ -758,7 +759,7 @@
final NetworkStatsHistory.Entry entry = history.getValues(start, end, now, null);
final NetworkStats stats = new NetworkStats(end - start, 1);
- stats.addEntry(new NetworkStats.Entry(IFACE_ALL, UID_ALL, SET_ALL, TAG_NONE,
+ stats.insertEntry(new NetworkStats.Entry(IFACE_ALL, UID_ALL, SET_ALL, TAG_NONE,
METERED_ALL, ROAMING_ALL, DEFAULT_NETWORK_ALL, entry.rxBytes, entry.rxPackets,
entry.txBytes, entry.txPackets, entry.operations));
return stats;
@@ -1375,7 +1376,8 @@
Trace.traceBegin(TRACE_TAG_NETWORK, "provider.requestStatsUpdate");
final int registeredCallbackCount = mStatsProviderCbList.getRegisteredCallbackCount();
mStatsProviderSem.drainPermits();
- invokeForAllStatsProviderCallbacks((cb) -> cb.mProvider.requestStatsUpdate(0 /* unused */));
+ invokeForAllStatsProviderCallbacks(
+ (cb) -> cb.mProvider.onRequestStatsUpdate(0 /* unused */));
try {
mStatsProviderSem.tryAcquire(registeredCallbackCount,
MAX_STATS_PROVIDER_POLL_WAIT_TIME_MS, TimeUnit.MILLISECONDS);
@@ -1550,7 +1552,7 @@
@Override
public void setStatsProviderLimitAsync(@NonNull String iface, long quota) {
Slog.v(TAG, "setStatsProviderLimitAsync(" + iface + "," + quota + ")");
- invokeForAllStatsProviderCallbacks((cb) -> cb.mProvider.setLimit(iface, quota));
+ invokeForAllStatsProviderCallbacks((cb) -> cb.mProvider.onSetLimit(iface, quota));
}
}
@@ -1819,16 +1821,15 @@
*
* @param tag a human readable identifier of the custom network stats provider.
* @param provider the {@link INetworkStatsProvider} binder corresponding to the
- * {@link android.net.netstats.provider.AbstractNetworkStatsProvider} to be
- * registered.
+ * {@link NetworkStatsProvider} to be registered.
*
- * @return a binder interface of
- * {@link android.net.netstats.provider.NetworkStatsProviderCallback}, which can be
- * used to report events to the system.
+ * @return a {@link INetworkStatsProviderCallback} binder
+ * interface, which can be used to report events to the system.
*/
public @NonNull INetworkStatsProviderCallback registerNetworkStatsProvider(
@NonNull String tag, @NonNull INetworkStatsProvider provider) {
- mContext.enforceCallingOrSelfPermission(UPDATE_DEVICE_STATS, TAG);
+ enforceAnyPermissionOf(NETWORK_STATS_PROVIDER,
+ NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK);
Objects.requireNonNull(provider, "provider is null");
Objects.requireNonNull(tag, "tag is null");
try {
@@ -1929,7 +1930,7 @@
}
@Override
- public void onStatsUpdated(int token, @Nullable NetworkStats ifaceStats,
+ public void notifyStatsUpdated(int token, @Nullable NetworkStats ifaceStats,
@Nullable NetworkStats uidStats) {
// TODO: 1. Use token to map ifaces to correct NetworkIdentity.
// 2. Store the difference and store it directly to the recorder.
@@ -1941,12 +1942,12 @@
}
@Override
- public void onAlertReached() throws RemoteException {
+ public void notifyAlertReached() throws RemoteException {
mAlertObserver.limitReached(LIMIT_GLOBAL_ALERT, null /* unused */);
}
@Override
- public void onLimitReached() {
+ public void notifyLimitReached() {
Log.d(TAG, mTag + ": onLimitReached");
LocalServices.getService(NetworkPolicyManagerInternal.class)
.onStatsProviderLimitReached(mTag);
diff --git a/services/core/java/com/android/server/notification/ZenModeHelper.java b/services/core/java/com/android/server/notification/ZenModeHelper.java
index f45e66e..2853956 100644
--- a/services/core/java/com/android/server/notification/ZenModeHelper.java
+++ b/services/core/java/com/android/server/notification/ZenModeHelper.java
@@ -141,6 +141,7 @@
updateDefaultAutomaticRuleNames();
mConfig = mDefaultConfig.copy();
mConfigs.put(UserHandle.USER_SYSTEM, mConfig);
+ mConsolidatedPolicy = mConfig.toNotificationPolicy();
mSettingsObserver = new SettingsObserver(mHandler);
mSettingsObserver.observe();
@@ -821,9 +822,6 @@
* @return a copy of the zen mode consolidated policy
*/
public Policy getConsolidatedNotificationPolicy() {
- if (mConsolidatedPolicy == null) {
- return null;
- }
return mConsolidatedPolicy.copy();
}
diff --git a/services/core/java/com/android/server/pm/LauncherAppsService.java b/services/core/java/com/android/server/pm/LauncherAppsService.java
index 8031eaa..1b271a7 100644
--- a/services/core/java/com/android/server/pm/LauncherAppsService.java
+++ b/services/core/java/com/android/server/pm/LauncherAppsService.java
@@ -819,6 +819,18 @@
}
@Override
+ public String getShortcutIconUri(String callingPackage, String packageName,
+ String shortcutId, int userId) {
+ ensureShortcutPermission(callingPackage);
+ if (!canAccessProfile(userId, "Cannot access shortcuts")) {
+ return null;
+ }
+
+ return mShortcutServiceInternal.getShortcutIconUri(getCallingUserId(), callingPackage,
+ packageName, shortcutId, userId);
+ }
+
+ @Override
public boolean hasShortcutHostPermission(String callingPackage) {
verifyCallingPackage(callingPackage);
return mShortcutServiceInternal.hasShortcutHostPermission(getCallingUserId(),
diff --git a/services/core/java/com/android/server/pm/PackageInstallerService.java b/services/core/java/com/android/server/pm/PackageInstallerService.java
index cdc3736..2ff3d2a 100644
--- a/services/core/java/com/android/server/pm/PackageInstallerService.java
+++ b/services/core/java/com/android/server/pm/PackageInstallerService.java
@@ -47,7 +47,6 @@
import android.net.Uri;
import android.os.Binder;
import android.os.Build;
-import android.os.Bundle;
import android.os.Environment;
import android.os.Handler;
import android.os.HandlerThread;
@@ -1038,80 +1037,11 @@
}
}
- static void sendPendingStreaming(Context context, IntentSender target, int sessionId,
- Throwable cause) {
- final Intent intent = new Intent();
- intent.putExtra(PackageInstaller.EXTRA_SESSION_ID, sessionId);
- intent.putExtra(PackageInstaller.EXTRA_STATUS, PackageInstaller.STATUS_PENDING_STREAMING);
- if (cause != null && !TextUtils.isEmpty(cause.getMessage())) {
- intent.putExtra(PackageInstaller.EXTRA_STATUS_MESSAGE,
- "Staging Image Not Ready [" + cause.getMessage() + "]");
- } else {
- intent.putExtra(PackageInstaller.EXTRA_STATUS_MESSAGE, "Staging Image Not Ready");
- }
- try {
- target.sendIntent(context, 0, intent, null, null);
- } catch (SendIntentException ignored) {
- }
- }
-
- static void sendOnUserActionRequired(Context context, IntentSender target, int sessionId,
- Intent intent) {
- final Intent fillIn = new Intent();
- fillIn.putExtra(PackageInstaller.EXTRA_SESSION_ID, sessionId);
- fillIn.putExtra(PackageInstaller.EXTRA_STATUS, PackageInstaller.STATUS_PENDING_USER_ACTION);
- fillIn.putExtra(Intent.EXTRA_INTENT, intent);
- try {
- target.sendIntent(context, 0, fillIn, null, null);
- } catch (SendIntentException ignored) {
- }
- }
-
- static void sendOnPackageInstalled(Context context, IntentSender target, int sessionId,
- boolean showNotification, int userId, String basePackageName, int returnCode,
- String msg, Bundle extras) {
- if (PackageManager.INSTALL_SUCCEEDED == returnCode && showNotification) {
- boolean update = (extras != null) && extras.getBoolean(Intent.EXTRA_REPLACING);
- Notification notification = buildSuccessNotification(context,
- context.getResources()
- .getString(update ? R.string.package_updated_device_owner :
- R.string.package_installed_device_owner),
- basePackageName,
- userId);
- if (notification != null) {
- NotificationManager notificationManager = (NotificationManager)
- context.getSystemService(Context.NOTIFICATION_SERVICE);
- notificationManager.notify(basePackageName,
- SystemMessage.NOTE_PACKAGE_STATE,
- notification);
- }
- }
- final Intent fillIn = new Intent();
- fillIn.putExtra(PackageInstaller.EXTRA_PACKAGE_NAME, basePackageName);
- fillIn.putExtra(PackageInstaller.EXTRA_SESSION_ID, sessionId);
- fillIn.putExtra(PackageInstaller.EXTRA_STATUS,
- PackageManager.installStatusToPublicStatus(returnCode));
- fillIn.putExtra(PackageInstaller.EXTRA_STATUS_MESSAGE,
- PackageManager.installStatusToString(returnCode, msg));
- fillIn.putExtra(PackageInstaller.EXTRA_LEGACY_STATUS, returnCode);
- if (extras != null) {
- final String existing = extras.getString(
- PackageManager.EXTRA_FAILURE_EXISTING_PACKAGE);
- if (!TextUtils.isEmpty(existing)) {
- fillIn.putExtra(PackageInstaller.EXTRA_OTHER_PACKAGE_NAME, existing);
- }
- }
- try {
- target.sendIntent(context, 0, fillIn, null, null);
- } catch (SendIntentException ignored) {
- }
- }
-
/**
* Build a notification for package installation / deletion by device owners that is shown if
* the operation succeeds.
*/
- private static Notification buildSuccessNotification(Context context, String contentText,
+ static Notification buildSuccessNotification(Context context, String contentText,
String basePackageName, int userId) {
PackageInfo packageInfo = null;
try {
diff --git a/services/core/java/com/android/server/pm/PackageInstallerSession.java b/services/core/java/com/android/server/pm/PackageInstallerSession.java
index 28d7c13..45a25a0 100644
--- a/services/core/java/com/android/server/pm/PackageInstallerSession.java
+++ b/services/core/java/com/android/server/pm/PackageInstallerSession.java
@@ -51,6 +51,8 @@
import android.Manifest;
import android.annotation.NonNull;
import android.annotation.Nullable;
+import android.app.Notification;
+import android.app.NotificationManager;
import android.app.admin.DevicePolicyEventLogger;
import android.app.admin.DevicePolicyManagerInternal;
import android.content.ComponentName;
@@ -119,9 +121,11 @@
import android.util.SparseIntArray;
import android.util.apk.ApkSignatureVerifier;
+import com.android.internal.R;
import com.android.internal.annotations.GuardedBy;
import com.android.internal.content.NativeLibraryHelper;
import com.android.internal.content.PackageHelper;
+import com.android.internal.messages.nano.SystemMessageProto;
import com.android.internal.os.SomeArgs;
import com.android.internal.util.ArrayUtils;
import com.android.internal.util.IndentingPrintWriter;
@@ -440,8 +444,7 @@
final int returnCode = args.argi1;
args.recycle();
- PackageInstallerService.sendOnPackageInstalled(mContext,
- statusReceiver, sessionId,
+ sendOnPackageInstalled(mContext, statusReceiver, sessionId,
isInstallerDeviceOwnerOrAffiliatedProfileOwnerLocked(), userId,
packageName, returnCode, message, extras);
@@ -1636,8 +1639,7 @@
}
}
if (!success) {
- PackageInstallerService.sendOnPackageInstalled(mContext,
- mRemoteStatusReceiver, sessionId,
+ sendOnPackageInstalled(mContext, mRemoteStatusReceiver, sessionId,
isInstallerDeviceOwnerOrAffiliatedProfileOwnerLocked(), userId, null,
failure.error, failure.getLocalizedMessage(), null);
return;
@@ -1684,8 +1686,7 @@
intent.setPackage(mPm.getPackageInstallerPackageName());
intent.putExtra(PackageInstaller.EXTRA_SESSION_ID, sessionId);
- PackageInstallerService.sendOnUserActionRequired(mContext,
- mRemoteStatusReceiver, sessionId, intent);
+ sendOnUserActionRequired(mContext, mRemoteStatusReceiver, sessionId, intent);
// Commit was keeping session marked as active until now; release
// that extra refcount so session appears idle.
@@ -2620,9 +2621,8 @@
} catch (RemoteException e) {
// In case of streaming failure we don't want to fail or commit the session.
// Just return from this method and allow caller to commit again.
- PackageInstallerService.sendPendingStreaming(mContext,
- mRemoteStatusReceiver,
- sessionId, new StreamingException(e));
+ sendPendingStreaming(mContext, mRemoteStatusReceiver, sessionId,
+ new StreamingException(e));
}
}
};
@@ -2924,6 +2924,75 @@
pw.decreaseIndent();
}
+ private static void sendOnUserActionRequired(Context context, IntentSender target,
+ int sessionId, Intent intent) {
+ final Intent fillIn = new Intent();
+ fillIn.putExtra(PackageInstaller.EXTRA_SESSION_ID, sessionId);
+ fillIn.putExtra(PackageInstaller.EXTRA_STATUS, PackageInstaller.STATUS_PENDING_USER_ACTION);
+ fillIn.putExtra(Intent.EXTRA_INTENT, intent);
+ try {
+ target.sendIntent(context, 0, fillIn, null, null);
+ } catch (IntentSender.SendIntentException ignored) {
+ }
+ }
+
+ private static void sendOnPackageInstalled(Context context, IntentSender target, int sessionId,
+ boolean showNotification, int userId, String basePackageName, int returnCode,
+ String msg, Bundle extras) {
+ if (PackageManager.INSTALL_SUCCEEDED == returnCode && showNotification) {
+ boolean update = (extras != null) && extras.getBoolean(Intent.EXTRA_REPLACING);
+ Notification notification = PackageInstallerService.buildSuccessNotification(context,
+ context.getResources()
+ .getString(update ? R.string.package_updated_device_owner :
+ R.string.package_installed_device_owner),
+ basePackageName,
+ userId);
+ if (notification != null) {
+ NotificationManager notificationManager = (NotificationManager)
+ context.getSystemService(Context.NOTIFICATION_SERVICE);
+ notificationManager.notify(basePackageName,
+ SystemMessageProto.SystemMessage.NOTE_PACKAGE_STATE,
+ notification);
+ }
+ }
+ final Intent fillIn = new Intent();
+ fillIn.putExtra(PackageInstaller.EXTRA_PACKAGE_NAME, basePackageName);
+ fillIn.putExtra(PackageInstaller.EXTRA_SESSION_ID, sessionId);
+ fillIn.putExtra(PackageInstaller.EXTRA_STATUS,
+ PackageManager.installStatusToPublicStatus(returnCode));
+ fillIn.putExtra(PackageInstaller.EXTRA_STATUS_MESSAGE,
+ PackageManager.installStatusToString(returnCode, msg));
+ fillIn.putExtra(PackageInstaller.EXTRA_LEGACY_STATUS, returnCode);
+ if (extras != null) {
+ final String existing = extras.getString(
+ PackageManager.EXTRA_FAILURE_EXISTING_PACKAGE);
+ if (!TextUtils.isEmpty(existing)) {
+ fillIn.putExtra(PackageInstaller.EXTRA_OTHER_PACKAGE_NAME, existing);
+ }
+ }
+ try {
+ target.sendIntent(context, 0, fillIn, null, null);
+ } catch (IntentSender.SendIntentException ignored) {
+ }
+ }
+
+ private static void sendPendingStreaming(Context context, IntentSender target, int sessionId,
+ Throwable cause) {
+ final Intent intent = new Intent();
+ intent.putExtra(PackageInstaller.EXTRA_SESSION_ID, sessionId);
+ intent.putExtra(PackageInstaller.EXTRA_STATUS, PackageInstaller.STATUS_PENDING_STREAMING);
+ if (cause != null && !TextUtils.isEmpty(cause.getMessage())) {
+ intent.putExtra(PackageInstaller.EXTRA_STATUS_MESSAGE,
+ "Staging Image Not Ready [" + cause.getMessage() + "]");
+ } else {
+ intent.putExtra(PackageInstaller.EXTRA_STATUS_MESSAGE, "Staging Image Not Ready");
+ }
+ try {
+ target.sendIntent(context, 0, intent, null, null);
+ } catch (IntentSender.SendIntentException ignored) {
+ }
+ }
+
private static void writeGrantedRuntimePermissionsLocked(XmlSerializer out,
String[] grantedRuntimePermissions) throws IOException {
if (grantedRuntimePermissions != null) {
diff --git a/services/core/java/com/android/server/pm/ShortcutBitmapSaver.java b/services/core/java/com/android/server/pm/ShortcutBitmapSaver.java
index dc534a7..1c5f0a7 100644
--- a/services/core/java/com/android/server/pm/ShortcutBitmapSaver.java
+++ b/services/core/java/com/android/server/pm/ShortcutBitmapSaver.java
@@ -28,7 +28,6 @@
import android.util.Slog;
import com.android.internal.annotations.GuardedBy;
-import com.android.internal.util.Preconditions;
import com.android.server.pm.ShortcutService.FileOutputStreamWithPath;
import libcore.io.IoUtils;
@@ -150,9 +149,10 @@
shortcut.setIconResourceId(0);
shortcut.setIconResName(null);
shortcut.setBitmapPath(null);
+ shortcut.setIconUri(null);
shortcut.clearFlags(ShortcutInfo.FLAG_HAS_ICON_FILE |
ShortcutInfo.FLAG_ADAPTIVE_BITMAP | ShortcutInfo.FLAG_HAS_ICON_RES |
- ShortcutInfo.FLAG_ICON_FILE_PENDING_SAVE);
+ ShortcutInfo.FLAG_ICON_FILE_PENDING_SAVE | ShortcutInfo.FLAG_HAS_ICON_URI);
}
public void saveBitmapLocked(ShortcutInfo shortcut,
diff --git a/services/core/java/com/android/server/pm/ShortcutPackage.java b/services/core/java/com/android/server/pm/ShortcutPackage.java
index c8df5c7..1fc0a38 100644
--- a/services/core/java/com/android/server/pm/ShortcutPackage.java
+++ b/services/core/java/com/android/server/pm/ShortcutPackage.java
@@ -102,6 +102,7 @@
private static final String ATTR_ICON_RES_ID = "icon-res";
private static final String ATTR_ICON_RES_NAME = "icon-resname";
private static final String ATTR_BITMAP_PATH = "bitmap-path";
+ private static final String ATTR_ICON_URI = "icon-uri";
private static final String ATTR_LOCUS_ID = "locus-id";
private static final String ATTR_PERSON_NAME = "name";
@@ -1628,7 +1629,8 @@
int flags = si.getFlags() &
~(ShortcutInfo.FLAG_HAS_ICON_FILE | ShortcutInfo.FLAG_HAS_ICON_RES
| ShortcutInfo.FLAG_ICON_FILE_PENDING_SAVE
- | ShortcutInfo.FLAG_DYNAMIC);
+ | ShortcutInfo.FLAG_DYNAMIC
+ | ShortcutInfo.FLAG_HAS_ICON_URI | ShortcutInfo.FLAG_ADAPTIVE_BITMAP);
ShortcutService.writeAttr(out, ATTR_FLAGS, flags);
// Set the publisher version code at every backup.
@@ -1646,6 +1648,7 @@
ShortcutService.writeAttr(out, ATTR_ICON_RES_ID, si.getIconResourceId());
ShortcutService.writeAttr(out, ATTR_ICON_RES_NAME, si.getIconResName());
ShortcutService.writeAttr(out, ATTR_BITMAP_PATH, si.getBitmapPath());
+ ShortcutService.writeAttr(out, ATTR_ICON_URI, si.getIconUri());
}
if (shouldBackupDetails) {
@@ -1764,6 +1767,7 @@
int iconResId;
String iconResName;
String bitmapPath;
+ String iconUri;
final String locusIdString;
int backupVersionCode;
ArraySet<String> categories = null;
@@ -1791,6 +1795,7 @@
iconResId = (int) ShortcutService.parseLongAttribute(parser, ATTR_ICON_RES_ID);
iconResName = ShortcutService.parseStringAttribute(parser, ATTR_ICON_RES_NAME);
bitmapPath = ShortcutService.parseStringAttribute(parser, ATTR_BITMAP_PATH);
+ iconUri = ShortcutService.parseStringAttribute(parser, ATTR_ICON_URI);
locusIdString = ShortcutService.parseStringAttribute(parser, ATTR_LOCUS_ID);
final int outerDepth = parser.getDepth();
@@ -1866,8 +1871,8 @@
categories,
intents.toArray(new Intent[intents.size()]),
rank, extras, lastChangedTimestamp, flags,
- iconResId, iconResName, bitmapPath, disabledReason,
- persons.toArray(new Person[persons.size()]), locusId);
+ iconResId, iconResName, bitmapPath, iconUri,
+ disabledReason, persons.toArray(new Person[persons.size()]), locusId);
}
private static Intent parseIntent(XmlPullParser parser)
@@ -1991,16 +1996,26 @@
Log.e(TAG_VERIFY, "Package " + getPackageName() + ": shortcut " + si.getId()
+ " still has an icon");
}
- if (si.hasAdaptiveBitmap() && !si.hasIconFile()) {
+ if (si.hasAdaptiveBitmap() && !(si.hasIconFile() || si.hasIconUri())) {
failed = true;
Log.e(TAG_VERIFY, "Package " + getPackageName() + ": shortcut " + si.getId()
- + " has adaptive bitmap but was not saved to a file.");
+ + " has adaptive bitmap but was not saved to a file nor has icon uri.");
}
if (si.hasIconFile() && si.hasIconResource()) {
failed = true;
Log.e(TAG_VERIFY, "Package " + getPackageName() + ": shortcut " + si.getId()
+ " has both resource and bitmap icons");
}
+ if (si.hasIconFile() && si.hasIconUri()) {
+ failed = true;
+ Log.e(TAG_VERIFY, "Package " + getPackageName() + ": shortcut " + si.getId()
+ + " has both url and bitmap icons");
+ }
+ if (si.hasIconUri() && si.hasIconResource()) {
+ failed = true;
+ Log.e(TAG_VERIFY, "Package " + getPackageName() + ": shortcut " + si.getId()
+ + " has both url and resource icons");
+ }
if (si.isEnabled()
!= (si.getDisabledReason() == ShortcutInfo.DISABLED_REASON_NOT_DISABLED)) {
failed = true;
diff --git a/services/core/java/com/android/server/pm/ShortcutParser.java b/services/core/java/com/android/server/pm/ShortcutParser.java
index f9c0db0..d3aace1 100644
--- a/services/core/java/com/android/server/pm/ShortcutParser.java
+++ b/services/core/java/com/android/server/pm/ShortcutParser.java
@@ -449,6 +449,7 @@
iconResId,
null, // icon res name
null, // bitmap path
+ null, // icon Url
disabledReason,
null /* persons */,
null /* locusId */);
diff --git a/services/core/java/com/android/server/pm/ShortcutService.java b/services/core/java/com/android/server/pm/ShortcutService.java
index 66f3574..8768ab0 100644
--- a/services/core/java/com/android/server/pm/ShortcutService.java
+++ b/services/core/java/com/android/server/pm/ShortcutService.java
@@ -24,6 +24,8 @@
import android.app.ActivityManagerInternal;
import android.app.AppGlobals;
import android.app.IUidObserver;
+import android.app.IUriGrantsManager;
+import android.app.UriGrantsManager;
import android.app.usage.UsageStatsManagerInternal;
import android.appwidget.AppWidgetProviderInfo;
import android.content.BroadcastReceiver;
@@ -65,6 +67,7 @@
import android.os.Environment;
import android.os.FileUtils;
import android.os.Handler;
+import android.os.IBinder;
import android.os.LocaleList;
import android.os.Looper;
import android.os.ParcelFileDescriptor;
@@ -106,6 +109,7 @@
import com.android.server.LocalServices;
import com.android.server.SystemService;
import com.android.server.pm.ShortcutUser.PackageWithUser;
+import com.android.server.uri.UriGrantsManagerInternal;
import libcore.io.IoUtils;
@@ -327,6 +331,9 @@
private final UserManagerInternal mUserManagerInternal;
private final UsageStatsManagerInternal mUsageStatsManagerInternal;
private final ActivityManagerInternal mActivityManagerInternal;
+ private final IUriGrantsManager mUriGrantsManager;
+ private final UriGrantsManagerInternal mUriGrantsManagerInternal;
+ private final IBinder mUriPermissionOwner;
private final ShortcutRequestPinProcessor mShortcutRequestPinProcessor;
private final ShortcutBitmapSaver mShortcutBitmapSaver;
@@ -449,6 +456,11 @@
mActivityManagerInternal = Objects.requireNonNull(
LocalServices.getService(ActivityManagerInternal.class));
+ mUriGrantsManager = UriGrantsManager.getService();
+ mUriGrantsManagerInternal = Objects.requireNonNull(
+ LocalServices.getService(UriGrantsManagerInternal.class));
+ mUriPermissionOwner = mUriGrantsManagerInternal.newUriPermissionOwner(TAG);
+
mShortcutRequestPinProcessor = new ShortcutRequestPinProcessor(this, mLock);
mShortcutBitmapSaver = new ShortcutBitmapSaver(this);
mShortcutDumpFiles = new ShortcutDumpFiles(this);
@@ -1414,7 +1426,7 @@
}
void saveIconAndFixUpShortcutLocked(ShortcutInfo shortcut) {
- if (shortcut.hasIconFile() || shortcut.hasIconResource()) {
+ if (shortcut.hasIconFile() || shortcut.hasIconResource() || shortcut.hasIconUri()) {
return;
}
@@ -1438,6 +1450,15 @@
shortcut.addFlags(ShortcutInfo.FLAG_HAS_ICON_RES);
return;
}
+ case Icon.TYPE_URI:
+ shortcut.setIconUri(icon.getUriString());
+ shortcut.addFlags(ShortcutInfo.FLAG_HAS_ICON_URI);
+ return;
+ case Icon.TYPE_URI_ADAPTIVE_BITMAP:
+ shortcut.setIconUri(icon.getUriString());
+ shortcut.addFlags(ShortcutInfo.FLAG_HAS_ICON_URI
+ | ShortcutInfo.FLAG_ADAPTIVE_BITMAP);
+ return;
case Icon.TYPE_BITMAP:
bitmap = icon.getBitmap(); // Don't recycle in this case.
break;
@@ -3129,6 +3150,59 @@
}
@Override
+ public String getShortcutIconUri(int launcherUserId, @NonNull String launcherPackage,
+ @NonNull String packageName, @NonNull String shortcutId, int userId) {
+ Objects.requireNonNull(launcherPackage, "launcherPackage");
+ Objects.requireNonNull(packageName, "packageName");
+ Objects.requireNonNull(shortcutId, "shortcutId");
+
+ synchronized (mLock) {
+ throwIfUserLockedL(userId);
+ throwIfUserLockedL(launcherUserId);
+
+ getLauncherShortcutsLocked(launcherPackage, userId, launcherUserId)
+ .attemptToRestoreIfNeededAndSave();
+
+ final ShortcutPackage p = getUserShortcutsLocked(userId)
+ .getPackageShortcutsIfExists(packageName);
+ if (p == null) {
+ return null;
+ }
+
+ final ShortcutInfo shortcutInfo = p.findShortcutById(shortcutId);
+ if (shortcutInfo == null || !shortcutInfo.hasIconUri()) {
+ return null;
+ }
+ String uri = shortcutInfo.getIconUri();
+ if (uri == null) {
+ Slog.w(TAG, "null uri detected in getShortcutIconUri()");
+ return null;
+ }
+
+ final long token = Binder.clearCallingIdentity();
+ try {
+ int packageUid = mPackageManagerInternal.getPackageUidInternal(packageName,
+ PackageManager.MATCH_DIRECT_BOOT_AUTO, userId);
+ // Grant read uri permission to the caller on behalf of the shortcut owner. All
+ // granted permissions are revoked when the default launcher changes, or when
+ // device is rebooted.
+ // b/151572645 is tracking a bug where Uri permissions are persisted across
+ // reboots, even when Intent#FLAG_GRANT_PERSISTABLE_URI_PERMISSION is not used.
+ mUriGrantsManager.grantUriPermissionFromOwner(mUriPermissionOwner, packageUid,
+ launcherPackage, Uri.parse(uri), Intent.FLAG_GRANT_READ_URI_PERMISSION,
+ userId, launcherUserId);
+ } catch (Exception e) {
+ Slog.e(TAG, "Failed to grant uri access to " + launcherPackage + " for " + uri,
+ e);
+ uri = null;
+ } finally {
+ Binder.restoreCallingIdentity(token);
+ }
+ return uri;
+ }
+ }
+
+ @Override
public boolean hasShortcutHostPermission(int launcherUserId,
@NonNull String callingPackage, int callingPid, int callingUid) {
return ShortcutService.this.hasShortcutHostPermission(callingPackage, launcherUserId,
@@ -3241,7 +3315,14 @@
user.clearLauncher();
}
if (Intent.ACTION_PREFERRED_ACTIVITY_CHANGED.equals(action)) {
- // Nothing farther to do.
+ final ShortcutUser user = getUserShortcutsLocked(userId);
+ final ComponentName lastLauncher = user.getLastKnownLauncher();
+ final ComponentName currentLauncher = getDefaultLauncher(userId);
+ if (currentLauncher == null || !currentLauncher.equals(lastLauncher)) {
+ // Default launcher is removed or changed, revoke all URI permissions.
+ mUriGrantsManagerInternal.revokeUriPermissionFromOwner(mUriPermissionOwner,
+ null, ~0, 0);
+ }
return;
}
diff --git a/services/core/java/com/android/server/pm/UserManagerService.java b/services/core/java/com/android/server/pm/UserManagerService.java
index 1c2fcc1..8280a61 100644
--- a/services/core/java/com/android/server/pm/UserManagerService.java
+++ b/services/core/java/com/android/server/pm/UserManagerService.java
@@ -455,11 +455,13 @@
@Override
public void onFinished(int id, Bundle extras) {
- try {
- mContext.startIntentSender(mTarget, null, 0, 0, 0);
- } catch (IntentSender.SendIntentException e) {
- Slog.e(LOG_TAG, "Failed to start the target in the callback", e);
- }
+ mHandler.post(() -> {
+ try {
+ mContext.startIntentSender(mTarget, null, 0, 0, 0);
+ } catch (IntentSender.SendIntentException e) {
+ Slog.e(LOG_TAG, "Failed to start the target in the callback", e);
+ }
+ });
}
}
diff --git a/services/core/java/com/android/server/power/PowerManagerService.java b/services/core/java/com/android/server/power/PowerManagerService.java
index 294deba..3257b63 100644
--- a/services/core/java/com/android/server/power/PowerManagerService.java
+++ b/services/core/java/com/android/server/power/PowerManagerService.java
@@ -18,6 +18,8 @@
import static android.os.IServiceManager.DUMP_FLAG_PRIORITY_CRITICAL;
import static android.os.IServiceManager.DUMP_FLAG_PRIORITY_DEFAULT;
+import static android.os.PowerManagerInternal.MODE_DEVICE_IDLE;
+import static android.os.PowerManagerInternal.MODE_DISPLAY_INACTIVE;
import static android.os.PowerManagerInternal.WAKEFULNESS_ASLEEP;
import static android.os.PowerManagerInternal.WAKEFULNESS_AWAKE;
import static android.os.PowerManagerInternal.WAKEFULNESS_DOZING;
@@ -42,8 +44,6 @@
import android.hardware.display.AmbientDisplayConfiguration;
import android.hardware.display.DisplayManagerInternal;
import android.hardware.display.DisplayManagerInternal.DisplayPowerRequest;
-import android.hardware.power.Boost;
-import android.hardware.power.Mode;
import android.hardware.power.V1_0.PowerHint;
import android.net.Uri;
import android.os.BatteryManager;
@@ -2975,6 +2975,8 @@
synchronized (mLock) {
if (mDisplayState != state) {
mDisplayState = state;
+ setPowerModeInternal(MODE_DISPLAY_INACTIVE,
+ !Display.isActiveState(state));
if (state == Display.STATE_OFF) {
if (!mDecoupleHalInteractiveModeFromDisplayConfig) {
setHalInteractiveModeLocked(false);
@@ -3297,6 +3299,7 @@
}
mDeviceIdleMode = enabled;
updateWakeLockDisabledStatesLocked();
+ setPowerModeInternal(MODE_DEVICE_IDLE, mDeviceIdleMode || mLightDeviceIdleMode);
}
if (enabled) {
EventLogTags.writeDeviceIdleOnPhase("power");
@@ -3310,6 +3313,7 @@
synchronized (mLock) {
if (mLightDeviceIdleMode != enabled) {
mLightDeviceIdleMode = enabled;
+ setPowerModeInternal(MODE_DEVICE_IDLE, mDeviceIdleMode || mLightDeviceIdleMode);
return true;
}
return false;
diff --git a/services/core/java/com/android/server/textclassifier/TextClassificationManagerService.java b/services/core/java/com/android/server/textclassifier/TextClassificationManagerService.java
index 74a6383..0d16fcc 100644
--- a/services/core/java/com/android/server/textclassifier/TextClassificationManagerService.java
+++ b/services/core/java/com/android/server/textclassifier/TextClassificationManagerService.java
@@ -234,7 +234,7 @@
handleRequest(
event.getSystemTextClassifierMetadata(),
- /* verifyCallingPackage= */ false,
+ /* verifyCallingPackage= */ true,
/* attemptToBind= */ false,
service -> service.onSelectionEvent(sessionId, event),
"onSelectionEvent",
@@ -253,7 +253,7 @@
handleRequest(
systemTcMetadata,
- /* verifyCallingPackage= */ false,
+ /* verifyCallingPackage= */ true,
/* attemptToBind= */ false,
service -> service.onTextClassifierEvent(sessionId, event),
"onTextClassifierEvent",
diff --git a/services/core/java/com/android/server/tv/tunerresourcemanager/TunerResourceManagerService.java b/services/core/java/com/android/server/tv/tunerresourcemanager/TunerResourceManagerService.java
index bd63b2d..25585b3 100644
--- a/services/core/java/com/android/server/tv/tunerresourcemanager/TunerResourceManagerService.java
+++ b/services/core/java/com/android/server/tv/tunerresourcemanager/TunerResourceManagerService.java
@@ -16,7 +16,6 @@
package com.android.server.tv.tunerresourcemanager;
-import android.annotation.IntDef;
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.content.Context;
@@ -41,8 +40,6 @@
import com.android.internal.annotations.VisibleForTesting;
import com.android.server.SystemService;
-import java.lang.annotation.Retention;
-import java.lang.annotation.RetentionPolicy;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
@@ -79,25 +76,6 @@
// Used to synchronize the access to the service.
private final Object mLock = new Object();
- /**
- * Tuner resource type to help generate resource handle
- */
- @IntDef({
- TUNER_RESOURCE_TYPE_FRONTEND,
- TUNER_RESOURCE_TYPE_DEMUX,
- TUNER_RESOURCE_TYPE_DESCRAMBLER,
- TUNER_RESOURCE_TYPE_LNB,
- TUNER_RESOURCE_TYPE_CAS_SESSION,
- })
- @Retention(RetentionPolicy.SOURCE)
- public @interface TunerResourceType {}
-
- public static final int TUNER_RESOURCE_TYPE_FRONTEND = 0;
- public static final int TUNER_RESOURCE_TYPE_DEMUX = 1;
- public static final int TUNER_RESOURCE_TYPE_DESCRAMBLER = 2;
- public static final int TUNER_RESOURCE_TYPE_LNB = 3;
- public static final int TUNER_RESOURCE_TYPE_CAS_SESSION = 4;
-
public TunerResourceManagerService(@Nullable Context context) {
super(context);
}
@@ -465,7 +443,7 @@
// Grant frontend when there is unused resource.
if (grantingFrontendId > -1) {
frontendHandle[0] = generateResourceHandle(
- TUNER_RESOURCE_TYPE_FRONTEND, grantingFrontendId);
+ TunerResourceManager.TUNER_RESOURCE_TYPE_FRONTEND, grantingFrontendId);
updateFrontendClientMappingOnNewGrant(grantingFrontendId, request.getClientId());
return true;
}
@@ -474,7 +452,7 @@
// request client has higher priority.
if (inUseLowestPriorityFrId > -1 && (requestClient.getPriority() > currentLowestPriority)) {
frontendHandle[0] = generateResourceHandle(
- TUNER_RESOURCE_TYPE_FRONTEND, inUseLowestPriorityFrId);
+ TunerResourceManager.TUNER_RESOURCE_TYPE_FRONTEND, inUseLowestPriorityFrId);
reclaimFrontendResource(getFrontendResource(
inUseLowestPriorityFrId).getOwnerClientId());
updateFrontendClientMappingOnNewGrant(inUseLowestPriorityFrId, request.getClientId());
@@ -489,7 +467,7 @@
if (DEBUG) {
Slog.d(TAG, "requestDemux(request=" + request + ")");
}
- demuxHandle[0] = generateResourceHandle(TUNER_RESOURCE_TYPE_DEMUX, 0);
+ demuxHandle[0] = generateResourceHandle(TunerResourceManager.TUNER_RESOURCE_TYPE_DEMUX, 0);
return true;
}
@@ -498,7 +476,8 @@
if (DEBUG) {
Slog.d(TAG, "requestDescrambler(request=" + request + ")");
}
- descramblerHandle[0] = generateResourceHandle(TUNER_RESOURCE_TYPE_DESCRAMBLER, 0);
+ descramblerHandle[0] =
+ generateResourceHandle(TunerResourceManager.TUNER_RESOURCE_TYPE_DESCRAMBLER, 0);
return true;
}
@@ -664,7 +643,8 @@
return mClientProfiles.keySet().contains(clientId);
}
- private int generateResourceHandle(@TunerResourceType int resourceType, int resourceId) {
+ private int generateResourceHandle(
+ @TunerResourceManager.TunerResourceType int resourceType, int resourceId) {
return (resourceType & 0x000000ff) << 24
| (resourceId << 16)
| (mResourceRequestCount++ & 0xffff);
diff --git a/services/core/java/com/android/server/wm/DisplayPolicy.java b/services/core/java/com/android/server/wm/DisplayPolicy.java
index ab96c61..38a406e 100644
--- a/services/core/java/com/android/server/wm/DisplayPolicy.java
+++ b/services/core/java/com/android/server/wm/DisplayPolicy.java
@@ -28,6 +28,7 @@
import static android.view.InsetsState.ITYPE_BOTTOM_DISPLAY_CUTOUT;
import static android.view.InsetsState.ITYPE_BOTTOM_GESTURES;
import static android.view.InsetsState.ITYPE_BOTTOM_TAPPABLE_ELEMENT;
+import static android.view.InsetsState.ITYPE_CAPTION_BAR;
import static android.view.InsetsState.ITYPE_IME;
import static android.view.InsetsState.ITYPE_LEFT_DISPLAY_CUTOUT;
import static android.view.InsetsState.ITYPE_LEFT_GESTURES;
@@ -1024,6 +1025,13 @@
case TYPE_STATUS_BAR_PANEL:
return WindowManagerGlobal.ADD_INVALID_TYPE;
}
+
+ if (attrs.providesInsetsTypes != null) {
+ mContext.enforcePermission(
+ android.Manifest.permission.STATUS_BAR_SERVICE, callingPid, callingUid,
+ "DisplayPolicy");
+ enforceSingleInsetsTypeCorrespondingToWindowType(attrs.providesInsetsTypes);
+ }
return ADD_OKAY;
}
@@ -1110,6 +1118,28 @@
});
if (DEBUG_LAYOUT) Slog.i(TAG, "NAVIGATION BAR: " + mNavigationBar);
break;
+ default:
+ if (attrs.providesInsetsTypes != null) {
+ for (int insetsType : attrs.providesInsetsTypes) {
+ mDisplayContent.setInsetProvider(insetsType, win, null);
+ }
+ }
+ break;
+ }
+ }
+
+ private static void enforceSingleInsetsTypeCorrespondingToWindowType(int[] insetsTypes) {
+ int count = 0;
+ for (int insetsType : insetsTypes) {
+ switch (insetsType) {
+ case ITYPE_NAVIGATION_BAR:
+ case ITYPE_STATUS_BAR:
+ case ITYPE_CAPTION_BAR:
+ if (++count > 1) {
+ throw new IllegalArgumentException(
+ "Multiple InsetsTypes corresponding to Window type");
+ }
+ }
}
}
diff --git a/services/core/java/com/android/server/wm/SurfaceAnimator.java b/services/core/java/com/android/server/wm/SurfaceAnimator.java
index 19f8ca9..aa817fd 100644
--- a/services/core/java/com/android/server/wm/SurfaceAnimator.java
+++ b/services/core/java/com/android/server/wm/SurfaceAnimator.java
@@ -36,6 +36,7 @@
import java.io.PrintWriter;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
+import java.util.function.Supplier;
/**
* A class that can run animations on objects that have a set of child surfaces. We do this by
@@ -145,7 +146,7 @@
if (mLeash == null) {
mLeash = createAnimationLeash(mAnimatable, surface, t, type,
mAnimatable.getSurfaceWidth(), mAnimatable.getSurfaceHeight(), 0 /* x */,
- 0 /* y */, hidden);
+ 0 /* y */, hidden, mService.mTransactionFactory);
mAnimatable.onAnimationLeashCreated(t, mLeash);
}
mAnimatable.onLeashAnimationStarting(t, mLeash);
@@ -374,13 +375,21 @@
static SurfaceControl createAnimationLeash(Animatable animatable, SurfaceControl surface,
Transaction t, @AnimationType int type, int width, int height, int x, int y,
- boolean hidden) {
+ boolean hidden, Supplier<Transaction> transactionFactory) {
if (DEBUG_ANIM) Slog.i(TAG, "Reparenting to leash");
final SurfaceControl.Builder builder = animatable.makeAnimationLeash()
.setParent(animatable.getAnimationLeashParent())
- .setHidden(hidden)
.setName(surface + " - animation-leash");
final SurfaceControl leash = builder.build();
+ if (!hidden) {
+ // TODO(b/151665759) Defer reparent calls
+ // We want the leash to be visible immediately but we want to set the effects on
+ // the layer. Since the transaction used in this function may be deferred, we apply
+ // another transaction immediately with the correct visibility and effects.
+ // If this doesn't work, you will can see the 2/3 button nav bar flicker during
+ // seamless rotation.
+ transactionFactory.get().unsetColor(leash).show(leash).apply();
+ }
t.setWindowCrop(leash, width, height);
t.setPosition(leash, x, y);
t.show(leash);
diff --git a/services/core/java/com/android/server/wm/SurfaceFreezer.java b/services/core/java/com/android/server/wm/SurfaceFreezer.java
index a696daf..8ab5043 100644
--- a/services/core/java/com/android/server/wm/SurfaceFreezer.java
+++ b/services/core/java/com/android/server/wm/SurfaceFreezer.java
@@ -75,7 +75,8 @@
mLeash = SurfaceAnimator.createAnimationLeash(mAnimatable, mAnimatable.getSurfaceControl(),
t, ANIMATION_TYPE_SCREEN_ROTATION, startBounds.width(), startBounds.height(),
- startBounds.left, startBounds.top, false /* hidden */);
+ startBounds.left, startBounds.top, false /* hidden */,
+ mWmService.mTransactionFactory);
mAnimatable.onAnimationLeashCreated(t, mLeash);
SurfaceControl freezeTarget = mAnimatable.getFreezeSnapshotTarget();
diff --git a/services/core/java/com/android/server/wm/TaskSnapshotController.java b/services/core/java/com/android/server/wm/TaskSnapshotController.java
index f83b052..0f5cafe 100644
--- a/services/core/java/com/android/server/wm/TaskSnapshotController.java
+++ b/services/core/java/com/android/server/wm/TaskSnapshotController.java
@@ -352,9 +352,19 @@
}
task.getBounds(mTmpRect);
mTmpRect.offsetTo(0, 0);
+
+ SurfaceControl[] excludeLayers;
+ final WindowState imeWindow = task.getDisplayContent().mInputMethodWindow;
+ if (imeWindow != null) {
+ excludeLayers = new SurfaceControl[1];
+ excludeLayers[0] = imeWindow.getSurfaceControl();
+ } else {
+ excludeLayers = new SurfaceControl[0];
+ }
final SurfaceControl.ScreenshotGraphicBuffer screenshotBuffer =
- SurfaceControl.captureLayers(
- task.getSurfaceControl(), mTmpRect, scaleFraction, pixelFormat);
+ SurfaceControl.captureLayersExcluding(
+ task.getSurfaceControl(), mTmpRect, scaleFraction,
+ pixelFormat, excludeLayers);
if (outTaskSize != null) {
outTaskSize.x = mTmpRect.width();
outTaskSize.y = mTmpRect.height();
diff --git a/services/core/java/com/android/server/wm/WindowManagerService.java b/services/core/java/com/android/server/wm/WindowManagerService.java
index 1a77807..7400d17 100644
--- a/services/core/java/com/android/server/wm/WindowManagerService.java
+++ b/services/core/java/com/android/server/wm/WindowManagerService.java
@@ -186,7 +186,6 @@
import android.os.Trace;
import android.os.UserHandle;
import android.os.WorkSource;
-import android.provider.DeviceConfig;
import android.provider.Settings;
import android.service.vr.IVrManager;
import android.service.vr.IVrStateCallbacks;
@@ -1162,9 +1161,7 @@
mAnimator = new WindowAnimator(this);
mRoot = new RootWindowContainer(this);
- mUseBLAST = DeviceConfig.getBoolean(
- DeviceConfig.NAMESPACE_WINDOW_MANAGER_NATIVE_BOOT,
- WM_USE_BLAST_ADAPTER_FLAG, false);
+ mUseBLAST = true;
mWindowPlacerLocked = new WindowSurfacePlacer(this);
mTaskSnapshotController = new TaskSnapshotController(this);
diff --git a/services/incremental/IncrementalService.cpp b/services/incremental/IncrementalService.cpp
index 7275936..4da0091 100644
--- a/services/incremental/IncrementalService.cpp
+++ b/services/incremental/IncrementalService.cpp
@@ -1090,7 +1090,9 @@
base::unique_fd(::dup(ifs.control.pendingReads)));
fsControlParcel.incremental->log.reset(base::unique_fd(::dup(ifs.control.logs)));
sp<IncrementalDataLoaderListener> listener =
- new IncrementalDataLoaderListener(*this, *externalListener);
+ new IncrementalDataLoaderListener(*this,
+ externalListener ? *externalListener
+ : DataLoaderStatusListener());
bool created = false;
auto status = mDataLoaderManager->initializeDataLoader(ifs.mountId, *dlp, fsControlParcel,
listener, &created);
@@ -1230,8 +1232,8 @@
std::unique_lock l(incrementalService.mLock);
const auto& ifs = incrementalService.getIfsLocked(mountId);
if (!ifs) {
- LOG(WARNING) << "Received data loader status " << int(newStatus) << " for unknown mount "
- << mountId;
+ LOG(WARNING) << "Received data loader status " << int(newStatus)
+ << " for unknown mount " << mountId;
return binder::Status::ok();
}
ifs->dataLoaderStatus = newStatus;
diff --git a/services/tests/servicestests/src/com/android/server/locksettings/FakeSettings.java b/services/tests/servicestests/src/com/android/server/locksettings/FakeSettings.java
index 70a927c..c5e924b 100644
--- a/services/tests/servicestests/src/com/android/server/locksettings/FakeSettings.java
+++ b/services/tests/servicestests/src/com/android/server/locksettings/FakeSettings.java
@@ -15,16 +15,23 @@
*/
package com.android.server.locksettings;
+import android.content.ContentResolver;
+import android.os.UserHandle;
import android.provider.Settings;
public class FakeSettings {
private int mDeviceProvisioned;
+ private int mSecureFrpMode;
public void setDeviceProvisioned(boolean provisioned) {
mDeviceProvisioned = provisioned ? 1 : 0;
}
+ public void setSecureFrpMode(boolean secure) {
+ mSecureFrpMode = secure ? 1 : 0;
+ }
+
public int globalGetInt(String keyName) {
switch (keyName) {
case Settings.Global.DEVICE_PROVISIONED:
@@ -33,4 +40,12 @@
throw new IllegalArgumentException("Unhandled global settings: " + keyName);
}
}
+
+ public int secureGetInt(ContentResolver contentResolver, String keyName, int defaultValue,
+ int userId) {
+ if (Settings.Secure.SECURE_FRP_MODE.equals(keyName) && userId == UserHandle.USER_SYSTEM) {
+ return mSecureFrpMode;
+ }
+ return defaultValue;
+ }
}
diff --git a/services/tests/servicestests/src/com/android/server/locksettings/LockSettingsServiceTestable.java b/services/tests/servicestests/src/com/android/server/locksettings/LockSettingsServiceTestable.java
index 1ff451b..4e1454b 100644
--- a/services/tests/servicestests/src/com/android/server/locksettings/LockSettingsServiceTestable.java
+++ b/services/tests/servicestests/src/com/android/server/locksettings/LockSettingsServiceTestable.java
@@ -124,6 +124,12 @@
}
@Override
+ public int settingsSecureGetInt(ContentResolver contentResolver, String keyName,
+ int defaultValue, int userId) {
+ return mSettings.secureGetInt(contentResolver, keyName, defaultValue, userId);
+ }
+
+ @Override
public UserManagerInternal getUserManagerInternal() {
return mUserManagerInternal;
}
diff --git a/services/tests/servicestests/src/com/android/server/locksettings/LockSettingsServiceTests.java b/services/tests/servicestests/src/com/android/server/locksettings/LockSettingsServiceTests.java
index 684bbd4..661ce11 100644
--- a/services/tests/servicestests/src/com/android/server/locksettings/LockSettingsServiceTests.java
+++ b/services/tests/servicestests/src/com/android/server/locksettings/LockSettingsServiceTests.java
@@ -416,6 +416,15 @@
eq(CREDENTIAL_TYPE_PASSWORD), any(), eq(MANAGED_PROFILE_USER_ID));
}
+ @Test
+ public void testCredentialChangeNotPossibleInSecureFrpMode() {
+ mSettings.setSecureFrpMode(true);
+ try {
+ mService.setLockCredential(newPassword("1234"), nonePassword(), PRIMARY_USER_ID);
+ fail("Password shouldn't be changeable before FRP unlock");
+ } catch (SecurityException e) { }
+ }
+
private void testCreateCredential(int userId, LockscreenCredential credential)
throws RemoteException {
assertTrue(mService.setLockCredential(credential, nonePassword(), userId));
diff --git a/services/tests/servicestests/src/com/android/server/net/NetworkPolicyManagerServiceTest.java b/services/tests/servicestests/src/com/android/server/net/NetworkPolicyManagerServiceTest.java
index 7e3cfc8..128177b 100644
--- a/services/tests/servicestests/src/com/android/server/net/NetworkPolicyManagerServiceTest.java
+++ b/services/tests/servicestests/src/com/android/server/net/NetworkPolicyManagerServiceTest.java
@@ -1084,7 +1084,7 @@
// pretend that 512 bytes total have happened
stats = new NetworkStats(getElapsedRealtime(), 1)
- .addIfaceValues(TEST_IFACE, 256L, 2L, 256L, 2L);
+ .insertEntry(TEST_IFACE, 256L, 2L, 256L, 2L);
when(mStatsService.getNetworkTotalBytes(sTemplateWifi, CYCLE_START, CYCLE_END))
.thenReturn(stats.getTotalBytes());
@@ -1276,11 +1276,11 @@
history.recordData(start, end,
new NetworkStats.Entry(DataUnit.MEGABYTES.toBytes(1440), 0L, 0L, 0L, 0));
stats.clear();
- stats.addEntry(IFACE_ALL, UID_A, SET_ALL, TAG_ALL,
+ stats.insertEntry(IFACE_ALL, UID_A, SET_ALL, TAG_ALL,
DataUnit.MEGABYTES.toBytes(480), 0, 0, 0, 0);
- stats.addEntry(IFACE_ALL, UID_B, SET_ALL, TAG_ALL,
+ stats.insertEntry(IFACE_ALL, UID_B, SET_ALL, TAG_ALL,
DataUnit.MEGABYTES.toBytes(480), 0, 0, 0, 0);
- stats.addEntry(IFACE_ALL, UID_C, SET_ALL, TAG_ALL,
+ stats.insertEntry(IFACE_ALL, UID_C, SET_ALL, TAG_ALL,
DataUnit.MEGABYTES.toBytes(480), 0, 0, 0, 0);
reset(mNotifManager);
@@ -1304,9 +1304,9 @@
history.recordData(start, end,
new NetworkStats.Entry(DataUnit.MEGABYTES.toBytes(1440), 0L, 0L, 0L, 0));
stats.clear();
- stats.addEntry(IFACE_ALL, UID_A, SET_ALL, TAG_ALL,
+ stats.insertEntry(IFACE_ALL, UID_A, SET_ALL, TAG_ALL,
DataUnit.MEGABYTES.toBytes(960), 0, 0, 0, 0);
- stats.addEntry(IFACE_ALL, UID_B, SET_ALL, TAG_ALL,
+ stats.insertEntry(IFACE_ALL, UID_B, SET_ALL, TAG_ALL,
DataUnit.MEGABYTES.toBytes(480), 0, 0, 0, 0);
reset(mNotifManager);
@@ -1338,7 +1338,7 @@
// bring up wifi network with metered policy
state = new NetworkState[] { buildWifi() };
stats = new NetworkStats(getElapsedRealtime(), 1)
- .addIfaceValues(TEST_IFACE, 0L, 0L, 0L, 0L);
+ .insertEntry(TEST_IFACE, 0L, 0L, 0L, 0L);
{
when(mConnManager.getAllNetworkState()).thenReturn(state);
@@ -1769,7 +1769,7 @@
final int CYCLE_DAY = 15;
final NetworkStats stats = new NetworkStats(0L, 1);
- stats.addEntry(TEST_IFACE, UID_A, SET_ALL, TAG_NONE,
+ stats.insertEntry(TEST_IFACE, UID_A, SET_ALL, TAG_NONE,
2999, 1, 2000, 1, 0);
when(mStatsService.getNetworkTotalBytes(any(), anyLong(), anyLong()))
.thenReturn(stats.getTotalBytes());
@@ -1793,7 +1793,7 @@
reset(mStatsService);
// Increase the usage.
- stats.addEntry(TEST_IFACE, UID_A, SET_ALL, TAG_NONE,
+ stats.insertEntry(TEST_IFACE, UID_A, SET_ALL, TAG_NONE,
1000, 1, 999, 1, 0);
when(mStatsService.getNetworkTotalBytes(any(), anyLong(), anyLong()))
.thenReturn(stats.getTotalBytes());
diff --git a/services/tests/servicestests/src/com/android/server/pm/BaseShortcutManagerTest.java b/services/tests/servicestests/src/com/android/server/pm/BaseShortcutManagerTest.java
index 6c769485..6a88298 100644
--- a/services/tests/servicestests/src/com/android/server/pm/BaseShortcutManagerTest.java
+++ b/services/tests/servicestests/src/com/android/server/pm/BaseShortcutManagerTest.java
@@ -94,6 +94,8 @@
import com.android.server.SystemService;
import com.android.server.pm.LauncherAppsService.LauncherAppsImpl;
import com.android.server.pm.ShortcutUser.PackageWithUser;
+import com.android.server.uri.UriGrantsManagerInternal;
+import com.android.server.uri.UriPermissionOwner;
import com.android.server.wm.ActivityTaskManagerInternal;
import org.junit.Assert;
@@ -630,6 +632,9 @@
protected UsageStatsManagerInternal mMockUsageStatsManagerInternal;
protected ActivityManagerInternal mMockActivityManagerInternal;
protected ActivityTaskManagerInternal mMockActivityTaskManagerInternal;
+ protected UriGrantsManagerInternal mMockUriGrantsManagerInternal;
+
+ protected UriPermissionOwner mUriPermissionOwner;
protected static final String CALLING_PACKAGE_1 = "com.android.test.1";
protected static final int CALLING_UID_1 = 10001;
@@ -771,6 +776,7 @@
mMockUsageStatsManagerInternal = mock(UsageStatsManagerInternal.class);
mMockActivityManagerInternal = mock(ActivityManagerInternal.class);
mMockActivityTaskManagerInternal = mock(ActivityTaskManagerInternal.class);
+ mMockUriGrantsManagerInternal = mock(UriGrantsManagerInternal.class);
LocalServices.removeServiceForTest(PackageManagerInternal.class);
LocalServices.addService(PackageManagerInternal.class, mMockPackageManagerInternal);
@@ -782,6 +788,10 @@
LocalServices.addService(ActivityTaskManagerInternal.class, mMockActivityTaskManagerInternal);
LocalServices.removeServiceForTest(UserManagerInternal.class);
LocalServices.addService(UserManagerInternal.class, mMockUserManagerInternal);
+ LocalServices.removeServiceForTest(UriGrantsManagerInternal.class);
+ LocalServices.addService(UriGrantsManagerInternal.class, mMockUriGrantsManagerInternal);
+
+ mUriPermissionOwner = new UriPermissionOwner(mMockUriGrantsManagerInternal, TAG);
// Prepare injection values.
@@ -2193,6 +2203,7 @@
for (ShortcutInfo s : actualShortcuts) {
assertTrue("ID " + s.getId() + " not have icon res ID", s.hasIconResource());
assertFalse("ID " + s.getId() + " shouldn't have icon FD", s.hasIconFile());
+ assertFalse("ID " + s.getId() + " shouldn't have icon URI", s.hasIconUri());
}
return actualShortcuts;
}
@@ -2202,6 +2213,17 @@
for (ShortcutInfo s : actualShortcuts) {
assertFalse("ID " + s.getId() + " shouldn't have icon res ID", s.hasIconResource());
assertTrue("ID " + s.getId() + " not have icon FD", s.hasIconFile());
+ assertFalse("ID " + s.getId() + " shouldn't have icon URI", s.hasIconUri());
+ }
+ return actualShortcuts;
+ }
+
+ public static List<ShortcutInfo> assertAllHaveIconUri(
+ List<ShortcutInfo> actualShortcuts) {
+ for (ShortcutInfo s : actualShortcuts) {
+ assertFalse("ID " + s.getId() + " shouldn't have icon res ID", s.hasIconResource());
+ assertFalse("ID " + s.getId() + " shouldn't have have icon FD", s.hasIconFile());
+ assertTrue("ID " + s.getId() + " not have icon URI", s.hasIconUri());
}
return actualShortcuts;
}
diff --git a/services/tests/servicestests/src/com/android/server/pm/ShortcutManagerTest1.java b/services/tests/servicestests/src/com/android/server/pm/ShortcutManagerTest1.java
index 56460fb..2cbb6d5 100644
--- a/services/tests/servicestests/src/com/android/server/pm/ShortcutManagerTest1.java
+++ b/services/tests/servicestests/src/com/android/server/pm/ShortcutManagerTest1.java
@@ -114,8 +114,11 @@
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.File;
+import java.io.FileOutputStream;
import java.io.IOException;
+import java.io.InputStream;
import java.io.InputStreamReader;
+import java.io.OutputStream;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.List;
@@ -133,6 +136,16 @@
*/
@SmallTest
public class ShortcutManagerTest1 extends BaseShortcutManagerTest {
+
+ @Override
+ protected void tearDown() throws Exception {
+ deleteUriFile("file32x32.jpg");
+ deleteUriFile("file64x64.jpg");
+ deleteUriFile("file512x512.jpg");
+
+ super.tearDown();
+ }
+
/**
* Test for the first launch path, no settings file available.
*/
@@ -724,6 +737,17 @@
final Icon bmp512x512 = Icon.createWithBitmap(BitmapFactory.decodeResource(
getTestContext().getResources(), R.drawable.black_512x512));
+ // The corresponding files will be deleted in tearDown()
+ final Icon uri32x32 = Icon.createWithContentUri(
+ getFileUriFromResource("file32x32.jpg", R.drawable.black_32x32));
+ final Icon uri64x64_maskable = Icon.createWithAdaptiveBitmapContentUri(
+ getFileUriFromResource("file64x64.jpg", R.drawable.black_64x64));
+ final Icon uri512x512 = Icon.createWithContentUri(
+ getFileUriFromResource("file512x512.jpg", R.drawable.black_512x512));
+
+ doReturn(mUriPermissionOwner.getExternalToken())
+ .when(mMockUriGrantsManagerInternal).newUriPermissionOwner(anyString());
+
// Set from package 1
setCaller(CALLING_PACKAGE_1);
assertTrue(mManager.setDynamicShortcuts(list(
@@ -732,6 +756,9 @@
makeShortcutWithIcon("bmp32x32", bmp32x32),
makeShortcutWithIcon("bmp64x64", bmp64x64_maskable),
makeShortcutWithIcon("bmp512x512", bmp512x512),
+ makeShortcutWithIcon("uri32x32", uri32x32),
+ makeShortcutWithIcon("uri64x64", uri64x64_maskable),
+ makeShortcutWithIcon("uri512x512", uri512x512),
makeShortcut("none")
)));
@@ -742,6 +769,9 @@
"bmp32x32",
"bmp64x64",
"bmp512x512",
+ "uri32x32",
+ "uri64x64",
+ "uri512x512",
"none");
// Call from another caller with the same ID, just to make sure storage is per-package.
@@ -749,11 +779,15 @@
assertTrue(mManager.setDynamicShortcuts(list(
makeShortcutWithIcon("res32x32", res512x512),
makeShortcutWithIcon("res64x64", res512x512),
+ makeShortcutWithIcon("uri32x32", uri512x512),
+ makeShortcutWithIcon("uri64x64", uri512x512),
makeShortcutWithIcon("none", res512x512)
)));
assertShortcutIds(assertAllNotHaveIcon(mManager.getDynamicShortcuts()),
"res32x32",
"res64x64",
+ "uri32x32",
+ "uri64x64",
"none");
// Different profile. Note the names and the contents don't match.
@@ -795,6 +829,18 @@
list(getShortcutInfoAsLauncher(CALLING_PACKAGE_1, "bmp512x512", USER_0))),
"bmp512x512");
+ assertShortcutIds(assertAllHaveIconUri(
+ list(getShortcutInfoAsLauncher(CALLING_PACKAGE_1, "uri32x32", USER_0))),
+ "uri32x32");
+
+ assertShortcutIds(assertAllHaveIconUri(
+ list(getShortcutInfoAsLauncher(CALLING_PACKAGE_1, "uri64x64", USER_0))),
+ "uri64x64");
+
+ assertShortcutIds(assertAllHaveIconUri(
+ list(getShortcutInfoAsLauncher(CALLING_PACKAGE_1, "uri512x512", USER_0))),
+ "uri512x512");
+
assertShortcutIds(assertAllHaveIconResId(
list(getShortcutInfoAsLauncher(CALLING_PACKAGE_1, "res32x32", USER_P0))),
"res32x32");
@@ -860,15 +906,37 @@
bmp = pfdToBitmap(
mLauncherApps.getShortcutIconFd(CALLING_PACKAGE_1, "bmp32x32", HANDLE_USER_P0));
assertBitmapSize(128, 128, bmp);
+/*
+ bmp = pfdToBitmap(mLauncherApps.getUriShortcutIconFd(
+ getShortcutInfoAsLauncher(CALLING_PACKAGE_1, "uri32x32", USER_0)));
+ assertBitmapSize(32, 32, bmp);
- Drawable dr = mLauncherApps.getShortcutIconDrawable(
+ bmp = pfdToBitmap(mLauncherApps.getUriShortcutIconFd(
+ getShortcutInfoAsLauncher(CALLING_PACKAGE_1, "uri64x64", USER_0)));
+ assertBitmapSize(64, 64, bmp);
+
+ bmp = pfdToBitmap(mLauncherApps.getUriShortcutIconFd(
+ getShortcutInfoAsLauncher(CALLING_PACKAGE_1, "uri512x512", USER_0)));
+ assertBitmapSize(512, 512, bmp);
+*/
+
+ Drawable dr_bmp = mLauncherApps.getShortcutIconDrawable(
makeShortcutWithIcon("bmp64x64", bmp64x64_maskable), 0);
- assertTrue(dr instanceof AdaptiveIconDrawable);
+ assertTrue(dr_bmp instanceof AdaptiveIconDrawable);
float viewportPercentage = 1 / (1 + 2 * AdaptiveIconDrawable.getExtraInsetFraction());
assertEquals((int) (bmp64x64_maskable.getBitmap().getWidth() * viewportPercentage),
- dr.getIntrinsicWidth());
+ dr_bmp.getIntrinsicWidth());
assertEquals((int) (bmp64x64_maskable.getBitmap().getHeight() * viewportPercentage),
- dr.getIntrinsicHeight());
+ dr_bmp.getIntrinsicHeight());
+/*
+ Drawable dr_uri = mLauncherApps.getShortcutIconDrawable(
+ makeShortcutWithIcon("uri64x64", uri64x64_maskable), 0);
+ assertTrue(dr_uri instanceof AdaptiveIconDrawable);
+ assertEquals((int) (bmp64x64_maskable.getBitmap().getWidth() * viewportPercentage),
+ dr_uri.getIntrinsicWidth());
+ assertEquals((int) (bmp64x64_maskable.getBitmap().getHeight() * viewportPercentage),
+ dr_uri.getIntrinsicHeight());
+*/
}
public void testCleanupDanglingBitmaps() throws Exception {
@@ -1274,6 +1342,18 @@
makeShortcut("s1")
)));
+ // Set uri icon
+ assertTrue(mManager.updateShortcuts(list(
+ new ShortcutInfo.Builder(mClientContext, "s1")
+ .setIcon(Icon.createWithContentUri("test_uri"))
+ .build()
+ )));
+ mService.waitForBitmapSavesForTest();
+ assertWith(getCallerShortcuts())
+ .forShortcutWithId("s1", si -> {
+ assertTrue(si.hasIconUri());
+ assertEquals("test_uri", si.getIconUri());
+ });
// Set resource icon
assertTrue(mManager.updateShortcuts(list(
new ShortcutInfo.Builder(mClientContext, "s1")
@@ -1287,6 +1367,9 @@
assertEquals(R.drawable.black_32x32, si.getIconResourceId());
});
mService.waitForBitmapSavesForTest();
+
+ mInjectedCurrentTimeMillis += INTERVAL; // reset throttling
+
// Set bitmap icon
assertTrue(mManager.updateShortcuts(list(
new ShortcutInfo.Builder(mClientContext, "s1")
@@ -1300,9 +1383,7 @@
assertTrue(si.hasIconFile());
});
- mInjectedCurrentTimeMillis += INTERVAL; // reset throttling
-
- // Do it again, with the reverse order (bitmap -> icon)
+ // Do it again, with the reverse order (bitmap -> resource -> uri)
assertTrue(mManager.setDynamicShortcuts(list(
makeShortcut("s1")
)));
@@ -1320,6 +1401,8 @@
assertTrue(si.hasIconFile());
});
+ mInjectedCurrentTimeMillis += INTERVAL; // reset throttling
+
// Set resource icon
assertTrue(mManager.updateShortcuts(list(
new ShortcutInfo.Builder(mClientContext, "s1")
@@ -1332,6 +1415,18 @@
assertTrue(si.hasIconResource());
assertEquals(R.drawable.black_32x32, si.getIconResourceId());
});
+ // Set uri icon
+ assertTrue(mManager.updateShortcuts(list(
+ new ShortcutInfo.Builder(mClientContext, "s1")
+ .setIcon(Icon.createWithContentUri("test_uri"))
+ .build()
+ )));
+ mService.waitForBitmapSavesForTest();
+ assertWith(getCallerShortcuts())
+ .forShortcutWithId("s1", si -> {
+ assertTrue(si.hasIconUri());
+ assertEquals("test_uri", si.getIconUri());
+ });
});
}
@@ -8499,4 +8594,26 @@
}
}
}
+
+ private Uri getFileUriFromResource(String fileName, int resId) throws IOException {
+ File file = new File(getTestContext().getFilesDir(), fileName);
+ // Make sure we are not leaving phantom files behind.
+ assertFalse(file.exists());
+ try (InputStream source = getTestContext().getResources().openRawResource(resId);
+ OutputStream target = new FileOutputStream(file)) {
+ byte[] buffer = new byte[1024];
+ for (int len = source.read(buffer); len >= 0; len = source.read(buffer)) {
+ target.write(buffer, 0, len);
+ }
+ }
+ assertTrue(file.exists());
+ return Uri.fromFile(file);
+ }
+
+ private void deleteUriFile(String fileName) {
+ File file = new File(getTestContext().getFilesDir(), fileName);
+ if (file.exists()) {
+ file.delete();
+ }
+ }
}
diff --git a/services/tests/servicestests/src/com/android/server/pm/ShortcutManagerTest2.java b/services/tests/servicestests/src/com/android/server/pm/ShortcutManagerTest2.java
index 7b101c7..ca77049 100644
--- a/services/tests/servicestests/src/com/android/server/pm/ShortcutManagerTest2.java
+++ b/services/tests/servicestests/src/com/android/server/pm/ShortcutManagerTest2.java
@@ -257,6 +257,7 @@
si.addFlags(ShortcutInfo.FLAG_PINNED);
si.setBitmapPath("abc");
si.setIconResourceId(456);
+ si.setIconUri("test_uri");
si = parceled(si);
@@ -279,6 +280,7 @@
assertEquals(ShortcutInfo.FLAG_PINNED | ShortcutInfo.FLAG_LONG_LIVED, si.getFlags());
assertEquals("abc", si.getBitmapPath());
assertEquals(456, si.getIconResourceId());
+ assertEquals("test_uri", si.getIconUri());
assertEquals(0, si.getTitleResId());
assertEquals(null, si.getTitleResName());
@@ -310,6 +312,7 @@
si.addFlags(ShortcutInfo.FLAG_PINNED);
si.setBitmapPath("abc");
si.setIconResourceId(456);
+ si.setIconUri("test_uri");
lookupAndFillInResourceNames(si);
@@ -335,6 +338,7 @@
assertEquals("abc", si.getBitmapPath());
assertEquals(456, si.getIconResourceId());
assertEquals("string/r456", si.getIconResName());
+ assertEquals("test_uri", si.getIconUri());
}
public void testShortcutInfoClone() {
@@ -359,6 +363,7 @@
sorig.addFlags(ShortcutInfo.FLAG_PINNED);
sorig.setBitmapPath("abc");
sorig.setIconResourceId(456);
+ sorig.setIconUri("test_uri");
lookupAndFillInResourceNames(sorig);
@@ -386,6 +391,7 @@
assertEquals("abc", si.getBitmapPath());
assertEquals(456, si.getIconResourceId());
assertEquals("string/r456", si.getIconResName());
+ assertEquals("test_uri", si.getIconUri());
si = sorig.clone(ShortcutInfo.CLONE_REMOVE_FOR_CREATOR);
@@ -407,6 +413,7 @@
assertEquals(ShortcutInfo.FLAG_PINNED | ShortcutInfo.FLAG_LONG_LIVED, si.getFlags());
assertEquals(null, si.getBitmapPath());
+ assertNull(si.getIconUri());
assertEquals(456, si.getIconResourceId());
assertEquals(null, si.getIconResName());
@@ -428,6 +435,7 @@
assertEquals(ShortcutInfo.FLAG_PINNED | ShortcutInfo.FLAG_LONG_LIVED, si.getFlags());
assertEquals(null, si.getBitmapPath());
+ assertNull(si.getIconUri());
assertEquals(456, si.getIconResourceId());
assertEquals(null, si.getIconResName());
@@ -450,6 +458,7 @@
assertEquals(ShortcutInfo.FLAG_PINNED | ShortcutInfo.FLAG_KEY_FIELDS_ONLY
| ShortcutInfo.FLAG_LONG_LIVED, si.getFlags());
assertEquals(null, si.getBitmapPath());
+ assertNull(si.getIconUri());
assertEquals(456, si.getIconResourceId());
assertEquals(null, si.getIconResName());
@@ -474,6 +483,7 @@
assertEquals(ShortcutInfo.FLAG_PINNED | ShortcutInfo.FLAG_LONG_LIVED, si.getFlags());
assertEquals(null, si.getBitmapPath());
+ assertNull(si.getIconUri());
assertEquals(456, si.getIconResourceId());
assertEquals(null, si.getIconResName());
@@ -499,6 +509,7 @@
sorig.addFlags(ShortcutInfo.FLAG_PINNED);
sorig.setBitmapPath("abc");
sorig.setIconResourceId(456);
+ sorig.setIconUri("test_uri");
lookupAndFillInResourceNames(sorig);
@@ -526,6 +537,7 @@
assertEquals("abc", si.getBitmapPath());
assertEquals(456, si.getIconResourceId());
assertEquals("string/r456", si.getIconResName());
+ assertEquals("test_uri", si.getIconUri());
si = sorig.clone(ShortcutInfo.CLONE_REMOVE_FOR_CREATOR);
@@ -547,6 +559,7 @@
assertEquals(ShortcutInfo.FLAG_PINNED, si.getFlags());
assertEquals(null, si.getBitmapPath());
+ assertNull(si.getIconUri());
assertEquals(456, si.getIconResourceId());
assertEquals(null, si.getIconResName());
@@ -570,6 +583,7 @@
assertEquals(ShortcutInfo.FLAG_PINNED, si.getFlags());
assertEquals(null, si.getBitmapPath());
+ assertNull(si.getIconUri());
assertEquals(456, si.getIconResourceId());
assertEquals(null, si.getIconResName());
@@ -593,6 +607,7 @@
assertEquals(ShortcutInfo.FLAG_PINNED | ShortcutInfo.FLAG_KEY_FIELDS_ONLY, si.getFlags());
assertEquals(null, si.getBitmapPath());
+ assertNull(si.getIconUri());
assertEquals(456, si.getIconResourceId());
assertEquals(null, si.getIconResName());
@@ -657,6 +672,7 @@
sorig.addFlags(ShortcutInfo.FLAG_PINNED);
sorig.setBitmapPath("abc");
sorig.setIconResourceId(456);
+ sorig.setIconUri("test_uri");
lookupAndFillInResourceNames(sorig);
@@ -677,6 +693,7 @@
assertEquals(0, si.getIconResourceId());
assertEquals(null, si.getIconResName());
assertEquals(null, si.getBitmapPath());
+ assertNull(si.getIconUri());
si = sorig.clone(/* flags=*/ 0);
si.copyNonNullFieldsFrom(new ShortcutInfo.Builder(getTestContext()).setId("id")
@@ -787,6 +804,7 @@
sorig.addFlags(ShortcutInfo.FLAG_PINNED);
sorig.setBitmapPath("abc");
sorig.setIconResourceId(456);
+ sorig.setIconUri("test_uri");
ShortcutInfo si;
@@ -804,6 +822,7 @@
assertEquals(0, si.getIconResourceId());
assertEquals(null, si.getIconResName());
assertEquals(null, si.getBitmapPath());
+ assertNull(si.getIconUri());
si = sorig.clone(/* flags=*/ 0);
si.copyNonNullFieldsFrom(new ShortcutInfo.Builder(getTestContext()).setId("id")
@@ -977,6 +996,7 @@
| ShortcutInfo.FLAG_STRINGS_RESOLVED, si.getFlags());
assertNotNull(si.getBitmapPath()); // Something should be set.
assertEquals(0, si.getIconResourceId());
+ assertNull(si.getIconUri());
assertTrue(si.getLastChangedTimestamp() < now);
// Make sure ranks are saved too. Because of the auto-adjusting, we need two shortcuts
@@ -1053,6 +1073,7 @@
si.getFlags());
assertNotNull(si.getBitmapPath()); // Something should be set.
assertEquals(0, si.getIconResourceId());
+ assertNull(si.getIconUri());
assertTrue(si.getLastChangedTimestamp() < now);
dumpUserFile(USER_10);
@@ -1125,6 +1146,7 @@
assertEquals(ShortcutInfo.FLAG_DYNAMIC | ShortcutInfo.FLAG_HAS_ICON_RES
| ShortcutInfo.FLAG_STRINGS_RESOLVED, si.getFlags());
assertNull(si.getBitmapPath());
+ assertNull(si.getIconUri());
assertEquals(R.drawable.black_32x32, si.getIconResourceId());
assertTrue(si.getLastChangedTimestamp() < now);
@@ -1134,6 +1156,94 @@
assertEquals(1, si.getRank());
}
+ public void testShortcutInfoSaveAndLoad_uri() throws InterruptedException {
+ mRunningUsers.put(USER_10, true);
+
+ setCaller(CALLING_PACKAGE_1, USER_10);
+
+ final Icon uriIcon = Icon.createWithContentUri("test_uri");
+
+ PersistableBundle pb = new PersistableBundle();
+ pb.putInt("k", 1);
+ ShortcutInfo sorig = new ShortcutInfo.Builder(mClientContext)
+ .setId("id")
+ .setActivity(new ComponentName(mClientContext, ShortcutActivity2.class))
+ .setIcon(uriIcon)
+ .setTitleResId(10)
+ .setTextResId(11)
+ .setDisabledMessageResId(12)
+ .setCategories(set(ShortcutInfo.SHORTCUT_CATEGORY_CONVERSATION, "xyz"))
+ .setIntent(makeIntent("action", ShortcutActivity.class, "key", "val"))
+ .setRank(123)
+ .setExtras(pb)
+ .build();
+ sorig.setTimestamp(mInjectedCurrentTimeMillis);
+
+ final Icon uriMaskableIcon = Icon.createWithAdaptiveBitmapContentUri("uri_maskable");
+
+ ShortcutInfo sorig2 = new ShortcutInfo.Builder(mClientContext)
+ .setId("id2")
+ .setTitle("x")
+ .setActivity(new ComponentName(mClientContext, ShortcutActivity2.class))
+ .setIntent(makeIntent("action", ShortcutActivity.class, "key", "val"))
+ .setRank(456)
+ .setIcon(uriMaskableIcon)
+ .build();
+ sorig2.setTimestamp(mInjectedCurrentTimeMillis);
+
+ mManager.addDynamicShortcuts(list(sorig, sorig2));
+
+ mInjectedCurrentTimeMillis += 1;
+ final long now = mInjectedCurrentTimeMillis;
+ mInjectedCurrentTimeMillis += 1;
+
+ // Save and load.
+ mService.saveDirtyInfo();
+ initService();
+ mService.handleUnlockUser(USER_10);
+
+ ShortcutInfo si;
+ si = mService.getPackageShortcutForTest(CALLING_PACKAGE_1, "id", USER_10);
+
+ assertEquals(USER_10, si.getUserId());
+ assertEquals(HANDLE_USER_10, si.getUserHandle());
+ assertEquals(CALLING_PACKAGE_1, si.getPackage());
+ assertEquals("id", si.getId());
+ assertEquals(ShortcutActivity2.class.getName(), si.getActivity().getClassName());
+ assertEquals(null, si.getIcon());
+ assertEquals(10, si.getTitleResId());
+ assertEquals("r10", si.getTitleResName());
+ assertEquals(11, si.getTextResId());
+ assertEquals("r11", si.getTextResName());
+ assertEquals(12, si.getDisabledMessageResourceId());
+ assertEquals("r12", si.getDisabledMessageResName());
+ assertEquals(set(ShortcutInfo.SHORTCUT_CATEGORY_CONVERSATION, "xyz"), si.getCategories());
+ assertEquals("action", si.getIntent().getAction());
+ assertEquals("val", si.getIntent().getStringExtra("key"));
+ assertEquals(0, si.getRank());
+ assertEquals(1, si.getExtras().getInt("k"));
+
+ assertEquals(ShortcutInfo.FLAG_DYNAMIC | ShortcutInfo.FLAG_HAS_ICON_URI
+ | ShortcutInfo.FLAG_STRINGS_RESOLVED, si.getFlags());
+ assertNull(si.getBitmapPath());
+ assertNull(si.getIconResName());
+ assertEquals(0, si.getIconResourceId());
+ assertEquals("test_uri", si.getIconUri());
+ assertTrue(si.getLastChangedTimestamp() < now);
+
+ // Make sure ranks are saved too. Because of the auto-adjusting, we need two shortcuts
+ // to test it.
+ si = mService.getPackageShortcutForTest(CALLING_PACKAGE_1, "id2", USER_10);
+ assertEquals(1, si.getRank());
+ assertEquals(ShortcutInfo.FLAG_DYNAMIC | ShortcutInfo.FLAG_HAS_ICON_URI
+ | ShortcutInfo.FLAG_STRINGS_RESOLVED | ShortcutInfo.FLAG_ADAPTIVE_BITMAP,
+ si.getFlags());
+ assertNull(si.getBitmapPath());
+ assertNull(si.getIconResName());
+ assertEquals(0, si.getIconResourceId());
+ assertEquals("uri_maskable", si.getIconUri());
+ }
+
public void testShortcutInfoSaveAndLoad_forBackup() {
setCaller(CALLING_PACKAGE_1, USER_0);
@@ -1196,6 +1306,7 @@
| ShortcutInfo.FLAG_SHADOW , si.getFlags());
assertNull(si.getBitmapPath()); // No icon.
assertEquals(0, si.getIconResourceId());
+ assertNull(si.getIconUri());
// Note when restored from backup, it's no longer dynamic, so shouldn't have a rank.
si = mService.getPackageShortcutForTest(CALLING_PACKAGE_1, "id2", USER_0);
@@ -1265,6 +1376,77 @@
assertNull(si.getBitmapPath()); // No icon.
assertEquals(0, si.getIconResourceId());
assertEquals(null, si.getIconResName());
+ assertNull(si.getIconUri());
+
+ // Note when restored from backup, it's no longer dynamic, so shouldn't have a rank.
+ si = mService.getPackageShortcutForTest(CALLING_PACKAGE_1, "id2", USER_0);
+ assertEquals(0, si.getRank());
+ }
+
+ public void testShortcutInfoSaveAndLoad_forBackup_uri() {
+ setCaller(CALLING_PACKAGE_1, USER_0);
+
+ final Icon uriIcon = Icon.createWithContentUri("test_uri");
+
+ PersistableBundle pb = new PersistableBundle();
+ pb.putInt("k", 1);
+ ShortcutInfo sorig = new ShortcutInfo.Builder(mClientContext)
+ .setId("id")
+ .setActivity(new ComponentName(mClientContext, ShortcutActivity2.class))
+ .setIcon(uriIcon)
+ .setTitleResId(10)
+ .setTextResId(11)
+ .setDisabledMessageResId(12)
+ .setCategories(set(ShortcutInfo.SHORTCUT_CATEGORY_CONVERSATION, "xyz"))
+ .setIntent(makeIntent("action", ShortcutActivity.class, "key", "val"))
+ .setRank(123)
+ .setExtras(pb)
+ .build();
+
+ ShortcutInfo sorig2 = new ShortcutInfo.Builder(mClientContext)
+ .setId("id2")
+ .setTitle("x")
+ .setActivity(new ComponentName(mClientContext, ShortcutActivity2.class))
+ .setIntent(makeIntent("action", ShortcutActivity.class, "key", "val"))
+ .setRank(456)
+ .build();
+
+ mManager.addDynamicShortcuts(list(sorig, sorig2));
+
+ // Dynamic shortcuts won't be backed up, so we need to pin it.
+ setCaller(LAUNCHER_1, USER_0);
+ mLauncherApps.pinShortcuts(CALLING_PACKAGE_1, list("id", "id2"), HANDLE_USER_0);
+
+ // Do backup & restore.
+ backupAndRestore();
+
+ mService.handleUnlockUser(USER_0); // Load user-0.
+
+ ShortcutInfo si;
+ si = mService.getPackageShortcutForTest(CALLING_PACKAGE_1, "id", USER_0);
+
+ assertEquals(CALLING_PACKAGE_1, si.getPackage());
+ assertEquals("id", si.getId());
+ assertEquals(ShortcutActivity2.class.getName(), si.getActivity().getClassName());
+ assertEquals(null, si.getIcon());
+ assertEquals(10, si.getTitleResId());
+ assertEquals("r10", si.getTitleResName());
+ assertEquals(11, si.getTextResId());
+ assertEquals("r11", si.getTextResName());
+ assertEquals(12, si.getDisabledMessageResourceId());
+ assertEquals("r12", si.getDisabledMessageResName());
+ assertEquals(set(ShortcutInfo.SHORTCUT_CATEGORY_CONVERSATION, "xyz"), si.getCategories());
+ assertEquals("action", si.getIntent().getAction());
+ assertEquals("val", si.getIntent().getStringExtra("key"));
+ assertEquals(0, si.getRank());
+ assertEquals(1, si.getExtras().getInt("k"));
+
+ assertEquals(ShortcutInfo.FLAG_PINNED | ShortcutInfo.FLAG_STRINGS_RESOLVED
+ | ShortcutInfo.FLAG_SHADOW , si.getFlags());
+ assertNull(si.getBitmapPath()); // No icon.
+ assertEquals(0, si.getIconResourceId());
+ assertEquals(null, si.getIconResName());
+ assertNull(si.getIconUri());
// Note when restored from backup, it's no longer dynamic, so shouldn't have a rank.
si = mService.getPackageShortcutForTest(CALLING_PACKAGE_1, "id2", USER_0);
diff --git a/services/tests/uiservicestests/src/com/android/server/notification/NotificationListenerServiceTest.java b/services/tests/uiservicestests/src/com/android/server/notification/NotificationListenerServiceTest.java
index 8e78047..010f8ac 100644
--- a/services/tests/uiservicestests/src/com/android/server/notification/NotificationListenerServiceTest.java
+++ b/services/tests/uiservicestests/src/com/android/server/notification/NotificationListenerServiceTest.java
@@ -390,7 +390,7 @@
"title", 0, "titleResName", "text", 0, "textResName",
"disabledMessage", 0, "disabledMessageResName",
null, null, 0, null, 0, 0,
- 0, "iconResName", "bitmapPath", 0,
+ 0, "iconResName", "bitmapPath", null, 0,
null, null);
return si;
}
diff --git a/services/tests/uiservicestests/src/com/android/server/notification/ScheduleConditionProviderTest.java b/services/tests/uiservicestests/src/com/android/server/notification/ScheduleConditionProviderTest.java
index 5a527a2..551e186 100644
--- a/services/tests/uiservicestests/src/com/android/server/notification/ScheduleConditionProviderTest.java
+++ b/services/tests/uiservicestests/src/com/android/server/notification/ScheduleConditionProviderTest.java
@@ -3,10 +3,8 @@
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;
-import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.spy;
-import android.app.Application;
import android.content.Intent;
import android.net.Uri;
import android.service.notification.Condition;
@@ -47,7 +45,7 @@
null, // ActivityThread not actually used in Service
ScheduleConditionProvider.class.getName(),
null, // token not needed when not talking with the activity manager
- mock(Application.class),
+ null,
null // mocked services don't talk with the activity manager
);
service.onCreate();
diff --git a/services/tests/wmtests/Android.bp b/services/tests/wmtests/Android.bp
index cdba9a1..6cb8b86 100644
--- a/services/tests/wmtests/Android.bp
+++ b/services/tests/wmtests/Android.bp
@@ -20,6 +20,7 @@
"mockito-target-extended-minus-junit4",
"platform-test-annotations",
"servicestests-utils",
+ "testng",
"truth-prebuilt",
"testables",
"ub-uiautomator",
diff --git a/services/tests/wmtests/src/com/android/server/wm/DisplayPolicyLayoutTests.java b/services/tests/wmtests/src/com/android/server/wm/DisplayPolicyLayoutTests.java
index e2c27ea..7928e76 100644
--- a/services/tests/wmtests/src/com/android/server/wm/DisplayPolicyLayoutTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/DisplayPolicyLayoutTests.java
@@ -20,6 +20,9 @@
import static android.view.Gravity.LEFT;
import static android.view.Gravity.RIGHT;
import static android.view.Gravity.TOP;
+import static android.view.InsetsState.ITYPE_NAVIGATION_BAR;
+import static android.view.InsetsState.ITYPE_STATUS_BAR;
+import static android.view.InsetsState.ITYPE_TOP_GESTURES;
import static android.view.Surface.ROTATION_0;
import static android.view.Surface.ROTATION_270;
import static android.view.Surface.ROTATION_90;
@@ -42,13 +45,17 @@
import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION;
import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION_OVERLAY;
import static android.view.WindowManager.LayoutParams.TYPE_KEYGUARD_DIALOG;
+import static android.view.WindowManager.LayoutParams.TYPE_STATUS_BAR;
+import static android.view.WindowManager.LayoutParams.TYPE_STATUS_BAR_SUB_PANEL;
import static org.hamcrest.Matchers.is;
import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotEquals;
import static org.junit.Assert.assertThat;
import static org.junit.Assume.assumeTrue;
import static org.mockito.Mockito.doNothing;
import static org.mockito.Mockito.spy;
+import static org.testng.Assert.expectThrows;
import android.app.WindowConfiguration;
import android.graphics.Insets;
@@ -154,6 +161,56 @@
}
@Test
+ public void addingWindow_withInsetsTypes() {
+ WindowState win = createWindow(null, TYPE_STATUS_BAR_SUB_PANEL, "StatusBarSubPanel");
+ win.mAttrs.providesInsetsTypes = new int[]{ITYPE_STATUS_BAR, ITYPE_TOP_GESTURES};
+ win.getFrameLw().set(0, 0, 500, 100);
+
+ addWindow(win);
+ InsetsStateController controller = mDisplayContent.getInsetsStateController();
+ controller.onPostLayout();
+
+ InsetsSourceProvider statusBarProvider = controller.getSourceProvider(ITYPE_STATUS_BAR);
+ assertEquals(new Rect(0, 0, 500, 100), statusBarProvider.getSource().getFrame());
+ assertEquals(Insets.of(0, 100, 0, 0),
+ statusBarProvider.getSource().calculateInsets(new Rect(0, 0, 500, 500),
+ false /* ignoreVisibility */));
+
+ InsetsSourceProvider topGesturesProvider = controller.getSourceProvider(ITYPE_TOP_GESTURES);
+ assertEquals(new Rect(0, 0, 500, 100), topGesturesProvider.getSource().getFrame());
+ assertEquals(Insets.of(0, 100, 0, 0),
+ topGesturesProvider.getSource().calculateInsets(new Rect(0, 0, 500, 500),
+ false /* ignoreVisibility */));
+
+ InsetsSourceProvider navigationBarProvider = controller.getSourceProvider(
+ ITYPE_NAVIGATION_BAR);
+ assertNotEquals(new Rect(0, 0, 500, 100), navigationBarProvider.getSource().getFrame());
+ }
+
+ @Test
+ public void addingWindow_ignoresInsetsTypes_InWindowTypeWithPredefinedInsets() {
+ mDisplayPolicy.removeWindowLw(mStatusBarWindow); // Removes the existing one.
+ WindowState win = createWindow(null, TYPE_STATUS_BAR, "StatusBar");
+ win.mAttrs.providesInsetsTypes = new int[]{ITYPE_STATUS_BAR};
+ win.getFrameLw().set(0, 0, 500, 100);
+
+ addWindow(win);
+ mDisplayContent.getInsetsStateController().onPostLayout();
+
+ InsetsSourceProvider provider =
+ mDisplayContent.getInsetsStateController().getSourceProvider(ITYPE_STATUS_BAR);
+ assertNotEquals(new Rect(0, 0, 500, 100), provider.getSource().getFrame());
+ }
+
+ @Test
+ public void addingWindow_throwsException_WithMultipleInsetTypes() {
+ WindowState win = createWindow(null, TYPE_STATUS_BAR_SUB_PANEL, "StatusBarSubPanel");
+ win.mAttrs.providesInsetsTypes = new int[]{ITYPE_STATUS_BAR, ITYPE_NAVIGATION_BAR};
+
+ expectThrows(IllegalArgumentException.class, () -> addWindow(win));
+ }
+
+ @Test
public void layoutWindowLw_fitStatusBars() {
assumeTrue(ViewRootImpl.sNewInsetsMode == ViewRootImpl.NEW_INSETS_MODE_FULL);
diff --git a/services/usb/java/com/android/server/usb/UsbDeviceManager.java b/services/usb/java/com/android/server/usb/UsbDeviceManager.java
index 8e85bb2..747c8d9 100644
--- a/services/usb/java/com/android/server/usb/UsbDeviceManager.java
+++ b/services/usb/java/com/android/server/usb/UsbDeviceManager.java
@@ -445,7 +445,6 @@
abstract static class UsbHandler extends Handler {
// current USB state
- private boolean mConnected;
private boolean mHostConnected;
private boolean mSourcePower;
private boolean mSinkPower;
@@ -473,6 +472,7 @@
private final UsbPermissionManager mPermissionManager;
private NotificationManager mNotificationManager;
+ protected boolean mConnected;
protected long mScreenUnlockedFunctions;
protected boolean mBootCompleted;
protected boolean mCurrentFunctionsApplied;
@@ -1794,7 +1794,8 @@
case MSG_SET_FUNCTIONS_TIMEOUT:
Slog.e(TAG, "Set functions timed out! no reply from usb hal");
if (msg.arg1 != 1) {
- setEnabledFunctions(UsbManager.FUNCTION_NONE, false);
+ // Set this since default function may be selected from Developer options
+ setEnabledFunctions(mScreenUnlockedFunctions, false);
}
break;
case MSG_GET_CURRENT_USB_FUNCTIONS:
@@ -1816,7 +1817,8 @@
* Dont force to default when the configuration is already set to default.
*/
if (msg.arg1 != 1) {
- setEnabledFunctions(UsbManager.FUNCTION_NONE, !isAdbEnabled());
+ // Set this since default function may be selected from Developer options
+ setEnabledFunctions(mScreenUnlockedFunctions, false);
}
break;
case MSG_GADGET_HAL_REGISTERED:
@@ -1936,8 +1938,11 @@
SET_FUNCTIONS_TIMEOUT_MS - SET_FUNCTIONS_LEEWAY_MS);
sendMessageDelayed(MSG_SET_FUNCTIONS_TIMEOUT, chargingFunctions,
SET_FUNCTIONS_TIMEOUT_MS);
- sendMessageDelayed(MSG_FUNCTION_SWITCH_TIMEOUT, chargingFunctions,
- SET_FUNCTIONS_TIMEOUT_MS + ENUMERATION_TIME_OUT_MS);
+ if (mConnected) {
+ // Only queue timeout of enumeration when the USB is connected
+ sendMessageDelayed(MSG_FUNCTION_SWITCH_TIMEOUT, chargingFunctions,
+ SET_FUNCTIONS_TIMEOUT_MS + ENUMERATION_TIME_OUT_MS);
+ }
if (DEBUG) Slog.d(TAG, "timeout message queued");
} catch (RemoteException e) {
Slog.e(TAG, "Remoteexception while calling setCurrentUsbFunctions", e);
diff --git a/services/voiceinteraction/java/com/android/server/soundtrigger/SoundTriggerService.java b/services/voiceinteraction/java/com/android/server/soundtrigger/SoundTriggerService.java
index 767010a..3196758 100644
--- a/services/voiceinteraction/java/com/android/server/soundtrigger/SoundTriggerService.java
+++ b/services/voiceinteraction/java/com/android/server/soundtrigger/SoundTriggerService.java
@@ -19,6 +19,7 @@
import static android.Manifest.permission.BIND_SOUND_TRIGGER_DETECTION_SERVICE;
import static android.content.Context.BIND_AUTO_CREATE;
import static android.content.Context.BIND_FOREGROUND_SERVICE;
+import static android.content.Context.BIND_INCLUDE_CAPABILITIES;
import static android.content.pm.PackageManager.GET_META_DATA;
import static android.content.pm.PackageManager.GET_SERVICES;
import static android.content.pm.PackageManager.MATCH_DEBUG_TRIAGED_MISSING;
@@ -1133,7 +1134,8 @@
}
mIsBound = mContext.bindServiceAsUser(i, this,
- BIND_AUTO_CREATE | BIND_FOREGROUND_SERVICE, mUser);
+ BIND_AUTO_CREATE | BIND_FOREGROUND_SERVICE | BIND_INCLUDE_CAPABILITIES,
+ mUser);
if (mIsBound) {
mRemoteServiceWakeLock.acquire();
diff --git a/telephony/java/android/telephony/Annotation.java b/telephony/java/android/telephony/Annotation.java
index dcd4eb5..28cc7d0 100644
--- a/telephony/java/android/telephony/Annotation.java
+++ b/telephony/java/android/telephony/Annotation.java
@@ -598,48 +598,6 @@
}
/**
- * Call forwarding function status
- */
- @IntDef(prefix = { "STATUS_" }, value = {
- CallForwardingInfo.STATUS_ACTIVE,
- CallForwardingInfo.STATUS_INACTIVE,
- CallForwardingInfo.STATUS_UNKNOWN_ERROR,
- CallForwardingInfo.STATUS_NOT_SUPPORTED,
- CallForwardingInfo.STATUS_FDN_CHECK_FAILURE
- })
- @Retention(RetentionPolicy.SOURCE)
- public @interface CallForwardingStatus {
- }
-
- /**
- * Call forwarding reason types
- */
- @IntDef(flag = true, prefix = { "REASON_" }, value = {
- CallForwardingInfo.REASON_UNCONDITIONAL,
- CallForwardingInfo.REASON_BUSY,
- CallForwardingInfo.REASON_NO_REPLY,
- CallForwardingInfo.REASON_NOT_REACHABLE,
- CallForwardingInfo.REASON_ALL,
- CallForwardingInfo.REASON_ALL_CONDITIONAL
- })
- @Retention(RetentionPolicy.SOURCE)
- public @interface CallForwardingReason {
- }
-
- /**
- * Call waiting function status
- */
- @IntDef(prefix = { "CALL_WAITING_STATUS_" }, value = {
- TelephonyManager.CALL_WAITING_STATUS_ACTIVE,
- TelephonyManager.CALL_WAITING_STATUS_INACTIVE,
- TelephonyManager.CALL_WAITING_STATUS_NOT_SUPPORTED,
- TelephonyManager.CALL_WAITING_STATUS_UNKNOWN_ERROR
- })
- @Retention(RetentionPolicy.SOURCE)
- public @interface CallWaitingStatus {
- }
-
- /**
* UICC SIM Application Types
*/
@IntDef(prefix = { "APPTYPE_" }, value = {
diff --git a/telephony/java/android/telephony/CallForwardingInfo.java b/telephony/java/android/telephony/CallForwardingInfo.java
index 1dd7539..7e777fa 100644
--- a/telephony/java/android/telephony/CallForwardingInfo.java
+++ b/telephony/java/android/telephony/CallForwardingInfo.java
@@ -15,24 +15,24 @@
*/
package android.telephony;
+
+import android.annotation.IntDef;
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.annotation.SuppressLint;
-import android.annotation.SystemApi;
import android.os.Parcel;
import android.os.Parcelable;
-import android.telephony.Annotation.CallForwardingReason;
-import android.telephony.Annotation.CallForwardingStatus;
import com.android.telephony.Rlog;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
import java.util.Objects;
/**
* Defines the call forwarding information.
* @hide
*/
-@SystemApi
public final class CallForwardingInfo implements Parcelable {
private static final String TAG = "CallForwardingInfo";
@@ -41,7 +41,6 @@
*
* @hide
*/
- @SystemApi
public static final int STATUS_INACTIVE = 0;
/**
@@ -49,7 +48,6 @@
*
* @hide
*/
- @SystemApi
public static final int STATUS_ACTIVE = 1;
/**
@@ -58,7 +56,6 @@
*
* @hide
*/
- @SystemApi
public static final int STATUS_FDN_CHECK_FAILURE = 2;
/**
@@ -66,7 +63,6 @@
*
* @hide
*/
- @SystemApi
public static final int STATUS_UNKNOWN_ERROR = 3;
/**
@@ -74,7 +70,6 @@
*
* @hide
*/
- @SystemApi
public static final int STATUS_NOT_SUPPORTED = 4;
/**
@@ -83,7 +78,6 @@
* and conditions +CCFC
* @hide
*/
- @SystemApi
public static final int REASON_UNCONDITIONAL = 0;
/**
@@ -92,7 +86,6 @@
* and conditions +CCFC
* @hide
*/
- @SystemApi
public static final int REASON_BUSY = 1;
/**
@@ -101,7 +94,6 @@
* and conditions +CCFC
* @hide
*/
- @SystemApi
public static final int REASON_NO_REPLY = 2;
/**
@@ -110,7 +102,6 @@
* and conditions +CCFC
* @hide
*/
- @SystemApi
public static final int REASON_NOT_REACHABLE = 3;
/**
@@ -120,7 +111,6 @@
* and conditions +CCFC
* @hide
*/
- @SystemApi
public static final int REASON_ALL = 4;
/**
@@ -130,20 +120,48 @@
* and conditions +CCFC
* @hide
*/
- @SystemApi
public static final int REASON_ALL_CONDITIONAL = 5;
/**
+ * Call forwarding function status
+ */
+ @IntDef(prefix = { "STATUS_" }, value = {
+ STATUS_ACTIVE,
+ STATUS_INACTIVE,
+ STATUS_UNKNOWN_ERROR,
+ STATUS_NOT_SUPPORTED,
+ STATUS_FDN_CHECK_FAILURE
+ })
+ @Retention(RetentionPolicy.SOURCE)
+ public @interface CallForwardingStatus {
+ }
+
+ /**
+ * Call forwarding reason types
+ */
+ @IntDef(flag = true, prefix = { "REASON_" }, value = {
+ REASON_UNCONDITIONAL,
+ REASON_BUSY,
+ REASON_NO_REPLY,
+ REASON_NOT_REACHABLE,
+ REASON_ALL,
+ REASON_ALL_CONDITIONAL
+ })
+ @Retention(RetentionPolicy.SOURCE)
+ public @interface CallForwardingReason {
+ }
+
+ /**
* The call forwarding status.
*/
- private @CallForwardingStatus int mStatus;
+ private int mStatus;
/**
* The call forwarding reason indicates the condition under which calls will be forwarded.
* Reference: 3GPP TS 27.007 version 10.3.0 Release 10 - 7.11 Call forwarding number
* and conditions +CCFC
*/
- private @CallForwardingReason int mReason;
+ private int mReason;
/**
* The phone number to which calls will be forwarded.
@@ -166,7 +184,6 @@
* @param timeSeconds the timeout (in seconds) before the forwarding is attempted
* @hide
*/
- @SystemApi
public CallForwardingInfo(@CallForwardingStatus int status, @CallForwardingReason int reason,
@Nullable String number, int timeSeconds) {
mStatus = status;
@@ -182,7 +199,6 @@
*
* @hide
*/
- @SystemApi
public @CallForwardingStatus int getStatus() {
return mStatus;
}
@@ -196,7 +212,6 @@
*
* @hide
*/
- @SystemApi
public @CallForwardingReason int getReason() {
return mReason;
}
@@ -209,7 +224,6 @@
*
* @hide
*/
- @SystemApi
@Nullable
public String getNumber() {
return mNumber;
@@ -227,7 +241,6 @@
*
* @hide
*/
- @SystemApi
@SuppressLint("MethodNameUnits")
public int getTimeoutSeconds() {
return mTimeSeconds;
diff --git a/telephony/java/android/telephony/PreciseDataConnectionState.java b/telephony/java/android/telephony/PreciseDataConnectionState.java
index e37a9b9..c2cfbef 100644
--- a/telephony/java/android/telephony/PreciseDataConnectionState.java
+++ b/telephony/java/android/telephony/PreciseDataConnectionState.java
@@ -95,7 +95,6 @@
* if there is no valid APN setting for the specific type, then this will be null
* @hide
*/
- @SystemApi
public PreciseDataConnectionState(@DataState int state,
@NetworkType int networkType,
@ApnType int apnTypes, @NonNull String apn,
diff --git a/telephony/java/android/telephony/SmsManager.java b/telephony/java/android/telephony/SmsManager.java
index f6a305f..6aea5ee 100644
--- a/telephony/java/android/telephony/SmsManager.java
+++ b/telephony/java/android/telephony/SmsManager.java
@@ -2894,7 +2894,7 @@
getSubscriptionId(), null);
}
} catch (RemoteException ex) {
- // ignore it
+ throw new RuntimeException(ex);
}
return smsc;
}
@@ -2916,7 +2916,7 @@
* </p>
*
* @param smsc the SMSC address string.
- * @return true for success, false otherwise.
+ * @return true for success, false otherwise. Failure can be due modem returning an error.
*/
@SuppressAutoDoc // for carrier privileges and default SMS application.
@RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE)
@@ -2928,7 +2928,7 @@
smsc, getSubscriptionId(), null);
}
} catch (RemoteException ex) {
- // ignore it
+ throw new RuntimeException(ex);
}
return false;
}
diff --git a/telephony/java/android/telephony/TelephonyManager.java b/telephony/java/android/telephony/TelephonyManager.java
index e559c2a..5339fb9 100644
--- a/telephony/java/android/telephony/TelephonyManager.java
+++ b/telephony/java/android/telephony/TelephonyManager.java
@@ -70,13 +70,12 @@
import android.telecom.PhoneAccountHandle;
import android.telecom.TelecomManager;
import android.telephony.Annotation.ApnType;
-import android.telephony.Annotation.CallForwardingReason;
import android.telephony.Annotation.CallState;
-import android.telephony.Annotation.CallWaitingStatus;
import android.telephony.Annotation.NetworkType;
import android.telephony.Annotation.RadioPowerState;
import android.telephony.Annotation.SimActivationState;
import android.telephony.Annotation.UiccAppType;
+import android.telephony.CallForwardingInfo.CallForwardingReason;
import android.telephony.VisualVoicemailService.VisualVoicemailTask;
import android.telephony.data.ApnSetting;
import android.telephony.data.ApnSetting.MvnoType;
@@ -11179,6 +11178,8 @@
* PackageManager.FEATURE_TELEPHONY system feature, which is available
* on any device with a telephony radio, even if the device is
* voice-only.
+ *
+ * @hide
*/
public boolean isDataCapable() {
if (mContext == null) return true;
@@ -12714,7 +12715,6 @@
*
* @hide
*/
- @SystemApi
@RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE)
@NonNull
public CallForwardingInfo getCallForwarding(@CallForwardingReason int callForwardingReason) {
@@ -12761,7 +12761,6 @@
*
* @hide
*/
- @SystemApi
@RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE)
public boolean setCallForwarding(@NonNull CallForwardingInfo callForwardingInfo) {
if (callForwardingInfo == null) {
@@ -12802,7 +12801,6 @@
*
* @hide
*/
- @SystemApi
public static final int CALL_WAITING_STATUS_ACTIVE = 1;
/**
@@ -12810,7 +12808,6 @@
*
* @hide
*/
- @SystemApi
public static final int CALL_WAITING_STATUS_INACTIVE = 2;
/**
@@ -12818,7 +12815,6 @@
*
* @hide
*/
- @SystemApi
public static final int CALL_WAITING_STATUS_UNKNOWN_ERROR = 3;
/**
@@ -12826,10 +12822,24 @@
*
* @hide
*/
- @SystemApi
public static final int CALL_WAITING_STATUS_NOT_SUPPORTED = 4;
/**
+ * Call waiting function status
+ *
+ * @hide
+ */
+ @IntDef(prefix = { "CALL_WAITING_STATUS_" }, value = {
+ CALL_WAITING_STATUS_ACTIVE,
+ CALL_WAITING_STATUS_INACTIVE,
+ CALL_WAITING_STATUS_NOT_SUPPORTED,
+ CALL_WAITING_STATUS_UNKNOWN_ERROR
+ })
+ @Retention(RetentionPolicy.SOURCE)
+ public @interface CallWaitingStatus {
+ }
+
+ /**
* Gets the status of voice call waiting function. Call waiting function enables the waiting
* for the incoming call when it reaches the user who is busy to make another call and allows
* users to decide whether to switch to the incoming call.
@@ -12837,7 +12847,6 @@
* @return the status of call waiting function.
* @hide
*/
- @SystemApi
@RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE)
public @CallWaitingStatus int getCallWaitingStatus() {
try {
@@ -12863,7 +12872,6 @@
*
* @hide
*/
- @SystemApi
@RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE)
public boolean setCallWaitingStatus(boolean isEnable) {
try {
diff --git a/tests/PackageWatchdog/src/com/android/server/PackageWatchdogTest.java b/tests/PackageWatchdog/src/com/android/server/PackageWatchdogTest.java
index dfaac2c..2957192 100644
--- a/tests/PackageWatchdog/src/com/android/server/PackageWatchdogTest.java
+++ b/tests/PackageWatchdog/src/com/android/server/PackageWatchdogTest.java
@@ -1077,6 +1077,52 @@
assertThat(observer1.mMitigatedPackages).isEmpty();
}
+ /**
+ * Test to verify that Package Watchdog syncs health check requests with the controller
+ * correctly, and that the requests are only synced when the set of observed packages
+ * changes.
+ */
+ @Test
+ public void testSyncHealthCheckRequests() {
+ TestController testController = spy(TestController.class);
+ testController.setSupportedPackages(List.of(APP_A, APP_B, APP_C));
+ PackageWatchdog watchdog = createWatchdog(testController, true);
+
+ TestObserver testObserver1 = new TestObserver(OBSERVER_NAME_1);
+ watchdog.registerHealthObserver(testObserver1);
+ watchdog.startObservingHealth(testObserver1, List.of(APP_A), LONG_DURATION);
+ mTestLooper.dispatchAll();
+
+ TestObserver testObserver2 = new TestObserver(OBSERVER_NAME_2);
+ watchdog.registerHealthObserver(testObserver2);
+ watchdog.startObservingHealth(testObserver2, List.of(APP_B), LONG_DURATION);
+ mTestLooper.dispatchAll();
+
+ TestObserver testObserver3 = new TestObserver(OBSERVER_NAME_3);
+ watchdog.registerHealthObserver(testObserver3);
+ watchdog.startObservingHealth(testObserver3, List.of(APP_C), LONG_DURATION);
+ mTestLooper.dispatchAll();
+
+ watchdog.unregisterHealthObserver(testObserver1);
+ mTestLooper.dispatchAll();
+
+ watchdog.unregisterHealthObserver(testObserver2);
+ mTestLooper.dispatchAll();
+
+ watchdog.unregisterHealthObserver(testObserver3);
+ mTestLooper.dispatchAll();
+
+ List<Set> expectedSyncRequests = List.of(
+ Set.of(APP_A),
+ Set.of(APP_A, APP_B),
+ Set.of(APP_A, APP_B, APP_C),
+ Set.of(APP_B, APP_C),
+ Set.of(APP_C),
+ Set.of()
+ );
+ assertThat(testController.getSyncRequests()).isEqualTo(expectedSyncRequests);
+ }
+
private void adoptShellPermissions(String... permissions) {
InstrumentationRegistry
.getInstrumentation()
@@ -1233,6 +1279,7 @@
private Consumer<String> mPassedConsumer;
private Consumer<List<PackageConfig>> mSupportedConsumer;
private Runnable mNotifySyncRunnable;
+ private List<Set> mSyncRequests = new ArrayList<>();
@Override
public void setEnabled(boolean enabled) {
@@ -1252,6 +1299,7 @@
@Override
public void syncRequests(Set<String> packages) {
+ mSyncRequests.add(packages);
mRequestedPackages.clear();
if (mIsEnabled) {
packages.retainAll(mSupportedPackages);
@@ -1282,6 +1330,10 @@
return Collections.emptyList();
}
}
+
+ public List<Set> getSyncRequests() {
+ return mSyncRequests;
+ }
}
private static class TestClock implements PackageWatchdog.SystemClock {
diff --git a/tests/net/AndroidManifest.xml b/tests/net/AndroidManifest.xml
index 480b12b..009f817 100644
--- a/tests/net/AndroidManifest.xml
+++ b/tests/net/AndroidManifest.xml
@@ -47,6 +47,7 @@
<uses-permission android:name="android.permission.NETWORK_STACK" />
<uses-permission android:name="android.permission.OBSERVE_NETWORK_POLICY" />
<uses-permission android:name="android.permission.NETWORK_FACTORY" />
+ <uses-permission android:name="android.permission.NETWORK_STATS_PROVIDER" />
<application>
<uses-library android:name="android.test.runner" />
diff --git a/tests/net/common/java/android/net/KeepalivePacketDataTest.kt b/tests/net/common/java/android/net/KeepalivePacketDataTest.kt
new file mode 100644
index 0000000..f464ec6
--- /dev/null
+++ b/tests/net/common/java/android/net/KeepalivePacketDataTest.kt
@@ -0,0 +1,120 @@
+/*
+ * 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.net
+
+import android.net.InvalidPacketException.ERROR_INVALID_IP_ADDRESS
+import android.net.InvalidPacketException.ERROR_INVALID_PORT
+import android.os.Build
+import androidx.test.filters.SmallTest
+import androidx.test.runner.AndroidJUnit4
+import com.android.testutils.DevSdkIgnoreRule
+import com.android.testutils.DevSdkIgnoreRule.IgnoreUpTo
+import java.net.InetAddress
+import java.util.Arrays
+import org.junit.Assert.assertEquals
+import org.junit.Assert.assertTrue
+import org.junit.Assert.fail
+import org.junit.Rule
+import org.junit.Test
+import org.junit.runner.RunWith
+
+@RunWith(AndroidJUnit4::class)
+@SmallTest
+class KeepalivePacketDataTest {
+ @Rule @JvmField
+ val ignoreRule: DevSdkIgnoreRule = DevSdkIgnoreRule()
+
+ private val INVALID_PORT = 65537
+ private val TEST_DST_PORT = 4244
+ private val TEST_SRC_PORT = 4243
+
+ private val TESTBYTES = byteArrayOf(12, 31, 22, 44)
+ private val TEST_SRC_ADDRV4 = "198.168.0.2".address()
+ private val TEST_DST_ADDRV4 = "198.168.0.1".address()
+ private val TEST_ADDRV6 = "2001:db8::1".address()
+
+ private fun String.address() = InetAddresses.parseNumericAddress(this)
+
+ // Add for test because constructor of KeepalivePacketData is protected.
+ private inner class TestKeepalivePacketData(
+ srcAddress: InetAddress? = TEST_SRC_ADDRV4,
+ srcPort: Int = TEST_SRC_PORT,
+ dstAddress: InetAddress? = TEST_DST_ADDRV4,
+ dstPort: Int = TEST_DST_PORT,
+ data: ByteArray = TESTBYTES
+ ) : KeepalivePacketData(srcAddress, srcPort, dstAddress, dstPort, data)
+
+ @Test
+ @IgnoreUpTo(Build.VERSION_CODES.Q)
+ fun testConstructor() {
+ var data: TestKeepalivePacketData
+
+ try {
+ data = TestKeepalivePacketData(srcAddress = null)
+ fail("Null src address should cause exception")
+ } catch (e: InvalidPacketException) {
+ assertEquals(e.error, ERROR_INVALID_IP_ADDRESS)
+ }
+
+ try {
+ data = TestKeepalivePacketData(dstAddress = null)
+ fail("Null dst address should cause exception")
+ } catch (e: InvalidPacketException) {
+ assertEquals(e.error, ERROR_INVALID_IP_ADDRESS)
+ }
+
+ try {
+ data = TestKeepalivePacketData(dstAddress = TEST_ADDRV6)
+ fail("Ip family mismatched should cause exception")
+ } catch (e: InvalidPacketException) {
+ assertEquals(e.error, ERROR_INVALID_IP_ADDRESS)
+ }
+
+ try {
+ data = TestKeepalivePacketData(srcPort = INVALID_PORT)
+ fail("Invalid srcPort should cause exception")
+ } catch (e: InvalidPacketException) {
+ assertEquals(e.error, ERROR_INVALID_PORT)
+ }
+
+ try {
+ data = TestKeepalivePacketData(dstPort = INVALID_PORT)
+ fail("Invalid dstPort should cause exception")
+ } catch (e: InvalidPacketException) {
+ assertEquals(e.error, ERROR_INVALID_PORT)
+ }
+ }
+
+ @Test
+ @IgnoreUpTo(Build.VERSION_CODES.Q)
+ fun testSrcAddress() = assertEquals(TEST_SRC_ADDRV4, TestKeepalivePacketData().srcAddress)
+
+ @Test
+ @IgnoreUpTo(Build.VERSION_CODES.Q)
+ fun testDstAddress() = assertEquals(TEST_DST_ADDRV4, TestKeepalivePacketData().dstAddress)
+
+ @Test
+ @IgnoreUpTo(Build.VERSION_CODES.Q)
+ fun testSrcPort() = assertEquals(TEST_SRC_PORT, TestKeepalivePacketData().srcPort)
+
+ @Test
+ @IgnoreUpTo(Build.VERSION_CODES.Q)
+ fun testDstPort() = assertEquals(TEST_DST_PORT, TestKeepalivePacketData().dstPort)
+
+ @Test
+ @IgnoreUpTo(Build.VERSION_CODES.Q)
+ fun testPacket() = assertTrue(Arrays.equals(TESTBYTES, TestKeepalivePacketData().packet))
+}
\ No newline at end of file
diff --git a/tests/net/common/java/android/net/NattKeepalivePacketDataTest.kt b/tests/net/common/java/android/net/NattKeepalivePacketDataTest.kt
new file mode 100644
index 0000000..46f39dd
--- /dev/null
+++ b/tests/net/common/java/android/net/NattKeepalivePacketDataTest.kt
@@ -0,0 +1,114 @@
+/*
+ * 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.net
+
+import android.net.InvalidPacketException.ERROR_INVALID_IP_ADDRESS
+import android.net.InvalidPacketException.ERROR_INVALID_PORT
+import android.net.NattSocketKeepalive.NATT_PORT
+import android.os.Build
+import androidx.test.filters.SmallTest
+import androidx.test.runner.AndroidJUnit4
+import com.android.testutils.assertEqualBothWays
+import com.android.testutils.assertFieldCountEquals
+import com.android.testutils.assertParcelSane
+import com.android.testutils.DevSdkIgnoreRule
+import com.android.testutils.DevSdkIgnoreRule.IgnoreUpTo
+import com.android.testutils.parcelingRoundTrip
+import java.net.InetAddress
+import org.junit.Assert.assertEquals
+import org.junit.Assert.assertNotEquals
+import org.junit.Assert.fail
+import org.junit.Rule
+import org.junit.Test
+import org.junit.runner.RunWith
+
+@RunWith(AndroidJUnit4::class)
+@SmallTest
+class NattKeepalivePacketDataTest {
+ @Rule @JvmField
+ val ignoreRule: DevSdkIgnoreRule = DevSdkIgnoreRule()
+
+ /* Refer to the definition in {@code NattKeepalivePacketData} */
+ private val IPV4_HEADER_LENGTH = 20
+ private val UDP_HEADER_LENGTH = 8
+
+ private val TEST_PORT = 4243
+ private val TEST_PORT2 = 4244
+ private val TEST_SRC_ADDRV4 = "198.168.0.2".address()
+ private val TEST_DST_ADDRV4 = "198.168.0.1".address()
+ private val TEST_ADDRV6 = "2001:db8::1".address()
+
+ private fun String.address() = InetAddresses.parseNumericAddress(this)
+ private fun nattKeepalivePacket(
+ srcAddress: InetAddress? = TEST_SRC_ADDRV4,
+ srcPort: Int = TEST_PORT,
+ dstAddress: InetAddress? = TEST_DST_ADDRV4,
+ dstPort: Int = NATT_PORT
+ ) = NattKeepalivePacketData.nattKeepalivePacket(srcAddress, srcPort, dstAddress, dstPort)
+
+ @Test @IgnoreUpTo(Build.VERSION_CODES.Q)
+ fun testConstructor() {
+ try {
+ nattKeepalivePacket(dstPort = TEST_PORT)
+ fail("Dst port is not NATT port should cause exception")
+ } catch (e: InvalidPacketException) {
+ assertEquals(e.error, ERROR_INVALID_PORT)
+ }
+
+ try {
+ nattKeepalivePacket(srcAddress = TEST_ADDRV6)
+ fail("A v6 srcAddress should cause exception")
+ } catch (e: InvalidPacketException) {
+ assertEquals(e.error, ERROR_INVALID_IP_ADDRESS)
+ }
+
+ try {
+ nattKeepalivePacket(dstAddress = TEST_ADDRV6)
+ fail("A v6 dstAddress should cause exception")
+ } catch (e: InvalidPacketException) {
+ assertEquals(e.error, ERROR_INVALID_IP_ADDRESS)
+ }
+
+ try {
+ parcelingRoundTrip(
+ NattKeepalivePacketData(TEST_SRC_ADDRV4, TEST_PORT, TEST_DST_ADDRV4, TEST_PORT,
+ byteArrayOf(12, 31, 22, 44)))
+ fail("Invalid data should cause exception")
+ } catch (e: IllegalArgumentException) { }
+ }
+
+ @Test @IgnoreUpTo(Build.VERSION_CODES.Q)
+ fun testParcel() {
+ assertParcelSane(nattKeepalivePacket(), 0)
+ }
+
+ @Test @IgnoreUpTo(Build.VERSION_CODES.Q)
+ fun testEquals() {
+ assertEqualBothWays(nattKeepalivePacket(), nattKeepalivePacket())
+ assertNotEquals(nattKeepalivePacket(dstAddress = TEST_SRC_ADDRV4), nattKeepalivePacket())
+ assertNotEquals(nattKeepalivePacket(srcAddress = TEST_DST_ADDRV4), nattKeepalivePacket())
+ // Test src port only because dst port have to be NATT_PORT
+ assertNotEquals(nattKeepalivePacket(srcPort = TEST_PORT2), nattKeepalivePacket())
+ // Make sure the parceling test is updated if fields are added in the base class.
+ assertFieldCountEquals(5, KeepalivePacketData::class.java)
+ }
+
+ @Test @IgnoreUpTo(Build.VERSION_CODES.Q)
+ fun testHashCode() {
+ assertEquals(nattKeepalivePacket().hashCode(), nattKeepalivePacket().hashCode())
+ }
+}
\ No newline at end of file
diff --git a/tests/net/java/android/net/NetworkStatsTest.java b/tests/net/java/android/net/NetworkStatsTest.java
index 33d77d2..e71d599 100644
--- a/tests/net/java/android/net/NetworkStatsTest.java
+++ b/tests/net/java/android/net/NetworkStatsTest.java
@@ -64,15 +64,15 @@
@Test
public void testFindIndex() throws Exception {
final NetworkStats stats = new NetworkStats(TEST_START, 5)
- .addEntry(TEST_IFACE, 100, SET_DEFAULT, TAG_NONE, METERED_NO, ROAMING_NO,
+ .insertEntry(TEST_IFACE, 100, SET_DEFAULT, TAG_NONE, METERED_NO, ROAMING_NO,
DEFAULT_NETWORK_YES, 1024L, 8L, 0L, 0L, 10)
- .addEntry(TEST_IFACE, 101, SET_DEFAULT, TAG_NONE, METERED_NO, ROAMING_NO,
+ .insertEntry(TEST_IFACE, 101, SET_DEFAULT, TAG_NONE, METERED_NO, ROAMING_NO,
DEFAULT_NETWORK_NO, 0L, 0L, 1024L, 8L, 11)
- .addEntry(TEST_IFACE, 101, SET_DEFAULT, TAG_NONE, METERED_YES, ROAMING_NO,
+ .insertEntry(TEST_IFACE, 101, SET_DEFAULT, TAG_NONE, METERED_YES, ROAMING_NO,
DEFAULT_NETWORK_YES, 0L, 0L, 1024L, 8L, 11)
- .addEntry(TEST_IFACE, 102, SET_DEFAULT, TAG_NONE, METERED_NO, ROAMING_NO,
+ .insertEntry(TEST_IFACE, 102, SET_DEFAULT, TAG_NONE, METERED_NO, ROAMING_NO,
DEFAULT_NETWORK_NO, 1024L, 8L, 1024L, 8L, 12)
- .addEntry(TEST_IFACE, 102, SET_DEFAULT, TAG_NONE, METERED_YES, ROAMING_YES,
+ .insertEntry(TEST_IFACE, 102, SET_DEFAULT, TAG_NONE, METERED_YES, ROAMING_YES,
DEFAULT_NETWORK_YES, 1024L, 8L, 1024L, 8L, 12);
assertEquals(4, stats.findIndex(TEST_IFACE, 102, SET_DEFAULT, TAG_NONE, METERED_YES,
@@ -94,21 +94,21 @@
@Test
public void testFindIndexHinted() {
final NetworkStats stats = new NetworkStats(TEST_START, 3)
- .addEntry(TEST_IFACE, 100, SET_DEFAULT, TAG_NONE, METERED_NO, ROAMING_NO,
+ .insertEntry(TEST_IFACE, 100, SET_DEFAULT, TAG_NONE, METERED_NO, ROAMING_NO,
DEFAULT_NETWORK_YES, 1024L, 8L, 0L, 0L, 10)
- .addEntry(TEST_IFACE, 101, SET_DEFAULT, TAG_NONE, METERED_NO, ROAMING_NO,
+ .insertEntry(TEST_IFACE, 101, SET_DEFAULT, TAG_NONE, METERED_NO, ROAMING_NO,
DEFAULT_NETWORK_NO, 0L, 0L, 1024L, 8L, 11)
- .addEntry(TEST_IFACE, 102, SET_DEFAULT, TAG_NONE, METERED_NO, ROAMING_NO,
+ .insertEntry(TEST_IFACE, 102, SET_DEFAULT, TAG_NONE, METERED_NO, ROAMING_NO,
DEFAULT_NETWORK_YES, 1024L, 8L, 1024L, 8L, 12)
- .addEntry(TEST_IFACE2, 100, SET_FOREGROUND, TAG_NONE, METERED_NO, ROAMING_NO,
+ .insertEntry(TEST_IFACE2, 100, SET_FOREGROUND, TAG_NONE, METERED_NO, ROAMING_NO,
DEFAULT_NETWORK_NO, 1024L, 8L, 0L, 0L, 10)
- .addEntry(TEST_IFACE2, 101, SET_DEFAULT, 0xF00D, METERED_NO, ROAMING_NO,
+ .insertEntry(TEST_IFACE2, 101, SET_DEFAULT, 0xF00D, METERED_NO, ROAMING_NO,
DEFAULT_NETWORK_YES, 0L, 0L, 1024L, 8L, 11)
- .addEntry(TEST_IFACE2, 101, SET_DEFAULT, 0xF00D, METERED_YES, ROAMING_NO,
+ .insertEntry(TEST_IFACE2, 101, SET_DEFAULT, 0xF00D, METERED_YES, ROAMING_NO,
DEFAULT_NETWORK_NO, 0L, 0L, 1024L, 8L, 11)
- .addEntry(TEST_IFACE2, 102, SET_DEFAULT, TAG_NONE, METERED_NO, ROAMING_NO,
+ .insertEntry(TEST_IFACE2, 102, SET_DEFAULT, TAG_NONE, METERED_NO, ROAMING_NO,
DEFAULT_NETWORK_YES, 1024L, 8L, 1024L, 8L, 12)
- .addEntry(TEST_IFACE2, 102, SET_DEFAULT, TAG_NONE, METERED_YES, ROAMING_YES,
+ .insertEntry(TEST_IFACE2, 102, SET_DEFAULT, TAG_NONE, METERED_YES, ROAMING_YES,
DEFAULT_NETWORK_NO, 1024L, 8L, 1024L, 8L, 12);
// verify that we correctly find across regardless of hinting
@@ -143,27 +143,27 @@
assertEquals(0, stats.size());
assertEquals(4, stats.internalSize());
- stats.addEntry(TEST_IFACE, TEST_UID, SET_DEFAULT, TAG_NONE, METERED_NO, ROAMING_NO,
+ stats.insertEntry(TEST_IFACE, TEST_UID, SET_DEFAULT, TAG_NONE, METERED_NO, ROAMING_NO,
DEFAULT_NETWORK_YES, 1L, 1L, 2L, 2L, 3);
- stats.addEntry(TEST_IFACE, TEST_UID, SET_DEFAULT, TAG_NONE, METERED_NO, ROAMING_NO,
+ stats.insertEntry(TEST_IFACE, TEST_UID, SET_DEFAULT, TAG_NONE, METERED_NO, ROAMING_NO,
DEFAULT_NETWORK_NO, 2L, 2L, 2L, 2L, 4);
- stats.addEntry(TEST_IFACE, TEST_UID, SET_DEFAULT, TAG_NONE, METERED_NO, ROAMING_YES,
+ stats.insertEntry(TEST_IFACE, TEST_UID, SET_DEFAULT, TAG_NONE, METERED_NO, ROAMING_YES,
DEFAULT_NETWORK_YES, 3L, 3L, 2L, 2L, 5);
- stats.addEntry(TEST_IFACE, TEST_UID, SET_DEFAULT, TAG_NONE, METERED_YES, ROAMING_YES,
+ stats.insertEntry(TEST_IFACE, TEST_UID, SET_DEFAULT, TAG_NONE, METERED_YES, ROAMING_YES,
DEFAULT_NETWORK_NO, 3L, 3L, 2L, 2L, 5);
assertEquals(4, stats.size());
assertEquals(4, stats.internalSize());
- stats.addEntry(TEST_IFACE, TEST_UID, SET_DEFAULT, TAG_NONE, METERED_NO, ROAMING_NO,
+ stats.insertEntry(TEST_IFACE, TEST_UID, SET_DEFAULT, TAG_NONE, METERED_NO, ROAMING_NO,
DEFAULT_NETWORK_NO, 4L, 40L, 4L, 40L, 7);
- stats.addEntry(TEST_IFACE, TEST_UID, SET_DEFAULT, TAG_NONE, METERED_NO, ROAMING_NO,
+ stats.insertEntry(TEST_IFACE, TEST_UID, SET_DEFAULT, TAG_NONE, METERED_NO, ROAMING_NO,
DEFAULT_NETWORK_YES, 5L, 50L, 4L, 40L, 8);
- stats.addEntry(TEST_IFACE, TEST_UID, SET_DEFAULT, TAG_NONE, METERED_NO, ROAMING_NO,
+ stats.insertEntry(TEST_IFACE, TEST_UID, SET_DEFAULT, TAG_NONE, METERED_NO, ROAMING_NO,
DEFAULT_NETWORK_NO, 6L, 60L, 5L, 50L, 10);
- stats.addEntry(TEST_IFACE, TEST_UID, SET_DEFAULT, TAG_NONE, METERED_NO, ROAMING_YES,
+ stats.insertEntry(TEST_IFACE, TEST_UID, SET_DEFAULT, TAG_NONE, METERED_NO, ROAMING_YES,
DEFAULT_NETWORK_YES, 7L, 70L, 5L, 50L, 11);
- stats.addEntry(TEST_IFACE, TEST_UID, SET_DEFAULT, TAG_NONE, METERED_YES, ROAMING_YES,
+ stats.insertEntry(TEST_IFACE, TEST_UID, SET_DEFAULT, TAG_NONE, METERED_YES, ROAMING_YES,
DEFAULT_NETWORK_NO, 7L, 70L, 5L, 50L, 11);
assertEquals(9, stats.size());
@@ -193,8 +193,8 @@
public void testCombineExisting() throws Exception {
final NetworkStats stats = new NetworkStats(TEST_START, 10);
- stats.addEntry(TEST_IFACE, 1001, SET_DEFAULT, TAG_NONE, 512L, 4L, 256L, 2L, 10);
- stats.addEntry(TEST_IFACE, 1001, SET_DEFAULT, 0xff, 128L, 1L, 128L, 1L, 2);
+ stats.insertEntry(TEST_IFACE, 1001, SET_DEFAULT, TAG_NONE, 512L, 4L, 256L, 2L, 10);
+ stats.insertEntry(TEST_IFACE, 1001, SET_DEFAULT, 0xff, 128L, 1L, 128L, 1L, 2);
stats.combineValues(TEST_IFACE, 1001, SET_DEFAULT, TAG_NONE, -128L, -1L,
-128L, -1L, -1);
@@ -215,12 +215,12 @@
@Test
public void testSubtractIdenticalData() throws Exception {
final NetworkStats before = new NetworkStats(TEST_START, 2)
- .addEntry(TEST_IFACE, 100, SET_DEFAULT, TAG_NONE, 1024L, 8L, 0L, 0L, 11)
- .addEntry(TEST_IFACE, 101, SET_DEFAULT, TAG_NONE, 0L, 0L, 1024L, 8L, 12);
+ .insertEntry(TEST_IFACE, 100, SET_DEFAULT, TAG_NONE, 1024L, 8L, 0L, 0L, 11)
+ .insertEntry(TEST_IFACE, 101, SET_DEFAULT, TAG_NONE, 0L, 0L, 1024L, 8L, 12);
final NetworkStats after = new NetworkStats(TEST_START, 2)
- .addEntry(TEST_IFACE, 100, SET_DEFAULT, TAG_NONE, 1024L, 8L, 0L, 0L, 11)
- .addEntry(TEST_IFACE, 101, SET_DEFAULT, TAG_NONE, 0L, 0L, 1024L, 8L, 12);
+ .insertEntry(TEST_IFACE, 100, SET_DEFAULT, TAG_NONE, 1024L, 8L, 0L, 0L, 11)
+ .insertEntry(TEST_IFACE, 101, SET_DEFAULT, TAG_NONE, 0L, 0L, 1024L, 8L, 12);
final NetworkStats result = after.subtract(before);
@@ -234,12 +234,12 @@
@Test
public void testSubtractIdenticalRows() throws Exception {
final NetworkStats before = new NetworkStats(TEST_START, 2)
- .addEntry(TEST_IFACE, 100, SET_DEFAULT, TAG_NONE, 1024L, 8L, 0L, 0L, 11)
- .addEntry(TEST_IFACE, 101, SET_DEFAULT, TAG_NONE, 0L, 0L, 1024L, 8L, 12);
+ .insertEntry(TEST_IFACE, 100, SET_DEFAULT, TAG_NONE, 1024L, 8L, 0L, 0L, 11)
+ .insertEntry(TEST_IFACE, 101, SET_DEFAULT, TAG_NONE, 0L, 0L, 1024L, 8L, 12);
final NetworkStats after = new NetworkStats(TEST_START, 2)
- .addEntry(TEST_IFACE, 100, SET_DEFAULT, TAG_NONE, 1025L, 9L, 2L, 1L, 15)
- .addEntry(TEST_IFACE, 101, SET_DEFAULT, TAG_NONE, 3L, 1L, 1028L, 9L, 20);
+ .insertEntry(TEST_IFACE, 100, SET_DEFAULT, TAG_NONE, 1025L, 9L, 2L, 1L, 15)
+ .insertEntry(TEST_IFACE, 101, SET_DEFAULT, TAG_NONE, 3L, 1L, 1028L, 9L, 20);
final NetworkStats result = after.subtract(before);
@@ -253,13 +253,13 @@
@Test
public void testSubtractNewRows() throws Exception {
final NetworkStats before = new NetworkStats(TEST_START, 2)
- .addEntry(TEST_IFACE, 100, SET_DEFAULT, TAG_NONE, 1024L, 8L, 0L, 0L, 11)
- .addEntry(TEST_IFACE, 101, SET_DEFAULT, TAG_NONE, 0L, 0L, 1024L, 8L, 12);
+ .insertEntry(TEST_IFACE, 100, SET_DEFAULT, TAG_NONE, 1024L, 8L, 0L, 0L, 11)
+ .insertEntry(TEST_IFACE, 101, SET_DEFAULT, TAG_NONE, 0L, 0L, 1024L, 8L, 12);
final NetworkStats after = new NetworkStats(TEST_START, 3)
- .addEntry(TEST_IFACE, 100, SET_DEFAULT, TAG_NONE, 1024L, 8L, 0L, 0L, 11)
- .addEntry(TEST_IFACE, 101, SET_DEFAULT, TAG_NONE, 0L, 0L, 1024L, 8L, 12)
- .addEntry(TEST_IFACE, 102, SET_DEFAULT, TAG_NONE, 1024L, 8L, 1024L, 8L, 20);
+ .insertEntry(TEST_IFACE, 100, SET_DEFAULT, TAG_NONE, 1024L, 8L, 0L, 0L, 11)
+ .insertEntry(TEST_IFACE, 101, SET_DEFAULT, TAG_NONE, 0L, 0L, 1024L, 8L, 12)
+ .insertEntry(TEST_IFACE, 102, SET_DEFAULT, TAG_NONE, 1024L, 8L, 1024L, 8L, 20);
final NetworkStats result = after.subtract(before);
@@ -275,11 +275,11 @@
@Test
public void testSubtractMissingRows() throws Exception {
final NetworkStats before = new NetworkStats(TEST_START, 2)
- .addEntry(TEST_IFACE, UID_ALL, SET_DEFAULT, TAG_NONE, 1024L, 0L, 0L, 0L, 0)
- .addEntry(TEST_IFACE2, UID_ALL, SET_DEFAULT, TAG_NONE, 2048L, 0L, 0L, 0L, 0);
+ .insertEntry(TEST_IFACE, UID_ALL, SET_DEFAULT, TAG_NONE, 1024L, 0L, 0L, 0L, 0)
+ .insertEntry(TEST_IFACE2, UID_ALL, SET_DEFAULT, TAG_NONE, 2048L, 0L, 0L, 0L, 0);
final NetworkStats after = new NetworkStats(TEST_START, 1)
- .addEntry(TEST_IFACE2, UID_ALL, SET_DEFAULT, TAG_NONE, 2049L, 2L, 3L, 4L, 0);
+ .insertEntry(TEST_IFACE2, UID_ALL, SET_DEFAULT, TAG_NONE, 2049L, 2L, 3L, 4L, 0);
final NetworkStats result = after.subtract(before);
@@ -293,40 +293,40 @@
@Test
public void testTotalBytes() throws Exception {
final NetworkStats iface = new NetworkStats(TEST_START, 2)
- .addEntry(TEST_IFACE, UID_ALL, SET_DEFAULT, TAG_NONE, 128L, 0L, 0L, 0L, 0L)
- .addEntry(TEST_IFACE2, UID_ALL, SET_DEFAULT, TAG_NONE, 256L, 0L, 0L, 0L, 0L);
+ .insertEntry(TEST_IFACE, UID_ALL, SET_DEFAULT, TAG_NONE, 128L, 0L, 0L, 0L, 0L)
+ .insertEntry(TEST_IFACE2, UID_ALL, SET_DEFAULT, TAG_NONE, 256L, 0L, 0L, 0L, 0L);
assertEquals(384L, iface.getTotalBytes());
final NetworkStats uidSet = new NetworkStats(TEST_START, 3)
- .addEntry(TEST_IFACE, 100, SET_DEFAULT, TAG_NONE, 32L, 0L, 0L, 0L, 0L)
- .addEntry(TEST_IFACE, 101, SET_DEFAULT, TAG_NONE, 32L, 0L, 0L, 0L, 0L)
- .addEntry(TEST_IFACE, 101, SET_FOREGROUND, TAG_NONE, 32L, 0L, 0L, 0L, 0L);
+ .insertEntry(TEST_IFACE, 100, SET_DEFAULT, TAG_NONE, 32L, 0L, 0L, 0L, 0L)
+ .insertEntry(TEST_IFACE, 101, SET_DEFAULT, TAG_NONE, 32L, 0L, 0L, 0L, 0L)
+ .insertEntry(TEST_IFACE, 101, SET_FOREGROUND, TAG_NONE, 32L, 0L, 0L, 0L, 0L);
assertEquals(96L, uidSet.getTotalBytes());
final NetworkStats uidTag = new NetworkStats(TEST_START, 6)
- .addEntry(TEST_IFACE, 100, SET_DEFAULT, TAG_NONE, 16L, 0L, 0L, 0L, 0L)
- .addEntry(TEST_IFACE2, 100, SET_DEFAULT, TAG_NONE, 16L, 0L, 0L, 0L, 0L)
- .addEntry(TEST_IFACE2, 100, SET_DEFAULT, 0xF00D, 8L, 0L, 0L, 0L, 0L)
- .addEntry(TEST_IFACE2, 100, SET_FOREGROUND, TAG_NONE, 16L, 0L, 0L, 0L, 0L)
- .addEntry(TEST_IFACE, 101, SET_DEFAULT, TAG_NONE, 16L, 0L, 0L, 0L, 0L)
- .addEntry(TEST_IFACE, 101, SET_DEFAULT, 0xF00D, 8L, 0L, 0L, 0L, 0L);
+ .insertEntry(TEST_IFACE, 100, SET_DEFAULT, TAG_NONE, 16L, 0L, 0L, 0L, 0L)
+ .insertEntry(TEST_IFACE2, 100, SET_DEFAULT, TAG_NONE, 16L, 0L, 0L, 0L, 0L)
+ .insertEntry(TEST_IFACE2, 100, SET_DEFAULT, 0xF00D, 8L, 0L, 0L, 0L, 0L)
+ .insertEntry(TEST_IFACE2, 100, SET_FOREGROUND, TAG_NONE, 16L, 0L, 0L, 0L, 0L)
+ .insertEntry(TEST_IFACE, 101, SET_DEFAULT, TAG_NONE, 16L, 0L, 0L, 0L, 0L)
+ .insertEntry(TEST_IFACE, 101, SET_DEFAULT, 0xF00D, 8L, 0L, 0L, 0L, 0L);
assertEquals(64L, uidTag.getTotalBytes());
final NetworkStats uidMetered = new NetworkStats(TEST_START, 3)
- .addEntry(TEST_IFACE, 100, SET_DEFAULT, TAG_NONE, METERED_NO, ROAMING_NO,
+ .insertEntry(TEST_IFACE, 100, SET_DEFAULT, TAG_NONE, METERED_NO, ROAMING_NO,
DEFAULT_NETWORK_YES, 32L, 0L, 0L, 0L, 0L)
- .addEntry(TEST_IFACE, 101, SET_DEFAULT, TAG_NONE, METERED_YES, ROAMING_NO,
+ .insertEntry(TEST_IFACE, 101, SET_DEFAULT, TAG_NONE, METERED_YES, ROAMING_NO,
DEFAULT_NETWORK_NO, 32L, 0L, 0L, 0L, 0L)
- .addEntry(TEST_IFACE, 101, SET_DEFAULT, TAG_NONE, METERED_YES, ROAMING_NO,
+ .insertEntry(TEST_IFACE, 101, SET_DEFAULT, TAG_NONE, METERED_YES, ROAMING_NO,
DEFAULT_NETWORK_YES, 32L, 0L, 0L, 0L, 0L);
assertEquals(96L, uidMetered.getTotalBytes());
final NetworkStats uidRoaming = new NetworkStats(TEST_START, 3)
- .addEntry(TEST_IFACE, 100, SET_DEFAULT, TAG_NONE, METERED_NO, ROAMING_NO,
+ .insertEntry(TEST_IFACE, 100, SET_DEFAULT, TAG_NONE, METERED_NO, ROAMING_NO,
DEFAULT_NETWORK_YES, 32L, 0L, 0L, 0L, 0L)
- .addEntry(TEST_IFACE, 101, SET_DEFAULT, TAG_NONE, METERED_YES, ROAMING_NO,
+ .insertEntry(TEST_IFACE, 101, SET_DEFAULT, TAG_NONE, METERED_YES, ROAMING_NO,
DEFAULT_NETWORK_NO, 32L, 0L, 0L, 0L, 0L)
- .addEntry(TEST_IFACE, 101, SET_DEFAULT, TAG_NONE, METERED_NO, ROAMING_YES,
+ .insertEntry(TEST_IFACE, 101, SET_DEFAULT, TAG_NONE, METERED_NO, ROAMING_YES,
DEFAULT_NETWORK_YES, 32L, 0L, 0L, 0L, 0L);
assertEquals(96L, uidRoaming.getTotalBytes());
}
@@ -343,11 +343,11 @@
@Test
public void testGroupedByIfaceAll() throws Exception {
final NetworkStats uidStats = new NetworkStats(TEST_START, 3)
- .addEntry(IFACE_ALL, 100, SET_ALL, TAG_NONE, METERED_NO, ROAMING_NO,
+ .insertEntry(IFACE_ALL, 100, SET_ALL, TAG_NONE, METERED_NO, ROAMING_NO,
DEFAULT_NETWORK_YES, 128L, 8L, 0L, 2L, 20L)
- .addEntry(IFACE_ALL, 101, SET_FOREGROUND, TAG_NONE, METERED_YES, ROAMING_NO,
+ .insertEntry(IFACE_ALL, 101, SET_FOREGROUND, TAG_NONE, METERED_YES, ROAMING_NO,
DEFAULT_NETWORK_NO, 128L, 8L, 0L, 2L, 20L)
- .addEntry(IFACE_ALL, 101, SET_ALL, TAG_NONE, METERED_NO, ROAMING_YES,
+ .insertEntry(IFACE_ALL, 101, SET_ALL, TAG_NONE, METERED_NO, ROAMING_YES,
DEFAULT_NETWORK_YES, 128L, 8L, 0L, 2L, 20L);
final NetworkStats grouped = uidStats.groupedByIface();
@@ -361,19 +361,19 @@
@Test
public void testGroupedByIface() throws Exception {
final NetworkStats uidStats = new NetworkStats(TEST_START, 7)
- .addEntry(TEST_IFACE, 100, SET_DEFAULT, TAG_NONE, METERED_NO, ROAMING_NO,
+ .insertEntry(TEST_IFACE, 100, SET_DEFAULT, TAG_NONE, METERED_NO, ROAMING_NO,
DEFAULT_NETWORK_YES, 128L, 8L, 0L, 2L, 20L)
- .addEntry(TEST_IFACE2, 100, SET_DEFAULT, TAG_NONE, METERED_NO, ROAMING_NO,
+ .insertEntry(TEST_IFACE2, 100, SET_DEFAULT, TAG_NONE, METERED_NO, ROAMING_NO,
DEFAULT_NETWORK_NO, 512L, 32L, 0L, 0L, 0L)
- .addEntry(TEST_IFACE2, 100, SET_DEFAULT, 0xF00D, METERED_NO, ROAMING_NO,
+ .insertEntry(TEST_IFACE2, 100, SET_DEFAULT, 0xF00D, METERED_NO, ROAMING_NO,
DEFAULT_NETWORK_YES, 64L, 4L, 0L, 0L, 0L)
- .addEntry(TEST_IFACE2, 100, SET_FOREGROUND, TAG_NONE, METERED_NO, ROAMING_NO,
+ .insertEntry(TEST_IFACE2, 100, SET_FOREGROUND, TAG_NONE, METERED_NO, ROAMING_NO,
DEFAULT_NETWORK_NO, 512L, 32L, 0L, 0L, 0L)
- .addEntry(TEST_IFACE, 101, SET_DEFAULT, TAG_NONE, METERED_NO, ROAMING_NO,
+ .insertEntry(TEST_IFACE, 101, SET_DEFAULT, TAG_NONE, METERED_NO, ROAMING_NO,
DEFAULT_NETWORK_YES, 128L, 8L, 0L, 0L, 0L)
- .addEntry(TEST_IFACE, 101, SET_DEFAULT, 0xF00D, METERED_YES, ROAMING_NO,
+ .insertEntry(TEST_IFACE, 101, SET_DEFAULT, 0xF00D, METERED_YES, ROAMING_NO,
DEFAULT_NETWORK_NO, 128L, 8L, 0L, 0L, 0L)
- .addEntry(TEST_IFACE, 101, SET_DEFAULT, TAG_NONE, METERED_NO, ROAMING_YES,
+ .insertEntry(TEST_IFACE, 101, SET_DEFAULT, TAG_NONE, METERED_NO, ROAMING_YES,
DEFAULT_NETWORK_YES, 128L, 8L, 0L, 0L, 0L);
final NetworkStats grouped = uidStats.groupedByIface();
@@ -390,19 +390,19 @@
@Test
public void testAddAllValues() {
final NetworkStats first = new NetworkStats(TEST_START, 5)
- .addEntry(TEST_IFACE, 100, SET_DEFAULT, TAG_NONE, METERED_YES, ROAMING_NO,
+ .insertEntry(TEST_IFACE, 100, SET_DEFAULT, TAG_NONE, METERED_YES, ROAMING_NO,
DEFAULT_NETWORK_YES, 32L, 0L, 0L, 0L, 0L)
- .addEntry(TEST_IFACE, 100, SET_FOREGROUND, TAG_NONE, METERED_NO, ROAMING_NO,
+ .insertEntry(TEST_IFACE, 100, SET_FOREGROUND, TAG_NONE, METERED_NO, ROAMING_NO,
DEFAULT_NETWORK_NO, 32L, 0L, 0L, 0L, 0L)
- .addEntry(TEST_IFACE, 100, SET_FOREGROUND, TAG_NONE, METERED_YES, ROAMING_YES,
+ .insertEntry(TEST_IFACE, 100, SET_FOREGROUND, TAG_NONE, METERED_YES, ROAMING_YES,
DEFAULT_NETWORK_YES, 32L, 0L, 0L, 0L, 0L);
final NetworkStats second = new NetworkStats(TEST_START, 2)
- .addEntry(TEST_IFACE, 100, SET_DEFAULT, TAG_NONE, METERED_YES, ROAMING_NO,
+ .insertEntry(TEST_IFACE, 100, SET_DEFAULT, TAG_NONE, METERED_YES, ROAMING_NO,
DEFAULT_NETWORK_YES, 32L, 0L, 0L, 0L, 0L)
- .addEntry(TEST_IFACE2, UID_ALL, SET_DEFAULT, TAG_NONE, METERED_NO, ROAMING_NO,
+ .insertEntry(TEST_IFACE2, UID_ALL, SET_DEFAULT, TAG_NONE, METERED_NO, ROAMING_NO,
DEFAULT_NETWORK_NO, 32L, 0L, 0L, 0L, 0L)
- .addEntry(TEST_IFACE, 100, SET_FOREGROUND, TAG_NONE, METERED_YES, ROAMING_YES,
+ .insertEntry(TEST_IFACE, 100, SET_FOREGROUND, TAG_NONE, METERED_YES, ROAMING_YES,
DEFAULT_NETWORK_YES, 32L, 0L, 0L, 0L, 0L);
first.combineAllValues(second);
@@ -421,19 +421,19 @@
@Test
public void testGetTotal() {
final NetworkStats stats = new NetworkStats(TEST_START, 7)
- .addEntry(TEST_IFACE, 100, SET_DEFAULT, TAG_NONE, METERED_NO, ROAMING_NO,
+ .insertEntry(TEST_IFACE, 100, SET_DEFAULT, TAG_NONE, METERED_NO, ROAMING_NO,
DEFAULT_NETWORK_YES, 128L, 8L, 0L, 2L, 20L)
- .addEntry(TEST_IFACE2, 100, SET_DEFAULT, TAG_NONE, METERED_NO, ROAMING_NO,
+ .insertEntry(TEST_IFACE2, 100, SET_DEFAULT, TAG_NONE, METERED_NO, ROAMING_NO,
DEFAULT_NETWORK_NO, 512L, 32L, 0L, 0L, 0L)
- .addEntry(TEST_IFACE2, 100, SET_DEFAULT, 0xF00D, METERED_NO, ROAMING_NO,
+ .insertEntry(TEST_IFACE2, 100, SET_DEFAULT, 0xF00D, METERED_NO, ROAMING_NO,
DEFAULT_NETWORK_YES, 64L, 4L, 0L, 0L, 0L)
- .addEntry(TEST_IFACE2, 100, SET_FOREGROUND, TAG_NONE, METERED_NO, ROAMING_NO,
+ .insertEntry(TEST_IFACE2, 100, SET_FOREGROUND, TAG_NONE, METERED_NO, ROAMING_NO,
DEFAULT_NETWORK_NO, 512L,32L, 0L, 0L, 0L)
- .addEntry(TEST_IFACE, 101, SET_DEFAULT, TAG_NONE, METERED_YES, ROAMING_NO,
+ .insertEntry(TEST_IFACE, 101, SET_DEFAULT, TAG_NONE, METERED_YES, ROAMING_NO,
DEFAULT_NETWORK_YES, 128L, 8L, 0L, 0L, 0L)
- .addEntry(TEST_IFACE, 101, SET_DEFAULT, 0xF00D, METERED_NO, ROAMING_NO,
+ .insertEntry(TEST_IFACE, 101, SET_DEFAULT, 0xF00D, METERED_NO, ROAMING_NO,
DEFAULT_NETWORK_NO, 128L, 8L, 0L, 0L, 0L)
- .addEntry(TEST_IFACE, 100, SET_DEFAULT, TAG_NONE, METERED_NO, ROAMING_YES,
+ .insertEntry(TEST_IFACE, 100, SET_DEFAULT, TAG_NONE, METERED_NO, ROAMING_YES,
DEFAULT_NETWORK_NO, 128L, 8L, 0L, 0L, 0L);
assertValues(stats.getTotal(null), 1408L, 88L, 0L, 2L, 20L);
@@ -459,7 +459,7 @@
assertEquals(0, after.size());
// Test 1 item stats.
- before.addEntry(TEST_IFACE, 99, SET_DEFAULT, TAG_NONE, 1L, 128L, 0L, 2L, 20L);
+ before.insertEntry(TEST_IFACE, 99, SET_DEFAULT, TAG_NONE, 1L, 128L, 0L, 2L, 20L);
after = before.clone();
after.removeUids(new int[0]);
assertEquals(1, after.size());
@@ -469,12 +469,12 @@
assertEquals(0, after.size());
// Append remaining test items.
- before.addEntry(TEST_IFACE, 100, SET_DEFAULT, TAG_NONE, 2L, 64L, 0L, 2L, 20L)
- .addEntry(TEST_IFACE2, 100, SET_DEFAULT, TAG_NONE, 4L, 32L, 0L, 0L, 0L)
- .addEntry(TEST_IFACE2, 100, SET_DEFAULT, 0xF00D, 8L, 16L, 0L, 0L, 0L)
- .addEntry(TEST_IFACE2, 100, SET_FOREGROUND, TAG_NONE, 16L, 8L, 0L, 0L, 0L)
- .addEntry(TEST_IFACE, 101, SET_DEFAULT, TAG_NONE, 32L, 4L, 0L, 0L, 0L)
- .addEntry(TEST_IFACE, 101, SET_DEFAULT, 0xF00D, 64L, 2L, 0L, 0L, 0L);
+ before.insertEntry(TEST_IFACE, 100, SET_DEFAULT, TAG_NONE, 2L, 64L, 0L, 2L, 20L)
+ .insertEntry(TEST_IFACE2, 100, SET_DEFAULT, TAG_NONE, 4L, 32L, 0L, 0L, 0L)
+ .insertEntry(TEST_IFACE2, 100, SET_DEFAULT, 0xF00D, 8L, 16L, 0L, 0L, 0L)
+ .insertEntry(TEST_IFACE2, 100, SET_FOREGROUND, TAG_NONE, 16L, 8L, 0L, 0L, 0L)
+ .insertEntry(TEST_IFACE, 101, SET_DEFAULT, TAG_NONE, 32L, 4L, 0L, 0L, 0L)
+ .insertEntry(TEST_IFACE, 101, SET_DEFAULT, 0xF00D, 64L, 2L, 0L, 0L, 0L);
assertEquals(7, before.size());
// Test remove with empty uid list.
@@ -505,12 +505,12 @@
@Test
public void testClone() throws Exception {
final NetworkStats original = new NetworkStats(TEST_START, 5)
- .addEntry(TEST_IFACE, 100, SET_DEFAULT, TAG_NONE, 128L, 8L, 0L, 2L, 20L)
- .addEntry(TEST_IFACE2, 100, SET_DEFAULT, TAG_NONE, 512L, 32L, 0L, 0L, 0L);
+ .insertEntry(TEST_IFACE, 100, SET_DEFAULT, TAG_NONE, 128L, 8L, 0L, 2L, 20L)
+ .insertEntry(TEST_IFACE2, 100, SET_DEFAULT, TAG_NONE, 512L, 32L, 0L, 0L, 0L);
// make clone and mutate original
final NetworkStats clone = original.clone();
- original.addEntry(TEST_IFACE, 101, SET_DEFAULT, TAG_NONE, 128L, 8L, 0L, 0L, 0L);
+ original.insertEntry(TEST_IFACE, 101, SET_DEFAULT, TAG_NONE, 128L, 8L, 0L, 0L, 0L);
assertEquals(3, original.size());
assertEquals(2, clone.size());
@@ -523,8 +523,8 @@
public void testAddWhenEmpty() throws Exception {
final NetworkStats red = new NetworkStats(TEST_START, -1);
final NetworkStats blue = new NetworkStats(TEST_START, 5)
- .addEntry(TEST_IFACE, 100, SET_DEFAULT, TAG_NONE, 128L, 8L, 0L, 2L, 20L)
- .addEntry(TEST_IFACE2, 100, SET_DEFAULT, TAG_NONE, 512L, 32L, 0L, 0L, 0L);
+ .insertEntry(TEST_IFACE, 100, SET_DEFAULT, TAG_NONE, 128L, 8L, 0L, 2L, 20L)
+ .insertEntry(TEST_IFACE2, 100, SET_DEFAULT, TAG_NONE, 512L, 32L, 0L, 0L, 0L);
// We're mostly checking that we don't crash
red.combineAllValues(blue);
@@ -537,37 +537,37 @@
final String underlyingIface = "wlan0";
final int testTag1 = 8888;
NetworkStats delta = new NetworkStats(TEST_START, 17)
- .addEntry(tunIface, 10100, SET_DEFAULT, TAG_NONE, METERED_NO, ROAMING_NO,
+ .insertEntry(tunIface, 10100, SET_DEFAULT, TAG_NONE, METERED_NO, ROAMING_NO,
DEFAULT_NETWORK_NO, 39605L, 46L, 12259L, 55L, 0L)
- .addEntry(tunIface, 10100, SET_FOREGROUND, TAG_NONE, METERED_NO, ROAMING_NO,
+ .insertEntry(tunIface, 10100, SET_FOREGROUND, TAG_NONE, METERED_NO, ROAMING_NO,
DEFAULT_NETWORK_NO, 0L, 0L, 0L, 0L, 0L)
- .addEntry(tunIface, 10120, SET_DEFAULT, TAG_NONE, METERED_NO, ROAMING_NO,
+ .insertEntry(tunIface, 10120, SET_DEFAULT, TAG_NONE, METERED_NO, ROAMING_NO,
DEFAULT_NETWORK_NO, 72667L, 197L, 43909L, 241L, 0L)
- .addEntry(tunIface, 10120, SET_FOREGROUND, TAG_NONE, METERED_NO, ROAMING_NO,
+ .insertEntry(tunIface, 10120, SET_FOREGROUND, TAG_NONE, METERED_NO, ROAMING_NO,
DEFAULT_NETWORK_NO, 9297L, 17L, 4128L, 21L, 0L)
// VPN package also uses some traffic through unprotected network.
- .addEntry(tunIface, tunUid, SET_DEFAULT, TAG_NONE, METERED_NO, ROAMING_NO,
+ .insertEntry(tunIface, tunUid, SET_DEFAULT, TAG_NONE, METERED_NO, ROAMING_NO,
DEFAULT_NETWORK_NO, 4983L, 10L, 1801L, 12L, 0L)
- .addEntry(tunIface, tunUid, SET_FOREGROUND, TAG_NONE, METERED_NO, ROAMING_NO,
+ .insertEntry(tunIface, tunUid, SET_FOREGROUND, TAG_NONE, METERED_NO, ROAMING_NO,
DEFAULT_NETWORK_NO, 0L, 0L, 0L, 0L, 0L)
// Tag entries
- .addEntry(tunIface, 10120, SET_DEFAULT, testTag1, METERED_NO, ROAMING_NO,
+ .insertEntry(tunIface, 10120, SET_DEFAULT, testTag1, METERED_NO, ROAMING_NO,
DEFAULT_NETWORK_NO, 21691L, 41L, 13820L, 51L, 0L)
- .addEntry(tunIface, 10120, SET_FOREGROUND, testTag1, METERED_NO, ROAMING_NO,
+ .insertEntry(tunIface, 10120, SET_FOREGROUND, testTag1, METERED_NO, ROAMING_NO,
DEFAULT_NETWORK_NO, 1281L, 2L, 665L, 2L, 0L)
// Irrelevant entries
- .addEntry(TEST_IFACE, 10100, SET_DEFAULT, TAG_NONE, METERED_NO, ROAMING_NO,
+ .insertEntry(TEST_IFACE, 10100, SET_DEFAULT, TAG_NONE, METERED_NO, ROAMING_NO,
DEFAULT_NETWORK_NO, 1685L, 5L, 2070L, 6L, 0L)
// Underlying Iface entries
- .addEntry(underlyingIface, 10100, SET_DEFAULT, TAG_NONE, METERED_NO, ROAMING_NO,
+ .insertEntry(underlyingIface, 10100, SET_DEFAULT, TAG_NONE, METERED_NO, ROAMING_NO,
DEFAULT_NETWORK_NO, 5178L, 8L, 2139L, 11L, 0L)
- .addEntry(underlyingIface, 10100, SET_FOREGROUND, TAG_NONE, METERED_NO, ROAMING_NO,
- DEFAULT_NETWORK_NO, 0L, 0L, 0L, 0L, 0L)
- .addEntry(underlyingIface, tunUid, SET_DEFAULT, TAG_NONE, METERED_NO, ROAMING_NO,
+ .insertEntry(underlyingIface, 10100, SET_FOREGROUND, TAG_NONE, METERED_NO,
+ ROAMING_NO, DEFAULT_NETWORK_NO, 0L, 0L, 0L, 0L, 0L)
+ .insertEntry(underlyingIface, tunUid, SET_DEFAULT, TAG_NONE, METERED_NO, ROAMING_NO,
DEFAULT_NETWORK_NO, 149873L, 287L, 59217L /* smaller than sum(tun0) */,
299L /* smaller than sum(tun0) */, 0L)
- .addEntry(underlyingIface, tunUid, SET_FOREGROUND, TAG_NONE, METERED_NO, ROAMING_NO,
- DEFAULT_NETWORK_NO, 0L, 0L, 0L, 0L, 0L);
+ .insertEntry(underlyingIface, tunUid, SET_FOREGROUND, TAG_NONE, METERED_NO,
+ ROAMING_NO, DEFAULT_NETWORK_NO, 0L, 0L, 0L, 0L, 0L);
delta.migrateTun(tunUid, tunIface, new String[]{underlyingIface});
assertEquals(20, delta.size());
@@ -635,19 +635,19 @@
final String underlyingIface = "wlan0";
NetworkStats delta = new NetworkStats(TEST_START, 9)
// 2 different apps sent/receive data via tun0.
- .addEntry(tunIface, 10100, SET_DEFAULT, TAG_NONE, METERED_NO, ROAMING_NO,
+ .insertEntry(tunIface, 10100, SET_DEFAULT, TAG_NONE, METERED_NO, ROAMING_NO,
DEFAULT_NETWORK_NO, 50000L, 25L, 100000L, 50L, 0L)
- .addEntry(tunIface, 20100, SET_DEFAULT, TAG_NONE, METERED_NO, ROAMING_NO,
+ .insertEntry(tunIface, 20100, SET_DEFAULT, TAG_NONE, METERED_NO, ROAMING_NO,
DEFAULT_NETWORK_NO, 500L, 2L, 200L, 5L, 0L)
// VPN package resends data through the tunnel (with exaggerated overhead)
- .addEntry(tunIface, tunUid, SET_DEFAULT, TAG_NONE, METERED_NO, ROAMING_NO,
+ .insertEntry(tunIface, tunUid, SET_DEFAULT, TAG_NONE, METERED_NO, ROAMING_NO,
DEFAULT_NETWORK_NO, 240000, 100L, 120000L, 60L, 0L)
// 1 app already has some traffic on the underlying interface, the other doesn't yet
- .addEntry(underlyingIface, 10100, SET_DEFAULT, TAG_NONE, METERED_NO, ROAMING_NO,
+ .insertEntry(underlyingIface, 10100, SET_DEFAULT, TAG_NONE, METERED_NO, ROAMING_NO,
DEFAULT_NETWORK_NO, 1000L, 10L, 2000L, 20L, 0L)
// Traffic through the underlying interface via the vpn app.
// This test should redistribute this data correctly.
- .addEntry(underlyingIface, tunUid, SET_DEFAULT, TAG_NONE, METERED_NO, ROAMING_NO,
+ .insertEntry(underlyingIface, tunUid, SET_DEFAULT, TAG_NONE, METERED_NO, ROAMING_NO,
DEFAULT_NETWORK_NO, 75500L, 37L, 130000L, 70L, 0L);
delta.migrateTun(tunUid, tunIface, new String[]{underlyingIface});
@@ -697,9 +697,9 @@
DEFAULT_NETWORK_NO, 50000L, 25L, 100000L, 50L, 0L);
NetworkStats stats = new NetworkStats(TEST_START, 3)
- .addEntry(entry1)
- .addEntry(entry2)
- .addEntry(entry3);
+ .insertEntry(entry1)
+ .insertEntry(entry2)
+ .insertEntry(entry3);
stats.filter(UID_ALL, INTERFACES_ALL, TAG_ALL);
assertEquals(3, stats.size());
@@ -724,9 +724,9 @@
DEFAULT_NETWORK_NO, 50000L, 25L, 100000L, 50L, 0L);
NetworkStats stats = new NetworkStats(TEST_START, 3)
- .addEntry(entry1)
- .addEntry(entry2)
- .addEntry(entry3);
+ .insertEntry(entry1)
+ .insertEntry(entry2)
+ .insertEntry(entry3);
stats.filter(testUid, INTERFACES_ALL, TAG_ALL);
assertEquals(2, stats.size());
@@ -755,10 +755,10 @@
DEFAULT_NETWORK_NO, 50000L, 25L, 100000L, 50L, 0L);
NetworkStats stats = new NetworkStats(TEST_START, 4)
- .addEntry(entry1)
- .addEntry(entry2)
- .addEntry(entry3)
- .addEntry(entry4);
+ .insertEntry(entry1)
+ .insertEntry(entry2)
+ .insertEntry(entry3)
+ .insertEntry(entry4);
stats.filter(UID_ALL, new String[] { testIf1, testIf2 }, TAG_ALL);
assertEquals(3, stats.size());
@@ -778,8 +778,8 @@
DEFAULT_NETWORK_NO, 50000L, 25L, 100000L, 50L, 0L);
NetworkStats stats = new NetworkStats(TEST_START, 3)
- .addEntry(entry1)
- .addEntry(entry2);
+ .insertEntry(entry1)
+ .insertEntry(entry2);
stats.filter(UID_ALL, new String[] { }, TAG_ALL);
assertEquals(0, stats.size());
@@ -802,9 +802,9 @@
DEFAULT_NETWORK_NO, 50000L, 25L, 100000L, 50L, 0L);
NetworkStats stats = new NetworkStats(TEST_START, 3)
- .addEntry(entry1)
- .addEntry(entry2)
- .addEntry(entry3);
+ .insertEntry(entry1)
+ .insertEntry(entry2)
+ .insertEntry(entry3);
stats.filter(UID_ALL, INTERFACES_ALL, testTag);
assertEquals(2, stats.size());
@@ -831,10 +831,10 @@
DEFAULT_NETWORK_NO, 50000L, 25L, 100000L, 50L, 0L);
NetworkStats stats = new NetworkStats(TEST_START, 4)
- .addEntry(entry1)
- .addEntry(entry2)
- .addEntry(entry3)
- .addEntry(entry4);
+ .insertEntry(entry1)
+ .insertEntry(entry2)
+ .insertEntry(entry3)
+ .insertEntry(entry4);
stats.filterDebugEntries();
@@ -891,14 +891,14 @@
0 /* operations */);
final NetworkStats statsXt = new NetworkStats(TEST_START, 3)
- .addEntry(appEntry)
- .addEntry(xtRootUidEntry)
- .addEntry(otherEntry);
+ .insertEntry(appEntry)
+ .insertEntry(xtRootUidEntry)
+ .insertEntry(otherEntry);
final NetworkStats statsEbpf = new NetworkStats(TEST_START, 3)
- .addEntry(appEntry)
- .addEntry(ebpfRootUidEntry)
- .addEntry(otherEntry);
+ .insertEntry(appEntry)
+ .insertEntry(ebpfRootUidEntry)
+ .insertEntry(otherEntry);
statsXt.apply464xlatAdjustments(stackedIface, false);
statsEbpf.apply464xlatAdjustments(stackedIface, true);
@@ -945,8 +945,8 @@
0 /* operations */);
NetworkStats stats = new NetworkStats(TEST_START, 2)
- .addEntry(firstEntry)
- .addEntry(secondEntry);
+ .insertEntry(firstEntry)
+ .insertEntry(secondEntry);
// Empty map: no adjustment
stats.apply464xlatAdjustments(new ArrayMap<>(), false);
diff --git a/tests/net/java/com/android/server/ConnectivityServiceTest.java b/tests/net/java/com/android/server/ConnectivityServiceTest.java
index c21772a..44216e8 100644
--- a/tests/net/java/com/android/server/ConnectivityServiceTest.java
+++ b/tests/net/java/com/android/server/ConnectivityServiceTest.java
@@ -2464,8 +2464,8 @@
final MockNetworkFactory testFactory = new MockNetworkFactory(handlerThread.getLooper(),
mServiceContext, "testFactory", filter);
// Register the factory and don't be surprised when the default request arrives.
- testFactory.register();
testFactory.expectAddRequestsWithScores(0);
+ testFactory.register();
testFactory.waitForNetworkRequests(1);
testFactory.setScoreFilter(42);
diff --git a/tests/net/java/com/android/server/net/NetworkStatsObserversTest.java b/tests/net/java/com/android/server/net/NetworkStatsObserversTest.java
index f0e5774..a6f7a36 100644
--- a/tests/net/java/com/android/server/net/NetworkStatsObserversTest.java
+++ b/tests/net/java/com/android/server/net/NetworkStatsObserversTest.java
@@ -240,7 +240,7 @@
// Baseline
NetworkStats xtSnapshot = new NetworkStats(TEST_START, 1 /* initialSize */)
- .addIfaceValues(TEST_IFACE, BASE_BYTES, 8L, BASE_BYTES, 16L);
+ .insertEntry(TEST_IFACE, BASE_BYTES, 8L, BASE_BYTES, 16L);
NetworkStats uidSnapshot = null;
mStatsObservers.updateStats(
@@ -264,14 +264,14 @@
// Baseline
NetworkStats xtSnapshot = new NetworkStats(TEST_START, 1 /* initialSize */)
- .addIfaceValues(TEST_IFACE, BASE_BYTES, 8L, BASE_BYTES, 16L);
+ .insertEntry(TEST_IFACE, BASE_BYTES, 8L, BASE_BYTES, 16L);
NetworkStats uidSnapshot = null;
mStatsObservers.updateStats(
xtSnapshot, uidSnapshot, mActiveIfaces, mActiveUidIfaces, TEST_START);
// Delta
xtSnapshot = new NetworkStats(TEST_START, 1 /* initialSize */)
- .addIfaceValues(TEST_IFACE, BASE_BYTES + 1024L, 10L, BASE_BYTES + 2048L, 20L);
+ .insertEntry(TEST_IFACE, BASE_BYTES + 1024L, 10L, BASE_BYTES + 2048L, 20L);
mStatsObservers.updateStats(
xtSnapshot, uidSnapshot, mActiveIfaces, mActiveUidIfaces, TEST_START);
waitForObserverToIdle();
@@ -294,14 +294,14 @@
// Baseline
NetworkStats xtSnapshot = new NetworkStats(TEST_START, 1 /* initialSize */)
- .addIfaceValues(TEST_IFACE, BASE_BYTES, 8L, BASE_BYTES, 16L);
+ .insertEntry(TEST_IFACE, BASE_BYTES, 8L, BASE_BYTES, 16L);
NetworkStats uidSnapshot = null;
mStatsObservers.updateStats(
xtSnapshot, uidSnapshot, mActiveIfaces, mActiveUidIfaces, TEST_START);
// Delta
xtSnapshot = new NetworkStats(TEST_START + MINUTE_IN_MILLIS, 1 /* initialSize */)
- .addIfaceValues(TEST_IFACE, BASE_BYTES + THRESHOLD_BYTES, 12L,
+ .insertEntry(TEST_IFACE, BASE_BYTES + THRESHOLD_BYTES, 12L,
BASE_BYTES + THRESHOLD_BYTES, 22L);
mStatsObservers.updateStats(
xtSnapshot, uidSnapshot, mActiveIfaces, mActiveUidIfaces, TEST_START);
@@ -326,14 +326,14 @@
// Baseline
NetworkStats xtSnapshot = null;
NetworkStats uidSnapshot = new NetworkStats(TEST_START, 2 /* initialSize */)
- .addEntry(TEST_IFACE, UID_RED, SET_DEFAULT, TAG_NONE, METERED_NO, ROAMING_NO,
+ .insertEntry(TEST_IFACE, UID_RED, SET_DEFAULT, TAG_NONE, METERED_NO, ROAMING_NO,
DEFAULT_NETWORK_YES, BASE_BYTES, 2L, BASE_BYTES, 2L, 0L);
mStatsObservers.updateStats(
xtSnapshot, uidSnapshot, mActiveIfaces, mActiveUidIfaces, TEST_START);
// Delta
uidSnapshot = new NetworkStats(TEST_START + 2 * MINUTE_IN_MILLIS, 2 /* initialSize */)
- .addEntry(TEST_IFACE, UID_RED, SET_DEFAULT, TAG_NONE, METERED_NO, ROAMING_NO,
+ .insertEntry(TEST_IFACE, UID_RED, SET_DEFAULT, TAG_NONE, METERED_NO, ROAMING_NO,
DEFAULT_NETWORK_NO, BASE_BYTES + THRESHOLD_BYTES, 2L,
BASE_BYTES + THRESHOLD_BYTES, 2L, 0L);
mStatsObservers.updateStats(
@@ -359,14 +359,14 @@
// Baseline
NetworkStats xtSnapshot = null;
NetworkStats uidSnapshot = new NetworkStats(TEST_START, 2 /* initialSize */)
- .addEntry(TEST_IFACE, UID_RED, SET_DEFAULT, TAG_NONE, METERED_NO, ROAMING_NO,
+ .insertEntry(TEST_IFACE, UID_RED, SET_DEFAULT, TAG_NONE, METERED_NO, ROAMING_NO,
DEFAULT_NETWORK_NO, BASE_BYTES, 2L, BASE_BYTES, 2L, 0L);
mStatsObservers.updateStats(
xtSnapshot, uidSnapshot, mActiveIfaces, mActiveUidIfaces, TEST_START);
// Delta
uidSnapshot = new NetworkStats(TEST_START + 2 * MINUTE_IN_MILLIS, 2 /* initialSize */)
- .addEntry(TEST_IFACE, UID_RED, SET_DEFAULT, TAG_NONE, METERED_NO, ROAMING_NO,
+ .insertEntry(TEST_IFACE, UID_RED, SET_DEFAULT, TAG_NONE, METERED_NO, ROAMING_NO,
DEFAULT_NETWORK_NO, BASE_BYTES + THRESHOLD_BYTES, 2L,
BASE_BYTES + THRESHOLD_BYTES, 2L, 0L);
mStatsObservers.updateStats(
@@ -391,14 +391,14 @@
// Baseline
NetworkStats xtSnapshot = null;
NetworkStats uidSnapshot = new NetworkStats(TEST_START, 2 /* initialSize */)
- .addEntry(TEST_IFACE, UID_RED, SET_DEFAULT, TAG_NONE, METERED_NO, ROAMING_NO,
+ .insertEntry(TEST_IFACE, UID_RED, SET_DEFAULT, TAG_NONE, METERED_NO, ROAMING_NO,
DEFAULT_NETWORK_YES, BASE_BYTES, 2L, BASE_BYTES, 2L, 0L);
mStatsObservers.updateStats(
xtSnapshot, uidSnapshot, mActiveIfaces, mActiveUidIfaces, TEST_START);
// Delta
uidSnapshot = new NetworkStats(TEST_START + 2 * MINUTE_IN_MILLIS, 2 /* initialSize */)
- .addEntry(TEST_IFACE, UID_RED, SET_DEFAULT, TAG_NONE, METERED_NO, ROAMING_NO,
+ .insertEntry(TEST_IFACE, UID_RED, SET_DEFAULT, TAG_NONE, METERED_NO, ROAMING_NO,
DEFAULT_NETWORK_YES, BASE_BYTES + THRESHOLD_BYTES, 2L,
BASE_BYTES + THRESHOLD_BYTES, 2L, 0L);
mStatsObservers.updateStats(
@@ -424,14 +424,14 @@
// Baseline
NetworkStats xtSnapshot = null;
NetworkStats uidSnapshot = new NetworkStats(TEST_START, 2 /* initialSize */)
- .addEntry(TEST_IFACE, UID_ANOTHER_USER, SET_DEFAULT, TAG_NONE, METERED_NO,
+ .insertEntry(TEST_IFACE, UID_ANOTHER_USER, SET_DEFAULT, TAG_NONE, METERED_NO,
ROAMING_NO, DEFAULT_NETWORK_YES, BASE_BYTES, 2L, BASE_BYTES, 2L, 0L);
mStatsObservers.updateStats(
xtSnapshot, uidSnapshot, mActiveIfaces, mActiveUidIfaces, TEST_START);
// Delta
uidSnapshot = new NetworkStats(TEST_START + 2 * MINUTE_IN_MILLIS, 2 /* initialSize */)
- .addEntry(TEST_IFACE, UID_ANOTHER_USER, SET_DEFAULT, TAG_NONE, METERED_NO,
+ .insertEntry(TEST_IFACE, UID_ANOTHER_USER, SET_DEFAULT, TAG_NONE, METERED_NO,
ROAMING_NO, DEFAULT_NETWORK_NO, BASE_BYTES + THRESHOLD_BYTES, 2L,
BASE_BYTES + THRESHOLD_BYTES, 2L, 0L);
mStatsObservers.updateStats(
diff --git a/tests/net/java/com/android/server/net/NetworkStatsServiceTest.java b/tests/net/java/com/android/server/net/NetworkStatsServiceTest.java
index 36deca3..b346c92 100644
--- a/tests/net/java/com/android/server/net/NetworkStatsServiceTest.java
+++ b/tests/net/java/com/android/server/net/NetworkStatsServiceTest.java
@@ -263,7 +263,7 @@
incrementCurrentTime(HOUR_IN_MILLIS);
expectDefaultSettings();
expectNetworkStatsSummary(new NetworkStats(getElapsedRealtime(), 1)
- .addIfaceValues(TEST_IFACE, 1024L, 1L, 2048L, 2L));
+ .insertEntry(TEST_IFACE, 1024L, 1L, 2048L, 2L));
expectNetworkStatsUidDetail(buildEmptyStats());
forcePollAndWaitForIdle();
@@ -276,7 +276,7 @@
incrementCurrentTime(DAY_IN_MILLIS);
expectDefaultSettings();
expectNetworkStatsSummary(new NetworkStats(getElapsedRealtime(), 1)
- .addIfaceValues(TEST_IFACE, 4096L, 4L, 8192L, 8L));
+ .insertEntry(TEST_IFACE, 4096L, 4L, 8192L, 8L));
expectNetworkStatsUidDetail(buildEmptyStats());
forcePollAndWaitForIdle();
@@ -306,13 +306,13 @@
incrementCurrentTime(HOUR_IN_MILLIS);
expectDefaultSettings();
expectNetworkStatsSummary(new NetworkStats(getElapsedRealtime(), 1)
- .addIfaceValues(TEST_IFACE, 1024L, 8L, 2048L, 16L));
+ .insertEntry(TEST_IFACE, 1024L, 8L, 2048L, 16L));
expectNetworkStatsUidDetail(new NetworkStats(getElapsedRealtime(), 2)
- .addEntry(TEST_IFACE, UID_RED, SET_DEFAULT, TAG_NONE, 512L, 4L, 256L, 2L, 0L)
- .addEntry(TEST_IFACE, UID_RED, SET_DEFAULT, 0xFAAD, 256L, 2L, 128L, 1L, 0L)
- .addEntry(TEST_IFACE, UID_RED, SET_FOREGROUND, TAG_NONE, 512L, 4L, 256L, 2L, 0L)
- .addEntry(TEST_IFACE, UID_RED, SET_FOREGROUND, 0xFAAD, 256L, 2L, 128L, 1L, 0L)
- .addEntry(TEST_IFACE, UID_BLUE, SET_DEFAULT, TAG_NONE, 128L, 1L, 128L, 1L, 0L));
+ .insertEntry(TEST_IFACE, UID_RED, SET_DEFAULT, TAG_NONE, 512L, 4L, 256L, 2L, 0L)
+ .insertEntry(TEST_IFACE, UID_RED, SET_DEFAULT, 0xFAAD, 256L, 2L, 128L, 1L, 0L)
+ .insertEntry(TEST_IFACE, UID_RED, SET_FOREGROUND, TAG_NONE, 512L, 4L, 256L, 2L, 0L)
+ .insertEntry(TEST_IFACE, UID_RED, SET_FOREGROUND, 0xFAAD, 256L, 2L, 128L, 1L, 0L)
+ .insertEntry(TEST_IFACE, UID_BLUE, SET_DEFAULT, TAG_NONE, 128L, 1L, 128L, 1L, 0L));
mService.setUidForeground(UID_RED, false);
mService.incrementOperationCount(UID_RED, 0xFAAD, 4);
mService.setUidForeground(UID_RED, true);
@@ -375,7 +375,7 @@
incrementCurrentTime(2 * HOUR_IN_MILLIS);
expectSettings(0L, HOUR_IN_MILLIS, WEEK_IN_MILLIS);
expectNetworkStatsSummary(new NetworkStats(getElapsedRealtime(), 1)
- .addIfaceValues(TEST_IFACE, 512L, 4L, 512L, 4L));
+ .insertEntry(TEST_IFACE, 512L, 4L, 512L, 4L));
expectNetworkStatsUidDetail(buildEmptyStats());
forcePollAndWaitForIdle();
@@ -415,11 +415,11 @@
incrementCurrentTime(HOUR_IN_MILLIS);
expectDefaultSettings();
expectNetworkStatsSummary(new NetworkStats(getElapsedRealtime(), 1)
- .addIfaceValues(TEST_IFACE, 2048L, 16L, 512L, 4L));
+ .insertEntry(TEST_IFACE, 2048L, 16L, 512L, 4L));
expectNetworkStatsUidDetail(new NetworkStats(getElapsedRealtime(), 3)
- .addEntry(TEST_IFACE, UID_RED, SET_DEFAULT, TAG_NONE, 1536L, 12L, 512L, 4L, 0L)
- .addEntry(TEST_IFACE, UID_RED, SET_DEFAULT, 0xF00D, 512L, 4L, 512L, 4L, 0L)
- .addEntry(TEST_IFACE, UID_BLUE, SET_DEFAULT, TAG_NONE, 512L, 4L, 0L, 0L, 0L));
+ .insertEntry(TEST_IFACE, UID_RED, SET_DEFAULT, TAG_NONE, 1536L, 12L, 512L, 4L, 0L)
+ .insertEntry(TEST_IFACE, UID_RED, SET_DEFAULT, 0xF00D, 512L, 4L, 512L, 4L, 0L)
+ .insertEntry(TEST_IFACE, UID_BLUE, SET_DEFAULT, TAG_NONE, 512L, 4L, 0L, 0L, 0L));
mService.incrementOperationCount(UID_RED, 0xF00D, 10);
forcePollAndWaitForIdle();
@@ -437,11 +437,11 @@
expectDefaultSettings();
states = new NetworkState[] {buildMobile3gState(IMSI_2)};
expectNetworkStatsSummary(new NetworkStats(getElapsedRealtime(), 1)
- .addIfaceValues(TEST_IFACE, 2048L, 16L, 512L, 4L));
+ .insertEntry(TEST_IFACE, 2048L, 16L, 512L, 4L));
expectNetworkStatsUidDetail(new NetworkStats(getElapsedRealtime(), 3)
- .addEntry(TEST_IFACE, UID_RED, SET_DEFAULT, TAG_NONE, 1536L, 12L, 512L, 4L, 0L)
- .addEntry(TEST_IFACE, UID_RED, SET_DEFAULT, 0xF00D, 512L, 4L, 512L, 4L, 0L)
- .addEntry(TEST_IFACE, UID_BLUE, SET_DEFAULT, TAG_NONE, 512L, 4L, 0L, 0L, 0L));
+ .insertEntry(TEST_IFACE, UID_RED, SET_DEFAULT, TAG_NONE, 1536L, 12L, 512L, 4L, 0L)
+ .insertEntry(TEST_IFACE, UID_RED, SET_DEFAULT, 0xF00D, 512L, 4L, 512L, 4L, 0L)
+ .insertEntry(TEST_IFACE, UID_BLUE, SET_DEFAULT, TAG_NONE, 512L, 4L, 0L, 0L, 0L));
mService.forceUpdateIfaces(NETWORKS_MOBILE, states, getActiveIface(states), new VpnInfo[0]);
forcePollAndWaitForIdle();
@@ -451,12 +451,12 @@
incrementCurrentTime(HOUR_IN_MILLIS);
expectDefaultSettings();
expectNetworkStatsSummary(new NetworkStats(getElapsedRealtime(), 1)
- .addIfaceValues(TEST_IFACE, 2176L, 17L, 1536L, 12L));
+ .insertEntry(TEST_IFACE, 2176L, 17L, 1536L, 12L));
expectNetworkStatsUidDetail(new NetworkStats(getElapsedRealtime(), 1)
- .addEntry(TEST_IFACE, UID_RED, SET_DEFAULT, TAG_NONE, 1536L, 12L, 512L, 4L, 0L)
- .addEntry(TEST_IFACE, UID_RED, SET_DEFAULT, 0xF00D, 512L, 4L, 512L, 4L, 0L)
- .addEntry(TEST_IFACE, UID_BLUE, SET_DEFAULT, TAG_NONE, 640L, 5L, 1024L, 8L, 0L)
- .addEntry(TEST_IFACE, UID_BLUE, SET_DEFAULT, 0xFAAD, 128L, 1L, 1024L, 8L, 0L));
+ .insertEntry(TEST_IFACE, UID_RED, SET_DEFAULT, TAG_NONE, 1536L, 12L, 512L, 4L, 0L)
+ .insertEntry(TEST_IFACE, UID_RED, SET_DEFAULT, 0xF00D, 512L, 4L, 512L, 4L, 0L)
+ .insertEntry(TEST_IFACE, UID_BLUE, SET_DEFAULT, TAG_NONE, 640L, 5L, 1024L, 8L, 0L)
+ .insertEntry(TEST_IFACE, UID_BLUE, SET_DEFAULT, 0xFAAD, 128L, 1L, 1024L, 8L, 0L));
mService.incrementOperationCount(UID_BLUE, 0xFAAD, 10);
forcePollAndWaitForIdle();
@@ -488,12 +488,13 @@
incrementCurrentTime(HOUR_IN_MILLIS);
expectDefaultSettings();
expectNetworkStatsSummary(new NetworkStats(getElapsedRealtime(), 1)
- .addIfaceValues(TEST_IFACE, 4128L, 258L, 544L, 34L));
+ .insertEntry(TEST_IFACE, 4128L, 258L, 544L, 34L));
expectNetworkStatsUidDetail(new NetworkStats(getElapsedRealtime(), 1)
- .addEntry(TEST_IFACE, UID_RED, SET_DEFAULT, TAG_NONE, 16L, 1L, 16L, 1L, 0L)
- .addEntry(TEST_IFACE, UID_RED, SET_DEFAULT, 0xFAAD, 16L, 1L, 16L, 1L, 0L)
- .addEntry(TEST_IFACE, UID_BLUE, SET_DEFAULT, TAG_NONE, 4096L, 258L, 512L, 32L, 0L)
- .addEntry(TEST_IFACE, UID_GREEN, SET_DEFAULT, TAG_NONE, 16L, 1L, 16L, 1L, 0L));
+ .insertEntry(TEST_IFACE, UID_RED, SET_DEFAULT, TAG_NONE, 16L, 1L, 16L, 1L, 0L)
+ .insertEntry(TEST_IFACE, UID_RED, SET_DEFAULT, 0xFAAD, 16L, 1L, 16L, 1L, 0L)
+ .insertEntry(TEST_IFACE, UID_BLUE, SET_DEFAULT, TAG_NONE,
+ 4096L, 258L, 512L, 32L, 0L)
+ .insertEntry(TEST_IFACE, UID_GREEN, SET_DEFAULT, TAG_NONE, 16L, 1L, 16L, 1L, 0L));
mService.incrementOperationCount(UID_RED, 0xFAAD, 10);
forcePollAndWaitForIdle();
@@ -509,12 +510,13 @@
// special "removed" bucket.
expectDefaultSettings();
expectNetworkStatsSummary(new NetworkStats(getElapsedRealtime(), 1)
- .addIfaceValues(TEST_IFACE, 4128L, 258L, 544L, 34L));
+ .insertEntry(TEST_IFACE, 4128L, 258L, 544L, 34L));
expectNetworkStatsUidDetail(new NetworkStats(getElapsedRealtime(), 1)
- .addEntry(TEST_IFACE, UID_RED, SET_DEFAULT, TAG_NONE, 16L, 1L, 16L, 1L, 0L)
- .addEntry(TEST_IFACE, UID_RED, SET_DEFAULT, 0xFAAD, 16L, 1L, 16L, 1L, 0L)
- .addEntry(TEST_IFACE, UID_BLUE, SET_DEFAULT, TAG_NONE, 4096L, 258L, 512L, 32L, 0L)
- .addEntry(TEST_IFACE, UID_GREEN, SET_DEFAULT, TAG_NONE, 16L, 1L, 16L, 1L, 0L));
+ .insertEntry(TEST_IFACE, UID_RED, SET_DEFAULT, TAG_NONE, 16L, 1L, 16L, 1L, 0L)
+ .insertEntry(TEST_IFACE, UID_RED, SET_DEFAULT, 0xFAAD, 16L, 1L, 16L, 1L, 0L)
+ .insertEntry(TEST_IFACE, UID_BLUE, SET_DEFAULT, TAG_NONE,
+ 4096L, 258L, 512L, 32L, 0L)
+ .insertEntry(TEST_IFACE, UID_GREEN, SET_DEFAULT, TAG_NONE, 16L, 1L, 16L, 1L, 0L));
final Intent intent = new Intent(ACTION_UID_REMOVED);
intent.putExtra(EXTRA_UID, UID_BLUE);
mServiceContext.sendBroadcast(intent);
@@ -546,8 +548,8 @@
expectDefaultSettings();
expectNetworkStatsSummary(buildEmptyStats());
expectNetworkStatsUidDetail(new NetworkStats(getElapsedRealtime(), 1)
- .addEntry(TEST_IFACE, UID_RED, SET_DEFAULT, TAG_NONE, 1024L, 8L, 1024L, 8L, 0L)
- .addEntry(TEST_IFACE, UID_RED, SET_DEFAULT, 0xF00D, 512L, 4L, 512L, 4L, 0L));
+ .insertEntry(TEST_IFACE, UID_RED, SET_DEFAULT, TAG_NONE, 1024L, 8L, 1024L, 8L, 0L)
+ .insertEntry(TEST_IFACE, UID_RED, SET_DEFAULT, 0xF00D, 512L, 4L, 512L, 4L, 0L));
mService.incrementOperationCount(UID_RED, 0xF00D, 5);
forcePollAndWaitForIdle();
@@ -562,8 +564,8 @@
states = new NetworkState[] {buildMobile4gState(TEST_IFACE2)};
expectNetworkStatsSummary(buildEmptyStats());
expectNetworkStatsUidDetail(new NetworkStats(getElapsedRealtime(), 1)
- .addEntry(TEST_IFACE, UID_RED, SET_DEFAULT, TAG_NONE, 1024L, 8L, 1024L, 8L, 0L)
- .addEntry(TEST_IFACE, UID_RED, SET_DEFAULT, 0xF00D, 512L, 4L, 512L, 4L, 0L));
+ .insertEntry(TEST_IFACE, UID_RED, SET_DEFAULT, TAG_NONE, 1024L, 8L, 1024L, 8L, 0L)
+ .insertEntry(TEST_IFACE, UID_RED, SET_DEFAULT, 0xF00D, 512L, 4L, 512L, 4L, 0L));
mService.forceUpdateIfaces(NETWORKS_MOBILE, states, getActiveIface(states), new VpnInfo[0]);
forcePollAndWaitForIdle();
@@ -574,10 +576,10 @@
expectDefaultSettings();
expectNetworkStatsSummary(buildEmptyStats());
expectNetworkStatsUidDetail(new NetworkStats(getElapsedRealtime(), 1)
- .addEntry(TEST_IFACE, UID_RED, SET_DEFAULT, TAG_NONE, 1024L, 8L, 1024L, 8L, 0L)
- .addEntry(TEST_IFACE, UID_RED, SET_DEFAULT, 0xF00D, 512L, 4L, 512L, 4L, 0L)
- .addEntry(TEST_IFACE2, UID_RED, SET_DEFAULT, TAG_NONE, 512L, 4L, 256L, 2L, 0L)
- .addEntry(TEST_IFACE2, UID_RED, SET_DEFAULT, 0xFAAD, 512L, 4L, 256L, 2L, 0L));
+ .insertEntry(TEST_IFACE, UID_RED, SET_DEFAULT, TAG_NONE, 1024L, 8L, 1024L, 8L, 0L)
+ .insertEntry(TEST_IFACE, UID_RED, SET_DEFAULT, 0xF00D, 512L, 4L, 512L, 4L, 0L)
+ .insertEntry(TEST_IFACE2, UID_RED, SET_DEFAULT, TAG_NONE, 512L, 4L, 256L, 2L, 0L)
+ .insertEntry(TEST_IFACE2, UID_RED, SET_DEFAULT, 0xFAAD, 512L, 4L, 256L, 2L, 0L));
mService.incrementOperationCount(UID_RED, 0xFAAD, 5);
forcePollAndWaitForIdle();
@@ -601,9 +603,9 @@
expectDefaultSettings();
expectNetworkStatsSummary(buildEmptyStats());
expectNetworkStatsUidDetail(new NetworkStats(getElapsedRealtime(), 1)
- .addEntry(TEST_IFACE, UID_RED, SET_DEFAULT, TAG_NONE, 50L, 5L, 50L, 5L, 0L)
- .addEntry(TEST_IFACE, UID_RED, SET_DEFAULT, 0xF00D, 10L, 1L, 10L, 1L, 0L)
- .addEntry(TEST_IFACE, UID_BLUE, SET_DEFAULT, TAG_NONE, 1024L, 8L, 512L, 4L, 0L));
+ .insertEntry(TEST_IFACE, UID_RED, SET_DEFAULT, TAG_NONE, 50L, 5L, 50L, 5L, 0L)
+ .insertEntry(TEST_IFACE, UID_RED, SET_DEFAULT, 0xF00D, 10L, 1L, 10L, 1L, 0L)
+ .insertEntry(TEST_IFACE, UID_BLUE, SET_DEFAULT, TAG_NONE, 1024L, 8L, 512L, 4L, 0L));
mService.incrementOperationCount(UID_RED, 0xF00D, 1);
forcePollAndWaitForIdle();
@@ -618,9 +620,10 @@
expectDefaultSettings();
expectNetworkStatsSummary(buildEmptyStats());
expectNetworkStatsUidDetail(new NetworkStats(getElapsedRealtime(), 1)
- .addEntry(TEST_IFACE, UID_RED, SET_DEFAULT, TAG_NONE, 50L, 5L, 50L, 5L, 0L)
- .addEntry(TEST_IFACE, UID_RED, SET_DEFAULT, 0xF00D, 10L, 1L, 10L, 1L, 0L)
- .addEntry(TEST_IFACE, UID_BLUE, SET_DEFAULT, TAG_NONE, 2048L, 16L, 1024L, 8L, 0L));
+ .insertEntry(TEST_IFACE, UID_RED, SET_DEFAULT, TAG_NONE, 50L, 5L, 50L, 5L, 0L)
+ .insertEntry(TEST_IFACE, UID_RED, SET_DEFAULT, 0xF00D, 10L, 1L, 10L, 1L, 0L)
+ .insertEntry(TEST_IFACE, UID_BLUE, SET_DEFAULT, TAG_NONE,
+ 2048L, 16L, 1024L, 8L, 0L));
forcePollAndWaitForIdle();
// first verify entire history present
@@ -664,9 +667,9 @@
expectDefaultSettings();
expectNetworkStatsSummary(buildEmptyStats());
expectNetworkStatsUidDetail(new NetworkStats(getElapsedRealtime(), 3)
- .addEntry(entry1)
- .addEntry(entry2)
- .addEntry(entry3));
+ .insertEntry(entry1)
+ .insertEntry(entry2)
+ .insertEntry(entry3));
mService.incrementOperationCount(UID_RED, 0xF00D, 1);
NetworkStats stats = mService.getDetailedUidStats(INTERFACES_ALL);
@@ -714,11 +717,11 @@
.thenReturn(augmentedIfaceFilter);
when(mStatsFactory.readNetworkStatsDetail(eq(UID_ALL), any(), eq(TAG_ALL)))
.thenReturn(new NetworkStats(getElapsedRealtime(), 1)
- .addEntry(uidStats));
+ .insertEntry(uidStats));
when(mNetManager.getNetworkStatsTethering(STATS_PER_UID))
.thenReturn(new NetworkStats(getElapsedRealtime(), 2)
- .addEntry(tetheredStats1)
- .addEntry(tetheredStats2));
+ .insertEntry(tetheredStats1)
+ .insertEntry(tetheredStats2));
NetworkStats stats = mService.getDetailedUidStats(ifaceFilter);
@@ -755,8 +758,8 @@
expectDefaultSettings();
expectNetworkStatsSummary(buildEmptyStats());
expectNetworkStatsUidDetail(new NetworkStats(getElapsedRealtime(), 1)
- .addEntry(TEST_IFACE, UID_RED, SET_DEFAULT, TAG_NONE, 128L, 2L, 128L, 2L, 0L)
- .addEntry(TEST_IFACE, UID_RED, SET_DEFAULT, 0xF00D, 64L, 1L, 64L, 1L, 0L));
+ .insertEntry(TEST_IFACE, UID_RED, SET_DEFAULT, TAG_NONE, 128L, 2L, 128L, 2L, 0L)
+ .insertEntry(TEST_IFACE, UID_RED, SET_DEFAULT, 0xF00D, 64L, 1L, 64L, 1L, 0L));
mService.incrementOperationCount(UID_RED, 0xF00D, 1);
forcePollAndWaitForIdle();
@@ -770,10 +773,10 @@
expectDefaultSettings();
expectNetworkStatsSummary(buildEmptyStats());
expectNetworkStatsUidDetail(new NetworkStats(getElapsedRealtime(), 1)
- .addEntry(TEST_IFACE, UID_RED, SET_DEFAULT, TAG_NONE, 128L, 2L, 128L, 2L, 0L)
- .addEntry(TEST_IFACE, UID_RED, SET_DEFAULT, 0xF00D, 64L, 1L, 64L, 1L, 0L)
- .addEntry(TEST_IFACE, UID_RED, SET_FOREGROUND, TAG_NONE, 32L, 2L, 32L, 2L, 0L)
- .addEntry(TEST_IFACE, UID_RED, SET_FOREGROUND, 0xFAAD, 1L, 1L, 1L, 1L, 0L));
+ .insertEntry(TEST_IFACE, UID_RED, SET_DEFAULT, TAG_NONE, 128L, 2L, 128L, 2L, 0L)
+ .insertEntry(TEST_IFACE, UID_RED, SET_DEFAULT, 0xF00D, 64L, 1L, 64L, 1L, 0L)
+ .insertEntry(TEST_IFACE, UID_RED, SET_FOREGROUND, TAG_NONE, 32L, 2L, 32L, 2L, 0L)
+ .insertEntry(TEST_IFACE, UID_RED, SET_FOREGROUND, 0xFAAD, 1L, 1L, 1L, 1L, 0L));
mService.setUidForeground(UID_RED, true);
mService.incrementOperationCount(UID_RED, 0xFAAD, 1);
@@ -814,9 +817,9 @@
// and DEFAULT_NETWORK_YES, because these three properties aren't tracked at that layer.
// We layer them on top by inspecting the iface properties.
expectNetworkStatsUidDetail(new NetworkStats(getElapsedRealtime(), 1)
- .addEntry(TEST_IFACE, UID_RED, SET_DEFAULT, TAG_NONE, METERED_NO, ROAMING_NO,
+ .insertEntry(TEST_IFACE, UID_RED, SET_DEFAULT, TAG_NONE, METERED_NO, ROAMING_NO,
DEFAULT_NETWORK_YES, 128L, 2L, 128L, 2L, 0L)
- .addEntry(TEST_IFACE, UID_RED, SET_DEFAULT, 0xF00D, METERED_NO, ROAMING_NO,
+ .insertEntry(TEST_IFACE, UID_RED, SET_DEFAULT, 0xF00D, METERED_NO, ROAMING_NO,
DEFAULT_NETWORK_YES, 64L, 1L, 64L, 1L, 0L));
mService.incrementOperationCount(UID_RED, 0xF00D, 1);
@@ -853,9 +856,9 @@
// ROAMING_NO, because metered and roaming isn't tracked at that layer. We layer it
// on top by inspecting the iface properties.
expectNetworkStatsUidDetail(new NetworkStats(getElapsedRealtime(), 1)
- .addEntry(TEST_IFACE, UID_RED, SET_DEFAULT, TAG_NONE, METERED_ALL, ROAMING_NO,
+ .insertEntry(TEST_IFACE, UID_RED, SET_DEFAULT, TAG_NONE, METERED_ALL, ROAMING_NO,
DEFAULT_NETWORK_YES, 128L, 2L, 128L, 2L, 0L)
- .addEntry(TEST_IFACE, UID_RED, SET_DEFAULT, 0xF00D, METERED_ALL, ROAMING_NO,
+ .insertEntry(TEST_IFACE, UID_RED, SET_DEFAULT, 0xF00D, METERED_ALL, ROAMING_NO,
DEFAULT_NETWORK_YES, 64L, 1L, 64L, 1L, 0L));
forcePollAndWaitForIdle();
@@ -888,17 +891,17 @@
// Traffic seen by kernel counters (includes software tethering).
final NetworkStats ifaceStats = new NetworkStats(getElapsedRealtime(), 1)
- .addIfaceValues(TEST_IFACE, 1536L, 12L, 384L, 3L);
+ .insertEntry(TEST_IFACE, 1536L, 12L, 384L, 3L);
// Hardware tethering traffic, not seen by kernel counters.
final NetworkStats tetherStatsHardware = new NetworkStats(getElapsedRealtime(), 1)
- .addIfaceValues(TEST_IFACE, 512L, 4L, 128L, 1L);
+ .insertEntry(TEST_IFACE, 512L, 4L, 128L, 1L);
// Traffic for UID_RED.
final NetworkStats uidStats = new NetworkStats(getElapsedRealtime(), 1)
- .addEntry(TEST_IFACE, UID_RED, SET_DEFAULT, TAG_NONE, 128L, 2L, 128L, 2L, 0L);
+ .insertEntry(TEST_IFACE, UID_RED, SET_DEFAULT, TAG_NONE, 128L, 2L, 128L, 2L, 0L);
// All tethering traffic, both hardware and software.
final NetworkStats tetherStats = new NetworkStats(getElapsedRealtime(), 1)
- .addEntry(TEST_IFACE, UID_TETHERING, SET_DEFAULT, TAG_NONE, 1920L, 14L, 384L, 2L,
+ .insertEntry(TEST_IFACE, UID_TETHERING, SET_DEFAULT, TAG_NONE, 1920L, 14L, 384L, 2L,
0L);
expectNetworkStatsSummary(ifaceStats, tetherStatsHardware);
@@ -957,7 +960,7 @@
incrementCurrentTime(HOUR_IN_MILLIS);
expectDefaultSettings();
expectNetworkStatsSummary(new NetworkStats(getElapsedRealtime(), 1)
- .addIfaceValues(TEST_IFACE, 1024L, 1L, 2048L, 2L));
+ .insertEntry(TEST_IFACE, 1024L, 1L, 2048L, 2L));
expectNetworkStatsUidDetail(buildEmptyStats());
forcePollAndWaitForIdle();
@@ -972,7 +975,7 @@
incrementCurrentTime(DAY_IN_MILLIS);
expectDefaultSettings();
expectNetworkStatsSummary(new NetworkStats(getElapsedRealtime(), 1)
- .addIfaceValues(TEST_IFACE, 4096000L, 4L, 8192000L, 8L));
+ .insertEntry(TEST_IFACE, 4096000L, 4L, 8192000L, 8L));
expectNetworkStatsUidDetail(buildEmptyStats());
forcePollAndWaitForIdle();
@@ -1026,18 +1029,18 @@
mService.forceUpdateIfaces(NETWORKS_WIFI, states, getActiveIface(states), new VpnInfo[0]);
// Verifies that one requestStatsUpdate will be called during iface update.
- provider.expectStatsUpdate(0 /* unused */);
+ provider.expectOnRequestStatsUpdate(0 /* unused */);
// Create some initial traffic and report to the service.
incrementCurrentTime(HOUR_IN_MILLIS);
final NetworkStats expectedStats = new NetworkStats(0L, 1)
- .addValues(new NetworkStats.Entry(TEST_IFACE, UID_RED, SET_DEFAULT,
+ .addEntry(new NetworkStats.Entry(TEST_IFACE, UID_RED, SET_DEFAULT,
TAG_NONE, METERED_YES, ROAMING_NO, DEFAULT_NETWORK_YES,
128L, 2L, 128L, 2L, 1L))
- .addValues(new NetworkStats.Entry(TEST_IFACE, UID_RED, SET_DEFAULT,
+ .addEntry(new NetworkStats.Entry(TEST_IFACE, UID_RED, SET_DEFAULT,
0xF00D, METERED_YES, ROAMING_NO, DEFAULT_NETWORK_YES,
64L, 1L, 64L, 1L, 1L));
- cb.onStatsUpdated(0 /* unused */, expectedStats, expectedStats);
+ cb.notifyStatsUpdated(0 /* unused */, expectedStats, expectedStats);
// Make another empty mutable stats object. This is necessary since the new NetworkStats
// object will be used to compare with the old one in NetworkStatsRecoder, two of them
@@ -1047,8 +1050,8 @@
forcePollAndWaitForIdle();
// Verifies that one requestStatsUpdate and setAlert will be called during polling.
- provider.expectStatsUpdate(0 /* unused */);
- provider.expectSetAlert(MB_IN_BYTES);
+ provider.expectOnRequestStatsUpdate(0 /* unused */);
+ provider.expectOnSetAlert(MB_IN_BYTES);
// Verifies that service recorded history, does not verify uid tag part.
assertUidTotal(sTemplateWifi, UID_RED, 128L, 2L, 128L, 2L, 1);
@@ -1082,13 +1085,13 @@
assertNotNull(cb);
// Simulates alert quota of the provider has been reached.
- cb.onAlertReached();
+ cb.notifyAlertReached();
HandlerUtilsKt.waitForIdle(mHandlerThread, WAIT_TIMEOUT);
// Verifies that polling is triggered by alert reached.
- provider.expectStatsUpdate(0 /* unused */);
+ provider.expectOnRequestStatsUpdate(0 /* unused */);
// Verifies that global alert will be re-armed.
- provider.expectSetAlert(MB_IN_BYTES);
+ provider.expectOnSetAlert(MB_IN_BYTES);
}
private static File getBaseDir(File statsDir) {
diff --git a/wifi/Android.bp b/wifi/Android.bp
index f4d2881..70c2741 100644
--- a/wifi/Android.bp
+++ b/wifi/Android.bp
@@ -72,8 +72,7 @@
// classes before they are renamed.
java_library {
name: "framework-wifi-pre-jarjar",
- // TODO(b/146757305): sdk_version should be "module_lib_current"
- sdk_version: "core_current",
+ sdk_version: "module_current",
static_libs: [
"framework-wifi-util-lib",
"android.hardware.wifi-V1.0-java-constants",
@@ -83,9 +82,6 @@
"unsupportedappusage", // for android.compat.annotation.UnsupportedAppUsage
"unsupportedappusage-annotation", // for dalvik.annotation.compat.UnsupportedAppUsage
"framework-telephony-stubs",
- // TODO(b/146757305): should be unnecessary once
- // sdk_version="module_lib_current"
- "android_system_stubs_current",
],
srcs: [
":framework-wifi-updatable-sources",
@@ -98,21 +94,12 @@
"//frameworks/opt/net/wifi/service",
"//frameworks/opt/net/wifi/tests/wifitests",
],
-
- // TODO(b/146757305): should be unnecessary once
- // sdk_version="module_lib_current"
- aidl: {
- include_dirs: [
- "frameworks/base/core/java",
- ],
- },
}
// post-jarjar version of framework-wifi
java_library {
name: "framework-wifi",
- // TODO(b/146757305): sdk_version should be "module_lib_current"
- sdk_version: "core_current",
+ sdk_version: "module_current",
static_libs: [
"framework-wifi-pre-jarjar",
],
diff --git a/wifi/java/android/net/wifi/WifiMigration.java b/wifi/java/android/net/wifi/WifiMigration.java
index 008b18b..f2a1aec 100755
--- a/wifi/java/android/net/wifi/WifiMigration.java
+++ b/wifi/java/android/net/wifi/WifiMigration.java
@@ -16,25 +16,252 @@
package android.net.wifi;
+import static android.os.Environment.getDataMiscCeDirectory;
+import static android.os.Environment.getDataMiscDirectory;
+
+import android.annotation.IntDef;
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.annotation.SystemApi;
import android.content.Context;
import android.os.Parcel;
import android.os.Parcelable;
+import android.os.UserHandle;
import android.provider.Settings;
+import android.util.AtomicFile;
+import android.util.SparseArray;
+
+import java.io.File;
+import java.io.FileNotFoundException;
+import java.io.InputStream;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.util.Objects;
/**
* Class used to provide one time hooks for existing OEM devices to migrate their config store
- * data and other settings to the wifi mainline module.
+ * data and other settings to the wifi apex.
* @hide
*/
@SystemApi
public final class WifiMigration {
+ /**
+ * Directory to read the wifi config store files from under.
+ */
+ private static final String LEGACY_WIFI_STORE_DIRECTORY_NAME = "wifi";
+ /**
+ * Config store file for general shared store file.
+ * AOSP Path on Android 10: /data/misc/wifi/WifiConfigStore.xml
+ */
+ public static final int STORE_FILE_SHARED_GENERAL = 0;
+ /**
+ * Config store file for softap shared store file.
+ * AOSP Path on Android 10: /data/misc/wifi/softap.conf
+ */
+ public static final int STORE_FILE_SHARED_SOFTAP = 1;
+ /**
+ * Config store file for general user store file.
+ * AOSP Path on Android 10: /data/misc_ce/<userId>/wifi/WifiConfigStore.xml
+ */
+ public static final int STORE_FILE_USER_GENERAL = 2;
+ /**
+ * Config store file for network suggestions user store file.
+ * AOSP Path on Android 10: /data/misc_ce/<userId>/wifi/WifiConfigStoreNetworkSuggestions.xml
+ */
+ public static final int STORE_FILE_USER_NETWORK_SUGGESTIONS = 3;
+
+ /** @hide */
+ @IntDef(prefix = { "STORE_FILE_SHARED_" }, value = {
+ STORE_FILE_SHARED_GENERAL,
+ STORE_FILE_SHARED_SOFTAP,
+ })
+ @Retention(RetentionPolicy.SOURCE)
+ public @interface SharedStoreFileId { }
+
+ /** @hide */
+ @IntDef(prefix = { "STORE_FILE_USER_" }, value = {
+ STORE_FILE_USER_GENERAL,
+ STORE_FILE_USER_NETWORK_SUGGESTIONS
+ })
+ @Retention(RetentionPolicy.SOURCE)
+ public @interface UserStoreFileId { }
+
+ /**
+ * Mapping of Store file Id to Store file names.
+ *
+ * NOTE: This is the default path for the files on AOSP devices. If the OEM has modified
+ * the path or renamed the files, please edit this appropriately.
+ */
+ private static final SparseArray<String> STORE_ID_TO_FILE_NAME =
+ new SparseArray<String>() {{
+ put(STORE_FILE_SHARED_GENERAL, "WifiConfigStore.xml");
+ put(STORE_FILE_SHARED_SOFTAP, "softap.conf");
+ put(STORE_FILE_USER_GENERAL, "WifiConfigStore.xml");
+ put(STORE_FILE_USER_NETWORK_SUGGESTIONS, "WifiConfigStoreNetworkSuggestions.xml");
+ }};
+
+ /**
+ * Pre-apex wifi shared folder.
+ */
+ private static File getLegacyWifiSharedDirectory() {
+ return new File(getDataMiscDirectory(), LEGACY_WIFI_STORE_DIRECTORY_NAME);
+ }
+
+ /**
+ * Pre-apex wifi user folder.
+ */
+ private static File getLegacyWifiUserDirectory(int userId) {
+ return new File(getDataMiscCeDirectory(userId), LEGACY_WIFI_STORE_DIRECTORY_NAME);
+ }
+
+ /**
+ * Legacy files were stored as AtomicFile. So, always use AtomicFile to operate on it to ensure
+ * data integrity.
+ */
+ private static AtomicFile getSharedAtomicFile(@SharedStoreFileId int storeFileId) {
+ return new AtomicFile(new File(
+ getLegacyWifiSharedDirectory(),
+ STORE_ID_TO_FILE_NAME.get(storeFileId)));
+ }
+
+ /**
+ * Legacy files were stored as AtomicFile. So, always use AtomicFile to operate on it to ensure
+ * data integrity.
+ */
+ private static AtomicFile getUserAtomicFile(@UserStoreFileId int storeFileId, int userId) {
+ return new AtomicFile(new File(
+ getLegacyWifiUserDirectory(userId),
+ STORE_ID_TO_FILE_NAME.get(storeFileId)));
+ }
private WifiMigration() { }
/**
+ * Load data from legacy shared wifi config store file.
+ * TODO(b/149418926): Add XSD for the AOSP file format for each file from R.
+ * <p>
+ * Note:
+ * <li>OEMs need to change the implementation of
+ * {@link #convertAndRetrieveSharedConfigStoreFile(int)} only if their existing config store
+ * format or file locations differs from the vanilla AOSP implementation.</li>
+ * <li>The wifi apex will invoke
+ * {@link #convertAndRetrieveSharedConfigStoreFile(int)}
+ * method on every bootup, it is the responsibility of the OEM implementation to ensure that
+ * they perform the necessary in place conversion of their config store file to conform to the
+ * AOSP format. The OEM should ensure that the method should only return the
+ * {@link InputStream} stream for the data to be migrated only on the first bootup.</li>
+ * <li>Once the migration is done, the apex will invoke
+ * {@link #removeSharedConfigStoreFile(int)} to delete the store file.</li>
+ * <li>The only relevant invocation of {@link #convertAndRetrieveSharedConfigStoreFile(int)}
+ * occurs when a previously released device upgrades to the wifi apex from an OEM
+ * implementation of the wifi stack.
+ * <li>Ensure that the legacy file paths are accessible to the wifi module (sepolicy rules, file
+ * permissions, etc). Since the wifi service continues to run inside system_server process, this
+ * method will be called from the same context (so ideally the file should still be accessible).
+ * </li>
+ *
+ * @param storeFileId Identifier for the config store file. One of
+ * {@link #STORE_FILE_SHARED_GENERAL} or {@link #STORE_FILE_SHARED_GENERAL}
+ * @return Instance of {@link InputStream} for migrating data, null if no migration is
+ * necessary.
+ * @throws IllegalArgumentException on invalid storeFileId.
+ */
+ @Nullable
+ public static InputStream convertAndRetrieveSharedConfigStoreFile(
+ @SharedStoreFileId int storeFileId) {
+ if (storeFileId != STORE_FILE_SHARED_GENERAL && storeFileId != STORE_FILE_SHARED_SOFTAP) {
+ throw new IllegalArgumentException("Invalid shared store file id");
+ }
+ try {
+ // OEMs should do conversions necessary here before returning the stream.
+ return getSharedAtomicFile(storeFileId).openRead();
+ } catch (FileNotFoundException e) {
+ return null;
+ }
+ }
+
+ /**
+ * Remove the legacy shared wifi config store file.
+ *
+ * @param storeFileId Identifier for the config store file. One of
+ * {@link #STORE_FILE_SHARED_GENERAL} or {@link #STORE_FILE_SHARED_GENERAL}
+ * @throws IllegalArgumentException on invalid storeFileId.
+ */
+ public static void removeSharedConfigStoreFile(@SharedStoreFileId int storeFileId) {
+ if (storeFileId != STORE_FILE_SHARED_GENERAL && storeFileId != STORE_FILE_SHARED_SOFTAP) {
+ throw new IllegalArgumentException("Invalid shared store file id");
+ }
+ getSharedAtomicFile(storeFileId).delete();
+ }
+
+ /**
+ * Load data from legacy user wifi config store file.
+ * TODO(b/149418926): Add XSD for the AOSP file format for each file from R.
+ * <p>
+ * Note:
+ * <li>OEMs need to change the implementation of
+ * {@link #convertAndRetrieveUserConfigStoreFile(int, UserHandle)} only if their existing config
+ * store format or file locations differs from the vanilla AOSP implementation.</li>
+ * <li>The wifi apex will invoke
+ * {@link #convertAndRetrieveUserConfigStoreFile(int, UserHandle)}
+ * method on every bootup, it is the responsibility of the OEM implementation to ensure that
+ * they perform the necessary in place conversion of their config store file to conform to the
+ * AOSP format. The OEM should ensure that the method should only return the
+ * {@link InputStream} stream for the data to be migrated only on the first bootup.</li>
+ * <li>Once the migration is done, the apex will invoke
+ * {@link #removeUserConfigStoreFile(int, UserHandle)} to delete the store file.</li>
+ * <li>The only relevant invocation of
+ * {@link #convertAndRetrieveUserConfigStoreFile(int, UserHandle)} occurs when a previously
+ * released device upgrades to the wifi apex from an OEM implementation of the wifi
+ * stack.
+ * </li>
+ * <li>Ensure that the legacy file paths are accessible to the wifi module (sepolicy rules, file
+ * permissions, etc). Since the wifi service continues to run inside system_server process, this
+ * method will be called from the same context (so ideally the file should still be accessible).
+ * </li>
+ *
+ * @param storeFileId Identifier for the config store file. One of
+ * {@link #STORE_FILE_USER_GENERAL} or {@link #STORE_FILE_USER_NETWORK_SUGGESTIONS}
+ * @param userHandle User handle.
+ * @return Instance of {@link InputStream} for migrating data, null if no migration is
+ * necessary.
+ * @throws IllegalArgumentException on invalid storeFileId or userHandle.
+ */
+ @Nullable
+ public static InputStream convertAndRetrieveUserConfigStoreFile(
+ @UserStoreFileId int storeFileId, @NonNull UserHandle userHandle) {
+ if (storeFileId != STORE_FILE_USER_GENERAL
+ && storeFileId != STORE_FILE_USER_NETWORK_SUGGESTIONS) {
+ throw new IllegalArgumentException("Invalid user store file id");
+ }
+ Objects.requireNonNull(userHandle);
+ try {
+ // OEMs should do conversions necessary here before returning the stream.
+ return getUserAtomicFile(storeFileId, userHandle.getIdentifier()).openRead();
+ } catch (FileNotFoundException e) {
+ return null;
+ }
+ }
+
+ /**
+ * Remove the legacy user wifi config store file.
+ *
+ * @param storeFileId Identifier for the config store file. One of
+ * {@link #STORE_FILE_USER_GENERAL} or {@link #STORE_FILE_USER_NETWORK_SUGGESTIONS}
+ * @param userHandle User handle.
+ * @throws IllegalArgumentException on invalid storeFileId or userHandle.
+ */
+ public static void removeUserConfigStoreFile(
+ @UserStoreFileId int storeFileId, @NonNull UserHandle userHandle) {
+ if (storeFileId != STORE_FILE_USER_GENERAL
+ && storeFileId != STORE_FILE_USER_NETWORK_SUGGESTIONS) {
+ throw new IllegalArgumentException("Invalid user store file id");
+ }
+ Objects.requireNonNull(userHandle);
+ getUserAtomicFile(storeFileId, userHandle.getIdentifier()).delete();
+ }
+
+ /**
* Container for all the wifi settings data to migrate.
*/
public static final class SettingsMigrationData implements Parcelable {
@@ -260,7 +487,7 @@
* <li> This is method is invoked once on the first bootup. OEM can safely delete these settings
* once the migration is complete. The first & only relevant invocation of
* {@link #loadFromSettings(Context)} ()} occurs when a previously released
- * device upgrades to the wifi mainline module from an OEM implementation of the wifi stack.
+ * device upgrades to the wifi apex from an OEM implementation of the wifi stack.
* </li>
*
* @param context Context to use for loading the settings provider.