Merge "OOM score management"
diff --git a/api/current.txt b/api/current.txt
index 41211f6..f30bc69 100644
--- a/api/current.txt
+++ b/api/current.txt
@@ -10137,6 +10137,7 @@
     field public static final int FLAG_ACTIVITY_SINGLE_TOP = 536870912; // 0x20000000
     field public static final int FLAG_ACTIVITY_TASK_ON_HOME = 16384; // 0x4000
     field public static final int FLAG_DEBUG_LOG_RESOLUTION = 8; // 0x8
+    field public static final int FLAG_DIRECT_BOOT_AUTO = 256; // 0x100
     field public static final int FLAG_EXCLUDE_STOPPED_PACKAGES = 16; // 0x10
     field public static final int FLAG_FROM_BACKGROUND = 4; // 0x4
     field public static final int FLAG_GRANT_PERSISTABLE_URI_PERMISSION = 64; // 0x40
@@ -11388,6 +11389,7 @@
     field public static final int INSTALL_REASON_USER = 4; // 0x4
     field public static final int MATCH_ALL = 131072; // 0x20000
     field public static final int MATCH_DEFAULT_ONLY = 65536; // 0x10000
+    field public static final int MATCH_DIRECT_BOOT_AUTO = 268435456; // 0x10000000
     field public static final int MATCH_DIRECT_BOOT_AWARE = 524288; // 0x80000
     field public static final int MATCH_DIRECT_BOOT_UNAWARE = 262144; // 0x40000
     field public static final int MATCH_DISABLED_COMPONENTS = 512; // 0x200
@@ -33207,6 +33209,7 @@
     method public android.os.StrictMode.VmPolicy.Builder detectCleartextNetwork();
     method public android.os.StrictMode.VmPolicy.Builder detectContentUriWithoutPermission();
     method public android.os.StrictMode.VmPolicy.Builder detectFileUriExposure();
+    method public android.os.StrictMode.VmPolicy.Builder detectImplicitDirectBoot();
     method public android.os.StrictMode.VmPolicy.Builder detectLeakedClosableObjects();
     method public android.os.StrictMode.VmPolicy.Builder detectLeakedRegistrationObjects();
     method public android.os.StrictMode.VmPolicy.Builder detectLeakedSqlLiteObjects();
@@ -33620,6 +33623,9 @@
   public final class FileUriExposedViolation extends android.os.strictmode.Violation {
   }
 
+  public final class ImplicitDirectBootViolation extends android.os.strictmode.Violation {
+  }
+
   public class InstanceCountViolation extends android.os.strictmode.Violation {
     method public long getNumberOfInstances();
   }
diff --git a/api/test-current.txt b/api/test-current.txt
index 1e76d4a..5d1f3e2 100644
--- a/api/test-current.txt
+++ b/api/test-current.txt
@@ -695,6 +695,7 @@
     field public static final int DETECT_VM_CONTENT_URI_WITHOUT_PERMISSION = 32768; // 0x8000
     field public static final int DETECT_VM_CURSOR_LEAKS = 256; // 0x100
     field public static final int DETECT_VM_FILE_URI_EXPOSURE = 8192; // 0x2000
+    field public static final int DETECT_VM_IMPLICIT_DIRECT_BOOT = 536870912; // 0x20000000
     field public static final int DETECT_VM_INSTANCE_LEAKS = 2048; // 0x800
     field public static final int DETECT_VM_NON_SDK_API_USAGE = 1073741824; // 0x40000000
     field public static final int DETECT_VM_REGISTRATION_LEAKS = 4096; // 0x1000
diff --git a/cmds/incident_helper/src/main.cpp b/cmds/incident_helper/src/main.cpp
index 418dc3f..5b6ac7a 100644
--- a/cmds/incident_helper/src/main.cpp
+++ b/cmds/incident_helper/src/main.cpp
@@ -73,7 +73,8 @@
         case 2006:
             return new BatteryTypeParser();
         default:
-            return NULL;
+            // Return no op parser when no specific ones are implemented.
+            return new NoopParser();
     }
 }
 
diff --git a/cmds/incidentd/src/IncidentService.cpp b/cmds/incidentd/src/IncidentService.cpp
index e305b54..e92cf94 100644
--- a/cmds/incidentd/src/IncidentService.cpp
+++ b/cmds/incidentd/src/IncidentService.cpp
@@ -314,6 +314,19 @@
             mThrottler->dump(out);
             return NO_ERROR;
         }
+        if (!args[0].compare(String8("section"))) {
+            int id = atoi(args[1]);
+            int idx = 0;
+            while (SECTION_LIST[idx] != NULL) {
+                const Section* section = SECTION_LIST[idx];
+                if (section->id == id) {
+                    fprintf(out, "Section[%d] %s\n", id, section->name.string());
+                    break;
+                }
+                idx++;
+            }
+            return NO_ERROR;
+        }
     }
     return cmd_help(out);
 }
@@ -321,8 +334,9 @@
 status_t IncidentService::cmd_help(FILE* out) {
     fprintf(out, "usage: adb shell cmd incident privacy print <section_id>\n");
     fprintf(out, "usage: adb shell cmd incident privacy parse <section_id> < proto.txt\n");
-    fprintf(out, "    Prints/parses for the section id.\n");
-    fprintf(out, "\n");
+    fprintf(out, "    Prints/parses for the section id.\n\n");
+    fprintf(out, "usage: adb shell cmd incident section <section_id>\n");
+    fprintf(out, "    Prints section id and its name.\n\n");
     fprintf(out, "usage: adb shell cmd incident throttler\n");
     fprintf(out, "    Prints the current throttler state\n");
     return NO_ERROR;
diff --git a/cmds/statsd/Android.mk b/cmds/statsd/Android.mk
index 0b5e358..1c20bff 100644
--- a/cmds/statsd/Android.mk
+++ b/cmds/statsd/Android.mk
@@ -71,7 +71,7 @@
     src/guardrail/StatsdStats.cpp \
     src/socket/StatsSocketListener.cpp
 
-# TODO: Once statsd is using a blueprint file, migrate to the proper filegroups.
+# TODO(b/110563449): Once statsd is using a blueprint file, migrate to the proper filegroups.
 statsd_common_src += \
     ../../../../system/extras/perfprofd/binder_interface/aidl/android/os/IPerfProfd.aidl \
     src/perfprofd/perfprofd_config.proto
diff --git a/cmds/statsd/src/FieldValue.h b/cmds/statsd/src/FieldValue.h
index 02c49b9..b1d6ab3 100644
--- a/cmds/statsd/src/FieldValue.h
+++ b/cmds/statsd/src/FieldValue.h
@@ -212,7 +212,7 @@
  * the result is equal to the Matcher Field. That's a bit wise AND operation + check if 2 ints are
  * equal. Nothing can beat the performance of this matching algorithm.
  *
- * TODO: ADD EXAMPLE HERE.
+ * TODO(b/110561213): ADD EXAMPLE HERE.
  */
 struct Matcher {
     Matcher(const Field& matcher, int32_t mask) : mMatcher(matcher), mMask(mask){};
diff --git a/cmds/statsd/src/HashableDimensionKey.cpp b/cmds/statsd/src/HashableDimensionKey.cpp
index 7103034..af8b3af 100644
--- a/cmds/statsd/src/HashableDimensionKey.cpp
+++ b/cmds/statsd/src/HashableDimensionKey.cpp
@@ -65,8 +65,6 @@
     for (const auto& value : values) {
         for (size_t i = 0; i < matcherFields.size(); ++i) {
             const auto& matcher = matcherFields[i];
-            // TODO: potential optimization here to break early because all fields are naturally
-            // sorted.
             if (value.mField.matches(matcher)) {
                 output->addValue(value);
                 output->mutableValue(num_matches)->mField.setTag(value.mField.getTag());
@@ -196,4 +194,4 @@
 
 }  // namespace statsd
 }  // namespace os
-}  // namespace android
\ No newline at end of file
+}  // namespace android
diff --git a/cmds/statsd/src/StatsService.cpp b/cmds/statsd/src/StatsService.cpp
index ae44ee9..1119eb3 100644
--- a/cmds/statsd/src/StatsService.cpp
+++ b/cmds/statsd/src/StatsService.cpp
@@ -440,7 +440,6 @@
     if (argCount == 2) {
         // Automatically pick the UID
         uid = IPCThreadState::self()->getCallingUid();
-        // TODO: What if this isn't a binder call? Should we fail?
         name.assign(args[1].c_str(), args[1].size());
         good = true;
     } else if (argCount == 3) {
@@ -493,7 +492,6 @@
             if (argCount == 3) {
                 // Automatically pick the UID
                 uid = IPCThreadState::self()->getCallingUid();
-                // TODO: What if this isn't a binder call? Should we fail?
                 name.assign(args[2].c_str(), args[2].size());
                 good = true;
             } else if (argCount == 4) {
@@ -578,7 +576,6 @@
         if (argCount == 2) {
             // Automatically pick the UID
             uid = IPCThreadState::self()->getCallingUid();
-            // TODO: What if this isn't a binder call? Should we fail?
             name.assign(args[1].c_str(), args[1].size());
             good = true;
         } else if (argCount == 3) {
@@ -604,7 +601,6 @@
             vector<uint8_t> data;
             mProcessor->onDumpReport(ConfigKey(uid, StrToInt64(name)), getElapsedRealtimeNs(),
                                      false /* include_current_bucket*/, ADB_DUMP, &data);
-            // TODO: print the returned StatsLogReport to file instead of printing to logcat.
             if (proto) {
                 for (size_t i = 0; i < data.size(); i ++) {
                     fprintf(out, "%c", data[i]);
diff --git a/cmds/statsd/src/StatsService.h b/cmds/statsd/src/StatsService.h
index 0a11f7c..ed90050 100644
--- a/cmds/statsd/src/StatsService.h
+++ b/cmds/statsd/src/StatsService.h
@@ -49,7 +49,6 @@
     virtual ~StatsService();
 
     /** The anomaly alarm registered with AlarmManager won't be updated by less than this. */
-    // TODO: Consider making this configurable. And choose a good number.
     const uint32_t MIN_DIFF_TO_UPDATE_REGISTERED_ALARM_SECS = 5;
 
     virtual status_t onTransact(uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags);
diff --git a/cmds/statsd/src/anomaly/AlarmMonitor.cpp b/cmds/statsd/src/anomaly/AlarmMonitor.cpp
index 78f0c2b..bc36dad 100644
--- a/cmds/statsd/src/anomaly/AlarmMonitor.cpp
+++ b/cmds/statsd/src/anomaly/AlarmMonitor.cpp
@@ -60,7 +60,7 @@
         ALOGW("Asked to add a 0-time alarm.");
         return;
     }
-    // TODO: Ensure that refractory period is respected.
+    // TODO(b/110563466): Ensure that refractory period is respected.
     VLOG("Adding alarm with time %u", alarm->timestampSec);
     mPq.push(alarm);
     if (mRegisteredAlarmTimeSec < 1 ||
diff --git a/cmds/statsd/src/anomaly/AnomalyTracker.cpp b/cmds/statsd/src/anomaly/AnomalyTracker.cpp
index f32efee..ee111cd 100644
--- a/cmds/statsd/src/anomaly/AnomalyTracker.cpp
+++ b/cmds/statsd/src/anomaly/AnomalyTracker.cpp
@@ -208,7 +208,8 @@
 }
 
 void AnomalyTracker::declareAnomaly(const int64_t& timestampNs, const MetricDimensionKey& key) {
-    // TODO: Why receive timestamp? RefractoryPeriod should always be based on real time right now.
+    // TODO(b/110563466): Why receive timestamp? RefractoryPeriod should always be based on
+    // real time right now.
     if (isInRefractoryPeriod(timestampNs, key)) {
         VLOG("Skipping anomaly declaration since within refractory period");
         return;
@@ -216,7 +217,8 @@
     if (mAlert.has_refractory_period_secs()) {
         mRefractoryPeriodEndsSec[key] = ((timestampNs + NS_PER_SEC - 1) / NS_PER_SEC) // round up
                                         + mAlert.refractory_period_secs();
-        // TODO: If we had access to the bucket_size_millis, consider calling resetStorage()
+        // TODO(b/110563466): If we had access to the bucket_size_millis, consider
+        // calling resetStorage()
         // if (mAlert.refractory_period_secs() > mNumOfPastBuckets * bucketSizeNs) {resetStorage();}
     }
 
@@ -230,7 +232,7 @@
 
     StatsdStats::getInstance().noteAnomalyDeclared(mConfigKey, mAlert.id());
 
-    // TODO: This should also take in the const MetricDimensionKey& key?
+    // TODO(b/110564268): This should also take in the const MetricDimensionKey& key?
     android::util::stats_write(android::util::ANOMALY_DETECTED, mConfigKey.GetUid(),
                                mConfigKey.GetId(), mAlert.id());
 }
diff --git a/cmds/statsd/src/external/ResourceHealthManagerPuller.cpp b/cmds/statsd/src/external/ResourceHealthManagerPuller.cpp
index 3741202..ae97d7a 100644
--- a/cmds/statsd/src/external/ResourceHealthManagerPuller.cpp
+++ b/cmds/statsd/src/external/ResourceHealthManagerPuller.cpp
@@ -54,7 +54,7 @@
 ResourceHealthManagerPuller::ResourceHealthManagerPuller(int tagId) : StatsPuller(tagId) {
 }
 
-// TODO: add other health atoms (eg. Temperature).
+// TODO(b/110565992): add other health atoms (eg. Temperature).
 bool ResourceHealthManagerPuller::PullInternal(vector<shared_ptr<LogEvent>>* data) {
     if (!getHealthHal()) {
         ALOGE("Health Hal not loaded");
diff --git a/cmds/statsd/src/guardrail/StatsdStats.cpp b/cmds/statsd/src/guardrail/StatsdStats.cpp
index 764366f..038cb95 100644
--- a/cmds/statsd/src/guardrail/StatsdStats.cpp
+++ b/cmds/statsd/src/guardrail/StatsdStats.cpp
@@ -103,7 +103,6 @@
         {android::util::CPU_TIME_PER_UID_FREQ, {6000, 10000}},
 };
 
-// TODO: add stats for pulled atoms.
 StatsdStats::StatsdStats() {
     mPushedAtomStats.resize(android::util::kMaxPushedAtomId + 1);
     mStartTimeSec = getWallClockSec();
diff --git a/cmds/statsd/src/guardrail/StatsdStats.h b/cmds/statsd/src/guardrail/StatsdStats.h
index 74541d3..9fb2cd8 100644
--- a/cmds/statsd/src/guardrail/StatsdStats.h
+++ b/cmds/statsd/src/guardrail/StatsdStats.h
@@ -86,7 +86,6 @@
     static StatsdStats& getInstance();
     ~StatsdStats(){};
 
-    // TODO: set different limit if the device is low ram.
     const static int kDimensionKeySizeSoftLimit = 500;
     const static int kDimensionKeySizeHardLimit = 800;
 
diff --git a/cmds/statsd/src/logd/LogEvent.cpp b/cmds/statsd/src/logd/LogEvent.cpp
index 4e4f146..04d34f3 100644
--- a/cmds/statsd/src/logd/LogEvent.cpp
+++ b/cmds/statsd/src/logd/LogEvent.cpp
@@ -273,7 +273,7 @@
 }
 
 int64_t LogEvent::GetLong(size_t key, status_t* err) const {
-    // TODO: encapsulate the magical operations all in Field struct as a static function.
+    // TODO(b/110561208): encapsulate the magical operations in Field struct as static functions
     int field = getSimpleField(key);
     for (const auto& value : mValues) {
         if (value.mField.getField() == field) {
diff --git a/cmds/statsd/src/main.cpp b/cmds/statsd/src/main.cpp
index 6aa68da..2f15d0f 100644
--- a/cmds/statsd/src/main.cpp
+++ b/cmds/statsd/src/main.cpp
@@ -82,7 +82,6 @@
     if (err != NO_ERROR) {
         return err;
     }
-    // TODO: Do we need to tweak thread priority?
     err = pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
     if (err != NO_ERROR) {
         pthread_attr_destroy(&attr);
diff --git a/cmds/statsd/src/matchers/LogMatchingTracker.h b/cmds/statsd/src/matchers/LogMatchingTracker.h
index 4f30a04..88ab4e6 100644
--- a/cmds/statsd/src/matchers/LogMatchingTracker.h
+++ b/cmds/statsd/src/matchers/LogMatchingTracker.h
@@ -86,8 +86,6 @@
     // The collection of the event tag ids that this LogMatchingTracker cares. So we can quickly
     // return kNotMatched when we receive an event with an id not in the list. This is especially
     // useful when we have a complex CombinationLogMatcherTracker.
-    // TODO: Consider use an array instead of stl set. In reality, the number of the tag ids a
-    // LogMatchingTracker cares is only a few.
     std::set<int> mAtomIds;
 };
 
diff --git a/cmds/statsd/src/metrics/CountMetricProducer.cpp b/cmds/statsd/src/metrics/CountMetricProducer.cpp
index 43f53e0..a894782 100644
--- a/cmds/statsd/src/metrics/CountMetricProducer.cpp
+++ b/cmds/statsd/src/metrics/CountMetricProducer.cpp
@@ -68,7 +68,6 @@
                                          const sp<ConditionWizard>& wizard,
                                          const int64_t startTimeNs)
     : MetricProducer(metric.id(), key, startTimeNs, conditionIndex, wizard) {
-    // TODO: evaluate initial conditions. and set mConditionMet.
     if (metric.has_bucket()) {
         mBucketSizeNs =
                 TimeUnitToBucketSizeInMillisGuardrailed(key.GetUid(), metric.bucket()) * 1000000;
diff --git a/cmds/statsd/src/metrics/CountMetricProducer.h b/cmds/statsd/src/metrics/CountMetricProducer.h
index 139c083..520d5de 100644
--- a/cmds/statsd/src/metrics/CountMetricProducer.h
+++ b/cmds/statsd/src/metrics/CountMetricProducer.h
@@ -40,7 +40,6 @@
 
 class CountMetricProducer : public MetricProducer {
 public:
-    // TODO: Pass in the start time from MetricsManager, it should be consistent for all metrics.
     CountMetricProducer(const ConfigKey& key, const CountMetric& countMetric,
                         const int conditionIndex, const sp<ConditionWizard>& wizard,
                         const int64_t startTimeNs);
@@ -80,7 +79,6 @@
 
     void flushCurrentBucketLocked(const int64_t& eventTimeNs) override;
 
-    // TODO: Add a lock to mPastBuckets.
     std::unordered_map<MetricDimensionKey, std::vector<CountBucket>> mPastBuckets;
 
     // The current bucket (may be a partial bucket).
diff --git a/cmds/statsd/src/metrics/DurationMetricProducer.cpp b/cmds/statsd/src/metrics/DurationMetricProducer.cpp
index 62237bc..a19eb0b 100644
--- a/cmds/statsd/src/metrics/DurationMetricProducer.cpp
+++ b/cmds/statsd/src/metrics/DurationMetricProducer.cpp
@@ -76,9 +76,6 @@
       mStopAllIndex(stopAllIndex),
       mNested(nesting),
       mContainANYPositionInInternalDimensions(false) {
-    // TODO: The following boiler plate code appears in all MetricProducers, but we can't abstract
-    // them in the base class, because the proto generated CountMetric, and DurationMetric are
-    // not related. Maybe we should add a template in the future??
     if (metric.has_bucket()) {
         mBucketSizeNs =
                 TimeUnitToBucketSizeInMillisGuardrailed(key.GetUid(), metric.bucket()) * 1000000;
@@ -434,8 +431,6 @@
     VLOG("Metric %lld onConditionChanged", (long long)mMetricId);
     mCondition = conditionMet;
     flushIfNeededLocked(eventTime);
-    // TODO: need to populate the condition change time from the event which triggers the condition
-    // change, instead of using current time.
     for (auto& whatIt : mCurrentSlicedDurationTrackerMap) {
         for (auto& pair : whatIt.second) {
             pair.second->onConditionChanged(conditionMet, eventTime);
diff --git a/cmds/statsd/src/metrics/DurationMetricProducer.h b/cmds/statsd/src/metrics/DurationMetricProducer.h
index 88e455a..c496b12 100644
--- a/cmds/statsd/src/metrics/DurationMetricProducer.h
+++ b/cmds/statsd/src/metrics/DurationMetricProducer.h
@@ -115,7 +115,6 @@
     ConditionState mUnSlicedPartCondition;
 
     // Save the past buckets and we can clear when the StatsLogReport is dumped.
-    // TODO: Add a lock to mPastBuckets.
     std::unordered_map<MetricDimensionKey, std::vector<DurationBucket>> mPastBuckets;
 
     // The duration trackers in the current bucket.
diff --git a/cmds/statsd/src/metrics/EventMetricProducer.h b/cmds/statsd/src/metrics/EventMetricProducer.h
index 62d1105..7f7aa37 100644
--- a/cmds/statsd/src/metrics/EventMetricProducer.h
+++ b/cmds/statsd/src/metrics/EventMetricProducer.h
@@ -33,7 +33,6 @@
 
 class EventMetricProducer : public MetricProducer {
 public:
-    // TODO: Pass in the start time from MetricsManager, it should be consistent for all metrics.
     EventMetricProducer(const ConfigKey& key, const EventMetric& eventMetric,
                         const int conditionIndex, const sp<ConditionWizard>& wizard,
                         const int64_t startTimeNs);
diff --git a/cmds/statsd/src/metrics/GaugeMetricProducer.cpp b/cmds/statsd/src/metrics/GaugeMetricProducer.cpp
index d75bb10..a779410 100644
--- a/cmds/statsd/src/metrics/GaugeMetricProducer.cpp
+++ b/cmds/statsd/src/metrics/GaugeMetricProducer.cpp
@@ -101,7 +101,6 @@
         translateFieldMatcher(metric.gauge_fields_filter().fields(), &mFieldMatchers);
     }
 
-    // TODO: use UidMap if uid->pkg_name is required
     if (metric.has_dimensions_in_what()) {
         translateFieldMatcher(metric.dimensions_in_what(), &mDimensionsInWhat);
         mContainANYPositionInDimensionsInWhat = HasPositionANY(metric.dimensions_in_what());
@@ -299,7 +298,6 @@
     protoOutput->end(protoToken);
 
     mPastBuckets.clear();
-    // TODO: Clear mDimensionKeyMap once the report is dumped.
 }
 
 void GaugeMetricProducer::pullLocked(const int64_t timestampNs) {
diff --git a/cmds/statsd/src/metrics/GaugeMetricProducer.h b/cmds/statsd/src/metrics/GaugeMetricProducer.h
index 62ec27eb..89b1f41 100644
--- a/cmds/statsd/src/metrics/GaugeMetricProducer.h
+++ b/cmds/statsd/src/metrics/GaugeMetricProducer.h
@@ -122,7 +122,6 @@
     const int mPullTagId;
 
     // Save the past buckets and we can clear when the StatsLogReport is dumped.
-    // TODO: Add a lock to mPastBuckets.
     std::unordered_map<MetricDimensionKey, std::vector<GaugeBucket>> mPastBuckets;
 
     // The current partial bucket.
diff --git a/cmds/statsd/src/metrics/MetricsManager.cpp b/cmds/statsd/src/metrics/MetricsManager.cpp
index 213f9ab..0e5ef4d 100644
--- a/cmds/statsd/src/metrics/MetricsManager.cpp
+++ b/cmds/statsd/src/metrics/MetricsManager.cpp
@@ -238,7 +238,6 @@
 
     if (event.GetTagId() == android::util::APP_BREADCRUMB_REPORTED) {
         // Check that app breadcrumb reported fields are valid.
-        // TODO: Find a way to make these checks easier to maintain.
         status_t err = NO_ERROR;
 
         // Uid is 3rd from last field and must match the caller's uid,
diff --git a/cmds/statsd/src/metrics/ValueMetricProducer.cpp b/cmds/statsd/src/metrics/ValueMetricProducer.cpp
index ef8b6cc..f5e953a 100644
--- a/cmds/statsd/src/metrics/ValueMetricProducer.cpp
+++ b/cmds/statsd/src/metrics/ValueMetricProducer.cpp
@@ -89,7 +89,6 @@
                                   ? StatsdStats::kAtomDimensionKeySizeLimitMap.at(pullTagId).second
                                   : StatsdStats::kDimensionKeySizeHardLimit),
       mUseAbsoluteValueOnReset(metric.use_absolute_value_on_reset()) {
-    // TODO: valuemetric for pushed events may need unlimited bucket length
     int64_t bucketSizeMills = 0;
     if (metric.has_bucket()) {
         bucketSizeMills = TimeUnitToBucketSizeInMillisGuardrailed(key.GetUid(), metric.bucket());
diff --git a/cmds/statsd/src/metrics/ValueMetricProducer.h b/cmds/statsd/src/metrics/ValueMetricProducer.h
index 75f3113..943d6dc 100644
--- a/cmds/statsd/src/metrics/ValueMetricProducer.h
+++ b/cmds/statsd/src/metrics/ValueMetricProducer.h
@@ -144,7 +144,6 @@
     std::unordered_map<MetricDimensionKey, int64_t> mCurrentFullBucket;
 
     // Save the past buckets and we can clear when the StatsLogReport is dumped.
-    // TODO: Add a lock to mPastBuckets.
     std::unordered_map<MetricDimensionKey, std::vector<ValueBucket>> mPastBuckets;
 
     // Pairs of (elapsed start, elapsed end) denoting buckets that were skipped.
diff --git a/cmds/statsd/src/metrics/duration_helper/DurationTracker.h b/cmds/statsd/src/metrics/duration_helper/DurationTracker.h
index 149b318..ccb1d43 100644
--- a/cmds/statsd/src/metrics/duration_helper/DurationTracker.h
+++ b/cmds/statsd/src/metrics/duration_helper/DurationTracker.h
@@ -44,7 +44,6 @@
     int64_t lastStartTime;
     // existing duration in current bucket.
     int64_t lastDuration;
-    // TODO: Optimize the way we track sliced condition in duration metrics.
     // cache the HashableDimensionKeys we need to query the condition for this duration event.
     ConditionKey conditionKeys;
 
diff --git a/cmds/statsd/src/metrics/duration_helper/OringDurationTracker.cpp b/cmds/statsd/src/metrics/duration_helper/OringDurationTracker.cpp
index b833dfc..956383a 100644
--- a/cmds/statsd/src/metrics/duration_helper/OringDurationTracker.cpp
+++ b/cmds/statsd/src/metrics/duration_helper/OringDurationTracker.cpp
@@ -326,7 +326,6 @@
 
 int64_t OringDurationTracker::predictAnomalyTimestampNs(
         const DurationAnomalyTracker& anomalyTracker, const int64_t eventTimestampNs) const {
-    // TODO: Unit-test this and see if it can be done more efficiently (e.g. use int32).
 
     // The anomaly threshold.
     const int64_t thresholdNs = anomalyTracker.getAnomalyThreshold();
diff --git a/cmds/statsd/src/metrics/metrics_manager_util.cpp b/cmds/statsd/src/metrics/metrics_manager_util.cpp
index deb9893..e03edb3 100644
--- a/cmds/statsd/src/metrics/metrics_manager_util.cpp
+++ b/cmds/statsd/src/metrics/metrics_manager_util.cpp
@@ -103,7 +103,6 @@
         }
         allConditionTrackers[condition_it->second]->setSliced(true);
         allConditionTrackers[it->second]->setSliced(true);
-        // TODO: We need to verify the link is valid.
     }
     conditionIndex = condition_it->second;
 
@@ -169,7 +168,6 @@
 bool isStateTracker(const SimplePredicate& simplePredicate, vector<Matcher>* primaryKeys) {
     // 1. must not have "stop". must have "dimension"
     if (!simplePredicate.has_stop() && simplePredicate.has_dimensions()) {
-        // TODO: need to check the start atom matcher too.
         auto it = android::util::AtomsInfo::kStateAtomsFieldOptions.find(
                 simplePredicate.dimensions().field());
         // 2. must be based on a state atom.
diff --git a/cmds/statsd/src/packages/UidMap.h b/cmds/statsd/src/packages/UidMap.h
index 514eec7..91f2030 100644
--- a/cmds/statsd/src/packages/UidMap.h
+++ b/cmds/statsd/src/packages/UidMap.h
@@ -146,7 +146,6 @@
 
     void getListenerListCopyLocked(std::vector<wp<PackageInfoListener>>* output);
 
-    // TODO: Use shared_mutex for improved read-locking if a library can be found in Android.
     mutable mutex mMutex;
     mutable mutex mIsolatedMutex;
 
diff --git a/cmds/statsd/src/storage/StorageManager.cpp b/cmds/statsd/src/storage/StorageManager.cpp
index 1f81812..3ebc8a4 100644
--- a/cmds/statsd/src/storage/StorageManager.cpp
+++ b/cmds/statsd/src/storage/StorageManager.cpp
@@ -57,7 +57,7 @@
     }
     // When index ends before hitting 3, file name is corrupted. We
     // intentionally put -1 at index 0 to indicate the error to caller.
-    // TODO: consider removing files with unexpected name format.
+    // TODO(b/110563137): consider removing files with unexpected name format.
     if (index < 3) {
         result[0] = -1;
     }
diff --git a/cmds/statsd/tests/FieldValue_test.cpp b/cmds/statsd/tests/FieldValue_test.cpp
index c253bc1..a9305ac 100644
--- a/cmds/statsd/tests/FieldValue_test.cpp
+++ b/cmds/statsd/tests/FieldValue_test.cpp
@@ -312,7 +312,8 @@
     dim.addValue(FieldValue(field4, value4));
 
     SubscriberReporter::getStatsDimensionsValue(dim);
-    // TODO: can't test anything here because SubscriberReport class doesn't have any read api.
+    // TODO(b/110562792): can't test anything here because StatsDimensionsValue class doesn't
+    // have any read api.
 }
 
 TEST(AtomMatcherTest, TestWriteDimensionToProto) {
@@ -483,4 +484,4 @@
 }  // namespace android
 #else
 GTEST_LOG_(INFO) << "This test does nothing.\n";
-#endif
\ No newline at end of file
+#endif
diff --git a/cmds/statsd/tests/MetricsManager_test.cpp b/cmds/statsd/tests/MetricsManager_test.cpp
index 4de9986..8fbb58a 100644
--- a/cmds/statsd/tests/MetricsManager_test.cpp
+++ b/cmds/statsd/tests/MetricsManager_test.cpp
@@ -39,8 +39,6 @@
 
 #ifdef __ANDROID__
 
-// TODO: ADD MORE TEST CASES.
-
 const ConfigKey kConfigKey(0, 12345);
 
 const long timeBaseSec = 1000;
diff --git a/cmds/statsd/tests/e2e/MetricConditionLink_e2e_test.cpp b/cmds/statsd/tests/e2e/MetricConditionLink_e2e_test.cpp
index 11aaab0..cc8894b 100644
--- a/cmds/statsd/tests/e2e/MetricConditionLink_e2e_test.cpp
+++ b/cmds/statsd/tests/e2e/MetricConditionLink_e2e_test.cpp
@@ -99,7 +99,6 @@
 
 // If we want to test multiple dump data, we must do it in separate tests, because in the e2e tests,
 // we should use the real API which will clear the data after dump data is called.
-// TODO: better refactor the code so that the tests are not so verbose.
 TEST(MetricConditionLinkE2eTest, TestMultiplePredicatesAndLinks1) {
     auto config = CreateStatsdConfig();
     uint64_t bucketStartTimeNs = 10000000000;
diff --git a/cmds/statsd/tests/metrics/EventMetricProducer_test.cpp b/cmds/statsd/tests/metrics/EventMetricProducer_test.cpp
index 3a15466..d2fd95c 100644
--- a/cmds/statsd/tests/metrics/EventMetricProducer_test.cpp
+++ b/cmds/statsd/tests/metrics/EventMetricProducer_test.cpp
@@ -54,8 +54,8 @@
     eventProducer.onMatchedLogEvent(1 /*matcher index*/, event1);
     eventProducer.onMatchedLogEvent(1 /*matcher index*/, event2);
 
-    // TODO: get the report and check the content after the ProtoOutputStream change is done.
-    // eventProducer.onDumpReport();
+    // TODO(b/110561136): get the report and check the content after the ProtoOutputStream change
+    // is done eventProducer.onDumpReport();
 }
 
 TEST(EventMetricProducerTest, TestEventsWithNonSlicedCondition) {
diff --git a/cmds/statsd/tests/metrics/GaugeMetricProducer_test.cpp b/cmds/statsd/tests/metrics/GaugeMetricProducer_test.cpp
index c7e72f9..19c9f77 100644
--- a/cmds/statsd/tests/metrics/GaugeMetricProducer_test.cpp
+++ b/cmds/statsd/tests/metrics/GaugeMetricProducer_test.cpp
@@ -59,8 +59,6 @@
 
     sp<MockConditionWizard> wizard = new NaggyMock<MockConditionWizard>();
 
-    // TODO: pending refactor of StatsPullerManager
-    // For now we still need this so that it doesn't do real pulling.
     sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>();
     EXPECT_CALL(*pullerManager, RegisterReceiver(tagId, _, _, _)).WillOnce(Return());
     EXPECT_CALL(*pullerManager, UnRegisterReceiver(tagId, _)).WillOnce(Return());
diff --git a/cmds/statsd/tests/metrics/ValueMetricProducer_test.cpp b/cmds/statsd/tests/metrics/ValueMetricProducer_test.cpp
index d93b46f..5195f01 100644
--- a/cmds/statsd/tests/metrics/ValueMetricProducer_test.cpp
+++ b/cmds/statsd/tests/metrics/ValueMetricProducer_test.cpp
@@ -60,8 +60,6 @@
     metric.mutable_value_field()->add_child()->set_field(2);
 
     sp<MockConditionWizard> wizard = new NaggyMock<MockConditionWizard>();
-    // TODO: pending refactor of StatsPullerManager
-    // For now we still need this so that it doesn't do real pulling.
     sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>();
     EXPECT_CALL(*pullerManager, RegisterReceiver(tagId, _, _, _)).WillOnce(Return());
     EXPECT_CALL(*pullerManager, UnRegisterReceiver(tagId, _)).WillOnce(Return());
diff --git a/core/java/android/animation/IntEvaluator.java b/core/java/android/animation/IntEvaluator.java
index 34fb0dc..1de2ae7 100644
--- a/core/java/android/animation/IntEvaluator.java
+++ b/core/java/android/animation/IntEvaluator.java
@@ -24,7 +24,7 @@
     /**
      * This function returns the result of linearly interpolating the start and end values, with
      * <code>fraction</code> representing the proportion between the start and end values. The
-     * calculation is a simple parametric calculation: <code>result = x0 + t * (v1 - v0)</code>,
+     * calculation is a simple parametric calculation: <code>result = x0 + t * (x1 - x0)</code>,
      * where <code>x0</code> is <code>startValue</code>, <code>x1</code> is <code>endValue</code>,
      * and <code>t</code> is <code>fraction</code>.
      *
@@ -39,4 +39,4 @@
         int startInt = startValue;
         return (int)(startInt + fraction * (endValue - startInt));
     }
-}
\ No newline at end of file
+}
diff --git a/core/java/android/app/ApplicationPackageManager.java b/core/java/android/app/ApplicationPackageManager.java
index 0e44833..344610a 100644
--- a/core/java/android/app/ApplicationPackageManager.java
+++ b/core/java/android/app/ApplicationPackageManager.java
@@ -73,6 +73,7 @@
 import android.os.PersistableBundle;
 import android.os.Process;
 import android.os.RemoteException;
+import android.os.StrictMode;
 import android.os.SystemProperties;
 import android.os.UserHandle;
 import android.os.UserManager;
@@ -149,15 +150,16 @@
     @Override
     public PackageInfo getPackageInfo(String packageName, int flags)
             throws NameNotFoundException {
-        return getPackageInfoAsUser(packageName, flags, mContext.getUserId());
+        return getPackageInfoAsUser(packageName, flags, getUserId());
     }
 
     @Override
     public PackageInfo getPackageInfo(VersionedPackage versionedPackage, int flags)
             throws NameNotFoundException {
+        final int userId = getUserId();
         try {
-            PackageInfo pi = mPM.getPackageInfoVersioned(versionedPackage, flags,
-                    mContext.getUserId());
+            PackageInfo pi = mPM.getPackageInfoVersioned(versionedPackage,
+                    updateFlagsForPackage(flags, userId), userId);
             if (pi != null) {
                 return pi;
             }
@@ -171,7 +173,8 @@
     public PackageInfo getPackageInfoAsUser(String packageName, int flags, int userId)
             throws NameNotFoundException {
         try {
-            PackageInfo pi = mPM.getPackageInfo(packageName, flags, userId);
+            PackageInfo pi = mPM.getPackageInfo(packageName,
+                    updateFlagsForPackage(flags, userId), userId);
             if (pi != null) {
                 return pi;
             }
@@ -262,8 +265,10 @@
     @Override
     public int[] getPackageGids(String packageName, int flags)
             throws NameNotFoundException {
+        final int userId = getUserId();
         try {
-            int[] gids = mPM.getPackageGids(packageName, flags, mContext.getUserId());
+            int[] gids = mPM.getPackageGids(packageName,
+                    updateFlagsForPackage(flags, userId), userId);
             if (gids != null) {
                 return gids;
             }
@@ -276,7 +281,7 @@
 
     @Override
     public int getPackageUid(String packageName, int flags) throws NameNotFoundException {
-        return getPackageUidAsUser(packageName, flags, mContext.getUserId());
+        return getPackageUidAsUser(packageName, flags, getUserId());
     }
 
     @Override
@@ -288,7 +293,8 @@
     public int getPackageUidAsUser(String packageName, int flags, int userId)
             throws NameNotFoundException {
         try {
-            int uid = mPM.getPackageUid(packageName, flags, userId);
+            int uid = mPM.getPackageUid(packageName,
+                    updateFlagsForPackage(flags, userId), userId);
             if (uid >= 0) {
                 return uid;
             }
@@ -374,14 +380,15 @@
     @Override
     public ApplicationInfo getApplicationInfo(String packageName, int flags)
             throws NameNotFoundException {
-        return getApplicationInfoAsUser(packageName, flags, mContext.getUserId());
+        return getApplicationInfoAsUser(packageName, flags, getUserId());
     }
 
     @Override
     public ApplicationInfo getApplicationInfoAsUser(String packageName, int flags, int userId)
             throws NameNotFoundException {
         try {
-            ApplicationInfo ai = mPM.getApplicationInfo(packageName, flags, userId);
+            ApplicationInfo ai = mPM.getApplicationInfo(packageName,
+                    updateFlagsForApplication(flags, userId), userId);
             if (ai != null) {
                 // This is a temporary hack. Callers must use
                 // createPackageContext(packageName).getApplicationInfo() to
@@ -423,8 +430,10 @@
     @Override
     public ActivityInfo getActivityInfo(ComponentName className, int flags)
             throws NameNotFoundException {
+        final int userId = getUserId();
         try {
-            ActivityInfo ai = mPM.getActivityInfo(className, flags, mContext.getUserId());
+            ActivityInfo ai = mPM.getActivityInfo(className,
+                    updateFlagsForComponent(flags, userId, null), userId);
             if (ai != null) {
                 return ai;
             }
@@ -438,8 +447,10 @@
     @Override
     public ActivityInfo getReceiverInfo(ComponentName className, int flags)
             throws NameNotFoundException {
+        final int userId = getUserId();
         try {
-            ActivityInfo ai = mPM.getReceiverInfo(className, flags, mContext.getUserId());
+            ActivityInfo ai = mPM.getReceiverInfo(className,
+                    updateFlagsForComponent(flags, userId, null), userId);
             if (ai != null) {
                 return ai;
             }
@@ -453,8 +464,10 @@
     @Override
     public ServiceInfo getServiceInfo(ComponentName className, int flags)
             throws NameNotFoundException {
+        final int userId = getUserId();
         try {
-            ServiceInfo si = mPM.getServiceInfo(className, flags, mContext.getUserId());
+            ServiceInfo si = mPM.getServiceInfo(className,
+                    updateFlagsForComponent(flags, userId, null), userId);
             if (si != null) {
                 return si;
             }
@@ -468,8 +481,10 @@
     @Override
     public ProviderInfo getProviderInfo(ComponentName className, int flags)
             throws NameNotFoundException {
+        final int userId = getUserId();
         try {
-            ProviderInfo pi = mPM.getProviderInfo(className, flags, mContext.getUserId());
+            ProviderInfo pi = mPM.getProviderInfo(className,
+                    updateFlagsForComponent(flags, userId, null), userId);
             if (pi != null) {
                 return pi;
             }
@@ -492,7 +507,7 @@
     /** @hide */
     @Override
     public @NonNull List<SharedLibraryInfo> getSharedLibraries(int flags) {
-        return getSharedLibrariesAsUser(flags, mContext.getUserId());
+        return getSharedLibrariesAsUser(flags, getUserId());
     }
 
     /** @hide */
@@ -535,7 +550,7 @@
     @Override
     public ChangedPackages getChangedPackages(int sequenceNumber) {
         try {
-            return mPM.getChangedPackages(sequenceNumber, mContext.getUserId());
+            return mPM.getChangedPackages(sequenceNumber, getUserId());
         } catch (RemoteException e) {
             throw e.rethrowFromSystemServer();
         }
@@ -578,7 +593,7 @@
     @Override
     public int checkPermission(String permName, String pkgName) {
         try {
-            return mPM.checkPermission(permName, pkgName, mContext.getUserId());
+            return mPM.checkPermission(permName, pkgName, getUserId());
         } catch (RemoteException e) {
             throw e.rethrowFromSystemServer();
         }
@@ -587,7 +602,7 @@
     @Override
     public boolean isPermissionRevokedByPolicy(String permName, String pkgName) {
         try {
-            return mPM.isPermissionRevokedByPolicy(permName, pkgName, mContext.getUserId());
+            return mPM.isPermissionRevokedByPolicy(permName, pkgName, getUserId());
         } catch (RemoteException e) {
             throw e.rethrowFromSystemServer();
         }
@@ -681,7 +696,7 @@
     public boolean shouldShowRequestPermissionRationale(String permission) {
         try {
             return mPM.shouldShowRequestPermissionRationale(permission,
-                    mContext.getPackageName(), mContext.getUserId());
+                    mContext.getPackageName(), getUserId());
         } catch (RemoteException e) {
             throw e.rethrowFromSystemServer();
         }
@@ -769,7 +784,7 @@
     @SuppressWarnings("unchecked")
     @Override
     public List<PackageInfo> getInstalledPackages(int flags) {
-        return getInstalledPackagesAsUser(flags, mContext.getUserId());
+        return getInstalledPackagesAsUser(flags, getUserId());
     }
 
     /** @hide */
@@ -778,7 +793,7 @@
     public List<PackageInfo> getInstalledPackagesAsUser(int flags, int userId) {
         try {
             ParceledListSlice<PackageInfo> parceledList =
-                    mPM.getInstalledPackages(flags, userId);
+                    mPM.getInstalledPackages(updateFlagsForPackage(flags, userId), userId);
             if (parceledList == null) {
                 return Collections.emptyList();
             }
@@ -792,10 +807,11 @@
     @Override
     public List<PackageInfo> getPackagesHoldingPermissions(
             String[] permissions, int flags) {
-        final int userId = mContext.getUserId();
+        final int userId = getUserId();
         try {
             ParceledListSlice<PackageInfo> parceledList =
-                    mPM.getPackagesHoldingPermissions(permissions, flags, userId);
+                    mPM.getPackagesHoldingPermissions(permissions,
+                            updateFlagsForPackage(flags, userId), userId);
             if (parceledList == null) {
                 return Collections.emptyList();
             }
@@ -808,7 +824,7 @@
     @SuppressWarnings("unchecked")
     @Override
     public List<ApplicationInfo> getInstalledApplications(int flags) {
-        return getInstalledApplicationsAsUser(flags, mContext.getUserId());
+        return getInstalledApplicationsAsUser(flags, getUserId());
     }
 
     /** @hide */
@@ -817,7 +833,7 @@
     public List<ApplicationInfo> getInstalledApplicationsAsUser(int flags, int userId) {
         try {
             ParceledListSlice<ApplicationInfo> parceledList =
-                    mPM.getInstalledApplications(flags, userId);
+                    mPM.getInstalledApplications(updateFlagsForApplication(flags, userId), userId);
             if (parceledList == null) {
                 return Collections.emptyList();
             }
@@ -832,8 +848,7 @@
     @Override
     public List<InstantAppInfo> getInstantApps() {
         try {
-            ParceledListSlice<InstantAppInfo> slice =
-                    mPM.getInstantApps(mContext.getUserId());
+            ParceledListSlice<InstantAppInfo> slice = mPM.getInstantApps(getUserId());
             if (slice != null) {
                 return slice.getList();
             }
@@ -847,8 +862,7 @@
     @Override
     public Drawable getInstantAppIcon(String packageName) {
         try {
-            Bitmap bitmap = mPM.getInstantAppIcon(
-                    packageName, mContext.getUserId());
+            Bitmap bitmap = mPM.getInstantAppIcon(packageName, getUserId());
             if (bitmap != null) {
                 return new BitmapDrawable(null, bitmap);
             }
@@ -866,7 +880,7 @@
     @Override
     public boolean isInstantApp(String packageName) {
         try {
-            return mPM.isInstantApp(packageName, mContext.getUserId());
+            return mPM.isInstantApp(packageName, getUserId());
         } catch (RemoteException e) {
             throw e.rethrowFromSystemServer();
         }
@@ -886,8 +900,7 @@
     @Override
     public @NonNull byte[] getInstantAppCookie() {
         try {
-            final byte[] cookie = mPM.getInstantAppCookie(
-                    mContext.getPackageName(), mContext.getUserId());
+            final byte[] cookie = mPM.getInstantAppCookie(mContext.getPackageName(), getUserId());
             if (cookie != null) {
                 return cookie;
             } else {
@@ -910,8 +923,7 @@
                     + getInstantAppCookieMaxBytes());
         }
         try {
-            mPM.setInstantAppCookie(mContext.getPackageName(),
-                    cookie, mContext.getUserId());
+            mPM.setInstantAppCookie(mContext.getPackageName(), cookie, getUserId());
         } catch (RemoteException e) {
             throw e.rethrowFromSystemServer();
         }
@@ -920,8 +932,7 @@
     @Override
     public boolean setInstantAppCookie(@NonNull byte[] cookie) {
         try {
-            return mPM.setInstantAppCookie(mContext.getPackageName(),
-                    cookie, mContext.getUserId());
+            return mPM.setInstantAppCookie(mContext.getPackageName(), cookie, getUserId());
         } catch (RemoteException e) {
             throw e.rethrowFromSystemServer();
         }
@@ -929,7 +940,7 @@
 
     @Override
     public ResolveInfo resolveActivity(Intent intent, int flags) {
-        return resolveActivityAsUser(intent, flags, mContext.getUserId());
+        return resolveActivityAsUser(intent, flags, getUserId());
     }
 
     @Override
@@ -938,7 +949,7 @@
             return mPM.resolveIntent(
                 intent,
                 intent.resolveTypeIfNeeded(mContext.getContentResolver()),
-                flags,
+                updateFlagsForComponent(flags, userId, intent),
                 userId);
         } catch (RemoteException e) {
             throw e.rethrowFromSystemServer();
@@ -948,7 +959,7 @@
     @Override
     public List<ResolveInfo> queryIntentActivities(Intent intent,
                                                    int flags) {
-        return queryIntentActivitiesAsUser(intent, flags, mContext.getUserId());
+        return queryIntentActivitiesAsUser(intent, flags, getUserId());
     }
 
     /** @hide Same as above but for a specific user */
@@ -957,10 +968,11 @@
     public List<ResolveInfo> queryIntentActivitiesAsUser(Intent intent,
             int flags, int userId) {
         try {
-            ParceledListSlice<ResolveInfo> parceledList =
-                    mPM.queryIntentActivities(intent,
-                            intent.resolveTypeIfNeeded(mContext.getContentResolver()),
-                            flags, userId);
+            ParceledListSlice<ResolveInfo> parceledList = mPM.queryIntentActivities(
+                    intent,
+                    intent.resolveTypeIfNeeded(mContext.getContentResolver()),
+                    updateFlagsForComponent(flags, userId, intent),
+                    userId);
             if (parceledList == null) {
                 return Collections.emptyList();
             }
@@ -972,9 +984,9 @@
 
     @Override
     @SuppressWarnings("unchecked")
-    public List<ResolveInfo> queryIntentActivityOptions(
-        ComponentName caller, Intent[] specifics, Intent intent,
-        int flags) {
+    public List<ResolveInfo> queryIntentActivityOptions(ComponentName caller, Intent[] specifics,
+            Intent intent, int flags) {
+        final int userId = getUserId();
         final ContentResolver resolver = mContext.getContentResolver();
 
         String[] specificTypes = null;
@@ -995,9 +1007,14 @@
         }
 
         try {
-            ParceledListSlice<ResolveInfo> parceledList =
-                    mPM.queryIntentActivityOptions(caller, specifics, specificTypes, intent,
-                    intent.resolveTypeIfNeeded(resolver), flags, mContext.getUserId());
+            ParceledListSlice<ResolveInfo> parceledList = mPM.queryIntentActivityOptions(
+                    caller,
+                    specifics,
+                    specificTypes,
+                    intent,
+                    intent.resolveTypeIfNeeded(resolver),
+                    updateFlagsForComponent(flags, userId, intent),
+                    userId);
             if (parceledList == null) {
                 return Collections.emptyList();
             }
@@ -1014,10 +1031,11 @@
     @SuppressWarnings("unchecked")
     public List<ResolveInfo> queryBroadcastReceiversAsUser(Intent intent, int flags, int userId) {
         try {
-            ParceledListSlice<ResolveInfo> parceledList =
-                    mPM.queryIntentReceivers(intent,
-                            intent.resolveTypeIfNeeded(mContext.getContentResolver()),
-                            flags,  userId);
+            ParceledListSlice<ResolveInfo> parceledList = mPM.queryIntentReceivers(
+                    intent,
+                    intent.resolveTypeIfNeeded(mContext.getContentResolver()),
+                    updateFlagsForComponent(flags, userId, intent),
+                    userId);
             if (parceledList == null) {
                 return Collections.emptyList();
             }
@@ -1029,7 +1047,7 @@
 
     @Override
     public List<ResolveInfo> queryBroadcastReceivers(Intent intent, int flags) {
-        return queryBroadcastReceiversAsUser(intent, flags, mContext.getUserId());
+        return queryBroadcastReceiversAsUser(intent, flags, getUserId());
     }
 
     @Override
@@ -1039,7 +1057,7 @@
             return mPM.resolveService(
                 intent,
                 intent.resolveTypeIfNeeded(mContext.getContentResolver()),
-                flags,
+                updateFlagsForComponent(flags, userId, intent),
                 userId);
         } catch (RemoteException e) {
             throw e.rethrowFromSystemServer();
@@ -1048,17 +1066,18 @@
 
     @Override
     public ResolveInfo resolveService(Intent intent, int flags) {
-        return resolveServiceAsUser(intent, flags, mContext.getUserId());
+        return resolveServiceAsUser(intent, flags, getUserId());
     }
 
     @Override
     @SuppressWarnings("unchecked")
     public List<ResolveInfo> queryIntentServicesAsUser(Intent intent, int flags, int userId) {
         try {
-            ParceledListSlice<ResolveInfo> parceledList =
-                    mPM.queryIntentServices(intent,
+            ParceledListSlice<ResolveInfo> parceledList = mPM.queryIntentServices(
+                    intent,
                     intent.resolveTypeIfNeeded(mContext.getContentResolver()),
-                    flags, userId);
+                    updateFlagsForComponent(flags, userId, intent),
+                    userId);
             if (parceledList == null) {
                 return Collections.emptyList();
             }
@@ -1070,7 +1089,7 @@
 
     @Override
     public List<ResolveInfo> queryIntentServices(Intent intent, int flags) {
-        return queryIntentServicesAsUser(intent, flags, mContext.getUserId());
+        return queryIntentServicesAsUser(intent, flags, getUserId());
     }
 
     @Override
@@ -1078,10 +1097,11 @@
     public List<ResolveInfo> queryIntentContentProvidersAsUser(
             Intent intent, int flags, int userId) {
         try {
-            ParceledListSlice<ResolveInfo> parceledList =
-                    mPM.queryIntentContentProviders(intent,
-                            intent.resolveTypeIfNeeded(mContext.getContentResolver()),
-                            flags, userId);
+            ParceledListSlice<ResolveInfo> parceledList = mPM.queryIntentContentProviders(
+                    intent,
+                    intent.resolveTypeIfNeeded(mContext.getContentResolver()),
+                    updateFlagsForComponent(flags, userId, intent),
+                    userId);
             if (parceledList == null) {
                 return Collections.emptyList();
             }
@@ -1093,19 +1113,20 @@
 
     @Override
     public List<ResolveInfo> queryIntentContentProviders(Intent intent, int flags) {
-        return queryIntentContentProvidersAsUser(intent, flags, mContext.getUserId());
+        return queryIntentContentProvidersAsUser(intent, flags, getUserId());
     }
 
     @Override
     public ProviderInfo resolveContentProvider(String name, int flags) {
-        return resolveContentProviderAsUser(name, flags, mContext.getUserId());
+        return resolveContentProviderAsUser(name, flags, getUserId());
     }
 
     /** @hide **/
     @Override
     public ProviderInfo resolveContentProviderAsUser(String name, int flags, int userId) {
         try {
-            return mPM.resolveContentProvider(name, flags, userId);
+            return mPM.resolveContentProvider(name,
+                    updateFlagsForComponent(flags, userId, null), userId);
         } catch (RemoteException e) {
             throw e.rethrowFromSystemServer();
         }
@@ -1122,8 +1143,8 @@
     public List<ProviderInfo> queryContentProviders(String processName,
             int uid, int flags, String metaDataKey) {
         try {
-            ParceledListSlice<ProviderInfo> slice =
-                    mPM.queryContentProviders(processName, uid, flags, metaDataKey);
+            ParceledListSlice<ProviderInfo> slice = mPM.queryContentProviders(processName, uid,
+                    updateFlagsForComponent(flags, UserHandle.getUserId(uid), null), metaDataKey);
             return slice != null ? slice.getList() : Collections.<ProviderInfo>emptyList();
         } catch (RemoteException e) {
             throw e.rethrowFromSystemServer();
@@ -1517,6 +1538,73 @@
         mPM = pm;
     }
 
+    /**
+     * Update given flags when being used to request {@link PackageInfo}.
+     */
+    private int updateFlagsForPackage(int flags, int userId) {
+        if ((flags & (GET_ACTIVITIES | GET_RECEIVERS | GET_SERVICES | GET_PROVIDERS)) != 0) {
+            // Caller is asking for component details, so they'd better be
+            // asking for specific Direct Boot matching behavior
+            if ((flags & (MATCH_DIRECT_BOOT_UNAWARE
+                    | MATCH_DIRECT_BOOT_AWARE
+                    | MATCH_DIRECT_BOOT_AUTO)) == 0) {
+                onImplicitDirectBoot(userId);
+            }
+        }
+        return flags;
+    }
+
+    /**
+     * Update given flags when being used to request {@link ApplicationInfo}.
+     */
+    private int updateFlagsForApplication(int flags, int userId) {
+        return updateFlagsForPackage(flags, userId);
+    }
+
+    /**
+     * Update given flags when being used to request {@link ComponentInfo}.
+     */
+    private int updateFlagsForComponent(int flags, int userId, Intent intent) {
+        if (intent != null) {
+            if ((intent.getFlags() & Intent.FLAG_DIRECT_BOOT_AUTO) != 0) {
+                flags |= MATCH_DIRECT_BOOT_AUTO;
+            }
+        }
+
+        // Caller is asking for component details, so they'd better be
+        // asking for specific Direct Boot matching behavior
+        if ((flags & (MATCH_DIRECT_BOOT_UNAWARE
+                | MATCH_DIRECT_BOOT_AWARE
+                | MATCH_DIRECT_BOOT_AUTO)) == 0) {
+            onImplicitDirectBoot(userId);
+        }
+        return flags;
+    }
+
+    private void onImplicitDirectBoot(int userId) {
+        // Only report if someone is relying on implicit behavior while the user
+        // is locked; code running when unlocked is going to see both aware and
+        // unaware components.
+        if (StrictMode.vmImplicitDirectBootEnabled()) {
+            // We can cache the unlocked state for the userId we're running as,
+            // since any relocking of that user will always result in our
+            // process being killed to release any CE FDs we're holding onto.
+            if (userId == UserHandle.myUserId()) {
+                if (mUserUnlocked) {
+                    return;
+                } else if (mContext.getSystemService(UserManager.class)
+                        .isUserUnlockingOrUnlocked(userId)) {
+                    mUserUnlocked = true;
+                } else {
+                    StrictMode.onImplicitDirectBoot();
+                }
+            } else if (!mContext.getSystemService(UserManager.class)
+                    .isUserUnlockingOrUnlocked(userId)) {
+                StrictMode.onImplicitDirectBoot();
+            }
+        }
+    }
+
     @Nullable
     private Drawable getCachedIcon(@NonNull ResourceName name) {
         synchronized (sSync) {
@@ -1730,7 +1818,7 @@
     @Override
     public int installExistingPackage(String packageName, int installReason)
             throws NameNotFoundException {
-        return installExistingPackageAsUser(packageName, installReason, mContext.getUserId());
+        return installExistingPackageAsUser(packageName, installReason, getUserId());
     }
 
     @Override
@@ -2089,7 +2177,7 @@
 
     @Override
     public void deletePackage(String packageName, IPackageDeleteObserver observer, int flags) {
-        deletePackageAsUser(packageName, observer, flags, mContext.getUserId());
+        deletePackageAsUser(packageName, observer, flags, getUserId());
     }
 
     @Override
@@ -2107,7 +2195,7 @@
     public void clearApplicationUserData(String packageName,
                                          IPackageDataObserver observer) {
         try {
-            mPM.clearApplicationUserData(packageName, observer, mContext.getUserId());
+            mPM.clearApplicationUserData(packageName, observer, getUserId());
         } catch (RemoteException e) {
             throw e.rethrowFromSystemServer();
         }
@@ -2158,7 +2246,7 @@
         try {
             return mPM.setPackagesSuspendedAsUser(packageNames, suspended, appExtras,
                     launcherExtras, dialogMessage, mContext.getOpPackageName(),
-                    mContext.getUserId());
+                    getUserId());
         } catch (RemoteException e) {
             throw e.rethrowFromSystemServer();
         }
@@ -2169,7 +2257,7 @@
         final PersistableBundle extras;
         try {
             extras = mPM.getSuspendedPackageAppExtras(mContext.getOpPackageName(),
-                    mContext.getUserId());
+                    getUserId());
         } catch (RemoteException e) {
             throw e.rethrowFromSystemServer();
         }
@@ -2189,7 +2277,7 @@
     @Override
     public boolean isPackageSuspended(String packageName) throws NameNotFoundException {
         try {
-            return isPackageSuspendedForUser(packageName, mContext.getUserId());
+            return isPackageSuspendedForUser(packageName, getUserId());
         } catch (IllegalArgumentException ie) {
             throw new NameNotFoundException(packageName);
         }
@@ -2197,7 +2285,7 @@
 
     @Override
     public boolean isPackageSuspended() {
-        return isPackageSuspendedForUser(mContext.getOpPackageName(), mContext.getUserId());
+        return isPackageSuspendedForUser(mContext.getOpPackageName(), getUserId());
     }
 
     /** @hide */
@@ -2247,7 +2335,7 @@
     public void addPreferredActivity(IntentFilter filter,
                                      int match, ComponentName[] set, ComponentName activity) {
         try {
-            mPM.addPreferredActivity(filter, match, set, activity, mContext.getUserId());
+            mPM.addPreferredActivity(filter, match, set, activity, getUserId());
         } catch (RemoteException e) {
             throw e.rethrowFromSystemServer();
         }
@@ -2267,7 +2355,7 @@
     public void replacePreferredActivity(IntentFilter filter,
                                          int match, ComponentName[] set, ComponentName activity) {
         try {
-            mPM.replacePreferredActivity(filter, match, set, activity, mContext.getUserId());
+            mPM.replacePreferredActivity(filter, match, set, activity, getUserId());
         } catch (RemoteException e) {
             throw e.rethrowFromSystemServer();
         }
@@ -2316,7 +2404,7 @@
     public void setComponentEnabledSetting(ComponentName componentName,
                                            int newState, int flags) {
         try {
-            mPM.setComponentEnabledSetting(componentName, newState, flags, mContext.getUserId());
+            mPM.setComponentEnabledSetting(componentName, newState, flags, getUserId());
         } catch (RemoteException e) {
             throw e.rethrowFromSystemServer();
         }
@@ -2325,7 +2413,7 @@
     @Override
     public int getComponentEnabledSetting(ComponentName componentName) {
         try {
-            return mPM.getComponentEnabledSetting(componentName, mContext.getUserId());
+            return mPM.getComponentEnabledSetting(componentName, getUserId());
         } catch (RemoteException e) {
             throw e.rethrowFromSystemServer();
         }
@@ -2336,7 +2424,7 @@
                                              int newState, int flags) {
         try {
             mPM.setApplicationEnabledSetting(packageName, newState, flags,
-                    mContext.getUserId(), mContext.getOpPackageName());
+                    getUserId(), mContext.getOpPackageName());
         } catch (RemoteException e) {
             throw e.rethrowFromSystemServer();
         }
@@ -2345,7 +2433,7 @@
     @Override
     public int getApplicationEnabledSetting(String packageName) {
         try {
-            return mPM.getApplicationEnabledSetting(packageName, mContext.getUserId());
+            return mPM.getApplicationEnabledSetting(packageName, getUserId());
         } catch (RemoteException e) {
             throw e.rethrowFromSystemServer();
         }
@@ -2457,7 +2545,7 @@
             if (mInstaller == null) {
                 try {
                     mInstaller = new PackageInstaller(mPM.getPackageInstaller(),
-                            mContext.getPackageName(), mContext.getUserId());
+                            mContext.getPackageName(), getUserId());
                 } catch (RemoteException e) {
                     throw e.rethrowFromSystemServer();
                 }
@@ -2469,7 +2557,7 @@
     @Override
     public boolean isPackageAvailable(String packageName) {
         try {
-            return mPM.isPackageAvailable(packageName, mContext.getUserId());
+            return mPM.isPackageAvailable(packageName, getUserId());
         } catch (RemoteException e) {
             throw e.rethrowFromSystemServer();
         }
@@ -2509,7 +2597,7 @@
         if (itemInfo.showUserIcon != UserHandle.USER_NULL) {
             return dr;
         }
-        return getUserBadgedIcon(dr, new UserHandle(mContext.getUserId()));
+        return getUserBadgedIcon(dr, new UserHandle(getUserId()));
     }
 
     /**
@@ -2657,6 +2745,9 @@
     private final ContextImpl mContext;
     private final IPackageManager mPM;
 
+    /** Assume locked until we hear otherwise */
+    private volatile boolean mUserUnlocked = false;
+
     private static final Object sSync = new Object();
     private static ArrayMap<ResourceName, WeakReference<Drawable.ConstantState>> sIconCache
             = new ArrayMap<ResourceName, WeakReference<Drawable.ConstantState>>();
@@ -2701,7 +2792,7 @@
     @Override
     public boolean canRequestPackageInstalls() {
         try {
-            return mPM.canRequestPackageInstalls(mContext.getPackageName(), mContext.getUserId());
+            return mPM.canRequestPackageInstalls(mContext.getPackageName(), getUserId());
         } catch (RemoteException e) {
             throw e.rethrowAsRuntimeException();
         }
@@ -2811,7 +2902,7 @@
     @Override
     public CharSequence getHarmfulAppWarning(String packageName) {
         try {
-            return mPM.getHarmfulAppWarning(packageName, mContext.getUserId());
+            return mPM.getHarmfulAppWarning(packageName, getUserId());
         } catch (RemoteException e) {
             throw e.rethrowAsRuntimeException();
         }
@@ -2820,7 +2911,7 @@
     @Override
     public void setHarmfulAppWarning(String packageName, CharSequence warning) {
         try {
-            mPM.setHarmfulAppWarning(packageName, warning, mContext.getUserId());
+            mPM.setHarmfulAppWarning(packageName, warning, getUserId());
         } catch (RemoteException e) {
             throw e.rethrowAsRuntimeException();
         }
diff --git a/core/java/android/app/WindowConfiguration.java b/core/java/android/app/WindowConfiguration.java
index 7a729f9..aea767e 100644
--- a/core/java/android/app/WindowConfiguration.java
+++ b/core/java/android/app/WindowConfiguration.java
@@ -488,7 +488,7 @@
                 + " mAppBounds=" + mAppBounds
                 + " mWindowingMode=" + windowingModeToString(mWindowingMode)
                 + " mActivityType=" + activityTypeToString(mActivityType)
-                + " mAlwaysOnTop=" + activityTypeToString(mAlwaysOnTop)
+                + " mAlwaysOnTop=" + alwaysOnTopToString(mAlwaysOnTop)
                 + "}";
     }
 
@@ -652,4 +652,14 @@
         }
         return String.valueOf(applicationType);
     }
+
+    /** @hide */
+    public static String alwaysOnTopToString(@AlwaysOnTop int alwaysOnTop) {
+        switch (alwaysOnTop) {
+            case ALWAYS_ON_TOP_UNDEFINED: return "undefined";
+            case ALWAYS_ON_TOP_ON: return "on";
+            case ALWAYS_ON_TOP_OFF: return "off";
+        }
+        return String.valueOf(alwaysOnTop);
+    }
 }
diff --git a/core/java/android/content/Intent.java b/core/java/android/content/Intent.java
index 631c4b7..78738e9 100644
--- a/core/java/android/content/Intent.java
+++ b/core/java/android/content/Intent.java
@@ -5372,19 +5372,23 @@
     public static final int FLAG_GRANT_PREFIX_URI_PERMISSION = 0x00000080;
 
     /**
-     * Internal flag used to indicate that a system component has done their
-     * homework and verified that they correctly handle packages and components
-     * that come and go over time. In particular:
-     * <ul>
-     * <li>Apps installed on external storage, which will appear to be
-     * uninstalled while the the device is ejected.
-     * <li>Apps with encryption unaware components, which will appear to not
-     * exist while the device is locked.
-     * </ul>
-     *
-     * @hide
+     * Flag used to automatically match intents based on their Direct Boot
+     * awareness and the current user state.
+     * <p>
+     * Since the default behavior is to automatically apply the current user
+     * state, this is effectively a sentinel value that doesn't change the
+     * output of any queries based on its presence or absence.
+     * <p>
+     * Instead, this value can be useful in conjunction with
+     * {@link android.os.StrictMode.VmPolicy.Builder#detectImplicitDirectBoot()}
+     * to detect when a caller is relying on implicit automatic matching,
+     * instead of confirming the explicit behavior they want.
      */
-    public static final int FLAG_DEBUG_TRIAGED_MISSING = 0x00000100;
+    public static final int FLAG_DIRECT_BOOT_AUTO = 0x00000100;
+
+    /** {@hide} */
+    @Deprecated
+    public static final int FLAG_DEBUG_TRIAGED_MISSING = FLAG_DIRECT_BOOT_AUTO;
 
     /**
      * Internal flag used to indicate ephemeral applications should not be
diff --git a/core/java/android/content/pm/ApplicationInfo.java b/core/java/android/content/pm/ApplicationInfo.java
index d65e051..3120421 100644
--- a/core/java/android/content/pm/ApplicationInfo.java
+++ b/core/java/android/content/pm/ApplicationInfo.java
@@ -1120,6 +1120,9 @@
     /** @hide */
     public String[] splitClassLoaderNames;
 
+    /** @hide */
+    public boolean hiddenUntilInstalled;
+
     /**
      * Represents the default policy. The actual policy used will depend on other properties of
      * the application, e.g. the target SDK version.
@@ -1460,6 +1463,7 @@
         compileSdkVersion = orig.compileSdkVersion;
         compileSdkVersionCodename = orig.compileSdkVersionCodename;
         mHiddenApiPolicy = orig.mHiddenApiPolicy;
+        hiddenUntilInstalled = orig.hiddenUntilInstalled;
     }
 
     public String toString() {
@@ -1534,6 +1538,7 @@
         dest.writeString(compileSdkVersionCodename);
         dest.writeString(appComponentFactory);
         dest.writeInt(mHiddenApiPolicy);
+        dest.writeInt(hiddenUntilInstalled ? 1 : 0);
     }
 
     public static final Parcelable.Creator<ApplicationInfo> CREATOR
@@ -1605,6 +1610,7 @@
         compileSdkVersionCodename = source.readString();
         appComponentFactory = source.readString();
         mHiddenApiPolicy = source.readInt();
+        hiddenUntilInstalled = source.readInt() != 0;
     }
 
     /**
diff --git a/core/java/android/content/pm/IPackageManager.aidl b/core/java/android/content/pm/IPackageManager.aidl
index c988fa9..bc5b32c 100644
--- a/core/java/android/content/pm/IPackageManager.aidl
+++ b/core/java/android/content/pm/IPackageManager.aidl
@@ -598,6 +598,9 @@
     boolean setApplicationHiddenSettingAsUser(String packageName, boolean hidden, int userId);
     boolean getApplicationHiddenSettingAsUser(String packageName, int userId);
 
+    void setSystemAppHiddenUntilInstalled(String packageName, boolean hidden);
+    boolean setSystemAppInstallState(String packageName, boolean installed, int userId);
+
     IPackageInstaller getPackageInstaller();
 
     boolean setBlockUninstallForUser(String packageName, boolean blockUninstall, int userId);
diff --git a/core/java/android/content/pm/PackageManager.java b/core/java/android/content/pm/PackageManager.java
index a76bc3a..721063a 100644
--- a/core/java/android/content/pm/PackageManager.java
+++ b/core/java/android/content/pm/PackageManager.java
@@ -147,6 +147,7 @@
             GET_DISABLED_COMPONENTS,
             GET_DISABLED_UNTIL_USED_COMPONENTS,
             GET_UNINSTALLED_PACKAGES,
+            MATCH_HIDDEN_UNTIL_INSTALLED_COMPONENTS,
     })
     @Retention(RetentionPolicy.SOURCE)
     public @interface PackageInfoFlags {}
@@ -164,6 +165,7 @@
             MATCH_STATIC_SHARED_LIBRARIES,
             GET_DISABLED_UNTIL_USED_COMPONENTS,
             GET_UNINSTALLED_PACKAGES,
+            MATCH_HIDDEN_UNTIL_INSTALLED_COMPONENTS,
     })
     @Retention(RetentionPolicy.SOURCE)
     public @interface ApplicationInfoFlags {}
@@ -177,6 +179,7 @@
             MATCH_DEFAULT_ONLY,
             MATCH_DISABLED_COMPONENTS,
             MATCH_DISABLED_UNTIL_USED_COMPONENTS,
+            MATCH_DIRECT_BOOT_AUTO,
             MATCH_DIRECT_BOOT_AWARE,
             MATCH_DIRECT_BOOT_UNAWARE,
             MATCH_SYSTEM_ONLY,
@@ -200,6 +203,7 @@
             MATCH_DISABLED_COMPONENTS,
             MATCH_DISABLED_UNTIL_USED_COMPONENTS,
             MATCH_DEFAULT_ONLY,
+            MATCH_DIRECT_BOOT_AUTO,
             MATCH_DIRECT_BOOT_AWARE,
             MATCH_DIRECT_BOOT_UNAWARE,
             MATCH_SYSTEM_ONLY,
@@ -504,22 +508,35 @@
     public static final int GET_SIGNING_CERTIFICATES = 0x08000000;
 
     /**
-     * Internal flag used to indicate that a system component has done their
-     * homework and verified that they correctly handle packages and components
-     * that come and go over time. In particular:
+     * Querying flag: automatically match components based on their Direct Boot
+     * awareness and the current user state.
+     * <p>
+     * Since the default behavior is to automatically apply the current user
+     * state, this is effectively a sentinel value that doesn't change the
+     * output of any queries based on its presence or absence.
+     * <p>
+     * Instead, this value can be useful in conjunction with
+     * {@link android.os.StrictMode.VmPolicy.Builder#detectImplicitDirectBoot()}
+     * to detect when a caller is relying on implicit automatic matching,
+     * instead of confirming the explicit behavior they want, using a
+     * combination of these flags:
      * <ul>
-     * <li>Apps installed on external storage, which will appear to be
-     * uninstalled while the the device is ejected.
-     * <li>Apps with encryption unaware components, which will appear to not
-     * exist while the device is locked.
+     * <li>{@link #MATCH_DIRECT_BOOT_AWARE}
+     * <li>{@link #MATCH_DIRECT_BOOT_UNAWARE}
+     * <li>{@link #MATCH_DIRECT_BOOT_AUTO}
      * </ul>
-     *
-     * @see #MATCH_UNINSTALLED_PACKAGES
-     * @see #MATCH_DIRECT_BOOT_AWARE
-     * @see #MATCH_DIRECT_BOOT_UNAWARE
+     */
+    public static final int MATCH_DIRECT_BOOT_AUTO = 0x10000000;
+
+    /** @hide */
+    @Deprecated
+    public static final int MATCH_DEBUG_TRIAGED_MISSING = MATCH_DIRECT_BOOT_AUTO;
+
+    /**
+     * Internal flag used to indicate that a package is a hidden system app.
      * @hide
      */
-    public static final int MATCH_DEBUG_TRIAGED_MISSING = 0x10000000;
+    public static final int MATCH_HIDDEN_UNTIL_INSTALLED_COMPONENTS =  0x20000000;
 
     /**
      * Flag for {@link #addCrossProfileIntentFilter}: if this flag is set: when
@@ -4855,7 +4872,8 @@
      * on the system for other users, also install it for the specified user.
      * @hide
      */
-     @RequiresPermission(anyOf = {
+    @RequiresPermission(anyOf = {
+            Manifest.permission.INSTALL_EXISTING_PACKAGES,
             Manifest.permission.INSTALL_PACKAGES,
             Manifest.permission.INTERACT_ACROSS_USERS_FULL})
     public abstract int installExistingPackageAsUser(String packageName, @UserIdInt int userId)
diff --git a/core/java/android/content/pm/PackageParser.java b/core/java/android/content/pm/PackageParser.java
index 033d2ee..54d383a 100644
--- a/core/java/android/content/pm/PackageParser.java
+++ b/core/java/android/content/pm/PackageParser.java
@@ -646,11 +646,19 @@
      */
     private static boolean checkUseInstalledOrHidden(int flags, PackageUserState state,
             ApplicationInfo appInfo) {
+        // Returns false if the package is hidden system app until installed.
+        if ((flags & PackageManager.MATCH_HIDDEN_UNTIL_INSTALLED_COMPONENTS) == 0
+                && !state.installed
+                && appInfo != null && appInfo.hiddenUntilInstalled) {
+            return false;
+        }
+
         // If available for the target user, or trying to match uninstalled packages and it's
         // a system app.
         return state.isAvailable(flags)
                 || (appInfo != null && appInfo.isSystemApp()
-                        && (flags & PackageManager.MATCH_KNOWN_PACKAGES) != 0);
+                        && ((flags & PackageManager.MATCH_KNOWN_PACKAGES) != 0
+                        || (flags & PackageManager.MATCH_HIDDEN_UNTIL_INSTALLED_COMPONENTS) != 0));
     }
 
     public static boolean isAvailable(PackageUserState state) {
diff --git a/core/java/android/os/StrictMode.java b/core/java/android/os/StrictMode.java
index f224550..3ce7150 100644
--- a/core/java/android/os/StrictMode.java
+++ b/core/java/android/os/StrictMode.java
@@ -27,6 +27,7 @@
 import android.content.Intent;
 import android.content.ServiceConnection;
 import android.content.pm.ApplicationInfo;
+import android.content.pm.PackageManager;
 import android.net.TrafficStats;
 import android.net.Uri;
 import android.os.strictmode.CleartextNetworkViolation;
@@ -36,6 +37,7 @@
 import android.os.strictmode.DiskWriteViolation;
 import android.os.strictmode.ExplicitGcViolation;
 import android.os.strictmode.FileUriExposedViolation;
+import android.os.strictmode.ImplicitDirectBootViolation;
 import android.os.strictmode.InstanceCountViolation;
 import android.os.strictmode.IntentReceiverLeakedViolation;
 import android.os.strictmode.LeakedClosableViolation;
@@ -272,6 +274,9 @@
     /** @hide */
     @TestApi public static final int DETECT_VM_NON_SDK_API_USAGE = 0x40 << 24; // for VmPolicy
 
+    /** @hide */
+    @TestApi public static final int DETECT_VM_IMPLICIT_DIRECT_BOOT = 0x20 << 24; // for VmPolicy
+
     private static final int ALL_VM_DETECT_BITS =
             DETECT_VM_CURSOR_LEAKS
                     | DETECT_VM_CLOSABLE_LEAKS
@@ -282,7 +287,8 @@
                     | DETECT_VM_CLEARTEXT_NETWORK
                     | DETECT_VM_CONTENT_URI_WITHOUT_PERMISSION
                     | DETECT_VM_UNTAGGED_SOCKET
-                    | DETECT_VM_NON_SDK_API_USAGE;
+                    | DETECT_VM_NON_SDK_API_USAGE
+                    | DETECT_VM_IMPLICIT_DIRECT_BOOT;
 
 
     // Byte 3: Penalty
@@ -891,6 +897,8 @@
                 }
 
                 // TODO: Decide whether to detect non SDK API usage beyond a certain API level.
+                // TODO: enable detectImplicitDirectBoot() once system is less noisy
+
                 return this;
             }
 
@@ -999,6 +1007,29 @@
             }
 
             /**
+             * Detect any implicit reliance on Direct Boot automatic filtering
+             * of {@link PackageManager} values. Violations are only triggered
+             * when implicit calls are made while the user is locked.
+             * <p>
+             * Apps becoming Direct Boot aware need to carefully inspect each
+             * query site and explicitly decide which combination of flags they
+             * want to use:
+             * <ul>
+             * <li>{@link PackageManager#MATCH_DIRECT_BOOT_AWARE}
+             * <li>{@link PackageManager#MATCH_DIRECT_BOOT_UNAWARE}
+             * <li>{@link PackageManager#MATCH_DIRECT_BOOT_AUTO}
+             * </ul>
+             */
+            public Builder detectImplicitDirectBoot() {
+                return enable(DETECT_VM_IMPLICIT_DIRECT_BOOT);
+            }
+
+            /** @hide */
+            public Builder permitImplicitDirectBoot() {
+                return disable(DETECT_VM_IMPLICIT_DIRECT_BOOT);
+            }
+
+            /**
              * Crashes the whole process on violation. This penalty runs at the end of all enabled
              * penalties so you'll still get your logging or other violations before the process
              * dies.
@@ -1991,6 +2022,11 @@
     }
 
     /** @hide */
+    public static boolean vmImplicitDirectBootEnabled() {
+        return (sVmPolicy.mask & DETECT_VM_IMPLICIT_DIRECT_BOOT) != 0;
+    }
+
+    /** @hide */
     public static void onSqliteObjectLeaked(String message, Throwable originStack) {
         onVmPolicyViolation(new SqliteObjectLeakedViolation(message, originStack));
     }
@@ -2062,6 +2098,11 @@
         onVmPolicyViolation(new UntaggedSocketViolation());
     }
 
+    /** @hide */
+    public static void onImplicitDirectBoot() {
+        onVmPolicyViolation(new ImplicitDirectBootViolation());
+    }
+
     // Map from VM violation fingerprint to uptime millis.
     private static final HashMap<Integer, Long> sLastVmViolationTime = new HashMap<>();
 
@@ -2665,6 +2706,8 @@
                 return DETECT_EXPLICIT_GC;
             } else if (mViolation instanceof NonSdkApiUsedViolation) {
                 return DETECT_VM_NON_SDK_API_USAGE;
+            } else if (mViolation instanceof ImplicitDirectBootViolation) {
+                return DETECT_VM_IMPLICIT_DIRECT_BOOT;
             }
             throw new IllegalStateException("missing violation bit");
         }
diff --git a/core/java/android/os/strictmode/ImplicitDirectBootViolation.java b/core/java/android/os/strictmode/ImplicitDirectBootViolation.java
new file mode 100644
index 0000000..d7877ca
--- /dev/null
+++ b/core/java/android/os/strictmode/ImplicitDirectBootViolation.java
@@ -0,0 +1,37 @@
+/*
+ * 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.os.strictmode;
+
+import android.content.pm.PackageManager;
+
+/**
+ * Subclass of {@code Violation} that is used when a process implicitly relies
+ * on automatic Direct Boot filtering.
+ *
+ * @see PackageManager#MATCH_DIRECT_BOOT_AUTO
+ */
+public final class ImplicitDirectBootViolation extends Violation {
+    /** @hide */
+    public static final String MESSAGE =
+            "Implicitly relying on automatic Direct Boot filtering; request explicit"
+                    + " filtering with PackageManager.MATCH_DIRECT_BOOT flags";
+
+    /** @hide */
+    public ImplicitDirectBootViolation() {
+        super(MESSAGE);
+    }
+}
diff --git a/core/java/android/util/TimestampedValue.java b/core/java/android/util/TimestampedValue.java
index 75fa18d..1289e4d 100644
--- a/core/java/android/util/TimestampedValue.java
+++ b/core/java/android/util/TimestampedValue.java
@@ -126,4 +126,12 @@
         dest.writeLong(timestampedValue.mReferenceTimeMillis);
         dest.writeValue(timestampedValue.mValue);
     }
+
+    /**
+     * Returns the difference in milliseconds between two instance's reference times.
+     */
+    public static long referenceTimeDifference(
+            @NonNull TimestampedValue<?> one, @NonNull TimestampedValue<?> two) {
+        return one.mReferenceTimeMillis - two.mReferenceTimeMillis;
+    }
 }
diff --git a/core/proto/android/os/incident.proto b/core/proto/android/os/incident.proto
index 1d299f5..5f6b6cc 100644
--- a/core/proto/android/os/incident.proto
+++ b/core/proto/android/os/incident.proto
@@ -71,6 +71,12 @@
         (section).args = "getprop"
     ];
 
+    optional string kernel_version = 1002 [
+        (section).type = SECTION_FILE,
+        (section).args = "/proc/version",
+        (privacy).dest = DEST_AUTOMATIC
+    ];
+
     // Device Logs
     optional android.util.EventLogTagMapProto event_log_tag_map = 1100 [
         (section).type = SECTION_FILE,
diff --git a/core/res/AndroidManifest.xml b/core/res/AndroidManifest.xml
index f4b7ec8..e2a5c57 100644
--- a/core/res/AndroidManifest.xml
+++ b/core/res/AndroidManifest.xml
@@ -3046,6 +3046,15 @@
     <permission android:name="android.permission.INSTALL_PACKAGE_UPDATES"
         android:protectionLevel="signature|privileged" />
 
+    <!-- Allows an application to install existing system packages. This is a limited
+         version of {@link android.Manifest.permission#INSTALL_PACKAGES}.
+         <p>Not for use by third-party applications.
+         TODO(b/80204953): remove this permission once we have a long-term solution.
+         @hide
+    -->
+    <permission android:name="com.android.permission.INSTALL_EXISTING_PACKAGES"
+        android:protectionLevel="signature|privileged" />
+
     <!-- @SystemApi Allows an application to clear user data.
          <p>Not for use by third-party applications
          @hide
diff --git a/core/res/res/values/config.xml b/core/res/res/values/config.xml
index 408a4d0..79e81d0 100644
--- a/core/res/res/values/config.xml
+++ b/core/res/res/values/config.xml
@@ -42,13 +42,13 @@
         <item><xliff:g id="id">@string/status_bar_phone_evdo_signal</xliff:g></item>
         <item><xliff:g id="id">@string/status_bar_phone_signal</xliff:g></item>
         <item><xliff:g id="id">@string/status_bar_secure</xliff:g></item>
-        <item><xliff:g id="id">@string/status_bar_bluetooth</xliff:g></item>
         <item><xliff:g id="id">@string/status_bar_managed_profile</xliff:g></item>
         <item><xliff:g id="id">@string/status_bar_cast</xliff:g></item>
         <item><xliff:g id="id">@string/status_bar_vpn</xliff:g></item>
+        <item><xliff:g id="id">@string/status_bar_bluetooth</xliff:g></item>
+        <item><xliff:g id="id">@string/status_bar_location</xliff:g></item>
         <item><xliff:g id="id">@string/status_bar_mute</xliff:g></item>
         <item><xliff:g id="id">@string/status_bar_volume</xliff:g></item>
-        <item><xliff:g id="id">@string/status_bar_location</xliff:g></item>
         <item><xliff:g id="id">@string/status_bar_zen</xliff:g></item>
         <item><xliff:g id="id">@string/status_bar_ethernet</xliff:g></item>
         <item><xliff:g id="id">@string/status_bar_wifi</xliff:g></item>
@@ -504,7 +504,7 @@
 
          When true, overrides the config_tether_upstream_types setting above.
     -->
-    <bool translatable="false" name="config_tether_upstream_automatic">false</bool>
+    <bool translatable="false" name="config_tether_upstream_automatic">true</bool>
 
     <!-- If the DUN connection for this CDMA device supports more than just DUN -->
     <!-- traffic you should list them here. -->
diff --git a/core/res/res/values/strings.xml b/core/res/res/values/strings.xml
index 4e96671..9b21298 100644
--- a/core/res/res/values/strings.xml
+++ b/core/res/res/values/strings.xml
@@ -671,7 +671,7 @@
     <string name="permgrouplab_contacts">Contacts</string>
     <!-- Description of a category of application permissions, listed so the user can choose whether they want to allow the application to do this. -->
     <string name="permgroupdesc_contacts">access your contacts</string>
-    <!-- Message shown to the user when the apps requests permission from this group -->
+    <!-- Message shown to the user when the apps requests permission from this group. If ever possible this should stay below 80 characters (assuming the parameters takes 20 characters). Don't abbreviate until the message reaches 120 characters though. [CHAR LIMIT=120] -->
     <string name="permgrouprequest_contacts">Allow
         &lt;b><xliff:g id="app_name" example="Gmail">%1$s</xliff:g>&lt;/b> to access your contacts?</string>
 
@@ -679,22 +679,22 @@
     <string name="permgrouplab_location">Location</string>
     <!-- Description of a category of application permissions, listed so the user can choose whether they want to allow the application to do this. -->
     <string name="permgroupdesc_location">access this device\'s location</string>
-    <!-- Message shown to the user when the apps requests permission from this group -->
+    <!-- Message shown to the user when the apps requests permission from this group. If ever possible this should stay below 80 characters (assuming the parameters takes 20 characters). Don't abbreviate until the message reaches 120 characters though. [CHAR LIMIT=120] -->
     <string name="permgrouprequest_location">Allow
         &lt;b><xliff:g id="app_name" example="Gmail">%1$s</xliff:g>&lt;/b> to access this device\'s location?</string>
-    <!-- Subtitle of the message shown to the user when the apps requests permission to use the location only while app is in foreground [CHAR LIMIT=none]-->
+    <!-- Subtitle of the message shown to the user when the apps requests permission to use the location only while app is in foreground [CHAR LIMIT=150]-->
     <string name="permgrouprequestdetail_location">The app will only have access to the location while you\u2019re using the app.</string>
-    <!-- Message shown to the user when the apps requests permission to use the location while app is in foreground and background [CHAR LIMIT=60] -->
+    <!-- Message shown to the user when the apps requests permission to use the location while app is in foreground and background. If ever possible this should stay below 80 characters (assuming the parameters takes 20 characters). Don't abbreviate until the message reaches 120 characters though. [CHAR LIMIT=120] -->
     <string name="permgroupbackgroundrequest_location">Always allow
         &lt;b><xliff:g id="app_name" example="Gmail">%1$s</xliff:g>&lt;/b> to access this device\u2019s location?</string>
-    <!-- Subtitle of the message shown to the user when the apps requests permission to use the location while app is in foreground and background [CHAR LIMIT=none] -->
+    <!-- Subtitle of the message shown to the user when the apps requests permission to use the location while app is in foreground and background [CHAR LIMIT=150] -->
     <string name="permgroupbackgroundrequestdetail_location">The app will always have access to the location, even when you\u2019re not using the app.</string>
 
     <!-- Title of a category of application permissions, listed so the user can choose whether they want to allow the application to do this. -->
     <string name="permgrouplab_calendar">Calendar</string>
     <!-- Description of a category of application permissions, listed so the user can choose whether they want to allow the application to do this. -->
     <string name="permgroupdesc_calendar">access your calendar</string>
-    <!-- Message shown to the user when the apps requests permission from this group -->
+    <!-- Message shown to the user when the apps requests permission from this group. If ever possible this should stay below 80 characters (assuming the parameters takes 20 characters). Don't abbreviate until the message reaches 120 characters though. [CHAR LIMIT=120] -->
     <string name="permgrouprequest_calendar">Allow
         &lt;b><xliff:g id="app_name" example="Gmail">%1$s</xliff:g>&lt;/b> to access your calendar?</string>
 
@@ -702,7 +702,7 @@
     <string name="permgrouplab_sms">SMS</string>
     <!-- Description of a category of application permissions, listed so the user can choose whether they want to allow the application to do this. -->
     <string name="permgroupdesc_sms">send and view SMS messages</string>
-    <!-- Message shown to the user when the apps requests permission from this group -->
+    <!-- Message shown to the user when the apps requests permission from this group. If ever possible this should stay below 80 characters (assuming the parameters takes 20 characters). Don't abbreviate until the message reaches 120 characters though. [CHAR LIMIT=120] -->
     <string name="permgrouprequest_sms">Allow
         &lt;b><xliff:g id="app_name" example="Gmail">%1$s</xliff:g>&lt;/b> to send and view SMS messages?</string>
 
@@ -710,7 +710,7 @@
     <string name="permgrouplab_storage">Storage</string>
     <!-- Description of a category of application permissions, listed so the user can choose whether they want to allow the application to do this. -->
     <string name="permgroupdesc_storage">access photos, media, and files on your device</string>
-    <!-- Message shown to the user when the apps requests permission from this group -->
+    <!-- Message shown to the user when the apps requests permission from this group. If ever possible this should stay below 80 characters (assuming the parameters takes 20 characters). Don't abbreviate until the message reaches 120 characters though. [CHAR LIMIT=120] -->
     <string name="permgrouprequest_storage">Allow
         &lt;b><xliff:g id="app_name" example="Gmail">%1$s</xliff:g>&lt;/b> to access photos, media, and files on your device?</string>
 
@@ -718,7 +718,7 @@
     <string name="permgrouplab_microphone">Microphone</string>
     <!-- Description of a category of application permissions, listed so the user can choose whether they want to allow the application to do this. -->
     <string name="permgroupdesc_microphone">record audio</string>
-    <!-- Message shown to the user when the apps requests permission from this group -->
+    <!-- Message shown to the user when the apps requests permission from this group. If ever possible this should stay below 80 characters (assuming the parameters takes 20 characters). Don't abbreviate until the message reaches 120 characters though. [CHAR LIMIT=120] -->
     <string name="permgrouprequest_microphone">Allow
         &lt;b><xliff:g id="app_name" example="Gmail">%1$s</xliff:g>&lt;/b> to record audio?</string>
 
@@ -726,7 +726,7 @@
     <string name="permgrouplab_camera">Camera</string>
     <!-- Description of a category of application permissions, listed so the user can choose whether they want to allow the application to do this. -->
     <string name="permgroupdesc_camera">take pictures and record video</string>
-    <!-- Message shown to the user when the apps requests permission from this group -->
+    <!-- Message shown to the user when the apps requests permission from this group. If ever possible this should stay below 80 characters (assuming the parameters takes 20 characters). Don't abbreviate until the message reaches 120 characters though. [CHAR LIMIT=120] -->
     <string name="permgrouprequest_camera">Allow
         &lt;b><xliff:g id="app_name" example="Gmail">%1$s</xliff:g>&lt;/b> to take pictures and record video?</string>
 
@@ -734,7 +734,7 @@
     <string name="permgrouplab_calllog">Call logs</string>
     <!-- Description of a category of application permissions, listed so the user can choose whether they want to allow the application to do this. -->
     <string name="permgroupdesc_calllog">read and write phone call log</string>
-    <!-- Message shown to the user when the apps requests permission from this group -->
+    <!-- Message shown to the user when the apps requests permission from this group. If ever possible this should stay below 80 characters (assuming the parameters takes 20 characters). Don't abbreviate until the message reaches 120 characters though. [CHAR LIMIT=120] -->
     <string name="permgrouprequest_calllog">Allow
         &lt;b><xliff:g id="app_name" example="Gmail">%1$s</xliff:g>&lt;/b> to access your phone call logs?</string>
 
@@ -742,7 +742,7 @@
     <string name="permgrouplab_phone">Phone</string>
     <!-- Description of a category of application permissions, listed so the user can choose whether they want to allow the application to do this. -->
     <string name="permgroupdesc_phone">make and manage phone calls</string>
-    <!-- Message shown to the user when the apps requests permission from this group -->
+    <!-- Message shown to the user when the apps requests permission from this group. If ever possible this should stay below 80 characters (assuming the parameters takes 20 characters). Don't abbreviate until the message reaches 120 characters though. [CHAR LIMIT=120] -->
     <string name="permgrouprequest_phone">Allow
         &lt;b><xliff:g id="app_name" example="Gmail">%1$s</xliff:g>&lt;/b> to make and manage phone calls?</string>
 
@@ -750,7 +750,7 @@
     <string name="permgrouplab_sensors">Body Sensors</string>
     <!-- Description of a category of application permissions, listed so the user can choose whether they want to allow the application to do this. -->
     <string name="permgroupdesc_sensors">access sensor data about your vital signs</string>
-    <!-- Message shown to the user when the apps requests permission from this group -->
+    <!-- Message shown to the user when the apps requests permission from this group. If ever possible this should stay below 80 characters (assuming the parameters takes 20 characters). Don't abbreviate until the message reaches 120 characters though. [CHAR LIMIT=120] -->
     <string name="permgrouprequest_sensors">Allow
         &lt;b><xliff:g id="app_name" example="Gmail">%1$s</xliff:g>&lt;/b> to access sensor data about your vital signs?</string>
 
diff --git a/core/tests/coretests/src/android/util/TimestampedValueTest.java b/core/tests/coretests/src/android/util/TimestampedValueTest.java
index 7117c1b..03b4abd 100644
--- a/core/tests/coretests/src/android/util/TimestampedValueTest.java
+++ b/core/tests/coretests/src/android/util/TimestampedValueTest.java
@@ -116,4 +116,14 @@
             parcel.recycle();
         }
     }
+
+    @Test
+    public void testReferenceTimeDifference() {
+        TimestampedValue<Long> value1 = new TimestampedValue<>(1000, 123L);
+        assertEquals(0, TimestampedValue.referenceTimeDifference(value1, value1));
+
+        TimestampedValue<Long> value2 = new TimestampedValue<>(1, 321L);
+        assertEquals(999, TimestampedValue.referenceTimeDifference(value1, value2));
+        assertEquals(-999, TimestampedValue.referenceTimeDifference(value2, value1));
+    }
 }
diff --git a/libs/hwui/pipeline/skia/SkiaOpenGLReadback.cpp b/libs/hwui/pipeline/skia/SkiaOpenGLReadback.cpp
index 208910a..f2f5056 100644
--- a/libs/hwui/pipeline/skia/SkiaOpenGLReadback.cpp
+++ b/libs/hwui/pipeline/skia/SkiaOpenGLReadback.cpp
@@ -26,6 +26,7 @@
 #include "DeviceInfo.h"
 #include "Matrix.h"
 #include "Properties.h"
+#include "utils/MathUtils.h"
 
 using namespace android::uirenderer::renderthread;
 
@@ -115,9 +116,9 @@
             paint.setBlendMode(SkBlendMode::kSrc);
             // Apply a filter, which is matching OpenGL pipeline readback behaviour. Filter usage
             // is codified by tests using golden images like DecodeAccuracyTest.
-            if (skiaSrcRect.width() != bitmap->width() ||
-                skiaSrcRect.height() != bitmap->height()) {
-                // TODO: apply filter always, but check if tests will be fine
+            bool disableFilter = MathUtils::areEqual(skiaSrcRect.width(), skiaDestRect.width())
+                    && MathUtils::areEqual(skiaSrcRect.height(), skiaDestRect.height());
+            if (!disableFilter) {
                 paint.setFilterQuality(kLow_SkFilterQuality);
             }
             scaledSurface->getCanvas()->concat(textureMatrix);
diff --git a/packages/SettingsLib/res/values-as/strings.xml b/packages/SettingsLib/res/values-as/strings.xml
index d8137b4..e3b4bc9 100644
--- a/packages/SettingsLib/res/values-as/strings.xml
+++ b/packages/SettingsLib/res/values-as/strings.xml
@@ -224,8 +224,7 @@
     <string name="bluetooth_select_a2dp_codec_channel_mode" msgid="884855779449390540">"ব্লুটুথ অডিঅ\' চ্চেনেল ম\'ড"</string>
     <string name="bluetooth_select_a2dp_codec_channel_mode_dialog_title" msgid="7234956835280563341">"ব্লুটুথ অডিঅ\' ক\'ডেকৰ বাছনি\nআৰম্ভ কৰক: চ্চেনেল ম\'ড"</string>
     <string name="bluetooth_select_a2dp_codec_ldac_playback_quality" msgid="3619694372407843405">"ব্লুটুথ অডিঅ’ LDAC ক’ডেক: পৰিৱেশনৰ মান"</string>
-    <!-- no translation found for bluetooth_select_a2dp_codec_ldac_playback_quality_dialog_title (6893955536658137179) -->
-    <skip />
+    <string name="bluetooth_select_a2dp_codec_ldac_playback_quality_dialog_title" msgid="6893955536658137179">"ব্লুটুথ অডিঅ\' LDAC\nক\'ডেক বাছনি আৰম্ভ কৰক: প্লেবেকৰ গুণগত মান"</string>
     <string name="bluetooth_select_a2dp_codec_streaming_label" msgid="5347862512596240506">"ষ্ট্ৰীম কৰি থকা হৈছে: <xliff:g id="STREAMING_PARAMETER">%1$s</xliff:g>"</string>
     <string name="select_private_dns_configuration_title" msgid="3700456559305263922">"ব্যক্তিগত DNS"</string>
     <string name="select_private_dns_configuration_dialog_title" msgid="9221994415765826811">"ব্যক্তিগত DNS ম\'ড বাছনি কৰক"</string>
@@ -366,18 +365,12 @@
     <string name="accessibility_display_daltonizer_preference_title" msgid="5800761362678707872">"ৰং শুধৰণী"</string>
     <string name="accessibility_display_daltonizer_preference_subtitle" msgid="3484969015295282911">"এই সুবিধাটো পৰীক্ষামূলক, সেয়ে ই কাৰ্যক্ষমতাৰ ওপৰত প্ৰভাৱ পেলাব পাৰে।"</string>
     <string name="daltonizer_type_overridden" msgid="3116947244410245916">"<xliff:g id="TITLE">%1$s</xliff:g>ৰ দ্বাৰা অগ্ৰাহ্য কৰা হৈছে"</string>
-    <!-- no translation found for power_remaining_settings_home_page (4845022416859002011) -->
-    <skip />
-    <!-- no translation found for power_remaining_duration_only (6123167166221295462) -->
-    <skip />
-    <!-- no translation found for power_discharging_duration (8848256785736335185) -->
-    <skip />
-    <!-- no translation found for power_remaining_duration_only_enhanced (4189311599812296592) -->
-    <skip />
-    <!-- no translation found for power_discharging_duration_enhanced (1992003260664804080) -->
-    <skip />
-    <!-- no translation found for power_remaining_duration_only_short (3463575350656389957) -->
-    <skip />
+    <string name="power_remaining_settings_home_page" msgid="4845022416859002011">"<xliff:g id="PERCENTAGE">%1$s</xliff:g> - <xliff:g id="TIME_STRING">%2$s</xliff:g>"</string>
+    <string name="power_remaining_duration_only" msgid="6123167166221295462">"প্রায় <xliff:g id="TIME_REMAINING">%1$s</xliff:g> বাকী আছে"</string>
+    <string name="power_discharging_duration" msgid="8848256785736335185">"প্রায় <xliff:g id="TIME_REMAINING">%1$s</xliff:g> বাকী আছে (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string>
+    <string name="power_remaining_duration_only_enhanced" msgid="4189311599812296592">"আপোনাৰ ব্যৱহাৰৰ ওপৰত ভিত্তি কৰি প্ৰায় <xliff:g id="TIME_REMAINING">%1$s</xliff:g> বাকী আছে"</string>
+    <string name="power_discharging_duration_enhanced" msgid="1992003260664804080">"আপোনাৰ ব্যৱহাৰৰ ওপৰত ভিত্তি কৰি প্রায় <xliff:g id="TIME_REMAINING">%1$s</xliff:g> বাকী আছে (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string>
+    <string name="power_remaining_duration_only_short" msgid="3463575350656389957">"<xliff:g id="TIME_REMAINING">%1$s</xliff:g> বাকী আছে"</string>
     <string name="power_discharge_by_enhanced" msgid="2095821536747992464">"আপোনাৰ ব্যৱহাৰৰ ওপৰত ভিত্তি কৰি বেটাৰি আনুমানিকভাৱে <xliff:g id="TIME">%1$s</xliff:g> লৈকে চলিব (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string>
     <string name="power_discharge_by_only_enhanced" msgid="2175151772952365149">"আপোনাৰ ব্যৱহাৰৰ ওপৰত ভিত্তি কৰি বেটাৰি আনুমানিকভাৱে <xliff:g id="TIME">%1$s</xliff:g> লৈকে চলিব"</string>
     <string name="power_discharge_by" msgid="6453537733650125582">"বেটাৰি আনুমানিকভাৱে <xliff:g id="TIME">%1$s</xliff:g> লৈকে চলিব (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string>
diff --git a/packages/SettingsLib/res/values-bn/strings.xml b/packages/SettingsLib/res/values-bn/strings.xml
index 98a95c2..66f5c07 100644
--- a/packages/SettingsLib/res/values-bn/strings.xml
+++ b/packages/SettingsLib/res/values-bn/strings.xml
@@ -278,7 +278,7 @@
     <string name="media_category" msgid="4388305075496848353">"মিডিয়া"</string>
     <string name="debug_monitoring_category" msgid="7640508148375798343">"পর্যবেক্ষণে রাখা"</string>
     <string name="strict_mode" msgid="1938795874357830695">"কঠোর মোড সক্ষম"</string>
-    <string name="strict_mode_summary" msgid="142834318897332338">"মুখ্য থ্রেডে অ্যাপ্লিকেশানগুলির দীর্ঘ কার্যকলাপের সময় স্ক্রিন ফ্ল্যাশ করে"</string>
+    <string name="strict_mode_summary" msgid="142834318897332338">"মুখ্য থ্রেডে অ্যাপ্লিকেশানগুলির দীর্ঘ অ্যাক্টিভিটির সময় স্ক্রিন ফ্ল্যাশ করে"</string>
     <string name="pointer_location" msgid="6084434787496938001">"পয়েন্টারের লোকেশন"</string>
     <string name="pointer_location_summary" msgid="840819275172753713">"স্ক্রিন ওভারলে বর্তমান স্পর্শ ডেটা দেখাচ্ছে"</string>
     <string name="show_touches" msgid="2642976305235070316">"আলতো চাপ দেখান"</string>
@@ -302,7 +302,7 @@
     <string name="force_rtl_layout_all_locales_summary" msgid="9192797796616132534">"সমস্ত স্থানের জন্য RTL এ স্ক্রিন লেআউট দিকনির্দেশে জোর দেয়"</string>
     <string name="force_msaa" msgid="7920323238677284387">"4x MSAA এ জোর দিন"</string>
     <string name="force_msaa_summary" msgid="9123553203895817537">"OpenGL ES 2.0 অ্যাপ্লিকেশানগুলির মধ্যে 4x MSAA সক্রিয় করুন"</string>
-    <string name="show_non_rect_clip" msgid="505954950474595172">"অ-আয়তক্ষেত্রাকার ক্লিপ কার্যকলাপ ডিবাগ করুন"</string>
+    <string name="show_non_rect_clip" msgid="505954950474595172">"অ-আয়তক্ষেত্রাকার ক্লিপ অ্যাক্টিভিটি ডিবাগ করুন"</string>
     <string name="track_frame_time" msgid="6094365083096851167">"প্রোফাইল HWUI রেন্ডারিং"</string>
     <string name="enable_gpu_debug_layers" msgid="3848838293793255097">"GPU ডিবাগ স্তর সক্ষম করুন"</string>
     <string name="enable_gpu_debug_layers_summary" msgid="8009136940671194940">"ডিবাগ অ্যাপের জন্য GPU ডিবাগ স্তর লোড হতে দিন"</string>
@@ -311,8 +311,8 @@
     <string name="animator_duration_scale_title" msgid="3406722410819934083">"অ্যানিমেটর সময়কাল স্কেল"</string>
     <string name="overlay_display_devices_title" msgid="5364176287998398539">"গৌণ প্রদর্শনগুলি নকল করুন"</string>
     <string name="debug_applications_category" msgid="4206913653849771549">"অ্যাপ"</string>
-    <string name="immediately_destroy_activities" msgid="1579659389568133959">"কার্যকলাপ রাখবেন না"</string>
-    <string name="immediately_destroy_activities_summary" msgid="3592221124808773368">"ব্যবহারকারী এটি ছেড়ে যাওয়ার পরে যত তাড়াতাড়ি সম্ভব প্রতিটি কার্যকলাপ ধ্বংস করুন"</string>
+    <string name="immediately_destroy_activities" msgid="1579659389568133959">"অ্যাক্টিভিটি রাখবেন না"</string>
+    <string name="immediately_destroy_activities_summary" msgid="3592221124808773368">"ব্যবহারকারী এটি ছেড়ে যাওয়ার পরে যত তাড়াতাড়ি সম্ভব প্রতিটি অ্যাক্টিভিটি ধ্বংস করুন"</string>
     <string name="app_process_limit_title" msgid="4280600650253107163">"পশ্চাদপট প্রক্রিয়ার সীমা"</string>
     <string name="show_all_anrs" msgid="4924885492787069007">"ব্যাকগ্রাউন্ডের ANR দেখুন"</string>
     <string name="show_all_anrs_summary" msgid="6636514318275139826">"ব্যাকগ্রাউন্ডের অ্যাপগুলির জন্য \'অ্যাপ থেকে সাড়া পাওয়া যাচ্ছে না\' মেসেজ দেখান"</string>
diff --git a/packages/SettingsLib/res/values-gl/arrays.xml b/packages/SettingsLib/res/values-gl/arrays.xml
index a25d136..c6c4a2e 100644
--- a/packages/SettingsLib/res/values-gl/arrays.xml
+++ b/packages/SettingsLib/res/values-gl/arrays.xml
@@ -209,15 +209,15 @@
     <item msgid="1606809880904982133">"Ningunha"</item>
     <item msgid="9033194758688161545">"480 p"</item>
     <item msgid="1025306206556583600">"480 p (seguro)"</item>
-    <item msgid="1853913333042744661">"720 p"</item>
-    <item msgid="3414540279805870511">"720 p (seguro)"</item>
+    <item msgid="1853913333042744661">"720p"</item>
+    <item msgid="3414540279805870511">"720p (seguro)"</item>
     <item msgid="9039818062847141551">"1080 p"</item>
     <item msgid="4939496949750174834">"1080 p (seguro)"</item>
     <item msgid="1833612718524903568">"4K"</item>
     <item msgid="238303513127879234">"4K (seguro)"</item>
     <item msgid="3547211260846843098">"4K (mellorado)"</item>
     <item msgid="5411365648951414254">"4K (mellorado e seguro)"</item>
-    <item msgid="1311305077526792901">"720 p, 1080 p (pantalla dual)"</item>
+    <item msgid="1311305077526792901">"720p, 1080p (pantalla dual)"</item>
   </string-array>
   <string-array name="enable_opengl_traces_entries">
     <item msgid="3191973083884253830">"Ningún"</item>
diff --git a/packages/SettingsLib/res/values-or/strings.xml b/packages/SettingsLib/res/values-or/strings.xml
index c84875e..987d075 100644
--- a/packages/SettingsLib/res/values-or/strings.xml
+++ b/packages/SettingsLib/res/values-or/strings.xml
@@ -224,8 +224,7 @@
     <string name="bluetooth_select_a2dp_codec_channel_mode" msgid="884855779449390540">"ବ୍ଲୁ-ଟୂଥ୍‍‌ ଅଡିଓ ଚ୍ୟାନେଲ୍‌ ମୋଡ୍"</string>
     <string name="bluetooth_select_a2dp_codec_channel_mode_dialog_title" msgid="7234956835280563341">"ବ୍ଲୁ-ଟୂଥ୍‍ ଅଡିଓ କୋଡେକ୍\nସିଲେକ୍ସନ୍‌କୁ ଗତିଶୀଳ କରନ୍ତୁ: ଚ୍ୟାନେଲ୍ ମୋଡ୍"</string>
     <string name="bluetooth_select_a2dp_codec_ldac_playback_quality" msgid="3619694372407843405">"ବ୍ଲୁ-ଟୂଥ୍‍‌ ଅଡିଓ LDAC କୋଡେକ୍‌: ପ୍ଲେବ୍ୟାକ୍‌ ଗୁଣବତ୍ତା"</string>
-    <!-- no translation found for bluetooth_select_a2dp_codec_ldac_playback_quality_dialog_title (6893955536658137179) -->
-    <skip />
+    <string name="bluetooth_select_a2dp_codec_ldac_playback_quality_dialog_title" msgid="6893955536658137179">"ବ୍ଲୁ-ଟୁଥ୍‌ ଅଡିଓ LDAC\nକୋଡେକ୍‌ ଚୟନକୁ ଗତିଶୀଳ କରନ୍ତୁ: ପ୍ଲେବ୍ୟାକ୍‌ କ୍ୱାଲିଟୀ"</string>
     <string name="bluetooth_select_a2dp_codec_streaming_label" msgid="5347862512596240506">"ଷ୍ଟ୍ରିମ୍ କରୁଛି: <xliff:g id="STREAMING_PARAMETER">%1$s</xliff:g>"</string>
     <string name="select_private_dns_configuration_title" msgid="3700456559305263922">"ବ୍ୟକ୍ତିଗତ DNS"</string>
     <string name="select_private_dns_configuration_dialog_title" msgid="9221994415765826811">"ବ୍ୟକ୍ତିଗତ DNS ମୋଡ୍‌ ବାଛନ୍ତୁ"</string>
diff --git a/packages/SettingsLib/res/values-pt-rBR/strings.xml b/packages/SettingsLib/res/values-pt-rBR/strings.xml
index d1726d3..dd623d0 100644
--- a/packages/SettingsLib/res/values-pt-rBR/strings.xml
+++ b/packages/SettingsLib/res/values-pt-rBR/strings.xml
@@ -195,7 +195,7 @@
     <string name="bugreport_in_power" msgid="7923901846375587241">"Atalho para relatório do bug"</string>
     <string name="bugreport_in_power_summary" msgid="1778455732762984579">"Mostrar um botão para gerar relatórios de bugs no menu do botão liga/desliga"</string>
     <string name="keep_screen_on" msgid="1146389631208760344">"Permanecer ativo"</string>
-    <string name="keep_screen_on_summary" msgid="2173114350754293009">"A tela nunca entrará em inatividade enquanto estiver carregando."</string>
+    <string name="keep_screen_on_summary" msgid="2173114350754293009">"A tela nunca entrará em suspensão enquanto estiver carregando."</string>
     <string name="bt_hci_snoop_log" msgid="3340699311158865670">"Ativar log de rastreamento Bluetooth HCI"</string>
     <string name="bt_hci_snoop_log_summary" msgid="366083475849911315">"Capturar todos os pacotes Bluetooth HCI em um arquivo (ative o Bluetooth depois de alterar esta configuração)"</string>
     <string name="oem_unlock_enable" msgid="6040763321967327691">"Desbloqueio de OEM"</string>
diff --git a/packages/SettingsLib/res/values-pt/strings.xml b/packages/SettingsLib/res/values-pt/strings.xml
index d1726d3..dd623d0 100644
--- a/packages/SettingsLib/res/values-pt/strings.xml
+++ b/packages/SettingsLib/res/values-pt/strings.xml
@@ -195,7 +195,7 @@
     <string name="bugreport_in_power" msgid="7923901846375587241">"Atalho para relatório do bug"</string>
     <string name="bugreport_in_power_summary" msgid="1778455732762984579">"Mostrar um botão para gerar relatórios de bugs no menu do botão liga/desliga"</string>
     <string name="keep_screen_on" msgid="1146389631208760344">"Permanecer ativo"</string>
-    <string name="keep_screen_on_summary" msgid="2173114350754293009">"A tela nunca entrará em inatividade enquanto estiver carregando."</string>
+    <string name="keep_screen_on_summary" msgid="2173114350754293009">"A tela nunca entrará em suspensão enquanto estiver carregando."</string>
     <string name="bt_hci_snoop_log" msgid="3340699311158865670">"Ativar log de rastreamento Bluetooth HCI"</string>
     <string name="bt_hci_snoop_log_summary" msgid="366083475849911315">"Capturar todos os pacotes Bluetooth HCI em um arquivo (ative o Bluetooth depois de alterar esta configuração)"</string>
     <string name="oem_unlock_enable" msgid="6040763321967327691">"Desbloqueio de OEM"</string>
diff --git a/packages/SettingsLib/res/values-ru/strings.xml b/packages/SettingsLib/res/values-ru/strings.xml
index 77de8db..a421c72 100644
--- a/packages/SettingsLib/res/values-ru/strings.xml
+++ b/packages/SettingsLib/res/values-ru/strings.xml
@@ -56,7 +56,7 @@
     <string name="bluetooth_disconnecting" msgid="8913264760027764974">"Отключение..."</string>
     <string name="bluetooth_connecting" msgid="8555009514614320497">"Подключение..."</string>
     <string name="bluetooth_connected" msgid="5427152882755735944">"Подключено<xliff:g id="ACTIVE_DEVICE">%1$s</xliff:g>"</string>
-    <string name="bluetooth_pairing" msgid="1426882272690346242">"Сопряжение..."</string>
+    <string name="bluetooth_pairing" msgid="1426882272690346242">"Устанавливается соединение..."</string>
     <string name="bluetooth_connected_no_headset" msgid="616068069034994802">"Подключено (кроме звонков)<xliff:g id="ACTIVE_DEVICE">%1$s</xliff:g>"</string>
     <string name="bluetooth_connected_no_a2dp" msgid="3736431800395923868">"Подключено (кроме аудио)<xliff:g id="ACTIVE_DEVICE">%1$s</xliff:g>"</string>
     <string name="bluetooth_connected_no_map" msgid="3200033913678466453">"Подключено (кроме сообщений)<xliff:g id="ACTIVE_DEVICE">%1$s</xliff:g>"</string>
@@ -102,11 +102,11 @@
     <string name="bluetooth_pairing_accept" msgid="6163520056536604875">"Добавить"</string>
     <string name="bluetooth_pairing_accept_all_caps" msgid="6061699265220789149">"ДОБАВИТЬ"</string>
     <string name="bluetooth_pairing_decline" msgid="4185420413578948140">"Отмена"</string>
-    <string name="bluetooth_pairing_will_share_phonebook" msgid="4982239145676394429">"Сопряжение обеспечивает доступ к вашим контактам и журналу звонков при подключении."</string>
-    <string name="bluetooth_pairing_error_message" msgid="3748157733635947087">"Не удалось установить сопряжение с устройством \"<xliff:g id="DEVICE_NAME">%1$s</xliff:g>\"."</string>
-    <string name="bluetooth_pairing_pin_error_message" msgid="8337234855188925274">"Не удалось установить сопряжение с устройством \"<xliff:g id="DEVICE_NAME">%1$s</xliff:g>\", так как введен неверный PIN-код или пароль."</string>
+    <string name="bluetooth_pairing_will_share_phonebook" msgid="4982239145676394429">"Установление соединения обеспечивает доступ к вашим контактам и журналу звонков при подключении."</string>
+    <string name="bluetooth_pairing_error_message" msgid="3748157733635947087">"Не удалось подключиться к устройству \"<xliff:g id="DEVICE_NAME">%1$s</xliff:g>\"."</string>
+    <string name="bluetooth_pairing_pin_error_message" msgid="8337234855188925274">"Не удалось подключиться к устройству \"<xliff:g id="DEVICE_NAME">%1$s</xliff:g>\", так как введен неверный PIN-код или пароль."</string>
     <string name="bluetooth_pairing_device_down_error_message" msgid="7870998403045801381">"Не удается установить соединение с устройством \"<xliff:g id="DEVICE_NAME">%1$s</xliff:g>\"."</string>
-    <string name="bluetooth_pairing_rejected_error_message" msgid="1648157108520832454">"<xliff:g id="DEVICE_NAME">%1$s</xliff:g> не разрешает сопряжение."</string>
+    <string name="bluetooth_pairing_rejected_error_message" msgid="1648157108520832454">"<xliff:g id="DEVICE_NAME">%1$s</xliff:g> не разрешает подключение."</string>
     <string name="bluetooth_talkback_computer" msgid="4875089335641234463">"Компьютер"</string>
     <string name="bluetooth_talkback_headset" msgid="5140152177885220949">"Гарнитура"</string>
     <string name="bluetooth_talkback_phone" msgid="4260255181240622896">"Телефон"</string>
diff --git a/packages/SettingsLib/res/values-sw/arrays.xml b/packages/SettingsLib/res/values-sw/arrays.xml
index f13c2ea..fdf9fd1 100644
--- a/packages/SettingsLib/res/values-sw/arrays.xml
+++ b/packages/SettingsLib/res/values-sw/arrays.xml
@@ -59,7 +59,7 @@
     <item msgid="45075631231212732">"Kila wakati tumia ukakuaji wa HDCP"</item>
   </string-array>
   <string-array name="bluetooth_avrcp_versions">
-    <item msgid="5347678900838034763">"AVRCP 1.4 (Chaguo msingi)"</item>
+    <item msgid="5347678900838034763">"AVRCP 1.4 (Chaguomsingi)"</item>
     <item msgid="2809759619990248160">"AVRCP 1.3"</item>
     <item msgid="6199178154704729352">"AVRCP 1.5"</item>
     <item msgid="5172170854953034852">"AVRCP 1.6"</item>
@@ -71,7 +71,7 @@
     <item msgid="3422726142222090896">"avrcp16"</item>
   </string-array>
   <string-array name="bluetooth_a2dp_codec_titles">
-    <item msgid="7065842274271279580">"Tumia Uteuzi wa Mfumo (Chaguo msingi)"</item>
+    <item msgid="7065842274271279580">"Tumia Uteuzi wa Mfumo (Chaguomsingi)"</item>
     <item msgid="7539690996561263909">"SBC"</item>
     <item msgid="686685526567131661">"AAC"</item>
     <item msgid="5254942598247222737">"Sauti ya <xliff:g id="QUALCOMM">Qualcomm®</xliff:g> <xliff:g id="APTX">aptX™</xliff:g>"</item>
@@ -81,7 +81,7 @@
     <item msgid="3304843301758635896">"Zima Kodeki Zisizo za Lazima"</item>
   </string-array>
   <string-array name="bluetooth_a2dp_codec_summaries">
-    <item msgid="5062108632402595000">"Tumia Uteuzi wa Mfumo (Chaguo msingi)"</item>
+    <item msgid="5062108632402595000">"Tumia Uteuzi wa Mfumo (Chaguomsingi)"</item>
     <item msgid="6898329690939802290">"SBC"</item>
     <item msgid="6839647709301342559">"AAC"</item>
     <item msgid="7848030269621918608">"Sauti ya <xliff:g id="QUALCOMM">Qualcomm®</xliff:g> <xliff:g id="APTX">aptX™</xliff:g>"</item>
@@ -91,38 +91,38 @@
     <item msgid="741805482892725657">"Zima Kodeki Zisizo za Lazima"</item>
   </string-array>
   <string-array name="bluetooth_a2dp_codec_sample_rate_titles">
-    <item msgid="3093023430402746802">"Tumia Uteuzi wa Mfumo (Chaguo msingi)"</item>
+    <item msgid="3093023430402746802">"Tumia Uteuzi wa Mfumo (Chaguomsingi)"</item>
     <item msgid="8895532488906185219">"kHz 44.1"</item>
     <item msgid="2909915718994807056">"kHz 48.0"</item>
     <item msgid="3347287377354164611">"kHz 88.2"</item>
     <item msgid="1234212100239985373">"kHz 96.0"</item>
   </string-array>
   <string-array name="bluetooth_a2dp_codec_sample_rate_summaries">
-    <item msgid="3214516120190965356">"Tumia Uteuzi wa Mfumo (Chaguo msingi)"</item>
+    <item msgid="3214516120190965356">"Tumia Uteuzi wa Mfumo (Chaguomsingi)"</item>
     <item msgid="4482862757811638365">"kHz 44.1"</item>
     <item msgid="354495328188724404">"kHz 48.0"</item>
     <item msgid="7329816882213695083">"kHz 88.2"</item>
     <item msgid="6967397666254430476">"kHz 96.0"</item>
   </string-array>
   <string-array name="bluetooth_a2dp_codec_bits_per_sample_titles">
-    <item msgid="2684127272582591429">"Tumia Uteuzi wa Mfumo (Chaguo msingi)"</item>
+    <item msgid="2684127272582591429">"Tumia Uteuzi wa Mfumo (Chaguomsingi)"</item>
     <item msgid="5618929009984956469">"Biti 16 kwa kila sampuli"</item>
     <item msgid="3412640499234627248">"Biti 24 kwa kila sampuli"</item>
     <item msgid="121583001492929387">"Biti 32 kwa kila sampuli"</item>
   </string-array>
   <string-array name="bluetooth_a2dp_codec_bits_per_sample_summaries">
-    <item msgid="1081159789834584363">"Tumia Uteuzi wa Mfumo (Chaguo msingi)"</item>
+    <item msgid="1081159789834584363">"Tumia Uteuzi wa Mfumo (Chaguomsingi)"</item>
     <item msgid="4726688794884191540">"Biti 16 kwa kila sampuli"</item>
     <item msgid="305344756485516870">"Biti 24 kwa kila sampuli"</item>
     <item msgid="244568657919675099">"Biti 32 kwa kila sampuli"</item>
   </string-array>
   <string-array name="bluetooth_a2dp_codec_channel_mode_titles">
-    <item msgid="5226878858503393706">"Tumia Uteuzi wa Mfumo (Chaguo msingi)"</item>
+    <item msgid="5226878858503393706">"Tumia Uteuzi wa Mfumo (Chaguomsingi)"</item>
     <item msgid="4106832974775067314">"Mono"</item>
     <item msgid="5571632958424639155">"Stereo"</item>
   </string-array>
   <string-array name="bluetooth_a2dp_codec_channel_mode_summaries">
-    <item msgid="4118561796005528173">"Tumia Uteuzi wa Mfumo (Chaguo msingi)"</item>
+    <item msgid="4118561796005528173">"Tumia Uteuzi wa Mfumo (Chaguomsingi)"</item>
     <item msgid="8900559293912978337">"Mono"</item>
     <item msgid="8883739882299884241">"Stereo"</item>
   </string-array>
diff --git a/packages/SettingsLib/res/values-sw/strings.xml b/packages/SettingsLib/res/values-sw/strings.xml
index 53f5d0c..2d752ea 100644
--- a/packages/SettingsLib/res/values-sw/strings.xml
+++ b/packages/SettingsLib/res/values-sw/strings.xml
@@ -138,7 +138,7 @@
     <string name="user_guest" msgid="8475274842845401871">"Aliyealikwa"</string>
     <string name="unknown" msgid="1592123443519355854">"Haijulikani"</string>
     <string name="running_process_item_user_label" msgid="3129887865552025943">"Mtumiaji: <xliff:g id="USER_NAME">%1$s</xliff:g>"</string>
-    <string name="launch_defaults_some" msgid="313159469856372621">"Baadhi ya chaguo msingi zimewekwa"</string>
+    <string name="launch_defaults_some" msgid="313159469856372621">"Baadhi ya chaguomsingi zimewekwa"</string>
     <string name="launch_defaults_none" msgid="4241129108140034876">"Hakuna chaguo-misingi zilizowekwa"</string>
     <string name="tts_settings" msgid="8186971894801348327">"Mipangilio ya kusoma maandishi kwa sauti"</string>
     <string name="tts_settings_title" msgid="1237820681016639683">"Kusoma maandishi kwa sauti"</string>
@@ -157,7 +157,7 @@
     <string name="tts_engine_security_warning" msgid="8786238102020223650">"Hotuba hii inawezesha injini huenda ikaweza kukusanya maandishi ambayo yatazungumziwa, ikijumlisha data ya kibinafsi ya nenosiri na namba ya kaddi ya mkopo. Inatoka kwa injini ya <xliff:g id="TTS_PLUGIN_ENGINE_NAME">%s</xliff:g> Wezesha matumizi ya hotuba hii iliyowezeshwa ya injini?"</string>
     <string name="tts_engine_network_required" msgid="1190837151485314743">"Lugha hii inahitaji muunganisho wa mtandao unaofanya kazi ili kipengele cha kusoma maandishi kwa sauti kifanye kazi."</string>
     <string name="tts_default_sample_string" msgid="4040835213373086322">"Huu ni mfano wa usanisi usemaji"</string>
-    <string name="tts_status_title" msgid="7268566550242584413">"Hali ya lugha chaguo msingi"</string>
+    <string name="tts_status_title" msgid="7268566550242584413">"Hali ya lugha chaguomsingi"</string>
     <string name="tts_status_ok" msgid="1309762510278029765">"<xliff:g id="LOCALE">%1$s</xliff:g> inaweza kutumiwa kikamilifu"</string>
     <string name="tts_status_requires_network" msgid="6042500821503226892">"<xliff:g id="LOCALE">%1$s</xliff:g> inahitaji muunganisho wa mtandao"</string>
     <string name="tts_status_not_supported" msgid="4491154212762472495">"<xliff:g id="LOCALE">%1$s</xliff:g> haiwezi kutumiwa"</string>
@@ -167,7 +167,7 @@
     <string name="tts_engine_preference_section_title" msgid="448294500990971413">"Injini inayofaa"</string>
     <string name="tts_general_section_title" msgid="4402572014604490502">"Kwa ujumla"</string>
     <string name="tts_reset_speech_pitch_title" msgid="5789394019544785915">"Weka upya mipangilio ya ubora wa matamshi"</string>
-    <string name="tts_reset_speech_pitch_summary" msgid="8700539616245004418">"Rejesha mipangilio ya ubora wa matamshi kuwa ya chaguo msingi."</string>
+    <string name="tts_reset_speech_pitch_summary" msgid="8700539616245004418">"Rejesha mipangilio ya ubora wa matamshi kuwa ya chaguomsingi."</string>
   <string-array name="tts_rate_entries">
     <item msgid="6695494874362656215">"Polepole sana"</item>
     <item msgid="4795095314303559268">"Polepole"</item>
@@ -331,7 +331,7 @@
     <string name="local_backup_password_toast_confirmation_mismatch" msgid="7805892532752708288">"Nenosiri jipya na uthibitisho havioani"</string>
     <string name="local_backup_password_toast_validation_failure" msgid="5646377234895626531">"Imeshindwa kuweka nenosiri la hifadhi rudufu"</string>
   <string-array name="color_mode_names">
-    <item msgid="2425514299220523812">"Maridadi (chaguo msingi)"</item>
+    <item msgid="2425514299220523812">"Maridadi (chaguomsingi)"</item>
     <item msgid="8446070607501413455">"Asili"</item>
     <item msgid="6553408765810699025">"Muundo-msingi"</item>
   </string-array>
@@ -410,7 +410,7 @@
     <string name="charge_length_format" msgid="8978516217024434156">"<xliff:g id="ID_1">%1$s</xliff:g> zilizopita"</string>
     <string name="remaining_length_format" msgid="7886337596669190587">"Zimesalia <xliff:g id="ID_1">%1$s</xliff:g>"</string>
     <string name="screen_zoom_summary_small" msgid="5867245310241621570">"Ndogo"</string>
-    <string name="screen_zoom_summary_default" msgid="2247006805614056507">"Chaguo msingi"</string>
+    <string name="screen_zoom_summary_default" msgid="2247006805614056507">"Chaguomsingi"</string>
     <string name="screen_zoom_summary_large" msgid="4835294730065424084">"Kubwa"</string>
     <string name="screen_zoom_summary_very_large" msgid="7108563375663670067">"Kubwa kiasi"</string>
     <string name="screen_zoom_summary_extremely_large" msgid="7427320168263276227">"Kubwa zaidi"</string>
diff --git a/packages/SettingsLib/src/com/android/settingslib/deviceinfo/AbstractWifiMacAddressPreferenceController.java b/packages/SettingsLib/src/com/android/settingslib/deviceinfo/AbstractWifiMacAddressPreferenceController.java
index 89d2595..ffbda3a 100644
--- a/packages/SettingsLib/src/com/android/settingslib/deviceinfo/AbstractWifiMacAddressPreferenceController.java
+++ b/packages/SettingsLib/src/com/android/settingslib/deviceinfo/AbstractWifiMacAddressPreferenceController.java
@@ -38,6 +38,10 @@
 
     @VisibleForTesting
     static final String KEY_WIFI_MAC_ADDRESS = "wifi_mac_address";
+    @VisibleForTesting
+    static final int OFF = 0;
+    @VisibleForTesting
+    static final int ON = 1;
 
     private static final String[] CONNECTIVITY_INTENTS = {
             ConnectivityManager.CONNECTIVITY_ACTION,
@@ -80,13 +84,14 @@
     protected void updateConnectivity() {
         WifiInfo wifiInfo = mWifiManager.getConnectionInfo();
         final int macRandomizationMode = Settings.Global.getInt(mContext.getContentResolver(),
-                Settings.Global.WIFI_CONNECTED_MAC_RANDOMIZATION_ENABLED, 0);
+                Settings.Global.WIFI_CONNECTED_MAC_RANDOMIZATION_ENABLED, OFF);
         final String macAddress = wifiInfo == null ? null : wifiInfo.getMacAddress();
 
-        if (TextUtils.isEmpty(macAddress)) {
-            mWifiMacAddress.setSummary(R.string.status_unavailable);
-        } else if (macRandomizationMode == 1 && WifiInfo.DEFAULT_MAC_ADDRESS.equals(macAddress)) {
+        if (macRandomizationMode == ON && WifiInfo.DEFAULT_MAC_ADDRESS.equals(macAddress)) {
             mWifiMacAddress.setSummary(R.string.wifi_status_mac_randomized);
+        } else if (TextUtils.isEmpty(macAddress)
+                || WifiInfo.DEFAULT_MAC_ADDRESS.equals(macAddress)) {
+            mWifiMacAddress.setSummary(R.string.status_unavailable);
         } else {
             mWifiMacAddress.setSummary(macAddress);
         }
diff --git a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/deviceinfo/WifiMacAddressPreferenceControllerTest.java b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/deviceinfo/WifiMacAddressPreferenceControllerTest.java
index ddbcb87..757df5b 100644
--- a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/deviceinfo/WifiMacAddressPreferenceControllerTest.java
+++ b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/deviceinfo/WifiMacAddressPreferenceControllerTest.java
@@ -16,11 +16,10 @@
 
 package com.android.settingslib.deviceinfo;
 
+import static com.google.common.truth.Truth.assertThat;
 import static com.google.common.truth.Truth.assertWithMessage;
 import static org.mockito.Mockito.doReturn;
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.times;
-import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.spy;
 
 import android.annotation.SuppressLint;
 import android.content.Context;
@@ -40,6 +39,7 @@
 import org.junit.runner.RunWith;
 import org.mockito.Mock;
 import org.mockito.MockitoAnnotations;
+import org.robolectric.RuntimeEnvironment;
 
 import java.util.Arrays;
 import java.util.List;
@@ -48,12 +48,16 @@
 @RunWith(SettingsLibRobolectricTestRunner.class)
 public class WifiMacAddressPreferenceControllerTest {
     @Mock
-    private Context mContext;
-    @Mock
     private Lifecycle mLifecycle;
     @Mock
     private PreferenceScreen mScreen;
     @Mock
+    private WifiManager mWifiManager;
+    @Mock
+    private WifiInfo mWifiInfo;
+
+    private AbstractWifiMacAddressPreferenceController mController;
+    private Context mContext;
     private Preference mPreference;
 
     private static final String TEST_MAC_ADDRESS = "00:11:22:33:44:55";
@@ -61,14 +65,20 @@
     @Before
     public void setUp() {
         MockitoAnnotations.initMocks(this);
+
+        mContext = spy(RuntimeEnvironment.application);
+        mPreference = new Preference(mContext);
+
         doReturn(mPreference).when(mScreen)
                 .findPreference(AbstractWifiMacAddressPreferenceController.KEY_WIFI_MAC_ADDRESS);
+        doReturn(mWifiManager).when(mContext).getSystemService(WifiManager.class);
+        doReturn(mWifiInfo).when(mWifiManager).getConnectionInfo();
+
+        mController = new ConcreteWifiMacAddressPreferenceController(mContext, mLifecycle);
     }
 
     @Test
     public void testHasIntentFilters() {
-        final AbstractWifiMacAddressPreferenceController wifiMacAddressPreferenceController =
-                new ConcreteWifiMacAddressPreferenceController(mContext, mLifecycle);
         final List<String> expectedIntents = Arrays.asList(
                 ConnectivityManager.CONNECTIVITY_ACTION,
                 WifiManager.LINK_CONFIGURATION_CHANGED_ACTION,
@@ -76,37 +86,110 @@
 
 
         assertWithMessage("Intent filter should contain expected intents")
-                .that(wifiMacAddressPreferenceController.getConnectivityIntents())
+                .that(mController.getConnectivityIntents())
                 .asList().containsAllIn(expectedIntents);
     }
 
     @Test
-    public void testWifiMacAddress() {
-        final WifiManager wifiManager = mock(WifiManager.class);
-        final WifiInfo wifiInfo = mock(WifiInfo.class);
-
-        doReturn(null).when(wifiManager).getConnectionInfo();
-        doReturn(wifiManager).when(mContext).getSystemService(WifiManager.class);
-
-        final AbstractWifiMacAddressPreferenceController wifiMacAddressPreferenceController =
-                new ConcreteWifiMacAddressPreferenceController(mContext, mLifecycle);
-
-        wifiMacAddressPreferenceController.displayPreference(mScreen);
-        verify(mPreference).setSummary(R.string.status_unavailable);
-
-        doReturn(wifiInfo).when(wifiManager).getConnectionInfo();
-        doReturn(TEST_MAC_ADDRESS).when(wifiInfo).getMacAddress();
-        wifiMacAddressPreferenceController.displayPreference(mScreen);
-        verify(mPreference).setSummary(TEST_MAC_ADDRESS);
-
+    public void updateConnectivity_nullWifiInfoWithMacRandomizationOff_setMacUnavailable() {
         Settings.Global.putInt(mContext.getContentResolver(),
-                Settings.Global.WIFI_CONNECTED_MAC_RANDOMIZATION_ENABLED, 1);
-        wifiMacAddressPreferenceController.displayPreference(mScreen);
-        verify(mPreference, times(2)).setSummary(TEST_MAC_ADDRESS);
+                Settings.Global.WIFI_CONNECTED_MAC_RANDOMIZATION_ENABLED,
+                AbstractWifiMacAddressPreferenceController.OFF);
+        doReturn(null).when(mWifiManager).getConnectionInfo();
 
-        doReturn(WifiInfo.DEFAULT_MAC_ADDRESS).when(wifiInfo).getMacAddress();
-        wifiMacAddressPreferenceController.displayPreference(mScreen);
-        verify(mPreference).setSummary(R.string.wifi_status_mac_randomized);
+        mController.displayPreference(mScreen);
+
+        assertThat(mPreference.getSummary())
+                .isEqualTo(mContext.getString(R.string.status_unavailable));
+    }
+
+    @Test
+    public void updateConnectivity_nullMacWithMacRandomizationOff_setMacUnavailable() {
+        Settings.Global.putInt(mContext.getContentResolver(),
+                Settings.Global.WIFI_CONNECTED_MAC_RANDOMIZATION_ENABLED,
+                AbstractWifiMacAddressPreferenceController.OFF);
+        doReturn(null).when(mWifiInfo).getMacAddress();
+
+        mController.displayPreference(mScreen);
+
+        assertThat(mPreference.getSummary())
+                .isEqualTo(mContext.getString(R.string.status_unavailable));
+    }
+
+    @Test
+    public void updateConnectivity_defaultMacWithMacRandomizationOff_setMacUnavailable() {
+        Settings.Global.putInt(mContext.getContentResolver(),
+                Settings.Global.WIFI_CONNECTED_MAC_RANDOMIZATION_ENABLED,
+                AbstractWifiMacAddressPreferenceController.OFF);
+        doReturn(WifiInfo.DEFAULT_MAC_ADDRESS).when(mWifiInfo).getMacAddress();
+
+        mController.displayPreference(mScreen);
+
+        assertThat(mPreference.getSummary())
+                .isEqualTo(mContext.getString(R.string.status_unavailable));
+    }
+
+    @Test
+    public void updateConnectivity_validMacWithMacRandomizationOff_setValidMac() {
+        Settings.Global.putInt(mContext.getContentResolver(),
+                Settings.Global.WIFI_CONNECTED_MAC_RANDOMIZATION_ENABLED,
+                AbstractWifiMacAddressPreferenceController.OFF);
+        doReturn(TEST_MAC_ADDRESS).when(mWifiInfo).getMacAddress();
+
+        mController.displayPreference(mScreen);
+
+        assertThat(mPreference.getSummary()).isEqualTo(TEST_MAC_ADDRESS);
+    }
+
+    @Test
+    public void updateConnectivity_nullWifiInfoWithMacRandomizationOn_setMacUnavailable() {
+        Settings.Global.putInt(mContext.getContentResolver(),
+                Settings.Global.WIFI_CONNECTED_MAC_RANDOMIZATION_ENABLED,
+                AbstractWifiMacAddressPreferenceController.ON);
+        doReturn(null).when(mWifiManager).getConnectionInfo();
+
+        mController.displayPreference(mScreen);
+
+        assertThat(mPreference.getSummary())
+                .isEqualTo(mContext.getString(R.string.status_unavailable));
+    }
+
+    @Test
+    public void updateConnectivity_nullMacWithMacRandomizationOn_setMacUnavailable() {
+        Settings.Global.putInt(mContext.getContentResolver(),
+                Settings.Global.WIFI_CONNECTED_MAC_RANDOMIZATION_ENABLED,
+                AbstractWifiMacAddressPreferenceController.ON);
+        doReturn(null).when(mWifiInfo).getMacAddress();
+
+        mController.displayPreference(mScreen);
+
+        assertThat(mPreference.getSummary())
+                .isEqualTo(mContext.getString(R.string.status_unavailable));
+    }
+
+    @Test
+    public void updateConnectivity_defaultMacWithMacRandomizationOn_setMacRandomized() {
+        Settings.Global.putInt(mContext.getContentResolver(),
+                Settings.Global.WIFI_CONNECTED_MAC_RANDOMIZATION_ENABLED,
+                AbstractWifiMacAddressPreferenceController.ON);
+        doReturn(WifiInfo.DEFAULT_MAC_ADDRESS).when(mWifiInfo).getMacAddress();
+
+        mController.displayPreference(mScreen);
+
+        assertThat(mPreference.getSummary())
+                .isEqualTo(mContext.getString(R.string.wifi_status_mac_randomized));
+    }
+
+    @Test
+    public void updateConnectivity_validMacWithMacRandomizationOn_setValidMac() {
+        Settings.Global.putInt(mContext.getContentResolver(),
+                Settings.Global.WIFI_CONNECTED_MAC_RANDOMIZATION_ENABLED,
+                AbstractWifiMacAddressPreferenceController.ON);
+        doReturn(TEST_MAC_ADDRESS).when(mWifiInfo).getMacAddress();
+
+        mController.displayPreference(mScreen);
+
+        assertThat(mPreference.getSummary()).isEqualTo(TEST_MAC_ADDRESS);
     }
 
     private static class ConcreteWifiMacAddressPreferenceController
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationSnooze.java b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationSnooze.java
index d84d3dc..b3ab109 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationSnooze.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationSnooze.java
@@ -256,10 +256,14 @@
         int count = showInHours ? (minutes / 60) : minutes;
         String description = res.getQuantityString(pluralResId, count, count);
         String resultText = String.format(res.getString(R.string.snoozed_for_time), description);
+        AccessibilityAction action = new AccessibilityAction(accessibilityActionId, description);
+        final int index = resultText.indexOf(description);
+        if (index == -1) {
+            return new NotificationSnoozeOption(null, minutes, description, resultText, action);
+        }
         SpannableString string = new SpannableString(resultText);
         string.setSpan(new StyleSpan(Typeface.BOLD),
-                resultText.length() - description.length(), resultText.length(), 0 /* flags */);
-        AccessibilityAction action = new AccessibilityAction(accessibilityActionId, description);
+                index, index + description.length(), 0 /* flags */);
         return new NotificationSnoozeOption(null, minutes, description, string,
                 action);
     }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelView.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelView.java
index 969b1b7..492efa2 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelView.java
@@ -223,6 +223,7 @@
     private boolean mClosingWithAlphaFadeOut;
     private boolean mHeadsUpAnimatingAway;
     private boolean mLaunchingAffordance;
+    private boolean mAffordanceHasPreview;
     private FalsingManager mFalsingManager;
     private String mLastCameraLaunchSource = KeyguardBottomAreaView.CAMERA_LAUNCH_SOURCE_AFFORDANCE;
 
@@ -2571,6 +2572,7 @@
         } else {
             animate = false;
         }
+        mAffordanceHasPreview = mKeyguardBottomArea.getRightPreview() != null;
         mAffordanceHelper.launchAffordance(animate, getLayoutDirection() == LAYOUT_DIRECTION_RTL);
     }
 
@@ -2616,6 +2618,13 @@
     }
 
     /**
+     * Return true when a bottom affordance is launching an occluded activity with a splash screen.
+     */
+    public boolean isLaunchingAffordanceWithPreview() {
+        return mLaunchingAffordance && mAffordanceHasPreview;
+    }
+
+    /**
      * Whether the camera application can be launched for the camera launch gesture.
      *
      * @param keyguardIsShowing whether keyguard is being shown
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/ScrimController.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/ScrimController.java
index fe141661..f573642 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/ScrimController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/ScrimController.java
@@ -889,9 +889,14 @@
     }
 
     public void setHasBackdrop(boolean hasBackdrop) {
-        ScrimState[] states = ScrimState.values();
-        for (int i = 0; i < states.length; i++) {
-            states[i].setHasBackdrop(hasBackdrop);
+        for (ScrimState state : ScrimState.values()) {
+            state.setHasBackdrop(hasBackdrop);
+        }
+    }
+
+    public void setLaunchingAffordanceWithPreview(boolean launchingAffordanceWithPreview) {
+        for (ScrimState state : ScrimState.values()) {
+            state.setLaunchingAffordanceWithPreview(launchingAffordanceWithPreview);
         }
     }
 
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/ScrimState.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/ScrimState.java
index ec6ada4..cdbad59 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/ScrimState.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/ScrimState.java
@@ -144,6 +144,7 @@
             mCurrentBehindAlpha = 0;
             mCurrentInFrontAlpha = 0;
             mAnimationDuration = StatusBar.FADE_KEYGUARD_DURATION;
+            mAnimateChange = !mLaunchingAffordanceWithPreview;
 
             if (previousState == ScrimState.AOD || previousState == ScrimState.PULSING) {
                 // Fade from black to transparent when coming directly from AOD
@@ -177,6 +178,7 @@
     boolean mWallpaperSupportsAmbientMode;
     int mIndex;
     boolean mHasBackdrop;
+    boolean mLaunchingAffordanceWithPreview;
 
     ScrimState(int index) {
         mIndex = index;
@@ -249,6 +251,10 @@
         mWallpaperSupportsAmbientMode = wallpaperSupportsAmbientMode;
     }
 
+    public void setLaunchingAffordanceWithPreview(boolean launchingAffordanceWithPreview) {
+        mLaunchingAffordanceWithPreview = launchingAffordanceWithPreview;
+    }
+
     public boolean isLowPowerState() {
         return false;
     }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java
index d8e3dd8..6ce631f 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java
@@ -4750,6 +4750,10 @@
         mScrimController.setExpansionAffectsAlpha(
                 !mBiometricUnlockController.isBiometricUnlock());
 
+        boolean launchingAffordanceWithPreview =
+                mNotificationPanel.isLaunchingAffordanceWithPreview();
+        mScrimController.setLaunchingAffordanceWithPreview(launchingAffordanceWithPreview);
+
         if (mBouncerShowing) {
             // Bouncer needs the front scrim when it's on top of an activity,
             // tapping on a notification, editing QS or being dismissed by
@@ -4757,7 +4761,8 @@
             ScrimState state = mStatusBarKeyguardViewManager.bouncerNeedsScrimming()
                     ? ScrimState.BOUNCER_SCRIMMED : ScrimState.BOUNCER;
             mScrimController.transitionTo(state);
-        } else if (mLaunchCameraOnScreenTurningOn || isInLaunchTransition()) {
+        } else if (isInLaunchTransition() || mLaunchCameraOnScreenTurningOn
+                || launchingAffordanceWithPreview) {
             mScrimController.transitionTo(ScrimState.UNLOCKED, mUnlockScrimCallback);
         } else if (mBrightnessMirrorVisible) {
             mScrimController.transitionTo(ScrimState.BRIGHTNESS_MIRROR);
diff --git a/services/core/Android.bp b/services/core/Android.bp
index ee7a5e2..d9519e0 100644
--- a/services/core/Android.bp
+++ b/services/core/Android.bp
@@ -26,7 +26,6 @@
         "android.hardware.light-V2.0-java",
         "android.hardware.power-V1.0-java",
         "android.hardware.tv.cec-V1.0-java",
-        "android.hidl.manager-V1.0-java",
     ],
 
     static_libs: [
@@ -44,6 +43,7 @@
         "android.hardware.vibrator-V1.0-java",
         "android.hardware.configstore-V1.0-java",
         "android.hardware.contexthub-V1.0-java",
+        "android.hidl.manager-V1.0-java",
     ],
 }
 
diff --git a/services/core/java/com/android/server/NetworkTimeUpdateService.java b/services/core/java/com/android/server/NetworkTimeUpdateService.java
index b3a8fb6..1ff455ea 100644
--- a/services/core/java/com/android/server/NetworkTimeUpdateService.java
+++ b/services/core/java/com/android/server/NetworkTimeUpdateService.java
@@ -16,314 +16,15 @@
 
 package com.android.server;
 
-import android.app.AlarmManager;
-import android.app.PendingIntent;
-import android.content.BroadcastReceiver;
-import android.content.ContentResolver;
-import android.content.Context;
-import android.content.Intent;
-import android.content.IntentFilter;
-import android.database.ContentObserver;
-import android.net.ConnectivityManager;
-import android.net.ConnectivityManager.NetworkCallback;
-import android.net.Network;
-import android.os.Binder;
-import android.os.Handler;
-import android.os.HandlerThread;
-import android.os.Looper;
-import android.os.Message;
-import android.os.PowerManager;
-import android.os.SystemClock;
-import android.provider.Settings;
-import android.util.Log;
-import android.util.NtpTrustedTime;
-import android.util.TimeUtils;
-
-import com.android.internal.telephony.TelephonyIntents;
-import com.android.internal.util.DumpUtils;
-
-import java.io.FileDescriptor;
-import java.io.PrintWriter;
+import android.os.IBinder;
 
 /**
- * Monitors the network time and updates the system time if it is out of sync
- * and there hasn't been any NITZ update from the carrier recently.
- * If looking up the network time fails for some reason, it tries a few times with a short
- * interval and then resets to checking on longer intervals.
- * <p>
- * If the user enables AUTO_TIME, it will check immediately for the network time, if NITZ wasn't
- * available.
- * </p>
+ * An interface for NetworkTimeUpdateService implementations. Eventually part or all of this service
+ * will be subsumed into {@link com.android.server.timedetector.TimeDetectorService}. In the
+ * meantime this interface allows Android to use either the old or new implementation.
  */
-public class NetworkTimeUpdateService extends Binder {
-
-    private static final String TAG = "NetworkTimeUpdateService";
-    private static final boolean DBG = false;
-
-    private static final int EVENT_AUTO_TIME_CHANGED = 1;
-    private static final int EVENT_POLL_NETWORK_TIME = 2;
-    private static final int EVENT_NETWORK_CHANGED = 3;
-
-    private static final String ACTION_POLL =
-            "com.android.server.NetworkTimeUpdateService.action.POLL";
-
-    private static final int POLL_REQUEST = 0;
-
-    private static final long NOT_SET = -1;
-    private long mNitzTimeSetTime = NOT_SET;
-    private Network mDefaultNetwork = null;
-
-    private final Context mContext;
-    private final NtpTrustedTime mTime;
-    private final AlarmManager mAlarmManager;
-    private final ConnectivityManager mCM;
-    private final PendingIntent mPendingPollIntent;
-    private final PowerManager.WakeLock mWakeLock;
-
-    // NTP lookup is done on this thread and handler
-    private Handler mHandler;
-    private SettingsObserver mSettingsObserver;
-    private NetworkTimeUpdateCallback mNetworkTimeUpdateCallback;
-
-    // Normal polling frequency
-    private final long mPollingIntervalMs;
-    // Try-again polling interval, in case the network request failed
-    private final long mPollingIntervalShorterMs;
-    // Number of times to try again
-    private final int mTryAgainTimesMax;
-    // If the time difference is greater than this threshold, then update the time.
-    private final int mTimeErrorThresholdMs;
-    // Keeps track of how many quick attempts were made to fetch NTP time.
-    // During bootup, the network may not have been up yet, or it's taking time for the
-    // connection to happen.
-    private int mTryAgainCounter;
-
-    public NetworkTimeUpdateService(Context context) {
-        mContext = context;
-        mTime = NtpTrustedTime.getInstance(context);
-        mAlarmManager = mContext.getSystemService(AlarmManager.class);
-        mCM = mContext.getSystemService(ConnectivityManager.class);
-
-        Intent pollIntent = new Intent(ACTION_POLL, null);
-        mPendingPollIntent = PendingIntent.getBroadcast(mContext, POLL_REQUEST, pollIntent, 0);
-
-        mPollingIntervalMs = mContext.getResources().getInteger(
-                com.android.internal.R.integer.config_ntpPollingInterval);
-        mPollingIntervalShorterMs = mContext.getResources().getInteger(
-                com.android.internal.R.integer.config_ntpPollingIntervalShorter);
-        mTryAgainTimesMax = mContext.getResources().getInteger(
-                com.android.internal.R.integer.config_ntpRetry);
-        mTimeErrorThresholdMs = mContext.getResources().getInteger(
-                com.android.internal.R.integer.config_ntpThreshold);
-
-        mWakeLock = context.getSystemService(PowerManager.class).newWakeLock(
-                PowerManager.PARTIAL_WAKE_LOCK, TAG);
-    }
+public interface NetworkTimeUpdateService extends IBinder {
 
     /** Initialize the receivers and initiate the first NTP request */
-    public void systemRunning() {
-        registerForTelephonyIntents();
-        registerForAlarms();
-
-        HandlerThread thread = new HandlerThread(TAG);
-        thread.start();
-        mHandler = new MyHandler(thread.getLooper());
-        mNetworkTimeUpdateCallback = new NetworkTimeUpdateCallback();
-        mCM.registerDefaultNetworkCallback(mNetworkTimeUpdateCallback, mHandler);
-
-        mSettingsObserver = new SettingsObserver(mHandler, EVENT_AUTO_TIME_CHANGED);
-        mSettingsObserver.observe(mContext);
-    }
-
-    private void registerForTelephonyIntents() {
-        IntentFilter intentFilter = new IntentFilter();
-        intentFilter.addAction(TelephonyIntents.ACTION_NETWORK_SET_TIME);
-        mContext.registerReceiver(mNitzReceiver, intentFilter);
-    }
-
-    private void registerForAlarms() {
-        mContext.registerReceiver(
-            new BroadcastReceiver() {
-                @Override
-                public void onReceive(Context context, Intent intent) {
-                    mHandler.obtainMessage(EVENT_POLL_NETWORK_TIME).sendToTarget();
-                }
-            }, new IntentFilter(ACTION_POLL));
-    }
-
-    private void onPollNetworkTime(int event) {
-        // If Automatic time is not set, don't bother. Similarly, if we don't
-        // have any default network, don't bother.
-        if (mDefaultNetwork == null) return;
-        mWakeLock.acquire();
-        try {
-            onPollNetworkTimeUnderWakeLock(event);
-        } finally {
-            mWakeLock.release();
-        }
-    }
-
-    private void onPollNetworkTimeUnderWakeLock(int event) {
-        // Force an NTP fix when outdated
-        if (mTime.getCacheAge() >= mPollingIntervalMs) {
-            if (DBG) Log.d(TAG, "Stale NTP fix; forcing refresh");
-            mTime.forceRefresh();
-        }
-
-        if (mTime.getCacheAge() < mPollingIntervalMs) {
-            // Obtained fresh fix; schedule next normal update
-            resetAlarm(mPollingIntervalMs);
-            if (isAutomaticTimeRequested()) {
-                updateSystemClock(event);
-            }
-
-        } else {
-            // No fresh fix; schedule retry
-            mTryAgainCounter++;
-            if (mTryAgainTimesMax < 0 || mTryAgainCounter <= mTryAgainTimesMax) {
-                resetAlarm(mPollingIntervalShorterMs);
-            } else {
-                // Try much later
-                mTryAgainCounter = 0;
-                resetAlarm(mPollingIntervalMs);
-            }
-        }
-    }
-
-    private long getNitzAge() {
-        if (mNitzTimeSetTime == NOT_SET) {
-            return Long.MAX_VALUE;
-        } else {
-            return SystemClock.elapsedRealtime() - mNitzTimeSetTime;
-        }
-    }
-
-    /**
-     * Consider updating system clock based on current NTP fix, if requested by
-     * user, significant enough delta, and we don't have a recent NITZ.
-     */
-    private void updateSystemClock(int event) {
-        final boolean forceUpdate = (event == EVENT_AUTO_TIME_CHANGED);
-        if (!forceUpdate) {
-            if (getNitzAge() < mPollingIntervalMs) {
-                if (DBG) Log.d(TAG, "Ignoring NTP update due to recent NITZ");
-                return;
-            }
-
-            final long skew = Math.abs(mTime.currentTimeMillis() - System.currentTimeMillis());
-            if (skew < mTimeErrorThresholdMs) {
-                if (DBG) Log.d(TAG, "Ignoring NTP update due to low skew");
-                return;
-            }
-        }
-
-        SystemClock.setCurrentTimeMillis(mTime.currentTimeMillis());
-    }
-
-    /**
-     * Cancel old alarm and starts a new one for the specified interval.
-     *
-     * @param interval when to trigger the alarm, starting from now.
-     */
-    private void resetAlarm(long interval) {
-        mAlarmManager.cancel(mPendingPollIntent);
-        long now = SystemClock.elapsedRealtime();
-        long next = now + interval;
-        mAlarmManager.set(AlarmManager.ELAPSED_REALTIME, next, mPendingPollIntent);
-    }
-
-    /**
-     * Checks if the user prefers to automatically set the time.
-     */
-    private boolean isAutomaticTimeRequested() {
-        return Settings.Global.getInt(
-                mContext.getContentResolver(), Settings.Global.AUTO_TIME, 0) != 0;
-    }
-
-    /** Receiver for Nitz time events */
-    private BroadcastReceiver mNitzReceiver = new BroadcastReceiver() {
-
-        @Override
-        public void onReceive(Context context, Intent intent) {
-            String action = intent.getAction();
-            if (DBG) Log.d(TAG, "Received " + action);
-            if (TelephonyIntents.ACTION_NETWORK_SET_TIME.equals(action)) {
-                mNitzTimeSetTime = SystemClock.elapsedRealtime();
-            }
-        }
-    };
-
-    /** Handler to do the network accesses on */
-    private class MyHandler extends Handler {
-
-        public MyHandler(Looper l) {
-            super(l);
-        }
-
-        @Override
-        public void handleMessage(Message msg) {
-            switch (msg.what) {
-                case EVENT_AUTO_TIME_CHANGED:
-                case EVENT_POLL_NETWORK_TIME:
-                case EVENT_NETWORK_CHANGED:
-                    onPollNetworkTime(msg.what);
-                    break;
-            }
-        }
-    }
-
-    private class NetworkTimeUpdateCallback extends NetworkCallback {
-        @Override
-        public void onAvailable(Network network) {
-            Log.d(TAG, String.format("New default network %s; checking time.", network));
-            mDefaultNetwork = network;
-            // Running on mHandler so invoke directly.
-            onPollNetworkTime(EVENT_NETWORK_CHANGED);
-        }
-
-        @Override
-        public void onLost(Network network) {
-            if (network.equals(mDefaultNetwork)) mDefaultNetwork = null;
-        }
-    }
-
-    /** Observer to watch for changes to the AUTO_TIME setting */
-    private static class SettingsObserver extends ContentObserver {
-
-        private int mMsg;
-        private Handler mHandler;
-
-        SettingsObserver(Handler handler, int msg) {
-            super(handler);
-            mHandler = handler;
-            mMsg = msg;
-        }
-
-        void observe(Context context) {
-            ContentResolver resolver = context.getContentResolver();
-            resolver.registerContentObserver(Settings.Global.getUriFor(Settings.Global.AUTO_TIME),
-                    false, this);
-        }
-
-        @Override
-        public void onChange(boolean selfChange) {
-            mHandler.obtainMessage(mMsg).sendToTarget();
-        }
-    }
-
-    @Override
-    protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
-        if (!DumpUtils.checkDumpPermission(mContext, TAG, pw)) return;
-        pw.print("PollingIntervalMs: ");
-        TimeUtils.formatDuration(mPollingIntervalMs, pw);
-        pw.print("\nPollingIntervalShorterMs: ");
-        TimeUtils.formatDuration(mPollingIntervalShorterMs, pw);
-        pw.println("\nTryAgainTimesMax: " + mTryAgainTimesMax);
-        pw.print("TimeErrorThresholdMs: ");
-        TimeUtils.formatDuration(mTimeErrorThresholdMs, pw);
-        pw.println("\nTryAgainCounter: " + mTryAgainCounter);
-        pw.println("NTP cache age: " + mTime.getCacheAge());
-        pw.println("NTP cache certainty: " + mTime.getCacheCertainty());
-        pw.println();
-    }
+    void systemRunning();
 }
diff --git a/services/core/java/com/android/server/NewNetworkTimeUpdateService.java b/services/core/java/com/android/server/NewNetworkTimeUpdateService.java
new file mode 100644
index 0000000..d21741a
--- /dev/null
+++ b/services/core/java/com/android/server/NewNetworkTimeUpdateService.java
@@ -0,0 +1,329 @@
+/*
+ * Copyright (C) 2010 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.server;
+
+import android.app.AlarmManager;
+import android.app.PendingIntent;
+import android.content.BroadcastReceiver;
+import android.content.ContentResolver;
+import android.content.Context;
+import android.content.Intent;
+import android.content.IntentFilter;
+import android.database.ContentObserver;
+import android.net.ConnectivityManager;
+import android.net.ConnectivityManager.NetworkCallback;
+import android.net.Network;
+import android.os.Binder;
+import android.os.Handler;
+import android.os.HandlerThread;
+import android.os.Looper;
+import android.os.Message;
+import android.os.PowerManager;
+import android.os.SystemClock;
+import android.provider.Settings;
+import android.util.Log;
+import android.util.NtpTrustedTime;
+import android.util.TimeUtils;
+
+import com.android.internal.telephony.TelephonyIntents;
+import com.android.internal.util.DumpUtils;
+
+import java.io.FileDescriptor;
+import java.io.PrintWriter;
+
+/**
+ * Monitors the network time and updates the system time if it is out of sync
+ * and there hasn't been any NITZ update from the carrier recently.
+ * If looking up the network time fails for some reason, it tries a few times with a short
+ * interval and then resets to checking on longer intervals.
+ * <p>
+ * If the user enables AUTO_TIME, it will check immediately for the network time, if NITZ wasn't
+ * available.
+ * </p>
+ */
+public class NewNetworkTimeUpdateService extends Binder implements NetworkTimeUpdateService {
+
+    private static final String TAG = "NetworkTimeUpdateService";
+    private static final boolean DBG = false;
+
+    private static final int EVENT_AUTO_TIME_CHANGED = 1;
+    private static final int EVENT_POLL_NETWORK_TIME = 2;
+    private static final int EVENT_NETWORK_CHANGED = 3;
+
+    private static final String ACTION_POLL =
+            "com.android.server.NetworkTimeUpdateService.action.POLL";
+
+    private static final int POLL_REQUEST = 0;
+
+    private static final long NOT_SET = -1;
+    private long mNitzTimeSetTime = NOT_SET;
+    private Network mDefaultNetwork = null;
+
+    private final Context mContext;
+    private final NtpTrustedTime mTime;
+    private final AlarmManager mAlarmManager;
+    private final ConnectivityManager mCM;
+    private final PendingIntent mPendingPollIntent;
+    private final PowerManager.WakeLock mWakeLock;
+
+    // NTP lookup is done on this thread and handler
+    private Handler mHandler;
+    private SettingsObserver mSettingsObserver;
+    private NetworkTimeUpdateCallback mNetworkTimeUpdateCallback;
+
+    // Normal polling frequency
+    private final long mPollingIntervalMs;
+    // Try-again polling interval, in case the network request failed
+    private final long mPollingIntervalShorterMs;
+    // Number of times to try again
+    private final int mTryAgainTimesMax;
+    // If the time difference is greater than this threshold, then update the time.
+    private final int mTimeErrorThresholdMs;
+    // Keeps track of how many quick attempts were made to fetch NTP time.
+    // During bootup, the network may not have been up yet, or it's taking time for the
+    // connection to happen.
+    private int mTryAgainCounter;
+
+    public NewNetworkTimeUpdateService(Context context) {
+        mContext = context;
+        mTime = NtpTrustedTime.getInstance(context);
+        mAlarmManager = mContext.getSystemService(AlarmManager.class);
+        mCM = mContext.getSystemService(ConnectivityManager.class);
+
+        Intent pollIntent = new Intent(ACTION_POLL, null);
+        mPendingPollIntent = PendingIntent.getBroadcast(mContext, POLL_REQUEST, pollIntent, 0);
+
+        mPollingIntervalMs = mContext.getResources().getInteger(
+                com.android.internal.R.integer.config_ntpPollingInterval);
+        mPollingIntervalShorterMs = mContext.getResources().getInteger(
+                com.android.internal.R.integer.config_ntpPollingIntervalShorter);
+        mTryAgainTimesMax = mContext.getResources().getInteger(
+                com.android.internal.R.integer.config_ntpRetry);
+        mTimeErrorThresholdMs = mContext.getResources().getInteger(
+                com.android.internal.R.integer.config_ntpThreshold);
+
+        mWakeLock = context.getSystemService(PowerManager.class).newWakeLock(
+                PowerManager.PARTIAL_WAKE_LOCK, TAG);
+    }
+
+    @Override
+    public void systemRunning() {
+        registerForTelephonyIntents();
+        registerForAlarms();
+
+        HandlerThread thread = new HandlerThread(TAG);
+        thread.start();
+        mHandler = new MyHandler(thread.getLooper());
+        mNetworkTimeUpdateCallback = new NetworkTimeUpdateCallback();
+        mCM.registerDefaultNetworkCallback(mNetworkTimeUpdateCallback, mHandler);
+
+        mSettingsObserver = new SettingsObserver(mHandler, EVENT_AUTO_TIME_CHANGED);
+        mSettingsObserver.observe(mContext);
+    }
+
+    private void registerForTelephonyIntents() {
+        IntentFilter intentFilter = new IntentFilter();
+        intentFilter.addAction(TelephonyIntents.ACTION_NETWORK_SET_TIME);
+        mContext.registerReceiver(mNitzReceiver, intentFilter);
+    }
+
+    private void registerForAlarms() {
+        mContext.registerReceiver(
+            new BroadcastReceiver() {
+                @Override
+                public void onReceive(Context context, Intent intent) {
+                    mHandler.obtainMessage(EVENT_POLL_NETWORK_TIME).sendToTarget();
+                }
+            }, new IntentFilter(ACTION_POLL));
+    }
+
+    private void onPollNetworkTime(int event) {
+        // If Automatic time is not set, don't bother. Similarly, if we don't
+        // have any default network, don't bother.
+        if (mDefaultNetwork == null) return;
+        mWakeLock.acquire();
+        try {
+            onPollNetworkTimeUnderWakeLock(event);
+        } finally {
+            mWakeLock.release();
+        }
+    }
+
+    private void onPollNetworkTimeUnderWakeLock(int event) {
+        // Force an NTP fix when outdated
+        if (mTime.getCacheAge() >= mPollingIntervalMs) {
+            if (DBG) Log.d(TAG, "Stale NTP fix; forcing refresh");
+            mTime.forceRefresh();
+        }
+
+        if (mTime.getCacheAge() < mPollingIntervalMs) {
+            // Obtained fresh fix; schedule next normal update
+            resetAlarm(mPollingIntervalMs);
+            if (isAutomaticTimeRequested()) {
+                updateSystemClock(event);
+            }
+
+        } else {
+            // No fresh fix; schedule retry
+            mTryAgainCounter++;
+            if (mTryAgainTimesMax < 0 || mTryAgainCounter <= mTryAgainTimesMax) {
+                resetAlarm(mPollingIntervalShorterMs);
+            } else {
+                // Try much later
+                mTryAgainCounter = 0;
+                resetAlarm(mPollingIntervalMs);
+            }
+        }
+    }
+
+    private long getNitzAge() {
+        if (mNitzTimeSetTime == NOT_SET) {
+            return Long.MAX_VALUE;
+        } else {
+            return SystemClock.elapsedRealtime() - mNitzTimeSetTime;
+        }
+    }
+
+    /**
+     * Consider updating system clock based on current NTP fix, if requested by
+     * user, significant enough delta, and we don't have a recent NITZ.
+     */
+    private void updateSystemClock(int event) {
+        final boolean forceUpdate = (event == EVENT_AUTO_TIME_CHANGED);
+        if (!forceUpdate) {
+            if (getNitzAge() < mPollingIntervalMs) {
+                if (DBG) Log.d(TAG, "Ignoring NTP update due to recent NITZ");
+                return;
+            }
+
+            final long skew = Math.abs(mTime.currentTimeMillis() - System.currentTimeMillis());
+            if (skew < mTimeErrorThresholdMs) {
+                if (DBG) Log.d(TAG, "Ignoring NTP update due to low skew");
+                return;
+            }
+        }
+
+        SystemClock.setCurrentTimeMillis(mTime.currentTimeMillis());
+    }
+
+    /**
+     * Cancel old alarm and starts a new one for the specified interval.
+     *
+     * @param interval when to trigger the alarm, starting from now.
+     */
+    private void resetAlarm(long interval) {
+        mAlarmManager.cancel(mPendingPollIntent);
+        long now = SystemClock.elapsedRealtime();
+        long next = now + interval;
+        mAlarmManager.set(AlarmManager.ELAPSED_REALTIME, next, mPendingPollIntent);
+    }
+
+    /**
+     * Checks if the user prefers to automatically set the time.
+     */
+    private boolean isAutomaticTimeRequested() {
+        return Settings.Global.getInt(
+                mContext.getContentResolver(), Settings.Global.AUTO_TIME, 0) != 0;
+    }
+
+    /** Receiver for Nitz time events */
+    private BroadcastReceiver mNitzReceiver = new BroadcastReceiver() {
+
+        @Override
+        public void onReceive(Context context, Intent intent) {
+            String action = intent.getAction();
+            if (DBG) Log.d(TAG, "Received " + action);
+            if (TelephonyIntents.ACTION_NETWORK_SET_TIME.equals(action)) {
+                mNitzTimeSetTime = SystemClock.elapsedRealtime();
+            }
+        }
+    };
+
+    /** Handler to do the network accesses on */
+    private class MyHandler extends Handler {
+
+        public MyHandler(Looper l) {
+            super(l);
+        }
+
+        @Override
+        public void handleMessage(Message msg) {
+            switch (msg.what) {
+                case EVENT_AUTO_TIME_CHANGED:
+                case EVENT_POLL_NETWORK_TIME:
+                case EVENT_NETWORK_CHANGED:
+                    onPollNetworkTime(msg.what);
+                    break;
+            }
+        }
+    }
+
+    private class NetworkTimeUpdateCallback extends NetworkCallback {
+        @Override
+        public void onAvailable(Network network) {
+            Log.d(TAG, String.format("New default network %s; checking time.", network));
+            mDefaultNetwork = network;
+            // Running on mHandler so invoke directly.
+            onPollNetworkTime(EVENT_NETWORK_CHANGED);
+        }
+
+        @Override
+        public void onLost(Network network) {
+            if (network.equals(mDefaultNetwork)) mDefaultNetwork = null;
+        }
+    }
+
+    /** Observer to watch for changes to the AUTO_TIME setting */
+    private static class SettingsObserver extends ContentObserver {
+
+        private int mMsg;
+        private Handler mHandler;
+
+        SettingsObserver(Handler handler, int msg) {
+            super(handler);
+            mHandler = handler;
+            mMsg = msg;
+        }
+
+        void observe(Context context) {
+            ContentResolver resolver = context.getContentResolver();
+            resolver.registerContentObserver(Settings.Global.getUriFor(Settings.Global.AUTO_TIME),
+                    false, this);
+        }
+
+        @Override
+        public void onChange(boolean selfChange) {
+            mHandler.obtainMessage(mMsg).sendToTarget();
+        }
+    }
+
+    @Override
+    protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
+        if (!DumpUtils.checkDumpPermission(mContext, TAG, pw)) return;
+        pw.print("PollingIntervalMs: ");
+        TimeUtils.formatDuration(mPollingIntervalMs, pw);
+        pw.print("\nPollingIntervalShorterMs: ");
+        TimeUtils.formatDuration(mPollingIntervalShorterMs, pw);
+        pw.println("\nTryAgainTimesMax: " + mTryAgainTimesMax);
+        pw.print("TimeErrorThresholdMs: ");
+        TimeUtils.formatDuration(mTimeErrorThresholdMs, pw);
+        pw.println("\nTryAgainCounter: " + mTryAgainCounter);
+        pw.println("NTP cache age: " + mTime.getCacheAge());
+        pw.println("NTP cache certainty: " + mTime.getCacheCertainty());
+        pw.println();
+    }
+}
diff --git a/services/core/java/com/android/server/OldNetworkTimeUpdateService.java b/services/core/java/com/android/server/OldNetworkTimeUpdateService.java
new file mode 100644
index 0000000..068b83d
--- /dev/null
+++ b/services/core/java/com/android/server/OldNetworkTimeUpdateService.java
@@ -0,0 +1,329 @@
+/*
+ * Copyright (C) 2010 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.server;
+
+import android.app.AlarmManager;
+import android.app.PendingIntent;
+import android.content.BroadcastReceiver;
+import android.content.ContentResolver;
+import android.content.Context;
+import android.content.Intent;
+import android.content.IntentFilter;
+import android.database.ContentObserver;
+import android.net.ConnectivityManager;
+import android.net.ConnectivityManager.NetworkCallback;
+import android.net.Network;
+import android.os.Binder;
+import android.os.Handler;
+import android.os.HandlerThread;
+import android.os.Looper;
+import android.os.Message;
+import android.os.PowerManager;
+import android.os.SystemClock;
+import android.provider.Settings;
+import android.util.Log;
+import android.util.NtpTrustedTime;
+import android.util.TimeUtils;
+
+import com.android.internal.telephony.TelephonyIntents;
+import com.android.internal.util.DumpUtils;
+
+import java.io.FileDescriptor;
+import java.io.PrintWriter;
+
+/**
+ * Monitors the network time and updates the system time if it is out of sync
+ * and there hasn't been any NITZ update from the carrier recently.
+ * If looking up the network time fails for some reason, it tries a few times with a short
+ * interval and then resets to checking on longer intervals.
+ * <p>
+ * If the user enables AUTO_TIME, it will check immediately for the network time, if NITZ wasn't
+ * available.
+ * </p>
+ */
+public class OldNetworkTimeUpdateService extends Binder implements NetworkTimeUpdateService {
+
+    private static final String TAG = "NetworkTimeUpdateService";
+    private static final boolean DBG = false;
+
+    private static final int EVENT_AUTO_TIME_CHANGED = 1;
+    private static final int EVENT_POLL_NETWORK_TIME = 2;
+    private static final int EVENT_NETWORK_CHANGED = 3;
+
+    private static final String ACTION_POLL =
+            "com.android.server.NetworkTimeUpdateService.action.POLL";
+
+    private static final int POLL_REQUEST = 0;
+
+    private static final long NOT_SET = -1;
+    private long mNitzTimeSetTime = NOT_SET;
+    private Network mDefaultNetwork = null;
+
+    private final Context mContext;
+    private final NtpTrustedTime mTime;
+    private final AlarmManager mAlarmManager;
+    private final ConnectivityManager mCM;
+    private final PendingIntent mPendingPollIntent;
+    private final PowerManager.WakeLock mWakeLock;
+
+    // NTP lookup is done on this thread and handler
+    private Handler mHandler;
+    private SettingsObserver mSettingsObserver;
+    private NetworkTimeUpdateCallback mNetworkTimeUpdateCallback;
+
+    // Normal polling frequency
+    private final long mPollingIntervalMs;
+    // Try-again polling interval, in case the network request failed
+    private final long mPollingIntervalShorterMs;
+    // Number of times to try again
+    private final int mTryAgainTimesMax;
+    // If the time difference is greater than this threshold, then update the time.
+    private final int mTimeErrorThresholdMs;
+    // Keeps track of how many quick attempts were made to fetch NTP time.
+    // During bootup, the network may not have been up yet, or it's taking time for the
+    // connection to happen.
+    private int mTryAgainCounter;
+
+    public OldNetworkTimeUpdateService(Context context) {
+        mContext = context;
+        mTime = NtpTrustedTime.getInstance(context);
+        mAlarmManager = mContext.getSystemService(AlarmManager.class);
+        mCM = mContext.getSystemService(ConnectivityManager.class);
+
+        Intent pollIntent = new Intent(ACTION_POLL, null);
+        mPendingPollIntent = PendingIntent.getBroadcast(mContext, POLL_REQUEST, pollIntent, 0);
+
+        mPollingIntervalMs = mContext.getResources().getInteger(
+                com.android.internal.R.integer.config_ntpPollingInterval);
+        mPollingIntervalShorterMs = mContext.getResources().getInteger(
+                com.android.internal.R.integer.config_ntpPollingIntervalShorter);
+        mTryAgainTimesMax = mContext.getResources().getInteger(
+                com.android.internal.R.integer.config_ntpRetry);
+        mTimeErrorThresholdMs = mContext.getResources().getInteger(
+                com.android.internal.R.integer.config_ntpThreshold);
+
+        mWakeLock = context.getSystemService(PowerManager.class).newWakeLock(
+                PowerManager.PARTIAL_WAKE_LOCK, TAG);
+    }
+
+    @Override
+    public void systemRunning() {
+        registerForTelephonyIntents();
+        registerForAlarms();
+
+        HandlerThread thread = new HandlerThread(TAG);
+        thread.start();
+        mHandler = new MyHandler(thread.getLooper());
+        mNetworkTimeUpdateCallback = new NetworkTimeUpdateCallback();
+        mCM.registerDefaultNetworkCallback(mNetworkTimeUpdateCallback, mHandler);
+
+        mSettingsObserver = new SettingsObserver(mHandler, EVENT_AUTO_TIME_CHANGED);
+        mSettingsObserver.observe(mContext);
+    }
+
+    private void registerForTelephonyIntents() {
+        IntentFilter intentFilter = new IntentFilter();
+        intentFilter.addAction(TelephonyIntents.ACTION_NETWORK_SET_TIME);
+        mContext.registerReceiver(mNitzReceiver, intentFilter);
+    }
+
+    private void registerForAlarms() {
+        mContext.registerReceiver(
+            new BroadcastReceiver() {
+                @Override
+                public void onReceive(Context context, Intent intent) {
+                    mHandler.obtainMessage(EVENT_POLL_NETWORK_TIME).sendToTarget();
+                }
+            }, new IntentFilter(ACTION_POLL));
+    }
+
+    private void onPollNetworkTime(int event) {
+        // If Automatic time is not set, don't bother. Similarly, if we don't
+        // have any default network, don't bother.
+        if (mDefaultNetwork == null) return;
+        mWakeLock.acquire();
+        try {
+            onPollNetworkTimeUnderWakeLock(event);
+        } finally {
+            mWakeLock.release();
+        }
+    }
+
+    private void onPollNetworkTimeUnderWakeLock(int event) {
+        // Force an NTP fix when outdated
+        if (mTime.getCacheAge() >= mPollingIntervalMs) {
+            if (DBG) Log.d(TAG, "Stale NTP fix; forcing refresh");
+            mTime.forceRefresh();
+        }
+
+        if (mTime.getCacheAge() < mPollingIntervalMs) {
+            // Obtained fresh fix; schedule next normal update
+            resetAlarm(mPollingIntervalMs);
+            if (isAutomaticTimeRequested()) {
+                updateSystemClock(event);
+            }
+
+        } else {
+            // No fresh fix; schedule retry
+            mTryAgainCounter++;
+            if (mTryAgainTimesMax < 0 || mTryAgainCounter <= mTryAgainTimesMax) {
+                resetAlarm(mPollingIntervalShorterMs);
+            } else {
+                // Try much later
+                mTryAgainCounter = 0;
+                resetAlarm(mPollingIntervalMs);
+            }
+        }
+    }
+
+    private long getNitzAge() {
+        if (mNitzTimeSetTime == NOT_SET) {
+            return Long.MAX_VALUE;
+        } else {
+            return SystemClock.elapsedRealtime() - mNitzTimeSetTime;
+        }
+    }
+
+    /**
+     * Consider updating system clock based on current NTP fix, if requested by
+     * user, significant enough delta, and we don't have a recent NITZ.
+     */
+    private void updateSystemClock(int event) {
+        final boolean forceUpdate = (event == EVENT_AUTO_TIME_CHANGED);
+        if (!forceUpdate) {
+            if (getNitzAge() < mPollingIntervalMs) {
+                if (DBG) Log.d(TAG, "Ignoring NTP update due to recent NITZ");
+                return;
+            }
+
+            final long skew = Math.abs(mTime.currentTimeMillis() - System.currentTimeMillis());
+            if (skew < mTimeErrorThresholdMs) {
+                if (DBG) Log.d(TAG, "Ignoring NTP update due to low skew");
+                return;
+            }
+        }
+
+        SystemClock.setCurrentTimeMillis(mTime.currentTimeMillis());
+    }
+
+    /**
+     * Cancel old alarm and starts a new one for the specified interval.
+     *
+     * @param interval when to trigger the alarm, starting from now.
+     */
+    private void resetAlarm(long interval) {
+        mAlarmManager.cancel(mPendingPollIntent);
+        long now = SystemClock.elapsedRealtime();
+        long next = now + interval;
+        mAlarmManager.set(AlarmManager.ELAPSED_REALTIME, next, mPendingPollIntent);
+    }
+
+    /**
+     * Checks if the user prefers to automatically set the time.
+     */
+    private boolean isAutomaticTimeRequested() {
+        return Settings.Global.getInt(
+                mContext.getContentResolver(), Settings.Global.AUTO_TIME, 0) != 0;
+    }
+
+    /** Receiver for Nitz time events */
+    private BroadcastReceiver mNitzReceiver = new BroadcastReceiver() {
+
+        @Override
+        public void onReceive(Context context, Intent intent) {
+            String action = intent.getAction();
+            if (DBG) Log.d(TAG, "Received " + action);
+            if (TelephonyIntents.ACTION_NETWORK_SET_TIME.equals(action)) {
+                mNitzTimeSetTime = SystemClock.elapsedRealtime();
+            }
+        }
+    };
+
+    /** Handler to do the network accesses on */
+    private class MyHandler extends Handler {
+
+        public MyHandler(Looper l) {
+            super(l);
+        }
+
+        @Override
+        public void handleMessage(Message msg) {
+            switch (msg.what) {
+                case EVENT_AUTO_TIME_CHANGED:
+                case EVENT_POLL_NETWORK_TIME:
+                case EVENT_NETWORK_CHANGED:
+                    onPollNetworkTime(msg.what);
+                    break;
+            }
+        }
+    }
+
+    private class NetworkTimeUpdateCallback extends NetworkCallback {
+        @Override
+        public void onAvailable(Network network) {
+            Log.d(TAG, String.format("New default network %s; checking time.", network));
+            mDefaultNetwork = network;
+            // Running on mHandler so invoke directly.
+            onPollNetworkTime(EVENT_NETWORK_CHANGED);
+        }
+
+        @Override
+        public void onLost(Network network) {
+            if (network.equals(mDefaultNetwork)) mDefaultNetwork = null;
+        }
+    }
+
+    /** Observer to watch for changes to the AUTO_TIME setting */
+    private static class SettingsObserver extends ContentObserver {
+
+        private int mMsg;
+        private Handler mHandler;
+
+        SettingsObserver(Handler handler, int msg) {
+            super(handler);
+            mHandler = handler;
+            mMsg = msg;
+        }
+
+        void observe(Context context) {
+            ContentResolver resolver = context.getContentResolver();
+            resolver.registerContentObserver(Settings.Global.getUriFor(Settings.Global.AUTO_TIME),
+                    false, this);
+        }
+
+        @Override
+        public void onChange(boolean selfChange) {
+            mHandler.obtainMessage(mMsg).sendToTarget();
+        }
+    }
+
+    @Override
+    protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
+        if (!DumpUtils.checkDumpPermission(mContext, TAG, pw)) return;
+        pw.print("PollingIntervalMs: ");
+        TimeUtils.formatDuration(mPollingIntervalMs, pw);
+        pw.print("\nPollingIntervalShorterMs: ");
+        TimeUtils.formatDuration(mPollingIntervalShorterMs, pw);
+        pw.println("\nTryAgainTimesMax: " + mTryAgainTimesMax);
+        pw.print("TimeErrorThresholdMs: ");
+        TimeUtils.formatDuration(mTimeErrorThresholdMs, pw);
+        pw.println("\nTryAgainCounter: " + mTryAgainCounter);
+        pw.println("NTP cache age: " + mTime.getCacheAge());
+        pw.println("NTP cache certainty: " + mTime.getCacheCertainty());
+        pw.println();
+    }
+}
diff --git a/services/core/java/com/android/server/am/ActivityManagerService.java b/services/core/java/com/android/server/am/ActivityManagerService.java
index c2f0b63..a29b67b 100644
--- a/services/core/java/com/android/server/am/ActivityManagerService.java
+++ b/services/core/java/com/android/server/am/ActivityManagerService.java
@@ -392,11 +392,13 @@
 import org.xmlpull.v1.XmlPullParserException;
 import org.xmlpull.v1.XmlSerializer;
 
+import java.io.BufferedReader;
 import java.io.File;
 import java.io.FileDescriptor;
 import java.io.FileInputStream;
 import java.io.FileNotFoundException;
 import java.io.FileOutputStream;
+import java.io.FileReader;
 import java.io.IOException;
 import java.io.InputStreamReader;
 import java.io.PrintWriter;
@@ -476,6 +478,8 @@
 
     static final String SYSTEM_DEBUGGABLE = "ro.debuggable";
 
+    private static final String ANR_TRACE_DIR = "/data/anr";
+
     // Maximum number of receivers an app can register.
     private static final int MAX_RECEIVERS_ALLOWED_PER_APP = 1000;
 
@@ -5022,7 +5026,7 @@
             }
         }
 
-        final File tracesDir = new File("/data/anr");
+        final File tracesDir = new File(ANR_TRACE_DIR);
         // Each set of ANR traces is written to a separate file and dumpstate will process
         // all such files and add them to a captured bug report if they're recent enough.
         maybePruneOldTraces(tracesDir);
@@ -12787,6 +12791,10 @@
                 synchronized (this) {
                     dumpLastANRLocked(pw);
                 }
+            } else if ("lastanr-traces".equals(cmd)) {
+                synchronized (this) {
+                    dumpLastANRTracesLocked(pw);
+                }
             } else if ("starter".equals(cmd)) {
                 synchronized (this) {
                     dumpActivityStarterLocked(pw, dumpPackage);
@@ -13136,6 +13144,35 @@
         }
     }
 
+    private void dumpLastANRTracesLocked(PrintWriter pw) {
+        pw.println("ACTIVITY MANAGER LAST ANR TRACES (dumpsys activity lastanr-traces)");
+
+        final File[] files = new File(ANR_TRACE_DIR).listFiles();
+        if (ArrayUtils.isEmpty(files)) {
+            return;
+        }
+        // Find the latest file.
+        File latest = null;
+        for (File f : files) {
+            if (latest == null || latest.getName().compareTo(f.getName()) < 0) {
+                latest = f;
+            }
+        }
+        pw.print("File: ");
+        pw.print(latest.getName());
+        pw.println();
+        try (BufferedReader in = new BufferedReader(new FileReader(latest))) {
+            String line;
+            while ((line = in.readLine()) != null) {
+                pw.println(line);
+            }
+        } catch (IOException e) {
+            pw.print("Unable to read: ");
+            pw.print(e);
+            pw.println();
+        }
+    }
+
     private void dumpActivityContainersLocked(PrintWriter pw) {
         pw.println("ACTIVITY MANAGER STARTER (dumpsys activity containers)");
         mStackSupervisor.dumpChildrenNames(pw, " ");
diff --git a/services/core/java/com/android/server/am/ActivityStack.java b/services/core/java/com/android/server/am/ActivityStack.java
index 9b01919..dae145d 100644
--- a/services/core/java/com/android/server/am/ActivityStack.java
+++ b/services/core/java/com/android/server/am/ActivityStack.java
@@ -1654,6 +1654,16 @@
     void addToStopping(ActivityRecord r, boolean scheduleIdle, boolean idleDelayed) {
         if (!mStackSupervisor.mStoppingActivities.contains(r)) {
             mStackSupervisor.mStoppingActivities.add(r);
+
+            // Some activity is waiting for another activity to become visible before it's being
+            // stopped, which means that we also want to wait with stopping this one to avoid
+            // flickers.
+            if (!mStackSupervisor.mActivitiesWaitingForVisibleActivity.isEmpty()
+                    && !mStackSupervisor.mActivitiesWaitingForVisibleActivity.contains(r)) {
+                if (DEBUG_SWITCH) Slog.i(TAG_SWITCH, "adding to waiting visible activity=" + r
+                        + " existing=" + mStackSupervisor.mActivitiesWaitingForVisibleActivity);
+                mStackSupervisor.mActivitiesWaitingForVisibleActivity.add(r);
+            }
         }
 
         // If we already have a few activities waiting to stop, then give up
@@ -5279,6 +5289,20 @@
         }
     }
 
+    public void setAlwaysOnTop(boolean alwaysOnTop) {
+        if (isAlwaysOnTop() == alwaysOnTop) {
+            return;
+        }
+        super.setAlwaysOnTop(alwaysOnTop);
+        final ActivityDisplay display = getDisplay();
+        // positionChildAtTop() must be called even when always on top gets turned off because we
+        // need to make sure that the stack is moved from among always on top windows to below other
+        // always on top windows. Since the position the stack should be inserted into is calculated
+        // properly in {@link ActivityDisplay#getTopInsertPosition()} in both cases, we can just
+        // request that the stack is put at top here.
+        display.positionChildAtTop(this);
+    }
+
     void moveToFrontAndResumeStateIfNeeded(ActivityRecord r, boolean moveToFront, boolean setResume,
             boolean setPause, String reason) {
         if (!moveToFront) {
diff --git a/services/core/java/com/android/server/am/ActivityStackSupervisor.java b/services/core/java/com/android/server/am/ActivityStackSupervisor.java
index f49943e..1cb6be6 100644
--- a/services/core/java/com/android/server/am/ActivityStackSupervisor.java
+++ b/services/core/java/com/android/server/am/ActivityStackSupervisor.java
@@ -3899,6 +3899,10 @@
                         stops = new ArrayList<>();
                     }
                     stops.add(s);
+
+                    // Make sure to remove it in all cases in case we entered this block with
+                    // shouldSleepOrShutDown
+                    mActivitiesWaitingForVisibleActivity.remove(s);
                     mStoppingActivities.remove(activityNdx);
                 }
             }
diff --git a/services/core/java/com/android/server/am/TaskRecord.java b/services/core/java/com/android/server/am/TaskRecord.java
index c8ffdb1..b44727f 100644
--- a/services/core/java/com/android/server/am/TaskRecord.java
+++ b/services/core/java/com/android/server/am/TaskRecord.java
@@ -542,8 +542,14 @@
                 if (r != null && !deferResume) {
                     kept = r.ensureActivityConfiguration(0 /* globalChanges */,
                             preserveWindow);
+                    // Preserve other windows for resizing because if resizing happens when there
+                    // is a dialog activity in the front, the activity that still shows some
+                    // content to the user will become black and cause flickers. Note in most cases
+                    // this won't cause tons of irrelevant windows being preserved because only
+                    // activities in this task may experience a bounds change. Configs for other
+                    // activities stay the same.
                     mService.mStackSupervisor.ensureActivitiesVisibleLocked(r, 0,
-                            !PRESERVE_WINDOWS);
+                            preserveWindow);
                     if (!kept) {
                         mService.mStackSupervisor.resumeFocusedStackTopActivityLocked();
                     }
diff --git a/services/core/java/com/android/server/notification/NotificationManagerService.java b/services/core/java/com/android/server/notification/NotificationManagerService.java
index c45d861..6402b7b 100644
--- a/services/core/java/com/android/server/notification/NotificationManagerService.java
+++ b/services/core/java/com/android/server/notification/NotificationManagerService.java
@@ -3125,14 +3125,19 @@
         protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
             if (!DumpUtils.checkDumpAndUsageStatsPermission(getContext(), TAG, pw)) return;
             final DumpFilter filter = DumpFilter.parseFromArguments(args);
-            if (filter.stats) {
-                dumpJson(pw, filter);
-            } else if (filter.proto) {
-                dumpProto(fd, filter);
-            } else if (filter.criticalPriority) {
-                dumpNotificationRecords(pw, filter);
-            } else {
-                dumpImpl(pw, filter);
+            final long token = Binder.clearCallingIdentity();
+            try {
+                if (filter.stats) {
+                    dumpJson(pw, filter);
+                } else if (filter.proto) {
+                    dumpProto(fd, filter);
+                } else if (filter.criticalPriority) {
+                    dumpNotificationRecords(pw, filter);
+                } else {
+                    dumpImpl(pw, filter);
+                }
+            } finally {
+                Binder.restoreCallingIdentity(token);
             }
         }
 
diff --git a/services/core/java/com/android/server/pm/PackageManagerService.java b/services/core/java/com/android/server/pm/PackageManagerService.java
index 9a15623..c536e4d 100644
--- a/services/core/java/com/android/server/pm/PackageManagerService.java
+++ b/services/core/java/com/android/server/pm/PackageManagerService.java
@@ -430,7 +430,6 @@
 
     private static final boolean DEBUG_ABI_SELECTION = false;
     private static final boolean DEBUG_INSTANT = Build.IS_DEBUGGABLE;
-    private static final boolean DEBUG_TRIAGED_MISSING = false;
     private static final boolean DEBUG_APP_DATA = false;
 
     /** REMOVE. According to Svet, this was only used to reset permissions during development. */
@@ -4750,22 +4749,6 @@
      */
     private int updateFlagsForPackage(int flags, int userId, Object cookie) {
         final boolean isCallerSystemUser = UserHandle.getCallingUserId() == UserHandle.USER_SYSTEM;
-        boolean triaged = true;
-        if ((flags & (PackageManager.GET_ACTIVITIES | PackageManager.GET_RECEIVERS
-                | PackageManager.GET_SERVICES | PackageManager.GET_PROVIDERS)) != 0) {
-            // Caller is asking for component details, so they'd better be
-            // asking for specific encryption matching behavior, or be triaged
-            if ((flags & (PackageManager.MATCH_DIRECT_BOOT_UNAWARE
-                    | PackageManager.MATCH_DIRECT_BOOT_AWARE
-                    | PackageManager.MATCH_DEBUG_TRIAGED_MISSING)) == 0) {
-                triaged = false;
-            }
-        }
-        if ((flags & (PackageManager.MATCH_UNINSTALLED_PACKAGES
-                | PackageManager.MATCH_SYSTEM_ONLY
-                | PackageManager.MATCH_DEBUG_TRIAGED_MISSING)) == 0) {
-            triaged = false;
-        }
         if ((flags & PackageManager.MATCH_ANY_USER) != 0) {
             // require the permission to be held; the calling uid and given user id referring
             // to the same user is not sufficient
@@ -4782,10 +4765,6 @@
             // MATCH_UNINSTALLED_PACKAGES to query apps in other profiles. b/31000380
             flags |= PackageManager.MATCH_ANY_USER;
         }
-        if (DEBUG_TRIAGED_MISSING && (Binder.getCallingUid() == Process.SYSTEM_UID) && !triaged) {
-            Log.w(TAG, "Caller hasn't been triaged for missing apps; they asked about " + cookie
-                    + " with flags 0x" + Integer.toHexString(flags), new Throwable());
-        }
         return updateFlags(flags, userId);
     }
 
@@ -4800,25 +4779,6 @@
      * Update given flags when being used to request {@link ComponentInfo}.
      */
     private int updateFlagsForComponent(int flags, int userId, Object cookie) {
-        if (cookie instanceof Intent) {
-            if ((((Intent) cookie).getFlags() & Intent.FLAG_DEBUG_TRIAGED_MISSING) != 0) {
-                flags |= PackageManager.MATCH_DEBUG_TRIAGED_MISSING;
-            }
-        }
-
-        boolean triaged = true;
-        // Caller is asking for component details, so they'd better be
-        // asking for specific encryption matching behavior, or be triaged
-        if ((flags & (PackageManager.MATCH_DIRECT_BOOT_UNAWARE
-                | PackageManager.MATCH_DIRECT_BOOT_AWARE
-                | PackageManager.MATCH_DEBUG_TRIAGED_MISSING)) == 0) {
-            triaged = false;
-        }
-        if (DEBUG_TRIAGED_MISSING && (Binder.getCallingUid() == Process.SYSTEM_UID) && !triaged) {
-            Log.w(TAG, "Caller hasn't been triaged for missing apps; they asked about " + cookie
-                    + " with flags 0x" + Integer.toHexString(flags), new Throwable());
-        }
-
         return updateFlags(flags, userId);
     }
 
@@ -13962,6 +13922,68 @@
         return false;
     }
 
+    @Override
+    public void setSystemAppHiddenUntilInstalled(String packageName, boolean hidden) {
+        enforceSystemOrPhoneCaller("setSystemAppHiddenUntilInstalled");
+        synchronized (mPackages) {
+            final PackageSetting pkgSetting = mSettings.mPackages.get(packageName);
+            if (pkgSetting == null || !pkgSetting.isSystem()) {
+                return;
+            }
+            PackageParser.Package pkg = pkgSetting.pkg;
+            if (pkg != null && pkg.applicationInfo != null) {
+                pkg.applicationInfo.hiddenUntilInstalled = hidden;
+            }
+            final PackageSetting disabledPs = mSettings.getDisabledSystemPkgLPr(packageName);
+            if (disabledPs == null) {
+                return;
+            }
+            pkg = disabledPs.pkg;
+            if (pkg != null && pkg.applicationInfo != null) {
+                pkg.applicationInfo.hiddenUntilInstalled = hidden;
+            }
+        }
+    }
+
+    @Override
+    public boolean setSystemAppInstallState(String packageName, boolean installed, int userId) {
+        enforceSystemOrPhoneCaller("setSystemAppInstallState");
+        synchronized (mPackages) {
+            final PackageSetting pkgSetting = mSettings.mPackages.get(packageName);
+            // The target app should always be in system
+            if (pkgSetting == null || !pkgSetting.isSystem()) {
+                return false;
+            }
+            // Check if the install state is the same
+            if (pkgSetting.getInstalled(userId) == installed) {
+                return false;
+            }
+        }
+
+        final long callingId = Binder.clearCallingIdentity();
+        try {
+            if (installed) {
+                // install the app from uninstalled state
+                installExistingPackageAsUser(
+                        packageName,
+                        userId,
+                        0 /*installFlags*/,
+                        PackageManager.INSTALL_REASON_DEVICE_SETUP);
+                return true;
+            }
+
+            // uninstall the app from installed state
+            deletePackageVersioned(
+                    new VersionedPackage(packageName, PackageManager.VERSION_CODE_HIGHEST),
+                    new LegacyPackageDeleteObserver(null).getBinder(),
+                    userId,
+                    PackageManager.DELETE_SYSTEM_APP);
+            return true;
+        } finally {
+            Binder.restoreCallingIdentity(callingId);
+        }
+    }
+
     private void sendApplicationHiddenForUser(String packageName, PackageSetting pkgSetting,
             int userId) {
         final PackageRemovedInfo info = new PackageRemovedInfo(this);
@@ -14026,10 +14048,16 @@
     @Override
     public int installExistingPackageAsUser(String packageName, int userId, int installFlags,
             int installReason) {
-        mContext.enforceCallingOrSelfPermission(android.Manifest.permission.INSTALL_PACKAGES,
-                null);
-        PackageSetting pkgSetting;
         final int callingUid = Binder.getCallingUid();
+        if (mContext.checkCallingOrSelfPermission(android.Manifest.permission.INSTALL_PACKAGES)
+                != PackageManager.PERMISSION_GRANTED
+                && mContext.checkCallingOrSelfPermission(
+                        android.Manifest.permission.INSTALL_EXISTING_PACKAGES)
+                != PackageManager.PERMISSION_GRANTED) {
+            throw new SecurityException("Neither user " + callingUid + " nor current process has "
+                    + android.Manifest.permission.INSTALL_PACKAGES + ".");
+        }
+        PackageSetting pkgSetting;
         mPermissionManager.enforceCrossUserPermission(callingUid, userId,
                 true /* requireFullPermission */, true /* checkShell */,
                 "installExistingPackage for user " + userId);
diff --git a/services/core/java/com/android/server/pm/Settings.java b/services/core/java/com/android/server/pm/Settings.java
index d963afb..d17697b 100644
--- a/services/core/java/com/android/server/pm/Settings.java
+++ b/services/core/java/com/android/server/pm/Settings.java
@@ -4121,7 +4121,8 @@
                     continue;
                 }
                 final boolean shouldInstall = ps.isSystem() &&
-                        !ArrayUtils.contains(disallowedPackages, ps.name);
+                        !ArrayUtils.contains(disallowedPackages, ps.name) &&
+                        !ps.pkg.applicationInfo.hiddenUntilInstalled;
                 // Only system apps are initially installed.
                 ps.setInstalled(shouldInstall, userHandle);
                 if (!shouldInstall) {
diff --git a/services/core/java/com/android/server/timedetector/SimpleTimeDetectorStrategy.java b/services/core/java/com/android/server/timedetector/SimpleTimeDetectorStrategy.java
index e5207cb..7bdc8a3 100644
--- a/services/core/java/com/android/server/timedetector/SimpleTimeDetectorStrategy.java
+++ b/services/core/java/com/android/server/timedetector/SimpleTimeDetectorStrategy.java
@@ -20,38 +20,213 @@
 import android.annotation.Nullable;
 import android.app.AlarmManager;
 import android.app.timedetector.TimeSignal;
+import android.content.Intent;
 import android.util.Slog;
+import android.util.TimestampedValue;
 
-import java.io.FileDescriptor;
+import com.android.internal.telephony.TelephonyIntents;
+
 import java.io.PrintWriter;
 
 /**
- * A placeholder implementation of TimeDetectorStrategy that passes NITZ suggestions immediately
- * to {@link AlarmManager}.
+ * An implementation of TimeDetectorStrategy that passes only NITZ suggestions to
+ * {@link AlarmManager}. The TimeDetectorService handles thread safety: all calls to
+ * this class can be assumed to be single threaded (though the thread used may vary).
  */
+// @NotThreadSafe
 public final class SimpleTimeDetectorStrategy implements TimeDetectorStrategy {
 
     private final static String TAG = "timedetector.SimpleTimeDetectorStrategy";
 
-    private Callback mHelper;
+    /**
+     * CLOCK_PARANOIA: The maximum difference allowed between the expected system clock time and the
+     * actual system clock time before a warning is logged. Used to help identify situations where
+     * there is something other than this class setting the system clock.
+     */
+    private static final long SYSTEM_CLOCK_PARANOIA_THRESHOLD_MILLIS = 2 * 1000;
+
+    // @NonNull after initialize()
+    private Callback mCallback;
+
+    // NITZ state.
+    @Nullable private TimestampedValue<Long> mLastNitzTime;
+
+
+    // Information about the last time signal received: Used when toggling auto-time.
+    @Nullable private TimestampedValue<Long> mLastSystemClockTime;
+    private boolean mLastSystemClockTimeSendNetworkBroadcast;
+
+    // System clock state.
+    @Nullable private TimestampedValue<Long> mLastSystemClockTimeSet;
 
     @Override
     public void initialize(@NonNull Callback callback) {
-        mHelper = callback;
+        mCallback = callback;
     }
 
     @Override
     public void suggestTime(@NonNull TimeSignal timeSignal) {
         if (!TimeSignal.SOURCE_ID_NITZ.equals(timeSignal.getSourceId())) {
-            Slog.w(TAG, "Ignoring signal from unknown source: " + timeSignal);
+            Slog.w(TAG, "Ignoring signal from unsupported source: " + timeSignal);
             return;
         }
 
-        mHelper.setTime(timeSignal.getUtcTime());
+        // NITZ logic
+
+        TimestampedValue<Long> newNitzUtcTime = timeSignal.getUtcTime();
+        boolean nitzTimeIsValid = validateNewNitzTime(newNitzUtcTime, mLastNitzTime);
+        if (!nitzTimeIsValid) {
+            return;
+        }
+        // Always store the last NITZ value received, regardless of whether we go on to use it to
+        // update the system clock. This is so that we can validate future NITZ signals.
+        mLastNitzTime = newNitzUtcTime;
+
+        // System clock update logic.
+
+        // Historically, Android has sent a telephony broadcast only when setting the time using
+        // NITZ.
+        final boolean sendNetworkBroadcast =
+                TimeSignal.SOURCE_ID_NITZ.equals(timeSignal.getSourceId());
+
+        final TimestampedValue<Long> newUtcTime = newNitzUtcTime;
+        setSystemClockIfRequired(newUtcTime, sendNetworkBroadcast);
+    }
+
+    private static boolean validateNewNitzTime(TimestampedValue<Long> newNitzUtcTime,
+            TimestampedValue<Long> lastNitzTime) {
+
+        if (lastNitzTime != null) {
+            long referenceTimeDifference =
+                    TimestampedValue.referenceTimeDifference(newNitzUtcTime, lastNitzTime);
+            if (referenceTimeDifference < 0 || referenceTimeDifference > Integer.MAX_VALUE) {
+                // Out of order or bogus.
+                Slog.w(TAG, "validateNewNitzTime: Bad NITZ signal received."
+                        + " referenceTimeDifference=" + referenceTimeDifference
+                        + " lastNitzTime=" + lastNitzTime
+                        + " newNitzUtcTime=" + newNitzUtcTime);
+                return false;
+            }
+        }
+        return true;
+    }
+
+    private void setSystemClockIfRequired(
+            TimestampedValue<Long> time, boolean sendNetworkBroadcast) {
+
+        // Store the last candidate we've seen in all cases so we can set the system clock
+        // when/if time detection is enabled.
+        mLastSystemClockTime = time;
+        mLastSystemClockTimeSendNetworkBroadcast = sendNetworkBroadcast;
+
+        if (!mCallback.isTimeDetectionEnabled()) {
+            Slog.d(TAG, "setSystemClockIfRequired: Time detection is not enabled. time=" + time);
+            return;
+        }
+
+        mCallback.acquireWakeLock();
+        try {
+            long elapsedRealtimeMillis = mCallback.elapsedRealtimeMillis();
+            long actualTimeMillis = mCallback.systemClockMillis();
+
+            // CLOCK_PARANOIA : Check to see if this class owns the clock or if something else
+            // may be setting the clock.
+            if (mLastSystemClockTimeSet != null) {
+                long expectedTimeMillis = TimeDetectorStrategy.getTimeAt(
+                        mLastSystemClockTimeSet, elapsedRealtimeMillis);
+                long absSystemClockDifference = Math.abs(expectedTimeMillis - actualTimeMillis);
+                if (absSystemClockDifference > SYSTEM_CLOCK_PARANOIA_THRESHOLD_MILLIS) {
+                    Slog.w(TAG, "System clock has not tracked elapsed real time clock. A clock may"
+                            + " be inaccurate or something unexpectedly set the system clock."
+                            + " elapsedRealtimeMillis=" + elapsedRealtimeMillis
+                            + " expectedTimeMillis=" + expectedTimeMillis
+                            + " actualTimeMillis=" + actualTimeMillis);
+                }
+            }
+
+            final String reason = "New time signal";
+            adjustAndSetDeviceSystemClock(
+                    time, sendNetworkBroadcast, elapsedRealtimeMillis, actualTimeMillis, reason);
+        } finally {
+            mCallback.releaseWakeLock();
+        }
     }
 
     @Override
-    public void dump(@NonNull FileDescriptor fd, @NonNull PrintWriter pw, @Nullable String[] args) {
-        // No state to dump.
+    public void handleAutoTimeDetectionToggle(boolean enabled) {
+        // If automatic time detection is enabled we update the system clock instantly if we can.
+        // Conversely, if automatic time detection is disabled we leave the clock as it is.
+        if (enabled) {
+            if (mLastSystemClockTime != null) {
+                // Only send the network broadcast if the last candidate would have caused one.
+                final boolean sendNetworkBroadcast = mLastSystemClockTimeSendNetworkBroadcast;
+
+                mCallback.acquireWakeLock();
+                try {
+                    long elapsedRealtimeMillis = mCallback.elapsedRealtimeMillis();
+                    long actualTimeMillis = mCallback.systemClockMillis();
+
+                    final String reason = "Automatic time detection enabled.";
+                    adjustAndSetDeviceSystemClock(mLastSystemClockTime, sendNetworkBroadcast,
+                            elapsedRealtimeMillis, actualTimeMillis, reason);
+                } finally {
+                    mCallback.releaseWakeLock();
+                }
+            }
+        } else {
+            // CLOCK_PARANOIA: We are losing "control" of the system clock so we cannot predict what
+            // it should be in future.
+            mLastSystemClockTimeSet = null;
+        }
+    }
+
+    @Override
+    public void dump(@NonNull PrintWriter pw, @Nullable String[] args) {
+        pw.println("mLastNitzTime=" + mLastNitzTime);
+        pw.println("mLastSystemClockTimeSet=" + mLastSystemClockTimeSet);
+        pw.println("mLastSystemClockTime=" + mLastSystemClockTime);
+        pw.println("mLastSystemClockTimeSendNetworkBroadcast="
+                + mLastSystemClockTimeSendNetworkBroadcast);
+    }
+
+    private void adjustAndSetDeviceSystemClock(
+            TimestampedValue<Long> newTime, boolean sendNetworkBroadcast,
+            long elapsedRealtimeMillis, long actualSystemClockMillis, String reason) {
+
+        // Adjust for the time that has elapsed since the signal was received.
+        long newSystemClockMillis = TimeDetectorStrategy.getTimeAt(newTime, elapsedRealtimeMillis);
+
+        // Check if the new signal would make sufficient difference to the system clock. If it's
+        // below the threshold then ignore it.
+        long absTimeDifference = Math.abs(newSystemClockMillis - actualSystemClockMillis);
+        long systemClockUpdateThreshold = mCallback.systemClockUpdateThresholdMillis();
+        if (absTimeDifference < systemClockUpdateThreshold) {
+            Slog.d(TAG, "adjustAndSetDeviceSystemClock: Not setting system clock. New time and"
+                    + " system clock are close enough."
+                    + " elapsedRealtimeMillis=" + elapsedRealtimeMillis
+                    + " newTime=" + newTime
+                    + " reason=" + reason
+                    + " systemClockUpdateThreshold=" + systemClockUpdateThreshold
+                    + " absTimeDifference=" + absTimeDifference);
+            return;
+        }
+
+        Slog.d(TAG, "Setting system clock using time=" + newTime
+                + " reason=" + reason
+                + " elapsedRealtimeMillis=" + elapsedRealtimeMillis
+                + " newTimeMillis=" + newSystemClockMillis);
+        mCallback.setSystemClock(newSystemClockMillis);
+
+        // CLOCK_PARANOIA : Record the last time this class set the system clock.
+        mLastSystemClockTimeSet = newTime;
+
+        if (sendNetworkBroadcast) {
+            // Send a broadcast that telephony code used to send after setting the clock.
+            // TODO Remove this broadcast as soon as there are no remaining listeners.
+            Intent intent = new Intent(TelephonyIntents.ACTION_NETWORK_SET_TIME);
+            intent.addFlags(Intent.FLAG_RECEIVER_REPLACE_PENDING);
+            intent.putExtra("time", newSystemClockMillis);
+            mCallback.sendStickyBroadcast(intent);
+        }
     }
 }
diff --git a/services/core/java/com/android/server/timedetector/TimeDetectorService.java b/services/core/java/com/android/server/timedetector/TimeDetectorService.java
index 0ec24d8..9c83000 100644
--- a/services/core/java/com/android/server/timedetector/TimeDetectorService.java
+++ b/services/core/java/com/android/server/timedetector/TimeDetectorService.java
@@ -20,24 +20,29 @@
 import android.annotation.Nullable;
 import android.app.timedetector.ITimeDetectorService;
 import android.app.timedetector.TimeSignal;
+import android.content.ContentResolver;
 import android.content.Context;
+import android.database.ContentObserver;
 import android.os.Binder;
+import android.provider.Settings;
 
+import com.android.internal.annotations.GuardedBy;
 import com.android.internal.annotations.VisibleForTesting;
 import com.android.internal.util.DumpUtils;
+import com.android.server.FgThread;
 import com.android.server.SystemService;
+import com.android.server.timedetector.TimeDetectorStrategy.Callback;
 
 import java.io.FileDescriptor;
 import java.io.PrintWriter;
 import java.util.Objects;
 
 public final class TimeDetectorService extends ITimeDetectorService.Stub {
-
     private static final String TAG = "timedetector.TimeDetectorService";
 
     public static class Lifecycle extends SystemService {
 
-        public Lifecycle(Context context) {
+        public Lifecycle(@NonNull Context context) {
             super(context);
         }
 
@@ -51,31 +56,65 @@
         }
     }
 
-    private final Context mContext;
-    private final TimeDetectorStrategy mTimeDetectorStrategy;
+    @NonNull private final Context mContext;
+    @NonNull private final Callback mCallback;
 
-    private static TimeDetectorService create(Context context) {
-        TimeDetectorStrategy timeDetector = new SimpleTimeDetectorStrategy();
-        timeDetector.initialize(new TimeDetectorStrategyCallbackImpl(context));
-        return new TimeDetectorService(context, timeDetector);
+    // The lock used when call the strategy to ensure thread safety.
+    @NonNull private final Object mStrategyLock = new Object();
+
+    @GuardedBy("mStrategyLock")
+    @NonNull private final TimeDetectorStrategy mTimeDetectorStrategy;
+
+    private static TimeDetectorService create(@NonNull Context context) {
+        final TimeDetectorStrategy timeDetector = new SimpleTimeDetectorStrategy();
+        final TimeDetectorStrategyCallbackImpl callback =
+                new TimeDetectorStrategyCallbackImpl(context);
+        timeDetector.initialize(callback);
+
+        TimeDetectorService timeDetectorService =
+                new TimeDetectorService(context, callback, timeDetector);
+
+        // Wire up event listening.
+        ContentResolver contentResolver = context.getContentResolver();
+        contentResolver.registerContentObserver(
+                Settings.Global.getUriFor(Settings.Global.AUTO_TIME), true,
+                new ContentObserver(FgThread.getHandler()) {
+                    public void onChange(boolean selfChange) {
+                        timeDetectorService.handleAutoTimeDetectionToggle();
+                    }
+                });
+
+        return timeDetectorService;
     }
 
     @VisibleForTesting
-    public TimeDetectorService(@NonNull Context context,
+    public TimeDetectorService(@NonNull Context context, @NonNull Callback callback,
             @NonNull TimeDetectorStrategy timeDetectorStrategy) {
         mContext = Objects.requireNonNull(context);
+        mCallback = Objects.requireNonNull(callback);
         mTimeDetectorStrategy = Objects.requireNonNull(timeDetectorStrategy);
     }
 
     @Override
     public void suggestTime(@NonNull TimeSignal timeSignal) {
         enforceSetTimePermission();
+        Objects.requireNonNull(timeSignal);
 
-        long callerIdToken = Binder.clearCallingIdentity();
+        long idToken = Binder.clearCallingIdentity();
         try {
-            mTimeDetectorStrategy.suggestTime(timeSignal);
+            synchronized (mStrategyLock) {
+                mTimeDetectorStrategy.suggestTime(timeSignal);
+            }
         } finally {
-            Binder.restoreCallingIdentity(callerIdToken);
+            Binder.restoreCallingIdentity(idToken);
+        }
+    }
+
+    @VisibleForTesting
+    public void handleAutoTimeDetectionToggle() {
+        synchronized (mStrategyLock) {
+            final boolean timeDetectionEnabled = mCallback.isTimeDetectionEnabled();
+            mTimeDetectorStrategy.handleAutoTimeDetectionToggle(timeDetectionEnabled);
         }
     }
 
@@ -84,7 +123,9 @@
             @Nullable String[] args) {
         if (!DumpUtils.checkDumpPermission(mContext, TAG, pw)) return;
 
-        mTimeDetectorStrategy.dump(fd, pw, args);
+        synchronized (mStrategyLock) {
+            mTimeDetectorStrategy.dump(pw, args);
+        }
     }
 
     private void enforceSetTimePermission() {
diff --git a/services/core/java/com/android/server/timedetector/TimeDetectorStrategy.java b/services/core/java/com/android/server/timedetector/TimeDetectorStrategy.java
index 5cb2eed..e050865 100644
--- a/services/core/java/com/android/server/timedetector/TimeDetectorStrategy.java
+++ b/services/core/java/com/android/server/timedetector/TimeDetectorStrategy.java
@@ -19,26 +19,66 @@
 import android.annotation.NonNull;
 import android.annotation.Nullable;
 import android.app.timedetector.TimeSignal;
+import android.content.Intent;
 import android.util.TimestampedValue;
 
-import java.io.FileDescriptor;
 import java.io.PrintWriter;
 
 /**
  * The interface for classes that implement the time detection algorithm used by the
- * TimeDetectorService.
+ * TimeDetectorService. The TimeDetectorService handles thread safety: all calls to implementations
+ * of this interface can be assumed to be single threaded (though the thread used may vary).
  *
  * @hide
  */
+// @NotThreadSafe
 public interface TimeDetectorStrategy {
 
+    /**
+     * The interface used by the strategy to interact with the surrounding service.
+     */
     interface Callback {
-        void setTime(TimestampedValue<Long> time);
+
+        /**
+         * The absolute threshold below which the system clock need not be updated. i.e. if setting
+         * the system clock would adjust it by less than this (either backwards or forwards) then it
+         * need not be set.
+         */
+        int systemClockUpdateThresholdMillis();
+
+        /** Returns true if automatic time detection is enabled. */
+        boolean isTimeDetectionEnabled();
+
+        /** Acquire a suitable wake lock. Must be followed by {@link #releaseWakeLock()} */
+        void acquireWakeLock();
+
+        /** Returns the elapsedRealtimeMillis clock value. The WakeLock must be held. */
+        long elapsedRealtimeMillis();
+
+        /** Returns the system clock value. The WakeLock must be held. */
+        long systemClockMillis();
+
+        /** Sets the device system clock. The WakeLock must be held. */
+        void setSystemClock(long newTimeMillis);
+
+        /** Release the wake lock acquired by a call to {@link #acquireWakeLock()}. */
+        void releaseWakeLock();
+
+        /** Send the supplied intent as a stick broadcast. */
+        void sendStickyBroadcast(@NonNull Intent intent);
     }
 
+    /** Initialize the strategy. */
     void initialize(@NonNull Callback callback);
+
+    /** Process the suggested time. */
     void suggestTime(@NonNull TimeSignal timeSignal);
-    void dump(@NonNull FileDescriptor fd, @NonNull PrintWriter pw, @Nullable String[] args);
+
+    /** Handle the auto-time setting being toggled on or off. */
+    void handleAutoTimeDetectionToggle(boolean enabled);
+
+    /** Dump debug information. */
+    void dump(@NonNull PrintWriter pw, @Nullable String[] args);
 
     // Utility methods below are to be moved to a better home when one becomes more obvious.
 
diff --git a/services/core/java/com/android/server/timedetector/TimeDetectorStrategyCallbackImpl.java b/services/core/java/com/android/server/timedetector/TimeDetectorStrategyCallbackImpl.java
index 568d73a..77b9e62 100644
--- a/services/core/java/com/android/server/timedetector/TimeDetectorStrategyCallbackImpl.java
+++ b/services/core/java/com/android/server/timedetector/TimeDetectorStrategyCallbackImpl.java
@@ -18,41 +18,108 @@
 
 import android.annotation.NonNull;
 import android.app.AlarmManager;
+import android.content.ContentResolver;
 import android.content.Context;
+import android.content.Intent;
 import android.os.PowerManager;
 import android.os.SystemClock;
+import android.os.SystemProperties;
+import android.os.UserHandle;
+import android.provider.Settings;
 import android.util.Slog;
-import android.util.TimestampedValue;
+
+import java.util.Objects;
 
 /**
  * The real implementation of {@link TimeDetectorStrategy.Callback} used on device.
  */
-public class TimeDetectorStrategyCallbackImpl implements TimeDetectorStrategy.Callback {
+public final class TimeDetectorStrategyCallbackImpl implements TimeDetectorStrategy.Callback {
 
     private final static String TAG = "timedetector.TimeDetectorStrategyCallbackImpl";
 
-    @NonNull private PowerManager.WakeLock mWakeLock;
-    @NonNull private AlarmManager mAlarmManager;
+    private static final int SYSTEM_CLOCK_UPDATE_THRESHOLD_MILLIS_DEFAULT = 2 * 1000;
 
-    public TimeDetectorStrategyCallbackImpl(Context context) {
+    /**
+     * If a newly calculated system clock time and the current system clock time differs by this or
+     * more the system clock will actually be updated. Used to prevent the system clock being set
+     * for only minor differences.
+     */
+    private final int mSystemClockUpdateThresholdMillis;
+
+    @NonNull private final Context mContext;
+    @NonNull private final ContentResolver mContentResolver;
+    @NonNull private final PowerManager.WakeLock mWakeLock;
+    @NonNull private final AlarmManager mAlarmManager;
+
+    public TimeDetectorStrategyCallbackImpl(@NonNull Context context) {
+        mContext = Objects.requireNonNull(context);
+        mContentResolver = Objects.requireNonNull(context.getContentResolver());
+
         PowerManager powerManager = context.getSystemService(PowerManager.class);
+        mWakeLock = Objects.requireNonNull(
+                powerManager.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, TAG));
 
-        mWakeLock = powerManager.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, TAG);
+        mAlarmManager = Objects.requireNonNull(context.getSystemService(AlarmManager.class));
 
-        mAlarmManager = context.getSystemService(AlarmManager.class);
+        mSystemClockUpdateThresholdMillis =
+                SystemProperties.getInt("ro.sys.time_detector_update_diff",
+                        SYSTEM_CLOCK_UPDATE_THRESHOLD_MILLIS_DEFAULT);
     }
 
     @Override
-    public void setTime(TimestampedValue<Long> time) {
-        mWakeLock.acquire();
+    public int systemClockUpdateThresholdMillis() {
+        return mSystemClockUpdateThresholdMillis;
+    }
+
+    @Override
+    public boolean isTimeDetectionEnabled() {
         try {
-            long elapsedRealtimeMillis = SystemClock.elapsedRealtime();
-            long currentTimeMillis = TimeDetectorStrategy.getTimeAt(time, elapsedRealtimeMillis);
-            Slog.d(TAG, "Setting system clock using time=" + time
-                    + ", elapsedRealtimeMillis=" + elapsedRealtimeMillis);
-            mAlarmManager.setTime(currentTimeMillis);
-        } finally {
-            mWakeLock.release();
+            return Settings.Global.getInt(mContentResolver, Settings.Global.AUTO_TIME) != 0;
+        } catch (Settings.SettingNotFoundException snfe) {
+            return true;
+        }
+    }
+
+    @Override
+    public void acquireWakeLock() {
+        if (mWakeLock.isHeld()) {
+            Slog.wtf(TAG, "WakeLock " + mWakeLock + " already held");
+        }
+        mWakeLock.acquire();
+    }
+
+    @Override
+    public long elapsedRealtimeMillis() {
+        checkWakeLockHeld();
+        return SystemClock.elapsedRealtime();
+    }
+
+    @Override
+    public long systemClockMillis() {
+        checkWakeLockHeld();
+        return System.currentTimeMillis();
+    }
+
+    @Override
+    public void setSystemClock(long newTimeMillis) {
+        checkWakeLockHeld();
+        mAlarmManager.setTime(newTimeMillis);
+    }
+
+    @Override
+    public void releaseWakeLock() {
+        checkWakeLockHeld();
+        mWakeLock.release();
+    }
+
+    @Override
+    public void sendStickyBroadcast(@NonNull Intent intent) {
+        mContext.sendStickyBroadcastAsUser(intent, UserHandle.ALL);
+    }
+
+    private void checkWakeLockHeld() {
+        if (!mWakeLock.isHeld()) {
+            Slog.wtf(TAG, "WakeLock " + mWakeLock + " not held");
         }
     }
 }
diff --git a/services/core/java/com/android/server/wm/DisplayContent.java b/services/core/java/com/android/server/wm/DisplayContent.java
index 0cbf8a7..98c554d 100644
--- a/services/core/java/com/android/server/wm/DisplayContent.java
+++ b/services/core/java/com/android/server/wm/DisplayContent.java
@@ -3427,50 +3427,53 @@
          * @return The proper position for the stack.
          */
         private int findPositionForStack(int requestedPosition, TaskStack stack, boolean adding) {
-            final int topChildPosition = mChildren.size() - 1;
-            boolean toTop = requestedPosition == POSITION_TOP;
-            toTop |= adding ? requestedPosition >= topChildPosition + 1
-                    : requestedPosition >= topChildPosition;
-
             if (stack.inPinnedWindowingMode()) {
-                // Stack in pinned windowing mode is z-ordered on-top of all other stacks so okay to
-                // just return the candidate position.
-                return requestedPosition;
+                return POSITION_TOP;
             }
 
-            // We might call mChildren.get() with targetPosition below, but targetPosition might be
-            // POSITION_TOP (INTEGER_MAX). We need to adjust the value to the actual index in the
-            // array.
-            int targetPosition = toTop ? topChildPosition : requestedPosition;
-            // Note that the index we should return varies depending on the value of adding.
-            // When we're adding a new stack the index is the current target position.
-            // When we're positioning an existing stack the index is the position below the target
-            // stack, because WindowContainer#positionAt() first removes element and then adds
-            // it to specified place.
-            if (toTop && adding) {
+            final int topChildPosition = mChildren.size() - 1;
+            int belowAlwaysOnTopPosition = POSITION_BOTTOM;
+            for (int i = topChildPosition; i >= 0; --i) {
+                if (getStacks().get(i) != stack && !getStacks().get(i).isAlwaysOnTop()) {
+                    belowAlwaysOnTopPosition = i;
+                    break;
+                }
+            }
+
+            // The max possible position we can insert the stack at.
+            int maxPosition = POSITION_TOP;
+            // The min possible position we can insert the stack at.
+            int minPosition = POSITION_BOTTOM;
+
+            if (stack.isAlwaysOnTop()) {
+                if (hasPinnedStack()) {
+                    // Always-on-top stacks go below the pinned stack.
+                    maxPosition = getStacks().indexOf(mPinnedStack) - 1;
+                }
+                // Always-on-top stacks need to be above all other stacks.
+                minPosition = belowAlwaysOnTopPosition !=
+                        POSITION_BOTTOM ? belowAlwaysOnTopPosition : topChildPosition;
+            } else {
+                // Other stacks need to be below the always-on-top stacks.
+                maxPosition = belowAlwaysOnTopPosition !=
+                        POSITION_BOTTOM ? belowAlwaysOnTopPosition : topChildPosition;
+            }
+
+            int targetPosition = requestedPosition;
+            targetPosition = Math.min(targetPosition, maxPosition);
+            targetPosition = Math.max(targetPosition, minPosition);
+
+            int prevPosition = getStacks().indexOf(stack);
+            // The positions we calculated above (maxPosition, minPosition) do not take into
+            // consideration the following edge cases.
+            // 1) We need to adjust the position depending on the value "adding".
+            // 2) When we are moving a stack to another position, we also need to adjust the
+            //    position depending on whether the stack is moving to a higher or lower position.
+            if ((targetPosition != requestedPosition) &&
+                    (adding || targetPosition < prevPosition)) {
                 targetPosition++;
             }
 
-            // Note we might have multiple always on top windows.
-            while (targetPosition >= 0) {
-                int adjustedTargetStackId = adding ? targetPosition - 1 : targetPosition;
-                if (adjustedTargetStackId < 0 || adjustedTargetStackId > topChildPosition) {
-                    break;
-                }
-                TaskStack targetStack = mChildren.get(adjustedTargetStackId);
-                if (!targetStack.isAlwaysOnTop()) {
-                    // We reached a stack that isn't always-on-top.
-                    break;
-                }
-                if (stack.isAlwaysOnTop() && !targetStack.inPinnedWindowingMode()) {
-                    // Always on-top non-pinned windowing mode stacks can go anywhere below pinned
-                    // stack.
-                    break;
-                }
-                // We go one level down, looking for the place on which the new stack can be put.
-                targetPosition--;
-            }
-
             return targetPosition;
         }
 
diff --git a/services/core/java/com/android/server/wm/TaskSnapshotPersister.java b/services/core/java/com/android/server/wm/TaskSnapshotPersister.java
index a642e6a..21e807e 100644
--- a/services/core/java/com/android/server/wm/TaskSnapshotPersister.java
+++ b/services/core/java/com/android/server/wm/TaskSnapshotPersister.java
@@ -39,6 +39,7 @@
 import java.io.FileOutputStream;
 import java.io.IOException;
 import java.util.ArrayDeque;
+import java.util.Arrays;
 
 /**
  * Persists {@link TaskSnapshot}s to disk.
@@ -399,8 +400,8 @@
         @VisibleForTesting
         RemoveObsoleteFilesQueueItem(ArraySet<Integer> persistentTaskIds,
                 int[] runningUserIds) {
-            mPersistentTaskIds = persistentTaskIds;
-            mRunningUserIds = runningUserIds;
+            mPersistentTaskIds = new ArraySet<>(persistentTaskIds);
+            mRunningUserIds = Arrays.copyOf(runningUserIds, runningUserIds.length);
         }
 
         @Override
diff --git a/services/core/java/com/android/server/wm/TaskStack.java b/services/core/java/com/android/server/wm/TaskStack.java
index 76a060e..e01cebd 100644
--- a/services/core/java/com/android/server/wm/TaskStack.java
+++ b/services/core/java/com/android/server/wm/TaskStack.java
@@ -726,18 +726,33 @@
     @Override
     public void onConfigurationChanged(Configuration newParentConfig) {
         final int prevWindowingMode = getWindowingMode();
+        final boolean prevIsAlwaysOnTop = isAlwaysOnTop();
         super.onConfigurationChanged(newParentConfig);
 
         // Only need to update surface size here since the super method will handle updating
         // surface position.
         updateSurfaceSize(getPendingTransaction());
         final int windowingMode = getWindowingMode();
+        final boolean isAlwaysOnTop = isAlwaysOnTop();
 
-        if (mDisplayContent == null || prevWindowingMode == windowingMode) {
+        if (mDisplayContent == null) {
             return;
         }
-        mDisplayContent.onStackWindowingModeChanged(this);
-        updateBoundsForWindowModeChange();
+
+        if (prevWindowingMode != windowingMode) {
+            mDisplayContent.onStackWindowingModeChanged(this);
+            updateBoundsForWindowModeChange();
+        }
+
+        if (prevIsAlwaysOnTop != isAlwaysOnTop) {
+            // positionStackAt(POSITION_TOP, this) must be called even when always on top gets
+            // turned off because we need to make sure that the stack is moved from among always on
+            // top windows to below other always on top windows. Since the position the stack should
+            // be inserted into is calculated properly in
+            // {@link DisplayContent#findPositionForStack()} in both cases, we can just request that
+            // the stack is put at top here.
+            mDisplayContent.positionStackAt(POSITION_TOP, this);
+        }
     }
 
     private void updateSurfaceBounds() {
diff --git a/services/core/java/com/android/server/wm/WindowContainer.java b/services/core/java/com/android/server/wm/WindowContainer.java
index 8fe7063..fee0fcb 100644
--- a/services/core/java/com/android/server/wm/WindowContainer.java
+++ b/services/core/java/com/android/server/wm/WindowContainer.java
@@ -246,6 +246,19 @@
                     + " is already a child of container=" + child.getParent().getName()
                     + " can't add to container=" + getName());
         }
+
+        if ((index < 0 && index != POSITION_BOTTOM)
+                || (index > mChildren.size() && index != POSITION_TOP)) {
+            throw new IllegalArgumentException("addChild: invalid position=" + index
+                    + ", children number=" + mChildren.size());
+        }
+
+        if (index == POSITION_TOP) {
+            index = mChildren.size();
+        } else if (index == POSITION_BOTTOM) {
+            index = 0;
+        }
+
         mChildren.add(index, child);
         onChildAdded(child);
 
diff --git a/services/java/com/android/server/SystemServer.java b/services/java/com/android/server/SystemServer.java
index 3321ced..1f1b3f8 100644
--- a/services/java/com/android/server/SystemServer.java
+++ b/services/java/com/android/server/SystemServer.java
@@ -1245,21 +1245,24 @@
             }
             traceEnd();
 
-            traceBeginAndSlog("StartTimeDetectorService");
-            try {
-                mSystemServiceManager.startService(TIME_DETECTOR_SERVICE_CLASS);
-            } catch (Throwable e) {
-                reportWtf("starting StartTimeDetectorService service", e);
-            }
-            traceEnd();
+            final boolean useNewTimeServices = true;
+            if (useNewTimeServices) {
+                traceBeginAndSlog("StartTimeDetectorService");
+                try {
+                    mSystemServiceManager.startService(TIME_DETECTOR_SERVICE_CLASS);
+                } catch (Throwable e) {
+                    reportWtf("starting StartTimeDetectorService service", e);
+                }
+                traceEnd();
 
-            traceBeginAndSlog("StartTimeZoneDetectorService");
-            try {
-                mSystemServiceManager.startService(TIME_ZONE_DETECTOR_SERVICE_CLASS);
-            } catch (Throwable e) {
-                reportWtf("starting StartTimeZoneDetectorService service", e);
+                traceBeginAndSlog("StartTimeZoneDetectorService");
+                try {
+                    mSystemServiceManager.startService(TIME_ZONE_DETECTOR_SERVICE_CLASS);
+                } catch (Throwable e) {
+                    reportWtf("starting StartTimeZoneDetectorService service", e);
+                }
+                traceEnd();
             }
-            traceEnd();
 
             if (!isWatch) {
                 traceBeginAndSlog("StartSearchManagerService");
@@ -1426,7 +1429,12 @@
             if (!isWatch) {
                 traceBeginAndSlog("StartNetworkTimeUpdateService");
                 try {
-                    networkTimeUpdater = new NetworkTimeUpdateService(context);
+                    if (useNewTimeServices) {
+                        networkTimeUpdater = new NewNetworkTimeUpdateService(context);
+                    } else {
+                        networkTimeUpdater = new OldNetworkTimeUpdateService(context);
+                    }
+                    Slog.d(TAG, "Using networkTimeUpdater class=" + networkTimeUpdater.getClass());
                     ServiceManager.addService("network_time_update_service", networkTimeUpdater);
                 } catch (Throwable e) {
                     reportWtf("starting NetworkTimeUpdate service", e);
diff --git a/services/tests/servicestests/src/com/android/server/am/ActivityStackTests.java b/services/tests/servicestests/src/com/android/server/am/ActivityStackTests.java
index 0d0a6ba..4094716 100644
--- a/services/tests/servicestests/src/com/android/server/am/ActivityStackTests.java
+++ b/services/tests/servicestests/src/com/android/server/am/ActivityStackTests.java
@@ -19,6 +19,7 @@
 import static android.app.WindowConfiguration.ACTIVITY_TYPE_ASSISTANT;
 import static android.app.WindowConfiguration.ACTIVITY_TYPE_HOME;
 import static android.app.WindowConfiguration.ACTIVITY_TYPE_STANDARD;
+import static android.app.WindowConfiguration.WINDOWING_MODE_FREEFORM;
 import static android.app.WindowConfiguration.WINDOWING_MODE_FULLSCREEN;
 import static android.app.WindowConfiguration.WINDOWING_MODE_PINNED;
 import static android.app.WindowConfiguration.WINDOWING_MODE_SPLIT_SCREEN_PRIMARY;
@@ -473,6 +474,42 @@
     }
 
     @Test
+    public void testSetAlwaysOnTop() {
+        final TestActivityStack homeStack = createStackForShouldBeVisibleTest(mDefaultDisplay,
+                WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_HOME, true /* onTop */);
+        final ActivityStack pinnedStack = createStackForShouldBeVisibleTest(mDefaultDisplay,
+                WINDOWING_MODE_PINNED, ACTIVITY_TYPE_STANDARD, true /* onTop */);
+        assertTrue(mDefaultDisplay.getStackAbove(homeStack) == pinnedStack);
+
+        final TestActivityStack alwaysOnTopStack = createStackForShouldBeVisibleTest(
+                mDefaultDisplay, WINDOWING_MODE_FREEFORM, ACTIVITY_TYPE_STANDARD,
+                true /* onTop */);
+        alwaysOnTopStack.setAlwaysOnTop(true);
+        assertTrue(alwaysOnTopStack.isAlwaysOnTop());
+        // Ensure (non-pinned) always on top stack is put below pinned stack.
+        assertTrue(mDefaultDisplay.getStackAbove(alwaysOnTopStack) == pinnedStack);
+
+        final TestActivityStack nonAlwaysOnTopStack = createStackForShouldBeVisibleTest(
+                mDefaultDisplay, WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD,
+                true /* onTop */);
+        // Ensure non always on top stack is put below always on top stacks.
+        assertTrue(mDefaultDisplay.getStackAbove(nonAlwaysOnTopStack) == alwaysOnTopStack);
+
+        final TestActivityStack alwaysOnTopStack2 = createStackForShouldBeVisibleTest(
+                mDefaultDisplay, WINDOWING_MODE_FREEFORM, ACTIVITY_TYPE_STANDARD,
+                true /* onTop */);
+        alwaysOnTopStack2.setAlwaysOnTop(true);
+        assertTrue(alwaysOnTopStack2.isAlwaysOnTop());
+        // Ensure newly created always on top stack is placed above other all always on top stacks.
+        assertTrue(mDefaultDisplay.getStackAbove(alwaysOnTopStack2) == pinnedStack);
+
+        alwaysOnTopStack2.setAlwaysOnTop(false);
+        // Ensure, when always on top is turned off for a stack, the stack is put just below all
+        // other always on top stacks.
+        assertTrue(mDefaultDisplay.getStackAbove(alwaysOnTopStack2) == alwaysOnTopStack);
+    }
+
+    @Test
     public void testSplitScreenMoveToFront() throws Exception {
         final TestActivityStack splitScreenPrimary = createStackForShouldBeVisibleTest(
                 mDefaultDisplay, WINDOWING_MODE_SPLIT_SCREEN_PRIMARY, ACTIVITY_TYPE_STANDARD,
diff --git a/services/tests/servicestests/src/com/android/server/timedetector/SimpleTimeZoneDetectorStrategyTest.java b/services/tests/servicestests/src/com/android/server/timedetector/SimpleTimeZoneDetectorStrategyTest.java
index e4b3b13..62f1433 100644
--- a/services/tests/servicestests/src/com/android/server/timedetector/SimpleTimeZoneDetectorStrategyTest.java
+++ b/services/tests/servicestests/src/com/android/server/timedetector/SimpleTimeZoneDetectorStrategyTest.java
@@ -16,12 +16,18 @@
 
 package com.android.server.timedetector;
 
-import static org.mockito.ArgumentMatchers.any;
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.never;
-import static org.mockito.Mockito.verify;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertNull;
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
 
 import android.app.timedetector.TimeSignal;
+import android.content.Intent;
+import android.icu.util.Calendar;
+import android.icu.util.GregorianCalendar;
+import android.icu.util.TimeZone;
 import android.support.test.runner.AndroidJUnit4;
 import android.util.TimestampedValue;
 
@@ -32,37 +38,476 @@
 @RunWith(AndroidJUnit4.class)
 public class SimpleTimeZoneDetectorStrategyTest {
 
-    private TimeDetectorStrategy.Callback mMockCallback;
+    private static final Scenario SCENARIO_1 = new Scenario.Builder()
+            .setInitialDeviceSystemClockUtc(1977, 1, 1, 12, 0, 0)
+            .setInitialDeviceRealtimeMillis(123456789L)
+            .setActualTimeUtc(2018, 1, 1, 12, 0, 0)
+            .build();
 
-    private SimpleTimeDetectorStrategy mSimpleTimeZoneDetectorStrategy;
+    private Script mScript;
 
     @Before
     public void setUp() {
-        mMockCallback = mock(TimeDetectorStrategy.Callback.class);
-        mSimpleTimeZoneDetectorStrategy = new SimpleTimeDetectorStrategy();
-        mSimpleTimeZoneDetectorStrategy.initialize(mMockCallback);
+        mScript = new Script();
     }
 
     @Test
-    public void testSuggestTime_nitz() {
-        TimestampedValue<Long> utcTime = createUtcTime();
-        TimeSignal timeSignal = new TimeSignal(TimeSignal.SOURCE_ID_NITZ, utcTime);
+    public void testSuggestTime_nitz_timeDetectionEnabled() {
+        Scenario scenario = SCENARIO_1;
+        mScript.pokeFakeClocks(scenario)
+                .pokeTimeDetectionEnabled(true);
 
-        mSimpleTimeZoneDetectorStrategy.suggestTime(timeSignal);
+        TimeSignal timeSignal = scenario.createTimeSignalForActual(TimeSignal.SOURCE_ID_NITZ);
+        final int clockIncrement = 1000;
+        long expectSystemClockMillis = scenario.getActualTimeMillis() + clockIncrement;
 
-        verify(mMockCallback).setTime(utcTime);
+        mScript.simulateTimePassing(clockIncrement)
+                .simulateTimeSignalReceived(timeSignal)
+                .verifySystemClockWasSetAndResetCallTracking(expectSystemClockMillis);
+    }
+
+    @Test
+    public void testSuggestTime_systemClockThreshold() {
+        Scenario scenario = SCENARIO_1;
+        final int systemClockUpdateThresholdMillis = 1000;
+        mScript.pokeFakeClocks(scenario)
+                .pokeThresholds(systemClockUpdateThresholdMillis)
+                .pokeTimeDetectionEnabled(true);
+
+        TimeSignal timeSignal1 = scenario.createTimeSignalForActual(TimeSignal.SOURCE_ID_NITZ);
+        TimestampedValue<Long> utcTime1 = timeSignal1.getUtcTime();
+
+        final int clockIncrement = 100;
+        // Increment the the device clocks to simulate the passage of time.
+        mScript.simulateTimePassing(clockIncrement);
+
+        long expectSystemClockMillis1 =
+                TimeDetectorStrategy.getTimeAt(utcTime1, mScript.peekElapsedRealtimeMillis());
+
+        // Send the first time signal. It should be used.
+        mScript.simulateTimeSignalReceived(timeSignal1)
+                .verifySystemClockWasSetAndResetCallTracking(expectSystemClockMillis1);
+
+        // Now send another time signal, but one that is too similar to the last one and should be
+        // ignored.
+        int underThresholdMillis = systemClockUpdateThresholdMillis - 1;
+        TimestampedValue<Long> utcTime2 = new TimestampedValue<>(
+                mScript.peekElapsedRealtimeMillis(),
+                mScript.peekSystemClockMillis() + underThresholdMillis);
+        TimeSignal timeSignal2 = new TimeSignal(TimeSignal.SOURCE_ID_NITZ, utcTime2);
+        mScript.simulateTimePassing(clockIncrement)
+                .simulateTimeSignalReceived(timeSignal2)
+                .verifySystemClockWasNotSetAndResetCallTracking();
+
+        // Now send another time signal, but one that is on the threshold and so should be used.
+        TimestampedValue<Long> utcTime3 = new TimestampedValue<>(
+                mScript.peekElapsedRealtimeMillis(),
+                mScript.peekSystemClockMillis() + systemClockUpdateThresholdMillis);
+
+        TimeSignal timeSignal3 = new TimeSignal(TimeSignal.SOURCE_ID_NITZ, utcTime3);
+        mScript.simulateTimePassing(clockIncrement);
+
+        long expectSystemClockMillis3 =
+                TimeDetectorStrategy.getTimeAt(utcTime3, mScript.peekElapsedRealtimeMillis());
+
+        mScript.simulateTimeSignalReceived(timeSignal3)
+                .verifySystemClockWasSetAndResetCallTracking(expectSystemClockMillis3);
+    }
+
+    @Test
+    public void testSuggestTime_nitz_timeDetectionDisabled() {
+        Scenario scenario = SCENARIO_1;
+        mScript.pokeFakeClocks(scenario)
+                .pokeTimeDetectionEnabled(false);
+
+        TimeSignal timeSignal = scenario.createTimeSignalForActual(TimeSignal.SOURCE_ID_NITZ);
+        mScript.simulateTimeSignalReceived(timeSignal)
+                .verifySystemClockWasNotSetAndResetCallTracking();
+    }
+
+    @Test
+    public void testSuggestTime_nitz_invalidNitzReferenceTimesIgnored() {
+        Scenario scenario = SCENARIO_1;
+        final int systemClockUpdateThreshold = 2000;
+        mScript.pokeFakeClocks(scenario)
+                .pokeThresholds(systemClockUpdateThreshold)
+                .pokeTimeDetectionEnabled(true);
+        TimeSignal timeSignal1 = scenario.createTimeSignalForActual(TimeSignal.SOURCE_ID_NITZ);
+        TimestampedValue<Long> utcTime1 = timeSignal1.getUtcTime();
+
+        // Initialize the strategy / device with a time set from NITZ.
+        mScript.simulateTimePassing(100);
+        long expectedSystemClockMillis1 =
+                TimeDetectorStrategy.getTimeAt(utcTime1, mScript.peekElapsedRealtimeMillis());
+        mScript.simulateTimeSignalReceived(timeSignal1)
+                .verifySystemClockWasSetAndResetCallTracking(expectedSystemClockMillis1);
+
+        // The UTC time increment should be larger than the system clock update threshold so we
+        // know it shouldn't be ignored for other reasons.
+        long validUtcTimeMillis = utcTime1.getValue() + (2 * systemClockUpdateThreshold);
+
+        // Now supply a new signal that has an obviously bogus reference time : older than the last
+        // one.
+        long referenceTimeBeforeLastSignalMillis = utcTime1.getReferenceTimeMillis() - 1;
+        TimestampedValue<Long> utcTime2 = new TimestampedValue<>(
+                referenceTimeBeforeLastSignalMillis, validUtcTimeMillis);
+        TimeSignal timeSignal2 = new TimeSignal(TimeSignal.SOURCE_ID_NITZ, utcTime2);
+        mScript.simulateTimeSignalReceived(timeSignal2)
+                .verifySystemClockWasNotSetAndResetCallTracking();
+
+        // Now supply a new signal that has an obviously bogus reference time : substantially in the
+        // future.
+        long referenceTimeInFutureMillis =
+                utcTime1.getReferenceTimeMillis() + Integer.MAX_VALUE + 1;
+        TimestampedValue<Long> utcTime3 = new TimestampedValue<>(
+                referenceTimeInFutureMillis, validUtcTimeMillis);
+        TimeSignal timeSignal3 = new TimeSignal(TimeSignal.SOURCE_ID_NITZ, utcTime3);
+        mScript.simulateTimeSignalReceived(timeSignal3)
+                .verifySystemClockWasNotSetAndResetCallTracking();
+
+        // Just to prove validUtcTimeMillis is valid.
+        long validReferenceTimeMillis = utcTime1.getReferenceTimeMillis() + 100;
+        TimestampedValue<Long> utcTime4 = new TimestampedValue<>(
+                validReferenceTimeMillis, validUtcTimeMillis);
+        long expectedSystemClockMillis4 =
+                TimeDetectorStrategy.getTimeAt(utcTime4, mScript.peekElapsedRealtimeMillis());
+        TimeSignal timeSignal4 = new TimeSignal(TimeSignal.SOURCE_ID_NITZ, utcTime4);
+        mScript.simulateTimeSignalReceived(timeSignal4)
+                .verifySystemClockWasSetAndResetCallTracking(expectedSystemClockMillis4);
+    }
+
+    @Test
+    public void testSuggestTime_timeDetectionToggled() {
+        Scenario scenario = SCENARIO_1;
+        final int clockIncrementMillis = 100;
+        final int systemClockUpdateThreshold = 2000;
+        mScript.pokeFakeClocks(scenario)
+                .pokeThresholds(systemClockUpdateThreshold)
+                .pokeTimeDetectionEnabled(false);
+
+        TimeSignal timeSignal1 = scenario.createTimeSignalForActual(TimeSignal.SOURCE_ID_NITZ);
+        TimestampedValue<Long> utcTime1 = timeSignal1.getUtcTime();
+
+        // Simulate time passing.
+        mScript.simulateTimePassing(clockIncrementMillis);
+
+        // Simulate the time signal being received. It should not be used because auto time
+        // detection is off but it should be recorded.
+        mScript.simulateTimeSignalReceived(timeSignal1)
+                .verifySystemClockWasNotSetAndResetCallTracking();
+
+        // Simulate more time passing.
+        mScript.simulateTimePassing(clockIncrementMillis);
+
+        long expectedSystemClockMillis1 =
+                TimeDetectorStrategy.getTimeAt(utcTime1, mScript.peekElapsedRealtimeMillis());
+
+        // Turn on auto time detection.
+        mScript.simulateAutoTimeDetectionToggle()
+                .verifySystemClockWasSetAndResetCallTracking(expectedSystemClockMillis1);
+
+        // Turn off auto time detection.
+        mScript.simulateAutoTimeDetectionToggle()
+                .verifySystemClockWasNotSetAndResetCallTracking();
+
+        // Receive another valid time signal.
+        // It should be on the threshold and accounting for the clock increments.
+        TimestampedValue<Long> utcTime2 = new TimestampedValue<>(
+                mScript.peekElapsedRealtimeMillis(),
+                mScript.peekSystemClockMillis() + systemClockUpdateThreshold);
+        TimeSignal timeSignal2 = new TimeSignal(TimeSignal.SOURCE_ID_NITZ, utcTime2);
+
+        // Simulate more time passing.
+        mScript.simulateTimePassing(clockIncrementMillis);
+
+        long expectedSystemClockMillis2 =
+                TimeDetectorStrategy.getTimeAt(utcTime2, mScript.peekElapsedRealtimeMillis());
+
+        // The new time, though valid, should not be set in the system clock because auto time is
+        // disabled.
+        mScript.simulateTimeSignalReceived(timeSignal2)
+                .verifySystemClockWasNotSetAndResetCallTracking();
+
+        // Turn on auto time detection.
+        mScript.simulateAutoTimeDetectionToggle()
+                .verifySystemClockWasSetAndResetCallTracking(expectedSystemClockMillis2);
     }
 
     @Test
     public void testSuggestTime_unknownSource() {
-        TimestampedValue<Long> utcTime = createUtcTime();
-        TimeSignal timeSignal = new TimeSignal("unknown", utcTime);
-        mSimpleTimeZoneDetectorStrategy.suggestTime(timeSignal);
+        Scenario scenario = SCENARIO_1;
+        mScript.pokeFakeClocks(scenario)
+                .pokeTimeDetectionEnabled(true);
 
-        verify(mMockCallback, never()).setTime(any());
+        TimeSignal timeSignal = scenario.createTimeSignalForActual("unknown");
+        mScript.simulateTimeSignalReceived(timeSignal)
+                .verifySystemClockWasNotSetAndResetCallTracking();
     }
 
-    private static TimestampedValue<Long> createUtcTime() {
-        return new TimestampedValue<>(321L, 123456L);
+    /**
+     * A fake implementation of TimeDetectorStrategy.Callback. Besides tracking changes and behaving
+     * like the real thing should, it also asserts preconditions.
+     */
+    private static class FakeCallback implements TimeDetectorStrategy.Callback {
+        private boolean mTimeDetectionEnabled;
+        private boolean mWakeLockAcquired;
+        private long mElapsedRealtimeMillis;
+        private long mSystemClockMillis;
+        private int mSystemClockUpdateThresholdMillis = 2000;
+
+        // Tracking operations.
+        private boolean mSystemClockWasSet;
+        private Intent mBroadcastSent;
+
+        @Override
+        public int systemClockUpdateThresholdMillis() {
+            return mSystemClockUpdateThresholdMillis;
+        }
+
+        @Override
+        public boolean isTimeDetectionEnabled() {
+            return mTimeDetectionEnabled;
+        }
+
+        @Override
+        public void acquireWakeLock() {
+            if (mWakeLockAcquired) {
+                fail("Wake lock already acquired");
+            }
+            mWakeLockAcquired = true;
+        }
+
+        @Override
+        public long elapsedRealtimeMillis() {
+            assertWakeLockAcquired();
+            return mElapsedRealtimeMillis;
+        }
+
+        @Override
+        public long systemClockMillis() {
+            assertWakeLockAcquired();
+            return mSystemClockMillis;
+        }
+
+        @Override
+        public void setSystemClock(long newTimeMillis) {
+            assertWakeLockAcquired();
+            mSystemClockWasSet = true;
+            mSystemClockMillis = newTimeMillis;
+        }
+
+        @Override
+        public void releaseWakeLock() {
+            assertWakeLockAcquired();
+            mWakeLockAcquired = false;
+        }
+
+        @Override
+        public void sendStickyBroadcast(Intent intent) {
+            assertNotNull(intent);
+            mBroadcastSent = intent;
+        }
+
+        // Methods below are for managing the fake's behavior.
+
+        public void pokeSystemClockUpdateThreshold(int thresholdMillis) {
+            mSystemClockUpdateThresholdMillis = thresholdMillis;
+        }
+
+        public void pokeElapsedRealtimeMillis(long elapsedRealtimeMillis) {
+            mElapsedRealtimeMillis = elapsedRealtimeMillis;
+        }
+
+        public void pokeSystemClockMillis(long systemClockMillis) {
+            mSystemClockMillis = systemClockMillis;
+        }
+
+        public void pokeTimeDetectionEnabled(boolean enabled) {
+            mTimeDetectionEnabled = enabled;
+        }
+
+        public long peekElapsedRealtimeMillis() {
+            return mElapsedRealtimeMillis;
+        }
+
+        public long peekSystemClockMillis() {
+            return mSystemClockMillis;
+        }
+
+        public void simulateTimePassing(int incrementMillis) {
+            mElapsedRealtimeMillis += incrementMillis;
+            mSystemClockMillis += incrementMillis;
+        }
+
+        public void verifySystemClockNotSet() {
+            assertFalse(mSystemClockWasSet);
+        }
+
+        public void verifySystemClockWasSet(long expectSystemClockMillis) {
+            assertTrue(mSystemClockWasSet);
+            assertEquals(expectSystemClockMillis, mSystemClockMillis);
+        }
+
+        public void verifyIntentWasBroadcast() {
+            assertTrue(mBroadcastSent != null);
+        }
+
+        public void verifyIntentWasNotBroadcast() {
+            assertNull(mBroadcastSent);
+        }
+
+        public void resetCallTracking() {
+            mSystemClockWasSet = false;
+            mBroadcastSent = null;
+        }
+
+        private void assertWakeLockAcquired() {
+            assertTrue("The operation must be performed only after acquiring the wakelock",
+                    mWakeLockAcquired);
+        }
+    }
+
+    /**
+     * A fluent helper class for tests.
+     */
+    private class Script {
+
+        private final FakeCallback mFakeCallback;
+        private final SimpleTimeDetectorStrategy mSimpleTimeDetectorStrategy;
+
+        public Script() {
+            mFakeCallback = new FakeCallback();
+            mSimpleTimeDetectorStrategy = new SimpleTimeDetectorStrategy();
+            mSimpleTimeDetectorStrategy.initialize(mFakeCallback);
+
+        }
+
+        Script pokeTimeDetectionEnabled(boolean enabled) {
+            mFakeCallback.pokeTimeDetectionEnabled(enabled);
+            return this;
+        }
+
+        Script pokeFakeClocks(Scenario scenario) {
+            mFakeCallback.pokeElapsedRealtimeMillis(scenario.getInitialRealTimeMillis());
+            mFakeCallback.pokeSystemClockMillis(scenario.getInitialSystemClockMillis());
+            return this;
+        }
+
+        Script pokeThresholds(int systemClockUpdateThreshold) {
+            mFakeCallback.pokeSystemClockUpdateThreshold(systemClockUpdateThreshold);
+            return this;
+        }
+
+        long peekElapsedRealtimeMillis() {
+            return mFakeCallback.peekElapsedRealtimeMillis();
+        }
+
+        long peekSystemClockMillis() {
+            return mFakeCallback.peekSystemClockMillis();
+        }
+
+        Script simulateTimeSignalReceived(TimeSignal timeSignal) {
+            mSimpleTimeDetectorStrategy.suggestTime(timeSignal);
+            return this;
+        }
+
+        Script simulateAutoTimeDetectionToggle() {
+            boolean enabled = !mFakeCallback.isTimeDetectionEnabled();
+            mFakeCallback.pokeTimeDetectionEnabled(enabled);
+            mSimpleTimeDetectorStrategy.handleAutoTimeDetectionToggle(enabled);
+            return this;
+        }
+
+        Script simulateTimePassing(int clockIncrement) {
+            mFakeCallback.simulateTimePassing(clockIncrement);
+            return this;
+        }
+
+        Script verifySystemClockWasNotSetAndResetCallTracking() {
+            mFakeCallback.verifySystemClockNotSet();
+            mFakeCallback.verifyIntentWasNotBroadcast();
+            mFakeCallback.resetCallTracking();
+            return this;
+        }
+
+        Script verifySystemClockWasSetAndResetCallTracking(long expectSystemClockMillis) {
+            mFakeCallback.verifySystemClockWasSet(expectSystemClockMillis);
+            mFakeCallback.verifyIntentWasBroadcast();
+            mFakeCallback.resetCallTracking();
+            return this;
+        }
+    }
+
+    /**
+     * A starting scenario used during tests. Describes a fictional "physical" reality.
+     */
+    private static class Scenario {
+
+        private final long mInitialDeviceSystemClockMillis;
+        private final long mInitialDeviceRealtimeMillis;
+        private final long mActualTimeMillis;
+
+        Scenario(long initialDeviceSystemClock, long elapsedRealtime, long timeMillis) {
+            mInitialDeviceSystemClockMillis = initialDeviceSystemClock;
+            mActualTimeMillis = timeMillis;
+            mInitialDeviceRealtimeMillis = elapsedRealtime;
+        }
+
+        long getInitialRealTimeMillis() {
+            return mInitialDeviceRealtimeMillis;
+        }
+
+        long getInitialSystemClockMillis() {
+            return mInitialDeviceSystemClockMillis;
+        }
+
+        long getActualTimeMillis() {
+            return mActualTimeMillis;
+        }
+
+        TimeSignal createTimeSignalForActual(String sourceId) {
+            TimestampedValue<Long> time = new TimestampedValue<>(
+                    mInitialDeviceRealtimeMillis, mActualTimeMillis);
+            return new TimeSignal(sourceId, time);
+        }
+
+        static class Builder {
+
+            private long mInitialDeviceSystemClockMillis;
+            private long mInitialDeviceRealtimeMillis;
+            private long mActualTimeMillis;
+
+            Builder setInitialDeviceSystemClockUtc(int year, int monthInYear, int day,
+                    int hourOfDay, int minute, int second) {
+                mInitialDeviceSystemClockMillis = createUtcTime(year, monthInYear, day, hourOfDay,
+                        minute, second);
+                return this;
+            }
+
+            Builder setInitialDeviceRealtimeMillis(long realtimeMillis) {
+                mInitialDeviceRealtimeMillis = realtimeMillis;
+                return this;
+            }
+
+            Builder setActualTimeUtc(int year, int monthInYear, int day, int hourOfDay,
+                    int minute, int second) {
+                mActualTimeMillis =
+                        createUtcTime(year, monthInYear, day, hourOfDay, minute, second);
+                return this;
+            }
+
+            Scenario build() {
+                return new Scenario(mInitialDeviceSystemClockMillis, mInitialDeviceRealtimeMillis,
+                        mActualTimeMillis);
+            }
+        }
+    }
+
+    private static long createUtcTime(int year, int monthInYear, int day, int hourOfDay, int minute,
+            int second) {
+        Calendar cal = new GregorianCalendar(TimeZone.getTimeZone("Etc/UTC"));
+        cal.clear();
+        cal.set(year, monthInYear - 1, day, hourOfDay, minute, second);
+        return cal.getTimeInMillis();
     }
 }
diff --git a/services/tests/servicestests/src/com/android/server/timedetector/TimeDetectorServiceTest.java b/services/tests/servicestests/src/com/android/server/timedetector/TimeDetectorServiceTest.java
index 22dea92..ed74cd7 100644
--- a/services/tests/servicestests/src/com/android/server/timedetector/TimeDetectorServiceTest.java
+++ b/services/tests/servicestests/src/com/android/server/timedetector/TimeDetectorServiceTest.java
@@ -16,6 +16,9 @@
 
 package com.android.server.timedetector;
 
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertTrue;
 import static org.mockito.ArgumentMatchers.any;
 import static org.mockito.ArgumentMatchers.anyString;
 import static org.mockito.ArgumentMatchers.eq;
@@ -23,36 +26,40 @@
 import static org.mockito.Mockito.doThrow;
 import static org.mockito.Mockito.mock;
 import static org.mockito.Mockito.verify;
-import static org.mockito.Mockito.verifyNoMoreInteractions;
+import static org.mockito.Mockito.when;
 
 import android.app.timedetector.TimeSignal;
 import android.content.Context;
+import android.content.pm.PackageManager;
 import android.support.test.runner.AndroidJUnit4;
 import android.util.TimestampedValue;
 
-import org.junit.After;
 import org.junit.Before;
 import org.junit.Test;
 import org.junit.runner.RunWith;
 
+import com.android.server.timedetector.TimeDetectorStrategy.Callback;
+
+import java.io.PrintWriter;
+
 @RunWith(AndroidJUnit4.class)
 public class TimeDetectorServiceTest {
 
-    private TimeDetectorService mTimeDetectorService;
-
     private Context mMockContext;
-    private TimeDetectorStrategy mMockTimeDetectorStrategy;
+    private StubbedTimeDetectorStrategy mStubbedTimeDetectorStrategy;
+    private Callback mMockCallback;
+
+    private TimeDetectorService mTimeDetectorService;
 
     @Before
     public void setUp() {
         mMockContext = mock(Context.class);
-        mMockTimeDetectorStrategy = mock(TimeDetectorStrategy.class);
-        mTimeDetectorService = new TimeDetectorService(mMockContext, mMockTimeDetectorStrategy);
-    }
+        mMockCallback = mock(Callback.class);
+        mStubbedTimeDetectorStrategy = new StubbedTimeDetectorStrategy();
 
-    @After
-    public void tearDown() {
-        verifyNoMoreInteractions(mMockContext, mMockTimeDetectorStrategy);
+        mTimeDetectorService = new TimeDetectorService(
+                mMockContext, mMockCallback,
+                mStubbedTimeDetectorStrategy);
     }
 
     @Test(expected=SecurityException.class)
@@ -78,11 +85,86 @@
 
         verify(mMockContext)
                 .enforceCallingPermission(eq(android.Manifest.permission.SET_TIME), anyString());
-        verify(mMockTimeDetectorStrategy).suggestTime(timeSignal);
+        mStubbedTimeDetectorStrategy.verifySuggestTimeCalled(timeSignal);
+    }
+
+    @Test
+    public void testDump() {
+        when(mMockContext.checkCallingOrSelfPermission(android.Manifest.permission.DUMP))
+                .thenReturn(PackageManager.PERMISSION_GRANTED);
+
+        mTimeDetectorService.dump(null, null, null);
+
+        verify(mMockContext).checkCallingOrSelfPermission(eq(android.Manifest.permission.DUMP));
+        mStubbedTimeDetectorStrategy.verifyDumpCalled();
+    }
+
+    @Test
+    public void testAutoTimeDetectionToggle() {
+        when(mMockCallback.isTimeDetectionEnabled()).thenReturn(true);
+
+        mTimeDetectorService.handleAutoTimeDetectionToggle();
+
+        mStubbedTimeDetectorStrategy.verifyHandleAutoTimeDetectionToggleCalled(true);
+
+        when(mMockCallback.isTimeDetectionEnabled()).thenReturn(false);
+
+        mTimeDetectorService.handleAutoTimeDetectionToggle();
+
+        mStubbedTimeDetectorStrategy.verifyHandleAutoTimeDetectionToggleCalled(false);
     }
 
     private static TimeSignal createNitzTimeSignal() {
         TimestampedValue<Long> timeValue = new TimestampedValue<>(100L, 1_000_000L);
         return new TimeSignal(TimeSignal.SOURCE_ID_NITZ, timeValue);
     }
+
+    private static class StubbedTimeDetectorStrategy implements TimeDetectorStrategy {
+
+        // Call tracking.
+        private TimeSignal mLastSuggestedTime;
+        private Boolean mLastAutoTimeDetectionToggle;
+        private boolean mDumpCalled;
+
+        @Override
+        public void initialize(Callback ignored) {
+        }
+
+        @Override
+        public void suggestTime(TimeSignal timeSignal) {
+            resetCallTracking();
+            mLastSuggestedTime = timeSignal;
+        }
+
+        @Override
+        public void handleAutoTimeDetectionToggle(boolean enabled) {
+            resetCallTracking();
+            mLastAutoTimeDetectionToggle = enabled;
+        }
+
+        @Override
+        public void dump(PrintWriter pw, String[] args) {
+            resetCallTracking();
+            mDumpCalled = true;
+        }
+
+        void resetCallTracking() {
+            mLastSuggestedTime = null;
+            mLastAutoTimeDetectionToggle = null;
+            mDumpCalled = false;
+        }
+
+        void verifySuggestTimeCalled(TimeSignal expectedSignal) {
+            assertEquals(expectedSignal, mLastSuggestedTime);
+        }
+
+        void verifyHandleAutoTimeDetectionToggleCalled(boolean expectedEnable) {
+            assertNotNull(mLastAutoTimeDetectionToggle);
+            assertEquals(expectedEnable, mLastAutoTimeDetectionToggle);
+        }
+
+        void verifyDumpCalled() {
+            assertTrue(mDumpCalled);
+        }
+    }
 }
diff --git a/services/tests/servicestests/src/com/android/server/wm/DisplayContentTests.java b/services/tests/servicestests/src/com/android/server/wm/DisplayContentTests.java
index bb9b1c4..ec068db 100644
--- a/services/tests/servicestests/src/com/android/server/wm/DisplayContentTests.java
+++ b/services/tests/servicestests/src/com/android/server/wm/DisplayContentTests.java
@@ -413,6 +413,14 @@
         // Ensure the non-alwaysOnTop stack is put below the three alwaysOnTop stacks, but above the
         // existing other non-alwaysOnTop stacks.
         assertEquals(nonAlwaysOnTopStack, mDisplayContent.getStacks().get(topPosition - 3));
+
+        anotherAlwaysOnTopStack.setAlwaysOnTop(false);
+        mDisplayContent.positionStackAt(POSITION_TOP, anotherAlwaysOnTopStack);
+        assertFalse(anotherAlwaysOnTopStack.isAlwaysOnTop());
+        topPosition = mDisplayContent.getStacks().size() - 1;
+        // Ensure, when always on top is turned off for a stack, the stack is put just below all
+        // other always on top stacks.
+        assertEquals(anotherAlwaysOnTopStack, mDisplayContent.getStacks().get(topPosition - 2));
     }
 
     /**
diff --git a/services/tests/servicestests/src/com/android/server/wm/WindowContainerTests.java b/services/tests/servicestests/src/com/android/server/wm/WindowContainerTests.java
index 6c7830e..f8b2828 100644
--- a/services/tests/servicestests/src/com/android/server/wm/WindowContainerTests.java
+++ b/services/tests/servicestests/src/com/android/server/wm/WindowContainerTests.java
@@ -256,6 +256,33 @@
     }
 
     @Test
+    public void testAddChildByIndex() throws Exception {
+        final TestWindowContainerBuilder builder = new TestWindowContainerBuilder();
+        final TestWindowContainer root = builder.setLayer(0).build();
+
+        final TestWindowContainer child = root.addChildWindow();
+
+        final TestWindowContainer child2 = builder.setLayer(1).build();
+        final TestWindowContainer child3 = builder.setLayer(2).build();
+        final TestWindowContainer child4 = builder.setLayer(3).build();
+
+        // Test adding at top.
+        root.addChild(child2, POSITION_TOP);
+        assertEquals(child2, root.getChildAt(root.getChildrenCount() - 1));
+
+        // Test adding at bottom.
+        root.addChild(child3, POSITION_BOTTOM);
+        assertEquals(child3, root.getChildAt(0));
+
+        // Test adding in the middle.
+        root.addChild(child4, 1);
+        assertEquals(child3, root.getChildAt(0));
+        assertEquals(child4, root.getChildAt(1));
+        assertEquals(child, root.getChildAt(2));
+        assertEquals(child2, root.getChildAt(3));
+    }
+
+    @Test
     public void testPositionChildAt() throws Exception {
         final TestWindowContainerBuilder builder = new TestWindowContainerBuilder();
         final TestWindowContainer root = builder.setLayer(0).build();
diff --git a/telecomm/java/android/telecom/Connection.java b/telecomm/java/android/telecom/Connection.java
index 3bf951d..3e97c8f 100644
--- a/telecomm/java/android/telecom/Connection.java
+++ b/telecomm/java/android/telecom/Connection.java
@@ -45,6 +45,7 @@
 import java.io.IOException;
 import java.io.InputStreamReader;
 import java.io.OutputStreamWriter;
+import java.nio.channels.Channels;
 import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.Collections;
@@ -861,8 +862,11 @@
         public RttTextStream(ParcelFileDescriptor toInCall, ParcelFileDescriptor fromInCall) {
             mFdFromInCall = fromInCall;
             mFdToInCall = toInCall;
+
+            // Wrap the FileInputStream in a Channel so that it's interruptible.
             mPipeFromInCall = new InputStreamReader(
-                    new FileInputStream(fromInCall.getFileDescriptor()));
+                    Channels.newInputStream(Channels.newChannel(
+                            new FileInputStream(fromInCall.getFileDescriptor()))));
             mPipeToInCall = new OutputStreamWriter(
                     new FileOutputStream(toInCall.getFileDescriptor()));
         }
diff --git a/telephony/java/android/telephony/TelephonyManager.java b/telephony/java/android/telephony/TelephonyManager.java
index 102d5a0..6e261dd 100644
--- a/telephony/java/android/telephony/TelephonyManager.java
+++ b/telephony/java/android/telephony/TelephonyManager.java
@@ -2783,7 +2783,8 @@
     }
 
     /**
-     * Gets all the UICC slots.
+     * Gets all the UICC slots. The objects in the array can be null if the slot info is not
+     * available, which is possible between phone process starting and getting slot info from modem.
      *
      * @return UiccSlotInfo array.
      *
diff --git a/telephony/java/com/android/internal/telephony/CarrierAppUtils.java b/telephony/java/com/android/internal/telephony/CarrierAppUtils.java
index bcad554..a1bea4d 100644
--- a/telephony/java/com/android/internal/telephony/CarrierAppUtils.java
+++ b/telephony/java/com/android/internal/telephony/CarrierAppUtils.java
@@ -21,7 +21,6 @@
 import android.content.pm.ApplicationInfo;
 import android.content.pm.IPackageManager;
 import android.content.pm.PackageManager;
-import android.content.res.Resources;
 import android.os.RemoteException;
 import android.provider.Settings;
 import android.telephony.TelephonyManager;
@@ -145,6 +144,18 @@
                         telephonyManager.checkCarrierPrivilegesForPackageAnyPhone(packageName) ==
                                 TelephonyManager.CARRIER_PRIVILEGE_STATUS_HAS_ACCESS;
 
+                // add hiddenUntilInstalled flag for carrier apps and associated apps
+                packageManager.setSystemAppHiddenUntilInstalled(packageName, true);
+                List<ApplicationInfo> associatedAppList = associatedApps.get(packageName);
+                if (associatedAppList != null) {
+                    for (ApplicationInfo associatedApp : associatedAppList) {
+                        packageManager.setSystemAppHiddenUntilInstalled(
+                                associatedApp.packageName,
+                                true
+                        );
+                    }
+                }
+
                 if (hasPrivileges) {
                     // Only update enabled state for the app on /system. Once it has been
                     // updated we shouldn't touch it.
@@ -152,9 +163,14 @@
                             && (ai.enabledSetting ==
                             PackageManager.COMPONENT_ENABLED_STATE_DEFAULT
                             || ai.enabledSetting ==
-                            PackageManager.COMPONENT_ENABLED_STATE_DISABLED_UNTIL_USED)) {
+                            PackageManager.COMPONENT_ENABLED_STATE_DISABLED_UNTIL_USED
+                            || (ai.flags & ApplicationInfo.FLAG_INSTALLED) == 0)) {
                         Slog.i(TAG, "Update state(" + packageName + "): ENABLED for user "
                                 + userId);
+                        packageManager.setSystemAppInstallState(
+                                packageName,
+                                true /*installed*/,
+                                userId);
                         packageManager.setApplicationEnabledSetting(
                                 packageName,
                                 PackageManager.COMPONENT_ENABLED_STATE_ENABLED,
@@ -164,15 +180,20 @@
                     }
 
                     // Also enable any associated apps for this carrier app.
-                    List<ApplicationInfo> associatedAppList = associatedApps.get(packageName);
                     if (associatedAppList != null) {
                         for (ApplicationInfo associatedApp : associatedAppList) {
                             if (associatedApp.enabledSetting ==
                                     PackageManager.COMPONENT_ENABLED_STATE_DEFAULT
                                     || associatedApp.enabledSetting ==
-                                    PackageManager.COMPONENT_ENABLED_STATE_DISABLED_UNTIL_USED) {
+                                    PackageManager.COMPONENT_ENABLED_STATE_DISABLED_UNTIL_USED
+                                    || (associatedApp.flags
+                                    & ApplicationInfo.FLAG_INSTALLED) == 0) {
                                 Slog.i(TAG, "Update associated state(" + associatedApp.packageName
                                         + "): ENABLED for user " + userId);
+                                packageManager.setSystemAppInstallState(
+                                        associatedApp.packageName,
+                                        true /*installed*/,
+                                        userId);
                                 packageManager.setApplicationEnabledSetting(
                                         associatedApp.packageName,
                                         PackageManager.COMPONENT_ENABLED_STATE_ENABLED,
@@ -190,36 +211,33 @@
                     // updated we shouldn't touch it.
                     if (!ai.isUpdatedSystemApp()
                             && ai.enabledSetting ==
-                            PackageManager.COMPONENT_ENABLED_STATE_DEFAULT) {
+                            PackageManager.COMPONENT_ENABLED_STATE_DEFAULT
+                            && (ai.flags & ApplicationInfo.FLAG_INSTALLED) != 0) {
                         Slog.i(TAG, "Update state(" + packageName
                                 + "): DISABLED_UNTIL_USED for user " + userId);
-                        packageManager.setApplicationEnabledSetting(
+                        packageManager.setSystemAppInstallState(
                                 packageName,
-                                PackageManager.COMPONENT_ENABLED_STATE_DISABLED_UNTIL_USED,
-                                0,
-                                userId,
-                                callingPackage);
+                                false /*installed*/,
+                                userId);
                     }
 
                     // Also disable any associated apps for this carrier app if this is the first
                     // run. We avoid doing this a second time because it is brittle to rely on the
                     // distinction between "default" and "enabled".
                     if (!hasRunOnce) {
-                        List<ApplicationInfo> associatedAppList = associatedApps.get(packageName);
                         if (associatedAppList != null) {
                             for (ApplicationInfo associatedApp : associatedAppList) {
                                 if (associatedApp.enabledSetting
-                                        == PackageManager.COMPONENT_ENABLED_STATE_DEFAULT) {
+                                        == PackageManager.COMPONENT_ENABLED_STATE_DEFAULT
+                                        && (associatedApp.flags
+                                        & ApplicationInfo.FLAG_INSTALLED) != 0) {
                                     Slog.i(TAG,
                                             "Update associated state(" + associatedApp.packageName
                                                     + "): DISABLED_UNTIL_USED for user " + userId);
-                                    packageManager.setApplicationEnabledSetting(
+                                    packageManager.setSystemAppInstallState(
                                             associatedApp.packageName,
-                                            PackageManager
-                                                    .COMPONENT_ENABLED_STATE_DISABLED_UNTIL_USED,
-                                            0,
-                                            userId,
-                                            callingPackage);
+                                            false /*installed*/,
+                                            userId);
                                 }
                             }
                         }
@@ -357,7 +375,8 @@
             String packageName) {
         try {
             ApplicationInfo ai = packageManager.getApplicationInfo(packageName,
-                    PackageManager.MATCH_DISABLED_UNTIL_USED_COMPONENTS, userId);
+                    PackageManager.MATCH_DISABLED_UNTIL_USED_COMPONENTS
+                    | PackageManager.MATCH_HIDDEN_UNTIL_INSTALLED_COMPONENTS, userId);
             if (ai != null && ai.isSystemApp()) {
                 return ai;
             }
diff --git a/tools/incident_section_gen/main.cpp b/tools/incident_section_gen/main.cpp
index 1f77719..639f980 100644
--- a/tools/incident_section_gen/main.cpp
+++ b/tools/incident_section_gen/main.cpp
@@ -110,9 +110,7 @@
     N = descriptor->field_count();
     for (int i=0; i<N; i++) {
         const FieldDescriptor* field = descriptor->field(i);
-        if (field->type() == FieldDescriptor::TYPE_MESSAGE) {
-            sections[field->name()] = field;
-        }
+        sections[field->name()] = field;
     }
 
     printf("IncidentSection const INCIDENT_SECTIONS[] = {\n");
@@ -404,7 +402,7 @@
     for (int i=0; i<descriptor->field_count(); i++) {
         const FieldDescriptor* field = descriptor->field(i);
 
-        if (field->type() != FieldDescriptor::TYPE_MESSAGE) {
+        if (field->type() != FieldDescriptor::TYPE_MESSAGE && field->type() != FieldDescriptor::TYPE_STRING) {
             continue;
         }
         const SectionFlags s = getSectionFlags(field);
@@ -456,13 +454,13 @@
         const FieldDescriptor* field = fieldsInOrder[i];
         const string fieldName = getFieldName(field);
         const Destination fieldDest = getFieldDest(field);
-        const string fieldMessageName = getMessageName(field->message_type(), fieldDest);
-
-        skip[i] = true;
-
         if (field->type() != FieldDescriptor::TYPE_MESSAGE) {
+            printPrivacy(fieldName, field, "NULL", fieldDest, "NULL");
             continue;
         }
+
+        skip[i] = true;
+        const string fieldMessageName = getMessageName(field->message_type(), fieldDest);
         // generate privacy flags for each section.
         if (generatePrivacyFlags(field->message_type(), fieldDest, variableNames, &parents)) {
             printPrivacy(fieldName, field, fieldMessageName, fieldDest, "NULL");