Merge "Fix flaky WindowStateTests"
diff --git a/api/current.txt b/api/current.txt
index b321c224..b7577d1 100644
--- a/api/current.txt
+++ b/api/current.txt
@@ -224,6 +224,11 @@
 
   public static final class R.attr {
     ctor public R.attr();
+    field public static final int __removed1 = 16844185; // 0x1010599
+    field public static final int __removed2 = 16844186; // 0x101059a
+    field public static final int __removed3 = 16844187; // 0x101059b
+    field public static final int __removed4 = 16844188; // 0x101059c
+    field public static final int __removed5 = 16844189; // 0x101059d
     field public static final int absListViewStyle = 16842858; // 0x101006a
     field public static final int accessibilityEventTypes = 16843648; // 0x1010380
     field public static final int accessibilityFeedbackType = 16843650; // 0x1010382
@@ -484,10 +489,6 @@
     field public static final int dashGap = 16843175; // 0x10101a7
     field public static final int dashWidth = 16843174; // 0x10101a6
     field public static final int data = 16842798; // 0x101002e
-    field public static final int dataRetentionTime = 16844189; // 0x101059d
-    field public static final int dataSentOffDevice = 16844186; // 0x101059a
-    field public static final int dataSharedWithThirdParty = 16844187; // 0x101059b
-    field public static final int dataUsedForMonetization = 16844188; // 0x101059c
     field public static final int datePickerDialogTheme = 16843948; // 0x10104ac
     field public static final int datePickerMode = 16843955; // 0x10104b3
     field public static final int datePickerStyle = 16843612; // 0x101035c
@@ -1508,7 +1509,6 @@
     field @Deprecated public static final int unfocusedMonthDateColor = 16843588; // 0x1010344
     field public static final int unselectedAlpha = 16843278; // 0x101020e
     field public static final int updatePeriodMillis = 16843344; // 0x1010250
-    field public static final int usageInfoRequired = 16844185; // 0x1010599
     field public static final int use32bitAbi = 16844053; // 0x1010515
     field public static final int useAppZygote = 16844184; // 0x1010598
     field public static final int useDefaultMargins = 16843641; // 0x1010379
@@ -10265,7 +10265,6 @@
     field public static final String ACTION_PACKAGE_RESTARTED = "android.intent.action.PACKAGE_RESTARTED";
     field public static final String ACTION_PACKAGE_VERIFIED = "android.intent.action.PACKAGE_VERIFIED";
     field public static final String ACTION_PASTE = "android.intent.action.PASTE";
-    field public static final String ACTION_PERMISSION_USAGE_DETAILS = "android.intent.action.PERMISSION_USAGE_DETAILS";
     field public static final String ACTION_PICK = "android.intent.action.PICK";
     field public static final String ACTION_PICK_ACTIVITY = "android.intent.action.PICK_ACTIVITY";
     field public static final String ACTION_POWER_CONNECTED = "android.intent.action.ACTION_POWER_CONNECTED";
@@ -10391,7 +10390,6 @@
     field public static final String EXTRA_NOT_UNKNOWN_SOURCE = "android.intent.extra.NOT_UNKNOWN_SOURCE";
     field public static final String EXTRA_ORIGINATING_URI = "android.intent.extra.ORIGINATING_URI";
     field public static final String EXTRA_PACKAGE_NAME = "android.intent.extra.PACKAGE_NAME";
-    field public static final String EXTRA_PERMISSION_USAGE_PERMISSIONS = "android.intent.extra.PERMISSION_USAGE_PERMISSIONS";
     field public static final String EXTRA_PHONE_NUMBER = "android.intent.extra.PHONE_NUMBER";
     field public static final String EXTRA_PROCESS_TEXT = "android.intent.extra.PROCESS_TEXT";
     field public static final String EXTRA_PROCESS_TEXT_READONLY = "android.intent.extra.PROCESS_TEXT_READONLY";
@@ -11356,8 +11354,8 @@
     field public android.content.pm.ProviderInfo[] providers;
     field public android.content.pm.ActivityInfo[] receivers;
     field public android.content.pm.FeatureInfo[] reqFeatures;
-    field @Deprecated public String[] requestedPermissions;
-    field @Deprecated public int[] requestedPermissionsFlags;
+    field public String[] requestedPermissions;
+    field public int[] requestedPermissionsFlags;
     field public android.content.pm.ServiceInfo[] services;
     field public String sharedUserId;
     field public int sharedUserLabel;
@@ -11365,7 +11363,6 @@
     field public android.content.pm.SigningInfo signingInfo;
     field public String[] splitNames;
     field public int[] splitRevisionCodes;
-    field public android.content.pm.UsesPermissionInfo[] usesPermissions;
     field @Deprecated public int versionCode;
     field public String versionName;
   }
@@ -11865,7 +11862,6 @@
     field public String group;
     field public CharSequence nonLocalizedDescription;
     field @Deprecated public int protectionLevel;
-    field public boolean usageInfoRequired;
   }
 
   public final class ProviderInfo extends android.content.pm.ComponentInfo implements android.os.Parcelable {
@@ -12057,28 +12053,6 @@
     field public static final android.os.Parcelable.Creator<android.content.pm.SigningInfo> CREATOR;
   }
 
-  public final class UsesPermissionInfo extends android.content.pm.PackageItemInfo implements android.os.Parcelable {
-    method public int describeContents();
-    method public int getDataRetention();
-    method public int getDataRetentionWeeks();
-    method public int getDataSentOffDevice();
-    method public int getDataSharedWithThirdParty();
-    method public int getDataUsedForMonetization();
-    method public int getFlags();
-    method public String getPermission();
-    field public static final android.os.Parcelable.Creator<android.content.pm.UsesPermissionInfo> CREATOR;
-    field public static final int FLAG_REQUESTED_PERMISSION_GRANTED = 2; // 0x2
-    field public static final int RETENTION_NOT_RETAINED = 1; // 0x1
-    field public static final int RETENTION_SPECIFIED = 4; // 0x4
-    field public static final int RETENTION_UNDEFINED = 0; // 0x0
-    field public static final int RETENTION_UNLIMITED = 3; // 0x3
-    field public static final int RETENTION_USER_SELECTED = 2; // 0x2
-    field public static final int USAGE_NO = 3; // 0x3
-    field public static final int USAGE_UNDEFINED = 0; // 0x0
-    field public static final int USAGE_USER_TRIGGERED = 2; // 0x2
-    field public static final int USAGE_YES = 1; // 0x1
-  }
-
   public final class VersionedPackage implements android.os.Parcelable {
     ctor public VersionedPackage(@NonNull String, int);
     ctor public VersionedPackage(@NonNull String, long);
diff --git a/cmds/idmap2/libidmap2/Idmap.cpp b/cmds/idmap2/libidmap2/Idmap.cpp
index fa5ac8e..b19d7a9 100644
--- a/cmds/idmap2/libidmap2/Idmap.cpp
+++ b/cmds/idmap2/libidmap2/Idmap.cpp
@@ -117,6 +117,12 @@
   return loaded_arsc.GetPackageById(id);
 }
 
+Result<uint32_t> GetCrc(const ZipFile& zip) {
+  const Result<uint32_t> a = zip.Crc("resources.arsc");
+  const Result<uint32_t> b = zip.Crc("AndroidManifest.xml");
+  return a && b ? Result<uint32_t>(*a ^ *b) : kResultError;
+}
+
 }  // namespace
 
 std::unique_ptr<const IdmapHeader> IdmapHeader::FromBinaryStream(std::istream& stream) {
@@ -153,7 +159,7 @@
     return false;
   }
 
-  Result<uint32_t> target_crc = target_zip->Crc("resources.arsc");
+  Result<uint32_t> target_crc = GetCrc(*target_zip);
   if (!target_crc) {
     out_error << "error: failed to get target crc" << std::endl;
     return false;
@@ -173,7 +179,7 @@
     return false;
   }
 
-  Result<uint32_t> overlay_crc = overlay_zip->Crc("resources.arsc");
+  Result<uint32_t> overlay_crc = GetCrc(*overlay_zip);
   if (!overlay_crc) {
     out_error << "error: failed to get overlay crc" << std::endl;
     return false;
@@ -356,14 +362,14 @@
   header->magic_ = kIdmapMagic;
   header->version_ = kIdmapCurrentVersion;
 
-  Result<uint32_t> crc = target_zip->Crc("resources.arsc");
+  Result<uint32_t> crc = GetCrc(*target_zip);
   if (!crc) {
     out_error << "error: failed to get zip crc for target" << std::endl;
     return nullptr;
   }
   header->target_crc_ = *crc;
 
-  crc = overlay_zip->Crc("resources.arsc");
+  crc = GetCrc(*overlay_zip);
   if (!crc) {
     out_error << "error: failed to get zip crc for overlay" << std::endl;
     return nullptr;
diff --git a/cmds/idmap2/tests/IdmapTests.cpp b/cmds/idmap2/tests/IdmapTests.cpp
index 9e27ccd..b40521f 100644
--- a/cmds/idmap2/tests/IdmapTests.cpp
+++ b/cmds/idmap2/tests/IdmapTests.cpp
@@ -191,8 +191,8 @@
   ASSERT_THAT(idmap->GetHeader(), NotNull());
   ASSERT_EQ(idmap->GetHeader()->GetMagic(), 0x504d4449U);
   ASSERT_EQ(idmap->GetHeader()->GetVersion(), 0x01U);
-  ASSERT_EQ(idmap->GetHeader()->GetTargetCrc(), 0xab7cf70d);
-  ASSERT_EQ(idmap->GetHeader()->GetOverlayCrc(), 0xd470336b);
+  ASSERT_EQ(idmap->GetHeader()->GetTargetCrc(), 0xdd53ca29);
+  ASSERT_EQ(idmap->GetHeader()->GetOverlayCrc(), 0xa71ccd77);
   ASSERT_EQ(idmap->GetHeader()->GetTargetPath().to_string(), target_apk_path);
   ASSERT_EQ(idmap->GetHeader()->GetOverlayPath(), overlay_apk_path);
   ASSERT_EQ(idmap->GetHeader()->GetOverlayPath(), overlay_apk_path);
diff --git a/cmds/idmap2/tests/RawPrintVisitorTests.cpp b/cmds/idmap2/tests/RawPrintVisitorTests.cpp
index b1ca125..a5588c3 100644
--- a/cmds/idmap2/tests/RawPrintVisitorTests.cpp
+++ b/cmds/idmap2/tests/RawPrintVisitorTests.cpp
@@ -52,8 +52,8 @@
 
   ASSERT_NE(stream.str().find("00000000: 504d4449  magic\n"), std::string::npos);
   ASSERT_NE(stream.str().find("00000004: 00000001  version\n"), std::string::npos);
-  ASSERT_NE(stream.str().find("00000008: ab7cf70d  target crc\n"), std::string::npos);
-  ASSERT_NE(stream.str().find("0000000c: d470336b  overlay crc\n"), std::string::npos);
+  ASSERT_NE(stream.str().find("00000008: dd53ca29  target crc\n"), std::string::npos);
+  ASSERT_NE(stream.str().find("0000000c: a71ccd77  overlay crc\n"), std::string::npos);
   ASSERT_NE(stream.str().find("0000021c: 00000000  0x7f010000 -> 0x7f010000 integer/int1\n"),
             std::string::npos);
 }
diff --git a/cmds/statsd/src/atom_field_options.proto b/cmds/statsd/src/atom_field_options.proto
index e33bd8c..2a3eee2 100644
--- a/cmds/statsd/src/atom_field_options.proto
+++ b/cmds/statsd/src/atom_field_options.proto
@@ -82,4 +82,6 @@
     optional bool is_uid = 50001 [default = false];
 
     optional LogMode log_mode = 50002 [default = MODE_AUTOMATIC];
+
+    optional bool allow_from_any_uid = 50003 [default = false];
 }
\ No newline at end of file
diff --git a/cmds/statsd/src/atoms.proto b/cmds/statsd/src/atoms.proto
index 07aced6..4f17d69 100644
--- a/cmds/statsd/src/atoms.proto
+++ b/cmds/statsd/src/atoms.proto
@@ -110,7 +110,7 @@
         PacketWakeupOccurred packet_wakeup_occurred = 44;
         WallClockTimeShifted wall_clock_time_shifted = 45;
         AnomalyDetected anomaly_detected = 46;
-        AppBreadcrumbReported app_breadcrumb_reported = 47;
+        AppBreadcrumbReported app_breadcrumb_reported = 47 [(allow_from_any_uid) = true];
         AppStartOccurred app_start_occurred = 48;
         AppStartCanceled app_start_canceled = 49;
         AppStartFullyDrawn app_start_fully_drawn = 50;
@@ -121,7 +121,7 @@
         AppStartMemoryStateCaptured app_start_memory_state_captured = 55;
         ShutdownSequenceReported shutdown_sequence_reported = 56;
         BootSequenceReported boot_sequence_reported = 57;
-        DaveyOccurred davey_occurred = 58;
+        DaveyOccurred davey_occurred = 58 [(allow_from_any_uid) = true];
         OverlayStateChanged overlay_state_changed = 59;
         ForegroundServiceStateChanged foreground_service_state_changed = 60;
         CallStateChanged call_state_changed = 61;
diff --git a/cmds/statsd/src/guardrail/StatsdStats.cpp b/cmds/statsd/src/guardrail/StatsdStats.cpp
index a5bd5c6..37d5ba0 100644
--- a/cmds/statsd/src/guardrail/StatsdStats.cpp
+++ b/cmds/statsd/src/guardrail/StatsdStats.cpp
@@ -443,6 +443,11 @@
     getAtomMetricStats(metricId).badValueType++;
 }
 
+void StatsdStats::noteBucketDropped(int metricId) {
+    lock_guard<std::mutex> lock(mLock);
+    getAtomMetricStats(metricId).bucketDropped++;
+}
+
 void StatsdStats::noteConditionChangeInNextBucket(int metricId) {
     lock_guard<std::mutex> lock(mLock);
     getAtomMetricStats(metricId).conditionChangeInNextBucket++;
diff --git a/cmds/statsd/src/guardrail/StatsdStats.h b/cmds/statsd/src/guardrail/StatsdStats.h
index cb17061..20ea7e5 100644
--- a/cmds/statsd/src/guardrail/StatsdStats.h
+++ b/cmds/statsd/src/guardrail/StatsdStats.h
@@ -360,6 +360,11 @@
     void noteBadValueType(int atomId);
 
     /**
+     * Buckets were dropped due to reclaim memory.
+     */
+    void noteBucketDropped(int metricId);
+
+    /**
      * A condition change was too late, arrived in the wrong bucket and was skipped
      */
     void noteConditionChangeInNextBucket(int atomId);
@@ -414,6 +419,7 @@
         long badValueType = 0;
         long conditionChangeInNextBucket = 0;
         long invalidatedBucket = 0;
+        long bucketDropped = 0;
     } AtomMetricStats;
 
 private:
diff --git a/cmds/statsd/src/metrics/CountMetricProducer.cpp b/cmds/statsd/src/metrics/CountMetricProducer.cpp
index 7cc57c1..350745b 100644
--- a/cmds/statsd/src/metrics/CountMetricProducer.cpp
+++ b/cmds/statsd/src/metrics/CountMetricProducer.cpp
@@ -243,6 +243,7 @@
 
 void CountMetricProducer::dropDataLocked(const int64_t dropTimeNs) {
     flushIfNeededLocked(dropTimeNs);
+    StatsdStats::getInstance().noteBucketDropped(mMetricId);
     mPastBuckets.clear();
 }
 
diff --git a/cmds/statsd/src/metrics/DurationMetricProducer.cpp b/cmds/statsd/src/metrics/DurationMetricProducer.cpp
index 69bafc3..6c1c47b 100644
--- a/cmds/statsd/src/metrics/DurationMetricProducer.cpp
+++ b/cmds/statsd/src/metrics/DurationMetricProducer.cpp
@@ -444,6 +444,7 @@
 
 void DurationMetricProducer::dropDataLocked(const int64_t dropTimeNs) {
     flushIfNeededLocked(dropTimeNs);
+    StatsdStats::getInstance().noteBucketDropped(mMetricId);
     mPastBuckets.clear();
 }
 
diff --git a/cmds/statsd/src/metrics/EventMetricProducer.cpp b/cmds/statsd/src/metrics/EventMetricProducer.cpp
index c53c4ce..7e695a6 100644
--- a/cmds/statsd/src/metrics/EventMetricProducer.cpp
+++ b/cmds/statsd/src/metrics/EventMetricProducer.cpp
@@ -77,6 +77,7 @@
 
 void EventMetricProducer::dropDataLocked(const int64_t dropTimeNs) {
     mProto->clear();
+    StatsdStats::getInstance().noteBucketDropped(mMetricId);
 }
 
 void EventMetricProducer::onSlicedConditionMayChangeLocked(bool overallCondition,
diff --git a/cmds/statsd/src/metrics/GaugeMetricProducer.cpp b/cmds/statsd/src/metrics/GaugeMetricProducer.cpp
index c9b7165..2609937 100644
--- a/cmds/statsd/src/metrics/GaugeMetricProducer.cpp
+++ b/cmds/statsd/src/metrics/GaugeMetricProducer.cpp
@@ -510,6 +510,7 @@
 
 void GaugeMetricProducer::dropDataLocked(const int64_t dropTimeNs) {
     flushIfNeededLocked(dropTimeNs);
+    StatsdStats::getInstance().noteBucketDropped(mMetricId);
     mPastBuckets.clear();
 }
 
diff --git a/cmds/statsd/src/metrics/MetricsManager.cpp b/cmds/statsd/src/metrics/MetricsManager.cpp
index ca68117..6ed6ab50 100644
--- a/cmds/statsd/src/metrics/MetricsManager.cpp
+++ b/cmds/statsd/src/metrics/MetricsManager.cpp
@@ -241,12 +241,22 @@
     VLOG("=========================Metric Reports End==========================");
 }
 
-// Consume the stats log if it's interesting to this metric.
-void MetricsManager::onLogEvent(const LogEvent& event) {
-    if (!mConfigValid) {
-        return;
-    }
 
+bool MetricsManager::checkLogCredentials(const LogEvent& event) {
+    if (android::util::AtomsInfo::kWhitelistedAtoms.find(event.GetTagId()) !=
+      android::util::AtomsInfo::kWhitelistedAtoms.end()) 
+    {
+        return true;
+    }
+    std::lock_guard<std::mutex> lock(mAllowedLogSourcesMutex);
+    if (mAllowedLogSources.find(event.GetUid()) == mAllowedLogSources.end()) {
+        VLOG("log source %d not on the whitelist", event.GetUid());
+        return false;
+    }
+    return true;
+}
+
+bool MetricsManager::eventSanityCheck(const LogEvent& event) {
     if (event.GetTagId() == android::util::APP_BREADCRUMB_REPORTED) {
         // Check that app breadcrumb reported fields are valid.
         status_t err = NO_ERROR;
@@ -256,23 +266,23 @@
         long appHookUid = event.GetLong(event.size()-2, &err);
         if (err != NO_ERROR ) {
             VLOG("APP_BREADCRUMB_REPORTED had error when parsing the uid");
-            return;
+            return false;
         }
         int32_t loggerUid = event.GetUid();
         if (loggerUid != appHookUid && loggerUid != AID_STATSD) {
             VLOG("APP_BREADCRUMB_REPORTED has invalid uid: claimed %ld but caller is %d",
                  appHookUid, loggerUid);
-            return;
+            return false;
         }
 
         // The state must be from 0,3. This part of code must be manually updated.
         long appHookState = event.GetLong(event.size(), &err);
         if (err != NO_ERROR ) {
             VLOG("APP_BREADCRUMB_REPORTED had error when parsing the state field");
-            return;
+            return false;
         } else if (appHookState < 0 || appHookState > 3) {
             VLOG("APP_BREADCRUMB_REPORTED does not have valid state %ld", appHookState);
-            return;
+            return false;
         }
     } else if (event.GetTagId() == android::util::DAVEY_OCCURRED) {
         // Daveys can be logged from any app since they are logged in libs/hwui/JankTracker.cpp.
@@ -283,29 +293,40 @@
         long jankUid = event.GetLong(1, &err);
         if (err != NO_ERROR ) {
             VLOG("Davey occurred had error when parsing the uid");
-            return;
+            return false;
         }
         int32_t loggerUid = event.GetUid();
         if (loggerUid != jankUid && loggerUid != AID_STATSD) {
             VLOG("DAVEY_OCCURRED has invalid uid: claimed %ld but caller is %d", jankUid,
                  loggerUid);
-            return;
+            return false;
         }
 
         long duration = event.GetLong(event.size(), &err);
         if (err != NO_ERROR ) {
             VLOG("Davey occurred had error when parsing the duration");
-            return;
+            return false;
         } else if (duration > 100000) {
             VLOG("Davey duration is unreasonably long: %ld", duration);
-            return;
+            return false;
         }
-    } else {
-        std::lock_guard<std::mutex> lock(mAllowedLogSourcesMutex);
-        if (mAllowedLogSources.find(event.GetUid()) == mAllowedLogSources.end()) {
-            VLOG("log source %d not on the whitelist", event.GetUid());
-            return;
-        }
+    }
+
+    return true;
+}
+
+// Consume the stats log if it's interesting to this metric.
+void MetricsManager::onLogEvent(const LogEvent& event) {
+    if (!mConfigValid) {
+        return;
+    }
+
+    if (!checkLogCredentials(event)) {
+        return;
+    }
+
+    if (!eventSanityCheck(event)) {
+        return;
     }
 
     int tagId = event.GetTagId();
diff --git a/cmds/statsd/src/metrics/MetricsManager.h b/cmds/statsd/src/metrics/MetricsManager.h
index 80982c3..fdc28ea 100644
--- a/cmds/statsd/src/metrics/MetricsManager.h
+++ b/cmds/statsd/src/metrics/MetricsManager.h
@@ -49,6 +49,10 @@
     // Return whether the configuration is valid.
     bool isConfigValid() const;
 
+    bool checkLogCredentials(const LogEvent& event);
+
+    bool eventSanityCheck(const LogEvent& event);
+
     void onLogEvent(const LogEvent& event);
 
     void onAnomalyAlarmFired(
diff --git a/cmds/statsd/src/metrics/ValueMetricProducer.cpp b/cmds/statsd/src/metrics/ValueMetricProducer.cpp
index 9fb78e7..1bd3ef2 100644
--- a/cmds/statsd/src/metrics/ValueMetricProducer.cpp
+++ b/cmds/statsd/src/metrics/ValueMetricProducer.cpp
@@ -175,6 +175,7 @@
 
 void ValueMetricProducer::dropDataLocked(const int64_t dropTimeNs) {
     flushIfNeededLocked(dropTimeNs);
+    StatsdStats::getInstance().noteBucketDropped(mMetricId);
     mPastBuckets.clear();
 }
 
@@ -434,6 +435,10 @@
             }
         }
         mHasGlobalBase = true;
+
+        // We can probably flush the bucket. Since we used bucketEndTime when calling
+        // #onMatchedLogEventInternalLocked, the current bucket will not have been flushed.
+        flushIfNeededLocked(realEventTime);
     } else {
         VLOG("No need to commit data on condition false.");
     }
diff --git a/cmds/statsd/src/metrics/ValueMetricProducer.h b/cmds/statsd/src/metrics/ValueMetricProducer.h
index d9bec5d..0cfefa9 100644
--- a/cmds/statsd/src/metrics/ValueMetricProducer.h
+++ b/cmds/statsd/src/metrics/ValueMetricProducer.h
@@ -61,6 +61,7 @@
         if (!mSplitBucketForAppUpgrade) {
             return;
         }
+        flushIfNeededLocked(eventTimeNs - 1);
         if (mIsPulled && mCondition) {
             pullAndMatchEventsLocked(eventTimeNs - 1);
         }
@@ -212,6 +213,7 @@
     FRIEND_TEST(ValueMetricProducerTest, TestEventsWithNonSlicedCondition);
     FRIEND_TEST(ValueMetricProducerTest, TestPushedEventsWithUpgrade);
     FRIEND_TEST(ValueMetricProducerTest, TestPulledValueWithUpgrade);
+    FRIEND_TEST(ValueMetricProducerTest, TestPartialBucketCreated);
     FRIEND_TEST(ValueMetricProducerTest, TestPulledValueWithUpgradeWhileConditionFalse);
     FRIEND_TEST(ValueMetricProducerTest, TestPulledWithAppUpgradeDisabled);
     FRIEND_TEST(ValueMetricProducerTest, TestPushedEventsWithoutCondition);
@@ -238,6 +240,8 @@
     FRIEND_TEST(ValueMetricProducerTest, TestInvalidBucketWhenOneConditionFailed);
     FRIEND_TEST(ValueMetricProducerTest, TestInvalidBucketWhenInitialPullFailed);
     FRIEND_TEST(ValueMetricProducerTest, TestInvalidBucketWhenLastPullFailed);
+    FRIEND_TEST(ValueMetricProducerTest, TestResetBaseOnPullDelayExceeded);
+    FRIEND_TEST(ValueMetricProducerTest, TestBaseSetOnConditionChange);
 };
 
 }  // namespace statsd
diff --git a/cmds/statsd/src/stats_log.proto b/cmds/statsd/src/stats_log.proto
index 5b91482..73aab48 100644
--- a/cmds/statsd/src/stats_log.proto
+++ b/cmds/statsd/src/stats_log.proto
@@ -418,6 +418,7 @@
       optional int64 bad_value_type = 5;
       optional int64 condition_change_in_next_bucket = 6;
       optional int64 invalidated_bucket = 7;
+      optional int64 bucket_dropped = 8;
     }
     repeated AtomMetricStats atom_metric_stats = 17;
 
diff --git a/cmds/statsd/src/stats_log_util.cpp b/cmds/statsd/src/stats_log_util.cpp
index 3cb7563..f76a9ad 100644
--- a/cmds/statsd/src/stats_log_util.cpp
+++ b/cmds/statsd/src/stats_log_util.cpp
@@ -79,6 +79,7 @@
 const int FIELD_ID_BAD_VALUE_TYPE = 5;
 const int FIELD_ID_CONDITION_CHANGE_IN_NEXT_BUCKET = 6;
 const int FIELD_ID_INVALIDATED_BUCKET = 7;
+const int FIELD_ID_BUCKET_DROPPED = 8;
 
 namespace {
 
@@ -497,6 +498,8 @@
                        (long long)pair.second.conditionChangeInNextBucket);
     protoOutput->write(FIELD_TYPE_INT64 | FIELD_ID_INVALIDATED_BUCKET,
                        (long long)pair.second.invalidatedBucket);
+    protoOutput->write(FIELD_TYPE_INT64 | FIELD_ID_BUCKET_DROPPED,
+                       (long long)pair.second.bucketDropped);
     protoOutput->end(token);
 }
 
diff --git a/cmds/statsd/tests/metrics/ValueMetricProducer_test.cpp b/cmds/statsd/tests/metrics/ValueMetricProducer_test.cpp
index 6404552..91b98ec 100644
--- a/cmds/statsd/tests/metrics/ValueMetricProducer_test.cpp
+++ b/cmds/statsd/tests/metrics/ValueMetricProducer_test.cpp
@@ -167,9 +167,10 @@
 
     EXPECT_EQ(true, curInterval.hasBase);
     EXPECT_EQ(11, curInterval.base.long_value);
-    EXPECT_EQ(true, curInterval.hasValue);
+    EXPECT_EQ(false, curInterval.hasValue);
     EXPECT_EQ(8, curInterval.value.long_value);
-    EXPECT_EQ(0UL, valueProducer.mPastBuckets.size());
+    EXPECT_EQ(1UL, valueProducer.mPastBuckets.size());
+    EXPECT_EQ(8, valueProducer.mPastBuckets.begin()->second[0].values[0].long_value);
 
     allData.clear();
     event = make_shared<LogEvent>(tagId, bucket3StartTimeNs + 1);
@@ -184,11 +185,12 @@
 
     EXPECT_EQ(true, curInterval.hasBase);
     EXPECT_EQ(23, curInterval.base.long_value);
-    EXPECT_EQ(true, curInterval.hasValue);
+    EXPECT_EQ(false, curInterval.hasValue);
     EXPECT_EQ(12, curInterval.value.long_value);
     EXPECT_EQ(1UL, valueProducer.mPastBuckets.size());
-    EXPECT_EQ(1UL, valueProducer.mPastBuckets.begin()->second.size());
-    EXPECT_EQ(8, valueProducer.mPastBuckets.begin()->second.back().values[0].long_value);
+    EXPECT_EQ(2UL, valueProducer.mPastBuckets.begin()->second.size());
+    EXPECT_EQ(8, valueProducer.mPastBuckets.begin()->second[0].values[0].long_value);
+    EXPECT_EQ(12, valueProducer.mPastBuckets.begin()->second.back().values[0].long_value);
 
     allData.clear();
     event = make_shared<LogEvent>(tagId, bucket4StartTimeNs + 1);
@@ -202,11 +204,80 @@
 
     EXPECT_EQ(true, curInterval.hasBase);
     EXPECT_EQ(36, curInterval.base.long_value);
-    EXPECT_EQ(true, curInterval.hasValue);
+    EXPECT_EQ(false, curInterval.hasValue);
     EXPECT_EQ(13, curInterval.value.long_value);
     EXPECT_EQ(1UL, valueProducer.mPastBuckets.size());
-    EXPECT_EQ(2UL, valueProducer.mPastBuckets.begin()->second.size());
-    EXPECT_EQ(12, valueProducer.mPastBuckets.begin()->second.back().values[0].long_value);
+    EXPECT_EQ(3UL, valueProducer.mPastBuckets.begin()->second.size());
+    EXPECT_EQ(8, valueProducer.mPastBuckets.begin()->second[0].values[0].long_value);
+    EXPECT_EQ(12, valueProducer.mPastBuckets.begin()->second[1].values[0].long_value);
+    EXPECT_EQ(13, valueProducer.mPastBuckets.begin()->second[2].values[0].long_value);
+}
+
+TEST(ValueMetricProducerTest, TestPartialBucketCreated) {
+    ValueMetric metric;
+    metric.set_id(metricId);
+    metric.set_bucket(ONE_MINUTE);
+    metric.mutable_value_field()->set_field(tagId);
+    metric.mutable_value_field()->add_child()->set_field(2);
+    metric.set_max_pull_delay_sec(INT_MAX);
+
+    UidMap uidMap;
+    SimpleAtomMatcher atomMatcher;
+    atomMatcher.set_atom_id(tagId);
+    sp<EventMatcherWizard> eventMatcherWizard =
+            new EventMatcherWizard({new SimpleLogMatchingTracker(
+                    atomMatcherId, logEventMatcherIndex, atomMatcher, uidMap)});
+    sp<MockConditionWizard> wizard = new NaggyMock<MockConditionWizard>();
+    sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>();
+    EXPECT_CALL(*pullerManager, RegisterReceiver(tagId, _, _, _)).WillOnce(Return());
+    EXPECT_CALL(*pullerManager, UnRegisterReceiver(tagId, _)).WillRepeatedly(Return());
+    EXPECT_CALL(*pullerManager, Pull(tagId, _))
+            // Initialize bucket.
+            .WillOnce(Invoke([](int tagId, vector<std::shared_ptr<LogEvent>>* data) {
+                data->clear();
+                shared_ptr<LogEvent> event = make_shared<LogEvent>(tagId, bucketStartTimeNs + 1);
+                event->write(tagId);
+                event->write(1);
+                event->init();
+                data->push_back(event);
+                return true;
+            }))
+            // Partial bucket.
+            .WillOnce(Invoke([](int tagId, vector<std::shared_ptr<LogEvent>>* data) {
+                data->clear();
+                shared_ptr<LogEvent> event = make_shared<LogEvent>(tagId, bucket2StartTimeNs + 10);
+                event->write(tagId);
+                event->write(5);
+                event->init();
+                data->push_back(event);
+                return true;
+            }));
+
+    ValueMetricProducer valueProducer(kConfigKey, metric, -1 /*-1 meaning no condition*/, wizard,
+                                      logEventMatcherIndex, eventMatcherWizard, tagId,
+                                      bucketStartTimeNs, bucketStartTimeNs, pullerManager);
+
+    // First bucket ends.
+    vector<shared_ptr<LogEvent>> allData;
+    allData.clear();
+    shared_ptr<LogEvent> event = make_shared<LogEvent>(tagId, bucket2StartTimeNs + 10);
+    event->write(tagId);
+    event->write(2);
+    event->init();
+    allData.push_back(event);
+    valueProducer.onDataPulled(allData, /** success */ true);
+
+    // Partial buckets created in 2nd bucket.
+    valueProducer.notifyAppUpgrade(bucket2StartTimeNs + 2, "com.foo", 10000, 1);
+
+    // One full bucket and one partial bucket.
+    EXPECT_EQ(1UL, valueProducer.mPastBuckets.size());
+    vector<ValueBucket> buckets = valueProducer.mPastBuckets.begin()->second;
+    EXPECT_EQ(2UL, buckets.size());
+    // Full bucket (2 - 1)
+    EXPECT_EQ(1, buckets[0].values[0].long_value);
+    // Full bucket (5 - 3)
+    EXPECT_EQ(3, buckets[1].values[0].long_value);
 }
 
 /*
@@ -264,9 +335,10 @@
 
     EXPECT_EQ(true, curInterval.hasBase);
     EXPECT_EQ(11, curInterval.base.long_value);
-    EXPECT_EQ(true, curInterval.hasValue);
+    EXPECT_EQ(false, curInterval.hasValue);
     EXPECT_EQ(8, curInterval.value.long_value);
-    EXPECT_EQ(0UL, valueProducer.mPastBuckets.size());
+    EXPECT_EQ(1UL, valueProducer.mPastBuckets.size());
+    EXPECT_EQ(8, valueProducer.mPastBuckets.begin()->second[0].values[0].long_value);
 
     allData.clear();
     event = make_shared<LogEvent>(tagId, bucket3StartTimeNs + 1);
@@ -275,16 +347,15 @@
     event->init();
     allData.push_back(event);
     valueProducer.onDataPulled(allData, /** succeed */ true);
-    // has one slice
-    EXPECT_EQ(1UL, valueProducer.mCurrentSlicedBucket.size());
-    curInterval = valueProducer.mCurrentSlicedBucket.begin()->second[0];
+    // No new data seen, so data has been cleared.
+    EXPECT_EQ(0UL, valueProducer.mCurrentSlicedBucket.size());
 
     EXPECT_EQ(true, curInterval.hasBase);
     EXPECT_EQ(11, curInterval.base.long_value);
-    // no events caused flush of bucket
-    EXPECT_EQ(true, curInterval.hasValue);
+    EXPECT_EQ(false, curInterval.hasValue);
     EXPECT_EQ(8, curInterval.value.long_value);
-    EXPECT_EQ(0UL, valueProducer.mPastBuckets.size());
+    EXPECT_EQ(1UL, valueProducer.mPastBuckets.size());
+    EXPECT_EQ(8, valueProducer.mPastBuckets.begin()->second[0].values[0].long_value);
 
     allData.clear();
     event = make_shared<LogEvent>(tagId, bucket4StartTimeNs + 1);
@@ -363,9 +434,10 @@
     curInterval = valueProducer.mCurrentSlicedBucket.begin()->second[0];
     EXPECT_EQ(true, curInterval.hasBase);
     EXPECT_EQ(10, curInterval.base.long_value);
-    EXPECT_EQ(true, curInterval.hasValue);
+    EXPECT_EQ(false, curInterval.hasValue);
     EXPECT_EQ(10, curInterval.value.long_value);
-    EXPECT_EQ(0UL, valueProducer.mPastBuckets.size());
+    EXPECT_EQ(1UL, valueProducer.mPastBuckets.size());
+    EXPECT_EQ(10, valueProducer.mPastBuckets.begin()->second.back().values[0].long_value);
 
     allData.clear();
     event = make_shared<LogEvent>(tagId, bucket4StartTimeNs + 1);
@@ -378,11 +450,12 @@
     curInterval = valueProducer.mCurrentSlicedBucket.begin()->second[0];
     EXPECT_EQ(true, curInterval.hasBase);
     EXPECT_EQ(36, curInterval.base.long_value);
-    EXPECT_EQ(true, curInterval.hasValue);
+    EXPECT_EQ(false, curInterval.hasValue);
     EXPECT_EQ(26, curInterval.value.long_value);
     EXPECT_EQ(1UL, valueProducer.mPastBuckets.size());
-    EXPECT_EQ(1UL, valueProducer.mPastBuckets.begin()->second.size());
-    EXPECT_EQ(10, valueProducer.mPastBuckets.begin()->second.back().values[0].long_value);
+    EXPECT_EQ(2UL, valueProducer.mPastBuckets.begin()->second.size());
+    EXPECT_EQ(10, valueProducer.mPastBuckets.begin()->second[0].values[0].long_value);
+    EXPECT_EQ(26, valueProducer.mPastBuckets.begin()->second[1].values[0].long_value);
 }
 
 /*
@@ -456,9 +529,10 @@
     curInterval = valueProducer.mCurrentSlicedBucket.begin()->second[0];
     EXPECT_EQ(true, curInterval.hasBase);
     EXPECT_EQ(36, curInterval.base.long_value);
-    EXPECT_EQ(true, curInterval.hasValue);
+    EXPECT_EQ(false, curInterval.hasValue);
     EXPECT_EQ(26, curInterval.value.long_value);
-    EXPECT_EQ(0UL, valueProducer.mPastBuckets.size());
+    EXPECT_EQ(1UL, valueProducer.mPastBuckets.size());
+    EXPECT_EQ(26, valueProducer.mPastBuckets.begin()->second[0].values[0].long_value);
 }
 
 /*
@@ -532,9 +606,10 @@
     curInterval = valueProducer.mCurrentSlicedBucket.begin()->second[0];
     EXPECT_EQ(true, curInterval.hasBase);
     EXPECT_EQ(110, curInterval.base.long_value);
-    EXPECT_EQ(true, curInterval.hasValue);
+    EXPECT_EQ(false, curInterval.hasValue);
     EXPECT_EQ(10, curInterval.value.long_value);
-    EXPECT_EQ(0UL, valueProducer.mPastBuckets.size());
+    EXPECT_EQ(1UL, valueProducer.mPastBuckets.size());
+    EXPECT_EQ(10, valueProducer.mPastBuckets.begin()->second[0].values[0].long_value);
 
     valueProducer.onConditionChanged(false, bucket2StartTimeNs + 1);
 
@@ -651,8 +726,8 @@
     event->init();
     allData.push_back(event);
     valueProducer.onDataPulled(allData, /** succeed */ true);
-    EXPECT_EQ(1UL, valueProducer.mPastBuckets[DEFAULT_METRIC_DIMENSION_KEY].size());
-    EXPECT_EQ(bucket2StartTimeNs + 150, valueProducer.mCurrentBucketStartTimeNs);
+    EXPECT_EQ(2UL, valueProducer.mPastBuckets[DEFAULT_METRIC_DIMENSION_KEY].size());
+    EXPECT_EQ(bucket3StartTimeNs, valueProducer.mCurrentBucketStartTimeNs);
     EXPECT_EQ(20L,
               valueProducer.mPastBuckets[DEFAULT_METRIC_DIMENSION_KEY][0].values[0].long_value);
 }
@@ -694,7 +769,7 @@
 
     valueProducer.notifyAppUpgrade(bucket2StartTimeNs + 150, "ANY.APP", 1, 1);
     EXPECT_EQ(0UL, valueProducer.mPastBuckets[DEFAULT_METRIC_DIMENSION_KEY].size());
-    EXPECT_EQ(bucketStartTimeNs, valueProducer.mCurrentBucketStartTimeNs);
+    EXPECT_EQ(bucket2StartTimeNs, valueProducer.mCurrentBucketStartTimeNs);
 }
 
 TEST(ValueMetricProducerTest, TestPulledValueWithUpgradeWhileConditionFalse) {
@@ -1018,9 +1093,9 @@
     // tartUpdated:false sum:12
     EXPECT_EQ(true, curInterval.hasBase);
     EXPECT_EQ(23, curInterval.base.long_value);
-    EXPECT_EQ(true, curInterval.hasValue);
-    EXPECT_EQ(12, curInterval.value.long_value);
-    EXPECT_EQ(0UL, valueProducer.mPastBuckets.size());
+    EXPECT_EQ(false, curInterval.hasValue);
+    EXPECT_EQ(1UL, valueProducer.mPastBuckets.size());
+    EXPECT_EQ(12, valueProducer.mPastBuckets.begin()->second.back().values[0].long_value);
 
     // pull 3 come late.
     // The previous bucket gets closed with error. (Has start value 23, no ending)
@@ -1681,7 +1756,7 @@
     EXPECT_EQ(2UL, valueProducer.mCurrentSlicedBucket.size());
     EXPECT_EQ(true, interval1.hasBase);
     EXPECT_EQ(11, interval1.base.long_value);
-    EXPECT_EQ(true, interval1.hasValue);
+    EXPECT_EQ(false, interval1.hasValue);
     EXPECT_EQ(8, interval1.value.long_value);
 
     auto it = valueProducer.mCurrentSlicedBucket.begin();
@@ -1695,9 +1770,14 @@
     EXPECT_EQ(2, it->first.getDimensionKeyInWhat().getValues()[0].mValue.int_value);
     EXPECT_EQ(true, interval2.hasBase);
     EXPECT_EQ(4, interval2.base.long_value);
-    EXPECT_EQ(true, interval2.hasValue);
+    EXPECT_EQ(false, interval2.hasValue);
     EXPECT_EQ(4, interval2.value.long_value);
-    EXPECT_EQ(0UL, valueProducer.mPastBuckets.size());
+
+    EXPECT_EQ(2UL, valueProducer.mPastBuckets.size());
+    auto iterator = valueProducer.mPastBuckets.begin();
+    EXPECT_EQ(8, iterator->second[0].values[0].long_value);
+    iterator++;
+    EXPECT_EQ(4, iterator->second[0].values[0].long_value);
 }
 
 /*
@@ -1766,7 +1846,7 @@
     EXPECT_EQ(2UL, valueProducer.mCurrentSlicedBucket.size());
     EXPECT_EQ(true, interval1.hasBase);
     EXPECT_EQ(11, interval1.base.long_value);
-    EXPECT_EQ(true, interval1.hasValue);
+    EXPECT_EQ(false, interval1.hasValue);
     EXPECT_EQ(8, interval1.value.long_value);
 
     auto it = valueProducer.mCurrentSlicedBucket.begin();
@@ -1780,9 +1860,9 @@
     EXPECT_EQ(2, it->first.getDimensionKeyInWhat().getValues()[0].mValue.int_value);
     EXPECT_EQ(true, interval2.hasBase);
     EXPECT_EQ(4, interval2.base.long_value);
-    EXPECT_EQ(true, interval2.hasValue);
+    EXPECT_EQ(false, interval2.hasValue);
     EXPECT_EQ(4, interval2.value.long_value);
-    EXPECT_EQ(0UL, valueProducer.mPastBuckets.size());
+    EXPECT_EQ(2UL, valueProducer.mPastBuckets.size());
 
     // next pull somehow did not happen, skip to end of bucket 3
     allData.clear();
@@ -1793,11 +1873,11 @@
     allData.push_back(event1);
     valueProducer.onDataPulled(allData, /** succeed */ true);
 
-    EXPECT_EQ(2UL, valueProducer.mCurrentSlicedBucket.size());
+    EXPECT_EQ(1UL, valueProducer.mCurrentSlicedBucket.size());
     EXPECT_EQ(true, interval2.hasBase);
-    EXPECT_EQ(5, interval2.base.long_value);
+    EXPECT_EQ(4, interval2.base.long_value);
     EXPECT_EQ(false, interval2.hasValue);
-    EXPECT_EQ(false, interval1.hasBase);
+    EXPECT_EQ(true, interval1.hasBase);
     EXPECT_EQ(false, interval1.hasValue);
     EXPECT_EQ(true, valueProducer.mHasGlobalBase);
     EXPECT_EQ(2UL, valueProducer.mPastBuckets.size());
@@ -1817,13 +1897,13 @@
 
     EXPECT_EQ(2UL, valueProducer.mCurrentSlicedBucket.size());
     EXPECT_EQ(true, interval2.hasBase);
-    EXPECT_EQ(13, interval2.base.long_value);
-    EXPECT_EQ(true, interval2.hasValue);
-    EXPECT_EQ(8, interval2.value.long_value);
+    EXPECT_EQ(5, interval2.base.long_value);
+    EXPECT_EQ(false, interval2.hasValue);
+    EXPECT_EQ(5, interval2.value.long_value);
     EXPECT_EQ(true, interval1.hasBase);
-    EXPECT_EQ(5, interval1.base.long_value);
-    EXPECT_EQ(true, interval1.hasValue);
-    EXPECT_EQ(5, interval1.value.long_value);
+    EXPECT_EQ(13, interval1.base.long_value);
+    EXPECT_EQ(false, interval1.hasValue);
+    EXPECT_EQ(8, interval1.value.long_value);
     EXPECT_EQ(true, valueProducer.mHasGlobalBase);
     EXPECT_EQ(2UL, valueProducer.mPastBuckets.size());
 }
@@ -1892,9 +1972,11 @@
     EXPECT_EQ(2UL, valueProducer.mCurrentSlicedBucket.size());
     EXPECT_EQ(true, interval1.hasBase);
     EXPECT_EQ(11, interval1.base.long_value);
-    EXPECT_EQ(true, interval1.hasValue);
+    EXPECT_EQ(false, interval1.hasValue);
     EXPECT_EQ(8, interval1.value.long_value);
-    EXPECT_TRUE(interval1.seenNewData);
+    EXPECT_FALSE(interval1.seenNewData);
+    EXPECT_EQ(1UL, valueProducer.mPastBuckets.size());
+    EXPECT_EQ(8, valueProducer.mPastBuckets.begin()->second[0].values[0].long_value);
 
     auto it = valueProducer.mCurrentSlicedBucket.begin();
     for (; it != valueProducer.mCurrentSlicedBucket.end(); it++) {
@@ -1908,8 +1990,8 @@
     EXPECT_EQ(true, interval2.hasBase);
     EXPECT_EQ(4, interval2.base.long_value);
     EXPECT_EQ(false, interval2.hasValue);
-    EXPECT_TRUE(interval2.seenNewData);
-    EXPECT_EQ(0UL, valueProducer.mPastBuckets.size());
+    EXPECT_FALSE(interval2.seenNewData);
+    EXPECT_EQ(1UL, valueProducer.mPastBuckets.size());
 
     // next pull somehow did not happen, skip to end of bucket 3
     allData.clear();
@@ -1920,35 +2002,34 @@
     allData.push_back(event1);
     valueProducer.onDataPulled(allData, /** succeed */ true);
 
-    EXPECT_EQ(2UL, valueProducer.mCurrentSlicedBucket.size());
-
-    EXPECT_EQ(false, interval1.hasBase);
-    EXPECT_EQ(false, interval1.hasValue);
-    EXPECT_EQ(8, interval1.value.long_value);
-    // on probation now
-    EXPECT_FALSE(interval1.seenNewData);
-
+	// Only one interval left. One was trimmed.
+    EXPECT_EQ(1UL, valueProducer.mCurrentSlicedBucket.size());
+    interval2 = valueProducer.mCurrentSlicedBucket.begin()->second[0];
+    EXPECT_EQ(2, it->first.getDimensionKeyInWhat().getValues()[0].mValue.int_value);
     EXPECT_EQ(true, interval2.hasBase);
     EXPECT_EQ(5, interval2.base.long_value);
     EXPECT_EQ(false, interval2.hasValue);
-    // back to good status
-    EXPECT_TRUE(interval2.seenNewData);
+    EXPECT_FALSE(interval2.seenNewData);
     EXPECT_EQ(1UL, valueProducer.mPastBuckets.size());
 
     allData.clear();
     event1 = make_shared<LogEvent>(tagId, bucket5StartTimeNs + 1);
     event1->write(2);
-    event1->write(13);
+    event1->write(14);
     event1->init();
     allData.push_back(event1);
     valueProducer.onDataPulled(allData, /** succeed */ true);
 
-    EXPECT_EQ(1UL, valueProducer.mCurrentSlicedBucket.size());
+    interval2 = valueProducer.mCurrentSlicedBucket.begin()->second[0];
     EXPECT_EQ(true, interval2.hasBase);
-    EXPECT_EQ(13, interval2.base.long_value);
-    EXPECT_EQ(true, interval2.hasValue);
-    EXPECT_EQ(8, interval2.value.long_value);
-    EXPECT_EQ(1UL, valueProducer.mPastBuckets.size());
+    EXPECT_EQ(14, interval2.base.long_value);
+    EXPECT_EQ(false, interval2.hasValue);
+    EXPECT_FALSE(interval2.seenNewData);
+    EXPECT_EQ(2UL, valueProducer.mPastBuckets.size());
+    auto iterator = valueProducer.mPastBuckets.begin();
+    EXPECT_EQ(9, iterator->second[0].values[0].long_value);
+    iterator++;
+    EXPECT_EQ(8, iterator->second[0].values[0].long_value);
 }
 
 TEST(ValueMetricProducerTest, TestResetBaseOnPullFailAfterConditionChange_EndOfBucket) {
@@ -2110,7 +2191,7 @@
     EXPECT_EQ(false, valueProducer.mHasGlobalBase);
 }
 
-TEST(ValueMetricProducerTest, TestResetBaseOnPullTooLate) {
+TEST(ValueMetricProducerTest, TestResetBaseOnPullDelayExceeded) {
     ValueMetric metric;
     metric.set_id(metricId);
     metric.set_bucket(ONE_MINUTE);
@@ -2133,7 +2214,7 @@
     EXPECT_CALL(*pullerManager, Pull(tagId, _))
             .WillOnce(Invoke([](int tagId, vector<std::shared_ptr<LogEvent>>* data) {
                 data->clear();
-                shared_ptr<LogEvent> event = make_shared<LogEvent>(tagId, bucket2StartTimeNs + 1);
+                shared_ptr<LogEvent> event = make_shared<LogEvent>(tagId, bucketStartTimeNs + 1);
                 event->write(tagId);
                 event->write(120);
                 event->init();
@@ -2145,35 +2226,91 @@
                                       eventMatcherWizard, tagId, bucketStartTimeNs,
                                       bucketStartTimeNs, pullerManager);
 
-    valueProducer.mCondition = true;
+    valueProducer.mCondition = false;
+
+    // Max delay is set to 0 so pull will exceed max delay.
+    valueProducer.onConditionChanged(true, bucketStartTimeNs + 1);
+    EXPECT_EQ(0UL, valueProducer.mCurrentSlicedBucket.size());
+}
+
+TEST(ValueMetricProducerTest, TestResetBaseOnPullTooLate) {
+    ValueMetric metric;
+    metric.set_id(metricId);
+    metric.set_bucket(ONE_MINUTE);
+    metric.mutable_value_field()->set_field(tagId);
+    metric.mutable_value_field()->add_child()->set_field(2);
+    metric.set_condition(StringToId("SCREEN_ON"));
+    metric.set_max_pull_delay_sec(INT_MAX);
+
+    UidMap uidMap;
+    SimpleAtomMatcher atomMatcher;
+    atomMatcher.set_atom_id(tagId);
+    sp<EventMatcherWizard> eventMatcherWizard =
+            new EventMatcherWizard({new SimpleLogMatchingTracker(
+                    atomMatcherId, logEventMatcherIndex, atomMatcher, uidMap)});
+    sp<MockConditionWizard> wizard = new NaggyMock<MockConditionWizard>();
+    sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>();
+    EXPECT_CALL(*pullerManager, RegisterReceiver(tagId, _, _, _)).WillOnce(Return());
+    EXPECT_CALL(*pullerManager, UnRegisterReceiver(tagId, _)).WillRepeatedly(Return());
+
+    ValueMetricProducer valueProducer(kConfigKey, metric, 1, wizard, logEventMatcherIndex,
+                                      eventMatcherWizard, tagId, bucket2StartTimeNs,
+                                      bucket2StartTimeNs, pullerManager);
+
+    valueProducer.mCondition = false;
+
+    // Event should be skipped since it is from previous bucket.
+    // Pull should not be called.
+    valueProducer.onConditionChanged(true, bucketStartTimeNs);
+    EXPECT_EQ(0UL, valueProducer.mCurrentSlicedBucket.size());
+}
+
+TEST(ValueMetricProducerTest, TestBaseSetOnConditionChange) {
+    ValueMetric metric;
+    metric.set_id(metricId);
+    metric.set_bucket(ONE_MINUTE);
+    metric.mutable_value_field()->set_field(tagId);
+    metric.mutable_value_field()->add_child()->set_field(2);
+    metric.set_condition(StringToId("SCREEN_ON"));
+    metric.set_max_pull_delay_sec(INT_MAX);
+
+    UidMap uidMap;
+    SimpleAtomMatcher atomMatcher;
+    atomMatcher.set_atom_id(tagId);
+    sp<EventMatcherWizard> eventMatcherWizard =
+            new EventMatcherWizard({new SimpleLogMatchingTracker(
+                    atomMatcherId, logEventMatcherIndex, atomMatcher, uidMap)});
+    sp<MockConditionWizard> wizard = new NaggyMock<MockConditionWizard>();
+    sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>();
+    EXPECT_CALL(*pullerManager, RegisterReceiver(tagId, _, _, _)).WillOnce(Return());
+    EXPECT_CALL(*pullerManager, UnRegisterReceiver(tagId, _)).WillRepeatedly(Return());
+    EXPECT_CALL(*pullerManager, Pull(tagId, _))
+            .WillOnce(Invoke([](int tagId, vector<std::shared_ptr<LogEvent>>* data) {
+                data->clear();
+                shared_ptr<LogEvent> event = make_shared<LogEvent>(tagId, bucketStartTimeNs + 1);
+                event->write(tagId);
+                event->write(100);
+                event->init();
+                data->push_back(event);
+                return true;
+            }));
+
+    ValueMetricProducer valueProducer(kConfigKey, metric, 1, wizard, logEventMatcherIndex,
+                                      eventMatcherWizard, tagId, bucketStartTimeNs,
+                                      bucketStartTimeNs, pullerManager);
+
+    valueProducer.mCondition = false;
+    valueProducer.mHasGlobalBase = false;
+
+    valueProducer.onConditionChanged(true, bucketStartTimeNs + 1);
     valueProducer.mHasGlobalBase = true;
-
-    vector<shared_ptr<LogEvent>> allData;
-    allData.clear();
-    shared_ptr<LogEvent> event = make_shared<LogEvent>(tagId, bucket2StartTimeNs + 1);
-    event->write(1);
-    event->write(110);
-    event->init();
-    allData.push_back(event);
-    valueProducer.onDataPulled(allData, /** succeed */ true);
-
-    // has one slice
     EXPECT_EQ(1UL, valueProducer.mCurrentSlicedBucket.size());
     ValueMetricProducer::Interval& curInterval =
             valueProducer.mCurrentSlicedBucket.begin()->second[0];
     EXPECT_EQ(true, curInterval.hasBase);
-    EXPECT_EQ(110, curInterval.base.long_value);
+    EXPECT_EQ(100, curInterval.base.long_value);
     EXPECT_EQ(false, curInterval.hasValue);
-    EXPECT_EQ(0UL, valueProducer.mPastBuckets.size());
     EXPECT_EQ(true, valueProducer.mHasGlobalBase);
-
-    valueProducer.onConditionChanged(false, bucket2StartTimeNs + 1);
-
-    // has one slice
-    EXPECT_EQ(1UL, valueProducer.mCurrentSlicedBucket.size());
-    EXPECT_EQ(false, curInterval.hasValue);
-    EXPECT_EQ(false, curInterval.hasBase);
-    EXPECT_EQ(false, valueProducer.mHasGlobalBase);
 }
 
 TEST(ValueMetricProducerTest, TestInvalidBucketWhenOneConditionFailed) {
diff --git a/core/java/android/content/Intent.java b/core/java/android/content/Intent.java
index a3021f3..d781a96 100644
--- a/core/java/android/content/Intent.java
+++ b/core/java/android/content/Intent.java
@@ -817,28 +817,6 @@
             = "android.intent.action.SHOW_APP_INFO";
 
     /**
-     * Activity Action: Start an activity to show the app's detailed usage information for
-     * permission protected data.
-     *
-     * The Intent contains an extra {@link #EXTRA_PERMISSION_USAGE_PERMISSIONS} that is of
-     * type {@code String[]} and contains the specific permissions to show information for.
-     *
-     * Apps should handle this intent if they want to provide more information about permission
-     * usage to users beyond the information provided in the manifest.
-     */
-    @SdkConstant(SdkConstantType.ACTIVITY_INTENT_ACTION)
-    public static final String ACTION_PERMISSION_USAGE_DETAILS =
-            "android.intent.action.PERMISSION_USAGE_DETAILS";
-
-    /**
-     * The name of the extra used to contain the permissions in
-     * {@link #ACTION_PERMISSION_USAGE_DETAILS}.
-     * @see #ACTION_PERMISSION_USAGE_DETAILS
-     */
-    public static final String EXTRA_PERMISSION_USAGE_PERMISSIONS =
-            "android.intent.extra.PERMISSION_USAGE_PERMISSIONS";
-
-    /**
      * Represents a shortcut/live folder icon resource.
      *
      * @see Intent#ACTION_CREATE_SHORTCUT
diff --git a/core/java/android/content/pm/PackageInfo.java b/core/java/android/content/pm/PackageInfo.java
index 6d22277..27a5b39 100644
--- a/core/java/android/content/pm/PackageInfo.java
+++ b/core/java/android/content/pm/PackageInfo.java
@@ -204,10 +204,7 @@
      * {@link PackageManager#GET_PERMISSIONS} was set.  This list includes
      * all permissions requested, even those that were not granted or known
      * by the system at install time.
-     *
-     * @deprecated Use {@link #usesPermissions}
      */
-    @Deprecated
     public String[] requestedPermissions;
 
     /**
@@ -217,23 +214,10 @@
      * {@link PackageManager#GET_PERMISSIONS} was set.  Each value matches
      * the corresponding entry in {@link #requestedPermissions}, and will have
      * the flag {@link #REQUESTED_PERMISSION_GRANTED} set as appropriate.
-     *
-     * @deprecated Use {@link #usesPermissions}
      */
-    @Deprecated
     public int[] requestedPermissionsFlags;
 
     /**
-     * Array of all {@link android.R.styleable#AndroidManifestUsesPermission
-     * &lt;uses-permission&gt;} tags included under &lt;manifest&gt;,
-     * or null if there were none.  This is only filled in if the flag
-     * {@link PackageManager#GET_PERMISSIONS} was set.  This list includes
-     * all permissions requested, even those that were not granted or known
-     * by the system at install time.
-     */
-    public UsesPermissionInfo[] usesPermissions;
-
-    /**
      * Flag for {@link #requestedPermissionsFlags}: the requested permission
      * is required for the application to run; the user can not optionally
      * disable it.  Currently all permissions are required.
@@ -480,7 +464,6 @@
         dest.writeTypedArray(permissions, parcelableFlags);
         dest.writeStringArray(requestedPermissions);
         dest.writeIntArray(requestedPermissionsFlags);
-        dest.writeTypedArray(usesPermissions, parcelableFlags);
         dest.writeTypedArray(signatures, parcelableFlags);
         dest.writeTypedArray(configPreferences, parcelableFlags);
         dest.writeTypedArray(reqFeatures, parcelableFlags);
@@ -545,7 +528,6 @@
         permissions = source.createTypedArray(PermissionInfo.CREATOR);
         requestedPermissions = source.createStringArray();
         requestedPermissionsFlags = source.createIntArray();
-        usesPermissions = source.createTypedArray(UsesPermissionInfo.CREATOR);
         signatures = source.createTypedArray(Signature.CREATOR);
         configPreferences = source.createTypedArray(ConfigurationInfo.CREATOR);
         reqFeatures = source.createTypedArray(FeatureInfo.CREATOR);
diff --git a/core/java/android/content/pm/PackageParser.java b/core/java/android/content/pm/PackageParser.java
index 81ed110..5020a94 100644
--- a/core/java/android/content/pm/PackageParser.java
+++ b/core/java/android/content/pm/PackageParser.java
@@ -791,23 +791,18 @@
                     pi.permissions[i] = generatePermissionInfo(p.permissions.get(i), flags);
                 }
             }
-            N = p.usesPermissionInfos.size();
+            N = p.requestedPermissions.size();
             if (N > 0) {
                 pi.requestedPermissions = new String[N];
                 pi.requestedPermissionsFlags = new int[N];
-                pi.usesPermissions = new UsesPermissionInfo[N];
                 for (int i=0; i<N; i++) {
-                    UsesPermissionInfo info = p.usesPermissionInfos.get(i);
-                    final String perm = info.getPermission();
+                    final String perm = p.requestedPermissions.get(i);
                     pi.requestedPermissions[i] = perm;
-                    int permissionFlags = 0;
                     // The notion of required permissions is deprecated but for compatibility.
-                    permissionFlags |= PackageInfo.REQUESTED_PERMISSION_REQUIRED;
+                    pi.requestedPermissionsFlags[i] |= PackageInfo.REQUESTED_PERMISSION_REQUIRED;
                     if (grantedPermissions != null && grantedPermissions.contains(perm)) {
-                        permissionFlags |= PackageInfo.REQUESTED_PERMISSION_GRANTED;
+                        pi.requestedPermissionsFlags[i] |= PackageInfo.REQUESTED_PERMISSION_GRANTED;
                     }
-                    pi.requestedPermissionsFlags[i] = permissionFlags;
-                    pi.usesPermissions[i] = new UsesPermissionInfo(info, permissionFlags);
                 }
             }
         }
@@ -2175,12 +2170,12 @@
                     return null;
                 }
             } else if (tagName.equals(TAG_USES_PERMISSION)) {
-                if (!parseUsesPermission(pkg, res, parser, outError)) {
+                if (!parseUsesPermission(pkg, res, parser)) {
                     return null;
                 }
             } else if (tagName.equals(TAG_USES_PERMISSION_SDK_M)
                     || tagName.equals(TAG_USES_PERMISSION_SDK_23)) {
-                if (!parseUsesPermission(pkg, res, parser, outError)) {
+                if (!parseUsesPermission(pkg, res, parser)) {
                     return null;
                 }
             } else if (tagName.equals(TAG_USES_CONFIGURATION)) {
@@ -2498,7 +2493,7 @@
                     newPermsMsg.append(' ');
                 }
                 newPermsMsg.append(npi.name);
-                addRequestedPermission(pkg, npi.name);
+                pkg.requestedPermissions.add(npi.name);
                 pkg.implicitPermissions.add(npi.name);
             }
         }
@@ -2519,7 +2514,7 @@
             for (int in = 0; in < newPerms.size(); in++) {
                 final String perm = newPerms.get(in);
                 if (!pkg.requestedPermissions.contains(perm)) {
-                    addRequestedPermission(pkg, perm);
+                    pkg.requestedPermissions.add(perm);
                     pkg.implicitPermissions.add(perm);
                 }
             }
@@ -2599,13 +2594,13 @@
             }
         } else {
             if (FORCE_AUDIO_PACKAGES.contains(pkg.packageName)) {
-                addRequestedPermission(pkg, android.Manifest.permission.READ_MEDIA_AUDIO);
+                pkg.requestedPermissions.add(android.Manifest.permission.READ_MEDIA_AUDIO);
             }
             if (FORCE_VIDEO_PACKAGES.contains(pkg.packageName)) {
-                addRequestedPermission(pkg, android.Manifest.permission.READ_MEDIA_VIDEO);
+                pkg.requestedPermissions.add(android.Manifest.permission.READ_MEDIA_VIDEO);
             }
             if (FORCE_IMAGES_PACKAGES.contains(pkg.packageName)) {
-                addRequestedPermission(pkg, android.Manifest.permission.READ_MEDIA_IMAGES);
+                pkg.requestedPermissions.add(android.Manifest.permission.READ_MEDIA_IMAGES);
             }
         }
 
@@ -2645,12 +2640,6 @@
     }
 
     /**
-     * Helper method for adding a requested permission to a package outside of a uses-permission.
-     */
-    private void addRequestedPermission(Package pkg, String permission) {
-        pkg.requestedPermissions.add(permission);
-        pkg.usesPermissionInfos.add(new UsesPermissionInfo(permission));
-    }
 
     /**
      * Matches a given {@code targetCode} against a set of release codeNames. Target codes can
@@ -2987,8 +2976,8 @@
         return certSha256Digests;
     }
 
-    private boolean parseUsesPermission(Package pkg, Resources res, XmlResourceParser parser,
-            String[] outError) throws XmlPullParserException, IOException {
+    private boolean parseUsesPermission(Package pkg, Resources res, XmlResourceParser parser)
+            throws XmlPullParserException, IOException {
         TypedArray sa = res.obtainAttributes(parser,
                 com.android.internal.R.styleable.AndroidManifestUsesPermission);
 
@@ -3012,44 +3001,6 @@
         final String requiredNotfeature = sa.getNonConfigurationString(
                 com.android.internal.R.styleable.AndroidManifestUsesPermission_requiredNotFeature, 0);
 
-        int dataSentOffDevice = sa.getInt(
-                com.android.internal.R.styleable.AndroidManifestUsesPermission_dataSentOffDevice, 0);
-
-        int dataSharedWithThirdParty = sa.getInt(
-                com.android.internal.R.styleable.AndroidManifestUsesPermission_dataSharedWithThirdParty, 0);
-
-        int dataUsedForMonetization = sa.getInt(
-                com.android.internal.R.styleable.AndroidManifestUsesPermission_dataUsedForMonetization, 0);
-
-        int retentionWeeks = -1;
-        int retention;
-
-        String rawRetention = sa.getString(
-                com.android.internal.R.styleable.AndroidManifestUsesPermission_dataRetentionTime);
-
-        if (rawRetention == null) {
-            retention = UsesPermissionInfo.RETENTION_UNDEFINED;
-        } else if ("notRetained".equals(rawRetention)) {
-            retention = UsesPermissionInfo.RETENTION_NOT_RETAINED;
-        } else if ("userSelected".equals(rawRetention)) {
-            retention = UsesPermissionInfo.RETENTION_USER_SELECTED;
-        } else if ("unlimited".equals(rawRetention)) {
-            retention = UsesPermissionInfo.RETENTION_UNLIMITED;
-        } else {
-            // A number of weeks was specified
-            retention = UsesPermissionInfo.RETENTION_SPECIFIED;
-            retentionWeeks = sa.getInt(
-                com.android.internal.R.styleable.AndroidManifestUsesPermission_dataRetentionTime,
-                -1);
-
-            if (retentionWeeks < 0) {
-                outError[0] = "Bad value provided for dataRetentionTime.";
-                mParseError = PackageManager.INSTALL_PARSE_FAILED_MANIFEST_MALFORMED;
-                XmlUtils.skipCurrentTag(parser);
-                sa.recycle();
-                return false;
-            }
-        }
         sa.recycle();
 
         XmlUtils.skipCurrentTag(parser);
@@ -3082,10 +3033,6 @@
                     + parser.getPositionDescription());
         }
 
-        UsesPermissionInfo info = new UsesPermissionInfo(name, dataSentOffDevice,
-                dataSharedWithThirdParty, dataUsedForMonetization, retention, retentionWeeks);
-        pkg.usesPermissionInfos.add(info);
-
         return true;
     }
 
@@ -3420,10 +3367,6 @@
         perm.info.flags = sa.getInt(
                 com.android.internal.R.styleable.AndroidManifestPermission_permissionFlags, 0);
 
-        perm.info.usageInfoRequired = sa.getInt(
-                com.android.internal.R.styleable.AndroidManifestPermission_usageInfoRequired, 0)
-                != 0;
-
         sa.recycle();
 
         if (perm.info.protectionLevel == -1) {
@@ -6625,9 +6568,6 @@
         @UnsupportedAppUsage
         public final ArrayList<String> requestedPermissions = new ArrayList<String>();
 
-        public final ArrayList<UsesPermissionInfo> usesPermissionInfos =
-                new ArrayList<>();
-
         /** Permissions requested but not in the manifest. */
         public final ArrayList<String> implicitPermissions = new ArrayList<>();
 
@@ -7159,7 +7099,6 @@
 
             dest.readStringList(requestedPermissions);
             internStringArrayList(requestedPermissions);
-            dest.readParcelableList(usesPermissionInfos, boot);
             dest.readStringList(implicitPermissions);
             internStringArrayList(implicitPermissions);
             protectedBroadcasts = dest.createStringArrayList();
@@ -7327,7 +7266,6 @@
             dest.writeParcelableList(instrumentation, flags);
 
             dest.writeStringList(requestedPermissions);
-            dest.writeParcelableList(usesPermissionInfos, flags);
             dest.writeStringList(implicitPermissions);
             dest.writeStringList(protectedBroadcasts);
 
diff --git a/core/java/android/content/pm/PermissionInfo.java b/core/java/android/content/pm/PermissionInfo.java
index fb63e0d..e245234 100644
--- a/core/java/android/content/pm/PermissionInfo.java
+++ b/core/java/android/content/pm/PermissionInfo.java
@@ -20,7 +20,6 @@
 import android.annotation.SystemApi;
 import android.annotation.TestApi;
 import android.annotation.UnsupportedAppUsage;
-import android.os.Build;
 import android.os.Parcel;
 import android.os.Parcelable;
 import android.text.TextUtils;
@@ -368,12 +367,6 @@
      */
     public CharSequence nonLocalizedDescription;
 
-    /**
-     * If {@code true} an application targeting {@link Build.VERSION_CODES#Q} <em>must</em>
-     * include permission data usage information in order to be able to be granted this permission.
-     */
-    public boolean usageInfoRequired;
-
     /** @hide */
     public static int fixProtectionLevel(int level) {
         if (level == PROTECTION_SIGNATURE_OR_SYSTEM) {
@@ -475,7 +468,6 @@
         descriptionRes = orig.descriptionRes;
         requestRes = orig.requestRes;
         nonLocalizedDescription = orig.nonLocalizedDescription;
-        usageInfoRequired = orig.usageInfoRequired;
     }
 
     /**
@@ -540,7 +532,6 @@
         dest.writeInt(descriptionRes);
         dest.writeInt(requestRes);
         TextUtils.writeToParcel(nonLocalizedDescription, dest, parcelableFlags);
-        dest.writeInt(usageInfoRequired ? 1 : 0);
     }
 
     /** @hide */
@@ -581,6 +572,5 @@
         descriptionRes = source.readInt();
         requestRes = source.readInt();
         nonLocalizedDescription = TextUtils.CHAR_SEQUENCE_CREATOR.createFromParcel(source);
-        usageInfoRequired = source.readInt() != 0;
     }
 }
diff --git a/core/java/android/content/pm/UsesPermissionInfo.java b/core/java/android/content/pm/UsesPermissionInfo.java
deleted file mode 100644
index d08548f..0000000
--- a/core/java/android/content/pm/UsesPermissionInfo.java
+++ /dev/null
@@ -1,275 +0,0 @@
-/*
- * Copyright (C) 2018 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.content.pm;
-
-import android.annotation.IntDef;
-import android.os.Parcel;
-import android.os.Parcelable;
-
-import java.lang.annotation.RetentionPolicy;
-/**
- * Information you can retrive about a particular application requested permission. This
- * corresponds to information collected from the AndroidManifest.xml's &lt;uses-permission&gt;
- * tags.
- */
-public final class UsesPermissionInfo extends PackageItemInfo implements Parcelable {
-
-    /**
-     * Flag for {@link #getFlags()}: the requested permission is currently granted to the
-     * application.
-     */
-    public static final int FLAG_REQUESTED_PERMISSION_GRANTED = 1 << 1;
-
-    /** @hide */
-    @IntDef(flag = true, prefix = {"FLAG_"}, value = {FLAG_REQUESTED_PERMISSION_GRANTED})
-    @java.lang.annotation.Retention(RetentionPolicy.SOURCE)
-    public @interface Flags {}
-
-    /** An unset value for {@link #getDataSentOffDevice()},
-     * {@link #getDataSharedWithThirdParty()}, and {@link #getDataUsedForMonetization()}
-     */
-    public static final int USAGE_UNDEFINED = 0;
-
-    /**
-     * A yes value for {@link #getDataSentOffDevice()}, {@link #getDataSharedWithThirdParty()},
-     * and {@link #getDataUsedForMonetization()} corresponding to the <code>yes</code> value of
-     * {@link android.R.attr#dataSentOffDevice}, {@link android.R.attr#dataSharedWithThirdParty},
-     * and {@link android.R.attr#dataUsedForMonetization} attributes.
-     */
-    public static final int USAGE_YES = 1;
-
-    /**
-     * A user triggered only value for {@link #getDataSentOffDevice()},
-     * {@link #getDataSharedWithThirdParty()}, and {@link #getDataUsedForMonetization()}
-     * corresponding to the <code>userTriggered</code> value of
-     * {@link android.R.attr#dataSentOffDevice}, {@link android.R.attr#dataSharedWithThirdParty},
-     * and {@link android.R.attr#dataUsedForMonetization} attributes.
-     */
-    public static final int USAGE_USER_TRIGGERED = 2;
-
-    /**
-     * A no value for {@link #getDataSentOffDevice()}, {@link #getDataSharedWithThirdParty()},
-     * and {@link #getDataUsedForMonetization()} corresponding to the <code>no</code> value of
-     * {@link android.R.attr#dataSentOffDevice}, {@link android.R.attr#dataSharedWithThirdParty},
-     * and {@link android.R.attr#dataUsedForMonetization} attributes.
-     */
-    public static final int USAGE_NO = 3;
-
-    /** @hide */
-    @IntDef(prefix = {"USAGE_"}, value = {
-        USAGE_UNDEFINED,
-        USAGE_YES,
-        USAGE_USER_TRIGGERED,
-        USAGE_NO})
-    @java.lang.annotation.Retention(RetentionPolicy.SOURCE)
-    public @interface Usage {}
-
-    /**
-     * An unset value for {@link #getDataRetention}.
-     */
-    public static final int RETENTION_UNDEFINED = 0;
-
-    /**
-     * A data not retained value for {@link #getDataRetention()} corresponding to the
-     * <code>notRetained</code> value of {@link android.R.attr#dataRetentionTime}.
-     */
-    public static final int RETENTION_NOT_RETAINED = 1;
-
-    /**
-     * A user selected value for {@link #getDataRetention()} corresponding to the
-     * <code>userSelected</code> value of {@link android.R.attr#dataRetentionTime}.
-     */
-    public static final int RETENTION_USER_SELECTED = 2;
-
-    /**
-     * An unlimited value for {@link #getDataRetention()} corresponding to the
-     * <code>unlimited</code> value of {@link android.R.attr#dataRetentionTime}.
-     */
-    public static final int RETENTION_UNLIMITED = 3;
-
-    /**
-     * A specified value for {@link #getDataRetention()} corresponding to providing the number of
-     * weeks data is retained in {@link android.R.attr#dataRetentionTime}. The number of weeks
-     * is available in {@link #getDataRetentionWeeks()}.
-     */
-    public static final int RETENTION_SPECIFIED = 4;
-
-    /** @hide */
-    @IntDef(prefix = {"RETENTION_"}, value = {
-        RETENTION_UNDEFINED,
-        RETENTION_NOT_RETAINED,
-        RETENTION_USER_SELECTED,
-        RETENTION_UNLIMITED,
-        RETENTION_SPECIFIED})
-    @java.lang.annotation.Retention(RetentionPolicy.SOURCE)
-    public @interface Retention {}
-
-    private final String mPermission;
-    private final @Flags int mFlags;
-    private final @Usage int mDataSentOffDevice;
-    private final @Usage int mDataSharedWithThirdParty;
-    private final @Usage int mDataUsedForMonetization;
-    private final @Retention int mDataRetention;
-    private final int mDataRetentionWeeks;
-
-    /** @hide */
-    public UsesPermissionInfo(String permission) {
-        mPermission = permission;
-        mDataSentOffDevice = USAGE_UNDEFINED;
-        mDataSharedWithThirdParty = USAGE_UNDEFINED;
-        mDataUsedForMonetization = USAGE_UNDEFINED;
-        mDataRetention = RETENTION_UNDEFINED;
-        mDataRetentionWeeks = -1;
-        mFlags = 0;
-    }
-
-    /** @hide */
-    public UsesPermissionInfo(String permission,
-            @Usage int dataSentOffDevice, @Usage int dataSharedWithThirdParty,
-            @Usage int dataUsedForMonetization, @Retention int dataRetention,
-            int dataRetentionWeeks) {
-        mPermission = permission;
-        mDataSentOffDevice = dataSentOffDevice;
-        mDataSharedWithThirdParty = dataSharedWithThirdParty;
-        mDataUsedForMonetization = dataUsedForMonetization;
-        mDataRetention = dataRetention;
-        mDataRetentionWeeks = dataRetentionWeeks;
-        mFlags = 0;
-    }
-
-    /** @hide */
-    public UsesPermissionInfo(UsesPermissionInfo orig) {
-        this(orig, orig.mFlags);
-    }
-
-    /** @hide */
-    public UsesPermissionInfo(UsesPermissionInfo orig, int flags) {
-        super(orig);
-        mPermission = orig.mPermission;
-        mFlags = flags;
-        mDataSentOffDevice = orig.mDataSentOffDevice;
-        mDataSharedWithThirdParty = orig.mDataSharedWithThirdParty;
-        mDataUsedForMonetization = orig.mDataUsedForMonetization;
-        mDataRetention = orig.mDataRetention;
-        mDataRetentionWeeks = orig.mDataRetentionWeeks;
-    }
-
-    /**
-     * The name of the requested permission.
-     */
-    public String getPermission() {
-        return mPermission;
-    }
-
-    public @Flags int getFlags() {
-        return mFlags;
-    }
-
-    /**
-     * If the application sends the data guarded by this permission off the device.
-     *
-     * See {@link android.R.attr#dataSentOffDevice}
-     */
-    public @Usage int getDataSentOffDevice() {
-        return mDataSentOffDevice;
-    }
-
-    /**
-     * If the application or its services shares the data guarded by this permission with third
-     * parties.
-     *
-     * See {@link android.R.attr#dataSharedWithThirdParty}
-     */
-    public @Usage int getDataSharedWithThirdParty() {
-        return mDataSharedWithThirdParty;
-    }
-
-    /**
-     * If the application or its services use the data guarded by this permission for monetization
-     * purposes.
-     *
-     * See {@link android.R.attr#dataUsedForMonetization}
-     */
-    public @Usage int getDataUsedForMonetization() {
-        return mDataUsedForMonetization;
-    }
-
-    /**
-     * How long the application or its services store the data guarded by this permission.
-     * If set to {@link #RETENTION_SPECIFIED} {@link #getDataRetentionWeeks()} will contain the
-     * number of weeks the data is stored.
-     *
-     * See {@link android.R.attr#dataRetentionTime}
-     */
-    public @Retention int getDataRetention() {
-        return mDataRetention;
-    }
-
-    /**
-     * If {@link #getDataRetention()} is {@link #RETENTION_SPECIFIED} the number of weeks the
-     * application or its services store data guarded by this permission.
-     *
-     * @throws IllegalStateException if {@link #getDataRetention} is not
-     * {@link #RETENTION_SPECIFIED}.
-     */
-    public int getDataRetentionWeeks() {
-        if (mDataRetention != RETENTION_SPECIFIED) {
-            throw new IllegalStateException("Data retention weeks not specified");
-        }
-        return mDataRetentionWeeks;
-    }
-
-    @Override
-    public int describeContents() {
-        return 0;
-    }
-
-    @Override
-    public void writeToParcel(Parcel dest, int flags) {
-        super.writeToParcel(dest, flags);
-        dest.writeString(mPermission);
-        dest.writeInt(mFlags);
-        dest.writeInt(mDataSentOffDevice);
-        dest.writeInt(mDataSharedWithThirdParty);
-        dest.writeInt(mDataUsedForMonetization);
-        dest.writeInt(mDataRetention);
-        dest.writeInt(mDataRetentionWeeks);
-    }
-
-    private UsesPermissionInfo(Parcel source) {
-        super(source);
-        mPermission = source.readString();
-        mFlags = source.readInt();
-        mDataSentOffDevice = source.readInt();
-        mDataSharedWithThirdParty = source.readInt();
-        mDataUsedForMonetization = source.readInt();
-        mDataRetention = source.readInt();
-        mDataRetentionWeeks = source.readInt();
-    }
-
-    public static final Creator<UsesPermissionInfo> CREATOR =
-            new Creator<UsesPermissionInfo>() {
-                @Override
-                public UsesPermissionInfo createFromParcel(Parcel source) {
-                    return new UsesPermissionInfo(source);
-                }
-                @Override
-                public UsesPermissionInfo[] newArray(int size) {
-                    return new UsesPermissionInfo[size];
-                }
-            };
-}
diff --git a/core/java/android/hardware/display/NightDisplayListener.java b/core/java/android/hardware/display/NightDisplayListener.java
new file mode 100644
index 0000000..468f833
--- /dev/null
+++ b/core/java/android/hardware/display/NightDisplayListener.java
@@ -0,0 +1,153 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.display;
+
+import android.annotation.NonNull;
+import android.annotation.UserIdInt;
+import android.app.ActivityManager;
+import android.content.ContentResolver;
+import android.content.Context;
+import android.database.ContentObserver;
+import android.net.Uri;
+import android.os.Handler;
+import android.os.Looper;
+import android.provider.Settings.Secure;
+
+import java.time.LocalTime;
+
+/**
+ * @hide
+ */
+public class NightDisplayListener {
+
+    private final Context mContext;
+    private final int mUserId;
+    private final ColorDisplayManager mManager;
+
+    private ContentObserver mContentObserver;
+    private Callback mCallback;
+
+    public NightDisplayListener(@NonNull Context context) {
+        this(context, ActivityManager.getCurrentUser());
+    }
+
+    public NightDisplayListener(@NonNull Context context, @UserIdInt int userId) {
+        mContext = context.getApplicationContext();
+        mUserId = userId;
+        mManager = mContext.getSystemService(ColorDisplayManager.class);
+    }
+
+    /**
+     * Register a callback to be invoked whenever the Night display settings are changed.
+     */
+    public void setCallback(Callback callback) {
+        final Callback oldCallback = mCallback;
+        if (oldCallback != callback) {
+            mCallback = callback;
+
+            if (mContentObserver == null) {
+                mContentObserver = new ContentObserver(new Handler(Looper.getMainLooper())) {
+                    @Override
+                    public void onChange(boolean selfChange, Uri uri) {
+                        super.onChange(selfChange, uri);
+                        onSettingChanged(uri);
+                    }
+                };
+            }
+
+            if (callback == null) {
+                // Stop listening for changes now that there IS NOT a callback.
+                mContext.getContentResolver().unregisterContentObserver(mContentObserver);
+            } else if (oldCallback == null) {
+                // Start listening for changes now that there IS a callback.
+                final ContentResolver cr = mContext.getContentResolver();
+                cr.registerContentObserver(Secure.getUriFor(Secure.NIGHT_DISPLAY_ACTIVATED),
+                        false /* notifyForDescendants */, mContentObserver, mUserId);
+                cr.registerContentObserver(Secure.getUriFor(Secure.NIGHT_DISPLAY_AUTO_MODE),
+                        false /* notifyForDescendants */, mContentObserver, mUserId);
+                cr.registerContentObserver(Secure.getUriFor(Secure.NIGHT_DISPLAY_CUSTOM_START_TIME),
+                        false /* notifyForDescendants */, mContentObserver, mUserId);
+                cr.registerContentObserver(Secure.getUriFor(Secure.NIGHT_DISPLAY_CUSTOM_END_TIME),
+                        false /* notifyForDescendants */, mContentObserver, mUserId);
+                cr.registerContentObserver(Secure.getUriFor(Secure.NIGHT_DISPLAY_COLOR_TEMPERATURE),
+                        false /* notifyForDescendants */, mContentObserver, mUserId);
+            }
+        }
+    }
+
+    private void onSettingChanged(Uri uri) {
+        final String setting = uri == null ? null : uri.getLastPathSegment();
+        if (setting == null || mCallback == null) {
+            return;
+        }
+
+        switch (setting) {
+            case Secure.NIGHT_DISPLAY_ACTIVATED:
+                mCallback.onActivated(mManager.isNightDisplayActivated());
+                break;
+            case Secure.NIGHT_DISPLAY_AUTO_MODE:
+                mCallback.onAutoModeChanged(mManager.getNightDisplayAutoMode());
+                break;
+            case Secure.NIGHT_DISPLAY_CUSTOM_START_TIME:
+                mCallback.onCustomStartTimeChanged(mManager.getNightDisplayCustomStartTime());
+                break;
+            case Secure.NIGHT_DISPLAY_CUSTOM_END_TIME:
+                mCallback.onCustomEndTimeChanged(mManager.getNightDisplayCustomEndTime());
+                break;
+            case Secure.NIGHT_DISPLAY_COLOR_TEMPERATURE:
+                mCallback.onColorTemperatureChanged(mManager.getNightDisplayColorTemperature());
+                break;
+        }
+    }
+
+    /**
+     * Callback invoked whenever the Night display settings are changed.
+     */
+    public interface Callback {
+        /**
+         * Callback invoked when the activated state changes.
+         *
+         * @param activated {@code true} if Night display is activated
+         */
+        default void onActivated(boolean activated) {}
+        /**
+         * Callback invoked when the auto mode changes.
+         *
+         * @param autoMode the auto mode to use
+         */
+        default void onAutoModeChanged(int autoMode) {}
+        /**
+         * Callback invoked when the time to automatically activate Night display changes.
+         *
+         * @param startTime the local time to automatically activate Night display
+         */
+        default void onCustomStartTimeChanged(LocalTime startTime) {}
+        /**
+         * Callback invoked when the time to automatically deactivate Night display changes.
+         *
+         * @param endTime the local time to automatically deactivate Night display
+         */
+        default void onCustomEndTimeChanged(LocalTime endTime) {}
+
+        /**
+         * Callback invoked when the color temperature changes.
+         *
+         * @param colorTemperature the color temperature to tint the screen
+         */
+        default void onColorTemperatureChanged(int colorTemperature) {}
+    }
+}
diff --git a/core/java/com/android/internal/os/ZygoteConnection.java b/core/java/com/android/internal/os/ZygoteConnection.java
index 9ba56b8..4ac7f50 100644
--- a/core/java/com/android/internal/os/ZygoteConnection.java
+++ b/core/java/com/android/internal/os/ZygoteConnection.java
@@ -334,9 +334,14 @@
         }
     }
 
-    private class HiddenApiUsageLogger implements VMRuntime.HiddenApiUsageLogger {
+    private static class HiddenApiUsageLogger implements VMRuntime.HiddenApiUsageLogger {
 
         private final MetricsLogger mMetricsLogger = new MetricsLogger();
+        private static HiddenApiUsageLogger sInstance = new HiddenApiUsageLogger();
+
+        public static HiddenApiUsageLogger getInstance() {
+            return HiddenApiUsageLogger.sInstance;
+        }
 
         public void hiddenApiUsed(String packageName, String signature,
                 int accessMethod, boolean accessDenied) {
@@ -370,7 +375,7 @@
     private void handleHiddenApiAccessLogSampleRate(int samplingRate) {
         try {
             ZygoteInit.setHiddenApiAccessLogSampleRate(samplingRate);
-            ZygoteInit.setHiddenApiUsageLogger(new HiddenApiUsageLogger());
+            ZygoteInit.setHiddenApiUsageLogger(HiddenApiUsageLogger.getInstance());
             mSocketOutStream.writeInt(0);
         } catch (IOException ioe) {
             throw new IllegalStateException("Error writing to command socket", ioe);
diff --git a/core/res/AndroidManifest.xml b/core/res/AndroidManifest.xml
index 60b04cf..07dd26e 100644
--- a/core/res/AndroidManifest.xml
+++ b/core/res/AndroidManifest.xml
@@ -662,8 +662,7 @@
         android:permissionGroup="android.permission-group.UNDEFINED"
         android:label="@string/permlab_readContacts"
         android:description="@string/permdesc_readContacts"
-        android:protectionLevel="dangerous"
-        android:usageInfoRequired="true" />
+        android:protectionLevel="dangerous" />
 
     <!-- Allows an application to write the user's contacts data.
          <p>Protection level: dangerous
@@ -694,8 +693,7 @@
         android:permissionGroup="android.permission-group.UNDEFINED"
         android:label="@string/permlab_readCalendar"
         android:description="@string/permdesc_readCalendar"
-        android:protectionLevel="dangerous"
-        android:usageInfoRequired="true" />
+        android:protectionLevel="dangerous" />
 
     <!-- Allows an application to write the user's calendar data.
          <p>Protection level: dangerous
@@ -736,8 +734,7 @@
         android:permissionGroup="android.permission-group.UNDEFINED"
         android:label="@string/permlab_receiveSms"
         android:description="@string/permdesc_receiveSms"
-        android:protectionLevel="dangerous"
-        android:usageInfoRequired="true" />
+        android:protectionLevel="dangerous" />
 
     <!-- Allows an application to read SMS messages.
          <p>Protection level: dangerous
@@ -746,8 +743,7 @@
         android:permissionGroup="android.permission-group.UNDEFINED"
         android:label="@string/permlab_readSms"
         android:description="@string/permdesc_readSms"
-        android:protectionLevel="dangerous"
-        android:usageInfoRequired="true" />
+        android:protectionLevel="dangerous" />
 
     <!-- Allows an application to receive WAP push messages.
          <p>Protection level: dangerous
@@ -756,8 +752,7 @@
         android:permissionGroup="android.permission-group.UNDEFINED"
         android:label="@string/permlab_receiveWapPush"
         android:description="@string/permdesc_receiveWapPush"
-        android:protectionLevel="dangerous"
-        android:usageInfoRequired="true" />
+        android:protectionLevel="dangerous" />
 
     <!-- Allows an application to monitor incoming MMS messages.
         <p>Protection level: dangerous
@@ -766,8 +761,7 @@
         android:permissionGroup="android.permission-group.UNDEFINED"
         android:label="@string/permlab_receiveMms"
         android:description="@string/permdesc_receiveMms"
-        android:protectionLevel="dangerous"
-        android:usageInfoRequired="true" />
+        android:protectionLevel="dangerous" />
 
     <!-- @SystemApi @TestApi Allows an application to read previously received cell broadcast
          messages and to register a content observer to get notifications when
@@ -785,8 +779,7 @@
         android:permissionGroup="android.permission-group.UNDEFINED"
         android:label="@string/permlab_readCellBroadcasts"
         android:description="@string/permdesc_readCellBroadcasts"
-        android:protectionLevel="dangerous"
-        android:usageInfoRequired="true" />
+        android:protectionLevel="dangerous" />
 
     <!-- ====================================================================== -->
     <!-- Permissions for accessing external storage                             -->
@@ -867,8 +860,7 @@
         android:permissionGroup="android.permission-group.UNDEFINED"
         android:label="@string/permlab_audioRead"
         android:description="@string/permdesc_audioRead"
-        android:protectionLevel="dangerous"
-        android:usageInfoRequired="true" />
+        android:protectionLevel="dangerous" />
 
     <!-- Runtime permission controlling access to the user's shared visual media
          collection, including images and videos. -->
@@ -884,16 +876,14 @@
         android:permissionGroup="android.permission-group.UNDEFINED"
         android:label="@string/permlab_imagesRead"
         android:description="@string/permdesc_imagesRead"
-        android:protectionLevel="dangerous"
-        android:usageInfoRequired="true" />
+        android:protectionLevel="dangerous" />
 
     <!-- Allows an application to read the user's shared video collection. -->
     <permission android:name="android.permission.READ_MEDIA_VIDEO"
         android:permissionGroup="android.permission-group.UNDEFINED"
         android:label="@string/permlab_videoRead"
         android:description="@string/permdesc_videoRead"
-        android:protectionLevel="dangerous"
-        android:usageInfoRequired="true" />
+        android:protectionLevel="dangerous" />
 
     <!-- Allows an application to access any geographic locations persisted in the
          user's shared collection. -->
@@ -901,8 +891,7 @@
         android:permissionGroup="android.permission-group.UNDEFINED"
         android:label="@string/permlab_mediaLocation"
         android:description="@string/permdesc_mediaLocation"
-        android:protectionLevel="dangerous"
-        android:usageInfoRequired="true" />
+        android:protectionLevel="dangerous" />
 
     <!-- @hide @SystemApi @TestApi
          Allows an application to modify OBB files visible to other apps. -->
@@ -934,8 +923,7 @@
         android:label="@string/permlab_accessFineLocation"
         android:description="@string/permdesc_accessFineLocation"
         android:backgroundPermission="android.permission.ACCESS_BACKGROUND_LOCATION"
-        android:protectionLevel="dangerous|instant"
-        android:usageInfoRequired="true" />
+        android:protectionLevel="dangerous|instant" />
 
     <!-- Allows an app to access approximate location.
          Alternatively, you might want {@link #ACCESS_FINE_LOCATION}.
@@ -946,8 +934,7 @@
         android:label="@string/permlab_accessCoarseLocation"
         android:description="@string/permdesc_accessCoarseLocation"
         android:backgroundPermission="android.permission.ACCESS_BACKGROUND_LOCATION"
-        android:protectionLevel="dangerous|instant"
-        android:usageInfoRequired="true" />
+        android:protectionLevel="dangerous|instant" />
 
     <!-- Allows an app to access location in the background.  If you
          are requesting this, you should also request {@link #ACCESS_FINE_LOCATION}.
@@ -959,8 +946,7 @@
         android:permissionGroup="android.permission-group.UNDEFINED"
         android:label="@string/permlab_accessBackgroundLocation"
         android:description="@string/permdesc_accessBackgroundLocation"
-        android:protectionLevel="dangerous|instant"
-        android:usageInfoRequired="true" />
+        android:protectionLevel="dangerous|instant" />
 
     <!-- ====================================================================== -->
     <!-- Permissions for accessing the call log                                 -->
@@ -1001,8 +987,7 @@
         android:permissionGroup="android.permission-group.UNDEFINED"
         android:label="@string/permlab_readCallLog"
         android:description="@string/permdesc_readCallLog"
-        android:protectionLevel="dangerous"
-        android:usageInfoRequired="true" />
+        android:protectionLevel="dangerous" />
 
     <!-- Allows an application to write (but not read) the user's
          call log data.
@@ -1032,8 +1017,7 @@
         android:permissionGroup="android.permission-group.UNDEFINED"
         android:label="@string/permlab_processOutgoingCalls"
         android:description="@string/permdesc_processOutgoingCalls"
-        android:protectionLevel="dangerous"
-        android:usageInfoRequired="true" />
+        android:protectionLevel="dangerous" />
 
     <!-- ====================================================================== -->
     <!-- Permissions for accessing the device telephony                         -->
@@ -1065,8 +1049,7 @@
         android:permissionGroup="android.permission-group.UNDEFINED"
         android:label="@string/permlab_readPhoneState"
         android:description="@string/permdesc_readPhoneState"
-        android:protectionLevel="dangerous"
-        android:usageInfoRequired="true" />
+        android:protectionLevel="dangerous" />
 
     <!-- Allows read access to the device's phone number(s). This is a subset of the capabilities
          granted by {@link #READ_PHONE_STATE} but is exposed to instant applications.
@@ -1075,8 +1058,7 @@
         android:permissionGroup="android.permission-group.UNDEFINED"
         android:label="@string/permlab_readPhoneNumbers"
         android:description="@string/permdesc_readPhoneNumbers"
-        android:protectionLevel="dangerous|instant"
-        android:usageInfoRequired="true" />
+        android:protectionLevel="dangerous|instant" />
 
     <!-- Allows an application to initiate a phone call without going through
         the Dialer user interface for the user to confirm the call.
@@ -1178,8 +1160,7 @@
         android:permissionGroup="android.permission-group.UNDEFINED"
         android:label="@string/permlab_recordAudio"
         android:description="@string/permdesc_recordAudio"
-        android:protectionLevel="dangerous|instant"
-        android:usageInfoRequired="true" />
+        android:protectionLevel="dangerous|instant" />
 
     <!-- ====================================================================== -->
     <!-- Permissions for activity recognition                        -->
@@ -1202,8 +1183,7 @@
         android:permissionGroup="android.permission-group.UNDEFINED"
         android:label="@string/permlab_activityRecognition"
         android:description="@string/permdesc_activityRecognition"
-        android:protectionLevel="dangerous|instant"
-        android:usageInfoRequired="true" />
+        android:protectionLevel="dangerous|instant" />
 
     <!-- ====================================================================== -->
     <!-- Permissions for accessing the UCE Service                              -->
@@ -1252,8 +1232,7 @@
         android:permissionGroup="android.permission-group.UNDEFINED"
         android:label="@string/permlab_camera"
         android:description="@string/permdesc_camera"
-        android:protectionLevel="dangerous|instant"
-        android:usageInfoRequired="true" />
+        android:protectionLevel="dangerous|instant" />
 
 
     <!-- ====================================================================== -->
@@ -1277,8 +1256,7 @@
         android:permissionGroup="android.permission-group.UNDEFINED"
         android:label="@string/permlab_bodySensors"
         android:description="@string/permdesc_bodySensors"
-        android:protectionLevel="dangerous"
-        android:usageInfoRequired="true" />
+        android:protectionLevel="dangerous" />
 
     <!-- Allows an app to use fingerprint hardware.
          <p>Protection level: normal
@@ -1780,8 +1758,7 @@
         android:permissionGroup="android.permission-group.UNDEFINED"
         android:protectionLevel="dangerous"
         android:description="@string/permdesc_getAccounts"
-        android:label="@string/permlab_getAccounts"
-        android:usageInfoRequired="true" />
+        android:label="@string/permlab_getAccounts" />
     <uses-permission android:name="android.permission.GET_ACCOUNTS"/>
 
     <!-- Allows applications to call into AccountAuthenticators.
diff --git a/core/res/res/values/attrs.xml b/core/res/res/values/attrs.xml
index fa3a549..46e14b4 100644
--- a/core/res/res/values/attrs.xml
+++ b/core/res/res/values/attrs.xml
@@ -2426,6 +2426,8 @@
         </attr>
 
         <attr name="__removed3" />
+        <attr name="__removed4" />
+        <attr name="__removed5" />
 
         <!-- Describes the content of a view so that a autofill service can fill in the appropriate
              data. Multiple hints can be combined in a comma separated list or an array of strings
diff --git a/core/res/res/values/attrs_manifest.xml b/core/res/res/values/attrs_manifest.xml
index 881688b..53cae63 100644
--- a/core/res/res/values/attrs_manifest.xml
+++ b/core/res/res/values/attrs_manifest.xml
@@ -1689,10 +1689,6 @@
         <attr name="request" />
         <attr name="protectionLevel" />
         <attr name="permissionFlags" />
-        <!-- If {@code true} applications that target Q <em>must</em> specify the permission usage
-             attributes in their {@code uses-permission} elements or the permission will not be
-             granted. -->
-        <attr name="usageInfoRequired" format="boolean" />
     </declare-styleable>
 
     <!-- The <code>permission-group</code> tag declares a logical grouping of
@@ -1792,81 +1788,6 @@
         requested.  If it does support the feature, it will be as if the manifest didn't
         request it at all. -->
         <attr name="requiredNotFeature" format="string" />
-
-        <!-- Specify if the app uploads data, or derived data, guarded by this permission.
-
-             If the permission is defined with {@link android.R.attr#usageInfoRequired}
-             {@code true} this <em>must</em> be specified by apps that target Android Q or the
-             permission will not be granted, it will be as if the manifest didn't request it at all.
-        -->
-        <attr name="dataSentOffDevice">
-          <!-- The application may send data, or derived data, guarded by this permission off of the
-               device. -->
-          <enum name="yes" value="1" />
-          <!-- The application may send data, or derived data, guarded by this permission off of the
-               device, however it will only do so when explicitly triggered by a user action. -->
-          <enum name="userTriggered" value="2" />
-          <!-- The application does not send data, or derived data, guarded by this permission off
-               of the device. -->
-          <enum name="no" value="3" />
-        </attr>
-
-        <!-- Specify if the application or its related off-device services provide data,
-             or derived data, guarded by this permission to third parties outside of the developer's
-             organization that do not qualify as data processors.
-
-             If the permission is defined with {@link android.R.attr#usageInfoRequired}
-             {@code true} this <em>must</em> be specified by apps that target Android Q or the
-             permission will not be granted, it will be as if the manifest didn't request it at all.
-             -->
-        <attr name="dataSharedWithThirdParty">
-          <!-- The application or its services may provide data, or derived data, guarded by this
-               permission to third party organizations. -->
-          <enum name="yes" value="1" />
-          <!-- The application or its services may provide data, or derived data, guarded by this
-               permission to third party organizations, however it will only do so when explicitly
-               triggered by a user action. -->
-          <enum name="userTriggered" value="2" />
-          <!-- The application or its services does not provide data, or derived data, guarded by
-               this permission to third party organizations. -->
-          <enum name="no" value="3" />
-        </attr>
-
-        <!-- Specify if the application or its related off-device services use data,
-             or derived data, guarded by this permission for monetization purposes.
-
-             For example, if the data is sold to another party or used for targeting advertisements
-             this must be set to {@code yes}.
-
-             If the permission is defined with {@link android.R.attr#usageInfoRequired}
-             {@code true} this <em>must</em> be specified by apps that target Android Q or the
-             permission will not be granted, it will be as if the manifest didn't request it at all.
-             -->
-        <attr name="dataUsedForMonetization">
-          <!-- The application or its services may use data, or derived data, guarded by this
-               permission for monetization purposes. -->
-          <enum name="yes" value="1" />
-          <!-- The application or its services may use data, or derived data, guarded by this
-               permission for monetization purposes, however it will only do so when explicity
-               triggered by a user action. -->
-          <enum name="userTriggered" value="2" />
-          <!--  The application or its services does not use data, or derived data, guarded by
-                this permission for monetization purposes. -->
-          <enum name="no" value="3" />
-        </attr>
-
-        <!-- Specify how long the application or its related off-device services store
-             data, or derived data, guarded by this permission.
-
-             This can be one of "notRetained", "userSelected", "unlimited", or a number
-             representing the number of weeks the data is retained.
-
-             If the permission is defined with {@link android.R.attr#usageInfoRequired}
-             {@code true} this <em>must</em> be specified by apps that target Android Q or the
-             permission will not be granted, it will be as if the manifest didn't request it at all.
-             -->
-        <attr name="dataRetentionTime" format="string" />
-
     </declare-styleable>
 
     <!-- The <code>uses-configuration</code> tag specifies
diff --git a/core/res/res/values/config.xml b/core/res/res/values/config.xml
index 76b589c..ec53811 100644
--- a/core/res/res/values/config.xml
+++ b/core/res/res/values/config.xml
@@ -963,7 +963,7 @@
     <bool name="config_nightDisplayAvailable">@bool/config_setColorTransformAccelerated</bool>
 
     <!-- Default mode to control how Night display is automatically activated.
-         One of the following values (see ColorDisplayController.java):
+         One of the following values (see ColorDisplayManager.java):
              0 - AUTO_MODE_DISABLED
              1 - AUTO_MODE_CUSTOM_TIME
              2 - AUTO_MODE_TWILIGHT
@@ -1052,7 +1052,7 @@
     </string-array>
 
 
-    <!-- Indicate available ColorDisplayController.COLOR_MODE_xxx. -->
+    <!-- Indicate available ColorDisplayManager.COLOR_MODE_xxx. -->
     <integer-array name="config_availableColorModes">
         <!-- Example:
         <item>0</item>
diff --git a/core/res/res/values/public.xml b/core/res/res/values/public.xml
index f84f1f1..e6d478a 100644
--- a/core/res/res/values/public.xml
+++ b/core/res/res/values/public.xml
@@ -2925,11 +2925,11 @@
         <public name="importantForContentCapture" />
         <public name="supportsMultipleDisplays" />
         <public name="useAppZygote" />
-        <public name="usageInfoRequired" />
-        <public name="dataSentOffDevice" />
-        <public name="dataSharedWithThirdParty" />
-        <public name="dataUsedForMonetization" />
-        <public name="dataRetentionTime" />
+        <public name="__removed1" />
+        <public name="__removed2" />
+        <public name="__removed3" />
+        <public name="__removed4" />
+        <public name="__removed5" />
         <public name="selectionDividerHeight" />
         <public name="foregroundServiceType" />
         <public name="hasFragileUserData" />
diff --git a/packages/PrintSpooler/AndroidManifest.xml b/packages/PrintSpooler/AndroidManifest.xml
index 478ee54..cd6abb2 100644
--- a/packages/PrintSpooler/AndroidManifest.xml
+++ b/packages/PrintSpooler/AndroidManifest.xml
@@ -37,16 +37,8 @@
     <uses-permission android:name="android.permission.READ_PRINT_SERVICES" />
     <uses-permission android:name="android.permission.READ_PRINT_SERVICE_RECOMMENDATIONS" />
 
-    <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION"
-                     android:dataSentOffDevice="no"
-                     android:dataSharedWithThirdParty="no"
-                     android:dataUsedForMonetization="no"
-                     android:dataRetentionTime="unlimited"/>
-    <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"
-                     android:dataSentOffDevice="no"
-                     android:dataSharedWithThirdParty="no"
-                     android:dataUsedForMonetization="no"
-                     android:dataRetentionTime="unlimited"/>
+    <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
+    <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
 
     <application
         android:allowClearUserData="true"
diff --git a/packages/SystemUI/src/com/android/systemui/Dependency.java b/packages/SystemUI/src/com/android/systemui/Dependency.java
index fece94e..c3f61ee 100644
--- a/packages/SystemUI/src/com/android/systemui/Dependency.java
+++ b/packages/SystemUI/src/com/android/systemui/Dependency.java
@@ -18,6 +18,7 @@
 import android.content.Context;
 import android.content.res.Configuration;
 import android.hardware.SensorPrivacyManager;
+import android.hardware.display.NightDisplayListener;
 import android.os.Handler;
 import android.os.Looper;
 import android.util.ArrayMap;
@@ -25,7 +26,6 @@
 import android.view.IWindowManager;
 
 import com.android.internal.annotations.VisibleForTesting;
-import com.android.internal.app.ColorDisplayController;
 import com.android.internal.logging.MetricsLogger;
 import com.android.internal.statusbar.IStatusBarService;
 import com.android.internal.util.Preconditions;
@@ -206,7 +206,7 @@
     @Inject Lazy<UserInfoController> mUserInfoController;
     @Inject Lazy<KeyguardMonitor> mKeyguardMonitor;
     @Inject Lazy<BatteryController> mBatteryController;
-    @Inject Lazy<ColorDisplayController> mColorDisplayController;
+    @Inject Lazy<NightDisplayListener> mNightDisplayListener;
     @Inject Lazy<ManagedProfileController> mManagedProfileController;
     @Inject Lazy<NextAlarmController> mNextAlarmController;
     @Inject Lazy<DataSaverController> mDataSaverController;
@@ -330,7 +330,7 @@
 
         mProviders.put(BatteryController.class, mBatteryController::get);
 
-        mProviders.put(ColorDisplayController.class, mColorDisplayController::get);
+        mProviders.put(NightDisplayListener.class, mNightDisplayListener::get);
 
         mProviders.put(ManagedProfileController.class, mManagedProfileController::get);
 
diff --git a/packages/SystemUI/src/com/android/systemui/DependencyProvider.java b/packages/SystemUI/src/com/android/systemui/DependencyProvider.java
index 88e32cb..a517d7c 100644
--- a/packages/SystemUI/src/com/android/systemui/DependencyProvider.java
+++ b/packages/SystemUI/src/com/android/systemui/DependencyProvider.java
@@ -24,6 +24,7 @@
 import android.annotation.Nullable;
 import android.content.Context;
 import android.hardware.SensorPrivacyManager;
+import android.hardware.display.NightDisplayListener;
 import android.os.Handler;
 import android.os.HandlerThread;
 import android.os.Looper;
@@ -34,7 +35,6 @@
 import android.view.IWindowManager;
 import android.view.WindowManagerGlobal;
 
-import com.android.internal.app.ColorDisplayController;
 import com.android.internal.logging.MetricsLogger;
 import com.android.internal.statusbar.IStatusBarService;
 import com.android.settingslib.bluetooth.LocalBluetoothManager;
@@ -152,8 +152,8 @@
 
     @Singleton
     @Provides
-    public ColorDisplayController provideColorDisplayController(Context context) {
-        return new ColorDisplayController(context);
+    public NightDisplayListener provideNightDisplayListener(Context context) {
+        return new NightDisplayListener(context);
     }
 
     @Singleton
diff --git a/packages/SystemUI/src/com/android/systemui/privacy/OngoingPrivacyDialog.kt b/packages/SystemUI/src/com/android/systemui/privacy/OngoingPrivacyDialog.kt
index fa1426e..cff7fe4 100644
--- a/packages/SystemUI/src/com/android/systemui/privacy/OngoingPrivacyDialog.kt
+++ b/packages/SystemUI/src/com/android/systemui/privacy/OngoingPrivacyDialog.kt
@@ -69,7 +69,7 @@
             setPositiveButton(R.string.ongoing_privacy_dialog_ok, null)
             setNeutralButton(R.string.ongoing_privacy_dialog_open_settings,
                     object : DialogInterface.OnClickListener {
-                        val intent = Intent(Settings.ACTION_ENTERPRISE_PRIVACY_SETTINGS).putExtra(
+                        val intent = Intent(Settings.ACTION_PRIVACY_SETTINGS).putExtra(
                                 Intent.EXTRA_DURATION_MILLIS, TimeUnit.MINUTES.toMillis(1))
 
                         @Suppress("DEPRECATION")
@@ -167,7 +167,7 @@
             // Check if package exists
             context.packageManager.getPackageInfo(app.packageName, 0)
             item.setOnClickListener(object : View.OnClickListener {
-                val intent = Intent(Intent.ACTION_REVIEW_APP_PERMISSION_USAGE)
+                val intent = Intent(Intent.ACTION_MANAGE_APP_PERMISSIONS)
                         .putExtra(Intent.EXTRA_PACKAGE_NAME, app.packageName)
                         .putExtra(Intent.EXTRA_USER, UserHandle.getUserHandleForUid(app.uid))
                 override fun onClick(v: View?) {
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/NightDisplayTile.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/NightDisplayTile.java
index de78d33..effa935 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/NightDisplayTile.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/NightDisplayTile.java
@@ -22,6 +22,7 @@
 import android.app.ActivityManager;
 import android.content.Intent;
 import android.hardware.display.ColorDisplayManager;
+import android.hardware.display.NightDisplayListener;
 import android.metrics.LogMaker;
 import android.provider.Settings;
 import android.service.quicksettings.Tile;
@@ -31,7 +32,6 @@
 
 import androidx.annotation.StringRes;
 
-import com.android.internal.app.ColorDisplayController;
 import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
 import com.android.systemui.R;
 import com.android.systemui.plugins.qs.QSTile.BooleanState;
@@ -46,8 +46,9 @@
 
 import javax.inject.Inject;
 
-public class NightDisplayTile extends QSTileImpl<BooleanState>
-        implements ColorDisplayController.Callback {
+/** Quick settings tile: Night display **/
+public class NightDisplayTile extends QSTileImpl<BooleanState> implements
+        NightDisplayListener.Callback {
 
     /**
      * Pattern for {@link java.time.format.DateTimeFormatter} used to approximate the time to the
@@ -57,13 +58,15 @@
     private static final String PATTERN_HOUR_MINUTE = "h:mm a";
     private static final String PATTERN_HOUR_NINUTE_24 = "HH:mm";
 
-    private ColorDisplayController mController;
+    private final ColorDisplayManager mManager;
+    private NightDisplayListener mListener;
     private boolean mIsListening;
 
     @Inject
     public NightDisplayTile(QSHost host) {
         super(host);
-        mController = new ColorDisplayController(mContext, ActivityManager.getCurrentUser());
+        mManager = mContext.getSystemService(ColorDisplayManager.class);
+        mListener = new NightDisplayListener(mContext, ActivityManager.getCurrentUser());
     }
 
     @Override
@@ -81,27 +84,27 @@
         // Enroll in forced auto mode if eligible.
         if ("1".equals(Settings.Global.getString(mContext.getContentResolver(),
                 Settings.Global.NIGHT_DISPLAY_FORCED_AUTO_MODE_AVAILABLE))
-                && mController.getAutoModeRaw() == -1) {
-            mController.setAutoMode(ColorDisplayManager.AUTO_MODE_CUSTOM_TIME);
+                && mManager.getNightDisplayAutoModeRaw() == -1) {
+            mManager.setNightDisplayAutoMode(ColorDisplayManager.AUTO_MODE_CUSTOM_TIME);
             Log.i("NightDisplayTile", "Enrolled in forced night display auto mode");
         }
 
         // Change current activation state.
         final boolean activated = !mState.value;
-        mController.setActivated(activated);
+        mManager.setNightDisplayActivated(activated);
     }
 
     @Override
     protected void handleUserSwitch(int newUserId) {
         // Stop listening to the old controller.
         if (mIsListening) {
-            mController.setListener(null);
+            mListener.setCallback(null);
         }
 
         // Make a new controller for the new user.
-        mController = new ColorDisplayController(mContext, newUserId);
+        mListener = new NightDisplayListener(mContext, newUserId);
         if (mIsListening) {
-            mController.setListener(this);
+            mListener.setCallback(this);
         }
 
         super.handleUserSwitch(newUserId);
@@ -109,7 +112,7 @@
 
     @Override
     protected void handleUpdateState(BooleanState state, Object arg) {
-        state.value = mController.isActivated();
+        state.value = mManager.isNightDisplayActivated();
         state.label = mContext.getString(R.string.quick_settings_night_display_label);
         state.icon = ResourceIcon.get(com.android.internal.R.drawable.ic_qs_night_display_on);
         state.expandedAccessibilityClassName = Switch.class.getName();
@@ -121,12 +124,12 @@
     }
 
     /**
-     * Returns a {@link String} for the secondary label that reflects when the light will be turned
-     * on or off based on the current auto mode and night light activated status.
+     * Returns a String for the secondary label that reflects when the light will be turned on or
+     * off based on the current auto mode and night light activated status.
      */
     @Nullable
     private String getSecondaryLabel(boolean isNightLightActivated) {
-        switch(mController.getAutoMode()) {
+        switch (mManager.getNightDisplayAutoMode()) {
             case ColorDisplayManager.AUTO_MODE_TWILIGHT:
                 // Auto mode related to sunrise & sunset. If the light is on, it's guaranteed to be
                 // turned off at sunrise. If it's off, it's guaranteed to be turned on at sunset.
@@ -143,10 +146,10 @@
                 final DateTimeFormatter toggleTimeFormat;
 
                 if (isNightLightActivated) {
-                    toggleTime = mController.getCustomEndTime();
+                    toggleTime = mManager.getNightDisplayCustomEndTime();
                     toggleTimeStringRes = R.string.quick_settings_secondary_label_until;
                 } else {
-                    toggleTime = mController.getCustomStartTime();
+                    toggleTime = mManager.getNightDisplayCustomStartTime();
                     toggleTimeStringRes = R.string.quick_settings_night_secondary_label_on_at;
                 }
 
@@ -175,7 +178,8 @@
 
     @Override
     public LogMaker populate(LogMaker logMaker) {
-        return super.populate(logMaker).addTaggedData(FIELD_QS_MODE, mController.getAutoModeRaw());
+        return super.populate(logMaker)
+                .addTaggedData(FIELD_QS_MODE, mManager.getNightDisplayAutoModeRaw());
     }
 
     @Override
@@ -187,10 +191,10 @@
     protected void handleSetListening(boolean listening) {
         mIsListening = listening;
         if (listening) {
-            mController.setListener(this);
+            mListener.setCallback(this);
             refreshState();
         } else {
-            mController.setListener(null);
+            mListener.setCallback(null);
         }
     }
 
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationInfo.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationInfo.java
index b6948fc..c7b2fab 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationInfo.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationInfo.java
@@ -537,7 +537,7 @@
                     mChosenImportance = IMPORTANCE_LOW;
                     confirmationText.setText(R.string.notification_channel_silenced);
                 } else {
-                    mChosenImportance = IMPORTANCE_HIGH;
+                    mChosenImportance = IMPORTANCE_DEFAULT;
                     confirmationText.setText(R.string.notification_channel_unsilenced);
                 }
                 break;
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/AutoTileManager.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/AutoTileManager.java
index b96c55b..c9be2c8 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/AutoTileManager.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/AutoTileManager.java
@@ -16,11 +16,11 @@
 
 import android.content.Context;
 import android.hardware.display.ColorDisplayManager;
+import android.hardware.display.NightDisplayListener;
 import android.os.Handler;
 import android.provider.Settings.Secure;
 
 import com.android.internal.annotations.VisibleForTesting;
-import com.android.internal.app.ColorDisplayController;
 import com.android.systemui.Dependency;
 import com.android.systemui.qs.AutoAddTracker;
 import com.android.systemui.qs.QSTileHost;
@@ -50,7 +50,7 @@
     private final HotspotController mHotspotController;
     private final DataSaverController mDataSaverController;
     private final ManagedProfileController mManagedProfileController;
-    private final ColorDisplayController mColorDisplayController;
+    private final NightDisplayListener mNightDisplayListener;
 
     @Inject
     public AutoTileManager(Context context, AutoAddTracker autoAddTracker, QSTileHost host,
@@ -58,7 +58,7 @@
             HotspotController hotspotController,
             DataSaverController dataSaverController,
             ManagedProfileController managedProfileController,
-            ColorDisplayController colorDisplayController) {
+            NightDisplayListener nightDisplayListener) {
         mAutoTracker = autoAddTracker;
         mContext = context;
         mHost = host;
@@ -66,7 +66,7 @@
         mHotspotController = hotspotController;
         mDataSaverController = dataSaverController;
         mManagedProfileController = managedProfileController;
-        mColorDisplayController = colorDisplayController;
+        mNightDisplayListener = nightDisplayListener;
         if (!mAutoTracker.isAdded(HOTSPOT)) {
             hotspotController.addCallback(mHotspotCallback);
         }
@@ -93,7 +93,7 @@
         }
         if (!mAutoTracker.isAdded(NIGHT)
                 && ColorDisplayManager.isNightDisplayAvailable(mContext)) {
-            colorDisplayController.setListener(mColorDisplayCallback);
+            nightDisplayListener.setCallback(mNightDisplayCallback);
         }
     }
 
@@ -106,7 +106,7 @@
         mDataSaverController.removeCallback(mDataSaverListener);
         mManagedProfileController.removeCallback(mProfileCallback);
         if (ColorDisplayManager.isNightDisplayAvailable(mContext)) {
-            mColorDisplayController.setListener(null);
+            mNightDisplayListener.setCallback(null);
         }
     }
 
@@ -157,8 +157,8 @@
     };
 
     @VisibleForTesting
-    final ColorDisplayController.Callback mColorDisplayCallback =
-            new ColorDisplayController.Callback() {
+    final NightDisplayListener.Callback mNightDisplayCallback =
+            new NightDisplayListener.Callback() {
         @Override
         public void onActivated(boolean activated) {
             if (activated) {
@@ -178,7 +178,7 @@
             if (mAutoTracker.isAdded(NIGHT)) return;
             mHost.addTile(NIGHT);
             mAutoTracker.setTileAdded(NIGHT);
-            mHandler.post(() -> mColorDisplayController.setListener(null));
+            mHandler.post(() -> mNightDisplayListener.setCallback(null));
         }
     };
 }
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/NotificationInfoTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/NotificationInfoTest.java
index 2a64445..105bd9d 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/NotificationInfoTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/NotificationInfoTest.java
@@ -18,7 +18,6 @@
 
 import static android.app.NotificationChannel.USER_LOCKED_IMPORTANCE;
 import static android.app.NotificationManager.IMPORTANCE_DEFAULT;
-import static android.app.NotificationManager.IMPORTANCE_HIGH;
 import static android.app.NotificationManager.IMPORTANCE_LOW;
 import static android.app.NotificationManager.IMPORTANCE_MIN;
 import static android.app.NotificationManager.IMPORTANCE_NONE;
@@ -1067,7 +1066,7 @@
                 anyString(), eq(TEST_UID), updated.capture());
         assertTrue((updated.getValue().getUserLockedFields()
                 & USER_LOCKED_IMPORTANCE) != 0);
-        assertEquals(IMPORTANCE_HIGH, updated.getValue().getImportance());
+        assertEquals(IMPORTANCE_DEFAULT, updated.getValue().getImportance());
     }
 
     @Test
@@ -1111,7 +1110,7 @@
                 anyString(), eq(TEST_UID), updated.capture());
         assertTrue((updated.getValue().getUserLockedFields()
                 & USER_LOCKED_IMPORTANCE) != 0);
-        assertEquals(IMPORTANCE_HIGH, updated.getValue().getImportance());
+        assertEquals(IMPORTANCE_DEFAULT, updated.getValue().getImportance());
     }
 
     @Test
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/AutoTileManagerTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/AutoTileManagerTest.java
index 1ded835..f3740c4 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/AutoTileManagerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/AutoTileManagerTest.java
@@ -21,13 +21,13 @@
 import static org.mockito.Mockito.verify;
 
 import android.hardware.display.ColorDisplayManager;
+import android.hardware.display.NightDisplayListener;
 import android.os.Handler;
 import android.support.test.filters.SmallTest;
 import android.testing.AndroidTestingRunner;
 import android.testing.TestableLooper;
 import android.testing.TestableLooper.RunWithLooper;
 
-import com.android.internal.app.ColorDisplayController;
 import com.android.systemui.SysuiTestCase;
 import com.android.systemui.qs.AutoAddTracker;
 import com.android.systemui.qs.QSTileHost;
@@ -58,7 +58,7 @@
                 mock(HotspotController.class),
                 mock(DataSaverController.class),
                 mock(ManagedProfileController.class),
-                mock(ColorDisplayController.class));
+                mock(NightDisplayListener.class));
     }
 
     @Test
@@ -66,7 +66,7 @@
         if (!ColorDisplayManager.isNightDisplayAvailable(mContext)) {
             return;
         }
-        mAutoTileManager.mColorDisplayCallback.onActivated(true);
+        mAutoTileManager.mNightDisplayCallback.onActivated(true);
         verify(mQsTileHost).addTile("night");
     }
 
@@ -75,7 +75,7 @@
         if (!ColorDisplayManager.isNightDisplayAvailable(mContext)) {
             return;
         }
-        mAutoTileManager.mColorDisplayCallback.onActivated(false);
+        mAutoTileManager.mNightDisplayCallback.onActivated(false);
         verify(mQsTileHost, never()).addTile("night");
     }
 
@@ -84,7 +84,7 @@
         if (!ColorDisplayManager.isNightDisplayAvailable(mContext)) {
             return;
         }
-        mAutoTileManager.mColorDisplayCallback.onAutoModeChanged(
+        mAutoTileManager.mNightDisplayCallback.onAutoModeChanged(
                 ColorDisplayManager.AUTO_MODE_TWILIGHT);
         verify(mQsTileHost).addTile("night");
     }
@@ -94,7 +94,7 @@
         if (!ColorDisplayManager.isNightDisplayAvailable(mContext)) {
             return;
         }
-        mAutoTileManager.mColorDisplayCallback.onAutoModeChanged(
+        mAutoTileManager.mNightDisplayCallback.onAutoModeChanged(
                 ColorDisplayManager.AUTO_MODE_CUSTOM_TIME);
         verify(mQsTileHost).addTile("night");
     }
@@ -104,7 +104,7 @@
         if (!ColorDisplayManager.isNightDisplayAvailable(mContext)) {
             return;
         }
-        mAutoTileManager.mColorDisplayCallback.onAutoModeChanged(
+        mAutoTileManager.mNightDisplayCallback.onAutoModeChanged(
                 ColorDisplayManager.AUTO_MODE_DISABLED);
         verify(mQsTileHost, never()).addTile("night");
     }
diff --git a/services/core/java/com/android/server/display/BrightnessTracker.java b/services/core/java/com/android/server/display/BrightnessTracker.java
index 727cf0e..126beef 100644
--- a/services/core/java/com/android/server/display/BrightnessTracker.java
+++ b/services/core/java/com/android/server/display/BrightnessTracker.java
@@ -34,6 +34,7 @@
 import android.hardware.SensorManager;
 import android.hardware.display.AmbientBrightnessDayStats;
 import android.hardware.display.BrightnessChangeEvent;
+import android.hardware.display.ColorDisplayManager;
 import android.hardware.display.DisplayManager;
 import android.hardware.display.DisplayManagerInternal;
 import android.hardware.display.DisplayedContentSample;
@@ -57,7 +58,6 @@
 
 import com.android.internal.annotations.GuardedBy;
 import com.android.internal.annotations.VisibleForTesting;
-import com.android.internal.app.ColorDisplayController;
 import com.android.internal.os.BackgroundThread;
 import com.android.internal.util.FastXmlSerializer;
 import com.android.internal.util.RingBuffer;
@@ -382,9 +382,8 @@
             return;
         }
 
-        builder.setNightMode(mInjector.isNightModeActive(mContext, UserHandle.USER_CURRENT));
-        builder.setColorTemperature(mInjector.getColorTemperature(mContext,
-                UserHandle.USER_CURRENT));
+        builder.setNightMode(mInjector.isNightDisplayActivated(mContext));
+        builder.setColorTemperature(mInjector.getNightDisplayColorTemperature(mContext));
 
         if (mColorSamplingEnabled) {
             DisplayedContentSample sample = mInjector.sampleColor(mNoFramesToSample);
@@ -1096,12 +1095,13 @@
             return context.getSystemService(PowerManager.class).isInteractive();
         }
 
-        public int getColorTemperature(Context context, int userId) {
-            return new ColorDisplayController(context, userId).getColorTemperature();
+        public int getNightDisplayColorTemperature(Context context) {
+            return context.getSystemService(ColorDisplayManager.class)
+                    .getNightDisplayColorTemperature();
         }
 
-        public boolean isNightModeActive(Context context, int userId) {
-            return new ColorDisplayController(context, userId).isActivated();
+        public boolean isNightDisplayActivated(Context context) {
+            return context.getSystemService(ColorDisplayManager.class).isNightDisplayActivated();
         }
 
         public DisplayedContentSample sampleColor(int noFramesToSample) {
diff --git a/services/core/java/com/android/server/display/ColorDisplayService.java b/services/core/java/com/android/server/display/ColorDisplayService.java
index 6a76087..9cb6eee 100644
--- a/services/core/java/com/android/server/display/ColorDisplayService.java
+++ b/services/core/java/com/android/server/display/ColorDisplayService.java
@@ -72,7 +72,6 @@
 
 import com.android.internal.R;
 import com.android.internal.annotations.VisibleForTesting;
-import com.android.internal.app.ColorDisplayController;
 import com.android.internal.util.DumpUtils;
 import com.android.server.DisplayThread;
 import com.android.server.SystemService;
@@ -448,7 +447,6 @@
     private ContentObserver mUserSetupObserver;
     private boolean mBootCompleted;
 
-    private ColorDisplayController mNightDisplayController;
     private ContentObserver mContentObserver;
 
     private DisplayWhiteBalanceListener mDisplayWhiteBalanceListener;
@@ -547,8 +545,6 @@
     private void setUp() {
         Slog.d(TAG, "setUp: currentUser=" + mCurrentUser);
 
-        mNightDisplayController = new ColorDisplayController(getContext(), mCurrentUser);
-
         // Listen for external changes to any of the settings.
         if (mContentObserver == null) {
             mContentObserver = new ContentObserver(new Handler(DisplayThread.get().getLooper())) {
@@ -586,7 +582,7 @@
                                         getNightDisplayCustomEndTimeInternal().getLocalTime());
                                 break;
                             case System.DISPLAY_COLOR_MODE:
-                                onDisplayColorModeChanged(mNightDisplayController.getColorMode());
+                                onDisplayColorModeChanged(getColorModeInternal());
                                 break;
                             case Secure.ACCESSIBILITY_DISPLAY_INVERSION_ENABLED:
                                 onAccessibilityInversionChanged();
@@ -634,7 +630,7 @@
 
         // Set the color mode, if valid, and immediately apply the updated tint matrix based on the
         // existing activated state. This ensures consistency of tint across the color mode change.
-        onDisplayColorModeChanged(mNightDisplayController.getColorMode());
+        onDisplayColorModeChanged(getColorModeInternal());
 
         if (mNightDisplayTintController.isAvailable(getContext())) {
             // Reset the activated state.
@@ -667,10 +663,6 @@
 
         getContext().getContentResolver().unregisterContentObserver(mContentObserver);
 
-        if (mNightDisplayController != null) {
-            mNightDisplayController = null;
-        }
-
         if (mNightDisplayTintController.isAvailable(getContext())) {
             if (mNightDisplayAutoMode != null) {
                 mNightDisplayAutoMode.onStop();
@@ -740,7 +732,7 @@
     }
 
     private void onAccessibilityActivated() {
-        onDisplayColorModeChanged(mNightDisplayController.getColorMode());
+        onDisplayColorModeChanged(getColorModeInternal());
     }
 
     /**
@@ -1003,8 +995,7 @@
                 mCurrentUser);
     }
 
-    private @ColorMode
-    int getColorModeInternal() {
+    private @ColorMode int getColorModeInternal() {
         final ContentResolver cr = getContext().getContentResolver();
         if (Secure.getIntForUser(cr, Secure.ACCESSIBILITY_DISPLAY_INVERSION_ENABLED,
                 0, mCurrentUser) == 1
diff --git a/services/core/java/com/android/server/pm/PackageManagerService.java b/services/core/java/com/android/server/pm/PackageManagerService.java
index 32dc988..eaedec5 100644
--- a/services/core/java/com/android/server/pm/PackageManagerService.java
+++ b/services/core/java/com/android/server/pm/PackageManagerService.java
@@ -195,7 +195,6 @@
 import android.content.pm.Signature;
 import android.content.pm.SuspendDialogInfo;
 import android.content.pm.UserInfo;
-import android.content.pm.UsesPermissionInfo;
 import android.content.pm.VerifierDeviceIdentity;
 import android.content.pm.VerifierInfo;
 import android.content.pm.VersionedPackage;
@@ -11313,26 +11312,6 @@
                     }
                 }
             }
-
-            // Check permission usage info requirements.
-            if (pkg.applicationInfo.targetSdkVersion >= Build.VERSION_CODES.Q) {
-                for (UsesPermissionInfo upi : pkg.usesPermissionInfos) {
-                    if (!mPermissionManager.isPermissionUsageInfoRequired(upi.getPermission())) {
-                        continue;
-                    }
-                    if (upi.getDataSentOffDevice() == UsesPermissionInfo.USAGE_UNDEFINED
-                            || upi.getDataSharedWithThirdParty()
-                                == UsesPermissionInfo.USAGE_UNDEFINED
-                            || upi.getDataUsedForMonetization()
-                                == UsesPermissionInfo.USAGE_UNDEFINED
-                            || upi.getDataRetention() == UsesPermissionInfo.RETENTION_UNDEFINED) {
-                        // STOPSHIP: Make this throw
-                        Slog.e(TAG, "Package " + pkg.packageName + " does not provide usage "
-                                + "information for permission " + upi.getPermission()
-                                + ". This will be a fatal error in Q.");
-                    }
-                }
-            }
         }
     }
 
diff --git a/services/core/java/com/android/server/pm/permission/BasePermission.java b/services/core/java/com/android/server/pm/permission/BasePermission.java
index 173d9a0..1957eb8 100644
--- a/services/core/java/com/android/server/pm/permission/BasePermission.java
+++ b/services/core/java/com/android/server/pm/permission/BasePermission.java
@@ -105,8 +105,6 @@
      */
     private boolean perUser;
 
-    boolean usageInfoRequired;
-
     public BasePermission(String _name, String _sourcePackageName, @PermissionType int _type) {
         name = _name;
         sourcePackageName = _sourcePackageName;
@@ -375,7 +373,6 @@
         }
         if (bp.perm == p) {
             bp.protectionLevel = p.info.protectionLevel;
-            bp.usageInfoRequired = p.info.usageInfoRequired;
         }
         if (PackageManagerService.DEBUG_PACKAGE_SCANNING && r != null) {
             Log.d(TAG, "  Permissions: " + r);
@@ -455,7 +452,6 @@
         permissionInfo.packageName = sourcePackageName;
         permissionInfo.nonLocalizedLabel = name;
         permissionInfo.protectionLevel = protectionLevel;
-        permissionInfo.usageInfoRequired = usageInfoRequired;
         return permissionInfo;
     }
 
@@ -484,7 +480,6 @@
         bp.protectionLevel = readInt(parser, null, "protection",
                 PermissionInfo.PROTECTION_NORMAL);
         bp.protectionLevel = PermissionInfo.fixProtectionLevel(bp.protectionLevel);
-        bp.usageInfoRequired = readInt(parser, null, "usageInfoRequired", 0) != 0;
         if (dynamic) {
             final PermissionInfo pi = new PermissionInfo();
             pi.packageName = sourcePackage.intern();
@@ -492,7 +487,6 @@
             pi.icon = readInt(parser, null, "icon", 0);
             pi.nonLocalizedLabel = parser.getAttributeValue(null, "label");
             pi.protectionLevel = bp.protectionLevel;
-            pi.usageInfoRequired = bp.usageInfoRequired;
             bp.pendingPermissionInfo = pi;
         }
         out.put(bp.name, bp);
@@ -525,7 +519,6 @@
         if (protectionLevel != PermissionInfo.PROTECTION_NORMAL) {
             serializer.attribute(null, "protection", Integer.toString(protectionLevel));
         }
-        serializer.attribute(null, "usageInfoRequired", usageInfoRequired ? "1" : "0");
         if (type == BasePermission.TYPE_DYNAMIC) {
             final PermissionInfo pi = perm != null ? perm.info : pendingPermissionInfo;
             if (pi != null) {
@@ -562,7 +555,6 @@
         if (!compareStrings(pi1.nonLocalizedLabel, pi2.nonLocalizedLabel)) return false;
         // We'll take care of setting this one.
         if (!compareStrings(pi1.packageName, pi2.packageName)) return false;
-        if (pi1.usageInfoRequired != pi2.usageInfoRequired) return false;
         // These are not currently stored in settings.
         //if (!compareStrings(pi1.group, pi2.group)) return false;
         //if (!compareStrings(pi1.nonLocalizedDescription, pi2.nonLocalizedDescription)) return false;
@@ -610,8 +602,6 @@
             pw.print("    enforced=");
             pw.println(readEnforced);
         }
-        pw.print("    usageInfoRequired=");
-        pw.println(usageInfoRequired);
         return true;
     }
 }
diff --git a/services/core/java/com/android/server/pm/permission/PermissionManagerInternal.java b/services/core/java/com/android/server/pm/permission/PermissionManagerInternal.java
index 189d0f4..f4979746 100644
--- a/services/core/java/com/android/server/pm/permission/PermissionManagerInternal.java
+++ b/services/core/java/com/android/server/pm/permission/PermissionManagerInternal.java
@@ -181,9 +181,4 @@
 
     /** HACK HACK methods to allow for partial migration of data to the PermissionManager class */
     public abstract @Nullable BasePermission getPermissionTEMP(@NonNull String permName);
-
-    /**
-     * Returns {@code true} if {@code permName} has {@code usageInfoRequired} set.
-     */
-    public abstract boolean isPermissionUsageInfoRequired(@NonNull String permName);
 }
diff --git a/services/core/java/com/android/server/pm/permission/PermissionManagerService.java b/services/core/java/com/android/server/pm/permission/PermissionManagerService.java
index a4413f9..38940d6 100644
--- a/services/core/java/com/android/server/pm/permission/PermissionManagerService.java
+++ b/services/core/java/com/android/server/pm/permission/PermissionManagerService.java
@@ -2737,12 +2737,5 @@
                 return mSettings.getPermissionLocked(permName);
             }
         }
-        @Override
-        public boolean isPermissionUsageInfoRequired(String permName) {
-            synchronized (PermissionManagerService.this.mLock) {
-                BasePermission bp = mSettings.getPermissionLocked(permName);
-                return bp != null && bp.usageInfoRequired;
-            }
-        }
     }
 }
diff --git a/services/tests/servicestests/src/com/android/server/display/BrightnessTrackerTest.java b/services/tests/servicestests/src/com/android/server/display/BrightnessTrackerTest.java
index e3b1245..7081d2e 100644
--- a/services/tests/servicestests/src/com/android/server/display/BrightnessTrackerTest.java
+++ b/services/tests/servicestests/src/com/android/server/display/BrightnessTrackerTest.java
@@ -962,13 +962,13 @@
         }
 
         @Override
-        public int getColorTemperature(Context context, int userId) {
+        public int getNightDisplayColorTemperature(Context context) {
           return mSecureIntSettings.getOrDefault(Settings.Secure.NIGHT_DISPLAY_COLOR_TEMPERATURE,
                   mDefaultNightModeColorTemperature);
         }
 
         @Override
-        public boolean isNightModeActive(Context context, int userId) {
+        public boolean isNightDisplayActivated(Context context) {
             return mSecureIntSettings.getOrDefault(Settings.Secure.NIGHT_DISPLAY_ACTIVATED,
                     0) == 1;
         }
diff --git a/services/tests/servicestests/src/com/android/server/display/ColorDisplayServiceTest.java b/services/tests/servicestests/src/com/android/server/display/ColorDisplayServiceTest.java
index 0b01657..5900fc5 100644
--- a/services/tests/servicestests/src/com/android/server/display/ColorDisplayServiceTest.java
+++ b/services/tests/servicestests/src/com/android/server/display/ColorDisplayServiceTest.java
@@ -26,6 +26,7 @@
 import android.content.Context;
 import android.content.ContextWrapper;
 import android.hardware.display.ColorDisplayManager;
+import android.hardware.display.Time;
 import android.os.Handler;
 import android.os.UserHandle;
 import android.provider.Settings;
@@ -37,7 +38,6 @@
 import androidx.test.runner.AndroidJUnit4;
 
 import com.android.internal.R;
-import com.android.internal.app.ColorDisplayController;
 import com.android.internal.util.test.FakeSettingsProvider;
 import com.android.server.LocalServices;
 import com.android.server.SystemService;
@@ -71,7 +71,6 @@
     private MockTwilightManager mTwilightManager;
 
     private ColorDisplayService mColorDisplayService;
-    private ColorDisplayController mColorDisplayController;
     private ColorDisplayService.BinderService mBinderService;
 
     @BeforeClass
@@ -97,7 +96,6 @@
         mTwilightManager = new MockTwilightManager();
         LocalServices.addService(TwilightManager.class, mTwilightManager);
 
-        mColorDisplayController = new ColorDisplayController(mContext, mUserId);
         mColorDisplayService = new ColorDisplayService(mContext);
         mBinderService = mColorDisplayService.new BinderService();
     }
@@ -988,9 +986,11 @@
      * @param endTimeOffset the offset relative to now to deactivate Night display (in minutes)
      */
     private void setAutoModeCustom(int startTimeOffset, int endTimeOffset) {
-        mColorDisplayController.setAutoMode(ColorDisplayManager.AUTO_MODE_CUSTOM_TIME);
-        mColorDisplayController.setCustomStartTime(getLocalTimeRelativeToNow(startTimeOffset));
-        mColorDisplayController.setCustomEndTime(getLocalTimeRelativeToNow(endTimeOffset));
+        mBinderService.setNightDisplayAutoMode(ColorDisplayManager.AUTO_MODE_CUSTOM_TIME);
+        mBinderService.setNightDisplayCustomStartTime(
+                new Time(getLocalTimeRelativeToNow(startTimeOffset)));
+        mBinderService
+                .setNightDisplayCustomEndTime(new Time(getLocalTimeRelativeToNow(endTimeOffset)));
     }
 
     /**
@@ -1000,7 +1000,7 @@
      * @param sunriseOffset the offset relative to now for sunrise (in minutes)
      */
     private void setAutoModeTwilight(int sunsetOffset, int sunriseOffset) {
-        mColorDisplayController.setAutoMode(ColorDisplayManager.AUTO_MODE_TWILIGHT);
+        mBinderService.setNightDisplayAutoMode(ColorDisplayManager.AUTO_MODE_TWILIGHT);
         mTwilightManager.setTwilightState(
                 getTwilightStateRelativeToNow(sunsetOffset, sunriseOffset));
     }
@@ -1041,22 +1041,18 @@
     }
 
     /**
-     * Configures color mode via ColorDisplayController.
-     *
-     * @param colorMode the color mode to set
+     * Configures color mode.
      */
     private void setColorMode(int colorMode) {
-        mColorDisplayController.setColorMode(colorMode);
+        mBinderService.setColorMode(colorMode);
     }
 
     /**
      * Returns whether the color mode is valid on the device the tests are running on.
-     *
-     * @param mode the mode to check
      */
     private boolean isColorModeValid(int mode) {
         final int[] availableColorModes = mContext.getResources().getIntArray(
-            R.array.config_availableColorModes);
+                R.array.config_availableColorModes);
         if (availableColorModes != null) {
             for (int availableMode : availableColorModes) {
                 if (mode == availableMode) {
@@ -1073,12 +1069,9 @@
     private void startService() {
         Secure.putIntForUser(mContext.getContentResolver(), Secure.USER_SETUP_COMPLETE, 1, mUserId);
 
-        InstrumentationRegistry.getInstrumentation().runOnMainSync(new Runnable() {
-            @Override
-            public void run() {
-                mColorDisplayService.onBootPhase(SystemService.PHASE_BOOT_COMPLETED);
-                mColorDisplayService.onStartUser(mUserId);
-            }
+        InstrumentationRegistry.getInstrumentation().runOnMainSync(() -> {
+            mColorDisplayService.onBootPhase(SystemService.PHASE_BOOT_COMPLETED);
+            mColorDisplayService.onStartUser(mUserId);
         });
     }
 
@@ -1100,7 +1093,7 @@
      */
     private void assertActiveColorMode(int mode) {
         assertWithMessage("Unexpected color mode setting")
-                .that(mColorDisplayController.getColorMode())
+                .that(mBinderService.getColorMode())
                 .isEqualTo(mode);
     }
 
diff --git a/services/tests/servicestests/src/com/android/server/pm/PackageParserTest.java b/services/tests/servicestests/src/com/android/server/pm/PackageParserTest.java
index 85909d5..72357ce 100644
--- a/services/tests/servicestests/src/com/android/server/pm/PackageParserTest.java
+++ b/services/tests/servicestests/src/com/android/server/pm/PackageParserTest.java
@@ -31,7 +31,6 @@
 import android.content.pm.ServiceInfo;
 import android.content.pm.SharedLibraryInfo;
 import android.content.pm.Signature;
-import android.content.pm.UsesPermissionInfo;
 import android.os.Bundle;
 import android.os.Parcel;
 import android.platform.test.annotations.Presubmit;
@@ -466,7 +465,6 @@
         pkg.services.add(new PackageParser.Service(dummy, new ServiceInfo()));
         pkg.instrumentation.add(new PackageParser.Instrumentation(dummy, new InstrumentationInfo()));
         pkg.requestedPermissions.add("foo7");
-        pkg.usesPermissionInfos.add(new UsesPermissionInfo("foo7"));
         pkg.implicitPermissions.add("foo25");
 
         pkg.protectedBroadcasts = new ArrayList<>();
diff --git a/tools/stats_log_api_gen/Collation.cpp b/tools/stats_log_api_gen/Collation.cpp
index 257043b..a8d970e 100644
--- a/tools/stats_log_api_gen/Collation.cpp
+++ b/tools/stats_log_api_gen/Collation.cpp
@@ -48,6 +48,7 @@
       primaryFields(that.primaryFields),
       exclusiveField(that.exclusiveField),
       uidField(that.uidField),
+      whitelisted(that.whitelisted),
       binaryFields(that.binaryFields) {}
 
 AtomDecl::AtomDecl(int c, const string& n, const string& m)
@@ -162,6 +163,7 @@
                  vector<java_type_t> *signature) {
 
   int errorCount = 0;
+
   // Build a sorted list of the fields. Descriptor has them in source file
   // order.
   map<int, const FieldDescriptor *> fields;
@@ -387,6 +389,11 @@
 
     const Descriptor *atom = atomField->message_type();
     AtomDecl atomDecl(atomField->number(), atomField->name(), atom->name());
+
+    if (atomField->options().GetExtension(os::statsd::allow_from_any_uid) == true) {
+      atomDecl.whitelisted = true;
+    }
+
     vector<java_type_t> signature;
     errorCount += collate_atom(atom, &atomDecl, &signature);
     if (atomDecl.primaryFields.size() != 0 && atomDecl.exclusiveField == 0) {
diff --git a/tools/stats_log_api_gen/Collation.h b/tools/stats_log_api_gen/Collation.h
index 450b305..6b86b862 100644
--- a/tools/stats_log_api_gen/Collation.h
+++ b/tools/stats_log_api_gen/Collation.h
@@ -89,6 +89,8 @@
 
     int uidField = 0;
 
+    bool whitelisted = false;
+
     vector<int> binaryFields;
 
     AtomDecl();
diff --git a/tools/stats_log_api_gen/main.cpp b/tools/stats_log_api_gen/main.cpp
index 4491a85..55440d2 100644
--- a/tools/stats_log_api_gen/main.cpp
+++ b/tools/stats_log_api_gen/main.cpp
@@ -158,6 +158,20 @@
             }
         }
     }
+
+    fprintf(out, "};\n");
+    fprintf(out, "\n");
+
+    fprintf(out,
+            "const std::set<int> AtomsInfo::kWhitelistedAtoms = {\n");
+    for (set<AtomDecl>::const_iterator atom = atoms.decls.begin();
+         atom != atoms.decls.end(); atom++) {
+        if (atom->whitelisted) {
+            string constant = make_constant_name(atom->name);
+            fprintf(out, " %s,\n", constant.c_str());
+        }
+    }
+
     fprintf(out, "};\n");
     fprintf(out, "\n");
 
@@ -728,6 +742,8 @@
     fprintf(out,
             "  const static std::map<int, std::vector<int>> "
             "kBytesFieldAtoms;");
+    fprintf(out,
+            "  const static std::set<int> kWhitelistedAtoms;\n");
     fprintf(out, "};\n");
 
     fprintf(out, "const static int kMaxPushedAtomId = %d;\n\n",
diff --git a/tools/stats_log_api_gen/test.proto b/tools/stats_log_api_gen/test.proto
index 3be87d9..24ebf4d 100644
--- a/tools/stats_log_api_gen/test.proto
+++ b/tools/stats_log_api_gen/test.proto
@@ -195,4 +195,22 @@
             [(android.os.statsd.state_field_option).option = PRIMARY];
     optional int32 state = 3
             [(android.os.statsd.state_field_option).option = EXCLUSIVE];
+}
+
+message WhitelistedAtom {
+  optional int32 field = 1;
+}
+
+message NonWhitelistedAtom {
+  optional int32 field = 1;
+}
+
+message ListedAtoms {
+  oneof event {
+    // Atoms can be whitelisted i.e. they can be triggered by any source
+    WhitelistedAtom whitelisted_atom = 1 [(android.os.statsd.allow_from_any_uid) = true];
+    // Atoms are not whitelisted by default, so they can only be triggered
+    // by whitelisted sources
+    NonWhitelistedAtom non_whitelisted_atom = 2;
+  }
 }
\ No newline at end of file
diff --git a/tools/stats_log_api_gen/test_collation.cpp b/tools/stats_log_api_gen/test_collation.cpp
index ad3bffac..dc585c1 100644
--- a/tools/stats_log_api_gen/test_collation.cpp
+++ b/tools/stats_log_api_gen/test_collation.cpp
@@ -226,5 +226,25 @@
     EXPECT_TRUE(errorCount > 0);
 }
 
+TEST(CollationTest, PassOnWhitelistedAtom) {
+    Atoms atoms;
+    int errorCount =
+            collate_atoms(ListedAtoms::descriptor(), &atoms);
+    EXPECT_EQ(errorCount, 0);
+    EXPECT_EQ(atoms.decls.size(), 2ul);
+}
+
+TEST(CollationTest, RecogniseWhitelistedAtom) {
+    Atoms atoms;
+    collate_atoms(ListedAtoms::descriptor(), &atoms);
+    for (const auto& atomDecl : atoms.decls) {
+        if (atomDecl.code == 1) {
+            EXPECT_TRUE(atomDecl.whitelisted);
+        } else {
+            EXPECT_FALSE(atomDecl.whitelisted);
+        }
+    }
+}
+
 }  // namespace stats_log_api_gen
 }  // namespace android
\ No newline at end of file