diff options
121 files changed, 1730 insertions, 2156 deletions
diff --git a/Android.mk b/Android.mk index 65d4d240fdcd..9c65948f4838 100644 --- a/Android.mk +++ b/Android.mk @@ -79,34 +79,6 @@ update-api: doc-comment-check-docs # ==== 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 8458ed33ad5d..b7577d1e1b85 100644 --- a/api/current.txt +++ b/api/current.txt @@ -224,6 +224,11 @@ package android { 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 @@ package android { 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 @@ package android { 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 @@ package android.content { 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 @@ package android.content { 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 @@ package android.content.pm { 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 @@ package android.content.pm { 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 @@ package android.content.pm { 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 @@ package android.content.pm { 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 @@ package android.icu.text { 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 @@ package android.icu.text { 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 376aad040532..b7fc33950642 100644 --- a/api/system-current.txt +++ b/api/system-current.txt @@ -3920,6 +3920,7 @@ package android.net { 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 5b51d6e42a68..94e83eac96d2 100644 --- a/api/test-current.txt +++ b/api/test-current.txt @@ -934,6 +934,7 @@ package android.net { } 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 fa5ac8ea11dc..b19d7a971cb8 100644 --- a/cmds/idmap2/libidmap2/Idmap.cpp +++ b/cmds/idmap2/libidmap2/Idmap.cpp @@ -117,6 +117,12 @@ const LoadedPackage* GetPackageAtIndex0(const LoadedArsc& loaded_arsc) { 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 @@ bool IdmapHeader::IsUpToDate(std::ostream& out_error) const { 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 @@ bool IdmapHeader::IsUpToDate(std::ostream& out_error) const { 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 @@ std::unique_ptr<const Idmap> Idmap::FromApkAssets( 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 9e27ccd7cfbb..b40521f054af 100644 --- a/cmds/idmap2/tests/IdmapTests.cpp +++ b/cmds/idmap2/tests/IdmapTests.cpp @@ -191,8 +191,8 @@ TEST(IdmapTests, CreateIdmapFromApkAssets) { 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 b1ca12557dcb..a5588c330d85 100644 --- a/cmds/idmap2/tests/RawPrintVisitorTests.cpp +++ b/cmds/idmap2/tests/RawPrintVisitorTests.cpp @@ -52,8 +52,8 @@ TEST(RawPrintVisitorTests, CreateRawPrintVisitor) { 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 e33bd8c97a07..2a3eee2a7e18 100644 --- a/cmds/statsd/src/atom_field_options.proto +++ b/cmds/statsd/src/atom_field_options.proto @@ -82,4 +82,6 @@ extend google.protobuf.FieldOptions { 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 07aced6846a4..4f17d69f23f2 100644 --- a/cmds/statsd/src/atoms.proto +++ b/cmds/statsd/src/atoms.proto @@ -110,7 +110,7 @@ message Atom { 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 @@ message Atom { 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 a5bd5c6b6364..37d5ba0e6801 100644 --- a/cmds/statsd/src/guardrail/StatsdStats.cpp +++ b/cmds/statsd/src/guardrail/StatsdStats.cpp @@ -443,6 +443,11 @@ void StatsdStats::noteBadValueType(int metricId) { 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 cb17061c1ed1..20ea7e5df1fa 100644 --- a/cmds/statsd/src/guardrail/StatsdStats.h +++ b/cmds/statsd/src/guardrail/StatsdStats.h @@ -360,6 +360,11 @@ public: 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 @@ public: 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 7cc57c12063c..350745b2c326 100644 --- a/cmds/statsd/src/metrics/CountMetricProducer.cpp +++ b/cmds/statsd/src/metrics/CountMetricProducer.cpp @@ -243,6 +243,7 @@ void CountMetricProducer::onDumpReportLocked(const int64_t dumpTimeNs, 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 69bafc354643..6c1c47bbc093 100644 --- a/cmds/statsd/src/metrics/DurationMetricProducer.cpp +++ b/cmds/statsd/src/metrics/DurationMetricProducer.cpp @@ -444,6 +444,7 @@ void DurationMetricProducer::onConditionChangedLocked(const bool conditionMet, 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 c53c4ce5e0d6..7e695a69988f 100644 --- a/cmds/statsd/src/metrics/EventMetricProducer.cpp +++ b/cmds/statsd/src/metrics/EventMetricProducer.cpp @@ -77,6 +77,7 @@ EventMetricProducer::~EventMetricProducer() { 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 c9b71659aa58..2609937924ac 100644 --- a/cmds/statsd/src/metrics/GaugeMetricProducer.cpp +++ b/cmds/statsd/src/metrics/GaugeMetricProducer.cpp @@ -510,6 +510,7 @@ void GaugeMetricProducer::updateCurrentSlicedBucketForAnomaly() { 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 ca681176c54a..6ed6ab500597 100644 --- a/cmds/statsd/src/metrics/MetricsManager.cpp +++ b/cmds/statsd/src/metrics/MetricsManager.cpp @@ -241,12 +241,22 @@ void MetricsManager::onDumpReport(const int64_t dumpTimeStampNs, 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 @@ void MetricsManager::onLogEvent(const LogEvent& event) { 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,31 +293,42 @@ void MetricsManager::onLogEvent(const LogEvent& event) { 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; - } - } 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 false; } } + 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(); int64_t eventTimeNs = event.GetElapsedTimestampNs(); diff --git a/cmds/statsd/src/metrics/MetricsManager.h b/cmds/statsd/src/metrics/MetricsManager.h index 80982c37dc6a..fdc28ea7f219 100644 --- a/cmds/statsd/src/metrics/MetricsManager.h +++ b/cmds/statsd/src/metrics/MetricsManager.h @@ -49,6 +49,10 @@ public: // 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 9fb78e780870..1bd3ef20a578 100644 --- a/cmds/statsd/src/metrics/ValueMetricProducer.cpp +++ b/cmds/statsd/src/metrics/ValueMetricProducer.cpp @@ -175,6 +175,7 @@ void ValueMetricProducer::onSlicedConditionMayChangeLocked(bool overallCondition void ValueMetricProducer::dropDataLocked(const int64_t dropTimeNs) { flushIfNeededLocked(dropTimeNs); + StatsdStats::getInstance().noteBucketDropped(mMetricId); mPastBuckets.clear(); } @@ -434,6 +435,10 @@ void ValueMetricProducer::onDataPulled(const std::vector<std::shared_ptr<LogEven } } 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 d9bec5d588be..0cfefa9e3eb4 100644 --- a/cmds/statsd/src/metrics/ValueMetricProducer.h +++ b/cmds/statsd/src/metrics/ValueMetricProducer.h @@ -61,6 +61,7 @@ public: if (!mSplitBucketForAppUpgrade) { return; } + flushIfNeededLocked(eventTimeNs - 1); if (mIsPulled && mCondition) { pullAndMatchEventsLocked(eventTimeNs - 1); } @@ -212,6 +213,7 @@ private: 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 @@ private: 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 5b9148283bdc..73aab4847e11 100644 --- a/cmds/statsd/src/stats_log.proto +++ b/cmds/statsd/src/stats_log.proto @@ -418,6 +418,7 @@ message StatsdStatsReport { 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 3cb7563b206b..f76a9ad78396 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_SKIPPED_FORWARD_BUCKETS = 4; 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 @@ void writeAtomMetricStatsToStream(const std::pair<int, StatsdStats::AtomMetricSt (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 64045520fb0b..91b98ecffa29 100644 --- a/cmds/statsd/tests/metrics/ValueMetricProducer_test.cpp +++ b/cmds/statsd/tests/metrics/ValueMetricProducer_test.cpp @@ -167,9 +167,10 @@ TEST(ValueMetricProducerTest, TestPulledEventsNoCondition) { 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 @@ TEST(ValueMetricProducerTest, TestPulledEventsNoCondition) { 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 @@ TEST(ValueMetricProducerTest, TestPulledEventsNoCondition) { 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 @@ TEST(ValueMetricProducerTest, TestPulledEventsWithFiltering) { 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 @@ TEST(ValueMetricProducerTest, TestPulledEventsWithFiltering) { 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 @@ TEST(ValueMetricProducerTest, TestPulledEventsTakeAbsoluteValueOnReset) { 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 @@ TEST(ValueMetricProducerTest, TestPulledEventsTakeAbsoluteValueOnReset) { 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 @@ TEST(ValueMetricProducerTest, TestPulledEventsTakeZeroOnReset) { 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 @@ TEST(ValueMetricProducerTest, TestEventsWithNonSlicedCondition) { 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 @@ TEST(ValueMetricProducerTest, TestPulledValueWithUpgrade) { 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 @@ TEST(ValueMetricProducerTest, TestPulledWithAppUpgradeDisabled) { 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 @@ TEST(ValueMetricProducerTest, TestBucketBoundaryNoCondition) { // 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 @@ TEST(ValueMetricProducerTest, TestUseZeroDefaultBase) { 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 @@ TEST(ValueMetricProducerTest, TestUseZeroDefaultBase) { 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 @@ TEST(ValueMetricProducerTest, TestUseZeroDefaultBaseWithPullFailures) { 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 @@ TEST(ValueMetricProducerTest, TestUseZeroDefaultBaseWithPullFailures) { 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 @@ TEST(ValueMetricProducerTest, TestUseZeroDefaultBaseWithPullFailures) { 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 @@ TEST(ValueMetricProducerTest, TestUseZeroDefaultBaseWithPullFailures) { 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 @@ TEST(ValueMetricProducerTest, TestTrimUnusedDimensionKey) { 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 @@ TEST(ValueMetricProducerTest, TestTrimUnusedDimensionKey) { 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 @@ TEST(ValueMetricProducerTest, TestTrimUnusedDimensionKey) { 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 @@ TEST(ValueMetricProducerTest, TestResetBaseOnPullFailBeforeConditionChange) { 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 @@ TEST(ValueMetricProducerTest, TestResetBaseOnPullTooLate) { 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 @@ TEST(ValueMetricProducerTest, TestResetBaseOnPullTooLate) { eventMatcherWizard, tagId, bucketStartTimeNs, bucketStartTimeNs, pullerManager); - valueProducer.mCondition = true; - valueProducer.mHasGlobalBase = true; + valueProducer.mCondition = false; - 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); + // Max delay is set to 0 so pull will exceed max delay. + valueProducer.onConditionChanged(true, bucketStartTimeNs + 1); + EXPECT_EQ(0UL, valueProducer.mCurrentSlicedBucket.size()); +} - // has one slice +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; 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 a3021f371e19..d781a96420c7 100644 --- a/core/java/android/content/Intent.java +++ b/core/java/android/content/Intent.java @@ -817,28 +817,6 @@ public class Intent implements Parcelable, Cloneable { = "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 6d22277a5384..27a5b392855e 100644 --- a/core/java/android/content/pm/PackageInfo.java +++ b/core/java/android/content/pm/PackageInfo.java @@ -204,10 +204,7 @@ public class PackageInfo implements Parcelable { * {@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 @@ public class PackageInfo implements Parcelable { * {@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 @@ public class PackageInfo implements Parcelable { 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 @@ public class PackageInfo implements Parcelable { 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 81ed110d15ec..5020a94c3469 100644 --- a/core/java/android/content/pm/PackageParser.java +++ b/core/java/android/content/pm/PackageParser.java @@ -791,23 +791,18 @@ public class PackageParser { 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 @@ public class PackageParser { 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 @@ public class PackageParser { newPermsMsg.append(' '); } newPermsMsg.append(npi.name); - addRequestedPermission(pkg, npi.name); + pkg.requestedPermissions.add(npi.name); pkg.implicitPermissions.add(npi.name); } } @@ -2519,7 +2514,7 @@ public class PackageParser { 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 @@ public class PackageParser { } } 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 @@ public class PackageParser { } /** - * 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 @@ public class PackageParser { 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 @@ public class PackageParser { 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 @@ public class PackageParser { + parser.getPositionDescription()); } - UsesPermissionInfo info = new UsesPermissionInfo(name, dataSentOffDevice, - dataSharedWithThirdParty, dataUsedForMonetization, retention, retentionWeeks); - pkg.usesPermissionInfos.add(info); - return true; } @@ -3420,10 +3367,6 @@ public class PackageParser { 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 @@ public class PackageParser { @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 @@ public class PackageParser { dest.readStringList(requestedPermissions); internStringArrayList(requestedPermissions); - dest.readParcelableList(usesPermissionInfos, boot); dest.readStringList(implicitPermissions); internStringArrayList(implicitPermissions); protectedBroadcasts = dest.createStringArrayList(); @@ -7327,7 +7266,6 @@ public class PackageParser { 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 fb63e0dad9b6..e24523406ab8 100644 --- a/core/java/android/content/pm/PermissionInfo.java +++ b/core/java/android/content/pm/PermissionInfo.java @@ -20,7 +20,6 @@ import android.annotation.IntDef; 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 class PermissionInfo extends PackageItemInfo implements Parcelable { */ 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 @@ public class PermissionInfo extends PackageItemInfo implements Parcelable { descriptionRes = orig.descriptionRes; requestRes = orig.requestRes; nonLocalizedDescription = orig.nonLocalizedDescription; - usageInfoRequired = orig.usageInfoRequired; } /** @@ -540,7 +532,6 @@ public class PermissionInfo extends PackageItemInfo implements Parcelable { dest.writeInt(descriptionRes); dest.writeInt(requestRes); TextUtils.writeToParcel(nonLocalizedDescription, dest, parcelableFlags); - dest.writeInt(usageInfoRequired ? 1 : 0); } /** @hide */ @@ -581,6 +572,5 @@ public class PermissionInfo extends PackageItemInfo implements Parcelable { 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 d08548fa31a5..000000000000 --- 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 000000000000..468f8332dc2b --- /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 8a141e2bfe6f..2aca55aacf7a 100644 --- a/core/java/android/net/ConnectivityManager.java +++ b/core/java/android/net/ConnectivityManager.java @@ -3923,6 +3923,25 @@ public class ConnectivityManager { } /** + * 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 3a405d35e9aa..872671fa5697 100644 --- a/core/java/android/net/IConnectivityManager.aidl +++ b/core/java/android/net/IConnectivityManager.aidl @@ -27,6 +27,7 @@ import android.net.NetworkQuotaInfo; 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 @@ interface IConnectivityManager 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 949328fd3a99..915a18e59226 100644 --- a/core/java/android/text/TextLine.java +++ b/core/java/android/text/TextLine.java @@ -94,7 +94,8 @@ public class TextLine { 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 6aafa348e3f5..06207a9290d7 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.PackageManager; 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 @@ public final class AccessibilityManager { 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 aee4b1f63812..8a097883dd5c 100644 --- a/core/java/android/view/inputmethod/InputMethodManager.java +++ b/core/java/android/view/inputmethod/InputMethodManager.java @@ -339,7 +339,11 @@ public final class InputMethodManager { // 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 @@ public final class InputMethodManager { * 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 a02103e94b75..542df4562908 100644 --- a/core/java/android/widget/AbsListView.java +++ b/core/java/android/widget/AbsListView.java @@ -442,8 +442,10 @@ public abstract class AbsListView extends AdapterView<ListAdapter> implements Te /** * 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 @@ public abstract class AbsListView extends AdapterView<ListAdapter> implements Te 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 @@ public abstract class AbsListView extends AdapterView<ListAdapter> implements Te 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 659b71f51588..0f4e23d87e0e 100644 --- a/core/java/android/widget/TextView.java +++ b/core/java/android/widget/TextView.java @@ -712,7 +712,7 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener @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 9ba56b8c0f4e..4ac7f5012613 100644 --- a/core/java/com/android/internal/os/ZygoteConnection.java +++ b/core/java/com/android/internal/os/ZygoteConnection.java @@ -334,9 +334,14 @@ class ZygoteConnection { } } - 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 @@ class ZygoteConnection { 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 60b04cf6c77b..07dd26e4969b 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 fa3a549463f5..46e14b41960c 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 881688bd00c0..53cae638db80 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 76b589ca4009..ec53811a6983 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 f84f1f1bdb4f..e6d478aadae0 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 0f35918232b4..6770ae19ce3d 100644 --- a/data/etc/privapp-permissions-platform.xml +++ b/data/etc/privapp-permissions-platform.xml @@ -104,16 +104,6 @@ applications that come with the platform <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 bb04ff3cc9ff..7c9529b8ff71 100644 --- a/graphics/java/android/graphics/Typeface.java +++ b/graphics/java/android/graphics/Typeface.java @@ -134,7 +134,7 @@ public class Typeface { /** * @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 @@ public class Typeface { * @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 @@ public class Typeface { * * @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 1c6210e0c060..761b62588e5a 100644 --- a/media/java/android/media/audiopolicy/AudioMix.java +++ b/media/java/android/media/audiopolicy/AudioMix.java @@ -353,11 +353,6 @@ public class AudioMix { // 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 @@ public class AudioMix { 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 406f9dd94bb4..f07f1e8fb62b 100644 --- a/media/jni/android_media_MediaCodec.cpp +++ b/media/jni/android_media_MediaCodec.cpp @@ -153,8 +153,12 @@ JMediaCodec::JMediaCodec( 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 @@ status_t JMediaCodec::getCodecInfo(JNIEnv *env, jobject *codecInfoObject) const 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 0a53f1a0e268..de08550fa3db 100644 --- a/media/jni/android_media_MediaCodec.h +++ b/media/jni/android_media_MediaCodec.h @@ -155,6 +155,7 @@ private: 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 cf1494296756..6b8f7457eab9 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 */ }; + } + + size_t countCodecs() const { + return mInfoList.size(); } - return mcl; + + 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 sp<MediaCodecInfo> getCodecInfo(JNIEnv *env, jint index) { 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 @@ static jint android_media_MediaCodecList_findCodecByName( 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 jint android_media_MediaCodecList_findCodecByName( 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 @@ static jobject android_media_MediaCodecList_getCodecCapabilities( 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 @@ static jobject android_media_MediaCodecList_getCodecCapabilities( // 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 @@ static jobject android_media_MediaCodecList_getCodecCapabilities( 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_getCodecCapabilities( } 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 dbffa6d6bcf2..0d6d080b6dc2 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.SharedLog; 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 class NetworkMonitor extends StateMachine { 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 @@ public class NetworkMonitor extends StateMachine { } })); 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 478ee54b40e5..cd6abb267e44 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 866b46f732d8..3778a9c1cf83 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 11d73a93ad04..000000000000 --- 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 4393e2bb0ebf..000000000000 --- 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 fece94e69a3d..c3f61eee4930 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.annotation.Nullable; 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.util.DisplayMetrics; 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 @@ public class Dependency extends SystemUI { @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 @@ public class Dependency extends SystemUI { 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 88e32cbeaa29..a517d7ce8e0e 100644 --- a/packages/SystemUI/src/com/android/systemui/DependencyProvider.java +++ b/packages/SystemUI/src/com/android/systemui/DependencyProvider.java @@ -24,6 +24,7 @@ import static com.android.systemui.Dependency.TIME_TICK_HANDLER_NAME; 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.util.DisplayMetrics; 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 @@ public class DependencyProvider { @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 50409421a68b..2aecc24e83c0 100644 --- a/packages/SystemUI/src/com/android/systemui/ImageWallpaper.java +++ b/packages/SystemUI/src/com/android/systemui/ImageWallpaper.java @@ -19,11 +19,8 @@ package com.android.systemui; 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.Rect; 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.Surface; 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 @@ import java.io.PrintWriter; 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 @@ public class ImageWallpaper extends WallpaperService { @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 @@ public class ImageWallpaper extends WallpaperService { } } } - - /** - * 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 d03b00bcfc85..000000000000 --- 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 4e07872c9456..000000000000 --- 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 477e7d7ebf72..000000000000 --- 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 787972c08e4a..000000000000 --- 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 8916b28f201a..000000000000 --- 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 fa1426e45142..cff7fe449be1 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 @@ class OngoingPrivacyDialog constructor( 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 @@ class OngoingPrivacyDialog constructor( // 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 de78d3376500..effa935c5c20 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.annotation.Nullable; 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 android.widget.Switch; 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 java.util.TimeZone; 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 @@ public class NightDisplayTile extends QSTileImpl<BooleanState> 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 @@ public class NightDisplayTile extends QSTileImpl<BooleanState> // 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 @@ public class NightDisplayTile extends QSTileImpl<BooleanState> @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 @@ public class NightDisplayTile extends QSTileImpl<BooleanState> } /** - * 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 @@ public class NightDisplayTile extends QSTileImpl<BooleanState> 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 @@ public class NightDisplayTile extends QSTileImpl<BooleanState> @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 @@ public class NightDisplayTile extends QSTileImpl<BooleanState> 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 b6948fc4bd1f..c7b2fab54fff 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 @@ public class NotificationInfo extends LinearLayout implements NotificationGuts.G 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 b96c55b37c48..c9be2c8f6703 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 @@ package com.android.systemui.statusbar.phone; 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 @@ public class AutoTileManager { 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 @@ public class AutoTileManager { HotspotController hotspotController, DataSaverController dataSaverController, ManagedProfileController managedProfileController, - ColorDisplayController colorDisplayController) { + NightDisplayListener nightDisplayListener) { mAutoTracker = autoAddTracker; mContext = context; mHost = host; @@ -66,7 +66,7 @@ public class AutoTileManager { mHotspotController = hotspotController; mDataSaverController = dataSaverController; mManagedProfileController = managedProfileController; - mColorDisplayController = colorDisplayController; + mNightDisplayListener = nightDisplayListener; if (!mAutoTracker.isAdded(HOTSPOT)) { hotspotController.addCallback(mHotspotCallback); } @@ -93,7 +93,7 @@ public class AutoTileManager { } if (!mAutoTracker.isAdded(NIGHT) && ColorDisplayManager.isNightDisplayAvailable(mContext)) { - colorDisplayController.setListener(mColorDisplayCallback); + nightDisplayListener.setCallback(mNightDisplayCallback); } } @@ -106,7 +106,7 @@ public class AutoTileManager { mDataSaverController.removeCallback(mDataSaverListener); mManagedProfileController.removeCallback(mProfileCallback); if (ColorDisplayManager.isNightDisplayAvailable(mContext)) { - mColorDisplayController.setListener(null); + mNightDisplayListener.setCallback(null); } } @@ -157,8 +157,8 @@ public class AutoTileManager { }; @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 @@ public class AutoTileManager { 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 8a2fc37b6ea1..37a0610d4de5 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 @@ public class StatusBar extends SystemUI implements DemoMode, 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 dd1d0ca06fa8..52cabe278e2d 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 @@ public class AodMaskView extends ImageView implements StatusBarStateController.S 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 2a64445f342a..105bd9dd8793 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 @@ package com.android.systemui.statusbar.notification.row; 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 @@ public class NotificationInfoTest extends SysuiTestCase { 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 @@ public class NotificationInfoTest extends SysuiTestCase { 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 1ded835e9651..f3740c4d51d0 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.never; 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 @@ public class AutoTileManagerTest extends SysuiTestCase { mock(HotspotController.class), mock(DataSaverController.class), mock(ManagedProfileController.class), - mock(ColorDisplayController.class)); + mock(NightDisplayListener.class)); } @Test @@ -66,7 +66,7 @@ public class AutoTileManagerTest extends SysuiTestCase { if (!ColorDisplayManager.isNightDisplayAvailable(mContext)) { return; } - mAutoTileManager.mColorDisplayCallback.onActivated(true); + mAutoTileManager.mNightDisplayCallback.onActivated(true); verify(mQsTileHost).addTile("night"); } @@ -75,7 +75,7 @@ public class AutoTileManagerTest extends SysuiTestCase { if (!ColorDisplayManager.isNightDisplayAvailable(mContext)) { return; } - mAutoTileManager.mColorDisplayCallback.onActivated(false); + mAutoTileManager.mNightDisplayCallback.onActivated(false); verify(mQsTileHost, never()).addTile("night"); } @@ -84,7 +84,7 @@ public class AutoTileManagerTest extends SysuiTestCase { if (!ColorDisplayManager.isNightDisplayAvailable(mContext)) { return; } - mAutoTileManager.mColorDisplayCallback.onAutoModeChanged( + mAutoTileManager.mNightDisplayCallback.onAutoModeChanged( ColorDisplayManager.AUTO_MODE_TWILIGHT); verify(mQsTileHost).addTile("night"); } @@ -94,7 +94,7 @@ public class AutoTileManagerTest extends SysuiTestCase { if (!ColorDisplayManager.isNightDisplayAvailable(mContext)) { return; } - mAutoTileManager.mColorDisplayCallback.onAutoModeChanged( + mAutoTileManager.mNightDisplayCallback.onAutoModeChanged( ColorDisplayManager.AUTO_MODE_CUSTOM_TIME); verify(mQsTileHost).addTile("night"); } @@ -104,7 +104,7 @@ public class AutoTileManagerTest extends SysuiTestCase { 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 b8a57ae7b98f..1294dbbbfa87 100644 --- a/packages/overlays/Android.mk +++ b/packages/overlays/Android.mk @@ -16,17 +16,13 @@ LOCAL_PATH:= $(call my-dir) 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 @@ LOCAL_REQUIRED_MODULES := \ 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 000000000000..004d9e3b45f1 --- /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 000000000000..69fb5cbf606d --- /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 000000000000..49d15712d4cc --- /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 000000000000..4aea60121810 --- /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 000000000000..0e4bd58345d5 --- /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 80b3d67217fd..fe4411c1dbb5 100644 --- a/services/core/java/com/android/server/ConnectivityService.java +++ b/services/core/java/com/android/server/ConnectivityService.java @@ -1833,14 +1833,20 @@ public class ConnectivityService extends IConnectivityManager.Stub "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 @@ public class ConnectivityService extends IConnectivityManager.Stub } 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 @@ public class ConnectivityService extends IConnectivityManager.Stub } private void enforceConnectivityInternalPermission() { - mContext.enforceCallingOrSelfPermission( + enforceAnyPermissionOf( android.Manifest.permission.CONNECTIVITY_INTERNAL, - "ConnectivityService"); + NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK); } private void enforceControlAlwaysOnVpnPermission() { @@ -1895,20 +1904,16 @@ public class ConnectivityService extends IConnectivityManager.Stub 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 @@ public class ConnectivityService extends IConnectivityManager.Stub }); } + /** + * 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 5278bbbb4af2..4834ce0da9b3 100644 --- a/services/core/java/com/android/server/LocationManagerService.java +++ b/services/core/java/com/android/server/LocationManagerService.java @@ -792,7 +792,7 @@ public class LocationManagerService extends ILocationManager.Stub { 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 @@ public class LocationManagerService extends ILocationManager.Stub { 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 @@ public class LocationManagerService extends ILocationManager.Stub { @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 class LocationManagerService extends ILocationManager.Stub { 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 @@ public class LocationManagerService extends ILocationManager.Stub { 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 class LocationManagerService extends ILocationManager.Stub { 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 @@ public class LocationManagerService extends ILocationManager.Stub { 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 @@ public class LocationManagerService extends ILocationManager.Stub { 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 @@ public class LocationManagerService extends ILocationManager.Stub { 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 @@ public class LocationManagerService extends ILocationManager.Stub { synchronized (mLock) { removeUpdatesLocked(this); - } - synchronized (this) { clearPendingBroadcastsLocked(); } } @@ -1524,7 +1497,7 @@ public class LocationManagerService extends ILocationManager.Stub { @Override public void onSendFinished(PendingIntent pendingIntent, Intent intent, int resultCode, String resultData, Bundle resultExtras) { - synchronized (this) { + synchronized (mLock) { decrementPendingBroadcastsLocked(); } } @@ -1533,13 +1506,25 @@ public class LocationManagerService extends ILocationManager.Stub { // 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 class LocationManagerService extends ILocationManager.Stub { 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 @@ public class LocationManagerService extends ILocationManager.Stub { //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 @@ public class LocationManagerService extends ILocationManager.Stub { if (!provider.isUseableLocked()) { if (isSettingsExemptLocked(record)) { providerRequest.forceLocation = true; + providerRequest.lowPowerMode = false; } else { continue; } @@ -2080,7 +2063,9 @@ public class LocationManagerService extends ILocationManager.Stub { 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 @@ public class LocationManagerService extends ILocationManager.Stub { return true; } - if (isProviderPackage(callerIdentity.mPackageName)) { - return true; - } + return isProviderPackage(callerIdentity.mPackageName); - return false; } @GuardedBy("mLock") @@ -2192,11 +2174,8 @@ public class LocationManagerService extends ILocationManager.Stub { 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 @@ public class LocationManagerService extends ILocationManager.Stub { 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 @@ public class LocationManagerService extends ILocationManager.Stub { // 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 @@ public class LocationManagerService extends ILocationManager.Stub { 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 @@ public class LocationManagerService extends ILocationManager.Stub { 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 @@ public class LocationManagerService extends ILocationManager.Stub { 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 @@ public class LocationManagerService extends ILocationManager.Stub { 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 @@ public class LocationManagerService extends ILocationManager.Stub { 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 @@ public class LocationManagerService extends ILocationManager.Stub { + 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 a3bae521a162..0dc73d9278a2 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 @@ import java.util.ArrayList; //--------------------------------------------------------------------- // 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 @@ import java.util.ArrayList; 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 @@ import java.util.ArrayList; } } - /*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 @@ import java.util.ArrayList; 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 @@ import java.util.ArrayList; (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 @@ import java.util.ArrayList; 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 11fdc8f05033..37f0496c0db3 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 @@ public final class AudioDeviceInventory { // 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 de63d0ef8edf..a6643d49c79f 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 @@ public class AudioService extends IAudioService.Stub 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 b63af8a31cd9..e9189974e988 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 @@ public class BtHelper { } /*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 @@ public class BtHelper { 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 @@ public class BtHelper { 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 @@ public class BtHelper { 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 @@ public class BtHelper { } }; - 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 90342ee31c3e..017503a03816 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 @@ public class FaceService extends BiometricServiceBase { 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 62947c7dd8b4..9e0a1c0c2ef2 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 @@ public class FingerprintService extends BiometricServiceBase { 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 727cf0e9f084..126beeffbb96 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.SensorEventListener; 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 android.view.Display; 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 @@ public class BrightnessTracker { 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 @@ public class BrightnessTracker { 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 6a760873c6ec..9cb6eeec2126 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 android.view.animation.AnimationUtils; 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 @@ public final class ColorDisplayService extends SystemService { private ContentObserver mUserSetupObserver; private boolean mBootCompleted; - private ColorDisplayController mNightDisplayController; private ContentObserver mContentObserver; private DisplayWhiteBalanceListener mDisplayWhiteBalanceListener; @@ -547,8 +545,6 @@ public final class ColorDisplayService extends SystemService { 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 @@ public final class ColorDisplayService extends SystemService { 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 @@ public final class ColorDisplayService extends SystemService { // 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 @@ public final class ColorDisplayService extends SystemService { getContext().getContentResolver().unregisterContentObserver(mContentObserver); - if (mNightDisplayController != null) { - mNightDisplayController = null; - } - if (mNightDisplayTintController.isAvailable(getContext())) { if (mNightDisplayAutoMode != null) { mNightDisplayAutoMode.onStop(); @@ -740,7 +732,7 @@ public final class ColorDisplayService extends SystemService { } private void onAccessibilityActivated() { - onDisplayColorModeChanged(mNightDisplayController.getColorMode()); + onDisplayColorModeChanged(getColorModeInternal()); } /** @@ -1003,8 +995,7 @@ public final class ColorDisplayService extends SystemService { 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 34c8786b00b3..afe34737fdee 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 @@ public class LocationProviderProxy extends AbstractLocationProvider { @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 d06fc513c0e8..1b719048bc89 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 static com.android.server.pm.PackageInstallerService.prepareStageDir; 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.ParcelableException; 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 @@ public class PackageInstallerSession extends IPackageInstallerSession.Stub { 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 @@ public class PackageInstallerSession extends IPackageInstallerSession.Stub { 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 @@ public class PackageInstallerSession extends IPackageInstallerSession.Stub { } 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 32dc98837854..eaedec597359 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.SharedLibraryInfo; 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 @@ public class PackageManagerService extends IPackageManager.Stub } } } - - // 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 2213901b2049..ee6995b11430 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 @@ public class DexManager { 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 173d9a0551df..1957eb89fd0c 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 @@ public final class BasePermission { */ private boolean perUser; - boolean usageInfoRequired; - public BasePermission(String _name, String _sourcePackageName, @PermissionType int _type) { name = _name; sourcePackageName = _sourcePackageName; @@ -375,7 +373,6 @@ public final class BasePermission { } 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 @@ public final class BasePermission { permissionInfo.packageName = sourcePackageName; permissionInfo.nonLocalizedLabel = name; permissionInfo.protectionLevel = protectionLevel; - permissionInfo.usageInfoRequired = usageInfoRequired; return permissionInfo; } @@ -484,7 +480,6 @@ public final class BasePermission { 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 @@ public final class BasePermission { 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 @@ public final class BasePermission { 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 @@ public final class BasePermission { 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 @@ public final class BasePermission { 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 189d0f476a8c..f4979746bae3 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 @@ public abstract class PermissionManagerInternal { /** 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 a4413f963642..38940d6241a6 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 @@ public class PermissionManagerService { 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 24d5bd14bc44..95c3f4c43313 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 @@ class RollbackManagerServiceImpl extends IRollbackManager.Stub { // 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 071dde74f103..b0ef8a0d4209 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 @@ public class WallpaperManagerService extends IWallpaperManager.Stub 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 000000000000..8df08262c9fa --- /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 000000000000..2af6f2bee8ff --- /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 000000000000..73baf80a2c70 --- /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 e3b1245f20a5..7081d2e3b370 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 @@ public class BrightnessTrackerTest { } @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 0b01657868a8..5900fc57296c 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.app.AlarmManager; 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.InstrumentationRegistry; 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 @@ public class ColorDisplayServiceTest { private MockTwilightManager mTwilightManager; private ColorDisplayService mColorDisplayService; - private ColorDisplayController mColorDisplayController; private ColorDisplayService.BinderService mBinderService; @BeforeClass @@ -97,7 +96,6 @@ public class ColorDisplayServiceTest { 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 @@ public class ColorDisplayServiceTest { * @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 @@ public class ColorDisplayServiceTest { * @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 @@ public class ColorDisplayServiceTest { } /** - * 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 @@ public class ColorDisplayServiceTest { 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 @@ public class ColorDisplayServiceTest { */ 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 85909d564a7b..72357ceee099 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.ProviderInfo; 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 @@ public class PackageParserTest { 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 2ddc71f570b8..48ab8d6698bd 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 @@ public class DexManagerTests { 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 @@ public class DexManagerTests { 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 ee228610ab21..2de4ae02828c 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 @@ import java.util.Arrays; */ @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 3bf884face42..defe9811ebcf 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 @@ import org.junit.Test; * 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 a498a1a9172a..0c363de36328 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.Before; 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 beaac8e58686..86bf3dbb6973 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 @@ import org.mockito.MockitoAnnotations; * 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 434ba932f8ad..c3d2f33b17dd 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 @@ import java.util.function.Predicate; * 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 530fd6d7d70e..dad6c952d7ab 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 @@ import org.junit.Test; * 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 9b84215a8f3b..edb395a17abb 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 @@ public class SurfaceAnimatorTest extends WindowTestsBase { } @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 df7bc11663bc..12ed3c28161f 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 @@ import org.junit.Test; * 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 de3567ed5018..af8ccc981bae 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 @@ import org.junit.Test; * 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 be47153bf0ad..8876214b9636 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.app.WindowConfiguration.WINDOWING_MODE_FULLSCREEN; 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.util.Size; 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 @@ import java.util.LinkedList; * 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 3048f1a3487b..d55688665f70 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 @@ import org.junit.Test; * 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 b81a8e72301a..b6b9a861a282 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 @@ import java.nio.charset.StandardCharsets; * 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 33f34b465576..05d8237b4da4 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 @@ import org.junit.Test; * 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 000000000000..e5aead9ddac8 --- /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 964a31304db5..9080e23eb88f 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.os.SystemProperties; 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 @@ public class SmsMessage extends SmsMessageBase { /** * 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 @@ public class SmsMessage extends SmsMessageBase { 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 @@ public class SmsMessage extends SmsMessageBase { 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 4b277ae850c5..f07ae9f65b1b 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 @@ public class RollbackTest { 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 @@ public class RollbackTest { 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 257043b30704..a8d970edaa85 100644 --- a/tools/stats_log_api_gen/Collation.cpp +++ b/tools/stats_log_api_gen/Collation.cpp @@ -48,6 +48,7 @@ AtomDecl::AtomDecl(const AtomDecl& that) 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 @@ int collate_atom(const Descriptor *atom, AtomDecl *atomDecl, 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 @@ int collate_atoms(const Descriptor *descriptor, Atoms *atoms) { 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 450b30547c21..6b86b862dfad 100644 --- a/tools/stats_log_api_gen/Collation.h +++ b/tools/stats_log_api_gen/Collation.h @@ -89,6 +89,8 @@ struct AtomDecl { 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 4491a8567441..55440d2261d3 100644 --- a/tools/stats_log_api_gen/main.cpp +++ b/tools/stats_log_api_gen/main.cpp @@ -158,6 +158,20 @@ static int write_stats_log_cpp(FILE *out, const Atoms &atoms, } } } + + 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 @@ write_stats_log_header(FILE* out, const Atoms& atoms, const AtomDecl &attributio 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 3be87d95df15..24ebf4de031a 100644 --- a/tools/stats_log_api_gen/test.proto +++ b/tools/stats_log_api_gen/test.proto @@ -195,4 +195,22 @@ message GoodStateAtom3 { [(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 ad3bffacd442..dc585c1c5dd1 100644 --- a/tools/stats_log_api_gen/test_collation.cpp +++ b/tools/stats_log_api_gen/test_collation.cpp @@ -226,5 +226,25 @@ TEST(CollationTest, FailOnBadBinaryFieldAtom) { 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 |