Merge "idmap2: introduce improved Result class"
diff --git a/Android.mk b/Android.mk
index 65d4d24..9c65948 100644
--- a/Android.mk
+++ b/Android.mk
@@ -79,34 +79,6 @@
# ==== hiddenapi lists =======================================
ifneq ($(UNSAFE_DISABLE_HIDDENAPI_FLAGS),true)
-.KATI_RESTAT: $(INTERNAL_PLATFORM_HIDDENAPI_FLAGS)
-$(INTERNAL_PLATFORM_HIDDENAPI_FLAGS): \
- PRIVATE_FLAGS_INPUTS := $(PRIVATE_FLAGS_INPUTS) $(SOONG_HIDDENAPI_FLAGS)
-$(INTERNAL_PLATFORM_HIDDENAPI_FLAGS): \
- frameworks/base/tools/hiddenapi/generate_hiddenapi_lists.py \
- frameworks/base/config/hiddenapi-greylist.txt \
- frameworks/base/config/hiddenapi-greylist-max-p.txt \
- frameworks/base/config/hiddenapi-greylist-max-o.txt \
- frameworks/base/config/hiddenapi-force-blacklist.txt \
- $(INTERNAL_PLATFORM_HIDDENAPI_STUB_FLAGS) \
- $(INTERNAL_PLATFORM_REMOVED_DEX_API_FILE) \
- $(SOONG_HIDDENAPI_FLAGS)
- frameworks/base/tools/hiddenapi/generate_hiddenapi_lists.py \
- --csv $(INTERNAL_PLATFORM_HIDDENAPI_STUB_FLAGS) $(PRIVATE_FLAGS_INPUTS) \
- --greylist frameworks/base/config/hiddenapi-greylist.txt \
- --greylist-ignore-conflicts $(INTERNAL_PLATFORM_REMOVED_DEX_API_FILE) \
- --greylist-max-p frameworks/base/config/hiddenapi-greylist-max-p.txt \
- --greylist-max-o-ignore-conflicts \
- frameworks/base/config/hiddenapi-greylist-max-o.txt \
- --blacklist frameworks/base/config/hiddenapi-force-blacklist.txt \
- --output $@.tmp
- $(call commit-change-for-toc,$@)
-
-$(INTERNAL_PLATFORM_HIDDENAPI_GREYLIST_METADATA): \
- frameworks/base/tools/hiddenapi/merge_csv.py \
- $(PRIVATE_METADATA_INPUTS)
- frameworks/base/tools/hiddenapi/merge_csv.py $(PRIVATE_METADATA_INPUTS) > $@
-
$(call dist-for-goals,droidcore,$(INTERNAL_PLATFORM_HIDDENAPI_FLAGS))
$(call dist-for-goals,droidcore,$(INTERNAL_PLATFORM_HIDDENAPI_GREYLIST_METADATA))
endif # UNSAFE_DISABLE_HIDDENAPI_FLAGS
diff --git a/api/current.txt b/api/current.txt
index 8458ed3..b7577d1 100644
--- a/api/current.txt
+++ b/api/current.txt
@@ -224,6 +224,11 @@
public static final class R.attr {
ctor public R.attr();
+ field public static final int __removed1 = 16844185; // 0x1010599
+ field public static final int __removed2 = 16844186; // 0x101059a
+ field public static final int __removed3 = 16844187; // 0x101059b
+ field public static final int __removed4 = 16844188; // 0x101059c
+ field public static final int __removed5 = 16844189; // 0x101059d
field public static final int absListViewStyle = 16842858; // 0x101006a
field public static final int accessibilityEventTypes = 16843648; // 0x1010380
field public static final int accessibilityFeedbackType = 16843650; // 0x1010382
@@ -484,10 +489,6 @@
field public static final int dashGap = 16843175; // 0x10101a7
field public static final int dashWidth = 16843174; // 0x10101a6
field public static final int data = 16842798; // 0x101002e
- field public static final int dataRetentionTime = 16844189; // 0x101059d
- field public static final int dataSentOffDevice = 16844186; // 0x101059a
- field public static final int dataSharedWithThirdParty = 16844187; // 0x101059b
- field public static final int dataUsedForMonetization = 16844188; // 0x101059c
field public static final int datePickerDialogTheme = 16843948; // 0x10104ac
field public static final int datePickerMode = 16843955; // 0x10104b3
field public static final int datePickerStyle = 16843612; // 0x101035c
@@ -1508,7 +1509,6 @@
field @Deprecated public static final int unfocusedMonthDateColor = 16843588; // 0x1010344
field public static final int unselectedAlpha = 16843278; // 0x101020e
field public static final int updatePeriodMillis = 16843344; // 0x1010250
- field public static final int usageInfoRequired = 16844185; // 0x1010599
field public static final int use32bitAbi = 16844053; // 0x1010515
field public static final int useAppZygote = 16844184; // 0x1010598
field public static final int useDefaultMargins = 16843641; // 0x1010379
@@ -10265,7 +10265,6 @@
field public static final String ACTION_PACKAGE_RESTARTED = "android.intent.action.PACKAGE_RESTARTED";
field public static final String ACTION_PACKAGE_VERIFIED = "android.intent.action.PACKAGE_VERIFIED";
field public static final String ACTION_PASTE = "android.intent.action.PASTE";
- field public static final String ACTION_PERMISSION_USAGE_DETAILS = "android.intent.action.PERMISSION_USAGE_DETAILS";
field public static final String ACTION_PICK = "android.intent.action.PICK";
field public static final String ACTION_PICK_ACTIVITY = "android.intent.action.PICK_ACTIVITY";
field public static final String ACTION_POWER_CONNECTED = "android.intent.action.ACTION_POWER_CONNECTED";
@@ -10391,7 +10390,6 @@
field public static final String EXTRA_NOT_UNKNOWN_SOURCE = "android.intent.extra.NOT_UNKNOWN_SOURCE";
field public static final String EXTRA_ORIGINATING_URI = "android.intent.extra.ORIGINATING_URI";
field public static final String EXTRA_PACKAGE_NAME = "android.intent.extra.PACKAGE_NAME";
- field public static final String EXTRA_PERMISSION_USAGE_PERMISSIONS = "android.intent.extra.PERMISSION_USAGE_PERMISSIONS";
field public static final String EXTRA_PHONE_NUMBER = "android.intent.extra.PHONE_NUMBER";
field public static final String EXTRA_PROCESS_TEXT = "android.intent.extra.PROCESS_TEXT";
field public static final String EXTRA_PROCESS_TEXT_READONLY = "android.intent.extra.PROCESS_TEXT_READONLY";
@@ -11356,8 +11354,8 @@
field public android.content.pm.ProviderInfo[] providers;
field public android.content.pm.ActivityInfo[] receivers;
field public android.content.pm.FeatureInfo[] reqFeatures;
- field @Deprecated public String[] requestedPermissions;
- field @Deprecated public int[] requestedPermissionsFlags;
+ field public String[] requestedPermissions;
+ field public int[] requestedPermissionsFlags;
field public android.content.pm.ServiceInfo[] services;
field public String sharedUserId;
field public int sharedUserLabel;
@@ -11365,7 +11363,6 @@
field public android.content.pm.SigningInfo signingInfo;
field public String[] splitNames;
field public int[] splitRevisionCodes;
- field public android.content.pm.UsesPermissionInfo[] usesPermissions;
field @Deprecated public int versionCode;
field public String versionName;
}
@@ -11865,7 +11862,6 @@
field public String group;
field public CharSequence nonLocalizedDescription;
field @Deprecated public int protectionLevel;
- field public boolean usageInfoRequired;
}
public final class ProviderInfo extends android.content.pm.ComponentInfo implements android.os.Parcelable {
@@ -12057,28 +12053,6 @@
field public static final android.os.Parcelable.Creator<android.content.pm.SigningInfo> CREATOR;
}
- public final class UsesPermissionInfo extends android.content.pm.PackageItemInfo implements android.os.Parcelable {
- method public int describeContents();
- method public int getDataRetention();
- method public int getDataRetentionWeeks();
- method public int getDataSentOffDevice();
- method public int getDataSharedWithThirdParty();
- method public int getDataUsedForMonetization();
- method public int getFlags();
- method public String getPermission();
- field public static final android.os.Parcelable.Creator<android.content.pm.UsesPermissionInfo> CREATOR;
- field public static final int FLAG_REQUESTED_PERMISSION_GRANTED = 2; // 0x2
- field public static final int RETENTION_NOT_RETAINED = 1; // 0x1
- field public static final int RETENTION_SPECIFIED = 4; // 0x4
- field public static final int RETENTION_UNDEFINED = 0; // 0x0
- field public static final int RETENTION_UNLIMITED = 3; // 0x3
- field public static final int RETENTION_USER_SELECTED = 2; // 0x2
- field public static final int USAGE_NO = 3; // 0x3
- field public static final int USAGE_UNDEFINED = 0; // 0x0
- field public static final int USAGE_USER_TRIGGERED = 2; // 0x2
- field public static final int USAGE_YES = 1; // 0x1
- }
-
public final class VersionedPackage implements android.os.Parcelable {
ctor public VersionedPackage(@NonNull String, int);
ctor public VersionedPackage(@NonNull String, long);
@@ -19446,9 +19420,9 @@
method public static android.icu.text.BreakIterator getSentenceInstance(java.util.Locale);
method public static android.icu.text.BreakIterator getSentenceInstance(android.icu.util.ULocale);
method public abstract java.text.CharacterIterator getText();
- method public static android.icu.text.BreakIterator getTitleInstance();
- method public static android.icu.text.BreakIterator getTitleInstance(java.util.Locale);
- method public static android.icu.text.BreakIterator getTitleInstance(android.icu.util.ULocale);
+ method @Deprecated public static android.icu.text.BreakIterator getTitleInstance();
+ method @Deprecated public static android.icu.text.BreakIterator getTitleInstance(java.util.Locale);
+ method @Deprecated public static android.icu.text.BreakIterator getTitleInstance(android.icu.util.ULocale);
method public static android.icu.text.BreakIterator getWordInstance();
method public static android.icu.text.BreakIterator getWordInstance(java.util.Locale);
method public static android.icu.text.BreakIterator getWordInstance(android.icu.util.ULocale);
@@ -19465,7 +19439,7 @@
field public static final int KIND_CHARACTER = 0; // 0x0
field public static final int KIND_LINE = 2; // 0x2
field public static final int KIND_SENTENCE = 3; // 0x3
- field public static final int KIND_TITLE = 4; // 0x4
+ field @Deprecated public static final int KIND_TITLE = 4; // 0x4
field public static final int KIND_WORD = 1; // 0x1
field public static final int WORD_IDEO = 400; // 0x190
field public static final int WORD_IDEO_LIMIT = 500; // 0x1f4
diff --git a/api/system-current.txt b/api/system-current.txt
index 376aad0..b7fc339 100644
--- a/api/system-current.txt
+++ b/api/system-current.txt
@@ -3920,6 +3920,7 @@
method @RequiresPermission(android.Manifest.permission.TETHER_PRIVILEGED) public void getLatestTetheringEntitlementValue(int, boolean, @NonNull android.net.ConnectivityManager.TetheringEntitlementValueListener, @Nullable android.os.Handler);
method @RequiresPermission(anyOf={android.Manifest.permission.TETHER_PRIVILEGED, android.Manifest.permission.WRITE_SETTINGS}) public boolean isTetheringSupported();
method @RequiresPermission(anyOf={"android.permission.NETWORK_SETTINGS", android.Manifest.permission.NETWORK_SETUP_WIZARD, "android.permission.NETWORK_STACK"}) public void setAirplaneMode(boolean);
+ method @RequiresPermission(android.net.NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK) public void startCaptivePortalApp(android.os.Bundle);
method @RequiresPermission(android.Manifest.permission.TETHER_PRIVILEGED) public void startTethering(int, boolean, android.net.ConnectivityManager.OnStartTetheringCallback);
method @RequiresPermission(android.Manifest.permission.TETHER_PRIVILEGED) public void startTethering(int, boolean, android.net.ConnectivityManager.OnStartTetheringCallback, android.os.Handler);
method @RequiresPermission(android.Manifest.permission.TETHER_PRIVILEGED) public void stopTethering(int);
diff --git a/api/test-current.txt b/api/test-current.txt
index 5b51d6e..94e83ea 100644
--- a/api/test-current.txt
+++ b/api/test-current.txt
@@ -934,6 +934,7 @@
}
public class ConnectivityManager {
+ method @RequiresPermission(android.net.NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK) public void startCaptivePortalApp(android.os.Bundle);
field public static final String EXTRA_CAPTIVE_PORTAL_PROBE_SPEC = "android.net.extra.CAPTIVE_PORTAL_PROBE_SPEC";
field public static final String EXTRA_CAPTIVE_PORTAL_USER_AGENT = "android.net.extra.CAPTIVE_PORTAL_USER_AGENT";
}
diff --git a/cmds/idmap2/libidmap2/Idmap.cpp b/cmds/idmap2/libidmap2/Idmap.cpp
index fa5ac8e..b19d7a9 100644
--- a/cmds/idmap2/libidmap2/Idmap.cpp
+++ b/cmds/idmap2/libidmap2/Idmap.cpp
@@ -117,6 +117,12 @@
return loaded_arsc.GetPackageById(id);
}
+Result<uint32_t> GetCrc(const ZipFile& zip) {
+ const Result<uint32_t> a = zip.Crc("resources.arsc");
+ const Result<uint32_t> b = zip.Crc("AndroidManifest.xml");
+ return a && b ? Result<uint32_t>(*a ^ *b) : kResultError;
+}
+
} // namespace
std::unique_ptr<const IdmapHeader> IdmapHeader::FromBinaryStream(std::istream& stream) {
@@ -153,7 +159,7 @@
return false;
}
- Result<uint32_t> target_crc = target_zip->Crc("resources.arsc");
+ Result<uint32_t> target_crc = GetCrc(*target_zip);
if (!target_crc) {
out_error << "error: failed to get target crc" << std::endl;
return false;
@@ -173,7 +179,7 @@
return false;
}
- Result<uint32_t> overlay_crc = overlay_zip->Crc("resources.arsc");
+ Result<uint32_t> overlay_crc = GetCrc(*overlay_zip);
if (!overlay_crc) {
out_error << "error: failed to get overlay crc" << std::endl;
return false;
@@ -356,14 +362,14 @@
header->magic_ = kIdmapMagic;
header->version_ = kIdmapCurrentVersion;
- Result<uint32_t> crc = target_zip->Crc("resources.arsc");
+ Result<uint32_t> crc = GetCrc(*target_zip);
if (!crc) {
out_error << "error: failed to get zip crc for target" << std::endl;
return nullptr;
}
header->target_crc_ = *crc;
- crc = overlay_zip->Crc("resources.arsc");
+ crc = GetCrc(*overlay_zip);
if (!crc) {
out_error << "error: failed to get zip crc for overlay" << std::endl;
return nullptr;
diff --git a/cmds/idmap2/tests/IdmapTests.cpp b/cmds/idmap2/tests/IdmapTests.cpp
index 9e27ccd..b40521f 100644
--- a/cmds/idmap2/tests/IdmapTests.cpp
+++ b/cmds/idmap2/tests/IdmapTests.cpp
@@ -191,8 +191,8 @@
ASSERT_THAT(idmap->GetHeader(), NotNull());
ASSERT_EQ(idmap->GetHeader()->GetMagic(), 0x504d4449U);
ASSERT_EQ(idmap->GetHeader()->GetVersion(), 0x01U);
- ASSERT_EQ(idmap->GetHeader()->GetTargetCrc(), 0xab7cf70d);
- ASSERT_EQ(idmap->GetHeader()->GetOverlayCrc(), 0xd470336b);
+ ASSERT_EQ(idmap->GetHeader()->GetTargetCrc(), 0xdd53ca29);
+ ASSERT_EQ(idmap->GetHeader()->GetOverlayCrc(), 0xa71ccd77);
ASSERT_EQ(idmap->GetHeader()->GetTargetPath().to_string(), target_apk_path);
ASSERT_EQ(idmap->GetHeader()->GetOverlayPath(), overlay_apk_path);
ASSERT_EQ(idmap->GetHeader()->GetOverlayPath(), overlay_apk_path);
diff --git a/cmds/idmap2/tests/RawPrintVisitorTests.cpp b/cmds/idmap2/tests/RawPrintVisitorTests.cpp
index b1ca125..a5588c3 100644
--- a/cmds/idmap2/tests/RawPrintVisitorTests.cpp
+++ b/cmds/idmap2/tests/RawPrintVisitorTests.cpp
@@ -52,8 +52,8 @@
ASSERT_NE(stream.str().find("00000000: 504d4449 magic\n"), std::string::npos);
ASSERT_NE(stream.str().find("00000004: 00000001 version\n"), std::string::npos);
- ASSERT_NE(stream.str().find("00000008: ab7cf70d target crc\n"), std::string::npos);
- ASSERT_NE(stream.str().find("0000000c: d470336b overlay crc\n"), std::string::npos);
+ ASSERT_NE(stream.str().find("00000008: dd53ca29 target crc\n"), std::string::npos);
+ ASSERT_NE(stream.str().find("0000000c: a71ccd77 overlay crc\n"), std::string::npos);
ASSERT_NE(stream.str().find("0000021c: 00000000 0x7f010000 -> 0x7f010000 integer/int1\n"),
std::string::npos);
}
diff --git a/cmds/statsd/src/atom_field_options.proto b/cmds/statsd/src/atom_field_options.proto
index e33bd8c..2a3eee2 100644
--- a/cmds/statsd/src/atom_field_options.proto
+++ b/cmds/statsd/src/atom_field_options.proto
@@ -82,4 +82,6 @@
optional bool is_uid = 50001 [default = false];
optional LogMode log_mode = 50002 [default = MODE_AUTOMATIC];
+
+ optional bool allow_from_any_uid = 50003 [default = false];
}
\ No newline at end of file
diff --git a/cmds/statsd/src/atoms.proto b/cmds/statsd/src/atoms.proto
index 07aced6..4f17d69 100644
--- a/cmds/statsd/src/atoms.proto
+++ b/cmds/statsd/src/atoms.proto
@@ -110,7 +110,7 @@
PacketWakeupOccurred packet_wakeup_occurred = 44;
WallClockTimeShifted wall_clock_time_shifted = 45;
AnomalyDetected anomaly_detected = 46;
- AppBreadcrumbReported app_breadcrumb_reported = 47;
+ AppBreadcrumbReported app_breadcrumb_reported = 47 [(allow_from_any_uid) = true];
AppStartOccurred app_start_occurred = 48;
AppStartCanceled app_start_canceled = 49;
AppStartFullyDrawn app_start_fully_drawn = 50;
@@ -121,7 +121,7 @@
AppStartMemoryStateCaptured app_start_memory_state_captured = 55;
ShutdownSequenceReported shutdown_sequence_reported = 56;
BootSequenceReported boot_sequence_reported = 57;
- DaveyOccurred davey_occurred = 58;
+ DaveyOccurred davey_occurred = 58 [(allow_from_any_uid) = true];
OverlayStateChanged overlay_state_changed = 59;
ForegroundServiceStateChanged foreground_service_state_changed = 60;
CallStateChanged call_state_changed = 61;
diff --git a/cmds/statsd/src/guardrail/StatsdStats.cpp b/cmds/statsd/src/guardrail/StatsdStats.cpp
index a5bd5c6..37d5ba0 100644
--- a/cmds/statsd/src/guardrail/StatsdStats.cpp
+++ b/cmds/statsd/src/guardrail/StatsdStats.cpp
@@ -443,6 +443,11 @@
getAtomMetricStats(metricId).badValueType++;
}
+void StatsdStats::noteBucketDropped(int metricId) {
+ lock_guard<std::mutex> lock(mLock);
+ getAtomMetricStats(metricId).bucketDropped++;
+}
+
void StatsdStats::noteConditionChangeInNextBucket(int metricId) {
lock_guard<std::mutex> lock(mLock);
getAtomMetricStats(metricId).conditionChangeInNextBucket++;
diff --git a/cmds/statsd/src/guardrail/StatsdStats.h b/cmds/statsd/src/guardrail/StatsdStats.h
index cb17061..20ea7e5 100644
--- a/cmds/statsd/src/guardrail/StatsdStats.h
+++ b/cmds/statsd/src/guardrail/StatsdStats.h
@@ -360,6 +360,11 @@
void noteBadValueType(int atomId);
/**
+ * Buckets were dropped due to reclaim memory.
+ */
+ void noteBucketDropped(int metricId);
+
+ /**
* A condition change was too late, arrived in the wrong bucket and was skipped
*/
void noteConditionChangeInNextBucket(int atomId);
@@ -414,6 +419,7 @@
long badValueType = 0;
long conditionChangeInNextBucket = 0;
long invalidatedBucket = 0;
+ long bucketDropped = 0;
} AtomMetricStats;
private:
diff --git a/cmds/statsd/src/metrics/CountMetricProducer.cpp b/cmds/statsd/src/metrics/CountMetricProducer.cpp
index 7cc57c1..350745b 100644
--- a/cmds/statsd/src/metrics/CountMetricProducer.cpp
+++ b/cmds/statsd/src/metrics/CountMetricProducer.cpp
@@ -243,6 +243,7 @@
void CountMetricProducer::dropDataLocked(const int64_t dropTimeNs) {
flushIfNeededLocked(dropTimeNs);
+ StatsdStats::getInstance().noteBucketDropped(mMetricId);
mPastBuckets.clear();
}
diff --git a/cmds/statsd/src/metrics/DurationMetricProducer.cpp b/cmds/statsd/src/metrics/DurationMetricProducer.cpp
index 69bafc3..6c1c47b 100644
--- a/cmds/statsd/src/metrics/DurationMetricProducer.cpp
+++ b/cmds/statsd/src/metrics/DurationMetricProducer.cpp
@@ -444,6 +444,7 @@
void DurationMetricProducer::dropDataLocked(const int64_t dropTimeNs) {
flushIfNeededLocked(dropTimeNs);
+ StatsdStats::getInstance().noteBucketDropped(mMetricId);
mPastBuckets.clear();
}
diff --git a/cmds/statsd/src/metrics/EventMetricProducer.cpp b/cmds/statsd/src/metrics/EventMetricProducer.cpp
index c53c4ce..7e695a6 100644
--- a/cmds/statsd/src/metrics/EventMetricProducer.cpp
+++ b/cmds/statsd/src/metrics/EventMetricProducer.cpp
@@ -77,6 +77,7 @@
void EventMetricProducer::dropDataLocked(const int64_t dropTimeNs) {
mProto->clear();
+ StatsdStats::getInstance().noteBucketDropped(mMetricId);
}
void EventMetricProducer::onSlicedConditionMayChangeLocked(bool overallCondition,
diff --git a/cmds/statsd/src/metrics/GaugeMetricProducer.cpp b/cmds/statsd/src/metrics/GaugeMetricProducer.cpp
index c9b7165..2609937 100644
--- a/cmds/statsd/src/metrics/GaugeMetricProducer.cpp
+++ b/cmds/statsd/src/metrics/GaugeMetricProducer.cpp
@@ -510,6 +510,7 @@
void GaugeMetricProducer::dropDataLocked(const int64_t dropTimeNs) {
flushIfNeededLocked(dropTimeNs);
+ StatsdStats::getInstance().noteBucketDropped(mMetricId);
mPastBuckets.clear();
}
diff --git a/cmds/statsd/src/metrics/MetricsManager.cpp b/cmds/statsd/src/metrics/MetricsManager.cpp
index ca68117..6ed6ab50 100644
--- a/cmds/statsd/src/metrics/MetricsManager.cpp
+++ b/cmds/statsd/src/metrics/MetricsManager.cpp
@@ -241,12 +241,22 @@
VLOG("=========================Metric Reports End==========================");
}
-// Consume the stats log if it's interesting to this metric.
-void MetricsManager::onLogEvent(const LogEvent& event) {
- if (!mConfigValid) {
- return;
- }
+bool MetricsManager::checkLogCredentials(const LogEvent& event) {
+ if (android::util::AtomsInfo::kWhitelistedAtoms.find(event.GetTagId()) !=
+ android::util::AtomsInfo::kWhitelistedAtoms.end())
+ {
+ return true;
+ }
+ std::lock_guard<std::mutex> lock(mAllowedLogSourcesMutex);
+ if (mAllowedLogSources.find(event.GetUid()) == mAllowedLogSources.end()) {
+ VLOG("log source %d not on the whitelist", event.GetUid());
+ return false;
+ }
+ return true;
+}
+
+bool MetricsManager::eventSanityCheck(const LogEvent& event) {
if (event.GetTagId() == android::util::APP_BREADCRUMB_REPORTED) {
// Check that app breadcrumb reported fields are valid.
status_t err = NO_ERROR;
@@ -256,23 +266,23 @@
long appHookUid = event.GetLong(event.size()-2, &err);
if (err != NO_ERROR ) {
VLOG("APP_BREADCRUMB_REPORTED had error when parsing the uid");
- return;
+ return false;
}
int32_t loggerUid = event.GetUid();
if (loggerUid != appHookUid && loggerUid != AID_STATSD) {
VLOG("APP_BREADCRUMB_REPORTED has invalid uid: claimed %ld but caller is %d",
appHookUid, loggerUid);
- return;
+ return false;
}
// The state must be from 0,3. This part of code must be manually updated.
long appHookState = event.GetLong(event.size(), &err);
if (err != NO_ERROR ) {
VLOG("APP_BREADCRUMB_REPORTED had error when parsing the state field");
- return;
+ return false;
} else if (appHookState < 0 || appHookState > 3) {
VLOG("APP_BREADCRUMB_REPORTED does not have valid state %ld", appHookState);
- return;
+ return false;
}
} else if (event.GetTagId() == android::util::DAVEY_OCCURRED) {
// Daveys can be logged from any app since they are logged in libs/hwui/JankTracker.cpp.
@@ -283,29 +293,40 @@
long jankUid = event.GetLong(1, &err);
if (err != NO_ERROR ) {
VLOG("Davey occurred had error when parsing the uid");
- return;
+ return false;
}
int32_t loggerUid = event.GetUid();
if (loggerUid != jankUid && loggerUid != AID_STATSD) {
VLOG("DAVEY_OCCURRED has invalid uid: claimed %ld but caller is %d", jankUid,
loggerUid);
- return;
+ return false;
}
long duration = event.GetLong(event.size(), &err);
if (err != NO_ERROR ) {
VLOG("Davey occurred had error when parsing the duration");
- return;
+ return false;
} else if (duration > 100000) {
VLOG("Davey duration is unreasonably long: %ld", duration);
- return;
+ return false;
}
- } else {
- std::lock_guard<std::mutex> lock(mAllowedLogSourcesMutex);
- if (mAllowedLogSources.find(event.GetUid()) == mAllowedLogSources.end()) {
- VLOG("log source %d not on the whitelist", event.GetUid());
- return;
- }
+ }
+
+ return true;
+}
+
+// Consume the stats log if it's interesting to this metric.
+void MetricsManager::onLogEvent(const LogEvent& event) {
+ if (!mConfigValid) {
+ return;
+ }
+
+ if (!checkLogCredentials(event)) {
+ return;
+ }
+
+ if (!eventSanityCheck(event)) {
+ return;
}
int tagId = event.GetTagId();
diff --git a/cmds/statsd/src/metrics/MetricsManager.h b/cmds/statsd/src/metrics/MetricsManager.h
index 80982c3..fdc28ea 100644
--- a/cmds/statsd/src/metrics/MetricsManager.h
+++ b/cmds/statsd/src/metrics/MetricsManager.h
@@ -49,6 +49,10 @@
// Return whether the configuration is valid.
bool isConfigValid() const;
+ bool checkLogCredentials(const LogEvent& event);
+
+ bool eventSanityCheck(const LogEvent& event);
+
void onLogEvent(const LogEvent& event);
void onAnomalyAlarmFired(
diff --git a/cmds/statsd/src/metrics/ValueMetricProducer.cpp b/cmds/statsd/src/metrics/ValueMetricProducer.cpp
index 9fb78e7..1bd3ef2 100644
--- a/cmds/statsd/src/metrics/ValueMetricProducer.cpp
+++ b/cmds/statsd/src/metrics/ValueMetricProducer.cpp
@@ -175,6 +175,7 @@
void ValueMetricProducer::dropDataLocked(const int64_t dropTimeNs) {
flushIfNeededLocked(dropTimeNs);
+ StatsdStats::getInstance().noteBucketDropped(mMetricId);
mPastBuckets.clear();
}
@@ -434,6 +435,10 @@
}
}
mHasGlobalBase = true;
+
+ // We can probably flush the bucket. Since we used bucketEndTime when calling
+ // #onMatchedLogEventInternalLocked, the current bucket will not have been flushed.
+ flushIfNeededLocked(realEventTime);
} else {
VLOG("No need to commit data on condition false.");
}
diff --git a/cmds/statsd/src/metrics/ValueMetricProducer.h b/cmds/statsd/src/metrics/ValueMetricProducer.h
index d9bec5d..0cfefa9 100644
--- a/cmds/statsd/src/metrics/ValueMetricProducer.h
+++ b/cmds/statsd/src/metrics/ValueMetricProducer.h
@@ -61,6 +61,7 @@
if (!mSplitBucketForAppUpgrade) {
return;
}
+ flushIfNeededLocked(eventTimeNs - 1);
if (mIsPulled && mCondition) {
pullAndMatchEventsLocked(eventTimeNs - 1);
}
@@ -212,6 +213,7 @@
FRIEND_TEST(ValueMetricProducerTest, TestEventsWithNonSlicedCondition);
FRIEND_TEST(ValueMetricProducerTest, TestPushedEventsWithUpgrade);
FRIEND_TEST(ValueMetricProducerTest, TestPulledValueWithUpgrade);
+ FRIEND_TEST(ValueMetricProducerTest, TestPartialBucketCreated);
FRIEND_TEST(ValueMetricProducerTest, TestPulledValueWithUpgradeWhileConditionFalse);
FRIEND_TEST(ValueMetricProducerTest, TestPulledWithAppUpgradeDisabled);
FRIEND_TEST(ValueMetricProducerTest, TestPushedEventsWithoutCondition);
@@ -238,6 +240,8 @@
FRIEND_TEST(ValueMetricProducerTest, TestInvalidBucketWhenOneConditionFailed);
FRIEND_TEST(ValueMetricProducerTest, TestInvalidBucketWhenInitialPullFailed);
FRIEND_TEST(ValueMetricProducerTest, TestInvalidBucketWhenLastPullFailed);
+ FRIEND_TEST(ValueMetricProducerTest, TestResetBaseOnPullDelayExceeded);
+ FRIEND_TEST(ValueMetricProducerTest, TestBaseSetOnConditionChange);
};
} // namespace statsd
diff --git a/cmds/statsd/src/stats_log.proto b/cmds/statsd/src/stats_log.proto
index 5b91482..73aab48 100644
--- a/cmds/statsd/src/stats_log.proto
+++ b/cmds/statsd/src/stats_log.proto
@@ -418,6 +418,7 @@
optional int64 bad_value_type = 5;
optional int64 condition_change_in_next_bucket = 6;
optional int64 invalidated_bucket = 7;
+ optional int64 bucket_dropped = 8;
}
repeated AtomMetricStats atom_metric_stats = 17;
diff --git a/cmds/statsd/src/stats_log_util.cpp b/cmds/statsd/src/stats_log_util.cpp
index 3cb7563..f76a9ad 100644
--- a/cmds/statsd/src/stats_log_util.cpp
+++ b/cmds/statsd/src/stats_log_util.cpp
@@ -79,6 +79,7 @@
const int FIELD_ID_BAD_VALUE_TYPE = 5;
const int FIELD_ID_CONDITION_CHANGE_IN_NEXT_BUCKET = 6;
const int FIELD_ID_INVALIDATED_BUCKET = 7;
+const int FIELD_ID_BUCKET_DROPPED = 8;
namespace {
@@ -497,6 +498,8 @@
(long long)pair.second.conditionChangeInNextBucket);
protoOutput->write(FIELD_TYPE_INT64 | FIELD_ID_INVALIDATED_BUCKET,
(long long)pair.second.invalidatedBucket);
+ protoOutput->write(FIELD_TYPE_INT64 | FIELD_ID_BUCKET_DROPPED,
+ (long long)pair.second.bucketDropped);
protoOutput->end(token);
}
diff --git a/cmds/statsd/tests/metrics/ValueMetricProducer_test.cpp b/cmds/statsd/tests/metrics/ValueMetricProducer_test.cpp
index 6404552..91b98ec 100644
--- a/cmds/statsd/tests/metrics/ValueMetricProducer_test.cpp
+++ b/cmds/statsd/tests/metrics/ValueMetricProducer_test.cpp
@@ -167,9 +167,10 @@
EXPECT_EQ(true, curInterval.hasBase);
EXPECT_EQ(11, curInterval.base.long_value);
- EXPECT_EQ(true, curInterval.hasValue);
+ EXPECT_EQ(false, curInterval.hasValue);
EXPECT_EQ(8, curInterval.value.long_value);
- EXPECT_EQ(0UL, valueProducer.mPastBuckets.size());
+ EXPECT_EQ(1UL, valueProducer.mPastBuckets.size());
+ EXPECT_EQ(8, valueProducer.mPastBuckets.begin()->second[0].values[0].long_value);
allData.clear();
event = make_shared<LogEvent>(tagId, bucket3StartTimeNs + 1);
@@ -184,11 +185,12 @@
EXPECT_EQ(true, curInterval.hasBase);
EXPECT_EQ(23, curInterval.base.long_value);
- EXPECT_EQ(true, curInterval.hasValue);
+ EXPECT_EQ(false, curInterval.hasValue);
EXPECT_EQ(12, curInterval.value.long_value);
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(2UL, valueProducer.mPastBuckets.begin()->second.size());
+ EXPECT_EQ(8, valueProducer.mPastBuckets.begin()->second[0].values[0].long_value);
+ EXPECT_EQ(12, valueProducer.mPastBuckets.begin()->second.back().values[0].long_value);
allData.clear();
event = make_shared<LogEvent>(tagId, bucket4StartTimeNs + 1);
@@ -202,11 +204,80 @@
EXPECT_EQ(true, curInterval.hasBase);
EXPECT_EQ(36, curInterval.base.long_value);
- EXPECT_EQ(true, curInterval.hasValue);
+ EXPECT_EQ(false, curInterval.hasValue);
EXPECT_EQ(13, curInterval.value.long_value);
EXPECT_EQ(1UL, valueProducer.mPastBuckets.size());
- EXPECT_EQ(2UL, valueProducer.mPastBuckets.begin()->second.size());
- EXPECT_EQ(12, valueProducer.mPastBuckets.begin()->second.back().values[0].long_value);
+ EXPECT_EQ(3UL, valueProducer.mPastBuckets.begin()->second.size());
+ EXPECT_EQ(8, valueProducer.mPastBuckets.begin()->second[0].values[0].long_value);
+ EXPECT_EQ(12, valueProducer.mPastBuckets.begin()->second[1].values[0].long_value);
+ EXPECT_EQ(13, valueProducer.mPastBuckets.begin()->second[2].values[0].long_value);
+}
+
+TEST(ValueMetricProducerTest, TestPartialBucketCreated) {
+ 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);
+
+ 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>();
+ EXPECT_CALL(*pullerManager, RegisterReceiver(tagId, _, _, _)).WillOnce(Return());
+ EXPECT_CALL(*pullerManager, UnRegisterReceiver(tagId, _)).WillRepeatedly(Return());
+ 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;
+ }));
+
+ ValueMetricProducer valueProducer(kConfigKey, metric, -1 /*-1 meaning no condition*/, wizard,
+ logEventMatcherIndex, eventMatcherWizard, tagId,
+ bucketStartTimeNs, bucketStartTimeNs, pullerManager);
+
+ // 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);
+
+ // 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);
+ // Full bucket (5 - 3)
+ EXPECT_EQ(3, buckets[1].values[0].long_value);
}
/*
@@ -264,9 +335,10 @@
EXPECT_EQ(true, curInterval.hasBase);
EXPECT_EQ(11, curInterval.base.long_value);
- EXPECT_EQ(true, curInterval.hasValue);
+ EXPECT_EQ(false, curInterval.hasValue);
EXPECT_EQ(8, curInterval.value.long_value);
- EXPECT_EQ(0UL, valueProducer.mPastBuckets.size());
+ EXPECT_EQ(1UL, valueProducer.mPastBuckets.size());
+ EXPECT_EQ(8, valueProducer.mPastBuckets.begin()->second[0].values[0].long_value);
allData.clear();
event = make_shared<LogEvent>(tagId, bucket3StartTimeNs + 1);
@@ -275,16 +347,15 @@
event->init();
allData.push_back(event);
valueProducer.onDataPulled(allData, /** succeed */ true);
- // has one slice
- EXPECT_EQ(1UL, valueProducer.mCurrentSlicedBucket.size());
- curInterval = valueProducer.mCurrentSlicedBucket.begin()->second[0];
+ // No new data seen, so data has been cleared.
+ EXPECT_EQ(0UL, valueProducer.mCurrentSlicedBucket.size());
EXPECT_EQ(true, curInterval.hasBase);
EXPECT_EQ(11, curInterval.base.long_value);
- // no events caused flush of bucket
- EXPECT_EQ(true, curInterval.hasValue);
+ EXPECT_EQ(false, curInterval.hasValue);
EXPECT_EQ(8, curInterval.value.long_value);
- EXPECT_EQ(0UL, valueProducer.mPastBuckets.size());
+ EXPECT_EQ(1UL, valueProducer.mPastBuckets.size());
+ EXPECT_EQ(8, valueProducer.mPastBuckets.begin()->second[0].values[0].long_value);
allData.clear();
event = make_shared<LogEvent>(tagId, bucket4StartTimeNs + 1);
@@ -363,9 +434,10 @@
curInterval = valueProducer.mCurrentSlicedBucket.begin()->second[0];
EXPECT_EQ(true, curInterval.hasBase);
EXPECT_EQ(10, curInterval.base.long_value);
- EXPECT_EQ(true, curInterval.hasValue);
+ EXPECT_EQ(false, curInterval.hasValue);
EXPECT_EQ(10, curInterval.value.long_value);
- EXPECT_EQ(0UL, valueProducer.mPastBuckets.size());
+ EXPECT_EQ(1UL, valueProducer.mPastBuckets.size());
+ EXPECT_EQ(10, valueProducer.mPastBuckets.begin()->second.back().values[0].long_value);
allData.clear();
event = make_shared<LogEvent>(tagId, bucket4StartTimeNs + 1);
@@ -378,11 +450,12 @@
curInterval = valueProducer.mCurrentSlicedBucket.begin()->second[0];
EXPECT_EQ(true, curInterval.hasBase);
EXPECT_EQ(36, curInterval.base.long_value);
- EXPECT_EQ(true, curInterval.hasValue);
+ EXPECT_EQ(false, curInterval.hasValue);
EXPECT_EQ(26, curInterval.value.long_value);
EXPECT_EQ(1UL, valueProducer.mPastBuckets.size());
- EXPECT_EQ(1UL, valueProducer.mPastBuckets.begin()->second.size());
- EXPECT_EQ(10, valueProducer.mPastBuckets.begin()->second.back().values[0].long_value);
+ EXPECT_EQ(2UL, valueProducer.mPastBuckets.begin()->second.size());
+ EXPECT_EQ(10, valueProducer.mPastBuckets.begin()->second[0].values[0].long_value);
+ EXPECT_EQ(26, valueProducer.mPastBuckets.begin()->second[1].values[0].long_value);
}
/*
@@ -456,9 +529,10 @@
curInterval = valueProducer.mCurrentSlicedBucket.begin()->second[0];
EXPECT_EQ(true, curInterval.hasBase);
EXPECT_EQ(36, curInterval.base.long_value);
- EXPECT_EQ(true, curInterval.hasValue);
+ EXPECT_EQ(false, curInterval.hasValue);
EXPECT_EQ(26, curInterval.value.long_value);
- EXPECT_EQ(0UL, valueProducer.mPastBuckets.size());
+ EXPECT_EQ(1UL, valueProducer.mPastBuckets.size());
+ EXPECT_EQ(26, valueProducer.mPastBuckets.begin()->second[0].values[0].long_value);
}
/*
@@ -532,9 +606,10 @@
curInterval = valueProducer.mCurrentSlicedBucket.begin()->second[0];
EXPECT_EQ(true, curInterval.hasBase);
EXPECT_EQ(110, curInterval.base.long_value);
- EXPECT_EQ(true, curInterval.hasValue);
+ EXPECT_EQ(false, curInterval.hasValue);
EXPECT_EQ(10, curInterval.value.long_value);
- EXPECT_EQ(0UL, valueProducer.mPastBuckets.size());
+ EXPECT_EQ(1UL, valueProducer.mPastBuckets.size());
+ EXPECT_EQ(10, valueProducer.mPastBuckets.begin()->second[0].values[0].long_value);
valueProducer.onConditionChanged(false, bucket2StartTimeNs + 1);
@@ -651,8 +726,8 @@
event->init();
allData.push_back(event);
valueProducer.onDataPulled(allData, /** succeed */ true);
- EXPECT_EQ(1UL, valueProducer.mPastBuckets[DEFAULT_METRIC_DIMENSION_KEY].size());
- EXPECT_EQ(bucket2StartTimeNs + 150, valueProducer.mCurrentBucketStartTimeNs);
+ EXPECT_EQ(2UL, valueProducer.mPastBuckets[DEFAULT_METRIC_DIMENSION_KEY].size());
+ EXPECT_EQ(bucket3StartTimeNs, valueProducer.mCurrentBucketStartTimeNs);
EXPECT_EQ(20L,
valueProducer.mPastBuckets[DEFAULT_METRIC_DIMENSION_KEY][0].values[0].long_value);
}
@@ -694,7 +769,7 @@
valueProducer.notifyAppUpgrade(bucket2StartTimeNs + 150, "ANY.APP", 1, 1);
EXPECT_EQ(0UL, valueProducer.mPastBuckets[DEFAULT_METRIC_DIMENSION_KEY].size());
- EXPECT_EQ(bucketStartTimeNs, valueProducer.mCurrentBucketStartTimeNs);
+ EXPECT_EQ(bucket2StartTimeNs, valueProducer.mCurrentBucketStartTimeNs);
}
TEST(ValueMetricProducerTest, TestPulledValueWithUpgradeWhileConditionFalse) {
@@ -1018,9 +1093,9 @@
// tartUpdated:false sum:12
EXPECT_EQ(true, curInterval.hasBase);
EXPECT_EQ(23, curInterval.base.long_value);
- EXPECT_EQ(true, curInterval.hasValue);
- EXPECT_EQ(12, curInterval.value.long_value);
- EXPECT_EQ(0UL, valueProducer.mPastBuckets.size());
+ EXPECT_EQ(false, curInterval.hasValue);
+ EXPECT_EQ(1UL, valueProducer.mPastBuckets.size());
+ EXPECT_EQ(12, valueProducer.mPastBuckets.begin()->second.back().values[0].long_value);
// pull 3 come late.
// The previous bucket gets closed with error. (Has start value 23, no ending)
@@ -1681,7 +1756,7 @@
EXPECT_EQ(2UL, valueProducer.mCurrentSlicedBucket.size());
EXPECT_EQ(true, interval1.hasBase);
EXPECT_EQ(11, interval1.base.long_value);
- EXPECT_EQ(true, interval1.hasValue);
+ EXPECT_EQ(false, interval1.hasValue);
EXPECT_EQ(8, interval1.value.long_value);
auto it = valueProducer.mCurrentSlicedBucket.begin();
@@ -1695,9 +1770,14 @@
EXPECT_EQ(2, it->first.getDimensionKeyInWhat().getValues()[0].mValue.int_value);
EXPECT_EQ(true, interval2.hasBase);
EXPECT_EQ(4, interval2.base.long_value);
- EXPECT_EQ(true, interval2.hasValue);
+ EXPECT_EQ(false, interval2.hasValue);
EXPECT_EQ(4, interval2.value.long_value);
- EXPECT_EQ(0UL, valueProducer.mPastBuckets.size());
+
+ EXPECT_EQ(2UL, valueProducer.mPastBuckets.size());
+ auto iterator = valueProducer.mPastBuckets.begin();
+ EXPECT_EQ(8, iterator->second[0].values[0].long_value);
+ iterator++;
+ EXPECT_EQ(4, iterator->second[0].values[0].long_value);
}
/*
@@ -1766,7 +1846,7 @@
EXPECT_EQ(2UL, valueProducer.mCurrentSlicedBucket.size());
EXPECT_EQ(true, interval1.hasBase);
EXPECT_EQ(11, interval1.base.long_value);
- EXPECT_EQ(true, interval1.hasValue);
+ EXPECT_EQ(false, interval1.hasValue);
EXPECT_EQ(8, interval1.value.long_value);
auto it = valueProducer.mCurrentSlicedBucket.begin();
@@ -1780,9 +1860,9 @@
EXPECT_EQ(2, it->first.getDimensionKeyInWhat().getValues()[0].mValue.int_value);
EXPECT_EQ(true, interval2.hasBase);
EXPECT_EQ(4, interval2.base.long_value);
- EXPECT_EQ(true, interval2.hasValue);
+ EXPECT_EQ(false, interval2.hasValue);
EXPECT_EQ(4, interval2.value.long_value);
- EXPECT_EQ(0UL, valueProducer.mPastBuckets.size());
+ EXPECT_EQ(2UL, valueProducer.mPastBuckets.size());
// next pull somehow did not happen, skip to end of bucket 3
allData.clear();
@@ -1793,11 +1873,11 @@
allData.push_back(event1);
valueProducer.onDataPulled(allData, /** succeed */ true);
- EXPECT_EQ(2UL, valueProducer.mCurrentSlicedBucket.size());
+ EXPECT_EQ(1UL, valueProducer.mCurrentSlicedBucket.size());
EXPECT_EQ(true, interval2.hasBase);
- EXPECT_EQ(5, interval2.base.long_value);
+ EXPECT_EQ(4, interval2.base.long_value);
EXPECT_EQ(false, interval2.hasValue);
- EXPECT_EQ(false, interval1.hasBase);
+ EXPECT_EQ(true, interval1.hasBase);
EXPECT_EQ(false, interval1.hasValue);
EXPECT_EQ(true, valueProducer.mHasGlobalBase);
EXPECT_EQ(2UL, valueProducer.mPastBuckets.size());
@@ -1817,13 +1897,13 @@
EXPECT_EQ(2UL, valueProducer.mCurrentSlicedBucket.size());
EXPECT_EQ(true, interval2.hasBase);
- EXPECT_EQ(13, interval2.base.long_value);
- EXPECT_EQ(true, interval2.hasValue);
- EXPECT_EQ(8, interval2.value.long_value);
+ EXPECT_EQ(5, interval2.base.long_value);
+ EXPECT_EQ(false, interval2.hasValue);
+ EXPECT_EQ(5, interval2.value.long_value);
EXPECT_EQ(true, interval1.hasBase);
- EXPECT_EQ(5, interval1.base.long_value);
- EXPECT_EQ(true, interval1.hasValue);
- EXPECT_EQ(5, interval1.value.long_value);
+ EXPECT_EQ(13, interval1.base.long_value);
+ EXPECT_EQ(false, interval1.hasValue);
+ EXPECT_EQ(8, interval1.value.long_value);
EXPECT_EQ(true, valueProducer.mHasGlobalBase);
EXPECT_EQ(2UL, valueProducer.mPastBuckets.size());
}
@@ -1892,9 +1972,11 @@
EXPECT_EQ(2UL, valueProducer.mCurrentSlicedBucket.size());
EXPECT_EQ(true, interval1.hasBase);
EXPECT_EQ(11, interval1.base.long_value);
- EXPECT_EQ(true, interval1.hasValue);
+ EXPECT_EQ(false, interval1.hasValue);
EXPECT_EQ(8, interval1.value.long_value);
- EXPECT_TRUE(interval1.seenNewData);
+ EXPECT_FALSE(interval1.seenNewData);
+ EXPECT_EQ(1UL, valueProducer.mPastBuckets.size());
+ EXPECT_EQ(8, valueProducer.mPastBuckets.begin()->second[0].values[0].long_value);
auto it = valueProducer.mCurrentSlicedBucket.begin();
for (; it != valueProducer.mCurrentSlicedBucket.end(); it++) {
@@ -1908,8 +1990,8 @@
EXPECT_EQ(true, interval2.hasBase);
EXPECT_EQ(4, interval2.base.long_value);
EXPECT_EQ(false, interval2.hasValue);
- EXPECT_TRUE(interval2.seenNewData);
- EXPECT_EQ(0UL, valueProducer.mPastBuckets.size());
+ EXPECT_FALSE(interval2.seenNewData);
+ EXPECT_EQ(1UL, valueProducer.mPastBuckets.size());
// next pull somehow did not happen, skip to end of bucket 3
allData.clear();
@@ -1920,35 +2002,34 @@
allData.push_back(event1);
valueProducer.onDataPulled(allData, /** succeed */ true);
- EXPECT_EQ(2UL, valueProducer.mCurrentSlicedBucket.size());
-
- EXPECT_EQ(false, interval1.hasBase);
- EXPECT_EQ(false, interval1.hasValue);
- EXPECT_EQ(8, interval1.value.long_value);
- // on probation now
- EXPECT_FALSE(interval1.seenNewData);
-
+ // Only one interval left. One was trimmed.
+ EXPECT_EQ(1UL, valueProducer.mCurrentSlicedBucket.size());
+ interval2 = valueProducer.mCurrentSlicedBucket.begin()->second[0];
+ EXPECT_EQ(2, it->first.getDimensionKeyInWhat().getValues()[0].mValue.int_value);
EXPECT_EQ(true, interval2.hasBase);
EXPECT_EQ(5, interval2.base.long_value);
EXPECT_EQ(false, interval2.hasValue);
- // back to good status
- EXPECT_TRUE(interval2.seenNewData);
+ EXPECT_FALSE(interval2.seenNewData);
EXPECT_EQ(1UL, valueProducer.mPastBuckets.size());
allData.clear();
event1 = make_shared<LogEvent>(tagId, bucket5StartTimeNs + 1);
event1->write(2);
- event1->write(13);
+ event1->write(14);
event1->init();
allData.push_back(event1);
valueProducer.onDataPulled(allData, /** succeed */ true);
- EXPECT_EQ(1UL, valueProducer.mCurrentSlicedBucket.size());
+ interval2 = valueProducer.mCurrentSlicedBucket.begin()->second[0];
EXPECT_EQ(true, interval2.hasBase);
- EXPECT_EQ(13, interval2.base.long_value);
- EXPECT_EQ(true, interval2.hasValue);
- EXPECT_EQ(8, interval2.value.long_value);
- EXPECT_EQ(1UL, valueProducer.mPastBuckets.size());
+ EXPECT_EQ(14, interval2.base.long_value);
+ EXPECT_EQ(false, interval2.hasValue);
+ EXPECT_FALSE(interval2.seenNewData);
+ EXPECT_EQ(2UL, valueProducer.mPastBuckets.size());
+ auto iterator = valueProducer.mPastBuckets.begin();
+ EXPECT_EQ(9, iterator->second[0].values[0].long_value);
+ iterator++;
+ EXPECT_EQ(8, iterator->second[0].values[0].long_value);
}
TEST(ValueMetricProducerTest, TestResetBaseOnPullFailAfterConditionChange_EndOfBucket) {
@@ -2110,7 +2191,7 @@
EXPECT_EQ(false, valueProducer.mHasGlobalBase);
}
-TEST(ValueMetricProducerTest, TestResetBaseOnPullTooLate) {
+TEST(ValueMetricProducerTest, TestResetBaseOnPullDelayExceeded) {
ValueMetric metric;
metric.set_id(metricId);
metric.set_bucket(ONE_MINUTE);
@@ -2133,7 +2214,7 @@
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, bucket2StartTimeNs + 1);
+ shared_ptr<LogEvent> event = make_shared<LogEvent>(tagId, bucketStartTimeNs + 1);
event->write(tagId);
event->write(120);
event->init();
@@ -2145,35 +2226,91 @@
eventMatcherWizard, tagId, bucketStartTimeNs,
bucketStartTimeNs, pullerManager);
- valueProducer.mCondition = true;
+ valueProducer.mCondition = false;
+
+ // Max delay is set to 0 so pull will exceed max delay.
+ valueProducer.onConditionChanged(true, bucketStartTimeNs + 1);
+ EXPECT_EQ(0UL, valueProducer.mCurrentSlicedBucket.size());
+}
+
+TEST(ValueMetricProducerTest, TestResetBaseOnPullTooLate) {
+ 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_condition(StringToId("SCREEN_ON"));
+ metric.set_max_pull_delay_sec(INT_MAX);
+
+ 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>();
+ EXPECT_CALL(*pullerManager, RegisterReceiver(tagId, _, _, _)).WillOnce(Return());
+ EXPECT_CALL(*pullerManager, UnRegisterReceiver(tagId, _)).WillRepeatedly(Return());
+
+ ValueMetricProducer valueProducer(kConfigKey, metric, 1, wizard, logEventMatcherIndex,
+ eventMatcherWizard, tagId, bucket2StartTimeNs,
+ bucket2StartTimeNs, pullerManager);
+
+ valueProducer.mCondition = false;
+
+ // Event should be skipped since it is from previous bucket.
+ // Pull should not be called.
+ valueProducer.onConditionChanged(true, bucketStartTimeNs);
+ EXPECT_EQ(0UL, valueProducer.mCurrentSlicedBucket.size());
+}
+
+TEST(ValueMetricProducerTest, TestBaseSetOnConditionChange) {
+ 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_condition(StringToId("SCREEN_ON"));
+ metric.set_max_pull_delay_sec(INT_MAX);
+
+ 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>();
+ EXPECT_CALL(*pullerManager, RegisterReceiver(tagId, _, _, _)).WillOnce(Return());
+ EXPECT_CALL(*pullerManager, UnRegisterReceiver(tagId, _)).WillRepeatedly(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 + 1);
+ event->write(tagId);
+ event->write(100);
+ event->init();
+ data->push_back(event);
+ return true;
+ }));
+
+ ValueMetricProducer valueProducer(kConfigKey, metric, 1, wizard, logEventMatcherIndex,
+ eventMatcherWizard, tagId, bucketStartTimeNs,
+ bucketStartTimeNs, pullerManager);
+
+ valueProducer.mCondition = false;
+ valueProducer.mHasGlobalBase = false;
+
+ valueProducer.onConditionChanged(true, bucketStartTimeNs + 1);
valueProducer.mHasGlobalBase = true;
-
- vector<shared_ptr<LogEvent>> allData;
- allData.clear();
- shared_ptr<LogEvent> event = make_shared<LogEvent>(tagId, bucket2StartTimeNs + 1);
- event->write(1);
- event->write(110);
- event->init();
- allData.push_back(event);
- valueProducer.onDataPulled(allData, /** succeed */ true);
-
- // has one slice
EXPECT_EQ(1UL, valueProducer.mCurrentSlicedBucket.size());
ValueMetricProducer::Interval& curInterval =
valueProducer.mCurrentSlicedBucket.begin()->second[0];
EXPECT_EQ(true, curInterval.hasBase);
- EXPECT_EQ(110, curInterval.base.long_value);
+ EXPECT_EQ(100, curInterval.base.long_value);
EXPECT_EQ(false, curInterval.hasValue);
- EXPECT_EQ(0UL, valueProducer.mPastBuckets.size());
EXPECT_EQ(true, valueProducer.mHasGlobalBase);
-
- valueProducer.onConditionChanged(false, bucket2StartTimeNs + 1);
-
- // has one slice
- EXPECT_EQ(1UL, valueProducer.mCurrentSlicedBucket.size());
- EXPECT_EQ(false, curInterval.hasValue);
- EXPECT_EQ(false, curInterval.hasBase);
- EXPECT_EQ(false, valueProducer.mHasGlobalBase);
}
TEST(ValueMetricProducerTest, TestInvalidBucketWhenOneConditionFailed) {
diff --git a/core/java/android/content/Intent.java b/core/java/android/content/Intent.java
index a3021f3..d781a96 100644
--- a/core/java/android/content/Intent.java
+++ b/core/java/android/content/Intent.java
@@ -817,28 +817,6 @@
= "android.intent.action.SHOW_APP_INFO";
/**
- * Activity Action: Start an activity to show the app's detailed usage information for
- * permission protected data.
- *
- * The Intent contains an extra {@link #EXTRA_PERMISSION_USAGE_PERMISSIONS} that is of
- * type {@code String[]} and contains the specific permissions to show information for.
- *
- * Apps should handle this intent if they want to provide more information about permission
- * usage to users beyond the information provided in the manifest.
- */
- @SdkConstant(SdkConstantType.ACTIVITY_INTENT_ACTION)
- public static final String ACTION_PERMISSION_USAGE_DETAILS =
- "android.intent.action.PERMISSION_USAGE_DETAILS";
-
- /**
- * The name of the extra used to contain the permissions in
- * {@link #ACTION_PERMISSION_USAGE_DETAILS}.
- * @see #ACTION_PERMISSION_USAGE_DETAILS
- */
- public static final String EXTRA_PERMISSION_USAGE_PERMISSIONS =
- "android.intent.extra.PERMISSION_USAGE_PERMISSIONS";
-
- /**
* Represents a shortcut/live folder icon resource.
*
* @see Intent#ACTION_CREATE_SHORTCUT
diff --git a/core/java/android/content/pm/PackageInfo.java b/core/java/android/content/pm/PackageInfo.java
index 6d22277..27a5b39 100644
--- a/core/java/android/content/pm/PackageInfo.java
+++ b/core/java/android/content/pm/PackageInfo.java
@@ -204,10 +204,7 @@
* {@link PackageManager#GET_PERMISSIONS} was set. This list includes
* all permissions requested, even those that were not granted or known
* by the system at install time.
- *
- * @deprecated Use {@link #usesPermissions}
*/
- @Deprecated
public String[] requestedPermissions;
/**
@@ -217,23 +214,10 @@
* {@link PackageManager#GET_PERMISSIONS} was set. Each value matches
* the corresponding entry in {@link #requestedPermissions}, and will have
* the flag {@link #REQUESTED_PERMISSION_GRANTED} set as appropriate.
- *
- * @deprecated Use {@link #usesPermissions}
*/
- @Deprecated
public int[] requestedPermissionsFlags;
/**
- * Array of all {@link android.R.styleable#AndroidManifestUsesPermission
- * <uses-permission>} tags included under <manifest>,
- * or null if there were none. This is only filled in if the flag
- * {@link PackageManager#GET_PERMISSIONS} was set. This list includes
- * all permissions requested, even those that were not granted or known
- * by the system at install time.
- */
- public UsesPermissionInfo[] usesPermissions;
-
- /**
* Flag for {@link #requestedPermissionsFlags}: the requested permission
* is required for the application to run; the user can not optionally
* disable it. Currently all permissions are required.
@@ -480,7 +464,6 @@
dest.writeTypedArray(permissions, parcelableFlags);
dest.writeStringArray(requestedPermissions);
dest.writeIntArray(requestedPermissionsFlags);
- dest.writeTypedArray(usesPermissions, parcelableFlags);
dest.writeTypedArray(signatures, parcelableFlags);
dest.writeTypedArray(configPreferences, parcelableFlags);
dest.writeTypedArray(reqFeatures, parcelableFlags);
@@ -545,7 +528,6 @@
permissions = source.createTypedArray(PermissionInfo.CREATOR);
requestedPermissions = source.createStringArray();
requestedPermissionsFlags = source.createIntArray();
- usesPermissions = source.createTypedArray(UsesPermissionInfo.CREATOR);
signatures = source.createTypedArray(Signature.CREATOR);
configPreferences = source.createTypedArray(ConfigurationInfo.CREATOR);
reqFeatures = source.createTypedArray(FeatureInfo.CREATOR);
diff --git a/core/java/android/content/pm/PackageParser.java b/core/java/android/content/pm/PackageParser.java
index 81ed110..5020a94 100644
--- a/core/java/android/content/pm/PackageParser.java
+++ b/core/java/android/content/pm/PackageParser.java
@@ -791,23 +791,18 @@
pi.permissions[i] = generatePermissionInfo(p.permissions.get(i), flags);
}
}
- N = p.usesPermissionInfos.size();
+ N = p.requestedPermissions.size();
if (N > 0) {
pi.requestedPermissions = new String[N];
pi.requestedPermissionsFlags = new int[N];
- pi.usesPermissions = new UsesPermissionInfo[N];
for (int i=0; i<N; i++) {
- UsesPermissionInfo info = p.usesPermissionInfos.get(i);
- final String perm = info.getPermission();
+ final String perm = p.requestedPermissions.get(i);
pi.requestedPermissions[i] = perm;
- int permissionFlags = 0;
// The notion of required permissions is deprecated but for compatibility.
- permissionFlags |= PackageInfo.REQUESTED_PERMISSION_REQUIRED;
+ pi.requestedPermissionsFlags[i] |= PackageInfo.REQUESTED_PERMISSION_REQUIRED;
if (grantedPermissions != null && grantedPermissions.contains(perm)) {
- permissionFlags |= PackageInfo.REQUESTED_PERMISSION_GRANTED;
+ pi.requestedPermissionsFlags[i] |= PackageInfo.REQUESTED_PERMISSION_GRANTED;
}
- pi.requestedPermissionsFlags[i] = permissionFlags;
- pi.usesPermissions[i] = new UsesPermissionInfo(info, permissionFlags);
}
}
}
@@ -2175,12 +2170,12 @@
return null;
}
} else if (tagName.equals(TAG_USES_PERMISSION)) {
- if (!parseUsesPermission(pkg, res, parser, outError)) {
+ if (!parseUsesPermission(pkg, res, parser)) {
return null;
}
} else if (tagName.equals(TAG_USES_PERMISSION_SDK_M)
|| tagName.equals(TAG_USES_PERMISSION_SDK_23)) {
- if (!parseUsesPermission(pkg, res, parser, outError)) {
+ if (!parseUsesPermission(pkg, res, parser)) {
return null;
}
} else if (tagName.equals(TAG_USES_CONFIGURATION)) {
@@ -2498,7 +2493,7 @@
newPermsMsg.append(' ');
}
newPermsMsg.append(npi.name);
- addRequestedPermission(pkg, npi.name);
+ pkg.requestedPermissions.add(npi.name);
pkg.implicitPermissions.add(npi.name);
}
}
@@ -2519,7 +2514,7 @@
for (int in = 0; in < newPerms.size(); in++) {
final String perm = newPerms.get(in);
if (!pkg.requestedPermissions.contains(perm)) {
- addRequestedPermission(pkg, perm);
+ pkg.requestedPermissions.add(perm);
pkg.implicitPermissions.add(perm);
}
}
@@ -2599,13 +2594,13 @@
}
} else {
if (FORCE_AUDIO_PACKAGES.contains(pkg.packageName)) {
- addRequestedPermission(pkg, android.Manifest.permission.READ_MEDIA_AUDIO);
+ pkg.requestedPermissions.add(android.Manifest.permission.READ_MEDIA_AUDIO);
}
if (FORCE_VIDEO_PACKAGES.contains(pkg.packageName)) {
- addRequestedPermission(pkg, android.Manifest.permission.READ_MEDIA_VIDEO);
+ pkg.requestedPermissions.add(android.Manifest.permission.READ_MEDIA_VIDEO);
}
if (FORCE_IMAGES_PACKAGES.contains(pkg.packageName)) {
- addRequestedPermission(pkg, android.Manifest.permission.READ_MEDIA_IMAGES);
+ pkg.requestedPermissions.add(android.Manifest.permission.READ_MEDIA_IMAGES);
}
}
@@ -2645,12 +2640,6 @@
}
/**
- * Helper method for adding a requested permission to a package outside of a uses-permission.
- */
- private void addRequestedPermission(Package pkg, String permission) {
- pkg.requestedPermissions.add(permission);
- pkg.usesPermissionInfos.add(new UsesPermissionInfo(permission));
- }
/**
* Matches a given {@code targetCode} against a set of release codeNames. Target codes can
@@ -2987,8 +2976,8 @@
return certSha256Digests;
}
- private boolean parseUsesPermission(Package pkg, Resources res, XmlResourceParser parser,
- String[] outError) throws XmlPullParserException, IOException {
+ private boolean parseUsesPermission(Package pkg, Resources res, XmlResourceParser parser)
+ throws XmlPullParserException, IOException {
TypedArray sa = res.obtainAttributes(parser,
com.android.internal.R.styleable.AndroidManifestUsesPermission);
@@ -3012,44 +3001,6 @@
final String requiredNotfeature = sa.getNonConfigurationString(
com.android.internal.R.styleable.AndroidManifestUsesPermission_requiredNotFeature, 0);
- int dataSentOffDevice = sa.getInt(
- com.android.internal.R.styleable.AndroidManifestUsesPermission_dataSentOffDevice, 0);
-
- int dataSharedWithThirdParty = sa.getInt(
- com.android.internal.R.styleable.AndroidManifestUsesPermission_dataSharedWithThirdParty, 0);
-
- int dataUsedForMonetization = sa.getInt(
- com.android.internal.R.styleable.AndroidManifestUsesPermission_dataUsedForMonetization, 0);
-
- int retentionWeeks = -1;
- int retention;
-
- String rawRetention = sa.getString(
- com.android.internal.R.styleable.AndroidManifestUsesPermission_dataRetentionTime);
-
- if (rawRetention == null) {
- retention = UsesPermissionInfo.RETENTION_UNDEFINED;
- } else if ("notRetained".equals(rawRetention)) {
- retention = UsesPermissionInfo.RETENTION_NOT_RETAINED;
- } else if ("userSelected".equals(rawRetention)) {
- retention = UsesPermissionInfo.RETENTION_USER_SELECTED;
- } else if ("unlimited".equals(rawRetention)) {
- retention = UsesPermissionInfo.RETENTION_UNLIMITED;
- } else {
- // A number of weeks was specified
- retention = UsesPermissionInfo.RETENTION_SPECIFIED;
- retentionWeeks = sa.getInt(
- com.android.internal.R.styleable.AndroidManifestUsesPermission_dataRetentionTime,
- -1);
-
- if (retentionWeeks < 0) {
- outError[0] = "Bad value provided for dataRetentionTime.";
- mParseError = PackageManager.INSTALL_PARSE_FAILED_MANIFEST_MALFORMED;
- XmlUtils.skipCurrentTag(parser);
- sa.recycle();
- return false;
- }
- }
sa.recycle();
XmlUtils.skipCurrentTag(parser);
@@ -3082,10 +3033,6 @@
+ parser.getPositionDescription());
}
- UsesPermissionInfo info = new UsesPermissionInfo(name, dataSentOffDevice,
- dataSharedWithThirdParty, dataUsedForMonetization, retention, retentionWeeks);
- pkg.usesPermissionInfos.add(info);
-
return true;
}
@@ -3420,10 +3367,6 @@
perm.info.flags = sa.getInt(
com.android.internal.R.styleable.AndroidManifestPermission_permissionFlags, 0);
- perm.info.usageInfoRequired = sa.getInt(
- com.android.internal.R.styleable.AndroidManifestPermission_usageInfoRequired, 0)
- != 0;
-
sa.recycle();
if (perm.info.protectionLevel == -1) {
@@ -6625,9 +6568,6 @@
@UnsupportedAppUsage
public final ArrayList<String> requestedPermissions = new ArrayList<String>();
- public final ArrayList<UsesPermissionInfo> usesPermissionInfos =
- new ArrayList<>();
-
/** Permissions requested but not in the manifest. */
public final ArrayList<String> implicitPermissions = new ArrayList<>();
@@ -7159,7 +7099,6 @@
dest.readStringList(requestedPermissions);
internStringArrayList(requestedPermissions);
- dest.readParcelableList(usesPermissionInfos, boot);
dest.readStringList(implicitPermissions);
internStringArrayList(implicitPermissions);
protectedBroadcasts = dest.createStringArrayList();
@@ -7327,7 +7266,6 @@
dest.writeParcelableList(instrumentation, flags);
dest.writeStringList(requestedPermissions);
- dest.writeParcelableList(usesPermissionInfos, flags);
dest.writeStringList(implicitPermissions);
dest.writeStringList(protectedBroadcasts);
diff --git a/core/java/android/content/pm/PermissionInfo.java b/core/java/android/content/pm/PermissionInfo.java
index fb63e0d..e245234 100644
--- a/core/java/android/content/pm/PermissionInfo.java
+++ b/core/java/android/content/pm/PermissionInfo.java
@@ -20,7 +20,6 @@
import android.annotation.SystemApi;
import android.annotation.TestApi;
import android.annotation.UnsupportedAppUsage;
-import android.os.Build;
import android.os.Parcel;
import android.os.Parcelable;
import android.text.TextUtils;
@@ -368,12 +367,6 @@
*/
public CharSequence nonLocalizedDescription;
- /**
- * If {@code true} an application targeting {@link Build.VERSION_CODES#Q} <em>must</em>
- * include permission data usage information in order to be able to be granted this permission.
- */
- public boolean usageInfoRequired;
-
/** @hide */
public static int fixProtectionLevel(int level) {
if (level == PROTECTION_SIGNATURE_OR_SYSTEM) {
@@ -475,7 +468,6 @@
descriptionRes = orig.descriptionRes;
requestRes = orig.requestRes;
nonLocalizedDescription = orig.nonLocalizedDescription;
- usageInfoRequired = orig.usageInfoRequired;
}
/**
@@ -540,7 +532,6 @@
dest.writeInt(descriptionRes);
dest.writeInt(requestRes);
TextUtils.writeToParcel(nonLocalizedDescription, dest, parcelableFlags);
- dest.writeInt(usageInfoRequired ? 1 : 0);
}
/** @hide */
@@ -581,6 +572,5 @@
descriptionRes = source.readInt();
requestRes = source.readInt();
nonLocalizedDescription = TextUtils.CHAR_SEQUENCE_CREATOR.createFromParcel(source);
- usageInfoRequired = source.readInt() != 0;
}
}
diff --git a/core/java/android/content/pm/UsesPermissionInfo.java b/core/java/android/content/pm/UsesPermissionInfo.java
deleted file mode 100644
index d08548f..0000000
--- a/core/java/android/content/pm/UsesPermissionInfo.java
+++ /dev/null
@@ -1,275 +0,0 @@
-/*
- * Copyright (C) 2018 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.content.pm;
-
-import android.annotation.IntDef;
-import android.os.Parcel;
-import android.os.Parcelable;
-
-import java.lang.annotation.RetentionPolicy;
-/**
- * Information you can retrive about a particular application requested permission. This
- * corresponds to information collected from the AndroidManifest.xml's <uses-permission>
- * tags.
- */
-public final class UsesPermissionInfo extends PackageItemInfo implements Parcelable {
-
- /**
- * Flag for {@link #getFlags()}: the requested permission is currently granted to the
- * application.
- */
- public static final int FLAG_REQUESTED_PERMISSION_GRANTED = 1 << 1;
-
- /** @hide */
- @IntDef(flag = true, prefix = {"FLAG_"}, value = {FLAG_REQUESTED_PERMISSION_GRANTED})
- @java.lang.annotation.Retention(RetentionPolicy.SOURCE)
- public @interface Flags {}
-
- /** An unset value for {@link #getDataSentOffDevice()},
- * {@link #getDataSharedWithThirdParty()}, and {@link #getDataUsedForMonetization()}
- */
- public static final int USAGE_UNDEFINED = 0;
-
- /**
- * A yes value for {@link #getDataSentOffDevice()}, {@link #getDataSharedWithThirdParty()},
- * and {@link #getDataUsedForMonetization()} corresponding to the <code>yes</code> value of
- * {@link android.R.attr#dataSentOffDevice}, {@link android.R.attr#dataSharedWithThirdParty},
- * and {@link android.R.attr#dataUsedForMonetization} attributes.
- */
- public static final int USAGE_YES = 1;
-
- /**
- * A user triggered only value for {@link #getDataSentOffDevice()},
- * {@link #getDataSharedWithThirdParty()}, and {@link #getDataUsedForMonetization()}
- * corresponding to the <code>userTriggered</code> value of
- * {@link android.R.attr#dataSentOffDevice}, {@link android.R.attr#dataSharedWithThirdParty},
- * and {@link android.R.attr#dataUsedForMonetization} attributes.
- */
- public static final int USAGE_USER_TRIGGERED = 2;
-
- /**
- * A no value for {@link #getDataSentOffDevice()}, {@link #getDataSharedWithThirdParty()},
- * and {@link #getDataUsedForMonetization()} corresponding to the <code>no</code> value of
- * {@link android.R.attr#dataSentOffDevice}, {@link android.R.attr#dataSharedWithThirdParty},
- * and {@link android.R.attr#dataUsedForMonetization} attributes.
- */
- public static final int USAGE_NO = 3;
-
- /** @hide */
- @IntDef(prefix = {"USAGE_"}, value = {
- USAGE_UNDEFINED,
- USAGE_YES,
- USAGE_USER_TRIGGERED,
- USAGE_NO})
- @java.lang.annotation.Retention(RetentionPolicy.SOURCE)
- public @interface Usage {}
-
- /**
- * An unset value for {@link #getDataRetention}.
- */
- public static final int RETENTION_UNDEFINED = 0;
-
- /**
- * A data not retained value for {@link #getDataRetention()} corresponding to the
- * <code>notRetained</code> value of {@link android.R.attr#dataRetentionTime}.
- */
- public static final int RETENTION_NOT_RETAINED = 1;
-
- /**
- * A user selected value for {@link #getDataRetention()} corresponding to the
- * <code>userSelected</code> value of {@link android.R.attr#dataRetentionTime}.
- */
- public static final int RETENTION_USER_SELECTED = 2;
-
- /**
- * An unlimited value for {@link #getDataRetention()} corresponding to the
- * <code>unlimited</code> value of {@link android.R.attr#dataRetentionTime}.
- */
- public static final int RETENTION_UNLIMITED = 3;
-
- /**
- * A specified value for {@link #getDataRetention()} corresponding to providing the number of
- * weeks data is retained in {@link android.R.attr#dataRetentionTime}. The number of weeks
- * is available in {@link #getDataRetentionWeeks()}.
- */
- public static final int RETENTION_SPECIFIED = 4;
-
- /** @hide */
- @IntDef(prefix = {"RETENTION_"}, value = {
- RETENTION_UNDEFINED,
- RETENTION_NOT_RETAINED,
- RETENTION_USER_SELECTED,
- RETENTION_UNLIMITED,
- RETENTION_SPECIFIED})
- @java.lang.annotation.Retention(RetentionPolicy.SOURCE)
- public @interface Retention {}
-
- private final String mPermission;
- private final @Flags int mFlags;
- private final @Usage int mDataSentOffDevice;
- private final @Usage int mDataSharedWithThirdParty;
- private final @Usage int mDataUsedForMonetization;
- private final @Retention int mDataRetention;
- private final int mDataRetentionWeeks;
-
- /** @hide */
- public UsesPermissionInfo(String permission) {
- mPermission = permission;
- mDataSentOffDevice = USAGE_UNDEFINED;
- mDataSharedWithThirdParty = USAGE_UNDEFINED;
- mDataUsedForMonetization = USAGE_UNDEFINED;
- mDataRetention = RETENTION_UNDEFINED;
- mDataRetentionWeeks = -1;
- mFlags = 0;
- }
-
- /** @hide */
- public UsesPermissionInfo(String permission,
- @Usage int dataSentOffDevice, @Usage int dataSharedWithThirdParty,
- @Usage int dataUsedForMonetization, @Retention int dataRetention,
- int dataRetentionWeeks) {
- mPermission = permission;
- mDataSentOffDevice = dataSentOffDevice;
- mDataSharedWithThirdParty = dataSharedWithThirdParty;
- mDataUsedForMonetization = dataUsedForMonetization;
- mDataRetention = dataRetention;
- mDataRetentionWeeks = dataRetentionWeeks;
- mFlags = 0;
- }
-
- /** @hide */
- public UsesPermissionInfo(UsesPermissionInfo orig) {
- this(orig, orig.mFlags);
- }
-
- /** @hide */
- public UsesPermissionInfo(UsesPermissionInfo orig, int flags) {
- super(orig);
- mPermission = orig.mPermission;
- mFlags = flags;
- mDataSentOffDevice = orig.mDataSentOffDevice;
- mDataSharedWithThirdParty = orig.mDataSharedWithThirdParty;
- mDataUsedForMonetization = orig.mDataUsedForMonetization;
- mDataRetention = orig.mDataRetention;
- mDataRetentionWeeks = orig.mDataRetentionWeeks;
- }
-
- /**
- * The name of the requested permission.
- */
- public String getPermission() {
- return mPermission;
- }
-
- public @Flags int getFlags() {
- return mFlags;
- }
-
- /**
- * If the application sends the data guarded by this permission off the device.
- *
- * See {@link android.R.attr#dataSentOffDevice}
- */
- public @Usage int getDataSentOffDevice() {
- return mDataSentOffDevice;
- }
-
- /**
- * If the application or its services shares the data guarded by this permission with third
- * parties.
- *
- * See {@link android.R.attr#dataSharedWithThirdParty}
- */
- public @Usage int getDataSharedWithThirdParty() {
- return mDataSharedWithThirdParty;
- }
-
- /**
- * If the application or its services use the data guarded by this permission for monetization
- * purposes.
- *
- * See {@link android.R.attr#dataUsedForMonetization}
- */
- public @Usage int getDataUsedForMonetization() {
- return mDataUsedForMonetization;
- }
-
- /**
- * How long the application or its services store the data guarded by this permission.
- * If set to {@link #RETENTION_SPECIFIED} {@link #getDataRetentionWeeks()} will contain the
- * number of weeks the data is stored.
- *
- * See {@link android.R.attr#dataRetentionTime}
- */
- public @Retention int getDataRetention() {
- return mDataRetention;
- }
-
- /**
- * If {@link #getDataRetention()} is {@link #RETENTION_SPECIFIED} the number of weeks the
- * application or its services store data guarded by this permission.
- *
- * @throws IllegalStateException if {@link #getDataRetention} is not
- * {@link #RETENTION_SPECIFIED}.
- */
- public int getDataRetentionWeeks() {
- if (mDataRetention != RETENTION_SPECIFIED) {
- throw new IllegalStateException("Data retention weeks not specified");
- }
- return mDataRetentionWeeks;
- }
-
- @Override
- public int describeContents() {
- return 0;
- }
-
- @Override
- public void writeToParcel(Parcel dest, int flags) {
- super.writeToParcel(dest, flags);
- dest.writeString(mPermission);
- dest.writeInt(mFlags);
- dest.writeInt(mDataSentOffDevice);
- dest.writeInt(mDataSharedWithThirdParty);
- dest.writeInt(mDataUsedForMonetization);
- dest.writeInt(mDataRetention);
- dest.writeInt(mDataRetentionWeeks);
- }
-
- private UsesPermissionInfo(Parcel source) {
- super(source);
- mPermission = source.readString();
- mFlags = source.readInt();
- mDataSentOffDevice = source.readInt();
- mDataSharedWithThirdParty = source.readInt();
- mDataUsedForMonetization = source.readInt();
- mDataRetention = source.readInt();
- mDataRetentionWeeks = source.readInt();
- }
-
- public static final Creator<UsesPermissionInfo> CREATOR =
- new Creator<UsesPermissionInfo>() {
- @Override
- public UsesPermissionInfo createFromParcel(Parcel source) {
- return new UsesPermissionInfo(source);
- }
- @Override
- public UsesPermissionInfo[] newArray(int size) {
- return new UsesPermissionInfo[size];
- }
- };
-}
diff --git a/core/java/android/hardware/display/NightDisplayListener.java b/core/java/android/hardware/display/NightDisplayListener.java
new file mode 100644
index 0000000..468f833
--- /dev/null
+++ b/core/java/android/hardware/display/NightDisplayListener.java
@@ -0,0 +1,153 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.display;
+
+import android.annotation.NonNull;
+import android.annotation.UserIdInt;
+import android.app.ActivityManager;
+import android.content.ContentResolver;
+import android.content.Context;
+import android.database.ContentObserver;
+import android.net.Uri;
+import android.os.Handler;
+import android.os.Looper;
+import android.provider.Settings.Secure;
+
+import java.time.LocalTime;
+
+/**
+ * @hide
+ */
+public class NightDisplayListener {
+
+ private final Context mContext;
+ private final int mUserId;
+ private final ColorDisplayManager mManager;
+
+ private ContentObserver mContentObserver;
+ private Callback mCallback;
+
+ public NightDisplayListener(@NonNull Context context) {
+ this(context, ActivityManager.getCurrentUser());
+ }
+
+ public NightDisplayListener(@NonNull Context context, @UserIdInt int userId) {
+ mContext = context.getApplicationContext();
+ mUserId = userId;
+ mManager = mContext.getSystemService(ColorDisplayManager.class);
+ }
+
+ /**
+ * Register a callback to be invoked whenever the Night display settings are changed.
+ */
+ public void setCallback(Callback callback) {
+ final Callback oldCallback = mCallback;
+ if (oldCallback != callback) {
+ mCallback = callback;
+
+ if (mContentObserver == null) {
+ mContentObserver = new ContentObserver(new Handler(Looper.getMainLooper())) {
+ @Override
+ public void onChange(boolean selfChange, Uri uri) {
+ super.onChange(selfChange, uri);
+ onSettingChanged(uri);
+ }
+ };
+ }
+
+ if (callback == null) {
+ // Stop listening for changes now that there IS NOT a callback.
+ mContext.getContentResolver().unregisterContentObserver(mContentObserver);
+ } else if (oldCallback == null) {
+ // Start listening for changes now that there IS a callback.
+ final ContentResolver cr = mContext.getContentResolver();
+ cr.registerContentObserver(Secure.getUriFor(Secure.NIGHT_DISPLAY_ACTIVATED),
+ false /* notifyForDescendants */, mContentObserver, mUserId);
+ cr.registerContentObserver(Secure.getUriFor(Secure.NIGHT_DISPLAY_AUTO_MODE),
+ false /* notifyForDescendants */, mContentObserver, mUserId);
+ cr.registerContentObserver(Secure.getUriFor(Secure.NIGHT_DISPLAY_CUSTOM_START_TIME),
+ false /* notifyForDescendants */, mContentObserver, mUserId);
+ cr.registerContentObserver(Secure.getUriFor(Secure.NIGHT_DISPLAY_CUSTOM_END_TIME),
+ false /* notifyForDescendants */, mContentObserver, mUserId);
+ cr.registerContentObserver(Secure.getUriFor(Secure.NIGHT_DISPLAY_COLOR_TEMPERATURE),
+ false /* notifyForDescendants */, mContentObserver, mUserId);
+ }
+ }
+ }
+
+ private void onSettingChanged(Uri uri) {
+ final String setting = uri == null ? null : uri.getLastPathSegment();
+ if (setting == null || mCallback == null) {
+ return;
+ }
+
+ switch (setting) {
+ case Secure.NIGHT_DISPLAY_ACTIVATED:
+ mCallback.onActivated(mManager.isNightDisplayActivated());
+ break;
+ case Secure.NIGHT_DISPLAY_AUTO_MODE:
+ mCallback.onAutoModeChanged(mManager.getNightDisplayAutoMode());
+ break;
+ case Secure.NIGHT_DISPLAY_CUSTOM_START_TIME:
+ mCallback.onCustomStartTimeChanged(mManager.getNightDisplayCustomStartTime());
+ break;
+ case Secure.NIGHT_DISPLAY_CUSTOM_END_TIME:
+ mCallback.onCustomEndTimeChanged(mManager.getNightDisplayCustomEndTime());
+ break;
+ case Secure.NIGHT_DISPLAY_COLOR_TEMPERATURE:
+ mCallback.onColorTemperatureChanged(mManager.getNightDisplayColorTemperature());
+ break;
+ }
+ }
+
+ /**
+ * Callback invoked whenever the Night display settings are changed.
+ */
+ public interface Callback {
+ /**
+ * Callback invoked when the activated state changes.
+ *
+ * @param activated {@code true} if Night display is activated
+ */
+ default void onActivated(boolean activated) {}
+ /**
+ * Callback invoked when the auto mode changes.
+ *
+ * @param autoMode the auto mode to use
+ */
+ default void onAutoModeChanged(int autoMode) {}
+ /**
+ * Callback invoked when the time to automatically activate Night display changes.
+ *
+ * @param startTime the local time to automatically activate Night display
+ */
+ default void onCustomStartTimeChanged(LocalTime startTime) {}
+ /**
+ * Callback invoked when the time to automatically deactivate Night display changes.
+ *
+ * @param endTime the local time to automatically deactivate Night display
+ */
+ default void onCustomEndTimeChanged(LocalTime endTime) {}
+
+ /**
+ * Callback invoked when the color temperature changes.
+ *
+ * @param colorTemperature the color temperature to tint the screen
+ */
+ default void onColorTemperatureChanged(int colorTemperature) {}
+ }
+}
diff --git a/core/java/android/net/ConnectivityManager.java b/core/java/android/net/ConnectivityManager.java
index 8a141e2..2aca55a 100644
--- a/core/java/android/net/ConnectivityManager.java
+++ b/core/java/android/net/ConnectivityManager.java
@@ -3923,6 +3923,25 @@
}
/**
+ * Requests that the system open the captive portal app with the specified extras.
+ *
+ * <p>This endpoint is exclusively for use by the NetworkStack and is protected by the
+ * corresponding permission.
+ * @param appExtras Extras to include in the app start intent.
+ * @hide
+ */
+ @SystemApi
+ @TestApi
+ @RequiresPermission(NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK)
+ public void startCaptivePortalApp(Bundle appExtras) {
+ try {
+ mService.startCaptivePortalAppInternal(appExtras);
+ } catch (RemoteException e) {
+ throw e.rethrowFromSystemServer();
+ }
+ }
+
+ /**
* Determine whether the device is configured to avoid bad wifi.
* @hide
*/
diff --git a/core/java/android/net/IConnectivityManager.aidl b/core/java/android/net/IConnectivityManager.aidl
index 3a405d3..872671f 100644
--- a/core/java/android/net/IConnectivityManager.aidl
+++ b/core/java/android/net/IConnectivityManager.aidl
@@ -27,6 +27,7 @@
import android.net.NetworkRequest;
import android.net.NetworkState;
import android.net.ProxyInfo;
+import android.os.Bundle;
import android.os.IBinder;
import android.os.Messenger;
import android.os.ParcelFileDescriptor;
@@ -167,6 +168,7 @@
void setAcceptUnvalidated(in Network network, boolean accept, boolean always);
void setAvoidUnvalidated(in Network network);
void startCaptivePortalApp(in Network network);
+ void startCaptivePortalAppInternal(in Bundle appExtras);
boolean getAvoidBadWifi();
int getMultipathPreference(in Network Network);
diff --git a/core/java/android/text/TextLine.java b/core/java/android/text/TextLine.java
index 949328f..915a18e 100644
--- a/core/java/android/text/TextLine.java
+++ b/core/java/android/text/TextLine.java
@@ -94,7 +94,8 @@
private final DecorationInfo mDecorationInfo = new DecorationInfo();
private final ArrayList<DecorationInfo> mDecorations = new ArrayList<>();
- @UnsupportedAppUsage
+ /** Not allowed to access. If it's for memory leak workaround, it was already fixed M. */
+ @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P)
private static final TextLine[] sCached = new TextLine[3];
/**
diff --git a/core/java/android/view/accessibility/AccessibilityManager.java b/core/java/android/view/accessibility/AccessibilityManager.java
index 6aafa34..06207a9 100644
--- a/core/java/android/view/accessibility/AccessibilityManager.java
+++ b/core/java/android/view/accessibility/AccessibilityManager.java
@@ -36,6 +36,7 @@
import android.content.pm.ServiceInfo;
import android.content.res.Resources;
import android.os.Binder;
+import android.os.Build;
import android.os.Handler;
import android.os.IBinder;
import android.os.Looper;
@@ -183,7 +184,7 @@
boolean mIsTouchExplorationEnabled;
- @UnsupportedAppUsage
+ @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 123768939)
boolean mIsHighTextContrastEnabled;
AccessibilityPolicy mAccessibilityPolicy;
diff --git a/core/java/android/view/inputmethod/InputMethodManager.java b/core/java/android/view/inputmethod/InputMethodManager.java
index aee4b1f..8a09788 100644
--- a/core/java/android/view/inputmethod/InputMethodManager.java
+++ b/core/java/android/view/inputmethod/InputMethodManager.java
@@ -339,7 +339,11 @@
// For scheduling work on the main thread. This also serves as our
// global lock.
- @UnsupportedAppUsage
+ // Remark on @UnsupportedAppUsage: there were context leaks on old versions
+ // of android (b/37043700), so developers used this field to perform manual clean up.
+ // Leaks were fixed, hacks were backported to AppCompatActivity,
+ // so an access to the field is closed.
+ @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P)
final H mH;
// Our generic input connection if the current target does not have its own.
@@ -375,13 +379,15 @@
* This is the view that should currently be served by an input method,
* regardless of the state of setting that up.
*/
- @UnsupportedAppUsage
+ // See comment to mH field in regard to @UnsupportedAppUsage
+ @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P)
View mServedView;
/**
* This is then next view that will be served by the input method, when
* we get around to updating things.
*/
- @UnsupportedAppUsage
+ // See comment to mH field in regard to @UnsupportedAppUsage
+ @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P)
View mNextServedView;
/**
* This is set when we are in the process of connecting, to determine
diff --git a/core/java/android/widget/AbsListView.java b/core/java/android/widget/AbsListView.java
index a02103e..542df45 100644
--- a/core/java/android/widget/AbsListView.java
+++ b/core/java/android/widget/AbsListView.java
@@ -442,8 +442,10 @@
/**
* Handles one frame of a fling
+ *
+ * To interrupt a fling early you should use smoothScrollBy(0,0) instead
*/
- @UnsupportedAppUsage
+ @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P)
private FlingRunnable mFlingRunnable;
/**
@@ -4679,7 +4681,8 @@
mScroller = new OverScroller(getContext());
}
- @UnsupportedAppUsage
+ // Use AbsListView#fling(int) instead
+ @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P)
void start(int initialVelocity) {
int initialY = initialVelocity < 0 ? Integer.MAX_VALUE : 0;
mLastFlingY = initialY;
@@ -4757,7 +4760,8 @@
postOnAnimation(this);
}
- @UnsupportedAppUsage
+ // To interrupt a fling early you should use smoothScrollBy(0,0) instead
+ @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P)
void endFling() {
mTouchMode = TOUCH_MODE_REST;
diff --git a/core/java/android/widget/TextView.java b/core/java/android/widget/TextView.java
index 659b71f..0f4e23d 100644
--- a/core/java/android/widget/TextView.java
+++ b/core/java/android/widget/TextView.java
@@ -712,7 +712,7 @@
@UnsupportedAppUsage
private ChangeWatcher mChangeWatcher;
- @UnsupportedAppUsage
+ @UnsupportedAppUsage(trackingBug = 123769451)
private ArrayList<TextWatcher> mListeners;
// display attributes
diff --git a/core/java/com/android/internal/os/ZygoteConnection.java b/core/java/com/android/internal/os/ZygoteConnection.java
index 9ba56b8..4ac7f50 100644
--- a/core/java/com/android/internal/os/ZygoteConnection.java
+++ b/core/java/com/android/internal/os/ZygoteConnection.java
@@ -334,9 +334,14 @@
}
}
- private class HiddenApiUsageLogger implements VMRuntime.HiddenApiUsageLogger {
+ private static class HiddenApiUsageLogger implements VMRuntime.HiddenApiUsageLogger {
private final MetricsLogger mMetricsLogger = new MetricsLogger();
+ private static HiddenApiUsageLogger sInstance = new HiddenApiUsageLogger();
+
+ public static HiddenApiUsageLogger getInstance() {
+ return HiddenApiUsageLogger.sInstance;
+ }
public void hiddenApiUsed(String packageName, String signature,
int accessMethod, boolean accessDenied) {
@@ -370,7 +375,7 @@
private void handleHiddenApiAccessLogSampleRate(int samplingRate) {
try {
ZygoteInit.setHiddenApiAccessLogSampleRate(samplingRate);
- ZygoteInit.setHiddenApiUsageLogger(new HiddenApiUsageLogger());
+ ZygoteInit.setHiddenApiUsageLogger(HiddenApiUsageLogger.getInstance());
mSocketOutStream.writeInt(0);
} catch (IOException ioe) {
throw new IllegalStateException("Error writing to command socket", ioe);
diff --git a/core/res/AndroidManifest.xml b/core/res/AndroidManifest.xml
index 60b04cf..07dd26e 100644
--- a/core/res/AndroidManifest.xml
+++ b/core/res/AndroidManifest.xml
@@ -662,8 +662,7 @@
android:permissionGroup="android.permission-group.UNDEFINED"
android:label="@string/permlab_readContacts"
android:description="@string/permdesc_readContacts"
- android:protectionLevel="dangerous"
- android:usageInfoRequired="true" />
+ android:protectionLevel="dangerous" />
<!-- Allows an application to write the user's contacts data.
<p>Protection level: dangerous
@@ -694,8 +693,7 @@
android:permissionGroup="android.permission-group.UNDEFINED"
android:label="@string/permlab_readCalendar"
android:description="@string/permdesc_readCalendar"
- android:protectionLevel="dangerous"
- android:usageInfoRequired="true" />
+ android:protectionLevel="dangerous" />
<!-- Allows an application to write the user's calendar data.
<p>Protection level: dangerous
@@ -736,8 +734,7 @@
android:permissionGroup="android.permission-group.UNDEFINED"
android:label="@string/permlab_receiveSms"
android:description="@string/permdesc_receiveSms"
- android:protectionLevel="dangerous"
- android:usageInfoRequired="true" />
+ android:protectionLevel="dangerous" />
<!-- Allows an application to read SMS messages.
<p>Protection level: dangerous
@@ -746,8 +743,7 @@
android:permissionGroup="android.permission-group.UNDEFINED"
android:label="@string/permlab_readSms"
android:description="@string/permdesc_readSms"
- android:protectionLevel="dangerous"
- android:usageInfoRequired="true" />
+ android:protectionLevel="dangerous" />
<!-- Allows an application to receive WAP push messages.
<p>Protection level: dangerous
@@ -756,8 +752,7 @@
android:permissionGroup="android.permission-group.UNDEFINED"
android:label="@string/permlab_receiveWapPush"
android:description="@string/permdesc_receiveWapPush"
- android:protectionLevel="dangerous"
- android:usageInfoRequired="true" />
+ android:protectionLevel="dangerous" />
<!-- Allows an application to monitor incoming MMS messages.
<p>Protection level: dangerous
@@ -766,8 +761,7 @@
android:permissionGroup="android.permission-group.UNDEFINED"
android:label="@string/permlab_receiveMms"
android:description="@string/permdesc_receiveMms"
- android:protectionLevel="dangerous"
- android:usageInfoRequired="true" />
+ android:protectionLevel="dangerous" />
<!-- @SystemApi @TestApi Allows an application to read previously received cell broadcast
messages and to register a content observer to get notifications when
@@ -785,8 +779,7 @@
android:permissionGroup="android.permission-group.UNDEFINED"
android:label="@string/permlab_readCellBroadcasts"
android:description="@string/permdesc_readCellBroadcasts"
- android:protectionLevel="dangerous"
- android:usageInfoRequired="true" />
+ android:protectionLevel="dangerous" />
<!-- ====================================================================== -->
<!-- Permissions for accessing external storage -->
@@ -867,8 +860,7 @@
android:permissionGroup="android.permission-group.UNDEFINED"
android:label="@string/permlab_audioRead"
android:description="@string/permdesc_audioRead"
- android:protectionLevel="dangerous"
- android:usageInfoRequired="true" />
+ android:protectionLevel="dangerous" />
<!-- Runtime permission controlling access to the user's shared visual media
collection, including images and videos. -->
@@ -884,16 +876,14 @@
android:permissionGroup="android.permission-group.UNDEFINED"
android:label="@string/permlab_imagesRead"
android:description="@string/permdesc_imagesRead"
- android:protectionLevel="dangerous"
- android:usageInfoRequired="true" />
+ android:protectionLevel="dangerous" />
<!-- Allows an application to read the user's shared video collection. -->
<permission android:name="android.permission.READ_MEDIA_VIDEO"
android:permissionGroup="android.permission-group.UNDEFINED"
android:label="@string/permlab_videoRead"
android:description="@string/permdesc_videoRead"
- android:protectionLevel="dangerous"
- android:usageInfoRequired="true" />
+ android:protectionLevel="dangerous" />
<!-- Allows an application to access any geographic locations persisted in the
user's shared collection. -->
@@ -901,8 +891,7 @@
android:permissionGroup="android.permission-group.UNDEFINED"
android:label="@string/permlab_mediaLocation"
android:description="@string/permdesc_mediaLocation"
- android:protectionLevel="dangerous"
- android:usageInfoRequired="true" />
+ android:protectionLevel="dangerous" />
<!-- @hide @SystemApi @TestApi
Allows an application to modify OBB files visible to other apps. -->
@@ -934,8 +923,7 @@
android:label="@string/permlab_accessFineLocation"
android:description="@string/permdesc_accessFineLocation"
android:backgroundPermission="android.permission.ACCESS_BACKGROUND_LOCATION"
- android:protectionLevel="dangerous|instant"
- android:usageInfoRequired="true" />
+ android:protectionLevel="dangerous|instant" />
<!-- Allows an app to access approximate location.
Alternatively, you might want {@link #ACCESS_FINE_LOCATION}.
@@ -946,8 +934,7 @@
android:label="@string/permlab_accessCoarseLocation"
android:description="@string/permdesc_accessCoarseLocation"
android:backgroundPermission="android.permission.ACCESS_BACKGROUND_LOCATION"
- android:protectionLevel="dangerous|instant"
- android:usageInfoRequired="true" />
+ android:protectionLevel="dangerous|instant" />
<!-- Allows an app to access location in the background. If you
are requesting this, you should also request {@link #ACCESS_FINE_LOCATION}.
@@ -959,8 +946,7 @@
android:permissionGroup="android.permission-group.UNDEFINED"
android:label="@string/permlab_accessBackgroundLocation"
android:description="@string/permdesc_accessBackgroundLocation"
- android:protectionLevel="dangerous|instant"
- android:usageInfoRequired="true" />
+ android:protectionLevel="dangerous|instant" />
<!-- ====================================================================== -->
<!-- Permissions for accessing the call log -->
@@ -1001,8 +987,7 @@
android:permissionGroup="android.permission-group.UNDEFINED"
android:label="@string/permlab_readCallLog"
android:description="@string/permdesc_readCallLog"
- android:protectionLevel="dangerous"
- android:usageInfoRequired="true" />
+ android:protectionLevel="dangerous" />
<!-- Allows an application to write (but not read) the user's
call log data.
@@ -1032,8 +1017,7 @@
android:permissionGroup="android.permission-group.UNDEFINED"
android:label="@string/permlab_processOutgoingCalls"
android:description="@string/permdesc_processOutgoingCalls"
- android:protectionLevel="dangerous"
- android:usageInfoRequired="true" />
+ android:protectionLevel="dangerous" />
<!-- ====================================================================== -->
<!-- Permissions for accessing the device telephony -->
@@ -1065,8 +1049,7 @@
android:permissionGroup="android.permission-group.UNDEFINED"
android:label="@string/permlab_readPhoneState"
android:description="@string/permdesc_readPhoneState"
- android:protectionLevel="dangerous"
- android:usageInfoRequired="true" />
+ android:protectionLevel="dangerous" />
<!-- Allows read access to the device's phone number(s). This is a subset of the capabilities
granted by {@link #READ_PHONE_STATE} but is exposed to instant applications.
@@ -1075,8 +1058,7 @@
android:permissionGroup="android.permission-group.UNDEFINED"
android:label="@string/permlab_readPhoneNumbers"
android:description="@string/permdesc_readPhoneNumbers"
- android:protectionLevel="dangerous|instant"
- android:usageInfoRequired="true" />
+ android:protectionLevel="dangerous|instant" />
<!-- Allows an application to initiate a phone call without going through
the Dialer user interface for the user to confirm the call.
@@ -1178,8 +1160,7 @@
android:permissionGroup="android.permission-group.UNDEFINED"
android:label="@string/permlab_recordAudio"
android:description="@string/permdesc_recordAudio"
- android:protectionLevel="dangerous|instant"
- android:usageInfoRequired="true" />
+ android:protectionLevel="dangerous|instant" />
<!-- ====================================================================== -->
<!-- Permissions for activity recognition -->
@@ -1202,8 +1183,7 @@
android:permissionGroup="android.permission-group.UNDEFINED"
android:label="@string/permlab_activityRecognition"
android:description="@string/permdesc_activityRecognition"
- android:protectionLevel="dangerous|instant"
- android:usageInfoRequired="true" />
+ android:protectionLevel="dangerous|instant" />
<!-- ====================================================================== -->
<!-- Permissions for accessing the UCE Service -->
@@ -1252,8 +1232,7 @@
android:permissionGroup="android.permission-group.UNDEFINED"
android:label="@string/permlab_camera"
android:description="@string/permdesc_camera"
- android:protectionLevel="dangerous|instant"
- android:usageInfoRequired="true" />
+ android:protectionLevel="dangerous|instant" />
<!-- ====================================================================== -->
@@ -1277,8 +1256,7 @@
android:permissionGroup="android.permission-group.UNDEFINED"
android:label="@string/permlab_bodySensors"
android:description="@string/permdesc_bodySensors"
- android:protectionLevel="dangerous"
- android:usageInfoRequired="true" />
+ android:protectionLevel="dangerous" />
<!-- Allows an app to use fingerprint hardware.
<p>Protection level: normal
@@ -1780,8 +1758,7 @@
android:permissionGroup="android.permission-group.UNDEFINED"
android:protectionLevel="dangerous"
android:description="@string/permdesc_getAccounts"
- android:label="@string/permlab_getAccounts"
- android:usageInfoRequired="true" />
+ android:label="@string/permlab_getAccounts" />
<uses-permission android:name="android.permission.GET_ACCOUNTS"/>
<!-- Allows applications to call into AccountAuthenticators.
diff --git a/core/res/res/values/attrs.xml b/core/res/res/values/attrs.xml
index fa3a549..46e14b4 100644
--- a/core/res/res/values/attrs.xml
+++ b/core/res/res/values/attrs.xml
@@ -2426,6 +2426,8 @@
</attr>
<attr name="__removed3" />
+ <attr name="__removed4" />
+ <attr name="__removed5" />
<!-- Describes the content of a view so that a autofill service can fill in the appropriate
data. Multiple hints can be combined in a comma separated list or an array of strings
diff --git a/core/res/res/values/attrs_manifest.xml b/core/res/res/values/attrs_manifest.xml
index 881688b..53cae63 100644
--- a/core/res/res/values/attrs_manifest.xml
+++ b/core/res/res/values/attrs_manifest.xml
@@ -1689,10 +1689,6 @@
<attr name="request" />
<attr name="protectionLevel" />
<attr name="permissionFlags" />
- <!-- If {@code true} applications that target Q <em>must</em> specify the permission usage
- attributes in their {@code uses-permission} elements or the permission will not be
- granted. -->
- <attr name="usageInfoRequired" format="boolean" />
</declare-styleable>
<!-- The <code>permission-group</code> tag declares a logical grouping of
@@ -1792,81 +1788,6 @@
requested. If it does support the feature, it will be as if the manifest didn't
request it at all. -->
<attr name="requiredNotFeature" format="string" />
-
- <!-- Specify if the app uploads data, or derived data, guarded by this permission.
-
- If the permission is defined with {@link android.R.attr#usageInfoRequired}
- {@code true} this <em>must</em> be specified by apps that target Android Q or the
- permission will not be granted, it will be as if the manifest didn't request it at all.
- -->
- <attr name="dataSentOffDevice">
- <!-- The application may send data, or derived data, guarded by this permission off of the
- device. -->
- <enum name="yes" value="1" />
- <!-- The application may send data, or derived data, guarded by this permission off of the
- device, however it will only do so when explicitly triggered by a user action. -->
- <enum name="userTriggered" value="2" />
- <!-- The application does not send data, or derived data, guarded by this permission off
- of the device. -->
- <enum name="no" value="3" />
- </attr>
-
- <!-- Specify if the application or its related off-device services provide data,
- or derived data, guarded by this permission to third parties outside of the developer's
- organization that do not qualify as data processors.
-
- If the permission is defined with {@link android.R.attr#usageInfoRequired}
- {@code true} this <em>must</em> be specified by apps that target Android Q or the
- permission will not be granted, it will be as if the manifest didn't request it at all.
- -->
- <attr name="dataSharedWithThirdParty">
- <!-- The application or its services may provide data, or derived data, guarded by this
- permission to third party organizations. -->
- <enum name="yes" value="1" />
- <!-- The application or its services may provide data, or derived data, guarded by this
- permission to third party organizations, however it will only do so when explicitly
- triggered by a user action. -->
- <enum name="userTriggered" value="2" />
- <!-- The application or its services does not provide data, or derived data, guarded by
- this permission to third party organizations. -->
- <enum name="no" value="3" />
- </attr>
-
- <!-- Specify if the application or its related off-device services use data,
- or derived data, guarded by this permission for monetization purposes.
-
- For example, if the data is sold to another party or used for targeting advertisements
- this must be set to {@code yes}.
-
- If the permission is defined with {@link android.R.attr#usageInfoRequired}
- {@code true} this <em>must</em> be specified by apps that target Android Q or the
- permission will not be granted, it will be as if the manifest didn't request it at all.
- -->
- <attr name="dataUsedForMonetization">
- <!-- The application or its services may use data, or derived data, guarded by this
- permission for monetization purposes. -->
- <enum name="yes" value="1" />
- <!-- The application or its services may use data, or derived data, guarded by this
- permission for monetization purposes, however it will only do so when explicity
- triggered by a user action. -->
- <enum name="userTriggered" value="2" />
- <!-- The application or its services does not use data, or derived data, guarded by
- this permission for monetization purposes. -->
- <enum name="no" value="3" />
- </attr>
-
- <!-- Specify how long the application or its related off-device services store
- data, or derived data, guarded by this permission.
-
- This can be one of "notRetained", "userSelected", "unlimited", or a number
- representing the number of weeks the data is retained.
-
- If the permission is defined with {@link android.R.attr#usageInfoRequired}
- {@code true} this <em>must</em> be specified by apps that target Android Q or the
- permission will not be granted, it will be as if the manifest didn't request it at all.
- -->
- <attr name="dataRetentionTime" format="string" />
-
</declare-styleable>
<!-- The <code>uses-configuration</code> tag specifies
diff --git a/core/res/res/values/config.xml b/core/res/res/values/config.xml
index 76b589c..ec53811 100644
--- a/core/res/res/values/config.xml
+++ b/core/res/res/values/config.xml
@@ -963,7 +963,7 @@
<bool name="config_nightDisplayAvailable">@bool/config_setColorTransformAccelerated</bool>
<!-- Default mode to control how Night display is automatically activated.
- One of the following values (see ColorDisplayController.java):
+ One of the following values (see ColorDisplayManager.java):
0 - AUTO_MODE_DISABLED
1 - AUTO_MODE_CUSTOM_TIME
2 - AUTO_MODE_TWILIGHT
@@ -1052,7 +1052,7 @@
</string-array>
- <!-- Indicate available ColorDisplayController.COLOR_MODE_xxx. -->
+ <!-- Indicate available ColorDisplayManager.COLOR_MODE_xxx. -->
<integer-array name="config_availableColorModes">
<!-- Example:
<item>0</item>
diff --git a/core/res/res/values/public.xml b/core/res/res/values/public.xml
index f84f1f1..e6d478a 100644
--- a/core/res/res/values/public.xml
+++ b/core/res/res/values/public.xml
@@ -2925,11 +2925,11 @@
<public name="importantForContentCapture" />
<public name="supportsMultipleDisplays" />
<public name="useAppZygote" />
- <public name="usageInfoRequired" />
- <public name="dataSentOffDevice" />
- <public name="dataSharedWithThirdParty" />
- <public name="dataUsedForMonetization" />
- <public name="dataRetentionTime" />
+ <public name="__removed1" />
+ <public name="__removed2" />
+ <public name="__removed3" />
+ <public name="__removed4" />
+ <public name="__removed5" />
<public name="selectionDividerHeight" />
<public name="foregroundServiceType" />
<public name="hasFragileUserData" />
diff --git a/data/etc/privapp-permissions-platform.xml b/data/etc/privapp-permissions-platform.xml
index 0f35918..6770ae1 100644
--- a/data/etc/privapp-permissions-platform.xml
+++ b/data/etc/privapp-permissions-platform.xml
@@ -104,16 +104,6 @@
<permission name="android.permission.WRITE_SECURE_SETTINGS"/>
</privapp-permissions>
- <privapp-permissions package="com.android.omadm.service">
- <permission name="android.permission.CHANGE_CONFIGURATION"/>
- <permission name="android.permission.CONNECTIVITY_INTERNAL"/>
- <permission name="android.permission.CONNECTIVITY_USE_RESTRICTED_NETWORKS"/>
- <permission name="android.permission.MODIFY_PHONE_STATE"/>
- <permission name="android.permission.READ_PRIVILEGED_PHONE_STATE"/>
- <permission name="android.permission.WRITE_APN_SETTINGS"/>
- <permission name="android.permission.WRITE_SECURE_SETTINGS"/>
- </privapp-permissions>
-
<privapp-permissions package="com.android.packageinstaller">
<permission name="android.permission.DELETE_PACKAGES"/>
<permission name="android.permission.INSTALL_PACKAGES"/>
diff --git a/graphics/java/android/graphics/Typeface.java b/graphics/java/android/graphics/Typeface.java
index bb04ff3..7c9529b 100644
--- a/graphics/java/android/graphics/Typeface.java
+++ b/graphics/java/android/graphics/Typeface.java
@@ -134,7 +134,7 @@
/**
* @deprecated Use {@link android.graphics.fonts.FontFamily} instead.
*/
- @UnsupportedAppUsage
+ @UnsupportedAppUsage(trackingBug = 123768928)
@Deprecated
static final Map<String, android.graphics.FontFamily[]> sSystemFallbackMap =
Collections.emptyMap();
@@ -1003,7 +1003,7 @@
* @deprecated
*/
@Deprecated
- @UnsupportedAppUsage
+ @UnsupportedAppUsage(trackingBug = 123768928)
private static Typeface createFromFamilies(android.graphics.FontFamily[] families) {
long[] ptrArray = new long[families.length];
for (int i = 0; i < families.length; i++) {
@@ -1054,7 +1054,7 @@
*
* @deprecated Use {@link android.graphics.fonts.FontFamily} instead.
*/
- @UnsupportedAppUsage
+ @UnsupportedAppUsage(trackingBug = 123768928)
@Deprecated
private static Typeface createFromFamiliesWithDefault(android.graphics.FontFamily[] families,
String fallbackName, int weight, int italic) {
diff --git a/media/java/android/media/audiopolicy/AudioMix.java b/media/java/android/media/audiopolicy/AudioMix.java
index 1c6210e..761b625 100644
--- a/media/java/android/media/audiopolicy/AudioMix.java
+++ b/media/java/android/media/audiopolicy/AudioMix.java
@@ -353,11 +353,6 @@
// no route flags set, use default as described in Builder.setRouteFlags(int)
mRouteFlags = ROUTE_FLAG_LOOP_BACK;
}
- // can't do loop back AND render at same time in this implementation
- if (mRouteFlags == (ROUTE_FLAG_RENDER | ROUTE_FLAG_LOOP_BACK)) {
- throw new IllegalArgumentException("Unsupported route behavior combination 0x" +
- Integer.toHexString(mRouteFlags));
- }
if (mFormat == null) {
// FIXME Can we eliminate this? Will AudioMix work with an unspecified sample rate?
int rate = AudioSystem.getPrimaryOutputSamplingRate();
@@ -377,11 +372,11 @@
throw new IllegalArgumentException("Unsupported device on non-playback mix");
}
} else {
- if ((mRouteFlags & ROUTE_FLAG_RENDER) == ROUTE_FLAG_RENDER) {
+ if ((mRouteFlags & ROUTE_FLAG_SUPPORTED) == ROUTE_FLAG_RENDER) {
throw new IllegalArgumentException(
"Can't have flag ROUTE_FLAG_RENDER without an audio device");
}
- if ((mRouteFlags & ROUTE_FLAG_SUPPORTED) == ROUTE_FLAG_LOOP_BACK) {
+ if ((mRouteFlags & ROUTE_FLAG_LOOP_BACK) == ROUTE_FLAG_LOOP_BACK) {
if (mRule.getTargetMixType() == MIX_TYPE_PLAYERS) {
mDeviceSystemType = AudioSystem.DEVICE_OUT_REMOTE_SUBMIX;
} else if (mRule.getTargetMixType() == MIX_TYPE_RECORDERS) {
diff --git a/media/jni/android_media_MediaCodec.cpp b/media/jni/android_media_MediaCodec.cpp
index 406f9dd..f07f1e8 100644
--- a/media/jni/android_media_MediaCodec.cpp
+++ b/media/jni/android_media_MediaCodec.cpp
@@ -153,8 +153,12 @@
if (nameIsType) {
mCodec = MediaCodec::CreateByType(mLooper, name, encoder, &mInitStatus);
+ if (mCodec == nullptr || mCodec->getName(&mNameAtCreation) != OK) {
+ mNameAtCreation = "(null)";
+ }
} else {
mCodec = MediaCodec::CreateByComponentName(mLooper, name, &mInitStatus);
+ mNameAtCreation = name;
}
CHECK((mCodec != NULL) != (mInitStatus != OK));
}
@@ -699,9 +703,8 @@
return err;
}
- // TODO: get alias
ScopedLocalRef<jstring> nameObject(env,
- env->NewStringUTF(codecInfo->getCodecName()));
+ env->NewStringUTF(mNameAtCreation.c_str()));
ScopedLocalRef<jstring> canonicalNameObject(env,
env->NewStringUTF(codecInfo->getCodecName()));
diff --git a/media/jni/android_media_MediaCodec.h b/media/jni/android_media_MediaCodec.h
index 0a53f1a..de08550 100644
--- a/media/jni/android_media_MediaCodec.h
+++ b/media/jni/android_media_MediaCodec.h
@@ -155,6 +155,7 @@
sp<ALooper> mLooper;
sp<MediaCodec> mCodec;
+ AString mNameAtCreation;
sp<AMessage> mCallbackNotification;
sp<AMessage> mOnFrameRenderedNotification;
diff --git a/media/jni/android_media_MediaCodecList.cpp b/media/jni/android_media_MediaCodecList.cpp
index cf14942..6b8f745 100644
--- a/media/jni/android_media_MediaCodecList.cpp
+++ b/media/jni/android_media_MediaCodecList.cpp
@@ -24,6 +24,10 @@
#include <media/IMediaCodecList.h>
#include <media/MediaCodecInfo.h>
+#include <utils/Vector.h>
+
+#include <vector>
+
#include "android_runtime/AndroidRuntime.h"
#include "jni.h"
#include <nativehelper/JNIHelp.h>
@@ -31,25 +35,91 @@
using namespace android;
-static sp<IMediaCodecList> getCodecList(JNIEnv *env) {
- sp<IMediaCodecList> mcl = MediaCodecList::getInstance();
- if (mcl == NULL) {
- // This should never happen unless something is really wrong
- jniThrowException(
- env, "java/lang/RuntimeException", "cannot get MediaCodecList");
+/**
+ * This object unwraps codec aliases into individual codec infos as the Java interface handles
+ * aliases in this way.
+ */
+class JavaMediaCodecListWrapper {
+public:
+ struct Info {
+ sp<MediaCodecInfo> info;
+ AString alias;
+ };
+
+ const Info getCodecInfo(size_t index) const {
+ if (index < mInfoList.size()) {
+ return mInfoList[index];
+ }
+ // return
+ return Info { nullptr /* info */, "(none)" /* alias */ };
}
- return mcl;
+
+ size_t countCodecs() const {
+ return mInfoList.size();
+ }
+
+ sp<IMediaCodecList> getCodecList() const {
+ return mCodecList;
+ }
+
+ size_t findCodecByName(AString name) const {
+ auto it = mInfoIndex.find(name);
+ return it == mInfoIndex.end() ? -ENOENT : it->second;
+ }
+
+ JavaMediaCodecListWrapper(sp<IMediaCodecList> mcl)
+ : mCodecList(mcl) {
+ size_t numCodecs = mcl->countCodecs();
+ for (size_t ix = 0; ix < numCodecs; ++ix) {
+ sp<MediaCodecInfo> info = mcl->getCodecInfo(ix);
+ Vector<AString> namesAndAliases;
+ info->getAliases(&namesAndAliases);
+ namesAndAliases.insertAt(0);
+ namesAndAliases.editItemAt(0) = info->getCodecName();
+ for (const AString &nameOrAlias : namesAndAliases) {
+ if (mInfoIndex.count(nameOrAlias) > 0) {
+ // skip duplicate names or aliases
+ continue;
+ }
+ mInfoIndex.emplace(nameOrAlias, mInfoList.size());
+ mInfoList.emplace_back(Info { info, nameOrAlias });
+ }
+ }
+ }
+
+private:
+ sp<IMediaCodecList> mCodecList;
+ std::vector<Info> mInfoList;
+ std::map<AString, size_t> mInfoIndex;
+};
+
+static std::mutex sMutex;
+static std::unique_ptr<JavaMediaCodecListWrapper> sListWrapper;
+
+static const JavaMediaCodecListWrapper *getCodecList(JNIEnv *env) {
+ std::lock_guard<std::mutex> lock(sMutex);
+ if (sListWrapper == nullptr) {
+ sp<IMediaCodecList> mcl = MediaCodecList::getInstance();
+ if (mcl == NULL) {
+ // This should never happen unless something is really wrong
+ jniThrowException(
+ env, "java/lang/RuntimeException", "cannot get MediaCodecList");
+ }
+
+ sListWrapper.reset(new JavaMediaCodecListWrapper(mcl));
+ }
+ return sListWrapper.get();
}
-static sp<MediaCodecInfo> getCodecInfo(JNIEnv *env, jint index) {
- sp<IMediaCodecList> mcl = getCodecList(env);
- if (mcl == NULL) {
+static JavaMediaCodecListWrapper::Info getCodecInfo(JNIEnv *env, jint index) {
+ const JavaMediaCodecListWrapper *mcl = getCodecList(env);
+ if (mcl == nullptr) {
// Runtime exception already pending.
- return NULL;
+ return JavaMediaCodecListWrapper::Info { nullptr /* info */, "(none)" /* alias */ };
}
- sp<MediaCodecInfo> info = mcl->getCodecInfo(index);
- if (info == NULL) {
+ JavaMediaCodecListWrapper::Info info = mcl->getCodecInfo(index);
+ if (info.info == NULL) {
jniThrowException(env, "java/lang/IllegalArgumentException", NULL);
}
@@ -58,36 +128,36 @@
static jint android_media_MediaCodecList_getCodecCount(
JNIEnv *env, jobject /* thiz */) {
- sp<IMediaCodecList> mcl = getCodecList(env);
+ const JavaMediaCodecListWrapper *mcl = getCodecList(env);
if (mcl == NULL) {
// Runtime exception already pending.
return 0;
}
+
return mcl->countCodecs();
}
static jstring android_media_MediaCodecList_getCodecName(
JNIEnv *env, jobject /* thiz */, jint index) {
- sp<MediaCodecInfo> info = getCodecInfo(env, index);
- if (info == NULL) {
+ JavaMediaCodecListWrapper::Info info = getCodecInfo(env, index);
+ if (info.info == NULL) {
// Runtime exception already pending.
return NULL;
}
- // TODO: support aliases
- const char *name = info->getCodecName();
+ const char *name = info.alias.c_str();
return env->NewStringUTF(name);
}
static jstring android_media_MediaCodecList_getCanonicalName(
JNIEnv *env, jobject /* thiz */, jint index) {
- sp<MediaCodecInfo> info = getCodecInfo(env, index);
- if (info == NULL) {
+ JavaMediaCodecListWrapper::Info info = getCodecInfo(env, index);
+ if (info.info == NULL) {
// Runtime exception already pending.
return NULL;
}
- const char *name = info->getCodecName();
+ const char *name = info.info->getCodecName();
return env->NewStringUTF(name);
}
@@ -104,7 +174,7 @@
return -ENOENT;
}
- sp<IMediaCodecList> mcl = getCodecList(env);
+ const JavaMediaCodecListWrapper *mcl = getCodecList(env);
if (mcl == NULL) {
// Runtime exception already pending.
env->ReleaseStringUTFChars(name, nameStr);
@@ -118,25 +188,25 @@
static jboolean android_media_MediaCodecList_getAttributes(
JNIEnv *env, jobject /* thiz */, jint index) {
- sp<MediaCodecInfo> info = getCodecInfo(env, index);
- if (info == NULL) {
+ JavaMediaCodecListWrapper::Info info = getCodecInfo(env, index);
+ if (info.info == NULL) {
// Runtime exception already pending.
return 0;
}
- return info->getAttributes();
+ return info.info->getAttributes();
}
static jarray android_media_MediaCodecList_getSupportedTypes(
JNIEnv *env, jobject /* thiz */, jint index) {
- sp<MediaCodecInfo> info = getCodecInfo(env, index);
- if (info == NULL) {
+ JavaMediaCodecListWrapper::Info info = getCodecInfo(env, index);
+ if (info.info == NULL) {
// Runtime exception already pending.
return NULL;
}
Vector<AString> types;
- info->getSupportedMediaTypes(&types);
+ info.info->getSupportedMediaTypes(&types);
jclass clazz = env->FindClass("java/lang/String");
CHECK(clazz != NULL);
@@ -160,8 +230,8 @@
return NULL;
}
- sp<MediaCodecInfo> info = getCodecInfo(env, index);
- if (info == NULL) {
+ JavaMediaCodecListWrapper::Info info = getCodecInfo(env, index);
+ if (info.info == NULL) {
// Runtime exception already pending.
return NULL;
}
@@ -181,7 +251,7 @@
// TODO query default-format also from codec/codec list
const sp<MediaCodecInfo::Capabilities> &capabilities =
- info->getCapabilitiesFor(typeStr);
+ info.info->getCapabilitiesFor(typeStr);
env->ReleaseStringUTFChars(type, typeStr);
typeStr = NULL;
if (capabilities == NULL) {
@@ -192,7 +262,7 @@
capabilities->getSupportedColorFormats(&colorFormats);
capabilities->getSupportedProfileLevels(&profileLevels);
sp<AMessage> details = capabilities->getDetails();
- bool isEncoder = info->isEncoder();
+ bool isEncoder = info.info->isEncoder();
jobject defaultFormatObj = NULL;
if (ConvertMessageToMap(env, defaultFormat, &defaultFormatObj)) {
@@ -267,13 +337,13 @@
}
static jobject android_media_MediaCodecList_getGlobalSettings(JNIEnv *env, jobject /* thiz */) {
- sp<IMediaCodecList> mcl = getCodecList(env);
+ const JavaMediaCodecListWrapper *mcl = getCodecList(env);
if (mcl == NULL) {
// Runtime exception already pending.
return NULL;
}
- const sp<AMessage> settings = mcl->getGlobalSettings();
+ const sp<AMessage> settings = mcl->getCodecList()->getGlobalSettings();
if (settings == NULL) {
jniThrowException(env, "java/lang/RuntimeException", "cannot get global settings");
return NULL;
diff --git a/packages/NetworkStack/src/com/android/server/connectivity/NetworkMonitor.java b/packages/NetworkStack/src/com/android/server/connectivity/NetworkMonitor.java
index dbffa6d..0d6d080 100644
--- a/packages/NetworkStack/src/com/android/server/connectivity/NetworkMonitor.java
+++ b/packages/NetworkStack/src/com/android/server/connectivity/NetworkMonitor.java
@@ -61,6 +61,7 @@
import android.net.util.Stopwatch;
import android.net.wifi.WifiInfo;
import android.net.wifi.WifiManager;
+import android.os.Bundle;
import android.os.Message;
import android.os.RemoteException;
import android.os.SystemClock;
@@ -674,11 +675,11 @@
public boolean processMessage(Message message) {
switch (message.what) {
case CMD_LAUNCH_CAPTIVE_PORTAL_APP:
- final Intent intent = new Intent(
- ConnectivityManager.ACTION_CAPTIVE_PORTAL_SIGN_IN);
+ final Bundle appExtras = new Bundle();
// OneAddressPerFamilyNetwork is not parcelable across processes.
- intent.putExtra(ConnectivityManager.EXTRA_NETWORK, new Network(mNetwork));
- intent.putExtra(ConnectivityManager.EXTRA_CAPTIVE_PORTAL,
+ appExtras.putParcelable(
+ ConnectivityManager.EXTRA_NETWORK, new Network(mNetwork));
+ appExtras.putParcelable(ConnectivityManager.EXTRA_CAPTIVE_PORTAL,
new CaptivePortal(new ICaptivePortal.Stub() {
@Override
public void appResponse(int response) {
@@ -700,16 +701,14 @@
}
}));
final CaptivePortalProbeResult probeRes = mLastPortalProbeResult;
- intent.putExtra(EXTRA_CAPTIVE_PORTAL_URL, probeRes.detectUrl);
+ appExtras.putString(EXTRA_CAPTIVE_PORTAL_URL, probeRes.detectUrl);
if (probeRes.probeSpec != null) {
final String encodedSpec = probeRes.probeSpec.getEncodedSpec();
- intent.putExtra(EXTRA_CAPTIVE_PORTAL_PROBE_SPEC, encodedSpec);
+ appExtras.putString(EXTRA_CAPTIVE_PORTAL_PROBE_SPEC, encodedSpec);
}
- intent.putExtra(ConnectivityManager.EXTRA_CAPTIVE_PORTAL_USER_AGENT,
+ appExtras.putString(ConnectivityManager.EXTRA_CAPTIVE_PORTAL_USER_AGENT,
mCaptivePortalUserAgent);
- intent.setFlags(
- Intent.FLAG_ACTIVITY_BROUGHT_TO_FRONT | Intent.FLAG_ACTIVITY_NEW_TASK);
- mContext.startActivityAsUser(intent, UserHandle.CURRENT);
+ mCm.startCaptivePortalApp(appExtras);
return HANDLED;
default:
return NOT_HANDLED;
diff --git a/packages/PrintSpooler/AndroidManifest.xml b/packages/PrintSpooler/AndroidManifest.xml
index 478ee54..cd6abb2 100644
--- a/packages/PrintSpooler/AndroidManifest.xml
+++ b/packages/PrintSpooler/AndroidManifest.xml
@@ -37,16 +37,8 @@
<uses-permission android:name="android.permission.READ_PRINT_SERVICES" />
<uses-permission android:name="android.permission.READ_PRINT_SERVICE_RECOMMENDATIONS" />
- <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION"
- android:dataSentOffDevice="no"
- android:dataSharedWithThirdParty="no"
- android:dataUsedForMonetization="no"
- android:dataRetentionTime="unlimited"/>
- <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"
- android:dataSentOffDevice="no"
- android:dataSharedWithThirdParty="no"
- android:dataUsedForMonetization="no"
- android:dataRetentionTime="unlimited"/>
+ <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
+ <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<application
android:allowClearUserData="true"
diff --git a/packages/SystemUI/AndroidManifest.xml b/packages/SystemUI/AndroidManifest.xml
index 866b46f..3778a9c 100644
--- a/packages/SystemUI/AndroidManifest.xml
+++ b/packages/SystemUI/AndroidManifest.xml
@@ -22,11 +22,6 @@
android:sharedUserId="android.uid.systemui"
coreApp="true">
- <!-- Using OpenGL ES 2.0 -->
- <uses-feature
- android:glEsVersion="0x00020000"
- android:required="true" />
-
<!-- SysUI must be the one to define this permission; its name is
referenced by the core OS. -->
<permission android:name="android.permission.systemui.IDENTITY"
diff --git a/packages/SystemUI/res/raw/image_wallpaper_fragment_shader.glsl b/packages/SystemUI/res/raw/image_wallpaper_fragment_shader.glsl
deleted file mode 100644
index 11d73a9..0000000
--- a/packages/SystemUI/res/raw/image_wallpaper_fragment_shader.glsl
+++ /dev/null
@@ -1,33 +0,0 @@
-precision mediump float;
-
-uniform sampler2D uTexture;
-uniform float uCenterReveal;
-uniform float uReveal;
-uniform float uAod2Opacity;
-uniform int uAodMode;
-varying vec2 vTextureCoordinates;
-
-vec3 luminosity(vec3 color) {
- float lum = 0.2126 * color.r + 0.7152 * color.g + 0.0722 * color.b;
- return vec3(lum);
-}
-
-vec4 transform(vec3 diffuse) {
- // TODO: Add well comments here, tracking on b/123615467.
- vec3 lum = luminosity(diffuse);
- diffuse = mix(diffuse, lum, smoothstep(0., uCenterReveal, uReveal));
- float val = mix(uReveal, uCenterReveal, step(uCenterReveal, uReveal));
- diffuse = smoothstep(val, 1.0, diffuse);
- diffuse *= uAod2Opacity * (1. - smoothstep(uCenterReveal, 1., uReveal));
- return vec4(diffuse.r, diffuse.g, diffuse.b, 1.);
-}
-
-void main() {
- vec4 fragColor = texture2D(uTexture, vTextureCoordinates);
- // TODO: Remove the branch logic here, tracking on b/123615467.
- if (uAodMode != 0) {
- gl_FragColor = transform(fragColor.rgb);
- } else {
- gl_FragColor = fragColor;
- }
-}
\ No newline at end of file
diff --git a/packages/SystemUI/res/raw/image_wallpaper_vertex_shader.glsl b/packages/SystemUI/res/raw/image_wallpaper_vertex_shader.glsl
deleted file mode 100644
index 4393e2b..0000000
--- a/packages/SystemUI/res/raw/image_wallpaper_vertex_shader.glsl
+++ /dev/null
@@ -1,8 +0,0 @@
-attribute vec4 aPosition;
-attribute vec2 aTextureCoordinates;
-varying vec2 vTextureCoordinates;
-
-void main() {
- vTextureCoordinates = aTextureCoordinates;
- gl_Position = aPosition;
-}
\ No newline at end of file
diff --git a/packages/SystemUI/src/com/android/systemui/Dependency.java b/packages/SystemUI/src/com/android/systemui/Dependency.java
index fece94e..c3f61ee 100644
--- a/packages/SystemUI/src/com/android/systemui/Dependency.java
+++ b/packages/SystemUI/src/com/android/systemui/Dependency.java
@@ -18,6 +18,7 @@
import android.content.Context;
import android.content.res.Configuration;
import android.hardware.SensorPrivacyManager;
+import android.hardware.display.NightDisplayListener;
import android.os.Handler;
import android.os.Looper;
import android.util.ArrayMap;
@@ -25,7 +26,6 @@
import android.view.IWindowManager;
import com.android.internal.annotations.VisibleForTesting;
-import com.android.internal.app.ColorDisplayController;
import com.android.internal.logging.MetricsLogger;
import com.android.internal.statusbar.IStatusBarService;
import com.android.internal.util.Preconditions;
@@ -206,7 +206,7 @@
@Inject Lazy<UserInfoController> mUserInfoController;
@Inject Lazy<KeyguardMonitor> mKeyguardMonitor;
@Inject Lazy<BatteryController> mBatteryController;
- @Inject Lazy<ColorDisplayController> mColorDisplayController;
+ @Inject Lazy<NightDisplayListener> mNightDisplayListener;
@Inject Lazy<ManagedProfileController> mManagedProfileController;
@Inject Lazy<NextAlarmController> mNextAlarmController;
@Inject Lazy<DataSaverController> mDataSaverController;
@@ -330,7 +330,7 @@
mProviders.put(BatteryController.class, mBatteryController::get);
- mProviders.put(ColorDisplayController.class, mColorDisplayController::get);
+ mProviders.put(NightDisplayListener.class, mNightDisplayListener::get);
mProviders.put(ManagedProfileController.class, mManagedProfileController::get);
diff --git a/packages/SystemUI/src/com/android/systemui/DependencyProvider.java b/packages/SystemUI/src/com/android/systemui/DependencyProvider.java
index 88e32cb..a517d7c 100644
--- a/packages/SystemUI/src/com/android/systemui/DependencyProvider.java
+++ b/packages/SystemUI/src/com/android/systemui/DependencyProvider.java
@@ -24,6 +24,7 @@
import android.annotation.Nullable;
import android.content.Context;
import android.hardware.SensorPrivacyManager;
+import android.hardware.display.NightDisplayListener;
import android.os.Handler;
import android.os.HandlerThread;
import android.os.Looper;
@@ -34,7 +35,6 @@
import android.view.IWindowManager;
import android.view.WindowManagerGlobal;
-import com.android.internal.app.ColorDisplayController;
import com.android.internal.logging.MetricsLogger;
import com.android.internal.statusbar.IStatusBarService;
import com.android.settingslib.bluetooth.LocalBluetoothManager;
@@ -152,8 +152,8 @@
@Singleton
@Provides
- public ColorDisplayController provideColorDisplayController(Context context) {
- return new ColorDisplayController(context);
+ public NightDisplayListener provideNightDisplayListener(Context context) {
+ return new NightDisplayListener(context);
}
@Singleton
diff --git a/packages/SystemUI/src/com/android/systemui/ImageWallpaper.java b/packages/SystemUI/src/com/android/systemui/ImageWallpaper.java
index 5040942..2aecc24 100644
--- a/packages/SystemUI/src/com/android/systemui/ImageWallpaper.java
+++ b/packages/SystemUI/src/com/android/systemui/ImageWallpaper.java
@@ -19,11 +19,8 @@
import static android.view.Display.DEFAULT_DISPLAY;
import android.app.WallpaperManager;
-import android.content.BroadcastReceiver;
import android.content.ComponentCallbacks2;
import android.content.Context;
-import android.content.Intent;
-import android.content.IntentFilter;
import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.RecordingCanvas;
@@ -31,9 +28,7 @@
import android.graphics.RectF;
import android.graphics.Region.Op;
import android.hardware.display.DisplayManager;
-import android.opengl.GLSurfaceView;
import android.os.AsyncTask;
-import android.os.Build;
import android.os.Handler;
import android.os.Trace;
import android.service.wallpaper.WallpaperService;
@@ -44,7 +39,6 @@
import android.view.SurfaceHolder;
import com.android.internal.annotations.VisibleForTesting;
-import com.android.systemui.glwallpaper.ImageWallpaperRenderer;
import java.io.FileDescriptor;
import java.io.IOException;
@@ -57,17 +51,12 @@
public class ImageWallpaper extends WallpaperService {
private static final String TAG = "ImageWallpaper";
private static final String GL_LOG_TAG = "ImageWallpaperGL";
- // TODO: Testing purpose, need to remove later, b/123616712.
- private static final String SENSOR_EVENT_AWAKE = "systemui.test.event.awake";
- // TODO: Testing purpose, need to remove later, b/123616712.
- private static final String SENSOR_EVENT_SLEEP = "systemui.test.event.sleep";
private static final boolean DEBUG = false;
private static final String PROPERTY_KERNEL_QEMU = "ro.kernel.qemu";
private static final long DELAY_FORGET_WALLPAPER = 5000;
private WallpaperManager mWallpaperManager;
private DrawableEngine mEngine;
- private GLEngine mGlEngine;
@Override
public void onCreate() {
@@ -84,112 +73,10 @@
@Override
public Engine onCreateEngine() {
- mGlEngine = new GLEngine(this);
- return mGlEngine;
+ mEngine = new DrawableEngine();
+ return mEngine;
}
- class GLEngine extends Engine {
- private GLWallpaperSurfaceView mWallpaperSurfaceView;
-
- GLEngine(Context context) {
- mWallpaperSurfaceView = new GLWallpaperSurfaceView(context);
- mWallpaperSurfaceView.setRenderer(
- new ImageWallpaperRenderer(context, mWallpaperSurfaceView));
- mWallpaperSurfaceView.setRenderMode(GLSurfaceView.RENDERMODE_WHEN_DIRTY);
- setOffsetNotificationsEnabled(true);
- }
-
- @Override
- public void onAmbientModeChanged(boolean inAmbientMode, long animationDuration) {
- if (mWallpaperSurfaceView != null) {
- mWallpaperSurfaceView.notifyAmbientModeChanged(inAmbientMode);
- }
- }
-
- @Override
- public void onOffsetsChanged(float xOffset, float yOffset, float xOffsetStep,
- float yOffsetStep, int xPixelOffset, int yPixelOffset) {
- if (mWallpaperSurfaceView != null) {
- mWallpaperSurfaceView.notifyOffsetsChanged(xOffset, yOffset);
- }
- }
-
- private class GLWallpaperSurfaceView extends GLSurfaceView implements ImageGLView {
- private SensorEventListener mEventListener;
- private WallpaperStatusListener mWallpaperChangedListener;
-
- // TODO: Testing purpose, need to remove later, b/123616712.
- /**
- * For testing only: adb shell am broadcast -a <INTENT>
- */
- private final BroadcastReceiver mReceiver = new BroadcastReceiver() {
- @Override
- public void onReceive(Context context, Intent intent) {
- if (intent == null) {
- return;
- }
- switch (intent.getAction()) {
- case SENSOR_EVENT_AWAKE:
- notifySensorEvents(true);
- break;
- case SENSOR_EVENT_SLEEP:
- notifySensorEvents(false);
- break;
- }
- }
- };
-
- GLWallpaperSurfaceView(Context context) {
- super(context);
- setEGLContextClientVersion(2);
- // TODO: Testing purpose, need to remove later, b/123616712.
- if (Build.IS_DEBUGGABLE) {
- IntentFilter filter = new IntentFilter();
- filter.addAction(SENSOR_EVENT_AWAKE);
- filter.addAction(SENSOR_EVENT_SLEEP);
- registerReceiver(mReceiver, filter);
- }
- }
-
- @Override
- public SurfaceHolder getHolder() {
- return getSurfaceHolder();
- }
-
- @Override
- public void setRenderer(Renderer renderer) {
- super.setRenderer(renderer);
- mEventListener = (SensorEventListener) renderer;
- mWallpaperChangedListener = (WallpaperStatusListener) renderer;
- }
-
- private void notifySensorEvents(boolean reach) {
- if (mEventListener != null) {
- mEventListener.onSensorEvent(reach);
- }
- }
-
- private void notifyAmbientModeChanged(boolean inAmbient) {
- if (mWallpaperChangedListener != null) {
- mWallpaperChangedListener.onAmbientModeChanged(inAmbient);
- }
- }
-
- private void notifyOffsetsChanged(float xOffset, float yOffset) {
- if (mWallpaperChangedListener != null) {
- mWallpaperChangedListener.onOffsetsChanged(
- xOffset, yOffset, getHolder().getSurfaceFrame());
- }
- }
-
- @Override
- public void render() {
- requestRender();
- }
- }
- }
-
- // TODO: Remove this engine, tracking on b/123617158.
class DrawableEngine extends Engine {
private final Runnable mUnloadWallpaperCallback = () -> {
unloadWallpaper(false /* forgetSize */);
@@ -677,46 +564,4 @@
}
}
}
-
- /**
- * A listener to trace sensor event.
- */
- public interface SensorEventListener {
-
- /**
- * Called back while sensor event comes.
- * @param reach The status of sensor.
- */
- void onSensorEvent(boolean reach);
- }
-
- /**
- * A listener to trace status of image wallpaper.
- */
- public interface WallpaperStatusListener {
-
- /**
- * Called back while ambient mode changes.
- * @param inAmbientMode true if is in ambient mode, false otherwise.
- */
- void onAmbientModeChanged(boolean inAmbientMode);
-
- /**
- * Called back while wallpaper offsets.
- * @param xOffset The offset portion along x.
- * @param yOffset The offset portion along y.
- */
- void onOffsetsChanged(float xOffset, float yOffset, Rect frame);
- }
-
- /**
- * An abstraction for view of GLRenderer.
- */
- public interface ImageGLView {
-
- /**
- * Ask the view to render.
- */
- void render();
- }
}
diff --git a/packages/SystemUI/src/com/android/systemui/glwallpaper/ImageGLProgram.java b/packages/SystemUI/src/com/android/systemui/glwallpaper/ImageGLProgram.java
deleted file mode 100644
index d03b00b..0000000
--- a/packages/SystemUI/src/com/android/systemui/glwallpaper/ImageGLProgram.java
+++ /dev/null
@@ -1,115 +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.glwallpaper;
-
-import static android.opengl.GLES20.GL_FRAGMENT_SHADER;
-import static android.opengl.GLES20.GL_VERTEX_SHADER;
-import static android.opengl.GLES20.glAttachShader;
-import static android.opengl.GLES20.glCompileShader;
-import static android.opengl.GLES20.glCreateProgram;
-import static android.opengl.GLES20.glCreateShader;
-import static android.opengl.GLES20.glGetAttribLocation;
-import static android.opengl.GLES20.glGetUniformLocation;
-import static android.opengl.GLES20.glLinkProgram;
-import static android.opengl.GLES20.glShaderSource;
-import static android.opengl.GLES20.glUseProgram;
-
-import android.content.Context;
-import android.content.res.Resources;
-import android.util.Log;
-
-import java.io.BufferedReader;
-import java.io.IOException;
-import java.io.InputStreamReader;
-
-/**
- * This class takes charge of linking shader codes and then return a handle for OpenGL ES program.
- */
-class ImageGLProgram {
- private static final String TAG = ImageGLProgram.class.getSimpleName();
-
- private Context mContext;
- private int mProgramHandle;
-
- ImageGLProgram(Context context) {
- mContext = context.getApplicationContext();
- }
-
- private int loadShaderProgram(int vertexId, int fragmentId) {
- final String vertexSrc = getShaderResource(vertexId);
- final String fragmentSrc = getShaderResource(fragmentId);
- final int vertexHandle = getShaderHandle(GL_VERTEX_SHADER, vertexSrc);
- final int fragmentHandle = getShaderHandle(GL_FRAGMENT_SHADER, fragmentSrc);
- return getProgramHandle(vertexHandle, fragmentHandle);
- }
-
- private String getShaderResource(int shaderId) {
- Resources res = mContext.getResources();
- StringBuilder code = new StringBuilder();
-
- try (BufferedReader reader = new BufferedReader(
- new InputStreamReader(res.openRawResource(shaderId)))) {
- String nextLine;
- while ((nextLine = reader.readLine()) != null) {
- code.append(nextLine).append("\n");
- }
- } catch (IOException | Resources.NotFoundException ex) {
- Log.d(TAG, "Can not read the shader source", ex);
- code = null;
- }
-
- return code == null ? "" : code.toString();
- }
-
- private int getShaderHandle(int type, String src) {
- final int shader = glCreateShader(type);
- if (shader == 0) {
- Log.d(TAG, "Create shader failed, type=" + type);
- return 0;
- }
- glShaderSource(shader, src);
- glCompileShader(shader);
- return shader;
- }
-
- private int getProgramHandle(int vertexHandle, int fragmentHandle) {
- final int program = glCreateProgram();
- if (program == 0) {
- Log.d(TAG, "Can not create OpenGL ES program");
- return 0;
- }
-
- glAttachShader(program, vertexHandle);
- glAttachShader(program, fragmentHandle);
- glLinkProgram(program);
- return program;
- }
-
- boolean useGLProgram(int vertexResId, int fragmentResId) {
- mProgramHandle = loadShaderProgram(vertexResId, fragmentResId);
- glUseProgram(mProgramHandle);
- return true;
- }
-
- int getAttributeHandle(String name) {
- return glGetAttribLocation(mProgramHandle, name);
- }
-
- int getUniformHandle(String name) {
- return glGetUniformLocation(mProgramHandle, name);
- }
-}
diff --git a/packages/SystemUI/src/com/android/systemui/glwallpaper/ImageGLWallpaper.java b/packages/SystemUI/src/com/android/systemui/glwallpaper/ImageGLWallpaper.java
deleted file mode 100644
index 4e07872..0000000
--- a/packages/SystemUI/src/com/android/systemui/glwallpaper/ImageGLWallpaper.java
+++ /dev/null
@@ -1,245 +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.glwallpaper;
-
-import static android.opengl.GLES20.GL_FLOAT;
-import static android.opengl.GLES20.GL_LINEAR;
-import static android.opengl.GLES20.GL_TEXTURE0;
-import static android.opengl.GLES20.GL_TEXTURE_2D;
-import static android.opengl.GLES20.GL_TEXTURE_MAG_FILTER;
-import static android.opengl.GLES20.GL_TEXTURE_MIN_FILTER;
-import static android.opengl.GLES20.GL_TRIANGLES;
-import static android.opengl.GLES20.glActiveTexture;
-import static android.opengl.GLES20.glBindTexture;
-import static android.opengl.GLES20.glDrawArrays;
-import static android.opengl.GLES20.glEnableVertexAttribArray;
-import static android.opengl.GLES20.glGenTextures;
-import static android.opengl.GLES20.glTexParameteri;
-import static android.opengl.GLES20.glUniform1i;
-import static android.opengl.GLES20.glVertexAttribPointer;
-
-import android.graphics.Bitmap;
-import android.opengl.GLUtils;
-import android.util.Log;
-
-import java.nio.ByteBuffer;
-import java.nio.ByteOrder;
-import java.nio.FloatBuffer;
-
-/**
- * This class takes charge of the geometry data like vertices and texture coordinates.
- * It delivers these data to opengl runtime and triggers draw calls if necessary.
- */
-class ImageGLWallpaper {
- private static final String TAG = ImageGLWallpaper.class.getSimpleName();
-
- static final String A_POSITION = "aPosition";
- static final String A_TEXTURE_COORDINATES = "aTextureCoordinates";
- static final String U_CENTER_REVEAL = "uCenterReveal";
- static final String U_REVEAL = "uReveal";
- static final String U_AOD2OPACITY = "uAod2Opacity";
- static final String U_TEXTURE = "uTexture";
- static final String U_AOD_MODE = "uAodMode";
-
- private static final int HANDLE_UNDEFINED = -1;
- private static final int POSITION_COMPONENT_COUNT = 2;
- private static final int TEXTURE_COMPONENT_COUNT = 2;
- private static final int BYTES_PER_FLOAT = 4;
-
- // Vertices to define the square with 2 triangles.
- private static final float[] VERTICES = {
- -1.0f, -1.0f,
- +1.0f, -1.0f,
- +1.0f, +1.0f,
- +1.0f, +1.0f,
- -1.0f, +1.0f,
- -1.0f, -1.0f
- };
-
- // Texture coordinates that maps to vertices.
- private static final float[] TEXTURES = {
- 0f, 1f,
- 1f, 1f,
- 1f, 0f,
- 1f, 0f,
- 0f, 0f,
- 0f, 1f
- };
-
- private final FloatBuffer mVertexBuffer;
- private final FloatBuffer mTextureBuffer;
- private final ImageGLProgram mProgram;
-
- private int mAttrPosition;
- private int mAttrTextureCoordinates;
- private int mUniAod2Opacity;
- private int mUniAodMode;
- private int mUniCenterReveal;
- private int mUniReveal;
- private int mUniTexture;
- private int mTextureId;
-
- ImageGLWallpaper(ImageGLProgram program) {
- mProgram = program;
-
- // Create an float array in opengles runtime (native) and put vertex data.
- mVertexBuffer = ByteBuffer.allocateDirect(VERTICES.length * BYTES_PER_FLOAT)
- .order(ByteOrder.nativeOrder())
- .asFloatBuffer();
- mVertexBuffer.put(VERTICES);
- mVertexBuffer.position(0);
-
- // Create an float array in opengles runtime (native) and put texture data.
- mTextureBuffer = ByteBuffer.allocateDirect(TEXTURES.length * BYTES_PER_FLOAT)
- .order(ByteOrder.nativeOrder())
- .asFloatBuffer();
- mTextureBuffer.put(TEXTURES);
- mTextureBuffer.position(0);
- }
-
- void setup() {
- setupAttributes();
- setupUniforms();
- }
-
- private void setupAttributes() {
- mAttrPosition = mProgram.getAttributeHandle(A_POSITION);
- mVertexBuffer.position(0);
- glVertexAttribPointer(mAttrPosition, POSITION_COMPONENT_COUNT, GL_FLOAT,
- false, 0, mVertexBuffer);
- glEnableVertexAttribArray(mAttrPosition);
-
- mAttrTextureCoordinates = mProgram.getAttributeHandle(A_TEXTURE_COORDINATES);
- mTextureBuffer.position(0);
- glVertexAttribPointer(mAttrTextureCoordinates, TEXTURE_COMPONENT_COUNT, GL_FLOAT,
- false, 0, mTextureBuffer);
- glEnableVertexAttribArray(mAttrTextureCoordinates);
- }
-
- private void setupUniforms() {
- mUniAod2Opacity = mProgram.getUniformHandle(U_AOD2OPACITY);
- mUniAodMode = mProgram.getUniformHandle(U_AOD_MODE);
- mUniCenterReveal = mProgram.getUniformHandle(U_CENTER_REVEAL);
- mUniReveal = mProgram.getUniformHandle(U_REVEAL);
- mUniTexture = mProgram.getUniformHandle(U_TEXTURE);
- }
-
- int getHandle(String name) {
- switch (name) {
- case A_POSITION:
- return mAttrPosition;
- case A_TEXTURE_COORDINATES:
- return mAttrTextureCoordinates;
- case U_AOD2OPACITY:
- return mUniAod2Opacity;
- case U_AOD_MODE:
- return mUniAodMode;
- case U_CENTER_REVEAL:
- return mUniCenterReveal;
- case U_REVEAL:
- return mUniReveal;
- case U_TEXTURE:
- return mUniTexture;
- default:
- return HANDLE_UNDEFINED;
- }
- }
-
- void draw() {
- glDrawArrays(GL_TRIANGLES, 0, VERTICES.length / 2);
- }
-
- void setupTexture(Bitmap bitmap) {
- final int[] tids = new int[1];
-
- if (bitmap == null) {
- Log.w(TAG, "setupTexture: invalid bitmap");
- return;
- }
-
- // Generate one texture object and store the id in tids[0].
- glGenTextures(1, tids, 0);
- if (tids[0] == 0) {
- Log.w(TAG, "setupTexture: glGenTextures() failed");
- return;
- }
-
- // Bind a named texture to a texturing target.
- glBindTexture(GL_TEXTURE_2D, tids[0]);
- // Load the bitmap data and copy it over into the texture object that is currently bound.
- GLUtils.texImage2D(GL_TEXTURE_2D, 0, bitmap, 0);
- // Use bilinear texture filtering when minification.
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
- // Use bilinear texture filtering when magnification.
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
-
- mTextureId = tids[0];
- }
-
- void useTexture() {
- // Set the active texture unit to texture unit 0.
- glActiveTexture(GL_TEXTURE0);
- // Bind the texture to this unit.
- glBindTexture(GL_TEXTURE_2D, mTextureId);
- // Let the texture sampler in fragment shader to read form this texture unit.
- glUniform1i(mUniTexture, 0);
- }
-
- void adjustTextureCoordinates(Bitmap bitmap, int surfaceWidth, int surfaceHeight,
- float xOffset, float yOffset) {
- if (bitmap == null) {
- Log.d(TAG, "adjustTextureCoordinates: invalid bitmap");
- return;
- }
-
- float ratioW = 1f;
- float ratioH = 1f;
- int bitmapWidth = bitmap.getWidth();
- int bitmapHeight = bitmap.getHeight();
-
- boolean adjustWidth = bitmapWidth > surfaceWidth;
- if (adjustWidth) {
- ratioW = (float) surfaceWidth / bitmapWidth;
- float referenceX = xOffset + ratioW > 1f ? 1f - ratioW : xOffset;
- for (int i = 0; i < TEXTURES.length; i += 2) {
- if (i == 2 || i == 4 || i == 6) {
- TEXTURES[i] = Math.min(1f, referenceX + ratioW);
- } else {
- TEXTURES[i] = referenceX;
- }
- }
- }
-
- boolean adjustHeight = bitmapHeight > surfaceHeight;
- if (adjustHeight) {
- ratioH = (float) surfaceHeight / bitmapHeight;
- float referenceY = yOffset + ratioH > 1f ? 1f - ratioH : yOffset;
- for (int i = 1; i < TEXTURES.length; i += 2) {
- if (i == 1 || i == 3 || i == 11) {
- TEXTURES[i] = Math.min(1f, referenceY + ratioH);
- } else {
- TEXTURES[i] = referenceY;
- }
- }
- }
-
- if (adjustWidth || adjustHeight) {
- mTextureBuffer.put(TEXTURES);
- mTextureBuffer.position(0);
- }
- }
-}
diff --git a/packages/SystemUI/src/com/android/systemui/glwallpaper/ImageProcessHelper.java b/packages/SystemUI/src/com/android/systemui/glwallpaper/ImageProcessHelper.java
deleted file mode 100644
index 477e7d7e..0000000
--- a/packages/SystemUI/src/com/android/systemui/glwallpaper/ImageProcessHelper.java
+++ /dev/null
@@ -1,144 +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.glwallpaper;
-
-import android.graphics.Bitmap;
-import android.graphics.Canvas;
-import android.graphics.Color;
-import android.graphics.ColorMatrix;
-import android.graphics.ColorMatrixColorFilter;
-import android.graphics.Matrix;
-import android.graphics.Paint;
-import android.os.AsyncTask;
-import android.os.Handler;
-import android.os.Handler.Callback;
-import android.os.Message;
-import android.util.Log;
-
-/**
- * A helper class that computes histogram and percentile 85 from a bitmap.
- * Percentile 85 will be computed each time the user picks a new image wallpaper.
- */
-class ImageProcessHelper {
- private static final String TAG = ImageProcessHelper.class.getSimpleName();
- private static final float DEFAULT_PER85 = 0.8f;
- private static final int MSG_UPDATE_PER85 = 1;
-
- /**
- * This color matrix will be applied to each pixel to get luminance from rgb by below formula:
- * Luminance = .2126f * r + .7152f * g + .0722f * b.
- */
- private static final float[] LUMINOSITY_MATRIX = new float[] {
- .2126f, .0000f, .0000f, .0000f, .0000f,
- .0000f, .7152f, .0000f, .0000f, .0000f,
- .0000f, .0000f, .0722f, .0000f, .0000f,
- .0000f, .0000f, .0000f, 1.000f, .0000f
- };
-
- private final Handler mHandler = new Handler(new Callback() {
- @Override
- public boolean handleMessage(Message msg) {
- switch (msg.what) {
- case MSG_UPDATE_PER85:
- mPer85 = (float) msg.obj;
- return true;
- default:
- return false;
- }
- }
- });
-
- private float mPer85 = DEFAULT_PER85;
-
- void startComputingPercentile85(Bitmap bitmap) {
- new Per85ComputeTask(mHandler).execute(bitmap);
- }
-
- float getPercentile85() {
- return mPer85;
- }
-
- private static class Per85ComputeTask extends AsyncTask<Bitmap, Void, Float> {
- private Handler mUpdateHandler;
-
- Per85ComputeTask(Handler handler) {
- super(handler);
- mUpdateHandler = handler;
- }
-
- @Override
- protected Float doInBackground(Bitmap... bitmaps) {
- Bitmap bitmap = bitmaps[0];
- if (bitmap != null) {
- int[] histogram = processHistogram(bitmap);
- return computePercentile85(bitmap, histogram);
- }
- Log.e(TAG, "Per85ComputeTask: Can't get bitmap");
- return DEFAULT_PER85;
- }
-
- @Override
- protected void onPostExecute(Float result) {
- Message msg = mUpdateHandler.obtainMessage(MSG_UPDATE_PER85, result);
- mUpdateHandler.sendMessage(msg);
- }
-
- private int[] processHistogram(Bitmap bitmap) {
- int width = bitmap.getWidth();
- int height = bitmap.getHeight();
-
- Bitmap target = Bitmap.createBitmap(width, height, bitmap.getConfig());
- Canvas canvas = new Canvas(target);
- ColorMatrix cm = new ColorMatrix(LUMINOSITY_MATRIX);
- Paint paint = new Paint();
- paint.setColorFilter(new ColorMatrixColorFilter(cm));
- canvas.drawBitmap(bitmap, new Matrix(), paint);
-
- // TODO: Fine tune the performance here, tracking on b/123615079.
- int[] histogram = new int[256];
- for (int row = 0; row < height; row++) {
- for (int col = 0; col < width; col++) {
- int pixel = target.getPixel(col, row);
- int y = Color.red(pixel) + Color.green(pixel) + Color.blue(pixel);
- histogram[y]++;
- }
- }
-
- return histogram;
- }
-
- private float computePercentile85(Bitmap bitmap, int[] histogram) {
- float per85 = DEFAULT_PER85;
- int pixelCount = bitmap.getWidth() * bitmap.getHeight();
- float[] acc = new float[256];
- for (int i = 0; i < acc.length; i++) {
- acc[i] = (float) histogram[i] / pixelCount;
- float prev = i == 0 ? 0f : acc[i - 1];
- float next = acc[i];
- float idx = (float) (i + 1) / 255;
- float sum = prev + next;
- if (prev < 0.85f && sum >= 0.85f) {
- per85 = idx;
- }
- if (i > 0) {
- acc[i] += acc[i - 1];
- }
- }
- return per85;
- }
- }
-}
diff --git a/packages/SystemUI/src/com/android/systemui/glwallpaper/ImageRevealHelper.java b/packages/SystemUI/src/com/android/systemui/glwallpaper/ImageRevealHelper.java
deleted file mode 100644
index 787972c..0000000
--- a/packages/SystemUI/src/com/android/systemui/glwallpaper/ImageRevealHelper.java
+++ /dev/null
@@ -1,103 +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.glwallpaper;
-
-import android.animation.Animator;
-import android.animation.AnimatorListenerAdapter;
-import android.animation.ValueAnimator;
-
-import com.android.systemui.Interpolators;
-
-/**
- * Use ValueAnimator and appropriate interpolator to control the progress of reveal transition.
- * The transition will happen while getting awake and quit events.
- */
-class ImageRevealHelper {
- private static final String TAG = ImageRevealHelper.class.getSimpleName();
- private static final float MAX_REVEAL = 0f;
- private static final float MIN_REVEAL = 1f;
- private static final int REVEAL_DURATION = 1000;
-
- private final ValueAnimator mAnimator;
- private final RevealStateListener mRevealListener;
- private float mReveal = MIN_REVEAL;
- private boolean mAwake = false;
-
- ImageRevealHelper(RevealStateListener listener) {
- mRevealListener = listener;
- mAnimator = ValueAnimator.ofFloat();
- mAnimator.setDuration(REVEAL_DURATION);
- mAnimator.setInterpolator(Interpolators.FAST_OUT_SLOW_IN);
- mAnimator.addUpdateListener(animator -> {
- mReveal = (float) animator.getAnimatedValue();
- if (mRevealListener != null) {
- mRevealListener.onRevealStateChanged();
- }
- });
- mAnimator.addListener(new AnimatorListenerAdapter() {
- private boolean mIsCanceled;
-
- @Override
- public void onAnimationCancel(Animator animation) {
- mIsCanceled = true;
- }
-
- @Override
- public void onAnimationEnd(Animator animation) {
- if (!mIsCanceled) {
- mAwake = !mAwake;
- }
- mIsCanceled = false;
- }
- });
- }
-
- private void animate() {
- mAnimator.cancel();
- mAnimator.setFloatValues(mReveal, !mAwake ? MIN_REVEAL : MAX_REVEAL);
- mAnimator.start();
- }
-
- public float getReveal() {
- return mReveal;
- }
-
- public boolean isAwake() {
- return mAwake;
- }
-
- void updateAwake(boolean awake) {
- mAwake = awake;
- animate();
- }
-
- void sleep() {
- mReveal = MIN_REVEAL;
- mAwake = false;
- }
-
- /**
- * A listener to trace value changes of reveal.
- */
- public interface RevealStateListener {
-
- /**
- * Called back while reveal status changes.
- */
- void onRevealStateChanged();
- }
-}
diff --git a/packages/SystemUI/src/com/android/systemui/glwallpaper/ImageWallpaperRenderer.java b/packages/SystemUI/src/com/android/systemui/glwallpaper/ImageWallpaperRenderer.java
deleted file mode 100644
index 8916b28..0000000
--- a/packages/SystemUI/src/com/android/systemui/glwallpaper/ImageWallpaperRenderer.java
+++ /dev/null
@@ -1,153 +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.glwallpaper;
-
-import static android.opengl.GLES20.GL_COLOR_BUFFER_BIT;
-import static android.opengl.GLES20.glClear;
-import static android.opengl.GLES20.glClearColor;
-import static android.opengl.GLES20.glUniform1f;
-import static android.opengl.GLES20.glUniform1i;
-import static android.opengl.GLES20.glViewport;
-
-import android.app.WallpaperManager;
-import android.content.Context;
-import android.graphics.Bitmap;
-import android.graphics.Rect;
-import android.opengl.GLSurfaceView;
-import android.util.Log;
-
-import com.android.systemui.ImageWallpaper;
-import com.android.systemui.ImageWallpaper.ImageGLView;
-import com.android.systemui.R;
-
-import javax.microedition.khronos.egl.EGLConfig;
-import javax.microedition.khronos.opengles.GL10;
-
-/**
- * A GL renderer for image wallpaper.
- */
-public class ImageWallpaperRenderer implements GLSurfaceView.Renderer,
- ImageWallpaper.SensorEventListener, ImageWallpaper.WallpaperStatusListener,
- ImageRevealHelper.RevealStateListener {
- private static final String TAG = ImageWallpaperRenderer.class.getSimpleName();
-
- private final WallpaperManager mWallpaperManager;
- private final ImageGLProgram mProgram;
- private final ImageGLWallpaper mWallpaper;
- private final ImageProcessHelper mImageProcessHelper;
- private final ImageRevealHelper mImageRevealHelper;
- private final ImageGLView mGLView;
- private boolean mIsInAmbientMode;
- private float mXOffset = 0f;
- private float mYOffset = 0f;
-
- public ImageWallpaperRenderer(Context context, ImageGLView glView) {
- mWallpaperManager = context.getSystemService(WallpaperManager.class);
- if (mWallpaperManager == null) {
- Log.w(TAG, "WallpaperManager not available");
- }
-
- mProgram = new ImageGLProgram(context);
- mWallpaper = new ImageGLWallpaper(mProgram);
- mImageProcessHelper = new ImageProcessHelper();
- mImageRevealHelper = new ImageRevealHelper(this);
- mGLView = glView;
-
- if (mWallpaperManager != null) {
- // Compute per85 as transition threshold, this is an async work.
- mImageProcessHelper.startComputingPercentile85(mWallpaperManager.getBitmap());
- }
- }
-
- @Override
- public void onSurfaceCreated(GL10 gl, EGLConfig config) {
- glClearColor(0f, 0f, 0f, 1.0f);
- mProgram.useGLProgram(
- R.raw.image_wallpaper_vertex_shader, R.raw.image_wallpaper_fragment_shader);
- mWallpaper.setup();
- mWallpaper.setupTexture(mWallpaperManager.getBitmap());
- }
-
- @Override
- public void onSurfaceChanged(GL10 gl, int width, int height) {
- glViewport(0, 0, width, height);
- mWallpaper.adjustTextureCoordinates(mWallpaperManager.getBitmap(),
- width, height, mXOffset, mYOffset);
- }
-
- @Override
- public void onDrawFrame(GL10 gl) {
- float threshold = mImageProcessHelper.getPercentile85();
- float reveal = mImageRevealHelper.getReveal();
-
- glClear(GL_COLOR_BUFFER_BIT);
-
- glUniform1f(mWallpaper.getHandle(ImageGLWallpaper.U_AOD2OPACITY), .25f);
- glUniform1f(mWallpaper.getHandle(ImageGLWallpaper.U_CENTER_REVEAL), threshold);
- glUniform1f(mWallpaper.getHandle(ImageGLWallpaper.U_REVEAL), reveal);
- glUniform1i(mWallpaper.getHandle(ImageGLWallpaper.U_AOD_MODE), mIsInAmbientMode ? 1 : 0);
-
- mWallpaper.useTexture();
- mWallpaper.draw();
- }
-
- @Override
- public void onSensorEvent(boolean awake) {
- mImageRevealHelper.updateAwake(awake);
- }
-
- @Override
- public void onAmbientModeChanged(boolean inAmbientMode) {
- mIsInAmbientMode = inAmbientMode;
- if (inAmbientMode) {
- mImageRevealHelper.sleep();
- }
- requestRender();
- }
-
- @Override
- public void onOffsetsChanged(float xOffset, float yOffset, Rect frame) {
- if (frame == null || mWallpaperManager == null
- || (xOffset == mXOffset && yOffset == mYOffset)) {
- return;
- }
-
- Bitmap bitmap = mWallpaperManager.getBitmap();
- if (bitmap == null) {
- return;
- }
-
- int width = frame.width();
- int height = frame.height();
- mXOffset = xOffset;
- mYOffset = yOffset;
-
- mWallpaper.adjustTextureCoordinates(bitmap, width, height, mXOffset, mYOffset);
- requestRender();
- }
-
- @Override
- public void onRevealStateChanged() {
- requestRender();
- }
-
- private void requestRender() {
- if (mGLView != null) {
- mGLView.render();
- }
- }
-}
diff --git a/packages/SystemUI/src/com/android/systemui/privacy/OngoingPrivacyDialog.kt b/packages/SystemUI/src/com/android/systemui/privacy/OngoingPrivacyDialog.kt
index fa1426e..cff7fe4 100644
--- a/packages/SystemUI/src/com/android/systemui/privacy/OngoingPrivacyDialog.kt
+++ b/packages/SystemUI/src/com/android/systemui/privacy/OngoingPrivacyDialog.kt
@@ -69,7 +69,7 @@
setPositiveButton(R.string.ongoing_privacy_dialog_ok, null)
setNeutralButton(R.string.ongoing_privacy_dialog_open_settings,
object : DialogInterface.OnClickListener {
- val intent = Intent(Settings.ACTION_ENTERPRISE_PRIVACY_SETTINGS).putExtra(
+ val intent = Intent(Settings.ACTION_PRIVACY_SETTINGS).putExtra(
Intent.EXTRA_DURATION_MILLIS, TimeUnit.MINUTES.toMillis(1))
@Suppress("DEPRECATION")
@@ -167,7 +167,7 @@
// Check if package exists
context.packageManager.getPackageInfo(app.packageName, 0)
item.setOnClickListener(object : View.OnClickListener {
- val intent = Intent(Intent.ACTION_REVIEW_APP_PERMISSION_USAGE)
+ val intent = Intent(Intent.ACTION_MANAGE_APP_PERMISSIONS)
.putExtra(Intent.EXTRA_PACKAGE_NAME, app.packageName)
.putExtra(Intent.EXTRA_USER, UserHandle.getUserHandleForUid(app.uid))
override fun onClick(v: View?) {
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/NightDisplayTile.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/NightDisplayTile.java
index de78d33..effa935 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/NightDisplayTile.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/NightDisplayTile.java
@@ -22,6 +22,7 @@
import android.app.ActivityManager;
import android.content.Intent;
import android.hardware.display.ColorDisplayManager;
+import android.hardware.display.NightDisplayListener;
import android.metrics.LogMaker;
import android.provider.Settings;
import android.service.quicksettings.Tile;
@@ -31,7 +32,6 @@
import androidx.annotation.StringRes;
-import com.android.internal.app.ColorDisplayController;
import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
import com.android.systemui.R;
import com.android.systemui.plugins.qs.QSTile.BooleanState;
@@ -46,8 +46,9 @@
import javax.inject.Inject;
-public class NightDisplayTile extends QSTileImpl<BooleanState>
- implements ColorDisplayController.Callback {
+/** Quick settings tile: Night display **/
+public class NightDisplayTile extends QSTileImpl<BooleanState> implements
+ NightDisplayListener.Callback {
/**
* Pattern for {@link java.time.format.DateTimeFormatter} used to approximate the time to the
@@ -57,13 +58,15 @@
private static final String PATTERN_HOUR_MINUTE = "h:mm a";
private static final String PATTERN_HOUR_NINUTE_24 = "HH:mm";
- private ColorDisplayController mController;
+ private final ColorDisplayManager mManager;
+ private NightDisplayListener mListener;
private boolean mIsListening;
@Inject
public NightDisplayTile(QSHost host) {
super(host);
- mController = new ColorDisplayController(mContext, ActivityManager.getCurrentUser());
+ mManager = mContext.getSystemService(ColorDisplayManager.class);
+ mListener = new NightDisplayListener(mContext, ActivityManager.getCurrentUser());
}
@Override
@@ -81,27 +84,27 @@
// Enroll in forced auto mode if eligible.
if ("1".equals(Settings.Global.getString(mContext.getContentResolver(),
Settings.Global.NIGHT_DISPLAY_FORCED_AUTO_MODE_AVAILABLE))
- && mController.getAutoModeRaw() == -1) {
- mController.setAutoMode(ColorDisplayManager.AUTO_MODE_CUSTOM_TIME);
+ && mManager.getNightDisplayAutoModeRaw() == -1) {
+ mManager.setNightDisplayAutoMode(ColorDisplayManager.AUTO_MODE_CUSTOM_TIME);
Log.i("NightDisplayTile", "Enrolled in forced night display auto mode");
}
// Change current activation state.
final boolean activated = !mState.value;
- mController.setActivated(activated);
+ mManager.setNightDisplayActivated(activated);
}
@Override
protected void handleUserSwitch(int newUserId) {
// Stop listening to the old controller.
if (mIsListening) {
- mController.setListener(null);
+ mListener.setCallback(null);
}
// Make a new controller for the new user.
- mController = new ColorDisplayController(mContext, newUserId);
+ mListener = new NightDisplayListener(mContext, newUserId);
if (mIsListening) {
- mController.setListener(this);
+ mListener.setCallback(this);
}
super.handleUserSwitch(newUserId);
@@ -109,7 +112,7 @@
@Override
protected void handleUpdateState(BooleanState state, Object arg) {
- state.value = mController.isActivated();
+ state.value = mManager.isNightDisplayActivated();
state.label = mContext.getString(R.string.quick_settings_night_display_label);
state.icon = ResourceIcon.get(com.android.internal.R.drawable.ic_qs_night_display_on);
state.expandedAccessibilityClassName = Switch.class.getName();
@@ -121,12 +124,12 @@
}
/**
- * Returns a {@link String} for the secondary label that reflects when the light will be turned
- * on or off based on the current auto mode and night light activated status.
+ * Returns a String for the secondary label that reflects when the light will be turned on or
+ * off based on the current auto mode and night light activated status.
*/
@Nullable
private String getSecondaryLabel(boolean isNightLightActivated) {
- switch(mController.getAutoMode()) {
+ switch (mManager.getNightDisplayAutoMode()) {
case ColorDisplayManager.AUTO_MODE_TWILIGHT:
// Auto mode related to sunrise & sunset. If the light is on, it's guaranteed to be
// turned off at sunrise. If it's off, it's guaranteed to be turned on at sunset.
@@ -143,10 +146,10 @@
final DateTimeFormatter toggleTimeFormat;
if (isNightLightActivated) {
- toggleTime = mController.getCustomEndTime();
+ toggleTime = mManager.getNightDisplayCustomEndTime();
toggleTimeStringRes = R.string.quick_settings_secondary_label_until;
} else {
- toggleTime = mController.getCustomStartTime();
+ toggleTime = mManager.getNightDisplayCustomStartTime();
toggleTimeStringRes = R.string.quick_settings_night_secondary_label_on_at;
}
@@ -175,7 +178,8 @@
@Override
public LogMaker populate(LogMaker logMaker) {
- return super.populate(logMaker).addTaggedData(FIELD_QS_MODE, mController.getAutoModeRaw());
+ return super.populate(logMaker)
+ .addTaggedData(FIELD_QS_MODE, mManager.getNightDisplayAutoModeRaw());
}
@Override
@@ -187,10 +191,10 @@
protected void handleSetListening(boolean listening) {
mIsListening = listening;
if (listening) {
- mController.setListener(this);
+ mListener.setCallback(this);
refreshState();
} else {
- mController.setListener(null);
+ mListener.setCallback(null);
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationInfo.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationInfo.java
index b6948fc..c7b2fab 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationInfo.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationInfo.java
@@ -537,7 +537,7 @@
mChosenImportance = IMPORTANCE_LOW;
confirmationText.setText(R.string.notification_channel_silenced);
} else {
- mChosenImportance = IMPORTANCE_HIGH;
+ mChosenImportance = IMPORTANCE_DEFAULT;
confirmationText.setText(R.string.notification_channel_unsilenced);
}
break;
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/AutoTileManager.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/AutoTileManager.java
index b96c55b..c9be2c8 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/AutoTileManager.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/AutoTileManager.java
@@ -16,11 +16,11 @@
import android.content.Context;
import android.hardware.display.ColorDisplayManager;
+import android.hardware.display.NightDisplayListener;
import android.os.Handler;
import android.provider.Settings.Secure;
import com.android.internal.annotations.VisibleForTesting;
-import com.android.internal.app.ColorDisplayController;
import com.android.systemui.Dependency;
import com.android.systemui.qs.AutoAddTracker;
import com.android.systemui.qs.QSTileHost;
@@ -50,7 +50,7 @@
private final HotspotController mHotspotController;
private final DataSaverController mDataSaverController;
private final ManagedProfileController mManagedProfileController;
- private final ColorDisplayController mColorDisplayController;
+ private final NightDisplayListener mNightDisplayListener;
@Inject
public AutoTileManager(Context context, AutoAddTracker autoAddTracker, QSTileHost host,
@@ -58,7 +58,7 @@
HotspotController hotspotController,
DataSaverController dataSaverController,
ManagedProfileController managedProfileController,
- ColorDisplayController colorDisplayController) {
+ NightDisplayListener nightDisplayListener) {
mAutoTracker = autoAddTracker;
mContext = context;
mHost = host;
@@ -66,7 +66,7 @@
mHotspotController = hotspotController;
mDataSaverController = dataSaverController;
mManagedProfileController = managedProfileController;
- mColorDisplayController = colorDisplayController;
+ mNightDisplayListener = nightDisplayListener;
if (!mAutoTracker.isAdded(HOTSPOT)) {
hotspotController.addCallback(mHotspotCallback);
}
@@ -93,7 +93,7 @@
}
if (!mAutoTracker.isAdded(NIGHT)
&& ColorDisplayManager.isNightDisplayAvailable(mContext)) {
- colorDisplayController.setListener(mColorDisplayCallback);
+ nightDisplayListener.setCallback(mNightDisplayCallback);
}
}
@@ -106,7 +106,7 @@
mDataSaverController.removeCallback(mDataSaverListener);
mManagedProfileController.removeCallback(mProfileCallback);
if (ColorDisplayManager.isNightDisplayAvailable(mContext)) {
- mColorDisplayController.setListener(null);
+ mNightDisplayListener.setCallback(null);
}
}
@@ -157,8 +157,8 @@
};
@VisibleForTesting
- final ColorDisplayController.Callback mColorDisplayCallback =
- new ColorDisplayController.Callback() {
+ final NightDisplayListener.Callback mNightDisplayCallback =
+ new NightDisplayListener.Callback() {
@Override
public void onActivated(boolean activated) {
if (activated) {
@@ -178,7 +178,7 @@
if (mAutoTracker.isAdded(NIGHT)) return;
mHost.addTile(NIGHT);
mAutoTracker.setTileAdded(NIGHT);
- mHandler.post(() -> mColorDisplayController.setListener(null));
+ mHandler.post(() -> mNightDisplayListener.setCallback(null));
}
};
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java
index 8a2fc37..37a0610 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java
@@ -482,7 +482,8 @@
updateAodMaskVisibility(deviceSupportsAodWallpaper && aodImageWallpaperEnabled);
// If WallpaperInfo is null, it must be ImageWallpaper.
final boolean supportsAmbientMode = deviceSupportsAodWallpaper
- && (info == null || info.supportsAmbientMode());
+ && (info == null && aodImageWallpaperEnabled
+ || info != null && info.supportsAmbientMode());
mStatusBarWindowController.setWallpaperSupportsAmbientMode(supportsAmbientMode);
mScrimController.setWallpaperSupportsAmbientMode(supportsAmbientMode);
diff --git a/packages/SystemUI/src/com/android/systemui/wallpaper/AodMaskView.java b/packages/SystemUI/src/com/android/systemui/wallpaper/AodMaskView.java
index dd1d0ca..52cabe2 100644
--- a/packages/SystemUI/src/com/android/systemui/wallpaper/AodMaskView.java
+++ b/packages/SystemUI/src/com/android/systemui/wallpaper/AodMaskView.java
@@ -156,8 +156,6 @@
private boolean checkIfNeedMask() {
// We need mask for ImageWallpaper / LockScreen Wallpaper (Music album art).
- // Because of conflicting with another wallpaper feature,
- // we only support LockScreen wallpaper currently.
return mWallpaperManager.getWallpaperInfo() == null || ScrimState.AOD.hasBackdrop();
}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/NotificationInfoTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/NotificationInfoTest.java
index 2a64445..105bd9d 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/NotificationInfoTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/NotificationInfoTest.java
@@ -18,7 +18,6 @@
import static android.app.NotificationChannel.USER_LOCKED_IMPORTANCE;
import static android.app.NotificationManager.IMPORTANCE_DEFAULT;
-import static android.app.NotificationManager.IMPORTANCE_HIGH;
import static android.app.NotificationManager.IMPORTANCE_LOW;
import static android.app.NotificationManager.IMPORTANCE_MIN;
import static android.app.NotificationManager.IMPORTANCE_NONE;
@@ -1067,7 +1066,7 @@
anyString(), eq(TEST_UID), updated.capture());
assertTrue((updated.getValue().getUserLockedFields()
& USER_LOCKED_IMPORTANCE) != 0);
- assertEquals(IMPORTANCE_HIGH, updated.getValue().getImportance());
+ assertEquals(IMPORTANCE_DEFAULT, updated.getValue().getImportance());
}
@Test
@@ -1111,7 +1110,7 @@
anyString(), eq(TEST_UID), updated.capture());
assertTrue((updated.getValue().getUserLockedFields()
& USER_LOCKED_IMPORTANCE) != 0);
- assertEquals(IMPORTANCE_HIGH, updated.getValue().getImportance());
+ assertEquals(IMPORTANCE_DEFAULT, updated.getValue().getImportance());
}
@Test
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/AutoTileManagerTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/AutoTileManagerTest.java
index 1ded835..f3740c4 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/AutoTileManagerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/AutoTileManagerTest.java
@@ -21,13 +21,13 @@
import static org.mockito.Mockito.verify;
import android.hardware.display.ColorDisplayManager;
+import android.hardware.display.NightDisplayListener;
import android.os.Handler;
import android.support.test.filters.SmallTest;
import android.testing.AndroidTestingRunner;
import android.testing.TestableLooper;
import android.testing.TestableLooper.RunWithLooper;
-import com.android.internal.app.ColorDisplayController;
import com.android.systemui.SysuiTestCase;
import com.android.systemui.qs.AutoAddTracker;
import com.android.systemui.qs.QSTileHost;
@@ -58,7 +58,7 @@
mock(HotspotController.class),
mock(DataSaverController.class),
mock(ManagedProfileController.class),
- mock(ColorDisplayController.class));
+ mock(NightDisplayListener.class));
}
@Test
@@ -66,7 +66,7 @@
if (!ColorDisplayManager.isNightDisplayAvailable(mContext)) {
return;
}
- mAutoTileManager.mColorDisplayCallback.onActivated(true);
+ mAutoTileManager.mNightDisplayCallback.onActivated(true);
verify(mQsTileHost).addTile("night");
}
@@ -75,7 +75,7 @@
if (!ColorDisplayManager.isNightDisplayAvailable(mContext)) {
return;
}
- mAutoTileManager.mColorDisplayCallback.onActivated(false);
+ mAutoTileManager.mNightDisplayCallback.onActivated(false);
verify(mQsTileHost, never()).addTile("night");
}
@@ -84,7 +84,7 @@
if (!ColorDisplayManager.isNightDisplayAvailable(mContext)) {
return;
}
- mAutoTileManager.mColorDisplayCallback.onAutoModeChanged(
+ mAutoTileManager.mNightDisplayCallback.onAutoModeChanged(
ColorDisplayManager.AUTO_MODE_TWILIGHT);
verify(mQsTileHost).addTile("night");
}
@@ -94,7 +94,7 @@
if (!ColorDisplayManager.isNightDisplayAvailable(mContext)) {
return;
}
- mAutoTileManager.mColorDisplayCallback.onAutoModeChanged(
+ mAutoTileManager.mNightDisplayCallback.onAutoModeChanged(
ColorDisplayManager.AUTO_MODE_CUSTOM_TIME);
verify(mQsTileHost).addTile("night");
}
@@ -104,7 +104,7 @@
if (!ColorDisplayManager.isNightDisplayAvailable(mContext)) {
return;
}
- mAutoTileManager.mColorDisplayCallback.onAutoModeChanged(
+ mAutoTileManager.mNightDisplayCallback.onAutoModeChanged(
ColorDisplayManager.AUTO_MODE_DISABLED);
verify(mQsTileHost, never()).addTile("night");
}
diff --git a/packages/overlays/Android.mk b/packages/overlays/Android.mk
index b8a57ae..1294dbb 100644
--- a/packages/overlays/Android.mk
+++ b/packages/overlays/Android.mk
@@ -16,17 +16,13 @@
include $(CLEAR_VARS)
LOCAL_MODULE := frameworks-base-overlays
-
LOCAL_REQUIRED_MODULES := \
- ExperimentNavigationBarFloatingOverlay \
- ExperimentNavigationBarDefaultOverlay \
- ExperimentNavigationBarSlimOverlay32 \
- ExperimentNavigationBarSlimOverlay40 \
- ExperimentNavigationBarLargeOverlay56 \
- ExperimentNavigationBarLargeOverlay64 \
AccentColorBlackOverlay \
AccentColorGreenOverlay \
AccentColorPurpleOverlay \
+ DisplayCutoutEmulationCornerOverlay \
+ DisplayCutoutEmulationDoubleOverlay \
+ DisplayCutoutEmulationTallOverlay \
FontNotoSerifSourceOverlay \
IconPackCircularAndroidOverlay \
IconPackCircularSettingsOverlay \
@@ -42,7 +38,17 @@
IconShapeSquircleOverlay \
IconShapeTeardropOverlay
+include $(BUILD_PHONY_PACKAGE)
+include $(CLEAR_VARS)
+
+LOCAL_MODULE := frameworks-base-overlays-debug
+LOCAL_REQUIRED_MODULES := \
+ ExperimentNavigationBarFloatingOverlay \
+ ExperimentNavigationBarDefaultOverlay \
+ ExperimentNavigationBarSlimOverlay32 \
+ ExperimentNavigationBarSlimOverlay40 \
+ ExperimentNavigationBarLargeOverlay56 \
+ ExperimentNavigationBarLargeOverlay64
include $(BUILD_PHONY_PACKAGE)
-
include $(call first-makefiles-under,$(LOCAL_PATH))
diff --git a/services/backup/java/com/android/server/backup/encryption/chunking/ByteRange.java b/services/backup/java/com/android/server/backup/encryption/chunking/ByteRange.java
new file mode 100644
index 0000000..004d9e3
--- /dev/null
+++ b/services/backup/java/com/android/server/backup/encryption/chunking/ByteRange.java
@@ -0,0 +1,80 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.server.backup.encryption.chunking;
+
+import com.android.internal.util.Preconditions;
+
+/** Representation of a range of bytes to be downloaded. */
+final class ByteRange {
+ private final long mStart;
+ private final long mEnd;
+
+ /** Creates a range of bytes which includes {@code mStart} and {@code mEnd}. */
+ ByteRange(long start, long end) {
+ Preconditions.checkArgument(start >= 0);
+ Preconditions.checkArgument(end >= start);
+ mStart = start;
+ mEnd = end;
+ }
+
+ /** Returns the start of the {@code ByteRange}. The start is included in the range. */
+ long getStart() {
+ return mStart;
+ }
+
+ /** Returns the end of the {@code ByteRange}. The end is included in the range. */
+ long getEnd() {
+ return mEnd;
+ }
+
+ /** Returns the number of bytes included in the {@code ByteRange}. */
+ int getLength() {
+ return (int) (mEnd - mStart + 1);
+ }
+
+ /** Creates a new {@link ByteRange} from {@code mStart} to {@code mEnd + length}. */
+ ByteRange extend(long length) {
+ Preconditions.checkArgument(length > 0);
+ return new ByteRange(mStart, mEnd + length);
+ }
+
+ @Override
+ public boolean equals(Object o) {
+ if (this == o) {
+ return true;
+ }
+ if (!(o instanceof ByteRange)) {
+ return false;
+ }
+
+ ByteRange byteRange = (ByteRange) o;
+ return (mEnd == byteRange.mEnd && mStart == byteRange.mStart);
+ }
+
+ @Override
+ public int hashCode() {
+ int result = 17;
+ result = 31 * result + (int) (mStart ^ (mStart >>> 32));
+ result = 31 * result + (int) (mEnd ^ (mEnd >>> 32));
+ return result;
+ }
+
+ @Override
+ public String toString() {
+ return String.format("ByteRange{mStart=%d, mEnd=%d}", mStart, mEnd);
+ }
+}
diff --git a/services/backup/java/com/android/server/backup/encryption/chunking/DiffScriptBackupWriter.java b/services/backup/java/com/android/server/backup/encryption/chunking/DiffScriptBackupWriter.java
new file mode 100644
index 0000000..69fb5cb
--- /dev/null
+++ b/services/backup/java/com/android/server/backup/encryption/chunking/DiffScriptBackupWriter.java
@@ -0,0 +1,75 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.server.backup.encryption.chunking;
+
+import com.android.internal.annotations.VisibleForTesting;
+
+import java.io.IOException;
+import java.io.OutputStream;
+
+/** Writes backup data to a diff script, using a {@link SingleStreamDiffScriptWriter}. */
+public class DiffScriptBackupWriter implements BackupWriter {
+ /**
+ * The maximum size of a chunk in the diff script. The diff script writer {@code mWriter} will
+ * buffer this many bytes in memory.
+ */
+ private static final int ENCRYPTION_DIFF_SCRIPT_MAX_CHUNK_SIZE_BYTES = 1024 * 1024;
+
+ private final SingleStreamDiffScriptWriter mWriter;
+ private long mBytesWritten;
+
+ /**
+ * Constructs a new writer which writes the diff script to the given output stream, using the
+ * maximum new chunk size {@code ENCRYPTION_DIFF_SCRIPT_MAX_CHUNK_SIZE_BYTES}.
+ */
+ public static DiffScriptBackupWriter newInstance(OutputStream outputStream) {
+ SingleStreamDiffScriptWriter writer =
+ new SingleStreamDiffScriptWriter(
+ outputStream, ENCRYPTION_DIFF_SCRIPT_MAX_CHUNK_SIZE_BYTES);
+ return new DiffScriptBackupWriter(writer);
+ }
+
+ @VisibleForTesting
+ DiffScriptBackupWriter(SingleStreamDiffScriptWriter writer) {
+ mWriter = writer;
+ }
+
+ @Override
+ public void writeBytes(byte[] bytes) throws IOException {
+ for (byte b : bytes) {
+ mWriter.writeByte(b);
+ }
+
+ mBytesWritten += bytes.length;
+ }
+
+ @Override
+ public void writeChunk(long start, int length) throws IOException {
+ mWriter.writeChunk(start, length);
+ mBytesWritten += length;
+ }
+
+ @Override
+ public long getBytesWritten() {
+ return mBytesWritten;
+ }
+
+ @Override
+ public void flush() throws IOException {
+ mWriter.flush();
+ }
+}
diff --git a/services/backup/java/com/android/server/backup/encryption/chunking/DiffScriptWriter.java b/services/backup/java/com/android/server/backup/encryption/chunking/DiffScriptWriter.java
new file mode 100644
index 0000000..49d1571
--- /dev/null
+++ b/services/backup/java/com/android/server/backup/encryption/chunking/DiffScriptWriter.java
@@ -0,0 +1,36 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.server.backup.encryption.chunking;
+
+import java.io.IOException;
+import java.io.OutputStream;
+
+/** Writer that formats a Diff Script and writes it to an output source. */
+interface DiffScriptWriter {
+ /** Adds a new byte to the diff script. */
+ void writeByte(byte b) throws IOException;
+
+ /** Adds a known chunk to the diff script. */
+ void writeChunk(long chunkStart, int chunkLength) throws IOException;
+
+ /** Indicates that no more bytes or chunks will be added to the diff script. */
+ void flush() throws IOException;
+
+ interface Factory {
+ DiffScriptWriter create(OutputStream outputStream);
+ }
+}
diff --git a/services/backup/java/com/android/server/backup/encryption/chunking/OutputStreamWrapper.java b/services/backup/java/com/android/server/backup/encryption/chunking/OutputStreamWrapper.java
new file mode 100644
index 0000000..4aea601
--- /dev/null
+++ b/services/backup/java/com/android/server/backup/encryption/chunking/OutputStreamWrapper.java
@@ -0,0 +1,25 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.server.backup.encryption.chunking;
+
+import java.io.OutputStream;
+
+/** An interface that wraps one {@link OutputStream} with another for filtration purposes. */
+public interface OutputStreamWrapper {
+ /** Wraps a given {@link OutputStream}. */
+ OutputStream wrap(OutputStream outputStream);
+}
diff --git a/services/backup/java/com/android/server/backup/encryption/chunking/SingleStreamDiffScriptWriter.java b/services/backup/java/com/android/server/backup/encryption/chunking/SingleStreamDiffScriptWriter.java
new file mode 100644
index 0000000..0e4bd58
--- /dev/null
+++ b/services/backup/java/com/android/server/backup/encryption/chunking/SingleStreamDiffScriptWriter.java
@@ -0,0 +1,130 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.server.backup.encryption.chunking;
+
+import android.annotation.Nullable;
+
+import com.android.internal.util.Preconditions;
+
+import java.io.IOException;
+import java.io.OutputStream;
+import java.nio.charset.Charset;
+import java.util.Locale;
+
+/**
+ * A {@link DiffScriptWriter} that writes an entire diff script to a single {@link OutputStream}.
+ */
+public class SingleStreamDiffScriptWriter implements DiffScriptWriter {
+ static final byte LINE_SEPARATOR = 0xA;
+ private static final Charset UTF_8 = Charset.forName("UTF-8");
+
+ private final int mMaxNewByteChunkSize;
+ private final OutputStream mOutputStream;
+ private final byte[] mByteBuffer;
+ private int mBufferSize = 0;
+ // Each chunk could be written immediately to the output stream. However,
+ // it is possible that chunks may overlap. We therefore cache the most recent
+ // reusable chunk and try to merge it with future chunks.
+ private ByteRange mReusableChunk;
+
+ public SingleStreamDiffScriptWriter(OutputStream outputStream, int maxNewByteChunkSize) {
+ mOutputStream = outputStream;
+ mMaxNewByteChunkSize = maxNewByteChunkSize;
+ mByteBuffer = new byte[maxNewByteChunkSize];
+ }
+
+ @Override
+ public void writeByte(byte b) throws IOException {
+ if (mReusableChunk != null) {
+ writeReusableChunk();
+ }
+ mByteBuffer[mBufferSize++] = b;
+ if (mBufferSize == mMaxNewByteChunkSize) {
+ writeByteBuffer();
+ }
+ }
+
+ @Override
+ public void writeChunk(long chunkStart, int chunkLength) throws IOException {
+ Preconditions.checkArgument(chunkStart >= 0);
+ Preconditions.checkArgument(chunkLength > 0);
+ if (mBufferSize != 0) {
+ writeByteBuffer();
+ }
+
+ if (mReusableChunk != null && mReusableChunk.getEnd() + 1 == chunkStart) {
+ // The new chunk overlaps the old, so combine them into a single byte range.
+ mReusableChunk = mReusableChunk.extend(chunkLength);
+ } else {
+ writeReusableChunk();
+ mReusableChunk = new ByteRange(chunkStart, chunkStart + chunkLength - 1);
+ }
+ }
+
+ @Override
+ public void flush() throws IOException {
+ Preconditions.checkState(!(mBufferSize != 0 && mReusableChunk != null));
+ if (mBufferSize != 0) {
+ writeByteBuffer();
+ }
+ if (mReusableChunk != null) {
+ writeReusableChunk();
+ }
+ mOutputStream.flush();
+ }
+
+ private void writeByteBuffer() throws IOException {
+ mOutputStream.write(Integer.toString(mBufferSize).getBytes(UTF_8));
+ mOutputStream.write(LINE_SEPARATOR);
+ mOutputStream.write(mByteBuffer, 0, mBufferSize);
+ mOutputStream.write(LINE_SEPARATOR);
+ mBufferSize = 0;
+ }
+
+ private void writeReusableChunk() throws IOException {
+ if (mReusableChunk != null) {
+ mOutputStream.write(
+ String.format(
+ Locale.US,
+ "%d-%d",
+ mReusableChunk.getStart(),
+ mReusableChunk.getEnd())
+ .getBytes(UTF_8));
+ mOutputStream.write(LINE_SEPARATOR);
+ mReusableChunk = null;
+ }
+ }
+
+ /** A factory that creates {@link SingleStreamDiffScriptWriter}s. */
+ public static class Factory implements DiffScriptWriter.Factory {
+ private final int mMaxNewByteChunkSize;
+ private final OutputStreamWrapper mOutputStreamWrapper;
+
+ public Factory(int maxNewByteChunkSize, @Nullable OutputStreamWrapper outputStreamWrapper) {
+ mMaxNewByteChunkSize = maxNewByteChunkSize;
+ mOutputStreamWrapper = outputStreamWrapper;
+ }
+
+ @Override
+ public SingleStreamDiffScriptWriter create(OutputStream outputStream) {
+ if (mOutputStreamWrapper != null) {
+ outputStream = mOutputStreamWrapper.wrap(outputStream);
+ }
+ return new SingleStreamDiffScriptWriter(outputStream, mMaxNewByteChunkSize);
+ }
+ }
+}
diff --git a/services/core/java/com/android/server/ConnectivityService.java b/services/core/java/com/android/server/ConnectivityService.java
index 80b3d67..fe4411c 100644
--- a/services/core/java/com/android/server/ConnectivityService.java
+++ b/services/core/java/com/android/server/ConnectivityService.java
@@ -1833,14 +1833,20 @@
"ConnectivityService");
}
- private void enforceAnyPermissionOf(String... permissions) {
+ private boolean checkAnyPermissionOf(String... permissions) {
for (String permission : permissions) {
if (mContext.checkCallingOrSelfPermission(permission) == PERMISSION_GRANTED) {
- return;
+ return true;
}
}
- throw new SecurityException(
- "Requires one of the following permissions: " + String.join(", ", permissions) + ".");
+ return false;
+ }
+
+ private void enforceAnyPermissionOf(String... permissions) {
+ if (!checkAnyPermissionOf(permissions)) {
+ throw new SecurityException("Requires one of the following permissions: "
+ + String.join(", ", permissions) + ".");
+ }
}
private void enforceInternetPermission() {
@@ -1860,19 +1866,22 @@
}
private void enforceSettingsPermission() {
- mContext.enforceCallingOrSelfPermission(
+ enforceAnyPermissionOf(
android.Manifest.permission.NETWORK_SETTINGS,
- "ConnectivityService");
+ NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK);
}
private boolean checkSettingsPermission() {
- return PERMISSION_GRANTED == mContext.checkCallingOrSelfPermission(
- android.Manifest.permission.NETWORK_SETTINGS);
+ return checkAnyPermissionOf(
+ android.Manifest.permission.NETWORK_SETTINGS,
+ NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK);
}
private boolean checkSettingsPermission(int pid, int uid) {
return PERMISSION_GRANTED == mContext.checkPermission(
- android.Manifest.permission.NETWORK_SETTINGS, pid, uid);
+ android.Manifest.permission.NETWORK_SETTINGS, pid, uid)
+ || PERMISSION_GRANTED == mContext.checkPermission(
+ NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK, pid, uid);
}
private void enforceTetherAccessPermission() {
@@ -1882,9 +1891,9 @@
}
private void enforceConnectivityInternalPermission() {
- mContext.enforceCallingOrSelfPermission(
+ enforceAnyPermissionOf(
android.Manifest.permission.CONNECTIVITY_INTERNAL,
- "ConnectivityService");
+ NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK);
}
private void enforceControlAlwaysOnVpnPermission() {
@@ -1895,20 +1904,16 @@
private void enforceNetworkStackSettingsOrSetup() {
enforceAnyPermissionOf(
- android.Manifest.permission.NETWORK_SETTINGS,
- android.Manifest.permission.NETWORK_SETUP_WIZARD,
- android.Manifest.permission.NETWORK_STACK);
- }
-
- private void enforceNetworkStackPermission() {
- mContext.enforceCallingOrSelfPermission(
+ android.Manifest.permission.NETWORK_SETTINGS,
+ android.Manifest.permission.NETWORK_SETUP_WIZARD,
android.Manifest.permission.NETWORK_STACK,
- "ConnectivityService");
+ NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK);
}
private boolean checkNetworkStackPermission() {
- return PERMISSION_GRANTED == mContext.checkCallingOrSelfPermission(
- android.Manifest.permission.NETWORK_STACK);
+ return checkAnyPermissionOf(
+ android.Manifest.permission.NETWORK_STACK,
+ NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK);
}
private void enforceConnectivityRestrictedNetworksPermission() {
@@ -3240,6 +3245,25 @@
});
}
+ /**
+ * NetworkStack endpoint to start the captive portal app. The NetworkStack needs to use this
+ * endpoint as it does not have INTERACT_ACROSS_USERS_FULL itself.
+ * @param appExtras Bundle to use as intent extras for the captive portal application.
+ * Must be treated as opaque to avoid preventing the captive portal app to
+ * update its arguments.
+ */
+ @Override
+ public void startCaptivePortalAppInternal(Bundle appExtras) {
+ mContext.checkCallingOrSelfPermission(NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK);
+
+ final Intent appIntent = new Intent(ConnectivityManager.ACTION_CAPTIVE_PORTAL_SIGN_IN);
+ appIntent.putExtras(appExtras);
+ appIntent.setFlags(Intent.FLAG_ACTIVITY_BROUGHT_TO_FRONT | Intent.FLAG_ACTIVITY_NEW_TASK);
+
+ Binder.withCleanCallingIdentity(() ->
+ mContext.startActivityAsUser(appIntent, UserHandle.CURRENT));
+ }
+
public boolean avoidBadWifi() {
return mMultinetworkPolicyTracker.getAvoidBadWifi();
}
diff --git a/services/core/java/com/android/server/LocationManagerService.java b/services/core/java/com/android/server/LocationManagerService.java
index 5278bbb..4834ce0 100644
--- a/services/core/java/com/android/server/LocationManagerService.java
+++ b/services/core/java/com/android/server/LocationManagerService.java
@@ -792,7 +792,7 @@
String[] testProviderStrings = resources.getStringArray(
com.android.internal.R.array.config_testLocationProviders);
for (String testProviderString : testProviderStrings) {
- String fragments[] = testProviderString.split(",");
+ String[] fragments = testProviderString.split(",");
String name = fragments[0].trim();
ProviderProperties properties = new ProviderProperties(
Boolean.parseBoolean(fragments[1]) /* requiresNetwork */,
@@ -816,12 +816,6 @@
return;
}
- // this call has the side effect of forcing a write to the LOCATION_MODE setting in an OS
- // upgrade case, and ensures that if anyone checks the LOCATION_MODE setting directly, they
- // will see it in an appropriate state (at least after that user becomes foreground for the
- // first time...)
- isLocationEnabledForUser(userId);
-
// let providers know the current user is on the way out before changing the user
for (LocationProvider p : mProviders) {
p.onUserChangingLocked();
@@ -934,17 +928,22 @@
@GuardedBy("mLock")
public void dumpLocked(FileDescriptor fd, PrintWriter pw, String[] args) {
- pw.println(mName + " provider:");
+ pw.print(" " + mName + " provider");
if (isMock()) {
- pw.println(" mock=true");
+ pw.print(" [mock]");
}
- pw.println(" attached=" + (mProvider != null));
- if (mIsManagedBySettings) {
- pw.println(" allowed=" + mAllowed);
+ pw.println(":");
+
+ pw.println(" useable=" + mUseable);
+ if (!mUseable) {
+ pw.println(" attached=" + (mProvider != null));
+ if (mIsManagedBySettings) {
+ pw.println(" allowed=" + mAllowed);
+ }
+ pw.println(" enabled=" + mEnabled);
}
- pw.println(" enabled=" + mEnabled);
- pw.println(" useable=" + mUseable);
- pw.println(" properties=" + mProperties);
+
+ pw.println(" properties=" + mProperties);
if (mProvider != null) {
long identity = Binder.clearCallingIdentity();
@@ -1397,14 +1396,10 @@
public boolean callStatusChangedLocked(String provider, int status, Bundle extras) {
if (mListener != null) {
try {
- synchronized (this) {
- // synchronize to ensure incrementPendingBroadcastsLocked()
- // is called before decrementPendingBroadcasts()
- mListener.onStatusChanged(provider, status, extras);
- // call this after broadcasting so we do not increment
- // if we throw an exeption.
- incrementPendingBroadcastsLocked();
- }
+ mListener.onStatusChanged(provider, status, extras);
+ // call this after broadcasting so we do not increment
+ // if we throw an exception.
+ incrementPendingBroadcastsLocked();
} catch (RemoteException e) {
return false;
}
@@ -1413,16 +1408,12 @@
statusChanged.putExtras(new Bundle(extras));
statusChanged.putExtra(LocationManager.KEY_STATUS_CHANGED, status);
try {
- synchronized (this) {
- // synchronize to ensure incrementPendingBroadcastsLocked()
- // is called before decrementPendingBroadcasts()
- mPendingIntent.send(mContext, 0, statusChanged, this, mHandler,
- getResolutionPermission(mAllowedResolutionLevel),
- PendingIntentUtils.createDontSendToRestrictedAppsBundle(null));
- // call this after broadcasting so we do not increment
- // if we throw an exeption.
- incrementPendingBroadcastsLocked();
- }
+ mPendingIntent.send(mContext, 0, statusChanged, this, mHandler,
+ getResolutionPermission(mAllowedResolutionLevel),
+ PendingIntentUtils.createDontSendToRestrictedAppsBundle(null));
+ // call this after broadcasting so we do not increment
+ // if we throw an exception.
+ incrementPendingBroadcastsLocked();
} catch (PendingIntent.CanceledException e) {
return false;
}
@@ -1433,14 +1424,10 @@
public boolean callLocationChangedLocked(Location location) {
if (mListener != null) {
try {
- synchronized (this) {
- // synchronize to ensure incrementPendingBroadcastsLocked()
- // is called before decrementPendingBroadcasts()
- mListener.onLocationChanged(new Location(location));
- // call this after broadcasting so we do not increment
- // if we throw an exeption.
- incrementPendingBroadcastsLocked();
- }
+ mListener.onLocationChanged(new Location(location));
+ // call this after broadcasting so we do not increment
+ // if we throw an exception.
+ incrementPendingBroadcastsLocked();
} catch (RemoteException e) {
return false;
}
@@ -1449,16 +1436,12 @@
locationChanged.putExtra(LocationManager.KEY_LOCATION_CHANGED,
new Location(location));
try {
- synchronized (this) {
- // synchronize to ensure incrementPendingBroadcastsLocked()
- // is called before decrementPendingBroadcasts()
- mPendingIntent.send(mContext, 0, locationChanged, this, mHandler,
- getResolutionPermission(mAllowedResolutionLevel),
- PendingIntentUtils.createDontSendToRestrictedAppsBundle(null));
- // call this after broadcasting so we do not increment
- // if we throw an exeption.
- incrementPendingBroadcastsLocked();
- }
+ mPendingIntent.send(mContext, 0, locationChanged, this, mHandler,
+ getResolutionPermission(mAllowedResolutionLevel),
+ PendingIntentUtils.createDontSendToRestrictedAppsBundle(null));
+ // call this after broadcasting so we do not increment
+ // if we throw an exception.
+ incrementPendingBroadcastsLocked();
} catch (PendingIntent.CanceledException e) {
return false;
}
@@ -1473,18 +1456,14 @@
if (mListener != null) {
try {
- synchronized (this) {
- // synchronize to ensure incrementPendingBroadcastsLocked()
- // is called before decrementPendingBroadcasts()
- if (enabled) {
- mListener.onProviderEnabled(provider);
- } else {
- mListener.onProviderDisabled(provider);
- }
- // call this after broadcasting so we do not increment
- // if we throw an exeption.
- incrementPendingBroadcastsLocked();
+ if (enabled) {
+ mListener.onProviderEnabled(provider);
+ } else {
+ mListener.onProviderDisabled(provider);
}
+ // call this after broadcasting so we do not increment
+ // if we throw an exception.
+ incrementPendingBroadcastsLocked();
} catch (RemoteException e) {
return false;
}
@@ -1492,16 +1471,12 @@
Intent providerIntent = new Intent();
providerIntent.putExtra(LocationManager.KEY_PROVIDER_ENABLED, enabled);
try {
- synchronized (this) {
- // synchronize to ensure incrementPendingBroadcastsLocked()
- // is called before decrementPendingBroadcasts()
- mPendingIntent.send(mContext, 0, providerIntent, this, mHandler,
- getResolutionPermission(mAllowedResolutionLevel),
- PendingIntentUtils.createDontSendToRestrictedAppsBundle(null));
- // call this after broadcasting so we do not increment
- // if we throw an exeption.
- incrementPendingBroadcastsLocked();
- }
+ mPendingIntent.send(mContext, 0, providerIntent, this, mHandler,
+ getResolutionPermission(mAllowedResolutionLevel),
+ PendingIntentUtils.createDontSendToRestrictedAppsBundle(null));
+ // call this after broadcasting so we do not increment
+ // if we throw an exception.
+ incrementPendingBroadcastsLocked();
} catch (PendingIntent.CanceledException e) {
return false;
}
@@ -1515,8 +1490,6 @@
synchronized (mLock) {
removeUpdatesLocked(this);
- }
- synchronized (this) {
clearPendingBroadcastsLocked();
}
}
@@ -1524,7 +1497,7 @@
@Override
public void onSendFinished(PendingIntent pendingIntent, Intent intent,
int resultCode, String resultData, Bundle resultExtras) {
- synchronized (this) {
+ synchronized (mLock) {
decrementPendingBroadcastsLocked();
}
}
@@ -1533,13 +1506,25 @@
// containing the sending of the broadcaset
private void incrementPendingBroadcastsLocked() {
mPendingBroadcasts++;
- mWakeLock.acquire(WAKELOCK_TIMEOUT_MILLIS);
+ // so wakelock calls will succeed
+ long identity = Binder.clearCallingIdentity();
+ try {
+ mWakeLock.acquire(WAKELOCK_TIMEOUT_MILLIS);
+ } finally {
+ Binder.restoreCallingIdentity(identity);
+ }
}
private void decrementPendingBroadcastsLocked() {
if (--mPendingBroadcasts == 0) {
- if (mWakeLock.isHeld()) {
- mWakeLock.release();
+ // so wakelock calls will succeed
+ long identity = Binder.clearCallingIdentity();
+ try {
+ if (mWakeLock.isHeld()) {
+ mWakeLock.release();
+ }
+ } finally {
+ Binder.restoreCallingIdentity(identity);
}
}
}
@@ -1547,8 +1532,14 @@
public void clearPendingBroadcastsLocked() {
if (mPendingBroadcasts > 0) {
mPendingBroadcasts = 0;
- if (mWakeLock.isHeld()) {
- mWakeLock.release();
+ // so wakelock calls will succeed
+ long identity = Binder.clearCallingIdentity();
+ try {
+ if (mWakeLock.isHeld()) {
+ mWakeLock.release();
+ }
+ } finally {
+ Binder.restoreCallingIdentity(identity);
}
}
}
@@ -1561,18 +1552,9 @@
//LocationListener was removed when it had a pending broadcast and should
//not be added back.
synchronized (mLock) {
- IBinder binder = listener.asBinder();
- Receiver receiver = mReceivers.get(binder);
+ Receiver receiver = mReceivers.get(listener.asBinder());
if (receiver != null) {
- synchronized (receiver) {
- // so wakelock calls will succeed
- long identity = Binder.clearCallingIdentity();
- try {
- receiver.decrementPendingBroadcastsLocked();
- } finally {
- Binder.restoreCallingIdentity(identity);
- }
- }
+ receiver.decrementPendingBroadcastsLocked();
}
}
}
@@ -2072,6 +2054,7 @@
if (!provider.isUseableLocked()) {
if (isSettingsExemptLocked(record)) {
providerRequest.forceLocation = true;
+ providerRequest.lowPowerMode = false;
} else {
continue;
}
@@ -2080,7 +2063,9 @@
LocationRequest locationRequest = record.mRealRequest;
long interval = locationRequest.getInterval();
- if (!isThrottlingExemptLocked(record.mReceiver.mCallerIdentity)) {
+ // if we're forcing location, don't apply any throttling
+ if (!providerRequest.forceLocation && !isThrottlingExemptLocked(
+ record.mReceiver.mCallerIdentity)) {
if (!record.mIsForegroundUid) {
interval = Math.max(interval, backgroundThrottleInterval);
}
@@ -2174,11 +2159,8 @@
return true;
}
- if (isProviderPackage(callerIdentity.mPackageName)) {
- return true;
- }
+ return isProviderPackage(callerIdentity.mPackageName);
- return false;
}
@GuardedBy("mLock")
@@ -2192,11 +2174,8 @@
return true;
}
- if (isProviderPackage(record.mReceiver.mCallerIdentity.mPackageName)) {
- return true;
- }
+ return isProviderPackage(record.mReceiver.mCallerIdentity.mPackageName);
- return false;
}
private class UpdateRecord {
@@ -2504,9 +2483,7 @@
if (mReceivers.remove(receiver.mKey) != null && receiver.isListener()) {
receiver.getListener().asBinder().unlinkToDeath(receiver, 0);
- synchronized (receiver) {
- receiver.clearPendingBroadcastsLocked();
- }
+ receiver.clearPendingBroadcastsLocked();
}
receiver.updateMonitoring(false);
@@ -2682,7 +2659,6 @@
// geo-fence manager uses the public location API, need to clear identity
int uid = Binder.getCallingUid();
- // TODO: http://b/23822629
if (UserHandle.getUserId(uid) != UserHandle.USER_SYSTEM) {
// temporary measure until geofences work for secondary users
Log.w(TAG, "proximity alerts are currently available only to the primary user");
@@ -2723,8 +2699,6 @@
return false;
}
- // TODO(b/120449926): The GNSS status listeners should be handled similar to the GNSS
- // measurements listeners.
return mGnssStatusProvider.addListener(callback, new CallerIdentity(Binder.getCallingUid(),
Binder.getCallingPid(), packageName));
}
@@ -2744,7 +2718,6 @@
synchronized (mLock) {
CallerIdentity callerIdentity = new CallerIdentity(Binder.getCallingUid(),
Binder.getCallingPid(), packageName);
- // TODO(b/120481270): Register for client death notification and update map.
mGnssMeasurementsListeners.put(listener.asBinder(), callerIdentity);
long identity = Binder.clearCallingIdentity();
try {
@@ -2768,9 +2741,9 @@
android.Manifest.permission.LOCATION_HARDWARE,
"Location Hardware permission not granted to inject GNSS measurement corrections.");
if (!hasGnssPermissions(packageName) || mGnssMeasurementsProvider == null) {
- mGnssMeasurementsProvider.injectGnssMeasurementCorrections(measurementCorrections);
- } else {
Slog.e(TAG, "Can not inject GNSS corrections due to no permission.");
+ } else {
+ mGnssMeasurementsProvider.injectGnssMeasurementCorrections(measurementCorrections);
}
}
@@ -2809,7 +2782,6 @@
CallerIdentity callerIdentity = new CallerIdentity(Binder.getCallingUid(),
Binder.getCallingPid(), packageName);
- // TODO(b/120481270): Register for client death notification and update map.
mGnssNavigationMessageListeners.put(listener.asBinder(), callerIdentity);
long identity = Binder.clearCallingIdentity();
try {
@@ -3382,7 +3354,9 @@
return;
}
pw.println("Current Location Manager state:");
- pw.println(" Location Mode: " + isLocationEnabled());
+ pw.println(" Current user: " + mCurrentUserId + " " + Arrays.toString(
+ mCurrentUserProfiles));
+ pw.println(" Location mode: " + isLocationEnabled());
pw.println(" Location Listeners:");
for (Receiver receiver : mReceivers.values()) {
pw.println(" " + receiver);
@@ -3406,14 +3380,6 @@
+ callerIdentity.mPackageName + ": "
+ isThrottlingExemptLocked(callerIdentity));
}
- pw.println(" Overlay Provider Packages:");
- for (LocationProvider provider : mProviders) {
- if (provider.mProvider instanceof LocationProviderProxy) {
- pw.println(" " + provider.getName() + ": "
- + ((LocationProviderProxy) provider.mProvider)
- .getProviderPackages());
- }
- }
pw.println(" Historical Records by Provider:");
for (Map.Entry<PackageProviderKey, PackageStatistics> entry
: mRequestStatistics.statistics.entrySet()) {
diff --git a/services/core/java/com/android/server/audio/AudioDeviceBroker.java b/services/core/java/com/android/server/audio/AudioDeviceBroker.java
index a3bae52..0dc73d9 100644
--- a/services/core/java/com/android/server/audio/AudioDeviceBroker.java
+++ b/services/core/java/com/android/server/audio/AudioDeviceBroker.java
@@ -381,11 +381,11 @@
//---------------------------------------------------------------------
// Message handling on behalf of helper classes
- /*package*/ void broadcastScoConnectionState(int state) {
+ /*package*/ void postBroadcastScoConnectionState(int state) {
sendIMsgNoDelay(MSG_I_BROADCAST_BT_CONNECTION_STATE, SENDMSG_QUEUE, state);
}
- /*package*/ void broadcastBecomingNoisy() {
+ /*package*/ void postBroadcastBecomingNoisy() {
sendMsgNoDelay(MSG_BROADCAST_AUDIO_BECOMING_NOISY, SENDMSG_REPLACE);
}
@@ -415,6 +415,22 @@
delay);
}
+ /*package*/ void postDisconnectA2dp() {
+ sendMsgNoDelay(MSG_DISCONNECT_A2DP, SENDMSG_QUEUE);
+ }
+
+ /*package*/ void postDisconnectA2dpSink() {
+ sendMsgNoDelay(MSG_DISCONNECT_A2DP_SINK, SENDMSG_QUEUE);
+ }
+
+ /*package*/ void postDisconnectHearingAid() {
+ sendMsgNoDelay(MSG_DISCONNECT_HEARING_AID, SENDMSG_QUEUE);
+ }
+
+ /*package*/ void postDisconnectHeadset() {
+ sendMsgNoDelay(MSG_DISCONNECT_HEADSET, SENDMSG_QUEUE);
+ }
+
//---------------------------------------------------------------------
// Method forwarding between the helper classes (BtHelper, AudioDeviceInventory)
// only call from a "handle"* method or "on"* method
@@ -444,23 +460,6 @@
}
}
- /*package*/ void handleDisconnectA2dp() {
- synchronized (mDeviceStateLock) {
- mDeviceInventory.disconnectA2dp();
- }
- }
- /*package*/ void handleDisconnectA2dpSink() {
- synchronized (mDeviceStateLock) {
- mDeviceInventory.disconnectA2dpSink();
- }
- }
-
- /*package*/ void handleDisconnectHearingAid() {
- synchronized (mDeviceStateLock) {
- mDeviceInventory.disconnectHearingAid();
- }
- }
-
/*package*/ void handleSetA2dpSinkConnectionState(@BluetoothProfile.BtProfileState int state,
@NonNull BtHelper.BluetoothA2dpDeviceInfo btDeviceInfo) {
final int intState = (state == BluetoothA2dp.STATE_CONNECTED)
@@ -482,7 +481,7 @@
state, btDeviceInfo, delay);
}
- /*package*/ void handleSetA2dpSourceConnectionState(@BluetoothProfile.BtProfileState int state,
+ /*package*/ void postSetA2dpSourceConnectionState(@BluetoothProfile.BtProfileState int state,
@NonNull BtHelper.BluetoothA2dpDeviceInfo btDeviceInfo) {
final int intState = (state == BluetoothA2dp.STATE_CONNECTED) ? 1 : 0;
sendILMsgNoDelay(MSG_IL_SET_A2DP_SOURCE_CONNECTION_STATE, SENDMSG_QUEUE, state,
@@ -710,6 +709,26 @@
(BtHelper.BluetoothA2dpDeviceInfo) msg.obj);
}
break;
+ case MSG_DISCONNECT_A2DP:
+ synchronized (mDeviceStateLock) {
+ mDeviceInventory.disconnectA2dp();
+ }
+ break;
+ case MSG_DISCONNECT_A2DP_SINK:
+ synchronized (mDeviceStateLock) {
+ mDeviceInventory.disconnectA2dpSink();
+ }
+ break;
+ case MSG_DISCONNECT_HEARING_AID:
+ synchronized (mDeviceStateLock) {
+ mDeviceInventory.disconnectHearingAid();
+ }
+ break;
+ case MSG_DISCONNECT_HEADSET:
+ synchronized (mDeviceStateLock) {
+ mBtHelper.disconnectHeadset();
+ }
+ break;
default:
Log.wtf(TAG, "Invalid message " + msg.what);
}
@@ -745,6 +764,10 @@
private static final int MSG_I_DISCONNECT_BT_SCO = 16;
private static final int MSG_TOGGLE_HDMI = 17;
private static final int MSG_L_A2DP_ACTIVE_DEVICE_CHANGE = 18;
+ private static final int MSG_DISCONNECT_A2DP = 19;
+ private static final int MSG_DISCONNECT_A2DP_SINK = 20;
+ private static final int MSG_DISCONNECT_HEARING_AID = 21;
+ private static final int MSG_DISCONNECT_HEADSET = 22;
private static boolean isMessageHandledUnderWakelock(int msgId) {
diff --git a/services/core/java/com/android/server/audio/AudioDeviceInventory.java b/services/core/java/com/android/server/audio/AudioDeviceInventory.java
index 11fdc8f..37f0496 100644
--- a/services/core/java/com/android/server/audio/AudioDeviceInventory.java
+++ b/services/core/java/com/android/server/audio/AudioDeviceInventory.java
@@ -859,7 +859,7 @@
// also checks whether media routing if affected by a dynamic policy
if (((device == musicDevice) || mDeviceBroker.isInCommunication())
&& (device == devices) && !mDeviceBroker.hasMediaDynamicPolicy()) {
- mDeviceBroker.broadcastBecomingNoisy();
+ mDeviceBroker.postBroadcastBecomingNoisy();
delay = 1000;
}
diff --git a/services/core/java/com/android/server/audio/AudioService.java b/services/core/java/com/android/server/audio/AudioService.java
index de63d0e..a6643d4 100644
--- a/services/core/java/com/android/server/audio/AudioService.java
+++ b/services/core/java/com/android/server/audio/AudioService.java
@@ -5120,7 +5120,7 @@
if (mUserSwitchedReceived) {
// attempt to stop music playback for background user except on first user
// switch (i.e. first boot)
- mDeviceBroker.broadcastBecomingNoisy();
+ mDeviceBroker.postBroadcastBecomingNoisy();
}
mUserSwitchedReceived = true;
// the current audio focus owner is no longer valid
diff --git a/services/core/java/com/android/server/audio/BtHelper.java b/services/core/java/com/android/server/audio/BtHelper.java
index b63af8a..e918997 100644
--- a/services/core/java/com/android/server/audio/BtHelper.java
+++ b/services/core/java/com/android/server/audio/BtHelper.java
@@ -374,10 +374,10 @@
}
/*package*/ synchronized void disconnectAllBluetoothProfiles() {
- mDeviceBroker.handleDisconnectA2dp();
- mDeviceBroker.handleDisconnectA2dpSink();
- disconnectHeadset();
- mDeviceBroker.handleDisconnectHearingAid();
+ mDeviceBroker.postDisconnectA2dp();
+ mDeviceBroker.postDisconnectA2dpSink();
+ mDeviceBroker.postDisconnectHeadset();
+ mDeviceBroker.postDisconnectHearingAid();
}
/*package*/ synchronized void resetBluetoothSco() {
@@ -388,9 +388,14 @@
mDeviceBroker.setBluetoothScoOn(false, "resetBluetoothSco");
}
+ /*package*/ synchronized void disconnectHeadset() {
+ setBtScoActiveDevice(null);
+ mBluetoothHeadset = null;
+ }
+
//----------------------------------------------------------------------
private void broadcastScoConnectionState(int state) {
- mDeviceBroker.broadcastScoConnectionState(state);
+ mDeviceBroker.postBroadcastScoConnectionState(state);
}
private boolean handleBtScoActiveDeviceChange(BluetoothDevice btDevice, boolean isActive) {
@@ -487,7 +492,7 @@
btDevice = deviceList.get(0);
final @BluetoothProfile.BtProfileState int state =
proxy.getConnectionState(btDevice);
- mDeviceBroker.handleSetA2dpSourceConnectionState(
+ mDeviceBroker.postSetA2dpSourceConnectionState(
state, new BluetoothA2dpDeviceInfo(btDevice));
}
break;
@@ -558,19 +563,19 @@
switch (profile) {
case BluetoothProfile.A2DP:
- mDeviceBroker.handleDisconnectA2dp();
+ mDeviceBroker.postDisconnectA2dp();
break;
case BluetoothProfile.A2DP_SINK:
- mDeviceBroker.handleDisconnectA2dpSink();
+ mDeviceBroker.postDisconnectA2dpSink();
break;
case BluetoothProfile.HEADSET:
- disconnectHeadset();
+ mDeviceBroker.postDisconnectHeadset();
break;
case BluetoothProfile.HEARING_AID:
- mDeviceBroker.handleDisconnectHearingAid();
+ mDeviceBroker.postDisconnectHearingAid();
break;
default:
@@ -579,11 +584,6 @@
}
};
- private void disconnectHeadset() {
- setBtScoActiveDevice(null);
- mBluetoothHeadset = null;
- }
-
//----------------------------------------------------------------------
private class ScoClient implements IBinder.DeathRecipient {
private IBinder mCb; // To be notified of client's death
diff --git a/services/core/java/com/android/server/biometrics/face/FaceService.java b/services/core/java/com/android/server/biometrics/face/FaceService.java
index 90342ee..017503a 100644
--- a/services/core/java/com/android/server/biometrics/face/FaceService.java
+++ b/services/core/java/com/android/server/biometrics/face/FaceService.java
@@ -168,6 +168,7 @@
String opPackageName, int cookie, int callingUid, int callingPid,
int callingUserId) {
checkPermission(USE_BIOMETRIC_INTERNAL);
+ updateActiveGroup(groupId, opPackageName);
final boolean restricted = true; // BiometricPrompt is always restricted
final AuthenticationClientImpl client = new FaceAuthClient(getContext(),
mDaemonWrapper, mHalDeviceId, token,
diff --git a/services/core/java/com/android/server/biometrics/fingerprint/FingerprintService.java b/services/core/java/com/android/server/biometrics/fingerprint/FingerprintService.java
index 62947c7..9e0a1c0c 100644
--- a/services/core/java/com/android/server/biometrics/fingerprint/FingerprintService.java
+++ b/services/core/java/com/android/server/biometrics/fingerprint/FingerprintService.java
@@ -192,6 +192,7 @@
IBiometricServiceReceiverInternal wrapperReceiver, String opPackageName,
int cookie, int callingUid, int callingPid, int callingUserId) {
checkPermission(MANAGE_BIOMETRIC);
+ updateActiveGroup(groupId, opPackageName);
final boolean restricted = true; // BiometricPrompt is always restricted
final AuthenticationClientImpl client = new FingerprintAuthClient(getContext(),
mDaemonWrapper, mHalDeviceId, token,
diff --git a/services/core/java/com/android/server/display/BrightnessTracker.java b/services/core/java/com/android/server/display/BrightnessTracker.java
index 727cf0e..126beef 100644
--- a/services/core/java/com/android/server/display/BrightnessTracker.java
+++ b/services/core/java/com/android/server/display/BrightnessTracker.java
@@ -34,6 +34,7 @@
import android.hardware.SensorManager;
import android.hardware.display.AmbientBrightnessDayStats;
import android.hardware.display.BrightnessChangeEvent;
+import android.hardware.display.ColorDisplayManager;
import android.hardware.display.DisplayManager;
import android.hardware.display.DisplayManagerInternal;
import android.hardware.display.DisplayedContentSample;
@@ -57,7 +58,6 @@
import com.android.internal.annotations.GuardedBy;
import com.android.internal.annotations.VisibleForTesting;
-import com.android.internal.app.ColorDisplayController;
import com.android.internal.os.BackgroundThread;
import com.android.internal.util.FastXmlSerializer;
import com.android.internal.util.RingBuffer;
@@ -382,9 +382,8 @@
return;
}
- builder.setNightMode(mInjector.isNightModeActive(mContext, UserHandle.USER_CURRENT));
- builder.setColorTemperature(mInjector.getColorTemperature(mContext,
- UserHandle.USER_CURRENT));
+ builder.setNightMode(mInjector.isNightDisplayActivated(mContext));
+ builder.setColorTemperature(mInjector.getNightDisplayColorTemperature(mContext));
if (mColorSamplingEnabled) {
DisplayedContentSample sample = mInjector.sampleColor(mNoFramesToSample);
@@ -1096,12 +1095,13 @@
return context.getSystemService(PowerManager.class).isInteractive();
}
- public int getColorTemperature(Context context, int userId) {
- return new ColorDisplayController(context, userId).getColorTemperature();
+ public int getNightDisplayColorTemperature(Context context) {
+ return context.getSystemService(ColorDisplayManager.class)
+ .getNightDisplayColorTemperature();
}
- public boolean isNightModeActive(Context context, int userId) {
- return new ColorDisplayController(context, userId).isActivated();
+ public boolean isNightDisplayActivated(Context context) {
+ return context.getSystemService(ColorDisplayManager.class).isNightDisplayActivated();
}
public DisplayedContentSample sampleColor(int noFramesToSample) {
diff --git a/services/core/java/com/android/server/display/ColorDisplayService.java b/services/core/java/com/android/server/display/ColorDisplayService.java
index 6a76087..9cb6eee 100644
--- a/services/core/java/com/android/server/display/ColorDisplayService.java
+++ b/services/core/java/com/android/server/display/ColorDisplayService.java
@@ -72,7 +72,6 @@
import com.android.internal.R;
import com.android.internal.annotations.VisibleForTesting;
-import com.android.internal.app.ColorDisplayController;
import com.android.internal.util.DumpUtils;
import com.android.server.DisplayThread;
import com.android.server.SystemService;
@@ -448,7 +447,6 @@
private ContentObserver mUserSetupObserver;
private boolean mBootCompleted;
- private ColorDisplayController mNightDisplayController;
private ContentObserver mContentObserver;
private DisplayWhiteBalanceListener mDisplayWhiteBalanceListener;
@@ -547,8 +545,6 @@
private void setUp() {
Slog.d(TAG, "setUp: currentUser=" + mCurrentUser);
- mNightDisplayController = new ColorDisplayController(getContext(), mCurrentUser);
-
// Listen for external changes to any of the settings.
if (mContentObserver == null) {
mContentObserver = new ContentObserver(new Handler(DisplayThread.get().getLooper())) {
@@ -586,7 +582,7 @@
getNightDisplayCustomEndTimeInternal().getLocalTime());
break;
case System.DISPLAY_COLOR_MODE:
- onDisplayColorModeChanged(mNightDisplayController.getColorMode());
+ onDisplayColorModeChanged(getColorModeInternal());
break;
case Secure.ACCESSIBILITY_DISPLAY_INVERSION_ENABLED:
onAccessibilityInversionChanged();
@@ -634,7 +630,7 @@
// Set the color mode, if valid, and immediately apply the updated tint matrix based on the
// existing activated state. This ensures consistency of tint across the color mode change.
- onDisplayColorModeChanged(mNightDisplayController.getColorMode());
+ onDisplayColorModeChanged(getColorModeInternal());
if (mNightDisplayTintController.isAvailable(getContext())) {
// Reset the activated state.
@@ -667,10 +663,6 @@
getContext().getContentResolver().unregisterContentObserver(mContentObserver);
- if (mNightDisplayController != null) {
- mNightDisplayController = null;
- }
-
if (mNightDisplayTintController.isAvailable(getContext())) {
if (mNightDisplayAutoMode != null) {
mNightDisplayAutoMode.onStop();
@@ -740,7 +732,7 @@
}
private void onAccessibilityActivated() {
- onDisplayColorModeChanged(mNightDisplayController.getColorMode());
+ onDisplayColorModeChanged(getColorModeInternal());
}
/**
@@ -1003,8 +995,7 @@
mCurrentUser);
}
- private @ColorMode
- int getColorModeInternal() {
+ private @ColorMode int getColorModeInternal() {
final ContentResolver cr = getContext().getContentResolver();
if (Secure.getIntForUser(cr, Secure.ACCESSIBILITY_DISPLAY_INVERSION_ENABLED,
0, mCurrentUser) == 1
diff --git a/services/core/java/com/android/server/location/LocationProviderProxy.java b/services/core/java/com/android/server/location/LocationProviderProxy.java
index 34c8786..afe3473 100644
--- a/services/core/java/com/android/server/location/LocationProviderProxy.java
+++ b/services/core/java/com/android/server/location/LocationProviderProxy.java
@@ -183,12 +183,17 @@
@Override
public void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
- pw.println(" service=" + mServiceWatcher);
+ pw.println(" service=" + mServiceWatcher);
+ synchronized (mProviderPackagesLock) {
+ if (mProviderPackages.size() > 1) {
+ pw.println(" additional packages=" + mProviderPackages);
+ }
+ }
mServiceWatcher.runOnBinderBlocking(binder -> {
try {
TransferPipe.dumpAsync(binder, fd, args);
} catch (IOException | RemoteException e) {
- pw.println(" failed to dump location provider");
+ pw.println(" <failed to dump location provider: " + e + ">");
}
return null;
}, null);
diff --git a/services/core/java/com/android/server/pm/PackageInstallerSession.java b/services/core/java/com/android/server/pm/PackageInstallerSession.java
index d06fc51..1b71904 100644
--- a/services/core/java/com/android/server/pm/PackageInstallerSession.java
+++ b/services/core/java/com/android/server/pm/PackageInstallerSession.java
@@ -44,7 +44,6 @@
import android.Manifest;
import android.annotation.NonNull;
import android.annotation.Nullable;
-import android.apex.IApexService;
import android.app.admin.DevicePolicyManagerInternal;
import android.content.Context;
import android.content.IIntentReceiver;
@@ -80,7 +79,6 @@
import android.os.Process;
import android.os.RemoteException;
import android.os.RevocableFileDescriptor;
-import android.os.ServiceManager;
import android.os.SystemProperties;
import android.os.UserHandle;
import android.os.storage.StorageManager;
@@ -1084,6 +1082,11 @@
dispatchSessionFinished(PackageManager.INSTALL_SUCCEEDED, "Session staged", null);
return;
}
+ if ((params.installFlags & PackageManager.INSTALL_APEX) != 0) {
+ throw new PackageManagerException(
+ PackageManager.INSTALL_FAILED_INTERNAL_ERROR,
+ "APEX packages can only be installed using staged sessions.");
+ }
final PackageManagerService.ActiveInstallSession committingSession =
makeSessionActiveLocked();
if (committingSession == null) {
@@ -1101,12 +1104,6 @@
final PackageManagerService.ActiveInstallSession activeSession =
session.makeSessionActiveLocked();
if (activeSession != null) {
- if ((activeSession.getSessionParams().installFlags
- & PackageManager.INSTALL_APEX) != 0) {
- throw new PackageManagerException(
- PackageManager.INSTALL_FAILED_INTERNAL_ERROR,
- "Atomic install is not supported for APEX packages.");
- }
childSessions.add(activeSession);
}
} catch (PackageManagerException e) {
@@ -1124,27 +1121,7 @@
}
mPm.installStage(childSessions);
} else {
- if ((params.installFlags & PackageManager.INSTALL_APEX) != 0) {
- commitApexLocked();
- } else {
- mPm.installStage(committingSession);
- }
- }
- }
-
- @GuardedBy("mLock")
- private void commitApexLocked() throws PackageManagerException {
- try {
- IApexService apex = IApexService.Stub.asInterface(
- ServiceManager.getService("apexservice"));
- apex.stagePackage(mResolvedBaseFile.toString());
- } catch (Throwable e) {
- // Convert all exceptions into package manager exceptions as only those are handled
- // in the code above
- throw new PackageManagerException(e);
- } finally {
- destroyInternal();
- dispatchSessionFinished(PackageManager.INSTALL_SUCCEEDED, "APEX installed", null);
+ mPm.installStage(committingSession);
}
}
diff --git a/services/core/java/com/android/server/pm/PackageManagerService.java b/services/core/java/com/android/server/pm/PackageManagerService.java
index 32dc988..eaedec5 100644
--- a/services/core/java/com/android/server/pm/PackageManagerService.java
+++ b/services/core/java/com/android/server/pm/PackageManagerService.java
@@ -195,7 +195,6 @@
import android.content.pm.Signature;
import android.content.pm.SuspendDialogInfo;
import android.content.pm.UserInfo;
-import android.content.pm.UsesPermissionInfo;
import android.content.pm.VerifierDeviceIdentity;
import android.content.pm.VerifierInfo;
import android.content.pm.VersionedPackage;
@@ -11313,26 +11312,6 @@
}
}
}
-
- // Check permission usage info requirements.
- if (pkg.applicationInfo.targetSdkVersion >= Build.VERSION_CODES.Q) {
- for (UsesPermissionInfo upi : pkg.usesPermissionInfos) {
- if (!mPermissionManager.isPermissionUsageInfoRequired(upi.getPermission())) {
- continue;
- }
- if (upi.getDataSentOffDevice() == UsesPermissionInfo.USAGE_UNDEFINED
- || upi.getDataSharedWithThirdParty()
- == UsesPermissionInfo.USAGE_UNDEFINED
- || upi.getDataUsedForMonetization()
- == UsesPermissionInfo.USAGE_UNDEFINED
- || upi.getDataRetention() == UsesPermissionInfo.RETENTION_UNDEFINED) {
- // STOPSHIP: Make this throw
- Slog.e(TAG, "Package " + pkg.packageName + " does not provide usage "
- + "information for permission " + upi.getPermission()
- + ". This will be a fatal error in Q.");
- }
- }
- }
}
}
diff --git a/services/core/java/com/android/server/pm/dex/DexManager.java b/services/core/java/com/android/server/pm/dex/DexManager.java
index 2213901..ee6995b 100644
--- a/services/core/java/com/android/server/pm/dex/DexManager.java
+++ b/services/core/java/com/android/server/pm/dex/DexManager.java
@@ -228,8 +228,11 @@
continue;
}
- mDexLogger.recordDex(loaderUserId, dexPath, searchResult.mOwningPackageName,
- loadingAppInfo.packageName);
+ if (!primaryOrSplit) {
+ // Record loading of a DEX file from an app data directory.
+ mDexLogger.recordDex(loaderUserId, dexPath, searchResult.mOwningPackageName,
+ loadingAppInfo.packageName);
+ }
if (classLoaderContexts != null) {
diff --git a/services/core/java/com/android/server/pm/permission/BasePermission.java b/services/core/java/com/android/server/pm/permission/BasePermission.java
index 173d9a0..1957eb8 100644
--- a/services/core/java/com/android/server/pm/permission/BasePermission.java
+++ b/services/core/java/com/android/server/pm/permission/BasePermission.java
@@ -105,8 +105,6 @@
*/
private boolean perUser;
- boolean usageInfoRequired;
-
public BasePermission(String _name, String _sourcePackageName, @PermissionType int _type) {
name = _name;
sourcePackageName = _sourcePackageName;
@@ -375,7 +373,6 @@
}
if (bp.perm == p) {
bp.protectionLevel = p.info.protectionLevel;
- bp.usageInfoRequired = p.info.usageInfoRequired;
}
if (PackageManagerService.DEBUG_PACKAGE_SCANNING && r != null) {
Log.d(TAG, " Permissions: " + r);
@@ -455,7 +452,6 @@
permissionInfo.packageName = sourcePackageName;
permissionInfo.nonLocalizedLabel = name;
permissionInfo.protectionLevel = protectionLevel;
- permissionInfo.usageInfoRequired = usageInfoRequired;
return permissionInfo;
}
@@ -484,7 +480,6 @@
bp.protectionLevel = readInt(parser, null, "protection",
PermissionInfo.PROTECTION_NORMAL);
bp.protectionLevel = PermissionInfo.fixProtectionLevel(bp.protectionLevel);
- bp.usageInfoRequired = readInt(parser, null, "usageInfoRequired", 0) != 0;
if (dynamic) {
final PermissionInfo pi = new PermissionInfo();
pi.packageName = sourcePackage.intern();
@@ -492,7 +487,6 @@
pi.icon = readInt(parser, null, "icon", 0);
pi.nonLocalizedLabel = parser.getAttributeValue(null, "label");
pi.protectionLevel = bp.protectionLevel;
- pi.usageInfoRequired = bp.usageInfoRequired;
bp.pendingPermissionInfo = pi;
}
out.put(bp.name, bp);
@@ -525,7 +519,6 @@
if (protectionLevel != PermissionInfo.PROTECTION_NORMAL) {
serializer.attribute(null, "protection", Integer.toString(protectionLevel));
}
- serializer.attribute(null, "usageInfoRequired", usageInfoRequired ? "1" : "0");
if (type == BasePermission.TYPE_DYNAMIC) {
final PermissionInfo pi = perm != null ? perm.info : pendingPermissionInfo;
if (pi != null) {
@@ -562,7 +555,6 @@
if (!compareStrings(pi1.nonLocalizedLabel, pi2.nonLocalizedLabel)) return false;
// We'll take care of setting this one.
if (!compareStrings(pi1.packageName, pi2.packageName)) return false;
- if (pi1.usageInfoRequired != pi2.usageInfoRequired) return false;
// These are not currently stored in settings.
//if (!compareStrings(pi1.group, pi2.group)) return false;
//if (!compareStrings(pi1.nonLocalizedDescription, pi2.nonLocalizedDescription)) return false;
@@ -610,8 +602,6 @@
pw.print(" enforced=");
pw.println(readEnforced);
}
- pw.print(" usageInfoRequired=");
- pw.println(usageInfoRequired);
return true;
}
}
diff --git a/services/core/java/com/android/server/pm/permission/PermissionManagerInternal.java b/services/core/java/com/android/server/pm/permission/PermissionManagerInternal.java
index 189d0f4..f4979746 100644
--- a/services/core/java/com/android/server/pm/permission/PermissionManagerInternal.java
+++ b/services/core/java/com/android/server/pm/permission/PermissionManagerInternal.java
@@ -181,9 +181,4 @@
/** HACK HACK methods to allow for partial migration of data to the PermissionManager class */
public abstract @Nullable BasePermission getPermissionTEMP(@NonNull String permName);
-
- /**
- * Returns {@code true} if {@code permName} has {@code usageInfoRequired} set.
- */
- public abstract boolean isPermissionUsageInfoRequired(@NonNull String permName);
}
diff --git a/services/core/java/com/android/server/pm/permission/PermissionManagerService.java b/services/core/java/com/android/server/pm/permission/PermissionManagerService.java
index a4413f9..38940d6 100644
--- a/services/core/java/com/android/server/pm/permission/PermissionManagerService.java
+++ b/services/core/java/com/android/server/pm/permission/PermissionManagerService.java
@@ -2737,12 +2737,5 @@
return mSettings.getPermissionLocked(permName);
}
}
- @Override
- public boolean isPermissionUsageInfoRequired(String permName) {
- synchronized (PermissionManagerService.this.mLock) {
- BasePermission bp = mSettings.getPermissionLocked(permName);
- return bp != null && bp.usageInfoRequired;
- }
- }
}
}
diff --git a/services/core/java/com/android/server/rollback/RollbackManagerServiceImpl.java b/services/core/java/com/android/server/rollback/RollbackManagerServiceImpl.java
index 24d5bd1..95c3f4c 100644
--- a/services/core/java/com/android/server/rollback/RollbackManagerServiceImpl.java
+++ b/services/core/java/com/android/server/rollback/RollbackManagerServiceImpl.java
@@ -340,12 +340,9 @@
// for apex?
if (!info.isApex()) {
String installerPackageName = pm.getInstallerPackageName(info.getPackageName());
- if (installerPackageName == null) {
- sendFailure(statusReceiver, RollbackManager.STATUS_FAILURE,
- "Cannot find installer package");
- return;
+ if (installerPackageName != null) {
+ params.setInstallerPackageName(installerPackageName);
}
- params.setInstallerPackageName(installerPackageName);
}
params.setAllowDowngrade(true);
if (data.isStaged()) {
diff --git a/services/core/java/com/android/server/wallpaper/WallpaperManagerService.java b/services/core/java/com/android/server/wallpaper/WallpaperManagerService.java
index 071dde7..b0ef8a0 100644
--- a/services/core/java/com/android/server/wallpaper/WallpaperManagerService.java
+++ b/services/core/java/com/android/server/wallpaper/WallpaperManagerService.java
@@ -2243,9 +2243,12 @@
synchronized (mLock) {
mInAmbientMode = inAmbientMode;
final WallpaperData data = mWallpaperMap.get(mCurrentUserId);
+ final boolean hasConnection = data != null && data.connection != null;
+ final WallpaperInfo info = hasConnection ? data.connection.mInfo : null;
+
// The wallpaper info is null for image wallpaper, also use the engine in this case.
- if (data != null && data.connection != null && (data.connection.mInfo == null
- || data.connection.mInfo.supportsAmbientMode())) {
+ if (hasConnection && (info == null && isAodImageWallpaperEnabled()
+ || info != null && info.supportsAmbientMode())) {
// TODO(multi-display) Extends this method with specific display.
engine = data.connection.getDisplayConnectorOrCreate(DEFAULT_DISPLAY).mEngine;
} else {
diff --git a/services/robotests/src/com/android/server/backup/encryption/chunking/ByteRangeTest.java b/services/robotests/src/com/android/server/backup/encryption/chunking/ByteRangeTest.java
new file mode 100644
index 0000000..8df0826
--- /dev/null
+++ b/services/robotests/src/com/android/server/backup/encryption/chunking/ByteRangeTest.java
@@ -0,0 +1,57 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.server.backup.encryption.chunking;
+
+import static org.junit.Assert.assertEquals;
+import static org.testng.Assert.assertThrows;
+
+import android.platform.test.annotations.Presubmit;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.robolectric.RobolectricTestRunner;
+
+/** Tests for {@link ByteRange}. */
+@RunWith(RobolectricTestRunner.class)
+@Presubmit
+public class ByteRangeTest {
+ @Test
+ public void getLength_includesEnd() throws Exception {
+ ByteRange byteRange = new ByteRange(5, 10);
+
+ int length = byteRange.getLength();
+
+ assertEquals(6, length);
+ }
+
+ @Test
+ public void constructor_rejectsNegativeStart() {
+ assertThrows(IllegalArgumentException.class, () -> new ByteRange(-1, 10));
+ }
+
+ @Test
+ public void constructor_rejectsEndBeforeStart() {
+ assertThrows(IllegalArgumentException.class, () -> new ByteRange(10, 9));
+ }
+
+ @Test
+ public void extend_withZeroLength_throwsException() {
+ ByteRange byteRange = new ByteRange(5, 10);
+
+ assertThrows(IllegalArgumentException.class, () -> byteRange.extend(0));
+ }
+}
diff --git a/services/robotests/src/com/android/server/backup/encryption/chunking/DiffScriptBackupWriterTest.java b/services/robotests/src/com/android/server/backup/encryption/chunking/DiffScriptBackupWriterTest.java
new file mode 100644
index 0000000..2af6f2b
--- /dev/null
+++ b/services/robotests/src/com/android/server/backup/encryption/chunking/DiffScriptBackupWriterTest.java
@@ -0,0 +1,90 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.server.backup.encryption.chunking;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import static org.mockito.Mockito.atLeastOnce;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.verify;
+
+import android.platform.test.annotations.Presubmit;
+
+import com.google.common.primitives.Bytes;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.ArgumentCaptor;
+import org.mockito.Captor;
+import org.mockito.Mock;
+import org.robolectric.RobolectricTestRunner;
+
+import java.io.IOException;
+
+/** Tests for {@link DiffScriptBackupWriter}. */
+@RunWith(RobolectricTestRunner.class)
+@Presubmit
+public class DiffScriptBackupWriterTest {
+ private static final byte[] TEST_BYTES = {1, 2, 3, 4, 5, 6, 7, 8, 9};
+
+ @Captor private ArgumentCaptor<Byte> mBytesCaptor;
+ @Mock private SingleStreamDiffScriptWriter mDiffScriptWriter;
+ private BackupWriter mBackupWriter;
+
+ @Before
+ public void setUp() {
+ mDiffScriptWriter = mock(SingleStreamDiffScriptWriter.class);
+ mBackupWriter = new DiffScriptBackupWriter(mDiffScriptWriter);
+ mBytesCaptor = ArgumentCaptor.forClass(Byte.class);
+ }
+
+ @Test
+ public void writeBytes_writesBytesToWriter() throws Exception {
+ mBackupWriter.writeBytes(TEST_BYTES);
+
+ verify(mDiffScriptWriter, atLeastOnce()).writeByte(mBytesCaptor.capture());
+ assertThat(mBytesCaptor.getAllValues())
+ .containsExactlyElementsIn(Bytes.asList(TEST_BYTES))
+ .inOrder();
+ }
+
+ @Test
+ public void writeChunk_writesChunkToWriter() throws Exception {
+ mBackupWriter.writeChunk(0, 10);
+
+ verify(mDiffScriptWriter).writeChunk(0, 10);
+ }
+
+ @Test
+ public void getBytesWritten_returnsTotalSum() throws Exception {
+ mBackupWriter.writeBytes(TEST_BYTES);
+ mBackupWriter.writeBytes(TEST_BYTES);
+ mBackupWriter.writeChunk(/*start=*/ 0, /*length=*/ 10);
+
+ long bytesWritten = mBackupWriter.getBytesWritten();
+
+ assertThat(bytesWritten).isEqualTo(2 * TEST_BYTES.length + 10);
+ }
+
+ @Test
+ public void flush_flushesWriter() throws IOException {
+ mBackupWriter.flush();
+
+ verify(mDiffScriptWriter).flush();
+ }
+}
diff --git a/services/robotests/src/com/android/server/backup/encryption/chunking/SingleStreamDiffScriptWriterTest.java b/services/robotests/src/com/android/server/backup/encryption/chunking/SingleStreamDiffScriptWriterTest.java
new file mode 100644
index 0000000..73baf80
--- /dev/null
+++ b/services/robotests/src/com/android/server/backup/encryption/chunking/SingleStreamDiffScriptWriterTest.java
@@ -0,0 +1,128 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.server.backup.encryption.chunking;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.verify;
+import static org.testng.Assert.assertThrows;
+
+import android.platform.test.annotations.Presubmit;
+
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.robolectric.RobolectricTestRunner;
+
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.util.Locale;
+
+/** Tests for {@link SingleStreamDiffScriptWriter}. */
+@RunWith(RobolectricTestRunner.class)
+@Presubmit
+public class SingleStreamDiffScriptWriterTest {
+ private static final int MAX_CHUNK_SIZE_IN_BYTES = 256;
+ /** By default this Locale does not use Arabic numbers for %d formatting. */
+ private static final Locale HINDI = new Locale("hi", "IN");
+
+ private Locale mDefaultLocale;
+ private ByteArrayOutputStream mOutputStream;
+ private SingleStreamDiffScriptWriter mDiffScriptWriter;
+
+ @Before
+ public void setUp() {
+ mDefaultLocale = Locale.getDefault();
+ mOutputStream = new ByteArrayOutputStream();
+ mDiffScriptWriter =
+ new SingleStreamDiffScriptWriter(mOutputStream, MAX_CHUNK_SIZE_IN_BYTES);
+ }
+
+ @After
+ public void tearDown() {
+ Locale.setDefault(mDefaultLocale);
+ }
+
+ @Test
+ public void writeChunk_withNegativeStart_throwsException() {
+ assertThrows(
+ IllegalArgumentException.class,
+ () -> mDiffScriptWriter.writeChunk(-1, 50));
+ }
+
+ @Test
+ public void writeChunk_withZeroLength_throwsException() {
+ assertThrows(
+ IllegalArgumentException.class,
+ () -> mDiffScriptWriter.writeChunk(0, 0));
+ }
+
+ @Test
+ public void writeChunk_withExistingBytesInBuffer_writesBufferFirst()
+ throws IOException {
+ String testString = "abcd";
+ writeStringAsBytesToWriter(testString, mDiffScriptWriter);
+
+ mDiffScriptWriter.writeChunk(0, 20);
+ mDiffScriptWriter.flush();
+
+ // Expected format: length of abcd, newline, abcd, newline, chunk start - chunk end
+ assertThat(mOutputStream.toString("UTF-8")).isEqualTo(
+ String.format("%d\n%s\n%d-%d\n", testString.length(), testString, 0, 19));
+ }
+
+ @Test
+ public void writeChunk_overlappingPreviousChunk_combinesChunks() throws IOException {
+ mDiffScriptWriter.writeChunk(3, 4);
+
+ mDiffScriptWriter.writeChunk(7, 5);
+ mDiffScriptWriter.flush();
+
+ assertThat(mOutputStream.toString("UTF-8")).isEqualTo(String.format("3-11\n"));
+ }
+
+ @Test
+ public void writeChunk_formatsByteIndexesUsingArabicNumbers() throws Exception {
+ Locale.setDefault(HINDI);
+
+ mDiffScriptWriter.writeChunk(0, 12345);
+ mDiffScriptWriter.flush();
+
+ assertThat(mOutputStream.toString("UTF-8")).isEqualTo("0-12344\n");
+ }
+
+ @Test
+ public void flush_flushesOutputStream() throws IOException {
+ ByteArrayOutputStream mockOutputStream = mock(ByteArrayOutputStream.class);
+ SingleStreamDiffScriptWriter diffScriptWriter =
+ new SingleStreamDiffScriptWriter(mockOutputStream, MAX_CHUNK_SIZE_IN_BYTES);
+
+ diffScriptWriter.flush();
+
+ verify(mockOutputStream).flush();
+ }
+
+ private void writeStringAsBytesToWriter(String string, SingleStreamDiffScriptWriter writer)
+ throws IOException {
+ byte[] bytes = string.getBytes("UTF-8");
+ for (int i = 0; i < bytes.length; i++) {
+ writer.writeByte(bytes[i]);
+ }
+ }
+}
diff --git a/services/tests/servicestests/src/com/android/server/display/BrightnessTrackerTest.java b/services/tests/servicestests/src/com/android/server/display/BrightnessTrackerTest.java
index e3b1245..7081d2e 100644
--- a/services/tests/servicestests/src/com/android/server/display/BrightnessTrackerTest.java
+++ b/services/tests/servicestests/src/com/android/server/display/BrightnessTrackerTest.java
@@ -962,13 +962,13 @@
}
@Override
- public int getColorTemperature(Context context, int userId) {
+ public int getNightDisplayColorTemperature(Context context) {
return mSecureIntSettings.getOrDefault(Settings.Secure.NIGHT_DISPLAY_COLOR_TEMPERATURE,
mDefaultNightModeColorTemperature);
}
@Override
- public boolean isNightModeActive(Context context, int userId) {
+ public boolean isNightDisplayActivated(Context context) {
return mSecureIntSettings.getOrDefault(Settings.Secure.NIGHT_DISPLAY_ACTIVATED,
0) == 1;
}
diff --git a/services/tests/servicestests/src/com/android/server/display/ColorDisplayServiceTest.java b/services/tests/servicestests/src/com/android/server/display/ColorDisplayServiceTest.java
index 0b01657..5900fc5 100644
--- a/services/tests/servicestests/src/com/android/server/display/ColorDisplayServiceTest.java
+++ b/services/tests/servicestests/src/com/android/server/display/ColorDisplayServiceTest.java
@@ -26,6 +26,7 @@
import android.content.Context;
import android.content.ContextWrapper;
import android.hardware.display.ColorDisplayManager;
+import android.hardware.display.Time;
import android.os.Handler;
import android.os.UserHandle;
import android.provider.Settings;
@@ -37,7 +38,6 @@
import androidx.test.runner.AndroidJUnit4;
import com.android.internal.R;
-import com.android.internal.app.ColorDisplayController;
import com.android.internal.util.test.FakeSettingsProvider;
import com.android.server.LocalServices;
import com.android.server.SystemService;
@@ -71,7 +71,6 @@
private MockTwilightManager mTwilightManager;
private ColorDisplayService mColorDisplayService;
- private ColorDisplayController mColorDisplayController;
private ColorDisplayService.BinderService mBinderService;
@BeforeClass
@@ -97,7 +96,6 @@
mTwilightManager = new MockTwilightManager();
LocalServices.addService(TwilightManager.class, mTwilightManager);
- mColorDisplayController = new ColorDisplayController(mContext, mUserId);
mColorDisplayService = new ColorDisplayService(mContext);
mBinderService = mColorDisplayService.new BinderService();
}
@@ -988,9 +986,11 @@
* @param endTimeOffset the offset relative to now to deactivate Night display (in minutes)
*/
private void setAutoModeCustom(int startTimeOffset, int endTimeOffset) {
- mColorDisplayController.setAutoMode(ColorDisplayManager.AUTO_MODE_CUSTOM_TIME);
- mColorDisplayController.setCustomStartTime(getLocalTimeRelativeToNow(startTimeOffset));
- mColorDisplayController.setCustomEndTime(getLocalTimeRelativeToNow(endTimeOffset));
+ mBinderService.setNightDisplayAutoMode(ColorDisplayManager.AUTO_MODE_CUSTOM_TIME);
+ mBinderService.setNightDisplayCustomStartTime(
+ new Time(getLocalTimeRelativeToNow(startTimeOffset)));
+ mBinderService
+ .setNightDisplayCustomEndTime(new Time(getLocalTimeRelativeToNow(endTimeOffset)));
}
/**
@@ -1000,7 +1000,7 @@
* @param sunriseOffset the offset relative to now for sunrise (in minutes)
*/
private void setAutoModeTwilight(int sunsetOffset, int sunriseOffset) {
- mColorDisplayController.setAutoMode(ColorDisplayManager.AUTO_MODE_TWILIGHT);
+ mBinderService.setNightDisplayAutoMode(ColorDisplayManager.AUTO_MODE_TWILIGHT);
mTwilightManager.setTwilightState(
getTwilightStateRelativeToNow(sunsetOffset, sunriseOffset));
}
@@ -1041,22 +1041,18 @@
}
/**
- * Configures color mode via ColorDisplayController.
- *
- * @param colorMode the color mode to set
+ * Configures color mode.
*/
private void setColorMode(int colorMode) {
- mColorDisplayController.setColorMode(colorMode);
+ mBinderService.setColorMode(colorMode);
}
/**
* Returns whether the color mode is valid on the device the tests are running on.
- *
- * @param mode the mode to check
*/
private boolean isColorModeValid(int mode) {
final int[] availableColorModes = mContext.getResources().getIntArray(
- R.array.config_availableColorModes);
+ R.array.config_availableColorModes);
if (availableColorModes != null) {
for (int availableMode : availableColorModes) {
if (mode == availableMode) {
@@ -1073,12 +1069,9 @@
private void startService() {
Secure.putIntForUser(mContext.getContentResolver(), Secure.USER_SETUP_COMPLETE, 1, mUserId);
- InstrumentationRegistry.getInstrumentation().runOnMainSync(new Runnable() {
- @Override
- public void run() {
- mColorDisplayService.onBootPhase(SystemService.PHASE_BOOT_COMPLETED);
- mColorDisplayService.onStartUser(mUserId);
- }
+ InstrumentationRegistry.getInstrumentation().runOnMainSync(() -> {
+ mColorDisplayService.onBootPhase(SystemService.PHASE_BOOT_COMPLETED);
+ mColorDisplayService.onStartUser(mUserId);
});
}
@@ -1100,7 +1093,7 @@
*/
private void assertActiveColorMode(int mode) {
assertWithMessage("Unexpected color mode setting")
- .that(mColorDisplayController.getColorMode())
+ .that(mBinderService.getColorMode())
.isEqualTo(mode);
}
diff --git a/services/tests/servicestests/src/com/android/server/pm/PackageParserTest.java b/services/tests/servicestests/src/com/android/server/pm/PackageParserTest.java
index 85909d5..72357ce 100644
--- a/services/tests/servicestests/src/com/android/server/pm/PackageParserTest.java
+++ b/services/tests/servicestests/src/com/android/server/pm/PackageParserTest.java
@@ -31,7 +31,6 @@
import android.content.pm.ServiceInfo;
import android.content.pm.SharedLibraryInfo;
import android.content.pm.Signature;
-import android.content.pm.UsesPermissionInfo;
import android.os.Bundle;
import android.os.Parcel;
import android.platform.test.annotations.Presubmit;
@@ -466,7 +465,6 @@
pkg.services.add(new PackageParser.Service(dummy, new ServiceInfo()));
pkg.instrumentation.add(new PackageParser.Instrumentation(dummy, new InstrumentationInfo()));
pkg.requestedPermissions.add("foo7");
- pkg.usesPermissionInfos.add(new UsesPermissionInfo("foo7"));
pkg.implicitPermissions.add("foo25");
pkg.protectedBroadcasts = new ArrayList<>();
diff --git a/services/tests/servicestests/src/com/android/server/pm/dex/DexManagerTests.java b/services/tests/servicestests/src/com/android/server/pm/dex/DexManagerTests.java
index 2ddc71f..48ab8d6 100644
--- a/services/tests/servicestests/src/com/android/server/pm/dex/DexManagerTests.java
+++ b/services/tests/servicestests/src/com/android/server/pm/dex/DexManagerTests.java
@@ -141,7 +141,8 @@
assertIsUsedByOtherApps(mBarUser0, pui, true);
assertTrue(pui.getDexUseInfoMap().isEmpty());
- assertHasDclInfo(mBarUser0, mFooUser0, mBarUser0.getBaseAndSplitDexPaths());
+ // A package loading another package's APK is not DCL (it's not app data).
+ assertNoDclInfo(mBarUser0);
}
@Test
@@ -334,7 +335,9 @@
notifyDexLoad(mFooUser0, newSplits, mUser0);
PackageUseInfo pui = getPackageUseInfo(mBarUser0);
assertIsUsedByOtherApps(newSplits, pui, true);
- assertHasDclInfo(mBarUser0, mFooUser0, newSplits);
+
+ // Primary and split APKs are not recorded as DCL.
+ assertNoDclInfo(mBarUser0);
}
@Test
diff --git a/services/tests/wmtests/src/com/android/server/wm/ActivityMetricsLaunchObserverTests.java b/services/tests/wmtests/src/com/android/server/wm/ActivityMetricsLaunchObserverTests.java
index ee22861..2de4ae0 100644
--- a/services/tests/wmtests/src/com/android/server/wm/ActivityMetricsLaunchObserverTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/ActivityMetricsLaunchObserverTests.java
@@ -57,7 +57,6 @@
*/
@SmallTest
@Presubmit
-@FlakyTest(detail="promote once confirmed non-flaky")
public class ActivityMetricsLaunchObserverTests extends ActivityTestsBase {
private ActivityMetricsLogger mActivityMetricsLogger;
private ActivityMetricsLaunchObserver mLaunchObserver;
diff --git a/services/tests/wmtests/src/com/android/server/wm/AppChangeTransitionTests.java b/services/tests/wmtests/src/com/android/server/wm/AppChangeTransitionTests.java
index 3bf884f..defe981 100644
--- a/services/tests/wmtests/src/com/android/server/wm/AppChangeTransitionTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/AppChangeTransitionTests.java
@@ -42,7 +42,6 @@
* Build/Install/Run:
* atest WmTests:AppChangeTransitionTests
*/
-@FlakyTest(detail = "Promote when shown to be stable.")
@SmallTest
public class AppChangeTransitionTests extends WindowTestsBase {
diff --git a/services/tests/wmtests/src/com/android/server/wm/InsetsSourceProviderTest.java b/services/tests/wmtests/src/com/android/server/wm/InsetsSourceProviderTest.java
index a498a1a..0c363de 100644
--- a/services/tests/wmtests/src/com/android/server/wm/InsetsSourceProviderTest.java
+++ b/services/tests/wmtests/src/com/android/server/wm/InsetsSourceProviderTest.java
@@ -39,7 +39,6 @@
import org.junit.Test;
@SmallTest
-@FlakyTest(detail = "Promote once confirmed non-flaky")
@Presubmit
public class InsetsSourceProviderTest extends WindowTestsBase {
diff --git a/services/tests/wmtests/src/com/android/server/wm/PendingRemoteAnimationRegistryTest.java b/services/tests/wmtests/src/com/android/server/wm/PendingRemoteAnimationRegistryTest.java
index beaac8e..86bf3db 100644
--- a/services/tests/wmtests/src/com/android/server/wm/PendingRemoteAnimationRegistryTest.java
+++ b/services/tests/wmtests/src/com/android/server/wm/PendingRemoteAnimationRegistryTest.java
@@ -40,7 +40,6 @@
* atest WmTests:PendingRemoteAnimationRegistryTest
*/
@SmallTest
-@FlakyTest
@Presubmit
public class PendingRemoteAnimationRegistryTest extends ActivityTestsBase {
diff --git a/services/tests/wmtests/src/com/android/server/wm/PersisterQueueTests.java b/services/tests/wmtests/src/com/android/server/wm/PersisterQueueTests.java
index 434ba93..c3d2f33 100644
--- a/services/tests/wmtests/src/com/android/server/wm/PersisterQueueTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/PersisterQueueTests.java
@@ -47,7 +47,6 @@
* atest WmTests:PersisterQueueTests
*/
@MediumTest
-@FlakyTest(detail = "Confirm stable in post-submit before removing")
@Presubmit
public class PersisterQueueTests implements PersisterQueue.Listener {
private static final long INTER_WRITE_DELAY_MS = 50;
diff --git a/services/tests/wmtests/src/com/android/server/wm/SafeActivityOptionsTest.java b/services/tests/wmtests/src/com/android/server/wm/SafeActivityOptionsTest.java
index 530fd6d..dad6c95 100644
--- a/services/tests/wmtests/src/com/android/server/wm/SafeActivityOptionsTest.java
+++ b/services/tests/wmtests/src/com/android/server/wm/SafeActivityOptionsTest.java
@@ -31,7 +31,6 @@
* atest WmTests:SafeActivityOptionsTest
*/
@MediumTest
-@FlakyTest
@Presubmit
public class SafeActivityOptionsTest {
diff --git a/services/tests/wmtests/src/com/android/server/wm/SurfaceAnimatorTest.java b/services/tests/wmtests/src/com/android/server/wm/SurfaceAnimatorTest.java
index 9b84215..edb395a 100644
--- a/services/tests/wmtests/src/com/android/server/wm/SurfaceAnimatorTest.java
+++ b/services/tests/wmtests/src/com/android/server/wm/SurfaceAnimatorTest.java
@@ -179,7 +179,6 @@
}
@Test
- @FlakyTest(detail = "Promote once confirmed non-flaky")
public void testDeferFinish() {
// Start animation
diff --git a/services/tests/wmtests/src/com/android/server/wm/TaskPersisterTest.java b/services/tests/wmtests/src/com/android/server/wm/TaskPersisterTest.java
index df7bc11..12ed3c2 100644
--- a/services/tests/wmtests/src/com/android/server/wm/TaskPersisterTest.java
+++ b/services/tests/wmtests/src/com/android/server/wm/TaskPersisterTest.java
@@ -41,7 +41,6 @@
* Build/Install/Run:
* atest WmTests:TaskPersisterTest
*/
-@FlakyTest(detail = "Promote to presubmit if stable")
@Presubmit
public class TaskPersisterTest {
private static final String TEST_USER_NAME = "AM-Test-User";
diff --git a/services/tests/wmtests/src/com/android/server/wm/WindowContainerControllerTests.java b/services/tests/wmtests/src/com/android/server/wm/WindowContainerControllerTests.java
index de3567e..af8ccc9 100644
--- a/services/tests/wmtests/src/com/android/server/wm/WindowContainerControllerTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/WindowContainerControllerTests.java
@@ -37,7 +37,6 @@
* Build/Install/Run:
* atest FrameworksServicesTests:WindowContainerControllerTests
*/
-@FlakyTest(bugId = 74078662)
@SmallTest
@Presubmit
public class WindowContainerControllerTests extends WindowTestsBase {
diff --git a/services/tests/wmtests/src/com/android/server/wm/WindowStateTests.java b/services/tests/wmtests/src/com/android/server/wm/WindowStateTests.java
index be47153..8876214 100644
--- a/services/tests/wmtests/src/com/android/server/wm/WindowStateTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/WindowStateTests.java
@@ -21,6 +21,7 @@
import static android.hardware.camera2.params.OutputConfiguration.ROTATION_90;
import static android.view.InsetsState.TYPE_TOP_BAR;
import static android.view.Surface.ROTATION_0;
+import static android.view.ViewRootImpl.NEW_INSETS_MODE_FULL;
import static android.view.WindowManager.LayoutParams.FIRST_SUB_WINDOW;
import static android.view.WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM;
import static android.view.WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE;
@@ -61,13 +62,15 @@
import android.view.DisplayCutout;
import android.view.InsetsSource;
import android.view.SurfaceControl;
+import android.view.ViewRootImpl;
import android.view.WindowManager;
-import androidx.test.filters.FlakyTest;
import androidx.test.filters.SmallTest;
import com.android.server.wm.utils.WmDisplayCutout;
+import org.junit.AfterClass;
+import org.junit.BeforeClass;
import org.junit.Test;
import java.util.LinkedList;
@@ -78,10 +81,23 @@
* Build/Install/Run:
* atest FrameworksServicesTests:WindowStateTests
*/
-@FlakyTest(bugId = 74078662)
@SmallTest
@Presubmit
public class WindowStateTests extends WindowTestsBase {
+ private static int sPreviousNewInsetsMode;
+
+ @BeforeClass
+ public static void setUpOnce() {
+ sPreviousNewInsetsMode = ViewRootImpl.sNewInsetsMode;
+ // To let the insets provider control the insets visibility, the insets mode has to be
+ // NEW_INSETS_MODE_FULL.
+ ViewRootImpl.sNewInsetsMode = NEW_INSETS_MODE_FULL;
+ }
+
+ @AfterClass
+ public static void tearDownOnce() {
+ ViewRootImpl.sNewInsetsMode = sPreviousNewInsetsMode;
+ }
@Test
public void testIsParentWindowHidden() {
diff --git a/services/tests/wmtests/src/com/android/server/wm/WindowTokenTests.java b/services/tests/wmtests/src/com/android/server/wm/WindowTokenTests.java
index 3048f1a..d556886 100644
--- a/services/tests/wmtests/src/com/android/server/wm/WindowTokenTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/WindowTokenTests.java
@@ -39,7 +39,6 @@
* Build/Install/Run:
* atest FrameworksServicesTests:WindowTokenTests
*/
-@FlakyTest(bugId = 74078662)
@SmallTest
@Presubmit
public class WindowTokenTests extends WindowTestsBase {
diff --git a/services/tests/wmtests/src/com/android/server/wm/WindowTracingTest.java b/services/tests/wmtests/src/com/android/server/wm/WindowTracingTest.java
index b81a8e7..b6b9a86 100644
--- a/services/tests/wmtests/src/com/android/server/wm/WindowTracingTest.java
+++ b/services/tests/wmtests/src/com/android/server/wm/WindowTracingTest.java
@@ -60,7 +60,6 @@
* Build/Install/Run:
* atest FrameworksServicesTests:WindowTracingTest
*/
-@FlakyTest(bugId = 74078662)
@SmallTest
@Presubmit
public class WindowTracingTest {
diff --git a/services/tests/wmtests/src/com/android/server/wm/utils/RotationCacheTest.java b/services/tests/wmtests/src/com/android/server/wm/utils/RotationCacheTest.java
index 33f34b4..05d8237 100644
--- a/services/tests/wmtests/src/com/android/server/wm/utils/RotationCacheTest.java
+++ b/services/tests/wmtests/src/com/android/server/wm/utils/RotationCacheTest.java
@@ -37,7 +37,6 @@
* atest WmTests:RotationCacheTest
*/
@SmallTest
-@FlakyTest(bugId = 74078662)
@Presubmit
public class RotationCacheTest {
diff --git a/startop/view_compiler/OWNERS b/startop/view_compiler/OWNERS
new file mode 100644
index 0000000..e5aead9
--- /dev/null
+++ b/startop/view_compiler/OWNERS
@@ -0,0 +1,2 @@
+eholk@google.com
+mathieuc@google.com
diff --git a/telephony/java/com/android/internal/telephony/cdma/SmsMessage.java b/telephony/java/com/android/internal/telephony/cdma/SmsMessage.java
index 964a313..9080e23 100644
--- a/telephony/java/com/android/internal/telephony/cdma/SmsMessage.java
+++ b/telephony/java/com/android/internal/telephony/cdma/SmsMessage.java
@@ -21,7 +21,6 @@
import android.telephony.PhoneNumberUtils;
import android.telephony.SmsCbLocation;
import android.telephony.SmsCbMessage;
-import android.telephony.TelephonyManager;
import android.telephony.cdma.CdmaSmsCbProgramData;
import android.telephony.Rlog;
import android.util.Log;
@@ -746,8 +745,10 @@
/**
* Parses a broadcast SMS, possibly containing a CMAS alert.
+ *
+ * @param plmn the PLMN for a broadcast SMS
*/
- public SmsCbMessage parseBroadcastSms() {
+ public SmsCbMessage parseBroadcastSms(String plmn) {
BearerData bData = BearerData.decode(mEnvelope.bearerData, mEnvelope.serviceCategory);
if (bData == null) {
Rlog.w(LOG_TAG, "BearerData.decode() returned null");
@@ -758,7 +759,6 @@
Rlog.d(LOG_TAG, "MT raw BearerData = " + HexDump.toHexString(mEnvelope.bearerData));
}
- String plmn = TelephonyManager.getDefault().getNetworkOperator();
SmsCbLocation location = new SmsCbLocation(plmn);
return new SmsCbMessage(SmsCbMessage.MESSAGE_FORMAT_3GPP2,
@@ -858,11 +858,11 @@
bearerData.userData = userData;
byte[] encodedBearerData = BearerData.encode(bearerData);
+ if (encodedBearerData == null) return null;
if (Rlog.isLoggable(LOGGABLE_TAG, Log.VERBOSE)) {
Rlog.d(LOG_TAG, "MO (encoded) BearerData = " + bearerData);
Rlog.d(LOG_TAG, "MO raw BearerData = '" + HexDump.toHexString(encodedBearerData) + "'");
}
- if (encodedBearerData == null) return null;
int teleservice = bearerData.hasUserDataHeader ?
SmsEnvelope.TELESERVICE_WEMT : SmsEnvelope.TELESERVICE_WMT;
diff --git a/tests/RollbackTest/src/com/android/tests/rollback/RollbackTest.java b/tests/RollbackTest/src/com/android/tests/rollback/RollbackTest.java
index 4b277ae..f07ae9f 100644
--- a/tests/RollbackTest/src/com/android/tests/rollback/RollbackTest.java
+++ b/tests/RollbackTest/src/com/android/tests/rollback/RollbackTest.java
@@ -685,7 +685,7 @@
ActivityManager am = context.getSystemService(ActivityManager.class);
am.killBackgroundProcesses(TEST_APP_A);
// Allow another package launch
- crashQueue.offer(intent.getIntExtra("count", 0), 5, TimeUnit.SECONDS);
+ crashQueue.put(intent.getIntExtra("count", 0));
} catch (InterruptedException e) {
fail("Failed to communicate with test app");
}
@@ -694,14 +694,9 @@
context.registerReceiver(crashCountReceiver, crashCountFilter);
// Start apps PackageWatchdog#TRIGGER_FAILURE_COUNT times so TEST_APP_A crashes
- Integer crashCount = null;
do {
RollbackTestUtils.launchPackage(TEST_APP_A);
- crashCount = crashQueue.poll(5, TimeUnit.SECONDS);
- if (crashCount == null) {
- fail("Timed out waiting for crash signal from test app");
- }
- } while(crashCount < 5);
+ } while(crashQueue.take() < 5);
// TEST_APP_A is automatically rolled back by the RollbackPackageHealthObserver
assertEquals(1, RollbackTestUtils.getInstalledVersion(TEST_APP_A));
diff --git a/tools/stats_log_api_gen/Collation.cpp b/tools/stats_log_api_gen/Collation.cpp
index 257043b..a8d970e 100644
--- a/tools/stats_log_api_gen/Collation.cpp
+++ b/tools/stats_log_api_gen/Collation.cpp
@@ -48,6 +48,7 @@
primaryFields(that.primaryFields),
exclusiveField(that.exclusiveField),
uidField(that.uidField),
+ whitelisted(that.whitelisted),
binaryFields(that.binaryFields) {}
AtomDecl::AtomDecl(int c, const string& n, const string& m)
@@ -162,6 +163,7 @@
vector<java_type_t> *signature) {
int errorCount = 0;
+
// Build a sorted list of the fields. Descriptor has them in source file
// order.
map<int, const FieldDescriptor *> fields;
@@ -387,6 +389,11 @@
const Descriptor *atom = atomField->message_type();
AtomDecl atomDecl(atomField->number(), atomField->name(), atom->name());
+
+ if (atomField->options().GetExtension(os::statsd::allow_from_any_uid) == true) {
+ atomDecl.whitelisted = true;
+ }
+
vector<java_type_t> signature;
errorCount += collate_atom(atom, &atomDecl, &signature);
if (atomDecl.primaryFields.size() != 0 && atomDecl.exclusiveField == 0) {
diff --git a/tools/stats_log_api_gen/Collation.h b/tools/stats_log_api_gen/Collation.h
index 450b305..6b86b862 100644
--- a/tools/stats_log_api_gen/Collation.h
+++ b/tools/stats_log_api_gen/Collation.h
@@ -89,6 +89,8 @@
int uidField = 0;
+ bool whitelisted = false;
+
vector<int> binaryFields;
AtomDecl();
diff --git a/tools/stats_log_api_gen/main.cpp b/tools/stats_log_api_gen/main.cpp
index 4491a85..55440d2 100644
--- a/tools/stats_log_api_gen/main.cpp
+++ b/tools/stats_log_api_gen/main.cpp
@@ -158,6 +158,20 @@
}
}
}
+
+ fprintf(out, "};\n");
+ fprintf(out, "\n");
+
+ fprintf(out,
+ "const std::set<int> AtomsInfo::kWhitelistedAtoms = {\n");
+ for (set<AtomDecl>::const_iterator atom = atoms.decls.begin();
+ atom != atoms.decls.end(); atom++) {
+ if (atom->whitelisted) {
+ string constant = make_constant_name(atom->name);
+ fprintf(out, " %s,\n", constant.c_str());
+ }
+ }
+
fprintf(out, "};\n");
fprintf(out, "\n");
@@ -728,6 +742,8 @@
fprintf(out,
" const static std::map<int, std::vector<int>> "
"kBytesFieldAtoms;");
+ fprintf(out,
+ " const static std::set<int> kWhitelistedAtoms;\n");
fprintf(out, "};\n");
fprintf(out, "const static int kMaxPushedAtomId = %d;\n\n",
diff --git a/tools/stats_log_api_gen/test.proto b/tools/stats_log_api_gen/test.proto
index 3be87d9..24ebf4d 100644
--- a/tools/stats_log_api_gen/test.proto
+++ b/tools/stats_log_api_gen/test.proto
@@ -195,4 +195,22 @@
[(android.os.statsd.state_field_option).option = PRIMARY];
optional int32 state = 3
[(android.os.statsd.state_field_option).option = EXCLUSIVE];
+}
+
+message WhitelistedAtom {
+ optional int32 field = 1;
+}
+
+message NonWhitelistedAtom {
+ optional int32 field = 1;
+}
+
+message ListedAtoms {
+ oneof event {
+ // Atoms can be whitelisted i.e. they can be triggered by any source
+ WhitelistedAtom whitelisted_atom = 1 [(android.os.statsd.allow_from_any_uid) = true];
+ // Atoms are not whitelisted by default, so they can only be triggered
+ // by whitelisted sources
+ NonWhitelistedAtom non_whitelisted_atom = 2;
+ }
}
\ No newline at end of file
diff --git a/tools/stats_log_api_gen/test_collation.cpp b/tools/stats_log_api_gen/test_collation.cpp
index ad3bffac..dc585c1 100644
--- a/tools/stats_log_api_gen/test_collation.cpp
+++ b/tools/stats_log_api_gen/test_collation.cpp
@@ -226,5 +226,25 @@
EXPECT_TRUE(errorCount > 0);
}
+TEST(CollationTest, PassOnWhitelistedAtom) {
+ Atoms atoms;
+ int errorCount =
+ collate_atoms(ListedAtoms::descriptor(), &atoms);
+ EXPECT_EQ(errorCount, 0);
+ EXPECT_EQ(atoms.decls.size(), 2ul);
+}
+
+TEST(CollationTest, RecogniseWhitelistedAtom) {
+ Atoms atoms;
+ collate_atoms(ListedAtoms::descriptor(), &atoms);
+ for (const auto& atomDecl : atoms.decls) {
+ if (atomDecl.code == 1) {
+ EXPECT_TRUE(atomDecl.whitelisted);
+ } else {
+ EXPECT_FALSE(atomDecl.whitelisted);
+ }
+ }
+}
+
} // namespace stats_log_api_gen
} // namespace android
\ No newline at end of file