Merge "Make silent notifications header font theme-aware" into qt-dev
diff --git a/api/test-current.txt b/api/test-current.txt
index 1a912a1c..be92106 100644
--- a/api/test-current.txt
+++ b/api/test-current.txt
@@ -646,6 +646,7 @@
     method public void setContentCaptureOptions(@Nullable android.content.ContentCaptureOptions);
     field public static final String BUGREPORT_SERVICE = "bugreport";
     field public static final String CONTENT_CAPTURE_MANAGER_SERVICE = "content_capture";
+    field public static final String PERMISSION_SERVICE = "permission";
     field public static final String ROLLBACK_SERVICE = "rollback";
     field public static final String STATUS_BAR_SERVICE = "statusbar";
     field public static final String TEST_NETWORK_SERVICE = "test_network";
@@ -2214,6 +2215,18 @@
     method public abstract void onRevokeRuntimePermissions(@NonNull java.util.Map<java.lang.String,java.util.List<java.lang.String>>);
   }
 
+  public final class PermissionManager {
+    method @IntRange(from=0) @RequiresPermission("android.permission.ADJUST_RUNTIME_PERMISSIONS_POLICY") public int getRuntimePermissionsVersion();
+    method @NonNull public java.util.List<android.permission.PermissionManager.SplitPermissionInfo> getSplitPermissions();
+    method @RequiresPermission("android.permission.ADJUST_RUNTIME_PERMISSIONS_POLICY") public void setRuntimePermissionsVersion(@IntRange(from=0) int);
+  }
+
+  public static final class PermissionManager.SplitPermissionInfo {
+    method @NonNull public java.util.List<java.lang.String> getNewPermissions();
+    method @NonNull public String getSplitPermission();
+    method public int getTargetSdk();
+  }
+
   public final class RuntimePermissionPresentationInfo implements android.os.Parcelable {
     ctor public RuntimePermissionPresentationInfo(@NonNull CharSequence, boolean, boolean);
     method public int describeContents();
diff --git a/cmds/idmap2/idmap2/Scan.cpp b/cmds/idmap2/idmap2/Scan.cpp
index 83c034b..cfac5f3 100644
--- a/cmds/idmap2/idmap2/Scan.cpp
+++ b/cmds/idmap2/idmap2/Scan.cpp
@@ -68,9 +68,13 @@
 };
 
 bool VendorIsQOrLater() {
-  // STOPSHIP(b/119390857): Check api version once Q sdk version is finalized
-  std::string version = android::base::GetProperty("ro.vndk.version", "Q");
-  return version == "Q" || version == "q";
+  constexpr int kQSdkVersion = 29;
+  constexpr int kBase = 10;
+  std::string version_prop = android::base::GetProperty("ro.vndk.version", "29");
+  int version = strtol(version_prop.data(), nullptr, kBase);
+
+  // If the string cannot be parsed, it is a development sdk codename.
+  return version >= kQSdkVersion || version == 0;
 }
 
 Result<std::unique_ptr<std::vector<std::string>>> FindApkFiles(const std::vector<std::string>& dirs,
diff --git a/cmds/incident_helper/src/main.cpp b/cmds/incident_helper/src/main.cpp
index 809a771..ff5fd86 100644
--- a/cmds/incident_helper/src/main.cpp
+++ b/cmds/incident_helper/src/main.cpp
@@ -72,6 +72,8 @@
             return new PsParser();
         case 2006:
             return new BatteryTypeParser();
+        case 3026: // system_trace is already a serialized protobuf
+            return new NoopParser();
         default:
             // 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 a8b99ce..a527263 100644
--- a/cmds/incidentd/src/IncidentService.cpp
+++ b/cmds/incidentd/src/IncidentService.cpp
@@ -564,7 +564,8 @@
     int skipped[] = SKIPPED_SECTIONS;
     for (const Section** section = SECTION_LIST; *section; section++) {
         const int id = (*section)->id;
-        if (std::find(std::begin(skipped), std::end(skipped), id) == std::end(skipped)) {
+        if (std::find(std::begin(skipped), std::end(skipped), id) == std::end(skipped)
+                && !section_requires_specific_mention(id)) {
             incidentArgs.addSection(id);
         }
     }
diff --git a/cmds/incidentd/src/Section.cpp b/cmds/incidentd/src/Section.cpp
index 85c5a20..1572114 100644
--- a/cmds/incidentd/src/Section.cpp
+++ b/cmds/incidentd/src/Section.cpp
@@ -67,6 +67,8 @@
     switch (sectionId) {
         case 3025: // restricted_images
             return true;
+        case 3026: // system_trace
+            return true;
         default:
             return false;
     }
diff --git a/cmds/statsd/Android.bp b/cmds/statsd/Android.bp
index d59d0e2..6bedfcd 100644
--- a/cmds/statsd/Android.bp
+++ b/cmds/statsd/Android.bp
@@ -263,6 +263,7 @@
         "tests/e2e/Anomaly_duration_sum_e2e_test.cpp",
         "tests/e2e/ConfigTtl_e2e_test.cpp",
         "tests/e2e/PartialBucket_e2e_test.cpp",
+        "tests/e2e/DurationMetric_e2e_test.cpp",
         "tests/shell/ShellSubscriber_test.cpp",
     ],
 
diff --git a/cmds/statsd/src/StatsLogProcessor.h b/cmds/statsd/src/StatsLogProcessor.h
index 92aa425..f0db1b0 100644
--- a/cmds/statsd/src/StatsLogProcessor.h
+++ b/cmds/statsd/src/StatsLogProcessor.h
@@ -272,7 +272,15 @@
     FRIEND_TEST(MetricActivationE2eTest, TestCountMetric);
     FRIEND_TEST(MetricActivationE2eTest, TestCountMetricWithOneDeactivation);
     FRIEND_TEST(MetricActivationE2eTest, TestCountMetricWithTwoDeactivations);
+    FRIEND_TEST(MetricActivationE2eTest, TestCountMetricWithSameDeactivation);
     FRIEND_TEST(MetricActivationE2eTest, TestCountMetricWithTwoMetricsTwoDeactivations);
+
+    FRIEND_TEST(DurationMetricE2eTest, TestOneBucket);
+    FRIEND_TEST(DurationMetricE2eTest, TestTwoBuckets);
+    FRIEND_TEST(DurationMetricE2eTest, TestWithActivation);
+    FRIEND_TEST(DurationMetricE2eTest, TestWithCondition);
+    FRIEND_TEST(DurationMetricE2eTest, TestWithSlicedCondition);
+    FRIEND_TEST(DurationMetricE2eTest, TestWithActivationAndSlicedCondition);
 };
 
 }  // namespace statsd
diff --git a/cmds/statsd/src/atoms.proto b/cmds/statsd/src/atoms.proto
index 495a09f..e920843 100644
--- a/cmds/statsd/src/atoms.proto
+++ b/cmds/statsd/src/atoms.proto
@@ -303,6 +303,8 @@
         ContentCaptureSessionEvents content_capture_session_events = 208;
         ContentCaptureFlushed content_capture_flushed = 209;
         LocationManagerApiUsageReported location_manager_api_usage_reported = 210;
+        ReviewPermissionsFragmentResultReported review_permissions_fragment_result_reported
+            = 211 [(log_from_module) = "permissioncontroller"];
     }
 
     // Pulled events will start at field 10000.
@@ -6544,3 +6546,24 @@
     // Categorized to 3 types that are interesting from location's perspective.
     optional android.stats.location.ActivityImportance activiy_importance = 12;
 }
+
+/**
+ * Information about a permission grant or denial made by user inside ReviewPermissionsFragment
+ */
+message ReviewPermissionsFragmentResultReported {
+    // unique value identifying a permission group change. A permission group change might result
+    // in multiple of these atoms
+    optional int64 change_id = 1;
+
+    // UID of package the permission belongs to
+    optional int32 uid = 2 [(is_uid) = true];
+
+    // Name of package the permission belongs to
+    optional string package_name = 3;
+
+    // The permission to be granted
+    optional string permission_name = 4;
+
+    // The result of the permission grant
+    optional bool permission_granted = 5;
+}
diff --git a/cmds/statsd/src/guardrail/StatsdStats.h b/cmds/statsd/src/guardrail/StatsdStats.h
index 8b39f5f..42d9e96 100644
--- a/cmds/statsd/src/guardrail/StatsdStats.h
+++ b/cmds/statsd/src/guardrail/StatsdStats.h
@@ -170,6 +170,12 @@
     // Vendor pulled atom start id.
     static const int32_t kVendorPulledAtomStartTag = 150000;
 
+    // Beginning of range for timestamp truncation.
+    static const int32_t kTimestampTruncationStartTag = 300000;
+
+    // End of range for timestamp truncation.
+    static const int32_t kTimestampTruncationEndTag = 304999;
+
     // Max accepted atom id.
     static const int32_t kMaxAtomTag = 200000;
 
diff --git a/cmds/statsd/src/metrics/DurationMetricProducer.cpp b/cmds/statsd/src/metrics/DurationMetricProducer.cpp
index 615c7f2..96fbf7f 100644
--- a/cmds/statsd/src/metrics/DurationMetricProducer.cpp
+++ b/cmds/statsd/src/metrics/DurationMetricProducer.cpp
@@ -220,7 +220,7 @@
                     trueConditionDimensions.end()) {
                 for (auto& condIt : whatIt.second) {
                     condIt.second->onConditionChanged(
-                        currentUnSlicedPartCondition, eventTime);
+                            currentUnSlicedPartCondition, eventTime);
                 }
             }
         }
@@ -314,7 +314,7 @@
                 auto condIt = whatIt.second.find(trueDim);
                 if (condIt != whatIt.second.end()) {
                     condIt->second->onConditionChanged(
-                        currentUnSlicedPartCondition, eventTime);
+                            currentUnSlicedPartCondition, eventTime);
                 } else {
                     if (mMetric2ConditionLinks.size() == 0 ||
                         trueDim.contains(linkedConditionDimensionKey)) {
@@ -338,32 +338,25 @@
     }
 }
 
-void DurationMetricProducer::onSlicedConditionMayChangeLocked(bool overallCondition,
-                                                              const int64_t eventTime) {
-    VLOG("Metric %lld onSlicedConditionMayChange", (long long)mMetricId);
-    flushIfNeededLocked(eventTime);
-
-    if (!mConditionSliced) {
-        return;
-    }
-
+void DurationMetricProducer::onSlicedConditionMayChangeInternalLocked(bool overallCondition,
+        const int64_t eventTimeNs) {
     bool changeDimTrackable = mWizard->IsChangedDimensionTrackable(mConditionTrackerIndex);
     if (changeDimTrackable && mHasLinksToAllConditionDimensionsInTracker &&
         mDimensionsInCondition.empty()) {
-        onSlicedConditionMayChangeLocked_opt1(overallCondition, eventTime);
+        onSlicedConditionMayChangeLocked_opt1(overallCondition, eventTimeNs);
         return;
     }
 
     if (changeDimTrackable && mSameConditionDimensionsInTracker &&
         mMetric2ConditionLinks.size() <= 1) {
-        onSlicedConditionMayChangeLocked_opt2(overallCondition, eventTime);
+        onSlicedConditionMayChangeLocked_opt2(overallCondition, eventTimeNs);
         return;
     }
 
     // Now for each of the on-going event, check if the condition has changed for them.
     for (auto& whatIt : mCurrentSlicedDurationTrackerMap) {
         for (auto& pair : whatIt.second) {
-            pair.second->onSlicedConditionMayChange(overallCondition, eventTime);
+            pair.second->onSlicedConditionMayChange(overallCondition, eventTimeNs);
         }
     }
 
@@ -389,10 +382,10 @@
                         continue;
                     }
                     unique_ptr<DurationTracker> newTracker =
-                        whatIt.second.begin()->second->clone(eventTime);
+                        whatIt.second.begin()->second->clone(eventTimeNs);
                     if (newTracker != nullptr) {
                         newTracker->setEventKey(MetricDimensionKey(newEventKey));
-                        newTracker->onSlicedConditionMayChange(overallCondition, eventTime);
+                        newTracker->onSlicedConditionMayChange(overallCondition, eventTimeNs);
                         whatIt.second[conditionDimension] = std::move(newTracker);
                     }
                 }
@@ -418,10 +411,10 @@
                     if (hitGuardRailLocked(newEventKey)) {
                         continue;
                     }
-                    auto newTracker = whatIt.second.begin()->second->clone(eventTime);
+                    auto newTracker = whatIt.second.begin()->second->clone(eventTimeNs);
                     if (newTracker != nullptr) {
                         newTracker->setEventKey(newEventKey);
-                        newTracker->onSlicedConditionMayChange(overallCondition, eventTime);
+                        newTracker->onSlicedConditionMayChange(overallCondition, eventTimeNs);
                         whatIt.second[conditionDimension] = std::move(newTracker);
                     }
                 }
@@ -430,10 +423,61 @@
     }
 }
 
+void DurationMetricProducer::onSlicedConditionMayChangeLocked(bool overallCondition,
+                                                              const int64_t eventTime) {
+    VLOG("Metric %lld onSlicedConditionMayChange", (long long)mMetricId);
+
+    if (!mIsActive) {
+        return;
+    }
+
+    flushIfNeededLocked(eventTime);
+
+    if (!mConditionSliced) {
+        return;
+    }
+
+    onSlicedConditionMayChangeInternalLocked(overallCondition, eventTime);
+}
+
+void DurationMetricProducer::onActiveStateChangedLocked(const int64_t& eventTimeNs) {
+    MetricProducer::onActiveStateChangedLocked(eventTimeNs);
+
+    if (!mConditionSliced) {
+        if (ConditionState::kTrue != mCondition) {
+            return;
+        }
+
+        if (mIsActive) {
+            flushIfNeededLocked(eventTimeNs);
+        }
+
+        for (auto& whatIt : mCurrentSlicedDurationTrackerMap) {
+            for (auto& pair : whatIt.second) {
+                pair.second->onConditionChanged(mIsActive, eventTimeNs);
+            }
+        }
+    } else if (mIsActive) {
+        flushIfNeededLocked(eventTimeNs);
+        onSlicedConditionMayChangeInternalLocked(mIsActive, eventTimeNs);
+    } else { // mConditionSliced == true && !mIsActive
+        for (auto& whatIt : mCurrentSlicedDurationTrackerMap) {
+            for (auto& pair : whatIt.second) {
+                pair.second->onConditionChanged(mIsActive, eventTimeNs);
+            }
+        }
+    }
+}
+
 void DurationMetricProducer::onConditionChangedLocked(const bool conditionMet,
                                                       const int64_t eventTime) {
     VLOG("Metric %lld onConditionChanged", (long long)mMetricId);
     mCondition = conditionMet ? ConditionState::kTrue : ConditionState::kFalse;
+
+    if (!mIsActive) {
+        return;
+    }
+
     flushIfNeededLocked(eventTime);
     for (auto& whatIt : mCurrentSlicedDurationTrackerMap) {
         for (auto& pair : whatIt.second) {
@@ -696,7 +740,9 @@
         return;
     }
 
-    flushIfNeededLocked(event.GetElapsedTimestampNs());
+    if (mIsActive) {
+        flushIfNeededLocked(event.GetElapsedTimestampNs());
+    }
 
     // Handles Stopall events.
     if (matcherIndex == mStopAllIndex) {
@@ -767,6 +813,8 @@
         }
     }
 
+    condition = condition && mIsActive;
+
     if (dimensionKeysInCondition.empty()) {
         handleStartEvent(MetricDimensionKey(dimensionInWhat, DEFAULT_DIMENSION_KEY),
                          conditionKey, condition, event);
diff --git a/cmds/statsd/src/metrics/DurationMetricProducer.h b/cmds/statsd/src/metrics/DurationMetricProducer.h
index f711df2..56c9fd6 100644
--- a/cmds/statsd/src/metrics/DurationMetricProducer.h
+++ b/cmds/statsd/src/metrics/DurationMetricProducer.h
@@ -73,9 +73,15 @@
     // Internal interface to handle condition change.
     void onConditionChangedLocked(const bool conditionMet, const int64_t eventTime) override;
 
+    // Internal interface to handle active state change.
+    void onActiveStateChangedLocked(const int64_t& eventTimeNs) override;
+
     // Internal interface to handle sliced condition change.
     void onSlicedConditionMayChangeLocked(bool overallCondition, const int64_t eventTime) override;
 
+    void onSlicedConditionMayChangeInternalLocked(bool overallCondition,
+                                                  const int64_t eventTimeNs);
+
     void onSlicedConditionMayChangeLocked_opt1(bool overallCondition, const int64_t eventTime);
     void onSlicedConditionMayChangeLocked_opt2(bool overallCondition, const int64_t eventTime);
 
diff --git a/cmds/statsd/src/metrics/EventMetricProducer.cpp b/cmds/statsd/src/metrics/EventMetricProducer.cpp
index 69816cb..96133bd 100644
--- a/cmds/statsd/src/metrics/EventMetricProducer.cpp
+++ b/cmds/statsd/src/metrics/EventMetricProducer.cpp
@@ -146,16 +146,9 @@
 
     uint64_t wrapperToken =
             mProto->start(FIELD_TYPE_MESSAGE | FIELD_COUNT_REPEATED | FIELD_ID_DATA);
-    const bool truncateTimestamp =
-            android::util::AtomsInfo::kNotTruncatingTimestampAtomWhiteList.find(event.GetTagId()) ==
-            android::util::AtomsInfo::kNotTruncatingTimestampAtomWhiteList.end();
-    if (truncateTimestamp) {
-        mProto->write(FIELD_TYPE_INT64 | FIELD_ID_ELAPSED_TIMESTAMP_NANOS,
-            (long long)truncateTimestampNsToFiveMinutes(event.GetElapsedTimestampNs()));
-    } else {
-        mProto->write(FIELD_TYPE_INT64 | FIELD_ID_ELAPSED_TIMESTAMP_NANOS,
-            (long long)event.GetElapsedTimestampNs());
-    }
+    const int64_t elapsedTimeNs = truncateTimestampIfNecessary(
+            event.GetTagId(), event.GetElapsedTimestampNs());
+    mProto->write(FIELD_TYPE_INT64 | FIELD_ID_ELAPSED_TIMESTAMP_NANOS, (long long) elapsedTimeNs);
 
     uint64_t eventToken = mProto->start(FIELD_TYPE_MESSAGE | FIELD_ID_ATOMS);
     event.ToProto(*mProto);
diff --git a/cmds/statsd/src/metrics/GaugeMetricProducer.cpp b/cmds/statsd/src/metrics/GaugeMetricProducer.cpp
index 41000da..a64bbc1 100644
--- a/cmds/statsd/src/metrics/GaugeMetricProducer.cpp
+++ b/cmds/statsd/src/metrics/GaugeMetricProducer.cpp
@@ -283,14 +283,9 @@
                     writeFieldValueTreeToStream(mAtomId, *(atom.mFields), protoOutput);
                     protoOutput->end(atomsToken);
                 }
-                const bool truncateTimestamp =
-                        android::util::AtomsInfo::kNotTruncatingTimestampAtomWhiteList.find(
-                                mAtomId) ==
-                        android::util::AtomsInfo::kNotTruncatingTimestampAtomWhiteList.end();
                 for (const auto& atom : bucket.mGaugeAtoms) {
-                    const int64_t elapsedTimestampNs =  truncateTimestamp ?
-                        truncateTimestampNsToFiveMinutes(atom.mElapsedTimestamps) :
-                            atom.mElapsedTimestamps;
+                    const int64_t elapsedTimestampNs =
+                            truncateTimestampIfNecessary(mAtomId, atom.mElapsedTimestamps);
                     protoOutput->write(
                         FIELD_TYPE_INT64 | FIELD_COUNT_REPEATED | FIELD_ID_ELAPSED_ATOM_TIMESTAMP,
                         (long long)elapsedTimestampNs);
@@ -364,11 +359,27 @@
     }
 }
 
+void GaugeMetricProducer::onActiveStateChangedLocked(const int64_t& eventTimeNs) {
+    MetricProducer::onActiveStateChangedLocked(eventTimeNs);
+    if (ConditionState::kTrue != mCondition || !mIsPulled) {
+        return;
+    }
+    if (mTriggerAtomId == -1 || (mIsActive && mSamplingType == GaugeMetric::RANDOM_ONE_SAMPLE)) {
+        pullAndMatchEventsLocked(eventTimeNs);
+    }
+
+}
+
 void GaugeMetricProducer::onConditionChangedLocked(const bool conditionMet,
                                                    const int64_t eventTimeNs) {
     VLOG("GaugeMetric %lld onConditionChanged", (long long)mMetricId);
-    flushIfNeededLocked(eventTimeNs);
+
     mCondition = conditionMet ? ConditionState::kTrue : ConditionState::kFalse;
+    if (!mIsActive) {
+        return;
+    }
+
+    flushIfNeededLocked(eventTimeNs);
     if (mIsPulled && mTriggerAtomId == -1) {
         pullAndMatchEventsLocked(eventTimeNs);
     }  // else: Push mode. No need to proactively pull the gauge data.
@@ -378,10 +389,14 @@
                                                            const int64_t eventTimeNs) {
     VLOG("GaugeMetric %lld onSlicedConditionMayChange overall condition %d", (long long)mMetricId,
          overallCondition);
+    mCondition = overallCondition ? ConditionState::kTrue : ConditionState::kFalse;
+    if (!mIsActive) {
+        return;
+    }
+
     flushIfNeededLocked(eventTimeNs);
     // If the condition is sliced, mCondition is true if any of the dimensions is true. And we will
     // pull for every dimension.
-    mCondition = overallCondition ? ConditionState::kTrue : ConditionState::kFalse;
     if (mIsPulled && mTriggerAtomId == -1) {
         pullAndMatchEventsLocked(eventTimeNs);
     }  // else: Push mode. No need to proactively pull the gauge data.
diff --git a/cmds/statsd/src/metrics/GaugeMetricProducer.h b/cmds/statsd/src/metrics/GaugeMetricProducer.h
index 1b43d43..a612adf 100644
--- a/cmds/statsd/src/metrics/GaugeMetricProducer.h
+++ b/cmds/statsd/src/metrics/GaugeMetricProducer.h
@@ -106,6 +106,9 @@
     // Internal interface to handle condition change.
     void onConditionChangedLocked(const bool conditionMet, const int64_t eventTime) override;
 
+    // Internal interface to handle active state change.
+    void onActiveStateChangedLocked(const int64_t& eventTimeNs) override;
+
     // Internal interface to handle sliced condition change.
     void onSlicedConditionMayChangeLocked(bool overallCondition, const int64_t eventTime) override;
 
diff --git a/cmds/statsd/src/metrics/MetricProducer.cpp b/cmds/statsd/src/metrics/MetricProducer.cpp
index d913427..92752b2 100644
--- a/cmds/statsd/src/metrics/MetricProducer.cpp
+++ b/cmds/statsd/src/metrics/MetricProducer.cpp
@@ -107,7 +107,7 @@
     }
     mIsActive = evaluateActiveStateLocked(elapsedTimestampNs);
     if (!mIsActive) {
-        flushLocked(elapsedTimestampNs);
+        onActiveStateChangedLocked(elapsedTimestampNs);
     }
 }
 
@@ -124,7 +124,8 @@
             std::make_shared<Activation>(activationType, ttl_seconds * NS_PER_SEC);
     mEventActivationMap.emplace(activationTrackerIndex, activation);
     if (-1 != deactivationTrackerIndex) {
-        mEventDeactivationMap.emplace(deactivationTrackerIndex, activation);
+        auto& deactivationList = mEventDeactivationMap[deactivationTrackerIndex];
+        deactivationList.push_back(activation);
     }
 }
 
@@ -143,7 +144,11 @@
     }
     activation->start_ns = elapsedTimestampNs;
     activation->state = ActivationState::kActive;
+    bool oldActiveState = mIsActive;
     mIsActive = true;
+    if (!oldActiveState) { // Metric went from not active to active.
+        onActiveStateChangedLocked(elapsedTimestampNs);
+    }
 }
 
 void MetricProducer::cancelEventActivationLocked(int deactivationTrackerIndex) {
@@ -151,7 +156,9 @@
     if (it == mEventDeactivationMap.end()) {
         return;
     }
-    it->second->state = ActivationState::kNotActive;
+    for (auto activationToCancelIt : it->second)  {
+        activationToCancelIt->state = ActivationState::kNotActive;
+    }
 }
 
 void MetricProducer::loadActiveMetricLocked(const ActiveMetric& activeMetric,
@@ -167,7 +174,9 @@
             continue;
         }
         auto& activation = it->second;
-        if (activeEventActivation.state() == ActiveEventActivation::ACTIVE) {
+        // If the event activation does not have a state, assume it is active.
+        if (!activeEventActivation.has_state() ||
+                activeEventActivation.state() == ActiveEventActivation::ACTIVE) {
             // We don't want to change the ttl for future activations, so we set the start_ns
             // such that start_ns + ttl_ns == currentTimeNs + remaining_ttl_nanos
             activation->start_ns =
diff --git a/cmds/statsd/src/metrics/MetricProducer.h b/cmds/statsd/src/metrics/MetricProducer.h
index 3ddbef4..09ad290 100644
--- a/cmds/statsd/src/metrics/MetricProducer.h
+++ b/cmds/statsd/src/metrics/MetricProducer.h
@@ -132,23 +132,17 @@
     // Consume the parsed stats log entry that already matched the "what" of the metric.
     void onMatchedLogEvent(const size_t matcherIndex, const LogEvent& event) {
         std::lock_guard<std::mutex> lock(mMutex);
-        if (mIsActive) {
-            onMatchedLogEventLocked(matcherIndex, event);
-        }
+        onMatchedLogEventLocked(matcherIndex, event);
     }
 
     void onConditionChanged(const bool condition, const int64_t eventTime) {
         std::lock_guard<std::mutex> lock(mMutex);
-        if (mIsActive) {
-            onConditionChangedLocked(condition, eventTime);
-        }
+        onConditionChangedLocked(condition, eventTime);
     }
 
     void onSlicedConditionMayChange(bool overallCondition, const int64_t eventTime) {
         std::lock_guard<std::mutex> lock(mMutex);
-        if (mIsActive) {
-            onSlicedConditionMayChangeLocked(overallCondition, eventTime);
-        }
+        onSlicedConditionMayChangeLocked(overallCondition, eventTime);
     }
 
     bool isConditionSliced() const {
@@ -304,12 +298,18 @@
      * bucket's end timestamp, than we flush up to the end of the latest full bucket; otherwise,
      * we assume that we want to flush a partial bucket. The bucket start timestamp and bucket
      * number are not changed by this function. This method should only be called by
-     * flushIfNeededLocked or the app upgrade handler; the caller MUST update the bucket timestamp
-     * and bucket number as needed.
+     * flushIfNeededLocked or flushLocked or the app upgrade handler; the caller MUST update the
+     * bucket timestamp and bucket number as needed.
      */
     virtual void flushCurrentBucketLocked(const int64_t& eventTimeNs,
                                           const int64_t& nextBucketStartTimeNs) {};
 
+    virtual void onActiveStateChangedLocked(const int64_t& eventTimeNs) {
+        if (!mIsActive) {
+            flushLocked(eventTimeNs);
+        }
+    }
+
     // Convenience to compute the current bucket's end time, which is always aligned with the
     // start time of the metric.
     int64_t getCurrentBucketEndTimeNs() const {
@@ -407,14 +407,22 @@
     // whether the metric producer is ready to generate metrics.
     std::unordered_map<int, std::shared_ptr<Activation>> mEventActivationMap;
 
-    // Maps index of atom matcher for deactivation to Activation struct.
-    std::unordered_map<int, std::shared_ptr<Activation>> mEventDeactivationMap;
+    // Maps index of atom matcher for deactivation to a list of Activation structs.
+    std::unordered_map<int, std::vector<std::shared_ptr<Activation>>> mEventDeactivationMap;
 
     bool mIsActive;
 
+    FRIEND_TEST(DurationMetricE2eTest, TestOneBucket);
+    FRIEND_TEST(DurationMetricE2eTest, TestTwoBuckets);
+    FRIEND_TEST(DurationMetricE2eTest, TestWithActivation);
+    FRIEND_TEST(DurationMetricE2eTest, TestWithCondition);
+    FRIEND_TEST(DurationMetricE2eTest, TestWithSlicedCondition);
+    FRIEND_TEST(DurationMetricE2eTest, TestWithActivationAndSlicedCondition);
+
     FRIEND_TEST(MetricActivationE2eTest, TestCountMetric);
     FRIEND_TEST(MetricActivationE2eTest, TestCountMetricWithOneDeactivation);
     FRIEND_TEST(MetricActivationE2eTest, TestCountMetricWithTwoDeactivations);
+    FRIEND_TEST(MetricActivationE2eTest, TestCountMetricWithSameDeactivation);
     FRIEND_TEST(MetricActivationE2eTest, TestCountMetricWithTwoMetricsTwoDeactivations);
 
     FRIEND_TEST(StatsLogProcessorTest, TestActiveConfigMetricDiskWriteRead);
diff --git a/cmds/statsd/src/metrics/MetricsManager.h b/cmds/statsd/src/metrics/MetricsManager.h
index da3be06..8efca1e 100644
--- a/cmds/statsd/src/metrics/MetricsManager.h
+++ b/cmds/statsd/src/metrics/MetricsManager.h
@@ -283,6 +283,7 @@
     FRIEND_TEST(MetricActivationE2eTest, TestCountMetric);
     FRIEND_TEST(MetricActivationE2eTest, TestCountMetricWithOneDeactivation);
     FRIEND_TEST(MetricActivationE2eTest, TestCountMetricWithTwoDeactivations);
+    FRIEND_TEST(MetricActivationE2eTest, TestCountMetricWithSameDeactivation);
     FRIEND_TEST(MetricActivationE2eTest, TestCountMetricWithTwoMetricsTwoDeactivations);
 
     FRIEND_TEST(StatsLogProcessorTest, TestActiveConfigMetricDiskWriteRead);
@@ -291,6 +292,13 @@
     FRIEND_TEST(StatsLogProcessorTest,
             TestActivationOnBootMultipleActivationsDifferentActivationTypes);
     FRIEND_TEST(StatsLogProcessorTest, TestActivationsPersistAcrossSystemServerRestart);
+
+    FRIEND_TEST(DurationMetricE2eTest, TestOneBucket);
+    FRIEND_TEST(DurationMetricE2eTest, TestTwoBuckets);
+    FRIEND_TEST(DurationMetricE2eTest, TestWithActivation);
+    FRIEND_TEST(DurationMetricE2eTest, TestWithCondition);
+    FRIEND_TEST(DurationMetricE2eTest, TestWithSlicedCondition);
+    FRIEND_TEST(DurationMetricE2eTest, TestWithActivationAndSlicedCondition);
 };
 
 }  // namespace statsd
diff --git a/cmds/statsd/src/metrics/ValueMetricProducer.cpp b/cmds/statsd/src/metrics/ValueMetricProducer.cpp
index 17f2994..0e33a0f 100644
--- a/cmds/statsd/src/metrics/ValueMetricProducer.cpp
+++ b/cmds/statsd/src/metrics/ValueMetricProducer.cpp
@@ -109,7 +109,8 @@
       mMaxPullDelayNs(metric.max_pull_delay_sec() > 0 ? metric.max_pull_delay_sec() * NS_PER_SEC
                                                       : StatsdStats::kPullMaxDelayNs),
       mSplitBucketForAppUpgrade(metric.split_bucket_for_app_upgrade()),
-      mConditionTimer(mCondition == ConditionState::kTrue, timeBaseNs) {
+      // Condition timer will be set in prepareFirstBucketLocked.
+      mConditionTimer(false, timeBaseNs) {
     int64_t bucketSizeMills = 0;
     if (metric.has_bucket()) {
         bucketSizeMills = TimeUnitToBucketSizeInMillisGuardrailed(key.GetUid(), metric.bucket());
@@ -175,6 +176,9 @@
     if (mIsActive && mIsPulled && mCondition == ConditionState::kTrue && mUseDiff) {
         pullAndMatchEventsLocked(mCurrentBucketStartTimeNs, mCondition);
     }
+    // Now that activations are processed, start the condition timer if needed.
+    mConditionTimer.onConditionChanged(mIsActive && mCondition == ConditionState::kTrue,
+                                       mCurrentBucketStartTimeNs);
 }
 
 void ValueMetricProducer::onSlicedConditionMayChangeLocked(bool overallCondition,
@@ -364,58 +368,98 @@
     mHasGlobalBase = false;
 }
 
-void ValueMetricProducer::onConditionChangedLocked(const bool condition,
-                                                   const int64_t eventTimeNs) {
+// Handle active state change. Active state change is treated like a condition change:
+// - drop bucket if active state change event arrives too late
+// - if condition is true, pull data on active state changes
+// - ConditionTimer tracks changes based on AND of condition and active state.
+void ValueMetricProducer::onActiveStateChangedLocked(const int64_t& eventTimeNs) {
     bool isEventTooLate  = eventTimeNs < mCurrentBucketStartTimeNs;
-    if (!isEventTooLate) {
-        if (mCondition == ConditionState::kUnknown) {
-            // If the condition was unknown, we mark the bucket as invalid since the bucket will
-            // contain partial data. For instance, the condition change might happen close to the
-            // end of the bucket and we might miss lots of data.
-            //
-            // We still want to pull to set the base.
-            invalidateCurrentBucket();
-        }
-
-        // Pull on condition changes.
-        ConditionState newCondition = condition ? ConditionState::kTrue : ConditionState::kFalse;
-        bool conditionChanged =
-                (mCondition == ConditionState::kTrue && newCondition == ConditionState::kFalse)
-                || (mCondition == ConditionState::kFalse && newCondition == ConditionState::kTrue);
-        // We do not need to pull when we go from unknown to false.
-        //
-        // We also pull if the condition was already true in order to be able to flush the bucket at
-        // the end if needed.
-        //
-        // onConditionChangedLocked might happen on bucket boundaries if this is called before
-        // #onDataPulled.
-        if (mIsPulled && (conditionChanged || condition)) {
-            pullAndMatchEventsLocked(eventTimeNs, newCondition);
-        }
-
-        // When condition change from true to false, clear diff base but don't
-        // reset other counters as we may accumulate more value in the bucket.
-        if (mUseDiff && mCondition == ConditionState::kTrue
-                && newCondition == ConditionState::kFalse) {
-            resetBase();
-        }
-        mCondition = newCondition;
-    } else {
-        VLOG("Skip event due to late arrival: %lld vs %lld", (long long)eventTimeNs,
-             (long long)mCurrentBucketStartTimeNs);
-        StatsdStats::getInstance().noteConditionChangeInNextBucket(mMetricId);
+    if (ConditionState::kTrue == mCondition && isEventTooLate) {
+        // Drop bucket because event arrived too late, ie. we are missing data for this bucket.
         invalidateCurrentBucket();
-        // Something weird happened. If we received another event in the future, the condition might
-        // be wrong.
-        mCondition = initialCondition(mConditionTrackerIndex);
     }
 
-    // This part should alway be called.
+    // Call parent method once we've verified the validity of current bucket.
+    MetricProducer::onActiveStateChangedLocked(eventTimeNs);
+
+    if (ConditionState::kTrue != mCondition) {
+        return;
+    }
+
+    // Pull on active state changes.
+    if (!isEventTooLate) {
+        if (mIsPulled) {
+            pullAndMatchEventsLocked(eventTimeNs, mCondition);
+        }
+        // When active state changes from true to false, clear diff base but don't
+        // reset other counters as we may accumulate more value in the bucket.
+        if (mUseDiff && !mIsActive) {
+            resetBase();
+        }
+    }
+
     flushIfNeededLocked(eventTimeNs);
-    mConditionTimer.onConditionChanged(mCondition, eventTimeNs);
+
+    // Let condition timer know of new active state.
+    mConditionTimer.onConditionChanged(mIsActive, eventTimeNs);
 }
 
-void ValueMetricProducer::pullAndMatchEventsLocked(const int64_t timestampNs, ConditionState condition) {
+void ValueMetricProducer::onConditionChangedLocked(const bool condition,
+                                                   const int64_t eventTimeNs) {
+    ConditionState newCondition = condition ? ConditionState::kTrue : ConditionState::kFalse;
+    bool isEventTooLate  = eventTimeNs < mCurrentBucketStartTimeNs;
+
+    if (mIsActive) {
+        if (isEventTooLate) {
+            VLOG("Skip event due to late arrival: %lld vs %lld", (long long)eventTimeNs,
+                 (long long)mCurrentBucketStartTimeNs);
+            StatsdStats::getInstance().noteConditionChangeInNextBucket(mMetricId);
+            invalidateCurrentBucket();
+        } else {
+            if (mCondition == ConditionState::kUnknown) {
+                // If the condition was unknown, we mark the bucket as invalid since the bucket will
+                // contain partial data. For instance, the condition change might happen close to
+                // the end of the bucket and we might miss lots of data.
+                //
+                // We still want to pull to set the base.
+                invalidateCurrentBucket();
+            }
+
+            // Pull on condition changes.
+            bool conditionChanged =
+                    (mCondition == ConditionState::kTrue && newCondition == ConditionState::kFalse)
+                    || (mCondition == ConditionState::kFalse &&
+                            newCondition == ConditionState::kTrue);
+            // We do not need to pull when we go from unknown to false.
+            //
+            // We also pull if the condition was already true in order to be able to flush the
+            // bucket at the end if needed.
+            //
+            // onConditionChangedLocked might happen on bucket boundaries if this is called before
+            // #onDataPulled.
+            if (mIsPulled && (conditionChanged || condition)) {
+                pullAndMatchEventsLocked(eventTimeNs, newCondition);
+            }
+
+            // When condition change from true to false, clear diff base but don't
+            // reset other counters as we may accumulate more value in the bucket.
+            if (mUseDiff && mCondition == ConditionState::kTrue
+                    && newCondition == ConditionState::kFalse) {
+                resetBase();
+            }
+        }
+    }
+
+    mCondition = isEventTooLate ? initialCondition(mConditionTrackerIndex) : newCondition;
+
+    if (mIsActive) {
+        flushIfNeededLocked(eventTimeNs);
+        mConditionTimer.onConditionChanged(mCondition, eventTimeNs);
+    }
+}
+
+void ValueMetricProducer::pullAndMatchEventsLocked(const int64_t timestampNs,
+        ConditionState condition) {
     vector<std::shared_ptr<LogEvent>> allData;
     if (!mPullerManager->Pull(mPullTagId, &allData)) {
         ALOGE("Stats puller failed for tag: %d at %lld", mPullTagId, (long long)timestampNs);
diff --git a/cmds/statsd/src/metrics/ValueMetricProducer.h b/cmds/statsd/src/metrics/ValueMetricProducer.h
index de01e72..739f6ef 100644
--- a/cmds/statsd/src/metrics/ValueMetricProducer.h
+++ b/cmds/statsd/src/metrics/ValueMetricProducer.h
@@ -93,6 +93,9 @@
                             android::util::ProtoOutputStream* protoOutput) override;
     void clearPastBucketsLocked(const int64_t dumpTimeNs) override;
 
+    // Internal interface to handle active state change.
+    void onActiveStateChangedLocked(const int64_t& eventTimeNs) override;
+
     // Internal interface to handle condition change.
     void onConditionChangedLocked(const bool conditionMet, const int64_t eventTime) override;
 
diff --git a/cmds/statsd/src/stats_log_util.cpp b/cmds/statsd/src/stats_log_util.cpp
index 31f160d..67625eb 100644
--- a/cmds/statsd/src/stats_log_util.cpp
+++ b/cmds/statsd/src/stats_log_util.cpp
@@ -545,8 +545,15 @@
     return time(nullptr) * MS_PER_SEC;
 }
 
-int64_t truncateTimestampNsToFiveMinutes(int64_t timestampNs) {
-    return timestampNs / NS_PER_SEC / (5 * 60) * NS_PER_SEC * (5 * 60);
+int64_t truncateTimestampIfNecessary(int atomId, int64_t timestampNs) {
+    if (AtomsInfo::kTruncatingTimestampAtomBlackList.find(atomId) !=
+            AtomsInfo::kTruncatingTimestampAtomBlackList.end() ||
+        (atomId >= StatsdStats::kTimestampTruncationStartTag &&
+         atomId <= StatsdStats::kTimestampTruncationEndTag)) {
+        return timestampNs / NS_PER_SEC / (5 * 60) * NS_PER_SEC * (5 * 60);
+    } else {
+        return timestampNs;
+    }
 }
 
 int64_t NanoToMillis(const int64_t nano) {
diff --git a/cmds/statsd/src/stats_log_util.h b/cmds/statsd/src/stats_log_util.h
index 53dd5b7..bfb84cf 100644
--- a/cmds/statsd/src/stats_log_util.h
+++ b/cmds/statsd/src/stats_log_util.h
@@ -89,8 +89,9 @@
     return message->ParseFromArray(pbBytes.c_str(), pbBytes.size());
 }
 
-// Returns the truncated timestamp.
-int64_t truncateTimestampNsToFiveMinutes(int64_t timestampNs);
+// Checks the blacklist of atoms as well as the blacklisted range of 300,000 - 304,999.
+// Returns the truncated timestamp to the nearest 5 minutes if needed.
+int64_t truncateTimestampIfNecessary(int atomId, int64_t timestampNs);
 
 inline bool isVendorPulledAtom(int atomId) {
     return atomId >= StatsdStats::kVendorPulledAtomStartTag && atomId < StatsdStats::kMaxAtomTag;
diff --git a/cmds/statsd/src/storage/StorageManager.cpp b/cmds/statsd/src/storage/StorageManager.cpp
index 0a9161d..9b48a02 100644
--- a/cmds/statsd/src/storage/StorageManager.cpp
+++ b/cmds/statsd/src/storage/StorageManager.cpp
@@ -442,7 +442,7 @@
 
         if (erase_data) {
             remove(fullPathName.c_str());
-        } else if (output.mIsHistory && !isAdb) {
+        } else if (!output.mIsHistory && !isAdb) {
             // This means a real data owner has called to get this data. But the config says it
             // wants to keep a local history. So now this file must be renamed as a history file.
             // So that next time, when owner calls getData() again, this data won't be uploaded
diff --git a/cmds/statsd/tests/e2e/DurationMetric_e2e_test.cpp b/cmds/statsd/tests/e2e/DurationMetric_e2e_test.cpp
new file mode 100644
index 0000000..5da0fca
--- /dev/null
+++ b/cmds/statsd/tests/e2e/DurationMetric_e2e_test.cpp
@@ -0,0 +1,717 @@
+// Copyright (C) 2019 The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+#include <gtest/gtest.h>
+
+#include "src/StatsLogProcessor.h"
+#include "src/stats_log_util.h"
+#include "tests/statsd_test_util.h"
+
+#include <vector>
+
+namespace android {
+namespace os {
+namespace statsd {
+
+#ifdef __ANDROID__
+
+TEST(DurationMetricE2eTest, TestOneBucket) {
+    StatsdConfig config;
+    config.add_allowed_log_source("AID_ROOT"); // LogEvent defaults to UID of root.
+
+    auto screenOnMatcher = CreateScreenTurnedOnAtomMatcher();
+    auto screenOffMatcher = CreateScreenTurnedOffAtomMatcher();
+    *config.add_atom_matcher() = screenOnMatcher;
+    *config.add_atom_matcher() = screenOffMatcher;
+
+    auto durationPredicate = CreateScreenIsOnPredicate();
+    *config.add_predicate() = durationPredicate;
+
+    int64_t metricId = 123456;
+    auto durationMetric = config.add_duration_metric();
+    durationMetric->set_id(metricId);
+    durationMetric->set_what(durationPredicate.id());
+    durationMetric->set_bucket(FIVE_MINUTES);
+    durationMetric->set_aggregation_type(DurationMetric_AggregationType_SUM);
+
+
+    const int64_t baseTimeNs = 0; // 0:00
+    const int64_t configAddedTimeNs = baseTimeNs + 1 * NS_PER_SEC; // 0:01
+    const int64_t bucketSizeNs =
+            TimeUnitToBucketSizeInMillis(config.duration_metric(0).bucket()) * 1000LL * 1000LL;
+
+    int uid = 12345;
+    int64_t cfgId = 98765;
+    ConfigKey cfgKey(uid, cfgId);
+
+    auto processor = CreateStatsLogProcessor(baseTimeNs, configAddedTimeNs, config, cfgKey);
+
+    EXPECT_EQ(processor->mMetricsManagers.size(), 1u);
+    sp<MetricsManager> metricsManager = processor->mMetricsManagers.begin()->second;
+    EXPECT_TRUE(metricsManager->isConfigValid());
+    EXPECT_EQ(metricsManager->mAllMetricProducers.size(), 1);
+    sp<MetricProducer> metricProducer = metricsManager->mAllMetricProducers[0];
+    EXPECT_TRUE(metricsManager->isActive());
+    EXPECT_TRUE(metricProducer->mIsActive);
+
+    std::unique_ptr<LogEvent> event;
+
+    // Screen is off at start of bucket.
+    event = CreateScreenStateChangedEvent(
+            android::view::DISPLAY_STATE_OFF, configAddedTimeNs); // 0:01
+    processor->OnLogEvent(event.get());
+
+    // Turn screen on.
+    const int64_t durationStartNs = configAddedTimeNs + 10 * NS_PER_SEC; // 0:11
+    event = CreateScreenStateChangedEvent(android::view::DISPLAY_STATE_ON, durationStartNs);
+    processor->OnLogEvent(event.get());
+
+    // Turn off screen 30 seconds after turning on.
+    const int64_t durationEndNs = durationStartNs + 30 * NS_PER_SEC; // 0:41
+    event = CreateScreenStateChangedEvent(android::view::DISPLAY_STATE_OFF, durationEndNs);
+    processor->OnLogEvent(event.get());
+
+    event = CreateScreenBrightnessChangedEvent(64, durationEndNs + 1 * NS_PER_SEC); // 0:42
+    processor->OnLogEvent(event.get());
+
+    ConfigMetricsReportList reports;
+    vector<uint8_t> buffer;
+    processor->onDumpReport(cfgKey, configAddedTimeNs + bucketSizeNs + 1 * NS_PER_SEC, false, true,
+                            ADB_DUMP, FAST, &buffer); // 5:01
+    EXPECT_TRUE(buffer.size() > 0);
+    EXPECT_TRUE(reports.ParseFromArray(&buffer[0], buffer.size()));
+    backfillDimensionPath(&reports);
+    backfillStartEndTimestamp(&reports);
+    EXPECT_EQ(1, reports.reports_size());
+    EXPECT_EQ(1, reports.reports(0).metrics_size());
+    EXPECT_EQ(metricId, reports.reports(0).metrics(0).metric_id());
+    EXPECT_TRUE(reports.reports(0).metrics(0).has_duration_metrics());
+
+    const StatsLogReport::DurationMetricDataWrapper& durationMetrics =
+            reports.reports(0).metrics(0).duration_metrics();
+    EXPECT_EQ(1, durationMetrics.data_size());
+
+    auto data = durationMetrics.data(0);
+    EXPECT_EQ(1, data.bucket_info_size());
+    EXPECT_EQ(durationEndNs - durationStartNs, data.bucket_info(0).duration_nanos());
+    EXPECT_EQ(configAddedTimeNs, data.bucket_info(0).start_bucket_elapsed_nanos());
+    EXPECT_EQ(baseTimeNs + bucketSizeNs, data.bucket_info(0).end_bucket_elapsed_nanos());
+}
+
+TEST(DurationMetricE2eTest, TestTwoBuckets) {
+    StatsdConfig config;
+    config.add_allowed_log_source("AID_ROOT"); // LogEvent defaults to UID of root.
+
+    auto screenOnMatcher = CreateScreenTurnedOnAtomMatcher();
+    auto screenOffMatcher = CreateScreenTurnedOffAtomMatcher();
+    *config.add_atom_matcher() = screenOnMatcher;
+    *config.add_atom_matcher() = screenOffMatcher;
+
+    auto durationPredicate = CreateScreenIsOnPredicate();
+    *config.add_predicate() = durationPredicate;
+
+    int64_t metricId = 123456;
+    auto durationMetric = config.add_duration_metric();
+    durationMetric->set_id(metricId);
+    durationMetric->set_what(durationPredicate.id());
+    durationMetric->set_bucket(FIVE_MINUTES);
+    durationMetric->set_aggregation_type(DurationMetric_AggregationType_SUM);
+
+
+    const int64_t baseTimeNs = 0; // 0:00
+    const int64_t configAddedTimeNs = baseTimeNs + 1 * NS_PER_SEC; // 0:01
+    const int64_t bucketSizeNs =
+            TimeUnitToBucketSizeInMillis(config.duration_metric(0).bucket()) * 1000LL * 1000LL;
+
+    int uid = 12345;
+    int64_t cfgId = 98765;
+    ConfigKey cfgKey(uid, cfgId);
+
+    auto processor = CreateStatsLogProcessor(baseTimeNs, configAddedTimeNs, config, cfgKey);
+
+    EXPECT_EQ(processor->mMetricsManagers.size(), 1u);
+    sp<MetricsManager> metricsManager = processor->mMetricsManagers.begin()->second;
+    EXPECT_TRUE(metricsManager->isConfigValid());
+    EXPECT_EQ(metricsManager->mAllMetricProducers.size(), 1);
+    sp<MetricProducer> metricProducer = metricsManager->mAllMetricProducers[0];
+    EXPECT_TRUE(metricsManager->isActive());
+    EXPECT_TRUE(metricProducer->mIsActive);
+
+    std::unique_ptr<LogEvent> event;
+
+    // Screen is off at start of bucket.
+    event = CreateScreenStateChangedEvent(
+            android::view::DISPLAY_STATE_OFF, configAddedTimeNs); // 0:01
+    processor->OnLogEvent(event.get());
+
+    // Turn screen on.
+    const int64_t durationStartNs = configAddedTimeNs + 10 * NS_PER_SEC; // 0:11
+    event = CreateScreenStateChangedEvent(android::view::DISPLAY_STATE_ON, durationStartNs);
+    processor->OnLogEvent(event.get());
+
+    // Turn off screen 30 seconds after turning on.
+    const int64_t durationEndNs = durationStartNs + 30 * NS_PER_SEC; // 0:41
+    event = CreateScreenStateChangedEvent(android::view::DISPLAY_STATE_OFF, durationEndNs);
+    processor->OnLogEvent(event.get());
+
+    event = CreateScreenBrightnessChangedEvent(64, durationEndNs + 1 * NS_PER_SEC); // 0:42
+    processor->OnLogEvent(event.get());
+
+    ConfigMetricsReportList reports;
+    vector<uint8_t> buffer;
+    processor->onDumpReport(cfgKey, configAddedTimeNs + 2 * bucketSizeNs + 1 * NS_PER_SEC, false, true,
+                            ADB_DUMP, FAST, &buffer); // 10:01
+    EXPECT_TRUE(buffer.size() > 0);
+    EXPECT_TRUE(reports.ParseFromArray(&buffer[0], buffer.size()));
+    backfillDimensionPath(&reports);
+    backfillStartEndTimestamp(&reports);
+    EXPECT_EQ(1, reports.reports_size());
+    EXPECT_EQ(1, reports.reports(0).metrics_size());
+    EXPECT_EQ(metricId, reports.reports(0).metrics(0).metric_id());
+    EXPECT_TRUE(reports.reports(0).metrics(0).has_duration_metrics());
+
+    const StatsLogReport::DurationMetricDataWrapper& durationMetrics =
+            reports.reports(0).metrics(0).duration_metrics();
+    EXPECT_EQ(1, durationMetrics.data_size());
+
+    auto data = durationMetrics.data(0);
+    EXPECT_EQ(1, data.bucket_info_size());
+
+    auto bucketInfo = data.bucket_info(0);
+    EXPECT_EQ(0, bucketInfo.bucket_num());
+    EXPECT_EQ(durationEndNs - durationStartNs, bucketInfo.duration_nanos());
+    EXPECT_EQ(configAddedTimeNs, bucketInfo.start_bucket_elapsed_nanos());
+    EXPECT_EQ(baseTimeNs + bucketSizeNs, bucketInfo.end_bucket_elapsed_nanos());
+}
+
+TEST(DurationMetricE2eTest, TestWithActivation) {
+    StatsdConfig config;
+    config.add_allowed_log_source("AID_ROOT"); // LogEvent defaults to UID of root.
+
+    auto screenOnMatcher = CreateScreenTurnedOnAtomMatcher();
+    auto screenOffMatcher = CreateScreenTurnedOffAtomMatcher();
+    auto crashMatcher = CreateProcessCrashAtomMatcher();
+    *config.add_atom_matcher() = screenOnMatcher;
+    *config.add_atom_matcher() = screenOffMatcher;
+    *config.add_atom_matcher() = crashMatcher;
+
+    auto durationPredicate = CreateScreenIsOnPredicate();
+    *config.add_predicate() = durationPredicate;
+
+    int64_t metricId = 123456;
+    auto durationMetric = config.add_duration_metric();
+    durationMetric->set_id(metricId);
+    durationMetric->set_what(durationPredicate.id());
+    durationMetric->set_bucket(FIVE_MINUTES);
+    durationMetric->set_aggregation_type(DurationMetric_AggregationType_SUM);
+
+    auto metric_activation1 = config.add_metric_activation();
+    metric_activation1->set_metric_id(metricId);
+    auto event_activation1 = metric_activation1->add_event_activation();
+    event_activation1->set_atom_matcher_id(crashMatcher.id());
+    event_activation1->set_ttl_seconds(30); // 30 secs.
+
+    const int64_t bucketStartTimeNs = 10000000000;
+    const int64_t bucketSizeNs =
+            TimeUnitToBucketSizeInMillis(config.duration_metric(0).bucket()) * 1000LL * 1000LL;
+
+    int uid = 12345;
+    int64_t cfgId = 98765;
+    ConfigKey cfgKey(uid, cfgId);
+
+    sp<UidMap> m = new UidMap();
+    sp<StatsPullerManager> pullerManager = new StatsPullerManager();
+    sp<AlarmMonitor> anomalyAlarmMonitor;
+    sp<AlarmMonitor> subscriberAlarmMonitor;
+    vector<int64_t> activeConfigsBroadcast;
+
+    int broadcastCount = 0;
+    StatsLogProcessor processor(m, pullerManager, anomalyAlarmMonitor, subscriberAlarmMonitor,
+            bucketStartTimeNs, [](const ConfigKey& key) { return true; },
+            [&uid, &broadcastCount, &activeConfigsBroadcast](const int& broadcastUid,
+                    const vector<int64_t>& activeConfigs) {
+                broadcastCount++;
+                EXPECT_EQ(broadcastUid, uid);
+                activeConfigsBroadcast.clear();
+                activeConfigsBroadcast.insert(activeConfigsBroadcast.end(),
+                        activeConfigs.begin(), activeConfigs.end());
+                return true;
+            });
+
+    processor.OnConfigUpdated(bucketStartTimeNs, cfgKey, config); // 0:00
+
+    EXPECT_EQ(processor.mMetricsManagers.size(), 1u);
+    sp<MetricsManager> metricsManager = processor.mMetricsManagers.begin()->second;
+    EXPECT_TRUE(metricsManager->isConfigValid());
+    EXPECT_EQ(metricsManager->mAllMetricProducers.size(), 1);
+    sp<MetricProducer> metricProducer = metricsManager->mAllMetricProducers[0];
+    auto& eventActivationMap = metricProducer->mEventActivationMap;
+
+    EXPECT_FALSE(metricsManager->isActive());
+    EXPECT_FALSE(metricProducer->mIsActive);
+    EXPECT_EQ(eventActivationMap.size(), 1u);
+    EXPECT_TRUE(eventActivationMap.find(2) != eventActivationMap.end());
+    EXPECT_EQ(eventActivationMap[2]->state, ActivationState::kNotActive);
+    EXPECT_EQ(eventActivationMap[2]->start_ns, 0);
+    EXPECT_EQ(eventActivationMap[2]->ttl_ns, event_activation1->ttl_seconds() * NS_PER_SEC);
+
+    std::unique_ptr<LogEvent> event;
+
+    // Turn screen off.
+    event = CreateScreenStateChangedEvent(
+            android::view::DISPLAY_STATE_OFF, bucketStartTimeNs + 2 * NS_PER_SEC); // 0:02
+    processor.OnLogEvent(event.get());
+
+    // Turn screen on.
+    const int64_t durationStartNs = bucketStartTimeNs + 5 * NS_PER_SEC; // 0:05
+    event = CreateScreenStateChangedEvent(android::view::DISPLAY_STATE_ON, durationStartNs);
+    processor.OnLogEvent(event.get());
+
+    // Activate metric.
+    const int64_t activationStartNs = bucketStartTimeNs + 5 * NS_PER_SEC; // 0:10
+    const int64_t activationEndNs =
+            activationStartNs + event_activation1->ttl_seconds() * NS_PER_SEC; // 0:40
+    event = CreateAppCrashEvent(111, activationStartNs);
+    processor.OnLogEvent(event.get());
+    EXPECT_TRUE(metricsManager->isActive());
+    EXPECT_TRUE(metricProducer->mIsActive);
+    EXPECT_EQ(broadcastCount, 1);
+    EXPECT_EQ(activeConfigsBroadcast.size(), 1);
+    EXPECT_EQ(activeConfigsBroadcast[0], cfgId);
+    EXPECT_EQ(eventActivationMap[2]->state, ActivationState::kActive);
+    EXPECT_EQ(eventActivationMap[2]->start_ns, activationStartNs);
+    EXPECT_EQ(eventActivationMap[2]->ttl_ns, event_activation1->ttl_seconds() * NS_PER_SEC);
+
+    // Expire activation.
+    const int64_t expirationNs = activationEndNs + 7 * NS_PER_SEC;
+    event = CreateScreenBrightnessChangedEvent(64, expirationNs); // 0:47
+    processor.OnLogEvent(event.get());
+    EXPECT_FALSE(metricsManager->isActive());
+    EXPECT_FALSE(metricProducer->mIsActive);
+    EXPECT_EQ(broadcastCount, 2);
+    EXPECT_EQ(activeConfigsBroadcast.size(), 0);
+    EXPECT_EQ(eventActivationMap.size(), 1u);
+    EXPECT_TRUE(eventActivationMap.find(2) != eventActivationMap.end());
+    EXPECT_EQ(eventActivationMap[2]->state, ActivationState::kNotActive);
+    EXPECT_EQ(eventActivationMap[2]->start_ns, activationStartNs);
+    EXPECT_EQ(eventActivationMap[2]->ttl_ns, event_activation1->ttl_seconds() * NS_PER_SEC);
+
+    // Turn off screen 10 seconds after activation expiration.
+    const int64_t durationEndNs = activationEndNs + 10 * NS_PER_SEC; // 0:50
+    event = CreateScreenStateChangedEvent(android::view::DISPLAY_STATE_OFF, durationEndNs);
+    processor.OnLogEvent(event.get());
+
+    // Turn screen on.
+    const int64_t duration2StartNs = durationEndNs + 5 * NS_PER_SEC; // 0:55
+    event = CreateScreenStateChangedEvent(android::view::DISPLAY_STATE_ON, duration2StartNs);
+    processor.OnLogEvent(event.get());
+
+    // Turn off screen.
+    const int64_t duration2EndNs = duration2StartNs + 10 * NS_PER_SEC; // 1:05
+    event = CreateScreenStateChangedEvent(android::view::DISPLAY_STATE_OFF, duration2EndNs);
+    processor.OnLogEvent(event.get());
+
+    // Activate metric.
+    const int64_t activation2StartNs = duration2EndNs + 5 * NS_PER_SEC; // 1:10
+    const int64_t activation2EndNs =
+            activation2StartNs + event_activation1->ttl_seconds() * NS_PER_SEC; // 1:40
+    event = CreateAppCrashEvent(211, activation2StartNs);
+    processor.OnLogEvent(event.get());
+    EXPECT_TRUE(metricsManager->isActive());
+    EXPECT_TRUE(metricProducer->mIsActive);
+    EXPECT_EQ(broadcastCount, 3);
+    EXPECT_EQ(activeConfigsBroadcast.size(), 1);
+    EXPECT_EQ(activeConfigsBroadcast[0], cfgId);
+    EXPECT_EQ(eventActivationMap[2]->state, ActivationState::kActive);
+    EXPECT_EQ(eventActivationMap[2]->start_ns, activation2StartNs);
+    EXPECT_EQ(eventActivationMap[2]->ttl_ns, event_activation1->ttl_seconds() * NS_PER_SEC);
+
+    ConfigMetricsReportList reports;
+    vector<uint8_t> buffer;
+    processor.onDumpReport(cfgKey, bucketStartTimeNs + bucketSizeNs + 1 * NS_PER_SEC, false, true,
+                            ADB_DUMP, FAST, &buffer); // 5:01
+    EXPECT_TRUE(buffer.size() > 0);
+    EXPECT_TRUE(reports.ParseFromArray(&buffer[0], buffer.size()));
+    backfillDimensionPath(&reports);
+    backfillStartEndTimestamp(&reports);
+    EXPECT_EQ(1, reports.reports_size());
+    EXPECT_EQ(1, reports.reports(0).metrics_size());
+    EXPECT_EQ(metricId, reports.reports(0).metrics(0).metric_id());
+    EXPECT_TRUE(reports.reports(0).metrics(0).has_duration_metrics());
+
+    const StatsLogReport::DurationMetricDataWrapper& durationMetrics =
+            reports.reports(0).metrics(0).duration_metrics();
+    EXPECT_EQ(1, durationMetrics.data_size());
+
+    auto data = durationMetrics.data(0);
+    EXPECT_EQ(1, data.bucket_info_size());
+
+    auto bucketInfo = data.bucket_info(0);
+    EXPECT_EQ(0, bucketInfo.bucket_num());
+    EXPECT_EQ(bucketStartTimeNs, bucketInfo.start_bucket_elapsed_nanos());
+    EXPECT_EQ(expirationNs, bucketInfo.end_bucket_elapsed_nanos());
+    EXPECT_EQ(expirationNs - durationStartNs, bucketInfo.duration_nanos());
+}
+
+TEST(DurationMetricE2eTest, TestWithCondition) {
+    StatsdConfig config;
+    config.add_allowed_log_source("AID_ROOT"); // LogEvent defaults to UID of root.
+    *config.add_atom_matcher() = CreateAcquireWakelockAtomMatcher();
+    *config.add_atom_matcher() = CreateReleaseWakelockAtomMatcher();
+    *config.add_atom_matcher() = CreateMoveToBackgroundAtomMatcher();
+    *config.add_atom_matcher() = CreateMoveToForegroundAtomMatcher();
+
+    auto holdingWakelockPredicate = CreateHoldingWakelockPredicate();
+    *config.add_predicate() = holdingWakelockPredicate;
+
+    auto isInBackgroundPredicate = CreateIsInBackgroundPredicate();
+    *config.add_predicate() = isInBackgroundPredicate;
+
+    auto durationMetric = config.add_duration_metric();
+    durationMetric->set_id(StringToId("WakelockDuration"));
+    durationMetric->set_what(holdingWakelockPredicate.id());
+    durationMetric->set_condition(isInBackgroundPredicate.id());
+    durationMetric->set_aggregation_type(DurationMetric::SUM);
+    durationMetric->set_bucket(FIVE_MINUTES);
+
+    ConfigKey cfgKey;
+    uint64_t bucketStartTimeNs = 10000000000;
+    uint64_t bucketSizeNs =
+            TimeUnitToBucketSizeInMillis(config.duration_metric(0).bucket()) * 1000000LL;
+    auto processor = CreateStatsLogProcessor(bucketStartTimeNs, bucketStartTimeNs, config, cfgKey);
+    EXPECT_EQ(processor->mMetricsManagers.size(), 1u);
+    sp<MetricsManager> metricsManager = processor->mMetricsManagers.begin()->second;
+    EXPECT_TRUE(metricsManager->isConfigValid());
+    EXPECT_EQ(metricsManager->mAllMetricProducers.size(), 1);
+    sp<MetricProducer> metricProducer = metricsManager->mAllMetricProducers[0];
+    auto& eventActivationMap = metricProducer->mEventActivationMap;
+    EXPECT_TRUE(metricsManager->isActive());
+    EXPECT_TRUE(metricProducer->mIsActive);
+    EXPECT_TRUE(eventActivationMap.empty());
+
+    int appUid = 123;
+    std::vector<AttributionNodeInternal> attributions1 = {CreateAttribution(appUid, "App1")};
+
+    auto event = CreateAcquireWakelockEvent(
+            attributions1, "wl1", bucketStartTimeNs + 10 * NS_PER_SEC); // 0:10
+    processor->OnLogEvent(event.get());
+
+    event = CreateMoveToBackgroundEvent(appUid, bucketStartTimeNs + 22 * NS_PER_SEC); // 0:22
+    processor->OnLogEvent(event.get());
+
+    event = CreateMoveToForegroundEvent(
+            appUid, bucketStartTimeNs + (3 * 60 + 15) * NS_PER_SEC); // 3:15
+    processor->OnLogEvent(event.get());
+
+    event = CreateReleaseWakelockEvent(
+            attributions1, "wl1", bucketStartTimeNs + 4 * 60 * NS_PER_SEC); // 4:00
+    processor->OnLogEvent(event.get());
+
+    vector<uint8_t> buffer;
+    ConfigMetricsReportList reports;
+    processor->onDumpReport(cfgKey, bucketStartTimeNs + bucketSizeNs + 1, false, true,
+                            ADB_DUMP, FAST, &buffer);
+    EXPECT_GT(buffer.size(), 0);
+    EXPECT_TRUE(reports.ParseFromArray(&buffer[0], buffer.size()));
+    backfillDimensionPath(&reports);
+    backfillStringInReport(&reports);
+    backfillStartEndTimestamp(&reports);
+
+    EXPECT_EQ(1, reports.reports_size());
+    EXPECT_EQ(1, reports.reports(0).metrics_size());
+    EXPECT_EQ(1, reports.reports(0).metrics(0).duration_metrics().data_size());
+
+    auto data = reports.reports(0).metrics(0).duration_metrics().data(0);
+
+    // Validate bucket info.
+    EXPECT_EQ(1, data.bucket_info_size());
+
+    auto bucketInfo = data.bucket_info(0);
+    EXPECT_EQ(bucketStartTimeNs, bucketInfo.start_bucket_elapsed_nanos());
+    EXPECT_EQ(bucketStartTimeNs + bucketSizeNs, bucketInfo.end_bucket_elapsed_nanos());
+    EXPECT_EQ((2 * 60 + 53) * NS_PER_SEC, bucketInfo.duration_nanos());
+}
+
+TEST(DurationMetricE2eTest, TestWithSlicedCondition) {
+    StatsdConfig config;
+    config.add_allowed_log_source("AID_ROOT"); // LogEvent defaults to UID of root.
+    auto screenOnMatcher = CreateScreenTurnedOnAtomMatcher();
+    *config.add_atom_matcher() = CreateAcquireWakelockAtomMatcher();
+    *config.add_atom_matcher() = CreateReleaseWakelockAtomMatcher();
+    *config.add_atom_matcher() = CreateMoveToBackgroundAtomMatcher();
+    *config.add_atom_matcher() = CreateMoveToForegroundAtomMatcher();
+
+    auto holdingWakelockPredicate = CreateHoldingWakelockPredicate();
+    // The predicate is dimensioning by first attribution node by uid.
+    FieldMatcher dimensions = CreateAttributionUidDimensions(
+            android::util::WAKELOCK_STATE_CHANGED, {Position::FIRST});
+    *holdingWakelockPredicate.mutable_simple_predicate()->mutable_dimensions() = dimensions;
+    *config.add_predicate() = holdingWakelockPredicate;
+
+    auto isInBackgroundPredicate = CreateIsInBackgroundPredicate();
+    *isInBackgroundPredicate.mutable_simple_predicate()->mutable_dimensions() =
+        CreateDimensions(android::util::ACTIVITY_FOREGROUND_STATE_CHANGED, {Position::FIRST});
+    *config.add_predicate() = isInBackgroundPredicate;
+
+    auto durationMetric = config.add_duration_metric();
+    durationMetric->set_id(StringToId("WakelockDuration"));
+    durationMetric->set_what(holdingWakelockPredicate.id());
+    durationMetric->set_condition(isInBackgroundPredicate.id());
+    durationMetric->set_aggregation_type(DurationMetric::SUM);
+    // The metric is dimensioning by first attribution node and only by uid.
+    *durationMetric->mutable_dimensions_in_what() =
+        CreateAttributionUidDimensions(
+            android::util::WAKELOCK_STATE_CHANGED, {Position::FIRST});
+    durationMetric->set_bucket(FIVE_MINUTES);
+
+    // Links between wakelock state atom and condition of app is in background.
+    auto links = durationMetric->add_links();
+    links->set_condition(isInBackgroundPredicate.id());
+    auto dimensionWhat = links->mutable_fields_in_what();
+    dimensionWhat->set_field(android::util::WAKELOCK_STATE_CHANGED);
+    dimensionWhat->add_child()->set_field(1);  // uid field.
+    *links->mutable_fields_in_condition() = CreateAttributionUidDimensions(
+            android::util::ACTIVITY_FOREGROUND_STATE_CHANGED, { Position::FIRST });
+
+    ConfigKey cfgKey;
+    uint64_t bucketStartTimeNs = 10000000000;
+    uint64_t bucketSizeNs =
+            TimeUnitToBucketSizeInMillis(config.duration_metric(0).bucket()) * 1000000LL;
+    auto processor = CreateStatsLogProcessor(bucketStartTimeNs, bucketStartTimeNs, config, cfgKey);
+    EXPECT_EQ(processor->mMetricsManagers.size(), 1u);
+    sp<MetricsManager> metricsManager = processor->mMetricsManagers.begin()->second;
+    EXPECT_TRUE(metricsManager->isConfigValid());
+    EXPECT_EQ(metricsManager->mAllMetricProducers.size(), 1);
+    sp<MetricProducer> metricProducer = metricsManager->mAllMetricProducers[0];
+    auto& eventActivationMap = metricProducer->mEventActivationMap;
+    EXPECT_TRUE(metricsManager->isActive());
+    EXPECT_TRUE(metricProducer->mIsActive);
+    EXPECT_TRUE(eventActivationMap.empty());
+
+    int appUid = 123;
+    std::vector<AttributionNodeInternal> attributions1 = {CreateAttribution(appUid, "App1")};
+
+    auto event = CreateAcquireWakelockEvent(
+            attributions1, "wl1", bucketStartTimeNs + 10 * NS_PER_SEC); // 0:10
+    processor->OnLogEvent(event.get());
+
+    event = CreateMoveToBackgroundEvent(appUid, bucketStartTimeNs + 22 * NS_PER_SEC); // 0:22
+    processor->OnLogEvent(event.get());
+
+    event = CreateReleaseWakelockEvent(
+            attributions1, "wl1", bucketStartTimeNs + 60 * NS_PER_SEC); // 1:00
+    processor->OnLogEvent(event.get());
+
+
+    event = CreateMoveToForegroundEvent(
+            appUid, bucketStartTimeNs + (3 * 60 + 15) * NS_PER_SEC); // 3:15
+    processor->OnLogEvent(event.get());
+
+    vector<uint8_t> buffer;
+    ConfigMetricsReportList reports;
+    processor->onDumpReport(cfgKey, bucketStartTimeNs + bucketSizeNs + 1, false, true,
+                            ADB_DUMP, FAST, &buffer);
+    EXPECT_GT(buffer.size(), 0);
+    EXPECT_TRUE(reports.ParseFromArray(&buffer[0], buffer.size()));
+    backfillDimensionPath(&reports);
+    backfillStringInReport(&reports);
+    backfillStartEndTimestamp(&reports);
+
+    EXPECT_EQ(1, reports.reports_size());
+    EXPECT_EQ(1, reports.reports(0).metrics_size());
+    EXPECT_EQ(1, reports.reports(0).metrics(0).duration_metrics().data_size());
+
+    auto data = reports.reports(0).metrics(0).duration_metrics().data(0);
+    // Validate dimension value.
+    ValidateAttributionUidDimension(data.dimensions_in_what(),
+                                    android::util::WAKELOCK_STATE_CHANGED, appUid);
+    // Validate bucket info.
+    EXPECT_EQ(1, data.bucket_info_size());
+
+    auto bucketInfo = data.bucket_info(0);
+    EXPECT_EQ(bucketStartTimeNs, bucketInfo.start_bucket_elapsed_nanos());
+    EXPECT_EQ(bucketStartTimeNs + bucketSizeNs, bucketInfo.end_bucket_elapsed_nanos());
+    EXPECT_EQ(38 * NS_PER_SEC, bucketInfo.duration_nanos());
+}
+
+TEST(DurationMetricE2eTest, TestWithActivationAndSlicedCondition) {
+    StatsdConfig config;
+    config.add_allowed_log_source("AID_ROOT"); // LogEvent defaults to UID of root.
+    auto screenOnMatcher = CreateScreenTurnedOnAtomMatcher();
+    *config.add_atom_matcher() = CreateAcquireWakelockAtomMatcher();
+    *config.add_atom_matcher() = CreateReleaseWakelockAtomMatcher();
+    *config.add_atom_matcher() = CreateMoveToBackgroundAtomMatcher();
+    *config.add_atom_matcher() = CreateMoveToForegroundAtomMatcher();
+    *config.add_atom_matcher() = screenOnMatcher;
+
+    auto holdingWakelockPredicate = CreateHoldingWakelockPredicate();
+    // The predicate is dimensioning by first attribution node by uid.
+    FieldMatcher dimensions = CreateAttributionUidDimensions(
+            android::util::WAKELOCK_STATE_CHANGED, {Position::FIRST});
+    *holdingWakelockPredicate.mutable_simple_predicate()->mutable_dimensions() = dimensions;
+    *config.add_predicate() = holdingWakelockPredicate;
+
+    auto isInBackgroundPredicate = CreateIsInBackgroundPredicate();
+    *isInBackgroundPredicate.mutable_simple_predicate()->mutable_dimensions() =
+        CreateDimensions(android::util::ACTIVITY_FOREGROUND_STATE_CHANGED, {Position::FIRST});
+    *config.add_predicate() = isInBackgroundPredicate;
+
+    auto durationMetric = config.add_duration_metric();
+    durationMetric->set_id(StringToId("WakelockDuration"));
+    durationMetric->set_what(holdingWakelockPredicate.id());
+    durationMetric->set_condition(isInBackgroundPredicate.id());
+    durationMetric->set_aggregation_type(DurationMetric::SUM);
+    // The metric is dimensioning by first attribution node and only by uid.
+    *durationMetric->mutable_dimensions_in_what() =
+        CreateAttributionUidDimensions(
+            android::util::WAKELOCK_STATE_CHANGED, {Position::FIRST});
+    durationMetric->set_bucket(FIVE_MINUTES);
+
+    // Links between wakelock state atom and condition of app is in background.
+    auto links = durationMetric->add_links();
+    links->set_condition(isInBackgroundPredicate.id());
+    auto dimensionWhat = links->mutable_fields_in_what();
+    dimensionWhat->set_field(android::util::WAKELOCK_STATE_CHANGED);
+    dimensionWhat->add_child()->set_field(1);  // uid field.
+    *links->mutable_fields_in_condition() = CreateAttributionUidDimensions(
+            android::util::ACTIVITY_FOREGROUND_STATE_CHANGED, { Position::FIRST });
+
+    auto metric_activation1 = config.add_metric_activation();
+    metric_activation1->set_metric_id(durationMetric->id());
+    auto event_activation1 = metric_activation1->add_event_activation();
+    event_activation1->set_atom_matcher_id(screenOnMatcher.id());
+    event_activation1->set_ttl_seconds(60 * 2);  // 2 minutes.
+
+    ConfigKey cfgKey;
+    uint64_t bucketStartTimeNs = 10000000000;
+    uint64_t bucketSizeNs =
+            TimeUnitToBucketSizeInMillis(config.duration_metric(0).bucket()) * 1000000LL;
+    auto processor = CreateStatsLogProcessor(bucketStartTimeNs, bucketStartTimeNs, config, cfgKey);
+    EXPECT_EQ(processor->mMetricsManagers.size(), 1u);
+    sp<MetricsManager> metricsManager = processor->mMetricsManagers.begin()->second;
+    EXPECT_TRUE(metricsManager->isConfigValid());
+    EXPECT_EQ(metricsManager->mAllMetricProducers.size(), 1);
+    sp<MetricProducer> metricProducer = metricsManager->mAllMetricProducers[0];
+    auto& eventActivationMap = metricProducer->mEventActivationMap;
+    EXPECT_FALSE(metricsManager->isActive());
+    EXPECT_FALSE(metricProducer->mIsActive);
+    EXPECT_EQ(eventActivationMap.size(), 1u);
+    EXPECT_TRUE(eventActivationMap.find(4) != eventActivationMap.end());
+    EXPECT_EQ(eventActivationMap[4]->state, ActivationState::kNotActive);
+    EXPECT_EQ(eventActivationMap[4]->start_ns, 0);
+    EXPECT_EQ(eventActivationMap[4]->ttl_ns, event_activation1->ttl_seconds() * NS_PER_SEC);
+
+    int appUid = 123;
+    std::vector<AttributionNodeInternal> attributions1 = {CreateAttribution(appUid, "App1")};
+
+    auto event = CreateAcquireWakelockEvent(
+            attributions1, "wl1", bucketStartTimeNs + 10 * NS_PER_SEC); // 0:10
+    processor->OnLogEvent(event.get());
+    EXPECT_FALSE(metricsManager->isActive());
+    EXPECT_FALSE(metricProducer->mIsActive);
+    EXPECT_EQ(eventActivationMap[4]->state, ActivationState::kNotActive);
+    EXPECT_EQ(eventActivationMap[4]->start_ns, 0);
+    EXPECT_EQ(eventActivationMap[4]->ttl_ns, event_activation1->ttl_seconds() * NS_PER_SEC);
+
+    event = CreateMoveToBackgroundEvent(appUid, bucketStartTimeNs + 22 * NS_PER_SEC); // 0:22
+    processor->OnLogEvent(event.get());
+    EXPECT_FALSE(metricsManager->isActive());
+    EXPECT_FALSE(metricProducer->mIsActive);
+    EXPECT_EQ(eventActivationMap[4]->state, ActivationState::kNotActive);
+    EXPECT_EQ(eventActivationMap[4]->start_ns, 0);
+    EXPECT_EQ(eventActivationMap[4]->ttl_ns, event_activation1->ttl_seconds() * NS_PER_SEC);
+
+    const int64_t durationStartNs = bucketStartTimeNs + 30 * NS_PER_SEC; // 0:30
+    event = CreateScreenStateChangedEvent(android::view::DISPLAY_STATE_ON, durationStartNs);
+    processor->OnLogEvent(event.get());
+    EXPECT_TRUE(metricsManager->isActive());
+    EXPECT_TRUE(metricProducer->mIsActive);
+    EXPECT_EQ(eventActivationMap[4]->state, ActivationState::kActive);
+    EXPECT_EQ(eventActivationMap[4]->start_ns, durationStartNs);
+    EXPECT_EQ(eventActivationMap[4]->ttl_ns, event_activation1->ttl_seconds() * NS_PER_SEC);
+
+    const int64_t durationEndNs =
+            durationStartNs + (event_activation1->ttl_seconds() + 30) * NS_PER_SEC; // 3:00
+    event = CreateAppCrashEvent(333, durationEndNs);
+    processor->OnLogEvent(event.get());
+    EXPECT_FALSE(metricsManager->isActive());
+    EXPECT_FALSE(metricProducer->mIsActive);
+    EXPECT_EQ(eventActivationMap[4]->state, ActivationState::kNotActive);
+    EXPECT_EQ(eventActivationMap[4]->start_ns, durationStartNs);
+    EXPECT_EQ(eventActivationMap[4]->ttl_ns, event_activation1->ttl_seconds() * NS_PER_SEC);
+
+    event = CreateMoveToForegroundEvent(
+            appUid, bucketStartTimeNs + (3 * 60 + 15) * NS_PER_SEC); // 3:15
+    processor->OnLogEvent(event.get());
+
+    event = CreateReleaseWakelockEvent(
+            attributions1, "wl1", bucketStartTimeNs + (4 * 60 + 17) * NS_PER_SEC); // 4:17
+    processor->OnLogEvent(event.get());
+
+    event = CreateMoveToBackgroundEvent(
+            appUid, bucketStartTimeNs + (4 * 60 + 20) * NS_PER_SEC); // 4:20
+    processor->OnLogEvent(event.get());
+
+    event = CreateAcquireWakelockEvent(
+            attributions1, "wl1", bucketStartTimeNs + (4 * 60 + 25) * NS_PER_SEC); // 4:25
+    processor->OnLogEvent(event.get());
+
+    const int64_t duration2StartNs = bucketStartTimeNs + (4 * 60 + 30) * NS_PER_SEC; // 4:30
+    event = CreateScreenStateChangedEvent(android::view::DISPLAY_STATE_ON, duration2StartNs);
+    processor->OnLogEvent(event.get());
+    EXPECT_TRUE(metricsManager->isActive());
+    EXPECT_TRUE(metricProducer->mIsActive);
+    EXPECT_EQ(eventActivationMap[4]->state, ActivationState::kActive);
+    EXPECT_EQ(eventActivationMap[4]->start_ns, duration2StartNs);
+    EXPECT_EQ(eventActivationMap[4]->ttl_ns, event_activation1->ttl_seconds() * NS_PER_SEC);
+
+    vector<uint8_t> buffer;
+    ConfigMetricsReportList reports;
+    processor->onDumpReport(cfgKey, bucketStartTimeNs + bucketSizeNs + 1, false, true,
+                            ADB_DUMP, FAST, &buffer);
+    EXPECT_GT(buffer.size(), 0);
+    EXPECT_TRUE(reports.ParseFromArray(&buffer[0], buffer.size()));
+    backfillDimensionPath(&reports);
+    backfillStringInReport(&reports);
+    backfillStartEndTimestamp(&reports);
+
+    EXPECT_EQ(1, reports.reports_size());
+    EXPECT_EQ(1, reports.reports(0).metrics_size());
+    EXPECT_EQ(1, reports.reports(0).metrics(0).duration_metrics().data_size());
+
+    auto data = reports.reports(0).metrics(0).duration_metrics().data(0);
+    // Validate dimension value.
+    ValidateAttributionUidDimension(data.dimensions_in_what(),
+                                    android::util::WAKELOCK_STATE_CHANGED, appUid);
+    // Validate bucket info.
+    EXPECT_EQ(2, data.bucket_info_size());
+
+    auto bucketInfo = data.bucket_info(0);
+    EXPECT_EQ(bucketStartTimeNs, bucketInfo.start_bucket_elapsed_nanos());
+    EXPECT_EQ(durationEndNs, bucketInfo.end_bucket_elapsed_nanos());
+    EXPECT_EQ(durationEndNs - durationStartNs, bucketInfo.duration_nanos());
+
+    bucketInfo = data.bucket_info(1);
+    EXPECT_EQ(durationEndNs, bucketInfo.start_bucket_elapsed_nanos());
+    EXPECT_EQ(bucketStartTimeNs + bucketSizeNs, bucketInfo.end_bucket_elapsed_nanos());
+    EXPECT_EQ(bucketStartTimeNs + bucketSizeNs - duration2StartNs, bucketInfo.duration_nanos());
+}
+
+#else
+GTEST_LOG_(INFO) << "This test does nothing.\n";
+#endif
+
+}  // namespace statsd
+}  // namespace os
+}  // namespace android
diff --git a/cmds/statsd/tests/e2e/GaugeMetric_e2e_pull_test.cpp b/cmds/statsd/tests/e2e/GaugeMetric_e2e_pull_test.cpp
index 6ec0a11..c7ba9be 100644
--- a/cmds/statsd/tests/e2e/GaugeMetric_e2e_pull_test.cpp
+++ b/cmds/statsd/tests/e2e/GaugeMetric_e2e_pull_test.cpp
@@ -446,22 +446,23 @@
 
     // Pulling alarm arrives on time and reset the sequential pulling alarm.
     // Event should not be kept.
-    processor->informPullAlarmFired(nextPullTimeNs + 1);
+    processor->informPullAlarmFired(nextPullTimeNs + 1); // 15 mins + 1 ns.
     EXPECT_EQ(baseTimeNs + startBucketNum * bucketSizeNs + 2 * bucketSizeNs, nextPullTimeNs);
     EXPECT_FALSE(processor->mMetricsManagers.begin()->second->mAllMetricProducers[0]->isActive());
 
+    // Activate the metric. A pull occurs upon activation.
     const int64_t activationNs = configAddedTimeNs + bucketSizeNs + (2 * 1000 * 1000); // 2 millis.
     auto batterySaverOnEvent = CreateBatterySaverOnEvent(activationNs);
-    processor->OnLogEvent(batterySaverOnEvent.get());
+    processor->OnLogEvent(batterySaverOnEvent.get()); // 15 mins + 2 ms.
     EXPECT_TRUE(processor->mMetricsManagers.begin()->second->mAllMetricProducers[0]->isActive());
 
-    // This event should be kept. 1 total.
-    processor->informPullAlarmFired(nextPullTimeNs + 1);
+    // This event should be kept. 2 total.
+    processor->informPullAlarmFired(nextPullTimeNs + 1); // 20 mins + 1 ns.
     EXPECT_EQ(baseTimeNs + startBucketNum * bucketSizeNs + 3 * bucketSizeNs,
               nextPullTimeNs);
 
-    // This event should be kept. 2 total.
-    processor->informPullAlarmFired(nextPullTimeNs + 2);
+    // This event should be kept. 3 total.
+    processor->informPullAlarmFired(nextPullTimeNs + 2); // 25 mins + 2 ns.
     EXPECT_EQ(baseTimeNs + startBucketNum * bucketSizeNs + 4 * bucketSizeNs, nextPullTimeNs);
 
     // Create random event to deactivate metric.
@@ -469,7 +470,7 @@
     processor->OnLogEvent(deactivationEvent.get());
     EXPECT_FALSE(processor->mMetricsManagers.begin()->second->mAllMetricProducers[0]->isActive());
 
-    // Event should not be kept. 2 total.
+    // Event should not be kept. 3 total.
     processor->informPullAlarmFired(nextPullTimeNs + 3);
     EXPECT_EQ(baseTimeNs + startBucketNum * bucketSizeNs + 5 * bucketSizeNs, nextPullTimeNs);
 
@@ -497,27 +498,39 @@
     EXPECT_EQ(1 /* subsystem name field */,
               data.dimensions_in_what().value_tuple().dimensions_value(0).field());
     EXPECT_FALSE(data.dimensions_in_what().value_tuple().dimensions_value(0).value_str().empty());
-    EXPECT_EQ(2, data.bucket_info_size());
+    EXPECT_EQ(3, data.bucket_info_size());
 
-    EXPECT_EQ(1, data.bucket_info(0).atom_size());
-    EXPECT_EQ(1, data.bucket_info(0).elapsed_timestamp_nanos_size());
-    EXPECT_EQ(baseTimeNs + 4 * bucketSizeNs + 1, data.bucket_info(0).elapsed_timestamp_nanos(0));
-    EXPECT_EQ(0, data.bucket_info(0).wall_clock_timestamp_nanos_size());
-    EXPECT_EQ(baseTimeNs + 4 * bucketSizeNs, data.bucket_info(0).start_bucket_elapsed_nanos());
-    EXPECT_EQ(baseTimeNs + 5 * bucketSizeNs, data.bucket_info(0).end_bucket_elapsed_nanos());
-    EXPECT_TRUE(data.bucket_info(0).atom(0).subsystem_sleep_state().subsystem_name().empty());
-    EXPECT_GT(data.bucket_info(0).atom(0).subsystem_sleep_state().time_millis(), 0);
+    auto bucketInfo = data.bucket_info(0);
+    EXPECT_EQ(1, bucketInfo.atom_size());
+    EXPECT_EQ(1, bucketInfo.elapsed_timestamp_nanos_size());
+    EXPECT_EQ(activationNs, bucketInfo.elapsed_timestamp_nanos(0));
+    EXPECT_EQ(0, bucketInfo.wall_clock_timestamp_nanos_size());
+    EXPECT_EQ(baseTimeNs + 3 * bucketSizeNs, bucketInfo.start_bucket_elapsed_nanos());
+    EXPECT_EQ(baseTimeNs + 4 * bucketSizeNs, bucketInfo.end_bucket_elapsed_nanos());
+    EXPECT_TRUE(bucketInfo.atom(0).subsystem_sleep_state().subsystem_name().empty());
+    EXPECT_GT(bucketInfo.atom(0).subsystem_sleep_state().time_millis(), 0);
 
-    EXPECT_EQ(1, data.bucket_info(1).atom_size());
-    EXPECT_EQ(1, data.bucket_info(1).elapsed_timestamp_nanos_size());
-    EXPECT_EQ(baseTimeNs + 5 * bucketSizeNs + 2, data.bucket_info(1).elapsed_timestamp_nanos(0));
-    EXPECT_EQ(0, data.bucket_info(1).wall_clock_timestamp_nanos_size());
+    bucketInfo = data.bucket_info(1);
+    EXPECT_EQ(1, bucketInfo.atom_size());
+    EXPECT_EQ(1, bucketInfo.elapsed_timestamp_nanos_size());
+    EXPECT_EQ(baseTimeNs + 4 * bucketSizeNs + 1, bucketInfo.elapsed_timestamp_nanos(0));
+    EXPECT_EQ(0, bucketInfo.wall_clock_timestamp_nanos_size());
+    EXPECT_EQ(baseTimeNs + 4 * bucketSizeNs, bucketInfo.start_bucket_elapsed_nanos());
+    EXPECT_EQ(baseTimeNs + 5 * bucketSizeNs, bucketInfo.end_bucket_elapsed_nanos());
+    EXPECT_TRUE(bucketInfo.atom(0).subsystem_sleep_state().subsystem_name().empty());
+    EXPECT_GT(bucketInfo.atom(0).subsystem_sleep_state().time_millis(), 0);
+
+    bucketInfo = data.bucket_info(2);
+    EXPECT_EQ(1, bucketInfo.atom_size());
+    EXPECT_EQ(1, bucketInfo.elapsed_timestamp_nanos_size());
+    EXPECT_EQ(baseTimeNs + 5 * bucketSizeNs + 2, bucketInfo.elapsed_timestamp_nanos(0));
+    EXPECT_EQ(0, bucketInfo.wall_clock_timestamp_nanos_size());
     EXPECT_EQ(MillisToNano(NanoToMillis(baseTimeNs + 5 * bucketSizeNs)),
-            data.bucket_info(1).start_bucket_elapsed_nanos());
+            bucketInfo.start_bucket_elapsed_nanos());
     EXPECT_EQ(MillisToNano(NanoToMillis(activationNs + ttlNs + 1)),
-            data.bucket_info(1).end_bucket_elapsed_nanos());
-    EXPECT_TRUE(data.bucket_info(1).atom(0).subsystem_sleep_state().subsystem_name().empty());
-    EXPECT_GT(data.bucket_info(1).atom(0).subsystem_sleep_state().time_millis(), 0);
+            bucketInfo.end_bucket_elapsed_nanos());
+    EXPECT_TRUE(bucketInfo.atom(0).subsystem_sleep_state().subsystem_name().empty());
+    EXPECT_GT(bucketInfo.atom(0).subsystem_sleep_state().time_millis(), 0);
 }
 
 TEST(GaugeMetricE2eTest, TestRandomSamplePulledEventsNoCondition) {
diff --git a/cmds/statsd/tests/e2e/MetricActivation_e2e_test.cpp b/cmds/statsd/tests/e2e/MetricActivation_e2e_test.cpp
index d99d281..f1b6029 100644
--- a/cmds/statsd/tests/e2e/MetricActivation_e2e_test.cpp
+++ b/cmds/statsd/tests/e2e/MetricActivation_e2e_test.cpp
@@ -134,6 +134,42 @@
     return config;
 }
 
+StatsdConfig CreateStatsdConfigWithSameDeactivations() {
+    StatsdConfig config;
+    config.add_allowed_log_source("AID_ROOT"); // LogEvent defaults to UID of root.
+    auto saverModeMatcher = CreateBatterySaverModeStartAtomMatcher();
+    auto crashMatcher = CreateProcessCrashAtomMatcher();
+    auto screenOnMatcher = CreateScreenTurnedOnAtomMatcher();
+    auto brightnessChangedMatcher = CreateScreenBrightnessChangedAtomMatcher();
+
+    *config.add_atom_matcher() = saverModeMatcher;
+    *config.add_atom_matcher() = crashMatcher;
+    *config.add_atom_matcher() = screenOnMatcher;
+    *config.add_atom_matcher() = brightnessChangedMatcher;
+
+    int64_t metricId = 123456;
+    auto countMetric = config.add_count_metric();
+    countMetric->set_id(metricId);
+    countMetric->set_what(crashMatcher.id());
+    countMetric->set_bucket(FIVE_MINUTES);
+    countMetric->mutable_dimensions_in_what()->set_field(
+        android::util::PROCESS_LIFE_CYCLE_STATE_CHANGED);
+    countMetric->mutable_dimensions_in_what()->add_child()->set_field(1);  // uid field
+
+    auto metric_activation1 = config.add_metric_activation();
+    metric_activation1->set_metric_id(metricId);
+    auto event_activation1 = metric_activation1->add_event_activation();
+    event_activation1->set_atom_matcher_id(saverModeMatcher.id());
+    event_activation1->set_ttl_seconds(60 * 6);  // 6 minutes
+    event_activation1->set_deactivation_atom_matcher_id(brightnessChangedMatcher.id());
+    auto event_activation2 = metric_activation1->add_event_activation();
+    event_activation2->set_atom_matcher_id(screenOnMatcher.id());
+    event_activation2->set_ttl_seconds(60 * 2);  // 2 minutes
+    event_activation2->set_deactivation_atom_matcher_id(brightnessChangedMatcher.id());
+
+    return config;
+}
+
 StatsdConfig CreateStatsdConfigWithTwoMetricsTwoDeactivations() {
     StatsdConfig config;
     config.add_allowed_log_source("AID_ROOT"); // LogEvent defaults to UID of root.
@@ -467,7 +503,8 @@
     EXPECT_EQ(eventActivationMap[2]->ttl_ns, 60 * 2 * NS_PER_SEC);
     EXPECT_EQ(eventDeactivationMap.size(), 1u);
     EXPECT_TRUE(eventDeactivationMap.find(3) != eventDeactivationMap.end());
-    EXPECT_EQ(eventDeactivationMap[3], eventActivationMap[0]);
+    EXPECT_EQ(eventDeactivationMap[3].size(), 1u);
+    EXPECT_EQ(eventDeactivationMap[3][0], eventActivationMap[0]);
 
     std::unique_ptr<LogEvent> event;
 
@@ -491,7 +528,7 @@
     EXPECT_EQ(eventActivationMap[2]->state, ActivationState::kNotActive);
     EXPECT_EQ(eventActivationMap[2]->start_ns, 0);
     EXPECT_EQ(eventActivationMap[2]->ttl_ns, 60 * 2 * NS_PER_SEC);
-    EXPECT_EQ(eventDeactivationMap[3], eventActivationMap[0]);
+    EXPECT_EQ(eventDeactivationMap[3][0], eventActivationMap[0]);
 
     // First processed event.
     event = CreateAppCrashEvent(222, bucketStartTimeNs + 15);
@@ -509,7 +546,7 @@
     EXPECT_EQ(eventActivationMap[2]->state, ActivationState::kActive);
     EXPECT_EQ(eventActivationMap[2]->start_ns, bucketStartTimeNs + 20);
     EXPECT_EQ(eventActivationMap[2]->ttl_ns, 60 * 2 * NS_PER_SEC);
-    EXPECT_EQ(eventDeactivationMap[3], eventActivationMap[0]);
+    EXPECT_EQ(eventDeactivationMap[3][0], eventActivationMap[0]);
 
     // 2nd processed event.
     // The activation by screen_on event expires, but the one by battery save mode is still active.
@@ -523,7 +560,7 @@
     EXPECT_EQ(eventActivationMap[2]->state, ActivationState::kNotActive);
     EXPECT_EQ(eventActivationMap[2]->start_ns, bucketStartTimeNs + 20);
     EXPECT_EQ(eventActivationMap[2]->ttl_ns, 60 * 2 * NS_PER_SEC);
-    EXPECT_EQ(eventDeactivationMap[3], eventActivationMap[0]);
+    EXPECT_EQ(eventDeactivationMap[3][0], eventActivationMap[0]);
     // No new broadcast since the config should still be active.
     EXPECT_EQ(broadcastCount, 1);
 
@@ -545,7 +582,7 @@
     EXPECT_EQ(eventActivationMap[2]->state, ActivationState::kNotActive);
     EXPECT_EQ(eventActivationMap[2]->start_ns, bucketStartTimeNs + 20);
     EXPECT_EQ(eventActivationMap[2]->ttl_ns, 60 * 2 * NS_PER_SEC);
-    EXPECT_EQ(eventDeactivationMap[3], eventActivationMap[0]);
+    EXPECT_EQ(eventDeactivationMap[3][0], eventActivationMap[0]);
 
     // Re-activate metric via screen on.
     event = CreateScreenStateChangedEvent(android::view::DISPLAY_STATE_ON,
@@ -562,7 +599,7 @@
     EXPECT_EQ(eventActivationMap[2]->state, ActivationState::kActive);
     EXPECT_EQ(eventActivationMap[2]->start_ns, bucketStartTimeNs + NS_PER_SEC * 60 * 10 + 10);
     EXPECT_EQ(eventActivationMap[2]->ttl_ns, 60 * 2 * NS_PER_SEC);
-    EXPECT_EQ(eventDeactivationMap[3], eventActivationMap[0]);
+    EXPECT_EQ(eventDeactivationMap[3][0], eventActivationMap[0]);
 
     // 4th processed event.
     event = CreateAppCrashEvent(666, bucketStartTimeNs + NS_PER_SEC * 60 * 11 + 1);
@@ -582,7 +619,7 @@
     EXPECT_EQ(eventActivationMap[2]->state, ActivationState::kActive);
     EXPECT_EQ(eventActivationMap[2]->start_ns, bucketStartTimeNs + NS_PER_SEC * 60 * 10 + 10);
     EXPECT_EQ(eventActivationMap[2]->ttl_ns, 60 * 2 * NS_PER_SEC);
-    EXPECT_EQ(eventDeactivationMap[3], eventActivationMap[0]);
+    EXPECT_EQ(eventDeactivationMap[3][0], eventActivationMap[0]);
 
     // 5th processed event.
     event = CreateAppCrashEvent(777, bucketStartTimeNs + NS_PER_SEC * 60 * 11 + 40);
@@ -602,7 +639,7 @@
     EXPECT_EQ(eventActivationMap[2]->state, ActivationState::kActive);
     EXPECT_EQ(eventActivationMap[2]->start_ns, bucketStartTimeNs + NS_PER_SEC * 60 * 10 + 10);
     EXPECT_EQ(eventActivationMap[2]->ttl_ns, 60 * 2 * NS_PER_SEC);
-    EXPECT_EQ(eventDeactivationMap[3], eventActivationMap[0]);
+    EXPECT_EQ(eventDeactivationMap[3][0], eventActivationMap[0]);
 
     // Screen-on activation expired.
     event = CreateAppCrashEvent(888, bucketStartTimeNs + NS_PER_SEC * 60 * 13);
@@ -618,7 +655,7 @@
     EXPECT_EQ(eventActivationMap[2]->state, ActivationState::kNotActive);
     EXPECT_EQ(eventActivationMap[2]->start_ns, bucketStartTimeNs + NS_PER_SEC * 60 * 10 + 10);
     EXPECT_EQ(eventActivationMap[2]->ttl_ns, 60 * 2 * NS_PER_SEC);
-    EXPECT_EQ(eventDeactivationMap[3], eventActivationMap[0]);
+    EXPECT_EQ(eventDeactivationMap[3][0], eventActivationMap[0]);
 
     event = CreateAppCrashEvent(999, bucketStartTimeNs + NS_PER_SEC * 60 * 14 + 1);
     processor.OnLogEvent(event.get());
@@ -637,7 +674,7 @@
     EXPECT_EQ(eventActivationMap[2]->state, ActivationState::kNotActive);
     EXPECT_EQ(eventActivationMap[2]->start_ns, bucketStartTimeNs + NS_PER_SEC * 60 * 10 + 10);
     EXPECT_EQ(eventActivationMap[2]->ttl_ns, 60 * 2 * NS_PER_SEC);
-    EXPECT_EQ(eventDeactivationMap[3], eventActivationMap[0]);
+    EXPECT_EQ(eventDeactivationMap[3][0], eventActivationMap[0]);
 
     // Cancel battery saver mode activation.
     event = CreateScreenBrightnessChangedEvent(140, bucketStartTimeNs + NS_PER_SEC * 60 * 16);
@@ -652,7 +689,7 @@
     EXPECT_EQ(eventActivationMap[2]->state, ActivationState::kNotActive);
     EXPECT_EQ(eventActivationMap[2]->start_ns, bucketStartTimeNs + NS_PER_SEC * 60 * 10 + 10);
     EXPECT_EQ(eventActivationMap[2]->ttl_ns, 60 * 2 * NS_PER_SEC);
-    EXPECT_EQ(eventDeactivationMap[3], eventActivationMap[0]);
+    EXPECT_EQ(eventDeactivationMap[3][0], eventActivationMap[0]);
 
     ConfigMetricsReportList reports;
     vector<uint8_t> buffer;
@@ -790,8 +827,10 @@
     EXPECT_EQ(eventDeactivationMap.size(), 2u);
     EXPECT_TRUE(eventDeactivationMap.find(3) != eventDeactivationMap.end());
     EXPECT_TRUE(eventDeactivationMap.find(4) != eventDeactivationMap.end());
-    EXPECT_EQ(eventDeactivationMap[3], eventActivationMap[0]);
-    EXPECT_EQ(eventDeactivationMap[4], eventActivationMap[2]);
+    EXPECT_EQ(eventDeactivationMap[3].size(), 1u);
+    EXPECT_EQ(eventDeactivationMap[4].size(), 1u);
+    EXPECT_EQ(eventDeactivationMap[3][0], eventActivationMap[0]);
+    EXPECT_EQ(eventDeactivationMap[4][0], eventActivationMap[2]);
 
     std::unique_ptr<LogEvent> event;
 
@@ -815,8 +854,8 @@
     EXPECT_EQ(eventActivationMap[2]->state, ActivationState::kNotActive);
     EXPECT_EQ(eventActivationMap[2]->start_ns, 0);
     EXPECT_EQ(eventActivationMap[2]->ttl_ns, 60 * 2 * NS_PER_SEC);
-    EXPECT_EQ(eventDeactivationMap[3], eventActivationMap[0]);
-    EXPECT_EQ(eventDeactivationMap[4], eventActivationMap[2]);
+    EXPECT_EQ(eventDeactivationMap[3][0], eventActivationMap[0]);
+    EXPECT_EQ(eventDeactivationMap[4][0], eventActivationMap[2]);
 
     // First processed event.
     event = CreateAppCrashEvent(222, bucketStartTimeNs + 15);
@@ -834,8 +873,8 @@
     EXPECT_EQ(eventActivationMap[2]->state, ActivationState::kActive);
     EXPECT_EQ(eventActivationMap[2]->start_ns, bucketStartTimeNs + 20);
     EXPECT_EQ(eventActivationMap[2]->ttl_ns, 60 * 2 * NS_PER_SEC);
-    EXPECT_EQ(eventDeactivationMap[3], eventActivationMap[0]);
-    EXPECT_EQ(eventDeactivationMap[4], eventActivationMap[2]);
+    EXPECT_EQ(eventDeactivationMap[3][0], eventActivationMap[0]);
+    EXPECT_EQ(eventDeactivationMap[4][0], eventActivationMap[2]);
 
     // 2nd processed event.
     // The activation by screen_on event expires, but the one by battery save mode is still active.
@@ -849,8 +888,8 @@
     EXPECT_EQ(eventActivationMap[2]->state, ActivationState::kNotActive);
     EXPECT_EQ(eventActivationMap[2]->start_ns, bucketStartTimeNs + 20);
     EXPECT_EQ(eventActivationMap[2]->ttl_ns, 60 * 2 * NS_PER_SEC);
-    EXPECT_EQ(eventDeactivationMap[3], eventActivationMap[0]);
-    EXPECT_EQ(eventDeactivationMap[4], eventActivationMap[2]);
+    EXPECT_EQ(eventDeactivationMap[3][0], eventActivationMap[0]);
+    EXPECT_EQ(eventDeactivationMap[4][0], eventActivationMap[2]);
     // No new broadcast since the config should still be active.
     EXPECT_EQ(broadcastCount, 1);
 
@@ -872,8 +911,8 @@
     EXPECT_EQ(eventActivationMap[2]->state, ActivationState::kNotActive);
     EXPECT_EQ(eventActivationMap[2]->start_ns, bucketStartTimeNs + 20);
     EXPECT_EQ(eventActivationMap[2]->ttl_ns, 60 * 2 * NS_PER_SEC);
-    EXPECT_EQ(eventDeactivationMap[3], eventActivationMap[0]);
-    EXPECT_EQ(eventDeactivationMap[4], eventActivationMap[2]);
+    EXPECT_EQ(eventDeactivationMap[3][0], eventActivationMap[0]);
+    EXPECT_EQ(eventDeactivationMap[4][0], eventActivationMap[2]);
 
     // Re-activate metric via screen on.
     event = CreateScreenStateChangedEvent(android::view::DISPLAY_STATE_ON,
@@ -890,8 +929,8 @@
     EXPECT_EQ(eventActivationMap[2]->state, ActivationState::kActive);
     EXPECT_EQ(eventActivationMap[2]->start_ns, bucketStartTimeNs + NS_PER_SEC * 60 * 10 + 10);
     EXPECT_EQ(eventActivationMap[2]->ttl_ns, 60 * 2 * NS_PER_SEC);
-    EXPECT_EQ(eventDeactivationMap[3], eventActivationMap[0]);
-    EXPECT_EQ(eventDeactivationMap[4], eventActivationMap[2]);
+    EXPECT_EQ(eventDeactivationMap[3][0], eventActivationMap[0]);
+    EXPECT_EQ(eventDeactivationMap[4][0], eventActivationMap[2]);
 
     // 4th processed event.
     event = CreateAppCrashEvent(666, bucketStartTimeNs + NS_PER_SEC * 60 * 11 + 1);
@@ -911,8 +950,8 @@
     EXPECT_EQ(eventActivationMap[2]->state, ActivationState::kActive);
     EXPECT_EQ(eventActivationMap[2]->start_ns, bucketStartTimeNs + NS_PER_SEC * 60 * 10 + 10);
     EXPECT_EQ(eventActivationMap[2]->ttl_ns, 60 * 2 * NS_PER_SEC);
-    EXPECT_EQ(eventDeactivationMap[3], eventActivationMap[0]);
-    EXPECT_EQ(eventDeactivationMap[4], eventActivationMap[2]);
+    EXPECT_EQ(eventDeactivationMap[3][0], eventActivationMap[0]);
+    EXPECT_EQ(eventDeactivationMap[4][0], eventActivationMap[2]);
 
     // 5th processed event.
     event = CreateAppCrashEvent(777, bucketStartTimeNs + NS_PER_SEC * 60 * 11 + 40);
@@ -932,8 +971,8 @@
     EXPECT_EQ(eventActivationMap[2]->state, ActivationState::kNotActive);
     EXPECT_EQ(eventActivationMap[2]->start_ns, bucketStartTimeNs + NS_PER_SEC * 60 * 10 + 10);
     EXPECT_EQ(eventActivationMap[2]->ttl_ns, 60 * 2 * NS_PER_SEC);
-    EXPECT_EQ(eventDeactivationMap[3], eventActivationMap[0]);
-    EXPECT_EQ(eventDeactivationMap[4], eventActivationMap[2]);
+    EXPECT_EQ(eventDeactivationMap[3][0], eventActivationMap[0]);
+    EXPECT_EQ(eventDeactivationMap[4][0], eventActivationMap[2]);
 
     // Screen-on activation expired.
     event = CreateAppCrashEvent(888, bucketStartTimeNs + NS_PER_SEC * 60 * 13);
@@ -948,8 +987,8 @@
     EXPECT_EQ(eventActivationMap[2]->state, ActivationState::kNotActive);
     EXPECT_EQ(eventActivationMap[2]->start_ns, bucketStartTimeNs + NS_PER_SEC * 60 * 10 + 10);
     EXPECT_EQ(eventActivationMap[2]->ttl_ns, 60 * 2 * NS_PER_SEC);
-    EXPECT_EQ(eventDeactivationMap[3], eventActivationMap[0]);
-    EXPECT_EQ(eventDeactivationMap[4], eventActivationMap[2]);
+    EXPECT_EQ(eventDeactivationMap[3][0], eventActivationMap[0]);
+    EXPECT_EQ(eventDeactivationMap[4][0], eventActivationMap[2]);
 
     event = CreateAppCrashEvent(999, bucketStartTimeNs + NS_PER_SEC * 60 * 14 + 1);
     processor.OnLogEvent(event.get());
@@ -968,8 +1007,8 @@
     EXPECT_EQ(eventActivationMap[2]->state, ActivationState::kNotActive);
     EXPECT_EQ(eventActivationMap[2]->start_ns, bucketStartTimeNs + NS_PER_SEC * 60 * 10 + 10);
     EXPECT_EQ(eventActivationMap[2]->ttl_ns, 60 * 2 * NS_PER_SEC);
-    EXPECT_EQ(eventDeactivationMap[3], eventActivationMap[0]);
-    EXPECT_EQ(eventDeactivationMap[4], eventActivationMap[2]);
+    EXPECT_EQ(eventDeactivationMap[3][0], eventActivationMap[0]);
+    EXPECT_EQ(eventDeactivationMap[4][0], eventActivationMap[2]);
 
     // Cancel battery saver mode and screen on activation.
     event = CreateScreenBrightnessChangedEvent(140, bucketStartTimeNs + NS_PER_SEC * 60 * 16);
@@ -984,8 +1023,8 @@
     EXPECT_EQ(eventActivationMap[2]->state, ActivationState::kNotActive);
     EXPECT_EQ(eventActivationMap[2]->start_ns, bucketStartTimeNs + NS_PER_SEC * 60 * 10 + 10);
     EXPECT_EQ(eventActivationMap[2]->ttl_ns, 60 * 2 * NS_PER_SEC);
-    EXPECT_EQ(eventDeactivationMap[3], eventActivationMap[0]);
-    EXPECT_EQ(eventDeactivationMap[4], eventActivationMap[2]);
+    EXPECT_EQ(eventDeactivationMap[3][0], eventActivationMap[0]);
+    EXPECT_EQ(eventDeactivationMap[4][0], eventActivationMap[2]);
 
     ConfigMetricsReportList reports;
     vector<uint8_t> buffer;
@@ -1066,6 +1105,203 @@
               data.bucket_info(0).end_bucket_elapsed_nanos());
 }
 
+TEST(MetricActivationE2eTest, TestCountMetricWithSameDeactivation) {
+    auto config = CreateStatsdConfigWithSameDeactivations();
+
+    int64_t bucketStartTimeNs = NS_PER_SEC * 10; // 10 secs
+    int64_t bucketSizeNs =
+            TimeUnitToBucketSizeInMillis(config.count_metric(0).bucket()) * 1000LL * 1000LL;
+
+    int uid = 12345;
+    int64_t cfgId = 98765;
+    ConfigKey cfgKey(uid, cfgId);
+
+    sp<UidMap> m = new UidMap();
+    sp<StatsPullerManager> pullerManager = new StatsPullerManager();
+    sp<AlarmMonitor> anomalyAlarmMonitor;
+    sp<AlarmMonitor> subscriberAlarmMonitor;
+    vector<int64_t> activeConfigsBroadcast;
+
+    long timeBase1 = 1;
+    int broadcastCount = 0;
+    StatsLogProcessor processor(m, pullerManager, anomalyAlarmMonitor, subscriberAlarmMonitor,
+            bucketStartTimeNs, [](const ConfigKey& key) { return true; },
+            [&uid, &broadcastCount, &activeConfigsBroadcast](const int& broadcastUid,
+                    const vector<int64_t>& activeConfigs) {
+                broadcastCount++;
+                EXPECT_EQ(broadcastUid, uid);
+                activeConfigsBroadcast.clear();
+                activeConfigsBroadcast.insert(activeConfigsBroadcast.end(),
+                        activeConfigs.begin(), activeConfigs.end());
+                return true;
+            });
+
+    processor.OnConfigUpdated(bucketStartTimeNs, cfgKey, config);
+
+    EXPECT_EQ(processor.mMetricsManagers.size(), 1u);
+    sp<MetricsManager> metricsManager = processor.mMetricsManagers.begin()->second;
+    EXPECT_TRUE(metricsManager->isConfigValid());
+    EXPECT_EQ(metricsManager->mAllMetricProducers.size(), 1);
+    sp<MetricProducer> metricProducer = metricsManager->mAllMetricProducers[0];
+    auto& eventActivationMap = metricProducer->mEventActivationMap;
+    auto& eventDeactivationMap = metricProducer->mEventDeactivationMap;
+
+    EXPECT_FALSE(metricsManager->isActive());
+    EXPECT_FALSE(metricProducer->mIsActive);
+    // Two activations: one is triggered by battery saver mode (tracker index 0), the other is
+    // triggered by screen on event (tracker index 2).
+    EXPECT_EQ(eventActivationMap.size(), 2u);
+    EXPECT_TRUE(eventActivationMap.find(0) != eventActivationMap.end());
+    EXPECT_TRUE(eventActivationMap.find(2) != eventActivationMap.end());
+    EXPECT_EQ(eventActivationMap[0]->state, ActivationState::kNotActive);
+    EXPECT_EQ(eventActivationMap[0]->start_ns, 0);
+    EXPECT_EQ(eventActivationMap[0]->ttl_ns, 60 * 6 * NS_PER_SEC);
+    EXPECT_EQ(eventActivationMap[2]->state, ActivationState::kNotActive);
+    EXPECT_EQ(eventActivationMap[2]->start_ns, 0);
+    EXPECT_EQ(eventActivationMap[2]->ttl_ns, 60 * 2 * NS_PER_SEC);
+    EXPECT_EQ(eventDeactivationMap.size(), 1u);
+    EXPECT_TRUE(eventDeactivationMap.find(3) != eventDeactivationMap.end());
+    EXPECT_EQ(eventDeactivationMap[3].size(), 2u);
+    EXPECT_EQ(eventDeactivationMap[3][0], eventActivationMap[0]);
+    EXPECT_EQ(eventDeactivationMap[3][1], eventActivationMap[2]);
+    EXPECT_EQ(broadcastCount, 0);
+
+    std::unique_ptr<LogEvent> event;
+
+    // Event that should be ignored.
+    event = CreateAppCrashEvent(111, bucketStartTimeNs + 1);
+    processor.OnLogEvent(event.get());
+
+    // Activate metric via screen on for 2 minutes.
+    event = CreateScreenStateChangedEvent(android::view::DISPLAY_STATE_ON, bucketStartTimeNs + 10);
+    processor.OnLogEvent(event.get());
+    EXPECT_TRUE(metricsManager->isActive());
+    EXPECT_TRUE(metricProducer->mIsActive);
+    EXPECT_EQ(broadcastCount, 1);
+    EXPECT_EQ(activeConfigsBroadcast.size(), 1);
+    EXPECT_EQ(activeConfigsBroadcast[0], cfgId);
+    EXPECT_EQ(eventActivationMap[0]->state, ActivationState::kNotActive);
+    EXPECT_EQ(eventActivationMap[2]->state, ActivationState::kActive);
+    EXPECT_EQ(eventActivationMap[2]->start_ns, bucketStartTimeNs + 10);
+
+    // 1st processed event.
+    event = CreateAppCrashEvent(222, bucketStartTimeNs + 15);
+    processor.OnLogEvent(event.get());
+
+    // Enable battery saver mode activation for 5 minutes.
+    event = CreateBatterySaverOnEvent(bucketStartTimeNs + NS_PER_SEC * 60 + 10);
+    processor.OnLogEvent(event.get());
+    EXPECT_TRUE(metricsManager->isActive());
+    EXPECT_TRUE(metricProducer->mIsActive);
+    EXPECT_EQ(broadcastCount, 1);
+    EXPECT_EQ(eventActivationMap[0]->state, ActivationState::kActive);
+    EXPECT_EQ(eventActivationMap[0]->start_ns, bucketStartTimeNs + NS_PER_SEC * 60 + 10);
+    EXPECT_EQ(eventActivationMap[2]->state, ActivationState::kActive);
+    EXPECT_EQ(eventActivationMap[2]->start_ns, bucketStartTimeNs + 10);
+
+    // 2nd processed event.
+    event = CreateAppCrashEvent(333, bucketStartTimeNs + NS_PER_SEC * 60 + 40);
+    processor.OnLogEvent(event.get());
+
+    // Cancel battery saver mode and screen on activation.
+    int64_t firstDeactivation = bucketStartTimeNs + NS_PER_SEC * 61;
+    event = CreateScreenBrightnessChangedEvent(64, firstDeactivation);
+    processor.OnLogEvent(event.get());
+    EXPECT_FALSE(metricsManager->isActive());
+    EXPECT_FALSE(metricProducer->mIsActive);
+    // New broadcast since the config is no longer active.
+    EXPECT_EQ(broadcastCount, 2);
+    EXPECT_EQ(activeConfigsBroadcast.size(), 0);
+    EXPECT_EQ(eventActivationMap[0]->state, ActivationState::kNotActive);
+    EXPECT_EQ(eventActivationMap[2]->state, ActivationState::kNotActive);
+
+    // Should be ignored
+    event = CreateAppCrashEvent(444, bucketStartTimeNs + NS_PER_SEC * 61 + 80);
+    processor.OnLogEvent(event.get());
+
+    // Re-enable battery saver mode activation.
+    event = CreateBatterySaverOnEvent(bucketStartTimeNs + NS_PER_SEC * 60 * 10 + 15);
+    processor.OnLogEvent(event.get());
+    EXPECT_TRUE(metricsManager->isActive());
+    EXPECT_TRUE(metricProducer->mIsActive);
+    EXPECT_EQ(broadcastCount, 3);
+    EXPECT_EQ(activeConfigsBroadcast.size(), 1);
+    EXPECT_EQ(activeConfigsBroadcast[0], cfgId);
+    EXPECT_EQ(eventActivationMap[0]->state, ActivationState::kActive);
+    EXPECT_EQ(eventActivationMap[0]->start_ns, bucketStartTimeNs + NS_PER_SEC * 60 * 10 + 15);
+    EXPECT_EQ(eventActivationMap[2]->state, ActivationState::kNotActive);
+
+    // 3rd processed event.
+    event = CreateAppCrashEvent(555, bucketStartTimeNs + NS_PER_SEC * 60 * 10 + 80);
+    processor.OnLogEvent(event.get());
+
+    // Cancel battery saver mode activation.
+    int64_t secondDeactivation = bucketStartTimeNs + NS_PER_SEC * 60 * 13;
+    event = CreateScreenBrightnessChangedEvent(140, secondDeactivation);
+    processor.OnLogEvent(event.get());
+    EXPECT_FALSE(metricsManager->isActive());
+    EXPECT_FALSE(metricProducer->mIsActive);
+    EXPECT_EQ(broadcastCount, 4);
+    EXPECT_EQ(activeConfigsBroadcast.size(), 0);
+    EXPECT_EQ(eventActivationMap[0]->state, ActivationState::kNotActive);
+    EXPECT_EQ(eventActivationMap[2]->state, ActivationState::kNotActive);
+
+    // Should be ignored.
+    event = CreateAppCrashEvent(666, bucketStartTimeNs + NS_PER_SEC * 60 * 13 + 80);
+    processor.OnLogEvent(event.get());
+
+    ConfigMetricsReportList reports;
+    vector<uint8_t> buffer;
+    processor.onDumpReport(cfgKey, bucketStartTimeNs + NS_PER_SEC * 60 * 15 + 1, false, true,
+                            ADB_DUMP, FAST, &buffer);
+    EXPECT_TRUE(buffer.size() > 0);
+    EXPECT_TRUE(reports.ParseFromArray(&buffer[0], buffer.size()));
+    backfillDimensionPath(&reports);
+    backfillStartEndTimestamp(&reports);
+    EXPECT_EQ(1, reports.reports_size());
+    EXPECT_EQ(1, reports.reports(0).metrics_size());
+    EXPECT_EQ(3, reports.reports(0).metrics(0).count_metrics().data_size());
+
+    StatsLogReport::CountMetricDataWrapper countMetrics;
+    sortMetricDataByDimensionsValue(
+            reports.reports(0).metrics(0).count_metrics(), &countMetrics);
+    EXPECT_EQ(3, countMetrics.data_size());
+
+    auto data = countMetrics.data(0);
+    EXPECT_EQ(android::util::PROCESS_LIFE_CYCLE_STATE_CHANGED, data.dimensions_in_what().field());
+    EXPECT_EQ(1, data.dimensions_in_what().value_tuple().dimensions_value_size());
+    EXPECT_EQ(1 /* uid field */,
+              data.dimensions_in_what().value_tuple().dimensions_value(0).field());
+    EXPECT_EQ(222, data.dimensions_in_what().value_tuple().dimensions_value(0).value_int());
+    EXPECT_EQ(1, data.bucket_info_size());
+    EXPECT_EQ(1, data.bucket_info(0).count());
+    EXPECT_EQ(bucketStartTimeNs, data.bucket_info(0).start_bucket_elapsed_nanos());
+    EXPECT_EQ(firstDeactivation, data.bucket_info(0).end_bucket_elapsed_nanos());
+
+    data = countMetrics.data(1);
+    EXPECT_EQ(android::util::PROCESS_LIFE_CYCLE_STATE_CHANGED, data.dimensions_in_what().field());
+    EXPECT_EQ(1, data.dimensions_in_what().value_tuple().dimensions_value_size());
+    EXPECT_EQ(1 /* uid field */,
+              data.dimensions_in_what().value_tuple().dimensions_value(0).field());
+    EXPECT_EQ(333, data.dimensions_in_what().value_tuple().dimensions_value(0).value_int());
+    EXPECT_EQ(1, data.bucket_info_size());
+    EXPECT_EQ(1, data.bucket_info(0).count());
+    EXPECT_EQ(bucketStartTimeNs, data.bucket_info(0).start_bucket_elapsed_nanos());
+    EXPECT_EQ(firstDeactivation, data.bucket_info(0).end_bucket_elapsed_nanos());
+
+    data = countMetrics.data(2);
+    EXPECT_EQ(android::util::PROCESS_LIFE_CYCLE_STATE_CHANGED, data.dimensions_in_what().field());
+    EXPECT_EQ(1, data.dimensions_in_what().value_tuple().dimensions_value_size());
+    EXPECT_EQ(1 /* uid field */,
+              data.dimensions_in_what().value_tuple().dimensions_value(0).field());
+    EXPECT_EQ(555, data.dimensions_in_what().value_tuple().dimensions_value(0).value_int());
+    EXPECT_EQ(1, data.bucket_info_size());
+    EXPECT_EQ(1, data.bucket_info(0).count());
+    // Partial bucket as metric is deactivated.
+    EXPECT_EQ(bucketStartTimeNs + 2 * bucketSizeNs, data.bucket_info(0).start_bucket_elapsed_nanos());
+    EXPECT_EQ(secondDeactivation, data.bucket_info(0).end_bucket_elapsed_nanos());
+}
+
 TEST(MetricActivationE2eTest, TestCountMetricWithTwoMetricsTwoDeactivations) {
     auto config = CreateStatsdConfigWithTwoMetricsTwoDeactivations();
 
@@ -1127,8 +1363,10 @@
     EXPECT_EQ(eventDeactivationMap.size(), 2u);
     EXPECT_TRUE(eventDeactivationMap.find(3) != eventDeactivationMap.end());
     EXPECT_TRUE(eventDeactivationMap.find(4) != eventDeactivationMap.end());
-    EXPECT_EQ(eventDeactivationMap[3], eventActivationMap[0]);
-    EXPECT_EQ(eventDeactivationMap[4], eventActivationMap[2]);
+    EXPECT_EQ(eventDeactivationMap[3].size(), 1u);
+    EXPECT_EQ(eventDeactivationMap[4].size(), 1u);
+    EXPECT_EQ(eventDeactivationMap[3][0], eventActivationMap[0]);
+    EXPECT_EQ(eventDeactivationMap[4][0], eventActivationMap[2]);
 
     EXPECT_EQ(eventActivationMap2.size(), 2u);
     EXPECT_TRUE(eventActivationMap2.find(0) != eventActivationMap2.end());
@@ -1142,8 +1380,10 @@
     EXPECT_EQ(eventDeactivationMap2.size(), 2u);
     EXPECT_TRUE(eventDeactivationMap2.find(3) != eventDeactivationMap2.end());
     EXPECT_TRUE(eventDeactivationMap2.find(4) != eventDeactivationMap2.end());
-    EXPECT_EQ(eventDeactivationMap2[3], eventActivationMap2[0]);
-    EXPECT_EQ(eventDeactivationMap2[4], eventActivationMap2[2]);
+    EXPECT_EQ(eventDeactivationMap[3].size(), 1u);
+    EXPECT_EQ(eventDeactivationMap[4].size(), 1u);
+    EXPECT_EQ(eventDeactivationMap2[3][0], eventActivationMap2[0]);
+    EXPECT_EQ(eventDeactivationMap2[4][0], eventActivationMap2[2]);
 
     std::unique_ptr<LogEvent> event;
 
@@ -1170,8 +1410,8 @@
     EXPECT_EQ(eventActivationMap[2]->state, ActivationState::kNotActive);
     EXPECT_EQ(eventActivationMap[2]->start_ns, 0);
     EXPECT_EQ(eventActivationMap[2]->ttl_ns, 60 * 2 * NS_PER_SEC);
-    EXPECT_EQ(eventDeactivationMap[3], eventActivationMap[0]);
-    EXPECT_EQ(eventDeactivationMap[4], eventActivationMap[2]);
+    EXPECT_EQ(eventDeactivationMap[3][0], eventActivationMap[0]);
+    EXPECT_EQ(eventDeactivationMap[4][0], eventActivationMap[2]);
     EXPECT_TRUE(metricProducer2->mIsActive);
     EXPECT_EQ(eventActivationMap2[0]->state, ActivationState::kActive);
     EXPECT_EQ(eventActivationMap2[0]->start_ns, bucketStartTimeNs + 10);
@@ -1179,8 +1419,8 @@
     EXPECT_EQ(eventActivationMap2[2]->state, ActivationState::kNotActive);
     EXPECT_EQ(eventActivationMap2[2]->start_ns, 0);
     EXPECT_EQ(eventActivationMap2[2]->ttl_ns, 60 * 2 * NS_PER_SEC);
-    EXPECT_EQ(eventDeactivationMap2[3], eventActivationMap2[0]);
-    EXPECT_EQ(eventDeactivationMap2[4], eventActivationMap2[2]);
+    EXPECT_EQ(eventDeactivationMap2[3][0], eventActivationMap2[0]);
+    EXPECT_EQ(eventDeactivationMap2[4][0], eventActivationMap2[2]);
 
     // First processed event.
     event = CreateAppCrashEvent(222, bucketStartTimeNs + 15);
@@ -1200,8 +1440,8 @@
     EXPECT_EQ(eventActivationMap[2]->state, ActivationState::kActive);
     EXPECT_EQ(eventActivationMap[2]->start_ns, bucketStartTimeNs + 20);
     EXPECT_EQ(eventActivationMap[2]->ttl_ns, 60 * 2 * NS_PER_SEC);
-    EXPECT_EQ(eventDeactivationMap[3], eventActivationMap[0]);
-    EXPECT_EQ(eventDeactivationMap[4], eventActivationMap[2]);
+    EXPECT_EQ(eventDeactivationMap[3][0], eventActivationMap[0]);
+    EXPECT_EQ(eventDeactivationMap[4][0], eventActivationMap[2]);
     EXPECT_TRUE(metricProducer2->mIsActive);
     EXPECT_EQ(eventActivationMap2[0]->state, ActivationState::kActive);
     EXPECT_EQ(eventActivationMap2[0]->start_ns, bucketStartTimeNs + 10);
@@ -1209,8 +1449,8 @@
     EXPECT_EQ(eventActivationMap2[2]->state, ActivationState::kActive);
     EXPECT_EQ(eventActivationMap2[2]->start_ns, bucketStartTimeNs + 20);
     EXPECT_EQ(eventActivationMap2[2]->ttl_ns, 60 * 2 * NS_PER_SEC);
-    EXPECT_EQ(eventDeactivationMap2[3], eventActivationMap2[0]);
-    EXPECT_EQ(eventDeactivationMap2[4], eventActivationMap2[2]);
+    EXPECT_EQ(eventDeactivationMap2[3][0], eventActivationMap2[0]);
+    EXPECT_EQ(eventDeactivationMap2[4][0], eventActivationMap2[2]);
 
     // 2nd processed event.
     // The activation by screen_on event expires, but the one by battery save mode is still active.
@@ -1226,8 +1466,8 @@
     EXPECT_EQ(eventActivationMap[2]->state, ActivationState::kNotActive);
     EXPECT_EQ(eventActivationMap[2]->start_ns, bucketStartTimeNs + 20);
     EXPECT_EQ(eventActivationMap[2]->ttl_ns, 60 * 2 * NS_PER_SEC);
-    EXPECT_EQ(eventDeactivationMap[3], eventActivationMap[0]);
-    EXPECT_EQ(eventDeactivationMap[4], eventActivationMap[2]);
+    EXPECT_EQ(eventDeactivationMap[3][0], eventActivationMap[0]);
+    EXPECT_EQ(eventDeactivationMap[4][0], eventActivationMap[2]);
     EXPECT_TRUE(metricProducer2->mIsActive);
     EXPECT_EQ(eventActivationMap2[0]->state, ActivationState::kActive);
     EXPECT_EQ(eventActivationMap2[0]->start_ns, bucketStartTimeNs + 10);
@@ -1235,8 +1475,8 @@
     EXPECT_EQ(eventActivationMap2[2]->state, ActivationState::kNotActive);
     EXPECT_EQ(eventActivationMap2[2]->start_ns, bucketStartTimeNs + 20);
     EXPECT_EQ(eventActivationMap2[2]->ttl_ns, 60 * 2 * NS_PER_SEC);
-    EXPECT_EQ(eventDeactivationMap2[3], eventActivationMap2[0]);
-    EXPECT_EQ(eventDeactivationMap2[4], eventActivationMap2[2]);
+    EXPECT_EQ(eventDeactivationMap2[3][0], eventActivationMap2[0]);
+    EXPECT_EQ(eventDeactivationMap2[4][0], eventActivationMap2[2]);
     // No new broadcast since the config should still be active.
     EXPECT_EQ(broadcastCount, 1);
 
@@ -1262,8 +1502,8 @@
     EXPECT_EQ(eventActivationMap[2]->state, ActivationState::kNotActive);
     EXPECT_EQ(eventActivationMap[2]->start_ns, bucketStartTimeNs + 20);
     EXPECT_EQ(eventActivationMap[2]->ttl_ns, 60 * 2 * NS_PER_SEC);
-    EXPECT_EQ(eventDeactivationMap[3], eventActivationMap[0]);
-    EXPECT_EQ(eventDeactivationMap[4], eventActivationMap[2]);
+    EXPECT_EQ(eventDeactivationMap[3][0], eventActivationMap[0]);
+    EXPECT_EQ(eventDeactivationMap[4][0], eventActivationMap[2]);
     EXPECT_FALSE(metricProducer2->mIsActive);
     EXPECT_EQ(eventActivationMap2[0]->state, ActivationState::kNotActive);
     EXPECT_EQ(eventActivationMap2[0]->start_ns, bucketStartTimeNs + 10);
@@ -1271,8 +1511,8 @@
     EXPECT_EQ(eventActivationMap2[2]->state, ActivationState::kNotActive);
     EXPECT_EQ(eventActivationMap2[2]->start_ns, bucketStartTimeNs + 20);
     EXPECT_EQ(eventActivationMap2[2]->ttl_ns, 60 * 2 * NS_PER_SEC);
-    EXPECT_EQ(eventDeactivationMap2[3], eventActivationMap2[0]);
-    EXPECT_EQ(eventDeactivationMap2[4], eventActivationMap2[2]);
+    EXPECT_EQ(eventDeactivationMap2[3][0], eventActivationMap2[0]);
+    EXPECT_EQ(eventDeactivationMap2[4][0], eventActivationMap2[2]);
 
     // Re-activate metric via screen on.
     event = CreateScreenStateChangedEvent(android::view::DISPLAY_STATE_ON,
@@ -1289,8 +1529,8 @@
     EXPECT_EQ(eventActivationMap[2]->state, ActivationState::kActive);
     EXPECT_EQ(eventActivationMap[2]->start_ns, bucketStartTimeNs + NS_PER_SEC * 60 * 10 + 10);
     EXPECT_EQ(eventActivationMap[2]->ttl_ns, 60 * 2 * NS_PER_SEC);
-    EXPECT_EQ(eventDeactivationMap[3], eventActivationMap[0]);
-    EXPECT_EQ(eventDeactivationMap[4], eventActivationMap[2]);
+    EXPECT_EQ(eventDeactivationMap[3][0], eventActivationMap[0]);
+    EXPECT_EQ(eventDeactivationMap[4][0], eventActivationMap[2]);
     EXPECT_TRUE(metricProducer2->mIsActive);
     EXPECT_EQ(eventActivationMap2[0]->state, ActivationState::kNotActive);
     EXPECT_EQ(eventActivationMap2[0]->start_ns, bucketStartTimeNs + 10);
@@ -1298,8 +1538,8 @@
     EXPECT_EQ(eventActivationMap2[2]->state, ActivationState::kActive);
     EXPECT_EQ(eventActivationMap2[2]->start_ns, bucketStartTimeNs + NS_PER_SEC * 60 * 10 + 10);
     EXPECT_EQ(eventActivationMap2[2]->ttl_ns, 60 * 2 * NS_PER_SEC);
-    EXPECT_EQ(eventDeactivationMap2[3], eventActivationMap2[0]);
-    EXPECT_EQ(eventDeactivationMap2[4], eventActivationMap2[2]);
+    EXPECT_EQ(eventDeactivationMap2[3][0], eventActivationMap2[0]);
+    EXPECT_EQ(eventDeactivationMap2[4][0], eventActivationMap2[2]);
 
     // 4th processed event.
     event = CreateAppCrashEvent(666, bucketStartTimeNs + NS_PER_SEC * 60 * 11 + 1);
@@ -1321,8 +1561,8 @@
     EXPECT_EQ(eventActivationMap[2]->state, ActivationState::kActive);
     EXPECT_EQ(eventActivationMap[2]->start_ns, bucketStartTimeNs + NS_PER_SEC * 60 * 10 + 10);
     EXPECT_EQ(eventActivationMap[2]->ttl_ns, 60 * 2 * NS_PER_SEC);
-    EXPECT_EQ(eventDeactivationMap[3], eventActivationMap[0]);
-    EXPECT_EQ(eventDeactivationMap[4], eventActivationMap[2]);
+    EXPECT_EQ(eventDeactivationMap[3][0], eventActivationMap[0]);
+    EXPECT_EQ(eventDeactivationMap[4][0], eventActivationMap[2]);
     EXPECT_TRUE(metricProducer2->mIsActive);
     EXPECT_EQ(eventActivationMap2[0]->state, ActivationState::kActive);
     EXPECT_EQ(eventActivationMap2[0]->start_ns, bucketStartTimeNs + NS_PER_SEC * 60 * 11 + 15);
@@ -1330,8 +1570,8 @@
     EXPECT_EQ(eventActivationMap2[2]->state, ActivationState::kActive);
     EXPECT_EQ(eventActivationMap2[2]->start_ns, bucketStartTimeNs + NS_PER_SEC * 60 * 10 + 10);
     EXPECT_EQ(eventActivationMap2[2]->ttl_ns, 60 * 2 * NS_PER_SEC);
-    EXPECT_EQ(eventDeactivationMap2[3], eventActivationMap2[0]);
-    EXPECT_EQ(eventDeactivationMap2[4], eventActivationMap2[2]);
+    EXPECT_EQ(eventDeactivationMap2[3][0], eventActivationMap2[0]);
+    EXPECT_EQ(eventDeactivationMap2[4][0], eventActivationMap2[2]);
 
     // 5th processed event.
     event = CreateAppCrashEvent(777, bucketStartTimeNs + NS_PER_SEC * 60 * 11 + 40);
@@ -1353,8 +1593,8 @@
     EXPECT_EQ(eventActivationMap[2]->state, ActivationState::kNotActive);
     EXPECT_EQ(eventActivationMap[2]->start_ns, bucketStartTimeNs + NS_PER_SEC * 60 * 10 + 10);
     EXPECT_EQ(eventActivationMap[2]->ttl_ns, 60 * 2 * NS_PER_SEC);
-    EXPECT_EQ(eventDeactivationMap[3], eventActivationMap[0]);
-    EXPECT_EQ(eventDeactivationMap[4], eventActivationMap[2]);
+    EXPECT_EQ(eventDeactivationMap[3][0], eventActivationMap[0]);
+    EXPECT_EQ(eventDeactivationMap[4][0], eventActivationMap[2]);
     EXPECT_FALSE(metricProducer2->mIsActive);
     EXPECT_EQ(eventActivationMap2[0]->state, ActivationState::kNotActive);
     EXPECT_EQ(eventActivationMap2[0]->start_ns, bucketStartTimeNs + NS_PER_SEC * 60 * 11 + 15);
@@ -1362,8 +1602,8 @@
     EXPECT_EQ(eventActivationMap2[2]->state, ActivationState::kNotActive);
     EXPECT_EQ(eventActivationMap2[2]->start_ns, bucketStartTimeNs + NS_PER_SEC * 60 * 10 + 10);
     EXPECT_EQ(eventActivationMap2[2]->ttl_ns, 60 * 2 * NS_PER_SEC);
-    EXPECT_EQ(eventDeactivationMap2[3], eventActivationMap2[0]);
-    EXPECT_EQ(eventDeactivationMap2[4], eventActivationMap2[2]);
+    EXPECT_EQ(eventDeactivationMap2[3][0], eventActivationMap2[0]);
+    EXPECT_EQ(eventDeactivationMap2[4][0], eventActivationMap2[2]);
 
     // Screen-on activation expired.
     event = CreateAppCrashEvent(888, bucketStartTimeNs + NS_PER_SEC * 60 * 13);
@@ -1380,8 +1620,8 @@
     EXPECT_EQ(eventActivationMap[2]->state, ActivationState::kNotActive);
     EXPECT_EQ(eventActivationMap[2]->start_ns, bucketStartTimeNs + NS_PER_SEC * 60 * 10 + 10);
     EXPECT_EQ(eventActivationMap[2]->ttl_ns, 60 * 2 * NS_PER_SEC);
-    EXPECT_EQ(eventDeactivationMap[3], eventActivationMap[0]);
-    EXPECT_EQ(eventDeactivationMap[4], eventActivationMap[2]);
+    EXPECT_EQ(eventDeactivationMap[3][0], eventActivationMap[0]);
+    EXPECT_EQ(eventDeactivationMap[4][0], eventActivationMap[2]);
     EXPECT_FALSE(metricProducer2->mIsActive);
     EXPECT_EQ(eventActivationMap2[0]->state, ActivationState::kNotActive);
     EXPECT_EQ(eventActivationMap2[0]->start_ns, bucketStartTimeNs + NS_PER_SEC * 60 * 11 + 15);
@@ -1389,8 +1629,8 @@
     EXPECT_EQ(eventActivationMap2[2]->state, ActivationState::kNotActive);
     EXPECT_EQ(eventActivationMap2[2]->start_ns, bucketStartTimeNs + NS_PER_SEC * 60 * 10 + 10);
     EXPECT_EQ(eventActivationMap2[2]->ttl_ns, 60 * 2 * NS_PER_SEC);
-    EXPECT_EQ(eventDeactivationMap2[3], eventActivationMap2[0]);
-    EXPECT_EQ(eventDeactivationMap2[4], eventActivationMap2[2]);
+    EXPECT_EQ(eventDeactivationMap2[3][0], eventActivationMap2[0]);
+    EXPECT_EQ(eventDeactivationMap2[4][0], eventActivationMap2[2]);
 
     event = CreateAppCrashEvent(999, bucketStartTimeNs + NS_PER_SEC * 60 * 14 + 1);
     processor.OnLogEvent(event.get());
@@ -1411,8 +1651,8 @@
     EXPECT_EQ(eventActivationMap[2]->state, ActivationState::kNotActive);
     EXPECT_EQ(eventActivationMap[2]->start_ns, bucketStartTimeNs + NS_PER_SEC * 60 * 10 + 10);
     EXPECT_EQ(eventActivationMap[2]->ttl_ns, 60 * 2 * NS_PER_SEC);
-    EXPECT_EQ(eventDeactivationMap[3], eventActivationMap[0]);
-    EXPECT_EQ(eventDeactivationMap[4], eventActivationMap[2]);
+    EXPECT_EQ(eventDeactivationMap[3][0], eventActivationMap[0]);
+    EXPECT_EQ(eventDeactivationMap[4][0], eventActivationMap[2]);
     EXPECT_TRUE(metricProducer2->mIsActive);
     EXPECT_EQ(eventActivationMap2[0]->state, ActivationState::kActive);
     EXPECT_EQ(eventActivationMap2[0]->start_ns, bucketStartTimeNs + NS_PER_SEC * 60 * 15 + 15);
@@ -1420,8 +1660,8 @@
     EXPECT_EQ(eventActivationMap2[2]->state, ActivationState::kNotActive);
     EXPECT_EQ(eventActivationMap2[2]->start_ns, bucketStartTimeNs + NS_PER_SEC * 60 * 10 + 10);
     EXPECT_EQ(eventActivationMap2[2]->ttl_ns, 60 * 2 * NS_PER_SEC);
-    EXPECT_EQ(eventDeactivationMap2[3], eventActivationMap2[0]);
-    EXPECT_EQ(eventDeactivationMap2[4], eventActivationMap2[2]);
+    EXPECT_EQ(eventDeactivationMap2[3][0], eventActivationMap2[0]);
+    EXPECT_EQ(eventDeactivationMap2[4][0], eventActivationMap2[2]);
 
     // Cancel battery saver mode and screen on activation.
     event = CreateScreenBrightnessChangedEvent(140, bucketStartTimeNs + NS_PER_SEC * 60 * 16);
@@ -1436,8 +1676,8 @@
     EXPECT_EQ(eventActivationMap[2]->state, ActivationState::kNotActive);
     EXPECT_EQ(eventActivationMap[2]->start_ns, bucketStartTimeNs + NS_PER_SEC * 60 * 10 + 10);
     EXPECT_EQ(eventActivationMap[2]->ttl_ns, 60 * 2 * NS_PER_SEC);
-    EXPECT_EQ(eventDeactivationMap[3], eventActivationMap[0]);
-    EXPECT_EQ(eventDeactivationMap[4], eventActivationMap[2]);
+    EXPECT_EQ(eventDeactivationMap[3][0], eventActivationMap[0]);
+    EXPECT_EQ(eventDeactivationMap[4][0], eventActivationMap[2]);
     EXPECT_FALSE(metricProducer2->mIsActive);
     EXPECT_EQ(eventActivationMap2[0]->state, ActivationState::kNotActive);
     EXPECT_EQ(eventActivationMap2[0]->start_ns, bucketStartTimeNs + NS_PER_SEC * 60 * 15 + 15);
@@ -1445,8 +1685,8 @@
     EXPECT_EQ(eventActivationMap2[2]->state, ActivationState::kNotActive);
     EXPECT_EQ(eventActivationMap2[2]->start_ns, bucketStartTimeNs + NS_PER_SEC * 60 * 10 + 10);
     EXPECT_EQ(eventActivationMap2[2]->ttl_ns, 60 * 2 * NS_PER_SEC);
-    EXPECT_EQ(eventDeactivationMap2[3], eventActivationMap2[0]);
-    EXPECT_EQ(eventDeactivationMap2[4], eventActivationMap2[2]);
+    EXPECT_EQ(eventDeactivationMap2[3][0], eventActivationMap2[0]);
+    EXPECT_EQ(eventDeactivationMap2[4][0], eventActivationMap2[2]);
 
     ConfigMetricsReportList reports;
     vector<uint8_t> buffer;
diff --git a/cmds/statsd/tests/e2e/ValueMetric_pull_e2e_test.cpp b/cmds/statsd/tests/e2e/ValueMetric_pull_e2e_test.cpp
index ff6af38..fb878dc7 100644
--- a/cmds/statsd/tests/e2e/ValueMetric_pull_e2e_test.cpp
+++ b/cmds/statsd/tests/e2e/ValueMetric_pull_e2e_test.cpp
@@ -306,18 +306,20 @@
     EXPECT_EQ(baseTimeNs + startBucketNum * bucketSizeNs + bucketSizeNs, expectedPullTimeNs);
 
     // Pulling alarm arrives on time and reset the sequential pulling alarm.
-    processor->informPullAlarmFired(expectedPullTimeNs + 1);
+    processor->informPullAlarmFired(expectedPullTimeNs + 1); // 15 mins + 1 ns.
     EXPECT_EQ(baseTimeNs + startBucketNum * bucketSizeNs + 2 * bucketSizeNs, expectedPullTimeNs);
+    EXPECT_FALSE(processor->mMetricsManagers.begin()->second->mAllMetricProducers[0]->isActive());
 
+    // Activate the metric. A pull occurs here
     const int64_t activationNs = configAddedTimeNs + bucketSizeNs + (2 * 1000 * 1000); // 2 millis.
     auto batterySaverOnEvent = CreateBatterySaverOnEvent(activationNs);
-    processor->OnLogEvent(batterySaverOnEvent.get());
+    processor->OnLogEvent(batterySaverOnEvent.get()); // 15 mins + 2 ms.
     EXPECT_TRUE(processor->mMetricsManagers.begin()->second->mAllMetricProducers[0]->isActive());
 
-    processor->informPullAlarmFired(expectedPullTimeNs + 1);
+    processor->informPullAlarmFired(expectedPullTimeNs + 1); // 20 mins + 1 ns.
     EXPECT_EQ(baseTimeNs + startBucketNum * bucketSizeNs + 3 * bucketSizeNs, expectedPullTimeNs);
 
-    processor->informPullAlarmFired(expectedPullTimeNs + 1);
+    processor->informPullAlarmFired(expectedPullTimeNs + 2); // 25 mins + 2 ns.
     EXPECT_EQ(baseTimeNs + startBucketNum * bucketSizeNs + 4 * bucketSizeNs, expectedPullTimeNs);
 
     // Create random event to deactivate metric.
@@ -325,10 +327,11 @@
     processor->OnLogEvent(deactivationEvent.get());
     EXPECT_FALSE(processor->mMetricsManagers.begin()->second->mAllMetricProducers[0]->isActive());
 
-    processor->informPullAlarmFired(expectedPullTimeNs + 1);
+    processor->informPullAlarmFired(expectedPullTimeNs + 3);
     EXPECT_EQ(baseTimeNs + startBucketNum * bucketSizeNs + 5 * bucketSizeNs, expectedPullTimeNs);
 
-    processor->informPullAlarmFired(expectedPullTimeNs + 1);
+    processor->informPullAlarmFired(expectedPullTimeNs + 4);
+    EXPECT_EQ(baseTimeNs + startBucketNum * bucketSizeNs + 6 * bucketSizeNs, expectedPullTimeNs);
 
     ConfigMetricsReportList reports;
     vector<uint8_t> buffer;
@@ -352,12 +355,18 @@
     EXPECT_EQ(1 /* subsystem name field */,
               data.dimensions_in_what().value_tuple().dimensions_value(0).field());
     EXPECT_FALSE(data.dimensions_in_what().value_tuple().dimensions_value(0).value_str().empty());
-    // We have 1 full bucket, the two surrounding the activation are dropped.
-    EXPECT_EQ(1, data.bucket_info_size());
+    // We have 2 full buckets, the two surrounding the activation are dropped.
+    EXPECT_EQ(2, data.bucket_info_size());
 
-    EXPECT_EQ(baseTimeNs + 4 * bucketSizeNs, data.bucket_info(0).start_bucket_elapsed_nanos());
-    EXPECT_EQ(baseTimeNs + 5 * bucketSizeNs, data.bucket_info(0).end_bucket_elapsed_nanos());
-    EXPECT_EQ(1, data.bucket_info(0).values_size());
+    auto bucketInfo = data.bucket_info(0);
+    EXPECT_EQ(baseTimeNs + 3 * bucketSizeNs, bucketInfo.start_bucket_elapsed_nanos());
+    EXPECT_EQ(baseTimeNs + 4 * bucketSizeNs, bucketInfo.end_bucket_elapsed_nanos());
+    EXPECT_EQ(1, bucketInfo.values_size());
+
+    bucketInfo = data.bucket_info(1);
+    EXPECT_EQ(baseTimeNs + 4 * bucketSizeNs, bucketInfo.start_bucket_elapsed_nanos());
+    EXPECT_EQ(baseTimeNs + 5 * bucketSizeNs, bucketInfo.end_bucket_elapsed_nanos());
+    EXPECT_EQ(1, bucketInfo.values_size());
 }
 
 #else
diff --git a/cmds/statsd/tests/storage/StorageManager_test.cpp b/cmds/statsd/tests/storage/StorageManager_test.cpp
index cae2f30..9e15e99 100644
--- a/cmds/statsd/tests/storage/StorageManager_test.cpp
+++ b/cmds/statsd/tests/storage/StorageManager_test.cpp
@@ -125,6 +125,105 @@
     EXPECT_EQ("300_2000_123454_history", list[3].mFileName);
 }
 
+const string testDir = "/data/misc/stats-data/";
+const string file1 = testDir + "2557169347_1066_1";
+const string file2 = testDir + "2557169349_1066_1";
+const string file1_history = file1 + "_history";
+const string file2_history = file2 + "_history";
+
+bool prepareLocalHistoryTestFiles() {
+    android::base::unique_fd fd(TEMP_FAILURE_RETRY(
+            open(file1.c_str(), O_WRONLY | O_CREAT | O_CLOEXEC, S_IRUSR | S_IWUSR)));
+    if (fd != -1) {
+        dprintf(fd, "content");
+    } else {
+        return false;
+    }
+
+    android::base::unique_fd fd2(TEMP_FAILURE_RETRY(
+            open(file2.c_str(), O_WRONLY | O_CREAT | O_CLOEXEC, S_IRUSR | S_IWUSR)));
+    if (fd2 != -1) {
+        dprintf(fd2, "content");
+    } else {
+        return false;
+    }
+    return true;
+}
+
+void clearLocalHistoryTestFiles() {
+    TEMP_FAILURE_RETRY(remove(file1.c_str()));
+    TEMP_FAILURE_RETRY(remove(file2.c_str()));
+    TEMP_FAILURE_RETRY(remove(file1_history.c_str()));
+    TEMP_FAILURE_RETRY(remove(file2_history.c_str()));
+}
+
+bool fileExist(string name) {
+    android::base::unique_fd fd(TEMP_FAILURE_RETRY(open(name.c_str(), O_RDONLY | O_CLOEXEC)));
+    return fd != -1;
+}
+
+/* The following AppendConfigReportTests test the 4 combinations of [whether erase data] [whether
+ * the caller is adb] */
+TEST(StorageManagerTest, AppendConfigReportTest1) {
+    EXPECT_TRUE(prepareLocalHistoryTestFiles());
+
+    ProtoOutputStream out;
+    StorageManager::appendConfigMetricsReport(ConfigKey(1066, 1), &out, false /*erase?*/,
+                                              false /*isAdb?*/);
+
+    EXPECT_FALSE(fileExist(file1));
+    EXPECT_FALSE(fileExist(file2));
+
+    EXPECT_TRUE(fileExist(file1_history));
+    EXPECT_TRUE(fileExist(file2_history));
+    clearLocalHistoryTestFiles();
+}
+
+TEST(StorageManagerTest, AppendConfigReportTest2) {
+    EXPECT_TRUE(prepareLocalHistoryTestFiles());
+
+    ProtoOutputStream out;
+    StorageManager::appendConfigMetricsReport(ConfigKey(1066, 1), &out, true /*erase?*/,
+                                              false /*isAdb?*/);
+
+    EXPECT_FALSE(fileExist(file1));
+    EXPECT_FALSE(fileExist(file2));
+    EXPECT_FALSE(fileExist(file1_history));
+    EXPECT_FALSE(fileExist(file2_history));
+
+    clearLocalHistoryTestFiles();
+}
+
+TEST(StorageManagerTest, AppendConfigReportTest3) {
+    EXPECT_TRUE(prepareLocalHistoryTestFiles());
+
+    ProtoOutputStream out;
+    StorageManager::appendConfigMetricsReport(ConfigKey(1066, 1), &out, false /*erase?*/,
+                                              true /*isAdb?*/);
+
+    EXPECT_TRUE(fileExist(file1));
+    EXPECT_TRUE(fileExist(file2));
+    EXPECT_FALSE(fileExist(file1_history));
+    EXPECT_FALSE(fileExist(file2_history));
+
+    clearLocalHistoryTestFiles();
+}
+
+TEST(StorageManagerTest, AppendConfigReportTest4) {
+    EXPECT_TRUE(prepareLocalHistoryTestFiles());
+
+    ProtoOutputStream out;
+    StorageManager::appendConfigMetricsReport(ConfigKey(1066, 1), &out, true /*erase?*/,
+                                              true /*isAdb?*/);
+
+    EXPECT_FALSE(fileExist(file1));
+    EXPECT_FALSE(fileExist(file2));
+    EXPECT_FALSE(fileExist(file1_history));
+    EXPECT_FALSE(fileExist(file2_history));
+
+    clearLocalHistoryTestFiles();
+}
+
 }  // namespace statsd
 }  // namespace os
 }  // namespace android
diff --git a/config/dirty-image-objects b/config/dirty-image-objects
index 9e2230b..ec2568d 100644
--- a/config/dirty-image-objects
+++ b/config/dirty-image-objects
@@ -28,147 +28,359 @@
 # Then, grep for lines containing "Private dirty object" from the output.
 # This particular file was generated by dumping systemserver and systemui.
 #
+android.accounts.Account
+android.accounts.OnAccountsUpdateListener
+android.animation.LayoutTransition
+android.app.ActivityManager
+android.app.ActivityManager$OnUidImportanceListener
+android.app.ActivityTaskManager
+android.app.ActivityThread
+android.app.admin.DevicePolicyManager
+android.app.AlarmManager
+android.app.Application
+android.app.AppOpsManager
+android.app.backup.BackupManager
+android.app.ContextImpl
+android.app.INotificationManager
+android.app.Notification$BigPictureStyle
+android.app.Notification$BigTextStyle
+android.app.Notification$InboxStyle
+android.app.NotificationChannel
+android.app.NotificationChannelGroup
+android.app.NotificationManager
+android.app.PendingIntent
+android.app.PendingIntent$OnFinished
+android.app.QueuedWork
+android.app.ResourcesManager
+android.app.WallpaperManager
+android.app.WindowConfiguration
+android.bluetooth.BluetoothAdapter
+android.bluetooth.BluetoothDevice
+android.bluetooth.BluetoothProfile
+android.bluetooth.IBluetoothA2dp
+android.bluetooth.IBluetoothHeadsetPhone
+android.bluetooth.IBluetoothHidDevice
+android.bluetooth.IBluetoothHidHost
+android.bluetooth.IBluetoothMap
+android.bluetooth.IBluetoothPan
+android.bluetooth.IBluetoothPbap
+android.bluetooth.IBluetoothSap
+android.content.ClipboardManager$OnPrimaryClipChangedListener
+android.content.ComponentName
+android.content.ContentProvider$PipeDataWriter
+android.content.ContentResolver
+android.content.Context
+android.content.Intent
+android.content.pm.PackageManager$OnPermissionsChangedListener
+android.content.pm.VersionedPackage
+android.content.res.Configuration
+android.content.SharedPreferences$OnSharedPreferenceChangeListener
+android.database.CursorWindow
+android.database.sqlite.SQLiteCompatibilityWalFlags
+android.database.sqlite.SQLiteDatabase$CursorFactory
+android.database.sqlite.SQLiteGlobal
+android.database.sqlite.SQLiteTransactionListener
+android.ddm.DdmHandleAppName
+android.graphics.Bitmap
+android.graphics.Canvas
+android.graphics.drawable.AdaptiveIconDrawable
+android.graphics.drawable.ColorDrawable
+android.graphics.drawable.GradientDrawable
+android.graphics.drawable.Icon
+android.graphics.drawable.InsetDrawable
+android.graphics.drawable.RippleDrawable
+android.graphics.drawable.VectorDrawable$VGroup
+android.graphics.ImageDecoder
+android.graphics.Rect
+android.graphics.TemporaryBuffer
+android.hardware.biometrics.BiometricSourceType
+android.hardware.display.ColorDisplayManager$ColorDisplayManagerInternal
+android.hardware.display.DisplayManagerGlobal
+android.hardware.display.NightDisplayListener$Callback
+android.hardware.input.InputManager
+android.hardware.input.InputManager$InputDeviceListener
+android.hardware.SensorPrivacyManager
+android.hardware.SystemSensorManager
+android.icu.impl.OlsonTimeZone
+android.icu.text.BreakIterator
+android.icu.text.Collator
+android.icu.text.DateFormat$BooleanAttribute
+android.icu.text.DateTimePatternGenerator$DTPGflags
+android.icu.text.PluralRules$Operand
+android.icu.util.TimeZone
+android.location.GpsStatus$Listener
+android.location.LocationListener
+android.media.AudioManager
+android.media.MediaRouter
+android.media.PlayerBase
+android.media.session.MediaSessionManager
+android.net.apf.ApfCapabilities
+android.net.ConnectivityManager
+android.net.ConnectivityManager$OnNetworkActiveListener
+android.net.ConnectivityThread$Singleton
+android.net.IpConfiguration$IpAssignment
+android.net.IpConfiguration$ProxySettings
+android.net.IpPrefix
+android.net.LinkAddress
+android.net.LinkProperties
+android.net.Network
+android.net.NetworkCapabilities
+android.net.NetworkInfo
+android.net.NetworkInfo$State
+android.net.NetworkRequest
+android.net.NetworkRequest$Type
+android.net.RouteInfo
+android.net.StringNetworkSpecifier
+android.net.TrafficStats
+android.net.UidRange
+android.net.Uri$HierarchicalUri
+android.net.Uri$StringUri
+android.net.wifi.WifiManager
+android.net.wifi.WifiManager$SoftApCallback
+android.os.AsyncResult
+android.os.AsyncTask
+android.os.BinderProxy
+android.os.Bundle
+android.os.DeadObjectException
+android.os.Environment
+android.os.FileObserver
+android.os.Handler
+android.os.IDeviceIdleController
+android.os.LocaleList
+android.os.Looper
+android.os.Message
+android.os.ParcelUuid
+android.os.Process
+android.os.RecoverySystem
+android.os.ServiceManager
+android.os.storage.StorageManager
+android.os.StrictMode
+android.os.Trace
+android.os.WorkSource
+android.os.WorkSource$WorkChain
+android.permission.PermissionManager
+android.provider.FontsContract
+android.provider.Settings$SettingNotFoundException
+android.renderscript.RenderScriptCacheDir
+android.security.IKeyChainService
+android.security.keystore.AndroidKeyStoreProvider
+android.security.net.config.ApplicationConfig
+android.security.net.config.SystemCertificateSource$NoPreloadHolder
+android.telecom.PhoneAccountHandle
+android.telephony.AnomalyReporter
+android.telephony.CellSignalStrengthCdma
+android.telephony.CellSignalStrengthGsm
+android.telephony.CellSignalStrengthLte
+android.telephony.CellSignalStrengthNr
+android.telephony.CellSignalStrengthTdscdma
+android.telephony.CellSignalStrengthWcdma
+android.telephony.DataSpecificRegistrationInfo
+android.telephony.emergency.EmergencyNumber
+android.telephony.ims.ImsMmTelManager$CapabilityCallback$CapabilityBinder
+android.telephony.ims.ImsMmTelManager$RegistrationCallback$RegistrationBinder
+android.telephony.ims.ImsReasonInfo
+android.telephony.ims.ProvisioningManager$Callback$CallbackBinder
+android.telephony.ModemActivityInfo
+android.telephony.ModemInfo
+android.telephony.NetworkRegistrationInfo
+android.telephony.NetworkService
+android.telephony.TelephonyManager
+android.telephony.VoiceSpecificRegistrationInfo
+android.text.format.DateFormat
+android.text.method.SingleLineTransformationMethod
+android.text.Selection$MemoryTextWatcher
+android.text.SpanWatcher
+android.text.style.AlignmentSpan
+android.text.style.CharacterStyle
+android.text.style.LeadingMarginSpan
+android.text.style.LineBackgroundSpan
+android.text.style.LineHeightSpan
+android.text.style.MetricAffectingSpan
+android.text.style.ReplacementSpan
+android.text.style.SuggestionSpan
+android.text.style.TabStopSpan
+android.text.TextUtils
+android.text.TextWatcher
+android.transition.ChangeClipBounds
+android.transition.ChangeImageTransform
+android.transition.ChangeTransform
+android.util.ArrayMap
+android.util.ArraySet
+android.util.DisplayMetrics
+android.util.EventLog
+android.util.Log
+android.util.Patterns
+android.view.AbsSavedState$1
+android.view.accessibility.AccessibilityManager
+android.view.accessibility.AccessibilityManager$AccessibilityServicesStateChangeListener
+android.view.accessibility.AccessibilityManager$TouchExplorationStateChangeListener
+android.view.accessibility.AccessibilityNodeIdManager
+android.view.autofill.AutofillManager
+android.view.autofill.Helper
+android.view.Choreographer
+android.view.inputmethod.InputMethodManager
+android.view.IWindowManager
+android.view.PointerIcon
+android.view.RemoteAnimationAdapter
+android.view.ThreadedRenderer
+android.view.View
+android.view.View$OnHoverListener
+android.view.ViewRootImpl
+android.view.ViewStub
+android.view.ViewStub$OnInflateListener
+android.view.ViewTreeObserver
+android.view.WindowManager$LayoutParams
+android.view.WindowManagerGlobal
+android.widget.ActionMenuPresenter$OverflowMenuButton
+android.widget.ActionMenuView
+android.widget.Button
+android.widget.CheckBox
+android.widget.FrameLayout
+android.widget.ImageButton
+android.widget.ImageView
+android.widget.LinearLayout
+android.widget.RelativeLayout
+android.widget.SeekBar
+android.widget.Space
+android.widget.TextView
+android.widget.Toolbar
+byte[]
+com.android.ims.ImsManager
+com.android.internal.logging.MetricsLogger
+com.android.internal.os.BackgroundThread
+com.android.internal.os.BinderInternal
+com.android.internal.os.BinderInternal$BinderProxyLimitListener
+com.android.internal.os.RuntimeInit
+com.android.internal.os.SomeArgs
+com.android.internal.policy.DecorView
+com.android.internal.statusbar.IStatusBarService
+com.android.internal.telephony.AppSmsManager
+com.android.internal.telephony.CallerInfoAsyncQuery$OnQueryCompleteListener
+com.android.internal.telephony.CarrierActionAgent
+com.android.internal.telephony.cat.CatService
+com.android.internal.telephony.cat.IconLoader
+com.android.internal.telephony.cat.RilMessageDecoder
+com.android.internal.telephony.cdma.CdmaSubscriptionSourceManager
+com.android.internal.telephony.cdma.EriManager
+com.android.internal.telephony.CellularNetworkValidator
+com.android.internal.telephony.CommandException
+com.android.internal.telephony.dataconnection.DataConnection$DcActivatingState
+com.android.internal.telephony.dataconnection.DataConnection$DcActiveState
+com.android.internal.telephony.dataconnection.DataConnection$DcInactiveState
+com.android.internal.telephony.dataconnection.DataEnabledSettings
+com.android.internal.telephony.dataconnection.DcTracker
+com.android.internal.telephony.euicc.EuiccCardController
+com.android.internal.telephony.euicc.EuiccController
+com.android.internal.telephony.GsmAlphabet
+com.android.internal.telephony.GsmCdmaCallTracker
+com.android.internal.telephony.GsmCdmaPhone
+com.android.internal.telephony.IccPhoneBookInterfaceManager
+com.android.internal.telephony.IccSmsInterfaceManager
+com.android.internal.telephony.ims.ImsResolver
+com.android.internal.telephony.imsphone.ImsExternalCallTracker
+com.android.internal.telephony.imsphone.ImsPhone
+com.android.internal.telephony.imsphone.ImsPhoneCallTracker
+com.android.internal.telephony.ims.RcsMessageStoreController
+com.android.internal.telephony.IntentBroadcaster
+com.android.internal.telephony.ITelephonyRegistry$Stub$Proxy
+com.android.internal.telephony.metrics.TelephonyMetrics
+com.android.internal.telephony.MultiSimSettingController
+com.android.internal.telephony.nano.CarrierIdProto$CarrierAttribute
+com.android.internal.telephony.nano.CarrierIdProto$CarrierId
+com.android.internal.telephony.nano.TelephonyProto$RilDataCall
+com.android.internal.telephony.nano.TelephonyProto$SmsSession$Event
+com.android.internal.telephony.nano.TelephonyProto$TelephonyCallSession$Event$RilCall
+com.android.internal.telephony.NitzStateMachine
+com.android.internal.telephony.PhoneConfigurationManager
+com.android.internal.telephony.PhoneFactory
+com.android.internal.telephony.PhoneSwitcher
+com.android.internal.telephony.ProxyController
+com.android.internal.telephony.RadioConfig
+com.android.internal.telephony.RIL
+com.android.internal.telephony.RILRequest
+com.android.internal.telephony.RilWakelockInfo
+com.android.internal.telephony.ServiceStateTracker
+com.android.internal.telephony.SimActivationTracker
+com.android.internal.telephony.SmsApplication
+com.android.internal.telephony.SmsBroadcastUndelivered
+com.android.internal.telephony.SmsStorageMonitor
+com.android.internal.telephony.SmsUsageMonitor
+com.android.internal.telephony.SubscriptionController
+com.android.internal.telephony.SubscriptionInfoUpdater
+com.android.internal.telephony.TelephonyComponentFactory
+com.android.internal.telephony.TelephonyDevController
+com.android.internal.telephony.TelephonyTester
+com.android.internal.telephony.uicc.AdnRecordCache
+com.android.internal.telephony.uicc.UiccCardApplication
+com.android.internal.telephony.uicc.UiccController
+com.android.internal.telephony.uicc.UiccProfile
+com.android.internal.telephony.uicc.UiccStateChangedLauncher
+com.android.internal.telephony.uicc.UsimFileHandler
+com.android.internal.telephony.uicc.VoiceMailConstants
+com.android.internal.util.LatencyTracker
+com.android.internal.util.StateMachine$SmHandler
+com.android.okhttp.OkHttpClient
+com.android.okhttp.okio.AsyncTimeout
+com.android.okhttp.okio.SegmentPool
+com.android.phone.ecc.nano.ProtobufEccData$CountryInfo
+com.android.phone.ecc.nano.ProtobufEccData$EccInfo
+com.android.server.sip.SipWakeupTimer
+com.android.server.SystemConfig
+dalvik.system.BaseDexClassLoader
+dalvik.system.BlockGuard
+dalvik.system.CloseGuard
+dalvik.system.RuntimeHooks
+dalvik.system.SocketTagger
+java.io.BufferedReader
+java.lang.AssertionError
+java.lang.Boolean
+java.lang.Byte
+java.lang.Character
+java.lang.CharSequence
+java.lang.Class
+java.lang.IllegalAccessException
+java.lang.IllegalStateException
+java.lang.NoSuchMethodException
+java.lang.NullPointerException
+java.lang.Object
+java.lang.Object[]
+java.lang.ref.FinalizerReference
+java.lang.Runnable
+java.lang.SecurityException
+java.lang.Short
+java.lang.String[]
 java.lang.System
-java.net.Inet4Address
 java.lang.Thread
 java.lang.Throwable
-java.util.Collections
-javax.net.ssl.SSLContext
+java.lang.UnsatisfiedLinkError
+java.net.Inet6Address
+java.net.Socket
+java.net.SocketException
+java.nio.Bits
 java.nio.charset.Charset
+java.security.interfaces.RSAPrivateKey
 java.security.Provider
-javax.net.ssl.HttpsURLConnection
-javax.net.ssl.SSLSocketFactory
-java.util.TimeZone
+java.util.Collections
+java.util.concurrent.Executor
+java.util.GregorianCalendar
 java.util.Locale
-java.util.function.ToIntFunction
-sun.misc.FormattedFloatingDecimal
-java.util.stream.IntStream
-android.icu.util.TimeZone
-org.apache.harmony.luni.internal.util.TimezoneGetter
-dalvik.system.SocketTagger
-dalvik.system.CloseGuard
-java.lang.ref.FinalizerReference
-com.android.org.conscrypt.ct.CTLogStoreImpl
-com.android.org.conscrypt.SSLParametersImpl
-com.android.org.conscrypt.OpenSSLContextImpl
-com.android.org.conscrypt.SSLParametersImpl$AliasChooser
-com.android.org.conscrypt.SSLParametersImpl$PSKCallbacks
-com.android.org.conscrypt.NativeCrypto$SSLHandshakeCallbacks
-com.android.okhttp.OkHttpClient
-com.android.okhttp.okio.SegmentPool
-com.android.okhttp.okio.AsyncTimeout
-com.android.okhttp.HttpUrl
-android.os.StrictMode
-com.android.internal.os.BinderInternal
-android.os.storage.StorageManager
-android.os.Trace
-android.app.ActivityManager
-android.media.MediaRouter
-android.os.Environment
-android.view.ThreadedRenderer
-android.media.AudioManager
-android.app.AlarmManager
-android.telephony.TelephonyManager
-android.bluetooth.BluetoothAdapter
-com.android.internal.os.SomeArgs
-android.os.LocaleList
-android.view.WindowManagerGlobal
-android.media.AudioSystem
-android.ddm.DdmHandleAppName
-android.provider.Settings
-android.view.ViewRootImpl
-android.net.ConnectivityManager
-android.app.ActivityThread
-android.os.BaseBundle
-android.util.ArraySet
-android.view.View
-android.os.ServiceManager
-android.view.ViewTreeObserver
-android.hardware.input.InputManager
-android.os.UEventObserver
-android.app.NotificationManager
-android.hardware.display.DisplayManagerGlobal
-android.os.Binder
-android.app.AppOpsManager
-android.content.ContentResolver
-android.app.backup.BackupManager
-android.util.ArrayMap
-android.os.Looper
-android.graphics.Bitmap
-android.view.textservice.TextServicesManager
-com.android.internal.inputmethod.InputMethodUtils
-android.app.QueuedWork
-android.graphics.TemporaryBuffer
-android.widget.ImageView
-android.database.sqlite.SQLiteGlobal
-android.view.autofill.Helper
-android.text.method.SingleLineTransformationMethod
-com.android.internal.os.RuntimeInit
-android.view.inputmethod.InputMethodManager
-android.hardware.SystemSensorManager
-android.database.CursorWindow
-android.text.TextUtils
-android.media.PlayerBase
-android.app.ResourcesManager
-android.os.Message
-android.view.accessibility.AccessibilityManager
-android.app.Notification
-android.provider.ContactsContract$ContactNameColumns
-android.provider.CalendarContract$EventsColumns
-android.provider.CalendarContract$CalendarColumns
-android.provider.CalendarContract$SyncColumns
-android.provider.ContactsContract$ContactsColumns
-android.content.pm.PackageManager$OnPermissionsChangedListener
-android.net.IpConfiguration$ProxySettings
-android.provider.ContactsContract$ContactOptionsColumns
-android.net.wifi.SupplicantState
-android.provider.ContactsContract$ContactStatusColumns
-android.view.accessibility.AccessibilityManager$TouchExplorationStateChangeListener
-android.provider.CalendarContract$CalendarSyncColumns
-android.bluetooth.BluetoothProfile$ServiceListener
-android.provider.ContactsContract$ContactCounts
-android.net.IpConfiguration$IpAssignment
-android.text.TextWatcher
-android.graphics.Bitmap$CompressFormat
-android.location.LocationListener
-sun.security.jca.Providers
-java.lang.CharSequence
-android.icu.util.ULocale
-dalvik.system.BaseDexClassLoader
-android.icu.text.BreakIterator
+java.util.Locale$NoImagePreloadHolder
+java.util.Scanner
+java.util.Set
+java.util.TimeZone
+javax.net.SocketFactory
+javax.net.ssl.HttpsURLConnection
+javax.net.ssl.HttpsURLConnection$NoPreloadHolder
+javax.net.ssl.SSLContext
+javax.net.ssl.SSLSessionContext
+javax.net.ssl.SSLSocketFactory
+libcore.io.Libcore
+libcore.io.Memory
 libcore.net.NetworkSecurityPolicy
-android.icu.text.UnicodeSet
-com.android.org.conscrypt.TrustedCertificateStore$PreloadHolder
-android.app.SearchManager
-android.os.Build
-android.app.ContextImpl
-android.app.WallpaperManager
-android.security.net.config.ApplicationConfig
-android.animation.LayoutTransition
-android.widget.TextView
-com.android.internal.logging.MetricsLogger
-android.renderscript.RenderScriptCacheDir
-android.os.Process
-android.os.Handler
-android.content.Context
-android.graphics.drawable.AdaptiveIconDrawable
-android.provider.FontsContract
-android.text.style.SuggestionSpan
-android.graphics.drawable.VectorDrawable$VGroup
-android.view.ViewStub
-android.text.style.MetricAffectingSpan
-android.content.SharedPreferences$OnSharedPreferenceChangeListener
-android.app.PendingIntent
-android.text.SpanWatcher
-android.widget.FrameLayout
-android.net.NetworkRequest$Type
-android.net.NetworkInfo$State
-android.graphics.drawable.GradientDrawable
-android.text.style.AlignmentSpan
-android.widget.LinearLayout
-android.text.style.CharacterStyle
-android.view.View$OnApplyWindowInsetsListener
-android.view.MenuItem
-android.text.style.ReplacementSpan
-android.graphics.drawable.Icon
-android.widget.Button
+libcore.timezone.TimeZoneFinder
+org.apache.http.params.HttpParams
+sun.misc.Cleaner
+sun.nio.ch.FileChannelImpl
+sun.nio.ch.FileChannelImpl$Unmapper
+sun.nio.fs.UnixChannelFactory
+sun.security.jca.Providers
diff --git a/config/preloaded-classes b/config/preloaded-classes
index 91cb47b..b4fd031 100644
--- a/config/preloaded-classes
+++ b/config/preloaded-classes
@@ -1105,7 +1105,6 @@
 android.database.sqlite.SQLiteDatabaseConfiguration
 android.database.sqlite.SQLiteDatabaseCorruptException
 android.database.sqlite.SQLiteDatabaseLockedException
-android.database.sqlite.SQLiteDebug$Consts
 android.database.sqlite.SQLiteDebug$DbStats
 android.database.sqlite.SQLiteDebug$PagerStats
 android.database.sqlite.SQLiteDebug
diff --git a/core/java/android/app/Activity.java b/core/java/android/app/Activity.java
index c08ed26..dc52c52 100644
--- a/core/java/android/app/Activity.java
+++ b/core/java/android/app/Activity.java
@@ -2330,7 +2330,7 @@
      * calling {@link VoiceInteractor#notifyDirectActionsChanged()}.
      *
      * <p>To get the voice interactor you need to call {@link #getVoiceInteractor()}
-     * which would return non <code>null<c/ode> only if there is an ongoing voice
+     * which would return non <code>null</code> only if there is an ongoing voice
      * interaction session. You an also detect when the voice interactor is no
      * longer valid because the voice interaction session that is backing is finished
      * by calling {@link VoiceInteractor#registerOnDestroyedCallback(Executor, Runnable)}.
@@ -2339,7 +2339,7 @@
      * before {@link #onStop()} is being called.
      *
      * <p>You should pass to the callback the currently supported direct actions which
-     * cannot be <code>null</code> or contain <code>null</null> elements.
+     * cannot be <code>null</code> or contain <code>null</code> elements.
      *
      * <p>You should return the action list as soon as possible to ensure the consumer,
      * for example the assistant, is as responsive as possible which would improve user
@@ -3681,7 +3681,7 @@
             ActivityTaskManager.getService().onBackPressedOnTaskRoot(mToken,
                     new IRequestFinishCallback.Stub() {
                         public void requestFinish() {
-                            finishAfterTransition();
+                            mHandler.post(() -> finishAfterTransition());
                         }
                     });
         } catch (RemoteException e) {
diff --git a/core/java/android/app/ActivityManagerInternal.java b/core/java/android/app/ActivityManagerInternal.java
index 46a520a..0b25b2e 100644
--- a/core/java/android/app/ActivityManagerInternal.java
+++ b/core/java/android/app/ActivityManagerInternal.java
@@ -286,7 +286,6 @@
     public abstract boolean isActivityStartsLoggingEnabled();
     /** Returns true if the background activity starts is enabled. */
     public abstract boolean isBackgroundActivityStartsEnabled();
-    public abstract boolean isPackageNameWhitelistedForBgActivityStarts(String packageName);
     public abstract void reportCurKeyguardUsageEvent(boolean keyguardShowing);
 
     /** Input dispatch timeout to a window, start the ANR process. */
diff --git a/core/java/android/app/ActivityThread.java b/core/java/android/app/ActivityThread.java
index 1e982bc..3a74f7d 100644
--- a/core/java/android/app/ActivityThread.java
+++ b/core/java/android/app/ActivityThread.java
@@ -5564,15 +5564,9 @@
 
     private void handleConfigurationChanged(Configuration config, CompatibilityInfo compat) {
 
-        int configDiff = 0;
+        int configDiff;
+        boolean equivalent;
 
-        // This flag tracks whether the new configuration is fundamentally equivalent to the
-        // existing configuration. This is necessary to determine whether non-activity
-        // callbacks should receive notice when the only changes are related to non-public fields.
-        // We do not gate calling {@link #performActivityConfigurationChanged} based on this flag
-        // as that method uses the same check on the activity config override as well.
-        final boolean equivalent = config != null && mConfiguration != null
-                && (0 == mConfiguration.diffPublicOnly(config));
         final Theme systemTheme = getSystemContext().getTheme();
         final Theme systemUiTheme = getSystemUiContext().getTheme();
 
@@ -5590,6 +5584,13 @@
                 return;
             }
 
+            // This flag tracks whether the new configuration is fundamentally equivalent to the
+            // existing configuration. This is necessary to determine whether non-activity callbacks
+            // should receive notice when the only changes are related to non-public fields.
+            // We do not gate calling {@link #performActivityConfigurationChanged} based on this
+            // flag as that method uses the same check on the activity config override as well.
+            equivalent = mConfiguration != null && (0 == mConfiguration.diffPublicOnly(config));
+
             if (DEBUG_CONFIGURATION) Slog.v(TAG, "Handle configuration changed: "
                     + config);
 
diff --git a/core/java/android/app/ApplicationPackageManager.java b/core/java/android/app/ApplicationPackageManager.java
index 685eedc..769fd48 100644
--- a/core/java/android/app/ApplicationPackageManager.java
+++ b/core/java/android/app/ApplicationPackageManager.java
@@ -2754,12 +2754,11 @@
     public Drawable loadUnbadgedItemIcon(@NonNull PackageItemInfo itemInfo,
             @Nullable ApplicationInfo appInfo) {
         if (itemInfo.showUserIcon != UserHandle.USER_NULL) {
-            Bitmap bitmap = getUserManager().getUserIcon(itemInfo.showUserIcon);
-            if (bitmap == null) {
-                return UserIcons.getDefaultUserIcon(
-                        mContext.getResources(), itemInfo.showUserIcon, /* light= */ false);
-            }
-            return new BitmapDrawable(bitmap);
+            // Indicates itemInfo is for a different user (e.g. a profile's parent), so use a 
+            // generic user icon (users generally lack permission to view each other's actual icons)
+            int targetUserId = itemInfo.showUserIcon;
+            return UserIcons.getDefaultUserIcon(
+                    mContext.getResources(), targetUserId, /* light= */ false);
         }
         Drawable dr = null;
         if (itemInfo.packageName != null) {
diff --git a/core/java/android/app/admin/DevicePolicyManager.java b/core/java/android/app/admin/DevicePolicyManager.java
index 3f7b291..d082f33 100644
--- a/core/java/android/app/admin/DevicePolicyManager.java
+++ b/core/java/android/app/admin/DevicePolicyManager.java
@@ -16,6 +16,8 @@
 
 package android.app.admin;
 
+import static com.android.internal.util.function.pooled.PooledLambda.obtainMessage;
+
 import android.Manifest.permission;
 import android.annotation.CallbackExecutor;
 import android.annotation.ColorInt;
@@ -88,6 +90,7 @@
 
 import com.android.internal.R;
 import com.android.internal.annotations.VisibleForTesting;
+import com.android.internal.os.BackgroundThread;
 import com.android.internal.util.Preconditions;
 import com.android.org.conscrypt.TrustedCertificateStore;
 
@@ -275,7 +278,6 @@
      * <li>{@link #EXTRA_PROVISIONING_LOGO_URI}, optional</li>
      * <li>{@link #EXTRA_PROVISIONING_MAIN_COLOR}, optional</li>
      * <li>{@link #EXTRA_PROVISIONING_DISCLAIMERS}, optional</li>
-     * <li>{@link #EXTRA_PROVISIONING_SKIP_EDUCATION_SCREENS}, optional</li>
      * </ul>
      *
      * <p>When device owner provisioning has completed, an intent of the type
@@ -383,7 +385,6 @@
      * <li>{@link #EXTRA_PROVISIONING_ORGANIZATION_NAME}, optional</li>
      * <li>{@link #EXTRA_PROVISIONING_ADMIN_EXTRAS_BUNDLE}, optional</li>
      * <li>{@link #EXTRA_PROVISIONING_USE_MOBILE_DATA}, optional </li>
-     * <li>{@link #EXTRA_PROVISIONING_SKIP_EDUCATION_SCREENS}, optional</li>
      * </ul>
      *
      * @hide
@@ -423,7 +424,6 @@
      * <li>{@link #EXTRA_PROVISIONING_ADMIN_EXTRAS_BUNDLE}, optional</li>
      * <li>{@link #EXTRA_PROVISIONING_LOGO_URI}, optional</li>
      * <li>{@link #EXTRA_PROVISIONING_MAIN_COLOR}, optional</li>
-     * <li>{@link #EXTRA_PROVISIONING_SKIP_EDUCATION_SCREENS}, optional</li>
      * </ul>
      *
      * <p>When device owner provisioning has completed, an intent of the type
@@ -1149,11 +1149,11 @@
      * A boolean extra indicating if the education screens from the provisioning flow should be
      * skipped. If unspecified, defaults to {@code false}.
      *
+     * <p>This extra can only be set by the admin app when performing the admin-integrated
+     * provisioning flow as a result of the {@link #ACTION_GET_PROVISIONING_MODE} activity.
+     *
      * <p>If the education screens are skipped, it is the admin application's responsibility
      * to display its own user education screens.
-     *
-     * <p>It can be used when provisioning a fully managed device via
-     * {@link #ACTION_PROVISION_MANAGED_DEVICE}.
      */
     public static final String EXTRA_PROVISIONING_SKIP_EDUCATION_SCREENS =
             "android.app.extra.PROVISIONING_SKIP_EDUCATION_SCREENS";
@@ -2263,6 +2263,10 @@
      *     <li>{@link #PROVISIONING_MODE_MANAGED_PROFILE}</li>
      * </ul>
      *
+     * <p>If performing fully-managed device provisioning and the admin app desires to show its
+     * own education screens, the target activity can additionally return
+     * {@link #EXTRA_PROVISIONING_SKIP_EDUCATION_SCREENS} set to <code>true</code>.
+     *
      * <p>The target activity may also return the account that needs to be migrated from primary
      * user to managed profile in case of a profile owner provisioning in
      * {@link #EXTRA_PROVISIONING_ACCOUNT_TO_MIGRATE} as result.
@@ -8809,6 +8813,11 @@
             mService.setPermissionGrantState(admin, mContext.getPackageName(), packageName,
                     permission, grantState, new RemoteCallback((b) -> result.complete(b != null)));
 
+            // Timeout
+            BackgroundThread.getHandler().sendMessageDelayed(
+                    obtainMessage(CompletableFuture::complete, result, false),
+                    20_000);
+
             return result.get();
         } catch (RemoteException re) {
             throw re.rethrowFromSystemServer();
diff --git a/core/java/android/content/Context.java b/core/java/android/content/Context.java
index 941eda8..529677a 100644
--- a/core/java/android/content/Context.java
+++ b/core/java/android/content/Context.java
@@ -4126,6 +4126,7 @@
      * @see #getSystemService(String)
      * @hide
      */
+    @TestApi
     @SystemApi
     public static final String PERMISSION_SERVICE = "permission";
 
diff --git a/core/java/android/content/om/TEST_MAPPING b/core/java/android/content/om/TEST_MAPPING
new file mode 100644
index 0000000..d35dfdb
--- /dev/null
+++ b/core/java/android/content/om/TEST_MAPPING
@@ -0,0 +1,26 @@
+{
+  "presubmit": [
+    {
+      "name": "FrameworksServicesTests",
+      "options": [
+        {
+          "include-filter": "com.android.server.om"
+        }
+      ]
+    },
+    {
+      "name": "OverlayDeviceTests"
+    },
+    {
+      "name": "OverlayHostTests"
+    },
+    {
+      "name": "CtsAppSecurityHostTestCases",
+      "options": [
+        {
+          "include-filter": "android.appsecurity.cts.OverlayHostTest"
+        }
+      ]
+    }
+  ]
+}
diff --git a/core/java/android/content/pm/PackageItemInfo.java b/core/java/android/content/pm/PackageItemInfo.java
index 081c5ad..d0ab8f7 100644
--- a/core/java/android/content/pm/PackageItemInfo.java
+++ b/core/java/android/content/pm/PackageItemInfo.java
@@ -159,7 +159,7 @@
     public Bundle metaData;
 
     /**
-     * If different of UserHandle.USER_NULL, The icon of this item will be the one of that user.
+     * If different of UserHandle.USER_NULL, The icon of this item will represent that user.
      * @hide
      */
     public int showUserIcon;
diff --git a/core/java/android/content/pm/PackageManager.java b/core/java/android/content/pm/PackageManager.java
index cb939f0..e08f4a2 100644
--- a/core/java/android/content/pm/PackageManager.java
+++ b/core/java/android/content/pm/PackageManager.java
@@ -727,6 +727,7 @@
             INSTALL_ENABLE_ROLLBACK,
             INSTALL_ALLOW_DOWNGRADE,
             INSTALL_STAGED,
+            INSTALL_DRY_RUN,
     })
     @Retention(RetentionPolicy.SOURCE)
     public @interface InstallFlags {}
@@ -904,6 +905,14 @@
      */
     public static final int INSTALL_STAGED = 0x00200000;
 
+    /**
+     * Flag parameter for {@link #installPackage} to indicate that package should only be verified
+     * but not installed.
+     *
+     * @hide
+     */
+    public static final int INSTALL_DRY_RUN = 0x00800000;
+
     /** @hide */
     @IntDef(flag = true, prefix = { "DONT_KILL_APP" }, value = {
             DONT_KILL_APP
diff --git a/core/java/android/content/pm/PackageManagerInternal.java b/core/java/android/content/pm/PackageManagerInternal.java
index 666508a..672994e 100644
--- a/core/java/android/content/pm/PackageManagerInternal.java
+++ b/core/java/android/content/pm/PackageManagerInternal.java
@@ -994,4 +994,9 @@
      */
     public abstract void setRuntimePermissionsFingerPrint(@NonNull String fingerPrint,
             @UserIdInt int userId);
+
+    /**
+     * Migrates legacy obb data to its new location.
+     */
+    public abstract void migrateLegacyObbData();
 }
diff --git a/core/java/android/database/sqlite/SQLiteConnection.java b/core/java/android/database/sqlite/SQLiteConnection.java
index 3844794..f722275 100644
--- a/core/java/android/database/sqlite/SQLiteConnection.java
+++ b/core/java/android/database/sqlite/SQLiteConnection.java
@@ -19,8 +19,8 @@
 import android.database.Cursor;
 import android.database.CursorWindow;
 import android.database.DatabaseUtils;
-import android.database.sqlite.SQLiteDebug.Consts;
 import android.database.sqlite.SQLiteDebug.DbStats;
+import android.database.sqlite.SQLiteDebug.NoPreloadHolder;
 import android.os.CancellationSignal;
 import android.os.OperationCanceledException;
 import android.os.ParcelFileDescriptor;
@@ -214,7 +214,7 @@
         try {
             mConnectionPtr = nativeOpen(mConfiguration.path, mConfiguration.openFlags,
                     mConfiguration.label,
-                    SQLiteDebug.Consts.DEBUG_SQL_STATEMENTS, SQLiteDebug.Consts.DEBUG_SQL_TIME,
+                    NoPreloadHolder.DEBUG_SQL_STATEMENTS, NoPreloadHolder.DEBUG_SQL_TIME,
                     mConfiguration.lookasideSlotSize, mConfiguration.lookasideSlotCount);
         } finally {
             mRecentOperations.endOperation(cookie);
@@ -1500,7 +1500,7 @@
                 operation.mFinished = true;
                 final long execTime = operation.mEndTime - operation.mStartTime;
                 mPool.onStatementExecuted(execTime);
-                return SQLiteDebug.Consts.DEBUG_LOG_SLOW_QUERIES && SQLiteDebug.shouldLogSlowQuery(
+                return NoPreloadHolder.DEBUG_LOG_SLOW_QUERIES && SQLiteDebug.shouldLogSlowQuery(
                         execTime);
             }
             return false;
@@ -1608,7 +1608,7 @@
             if (mSql != null) {
                 msg.append(", sql=\"").append(trimSqlForDisplay(mSql)).append("\"");
             }
-            final boolean dumpDetails = allowDetailedLog && Consts.DEBUG_LOG_DETAILED
+            final boolean dumpDetails = allowDetailedLog && NoPreloadHolder.DEBUG_LOG_DETAILED
                     && mBindArgs != null && mBindArgs.size() != 0;
             if (dumpDetails) {
                 msg.append(", bindArgs=[");
diff --git a/core/java/android/database/sqlite/SQLiteDebug.java b/core/java/android/database/sqlite/SQLiteDebug.java
index 4fc7f5d..a231a92 100644
--- a/core/java/android/database/sqlite/SQLiteDebug.java
+++ b/core/java/android/database/sqlite/SQLiteDebug.java
@@ -39,7 +39,7 @@
      *
      * {@hide}
      */
-    public static final class Consts {
+    public static final class NoPreloadHolder {
         /**
          * Controls the printing of informational SQL log messages.
          *
@@ -103,8 +103,9 @@
      */
     public static boolean shouldLogSlowQuery(long elapsedTimeMillis) {
         final int slowQueryMillis = Math.min(
-                SystemProperties.getInt(Consts.SLOW_QUERY_THRESHOLD_PROP, Integer.MAX_VALUE),
-                SystemProperties.getInt(Consts.SLOW_QUERY_THRESHOLD_UID_PROP,
+                SystemProperties.getInt(NoPreloadHolder.SLOW_QUERY_THRESHOLD_PROP,
+                        Integer.MAX_VALUE),
+                SystemProperties.getInt(NoPreloadHolder.SLOW_QUERY_THRESHOLD_UID_PROP,
                         Integer.MAX_VALUE));
         return elapsedTimeMillis >= slowQueryMillis;
     }
diff --git a/core/java/android/hardware/SensorAdditionalInfo.java b/core/java/android/hardware/SensorAdditionalInfo.java
index 5ff627f..12edc5e 100644
--- a/core/java/android/hardware/SensorAdditionalInfo.java
+++ b/core/java/android/hardware/SensorAdditionalInfo.java
@@ -119,12 +119,50 @@
     public static final int TYPE_VEC3_CALIBRATION = 0x10002;
 
     /**
-     * Sensor placement. Describes location and installation angle of the sensor device.
+     * Sensor placement.
      *
-     * Payload:
-     *     floatValues[0..11]: First 3 rows of homogeneous matrix in row major order that describes
-     *     the location and orientation of the sensor. Origin of reference will be the mobile device
-     *     geometric sensor. Reference frame is defined as the same as Android sensor frame.
+     * Provides the orientation and location of the sensor element in terms of the
+     * Android coordinate system. This data is given as a 3x4 matrix consisting of a 3x3 rotation
+     * matrix (R) concatenated with a 3x1 location vector (t). The rotation matrix provides the
+     * orientation of the Android device coordinate frame relative to the local coordinate frame of
+     * the sensor. Note that assuming the axes conventions of the sensor are the same as Android,
+     * this is the inverse of the matrix applied to raw samples read from the sensor to convert them
+     * into the Android representation. The location vector represents the translation from the
+     * origin of the Android sensor coordinate system to the geometric center of the sensor,
+     * specified in millimeters (mm).
+     * <p>
+     * <b>Payload</b>:
+     *     <code>floatValues[0..11]</code>: 3x4 matrix in row major order [R; t]
+     * </p>
+     * <p>
+     * <b>Example</b>:
+     *     This raw buffer: <code>{0, 1, 0, 0, -1, 0, 0, 10, 0, 0, 1, -2.5}</code><br>
+     *     Corresponds to this 3x4 matrix:
+     *     <table>
+     *      <thead>
+     *       <tr><td colspan="3">Orientation</td><td>Location</tr>
+     *      </thead>
+     *      <tbody>
+     *       <tr><td>0</td><td>1</td><td>0</td><td>0</td></tr>
+     *       <tr><td>-1</td><td>0</td><td>0</td><td>10</td></tr>
+     *       <tr><td>0</td><td>0</td><td>1</td><td>-2.5</td></tr>
+     *      </tbody>
+     *     </table>
+     *     The sensor is oriented such that:
+     *     <ul>
+     *        <li>The device X axis corresponds to the sensor's local -Y axis
+     *        <li>The device Y axis corresponds to the sensor's local X axis
+     *        <li>The device Z axis and sensor's local Z axis are equivalent
+     *     </ul>
+     *     In other words, if viewing the origin of the Android coordinate system from the positive
+     *     Z direction, the device coordinate frame is to be rotated 90° counter-clockwise about the
+     *     Z axis to align with the sensor's local coordinate frame. Equivalently, a vector in the
+     *     Android coordinate frame may be multiplied with R to rotate it 90° clockwise (270°
+     *     counter-clockwise), yielding its representation in the sensor's coordinate frame.
+     *     Relative to the origin of the Android coordinate system, the physical center of the
+     *     sensor is located 10mm in the positive Y direction, and 2.5mm in the negative Z
+     *     direction.
+     * </p>
      */
     public static final int TYPE_SENSOR_PLACEMENT = 0x10003;
 
diff --git a/core/java/android/hardware/camera2/CameraManager.java b/core/java/android/hardware/camera2/CameraManager.java
index f662b61..c8276b2 100644
--- a/core/java/android/hardware/camera2/CameraManager.java
+++ b/core/java/android/hardware/camera2/CameraManager.java
@@ -857,8 +857,10 @@
      *
      * @param cameraId a non-{@code null} camera identifier
      * @return {@code true} if cameraId is a hidden physical camera device
+     *
+     * @hide
      */
-    private boolean isHiddenPhysicalCamera(String cameraId) {
+    public static boolean isHiddenPhysicalCamera(String cameraId) {
         try {
             ICameraService cameraService = CameraManagerGlobal.get().getCameraService();
             // If no camera service, no support
diff --git a/core/java/android/hardware/camera2/params/MandatoryStreamCombination.java b/core/java/android/hardware/camera2/params/MandatoryStreamCombination.java
index d44b6b5..6eaf54b 100644
--- a/core/java/android/hardware/camera2/params/MandatoryStreamCombination.java
+++ b/core/java/android/hardware/camera2/params/MandatoryStreamCombination.java
@@ -28,6 +28,7 @@
 import android.hardware.camera2.CameraCharacteristics;
 import android.hardware.camera2.CameraCharacteristics.Key;
 import android.hardware.camera2.CameraDevice;
+import android.hardware.camera2.CameraManager;
 import android.hardware.camera2.CameraMetadata;
 import android.hardware.camera2.params.StreamConfigurationMap;
 import android.hardware.camera2.utils.HashCodeHelpers;
@@ -661,6 +662,7 @@
         private List<Integer> mCapabilities;
         private int mHwLevel, mCameraId;
         private StreamConfigurationMap mStreamConfigMap;
+        private boolean mIsHiddenPhysicalCamera;
 
         private final Size kPreviewSizeBound = new Size(1920, 1088);
 
@@ -680,6 +682,8 @@
             mCapabilities = capabilities;
             mStreamConfigMap = sm;
             mHwLevel = hwLevel;
+            mIsHiddenPhysicalCamera =
+                    CameraManager.isHiddenPhysicalCamera(Integer.toString(mCameraId));
         }
 
         /**
@@ -893,8 +897,10 @@
             Size recordingMaxSize = new Size(0, 0);
             Size previewMaxSize = new Size(0, 0);
             Size vgaSize = new Size(640, 480);
-            if (isExternalCamera()) {
-                recordingMaxSize = getMaxExternalRecordingSize();
+            // For external camera, or hidden physical camera, CamcorderProfile may not be
+            // available, so get maximum recording size using stream configuration map.
+            if (isExternalCamera() || mIsHiddenPhysicalCamera) {
+                recordingMaxSize = getMaxCameraRecordingSize();
             } else {
                 recordingMaxSize = getMaxRecordingSize();
             }
@@ -1123,12 +1129,12 @@
         }
 
         /**
-         * Return the maximum supported video size for external cameras using data from
+         * Return the maximum supported video size for cameras using data from
          * the stream configuration map.
          *
          * @return Maximum supported video size.
          */
-        private @NonNull Size getMaxExternalRecordingSize() {
+        private @NonNull Size getMaxCameraRecordingSize() {
             final Size FULLHD = new Size(1920, 1080);
 
             Size[] videoSizeArr = mStreamConfigMap.getOutputSizes(
diff --git a/core/java/android/net/DnsResolver.java b/core/java/android/net/DnsResolver.java
index 7a85dcb..0b1a845 100644
--- a/core/java/android/net/DnsResolver.java
+++ b/core/java/android/net/DnsResolver.java
@@ -34,6 +34,7 @@
 import android.annotation.Nullable;
 import android.os.CancellationSignal;
 import android.os.Looper;
+import android.os.MessageQueue;
 import android.system.ErrnoException;
 import android.util.Log;
 
@@ -466,10 +467,20 @@
     private void registerFDListener(@NonNull Executor executor,
             @NonNull FileDescriptor queryfd, @NonNull Callback<? super byte[]> answerCallback,
             @Nullable CancellationSignal cancellationSignal, @NonNull Object lock) {
-        Looper.getMainLooper().getQueue().addOnFileDescriptorEventListener(
+        final MessageQueue mainThreadMessageQueue = Looper.getMainLooper().getQueue();
+        mainThreadMessageQueue.addOnFileDescriptorEventListener(
                 queryfd,
                 FD_EVENTS,
                 (fd, events) -> {
+                    // b/134310704
+                    // Unregister fd event listener before resNetworkResult is called to prevent
+                    // race condition caused by fd reused.
+                    // For example when querying v4 and v6, it's possible that the first query ends
+                    // and the fd is closed before the second request starts, which might return
+                    // the same fd for the second request. By that time, the looper must have
+                    // unregistered the fd, otherwise another event listener can't be registered.
+                    mainThreadMessageQueue.removeOnFileDescriptorEventListener(fd);
+
                     executor.execute(() -> {
                         DnsResponse resp = null;
                         ErrnoException exception = null;
@@ -490,7 +501,11 @@
                         }
                         answerCallback.onAnswer(resp.answerbuf, resp.rcode);
                     });
-                    // Unregister this fd listener
+
+                    // The file descriptor has already been unregistered, so it does not really
+                    // matter what is returned here. In spirit 0 (meaning "unregister this FD")
+                    // is still the closest to what the looper needs to do. When returning 0,
+                    // Looper knows to ignore the fd if it has already been unregistered.
                     return 0;
                 });
     }
diff --git a/services/net/java/android/net/NattKeepalivePacketData.java b/core/java/android/net/NattKeepalivePacketData.java
similarity index 66%
rename from services/net/java/android/net/NattKeepalivePacketData.java
rename to core/java/android/net/NattKeepalivePacketData.java
index 06838fe..a77c244 100644
--- a/services/net/java/android/net/NattKeepalivePacketData.java
+++ b/core/java/android/net/NattKeepalivePacketData.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2018 The Android Open Source Project
+ * Copyright (C) 2019 The Android Open Source Project
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -19,9 +19,9 @@
 import static android.net.SocketKeepalive.ERROR_INVALID_IP_ADDRESS;
 import static android.net.SocketKeepalive.ERROR_INVALID_PORT;
 
-import android.annotation.NonNull;
 import android.net.SocketKeepalive.InvalidPacketException;
 import android.net.util.IpUtils;
+import android.os.Parcel;
 import android.os.Parcelable;
 import android.system.OsConstants;
 
@@ -79,17 +79,40 @@
         return new NattKeepalivePacketData(srcAddress, srcPort, dstAddress, dstPort, buf.array());
     }
 
-     /**
-     * Convert this NattKeepalivePacketData to a NattKeepalivePacketDataParcelable.
-     */
-    @NonNull
-    public NattKeepalivePacketDataParcelable toStableParcelable() {
-        final NattKeepalivePacketDataParcelable parcel = new NattKeepalivePacketDataParcelable();
-
-        parcel.srcAddress = srcAddress.getAddress();
-        parcel.srcPort = srcPort;
-        parcel.dstAddress = dstAddress.getAddress();
-        parcel.dstPort = dstPort;
-        return parcel;
+    /** Parcelable Implementation */
+    public int describeContents() {
+        return 0;
     }
+
+    /** Write to parcel */
+    public void writeToParcel(Parcel out, int flags) {
+        out.writeString(srcAddress.getHostAddress());
+        out.writeString(dstAddress.getHostAddress());
+        out.writeInt(srcPort);
+        out.writeInt(dstPort);
+    }
+
+    /** Parcelable Creator */
+    public static final Parcelable.Creator<NattKeepalivePacketData> CREATOR =
+            new Parcelable.Creator<NattKeepalivePacketData>() {
+                public NattKeepalivePacketData createFromParcel(Parcel in) {
+                    final InetAddress srcAddress =
+                            InetAddresses.parseNumericAddress(in.readString());
+                    final InetAddress dstAddress =
+                            InetAddresses.parseNumericAddress(in.readString());
+                    final int srcPort = in.readInt();
+                    final int dstPort = in.readInt();
+                    try {
+                        return NattKeepalivePacketData.nattKeepalivePacket(srcAddress, srcPort,
+                                    dstAddress, dstPort);
+                    } catch (InvalidPacketException e) {
+                        throw new IllegalArgumentException(
+                                "Invalid NAT-T keepalive data: " + e.error);
+                    }
+                }
+
+                public NattKeepalivePacketData[] newArray(int size) {
+                    return new NattKeepalivePacketData[size];
+                }
+            };
 }
diff --git a/core/java/android/net/NetworkAgent.java b/core/java/android/net/NetworkAgent.java
index 419fa7a..9cd4f53 100644
--- a/core/java/android/net/NetworkAgent.java
+++ b/core/java/android/net/NetworkAgent.java
@@ -434,7 +434,24 @@
      * {@link #saveAcceptUnvalidated} to respect the user's choice.
      */
     public void explicitlySelected(boolean acceptUnvalidated) {
-        queueOrSendMessage(EVENT_SET_EXPLICITLY_SELECTED, acceptUnvalidated ? 1 : 0, 0);
+        explicitlySelected(true /* explicitlySelected */, acceptUnvalidated);
+    }
+
+    /**
+     * Called by the bearer to indicate this network was manually selected by the user.
+     * This should be called before the NetworkInfo is marked CONNECTED so that this
+     * Network can be given special treatment at that time. If {@code acceptUnvalidated} is
+     * {@code true}, then the system will switch to this network. If it is {@code false} and the
+     * network cannot be validated, the system will ask the user whether to switch to this network.
+     * If the user confirms and selects "don't ask again", then the system will call
+     * {@link #saveAcceptUnvalidated} to persist the user's choice. Thus, if the transport ever
+     * calls this method with {@code acceptUnvalidated} set to {@code false}, it must also implement
+     * {@link #saveAcceptUnvalidated} to respect the user's choice.
+     */
+    public void explicitlySelected(boolean explicitlySelected, boolean acceptUnvalidated) {
+        queueOrSendMessage(EVENT_SET_EXPLICITLY_SELECTED,
+                explicitlySelected ? 1 : 0,
+                acceptUnvalidated ? 1 : 0);
     }
 
     /**
@@ -511,7 +528,6 @@
      * override this method.
      */
     protected void addKeepalivePacketFilter(Message msg) {
-        onSocketKeepaliveEvent(msg.arg1, SocketKeepalive.ERROR_UNSUPPORTED);
     }
 
     /**
@@ -520,7 +536,6 @@
      * must override this method.
      */
     protected void removeKeepalivePacketFilter(Message msg) {
-        onSocketKeepaliveEvent(msg.arg1, SocketKeepalive.ERROR_UNSUPPORTED);
     }
 
     /**
diff --git a/core/java/android/net/NetworkStats.java b/core/java/android/net/NetworkStats.java
index bb344e2..e892b65 100644
--- a/core/java/android/net/NetworkStats.java
+++ b/core/java/android/net/NetworkStats.java
@@ -18,7 +18,6 @@
 
 import static android.os.Process.CLAT_UID;
 
-import android.annotation.NonNull;
 import android.annotation.UnsupportedAppUsage;
 import android.os.Parcel;
 import android.os.Parcelable;
@@ -34,7 +33,6 @@
 import java.io.CharArrayWriter;
 import java.io.PrintWriter;
 import java.util.Arrays;
-import java.util.function.Predicate;
 import java.util.HashSet;
 import java.util.Map;
 import java.util.Objects;
@@ -995,33 +993,23 @@
         if (limitUid == UID_ALL && limitTag == TAG_ALL && limitIfaces == INTERFACES_ALL) {
             return;
         }
-        filter(e -> (limitUid == UID_ALL || limitUid == e.uid)
-            && (limitTag == TAG_ALL || limitTag == e.tag)
-            && (limitIfaces == INTERFACES_ALL
-                    || ArrayUtils.contains(limitIfaces, e.iface)));
-    }
 
-    /**
-     * Only keep entries with {@link #set} value less than {@link #SET_DEBUG_START}.
-     *
-     * <p>This mutates the original structure in place.
-     */
-    public void filterDebugEntries() {
-        filter(e -> e.set < SET_DEBUG_START);
-    }
-
-    private void filter(Predicate<Entry> predicate) {
         Entry entry = new Entry();
         int nextOutputEntry = 0;
         for (int i = 0; i < size; i++) {
             entry = getValues(i, entry);
-            if (predicate.test(entry)) {
-                if (nextOutputEntry != i) {
-                    setValues(nextOutputEntry, entry);
-                }
+            final boolean matches =
+                    (limitUid == UID_ALL || limitUid == entry.uid)
+                    && (limitTag == TAG_ALL || limitTag == entry.tag)
+                    && (limitIfaces == INTERFACES_ALL
+                            || ArrayUtils.contains(limitIfaces, entry.iface));
+
+            if (matches) {
+                setValues(nextOutputEntry, entry);
                 nextOutputEntry++;
             }
         }
+
         size = nextOutputEntry;
     }
 
@@ -1187,221 +1175,133 @@
     /**
      * VPN accounting. Move some VPN's underlying traffic to other UIDs that use tun0 iface.
      *
-     * <p>This method should only be called on delta NetworkStats. Do not call this method on a
-     * snapshot {@link NetworkStats} object because the tunUid and/or the underlyingIface may change
-     * over time.
+     * This method should only be called on delta NetworkStats. Do not call this method on a
+     * snapshot {@link NetworkStats} object because the tunUid and/or the underlyingIface may
+     * change over time.
      *
-     * <p>This method performs adjustments for one active VPN package and one VPN iface at a time.
+     * This method performs adjustments for one active VPN package and one VPN iface at a time.
+     *
+     * It is possible for the VPN software to use multiple underlying networks. This method
+     * only migrates traffic for the primary underlying network.
      *
      * @param tunUid uid of the VPN application
      * @param tunIface iface of the vpn tunnel
-     * @param underlyingIfaces underlying network ifaces used by the VPN application
+     * @param underlyingIface the primary underlying network iface used by the VPN application
+     * @return true if it successfully adjusts the accounting for VPN, false otherwise
      */
-    public void migrateTun(int tunUid, @NonNull String tunIface,
-            @NonNull String[] underlyingIfaces) {
-        // Combined usage by all apps using VPN.
-        final Entry tunIfaceTotal = new Entry();
-        // Usage by VPN, grouped by its {@code underlyingIfaces}.
-        final Entry[] perInterfaceTotal = new Entry[underlyingIfaces.length];
-        // Usage by VPN, summed across all its {@code underlyingIfaces}.
-        final Entry underlyingIfacesTotal = new Entry();
+    public boolean migrateTun(int tunUid, String tunIface, String underlyingIface) {
+        Entry tunIfaceTotal = new Entry();
+        Entry underlyingIfaceTotal = new Entry();
 
-        for (int i = 0; i < perInterfaceTotal.length; i++) {
-            perInterfaceTotal[i] = new Entry();
-        }
+        tunAdjustmentInit(tunUid, tunIface, underlyingIface, tunIfaceTotal, underlyingIfaceTotal);
 
-        tunAdjustmentInit(tunUid, tunIface, underlyingIfaces, tunIfaceTotal, perInterfaceTotal,
-                underlyingIfacesTotal);
-
-        // If tunIface < underlyingIfacesTotal, it leaves the overhead traffic in the VPN app.
-        // If tunIface > underlyingIfacesTotal, the VPN app doesn't get credit for data compression.
+        // If tunIface < underlyingIface, it leaves the overhead traffic in the VPN app.
+        // If tunIface > underlyingIface, the VPN app doesn't get credit for data compression.
         // Negative stats should be avoided.
-        final Entry[] moved =
-                addTrafficToApplications(tunUid, tunIface, underlyingIfaces, tunIfaceTotal,
-                        perInterfaceTotal, underlyingIfacesTotal);
-        deductTrafficFromVpnApp(tunUid, underlyingIfaces, moved);
+        Entry pool = tunGetPool(tunIfaceTotal, underlyingIfaceTotal);
+        if (pool.isEmpty()) {
+            return true;
+        }
+        Entry moved =
+                addTrafficToApplications(tunUid, tunIface, underlyingIface, tunIfaceTotal, pool);
+        deductTrafficFromVpnApp(tunUid, underlyingIface, moved);
+
+        if (!moved.isEmpty()) {
+            Slog.wtf(TAG, "Failed to deduct underlying network traffic from VPN package. Moved="
+                    + moved);
+            return false;
+        }
+        return true;
     }
 
     /**
      * Initializes the data used by the migrateTun() method.
      *
-     * <p>This is the first pass iteration which does the following work:
-     *
-     * <ul>
-     *   <li>Adds up all the traffic through the tunUid's underlyingIfaces (both foreground and
-     *       background).
-     *   <li>Adds up all the traffic through tun0 excluding traffic from the vpn app itself.
-     * </ul>
-     *
-     * @param tunUid uid of the VPN application
-     * @param tunIface iface of the vpn tunnel
-     * @param underlyingIfaces underlying network ifaces used by the VPN application
-     * @param tunIfaceTotal output parameter; combined data usage by all apps using VPN
-     * @param perInterfaceTotal output parameter; data usage by VPN app, grouped by its {@code
-     *     underlyingIfaces}
-     * @param underlyingIfacesTotal output parameter; data usage by VPN, summed across all of its
-     *     {@code underlyingIfaces}
+     * This is the first pass iteration which does the following work:
+     * (1) Adds up all the traffic through the tunUid's underlyingIface
+     *     (both foreground and background).
+     * (2) Adds up all the traffic through tun0 excluding traffic from the vpn app itself.
      */
-    private void tunAdjustmentInit(int tunUid, @NonNull String tunIface,
-            @NonNull String[] underlyingIfaces, @NonNull Entry tunIfaceTotal,
-            @NonNull Entry[] perInterfaceTotal, @NonNull Entry underlyingIfacesTotal) {
-        final Entry recycle = new Entry();
+    private void tunAdjustmentInit(int tunUid, String tunIface, String underlyingIface,
+            Entry tunIfaceTotal, Entry underlyingIfaceTotal) {
+        Entry recycle = new Entry();
         for (int i = 0; i < size; i++) {
             getValues(i, recycle);
             if (recycle.uid == UID_ALL) {
                 throw new IllegalStateException(
                         "Cannot adjust VPN accounting on an iface aggregated NetworkStats.");
-            }
-            if (recycle.set == SET_DBG_VPN_IN || recycle.set == SET_DBG_VPN_OUT) {
+            } if (recycle.set == SET_DBG_VPN_IN || recycle.set == SET_DBG_VPN_OUT) {
                 throw new IllegalStateException(
                         "Cannot adjust VPN accounting on a NetworkStats containing SET_DBG_VPN_*");
             }
-            if (recycle.tag != TAG_NONE) {
-                // TODO(b/123666283): Take all tags for tunUid into account.
-                continue;
+
+            if (recycle.uid == tunUid && recycle.tag == TAG_NONE
+                    && Objects.equals(underlyingIface, recycle.iface)) {
+                underlyingIfaceTotal.add(recycle);
             }
 
-            if (recycle.uid == tunUid) {
-                // Add up traffic through tunUid's underlying interfaces.
-                for (int j = 0; j < underlyingIfaces.length; j++) {
-                    if (Objects.equals(underlyingIfaces[j], recycle.iface)) {
-                        perInterfaceTotal[j].add(recycle);
-                        underlyingIfacesTotal.add(recycle);
-                        break;
-                    }
-                }
-            } else if (tunIface.equals(recycle.iface)) {
+            if (recycle.uid != tunUid && recycle.tag == TAG_NONE
+                    && Objects.equals(tunIface, recycle.iface)) {
                 // Add up all tunIface traffic excluding traffic from the vpn app itself.
                 tunIfaceTotal.add(recycle);
             }
         }
     }
 
-    /**
-     * Distributes traffic across apps that are using given {@code tunIface}, and returns the total
-     * traffic that should be moved off of {@code tunUid} grouped by {@code underlyingIfaces}.
-     *
-     * @param tunUid uid of the VPN application
-     * @param tunIface iface of the vpn tunnel
-     * @param underlyingIfaces underlying network ifaces used by the VPN application
-     * @param tunIfaceTotal combined data usage across all apps using {@code tunIface}
-     * @param perInterfaceTotal data usage by VPN app, grouped by its {@code underlyingIfaces}
-     * @param underlyingIfacesTotal data usage by VPN, summed across all of its {@code
-     *     underlyingIfaces}
-     */
-    private Entry[] addTrafficToApplications(int tunUid, @NonNull String tunIface,
-            @NonNull String[] underlyingIfaces, @NonNull Entry tunIfaceTotal,
-            @NonNull Entry[] perInterfaceTotal, @NonNull Entry underlyingIfacesTotal) {
-        // Traffic that should be moved off of each underlying interface for tunUid (see
-        // deductTrafficFromVpnApp below).
-        final Entry[] moved = new Entry[underlyingIfaces.length];
-        for (int i = 0; i < underlyingIfaces.length; i++) {
-            moved[i] = new Entry();
-        }
+    private static Entry tunGetPool(Entry tunIfaceTotal, Entry underlyingIfaceTotal) {
+        Entry pool = new Entry();
+        pool.rxBytes = Math.min(tunIfaceTotal.rxBytes, underlyingIfaceTotal.rxBytes);
+        pool.rxPackets = Math.min(tunIfaceTotal.rxPackets, underlyingIfaceTotal.rxPackets);
+        pool.txBytes = Math.min(tunIfaceTotal.txBytes, underlyingIfaceTotal.txBytes);
+        pool.txPackets = Math.min(tunIfaceTotal.txPackets, underlyingIfaceTotal.txPackets);
+        pool.operations = Math.min(tunIfaceTotal.operations, underlyingIfaceTotal.operations);
+        return pool;
+    }
 
-        final Entry tmpEntry = new Entry();
-        final int origSize = size;
-        for (int i = 0; i < origSize; i++) {
-            if (!Objects.equals(iface[i], tunIface)) {
-                // Consider only entries that go onto the VPN interface.
-                continue;
-            }
-            if (uid[i] == tunUid) {
-                // Exclude VPN app from the redistribution, as it can choose to create packet
-                // streams by writing to itself.
-                continue;
-            }
-            tmpEntry.uid = uid[i];
-            tmpEntry.tag = tag[i];
-            tmpEntry.metered = metered[i];
-            tmpEntry.roaming = roaming[i];
-            tmpEntry.defaultNetwork = defaultNetwork[i];
-
-            // In a first pass, compute this entry's total share of data across all
-            // underlyingIfaces. This is computed on the basis of the share of this entry's usage
-            // over tunIface.
-            // TODO: Consider refactoring first pass into a separate helper method.
-            long totalRxBytes = 0;
-            if (tunIfaceTotal.rxBytes > 0) {
-                // Note - The multiplication below should not overflow since NetworkStatsService
-                // processes this every time device has transmitted/received amount equivalent to
-                // global threshold alert (~ 2MB) across all interfaces.
-                final long rxBytesAcrossUnderlyingIfaces =
-                        underlyingIfacesTotal.rxBytes * rxBytes[i] / tunIfaceTotal.rxBytes;
-                // app must not be blamed for more than it consumed on tunIface
-                totalRxBytes = Math.min(rxBytes[i], rxBytesAcrossUnderlyingIfaces);
-            }
-            long totalRxPackets = 0;
-            if (tunIfaceTotal.rxPackets > 0) {
-                final long rxPacketsAcrossUnderlyingIfaces =
-                        underlyingIfacesTotal.rxPackets * rxPackets[i] / tunIfaceTotal.rxPackets;
-                totalRxPackets = Math.min(rxPackets[i], rxPacketsAcrossUnderlyingIfaces);
-            }
-            long totalTxBytes = 0;
-            if (tunIfaceTotal.txBytes > 0) {
-                final long txBytesAcrossUnderlyingIfaces =
-                        underlyingIfacesTotal.txBytes * txBytes[i] / tunIfaceTotal.txBytes;
-                totalTxBytes = Math.min(txBytes[i], txBytesAcrossUnderlyingIfaces);
-            }
-            long totalTxPackets = 0;
-            if (tunIfaceTotal.txPackets > 0) {
-                final long txPacketsAcrossUnderlyingIfaces =
-                        underlyingIfacesTotal.txPackets * txPackets[i] / tunIfaceTotal.txPackets;
-                totalTxPackets = Math.min(txPackets[i], txPacketsAcrossUnderlyingIfaces);
-            }
-            long totalOperations = 0;
-            if (tunIfaceTotal.operations > 0) {
-                final long operationsAcrossUnderlyingIfaces =
-                        underlyingIfacesTotal.operations * operations[i] / tunIfaceTotal.operations;
-                totalOperations = Math.min(operations[i], operationsAcrossUnderlyingIfaces);
-            }
-            // In a second pass, distribute these values across interfaces in the proportion that
-            // each interface represents of the total traffic of the underlying interfaces.
-            for (int j = 0; j < underlyingIfaces.length; j++) {
-                tmpEntry.iface = underlyingIfaces[j];
-                tmpEntry.rxBytes = 0;
-                // Reset 'set' to correct value since it gets updated when adding debug info below.
-                tmpEntry.set = set[i];
-                if (underlyingIfacesTotal.rxBytes > 0) {
-                    tmpEntry.rxBytes =
-                            totalRxBytes
-                                    * perInterfaceTotal[j].rxBytes
-                                    / underlyingIfacesTotal.rxBytes;
+    private Entry addTrafficToApplications(int tunUid, String tunIface, String underlyingIface,
+            Entry tunIfaceTotal, Entry pool) {
+        Entry moved = new Entry();
+        Entry tmpEntry = new Entry();
+        tmpEntry.iface = underlyingIface;
+        for (int i = 0; i < size; i++) {
+            // the vpn app is excluded from the redistribution but all moved traffic will be
+            // deducted from the vpn app (see deductTrafficFromVpnApp below).
+            if (Objects.equals(iface[i], tunIface) && uid[i] != tunUid) {
+                if (tunIfaceTotal.rxBytes > 0) {
+                    tmpEntry.rxBytes = pool.rxBytes * rxBytes[i] / tunIfaceTotal.rxBytes;
+                } else {
+                    tmpEntry.rxBytes = 0;
                 }
-                tmpEntry.rxPackets = 0;
-                if (underlyingIfacesTotal.rxPackets > 0) {
-                    tmpEntry.rxPackets =
-                            totalRxPackets
-                                    * perInterfaceTotal[j].rxPackets
-                                    / underlyingIfacesTotal.rxPackets;
+                if (tunIfaceTotal.rxPackets > 0) {
+                    tmpEntry.rxPackets = pool.rxPackets * rxPackets[i] / tunIfaceTotal.rxPackets;
+                } else {
+                    tmpEntry.rxPackets = 0;
                 }
-                tmpEntry.txBytes = 0;
-                if (underlyingIfacesTotal.txBytes > 0) {
-                    tmpEntry.txBytes =
-                            totalTxBytes
-                                    * perInterfaceTotal[j].txBytes
-                                    / underlyingIfacesTotal.txBytes;
+                if (tunIfaceTotal.txBytes > 0) {
+                    tmpEntry.txBytes = pool.txBytes * txBytes[i] / tunIfaceTotal.txBytes;
+                } else {
+                    tmpEntry.txBytes = 0;
                 }
-                tmpEntry.txPackets = 0;
-                if (underlyingIfacesTotal.txPackets > 0) {
-                    tmpEntry.txPackets =
-                            totalTxPackets
-                                    * perInterfaceTotal[j].txPackets
-                                    / underlyingIfacesTotal.txPackets;
+                if (tunIfaceTotal.txPackets > 0) {
+                    tmpEntry.txPackets = pool.txPackets * txPackets[i] / tunIfaceTotal.txPackets;
+                } else {
+                    tmpEntry.txPackets = 0;
                 }
-                tmpEntry.operations = 0;
-                if (underlyingIfacesTotal.operations > 0) {
+                if (tunIfaceTotal.operations > 0) {
                     tmpEntry.operations =
-                            totalOperations
-                                    * perInterfaceTotal[j].operations
-                                    / underlyingIfacesTotal.operations;
+                            pool.operations * operations[i] / tunIfaceTotal.operations;
+                } else {
+                    tmpEntry.operations = 0;
                 }
-                // tmpEntry now contains the migrated data of the i-th entry for the j-th underlying
-                // interface. Add that data usage to this object.
+                tmpEntry.uid = uid[i];
+                tmpEntry.tag = tag[i];
+                tmpEntry.set = set[i];
+                tmpEntry.metered = metered[i];
+                tmpEntry.roaming = roaming[i];
+                tmpEntry.defaultNetwork = defaultNetwork[i];
                 combineValues(tmpEntry);
                 if (tag[i] == TAG_NONE) {
-                    // Add the migrated data to moved so it is deducted from the VPN app later.
-                    moved[j].add(tmpEntry);
+                    moved.add(tmpEntry);
                     // Add debug info
                     tmpEntry.set = SET_DBG_VPN_IN;
                     combineValues(tmpEntry);
@@ -1411,45 +1311,38 @@
         return moved;
     }
 
-    private void deductTrafficFromVpnApp(
-            int tunUid,
-            @NonNull String[] underlyingIfaces,
-            @NonNull Entry[] moved) {
-        for (int i = 0; i < underlyingIfaces.length; i++) {
-            moved[i].uid = tunUid;
-            // Add debug info
-            moved[i].set = SET_DBG_VPN_OUT;
-            moved[i].tag = TAG_NONE;
-            moved[i].iface = underlyingIfaces[i];
-            moved[i].metered = METERED_ALL;
-            moved[i].roaming = ROAMING_ALL;
-            moved[i].defaultNetwork = DEFAULT_NETWORK_ALL;
-            combineValues(moved[i]);
+    private void deductTrafficFromVpnApp(int tunUid, String underlyingIface, Entry moved) {
+        // Add debug info
+        moved.uid = tunUid;
+        moved.set = SET_DBG_VPN_OUT;
+        moved.tag = TAG_NONE;
+        moved.iface = underlyingIface;
+        moved.metered = METERED_ALL;
+        moved.roaming = ROAMING_ALL;
+        moved.defaultNetwork = DEFAULT_NETWORK_ALL;
+        combineValues(moved);
 
-            // Caveat: if the vpn software uses tag, the total tagged traffic may be greater than
-            // the TAG_NONE traffic.
-            //
-            // Relies on the fact that the underlying traffic only has state ROAMING_NO and
-            // METERED_NO, which should be the case as it comes directly from the /proc file.
-            // We only blend in the roaming data after applying these adjustments, by checking the
-            // NetworkIdentity of the underlying iface.
-            final int idxVpnBackground = findIndex(underlyingIfaces[i], tunUid, SET_DEFAULT,
-                            TAG_NONE, METERED_NO, ROAMING_NO, DEFAULT_NETWORK_NO);
-            if (idxVpnBackground != -1) {
-                // Note - tunSubtract also updates moved[i]; whatever traffic that's left is removed
-                // from foreground usage.
-                tunSubtract(idxVpnBackground, this, moved[i]);
-            }
+        // Caveat: if the vpn software uses tag, the total tagged traffic may be greater than
+        // the TAG_NONE traffic.
+        //
+        // Relies on the fact that the underlying traffic only has state ROAMING_NO and METERED_NO,
+        // which should be the case as it comes directly from the /proc file. We only blend in the
+        // roaming data after applying these adjustments, by checking the NetworkIdentity of the
+        // underlying iface.
+        int idxVpnBackground = findIndex(underlyingIface, tunUid, SET_DEFAULT, TAG_NONE,
+                METERED_NO, ROAMING_NO, DEFAULT_NETWORK_NO);
+        if (idxVpnBackground != -1) {
+            tunSubtract(idxVpnBackground, this, moved);
+        }
 
-            final int idxVpnForeground = findIndex(underlyingIfaces[i], tunUid, SET_FOREGROUND,
-                            TAG_NONE, METERED_NO, ROAMING_NO, DEFAULT_NETWORK_NO);
-            if (idxVpnForeground != -1) {
-                tunSubtract(idxVpnForeground, this, moved[i]);
-            }
+        int idxVpnForeground = findIndex(underlyingIface, tunUid, SET_FOREGROUND, TAG_NONE,
+                METERED_NO, ROAMING_NO, DEFAULT_NETWORK_NO);
+        if (idxVpnForeground != -1) {
+            tunSubtract(idxVpnForeground, this, moved);
         }
     }
 
-    private static void tunSubtract(int i, @NonNull NetworkStats left, @NonNull Entry right) {
+    private static void tunSubtract(int i, NetworkStats left, Entry right) {
         long rxBytes = Math.min(left.rxBytes[i], right.rxBytes);
         left.rxBytes[i] -= rxBytes;
         right.rxBytes -= rxBytes;
diff --git a/core/java/android/os/Environment.java b/core/java/android/os/Environment.java
index 3716b3e..0ee9a11 100644
--- a/core/java/android/os/Environment.java
+++ b/core/java/android/os/Environment.java
@@ -16,6 +16,7 @@
 
 package android.os;
 
+import android.Manifest;
 import android.annotation.NonNull;
 import android.annotation.SystemApi;
 import android.annotation.TestApi;
@@ -25,6 +26,7 @@
 import android.app.admin.DevicePolicyManager;
 import android.content.Context;
 import android.content.Intent;
+import android.content.pm.PackageManager;
 import android.os.storage.StorageManager;
 import android.os.storage.StorageVolume;
 import android.provider.MediaStore;
@@ -1159,11 +1161,36 @@
      */
     public static boolean isExternalStorageLegacy(@NonNull File path) {
         final Context context = AppGlobals.getInitialApplication();
+        final int uid = context.getApplicationInfo().uid;
+        if (Process.isIsolated(uid)) {
+            return false;
+        }
+
+        final PackageManager packageManager = context.getPackageManager();
+        if (packageManager.isInstantApp()) {
+            return false;
+        }
+
+        if (packageManager.checkPermission(Manifest.permission.WRITE_MEDIA_STORAGE,
+                context.getPackageName()) == PackageManager.PERMISSION_GRANTED) {
+            return true;
+        }
+
+        if (packageManager.checkPermission(Manifest.permission.INSTALL_PACKAGES,
+                context.getPackageName()) == PackageManager.PERMISSION_GRANTED) {
+            return true;
+        }
         final AppOpsManager appOps = context.getSystemService(AppOpsManager.class);
+        final String[] packagesForUid = packageManager.getPackagesForUid(uid);
+        for (String packageName : packagesForUid) {
+            if (appOps.checkOpNoThrow(AppOpsManager.OP_REQUEST_INSTALL_PACKAGES,
+                    uid, packageName) == AppOpsManager.MODE_ALLOWED) {
+                return true;
+            }
+        }
 
         return appOps.checkOpNoThrow(AppOpsManager.OP_LEGACY_STORAGE,
-                context.getApplicationInfo().uid,
-                context.getOpPackageName()) == AppOpsManager.MODE_ALLOWED;
+                uid, context.getOpPackageName()) == AppOpsManager.MODE_ALLOWED;
     }
 
     static File getDirectory(String variableName, String defaultPath) {
diff --git a/core/java/android/os/ExternalVibration.java b/core/java/android/os/ExternalVibration.java
index b93bef8..37ca868 100644
--- a/core/java/android/os/ExternalVibration.java
+++ b/core/java/android/os/ExternalVibration.java
@@ -114,6 +114,24 @@
         return true;
     }
 
+    /**
+     * Links a recipient to death against this external vibration token
+     */
+    public void linkToDeath(IBinder.DeathRecipient recipient) {
+        try {
+            mToken.linkToDeath(recipient, 0);
+        } catch (RemoteException e) {
+            return;
+        }
+    }
+
+    /**
+     * Unlinks a recipient to death against this external vibration token
+     */
+    public void unlinkToDeath(IBinder.DeathRecipient recipient) {
+        mToken.unlinkToDeath(recipient, 0);
+    }
+
     @Override
     public boolean equals(Object o) {
         if (o == null || !(o instanceof ExternalVibration)) {
diff --git a/core/java/android/os/GraphicsEnvironment.java b/core/java/android/os/GraphicsEnvironment.java
index 24a1477..ce1942c 100644
--- a/core/java/android/os/GraphicsEnvironment.java
+++ b/core/java/android/os/GraphicsEnvironment.java
@@ -33,11 +33,13 @@
 
 import dalvik.system.VMRuntime;
 
+import java.io.BufferedReader;
 import java.io.File;
 import java.io.FileDescriptor;
 import java.io.FileInputStream;
 import java.io.FileNotFoundException;
 import java.io.IOException;
+import java.io.InputStreamReader;
 import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.HashMap;
@@ -62,6 +64,7 @@
     private static final String SYSTEM_DRIVER_VERSION_NAME = "";
     private static final long SYSTEM_DRIVER_VERSION_CODE = 0;
     private static final String PROPERTY_GFX_DRIVER = "ro.gfx.driver.0";
+    private static final String PROPERTY_GFX_DRIVER_PRERELEASE = "ro.gfx.driver.1";
     private static final String PROPERTY_GFX_DRIVER_BUILD_TIME = "ro.gfx.driver_build_time";
     private static final String METADATA_DRIVER_BUILD_TIME = "com.android.gamedriver.build_time";
     private static final String ANGLE_RULES_FILE = "a4a_rules.json";
@@ -71,16 +74,19 @@
             "android.app.action.ANGLE_FOR_ANDROID_TOAST_MESSAGE";
     private static final String INTENT_KEY_A4A_TOAST_MESSAGE = "A4A Toast Message";
     private static final String GAME_DRIVER_WHITELIST_ALL = "*";
+    private static final String GAME_DRIVER_SPHAL_LIBRARIES_FILENAME = "sphal_libraries.txt";
     private static final int VULKAN_1_0 = 0x00400000;
     private static final int VULKAN_1_1 = 0x00401000;
 
     // GAME_DRIVER_ALL_APPS
     // 0: Default (Invalid values fallback to default as well)
     // 1: All apps use Game Driver
-    // 2: All apps use system graphics driver
+    // 2: All apps use Prerelease Driver
+    // 3: All apps use system graphics driver
     private static final int GAME_DRIVER_GLOBAL_OPT_IN_DEFAULT = 0;
-    private static final int GAME_DRIVER_GLOBAL_OPT_IN_ALL = 1;
-    private static final int GAME_DRIVER_GLOBAL_OPT_IN_NONE = 2;
+    private static final int GAME_DRIVER_GLOBAL_OPT_IN_GAME_DRIVER = 1;
+    private static final int GAME_DRIVER_GLOBAL_OPT_IN_PRERELEASE_DRIVER = 2;
+    private static final int GAME_DRIVER_GLOBAL_OPT_IN_OFF = 3;
 
     private ClassLoader mClassLoader;
     private String mLayerPath;
@@ -114,65 +120,6 @@
     public static native void hintActivityLaunch();
 
     /**
-     * Allow to query whether an application will use Game Driver.
-     */
-    public static boolean shouldUseGameDriver(Context context, Bundle coreSettings,
-            ApplicationInfo applicationInfo) {
-        final String driverPackageName = SystemProperties.get(PROPERTY_GFX_DRIVER);
-        if (driverPackageName == null || driverPackageName.isEmpty()) {
-            return false;
-        }
-
-        // To minimize risk of driver updates crippling the device beyond user repair, never use an
-        // updated driver for privileged or non-updated system apps. Presumably pre-installed apps
-        // were tested thoroughly with the pre-installed driver.
-        if (applicationInfo.isPrivilegedApp() || (applicationInfo.isSystemApp()
-                && !applicationInfo.isUpdatedSystemApp())) {
-            if (DEBUG) Log.v(TAG, "ignoring driver package for privileged/non-updated system app");
-            return false;
-        }
-        final ContentResolver contentResolver = context.getContentResolver();
-        final String packageName = applicationInfo.packageName;
-        final int globalOptIn;
-        if (coreSettings != null) {
-            globalOptIn = coreSettings.getInt(Settings.Global.GAME_DRIVER_ALL_APPS, 0);
-        } else {
-            globalOptIn = Settings.Global.getInt(contentResolver,
-                    Settings.Global.GAME_DRIVER_ALL_APPS, 0);
-        }
-        if (globalOptIn == GAME_DRIVER_GLOBAL_OPT_IN_ALL) {
-            return true;
-        }
-        if (globalOptIn == GAME_DRIVER_GLOBAL_OPT_IN_NONE) {
-            return false;
-        }
-
-        // GAME_DRIVER_OPT_OUT_APPS has higher priority than GAME_DRIVER_OPT_IN_APPS
-        if (getGlobalSettingsString(contentResolver, coreSettings,
-                Settings.Global.GAME_DRIVER_OPT_OUT_APPS).contains(packageName)) {
-            return false;
-        }
-        final boolean isOptIn = getGlobalSettingsString(contentResolver, coreSettings,
-                Settings.Global.GAME_DRIVER_OPT_IN_APPS).contains(packageName);
-        final List<String> whitelist = getGlobalSettingsString(contentResolver, coreSettings,
-                Settings.Global.GAME_DRIVER_WHITELIST);
-        if (!isOptIn && whitelist.indexOf(GAME_DRIVER_WHITELIST_ALL) != 0
-                && !whitelist.contains(packageName)) {
-            return false;
-        }
-
-        // If the application is not opted-in, then check whether it's on the blacklist,
-        // terminate early if it's on the blacklist and fallback to system driver.
-        if (!isOptIn
-                && getGlobalSettingsString(contentResolver, coreSettings,
-                                       Settings.Global.GAME_DRIVER_BLACKLIST)
-                        .contains(packageName)) {
-            return false;
-        }
-        return true;
-    }
-
-    /**
      * Query to determine if ANGLE should be used
      */
     public static boolean shouldUseAngle(Context context, Bundle coreSettings,
@@ -742,12 +689,102 @@
     }
 
     /**
+     * Return the driver package name to use. Return null for system driver.
+     */
+    private static String chooseDriverInternal(Context context, Bundle coreSettings) {
+        final String gameDriver = SystemProperties.get(PROPERTY_GFX_DRIVER);
+        final boolean hasGameDriver = gameDriver != null && !gameDriver.isEmpty();
+
+        final String prereleaseDriver = SystemProperties.get(PROPERTY_GFX_DRIVER_PRERELEASE);
+        final boolean hasPrereleaseDriver = prereleaseDriver != null && !prereleaseDriver.isEmpty();
+
+        if (!hasGameDriver && !hasPrereleaseDriver) {
+            if (DEBUG) Log.v(TAG, "Neither Game Driver nor prerelease driver is supported.");
+            return null;
+        }
+
+        // To minimize risk of driver updates crippling the device beyond user repair, never use an
+        // updated driver for privileged or non-updated system apps. Presumably pre-installed apps
+        // were tested thoroughly with the pre-installed driver.
+        final ApplicationInfo ai = context.getApplicationInfo();
+        if (ai.isPrivilegedApp() || (ai.isSystemApp() && !ai.isUpdatedSystemApp())) {
+            if (DEBUG) Log.v(TAG, "Ignoring driver package for privileged/non-updated system app.");
+            return null;
+        }
+
+        // Priority for Game Driver settings global on confliction (Higher priority comes first):
+        // 1. GAME_DRIVER_ALL_APPS
+        // 2. GAME_DRIVER_OPT_OUT_APPS
+        // 3. GAME_DRIVER_PRERELEASE_OPT_IN_APPS
+        // 4. GAME_DRIVER_OPT_IN_APPS
+        // 5. GAME_DRIVER_BLACKLIST
+        // 6. GAME_DRIVER_WHITELIST
+        switch (coreSettings.getInt(Settings.Global.GAME_DRIVER_ALL_APPS, 0)) {
+            case GAME_DRIVER_GLOBAL_OPT_IN_OFF:
+                if (DEBUG) Log.v(TAG, "Game Driver is turned off on this device.");
+                return null;
+            case GAME_DRIVER_GLOBAL_OPT_IN_GAME_DRIVER:
+                if (DEBUG) Log.v(TAG, "All apps opt in to use Game Driver.");
+                return hasGameDriver ? gameDriver : null;
+            case GAME_DRIVER_GLOBAL_OPT_IN_PRERELEASE_DRIVER:
+                if (DEBUG) Log.v(TAG, "All apps opt in to use prerelease driver.");
+                return hasPrereleaseDriver ? prereleaseDriver : null;
+            case GAME_DRIVER_GLOBAL_OPT_IN_DEFAULT:
+            default:
+                break;
+        }
+
+        final String appPackageName = ai.packageName;
+        if (getGlobalSettingsString(null, coreSettings, Settings.Global.GAME_DRIVER_OPT_OUT_APPS)
+                        .contains(appPackageName)) {
+            if (DEBUG) Log.v(TAG, "App opts out for Game Driver.");
+            return null;
+        }
+
+        if (getGlobalSettingsString(
+                    null, coreSettings, Settings.Global.GAME_DRIVER_PRERELEASE_OPT_IN_APPS)
+                        .contains(appPackageName)) {
+            if (DEBUG) Log.v(TAG, "App opts in for prerelease Game Driver.");
+            return hasPrereleaseDriver ? prereleaseDriver : null;
+        }
+
+        // Early return here since the rest logic is only for Game Driver.
+        if (!hasGameDriver) {
+            if (DEBUG) Log.v(TAG, "Game Driver is not supported on the device.");
+            return null;
+        }
+
+        final boolean isOptIn =
+                getGlobalSettingsString(null, coreSettings, Settings.Global.GAME_DRIVER_OPT_IN_APPS)
+                        .contains(appPackageName);
+        final List<String> whitelist =
+                getGlobalSettingsString(null, coreSettings, Settings.Global.GAME_DRIVER_WHITELIST);
+        if (!isOptIn && whitelist.indexOf(GAME_DRIVER_WHITELIST_ALL) != 0
+                && !whitelist.contains(appPackageName)) {
+            if (DEBUG) Log.v(TAG, "App is not on the whitelist for Game Driver.");
+            return null;
+        }
+
+        // If the application is not opted-in, then check whether it's on the blacklist,
+        // terminate early if it's on the blacklist and fallback to system driver.
+        if (!isOptIn
+                && getGlobalSettingsString(
+                        null, coreSettings, Settings.Global.GAME_DRIVER_BLACKLIST)
+                           .contains(appPackageName)) {
+            if (DEBUG) Log.v(TAG, "App is on the blacklist for Game Driver.");
+            return null;
+        }
+
+        return gameDriver;
+    }
+
+    /**
      * Choose whether the current process should use the builtin or an updated driver.
      */
     private static boolean chooseDriver(
             Context context, Bundle coreSettings, PackageManager pm, String packageName) {
-        final String driverPackageName = SystemProperties.get(PROPERTY_GFX_DRIVER);
-        if (driverPackageName == null || driverPackageName.isEmpty()) {
+        final String driverPackageName = chooseDriverInternal(context, coreSettings);
+        if (driverPackageName == null) {
             return false;
         }
 
@@ -770,10 +807,6 @@
             return false;
         }
 
-        if (!shouldUseGameDriver(context, coreSettings, context.getApplicationInfo())) {
-            return false;
-        }
-
         final String abi = chooseAbi(driverAppInfo);
         if (abi == null) {
             if (DEBUG) {
@@ -792,10 +825,7 @@
           .append("!/lib/")
           .append(abi);
         final String paths = sb.toString();
-
-        final String sphalLibraries =
-                coreSettings.getString(Settings.Global.GAME_DRIVER_SPHAL_LIBRARIES);
-
+        final String sphalLibraries = getSphalLibraries(context, driverPackageName);
         if (DEBUG) {
             Log.v(TAG,
                     "gfx driver package search path: " + paths
@@ -832,6 +862,29 @@
         return null;
     }
 
+    private static String getSphalLibraries(Context context, String driverPackageName) {
+        try {
+            final Context driverContext =
+                    context.createPackageContext(driverPackageName, Context.CONTEXT_RESTRICTED);
+            final BufferedReader reader = new BufferedReader(new InputStreamReader(
+                    driverContext.getAssets().open(GAME_DRIVER_SPHAL_LIBRARIES_FILENAME)));
+            final ArrayList<String> assetStrings = new ArrayList<>();
+            for (String assetString; (assetString = reader.readLine()) != null;) {
+                assetStrings.add(assetString);
+            }
+            return String.join(":", assetStrings);
+        } catch (PackageManager.NameNotFoundException e) {
+            if (DEBUG) {
+                Log.w(TAG, "Driver package '" + driverPackageName + "' not installed");
+            }
+        } catch (IOException e) {
+            if (DEBUG) {
+                Log.w(TAG, "Failed to load '" + GAME_DRIVER_SPHAL_LIBRARIES_FILENAME + "'");
+            }
+        }
+        return "";
+    }
+
     private static native int getCanLoadSystemLibraries();
     private static native void setLayerPaths(ClassLoader classLoader, String layerPaths);
     private static native void setDebugLayers(String layers);
diff --git a/core/java/android/os/Process.java b/core/java/android/os/Process.java
index e50ab6c..74c89d6 100644
--- a/core/java/android/os/Process.java
+++ b/core/java/android/os/Process.java
@@ -511,7 +511,6 @@
      * @param appDataDir null-ok the data directory of the app.
      * @param invokeWith null-ok the command to invoke with.
      * @param packageName null-ok the name of the package this process belongs to.
-     * @param useSystemGraphicsDriver whether the process uses system graphics driver.
      *
      * @param zygoteArgs Additional arguments to supply to the zygote process.
      * @return An object that describes the result of the attempt to start the process.
@@ -531,13 +530,11 @@
                                            @Nullable String appDataDir,
                                            @Nullable String invokeWith,
                                            @Nullable String packageName,
-                                           boolean useSystemGraphicsDriver,
                                            @Nullable String[] zygoteArgs) {
         return ZYGOTE_PROCESS.start(processClass, niceName, uid, gid, gids,
                     runtimeFlags, mountExternal, targetSdkVersion, seInfo,
                     abi, instructionSet, appDataDir, invokeWith, packageName,
-                    /*useUsapPool=*/ true,
-                    useSystemGraphicsDriver, zygoteArgs);
+                    /*useUsapPool=*/ true, zygoteArgs);
     }
 
     /** @hide */
@@ -553,13 +550,11 @@
                                                   @Nullable String appDataDir,
                                                   @Nullable String invokeWith,
                                                   @Nullable String packageName,
-                                                  boolean useSystemGraphicsDriver,
                                                   @Nullable String[] zygoteArgs) {
         return WebViewZygote.getProcess().start(processClass, niceName, uid, gid, gids,
                     runtimeFlags, mountExternal, targetSdkVersion, seInfo,
                     abi, instructionSet, appDataDir, invokeWith, packageName,
-                    /*useUsapPool=*/ false,
-                    useSystemGraphicsDriver, zygoteArgs);
+                    /*useUsapPool=*/ false, zygoteArgs);
     }
 
     /**
diff --git a/core/java/android/os/VibrationEffect.java b/core/java/android/os/VibrationEffect.java
index 035061b..702b41b 100644
--- a/core/java/android/os/VibrationEffect.java
+++ b/core/java/android/os/VibrationEffect.java
@@ -330,18 +330,25 @@
     @TestApi
     @Nullable
     public static VibrationEffect get(Uri uri, Context context) {
+        final ContentResolver cr = context.getContentResolver();
+        Uri uncanonicalUri = cr.uncanonicalize(uri);
+        if (uncanonicalUri == null) {
+            // If we already had an uncanonical URI, it's possible we'll get null back here. In
+            // this case, just use the URI as passed in since it wasn't canonicalized in the first
+            // place.
+            uncanonicalUri = uri;
+        }
         String[] uris = context.getResources().getStringArray(
                 com.android.internal.R.array.config_ringtoneEffectUris);
         for (int i = 0; i < uris.length && i < RINGTONES.length; i++) {
             if (uris[i] == null) {
                 continue;
             }
-            ContentResolver cr = context.getContentResolver();
             Uri mappedUri = cr.uncanonicalize(Uri.parse(uris[i]));
             if (mappedUri == null) {
                 continue;
             }
-            if (mappedUri.equals(uri)) {
+            if (mappedUri.equals(uncanonicalUri)) {
                 return get(RINGTONES[i]);
             }
         }
diff --git a/core/java/android/os/ZygoteProcess.java b/core/java/android/os/ZygoteProcess.java
index 3ea3bbc..9bcdcee 100644
--- a/core/java/android/os/ZygoteProcess.java
+++ b/core/java/android/os/ZygoteProcess.java
@@ -307,7 +307,6 @@
      * @param invokeWith null-ok the command to invoke with.
      * @param packageName null-ok the name of the package this process belongs to.
      * @param zygoteArgs Additional arguments to supply to the zygote process.
-     * @param useSystemGraphicsDriver whether the process uses system graphics driver.
      *
      * @return An object that describes the result of the attempt to start the process.
      * @throws RuntimeException on fatal start failure
@@ -324,7 +323,6 @@
                                                   @Nullable String invokeWith,
                                                   @Nullable String packageName,
                                                   boolean useUsapPool,
-                                                  boolean useSystemGraphicsDriver,
                                                   @Nullable String[] zygoteArgs) {
         // TODO (chriswailes): Is there a better place to check this value?
         if (fetchUsapPoolEnabledPropWithMinInterval()) {
@@ -335,7 +333,7 @@
             return startViaZygote(processClass, niceName, uid, gid, gids,
                     runtimeFlags, mountExternal, targetSdkVersion, seInfo,
                     abi, instructionSet, appDataDir, invokeWith, /*startChildZygote=*/ false,
-                    packageName, useUsapPool, useSystemGraphicsDriver, zygoteArgs);
+                    packageName, useUsapPool, zygoteArgs);
         } catch (ZygoteStartFailedEx ex) {
             Log.e(LOG_TAG,
                     "Starting VM process through Zygote failed");
@@ -407,7 +405,7 @@
          */
         String msgStr = args.size() + "\n" + String.join("\n", args) + "\n";
 
-        if (useUsapPool && mUsapPoolEnabled && isValidUsapCommand(args)) {
+        if (useUsapPool && mUsapPoolEnabled && canAttemptUsap(args)) {
             try {
                 return attemptUsapSendArgsAndGetResult(zygoteState, msgStr);
             } catch (IOException ex) {
@@ -498,13 +496,21 @@
      * @param args  Zygote/USAP command arguments
      * @return  True if the command can be passed to a USAP; false otherwise
      */
-    private static boolean isValidUsapCommand(ArrayList<String> args) {
+    private static boolean canAttemptUsap(ArrayList<String> args) {
         for (String flag : args) {
             for (String badFlag : INVALID_USAP_FLAGS) {
                 if (flag.startsWith(badFlag)) {
                     return false;
                 }
             }
+            if (flag.startsWith("--nice-name=")) {
+                // Check if the wrap property is set, usap would ignore it.
+                String niceName = flag.substring(12);
+                String property_value = SystemProperties.get("wrap." + niceName);
+                if (property_value != null && property_value.length() != 0) {
+                    return false;
+                }
+            }
         }
 
         return true;
@@ -546,7 +552,6 @@
                                                       boolean startChildZygote,
                                                       @Nullable String packageName,
                                                       boolean useUsapPool,
-                                                      boolean useSystemGraphicsDriver,
                                                       @Nullable String[] extraArgs)
                                                       throws ZygoteStartFailedEx {
         ArrayList<String> argsForZygote = new ArrayList<>();
@@ -628,7 +633,7 @@
             // The USAP pool can not be used if the application will not use the systems graphics
             // driver.  If that driver is requested use the Zygote application start path.
             return zygoteSendArgsAndGetResult(openZygoteSocketIfNeeded(abi),
-                                              useUsapPool && useSystemGraphicsDriver,
+                                              useUsapPool,
                                               argsForZygote);
         }
     }
@@ -1139,8 +1144,7 @@
                     gids, runtimeFlags, 0 /* mountExternal */, 0 /* targetSdkVersion */, seInfo,
                     abi, instructionSet, null /* appDataDir */, null /* invokeWith */,
                     true /* startChildZygote */, null /* packageName */,
-                    false /* useUsapPool */, false /*useSystemGraphicsDriver*/,
-                    extraArgs);
+                    false /* useUsapPool */, extraArgs);
         } catch (ZygoteStartFailedEx ex) {
             throw new RuntimeException("Starting child-zygote through Zygote failed", ex);
         }
diff --git a/core/java/android/permission/PermissionManager.java b/core/java/android/permission/PermissionManager.java
index e15659d..182a2ff 100644
--- a/core/java/android/permission/PermissionManager.java
+++ b/core/java/android/permission/PermissionManager.java
@@ -39,6 +39,7 @@
  *
  * @hide
  */
+@TestApi
 @SystemApi
 @SystemService(Context.PERMISSION_SERVICE)
 public final class PermissionManager {
@@ -140,12 +141,13 @@
             if (o == null || getClass() != o.getClass()) return false;
             SplitPermissionInfo that = (SplitPermissionInfo) o;
             return mTargetSdk == that.mTargetSdk
-                    && Objects.equals(mSplitPerm, that.mSplitPerm);
+                    && mSplitPerm.equals(that.mSplitPerm)
+                    && mNewPerms.equals(that.mNewPerms);
         }
 
         @Override
         public int hashCode() {
-            return Objects.hash(mSplitPerm, mTargetSdk);
+            return Objects.hash(mSplitPerm, mNewPerms, mTargetSdk);
         }
 
         /**
diff --git a/core/java/android/provider/DeviceConfig.java b/core/java/android/provider/DeviceConfig.java
index 9a11104..19dbc6a 100644
--- a/core/java/android/provider/DeviceConfig.java
+++ b/core/java/android/provider/DeviceConfig.java
@@ -48,6 +48,8 @@
 
 /**
  * Device level configuration parameters which can be tuned by a separate configuration service.
+ * Namespaces that end in "_native" such as {@link #NAMESPACE_NETD_NATIVE} are intended to be used
+ * by native code and should be pushed to system properties to make them accessible.
  *
  * @hide
  */
diff --git a/core/java/android/provider/OWNERS b/core/java/android/provider/OWNERS
new file mode 100644
index 0000000..8b7d6ad
--- /dev/null
+++ b/core/java/android/provider/OWNERS
@@ -0,0 +1,4 @@
+per-file DeviceConfig.java = svetoslavganov@google.com
+per-file DeviceConfig.java = hackbod@google.com
+
+
diff --git a/core/java/android/provider/Settings.java b/core/java/android/provider/Settings.java
index 0db5c36..383d8db 100644
--- a/core/java/android/provider/Settings.java
+++ b/core/java/android/provider/Settings.java
@@ -11649,16 +11649,6 @@
                 = "activity_starts_logging_enabled";
 
         /**
-         * Feature flag to enable or disable the background activity starts.
-         * When disabled, apps aren't allowed to start activities unless they're in the foreground.
-         * Type: int (0 for false, 1 for true)
-         * Default: 1
-         * @hide
-         */
-        public static final String BACKGROUND_ACTIVITY_STARTS_ENABLED =
-                "background_activity_starts_enabled";
-
-        /**
          * @hide
          * @see com.android.server.appbinding.AppBindingConstants
          */
@@ -12675,6 +12665,14 @@
         public static final String GAME_DRIVER_OPT_IN_APPS = "game_driver_opt_in_apps";
 
         /**
+         * List of Apps selected to use prerelease Game Driver.
+         * i.e. <pkg1>,<pkg2>,...,<pkgN>
+         * @hide
+         */
+        public static final String GAME_DRIVER_PRERELEASE_OPT_IN_APPS =
+                "game_driver_prerelease_opt_in_apps";
+
+        /**
          * List of Apps selected not to use Game Driver.
          * i.e. <pkg1>,<pkg2>,...,<pkgN>
          * @hide
@@ -13579,39 +13577,6 @@
                 "location_global_kill_switch";
 
         /**
-         * If set to 1, the device identifier check will be relaxed to the previous READ_PHONE_STATE
-         * permission check for 3P apps.
-         *
-         * STOPSHIP: Remove this once we ship with the new device identifier check enabled.
-         *
-         * @hide
-         */
-        public static final String PRIVILEGED_DEVICE_IDENTIFIER_3P_CHECK_RELAXED =
-                "privileged_device_identifier_3p_check_relaxed";
-
-        /**
-         * If set to 1, the device identifier check will be relaxed to the previous READ_PHONE_STATE
-         * permission check for preloaded non-privileged apps.
-         *
-         * STOPSHIP: Remove this once we ship with the new device identifier check enabled.
-         *
-         * @hide
-         */
-        public static final String PRIVILEGED_DEVICE_IDENTIFIER_NON_PRIV_CHECK_RELAXED =
-                "privileged_device_identifier_non_priv_check_relaxed";
-
-        /**
-         * If set to 1, the device identifier check will be relaxed to the previous READ_PHONE_STATE
-         * permission check for preloaded privileged apps.
-         *
-         * STOPSHIP: Remove this once we ship with the new device identifier check enabled.
-         *
-         * @hide
-         */
-        public static final String PRIVILEGED_DEVICE_IDENTIFIER_PRIV_CHECK_RELAXED =
-                "privileged_device_identifier_priv_check_relaxed";
-
-        /**
          * If set to 1, SettingsProvider's restoreAnyVersion="true" attribute will be ignored
          * and restoring to lower version of platform API will be skipped.
          *
@@ -15418,4 +15383,4 @@
         }
         return packages[0];
     }
-}
\ No newline at end of file
+}
diff --git a/core/java/android/service/notification/NotificationListenerService.java b/core/java/android/service/notification/NotificationListenerService.java
index 3ec21e3..b44c9d5 100644
--- a/core/java/android/service/notification/NotificationListenerService.java
+++ b/core/java/android/service/notification/NotificationListenerService.java
@@ -42,7 +42,6 @@
 import android.graphics.drawable.Drawable;
 import android.graphics.drawable.Icon;
 import android.os.Build;
-import android.os.Bundle;
 import android.os.Handler;
 import android.os.IBinder;
 import android.os.Looper;
@@ -53,7 +52,6 @@
 import android.os.ServiceManager;
 import android.os.UserHandle;
 import android.util.ArrayMap;
-import android.util.ArraySet;
 import android.util.Log;
 import android.widget.RemoteViews;
 
@@ -64,8 +62,8 @@
 import java.lang.annotation.Retention;
 import java.lang.annotation.RetentionPolicy;
 import java.util.ArrayList;
-import java.util.Collections;
 import java.util.List;
+import java.util.Objects;
 
 /**
  * A service that receives calls from the system when new notifications are
@@ -1201,20 +1199,25 @@
         }
     }
 
-    /** Convert new-style Icons to legacy representations for pre-M clients. */
-    private void createLegacyIconExtras(Notification n) {
-        Icon smallIcon = n.getSmallIcon();
-        Icon largeIcon = n.getLargeIcon();
-        if (smallIcon != null && smallIcon.getType() == Icon.TYPE_RESOURCE) {
-            n.extras.putInt(Notification.EXTRA_SMALL_ICON, smallIcon.getResId());
-            n.icon = smallIcon.getResId();
-        }
-        if (largeIcon != null) {
-            Drawable d = largeIcon.loadDrawable(getContext());
-            if (d != null && d instanceof BitmapDrawable) {
-                final Bitmap largeIconBits = ((BitmapDrawable) d).getBitmap();
-                n.extras.putParcelable(Notification.EXTRA_LARGE_ICON, largeIconBits);
-                n.largeIcon = largeIconBits;
+    /**
+     * Convert new-style Icons to legacy representations for pre-M clients.
+     * @hide
+     */
+    public final void createLegacyIconExtras(Notification n) {
+        if (getContext().getApplicationInfo().targetSdkVersion < Build.VERSION_CODES.M) {
+            Icon smallIcon = n.getSmallIcon();
+            Icon largeIcon = n.getLargeIcon();
+            if (smallIcon != null && smallIcon.getType() == Icon.TYPE_RESOURCE) {
+                n.extras.putInt(Notification.EXTRA_SMALL_ICON, smallIcon.getResId());
+                n.icon = smallIcon.getResId();
+            }
+            if (largeIcon != null) {
+                Drawable d = largeIcon.loadDrawable(getContext());
+                if (d != null && d instanceof BitmapDrawable) {
+                    final Bitmap largeIconBits = ((BitmapDrawable) d).getBitmap();
+                    n.extras.putParcelable(Notification.EXTRA_LARGE_ICON, largeIconBits);
+                    n.largeIcon = largeIconBits;
+                }
             }
         }
     }
@@ -1442,7 +1445,7 @@
      */
     @GuardedBy("mLock")
     public final void applyUpdateLocked(NotificationRankingUpdate update) {
-        mRankingMap = new RankingMap(update);
+        mRankingMap = update.getRankingMap();
     }
 
     /** @hide */
@@ -1480,14 +1483,14 @@
          */
         public static final int USER_SENTIMENT_POSITIVE = 1;
 
-        /** @hide */
+       /** @hide */
         @IntDef(prefix = { "USER_SENTIMENT_" }, value = {
                 USER_SENTIMENT_NEGATIVE, USER_SENTIMENT_NEUTRAL, USER_SENTIMENT_POSITIVE
         })
         @Retention(RetentionPolicy.SOURCE)
         public @interface UserSentiment {}
 
-        private String mKey;
+        private @NonNull String mKey;
         private int mRank = -1;
         private boolean mIsAmbient;
         private boolean mMatchesInterruptionFilter;
@@ -1512,7 +1515,70 @@
         private ArrayList<CharSequence> mSmartReplies;
         private boolean mCanBubble;
 
-        public Ranking() {}
+        private static final int PARCEL_VERSION = 2;
+
+        public Ranking() { }
+
+        // You can parcel it, but it's not Parcelable
+        /** @hide */
+        @VisibleForTesting
+        public void writeToParcel(Parcel out, int flags) {
+            final long start = out.dataPosition();
+            out.writeInt(PARCEL_VERSION);
+            out.writeString(mKey);
+            out.writeInt(mRank);
+            out.writeBoolean(mIsAmbient);
+            out.writeBoolean(mMatchesInterruptionFilter);
+            out.writeInt(mVisibilityOverride);
+            out.writeInt(mSuppressedVisualEffects);
+            out.writeInt(mImportance);
+            out.writeCharSequence(mImportanceExplanation);
+            out.writeString(mOverrideGroupKey);
+            out.writeParcelable(mChannel, flags);
+            out.writeStringList(mOverridePeople);
+            out.writeTypedList(mSnoozeCriteria, flags);
+            out.writeBoolean(mShowBadge);
+            out.writeInt(mUserSentiment);
+            out.writeBoolean(mHidden);
+            out.writeLong(mLastAudiblyAlertedMs);
+            out.writeBoolean(mNoisy);
+            out.writeTypedList(mSmartActions, flags);
+            out.writeCharSequenceList(mSmartReplies);
+            out.writeBoolean(mCanBubble);
+        }
+
+        /** @hide */
+        @VisibleForTesting
+        public Ranking(Parcel in) {
+            final ClassLoader cl = getClass().getClassLoader();
+
+            final int version = in.readInt();
+            if (version != PARCEL_VERSION) {
+                throw new IllegalArgumentException("malformed Ranking parcel: " + in + " version "
+                        + version + ", expected " + PARCEL_VERSION);
+            }
+            mKey = in.readString();
+            mRank = in.readInt();
+            mIsAmbient = in.readBoolean();
+            mMatchesInterruptionFilter = in.readBoolean();
+            mVisibilityOverride = in.readInt();
+            mSuppressedVisualEffects = in.readInt();
+            mImportance = in.readInt();
+            mImportanceExplanation = in.readCharSequence(); // may be null
+            mOverrideGroupKey = in.readString(); // may be null
+            mChannel = (NotificationChannel) in.readParcelable(cl); // may be null
+            mOverridePeople = in.createStringArrayList();
+            mSnoozeCriteria = in.createTypedArrayList(SnoozeCriterion.CREATOR);
+            mShowBadge = in.readBoolean();
+            mUserSentiment = in.readInt();
+            mHidden = in.readBoolean();
+            mLastAudiblyAlertedMs = in.readLong();
+            mNoisy = in.readBoolean();
+            mSmartActions = in.createTypedArrayList(Notification.Action.CREATOR);
+            mSmartReplies = in.readCharSequenceList();
+            mCanBubble = in.readBoolean();
+        }
+
 
         /**
          * Returns the key of the notification this Ranking applies to.
@@ -1737,6 +1803,31 @@
         }
 
         /**
+         * @hide
+         */
+        public void populate(Ranking other) {
+            populate(other.mKey,
+                    other.mRank,
+                    other.mMatchesInterruptionFilter,
+                    other.mVisibilityOverride,
+                    other.mSuppressedVisualEffects,
+                    other.mImportance,
+                    other.mImportanceExplanation,
+                    other.mOverrideGroupKey,
+                    other.mChannel,
+                    other.mOverridePeople,
+                    other.mSnoozeCriteria,
+                    other.mShowBadge,
+                    other.mUserSentiment,
+                    other.mHidden,
+                    other.mLastAudiblyAlertedMs,
+                    other.mNoisy,
+                    other.mSmartActions,
+                    other.mSmartReplies,
+                    other.mCanBubble);
+        }
+
+        /**
          * {@hide}
          */
         public static String importanceToString(int importance) {
@@ -1758,6 +1849,35 @@
                     return "UNKNOWN(" + String.valueOf(importance) + ")";
             }
         }
+
+        @Override
+        public boolean equals(Object o) {
+            if (this == o) return true;
+            if (o == null || getClass() != o.getClass()) return false;
+
+            Ranking other = (Ranking) o;
+            return Objects.equals(mKey, other.mKey)
+                    && Objects.equals(mRank, other.mRank)
+                    && Objects.equals(mMatchesInterruptionFilter, other.mMatchesInterruptionFilter)
+                    && Objects.equals(mVisibilityOverride, other.mVisibilityOverride)
+                    && Objects.equals(mSuppressedVisualEffects, other.mSuppressedVisualEffects)
+                    && Objects.equals(mImportance, other.mImportance)
+                    && Objects.equals(mImportanceExplanation, other.mImportanceExplanation)
+                    && Objects.equals(mOverrideGroupKey, other.mOverrideGroupKey)
+                    && Objects.equals(mChannel, other.mChannel)
+                    && Objects.equals(mOverridePeople, other.mOverridePeople)
+                    && Objects.equals(mSnoozeCriteria, other.mSnoozeCriteria)
+                    && Objects.equals(mShowBadge, other.mShowBadge)
+                    && Objects.equals(mUserSentiment, other.mUserSentiment)
+                    && Objects.equals(mHidden, other.mHidden)
+                    && Objects.equals(mLastAudiblyAlertedMs, other.mLastAudiblyAlertedMs)
+                    && Objects.equals(mNoisy, other.mNoisy)
+                    // Action.equals() doesn't exist so let's just compare list lengths
+                    && ((mSmartActions == null ? 0 : mSmartActions.size())
+                        == (other.mSmartActions == null ? 0 : other.mSmartActions.size()))
+                    && Objects.equals(mSmartReplies, other.mSmartReplies)
+                    && Objects.equals(mCanBubble, other.mCanBubble);
+        }
     }
 
     /**
@@ -1769,30 +1889,74 @@
      * notifications active at the time of retrieval.
      */
     public static class RankingMap implements Parcelable {
-        private final NotificationRankingUpdate mRankingUpdate;
-        private ArrayMap<String,Integer> mRanks;
-        private ArraySet<Object> mIntercepted;
-        private ArrayMap<String, Integer> mVisibilityOverrides;
-        private ArrayMap<String, Integer> mSuppressedVisualEffects;
-        private ArrayMap<String, Integer> mImportance;
-        private ArrayMap<String, String> mImportanceExplanation;
-        private ArrayMap<String, String> mOverrideGroupKeys;
-        private ArrayMap<String, NotificationChannel> mChannels;
-        private ArrayMap<String, ArrayList<String>> mOverridePeople;
-        private ArrayMap<String, ArrayList<SnoozeCriterion>> mSnoozeCriteria;
-        private ArrayMap<String, Boolean> mShowBadge;
-        private ArrayMap<String, Integer> mUserSentiment;
-        private ArrayMap<String, Boolean> mHidden;
-        private ArrayMap<String, Long> mLastAudiblyAlerted;
-        private ArrayMap<String, Boolean> mNoisy;
-        private ArrayMap<String, ArrayList<Notification.Action>> mSmartActions;
-        private ArrayMap<String, ArrayList<CharSequence>> mSmartReplies;
-        private boolean[] mCanBubble;
+        private ArrayList<String> mOrderedKeys = new ArrayList<>();
+        // Note: all String keys should be intern'd as pointers into mOrderedKeys
+        private ArrayMap<String, Ranking> mRankings = new ArrayMap<>();
 
-        private RankingMap(NotificationRankingUpdate rankingUpdate) {
-            mRankingUpdate = rankingUpdate;
+        /**
+         * @hide
+         */
+        public RankingMap(Ranking[] rankings) {
+            for (int i = 0; i < rankings.length; i++) {
+                final String key = rankings[i].getKey();
+                mOrderedKeys.add(key);
+                mRankings.put(key, rankings[i]);
+            }
         }
 
+        // -- parcelable interface --
+
+        private RankingMap(Parcel in) {
+            final ClassLoader cl = getClass().getClassLoader();
+            final int count = in.readInt();
+            mOrderedKeys.ensureCapacity(count);
+            mRankings.ensureCapacity(count);
+            for (int i = 0; i < count; i++) {
+                final Ranking r = new Ranking(in);
+                final String key = r.getKey();
+                mOrderedKeys.add(key);
+                mRankings.put(key, r);
+            }
+        }
+
+        @Override
+        public boolean equals(Object o) {
+            if (this == o) return true;
+            if (o == null || getClass() != o.getClass()) return false;
+
+            RankingMap other = (RankingMap) o;
+
+            return mOrderedKeys.equals(other.mOrderedKeys)
+                    && mRankings.equals(other.mRankings);
+
+        }
+
+        @Override
+        public int describeContents() {
+            return 0;
+        }
+
+        @Override
+        public void writeToParcel(Parcel out, int flags) {
+            final int count = mOrderedKeys.size();
+            out.writeInt(count);
+            for (int i = 0; i < count; i++) {
+                mRankings.get(mOrderedKeys.get(i)).writeToParcel(out, flags);
+            }
+        }
+
+        public static final @android.annotation.NonNull Creator<RankingMap> CREATOR = new Creator<RankingMap>() {
+            @Override
+            public RankingMap createFromParcel(Parcel source) {
+                return new RankingMap(source);
+            }
+
+            @Override
+            public RankingMap[] newArray(int size) {
+                return new RankingMap[size];
+            }
+        };
+
         /**
          * Request the list of notification keys in their current ranking
          * order.
@@ -1800,7 +1964,7 @@
          * @return An array of active notification keys, in their ranking order.
          */
         public String[] getOrderedKeys() {
-            return mRankingUpdate.getOrderedKeys();
+            return mOrderedKeys.toArray(new String[0]);
         }
 
         /**
@@ -1808,381 +1972,26 @@
          * with the given key.
          *
          * @return true if a valid key has been passed and outRanking has
-         *     been populated; false otherwise
+         * been populated; false otherwise
          */
         public boolean getRanking(String key, Ranking outRanking) {
-            int rank = getRank(key);
-            outRanking.populate(key, rank, !isIntercepted(key),
-                    getVisibilityOverride(key), getSuppressedVisualEffects(key),
-                    getImportance(key), getImportanceExplanation(key), getOverrideGroupKey(key),
-                    getChannel(key), getOverridePeople(key), getSnoozeCriteria(key),
-                    getShowBadge(key), getUserSentiment(key), getHidden(key),
-                    getLastAudiblyAlerted(key), getNoisy(key), getSmartActions(key),
-                    getSmartReplies(key), canBubble(key));
-            return rank >= 0;
-        }
-
-        private int getRank(String key) {
-            synchronized (this) {
-                if (mRanks == null) {
-                    buildRanksLocked();
-                }
+            if (mRankings.containsKey(key)) {
+                outRanking.populate(mRankings.get(key));
+                return true;
             }
-            Integer rank = mRanks.get(key);
-            return rank != null ? rank : -1;
+            return false;
         }
 
-        private boolean isIntercepted(String key) {
-            synchronized (this) {
-                if (mIntercepted == null) {
-                    buildInterceptedSetLocked();
-                }
-            }
-            return mIntercepted.contains(key);
+        /**
+         * Get a reference to the actual Ranking object corresponding to the key.
+         * Used only by unit tests.
+         *
+         * @hide
+         */
+        @VisibleForTesting
+        public Ranking getRawRankingObject(String key) {
+            return mRankings.get(key);
         }
-
-        private int getVisibilityOverride(String key) {
-            synchronized (this) {
-                if (mVisibilityOverrides == null) {
-                    buildVisibilityOverridesLocked();
-                }
-            }
-            Integer override = mVisibilityOverrides.get(key);
-            if (override == null) {
-                return Ranking.VISIBILITY_NO_OVERRIDE;
-            }
-            return override.intValue();
-        }
-
-        private int getSuppressedVisualEffects(String key) {
-            synchronized (this) {
-                if (mSuppressedVisualEffects == null) {
-                    buildSuppressedVisualEffectsLocked();
-                }
-            }
-            Integer suppressed = mSuppressedVisualEffects.get(key);
-            if (suppressed == null) {
-                return 0;
-            }
-            return suppressed.intValue();
-        }
-
-        private int getImportance(String key) {
-            synchronized (this) {
-                if (mImportance == null) {
-                    buildImportanceLocked();
-                }
-            }
-            Integer importance = mImportance.get(key);
-            if (importance == null) {
-                return NotificationManager.IMPORTANCE_DEFAULT;
-            }
-            return importance.intValue();
-        }
-
-        private String getImportanceExplanation(String key) {
-            synchronized (this) {
-                if (mImportanceExplanation == null) {
-                    buildImportanceExplanationLocked();
-                }
-            }
-            return mImportanceExplanation.get(key);
-        }
-
-        private String getOverrideGroupKey(String key) {
-            synchronized (this) {
-                if (mOverrideGroupKeys == null) {
-                    buildOverrideGroupKeys();
-                }
-            }
-            return mOverrideGroupKeys.get(key);
-        }
-
-        private NotificationChannel getChannel(String key) {
-            synchronized (this) {
-                if (mChannels == null) {
-                    buildChannelsLocked();
-                }
-            }
-            return mChannels.get(key);
-        }
-
-        private ArrayList<String> getOverridePeople(String key) {
-            synchronized (this) {
-                if (mOverridePeople == null) {
-                    buildOverridePeopleLocked();
-                }
-            }
-            return mOverridePeople.get(key);
-        }
-
-        private ArrayList<SnoozeCriterion> getSnoozeCriteria(String key) {
-            synchronized (this) {
-                if (mSnoozeCriteria == null) {
-                    buildSnoozeCriteriaLocked();
-                }
-            }
-            return mSnoozeCriteria.get(key);
-        }
-
-        private boolean getShowBadge(String key) {
-            synchronized (this) {
-                if (mShowBadge == null) {
-                    buildShowBadgeLocked();
-                }
-            }
-            Boolean showBadge = mShowBadge.get(key);
-            return showBadge == null ? false : showBadge.booleanValue();
-        }
-
-        private int getUserSentiment(String key) {
-            synchronized (this) {
-                if (mUserSentiment == null) {
-                    buildUserSentimentLocked();
-                }
-            }
-            Integer userSentiment = mUserSentiment.get(key);
-            return userSentiment == null
-                    ? Ranking.USER_SENTIMENT_NEUTRAL : userSentiment.intValue();
-        }
-
-        private boolean getHidden(String key) {
-            synchronized (this) {
-                if (mHidden == null) {
-                    buildHiddenLocked();
-                }
-            }
-            Boolean hidden = mHidden.get(key);
-            return hidden == null ? false : hidden.booleanValue();
-        }
-
-        private long getLastAudiblyAlerted(String key) {
-            synchronized (this) {
-                if (mLastAudiblyAlerted == null) {
-                    buildLastAudiblyAlertedLocked();
-                }
-            }
-            Long lastAudibleAlerted = mLastAudiblyAlerted.get(key);
-            return lastAudibleAlerted == null ? -1 : lastAudibleAlerted.longValue();
-        }
-
-        private boolean getNoisy(String key) {
-            synchronized (this) {
-                if (mNoisy == null) {
-                    buildNoisyLocked();
-                }
-            }
-            Boolean noisy = mNoisy.get(key);
-            return noisy == null ? false : noisy.booleanValue();
-        }
-
-        private ArrayList<Notification.Action> getSmartActions(String key) {
-            synchronized (this) {
-                if (mSmartActions == null) {
-                    buildSmartActions();
-                }
-            }
-            return mSmartActions.get(key);
-        }
-
-        private ArrayList<CharSequence> getSmartReplies(String key) {
-            synchronized (this) {
-                if (mSmartReplies == null) {
-                    buildSmartReplies();
-                }
-            }
-            return mSmartReplies.get(key);
-        }
-
-        private boolean canBubble(String key) {
-            synchronized (this) {
-                if (mRanks == null) {
-                    buildRanksLocked();
-                }
-                if (mCanBubble == null) {
-                    mCanBubble = mRankingUpdate.getCanBubble();
-                }
-            }
-            int keyIndex = mRanks.getOrDefault(key, -1);
-            return keyIndex >= 0 ? mCanBubble[keyIndex] : false;
-        }
-
-        // Locked by 'this'
-        private void buildRanksLocked() {
-            String[] orderedKeys = mRankingUpdate.getOrderedKeys();
-            mRanks = new ArrayMap<>(orderedKeys.length);
-            for (int i = 0; i < orderedKeys.length; i++) {
-                String key = orderedKeys[i];
-                mRanks.put(key, i);
-            }
-        }
-
-        // Locked by 'this'
-        private void buildInterceptedSetLocked() {
-            String[] dndInterceptedKeys = mRankingUpdate.getInterceptedKeys();
-            mIntercepted = new ArraySet<>(dndInterceptedKeys.length);
-            Collections.addAll(mIntercepted, dndInterceptedKeys);
-        }
-
-        private ArrayMap<String, Integer> buildIntMapFromBundle(Bundle bundle) {
-            ArrayMap<String, Integer> newMap = new ArrayMap<>(bundle.size());
-            for (String key : bundle.keySet()) {
-                newMap.put(key, bundle.getInt(key));
-            }
-            return newMap;
-        }
-
-        private ArrayMap<String, String> buildStringMapFromBundle(Bundle bundle) {
-            ArrayMap<String, String> newMap = new ArrayMap<>(bundle.size());
-            for (String key : bundle.keySet()) {
-                newMap.put(key, bundle.getString(key));
-            }
-            return newMap;
-        }
-
-        private ArrayMap<String, Boolean> buildBooleanMapFromBundle(Bundle bundle) {
-            ArrayMap<String, Boolean> newMap = new ArrayMap<>(bundle.size());
-            for (String key : bundle.keySet()) {
-                newMap.put(key, bundle.getBoolean(key));
-            }
-            return newMap;
-        }
-
-        private ArrayMap<String, Long> buildLongMapFromBundle(Bundle bundle) {
-            ArrayMap<String, Long> newMap = new ArrayMap<>(bundle.size());
-            for (String key : bundle.keySet()) {
-                newMap.put(key, bundle.getLong(key));
-            }
-            return newMap;
-        }
-
-        // Locked by 'this'
-        private void buildVisibilityOverridesLocked() {
-            mVisibilityOverrides = buildIntMapFromBundle(mRankingUpdate.getVisibilityOverrides());
-        }
-
-        // Locked by 'this'
-        private void buildSuppressedVisualEffectsLocked() {
-            mSuppressedVisualEffects =
-                buildIntMapFromBundle(mRankingUpdate.getSuppressedVisualEffects());
-        }
-
-        // Locked by 'this'
-        private void buildImportanceLocked() {
-            String[] orderedKeys = mRankingUpdate.getOrderedKeys();
-            int[] importance = mRankingUpdate.getImportance();
-            mImportance = new ArrayMap<>(orderedKeys.length);
-            for (int i = 0; i < orderedKeys.length; i++) {
-                String key = orderedKeys[i];
-                mImportance.put(key, importance[i]);
-            }
-        }
-
-        // Locked by 'this'
-        private void buildImportanceExplanationLocked() {
-            mImportanceExplanation =
-                buildStringMapFromBundle(mRankingUpdate.getImportanceExplanation());
-        }
-
-        // Locked by 'this'
-        private void buildOverrideGroupKeys() {
-            mOverrideGroupKeys = buildStringMapFromBundle(mRankingUpdate.getOverrideGroupKeys());
-        }
-
-        // Locked by 'this'
-        private void buildChannelsLocked() {
-            Bundle channels = mRankingUpdate.getChannels();
-            mChannels = new ArrayMap<>(channels.size());
-            for (String key : channels.keySet()) {
-                mChannels.put(key, channels.getParcelable(key));
-            }
-        }
-
-        // Locked by 'this'
-        private void buildOverridePeopleLocked() {
-            Bundle overridePeople = mRankingUpdate.getOverridePeople();
-            mOverridePeople = new ArrayMap<>(overridePeople.size());
-            for (String key : overridePeople.keySet()) {
-                mOverridePeople.put(key, overridePeople.getStringArrayList(key));
-            }
-        }
-
-        // Locked by 'this'
-        private void buildSnoozeCriteriaLocked() {
-            Bundle snoozeCriteria = mRankingUpdate.getSnoozeCriteria();
-            mSnoozeCriteria = new ArrayMap<>(snoozeCriteria.size());
-            for (String key : snoozeCriteria.keySet()) {
-                mSnoozeCriteria.put(key, snoozeCriteria.getParcelableArrayList(key));
-            }
-        }
-
-        // Locked by 'this'
-        private void buildShowBadgeLocked() {
-            mShowBadge = buildBooleanMapFromBundle(mRankingUpdate.getShowBadge());
-        }
-
-        // Locked by 'this'
-        private void buildUserSentimentLocked() {
-            mUserSentiment = buildIntMapFromBundle(mRankingUpdate.getUserSentiment());
-        }
-
-        // Locked by 'this'
-        private void buildHiddenLocked() {
-            mHidden = buildBooleanMapFromBundle(mRankingUpdate.getHidden());
-        }
-
-        // Locked by 'this'
-        private void buildLastAudiblyAlertedLocked() {
-            mLastAudiblyAlerted = buildLongMapFromBundle(mRankingUpdate.getLastAudiblyAlerted());
-        }
-
-        // Locked by 'this'
-        private void buildNoisyLocked() {
-            mNoisy = buildBooleanMapFromBundle(mRankingUpdate.getNoisy());
-        }
-
-        // Locked by 'this'
-        private void buildSmartActions() {
-            Bundle smartActions = mRankingUpdate.getSmartActions();
-            mSmartActions = new ArrayMap<>(smartActions.size());
-            for (String key : smartActions.keySet()) {
-                mSmartActions.put(key, smartActions.getParcelableArrayList(key));
-            }
-        }
-
-        // Locked by 'this'
-        private void buildSmartReplies() {
-            Bundle smartReplies = mRankingUpdate.getSmartReplies();
-            mSmartReplies = new ArrayMap<>(smartReplies.size());
-            for (String key : smartReplies.keySet()) {
-                mSmartReplies.put(key, smartReplies.getCharSequenceArrayList(key));
-            }
-        }
-
-        // ----------- Parcelable
-
-        @Override
-        public int describeContents() {
-            return 0;
-        }
-
-        @Override
-        public void writeToParcel(Parcel dest, int flags) {
-            dest.writeParcelable(mRankingUpdate, flags);
-        }
-
-        public static final @android.annotation.NonNull Creator<RankingMap> CREATOR = new Creator<RankingMap>() {
-            @Override
-            public RankingMap createFromParcel(Parcel source) {
-                NotificationRankingUpdate rankingUpdate = source.readParcelable(null);
-                return new RankingMap(rankingUpdate);
-            }
-
-            @Override
-            public RankingMap[] newArray(int size) {
-                return new RankingMap[size];
-            }
-        };
     }
 
     private final class MyHandler extends Handler {
diff --git a/core/java/android/service/notification/NotificationRankingUpdate.java b/core/java/android/service/notification/NotificationRankingUpdate.java
index c5c70f8..675c5cd 100644
--- a/core/java/android/service/notification/NotificationRankingUpdate.java
+++ b/core/java/android/service/notification/NotificationRankingUpdate.java
@@ -15,7 +15,6 @@
  */
 package android.service.notification;
 
-import android.os.Bundle;
 import android.os.Parcel;
 import android.os.Parcelable;
 
@@ -23,73 +22,18 @@
  * @hide
  */
 public class NotificationRankingUpdate implements Parcelable {
-    // TODO: Support incremental updates.
-    private final String[] mKeys;
-    private final String[] mInterceptedKeys;
-    private final Bundle mVisibilityOverrides;
-    private final Bundle mSuppressedVisualEffects;
-    private final int[] mImportance;
-    private final Bundle mImportanceExplanation;
-    private final Bundle mOverrideGroupKeys;
-    private final Bundle mChannels;
-    private final Bundle mOverridePeople;
-    private final Bundle mSnoozeCriteria;
-    private final Bundle mShowBadge;
-    private final Bundle mUserSentiment;
-    private final Bundle mHidden;
-    private final Bundle mSmartActions;
-    private final Bundle mSmartReplies;
-    private final Bundle mLastAudiblyAlerted;
-    private final Bundle mNoisy;
-    private final boolean[] mCanBubble;
+    private final NotificationListenerService.RankingMap mRankingMap;
 
-    public NotificationRankingUpdate(String[] keys, String[] interceptedKeys,
-            Bundle visibilityOverrides, Bundle suppressedVisualEffects,
-            int[] importance, Bundle explanation, Bundle overrideGroupKeys,
-            Bundle channels, Bundle overridePeople, Bundle snoozeCriteria,
-            Bundle showBadge, Bundle userSentiment, Bundle hidden, Bundle smartActions,
-            Bundle smartReplies, Bundle lastAudiblyAlerted, Bundle noisy, boolean[] canBubble) {
-        mKeys = keys;
-        mInterceptedKeys = interceptedKeys;
-        mVisibilityOverrides = visibilityOverrides;
-        mSuppressedVisualEffects = suppressedVisualEffects;
-        mImportance = importance;
-        mImportanceExplanation = explanation;
-        mOverrideGroupKeys = overrideGroupKeys;
-        mChannels = channels;
-        mOverridePeople = overridePeople;
-        mSnoozeCriteria = snoozeCriteria;
-        mShowBadge = showBadge;
-        mUserSentiment = userSentiment;
-        mHidden = hidden;
-        mSmartActions = smartActions;
-        mSmartReplies = smartReplies;
-        mLastAudiblyAlerted = lastAudiblyAlerted;
-        mNoisy = noisy;
-        mCanBubble = canBubble;
+    public NotificationRankingUpdate(NotificationListenerService.Ranking[] rankings) {
+        mRankingMap = new NotificationListenerService.RankingMap(rankings);
     }
 
     public NotificationRankingUpdate(Parcel in) {
-        mKeys = in.readStringArray();
-        mInterceptedKeys = in.readStringArray();
-        mVisibilityOverrides = in.readBundle();
-        mSuppressedVisualEffects = in.readBundle();
-        mImportance = new int[mKeys.length];
-        in.readIntArray(mImportance);
-        mImportanceExplanation = in.readBundle();
-        mOverrideGroupKeys = in.readBundle();
-        mChannels = in.readBundle();
-        mOverridePeople = in.readBundle();
-        mSnoozeCriteria = in.readBundle();
-        mShowBadge = in.readBundle();
-        mUserSentiment = in.readBundle();
-        mHidden = in.readBundle();
-        mSmartActions = in.readBundle();
-        mSmartReplies = in.readBundle();
-        mLastAudiblyAlerted = in.readBundle();
-        mNoisy = in.readBundle();
-        mCanBubble = new boolean[mKeys.length];
-        in.readBooleanArray(mCanBubble);
+        mRankingMap = in.readParcelable(getClass().getClassLoader());
+    }
+
+    public NotificationListenerService.RankingMap getRankingMap() {
+        return mRankingMap;
     }
 
     @Override
@@ -98,25 +42,17 @@
     }
 
     @Override
+    public boolean equals(Object o) {
+        if (this == o) return true;
+        if (o == null || getClass() != o.getClass()) return false;
+
+        NotificationRankingUpdate other = (NotificationRankingUpdate) o;
+        return mRankingMap.equals(other.mRankingMap);
+    }
+
+    @Override
     public void writeToParcel(Parcel out, int flags) {
-        out.writeStringArray(mKeys);
-        out.writeStringArray(mInterceptedKeys);
-        out.writeBundle(mVisibilityOverrides);
-        out.writeBundle(mSuppressedVisualEffects);
-        out.writeIntArray(mImportance);
-        out.writeBundle(mImportanceExplanation);
-        out.writeBundle(mOverrideGroupKeys);
-        out.writeBundle(mChannels);
-        out.writeBundle(mOverridePeople);
-        out.writeBundle(mSnoozeCriteria);
-        out.writeBundle(mShowBadge);
-        out.writeBundle(mUserSentiment);
-        out.writeBundle(mHidden);
-        out.writeBundle(mSmartActions);
-        out.writeBundle(mSmartReplies);
-        out.writeBundle(mLastAudiblyAlerted);
-        out.writeBundle(mNoisy);
-        out.writeBooleanArray(mCanBubble);
+        out.writeParcelable(mRankingMap, flags);
     }
 
     public static final @android.annotation.NonNull Parcelable.Creator<NotificationRankingUpdate> CREATOR
@@ -129,76 +65,4 @@
             return new NotificationRankingUpdate[size];
         }
     };
-
-    public String[] getOrderedKeys() {
-        return mKeys;
-    }
-
-    public String[] getInterceptedKeys() {
-        return mInterceptedKeys;
-    }
-
-    public Bundle getVisibilityOverrides() {
-        return mVisibilityOverrides;
-    }
-
-    public Bundle getSuppressedVisualEffects() {
-        return mSuppressedVisualEffects;
-    }
-
-    public int[] getImportance() {
-        return mImportance;
-    }
-
-    public Bundle getImportanceExplanation() {
-        return mImportanceExplanation;
-    }
-
-    public Bundle getOverrideGroupKeys() {
-        return mOverrideGroupKeys;
-    }
-
-    public Bundle getChannels() {
-        return mChannels;
-    }
-
-    public Bundle getOverridePeople() {
-        return mOverridePeople;
-    }
-
-    public Bundle getSnoozeCriteria() {
-        return mSnoozeCriteria;
-    }
-
-    public Bundle getShowBadge() {
-        return mShowBadge;
-    }
-
-    public Bundle getUserSentiment() {
-        return mUserSentiment;
-    }
-
-    public Bundle getHidden() {
-        return mHidden;
-    }
-
-    public Bundle getSmartActions() {
-        return mSmartActions;
-    }
-
-    public Bundle getSmartReplies() {
-        return mSmartReplies;
-    }
-
-    public Bundle getLastAudiblyAlerted() {
-        return mLastAudiblyAlerted;
-    }
-
-    public Bundle getNoisy() {
-        return mNoisy;
-    }
-
-    public boolean[] getCanBubble() {
-        return mCanBubble;
-    }
 }
diff --git a/core/java/android/text/util/Linkify.java b/core/java/android/text/util/Linkify.java
index 50e7ec3..df54209 100644
--- a/core/java/android/text/util/Linkify.java
+++ b/core/java/android/text/util/Linkify.java
@@ -67,6 +67,14 @@
  *  create <code>http://example.com</code> when the clickable URL link is
  *  created.
  *
+ *  <p class="note"><b>Note:</b> When using {@link #MAP_ADDRESSES} or {@link #ALL}
+ *  to match street addresses on API level {@link android.os.Build.VERSION_CODES#O_MR1}
+ *  and earlier, methods in this class may throw
+ *  {@link android.util.AndroidRuntimeException} or other exceptions if the
+ *  device's WebView implementation is currently being updated, because
+ *  {@link android.webkit.WebView#findAddress} is required to match street
+ *  addresses.
+ *
  * @see MatchFilter
  * @see TransformFilter
  */
@@ -95,10 +103,11 @@
 
     /**
      *  Bit field indicating that street addresses should be matched in methods that
-     *  take an options mask. Note that this uses the
-     *  {@link android.webkit.WebView#findAddress(String) findAddress()} method in
-     *  {@link android.webkit.WebView} for finding addresses, which has various
-     *  limitations and has been deprecated.
+     *  take an options mask. Note that this should be avoided, as it uses the
+     *  {@link android.webkit.WebView#findAddress(String)} method, which has various
+     *  limitations and has been deprecated: see the documentation for
+     *  {@link android.webkit.WebView#findAddress(String)} for more information.
+     *
      *  @deprecated use {@link android.view.textclassifier.TextClassifier#generateLinks(
      *  TextLinks.Request)} instead and avoid it even when targeting API levels where no alternative
      *  is available.
diff --git a/core/java/android/view/ViewRootImpl.java b/core/java/android/view/ViewRootImpl.java
index e835675..7a3609a 100644
--- a/core/java/android/view/ViewRootImpl.java
+++ b/core/java/android/view/ViewRootImpl.java
@@ -1522,6 +1522,7 @@
     }
 
     void setWindowStopped(boolean stopped) {
+        checkThread();
         if (mStopped != stopped) {
             mStopped = stopped;
             final ThreadedRenderer renderer = mAttachInfo.mThreadedRenderer;
@@ -1543,7 +1544,7 @@
             }
 
             if (mStopped) {
-                if (mSurfaceHolder != null) {
+                if (mSurfaceHolder != null && mSurface.isValid()) {
                     notifySurfaceDestroyed();
                 }
                 destroySurface();
@@ -2001,9 +2002,18 @@
                 mDisplay.getRealSize(size);
                 desiredWindowWidth = size.x;
                 desiredWindowHeight = size.y;
+            } else if (lp.width == ViewGroup.LayoutParams.WRAP_CONTENT
+                    || lp.height == ViewGroup.LayoutParams.WRAP_CONTENT) {
+                // For wrap content, we have to remeasure later on anyways. Use size consistent with
+                // below so we get best use of the measure cache.
+                desiredWindowWidth = dipToPx(config.screenWidthDp);
+                desiredWindowHeight = dipToPx(config.screenHeightDp);
             } else {
-                desiredWindowWidth = mWinFrame.width();
-                desiredWindowHeight = mWinFrame.height();
+                // After addToDisplay, the frame contains the frameHint from window manager, which
+                // for most windows is going to be the same size as the result of relayoutWindow.
+                // Using this here allows us to avoid remeasuring after relayoutWindow
+                desiredWindowWidth = frame.width();
+                desiredWindowHeight = frame.height();
             }
 
             // We used to use the following condition to choose 32 bits drawing caches:
@@ -2209,6 +2219,8 @@
 
         final boolean isViewVisible = viewVisibility == View.VISIBLE;
         final boolean windowRelayoutWasForced = mForceNextWindowRelayout;
+        boolean surfaceSizeChanged = false;
+
         if (mFirst || windowShouldResize || insetsChanged ||
                 viewVisibilityChanged || params != null || mForceNextWindowRelayout) {
             mForceNextWindowRelayout = false;
@@ -2287,7 +2299,7 @@
                 final boolean cutoutChanged = !mPendingDisplayCutout.equals(
                         mAttachInfo.mDisplayCutout);
                 final boolean outsetsChanged = !mPendingOutsets.equals(mAttachInfo.mOutsets);
-                final boolean surfaceSizeChanged = (relayoutResult
+                surfaceSizeChanged = (relayoutResult
                         & WindowManagerGlobal.RELAYOUT_RES_SURFACE_RESIZED) != 0;
                 surfaceChanged |= surfaceSizeChanged;
                 final boolean alwaysConsumeSystemBarsChanged =
@@ -2570,7 +2582,7 @@
             maybeHandleWindowMove(frame);
         }
 
-        if (surfaceChanged) {
+        if (surfaceSizeChanged) {
             updateBoundsSurface();
         }
 
diff --git a/core/java/android/view/WindowManagerGlobal.java b/core/java/android/view/WindowManagerGlobal.java
index 8a111cf..379acbe 100644
--- a/core/java/android/view/WindowManagerGlobal.java
+++ b/core/java/android/view/WindowManagerGlobal.java
@@ -636,13 +636,21 @@
     }
 
     public void setStoppedState(IBinder token, boolean stopped) {
+        ArrayList<ViewRootImpl> nonCurrentThreadRoots = null;
         synchronized (mLock) {
             int count = mViews.size();
             for (int i = count - 1; i >= 0; i--) {
                 if (token == null || mParams.get(i).token == token) {
                     ViewRootImpl root = mRoots.get(i);
                     // Client might remove the view by "stopped" event.
-                    root.setWindowStopped(stopped);
+                    if (root.mThread == Thread.currentThread()) {
+                        root.setWindowStopped(stopped);
+                    } else {
+                        if (nonCurrentThreadRoots == null) {
+                            nonCurrentThreadRoots = new ArrayList<>();
+                        }
+                        nonCurrentThreadRoots.add(root);
+                    }
                     // Recursively forward stopped state to View's attached
                     // to this Window rather than the root application token,
                     // e.g. PopupWindow's.
@@ -650,6 +658,16 @@
                 }
             }
         }
+
+        // Update the stopped state synchronously to ensure the surface won't be used after server
+        // side has destroyed it. This operation should be outside the lock to avoid any potential
+        // paths from setWindowStopped to WindowManagerGlobal which may cause deadlocks.
+        if (nonCurrentThreadRoots != null) {
+            for (int i = nonCurrentThreadRoots.size() - 1; i >= 0; i--) {
+                ViewRootImpl root = nonCurrentThreadRoots.get(i);
+                root.mHandler.runWithScissors(() -> root.setWindowStopped(stopped), 0);
+            }
+        }
     }
 
     public void reportNewConfiguration(Configuration config) {
diff --git a/core/java/android/view/accessibility/AccessibilityNodeIdManager.java b/core/java/android/view/accessibility/AccessibilityNodeIdManager.java
index 0f5e950..d78dadd 100644
--- a/core/java/android/view/accessibility/AccessibilityNodeIdManager.java
+++ b/core/java/android/view/accessibility/AccessibilityNodeIdManager.java
@@ -16,12 +16,11 @@
 
 package android.view.accessibility;
 
-import android.util.SparseArray;
 import android.view.View;
 
 /** @hide */
 public final class AccessibilityNodeIdManager {
-    private SparseArray<View> mIdsToViews = new SparseArray<>();
+    private WeakSparseArray<View> mIdsToViews = new WeakSparseArray<View>();
     private static AccessibilityNodeIdManager sIdManager;
 
     /**
diff --git a/core/java/android/view/accessibility/WeakSparseArray.java b/core/java/android/view/accessibility/WeakSparseArray.java
new file mode 100644
index 0000000..04a4cc7
--- /dev/null
+++ b/core/java/android/view/accessibility/WeakSparseArray.java
@@ -0,0 +1,63 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.view.accessibility;
+
+import android.util.SparseArray;
+
+import java.lang.ref.Reference;
+import java.lang.ref.ReferenceQueue;
+import java.lang.ref.WeakReference;
+
+
+final class WeakSparseArray<E> {
+
+    private final ReferenceQueue<E> mRefQueue = new ReferenceQueue<>();
+    private final SparseArray<WeakReferenceWithId<E>> mSparseArray = new SparseArray<>();
+
+    public void append(int key, E value) {
+        removeUnreachableValues();
+        mSparseArray.append(key, new WeakReferenceWithId(value, mRefQueue, key));
+    }
+
+    public void remove(int key) {
+        removeUnreachableValues();
+        mSparseArray.remove(key);
+    }
+
+    public E get(int key) {
+        removeUnreachableValues();
+        WeakReferenceWithId<E> ref = mSparseArray.get(key);
+        return ref != null ? ref.get() : null;
+    }
+
+    private void removeUnreachableValues() {
+        for (Reference ref = mRefQueue.poll(); ref != null; ref = mRefQueue.poll()) {
+            mSparseArray.remove(((WeakReferenceWithId) ref).mId);
+        }
+    }
+
+    private static class WeakReferenceWithId<E> extends WeakReference<E> {
+
+        final int mId;
+
+        WeakReferenceWithId(E referent, ReferenceQueue<? super E> q, int id) {
+            super(referent, q);
+            mId = id;
+        }
+    }
+}
+
diff --git a/core/java/android/view/textclassifier/ActionsSuggestionsHelper.java b/core/java/android/view/textclassifier/ActionsSuggestionsHelper.java
index 9c268f2..3ed48f6 100644
--- a/core/java/android/view/textclassifier/ActionsSuggestionsHelper.java
+++ b/core/java/android/view/textclassifier/ActionsSuggestionsHelper.java
@@ -19,7 +19,9 @@
 import android.annotation.Nullable;
 import android.app.Person;
 import android.app.RemoteAction;
+import android.content.ComponentName;
 import android.content.Context;
+import android.content.Intent;
 import android.text.TextUtils;
 import android.util.ArrayMap;
 import android.util.Pair;
@@ -200,10 +202,12 @@
         if (remoteAction == null) {
             return null;
         }
+        Intent actionIntent = ExtrasUtils.getActionIntent(conversationAction.getExtras());
+        ComponentName componentName = actionIntent.getComponent();
+        // Action without a component name will be considered as from the same app.
+        String packageName = componentName == null ? null : componentName.getPackageName();
         return new Pair<>(
-                conversationAction.getAction().getTitle().toString(),
-                ExtrasUtils.getActionIntent(
-                        conversationAction.getExtras()).getComponent().getPackageName());
+                conversationAction.getAction().getTitle().toString(), packageName);
     }
 
     private static final class PersonEncoder {
diff --git a/core/java/android/view/textclassifier/intent/LabeledIntent.java b/core/java/android/view/textclassifier/intent/LabeledIntent.java
index b4bc8d3..30fc20e 100644
--- a/core/java/android/view/textclassifier/intent/LabeledIntent.java
+++ b/core/java/android/view/textclassifier/intent/LabeledIntent.java
@@ -118,14 +118,16 @@
             return null;
         }
         Intent resolvedIntent = new Intent(intent);
-        resolvedIntent.setComponent(new ComponentName(packageName, className));
         resolvedIntent.putExtra(
                 TextClassifier.EXTRA_FROM_TEXT_CLASSIFIER,
                 getFromTextClassifierExtra(textLanguagesBundle));
-
         boolean shouldShowIcon = false;
         Icon icon = null;
         if (!"android".equals(packageName)) {
+            // We only set the component name when the package name is not resolved to "android"
+            // to workaround a bug that explicit intent with component name == ResolverActivity
+            // can't be launched on keyguard.
+            resolvedIntent.setComponent(new ComponentName(packageName, className));
             if (resolveInfo.activityInfo.getIconResource() != 0) {
                 icon = Icon.createWithResource(
                         packageName, resolveInfo.activityInfo.getIconResource());
diff --git a/core/java/android/webkit/WebView.java b/core/java/android/webkit/WebView.java
index 137b67c..14be73d 100644
--- a/core/java/android/webkit/WebView.java
+++ b/core/java/android/webkit/WebView.java
@@ -1603,9 +1603,9 @@
     }
 
     /**
-     * Gets the first substring consisting of the address of a physical
-     * location. Currently, only addresses in the United States are detected,
-     * and consist of:
+     * Gets the first substring which appears to be the address of a physical
+     * location. Only addresses in the United States can be detected, which
+     * must consist of:
      * <ul>
      *   <li>a house number</li>
      *   <li>a street name</li>
@@ -1621,9 +1621,17 @@
      * or abbreviated using USPS standards. The house number may not exceed
      * five digits.
      *
+     * <p class="note"><b>Note:</b> This function is deprecated and should be
+     * avoided on all API levels, as it cannot detect addresses outside of the
+     * United States and has a high rate of false positives. On API level
+     * {@link android.os.Build.VERSION_CODES#O_MR1} and earlier, it also causes
+     * the entire WebView implementation to be loaded and initialized, which
+     * can throw {@link android.util.AndroidRuntimeException} or other exceptions
+     * if the WebView implementation is currently being updated.
+     *
      * @param addr the string to search for addresses
      * @return the address, or if no address is found, {@code null}
-     * @deprecated this method is superseded by {@link TextClassifier#generateLinks(
+     * @deprecated This method is superseded by {@link TextClassifier#generateLinks(
      * android.view.textclassifier.TextLinks.Request)}. Avoid using this method even when targeting
      * API levels where no alternative is available.
      */
diff --git a/core/java/android/widget/AbsListView.java b/core/java/android/widget/AbsListView.java
index 4cb552d..85e9e49 100644
--- a/core/java/android/widget/AbsListView.java
+++ b/core/java/android/widget/AbsListView.java
@@ -2553,34 +2553,42 @@
         final boolean isItemEnabled;
         final ViewGroup.LayoutParams lp = view.getLayoutParams();
         if (lp instanceof AbsListView.LayoutParams) {
-            isItemEnabled = ((AbsListView.LayoutParams) lp).isEnabled;
+            isItemEnabled = ((AbsListView.LayoutParams) lp).isEnabled && isEnabled();
         } else {
             isItemEnabled = false;
         }
 
-        if (!isEnabled() || !isItemEnabled) {
-            info.setEnabled(false);
-            return;
-        }
+        info.setEnabled(isItemEnabled);
 
         if (position == getSelectedItemPosition()) {
             info.setSelected(true);
-            info.addAction(AccessibilityAction.ACTION_CLEAR_SELECTION);
-        } else {
-            info.addAction(AccessibilityAction.ACTION_SELECT);
+            addAccessibilityActionIfEnabled(info, isItemEnabled,
+                    AccessibilityAction.ACTION_CLEAR_SELECTION);
+        } else  {
+            addAccessibilityActionIfEnabled(info, isItemEnabled,
+                    AccessibilityAction.ACTION_SELECT);
         }
 
         if (isItemClickable(view)) {
-            info.addAction(AccessibilityAction.ACTION_CLICK);
+            addAccessibilityActionIfEnabled(info, isItemEnabled, AccessibilityAction.ACTION_CLICK);
             info.setClickable(true);
         }
 
         if (isLongClickable()) {
-            info.addAction(AccessibilityAction.ACTION_LONG_CLICK);
+            addAccessibilityActionIfEnabled(info, isItemEnabled,
+                    AccessibilityAction.ACTION_LONG_CLICK);
             info.setLongClickable(true);
         }
     }
 
+
+    private void addAccessibilityActionIfEnabled(AccessibilityNodeInfo info, boolean enabled,
+            AccessibilityAction action) {
+        if (enabled) {
+            info.addAction(action);
+        }
+    }
+
     private boolean isItemClickable(View view) {
         return !view.hasExplicitFocusable();
     }
diff --git a/core/java/android/widget/AbsSeekBar.java b/core/java/android/widget/AbsSeekBar.java
index 18c6abb..50bb688 100644
--- a/core/java/android/widget/AbsSeekBar.java
+++ b/core/java/android/widget/AbsSeekBar.java
@@ -38,6 +38,11 @@
 import android.view.inspector.InspectableProperty;
 
 import com.android.internal.R;
+import com.android.internal.util.Preconditions;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
 
 
 /**
@@ -91,6 +96,10 @@
     @UnsupportedAppUsage
     private boolean mIsDragging;
 
+    private List<Rect> mUserGestureExclusionRects = Collections.emptyList();
+    private final List<Rect> mGestureExclusionRects = new ArrayList<>();
+    private final Rect mThumbRect = new Rect();
+
     public AbsSeekBar(Context context) {
         super(context);
     }
@@ -735,6 +744,27 @@
 
         // Canvas will be translated, so 0,0 is where we start drawing
         thumb.setBounds(left, top, right, bottom);
+        updateGestureExclusionRects();
+    }
+
+    @Override
+    public void setSystemGestureExclusionRects(@NonNull List<Rect> rects) {
+        Preconditions.checkNotNull(rects, "rects must not be null");
+        mUserGestureExclusionRects = rects;
+        updateGestureExclusionRects();
+    }
+
+    private void updateGestureExclusionRects() {
+        final Drawable thumb = mThumb;
+        if (thumb == null) {
+            super.setSystemGestureExclusionRects(mUserGestureExclusionRects);
+            return;
+        }
+        mGestureExclusionRects.clear();
+        thumb.copyBounds(mThumbRect);
+        mGestureExclusionRects.add(mThumbRect);
+        mGestureExclusionRects.addAll(mUserGestureExclusionRects);
+        super.setSystemGestureExclusionRects(mGestureExclusionRects);
     }
 
     /**
diff --git a/core/java/android/widget/Editor.java b/core/java/android/widget/Editor.java
index c9ef038..cac75cfd 100644
--- a/core/java/android/widget/Editor.java
+++ b/core/java/android/widget/Editor.java
@@ -134,6 +134,7 @@
 import java.text.BreakIterator;
 import java.util.ArrayList;
 import java.util.Arrays;
+import java.util.Collections;
 import java.util.Comparator;
 import java.util.HashMap;
 import java.util.List;
@@ -5097,6 +5098,12 @@
         void onHandleMoved() {}
 
         public void onDetached() {}
+
+        @Override
+        protected void onSizeChanged(int w, int h, int oldw, int oldh) {
+            super.onSizeChanged(w, h, oldw, oldh);
+            setSystemGestureExclusionRects(Collections.singletonList(new Rect(0, 0, w, h)));
+        }
     }
 
     private class InsertionHandleView extends HandleView {
diff --git a/core/java/android/widget/RemoteViewsAdapter.java b/core/java/android/widget/RemoteViewsAdapter.java
index 365638f..efc5eb3 100644
--- a/core/java/android/widget/RemoteViewsAdapter.java
+++ b/core/java/android/widget/RemoteViewsAdapter.java
@@ -28,7 +28,9 @@
 import android.content.Context;
 import android.content.Intent;
 import android.content.ServiceConnection;
+import android.content.pm.ActivityInfo;
 import android.content.pm.ApplicationInfo;
+import android.content.res.Configuration;
 import android.os.Handler;
 import android.os.HandlerThread;
 import android.os.IBinder;
@@ -555,6 +557,12 @@
     }
 
     /**
+     * Config diff flags for which the cache should be reset
+     */
+    private static final int CACHE_RESET_CONFIG_FLAGS = ActivityInfo.CONFIG_FONT_SCALE
+            | ActivityInfo.CONFIG_UI_MODE | ActivityInfo.CONFIG_DENSITY
+            | ActivityInfo.CONFIG_ASSETS_PATHS;
+    /**
      *
      */
     private static class FixedSizeRemoteViewsCache {
@@ -587,7 +595,6 @@
         // farthest items from when we hit the memory limit
         private int mLastRequestedIndex;
 
-
         // The lower and upper bounds of the preloaded range
         private int mPreloadLowerBound;
         private int mPreloadUpperBound;
@@ -602,12 +609,17 @@
         private static final float sMaxCountSlackPercent = 0.75f;
         private static final int sMaxMemoryLimitInBytes = 2 * 1024 * 1024;
 
-        public FixedSizeRemoteViewsCache(int maxCacheSize) {
+        // Configuration for which the cache was created
+        private final Configuration mConfiguration;
+
+        FixedSizeRemoteViewsCache(int maxCacheSize, Configuration configuration) {
             mMaxCount = maxCacheSize;
             mMaxCountSlack = Math.round(sMaxCountSlackPercent * (mMaxCount / 2));
             mPreloadLowerBound = 0;
             mPreloadUpperBound = -1;
             mLastRequestedIndex = -1;
+
+            mConfiguration = new Configuration(configuration);
         }
 
         public void insert(int position, RemoteViews v, long itemId, int[] visibleWindow) {
@@ -852,7 +864,12 @@
                 mAppWidgetId);
 
         synchronized(sCachedRemoteViewsCaches) {
-            if (sCachedRemoteViewsCaches.containsKey(key)) {
+            FixedSizeRemoteViewsCache cache = sCachedRemoteViewsCaches.get(key);
+            Configuration config = context.getResources().getConfiguration();
+            if (cache == null
+                    || (cache.mConfiguration.diff(config) & CACHE_RESET_CONFIG_FLAGS) != 0) {
+                mCache = new FixedSizeRemoteViewsCache(DEFAULT_CACHE_SIZE, config);
+            } else {
                 mCache = sCachedRemoteViewsCaches.get(key);
                 synchronized (mCache.mMetaData) {
                     if (mCache.mMetaData.count > 0) {
@@ -861,8 +878,6 @@
                         mDataReady = true;
                     }
                 }
-            } else {
-                mCache = new FixedSizeRemoteViewsCache(DEFAULT_CACHE_SIZE);
             }
             if (!mDataReady) {
                 requestBindService();
diff --git a/core/java/android/widget/TextView.java b/core/java/android/widget/TextView.java
index a9e183a..62598fc 100644
--- a/core/java/android/widget/TextView.java
+++ b/core/java/android/widget/TextView.java
@@ -1011,6 +1011,8 @@
          */
         TypedArray a = theme.obtainStyledAttributes(attrs,
                 com.android.internal.R.styleable.TextViewAppearance, defStyleAttr, defStyleRes);
+        saveAttributeDataForStyleable(context, com.android.internal.R.styleable.TextViewAppearance,
+                attrs, a, defStyleAttr, defStyleRes);
         TypedArray appearance = null;
         int ap = a.getResourceId(
                 com.android.internal.R.styleable.TextViewAppearance_textAppearance, -1);
@@ -1018,6 +1020,8 @@
         if (ap != -1) {
             appearance = theme.obtainStyledAttributes(
                     ap, com.android.internal.R.styleable.TextAppearance);
+            saveAttributeDataForStyleable(context, com.android.internal.R.styleable.TextAppearance,
+                    null, appearance, 0, ap);
         }
         if (appearance != null) {
             readTextAppearance(context, appearance, attributes, false /* styleArray */);
@@ -4960,6 +4964,10 @@
      * android.text.util.Linkify#ALL Linkify.ALL} and peers for
      * possible values.
      *
+     * <p class="note"><b>Note:</b>
+     * {@link android.text.util.Linkify#MAP_ADDRESSES Linkify.MAP_ADDRESSES}
+     * is deprecated and should be avoided; see its documentation.
+     *
      * @attr ref android.R.styleable#TextView_autoLink
      */
     @android.view.RemotableViewMethod
diff --git a/core/java/com/android/internal/app/AccessibilityButtonChooserActivity.java b/core/java/com/android/internal/app/AccessibilityButtonChooserActivity.java
index b9ed963..7af45fc 100644
--- a/core/java/com/android/internal/app/AccessibilityButtonChooserActivity.java
+++ b/core/java/com/android/internal/app/AccessibilityButtonChooserActivity.java
@@ -15,6 +15,8 @@
  */
 package com.android.internal.app;
 
+import static android.view.WindowManagerPolicyConstants.NAV_BAR_MODE_GESTURAL;
+
 import android.accessibilityservice.AccessibilityServiceInfo;
 import android.annotation.NonNull;
 import android.annotation.Nullable;
@@ -64,8 +66,21 @@
 
         String component = Settings.Secure.getString(getContentResolver(),
                 Settings.Secure.ACCESSIBILITY_BUTTON_TARGET_COMPONENT);
+
+        if (isGestureNavigateEnabled()) {
+            TextView promptPrologue = findViewById(R.id.accessibility_button_prompt_prologue);
+            promptPrologue.setText(isTouchExploreOn()
+                    ? R.string.accessibility_gesture_3finger_prompt_text
+                    : R.string.accessibility_gesture_prompt_text);
+        }
+
         if (TextUtils.isEmpty(component)) {
             TextView prompt = findViewById(R.id.accessibility_button_prompt);
+            if (isGestureNavigateEnabled()) {
+                prompt.setText(isTouchExploreOn()
+                        ? R.string.accessibility_gesture_3finger_instructional_text
+                        : R.string.accessibility_gesture_instructional_text);
+            }
             prompt.setVisibility(View.VISIBLE);
         }
 
@@ -91,6 +106,16 @@
         });
     }
 
+    private boolean isGestureNavigateEnabled() {
+        return NAV_BAR_MODE_GESTURAL == getResources().getInteger(
+                com.android.internal.R.integer.config_navBarInteractionMode);
+    }
+
+    private boolean isTouchExploreOn() {
+        return ((AccessibilityManager) getSystemService(Context.ACCESSIBILITY_SERVICE))
+                .isTouchExplorationEnabled();
+    }
+
     private static List<AccessibilityButtonTarget> getServiceAccessibilityButtonTargets(
             @NonNull Context context) {
         AccessibilityManager ams = (AccessibilityManager) context.getSystemService(
@@ -177,4 +202,4 @@
             return mDrawable;
         }
     }
-}
\ No newline at end of file
+}
diff --git a/core/java/com/android/internal/app/ChooserActivity.java b/core/java/com/android/internal/app/ChooserActivity.java
index ee99837..5294714 100644
--- a/core/java/com/android/internal/app/ChooserActivity.java
+++ b/core/java/com/android/internal/app/ChooserActivity.java
@@ -110,6 +110,7 @@
 import com.android.internal.R;
 import com.android.internal.annotations.VisibleForTesting;
 import com.android.internal.config.sysui.SystemUiDeviceConfigFlags;
+import com.android.internal.content.PackageMonitor;
 import com.android.internal.logging.MetricsLogger;
 import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
 import com.android.internal.util.ImageUtils;
@@ -125,8 +126,10 @@
 import java.util.Collections;
 import java.util.Comparator;
 import java.util.HashMap;
+import java.util.HashSet;
 import java.util.List;
 import java.util.Map;
+import java.util.Set;
 
 /**
  * The Chooser Activity handles intent resolution specifically for sharing intents -
@@ -185,7 +188,6 @@
     private static final int SHARE_TARGET_QUERY_PACKAGE_LIMIT = 20;
 
     private static final int QUERY_TARGET_SERVICE_LIMIT = 5;
-    private static final int WATCHDOG_TIMEOUT_MILLIS = 5000;
 
     private static final int DEFAULT_SALT_EXPIRATION_DAYS = 7;
     private int mMaxHashSaltDays = DeviceConfig.getInt(DeviceConfig.NAMESPACE_SYSTEMUI,
@@ -211,6 +213,8 @@
     private ChooserRowAdapter mChooserRowAdapter;
     private int mChooserRowServiceSpacing;
 
+    private int mCurrAvailableWidth = 0;
+
     /** {@link ChooserActivity#getBaseScore} */
     private static final float CALLER_TARGET_SCORE_BOOST = 900.f;
     /** {@link ChooserActivity#getBaseScore} */
@@ -220,12 +224,7 @@
     private static final int MAX_RANKED_TARGETS = 4;
 
     private final List<ChooserTargetServiceConnection> mServiceConnections = new ArrayList<>();
-
-    private static final int CHOOSER_TARGET_SERVICE_RESULT = 1;
-    private static final int CHOOSER_TARGET_SERVICE_WATCHDOG_TIMEOUT = 2;
-    private static final int SHORTCUT_MANAGER_SHARE_TARGET_RESULT = 3;
-    private static final int SHORTCUT_MANAGER_SHARE_TARGET_RESULT_COMPLETED = 4;
-    private static final int LIST_VIEW_UPDATE_MESSAGE = 5;
+    private final Set<ComponentName> mServicesRequested = new HashSet<>();
 
     private static final int MAX_LOG_RANK_POSITION = 12;
 
@@ -255,11 +254,13 @@
     private ContentPreviewCoordinator mPreviewCoord;
 
     private class ContentPreviewCoordinator {
-        private static final int IMAGE_LOAD_TIMEOUT_MILLIS = 300;
         private static final int IMAGE_FADE_IN_MILLIS = 150;
         private static final int IMAGE_LOAD_TIMEOUT = 1;
         private static final int IMAGE_LOAD_INTO_VIEW = 2;
 
+        private final int mImageLoadTimeoutMillis =
+                getResources().getInteger(R.integer.config_shortAnimTime);
+
         private final View mParentView;
         private boolean mHideParentOnFail;
         private boolean mAtLeastOneLoaded = false;
@@ -328,7 +329,7 @@
 
         private void loadUriIntoView(final int imageResourceId, final Uri uri,
                 final int extraImages) {
-            mHandler.sendEmptyMessageDelayed(IMAGE_LOAD_TIMEOUT, IMAGE_LOAD_TIMEOUT_MILLIS);
+            mHandler.sendEmptyMessageDelayed(IMAGE_LOAD_TIMEOUT, mImageLoadTimeoutMillis);
 
             AsyncTask.THREAD_POOL_EXECUTOR.execute(() -> {
                 final Bitmap bmp = loadThumbnail(uri, new Size(200, 200));
@@ -347,7 +348,7 @@
         private void maybeHideContentPreview() {
             if (!mAtLeastOneLoaded && mHideParentOnFail) {
                 Log.i(TAG, "Hiding image preview area. Timed out waiting for preview to load"
-                        + " within " + IMAGE_LOAD_TIMEOUT_MILLIS + "ms.");
+                        + " within " + mImageLoadTimeoutMillis + "ms.");
                 collapseParentView();
                 if (mChooserRowAdapter != null) {
                     mChooserRowAdapter.hideContentPreview();
@@ -369,7 +370,59 @@
         }
     }
 
-    private final Handler mChooserHandler = new Handler() {
+    private final ChooserHandler mChooserHandler = new ChooserHandler();
+
+    private class ChooserHandler extends Handler {
+        private static final int CHOOSER_TARGET_SERVICE_RESULT = 1;
+        private static final int CHOOSER_TARGET_SERVICE_WATCHDOG_MIN_TIMEOUT = 2;
+        private static final int CHOOSER_TARGET_SERVICE_WATCHDOG_MAX_TIMEOUT = 3;
+        private static final int SHORTCUT_MANAGER_SHARE_TARGET_RESULT = 4;
+        private static final int SHORTCUT_MANAGER_SHARE_TARGET_RESULT_COMPLETED = 5;
+        private static final int LIST_VIEW_UPDATE_MESSAGE = 6;
+
+        private static final int WATCHDOG_TIMEOUT_MAX_MILLIS = 10000;
+        private static final int WATCHDOG_TIMEOUT_MIN_MILLIS = 3000;
+
+        private boolean mMinTimeoutPassed = false;
+
+        private void removeAllMessages() {
+            removeMessages(LIST_VIEW_UPDATE_MESSAGE);
+            removeMessages(CHOOSER_TARGET_SERVICE_WATCHDOG_MIN_TIMEOUT);
+            removeMessages(CHOOSER_TARGET_SERVICE_WATCHDOG_MAX_TIMEOUT);
+            removeMessages(CHOOSER_TARGET_SERVICE_RESULT);
+            removeMessages(SHORTCUT_MANAGER_SHARE_TARGET_RESULT);
+            removeMessages(SHORTCUT_MANAGER_SHARE_TARGET_RESULT_COMPLETED);
+        }
+
+        private void restartServiceRequestTimer() {
+            mMinTimeoutPassed = false;
+            removeMessages(CHOOSER_TARGET_SERVICE_WATCHDOG_MIN_TIMEOUT);
+            removeMessages(CHOOSER_TARGET_SERVICE_WATCHDOG_MAX_TIMEOUT);
+
+            if (DEBUG) {
+                Log.d(TAG, "queryTargets setting watchdog timer for "
+                        + WATCHDOG_TIMEOUT_MIN_MILLIS + "-"
+                        + WATCHDOG_TIMEOUT_MAX_MILLIS + "ms");
+            }
+
+            sendEmptyMessageDelayed(CHOOSER_TARGET_SERVICE_WATCHDOG_MIN_TIMEOUT,
+                    WATCHDOG_TIMEOUT_MIN_MILLIS);
+            sendEmptyMessageDelayed(CHOOSER_TARGET_SERVICE_WATCHDOG_MAX_TIMEOUT,
+                    WATCHDOG_TIMEOUT_MAX_MILLIS);
+        }
+
+        private void maybeStopServiceRequestTimer() {
+            // Set a minimum timeout threshold, to ensure both apis, sharing shortcuts
+            // and older-style direct share services, have had time to load, otherwise
+            // just checking mServiceConnections could force us to end prematurely
+            if (mMinTimeoutPassed && mServiceConnections.isEmpty()) {
+                logDirectShareTargetReceived(
+                        MetricsEvent.ACTION_DIRECT_SHARE_TARGETS_LOADED_CHOOSER_SERVICE);
+                sendVoiceChoicesIfNeeded();
+                mChooserListAdapter.completeServiceTargetLoading();
+            }
+        }
+
         @Override
         public void handleMessage(Message msg) {
             if (mChooserListAdapter == null || isDestroyed()) {
@@ -393,23 +446,17 @@
                     unbindService(sri.connection);
                     sri.connection.destroy();
                     mServiceConnections.remove(sri.connection);
-                    if (mServiceConnections.isEmpty()) {
-                        logDirectShareTargetReceived(
-                                MetricsEvent.ACTION_DIRECT_SHARE_TARGETS_LOADED_CHOOSER_SERVICE);
-                        sendVoiceChoicesIfNeeded();
-                    }
+                    maybeStopServiceRequestTimer();
                     break;
 
-                case CHOOSER_TARGET_SERVICE_WATCHDOG_TIMEOUT:
-                    if (DEBUG) {
-                        Log.d(TAG, "CHOOSER_TARGET_SERVICE_WATCHDOG_TIMEOUT; unbinding services");
-                    }
+                case CHOOSER_TARGET_SERVICE_WATCHDOG_MIN_TIMEOUT:
+                    mMinTimeoutPassed = true;
+                    maybeStopServiceRequestTimer();
+                    break;
 
+                case CHOOSER_TARGET_SERVICE_WATCHDOG_MAX_TIMEOUT:
                     unbindRemainingServices();
-                    logDirectShareTargetReceived(
-                            MetricsEvent.ACTION_DIRECT_SHARE_TARGETS_LOADED_CHOOSER_SERVICE);
-                    sendVoiceChoicesIfNeeded();
-                    mChooserListAdapter.completeServiceTargetLoading();
+                    maybeStopServiceRequestTimer();
                     break;
 
                 case LIST_VIEW_UPDATE_MESSAGE:
@@ -669,6 +716,17 @@
                 .getUserInfo(UserHandle.myUserId()).isManagedProfile();
     }
 
+    @Override
+    protected PackageMonitor createPackageMonitor() {
+        return new PackageMonitor() {
+            @Override
+            public void onSomePackagesChanged() {
+                mAdapter.handlePackagesChanged();
+                bindProfileView();
+            }
+        };
+    }
+
     private void onCopyButtonClicked(View v) {
         Intent targetIntent = getTargetIntent();
         if (targetIntent == null) {
@@ -716,18 +774,31 @@
     public void onConfigurationChanged(Configuration newConfig) {
         super.onConfigurationChanged(newConfig);
 
+        adjustPreviewWidth(newConfig.orientation, null);
+    }
+
+    private boolean shouldDisplayLandscape(int orientation) {
+        // Sharesheet fixes the # of items per row and therefore can not correctly lay out
+        // when in the restricted size of multi-window mode. In the future, would be nice
+        // to use minimum dp size requirements instead
+        return orientation == Configuration.ORIENTATION_LANDSCAPE && !isInMultiWindowMode();
+    }
+
+    private void adjustPreviewWidth(int orientation, View parent) {
         int width = -1;
-        if (newConfig.orientation == Configuration.ORIENTATION_LANDSCAPE) {
+        if (shouldDisplayLandscape(orientation)) {
             width = getResources().getDimensionPixelSize(R.dimen.chooser_preview_width);
         }
 
-        updateLayoutWidth(R.id.content_preview_text_layout, width);
-        updateLayoutWidth(R.id.content_preview_title_layout, width);
-        updateLayoutWidth(R.id.content_preview_file_layout, width);
+        parent = parent == null ? getWindow().getDecorView() : parent;
+
+        updateLayoutWidth(R.id.content_preview_text_layout, width, parent);
+        updateLayoutWidth(R.id.content_preview_title_layout, width, parent);
+        updateLayoutWidth(R.id.content_preview_file_layout, width, parent);
     }
 
-    private void updateLayoutWidth(int layoutResourceId, int width) {
-        View view = findViewById(layoutResourceId);
+    private void updateLayoutWidth(int layoutResourceId, int width, View parent) {
+        View view = parent.findViewById(layoutResourceId);
         if (view != null && view.getLayoutParams() != null) {
             LayoutParams params = view.getLayoutParams();
             params.width = width;
@@ -740,18 +811,27 @@
             ViewGroup parent) {
         if (convertView != null) return convertView;
 
+        ViewGroup layout = null;
+
         switch (previewType) {
             case CONTENT_PREVIEW_TEXT:
-                return displayTextContentPreview(targetIntent, layoutInflater, parent);
+                layout = displayTextContentPreview(targetIntent, layoutInflater, parent);
+                break;
             case CONTENT_PREVIEW_IMAGE:
-                return displayImageContentPreview(targetIntent, layoutInflater, parent);
+                layout = displayImageContentPreview(targetIntent, layoutInflater, parent);
+                break;
             case CONTENT_PREVIEW_FILE:
-                return displayFileContentPreview(targetIntent, layoutInflater, parent);
+                layout = displayFileContentPreview(targetIntent, layoutInflater, parent);
+                break;
             default:
                 Log.e(TAG, "Unexpected content preview type: " + previewType);
         }
 
-        return null;
+        if (layout != null) {
+            adjustPreviewWidth(getResources().getConfiguration().orientation, layout);
+        }
+
+        return layout;
     }
 
     private ViewGroup displayTextContentPreview(Intent targetIntent, LayoutInflater layoutInflater,
@@ -1043,11 +1123,7 @@
             mRefinementResultReceiver = null;
         }
         unbindRemainingServices();
-        mChooserHandler.removeMessages(LIST_VIEW_UPDATE_MESSAGE);
-        mChooserHandler.removeMessages(CHOOSER_TARGET_SERVICE_WATCHDOG_TIMEOUT);
-        mChooserHandler.removeMessages(CHOOSER_TARGET_SERVICE_RESULT);
-        mChooserHandler.removeMessages(SHORTCUT_MANAGER_SHARE_TARGET_RESULT);
-        mChooserHandler.removeMessages(SHORTCUT_MANAGER_SHARE_TARGET_RESULT_COMPLETED);
+        mChooserHandler.removeAllMessages();
 
         if (mPreviewCoord != null) mPreviewCoord.cancelLoads();
 
@@ -1285,6 +1361,7 @@
         final PackageManager pm = getPackageManager();
         ShortcutManager sm = (ShortcutManager) getSystemService(ShortcutManager.class);
         int targetsToQuery = 0;
+
         for (int i = 0, N = adapter.getDisplayResolveInfoCount(); i < N; i++) {
             final DisplayResolveInfo dri = adapter.getDisplayResolveInfo(i);
             if (adapter.getScore(dri) == 0) {
@@ -1304,6 +1381,12 @@
             if (serviceName != null) {
                 final ComponentName serviceComponent = new ComponentName(
                         ai.packageName, serviceName);
+
+                if (mServicesRequested.contains(serviceComponent)) {
+                    continue;
+                }
+                mServicesRequested.add(serviceComponent);
+
                 final Intent serviceIntent = new Intent(ChooserTargetService.SERVICE_INTERFACE)
                         .setComponent(serviceComponent);
 
@@ -1354,16 +1437,7 @@
             }
         }
 
-        if (DEBUG) {
-            Log.d(TAG, "queryTargets setting watchdog timer for "
-                    + WATCHDOG_TIMEOUT_MILLIS + "ms");
-        }
-        mChooserHandler.sendEmptyMessageDelayed(CHOOSER_TARGET_SERVICE_WATCHDOG_TIMEOUT,
-                WATCHDOG_TIMEOUT_MILLIS);
-
-        if (mServiceConnections.isEmpty()) {
-            sendVoiceChoicesIfNeeded();
-        }
+        mChooserHandler.restartServiceRequestTimer();
     }
 
     private IntentFilter getTargetIntentFilter() {
@@ -1471,7 +1545,7 @@
                 continue;
             }
             final Message msg = Message.obtain();
-            msg.what = SHORTCUT_MANAGER_SHARE_TARGET_RESULT;
+            msg.what = ChooserHandler.SHORTCUT_MANAGER_SHARE_TARGET_RESULT;
             msg.obj = new ServiceResultInfo(driList.get(i), chooserTargets, null);
             mChooserHandler.sendMessage(msg);
             resultMessageSent = true;
@@ -1484,7 +1558,7 @@
 
     private void sendShortcutManagerShareTargetResultCompleted() {
         final Message msg = Message.obtain();
-        msg.what = SHORTCUT_MANAGER_SHARE_TARGET_RESULT_COMPLETED;
+        msg.what = ChooserHandler.SHORTCUT_MANAGER_SHARE_TARGET_RESULT_COMPLETED;
         mChooserHandler.sendMessage(msg);
     }
 
@@ -1552,6 +1626,7 @@
             unbindService(conn);
             conn.destroy();
         }
+        mServicesRequested.clear();
         mServiceConnections.clear();
     }
 
@@ -2176,13 +2251,13 @@
             return;
         }
 
-        int availableWidth = right - left - v.getPaddingLeft() - v.getPaddingRight();
+        final int availableWidth = right - left - v.getPaddingLeft() - v.getPaddingRight();
         if (mChooserRowAdapter.consumeLayoutRequest()
                 || mChooserRowAdapter.calculateChooserTargetWidth(availableWidth)
-                || mAdapterView.getAdapter() == null) {
-            if (mAdapterView.getAdapter() == null) {
-                mAdapterView.setAdapter(mChooserRowAdapter);
-            }
+                || mAdapterView.getAdapter() == null
+                || availableWidth != mCurrAvailableWidth) {
+            mCurrAvailableWidth = availableWidth;
+            mAdapterView.setAdapter(mChooserRowAdapter);
 
             getMainThreadHandler().post(() -> {
                 if (mResolverDrawerLayout == null || mChooserRowAdapter == null) {
@@ -2225,9 +2300,9 @@
                     }
                 }
 
-                boolean isPortrait = getResources().getConfiguration().orientation
-                                         == Configuration.ORIENTATION_PORTRAIT;
-                if (directShareHeight != 0 && isSendAction(getTargetIntent()) && isPortrait) {
+                boolean isExpandable = getResources().getConfiguration().orientation
+                        == Configuration.ORIENTATION_PORTRAIT && !isInMultiWindowMode();
+                if (directShareHeight != 0 && isSendAction(getTargetIntent()) && isExpandable) {
                     // make sure to leave room for direct share 4->8 expansion
                     int requiredExpansionHeight =
                             (int) (directShareHeight / DIRECT_SHARE_EXPANSION_RATE);
@@ -2262,7 +2337,6 @@
         private ChooserTargetInfo mPlaceHolderTargetInfo = new PlaceHolderTargetInfo();
         private final List<ChooserTargetInfo> mServiceTargets = new ArrayList<>();
         private final List<TargetInfo> mCallerTargets = new ArrayList<>();
-        private boolean mTargetsNeedPruning = false;
 
         private final BaseChooserTargetComparator mBaseTargetComparator
                 = new BaseChooserTargetComparator();
@@ -2331,9 +2405,21 @@
         }
 
         @Override
+        public void handlePackagesChanged() {
+            if (DEBUG) {
+                Log.d(TAG, "clearing queryTargets on package change");
+            }
+            createPlaceHolders();
+            mServicesRequested.clear();
+            notifyDataSetChanged();
+
+            super.handlePackagesChanged();
+        }
+
+        @Override
         public void notifyDataSetChanged() {
             if (!mListViewDataChanged) {
-                mChooserHandler.sendEmptyMessageDelayed(LIST_VIEW_UPDATE_MESSAGE,
+                mChooserHandler.sendEmptyMessageDelayed(ChooserHandler.LIST_VIEW_UPDATE_MESSAGE,
                         LIST_VIEW_UPDATE_INTERVAL_IN_MILLIS);
                 mListViewDataChanged = true;
             }
@@ -2348,6 +2434,7 @@
 
 
         private void createPlaceHolders() {
+            mNumShortcutResults = 0;
             mServiceTargets.clear();
             for (int i = 0; i < MAX_SERVICE_TARGETS; i++) {
                 mServiceTargets.add(mPlaceHolderTargetInfo);
@@ -2390,16 +2477,6 @@
                 return;
             }
 
-            if (mServiceTargets != null) {
-                if (getDisplayResolveInfoCount() == 0) {
-                    // b/109676071: When packages change, onListRebuilt() is called before
-                    // ResolverActivity.mDisplayList is re-populated; pruning now would cause the
-                    // list to disappear briefly, so instead we detect this case (the
-                    // set of targets suddenly dropping to zero) and remember to prune later.
-                    mTargetsNeedPruning = true;
-                }
-            }
-
             if (USE_SHORTCUT_MANAGER_FOR_DIRECT_TARGETS
                         || USE_PREDICTION_MANAGER_FOR_DIRECT_TARGETS) {
                 if (DEBUG) {
@@ -2456,7 +2533,7 @@
         }
 
         public int getServiceTargetCount() {
-            if (isSendAction(getTargetIntent())) {
+            if (isSendAction(getTargetIntent()) && !ActivityManager.isLowRamDeviceStatic()) {
                 return Math.min(mServiceTargets.size(), MAX_SERVICE_TARGETS);
             }
 
@@ -2568,19 +2645,6 @@
                 return;
             }
 
-            if (mTargetsNeedPruning) {
-                // First proper update since we got an onListRebuilt() with (transient) 0 items.
-                // Clear out the target list and rebuild.
-                createPlaceHolders();
-                mTargetsNeedPruning = false;
-
-                // Add back any app-supplied direct share targets that may have been
-                // wiped by this clear
-                if (mCallerChooserTargets != null) {
-                    addServiceResults(null, Lists.newArrayList(mCallerChooserTargets), false);
-                }
-            }
-
             final float baseScore = getBaseScore(origTarget, isShortcutResult);
             Collections.sort(targets, mBaseTargetComparator);
 
@@ -2791,8 +2855,7 @@
 
         private int getMaxTargetsPerRow() {
             int maxTargets = MAX_TARGETS_PER_ROW_PORTRAIT;
-            if (getResources().getConfiguration().orientation
-                    == Configuration.ORIENTATION_LANDSCAPE) {
+            if (shouldDisplayLandscape(getResources().getConfiguration().orientation)) {
                 maxTargets = MAX_TARGETS_PER_ROW_LANDSCAPE;
             }
 
@@ -3178,7 +3241,8 @@
             int orientation = getResources().getConfiguration().orientation;
             boolean canExpandDirectShare =
                     mChooserListAdapter.getNumShortcutResults() > getMaxTargetsPerRow()
-                    && orientation == Configuration.ORIENTATION_PORTRAIT;
+                    && orientation == Configuration.ORIENTATION_PORTRAIT
+                    && !isInMultiWindowMode();
 
             if (mDirectShareViewHolder != null && canExpandDirectShare) {
                 mDirectShareViewHolder.handleScroll(mAdapterView, y, oldy, getMaxTargetsPerRow());
@@ -3425,7 +3489,7 @@
                     mChooserActivity.filterServiceTargets(
                             mOriginalTarget.getResolveInfo().activityInfo.packageName, targets);
                     final Message msg = Message.obtain();
-                    msg.what = CHOOSER_TARGET_SERVICE_RESULT;
+                    msg.what = ChooserHandler.CHOOSER_TARGET_SERVICE_RESULT;
                     msg.obj = new ServiceResultInfo(mOriginalTarget, targets,
                             ChooserTargetServiceConnection.this);
                     mChooserActivity.mChooserHandler.sendMessage(msg);
diff --git a/core/java/com/android/internal/app/ResolverActivity.java b/core/java/com/android/internal/app/ResolverActivity.java
index 0a01beb..7cc8128 100644
--- a/core/java/com/android/internal/app/ResolverActivity.java
+++ b/core/java/com/android/internal/app/ResolverActivity.java
@@ -146,19 +146,7 @@
     /** See {@link #setRetainInOnStop}. */
     private boolean mRetainInOnStop;
 
-    private final PackageMonitor mPackageMonitor = new PackageMonitor() {
-        @Override public void onSomePackagesChanged() {
-            mAdapter.handlePackagesChanged();
-            bindProfileView();
-        }
-
-        @Override
-        public boolean onPackageChanged(String packageName, int uid, String[] components) {
-            // We care about all package changes, not just the whole package itself which is
-            // default behavior.
-            return true;
-        }
-    };
+    private final PackageMonitor mPackageMonitor = createPackageMonitor();
 
     /**
      * Get the string resource to be used as a label for the link to the resolver activity for an
@@ -234,6 +222,23 @@
         }
     }
 
+    protected PackageMonitor createPackageMonitor() {
+        return new PackageMonitor() {
+            @Override
+            public void onSomePackagesChanged() {
+                mAdapter.handlePackagesChanged();
+                bindProfileView();
+            }
+
+            @Override
+            public boolean onPackageChanged(String packageName, int uid, String[] components) {
+                // We care about all package changes, not just the whole package itself which is
+                // default behavior.
+                return true;
+            }
+        };
+    }
+
     private Intent makeMyIntent() {
         Intent intent = new Intent(getIntent());
         intent.setComponent(null);
@@ -398,6 +403,8 @@
                 mSystemWindowInsets.bottom));
         ((ListView) mAdapterView).addFooterView(mFooterSpacer);
 
+        resetButtonBar();
+
         return insets.consumeSystemWindowInsets();
     }
 
diff --git a/core/java/com/android/internal/colorextraction/ColorExtractor.java b/core/java/com/android/internal/colorextraction/ColorExtractor.java
index d9fd3b5..b27c11b 100644
--- a/core/java/com/android/internal/colorextraction/ColorExtractor.java
+++ b/core/java/com/android/internal/colorextraction/ColorExtractor.java
@@ -53,11 +53,13 @@
     protected WallpaperColors mLockColors;
 
     public ColorExtractor(Context context) {
-        this(context, new Tonal(context), true /* immediately */);
+        this(context, new Tonal(context), true /* immediately */,
+                context.getSystemService(WallpaperManager.class));
     }
 
     @VisibleForTesting
-    public ColorExtractor(Context context, ExtractionType extractionType, boolean immediately) {
+    public ColorExtractor(Context context, ExtractionType extractionType, boolean immediately,
+            WallpaperManager wallpaperManager) {
         mContext = context;
         mExtractionType = extractionType;
 
@@ -72,7 +74,6 @@
 
         mOnColorsChangedListeners = new ArrayList<>();
 
-        WallpaperManager wallpaperManager = mContext.getSystemService(WallpaperManager.class);
         if (wallpaperManager == null) {
             Log.w(TAG, "Can't listen to color changes!");
         } else {
@@ -110,7 +111,7 @@
         }
     }
 
-    private void extractWallpaperColors() {
+    protected void extractWallpaperColors() {
         GradientColors[] systemColors = mGradientColors.get(WallpaperManager.FLAG_SYSTEM);
         GradientColors[] lockColors = mGradientColors.get(WallpaperManager.FLAG_LOCK);
         extractInto(mSystemColors,
diff --git a/core/java/com/android/internal/config/sysui/SystemUiDeviceConfigFlags.java b/core/java/com/android/internal/config/sysui/SystemUiDeviceConfigFlags.java
index 1b0a458..8b90722 100644
--- a/core/java/com/android/internal/config/sysui/SystemUiDeviceConfigFlags.java
+++ b/core/java/com/android/internal/config/sysui/SystemUiDeviceConfigFlags.java
@@ -106,13 +106,6 @@
      */
     public static final String HASH_SALT_MAX_DAYS = "hash_salt_max_days";
 
-    // Flag related to Privacy Indicators
-
-    /**
-     * Whether the Permissions Hub is showing.
-     */
-    public static final String PROPERTY_PERMISSIONS_HUB_ENABLED = "permissions_hub_enabled";
-
     // Flags related to Assistant Handles
 
     /**
@@ -127,6 +120,26 @@
             "assist_handles_show_and_go_duration_ms";
 
     /**
+     * (long) How long, in milliseconds, to wait before showing the Assist Handles temporarily when
+     * performing a short delayed show.
+     */
+    public static final String ASSIST_HANDLES_SHOW_AND_GO_DELAYED_SHORT_DELAY_MS =
+            "assist_handles_show_and_go_delayed_short_delay_ms";
+
+    /**
+     * (long) How long, in milliseconds, to wait before showing the Assist Handles temporarily when
+     * performing a long delayed show.
+     */
+    public static final String ASSIST_HANDLES_SHOW_AND_GO_DELAYED_LONG_DELAY_MS =
+            "assist_handles_show_and_go_delayed_long_delay_ms";
+
+    /**
+     * (long) How long, in milliseconds, to wait before resetting delayed show delay times.
+     */
+    public static final String ASSIST_HANDLES_SHOW_AND_GO_DELAY_RESET_TIMEOUT_MS =
+            "assist_handles_show_and_go_delay_reset_timeout_ms";
+
+    /**
      * (long) How long, in milliseconds, to wait before displaying Assist Handles temporarily after
      * hiding them.
      */
@@ -145,5 +158,23 @@
      */
     public static final String ASSIST_HANDLES_LEARN_COUNT = "assist_handles_learn_count";
 
+    /**
+     * (bool) Whether to suppress handles on lockscreen."
+     */
+    public static final String ASSIST_HANDLES_SUPPRESS_ON_LOCKSCREEN =
+            "assist_handles_suppress_on_lockscreen";
+
+    /**
+     * (bool) Whether to suppress handles on launcher."
+     */
+    public static final String ASSIST_HANDLES_SUPPRESS_ON_LAUNCHER =
+            "assist_handles_suppress_on_launcher";
+
+    /**
+     * (bool) Whether to suppress handles on apps."
+     */
+    public static final String ASSIST_HANDLES_SUPPRESS_ON_APPS =
+            "assist_handles_suppress_on_apps";
+
     private SystemUiDeviceConfigFlags() { }
 }
diff --git a/core/java/com/android/internal/net/VpnInfo.java b/core/java/com/android/internal/net/VpnInfo.java
index e74af5e..b1a41287 100644
--- a/core/java/com/android/internal/net/VpnInfo.java
+++ b/core/java/com/android/internal/net/VpnInfo.java
@@ -19,8 +19,6 @@
 import android.os.Parcel;
 import android.os.Parcelable;
 
-import java.util.Arrays;
-
 /**
  * A lightweight container used to carry information of the ongoing VPN.
  * Internal use only..
@@ -30,14 +28,14 @@
 public class VpnInfo implements Parcelable {
     public int ownerUid;
     public String vpnIface;
-    public String[] underlyingIfaces;
+    public String primaryUnderlyingIface;
 
     @Override
     public String toString() {
         return "VpnInfo{"
                 + "ownerUid=" + ownerUid
                 + ", vpnIface='" + vpnIface + '\''
-                + ", underlyingIfaces='" + Arrays.toString(underlyingIfaces) + '\''
+                + ", primaryUnderlyingIface='" + primaryUnderlyingIface + '\''
                 + '}';
     }
 
@@ -50,7 +48,7 @@
     public void writeToParcel(Parcel dest, int flags) {
         dest.writeInt(ownerUid);
         dest.writeString(vpnIface);
-        dest.writeStringArray(underlyingIfaces);
+        dest.writeString(primaryUnderlyingIface);
     }
 
     public static final Parcelable.Creator<VpnInfo> CREATOR = new Parcelable.Creator<VpnInfo>() {
@@ -59,7 +57,7 @@
             VpnInfo info = new VpnInfo();
             info.ownerUid = source.readInt();
             info.vpnIface = source.readString();
-            info.underlyingIfaces = source.readStringArray();
+            info.primaryUnderlyingIface = source.readString();
             return info;
         }
 
diff --git a/core/java/com/android/internal/os/BatteryStatsHistory.java b/core/java/com/android/internal/os/BatteryStatsHistory.java
index 24ad751..392f074 100644
--- a/core/java/com/android/internal/os/BatteryStatsHistory.java
+++ b/core/java/com/android/internal/os/BatteryStatsHistory.java
@@ -28,7 +28,6 @@
 
 import java.io.File;
 import java.io.FilenameFilter;
-import java.io.IOException;
 import java.util.ArrayList;
 import java.util.Collections;
 import java.util.List;
@@ -138,11 +137,12 @@
         if (!dedup.isEmpty()) {
             mFileNumbers.addAll(dedup);
             Collections.sort(mFileNumbers);
+            setActiveFile(mFileNumbers.get(mFileNumbers.size() - 1));
         } else {
             // No file found, default to have file 0.
             mFileNumbers.add(0);
+            setActiveFile(0);
         }
-        createActiveFile();
     }
 
     /**
@@ -157,22 +157,15 @@
         mHistoryBuffer = historyBuffer;
     }
     /**
-     * The highest numbered history file is active file that mHistoryBuffer is backed up into.
-     * If file does not exists, truncate() creates a empty file.
+     * Set the active file that mHistoryBuffer is backed up into.
+     *
+     * @param fileNumber the history file that mHistoryBuffer is backed up into.
      */
-    private void createActiveFile() {
-        final AtomicFile file = getFile(mFileNumbers.get(mFileNumbers.size() - 1));
+    private void setActiveFile(int fileNumber) {
+        mActiveFile = getFile(fileNumber);
         if (DEBUG) {
-            Slog.d(TAG, "activeHistoryFile:" + file.getBaseFile().getPath());
+            Slog.d(TAG, "activeHistoryFile:" + mActiveFile.getBaseFile().getPath());
         }
-        if (!file.exists()) {
-            try {
-                file.truncate();
-            } catch (IOException e) {
-                Slog.e(TAG, "Error creating history file "+ file.getBaseFile().getPath(), e);
-            }
-        }
-        mActiveFile = file;
     }
 
     /**
@@ -189,7 +182,7 @@
      * When {@link #mHistoryBuffer} reaches {@link BatteryStatsImpl.Constants#MAX_HISTORY_BUFFER},
      * create next history file.
      */
-    public void createNextFile() {
+    public void startNextFile() {
         if (mFileNumbers.isEmpty()) {
             Slog.wtf(TAG, "mFileNumbers should never be empty");
             return;
@@ -198,7 +191,7 @@
         // number plus one.
         final int next = mFileNumbers.get(mFileNumbers.size() - 1) + 1;
         mFileNumbers.add(next);
-        createActiveFile();
+        setActiveFile(next);
 
         // if free disk space is less than 100MB, delete oldest history file.
         if (!hasFreeDiskSpace()) {
@@ -224,7 +217,7 @@
         }
         mFileNumbers.clear();
         mFileNumbers.add(0);
-        createActiveFile();
+        setActiveFile(0);
     }
 
     /**
diff --git a/core/java/com/android/internal/os/BatteryStatsImpl.java b/core/java/com/android/internal/os/BatteryStatsImpl.java
index c04a249..3a7caa4 100644
--- a/core/java/com/android/internal/os/BatteryStatsImpl.java
+++ b/core/java/com/android/internal/os/BatteryStatsImpl.java
@@ -188,6 +188,7 @@
     static final long DELAY_UPDATE_WAKELOCKS = 5*1000;
 
     private static final double MILLISECONDS_IN_HOUR = 3600 * 1000;
+    private static final long MILLISECONDS_IN_YEAR = 365 * 24 * 3600 * 1000L;
 
     private final KernelWakelockReader mKernelWakelockReader = new KernelWakelockReader();
     private final KernelWakelockStats mTmpWakelockStats = new KernelWakelockStats();
@@ -3608,8 +3609,8 @@
 
     public void createFakeHistoryEvents(long numEvents) {
         for(long i = 0; i < numEvents; i++) {
-            noteWifiOnLocked();
-            noteWifiOffLocked();
+            noteLongPartialWakelockStart("name1", "historyName1", 1000);
+            noteLongPartialWakelockFinish("name1", "historyName1", 1000);
         }
     }
 
@@ -3685,16 +3686,17 @@
                 Slog.d(TAG, "addHistoryBufferLocked writeHistoryLocked takes ms:"
                         + (SystemClock.uptimeMillis() - start));
             }
-            mBatteryStatsHistory.createNextFile();
+            mBatteryStatsHistory.startNextFile();
             mHistoryBuffer.setDataSize(0);
             mHistoryBuffer.setDataPosition(0);
             mHistoryBuffer.setDataCapacity(mConstants.MAX_HISTORY_BUFFER / 2);
             mHistoryBufferLastPos = -1;
             final long elapsedRealtime = mClocks.elapsedRealtime();
             final long uptime = mClocks.uptimeMillis();
+            HistoryItem newItem = new HistoryItem();
+            newItem.setTo(cur);
             startRecordingHistory(elapsedRealtime, uptime, false);
-
-            addHistoryBufferLocked(elapsedRealtimeMs, HistoryItem.CMD_UPDATE, cur);
+            addHistoryBufferLocked(elapsedRealtimeMs, HistoryItem.CMD_UPDATE, newItem);
             return;
         }
 
@@ -3955,25 +3957,11 @@
         addHistoryEventLocked(elapsedRealtime, uptime, code, name, uid);
     }
 
-    boolean ensureStartClockTime(final long currentTime) {
-        final long ABOUT_ONE_YEAR = 365*24*60*60*1000L;
-        if ((currentTime > ABOUT_ONE_YEAR && mStartClockTime < (currentTime-ABOUT_ONE_YEAR))
-                || (mStartClockTime > currentTime)) {
-            // If the start clock time has changed by more than a year, then presumably
-            // the previous time was completely bogus.  So we are going to figure out a
-            // new time based on how much time has elapsed since we started counting.
-            mStartClockTime = currentTime - (mClocks.elapsedRealtime()-(mRealtimeStart/1000));
-            return true;
-        }
-        return false;
-    }
-
     public void noteCurrentTimeChangedLocked() {
         final long currentTime = System.currentTimeMillis();
         final long elapsedRealtime = mClocks.elapsedRealtime();
         final long uptime = mClocks.uptimeMillis();
         recordCurrentTimeChangeLocked(currentTime, elapsedRealtime, uptime);
-        ensureStartClockTime(currentTime);
     }
 
     public void noteProcessStartLocked(String name, int uid) {
@@ -6452,9 +6440,15 @@
 
     @Override public long getStartClockTime() {
         final long currentTime = System.currentTimeMillis();
-        if (ensureStartClockTime(currentTime)) {
+        if ((currentTime > MILLISECONDS_IN_YEAR
+                && mStartClockTime < (currentTime - MILLISECONDS_IN_YEAR))
+                || (mStartClockTime > currentTime)) {
+            // If the start clock time has changed by more than a year, then presumably
+            // the previous time was completely bogus.  So we are going to figure out a
+            // new time based on how much time has elapsed since we started counting.
             recordCurrentTimeChangeLocked(currentTime, mClocks.elapsedRealtime(),
                     mClocks.uptimeMillis());
+            return currentTime - (mClocks.elapsedRealtime() - (mRealtimeStart / 1000));
         }
         return mStartClockTime;
     }
@@ -14022,7 +14016,7 @@
 
         // Pull the clock time.  This may update the time and make a new history entry
         // if we had originally pulled a time before the RTC was set.
-        long startClockTime = getStartClockTime();
+        getStartClockTime();
 
         final long NOW_SYS = mClocks.uptimeMillis() * 1000;
         final long NOWREAL_SYS = mClocks.elapsedRealtime() * 1000;
@@ -14046,7 +14040,7 @@
         out.writeInt(mStartCount);
         out.writeLong(computeUptime(NOW_SYS, STATS_SINCE_CHARGED));
         out.writeLong(computeRealtime(NOWREAL_SYS, STATS_SINCE_CHARGED));
-        out.writeLong(startClockTime);
+        out.writeLong(mStartClockTime);
         out.writeString(mStartPlatformVersion);
         out.writeString(mEndPlatformVersion);
         mOnBatteryTimeBase.writeSummaryToParcel(out, NOW_SYS, NOWREAL_SYS);
@@ -14759,7 +14753,7 @@
 
         // Pull the clock time.  This may update the time and make a new history entry
         // if we had originally pulled a time before the RTC was set.
-        long startClockTime = getStartClockTime();
+        getStartClockTime();
 
         final long uSecUptime = mClocks.uptimeMillis() * 1000;
         final long uSecRealtime = mClocks.elapsedRealtime() * 1000;
@@ -14772,7 +14766,7 @@
         mBatteryStatsHistory.writeToParcel(out);
 
         out.writeInt(mStartCount);
-        out.writeLong(startClockTime);
+        out.writeLong(mStartClockTime);
         out.writeString(mStartPlatformVersion);
         out.writeString(mEndPlatformVersion);
         out.writeLong(mUptime);
diff --git a/core/java/com/android/internal/os/BinderDeathDispatcher.java b/core/java/com/android/internal/os/BinderDeathDispatcher.java
new file mode 100644
index 0000000..0c93f7f
--- /dev/null
+++ b/core/java/com/android/internal/os/BinderDeathDispatcher.java
@@ -0,0 +1,147 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.internal.os;
+
+import android.annotation.NonNull;
+import android.annotation.Nullable;
+import android.os.IBinder;
+import android.os.IBinder.DeathRecipient;
+import android.os.IInterface;
+import android.os.RemoteException;
+import android.util.ArrayMap;
+import android.util.ArraySet;
+
+import com.android.internal.annotations.GuardedBy;
+import com.android.internal.annotations.VisibleForTesting;
+
+import java.io.PrintWriter;
+
+/**
+ * Multiplexes multiple binder death recipients on the same binder objects, so that at the native
+ * level, we only need to keep track of one death recipient reference. This will help reduce the
+ * number of JNI strong references.
+ *
+ * test with: atest FrameworksCoreTests:BinderDeathDispatcherTest
+ */
+public class BinderDeathDispatcher<T extends IInterface> {
+    private static final String TAG = "BinderDeathDispatcher";
+
+    private final Object mLock = new Object();
+
+    @GuardedBy("mLock")
+    private final ArrayMap<IBinder, RecipientsInfo> mTargets = new ArrayMap<>();
+
+    @VisibleForTesting
+    class RecipientsInfo implements DeathRecipient {
+        final IBinder mTarget;
+
+        /**
+         * Recipient list. If it's null, {@link #mTarget} has already died, but in that case
+         * this RecipientsInfo instance is removed from {@link #mTargets}.
+         */
+        @GuardedBy("mLock")
+        @Nullable
+        ArraySet<DeathRecipient> mRecipients = new ArraySet<>();
+
+        private RecipientsInfo(IBinder target) {
+            mTarget = target;
+        }
+
+        @Override
+        public void binderDied() {
+            final ArraySet<DeathRecipient> copy;
+            synchronized (mLock) {
+                copy = mRecipients;
+                mRecipients = null;
+
+                // Also remove from the targets.
+                mTargets.remove(mTarget);
+            }
+            if (copy == null) {
+                return;
+            }
+            // Let's call it without holding the lock.
+            final int size = copy.size();
+            for (int i = 0; i < size; i++) {
+                copy.valueAt(i).binderDied();
+            }
+        }
+    }
+
+    /**
+     * Add a {@code recipient} to the death recipient list on {@code target}.
+     *
+     * @return # of recipients in the recipient list, including {@code recipient}. Or, -1
+     * if {@code target} is already dead, in which case recipient's
+     * {@link DeathRecipient#binderDied} won't be called.
+     */
+    public int linkToDeath(@NonNull T target, @NonNull DeathRecipient recipient) {
+        final IBinder ib = target.asBinder();
+        synchronized (mLock) {
+            RecipientsInfo info = mTargets.get(ib);
+            if (info == null) {
+                info = new RecipientsInfo(ib);
+
+                // First recipient; need to link to death.
+                try {
+                    ib.linkToDeath(info, 0);
+                } catch (RemoteException e) {
+                    return -1; // Already dead.
+                }
+                mTargets.put(ib, info);
+            }
+            info.mRecipients.add(recipient);
+            return info.mRecipients.size();
+        }
+    }
+
+    public void unlinkToDeath(@NonNull T target, @NonNull DeathRecipient recipient) {
+        final IBinder ib = target.asBinder();
+
+        synchronized (mLock) {
+            final RecipientsInfo info = mTargets.get(ib);
+            if (info == null) {
+                return;
+            }
+            if (info.mRecipients.remove(recipient) && info.mRecipients.size() == 0) {
+                info.mTarget.unlinkToDeath(info, 0);
+                mTargets.remove(info.mTarget);
+            }
+        }
+    }
+
+    public void dump(PrintWriter pw, String indent) {
+        synchronized (mLock) {
+            pw.print(indent);
+            pw.print("# of watched binders: ");
+            pw.println(mTargets.size());
+
+            pw.print(indent);
+            pw.print("# of death recipients: ");
+            int n = 0;
+            for (RecipientsInfo info : mTargets.values()) {
+                n += info.mRecipients.size();
+            }
+            pw.println(n);
+        }
+    }
+
+    @VisibleForTesting
+    public ArrayMap<IBinder, RecipientsInfo> getTargetsForTest() {
+        return mTargets;
+    }
+}
diff --git a/core/java/com/android/internal/os/Zygote.java b/core/java/com/android/internal/os/Zygote.java
index 2736c6a..2ba9cf1 100644
--- a/core/java/com/android/internal/os/Zygote.java
+++ b/core/java/com/android/internal/os/Zygote.java
@@ -512,13 +512,13 @@
         Credentials peerCredentials = null;
         ZygoteArguments args = null;
 
-        // Load resources
-        ZygoteInit.nativePreloadGraphicsDriver();
-
         while (true) {
             try {
                 sessionSocket = usapPoolSocket.accept();
 
+                // Block SIGTERM so we won't be killed if the Zygote flushes the USAP pool.
+                blockSigTerm();
+
                 BufferedReader usapReader =
                         new BufferedReader(new InputStreamReader(sessionSocket.getInputStream()));
                 usapOutputStream =
@@ -537,87 +537,116 @@
                 } else {
                     Log.e("USAP", "Truncated command received.");
                     IoUtils.closeQuietly(sessionSocket);
+
+                    // Re-enable SIGTERM so the USAP can be flushed from the pool if necessary.
+                    unblockSigTerm();
                 }
             } catch (Exception ex) {
                 Log.e("USAP", ex.getMessage());
                 IoUtils.closeQuietly(sessionSocket);
+
+                // Re-enable SIGTERM so the USAP can be flushed from the pool if necessary.
+                unblockSigTerm();
             }
         }
 
-        applyUidSecurityPolicy(args, peerCredentials);
-        applyDebuggerSystemProperty(args);
-
-        int[][] rlimits = null;
-
-        if (args.mRLimits != null) {
-            rlimits = args.mRLimits.toArray(INT_ARRAY_2D);
-        }
-
-        // This must happen before the SELinux policy for this process is
-        // changed when specializing.
         try {
-            // Used by ZygoteProcess.zygoteSendArgsAndGetResult to fill in a
-            // Process.ProcessStartResult object.
-            usapOutputStream.writeInt(pid);
-        } catch (IOException ioEx) {
-            Log.e("USAP", "Failed to write response to session socket: " + ioEx.getMessage());
-            System.exit(-1);
-        } finally {
-            IoUtils.closeQuietly(sessionSocket);
+            // SIGTERM is blocked on loop exit.  This prevents a USAP that is specializing from
+            // being killed during a pool flush.
+
+            applyUidSecurityPolicy(args, peerCredentials);
+            applyDebuggerSystemProperty(args);
+
+            int[][] rlimits = null;
+
+            if (args.mRLimits != null) {
+                rlimits = args.mRLimits.toArray(INT_ARRAY_2D);
+            }
+
+            // This must happen before the SELinux policy for this process is
+            // changed when specializing.
+            try {
+                // Used by ZygoteProcess.zygoteSendArgsAndGetResult to fill in a
+                // Process.ProcessStartResult object.
+                usapOutputStream.writeInt(pid);
+            } catch (IOException ioEx) {
+                Log.e("USAP", "Failed to write response to session socket: "
+                        + ioEx.getMessage());
+                throw new RuntimeException(ioEx);
+            } finally {
+                IoUtils.closeQuietly(sessionSocket);
+
+                try {
+                    // This socket is closed using Os.close due to an issue with the implementation
+                    // of LocalSocketImp.close().  Because the raw FD is created by init and then
+                    // loaded from an environment variable (as opposed to being created by the
+                    // LocalSocketImpl itself) the current implementation will not actually close
+                    // the underlying FD.
+                    //
+                    // See b/130309968 for discussion of this issue.
+                    Os.close(usapPoolSocket.getFileDescriptor());
+                } catch (ErrnoException ex) {
+                    Log.e("USAP", "Failed to close USAP pool socket");
+                    throw new RuntimeException(ex);
+                }
+            }
 
             try {
-                // This socket is closed using Os.close due to an issue with the implementation of
-                // LocalSocketImp.close.  Because the raw FD is created by init and then loaded from
-                // an environment variable (as opposed to being created by the LocalSocketImpl
-                // itself) the current implementation will not actually close the underlying FD.
-                //
-                // See b/130309968 for discussion of this issue.
-                Os.close(usapPoolSocket.getFileDescriptor());
-            } catch (ErrnoException ex) {
-                Log.e("USAP", "Failed to close USAP pool socket: " + ex.getMessage());
+                ByteArrayOutputStream buffer =
+                        new ByteArrayOutputStream(Zygote.USAP_MANAGEMENT_MESSAGE_BYTES);
+                DataOutputStream outputStream = new DataOutputStream(buffer);
+
+                // This is written as a long so that the USAP reporting pipe and USAP pool event FD
+                // handlers in ZygoteServer.runSelectLoop can be unified.  These two cases should
+                // both send/receive 8 bytes.
+                outputStream.writeLong(pid);
+                outputStream.flush();
+
+                Os.write(writePipe, buffer.toByteArray(), 0, buffer.size());
+            } catch (Exception ex) {
+                Log.e("USAP",
+                        String.format("Failed to write PID (%d) to pipe (%d): %s",
+                                pid, writePipe.getInt$(), ex.getMessage()));
+                throw new RuntimeException(ex);
+            } finally {
+                IoUtils.closeQuietly(writePipe);
             }
-        }
 
-        try {
-            ByteArrayOutputStream buffer =
-                    new ByteArrayOutputStream(Zygote.USAP_MANAGEMENT_MESSAGE_BYTES);
-            DataOutputStream outputStream = new DataOutputStream(buffer);
+            specializeAppProcess(args.mUid, args.mGid, args.mGids,
+                                 args.mRuntimeFlags, rlimits, args.mMountExternal,
+                                 args.mSeInfo, args.mNiceName, args.mStartChildZygote,
+                                 args.mInstructionSet, args.mAppDataDir);
 
-            // This is written as a long so that the USAP reporting pipe and USAP pool event FD
-            // handlers in ZygoteServer.runSelectLoop can be unified.  These two cases should both
-            // send/receive 8 bytes.
-            outputStream.writeLong(pid);
-            outputStream.flush();
+            disableExecuteOnly(args.mTargetSdkVersion);
 
-            Os.write(writePipe, buffer.toByteArray(), 0, buffer.size());
-        } catch (Exception ex) {
-            Log.e("USAP",
-                    String.format("Failed to write PID (%d) to pipe (%d): %s",
-                            pid, writePipe.getInt$(), ex.getMessage()));
-            System.exit(-1);
+            if (args.mNiceName != null) {
+                Process.setArgV0(args.mNiceName);
+            }
+
+            // End of the postFork event.
+            Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
+
+            return ZygoteInit.zygoteInit(args.mTargetSdkVersion,
+                                         args.mRemainingArgs,
+                                         null /* classLoader */);
         } finally {
-            IoUtils.closeQuietly(writePipe);
+            // Unblock SIGTERM to restore the process to default behavior.
+            unblockSigTerm();
         }
-
-        specializeAppProcess(args.mUid, args.mGid, args.mGids,
-                           args.mRuntimeFlags, rlimits, args.mMountExternal,
-                           args.mSeInfo, args.mNiceName, args.mStartChildZygote,
-                           args.mInstructionSet, args.mAppDataDir);
-
-        disableExecuteOnly(args.mTargetSdkVersion);
-
-        if (args.mNiceName != null) {
-            Process.setArgV0(args.mNiceName);
-        }
-
-        // End of the postFork event.
-        Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
-
-        return ZygoteInit.zygoteInit(args.mTargetSdkVersion,
-                                     args.mRemainingArgs,
-                                     null /* classLoader */);
     }
 
+    private static void blockSigTerm() {
+        nativeBlockSigTerm();
+    }
+
+    private static native void nativeBlockSigTerm();
+
+    private static void unblockSigTerm() {
+        nativeUnblockSigTerm();
+    }
+
+    private static native void nativeUnblockSigTerm();
+
     private static final String USAP_ERROR_PREFIX = "Invalid command to USAP: ";
 
     /**
diff --git a/core/java/com/android/internal/os/ZygoteConnection.java b/core/java/com/android/internal/os/ZygoteConnection.java
index 785256e..e556dd4 100644
--- a/core/java/com/android/internal/os/ZygoteConnection.java
+++ b/core/java/com/android/internal/os/ZygoteConnection.java
@@ -338,6 +338,7 @@
             Runnable stateChangeCode) {
         try {
             if (zygoteServer.isUsapPoolEnabled()) {
+                Log.i(TAG, "Emptying USAP Pool due to state change.");
                 Zygote.emptyUsapPool();
             }
 
@@ -351,6 +352,8 @@
                 if (fpResult != null) {
                     zygoteServer.setForkChild();
                     return fpResult;
+                } else {
+                    Log.i(TAG, "Finished refilling USAP Pool after state change.");
                 }
             }
 
diff --git a/core/java/com/android/internal/os/ZygoteInit.java b/core/java/com/android/internal/os/ZygoteInit.java
index f9e868f..7ec8309 100644
--- a/core/java/com/android/internal/os/ZygoteInit.java
+++ b/core/java/com/android/internal/os/ZygoteInit.java
@@ -87,7 +87,6 @@
 
     private static final String PROPERTY_DISABLE_GRAPHICS_DRIVER_PRELOADING =
             "ro.zygote.disable_gl_preload";
-    private static final String PROPERTY_GFX_DRIVER = "ro.gfx.driver.0";
 
     private static final int LOG_BOOT_PROGRESS_PRELOAD_START = 3020;
     private static final int LOG_BOOT_PROGRESS_PRELOAD_END = 3030;
@@ -203,9 +202,7 @@
     static native void nativePreloadGraphicsDriver();
 
     private static void maybePreloadGraphicsDriver() {
-        String driverPackageName = SystemProperties.get(PROPERTY_GFX_DRIVER);
-        if (!SystemProperties.getBoolean(PROPERTY_DISABLE_GRAPHICS_DRIVER_PRELOADING, false)
-                && (driverPackageName == null || driverPackageName.isEmpty())) {
+        if (!SystemProperties.getBoolean(PROPERTY_DISABLE_GRAPHICS_DRIVER_PRELOADING, false)) {
             nativePreloadGraphicsDriver();
         }
     }
diff --git a/core/java/com/android/internal/policy/DecorView.java b/core/java/com/android/internal/policy/DecorView.java
index 1a16150..723f161 100644
--- a/core/java/com/android/internal/policy/DecorView.java
+++ b/core/java/com/android/internal/policy/DecorView.java
@@ -262,8 +262,10 @@
     private final int mResizeShadowSize;
     private final Paint mVerticalResizeShadowPaint = new Paint();
     private final Paint mHorizontalResizeShadowPaint = new Paint();
+    private final Paint mLegacyNavigationBarBackgroundPaint = new Paint();
     private Insets mBackgroundInsets = Insets.NONE;
     private Insets mLastBackgroundInsets = Insets.NONE;
+    private boolean mDrawLegacyNavigationBarBackground;
 
     DecorView(Context context, int featureId, PhoneWindow window,
             WindowManager.LayoutParams params) {
@@ -292,6 +294,8 @@
         mResizeShadowSize = context.getResources().getDimensionPixelSize(
                 R.dimen.resize_shadow_size);
         initResizingPaints();
+
+        mLegacyNavigationBarBackgroundPaint.setColor(Color.BLACK);
     }
 
     void setBackgroundFallback(@Nullable Drawable fallbackDrawable) {
@@ -1004,6 +1008,10 @@
     public void onWindowSystemUiVisibilityChanged(int visible) {
         updateColorViews(null /* insets */, true /* animate */);
         updateDecorCaptionStatus(getResources().getConfiguration());
+
+        if (mStatusGuard != null && mStatusGuard.getVisibility() == VISIBLE) {
+            updateStatusGuardColor();
+        }
     }
 
     @Override
@@ -1139,6 +1147,8 @@
                     navBarToRightEdge || navBarToLeftEdge, navBarToLeftEdge,
                     0 /* sideInset */, animate && !disallowAnimate,
                     mForceWindowDrawsBarBackgrounds);
+            mDrawLegacyNavigationBarBackground = mNavigationColorViewState.visible
+                    && (mWindow.getAttributes().flags & FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS) == 0;
 
             boolean statusBarNeedsRightInset = navBarToRightEdge
                     && mNavigationColorViewState.present;
@@ -1160,16 +1170,17 @@
         // Note: We don't need to check for IN_SCREEN or INSET_DECOR because unlike the status bar,
         // these flags wouldn't make the window draw behind the navigation bar, unless
         // LAYOUT_HIDE_NAVIGATION was set.
+        boolean hideNavigation = (sysUiVisibility & SYSTEM_UI_FLAG_HIDE_NAVIGATION) != 0;
         boolean forceConsumingNavBar = (mForceWindowDrawsBarBackgrounds
                         && (attrs.flags & FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS) == 0
                         && (sysUiVisibility & SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION) == 0
-                        && (sysUiVisibility & SYSTEM_UI_FLAG_HIDE_NAVIGATION) == 0)
-                || mLastShouldAlwaysConsumeSystemBars;
+                        && !hideNavigation)
+                || (mLastShouldAlwaysConsumeSystemBars && hideNavigation);
 
         boolean consumingNavBar =
                 ((attrs.flags & FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS) != 0
                         && (sysUiVisibility & SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION) == 0
-                        && (sysUiVisibility & SYSTEM_UI_FLAG_HIDE_NAVIGATION) == 0)
+                        && !hideNavigation)
                 || forceConsumingNavBar;
 
         // If we didn't request fullscreen layout, but we still got it because of the
@@ -1461,28 +1472,45 @@
                     }
                     final Rect rect = mTempRect;
 
-                    // If the parent doesn't consume the insets, manually
-                    // apply the default system window insets.
-                    mWindow.mContentParent.computeSystemWindowInsets(insets, rect);
-                    final int newMargin = rect.top == 0 ? insets.getSystemWindowInsetTop() : 0;
-                    if (mlp.topMargin != newMargin) {
-                        mlpChanged = true;
-                        mlp.topMargin = insets.getSystemWindowInsetTop();
+                    // Apply the insets that have not been applied by the contentParent yet.
+                    WindowInsets innerInsets =
+                            mWindow.mContentParent.computeSystemWindowInsets(insets, rect);
+                    int newTopMargin = innerInsets.getSystemWindowInsetTop();
+                    int newLeftMargin = innerInsets.getSystemWindowInsetLeft();
+                    int newRightMargin = innerInsets.getSystemWindowInsetRight();
 
-                        if (mStatusGuard == null) {
-                            mStatusGuard = new View(mContext);
-                            mStatusGuard.setBackgroundColor(mContext.getColor(
-                                    R.color.decor_view_status_guard));
-                            addView(mStatusGuard, indexOfChild(mStatusColorViewState.view),
-                                    new LayoutParams(LayoutParams.MATCH_PARENT,
-                                            mlp.topMargin, Gravity.START | Gravity.TOP));
-                        } else {
-                            final LayoutParams lp = (LayoutParams)
-                                    mStatusGuard.getLayoutParams();
-                            if (lp.height != mlp.topMargin) {
-                                lp.height = mlp.topMargin;
-                                mStatusGuard.setLayoutParams(lp);
-                            }
+                    // Must use root window insets for the guard, because the color views consume
+                    // the navigation bar inset if the window does not request LAYOUT_HIDE_NAV - but
+                    // the status guard is attached at the root.
+                    WindowInsets rootInsets = getRootWindowInsets();
+                    int newGuardLeftMargin = rootInsets.getSystemWindowInsetLeft();
+                    int newGuardRightMargin = rootInsets.getSystemWindowInsetRight();
+
+                    if (mlp.topMargin != newTopMargin || mlp.leftMargin != newLeftMargin
+                            || mlp.rightMargin != newRightMargin) {
+                        mlpChanged = true;
+                        mlp.topMargin = newTopMargin;
+                        mlp.leftMargin = newLeftMargin;
+                        mlp.rightMargin = newRightMargin;
+                    }
+
+                    if (newTopMargin > 0 && mStatusGuard == null) {
+                        mStatusGuard = new View(mContext);
+                        mStatusGuard.setVisibility(GONE);
+                        final LayoutParams lp = new LayoutParams(MATCH_PARENT,
+                                mlp.topMargin, Gravity.LEFT | Gravity.TOP);
+                        lp.leftMargin = newGuardLeftMargin;
+                        lp.rightMargin = newGuardRightMargin;
+                        addView(mStatusGuard, indexOfChild(mStatusColorViewState.view), lp);
+                    } else if (mStatusGuard != null) {
+                        final LayoutParams lp = (LayoutParams)
+                                mStatusGuard.getLayoutParams();
+                        if (lp.height != mlp.topMargin || lp.leftMargin != newGuardLeftMargin
+                                || lp.rightMargin != newGuardRightMargin) {
+                            lp.height = mlp.topMargin;
+                            lp.leftMargin = newGuardLeftMargin;
+                            lp.rightMargin = newGuardRightMargin;
+                            mStatusGuard.setLayoutParams(lp);
                         }
                     }
 
@@ -1490,6 +1518,11 @@
                     // always show the status guard above it if we have one.
                     showStatusGuard = mStatusGuard != null;
 
+                    if (showStatusGuard && mStatusGuard.getVisibility() != VISIBLE) {
+                        // If it wasn't previously shown, the color may be stale
+                        updateStatusGuardColor();
+                    }
+
                     // We only need to consume the insets if the action
                     // mode is overlaid on the app content (e.g. it's
                     // sitting in a FrameLayout, see
@@ -1501,7 +1534,7 @@
                     }
                 } else {
                     // reset top margin
-                    if (mlp.topMargin != 0) {
+                    if (mlp.topMargin != 0 || mlp.leftMargin != 0 || mlp.rightMargin != 0) {
                         mlpChanged = true;
                         mlp.topMargin = 0;
                     }
@@ -1512,11 +1545,19 @@
             }
         }
         if (mStatusGuard != null) {
-            mStatusGuard.setVisibility(showStatusGuard ? View.VISIBLE : View.GONE);
+            mStatusGuard.setVisibility(showStatusGuard ? VISIBLE : GONE);
         }
         return insets;
     }
 
+    private void updateStatusGuardColor() {
+        boolean lightStatusBar =
+                (getWindowSystemUiVisibility() & SYSTEM_UI_FLAG_LIGHT_STATUS_BAR) != 0;
+        mStatusGuard.setBackgroundColor(lightStatusBar
+                ? mContext.getColor(R.color.decor_view_status_guard_light)
+                : mContext.getColor(R.color.decor_view_status_guard));
+    }
+
     /**
      * Overrides the view outline when the activity enters picture-in-picture to ensure that it has
      * an opaque shadow even if the window background is completely transparent. This only applies
@@ -2275,6 +2316,7 @@
     @Override
     public void onPostDraw(RecordingCanvas canvas) {
         drawResizingShadowIfNeeded(canvas);
+        drawLegacyNavigationBarBackground(canvas);
     }
 
     private void initResizingPaints() {
@@ -2307,6 +2349,18 @@
         canvas.restore();
     }
 
+    private void drawLegacyNavigationBarBackground(RecordingCanvas canvas) {
+        if (!mDrawLegacyNavigationBarBackground) {
+            return;
+        }
+        View v = mNavigationColorViewState.view;
+        if (v == null) {
+            return;
+        }
+        canvas.drawRect(v.getLeft(), v.getTop(), v.getRight(), v.getBottom(),
+                mLegacyNavigationBarBackgroundPaint);
+    }
+
     /** Release the renderer thread which is usually done when the user stops resizing. */
     private void releaseThreadedRenderer() {
         if (mResizingBackgroundDrawable != null && mLastBackgroundDrawableCb != null) {
@@ -2593,6 +2647,7 @@
                                         }
                                         lastActionModeView.killMode();
                                         mFadeAnim = null;
+                                        requestApplyInsets();
                                     }
                                 }
 
diff --git a/core/java/com/android/internal/util/ArrayUtils.java b/core/java/com/android/internal/util/ArrayUtils.java
index e8691fa..b73ecd1 100644
--- a/core/java/com/android/internal/util/ArrayUtils.java
+++ b/core/java/com/android/internal/util/ArrayUtils.java
@@ -756,4 +756,8 @@
             return String.valueOf(value);
         }
     }
+
+    public static @Nullable <T> T firstOrNull(T[] items) {
+        return items.length > 0 ? items[0] : null;
+    }
 }
diff --git a/core/java/com/android/internal/util/function/pooled/PooledLambdaImpl.java b/core/java/com/android/internal/util/function/pooled/PooledLambdaImpl.java
index 6be626a..1bbd87c 100755
--- a/core/java/com/android/internal/util/function/pooled/PooledLambdaImpl.java
+++ b/core/java/com/android/internal/util/function/pooled/PooledLambdaImpl.java
@@ -24,6 +24,7 @@
 
 import com.android.internal.util.ArrayUtils;
 import com.android.internal.util.BitUtils;
+import com.android.internal.util.Preconditions;
 import com.android.internal.util.function.HeptConsumer;
 import com.android.internal.util.function.HeptFunction;
 import com.android.internal.util.function.HeptPredicate;
@@ -47,6 +48,7 @@
 import com.android.internal.util.function.TriPredicate;
 
 import java.util.Arrays;
+import java.util.Objects;
 import java.util.function.BiConsumer;
 import java.util.function.BiFunction;
 import java.util.function.BiPredicate;
@@ -432,13 +434,15 @@
         if (isConstSupplier()) {
             sb.append(getFuncTypeAsString()).append("(").append(doInvoke()).append(")");
         } else {
-            if (mFunc instanceof PooledLambdaImpl) {
-                sb.append(mFunc);
+            Object func = mFunc;
+            if (func instanceof PooledLambdaImpl) {
+                sb.append(func);
             } else {
-                sb.append(getFuncTypeAsString()).append("@").append(hashCodeHex(mFunc));
+                sb.append(getFuncTypeAsString()).append("@").append(hashCodeHex(func));
             }
             sb.append("(");
-            sb.append(commaSeparateFirstN(mArgs, LambdaType.decodeArgCount(getFlags(MASK_FUNC_TYPE))));
+            sb.append(commaSeparateFirstN(mArgs,
+                    LambdaType.decodeArgCount(getFlags(MASK_FUNC_TYPE))));
             sb.append(")");
         }
         return sb.toString();
@@ -450,7 +454,7 @@
     }
 
     private static String hashCodeHex(Object o) {
-        return Integer.toHexString(o.hashCode());
+        return Integer.toHexString(Objects.hashCode(o));
     }
 
     private String getFuncTypeAsString() {
@@ -490,7 +494,7 @@
                             + ", i = " + i
                             + ")");
         }
-        r.mFunc = func;
+        r.mFunc = Preconditions.checkNotNull(func);
         r.setFlags(MASK_FUNC_TYPE, LambdaType.encode(fNumArgs, fReturnType));
         r.setFlags(MASK_EXPOSED_AS, LambdaType.encode(numPlaceholders, fReturnType));
         if (ArrayUtils.size(r.mArgs) < fNumArgs) r.mArgs = new Object[fNumArgs];
diff --git a/core/java/com/android/internal/widget/LockPatternUtils.java b/core/java/com/android/internal/widget/LockPatternUtils.java
index 07f8ee0..dc45f78 100644
--- a/core/java/com/android/internal/widget/LockPatternUtils.java
+++ b/core/java/com/android/internal/widget/LockPatternUtils.java
@@ -886,13 +886,13 @@
             return;
         }
 
+        // TODO(b/120484642): This is a location where we still use a String for vold
+        String passwordString = password != null ? new String(password) : null;
         new AsyncTask<Void, Void, Void>() {
             @Override
             protected Void doInBackground(Void... dummy) {
                 IStorageManager storageManager = IStorageManager.Stub.asInterface(service);
                 try {
-                    // TODO(b/120484642): This is a location where we still use a String for vold
-                    String passwordString = password != null ? new String(password) : null;
                     storageManager.changeEncryptionPassword(type, passwordString);
                 } catch (RemoteException e) {
                     Log.e(TAG, "Error changing encryption password", e);
diff --git a/core/jni/AndroidRuntime.cpp b/core/jni/AndroidRuntime.cpp
index f266502..cd0b340 100644
--- a/core/jni/AndroidRuntime.cpp
+++ b/core/jni/AndroidRuntime.cpp
@@ -250,6 +250,11 @@
 // Flag to pass to the runtime when using the apex image.
 static const char* kApexImageOption = "-Ximage:/system/framework/apex.art";
 
+// Feature flag name for disabling lock profiling.
+static const char* DISABLE_LOCK_PROFILING = "disable_lock_profiling";
+// Runtime option disabling lock profiling.
+static const char* kLockProfThresholdRuntimeOption = "-Xlockprofthreshold:0";
+
 static AndroidRuntime* gCurRuntime = NULL;
 
 /*
@@ -698,6 +703,17 @@
         ALOGI("Using default boot image");
     }
 
+    std::string disable_lock_profiling =
+        server_configurable_flags::GetServerConfigurableFlag(RUNTIME_NATIVE_BOOT_NAMESPACE,
+                                                             DISABLE_LOCK_PROFILING,
+                                                             /*default_value=*/ "");
+    if (disable_lock_profiling == "true") {
+        addOption(kLockProfThresholdRuntimeOption);
+        ALOGI("Disabling lock profiling: '%s'\n", kLockProfThresholdRuntimeOption);
+    } else {
+        ALOGI("Leaving lock profiling enabled");
+    }
+
     bool checkJni = false;
     property_get("dalvik.vm.checkjni", propBuf, "");
     if (strcmp(propBuf, "true") == 0) {
diff --git a/core/jni/android_media_AudioSystem.cpp b/core/jni/android_media_AudioSystem.cpp
index fc2b7f6..686a919 100644
--- a/core/jni/android_media_AudioSystem.cpp
+++ b/core/jni/android_media_AudioSystem.cpp
@@ -2242,6 +2242,12 @@
     return AudioSystem::setAllowedCapturePolicy(uid, flags);
 }
 
+static jint
+android_media_AudioSystem_setRttEnabled(JNIEnv *env, jobject thiz, jboolean enabled)
+{
+    return (jint) check_AudioSystem_Command(AudioSystem::setRttEnabled(enabled));
+}
+
 // ----------------------------------------------------------------------------
 
 static const JNINativeMethod gMethods[] = {
@@ -2319,6 +2325,7 @@
     {"getHwOffloadEncodingFormatsSupportedForA2DP", "(Ljava/util/ArrayList;)I",
                     (void*)android_media_AudioSystem_getHwOffloadEncodingFormatsSupportedForA2DP},
     {"setAllowedCapturePolicy", "(II)I", (void *)android_media_AudioSystem_setAllowedCapturePolicy},
+    {"setRttEnabled",       "(Z)I",     (void *)android_media_AudioSystem_setRttEnabled},
 };
 
 static const JNINativeMethod gEventHandlerMethods[] = {
diff --git a/core/jni/android_os_Debug.cpp b/core/jni/android_os_Debug.cpp
index a67cb34..14dbabb 100644
--- a/core/jni/android_os_Debug.cpp
+++ b/core/jni/android_os_Debug.cpp
@@ -289,14 +289,14 @@
         } else if (base::EndsWith(name, ".oat")) {
             which_heap = HEAP_OAT;
             is_swappable = true;
-        } else if (base::EndsWith(name, ".art")) {
+        } else if (base::EndsWith(name, ".art") || base::EndsWith(name, ".art]")) {
             which_heap = HEAP_ART;
             // Handle system@framework@boot* and system/framework/boot*
             if ((strstr(name.c_str(), "@boot") != nullptr) ||
                     (strstr(name.c_str(), "/boot"))) {
-                sub_heap = HEAP_DEX_BOOT_VDEX;
+                sub_heap = HEAP_ART_BOOT;
             } else {
-                sub_heap = HEAP_DEX_APP_VDEX;
+                sub_heap = HEAP_ART_APP;
             }
             is_swappable = true;
         } else if (base::StartsWith(name, "/dev/")) {
@@ -713,16 +713,20 @@
                                      O_CREAT | O_WRONLY | O_NOFOLLOW | O_CLOEXEC | O_APPEND,
                                      0666));
     if (fd < 0) {
-        fprintf(stderr, "Can't open %s: %s\n", fileNameChars.c_str(), strerror(errno));
+        PLOG(ERROR) << "Can't open " << fileNameChars.c_str();
         return false;
     }
 
-    return (dump_backtrace_to_file_timeout(pid, dumpType, timeoutSecs, fd) == 0);
+    int res = dump_backtrace_to_file_timeout(pid, dumpType, timeoutSecs, fd);
+    if (fdatasync(fd.get()) != 0) {
+        PLOG(ERROR) << "Failed flushing trace.";
+    }
+    return res == 0;
 }
 
 static jboolean android_os_Debug_dumpJavaBacktraceToFileTimeout(JNIEnv* env, jobject clazz,
         jint pid, jstring fileName, jint timeoutSecs) {
-    const bool ret =  dumpTraces(env, pid, fileName, timeoutSecs, kDebuggerdJavaBacktrace);
+    const bool ret = dumpTraces(env, pid, fileName, timeoutSecs, kDebuggerdJavaBacktrace);
     return ret ? JNI_TRUE : JNI_FALSE;
 }
 
diff --git a/core/jni/android_os_Trace.cpp b/core/jni/android_os_Trace.cpp
index 81428dc..bd82bd9 100644
--- a/core/jni/android_os_Trace.cpp
+++ b/core/jni/android_os_Trace.cpp
@@ -24,26 +24,29 @@
 
 namespace android {
 
-inline static void sanitizeString(char* str, size_t size) {
-    for (size_t i = 0; i < size; i++) {
-        char c = str[i];
-        if (c == '\0' || c == '\n' || c == '|') {
-            str[i] = ' ';
+inline static void sanitizeString(char* str) {
+    while (*str) {
+        char c = *str;
+        if (c == '\n' || c == '|') {
+            *str = ' ';
         }
+        str++;
     }
 }
 
-inline static void getString(JNIEnv* env, jstring jstring, char* outBuffer, jsize maxSize) {
-    jsize size = std::min(env->GetStringLength(jstring), maxSize);
-    env->GetStringUTFRegion(jstring, 0, size, outBuffer);
-    sanitizeString(outBuffer, size);
-    outBuffer[size] = '\0';
-}
-
 template<typename F>
 inline static void withString(JNIEnv* env, jstring jstr, F callback) {
-    std::array<char, 1024> buffer;
-    getString(env, jstr, buffer.data(), buffer.size());
+    // We need to handle the worst case of 1 character -> 4 bytes
+    // So make a buffer of size 4097 and let it hold a string with a maximum length
+    // of 1024. The extra last byte for the null terminator.
+    std::array<char, 4097> buffer;
+    // We have no idea of knowing how much data GetStringUTFRegion wrote, so null it out in
+    // advance so we can have a reliable null terminator
+    memset(buffer.data(), 0, buffer.size());
+    jsize size = std::min(env->GetStringLength(jstr), 1024);
+    env->GetStringUTFRegion(jstr, 0, size, buffer.data());
+    sanitizeString(buffer.data());
+
     callback(buffer.data());
 }
 
diff --git a/core/jni/com_android_internal_os_Zygote.cpp b/core/jni/com_android_internal_os_Zygote.cpp
index 8ff1691..4783a25 100644
--- a/core/jni/com_android_internal_os_Zygote.cpp
+++ b/core/jni/com_android_internal_os_Zygote.cpp
@@ -198,7 +198,7 @@
    * PIDs don't match nothing will happen.
    *
    * @param pid The ID of the process who's entry we want to clear.
-   * @return True if the entry was cleared; false otherwise
+   * @return True if the entry was cleared by this call; false otherwise
    */
   bool ClearForPID(int32_t pid) {
     EntryStorage storage = mStorage.load();
@@ -212,14 +212,16 @@
        *   3) It fails and the new value isn't INVALID_ENTRY_VALUE, in which
        *      case the entry has already been cleared and re-used.
        *
-       * In all three cases the goal of the caller has been met and we can
-       * return true.
+       * In all three cases the goal of the caller has been met, but only in
+       * the first case do we need to decrement the pool count.
        */
       if (mStorage.compare_exchange_strong(storage, INVALID_ENTRY_VALUE)) {
         close(storage.read_pipe_fd);
+        return true;
+      } else {
+        return false;
       }
 
-      return true;
     } else {
       return false;
     }
@@ -331,11 +333,24 @@
     if (WIFEXITED(status)) {
       async_safe_format_log(ANDROID_LOG_INFO, LOG_TAG,
                             "Process %d exited cleanly (%d)", pid, WEXITSTATUS(status));
+
+      // Check to see if the PID is in the USAP pool and remove it if it is.
+      if (RemoveUsapTableEntry(pid)) {
+        ++usaps_removed;
+      }
     } else if (WIFSIGNALED(status)) {
       async_safe_format_log(ANDROID_LOG_INFO, LOG_TAG,
                             "Process %d exited due to signal %d (%s)%s", pid,
                             WTERMSIG(status), strsignal(WTERMSIG(status)),
                             WCOREDUMP(status) ? "; core dumped" : "");
+
+      // If the process exited due to a signal other than SIGTERM, check to see
+      // if the PID is in the USAP pool and remove it if it is.  If the process
+      // was closed by the Zygote using SIGTERM then the USAP pool entry will
+      // have already been removed (see nativeEmptyUsapPool()).
+      if (WTERMSIG(status) != SIGTERM && RemoveUsapTableEntry(pid)) {
+        ++usaps_removed;
+      }
     }
 
     // If the just-crashed process is the system_server, bring down zygote
@@ -346,11 +361,6 @@
                             "Exit zygote because system server (pid %d) has terminated", pid);
       kill(getpid(), SIGKILL);
     }
-
-    // Check to see if the PID is in the USAP pool and remove it if it is.
-    if (RemoveUsapTableEntry(pid)) {
-      ++usaps_removed;
-    }
   }
 
   // Note that we shouldn't consider ECHILD an error because
@@ -1648,7 +1658,13 @@
     auto entry_storage = entry.GetValues();
 
     if (entry_storage.has_value()) {
-      kill(entry_storage.value().pid, SIGKILL);
+      kill(entry_storage.value().pid, SIGTERM);
+
+      // Clean up the USAP table entry here.  This avoids a potential race
+      // where a newly created USAP might not be able to find a valid table
+      // entry if signal handler (which would normally do the cleanup) doesn't
+      // run between now and when the new process is created.
+
       close(entry_storage.value().read_pipe_fd);
 
       // Avoid a second atomic load by invalidating instead of clearing.
@@ -1678,6 +1694,16 @@
   return dl_iterate_phdr(disable_execute_only, nullptr) == 0;
 }
 
+static void com_android_internal_os_Zygote_nativeBlockSigTerm(JNIEnv* env, jclass) {
+  auto fail_fn = std::bind(ZygoteFailure, env, "usap", nullptr, _1);
+  BlockSignal(SIGTERM, fail_fn);
+}
+
+static void com_android_internal_os_Zygote_nativeUnblockSigTerm(JNIEnv* env, jclass) {
+  auto fail_fn = std::bind(ZygoteFailure, env, "usap", nullptr, _1);
+  UnblockSignal(SIGTERM, fail_fn);
+}
+
 static const JNINativeMethod gMethods[] = {
     { "nativeForkAndSpecialize",
       "(II[II[[IILjava/lang/String;Ljava/lang/String;[I[IZLjava/lang/String;Ljava/lang/String;)I",
@@ -1708,7 +1734,11 @@
     { "nativeEmptyUsapPool", "()V",
       (void *) com_android_internal_os_Zygote_nativeEmptyUsapPool },
     { "nativeDisableExecuteOnly", "()Z",
-      (void *) com_android_internal_os_Zygote_nativeDisableExecuteOnly }
+      (void *) com_android_internal_os_Zygote_nativeDisableExecuteOnly },
+    { "nativeBlockSigTerm", "()V",
+      (void* ) com_android_internal_os_Zygote_nativeBlockSigTerm },
+    { "nativeUnblockSigTerm", "()V",
+      (void* ) com_android_internal_os_Zygote_nativeUnblockSigTerm }
 };
 
 int register_com_android_internal_os_Zygote(JNIEnv* env) {
diff --git a/core/proto/android/os/incident.proto b/core/proto/android/os/incident.proto
index 9a9c9d1..7d0629e 100644
--- a/core/proto/android/os/incident.proto
+++ b/core/proto/android/os/incident.proto
@@ -321,6 +321,14 @@
         (section).args = "incidentcompanion --restricted_image"
     ];
 
+    // System trace as a serialized protobuf.
+    optional bytes system_trace = 3026 [
+        (section).type = SECTION_FILE,
+        (section).args = "/data/misc/perfetto-traces/incident-trace",
+        (privacy).dest = DEST_AUTOMATIC,
+        (section).userdebug_and_eng_only = true
+    ];
+
     // Reserved for OEMs.
     extensions 50000 to 100000;
 }
diff --git a/core/proto/android/providers/settings/global.proto b/core/proto/android/providers/settings/global.proto
index 8f16b41..0070694 100644
--- a/core/proto/android/providers/settings/global.proto
+++ b/core/proto/android/providers/settings/global.proto
@@ -457,6 +457,9 @@
         optional SettingProto game_driver_sphal_libraries = 16;
         // ANGLE - External package containing ANGLE libraries
         optional SettingProto angle_debug_package = 17;
+        // Game Driver - List of Apps selected to use prerelease Game Driver
+        // i.e. <pkg1>,<pkg2>,...,<pkgN>
+        optional SettingProto game_driver_prerelease_opt_in_apps = 18;
     }
     optional Gpu gpu = 59;
 
diff --git a/core/res/res/layout/accessibility_button_chooser.xml b/core/res/res/layout/accessibility_button_chooser.xml
index 480defb..383780a 100644
--- a/core/res/res/layout/accessibility_button_chooser.xml
+++ b/core/res/res/layout/accessibility_button_chooser.xml
@@ -40,6 +40,7 @@
             android:layout_width="match_parent"
             android:layout_height="wrap_content"
             android:minHeight="56dp"
+            android:id="@+id/accessibility_button_prompt_prologue"
             android:textAppearance="?attr/textAppearanceMedium"
             android:text="@string/accessibility_button_prompt_text"
             android:gravity="start|center_vertical"
diff --git a/core/res/res/values-af/strings.xml b/core/res/res/values-af/strings.xml
index 7ee1f2a..e849da3 100644
--- a/core/res/res/values-af/strings.xml
+++ b/core/res/res/values-af/strings.xml
@@ -131,6 +131,7 @@
     <!-- no translation found for wfcSpnFormat_spn (4998685024207291232) -->
     <skip />
     <string name="wfcSpnFormat_spn_wifi_calling" msgid="136001023263502280">"<xliff:g id="SPN">%s</xliff:g>-Wi-Fi-oproepe"</string>
+    <string name="wfcSpnFormat_spn_wifi_calling_vo_hyphen" msgid="1730997175789582756">"<xliff:g id="SPN">%s</xliff:g>-Wi-Fi-oproepe"</string>
     <string name="wfcSpnFormat_wlan_call" msgid="2533371081782489793">"WLAN-oproep"</string>
     <string name="wfcSpnFormat_spn_wlan_call" msgid="2315240198303197168">"<xliff:g id="SPN">%s</xliff:g>-WLAN-oproep"</string>
     <string name="wfcSpnFormat_spn_wifi" msgid="6546481665561961938">"<xliff:g id="SPN">%s</xliff:g>-Wi-Fi"</string>
@@ -1611,8 +1612,6 @@
     <string name="display_manager_overlay_display_name" msgid="5142365982271620716">"Oorlegger #<xliff:g id="ID">%1$d</xliff:g>"</string>
     <string name="display_manager_overlay_display_title" msgid="652124517672257172">"<xliff:g id="NAME">%1$s</xliff:g>: <xliff:g id="WIDTH">%2$d</xliff:g>x<xliff:g id="HEIGHT">%3$d</xliff:g>, <xliff:g id="DPI">%4$d</xliff:g> dpi"</string>
     <string name="display_manager_overlay_display_secure_suffix" msgid="6022119702628572080">", veilig"</string>
-    <string name="activity_starter_block_bg_activity_starts_permissive" msgid="6995473033438879646">"Hierdie begin van agtergrondaktiwiteit vanaf <xliff:g id="PACKAGENAME">%1$s</xliff:g> sal in toekomstige Q-bouweergawes geblokkeer word. Sien g.co/dev/bgblock."</string>
-    <string name="activity_starter_block_bg_activity_starts_enforcing" msgid="3317816771072146229">"Begin van agtergrondaktiwiteit vanaf <xliff:g id="PACKAGENAME">%1$s</xliff:g> word geblokkeer. Sien g.co/dev/bgblock."</string>
     <string name="kg_forgot_pattern_button_text" msgid="8852021467868220608">"Het jy die patroon vergeet?"</string>
     <string name="kg_wrong_pattern" msgid="1850806070801358830">"Verkeerde patroon"</string>
     <string name="kg_wrong_password" msgid="2333281762128113157">"Verkeerde wagwoord"</string>
@@ -1666,8 +1665,12 @@
     <string name="accessibility_shortcut_enabling_service" msgid="7771852911861522636">"Toeganklikheidskortpad het <xliff:g id="SERVICE_NAME">%1$s</xliff:g> aangeskakel"</string>
     <string name="accessibility_shortcut_disabling_service" msgid="2747243438223109821">"Toeganklikheidskortpad het <xliff:g id="SERVICE_NAME">%1$s</xliff:g> afgeskakel"</string>
     <string name="accessibility_shortcut_spoken_feedback" msgid="8376923232350078434">"Druk en hou albei volumesleutels drie sekondes lank om <xliff:g id="SERVICE_NAME">%1$s</xliff:g> te gebruik"</string>
-    <string name="accessibility_button_prompt_text" msgid="4234556536456854251">"Kies \'n kenmerk om te gebruik wanneer jy op die Toeganklikheid-knoppie tik:"</string>
-    <string name="accessibility_button_instructional_text" msgid="6942300463612999993">"Raak en hou die Toeganklikheid-knoppie om kenmerke te verander."</string>
+    <string name="accessibility_button_prompt_text" msgid="1176658502969738564">"Kies \'n diens om te gebruik wanneer jy op die toeganklikheidknoppie tik:"</string>
+    <string name="accessibility_gesture_prompt_text" msgid="8259145549733019401">"Kies \'n diens om te gebruik saam met die toeganklikheidgebaar (swiep met twee vingers op van die onderkant van die skerm af):"</string>
+    <string name="accessibility_gesture_3finger_prompt_text" msgid="1041435574275047665">"Kies \'n diens om te gebruik saam met die toeganklikheidgebaar (swiep met drie vingers op van die onderkant van die skerm af):"</string>
+    <string name="accessibility_button_instructional_text" msgid="7003212763213614833">"Raak en hou die toeganklikheidknoppie om tussen dienste te wissel."</string>
+    <string name="accessibility_gesture_instructional_text" msgid="5261788874937410950">"Swiep op met twee vingers en hou om tussen dienste te wissel."</string>
+    <string name="accessibility_gesture_3finger_instructional_text" msgid="4969448938984394550">"Swiep op met drie vingers en hou om tussen dienste te wissel."</string>
     <string name="accessibility_magnification_chooser_text" msgid="1227146738764986237">"Vergroting"</string>
     <string name="user_switched" msgid="3768006783166984410">"Huidige gebruiker <xliff:g id="NAME">%1$s</xliff:g> ."</string>
     <string name="user_switching_message" msgid="2871009331809089783">"Skakel tans oor na <xliff:g id="NAME">%1$s</xliff:g> …"</string>
diff --git a/core/res/res/values-am/strings.xml b/core/res/res/values-am/strings.xml
index ebd79b2..ce70f27 100644
--- a/core/res/res/values-am/strings.xml
+++ b/core/res/res/values-am/strings.xml
@@ -131,6 +131,7 @@
     <!-- no translation found for wfcSpnFormat_spn (4998685024207291232) -->
     <skip />
     <string name="wfcSpnFormat_spn_wifi_calling" msgid="136001023263502280">"<xliff:g id="SPN">%s</xliff:g> የWi-Fi ጥሪ አደራረግ"</string>
+    <string name="wfcSpnFormat_spn_wifi_calling_vo_hyphen" msgid="1730997175789582756">"<xliff:g id="SPN">%s</xliff:g> የWi-Fi ጥሪ"</string>
     <string name="wfcSpnFormat_wlan_call" msgid="2533371081782489793">"የWLAN ጥሪ"</string>
     <string name="wfcSpnFormat_spn_wlan_call" msgid="2315240198303197168">"<xliff:g id="SPN">%s</xliff:g> የWLAN ጥሪ"</string>
     <string name="wfcSpnFormat_spn_wifi" msgid="6546481665561961938">"<xliff:g id="SPN">%s</xliff:g> Wi-Fi"</string>
@@ -1357,8 +1358,7 @@
     <string name="test_harness_mode_notification_message" msgid="1343197173054407119">"የመሞከሪያ ጥቅል ሁነታን ለማሰናከል የፋብሪካ ዳግም ቅንብርን ይሞክሩ።"</string>
     <string name="usb_contaminant_detected_title" msgid="7136400633704058349">"በዩኤስቢ ወደብ ውስጥ ፈሳሽ ወይም ፍርስራሽ"</string>
     <string name="usb_contaminant_detected_message" msgid="832337061059487250">"የዩኤስቢ ወደብ በራስ-ሰር ተሰናክሏል። የበለጠ ለመረዳት መታ ያድርጉ።"</string>
-    <!-- no translation found for usb_contaminant_not_detected_title (7708281124088684821) -->
-    <skip />
+    <string name="usb_contaminant_not_detected_title" msgid="7708281124088684821">"የዩኤስቢ ወደቡን መጠቀም ችግር የለውም"</string>
     <string name="usb_contaminant_not_detected_message" msgid="2415791798244545292">"ስልክ ከእንግዲህ ፈሳሽ ወይም ፍርስራሽ አላገኘም።"</string>
     <string name="taking_remote_bugreport_notification_title" msgid="6742483073875060934">"የሳንካ ሪፖርትን በመውሰድ ላይ…"</string>
     <string name="share_remote_bugreport_notification_title" msgid="4987095013583691873">"የሳንካ ሪፖርት ይጋራ?"</string>
@@ -1494,7 +1494,7 @@
     <string name="find_next" msgid="5742124618942193978">"ቀጣዩን አግኝ"</string>
     <string name="find_previous" msgid="2196723669388360506">"ቀዳሚውን አግኝ"</string>
     <string name="gpsNotifTicker" msgid="5622683912616496172">"የስፍራ ጥየቃ ቅፅ<xliff:g id="NAME">%s</xliff:g>"</string>
-    <string name="gpsNotifTitle" msgid="5446858717157416839">"የስፍራ ጥየቃ"</string>
+    <string name="gpsNotifTitle" msgid="5446858717157416839">"የአካባቢ ጥየቃ"</string>
     <string name="gpsNotifMessage" msgid="1374718023224000702">" በ፡<xliff:g id="NAME">%1$s</xliff:g>(<xliff:g id="SERVICE">%2$s</xliff:g>) ተጠየቀ"</string>
     <string name="gpsVerifYes" msgid="2346566072867213563">"አዎ"</string>
     <string name="gpsVerifNo" msgid="1146564937346454865">"አይ"</string>
@@ -1612,8 +1612,6 @@
     <string name="display_manager_overlay_display_name" msgid="5142365982271620716">"ተደራቢ #<xliff:g id="ID">%1$d</xliff:g>"</string>
     <string name="display_manager_overlay_display_title" msgid="652124517672257172">"<xliff:g id="NAME">%1$s</xliff:g>፦ <xliff:g id="WIDTH">%2$d</xliff:g>x<xliff:g id="HEIGHT">%3$d</xliff:g>፣ <xliff:g id="DPI">%4$d</xliff:g> dpi"</string>
     <string name="display_manager_overlay_display_secure_suffix" msgid="6022119702628572080">"፣ የተጠበቀ"</string>
-    <string name="activity_starter_block_bg_activity_starts_permissive" msgid="6995473033438879646">"ይህ የ<xliff:g id="PACKAGENAME">%1$s</xliff:g> የበስተጀርባ እንቅስቃሴ ጅምር በወደፊት የQ ግንቦች ላይ ይታገዳል። g.co/dev/bgblock ይመልከቱ።"</string>
-    <string name="activity_starter_block_bg_activity_starts_enforcing" msgid="3317816771072146229">"የ<xliff:g id="PACKAGENAME">%1$s</xliff:g> የበስተጀርባ እንቅስቃሴ ጅምር ታግዷል። g.co/dev/bgblock ይመልከቱ።"</string>
     <string name="kg_forgot_pattern_button_text" msgid="8852021467868220608">"ስርዓተ ጥለቱን እርሳ"</string>
     <string name="kg_wrong_pattern" msgid="1850806070801358830">"የተሳሳተ ስርዓተ ጥለት"</string>
     <string name="kg_wrong_password" msgid="2333281762128113157">"የተሳሳተ ይለፍ ቃል"</string>
@@ -1667,8 +1665,12 @@
     <string name="accessibility_shortcut_enabling_service" msgid="7771852911861522636">"የተደራሽነት አቋራጭ <xliff:g id="SERVICE_NAME">%1$s</xliff:g>ን አብርቶታል"</string>
     <string name="accessibility_shortcut_disabling_service" msgid="2747243438223109821">"የተደራሽነት አቋራጭ <xliff:g id="SERVICE_NAME">%1$s</xliff:g>ን አጥፍቶታል"</string>
     <string name="accessibility_shortcut_spoken_feedback" msgid="8376923232350078434">"<xliff:g id="SERVICE_NAME">%1$s</xliff:g>ን ለመጠቀም ለሦስት ሰከንዶች ሁለቱንም የድምፅ ቁልፎች ተጭነው ይያዙ"</string>
-    <string name="accessibility_button_prompt_text" msgid="4234556536456854251">"የተደራሽነት አዝራርን መታ በሚያደርጉበት ጊዜ ጥቅም ላይ የሚውለውን ባህሪ ይምረጡ፦"</string>
-    <string name="accessibility_button_instructional_text" msgid="6942300463612999993">"ባህሪያትን ለመለወጥ የተደራሽነት አዝራሩን ይንኩ እና ይያዙት።"</string>
+    <string name="accessibility_button_prompt_text" msgid="1176658502969738564">"የተደራሽነት አዝራርን መታ በሚያደርጉበት ጊዜ ጥቅም ላይ የሚውለውን አገልግሎት ይምረጡ፦"</string>
+    <string name="accessibility_gesture_prompt_text" msgid="8259145549733019401">"ከተደራሽነት ጣት ምልክት ጋር የሚጠቀሙበት አአገልግሎት ይምረጡ (በሁለት ጣቶች ከማያ ገጹ ግርጌ ወደ ላይ ይጥረጉ)፦"</string>
+    <string name="accessibility_gesture_3finger_prompt_text" msgid="1041435574275047665">"ከተደራሽነት ጣት ምልክት ጋር አብረው የሚጠቀሙበት አገልግሎት ይምረጡ (በሶስት ጣቶች ከማያ ገጹ ግርጌ ወደ ላይ ይጥረጉ)፦"</string>
+    <string name="accessibility_button_instructional_text" msgid="7003212763213614833">"በአገልግሎቶች መካከል ለመቀያየር የተደራሽነት አዝራሩን ነክተው ይያዙ።"</string>
+    <string name="accessibility_gesture_instructional_text" msgid="5261788874937410950">"በአገልግሎቶች መካከል ለመቀያየር በሁለት ጣቶች ወደ ላይ ጠርገው ይያዙ።"</string>
+    <string name="accessibility_gesture_3finger_instructional_text" msgid="4969448938984394550">"በአገልግሎቶች መካከል ለመቀያየር በሶስት ጣቶች ወደ ላይ ጠርገው ይያዙ።"</string>
     <string name="accessibility_magnification_chooser_text" msgid="1227146738764986237">"ማጉላት"</string>
     <string name="user_switched" msgid="3768006783166984410">"የአሁኑ ተጠቃሚ <xliff:g id="NAME">%1$s</xliff:g>።"</string>
     <string name="user_switching_message" msgid="2871009331809089783">"ወደ <xliff:g id="NAME">%1$s</xliff:g> በመቀየር ላይ…"</string>
diff --git a/core/res/res/values-ar/strings.xml b/core/res/res/values-ar/strings.xml
index 99f3747..3149c2d 100644
--- a/core/res/res/values-ar/strings.xml
+++ b/core/res/res/values-ar/strings.xml
@@ -135,6 +135,7 @@
     <!-- no translation found for wfcSpnFormat_spn (4998685024207291232) -->
     <skip />
     <string name="wfcSpnFormat_spn_wifi_calling" msgid="136001023263502280">"‏الاتصال عبر شبكة Wi-Fi التابعة لـ <xliff:g id="SPN">%s</xliff:g>"</string>
+    <string name="wfcSpnFormat_spn_wifi_calling_vo_hyphen" msgid="1730997175789582756">"‏الاتصال عبر Wi-Fi ضمن شبكة <xliff:g id="SPN">%s</xliff:g>"</string>
     <string name="wfcSpnFormat_wlan_call" msgid="2533371081782489793">"‏مكالمة عبر شبكة WLAN"</string>
     <string name="wfcSpnFormat_spn_wlan_call" msgid="2315240198303197168">"‏مكالمة عبر شبكة WLAN التابعة لـ <xliff:g id="SPN">%s</xliff:g>"</string>
     <string name="wfcSpnFormat_spn_wifi" msgid="6546481665561961938">"‏شبكة Wi-Fi التابعة لـ <xliff:g id="SPN">%s</xliff:g>"</string>
@@ -700,7 +701,7 @@
     <item msgid="1103601433382158155">"فاكس العمل"</item>
     <item msgid="1735177144948329370">"فاكس المنزل"</item>
     <item msgid="603878674477207394">"جهاز نداء"</item>
-    <item msgid="1650824275177931637">"آخر"</item>
+    <item msgid="1650824275177931637">"غير ذلك"</item>
     <item msgid="9192514806975898961">"مخصص"</item>
   </string-array>
   <string-array name="emailAddressTypes">
@@ -1201,7 +1202,7 @@
     <string name="no" msgid="5141531044935541497">"إلغاء"</string>
     <string name="dialog_alert_title" msgid="2049658708609043103">"تنبيه"</string>
     <string name="loading" msgid="7933681260296021180">"جارٍ التحميل…"</string>
-    <string name="capital_on" msgid="1544682755514494298">"تشغيل"</string>
+    <string name="capital_on" msgid="1544682755514494298">"مفعّلة"</string>
     <string name="capital_off" msgid="6815870386972805832">"إيقاف"</string>
     <string name="whichApplication" msgid="4533185947064773386">"إكمال الإجراء باستخدام"</string>
     <string name="whichApplicationNamed" msgid="8260158865936942783">"‏إكمال الإجراء باستخدام %1$s"</string>
@@ -1445,8 +1446,7 @@
     <string name="test_harness_mode_notification_message" msgid="1343197173054407119">"يمكنك إجراء إعادة ضبط على إعدادات المصنع لإيقاف وضع \"مفعِّل اختبار\"."</string>
     <string name="usb_contaminant_detected_title" msgid="7136400633704058349">"‏السوائل والشوائب في منفذ USB"</string>
     <string name="usb_contaminant_detected_message" msgid="832337061059487250">"‏تمّ إيقاف منفذ USB تلقائيًا. انقُر لمعرفة المزيد من المعلومات."</string>
-    <!-- no translation found for usb_contaminant_not_detected_title (7708281124088684821) -->
-    <skip />
+    <string name="usb_contaminant_not_detected_title" msgid="7708281124088684821">"‏مسموح باستخدام منفذ USB"</string>
     <string name="usb_contaminant_not_detected_message" msgid="2415791798244545292">"لم يَعُد الهاتف يكتشف سوائل أو شوائب."</string>
     <string name="taking_remote_bugreport_notification_title" msgid="6742483073875060934">"جارٍ الحصول على تقرير الخطأ…"</string>
     <string name="share_remote_bugreport_notification_title" msgid="4987095013583691873">"هل تريد مشاركة تقرير الخطأ؟"</string>
@@ -1586,7 +1586,7 @@
     <string name="find_next" msgid="5742124618942193978">"بحث عن التطابق التالي"</string>
     <string name="find_previous" msgid="2196723669388360506">"بحث عن التطابق السابق"</string>
     <string name="gpsNotifTicker" msgid="5622683912616496172">"طلب الموقع من <xliff:g id="NAME">%s</xliff:g>"</string>
-    <string name="gpsNotifTitle" msgid="5446858717157416839">"طلب الموقع"</string>
+    <string name="gpsNotifTitle" msgid="5446858717157416839">"طلب الموقع الجغرافي"</string>
     <string name="gpsNotifMessage" msgid="1374718023224000702">"مطلوب من <xliff:g id="NAME">%1$s</xliff:g> (<xliff:g id="SERVICE">%2$s</xliff:g>)"</string>
     <string name="gpsVerifYes" msgid="2346566072867213563">"نعم"</string>
     <string name="gpsVerifNo" msgid="1146564937346454865">"لا"</string>
@@ -1704,8 +1704,6 @@
     <string name="display_manager_overlay_display_name" msgid="5142365982271620716">"المركب #<xliff:g id="ID">%1$d</xliff:g>"</string>
     <string name="display_manager_overlay_display_title" msgid="652124517672257172">"‏<xliff:g id="NAME">%1$s</xliff:g>: <xliff:g id="WIDTH">%2$d</xliff:g>x<xliff:g id="HEIGHT">%3$d</xliff:g>، <xliff:g id="DPI">%4$d</xliff:g> نقطة لكل بوصة"</string>
     <string name="display_manager_overlay_display_secure_suffix" msgid="6022119702628572080">"آمن"</string>
-    <string name="activity_starter_block_bg_activity_starts_permissive" msgid="6995473033438879646">"‏سيتم حظر بدء نشاط الخلفية هذا من <xliff:g id="PACKAGENAME">%1$s</xliff:g> في إصدارات Q القادمة. اطّلع على g.co/dev/bgblock."</string>
-    <string name="activity_starter_block_bg_activity_starts_enforcing" msgid="3317816771072146229">"‏تم حظر بدء نشاط الخلفية من <xliff:g id="PACKAGENAME">%1$s</xliff:g>. اطّلع على g.co/dev/bgblock."</string>
     <string name="kg_forgot_pattern_button_text" msgid="8852021467868220608">"نسيت النقش"</string>
     <string name="kg_wrong_pattern" msgid="1850806070801358830">"النقش غير صحيح"</string>
     <string name="kg_wrong_password" msgid="2333281762128113157">"كلمة مرور خاطئة"</string>
@@ -1763,8 +1761,12 @@
     <string name="accessibility_shortcut_enabling_service" msgid="7771852911861522636">"شغَّل اختصار إمكانية الوصول خدمة <xliff:g id="SERVICE_NAME">%1$s</xliff:g>"</string>
     <string name="accessibility_shortcut_disabling_service" msgid="2747243438223109821">"أوقف اختصار إمكانية الوصول خدمة <xliff:g id="SERVICE_NAME">%1$s</xliff:g>"</string>
     <string name="accessibility_shortcut_spoken_feedback" msgid="8376923232350078434">"اضغط مع الاستمرار على مفتاحي مستوى الصوت لمدة 3 ثوانٍ لاستخدام <xliff:g id="SERVICE_NAME">%1$s</xliff:g>."</string>
-    <string name="accessibility_button_prompt_text" msgid="4234556536456854251">"يمكنك اختيار إحدى الميزات لاستخدامها عند النقر على زر إمكانية الوصول:"</string>
-    <string name="accessibility_button_instructional_text" msgid="6942300463612999993">"لتغيير الميزات، يمكنك لمس زر \"إمكانية الوصول\" مع الاستمرار."</string>
+    <string name="accessibility_button_prompt_text" msgid="1176658502969738564">"يمكنك اختيار إحدى الخدمات لاستخدامها عند النقر على زر سهولة الاستخدام:"</string>
+    <string name="accessibility_gesture_prompt_text" msgid="8259145549733019401">"يمكنك اختيار إحدى الخدمات لاستخدامها مع إيماءة سهولة الاستخدام (مرّر سريعًا لأعلى من أسفل الشاشة باستخدام إصبعين):"</string>
+    <string name="accessibility_gesture_3finger_prompt_text" msgid="1041435574275047665">"يمكنك اختيار إحدى الخدمات لاستخدامها مع إيماءة سهولة الاستخدام (مرّر سريعًا لأعلى من أسفل الشاشة باستخدام ثلاثة أصابع):"</string>
+    <string name="accessibility_button_instructional_text" msgid="7003212763213614833">"للتبديل بين الخدمات، يمكنك لمس زر سهولة الاستخدام مع الاستمرار."</string>
+    <string name="accessibility_gesture_instructional_text" msgid="5261788874937410950">"للتبديل بين الخدمات، يمكنك التمرير سريعًا لأعلى باستخدام إصبعين مع الاستمرار."</string>
+    <string name="accessibility_gesture_3finger_instructional_text" msgid="4969448938984394550">"للتبديل بين الخدمات، يمكنك التمرير سريعًا لأعلى باستخدام ثلاثة أصابع مع الاستمرار."</string>
     <string name="accessibility_magnification_chooser_text" msgid="1227146738764986237">"التكبير"</string>
     <string name="user_switched" msgid="3768006783166984410">"المستخدم الحالي <xliff:g id="NAME">%1$s</xliff:g>."</string>
     <string name="user_switching_message" msgid="2871009331809089783">"جارٍ التبديل إلى <xliff:g id="NAME">%1$s</xliff:g>…"</string>
diff --git a/core/res/res/values-as/strings.xml b/core/res/res/values-as/strings.xml
index b44f052..df5c303 100644
--- a/core/res/res/values-as/strings.xml
+++ b/core/res/res/values-as/strings.xml
@@ -131,6 +131,8 @@
     <!-- no translation found for wfcSpnFormat_spn (4998685024207291232) -->
     <skip />
     <string name="wfcSpnFormat_spn_wifi_calling" msgid="136001023263502280">"<xliff:g id="SPN">%s</xliff:g> ৱাই- ফাই কলিং"</string>
+    <!-- no translation found for wfcSpnFormat_spn_wifi_calling_vo_hyphen (1730997175789582756) -->
+    <skip />
     <string name="wfcSpnFormat_wlan_call" msgid="2533371081782489793">"WLAN কল"</string>
     <string name="wfcSpnFormat_spn_wlan_call" msgid="2315240198303197168">"<xliff:g id="SPN">%s</xliff:g> WLAN কল"</string>
     <string name="wfcSpnFormat_spn_wifi" msgid="6546481665561961938">"<xliff:g id="SPN">%s</xliff:g> ৱাই-ফাই"</string>
@@ -1357,8 +1359,7 @@
     <string name="test_harness_mode_notification_message" msgid="1343197173054407119">"টেষ্ট হাৰনেছ ম’ড অক্ষম কৰিবলৈ ফেক্টৰী ৰিছেট কৰক।"</string>
     <string name="usb_contaminant_detected_title" msgid="7136400633704058349">"ইউএছবি প’ৰ্টত তৰল বা ধূলি-মাকতি আছে"</string>
     <string name="usb_contaminant_detected_message" msgid="832337061059487250">"ইউএছবি প’ৰ্ট স্বয়ংক্ৰিয়ভাৱে অক্ষম কৰা হয়। অধিক জানিবৰ বাবে টিপক।"</string>
-    <!-- no translation found for usb_contaminant_not_detected_title (7708281124088684821) -->
-    <skip />
+    <string name="usb_contaminant_not_detected_title" msgid="7708281124088684821">"ইউএছবি প’ৰ্ট ব্যৱহাৰ কৰাত সমস্যা নাই"</string>
     <string name="usb_contaminant_not_detected_message" msgid="2415791798244545292">"ফ’নটোৱে তৰল বা ধূলি-মাকতি আৰু চিনাক্ত নকৰে।"</string>
     <string name="taking_remote_bugreport_notification_title" msgid="6742483073875060934">"বাগ সম্পর্কীয় অভিযোগ গ্ৰহণ কৰি থকা হৈছে…"</string>
     <string name="share_remote_bugreport_notification_title" msgid="4987095013583691873">"বাগ সম্পর্কীয় অভিযোগ শ্বেয়াৰ কৰিবনে?"</string>
@@ -1612,8 +1613,6 @@
     <string name="display_manager_overlay_display_name" msgid="5142365982271620716">"অ\'ভাৰলে\' #<xliff:g id="ID">%1$d</xliff:g>"</string>
     <string name="display_manager_overlay_display_title" msgid="652124517672257172">"<xliff:g id="NAME">%1$s</xliff:g>: <xliff:g id="WIDTH">%2$d</xliff:g>x<xliff:g id="HEIGHT">%3$d</xliff:g>, <xliff:g id="DPI">%4$d</xliff:g> dpi"</string>
     <string name="display_manager_overlay_display_secure_suffix" msgid="6022119702628572080">", সুৰক্ষিত"</string>
-    <string name="activity_starter_block_bg_activity_starts_permissive" msgid="6995473033438879646">"<xliff:g id="PACKAGENAME">%1$s</xliff:g>ৰ পৰা নেপথ্যত আৰম্ভ হোৱা এই কাৰ্যকলাপটো ভৱিষ্যতে Q বিল্ডত অৱৰোধ কৰা হ’ব। g.co/dev/bgblock চাওক।"</string>
-    <string name="activity_starter_block_bg_activity_starts_enforcing" msgid="3317816771072146229">"<xliff:g id="PACKAGENAME">%1$s</xliff:g>ৰ পৰা নেপথ্যত আৰম্ভ হোৱা কাৰ্যকলাপ অৱৰোধ কৰা হৈছে। g.co/dev/bgblock চাওক।"</string>
     <string name="kg_forgot_pattern_button_text" msgid="8852021467868220608">"আৰ্হি পাহৰিলেনে"</string>
     <string name="kg_wrong_pattern" msgid="1850806070801358830">"ভুল আৰ্হি"</string>
     <string name="kg_wrong_password" msgid="2333281762128113157">"ভুল পাছৱৰ্ড"</string>
@@ -1667,8 +1666,12 @@
     <string name="accessibility_shortcut_enabling_service" msgid="7771852911861522636">"দিব্যাংগসকলৰ সুবিধাৰ শ্বৰ্টকাটটোৱে <xliff:g id="SERVICE_NAME">%1$s</xliff:g>ক অন কৰিছে"</string>
     <string name="accessibility_shortcut_disabling_service" msgid="2747243438223109821">"দিব্যাংগসকলৰ সুবিধাৰ শ্বৰ্টকাটটোৱে <xliff:g id="SERVICE_NAME">%1$s</xliff:g>ক অফ কৰিছে"</string>
     <string name="accessibility_shortcut_spoken_feedback" msgid="8376923232350078434">"<xliff:g id="SERVICE_NAME">%1$s</xliff:g> ব্যৱহাৰ কৰিবলৈ দুয়োটা ভলিউম বুটাম তিনি ছেকেণ্ডৰ বাবে হেঁচি ৰাখক"</string>
-    <string name="accessibility_button_prompt_text" msgid="4234556536456854251">"আপুনি দিব্যাংগসকলৰ সুবিধাৰ বুটামটো টিপিলে ব্যৱহাৰ কৰিবলগীয়া কোনো সুবিধা বাছক:"</string>
-    <string name="accessibility_button_instructional_text" msgid="6942300463612999993">"সুবিধাসমূহ সলনি কৰিবলৈ দিব্যাংগসকলৰ সুবিধাৰ বুটামটো স্পৰ্শ কৰি থাকক।"</string>
+    <string name="accessibility_button_prompt_text" msgid="1176658502969738564">"আপুনি সাধ্য সুবিধাৰ বুটামটো টিপিলে ব্যৱহাৰ কৰিবলৈ এটা সেৱা বাছনি কৰক:"</string>
+    <string name="accessibility_gesture_prompt_text" msgid="8259145549733019401">"সাধ্য সুবিধা ভংগিমাৰ সৈতে ব্যৱহাৰ কৰিবলৈ এটা সেৱা বাছনি কৰক (দুটা আঙুলিৰে স্ক্রীণখনৰ একেবাৰে তলিৰ পৰা ওপৰলৈ ছোৱাইপ কৰক):"</string>
+    <string name="accessibility_gesture_3finger_prompt_text" msgid="1041435574275047665">"সাধ্য সুবিধা ভংগিমাৰ সৈতে ব্যৱহাৰ কৰিবলৈ এটা সেৱা বাছনি কৰক (তিনিটা আঙুলিৰে স্ক্রীণখনৰ একেবাৰে তলিৰ পৰা ওপৰলৈ ছোৱাইপ কৰক):"</string>
+    <string name="accessibility_button_instructional_text" msgid="7003212763213614833">"সেৱাসমূহ সালসলনিকৈ ব্যৱহাৰ কৰিবলৈ সাধ্য সুবিধাৰ বুটামটো স্পৰ্শ কৰি ধৰি ৰাখক।"</string>
+    <string name="accessibility_gesture_instructional_text" msgid="5261788874937410950">"সেৱাসমূহ সালসলনিকৈ ব্যৱহাৰ কৰিবলৈ দুটা আঙুলিৰে ওপৰলৈ ছোৱাইপ কৰি ধৰি ৰাখক।"</string>
+    <string name="accessibility_gesture_3finger_instructional_text" msgid="4969448938984394550">"সেৱাসমূহ সালসলনিকৈ ব্যৱহাৰ কৰিবলৈ তিনিটা আঙুলিৰে ওপৰলৈ ছোৱাইপ কৰি ধৰি ৰাখক।"</string>
     <string name="accessibility_magnification_chooser_text" msgid="1227146738764986237">"বিবৰ্ধন"</string>
     <string name="user_switched" msgid="3768006783166984410">"বৰ্তমানৰ ব্যৱহাৰকাৰী <xliff:g id="NAME">%1$s</xliff:g>।"</string>
     <string name="user_switching_message" msgid="2871009331809089783">"<xliff:g id="NAME">%1$s</xliff:g>লৈ সলনি কৰি থকা হৈছে…"</string>
diff --git a/core/res/res/values-az/strings.xml b/core/res/res/values-az/strings.xml
index 38e93d9..77ecfa5 100644
--- a/core/res/res/values-az/strings.xml
+++ b/core/res/res/values-az/strings.xml
@@ -131,6 +131,7 @@
     <!-- no translation found for wfcSpnFormat_spn (4998685024207291232) -->
     <skip />
     <string name="wfcSpnFormat_spn_wifi_calling" msgid="136001023263502280">"<xliff:g id="SPN">%s</xliff:g> Wi-Fi Zəngi"</string>
+    <string name="wfcSpnFormat_spn_wifi_calling_vo_hyphen" msgid="1730997175789582756">"<xliff:g id="SPN">%s</xliff:g> WiFi Zəngi"</string>
     <string name="wfcSpnFormat_wlan_call" msgid="2533371081782489793">"WLAN Zəngi"</string>
     <string name="wfcSpnFormat_spn_wlan_call" msgid="2315240198303197168">"<xliff:g id="SPN">%s</xliff:g> WLAN Zəngi"</string>
     <string name="wfcSpnFormat_spn_wifi" msgid="6546481665561961938">"<xliff:g id="SPN">%s</xliff:g> Wi-Fi"</string>
@@ -1357,8 +1358,7 @@
     <string name="test_harness_mode_notification_message" msgid="1343197173054407119">"Test Rejimini deaktiv etmək üçün fabrika ayarlarına sıfırlayın."</string>
     <string name="usb_contaminant_detected_title" msgid="7136400633704058349">"USB portuna maye sızıb və ya qırılıb"</string>
     <string name="usb_contaminant_detected_message" msgid="832337061059487250">"USB portu avtomatik deaktiv edildi. Ətraflı məlumat üçün klikləyin."</string>
-    <!-- no translation found for usb_contaminant_not_detected_title (7708281124088684821) -->
-    <skip />
+    <string name="usb_contaminant_not_detected_title" msgid="7708281124088684821">"USB portundan istifadə etmək üçün OK"</string>
     <string name="usb_contaminant_not_detected_message" msgid="2415791798244545292">"Telefon artıq maye və ya nasazlığı aşkarlamayacaq."</string>
     <string name="taking_remote_bugreport_notification_title" msgid="6742483073875060934">"Baq hesabatı verilir..."</string>
     <string name="share_remote_bugreport_notification_title" msgid="4987095013583691873">"Baq hesabatı paylaşılsın?"</string>
@@ -1612,8 +1612,6 @@
     <string name="display_manager_overlay_display_name" msgid="5142365982271620716">"Örtük #<xliff:g id="ID">%1$d</xliff:g>"</string>
     <string name="display_manager_overlay_display_title" msgid="652124517672257172">"<xliff:g id="NAME">%1$s</xliff:g>: <xliff:g id="WIDTH">%2$d</xliff:g>x<xliff:g id="HEIGHT">%3$d</xliff:g>, <xliff:g id="DPI">%4$d</xliff:g> dpi"</string>
     <string name="display_manager_overlay_display_secure_suffix" msgid="6022119702628572080">", təhlükəsiz"</string>
-    <string name="activity_starter_block_bg_activity_starts_permissive" msgid="6995473033438879646">"<xliff:g id="PACKAGENAME">%1$s</xliff:g> ünvanından olan bu arxa fon fəaliyyəti növbəti Q versiyalarında blok ediləcək. G.co/dev/bgblock ünvanına baxın."</string>
-    <string name="activity_starter_block_bg_activity_starts_enforcing" msgid="3317816771072146229">"<xliff:g id="PACKAGENAME">%1$s</xliff:g> ünvanından olan arxa fon fəaliyyəti blok edildi. G.co/dev/bgblock ünvanına baxın."</string>
     <string name="kg_forgot_pattern_button_text" msgid="8852021467868220608">"Şablonu unutmuşam"</string>
     <string name="kg_wrong_pattern" msgid="1850806070801358830">"Yanlış Model"</string>
     <string name="kg_wrong_password" msgid="2333281762128113157">"Yanlış Şifrə"</string>
@@ -1667,8 +1665,12 @@
     <string name="accessibility_shortcut_enabling_service" msgid="7771852911861522636">"Əlçatımlıq Qısayolu <xliff:g id="SERVICE_NAME">%1$s</xliff:g> xidmətini aktiv etdi"</string>
     <string name="accessibility_shortcut_disabling_service" msgid="2747243438223109821">"Əlçatımlıq Qısayolu <xliff:g id="SERVICE_NAME">%1$s</xliff:g> xidmətini deaktiv etdi"</string>
     <string name="accessibility_shortcut_spoken_feedback" msgid="8376923232350078434">"<xliff:g id="SERVICE_NAME">%1$s</xliff:g> istifadə etmək üçün hər iki səs düyməsini üç saniyə basıb saxlayın"</string>
-    <string name="accessibility_button_prompt_text" msgid="4234556536456854251">"Əlçatımlılıq düyməsinə kliklədikdə istifadə etmək üçün funksiya seçin:"</string>
-    <string name="accessibility_button_instructional_text" msgid="6942300463612999993">"Funksiyaları dəyişmək üçün Əlçatımlılıq düyməsinə basıb saxlayın."</string>
+    <string name="accessibility_button_prompt_text" msgid="1176658502969738564">"Əlçatımlılıq düyməsinə toxunduqda istifadə etmək üçün xidmət seçin:"</string>
+    <string name="accessibility_gesture_prompt_text" msgid="8259145549733019401">"Əlçatımlılıq jestləri (iki barmağınızla ekranın aşağısından yuxarı doğru sürüşdürün) ilə istifadə etmək üçün xidmət seçin:"</string>
+    <string name="accessibility_gesture_3finger_prompt_text" msgid="1041435574275047665">"Əlçatımlılıq jestləri (üç barmağınızla ekranın aşağısından yuxarı doğru sürüşdürün) ilə istifadə etmək üçün xidmət seçin:"</string>
+    <string name="accessibility_button_instructional_text" msgid="7003212763213614833">"Xidmətlər arasında keçid etmək üçün əlçatımlılıq düyməsinə basın &amp; saxlayın."</string>
+    <string name="accessibility_gesture_instructional_text" msgid="5261788874937410950">"Xidmətlər arasında keçid etmək üçün ekranı iki barmağınızla yuxarı sürüşdürüb saxlayın."</string>
+    <string name="accessibility_gesture_3finger_instructional_text" msgid="4969448938984394550">"Xidmətlər arasında keçid etmək üçün ekranı üç barmağınızla yuxarı sürüşdürüb saxlayın."</string>
     <string name="accessibility_magnification_chooser_text" msgid="1227146738764986237">"Böyütmə"</string>
     <string name="user_switched" msgid="3768006783166984410">"Cari istifadəçi <xliff:g id="NAME">%1$s</xliff:g>."</string>
     <string name="user_switching_message" msgid="2871009331809089783">"<xliff:g id="NAME">%1$s</xliff:g> adına keçirilir…"</string>
diff --git a/core/res/res/values-b+sr+Latn/strings.xml b/core/res/res/values-b+sr+Latn/strings.xml
index 5539515..de95895 100644
--- a/core/res/res/values-b+sr+Latn/strings.xml
+++ b/core/res/res/values-b+sr+Latn/strings.xml
@@ -132,6 +132,7 @@
     <!-- no translation found for wfcSpnFormat_spn (4998685024207291232) -->
     <skip />
     <string name="wfcSpnFormat_spn_wifi_calling" msgid="136001023263502280">"<xliff:g id="SPN">%s</xliff:g> pozivanje preko Wi-Fi-ja"</string>
+    <string name="wfcSpnFormat_spn_wifi_calling_vo_hyphen" msgid="1730997175789582756">"<xliff:g id="SPN">%s</xliff:g> – pozivanje preko Wi-Fi-ja"</string>
     <string name="wfcSpnFormat_wlan_call" msgid="2533371081782489793">"WLAN poziv"</string>
     <string name="wfcSpnFormat_spn_wlan_call" msgid="2315240198303197168">"<xliff:g id="SPN">%s</xliff:g> WLAN poziv"</string>
     <string name="wfcSpnFormat_spn_wifi" msgid="6546481665561961938">"<xliff:g id="SPN">%s</xliff:g> Wi-Fi"</string>
@@ -1379,8 +1380,7 @@
     <string name="test_harness_mode_notification_message" msgid="1343197173054407119">"Obavite resetovanje na fabrička podešavanja da biste onemogućili režim probnog korišćenja."</string>
     <string name="usb_contaminant_detected_title" msgid="7136400633704058349">"Tečnost ili nečistoća u USB portu"</string>
     <string name="usb_contaminant_detected_message" msgid="832337061059487250">"USB port je automatski isključen. Dodirnite da biste saznali više."</string>
-    <!-- no translation found for usb_contaminant_not_detected_title (7708281124088684821) -->
-    <skip />
+    <string name="usb_contaminant_not_detected_title" msgid="7708281124088684821">"Korišćenje USB porta je dozvoljeno"</string>
     <string name="usb_contaminant_not_detected_message" msgid="2415791798244545292">"Telefon više ne otkriva tečnost ili nečistoću."</string>
     <string name="taking_remote_bugreport_notification_title" msgid="6742483073875060934">"Izveštaj o grešci se generiše…"</string>
     <string name="share_remote_bugreport_notification_title" msgid="4987095013583691873">"Želite li da podelite izveštaj o grešci?"</string>
@@ -1635,8 +1635,6 @@
     <string name="display_manager_overlay_display_name" msgid="5142365982271620716">"Postavljeni element br. <xliff:g id="ID">%1$d</xliff:g>"</string>
     <string name="display_manager_overlay_display_title" msgid="652124517672257172">"<xliff:g id="NAME">%1$s</xliff:g>: <xliff:g id="WIDTH">%2$d</xliff:g>×<xliff:g id="HEIGHT">%3$d</xliff:g>, <xliff:g id="DPI">%4$d</xliff:g> dpi"</string>
     <string name="display_manager_overlay_display_secure_suffix" msgid="6022119702628572080">", bezbedno"</string>
-    <string name="activity_starter_block_bg_activity_starts_permissive" msgid="6995473033438879646">"Ovo pokretanje aktivnosti u pozadini sa <xliff:g id="PACKAGENAME">%1$s</xliff:g> biće blokirano u budućim Q verzijama. Pogledajte g.co/dev/bgblock."</string>
-    <string name="activity_starter_block_bg_activity_starts_enforcing" msgid="3317816771072146229">"Pokretanje aktivnosti u pozadini sa <xliff:g id="PACKAGENAME">%1$s</xliff:g> je blokirano. Pogledajte g.co/dev/bgblock."</string>
     <string name="kg_forgot_pattern_button_text" msgid="8852021467868220608">"Zaboravljeni šablon"</string>
     <string name="kg_wrong_pattern" msgid="1850806070801358830">"Pogrešan šablon"</string>
     <string name="kg_wrong_password" msgid="2333281762128113157">"Pogrešna lozinka"</string>
@@ -1691,8 +1689,12 @@
     <string name="accessibility_shortcut_enabling_service" msgid="7771852911861522636">"Prečica za pristupačnost je uključila uslugu <xliff:g id="SERVICE_NAME">%1$s</xliff:g>"</string>
     <string name="accessibility_shortcut_disabling_service" msgid="2747243438223109821">"Prečica za pristupačnost je isključila uslugu <xliff:g id="SERVICE_NAME">%1$s</xliff:g>"</string>
     <string name="accessibility_shortcut_spoken_feedback" msgid="8376923232350078434">"Pritisnite i zadržite oba tastera za jačinu zvuka tri sekunde da biste koristili <xliff:g id="SERVICE_NAME">%1$s</xliff:g>"</string>
-    <string name="accessibility_button_prompt_text" msgid="4234556536456854251">"Izaberite funkciju koja će se koristiti kada dodirnete dugme za pristupačnost:"</string>
-    <string name="accessibility_button_instructional_text" msgid="6942300463612999993">"Pritisnite i zadržite dugme za pristupačnost da biste menjali funkcije."</string>
+    <string name="accessibility_button_prompt_text" msgid="1176658502969738564">"Odaberite uslugu koja će se koristiti kada dodirnete dugme za pristupačnost:"</string>
+    <string name="accessibility_gesture_prompt_text" msgid="8259145549733019401">"Odaberite funkciju koja će se koristiti pomoću pokreta za pristupačnost (pomoću dva prsta prevucite nagore od dna ekrana):"</string>
+    <string name="accessibility_gesture_3finger_prompt_text" msgid="1041435574275047665">"Odaberite uslugu koja će se koristiti pomoću pokreta za pristupačnost (pomoću tri prsta prevucite nagore od dna ekrana):"</string>
+    <string name="accessibility_button_instructional_text" msgid="7003212763213614833">"Da biste prelazili sa jedne usluge na drugu, dodirnite i zadržite dugme za pristupačnost."</string>
+    <string name="accessibility_gesture_instructional_text" msgid="5261788874937410950">"Da biste prelazili sa jedne usluge na drugu, prevucite nagore pomoću dva prsta i zadržite."</string>
+    <string name="accessibility_gesture_3finger_instructional_text" msgid="4969448938984394550">"Da biste prelazili sa jedne usluge na drugu, prevucite nagore pomoću tri prsta i zadržite."</string>
     <string name="accessibility_magnification_chooser_text" msgid="1227146738764986237">"Uvećanje"</string>
     <string name="user_switched" msgid="3768006783166984410">"Aktuelni korisnik <xliff:g id="NAME">%1$s</xliff:g>."</string>
     <string name="user_switching_message" msgid="2871009331809089783">"Prebacivanje na <xliff:g id="NAME">%1$s</xliff:g>…"</string>
diff --git a/core/res/res/values-be/strings.xml b/core/res/res/values-be/strings.xml
index 5705e61..8326d4f 100644
--- a/core/res/res/values-be/strings.xml
+++ b/core/res/res/values-be/strings.xml
@@ -133,6 +133,7 @@
     <!-- no translation found for wfcSpnFormat_spn (4998685024207291232) -->
     <skip />
     <string name="wfcSpnFormat_spn_wifi_calling" msgid="136001023263502280">"Wi-Fi-тэлефанія ад <xliff:g id="SPN">%s</xliff:g>"</string>
+    <string name="wfcSpnFormat_spn_wifi_calling_vo_hyphen" msgid="1730997175789582756">"Wi-Fi-тэлефанія ад аператара \"<xliff:g id="SPN">%s</xliff:g>\""</string>
     <string name="wfcSpnFormat_wlan_call" msgid="2533371081782489793">"Выклік праз WLAN"</string>
     <string name="wfcSpnFormat_spn_wlan_call" msgid="2315240198303197168">"Выклік праз WLAN ад <xliff:g id="SPN">%s</xliff:g>"</string>
     <string name="wfcSpnFormat_spn_wifi" msgid="6546481665561961938">"Wi-Fi ад <xliff:g id="SPN">%s</xliff:g>"</string>
@@ -1401,8 +1402,7 @@
     <string name="test_harness_mode_notification_message" msgid="1343197173054407119">"Каб выключыць тэставы рэжым, скіньце налады да заводскіх значэнняў."</string>
     <string name="usb_contaminant_detected_title" msgid="7136400633704058349">"Вадкасць або смецце ў порце USB"</string>
     <string name="usb_contaminant_detected_message" msgid="832337061059487250">"Порт USB аўтаматычна адключаны. Каб даведацца больш, націсніце тут."</string>
-    <!-- no translation found for usb_contaminant_not_detected_title (7708281124088684821) -->
-    <skip />
+    <string name="usb_contaminant_not_detected_title" msgid="7708281124088684821">"Порт USB можна выкарыстоўваць"</string>
     <string name="usb_contaminant_not_detected_message" msgid="2415791798244545292">"Тэлефон выявіў, што вадкасці і смецця больш няма."</string>
     <string name="taking_remote_bugreport_notification_title" msgid="6742483073875060934">"Стварэнне справаздачы пра памылку…"</string>
     <string name="share_remote_bugreport_notification_title" msgid="4987095013583691873">"Падзяліцца справаздачай пра памылку?"</string>
@@ -1658,8 +1658,6 @@
     <string name="display_manager_overlay_display_name" msgid="5142365982271620716">"Оверлей # <xliff:g id="ID">%1$d</xliff:g>"</string>
     <string name="display_manager_overlay_display_title" msgid="652124517672257172">"<xliff:g id="NAME">%1$s</xliff:g>: <xliff:g id="WIDTH">%2$d</xliff:g>x<xliff:g id="HEIGHT">%3$d</xliff:g>, <xliff:g id="DPI">%4$d</xliff:g> кр. на цалю"</string>
     <string name="display_manager_overlay_display_secure_suffix" msgid="6022119702628572080">", бяспечны"</string>
-    <string name="activity_starter_block_bg_activity_starts_permissive" msgid="6995473033438879646">"Запуск дзеянняў у фонавым рэжыме з пакета \"<xliff:g id="PACKAGENAME">%1$s</xliff:g>\" будзе заблакіраваны ў будучых Q-зборках. Глядзіце g.co/dev/bgblock."</string>
-    <string name="activity_starter_block_bg_activity_starts_enforcing" msgid="3317816771072146229">"Запуск дзеянняў у фонавым рэжыме з пакета \"<xliff:g id="PACKAGENAME">%1$s</xliff:g>\" заблакіраваны. Глядзіце g.co/dev/bgblock."</string>
     <string name="kg_forgot_pattern_button_text" msgid="8852021467868220608">"Забылі ключ"</string>
     <string name="kg_wrong_pattern" msgid="1850806070801358830">"Няправільны ўзор"</string>
     <string name="kg_wrong_password" msgid="2333281762128113157">"Няправiльны пароль"</string>
@@ -1715,8 +1713,12 @@
     <string name="accessibility_shortcut_enabling_service" msgid="7771852911861522636">"<xliff:g id="SERVICE_NAME">%1$s</xliff:g> быў уключаны з дапамогай камбінацыі хуткага доступу для спецыяльных магчымасцей"</string>
     <string name="accessibility_shortcut_disabling_service" msgid="2747243438223109821">"<xliff:g id="SERVICE_NAME">%1$s</xliff:g> быў адключаны з дапамогай камбінацыі хуткага доступу для спецыяльных магчымасцей"</string>
     <string name="accessibility_shortcut_spoken_feedback" msgid="8376923232350078434">"Каб карыстацца сэрвісам \"<xliff:g id="SERVICE_NAME">%1$s</xliff:g>\", націсніце і ўтрымлівайце на працягу трох секунд абедзве клавішы гучнасці"</string>
-    <string name="accessibility_button_prompt_text" msgid="4234556536456854251">"Выберыце функцыю для выкарыстання пры націску кнопкі \"Спецыяльныя магчымасці\":"</string>
-    <string name="accessibility_button_instructional_text" msgid="6942300463612999993">"Каб змяняць функцыі, краніце і ўтрымлівайце кнопку \"Спецыяльныя магчымасці\"."</string>
+    <string name="accessibility_button_prompt_text" msgid="1176658502969738564">"Выберыце службу для выкарыстання пры націску кнопкі \"Спецыяльныя магчымасці\":"</string>
+    <string name="accessibility_gesture_prompt_text" msgid="8259145549733019401">"З дапамогай жэста спецыяльных магчымасцей (правядзіце двума пальцамі па экране знізу ўверх) выберыце службу для выкарыстання:"</string>
+    <string name="accessibility_gesture_3finger_prompt_text" msgid="1041435574275047665">"З дапамогай жэста спецыяльных магчымасцей (правядзіце трыма пальцамі па экране знізу ўверх) выберыце службу для выкарыстання:"</string>
+    <string name="accessibility_button_instructional_text" msgid="7003212763213614833">"Каб пераключыцца на другую службу, націсніце і ўтрымлівайце кнопку спецыяльных магчымасцей."</string>
+    <string name="accessibility_gesture_instructional_text" msgid="5261788874937410950">"Каб пераключыцца на другую службу, правядзіце ўверх двума пальцамі, утрымліваючы іх на экране."</string>
+    <string name="accessibility_gesture_3finger_instructional_text" msgid="4969448938984394550">"Каб пераключыцца на другую службу, правядзіце ўверх трыма пальцамі, утрымліваючы іх на экране."</string>
     <string name="accessibility_magnification_chooser_text" msgid="1227146738764986237">"Павелічэнне"</string>
     <string name="user_switched" msgid="3768006783166984410">"Бягучы карыстальнік <xliff:g id="NAME">%1$s</xliff:g>."</string>
     <string name="user_switching_message" msgid="2871009331809089783">"Пераход да <xliff:g id="NAME">%1$s</xliff:g>..."</string>
diff --git a/core/res/res/values-bg/strings.xml b/core/res/res/values-bg/strings.xml
index 4027f03..dc5e17d 100644
--- a/core/res/res/values-bg/strings.xml
+++ b/core/res/res/values-bg/strings.xml
@@ -131,6 +131,7 @@
     <!-- no translation found for wfcSpnFormat_spn (4998685024207291232) -->
     <skip />
     <string name="wfcSpnFormat_spn_wifi_calling" msgid="136001023263502280">"Обаждания през Wi-Fi от <xliff:g id="SPN">%s</xliff:g>"</string>
+    <string name="wfcSpnFormat_spn_wifi_calling_vo_hyphen" msgid="1730997175789582756">"Обаждания през Wi-Fi от <xliff:g id="SPN">%s</xliff:g>"</string>
     <string name="wfcSpnFormat_wlan_call" msgid="2533371081782489793">"Обаждане през WLAN"</string>
     <string name="wfcSpnFormat_spn_wlan_call" msgid="2315240198303197168">"Обаждане през WLAN от <xliff:g id="SPN">%s</xliff:g>"</string>
     <string name="wfcSpnFormat_spn_wifi" msgid="6546481665561961938">"Wi-Fi от <xliff:g id="SPN">%s</xliff:g>"</string>
@@ -1357,8 +1358,7 @@
     <string name="test_harness_mode_notification_message" msgid="1343197173054407119">"Възстановете фабричните настройки, за да деактивирате режима за тестова среда."</string>
     <string name="usb_contaminant_detected_title" msgid="7136400633704058349">"Течност или замърсяване в USB порта"</string>
     <string name="usb_contaminant_detected_message" msgid="832337061059487250">"USB портът е деактивиран автоматично. Докоснете, за да научите повече."</string>
-    <!-- no translation found for usb_contaminant_not_detected_title (7708281124088684821) -->
-    <skip />
+    <string name="usb_contaminant_not_detected_title" msgid="7708281124088684821">"Можете да използвате USB порта"</string>
     <string name="usb_contaminant_not_detected_message" msgid="2415791798244545292">"Телефонът вече не открива течности или замърсяване."</string>
     <string name="taking_remote_bugreport_notification_title" msgid="6742483073875060934">"Сигналът за програмна грешка се извлича…"</string>
     <string name="share_remote_bugreport_notification_title" msgid="4987095013583691873">"Да се сподели ли сигналът за програмна грешка?"</string>
@@ -1612,8 +1612,6 @@
     <string name="display_manager_overlay_display_name" msgid="5142365982271620716">"Наслагване №<xliff:g id="ID">%1$d</xliff:g>"</string>
     <string name="display_manager_overlay_display_title" msgid="652124517672257172">"„<xliff:g id="NAME">%1$s</xliff:g>“: <xliff:g id="WIDTH">%2$d</xliff:g> x <xliff:g id="HEIGHT">%3$d</xliff:g>, <xliff:g id="DPI">%4$d</xliff:g> dpi"</string>
     <string name="display_manager_overlay_display_secure_suffix" msgid="6022119702628572080">", защитено"</string>
-    <string name="activity_starter_block_bg_activity_starts_permissive" msgid="6995473033438879646">"Стартирането на активност на заден план от <xliff:g id="PACKAGENAME">%1$s</xliff:g> ще бъде блокирано в бъдещите компилации под Q. Разгледайте g.co/dev/bgblock."</string>
-    <string name="activity_starter_block_bg_activity_starts_enforcing" msgid="3317816771072146229">"Стартирането на активност на заден план от <xliff:g id="PACKAGENAME">%1$s</xliff:g> е блокирано. Разгледайте g.co/dev/bgblock."</string>
     <string name="kg_forgot_pattern_button_text" msgid="8852021467868220608">"Забравена фигура"</string>
     <string name="kg_wrong_pattern" msgid="1850806070801358830">"Грешна фигура"</string>
     <string name="kg_wrong_password" msgid="2333281762128113157">"Грешна парола"</string>
@@ -1667,8 +1665,12 @@
     <string name="accessibility_shortcut_enabling_service" msgid="7771852911861522636">"Прекият път за достъпност включи <xliff:g id="SERVICE_NAME">%1$s</xliff:g>"</string>
     <string name="accessibility_shortcut_disabling_service" msgid="2747243438223109821">"Прекият път за достъпност изключи <xliff:g id="SERVICE_NAME">%1$s</xliff:g>"</string>
     <string name="accessibility_shortcut_spoken_feedback" msgid="8376923232350078434">"За да използвате <xliff:g id="SERVICE_NAME">%1$s</xliff:g>, натиснете двата бутона за силата на звука и ги задръжте за 3 секунди"</string>
-    <string name="accessibility_button_prompt_text" msgid="4234556536456854251">"Изберете функция, която да използвате, когато докоснете бутона за достъпност:"</string>
-    <string name="accessibility_button_instructional_text" msgid="6942300463612999993">"За да промените функции, докоснете и задръжте бутона за достъпност."</string>
+    <string name="accessibility_button_prompt_text" msgid="1176658502969738564">"Изберете коя услуга да се използва при докосване на бутона за достъпност:"</string>
+    <string name="accessibility_gesture_prompt_text" msgid="8259145549733019401">"Изберете коя услуга да се използва с жеста за достъпност (прекарване на два пръста нагоре от долната част на екрана):"</string>
+    <string name="accessibility_gesture_3finger_prompt_text" msgid="1041435574275047665">"Изберете коя услуга да се използва с жеста за достъпност (прекарване на три пръста нагоре от долната част на екрана):"</string>
+    <string name="accessibility_button_instructional_text" msgid="7003212763213614833">"За превключване между услугите докоснете и задръжте бутона за достъпност."</string>
+    <string name="accessibility_gesture_instructional_text" msgid="5261788874937410950">"За превключване между услугите прекарайте два пръста нагоре и задръжте."</string>
+    <string name="accessibility_gesture_3finger_instructional_text" msgid="4969448938984394550">"За превключване между услугите прекарайте три пръста нагоре и задръжте."</string>
     <string name="accessibility_magnification_chooser_text" msgid="1227146738764986237">"Ниво на мащаба"</string>
     <string name="user_switched" msgid="3768006783166984410">"Текущ потребител <xliff:g id="NAME">%1$s</xliff:g>."</string>
     <string name="user_switching_message" msgid="2871009331809089783">"Превключва се към <xliff:g id="NAME">%1$s</xliff:g>…"</string>
diff --git a/core/res/res/values-bn/strings.xml b/core/res/res/values-bn/strings.xml
index dbe3cd2..676eced 100644
--- a/core/res/res/values-bn/strings.xml
+++ b/core/res/res/values-bn/strings.xml
@@ -131,6 +131,7 @@
     <!-- no translation found for wfcSpnFormat_spn (4998685024207291232) -->
     <skip />
     <string name="wfcSpnFormat_spn_wifi_calling" msgid="136001023263502280">"<xliff:g id="SPN">%s</xliff:g> ওয়াই-ফাই কলিং"</string>
+    <string name="wfcSpnFormat_spn_wifi_calling_vo_hyphen" msgid="1730997175789582756">"<xliff:g id="SPN">%s</xliff:g> Wi‑Fi কলিং"</string>
     <string name="wfcSpnFormat_wlan_call" msgid="2533371081782489793">"WLAN কল"</string>
     <string name="wfcSpnFormat_spn_wlan_call" msgid="2315240198303197168">"<xliff:g id="SPN">%s</xliff:g> WLAN কল"</string>
     <string name="wfcSpnFormat_spn_wifi" msgid="6546481665561961938">"<xliff:g id="SPN">%s</xliff:g> ওয়াই-ফাই"</string>
@@ -1358,8 +1359,7 @@
     <string name="test_harness_mode_notification_message" msgid="1343197173054407119">"টেস্ট হারনেস মোড বন্ধ করতে ফ্যাক্টরি রিসেট করুন।"</string>
     <string name="usb_contaminant_detected_title" msgid="7136400633704058349">"ইউএসবি পোর্টে তরল পদার্থ অথবা ধুলো কণা"</string>
     <string name="usb_contaminant_detected_message" msgid="832337061059487250">"ইউএসবি পোর্ট নিজে থেকে বন্ধ করা হবে। আরও জানতে ট্যাপ করুন।"</string>
-    <!-- no translation found for usb_contaminant_not_detected_title (7708281124088684821) -->
-    <skip />
+    <string name="usb_contaminant_not_detected_title" msgid="7708281124088684821">"ইউএসবি পোর্ট ব্যবহার করা যেতে পারে"</string>
     <string name="usb_contaminant_not_detected_message" msgid="2415791798244545292">"ফোন আর তরল পদার্থ এবং ধুলো কণা শনাক্ত করবে না।"</string>
     <string name="taking_remote_bugreport_notification_title" msgid="6742483073875060934">"ত্রুটির প্রতিবেদন নেওয়া হচ্ছে..."</string>
     <string name="share_remote_bugreport_notification_title" msgid="4987095013583691873">"ত্রুটির প্রতিবেদন শেয়ার করবেন?"</string>
@@ -1495,7 +1495,7 @@
     <string name="find_next" msgid="5742124618942193978">"পরবর্তীটি খুঁজুন"</string>
     <string name="find_previous" msgid="2196723669388360506">"পূর্ববর্তীটি খুঁজুন"</string>
     <string name="gpsNotifTicker" msgid="5622683912616496172">"<xliff:g id="NAME">%s</xliff:g> এর থেকে অবস্থানের অনুরোধ"</string>
-    <string name="gpsNotifTitle" msgid="5446858717157416839">"অবস্থানের অনুরোধ"</string>
+    <string name="gpsNotifTitle" msgid="5446858717157416839">"লোকেশন জানার অনুরোধ"</string>
     <string name="gpsNotifMessage" msgid="1374718023224000702">"<xliff:g id="NAME">%1$s</xliff:g> (<xliff:g id="SERVICE">%2$s</xliff:g>) এর দ্বারা অনুরোধকৃত"</string>
     <string name="gpsVerifYes" msgid="2346566072867213563">"হ্যাঁ"</string>
     <string name="gpsVerifNo" msgid="1146564937346454865">"না"</string>
@@ -1613,8 +1613,6 @@
     <string name="display_manager_overlay_display_name" msgid="5142365982271620716">"আচ্ছাদন #<xliff:g id="ID">%1$d</xliff:g>"</string>
     <string name="display_manager_overlay_display_title" msgid="652124517672257172">"<xliff:g id="NAME">%1$s</xliff:g>: <xliff:g id="WIDTH">%2$d</xliff:g>x<xliff:g id="HEIGHT">%3$d</xliff:g>, <xliff:g id="DPI">%4$d</xliff:g> dpi"</string>
     <string name="display_manager_overlay_display_secure_suffix" msgid="6022119702628572080">", নিরাপদ"</string>
-    <string name="activity_starter_block_bg_activity_starts_permissive" msgid="6995473033438879646">"<xliff:g id="PACKAGENAME">%1$s</xliff:g>-এর ব্যাকগ্রাউন্ড অ্যাক্টিভিটি ভবিষ্যতে Q বিল্ড ভার্সনে ব্লক করা হবে। g.co/dev/bgblock লিঙ্ক দেখুন।"</string>
-    <string name="activity_starter_block_bg_activity_starts_enforcing" msgid="3317816771072146229">"<xliff:g id="PACKAGENAME">%1$s</xliff:g>-এর ব্যাকগ্রাউন্ড অ্যাক্টিভিটি ব্লক করা হয়েছে। g.co/dev/bgblock লিঙ্ক দেখুন।"</string>
     <string name="kg_forgot_pattern_button_text" msgid="8852021467868220608">"প্যাটার্ন ভুলে গেছেন"</string>
     <string name="kg_wrong_pattern" msgid="1850806070801358830">"ভুল প্যাটার্ন"</string>
     <string name="kg_wrong_password" msgid="2333281762128113157">"ভুল পাসওয়ার্ড"</string>
@@ -1668,8 +1666,12 @@
     <string name="accessibility_shortcut_enabling_service" msgid="7771852911861522636">"অ্যাক্সেসযোগ্যতা শর্টকাট <xliff:g id="SERVICE_NAME">%1$s</xliff:g> কে চালু করেছে"</string>
     <string name="accessibility_shortcut_disabling_service" msgid="2747243438223109821">"অ্যাক্সেসযোগ্যতা শর্টকাট <xliff:g id="SERVICE_NAME">%1$s</xliff:g> কে বন্ধ করেছে"</string>
     <string name="accessibility_shortcut_spoken_feedback" msgid="8376923232350078434">"<xliff:g id="SERVICE_NAME">%1$s</xliff:g> ব্যবহার করতে ভলিউম কী বোতাম ৩ সেকেন্ডের জন্য চেপে ধরে রাখুন"</string>
-    <string name="accessibility_button_prompt_text" msgid="4234556536456854251">"অ্যাক্সেসযোগ্যতা বোতামের সাহায্যে যে বৈশিষ্ট্যটি নিয়ন্ত্রণ করতে চান, সেটি বেছে নিন:"</string>
-    <string name="accessibility_button_instructional_text" msgid="6942300463612999993">"বৈশিষ্ট্যগুলি পরিবর্তন করতে অ্যাক্সেসযোগ্যতা বোতামটি ট্যাপ করে ধরে রাখুন।"</string>
+    <string name="accessibility_button_prompt_text" msgid="1176658502969738564">"অ্যাক্সেসিবিলিটি বোতামে ট্যাপ করে ব্যবহার করার জন্য এই পরিষেবাটি বেছে নিন:"</string>
+    <string name="accessibility_gesture_prompt_text" msgid="8259145549733019401">"অ্যাক্সেসিবিলিটি জেসচারের সাহায্যে ব্যবহার করার জন্য এই পরিষেবা বেছে নিন (দুটি আঙুল দিয়ে স্ক্রিনের নিচ থেকে উপরের দিকে সোয়াইপ করুন):"</string>
+    <string name="accessibility_gesture_3finger_prompt_text" msgid="1041435574275047665">"অ্যাক্সেসিবিলিটি জেসচারের সাহায্যে ব্যবহার করার জন্য এই পরিষেবা বেছে নিন (তিনটি আঙুল দিয়ে স্ক্রিনের নিচ থেকে উপরের দিকে সোয়াইপ করুন):"</string>
+    <string name="accessibility_button_instructional_text" msgid="7003212763213614833">"একটি পরিষেবা থেকে অন্য পরিষেবায় পাল্টাতে অ্যাক্সেসিবিলিটি বোতামটি টাচ করে &amp; ধরে রাখুন।"</string>
+    <string name="accessibility_gesture_instructional_text" msgid="5261788874937410950">"একটি পরিষেবা থেকে অন্য পরিষেবায় পাল্টাতে, দুটি আঙ্গুল দিয়ে উপরের দিকে সোয়াইপ করে ধরে রাখুন।"</string>
+    <string name="accessibility_gesture_3finger_instructional_text" msgid="4969448938984394550">"একটি পরিষেবা থেকে অন্য পরিষেবায় পাল্টাতে, তিনটি আঙ্গুল দিয়ে উপরের দিকে সোয়াইপ করে ধরে রাখুন।"</string>
     <string name="accessibility_magnification_chooser_text" msgid="1227146738764986237">"বড় করে দেখা"</string>
     <string name="user_switched" msgid="3768006783166984410">"বর্তমান ব্যবহারকারী <xliff:g id="NAME">%1$s</xliff:g>৷"</string>
     <string name="user_switching_message" msgid="2871009331809089783">"<xliff:g id="NAME">%1$s</xliff:g> নামের ব্যবহারকারীতে যাচ্ছে…"</string>
diff --git a/core/res/res/values-bs/strings.xml b/core/res/res/values-bs/strings.xml
index fb1b1b0..b941546 100644
--- a/core/res/res/values-bs/strings.xml
+++ b/core/res/res/values-bs/strings.xml
@@ -132,6 +132,7 @@
     <!-- no translation found for wfcSpnFormat_spn (4998685024207291232) -->
     <skip />
     <string name="wfcSpnFormat_spn_wifi_calling" msgid="136001023263502280">"<xliff:g id="SPN">%s</xliff:g> Pozivanje putem WiFi-ja"</string>
+    <string name="wfcSpnFormat_spn_wifi_calling_vo_hyphen" msgid="1730997175789582756">"<xliff:g id="SPN">%s</xliff:g> Pozivanje putem WiFi-ja"</string>
     <string name="wfcSpnFormat_wlan_call" msgid="2533371081782489793">"WLAN poziv"</string>
     <string name="wfcSpnFormat_spn_wlan_call" msgid="2315240198303197168">"<xliff:g id="SPN">%s</xliff:g> WLAN poziv"</string>
     <string name="wfcSpnFormat_spn_wifi" msgid="6546481665561961938">"<xliff:g id="SPN">%s</xliff:g> WiFi"</string>
@@ -1381,8 +1382,7 @@
     <string name="test_harness_mode_notification_message" msgid="1343197173054407119">"Izvršite vraćanje na fabričke postavke da onemogućite način rada okvira za testiranje."</string>
     <string name="usb_contaminant_detected_title" msgid="7136400633704058349">"Tečnost ili nečistoće u USB priključku"</string>
     <string name="usb_contaminant_detected_message" msgid="832337061059487250">"USB priključak je automatski onemogućen. Dodirnite da saznate više."</string>
-    <!-- no translation found for usb_contaminant_not_detected_title (7708281124088684821) -->
-    <skip />
+    <string name="usb_contaminant_not_detected_title" msgid="7708281124088684821">"USB priključak je sada sigurno koristiti"</string>
     <string name="usb_contaminant_not_detected_message" msgid="2415791798244545292">"Telefon više ne detektira tečnost ili nečistoće."</string>
     <string name="taking_remote_bugreport_notification_title" msgid="6742483073875060934">"Prijem izvještaja o grešci..."</string>
     <string name="share_remote_bugreport_notification_title" msgid="4987095013583691873">"Podijeliti izvještaj o grešci?"</string>
@@ -1519,7 +1519,7 @@
     <string name="find_next" msgid="5742124618942193978">"Nađi sljedeći"</string>
     <string name="find_previous" msgid="2196723669388360506">"Nađi prethodni"</string>
     <string name="gpsNotifTicker" msgid="5622683912616496172">"Korisnik <xliff:g id="NAME">%s</xliff:g> je poslao zahtjev za utvrđivanje lokacije"</string>
-    <string name="gpsNotifTitle" msgid="5446858717157416839">"Zahtjev za utvrđivanje lokacije"</string>
+    <string name="gpsNotifTitle" msgid="5446858717157416839">"Zahtjev za lokaciju"</string>
     <string name="gpsNotifMessage" msgid="1374718023224000702">"Zahtjev uputio <xliff:g id="NAME">%1$s</xliff:g> (<xliff:g id="SERVICE">%2$s</xliff:g>)"</string>
     <string name="gpsVerifYes" msgid="2346566072867213563">"Da"</string>
     <string name="gpsVerifNo" msgid="1146564937346454865">"Ne"</string>
@@ -1637,8 +1637,6 @@
     <string name="display_manager_overlay_display_name" msgid="5142365982271620716">"Nadsloj #<xliff:g id="ID">%1$d</xliff:g>"</string>
     <string name="display_manager_overlay_display_title" msgid="652124517672257172">"<xliff:g id="NAME">%1$s</xliff:g>: <xliff:g id="WIDTH">%2$d</xliff:g>x<xliff:g id="HEIGHT">%3$d</xliff:g>, <xliff:g id="DPI">%4$d</xliff:g> dpi"</string>
     <string name="display_manager_overlay_display_secure_suffix" msgid="6022119702628572080">", osigurano"</string>
-    <string name="activity_starter_block_bg_activity_starts_permissive" msgid="6995473033438879646">"Pokretanje aktivnosti u pozadini na web lokaciji <xliff:g id="PACKAGENAME">%1$s</xliff:g> blokirat će se u budućim Q verzijama. Pogledajte g.co/dev/bgblock."</string>
-    <string name="activity_starter_block_bg_activity_starts_enforcing" msgid="3317816771072146229">"Blokirano je pokretanje aktivnosti u pozadini na web lokaciji <xliff:g id="PACKAGENAME">%1$s</xliff:g>. Pogledajte g.co/dev/bgblock."</string>
     <string name="kg_forgot_pattern_button_text" msgid="8852021467868220608">"Zaboravili ste uzorak?"</string>
     <string name="kg_wrong_pattern" msgid="1850806070801358830">"Pogrešan uzorak"</string>
     <string name="kg_wrong_password" msgid="2333281762128113157">"Pogrešna lozinka"</string>
@@ -1693,8 +1691,12 @@
     <string name="accessibility_shortcut_enabling_service" msgid="7771852911861522636">"Prečica za pristupačnost je uključila uslugu <xliff:g id="SERVICE_NAME">%1$s</xliff:g>"</string>
     <string name="accessibility_shortcut_disabling_service" msgid="2747243438223109821">"Prečica za pristupačnost je isključila uslugu <xliff:g id="SERVICE_NAME">%1$s</xliff:g>"</string>
     <string name="accessibility_shortcut_spoken_feedback" msgid="8376923232350078434">"Pritisnite obje tipke za podešavanje jačine zvuka i držite ih pritisnutim tri sekunde da koristite uslugu <xliff:g id="SERVICE_NAME">%1$s</xliff:g>"</string>
-    <string name="accessibility_button_prompt_text" msgid="4234556536456854251">"Odaberite funkciju koja će se koristiti kada dodirnete dugme Pristupačnost:"</string>
-    <string name="accessibility_button_instructional_text" msgid="6942300463612999993">"Da promijenite funkcije, dodirnite i držite dugme Pristupačnost."</string>
+    <string name="accessibility_button_prompt_text" msgid="1176658502969738564">"Odaberite uslugu koja će se koristiti kada dodirnete dugme za pristupačnost:"</string>
+    <string name="accessibility_gesture_prompt_text" msgid="8259145549733019401">"Odaberite uslugu koja će se koristiti kada izvedete pokret za pristupačnost (s dva prsta prevucite prema gore s dna ekrana):"</string>
+    <string name="accessibility_gesture_3finger_prompt_text" msgid="1041435574275047665">"Odaberite uslugu koja će se koristiti kada izvedete pokret za pristupačnost (s tri prsta prevucite prema gore s dna ekrana):"</string>
+    <string name="accessibility_button_instructional_text" msgid="7003212763213614833">"Za prebacivanje između usluga dodirnite i zadržite dugme za pristupačnost."</string>
+    <string name="accessibility_gesture_instructional_text" msgid="5261788874937410950">"Za prebacivanje između usluga s dva prsta prevucite prema gore i zadržite."</string>
+    <string name="accessibility_gesture_3finger_instructional_text" msgid="4969448938984394550">"Za prebacivanje između usluga s tri prsta prevucite prema gore i zadržite."</string>
     <string name="accessibility_magnification_chooser_text" msgid="1227146738764986237">"Uvećanje"</string>
     <string name="user_switched" msgid="3768006783166984410">"Trenutni korisnik <xliff:g id="NAME">%1$s</xliff:g>."</string>
     <string name="user_switching_message" msgid="2871009331809089783">"Prebacivanje na korisnika <xliff:g id="NAME">%1$s</xliff:g>..."</string>
diff --git a/core/res/res/values-ca/strings.xml b/core/res/res/values-ca/strings.xml
index f94fcbb..26790dd 100644
--- a/core/res/res/values-ca/strings.xml
+++ b/core/res/res/values-ca/strings.xml
@@ -131,6 +131,7 @@
     <!-- no translation found for wfcSpnFormat_spn (4998685024207291232) -->
     <skip />
     <string name="wfcSpnFormat_spn_wifi_calling" msgid="136001023263502280">"Trucades per Wi‑Fi (<xliff:g id="SPN">%s</xliff:g>)"</string>
+    <string name="wfcSpnFormat_spn_wifi_calling_vo_hyphen" msgid="1730997175789582756">"Trucades per Wi-Fi (<xliff:g id="SPN">%s</xliff:g>)"</string>
     <string name="wfcSpnFormat_wlan_call" msgid="2533371081782489793">"Trucada per WLAN"</string>
     <string name="wfcSpnFormat_spn_wlan_call" msgid="2315240198303197168">"Trucada per WLAN (<xliff:g id="SPN">%s</xliff:g>)"</string>
     <string name="wfcSpnFormat_spn_wifi" msgid="6546481665561961938">"Wi‑Fi (<xliff:g id="SPN">%s</xliff:g>)"</string>
@@ -1357,8 +1358,7 @@
     <string name="test_harness_mode_notification_message" msgid="1343197173054407119">"Si vols desactivar el mode Agent de prova, restableix les dades de fàbrica."</string>
     <string name="usb_contaminant_detected_title" msgid="7136400633704058349">"Hi ha líquid o pols al port USB"</string>
     <string name="usb_contaminant_detected_message" msgid="832337061059487250">"El port USB es desactiva automàticament. Toca per obtenir més informació."</string>
-    <!-- no translation found for usb_contaminant_not_detected_title (7708281124088684821) -->
-    <skip />
+    <string name="usb_contaminant_not_detected_title" msgid="7708281124088684821">"Ja pots utilitzar el port USB"</string>
     <string name="usb_contaminant_not_detected_message" msgid="2415791798244545292">"El telèfon ja no detecta líquids ni pols."</string>
     <string name="taking_remote_bugreport_notification_title" msgid="6742483073875060934">"S\'està creant l\'informe d\'errors…"</string>
     <string name="share_remote_bugreport_notification_title" msgid="4987095013583691873">"Vols compartir l\'informe d\'errors?"</string>
@@ -1612,8 +1612,6 @@
     <string name="display_manager_overlay_display_name" msgid="5142365982271620716">"Superposa #<xliff:g id="ID">%1$d</xliff:g>"</string>
     <string name="display_manager_overlay_display_title" msgid="652124517672257172">"<xliff:g id="NAME">%1$s</xliff:g>: <xliff:g id="WIDTH">%2$d</xliff:g> x <xliff:g id="HEIGHT">%3$d</xliff:g>, <xliff:g id="DPI">%4$d</xliff:g> dpi"</string>
     <string name="display_manager_overlay_display_secure_suffix" msgid="6022119702628572080">", segur"</string>
-    <string name="activity_starter_block_bg_activity_starts_permissive" msgid="6995473033438879646">"A les futures compilacions de Q, es bloquejarà aquest inici d\'activitat en segon pla del paquet <xliff:g id="PACKAGENAME">%1$s</xliff:g>. Consulta g.co/dev/bgblock."</string>
-    <string name="activity_starter_block_bg_activity_starts_enforcing" msgid="3317816771072146229">"S\'ha bloquejat l\'inici d\'activitat en segon pla del paquet <xliff:g id="PACKAGENAME">%1$s</xliff:g>. Consulta g.co/dev/bgblock."</string>
     <string name="kg_forgot_pattern_button_text" msgid="8852021467868220608">"He oblidat el patró"</string>
     <string name="kg_wrong_pattern" msgid="1850806070801358830">"Patró incorrecte"</string>
     <string name="kg_wrong_password" msgid="2333281762128113157">"Contrasenya incorrecta"</string>
@@ -1667,8 +1665,12 @@
     <string name="accessibility_shortcut_enabling_service" msgid="7771852911861522636">"La drecera d\'accessibilitat ha activat <xliff:g id="SERVICE_NAME">%1$s</xliff:g>"</string>
     <string name="accessibility_shortcut_disabling_service" msgid="2747243438223109821">"La drecera d\'accessibilitat ha desactivat <xliff:g id="SERVICE_NAME">%1$s</xliff:g>"</string>
     <string name="accessibility_shortcut_spoken_feedback" msgid="8376923232350078434">"Mantén premudes les dues tecles de volum durant 3 segons per fer servir <xliff:g id="SERVICE_NAME">%1$s</xliff:g>"</string>
-    <string name="accessibility_button_prompt_text" msgid="4234556536456854251">"Tria la funció que s\'utilitzarà quan toquis el botó Accessibilitat:"</string>
-    <string name="accessibility_button_instructional_text" msgid="6942300463612999993">"Per canviar les funcions, toca i mantén premut el botó Accessibilitat."</string>
+    <string name="accessibility_button_prompt_text" msgid="1176658502969738564">"Tria el servei que s\'utilitzarà quan toquis el botó d\'accessibilitat:"</string>
+    <string name="accessibility_gesture_prompt_text" msgid="8259145549733019401">"Tria el servei que s\'utilitzarà amb el gest d\'accessibilitat (fes lliscar dos dits cap amunt des de la part inferior de la pantalla)."</string>
+    <string name="accessibility_gesture_3finger_prompt_text" msgid="1041435574275047665">"Tria el servei que s\'utilitzarà amb el gest d\'accessibilitat (fes lliscar tres dits cap amunt des de la part inferior de la pantalla)."</string>
+    <string name="accessibility_button_instructional_text" msgid="7003212763213614833">"Per canviar de servei, mantén premut el botó d\'accessibilitat."</string>
+    <string name="accessibility_gesture_instructional_text" msgid="5261788874937410950">"Per canviar de servei, fes lliscar dos dits i mantén premut."</string>
+    <string name="accessibility_gesture_3finger_instructional_text" msgid="4969448938984394550">"Per canviar de servei, fes lliscar tres dits i mantén premut."</string>
     <string name="accessibility_magnification_chooser_text" msgid="1227146738764986237">"Ampliació"</string>
     <string name="user_switched" msgid="3768006783166984410">"Usuari actual: <xliff:g id="NAME">%1$s</xliff:g>."</string>
     <string name="user_switching_message" msgid="2871009331809089783">"S\'està canviant a <xliff:g id="NAME">%1$s</xliff:g>…"</string>
@@ -1783,7 +1785,7 @@
     <string name="restr_pin_try_later" msgid="973144472490532377">"Torna-ho a provar més tard"</string>
     <string name="immersive_cling_title" msgid="8394201622932303336">"Mode de pantalla completa"</string>
     <string name="immersive_cling_description" msgid="3482371193207536040">"Per sortir, llisca cap avall des de la part superior."</string>
-    <string name="immersive_cling_positive" msgid="5016839404568297683">"D\'acord"</string>
+    <string name="immersive_cling_positive" msgid="5016839404568297683">"Entesos"</string>
     <string name="done_label" msgid="2093726099505892398">"Fet"</string>
     <string name="hour_picker_description" msgid="6698199186859736512">"Control circular de les hores"</string>
     <string name="minute_picker_description" msgid="8606010966873791190">"Control circular dels minuts"</string>
@@ -2005,7 +2007,7 @@
     <string name="battery_saver_off_notification_summary" msgid="1374222493681267143">"L\'estalvi de bateria s\'ha desactivat. Les funcions ja no estan restringides."</string>
     <string name="battery_saver_off_alternative_notification_summary" msgid="4340727818546508436">"L\'estalvi de bateria s\'ha desactivat. Les funcions ja no estan restringides."</string>
     <string name="mime_type_folder" msgid="7111951698626315204">"Carpeta"</string>
-    <string name="mime_type_apk" msgid="5518003630972506900">"Aplicació per a Android"</string>
+    <string name="mime_type_apk" msgid="5518003630972506900">"Aplicació d\'Android"</string>
     <string name="mime_type_generic" msgid="6833871596845900027">"Fitxer"</string>
     <string name="mime_type_generic_ext" msgid="8450275970061657174">"Fitxer <xliff:g id="EXTENSION">%1$s</xliff:g>"</string>
     <string name="mime_type_audio" msgid="6289777657172050926">"Àudio"</string>
diff --git a/core/res/res/values-cs/strings.xml b/core/res/res/values-cs/strings.xml
index f2ed698..404aa1d 100644
--- a/core/res/res/values-cs/strings.xml
+++ b/core/res/res/values-cs/strings.xml
@@ -133,6 +133,7 @@
     <!-- no translation found for wfcSpnFormat_spn (4998685024207291232) -->
     <skip />
     <string name="wfcSpnFormat_spn_wifi_calling" msgid="136001023263502280">"<xliff:g id="SPN">%s</xliff:g>: volání přes Wi-Fi"</string>
+    <string name="wfcSpnFormat_spn_wifi_calling_vo_hyphen" msgid="1730997175789582756">"Volání přes Wi-Fi – <xliff:g id="SPN">%s</xliff:g>"</string>
     <string name="wfcSpnFormat_wlan_call" msgid="2533371081782489793">"Volání přes WLAN"</string>
     <string name="wfcSpnFormat_spn_wlan_call" msgid="2315240198303197168">"<xliff:g id="SPN">%s</xliff:g>: volání přes WLAN"</string>
     <string name="wfcSpnFormat_spn_wifi" msgid="6546481665561961938">"<xliff:g id="SPN">%s</xliff:g>: Wi-Fi"</string>
@@ -1401,8 +1402,7 @@
     <string name="test_harness_mode_notification_message" msgid="1343197173054407119">"Chcete-li deaktivovat režim správce testů, restartujte zařízení do továrního nastavení."</string>
     <string name="usb_contaminant_detected_title" msgid="7136400633704058349">"Kapalina nebo nečistota v portu USB"</string>
     <string name="usb_contaminant_detected_message" msgid="832337061059487250">"Port USB byl automaticky deaktivován. Klepnutím zobrazíte další informace."</string>
-    <!-- no translation found for usb_contaminant_not_detected_title (7708281124088684821) -->
-    <skip />
+    <string name="usb_contaminant_not_detected_title" msgid="7708281124088684821">"Port USB lze bezpečně použít"</string>
     <string name="usb_contaminant_not_detected_message" msgid="2415791798244545292">"Telefon již nedetekuje kapaliny ani nečistoty."</string>
     <string name="taking_remote_bugreport_notification_title" msgid="6742483073875060934">"Vytváření zprávy o chybě…"</string>
     <string name="share_remote_bugreport_notification_title" msgid="4987095013583691873">"Sdílet zprávu o chybě?"</string>
@@ -1540,7 +1540,7 @@
     <string name="find_next" msgid="5742124618942193978">"Najít další"</string>
     <string name="find_previous" msgid="2196723669388360506">"Najít předchozí"</string>
     <string name="gpsNotifTicker" msgid="5622683912616496172">"Požadavek na informace o poloze od uživatele <xliff:g id="NAME">%s</xliff:g>"</string>
-    <string name="gpsNotifTitle" msgid="5446858717157416839">"Požadavek na informace o poloze"</string>
+    <string name="gpsNotifTitle" msgid="5446858717157416839">"Žádost o informaci o poloze"</string>
     <string name="gpsNotifMessage" msgid="1374718023224000702">"Požadavek od uživatele <xliff:g id="NAME">%1$s</xliff:g> (<xliff:g id="SERVICE">%2$s</xliff:g>)"</string>
     <string name="gpsVerifYes" msgid="2346566072867213563">"Ano"</string>
     <string name="gpsVerifNo" msgid="1146564937346454865">"Ne"</string>
@@ -1658,8 +1658,6 @@
     <string name="display_manager_overlay_display_name" msgid="5142365982271620716">"Překryvná vrstva č. <xliff:g id="ID">%1$d</xliff:g>"</string>
     <string name="display_manager_overlay_display_title" msgid="652124517672257172">"<xliff:g id="NAME">%1$s</xliff:g>: <xliff:g id="WIDTH">%2$d</xliff:g>x<xliff:g id="HEIGHT">%3$d</xliff:g>, <xliff:g id="DPI">%4$d</xliff:g> dpi"</string>
     <string name="display_manager_overlay_display_secure_suffix" msgid="6022119702628572080">", zabezpečené"</string>
-    <string name="activity_starter_block_bg_activity_starts_permissive" msgid="6995473033438879646">"Zahájení této aktivity na pozadí ze zdroje <xliff:g id="PACKAGENAME">%1$s</xliff:g> bude v budoucích sestaveních Q zablokováno. Další informace: g.co/dev/bgblock."</string>
-    <string name="activity_starter_block_bg_activity_starts_enforcing" msgid="3317816771072146229">"Zahájení aktivity na pozadí ze zdroje <xliff:g id="PACKAGENAME">%1$s</xliff:g> bylo zablokováno. Další informace: g.co/dev/bgblock."</string>
     <string name="kg_forgot_pattern_button_text" msgid="8852021467868220608">"Zapomenuté gesto"</string>
     <string name="kg_wrong_pattern" msgid="1850806070801358830">"Nesprávné gesto"</string>
     <string name="kg_wrong_password" msgid="2333281762128113157">"Nesprávné heslo"</string>
@@ -1715,8 +1713,12 @@
     <string name="accessibility_shortcut_enabling_service" msgid="7771852911861522636">"Zkratka přístupnosti zapnula službu <xliff:g id="SERVICE_NAME">%1$s</xliff:g>"</string>
     <string name="accessibility_shortcut_disabling_service" msgid="2747243438223109821">"Zkratka přístupnosti vypnula službu <xliff:g id="SERVICE_NAME">%1$s</xliff:g>"</string>
     <string name="accessibility_shortcut_spoken_feedback" msgid="8376923232350078434">"Chcete-li používat službu <xliff:g id="SERVICE_NAME">%1$s</xliff:g>, tři sekundy podržte stisknutá obě tlačítka hlasitosti"</string>
-    <string name="accessibility_button_prompt_text" msgid="4234556536456854251">"Určete, jakou funkci aktivujete klepnutím na tlačítko Přístupnost:"</string>
-    <string name="accessibility_button_instructional_text" msgid="6942300463612999993">"Chcete-li vybrat jinou funkci, podržte tlačítko Přístupnost."</string>
+    <string name="accessibility_button_prompt_text" msgid="1176658502969738564">"Určete, jakou službu aktivujete klepnutím na tlačítko Přístupnost:"</string>
+    <string name="accessibility_gesture_prompt_text" msgid="8259145549733019401">"Určete, jakou službu aktivujete pomocí gesta přístupnosti (přejetí dvěma prsty ze spodní části obrazovky nahoru):"</string>
+    <string name="accessibility_gesture_3finger_prompt_text" msgid="1041435574275047665">"Určete, jakou službu aktivujete pomocí gesta přístupnosti (přejetí třemi prsty ze spodní části obrazovky nahoru):"</string>
+    <string name="accessibility_button_instructional_text" msgid="7003212763213614833">"Chcete-li přepnout mezi službami, podržte tlačítko Přístupnost."</string>
+    <string name="accessibility_gesture_instructional_text" msgid="5261788874937410950">"Chcete-li přepnout mezi službami, přejeďte nahoru dvěma prsty a podržte je."</string>
+    <string name="accessibility_gesture_3finger_instructional_text" msgid="4969448938984394550">"Chcete-li přepnout mezi službami, přejeďte nahoru třemi prsty a podržte je."</string>
     <string name="accessibility_magnification_chooser_text" msgid="1227146738764986237">"Zvětšení"</string>
     <string name="user_switched" msgid="3768006783166984410">"Aktuální uživatel je <xliff:g id="NAME">%1$s</xliff:g>."</string>
     <string name="user_switching_message" msgid="2871009331809089783">"Přepínání na účet <xliff:g id="NAME">%1$s</xliff:g>…"</string>
diff --git a/core/res/res/values-da/strings.xml b/core/res/res/values-da/strings.xml
index c2e8f6b..a933520 100644
--- a/core/res/res/values-da/strings.xml
+++ b/core/res/res/values-da/strings.xml
@@ -131,6 +131,7 @@
     <!-- no translation found for wfcSpnFormat_spn (4998685024207291232) -->
     <skip />
     <string name="wfcSpnFormat_spn_wifi_calling" msgid="136001023263502280">"Wi-Fi-opkald via <xliff:g id="SPN">%s</xliff:g>"</string>
+    <string name="wfcSpnFormat_spn_wifi_calling_vo_hyphen" msgid="1730997175789582756">"<xliff:g id="SPN">%s</xliff:g>-opkald via Wi-Fi"</string>
     <string name="wfcSpnFormat_wlan_call" msgid="2533371081782489793">"WLAN-opkald"</string>
     <string name="wfcSpnFormat_spn_wlan_call" msgid="2315240198303197168">"WLAN-opkald via <xliff:g id="SPN">%s</xliff:g>"</string>
     <string name="wfcSpnFormat_spn_wifi" msgid="6546481665561961938">"Wi-Fi via <xliff:g id="SPN">%s</xliff:g>"</string>
@@ -1357,8 +1358,7 @@
     <string name="test_harness_mode_notification_message" msgid="1343197173054407119">"Gendan fabriksindstillingerne for at deaktivere tilstanden Testsele."</string>
     <string name="usb_contaminant_detected_title" msgid="7136400633704058349">"Væske eller snavs i USB-porten"</string>
     <string name="usb_contaminant_detected_message" msgid="832337061059487250">"USB-porten deaktiveres automatisk. Tryk for at få flere oplysninger."</string>
-    <!-- no translation found for usb_contaminant_not_detected_title (7708281124088684821) -->
-    <skip />
+    <string name="usb_contaminant_not_detected_title" msgid="7708281124088684821">"USB-porten kan bruges"</string>
     <string name="usb_contaminant_not_detected_message" msgid="2415791798244545292">"Telefonen registrerer ikke længere væske og snavs."</string>
     <string name="taking_remote_bugreport_notification_title" msgid="6742483073875060934">"Opretter fejlrapport…"</string>
     <string name="share_remote_bugreport_notification_title" msgid="4987095013583691873">"Vil du dele fejlrapporten?"</string>
@@ -1612,8 +1612,6 @@
     <string name="display_manager_overlay_display_name" msgid="5142365982271620716">"Overlejring nr. <xliff:g id="ID">%1$d</xliff:g>"</string>
     <string name="display_manager_overlay_display_title" msgid="652124517672257172">"<xliff:g id="NAME">%1$s</xliff:g>: <xliff:g id="WIDTH">%2$d</xliff:g> x <xliff:g id="HEIGHT">%3$d</xliff:g>, <xliff:g id="DPI">%4$d</xliff:g> dpi"</string>
     <string name="display_manager_overlay_display_secure_suffix" msgid="6022119702628572080">", sikker"</string>
-    <string name="activity_starter_block_bg_activity_starts_permissive" msgid="6995473033438879646">"Denne opstart af aktivitet i baggrunden fra <xliff:g id="PACKAGENAME">%1$s</xliff:g> blokeres i fremtidige Q-builds. Se g.co/dev/bgblock."</string>
-    <string name="activity_starter_block_bg_activity_starts_enforcing" msgid="3317816771072146229">"Opstart af aktivitet i baggrunden fra <xliff:g id="PACKAGENAME">%1$s</xliff:g> er blokeret. Se g.co/dev/bgblock."</string>
     <string name="kg_forgot_pattern_button_text" msgid="8852021467868220608">"Glemt mønster"</string>
     <string name="kg_wrong_pattern" msgid="1850806070801358830">"Forkert mønster"</string>
     <string name="kg_wrong_password" msgid="2333281762128113157">"Forkert adgangskode"</string>
@@ -1667,8 +1665,12 @@
     <string name="accessibility_shortcut_enabling_service" msgid="7771852911861522636">"Genvejen til hjælpefunktioner aktiverede <xliff:g id="SERVICE_NAME">%1$s</xliff:g>"</string>
     <string name="accessibility_shortcut_disabling_service" msgid="2747243438223109821">"Genvejen til hjælpefunktioner deaktiverede <xliff:g id="SERVICE_NAME">%1$s</xliff:g>"</string>
     <string name="accessibility_shortcut_spoken_feedback" msgid="8376923232350078434">"Hold begge lydstyrkeknapper nede i tre sekunder for at bruge <xliff:g id="SERVICE_NAME">%1$s</xliff:g>"</string>
-    <string name="accessibility_button_prompt_text" msgid="4234556536456854251">"Vælg, hvilken funktion du vil bruge, når du trykker på knappen Hjælpefunktioner:"</string>
-    <string name="accessibility_button_instructional_text" msgid="6942300463612999993">"Tryk på knappen Hjælpefunktioner, og hold fingeren nede for at skifte funktion."</string>
+    <string name="accessibility_button_prompt_text" msgid="1176658502969738564">"Vælg, hvilken funktion du vil bruge, når du trykker på knappen Hjælpefunktioner:"</string>
+    <string name="accessibility_gesture_prompt_text" msgid="8259145549733019401">"Vælg, hvilken funktion du vil bruge, når du laver bevægelsen for hjælpefunktioner (stryger opad fra bunden af skærmen med to fingre):"</string>
+    <string name="accessibility_gesture_3finger_prompt_text" msgid="1041435574275047665">"Vælg, hvilken funktion du vil bruge, når du laver bevægelsen for hjælpefunktioner (stryger opad fra bunden af skærmen med tre fingre):"</string>
+    <string name="accessibility_button_instructional_text" msgid="7003212763213614833">"Du kan skifte mellem funktioner ved at holde knappen Hjælpefunktioner nede."</string>
+    <string name="accessibility_gesture_instructional_text" msgid="5261788874937410950">"Du kan skifte mellem funktioner ved at stryge opad med to fingre og holde dem nede."</string>
+    <string name="accessibility_gesture_3finger_instructional_text" msgid="4969448938984394550">"Du kan skifte mellem funktioner ved at stryge opad med tre fingre og holde dem nede."</string>
     <string name="accessibility_magnification_chooser_text" msgid="1227146738764986237">"Forstørrelse"</string>
     <string name="user_switched" msgid="3768006783166984410">"Nuværende bruger <xliff:g id="NAME">%1$s</xliff:g>."</string>
     <string name="user_switching_message" msgid="2871009331809089783">"Skifter til <xliff:g id="NAME">%1$s</xliff:g>…"</string>
@@ -1886,7 +1888,7 @@
     <string name="user_creation_adding" msgid="4482658054622099197">"Vil du give <xliff:g id="APP">%1$s</xliff:g> tilladelse til at oprette en ny bruger med <xliff:g id="ACCOUNT">%2$s</xliff:g> (der findes allerede en bruger med denne konto)?"</string>
     <string name="language_selection_title" msgid="2680677278159281088">"Tilføj et sprog"</string>
     <string name="country_selection_title" msgid="2954859441620215513">"Områdeindstilling"</string>
-    <string name="search_language_hint" msgid="7042102592055108574">"Angiv sprogets navn"</string>
+    <string name="search_language_hint" msgid="7042102592055108574">"Angiv sprog"</string>
     <string name="language_picker_section_suggested" msgid="8414489646861640885">"Foreslået"</string>
     <string name="language_picker_section_all" msgid="3097279199511617537">"Alle sprog"</string>
     <string name="region_picker_section_all" msgid="8966316787153001779">"Alle områder"</string>
@@ -1980,7 +1982,7 @@
     <string name="harmful_app_warning_title" msgid="8982527462829423432">"Der er registreret en skadelig app"</string>
     <string name="slices_permission_request" msgid="8484943441501672932">"<xliff:g id="APP_0">%1$s</xliff:g> anmoder om tilladelse til at vise eksempler fra <xliff:g id="APP_2">%2$s</xliff:g>"</string>
     <string name="screenshot_edit" msgid="7867478911006447565">"Rediger"</string>
-    <string name="volume_dialog_ringer_guidance_vibrate" msgid="8902050240801159042">"Telefonen vil vibrere ved opkald og notifikationer"</string>
+    <string name="volume_dialog_ringer_guidance_vibrate" msgid="8902050240801159042">"Telefonen vibrerer ved opkald og notifikationer"</string>
     <string name="volume_dialog_ringer_guidance_silent" msgid="2128975224280276122">"Der afspilles ikke lyd ved opkald og notifikationer"</string>
     <string name="notification_channel_system_changes" msgid="5072715579030948646">"Systemændringer"</string>
     <string name="notification_channel_do_not_disturb" msgid="6766940333105743037">"Forstyr ikke"</string>
diff --git a/core/res/res/values-de/strings.xml b/core/res/res/values-de/strings.xml
index a6e8997..9c14788 100644
--- a/core/res/res/values-de/strings.xml
+++ b/core/res/res/values-de/strings.xml
@@ -131,6 +131,7 @@
     <!-- no translation found for wfcSpnFormat_spn (4998685024207291232) -->
     <skip />
     <string name="wfcSpnFormat_spn_wifi_calling" msgid="136001023263502280">"<xliff:g id="SPN">%s</xliff:g> WLAN-Telefonie"</string>
+    <string name="wfcSpnFormat_spn_wifi_calling_vo_hyphen" msgid="1730997175789582756">"<xliff:g id="SPN">%s</xliff:g> WLAN-Telefonie"</string>
     <string name="wfcSpnFormat_wlan_call" msgid="2533371081782489793">"WLAN-Anruf"</string>
     <string name="wfcSpnFormat_spn_wlan_call" msgid="2315240198303197168">"<xliff:g id="SPN">%s</xliff:g> WLAN-Anruf"</string>
     <string name="wfcSpnFormat_spn_wifi" msgid="6546481665561961938">"<xliff:g id="SPN">%s</xliff:g> WLAN"</string>
@@ -1357,8 +1358,7 @@
     <string name="test_harness_mode_notification_message" msgid="1343197173054407119">"Setz das Gerät auf die Werkseinstellungen zurück, um den Test-Harnischmodus zu deaktivieren."</string>
     <string name="usb_contaminant_detected_title" msgid="7136400633704058349">"Flüssigkeiten oder Fremdkörper im USB-Port"</string>
     <string name="usb_contaminant_detected_message" msgid="832337061059487250">"Der USB-Port wird automatisch deaktiviert. Für weitere Informationen tippen."</string>
-    <!-- no translation found for usb_contaminant_not_detected_title (7708281124088684821) -->
-    <skip />
+    <string name="usb_contaminant_not_detected_title" msgid="7708281124088684821">"USB-Port kann wieder verwendet werden"</string>
     <string name="usb_contaminant_not_detected_message" msgid="2415791798244545292">"Das Smartphone erkennt keine Flüssigkeiten oder Fremdkörper mehr."</string>
     <string name="taking_remote_bugreport_notification_title" msgid="6742483073875060934">"Fehlerbericht wird abgerufen…"</string>
     <string name="share_remote_bugreport_notification_title" msgid="4987095013583691873">"Fehlerbericht teilen?"</string>
@@ -1612,8 +1612,6 @@
     <string name="display_manager_overlay_display_name" msgid="5142365982271620716">"Overlay-Nr. <xliff:g id="ID">%1$d</xliff:g>"</string>
     <string name="display_manager_overlay_display_title" msgid="652124517672257172">"<xliff:g id="NAME">%1$s</xliff:g>: <xliff:g id="WIDTH">%2$d</xliff:g> x <xliff:g id="HEIGHT">%3$d</xliff:g>, <xliff:g id="DPI">%4$d</xliff:g> dpi"</string>
     <string name="display_manager_overlay_display_secure_suffix" msgid="6022119702628572080">", sicher"</string>
-    <string name="activity_starter_block_bg_activity_starts_permissive" msgid="6995473033438879646">"Der Start dieser Hintergrundaktivität aus <xliff:g id="PACKAGENAME">%1$s</xliff:g> wird in künftigen Q-Builds blockiert. Weitere Informationen findest du unter g.co/dev/bgblock."</string>
-    <string name="activity_starter_block_bg_activity_starts_enforcing" msgid="3317816771072146229">"Der Start der Hintergrundaktivität aus <xliff:g id="PACKAGENAME">%1$s</xliff:g> wurde blockiert. Weitere Informationen findest du unter g.co/dev/bgblock."</string>
     <string name="kg_forgot_pattern_button_text" msgid="8852021467868220608">"Muster vergessen"</string>
     <string name="kg_wrong_pattern" msgid="1850806070801358830">"Falsches Muster"</string>
     <string name="kg_wrong_password" msgid="2333281762128113157">"Falsches Passwort"</string>
@@ -1667,8 +1665,12 @@
     <string name="accessibility_shortcut_enabling_service" msgid="7771852911861522636">"<xliff:g id="SERVICE_NAME">%1$s</xliff:g> wurde durch die Bedienungshilfenverknüpfung aktiviert"</string>
     <string name="accessibility_shortcut_disabling_service" msgid="2747243438223109821">"<xliff:g id="SERVICE_NAME">%1$s</xliff:g> wurde durch die Bedienungshilfenverknüpfung deaktiviert"</string>
     <string name="accessibility_shortcut_spoken_feedback" msgid="8376923232350078434">"Halten Sie beide Lautstärketasten drei Sekunden lang gedrückt, um <xliff:g id="SERVICE_NAME">%1$s</xliff:g> zu verwenden"</string>
-    <string name="accessibility_button_prompt_text" msgid="4234556536456854251">"Wähle eine Funktion aus, die verwendet wird, wenn du auf die Schaltfläche für die Bedienungshilfen tippst:"</string>
-    <string name="accessibility_button_instructional_text" msgid="6942300463612999993">"Um die Funktionen zu ändern, halte die Schaltfläche für die Bedienungshilfen gedrückt."</string>
+    <string name="accessibility_button_prompt_text" msgid="1176658502969738564">"Wähle einen Dienst aus, der verwendet wird, wenn du auf die Schaltfläche für die Bedienungshilfen tippst:"</string>
+    <string name="accessibility_gesture_prompt_text" msgid="8259145549733019401">"Wähle einen Dienst aus, der mit der Bewegung für die Bedienungshilfen verwendet wird (mit zwei Fingern vom unteren Bildschirmrand nach oben wischen):"</string>
+    <string name="accessibility_gesture_3finger_prompt_text" msgid="1041435574275047665">"Wähle einen Dienst aus, der mit der Bewegung für die Bedienungshilfen verwendet wird (mit drei Fingern vom unteren Bildschirmrand nach oben wischen):"</string>
+    <string name="accessibility_button_instructional_text" msgid="7003212763213614833">"Wenn du zwischen den Diensten wechseln möchtest, halte die Schaltfläche für die Bedienungshilfen gedrückt."</string>
+    <string name="accessibility_gesture_instructional_text" msgid="5261788874937410950">"Wenn du zwischen den Diensten wechseln möchtest, wische mit zwei Fingern nach oben und halte sie gedrückt."</string>
+    <string name="accessibility_gesture_3finger_instructional_text" msgid="4969448938984394550">"Wenn du zwischen den Diensten wechseln möchtest, wische mit drei Fingern nach oben und halte sie gedrückt."</string>
     <string name="accessibility_magnification_chooser_text" msgid="1227146738764986237">"Vergrößerung"</string>
     <string name="user_switched" msgid="3768006783166984410">"Aktueller Nutzer <xliff:g id="NAME">%1$s</xliff:g>"</string>
     <string name="user_switching_message" msgid="2871009331809089783">"Wechseln zu <xliff:g id="NAME">%1$s</xliff:g>…"</string>
diff --git a/core/res/res/values-el/strings.xml b/core/res/res/values-el/strings.xml
index 70a6681..d8d68ca 100644
--- a/core/res/res/values-el/strings.xml
+++ b/core/res/res/values-el/strings.xml
@@ -131,6 +131,7 @@
     <!-- no translation found for wfcSpnFormat_spn (4998685024207291232) -->
     <skip />
     <string name="wfcSpnFormat_spn_wifi_calling" msgid="136001023263502280">"Κλήση Wi-Fi <xliff:g id="SPN">%s</xliff:g>"</string>
+    <string name="wfcSpnFormat_spn_wifi_calling_vo_hyphen" msgid="1730997175789582756">"Κλήση Wi-Fi <xliff:g id="SPN">%s</xliff:g>"</string>
     <string name="wfcSpnFormat_wlan_call" msgid="2533371081782489793">"Κλήση μέσω WLAN"</string>
     <string name="wfcSpnFormat_spn_wlan_call" msgid="2315240198303197168">"Κλήση μέσω WLAN <xliff:g id="SPN">%s</xliff:g>"</string>
     <string name="wfcSpnFormat_spn_wifi" msgid="6546481665561961938">"<xliff:g id="SPN">%s</xliff:g> Wi-Fi"</string>
@@ -1611,8 +1612,6 @@
     <string name="display_manager_overlay_display_name" msgid="5142365982271620716">"Επικάλυψη #<xliff:g id="ID">%1$d</xliff:g>"</string>
     <string name="display_manager_overlay_display_title" msgid="652124517672257172">"<xliff:g id="NAME">%1$s</xliff:g>: <xliff:g id="WIDTH">%2$d</xliff:g>x<xliff:g id="HEIGHT">%3$d</xliff:g>, <xliff:g id="DPI">%4$d</xliff:g> dpi"</string>
     <string name="display_manager_overlay_display_secure_suffix" msgid="6022119702628572080">", ασφαλές"</string>
-    <string name="activity_starter_block_bg_activity_starts_permissive" msgid="6995473033438879646">"Αυτή η έναρξη δραστηριότητας παρασκηνίου από το <xliff:g id="PACKAGENAME">%1$s</xliff:g> θα αποκλειστεί σε μελλοντικές εκδόσεις του Q. Ανατρέξτε στο g.co/dev/bgblock."</string>
-    <string name="activity_starter_block_bg_activity_starts_enforcing" msgid="3317816771072146229">"Η έναρξη δραστηριότητας παρασκηνίου από το <xliff:g id="PACKAGENAME">%1$s</xliff:g> αποκλείστηκε. Ανατρέξτε στο g.co/dev/bgblock."</string>
     <string name="kg_forgot_pattern_button_text" msgid="8852021467868220608">"Ξεχάσατε το μοτίβο"</string>
     <string name="kg_wrong_pattern" msgid="1850806070801358830">"Λάθος μοτίβο"</string>
     <string name="kg_wrong_password" msgid="2333281762128113157">"Λανθασμένος κωδικός πρόσβασης"</string>
@@ -1666,8 +1665,12 @@
     <string name="accessibility_shortcut_enabling_service" msgid="7771852911861522636">"Η συντόμευση προσβασιμότητας ενεργοποίησε την υπηρεσία <xliff:g id="SERVICE_NAME">%1$s</xliff:g>"</string>
     <string name="accessibility_shortcut_disabling_service" msgid="2747243438223109821">"Η συντόμευση προσβασιμότητας απενεργοποίησε την υπηρεσία <xliff:g id="SERVICE_NAME">%1$s</xliff:g>"</string>
     <string name="accessibility_shortcut_spoken_feedback" msgid="8376923232350078434">"Πατήστε παρατεταμένα και τα δύο κουμπιά έντασης ήχου για τρία δευτερόλεπτα, ώστε να χρησιμοποιήσετε την υπηρεσία <xliff:g id="SERVICE_NAME">%1$s</xliff:g>"</string>
-    <string name="accessibility_button_prompt_text" msgid="4234556536456854251">"Επιλέξτε μια λειτουργία που θα χρησιμοποιείται κατά το πάτημα του κουμπιού \"Προσβασιμότητα\"."</string>
-    <string name="accessibility_button_instructional_text" msgid="6942300463612999993">"Για να αλλάξετε λειτουργίες, αγγίξτε παρατεταμένα το κουμπί \"Προσβασιμότητα\"."</string>
+    <string name="accessibility_button_prompt_text" msgid="1176658502969738564">"Επιλέξτε μια υπηρεσία που θα χρησιμοποιείται κατά το πάτημα του κουμπιού προσβασιμότητας:"</string>
+    <string name="accessibility_gesture_prompt_text" msgid="8259145549733019401">"Επιλέξτε μια υπηρεσία που θα χρησιμοποιείται με την κίνηση προσβασιμότητας (σύρετε με δύο δάχτυλα προς τα επάνω από το κάτω μέρος της οθόνης):"</string>
+    <string name="accessibility_gesture_3finger_prompt_text" msgid="1041435574275047665">"Επιλέξτε μια υπηρεσία που θα χρησιμοποιείται με την κίνηση προσβασιμότητας (σύρετε με τρία δάχτυλα προς τα επάνω από το κάτω μέρος της οθόνης):"</string>
+    <string name="accessibility_button_instructional_text" msgid="7003212763213614833">"Για εναλλαγή μεταξύ υπηρεσιών, αγγίξτε παρατεταμένα το κουμπί προσβασιμότητας."</string>
+    <string name="accessibility_gesture_instructional_text" msgid="5261788874937410950">"Για εναλλαγή μεταξύ υπηρεσιών, σύρετε παρατεταμένα με δύο δάχτυλα προς τα επάνω."</string>
+    <string name="accessibility_gesture_3finger_instructional_text" msgid="4969448938984394550">"Για εναλλαγή μεταξύ υπηρεσιών, σύρετε παρατεταμένα με τρία δάχτυλα προς τα επάνω."</string>
     <string name="accessibility_magnification_chooser_text" msgid="1227146738764986237">"Μεγιστοποίηση"</string>
     <string name="user_switched" msgid="3768006783166984410">"Τρέχων χρήστης <xliff:g id="NAME">%1$s</xliff:g>."</string>
     <string name="user_switching_message" msgid="2871009331809089783">"Εναλλαγή σε <xliff:g id="NAME">%1$s</xliff:g>…"</string>
diff --git a/core/res/res/values-en-rAU/strings.xml b/core/res/res/values-en-rAU/strings.xml
index 82972d9..c48a1fd 100644
--- a/core/res/res/values-en-rAU/strings.xml
+++ b/core/res/res/values-en-rAU/strings.xml
@@ -131,6 +131,7 @@
     <!-- no translation found for wfcSpnFormat_spn (4998685024207291232) -->
     <skip />
     <string name="wfcSpnFormat_spn_wifi_calling" msgid="136001023263502280">"<xliff:g id="SPN">%s</xliff:g> Wi-Fi Calling"</string>
+    <string name="wfcSpnFormat_spn_wifi_calling_vo_hyphen" msgid="1730997175789582756">"<xliff:g id="SPN">%s</xliff:g> Wi-Fi calling"</string>
     <string name="wfcSpnFormat_wlan_call" msgid="2533371081782489793">"WLAN call"</string>
     <string name="wfcSpnFormat_spn_wlan_call" msgid="2315240198303197168">"<xliff:g id="SPN">%s</xliff:g> WLAN Call"</string>
     <string name="wfcSpnFormat_spn_wifi" msgid="6546481665561961938">"<xliff:g id="SPN">%s</xliff:g> Wi-Fi"</string>
@@ -1611,8 +1612,6 @@
     <string name="display_manager_overlay_display_name" msgid="5142365982271620716">"Overlay #<xliff:g id="ID">%1$d</xliff:g>"</string>
     <string name="display_manager_overlay_display_title" msgid="652124517672257172">"<xliff:g id="NAME">%1$s</xliff:g>: <xliff:g id="WIDTH">%2$d</xliff:g>x<xliff:g id="HEIGHT">%3$d</xliff:g>, <xliff:g id="DPI">%4$d</xliff:g> dpi"</string>
     <string name="display_manager_overlay_display_secure_suffix" msgid="6022119702628572080">", secure"</string>
-    <string name="activity_starter_block_bg_activity_starts_permissive" msgid="6995473033438879646">"This background activity start from <xliff:g id="PACKAGENAME">%1$s</xliff:g> will be blocked in future Q builds. See g.co/dev/bgblock."</string>
-    <string name="activity_starter_block_bg_activity_starts_enforcing" msgid="3317816771072146229">"Background activity start from <xliff:g id="PACKAGENAME">%1$s</xliff:g> blocked. See g.co/dev/bgblock."</string>
     <string name="kg_forgot_pattern_button_text" msgid="8852021467868220608">"Forgot Pattern"</string>
     <string name="kg_wrong_pattern" msgid="1850806070801358830">"Wrong Pattern"</string>
     <string name="kg_wrong_password" msgid="2333281762128113157">"Wrong Password"</string>
@@ -1666,8 +1665,12 @@
     <string name="accessibility_shortcut_enabling_service" msgid="7771852911861522636">"Accessibility Shortcut turned <xliff:g id="SERVICE_NAME">%1$s</xliff:g> on"</string>
     <string name="accessibility_shortcut_disabling_service" msgid="2747243438223109821">"Accessibility Shortcut turned <xliff:g id="SERVICE_NAME">%1$s</xliff:g> off"</string>
     <string name="accessibility_shortcut_spoken_feedback" msgid="8376923232350078434">"Press and hold both volume keys for three seconds to use <xliff:g id="SERVICE_NAME">%1$s</xliff:g>"</string>
-    <string name="accessibility_button_prompt_text" msgid="4234556536456854251">"Choose a feature to use when you tap the Accessibility button:"</string>
-    <string name="accessibility_button_instructional_text" msgid="6942300463612999993">"To change features, touch &amp; hold the Accessibility button."</string>
+    <string name="accessibility_button_prompt_text" msgid="1176658502969738564">"Choose a service to use when you tap the accessibility button:"</string>
+    <string name="accessibility_gesture_prompt_text" msgid="8259145549733019401">"Choose a service to use with the accessibility gesture (swipe up from the bottom of the screen with two fingers):"</string>
+    <string name="accessibility_gesture_3finger_prompt_text" msgid="1041435574275047665">"Choose a service to use with the accessibility gesture (swipe up from the bottom of the screen with three fingers):"</string>
+    <string name="accessibility_button_instructional_text" msgid="7003212763213614833">"To switch between services, touch &amp; hold the accessibility button."</string>
+    <string name="accessibility_gesture_instructional_text" msgid="5261788874937410950">"To switch between services, swipe up with two fingers and hold."</string>
+    <string name="accessibility_gesture_3finger_instructional_text" msgid="4969448938984394550">"To switch between services, swipe up with three fingers and hold."</string>
     <string name="accessibility_magnification_chooser_text" msgid="1227146738764986237">"Magnification"</string>
     <string name="user_switched" msgid="3768006783166984410">"Current user <xliff:g id="NAME">%1$s</xliff:g>."</string>
     <string name="user_switching_message" msgid="2871009331809089783">"Switching to <xliff:g id="NAME">%1$s</xliff:g>…"</string>
diff --git a/core/res/res/values-en-rCA/strings.xml b/core/res/res/values-en-rCA/strings.xml
index 0ededb8..6f28685 100644
--- a/core/res/res/values-en-rCA/strings.xml
+++ b/core/res/res/values-en-rCA/strings.xml
@@ -131,6 +131,7 @@
     <!-- no translation found for wfcSpnFormat_spn (4998685024207291232) -->
     <skip />
     <string name="wfcSpnFormat_spn_wifi_calling" msgid="136001023263502280">"<xliff:g id="SPN">%s</xliff:g> Wi-Fi Calling"</string>
+    <string name="wfcSpnFormat_spn_wifi_calling_vo_hyphen" msgid="1730997175789582756">"<xliff:g id="SPN">%s</xliff:g> Wi-Fi calling"</string>
     <string name="wfcSpnFormat_wlan_call" msgid="2533371081782489793">"WLAN call"</string>
     <string name="wfcSpnFormat_spn_wlan_call" msgid="2315240198303197168">"<xliff:g id="SPN">%s</xliff:g> WLAN Call"</string>
     <string name="wfcSpnFormat_spn_wifi" msgid="6546481665561961938">"<xliff:g id="SPN">%s</xliff:g> Wi-Fi"</string>
@@ -1611,8 +1612,6 @@
     <string name="display_manager_overlay_display_name" msgid="5142365982271620716">"Overlay #<xliff:g id="ID">%1$d</xliff:g>"</string>
     <string name="display_manager_overlay_display_title" msgid="652124517672257172">"<xliff:g id="NAME">%1$s</xliff:g>: <xliff:g id="WIDTH">%2$d</xliff:g>x<xliff:g id="HEIGHT">%3$d</xliff:g>, <xliff:g id="DPI">%4$d</xliff:g> dpi"</string>
     <string name="display_manager_overlay_display_secure_suffix" msgid="6022119702628572080">", secure"</string>
-    <string name="activity_starter_block_bg_activity_starts_permissive" msgid="6995473033438879646">"This background activity start from <xliff:g id="PACKAGENAME">%1$s</xliff:g> will be blocked in future Q builds. See g.co/dev/bgblock."</string>
-    <string name="activity_starter_block_bg_activity_starts_enforcing" msgid="3317816771072146229">"Background activity start from <xliff:g id="PACKAGENAME">%1$s</xliff:g> blocked. See g.co/dev/bgblock."</string>
     <string name="kg_forgot_pattern_button_text" msgid="8852021467868220608">"Forgot Pattern"</string>
     <string name="kg_wrong_pattern" msgid="1850806070801358830">"Wrong Pattern"</string>
     <string name="kg_wrong_password" msgid="2333281762128113157">"Wrong Password"</string>
@@ -1666,8 +1665,12 @@
     <string name="accessibility_shortcut_enabling_service" msgid="7771852911861522636">"Accessibility Shortcut turned <xliff:g id="SERVICE_NAME">%1$s</xliff:g> on"</string>
     <string name="accessibility_shortcut_disabling_service" msgid="2747243438223109821">"Accessibility Shortcut turned <xliff:g id="SERVICE_NAME">%1$s</xliff:g> off"</string>
     <string name="accessibility_shortcut_spoken_feedback" msgid="8376923232350078434">"Press and hold both volume keys for three seconds to use <xliff:g id="SERVICE_NAME">%1$s</xliff:g>"</string>
-    <string name="accessibility_button_prompt_text" msgid="4234556536456854251">"Choose a feature to use when you tap the Accessibility button:"</string>
-    <string name="accessibility_button_instructional_text" msgid="6942300463612999993">"To change features, touch &amp; hold the Accessibility button."</string>
+    <string name="accessibility_button_prompt_text" msgid="1176658502969738564">"Choose a service to use when you tap the accessibility button:"</string>
+    <string name="accessibility_gesture_prompt_text" msgid="8259145549733019401">"Choose a service to use with the accessibility gesture (swipe up from the bottom of the screen with two fingers):"</string>
+    <string name="accessibility_gesture_3finger_prompt_text" msgid="1041435574275047665">"Choose a service to use with the accessibility gesture (swipe up from the bottom of the screen with three fingers):"</string>
+    <string name="accessibility_button_instructional_text" msgid="7003212763213614833">"To switch between services, touch &amp; hold the accessibility button."</string>
+    <string name="accessibility_gesture_instructional_text" msgid="5261788874937410950">"To switch between services, swipe up with two fingers and hold."</string>
+    <string name="accessibility_gesture_3finger_instructional_text" msgid="4969448938984394550">"To switch between services, swipe up with three fingers and hold."</string>
     <string name="accessibility_magnification_chooser_text" msgid="1227146738764986237">"Magnification"</string>
     <string name="user_switched" msgid="3768006783166984410">"Current user <xliff:g id="NAME">%1$s</xliff:g>."</string>
     <string name="user_switching_message" msgid="2871009331809089783">"Switching to <xliff:g id="NAME">%1$s</xliff:g>…"</string>
diff --git a/core/res/res/values-en-rGB/strings.xml b/core/res/res/values-en-rGB/strings.xml
index 82972d9..c48a1fd 100644
--- a/core/res/res/values-en-rGB/strings.xml
+++ b/core/res/res/values-en-rGB/strings.xml
@@ -131,6 +131,7 @@
     <!-- no translation found for wfcSpnFormat_spn (4998685024207291232) -->
     <skip />
     <string name="wfcSpnFormat_spn_wifi_calling" msgid="136001023263502280">"<xliff:g id="SPN">%s</xliff:g> Wi-Fi Calling"</string>
+    <string name="wfcSpnFormat_spn_wifi_calling_vo_hyphen" msgid="1730997175789582756">"<xliff:g id="SPN">%s</xliff:g> Wi-Fi calling"</string>
     <string name="wfcSpnFormat_wlan_call" msgid="2533371081782489793">"WLAN call"</string>
     <string name="wfcSpnFormat_spn_wlan_call" msgid="2315240198303197168">"<xliff:g id="SPN">%s</xliff:g> WLAN Call"</string>
     <string name="wfcSpnFormat_spn_wifi" msgid="6546481665561961938">"<xliff:g id="SPN">%s</xliff:g> Wi-Fi"</string>
@@ -1611,8 +1612,6 @@
     <string name="display_manager_overlay_display_name" msgid="5142365982271620716">"Overlay #<xliff:g id="ID">%1$d</xliff:g>"</string>
     <string name="display_manager_overlay_display_title" msgid="652124517672257172">"<xliff:g id="NAME">%1$s</xliff:g>: <xliff:g id="WIDTH">%2$d</xliff:g>x<xliff:g id="HEIGHT">%3$d</xliff:g>, <xliff:g id="DPI">%4$d</xliff:g> dpi"</string>
     <string name="display_manager_overlay_display_secure_suffix" msgid="6022119702628572080">", secure"</string>
-    <string name="activity_starter_block_bg_activity_starts_permissive" msgid="6995473033438879646">"This background activity start from <xliff:g id="PACKAGENAME">%1$s</xliff:g> will be blocked in future Q builds. See g.co/dev/bgblock."</string>
-    <string name="activity_starter_block_bg_activity_starts_enforcing" msgid="3317816771072146229">"Background activity start from <xliff:g id="PACKAGENAME">%1$s</xliff:g> blocked. See g.co/dev/bgblock."</string>
     <string name="kg_forgot_pattern_button_text" msgid="8852021467868220608">"Forgot Pattern"</string>
     <string name="kg_wrong_pattern" msgid="1850806070801358830">"Wrong Pattern"</string>
     <string name="kg_wrong_password" msgid="2333281762128113157">"Wrong Password"</string>
@@ -1666,8 +1665,12 @@
     <string name="accessibility_shortcut_enabling_service" msgid="7771852911861522636">"Accessibility Shortcut turned <xliff:g id="SERVICE_NAME">%1$s</xliff:g> on"</string>
     <string name="accessibility_shortcut_disabling_service" msgid="2747243438223109821">"Accessibility Shortcut turned <xliff:g id="SERVICE_NAME">%1$s</xliff:g> off"</string>
     <string name="accessibility_shortcut_spoken_feedback" msgid="8376923232350078434">"Press and hold both volume keys for three seconds to use <xliff:g id="SERVICE_NAME">%1$s</xliff:g>"</string>
-    <string name="accessibility_button_prompt_text" msgid="4234556536456854251">"Choose a feature to use when you tap the Accessibility button:"</string>
-    <string name="accessibility_button_instructional_text" msgid="6942300463612999993">"To change features, touch &amp; hold the Accessibility button."</string>
+    <string name="accessibility_button_prompt_text" msgid="1176658502969738564">"Choose a service to use when you tap the accessibility button:"</string>
+    <string name="accessibility_gesture_prompt_text" msgid="8259145549733019401">"Choose a service to use with the accessibility gesture (swipe up from the bottom of the screen with two fingers):"</string>
+    <string name="accessibility_gesture_3finger_prompt_text" msgid="1041435574275047665">"Choose a service to use with the accessibility gesture (swipe up from the bottom of the screen with three fingers):"</string>
+    <string name="accessibility_button_instructional_text" msgid="7003212763213614833">"To switch between services, touch &amp; hold the accessibility button."</string>
+    <string name="accessibility_gesture_instructional_text" msgid="5261788874937410950">"To switch between services, swipe up with two fingers and hold."</string>
+    <string name="accessibility_gesture_3finger_instructional_text" msgid="4969448938984394550">"To switch between services, swipe up with three fingers and hold."</string>
     <string name="accessibility_magnification_chooser_text" msgid="1227146738764986237">"Magnification"</string>
     <string name="user_switched" msgid="3768006783166984410">"Current user <xliff:g id="NAME">%1$s</xliff:g>."</string>
     <string name="user_switching_message" msgid="2871009331809089783">"Switching to <xliff:g id="NAME">%1$s</xliff:g>…"</string>
diff --git a/core/res/res/values-en-rIN/strings.xml b/core/res/res/values-en-rIN/strings.xml
index 82972d9..c48a1fd 100644
--- a/core/res/res/values-en-rIN/strings.xml
+++ b/core/res/res/values-en-rIN/strings.xml
@@ -131,6 +131,7 @@
     <!-- no translation found for wfcSpnFormat_spn (4998685024207291232) -->
     <skip />
     <string name="wfcSpnFormat_spn_wifi_calling" msgid="136001023263502280">"<xliff:g id="SPN">%s</xliff:g> Wi-Fi Calling"</string>
+    <string name="wfcSpnFormat_spn_wifi_calling_vo_hyphen" msgid="1730997175789582756">"<xliff:g id="SPN">%s</xliff:g> Wi-Fi calling"</string>
     <string name="wfcSpnFormat_wlan_call" msgid="2533371081782489793">"WLAN call"</string>
     <string name="wfcSpnFormat_spn_wlan_call" msgid="2315240198303197168">"<xliff:g id="SPN">%s</xliff:g> WLAN Call"</string>
     <string name="wfcSpnFormat_spn_wifi" msgid="6546481665561961938">"<xliff:g id="SPN">%s</xliff:g> Wi-Fi"</string>
@@ -1611,8 +1612,6 @@
     <string name="display_manager_overlay_display_name" msgid="5142365982271620716">"Overlay #<xliff:g id="ID">%1$d</xliff:g>"</string>
     <string name="display_manager_overlay_display_title" msgid="652124517672257172">"<xliff:g id="NAME">%1$s</xliff:g>: <xliff:g id="WIDTH">%2$d</xliff:g>x<xliff:g id="HEIGHT">%3$d</xliff:g>, <xliff:g id="DPI">%4$d</xliff:g> dpi"</string>
     <string name="display_manager_overlay_display_secure_suffix" msgid="6022119702628572080">", secure"</string>
-    <string name="activity_starter_block_bg_activity_starts_permissive" msgid="6995473033438879646">"This background activity start from <xliff:g id="PACKAGENAME">%1$s</xliff:g> will be blocked in future Q builds. See g.co/dev/bgblock."</string>
-    <string name="activity_starter_block_bg_activity_starts_enforcing" msgid="3317816771072146229">"Background activity start from <xliff:g id="PACKAGENAME">%1$s</xliff:g> blocked. See g.co/dev/bgblock."</string>
     <string name="kg_forgot_pattern_button_text" msgid="8852021467868220608">"Forgot Pattern"</string>
     <string name="kg_wrong_pattern" msgid="1850806070801358830">"Wrong Pattern"</string>
     <string name="kg_wrong_password" msgid="2333281762128113157">"Wrong Password"</string>
@@ -1666,8 +1665,12 @@
     <string name="accessibility_shortcut_enabling_service" msgid="7771852911861522636">"Accessibility Shortcut turned <xliff:g id="SERVICE_NAME">%1$s</xliff:g> on"</string>
     <string name="accessibility_shortcut_disabling_service" msgid="2747243438223109821">"Accessibility Shortcut turned <xliff:g id="SERVICE_NAME">%1$s</xliff:g> off"</string>
     <string name="accessibility_shortcut_spoken_feedback" msgid="8376923232350078434">"Press and hold both volume keys for three seconds to use <xliff:g id="SERVICE_NAME">%1$s</xliff:g>"</string>
-    <string name="accessibility_button_prompt_text" msgid="4234556536456854251">"Choose a feature to use when you tap the Accessibility button:"</string>
-    <string name="accessibility_button_instructional_text" msgid="6942300463612999993">"To change features, touch &amp; hold the Accessibility button."</string>
+    <string name="accessibility_button_prompt_text" msgid="1176658502969738564">"Choose a service to use when you tap the accessibility button:"</string>
+    <string name="accessibility_gesture_prompt_text" msgid="8259145549733019401">"Choose a service to use with the accessibility gesture (swipe up from the bottom of the screen with two fingers):"</string>
+    <string name="accessibility_gesture_3finger_prompt_text" msgid="1041435574275047665">"Choose a service to use with the accessibility gesture (swipe up from the bottom of the screen with three fingers):"</string>
+    <string name="accessibility_button_instructional_text" msgid="7003212763213614833">"To switch between services, touch &amp; hold the accessibility button."</string>
+    <string name="accessibility_gesture_instructional_text" msgid="5261788874937410950">"To switch between services, swipe up with two fingers and hold."</string>
+    <string name="accessibility_gesture_3finger_instructional_text" msgid="4969448938984394550">"To switch between services, swipe up with three fingers and hold."</string>
     <string name="accessibility_magnification_chooser_text" msgid="1227146738764986237">"Magnification"</string>
     <string name="user_switched" msgid="3768006783166984410">"Current user <xliff:g id="NAME">%1$s</xliff:g>."</string>
     <string name="user_switching_message" msgid="2871009331809089783">"Switching to <xliff:g id="NAME">%1$s</xliff:g>…"</string>
diff --git a/core/res/res/values-en-rXC/strings.xml b/core/res/res/values-en-rXC/strings.xml
index bbededf..5182ccc 100644
--- a/core/res/res/values-en-rXC/strings.xml
+++ b/core/res/res/values-en-rXC/strings.xml
@@ -131,6 +131,7 @@
     <!-- no translation found for wfcSpnFormat_spn (4998685024207291232) -->
     <skip />
     <string name="wfcSpnFormat_spn_wifi_calling" msgid="136001023263502280">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‎‎‏‏‏‏‏‎‎‎‏‏‎‎‏‎‏‏‎‎‎‎‏‏‎‏‎‏‏‏‎‎‏‎‎‎‏‎‏‏‎‏‎‏‏‏‏‎‏‏‏‏‏‏‎‎‏‎‎‎‎‎‏‎‎‏‏‎<xliff:g id="SPN">%s</xliff:g>‎‏‎‎‏‏‏‎ Wi-Fi Calling‎‏‎‎‏‎"</string>
+    <string name="wfcSpnFormat_spn_wifi_calling_vo_hyphen" msgid="1730997175789582756">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‏‏‏‎‎‎‎‎‎‎‎‏‎‏‏‎‏‏‏‏‎‎‏‏‎‎‎‎‏‎‏‎‎‏‏‎‏‎‎‎‏‎‎‏‎‎‎‏‏‏‏‎‎‏‏‎‏‎‎‏‎‎‎‎‏‎‎‏‏‎<xliff:g id="SPN">%s</xliff:g>‎‏‎‎‏‏‏‎ WiFi Calling‎‏‎‎‏‎"</string>
     <string name="wfcSpnFormat_wlan_call" msgid="2533371081782489793">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‎‎‎‏‏‎‎‏‎‏‎‎‎‎‏‎‏‎‏‏‏‏‎‎‏‎‎‏‏‏‎‎‏‎‏‎‏‏‏‏‎‎‏‎‎‎‏‏‏‎‎‏‎‏‏‎‎‎‎‎‏‎WLAN Call‎‏‎‎‏‎"</string>
     <string name="wfcSpnFormat_spn_wlan_call" msgid="2315240198303197168">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‎‎‎‎‎‎‎‏‎‎‎‎‏‎‏‏‎‎‎‏‎‏‎‏‏‎‎‎‏‏‎‎‏‎‏‎‏‏‎‎‏‎‎‎‏‎‎‏‎‎‏‏‏‏‏‏‏‎‎‎‎‎‎‏‎‎‏‏‎<xliff:g id="SPN">%s</xliff:g>‎‏‎‎‏‏‏‎ WLAN Call‎‏‎‎‏‎"</string>
     <string name="wfcSpnFormat_spn_wifi" msgid="6546481665561961938">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‏‏‎‏‎‏‏‎‏‏‎‎‏‏‏‎‎‎‏‏‎‎‏‏‎‎‎‏‏‏‏‎‏‏‏‎‎‎‏‏‎‏‏‎‏‏‎‏‎‎‏‎‏‏‏‎‏‎‎‏‎‎‎‏‎‎‏‏‎<xliff:g id="SPN">%s</xliff:g>‎‏‎‎‏‏‏‎ Wi-Fi‎‏‎‎‏‎"</string>
@@ -1611,8 +1612,6 @@
     <string name="display_manager_overlay_display_name" msgid="5142365982271620716">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‎‎‏‏‏‎‏‎‏‏‏‎‏‎‏‎‏‏‎‏‎‏‎‎‏‏‏‎‏‏‎‎‎‏‏‏‎‎‏‎‏‏‎‏‎‎‏‎‎‎‏‏‎‎‏‏‎‏‏‎‎‎Overlay #‎‏‎‎‏‏‎<xliff:g id="ID">%1$d</xliff:g>‎‏‎‎‏‏‏‎‎‏‎‎‏‎"</string>
     <string name="display_manager_overlay_display_title" msgid="652124517672257172">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‎‏‎‎‏‎‎‎‎‏‏‎‎‏‏‎‎‏‏‏‏‏‏‎‎‏‎‏‏‎‎‏‏‎‎‎‏‎‎‏‎‏‏‎‏‏‎‎‎‎‏‏‎‏‎‎‏‎‏‎‎‎‎‏‎‎‏‏‎<xliff:g id="NAME">%1$s</xliff:g>‎‏‎‎‏‏‏‎: ‎‏‎‎‏‏‎<xliff:g id="WIDTH">%2$d</xliff:g>‎‏‎‎‏‏‏‎x‎‏‎‎‏‏‎<xliff:g id="HEIGHT">%3$d</xliff:g>‎‏‎‎‏‏‏‎, ‎‏‎‎‏‏‎<xliff:g id="DPI">%4$d</xliff:g>‎‏‎‎‏‏‏‎ dpi‎‏‎‎‏‎"</string>
     <string name="display_manager_overlay_display_secure_suffix" msgid="6022119702628572080">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‏‎‎‏‏‏‎‎‏‎‎‏‎‏‏‎‏‏‏‎‏‏‏‏‏‎‏‏‎‏‎‎‎‎‏‏‎‎‎‎‎‏‏‏‎‏‎‎‏‏‎‏‏‏‎‏‏‎‎‎‎‎, secure‎‏‎‎‏‎"</string>
-    <string name="activity_starter_block_bg_activity_starts_permissive" msgid="6995473033438879646">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‎‎‎‎‏‎‎‎‏‎‏‎‎‏‏‏‎‏‎‎‏‏‎‏‎‏‎‎‏‎‎‎‎‏‎‎‏‏‏‏‏‎‎‏‎‏‏‎‏‏‏‏‏‏‎‎‏‏‏‏‎‎This background activity start from ‎‏‎‎‏‏‎<xliff:g id="PACKAGENAME">%1$s</xliff:g>‎‏‎‎‏‏‏‎ will be blocked in future Q builds. See g.co/dev/bgblock.‎‏‎‎‏‎"</string>
-    <string name="activity_starter_block_bg_activity_starts_enforcing" msgid="3317816771072146229">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‎‏‏‏‎‎‎‎‎‏‎‏‏‎‏‎‎‎‎‎‎‏‏‎‎‎‏‏‎‎‏‎‏‎‏‎‏‏‎‎‏‎‏‏‎‏‎‏‏‏‎‏‏‎‎‏‏‎‏‎‏‎Background activity start from ‎‏‎‎‏‏‎<xliff:g id="PACKAGENAME">%1$s</xliff:g>‎‏‎‎‏‏‏‎ blocked. See g.co/dev/bgblock.‎‏‎‎‏‎"</string>
     <string name="kg_forgot_pattern_button_text" msgid="8852021467868220608">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‏‏‎‏‎‏‏‎‏‏‎‎‎‏‎‏‏‎‎‏‎‏‎‏‎‎‎‎‎‎‎‎‎‎‎‎‎‎‏‏‎‏‎‏‎‏‏‎‎‏‏‎‎‏‏‎‎‎‎‎‎‎Forgot Pattern‎‏‎‎‏‎"</string>
     <string name="kg_wrong_pattern" msgid="1850806070801358830">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‏‏‏‎‎‏‏‎‏‎‏‏‏‏‎‏‏‎‎‎‏‎‎‏‎‏‎‎‎‎‏‎‏‏‏‏‏‎‎‏‎‎‎‎‎‎‎‏‎‏‏‏‏‏‏‏‏‎‏‏‏‎‎Wrong Pattern‎‏‎‎‏‎"</string>
     <string name="kg_wrong_password" msgid="2333281762128113157">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‎‎‎‎‎‎‏‏‎‎‎‎‏‎‏‏‏‏‎‏‏‎‏‏‎‎‏‏‎‏‎‎‎‎‎‎‎‏‎‎‎‏‎‏‏‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‏‎Wrong Password‎‏‎‎‏‎"</string>
@@ -1666,8 +1665,12 @@
     <string name="accessibility_shortcut_enabling_service" msgid="7771852911861522636">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‎‏‎‏‏‏‏‎‏‏‎‏‏‎‎‏‎‏‎‏‏‎‎‎‎‏‎‏‏‏‏‎‏‏‎‏‎‎‎‎‏‎‏‏‏‎‏‏‎‎‎‎‎‏‏‎‎‏‏‎‎‎Accessibility Shortcut turned ‎‏‎‎‏‏‎<xliff:g id="SERVICE_NAME">%1$s</xliff:g>‎‏‎‎‏‏‏‎ on‎‏‎‎‏‎"</string>
     <string name="accessibility_shortcut_disabling_service" msgid="2747243438223109821">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‎‎‏‏‎‎‎‏‎‎‎‎‎‎‎‏‎‏‎‏‏‎‏‎‏‏‎‎‏‏‏‏‏‏‏‏‎‏‏‎‎‏‏‏‏‏‎‏‎‏‏‏‎‏‎‏‏‏‏‎‏‎Accessibility Shortcut turned ‎‏‎‎‏‏‎<xliff:g id="SERVICE_NAME">%1$s</xliff:g>‎‏‎‎‏‏‏‎ off‎‏‎‎‏‎"</string>
     <string name="accessibility_shortcut_spoken_feedback" msgid="8376923232350078434">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‏‎‏‎‎‎‏‎‎‎‎‎‎‏‏‎‎‏‏‏‏‎‏‎‎‏‏‎‎‎‎‎‎‎‏‏‎‏‏‏‏‎‎‎‏‏‎‎‎‎‏‎‏‏‏‏‎‎‎‏‎‎Press and hold both volume keys for three seconds to use ‎‏‎‎‏‏‎<xliff:g id="SERVICE_NAME">%1$s</xliff:g>‎‏‎‎‏‏‏‎‎‏‎‎‏‎"</string>
-    <string name="accessibility_button_prompt_text" msgid="4234556536456854251">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‏‏‎‏‎‏‏‎‎‎‏‎‎‎‎‏‎‏‎‏‎‏‎‏‏‏‎‏‏‏‏‏‏‏‎‎‎‏‏‎‏‎‎‎‏‏‎‏‏‏‎‏‎‏‏‏‎‏‎‏‏‎Choose a feature to use when you tap the Accessibility button:‎‏‎‎‏‎"</string>
-    <string name="accessibility_button_instructional_text" msgid="6942300463612999993">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‎‎‎‎‎‎‏‎‏‏‎‎‎‎‎‎‎‎‎‎‏‎‏‏‏‏‏‎‏‎‏‏‎‎‎‎‏‏‎‏‎‏‏‏‎‏‎‏‏‏‎‎‏‎‎‏‏‏‎‎‏‎To change features, touch &amp; hold the Accessibility button.‎‏‎‎‏‎"</string>
+    <string name="accessibility_button_prompt_text" msgid="1176658502969738564">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‏‏‎‎‎‎‎‏‎‏‎‏‎‎‎‏‎‏‎‏‎‎‏‎‏‎‏‏‎‎‏‎‎‏‏‎‏‏‎‏‏‏‎‏‎‎‎‏‎‎‎‏‎‏‎‏‎‎‎‏‎‎‎Choose a service to use when you tap the accessibility button:‎‏‎‎‏‎"</string>
+    <string name="accessibility_gesture_prompt_text" msgid="8259145549733019401">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‏‎‎‏‎‏‎‎‏‏‏‏‎‎‏‏‎‎‎‎‏‎‎‎‏‏‏‏‎‎‏‏‎‎‎‎‎‎‎‎‏‎‏‎‏‏‎‏‏‏‏‏‏‎‎‎‎‏‎‎‏‎Choose a service to use with the accessibility gesture (swipe up from the bottom of the screen with two fingers):‎‏‎‎‏‎"</string>
+    <string name="accessibility_gesture_3finger_prompt_text" msgid="1041435574275047665">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‎‏‏‏‎‎‏‏‏‎‎‏‏‏‏‏‎‏‏‎‎‎‎‏‎‎‎‏‏‎‎‎‏‎‏‎‏‎‎‎‏‏‏‏‎‏‎‎‎‎‎‎‎‏‏‏‏‎‎‎‏‎Choose a service to use with the accessibility gesture (swipe up from the bottom of the screen with three fingers):‎‏‎‎‏‎"</string>
+    <string name="accessibility_button_instructional_text" msgid="7003212763213614833">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‎‎‎‎‏‎‎‏‏‎‎‎‎‎‏‏‎‏‎‎‎‏‏‏‎‎‏‏‏‎‏‎‎‏‏‎‏‏‏‎‏‎‏‎‎‎‏‎‎‏‏‏‎‏‏‏‏‎‎‎‏‎To switch between services, touch &amp; hold the accessibility button.‎‏‎‎‏‎"</string>
+    <string name="accessibility_gesture_instructional_text" msgid="5261788874937410950">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‎‏‎‎‏‎‎‎‎‎‏‎‏‏‎‏‎‎‎‎‏‎‎‎‏‏‎‏‎‏‎‎‎‎‏‎‏‏‎‏‏‏‏‏‏‎‎‏‎‎‏‎‏‏‎‎‎‎‏‏‎‎To switch between services, swipe up with two fingers and hold.‎‏‎‎‏‎"</string>
+    <string name="accessibility_gesture_3finger_instructional_text" msgid="4969448938984394550">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‎‎‏‎‎‏‏‏‏‎‏‏‏‎‎‎‎‎‏‏‏‎‏‏‏‏‎‏‏‎‎‎‏‎‎‎‏‏‎‎‏‏‎‏‏‎‏‎‎‏‏‏‏‎‎‏‏‎‏‏‎‎To switch between services, swipe up with three fingers and hold.‎‏‎‎‏‎"</string>
     <string name="accessibility_magnification_chooser_text" msgid="1227146738764986237">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‏‏‎‎‎‏‎‎‎‎‎‏‏‏‏‎‏‏‎‎‏‏‎‏‏‏‎‏‎‏‎‎‎‎‏‎‏‏‎‏‎‏‏‏‎‏‏‎‏‏‎‏‏‏‎‏‏‏‏‏‎‏‎Magnification‎‏‎‎‏‎"</string>
     <string name="user_switched" msgid="3768006783166984410">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‏‎‏‎‎‎‏‎‎‏‎‏‎‏‎‏‎‎‏‏‎‎‎‏‏‎‏‎‎‏‎‎‏‏‏‎‏‏‏‏‎‏‏‏‎‎‎‏‏‎‎‎‎‏‏‎‏‏‎‏‎‎Current user ‎‏‎‎‏‏‎<xliff:g id="NAME">%1$s</xliff:g>‎‏‎‎‏‏‏‎.‎‏‎‎‏‎"</string>
     <string name="user_switching_message" msgid="2871009331809089783">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‎‎‏‏‏‏‏‎‏‎‏‏‏‏‏‎‏‏‏‏‏‏‏‎‎‎‏‏‎‏‎‏‎‏‎‎‏‎‏‎‎‏‏‏‏‏‏‏‏‏‎‎‎‏‏‏‏‎‏‏‏‎Switching to ‎‏‎‎‏‏‎<xliff:g id="NAME">%1$s</xliff:g>‎‏‎‎‏‏‏‎…‎‏‎‎‏‎"</string>
diff --git a/core/res/res/values-es-rUS/strings.xml b/core/res/res/values-es-rUS/strings.xml
index 6fef44c..59c185c 100644
--- a/core/res/res/values-es-rUS/strings.xml
+++ b/core/res/res/values-es-rUS/strings.xml
@@ -131,6 +131,7 @@
     <!-- no translation found for wfcSpnFormat_spn (4998685024207291232) -->
     <skip />
     <string name="wfcSpnFormat_spn_wifi_calling" msgid="136001023263502280">"Llamada por Wi-Fi de <xliff:g id="SPN">%s</xliff:g>"</string>
+    <string name="wfcSpnFormat_spn_wifi_calling_vo_hyphen" msgid="1730997175789582756">"Llamada por Wi-Fi de <xliff:g id="SPN">%s</xliff:g>"</string>
     <string name="wfcSpnFormat_wlan_call" msgid="2533371081782489793">"Llamada por WLAN"</string>
     <string name="wfcSpnFormat_spn_wlan_call" msgid="2315240198303197168">"Llamada por WLAN de <xliff:g id="SPN">%s</xliff:g>"</string>
     <string name="wfcSpnFormat_spn_wifi" msgid="6546481665561961938">"Wi-Fi de <xliff:g id="SPN">%s</xliff:g>"</string>
@@ -1357,8 +1358,7 @@
     <string name="test_harness_mode_notification_message" msgid="1343197173054407119">"Restablece la configuración de fábrica para inhabilitar el modo de agente de prueba."</string>
     <string name="usb_contaminant_detected_title" msgid="7136400633704058349">"Hay líquido o suciedad en el puerto USB"</string>
     <string name="usb_contaminant_detected_message" msgid="832337061059487250">"El puerto USB se inhabilitó automáticamente. Presiona para obtener más información."</string>
-    <!-- no translation found for usb_contaminant_not_detected_title (7708281124088684821) -->
-    <skip />
+    <string name="usb_contaminant_not_detected_title" msgid="7708281124088684821">"Se puede usar el puerto USB"</string>
     <string name="usb_contaminant_not_detected_message" msgid="2415791798244545292">"El teléfono ya no detecta líquidos o suciedad."</string>
     <string name="taking_remote_bugreport_notification_title" msgid="6742483073875060934">"Realizando un informe de errores…"</string>
     <string name="share_remote_bugreport_notification_title" msgid="4987095013583691873">"¿Compartir informe de errores?"</string>
@@ -1612,8 +1612,6 @@
     <string name="display_manager_overlay_display_name" msgid="5142365982271620716">"Superposición #<xliff:g id="ID">%1$d</xliff:g>"</string>
     <string name="display_manager_overlay_display_title" msgid="652124517672257172">"<xliff:g id="NAME">%1$s</xliff:g>: <xliff:g id="WIDTH">%2$d</xliff:g> x <xliff:g id="HEIGHT">%3$d</xliff:g>, <xliff:g id="DPI">%4$d</xliff:g> ppp"</string>
     <string name="display_manager_overlay_display_secure_suffix" msgid="6022119702628572080">", segura"</string>
-    <string name="activity_starter_block_bg_activity_starts_permissive" msgid="6995473033438879646">"En las próximas compilaciones de Q, se bloqueará el inicio de la actividad en segundo plano de <xliff:g id="PACKAGENAME">%1$s</xliff:g>. Consulta g.co/dev/bgblock."</string>
-    <string name="activity_starter_block_bg_activity_starts_enforcing" msgid="3317816771072146229">"Se bloqueó el inicio de la actividad en segundo plano de <xliff:g id="PACKAGENAME">%1$s</xliff:g>. Consulta g.co/dev/bgblock."</string>
     <string name="kg_forgot_pattern_button_text" msgid="8852021467868220608">"¿Olvidaste el patrón?"</string>
     <string name="kg_wrong_pattern" msgid="1850806070801358830">"Patrón incorrecto"</string>
     <string name="kg_wrong_password" msgid="2333281762128113157">"Contraseña incorrecta"</string>
@@ -1667,8 +1665,12 @@
     <string name="accessibility_shortcut_enabling_service" msgid="7771852911861522636">"El acceso directo de accesibilidad activó <xliff:g id="SERVICE_NAME">%1$s</xliff:g>"</string>
     <string name="accessibility_shortcut_disabling_service" msgid="2747243438223109821">"El acceso directo de accesibilidad desactivó <xliff:g id="SERVICE_NAME">%1$s</xliff:g>"</string>
     <string name="accessibility_shortcut_spoken_feedback" msgid="8376923232350078434">"Mantén presionadas ambas teclas de volumen durante tres segundos para usar <xliff:g id="SERVICE_NAME">%1$s</xliff:g>"</string>
-    <string name="accessibility_button_prompt_text" msgid="4234556536456854251">"Elige una función para usar cuando presionas el botón Accesibilidad:"</string>
-    <string name="accessibility_button_instructional_text" msgid="6942300463612999993">"Para cambiar funciones, mantén presionado el botón Accesibilidad."</string>
+    <string name="accessibility_button_prompt_text" msgid="1176658502969738564">"Elige un servicio para usar cuando presiones el botón de accesibilidad:"</string>
+    <string name="accessibility_gesture_prompt_text" msgid="8259145549733019401">"Elige un servicio para usar cuando realices el gesto de accesibilidad (deslizar dos dedos hacia arriba desde la parte inferior de la pantalla):"</string>
+    <string name="accessibility_gesture_3finger_prompt_text" msgid="1041435574275047665">"Elige un servicio para usar cuando realices el gesto de accesibilidad (deslizar tres dedos hacia arriba desde la parte inferior de la pantalla):"</string>
+    <string name="accessibility_button_instructional_text" msgid="7003212763213614833">"Para cambiar de servicio, mantén presionado el botón de accesibilidad."</string>
+    <string name="accessibility_gesture_instructional_text" msgid="5261788874937410950">"Para cambiar de servicio, desliza dos dedos hacia arriba y mantén presionado."</string>
+    <string name="accessibility_gesture_3finger_instructional_text" msgid="4969448938984394550">"Para cambiar de servicio, desliza tres dedos hacia arriba y mantén presionado."</string>
     <string name="accessibility_magnification_chooser_text" msgid="1227146738764986237">"Ampliación"</string>
     <string name="user_switched" msgid="3768006783166984410">"Usuario actual: <xliff:g id="NAME">%1$s</xliff:g>"</string>
     <string name="user_switching_message" msgid="2871009331809089783">"Cambiando a <xliff:g id="NAME">%1$s</xliff:g>…"</string>
diff --git a/core/res/res/values-es/strings.xml b/core/res/res/values-es/strings.xml
index 4a39018..db39bb5 100644
--- a/core/res/res/values-es/strings.xml
+++ b/core/res/res/values-es/strings.xml
@@ -131,6 +131,7 @@
     <!-- no translation found for wfcSpnFormat_spn (4998685024207291232) -->
     <skip />
     <string name="wfcSpnFormat_spn_wifi_calling" msgid="136001023263502280">"Llamada por Wi‑Fi de <xliff:g id="SPN">%s</xliff:g>"</string>
+    <string name="wfcSpnFormat_spn_wifi_calling_vo_hyphen" msgid="1730997175789582756">"<xliff:g id="SPN">%s</xliff:g> Llamada por Wi‑Fi"</string>
     <string name="wfcSpnFormat_wlan_call" msgid="2533371081782489793">"Llamada por WLAN"</string>
     <string name="wfcSpnFormat_spn_wlan_call" msgid="2315240198303197168">"Llamada por WLAN de <xliff:g id="SPN">%s</xliff:g>"</string>
     <string name="wfcSpnFormat_spn_wifi" msgid="6546481665561961938">"Wi‑Fi de <xliff:g id="SPN">%s</xliff:g>"</string>
@@ -1357,8 +1358,7 @@
     <string name="test_harness_mode_notification_message" msgid="1343197173054407119">"Restablece los ajustes de fábrica para inhabilitar el modo de agente de prueba."</string>
     <string name="usb_contaminant_detected_title" msgid="7136400633704058349">"Se ha detectado líquido o suciedad en el puerto USB"</string>
     <string name="usb_contaminant_detected_message" msgid="832337061059487250">"El puerto USB se ha inhabilitado automáticamente. Toca para obtener más información."</string>
-    <!-- no translation found for usb_contaminant_not_detected_title (7708281124088684821) -->
-    <skip />
+    <string name="usb_contaminant_not_detected_title" msgid="7708281124088684821">"Se puede utilizar el puerto USB"</string>
     <string name="usb_contaminant_not_detected_message" msgid="2415791798244545292">"El teléfono ya no detecta líquidos ni suciedad."</string>
     <string name="taking_remote_bugreport_notification_title" msgid="6742483073875060934">"Creando informe de errores…"</string>
     <string name="share_remote_bugreport_notification_title" msgid="4987095013583691873">"¿Compartir informe de errores?"</string>
@@ -1612,8 +1612,6 @@
     <string name="display_manager_overlay_display_name" msgid="5142365982271620716">"Superposición #<xliff:g id="ID">%1$d</xliff:g>"</string>
     <string name="display_manager_overlay_display_title" msgid="652124517672257172">"<xliff:g id="NAME">%1$s</xliff:g>: <xliff:g id="WIDTH">%2$d</xliff:g> x <xliff:g id="HEIGHT">%3$d</xliff:g>, <xliff:g id="DPI">%4$d</xliff:g> dpi"</string>
     <string name="display_manager_overlay_display_secure_suffix" msgid="6022119702628572080">", seguro"</string>
-    <string name="activity_starter_block_bg_activity_starts_permissive" msgid="6995473033438879646">"El inicio de la actividad en segundo plano de <xliff:g id="PACKAGENAME">%1$s</xliff:g> se bloqueará en las próximas compilaciones de Q. Accede a g.co/dev/bgblock."</string>
-    <string name="activity_starter_block_bg_activity_starts_enforcing" msgid="3317816771072146229">"Se ha bloqueado el inicio de la actividad en segundo plano de <xliff:g id="PACKAGENAME">%1$s</xliff:g>. Accede a g.co/dev/bgblock."</string>
     <string name="kg_forgot_pattern_button_text" msgid="8852021467868220608">"¿Has olvidado el patrón?"</string>
     <string name="kg_wrong_pattern" msgid="1850806070801358830">"El patrón es incorrecto"</string>
     <string name="kg_wrong_password" msgid="2333281762128113157">"Contraseña incorrecta"</string>
@@ -1667,8 +1665,12 @@
     <string name="accessibility_shortcut_enabling_service" msgid="7771852911861522636">"El acceso directo a accesibilidad ha activado <xliff:g id="SERVICE_NAME">%1$s</xliff:g>"</string>
     <string name="accessibility_shortcut_disabling_service" msgid="2747243438223109821">"El acceso directo a accesibilidad ha desactivado <xliff:g id="SERVICE_NAME">%1$s</xliff:g>"</string>
     <string name="accessibility_shortcut_spoken_feedback" msgid="8376923232350078434">"Para utilizar <xliff:g id="SERVICE_NAME">%1$s</xliff:g>, mantén pulsadas ambas teclas de volumen durante 3 segundos"</string>
-    <string name="accessibility_button_prompt_text" msgid="4234556536456854251">"Selecciona la función que se utilizará cuando toques el botón Accesibilidad:"</string>
-    <string name="accessibility_button_instructional_text" msgid="6942300463612999993">"Para cambiar las funciones, mantén pulsado el botón Accesibilidad."</string>
+    <string name="accessibility_button_prompt_text" msgid="1176658502969738564">"Selecciona el servicio que se utilizará cuando toques el botón Accesibilidad:"</string>
+    <string name="accessibility_gesture_prompt_text" msgid="8259145549733019401">"Elige el servicio que se utilizará con el gesto de accesibilidad (desliza dos dedos hacia arriba desde la parte inferior de la pantalla):"</string>
+    <string name="accessibility_gesture_3finger_prompt_text" msgid="1041435574275047665">"Elige el servicio que se utilizará con el gesto de accesibilidad (desliza tres dedos hacia arriba desde la parte inferior de la pantalla):"</string>
+    <string name="accessibility_button_instructional_text" msgid="7003212763213614833">"Para cambiar de un servicio a otro, mantén pulsado el botón de accesibilidad."</string>
+    <string name="accessibility_gesture_instructional_text" msgid="5261788874937410950">"Para cambiar de un servicio a otro, desliza dos dedos hacia arriba y mantén pulsada la pantalla."</string>
+    <string name="accessibility_gesture_3finger_instructional_text" msgid="4969448938984394550">"Para cambiar de un servicio a otro, desliza tres dedos hacia arriba y mantén pulsada la pantalla."</string>
     <string name="accessibility_magnification_chooser_text" msgid="1227146738764986237">"Ampliar"</string>
     <string name="user_switched" msgid="3768006783166984410">"Usuario actual: <xliff:g id="NAME">%1$s</xliff:g>"</string>
     <string name="user_switching_message" msgid="2871009331809089783">"Cambiando a <xliff:g id="NAME">%1$s</xliff:g>…"</string>
diff --git a/core/res/res/values-et/strings.xml b/core/res/res/values-et/strings.xml
index d7de02f..23ba43ce 100644
--- a/core/res/res/values-et/strings.xml
+++ b/core/res/res/values-et/strings.xml
@@ -131,6 +131,7 @@
     <!-- no translation found for wfcSpnFormat_spn (4998685024207291232) -->
     <skip />
     <string name="wfcSpnFormat_spn_wifi_calling" msgid="136001023263502280">"<xliff:g id="SPN">%s</xliff:g>: WiFi-kõned"</string>
+    <string name="wfcSpnFormat_spn_wifi_calling_vo_hyphen" msgid="1730997175789582756">"<xliff:g id="SPN">%s</xliff:g>: WiFi-kõned"</string>
     <string name="wfcSpnFormat_wlan_call" msgid="2533371081782489793">"WLAN-kõne"</string>
     <string name="wfcSpnFormat_spn_wlan_call" msgid="2315240198303197168">"<xliff:g id="SPN">%s</xliff:g>: WLAN-kõne"</string>
     <string name="wfcSpnFormat_spn_wifi" msgid="6546481665561961938">"<xliff:g id="SPN">%s</xliff:g>: WiFi"</string>
@@ -1357,8 +1358,7 @@
     <string name="test_harness_mode_notification_message" msgid="1343197173054407119">"Testrakendirežiimi keelamiseks taastage tehaseseaded."</string>
     <string name="usb_contaminant_detected_title" msgid="7136400633704058349">"USB-pordis on vedelik või mustus"</string>
     <string name="usb_contaminant_detected_message" msgid="832337061059487250">"USB-port on automaatselt keelatud. Puudutage lisateabe saamiseks."</string>
-    <!-- no translation found for usb_contaminant_not_detected_title (7708281124088684821) -->
-    <skip />
+    <string name="usb_contaminant_not_detected_title" msgid="7708281124088684821">"USB-porti tohib kasutada"</string>
     <string name="usb_contaminant_not_detected_message" msgid="2415791798244545292">"Telefon ei tuvasta enam vedelikku ega mustust."</string>
     <string name="taking_remote_bugreport_notification_title" msgid="6742483073875060934">"Veaaruande võtmine …"</string>
     <string name="share_remote_bugreport_notification_title" msgid="4987095013583691873">"Kas jagada veaaruannet?"</string>
@@ -1612,8 +1612,6 @@
     <string name="display_manager_overlay_display_name" msgid="5142365982271620716">"Ülekate nr .<xliff:g id="ID">%1$d</xliff:g>"</string>
     <string name="display_manager_overlay_display_title" msgid="652124517672257172">"<xliff:g id="NAME">%1$s</xliff:g>: <xliff:g id="WIDTH">%2$d</xliff:g> x <xliff:g id="HEIGHT">%3$d</xliff:g>, <xliff:g id="DPI">%4$d</xliff:g> dpi"</string>
     <string name="display_manager_overlay_display_secure_suffix" msgid="6022119702628572080">", turvaline"</string>
-    <string name="activity_starter_block_bg_activity_starts_permissive" msgid="6995473033438879646">"See taustategevuse käivitamine paketist <xliff:g id="PACKAGENAME">%1$s</xliff:g> blokeeritakse tulevaste Q järkude puhul. Vt g.co/dev/bgblock."</string>
-    <string name="activity_starter_block_bg_activity_starts_enforcing" msgid="3317816771072146229">"Taustategevuse käivitamine paketist <xliff:g id="PACKAGENAME">%1$s</xliff:g> blokeeriti. Vt g.co/dev/bgblock."</string>
     <string name="kg_forgot_pattern_button_text" msgid="8852021467868220608">"Unustasin mustri"</string>
     <string name="kg_wrong_pattern" msgid="1850806070801358830">"Vale muster"</string>
     <string name="kg_wrong_password" msgid="2333281762128113157">"Vale parool"</string>
@@ -1667,8 +1665,12 @@
     <string name="accessibility_shortcut_enabling_service" msgid="7771852911861522636">"Juurdepääsetavuse otsetee lülitas teenuse <xliff:g id="SERVICE_NAME">%1$s</xliff:g> sisse"</string>
     <string name="accessibility_shortcut_disabling_service" msgid="2747243438223109821">"Juurdepääsetavuse otsetee lülitas teenuse <xliff:g id="SERVICE_NAME">%1$s</xliff:g> välja"</string>
     <string name="accessibility_shortcut_spoken_feedback" msgid="8376923232350078434">"Teenuse <xliff:g id="SERVICE_NAME">%1$s</xliff:g> kasutamiseks hoidke kolm sekundit all mõlemat helitugevuse klahvi"</string>
-    <string name="accessibility_button_prompt_text" msgid="4234556536456854251">"Valige, millist funktsiooni kasutada, kui vajutate nuppu Juurdepääsetavus:"</string>
-    <string name="accessibility_button_instructional_text" msgid="6942300463612999993">"Funktsioonide muutmiseks puudutage pikalt nuppu Juurdepääsetavus."</string>
+    <string name="accessibility_button_prompt_text" msgid="1176658502969738564">"Valige, millist teenust kasutada, kui puudutate juurdepääsetavuse nuppu:"</string>
+    <string name="accessibility_gesture_prompt_text" msgid="8259145549733019401">"Valige, millist teenust kasutada koos juurdepääsetavuse liigutusega (pühkige kahe sõrmega ekraanikuval alt üles):"</string>
+    <string name="accessibility_gesture_3finger_prompt_text" msgid="1041435574275047665">"Valige, millist teenust kasutada koos juurdepääsetavuse liigutusega (pühkige kolme sõrmega ekraanikuval alt üles):"</string>
+    <string name="accessibility_button_instructional_text" msgid="7003212763213614833">"Teenuste vahel vahetamiseks vajutage pikalt juurdepääsetavuse nuppu."</string>
+    <string name="accessibility_gesture_instructional_text" msgid="5261788874937410950">"Teenuste vahel vahetamiseks pühkige kahe sõrmega üles ja hoidke."</string>
+    <string name="accessibility_gesture_3finger_instructional_text" msgid="4969448938984394550">"Teenuste vahel vahetamiseks pühkige kolme sõrmega üles ja hoidke."</string>
     <string name="accessibility_magnification_chooser_text" msgid="1227146738764986237">"Suurendus"</string>
     <string name="user_switched" msgid="3768006783166984410">"Praegune kasutaja <xliff:g id="NAME">%1$s</xliff:g>."</string>
     <string name="user_switching_message" msgid="2871009331809089783">"Üleminek kasutajale <xliff:g id="NAME">%1$s</xliff:g> ..."</string>
diff --git a/core/res/res/values-eu/strings.xml b/core/res/res/values-eu/strings.xml
index 4ec7c1c..ba15353 100644
--- a/core/res/res/values-eu/strings.xml
+++ b/core/res/res/values-eu/strings.xml
@@ -131,6 +131,7 @@
     <!-- no translation found for wfcSpnFormat_spn (4998685024207291232) -->
     <skip />
     <string name="wfcSpnFormat_spn_wifi_calling" msgid="136001023263502280">"<xliff:g id="SPN">%s</xliff:g> Wi-Fi bidezko deiak"</string>
+    <string name="wfcSpnFormat_spn_wifi_calling_vo_hyphen" msgid="1730997175789582756">"<xliff:g id="SPN">%s</xliff:g> operadorearen wifi bidezko deiak"</string>
     <string name="wfcSpnFormat_wlan_call" msgid="2533371081782489793">"WLAN bidezko deia"</string>
     <string name="wfcSpnFormat_spn_wlan_call" msgid="2315240198303197168">"<xliff:g id="SPN">%s</xliff:g> WLAN bidezko deia"</string>
     <string name="wfcSpnFormat_spn_wifi" msgid="6546481665561961938">"<xliff:g id="SPN">%s</xliff:g> wifia"</string>
@@ -584,7 +585,7 @@
     <string name="face_error_canceled" msgid="2768146728600802422">"Utzi da aurpegi bidezko eragiketa"</string>
     <string name="face_error_user_canceled" msgid="9003022830076496163">"Erabiltzaileak utzi du aurpegi bidezko autentifikazioa"</string>
     <string name="face_error_lockout" msgid="3407426963155388504">"Saiakera gehiegi egin dituzu. Saiatu berriro geroago."</string>
-    <string name="face_error_lockout_permanent" msgid="3485837851962070925">"Saiakera gehiegi egin dira. Desgaitu da aurpegi bidezko autentifikazioa."</string>
+    <string name="face_error_lockout_permanent" msgid="3485837851962070925">"Saiakera gehiegi egin dira. Desgaitu egin da aurpegi bidezko autentifikazioa."</string>
     <string name="face_error_unable_to_process" msgid="4940944939691171539">"Ezin da egiaztatu aurpegia. Saiatu berriro."</string>
     <string name="face_error_not_enrolled" msgid="2600952202843125796">"Ez duzu konfiguratu aurpegi bidezko autentifikazioa"</string>
     <string name="face_error_hw_not_present" msgid="1317845121210260372">"Gailu honek ez du onartzen aurpegi bidezko autentifikazioa"</string>
@@ -612,8 +613,8 @@
     <string name="permdesc_connection_manager" msgid="5925480810356483565">"Telekomunikabideekiko konexioak kudeatzea baimentzen die aplikazioei."</string>
     <string name="permlab_bind_incall_service" msgid="6773648341975287125">"erabili pantaila deiak abian direnean"</string>
     <string name="permdesc_bind_incall_service" msgid="8343471381323215005">"Erabiltzaileak deiaren pantaila noiz eta nola ikusten duen kontrolatzeko aukera ematen die aplikazioei."</string>
-    <string name="permlab_bind_connection_service" msgid="3557341439297014940">"elkarreragin telefono-zerbitzuekin"</string>
-    <string name="permdesc_bind_connection_service" msgid="4008754499822478114">"Deiak egiteko eta jasotzeko telefonia-zerbitzuekin elkarreragitea baimentzen die aplikazioei."</string>
+    <string name="permlab_bind_connection_service" msgid="3557341439297014940">"jardun interakzioan telefono-zerbitzuekin"</string>
+    <string name="permdesc_bind_connection_service" msgid="4008754499822478114">"Deiak egiteko eta jasotzeko telefonia-zerbitzuekin interakzioan aritzea baimentzen die aplikazioei."</string>
     <string name="permlab_control_incall_experience" msgid="9061024437607777619">"eskaini erabiltzaileentzako aukerak deiak abian direnean"</string>
     <string name="permdesc_control_incall_experience" msgid="915159066039828124">"Deiak abian direnean erabiltzeko aukera eskaintzea baimentzen die aplikazioei."</string>
     <string name="permlab_readNetworkUsageHistory" msgid="7862593283611493232">"irakurri sare-erabileraren historia"</string>
@@ -969,8 +970,8 @@
     <string name="searchview_description_submit" msgid="2688450133297983542">"Bidali kontsulta"</string>
     <string name="searchview_description_voice" msgid="2453203695674994440">"Ahozko bilaketa"</string>
     <string name="enable_explore_by_touch_warning_title" msgid="7460694070309730149">"\"Arakatu ukituta\" eginbidea gaitu nahi duzu?"</string>
-    <string name="enable_explore_by_touch_warning_message" product="tablet" msgid="8655887539089910577">"<xliff:g id="ACCESSIBILITY_SERVICE_NAME">%1$s</xliff:g> zerbitzuak \"Arakatu ukituta\" eginbidea gaitu nahi du. Eginbide hori aktibatuta dagoenean, hatzaren azpian duzunaren azalpena ikus edo entzun dezakezu, edo tabletarekin elkarrekintzan aritzeko keinuak egin ditzakezu."</string>
-    <string name="enable_explore_by_touch_warning_message" product="default" msgid="2708199672852373195">"<xliff:g id="ACCESSIBILITY_SERVICE_NAME">%1$s</xliff:g> zerbitzuak \"Arakatu ukituta\" eginbidea gaitu nahi du. Eginbide hori aktibatuta dagoenean, hatzaren azpian duzunaren azalpena ikus edo entzun dezakezu, edo telefonoarekin elkarrekintzan aritzeko keinuak egin ditzakezu."</string>
+    <string name="enable_explore_by_touch_warning_message" product="tablet" msgid="8655887539089910577">"<xliff:g id="ACCESSIBILITY_SERVICE_NAME">%1$s</xliff:g> zerbitzuak \"Arakatu ukituta\" eginbidea gaitu nahi du. Eginbide hori aktibatuta dagoenean, hatzaren azpian duzunaren azalpena ikus edo entzun dezakezu, edo tabletarekin interakzioan aritzeko keinuak egin ditzakezu."</string>
+    <string name="enable_explore_by_touch_warning_message" product="default" msgid="2708199672852373195">"<xliff:g id="ACCESSIBILITY_SERVICE_NAME">%1$s</xliff:g> zerbitzuak \"Arakatu ukituta\" eginbidea gaitu nahi du. Eginbide hori aktibatuta dagoenean, hatzaren azpian duzunaren azalpena ikus edo entzun dezakezu, edo telefonoarekin interakzioan aritzeko keinuak egin ditzakezu."</string>
     <string name="oneMonthDurationPast" msgid="7396384508953779925">"Duela hilabete"</string>
     <string name="beforeOneMonthDurationPast" msgid="909134546836499826">"Duela hilabete baino gutxiago"</string>
     <plurals name="last_num_days" formatted="false" msgid="5104533550723932025">
@@ -1151,7 +1152,7 @@
     <string name="use_a_different_app" msgid="8134926230585710243">"Erabili beste aplikazio bat"</string>
     <string name="clearDefaultHintMsg" msgid="3252584689512077257">"Garbitu aplikazio lehenetsia Sistemaren ezarpenak &gt; Aplikazioak &gt; Deskargatutakoak atalean."</string>
     <string name="chooseActivity" msgid="7486876147751803333">"Aukeratu ekintza bat"</string>
-    <string name="chooseUsbActivity" msgid="6894748416073583509">"Aukeratu USB gailurako aplikazioa"</string>
+    <string name="chooseUsbActivity" msgid="6894748416073583509">"Aukeratu USB bidezko gailurako aplikazioa"</string>
     <string name="noApplications" msgid="2991814273936504689">"Ez dago ekintza hori egin dezakeen aplikaziorik."</string>
     <string name="aerr_application" msgid="250320989337856518">"Gelditu egin da <xliff:g id="APPLICATION">%1$s</xliff:g>"</string>
     <string name="aerr_process" msgid="6201597323218674729">"Gelditu egin da <xliff:g id="PROCESS">%1$s</xliff:g>"</string>
@@ -1358,8 +1359,7 @@
     <string name="test_harness_mode_notification_message" msgid="1343197173054407119">"Proba-materialaren modua desgaitzeko, berrezarri jatorrizko datuak."</string>
     <string name="usb_contaminant_detected_title" msgid="7136400633704058349">"Likidoa edo zikinkeriak daude USB atakan"</string>
     <string name="usb_contaminant_detected_message" msgid="832337061059487250">"USB ataka automatikoki desgaitu da. Informazio gehiago lortzeko, sakatu hau."</string>
-    <!-- no translation found for usb_contaminant_not_detected_title (7708281124088684821) -->
-    <skip />
+    <string name="usb_contaminant_not_detected_title" msgid="7708281124088684821">"Erabiltzeko moduan dago USB ataka"</string>
     <string name="usb_contaminant_not_detected_message" msgid="2415791798244545292">"Telefonoak ez du hautematen likidorik edo zikinkeriarik."</string>
     <string name="taking_remote_bugreport_notification_title" msgid="6742483073875060934">"Akatsen txostena sortzen…"</string>
     <string name="share_remote_bugreport_notification_title" msgid="4987095013583691873">"Akatsen txostena partekatu nahi duzu?"</string>
@@ -1546,8 +1546,8 @@
     <string name="storage_internal" msgid="3570990907910199483">"Barneko biltegiratze partekatua"</string>
     <string name="storage_sd_card" msgid="3282948861378286745">"SD txartela"</string>
     <string name="storage_sd_card_label" msgid="6347111320774379257">"<xliff:g id="MANUFACTURER">%s</xliff:g> SD txartela"</string>
-    <string name="storage_usb_drive" msgid="6261899683292244209">"USB unitatea"</string>
-    <string name="storage_usb_drive_label" msgid="4501418548927759953">"<xliff:g id="MANUFACTURER">%s</xliff:g> USB unitatea"</string>
+    <string name="storage_usb_drive" msgid="6261899683292244209">"USB bidezko unitatea"</string>
+    <string name="storage_usb_drive_label" msgid="4501418548927759953">"<xliff:g id="MANUFACTURER">%s</xliff:g> enpresaren USB bidezko unitatea"</string>
     <string name="storage_usb" msgid="3017954059538517278">"USB memoria"</string>
     <string name="extract_edit_menu_button" msgid="8940478730496610137">"Editatu"</string>
     <string name="data_usage_warning_title" msgid="6499834033204801605">"Datuen erabileraren abisua"</string>
@@ -1613,8 +1613,6 @@
     <string name="display_manager_overlay_display_name" msgid="5142365982271620716">"<xliff:g id="ID">%1$d</xliff:g>. gainjartzea"</string>
     <string name="display_manager_overlay_display_title" msgid="652124517672257172">"<xliff:g id="NAME">%1$s</xliff:g>: <xliff:g id="WIDTH">%2$d</xliff:g> x <xliff:g id="HEIGHT">%3$d</xliff:g>, <xliff:g id="DPI">%4$d</xliff:g> dpi"</string>
     <string name="display_manager_overlay_display_secure_suffix" msgid="6022119702628572080">", segurua"</string>
-    <string name="activity_starter_block_bg_activity_starts_permissive" msgid="6995473033438879646">"<xliff:g id="PACKAGENAME">%1$s</xliff:g> paketearen atzeko planoko jardueraren abio hau blokeatu egingo da Q bertsioaren etorkizuneko konpilazioetan. Joan g.co/dev/bgblock helbidera."</string>
-    <string name="activity_starter_block_bg_activity_starts_enforcing" msgid="3317816771072146229">"Blokeatu da <xliff:g id="PACKAGENAME">%1$s</xliff:g> paketearen atzeko planoko jardueraren abioa. Joan g.co/dev/bgblock helbidera."</string>
     <string name="kg_forgot_pattern_button_text" msgid="8852021467868220608">"Eredua ahaztu zaizu"</string>
     <string name="kg_wrong_pattern" msgid="1850806070801358830">"Eredu okerra"</string>
     <string name="kg_wrong_password" msgid="2333281762128113157">"Pasahitz okerra"</string>
@@ -1668,8 +1666,12 @@
     <string name="accessibility_shortcut_enabling_service" msgid="7771852911861522636">"Erabilerraztasun-lasterbideak <xliff:g id="SERVICE_NAME">%1$s</xliff:g> aktibatu du"</string>
     <string name="accessibility_shortcut_disabling_service" msgid="2747243438223109821">"Erabilerraztasun-lasterbideak <xliff:g id="SERVICE_NAME">%1$s</xliff:g> desaktibatu du"</string>
     <string name="accessibility_shortcut_spoken_feedback" msgid="8376923232350078434">"<xliff:g id="SERVICE_NAME">%1$s</xliff:g> erabiltzeko, eduki sakatuta bolumen-tekla biak hiru segundoz"</string>
-    <string name="accessibility_button_prompt_text" msgid="4234556536456854251">"Aukeratu zein eginbide erabili nahi duzun Erabilerraztasuna botoia sakatzean:"</string>
-    <string name="accessibility_button_instructional_text" msgid="6942300463612999993">"Eginbideak aldatzeko, eduki sakatuta Erabilerraztasuna botoia."</string>
+    <string name="accessibility_button_prompt_text" msgid="1176658502969738564">"Aukeratu zer zerbitzu erabili nahi duzun Erabilerraztasuna botoia sakatzean:"</string>
+    <string name="accessibility_gesture_prompt_text" msgid="8259145549733019401">"Aukeratu zer zerbitzu erabili nahi duzun erabilerraztasun-keinua egitean (hau da, bi hatz pantailaren behealdetik gora pasatuz gero):"</string>
+    <string name="accessibility_gesture_3finger_prompt_text" msgid="1041435574275047665">"Aukeratu zer zerbitzu erabili nahi duzun erabilerraztasun-keinua egitean (hau da, hiru hatz pantailaren behealdetik gora pasatuz gero):"</string>
+    <string name="accessibility_button_instructional_text" msgid="7003212763213614833">"Zerbitzu batetik bestera aldatzeko, eduki sakatuta Erabilerraztasuna botoia."</string>
+    <string name="accessibility_gesture_instructional_text" msgid="5261788874937410950">"Zerbitzu batetik bestera aldatzeko, pasatu bi hatz pantailaren behealdetik gora eta eduki sakatuta une batez."</string>
+    <string name="accessibility_gesture_3finger_instructional_text" msgid="4969448938984394550">"Zerbitzu batetik bestera aldatzeko, pasatu hiru hatz pantailaren behealdetik gora eta eduki sakatuta une batez."</string>
     <string name="accessibility_magnification_chooser_text" msgid="1227146738764986237">"Lupa"</string>
     <string name="user_switched" msgid="3768006783166984410">"Uneko erabiltzailea: <xliff:g id="NAME">%1$s</xliff:g>."</string>
     <string name="user_switching_message" msgid="2871009331809089783">"<xliff:g id="NAME">%1$s</xliff:g> erabiltzailera aldatzen…"</string>
@@ -1901,7 +1903,7 @@
     <string name="deprecated_target_sdk_message" msgid="1449696506742572767">"Aplikazioa Android-en bertsio zaharrago baterako sortu zenez, baliteke behar bezala ez funtzionatzea. Bilatu eguneratzerik baden, edo jarri garatzailearekin harremanetan."</string>
     <string name="deprecated_target_sdk_app_store" msgid="5032340500368495077">"Bilatu eguneratzeak"</string>
     <string name="new_sms_notification_title" msgid="8442817549127555977">"Mezu berriak dituzu"</string>
-    <string name="new_sms_notification_content" msgid="7002938807812083463">"Mezuak ikusteko, ireki SMS mezuen aplikazioa"</string>
+    <string name="new_sms_notification_content" msgid="7002938807812083463">"Mezuak ikusteko, ireki SMS mezuetarako aplikazioa"</string>
     <string name="profile_encrypted_title" msgid="4260432497586829134">"Baliteke funtzio batzuk mugatuta egotea"</string>
     <string name="profile_encrypted_detail" msgid="3700965619978314974">"Blokeatuta dago laneko profila"</string>
     <string name="profile_encrypted_message" msgid="6964994232310195874">"Sakatu profila desblokeatzeko"</string>
diff --git a/core/res/res/values-fa/strings.xml b/core/res/res/values-fa/strings.xml
index deb015c..0c957e0 100644
--- a/core/res/res/values-fa/strings.xml
+++ b/core/res/res/values-fa/strings.xml
@@ -131,6 +131,7 @@
     <!-- no translation found for wfcSpnFormat_spn (4998685024207291232) -->
     <skip />
     <string name="wfcSpnFormat_spn_wifi_calling" msgid="136001023263502280">"‏تماس ازطریق Wi-Fi <xliff:g id="SPN">%s</xliff:g>"</string>
+    <string name="wfcSpnFormat_spn_wifi_calling_vo_hyphen" msgid="1730997175789582756">"‏تماس Wi‑Fi <xliff:g id="SPN">%s</xliff:g>"</string>
     <string name="wfcSpnFormat_wlan_call" msgid="2533371081782489793">"‏تماس ازطریق WLAN"</string>
     <string name="wfcSpnFormat_spn_wlan_call" msgid="2315240198303197168">"‏تماس ازطریق WLAN <xliff:g id="SPN">%s</xliff:g>"</string>
     <string name="wfcSpnFormat_spn_wifi" msgid="6546481665561961938">"Wi-Fi <xliff:g id="SPN">%s</xliff:g>"</string>
@@ -1357,8 +1358,7 @@
     <string name="test_harness_mode_notification_message" msgid="1343197173054407119">"برای غیرفعال کردن «حالت مجموعه داده‌های تست»، بازنشانی کارخانه‌ای کنید."</string>
     <string name="usb_contaminant_detected_title" msgid="7136400633704058349">"‏مایعات یا خاکروبه در درگاه USB"</string>
     <string name="usb_contaminant_detected_message" msgid="832337061059487250">"‏درگاه USB به‌طور خودکار غیرفعال شده است. برای اطلاعات بیشتر، ضربه بزنید."</string>
-    <!-- no translation found for usb_contaminant_not_detected_title (7708281124088684821) -->
-    <skip />
+    <string name="usb_contaminant_not_detected_title" msgid="7708281124088684821">"‏می‌توان از درگاه USB استفاده کرد"</string>
     <string name="usb_contaminant_not_detected_message" msgid="2415791798244545292">"تلفن دیگر وجود مایعات یا خاکروبه را تشخیص نمی‌دهد."</string>
     <string name="taking_remote_bugreport_notification_title" msgid="6742483073875060934">"درحال گرفتن گزارش اشکال…"</string>
     <string name="share_remote_bugreport_notification_title" msgid="4987095013583691873">"گزارش اشکال به اشتراک گذاشته شود؟"</string>
@@ -1493,8 +1493,8 @@
     <string name="websearch" msgid="4337157977400211589">"جستجوی وب"</string>
     <string name="find_next" msgid="5742124618942193978">"یافتن بعدی"</string>
     <string name="find_previous" msgid="2196723669388360506">"یافتن قبلی"</string>
-    <string name="gpsNotifTicker" msgid="5622683912616496172">"درخواست موقعیت مکانی از <xliff:g id="NAME">%s</xliff:g>"</string>
-    <string name="gpsNotifTitle" msgid="5446858717157416839">"درخواست موقعیت مکانی"</string>
+    <string name="gpsNotifTicker" msgid="5622683912616496172">"درخواست مکان از <xliff:g id="NAME">%s</xliff:g>"</string>
+    <string name="gpsNotifTitle" msgid="5446858717157416839">"درخواست مکان"</string>
     <string name="gpsNotifMessage" msgid="1374718023224000702">"درخواست شده توسط <xliff:g id="NAME">%1$s</xliff:g> (<xliff:g id="SERVICE">%2$s</xliff:g>)"</string>
     <string name="gpsVerifYes" msgid="2346566072867213563">"بله"</string>
     <string name="gpsVerifNo" msgid="1146564937346454865">"نه"</string>
@@ -1612,8 +1612,6 @@
     <string name="display_manager_overlay_display_name" msgid="5142365982271620716">"هم‌پوشانی #<xliff:g id="ID">%1$d</xliff:g>"</string>
     <string name="display_manager_overlay_display_title" msgid="652124517672257172">"<xliff:g id="NAME">%1$s</xliff:g>: <xliff:g id="WIDTH">%2$d</xliff:g>x<xliff:g id="HEIGHT">%3$d</xliff:g>, <xliff:g id="DPI">%4$d</xliff:g> dpi"</string>
     <string name="display_manager_overlay_display_secure_suffix" msgid="6022119702628572080">"، امن"</string>
-    <string name="activity_starter_block_bg_activity_starts_permissive" msgid="6995473033438879646">"‏شروع فعالیت پس‌زمینه<xliff:g id="PACKAGENAME">%1$s</xliff:g> در نسخه‌های Q آینده مسدود خواهد شد. به g.co/dev/bgblock مراجعه کنید."</string>
-    <string name="activity_starter_block_bg_activity_starts_enforcing" msgid="3317816771072146229">"‏شروع فعالیت پس‌زمینه <xliff:g id="PACKAGENAME">%1$s</xliff:g> مسدود شده است. به g.co/dev/bgblock مراجعه کنید."</string>
     <string name="kg_forgot_pattern_button_text" msgid="8852021467868220608">"الگو را فراموش کرده‌اید"</string>
     <string name="kg_wrong_pattern" msgid="1850806070801358830">"الگوی اشتباه"</string>
     <string name="kg_wrong_password" msgid="2333281762128113157">"گذرواژه اشتباه"</string>
@@ -1667,8 +1665,12 @@
     <string name="accessibility_shortcut_enabling_service" msgid="7771852911861522636">"«میان‌بر دسترس‌پذیری» <xliff:g id="SERVICE_NAME">%1$s</xliff:g> را روشن کرد"</string>
     <string name="accessibility_shortcut_disabling_service" msgid="2747243438223109821">"«میان‌بر دسترس‌پذیری» <xliff:g id="SERVICE_NAME">%1$s</xliff:g> را خاموش کرد"</string>
     <string name="accessibility_shortcut_spoken_feedback" msgid="8376923232350078434">"برای استفاده از <xliff:g id="SERVICE_NAME">%1$s</xliff:g>، هر دو کلید صدا را فشار دهید و سه ثانیه نگه دارید"</string>
-    <string name="accessibility_button_prompt_text" msgid="4234556536456854251">"قابلیتی را انتخاب کنید که هنگام ضربه زدن روی دکمه «دسترس‌پذیری» استفاده می‌شود:"</string>
-    <string name="accessibility_button_instructional_text" msgid="6942300463612999993">"برای تغییر دادن قابلیت‌ها، دکمه «دسترس‌پذیری» را لمس کنید و نگه‌دارید."</string>
+    <string name="accessibility_button_prompt_text" msgid="1176658502969738564">"سرویسی را انتخاب کنید که هنگام ضربه زدن روی دکمه دسترس‌پذیری استفاده می‌شود:"</string>
+    <string name="accessibility_gesture_prompt_text" msgid="8259145549733019401">"سرویسی را برای استفاده با اشاره دسترس‌پذیری انتخاب کنید (با دو انگشت صفحه را از پایین تند به بالا بکشید):"</string>
+    <string name="accessibility_gesture_3finger_prompt_text" msgid="1041435574275047665">"سرویسی را برای استفاده با اشاره دسترس‌پذیری انتخاب کنید (با سه انگشت صفحه را از پایین تند به بالا بکشید):"</string>
+    <string name="accessibility_button_instructional_text" msgid="7003212763213614833">"برای جابه‌جایی بین سرویس‌ها، دکمه دسترس‌پذیری را لمس کنید و نگه‌دارید."</string>
+    <string name="accessibility_gesture_instructional_text" msgid="5261788874937410950">"برای جابه‌جایی بین سرویس‌ها، با دو انگشت صفحه را تند به بالا بکشید و نگه‌دارید."</string>
+    <string name="accessibility_gesture_3finger_instructional_text" msgid="4969448938984394550">"برای جابه‌جایی بین سرویس‌ها، با سه انگشت صفحه را تند به بالا بکشید و نگه‌دارید."</string>
     <string name="accessibility_magnification_chooser_text" msgid="1227146738764986237">"درشت‌نمایی"</string>
     <string name="user_switched" msgid="3768006783166984410">"کاربر کنونی <xliff:g id="NAME">%1$s</xliff:g>."</string>
     <string name="user_switching_message" msgid="2871009331809089783">"در حالت تغییر به <xliff:g id="NAME">%1$s</xliff:g>…"</string>
diff --git a/core/res/res/values-fi/strings.xml b/core/res/res/values-fi/strings.xml
index 8dcf338..2ff256b 100644
--- a/core/res/res/values-fi/strings.xml
+++ b/core/res/res/values-fi/strings.xml
@@ -131,6 +131,7 @@
     <!-- no translation found for wfcSpnFormat_spn (4998685024207291232) -->
     <skip />
     <string name="wfcSpnFormat_spn_wifi_calling" msgid="136001023263502280">"Wi-Fi-puhelut (<xliff:g id="SPN">%s</xliff:g>)"</string>
+    <string name="wfcSpnFormat_spn_wifi_calling_vo_hyphen" msgid="1730997175789582756">"<xliff:g id="SPN">%s</xliff:g> Wi-Fi-puhelut"</string>
     <string name="wfcSpnFormat_wlan_call" msgid="2533371081782489793">"WLAN-puhelu"</string>
     <string name="wfcSpnFormat_spn_wlan_call" msgid="2315240198303197168">"WLAN-puhelu (<xliff:g id="SPN">%s</xliff:g>)"</string>
     <string name="wfcSpnFormat_spn_wifi" msgid="6546481665561961938">"<xliff:g id="SPN">%s</xliff:g> Wi-Fi"</string>
@@ -1357,8 +1358,7 @@
     <string name="test_harness_mode_notification_message" msgid="1343197173054407119">"Palauta tehdasasetukset, niin voit poistaa testikehystilan käytöstä."</string>
     <string name="usb_contaminant_detected_title" msgid="7136400633704058349">"Nestettä tai likaa USB-portissa"</string>
     <string name="usb_contaminant_detected_message" msgid="832337061059487250">"USB-portti poistetaan käytöstä automaattisesti. Napauta nähdäksesi lisätietoja."</string>
-    <!-- no translation found for usb_contaminant_not_detected_title (7708281124088684821) -->
-    <skip />
+    <string name="usb_contaminant_not_detected_title" msgid="7708281124088684821">"USB-portin käyttö on sallittu"</string>
     <string name="usb_contaminant_not_detected_message" msgid="2415791798244545292">"Puhelin ei enää havaitse nesteitä eikä likaa."</string>
     <string name="taking_remote_bugreport_notification_title" msgid="6742483073875060934">"Luodaan virheraporttia…"</string>
     <string name="share_remote_bugreport_notification_title" msgid="4987095013583691873">"Jaetaanko virheraportti?"</string>
@@ -1612,8 +1612,6 @@
     <string name="display_manager_overlay_display_name" msgid="5142365982271620716">"Peittokuva # <xliff:g id="ID">%1$d</xliff:g>"</string>
     <string name="display_manager_overlay_display_title" msgid="652124517672257172">"<xliff:g id="NAME">%1$s</xliff:g>: <xliff:g id="WIDTH">%2$d</xliff:g> x <xliff:g id="HEIGHT">%3$d</xliff:g>, <xliff:g id="DPI">%4$d</xliff:g> dpi"</string>
     <string name="display_manager_overlay_display_secure_suffix" msgid="6022119702628572080">", suojattu"</string>
-    <string name="activity_starter_block_bg_activity_starts_permissive" msgid="6995473033438879646">"Tämä taustatoiminnan käynnistys kohteesta <xliff:g id="PACKAGENAME">%1$s</xliff:g> estetään tulevissa Q-versioissa. Siirry osoitteeseen g.co/dev/bgblock."</string>
-    <string name="activity_starter_block_bg_activity_starts_enforcing" msgid="3317816771072146229">"Taustatoiminnan käynnistys kohteesta <xliff:g id="PACKAGENAME">%1$s</xliff:g> estettiin. Siirry osoitteeseen g.co/dev/bgblock."</string>
     <string name="kg_forgot_pattern_button_text" msgid="8852021467868220608">"Unohtunut kuvio"</string>
     <string name="kg_wrong_pattern" msgid="1850806070801358830">"Väärä kuvio"</string>
     <string name="kg_wrong_password" msgid="2333281762128113157">"Väärä salasana"</string>
@@ -1667,8 +1665,12 @@
     <string name="accessibility_shortcut_enabling_service" msgid="7771852911861522636">"<xliff:g id="SERVICE_NAME">%1$s</xliff:g> otettiin käyttöön esteettömyystilan pikanäppäimellä."</string>
     <string name="accessibility_shortcut_disabling_service" msgid="2747243438223109821">"<xliff:g id="SERVICE_NAME">%1$s</xliff:g> poistettiin käytöstä esteettömyystilan pikanäppäimellä."</string>
     <string name="accessibility_shortcut_spoken_feedback" msgid="8376923232350078434">"Voit käyttää palvelua <xliff:g id="SERVICE_NAME">%1$s</xliff:g> painamalla molempia äänenvoimakkuuspainikkeita kolmen sekunnin ajan"</string>
-    <string name="accessibility_button_prompt_text" msgid="4234556536456854251">"Valitse toiminto, jonka Esteettömyys-painike aktivoi:"</string>
-    <string name="accessibility_button_instructional_text" msgid="6942300463612999993">"Jos haluat muokata ominaisuuksia, kosketa Esteettömyys-painiketta pitkään."</string>
+    <string name="accessibility_button_prompt_text" msgid="1176658502969738564">"Valitse palvelu, jonka esteettömyyspainike aktivoi:"</string>
+    <string name="accessibility_gesture_prompt_text" msgid="8259145549733019401">"Valitse palvelu, jota käytetään esteettömyyseleellä (pyyhkäise näytön alalaidasta ylös kahdella sormella):"</string>
+    <string name="accessibility_gesture_3finger_prompt_text" msgid="1041435574275047665">"Valitse palvelu, jota käytetään esteettömyyseleellä (pyyhkäise näytön alalaidasta ylös kolmella sormella):"</string>
+    <string name="accessibility_button_instructional_text" msgid="7003212763213614833">"Vaihda palveluiden välillä painamalla painiketta pitkään."</string>
+    <string name="accessibility_gesture_instructional_text" msgid="5261788874937410950">"Vaihda palveluiden välillä pyyhkäisemällä ylös kahdella sormella ja koskettamalla pitkään."</string>
+    <string name="accessibility_gesture_3finger_instructional_text" msgid="4969448938984394550">"Vaihda palveluiden välillä pyyhkäisemällä ylös kolmella sormella ja koskettamalla pitkään."</string>
     <string name="accessibility_magnification_chooser_text" msgid="1227146738764986237">"Suurennus"</string>
     <string name="user_switched" msgid="3768006783166984410">"Nykyinen käyttäjä: <xliff:g id="NAME">%1$s</xliff:g>."</string>
     <string name="user_switching_message" msgid="2871009331809089783">"Vaihdetaan käyttäjään <xliff:g id="NAME">%1$s</xliff:g>…"</string>
diff --git a/core/res/res/values-fr-rCA/strings.xml b/core/res/res/values-fr-rCA/strings.xml
index 3fc57f8..da5f866 100644
--- a/core/res/res/values-fr-rCA/strings.xml
+++ b/core/res/res/values-fr-rCA/strings.xml
@@ -131,6 +131,7 @@
     <!-- no translation found for wfcSpnFormat_spn (4998685024207291232) -->
     <skip />
     <string name="wfcSpnFormat_spn_wifi_calling" msgid="136001023263502280">"Appels Wi-Fi <xliff:g id="SPN">%s</xliff:g>"</string>
+    <string name="wfcSpnFormat_spn_wifi_calling_vo_hyphen" msgid="1730997175789582756">"Appels Wi-Fi : <xliff:g id="SPN">%s</xliff:g>"</string>
     <string name="wfcSpnFormat_wlan_call" msgid="2533371081782489793">"Appel WLAN"</string>
     <string name="wfcSpnFormat_spn_wlan_call" msgid="2315240198303197168">"Appel WLAN <xliff:g id="SPN">%s</xliff:g>"</string>
     <string name="wfcSpnFormat_spn_wifi" msgid="6546481665561961938">"Wi-Fi <xliff:g id="SPN">%s</xliff:g>"</string>
@@ -1357,8 +1358,7 @@
     <string name="test_harness_mode_notification_message" msgid="1343197173054407119">"Effectuez une réinitialisation pour désactiver le mode Logiciel de test."</string>
     <string name="usb_contaminant_detected_title" msgid="7136400633704058349">"Liquide ou débris dans le port USB"</string>
     <string name="usb_contaminant_detected_message" msgid="832337061059487250">"Le port USB est désactivé automatiquement. Touchez ici pour en savoir plus."</string>
-    <!-- no translation found for usb_contaminant_not_detected_title (7708281124088684821) -->
-    <skip />
+    <string name="usb_contaminant_not_detected_title" msgid="7708281124088684821">"Autorisation d\'utiliser le port USB"</string>
     <string name="usb_contaminant_not_detected_message" msgid="2415791798244545292">"Le téléphone ne détecte plus les liquides ni les débris."</string>
     <string name="taking_remote_bugreport_notification_title" msgid="6742483073875060934">"Création d\'un rapport de bogue en cours..."</string>
     <string name="share_remote_bugreport_notification_title" msgid="4987095013583691873">"Partager le rapport de bogue?"</string>
@@ -1612,8 +1612,6 @@
     <string name="display_manager_overlay_display_name" msgid="5142365982271620716">"Superposition n° <xliff:g id="ID">%1$d</xliff:g>"</string>
     <string name="display_manager_overlay_display_title" msgid="652124517672257172">"<xliff:g id="NAME">%1$s</xliff:g> : <xliff:g id="WIDTH">%2$d</xliff:g> x <xliff:g id="HEIGHT">%3$d</xliff:g>, <xliff:g id="DPI">%4$d</xliff:g> ppp"</string>
     <string name="display_manager_overlay_display_secure_suffix" msgid="6022119702628572080">", sécurisé"</string>
-    <string name="activity_starter_block_bg_activity_starts_permissive" msgid="6995473033438879646">"Ce lancement d\'activité en arrière-plan par <xliff:g id="PACKAGENAME">%1$s</xliff:g> sera bloqué dans les versions futures de Q. Consultez la page g.co/dev/bgblock."</string>
-    <string name="activity_starter_block_bg_activity_starts_enforcing" msgid="3317816771072146229">"Le lancement d\'une activité en arrière-plan par <xliff:g id="PACKAGENAME">%1$s</xliff:g> a été bloqué. Consultez la page g.co/dev/bgblock."</string>
     <string name="kg_forgot_pattern_button_text" msgid="8852021467868220608">"J\'ai oublié le schéma"</string>
     <string name="kg_wrong_pattern" msgid="1850806070801358830">"Schéma incorrect."</string>
     <string name="kg_wrong_password" msgid="2333281762128113157">"Mot de passe incorrect."</string>
@@ -1667,8 +1665,12 @@
     <string name="accessibility_shortcut_enabling_service" msgid="7771852911861522636">"Le raccourci d\'accessibilité a activé la fonction <xliff:g id="SERVICE_NAME">%1$s</xliff:g>"</string>
     <string name="accessibility_shortcut_disabling_service" msgid="2747243438223109821">"Le raccourci d\'accessibilité a désactivé la fonction <xliff:g id="SERVICE_NAME">%1$s</xliff:g>"</string>
     <string name="accessibility_shortcut_spoken_feedback" msgid="8376923232350078434">"Maintenez enfoncées les deux touches de volume pendant trois secondes pour utiliser <xliff:g id="SERVICE_NAME">%1$s</xliff:g>"</string>
-    <string name="accessibility_button_prompt_text" msgid="4234556536456854251">"Choisissez une fonctionnalité à utiliser lorsque vous touchez le bouton d\'accessibilité :"</string>
-    <string name="accessibility_button_instructional_text" msgid="6942300463612999993">"Pour changer des fonctionnalités, maintenez le doigt sur le bouton d\'accessibilité."</string>
+    <string name="accessibility_button_prompt_text" msgid="1176658502969738564">"Choisissez un service à utiliser lorsque vous touchez le bouton d\'accessibilité :"</string>
+    <string name="accessibility_gesture_prompt_text" msgid="8259145549733019401">"Choisissez un service à utiliser lorsque vous utilisez le geste d\'accessibilité (balayer deux doigts du bas de l\'écran vers le haut) :"</string>
+    <string name="accessibility_gesture_3finger_prompt_text" msgid="1041435574275047665">"Choisissez un service à utiliser lorsque vous utilisez le geste d\'accessibilité (balayer trois doigts du bas de l\'écran vers le haut) :"</string>
+    <string name="accessibility_button_instructional_text" msgid="7003212763213614833">"Pour basculer entre les services, maintenez le doigt sur le bouton d\'accessibilité."</string>
+    <string name="accessibility_gesture_instructional_text" msgid="5261788874937410950">"Pour basculer entre les services, balayez deux doigts vers le haut et maintenez-les sur l\'écran."</string>
+    <string name="accessibility_gesture_3finger_instructional_text" msgid="4969448938984394550">"Pour basculer entre les services, balayez trois doigts vers le haut et maintenez-les sur l\'écran."</string>
     <string name="accessibility_magnification_chooser_text" msgid="1227146738764986237">"Zoom"</string>
     <string name="user_switched" msgid="3768006783166984410">"Utilisateur actuel : <xliff:g id="NAME">%1$s</xliff:g>"</string>
     <string name="user_switching_message" msgid="2871009331809089783">"Changement d\'utilisateur (<xliff:g id="NAME">%1$s</xliff:g>) en cours…"</string>
diff --git a/core/res/res/values-fr/strings.xml b/core/res/res/values-fr/strings.xml
index 364e87b..345cfcc 100644
--- a/core/res/res/values-fr/strings.xml
+++ b/core/res/res/values-fr/strings.xml
@@ -131,6 +131,7 @@
     <!-- no translation found for wfcSpnFormat_spn (4998685024207291232) -->
     <skip />
     <string name="wfcSpnFormat_spn_wifi_calling" msgid="136001023263502280">"Appels Wi-Fi <xliff:g id="SPN">%s</xliff:g>"</string>
+    <string name="wfcSpnFormat_spn_wifi_calling_vo_hyphen" msgid="1730997175789582756">"Appels Wi-Fi <xliff:g id="SPN">%s</xliff:g>"</string>
     <string name="wfcSpnFormat_wlan_call" msgid="2533371081782489793">"Appel WLAN"</string>
     <string name="wfcSpnFormat_spn_wlan_call" msgid="2315240198303197168">"Appel WLAN <xliff:g id="SPN">%s</xliff:g>"</string>
     <string name="wfcSpnFormat_spn_wifi" msgid="6546481665561961938">"Wi-Fi <xliff:g id="SPN">%s</xliff:g>"</string>
@@ -1357,8 +1358,7 @@
     <string name="test_harness_mode_notification_message" msgid="1343197173054407119">"Rétablissez la configuration d\'usine pour désactiver le mode Atelier de test."</string>
     <string name="usb_contaminant_detected_title" msgid="7136400633704058349">"Présence de liquide ou de saletés dans le port USB"</string>
     <string name="usb_contaminant_detected_message" msgid="832337061059487250">"Le port USB est désactivé automatiquement. Appuyez sur cette notification pour en savoir plus."</string>
-    <!-- no translation found for usb_contaminant_not_detected_title (7708281124088684821) -->
-    <skip />
+    <string name="usb_contaminant_not_detected_title" msgid="7708281124088684821">"Autoriser l\'utilisation du port USB"</string>
     <string name="usb_contaminant_not_detected_message" msgid="2415791798244545292">"Le téléphone ne détecte plus les liquides ni les saletés."</string>
     <string name="taking_remote_bugreport_notification_title" msgid="6742483073875060934">"Création du rapport de bug…"</string>
     <string name="share_remote_bugreport_notification_title" msgid="4987095013583691873">"Partager le rapport de bug ?"</string>
@@ -1612,8 +1612,6 @@
     <string name="display_manager_overlay_display_name" msgid="5142365982271620716">"Superposition n° <xliff:g id="ID">%1$d</xliff:g>"</string>
     <string name="display_manager_overlay_display_title" msgid="652124517672257172">"<xliff:g id="NAME">%1$s</xliff:g> : <xliff:g id="WIDTH">%2$d</xliff:g> x <xliff:g id="HEIGHT">%3$d</xliff:g>, <xliff:g id="DPI">%4$d</xliff:g> dpi"</string>
     <string name="display_manager_overlay_display_secure_suffix" msgid="6022119702628572080">", sécurisé"</string>
-    <string name="activity_starter_block_bg_activity_starts_permissive" msgid="6995473033438879646">"Le démarrage de cette activité en arrière-plan de <xliff:g id="PACKAGENAME">%1$s</xliff:g> sera bloqué dans les prochaines builds Q. Consultez g.co/dev/bgblock."</string>
-    <string name="activity_starter_block_bg_activity_starts_enforcing" msgid="3317816771072146229">"Le démarrage de l\'activité en arrière-plan de <xliff:g id="PACKAGENAME">%1$s</xliff:g> a été bloqué. Consultez g.co/dev/bgblock."</string>
     <string name="kg_forgot_pattern_button_text" msgid="8852021467868220608">"J\'ai oublié le schéma"</string>
     <string name="kg_wrong_pattern" msgid="1850806070801358830">"Schéma incorrect."</string>
     <string name="kg_wrong_password" msgid="2333281762128113157">"Mot de passe incorrect."</string>
@@ -1667,8 +1665,12 @@
     <string name="accessibility_shortcut_enabling_service" msgid="7771852911861522636">"Le raccourci d\'accessibilité a activé <xliff:g id="SERVICE_NAME">%1$s</xliff:g>"</string>
     <string name="accessibility_shortcut_disabling_service" msgid="2747243438223109821">"Le raccourci d\'accessibilité a désactivé <xliff:g id="SERVICE_NAME">%1$s</xliff:g>"</string>
     <string name="accessibility_shortcut_spoken_feedback" msgid="8376923232350078434">"Appuyez de manière prolongée sur les deux touches de volume pendant trois secondes pour utiliser <xliff:g id="SERVICE_NAME">%1$s</xliff:g>"</string>
-    <string name="accessibility_button_prompt_text" msgid="4234556536456854251">"Choisissez une fonctionnalité à utiliser lorsque vous appuyez sur le bouton Accessibilité :"</string>
-    <string name="accessibility_button_instructional_text" msgid="6942300463612999993">"Pour changer de fonctionnalités, appuyez de manière prolongée sur le bouton Accessibilité."</string>
+    <string name="accessibility_button_prompt_text" msgid="1176658502969738564">"Choisissez un service à utiliser lorsque vous appuyez sur le bouton Accessibilité :"</string>
+    <string name="accessibility_gesture_prompt_text" msgid="8259145549733019401">"Choisissez un service à utiliser avec le geste d\'accessibilité (balayez l\'écran de bas en haut avec deux doigts) :"</string>
+    <string name="accessibility_gesture_3finger_prompt_text" msgid="1041435574275047665">"Choisissez un service à utiliser avec le geste d\'accessibilité (balayez l\'écran de bas en haut avec trois doigts) :"</string>
+    <string name="accessibility_button_instructional_text" msgid="7003212763213614833">"Pour changer de service, appuyez de manière prolongée sur le bouton Accessibilité."</string>
+    <string name="accessibility_gesture_instructional_text" msgid="5261788874937410950">"Pour changer de service, balayez l\'écran vers le haut avec deux doigts et appuyez de manière prolongée."</string>
+    <string name="accessibility_gesture_3finger_instructional_text" msgid="4969448938984394550">"Pour changer de service, balayez l\'écran vers le haut avec trois doigts et appuyez de manière prolongée."</string>
     <string name="accessibility_magnification_chooser_text" msgid="1227146738764986237">"Agrandissement"</string>
     <string name="user_switched" msgid="3768006783166984410">"Utilisateur actuel : <xliff:g id="NAME">%1$s</xliff:g>"</string>
     <string name="user_switching_message" msgid="2871009331809089783">"Chargement du profil de <xliff:g id="NAME">%1$s</xliff:g>..."</string>
diff --git a/core/res/res/values-gl/strings.xml b/core/res/res/values-gl/strings.xml
index 58212db..73a32f3 100644
--- a/core/res/res/values-gl/strings.xml
+++ b/core/res/res/values-gl/strings.xml
@@ -131,6 +131,7 @@
     <!-- no translation found for wfcSpnFormat_spn (4998685024207291232) -->
     <skip />
     <string name="wfcSpnFormat_spn_wifi_calling" msgid="136001023263502280">"Chamadas por wifi de <xliff:g id="SPN">%s</xliff:g>"</string>
+    <string name="wfcSpnFormat_spn_wifi_calling_vo_hyphen" msgid="1730997175789582756">"Chamadas por wifi con <xliff:g id="SPN">%s</xliff:g>"</string>
     <string name="wfcSpnFormat_wlan_call" msgid="2533371081782489793">"Chamada por WLAN"</string>
     <string name="wfcSpnFormat_spn_wlan_call" msgid="2315240198303197168">"Chamada por WLAN de <xliff:g id="SPN">%s</xliff:g>"</string>
     <string name="wfcSpnFormat_spn_wifi" msgid="6546481665561961938">"Wifi de <xliff:g id="SPN">%s</xliff:g>"</string>
@@ -1358,8 +1359,7 @@
     <string name="test_harness_mode_notification_message" msgid="1343197173054407119">"Restablece a configuración de fábrica para desactivar o modo de axente de proba."</string>
     <string name="usb_contaminant_detected_title" msgid="7136400633704058349">"Hai líquido ou residuos no porto USB"</string>
     <string name="usb_contaminant_detected_message" msgid="832337061059487250">"O porto USB desactivouse automaticamente. Toca para obter máis información."</string>
-    <!-- no translation found for usb_contaminant_not_detected_title (7708281124088684821) -->
-    <skip />
+    <string name="usb_contaminant_not_detected_title" msgid="7708281124088684821">"Pódese utilizar o porto USB"</string>
     <string name="usb_contaminant_not_detected_message" msgid="2415791798244545292">"O teléfono xa non detecta líquidos nin residuos."</string>
     <string name="taking_remote_bugreport_notification_title" msgid="6742483073875060934">"Creando informe de erros…"</string>
     <string name="share_remote_bugreport_notification_title" msgid="4987095013583691873">"Queres compartir o informe de erros?"</string>
@@ -1613,8 +1613,6 @@
     <string name="display_manager_overlay_display_name" msgid="5142365982271620716">"Superposición n.º <xliff:g id="ID">%1$d</xliff:g>"</string>
     <string name="display_manager_overlay_display_title" msgid="652124517672257172">"<xliff:g id="NAME">%1$s</xliff:g>: <xliff:g id="WIDTH">%2$d</xliff:g> x <xliff:g id="HEIGHT">%3$d</xliff:g>, <xliff:g id="DPI">%4$d</xliff:g> ppp"</string>
     <string name="display_manager_overlay_display_secure_suffix" msgid="6022119702628572080">", segura"</string>
-    <string name="activity_starter_block_bg_activity_starts_permissive" msgid="6995473033438879646">"O inicio desta actividade en segundo plano desde <xliff:g id="PACKAGENAME">%1$s</xliff:g> bloquearase en futuras compilacións de Q. Consulta g.co/dev/bgblock."</string>
-    <string name="activity_starter_block_bg_activity_starts_enforcing" msgid="3317816771072146229">"Bloqueouse o inicio da actividade en segundo plano desde <xliff:g id="PACKAGENAME">%1$s</xliff:g>. Consulta g.co/dev/bgblock."</string>
     <string name="kg_forgot_pattern_button_text" msgid="8852021467868220608">"Esqueciches o padrón"</string>
     <string name="kg_wrong_pattern" msgid="1850806070801358830">"Padrón incorrecto"</string>
     <string name="kg_wrong_password" msgid="2333281762128113157">"Contrasinal incorrecto"</string>
@@ -1668,8 +1666,12 @@
     <string name="accessibility_shortcut_enabling_service" msgid="7771852911861522636">"O atallo de accesibilidade activou <xliff:g id="SERVICE_NAME">%1$s</xliff:g>"</string>
     <string name="accessibility_shortcut_disabling_service" msgid="2747243438223109821">"O atallo de accesibilidade desactivou <xliff:g id="SERVICE_NAME">%1$s</xliff:g>"</string>
     <string name="accessibility_shortcut_spoken_feedback" msgid="8376923232350078434">"Mantén premidas as teclas do volume durante tres segudos para usar <xliff:g id="SERVICE_NAME">%1$s</xliff:g>"</string>
-    <string name="accessibility_button_prompt_text" msgid="4234556536456854251">"Escolle que función queres utilizar cando toques o botón Accesibilidade:"</string>
-    <string name="accessibility_button_instructional_text" msgid="6942300463612999993">"Para cambiar as funcións, mantén premido o botón Accesibilidade."</string>
+    <string name="accessibility_button_prompt_text" msgid="1176658502969738564">"Escolle o servizo que queres utilizar cando toques o botón de accesibilidade:"</string>
+    <string name="accessibility_gesture_prompt_text" msgid="8259145549733019401">"Escolle o servizo que queres usar co xesto de accesibilidade (pasa dous dedos cara arriba desde a parte inferior da pantalla):"</string>
+    <string name="accessibility_gesture_3finger_prompt_text" msgid="1041435574275047665">"Escolle o servizo que queres usar co xesto de accesibilidade (pasa tres dedos cara arriba desde a parte inferior da pantalla):"</string>
+    <string name="accessibility_button_instructional_text" msgid="7003212763213614833">"Para cambiar de servizo, mantén premido o botón de accesibilidade."</string>
+    <string name="accessibility_gesture_instructional_text" msgid="5261788874937410950">"Para cambiar de servizo, pasa dous dedos cara arriba e mantén premida a pantalla."</string>
+    <string name="accessibility_gesture_3finger_instructional_text" msgid="4969448938984394550">"Para cambiar de servizo, pasa tres dedos cara arriba e mantén premida a pantalla."</string>
     <string name="accessibility_magnification_chooser_text" msgid="1227146738764986237">"Ampliación"</string>
     <string name="user_switched" msgid="3768006783166984410">"Usuario actual <xliff:g id="NAME">%1$s</xliff:g>."</string>
     <string name="user_switching_message" msgid="2871009331809089783">"Cambiando a <xliff:g id="NAME">%1$s</xliff:g>…"</string>
diff --git a/core/res/res/values-gu/strings.xml b/core/res/res/values-gu/strings.xml
index 9f13a9a..ab71914 100644
--- a/core/res/res/values-gu/strings.xml
+++ b/core/res/res/values-gu/strings.xml
@@ -131,6 +131,7 @@
     <!-- no translation found for wfcSpnFormat_spn (4998685024207291232) -->
     <skip />
     <string name="wfcSpnFormat_spn_wifi_calling" msgid="136001023263502280">"<xliff:g id="SPN">%s</xliff:g> વાઇ-ફાઇ કૉલિંગ"</string>
+    <string name="wfcSpnFormat_spn_wifi_calling_vo_hyphen" msgid="1730997175789582756">"<xliff:g id="SPN">%s</xliff:g> વાઇ-ફાઇ કૉલિંગ"</string>
     <string name="wfcSpnFormat_wlan_call" msgid="2533371081782489793">"WLAN કૉલ"</string>
     <string name="wfcSpnFormat_spn_wlan_call" msgid="2315240198303197168">"<xliff:g id="SPN">%s</xliff:g> WLAN કૉલ"</string>
     <string name="wfcSpnFormat_spn_wifi" msgid="6546481665561961938">"<xliff:g id="SPN">%s</xliff:g> વાઇ-ફાઇ"</string>
@@ -1358,8 +1359,7 @@
     <string name="test_harness_mode_notification_message" msgid="1343197173054407119">"ટેસ્ટ હાર્નેસ મોડ બંધ કરવા માટે ફૅક્ટરી રીસેટ કરો."</string>
     <string name="usb_contaminant_detected_title" msgid="7136400633704058349">"USB પોર્ટમાં પ્રવાહી કે ધૂળ"</string>
     <string name="usb_contaminant_detected_message" msgid="832337061059487250">"USB પોર્ટ ઑટોમૅટિક રીતે બંધ કરવામાં આવ્યો છે. વધુ જાણવા માટે ટૅપ કરો."</string>
-    <!-- no translation found for usb_contaminant_not_detected_title (7708281124088684821) -->
-    <skip />
+    <string name="usb_contaminant_not_detected_title" msgid="7708281124088684821">"USB પોર્ટનો ઉપયોગ કરવો યોગ્ય છે"</string>
     <string name="usb_contaminant_not_detected_message" msgid="2415791798244545292">"ફોનને હવે કોઈ પ્રવાહી કે ધૂળ હોવાનું જણાયું નથી."</string>
     <string name="taking_remote_bugreport_notification_title" msgid="6742483073875060934">"બગ રિપોર્ટ લઈ રહ્યાં છે…"</string>
     <string name="share_remote_bugreport_notification_title" msgid="4987095013583691873">"બગ રિપોર્ટ શેર કરીએ?"</string>
@@ -1613,8 +1613,6 @@
     <string name="display_manager_overlay_display_name" msgid="5142365982271620716">"#<xliff:g id="ID">%1$d</xliff:g> ઓવરલે કરો"</string>
     <string name="display_manager_overlay_display_title" msgid="652124517672257172">"<xliff:g id="NAME">%1$s</xliff:g>: <xliff:g id="WIDTH">%2$d</xliff:g>x<xliff:g id="HEIGHT">%3$d</xliff:g>, <xliff:g id="DPI">%4$d</xliff:g> dpi"</string>
     <string name="display_manager_overlay_display_secure_suffix" msgid="6022119702628572080">", સુરક્ષિત"</string>
-    <string name="activity_starter_block_bg_activity_starts_permissive" msgid="6995473033438879646">"<xliff:g id="PACKAGENAME">%1$s</xliff:g>માંથી શરૂ થયેલી આ બૅકગ્રાઉન્ડ પ્રવૃત્તિને ભાવિ Q બિલ્ડમાં બ્લૉક કરવામાં આવશે. g.co/dev/bgblock જુઓ."</string>
-    <string name="activity_starter_block_bg_activity_starts_enforcing" msgid="3317816771072146229">"<xliff:g id="PACKAGENAME">%1$s</xliff:g>માંથી શરૂ થયેલી બૅકગ્રાઉન્ડ પ્રવૃત્તિ બ્લૉક કરી છે. g.co/dev/bgblock જુઓ."</string>
     <string name="kg_forgot_pattern_button_text" msgid="8852021467868220608">"પૅટર્ન ભૂલી ગયાં"</string>
     <string name="kg_wrong_pattern" msgid="1850806070801358830">"ખોટી પૅટર્ન"</string>
     <string name="kg_wrong_password" msgid="2333281762128113157">"ખોટો પાસવર્ડ"</string>
@@ -1668,8 +1666,12 @@
     <string name="accessibility_shortcut_enabling_service" msgid="7771852911861522636">"ઍક્સેસિબિલિટી શૉર્ટકટે <xliff:g id="SERVICE_NAME">%1$s</xliff:g> ચાલુ કરી"</string>
     <string name="accessibility_shortcut_disabling_service" msgid="2747243438223109821">"ઍક્સેસિબિલિટી શૉર્ટકટે <xliff:g id="SERVICE_NAME">%1$s</xliff:g> બંધ કરી"</string>
     <string name="accessibility_shortcut_spoken_feedback" msgid="8376923232350078434">"<xliff:g id="SERVICE_NAME">%1$s</xliff:g>નો ઉપયોગ કરવા માટે બન્ને વૉલ્યૂમ કીને ત્રણ સેકન્ડ સુધી દબાવી રાખો"</string>
-    <string name="accessibility_button_prompt_text" msgid="4234556536456854251">"જ્યારે તમે ઍક્સેસિબિલિટી બટન પર ટૅપ કરો, ત્યારે ઉપયોગ કરવાની સુવિધા પસંદ કરો:"</string>
-    <string name="accessibility_button_instructional_text" msgid="6942300463612999993">"સુવિધાઓ બદલવા માટે, ઍક્સેસિબિલિટી બટન દબાવી રાખો."</string>
+    <string name="accessibility_button_prompt_text" msgid="1176658502969738564">"જ્યારે તમે ઍક્સેસિબિલિટી બટન પર ટૅપ કરો, ત્યારે ઉપયોગ કરવાની સેવા પસંદ કરો:"</string>
+    <string name="accessibility_gesture_prompt_text" msgid="8259145549733019401">"ઍક્સેસિબિલિટી સંકેત સાથે ઉપયોગ કરવાની સેવા પસંદ કરો (બે આંગળીઓ વડે સ્ક્રીનના નીચેના ભાગથી ઉપરની તરફ સ્વાઇપ કરવા માટે):"</string>
+    <string name="accessibility_gesture_3finger_prompt_text" msgid="1041435574275047665">"ઍક્સેસિબિલિટી સંકેત સાથે ઉપયોગ કરવાની સેવા પસંદ કરો (ત્રણ આંગળીઓ વડે સ્ક્રીનના નીચેના ભાગથી ઉપરની તરફ સ્વાઇપ કરવા માટે):"</string>
+    <string name="accessibility_button_instructional_text" msgid="7003212763213614833">"કોઈ એક સેવાથી બીજી સેવા પર સ્વિચ કરવા માટે, ઍક્સેસિબિલિટી બટનને ટચ કરીને દબાવી રાખો."</string>
+    <string name="accessibility_gesture_instructional_text" msgid="5261788874937410950">"કોઈ એક સેવાથી બીજી સેવા પર સ્વિચ કરવા માટે, બે આંગળીઓ વડે સ્ક્રીનની ઉપરની તરફ સ્વાઇપ કરીને દબાવી રાખો."</string>
+    <string name="accessibility_gesture_3finger_instructional_text" msgid="4969448938984394550">"કોઈ એક સેવાથી બીજી સેવા પર સ્વિચ કરવા માટે, ત્રણ આંગળીઓ વડે સ્ક્રીનની ઉપરની તરફ સ્વાઇપ કરીને દબાવી રાખો."</string>
     <string name="accessibility_magnification_chooser_text" msgid="1227146738764986237">"વિસ્તૃતીકરણ"</string>
     <string name="user_switched" msgid="3768006783166984410">"વર્તમાન વપરાશકર્તા <xliff:g id="NAME">%1$s</xliff:g>."</string>
     <string name="user_switching_message" msgid="2871009331809089783">"<xliff:g id="NAME">%1$s</xliff:g> પર સ્વિચ કરી રહ્યાં છે…"</string>
diff --git a/core/res/res/values-hi/strings.xml b/core/res/res/values-hi/strings.xml
index 933a024..4e9b0d2 100644
--- a/core/res/res/values-hi/strings.xml
+++ b/core/res/res/values-hi/strings.xml
@@ -131,6 +131,7 @@
     <!-- no translation found for wfcSpnFormat_spn (4998685024207291232) -->
     <skip />
     <string name="wfcSpnFormat_spn_wifi_calling" msgid="136001023263502280">"<xliff:g id="SPN">%s</xliff:g> वाई-फ़ाई कॉलिंग"</string>
+    <string name="wfcSpnFormat_spn_wifi_calling_vo_hyphen" msgid="1730997175789582756">"वाई-फ़ाई के ज़रिए कॉल करते समय <xliff:g id="SPN">%s</xliff:g>"</string>
     <string name="wfcSpnFormat_wlan_call" msgid="2533371081782489793">"WLAN कॉल"</string>
     <string name="wfcSpnFormat_spn_wlan_call" msgid="2315240198303197168">"<xliff:g id="SPN">%s</xliff:g> WLAN कॉल"</string>
     <string name="wfcSpnFormat_spn_wifi" msgid="6546481665561961938">"<xliff:g id="SPN">%s</xliff:g> वाई-फ़ाई"</string>
@@ -1357,8 +1358,7 @@
     <string name="test_harness_mode_notification_message" msgid="1343197173054407119">"टेस्ट हार्नेस मोड बंद करने के लिए फ़ैक्ट्री रीसेट करें."</string>
     <string name="usb_contaminant_detected_title" msgid="7136400633704058349">"यूएसबी पोर्ट में तरल चीज़ या कचरा है"</string>
     <string name="usb_contaminant_detected_message" msgid="832337061059487250">"यूएसबी पोर्ट अपने आप बंद हो गया है. ज़्यादा जानने के लिए टैप करें."</string>
-    <!-- no translation found for usb_contaminant_not_detected_title (7708281124088684821) -->
-    <skip />
+    <string name="usb_contaminant_not_detected_title" msgid="7708281124088684821">"यूएसबी पोर्ट का इस्तेमाल करना सुरक्षित है"</string>
     <string name="usb_contaminant_not_detected_message" msgid="2415791798244545292">"फ़ोन अब तरल चीज़ों या कचरे की पहचान नहीं करता."</string>
     <string name="taking_remote_bugreport_notification_title" msgid="6742483073875060934">"गड़बड़ी की रिपोर्ट ली जा रही है…"</string>
     <string name="share_remote_bugreport_notification_title" msgid="4987095013583691873">"गड़बड़ी की रिपोर्ट शेयर करें?"</string>
@@ -1456,7 +1456,7 @@
     <string name="chooser_wallpaper" msgid="7873476199295190279">"वॉलपेपर बदलें"</string>
     <string name="notification_listener_binding_label" msgid="2014162835481906429">"सूचना को सुनने की सुविधा"</string>
     <string name="vr_listener_binding_label" msgid="4316591939343607306">"VR श्रोता"</string>
-    <string name="condition_provider_service_binding_label" msgid="1321343352906524564">"स्थिति प्रदाता"</string>
+    <string name="condition_provider_service_binding_label" msgid="1321343352906524564">"स्थिति देने वाली"</string>
     <string name="notification_ranker_binding_label" msgid="774540592299064747">"सूचना रैंकर सेवा"</string>
     <string name="vpn_title" msgid="19615213552042827">"VPN सक्रिय"</string>
     <string name="vpn_title_long" msgid="6400714798049252294">"VPN को <xliff:g id="APP">%s</xliff:g> द्वारा सक्रिय किया गया है"</string>
@@ -1494,7 +1494,7 @@
     <string name="find_next" msgid="5742124618942193978">"आगे ढूंढें"</string>
     <string name="find_previous" msgid="2196723669388360506">"पिछला ढूंढें"</string>
     <string name="gpsNotifTicker" msgid="5622683912616496172">"<xliff:g id="NAME">%s</xliff:g> ने जगह का अनुरोध किया गया है"</string>
-    <string name="gpsNotifTitle" msgid="5446858717157416839">"जगह का अनुरोध किया जा रहा है"</string>
+    <string name="gpsNotifTitle" msgid="5446858717157416839">"जगह की जानकारी मांगी जा रही है"</string>
     <string name="gpsNotifMessage" msgid="1374718023224000702">"<xliff:g id="NAME">%1$s</xliff:g> (<xliff:g id="SERVICE">%2$s</xliff:g>) द्वारा अनुरोधित"</string>
     <string name="gpsVerifYes" msgid="2346566072867213563">"हां"</string>
     <string name="gpsVerifNo" msgid="1146564937346454865">"नहीं"</string>
@@ -1612,8 +1612,6 @@
     <string name="display_manager_overlay_display_name" msgid="5142365982271620716">"ओवरले #<xliff:g id="ID">%1$d</xliff:g>"</string>
     <string name="display_manager_overlay_display_title" msgid="652124517672257172">"<xliff:g id="NAME">%1$s</xliff:g>: <xliff:g id="WIDTH">%2$d</xliff:g>x<xliff:g id="HEIGHT">%3$d</xliff:g>, <xliff:g id="DPI">%4$d</xliff:g> dpi"</string>
     <string name="display_manager_overlay_display_secure_suffix" msgid="6022119702628572080">", सुरक्षित"</string>
-    <string name="activity_starter_block_bg_activity_starts_permissive" msgid="6995473033438879646">"आने वाले Q बिल्ड में <xliff:g id="PACKAGENAME">%1$s</xliff:g> के बैकग्राउंड में गतिविधि शुरू करने पर रोक लगा दी जाएगी. इस बारे में जानने के लिए g.co/dev/bgblock पर जाएं."</string>
-    <string name="activity_starter_block_bg_activity_starts_enforcing" msgid="3317816771072146229">"<xliff:g id="PACKAGENAME">%1$s</xliff:g> के बैकग्राउंड में गतिविधि शुरू करने पर रोक लगा दी गई है. इस बारे में जानने के लिए g.co/dev/bgblock पर जाएं."</string>
     <string name="kg_forgot_pattern_button_text" msgid="8852021467868220608">"आकार भूल गए"</string>
     <string name="kg_wrong_pattern" msgid="1850806070801358830">"गलत पैटर्न डाला गया है"</string>
     <string name="kg_wrong_password" msgid="2333281762128113157">"गलत पासवर्ड"</string>
@@ -1667,8 +1665,12 @@
     <string name="accessibility_shortcut_enabling_service" msgid="7771852911861522636">"सुलभता शॉर्टकट ने <xliff:g id="SERVICE_NAME">%1$s</xliff:g> को चालू किया"</string>
     <string name="accessibility_shortcut_disabling_service" msgid="2747243438223109821">"सुलभता शॉर्टकट ने <xliff:g id="SERVICE_NAME">%1$s</xliff:g> को बंद किया"</string>
     <string name="accessibility_shortcut_spoken_feedback" msgid="8376923232350078434">"<xliff:g id="SERVICE_NAME">%1$s</xliff:g> इस्तेमाल करने के लिए आवाज़ वाले दोनों बटन तीन सेकंड तक दबाकर रखें"</string>
-    <string name="accessibility_button_prompt_text" msgid="4234556536456854251">"सुलभता बटन पर टैप करते समय इस्तेमाल की जाने वाली सुविधा चुनें:"</string>
-    <string name="accessibility_button_instructional_text" msgid="6942300463612999993">"सुविधाओं में बदलाव करने के लिए, सुलभता बटन को दबाकर रखें."</string>
+    <string name="accessibility_button_prompt_text" msgid="1176658502969738564">"\'सुलभता\' बटन पर टैप करके इस्तेमाल करने के लिए सेवा चुनें:"</string>
+    <string name="accessibility_gesture_prompt_text" msgid="8259145549733019401">"सुलभता वाले जेस्चर के साथ इस्तेमाल करने के लिए सेवा चुनें (दो उंगलियों से स्क्रीन पर सबसे नीचे से ऊपर की ओर स्वाइप करें):"</string>
+    <string name="accessibility_gesture_3finger_prompt_text" msgid="1041435574275047665">"सुलभता वाले जेस्चर के साथ इस्तेमाल करने के लिए सेवा चुनें (तीन उंगलियों से स्क्रीन पर सबसे नीचे से ऊपर की ओर स्वाइप करें):"</string>
+    <string name="accessibility_button_instructional_text" msgid="7003212763213614833">"एक सेवा से दूसरी सेवा पर जाने के लिए, \'सुलभता\' बटन को कुछ देर दबाकर रखें."</string>
+    <string name="accessibility_gesture_instructional_text" msgid="5261788874937410950">"एक सेवा से दूसरी सेवा पर जाने के लिए, स्क्रीन पर दो उंगलियों से ऊपर की ओर स्वाइप करें और थोड़ी देर तक स्क्रीन पर उंगलियां रखे रहें."</string>
+    <string name="accessibility_gesture_3finger_instructional_text" msgid="4969448938984394550">"एक सेवा से दूसरी सेवा पर जाने के लिए, स्क्रीन पर तीन उंगलियों से ऊपर की ओर स्वाइप करें और थोड़ी देर तक स्क्रीन पर उंगलियां रखे रहें."</string>
     <string name="accessibility_magnification_chooser_text" msgid="1227146738764986237">"बड़ा करना"</string>
     <string name="user_switched" msgid="3768006783166984410">"मौजूदा उपयोगकर्ता <xliff:g id="NAME">%1$s</xliff:g>."</string>
     <string name="user_switching_message" msgid="2871009331809089783">"<xliff:g id="NAME">%1$s</xliff:g> पर स्विच किया जा रहा है…"</string>
diff --git a/core/res/res/values-hr/strings.xml b/core/res/res/values-hr/strings.xml
index b55ff89..83c3901 100644
--- a/core/res/res/values-hr/strings.xml
+++ b/core/res/res/values-hr/strings.xml
@@ -132,6 +132,7 @@
     <!-- no translation found for wfcSpnFormat_spn (4998685024207291232) -->
     <skip />
     <string name="wfcSpnFormat_spn_wifi_calling" msgid="136001023263502280">"<xliff:g id="SPN">%s</xliff:g> Wi-Fi pozivi"</string>
+    <string name="wfcSpnFormat_spn_wifi_calling_vo_hyphen" msgid="1730997175789582756">"<xliff:g id="SPN">%s</xliff:g> Wi-Fi pozivi"</string>
     <string name="wfcSpnFormat_wlan_call" msgid="2533371081782489793">"Poziv putem WLAN-a"</string>
     <string name="wfcSpnFormat_spn_wlan_call" msgid="2315240198303197168">"<xliff:g id="SPN">%s</xliff:g> poziv putem WLAN-a"</string>
     <string name="wfcSpnFormat_spn_wifi" msgid="6546481665561961938">"<xliff:g id="SPN">%s</xliff:g> Wi-Fi"</string>
@@ -1379,8 +1380,7 @@
     <string name="test_harness_mode_notification_message" msgid="1343197173054407119">"Vratite na tvorničke postavke da biste onemogućili način testnog okvira."</string>
     <string name="usb_contaminant_detected_title" msgid="7136400633704058349">"Tekućina ili prljavština u USB priključku"</string>
     <string name="usb_contaminant_detected_message" msgid="832337061059487250">"USB priključak automatski je onemogućen. Dodirnite da biste saznali više."</string>
-    <!-- no translation found for usb_contaminant_not_detected_title (7708281124088684821) -->
-    <skip />
+    <string name="usb_contaminant_not_detected_title" msgid="7708281124088684821">"Možete koristiti USB priključak"</string>
     <string name="usb_contaminant_not_detected_message" msgid="2415791798244545292">"Telefon više ne otkriva tekućinu ili prljavštinu."</string>
     <string name="taking_remote_bugreport_notification_title" msgid="6742483073875060934">"Izrada izvješća o programskoj pogrešci…"</string>
     <string name="share_remote_bugreport_notification_title" msgid="4987095013583691873">"Želite li podijeliti izvješće o programskoj pogrešci?"</string>
@@ -1635,8 +1635,6 @@
     <string name="display_manager_overlay_display_name" msgid="5142365982271620716">"Preklapanje br. <xliff:g id="ID">%1$d</xliff:g>"</string>
     <string name="display_manager_overlay_display_title" msgid="652124517672257172">"<xliff:g id="NAME">%1$s</xliff:g>: <xliff:g id="WIDTH">%2$d</xliff:g> x <xliff:g id="HEIGHT">%3$d</xliff:g>, <xliff:g id="DPI">%4$d</xliff:g> dpi"</string>
     <string name="display_manager_overlay_display_secure_suffix" msgid="6022119702628572080">", sigurno"</string>
-    <string name="activity_starter_block_bg_activity_starts_permissive" msgid="6995473033438879646">"Pokretanje aktivnosti u pozadini iz aplikacije <xliff:g id="PACKAGENAME">%1$s</xliff:g> blokirat će se u budućim međuverzijama Q. Pogledajte g.co/dev/bgblock."</string>
-    <string name="activity_starter_block_bg_activity_starts_enforcing" msgid="3317816771072146229">"Blokirano je pokretanje aktivnosti u pozadini iz aplikacije <xliff:g id="PACKAGENAME">%1$s</xliff:g>. Pogledajte g.co/dev/bgblock."</string>
     <string name="kg_forgot_pattern_button_text" msgid="8852021467868220608">"Zaboravili ste obrazac"</string>
     <string name="kg_wrong_pattern" msgid="1850806070801358830">"Pogrešan obrazac"</string>
     <string name="kg_wrong_password" msgid="2333281762128113157">"Pogrešna zaporka"</string>
@@ -1691,8 +1689,12 @@
     <string name="accessibility_shortcut_enabling_service" msgid="7771852911861522636">"Prečac pristupačnosti uključio je uslugu <xliff:g id="SERVICE_NAME">%1$s</xliff:g>"</string>
     <string name="accessibility_shortcut_disabling_service" msgid="2747243438223109821">"Prečac pristupačnosti isključio je uslugu <xliff:g id="SERVICE_NAME">%1$s</xliff:g>"</string>
     <string name="accessibility_shortcut_spoken_feedback" msgid="8376923232350078434">"Pritisnite i zadržite tipke za glasnoću na tri sekunde da biste koristili uslugu <xliff:g id="SERVICE_NAME">%1$s</xliff:g>"</string>
-    <string name="accessibility_button_prompt_text" msgid="4234556536456854251">"Odaberite značajku koju ćete upotrebljavati kada dodirnete gumb Pristupačnost:"</string>
-    <string name="accessibility_button_instructional_text" msgid="6942300463612999993">"Da biste promijenili značajke, dodirnite i zadržite gumb Pristupačnost."</string>
+    <string name="accessibility_button_prompt_text" msgid="1176658502969738564">"Odaberite uslugu koju ćete upotrebljavati kad dodirnete gumb pristupačnosti:"</string>
+    <string name="accessibility_gesture_prompt_text" msgid="8259145549733019401">"Odaberite uslugu koju ćete upotrebljavati uz pokret pristupačnosti (prelazak s dva prsta prema gore od dna zaslona):"</string>
+    <string name="accessibility_gesture_3finger_prompt_text" msgid="1041435574275047665">"Odaberite uslugu koju ćete upotrebljavati uz pokret pristupačnosti (prelazak s tri prsta prema gore od dna zaslona):"</string>
+    <string name="accessibility_button_instructional_text" msgid="7003212763213614833">"Da biste prešli na neku drugu uslugu, dodirnite i zadržite gumb pristupačnosti."</string>
+    <string name="accessibility_gesture_instructional_text" msgid="5261788874937410950">"Da biste prešli na neku drugu uslugu, prijeđite s dva prsta prema gore i zadržite."</string>
+    <string name="accessibility_gesture_3finger_instructional_text" msgid="4969448938984394550">"Da biste prešli na neku drugu uslugu, prijeđite s tri prsta prema gore i zadržite."</string>
     <string name="accessibility_magnification_chooser_text" msgid="1227146738764986237">"Povećavanje"</string>
     <string name="user_switched" msgid="3768006783166984410">"Trenutačni korisnik <xliff:g id="NAME">%1$s</xliff:g>."</string>
     <string name="user_switching_message" msgid="2871009331809089783">"Prebacivanje na korisnika <xliff:g id="NAME">%1$s</xliff:g>…"</string>
diff --git a/core/res/res/values-hu/strings.xml b/core/res/res/values-hu/strings.xml
index 0555c06..c37cf3a 100644
--- a/core/res/res/values-hu/strings.xml
+++ b/core/res/res/values-hu/strings.xml
@@ -131,6 +131,7 @@
     <!-- no translation found for wfcSpnFormat_spn (4998685024207291232) -->
     <skip />
     <string name="wfcSpnFormat_spn_wifi_calling" msgid="136001023263502280">"<xliff:g id="SPN">%s</xliff:g> Wi-Fi-hívás"</string>
+    <string name="wfcSpnFormat_spn_wifi_calling_vo_hyphen" msgid="1730997175789582756">"<xliff:g id="SPN">%s</xliff:g> Wi‑Fi-hívás"</string>
     <string name="wfcSpnFormat_wlan_call" msgid="2533371081782489793">"WLAN-hívás"</string>
     <string name="wfcSpnFormat_spn_wlan_call" msgid="2315240198303197168">"<xliff:g id="SPN">%s</xliff:g> WLAN-hívás"</string>
     <string name="wfcSpnFormat_spn_wifi" msgid="6546481665561961938">"<xliff:g id="SPN">%s</xliff:g> Wi-Fi"</string>
@@ -1357,8 +1358,7 @@
     <string name="test_harness_mode_notification_message" msgid="1343197173054407119">"A Tesztelési alapkörnyezet mód kikapcsolásához állítsa vissza a gyári beállításokat."</string>
     <string name="usb_contaminant_detected_title" msgid="7136400633704058349">"Folyadék vagy szennyeződés az USB-portban"</string>
     <string name="usb_contaminant_detected_message" msgid="832337061059487250">"USB-port automatikusan letiltva. Koppintson, ha további információra van szüksége."</string>
-    <!-- no translation found for usb_contaminant_not_detected_title (7708281124088684821) -->
-    <skip />
+    <string name="usb_contaminant_not_detected_title" msgid="7708281124088684821">"Az USB-port rendben használható"</string>
     <string name="usb_contaminant_not_detected_message" msgid="2415791798244545292">"A telefon már nem észlel folyadékot vagy szennyeződést."</string>
     <string name="taking_remote_bugreport_notification_title" msgid="6742483073875060934">"Hibajelentés készítése…"</string>
     <string name="share_remote_bugreport_notification_title" msgid="4987095013583691873">"Megosztja a hibajelentést?"</string>
@@ -1612,8 +1612,6 @@
     <string name="display_manager_overlay_display_name" msgid="5142365982271620716">"<xliff:g id="ID">%1$d</xliff:g>. fedvény"</string>
     <string name="display_manager_overlay_display_title" msgid="652124517672257172">"<xliff:g id="NAME">%1$s</xliff:g>: <xliff:g id="WIDTH">%2$d</xliff:g> x <xliff:g id="HEIGHT">%3$d</xliff:g>, <xliff:g id="DPI">%4$d</xliff:g> képpont"</string>
     <string name="display_manager_overlay_display_secure_suffix" msgid="6022119702628572080">", biztonságos"</string>
-    <string name="activity_starter_block_bg_activity_starts_permissive" msgid="6995473033438879646">"Ez a háttértevékenység-indítás le lesz tiltva a(z) <xliff:g id="PACKAGENAME">%1$s</xliff:g> számára a jövőbeni Q-buildeknél. Lásd: g.co/dev/bgblock."</string>
-    <string name="activity_starter_block_bg_activity_starts_enforcing" msgid="3317816771072146229">"A(z) <xliff:g id="PACKAGENAME">%1$s</xliff:g> számára le van tiltva a háttértevékenységek indítása. Lásd: g.co/dev/bgblock."</string>
     <string name="kg_forgot_pattern_button_text" msgid="8852021467868220608">"Elfelejtett minta"</string>
     <string name="kg_wrong_pattern" msgid="1850806070801358830">"Helytelen minta"</string>
     <string name="kg_wrong_password" msgid="2333281762128113157">"Helytelen jelszó"</string>
@@ -1667,8 +1665,12 @@
     <string name="accessibility_shortcut_enabling_service" msgid="7771852911861522636">"A Kisegítő lehetőségek gyorsparancsa bekapcsolta a következő szolgáltatást: <xliff:g id="SERVICE_NAME">%1$s</xliff:g>"</string>
     <string name="accessibility_shortcut_disabling_service" msgid="2747243438223109821">"A Kisegítő lehetőségek gyorsparancsa kikapcsolta a következő szolgáltatást: <xliff:g id="SERVICE_NAME">%1$s</xliff:g>"</string>
     <string name="accessibility_shortcut_spoken_feedback" msgid="8376923232350078434">"A(z) <xliff:g id="SERVICE_NAME">%1$s</xliff:g> használatához tartsa lenyomva három másodpercig a két hangerőgombot"</string>
-    <string name="accessibility_button_prompt_text" msgid="4234556536456854251">"Válassza ki a Kisegítő lehetőségek gombra koppintáskor használni kívánt funkciót:"</string>
-    <string name="accessibility_button_instructional_text" msgid="6942300463612999993">"A funkciók módosításához tartsa lenyomva a Kisegítő lehetőségek gombot."</string>
+    <string name="accessibility_button_prompt_text" msgid="1176658502969738564">"Válassza ki a kisegítő lehetőségek gombra koppintáskor használni kívánt szolgáltatást:"</string>
+    <string name="accessibility_gesture_prompt_text" msgid="8259145549733019401">"Válassza ki a kisegítő kézmozdulattal használni kívánt szolgáltatást (csúsztassa felfelé két ujját a képernyő aljáról):"</string>
+    <string name="accessibility_gesture_3finger_prompt_text" msgid="1041435574275047665">"Válassza ki a kisegítő kézmozdulattal használni kívánt szolgáltatást (csúsztassa felfelé három ujját a képernyő aljáról):"</string>
+    <string name="accessibility_button_instructional_text" msgid="7003212763213614833">"A szolgáltatások közötti váltáshoz tartsa lenyomva a kisegítő lehetőségek gombot."</string>
+    <string name="accessibility_gesture_instructional_text" msgid="5261788874937410950">"A szolgáltatások közötti váltáshoz csúsztassa felfelé két ujját, és ne engedje el a képernyőt."</string>
+    <string name="accessibility_gesture_3finger_instructional_text" msgid="4969448938984394550">"A szolgáltatások közötti váltáshoz csúsztassa felfelé három ujját, és ne engedje el a képernyőt."</string>
     <string name="accessibility_magnification_chooser_text" msgid="1227146738764986237">"Nagyítás"</string>
     <string name="user_switched" msgid="3768006783166984410">"<xliff:g id="NAME">%1$s</xliff:g> az aktuális felhasználó."</string>
     <string name="user_switching_message" msgid="2871009331809089783">"Átváltás erre: <xliff:g id="NAME">%1$s</xliff:g>..."</string>
diff --git a/core/res/res/values-hy/strings.xml b/core/res/res/values-hy/strings.xml
index 0253757..7f78ae7 100644
--- a/core/res/res/values-hy/strings.xml
+++ b/core/res/res/values-hy/strings.xml
@@ -131,6 +131,7 @@
     <!-- no translation found for wfcSpnFormat_spn (4998685024207291232) -->
     <skip />
     <string name="wfcSpnFormat_spn_wifi_calling" msgid="136001023263502280">"<xliff:g id="SPN">%s</xliff:g> Wi-Fi-ի միջոցով զանգեր"</string>
+    <string name="wfcSpnFormat_spn_wifi_calling_vo_hyphen" msgid="1730997175789582756">"<xliff:g id="SPN">%s</xliff:g> Զանգեր Wi-Fi-ի միջոցով"</string>
     <string name="wfcSpnFormat_wlan_call" msgid="2533371081782489793">"Զանգ WLAN ցանցով"</string>
     <string name="wfcSpnFormat_spn_wlan_call" msgid="2315240198303197168">"<xliff:g id="SPN">%s</xliff:g> WLAN ցանցով զանգեր"</string>
     <string name="wfcSpnFormat_spn_wifi" msgid="6546481665561961938">"<xliff:g id="SPN">%s</xliff:g> Wi-Fi"</string>
@@ -280,7 +281,7 @@
     <string name="permgrouprequest_contacts" msgid="6032805601881764300">"Թույլատրե՞լ &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; հավելվածին օգտագործել ձեր կոնտակտները"</string>
     <string name="permgrouplab_location" msgid="7275582855722310164">"Տեղորոշում"</string>
     <string name="permgroupdesc_location" msgid="1346617465127855033">"տեղորոշել այս սարքը"</string>
-    <string name="permgrouprequest_location" msgid="3788275734953323491">"Թույլատրե՞լ &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt;-ին օգտագործել այս սարքի տեղադրության տվյալները"</string>
+    <string name="permgrouprequest_location" msgid="3788275734953323491">"Թույլատրե՞լ &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; հավելվածին օգտագործել այս սարքի տեղադրության տվյալները"</string>
     <string name="permgrouprequestdetail_location" msgid="1347189607421252902">"Տեղադրության տվյալները հասանելի կլինեն հավելվածին, միայն երբ այն օգտագործելիս լինեք"</string>
     <string name="permgroupbackgroundrequest_location" msgid="5039063878675613235">"&lt;b&gt;Միշտ&lt;/b&gt; հասանելի դարձնե՞լ &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; հավելվածին ձեր սարքի տեղադրությունը"</string>
     <string name="permgroupbackgroundrequestdetail_location" msgid="4597006851453417387">"Տեղադրության տվյալները հասանելի կլինեն հավելվածին, միայն երբ այն օգտագործելիս լինեք"</string>
@@ -1357,8 +1358,7 @@
     <string name="test_harness_mode_notification_message" msgid="1343197173054407119">"Թեստային ռեժիմն անջատելու համար զրոյացրեք կարգավորումները։"</string>
     <string name="usb_contaminant_detected_title" msgid="7136400633704058349">"USB միացքում ջուր կամ աղտ է հայտնաբերվել"</string>
     <string name="usb_contaminant_detected_message" msgid="832337061059487250">"USB միացքն ավտոմատ անջատվել է: Հպեք՝ ավելին իմանալու համար:"</string>
-    <!-- no translation found for usb_contaminant_not_detected_title (7708281124088684821) -->
-    <skip />
+    <string name="usb_contaminant_not_detected_title" msgid="7708281124088684821">"USB միացքը կարող է օգտագործվել"</string>
     <string name="usb_contaminant_not_detected_message" msgid="2415791798244545292">"Հեռախոսում ջուր կամ աղտ չի հայտնաբերվել:"</string>
     <string name="taking_remote_bugreport_notification_title" msgid="6742483073875060934">"Վրիպակի զեկույցի ստեղծում…"</string>
     <string name="share_remote_bugreport_notification_title" msgid="4987095013583691873">"Տրամադրե՞լ վրիպակի զեկույցը:"</string>
@@ -1612,8 +1612,6 @@
     <string name="display_manager_overlay_display_name" msgid="5142365982271620716">"Վերածածկ #<xliff:g id="ID">%1$d</xliff:g>"</string>
     <string name="display_manager_overlay_display_title" msgid="652124517672257172">"<xliff:g id="NAME">%1$s</xliff:g>. <xliff:g id="WIDTH">%2$d</xliff:g>x<xliff:g id="HEIGHT">%3$d</xliff:g>, <xliff:g id="DPI">%4$d</xliff:g> կմվ"</string>
     <string name="display_manager_overlay_display_secure_suffix" msgid="6022119702628572080">", անվտանգ"</string>
-    <string name="activity_starter_block_bg_activity_starts_permissive" msgid="6995473033438879646">"<xliff:g id="PACKAGENAME">%1$s</xliff:g> հավելվածի գործողությունները ֆոնային ռեժիմում կարգելափակվեն Android Q-ի հաջորդ կառուցումներում։ Մանրամասն տեղեկություններ կարող եք գտնել g.co/dev/bgblock էջում։"</string>
-    <string name="activity_starter_block_bg_activity_starts_enforcing" msgid="3317816771072146229">"<xliff:g id="PACKAGENAME">%1$s</xliff:g> հավելվածի գործողությունները ֆոնային ռեժիմում արգելափակվեցին։ Մանրամասն տեղեկություններ կարող եք գտնել g.co/dev/bgblock էջում։"</string>
     <string name="kg_forgot_pattern_button_text" msgid="8852021467868220608">"Մոռացել եմ սխեման"</string>
     <string name="kg_wrong_pattern" msgid="1850806070801358830">"Սխալ սխեմա"</string>
     <string name="kg_wrong_password" msgid="2333281762128113157">"Սխալ գաղտնաբառ"</string>
@@ -1667,8 +1665,12 @@
     <string name="accessibility_shortcut_enabling_service" msgid="7771852911861522636">"Մատչելիության դյուրանցումն միացրել է <xliff:g id="SERVICE_NAME">%1$s</xliff:g> ծառայությունը"</string>
     <string name="accessibility_shortcut_disabling_service" msgid="2747243438223109821">"Մատչելիության դյուրանցումն անջատել է <xliff:g id="SERVICE_NAME">%1$s</xliff:g> ծառայությունը"</string>
     <string name="accessibility_shortcut_spoken_feedback" msgid="8376923232350078434">"«<xliff:g id="SERVICE_NAME">%1$s</xliff:g>» ծառայությունն օգտագործելու համար սեղմեք և 3 վայրկյան պահեք ձայնի ուժգնության երկու կոճակները"</string>
-    <string name="accessibility_button_prompt_text" msgid="4234556536456854251">"Ընտրեք որևէ գործառույթ, որը կօգտագործվի Հատուկ գործառույթներ կոճակին հպելու դեպքում՝"</string>
-    <string name="accessibility_button_instructional_text" msgid="6942300463612999993">"Գործառույթները փոխելու համար հպեք և պահեք Հատուկ գործառույթներ կոճակը։"</string>
+    <string name="accessibility_button_prompt_text" msgid="1176658502969738564">"Ընտրեք գործառույթ, որը կգործարկվի «Հատուկ գործառույթներ» կոճակին հպելու դեպքում՝"</string>
+    <string name="accessibility_gesture_prompt_text" msgid="8259145549733019401">"Ընտրեք գործառույթ, որը կգործարկվի հատուկ գործառույթների ժեստն անելու դեպքում (երկու մատը էկրանի ներքևից սահեցրեք վերև)՝"</string>
+    <string name="accessibility_gesture_3finger_prompt_text" msgid="1041435574275047665">"Ընտրեք գործառույթ, որը կգործարկվի հատուկ գործառույթների ժեստն անելու դեպքում (երեք մատը էկրանի ներքևից սահեցրեք վերև)՝"</string>
+    <string name="accessibility_button_instructional_text" msgid="7003212763213614833">"Մեկ գործառույթից մյուսն անցնելու համար հպեք «Հատուկ գործառույթներ» կոճակին և պահեք:"</string>
+    <string name="accessibility_gesture_instructional_text" msgid="5261788874937410950">"Մեկ գործառույթից մյուսն անցնելու համար երկու մատը սահեցրեք վերև և պահեք:"</string>
+    <string name="accessibility_gesture_3finger_instructional_text" msgid="4969448938984394550">"Մեկ գործառույթից մյուսն անցնելու համար երեք մատը սահեցրեք վերև և պահեք:"</string>
     <string name="accessibility_magnification_chooser_text" msgid="1227146738764986237">"Խոշորացում"</string>
     <string name="user_switched" msgid="3768006783166984410">"Ներկայիս օգտատերը <xliff:g id="NAME">%1$s</xliff:g>:"</string>
     <string name="user_switching_message" msgid="2871009331809089783">"Փոխարկվում է <xliff:g id="NAME">%1$s</xliff:g>-ին..."</string>
diff --git a/core/res/res/values-in/strings.xml b/core/res/res/values-in/strings.xml
index cb91f85..2aaa445 100644
--- a/core/res/res/values-in/strings.xml
+++ b/core/res/res/values-in/strings.xml
@@ -131,6 +131,7 @@
     <!-- no translation found for wfcSpnFormat_spn (4998685024207291232) -->
     <skip />
     <string name="wfcSpnFormat_spn_wifi_calling" msgid="136001023263502280">"Panggilan Wi-Fi <xliff:g id="SPN">%s</xliff:g>"</string>
+    <string name="wfcSpnFormat_spn_wifi_calling_vo_hyphen" msgid="1730997175789582756">"Panggilan Wi-Fi <xliff:g id="SPN">%s</xliff:g>"</string>
     <string name="wfcSpnFormat_wlan_call" msgid="2533371081782489793">"Panggilan WLAN"</string>
     <string name="wfcSpnFormat_spn_wlan_call" msgid="2315240198303197168">"Panggilan WLAN <xliff:g id="SPN">%s</xliff:g>"</string>
     <string name="wfcSpnFormat_spn_wifi" msgid="6546481665561961938">"Wi-Fi <xliff:g id="SPN">%s</xliff:g>"</string>
@@ -1611,8 +1612,6 @@
     <string name="display_manager_overlay_display_name" msgid="5142365982271620716">"Hamparan #<xliff:g id="ID">%1$d</xliff:g>"</string>
     <string name="display_manager_overlay_display_title" msgid="652124517672257172">"<xliff:g id="NAME">%1$s</xliff:g>: <xliff:g id="WIDTH">%2$d</xliff:g>x<xliff:g id="HEIGHT">%3$d</xliff:g>, <xliff:g id="DPI">%4$d</xliff:g> dpi"</string>
     <string name="display_manager_overlay_display_secure_suffix" msgid="6022119702628572080">", aman"</string>
-    <string name="activity_starter_block_bg_activity_starts_permissive" msgid="6995473033438879646">"Aktivitas latar belakang yang dimulai dari <xliff:g id="PACKAGENAME">%1$s</xliff:g> akan diblokir di build Q di masa mendatang. Lihat g.co/dev/bgblock."</string>
-    <string name="activity_starter_block_bg_activity_starts_enforcing" msgid="3317816771072146229">"Aktivitas latar belakang yang dimulai dari <xliff:g id="PACKAGENAME">%1$s</xliff:g> diblokir. Lihat g.co/dev/bgblock."</string>
     <string name="kg_forgot_pattern_button_text" msgid="8852021467868220608">"Lupa Pola?"</string>
     <string name="kg_wrong_pattern" msgid="1850806070801358830">"Pola Salah"</string>
     <string name="kg_wrong_password" msgid="2333281762128113157">"Sandi Salah"</string>
@@ -1666,8 +1665,12 @@
     <string name="accessibility_shortcut_enabling_service" msgid="7771852911861522636">"Pintasan Aksesibilitas mengaktifkan <xliff:g id="SERVICE_NAME">%1$s</xliff:g>"</string>
     <string name="accessibility_shortcut_disabling_service" msgid="2747243438223109821">"Pintasan Aksesibilitas menonaktifkan <xliff:g id="SERVICE_NAME">%1$s</xliff:g>"</string>
     <string name="accessibility_shortcut_spoken_feedback" msgid="8376923232350078434">"Tekan dan tahan kedua tombol volume selama tiga detik untuk menggunakan <xliff:g id="SERVICE_NAME">%1$s</xliff:g>"</string>
-    <string name="accessibility_button_prompt_text" msgid="4234556536456854251">"Pilih fitur yang akan digunakan saat menge-tap tombol Aksesibilitas:"</string>
-    <string name="accessibility_button_instructional_text" msgid="6942300463612999993">"Untuk mengubah fitur, sentuh &amp; tahan tombol Aksesibilitas."</string>
+    <string name="accessibility_button_prompt_text" msgid="1176658502969738564">"Pilih layanan yang akan digunakan saat menge-tap tombol aksesibilitas:"</string>
+    <string name="accessibility_gesture_prompt_text" msgid="8259145549733019401">"Pilih layanan yang akan digunakan dengan gestur aksesibilitas (geser ke atas dari bawah layar dengan dua jari):"</string>
+    <string name="accessibility_gesture_3finger_prompt_text" msgid="1041435574275047665">"Pilih layanan yang akan digunakan dengan gestur aksesibilitas (geser ke atas dari bawah layar dengan tiga jari):"</string>
+    <string name="accessibility_button_instructional_text" msgid="7003212763213614833">"Sentuh &amp; tahan tombol aksesibilitas untuk beralih layanan."</string>
+    <string name="accessibility_gesture_instructional_text" msgid="5261788874937410950">"Geser dengan dua jari dan tahan untuk beralih layanan."</string>
+    <string name="accessibility_gesture_3finger_instructional_text" msgid="4969448938984394550">"Geser ke atas dengan tiga jari dan tahan untuk beralih layanan."</string>
     <string name="accessibility_magnification_chooser_text" msgid="1227146738764986237">"Pembesaran"</string>
     <string name="user_switched" msgid="3768006783166984410">"Pengguna saat ini <xliff:g id="NAME">%1$s</xliff:g>."</string>
     <string name="user_switching_message" msgid="2871009331809089783">"Beralih ke <xliff:g id="NAME">%1$s</xliff:g>…"</string>
diff --git a/core/res/res/values-is/strings.xml b/core/res/res/values-is/strings.xml
index 9452846..d11fead 100644
--- a/core/res/res/values-is/strings.xml
+++ b/core/res/res/values-is/strings.xml
@@ -131,6 +131,7 @@
     <!-- no translation found for wfcSpnFormat_spn (4998685024207291232) -->
     <skip />
     <string name="wfcSpnFormat_spn_wifi_calling" msgid="136001023263502280">"<xliff:g id="SPN">%s</xliff:g> Wi-Fi símtöl"</string>
+    <string name="wfcSpnFormat_spn_wifi_calling_vo_hyphen" msgid="1730997175789582756">"Wi-Fi símtöl með <xliff:g id="SPN">%s</xliff:g>"</string>
     <string name="wfcSpnFormat_wlan_call" msgid="2533371081782489793">"WLAN-símtal"</string>
     <string name="wfcSpnFormat_spn_wlan_call" msgid="2315240198303197168">"<xliff:g id="SPN">%s</xliff:g> WLAN-símtal"</string>
     <string name="wfcSpnFormat_spn_wifi" msgid="6546481665561961938">"<xliff:g id="SPN">%s</xliff:g> Wi-Fi"</string>
@@ -1358,8 +1359,7 @@
     <string name="test_harness_mode_notification_message" msgid="1343197173054407119">"Núllstilltu til að slökkva á stillingu prófunarvangs."</string>
     <string name="usb_contaminant_detected_title" msgid="7136400633704058349">"Vökvi eða óhreinindi í USB-tengi"</string>
     <string name="usb_contaminant_detected_message" msgid="832337061059487250">"USB-tengi er gert óvirkt sjálfkrafa. Ýttu til að fá frekari upplýsingar."</string>
-    <!-- no translation found for usb_contaminant_not_detected_title (7708281124088684821) -->
-    <skip />
+    <string name="usb_contaminant_not_detected_title" msgid="7708281124088684821">"Óhætt að nota USB-tengi"</string>
     <string name="usb_contaminant_not_detected_message" msgid="2415791798244545292">"Síminn greinir ekki lengur vökva eða óhreinindi"</string>
     <string name="taking_remote_bugreport_notification_title" msgid="6742483073875060934">"Tekur við villutilkynningu…"</string>
     <string name="share_remote_bugreport_notification_title" msgid="4987095013583691873">"Deila villutilkynningu?"</string>
@@ -1613,8 +1613,6 @@
     <string name="display_manager_overlay_display_name" msgid="5142365982271620716">"Yfirlögn #<xliff:g id="ID">%1$d</xliff:g>"</string>
     <string name="display_manager_overlay_display_title" msgid="652124517672257172">"<xliff:g id="NAME">%1$s</xliff:g>: <xliff:g id="WIDTH">%2$d</xliff:g>x<xliff:g id="HEIGHT">%3$d</xliff:g>, <xliff:g id="DPI">%4$d</xliff:g> dpi"</string>
     <string name="display_manager_overlay_display_secure_suffix" msgid="6022119702628572080">", öruggur"</string>
-    <string name="activity_starter_block_bg_activity_starts_permissive" msgid="6995473033438879646">"Framvegis verður lokað á þessa bakgrunnsvirkni frá <xliff:g id="PACKAGENAME">%1$s</xliff:g> í Q-smíði. Sjá g.co/dev/bgblock."</string>
-    <string name="activity_starter_block_bg_activity_starts_enforcing" msgid="3317816771072146229">"Lokað á bakgrunnsvirkni frá <xliff:g id="PACKAGENAME">%1$s</xliff:g>. Sjá g.co/dev/bgblock."</string>
     <string name="kg_forgot_pattern_button_text" msgid="8852021467868220608">"Man ekki mynstrið"</string>
     <string name="kg_wrong_pattern" msgid="1850806070801358830">"Rangt mynstur"</string>
     <string name="kg_wrong_password" msgid="2333281762128113157">"Rangt aðgangsorð"</string>
@@ -1668,8 +1666,12 @@
     <string name="accessibility_shortcut_enabling_service" msgid="7771852911861522636">"Flýtileið aðgengisstillingar kveikti á <xliff:g id="SERVICE_NAME">%1$s</xliff:g>"</string>
     <string name="accessibility_shortcut_disabling_service" msgid="2747243438223109821">"Flýtileið aðgengisstillingar slökkti á <xliff:g id="SERVICE_NAME">%1$s</xliff:g>"</string>
     <string name="accessibility_shortcut_spoken_feedback" msgid="8376923232350078434">"Haltu báðum hljóðstyrkstökkunum inni í þrjár sekúndur til að nota <xliff:g id="SERVICE_NAME">%1$s</xliff:g>"</string>
-    <string name="accessibility_button_prompt_text" msgid="4234556536456854251">"Veldu eiginleika sem á að nota þegar ýtt er á aðgengishnappinn:"</string>
-    <string name="accessibility_button_instructional_text" msgid="6942300463612999993">"Haltu fingri á aðgengishnappinum til að breyta eiginleikum."</string>
+    <string name="accessibility_button_prompt_text" msgid="1176658502969738564">"Veldu þjónustu sem á að nota þegar ýtt er á aðgengishnappinn:"</string>
+    <string name="accessibility_gesture_prompt_text" msgid="8259145549733019401">"Veldu þjónustu sem á að nota með aðgengisbendingunni (strjúka upp frá neðri hluta skjásins með tveimur fingrum):"</string>
+    <string name="accessibility_gesture_3finger_prompt_text" msgid="1041435574275047665">"Veldu þjónustu sem á að nota með aðgengisbendingunni (strjúka upp frá neðri hluta skjásins með þremur fingrum):"</string>
+    <string name="accessibility_button_instructional_text" msgid="7003212763213614833">"Til að skipta á milli þjónusta skaltu halda aðgengishnappinum inni."</string>
+    <string name="accessibility_gesture_instructional_text" msgid="5261788874937410950">"Til að skipta á milli þjónusta skaltu strjúka upp með tveimur fingrum og halda inni."</string>
+    <string name="accessibility_gesture_3finger_instructional_text" msgid="4969448938984394550">"Til að skipta á milli þjónusta skaltu strjúka upp með þremur fingrum og halda inni."</string>
     <string name="accessibility_magnification_chooser_text" msgid="1227146738764986237">"Stækkun"</string>
     <string name="user_switched" msgid="3768006783166984410">"Núverandi notandi <xliff:g id="NAME">%1$s</xliff:g>."</string>
     <string name="user_switching_message" msgid="2871009331809089783">"Skiptir yfir á <xliff:g id="NAME">%1$s</xliff:g>…"</string>
diff --git a/core/res/res/values-it/strings.xml b/core/res/res/values-it/strings.xml
index f0b17c39..ec18963 100644
--- a/core/res/res/values-it/strings.xml
+++ b/core/res/res/values-it/strings.xml
@@ -131,6 +131,7 @@
     <!-- no translation found for wfcSpnFormat_spn (4998685024207291232) -->
     <skip />
     <string name="wfcSpnFormat_spn_wifi_calling" msgid="136001023263502280">"Chiamate Wi-Fi <xliff:g id="SPN">%s</xliff:g>"</string>
+    <string name="wfcSpnFormat_spn_wifi_calling_vo_hyphen" msgid="1730997175789582756">"Chiamate Wi-Fi <xliff:g id="SPN">%s</xliff:g>"</string>
     <string name="wfcSpnFormat_wlan_call" msgid="2533371081782489793">"Chiamata WLAN"</string>
     <string name="wfcSpnFormat_spn_wlan_call" msgid="2315240198303197168">"Chiamata WLAN <xliff:g id="SPN">%s</xliff:g>"</string>
     <string name="wfcSpnFormat_spn_wifi" msgid="6546481665561961938">"Wi-Fi <xliff:g id="SPN">%s</xliff:g>"</string>
@@ -1492,8 +1493,8 @@
     <string name="websearch" msgid="4337157977400211589">"Ricerca Web"</string>
     <string name="find_next" msgid="5742124618942193978">"Trova successivo"</string>
     <string name="find_previous" msgid="2196723669388360506">"Trova precedente"</string>
-    <string name="gpsNotifTicker" msgid="5622683912616496172">"Richiesta posizione da <xliff:g id="NAME">%s</xliff:g>"</string>
-    <string name="gpsNotifTitle" msgid="5446858717157416839">"Richiesta posizione"</string>
+    <string name="gpsNotifTicker" msgid="5622683912616496172">"Richiesta di posizione da <xliff:g id="NAME">%s</xliff:g>"</string>
+    <string name="gpsNotifTitle" msgid="5446858717157416839">"Richiesta di posizione"</string>
     <string name="gpsNotifMessage" msgid="1374718023224000702">"Richiesto da <xliff:g id="NAME">%1$s</xliff:g> (<xliff:g id="SERVICE">%2$s</xliff:g>)"</string>
     <string name="gpsVerifYes" msgid="2346566072867213563">"Sì"</string>
     <string name="gpsVerifNo" msgid="1146564937346454865">"No"</string>
@@ -1611,8 +1612,6 @@
     <string name="display_manager_overlay_display_name" msgid="5142365982271620716">"Overlay n. <xliff:g id="ID">%1$d</xliff:g>"</string>
     <string name="display_manager_overlay_display_title" msgid="652124517672257172">"<xliff:g id="NAME">%1$s</xliff:g>: <xliff:g id="WIDTH">%2$d</xliff:g> x <xliff:g id="HEIGHT">%3$d</xliff:g>, <xliff:g id="DPI">%4$d</xliff:g> dpi"</string>
     <string name="display_manager_overlay_display_secure_suffix" msgid="6022119702628572080">", opzione sicura"</string>
-    <string name="activity_starter_block_bg_activity_starts_permissive" msgid="6995473033438879646">"L\'avvio di questa attività in background da <xliff:g id="PACKAGENAME">%1$s</xliff:g> verrà bloccato nelle future build Q. Visita la pagina g.co/dev/bgblock."</string>
-    <string name="activity_starter_block_bg_activity_starts_enforcing" msgid="3317816771072146229">"Avvio delle attività in background da <xliff:g id="PACKAGENAME">%1$s</xliff:g> bloccato. Visita la pagina g.co/dev/bgblock."</string>
     <string name="kg_forgot_pattern_button_text" msgid="8852021467868220608">"Sequenza dimenticata"</string>
     <string name="kg_wrong_pattern" msgid="1850806070801358830">"Sequenza sbagliata"</string>
     <string name="kg_wrong_password" msgid="2333281762128113157">"Password sbagliata"</string>
@@ -1666,8 +1665,12 @@
     <string name="accessibility_shortcut_enabling_service" msgid="7771852911861522636">"La scorciatoia Accessibilità ha attivato <xliff:g id="SERVICE_NAME">%1$s</xliff:g>"</string>
     <string name="accessibility_shortcut_disabling_service" msgid="2747243438223109821">"La scorciatoia Accessibilità ha disattivato <xliff:g id="SERVICE_NAME">%1$s</xliff:g>"</string>
     <string name="accessibility_shortcut_spoken_feedback" msgid="8376923232350078434">"Tieni premuti entrambi i tasti del volume per tre secondi per utilizzare <xliff:g id="SERVICE_NAME">%1$s</xliff:g>"</string>
-    <string name="accessibility_button_prompt_text" msgid="4234556536456854251">"Scegli una funzione da usare quando tocchi il pulsante Accessibilità:"</string>
-    <string name="accessibility_button_instructional_text" msgid="6942300463612999993">"Per cambiare le funzioni, tocca e tieni premuto il pulsante Accessibilità."</string>
+    <string name="accessibility_button_prompt_text" msgid="1176658502969738564">"Scegli un servizio da usare quando tocchi il pulsante Accessibilità:"</string>
+    <string name="accessibility_gesture_prompt_text" msgid="8259145549733019401">"Scegli un servizio da usare con il gesto di accessibilità (scorrimento verso l\'alto dalla parte inferiore dello schermo con due dita):"</string>
+    <string name="accessibility_gesture_3finger_prompt_text" msgid="1041435574275047665">"Scegli un servizio da usare con il gesto di accessibilità (scorrimento verso l\'alto dalla parte inferiore dello schermo con tre dita):"</string>
+    <string name="accessibility_button_instructional_text" msgid="7003212763213614833">"Per spostarti tra i servizi, tocca e tieni premuto il pulsante Accessibilità."</string>
+    <string name="accessibility_gesture_instructional_text" msgid="5261788874937410950">"Per spostarti tra i servizi, scorri verso l\'alto con due dita e tieni premuto."</string>
+    <string name="accessibility_gesture_3finger_instructional_text" msgid="4969448938984394550">"Per spostarti tra i servizi, scorri verso l\'alto con tre dita e tieni premuto."</string>
     <string name="accessibility_magnification_chooser_text" msgid="1227146738764986237">"Ingrandimento"</string>
     <string name="user_switched" msgid="3768006783166984410">"Utente corrente <xliff:g id="NAME">%1$s</xliff:g>."</string>
     <string name="user_switching_message" msgid="2871009331809089783">"Passaggio a <xliff:g id="NAME">%1$s</xliff:g>…"</string>
diff --git a/core/res/res/values-iw/strings.xml b/core/res/res/values-iw/strings.xml
index 20c6aa3..6fc77fef 100644
--- a/core/res/res/values-iw/strings.xml
+++ b/core/res/res/values-iw/strings.xml
@@ -133,6 +133,7 @@
     <!-- no translation found for wfcSpnFormat_spn (4998685024207291232) -->
     <skip />
     <string name="wfcSpnFormat_spn_wifi_calling" msgid="136001023263502280">"‏שיחות Wi-Fi <xliff:g id="SPN">%s</xliff:g>"</string>
+    <string name="wfcSpnFormat_spn_wifi_calling_vo_hyphen" msgid="1730997175789582756">"‏שיחות Wi-Fi באמצעות <xliff:g id="SPN">%s</xliff:g>"</string>
     <string name="wfcSpnFormat_wlan_call" msgid="2533371081782489793">"שיחה ברשת אלחוטית"</string>
     <string name="wfcSpnFormat_spn_wlan_call" msgid="2315240198303197168">"‏שיחת WLAN <xliff:g id="SPN">%s</xliff:g>"</string>
     <string name="wfcSpnFormat_spn_wifi" msgid="6546481665561961938">"Wi-Fi <xliff:g id="SPN">%s</xliff:g>"</string>
@@ -1401,8 +1402,7 @@
     <string name="test_harness_mode_notification_message" msgid="1343197173054407119">"כדי להשבית את מצב מסגרת בדיקה צריך לאפס להגדרות היצרן."</string>
     <string name="usb_contaminant_detected_title" msgid="7136400633704058349">"‏יש נוזלים או חלקיקים ביציאת ה-USB"</string>
     <string name="usb_contaminant_detected_message" msgid="832337061059487250">"‏יציאת ה-USB הושבתה באופן אוטומטי. יש להקיש לקבלת מידע נוסף."</string>
-    <!-- no translation found for usb_contaminant_not_detected_title (7708281124088684821) -->
-    <skip />
+    <string name="usb_contaminant_not_detected_title" msgid="7708281124088684821">"‏ניתן להשתמש ביציאת ה-USB"</string>
     <string name="usb_contaminant_not_detected_message" msgid="2415791798244545292">"הטלפון לא מזהה יותר נוזלים וחלקיקים."</string>
     <string name="taking_remote_bugreport_notification_title" msgid="6742483073875060934">"עיבוד דוח על באג..."</string>
     <string name="share_remote_bugreport_notification_title" msgid="4987095013583691873">"האם לשתף דוח על באג?"</string>
@@ -1658,8 +1658,6 @@
     <string name="display_manager_overlay_display_name" msgid="5142365982271620716">"שכבת-על #<xliff:g id="ID">%1$d</xliff:g>"</string>
     <string name="display_manager_overlay_display_title" msgid="652124517672257172">"‏<xliff:g id="NAME">%1$s</xliff:g>: ‎<xliff:g id="WIDTH">%2$d</xliff:g>x<xliff:g id="HEIGHT">%3$d</xliff:g>‎, ‏<xliff:g id="DPI">%4$d</xliff:g> dpi"</string>
     <string name="display_manager_overlay_display_secure_suffix" msgid="6022119702628572080">", מאובטח"</string>
-    <string name="activity_starter_block_bg_activity_starts_permissive" msgid="6995473033438879646">"‏התחלה זו של פעילות ברקע מ-<xliff:g id="PACKAGENAME">%1$s</xliff:g> תיחסם בגרסאות build עתידיות של Q. ניתן לעיין בכתובת g.co/dev/bgblock."</string>
-    <string name="activity_starter_block_bg_activity_starts_enforcing" msgid="3317816771072146229">"‏נחסמה התחלה של פעילות ברקע מ-<xliff:g id="PACKAGENAME">%1$s</xliff:g>. ניתן לעיין בכתובת g.co/dev/bgblock."</string>
     <string name="kg_forgot_pattern_button_text" msgid="8852021467868220608">"שכחת את קו ביטול הנעילה?"</string>
     <string name="kg_wrong_pattern" msgid="1850806070801358830">"קו ביטול נעילה שגוי"</string>
     <string name="kg_wrong_password" msgid="2333281762128113157">"סיסמה שגויה"</string>
@@ -1715,8 +1713,12 @@
     <string name="accessibility_shortcut_enabling_service" msgid="7771852911861522636">"<xliff:g id="SERVICE_NAME">%1$s</xliff:g> הופעל על-ידי קיצור הדרך לנגישות"</string>
     <string name="accessibility_shortcut_disabling_service" msgid="2747243438223109821">"<xliff:g id="SERVICE_NAME">%1$s</xliff:g> הושבת על-ידי קיצור הדרך לנגישות"</string>
     <string name="accessibility_shortcut_spoken_feedback" msgid="8376923232350078434">"יש ללחוץ לחיצה ארוכה על שני לחצני עוצמת הקול למשך שלוש שניות כדי להשתמש בשירות <xliff:g id="SERVICE_NAME">%1$s</xliff:g>"</string>
-    <string name="accessibility_button_prompt_text" msgid="4234556536456854251">"בחר תכונה שתופעל כשתלחץ על הלחצן \'נגישות\':"</string>
-    <string name="accessibility_button_instructional_text" msgid="6942300463612999993">"כדי להחליף תכונה, יש ללחוץ לחיצה ארוכה על הלחצן \'נגישות\'."</string>
+    <string name="accessibility_button_prompt_text" msgid="1176658502969738564">"יש לבחור שירות שיופעל באמצעות הקשה על לחצן הנגישות:"</string>
+    <string name="accessibility_gesture_prompt_text" msgid="8259145549733019401">"יש לבחור שירות שיופעל באמצעות תנועת הנגישות (החלקה למעלה מתחתית המסך בעזרת שתי אצבעות):"</string>
+    <string name="accessibility_gesture_3finger_prompt_text" msgid="1041435574275047665">"יש לבחור שירות שיופעל באמצעות תנועת הנגישות (החלקה למעלה מתחתית המסך בעזרת שלוש אצבעות):"</string>
+    <string name="accessibility_button_instructional_text" msgid="7003212763213614833">"כדי לעבור בין שירותים, יש ללחוץ לחיצה ארוכה על לחצן הנגישות."</string>
+    <string name="accessibility_gesture_instructional_text" msgid="5261788874937410950">"כדי לעבור בין שירותים, יש להחליק כלפי מעלה בעזרת שתי אצבעות ולהחזיק."</string>
+    <string name="accessibility_gesture_3finger_instructional_text" msgid="4969448938984394550">"כדי לעבור בין שירותים, יש להחליק כלפי מעלה בעזרת שלוש אצבעות ולהחזיק."</string>
     <string name="accessibility_magnification_chooser_text" msgid="1227146738764986237">"הגדלה"</string>
     <string name="user_switched" msgid="3768006783166984410">"המשתמש הנוכחי <xliff:g id="NAME">%1$s</xliff:g>."</string>
     <string name="user_switching_message" msgid="2871009331809089783">"עובר אל <xliff:g id="NAME">%1$s</xliff:g>…"</string>
diff --git a/core/res/res/values-ja/strings.xml b/core/res/res/values-ja/strings.xml
index 2fbdebc..73a02cb 100644
--- a/core/res/res/values-ja/strings.xml
+++ b/core/res/res/values-ja/strings.xml
@@ -131,6 +131,7 @@
     <!-- no translation found for wfcSpnFormat_spn (4998685024207291232) -->
     <skip />
     <string name="wfcSpnFormat_spn_wifi_calling" msgid="136001023263502280">"<xliff:g id="SPN">%s</xliff:g> Wi-Fi 通話"</string>
+    <string name="wfcSpnFormat_spn_wifi_calling_vo_hyphen" msgid="1730997175789582756">"<xliff:g id="SPN">%s</xliff:g> Wi-Fi 通話"</string>
     <string name="wfcSpnFormat_wlan_call" msgid="2533371081782489793">"WLAN 通話"</string>
     <string name="wfcSpnFormat_spn_wlan_call" msgid="2315240198303197168">"<xliff:g id="SPN">%s</xliff:g> WLAN 通話"</string>
     <string name="wfcSpnFormat_spn_wifi" msgid="6546481665561961938">"<xliff:g id="SPN">%s</xliff:g> Wi-Fi"</string>
@@ -1357,8 +1358,7 @@
     <string name="test_harness_mode_notification_message" msgid="1343197173054407119">"出荷時設定にリセットしてテストハーネス モードを無効にしてください。"</string>
     <string name="usb_contaminant_detected_title" msgid="7136400633704058349">"USB ポート内の液体やゴミ"</string>
     <string name="usb_contaminant_detected_message" msgid="832337061059487250">"USB ポートが自動的に無効になりました。タップして詳細をご確認ください。"</string>
-    <!-- no translation found for usb_contaminant_not_detected_title (7708281124088684821) -->
-    <skip />
+    <string name="usb_contaminant_not_detected_title" msgid="7708281124088684821">"USB ポートを安全に使用できます"</string>
     <string name="usb_contaminant_not_detected_message" msgid="2415791798244545292">"液体やゴミは検出されなくなりました。"</string>
     <string name="taking_remote_bugreport_notification_title" msgid="6742483073875060934">"バグレポートを取得しています…"</string>
     <string name="share_remote_bugreport_notification_title" msgid="4987095013583691873">"バグレポートを共有しますか?"</string>
@@ -1494,7 +1494,7 @@
     <string name="find_next" msgid="5742124618942193978">"次を検索"</string>
     <string name="find_previous" msgid="2196723669388360506">"前を検索"</string>
     <string name="gpsNotifTicker" msgid="5622683912616496172">"<xliff:g id="NAME">%s</xliff:g>さんからの現在地情報リクエスト"</string>
-    <string name="gpsNotifTitle" msgid="5446858717157416839">"現在地情報へのアクセス許可"</string>
+    <string name="gpsNotifTitle" msgid="5446858717157416839">"現在地情報リクエスト"</string>
     <string name="gpsNotifMessage" msgid="1374718023224000702">"<xliff:g id="NAME">%1$s</xliff:g>さん(<xliff:g id="SERVICE">%2$s</xliff:g>)からのリクエスト"</string>
     <string name="gpsVerifYes" msgid="2346566072867213563">"はい"</string>
     <string name="gpsVerifNo" msgid="1146564937346454865">"いいえ"</string>
@@ -1612,8 +1612,6 @@
     <string name="display_manager_overlay_display_name" msgid="5142365982271620716">"オーバーレイ第<xliff:g id="ID">%1$d</xliff:g>"</string>
     <string name="display_manager_overlay_display_title" msgid="652124517672257172">"<xliff:g id="NAME">%1$s</xliff:g>: <xliff:g id="WIDTH">%2$d</xliff:g>x<xliff:g id="HEIGHT">%3$d</xliff:g>、<xliff:g id="DPI">%4$d</xliff:g> dpi"</string>
     <string name="display_manager_overlay_display_secure_suffix" msgid="6022119702628572080">"、セキュア"</string>
-    <string name="activity_starter_block_bg_activity_starts_permissive" msgid="6995473033438879646">"<xliff:g id="PACKAGENAME">%1$s</xliff:g> からのこのバックグラウンド アクティビティの開始は今後の Q ビルドではブロックされます。g.co/dev/bgblock をご覧ください。"</string>
-    <string name="activity_starter_block_bg_activity_starts_enforcing" msgid="3317816771072146229">"<xliff:g id="PACKAGENAME">%1$s</xliff:g> からのバックグラウンド アクティビティの開始がブロックされました。g.co/dev/bgblock をご覧ください。"</string>
     <string name="kg_forgot_pattern_button_text" msgid="8852021467868220608">"パターンを忘れた場合"</string>
     <string name="kg_wrong_pattern" msgid="1850806070801358830">"パターンが正しくありません"</string>
     <string name="kg_wrong_password" msgid="2333281762128113157">"パスワードが正しくありません"</string>
@@ -1667,8 +1665,12 @@
     <string name="accessibility_shortcut_enabling_service" msgid="7771852911861522636">"ユーザー補助機能のショートカットにより <xliff:g id="SERVICE_NAME">%1$s</xliff:g> は ON になっています"</string>
     <string name="accessibility_shortcut_disabling_service" msgid="2747243438223109821">"ユーザー補助機能のショートカットにより <xliff:g id="SERVICE_NAME">%1$s</xliff:g> は OFF になっています"</string>
     <string name="accessibility_shortcut_spoken_feedback" msgid="8376923232350078434">"<xliff:g id="SERVICE_NAME">%1$s</xliff:g> を使用するには、音量大と音量小の両方のボタンを 3 秒間長押ししてください"</string>
-    <string name="accessibility_button_prompt_text" msgid="4234556536456854251">"ユーザー補助機能ボタンをタップした場合に使用する機能を選択してください。"</string>
-    <string name="accessibility_button_instructional_text" msgid="6942300463612999993">"機能を変更するには、ユーザー補助機能ボタンを長押ししてください。"</string>
+    <string name="accessibility_button_prompt_text" msgid="1176658502969738564">"ユーザー補助機能ボタンをタップした場合に使用するサービスを選択してください。"</string>
+    <string name="accessibility_gesture_prompt_text" msgid="8259145549733019401">"ユーザー補助操作(2 本の指で画面の下から上にスワイプ)で使用するサービスを選択してください。"</string>
+    <string name="accessibility_gesture_3finger_prompt_text" msgid="1041435574275047665">"ユーザー補助操作(3 本の指で画面の下から上にスワイプ)で使用するサービスを選択してください。"</string>
+    <string name="accessibility_button_instructional_text" msgid="7003212763213614833">"サービスを切り替えるには、ユーザー補助機能ボタンを長押しします。"</string>
+    <string name="accessibility_gesture_instructional_text" msgid="5261788874937410950">"サービスを切り替えるには、2 本の指で上にスワイプしたまま長押しします。"</string>
+    <string name="accessibility_gesture_3finger_instructional_text" msgid="4969448938984394550">"サービスを切り替えるには、3 本の指で上にスワイプしたまま長押しします。"</string>
     <string name="accessibility_magnification_chooser_text" msgid="1227146738764986237">"拡大"</string>
     <string name="user_switched" msgid="3768006783166984410">"現在のユーザーは<xliff:g id="NAME">%1$s</xliff:g>です。"</string>
     <string name="user_switching_message" msgid="2871009331809089783">"<xliff:g id="NAME">%1$s</xliff:g>に切り替えています…"</string>
diff --git a/core/res/res/values-ka/strings.xml b/core/res/res/values-ka/strings.xml
index 299c3e1..31d5887 100644
--- a/core/res/res/values-ka/strings.xml
+++ b/core/res/res/values-ka/strings.xml
@@ -131,6 +131,7 @@
     <!-- no translation found for wfcSpnFormat_spn (4998685024207291232) -->
     <skip />
     <string name="wfcSpnFormat_spn_wifi_calling" msgid="136001023263502280">"<xliff:g id="SPN">%s</xliff:g> Wi-Fi დარეკვა"</string>
+    <string name="wfcSpnFormat_spn_wifi_calling_vo_hyphen" msgid="1730997175789582756">"<xliff:g id="SPN">%s</xliff:g> Wi-Fi დარეკვა"</string>
     <string name="wfcSpnFormat_wlan_call" msgid="2533371081782489793">"WLAN ზარი"</string>
     <string name="wfcSpnFormat_spn_wlan_call" msgid="2315240198303197168">"<xliff:g id="SPN">%s</xliff:g> WLAN ზარი"</string>
     <string name="wfcSpnFormat_spn_wifi" msgid="6546481665561961938">"<xliff:g id="SPN">%s</xliff:g> Wi-Fi"</string>
@@ -1357,8 +1358,7 @@
     <string name="test_harness_mode_notification_message" msgid="1343197173054407119">"დააბრუნეთ ქარხნული პარამეტრები „გარემო ტესტირებისთვის“ რეჟიმის გასათიშად."</string>
     <string name="usb_contaminant_detected_title" msgid="7136400633704058349">"USB პორტში აღმოჩენილია სითხე ან ჭუჭყი"</string>
     <string name="usb_contaminant_detected_message" msgid="832337061059487250">"USB პორტი ავტომატურად გათიშულია. შეეხეთ დამატებითი ინფორმაციისთვის."</string>
-    <!-- no translation found for usb_contaminant_not_detected_title (7708281124088684821) -->
-    <skip />
+    <string name="usb_contaminant_not_detected_title" msgid="7708281124088684821">"თანხმობა USB პორტის გამოყენებაზე"</string>
     <string name="usb_contaminant_not_detected_message" msgid="2415791798244545292">"ტელეფონი აღარ აღმოაჩენს სითხეს ან ჭუჭყს."</string>
     <string name="taking_remote_bugreport_notification_title" msgid="6742483073875060934">"მიმდინარეობს ხარვეზის შესახებ ანგარიშის შექმნა…"</string>
     <string name="share_remote_bugreport_notification_title" msgid="4987095013583691873">"გსურთ ხარვეზის შესახებ ანგარიშის გაზიარება?"</string>
@@ -1612,8 +1612,6 @@
     <string name="display_manager_overlay_display_name" msgid="5142365982271620716">"გადაფარვა #<xliff:g id="ID">%1$d</xliff:g>"</string>
     <string name="display_manager_overlay_display_title" msgid="652124517672257172">"<xliff:g id="NAME">%1$s</xliff:g>: <xliff:g id="WIDTH">%2$d</xliff:g>x<xliff:g id="HEIGHT">%3$d</xliff:g>, <xliff:g id="DPI">%4$d</xliff:g> dpi"</string>
     <string name="display_manager_overlay_display_secure_suffix" msgid="6022119702628572080">", დაცული"</string>
-    <string name="activity_starter_block_bg_activity_starts_permissive" msgid="6995473033438879646">"<xliff:g id="PACKAGENAME">%1$s</xliff:g>-დან ამ ფონური აქტივობის გაშვება დაიბლოკება Q-ის მომდევნო ანაწყობებში. იხილეთ g.co/dev/bgblock."</string>
-    <string name="activity_starter_block_bg_activity_starts_enforcing" msgid="3317816771072146229">"<xliff:g id="PACKAGENAME">%1$s</xliff:g>-დან ფონური აქტივობის გაშვება დაიბლოკა. იხილეთ g.co/dev/bgblock."</string>
     <string name="kg_forgot_pattern_button_text" msgid="8852021467868220608">"დაგავიწყდათ ნიმუში"</string>
     <string name="kg_wrong_pattern" msgid="1850806070801358830">"არასწორი ნიმუში"</string>
     <string name="kg_wrong_password" msgid="2333281762128113157">"არასწორი პაროლი"</string>
@@ -1667,8 +1665,12 @@
     <string name="accessibility_shortcut_enabling_service" msgid="7771852911861522636">"მარტივი წვდომის მალსახმობმა ჩართო <xliff:g id="SERVICE_NAME">%1$s</xliff:g>"</string>
     <string name="accessibility_shortcut_disabling_service" msgid="2747243438223109821">"მარტივი წვდომის მალსახმობმა გამორთო <xliff:g id="SERVICE_NAME">%1$s</xliff:g>"</string>
     <string name="accessibility_shortcut_spoken_feedback" msgid="8376923232350078434">"<xliff:g id="SERVICE_NAME">%1$s</xliff:g> რომ გამოიყენოთ, დააჭირეთ ხმის ორივე ღილაკზე 3 წამის განმავლობაში"</string>
-    <string name="accessibility_button_prompt_text" msgid="4234556536456854251">"აირჩიეთ მარტივი წვდომის ღილაკზე შეხებისას გამოსაყენებელი ფუნქცია:"</string>
-    <string name="accessibility_button_instructional_text" msgid="6942300463612999993">"ფუნქციების შესაცვლელად ხანგრძლივად შეეხეთ მარტივი წვდომის ღილაკს."</string>
+    <string name="accessibility_button_prompt_text" msgid="1176658502969738564">"აირჩიეთ მარტივი წვდომის ღილაკზე შეხებისას გამოსაყენებელი სერვისი:"</string>
+    <string name="accessibility_gesture_prompt_text" msgid="8259145549733019401">"აირჩიეთ მარტივი წვდომის ჟესტთან (ორი თითით გადაფურცვლა ეკრანის ქვედა კიდიდან ზემოთ) გამოსაყენებელი სერვისი:"</string>
+    <string name="accessibility_gesture_3finger_prompt_text" msgid="1041435574275047665">"აირჩიეთ მარტივი წვდომის ჟესტთან (სამი თითით გადაფურცვლა ეკრანის ქვედა კიდიდან ზემოთ) გამოსაყენებელი სერვისი:"</string>
+    <string name="accessibility_button_instructional_text" msgid="7003212763213614833">"სერვისების გადასართავად, ხანგრძლივად შეეხეთ მარტივი წვდომის ღილაკს."</string>
+    <string name="accessibility_gesture_instructional_text" msgid="5261788874937410950">"სერვისების გადასართავად, ორი თითით გადაფურცლეთ ზემოთ და დააყოვნეთ."</string>
+    <string name="accessibility_gesture_3finger_instructional_text" msgid="4969448938984394550">"სერვისების გადასართავად, სამი თითით გადაფურცლეთ ზემოთ და დააყოვნეთ."</string>
     <string name="accessibility_magnification_chooser_text" msgid="1227146738764986237">"გადიდება"</string>
     <string name="user_switched" msgid="3768006783166984410">"ამჟამინდელი მომხმარებელი <xliff:g id="NAME">%1$s</xliff:g>."</string>
     <string name="user_switching_message" msgid="2871009331809089783">"<xliff:g id="NAME">%1$s</xliff:g>-ზე გადართვა…"</string>
diff --git a/core/res/res/values-kk/strings.xml b/core/res/res/values-kk/strings.xml
index 9cd94fc..2bdb05f 100644
--- a/core/res/res/values-kk/strings.xml
+++ b/core/res/res/values-kk/strings.xml
@@ -131,6 +131,7 @@
     <!-- no translation found for wfcSpnFormat_spn (4998685024207291232) -->
     <skip />
     <string name="wfcSpnFormat_spn_wifi_calling" msgid="136001023263502280">"<xliff:g id="SPN">%s</xliff:g> Wi-Fi қоңыраулары"</string>
+    <string name="wfcSpnFormat_spn_wifi_calling_vo_hyphen" msgid="1730997175789582756">"<xliff:g id="SPN">%s</xliff:g> Wi-Fi қоңырауы"</string>
     <string name="wfcSpnFormat_wlan_call" msgid="2533371081782489793">"WLAN қоңырауы"</string>
     <string name="wfcSpnFormat_spn_wlan_call" msgid="2315240198303197168">"<xliff:g id="SPN">%s</xliff:g> WLAN қоңырауы"</string>
     <string name="wfcSpnFormat_spn_wifi" msgid="6546481665561961938">"<xliff:g id="SPN">%s</xliff:g> Wi-Fi"</string>
@@ -1358,8 +1359,7 @@
     <string name="test_harness_mode_notification_message" msgid="1343197173054407119">"Сынақ бағдарламасы режимін өшіру үшін зауыттық күйіне қайтарыңыз."</string>
     <string name="usb_contaminant_detected_title" msgid="7136400633704058349">"USB портына сұйықтық немесе қоқыс кірді"</string>
     <string name="usb_contaminant_detected_message" msgid="832337061059487250">"USB порты автоматты түрде өшірілді. Толығырақ ақпарат алу үшін түртіңіз."</string>
-    <!-- no translation found for usb_contaminant_not_detected_title (7708281124088684821) -->
-    <skip />
+    <string name="usb_contaminant_not_detected_title" msgid="7708281124088684821">"USB портын пайдалана беруге болады"</string>
     <string name="usb_contaminant_not_detected_message" msgid="2415791798244545292">"Телефон бұдан былай сұйықтықты немесе қоқысты анықтамайды."</string>
     <string name="taking_remote_bugreport_notification_title" msgid="6742483073875060934">"Қате туралы есеп алынуда…"</string>
     <string name="share_remote_bugreport_notification_title" msgid="4987095013583691873">"Қате туралы есепті бөлісу керек пе?"</string>
@@ -1495,7 +1495,7 @@
     <string name="find_next" msgid="5742124618942193978">"Келесіні табу"</string>
     <string name="find_previous" msgid="2196723669388360506">"Алдыңғыны табу"</string>
     <string name="gpsNotifTicker" msgid="5622683912616496172">"Орын туралы өтініші жіберген <xliff:g id="NAME">%s</xliff:g>"</string>
-    <string name="gpsNotifTitle" msgid="5446858717157416839">"Орын туралы өтініш"</string>
+    <string name="gpsNotifTitle" msgid="5446858717157416839">"Орын туралы сұрау"</string>
     <string name="gpsNotifMessage" msgid="1374718023224000702">"Өтініш жіберген <xliff:g id="NAME">%1$s</xliff:g> (<xliff:g id="SERVICE">%2$s</xliff:g>)"</string>
     <string name="gpsVerifYes" msgid="2346566072867213563">"Иә"</string>
     <string name="gpsVerifNo" msgid="1146564937346454865">"Жоқ"</string>
@@ -1613,8 +1613,6 @@
     <string name="display_manager_overlay_display_name" msgid="5142365982271620716">"№<xliff:g id="ID">%1$d</xliff:g> қабаттама"</string>
     <string name="display_manager_overlay_display_title" msgid="652124517672257172">"<xliff:g id="NAME">%1$s</xliff:g>: <xliff:g id="WIDTH">%2$d</xliff:g>x<xliff:g id="HEIGHT">%3$d</xliff:g>, <xliff:g id="DPI">%4$d</xliff:g> dpi"</string>
     <string name="display_manager_overlay_display_secure_suffix" msgid="6022119702628572080">", қауіпсіз"</string>
-    <string name="activity_starter_block_bg_activity_starts_permissive" msgid="6995473033438879646">"Алдағы Q құрамаларында <xliff:g id="PACKAGENAME">%1$s</xliff:g> сайтындағы фондық әрекеттерге тыйым салынады. g.co/dev/bgblock бетін қараңыз."</string>
-    <string name="activity_starter_block_bg_activity_starts_enforcing" msgid="3317816771072146229">"<xliff:g id="PACKAGENAME">%1$s</xliff:g> сайтындағы фондық әрекеттерге тыйым салынған. g.co/dev/bgblock бетін қараңыз."</string>
     <string name="kg_forgot_pattern_button_text" msgid="8852021467868220608">"Кескінді ұмытып қалу"</string>
     <string name="kg_wrong_pattern" msgid="1850806070801358830">"Қате өрнек"</string>
     <string name="kg_wrong_password" msgid="2333281762128113157">"Қате кілтсөз"</string>
@@ -1668,8 +1666,12 @@
     <string name="accessibility_shortcut_enabling_service" msgid="7771852911861522636">"Арнайы мүмкіндіктер таңбашасы <xliff:g id="SERVICE_NAME">%1$s</xliff:g> қызметін қосты"</string>
     <string name="accessibility_shortcut_disabling_service" msgid="2747243438223109821">"Арнайы мүмкіндіктер таңбашасы <xliff:g id="SERVICE_NAME">%1$s</xliff:g> қызметін өшірді"</string>
     <string name="accessibility_shortcut_spoken_feedback" msgid="8376923232350078434">"<xliff:g id="SERVICE_NAME">%1$s</xliff:g> қызметін пайдалану үшін дыбыс деңгейін реттейтін екі түймені де 3 секунд басып тұрыңыз"</string>
-    <string name="accessibility_button_prompt_text" msgid="4234556536456854251">"\"Арнайы мүмкіндіктер\" түймесін түрткенде пайдаланатын мүмкіндікті таңдаңыз:"</string>
-    <string name="accessibility_button_instructional_text" msgid="6942300463612999993">"Мүмкіндіктерді өзгерту үшін \"Арнайы мүмкіндіктер\" түймесін басып тұрыңыз."</string>
+    <string name="accessibility_button_prompt_text" msgid="1176658502969738564">"\"Арнайы мүмкіндіктер\" түймесін түрткенде пайдаланатын қызметті таңдаңыз:"</string>
+    <string name="accessibility_gesture_prompt_text" msgid="8259145549733019401">"Арнайы мүмкіндіктер қимылымен пайдаланатын қызметті таңдаңыз (екі саусақпен экранның төменгі жағынан жоғары қарай сырғытыңыз):"</string>
+    <string name="accessibility_gesture_3finger_prompt_text" msgid="1041435574275047665">"Арнайы мүмкіндіктер қимылымен пайдаланатын қызметті таңдаңыз (үш саусақпен экранның төменгі жағынан жоғары қарай сырғытыңыз):"</string>
+    <string name="accessibility_button_instructional_text" msgid="7003212763213614833">"Бір қызметтен екінші қызметке ауысу үшін арнайы мүмкіндіктер түймесін түртіп, оны ұстап тұрыңыз."</string>
+    <string name="accessibility_gesture_instructional_text" msgid="5261788874937410950">"Бір қызметтен екінші қызметке ауысу үшін екі саусақпен жоғары қарай сырғытып, ұстап тұрыңыз."</string>
+    <string name="accessibility_gesture_3finger_instructional_text" msgid="4969448938984394550">"Бір қызметтен екінші қызметке ауысу үшін үш саусақпен жоғары қарай сырғытып, ұстап тұрыңыз."</string>
     <string name="accessibility_magnification_chooser_text" msgid="1227146738764986237">"Ұлғайту"</string>
     <string name="user_switched" msgid="3768006783166984410">"Ағымдағы пайдаланушы <xliff:g id="NAME">%1$s</xliff:g>."</string>
     <string name="user_switching_message" msgid="2871009331809089783">"<xliff:g id="NAME">%1$s</xliff:g> ауысу орындалуда…"</string>
diff --git a/core/res/res/values-km/strings.xml b/core/res/res/values-km/strings.xml
index 9f34532..9c01fdb 100644
--- a/core/res/res/values-km/strings.xml
+++ b/core/res/res/values-km/strings.xml
@@ -131,6 +131,7 @@
     <!-- no translation found for wfcSpnFormat_spn (4998685024207291232) -->
     <skip />
     <string name="wfcSpnFormat_spn_wifi_calling" msgid="136001023263502280">"<xliff:g id="SPN">%s</xliff:g> ការហៅតាម Wi-Fi"</string>
+    <string name="wfcSpnFormat_spn_wifi_calling_vo_hyphen" msgid="1730997175789582756">"<xliff:g id="SPN">%s</xliff:g> ការហៅ​តាម Wi-Fi"</string>
     <string name="wfcSpnFormat_wlan_call" msgid="2533371081782489793">"ការហៅ​តាម WLAN"</string>
     <string name="wfcSpnFormat_spn_wlan_call" msgid="2315240198303197168">"<xliff:g id="SPN">%s</xliff:g> ការហៅតាម WLAN"</string>
     <string name="wfcSpnFormat_spn_wifi" msgid="6546481665561961938">"<xliff:g id="SPN">%s</xliff:g> Wi-Fi"</string>
@@ -1070,7 +1071,7 @@
     <string name="Midnight" msgid="5630806906897892201">"កណ្ដាល​អធ្រាត្រ​"</string>
     <string name="elapsed_time_short_format_mm_ss" msgid="4431555943828711473">"<xliff:g id="MINUTES">%1$02d</xliff:g>:<xliff:g id="SECONDS">%2$02d</xliff:g>"</string>
     <string name="elapsed_time_short_format_h_mm_ss" msgid="1846071997616654124">"<xliff:g id="HOURS">%1$d</xliff:g>:<xliff:g id="MINUTES">%2$02d</xliff:g>:<xliff:g id="SECONDS">%3$02d</xliff:g>"</string>
-    <string name="selectAll" msgid="6876518925844129331">"ជ្រើស​ទាំងអស់"</string>
+    <string name="selectAll" msgid="6876518925844129331">"ជ្រើសរើស​ទាំងអស់"</string>
     <string name="cut" msgid="3092569408438626261">"កាត់"</string>
     <string name="copy" msgid="2681946229533511987">"ចម្លង"</string>
     <string name="failed_to_copy_to_clipboard" msgid="1833662432489814471">"មិនអាច​ចម្លងទៅ​អង្គចងចាំទេ"</string>
@@ -1359,8 +1360,7 @@
     <string name="test_harness_mode_notification_message" msgid="1343197173054407119">"ធ្វើការកំណត់ដូចដើមឡើងវិញ ដើម្បី​បិទ​មុខងារប្រមូលធ្វើតេស្ត។"</string>
     <string name="usb_contaminant_detected_title" msgid="7136400633704058349">"មានទឹក ឬ​កម្ទេចផ្សេងៗ​នៅក្នុងរន្ធ USB"</string>
     <string name="usb_contaminant_detected_message" msgid="832337061059487250">"រន្ធ USB ត្រូវបាន​បិទ​ដោយ​ស្វ័យប្រវត្តិ។ សូមចុច​ដើម្បី​ស្វែងយល់​បន្ថែម។"</string>
-    <!-- no translation found for usb_contaminant_not_detected_title (7708281124088684821) -->
-    <skip />
+    <string name="usb_contaminant_not_detected_title" msgid="7708281124088684821">"អាច​ប្រើរន្ធ USB បាន"</string>
     <string name="usb_contaminant_not_detected_message" msgid="2415791798244545292">"ទូរសព្ទ​រកមិនឃើញ​ទឹក ឬ​កម្ទេចផ្សេងៗ​ទេ។"</string>
     <string name="taking_remote_bugreport_notification_title" msgid="6742483073875060934">"កំពុងទទួលយករបាយការណ៍កំហុស…"</string>
     <string name="share_remote_bugreport_notification_title" msgid="4987095013583691873">"ចែករំលែករបាយការណ៍កំហុសឬ?"</string>
@@ -1614,8 +1614,6 @@
     <string name="display_manager_overlay_display_name" msgid="5142365982271620716">"#<xliff:g id="ID">%1$d</xliff:g> ត្រួត​គ្នា"</string>
     <string name="display_manager_overlay_display_title" msgid="652124517672257172">"<xliff:g id="NAME">%1$s</xliff:g>: <xliff:g id="WIDTH">%2$d</xliff:g>x<xliff:g id="HEIGHT">%3$d</xliff:g>, <xliff:g id="DPI">%4$d</xliff:g> dpi"</string>
     <string name="display_manager_overlay_display_secure_suffix" msgid="6022119702628572080">", សុវត្ថិភាព"</string>
-    <string name="activity_starter_block_bg_activity_starts_permissive" msgid="6995473033438879646">"មុខងារចាប់ផ្ដើម​សកម្មភាព​នៅផ្ទៃខាងក្រោយ​ពី <xliff:g id="PACKAGENAME">%1$s</xliff:g> នេះ​នឹងត្រូវ​ទប់ស្កាត់​នៅក្នុង​កំណែបង្កើត Q នាពេលអនាគត។ សូមមើល g.co/dev/bgblock ។"</string>
-    <string name="activity_starter_block_bg_activity_starts_enforcing" msgid="3317816771072146229">"បានទប់ស្កាត់​មុខងារចាប់ផ្ដើម​សកម្មភាព​នៅផ្ទៃខាងក្រោយ​ពី <xliff:g id="PACKAGENAME">%1$s</xliff:g> ។ សូមមើល g.co/dev/bgblock ។"</string>
     <string name="kg_forgot_pattern_button_text" msgid="8852021467868220608">"ភ្លេច​​លំនាំ"</string>
     <string name="kg_wrong_pattern" msgid="1850806070801358830">"លំនាំ​មិន​ត្រឹមត្រូវ"</string>
     <string name="kg_wrong_password" msgid="2333281762128113157">"ពាក្យ​សម្ងាត់​មិន​ត្រឹមត្រូវ"</string>
@@ -1669,8 +1667,12 @@
     <string name="accessibility_shortcut_enabling_service" msgid="7771852911861522636">"ផ្លូវកាត់​ភាព​ងាយ​ស្រួល​បាន​បើក <xliff:g id="SERVICE_NAME">%1$s</xliff:g>"</string>
     <string name="accessibility_shortcut_disabling_service" msgid="2747243438223109821">"ផ្លូវកាត់​ភាព​ងាយ​ស្រួល​បាន​បិទ <xliff:g id="SERVICE_NAME">%1$s</xliff:g>"</string>
     <string name="accessibility_shortcut_spoken_feedback" msgid="8376923232350078434">"ចុចគ្រាប់ចុច​កម្រិត​សំឡេងទាំងពីរ​ឱ្យជាប់រយៈពេលបីវិនាទី ដើម្បីប្រើ <xliff:g id="SERVICE_NAME">%1$s</xliff:g>"</string>
-    <string name="accessibility_button_prompt_text" msgid="4234556536456854251">"ជ្រើសរើស​មុខងារ​ដែលត្រូវ​ប្រើ នៅពេល​ដែល​អ្នកចុច​ប៊ូតុង​ភាពងាយស្រួល៖"</string>
-    <string name="accessibility_button_instructional_text" msgid="6942300463612999993">"ដើម្បី​ផ្លាស់ប្តូរ​មុខងារ សូម​ចុច​ប៊ូតុង​ភាព​ងាយស្រួល​ឲ្យ​ជាប់។"</string>
+    <string name="accessibility_button_prompt_text" msgid="1176658502969738564">"ជ្រើសរើស​សេវាកម្ម​ដែលត្រូវ​ប្រើ នៅពេល​ដែល​អ្នក​ចុច​ប៊ូតុង​ភាពងាយស្រួល៖"</string>
+    <string name="accessibility_gesture_prompt_text" msgid="8259145549733019401">"ជ្រើសរើស​សេវាកម្ម​ដែលត្រូវប្រើជាមួយចលនា​ភាពងាយស្រួល (អូស​ឡើងលើ​ពី​ផ្នែកខាងក្រោម​នៃ​អេក្រង់​ដោយប្រើ​ម្រាមដៃ​ពីរ)៖"</string>
+    <string name="accessibility_gesture_3finger_prompt_text" msgid="1041435574275047665">"ជ្រើសរើស​សេវាកម្ម​ដែលត្រូវប្រើជាមួយ​ចលនា​ភាពងាយស្រួល (អូស​ឡើងលើ​ពី​ផ្នែកខាងក្រោម​នៃ​អេក្រង់​ដោយប្រើ​ម្រាមដៃ​បី)៖"</string>
+    <string name="accessibility_button_instructional_text" msgid="7003212763213614833">"ដើម្បី​ប្ដូរឆ្លាស់​រវាង​សេវាកម្មផ្សេងៗ សូមចុច​ប៊ូតុង​ភាពងាយស្រួល​ឱ្យជាប់។"</string>
+    <string name="accessibility_gesture_instructional_text" msgid="5261788874937410950">"ដើម្បី​ប្ដូរឆ្លាស់​រវាង​សេវាកម្មផ្សេងៗ សូមអូស​ឡើងលើ​ដោយប្រើ​ម្រាមដៃ​ពីរ ហើយ​សង្កត់ឱ្យជាប់។"</string>
+    <string name="accessibility_gesture_3finger_instructional_text" msgid="4969448938984394550">"ដើម្បី​ប្ដូរឆ្លាស់​រវាង​សេវាកម្មផ្សេងៗ សូមអូស​ឡើងលើ​ដោយប្រើ​ម្រាមដៃ​បី ហើយ​សង្កត់ឱ្យជាប់។"</string>
     <string name="accessibility_magnification_chooser_text" msgid="1227146738764986237">"ការ​ពង្រីក"</string>
     <string name="user_switched" msgid="3768006783166984410">"អ្នក​ប្រើ​បច្ចុប្បន្ន <xliff:g id="NAME">%1$s</xliff:g> ។"</string>
     <string name="user_switching_message" msgid="2871009331809089783">"កំពុង​ប្ដូរ​ទៅ <xliff:g id="NAME">%1$s</xliff:g>…"</string>
diff --git a/core/res/res/values-kn/strings.xml b/core/res/res/values-kn/strings.xml
index 521343b..2770d92 100644
--- a/core/res/res/values-kn/strings.xml
+++ b/core/res/res/values-kn/strings.xml
@@ -131,6 +131,7 @@
     <!-- no translation found for wfcSpnFormat_spn (4998685024207291232) -->
     <skip />
     <string name="wfcSpnFormat_spn_wifi_calling" msgid="136001023263502280">"<xliff:g id="SPN">%s</xliff:g> ವೈ-ಫೈ ಕರೆ ಮಾಡುವಿಕೆ"</string>
+    <string name="wfcSpnFormat_spn_wifi_calling_vo_hyphen" msgid="1730997175789582756">"<xliff:g id="SPN">%s</xliff:g> ವೈ-ಫೈ ಕರೆ ಮಾಡುವಿಕೆ"</string>
     <string name="wfcSpnFormat_wlan_call" msgid="2533371081782489793">"WLAN ಕರೆ"</string>
     <string name="wfcSpnFormat_spn_wlan_call" msgid="2315240198303197168">"<xliff:g id="SPN">%s</xliff:g> WLAN ಕರೆ"</string>
     <string name="wfcSpnFormat_spn_wifi" msgid="6546481665561961938">"<xliff:g id="SPN">%s</xliff:g> ವೈ-ಫೈ"</string>
@@ -1612,8 +1613,6 @@
     <string name="display_manager_overlay_display_name" msgid="5142365982271620716">"ಓವರ್‌ಲೇ #<xliff:g id="ID">%1$d</xliff:g>"</string>
     <string name="display_manager_overlay_display_title" msgid="652124517672257172">"<xliff:g id="NAME">%1$s</xliff:g>: <xliff:g id="WIDTH">%2$d</xliff:g>x<xliff:g id="HEIGHT">%3$d</xliff:g>, <xliff:g id="DPI">%4$d</xliff:g> dpi"</string>
     <string name="display_manager_overlay_display_secure_suffix" msgid="6022119702628572080">", ಸುರಕ್ಷಿತ"</string>
-    <string name="activity_starter_block_bg_activity_starts_permissive" msgid="6995473033438879646">"ಭವಿಷ್ಯದ Q ಬಿಲ್ಡ್‌ಗಳಲ್ಲಿ <xliff:g id="PACKAGENAME">%1$s</xliff:g> ನಿಂದ ಪ್ರಾರಂಭವಾಗುವ ಈ ಹಿನ್ನೆಲೆ ಚಟುವಟಿಕೆಯನ್ನು ನಿರ್ಬಂಧಿಸಲಾಗುತ್ತದೆ. g.co/dev/bgblock ಅನ್ನು ನೋಡಿ."</string>
-    <string name="activity_starter_block_bg_activity_starts_enforcing" msgid="3317816771072146229">"<xliff:g id="PACKAGENAME">%1$s</xliff:g> ನಿಂದ ಪ್ರಾರಂಭವಾಗುವ ಹಿನ್ನೆಲೆ ಚಟುವಟಿಕೆಯನ್ನು ನಿರ್ಬಂಧಿಸಲಾಗಿದೆ. g.co/dev/bgblock ಅನ್ನು ನೋಡಿ."</string>
     <string name="kg_forgot_pattern_button_text" msgid="8852021467868220608">"ಪ್ಯಾಟರ್ನ್ ಅನ್ನು ಮರೆತಿರುವಿರಿ"</string>
     <string name="kg_wrong_pattern" msgid="1850806070801358830">"ತಪ್ಪು ಪ್ಯಾಟರ್ನ್"</string>
     <string name="kg_wrong_password" msgid="2333281762128113157">"ತಪ್ಪು ಪಾಸ್‌ವರ್ಡ್"</string>
@@ -1667,8 +1666,12 @@
     <string name="accessibility_shortcut_enabling_service" msgid="7771852911861522636">"ಪ್ರವೇಶಿಸುವಿಕೆ ಶಾರ್ಟ್‌ಕಟ್‌, <xliff:g id="SERVICE_NAME">%1$s</xliff:g> ಅನ್ನು ಆನ್ ಮಾಡಿದೆ"</string>
     <string name="accessibility_shortcut_disabling_service" msgid="2747243438223109821">"ಪ್ರವೇಶಿಸುವಿಕೆ ಶಾರ್ಟ್‌ಕಟ್‌, <xliff:g id="SERVICE_NAME">%1$s</xliff:g> ಅನ್ನು ಆಫ್ ಮಾಡಿದೆ"</string>
     <string name="accessibility_shortcut_spoken_feedback" msgid="8376923232350078434">"<xliff:g id="SERVICE_NAME">%1$s</xliff:g> ಅನ್ನು ಬಳಸಲು ಎರಡೂ ಧ್ವನಿ ಕೀಗಳನ್ನು ಮೂರು ಸೆಕೆಂಡ್‌ಗಳ ಕಾಲ ಒತ್ತಿ ಹಿಡಿದುಕೊಳ್ಳಿ"</string>
-    <string name="accessibility_button_prompt_text" msgid="4234556536456854251">"ನೀವು ಪ್ರವೇಶಿಸುವಿಕೆ ಬಟನ್ ಟ್ಯಾಪ್ ಮಾಡಿದಾಗ ಬಳಸುವುದಕ್ಕಾಗಿ ವೈಶಿಷ್ಟ್ಯವನ್ನು ಆರಿಸಿ:"</string>
-    <string name="accessibility_button_instructional_text" msgid="6942300463612999993">"ವೈಶಿಷ್ಟ್ಯಗಳನ್ನು ಬದಲಾಯಿಸಲು, ಪ್ರವೇಶಿಸುವಿಕೆ ಬಟನ್ ಒತ್ತಿಹಿಡಿದುಕೊಳ್ಳಿ."</string>
+    <string name="accessibility_button_prompt_text" msgid="1176658502969738564">"ನೀವು ಪ್ರವೇಶಿಸುವಿಕೆ ಬಟನ್ ಟ್ಯಾಪ್ ಮಾಡಿದಾಗ ಬಳಸುವುದಕ್ಕಾಗಿ ಸೇವೆಯೊಂದನ್ನು ಆರಿಸಿ:"</string>
+    <string name="accessibility_gesture_prompt_text" msgid="8259145549733019401">"ಪ್ರವೇಶಿಸುವಿಕೆ ಗೆಸ್ಚರ್‌ನೊಂದಿಗೆ ಬಳಸಲು ಸೇವೆಯೊಂದನ್ನು ಆಯ್ಕೆಮಾಡಿ (ಎರಡು ಬೆರಳುಗಳನ್ನು ಬಳಸಿ ಪರದೆಯ ಕೆಳಭಾಗದಿಂದ ಮೇಲಕ್ಕೆ ಸ್ವೈಪ್ ಮಾಡಿ):"</string>
+    <string name="accessibility_gesture_3finger_prompt_text" msgid="1041435574275047665">"ಪ್ರವೇಶಿಸುವಿಕೆ ಗೆಸ್ಚರ್‌ನೊಂದಿಗೆ ಬಳಸಲು ಸೇವೆಯೊಂದನ್ನು ಆಯ್ಕೆಮಾಡಿ (ಮೂರು ಬೆರಳುಗಳನ್ನು ಬಳಸಿ ಪರದೆಯ ಕೆಳಭಾಗದಿಂದ ಮೇಲಕ್ಕೆ ಸ್ವೈಪ್ ಮಾಡಿ):"</string>
+    <string name="accessibility_button_instructional_text" msgid="7003212763213614833">"ಸೇವೆಗಳ ನಡುವೆ ಬದಲಿಸಲು, ಸ್ಪರ್ಶಿಸಿ ಮತ್ತು ಪ್ರವೇಶಿಸುವಿಕೆ ಬಟನ್ ಅನ್ನು ಒತ್ತಿ ಹಿಡಿಯಿರಿ."</string>
+    <string name="accessibility_gesture_instructional_text" msgid="5261788874937410950">"ಸೇವೆಗಳ ನಡುವೆ ಬದಲಿಸಲು, ಎರಡು ಬೆರಳುಗಳನ್ನು ಬಳಸಿ ಮೇಲಕ್ಕೆ ಸ್ವೈಪ್ ಮಾಡಿ ಮತ್ತು ಒತ್ತಿ ಹಿಡಿಯಿರಿ."</string>
+    <string name="accessibility_gesture_3finger_instructional_text" msgid="4969448938984394550">"ಸೇವೆಗಳ ನಡುವೆ ಬದಲಿಸಲು, ಮೂರು ಬೆರಳುಗಳನ್ನು ಬಳಸಿ ಮೇಲಕ್ಕೆ ಸ್ವೈಪ್ ಮಾಡಿ ಮತ್ತು ಒತ್ತಿ ಹಿಡಿಯಿರಿ."</string>
     <string name="accessibility_magnification_chooser_text" msgid="1227146738764986237">"ಹಿಗ್ಗಿಸುವಿಕೆ"</string>
     <string name="user_switched" msgid="3768006783166984410">"ಪ್ರಸ್ತುತ ಬಳಕೆದಾರರು <xliff:g id="NAME">%1$s</xliff:g>."</string>
     <string name="user_switching_message" msgid="2871009331809089783">"<xliff:g id="NAME">%1$s</xliff:g> ಗೆ ಬದಲಾಯಿಸಲಾಗುತ್ತಿದೆ…"</string>
diff --git a/core/res/res/values-ko/strings.xml b/core/res/res/values-ko/strings.xml
index 32f7eec..69c53db 100644
--- a/core/res/res/values-ko/strings.xml
+++ b/core/res/res/values-ko/strings.xml
@@ -131,6 +131,7 @@
     <!-- no translation found for wfcSpnFormat_spn (4998685024207291232) -->
     <skip />
     <string name="wfcSpnFormat_spn_wifi_calling" msgid="136001023263502280">"<xliff:g id="SPN">%s</xliff:g> Wi-Fi 통화"</string>
+    <string name="wfcSpnFormat_spn_wifi_calling_vo_hyphen" msgid="1730997175789582756">"<xliff:g id="SPN">%s</xliff:g> Wi-Fi 통화"</string>
     <string name="wfcSpnFormat_wlan_call" msgid="2533371081782489793">"WLAN 통화"</string>
     <string name="wfcSpnFormat_spn_wlan_call" msgid="2315240198303197168">"<xliff:g id="SPN">%s</xliff:g> WLAN 통화"</string>
     <string name="wfcSpnFormat_spn_wifi" msgid="6546481665561961938">"<xliff:g id="SPN">%s</xliff:g> Wi-Fi"</string>
@@ -1357,8 +1358,7 @@
     <string name="test_harness_mode_notification_message" msgid="1343197173054407119">"테스트 하네스 모드를 사용 중지하려면 초기화하세요."</string>
     <string name="usb_contaminant_detected_title" msgid="7136400633704058349">"USB 포트에서 액체 또는 이물질 감지됨"</string>
     <string name="usb_contaminant_detected_message" msgid="832337061059487250">"USB 포트가 자동으로 사용 중지되었습니다. 자세한 내용을 보려면 탭하세요."</string>
-    <!-- no translation found for usb_contaminant_not_detected_title (7708281124088684821) -->
-    <skip />
+    <string name="usb_contaminant_not_detected_title" msgid="7708281124088684821">"USB 포트를 사용해도 좋음"</string>
     <string name="usb_contaminant_not_detected_message" msgid="2415791798244545292">"휴대전화에서 액체나 이물질이 더 이상 감지되지 않습니다."</string>
     <string name="taking_remote_bugreport_notification_title" msgid="6742483073875060934">"버그 보고서 가져오는 중..."</string>
     <string name="share_remote_bugreport_notification_title" msgid="4987095013583691873">"버그 보고서를 공유하시겠습니까?"</string>
@@ -1612,8 +1612,6 @@
     <string name="display_manager_overlay_display_name" msgid="5142365982271620716">"<xliff:g id="ID">%1$d</xliff:g>번째 오버레이"</string>
     <string name="display_manager_overlay_display_title" msgid="652124517672257172">"<xliff:g id="NAME">%1$s</xliff:g>: <xliff:g id="WIDTH">%2$d</xliff:g>x<xliff:g id="HEIGHT">%3$d</xliff:g>, <xliff:g id="DPI">%4$d</xliff:g> dpi"</string>
     <string name="display_manager_overlay_display_secure_suffix" msgid="6022119702628572080">", 보안"</string>
-    <string name="activity_starter_block_bg_activity_starts_permissive" msgid="6995473033438879646">"<xliff:g id="PACKAGENAME">%1$s</xliff:g>의 백그라운드 활동 시작은 향후 Q 빌드에서 차단됩니다. g.co/dev/bgblock을 참조하세요."</string>
-    <string name="activity_starter_block_bg_activity_starts_enforcing" msgid="3317816771072146229">"<xliff:g id="PACKAGENAME">%1$s</xliff:g>의 백그라운드 활동 시작이 차단되었습니다. g.co/dev/bgblock을 참조하세요."</string>
     <string name="kg_forgot_pattern_button_text" msgid="8852021467868220608">"패턴을 잊음"</string>
     <string name="kg_wrong_pattern" msgid="1850806070801358830">"잘못된 패턴"</string>
     <string name="kg_wrong_password" msgid="2333281762128113157">"잘못된 비밀번호"</string>
@@ -1667,8 +1665,12 @@
     <string name="accessibility_shortcut_enabling_service" msgid="7771852911861522636">"접근성 단축키로 인해 <xliff:g id="SERVICE_NAME">%1$s</xliff:g>이(가) 사용 설정되었습니다."</string>
     <string name="accessibility_shortcut_disabling_service" msgid="2747243438223109821">"접근성 단축키로 인해 <xliff:g id="SERVICE_NAME">%1$s</xliff:g>이(가) 사용 중지되었습니다."</string>
     <string name="accessibility_shortcut_spoken_feedback" msgid="8376923232350078434">"<xliff:g id="SERVICE_NAME">%1$s</xliff:g> 서비스를 사용하려면 두 볼륨 키를 3초 동안 길게 누르세요"</string>
-    <string name="accessibility_button_prompt_text" msgid="4234556536456854251">"접근성 버튼을 탭할 때 사용할 기능을 선택하세요."</string>
-    <string name="accessibility_button_instructional_text" msgid="6942300463612999993">"기능을 변경하려면 접근성 버튼을 길게 터치하세요."</string>
+    <string name="accessibility_button_prompt_text" msgid="1176658502969738564">"접근성 버튼을 탭했을 때 실행할 서비스를 선택하세요."</string>
+    <string name="accessibility_gesture_prompt_text" msgid="8259145549733019401">"접근성 동작(두 손가락을 사용하여 화면 하단에서 위로 스와이프)으로 실행할 서비스를 선택하세요."</string>
+    <string name="accessibility_gesture_3finger_prompt_text" msgid="1041435574275047665">"접근성 동작(세 손가락을 사용하여 화면 하단에서 위로 스와이프)으로 실행할 서비스를 선택하세요."</string>
+    <string name="accessibility_button_instructional_text" msgid="7003212763213614833">"서비스 간에 전환하려면 접근성 버튼을 길게 터치합니다."</string>
+    <string name="accessibility_gesture_instructional_text" msgid="5261788874937410950">"서비스 간에 전환하려면 두 손가락을 사용하여 위로 스와이프한 다음 잠시 기다립니다."</string>
+    <string name="accessibility_gesture_3finger_instructional_text" msgid="4969448938984394550">"서비스 간에 전환하려면 세 손가락을 사용하여 위로 스와이프한 다음 잠시 기다립니다."</string>
     <string name="accessibility_magnification_chooser_text" msgid="1227146738764986237">"확대"</string>
     <string name="user_switched" msgid="3768006783166984410">"현재 사용자는 <xliff:g id="NAME">%1$s</xliff:g>님입니다."</string>
     <string name="user_switching_message" msgid="2871009331809089783">"<xliff:g id="NAME">%1$s</xliff:g>(으)로 전환하는 중…"</string>
diff --git a/core/res/res/values-ky/strings.xml b/core/res/res/values-ky/strings.xml
index f10c057..d78e8b9 100644
--- a/core/res/res/values-ky/strings.xml
+++ b/core/res/res/values-ky/strings.xml
@@ -131,6 +131,7 @@
     <!-- no translation found for wfcSpnFormat_spn (4998685024207291232) -->
     <skip />
     <string name="wfcSpnFormat_spn_wifi_calling" msgid="136001023263502280">"<xliff:g id="SPN">%s</xliff:g> Wi-Fi аркылуу чалуу"</string>
+    <string name="wfcSpnFormat_spn_wifi_calling_vo_hyphen" msgid="1730997175789582756">"<xliff:g id="SPN">%s</xliff:g> аркылуу Wi-Fi менен чалуу"</string>
     <string name="wfcSpnFormat_wlan_call" msgid="2533371081782489793">"WLAN аркылуу чалуу"</string>
     <string name="wfcSpnFormat_spn_wlan_call" msgid="2315240198303197168">"<xliff:g id="SPN">%s</xliff:g> WLAN аркылуу чалуу"</string>
     <string name="wfcSpnFormat_spn_wifi" msgid="6546481665561961938">"<xliff:g id="SPN">%s</xliff:g> Wi-Fi"</string>
@@ -1359,8 +1360,7 @@
     <string name="test_harness_mode_notification_message" msgid="1343197173054407119">"Сыноо программасынын режимин өчүрүү үчүн, баштапкы жөндөөлөргө кайтарыңыз."</string>
     <string name="usb_contaminant_detected_title" msgid="7136400633704058349">"USB портунда суюктук же урандылар бар"</string>
     <string name="usb_contaminant_detected_message" msgid="832337061059487250">"USB порт автоматтык түрдө өчүрүлдү. Кененирээк маалымат алуу үчүн таптап коюңуз."</string>
-    <!-- no translation found for usb_contaminant_not_detected_title (7708281124088684821) -->
-    <skip />
+    <string name="usb_contaminant_not_detected_title" msgid="7708281124088684821">"USB портун колдонууга болот"</string>
     <string name="usb_contaminant_not_detected_message" msgid="2415791798244545292">"Телефон суюктук менен урандыларды аныктаган жок."</string>
     <string name="taking_remote_bugreport_notification_title" msgid="6742483073875060934">"Мүчүлүштүк тууралуу кабар алынууда…"</string>
     <string name="share_remote_bugreport_notification_title" msgid="4987095013583691873">"Мүчүлүштүк тууралуу баяндама бөлүшүлсүнбү?"</string>
@@ -1496,7 +1496,7 @@
     <string name="find_next" msgid="5742124618942193978">"Кийинкиси"</string>
     <string name="find_previous" msgid="2196723669388360506">"Мурункусу"</string>
     <string name="gpsNotifTicker" msgid="5622683912616496172">"<xliff:g id="NAME">%s</xliff:g> колдонуучусу жайгашкан жердин маалыматын сурады"</string>
-    <string name="gpsNotifTitle" msgid="5446858717157416839">"Жайгашкан жердин маалыматын суроо"</string>
+    <string name="gpsNotifTitle" msgid="5446858717157416839">"Каякта экенин билүү"</string>
     <string name="gpsNotifMessage" msgid="1374718023224000702">"<xliff:g id="NAME">%1$s</xliff:g> (<xliff:g id="SERVICE">%2$s</xliff:g>) сурады"</string>
     <string name="gpsVerifYes" msgid="2346566072867213563">"Ооба"</string>
     <string name="gpsVerifNo" msgid="1146564937346454865">"Жок"</string>
@@ -1614,8 +1614,6 @@
     <string name="display_manager_overlay_display_name" msgid="5142365982271620716">"Катмар №<xliff:g id="ID">%1$d</xliff:g>"</string>
     <string name="display_manager_overlay_display_title" msgid="652124517672257172">"<xliff:g id="NAME">%1$s</xliff:g>: <xliff:g id="WIDTH">%2$d</xliff:g>x<xliff:g id="HEIGHT">%3$d</xliff:g>, <xliff:g id="DPI">%4$d</xliff:g> dpi"</string>
     <string name="display_manager_overlay_display_secure_suffix" msgid="6022119702628572080">", корголгон"</string>
-    <string name="activity_starter_block_bg_activity_starts_permissive" msgid="6995473033438879646">"<xliff:g id="PACKAGENAME">%1$s</xliff:g> сайтынын фондук режимде иштеши Q курамдарында бөгөттөлүп турат. Төмөнкүгө өтүңүз: g.co/dev/bgblock."</string>
-    <string name="activity_starter_block_bg_activity_starts_enforcing" msgid="3317816771072146229">"<xliff:g id="PACKAGENAME">%1$s</xliff:g> сайтынын фондук режимде иштеши бөгөттөлдү. Төмөнкүгө өтүңүз: g.co/dev/bgblock."</string>
     <string name="kg_forgot_pattern_button_text" msgid="8852021467868220608">"Үлгү унутулду"</string>
     <string name="kg_wrong_pattern" msgid="1850806070801358830">"Графикалык ачкыч туура эмес"</string>
     <string name="kg_wrong_password" msgid="2333281762128113157">"Сырсөз туура эмес"</string>
@@ -1669,8 +1667,12 @@
     <string name="accessibility_shortcut_enabling_service" msgid="7771852911861522636">"Атайын мүмкүнчүлүктөр кыска жолу <xliff:g id="SERVICE_NAME">%1$s</xliff:g> кызматын күйгүздү"</string>
     <string name="accessibility_shortcut_disabling_service" msgid="2747243438223109821">"Атайын мүмкүнчүлүктөр кыска жолу <xliff:g id="SERVICE_NAME">%1$s</xliff:g> кызматын өчүрдү"</string>
     <string name="accessibility_shortcut_spoken_feedback" msgid="8376923232350078434">"<xliff:g id="SERVICE_NAME">%1$s</xliff:g> кызматын колдонуу үчүн үнүн чоңойтуп/кичирейтүү баскычтарын үч секунд коё бербей басып туруңуз"</string>
-    <string name="accessibility_button_prompt_text" msgid="4234556536456854251">"Атайын мүмкүнчүлүктөр баскычын таптаганыңызда иштей турган функцияны тандаңыз:"</string>
-    <string name="accessibility_button_instructional_text" msgid="6942300463612999993">"Функцияларды өзгөртүү үчүн Атайын мүмкүнчүлүктөр баскычын басып, кармап туруңуз."</string>
+    <string name="accessibility_button_prompt_text" msgid="1176658502969738564">"Атайын мүмкүнчүлүктөр баскычын таптаганыңызда иштей турган кызматты тандаңыз:"</string>
+    <string name="accessibility_gesture_prompt_text" msgid="8259145549733019401">"Атайын мүмкүнчүлүктөр жаңсоосу үчүн кызматты тандаңыз (эки манжаңыз менен экрандын ылдый жагынан өйдө карай сүрүңүз):"</string>
+    <string name="accessibility_gesture_3finger_prompt_text" msgid="1041435574275047665">"Атайын мүмкүнчүлүктөр жаңсоосу үчүн кызматты тандаңыз (үч манжаңыз менен экрандын ылдый жагынан өйдө карай сүрүңүз):"</string>
+    <string name="accessibility_button_instructional_text" msgid="7003212763213614833">"Кызматтарды которуштуруу үчүн Атайын мүмкүнчүлүктөр баскычын басып, кармап туруңуз."</string>
+    <string name="accessibility_gesture_instructional_text" msgid="5261788874937410950">"Кызматтарды которуштуруу үчүн эки манжаңыз менен өйдө сүрүп, кармап туруңуз."</string>
+    <string name="accessibility_gesture_3finger_instructional_text" msgid="4969448938984394550">"Кызматтарды которуштуруу үчүн үч манжаңыз менен өйдө сүрүп, кармап туруңуз."</string>
     <string name="accessibility_magnification_chooser_text" msgid="1227146738764986237">"Чоңойтуу"</string>
     <string name="user_switched" msgid="3768006783166984410">"Учурдагы колдонуучу <xliff:g id="NAME">%1$s</xliff:g>."</string>
     <string name="user_switching_message" msgid="2871009331809089783">"<xliff:g id="NAME">%1$s</xliff:g> дегенге которулууда…"</string>
diff --git a/core/res/res/values-lo/strings.xml b/core/res/res/values-lo/strings.xml
index 85957c0..b5d950e 100644
--- a/core/res/res/values-lo/strings.xml
+++ b/core/res/res/values-lo/strings.xml
@@ -131,6 +131,7 @@
     <!-- no translation found for wfcSpnFormat_spn (4998685024207291232) -->
     <skip />
     <string name="wfcSpnFormat_spn_wifi_calling" msgid="136001023263502280">"<xliff:g id="SPN">%s</xliff:g> Wi-Fi Calling"</string>
+    <string name="wfcSpnFormat_spn_wifi_calling_vo_hyphen" msgid="1730997175789582756">"<xliff:g id="SPN">%s</xliff:g> ການໂທ Wi-Fi"</string>
     <string name="wfcSpnFormat_wlan_call" msgid="2533371081782489793">"WLAN Call"</string>
     <string name="wfcSpnFormat_spn_wlan_call" msgid="2315240198303197168">"<xliff:g id="SPN">%s</xliff:g> WLAN Call"</string>
     <string name="wfcSpnFormat_spn_wifi" msgid="6546481665561961938">"<xliff:g id="SPN">%s</xliff:g> Wi-Fi"</string>
@@ -1357,8 +1358,7 @@
     <string name="test_harness_mode_notification_message" msgid="1343197173054407119">"ດຳເນີນການຣີເຊັດເປັນຄ່າຈາກໂຮງງານເພື່ອປິດການນຳໃຊ້ໂໝດ Test Harness."</string>
     <string name="usb_contaminant_detected_title" msgid="7136400633704058349">"ມີຂອງແຫລວ ຫຼື ເສດດິນໃນຜອດ USB"</string>
     <string name="usb_contaminant_detected_message" msgid="832337061059487250">"ປິດຜອດ USB ໂດຍອັດຕະໂນມັດແລ້ວ. ແຕະເພື່ອສຶກສາເພີ່ມເຕີມ."</string>
-    <!-- no translation found for usb_contaminant_not_detected_title (7708281124088684821) -->
-    <skip />
+    <string name="usb_contaminant_not_detected_title" msgid="7708281124088684821">"ສາມາດໃຊ້ຜອດ USB ໄດ້"</string>
     <string name="usb_contaminant_not_detected_message" msgid="2415791798244545292">"ໂທລະສັບຈະບໍ່ກວດຫາຂອງແຫລວ ຫຼື ເສດດິນອີກຕໍ່ໄປ."</string>
     <string name="taking_remote_bugreport_notification_title" msgid="6742483073875060934">"ກຳລັງຂໍລາຍງານຂໍ້ຜິດພາດ…"</string>
     <string name="share_remote_bugreport_notification_title" msgid="4987095013583691873">"ແບ່ງປັນລາຍງານບັນຫາບໍ?"</string>
@@ -1612,8 +1612,6 @@
     <string name="display_manager_overlay_display_name" msgid="5142365982271620716">"ການວາງຊ້ອນ #<xliff:g id="ID">%1$d</xliff:g>"</string>
     <string name="display_manager_overlay_display_title" msgid="652124517672257172">"<xliff:g id="NAME">%1$s</xliff:g>: <xliff:g id="WIDTH">%2$d</xliff:g>x<xliff:g id="HEIGHT">%3$d</xliff:g>, <xliff:g id="DPI">%4$d</xliff:g> dpi"</string>
     <string name="display_manager_overlay_display_secure_suffix" msgid="6022119702628572080">", ປອດໄພ"</string>
-    <string name="activity_starter_block_bg_activity_starts_permissive" msgid="6995473033438879646">"ການເລີ່ມການເຄື່ອນໄຫວໃນພື້ນຫຼັງນີ້ຈາກ <xliff:g id="PACKAGENAME">%1$s</xliff:g> ຈະຖືກບລັອກໄວ້ໃນ Q ເວີຊັນອະນາຄົດ. ກະລຸນາອ່ານ g.co/dev/bgblock."</string>
-    <string name="activity_starter_block_bg_activity_starts_enforcing" msgid="3317816771072146229">"ບລັອກການເຄື່ອນໄຫວພື້ນຫຼັງຈາກ <xliff:g id="PACKAGENAME">%1$s</xliff:g> ໄວ້ແລ້ວ. ກະລຸນາອ່ານ g.co/dev/bgblock."</string>
     <string name="kg_forgot_pattern_button_text" msgid="8852021467868220608">"ລືມຮູບແບບປົດລັອກ?"</string>
     <string name="kg_wrong_pattern" msgid="1850806070801358830">"ຮູບແບບຜິດ"</string>
     <string name="kg_wrong_password" msgid="2333281762128113157">"ລະຫັດຜ່ານບໍ່ຖືກຕ້ອງ"</string>
@@ -1667,8 +1665,12 @@
     <string name="accessibility_shortcut_enabling_service" msgid="7771852911861522636">"Accessibility Shortcut turned <xliff:g id="SERVICE_NAME">%1$s</xliff:g> on"</string>
     <string name="accessibility_shortcut_disabling_service" msgid="2747243438223109821">"Accessibility Shortcut turned <xliff:g id="SERVICE_NAME">%1$s</xliff:g> off"</string>
     <string name="accessibility_shortcut_spoken_feedback" msgid="8376923232350078434">"ກົດປຸ່ມສຽງທັງສອງພ້ອມກັນຄ້າງໄວ້ສາມວິນາທີເພື່ອໃຊ້ <xliff:g id="SERVICE_NAME">%1$s</xliff:g>"</string>
-    <string name="accessibility_button_prompt_text" msgid="4234556536456854251">"ເລືອກຄຸນສົມບັດທີ່ຈະໃຊ້ເມື່ອທ່ານແຕະປຸ່ມການຊ່ວຍເຂົ້າເຖິງ:"</string>
-    <string name="accessibility_button_instructional_text" msgid="6942300463612999993">"ເພື່ອປ່ຽນຄຸນສົມບັດ, ໃຫ້ແຕະປຸ່ມການຊ່ວຍເຂົ້າເຖິງຄ້າງໄວ້."</string>
+    <string name="accessibility_button_prompt_text" msgid="1176658502969738564">"ເລືອກບໍລິການເພື່ອໃຊ້ເມື່ອທ່ານແຕະໃສ່ປຸ່ມການຊ່ວຍເຂົ້າເຖິງ:"</string>
+    <string name="accessibility_gesture_prompt_text" msgid="8259145549733019401">"ເລືອກບໍລິການເພື່ອໃຊ້ກັບທ່າທາງການຊ່ວຍເຂົ້າເຖິງ (ປັດຂຶ້ນຈາກລຸ່ມສຸດຂອງໜ້າຈໍດ້ວຍສອງນິ້ວ):"</string>
+    <string name="accessibility_gesture_3finger_prompt_text" msgid="1041435574275047665">"ເລືອກບໍລິການເພື່ອໃຊ້ກັບທ່າທາງການຊ່ວຍເຂົ້າເຖິງ (ປັດຂຶ້ນຈາກລຸ່ມສຸດຂອງໜ້າຈໍດ້ວຍສາມນິ້ວ):"</string>
+    <string name="accessibility_button_instructional_text" msgid="7003212763213614833">"ເພື່ອສະຫຼັບລະຫວ່າງບໍລິການຕ່າງໆ, ໃຫ້ແຕະໃສ່ປຸ່ມການຊ່ວຍເຂົ້າເຖິງຄ້າງໄວ້."</string>
+    <string name="accessibility_gesture_instructional_text" msgid="5261788874937410950">"ເພື່ອສະຫຼັບລະຫວ່າງບໍລິການຕ່າງໆ, ໃຫ້ປັດຂຶ້ນດ້ວຍສອງນິ້ວຄ້າງໄວ້."</string>
+    <string name="accessibility_gesture_3finger_instructional_text" msgid="4969448938984394550">"ເພື່ອສະຫຼັບລະຫວ່າງບໍລິການຕ່າງໆ, ໃຫ້ປັດຂຶ້ນດ້ວຍສາມນິ້ວຄ້າງໄວ້."</string>
     <string name="accessibility_magnification_chooser_text" msgid="1227146738764986237">"ການຂະຫຍາຍ"</string>
     <string name="user_switched" msgid="3768006783166984410">"ຜູ່ໃຊ້ປັດຈຸບັນ <xliff:g id="NAME">%1$s</xliff:g> ."</string>
     <string name="user_switching_message" msgid="2871009331809089783">"ກຳ​ລັງ​ສະ​ລັບ​​ໄປ​ຫາ <xliff:g id="NAME">%1$s</xliff:g>…"</string>
diff --git a/core/res/res/values-lt/strings.xml b/core/res/res/values-lt/strings.xml
index d1fc5fa..0cb0a3d 100644
--- a/core/res/res/values-lt/strings.xml
+++ b/core/res/res/values-lt/strings.xml
@@ -133,6 +133,7 @@
     <!-- no translation found for wfcSpnFormat_spn (4998685024207291232) -->
     <skip />
     <string name="wfcSpnFormat_spn_wifi_calling" msgid="136001023263502280">"<xliff:g id="SPN">%s</xliff:g> „Wi-Fi“ skambinimas"</string>
+    <string name="wfcSpnFormat_spn_wifi_calling_vo_hyphen" msgid="1730997175789582756">"<xliff:g id="SPN">%s</xliff:g> „Wi-Fi“ skambinimas"</string>
     <string name="wfcSpnFormat_wlan_call" msgid="2533371081782489793">"WLAN skambutis"</string>
     <string name="wfcSpnFormat_spn_wlan_call" msgid="2315240198303197168">"<xliff:g id="SPN">%s</xliff:g> WLAN skambutis"</string>
     <string name="wfcSpnFormat_spn_wifi" msgid="6546481665561961938">"<xliff:g id="SPN">%s</xliff:g> „Wi-Fi“"</string>
@@ -1401,8 +1402,7 @@
     <string name="test_harness_mode_notification_message" msgid="1343197173054407119">"Atkurkite gamyklinius duomenis, kad išjungtumėte testavimo sistemos režimą."</string>
     <string name="usb_contaminant_detected_title" msgid="7136400633704058349">"USB prievade yra skysčių ar smulkių dalelių"</string>
     <string name="usb_contaminant_detected_message" msgid="832337061059487250">"USB prievadas automatiškai išjungtas. Palieskite, kad sužinotumėte daugiau."</string>
-    <!-- no translation found for usb_contaminant_not_detected_title (7708281124088684821) -->
-    <skip />
+    <string name="usb_contaminant_not_detected_title" msgid="7708281124088684821">"Saugu naudoti USB prievadą"</string>
     <string name="usb_contaminant_not_detected_message" msgid="2415791798244545292">"Telefonas nebeaptinka skysčių ar smulkių dalelių."</string>
     <string name="taking_remote_bugreport_notification_title" msgid="6742483073875060934">"Pateikiamas pranešimas apie riktą…"</string>
     <string name="share_remote_bugreport_notification_title" msgid="4987095013583691873">"Bendrinti pranešimą apie riktą?"</string>
@@ -1658,8 +1658,6 @@
     <string name="display_manager_overlay_display_name" msgid="5142365982271620716">"Perdanga nr. <xliff:g id="ID">%1$d</xliff:g>"</string>
     <string name="display_manager_overlay_display_title" msgid="652124517672257172">"„<xliff:g id="NAME">%1$s</xliff:g>“: <xliff:g id="WIDTH">%2$d</xliff:g> x <xliff:g id="HEIGHT">%3$d</xliff:g>, <xliff:g id="DPI">%4$d</xliff:g> tašk. colyje"</string>
     <string name="display_manager_overlay_display_secure_suffix" msgid="6022119702628572080">", saugu"</string>
-    <string name="activity_starter_block_bg_activity_starts_permissive" msgid="6995473033438879646">"Šios fono veiklos paleidimas iš „<xliff:g id="PACKAGENAME">%1$s</xliff:g>“ bus užblokuotas būsimose Q versijose. Žr. g.co/dev/bgblock."</string>
-    <string name="activity_starter_block_bg_activity_starts_enforcing" msgid="3317816771072146229">"Fono veiklos paleidimas iš „<xliff:g id="PACKAGENAME">%1$s</xliff:g>“ užblokuotas. Žr. g.co/dev/bgblock."</string>
     <string name="kg_forgot_pattern_button_text" msgid="8852021467868220608">"Pamiršau atrakinimo piešinį"</string>
     <string name="kg_wrong_pattern" msgid="1850806070801358830">"Netinkamas atrakinimo piešinys"</string>
     <string name="kg_wrong_password" msgid="2333281762128113157">"Netinkamas slaptažodis"</string>
@@ -1715,8 +1713,12 @@
     <string name="accessibility_shortcut_enabling_service" msgid="7771852911861522636">"Pritaikymo neįgaliesiems sparčiuoju klavišu buvo įjungta „<xliff:g id="SERVICE_NAME">%1$s</xliff:g>“"</string>
     <string name="accessibility_shortcut_disabling_service" msgid="2747243438223109821">"Pritaikymo neįgaliesiems sparčiuoju klavišu buvo išjungta „<xliff:g id="SERVICE_NAME">%1$s</xliff:g>“"</string>
     <string name="accessibility_shortcut_spoken_feedback" msgid="8376923232350078434">"Jei norite naudoti „<xliff:g id="SERVICE_NAME">%1$s</xliff:g>“, paspauskite abu garsumo klavišus ir palaikykite tris sekundes"</string>
-    <string name="accessibility_button_prompt_text" msgid="4234556536456854251">"Pasirinkite funkciją, kuri bus naudojama, kai paliesite pritaikymo neįgaliesiems mygtuką:"</string>
-    <string name="accessibility_button_instructional_text" msgid="6942300463612999993">"Jei norite pakeisti funkcijas, palieskite ir palaikykite pritaikymo neįgaliesiems mygtuką."</string>
+    <string name="accessibility_button_prompt_text" msgid="1176658502969738564">"Pasirinkite paslaugą, kuri bus naudojama, kai paliesite pritaikomumo mygtuką:"</string>
+    <string name="accessibility_gesture_prompt_text" msgid="8259145549733019401">"Pasirinkite paslaugą, kuri bus naudojama su pritaikomumo gestu (perbraukimas aukštyn dviem pirštais iš ekrano apačios):"</string>
+    <string name="accessibility_gesture_3finger_prompt_text" msgid="1041435574275047665">"Pasirinkite paslaugą, kuri bus naudojama su pritaikomumo gestu (perbraukimas aukštyn trimis pirštais iš ekrano apačios):"</string>
+    <string name="accessibility_button_instructional_text" msgid="7003212763213614833">"Norėdami perjungti paslaugas, palieskite ir palaikykite pritaikomumo mygtuką."</string>
+    <string name="accessibility_gesture_instructional_text" msgid="5261788874937410950">"Norėdami perjungti paslaugas, perbraukite aukštyn dviem pirštais ir palaikykite."</string>
+    <string name="accessibility_gesture_3finger_instructional_text" msgid="4969448938984394550">"Norėdami perjungti paslaugas, perbraukite aukštyn trimis pirštais ir palaikykite."</string>
     <string name="accessibility_magnification_chooser_text" msgid="1227146738764986237">"Didinimas"</string>
     <string name="user_switched" msgid="3768006783166984410">"Dabartinis naudotojas: <xliff:g id="NAME">%1$s</xliff:g>."</string>
     <string name="user_switching_message" msgid="2871009331809089783">"Perjungiama į <xliff:g id="NAME">%1$s</xliff:g>…"</string>
diff --git a/core/res/res/values-lv/strings.xml b/core/res/res/values-lv/strings.xml
index efbb677..7a5301b 100644
--- a/core/res/res/values-lv/strings.xml
+++ b/core/res/res/values-lv/strings.xml
@@ -132,6 +132,7 @@
     <!-- no translation found for wfcSpnFormat_spn (4998685024207291232) -->
     <skip />
     <string name="wfcSpnFormat_spn_wifi_calling" msgid="136001023263502280">"<xliff:g id="SPN">%s</xliff:g> Wi-Fi zvani"</string>
+    <string name="wfcSpnFormat_spn_wifi_calling_vo_hyphen" msgid="1730997175789582756">"<xliff:g id="SPN">%s</xliff:g> Wi-Fi zvani"</string>
     <string name="wfcSpnFormat_wlan_call" msgid="2533371081782489793">"WLAN zvans"</string>
     <string name="wfcSpnFormat_spn_wlan_call" msgid="2315240198303197168">"<xliff:g id="SPN">%s</xliff:g> WLAN zvans"</string>
     <string name="wfcSpnFormat_spn_wifi" msgid="6546481665561961938">"<xliff:g id="SPN">%s</xliff:g> Wi-Fi"</string>
@@ -1379,8 +1380,7 @@
     <string name="test_harness_mode_notification_message" msgid="1343197173054407119">"Lai atspējotu drošības pārbaudes režīmu, veiciet rūpnīcas datu atiestatīšanu."</string>
     <string name="usb_contaminant_detected_title" msgid="7136400633704058349">"USB pieslēgvietā ir šķidrums vai daļiņas"</string>
     <string name="usb_contaminant_detected_message" msgid="832337061059487250">"USB pieslēgvieta ir automātiski atspējota. Pieskarieties, lai uzzinātu vairāk."</string>
-    <!-- no translation found for usb_contaminant_not_detected_title (7708281124088684821) -->
-    <skip />
+    <string name="usb_contaminant_not_detected_title" msgid="7708281124088684821">"USB pieslēgvietu drīkst izmantot"</string>
     <string name="usb_contaminant_not_detected_message" msgid="2415791798244545292">"Tālrunī vairs netiek konstatēts šķidrums vai gruži."</string>
     <string name="taking_remote_bugreport_notification_title" msgid="6742483073875060934">"Notiek kļūdas pārskata izveide…"</string>
     <string name="share_remote_bugreport_notification_title" msgid="4987095013583691873">"Vai kopīgot kļūdas pārskatu?"</string>
@@ -1635,8 +1635,6 @@
     <string name="display_manager_overlay_display_name" msgid="5142365982271620716">"Pārklājums Nr. <xliff:g id="ID">%1$d</xliff:g>"</string>
     <string name="display_manager_overlay_display_title" msgid="652124517672257172">"<xliff:g id="NAME">%1$s</xliff:g>: <xliff:g id="WIDTH">%2$d</xliff:g> x <xliff:g id="HEIGHT">%3$d</xliff:g>, <xliff:g id="DPI">%4$d</xliff:g> dpi"</string>
     <string name="display_manager_overlay_display_secure_suffix" msgid="6022119702628572080">", drošs"</string>
-    <string name="activity_starter_block_bg_activity_starts_permissive" msgid="6995473033438879646">"Šīs fona darbības sākšana no pakotnes <xliff:g id="PACKAGENAME">%1$s</xliff:g> tiks bloķēta turpmākajās Q versijās. Skatiet rakstu g.co/dev/bgblock."</string>
-    <string name="activity_starter_block_bg_activity_starts_enforcing" msgid="3317816771072146229">"Fona darbības sākšana no pakotnes <xliff:g id="PACKAGENAME">%1$s</xliff:g> bloķēta. Skatiet rakstu g.co/dev/bgblock."</string>
     <string name="kg_forgot_pattern_button_text" msgid="8852021467868220608">"Aizmirsu kombināciju"</string>
     <string name="kg_wrong_pattern" msgid="1850806070801358830">"Nepareiza kombinācija"</string>
     <string name="kg_wrong_password" msgid="2333281762128113157">"Nepareiza parole"</string>
@@ -1691,8 +1689,12 @@
     <string name="accessibility_shortcut_enabling_service" msgid="7771852911861522636">"Pieejamības saīsne aktivizēja lietotni <xliff:g id="SERVICE_NAME">%1$s</xliff:g>"</string>
     <string name="accessibility_shortcut_disabling_service" msgid="2747243438223109821">"Pieejamības saīsne deaktivizēja lietotni <xliff:g id="SERVICE_NAME">%1$s</xliff:g>"</string>
     <string name="accessibility_shortcut_spoken_feedback" msgid="8376923232350078434">"Lai izmantotu pakalpojumu <xliff:g id="SERVICE_NAME">%1$s</xliff:g>, nospiediet abus skaļuma taustiņus un turiet tos trīs sekundes."</string>
-    <string name="accessibility_button_prompt_text" msgid="4234556536456854251">"Izvēlieties funkciju, ko izmantot, kad pieskaraties pogai Pieejamība."</string>
-    <string name="accessibility_button_instructional_text" msgid="6942300463612999993">"Lai mainītu funkcijas, pieskarieties pogai Pieejamība un turiet to."</string>
+    <string name="accessibility_button_prompt_text" msgid="1176658502969738564">"Izvēlieties pakalpojumu, ko izmantot, kad pieskaraties pieejamības pogai."</string>
+    <string name="accessibility_gesture_prompt_text" msgid="8259145549733019401">"Izvēlieties pakalpojumu, ko izmantot ar pieejamības žestu (vilkšana ar diviem pirkstiem augšup no ekrāna apakšdaļas)."</string>
+    <string name="accessibility_gesture_3finger_prompt_text" msgid="1041435574275047665">"Izvēlieties pakalpojumu, ko izmantot ar pieejamības žestu (vilkšana ar trīs pirkstiem augšup no ekrāna apakšdaļas)."</string>
+    <string name="accessibility_button_instructional_text" msgid="7003212763213614833">"Lai pārslēgtu pakalpojumus, pieskarieties pieejamības pogai un turiet to."</string>
+    <string name="accessibility_gesture_instructional_text" msgid="5261788874937410950">"Lai pārslēgtu pakalpojumus, velciet ar diviem pirkstiem augšup un turiet."</string>
+    <string name="accessibility_gesture_3finger_instructional_text" msgid="4969448938984394550">"Lai pārslēgtu pakalpojumus, velciet ar trīs pirkstiem augšup un turiet."</string>
     <string name="accessibility_magnification_chooser_text" msgid="1227146738764986237">"Palielinājums"</string>
     <string name="user_switched" msgid="3768006783166984410">"Pašreizējais lietotājs: <xliff:g id="NAME">%1$s</xliff:g>."</string>
     <string name="user_switching_message" msgid="2871009331809089783">"Notiek pāriešana uz: <xliff:g id="NAME">%1$s</xliff:g>"</string>
diff --git a/core/res/res/values-mk/strings.xml b/core/res/res/values-mk/strings.xml
index a0088a8..4a81b9a 100644
--- a/core/res/res/values-mk/strings.xml
+++ b/core/res/res/values-mk/strings.xml
@@ -131,6 +131,7 @@
     <!-- no translation found for wfcSpnFormat_spn (4998685024207291232) -->
     <skip />
     <string name="wfcSpnFormat_spn_wifi_calling" msgid="136001023263502280">"Повици преку Wi-Fi на <xliff:g id="SPN">%s</xliff:g>"</string>
+    <string name="wfcSpnFormat_spn_wifi_calling_vo_hyphen" msgid="1730997175789582756">"Повикување преку Wi-Fi на <xliff:g id="SPN">%s</xliff:g>"</string>
     <string name="wfcSpnFormat_wlan_call" msgid="2533371081782489793">"Повик преку WLAN"</string>
     <string name="wfcSpnFormat_spn_wlan_call" msgid="2315240198303197168">"Повик преку WLAN на <xliff:g id="SPN">%s</xliff:g>"</string>
     <string name="wfcSpnFormat_spn_wifi" msgid="6546481665561961938">"Wi-Fi на <xliff:g id="SPN">%s</xliff:g>"</string>
@@ -1358,8 +1359,7 @@
     <string name="test_harness_mode_notification_message" msgid="1343197173054407119">"Извршете фабричко ресетирање за да го оневозможите режимот на рамка за тестирање."</string>
     <string name="usb_contaminant_detected_title" msgid="7136400633704058349">"Течност или нечистотија во USB-портата"</string>
     <string name="usb_contaminant_detected_message" msgid="832337061059487250">"USB-портата е автоматски оневозможена. Допрете за да дознаете повеќе."</string>
-    <!-- no translation found for usb_contaminant_not_detected_title (7708281124088684821) -->
-    <skip />
+    <string name="usb_contaminant_not_detected_title" msgid="7708281124088684821">"Во ред е да се користи USB-порта"</string>
     <string name="usb_contaminant_not_detected_message" msgid="2415791798244545292">"Телефонот веќе не открива течност или нечистотија."</string>
     <string name="taking_remote_bugreport_notification_title" msgid="6742483073875060934">"Се зема извештајот за грешки…"</string>
     <string name="share_remote_bugreport_notification_title" msgid="4987095013583691873">"Да се сподели извештајот за грешки?"</string>
@@ -1615,8 +1615,6 @@
     <string name="display_manager_overlay_display_name" msgid="5142365982271620716">"Прекривка #<xliff:g id="ID">%1$d</xliff:g>"</string>
     <string name="display_manager_overlay_display_title" msgid="652124517672257172">"<xliff:g id="NAME">%1$s</xliff:g> : <xliff:g id="WIDTH">%2$d</xliff:g>х<xliff:g id="HEIGHT">%3$d</xliff:g>, <xliff:g id="DPI">%4$d</xliff:g> dpi"</string>
     <string name="display_manager_overlay_display_secure_suffix" msgid="6022119702628572080">", безбедно"</string>
-    <string name="activity_starter_block_bg_activity_starts_permissive" msgid="6995473033438879646">"Ова стартување активност во заднина од <xliff:g id="PACKAGENAME">%1$s</xliff:g> ќе се блокира во идните верзии на Q. Видете g.co/dev/bgblock."</string>
-    <string name="activity_starter_block_bg_activity_starts_enforcing" msgid="3317816771072146229">"Блокирано е стартување активност во заднина од <xliff:g id="PACKAGENAME">%1$s</xliff:g>. Видете g.co/dev/bgblock."</string>
     <string name="kg_forgot_pattern_button_text" msgid="8852021467868220608">"Заборавив шема"</string>
     <string name="kg_wrong_pattern" msgid="1850806070801358830">"Погрешна шема"</string>
     <string name="kg_wrong_password" msgid="2333281762128113157">"Погрешна лозинка"</string>
@@ -1670,8 +1668,12 @@
     <string name="accessibility_shortcut_enabling_service" msgid="7771852911861522636">"Кратенката за пристапност ја вклучи <xliff:g id="SERVICE_NAME">%1$s</xliff:g>"</string>
     <string name="accessibility_shortcut_disabling_service" msgid="2747243438223109821">"Кратенката за пристапност ја исклучи <xliff:g id="SERVICE_NAME">%1$s</xliff:g>"</string>
     <string name="accessibility_shortcut_spoken_feedback" msgid="8376923232350078434">"Притиснете ги и задржете ги двете копчиња за јачина на звукот во траење од три секунди за да користите <xliff:g id="SERVICE_NAME">%1$s</xliff:g>"</string>
-    <string name="accessibility_button_prompt_text" msgid="4234556536456854251">"Изберете функција за користење кога ќе го допрете копчето за „Пристапност“."</string>
-    <string name="accessibility_button_instructional_text" msgid="6942300463612999993">"За променување функции, допрете го и задржете го копчето за „Пристапност“."</string>
+    <string name="accessibility_button_prompt_text" msgid="1176658502969738564">"Изберете ја услугата што ќе ја користите кога ќе го допрете копчето за пристапност:"</string>
+    <string name="accessibility_gesture_prompt_text" msgid="8259145549733019401">"Изберете ја услугата што ќе ја користите со движењето за пристапност (повлекување нагоре од дното на екранот со два прста):"</string>
+    <string name="accessibility_gesture_3finger_prompt_text" msgid="1041435574275047665">"Изберете ја услугата што ќе ја користите со движењето за пристапност (повлекување нагоре од дното на екранот со три прста):"</string>
+    <string name="accessibility_button_instructional_text" msgid="7003212763213614833">"За да се префрлате помеѓу услуги, допрете и задржете го копчето за пристапност."</string>
+    <string name="accessibility_gesture_instructional_text" msgid="5261788874937410950">"За да се префрлате помеѓу услуги, лизгајте нагоре со два прста и задржете."</string>
+    <string name="accessibility_gesture_3finger_instructional_text" msgid="4969448938984394550">"За да се префрлате помеѓу услуги, лизгајте нагоре со три прста и задржете."</string>
     <string name="accessibility_magnification_chooser_text" msgid="1227146738764986237">"Зголемување"</string>
     <string name="user_switched" msgid="3768006783166984410">"Тековен корисник <xliff:g id="NAME">%1$s</xliff:g>."</string>
     <string name="user_switching_message" msgid="2871009331809089783">"Се префрла на <xliff:g id="NAME">%1$s</xliff:g>…"</string>
diff --git a/core/res/res/values-ml/strings.xml b/core/res/res/values-ml/strings.xml
index 9503bf4..b3634df 100644
--- a/core/res/res/values-ml/strings.xml
+++ b/core/res/res/values-ml/strings.xml
@@ -131,6 +131,7 @@
     <!-- no translation found for wfcSpnFormat_spn (4998685024207291232) -->
     <skip />
     <string name="wfcSpnFormat_spn_wifi_calling" msgid="136001023263502280">"<xliff:g id="SPN">%s</xliff:g> വൈഫൈ കോളിംഗ്"</string>
+    <string name="wfcSpnFormat_spn_wifi_calling_vo_hyphen" msgid="1730997175789582756">"<xliff:g id="SPN">%s</xliff:g> വൈഫൈ കോളിംഗ്"</string>
     <string name="wfcSpnFormat_wlan_call" msgid="2533371081782489793">"WLAN കോൾ"</string>
     <string name="wfcSpnFormat_spn_wlan_call" msgid="2315240198303197168">"<xliff:g id="SPN">%s</xliff:g> WLAN കോൾ"</string>
     <string name="wfcSpnFormat_spn_wifi" msgid="6546481665561961938">"<xliff:g id="SPN">%s</xliff:g> വൈഫൈ"</string>
@@ -1358,8 +1359,7 @@
     <string name="test_harness_mode_notification_message" msgid="1343197173054407119">"പരിശോധനാ സംവിധാന മോഡ് പ്രവർത്തനരഹിതമാക്കാൻ ഫാക്‌ടറി പുനഃക്രമീകരണം നിർവഹിക്കുക."</string>
     <string name="usb_contaminant_detected_title" msgid="7136400633704058349">"USB പോർട്ടിൽ ദ്രാവകമോ പൊടിയോ കണ്ടെത്തി"</string>
     <string name="usb_contaminant_detected_message" msgid="832337061059487250">"USB പോർട്ടർ സ്വയമേവ പ്രവർത്തനരഹിതമായി. കൂടുതലറിയാൻ ടാപ്പ് ചെയ്യുക."</string>
-    <!-- no translation found for usb_contaminant_not_detected_title (7708281124088684821) -->
-    <skip />
+    <string name="usb_contaminant_not_detected_title" msgid="7708281124088684821">"ഇനി USB പോർട്ട് ഉപയോഗിക്കാം"</string>
     <string name="usb_contaminant_not_detected_message" msgid="2415791798244545292">"നിലവിൽ ദ്രാവകമോ പൊടിയോ ഉള്ളതായി ഫോൺ കണ്ടെത്തുന്നില്ല."</string>
     <string name="taking_remote_bugreport_notification_title" msgid="6742483073875060934">"ബഗ് റിപ്പോർട്ട് എടുക്കുന്നു…"</string>
     <string name="share_remote_bugreport_notification_title" msgid="4987095013583691873">"ബഗ് റിപ്പോർട്ട് പങ്കിടണോ?"</string>
@@ -1613,8 +1613,6 @@
     <string name="display_manager_overlay_display_name" msgid="5142365982271620716">"ഓവർലേ #<xliff:g id="ID">%1$d</xliff:g>"</string>
     <string name="display_manager_overlay_display_title" msgid="652124517672257172">"<xliff:g id="NAME">%1$s</xliff:g>: <xliff:g id="WIDTH">%2$d</xliff:g>x<xliff:g id="HEIGHT">%3$d</xliff:g>, <xliff:g id="DPI">%4$d</xliff:g> dpi"</string>
     <string name="display_manager_overlay_display_secure_suffix" msgid="6022119702628572080">", സുരക്ഷിതമാക്കുക"</string>
-    <string name="activity_starter_block_bg_activity_starts_permissive" msgid="6995473033438879646">"<xliff:g id="PACKAGENAME">%1$s</xliff:g> എന്നതിൽ നിന്ന് ഈ പശ്ചാത്തല ആക്റ്റിവിറ്റി ആരംഭിക്കുന്നത് ഭാവിയിലെ Q ബിൽഡുകളിൽ ബ്ലോക്ക് ചെയ്യപ്പെടും. g.co/dev/bgblock കാണുക."</string>
-    <string name="activity_starter_block_bg_activity_starts_enforcing" msgid="3317816771072146229">"<xliff:g id="PACKAGENAME">%1$s</xliff:g> എന്നതിൽ നിന്ന് പശ്ചാത്തല ആക്റ്റിവിറ്റി ആരംഭിക്കുന്നത് ബ്ലോക്ക് ചെയ്‌തു. g.co/dev/bgblock കാണുക."</string>
     <string name="kg_forgot_pattern_button_text" msgid="8852021467868220608">"പാറ്റേൺ മറന്നു"</string>
     <string name="kg_wrong_pattern" msgid="1850806070801358830">"പാറ്റേൺ തെറ്റാണ്"</string>
     <string name="kg_wrong_password" msgid="2333281762128113157">"പാസ്‌വേഡ് തെറ്റാണ്"</string>
@@ -1668,8 +1666,12 @@
     <string name="accessibility_shortcut_enabling_service" msgid="7771852911861522636">"ഉപയോഗസഹായിക്കുള്ള കുറുക്കുവഴി <xliff:g id="SERVICE_NAME">%1$s</xliff:g> ഓൺ ചെയ്തിരിക്കുന്നു"</string>
     <string name="accessibility_shortcut_disabling_service" msgid="2747243438223109821">"ഉപയോഗസഹായിക്കുള്ള കുറുക്കുവഴി <xliff:g id="SERVICE_NAME">%1$s</xliff:g> ഓഫ് ചെയ്തിരിക്കുന്നു"</string>
     <string name="accessibility_shortcut_spoken_feedback" msgid="8376923232350078434">"<xliff:g id="SERVICE_NAME">%1$s</xliff:g> ഉപയോഗിക്കാൻ, രണ്ട് വോളിയം കീകളും മൂന്ന് സെക്കൻഡ് അമർത്തിപ്പിടിക്കുക"</string>
-    <string name="accessibility_button_prompt_text" msgid="4234556536456854251">"നിങ്ങൾ ഉപയോഗസഹായി ബട്ടൺ ടാപ്പ് ചെയ്യുമ്പോൾ ഉപയോഗിക്കുന്നതിന് ഒരു ഫീച്ചർ തിരഞ്ഞെടുക്കുക:"</string>
-    <string name="accessibility_button_instructional_text" msgid="6942300463612999993">"ഫീച്ചറുകൾ മാറ്റുന്നതിന് ഉപയോഗസഹായി ബട്ടൺ സ്‌പർശിച്ചുപിടിക്കുക."</string>
+    <string name="accessibility_button_prompt_text" msgid="1176658502969738564">"നിങ്ങൾ ഉപയോഗസഹായി ബട്ടൺ ടാപ്പ് ചെയ്യുമ്പോൾ ഉപയോഗിക്കാൻ ഒരു ഫീച്ചർ തിരഞ്ഞെടുക്കുക:"</string>
+    <string name="accessibility_gesture_prompt_text" msgid="8259145549733019401">"ഉപയോഗസഹായി വിരൽചലനത്തോടൊപ്പം ഉപയോഗിക്കാൻ ഒരു സർവീസ് തിരഞ്ഞെടുക്കുക (രണ്ട് വിരലുകളുപയോഗിച്ച് സ്‌ക്രീനിന്റെ താഴെ നിന്ന് മുകളിലോട്ട് സ്വൈപ്പ് ചെയ്യുക):"</string>
+    <string name="accessibility_gesture_3finger_prompt_text" msgid="1041435574275047665">"ഉപയോഗസഹായി വിരൽചലനത്തോടൊപ്പം ഉപയോഗിക്കാൻ ഒരു സർവീസ് തിരഞ്ഞെടുക്കുക (മൂന്ന് വിരലുകളുപയോഗിച്ച് സ്‌ക്രീനിന്റെ താഴെ നിന്ന് മുകളിലോട്ട് സ്വൈപ്പ് ചെയ്യുക):"</string>
+    <string name="accessibility_button_instructional_text" msgid="7003212763213614833">"സർവീസുകൾക്കിടയിൽ മാറാൻ, ഉപയോഗസഹായി ബട്ടൺ സ്‌പർശിച്ചുപിടിക്കുക."</string>
+    <string name="accessibility_gesture_instructional_text" msgid="5261788874937410950">"സർവീസുകൾക്കിടയിൽ മാറാൻ, രണ്ട് വിരലുകളുപയോഗിച്ച് മുകളിലോട്ട് സ്വൈപ്പ് ചെയ്‌ത് പിടിക്കുക."</string>
+    <string name="accessibility_gesture_3finger_instructional_text" msgid="4969448938984394550">"സർവീസുകൾക്കിടയിൽ മാറാൻ, മൂന്ന് വിരലുകളുപയോഗിച്ച് മുകളിലോട്ട് സ്വൈപ്പ് ചെയ്‌ത് പിടിക്കുക."</string>
     <string name="accessibility_magnification_chooser_text" msgid="1227146738764986237">"മാഗ്നിഫിക്കേഷൻ"</string>
     <string name="user_switched" msgid="3768006783166984410">"നിലവിലെ ഉപയോക്താവ് <xliff:g id="NAME">%1$s</xliff:g> ആണ്."</string>
     <string name="user_switching_message" msgid="2871009331809089783">"<xliff:g id="NAME">%1$s</xliff:g> എന്ന ഉപയോക്താവിലേക്ക് മാറുന്നു…"</string>
diff --git a/core/res/res/values-mn/strings.xml b/core/res/res/values-mn/strings.xml
index 0711a80..0158076 100644
--- a/core/res/res/values-mn/strings.xml
+++ b/core/res/res/values-mn/strings.xml
@@ -131,6 +131,7 @@
     <!-- no translation found for wfcSpnFormat_spn (4998685024207291232) -->
     <skip />
     <string name="wfcSpnFormat_spn_wifi_calling" msgid="136001023263502280">"<xliff:g id="SPN">%s</xliff:g> Wi-Fi дуудлага"</string>
+    <string name="wfcSpnFormat_spn_wifi_calling_vo_hyphen" msgid="1730997175789582756">"<xliff:g id="SPN">%s</xliff:g> Wi-Fi Дуудлага"</string>
     <string name="wfcSpnFormat_wlan_call" msgid="2533371081782489793">"WLAN дуудлага"</string>
     <string name="wfcSpnFormat_spn_wlan_call" msgid="2315240198303197168">"<xliff:g id="SPN">%s</xliff:g> WLAN дуудлага"</string>
     <string name="wfcSpnFormat_spn_wifi" msgid="6546481665561961938">"<xliff:g id="SPN">%s</xliff:g> Wi-Fi"</string>
@@ -1357,8 +1358,7 @@
     <string name="test_harness_mode_notification_message" msgid="1343197173054407119">"Туршилтын цогц горимыг идэвхгүй болгохын тулд үйлдвэрийн төлөвт шинэчилнэ үү."</string>
     <string name="usb_contaminant_detected_title" msgid="7136400633704058349">"USB порт дээрх шингэн зүйл эсвэл бохирдол"</string>
     <string name="usb_contaminant_detected_message" msgid="832337061059487250">"USB портыг автоматаар идэвхгүй болгосон байна. Дэлгэрэнгүй мэдээлэл авахын тулд товшино уу."</string>
-    <!-- no translation found for usb_contaminant_not_detected_title (7708281124088684821) -->
-    <skip />
+    <string name="usb_contaminant_not_detected_title" msgid="7708281124088684821">"USB портыг ашиглахад зүгээр"</string>
     <string name="usb_contaminant_not_detected_message" msgid="2415791798244545292">"Утас шингэн зүйл эсвэл бохирдлыг илрүүлсэнгүй."</string>
     <string name="taking_remote_bugreport_notification_title" msgid="6742483073875060934">"Алдааны тайланг авч байна..."</string>
     <string name="share_remote_bugreport_notification_title" msgid="4987095013583691873">"Алдааны тайланг хуваалцах уу?"</string>
@@ -1612,8 +1612,6 @@
     <string name="display_manager_overlay_display_name" msgid="5142365982271620716">"Давхарга #<xliff:g id="ID">%1$d</xliff:g>"</string>
     <string name="display_manager_overlay_display_title" msgid="652124517672257172">"<xliff:g id="NAME">%1$s</xliff:g>: <xliff:g id="WIDTH">%2$d</xliff:g>x<xliff:g id="HEIGHT">%3$d</xliff:g>, <xliff:g id="DPI">%4$d</xliff:g> dpi"</string>
     <string name="display_manager_overlay_display_secure_suffix" msgid="6022119702628572080">", найдвартай"</string>
-    <string name="activity_starter_block_bg_activity_starts_permissive" msgid="6995473033438879646">"<xliff:g id="PACKAGENAME">%1$s</xliff:g>-с эхлэх арын энэ үйл ажиллагааг цаашдын Q боловсруулагдсан программд хориглоно. Та g.co/dev/bgblock холбоосыг харна уу."</string>
-    <string name="activity_starter_block_bg_activity_starts_enforcing" msgid="3317816771072146229">"<xliff:g id="PACKAGENAME">%1$s</xliff:g>-с эхлэх арын үйл ажиллагааг хориглосон. Та g.co/dev/bgblock холбоосыг харна уу."</string>
     <string name="kg_forgot_pattern_button_text" msgid="8852021467868220608">"Хээг мартсан"</string>
     <string name="kg_wrong_pattern" msgid="1850806070801358830">"Буруу хээ"</string>
     <string name="kg_wrong_password" msgid="2333281762128113157">"Нууц үг буруу"</string>
@@ -1667,8 +1665,12 @@
     <string name="accessibility_shortcut_enabling_service" msgid="7771852911861522636">"Хүртээмжийн товчлол <xliff:g id="SERVICE_NAME">%1$s</xliff:g>-г асаасан"</string>
     <string name="accessibility_shortcut_disabling_service" msgid="2747243438223109821">"Хүртээмжийн товчлол <xliff:g id="SERVICE_NAME">%1$s</xliff:g>-г унтраасан"</string>
     <string name="accessibility_shortcut_spoken_feedback" msgid="8376923232350078434">"<xliff:g id="SERVICE_NAME">%1$s</xliff:g>-г ашиглахын тулд дууны түвшнийг ихэсгэх, багасгах түлхүүрийг 3 секундийн турш зэрэг дарна уу"</string>
-    <string name="accessibility_button_prompt_text" msgid="4234556536456854251">"Хүртээмжийн товчлуурыг товших үедээ ашиглах онцлогийг сонгоно уу:"</string>
-    <string name="accessibility_button_instructional_text" msgid="6942300463612999993">"Онцлогийг өөрчлөхийн тулд Хүртээмжийн товчлуурыг дараад хүлээнэ үү."</string>
+    <string name="accessibility_button_prompt_text" msgid="1176658502969738564">"Хүртээмжийн товчлуурыг товшихдоо ашиглах үйлчилгээг сонгоно уу:"</string>
+    <string name="accessibility_gesture_prompt_text" msgid="8259145549733019401">"Хүртээмжийн зангаатай ашиглах үйлчилгээг сонгоно уу (хоёр хуруугаараа дэлгэцийн доороос дээш шударна уу):"</string>
+    <string name="accessibility_gesture_3finger_prompt_text" msgid="1041435574275047665">"Хүртээмжийн зангаатай ашиглах үйлчилгээг сонгоно уу (гурван хуруугаараа дэлгэцийн доороос дээш шударна уу):"</string>
+    <string name="accessibility_button_instructional_text" msgid="7003212763213614833">"Үйлчилгээнүүд хооронд сэлгэхийн тулд хүртээмжийн товчлуурт хүрээд удаан дарна уу."</string>
+    <string name="accessibility_gesture_instructional_text" msgid="5261788874937410950">"Үйлчилгээнүүд хооронд сэлгэхийн тулд хоёр хуруугаараа дээш шудраад удаан дарна уу."</string>
+    <string name="accessibility_gesture_3finger_instructional_text" msgid="4969448938984394550">"Үйлчилгээнүүд хооронд сэлгэхийн тулд гурван хуруугаараа дээш шудраад удаан дарна уу."</string>
     <string name="accessibility_magnification_chooser_text" msgid="1227146738764986237">"Томруулах"</string>
     <string name="user_switched" msgid="3768006783166984410">"Одоогийн хэрэглэгч <xliff:g id="NAME">%1$s</xliff:g>."</string>
     <string name="user_switching_message" msgid="2871009331809089783">"<xliff:g id="NAME">%1$s</xliff:g> руу сэлгэж байна…"</string>
diff --git a/core/res/res/values-mr/strings.xml b/core/res/res/values-mr/strings.xml
index 73c0b42..5125eb3 100644
--- a/core/res/res/values-mr/strings.xml
+++ b/core/res/res/values-mr/strings.xml
@@ -131,6 +131,7 @@
     <!-- no translation found for wfcSpnFormat_spn (4998685024207291232) -->
     <skip />
     <string name="wfcSpnFormat_spn_wifi_calling" msgid="136001023263502280">"<xliff:g id="SPN">%s</xliff:g> वाय-फाय कॉलिंग"</string>
+    <string name="wfcSpnFormat_spn_wifi_calling_vo_hyphen" msgid="1730997175789582756">"<xliff:g id="SPN">%s</xliff:g> वाय-फाय कॉलिंग"</string>
     <string name="wfcSpnFormat_wlan_call" msgid="2533371081782489793">"WLAN कॉल"</string>
     <string name="wfcSpnFormat_spn_wlan_call" msgid="2315240198303197168">"<xliff:g id="SPN">%s</xliff:g> WLAN कॉल"</string>
     <string name="wfcSpnFormat_spn_wifi" msgid="6546481665561961938">"<xliff:g id="SPN">%s</xliff:g> वाय-फाय"</string>
@@ -280,7 +281,7 @@
     <string name="permgrouprequest_contacts" msgid="6032805601881764300">"&lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; ला तुमचे संपर्क अॅक्सेस करू द्यायचे?"</string>
     <string name="permgrouplab_location" msgid="7275582855722310164">"स्थान"</string>
     <string name="permgroupdesc_location" msgid="1346617465127855033">"या डिव्हाइसच्या स्थानावर प्रवेश"</string>
-    <string name="permgrouprequest_location" msgid="3788275734953323491">"&lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; ला या डिव्हाइसचे स्थान अॅक्सेस करू द्यायचे?"</string>
+    <string name="permgrouprequest_location" msgid="3788275734953323491">"&lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; ला या डिव्हाइसचे स्थान अ‍ॅक्सेस करू द्यायचे?"</string>
     <string name="permgrouprequestdetail_location" msgid="1347189607421252902">"तुम्ही अ‍ॅप वापरत असताना अ‍ॅपला फक्त स्थानाचा अॅक्सेस असेल"</string>
     <string name="permgroupbackgroundrequest_location" msgid="5039063878675613235">"&lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; ला &lt;b&gt;प्रत्येक वेळी&lt;/b&gt; या डिव्हाइसच्या स्थानाचा अ‍ॅक्सेस द्यायचा?"</string>
     <string name="permgroupbackgroundrequestdetail_location" msgid="4597006851453417387">"अ‍ॅप सध्या फक्त तुम्ही अ‍ॅप वापरत असतानाच स्थान अ‍ॅक्सेस करू शकते"</string>
@@ -1358,8 +1359,7 @@
     <string name="test_harness_mode_notification_message" msgid="1343197173054407119">"टेस्ट हार्नेस मोड बंद करण्यासाठी फॅक्टरी रीसेट करा."</string>
     <string name="usb_contaminant_detected_title" msgid="7136400633704058349">"USB पोर्ट मध्ये ओलावा किंवा धूळ आहे"</string>
     <string name="usb_contaminant_detected_message" msgid="832337061059487250">"USB पोर्ट आपोआप बंद होईल. अधिक जाणून घेण्यासाठी टॅप करा."</string>
-    <!-- no translation found for usb_contaminant_not_detected_title (7708281124088684821) -->
-    <skip />
+    <string name="usb_contaminant_not_detected_title" msgid="7708281124088684821">"USB पोर्ट वापरण्यासाठी ठीक आहे"</string>
     <string name="usb_contaminant_not_detected_message" msgid="2415791798244545292">"फोनला धूळ किंवा ओलावा आढळला नाही."</string>
     <string name="taking_remote_bugreport_notification_title" msgid="6742483073875060934">"बग रीपोर्ट घेत आहे..."</string>
     <string name="share_remote_bugreport_notification_title" msgid="4987095013583691873">"बग अहवाल शेअर करायचा?"</string>
@@ -1613,8 +1613,6 @@
     <string name="display_manager_overlay_display_name" msgid="5142365982271620716">"ओव्हरले #<xliff:g id="ID">%1$d</xliff:g>"</string>
     <string name="display_manager_overlay_display_title" msgid="652124517672257172">"<xliff:g id="NAME">%1$s</xliff:g>: <xliff:g id="WIDTH">%2$d</xliff:g>x<xliff:g id="HEIGHT">%3$d</xliff:g>, <xliff:g id="DPI">%4$d</xliff:g> dpi"</string>
     <string name="display_manager_overlay_display_secure_suffix" msgid="6022119702628572080">", सुरक्षित"</string>
-    <string name="activity_starter_block_bg_activity_starts_permissive" msgid="6995473033438879646">"<xliff:g id="PACKAGENAME">%1$s</xliff:g> पासून सुरू होणारी ही बॅकग्राउंड अ‍ॅक्टिव्हिटी भविष्यातील Q बिल्डमध्ये ब्लॉक केली जाईल. g.co/dev/bgblock पाहा."</string>
-    <string name="activity_starter_block_bg_activity_starts_enforcing" msgid="3317816771072146229">"<xliff:g id="PACKAGENAME">%1$s</xliff:g> वरून सुरू होणारी बॅकग्राउंड अ‍ॅक्टिव्हिटी ब्लॉक केली आहे. g.co/dev/bgblock पाहा."</string>
     <string name="kg_forgot_pattern_button_text" msgid="8852021467868220608">"पॅटर्न विसरलात"</string>
     <string name="kg_wrong_pattern" msgid="1850806070801358830">"चुकीचा पॅटर्न"</string>
     <string name="kg_wrong_password" msgid="2333281762128113157">"चुकीचा पासवर्ड"</string>
@@ -1668,8 +1666,12 @@
     <string name="accessibility_shortcut_enabling_service" msgid="7771852911861522636">"प्रवेशयोग्यता शॉर्टकटने <xliff:g id="SERVICE_NAME">%1$s</xliff:g> चालू केली"</string>
     <string name="accessibility_shortcut_disabling_service" msgid="2747243438223109821">"प्रवेशयोग्यता शॉर्टकटने <xliff:g id="SERVICE_NAME">%1$s</xliff:g> बंद केली"</string>
     <string name="accessibility_shortcut_spoken_feedback" msgid="8376923232350078434">"<xliff:g id="SERVICE_NAME">%1$s</xliff:g> वापरण्यासाठी दोन्ही व्हॉल्युम की तीन सेकंद दाबा आणि धरून ठेवा"</string>
-    <string name="accessibility_button_prompt_text" msgid="4234556536456854251">"तुम्ही प्रवेशयोग्यता बटण दाबल्यावर वापरण्यासाठी वैशिष्ट्य निवडा:"</string>
-    <string name="accessibility_button_instructional_text" msgid="6942300463612999993">"वैशिष्ट्ये बदलण्यासाठी, प्रवेशयोग्यता बटणाला स्पर्श करा आणि धरून ठेवा."</string>
+    <string name="accessibility_button_prompt_text" msgid="1176658502969738564">"तुम्ही अ‍ॅक्सेसिबिलिटी बटण दाबल्यावर वापरण्यासाठी वैशिष्ट्य निवडा:"</string>
+    <string name="accessibility_gesture_prompt_text" msgid="8259145549733019401">"अ‍ॅक्सेसिबिलिटी जेश्चर ज्या सोबत वापराचे आहे अशी सेवा निवडा (स्क्रीनच्या खालच्या बाजूने दोन बोटांनी स्वाइप करा):"</string>
+    <string name="accessibility_gesture_3finger_prompt_text" msgid="1041435574275047665">"अ‍ॅक्सेसिबिलिटी जेश्चर ज्या सोबत वापराचे आहे अशी सेवा निवडा (स्क्रीनच्या खालच्या बाजूने तीन बोटांनी स्वाइप करा):"</string>
+    <string name="accessibility_button_instructional_text" msgid="7003212763213614833">"सेवांदरम्यान स्विच करण्यासाठी, अ‍ॅक्सेसिबिलिटी बटणाला स्पर्श करा आणि धरून ठेवा."</string>
+    <string name="accessibility_gesture_instructional_text" msgid="5261788874937410950">"सेवांदरम्यान स्विच करण्यासाठी, दोन बोटांनी वरच्या दिशेला स्वाइप करा आणि धरून ठेवा."</string>
+    <string name="accessibility_gesture_3finger_instructional_text" msgid="4969448938984394550">"सेवांदरम्यान स्विच करण्यासाठी, तीन बोटांनी वरच्या दिशेला स्वाइप करा आणि धरून ठेवा."</string>
     <string name="accessibility_magnification_chooser_text" msgid="1227146738764986237">"मोठे करणे"</string>
     <string name="user_switched" msgid="3768006783166984410">"वर्तमान वापरकर्ता <xliff:g id="NAME">%1$s</xliff:g>."</string>
     <string name="user_switching_message" msgid="2871009331809089783">"<xliff:g id="NAME">%1$s</xliff:g> वर स्विच करत आहे…"</string>
@@ -1851,7 +1853,7 @@
     <string name="zen_mode_default_weeknights_name" msgid="3081318299464998143">"आठवड्याची शेवटची रात्र"</string>
     <string name="zen_mode_default_weekends_name" msgid="2786495801019345244">"आठवड्याच्या शेवटी"</string>
     <string name="zen_mode_default_events_name" msgid="8158334939013085363">"इव्‍हेंट"</string>
-    <string name="zen_mode_default_every_night_name" msgid="3012363838882944175">"निष्क्रिय आहे"</string>
+    <string name="zen_mode_default_every_night_name" msgid="3012363838882944175">"झोपताना"</string>
     <string name="muted_by" msgid="5942954724562097128">"<xliff:g id="THIRD_PARTY">%1$s</xliff:g> काही ध्‍वनी म्‍यूट करत आहे"</string>
     <string name="system_error_wipe_data" msgid="6608165524785354962">"आपल्‍या डिव्‍हाइसमध्‍ये अंतर्गत समस्‍या आहे आणि तुमचा फॅक्‍टरी डेटा रीसेट होईपर्यंत ती अस्‍थिर असू शकते."</string>
     <string name="system_error_manufacturer" msgid="8086872414744210668">"आपल्‍या डिव्‍हाइसमध्‍ये अंतर्गत समस्‍या आहे. तपशीलांसाठी आपल्‍या निर्मात्याशी संपर्क साधा."</string>
diff --git a/core/res/res/values-ms/strings.xml b/core/res/res/values-ms/strings.xml
index 5edfc63..73f8c40 100644
--- a/core/res/res/values-ms/strings.xml
+++ b/core/res/res/values-ms/strings.xml
@@ -131,6 +131,7 @@
     <!-- no translation found for wfcSpnFormat_spn (4998685024207291232) -->
     <skip />
     <string name="wfcSpnFormat_spn_wifi_calling" msgid="136001023263502280">"Panggilan Wi-Fi <xliff:g id="SPN">%s</xliff:g>"</string>
+    <string name="wfcSpnFormat_spn_wifi_calling_vo_hyphen" msgid="1730997175789582756">"Panggilan Wi-Fi <xliff:g id="SPN">%s</xliff:g>"</string>
     <string name="wfcSpnFormat_wlan_call" msgid="2533371081782489793">"Panggilan WLAN"</string>
     <string name="wfcSpnFormat_spn_wlan_call" msgid="2315240198303197168">"Panggilan WLAN <xliff:g id="SPN">%s</xliff:g>"</string>
     <string name="wfcSpnFormat_spn_wifi" msgid="6546481665561961938">"Wi-Fi <xliff:g id="SPN">%s</xliff:g>"</string>
@@ -1357,8 +1358,7 @@
     <string name="test_harness_mode_notification_message" msgid="1343197173054407119">"Laksanakan tetapan semula kilang untuk melumpuhkan Mod Abah-abah Ujian."</string>
     <string name="usb_contaminant_detected_title" msgid="7136400633704058349">"Cecair atau serpihan dalam port USB"</string>
     <string name="usb_contaminant_detected_message" msgid="832337061059487250">"Port USB dilumpuhkan secara automatik. Ketik untuk mengetahui lebih lanjut."</string>
-    <!-- no translation found for usb_contaminant_not_detected_title (7708281124088684821) -->
-    <skip />
+    <string name="usb_contaminant_not_detected_title" msgid="7708281124088684821">"OK untuk menggunakan port USB"</string>
     <string name="usb_contaminant_not_detected_message" msgid="2415791798244545292">"Telefon tidak lagi mengesan cecair atau serpihan."</string>
     <string name="taking_remote_bugreport_notification_title" msgid="6742483073875060934">"Mengambil laporan pepijat…"</string>
     <string name="share_remote_bugreport_notification_title" msgid="4987095013583691873">"Kongsi laporan pepijat?"</string>
@@ -1612,8 +1612,6 @@
     <string name="display_manager_overlay_display_name" msgid="5142365982271620716">"Tindih #<xliff:g id="ID">%1$d</xliff:g>"</string>
     <string name="display_manager_overlay_display_title" msgid="652124517672257172">"<xliff:g id="NAME">%1$s</xliff:g>: <xliff:g id="WIDTH">%2$d</xliff:g>x<xliff:g id="HEIGHT">%3$d</xliff:g>, <xliff:g id="DPI">%4$d</xliff:g> dpi"</string>
     <string name="display_manager_overlay_display_secure_suffix" msgid="6022119702628572080">", selamat"</string>
-    <string name="activity_starter_block_bg_activity_starts_permissive" msgid="6995473033438879646">"Permulaan aktiviti latar belakang daripada <xliff:g id="PACKAGENAME">%1$s</xliff:g> ini akan disekat dalam binaan Q pada masa hadapan. Lihat g.co/dev/bgblock."</string>
-    <string name="activity_starter_block_bg_activity_starts_enforcing" msgid="3317816771072146229">"Permulaan aktiviti latar belakang daripada <xliff:g id="PACKAGENAME">%1$s</xliff:g> disekat. Lihat g.co/dev/bgblock."</string>
     <string name="kg_forgot_pattern_button_text" msgid="8852021467868220608">"Lupa Corak"</string>
     <string name="kg_wrong_pattern" msgid="1850806070801358830">"Corak Salah"</string>
     <string name="kg_wrong_password" msgid="2333281762128113157">"Kata Laluan Salah"</string>
@@ -1667,8 +1665,12 @@
     <string name="accessibility_shortcut_enabling_service" msgid="7771852911861522636">"Pintasan kebolehaksesan menghidupkan <xliff:g id="SERVICE_NAME">%1$s</xliff:g>"</string>
     <string name="accessibility_shortcut_disabling_service" msgid="2747243438223109821">"Pintasan Kebolehaksesan mematikan <xliff:g id="SERVICE_NAME">%1$s</xliff:g>"</string>
     <string name="accessibility_shortcut_spoken_feedback" msgid="8376923232350078434">"Tekan dan tahan kedua-dua kekunci kelantangan selama tiga saat untuk menggunakan <xliff:g id="SERVICE_NAME">%1$s</xliff:g>"</string>
-    <string name="accessibility_button_prompt_text" msgid="4234556536456854251">"Pilih ciri yang hendak digunakan apabila anda mengetik butang Kebolehaksesan:"</string>
-    <string name="accessibility_button_instructional_text" msgid="6942300463612999993">"Untuk menukar ciri, sentuh &amp; tahan butang Kebolehaksesan."</string>
+    <string name="accessibility_button_prompt_text" msgid="1176658502969738564">"Pilih perkhidmatan yang hendak digunakan apabila anda mengetik butang kebolehaksesan:"</string>
+    <string name="accessibility_gesture_prompt_text" msgid="8259145549733019401">"Pilih perkhidmatan untuk digunakan dengan gerak isyarat kebolehaksesan (leret ke atas dari bahagian bawah skrin menggunakan dua jari):"</string>
+    <string name="accessibility_gesture_3finger_prompt_text" msgid="1041435574275047665">"Pilih perkhidmatan untuk digunakan dengan gerak isyarat kebolehaksesan (leret ke atas dari bahagian bawah skrin menggunakan tiga jari):"</string>
+    <string name="accessibility_button_instructional_text" msgid="7003212763213614833">"Untuk beralih antara perkhidmatan, sentuh &amp; tahan butang kebolehaksesan."</string>
+    <string name="accessibility_gesture_instructional_text" msgid="5261788874937410950">"Untuk beralih antara perkhidmatan, leret ke atas menggunakan dua jari dan tahan."</string>
+    <string name="accessibility_gesture_3finger_instructional_text" msgid="4969448938984394550">"Untuk beralih antara perkhidmatan, leret ke atas menggunakan tiga jari dan tahan."</string>
     <string name="accessibility_magnification_chooser_text" msgid="1227146738764986237">"Pembesaran"</string>
     <string name="user_switched" msgid="3768006783166984410">"Pengguna semasa <xliff:g id="NAME">%1$s</xliff:g>."</string>
     <string name="user_switching_message" msgid="2871009331809089783">"Bertukar kepada <xliff:g id="NAME">%1$s</xliff:g>…"</string>
diff --git a/core/res/res/values-my/strings.xml b/core/res/res/values-my/strings.xml
index 50b3372..b760e28 100644
--- a/core/res/res/values-my/strings.xml
+++ b/core/res/res/values-my/strings.xml
@@ -131,6 +131,7 @@
     <!-- no translation found for wfcSpnFormat_spn (4998685024207291232) -->
     <skip />
     <string name="wfcSpnFormat_spn_wifi_calling" msgid="136001023263502280">"<xliff:g id="SPN">%s</xliff:g> Wi-Fi ခေါ်ဆိုမှု"</string>
+    <string name="wfcSpnFormat_spn_wifi_calling_vo_hyphen" msgid="1730997175789582756">"<xliff:g id="SPN">%s</xliff:g>Wi-Fi ခေါ်ဆိုမှု"</string>
     <string name="wfcSpnFormat_wlan_call" msgid="2533371081782489793">"WLAN ခေါ်ဆိုမှု"</string>
     <string name="wfcSpnFormat_spn_wlan_call" msgid="2315240198303197168">"<xliff:g id="SPN">%s</xliff:g> WLAN ခေါ်ဆိုမှု"</string>
     <string name="wfcSpnFormat_spn_wifi" msgid="6546481665561961938">"<xliff:g id="SPN">%s</xliff:g> Wi-Fi"</string>
@@ -1494,7 +1495,7 @@
     <string name="find_next" msgid="5742124618942193978">"နောက်တစ်ခု ရှာဖွေရန်"</string>
     <string name="find_previous" msgid="2196723669388360506">"အရင်တစ်ခု ရှာဖွေရန်"</string>
     <string name="gpsNotifTicker" msgid="5622683912616496172">"<xliff:g id="NAME">%s</xliff:g>မှ တည်နေရာအား တောင်းခံသည်"</string>
-    <string name="gpsNotifTitle" msgid="5446858717157416839">"တည်နေရာအား တောင်းခံသည်"</string>
+    <string name="gpsNotifTitle" msgid="5446858717157416839">"တည်နေရာ တောင်းခံခြင်း"</string>
     <string name="gpsNotifMessage" msgid="1374718023224000702">"<xliff:g id="NAME">%1$s</xliff:g> (<xliff:g id="SERVICE">%2$s</xliff:g>)မှတောင်းခံသည်"</string>
     <string name="gpsVerifYes" msgid="2346566072867213563">"Yes"</string>
     <string name="gpsVerifNo" msgid="1146564937346454865">"No"</string>
@@ -1612,8 +1613,6 @@
     <string name="display_manager_overlay_display_name" msgid="5142365982271620716">"အပေါ်မှ ထပ်သောအရာ #<xliff:g id="ID">%1$d</xliff:g>"</string>
     <string name="display_manager_overlay_display_title" msgid="652124517672257172">"<xliff:g id="NAME">%1$s</xliff:g>: <xliff:g id="WIDTH">%2$d</xliff:g>x<xliff:g id="HEIGHT">%3$d</xliff:g>, <xliff:g id="DPI">%4$d</xliff:g>  dpi"</string>
     <string name="display_manager_overlay_display_secure_suffix" msgid="6022119702628572080">", လုံခြုံသော"</string>
-    <string name="activity_starter_block_bg_activity_starts_permissive" msgid="6995473033438879646">"<xliff:g id="PACKAGENAME">%1$s</xliff:g> မှစတင်သော ဤနောက်ခံလုပ်ဆောင်ချက်ကို အနာဂတ် Q တည်ဆောက်ပုံများတွင် ပိတ်ထားပါမည်။ g.co/dev/bgblock ကိုကြည့်ပါ။"</string>
-    <string name="activity_starter_block_bg_activity_starts_enforcing" msgid="3317816771072146229">"<xliff:g id="PACKAGENAME">%1$s</xliff:g> မှစတင်သော နောက်ခံလုပ်ဆောင်ချက်ကို ပိတ်ထားသည်။ g.co/dev/bgblock ကိုကြည့်ပါ။"</string>
     <string name="kg_forgot_pattern_button_text" msgid="8852021467868220608">"ပုံဖော်မှုအား မေ့လျော့ခြင်း"</string>
     <string name="kg_wrong_pattern" msgid="1850806070801358830">"ပုံဆွဲအမှား"</string>
     <string name="kg_wrong_password" msgid="2333281762128113157">"စကားဝှက်အမှား"</string>
@@ -1667,8 +1666,12 @@
     <string name="accessibility_shortcut_enabling_service" msgid="7771852911861522636">"အများသုံးစွဲနိုင်မှု ဖြတ်လမ်းလင့်ခ်သည် <xliff:g id="SERVICE_NAME">%1$s</xliff:g> ကို ဖွင့်လိုက်ပါသည်"</string>
     <string name="accessibility_shortcut_disabling_service" msgid="2747243438223109821">"အများသုံးစွဲနိုင်မှု ဖြတ်လမ်းလင့်ခ်သည် <xliff:g id="SERVICE_NAME">%1$s</xliff:g> ကို ပိတ်လိုက်ပါသည်"</string>
     <string name="accessibility_shortcut_spoken_feedback" msgid="8376923232350078434">"<xliff:g id="SERVICE_NAME">%1$s</xliff:g> ကို သုံးရန် အသံအတိုးအလျှော့ ခလုတ်နှစ်ခုလုံးကို သုံးစက္ကန့်ကြာ ဖိထားပါ"</string>
-    <string name="accessibility_button_prompt_text" msgid="4234556536456854251">"အများသုံးစွဲနိုင်မှု ခလုတ်ကို တို့သည့်အခါ အသုံးပြုမည့် ဝန်ဆောင်မှုကို ရွေးချယ်ပါ−"</string>
-    <string name="accessibility_button_instructional_text" msgid="6942300463612999993">"ဝန်ဆောင်မှုများကို ပြောင်းလဲရန် အများသုံးစွဲနိုင်မှု ခလုတ်ကို တို့၍ ထိထားပါ။"</string>
+    <string name="accessibility_button_prompt_text" msgid="1176658502969738564">"အများသုံးစွဲနိုင်မှု ခလုတ်ကို တို့သည့်အခါ အသုံးပြုမည့် ဝန်ဆောင်မှုကို ရွေးချယ်ပါ−"</string>
+    <string name="accessibility_gesture_prompt_text" msgid="8259145549733019401">"အများသုံးစွဲနိုင်မှုလက်ဟန်ဖြင့် အသုံးပြုရန် ဝန်ဆောင်မှုတစ်ခုကို ရွေးပါ (မျက်နှာပြင်အောက်ခြေမှနေ၍ လက်နှစ်ချောင်းဖြင့် အပေါ်သို့ ပွတ်ဆွဲပါ)-"</string>
+    <string name="accessibility_gesture_3finger_prompt_text" msgid="1041435574275047665">"အများသုံးစွဲနိုင်မှုလက်ဟန်ဖြင့် အသုံးပြုရန် ဝန်ဆောင်မှုတစ်ခုကို ရွေးပါ (မျက်နှာပြင်အောက်ခြေမှနေ၍ လက်သုံးချောင်းဖြင့် အပေါ်သို့ ပွတ်ဆွဲပါ)-"</string>
+    <string name="accessibility_button_instructional_text" msgid="7003212763213614833">"ဝန်ဆောင်မှုများအကြား ပြောင်းရန် အများသုံးစွဲနိုင်မှုခလုတ်ကို ဖိထားပါ။"</string>
+    <string name="accessibility_gesture_instructional_text" msgid="5261788874937410950">"ဝန်ဆောင်မှုများအကြား ပြောင်းရန် လက်နှစ်ချောင်းဖြင့် အပေါ်သို့ ပွတ်ဆွဲပြီး ဖိထားပါ။"</string>
+    <string name="accessibility_gesture_3finger_instructional_text" msgid="4969448938984394550">"ဝန်ဆောင်မှုများအကြား ပြောင်းရန် လက်သုံးချေင်းဖြင့် အပေါ်သို့ ပွတ်ဆွဲပြီး ဖိထားပါ။"</string>
     <string name="accessibility_magnification_chooser_text" msgid="1227146738764986237">"ချဲ့ခြင်း"</string>
     <string name="user_switched" msgid="3768006783166984410">"လက်ရှိအသုံးပြုနေသူ <xliff:g id="NAME">%1$s</xliff:g>."</string>
     <string name="user_switching_message" msgid="2871009331809089783">"<xliff:g id="NAME">%1$s</xliff:g>သို့ ပြောင်းနေ…"</string>
@@ -1888,7 +1891,7 @@
     <string name="country_selection_title" msgid="2954859441620215513">"ဒေသရွေးချယ်မှု"</string>
     <string name="search_language_hint" msgid="7042102592055108574">"ဘာသာစကားအမည် ထည့်ပါ"</string>
     <string name="language_picker_section_suggested" msgid="8414489646861640885">"အကြံပြုထားသည်"</string>
-    <string name="language_picker_section_all" msgid="3097279199511617537">"ဘာသာစကားများအားလုံး"</string>
+    <string name="language_picker_section_all" msgid="3097279199511617537">"ဘာသာစကားအားလုံး"</string>
     <string name="region_picker_section_all" msgid="8966316787153001779">"ဒေသအားလုံး"</string>
     <string name="locale_search_menu" msgid="2560710726687249178">"ရှာဖွေရန်"</string>
     <string name="app_suspended_title" msgid="2075071241147969611">"အက်ပ်ကို မရရှိနိုင်ပါ"</string>
diff --git a/core/res/res/values-nb/strings.xml b/core/res/res/values-nb/strings.xml
index 58c032b..7923d81 100644
--- a/core/res/res/values-nb/strings.xml
+++ b/core/res/res/values-nb/strings.xml
@@ -131,6 +131,7 @@
     <!-- no translation found for wfcSpnFormat_spn (4998685024207291232) -->
     <skip />
     <string name="wfcSpnFormat_spn_wifi_calling" msgid="136001023263502280">"<xliff:g id="SPN">%s</xliff:g> Wi-Fi-anrop"</string>
+    <string name="wfcSpnFormat_spn_wifi_calling_vo_hyphen" msgid="1730997175789582756">"<xliff:g id="SPN">%s</xliff:g>-Wi-Fi-anrop"</string>
     <string name="wfcSpnFormat_wlan_call" msgid="2533371081782489793">"WLAN-anrop"</string>
     <string name="wfcSpnFormat_spn_wlan_call" msgid="2315240198303197168">"<xliff:g id="SPN">%s</xliff:g> WLAN-anrop"</string>
     <string name="wfcSpnFormat_spn_wifi" msgid="6546481665561961938">"<xliff:g id="SPN">%s</xliff:g> Wi-Fi"</string>
@@ -1357,8 +1358,7 @@
     <string name="test_harness_mode_notification_message" msgid="1343197173054407119">"Tilbakestill enheten til fabrikkstandard for å slå av Testrammeverk-modus."</string>
     <string name="usb_contaminant_detected_title" msgid="7136400633704058349">"Væske eller rusk i USB-porten"</string>
     <string name="usb_contaminant_detected_message" msgid="832337061059487250">"USB-porten deaktiveres automatisk. Trykk for å finne ut mer."</string>
-    <!-- no translation found for usb_contaminant_not_detected_title (7708281124088684821) -->
-    <skip />
+    <string name="usb_contaminant_not_detected_title" msgid="7708281124088684821">"Trygt å bruke USB-porten"</string>
     <string name="usb_contaminant_not_detected_message" msgid="2415791798244545292">"Telefonen oppdager ikke væsker eller rusk lenger."</string>
     <string name="taking_remote_bugreport_notification_title" msgid="6742483073875060934">"Kjører feilrapport …"</string>
     <string name="share_remote_bugreport_notification_title" msgid="4987095013583691873">"Vil du dele feilrapporten?"</string>
@@ -1612,8 +1612,6 @@
     <string name="display_manager_overlay_display_name" msgid="5142365982271620716">"Overlegg #<xliff:g id="ID">%1$d</xliff:g>"</string>
     <string name="display_manager_overlay_display_title" msgid="652124517672257172">"<xliff:g id="NAME">%1$s</xliff:g>: <xliff:g id="WIDTH">%2$d</xliff:g> x <xliff:g id="HEIGHT">%3$d</xliff:g>, <xliff:g id="DPI">%4$d</xliff:g> dpi"</string>
     <string name="display_manager_overlay_display_secure_suffix" msgid="6022119702628572080">", sikker"</string>
-    <string name="activity_starter_block_bg_activity_starts_permissive" msgid="6995473033438879646">"Denne bakgrunnsaktiviteten som starter fra <xliff:g id="PACKAGENAME">%1$s</xliff:g>, blir blokkert i fremtidige Q-delversjoner. Se g.co/dev/bgblock."</string>
-    <string name="activity_starter_block_bg_activity_starts_enforcing" msgid="3317816771072146229">"Bakgrunnsaktivitet som starter fra <xliff:g id="PACKAGENAME">%1$s</xliff:g>, er blokkert. Se g.co/dev/bgblock."</string>
     <string name="kg_forgot_pattern_button_text" msgid="8852021467868220608">"Har du glemt mønsteret?"</string>
     <string name="kg_wrong_pattern" msgid="1850806070801358830">"Feil mønster"</string>
     <string name="kg_wrong_password" msgid="2333281762128113157">"Feil passord"</string>
@@ -1667,8 +1665,12 @@
     <string name="accessibility_shortcut_enabling_service" msgid="7771852911861522636">"Snarveien for tilgjengelighet slo på <xliff:g id="SERVICE_NAME">%1$s</xliff:g>"</string>
     <string name="accessibility_shortcut_disabling_service" msgid="2747243438223109821">"Snarveien for tilgjengelighet slo av <xliff:g id="SERVICE_NAME">%1$s</xliff:g>"</string>
     <string name="accessibility_shortcut_spoken_feedback" msgid="8376923232350078434">"Trykk og hold inne begge volumtastene i tre sekunder for å bruke <xliff:g id="SERVICE_NAME">%1$s</xliff:g>"</string>
-    <string name="accessibility_button_prompt_text" msgid="4234556536456854251">"Velg en funksjon du vil bruke når du trykker på Tilgjengelighet-knappen:"</string>
-    <string name="accessibility_button_instructional_text" msgid="6942300463612999993">"For å endre funksjoner, trykk på og hold inne Tilgjengelighet-knappen."</string>
+    <string name="accessibility_button_prompt_text" msgid="1176658502969738564">"Velg en tjeneste du vil bruke når du trykker på Tilgjengelighet-knappen:"</string>
+    <string name="accessibility_gesture_prompt_text" msgid="8259145549733019401">"Velg en tjeneste du vil bruke med tilgjengelighetsbevegelsen (sveip opp fra bunnen av skjermen med to fingre):"</string>
+    <string name="accessibility_gesture_3finger_prompt_text" msgid="1041435574275047665">"Velg en tjeneste du vil bruke med tilgjengelighetsbevegelsen (sveip opp fra bunnen av skjermen med tre fingre):"</string>
+    <string name="accessibility_button_instructional_text" msgid="7003212763213614833">"For å bytte mellom tjenester, trykk og hold på Tilgjengelighet-knappen."</string>
+    <string name="accessibility_gesture_instructional_text" msgid="5261788874937410950">"For å bytte mellom tjenester, sveip opp med to fingre og hold."</string>
+    <string name="accessibility_gesture_3finger_instructional_text" msgid="4969448938984394550">"For å bytte mellom tjenester, sveip opp med tre fingre og hold."</string>
     <string name="accessibility_magnification_chooser_text" msgid="1227146738764986237">"Forstørring"</string>
     <string name="user_switched" msgid="3768006783166984410">"Gjeldende bruker: <xliff:g id="NAME">%1$s</xliff:g>."</string>
     <string name="user_switching_message" msgid="2871009331809089783">"Bytter til <xliff:g id="NAME">%1$s</xliff:g> …"</string>
@@ -1898,7 +1900,7 @@
     <string name="work_mode_off_message" msgid="5130856710614337649">"Jobbappene dine samt varsler, data og andre funksjoner i jobbprofilen din blir slått på"</string>
     <string name="work_mode_turn_on" msgid="2062544985670564875">"Slå på"</string>
     <string name="deprecated_target_sdk_message" msgid="1449696506742572767">"Denne appen er utviklet for en eldre versjon av Android og fungerer kanskje ikke som den skal. Prøv å se etter oppdateringer, eller kontakt utvikleren."</string>
-    <string name="deprecated_target_sdk_app_store" msgid="5032340500368495077">"Se etter oppdatering"</string>
+    <string name="deprecated_target_sdk_app_store" msgid="5032340500368495077">"Se etter oppdateringer"</string>
     <string name="new_sms_notification_title" msgid="8442817549127555977">"Du har nye meldinger"</string>
     <string name="new_sms_notification_content" msgid="7002938807812083463">"Åpne SMS-appen for å se"</string>
     <string name="profile_encrypted_title" msgid="4260432497586829134">"Enkelte funksjoner kan begrenses"</string>
diff --git a/core/res/res/values-ne/strings.xml b/core/res/res/values-ne/strings.xml
index 534752a..b8649ae 100644
--- a/core/res/res/values-ne/strings.xml
+++ b/core/res/res/values-ne/strings.xml
@@ -131,6 +131,7 @@
     <!-- no translation found for wfcSpnFormat_spn (4998685024207291232) -->
     <skip />
     <string name="wfcSpnFormat_spn_wifi_calling" msgid="136001023263502280">"<xliff:g id="SPN">%s</xliff:g> Wi-Fi कलिङ"</string>
+    <string name="wfcSpnFormat_spn_wifi_calling_vo_hyphen" msgid="1730997175789582756">"<xliff:g id="SPN">%s</xliff:g> Wi-Fi कलिङ"</string>
     <string name="wfcSpnFormat_wlan_call" msgid="2533371081782489793">"WLAN कल"</string>
     <string name="wfcSpnFormat_spn_wlan_call" msgid="2315240198303197168">"<xliff:g id="SPN">%s</xliff:g> WLAN कल"</string>
     <string name="wfcSpnFormat_spn_wifi" msgid="6546481665561961938">"<xliff:g id="SPN">%s</xliff:g> Wi-Fi"</string>
@@ -1363,8 +1364,7 @@
     <string name="test_harness_mode_notification_message" msgid="1343197173054407119">"परीक्षण प्याकेज मोड असक्षम पार्न फ्याक्ट्री रिसेट गर्नुहोस्।"</string>
     <string name="usb_contaminant_detected_title" msgid="7136400633704058349">"USB पोर्टमा तरल पदार्थ वा धुलो भएको कुरा पत्ता लाग्यो"</string>
     <string name="usb_contaminant_detected_message" msgid="832337061059487250">"USB पोर्ट स्वतः असक्षम पारियो। थप जान्न ट्याप गर्नुहोस्।"</string>
-    <!-- no translation found for usb_contaminant_not_detected_title (7708281124088684821) -->
-    <skip />
+    <string name="usb_contaminant_not_detected_title" msgid="7708281124088684821">"USB पोर्ट प्रयोग गर्दा हुन्छ"</string>
     <string name="usb_contaminant_not_detected_message" msgid="2415791798244545292">"फोनले अब उप्रान्त तरल पदार्थ वा धुलो नभएको पत्ता लगायो"</string>
     <string name="taking_remote_bugreport_notification_title" msgid="6742483073875060934">"बग रिपोर्ट लिँदै..."</string>
     <string name="share_remote_bugreport_notification_title" msgid="4987095013583691873">"बग रिपोर्टलाई साझेदारी गर्ने हो?"</string>
@@ -1500,7 +1500,7 @@
     <string name="find_next" msgid="5742124618942193978">"अर्को भेटाउनुहोस्"</string>
     <string name="find_previous" msgid="2196723669388360506">"अघिल्लो फेला पार्नुहोस्"</string>
     <string name="gpsNotifTicker" msgid="5622683912616496172">"<xliff:g id="NAME">%s</xliff:g> बाट स्थान अनुरोध"</string>
-    <string name="gpsNotifTitle" msgid="5446858717157416839">"स्थान अनुरोध"</string>
+    <string name="gpsNotifTitle" msgid="5446858717157416839">"स्थानसम्बन्धी अनुरोध"</string>
     <string name="gpsNotifMessage" msgid="1374718023224000702">"<xliff:g id="NAME">%1$s</xliff:g> (<xliff:g id="SERVICE">%2$s</xliff:g>) द्वारा अनुरोध गरिएको"</string>
     <string name="gpsVerifYes" msgid="2346566072867213563">"हो"</string>
     <string name="gpsVerifNo" msgid="1146564937346454865">"होइन"</string>
@@ -1618,8 +1618,6 @@
     <string name="display_manager_overlay_display_name" msgid="5142365982271620716">"आवरण #<xliff:g id="ID">%1$d</xliff:g>"</string>
     <string name="display_manager_overlay_display_title" msgid="652124517672257172">"<xliff:g id="NAME">%1$s</xliff:g>: <xliff:g id="WIDTH">%2$d</xliff:g>x<xliff:g id="HEIGHT">%3$d</xliff:g>, <xliff:g id="DPI">%4$d</xliff:g> dpi"</string>
     <string name="display_manager_overlay_display_secure_suffix" msgid="6022119702628572080">", सुरक्षित"</string>
-    <string name="activity_starter_block_bg_activity_starts_permissive" msgid="6995473033438879646">"यो पृष्ठभूमिमा चल्ने क्रियाकलापलाई <xliff:g id="PACKAGENAME">%1$s</xliff:g> बाट भविष्यका Q build हरूमा रोक लगाइने छ। g.co/dev/bgblock हेर्नुहोस्।"</string>
-    <string name="activity_starter_block_bg_activity_starts_enforcing" msgid="3317816771072146229">"<xliff:g id="PACKAGENAME">%1$s</xliff:g> माथि रोक लगाएपछि पृष्ठभूमिको क्रियाकलाप सुरु हुन्छ। g.co/dev/bgblock हेर्नुहोस्।"</string>
     <string name="kg_forgot_pattern_button_text" msgid="8852021467868220608">"ढाँचा बिर्सनु भयो"</string>
     <string name="kg_wrong_pattern" msgid="1850806070801358830">"गलत ढाँचा"</string>
     <string name="kg_wrong_password" msgid="2333281762128113157">"गलत पासवर्ड"</string>
@@ -1673,8 +1671,12 @@
     <string name="accessibility_shortcut_enabling_service" msgid="7771852911861522636">"पहुँचको सर्टकटले <xliff:g id="SERVICE_NAME">%1$s</xliff:g> लाई सक्रिय पार्‍यो"</string>
     <string name="accessibility_shortcut_disabling_service" msgid="2747243438223109821">"पहुँचको सर्टकटले <xliff:g id="SERVICE_NAME">%1$s</xliff:g> लाई निष्क्रिय पार्‍यो"</string>
     <string name="accessibility_shortcut_spoken_feedback" msgid="8376923232350078434">"<xliff:g id="SERVICE_NAME">%1$s</xliff:g> प्रयोग गर्न दुवै भोल्युम कुञ्जीहरूलाई तीन सेकेन्डसम्म थिचिराख्नुहोस्"</string>
-    <string name="accessibility_button_prompt_text" msgid="4234556536456854251">"तपाईंले पहुँच सम्बन्धी बटनलाई ट्याप गर्दा प्रयोग गर्नुपर्ने सुविधा रोज्नुहोस्:"</string>
-    <string name="accessibility_button_instructional_text" msgid="6942300463612999993">"सुविधाहरूलाई बदल्न, पहुँच सम्बन्धी बटनलाई छोएर थिची राख्नुहोस्।"</string>
+    <string name="accessibility_button_prompt_text" msgid="1176658502969738564">"तपाईंले पहुँचसम्बन्धी बटन ट्याप गर्दा प्रयोग गर्नु पर्ने सुविधा रोज्नुहोस्:"</string>
+    <string name="accessibility_gesture_prompt_text" msgid="8259145549733019401">"पहुँचसम्बन्धी इसारासँगै प्रयोग गर्नु पर्ने कुनै सेवा छनौट गर्नुहोस् (दुईवटा औँलाले स्क्रिनको फेदबाट माथितिर स्वाइप गर्नुहोस्):"</string>
+    <string name="accessibility_gesture_3finger_prompt_text" msgid="1041435574275047665">"पहुँचसम्बन्धी इसारासँगै प्रयोग गर्नु पर्ने कुनै सेवा छनौट गर्नुहोस् (तीनवटा औँलाले स्क्रिनको फेदबाट माथितिर स्वाइप गर्नुहोस्):"</string>
+    <string name="accessibility_button_instructional_text" msgid="7003212763213614833">"एउटा सेवाबाट अर्को सेवामा जान पहुँचसम्बन्धी बटनमा छोइराख्नुहोस्।"</string>
+    <string name="accessibility_gesture_instructional_text" msgid="5261788874937410950">"एउटा सेवाबाट अर्को सेवामा जान दुईवटा औँलाले माथितिर स्वाइप गरी थिचिराख्नुहोस्।"</string>
+    <string name="accessibility_gesture_3finger_instructional_text" msgid="4969448938984394550">"एउटा सेवाबाट अर्को सेवामा जान तीनवटा औँलाले माथितिर स्वाइप गरी थिचिराख्नुहोस्।"</string>
     <string name="accessibility_magnification_chooser_text" msgid="1227146738764986237">"म्याग्निफिकेसन"</string>
     <string name="user_switched" msgid="3768006783166984410">"अहिलेको प्रयोगकर्ता <xliff:g id="NAME">%1$s</xliff:g>।"</string>
     <string name="user_switching_message" msgid="2871009331809089783">"<xliff:g id="NAME">%1$s</xliff:g> मा स्विच गर्दै..."</string>
diff --git a/core/res/res/values-night/themes_device_defaults.xml b/core/res/res/values-night/themes_device_defaults.xml
index 8ba2c60..93975a9 100644
--- a/core/res/res/values-night/themes_device_defaults.xml
+++ b/core/res/res/values-night/themes_device_defaults.xml
@@ -87,5 +87,7 @@
 
     <style name="Theme.DeviceDefault.Resolver" parent="Theme.DeviceDefault.ResolverCommon">
         <item name="windowLightNavigationBar">false</item>
+        <item name="colorBackgroundFloating">@android:color/GM2_grey_800</item>
+        <item name="textColorSecondary">@android:color/resolver_text_color_secondary_dark</item>
     </style>
 </resources>
diff --git a/core/res/res/values-nl/strings.xml b/core/res/res/values-nl/strings.xml
index fe106e1..7a3a030 100644
--- a/core/res/res/values-nl/strings.xml
+++ b/core/res/res/values-nl/strings.xml
@@ -131,6 +131,7 @@
     <!-- no translation found for wfcSpnFormat_spn (4998685024207291232) -->
     <skip />
     <string name="wfcSpnFormat_spn_wifi_calling" msgid="136001023263502280">"Bellen via wifi van <xliff:g id="SPN">%s</xliff:g>"</string>
+    <string name="wfcSpnFormat_spn_wifi_calling_vo_hyphen" msgid="1730997175789582756">"Bellen via wifi met <xliff:g id="SPN">%s</xliff:g>"</string>
     <string name="wfcSpnFormat_wlan_call" msgid="2533371081782489793">"Bellen via WLAN"</string>
     <string name="wfcSpnFormat_spn_wlan_call" msgid="2315240198303197168">"Bellen via WLAN van <xliff:g id="SPN">%s</xliff:g>"</string>
     <string name="wfcSpnFormat_spn_wifi" msgid="6546481665561961938">"Wifi van <xliff:g id="SPN">%s</xliff:g>"</string>
@@ -1357,8 +1358,7 @@
     <string name="test_harness_mode_notification_message" msgid="1343197173054407119">"Reset de fabrieksinstellingen om de test harness-modus uit te schakelen."</string>
     <string name="usb_contaminant_detected_title" msgid="7136400633704058349">"Vloeistof of vuil in USB-poort"</string>
     <string name="usb_contaminant_detected_message" msgid="832337061059487250">"USB-poort is automatisch uitgeschakeld. Tik voor meer informatie."</string>
-    <!-- no translation found for usb_contaminant_not_detected_title (7708281124088684821) -->
-    <skip />
+    <string name="usb_contaminant_not_detected_title" msgid="7708281124088684821">"USB-poort kan worden gebruikt"</string>
     <string name="usb_contaminant_not_detected_message" msgid="2415791798244545292">"De telefoon detecteert geen vloeistof of vuil meer."</string>
     <string name="taking_remote_bugreport_notification_title" msgid="6742483073875060934">"Bugrapport genereren…"</string>
     <string name="share_remote_bugreport_notification_title" msgid="4987095013583691873">"Bugrapport delen?"</string>
@@ -1612,8 +1612,6 @@
     <string name="display_manager_overlay_display_name" msgid="5142365982271620716">"Overlay <xliff:g id="ID">%1$d</xliff:g>"</string>
     <string name="display_manager_overlay_display_title" msgid="652124517672257172">"<xliff:g id="NAME">%1$s</xliff:g>: <xliff:g id="WIDTH">%2$d</xliff:g>x<xliff:g id="HEIGHT">%3$d</xliff:g>, <xliff:g id="DPI">%4$d</xliff:g> dpi"</string>
     <string name="display_manager_overlay_display_secure_suffix" msgid="6022119702628572080">", beveiligd"</string>
-    <string name="activity_starter_block_bg_activity_starts_permissive" msgid="6995473033438879646">"Het starten van deze achtergrondactiviteit voor <xliff:g id="PACKAGENAME">%1$s</xliff:g> wordt geblokkeerd in toekomstige Q-builds. Ga naar g.co/dev/bgblock."</string>
-    <string name="activity_starter_block_bg_activity_starts_enforcing" msgid="3317816771072146229">"Starten van achtergrondactiviteit voor <xliff:g id="PACKAGENAME">%1$s</xliff:g> is geblokkeerd. Ga naar g.co/dev/bgblock."</string>
     <string name="kg_forgot_pattern_button_text" msgid="8852021467868220608">"Patroon vergeten"</string>
     <string name="kg_wrong_pattern" msgid="1850806070801358830">"Onjuist patroon"</string>
     <string name="kg_wrong_password" msgid="2333281762128113157">"Onjuist wachtwoord"</string>
@@ -1667,8 +1665,12 @@
     <string name="accessibility_shortcut_enabling_service" msgid="7771852911861522636">"\'Snelle link voor toegankelijkheid\' heeft <xliff:g id="SERVICE_NAME">%1$s</xliff:g> ingeschakeld"</string>
     <string name="accessibility_shortcut_disabling_service" msgid="2747243438223109821">"\'Snelle link voor toegankelijkheid\' heeft <xliff:g id="SERVICE_NAME">%1$s</xliff:g> uitgeschakeld"</string>
     <string name="accessibility_shortcut_spoken_feedback" msgid="8376923232350078434">"Houd beide volumetoetsen drie seconden ingedrukt om <xliff:g id="SERVICE_NAME">%1$s</xliff:g> te gebruiken"</string>
-    <string name="accessibility_button_prompt_text" msgid="4234556536456854251">"Kies een functie om te gebruiken wanneer je op de knop Toegankelijkheid tikt:"</string>
-    <string name="accessibility_button_instructional_text" msgid="6942300463612999993">"Als je functies wilt wijzigen, tik je op de knop Toegankelijkheid en houd je deze vast."</string>
+    <string name="accessibility_button_prompt_text" msgid="1176658502969738564">"Kies een service om te gebruiken wanneer je op de toegankelijkheidsknop tikt:"</string>
+    <string name="accessibility_gesture_prompt_text" msgid="8259145549733019401">"Kies een service om te gebruiken met het toegankelijkheidsgebaar (veeg met twee vingers omhoog vanaf de onderkant van het scherm):"</string>
+    <string name="accessibility_gesture_3finger_prompt_text" msgid="1041435574275047665">"Kies een service om te gebruiken met het toegankelijkheidsgebaar (veeg met drie vingers omhoog vanaf de onderkant van het scherm):"</string>
+    <string name="accessibility_button_instructional_text" msgid="7003212763213614833">"Tik op de toegankelijkheidsknop en houd deze vast om tussen services te schakelen."</string>
+    <string name="accessibility_gesture_instructional_text" msgid="5261788874937410950">"Veeg met twee vingers omhoog en houd vast om tussen services te schakelen."</string>
+    <string name="accessibility_gesture_3finger_instructional_text" msgid="4969448938984394550">"Veeg met drie vingers omhoog en houd vast om tussen services te schakelen."</string>
     <string name="accessibility_magnification_chooser_text" msgid="1227146738764986237">"Vergroting"</string>
     <string name="user_switched" msgid="3768006783166984410">"Huidige gebruiker <xliff:g id="NAME">%1$s</xliff:g>."</string>
     <string name="user_switching_message" msgid="2871009331809089783">"Overschakelen naar <xliff:g id="NAME">%1$s</xliff:g>…"</string>
diff --git a/core/res/res/values-or/strings.xml b/core/res/res/values-or/strings.xml
index 7e79f21..b37cf9d 100644
--- a/core/res/res/values-or/strings.xml
+++ b/core/res/res/values-or/strings.xml
@@ -131,6 +131,7 @@
     <!-- no translation found for wfcSpnFormat_spn (4998685024207291232) -->
     <skip />
     <string name="wfcSpnFormat_spn_wifi_calling" msgid="136001023263502280">"<xliff:g id="SPN">%s</xliff:g> ୱାଇ-ଫାଇ କଲିଂ"</string>
+    <string name="wfcSpnFormat_spn_wifi_calling_vo_hyphen" msgid="1730997175789582756">"<xliff:g id="SPN">%s</xliff:g> ୱାଇଫାଇ କଲିଂ"</string>
     <string name="wfcSpnFormat_wlan_call" msgid="2533371081782489793">"WLAN କଲ୍‍"</string>
     <string name="wfcSpnFormat_spn_wlan_call" msgid="2315240198303197168">"<xliff:g id="SPN">%s</xliff:g> WLAN କଲ୍‍"</string>
     <string name="wfcSpnFormat_spn_wifi" msgid="6546481665561961938">"<xliff:g id="SPN">%s</xliff:g> ୱାଇ-ଫାଇ"</string>
@@ -1357,8 +1358,7 @@
     <string name="test_harness_mode_notification_message" msgid="1343197173054407119">"ଟେଷ୍ଟ ହାର୍‌ନେସ୍ ମୋଡ୍ ଅକ୍ଷମ କରିବାକୁ ଏକ ଫ୍ୟାକ୍ଟରୀ ରିସେଟ୍ କରନ୍ତୁ।"</string>
     <string name="usb_contaminant_detected_title" msgid="7136400633704058349">"USB ପୋର୍ଟରେ ତରଳ ପଦାର୍ଥ ବା ଧୂଳି"</string>
     <string name="usb_contaminant_detected_message" msgid="832337061059487250">"USB ପୋର୍ଟ ସ୍ୱଚାଳିତ ଭାବେ ଅକ୍ଷମ ହୋଇଛି। ଅଧିକ ଜାଣିବା ପାଇଁ ଟାପ୍ କରନ୍ତୁ।"</string>
-    <!-- no translation found for usb_contaminant_not_detected_title (7708281124088684821) -->
-    <skip />
+    <string name="usb_contaminant_not_detected_title" msgid="7708281124088684821">"USB ପୋର୍ଟ ବ୍ୟବହାର କରିବା ପାଇଁ ଠିକ୍ ଅଟେ"</string>
     <string name="usb_contaminant_not_detected_message" msgid="2415791798244545292">"ଫୋନ୍ ଆଉ ତରଳ ପଦାର୍ଥ କିମ୍ବା ଧୂଳିର ଚିହ୍ନଟ କରୁନାହିଁ।"</string>
     <string name="taking_remote_bugreport_notification_title" msgid="6742483073875060934">"ବଗ୍ ରିପୋର୍ଟ ନିଆଯାଉଛି…"</string>
     <string name="share_remote_bugreport_notification_title" msgid="4987095013583691873">"ବଗ୍‍ ରିପୋର୍ଟ ସେୟାର୍‌ କରିବେ?"</string>
@@ -1612,8 +1612,6 @@
     <string name="display_manager_overlay_display_name" msgid="5142365982271620716">"ପ୍ରାୟତଃ #<xliff:g id="ID">%1$d</xliff:g>"</string>
     <string name="display_manager_overlay_display_title" msgid="652124517672257172">"<xliff:g id="NAME">%1$s</xliff:g>: <xliff:g id="WIDTH">%2$d</xliff:g>x<xliff:g id="HEIGHT">%3$d</xliff:g>, <xliff:g id="DPI">%4$d</xliff:g> dpi"</string>
     <string name="display_manager_overlay_display_secure_suffix" msgid="6022119702628572080">", ସୁରକ୍ଷିତ"</string>
-    <string name="activity_starter_block_bg_activity_starts_permissive" msgid="6995473033438879646">"<xliff:g id="PACKAGENAME">%1$s</xliff:g> ଠାରୁ ଆରମ୍ଭ ହୋଇଥିବା ପୃଷ୍ଠଭୂମି କାର୍ଯ୍ୟକଳାପ ଆଗାମୀ Q ବିଲ୍ଡରେ ବ୍ଲକ୍ କରାଯିବ। g.co/dev/bgblock ଦେଖନ୍ତୁ।"</string>
-    <string name="activity_starter_block_bg_activity_starts_enforcing" msgid="3317816771072146229">"<xliff:g id="PACKAGENAME">%1$s</xliff:g>ଠାରୁ ଆରମ୍ଭ ହୋଇଥିବା ପୃଷ୍ଠଭୂମି କାର୍ଯ୍ୟକଳାପ ବ୍ଲକ୍ କରାଯାଇଛି। g.co/dev/bgblock ଦେଖନ୍ତୁ।"</string>
     <string name="kg_forgot_pattern_button_text" msgid="8852021467868220608">"ପାଟର୍ନ ଭୁଲି ଯାଇଛନ୍ତି"</string>
     <string name="kg_wrong_pattern" msgid="1850806070801358830">"ଭୁଲ ପାଟର୍ନ"</string>
     <string name="kg_wrong_password" msgid="2333281762128113157">"ଭୁଲ ପାସ୍‌ୱର୍ଡ"</string>
@@ -1667,8 +1665,12 @@
     <string name="accessibility_shortcut_enabling_service" msgid="7771852911861522636">"ଆକ୍ସେସିବିଲିଟୀ ଶର୍ଟକଟ୍‍ <xliff:g id="SERVICE_NAME">%1$s</xliff:g> ଅନ୍‍ କରାଯାଇଛି"</string>
     <string name="accessibility_shortcut_disabling_service" msgid="2747243438223109821">"ଆକ୍ସେସିବିଲିଟୀ ଶର୍ଟକଟ୍‍ <xliff:g id="SERVICE_NAME">%1$s</xliff:g> ଅଫ୍‍ କରାଯାଇଛି"</string>
     <string name="accessibility_shortcut_spoken_feedback" msgid="8376923232350078434">"<xliff:g id="SERVICE_NAME">%1$s</xliff:g> ବ୍ୟବହାର କରିବାକୁ ତିନି ସେକେଣ୍ଡ ପାଇଁ ଉଭୟ ଭଲ୍ୟୁମ୍‍ କୀ ଦବାଇ ଧରି ରଖନ୍ତୁ"</string>
-    <string name="accessibility_button_prompt_text" msgid="4234556536456854251">"ଆପଣ ଆକ୍ସେସବିଲିଟି ବଟନ୍‍ ଟାପ୍‍ କରିବା ବେଳେ ଏକ ବୈଶିଷ୍ଟ୍ୟ ବ୍ୟବହାର କରିବାକୁ ବାଛନ୍ତୁ:"</string>
-    <string name="accessibility_button_instructional_text" msgid="6942300463612999993">"ବୈଶିଷ୍ଟ୍ୟ ବଦଳାଇବାକୁ, ଆକ୍ସେସବିଲିଟି ବଟନ୍‍ ସ୍ପର୍ଶ କରନ୍ତୁ ଓ ଧରିରଖନ୍ତୁ।"</string>
+    <string name="accessibility_button_prompt_text" msgid="1176658502969738564">"ଆପଣ ଆକ୍ସେସିବିଲିଟୀ ବଟନ୍ ଟାପ୍ କରିବା ସମୟରେ ଏକ ସେବା ବ୍ୟବହାର କରିବା ପାଇଁ ବାଛନ୍ତୁ:"</string>
+    <string name="accessibility_gesture_prompt_text" msgid="8259145549733019401">"ଆକ୍ସେସିବିଲିଟୀ ଜେଶ୍ଚର୍ ବ୍ୟବହାର କରିବା ପାଇଁ ଏକ ସେବା ବାଛନ୍ତୁ (ଦୁଇଟି ଆଙ୍ଗୁଠିରେ ସ୍କ୍ରିନ୍‍ର ତଳୁ ଉପରକୁ ସ୍ୱାଇପ୍ କରନ୍ତୁ):"</string>
+    <string name="accessibility_gesture_3finger_prompt_text" msgid="1041435574275047665">"ଆକ୍ସେସିବିଲିଟୀ ଜେଶ୍ଚର୍ ବ୍ୟବହାର କରିବା ପାଇଁ ଏକ ସେବା ବାଛନ୍ତୁ (ତିନିଟି ଆଙ୍ଗୁଠିରେ ସ୍କ୍ରିନ୍‍ର ତଳୁ ଉପରକୁ ସ୍ୱାଇପ୍ କରନ୍ତୁ):"</string>
+    <string name="accessibility_button_instructional_text" msgid="7003212763213614833">"ସେବାଗୁଡ଼ିକ ମଧ୍ୟରେ ସ୍ୱିଚ୍ କରିବା ପାଇଁ ଆକ୍ସେସିବିଲିଟୀ ବଟନ୍ ସ୍ପର୍ଶ ଓ ଧରି ରଖନ୍ତୁ।"</string>
+    <string name="accessibility_gesture_instructional_text" msgid="5261788874937410950">"ସେବାଗୁଡ଼ିକ ମଧ୍ୟରେ ସ୍ୱିଚ୍ କରିବା ପାଇଁ ଦୁଇଟି ଆଙ୍ଗୁଠିରେ ଉପରକୁ ସ୍ୱାଇପ୍ କରନ୍ତୁ ଏବଂ ଧରି ରଖନ୍ତୁ।"</string>
+    <string name="accessibility_gesture_3finger_instructional_text" msgid="4969448938984394550">"ସେବାଗୁଡ଼ିକ ମଧ୍ୟରେ ସ୍ୱିଚ୍ କରିବା ପାଇଁ ତିନିଟି ଆଙ୍ଗୁଠିରେ ଉପରକୁ ସ୍ୱାଇପ୍ କରନ୍ତୁ ଏବଂ ଧରି ରଖନ୍ତୁ।"</string>
     <string name="accessibility_magnification_chooser_text" msgid="1227146738764986237">"ମ୍ୟାଗ୍ନିଫିକେସନ୍‍"</string>
     <string name="user_switched" msgid="3768006783166984410">"ବର୍ତ୍ତମାନର ୟୁଜର୍‌ ହେଉଛନ୍ତି <xliff:g id="NAME">%1$s</xliff:g>।"</string>
     <string name="user_switching_message" msgid="2871009331809089783">"<xliff:g id="NAME">%1$s</xliff:g> ରେ ସୁଇଚ୍ କରନ୍ତୁ…"</string>
diff --git a/core/res/res/values-pa/strings.xml b/core/res/res/values-pa/strings.xml
index e6c8bfc..65feb91 100644
--- a/core/res/res/values-pa/strings.xml
+++ b/core/res/res/values-pa/strings.xml
@@ -131,6 +131,7 @@
     <!-- no translation found for wfcSpnFormat_spn (4998685024207291232) -->
     <skip />
     <string name="wfcSpnFormat_spn_wifi_calling" msgid="136001023263502280">"<xliff:g id="SPN">%s</xliff:g> ਵਾਈ-ਫਾਈ ਕਾਲਿੰਗ"</string>
+    <string name="wfcSpnFormat_spn_wifi_calling_vo_hyphen" msgid="1730997175789582756">"<xliff:g id="SPN">%s</xliff:g> ਵਾਈ-ਫਾਈ Calling"</string>
     <string name="wfcSpnFormat_wlan_call" msgid="2533371081782489793">"WLAN ਕਾਲ"</string>
     <string name="wfcSpnFormat_spn_wlan_call" msgid="2315240198303197168">"<xliff:g id="SPN">%s</xliff:g> WLAN ਕਾਲ"</string>
     <string name="wfcSpnFormat_spn_wifi" msgid="6546481665561961938">"<xliff:g id="SPN">%s</xliff:g> ਵਾਈ-ਫਾਈ"</string>
@@ -1358,8 +1359,7 @@
     <string name="test_harness_mode_notification_message" msgid="1343197173054407119">"ਟੈਸਟ ਹਾਰਨੈੱਸ ਮੋਡ ਬੰਦ ਕਰਨ ਲਈ ਫੈਕਟਰੀ ਰੀਸੈੱਟ ਕਰੋ।"</string>
     <string name="usb_contaminant_detected_title" msgid="7136400633704058349">"USB ਪੋਰਟ ਵਿੱਚ ਪਾਣੀ ਜਾਂ ਧੂੜ-ਮਿੱਟੀ"</string>
     <string name="usb_contaminant_detected_message" msgid="832337061059487250">"USB ਪੋਰਟ ਸਵੈਚਲਿਤ ਤੌਰ \'ਤੇ ਬੰਦ ਕੀਤਾ ਗਿਆ। ਹੋਰ ਜਾਣਨ ਲਈ ਟੈਪ ਕਰੋ।"</string>
-    <!-- no translation found for usb_contaminant_not_detected_title (7708281124088684821) -->
-    <skip />
+    <string name="usb_contaminant_not_detected_title" msgid="7708281124088684821">"USB ਪੋਰਟ ਵਰਤਣ ਲਈ ਠੀਕ ਹੈ"</string>
     <string name="usb_contaminant_not_detected_message" msgid="2415791798244545292">"ਫ਼ੋਨ ਹੁਣ ਪਾਣੀ ਜਾਂ ਧੂੜ-ਮਿੱਟੀ ਦਾ ਪਤਾ ਨਹੀਂ ਲਗਾਉਂਦਾ ਹੈ।"</string>
     <string name="taking_remote_bugreport_notification_title" msgid="6742483073875060934">"ਬੱਗ ਰਿਪਰੋਟ ਪ੍ਰਾਪਤ ਕੀਤੀ ਜਾ ਰਹੀ ਹੈ..."</string>
     <string name="share_remote_bugreport_notification_title" msgid="4987095013583691873">"ਕੀ ਬੱਗ ਰਿਪੋਰਟ ਸਾਂਝੀ ਕਰਨੀ ਹੈ?"</string>
@@ -1613,8 +1613,6 @@
     <string name="display_manager_overlay_display_name" msgid="5142365982271620716">"ਓਵਰਲੇ #<xliff:g id="ID">%1$d</xliff:g>"</string>
     <string name="display_manager_overlay_display_title" msgid="652124517672257172">"<xliff:g id="NAME">%1$s</xliff:g>: <xliff:g id="WIDTH">%2$d</xliff:g>x<xliff:g id="HEIGHT">%3$d</xliff:g>, <xliff:g id="DPI">%4$d</xliff:g> dpi"</string>
     <string name="display_manager_overlay_display_secure_suffix" msgid="6022119702628572080">", ਸੁਰੱਖਿਅਤ"</string>
-    <string name="activity_starter_block_bg_activity_starts_permissive" msgid="6995473033438879646">"ਇਹ ਬੈਕਗ੍ਰਾਊਂਡ ਸਰਗਰਮੀ <xliff:g id="PACKAGENAME">%1$s</xliff:g> ਤੋਂ ਸ਼ੁਰੂ ਹੋ ਕੇ ਭਵਿੱਖ ਦੇ Q ਬਿਲਡ ਵਿੱਚ ਬਲਾਕ ਕੀਤੀ ਜਾਵੇਗੀ। g.co/dev/bgblock ਦੇਖੋ।"</string>
-    <string name="activity_starter_block_bg_activity_starts_enforcing" msgid="3317816771072146229">"<xliff:g id="PACKAGENAME">%1$s</xliff:g> ਬਲਾਕ ਕਰਕੇ ਬੈਕਗ੍ਰਾਊਂਡ ਸਰਗਰਮੀ ਸ਼ੁਰੂ ਕੀਤੀ ਗਈ। g.co/dev/bgblock ਦੇਖੋ।"</string>
     <string name="kg_forgot_pattern_button_text" msgid="8852021467868220608">"ਪੈਟਰਨ ਭੁੱਲ ਗਏ"</string>
     <string name="kg_wrong_pattern" msgid="1850806070801358830">"ਗ਼ਲਤ ਪੈਟਰਨ"</string>
     <string name="kg_wrong_password" msgid="2333281762128113157">"ਗਲਤ ਪਾਸਵਰਡ"</string>
@@ -1668,8 +1666,12 @@
     <string name="accessibility_shortcut_enabling_service" msgid="7771852911861522636">"ਪਹੁੰਚਯੋਗਤਾ ਸ਼ਾਰਟਕੱਟ ਨੇ <xliff:g id="SERVICE_NAME">%1$s</xliff:g> ਨੂੰ ਚਾਲੂ ਕੀਤਾ"</string>
     <string name="accessibility_shortcut_disabling_service" msgid="2747243438223109821">"ਪਹੁੰਚਯੋਗਤਾ ਸ਼ਾਰਟਕੱਟ ਨੇ <xliff:g id="SERVICE_NAME">%1$s</xliff:g> ਨੂੰ ਬੰਦ ਕੀਤਾ"</string>
     <string name="accessibility_shortcut_spoken_feedback" msgid="8376923232350078434">"<xliff:g id="SERVICE_NAME">%1$s</xliff:g> ਦੀ ਵਰਤੋਂ ਕਰਨ ਲਈ ਦੋਵੇਂ ਅਵਾਜ਼ ਕੁੰਜੀਆਂ ਨੂੰ 3 ਸਕਿੰਟਾਂ ਲਈ ਦਬਾਈ ਰੱਖੋ"</string>
-    <string name="accessibility_button_prompt_text" msgid="4234556536456854251">"ਤੁਹਾਡੇ ਵੱਲੋਂ ਪਹੁੰਚਯੋਗਤਾ ਬਟਨ ਨੂੰ ਟੈਪ ਕੀਤੇ ਜਾਣ \'ਤੇ ਵਰਤਣ ਲਈ ਕੋਈ ਵਿਸ਼ੇਸ਼ਤਾ ਚੁਣੋ:"</string>
-    <string name="accessibility_button_instructional_text" msgid="6942300463612999993">"ਵਿਸ਼ੇਸ਼ਤਾਵਾਂ ਨੂੰ ਬਦਲਣ ਲਈ, ਪਹੁੰਚਯੋਗਤਾ ਬਟਨ ਨੂੰ ਸਪੱਰਸ਼ ਕਰੋ ਅਤੇ ਦਬਾਈ ਰੱਖੋ।"</string>
+    <string name="accessibility_button_prompt_text" msgid="1176658502969738564">"ਪਹੁੰਚਯੋਗਤਾ ਬਟਨ \'ਤੇ ਟੈਪ ਕਰਕੇ ਵਰਤਣ ਲਈ ਕੋਈ ਸੇਵਾ ਚੁਣੋ:"</string>
+    <string name="accessibility_gesture_prompt_text" msgid="8259145549733019401">"ਪਹੁੰਚਯੋਗਤਾ ਸੰਕੇਤ ਨਾਲ ਵਰਤਣ ਲਈ ਕੋਈ ਸੇਵਾ ਚੁਣੋ (ਦੋ ਉਂਗਲਾਂ ਨਾਲ ਸਕ੍ਰੀਨ ਦੇ ਹੇਠਾਂ ਤੋਂ ਉੱਪਰ ਵੱਲ ਸਕ੍ਰੋਲ ਕਰੋ):"</string>
+    <string name="accessibility_gesture_3finger_prompt_text" msgid="1041435574275047665">"ਪਹੁੰਚਯੋਗਤਾ ਸੰਕੇਤ ਨਾਲ ਵਰਤਣ ਲਈ ਕੋਈ ਸੇਵਾ ਚੁਣੋ (ਤਿੰਨ ਉਂਗਲਾਂ ਨਾਲ ਸਕ੍ਰੀਨ ਦੇ ਹੇਠਾਂ ਤੋਂ ਉੱਪਰ ਵੱਲ ਸਕ੍ਰੋਲ ਕਰੋ):"</string>
+    <string name="accessibility_button_instructional_text" msgid="7003212763213614833">"ਸੇਵਾਵਾਂ ਵਿਚਾਲੇ ਅਦਲਾ-ਬਦਲੀ ਕਰਨ ਲਈ, ਪਹੁੰਚਯੋਗਤਾ ਬਟਨ \'ਤੇ ਸਪਰਸ਼ ਕਰਕੇ ਰੱਖੋ।"</string>
+    <string name="accessibility_gesture_instructional_text" msgid="5261788874937410950">"ਸੇਵਾਵਾਂ ਵਿਚਾਲੇ ਅਦਲਾ-ਬਦਲੀ ਕਰਨ ਲਈ, ਦੋ ਉਂਗਲਾਂ ਨਾਲ ਉੱਪਰ ਵੱਲ ਸਵਾਈਪ ਕਰਕੇ ਦਬਾਈ ਰੱਖੋ।"</string>
+    <string name="accessibility_gesture_3finger_instructional_text" msgid="4969448938984394550">"ਸੇਵਾਵਾਂ ਵਿਚਾਲੇ ਅਦਲਾ-ਬਦਲੀ ਕਰਨ ਲਈ, ਤਿੰਨ ਉਂਗਲਾਂ ਨਾਲ ਉੱਪਰ ਵੱਲ ਸਵਾਈਪ ਕਰਕੇ ਦਬਾਈ ਰੱਖੋ।"</string>
     <string name="accessibility_magnification_chooser_text" msgid="1227146738764986237">"ਵੱਡਦਰਸ਼ੀਕਰਨ"</string>
     <string name="user_switched" msgid="3768006783166984410">"ਮੌਜੂਦਾ ਉਪਭੋਗਤਾ <xliff:g id="NAME">%1$s</xliff:g>।"</string>
     <string name="user_switching_message" msgid="2871009331809089783">"<xliff:g id="NAME">%1$s</xliff:g> ਤੇ ਸਵਿਚ ਕਰ ਰਿਹਾ ਹੈ…"</string>
diff --git a/core/res/res/values-pl/strings.xml b/core/res/res/values-pl/strings.xml
index bcf47e0..dc458e4 100644
--- a/core/res/res/values-pl/strings.xml
+++ b/core/res/res/values-pl/strings.xml
@@ -133,6 +133,7 @@
     <!-- no translation found for wfcSpnFormat_spn (4998685024207291232) -->
     <skip />
     <string name="wfcSpnFormat_spn_wifi_calling" msgid="136001023263502280">"<xliff:g id="SPN">%s</xliff:g>, połączenia przez Wi-Fi"</string>
+    <string name="wfcSpnFormat_spn_wifi_calling_vo_hyphen" msgid="1730997175789582756">"<xliff:g id="SPN">%s</xliff:g>, połączenia przez Wi-Fi"</string>
     <string name="wfcSpnFormat_wlan_call" msgid="2533371081782489793">"Połączenie przez WLAN"</string>
     <string name="wfcSpnFormat_spn_wlan_call" msgid="2315240198303197168">"<xliff:g id="SPN">%s</xliff:g>, połączenie przez WLAN"</string>
     <string name="wfcSpnFormat_spn_wifi" msgid="6546481665561961938">"<xliff:g id="SPN">%s</xliff:g>, Wi-Fi"</string>
@@ -1401,8 +1402,7 @@
     <string name="test_harness_mode_notification_message" msgid="1343197173054407119">"Przywróć ustawienia fabryczne, by wyłączyć tryb jarzma testowego."</string>
     <string name="usb_contaminant_detected_title" msgid="7136400633704058349">"Wilgoć lub brud w porcie USB"</string>
     <string name="usb_contaminant_detected_message" msgid="832337061059487250">"Port USB został automatycznie wyłączony. Kliknij, by dowiedzieć się więcej."</string>
-    <!-- no translation found for usb_contaminant_not_detected_title (7708281124088684821) -->
-    <skip />
+    <string name="usb_contaminant_not_detected_title" msgid="7708281124088684821">"Możesz używać portu USB"</string>
     <string name="usb_contaminant_not_detected_message" msgid="2415791798244545292">"Telefon nie wykrywa już wilgoci ani zanieczyszczeń."</string>
     <string name="taking_remote_bugreport_notification_title" msgid="6742483073875060934">"Zgłaszam błąd…"</string>
     <string name="share_remote_bugreport_notification_title" msgid="4987095013583691873">"Udostępnić raport o błędzie?"</string>
@@ -1658,8 +1658,6 @@
     <string name="display_manager_overlay_display_name" msgid="5142365982271620716">"Nakładka nr <xliff:g id="ID">%1$d</xliff:g>"</string>
     <string name="display_manager_overlay_display_title" msgid="652124517672257172">"<xliff:g id="NAME">%1$s</xliff:g>: <xliff:g id="WIDTH">%2$d</xliff:g> x <xliff:g id="HEIGHT">%3$d</xliff:g>, <xliff:g id="DPI">%4$d</xliff:g> dpi"</string>
     <string name="display_manager_overlay_display_secure_suffix" msgid="6022119702628572080">", bezpieczny"</string>
-    <string name="activity_starter_block_bg_activity_starts_permissive" msgid="6995473033438879646">"Rozpoczęcie tej aktywności w tle przez pakiet <xliff:g id="PACKAGENAME">%1$s</xliff:g> zostanie zablokowane w przyszłych kompilacjach Q. Patrz g.co/dev/bgblock."</string>
-    <string name="activity_starter_block_bg_activity_starts_enforcing" msgid="3317816771072146229">"Rozpoczęcie aktywności w tle przez pakiet <xliff:g id="PACKAGENAME">%1$s</xliff:g> zostało zablokowane. Patrz g.co/dev/bgblock."</string>
     <string name="kg_forgot_pattern_button_text" msgid="8852021467868220608">"Nie pamiętam wzoru"</string>
     <string name="kg_wrong_pattern" msgid="1850806070801358830">"Nieprawidłowy wzór"</string>
     <string name="kg_wrong_password" msgid="2333281762128113157">"Nieprawidłowe hasło"</string>
@@ -1715,8 +1713,12 @@
     <string name="accessibility_shortcut_enabling_service" msgid="7771852911861522636">"Skrót ułatwień dostępu wyłączył usługę <xliff:g id="SERVICE_NAME">%1$s</xliff:g>"</string>
     <string name="accessibility_shortcut_disabling_service" msgid="2747243438223109821">"Skrót ułatwień dostępu wyłączył usługę <xliff:g id="SERVICE_NAME">%1$s</xliff:g>"</string>
     <string name="accessibility_shortcut_spoken_feedback" msgid="8376923232350078434">"Naciśnij i przytrzymaj oba przyciski głośności przez trzy sekundy, by użyć usługi <xliff:g id="SERVICE_NAME">%1$s</xliff:g>"</string>
-    <string name="accessibility_button_prompt_text" msgid="4234556536456854251">"Wybierz funkcję używaną po kliknięciu przycisku ułatwień dostępu."</string>
-    <string name="accessibility_button_instructional_text" msgid="6942300463612999993">"Aby zmienić funkcje, kliknij i przytrzymaj przycisk ułatwień dostępu."</string>
+    <string name="accessibility_button_prompt_text" msgid="1176658502969738564">"Wybierz usługę używaną po kliknięciu przycisku ułatwień dostępu:"</string>
+    <string name="accessibility_gesture_prompt_text" msgid="8259145549733019401">"Wybierz usługę używaną w przypadku gestu ułatwień dostępu (przesunięcie dwoma palcami z dołu ekranu w górę):"</string>
+    <string name="accessibility_gesture_3finger_prompt_text" msgid="1041435574275047665">"Wybierz usługę używaną w przypadku gestu ułatwień dostępu (przesunięcie trzema palcami z dołu ekranu w górę):"</string>
+    <string name="accessibility_button_instructional_text" msgid="7003212763213614833">"Aby przełączać usługi, kliknij i przytrzymaj przycisk ułatwień dostępu."</string>
+    <string name="accessibility_gesture_instructional_text" msgid="5261788874937410950">"Aby przełączać usługi, przesuń dwoma palcami w górę i przytrzymaj."</string>
+    <string name="accessibility_gesture_3finger_instructional_text" msgid="4969448938984394550">"Aby przełączać usługi, przesuń trzema palcami w górę i przytrzymaj."</string>
     <string name="accessibility_magnification_chooser_text" msgid="1227146738764986237">"Powiększenie"</string>
     <string name="user_switched" msgid="3768006783166984410">"Bieżący użytkownik: <xliff:g id="NAME">%1$s</xliff:g>."</string>
     <string name="user_switching_message" msgid="2871009331809089783">"Przełączam na użytkownika <xliff:g id="NAME">%1$s</xliff:g>…"</string>
diff --git a/core/res/res/values-pt-rBR/strings.xml b/core/res/res/values-pt-rBR/strings.xml
index fbabb34..a8de75d1 100644
--- a/core/res/res/values-pt-rBR/strings.xml
+++ b/core/res/res/values-pt-rBR/strings.xml
@@ -131,6 +131,7 @@
     <!-- no translation found for wfcSpnFormat_spn (4998685024207291232) -->
     <skip />
     <string name="wfcSpnFormat_spn_wifi_calling" msgid="136001023263502280">"Chamada no Wi-Fi de <xliff:g id="SPN">%s</xliff:g>"</string>
+    <string name="wfcSpnFormat_spn_wifi_calling_vo_hyphen" msgid="1730997175789582756">"Chamada no Wi-Fi de <xliff:g id="SPN">%s</xliff:g>"</string>
     <string name="wfcSpnFormat_wlan_call" msgid="2533371081782489793">"Chamada por WLAN"</string>
     <string name="wfcSpnFormat_spn_wlan_call" msgid="2315240198303197168">"Chamada por WLAN de <xliff:g id="SPN">%s</xliff:g>"</string>
     <string name="wfcSpnFormat_spn_wifi" msgid="6546481665561961938">"Wi-Fi de <xliff:g id="SPN">%s</xliff:g>"</string>
@@ -1357,8 +1358,7 @@
     <string name="test_harness_mode_notification_message" msgid="1343197173054407119">"Realize uma redefinição para configuração original para desativar o modo Arcabouço de testes."</string>
     <string name="usb_contaminant_detected_title" msgid="7136400633704058349">"Líquido ou detrito na porta USB"</string>
     <string name="usb_contaminant_detected_message" msgid="832337061059487250">"A porta USB é desativada automaticamente. Toque para saber mais."</string>
-    <!-- no translation found for usb_contaminant_not_detected_title (7708281124088684821) -->
-    <skip />
+    <string name="usb_contaminant_not_detected_title" msgid="7708281124088684821">"É seguro usar a porta USB"</string>
     <string name="usb_contaminant_not_detected_message" msgid="2415791798244545292">"Não há mais líquidos ou detritos detectados no smartphone."</string>
     <string name="taking_remote_bugreport_notification_title" msgid="6742483073875060934">"Gerando relatório do bug..."</string>
     <string name="share_remote_bugreport_notification_title" msgid="4987095013583691873">"Compartilhar relatório do bug?"</string>
@@ -1494,7 +1494,7 @@
     <string name="find_next" msgid="5742124618942193978">"Localizar próximo"</string>
     <string name="find_previous" msgid="2196723669388360506">"Localizar anterior"</string>
     <string name="gpsNotifTicker" msgid="5622683912616496172">"Solicitação de local de <xliff:g id="NAME">%s</xliff:g>"</string>
-    <string name="gpsNotifTitle" msgid="5446858717157416839">"Solicitação de local"</string>
+    <string name="gpsNotifTitle" msgid="5446858717157416839">"Pedido de localização"</string>
     <string name="gpsNotifMessage" msgid="1374718023224000702">"Solicitado por <xliff:g id="NAME">%1$s</xliff:g> (<xliff:g id="SERVICE">%2$s</xliff:g>)"</string>
     <string name="gpsVerifYes" msgid="2346566072867213563">"Sim"</string>
     <string name="gpsVerifNo" msgid="1146564937346454865">"Não"</string>
@@ -1589,7 +1589,7 @@
     <string name="default_audio_route_name" product="tablet" msgid="4617053898167127471">"Tablet"</string>
     <string name="default_audio_route_name" product="tv" msgid="9158088547603019321">"TV"</string>
     <string name="default_audio_route_name" product="default" msgid="4239291273420140123">"Telefone"</string>
-    <string name="default_audio_route_name_dock_speakers" msgid="6240602982276591864">"Alto-falantes da dock"</string>
+    <string name="default_audio_route_name_dock_speakers" msgid="6240602982276591864">"Alto-falantes na base"</string>
     <string name="default_audio_route_name_hdmi" msgid="1486254205617081251">"HDMI"</string>
     <string name="default_audio_route_name_headphones" msgid="8119971843803439110">"Fones de ouvido"</string>
     <string name="default_audio_route_name_usb" msgid="1234984851352637769">"USB"</string>
@@ -1612,8 +1612,6 @@
     <string name="display_manager_overlay_display_name" msgid="5142365982271620716">"Sobreposição nº <xliff:g id="ID">%1$d</xliff:g>"</string>
     <string name="display_manager_overlay_display_title" msgid="652124517672257172">"<xliff:g id="NAME">%1$s</xliff:g>: <xliff:g id="WIDTH">%2$d</xliff:g>x<xliff:g id="HEIGHT">%3$d</xliff:g>, <xliff:g id="DPI">%4$d</xliff:g> dpi"</string>
     <string name="display_manager_overlay_display_secure_suffix" msgid="6022119702628572080">", seguro"</string>
-    <string name="activity_starter_block_bg_activity_starts_permissive" msgid="6995473033438879646">"Esse início de atividade em segundo plano a partir de <xliff:g id="PACKAGENAME">%1$s</xliff:g> será bloqueado nas versões futuras do Android Q. Acesse g.co/dev/bgblock."</string>
-    <string name="activity_starter_block_bg_activity_starts_enforcing" msgid="3317816771072146229">"O início da atividade em segundo plano a partir de <xliff:g id="PACKAGENAME">%1$s</xliff:g> foi bloqueado. Acesse g.co/dev/bgblock."</string>
     <string name="kg_forgot_pattern_button_text" msgid="8852021467868220608">"Esqueci o padrão"</string>
     <string name="kg_wrong_pattern" msgid="1850806070801358830">"Padrão incorreto"</string>
     <string name="kg_wrong_password" msgid="2333281762128113157">"Senha incorreta"</string>
@@ -1667,8 +1665,12 @@
     <string name="accessibility_shortcut_enabling_service" msgid="7771852911861522636">"O atalho de acessibilidade ativou o <xliff:g id="SERVICE_NAME">%1$s</xliff:g>"</string>
     <string name="accessibility_shortcut_disabling_service" msgid="2747243438223109821">"O atalho de acessibilidade desativou o <xliff:g id="SERVICE_NAME">%1$s</xliff:g>"</string>
     <string name="accessibility_shortcut_spoken_feedback" msgid="8376923232350078434">"Toque nos dois botões de volume e os mantenha pressionados por três segundo para usar o <xliff:g id="SERVICE_NAME">%1$s</xliff:g>"</string>
-    <string name="accessibility_button_prompt_text" msgid="4234556536456854251">"Escolha um recurso a ser usado quando você toca no botão Acessibilidade:"</string>
-    <string name="accessibility_button_instructional_text" msgid="6942300463612999993">"Para alterar os recursos, mantenha o botão Acessibilidade pressionado."</string>
+    <string name="accessibility_button_prompt_text" msgid="1176658502969738564">"Escolha um serviço a ser usado quando você toca no botão Acessibilidade:"</string>
+    <string name="accessibility_gesture_prompt_text" msgid="8259145549733019401">"Escolha um serviço a ser usado com o gesto de acessibilidade (deslizar de baixo para cima na tela com dois dedos):"</string>
+    <string name="accessibility_gesture_3finger_prompt_text" msgid="1041435574275047665">"Escolha um serviço a ser usado com o gesto de acessibilidade (deslizar de baixo para cima na tela com três dedos):"</string>
+    <string name="accessibility_button_instructional_text" msgid="7003212763213614833">"Para alternar entre serviços, toque no botão de acessibilidade e mantenha-o pressionado."</string>
+    <string name="accessibility_gesture_instructional_text" msgid="5261788874937410950">"Para alternar entre serviços, deslize de baixo para cima na tela com dois dedos e mantenha-a pressionada."</string>
+    <string name="accessibility_gesture_3finger_instructional_text" msgid="4969448938984394550">"Para alternar entre serviços, deslize de baixo para cima na tela com três dedos e mantenha-a pressionada."</string>
     <string name="accessibility_magnification_chooser_text" msgid="1227146738764986237">"Ampliação"</string>
     <string name="user_switched" msgid="3768006783166984410">"Usuário atual <xliff:g id="NAME">%1$s</xliff:g>."</string>
     <string name="user_switching_message" msgid="2871009331809089783">"Alternando para <xliff:g id="NAME">%1$s</xliff:g>…"</string>
diff --git a/core/res/res/values-pt-rPT/strings.xml b/core/res/res/values-pt-rPT/strings.xml
index 5287600..c4ed32ed 100644
--- a/core/res/res/values-pt-rPT/strings.xml
+++ b/core/res/res/values-pt-rPT/strings.xml
@@ -131,6 +131,7 @@
     <!-- no translation found for wfcSpnFormat_spn (4998685024207291232) -->
     <skip />
     <string name="wfcSpnFormat_spn_wifi_calling" msgid="136001023263502280">"Chamadas Wi-Fi <xliff:g id="SPN">%s</xliff:g>"</string>
+    <string name="wfcSpnFormat_spn_wifi_calling_vo_hyphen" msgid="1730997175789582756">"Chamadas Wi-Fi de <xliff:g id="SPN">%s</xliff:g>"</string>
     <string name="wfcSpnFormat_wlan_call" msgid="2533371081782489793">"Chamada WLAN"</string>
     <string name="wfcSpnFormat_spn_wlan_call" msgid="2315240198303197168">"Chamada WLAN <xliff:g id="SPN">%s</xliff:g>"</string>
     <string name="wfcSpnFormat_spn_wifi" msgid="6546481665561961938">"Wi-Fi <xliff:g id="SPN">%s</xliff:g>"</string>
@@ -1357,8 +1358,7 @@
     <string name="test_harness_mode_notification_message" msgid="1343197173054407119">"Efetue uma reposição de dados de fábrica para desativar o Modo de estrutura de teste."</string>
     <string name="usb_contaminant_detected_title" msgid="7136400633704058349">"Líquido ou resíduos na porta USB"</string>
     <string name="usb_contaminant_detected_message" msgid="832337061059487250">"A porta USB é automaticamente desativada. Toque para saber mais."</string>
-    <!-- no translation found for usb_contaminant_not_detected_title (7708281124088684821) -->
-    <skip />
+    <string name="usb_contaminant_not_detected_title" msgid="7708281124088684821">"É seguro utilizar a porta USB"</string>
     <string name="usb_contaminant_not_detected_message" msgid="2415791798244545292">"O telemóvel já não deteta líquidos nem resíduos."</string>
     <string name="taking_remote_bugreport_notification_title" msgid="6742483073875060934">"A criar relatório de erro…"</string>
     <string name="share_remote_bugreport_notification_title" msgid="4987095013583691873">"Pretende partilhar o relatório de erro?"</string>
@@ -1612,8 +1612,6 @@
     <string name="display_manager_overlay_display_name" msgid="5142365982271620716">"Sobreposição #<xliff:g id="ID">%1$d</xliff:g>"</string>
     <string name="display_manager_overlay_display_title" msgid="652124517672257172">"<xliff:g id="NAME">%1$s</xliff:g>: <xliff:g id="WIDTH">%2$d</xliff:g>x<xliff:g id="HEIGHT">%3$d</xliff:g>, <xliff:g id="DPI">%4$d</xliff:g> ppp"</string>
     <string name="display_manager_overlay_display_secure_suffix" msgid="6022119702628572080">", protegido"</string>
-    <string name="activity_starter_block_bg_activity_starts_permissive" msgid="6995473033438879646">"Este início da atividade em segundo plano do pacote <xliff:g id="PACKAGENAME">%1$s</xliff:g> será bloqueado em compilações futuras do Q. Aceda a g.co/dev/bgblock."</string>
-    <string name="activity_starter_block_bg_activity_starts_enforcing" msgid="3317816771072146229">"Início da atividade em segundo plano do pacote <xliff:g id="PACKAGENAME">%1$s</xliff:g> bloqueado. Aceda a g.co/dev/bgblock."</string>
     <string name="kg_forgot_pattern_button_text" msgid="8852021467868220608">"Esqueceu-se da Sequência"</string>
     <string name="kg_wrong_pattern" msgid="1850806070801358830">"Padrão Incorreto"</string>
     <string name="kg_wrong_password" msgid="2333281762128113157">"Palavra-passe Incorreta"</string>
@@ -1667,8 +1665,12 @@
     <string name="accessibility_shortcut_enabling_service" msgid="7771852911861522636">"O Atalho de acessibilidade ativou o serviço <xliff:g id="SERVICE_NAME">%1$s</xliff:g>"</string>
     <string name="accessibility_shortcut_disabling_service" msgid="2747243438223109821">"O Atalho de acessibilidade desativou o serviço <xliff:g id="SERVICE_NAME">%1$s</xliff:g>"</string>
     <string name="accessibility_shortcut_spoken_feedback" msgid="8376923232350078434">"Prima sem soltar as teclas de volume durante três segundos para utilizar o serviço <xliff:g id="SERVICE_NAME">%1$s</xliff:g>."</string>
-    <string name="accessibility_button_prompt_text" msgid="4234556536456854251">"Escolha uma funcionalidade para utilizar quando tocar no botão Acessibilidade:"</string>
-    <string name="accessibility_button_instructional_text" msgid="6942300463612999993">"Para alterar as funcionalidades, toque sem soltar no botão Acessibilidade."</string>
+    <string name="accessibility_button_prompt_text" msgid="1176658502969738564">"Escolha o serviço a utilizar quando tocar no botão de acessibilidade:"</string>
+    <string name="accessibility_gesture_prompt_text" msgid="8259145549733019401">"Escolha o serviço a utilizar com o gesto de acessibilidade (deslize rapidamente com dois dedos para cima a partir da parte inferior do ecrã):"</string>
+    <string name="accessibility_gesture_3finger_prompt_text" msgid="1041435574275047665">"Escolha o serviço a utilizar com o gesto de acessibilidade (deslize rapidamente com três dedos para cima a partir da parte inferior do ecrã):"</string>
+    <string name="accessibility_button_instructional_text" msgid="7003212763213614833">"Para alternar entre serviços, toque sem soltar no botão de acessibilidade."</string>
+    <string name="accessibility_gesture_instructional_text" msgid="5261788874937410950">"Para alternar entre serviços, deslize rapidamente com dois dedos para cima sem soltar."</string>
+    <string name="accessibility_gesture_3finger_instructional_text" msgid="4969448938984394550">"Para alternar entre serviços, deslize rapidamente com três dedos para cima sem soltar."</string>
     <string name="accessibility_magnification_chooser_text" msgid="1227146738764986237">"Ampliação"</string>
     <string name="user_switched" msgid="3768006783166984410">"<xliff:g id="NAME">%1$s</xliff:g> do utilizador atual."</string>
     <string name="user_switching_message" msgid="2871009331809089783">"A mudar para <xliff:g id="NAME">%1$s</xliff:g>…"</string>
diff --git a/core/res/res/values-pt/strings.xml b/core/res/res/values-pt/strings.xml
index fbabb34..a8de75d1 100644
--- a/core/res/res/values-pt/strings.xml
+++ b/core/res/res/values-pt/strings.xml
@@ -131,6 +131,7 @@
     <!-- no translation found for wfcSpnFormat_spn (4998685024207291232) -->
     <skip />
     <string name="wfcSpnFormat_spn_wifi_calling" msgid="136001023263502280">"Chamada no Wi-Fi de <xliff:g id="SPN">%s</xliff:g>"</string>
+    <string name="wfcSpnFormat_spn_wifi_calling_vo_hyphen" msgid="1730997175789582756">"Chamada no Wi-Fi de <xliff:g id="SPN">%s</xliff:g>"</string>
     <string name="wfcSpnFormat_wlan_call" msgid="2533371081782489793">"Chamada por WLAN"</string>
     <string name="wfcSpnFormat_spn_wlan_call" msgid="2315240198303197168">"Chamada por WLAN de <xliff:g id="SPN">%s</xliff:g>"</string>
     <string name="wfcSpnFormat_spn_wifi" msgid="6546481665561961938">"Wi-Fi de <xliff:g id="SPN">%s</xliff:g>"</string>
@@ -1357,8 +1358,7 @@
     <string name="test_harness_mode_notification_message" msgid="1343197173054407119">"Realize uma redefinição para configuração original para desativar o modo Arcabouço de testes."</string>
     <string name="usb_contaminant_detected_title" msgid="7136400633704058349">"Líquido ou detrito na porta USB"</string>
     <string name="usb_contaminant_detected_message" msgid="832337061059487250">"A porta USB é desativada automaticamente. Toque para saber mais."</string>
-    <!-- no translation found for usb_contaminant_not_detected_title (7708281124088684821) -->
-    <skip />
+    <string name="usb_contaminant_not_detected_title" msgid="7708281124088684821">"É seguro usar a porta USB"</string>
     <string name="usb_contaminant_not_detected_message" msgid="2415791798244545292">"Não há mais líquidos ou detritos detectados no smartphone."</string>
     <string name="taking_remote_bugreport_notification_title" msgid="6742483073875060934">"Gerando relatório do bug..."</string>
     <string name="share_remote_bugreport_notification_title" msgid="4987095013583691873">"Compartilhar relatório do bug?"</string>
@@ -1494,7 +1494,7 @@
     <string name="find_next" msgid="5742124618942193978">"Localizar próximo"</string>
     <string name="find_previous" msgid="2196723669388360506">"Localizar anterior"</string>
     <string name="gpsNotifTicker" msgid="5622683912616496172">"Solicitação de local de <xliff:g id="NAME">%s</xliff:g>"</string>
-    <string name="gpsNotifTitle" msgid="5446858717157416839">"Solicitação de local"</string>
+    <string name="gpsNotifTitle" msgid="5446858717157416839">"Pedido de localização"</string>
     <string name="gpsNotifMessage" msgid="1374718023224000702">"Solicitado por <xliff:g id="NAME">%1$s</xliff:g> (<xliff:g id="SERVICE">%2$s</xliff:g>)"</string>
     <string name="gpsVerifYes" msgid="2346566072867213563">"Sim"</string>
     <string name="gpsVerifNo" msgid="1146564937346454865">"Não"</string>
@@ -1589,7 +1589,7 @@
     <string name="default_audio_route_name" product="tablet" msgid="4617053898167127471">"Tablet"</string>
     <string name="default_audio_route_name" product="tv" msgid="9158088547603019321">"TV"</string>
     <string name="default_audio_route_name" product="default" msgid="4239291273420140123">"Telefone"</string>
-    <string name="default_audio_route_name_dock_speakers" msgid="6240602982276591864">"Alto-falantes da dock"</string>
+    <string name="default_audio_route_name_dock_speakers" msgid="6240602982276591864">"Alto-falantes na base"</string>
     <string name="default_audio_route_name_hdmi" msgid="1486254205617081251">"HDMI"</string>
     <string name="default_audio_route_name_headphones" msgid="8119971843803439110">"Fones de ouvido"</string>
     <string name="default_audio_route_name_usb" msgid="1234984851352637769">"USB"</string>
@@ -1612,8 +1612,6 @@
     <string name="display_manager_overlay_display_name" msgid="5142365982271620716">"Sobreposição nº <xliff:g id="ID">%1$d</xliff:g>"</string>
     <string name="display_manager_overlay_display_title" msgid="652124517672257172">"<xliff:g id="NAME">%1$s</xliff:g>: <xliff:g id="WIDTH">%2$d</xliff:g>x<xliff:g id="HEIGHT">%3$d</xliff:g>, <xliff:g id="DPI">%4$d</xliff:g> dpi"</string>
     <string name="display_manager_overlay_display_secure_suffix" msgid="6022119702628572080">", seguro"</string>
-    <string name="activity_starter_block_bg_activity_starts_permissive" msgid="6995473033438879646">"Esse início de atividade em segundo plano a partir de <xliff:g id="PACKAGENAME">%1$s</xliff:g> será bloqueado nas versões futuras do Android Q. Acesse g.co/dev/bgblock."</string>
-    <string name="activity_starter_block_bg_activity_starts_enforcing" msgid="3317816771072146229">"O início da atividade em segundo plano a partir de <xliff:g id="PACKAGENAME">%1$s</xliff:g> foi bloqueado. Acesse g.co/dev/bgblock."</string>
     <string name="kg_forgot_pattern_button_text" msgid="8852021467868220608">"Esqueci o padrão"</string>
     <string name="kg_wrong_pattern" msgid="1850806070801358830">"Padrão incorreto"</string>
     <string name="kg_wrong_password" msgid="2333281762128113157">"Senha incorreta"</string>
@@ -1667,8 +1665,12 @@
     <string name="accessibility_shortcut_enabling_service" msgid="7771852911861522636">"O atalho de acessibilidade ativou o <xliff:g id="SERVICE_NAME">%1$s</xliff:g>"</string>
     <string name="accessibility_shortcut_disabling_service" msgid="2747243438223109821">"O atalho de acessibilidade desativou o <xliff:g id="SERVICE_NAME">%1$s</xliff:g>"</string>
     <string name="accessibility_shortcut_spoken_feedback" msgid="8376923232350078434">"Toque nos dois botões de volume e os mantenha pressionados por três segundo para usar o <xliff:g id="SERVICE_NAME">%1$s</xliff:g>"</string>
-    <string name="accessibility_button_prompt_text" msgid="4234556536456854251">"Escolha um recurso a ser usado quando você toca no botão Acessibilidade:"</string>
-    <string name="accessibility_button_instructional_text" msgid="6942300463612999993">"Para alterar os recursos, mantenha o botão Acessibilidade pressionado."</string>
+    <string name="accessibility_button_prompt_text" msgid="1176658502969738564">"Escolha um serviço a ser usado quando você toca no botão Acessibilidade:"</string>
+    <string name="accessibility_gesture_prompt_text" msgid="8259145549733019401">"Escolha um serviço a ser usado com o gesto de acessibilidade (deslizar de baixo para cima na tela com dois dedos):"</string>
+    <string name="accessibility_gesture_3finger_prompt_text" msgid="1041435574275047665">"Escolha um serviço a ser usado com o gesto de acessibilidade (deslizar de baixo para cima na tela com três dedos):"</string>
+    <string name="accessibility_button_instructional_text" msgid="7003212763213614833">"Para alternar entre serviços, toque no botão de acessibilidade e mantenha-o pressionado."</string>
+    <string name="accessibility_gesture_instructional_text" msgid="5261788874937410950">"Para alternar entre serviços, deslize de baixo para cima na tela com dois dedos e mantenha-a pressionada."</string>
+    <string name="accessibility_gesture_3finger_instructional_text" msgid="4969448938984394550">"Para alternar entre serviços, deslize de baixo para cima na tela com três dedos e mantenha-a pressionada."</string>
     <string name="accessibility_magnification_chooser_text" msgid="1227146738764986237">"Ampliação"</string>
     <string name="user_switched" msgid="3768006783166984410">"Usuário atual <xliff:g id="NAME">%1$s</xliff:g>."</string>
     <string name="user_switching_message" msgid="2871009331809089783">"Alternando para <xliff:g id="NAME">%1$s</xliff:g>…"</string>
diff --git a/core/res/res/values-ro/strings.xml b/core/res/res/values-ro/strings.xml
index bda936e..2a3a898 100644
--- a/core/res/res/values-ro/strings.xml
+++ b/core/res/res/values-ro/strings.xml
@@ -132,6 +132,7 @@
     <!-- no translation found for wfcSpnFormat_spn (4998685024207291232) -->
     <skip />
     <string name="wfcSpnFormat_spn_wifi_calling" msgid="136001023263502280">"Apelare prin Wi-Fi <xliff:g id="SPN">%s</xliff:g>"</string>
+    <string name="wfcSpnFormat_spn_wifi_calling_vo_hyphen" msgid="1730997175789582756">"Apelare prin Wi-Fi <xliff:g id="SPN">%s</xliff:g>"</string>
     <string name="wfcSpnFormat_wlan_call" msgid="2533371081782489793">"Apel WLAN"</string>
     <string name="wfcSpnFormat_spn_wlan_call" msgid="2315240198303197168">"Apel WLAN <xliff:g id="SPN">%s</xliff:g>"</string>
     <string name="wfcSpnFormat_spn_wifi" msgid="6546481665561961938">"Wi-Fi <xliff:g id="SPN">%s</xliff:g>"</string>
@@ -1379,8 +1380,7 @@
     <string name="test_harness_mode_notification_message" msgid="1343197173054407119">"Reveniți la setările din fabrică pentru a dezactiva modul Set de testare."</string>
     <string name="usb_contaminant_detected_title" msgid="7136400633704058349">"Lichide sau reziduuri în portul USB"</string>
     <string name="usb_contaminant_detected_message" msgid="832337061059487250">"Portul USB este dezactivat automat. Atingeți ca să aflați mai multe."</string>
-    <!-- no translation found for usb_contaminant_not_detected_title (7708281124088684821) -->
-    <skip />
+    <string name="usb_contaminant_not_detected_title" msgid="7708281124088684821">"Portul USB poate fi folosit"</string>
     <string name="usb_contaminant_not_detected_message" msgid="2415791798244545292">"Telefonul nu mai detectează lichide sau reziduuri."</string>
     <string name="taking_remote_bugreport_notification_title" msgid="6742483073875060934">"Se creează un raport de eroare…"</string>
     <string name="share_remote_bugreport_notification_title" msgid="4987095013583691873">"Trimiteți raportul de eroare?"</string>
@@ -1635,8 +1635,6 @@
     <string name="display_manager_overlay_display_name" msgid="5142365982271620716">"Suprapunerea <xliff:g id="ID">%1$d</xliff:g>"</string>
     <string name="display_manager_overlay_display_title" msgid="652124517672257172">"<xliff:g id="NAME">%1$s</xliff:g>: <xliff:g id="WIDTH">%2$d</xliff:g>x<xliff:g id="HEIGHT">%3$d</xliff:g>, <xliff:g id="DPI">%4$d</xliff:g> dpi"</string>
     <string name="display_manager_overlay_display_secure_suffix" msgid="6022119702628572080">", securizat"</string>
-    <string name="activity_starter_block_bg_activity_starts_permissive" msgid="6995473033438879646">"Începerea activității în fundal de la <xliff:g id="PACKAGENAME">%1$s</xliff:g> va fi blocată în versiunile Q viitoare. Consultați g.co/dev/bgblock."</string>
-    <string name="activity_starter_block_bg_activity_starts_enforcing" msgid="3317816771072146229">"Începerea activității din fundal de la <xliff:g id="PACKAGENAME">%1$s</xliff:g> este blocată. Consultați g.co/dev/bgblock."</string>
     <string name="kg_forgot_pattern_button_text" msgid="8852021467868220608">"Model uitat"</string>
     <string name="kg_wrong_pattern" msgid="1850806070801358830">"Model greșit"</string>
     <string name="kg_wrong_password" msgid="2333281762128113157">"Parolă greșită"</string>
@@ -1691,8 +1689,12 @@
     <string name="accessibility_shortcut_enabling_service" msgid="7771852911861522636">"Comanda rapidă de accesibilitate a activat <xliff:g id="SERVICE_NAME">%1$s</xliff:g>"</string>
     <string name="accessibility_shortcut_disabling_service" msgid="2747243438223109821">"Comanda rapidă de accesibilitate a dezactivat <xliff:g id="SERVICE_NAME">%1$s</xliff:g>"</string>
     <string name="accessibility_shortcut_spoken_feedback" msgid="8376923232350078434">"Apăsați ambele butoane de volum timp de trei secunde pentru a folosi <xliff:g id="SERVICE_NAME">%1$s</xliff:g>"</string>
-    <string name="accessibility_button_prompt_text" msgid="4234556536456854251">"Alegeți o funcție pe care să o folosiți când atingeți butonul Accesibilitate:"</string>
-    <string name="accessibility_button_instructional_text" msgid="6942300463612999993">"Pentru a schimba funcțiile, atingeți lung butonul Accesibilitate."</string>
+    <string name="accessibility_button_prompt_text" msgid="1176658502969738564">"Alegeți un serviciu pe care să îl folosiți când atingeți butonul de accesibilitate:"</string>
+    <string name="accessibility_gesture_prompt_text" msgid="8259145549733019401">"Alegeți un serviciu pe care să îl folosiți cu gestul de accesibilitate (glisați în sus cu două degete din partea de jos a ecranului):"</string>
+    <string name="accessibility_gesture_3finger_prompt_text" msgid="1041435574275047665">"Alegeți un serviciu pe care să îl folosiți cu gestul de accesibilitate (glisați în sus cu trei degete din partea de jos a ecranului):"</string>
+    <string name="accessibility_button_instructional_text" msgid="7003212763213614833">"Pentru a comuta între servicii, atingeți lung butonul de accesibilitate."</string>
+    <string name="accessibility_gesture_instructional_text" msgid="5261788874937410950">"Pentru a comuta între servicii, glisați în sus cu două degete și țineți lung."</string>
+    <string name="accessibility_gesture_3finger_instructional_text" msgid="4969448938984394550">"Pentru a comuta între servicii, glisați în sus cu trei degete și țineți lung."</string>
     <string name="accessibility_magnification_chooser_text" msgid="1227146738764986237">"Mărire"</string>
     <string name="user_switched" msgid="3768006783166984410">"Utilizator curent: <xliff:g id="NAME">%1$s</xliff:g>."</string>
     <string name="user_switching_message" msgid="2871009331809089783">"Se comută la <xliff:g id="NAME">%1$s</xliff:g>…"</string>
diff --git a/core/res/res/values-ru/strings.xml b/core/res/res/values-ru/strings.xml
index dc3a810..9fae441 100644
--- a/core/res/res/values-ru/strings.xml
+++ b/core/res/res/values-ru/strings.xml
@@ -133,6 +133,7 @@
     <!-- no translation found for wfcSpnFormat_spn (4998685024207291232) -->
     <skip />
     <string name="wfcSpnFormat_spn_wifi_calling" msgid="136001023263502280">"<xliff:g id="SPN">%s</xliff:g> Звонки по Wi-Fi"</string>
+    <string name="wfcSpnFormat_spn_wifi_calling_vo_hyphen" msgid="1730997175789582756">"Звонок по Wi-Fi через оператора \"<xliff:g id="SPN">%s</xliff:g>\""</string>
     <string name="wfcSpnFormat_wlan_call" msgid="2533371081782489793">"Вызов WLAN"</string>
     <string name="wfcSpnFormat_spn_wlan_call" msgid="2315240198303197168">"<xliff:g id="SPN">%s</xliff:g> Вызов WLAN"</string>
     <string name="wfcSpnFormat_spn_wifi" msgid="6546481665561961938">"<xliff:g id="SPN">%s</xliff:g> Wi-Fi"</string>
@@ -1401,8 +1402,7 @@
     <string name="test_harness_mode_notification_message" msgid="1343197173054407119">"Чтобы отключить тестовый режим, сбросьте настройки до заводских."</string>
     <string name="usb_contaminant_detected_title" msgid="7136400633704058349">"В USB-порт попала вода или грязь"</string>
     <string name="usb_contaminant_detected_message" msgid="832337061059487250">"USB-порт был автоматически отключен. Нажмите, чтобы узнать подробности."</string>
-    <!-- no translation found for usb_contaminant_not_detected_title (7708281124088684821) -->
-    <skip />
+    <string name="usb_contaminant_not_detected_title" msgid="7708281124088684821">"USB-порт можно использовать"</string>
     <string name="usb_contaminant_not_detected_message" msgid="2415791798244545292">"Вода или грязь внутри не обнаружена."</string>
     <string name="taking_remote_bugreport_notification_title" msgid="6742483073875060934">"Подготовка отчета об ошибке"</string>
     <string name="share_remote_bugreport_notification_title" msgid="4987095013583691873">"Разрешить доступ к информации об ошибке?"</string>
@@ -1658,8 +1658,6 @@
     <string name="display_manager_overlay_display_name" msgid="5142365982271620716">"Наложение № <xliff:g id="ID">%1$d</xliff:g>"</string>
     <string name="display_manager_overlay_display_title" msgid="652124517672257172">"<xliff:g id="NAME">%1$s</xliff:g>: <xliff:g id="WIDTH">%2$d</xliff:g> х <xliff:g id="HEIGHT">%3$d</xliff:g>, <xliff:g id="DPI">%4$d</xliff:g> тчк/дюйм"</string>
     <string name="display_manager_overlay_display_secure_suffix" msgid="6022119702628572080">", безопасный"</string>
-    <string name="activity_starter_block_bg_activity_starts_permissive" msgid="6995473033438879646">"Действия приложения \"<xliff:g id="PACKAGENAME">%1$s</xliff:g>\" в фоновом режиме будут блокироваться в следующих сборках Android Q. Подробную информацию можно найти на странице g.co/dev/bgblock."</string>
-    <string name="activity_starter_block_bg_activity_starts_enforcing" msgid="3317816771072146229">"Действие приложения \"<xliff:g id="PACKAGENAME">%1$s</xliff:g>\" в фоновом режиме заблокировано. Подробную информацию можно найти на странице g.co/dev/bgblock."</string>
     <string name="kg_forgot_pattern_button_text" msgid="8852021467868220608">"Забыли графический ключ?"</string>
     <string name="kg_wrong_pattern" msgid="1850806070801358830">"Неправильный графический ключ"</string>
     <string name="kg_wrong_password" msgid="2333281762128113157">"Неправильный пароль"</string>
@@ -1715,8 +1713,12 @@
     <string name="accessibility_shortcut_enabling_service" msgid="7771852911861522636">"Сервис <xliff:g id="SERVICE_NAME">%1$s</xliff:g> включен"</string>
     <string name="accessibility_shortcut_disabling_service" msgid="2747243438223109821">"Сервис <xliff:g id="SERVICE_NAME">%1$s</xliff:g> отключен"</string>
     <string name="accessibility_shortcut_spoken_feedback" msgid="8376923232350078434">"Чтобы использовать сервис \"<xliff:g id="SERVICE_NAME">%1$s</xliff:g>\", нажмите и удерживайте обе клавиши громкости в течение трех секунд."</string>
-    <string name="accessibility_button_prompt_text" msgid="4234556536456854251">"Выберите функцию, которая запускается при нажатии кнопки специальных возможностей:"</string>
-    <string name="accessibility_button_instructional_text" msgid="6942300463612999993">"Чтобы изменить функцию, удерживайте кнопку специальных возможностей."</string>
+    <string name="accessibility_button_prompt_text" msgid="1176658502969738564">"Выберите сервис, который будет запускаться при нажатии кнопки специальных возможностей:"</string>
+    <string name="accessibility_gesture_prompt_text" msgid="8259145549733019401">"Выберите сервис, который будет запускаться жестом для доступа к специальным возможностям (провести по экрану снизу вверх двумя пальцами):"</string>
+    <string name="accessibility_gesture_3finger_prompt_text" msgid="1041435574275047665">"Выберите сервис, который будет запускаться жестом для доступа к специальным возможностям (провести по экрану снизу вверх тремя пальцами):"</string>
+    <string name="accessibility_button_instructional_text" msgid="7003212763213614833">"Для переключения между сервисами нажмите и удерживайте кнопку специальных возможностей."</string>
+    <string name="accessibility_gesture_instructional_text" msgid="5261788874937410950">"Для переключения между сервисами проведите по экрану снизу вверх двумя пальцами и задержите их."</string>
+    <string name="accessibility_gesture_3finger_instructional_text" msgid="4969448938984394550">"Для переключения между сервисами проведите по экрану снизу вверх тремя пальцами и задержите их."</string>
     <string name="accessibility_magnification_chooser_text" msgid="1227146738764986237">"Увеличение"</string>
     <string name="user_switched" msgid="3768006783166984410">"Выбран аккаунт пользователя <xliff:g id="NAME">%1$s</xliff:g>."</string>
     <string name="user_switching_message" msgid="2871009331809089783">"Смена профиля на <xliff:g id="NAME">%1$s</xliff:g>…"</string>
diff --git a/core/res/res/values-si/strings.xml b/core/res/res/values-si/strings.xml
index 8e7beac..4b41f9a 100644
--- a/core/res/res/values-si/strings.xml
+++ b/core/res/res/values-si/strings.xml
@@ -131,6 +131,7 @@
     <!-- no translation found for wfcSpnFormat_spn (4998685024207291232) -->
     <skip />
     <string name="wfcSpnFormat_spn_wifi_calling" msgid="136001023263502280">"<xliff:g id="SPN">%s</xliff:g> Wi-Fi ඇමතුම්"</string>
+    <string name="wfcSpnFormat_spn_wifi_calling_vo_hyphen" msgid="1730997175789582756">"<xliff:g id="SPN">%s</xliff:g> WiFi ඇමතුම"</string>
     <string name="wfcSpnFormat_wlan_call" msgid="2533371081782489793">"WLAN ඇමතුම"</string>
     <string name="wfcSpnFormat_spn_wlan_call" msgid="2315240198303197168">"<xliff:g id="SPN">%s</xliff:g> WLAN ඇමතුම්"</string>
     <string name="wfcSpnFormat_spn_wifi" msgid="6546481665561961938">"<xliff:g id="SPN">%s</xliff:g> Wi-Fi"</string>
@@ -1613,8 +1614,6 @@
     <string name="display_manager_overlay_display_name" msgid="5142365982271620716">"උඩැතිරිය #<xliff:g id="ID">%1$d</xliff:g>"</string>
     <string name="display_manager_overlay_display_title" msgid="652124517672257172">"<xliff:g id="NAME">%1$s</xliff:g>: <xliff:g id="WIDTH">%2$d</xliff:g>x<xliff:g id="HEIGHT">%3$d</xliff:g>, <xliff:g id="DPI">%4$d</xliff:g> dpi"</string>
     <string name="display_manager_overlay_display_secure_suffix" msgid="6022119702628572080">", ආරක්‍ෂිත"</string>
-    <string name="activity_starter_block_bg_activity_starts_permissive" msgid="6995473033438879646">"<xliff:g id="PACKAGENAME">%1$s</xliff:g> සිට ඇරඹෙන මෙම පසුබිම් ක්‍රියාකාරකම අනාගත Q නිමැවුම්වල අවහිර කෙරේ. g.co/dev/bgblock බලන්න."</string>
-    <string name="activity_starter_block_bg_activity_starts_enforcing" msgid="3317816771072146229">"<xliff:g id="PACKAGENAME">%1$s</xliff:g> සිට ඇරඹෙන පසුබිම් ක්‍රියාකාරකම අවහිරයි. g.co/dev/bgblock බලන්න."</string>
     <string name="kg_forgot_pattern_button_text" msgid="8852021467868220608">"රටාව අමතකයි"</string>
     <string name="kg_wrong_pattern" msgid="1850806070801358830">"වැරදි රටාවකි"</string>
     <string name="kg_wrong_password" msgid="2333281762128113157">"වැරදි මුරපදය"</string>
@@ -1668,8 +1667,12 @@
     <string name="accessibility_shortcut_enabling_service" msgid="7771852911861522636">"ප්‍රවේශ්‍යතා කෙටි මග <xliff:g id="SERVICE_NAME">%1$s</xliff:g> ක්‍රියාත්මක කරන ලදී"</string>
     <string name="accessibility_shortcut_disabling_service" msgid="2747243438223109821">"ප්‍රවේශ්‍යතා කෙටි මග <xliff:g id="SERVICE_NAME">%1$s</xliff:g> ක්‍රියාවිරහිත කරන ලදී"</string>
     <string name="accessibility_shortcut_spoken_feedback" msgid="8376923232350078434">"<xliff:g id="SERVICE_NAME">%1$s</xliff:g> භාවිත කිරීමට හඬ පරිමා යතුරු දෙකම තත්පර තුනකට ඔබාගෙන සිටින්න"</string>
-    <string name="accessibility_button_prompt_text" msgid="4234556536456854251">"ඔබ ප්‍රවේශ්‍යතා බොත්තම තට්ටු කරන විට භාවිතා කිරීමට අංගයක් තෝරාගන්න:"</string>
-    <string name="accessibility_button_instructional_text" msgid="6942300463612999993">"අංග වෙනස් කිරීමට ප්‍රවේශ්‍යතා බොත්තම ස්පර්ශ කර අල්ලා ගෙන සිටින්න."</string>
+    <string name="accessibility_button_prompt_text" msgid="1176658502969738564">"ඔබ ප්‍රවේශ්‍යතා බොත්තම තට්ටු කරන විට භාවිතයට සේවාවක් තෝරා ගන්න:"</string>
+    <string name="accessibility_gesture_prompt_text" msgid="8259145549733019401">"ප්‍රවේශ්‍යතා ඉංගිතය සමඟ භාවිතයට සේවාවක් තෝරා ගන්න (ඇඟිලි දෙකක් සමඟින් තිරයේ පහළින් උඩට ස්වයිප් කරන්න):"</string>
+    <string name="accessibility_gesture_3finger_prompt_text" msgid="1041435574275047665">"ප්‍රවේශ්‍යතා ඉංගිතය සමඟ භාවිතයට සේවාවක් තෝරා ගන්න (ඇඟිලි තුනක් සමඟින් තිරයේ පහළින් උඩට ස්වයිප් කරන්න):"</string>
+    <string name="accessibility_button_instructional_text" msgid="7003212763213614833">"සේවා අතර මාරු වීමට, ප්‍රවේශ්‍යතා බොත්තම ස්පර්ශ කර අල්ලා සිටින්න."</string>
+    <string name="accessibility_gesture_instructional_text" msgid="5261788874937410950">"සේවා අතර මාරු වීමට, ඇඟිලි දෙකක් සමඟින් උඩට ස්වයිප් කර අල්ලා සිටින්න."</string>
+    <string name="accessibility_gesture_3finger_instructional_text" msgid="4969448938984394550">"සේවා අතර මාරු වීමට, ඇඟිලි තුනක් සමඟින් උඩට ස්වයිප් කර අල්ලා සිටින්න."</string>
     <string name="accessibility_magnification_chooser_text" msgid="1227146738764986237">"විශාලනය"</string>
     <string name="user_switched" msgid="3768006783166984410">"දැනට සිටින පරිශීලකයා <xliff:g id="NAME">%1$s</xliff:g>."</string>
     <string name="user_switching_message" msgid="2871009331809089783">"<xliff:g id="NAME">%1$s</xliff:g> වෙත මාරු කරමින්…"</string>
diff --git a/core/res/res/values-sk/strings.xml b/core/res/res/values-sk/strings.xml
index 222d648..c79fe52 100644
--- a/core/res/res/values-sk/strings.xml
+++ b/core/res/res/values-sk/strings.xml
@@ -133,6 +133,7 @@
     <!-- no translation found for wfcSpnFormat_spn (4998685024207291232) -->
     <skip />
     <string name="wfcSpnFormat_spn_wifi_calling" msgid="136001023263502280">"<xliff:g id="SPN">%s</xliff:g> volanie cez Wi-Fi"</string>
+    <string name="wfcSpnFormat_spn_wifi_calling_vo_hyphen" msgid="1730997175789582756">"<xliff:g id="SPN">%s</xliff:g> Volanie cez Wi‑Fi"</string>
     <string name="wfcSpnFormat_wlan_call" msgid="2533371081782489793">"Volanie cez WLAN"</string>
     <string name="wfcSpnFormat_spn_wlan_call" msgid="2315240198303197168">"<xliff:g id="SPN">%s</xliff:g> volanie cez WLAN"</string>
     <string name="wfcSpnFormat_spn_wifi" msgid="6546481665561961938">"<xliff:g id="SPN">%s</xliff:g> Wi-Fi"</string>
@@ -301,7 +302,7 @@
     <string name="permgrouprequest_storage" msgid="7885942926944299560">"Povoliť aplikácii &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; používať fotky, médiá a súbory v zariadení?"</string>
     <string name="permgrouplab_microphone" msgid="171539900250043464">"Mikrofón"</string>
     <string name="permgroupdesc_microphone" msgid="4988812113943554584">"nahrávanie zvuku"</string>
-    <string name="permgrouprequest_microphone" msgid="9167492350681916038">"Povoliť aplikácii &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; zaznamenávať zvuk?"</string>
+    <string name="permgrouprequest_microphone" msgid="9167492350681916038">"Chcete povoliť aplikácii &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; nahrávať zvuk?"</string>
     <string name="permgrouplab_activityRecognition" msgid="1565108047054378642">"Fyzická aktivita"</string>
     <string name="permgroupdesc_activityRecognition" msgid="6949472038320473478">"prístup k vašej fyzickej aktivite"</string>
     <string name="permgrouprequest_activityRecognition" msgid="7626438016904799383">"Povoliť aplikácii &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; prístup k vašej fyzickej aktivite?"</string>
@@ -430,7 +431,7 @@
     <string name="permlab_modifyAudioSettings" msgid="6095859937069146086">"meniť nastavenia zvuku"</string>
     <string name="permdesc_modifyAudioSettings" msgid="3522565366806248517">"Umožňuje aplikácii upraviť globálne nastavenia zvuku, ako je hlasitosť, alebo určiť, z ktorého reproduktora bude zvuk vychádzať."</string>
     <string name="permlab_recordAudio" msgid="3876049771427466323">"nahrávať zvuk"</string>
-    <string name="permdesc_recordAudio" msgid="4245930455135321433">"Táto aplikácia môže kedykoľvek zaznamenávať zvuk pomocou mikrofónu."</string>
+    <string name="permdesc_recordAudio" msgid="4245930455135321433">"Táto aplikácia môže kedykoľvek nahrávať zvuk pomocou mikrofónu."</string>
     <string name="permlab_sim_communication" msgid="2935852302216852065">"posielanie príkazov do SIM karty"</string>
     <string name="permdesc_sim_communication" msgid="5725159654279639498">"Umožňuje aplikácii odosielať príkazy na SIM kartu. Toto je veľmi nebezpečné povolenie."</string>
     <string name="permlab_activityRecognition" msgid="3634590230567608356">"rozpoznávanie fyzickej aktivity"</string>
@@ -1401,8 +1402,7 @@
     <string name="test_harness_mode_notification_message" msgid="1343197173054407119">"Ak chcete zakázať režim správcu testov, obnovte výrobné nastavenia."</string>
     <string name="usb_contaminant_detected_title" msgid="7136400633704058349">"Tekutina alebo nečistoty v porte USB"</string>
     <string name="usb_contaminant_detected_message" msgid="832337061059487250">"Port USB je automaticky deaktivovaný. Ďalšie informácie zobrazíte klepnutím."</string>
-    <!-- no translation found for usb_contaminant_not_detected_title (7708281124088684821) -->
-    <skip />
+    <string name="usb_contaminant_not_detected_title" msgid="7708281124088684821">"Port USB môžete použiť"</string>
     <string name="usb_contaminant_not_detected_message" msgid="2415791798244545292">"Telefón už nerozpoznáva tekutinu ani nečistoty."</string>
     <string name="taking_remote_bugreport_notification_title" msgid="6742483073875060934">"Preberá sa hlásenie chyby…"</string>
     <string name="share_remote_bugreport_notification_title" msgid="4987095013583691873">"Chcete zdieľať hlásenie chyby?"</string>
@@ -1540,7 +1540,7 @@
     <string name="find_next" msgid="5742124618942193978">"Nájsť ďalšiu"</string>
     <string name="find_previous" msgid="2196723669388360506">"Nájsť predchádzajúcu"</string>
     <string name="gpsNotifTicker" msgid="5622683912616496172">"Žiadosť o informácie o polohe od používateľa <xliff:g id="NAME">%s</xliff:g>"</string>
-    <string name="gpsNotifTitle" msgid="5446858717157416839">"Žiadosť o informácie o polohe"</string>
+    <string name="gpsNotifTitle" msgid="5446858717157416839">"Žiadosť o informácie o polohe"</string>
     <string name="gpsNotifMessage" msgid="1374718023224000702">"Žiadosť od používateľa <xliff:g id="NAME">%1$s</xliff:g> (<xliff:g id="SERVICE">%2$s</xliff:g>)"</string>
     <string name="gpsVerifYes" msgid="2346566072867213563">"Áno"</string>
     <string name="gpsVerifNo" msgid="1146564937346454865">"Nie"</string>
@@ -1581,7 +1581,7 @@
     <string name="activitychooserview_choose_application_error" msgid="8624618365481126668">"Aplikáciu <xliff:g id="APPLICATION_NAME">%s</xliff:g> nie je možné spustiť"</string>
     <string name="shareactionprovider_share_with" msgid="806688056141131819">"Zdieľať s"</string>
     <string name="shareactionprovider_share_with_application" msgid="5627411384638389738">"Zdieľať s aplikáciou <xliff:g id="APPLICATION_NAME">%s</xliff:g>"</string>
-    <string name="content_description_sliding_handle" msgid="415975056159262248">"Posuvné tlačidlo. Dotknite sa a podržte."</string>
+    <string name="content_description_sliding_handle" msgid="415975056159262248">"Posuvník. Pridržte."</string>
     <string name="description_target_unlock_tablet" msgid="3833195335629795055">"Posunom odomknúť."</string>
     <string name="action_bar_home_description" msgid="5293600496601490216">"Prejsť na plochu"</string>
     <string name="action_bar_up_description" msgid="2237496562952152589">"Prejsť na"</string>
@@ -1658,8 +1658,6 @@
     <string name="display_manager_overlay_display_name" msgid="5142365982271620716">"Prekrytie č. <xliff:g id="ID">%1$d</xliff:g>"</string>
     <string name="display_manager_overlay_display_title" msgid="652124517672257172">"<xliff:g id="NAME">%1$s</xliff:g>: <xliff:g id="WIDTH">%2$d</xliff:g> x <xliff:g id="HEIGHT">%3$d</xliff:g>, <xliff:g id="DPI">%4$d</xliff:g> dpi"</string>
     <string name="display_manager_overlay_display_secure_suffix" msgid="6022119702628572080">", zabezpečené"</string>
-    <string name="activity_starter_block_bg_activity_starts_permissive" msgid="6995473033438879646">"Toto spustenie aktivity na pozadí v režime <xliff:g id="PACKAGENAME">%1$s</xliff:g> bude blokované v budúcich zostavách Q. Pozrite si informácie na g.co/dev/bgblock."</string>
-    <string name="activity_starter_block_bg_activity_starts_enforcing" msgid="3317816771072146229">"Spustenie aktivity na pozadí v režime <xliff:g id="PACKAGENAME">%1$s</xliff:g> je blokované. Pozrite si informácie na g.co/dev/bgblock."</string>
     <string name="kg_forgot_pattern_button_text" msgid="8852021467868220608">"Nepamätám si vzor"</string>
     <string name="kg_wrong_pattern" msgid="1850806070801358830">"Nesprávny vzor"</string>
     <string name="kg_wrong_password" msgid="2333281762128113157">"Nesprávne heslo"</string>
@@ -1715,8 +1713,12 @@
     <string name="accessibility_shortcut_enabling_service" msgid="7771852911861522636">"Skratka dostupnosti zapla službu <xliff:g id="SERVICE_NAME">%1$s</xliff:g>"</string>
     <string name="accessibility_shortcut_disabling_service" msgid="2747243438223109821">"Skratka dostupnosti vypla službu <xliff:g id="SERVICE_NAME">%1$s</xliff:g>"</string>
     <string name="accessibility_shortcut_spoken_feedback" msgid="8376923232350078434">"Ak chcete používať službu <xliff:g id="SERVICE_NAME">%1$s</xliff:g>, pridržte tri sekundy oba klávesy hlasitosti"</string>
-    <string name="accessibility_button_prompt_text" msgid="4234556536456854251">"Klepnutím na tlačidlo dostupnosti vyberte požadovanú funkciu:"</string>
-    <string name="accessibility_button_instructional_text" msgid="6942300463612999993">"Ak chcete zmeniť funkcie, klepnite na tlačidlo dostupnosti a podržte ho"</string>
+    <string name="accessibility_button_prompt_text" msgid="1176658502969738564">"Vyberte službu, ktorú chcete používať po klepnutí na tlačidlo dostupnosti:"</string>
+    <string name="accessibility_gesture_prompt_text" msgid="8259145549733019401">"Vyberte službu, ktorú chcete používať s daným gestom dostupnosti (potiahnutím dvoma prstami z dolnej časti obrazovky smerom nahor):"</string>
+    <string name="accessibility_gesture_3finger_prompt_text" msgid="1041435574275047665">"Vyberte službu, ktorú chcete používať s daným gestom dostupnosti (potiahnutím troma prstami z dolnej časti obrazovky smerom nahor):"</string>
+    <string name="accessibility_button_instructional_text" msgid="7003212763213614833">"Služby prepnete pridržaním tlačidla dostupnosti."</string>
+    <string name="accessibility_gesture_instructional_text" msgid="5261788874937410950">"Služby prepnete potiahnutím dvoma prstami smerom nahor a pridržaním."</string>
+    <string name="accessibility_gesture_3finger_instructional_text" msgid="4969448938984394550">"Služby prepnete potiahnutím troma prstami smerom nahor a pridržaním."</string>
     <string name="accessibility_magnification_chooser_text" msgid="1227146738764986237">"Priblíženie"</string>
     <string name="user_switched" msgid="3768006783166984410">"Aktuálny používateľ je <xliff:g id="NAME">%1$s</xliff:g>."</string>
     <string name="user_switching_message" msgid="2871009331809089783">"Prepína sa na účet <xliff:g id="NAME">%1$s</xliff:g>…"</string>
diff --git a/core/res/res/values-sl/strings.xml b/core/res/res/values-sl/strings.xml
index c8e3a9d..f1dc25e 100644
--- a/core/res/res/values-sl/strings.xml
+++ b/core/res/res/values-sl/strings.xml
@@ -133,6 +133,7 @@
     <!-- no translation found for wfcSpnFormat_spn (4998685024207291232) -->
     <skip />
     <string name="wfcSpnFormat_spn_wifi_calling" msgid="136001023263502280">"Klicanje prek Wi-Fi-ja operaterja <xliff:g id="SPN">%s</xliff:g>"</string>
+    <string name="wfcSpnFormat_spn_wifi_calling_vo_hyphen" msgid="1730997175789582756">"Klicanje prek Wi‑Fi-ja pri operaterju <xliff:g id="SPN">%s</xliff:g>"</string>
     <string name="wfcSpnFormat_wlan_call" msgid="2533371081782489793">"Klic prek omrežja WLAN"</string>
     <string name="wfcSpnFormat_spn_wlan_call" msgid="2315240198303197168">"Klic prek omrežja WLAN operaterja <xliff:g id="SPN">%s</xliff:g>"</string>
     <string name="wfcSpnFormat_spn_wifi" msgid="6546481665561961938">"Wi-Fi operaterja <xliff:g id="SPN">%s</xliff:g>"</string>
@@ -1401,8 +1402,7 @@
     <string name="test_harness_mode_notification_message" msgid="1343197173054407119">"Če želite onemogočiti način preizkusnega ogrodja, ponastavite napravo na tovarniške nastavitve."</string>
     <string name="usb_contaminant_detected_title" msgid="7136400633704058349">"V vratih USB je tekočina ali umazanija"</string>
     <string name="usb_contaminant_detected_message" msgid="832337061059487250">"Vrata USB so samodejno onemogočena. Dotaknite se, če želite izvedeti več."</string>
-    <!-- no translation found for usb_contaminant_not_detected_title (7708281124088684821) -->
-    <skip />
+    <string name="usb_contaminant_not_detected_title" msgid="7708281124088684821">"Vrata USB so varna za uporabo"</string>
     <string name="usb_contaminant_not_detected_message" msgid="2415791798244545292">"Telefon ne zaznava več tekočine ali umazanije."</string>
     <string name="taking_remote_bugreport_notification_title" msgid="6742483073875060934">"Zajemanje poročila o napakah …"</string>
     <string name="share_remote_bugreport_notification_title" msgid="4987095013583691873">"Želite poslati poročilo o napakah?"</string>
@@ -1658,8 +1658,6 @@
     <string name="display_manager_overlay_display_name" msgid="5142365982271620716">"Prekrivanje #<xliff:g id="ID">%1$d</xliff:g>"</string>
     <string name="display_manager_overlay_display_title" msgid="652124517672257172">"<xliff:g id="NAME">%1$s</xliff:g>: <xliff:g id="WIDTH">%2$d</xliff:g> x <xliff:g id="HEIGHT">%3$d</xliff:g>, <xliff:g id="DPI">%4$d</xliff:g> pik na palec"</string>
     <string name="display_manager_overlay_display_secure_suffix" msgid="6022119702628572080">", varen"</string>
-    <string name="activity_starter_block_bg_activity_starts_permissive" msgid="6995473033438879646">"Ta zagon dejavnosti v ozadju za paket <xliff:g id="PACKAGENAME">%1$s</xliff:g> bo blokiran v prihodnjih različicah Androida Q. Za več informacij obiščite g.co/dev/bgblock."</string>
-    <string name="activity_starter_block_bg_activity_starts_enforcing" msgid="3317816771072146229">"Zagon dejavnosti v ozadju za paket <xliff:g id="PACKAGENAME">%1$s</xliff:g> je bil blokiran. Za več informacij obiščite g.co/dev/bgblock."</string>
     <string name="kg_forgot_pattern_button_text" msgid="8852021467868220608">"Pozabljen vzorec"</string>
     <string name="kg_wrong_pattern" msgid="1850806070801358830">"Napačen vzorec"</string>
     <string name="kg_wrong_password" msgid="2333281762128113157">"Napačno geslo"</string>
@@ -1715,8 +1713,12 @@
     <string name="accessibility_shortcut_enabling_service" msgid="7771852911861522636">"Bližnjica funkcij za ljudi s posebnimi potrebami je vklopila <xliff:g id="SERVICE_NAME">%1$s</xliff:g>"</string>
     <string name="accessibility_shortcut_disabling_service" msgid="2747243438223109821">"Bližnjica funkcij za ljudi s posebnimi potrebami je izklopila <xliff:g id="SERVICE_NAME">%1$s</xliff:g>"</string>
     <string name="accessibility_shortcut_spoken_feedback" msgid="8376923232350078434">"Za uporabo storitve <xliff:g id="SERVICE_NAME">%1$s</xliff:g> pritisnite obe tipki za glasnost in ju pridržite tri sekunde"</string>
-    <string name="accessibility_button_prompt_text" msgid="4234556536456854251">"Izberite funkcijo, ki jo želite uporabljati, ko se dotaknete gumba »Dostopnost«:"</string>
-    <string name="accessibility_button_instructional_text" msgid="6942300463612999993">"Če želite spremeniti funkcije, se dotaknite gumba »Dostopnost« in ga pridržite."</string>
+    <string name="accessibility_button_prompt_text" msgid="1176658502969738564">"Izberite storitev, ki jo želite uporabljati, ko se dotaknete gumba za funkcije za ljudi s posebnimi potrebami:"</string>
+    <string name="accessibility_gesture_prompt_text" msgid="8259145549733019401">"Izberite storitev, ki jo želite zagnati s potezo za ljudi s posebnimi potrebami (vlečenje z dvema prstoma z dna zaslona navzgor):"</string>
+    <string name="accessibility_gesture_3finger_prompt_text" msgid="1041435574275047665">"Izberite storitev, ki jo želite zagnati s potezo za ljudi s posebnimi potrebami (vlečenje s tremi prsti z dna zaslona navzgor):"</string>
+    <string name="accessibility_button_instructional_text" msgid="7003212763213614833">"Če želite preklopiti med storitvami, pridržite gumb za funkcije za ljudi s posebnimi potrebami."</string>
+    <string name="accessibility_gesture_instructional_text" msgid="5261788874937410950">"Če želite preklopiti med storitvami, z dvema prstoma povlecite navzgor in pridržite."</string>
+    <string name="accessibility_gesture_3finger_instructional_text" msgid="4969448938984394550">"Če želite preklopiti med storitvami, s tremi prsti povlecite navzgor in pridržite."</string>
     <string name="accessibility_magnification_chooser_text" msgid="1227146738764986237">"Povečava"</string>
     <string name="user_switched" msgid="3768006783166984410">"Trenutni uporabnik <xliff:g id="NAME">%1$s</xliff:g>."</string>
     <string name="user_switching_message" msgid="2871009331809089783">"Preklop na uporabnika <xliff:g id="NAME">%1$s</xliff:g> …"</string>
diff --git a/core/res/res/values-sq/strings.xml b/core/res/res/values-sq/strings.xml
index 72ee396..0a9cebe 100644
--- a/core/res/res/values-sq/strings.xml
+++ b/core/res/res/values-sq/strings.xml
@@ -131,6 +131,7 @@
     <!-- no translation found for wfcSpnFormat_spn (4998685024207291232) -->
     <skip />
     <string name="wfcSpnFormat_spn_wifi_calling" msgid="136001023263502280">"Telefonatë me Wi-Fi në <xliff:g id="SPN">%s</xliff:g>"</string>
+    <string name="wfcSpnFormat_spn_wifi_calling_vo_hyphen" msgid="1730997175789582756">"Telefonatat me WiFi me <xliff:g id="SPN">%s</xliff:g>"</string>
     <string name="wfcSpnFormat_wlan_call" msgid="2533371081782489793">"Telefonatë me WLAN"</string>
     <string name="wfcSpnFormat_spn_wlan_call" msgid="2315240198303197168">"Telefonatë me WLAN në <xliff:g id="SPN">%s</xliff:g>"</string>
     <string name="wfcSpnFormat_spn_wifi" msgid="6546481665561961938">"Wi-Fi në <xliff:g id="SPN">%s</xliff:g>"</string>
@@ -1358,8 +1359,7 @@
     <string name="test_harness_mode_notification_message" msgid="1343197173054407119">"Kryej një rivendosje në cilësimet e fabrikës për të çaktivizuar \"Modalitetin e lidhjes së testimit\"."</string>
     <string name="usb_contaminant_detected_title" msgid="7136400633704058349">"Lëngje ose papastërti në portën e USB-së"</string>
     <string name="usb_contaminant_detected_message" msgid="832337061059487250">"Porta e USB-së është çaktivizuar automatikisht. Trokit për të mësuar më shumë."</string>
-    <!-- no translation found for usb_contaminant_not_detected_title (7708281124088684821) -->
-    <skip />
+    <string name="usb_contaminant_not_detected_title" msgid="7708281124088684821">"Në rregulloj për përdorimin e portës USB"</string>
     <string name="usb_contaminant_not_detected_message" msgid="2415791798244545292">"Telefoni nuk i dallon më lëngjet apo papastërtitë."</string>
     <string name="taking_remote_bugreport_notification_title" msgid="6742483073875060934">"Po merret raporti i defekteve në kod…"</string>
     <string name="share_remote_bugreport_notification_title" msgid="4987095013583691873">"Të ndahet raporti i defektit në kod?"</string>
@@ -1613,8 +1613,6 @@
     <string name="display_manager_overlay_display_name" msgid="5142365982271620716">"Mbivendosja #<xliff:g id="ID">%1$d</xliff:g>"</string>
     <string name="display_manager_overlay_display_title" msgid="652124517672257172">"<xliff:g id="NAME">%1$s</xliff:g>: <xliff:g id="WIDTH">%2$d</xliff:g>x<xliff:g id="HEIGHT">%3$d</xliff:g>, <xliff:g id="DPI">%4$d</xliff:g> ppi"</string>
     <string name="display_manager_overlay_display_secure_suffix" msgid="6022119702628572080">", i sigurt"</string>
-    <string name="activity_starter_block_bg_activity_starts_permissive" msgid="6995473033438879646">"Kjo nisje e aktivitetit në sfond nga <xliff:g id="PACKAGENAME">%1$s</xliff:g> do të bllokohet në ndërtimet e ardhshme të Q. Shiko g.co/dev/bgblock."</string>
-    <string name="activity_starter_block_bg_activity_starts_enforcing" msgid="3317816771072146229">"Nisja e aktivitetit në sfond nga <xliff:g id="PACKAGENAME">%1$s</xliff:g> u bllokua. Shiko g.co/dev/bgblock."</string>
     <string name="kg_forgot_pattern_button_text" msgid="8852021467868220608">"Harrova motivin"</string>
     <string name="kg_wrong_pattern" msgid="1850806070801358830">"Motivi është i gabuar"</string>
     <string name="kg_wrong_password" msgid="2333281762128113157">"Fjalëkalim i gabuar"</string>
@@ -1668,8 +1666,12 @@
     <string name="accessibility_shortcut_enabling_service" msgid="7771852911861522636">"Shkurtorja e qasshmërisë e aktivizoi <xliff:g id="SERVICE_NAME">%1$s</xliff:g>"</string>
     <string name="accessibility_shortcut_disabling_service" msgid="2747243438223109821">"Shkurtorja e qasshmërisë e çaktivizoi <xliff:g id="SERVICE_NAME">%1$s</xliff:g>"</string>
     <string name="accessibility_shortcut_spoken_feedback" msgid="8376923232350078434">"Shtyp dhe mbaj shtypur të dy butonat e volumit për tre sekonda për të përdorur <xliff:g id="SERVICE_NAME">%1$s</xliff:g>"</string>
-    <string name="accessibility_button_prompt_text" msgid="4234556536456854251">"Zgjidh një funksion për ta përdorur kur troket butonin e \"Qasshmërisë\":"</string>
-    <string name="accessibility_button_instructional_text" msgid="6942300463612999993">"Për të ndryshuar funksionet, prek dhe mbaj butonin e \"Qasshmërisë\"."</string>
+    <string name="accessibility_button_prompt_text" msgid="1176658502969738564">"Zgjidh një shërbim për ta përdorur kur troket butonin e qasshmërisë:"</string>
+    <string name="accessibility_gesture_prompt_text" msgid="8259145549733019401">"Zgjidh një shërbim për ta përdorur me gjestin e qasshmërisë (rrëshqit shpejt lart nga fundi i ekranit me dy gishta):"</string>
+    <string name="accessibility_gesture_3finger_prompt_text" msgid="1041435574275047665">"Zgjidh një shërbim për ta përdorur me gjestin e qasshmërisë (rrëshqit shpejt lart nga fundi i ekranit me tre gishta):"</string>
+    <string name="accessibility_button_instructional_text" msgid="7003212763213614833">"Për të kaluar mes shërbimeve, prek dhe mbaj prekur butonin e qasshmërisë."</string>
+    <string name="accessibility_gesture_instructional_text" msgid="5261788874937410950">"Për të kaluar mes pajisjeve, rrëshqit shpejt lart me dy gishta dhe mbaje prekur."</string>
+    <string name="accessibility_gesture_3finger_instructional_text" msgid="4969448938984394550">"Për të kaluar mes pajisjeve, rrëshqit shpejt lart me tre gishta dhe mbaje prekur."</string>
     <string name="accessibility_magnification_chooser_text" msgid="1227146738764986237">"Zmadhimi"</string>
     <string name="user_switched" msgid="3768006783166984410">"Emri i përdoruesit aktual: <xliff:g id="NAME">%1$s</xliff:g>"</string>
     <string name="user_switching_message" msgid="2871009331809089783">"Po kalon në <xliff:g id="NAME">%1$s</xliff:g>…"</string>
diff --git a/core/res/res/values-sr/strings.xml b/core/res/res/values-sr/strings.xml
index 96d97dd..82ee9ef4 100644
--- a/core/res/res/values-sr/strings.xml
+++ b/core/res/res/values-sr/strings.xml
@@ -132,6 +132,7 @@
     <!-- no translation found for wfcSpnFormat_spn (4998685024207291232) -->
     <skip />
     <string name="wfcSpnFormat_spn_wifi_calling" msgid="136001023263502280">"<xliff:g id="SPN">%s</xliff:g> позивање преко Wi-Fi-ја"</string>
+    <string name="wfcSpnFormat_spn_wifi_calling_vo_hyphen" msgid="1730997175789582756">"<xliff:g id="SPN">%s</xliff:g> – позивање преко Wi-Fi-ја"</string>
     <string name="wfcSpnFormat_wlan_call" msgid="2533371081782489793">"WLAN позив"</string>
     <string name="wfcSpnFormat_spn_wlan_call" msgid="2315240198303197168">"<xliff:g id="SPN">%s</xliff:g> WLAN позив"</string>
     <string name="wfcSpnFormat_spn_wifi" msgid="6546481665561961938">"<xliff:g id="SPN">%s</xliff:g> Wi-Fi"</string>
@@ -1379,8 +1380,7 @@
     <string name="test_harness_mode_notification_message" msgid="1343197173054407119">"Обавите ресетовање на фабричка подешавања да бисте онемогућили режим пробног коришћења."</string>
     <string name="usb_contaminant_detected_title" msgid="7136400633704058349">"Течност или нечистоћа у USB порту"</string>
     <string name="usb_contaminant_detected_message" msgid="832337061059487250">"USB порт је аутоматски искључен. Додирните да бисте сазнали више."</string>
-    <!-- no translation found for usb_contaminant_not_detected_title (7708281124088684821) -->
-    <skip />
+    <string name="usb_contaminant_not_detected_title" msgid="7708281124088684821">"Коришћење USB порта је дозвољено"</string>
     <string name="usb_contaminant_not_detected_message" msgid="2415791798244545292">"Телефон више не открива течност или нечистоћу."</string>
     <string name="taking_remote_bugreport_notification_title" msgid="6742483073875060934">"Извештај о грешци се генерише…"</string>
     <string name="share_remote_bugreport_notification_title" msgid="4987095013583691873">"Желите ли да поделите извештај о грешци?"</string>
@@ -1635,8 +1635,6 @@
     <string name="display_manager_overlay_display_name" msgid="5142365982271620716">"Постављени елемент бр. <xliff:g id="ID">%1$d</xliff:g>"</string>
     <string name="display_manager_overlay_display_title" msgid="652124517672257172">"<xliff:g id="NAME">%1$s</xliff:g>: <xliff:g id="WIDTH">%2$d</xliff:g>×<xliff:g id="HEIGHT">%3$d</xliff:g>, <xliff:g id="DPI">%4$d</xliff:g> dpi"</string>
     <string name="display_manager_overlay_display_secure_suffix" msgid="6022119702628572080">", безбедно"</string>
-    <string name="activity_starter_block_bg_activity_starts_permissive" msgid="6995473033438879646">"Ово покретање активности у позадини са <xliff:g id="PACKAGENAME">%1$s</xliff:g> биће блокирано у будућим Q верзијама. Погледајте g.co/dev/bgblock."</string>
-    <string name="activity_starter_block_bg_activity_starts_enforcing" msgid="3317816771072146229">"Покретање активности у позадини са <xliff:g id="PACKAGENAME">%1$s</xliff:g> је блокирано. Погледајте g.co/dev/bgblock."</string>
     <string name="kg_forgot_pattern_button_text" msgid="8852021467868220608">"Заборављени шаблон"</string>
     <string name="kg_wrong_pattern" msgid="1850806070801358830">"Погрешан шаблон"</string>
     <string name="kg_wrong_password" msgid="2333281762128113157">"Погрешна лозинка"</string>
@@ -1691,8 +1689,12 @@
     <string name="accessibility_shortcut_enabling_service" msgid="7771852911861522636">"Пречица за приступачност је укључила услугу <xliff:g id="SERVICE_NAME">%1$s</xliff:g>"</string>
     <string name="accessibility_shortcut_disabling_service" msgid="2747243438223109821">"Пречица за приступачност је искључила услугу <xliff:g id="SERVICE_NAME">%1$s</xliff:g>"</string>
     <string name="accessibility_shortcut_spoken_feedback" msgid="8376923232350078434">"Притисните и задржите оба тастера за јачину звука три секунде да бисте користили <xliff:g id="SERVICE_NAME">%1$s</xliff:g>"</string>
-    <string name="accessibility_button_prompt_text" msgid="4234556536456854251">"Изаберите функцију која ће се користити када додирнете дугме за приступачност:"</string>
-    <string name="accessibility_button_instructional_text" msgid="6942300463612999993">"Притисните и задржите дугме за приступачност да бисте мењали функције."</string>
+    <string name="accessibility_button_prompt_text" msgid="1176658502969738564">"Одаберите услугу која ће се користити када додирнете дугме за приступачност:"</string>
+    <string name="accessibility_gesture_prompt_text" msgid="8259145549733019401">"Одаберите функцију која ће се користити помоћу покрета за приступачност (помоћу два прста превуците нагоре од дна екрана):"</string>
+    <string name="accessibility_gesture_3finger_prompt_text" msgid="1041435574275047665">"Одаберите услугу која ће се користити помоћу покрета за приступачност (помоћу три прста превуците нагоре од дна екрана):"</string>
+    <string name="accessibility_button_instructional_text" msgid="7003212763213614833">"Да бисте прелазили са једне услуге на другу, додирните и задржите дугме за приступачност."</string>
+    <string name="accessibility_gesture_instructional_text" msgid="5261788874937410950">"Да бисте прелазили са једне услуге на другу, превуците нагоре помоћу два прста и задржите."</string>
+    <string name="accessibility_gesture_3finger_instructional_text" msgid="4969448938984394550">"Да бисте прелазили са једне услуге на другу, превуците нагоре помоћу три прста и задржите."</string>
     <string name="accessibility_magnification_chooser_text" msgid="1227146738764986237">"Увећање"</string>
     <string name="user_switched" msgid="3768006783166984410">"Актуелни корисник <xliff:g id="NAME">%1$s</xliff:g>."</string>
     <string name="user_switching_message" msgid="2871009331809089783">"Пребацивање на <xliff:g id="NAME">%1$s</xliff:g>…"</string>
diff --git a/core/res/res/values-sv/strings.xml b/core/res/res/values-sv/strings.xml
index a7f74c9..088fd98 100644
--- a/core/res/res/values-sv/strings.xml
+++ b/core/res/res/values-sv/strings.xml
@@ -131,6 +131,7 @@
     <!-- no translation found for wfcSpnFormat_spn (4998685024207291232) -->
     <skip />
     <string name="wfcSpnFormat_spn_wifi_calling" msgid="136001023263502280">"Wi-Fi-samtal via <xliff:g id="SPN">%s</xliff:g>"</string>
+    <string name="wfcSpnFormat_spn_wifi_calling_vo_hyphen" msgid="1730997175789582756">"Wi-Fi-samtal med <xliff:g id="SPN">%s</xliff:g>"</string>
     <string name="wfcSpnFormat_wlan_call" msgid="2533371081782489793">"WLAN-samtal"</string>
     <string name="wfcSpnFormat_spn_wlan_call" msgid="2315240198303197168">"WLAN-samtal via <xliff:g id="SPN">%s</xliff:g>"</string>
     <string name="wfcSpnFormat_spn_wifi" msgid="6546481665561961938">"Wi-Fi via <xliff:g id="SPN">%s</xliff:g>"</string>
@@ -295,7 +296,7 @@
     <string name="permgrouprequest_storage" msgid="7885942926944299560">"Vill du ge &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; åtkomst till foton, mediefiler och andra filer på enheten?"</string>
     <string name="permgrouplab_microphone" msgid="171539900250043464">"Mikrofon"</string>
     <string name="permgroupdesc_microphone" msgid="4988812113943554584">"spela in ljud"</string>
-    <string name="permgrouprequest_microphone" msgid="9167492350681916038">"Vill du ge &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>n&lt;/b&gt; behörighet att spela in ljud?"</string>
+    <string name="permgrouprequest_microphone" msgid="9167492350681916038">"Vill du ge &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; behörighet att spela in ljud?"</string>
     <string name="permgrouplab_activityRecognition" msgid="1565108047054378642">"Fysiska aktivitet"</string>
     <string name="permgroupdesc_activityRecognition" msgid="6949472038320473478">"åtkomst till data om fysisk aktivitet"</string>
     <string name="permgrouprequest_activityRecognition" msgid="7626438016904799383">"Vill du ge &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; to åtkomst till data om fysisk aktivitet?"</string>
@@ -1357,8 +1358,7 @@
     <string name="test_harness_mode_notification_message" msgid="1343197173054407119">"Inaktivera testverktygsläget genom att göra en återställning till standardinställningarna."</string>
     <string name="usb_contaminant_detected_title" msgid="7136400633704058349">"Vätska eller smuts i USB-porten"</string>
     <string name="usb_contaminant_detected_message" msgid="832337061059487250">"USB-porten har inaktiverats automatiskt. Tryck för att läsa mer."</string>
-    <!-- no translation found for usb_contaminant_not_detected_title (7708281124088684821) -->
-    <skip />
+    <string name="usb_contaminant_not_detected_title" msgid="7708281124088684821">"Nu kan du använda USB-porten"</string>
     <string name="usb_contaminant_not_detected_message" msgid="2415791798244545292">"Mobilen känner inte längre av någon vätska eller smuts."</string>
     <string name="taking_remote_bugreport_notification_title" msgid="6742483073875060934">"Felrapporten överförs …"</string>
     <string name="share_remote_bugreport_notification_title" msgid="4987095013583691873">"Vill du dela felrapporten?"</string>
@@ -1494,7 +1494,7 @@
     <string name="find_next" msgid="5742124618942193978">"Sök nästa"</string>
     <string name="find_previous" msgid="2196723669388360506">"Sök föregående"</string>
     <string name="gpsNotifTicker" msgid="5622683912616496172">"Positionsförfrågan från <xliff:g id="NAME">%s</xliff:g>"</string>
-    <string name="gpsNotifTitle" msgid="5446858717157416839">"Positionsförfrågan"</string>
+    <string name="gpsNotifTitle" msgid="5446858717157416839">"Platsförfrågan"</string>
     <string name="gpsNotifMessage" msgid="1374718023224000702">"Begärt av <xliff:g id="NAME">%1$s</xliff:g> (<xliff:g id="SERVICE">%2$s</xliff:g>)"</string>
     <string name="gpsVerifYes" msgid="2346566072867213563">"Ja"</string>
     <string name="gpsVerifNo" msgid="1146564937346454865">"Nej"</string>
@@ -1612,8 +1612,6 @@
     <string name="display_manager_overlay_display_name" msgid="5142365982271620716">"Överlagring #<xliff:g id="ID">%1$d</xliff:g>"</string>
     <string name="display_manager_overlay_display_title" msgid="652124517672257172">"<xliff:g id="NAME">%1$s</xliff:g>: <xliff:g id="WIDTH">%2$d</xliff:g> x <xliff:g id="HEIGHT">%3$d</xliff:g>, <xliff:g id="DPI">%4$d</xliff:g> dpi"</string>
     <string name="display_manager_overlay_display_secure_suffix" msgid="6022119702628572080">", säker"</string>
-    <string name="activity_starter_block_bg_activity_starts_permissive" msgid="6995473033438879646">"Denna bakgrundsaktivitet som startar från <xliff:g id="PACKAGENAME">%1$s</xliff:g> blockeras i framtida Q-versioner. Läs mer på g.co/dev/bgblock."</string>
-    <string name="activity_starter_block_bg_activity_starts_enforcing" msgid="3317816771072146229">"Start av bakgrundsaktivitet från <xliff:g id="PACKAGENAME">%1$s</xliff:g> blockerades. Läs mer på g.co/dev/bgblock."</string>
     <string name="kg_forgot_pattern_button_text" msgid="8852021467868220608">"Har du glömt ditt grafiska lösenord?"</string>
     <string name="kg_wrong_pattern" msgid="1850806070801358830">"Fel grafiskt lösenord"</string>
     <string name="kg_wrong_password" msgid="2333281762128113157">"Fel lösenord"</string>
@@ -1667,8 +1665,12 @@
     <string name="accessibility_shortcut_enabling_service" msgid="7771852911861522636">"<xliff:g id="SERVICE_NAME">%1$s</xliff:g> aktiverades av Aktivera tillgänglighet snabbt"</string>
     <string name="accessibility_shortcut_disabling_service" msgid="2747243438223109821">"<xliff:g id="SERVICE_NAME">%1$s</xliff:g> inaktiverades av Aktivera tillgänglighet snabbt"</string>
     <string name="accessibility_shortcut_spoken_feedback" msgid="8376923232350078434">"Tryck och håll båda volymknapparna i tre sekunder för att använda <xliff:g id="SERVICE_NAME">%1$s</xliff:g>"</string>
-    <string name="accessibility_button_prompt_text" msgid="4234556536456854251">"Välj en funktion som ska användas när du trycker på tillgänglighetsknappen:"</string>
-    <string name="accessibility_button_instructional_text" msgid="6942300463612999993">"Tryck länge på tillgänglighetsknappen för att ändra funktioner."</string>
+    <string name="accessibility_button_prompt_text" msgid="1176658502969738564">"Välj en tjänst som ska användas när du trycker på tillgänglighetsknappen:"</string>
+    <string name="accessibility_gesture_prompt_text" msgid="8259145549733019401">"Välj en tjänst som ska användas med tillgänglighetsrörelsen (svepa uppåt med två fingrar från skärmens nederkant):"</string>
+    <string name="accessibility_gesture_3finger_prompt_text" msgid="1041435574275047665">"Välj en tjänst som ska användas med tillgänglighetsrörelsen (svepa uppåt med tre fingrar från skärmens nederkant):"</string>
+    <string name="accessibility_button_instructional_text" msgid="7003212763213614833">"Byt mellan tjänster genom att trycka länge på tillgänglighetsknappen."</string>
+    <string name="accessibility_gesture_instructional_text" msgid="5261788874937410950">"Byt mellan tjänster genom att svepa uppåt med två fingrar och hålla kvar dem."</string>
+    <string name="accessibility_gesture_3finger_instructional_text" msgid="4969448938984394550">"Byt mellan tjänster genom att svepa uppåt med tre fingrar och hålla kvar dem."</string>
     <string name="accessibility_magnification_chooser_text" msgid="1227146738764986237">"Förstoring"</string>
     <string name="user_switched" msgid="3768006783166984410">"Nuvarande användare: <xliff:g id="NAME">%1$s</xliff:g>."</string>
     <string name="user_switching_message" msgid="2871009331809089783">"Byter till <xliff:g id="NAME">%1$s</xliff:g> …"</string>
diff --git a/core/res/res/values-sw/strings.xml b/core/res/res/values-sw/strings.xml
index dec924e..6e2ba99 100644
--- a/core/res/res/values-sw/strings.xml
+++ b/core/res/res/values-sw/strings.xml
@@ -131,6 +131,7 @@
     <!-- no translation found for wfcSpnFormat_spn (4998685024207291232) -->
     <skip />
     <string name="wfcSpnFormat_spn_wifi_calling" msgid="136001023263502280">"Kupiga Simu Kupitia Wi-Fi ya <xliff:g id="SPN">%s</xliff:g>"</string>
+    <string name="wfcSpnFormat_spn_wifi_calling_vo_hyphen" msgid="1730997175789582756">"Kupiga Simu Kupitia WiFi <xliff:g id="SPN">%s</xliff:g>"</string>
     <string name="wfcSpnFormat_wlan_call" msgid="2533371081782489793">"Simu ya WLAN"</string>
     <string name="wfcSpnFormat_spn_wlan_call" msgid="2315240198303197168">"Simu ya WLAN ya <xliff:g id="SPN">%s</xliff:g>"</string>
     <string name="wfcSpnFormat_spn_wifi" msgid="6546481665561961938">"Wi-Fi ya <xliff:g id="SPN">%s</xliff:g>"</string>
@@ -1357,8 +1358,7 @@
     <string name="test_harness_mode_notification_message" msgid="1343197173054407119">"Rejesha mipangilio iliyotoka nayo kiwandani ili uzime hali ya Muunganisho wa Majaribio."</string>
     <string name="usb_contaminant_detected_title" msgid="7136400633704058349">"Unyevu au uchafu katika mlango wa USB"</string>
     <string name="usb_contaminant_detected_message" msgid="832337061059487250">"Mlango wa USB umezimwa kiotomatiki. Gusa ili upate maelezo zaidi."</string>
-    <!-- no translation found for usb_contaminant_not_detected_title (7708281124088684821) -->
-    <skip />
+    <string name="usb_contaminant_not_detected_title" msgid="7708281124088684821">"Ni sawa kutumia mlango wa USB"</string>
     <string name="usb_contaminant_not_detected_message" msgid="2415791798244545292">"Simu haitambui tena unyevu au uchafu."</string>
     <string name="taking_remote_bugreport_notification_title" msgid="6742483073875060934">"Inatayarisha ripoti ya hitilafu…"</string>
     <string name="share_remote_bugreport_notification_title" msgid="4987095013583691873">"Ungependa kushiriki ripoti ya hitilafu?"</string>
@@ -1494,7 +1494,7 @@
     <string name="find_next" msgid="5742124618942193978">"Pata ifuatayo"</string>
     <string name="find_previous" msgid="2196723669388360506">"Pata iliyotangulia"</string>
     <string name="gpsNotifTicker" msgid="5622683912616496172">"Ombi la mahali kutoka <xliff:g id="NAME">%s</xliff:g>"</string>
-    <string name="gpsNotifTitle" msgid="5446858717157416839">"Ombi la mahali"</string>
+    <string name="gpsNotifTitle" msgid="5446858717157416839">"Ombi la kutambua mahali"</string>
     <string name="gpsNotifMessage" msgid="1374718023224000702">"Imeombwa na <xliff:g id="NAME">%1$s</xliff:g> (<xliff:g id="SERVICE">%2$s</xliff:g>)"</string>
     <string name="gpsVerifYes" msgid="2346566072867213563">"Ndiyo"</string>
     <string name="gpsVerifNo" msgid="1146564937346454865">"Hapana"</string>
@@ -1612,8 +1612,6 @@
     <string name="display_manager_overlay_display_name" msgid="5142365982271620716">"Uwekeleaji #<xliff:g id="ID">%1$d</xliff:g>"</string>
     <string name="display_manager_overlay_display_title" msgid="652124517672257172">"<xliff:g id="NAME">%1$s</xliff:g>: <xliff:g id="WIDTH">%2$d</xliff:g>x<xliff:g id="HEIGHT">%3$d</xliff:g>, <xliff:g id="DPI">%4$d</xliff:g> dpi"</string>
     <string name="display_manager_overlay_display_secure_suffix" msgid="6022119702628572080">", salama"</string>
-    <string name="activity_starter_block_bg_activity_starts_permissive" msgid="6995473033438879646">"Itazuia shughuli hii ya chinichini inayoanzia <xliff:g id="PACKAGENAME">%1$s</xliff:g> katika miundo ya baadaye ya Q. Angalia g.co/dev/bgblock."</string>
-    <string name="activity_starter_block_bg_activity_starts_enforcing" msgid="3317816771072146229">"Imezuia shughuli za chinichini zinazoanzia <xliff:g id="PACKAGENAME">%1$s</xliff:g>. Angalia g.co/dev/bgblock."</string>
     <string name="kg_forgot_pattern_button_text" msgid="8852021467868220608">"Umesahau Ruwaza"</string>
     <string name="kg_wrong_pattern" msgid="1850806070801358830">"Mchoro huo si sahihi"</string>
     <string name="kg_wrong_password" msgid="2333281762128113157">"Nenosiri Lisilo sahihi"</string>
@@ -1667,8 +1665,12 @@
     <string name="accessibility_shortcut_enabling_service" msgid="7771852911861522636">"Njia ya mkato ya zana za walio na matatizo ya kuona au kusikia imewasha <xliff:g id="SERVICE_NAME">%1$s</xliff:g>"</string>
     <string name="accessibility_shortcut_disabling_service" msgid="2747243438223109821">"Njia ya mkato ya zana za walio na matatizo ya kuona au kusikia imezima <xliff:g id="SERVICE_NAME">%1$s</xliff:g>"</string>
     <string name="accessibility_shortcut_spoken_feedback" msgid="8376923232350078434">"Bonyeza na ushikilie vitufe vyote viwili vya sauti kwa sekunde tatu ili utumie <xliff:g id="SERVICE_NAME">%1$s</xliff:g>"</string>
-    <string name="accessibility_button_prompt_text" msgid="4234556536456854251">"Chagua kipengele utakachotumia, ukigusa kitufe cha Ufikivu:"</string>
-    <string name="accessibility_button_instructional_text" msgid="6942300463612999993">"Ili kubadilisha vipengele, gusa na ushikilie kitufe cha Ufikivu."</string>
+    <string name="accessibility_button_prompt_text" msgid="1176658502969738564">"Chagua huduma ya kutumia unapogusa kitufe cha ufikivu:"</string>
+    <string name="accessibility_gesture_prompt_text" msgid="8259145549733019401">"Chagua huduma ya kutumia pamoja na ishara ya ufikivu (telezesha vidole viwili juu kutoka sehemu ya chini ya skrini):"</string>
+    <string name="accessibility_gesture_3finger_prompt_text" msgid="1041435574275047665">"Chagua huduma ya kutumia pamoja na ishara ya ufikivu (telezesha vidole vitatu juu kutoka sehemu ya chini ya skrini):"</string>
+    <string name="accessibility_button_instructional_text" msgid="7003212763213614833">"Ili ubadilishe kati ya huduma, gusa na ushikilie kitufe cha ufikivu."</string>
+    <string name="accessibility_gesture_instructional_text" msgid="5261788874937410950">"Ili ubadilishe kati ya huduma, telezesha vidole viwili juu na ushikilie."</string>
+    <string name="accessibility_gesture_3finger_instructional_text" msgid="4969448938984394550">"Ili ubadilishe kati ya huduma, telezesha vidole vitatu juu na ushikilie."</string>
     <string name="accessibility_magnification_chooser_text" msgid="1227146738764986237">"Ukuzaji"</string>
     <string name="user_switched" msgid="3768006783166984410">"Mtumiaji wa sasa <xliff:g id="NAME">%1$s</xliff:g>."</string>
     <string name="user_switching_message" msgid="2871009331809089783">"Inabadili kwenda <xliff:g id="NAME">%1$s</xliff:g>…"</string>
diff --git a/core/res/res/values-ta/strings.xml b/core/res/res/values-ta/strings.xml
index 97a8df2..30001b1 100644
--- a/core/res/res/values-ta/strings.xml
+++ b/core/res/res/values-ta/strings.xml
@@ -131,6 +131,8 @@
     <!-- no translation found for wfcSpnFormat_spn (4998685024207291232) -->
     <skip />
     <string name="wfcSpnFormat_spn_wifi_calling" msgid="136001023263502280">"<xliff:g id="SPN">%s</xliff:g> வைஃபை அழைப்பு"</string>
+    <!-- no translation found for wfcSpnFormat_spn_wifi_calling_vo_hyphen (1730997175789582756) -->
+    <skip />
     <string name="wfcSpnFormat_wlan_call" msgid="2533371081782489793">"WLAN அழைப்பு"</string>
     <string name="wfcSpnFormat_spn_wlan_call" msgid="2315240198303197168">"<xliff:g id="SPN">%s</xliff:g> WLAN அழைப்பு"</string>
     <string name="wfcSpnFormat_spn_wifi" msgid="6546481665561961938">"<xliff:g id="SPN">%s</xliff:g> வைஃபை"</string>
@@ -1358,8 +1360,7 @@
     <string name="test_harness_mode_notification_message" msgid="1343197173054407119">"’தன்னியக்க சோதனைப்\' பயன்முறையை முடக்க ஆரம்பநிலைக்கு மீட்டமைக்கவும்."</string>
     <string name="usb_contaminant_detected_title" msgid="7136400633704058349">"USB போர்ட்டில் சேதம் உள்ளது"</string>
     <string name="usb_contaminant_detected_message" msgid="832337061059487250">"USB போர்ட் தானாகவே முடக்கப்பட்டது மேலும் அறிய, தட்டவும்."</string>
-    <!-- no translation found for usb_contaminant_not_detected_title (7708281124088684821) -->
-    <skip />
+    <string name="usb_contaminant_not_detected_title" msgid="7708281124088684821">"USB போர்ட்டைப் பயன்படுத்தலாம்"</string>
     <string name="usb_contaminant_not_detected_message" msgid="2415791798244545292">"மொபைலில் எந்தச் சேதாரமும் கண்டறியப்படவில்லை."</string>
     <string name="taking_remote_bugreport_notification_title" msgid="6742483073875060934">"பிழை அறிக்கையை எடுக்கிறது…"</string>
     <string name="share_remote_bugreport_notification_title" msgid="4987095013583691873">"பிழை அறிக்கையைப் பகிரவா?"</string>
@@ -1613,8 +1614,6 @@
     <string name="display_manager_overlay_display_name" msgid="5142365982271620716">"மேலோட்ட #<xliff:g id="ID">%1$d</xliff:g>"</string>
     <string name="display_manager_overlay_display_title" msgid="652124517672257172">"<xliff:g id="NAME">%1$s</xliff:g>: <xliff:g id="WIDTH">%2$d</xliff:g>x<xliff:g id="HEIGHT">%3$d</xliff:g>, <xliff:g id="DPI">%4$d</xliff:g> dpi"</string>
     <string name="display_manager_overlay_display_secure_suffix" msgid="6022119702628572080">", பாதுகாப்பானது"</string>
-    <string name="activity_starter_block_bg_activity_starts_permissive" msgid="6995473033438879646">"<xliff:g id="PACKAGENAME">%1$s</xliff:g>மின் \'பின்னணிச் செயல்பாடுத் தொடக்கம்\' இனிவரும் Q பதிப்புகளில் தடுக்கப்படும். g.co/dev/bgblock என்ற இணைப்பைப் பார்க்கவும்."</string>
-    <string name="activity_starter_block_bg_activity_starts_enforcing" msgid="3317816771072146229">"<xliff:g id="PACKAGENAME">%1$s</xliff:g>மில் \'பின்னணிச் செயல்பாட்டுத் தொடக்கம்\' தடுக்கப்பட்டுள்ளது. g.co/dev/bgblock என்ற இணைப்பைப் பார்க்கவும்."</string>
     <string name="kg_forgot_pattern_button_text" msgid="8852021467868220608">"வடிவத்தை மறந்துவிட்டீர்களா"</string>
     <string name="kg_wrong_pattern" msgid="1850806070801358830">"தவறான வடிவம்"</string>
     <string name="kg_wrong_password" msgid="2333281762128113157">"தவறான கடவுச்சொல்"</string>
@@ -1668,8 +1667,12 @@
     <string name="accessibility_shortcut_enabling_service" msgid="7771852911861522636">"அணுகல்தன்மை ஷார்ட்கட்டானது <xliff:g id="SERVICE_NAME">%1$s</xliff:g>ஐ இயக்கியது"</string>
     <string name="accessibility_shortcut_disabling_service" msgid="2747243438223109821">"அணுகல்தன்மை ஷார்ட்கட்டானது <xliff:g id="SERVICE_NAME">%1$s</xliff:g>ஐ முடக்கியது"</string>
     <string name="accessibility_shortcut_spoken_feedback" msgid="8376923232350078434">"<xliff:g id="SERVICE_NAME">%1$s</xliff:g>ஐப் பயன்படுத்த 3 விநாடிகளுக்கு இரண்டு ஒலியளவு பட்டன்களையும் அழுத்திப் பிடிக்கவும்"</string>
-    <string name="accessibility_button_prompt_text" msgid="4234556536456854251">"அணுகல்தன்மை பட்டனைத் தட்டி, பயன்படுத்துவதற்கான அம்சத்தைத் தேர்ந்தெடுக்கவும்:"</string>
-    <string name="accessibility_button_instructional_text" msgid="6942300463612999993">"அம்சங்களை மாற்ற, அணுகல்தன்மை பட்டனைத் தொட்டுப் பிடித்திருக்கவும்."</string>
+    <string name="accessibility_button_prompt_text" msgid="1176658502969738564">"அணுகல்தன்மை பட்டனுக்கான சேவையைத் தேர்வுசெய்யவும்:"</string>
+    <string name="accessibility_gesture_prompt_text" msgid="8259145549733019401">"அணுகல்தன்மை சைகைக்கான சேவையைத் தேர்வுசெய்யவும் (இரண்டு விரல்களால் திரையின் கீழிருந்து மேல் நோக்கி ஸ்வைப் செய்யவும்):"</string>
+    <string name="accessibility_gesture_3finger_prompt_text" msgid="1041435574275047665">"அணுகல்தன்மை சைகைக்கான சேவையைத் தேர்வுசெய்யவும் (மூன்று விரல்களால் திரையின் கீழிருந்து மேல் நோக்கி ஸ்வைப் செய்யவும்):"</string>
+    <string name="accessibility_button_instructional_text" msgid="7003212763213614833">"சேவைகளுக்கு இடையே மாற அணுகல்தன்மை பட்டனைத் தொட்டுப் பிடிக்கவும்."</string>
+    <string name="accessibility_gesture_instructional_text" msgid="5261788874937410950">"சேவைகளுக்கு இடையே மாற இரண்டு விரல்களால் மேல்நோக்கி ஸ்வைப் செய்து பிடிக்கவும்."</string>
+    <string name="accessibility_gesture_3finger_instructional_text" msgid="4969448938984394550">"சேவைகளுக்கு இடையே மாற மூன்று விரல்களால் மேல்நோக்கி ஸ்வைப் செய்து பிடிக்கவும்."</string>
     <string name="accessibility_magnification_chooser_text" msgid="1227146738764986237">"பெரிதாக்கல்"</string>
     <string name="user_switched" msgid="3768006783166984410">"நடப்பு பயனர் <xliff:g id="NAME">%1$s</xliff:g>."</string>
     <string name="user_switching_message" msgid="2871009331809089783">"<xliff:g id="NAME">%1$s</xliff:g>க்கு மாறுகிறது…"</string>
diff --git a/core/res/res/values-te/strings.xml b/core/res/res/values-te/strings.xml
index a0da181..dd65143 100644
--- a/core/res/res/values-te/strings.xml
+++ b/core/res/res/values-te/strings.xml
@@ -131,6 +131,7 @@
     <!-- no translation found for wfcSpnFormat_spn (4998685024207291232) -->
     <skip />
     <string name="wfcSpnFormat_spn_wifi_calling" msgid="136001023263502280">"<xliff:g id="SPN">%s</xliff:g> Wi-Fi కాలింగ్"</string>
+    <string name="wfcSpnFormat_spn_wifi_calling_vo_hyphen" msgid="1730997175789582756">"<xliff:g id="SPN">%s</xliff:g> Wi-Fi కాలింగ్"</string>
     <string name="wfcSpnFormat_wlan_call" msgid="2533371081782489793">"WLAN కాల్"</string>
     <string name="wfcSpnFormat_spn_wlan_call" msgid="2315240198303197168">"<xliff:g id="SPN">%s</xliff:g> WLAN కాల్"</string>
     <string name="wfcSpnFormat_spn_wifi" msgid="6546481665561961938">"<xliff:g id="SPN">%s</xliff:g> Wi-Fi"</string>
@@ -280,7 +281,7 @@
     <string name="permgrouprequest_contacts" msgid="6032805601881764300">"మీ పరిచయాలను యాక్సెస్ చేయడానికి &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt;ని అనుమతించాలా?"</string>
     <string name="permgrouplab_location" msgid="7275582855722310164">"స్థానం"</string>
     <string name="permgroupdesc_location" msgid="1346617465127855033">"ఈ పరికర స్థానాన్ని యాక్సెస్ చేయడానికి"</string>
-    <string name="permgrouprequest_location" msgid="3788275734953323491">"ఈ పరికర స్థానాన్ని యాక్సెస్ చేయడానికి &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt;ని అనుమతించాలా?"</string>
+    <string name="permgrouprequest_location" msgid="3788275734953323491">"ఈ పరికర స్థానాన్ని యాక్సెస్ చేయడానికి &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt;ను అనుమతించాలా?"</string>
     <string name="permgrouprequestdetail_location" msgid="1347189607421252902">"మీరు యాప్‌ను ఉపయోగిస్తున్నప్పుడు మాత్రమే స్థానానికి యాప్ యాక్సెస్ కలిగి ఉంటుంది"</string>
     <string name="permgroupbackgroundrequest_location" msgid="5039063878675613235">"ఈ పరికర స్థానాన్ని &lt;b&gt;అన్ని సమయాలలో&lt;/b&gt; యాక్సెస్ చేయడానికి &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt;ను అనుమతించాలా?"</string>
     <string name="permgroupbackgroundrequestdetail_location" msgid="4597006851453417387">"యాప్ ప్రస్తుతం మీరు ఆ యాప్‌ను ఉపయోగిస్తున్నప్పుడు మాత్రమే స్థానాన్ని యాక్సెస్ చేయగలుగుతుంది"</string>
@@ -1358,8 +1359,7 @@
     <string name="test_harness_mode_notification_message" msgid="1343197173054407119">"పరీక్ష నియంత్రణ మోడ్‌ను నిలిపివేయడానికి ఫ్యాక్టరీ రీసెట్‍‌ను అమలు చేయండి."</string>
     <string name="usb_contaminant_detected_title" msgid="7136400633704058349">"USB పోర్ట్‌లో ద్రవ లేదా వ్యర్థ పదార్థాలు ఉన్నాయి"</string>
     <string name="usb_contaminant_detected_message" msgid="832337061059487250">"USB పోర్ట్ ఆటోమేటిక్‌గా నిలిపివేయబడింది. మరింత తెలుసుకోవడానికి నొక్కండి."</string>
-    <!-- no translation found for usb_contaminant_not_detected_title (7708281124088684821) -->
-    <skip />
+    <string name="usb_contaminant_not_detected_title" msgid="7708281124088684821">"USB పోర్ట్‌ను ఉపయోగించడం సురక్షితం"</string>
     <string name="usb_contaminant_not_detected_message" msgid="2415791798244545292">"ఫోన్ ఇకపై ద్రవ లేదా వ్యర్థ పదార్థాలను గుర్తించదు."</string>
     <string name="taking_remote_bugreport_notification_title" msgid="6742483073875060934">"బగ్ నివేదికను తీస్తోంది…"</string>
     <string name="share_remote_bugreport_notification_title" msgid="4987095013583691873">"బగ్ నివేదికను భాగస్వామ్యం చేయాలా?"</string>
@@ -1613,8 +1613,6 @@
     <string name="display_manager_overlay_display_name" msgid="5142365982271620716">"అతివ్యాప్తి #<xliff:g id="ID">%1$d</xliff:g>"</string>
     <string name="display_manager_overlay_display_title" msgid="652124517672257172">"<xliff:g id="NAME">%1$s</xliff:g>: <xliff:g id="WIDTH">%2$d</xliff:g>x<xliff:g id="HEIGHT">%3$d</xliff:g>, <xliff:g id="DPI">%4$d</xliff:g> dpi"</string>
     <string name="display_manager_overlay_display_secure_suffix" msgid="6022119702628572080">", సురక్షితం"</string>
-    <string name="activity_starter_block_bg_activity_starts_permissive" msgid="6995473033438879646">"<xliff:g id="PACKAGENAME">%1$s</xliff:g> నుండి ప్రారంభం అయ్యే నేపథ్య కార్యకలాపం భవిష్యత్తు Q బిల్డ్‌లలో బ్లాక్ చేయబడుతుంది. See g.co/dev/bgblock."</string>
-    <string name="activity_starter_block_bg_activity_starts_enforcing" msgid="3317816771072146229">"<xliff:g id="PACKAGENAME">%1$s</xliff:g> నుండి ప్రారంభం అయ్యే నేపథ్య కార్యకలాపం బ్లాక్ చేయబడింది. See g.co/dev/bgblock."</string>
     <string name="kg_forgot_pattern_button_text" msgid="8852021467868220608">"నమూనాను మర్చిపోయాను"</string>
     <string name="kg_wrong_pattern" msgid="1850806070801358830">"ఆకృతి తప్పు"</string>
     <string name="kg_wrong_password" msgid="2333281762128113157">"పాస్‌వర్డ్ తప్పు"</string>
@@ -1668,8 +1666,12 @@
     <string name="accessibility_shortcut_enabling_service" msgid="7771852911861522636">"యాక్సెస్ సామర్థ్య షార్ట్‌కట్ ద్వారా <xliff:g id="SERVICE_NAME">%1$s</xliff:g> ఆన్ చేయబడింది"</string>
     <string name="accessibility_shortcut_disabling_service" msgid="2747243438223109821">"యాక్సెస్ సామర్థ్య షార్ట్‌కట్ ద్వారా <xliff:g id="SERVICE_NAME">%1$s</xliff:g> ఆఫ్ చేయబడింది"</string>
     <string name="accessibility_shortcut_spoken_feedback" msgid="8376923232350078434">"<xliff:g id="SERVICE_NAME">%1$s</xliff:g>ని ఉపయోగించడానికి వాల్యూమ్ కీలు రెండింటినీ 3 సెకన్లు నొక్కి ఉంచండి"</string>
-    <string name="accessibility_button_prompt_text" msgid="4234556536456854251">"యాక్సెస్ సామర్థ్య బటన్‌ను మీరు నొక్కినప్పుడు ఉపయోగించాల్సిన ఒక ఫీచర్‌ను ఎంచుకోండి:"</string>
-    <string name="accessibility_button_instructional_text" msgid="6942300463612999993">"ఫీచర్లను మార్చడానికి, యాక్సెస్ సామర్థ్య బటన్‌ను నొక్కి &amp; పట్టుకోండి."</string>
+    <string name="accessibility_button_prompt_text" msgid="1176658502969738564">"యాక్సెసిబిలిటీ బటన్‌ను మీరు నొక్కినప్పుడు ఉపయోగించాల్సిన ఒక ఫీచర్‌ను ఎంచుకోండి:"</string>
+    <string name="accessibility_gesture_prompt_text" msgid="8259145549733019401">"యాక్సెసిబిలిటీ సంజ్ఞతో ఉపయోగించడానికి ఒక సేవను ఎంచుకోండి (రెండు చేతి వేళ్లతో స్క్రీన్‌ను కింద నుండి పైకి స్వైప్ చేయండి):"</string>
+    <string name="accessibility_gesture_3finger_prompt_text" msgid="1041435574275047665">"యాక్సెసిబిలిటీ సంజ్ఞతో ఉపయోగించడానికి ఒక సేవను ఎంచుకోండి (మూడు చేతి వేళ్లతో స్క్రీన్‌ను కింద నుండి పైకి స్వైప్ చేయండి):"</string>
+    <string name="accessibility_button_instructional_text" msgid="7003212763213614833">"సేవల మధ్య మారడానికి, యాక్సెసిబిలిటీ బటన్‌ను నొక్కి &amp; పట్టుకోండి."</string>
+    <string name="accessibility_gesture_instructional_text" msgid="5261788874937410950">"సేవల మధ్య మారడానికి, రెండు చేతి వేళ్ళతో పైకి స్వైప్ చేసి పట్టుకోండి."</string>
+    <string name="accessibility_gesture_3finger_instructional_text" msgid="4969448938984394550">"సేవల మధ్య మారడానికి, మూడు చేతి వేళ్ళతో పైకి స్వైప్ చేసి పట్టుకోండి."</string>
     <string name="accessibility_magnification_chooser_text" msgid="1227146738764986237">"మాగ్నిఫికేషన్"</string>
     <string name="user_switched" msgid="3768006783166984410">"ప్రస్తుత వినియోగదారు <xliff:g id="NAME">%1$s</xliff:g>."</string>
     <string name="user_switching_message" msgid="2871009331809089783">"<xliff:g id="NAME">%1$s</xliff:g>కి మారుస్తోంది…"</string>
diff --git a/core/res/res/values-th/strings.xml b/core/res/res/values-th/strings.xml
index 2bf0a9c..633c38e1 100644
--- a/core/res/res/values-th/strings.xml
+++ b/core/res/res/values-th/strings.xml
@@ -131,6 +131,7 @@
     <!-- no translation found for wfcSpnFormat_spn (4998685024207291232) -->
     <skip />
     <string name="wfcSpnFormat_spn_wifi_calling" msgid="136001023263502280">"การโทรผ่าน Wi-Fi <xliff:g id="SPN">%s</xliff:g>"</string>
+    <string name="wfcSpnFormat_spn_wifi_calling_vo_hyphen" msgid="1730997175789582756">"การโทรผ่าน Wi-Fi ของ <xliff:g id="SPN">%s</xliff:g>"</string>
     <string name="wfcSpnFormat_wlan_call" msgid="2533371081782489793">"การโทรผ่าน WLAN"</string>
     <string name="wfcSpnFormat_spn_wlan_call" msgid="2315240198303197168">"การโทรผ่าน WLAN <xliff:g id="SPN">%s</xliff:g>"</string>
     <string name="wfcSpnFormat_spn_wifi" msgid="6546481665561961938">"Wi-Fi <xliff:g id="SPN">%s</xliff:g>"</string>
@@ -1357,8 +1358,7 @@
     <string name="test_harness_mode_notification_message" msgid="1343197173054407119">"รีเซ็ตเป็นค่าเริ่มต้นเพื่อปิดใช้โหมดโปรแกรมทดสอบอัตโนมัติ"</string>
     <string name="usb_contaminant_detected_title" msgid="7136400633704058349">"มีของเหลวหรือฝุ่นละอองในพอร์ต USB"</string>
     <string name="usb_contaminant_detected_message" msgid="832337061059487250">"พอร์ต USB ปิดใช้โดยอัตโนมัติ แตะเพื่อดูข้อมูลเพิ่มเติม"</string>
-    <!-- no translation found for usb_contaminant_not_detected_title (7708281124088684821) -->
-    <skip />
+    <string name="usb_contaminant_not_detected_title" msgid="7708281124088684821">"ใช้พอร์ต USB ได้แล้ว"</string>
     <string name="usb_contaminant_not_detected_message" msgid="2415791798244545292">"โทรศัพท์ไม่ได้ตรวจจับของเหลวและฝุ่นละอองแล้ว"</string>
     <string name="taking_remote_bugreport_notification_title" msgid="6742483073875060934">"กำลังสร้างรายงานข้อบกพร่อง…"</string>
     <string name="share_remote_bugreport_notification_title" msgid="4987095013583691873">"แชร์รายงานข้อบกพร่องไหม"</string>
@@ -1612,8 +1612,6 @@
     <string name="display_manager_overlay_display_name" msgid="5142365982271620716">"การวางซ้อน #<xliff:g id="ID">%1$d</xliff:g>"</string>
     <string name="display_manager_overlay_display_title" msgid="652124517672257172">"<xliff:g id="NAME">%1$s</xliff:g>: <xliff:g id="WIDTH">%2$d</xliff:g>x<xliff:g id="HEIGHT">%3$d</xliff:g>, <xliff:g id="DPI">%4$d</xliff:g> dpi"</string>
     <string name="display_manager_overlay_display_secure_suffix" msgid="6022119702628572080">", ปลอดภัย"</string>
-    <string name="activity_starter_block_bg_activity_starts_permissive" msgid="6995473033438879646">"การเริ่มกิจกรรมในเบื้องหลังจาก <xliff:g id="PACKAGENAME">%1$s</xliff:g> นี้จะถูกบล็อกในบิวด์ Q ในอนาคต โปรดดู g.co/dev/bgblock"</string>
-    <string name="activity_starter_block_bg_activity_starts_enforcing" msgid="3317816771072146229">"บล็อกการเริ่มกิจกรรมในเบื้องหลังจาก <xliff:g id="PACKAGENAME">%1$s</xliff:g> แล้ว โปรดดู g.co/dev/bgblock"</string>
     <string name="kg_forgot_pattern_button_text" msgid="8852021467868220608">"ลืมรูปแบบใช่หรือไม่"</string>
     <string name="kg_wrong_pattern" msgid="1850806070801358830">"รูปแบบไม่ถูกต้อง"</string>
     <string name="kg_wrong_password" msgid="2333281762128113157">"รหัสผ่านไม่ถูกต้อง"</string>
@@ -1667,8 +1665,12 @@
     <string name="accessibility_shortcut_enabling_service" msgid="7771852911861522636">"ทางลัดการเข้าถึงเปิด <xliff:g id="SERVICE_NAME">%1$s</xliff:g> แล้ว"</string>
     <string name="accessibility_shortcut_disabling_service" msgid="2747243438223109821">"ทางลัดการเข้าถึงปิด <xliff:g id="SERVICE_NAME">%1$s</xliff:g> แล้ว"</string>
     <string name="accessibility_shortcut_spoken_feedback" msgid="8376923232350078434">"กดปุ่มปรับระดับเสียงทั้ง 2 ปุ่มค้างไว้ 3 วินาทีเพื่อใช้ <xliff:g id="SERVICE_NAME">%1$s</xliff:g>"</string>
-    <string name="accessibility_button_prompt_text" msgid="4234556536456854251">"เลือกฟีเจอร์ที่จะใช้เมื่อคุณแตะปุ่ม \"การช่วยเหลือพิเศษ\":"</string>
-    <string name="accessibility_button_instructional_text" msgid="6942300463612999993">"หากต้องการเปลี่ยนฟีเจอร์ ให้แตะปุ่ม \"การช่วยเหลือพิเศษ\" ค้างไว้"</string>
+    <string name="accessibility_button_prompt_text" msgid="1176658502969738564">"เลือกบริการที่จะใช้เมื่อคุณแตะปุ่มการช่วยเหลือพิเศษ:"</string>
+    <string name="accessibility_gesture_prompt_text" msgid="8259145549733019401">"เลือกบริการที่จะใช้กับท่าทางสัมผัสการช่วยเหลือพิเศษ (ใช้ 2 นิ้วเลื่อนขึ้นจากด้านล่างของหน้าจอ):"</string>
+    <string name="accessibility_gesture_3finger_prompt_text" msgid="1041435574275047665">"เลือกบริการที่จะใช้กับท่าทางสัมผัสการช่วยเหลือพิเศษ (ใช้ 3 นิ้วเลื่อนขึ้นจากด้านล่างของหน้าจอ):"</string>
+    <string name="accessibility_button_instructional_text" msgid="7003212763213614833">"หากต้องการสลับระหว่างบริการ ให้แตะปุ่มการช่วยเหลือพิเศษค้างไว้"</string>
+    <string name="accessibility_gesture_instructional_text" msgid="5261788874937410950">"หากต้องการสลับระหว่างบริการ ให้ใช้ 2 นิ้วเลื่อนขึ้นค้างไว้"</string>
+    <string name="accessibility_gesture_3finger_instructional_text" msgid="4969448938984394550">"หากต้องการสลับระหว่างบริการ ให้ใช้ 3 นิ้วเลื่อนขึ้นค้างไว้"</string>
     <string name="accessibility_magnification_chooser_text" msgid="1227146738764986237">"การขยาย"</string>
     <string name="user_switched" msgid="3768006783166984410">"ผู้ใช้ปัจจุบัน <xliff:g id="NAME">%1$s</xliff:g>"</string>
     <string name="user_switching_message" msgid="2871009331809089783">"กำลังเปลี่ยนเป็น <xliff:g id="NAME">%1$s</xliff:g>…"</string>
diff --git a/core/res/res/values-tl/strings.xml b/core/res/res/values-tl/strings.xml
index 02410f2..714a6ea8 100644
--- a/core/res/res/values-tl/strings.xml
+++ b/core/res/res/values-tl/strings.xml
@@ -131,6 +131,7 @@
     <!-- no translation found for wfcSpnFormat_spn (4998685024207291232) -->
     <skip />
     <string name="wfcSpnFormat_spn_wifi_calling" msgid="136001023263502280">"Pagtawag Gamit ang Wi-Fi ng <xliff:g id="SPN">%s</xliff:g>"</string>
+    <string name="wfcSpnFormat_spn_wifi_calling_vo_hyphen" msgid="1730997175789582756">"Pagtawag Gamit ang WiFi ng <xliff:g id="SPN">%s</xliff:g>"</string>
     <string name="wfcSpnFormat_wlan_call" msgid="2533371081782489793">"Pagtawag Gamit ang WLAN"</string>
     <string name="wfcSpnFormat_spn_wlan_call" msgid="2315240198303197168">"Pagtawag Gamit ang WLAN ng <xliff:g id="SPN">%s</xliff:g>"</string>
     <string name="wfcSpnFormat_spn_wifi" msgid="6546481665561961938">"Wi-Fi ng <xliff:g id="SPN">%s</xliff:g>"</string>
@@ -1357,8 +1358,7 @@
     <string name="test_harness_mode_notification_message" msgid="1343197173054407119">"Mag-factory reset para i-disable ang Test Harness Mode."</string>
     <string name="usb_contaminant_detected_title" msgid="7136400633704058349">"Liquid o debris sa USB port"</string>
     <string name="usb_contaminant_detected_message" msgid="832337061059487250">"Awtomatikong na-disable ang USB port. Mag-tap para matuto pa."</string>
-    <!-- no translation found for usb_contaminant_not_detected_title (7708281124088684821) -->
-    <skip />
+    <string name="usb_contaminant_not_detected_title" msgid="7708281124088684821">"Ayos na gamitin ang USB port"</string>
     <string name="usb_contaminant_not_detected_message" msgid="2415791798244545292">"Hindi na nakaka-detect ang telepono ng liquid o debris."</string>
     <string name="taking_remote_bugreport_notification_title" msgid="6742483073875060934">"Kinukuha ang ulat ng bug…"</string>
     <string name="share_remote_bugreport_notification_title" msgid="4987095013583691873">"Gusto mo bang ibahagi ang ulat ng bug?"</string>
@@ -1612,8 +1612,6 @@
     <string name="display_manager_overlay_display_name" msgid="5142365982271620716">"Overlay #<xliff:g id="ID">%1$d</xliff:g>"</string>
     <string name="display_manager_overlay_display_title" msgid="652124517672257172">"<xliff:g id="NAME">%1$s</xliff:g>: <xliff:g id="WIDTH">%2$d</xliff:g>x<xliff:g id="HEIGHT">%3$d</xliff:g>, <xliff:g id="DPI">%4$d</xliff:g> dpi"</string>
     <string name="display_manager_overlay_display_secure_suffix" msgid="6022119702628572080">", secure"</string>
-    <string name="activity_starter_block_bg_activity_starts_permissive" msgid="6995473033438879646">"Iba-block ang pagsisimula ng aktibidad sa background na ito mula sa <xliff:g id="PACKAGENAME">%1$s</xliff:g> sa mga Q build sa hinaharap. Tingnan ang g.co/dev/bgblock."</string>
-    <string name="activity_starter_block_bg_activity_starts_enforcing" msgid="3317816771072146229">"Na-block ang pagsisimula ng aktibidad sa background mula sa <xliff:g id="PACKAGENAME">%1$s</xliff:g>. Tingnan ang g.co/dev/bgblock."</string>
     <string name="kg_forgot_pattern_button_text" msgid="8852021467868220608">"Nakalimutan ang Pattern"</string>
     <string name="kg_wrong_pattern" msgid="1850806070801358830">"Maling Pattern"</string>
     <string name="kg_wrong_password" msgid="2333281762128113157">"Maling Password"</string>
@@ -1667,8 +1665,12 @@
     <string name="accessibility_shortcut_enabling_service" msgid="7771852911861522636">"Na-on ng Shortcut sa Accessibility ang <xliff:g id="SERVICE_NAME">%1$s</xliff:g>"</string>
     <string name="accessibility_shortcut_disabling_service" msgid="2747243438223109821">"Na-off ng Shortcut sa Accessibility ang <xliff:g id="SERVICE_NAME">%1$s</xliff:g>"</string>
     <string name="accessibility_shortcut_spoken_feedback" msgid="8376923232350078434">"Pindutin nang matagal ang parehong volume key sa loob ng tatlong segundo para magamit ang <xliff:g id="SERVICE_NAME">%1$s</xliff:g>"</string>
-    <string name="accessibility_button_prompt_text" msgid="4234556536456854251">"Pumili ng feature na gagamitin kapag na-tap mo ang button ng Pagiging Accessible:"</string>
-    <string name="accessibility_button_instructional_text" msgid="6942300463612999993">"Upang baguhin ang mga feature, pindutin nang matagal ang button ng Pagiging Naa-access."</string>
+    <string name="accessibility_button_prompt_text" msgid="1176658502969738564">"Pumili ng serbisyong gagamitin kapag na-tap mo ang button ng pagiging accessible:"</string>
+    <string name="accessibility_gesture_prompt_text" msgid="8259145549733019401">"Pumili ng serbisyong gagamitin sa galaw ng pagiging accessible (pag-swipe pataas mula sa ibaba ng screen gamit ang dalawang daliri):"</string>
+    <string name="accessibility_gesture_3finger_prompt_text" msgid="1041435574275047665">"Pumili ng serbisyong gagamitin sa galaw ng pagiging accessible (pag-swipe pataas mula sa ibaba ng screen gamit ang tatlong daliri):"</string>
+    <string name="accessibility_button_instructional_text" msgid="7003212763213614833">"Para magpalipat-lipat sa mga serbisyo, pindutin nang matagal ang button ng pagiging accessible."</string>
+    <string name="accessibility_gesture_instructional_text" msgid="5261788874937410950">"Para magpalipat-lipat sa mga serbisyo, mag-swipe pataas gamit ang dalawang daliri at i-hold."</string>
+    <string name="accessibility_gesture_3finger_instructional_text" msgid="4969448938984394550">"Para magpalipat-lipat sa mga serbisyo, mag-swipe pataas gamit ang tatlong daliri at i-hold."</string>
     <string name="accessibility_magnification_chooser_text" msgid="1227146738764986237">"Pag-magnify"</string>
     <string name="user_switched" msgid="3768006783166984410">"Kasalukuyang user <xliff:g id="NAME">%1$s</xliff:g>."</string>
     <string name="user_switching_message" msgid="2871009331809089783">"Lumilipat kay <xliff:g id="NAME">%1$s</xliff:g>…"</string>
diff --git a/core/res/res/values-tr/strings.xml b/core/res/res/values-tr/strings.xml
index 6800a72..eaf6bbf 100644
--- a/core/res/res/values-tr/strings.xml
+++ b/core/res/res/values-tr/strings.xml
@@ -131,6 +131,7 @@
     <!-- no translation found for wfcSpnFormat_spn (4998685024207291232) -->
     <skip />
     <string name="wfcSpnFormat_spn_wifi_calling" msgid="136001023263502280">"<xliff:g id="SPN">%s</xliff:g> Kablosuz Çağrı"</string>
+    <string name="wfcSpnFormat_spn_wifi_calling_vo_hyphen" msgid="1730997175789582756">"<xliff:g id="SPN">%s</xliff:g> Kablosuz Arama"</string>
     <string name="wfcSpnFormat_wlan_call" msgid="2533371081782489793">"WLAN Üzerinden Çağrı"</string>
     <string name="wfcSpnFormat_spn_wlan_call" msgid="2315240198303197168">"<xliff:g id="SPN">%s</xliff:g> WLAN Üzerinden Çağrı"</string>
     <string name="wfcSpnFormat_spn_wifi" msgid="6546481665561961938">"<xliff:g id="SPN">%s</xliff:g> Kablosuz"</string>
@@ -1357,8 +1358,7 @@
     <string name="test_harness_mode_notification_message" msgid="1343197173054407119">"Test Bandı Modu\'nu devre dışı bırakmak için cihazı fabrika ayarlarına sıfırlayın."</string>
     <string name="usb_contaminant_detected_title" msgid="7136400633704058349">"USB bağlantı noktasında sıvı veya toz var"</string>
     <string name="usb_contaminant_detected_message" msgid="832337061059487250">"USB bağlantı noktası otomatik olarak devre dışı bırakıldı. Daha fazla bilgi için dokunun."</string>
-    <!-- no translation found for usb_contaminant_not_detected_title (7708281124088684821) -->
-    <skip />
+    <string name="usb_contaminant_not_detected_title" msgid="7708281124088684821">"USB bağlantı noktasını kullanabilirsiniz"</string>
     <string name="usb_contaminant_not_detected_message" msgid="2415791798244545292">"Telefon artık sıvıları veya tozları algılamıyor."</string>
     <string name="taking_remote_bugreport_notification_title" msgid="6742483073875060934">"Hata raporu alınıyor…"</string>
     <string name="share_remote_bugreport_notification_title" msgid="4987095013583691873">"Hata raporu paylaşılsın mı?"</string>
@@ -1612,8 +1612,6 @@
     <string name="display_manager_overlay_display_name" msgid="5142365982271620716">"Yer Paylaşımı No. <xliff:g id="ID">%1$d</xliff:g>"</string>
     <string name="display_manager_overlay_display_title" msgid="652124517672257172">"<xliff:g id="NAME">%1$s</xliff:g>: <xliff:g id="WIDTH">%2$d</xliff:g>x<xliff:g id="HEIGHT">%3$d</xliff:g>, <xliff:g id="DPI">%4$d</xliff:g> dpi"</string>
     <string name="display_manager_overlay_display_secure_suffix" msgid="6022119702628572080">", güvenli"</string>
-    <string name="activity_starter_block_bg_activity_starts_permissive" msgid="6995473033438879646">"<xliff:g id="PACKAGENAME">%1$s</xliff:g> paketinden bu arka plan etkinliği başlangıcı, ilerideki Q derlemelerinde engellenecek. g.co/dev/bgblock adresini ziyaret edin."</string>
-    <string name="activity_starter_block_bg_activity_starts_enforcing" msgid="3317816771072146229">"<xliff:g id="PACKAGENAME">%1$s</xliff:g> paketinden arka plan etkinliği başlangıcı engellendi. g.co/dev/bgblock adresini ziyaret edin."</string>
     <string name="kg_forgot_pattern_button_text" msgid="8852021467868220608">"Deseni Unuttunuz mu?"</string>
     <string name="kg_wrong_pattern" msgid="1850806070801358830">"Yanlış Desen"</string>
     <string name="kg_wrong_password" msgid="2333281762128113157">"Yanlış Şifre"</string>
@@ -1667,8 +1665,12 @@
     <string name="accessibility_shortcut_enabling_service" msgid="7771852911861522636">"Erişilebilirlik Kısayolu <xliff:g id="SERVICE_NAME">%1$s</xliff:g> hizmetini açtı"</string>
     <string name="accessibility_shortcut_disabling_service" msgid="2747243438223109821">"Erişilebilirlik Kısayolu <xliff:g id="SERVICE_NAME">%1$s</xliff:g> hizmetini kapattı"</string>
     <string name="accessibility_shortcut_spoken_feedback" msgid="8376923232350078434">"<xliff:g id="SERVICE_NAME">%1$s</xliff:g> hizmetini kullanmak için her iki ses tuşunu basılı tutun"</string>
-    <string name="accessibility_button_prompt_text" msgid="4234556536456854251">"Erişilebilirlik düğmesine dokunduğunuzda kullanmak üzere bir özellik seçin:"</string>
-    <string name="accessibility_button_instructional_text" msgid="6942300463612999993">"Özellikleri değiştirmek için Erişilebilirlik düğmesine dokunup basılı tutun."</string>
+    <string name="accessibility_button_prompt_text" msgid="1176658502969738564">"Erişilebilirlik düğmesine dokunduğunuzda kullanmak üzere bir hizmet seçin:"</string>
+    <string name="accessibility_gesture_prompt_text" msgid="8259145549733019401">"Erişilebilirlik hareketiyle (iki parmakla ekranın altından yukarı kaydırma) kullanılacak bir hizmet seçin:"</string>
+    <string name="accessibility_gesture_3finger_prompt_text" msgid="1041435574275047665">"Erişilebilirlik hareketiyle (üç parmakla ekranın altından yukarı kaydırma) kullanılacak bir hizmet seçin:"</string>
+    <string name="accessibility_button_instructional_text" msgid="7003212763213614833">"Hizmetler arasında geçiş yapmak erişilebilirlik düğmesine dokunup basılı tutun."</string>
+    <string name="accessibility_gesture_instructional_text" msgid="5261788874937410950">"Hizmetler arasında geçiş yapmak için iki parmakla yukarı kaydırıp basılı tutun."</string>
+    <string name="accessibility_gesture_3finger_instructional_text" msgid="4969448938984394550">"Hizmetler arasında geçiş yapmak için üç parmakla yukarı kaydırıp basılı tutun."</string>
     <string name="accessibility_magnification_chooser_text" msgid="1227146738764986237">"Büyütme"</string>
     <string name="user_switched" msgid="3768006783166984410">"Geçerli kullanıcı: <xliff:g id="NAME">%1$s</xliff:g>."</string>
     <string name="user_switching_message" msgid="2871009331809089783">"<xliff:g id="NAME">%1$s</xliff:g> adlı kullanıcıya geçiliyor…"</string>
diff --git a/core/res/res/values-uk/strings.xml b/core/res/res/values-uk/strings.xml
index 993223772..c8c4bfc 100644
--- a/core/res/res/values-uk/strings.xml
+++ b/core/res/res/values-uk/strings.xml
@@ -133,6 +133,7 @@
     <!-- no translation found for wfcSpnFormat_spn (4998685024207291232) -->
     <skip />
     <string name="wfcSpnFormat_spn_wifi_calling" msgid="136001023263502280">"Виклики <xliff:g id="SPN">%s</xliff:g> через Wi-Fi"</string>
+    <string name="wfcSpnFormat_spn_wifi_calling_vo_hyphen" msgid="1730997175789582756">"Дзвінок від абонента <xliff:g id="SPN">%s</xliff:g> через Wi-Fi"</string>
     <string name="wfcSpnFormat_wlan_call" msgid="2533371081782489793">"Виклик через WLAN"</string>
     <string name="wfcSpnFormat_spn_wlan_call" msgid="2315240198303197168">"Виклик <xliff:g id="SPN">%s</xliff:g> через WLAN"</string>
     <string name="wfcSpnFormat_spn_wifi" msgid="6546481665561961938">"<xliff:g id="SPN">%s</xliff:g> через Wi-Fi"</string>
@@ -1401,8 +1402,7 @@
     <string name="test_harness_mode_notification_message" msgid="1343197173054407119">"Щоб вимкнути режим автоматизованого тестування, відновіть заводські налаштування."</string>
     <string name="usb_contaminant_detected_title" msgid="7136400633704058349">"Рідина або сміття в USB-порту"</string>
     <string name="usb_contaminant_detected_message" msgid="832337061059487250">"USB-порт автоматично вимкнено. Торкніться, щоб дізнатися більше."</string>
-    <!-- no translation found for usb_contaminant_not_detected_title (7708281124088684821) -->
-    <skip />
+    <string name="usb_contaminant_not_detected_title" msgid="7708281124088684821">"Можна використовувати USB-порт"</string>
     <string name="usb_contaminant_not_detected_message" msgid="2415791798244545292">"Телефон уже не виявляє рідини або сміття."</string>
     <string name="taking_remote_bugreport_notification_title" msgid="6742483073875060934">"Створюється повідомлення про помилку…"</string>
     <string name="share_remote_bugreport_notification_title" msgid="4987095013583691873">"Надіслати звіт про помилку?"</string>
@@ -1658,8 +1658,6 @@
     <string name="display_manager_overlay_display_name" msgid="5142365982271620716">"Накладання №<xliff:g id="ID">%1$d</xliff:g>"</string>
     <string name="display_manager_overlay_display_title" msgid="652124517672257172">"<xliff:g id="NAME">%1$s</xliff:g>: <xliff:g id="WIDTH">%2$d</xliff:g>х<xliff:g id="HEIGHT">%3$d</xliff:g>, <xliff:g id="DPI">%4$d</xliff:g> dpi"</string>
     <string name="display_manager_overlay_display_secure_suffix" msgid="6022119702628572080">", безпечний"</string>
-    <string name="activity_starter_block_bg_activity_starts_permissive" msgid="6995473033438879646">"Фонову активність пакета <xliff:g id="PACKAGENAME">%1$s</xliff:g> буде заблоковано в майбутніх складаннях Q. Докладніше: g.co/dev/bgblock."</string>
-    <string name="activity_starter_block_bg_activity_starts_enforcing" msgid="3317816771072146229">"Фонову активність додатка <xliff:g id="PACKAGENAME">%1$s</xliff:g> заблоковано. Докладніше: g.co/dev/bgblock."</string>
     <string name="kg_forgot_pattern_button_text" msgid="8852021467868220608">"Не пам’ятаю ключ"</string>
     <string name="kg_wrong_pattern" msgid="1850806070801358830">"Неправильний ключ"</string>
     <string name="kg_wrong_password" msgid="2333281762128113157">"Неправильний пароль"</string>
@@ -1715,8 +1713,12 @@
     <string name="accessibility_shortcut_enabling_service" msgid="7771852911861522636">"Ярлик спеціальних можливостей увімкнув <xliff:g id="SERVICE_NAME">%1$s</xliff:g>"</string>
     <string name="accessibility_shortcut_disabling_service" msgid="2747243438223109821">"Ярлик спеціальних можливостей вимкнув <xliff:g id="SERVICE_NAME">%1$s</xliff:g>"</string>
     <string name="accessibility_shortcut_spoken_feedback" msgid="8376923232350078434">"Щоб скористатися службою <xliff:g id="SERVICE_NAME">%1$s</xliff:g>, утримуйте обидві клавіші гучності впродовж трьох секунд"</string>
-    <string name="accessibility_button_prompt_text" msgid="4234556536456854251">"Виберіть функцію для кнопки спеціальних можливостей:"</string>
-    <string name="accessibility_button_instructional_text" msgid="6942300463612999993">"Щоб змінити функцію, натисніть і втримуйте кнопку спеціальних можливостей."</string>
+    <string name="accessibility_button_prompt_text" msgid="1176658502969738564">"Виберіть сервіс для кнопки спеціальних можливостей:"</string>
+    <string name="accessibility_gesture_prompt_text" msgid="8259145549733019401">"Виберіть сервіс для жесту спеціальних можливостей (проведення двома пальцями знизу вгору):"</string>
+    <string name="accessibility_gesture_3finger_prompt_text" msgid="1041435574275047665">"Виберіть сервіс для жесту спеціальних можливостей (проведення трьома пальцями знизу вгору):"</string>
+    <string name="accessibility_button_instructional_text" msgid="7003212763213614833">"Щоб переключитися між сервісами, натисніть і утримуйте кнопку спеціальних можливостей."</string>
+    <string name="accessibility_gesture_instructional_text" msgid="5261788874937410950">"Щоб переключитися між сервісами, проведіть двома пальцями вгору й утримуйте екран."</string>
+    <string name="accessibility_gesture_3finger_instructional_text" msgid="4969448938984394550">"Щоб переключитися між сервісами, проведіть трьома пальцями вгору й утримуйте екран."</string>
     <string name="accessibility_magnification_chooser_text" msgid="1227146738764986237">"Збільшення"</string>
     <string name="user_switched" msgid="3768006783166984410">"Поточний користувач: <xliff:g id="NAME">%1$s</xliff:g>."</string>
     <string name="user_switching_message" msgid="2871009331809089783">"Перехід в обліковий запис \"<xliff:g id="NAME">%1$s</xliff:g>\"…"</string>
diff --git a/core/res/res/values-ur/strings.xml b/core/res/res/values-ur/strings.xml
index 3deaa84..4d5f05c 100644
--- a/core/res/res/values-ur/strings.xml
+++ b/core/res/res/values-ur/strings.xml
@@ -131,6 +131,7 @@
     <!-- no translation found for wfcSpnFormat_spn (4998685024207291232) -->
     <skip />
     <string name="wfcSpnFormat_spn_wifi_calling" msgid="136001023263502280">"‏<xliff:g id="SPN">%s</xliff:g> Wi-Fi کالنگ"</string>
+    <string name="wfcSpnFormat_spn_wifi_calling_vo_hyphen" msgid="1730997175789582756">"‏<xliff:g id="SPN">%s</xliff:g> Wi-Fi کالنگ"</string>
     <string name="wfcSpnFormat_wlan_call" msgid="2533371081782489793">"‏WLAN کال"</string>
     <string name="wfcSpnFormat_spn_wlan_call" msgid="2315240198303197168">"‏<xliff:g id="SPN">%s</xliff:g> WLAN کال"</string>
     <string name="wfcSpnFormat_spn_wifi" msgid="6546481665561961938">"<xliff:g id="SPN">%s</xliff:g> Wi-Fi"</string>
@@ -1358,8 +1359,7 @@
     <string name="test_harness_mode_notification_message" msgid="1343197173054407119">"ٹیسٹ ہارنیس موڈ غیر فعال کرنے کے لیے فیکٹری ری سیٹ کریں۔"</string>
     <string name="usb_contaminant_detected_title" msgid="7136400633704058349">"‏USB پورٹ میں سیال یا دھول ہے"</string>
     <string name="usb_contaminant_detected_message" msgid="832337061059487250">"‏USB پورٹ خودکار طور پر غیر فعال کر دیا گیا۔ مزید جاننے کیلئے تھپتھپائیں۔"</string>
-    <!-- no translation found for usb_contaminant_not_detected_title (7708281124088684821) -->
-    <skip />
+    <string name="usb_contaminant_not_detected_title" msgid="7708281124088684821">"‏USB پورٹ کا استعمال ٹھیک ہے"</string>
     <string name="usb_contaminant_not_detected_message" msgid="2415791798244545292">"فون مزید سیال یا دھول کا پتہ نہیں لگاتا۔"</string>
     <string name="taking_remote_bugreport_notification_title" msgid="6742483073875060934">"بگ رپورٹ لی جا رہی ہے…"</string>
     <string name="share_remote_bugreport_notification_title" msgid="4987095013583691873">"بگ رپورٹ کا اشتراک کریں؟"</string>
@@ -1613,8 +1613,6 @@
     <string name="display_manager_overlay_display_name" msgid="5142365982271620716">"‏اوور لے ‎#<xliff:g id="ID">%1$d</xliff:g>"</string>
     <string name="display_manager_overlay_display_title" msgid="652124517672257172">"<xliff:g id="NAME">%1$s</xliff:g>: <xliff:g id="WIDTH">%2$d</xliff:g>x<xliff:g id="HEIGHT">%3$d</xliff:g>, <xliff:g id="DPI">%4$d</xliff:g> dpi"</string>
     <string name="display_manager_overlay_display_secure_suffix" msgid="6022119702628572080">"، محفوظ"</string>
-    <string name="activity_starter_block_bg_activity_starts_permissive" msgid="6995473033438879646">"‏<xliff:g id="PACKAGENAME">%1$s</xliff:g> سے شروع ہونے والی پس منظر کی اس سرگرمی کو مستقبل کے Q بلڈز میں مسدود کر دیا جائے گا۔ g.co/dev/bgblock ملاحظہ کریں۔"</string>
-    <string name="activity_starter_block_bg_activity_starts_enforcing" msgid="3317816771072146229">"‏<xliff:g id="PACKAGENAME">%1$s</xliff:g> سے شروع ہونے والی پس منظر کی سرگرمی کو مسدود کر دیا گیا ہے۔ g.co/dev/bgblock ملاحظہ کریں۔"</string>
     <string name="kg_forgot_pattern_button_text" msgid="8852021467868220608">"پیٹرن بھول گئے"</string>
     <string name="kg_wrong_pattern" msgid="1850806070801358830">"غلط پیٹرن"</string>
     <string name="kg_wrong_password" msgid="2333281762128113157">"غلط پاس ورڈ"</string>
@@ -1668,8 +1666,12 @@
     <string name="accessibility_shortcut_enabling_service" msgid="7771852911861522636">"ایکسیسبیلٹی شارٹ کٹ نے <xliff:g id="SERVICE_NAME">%1$s</xliff:g> کو آن کر دیا"</string>
     <string name="accessibility_shortcut_disabling_service" msgid="2747243438223109821">"ایکسیسبیلٹی شارٹ کٹ نے <xliff:g id="SERVICE_NAME">%1$s</xliff:g> کو آف کر دیا"</string>
     <string name="accessibility_shortcut_spoken_feedback" msgid="8376923232350078434">"<xliff:g id="SERVICE_NAME">%1$s</xliff:g> کا استعمال کرنے کے لیے 3 سیکنڈ تک والیوم کی دونوں کلیدوں کو چھوئیں اور دبائے رکھیں"</string>
-    <string name="accessibility_button_prompt_text" msgid="4234556536456854251">"ایکسیسبیلٹی بٹن پر تھپتھپانے وقت استعمال کرنے کیلئے ایک خصوصیت چنیں:"</string>
-    <string name="accessibility_button_instructional_text" msgid="6942300463612999993">"خصوصیات تبدیل کرنے کیلئے، ایکسیسبیلٹی بٹن ٹچ کریں اور دبائے رکھیں۔"</string>
+    <string name="accessibility_button_prompt_text" msgid="1176658502969738564">"ایکسیسبیلٹی بٹن پر تھپتھپانے وقت استعمال کرنے کیلئے ایک سروس چنیں:"</string>
+    <string name="accessibility_gesture_prompt_text" msgid="8259145549733019401">"ایکسیسبیلٹی اشارہ کے ساتھ استعمال کرنے کے لیے ایک سروس چنیں (دو انگلیوں سے اسکرین کے نیچے سے اوپر کی طرف سوائپ کریں):"</string>
+    <string name="accessibility_gesture_3finger_prompt_text" msgid="1041435574275047665">"ایکسیسبیلٹی اشارہ کے ساتھ استعمال کرنے کے لیے ایک سروس چنیں (تین انگلیوں سے اسکرین کے نیچے سے اوپر کی طرف سوائپ کریں):"</string>
+    <string name="accessibility_button_instructional_text" msgid="7003212763213614833">"سروسز کے مابین سوئچ کرنے کے لیے، ایکسیسبیلٹی بٹن کو ٹچ کرکے ہولڈ کریں۔"</string>
+    <string name="accessibility_gesture_instructional_text" msgid="5261788874937410950">"سروسز کے مابین سوئچ کرنے کے لیے، دو انگلیوں سے سوائپ کرکے ہولڈ کریں۔"</string>
+    <string name="accessibility_gesture_3finger_instructional_text" msgid="4969448938984394550">"سروسز کے مابین سوئچ کرنے کے لیے، تین انگلیوں سے سوائپ کرکے ہولڈ کریں۔"</string>
     <string name="accessibility_magnification_chooser_text" msgid="1227146738764986237">"میگنیفکیشن"</string>
     <string name="user_switched" msgid="3768006783166984410">"موجودہ صارف <xliff:g id="NAME">%1$s</xliff:g>۔"</string>
     <string name="user_switching_message" msgid="2871009331809089783">"<xliff:g id="NAME">%1$s</xliff:g> پر سوئچ کیا جا رہا ہے…"</string>
diff --git a/core/res/res/values-uz/strings.xml b/core/res/res/values-uz/strings.xml
index 1edf644..6c1e435 100644
--- a/core/res/res/values-uz/strings.xml
+++ b/core/res/res/values-uz/strings.xml
@@ -131,6 +131,7 @@
     <!-- no translation found for wfcSpnFormat_spn (4998685024207291232) -->
     <skip />
     <string name="wfcSpnFormat_spn_wifi_calling" msgid="136001023263502280">"<xliff:g id="SPN">%s</xliff:g> Wi-Fi chaqiruv"</string>
+    <string name="wfcSpnFormat_spn_wifi_calling_vo_hyphen" msgid="1730997175789582756">"<xliff:g id="SPN">%s</xliff:g> Wi-Fi chaqiruv"</string>
     <string name="wfcSpnFormat_wlan_call" msgid="2533371081782489793">"WLAN chaqiruv"</string>
     <string name="wfcSpnFormat_spn_wlan_call" msgid="2315240198303197168">"<xliff:g id="SPN">%s</xliff:g> WLAN chaqiruv"</string>
     <string name="wfcSpnFormat_spn_wifi" msgid="6546481665561961938">"<xliff:g id="SPN">%s</xliff:g> Wi-Fi"</string>
@@ -1358,8 +1359,7 @@
     <string name="test_harness_mode_notification_message" msgid="1343197173054407119">"Xavfsizlik sinovi rejimini faolsizlantirish uchun zavod sozlamalariga qaytaring."</string>
     <string name="usb_contaminant_detected_title" msgid="7136400633704058349">"USB portda suyuqlik yoki parcha bor"</string>
     <string name="usb_contaminant_detected_message" msgid="832337061059487250">"USB port avtomatik tarzda faolsizlashtirildi. Batafsil axborot olish uchun bosing."</string>
-    <!-- no translation found for usb_contaminant_not_detected_title (7708281124088684821) -->
-    <skip />
+    <string name="usb_contaminant_not_detected_title" msgid="7708281124088684821">"USB portdan foydalanish mumkin"</string>
     <string name="usb_contaminant_not_detected_message" msgid="2415791798244545292">"Telefon endi suyuqlik yoki turli parchalarni aniqlay olmaydi."</string>
     <string name="taking_remote_bugreport_notification_title" msgid="6742483073875060934">"Xatoliklar hisoboti olinmoqda…"</string>
     <string name="share_remote_bugreport_notification_title" msgid="4987095013583691873">"Xatoliklar hisoboti yuborilsinmi?"</string>
@@ -1495,7 +1495,7 @@
     <string name="find_next" msgid="5742124618942193978">"Keyingisini topish"</string>
     <string name="find_previous" msgid="2196723669388360506">"Oldingisini topish"</string>
     <string name="gpsNotifTicker" msgid="5622683912616496172">"<xliff:g id="NAME">%s</xliff:g>dan manzil haqida so‘rov"</string>
-    <string name="gpsNotifTitle" msgid="5446858717157416839">"Manzil so‘rovi"</string>
+    <string name="gpsNotifTitle" msgid="5446858717157416839">"Joylashuv axboroti talabi"</string>
     <string name="gpsNotifMessage" msgid="1374718023224000702">"<xliff:g id="NAME">%1$s</xliff:g> (<xliff:g id="SERVICE">%2$s</xliff:g>) tomonidan so‘raldi"</string>
     <string name="gpsVerifYes" msgid="2346566072867213563">"Ha"</string>
     <string name="gpsVerifNo" msgid="1146564937346454865">"Yo‘q"</string>
@@ -1613,8 +1613,6 @@
     <string name="display_manager_overlay_display_name" msgid="5142365982271620716">"Tasvir uzatish #<xliff:g id="ID">%1$d</xliff:g>"</string>
     <string name="display_manager_overlay_display_title" msgid="652124517672257172">"<xliff:g id="NAME">%1$s</xliff:g>: <xliff:g id="WIDTH">%2$d</xliff:g>x<xliff:g id="HEIGHT">%3$d</xliff:g>, <xliff:g id="DPI">%4$d</xliff:g> dpi"</string>
     <string name="display_manager_overlay_display_secure_suffix" msgid="6022119702628572080">", xavfsiz"</string>
-    <string name="activity_starter_block_bg_activity_starts_permissive" msgid="6995473033438879646">"Keyingi Android Q nashrlarida fondagi ushbu <xliff:g id="PACKAGENAME">%1$s</xliff:g> jarayoni bloklanadi. g.co/dev/bgblock bilan tanishing."</string>
-    <string name="activity_starter_block_bg_activity_starts_enforcing" msgid="3317816771072146229">"Fondagi <xliff:g id="PACKAGENAME">%1$s</xliff:g> jarayoni bloklandi. g.co/dev/bgblock bilan tanishing."</string>
     <string name="kg_forgot_pattern_button_text" msgid="8852021467868220608">"Grafik kalit esimdan chiqdi"</string>
     <string name="kg_wrong_pattern" msgid="1850806070801358830">"Grafik kalit xato"</string>
     <string name="kg_wrong_password" msgid="2333281762128113157">"Parol noto‘g‘ri"</string>
@@ -1668,8 +1666,12 @@
     <string name="accessibility_shortcut_enabling_service" msgid="7771852911861522636">"<xliff:g id="SERVICE_NAME">%1$s</xliff:g> xizmati yoqildi"</string>
     <string name="accessibility_shortcut_disabling_service" msgid="2747243438223109821">"<xliff:g id="SERVICE_NAME">%1$s</xliff:g> xizmati o‘chirib qo‘yildi"</string>
     <string name="accessibility_shortcut_spoken_feedback" msgid="8376923232350078434">"<xliff:g id="SERVICE_NAME">%1$s</xliff:g> xizmatidan foydalanish uchun ikkala ovoz balandligi tugmalarini uzoq bosib turing"</string>
-    <string name="accessibility_button_prompt_text" msgid="4234556536456854251">"Maxsus imkoniyatlar tugmasi bosilganda ishga tushadigan funksiyani tanlang:"</string>
-    <string name="accessibility_button_instructional_text" msgid="6942300463612999993">"Funksiyalarni o‘zgartirish uchun Maxsus imkoniyatlar tugmasini bosib turing."</string>
+    <string name="accessibility_button_prompt_text" msgid="1176658502969738564">"Maxsus imkoniyatlar tugmasi bosilganda ishga tushadigan xizmatni tanlang:"</string>
+    <string name="accessibility_gesture_prompt_text" msgid="8259145549733019401">"Maxsus imkoniyatlar ishorasi bilan ishga tushadigan xizmatni tanlang (2 barmoq bilan ekranning pastidan tepaga surib tortilganda:"</string>
+    <string name="accessibility_gesture_3finger_prompt_text" msgid="1041435574275047665">"Maxsus imkoniyatlar ishorasi bilan ishga tushadigan xizmatni tanlang (3 barmoq bilan ekranning pastidan tepaga surib tortilganda:"</string>
+    <string name="accessibility_button_instructional_text" msgid="7003212763213614833">"Xizmatlarni almashtirihs uchun maxsus imkoniyatlar tugmasini bosib turing."</string>
+    <string name="accessibility_gesture_instructional_text" msgid="5261788874937410950">"Xizmatlarni almashtirish uchun 2 barmoq bilan tepaga suring va bosib turing."</string>
+    <string name="accessibility_gesture_3finger_instructional_text" msgid="4969448938984394550">"Xizmatlarni almashtirish uchun 3 barmoq bilan tepaga suring va bosib turing."</string>
     <string name="accessibility_magnification_chooser_text" msgid="1227146738764986237">"Kattalashtirish"</string>
     <string name="user_switched" msgid="3768006783166984410">"Joriy foydalanuvchi <xliff:g id="NAME">%1$s</xliff:g>."</string>
     <string name="user_switching_message" msgid="2871009331809089783">"Quyidagi foydalanuvchiga o‘tilmoqda: <xliff:g id="NAME">%1$s</xliff:g>…"</string>
diff --git a/core/res/res/values-vi/strings.xml b/core/res/res/values-vi/strings.xml
index 7c69ee4..7e0e9693 100644
--- a/core/res/res/values-vi/strings.xml
+++ b/core/res/res/values-vi/strings.xml
@@ -131,6 +131,7 @@
     <!-- no translation found for wfcSpnFormat_spn (4998685024207291232) -->
     <skip />
     <string name="wfcSpnFormat_spn_wifi_calling" msgid="136001023263502280">"Gọi qua Wi-Fi <xliff:g id="SPN">%s</xliff:g>"</string>
+    <string name="wfcSpnFormat_spn_wifi_calling_vo_hyphen" msgid="1730997175789582756">"Gọi qua Wi-Fi <xliff:g id="SPN">%s</xliff:g>"</string>
     <string name="wfcSpnFormat_wlan_call" msgid="2533371081782489793">"Cuộc gọi qua WLAN"</string>
     <string name="wfcSpnFormat_spn_wlan_call" msgid="2315240198303197168">"Cuộc gọi qua WLAN <xliff:g id="SPN">%s</xliff:g>"</string>
     <string name="wfcSpnFormat_spn_wifi" msgid="6546481665561961938">"Wi-Fi <xliff:g id="SPN">%s</xliff:g>"</string>
@@ -683,7 +684,7 @@
     <string name="policydesc_disableKeyguardFeatures" msgid="2044755691354158439">"Ngăn sử dụng một số tính năng của phương thức khóa màn hình."</string>
   <string-array name="phoneTypes">
     <item msgid="8901098336658710359">"Nhà riêng"</item>
-    <item msgid="869923650527136615">"Di Động"</item>
+    <item msgid="869923650527136615">"Di động"</item>
     <item msgid="7897544654242874543">"Cơ quan"</item>
     <item msgid="1103601433382158155">"Số fax cơ quan"</item>
     <item msgid="1735177144948329370">"Số fax nhà riêng"</item>
@@ -1357,8 +1358,7 @@
     <string name="test_harness_mode_notification_message" msgid="1343197173054407119">"Khôi phục cài đặt gốc để tắt Chế độ khai thác kiểm thử."</string>
     <string name="usb_contaminant_detected_title" msgid="7136400633704058349">"Có chất lỏng hoặc mảnh vỡ trong cổng USB"</string>
     <string name="usb_contaminant_detected_message" msgid="832337061059487250">"Cổng USB đã tự động tắt. Nhấn để tìm hiểu thêm."</string>
-    <!-- no translation found for usb_contaminant_not_detected_title (7708281124088684821) -->
-    <skip />
+    <string name="usb_contaminant_not_detected_title" msgid="7708281124088684821">"Có thể sử dụng cổng USB"</string>
     <string name="usb_contaminant_not_detected_message" msgid="2415791798244545292">"Điện thoại không còn phát hiện chất lỏng hay mảnh vỡ nữa."</string>
     <string name="taking_remote_bugreport_notification_title" msgid="6742483073875060934">"Đang thu thập báo cáo lỗi…"</string>
     <string name="share_remote_bugreport_notification_title" msgid="4987095013583691873">"Chia sẻ báo cáo lỗi?"</string>
@@ -1494,7 +1494,7 @@
     <string name="find_next" msgid="5742124618942193978">"Tìm kết quả phù hợp tiếp theo"</string>
     <string name="find_previous" msgid="2196723669388360506">"Tìm kết quả phù hợp trước"</string>
     <string name="gpsNotifTicker" msgid="5622683912616496172">"Yêu cầu vị trí từ <xliff:g id="NAME">%s</xliff:g>"</string>
-    <string name="gpsNotifTitle" msgid="5446858717157416839">"Yêu cầu vị trí"</string>
+    <string name="gpsNotifTitle" msgid="5446858717157416839">"Yêu cầu truy cập vị trí"</string>
     <string name="gpsNotifMessage" msgid="1374718023224000702">"Được yêu cầu bởi <xliff:g id="NAME">%1$s</xliff:g> (<xliff:g id="SERVICE">%2$s</xliff:g>)"</string>
     <string name="gpsVerifYes" msgid="2346566072867213563">"Có"</string>
     <string name="gpsVerifNo" msgid="1146564937346454865">"Không"</string>
@@ -1612,8 +1612,6 @@
     <string name="display_manager_overlay_display_name" msgid="5142365982271620716">"Lớp phủ #<xliff:g id="ID">%1$d</xliff:g>"</string>
     <string name="display_manager_overlay_display_title" msgid="652124517672257172">"<xliff:g id="NAME">%1$s</xliff:g>: <xliff:g id="WIDTH">%2$d</xliff:g>x<xliff:g id="HEIGHT">%3$d</xliff:g>, <xliff:g id="DPI">%4$d</xliff:g> dpi"</string>
     <string name="display_manager_overlay_display_secure_suffix" msgid="6022119702628572080">", an toàn"</string>
-    <string name="activity_starter_block_bg_activity_starts_permissive" msgid="6995473033438879646">"Tính năng bắt đầu hoạt động trong nền từ <xliff:g id="PACKAGENAME">%1$s</xliff:g> này sẽ bị chặn ở các bản dựng Q trong tương lai. Hãy xem trang g.co/dev/bgblock để biết thêm chi tiết."</string>
-    <string name="activity_starter_block_bg_activity_starts_enforcing" msgid="3317816771072146229">"Tính năng bắt đầu hoạt động trong nền từ <xliff:g id="PACKAGENAME">%1$s</xliff:g> đã bị chặn. Hãy xem trang g.co/dev/bgblock để biết thêm chi tiết."</string>
     <string name="kg_forgot_pattern_button_text" msgid="8852021467868220608">"Đã quên hình"</string>
     <string name="kg_wrong_pattern" msgid="1850806070801358830">"Hình không chính xác"</string>
     <string name="kg_wrong_password" msgid="2333281762128113157">"Mật khẩu sai"</string>
@@ -1667,8 +1665,12 @@
     <string name="accessibility_shortcut_enabling_service" msgid="7771852911861522636">"Đã bật phím tắt trợ năng <xliff:g id="SERVICE_NAME">%1$s</xliff:g>"</string>
     <string name="accessibility_shortcut_disabling_service" msgid="2747243438223109821">"Đã tắt phím tắt trợ năng <xliff:g id="SERVICE_NAME">%1$s</xliff:g>"</string>
     <string name="accessibility_shortcut_spoken_feedback" msgid="8376923232350078434">"Nhấn và giữ đồng thời cả hai phím âm lượng trong 3 giây để sử dụng <xliff:g id="SERVICE_NAME">%1$s</xliff:g>"</string>
-    <string name="accessibility_button_prompt_text" msgid="4234556536456854251">"Chọn tính năng sẽ sử dụng khi bạn nhấn nút Hỗ trợ tiếp cận:"</string>
-    <string name="accessibility_button_instructional_text" msgid="6942300463612999993">"Để thay đổi các tính năng, hãy chạm và giữ nút Hỗ trợ tiếp cận."</string>
+    <string name="accessibility_button_prompt_text" msgid="1176658502969738564">"Chọn dịch vụ sẽ sử dụng khi bạn nhấn vào nút hỗ trợ tiếp cận:"</string>
+    <string name="accessibility_gesture_prompt_text" msgid="8259145549733019401">"Chọn dịch vụ sẽ sử dụng với cử chỉ hỗ trợ tiếp cận (vuốt lên từ cuối màn hình bằng 2 ngón tay):"</string>
+    <string name="accessibility_gesture_3finger_prompt_text" msgid="1041435574275047665">"Chọn dịch vụ sẽ sử dụng với cử chỉ hỗ trợ tiếp cận (vuốt lên từ cuối màn hình bằng 3 ngón tay):"</string>
+    <string name="accessibility_button_instructional_text" msgid="7003212763213614833">"Để chuyển đổi giữa các dịch vụ, hãy chạm và giữ nút hỗ trợ tiếp cận."</string>
+    <string name="accessibility_gesture_instructional_text" msgid="5261788874937410950">"Để chuyển đổi giữa các dịch vụ, hãy vuốt lên và giữ bằng 2 ngón tay."</string>
+    <string name="accessibility_gesture_3finger_instructional_text" msgid="4969448938984394550">"Để chuyển đổi giữa các dịch vụ, hãy vuốt lên và giữ bằng 3 ngón tay."</string>
     <string name="accessibility_magnification_chooser_text" msgid="1227146738764986237">"Phóng to"</string>
     <string name="user_switched" msgid="3768006783166984410">"Người dùng hiện tại <xliff:g id="NAME">%1$s</xliff:g>."</string>
     <string name="user_switching_message" msgid="2871009331809089783">"Đang chuyển sang <xliff:g id="NAME">%1$s</xliff:g>…"</string>
diff --git a/core/res/res/values-zh-rCN/strings.xml b/core/res/res/values-zh-rCN/strings.xml
index eb8e9bb..d965d48 100644
--- a/core/res/res/values-zh-rCN/strings.xml
+++ b/core/res/res/values-zh-rCN/strings.xml
@@ -131,6 +131,7 @@
     <!-- no translation found for wfcSpnFormat_spn (4998685024207291232) -->
     <skip />
     <string name="wfcSpnFormat_spn_wifi_calling" msgid="136001023263502280">"<xliff:g id="SPN">%s</xliff:g> WLAN 通话"</string>
+    <string name="wfcSpnFormat_spn_wifi_calling_vo_hyphen" msgid="1730997175789582756">"<xliff:g id="SPN">%s</xliff:g> WLAN 通话"</string>
     <string name="wfcSpnFormat_wlan_call" msgid="2533371081782489793">"WLAN 通话"</string>
     <string name="wfcSpnFormat_spn_wlan_call" msgid="2315240198303197168">"<xliff:g id="SPN">%s</xliff:g> WLAN 通话"</string>
     <string name="wfcSpnFormat_spn_wifi" msgid="6546481665561961938">"<xliff:g id="SPN">%s</xliff:g> WLAN"</string>
@@ -1357,8 +1358,7 @@
     <string name="test_harness_mode_notification_message" msgid="1343197173054407119">"恢复出厂设置以停用自动化测试框架模式。"</string>
     <string name="usb_contaminant_detected_title" msgid="7136400633704058349">"USB 端口中有液体或碎屑"</string>
     <string name="usb_contaminant_detected_message" msgid="832337061059487250">"USB 端口已自动停用。点按即可了解详情。"</string>
-    <!-- no translation found for usb_contaminant_not_detected_title (7708281124088684821) -->
-    <skip />
+    <string name="usb_contaminant_not_detected_title" msgid="7708281124088684821">"允许使用 USB 端口"</string>
     <string name="usb_contaminant_not_detected_message" msgid="2415791798244545292">"手机不再检测到液体或碎屑。"</string>
     <string name="taking_remote_bugreport_notification_title" msgid="6742483073875060934">"正在生成错误报告…"</string>
     <string name="share_remote_bugreport_notification_title" msgid="4987095013583691873">"要分享错误报告吗?"</string>
@@ -1494,7 +1494,7 @@
     <string name="find_next" msgid="5742124618942193978">"下一条结果"</string>
     <string name="find_previous" msgid="2196723669388360506">"上一条结果"</string>
     <string name="gpsNotifTicker" msgid="5622683912616496172">"来自<xliff:g id="NAME">%s</xliff:g>的定位请求"</string>
-    <string name="gpsNotifTitle" msgid="5446858717157416839">"定位请求"</string>
+    <string name="gpsNotifTitle" msgid="5446858717157416839">"位置信息请求"</string>
     <string name="gpsNotifMessage" msgid="1374718023224000702">"请求人:<xliff:g id="NAME">%1$s</xliff:g>(<xliff:g id="SERVICE">%2$s</xliff:g>)"</string>
     <string name="gpsVerifYes" msgid="2346566072867213563">"是"</string>
     <string name="gpsVerifNo" msgid="1146564937346454865">"否"</string>
@@ -1612,8 +1612,6 @@
     <string name="display_manager_overlay_display_name" msgid="5142365982271620716">"叠加视图 #<xliff:g id="ID">%1$d</xliff:g>"</string>
     <string name="display_manager_overlay_display_title" msgid="652124517672257172">"<xliff:g id="NAME">%1$s</xliff:g>:<xliff:g id="WIDTH">%2$d</xliff:g>x<xliff:g id="HEIGHT">%3$d</xliff:g>,<xliff:g id="DPI">%4$d</xliff:g> dpi"</string>
     <string name="display_manager_overlay_display_secure_suffix" msgid="6022119702628572080">",安全"</string>
-    <string name="activity_starter_block_bg_activity_starts_permissive" msgid="6995473033438879646">"<xliff:g id="PACKAGENAME">%1$s</xliff:g> 的这类后台活动启动程序会在日后的 Android Q 版本中遭到屏蔽。请参阅 g.co/dev/bgblock。"</string>
-    <string name="activity_starter_block_bg_activity_starts_enforcing" msgid="3317816771072146229">"已屏蔽 <xliff:g id="PACKAGENAME">%1$s</xliff:g> 的后台活动启动程序。请参阅 g.co/dev/bgblock。"</string>
     <string name="kg_forgot_pattern_button_text" msgid="8852021467868220608">"忘记了图案"</string>
     <string name="kg_wrong_pattern" msgid="1850806070801358830">"图案错误"</string>
     <string name="kg_wrong_password" msgid="2333281762128113157">"密码错误"</string>
@@ -1667,8 +1665,12 @@
     <string name="accessibility_shortcut_enabling_service" msgid="7771852911861522636">"无障碍快捷方式已开启<xliff:g id="SERVICE_NAME">%1$s</xliff:g>"</string>
     <string name="accessibility_shortcut_disabling_service" msgid="2747243438223109821">"无障碍快捷方式已关闭<xliff:g id="SERVICE_NAME">%1$s</xliff:g>"</string>
     <string name="accessibility_shortcut_spoken_feedback" msgid="8376923232350078434">"同时按住两个音量键 3 秒钟即可使用 <xliff:g id="SERVICE_NAME">%1$s</xliff:g>"</string>
-    <string name="accessibility_button_prompt_text" msgid="4234556536456854251">"选择按下“无障碍”按钮时要使用的功能:"</string>
-    <string name="accessibility_button_instructional_text" msgid="6942300463612999993">"要更改指定的功能,请触摸并按住“无障碍”按钮。"</string>
+    <string name="accessibility_button_prompt_text" msgid="1176658502969738564">"选择按“无障碍”按钮后要使用的服务:"</string>
+    <string name="accessibility_gesture_prompt_text" msgid="8259145549733019401">"选择要搭配无障碍手势(用两指从屏幕底部向上滑动)使用的服务:"</string>
+    <string name="accessibility_gesture_3finger_prompt_text" msgid="1041435574275047665">"选择要搭配无障碍手势(用三指从屏幕底部向上滑动)使用的服务:"</string>
+    <string name="accessibility_button_instructional_text" msgid="7003212763213614833">"要在多项服务之间切换,请轻触并按住“无障碍”按钮。"</string>
+    <string name="accessibility_gesture_instructional_text" msgid="5261788874937410950">"要在多项服务之间切换,请用两指向上滑动并按住。"</string>
+    <string name="accessibility_gesture_3finger_instructional_text" msgid="4969448938984394550">"要在多项服务之间切换,请用三指向上滑动并按住。"</string>
     <string name="accessibility_magnification_chooser_text" msgid="1227146738764986237">"放大功能"</string>
     <string name="user_switched" msgid="3768006783166984410">"当前用户是<xliff:g id="NAME">%1$s</xliff:g>。"</string>
     <string name="user_switching_message" msgid="2871009331809089783">"正在切换为<xliff:g id="NAME">%1$s</xliff:g>…"</string>
diff --git a/core/res/res/values-zh-rHK/strings.xml b/core/res/res/values-zh-rHK/strings.xml
index e3def2e..86a962f 100644
--- a/core/res/res/values-zh-rHK/strings.xml
+++ b/core/res/res/values-zh-rHK/strings.xml
@@ -131,6 +131,7 @@
     <!-- no translation found for wfcSpnFormat_spn (4998685024207291232) -->
     <skip />
     <string name="wfcSpnFormat_spn_wifi_calling" msgid="136001023263502280">"<xliff:g id="SPN">%s</xliff:g> Wi-Fi 通話"</string>
+    <string name="wfcSpnFormat_spn_wifi_calling_vo_hyphen" msgid="1730997175789582756">"<xliff:g id="SPN">%s</xliff:g> Wi-Fi 通話"</string>
     <string name="wfcSpnFormat_wlan_call" msgid="2533371081782489793">"WLAN 通話"</string>
     <string name="wfcSpnFormat_spn_wlan_call" msgid="2315240198303197168">"<xliff:g id="SPN">%s</xliff:g> WLAN 通話"</string>
     <string name="wfcSpnFormat_spn_wifi" msgid="6546481665561961938">"<xliff:g id="SPN">%s</xliff:g> Wi-Fi"</string>
@@ -1357,8 +1358,7 @@
     <string name="test_harness_mode_notification_message" msgid="1343197173054407119">"請將裝置回復原廠設定,以停用測試工具模式。"</string>
     <string name="usb_contaminant_detected_title" msgid="7136400633704058349">"USB 連接埠中有液體或碎片"</string>
     <string name="usb_contaminant_detected_message" msgid="832337061059487250">"USB 連接埠已自動停用。輕按即可瞭解詳情。"</string>
-    <!-- no translation found for usb_contaminant_not_detected_title (7708281124088684821) -->
-    <skip />
+    <string name="usb_contaminant_not_detected_title" msgid="7708281124088684821">"USB 連接埠可安全使用"</string>
     <string name="usb_contaminant_not_detected_message" msgid="2415791798244545292">"手機不再偵測到液體或碎片。"</string>
     <string name="taking_remote_bugreport_notification_title" msgid="6742483073875060934">"正在取得錯誤報告…"</string>
     <string name="share_remote_bugreport_notification_title" msgid="4987095013583691873">"要分享錯誤報告嗎?"</string>
@@ -1612,8 +1612,6 @@
     <string name="display_manager_overlay_display_name" msgid="5142365982271620716">"重疊效果 #<xliff:g id="ID">%1$d</xliff:g>"</string>
     <string name="display_manager_overlay_display_title" msgid="652124517672257172">"<xliff:g id="NAME">%1$s</xliff:g>:<xliff:g id="WIDTH">%2$d</xliff:g>x<xliff:g id="HEIGHT">%3$d</xliff:g>,<xliff:g id="DPI">%4$d</xliff:g> dpi"</string>
     <string name="display_manager_overlay_display_secure_suffix" msgid="6022119702628572080">"(安全)"</string>
-    <string name="activity_starter_block_bg_activity_starts_permissive" msgid="6995473033438879646">"在日後的 Q 版本中,系統將會封鎖這個由 <xliff:g id="PACKAGENAME">%1$s</xliff:g> 啟動的背景活動。請瀏覽 g.co/dev/bgblock。"</string>
-    <string name="activity_starter_block_bg_activity_starts_enforcing" msgid="3317816771072146229">"已封鎖 <xliff:g id="PACKAGENAME">%1$s</xliff:g> 啟動的背景活動。請瀏覽 g.co/dev/bgblock。"</string>
     <string name="kg_forgot_pattern_button_text" msgid="8852021467868220608">"忘記圖案"</string>
     <string name="kg_wrong_pattern" msgid="1850806070801358830">"圖形不對"</string>
     <string name="kg_wrong_password" msgid="2333281762128113157">"密碼錯誤"</string>
@@ -1667,8 +1665,12 @@
     <string name="accessibility_shortcut_enabling_service" msgid="7771852911861522636">"無障礙功能快速鍵已啟用 <xliff:g id="SERVICE_NAME">%1$s</xliff:g>"</string>
     <string name="accessibility_shortcut_disabling_service" msgid="2747243438223109821">"無障礙功能快速鍵已停用 <xliff:g id="SERVICE_NAME">%1$s</xliff:g>"</string>
     <string name="accessibility_shortcut_spoken_feedback" msgid="8376923232350078434">"㩒住兩個音量鍵 3 秒就可以用 <xliff:g id="SERVICE_NAME">%1$s</xliff:g>"</string>
-    <string name="accessibility_button_prompt_text" msgid="4234556536456854251">"請選擇輕按「無障礙功能」按鈕時使用的功能:"</string>
-    <string name="accessibility_button_instructional_text" msgid="6942300463612999993">"如要變更功能,可按住「無障礙功能」按鈕。"</string>
+    <string name="accessibility_button_prompt_text" msgid="1176658502969738564">"請選擇輕按無障礙功能按鈕時使用的服務:"</string>
+    <string name="accessibility_gesture_prompt_text" msgid="8259145549733019401">"請選擇透過無障礙手勢 (使用兩隻手指從螢幕底部向上滑動) 使用的服務:"</string>
+    <string name="accessibility_gesture_3finger_prompt_text" msgid="1041435574275047665">"請選擇透過無障礙手勢 (使用三隻手指從螢幕底部向上滑動) 使用的服務:"</string>
+    <string name="accessibility_button_instructional_text" msgid="7003212763213614833">"如要在服務之間切換,請按住無障礙功能按鈕。"</string>
+    <string name="accessibility_gesture_instructional_text" msgid="5261788874937410950">"如要在服務之間切換,請使用兩隻手指向上滑動並按住。"</string>
+    <string name="accessibility_gesture_3finger_instructional_text" msgid="4969448938984394550">"如要在服務之間切換,請使用三隻手指向上滑動並按住。"</string>
     <string name="accessibility_magnification_chooser_text" msgid="1227146738764986237">"放大"</string>
     <string name="user_switched" msgid="3768006783166984410">"目前的使用者是<xliff:g id="NAME">%1$s</xliff:g>。"</string>
     <string name="user_switching_message" msgid="2871009331809089783">"正在切換至<xliff:g id="NAME">%1$s</xliff:g>…"</string>
diff --git a/core/res/res/values-zh-rTW/strings.xml b/core/res/res/values-zh-rTW/strings.xml
index 9c1b05d..e446c3f 100644
--- a/core/res/res/values-zh-rTW/strings.xml
+++ b/core/res/res/values-zh-rTW/strings.xml
@@ -131,6 +131,7 @@
     <!-- no translation found for wfcSpnFormat_spn (4998685024207291232) -->
     <skip />
     <string name="wfcSpnFormat_spn_wifi_calling" msgid="136001023263502280">"<xliff:g id="SPN">%s</xliff:g> Wi-Fi 通話"</string>
+    <string name="wfcSpnFormat_spn_wifi_calling_vo_hyphen" msgid="1730997175789582756">"<xliff:g id="SPN">%s</xliff:g> Wi-Fi 通話"</string>
     <string name="wfcSpnFormat_wlan_call" msgid="2533371081782489793">"WLAN 通話"</string>
     <string name="wfcSpnFormat_spn_wlan_call" msgid="2315240198303197168">"<xliff:g id="SPN">%s</xliff:g> WLAN 通話"</string>
     <string name="wfcSpnFormat_spn_wifi" msgid="6546481665561961938">"<xliff:g id="SPN">%s</xliff:g> Wi-Fi"</string>
@@ -1357,8 +1358,7 @@
     <string name="test_harness_mode_notification_message" msgid="1343197173054407119">"恢復原廠設定以停用測試控管工具模式。"</string>
     <string name="usb_contaminant_detected_title" msgid="7136400633704058349">"USB 連接埠中有液體或灰塵"</string>
     <string name="usb_contaminant_detected_message" msgid="832337061059487250">"系統已自動停用 USB 連接埠。輕觸即可瞭解詳情。"</string>
-    <!-- no translation found for usb_contaminant_not_detected_title (7708281124088684821) -->
-    <skip />
+    <string name="usb_contaminant_not_detected_title" msgid="7708281124088684821">"現在可以使用 USB 連接埠"</string>
     <string name="usb_contaminant_not_detected_message" msgid="2415791798244545292">"手機目前無法偵測液體或灰塵。"</string>
     <string name="taking_remote_bugreport_notification_title" msgid="6742483073875060934">"正在接收錯誤報告…"</string>
     <string name="share_remote_bugreport_notification_title" msgid="4987095013583691873">"要分享錯誤報告嗎?"</string>
@@ -1494,7 +1494,7 @@
     <string name="find_next" msgid="5742124618942193978">"尋找下一個項目"</string>
     <string name="find_previous" msgid="2196723669388360506">"尋找上一個項目"</string>
     <string name="gpsNotifTicker" msgid="5622683912616496172">"<xliff:g id="NAME">%s</xliff:g> 的地點要求"</string>
-    <string name="gpsNotifTitle" msgid="5446858717157416839">"位置要求"</string>
+    <string name="gpsNotifTitle" msgid="5446858717157416839">"位置資訊要求"</string>
     <string name="gpsNotifMessage" msgid="1374718023224000702">"要求者:<xliff:g id="NAME">%1$s</xliff:g> (<xliff:g id="SERVICE">%2$s</xliff:g>)"</string>
     <string name="gpsVerifYes" msgid="2346566072867213563">"是"</string>
     <string name="gpsVerifNo" msgid="1146564937346454865">"否"</string>
@@ -1612,8 +1612,6 @@
     <string name="display_manager_overlay_display_name" msgid="5142365982271620716">"第 <xliff:g id="ID">%1$d</xliff:g> 個重疊效果"</string>
     <string name="display_manager_overlay_display_title" msgid="652124517672257172">"<xliff:g id="NAME">%1$s</xliff:g>:<xliff:g id="WIDTH">%2$d</xliff:g>x<xliff:g id="HEIGHT">%3$d</xliff:g>,<xliff:g id="DPI">%4$d</xliff:g> dpi"</string>
     <string name="display_manager_overlay_display_secure_suffix" msgid="6022119702628572080">"(安全)"</string>
-    <string name="activity_starter_block_bg_activity_starts_permissive" msgid="6995473033438879646">"<xliff:g id="PACKAGENAME">%1$s</xliff:g> 的這類背景活動啟動程序會在日後的 Android Q 版本遭到封鎖。請前往 g.co/dev/bgblock 查看詳情。"</string>
-    <string name="activity_starter_block_bg_activity_starts_enforcing" msgid="3317816771072146229">"已封鎖 <xliff:g id="PACKAGENAME">%1$s</xliff:g> 的背景活動啟動程序。請前往 g.co/dev/bgblock 查看詳情。"</string>
     <string name="kg_forgot_pattern_button_text" msgid="8852021467868220608">"忘記圖案"</string>
     <string name="kg_wrong_pattern" msgid="1850806070801358830">"圖案錯誤"</string>
     <string name="kg_wrong_password" msgid="2333281762128113157">"密碼錯誤"</string>
@@ -1667,8 +1665,12 @@
     <string name="accessibility_shortcut_enabling_service" msgid="7771852911861522636">"無障礙捷徑啟用了「<xliff:g id="SERVICE_NAME">%1$s</xliff:g>」"</string>
     <string name="accessibility_shortcut_disabling_service" msgid="2747243438223109821">"無障礙捷徑停用了「<xliff:g id="SERVICE_NAME">%1$s</xliff:g>」"</string>
     <string name="accessibility_shortcut_spoken_feedback" msgid="8376923232350078434">"同時按住調低及調高音量鍵三秒即可使用「<xliff:g id="SERVICE_NAME">%1$s</xliff:g>」"</string>
-    <string name="accessibility_button_prompt_text" msgid="4234556536456854251">"輕觸 [無障礙設定] 按鈕後,選擇你想使用的功能:"</string>
-    <string name="accessibility_button_instructional_text" msgid="6942300463612999993">"如要變更指派的功能,請按住 [無障礙設定] 按鈕。"</string>
+    <string name="accessibility_button_prompt_text" msgid="1176658502969738564">"選擇輕觸無障礙按鈕後要使用的服務:"</string>
+    <string name="accessibility_gesture_prompt_text" msgid="8259145549733019401">"選擇要搭配無障礙手勢 (用兩指從螢幕底部向上滑動) 使用的服務:"</string>
+    <string name="accessibility_gesture_3finger_prompt_text" msgid="1041435574275047665">"選擇要搭配無障礙手勢 (用三指從螢幕底部向上滑動) 使用的服務:"</string>
+    <string name="accessibility_button_instructional_text" msgid="7003212763213614833">"如要切換不同的服務,請輕觸並按住無障礙按鈕。"</string>
+    <string name="accessibility_gesture_instructional_text" msgid="5261788874937410950">"如要切換不同的服務,請用兩指向上滑動並按住。"</string>
+    <string name="accessibility_gesture_3finger_instructional_text" msgid="4969448938984394550">"如要切換不同的服務,請用三指向上滑動並按住。"</string>
     <string name="accessibility_magnification_chooser_text" msgid="1227146738764986237">"放大"</string>
     <string name="user_switched" msgid="3768006783166984410">"目前的使用者是 <xliff:g id="NAME">%1$s</xliff:g>。"</string>
     <string name="user_switching_message" msgid="2871009331809089783">"正在切換至<xliff:g id="NAME">%1$s</xliff:g>…"</string>
diff --git a/core/res/res/values-zu/strings.xml b/core/res/res/values-zu/strings.xml
index 98ec22a..e15c378 100644
--- a/core/res/res/values-zu/strings.xml
+++ b/core/res/res/values-zu/strings.xml
@@ -131,6 +131,7 @@
     <!-- no translation found for wfcSpnFormat_spn (4998685024207291232) -->
     <skip />
     <string name="wfcSpnFormat_spn_wifi_calling" msgid="136001023263502280">"<xliff:g id="SPN">%s</xliff:g> ukushaya kwe-Wi-Fi"</string>
+    <string name="wfcSpnFormat_spn_wifi_calling_vo_hyphen" msgid="1730997175789582756">"<xliff:g id="SPN">%s</xliff:g> Ukushaya kwe-Wi-Fi"</string>
     <string name="wfcSpnFormat_wlan_call" msgid="2533371081782489793">"Ikholi ye-WLAN"</string>
     <string name="wfcSpnFormat_spn_wlan_call" msgid="2315240198303197168">"<xliff:g id="SPN">%s</xliff:g> ikholi ye-WLAN"</string>
     <string name="wfcSpnFormat_spn_wifi" msgid="6546481665561961938">"<xliff:g id="SPN">%s</xliff:g> Wi-Fi"</string>
@@ -1611,8 +1612,6 @@
     <string name="display_manager_overlay_display_name" msgid="5142365982271620716">"Isendlalelo #<xliff:g id="ID">%1$d</xliff:g>"</string>
     <string name="display_manager_overlay_display_title" msgid="652124517672257172">"<xliff:g id="NAME">%1$s</xliff:g>: <xliff:g id="WIDTH">%2$d</xliff:g>x<xliff:g id="HEIGHT">%3$d</xliff:g>, <xliff:g id="DPI">%4$d</xliff:g> dpi"</string>
     <string name="display_manager_overlay_display_secure_suffix" msgid="6022119702628572080">", kuphephile"</string>
-    <string name="activity_starter_block_bg_activity_starts_permissive" msgid="6995473033438879646">"Lesi siqalo somsebenzi ongemuva kusukela ku-<xliff:g id="PACKAGENAME">%1$s</xliff:g> sizovinjelwa ekwakhiweni okuzayo kwe-Q. Bona i-g.co/dev/bgblock."</string>
-    <string name="activity_starter_block_bg_activity_starts_enforcing" msgid="3317816771072146229">"Umsebenzi ongemuva oqala kusukela ku-<xliff:g id="PACKAGENAME">%1$s</xliff:g> uvinjelwe. Bona i-g.co/dev/bgblock."</string>
     <string name="kg_forgot_pattern_button_text" msgid="8852021467868220608">"Ukhohlwe iphethini?"</string>
     <string name="kg_wrong_pattern" msgid="1850806070801358830">"Iphatheni engalungile"</string>
     <string name="kg_wrong_password" msgid="2333281762128113157">"Iphasiwedi engalungile"</string>
@@ -1666,8 +1665,12 @@
     <string name="accessibility_shortcut_enabling_service" msgid="7771852911861522636">"Isinqamuleli sokufinyelela sivule i-<xliff:g id="SERVICE_NAME">%1$s</xliff:g>"</string>
     <string name="accessibility_shortcut_disabling_service" msgid="2747243438223109821">"Isinqamuleli sokufinyelela sivale i-<xliff:g id="SERVICE_NAME">%1$s</xliff:g>"</string>
     <string name="accessibility_shortcut_spoken_feedback" msgid="8376923232350078434">"Cindezela uphinde ubambe bobabili okhiye bevolumu ngamasekhondi amathathu ukuze usebenzise i-<xliff:g id="SERVICE_NAME">%1$s</xliff:g>"</string>
-    <string name="accessibility_button_prompt_text" msgid="4234556536456854251">"Khetha isici ozosisebenzisa uma uthepha inkinobho yokufinyelela:"</string>
-    <string name="accessibility_button_instructional_text" msgid="6942300463612999993">"Ukuze ushintshe izici, thinta uphinde ubambe inkinobho yokufinyelela."</string>
+    <string name="accessibility_button_prompt_text" msgid="1176658502969738564">"Khetha isevisi ozoyisebenzisa uma uthepha inkinobho yokufinyeleleka:"</string>
+    <string name="accessibility_gesture_prompt_text" msgid="8259145549733019401">"Khetha isevisi ezosetshenziswa ngokuthinta kokufinyeleleka (swayiphela phezulu kusukela ngaphansi kwesikrini ngeminwe emibili):"</string>
+    <string name="accessibility_gesture_3finger_prompt_text" msgid="1041435574275047665">"Khetha isevisi ozoyisebenzisa ngokuthinta kokufinyeleleka (swayiphela phezulu kusukela ngaphansi kwesikrini ngeminwe emithathu):"</string>
+    <string name="accessibility_button_instructional_text" msgid="7003212763213614833">"Ukuze ushintshe phakathi kwamasevisi, thinta uphinde ubambe inkinobho yokufinyeleleka."</string>
+    <string name="accessibility_gesture_instructional_text" msgid="5261788874937410950">"Ukuze ushintshe phakathi kwamasevisi, swayiphela phezulu ngeminwe emibili uphinde ubambe."</string>
+    <string name="accessibility_gesture_3finger_instructional_text" msgid="4969448938984394550">"Ukuze ushintshe phakathi kwamasevisi, swayiphela phezulu ngeminwe emithathu uphinde ubambe."</string>
     <string name="accessibility_magnification_chooser_text" msgid="1227146738764986237">"Ukukhuliswa"</string>
     <string name="user_switched" msgid="3768006783166984410">"Umsebenzisi wamanje <xliff:g id="NAME">%1$s</xliff:g>."</string>
     <string name="user_switching_message" msgid="2871009331809089783">"Ishintshela ku-<xliff:g id="NAME">%1$s</xliff:g>…"</string>
diff --git a/core/res/res/values/attrs.xml b/core/res/res/values/attrs.xml
index 81accdf..2f30194 100644
--- a/core/res/res/values/attrs.xml
+++ b/core/res/res/values/attrs.xml
@@ -1560,7 +1560,8 @@
         <flag name="email" value="0x02" />
         <!-- Match phone numbers. -->
         <flag name="phone" value="0x04" />
-        <!-- Match map addresses. -->
+        <!-- Match map addresses.
+             Deprecated: see {@link android.text.util.Linkify#MAP_ADDRESSES}. -->
         <flag name="map" value="0x08" />
         <!-- Match all patterns (equivalent to web|email|phone|map). -->
         <flag name="all" value="0x0f" />
diff --git a/core/res/res/values/colors.xml b/core/res/res/values/colors.xml
index 048f341..1dcd389 100644
--- a/core/res/res/values/colors.xml
+++ b/core/res/res/values/colors.xml
@@ -79,6 +79,7 @@
 
     <drawable name="input_method_fullscreen_background">#fff9f9f9</drawable>
     <color name="decor_view_status_guard">#ff000000</color>
+    <color name="decor_view_status_guard_light">#ffffffff</color>
 
     <!-- For date picker widget -->
     <drawable name="selected_day_background">#ff0092f4</drawable>
@@ -218,4 +219,9 @@
     <color name="chooser_row_divider">@color/list_divider_color_light</color>
     <color name="chooser_gradient_background">@color/loading_gradient_background_color_light</color>
     <color name="chooser_gradient_highlight">@color/loading_gradient_highlight_color_light</color>
+
+    <color name="GM2_grey_800">#ff3C4043</color>
+
+    <!-- Resolver/Chooser -->
+    <color name="resolver_text_color_secondary_dark">#ffC4C6C6</color>
 </resources>
diff --git a/core/res/res/values/config.xml b/core/res/res/values/config.xml
index 9bd56ad..14abb77 100644
--- a/core/res/res/values/config.xml
+++ b/core/res/res/values/config.xml
@@ -3279,7 +3279,8 @@
          various workspace stacks.
          0 - Nav bar is always opaque when either the freeform stack or docked stack is visible.
          1 - Nav bar is always translucent when the freeform stack is visible, otherwise always
-         opaque.
+             opaque.
+         2 - Nav bar is never forced opaque.
          -->
     <integer name="config_navBarOpacityMode">0</integer>
 
diff --git a/core/res/res/values/strings.xml b/core/res/res/values/strings.xml
index 5b917cc..a8f1c64 100644
--- a/core/res/res/values/strings.xml
+++ b/core/res/res/values/strings.xml
@@ -252,12 +252,15 @@
         <item>@string/wfcSpnFormat_wifi</item>
         <item>@string/wfcSpnFormat_wifi_calling_wo_hyphen</item>
         <item>@string/wfcSpnFormat_vowifi</item>
+        <item>@string/wfcSpnFormat_spn_wifi_calling_vo_hyphen</item>
     </string-array>
 
     <!-- Spn during Wi-Fi Calling: "<operator>" -->
     <string name="wfcSpnFormat_spn"><xliff:g id="spn" example="Operator">%s</xliff:g></string>
     <!-- Spn during Wi-Fi Calling: "<operator> Wi-Fi Calling" -->
     <string name="wfcSpnFormat_spn_wifi_calling"><xliff:g id="spn" example="Operator">%s</xliff:g> Wi-Fi Calling</string>
+    <!-- Spn during Wi-Fi Calling: "<operator> WiFi Calling" -->
+    <string name="wfcSpnFormat_spn_wifi_calling_vo_hyphen"><xliff:g id="spn" example="Operator">%s</xliff:g> WiFi Calling</string>
     <!-- Spn during Wi-Fi Calling: "WLAN Call" -->
     <string name="wfcSpnFormat_wlan_call">WLAN Call</string>
     <!-- Spn during Wi-Fi Calling: "<operator> WLAN Call" -->
@@ -4305,13 +4308,6 @@
     <!-- Title text to append when the display is secure.  [CHAR LIMIT=30] -->
     <string name="display_manager_overlay_display_secure_suffix">, secure</string>
 
-    <!-- Activity starter -->
-    <!-- Toast message for blocking background activity starts feature running in permissive mode -->
-    <string name="activity_starter_block_bg_activity_starts_permissive">This background activity start from <xliff:g id="packageName" example="com.example">%1$s</xliff:g> will be blocked in future Q builds. See g.co/dev/bgblock.</string>
-
-    <!-- Toast message for blocking background activity starts feature running in enforcing mode -->
-    <string name="activity_starter_block_bg_activity_starts_enforcing">Background activity start from <xliff:g id="packageName" example="com.example">%1$s</xliff:g> blocked. See g.co/dev/bgblock. </string>
-
     <!-- Keyguard strings -->
     <!-- Message shown in pattern unlock after some number of unsuccessful attempts -->
     <string name="kg_forgot_pattern_button_text">Forgot Pattern</string>
@@ -4495,10 +4491,18 @@
         <xliff:g id="service_name" example="TalkBack">%1$s</xliff:g></string>
 
     <!-- Text appearing in a prompt at the top of UI allowing the user to select a target service or feature to be assigned to the Accessibility button in the navigation bar. -->
-    <string name="accessibility_button_prompt_text">Choose a feature to use when you tap the Accessibility button:</string>
+    <string name="accessibility_button_prompt_text">Choose a service to use when you tap the accessibility button:</string>
+    <!-- Text appearing in a prompt at the top of UI allowing the user to select a target service or feature to be assigned to the Accessibility button when gesture navigation is enabled [CHAR LIMIT=none] -->
+    <string name="accessibility_gesture_prompt_text">Choose a service to use with the accessibility gesture (swipe up from the bottom of the screen with two fingers):</string>
+    <!-- Text appearing in a prompt at the top of UI allowing the user to select a target service or feature to be assigned to the Accessibility button when gesture navigation and TalkBack is enabled [CHAR LIMIT=none] -->
+    <string name="accessibility_gesture_3finger_prompt_text">Choose a service to use with the accessibility gesture (swipe up from the bottom of the screen with three fingers):</string>
 
     <!-- Text describing how to display UI allowing a user to select a target service or feature to be assigned to the Accessibility button in the navigation bar. -->
-    <string name="accessibility_button_instructional_text">To change features, touch &amp; hold the Accessibility button.</string>
+    <string name="accessibility_button_instructional_text">To switch between services, touch &amp; hold the accessibility button.</string>
+    <!-- Text describing how to display UI allowing a user to select a target service or feature to be assigned to the Accessibility button when gesture navigation is enabled. [CHAR LIMIT=none] -->
+    <string name="accessibility_gesture_instructional_text">To switch between services, swipe up with two fingers and hold.</string>
+    <!-- Text describing how to display UI allowing a user to select a target service or feature to be assigned to the Accessibility button when gesture navigation and TalkBack is enabled. [CHAR LIMIT=none] -->
+    <string name="accessibility_gesture_3finger_instructional_text">To switch between services, swipe up with three fingers and hold.</string>
 
     <!-- Text used to describe system navigation features, shown within a UI allowing a user to assign system magnification features to the Accessibility button in the navigation bar. -->
     <string name="accessibility_magnification_chooser_text">Magnification</string>
diff --git a/core/res/res/values/symbols.xml b/core/res/res/values/symbols.xml
index 3b3a062..9d75654 100644
--- a/core/res/res/values/symbols.xml
+++ b/core/res/res/values/symbols.xml
@@ -766,8 +766,6 @@
   <java-symbol type="string" name="display_manager_hdmi_display_name" />
   <java-symbol type="string" name="display_manager_overlay_display_name" />
   <java-symbol type="string" name="display_manager_overlay_display_secure_suffix" />
-  <java-symbol type="string" name="activity_starter_block_bg_activity_starts_permissive" />
-  <java-symbol type="string" name="activity_starter_block_bg_activity_starts_enforcing" />
   <java-symbol type="string" name="display_manager_overlay_display_title" />
   <java-symbol type="string" name="double_tap_toast" />
   <java-symbol type="string" name="elapsed_time_short_format_h_mm_ss" />
@@ -1964,6 +1962,7 @@
   <java-symbol type="bool" name="show_ongoing_ime_switcher" />
   <java-symbol type="color" name="config_defaultNotificationColor" />
   <java-symbol type="color" name="decor_view_status_guard" />
+  <java-symbol type="color" name="decor_view_status_guard_light" />
   <java-symbol type="drawable" name="ic_notification_ime_default" />
   <java-symbol type="drawable" name="ic_menu_refresh" />
   <java-symbol type="drawable" name="ic_settings" />
@@ -3286,9 +3285,16 @@
   <java-symbol type="layout" name="accessibility_button_chooser_item" />
   <java-symbol type="id" name="accessibility_button_chooser_grid" />
   <java-symbol type="id" name="accessibility_button_prompt" />
+  <java-symbol type="id" name="accessibility_button_prompt_prologue" />
   <java-symbol type="id" name="accessibility_button_target_icon" />
   <java-symbol type="id" name="accessibility_button_target_label" />
   <java-symbol type="string" name="accessibility_magnification_chooser_text" />
+
+  <java-symbol type="string" name="accessibility_gesture_prompt_text" />
+  <java-symbol type="string" name="accessibility_gesture_3finger_prompt_text" />
+  <java-symbol type="string" name="accessibility_gesture_instructional_text" />
+  <java-symbol type="string" name="accessibility_gesture_3finger_instructional_text" />
+
   <java-symbol type="drawable" name="ic_accessibility_magnification" />
 
   <!-- com.android.internal.widget.RecyclerView -->
@@ -3798,7 +3804,9 @@
   <java-symbol type="string" name="chooser_all_apps_button_label" />
   <java-symbol type="anim" name="resolver_launch_anim" />
   <java-symbol type="style" name="Animation.DeviceDefault.Activity.Resolver" />
-  
+
+  <java-symbol type="color" name="decor_view_status_guard_light" />
+
   <java-symbol type="string" name="config_defaultSupervisionProfileOwnerComponent" />
   <java-symbol type="bool" name="config_inflateSignalStrength" />
 </resources>
diff --git a/core/tests/benchmarks/src/android/net/NetworkStatsBenchmark.java b/core/tests/benchmarks/src/android/net/NetworkStatsBenchmark.java
index 707d7b3..1b65603 100644
--- a/core/tests/benchmarks/src/android/net/NetworkStatsBenchmark.java
+++ b/core/tests/benchmarks/src/android/net/NetworkStatsBenchmark.java
@@ -19,22 +19,13 @@
 import com.google.caliper.BeforeExperiment;
 import com.google.caliper.Param;
 
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.List;
-
 public class NetworkStatsBenchmark {
-    private static final String[] UNDERLYING_IFACES = {"wlan0", "rmnet0"};
+    private static final String UNDERLYING_IFACE = "wlan0";
     private static final String TUN_IFACE = "tun0";
     private static final int TUN_UID = 999999999;
 
     @Param({"100", "1000"})
     private int mSize;
-    /**
-     * Should not be more than the length of {@link #UNDERLYING_IFACES}.
-     */
-    @Param({"1", "2"})
-    private int mNumUnderlyingIfaces;
     private NetworkStats mNetworkStats;
 
     @BeforeExperiment
@@ -42,10 +33,8 @@
         mNetworkStats = new NetworkStats(0, mSize + 2);
         int uid = 0;
         NetworkStats.Entry recycle = new NetworkStats.Entry();
-        final List<String> allIfaces = getAllIfacesForBenchmark(); // also contains TUN_IFACE.
-        final int totalIfaces = allIfaces.size();
         for (int i = 0; i < mSize; i++) {
-            recycle.iface = allIfaces.get(i % totalIfaces);
+            recycle.iface = (i < mSize / 2) ? TUN_IFACE : UNDERLYING_IFACE;
             recycle.uid = uid;
             recycle.set = i % 2;
             recycle.tag = NetworkStats.TAG_NONE;
@@ -59,39 +48,22 @@
                 uid++;
             }
         }
-
-        for (int i = 0; i < mNumUnderlyingIfaces; i++) {
-            recycle.iface = UNDERLYING_IFACES[i];
-            recycle.uid = TUN_UID;
-            recycle.set = NetworkStats.SET_FOREGROUND;
-            recycle.tag = NetworkStats.TAG_NONE;
-            recycle.rxBytes = 90000 * mSize;
-            recycle.rxPackets = 40 * mSize;
-            recycle.txBytes = 180000 * mSize;
-            recycle.txPackets = 1200 * mSize;
-            recycle.operations = 0;
-            mNetworkStats.addValues(recycle);
-        }
-    }
-
-    private String[] getVpnUnderlyingIfaces() {
-        return Arrays.copyOf(UNDERLYING_IFACES, mNumUnderlyingIfaces);
-    }
-
-    /**
-     * Same as {@link #getVpnUnderlyingIfaces}, but also contains {@link #TUN_IFACE}.
-     */
-    private List<String> getAllIfacesForBenchmark() {
-        List<String> ifaces = new ArrayList<>();
-        ifaces.add(TUN_IFACE);
-        ifaces.addAll(Arrays.asList(getVpnUnderlyingIfaces()));
-        return ifaces;
+        recycle.iface = UNDERLYING_IFACE;
+        recycle.uid = TUN_UID;
+        recycle.set = NetworkStats.SET_FOREGROUND;
+        recycle.tag = NetworkStats.TAG_NONE;
+        recycle.rxBytes = 90000 * mSize;
+        recycle.rxPackets = 40 * mSize;
+        recycle.txBytes = 180000 * mSize;
+        recycle.txPackets = 1200 * mSize;
+        recycle.operations = 0;
+        mNetworkStats.addValues(recycle);
     }
 
     public void timeMigrateTun(int reps) {
         for (int i = 0; i < reps; i++) {
             NetworkStats stats = mNetworkStats.clone();
-            stats.migrateTun(TUN_UID, TUN_IFACE, getVpnUnderlyingIfaces());
+            stats.migrateTun(TUN_UID, TUN_IFACE, UNDERLYING_IFACE);
         }
     }
 
diff --git a/core/tests/coretests/src/android/content/ContextTest.java b/core/tests/coretests/src/android/content/ContextTest.java
index 2f442c3..b1a54dc 100644
--- a/core/tests/coretests/src/android/content/ContextTest.java
+++ b/core/tests/coretests/src/android/content/ContextTest.java
@@ -19,6 +19,7 @@
 import static org.junit.Assert.assertEquals;
 
 import android.app.ActivityThread;
+import android.os.UserHandle;
 import android.view.WindowManager;
 
 import androidx.test.InstrumentationRegistry;
@@ -58,4 +59,32 @@
         assertEquals(defaultDisplayContext.getDisplay().getDisplayId(),
                 defaultDisplayContext.getDisplayId());
     }
+
+    @Test(expected = NullPointerException.class)
+    public void testStartActivityAsUserNullIntentNullUser() {
+        final Context testContext =
+                InstrumentationRegistry.getInstrumentation().getTargetContext();
+        testContext.startActivityAsUser(null, null);
+    }
+
+    @Test(expected = NullPointerException.class)
+    public void testStartActivityAsUserNullIntentNonNullUser() {
+        final Context testContext =
+                InstrumentationRegistry.getInstrumentation().getTargetContext();
+        testContext.startActivityAsUser(null, new UserHandle(UserHandle.USER_ALL));
+    }
+
+    @Test(expected = NullPointerException.class)
+    public void testStartActivityAsUserNonNullIntentNullUser() {
+        final Context testContext =
+                InstrumentationRegistry.getInstrumentation().getTargetContext();
+        testContext.startActivityAsUser(new Intent(), null);
+    }
+
+    @Test(expected = RuntimeException.class)
+    public void testStartActivityAsUserNonNullIntentNonNullUser() {
+        final Context testContext =
+                InstrumentationRegistry.getInstrumentation().getTargetContext();
+        testContext.startActivityAsUser(new Intent(), new UserHandle(UserHandle.USER_ALL));
+    }
 }
diff --git a/core/tests/coretests/src/android/provider/SettingsBackupTest.java b/core/tests/coretests/src/android/provider/SettingsBackupTest.java
index fda37c8..cd36ba7 100644
--- a/core/tests/coretests/src/android/provider/SettingsBackupTest.java
+++ b/core/tests/coretests/src/android/provider/SettingsBackupTest.java
@@ -131,7 +131,6 @@
                     Settings.Global.AUTOFILL_MAX_VISIBLE_DATASETS,
                     Settings.Global.AUTOMATIC_POWER_SAVE_MODE,
                     Settings.Global.AVERAGE_TIME_TO_DISCHARGE,
-                    Settings.Global.BACKGROUND_ACTIVITY_STARTS_ENABLED,
                     Settings.Global.BATTERY_CHARGING_STATE_UPDATE_DELAY,
                     Settings.Global.BATTERY_ESTIMATES_LAST_UPDATE_TIME,
                     Settings.Global.BROADCAST_BG_CONSTANTS,
@@ -398,9 +397,6 @@
                     Settings.Global.POWER_MANAGER_CONSTANTS,
                     Settings.Global.PREFERRED_NETWORK_MODE,
                     Settings.Global.PRIVATE_DNS_DEFAULT_MODE,
-                    Settings.Global.PRIVILEGED_DEVICE_IDENTIFIER_NON_PRIV_CHECK_RELAXED,
-                    Settings.Global.PRIVILEGED_DEVICE_IDENTIFIER_PRIV_CHECK_RELAXED,
-                    Settings.Global.PRIVILEGED_DEVICE_IDENTIFIER_3P_CHECK_RELAXED,
                     Settings.Global.PROVISIONING_APN_ALARM_DELAY_IN_MS,
                     Settings.Global.RADIO_BLUETOOTH,
                     Settings.Global.RADIO_CELL,
@@ -496,6 +492,7 @@
                     Settings.Global.GLOBAL_SETTINGS_ANGLE_WHITELIST,
                     Settings.Global.GAME_DRIVER_ALL_APPS,
                     Settings.Global.GAME_DRIVER_OPT_IN_APPS,
+                    Settings.Global.GAME_DRIVER_PRERELEASE_OPT_IN_APPS,
                     Settings.Global.GAME_DRIVER_OPT_OUT_APPS,
                     Settings.Global.GAME_DRIVER_BLACKLISTS,
                     Settings.Global.GAME_DRIVER_BLACKLIST,
diff --git a/core/tests/coretests/src/android/view/ViewRootSurfaceCallbackTest.java b/core/tests/coretests/src/android/view/ViewRootSurfaceCallbackTest.java
new file mode 100644
index 0000000..94917cf
--- /dev/null
+++ b/core/tests/coretests/src/android/view/ViewRootSurfaceCallbackTest.java
@@ -0,0 +1,105 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.view;
+
+import static android.os.Process.myTid;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+
+import android.app.Activity;
+import android.app.AlertDialog;
+import android.os.HandlerThread;
+
+import androidx.test.filters.SmallTest;
+import androidx.test.platform.app.InstrumentationRegistry;
+import androidx.test.rule.ActivityTestRule;
+
+import org.junit.Rule;
+import org.junit.Test;
+
+import java.util.concurrent.CompletableFuture;
+import java.util.concurrent.TimeUnit;
+
+@SmallTest
+public class ViewRootSurfaceCallbackTest implements SurfaceHolder.Callback2 {
+    private static final String TAG = ViewRootSurfaceCallbackTest.class.getSimpleName();
+    private static final long TIMEOUT_MS = TimeUnit.SECONDS.toMillis(3);
+
+    @Rule
+    public ActivityTestRule<Activity> mActivityRule = new ActivityTestRule<>(Activity.class);
+
+    private final CompletableFuture<Integer> mTidOfSurfaceCreated = new CompletableFuture<>();
+    private final CompletableFuture<Integer> mTidOfSurfaceDestroyed = new CompletableFuture<>();
+
+    private boolean mDuplicatedSurfaceDestroyed;
+
+    /**
+     * Verifies that the calling thread of {@link SurfaceHolder.Callback2} should be the same as the
+     * thread that created the view root.
+     */
+    @Test
+    public void testCallingTidOfSurfaceCallback() throws Exception {
+        final Activity activity = mActivityRule.getActivity();
+        activity.setTurnScreenOn(true);
+        activity.setShowWhenLocked(true);
+
+        // Create a dialog that runs on another thread and let it handle surface by itself.
+        final HandlerThread thread = new HandlerThread(TAG);
+        thread.start();
+        thread.getThreadHandler().runWithScissors(() -> {
+            final AlertDialog dialog = new AlertDialog.Builder(activity)
+                    .setTitle(TAG).setMessage(TAG).create();
+            dialog.getWindow().takeSurface(this);
+            dialog.show();
+        }, TIMEOUT_MS);
+        final int attachedTid = thread.getThreadId();
+
+        assertEquals(attachedTid,
+                mTidOfSurfaceCreated.get(TIMEOUT_MS, TimeUnit.MILLISECONDS).intValue());
+
+        // Make the activity invisible.
+        activity.moveTaskToBack(true /* nonRoot */);
+        InstrumentationRegistry.getInstrumentation().waitForIdleSync();
+
+        assertEquals(attachedTid,
+                mTidOfSurfaceDestroyed.get(TIMEOUT_MS, TimeUnit.MILLISECONDS).intValue());
+        assertFalse("surfaceDestroyed should not be called twice", mDuplicatedSurfaceDestroyed);
+    }
+
+    @Override
+    public void surfaceCreated(SurfaceHolder holder) {
+        mTidOfSurfaceCreated.complete(myTid());
+    }
+
+    @Override
+    public void surfaceDestroyed(SurfaceHolder holder) {
+        if  (!mTidOfSurfaceDestroyed.isDone()) {
+            mTidOfSurfaceDestroyed.complete(myTid());
+        } else {
+            mDuplicatedSurfaceDestroyed = true;
+        }
+    }
+
+    @Override
+    public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
+    }
+
+    @Override
+    public void surfaceRedrawNeeded(SurfaceHolder holder) {
+    }
+}
diff --git a/core/tests/coretests/src/android/view/textclassifier/ActionsSuggestionsHelperTest.java b/core/tests/coretests/src/android/view/textclassifier/ActionsSuggestionsHelperTest.java
index db5f82a..80bce26 100644
--- a/core/tests/coretests/src/android/view/textclassifier/ActionsSuggestionsHelperTest.java
+++ b/core/tests/coretests/src/android/view/textclassifier/ActionsSuggestionsHelperTest.java
@@ -208,6 +208,36 @@
         assertThat(conversationActions.get(2).getAction()).isNull();
     }
 
+    @Test
+    public void testDeduplicateActions_nullComponent() {
+        Bundle phoneExtras = new Bundle();
+        Intent phoneIntent = new Intent(Intent.ACTION_DIAL);
+        ExtrasUtils.putActionIntent(phoneExtras, phoneIntent);
+        PendingIntent pendingIntent = PendingIntent.getActivity(
+                InstrumentationRegistry.getTargetContext(),
+                0,
+                phoneIntent,
+                0);
+        Icon icon = Icon.createWithData(new byte[0], 0, 0);
+        ConversationAction action =
+                new ConversationAction.Builder(ConversationAction.TYPE_CALL_PHONE)
+                        .setAction(new RemoteAction(icon, "label", "1", pendingIntent))
+                        .setExtras(phoneExtras)
+                        .build();
+        ConversationAction actionWithSameLabel =
+                new ConversationAction.Builder(ConversationAction.TYPE_CALL_PHONE)
+                        .setAction(new RemoteAction(
+                                icon, "label", "2", pendingIntent))
+                        .setExtras(phoneExtras)
+                        .build();
+
+        List<ConversationAction> conversationActions =
+                ActionsSuggestionsHelper.removeActionsWithDuplicates(
+                        Arrays.asList(action, actionWithSameLabel));
+
+        assertThat(conversationActions).isEmpty();
+    }
+
     public void createLabeledIntentResult_null() {
         ActionsSuggestionsModel.ActionSuggestion nativeSuggestion =
                 new ActionsSuggestionsModel.ActionSuggestion(
diff --git a/core/tests/coretests/src/com/android/internal/os/BatteryStatsHistoryTest.java b/core/tests/coretests/src/com/android/internal/os/BatteryStatsHistoryTest.java
index cc0ddb7..cd61011 100644
--- a/core/tests/coretests/src/com/android/internal/os/BatteryStatsHistoryTest.java
+++ b/core/tests/coretests/src/com/android/internal/os/BatteryStatsHistoryTest.java
@@ -22,25 +22,28 @@
 
 import android.content.Context;
 import android.os.Parcel;
+import android.util.Log;
 
 import androidx.test.InstrumentationRegistry;
 import androidx.test.runner.AndroidJUnit4;
 
+import java.io.File;
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+
 import org.junit.Before;
 import org.junit.Test;
 import org.junit.runner.RunWith;
 import org.mockito.MockitoAnnotations;
 
-import java.io.File;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.List;
-
 /**
  * Test BatteryStatsHistory.
  */
 @RunWith(AndroidJUnit4.class)
 public class BatteryStatsHistoryTest {
+    private static final String TAG = "BatteryStatsHistoryTest";
     private static final int MAX_HISTORY_FILES = 32;
     private final BatteryStatsImpl mBatteryStatsImpl = new MockBatteryStatsImpl();
     private final Parcel mHistoryBuffer = Parcel.obtain();
@@ -53,6 +56,12 @@
         Context context = InstrumentationRegistry.getContext();
         mSystemDir = context.getDataDir();
         mHistoryDir = new File(mSystemDir, BatteryStatsHistory.HISTORY_DIR);
+        String[] files = mHistoryDir.list();
+        if (files != null) {
+            for (int i = 0; i < files.length; i++) {
+                new File(mHistoryDir, files[i]).delete();
+            }
+        }
         mHistoryDir.delete();
     }
 
@@ -60,28 +69,32 @@
     public void testConstruct() {
         BatteryStatsHistory history =
                 new BatteryStatsHistory(mBatteryStatsImpl, mSystemDir, mHistoryBuffer);
+        createActiveFile(history);
         verifyFileNumbers(history, Arrays.asList(0));
         verifyActiveFile(history, "0.bin");
     }
 
     @Test
-    public void testCreateNextFile() {
+    public void testStartNextFile() {
         BatteryStatsHistory history =
                 new BatteryStatsHistory(mBatteryStatsImpl, mSystemDir, mHistoryBuffer);
 
         List<Integer> fileList = new ArrayList<>();
         fileList.add(0);
+        createActiveFile(history);
 
         // create file 1 to 31.
         for (int i = 1; i < MAX_HISTORY_FILES; i++) {
             fileList.add(i);
-            history.createNextFile();
+            history.startNextFile();
+            createActiveFile(history);
             verifyFileNumbers(history, fileList);
             verifyActiveFile(history, i + ".bin");
         }
 
         // create file 32
-        history.createNextFile();
+        history.startNextFile();
+        createActiveFile(history);
         fileList.add(32);
         fileList.remove(0);
         // verify file 0 is deleted.
@@ -90,7 +103,8 @@
         verifyActiveFile(history, "32.bin");
 
         // create file 33
-        history.createNextFile();
+        history.startNextFile();
+        createActiveFile(history);
         // verify file 1 is deleted
         fileList.add(33);
         fileList.remove(0);
@@ -108,6 +122,7 @@
         verifyActiveFile(history2, "33.bin");
 
         history2.resetAllFiles();
+        createActiveFile(history2);
         // verify all existing files are deleted.
         for (int i = 2; i < 33; ++i) {
             verifyFileDeleted(i + ".bin");
@@ -118,7 +133,8 @@
         verifyActiveFile(history2, "0.bin");
 
         // create file 1.
-        history2.createNextFile();
+        history2.startNextFile();
+        createActiveFile(history2);
         verifyFileNumbers(history2, Arrays.asList(0, 1));
         verifyActiveFile(history2, "1.bin");
     }
@@ -142,4 +158,13 @@
     private void verifyFileDeleted(String file) {
         assertFalse(new File(mHistoryDir, file).exists());
     }
+
+    private void createActiveFile(BatteryStatsHistory history) {
+        final File file = history.getActiveFile().getBaseFile();
+        try {
+            file.createNewFile();
+        } catch (IOException e) {
+            Log.e(TAG, "Error creating history file " + file.getPath(), e);
+        }
+    }
 }
\ No newline at end of file
diff --git a/core/tests/coretests/src/com/android/internal/os/BinderDeathDispatcherTest.java b/core/tests/coretests/src/com/android/internal/os/BinderDeathDispatcherTest.java
new file mode 100644
index 0000000..5914887
--- /dev/null
+++ b/core/tests/coretests/src/com/android/internal/os/BinderDeathDispatcherTest.java
@@ -0,0 +1,265 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.internal.os;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.reset;
+import static org.mockito.Mockito.times;
+import static org.mockito.Mockito.verify;
+
+import android.os.DeadObjectException;
+import android.os.IBinder;
+import android.os.IBinder.DeathRecipient;
+import android.os.IInterface;
+import android.os.Parcel;
+import android.os.RemoteException;
+import android.os.ResultReceiver;
+import android.os.ShellCallback;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import java.io.FileDescriptor;
+
+import androidx.test.filters.SmallTest;
+import androidx.test.runner.AndroidJUnit4;
+
+@SmallTest
+@RunWith(AndroidJUnit4.class)
+public class BinderDeathDispatcherTest {
+    private static class MyTarget implements IInterface, IBinder {
+        public boolean isAlive = true;
+        public DeathRecipient mRecipient;
+
+        @Override
+        public String getInterfaceDescriptor() throws RemoteException {
+            return null;
+        }
+
+        @Override
+        public boolean pingBinder() {
+            return false;
+        }
+
+        @Override
+        public boolean isBinderAlive() {
+            return isAlive;
+        }
+
+        @Override
+        public IInterface queryLocalInterface(String descriptor) {
+            return null;
+        }
+
+        @Override
+        public void dump(FileDescriptor fd, String[] args) throws RemoteException {
+
+        }
+
+        @Override
+        public void dumpAsync(FileDescriptor fd, String[] args) throws RemoteException {
+
+        }
+
+        @Override
+        public void shellCommand(FileDescriptor in, FileDescriptor out, FileDescriptor err,
+                String[] args, ShellCallback shellCallback, ResultReceiver resultReceiver)
+                throws RemoteException {
+
+        }
+
+        @Override
+        public boolean transact(int code, Parcel data, Parcel reply, int flags)
+                throws RemoteException {
+            return false;
+        }
+
+        @Override
+        public void linkToDeath(DeathRecipient recipient, int flags) throws RemoteException {
+            // In any situation, a single binder object should only have at most one death
+            // recipient.
+            assertThat(mRecipient).isNull();
+
+            if (!isAlive) {
+                throw new DeadObjectException();
+            }
+
+            mRecipient = recipient;
+        }
+
+        @Override
+        public boolean unlinkToDeath(DeathRecipient recipient, int flags) {
+            if (!isAlive) {
+                return false;
+            }
+            assertThat(mRecipient).isSameAs(recipient);
+            mRecipient = null;
+            return true;
+        }
+
+        @Override
+        public IBinder asBinder() {
+            return this;
+        }
+
+        public void die() {
+            isAlive = false;
+            if (mRecipient != null) {
+                mRecipient.binderDied();
+            }
+            mRecipient = null;
+        }
+
+        public boolean hasDeathRecipient() {
+            return mRecipient != null;
+        }
+    }
+
+    @Test
+    public void testRegisterAndUnregister() {
+        BinderDeathDispatcher<MyTarget> d = new BinderDeathDispatcher<>();
+
+        MyTarget t1 = new MyTarget();
+        MyTarget t2 = new MyTarget();
+        MyTarget t3 = new MyTarget();
+
+        DeathRecipient r1 = mock(DeathRecipient.class);
+        DeathRecipient r2 = mock(DeathRecipient.class);
+        DeathRecipient r3 = mock(DeathRecipient.class);
+        DeathRecipient r4 = mock(DeathRecipient.class);
+        DeathRecipient r5 = mock(DeathRecipient.class);
+
+        // Start hooking up.
+
+        // Link 3 recipients to t1 -- only one real recipient will be set.
+        assertThat(d.linkToDeath(t1, r1)).isEqualTo(1);
+        assertThat(d.getTargetsForTest().size()).isEqualTo(1);
+
+        assertThat(d.linkToDeath(t1, r2)).isEqualTo(2);
+        assertThat(d.linkToDeath(t1, r3)).isEqualTo(3);
+        assertThat(d.getTargetsForTest().size()).isEqualTo(1);
+
+        // Unlink two -- the real recipient is still set.
+        d.unlinkToDeath(t1, r1);
+        d.unlinkToDeath(t1, r2);
+
+        assertThat(t1.hasDeathRecipient()).isTrue();
+        assertThat(d.getTargetsForTest().size()).isEqualTo(1);
+
+        // Unlink the last one. The real recipient is also unlinked.
+        d.unlinkToDeath(t1, r3);
+        assertThat(t1.hasDeathRecipient()).isFalse();
+        assertThat(d.getTargetsForTest().size()).isEqualTo(0);
+
+        // Set recipients to t1, t2 and t3. t3 has two.
+        assertThat(d.linkToDeath(t1, r1)).isEqualTo(1);
+        assertThat(d.linkToDeath(t2, r1)).isEqualTo(1);
+        assertThat(d.linkToDeath(t3, r1)).isEqualTo(1);
+        assertThat(d.linkToDeath(t3, r2)).isEqualTo(2);
+
+
+        // They should all have a real recipient.
+        assertThat(t1.hasDeathRecipient()).isTrue();
+        assertThat(t2.hasDeathRecipient()).isTrue();
+        assertThat(t3.hasDeathRecipient()).isTrue();
+
+        assertThat(d.getTargetsForTest().size()).isEqualTo(3);
+
+        // Unlink r1 from t3. t3 still has r2, so it should still have a real recipient.
+        d.unlinkToDeath(t3, r1);
+        assertThat(t1.hasDeathRecipient()).isTrue();
+        assertThat(t2.hasDeathRecipient()).isTrue();
+        assertThat(t3.hasDeathRecipient()).isTrue();
+        assertThat(d.getTargetsForTest().size()).isEqualTo(3);
+
+        // Unlink r2 from t3. Now t3 has no real recipient.
+        d.unlinkToDeath(t3, r2);
+        assertThat(t3.hasDeathRecipient()).isFalse();
+        assertThat(d.getTargetsForTest().size()).isEqualTo(2);
+    }
+
+    @Test
+    public void testRegisterAndKill() {
+        BinderDeathDispatcher<MyTarget> d = new BinderDeathDispatcher<>();
+
+        MyTarget t1 = new MyTarget();
+        MyTarget t2 = new MyTarget();
+        MyTarget t3 = new MyTarget();
+
+        DeathRecipient r1 = mock(DeathRecipient.class);
+        DeathRecipient r2 = mock(DeathRecipient.class);
+        DeathRecipient r3 = mock(DeathRecipient.class);
+        DeathRecipient r4 = mock(DeathRecipient.class);
+        DeathRecipient r5 = mock(DeathRecipient.class);
+
+        // Hook them up.
+
+        d.linkToDeath(t1, r1);
+        d.linkToDeath(t1, r2);
+        d.linkToDeath(t1, r3);
+
+        // r4 is linked then unlinked. It shouldn't be notified.
+        d.linkToDeath(t1, r4);
+        d.unlinkToDeath(t1, r4);
+
+        d.linkToDeath(t2, r1);
+
+        d.linkToDeath(t3, r3);
+        d.linkToDeath(t3, r5);
+
+        assertThat(d.getTargetsForTest().size()).isEqualTo(3);
+
+        // Kill the targets.
+
+        t1.die();
+        verify(r1, times(1)).binderDied();
+        verify(r2, times(1)).binderDied();
+        verify(r3, times(1)).binderDied();
+        verify(r4, times(0)).binderDied();
+        verify(r5, times(0)).binderDied();
+
+        assertThat(d.getTargetsForTest().size()).isEqualTo(2);
+
+        reset(r1, r2, r3, r4, r5);
+
+        t2.die();
+        verify(r1, times(1)).binderDied();
+        verify(r2, times(0)).binderDied();
+        verify(r3, times(0)).binderDied();
+        verify(r4, times(0)).binderDied();
+        verify(r5, times(0)).binderDied();
+
+        assertThat(d.getTargetsForTest().size()).isEqualTo(1);
+
+        reset(r1, r2, r3, r4, r5);
+
+        t3.die();
+        verify(r1, times(0)).binderDied();
+        verify(r2, times(0)).binderDied();
+        verify(r3, times(1)).binderDied();
+        verify(r4, times(0)).binderDied();
+        verify(r5, times(1)).binderDied();
+
+        assertThat(d.getTargetsForTest().size()).isEqualTo(0);
+
+        // Try to register to a dead object -> should return -1.
+        assertThat(d.linkToDeath(t1, r1)).isEqualTo(-1);
+
+        assertThat(d.getTargetsForTest().size()).isEqualTo(0);
+    }
+}
diff --git a/data/etc/com.android.systemui.xml b/data/etc/com.android.systemui.xml
index a4337cc8..a305d48 100644
--- a/data/etc/com.android.systemui.xml
+++ b/data/etc/com.android.systemui.xml
@@ -54,6 +54,7 @@
         <permission name="android.permission.TETHER_PRIVILEGED"/>
         <permission name="android.permission.UPDATE_APP_OPS_STATS"/>
         <permission name="android.permission.USE_RESERVED_DISK"/>
+        <permission name="android.permission.WATCH_APPOPS"/>
         <permission name="android.permission.WRITE_DREAM_STATE"/>
         <permission name="android.permission.WRITE_MEDIA_STORAGE"/>
         <permission name="android.permission.WRITE_SECURE_SETTINGS"/>
diff --git a/data/etc/privapp-permissions-platform.xml b/data/etc/privapp-permissions-platform.xml
index a640122..c023e85 100644
--- a/data/etc/privapp-permissions-platform.xml
+++ b/data/etc/privapp-permissions-platform.xml
@@ -119,6 +119,8 @@
         <permission name="android.permission.APPROVE_INCIDENT_REPORTS"/>
         <permission name="android.permission.READ_PRIVILEGED_PHONE_STATE" />
         <permission name="android.permission.SUBSTITUTE_NOTIFICATION_APP_NAME" />
+        <!-- This permission will be removed in R. -->
+        <permission name="android.permission.START_ACTIVITIES_FROM_BACKGROUND"/>
     </privapp-permissions>
 
     <privapp-permissions package="com.android.phone">
diff --git a/data/keyboards/Vendor_045e_Product_02d1.kl b/data/keyboards/Vendor_045e_Product_02d1.kl
index 5d1637b..0867670 100644
--- a/data/keyboards/Vendor_045e_Product_02d1.kl
+++ b/data/keyboards/Vendor_045e_Product_02d1.kl
@@ -13,20 +13,22 @@
 # limitations under the License.
 
 #
-# XBox One USB Controller
+# XBox One Controller - Model 1537 - USB
 #
 
+# Mapping according to https://developer.android.com/training/game-controllers/controller-input.html
+
 key 304   BUTTON_A
 key 305   BUTTON_B
 key 307   BUTTON_X
 key 308   BUTTON_Y
+
 key 310   BUTTON_L1
 key 311   BUTTON_R1
-key 314   BACK
-key 315   BUTTON_START
-key 316   HOME
-key 317   BUTTON_THUMBL
-key 318   BUTTON_THUMBR
+
+# Triggers.
+axis 0x02 LTRIGGER
+axis 0x05 RTRIGGER
 
 # Left and right stick.
 # The reported value for flat is 128 out of a range from -32767 to 32768, which is absurd.
@@ -37,10 +39,19 @@
 axis 0x03 Z flat 4096
 axis 0x04 RZ flat 4096
 
-# Triggers.
-axis 0x02 LTRIGGER
-axis 0x05 RTRIGGER
+key 317   BUTTON_THUMBL
+key 318   BUTTON_THUMBR
 
 # Hat.
 axis 0x10 HAT_X
 axis 0x11 HAT_Y
+
+
+# Mapping according to https://www.kernel.org/doc/Documentation/input/gamepad.txt
+# Two overlapping rectangles
+key 314   BUTTON_SELECT
+# Hamburger - 3 parallel lines
+key 315   BUTTON_START
+
+# Xbox key
+key 316   BUTTON_MODE
diff --git a/data/keyboards/Vendor_045e_Product_02ea.kl b/data/keyboards/Vendor_045e_Product_02ea.kl
new file mode 100644
index 0000000..3b46db2
--- /dev/null
+++ b/data/keyboards/Vendor_045e_Product_02ea.kl
@@ -0,0 +1,57 @@
+# Copyright (C) 2019 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+#
+# XBox One Controller - Model 1708 - USB
+#
+
+# Mapping according to https://developer.android.com/training/game-controllers/controller-input.html
+
+key 304   BUTTON_A
+key 305   BUTTON_B
+key 307   BUTTON_X
+key 308   BUTTON_Y
+
+key 310   BUTTON_L1
+key 311   BUTTON_R1
+
+# Triggers.
+axis 0x02 LTRIGGER
+axis 0x05 RTRIGGER
+
+# Left and right stick.
+# The reported value for flat is 128 out of a range from -32767 to 32768, which is absurd.
+# This confuses applications that rely on the flat value because the joystick actually
+# settles in a flat range of +/- 4096 or so.
+axis 0x00 X flat 4096
+axis 0x01 Y flat 4096
+axis 0x03 Z flat 4096
+axis 0x04 RZ flat 4096
+
+key 317   BUTTON_THUMBL
+key 318   BUTTON_THUMBR
+
+# Hat.
+axis 0x10 HAT_X
+axis 0x11 HAT_Y
+
+
+# Mapping according to https://www.kernel.org/doc/Documentation/input/gamepad.txt
+# Two overlapping rectangles
+key 314   BUTTON_SELECT
+# Hamburger - 3 parallel lines
+key 315   BUTTON_START
+
+# Xbox key
+key 316   BUTTON_MODE
diff --git a/data/keyboards/Vendor_045e_Product_02fd.kl b/data/keyboards/Vendor_045e_Product_02fd.kl
new file mode 100644
index 0000000..512f7e1
--- /dev/null
+++ b/data/keyboards/Vendor_045e_Product_02fd.kl
@@ -0,0 +1,57 @@
+# Copyright (C) 2019 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+#
+# XBox One Controller - Model 1708 - Bluetooth
+#
+
+# Mapping according to https://developer.android.com/training/game-controllers/controller-input.html
+
+key 304   BUTTON_A
+key 305   BUTTON_B
+key 307   BUTTON_X
+key 308   BUTTON_Y
+
+key 310   BUTTON_L1
+key 311   BUTTON_R1
+
+# Triggers.
+axis 0x0a LTRIGGER
+axis 0x09 RTRIGGER
+
+# Left and right stick.
+# The reported value for flat is 128 out of a range from -32767 to 32768, which is absurd.
+# This confuses applications that rely on the flat value because the joystick actually
+# settles in a flat range of +/- 4096 or so.
+axis 0x00 X flat 4096
+axis 0x01 Y flat 4096
+axis 0x02 Z flat 4096
+axis 0x05 RZ flat 4096
+
+key 317   BUTTON_THUMBL
+key 318   BUTTON_THUMBR
+
+# Hat.
+axis 0x10 HAT_X
+axis 0x11 HAT_Y
+
+
+# Mapping according to https://www.kernel.org/doc/Documentation/input/gamepad.txt
+# Two overlapping rectangles
+key 158   BUTTON_SELECT
+# Hamburger - 3 parallel lines
+key 315   BUTTON_START
+
+# Xbox key
+key 172   BUTTON_MODE
diff --git a/graphics/java/android/graphics/drawable/GradientDrawable.java b/graphics/java/android/graphics/drawable/GradientDrawable.java
index 32f2fc2..b9945cc 100644
--- a/graphics/java/android/graphics/drawable/GradientDrawable.java
+++ b/graphics/java/android/graphics/drawable/GradientDrawable.java
@@ -1757,7 +1757,7 @@
         }
 
         int angle = (int) a.getFloat(R.styleable.GradientDrawableGradient_angle, st.mAngle);
-        st.mAngle = angle % 360;
+        st.mAngle = ((angle % 360) + 360) % 360; // offset negative angle measures
 
         final TypedValue tv = a.peekValue(R.styleable.GradientDrawableGradient_gradientRadius);
         if (tv != null) {
diff --git a/libs/hwui/RenderNode.cpp b/libs/hwui/RenderNode.cpp
index e0ed3e4..b73347b 100644
--- a/libs/hwui/RenderNode.cpp
+++ b/libs/hwui/RenderNode.cpp
@@ -264,6 +264,12 @@
 }
 
 void RenderNode::pushStagingPropertiesChanges(TreeInfo& info) {
+    if (mPositionListenerDirty) {
+        mPositionListener = std::move(mStagingPositionListener);
+        mStagingPositionListener = nullptr;
+        mPositionListenerDirty = false;
+    }
+
     // Push the animators first so that setupStartValueIfNecessary() is called
     // before properties() is trampled by stagingProperties(), as they are
     // required by some animators.
diff --git a/libs/hwui/RenderNode.h b/libs/hwui/RenderNode.h
index 23e7a0e..c6db7f1 100644
--- a/libs/hwui/RenderNode.h
+++ b/libs/hwui/RenderNode.h
@@ -188,11 +188,9 @@
         virtual void onPositionLost(RenderNode& node, const TreeInfo* info) = 0;
     };
 
-    // Note this is not thread safe, this needs to be called
-    // before the RenderNode is used for drawing.
-    // RenderNode takes ownership of the pointer
     ANDROID_API void setPositionListener(PositionListener* listener) {
-        mPositionListener = listener;
+        mStagingPositionListener = listener;
+        mPositionListenerDirty = true;
     }
 
     // This is only modified in MODE_FULL, so it can be safely accessed
@@ -275,6 +273,8 @@
     // mDisplayList, not mStagingDisplayList.
     uint32_t mParentCount;
 
+    bool mPositionListenerDirty = false;
+    sp<PositionListener> mStagingPositionListener;
     sp<PositionListener> mPositionListener;
 
     UsageHint mUsageHint = UsageHint::Unknown;
diff --git a/media/java/android/media/AudioSystem.java b/media/java/android/media/AudioSystem.java
index 987db8b..53bc65d 100644
--- a/media/java/android/media/AudioSystem.java
+++ b/media/java/android/media/AudioSystem.java
@@ -24,7 +24,6 @@
 import android.content.pm.PackageManager;
 import android.media.audiofx.AudioEffect;
 import android.media.audiopolicy.AudioMix;
-import android.os.Build;
 import android.util.Log;
 
 import java.util.ArrayList;
@@ -981,6 +980,8 @@
     public static native boolean getMasterMono();
     /** @hide enables or disables the master mono mode. */
     public static native int setMasterMono(boolean mono);
+    /** @hide enables or disables the RTT mode. */
+    public static native int setRttEnabled(boolean enabled);
 
     /** @hide returns master balance value in range -1.f -> 1.f, where 0.f is dead center. */
     @TestApi
@@ -990,9 +991,9 @@
     public static native int setMasterBalance(float balance);
 
     // helpers for android.media.AudioManager.getProperty(), see description there for meaning
-    @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 112561552)
+    @UnsupportedAppUsage(trackingBug = 134049522)
     public static native int getPrimaryOutputSamplingRate();
-    @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 112561552)
+    @UnsupportedAppUsage(trackingBug = 134049522)
     public static native int getPrimaryOutputFrameCount();
     @UnsupportedAppUsage
     public static native int getOutputLatency(int stream);
diff --git a/packages/CaptivePortalLogin/Android.bp b/packages/CaptivePortalLogin/Android.bp
deleted file mode 100644
index 1f6c2ae..0000000
--- a/packages/CaptivePortalLogin/Android.bp
+++ /dev/null
@@ -1,43 +0,0 @@
-//
-// Copyright (C) 2019 The Android Open Source Project
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//      http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-//
-
-java_defaults {
-    name: "CaptivePortalLoginDefaults",
-    srcs: ["src/**/*.java"],
-    sdk_version: "system_current",
-    min_sdk_version: "28",
-    static_libs: [
-        "androidx.legacy_legacy-support-v4",
-        "metrics-constants-protos",
-        "captiveportal-lib",
-    ],
-    manifest: "AndroidManifest.xml",
-}
-
-android_app {
-    name: "CaptivePortalLogin",
-    defaults: ["CaptivePortalLoginDefaults"],
-    certificate: "networkstack",
-}
-
-// Alternative CaptivePortalLogin signed with the platform cert, to use
-// with InProcessNetworkStack.
-android_app {
-    name: "PlatformCaptivePortalLogin",
-    defaults: ["CaptivePortalLoginDefaults"],
-    certificate: "platform",
-    overrides: ["CaptivePortalLogin"],
-}
diff --git a/packages/CaptivePortalLogin/AndroidManifest.xml b/packages/CaptivePortalLogin/AndroidManifest.xml
deleted file mode 100644
index 86d6d44..0000000
--- a/packages/CaptivePortalLogin/AndroidManifest.xml
+++ /dev/null
@@ -1,48 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-/*
- * Copyright (C) 2014 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.
- */
--->
-<manifest xmlns:android="http://schemas.android.com/apk/res/android"
-    package="com.android.captiveportallogin"
-    android:versionCode="220000000"
-    android:versionName="Q-initial">
-
-    <uses-sdk android:minSdkVersion="28" android:targetSdkVersion="28" />
-    <uses-permission android:name="android.permission.INTERNET" />
-    <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
-    <uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
-    <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
-    <uses-permission android:name="android.permission.CONNECTIVITY_USE_RESTRICTED_NETWORKS" />
-    <uses-permission android:name="android.permission.NETWORK_BYPASS_PRIVATE_DNS" />
-    <uses-permission android:name="android.permission.MAINLINE_NETWORK_STACK" />
-
-    <application android:label="@string/app_name"
-                 android:icon="@drawable/app_icon"
-                 android:usesCleartextTraffic="true"
-                 android:supportsRtl="true" >
-        <activity
-            android:name="com.android.captiveportallogin.CaptivePortalLoginActivity"
-            android:label="@string/action_bar_label"
-            android:theme="@style/AppTheme"
-            android:configChanges="keyboardHidden|orientation|screenSize" >
-            <intent-filter>
-                <action android:name="android.net.conn.CAPTIVE_PORTAL"/>
-                <category android:name="android.intent.category.DEFAULT"/>
-            </intent-filter>
-        </activity>
-    </application>
-</manifest>
diff --git a/packages/CaptivePortalLogin/OWNERS b/packages/CaptivePortalLogin/OWNERS
deleted file mode 100644
index 52193eb..0000000
--- a/packages/CaptivePortalLogin/OWNERS
+++ /dev/null
@@ -1,5 +0,0 @@
-set noparent
-
-lorenzo@google.com
-baligh@google.com
-delphij@google.com
diff --git a/packages/CaptivePortalLogin/assets/quantum_ic_warning_amber_96.png b/packages/CaptivePortalLogin/assets/quantum_ic_warning_amber_96.png
deleted file mode 100644
index 08294ce..0000000
--- a/packages/CaptivePortalLogin/assets/quantum_ic_warning_amber_96.png
+++ /dev/null
Binary files differ
diff --git a/packages/CaptivePortalLogin/res/drawable/app_icon.xml b/packages/CaptivePortalLogin/res/drawable/app_icon.xml
deleted file mode 100644
index 456ca83..0000000
--- a/packages/CaptivePortalLogin/res/drawable/app_icon.xml
+++ /dev/null
@@ -1,26 +0,0 @@
-<!--
-    Copyright (C) 2019 The Android Open Source Project
-
-    Licensed under the Apache License, Version 2.0 (the "License");
-    you may not use this file except in compliance with the License.
-    You may obtain a copy of the License at
-
-         http://www.apache.org/licenses/LICENSE-2.0
-
-    Unless required by applicable law or agreed to in writing, software
-    distributed under the License is distributed on an "AS IS" BASIS,
-    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-    See the License for the specific language governing permissions and
-    limitations under the License.
--->
-<adaptive-icon xmlns:android="http://schemas.android.com/apk/res/android">
-    <background>
-        <color android:color="@*android:color/accent_device_default_light" />
-    </background>
-    <foreground>
-        <inset
-            android:drawable="@drawable/maybe_wifi"
-            android:inset="25%">
-        </inset>
-    </foreground>
-</adaptive-icon>
diff --git a/packages/CaptivePortalLogin/res/drawable/maybe_wifi.xml b/packages/CaptivePortalLogin/res/drawable/maybe_wifi.xml
deleted file mode 100644
index 207aade..0000000
--- a/packages/CaptivePortalLogin/res/drawable/maybe_wifi.xml
+++ /dev/null
@@ -1,27 +0,0 @@
-<!--
-Copyright (C) 2019 The Android Open Source Project
-
-   Licensed under the Apache License, Version 2.0 (the "License");
-    you may not use this file except in compliance with the License.
-    You may obtain a copy of the License at
-
-         http://www.apache.org/licenses/LICENSE-2.0
-
-    Unless required by applicable law or agreed to in writing, software
-    distributed under the License is distributed on an "AS IS" BASIS,
-    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-    See the License for the specific language governing permissions and
-    limitations under the License.
--->
-<vector xmlns:android="http://schemas.android.com/apk/res/android"
-        android:width="26.0dp"
-        android:height="24.0dp"
-        android:viewportWidth="26.0"
-        android:viewportHeight="24.0">
-    <path
-        android:fillColor="#4DFFFFFF"
-        android:pathData="M19.1,14l-3.4,0l0,-1.5c0,-1.8 0.8,-2.8 1.5,-3.4C18.1,8.3 19.200001,8 20.6,8c1.2,0 2.3,0.3 3.1,0.8l1.9,-2.3C25.1,6.1 20.299999,2.1 13,2.1S0.9,6.1 0.4,6.5L13,22l0,0l0,0l0,0l0,0l6.5,-8.1L19.1,14z"/>
-    <path
-        android:fillColor="#FFFFFFFF"
-        android:pathData="M19.5,17.799999c0,-0.8 0.1,-1.3 0.2,-1.6c0.2,-0.3 0.5,-0.7 1.1,-1.2c0.4,-0.4 0.7,-0.8 1,-1.1s0.4,-0.8 0.4,-1.2c0,-0.5 -0.1,-0.9 -0.4,-1.2c-0.3,-0.3 -0.7,-0.4 -1.2,-0.4c-0.4,0 -0.8,0.1 -1.1,0.3c-0.3,0.2 -0.4,0.6 -0.4,1.1l-1.9,0c0,-1 0.3,-1.7 1,-2.2c0.6,-0.5 1.5,-0.8 2.5,-0.8c1.1,0 2,0.3 2.6,0.8c0.6,0.5 0.9,1.3 0.9,2.3c0,0.7 -0.2,1.3 -0.6,1.8c-0.4,0.6 -0.9,1.1 -1.5,1.6c-0.3,0.3 -0.5,0.5 -0.6,0.7c-0.1,0.2 -0.1,0.6 -0.1,1L19.5,17.700001zM21.4,21l-1.9,0l0,-1.8l1.9,0L21.4,21z"/>
-</vector>
diff --git a/packages/CaptivePortalLogin/res/layout/activity_captive_portal_login.xml b/packages/CaptivePortalLogin/res/layout/activity_captive_portal_login.xml
deleted file mode 100644
index f095d4e..0000000
--- a/packages/CaptivePortalLogin/res/layout/activity_captive_portal_login.xml
+++ /dev/null
@@ -1,43 +0,0 @@
-<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:tools="http://schemas.android.com/tools"
-    android:id="@+id/container"
-    android:layout_width="match_parent"
-    android:layout_height="match_parent"
-    tools:context="com.android.captiveportallogin.CaptivePortalLoginActivity"
-    tools:ignore="MergeRootFrame" >
-
-    <LinearLayout
-    android:layout_width="match_parent"
-    android:layout_height="match_parent"
-    android:orientation="vertical" >
-
-      <FrameLayout
-          android:layout_width="match_parent"
-          android:layout_height="4dp" >
-
-        <!-- Eliminates ProgressBar padding by boxing it into a 4dp high container -->
-        <ProgressBar
-            android:id="@+id/progress_bar"
-            style="@android:style/Widget.Material.Light.ProgressBar.Horizontal"
-            android:indeterminate="false"
-            android:max="100"
-            android:progress="0"
-            android:layout_gravity="center"
-            android:layout_width="match_parent"
-            android:layout_height="wrap_content" />
-      </FrameLayout>
-
-      <androidx.swiperefreshlayout.widget.SwipeRefreshLayout
-            android:id="@+id/swipe_refresh"
-            android:layout_width="match_parent"
-            android:layout_height="match_parent">
-        <WebView
-              android:id="@+id/webview"
-              android:layout_width="match_parent"
-              android:layout_height="match_parent"
-              android:layout_alignParentBottom="false"
-              android:layout_alignParentRight="false" />
-      </androidx.swiperefreshlayout.widget.SwipeRefreshLayout>
-
-    </LinearLayout>
-</FrameLayout>
diff --git a/packages/CaptivePortalLogin/res/layout/ssl_warning.xml b/packages/CaptivePortalLogin/res/layout/ssl_warning.xml
deleted file mode 100644
index ce05e78..0000000
--- a/packages/CaptivePortalLogin/res/layout/ssl_warning.xml
+++ /dev/null
@@ -1,97 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- 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.
--->
-
-<LinearLayout
-    xmlns:android="http://schemas.android.com/apk/res/android"
-    android:layout_width="match_parent"
-    android:layout_height="wrap_content"
-    android:orientation="vertical" >
-
-    <!-- ssl error type -->
-    <TextView
-        android:id="@+id/ssl_error_type"
-        android:layout_width="match_parent"
-        android:layout_height="wrap_content"
-        android:layout_gravity="start"
-        android:text="SSL_UNKNOWN"
-        android:layout_marginStart="24dip"
-        android:layout_marginEnd="24dip"
-        android:layout_marginBottom="0dip"
-        android:layout_marginTop="24dip" />
-
-    <!-- Page info: -->
-    <TextView
-        android:id="@+id/page_info"
-        android:layout_width="match_parent"
-        android:layout_height="wrap_content"
-        android:text="@string/page_info"
-        android:textStyle="bold"
-        android:layout_marginStart="24dip"
-        android:layout_marginEnd="24dip" />
-
-    <!-- Title: -->
-    <TextView
-        android:id="@+id/title"
-        android:layout_width="match_parent"
-        android:layout_height="wrap_content"
-        android:textStyle="bold"
-        android:layout_marginStart="24dip"
-        android:layout_marginEnd="24dip" />
-
-    <!-- Address: -->
-    <TextView
-        android:id="@+id/address_header"
-        android:layout_width="match_parent"
-        android:layout_height="wrap_content"
-        android:text="@string/page_info_address"
-        android:layout_marginStart="24dip"
-        android:layout_marginEnd="24dip" />
-
-    <TextView
-        android:id="@+id/address"
-        android:layout_width="match_parent"
-        android:layout_height="wrap_content"
-        android:layout_marginStart="24dip"
-        android:layout_marginEnd="24dip" />
-
-    <ScrollView
-        android:layout_width="match_parent"
-        android:layout_height="wrap_content"
-        android:paddingStart="4dip"
-        android:paddingEnd="4dip" >
-
-        <!-- certificate view: -->
-        <LinearLayout
-            android:id="@+id/certificate_layout"
-            android:layout_width="match_parent"
-            android:layout_height="wrap_content"
-            android:orientation="vertical"
-            android:layout_marginBottom="16dip" >
-            <TextView
-                android:id="@+id/ssl_error_msg"
-                android:layout_width="wrap_content"
-                android:layout_height="wrap_content"
-                android:textAppearance="?android:attr/textAppearanceSmall"
-                android:layout_marginStart="20dip"
-                android:layout_marginEnd="20dip"
-                android:gravity="center_vertical"
-                android:layout_marginBottom="4dip"
-                android:layout_marginTop="16dip" />
-        </LinearLayout>
-
-    </ScrollView>
-
-</LinearLayout>
diff --git a/packages/CaptivePortalLogin/res/menu/captive_portal_login.xml b/packages/CaptivePortalLogin/res/menu/captive_portal_login.xml
deleted file mode 100644
index 1a88c5c..0000000
--- a/packages/CaptivePortalLogin/res/menu/captive_portal_login.xml
+++ /dev/null
@@ -1,15 +0,0 @@
-<menu xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:tools="http://schemas.android.com/tools"
-    tools:context="com.android.captiveportallogin.CaptivePortalLoginActivity" >
-    <item
-        android:id="@+id/action_do_not_use_network"
-        android:orderInCategory="100"
-        android:showAsAction="never"
-        android:title="@string/action_do_not_use_network"/>
-    <item
-        android:id="@+id/action_use_network"
-        android:orderInCategory="200"
-        android:showAsAction="never"
-        android:title="@string/action_use_network"/>
-
-</menu>
diff --git a/packages/CaptivePortalLogin/res/values-af/strings.xml b/packages/CaptivePortalLogin/res/values-af/strings.xml
deleted file mode 100644
index 37acf45..0000000
--- a/packages/CaptivePortalLogin/res/values-af/strings.xml
+++ /dev/null
@@ -1,24 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="app_name" msgid="5934709770924185752">"CaptivePortal-aanmelding"</string>
-    <string name="action_use_network" msgid="6076184727448466030">"Gebruik hierdie netwerk nes dit is"</string>
-    <string name="action_do_not_use_network" msgid="4577366536956516683">"Moenie hierdie netwerk gebruik nie"</string>
-    <string name="action_bar_label" msgid="917235635415966620">"Meld by netwerk aan"</string>
-    <string name="action_bar_title" msgid="5645564790486983117">"Meld aan by %1$s"</string>
-    <string name="ssl_error_warning" msgid="6653188881418638872">"Die netwerk waarby jy probeer aansluit, het sekuriteitkwessies."</string>
-    <string name="ssl_error_example" msgid="647898534624078900">"Byvoorbeeld, die aanmeldbladsy behoort dalk nie aan die organisasie wat gewys word nie."</string>
-    <string name="ssl_error_continue" msgid="6492718244923937110">"Gaan in elk geval deur blaaier voort"</string>
-    <string name="ssl_error_untrusted" msgid="1496280318271264520">"Hierdie sertifikaat is nie van \'n betroubare owerheid nie."</string>
-    <string name="ssl_error_mismatch" msgid="3060364165934822383">"Die naam van die werf stem nie ooreen met die naam op die sertifikaat nie."</string>
-    <string name="ssl_error_expired" msgid="1501588340716182495">"Hierdie sertifikaat het verval."</string>
-    <string name="ssl_error_not_yet_valid" msgid="8648649030525886924">"Hierdie sertifikaat is nog nie geldig nie."</string>
-    <string name="ssl_error_date_invalid" msgid="88425990680059223">"Hierdie sertifikaat het \'n ongeldige datum."</string>
-    <string name="ssl_error_invalid" msgid="2540546515565633432">"Hierdie sertifikaat is ongeldig."</string>
-    <string name="ssl_error_unknown" msgid="4405203446079465859">"Onbekende sertifikaatfout."</string>
-    <string name="ssl_security_warning_title" msgid="8768539813847504404">"Sekuriteitswaarskuwing"</string>
-    <string name="ssl_error_view_certificate" msgid="5722652540168339333">"Bekyk sertifikaat"</string>
-    <string name="ok" msgid="2817931639040794018">"OK"</string>
-    <string name="page_info_address" msgid="1261481517455692363">"Adres:"</string>
-    <string name="page_info" msgid="4416941086705172545">"Bladsy-inligting"</string>
-</resources>
diff --git a/packages/CaptivePortalLogin/res/values-am/strings.xml b/packages/CaptivePortalLogin/res/values-am/strings.xml
deleted file mode 100644
index 4e35e19..0000000
--- a/packages/CaptivePortalLogin/res/values-am/strings.xml
+++ /dev/null
@@ -1,24 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="app_name" msgid="5934709770924185752">"CaptivePortalLogin"</string>
-    <string name="action_use_network" msgid="6076184727448466030">"ይህን አውታረ መረብ እንዳለ ተጠቀምበት"</string>
-    <string name="action_do_not_use_network" msgid="4577366536956516683">"ይህን አውታረ መረብ አትጠቀምበት"</string>
-    <string name="action_bar_label" msgid="917235635415966620">"ወደ አውታረ መረብ በመለያ ይግቡ"</string>
-    <string name="action_bar_title" msgid="5645564790486983117">"ወደ %1$s ይግቡ"</string>
-    <string name="ssl_error_warning" msgid="6653188881418638872">"ለመቀላቀል እየሞከሩ ያሉት አውታረ መረብ የደህንነት ችግሮች አሉበት።"</string>
-    <string name="ssl_error_example" msgid="647898534624078900">"ለምሳሌ፣ የመግቢያ ገጹ የሚታየው ድርጅት ላይሆን ይችላል።"</string>
-    <string name="ssl_error_continue" msgid="6492718244923937110">"ለማንኛውም በአሳሽ በኩል ይቀጥሉ"</string>
-    <string name="ssl_error_untrusted" msgid="1496280318271264520">"ይህ የእውቅና ማረጋገጫ ከታማኝ ቦታ አይደለም።"</string>
-    <string name="ssl_error_mismatch" msgid="3060364165934822383">"የጣቢያው ስም ከእውቅና ማረጋገጫው ስም ጋር አይዛመድም።"</string>
-    <string name="ssl_error_expired" msgid="1501588340716182495">"ይህ የእውቅና ማረጋገጫ ጊዜው አልፏል።"</string>
-    <string name="ssl_error_not_yet_valid" msgid="8648649030525886924">"ይህ የእውቅና ማረጋገጫ ገና የሚሰራ አይደለም።"</string>
-    <string name="ssl_error_date_invalid" msgid="88425990680059223">"ይህ የእውቅና ማረጋገጫ ልክ ያልሆነ ቀን ነው ያለው።"</string>
-    <string name="ssl_error_invalid" msgid="2540546515565633432">"ይህ የእውቅና ማረጋገጫ ልክ ያልሆነ ነው።"</string>
-    <string name="ssl_error_unknown" msgid="4405203446079465859">"ያልታወቀ የእውቅና ማረጋገጫ ስህተት።"</string>
-    <string name="ssl_security_warning_title" msgid="8768539813847504404">"የደህንነት ቅንብሮች"</string>
-    <string name="ssl_error_view_certificate" msgid="5722652540168339333">"የእውቅና ማረጋገጫን ይመልከቱ"</string>
-    <string name="ok" msgid="2817931639040794018">"እሺ"</string>
-    <string name="page_info_address" msgid="1261481517455692363">"አድራሻ፦"</string>
-    <string name="page_info" msgid="4416941086705172545">"የገጽ መረጃ"</string>
-</resources>
diff --git a/packages/CaptivePortalLogin/res/values-ar/strings.xml b/packages/CaptivePortalLogin/res/values-ar/strings.xml
deleted file mode 100644
index 9f3aefa..0000000
--- a/packages/CaptivePortalLogin/res/values-ar/strings.xml
+++ /dev/null
@@ -1,26 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="app_name" msgid="5934709770924185752">"CaptivePortalLogin"</string>
-    <string name="action_use_network" msgid="6076184727448466030">"استخدام هذه الشبكة كما هي"</string>
-    <string name="action_do_not_use_network" msgid="4577366536956516683">"عدم استخدام هذه الشبكة"</string>
-    <string name="action_bar_label" msgid="917235635415966620">"تسجيل الدخول إلى الشبكة"</string>
-    <!-- String.format failed for translation -->
-    <!-- no translation found for action_bar_title (5645564790486983117) -->
-    <skip />
-    <string name="ssl_error_warning" msgid="6653188881418638872">"الشبكة التي تحاول الانضمام إليها بها مشاكل أمنية."</string>
-    <string name="ssl_error_example" msgid="647898534624078900">"على سبيل المثال، قد لا تنتمي صفحة تسجيل الدخول إلى المنظمة المعروضة."</string>
-    <string name="ssl_error_continue" msgid="6492718244923937110">"المتابعة على أي حال عبر المتصفح"</string>
-    <string name="ssl_error_untrusted" msgid="1496280318271264520">"هذه الشهادة ليست من جهة موثوق بها."</string>
-    <string name="ssl_error_mismatch" msgid="3060364165934822383">"لا يتطابق اسم الموقع مع الاسم على الشهادة."</string>
-    <string name="ssl_error_expired" msgid="1501588340716182495">"انتهت صلاحية هذه الشهادة."</string>
-    <string name="ssl_error_not_yet_valid" msgid="8648649030525886924">"هذه الشهادة ليست صالحة بعد."</string>
-    <string name="ssl_error_date_invalid" msgid="88425990680059223">"تشتمل هذه الشهادة على تاريخ غير صالح."</string>
-    <string name="ssl_error_invalid" msgid="2540546515565633432">"هذه الشهادة غير صالحة."</string>
-    <string name="ssl_error_unknown" msgid="4405203446079465859">"حدث خطأ غير معروف بالشهادة."</string>
-    <string name="ssl_security_warning_title" msgid="8768539813847504404">"تحذير أمني"</string>
-    <string name="ssl_error_view_certificate" msgid="5722652540168339333">"عرض الشهادة"</string>
-    <string name="ok" msgid="2817931639040794018">"حسنًا"</string>
-    <string name="page_info_address" msgid="1261481517455692363">"العنوان:"</string>
-    <string name="page_info" msgid="4416941086705172545">"معلومات الصفحة"</string>
-</resources>
diff --git a/packages/CaptivePortalLogin/res/values-as/strings.xml b/packages/CaptivePortalLogin/res/values-as/strings.xml
deleted file mode 100644
index 696483c..0000000
--- a/packages/CaptivePortalLogin/res/values-as/strings.xml
+++ /dev/null
@@ -1,24 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="app_name" msgid="5934709770924185752">"CaptivePortalLogin"</string>
-    <string name="action_use_network" msgid="6076184727448466030">"এই নেটৱৰ্কটো এইদৰে ব্যৱহাৰ কৰক"</string>
-    <string name="action_do_not_use_network" msgid="4577366536956516683">"এই নেটৱৰ্কটো ব্যৱহাৰ নকৰিব"</string>
-    <string name="action_bar_label" msgid="917235635415966620">"নেটৱৰ্কত ছাইন ইন কৰক"</string>
-    <string name="action_bar_title" msgid="5645564790486983117">"%1$st ছাইন ইন কৰক"</string>
-    <string name="ssl_error_warning" msgid="6653188881418638872">"আপুনি সংযোগ কৰিবলৈ চেষ্টা কৰি থকা নেটৱৰ্কটোত সুৰক্ষাজনিত সমস্যা আছে।"</string>
-    <string name="ssl_error_example" msgid="647898534624078900">"উদাহৰণস্বৰূপে, আপোনাক দেখুওৱা লগ ইনৰ পৃষ্ঠাটো প্ৰতিষ্ঠানটোৰ নিজা নহ\'বও পাৰে।"</string>
-    <string name="ssl_error_continue" msgid="6492718244923937110">"তথাপি ব্ৰাউজাৰৰ জৰিয়তে অব্যাহত ৰাখক"</string>
-    <string name="ssl_error_untrusted" msgid="1496280318271264520">"এই প্ৰমাণপত্ৰখন কোনো বিশ্বাসী কর্তৃপক্ষৰ নহয়।"</string>
-    <string name="ssl_error_mismatch" msgid="3060364165934822383">"ৱেবচাইটটোৰ নাম আৰু প্ৰমাণপত্ৰখনত থকা নামটোৰ মিল নাই।"</string>
-    <string name="ssl_error_expired" msgid="1501588340716182495">"এই প্ৰমাণপত্ৰখনৰ ম্যাদ উকলি গৈছে।"</string>
-    <string name="ssl_error_not_yet_valid" msgid="8648649030525886924">"এই প্ৰমাণপত্ৰখন এই পর্যন্ত মান্য হোৱা নাই।"</string>
-    <string name="ssl_error_date_invalid" msgid="88425990680059223">"এই প্ৰমাণপত্ৰখনত থকা তাৰিখটো মান্য নহয়।"</string>
-    <string name="ssl_error_invalid" msgid="2540546515565633432">"এই প্ৰমাণপত্ৰখন মান্য নহয়।"</string>
-    <string name="ssl_error_unknown" msgid="4405203446079465859">"প্ৰমাণপত্ৰত অজ্ঞাত আসোঁৱাহ।"</string>
-    <string name="ssl_security_warning_title" msgid="8768539813847504404">"সুৰক্ষা সম্পর্কীয় সতৰ্কতা"</string>
-    <string name="ssl_error_view_certificate" msgid="5722652540168339333">"প্ৰমাণপত্ৰ চাওক"</string>
-    <string name="ok" msgid="2817931639040794018">"ঠিক আছে"</string>
-    <string name="page_info_address" msgid="1261481517455692363">"ঠিকনা:"</string>
-    <string name="page_info" msgid="4416941086705172545">"পৃষ্ঠাৰ তথ্য"</string>
-</resources>
diff --git a/packages/CaptivePortalLogin/res/values-az/strings.xml b/packages/CaptivePortalLogin/res/values-az/strings.xml
deleted file mode 100644
index f002544..0000000
--- a/packages/CaptivePortalLogin/res/values-az/strings.xml
+++ /dev/null
@@ -1,24 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="app_name" msgid="5934709770924185752">"CaptivePortalLogin"</string>
-    <string name="action_use_network" msgid="6076184727448466030">"Bu şəbəkəni olduğu kimi istifadə edin"</string>
-    <string name="action_do_not_use_network" msgid="4577366536956516683">"Bu şəbəkəni istifadə etməyin"</string>
-    <string name="action_bar_label" msgid="917235635415966620">"Şəbəkəyə daxil olun"</string>
-    <string name="action_bar_title" msgid="5645564790486983117">"Daxil olun: %1$s"</string>
-    <string name="ssl_error_warning" msgid="6653188881418638872">"Qoşulmaq istədiyiniz şəbəkənin təhlükəsizlik problemləri var."</string>
-    <string name="ssl_error_example" msgid="647898534624078900">"Məsələn, giriş səhifəsi göstərilən təşkilata aid olmaya bilər."</string>
-    <string name="ssl_error_continue" msgid="6492718244923937110">"Hər bir halda brazuer ilə davam edin"</string>
-    <string name="ssl_error_untrusted" msgid="1496280318271264520">"Bu sertifikat etibarlı orqan tərəfindən verilməyib."</string>
-    <string name="ssl_error_mismatch" msgid="3060364165934822383">"Saytın adı sertifikatdakı ada uyğun deyil."</string>
-    <string name="ssl_error_expired" msgid="1501588340716182495">"Bu sertifikatın müddəti bitib."</string>
-    <string name="ssl_error_not_yet_valid" msgid="8648649030525886924">"Bu sertifikat hələ etibarlı deyil."</string>
-    <string name="ssl_error_date_invalid" msgid="88425990680059223">"Bu sertifikatın tarixi yanlışdır."</string>
-    <string name="ssl_error_invalid" msgid="2540546515565633432">"Bu sertifikat etibarsızdır."</string>
-    <string name="ssl_error_unknown" msgid="4405203446079465859">"Bilinməyən sertifikat xətası."</string>
-    <string name="ssl_security_warning_title" msgid="8768539813847504404">"Təhlükəsizlik xəbərdarlığı"</string>
-    <string name="ssl_error_view_certificate" msgid="5722652540168339333">"Sertifikata baxın"</string>
-    <string name="ok" msgid="2817931639040794018">"OK"</string>
-    <string name="page_info_address" msgid="1261481517455692363">"Ünvan:"</string>
-    <string name="page_info" msgid="4416941086705172545">"Səhifə məlumatı"</string>
-</resources>
diff --git a/packages/CaptivePortalLogin/res/values-b+sr+Latn/strings.xml b/packages/CaptivePortalLogin/res/values-b+sr+Latn/strings.xml
deleted file mode 100644
index 401548b..0000000
--- a/packages/CaptivePortalLogin/res/values-b+sr+Latn/strings.xml
+++ /dev/null
@@ -1,24 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="app_name" msgid="5934709770924185752">"CaptivePortalLogin"</string>
-    <string name="action_use_network" msgid="6076184727448466030">"Koristi ovu mrežu takvu kakva je"</string>
-    <string name="action_do_not_use_network" msgid="4577366536956516683">"Ne koristi ovu mrežu"</string>
-    <string name="action_bar_label" msgid="917235635415966620">"Prijavi me na mrežu"</string>
-    <string name="action_bar_title" msgid="5645564790486983117">"Prijavite se u: %1$s"</string>
-    <string name="ssl_error_warning" msgid="6653188881418638872">"Mreža kojoj pokušavate da se pridružite ima bezbednosnih problema."</string>
-    <string name="ssl_error_example" msgid="647898534624078900">"Na primer, stranica za prijavljivanje možda ne pripada prikazanoj organizaciji."</string>
-    <string name="ssl_error_continue" msgid="6492718244923937110">"Ipak nastavi preko pregledača"</string>
-    <string name="ssl_error_untrusted" msgid="1496280318271264520">"Ovaj sertifikat ne potiče iz pouzdanog izvora."</string>
-    <string name="ssl_error_mismatch" msgid="3060364165934822383">"Naziv sajta se ne podudara sa nazivom na sertifikatu."</string>
-    <string name="ssl_error_expired" msgid="1501588340716182495">"Ovaj sertifikat je istekao."</string>
-    <string name="ssl_error_not_yet_valid" msgid="8648649030525886924">"Ovaj sertifikat još uvek nije važeći."</string>
-    <string name="ssl_error_date_invalid" msgid="88425990680059223">"Datum ovog sertifikata je nevažeći."</string>
-    <string name="ssl_error_invalid" msgid="2540546515565633432">"Ovaj sertifikat je nevažeći."</string>
-    <string name="ssl_error_unknown" msgid="4405203446079465859">"Nepoznata greška sertifikata."</string>
-    <string name="ssl_security_warning_title" msgid="8768539813847504404">"Bezbednosno upozorenje"</string>
-    <string name="ssl_error_view_certificate" msgid="5722652540168339333">"Prikaži sertifikat"</string>
-    <string name="ok" msgid="2817931639040794018">"Potvrdi"</string>
-    <string name="page_info_address" msgid="1261481517455692363">"Adresa:"</string>
-    <string name="page_info" msgid="4416941086705172545">"Informacije o stranici"</string>
-</resources>
diff --git a/packages/CaptivePortalLogin/res/values-be/strings.xml b/packages/CaptivePortalLogin/res/values-be/strings.xml
deleted file mode 100644
index 5f2bd90..0000000
--- a/packages/CaptivePortalLogin/res/values-be/strings.xml
+++ /dev/null
@@ -1,24 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="app_name" msgid="5934709770924185752">"CaptivePortalLogin"</string>
-    <string name="action_use_network" msgid="6076184727448466030">"Выкарыстоўваць гэтую сетку як ёсць"</string>
-    <string name="action_do_not_use_network" msgid="4577366536956516683">"Не выкарыстоўваць гэту сетку"</string>
-    <string name="action_bar_label" msgid="917235635415966620">"Увайсці ў сетку"</string>
-    <string name="action_bar_title" msgid="5645564790486983117">"Увайсці ў %1$s"</string>
-    <string name="ssl_error_warning" msgid="6653188881418638872">"У сеткі, да якой вы спрабуеце далучыцца, ёсць праблемы з бяспекай."</string>
-    <string name="ssl_error_example" msgid="647898534624078900">"Напрыклад, старонка ўваходу можа не належаць указанай арганізацыі."</string>
-    <string name="ssl_error_continue" msgid="6492718244923937110">"Усё роўна працягнуць праз браўзер"</string>
-    <string name="ssl_error_untrusted" msgid="1496280318271264520">"Гэты сертыфікат не выдадзены давераным цэнтрам."</string>
-    <string name="ssl_error_mismatch" msgid="3060364165934822383">"Назва сайта не адпавядае назве ў сертыфікаце."</string>
-    <string name="ssl_error_expired" msgid="1501588340716182495">"Тэрмін дзеяння сертыфіката мінуў."</string>
-    <string name="ssl_error_not_yet_valid" msgid="8648649030525886924">"Гэты сертыфікат яшчэ не дзейнічае."</string>
-    <string name="ssl_error_date_invalid" msgid="88425990680059223">"Гэты сертыфікат мае несапраўдную дату."</string>
-    <string name="ssl_error_invalid" msgid="2540546515565633432">"Гэты сертыфікат несапраўдны."</string>
-    <string name="ssl_error_unknown" msgid="4405203446079465859">"Невядомая памылка сертыфіката."</string>
-    <string name="ssl_security_warning_title" msgid="8768539813847504404">"Папярэджанне сістэмы бяспекі"</string>
-    <string name="ssl_error_view_certificate" msgid="5722652540168339333">"Прагледзець сертыфікат"</string>
-    <string name="ok" msgid="2817931639040794018">"ОК"</string>
-    <string name="page_info_address" msgid="1261481517455692363">"Адрас:"</string>
-    <string name="page_info" msgid="4416941086705172545">"Інфармацыя пра старонку"</string>
-</resources>
diff --git a/packages/CaptivePortalLogin/res/values-bg/strings.xml b/packages/CaptivePortalLogin/res/values-bg/strings.xml
deleted file mode 100644
index c5354e8..0000000
--- a/packages/CaptivePortalLogin/res/values-bg/strings.xml
+++ /dev/null
@@ -1,24 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="app_name" msgid="5934709770924185752">"CaptivePortalLogin"</string>
-    <string name="action_use_network" msgid="6076184727448466030">"Директно използване на тази мрежа"</string>
-    <string name="action_do_not_use_network" msgid="4577366536956516683">"Без използване на тази мрежа"</string>
-    <string name="action_bar_label" msgid="917235635415966620">"Вход в мрежата"</string>
-    <string name="action_bar_title" msgid="5645564790486983117">"Влезте в/ъв %1$s"</string>
-    <string name="ssl_error_warning" msgid="6653188881418638872">"Мрежата, към която опитвате да се присъедините, има проблеми със сигурността."</string>
-    <string name="ssl_error_example" msgid="647898534624078900">"Например страницата за вход може да не принадлежи на показаната организация."</string>
-    <string name="ssl_error_continue" msgid="6492718244923937110">"Продължаване през браузър въпреки това"</string>
-    <string name="ssl_error_untrusted" msgid="1496280318271264520">"Този сертификат не е от надежден орган."</string>
-    <string name="ssl_error_mismatch" msgid="3060364165934822383">"Името на сайта не съответства на името в сертификата."</string>
-    <string name="ssl_error_expired" msgid="1501588340716182495">"Този сертификат е изтекъл."</string>
-    <string name="ssl_error_not_yet_valid" msgid="8648649030525886924">"Този сертификат още не е валиден."</string>
-    <string name="ssl_error_date_invalid" msgid="88425990680059223">"Този сертификат е с невалидна дата."</string>
-    <string name="ssl_error_invalid" msgid="2540546515565633432">"Този сертификат е невалиден."</string>
-    <string name="ssl_error_unknown" msgid="4405203446079465859">"Неизвестна грешка в сертификата."</string>
-    <string name="ssl_security_warning_title" msgid="8768539813847504404">"Предупреждение относно сигурността"</string>
-    <string name="ssl_error_view_certificate" msgid="5722652540168339333">"Преглед на сертификата"</string>
-    <string name="ok" msgid="2817931639040794018">"OK"</string>
-    <string name="page_info_address" msgid="1261481517455692363">"Адрес:"</string>
-    <string name="page_info" msgid="4416941086705172545">"Данни за страницата"</string>
-</resources>
diff --git a/packages/CaptivePortalLogin/res/values-bn/strings.xml b/packages/CaptivePortalLogin/res/values-bn/strings.xml
deleted file mode 100644
index 3fbe2f2..0000000
--- a/packages/CaptivePortalLogin/res/values-bn/strings.xml
+++ /dev/null
@@ -1,24 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="app_name" msgid="5934709770924185752">"CaptivePortalLogin"</string>
-    <string name="action_use_network" msgid="6076184727448466030">"যেভাবে আছে সেভাবেই এই নেটওয়ার্ক ব্যবহার করুন"</string>
-    <string name="action_do_not_use_network" msgid="4577366536956516683">"এই নেটওয়ার্ক ব্যবহার করবেন না"</string>
-    <string name="action_bar_label" msgid="917235635415966620">"নেটওয়ার্কে সাইন-ইন করুন"</string>
-    <string name="action_bar_title" msgid="5645564790486983117">"%1$s তে সাইন-ইন করুন"</string>
-    <string name="ssl_error_warning" msgid="6653188881418638872">"আপনি যে নেটওয়ার্কে যোগ দেওয়ার চেষ্টা করছেন তাতে নিরাপত্তার সমস্যা আছে।"</string>
-    <string name="ssl_error_example" msgid="647898534624078900">"উদাহরণস্বরূপ, লগ-ইন পৃষ্ঠাটি প্রদর্শিত প্রতিষ্ঠানের অন্তর্গত নাও হতে পারে৷"</string>
-    <string name="ssl_error_continue" msgid="6492718244923937110">"যাই হোক না কেন ব্রাউজারের মাধ্যমে অবিরত রাখুন"</string>
-    <string name="ssl_error_untrusted" msgid="1496280318271264520">"এই সার্টিফিকেটটি একটি বিশ্বস্ত কর্তৃপক্ষের তরফ থেকে নয়।"</string>
-    <string name="ssl_error_mismatch" msgid="3060364165934822383">"সাইটের নামটি সার্টিফিকেটে লেখা নামের সাথে মিলছে না।"</string>
-    <string name="ssl_error_expired" msgid="1501588340716182495">"এই সার্টিফিকেটের মেয়াদ শেষ হয়ে গেছে।"</string>
-    <string name="ssl_error_not_yet_valid" msgid="8648649030525886924">"সার্টিফিকেটটি এখনও সঠিক নয়।"</string>
-    <string name="ssl_error_date_invalid" msgid="88425990680059223">"এই সার্টিফিকেটের তারিখটি সঠিক নয়।"</string>
-    <string name="ssl_error_invalid" msgid="2540546515565633432">"সার্টিফিকেটটি সঠিক নয়।"</string>
-    <string name="ssl_error_unknown" msgid="4405203446079465859">"সার্টিফিকেটের সমস্যাটি অজানা।"</string>
-    <string name="ssl_security_warning_title" msgid="8768539813847504404">"নিরাপত্তার সতর্কতা"</string>
-    <string name="ssl_error_view_certificate" msgid="5722652540168339333">"সার্টিফিকেট দেখুন"</string>
-    <string name="ok" msgid="2817931639040794018">"ঠিক আছে"</string>
-    <string name="page_info_address" msgid="1261481517455692363">"ঠিকানা:"</string>
-    <string name="page_info" msgid="4416941086705172545">"পৃষ্ঠার তথ্য"</string>
-</resources>
diff --git a/packages/CaptivePortalLogin/res/values-bs/strings.xml b/packages/CaptivePortalLogin/res/values-bs/strings.xml
deleted file mode 100644
index 83b5067..0000000
--- a/packages/CaptivePortalLogin/res/values-bs/strings.xml
+++ /dev/null
@@ -1,24 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="app_name" msgid="5934709770924185752">"Prijava na zaštitnom portalu"</string>
-    <string name="action_use_network" msgid="6076184727448466030">"Koristi ovu mrežu kakva jeste"</string>
-    <string name="action_do_not_use_network" msgid="4577366536956516683">"Ne koristi ovu mrežu"</string>
-    <string name="action_bar_label" msgid="917235635415966620">"Prijava na mrežu"</string>
-    <string name="action_bar_title" msgid="5645564790486983117">"Prijava na %1$s"</string>
-    <string name="ssl_error_warning" msgid="6653188881418638872">"Mreža kojoj pokušavate pristupiti ima sigurnosnih problema."</string>
-    <string name="ssl_error_example" msgid="647898534624078900">"Naprimjer, stranica za prijavu možda ne pripada prikazanoj organizaciji."</string>
-    <string name="ssl_error_continue" msgid="6492718244923937110">"Ipak nastavi preko preglednika"</string>
-    <string name="ssl_error_untrusted" msgid="1496280318271264520">"Ova potvrda ne potiče iz pouzdanog izvora."</string>
-    <string name="ssl_error_mismatch" msgid="3060364165934822383">"Naziv web lokacije se ne podudara s nazivom na potvrdi."</string>
-    <string name="ssl_error_expired" msgid="1501588340716182495">"Ova potvrda je istekla."</string>
-    <string name="ssl_error_not_yet_valid" msgid="8648649030525886924">"Ova potvrda još uvijek nije važeća."</string>
-    <string name="ssl_error_date_invalid" msgid="88425990680059223">"Ova potvrda sadrži nevažeći datum."</string>
-    <string name="ssl_error_invalid" msgid="2540546515565633432">"Ova potvrda je nevažeća."</string>
-    <string name="ssl_error_unknown" msgid="4405203446079465859">"Nepoznata greška potvrde."</string>
-    <string name="ssl_security_warning_title" msgid="8768539813847504404">"Sigurnosno upozorenje"</string>
-    <string name="ssl_error_view_certificate" msgid="5722652540168339333">"Prikaži potvrdu"</string>
-    <string name="ok" msgid="2817931639040794018">"Uredu"</string>
-    <string name="page_info_address" msgid="1261481517455692363">"Adresa:"</string>
-    <string name="page_info" msgid="4416941086705172545">"Informacije o stranici"</string>
-</resources>
diff --git a/packages/CaptivePortalLogin/res/values-ca/strings.xml b/packages/CaptivePortalLogin/res/values-ca/strings.xml
deleted file mode 100644
index 557c3f4..0000000
--- a/packages/CaptivePortalLogin/res/values-ca/strings.xml
+++ /dev/null
@@ -1,24 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="app_name" msgid="5934709770924185752">"CaptivePortalLogin"</string>
-    <string name="action_use_network" msgid="6076184727448466030">"Fes servir aquesta xarxa tal com està."</string>
-    <string name="action_do_not_use_network" msgid="4577366536956516683">"No facis servir aquesta xarxa."</string>
-    <string name="action_bar_label" msgid="917235635415966620">"Inicia la sessió a la xarxa"</string>
-    <string name="action_bar_title" msgid="5645564790486983117">"Inicia la sessió a %1$s"</string>
-    <string name="ssl_error_warning" msgid="6653188881418638872">"La xarxa a què et vols connectar té problemes de seguretat."</string>
-    <string name="ssl_error_example" msgid="647898534624078900">"Per exemple, la pàgina d\'inici de sessió podria no pertànyer a l\'organització que es mostra."</string>
-    <string name="ssl_error_continue" msgid="6492718244923937110">"Continua igualment mitjançant el navegador"</string>
-    <string name="ssl_error_untrusted" msgid="1496280318271264520">"Aquest certificat no és d\'una autoritat de confiança."</string>
-    <string name="ssl_error_mismatch" msgid="3060364165934822383">"El nom del lloc web no coincideix amb el que inclou el certificat."</string>
-    <string name="ssl_error_expired" msgid="1501588340716182495">"Aquest certificat ha caducat."</string>
-    <string name="ssl_error_not_yet_valid" msgid="8648649030525886924">"Aquest certificat encara no és vàlid."</string>
-    <string name="ssl_error_date_invalid" msgid="88425990680059223">"Aquest certificat té una data no vàlida."</string>
-    <string name="ssl_error_invalid" msgid="2540546515565633432">"Aquest certificat no és vàlid."</string>
-    <string name="ssl_error_unknown" msgid="4405203446079465859">"S\'ha produït un error desconegut de certificat."</string>
-    <string name="ssl_security_warning_title" msgid="8768539813847504404">"Advertiment de seguretat"</string>
-    <string name="ssl_error_view_certificate" msgid="5722652540168339333">"Mostra el certificat"</string>
-    <string name="ok" msgid="2817931639040794018">"D\'acord"</string>
-    <string name="page_info_address" msgid="1261481517455692363">"Adreça:"</string>
-    <string name="page_info" msgid="4416941086705172545">"Informació de la pàgina"</string>
-</resources>
diff --git a/packages/CaptivePortalLogin/res/values-cs/strings.xml b/packages/CaptivePortalLogin/res/values-cs/strings.xml
deleted file mode 100644
index 0328c76..0000000
--- a/packages/CaptivePortalLogin/res/values-cs/strings.xml
+++ /dev/null
@@ -1,24 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="app_name" msgid="5934709770924185752">"CaptivePortalLogin"</string>
-    <string name="action_use_network" msgid="6076184727448466030">"Použít tuto síť tak, jak je"</string>
-    <string name="action_do_not_use_network" msgid="4577366536956516683">"Tuto síť nepoužívat"</string>
-    <string name="action_bar_label" msgid="917235635415966620">"Přihlásit se k síti"</string>
-    <string name="action_bar_title" msgid="5645564790486983117">"Přihlaste se k síti %1$s"</string>
-    <string name="ssl_error_warning" msgid="6653188881418638872">"Síť, ke které se pokoušíte připojit, má bezpečnostní problémy."</string>
-    <string name="ssl_error_example" msgid="647898534624078900">"Například přihlašovací stránka nemusí patřit do zobrazované organizace."</string>
-    <string name="ssl_error_continue" msgid="6492718244923937110">"Přesto pokračovat prostřednictvím prohlížeče"</string>
-    <string name="ssl_error_untrusted" msgid="1496280318271264520">"Tento certifikát nepochází od důvěryhodné autority."</string>
-    <string name="ssl_error_mismatch" msgid="3060364165934822383">"Název webu se neshoduje s názvem uvedeným v certifikátu."</string>
-    <string name="ssl_error_expired" msgid="1501588340716182495">"Platnost certifikátu vypršela."</string>
-    <string name="ssl_error_not_yet_valid" msgid="8648649030525886924">"Tento certifikát ještě není platný."</string>
-    <string name="ssl_error_date_invalid" msgid="88425990680059223">"Datum tohoto certifikátu není platné."</string>
-    <string name="ssl_error_invalid" msgid="2540546515565633432">"Tento certifikát je neplatný."</string>
-    <string name="ssl_error_unknown" msgid="4405203446079465859">"Neznámá chyba certifikátu."</string>
-    <string name="ssl_security_warning_title" msgid="8768539813847504404">"Bezpečnostní upozornění"</string>
-    <string name="ssl_error_view_certificate" msgid="5722652540168339333">"Zobrazit certifikát"</string>
-    <string name="ok" msgid="2817931639040794018">"OK"</string>
-    <string name="page_info_address" msgid="1261481517455692363">"Adresa:"</string>
-    <string name="page_info" msgid="4416941086705172545">"Informace o stránce"</string>
-</resources>
diff --git a/packages/CaptivePortalLogin/res/values-da/strings.xml b/packages/CaptivePortalLogin/res/values-da/strings.xml
deleted file mode 100644
index b9cf7fe9..0000000
--- a/packages/CaptivePortalLogin/res/values-da/strings.xml
+++ /dev/null
@@ -1,24 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="app_name" msgid="5934709770924185752">"Login til captive portal"</string>
-    <string name="action_use_network" msgid="6076184727448466030">"Brug dette netværk, som det er"</string>
-    <string name="action_do_not_use_network" msgid="4577366536956516683">"Brug ikke dette netværk"</string>
-    <string name="action_bar_label" msgid="917235635415966620">"Log ind på netværk"</string>
-    <string name="action_bar_title" msgid="5645564790486983117">"Log ind på %1$s"</string>
-    <string name="ssl_error_warning" msgid="6653188881418638872">"Der er sikkerhedsproblemer på det netværk, du forsøger at logge ind på."</string>
-    <string name="ssl_error_example" msgid="647898534624078900">"Det er f.eks. ikke sikkert, at loginsiden tilhører den anførte organisation."</string>
-    <string name="ssl_error_continue" msgid="6492718244923937110">"Fortsæt alligevel via browseren"</string>
-    <string name="ssl_error_untrusted" msgid="1496280318271264520">"Dette certifikat stammer ikke fra en pålidelig kilde."</string>
-    <string name="ssl_error_mismatch" msgid="3060364165934822383">"Navnet på websitet stemmer ikke overens med navnet på certifikatet."</string>
-    <string name="ssl_error_expired" msgid="1501588340716182495">"Dette certifikat er udløbet."</string>
-    <string name="ssl_error_not_yet_valid" msgid="8648649030525886924">"Dette certifikat er ikke gyldigt endnu."</string>
-    <string name="ssl_error_date_invalid" msgid="88425990680059223">"Dette certifikat har en ugyldig dato."</string>
-    <string name="ssl_error_invalid" msgid="2540546515565633432">"Dette certifikat er ugyldigt."</string>
-    <string name="ssl_error_unknown" msgid="4405203446079465859">"Ukendt certifikatfejl."</string>
-    <string name="ssl_security_warning_title" msgid="8768539813847504404">"Sikkerhedsadvarsel"</string>
-    <string name="ssl_error_view_certificate" msgid="5722652540168339333">"Se certifikat"</string>
-    <string name="ok" msgid="2817931639040794018">"OK"</string>
-    <string name="page_info_address" msgid="1261481517455692363">"Adresse:"</string>
-    <string name="page_info" msgid="4416941086705172545">"Sideoplysninger"</string>
-</resources>
diff --git a/packages/CaptivePortalLogin/res/values-de/strings.xml b/packages/CaptivePortalLogin/res/values-de/strings.xml
deleted file mode 100644
index 4276bf9..0000000
--- a/packages/CaptivePortalLogin/res/values-de/strings.xml
+++ /dev/null
@@ -1,24 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="app_name" msgid="5934709770924185752">"CaptivePortalLogin"</string>
-    <string name="action_use_network" msgid="6076184727448466030">"Netzwerk im Istzustand verwenden"</string>
-    <string name="action_do_not_use_network" msgid="4577366536956516683">"Netzwerk nicht verwenden"</string>
-    <string name="action_bar_label" msgid="917235635415966620">"Im Netzwerk anmelden"</string>
-    <string name="action_bar_title" msgid="5645564790486983117">"In %1$s anmelden"</string>
-    <string name="ssl_error_warning" msgid="6653188881418638872">"Im Netzwerk, zu dem du eine Verbindung herstellen möchtest, liegen Sicherheitsprobleme vor."</string>
-    <string name="ssl_error_example" msgid="647898534624078900">"Beispiel: Die Log-in-Seite gehört eventuell nicht zur angezeigten Organisation."</string>
-    <string name="ssl_error_continue" msgid="6492718244923937110">"Trotzdem in einem Browser fortfahren"</string>
-    <string name="ssl_error_untrusted" msgid="1496280318271264520">"Dieses Zertifikat stammt nicht von einer vertrauenswürdigen Stelle."</string>
-    <string name="ssl_error_mismatch" msgid="3060364165934822383">"Der Name der Website stimmt nicht mit dem Namen auf dem Zertifikat überein."</string>
-    <string name="ssl_error_expired" msgid="1501588340716182495">"Dieses Zertifikat ist abgelaufen."</string>
-    <string name="ssl_error_not_yet_valid" msgid="8648649030525886924">"Dieses Zertifikat ist noch nicht gültig."</string>
-    <string name="ssl_error_date_invalid" msgid="88425990680059223">"Dieses Zertifikat hat ein ungültiges Datum."</string>
-    <string name="ssl_error_invalid" msgid="2540546515565633432">"Dieses Zertifikat ist ungültig."</string>
-    <string name="ssl_error_unknown" msgid="4405203446079465859">"Unbekannter Zertifikatfehler."</string>
-    <string name="ssl_security_warning_title" msgid="8768539813847504404">"Sicherheitswarnung"</string>
-    <string name="ssl_error_view_certificate" msgid="5722652540168339333">"Zertifikat ansehen"</string>
-    <string name="ok" msgid="2817931639040794018">"Ok"</string>
-    <string name="page_info_address" msgid="1261481517455692363">"Adresse:"</string>
-    <string name="page_info" msgid="4416941086705172545">"Seiteninformationen"</string>
-</resources>
diff --git a/packages/CaptivePortalLogin/res/values-el/strings.xml b/packages/CaptivePortalLogin/res/values-el/strings.xml
deleted file mode 100644
index f4de7c3..0000000
--- a/packages/CaptivePortalLogin/res/values-el/strings.xml
+++ /dev/null
@@ -1,24 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="app_name" msgid="5934709770924185752">"CaptivePortalLogin"</string>
-    <string name="action_use_network" msgid="6076184727448466030">"Χρήση αυτού του δικτύου ως έχει"</string>
-    <string name="action_do_not_use_network" msgid="4577366536956516683">"Να μη χρησιμοποιείται αυτό το δίκτυο"</string>
-    <string name="action_bar_label" msgid="917235635415966620">"Σύνδεση στο δίκτυο"</string>
-    <string name="action_bar_title" msgid="5645564790486983117">"Συνδεθείτε στο %1$s"</string>
-    <string name="ssl_error_warning" msgid="6653188881418638872">"Παρουσιάζονται προβλήματα ασφάλειας στο δίκτυο στο οποίο προσπαθείτε να συνδεθείτε."</string>
-    <string name="ssl_error_example" msgid="647898534624078900">"Για παράδειγμα, η σελίδα σύνδεσης ενδέχεται να μην ανήκει στον οργανισμό που εμφανίζεται."</string>
-    <string name="ssl_error_continue" msgid="6492718244923937110">"Συνέχεια ούτως ή άλλως μέσω του προγράμματος περιήγησης"</string>
-    <string name="ssl_error_untrusted" msgid="1496280318271264520">"Αυτό το πιστοποιητικό δεν προέρχεται από αξιόπιστη αρχή."</string>
-    <string name="ssl_error_mismatch" msgid="3060364165934822383">"Το όνομα του ιστοτόπου δεν αντιστοιχεί στο όνομα στο πιστοποιητικό."</string>
-    <string name="ssl_error_expired" msgid="1501588340716182495">"Αυτό το πιστοποιητικό έχει λήξει."</string>
-    <string name="ssl_error_not_yet_valid" msgid="8648649030525886924">"Αυτό το πιστοποιητικό δεν είναι έγκυρο ακόμα."</string>
-    <string name="ssl_error_date_invalid" msgid="88425990680059223">"Αυτό το πιστοποιητικό δεν έχει έγκυρη ημερομηνία."</string>
-    <string name="ssl_error_invalid" msgid="2540546515565633432">"Αυτό το πιστοποιητικό δεν είναι έγκυρο."</string>
-    <string name="ssl_error_unknown" msgid="4405203446079465859">"Άγνωστο σφάλμα πιστοποιητικού."</string>
-    <string name="ssl_security_warning_title" msgid="8768539813847504404">"Προειδοποίηση ασφαλείας"</string>
-    <string name="ssl_error_view_certificate" msgid="5722652540168339333">"Προβολή πιστοποιητικού"</string>
-    <string name="ok" msgid="2817931639040794018">"ΟΚ"</string>
-    <string name="page_info_address" msgid="1261481517455692363">"Διεύθυνση:"</string>
-    <string name="page_info" msgid="4416941086705172545">"Πληροφορίες σελίδας"</string>
-</resources>
diff --git a/packages/CaptivePortalLogin/res/values-en-rAU/strings.xml b/packages/CaptivePortalLogin/res/values-en-rAU/strings.xml
deleted file mode 100644
index 9763339..0000000
--- a/packages/CaptivePortalLogin/res/values-en-rAU/strings.xml
+++ /dev/null
@@ -1,24 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="app_name" msgid="5934709770924185752">"CaptivePortalLogin"</string>
-    <string name="action_use_network" msgid="6076184727448466030">"Use this network as is"</string>
-    <string name="action_do_not_use_network" msgid="4577366536956516683">"Do not use this network"</string>
-    <string name="action_bar_label" msgid="917235635415966620">"Sign in to network"</string>
-    <string name="action_bar_title" msgid="5645564790486983117">"Sign in to %1$s"</string>
-    <string name="ssl_error_warning" msgid="6653188881418638872">"The network that you’re trying to join has security issues."</string>
-    <string name="ssl_error_example" msgid="647898534624078900">"For example, the login page might not belong to the organisation shown."</string>
-    <string name="ssl_error_continue" msgid="6492718244923937110">"Continue anyway via browser"</string>
-    <string name="ssl_error_untrusted" msgid="1496280318271264520">"This certificate isn\'t from a trusted authority."</string>
-    <string name="ssl_error_mismatch" msgid="3060364165934822383">"The name of the site doesn\'t match the name on the certificate."</string>
-    <string name="ssl_error_expired" msgid="1501588340716182495">"This certificate has expired."</string>
-    <string name="ssl_error_not_yet_valid" msgid="8648649030525886924">"This certificate isn\'t valid yet."</string>
-    <string name="ssl_error_date_invalid" msgid="88425990680059223">"This certificate has an invalid date."</string>
-    <string name="ssl_error_invalid" msgid="2540546515565633432">"This certificate is invalid."</string>
-    <string name="ssl_error_unknown" msgid="4405203446079465859">"Unknown certificate error."</string>
-    <string name="ssl_security_warning_title" msgid="8768539813847504404">"Security warning"</string>
-    <string name="ssl_error_view_certificate" msgid="5722652540168339333">"View certificate"</string>
-    <string name="ok" msgid="2817931639040794018">"OK"</string>
-    <string name="page_info_address" msgid="1261481517455692363">"Address:"</string>
-    <string name="page_info" msgid="4416941086705172545">"Page info"</string>
-</resources>
diff --git a/packages/CaptivePortalLogin/res/values-en-rCA/strings.xml b/packages/CaptivePortalLogin/res/values-en-rCA/strings.xml
deleted file mode 100644
index 9763339..0000000
--- a/packages/CaptivePortalLogin/res/values-en-rCA/strings.xml
+++ /dev/null
@@ -1,24 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="app_name" msgid="5934709770924185752">"CaptivePortalLogin"</string>
-    <string name="action_use_network" msgid="6076184727448466030">"Use this network as is"</string>
-    <string name="action_do_not_use_network" msgid="4577366536956516683">"Do not use this network"</string>
-    <string name="action_bar_label" msgid="917235635415966620">"Sign in to network"</string>
-    <string name="action_bar_title" msgid="5645564790486983117">"Sign in to %1$s"</string>
-    <string name="ssl_error_warning" msgid="6653188881418638872">"The network that you’re trying to join has security issues."</string>
-    <string name="ssl_error_example" msgid="647898534624078900">"For example, the login page might not belong to the organisation shown."</string>
-    <string name="ssl_error_continue" msgid="6492718244923937110">"Continue anyway via browser"</string>
-    <string name="ssl_error_untrusted" msgid="1496280318271264520">"This certificate isn\'t from a trusted authority."</string>
-    <string name="ssl_error_mismatch" msgid="3060364165934822383">"The name of the site doesn\'t match the name on the certificate."</string>
-    <string name="ssl_error_expired" msgid="1501588340716182495">"This certificate has expired."</string>
-    <string name="ssl_error_not_yet_valid" msgid="8648649030525886924">"This certificate isn\'t valid yet."</string>
-    <string name="ssl_error_date_invalid" msgid="88425990680059223">"This certificate has an invalid date."</string>
-    <string name="ssl_error_invalid" msgid="2540546515565633432">"This certificate is invalid."</string>
-    <string name="ssl_error_unknown" msgid="4405203446079465859">"Unknown certificate error."</string>
-    <string name="ssl_security_warning_title" msgid="8768539813847504404">"Security warning"</string>
-    <string name="ssl_error_view_certificate" msgid="5722652540168339333">"View certificate"</string>
-    <string name="ok" msgid="2817931639040794018">"OK"</string>
-    <string name="page_info_address" msgid="1261481517455692363">"Address:"</string>
-    <string name="page_info" msgid="4416941086705172545">"Page info"</string>
-</resources>
diff --git a/packages/CaptivePortalLogin/res/values-en-rGB/strings.xml b/packages/CaptivePortalLogin/res/values-en-rGB/strings.xml
deleted file mode 100644
index 9763339..0000000
--- a/packages/CaptivePortalLogin/res/values-en-rGB/strings.xml
+++ /dev/null
@@ -1,24 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="app_name" msgid="5934709770924185752">"CaptivePortalLogin"</string>
-    <string name="action_use_network" msgid="6076184727448466030">"Use this network as is"</string>
-    <string name="action_do_not_use_network" msgid="4577366536956516683">"Do not use this network"</string>
-    <string name="action_bar_label" msgid="917235635415966620">"Sign in to network"</string>
-    <string name="action_bar_title" msgid="5645564790486983117">"Sign in to %1$s"</string>
-    <string name="ssl_error_warning" msgid="6653188881418638872">"The network that you’re trying to join has security issues."</string>
-    <string name="ssl_error_example" msgid="647898534624078900">"For example, the login page might not belong to the organisation shown."</string>
-    <string name="ssl_error_continue" msgid="6492718244923937110">"Continue anyway via browser"</string>
-    <string name="ssl_error_untrusted" msgid="1496280318271264520">"This certificate isn\'t from a trusted authority."</string>
-    <string name="ssl_error_mismatch" msgid="3060364165934822383">"The name of the site doesn\'t match the name on the certificate."</string>
-    <string name="ssl_error_expired" msgid="1501588340716182495">"This certificate has expired."</string>
-    <string name="ssl_error_not_yet_valid" msgid="8648649030525886924">"This certificate isn\'t valid yet."</string>
-    <string name="ssl_error_date_invalid" msgid="88425990680059223">"This certificate has an invalid date."</string>
-    <string name="ssl_error_invalid" msgid="2540546515565633432">"This certificate is invalid."</string>
-    <string name="ssl_error_unknown" msgid="4405203446079465859">"Unknown certificate error."</string>
-    <string name="ssl_security_warning_title" msgid="8768539813847504404">"Security warning"</string>
-    <string name="ssl_error_view_certificate" msgid="5722652540168339333">"View certificate"</string>
-    <string name="ok" msgid="2817931639040794018">"OK"</string>
-    <string name="page_info_address" msgid="1261481517455692363">"Address:"</string>
-    <string name="page_info" msgid="4416941086705172545">"Page info"</string>
-</resources>
diff --git a/packages/CaptivePortalLogin/res/values-en-rIN/strings.xml b/packages/CaptivePortalLogin/res/values-en-rIN/strings.xml
deleted file mode 100644
index 9763339..0000000
--- a/packages/CaptivePortalLogin/res/values-en-rIN/strings.xml
+++ /dev/null
@@ -1,24 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="app_name" msgid="5934709770924185752">"CaptivePortalLogin"</string>
-    <string name="action_use_network" msgid="6076184727448466030">"Use this network as is"</string>
-    <string name="action_do_not_use_network" msgid="4577366536956516683">"Do not use this network"</string>
-    <string name="action_bar_label" msgid="917235635415966620">"Sign in to network"</string>
-    <string name="action_bar_title" msgid="5645564790486983117">"Sign in to %1$s"</string>
-    <string name="ssl_error_warning" msgid="6653188881418638872">"The network that you’re trying to join has security issues."</string>
-    <string name="ssl_error_example" msgid="647898534624078900">"For example, the login page might not belong to the organisation shown."</string>
-    <string name="ssl_error_continue" msgid="6492718244923937110">"Continue anyway via browser"</string>
-    <string name="ssl_error_untrusted" msgid="1496280318271264520">"This certificate isn\'t from a trusted authority."</string>
-    <string name="ssl_error_mismatch" msgid="3060364165934822383">"The name of the site doesn\'t match the name on the certificate."</string>
-    <string name="ssl_error_expired" msgid="1501588340716182495">"This certificate has expired."</string>
-    <string name="ssl_error_not_yet_valid" msgid="8648649030525886924">"This certificate isn\'t valid yet."</string>
-    <string name="ssl_error_date_invalid" msgid="88425990680059223">"This certificate has an invalid date."</string>
-    <string name="ssl_error_invalid" msgid="2540546515565633432">"This certificate is invalid."</string>
-    <string name="ssl_error_unknown" msgid="4405203446079465859">"Unknown certificate error."</string>
-    <string name="ssl_security_warning_title" msgid="8768539813847504404">"Security warning"</string>
-    <string name="ssl_error_view_certificate" msgid="5722652540168339333">"View certificate"</string>
-    <string name="ok" msgid="2817931639040794018">"OK"</string>
-    <string name="page_info_address" msgid="1261481517455692363">"Address:"</string>
-    <string name="page_info" msgid="4416941086705172545">"Page info"</string>
-</resources>
diff --git a/packages/CaptivePortalLogin/res/values-en-rXC/strings.xml b/packages/CaptivePortalLogin/res/values-en-rXC/strings.xml
deleted file mode 100644
index 8b3ca29..0000000
--- a/packages/CaptivePortalLogin/res/values-en-rXC/strings.xml
+++ /dev/null
@@ -1,24 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="app_name" msgid="5934709770924185752">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‏‎‎‏‎‎‏‎‏‏‏‎‎‎‏‎‏‎‎‏‏‎‎‎‏‎‏‏‏‏‏‎‏‏‏‎‎‏‏‏‏‏‎‎‏‏‏‎‏‏‎‎‎‏‎‎‏‏‎‎‎‎CaptivePortalLogin‎‏‎‎‏‎"</string>
-    <string name="action_use_network" msgid="6076184727448466030">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‏‎‏‎‎‎‏‎‏‎‎‏‎‏‏‏‏‎‎‎‏‏‏‎‏‎‎‎‏‎‎‎‎‏‏‎‏‎‎‏‏‏‎‎‎‎‎‏‏‎‎‏‎‎‏‏‎‏‏‏‎‎Use this network as is‎‏‎‎‏‎"</string>
-    <string name="action_do_not_use_network" msgid="4577366536956516683">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‏‏‏‏‏‏‎‎‎‎‏‏‎‎‎‎‏‎‎‏‎‏‎‎‏‏‏‎‏‎‎‎‎‏‎‏‎‎‎‎‎‏‏‎‏‏‎‎‏‏‎‎‏‎‏‎‎‏‎‏‏‎Do not use this network‎‏‎‎‏‎"</string>
-    <string name="action_bar_label" msgid="917235635415966620">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‎‏‏‎‎‏‎‏‏‏‎‏‎‏‎‏‎‏‏‎‎‏‏‏‏‎‎‏‏‎‏‏‎‎‎‎‎‎‏‎‎‏‏‎‎‎‏‏‎‎‎‏‏‏‎‎‏‏‏‎‎‎Sign in to network‎‏‎‎‏‎"</string>
-    <string name="action_bar_title" msgid="5645564790486983117">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‎‏‏‏‎‎‏‎‏‏‎‎‏‎‎‎‏‎‎‏‏‎‏‎‎‎‎‏‏‏‏‏‏‎‏‎‏‎‏‏‎‏‏‎‏‏‏‏‎‎‎‎‏‏‏‎‎‏‏‎‏‎Sign in to %1$s‎‏‎‎‏‎"</string>
-    <string name="ssl_error_warning" msgid="6653188881418638872">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‏‏‏‎‎‎‏‎‏‎‏‎‎‏‏‏‎‎‎‎‎‎‎‎‎‏‎‎‏‏‎‎‏‏‏‎‎‏‎‎‎‏‎‎‏‎‏‎‏‎‏‏‎‎‎‎‏‏‎‎‎‎The network you’re trying to join has security issues.‎‏‎‎‏‎"</string>
-    <string name="ssl_error_example" msgid="647898534624078900">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‎‏‎‎‎‏‏‏‏‏‏‎‏‏‏‎‎‏‏‎‎‎‏‎‎‏‎‎‎‏‏‎‏‎‏‏‎‏‏‎‎‎‎‏‏‏‎‏‎‏‏‎‎‎‎‏‏‎‏‎‎‎For example, the login page may not belong to the organization shown.‎‏‎‎‏‎"</string>
-    <string name="ssl_error_continue" msgid="6492718244923937110">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‏‏‎‏‎‎‎‎‏‏‎‏‎‏‏‎‎‎‏‎‎‏‏‎‏‏‎‎‎‎‎‎‎‎‏‏‏‎‏‏‎‎‎‏‏‏‎‎‏‎‎‎‏‎‏‎‏‎‏‏‎‎Continue anyway via browser‎‏‎‎‏‎"</string>
-    <string name="ssl_error_untrusted" msgid="1496280318271264520">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‏‏‎‏‎‎‏‏‎‎‎‎‏‏‏‏‎‏‏‎‏‏‎‎‎‎‎‏‎‏‏‎‎‏‎‏‏‎‏‏‏‏‎‏‏‏‏‎‎‏‎‏‏‏‎‎‎‎‏‎‎‎‎This certificate isn\'t from a trusted authority.‎‏‎‎‏‎"</string>
-    <string name="ssl_error_mismatch" msgid="3060364165934822383">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‎‏‎‏‎‎‏‏‏‏‎‎‎‏‎‎‏‏‎‎‎‏‏‏‏‏‏‏‎‏‎‎‏‎‎‎‏‏‏‏‎‎‎‎‏‎‎‏‏‎‎‏‏‏‏‏‎‏‏‏‏‎The name of the site doesn\'t match the name on the certificate.‎‏‎‎‏‎"</string>
-    <string name="ssl_error_expired" msgid="1501588340716182495">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‏‏‎‏‎‎‏‏‎‏‎‏‏‎‏‎‏‏‎‏‏‎‏‎‏‎‎‎‏‏‏‏‎‏‏‏‏‏‎‏‎‎‎‎‎‏‏‎‎‏‏‎‏‏‏‏‎‏‏‏‏‏‎This certificate has expired.‎‏‎‎‏‎"</string>
-    <string name="ssl_error_not_yet_valid" msgid="8648649030525886924">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‏‏‎‎‎‎‎‎‎‎‏‏‎‎‎‏‎‏‏‎‎‎‏‏‏‏‎‎‎‏‎‎‎‎‎‏‏‏‎‎‎‎‏‎‏‏‎‏‎‎‎‎‏‏‏‎‎‏‏‎‎‎This certificate isn\'t valid yet.‎‏‎‎‏‎"</string>
-    <string name="ssl_error_date_invalid" msgid="88425990680059223">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‎‎‏‏‎‎‏‏‏‎‏‎‎‎‏‎‎‏‏‎‏‏‏‏‏‎‎‎‎‏‎‏‎‎‏‏‎‏‏‎‎‏‎‏‏‎‎‏‏‏‎‏‎‏‎‏‎‏‏‏‎This certificate has an invalid date.‎‏‎‎‏‎"</string>
-    <string name="ssl_error_invalid" msgid="2540546515565633432">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‎‎‎‏‏‎‏‎‎‎‎‎‏‏‏‎‏‎‏‎‏‏‎‎‏‏‎‎‎‎‏‏‏‎‎‏‏‏‎‏‎‎‏‎‏‎‏‎‏‏‏‏‏‏‎‎‏‏‎‎‎‎This certificate is invalid.‎‏‎‎‏‎"</string>
-    <string name="ssl_error_unknown" msgid="4405203446079465859">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‏‏‏‎‏‎‎‏‎‎‎‏‎‎‏‏‎‏‏‎‏‎‎‏‏‎‎‎‏‏‏‎‎‎‏‏‎‏‏‏‎‎‏‎‎‏‎‏‎‏‎‎‏‏‎‎‎‎‎‏‏‎Unknown certificate error.‎‏‎‎‏‎"</string>
-    <string name="ssl_security_warning_title" msgid="8768539813847504404">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‏‏‎‎‏‏‎‏‏‎‎‎‎‎‎‎‏‏‏‎‎‏‎‎‎‎‎‎‎‏‏‎‎‎‎‏‏‎‏‎‎‎‎‎‎‎‎‎‏‎‏‏‎‎‎‎‏‎‏‎‎‎Security warning‎‏‎‎‏‎"</string>
-    <string name="ssl_error_view_certificate" msgid="5722652540168339333">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‎‏‏‏‏‎‏‏‎‏‎‏‎‏‏‏‏‎‎‏‎‎‎‏‎‏‎‏‎‎‏‎‏‎‏‎‏‏‎‏‏‏‎‎‎‎‏‏‏‏‏‏‏‏‎‎‎‎‏‎‏‎View certificate‎‏‎‎‏‎"</string>
-    <string name="ok" msgid="2817931639040794018">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‎‎‏‏‏‎‎‎‏‏‎‏‏‎‏‎‎‏‏‎‏‏‏‏‎‎‏‎‏‎‏‎‎‏‎‏‎‎‏‎‏‏‏‎‎‎‏‎‏‏‏‎‏‏‎‏‎‎‎‏‎‎OK‎‏‎‎‏‎"</string>
-    <string name="page_info_address" msgid="1261481517455692363">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‏‏‎‎‎‏‏‎‎‎‎‎‎‏‏‎‏‎‏‏‏‎‏‏‎‎‎‎‎‏‏‎‏‎‏‎‏‎‏‎‏‎‏‎‏‎‏‏‎‏‎‎‏‎‎‏‎‎‏‎‏‏‎Address:‎‏‎‎‏‎"</string>
-    <string name="page_info" msgid="4416941086705172545">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‏‏‏‎‏‎‏‎‎‏‏‎‎‎‎‏‎‎‎‎‎‏‎‎‎‎‏‎‎‎‎‏‏‎‎‏‎‏‏‏‎‎‎‏‏‏‏‎‎‎‎‎‎‎‏‎‎‎‎‎‏‎Page info‎‏‎‎‏‎"</string>
-</resources>
diff --git a/packages/CaptivePortalLogin/res/values-es-rUS/strings.xml b/packages/CaptivePortalLogin/res/values-es-rUS/strings.xml
deleted file mode 100644
index d7ddaa7..0000000
--- a/packages/CaptivePortalLogin/res/values-es-rUS/strings.xml
+++ /dev/null
@@ -1,24 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="app_name" msgid="5934709770924185752">"CaptivePortalLogin"</string>
-    <string name="action_use_network" msgid="6076184727448466030">"Usar esta red como está"</string>
-    <string name="action_do_not_use_network" msgid="4577366536956516683">"No usar esta red"</string>
-    <string name="action_bar_label" msgid="917235635415966620">"Acceder a la red"</string>
-    <string name="action_bar_title" msgid="5645564790486983117">"Acceder a %1$s"</string>
-    <string name="ssl_error_warning" msgid="6653188881418638872">"La red a la que intentas conectarte tiene problemas de seguridad."</string>
-    <string name="ssl_error_example" msgid="647898534624078900">"Por ejemplo, es posible que la página de acceso no pertenezca a la organización que aparece."</string>
-    <string name="ssl_error_continue" msgid="6492718244923937110">"Continuar de todos modos desde el navegador"</string>
-    <string name="ssl_error_untrusted" msgid="1496280318271264520">"Este certificado no proviene de una autoridad confiable."</string>
-    <string name="ssl_error_mismatch" msgid="3060364165934822383">"El nombre del sitio no coincide con el nombre del certificado."</string>
-    <string name="ssl_error_expired" msgid="1501588340716182495">"Este certificado venció."</string>
-    <string name="ssl_error_not_yet_valid" msgid="8648649030525886924">"Este certificado aún no es válido."</string>
-    <string name="ssl_error_date_invalid" msgid="88425990680059223">"La fecha de este certificado no es válida."</string>
-    <string name="ssl_error_invalid" msgid="2540546515565633432">"Este certificado no es válido."</string>
-    <string name="ssl_error_unknown" msgid="4405203446079465859">"Error de certificado desconocido"</string>
-    <string name="ssl_security_warning_title" msgid="8768539813847504404">"Advertencia de seguridad"</string>
-    <string name="ssl_error_view_certificate" msgid="5722652540168339333">"Ver certificado"</string>
-    <string name="ok" msgid="2817931639040794018">"Aceptar"</string>
-    <string name="page_info_address" msgid="1261481517455692363">"Dirección:"</string>
-    <string name="page_info" msgid="4416941086705172545">"Información de la página"</string>
-</resources>
diff --git a/packages/CaptivePortalLogin/res/values-es/strings.xml b/packages/CaptivePortalLogin/res/values-es/strings.xml
deleted file mode 100644
index e10380f..0000000
--- a/packages/CaptivePortalLogin/res/values-es/strings.xml
+++ /dev/null
@@ -1,24 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="app_name" msgid="5934709770924185752">"CaptivePortalLogin"</string>
-    <string name="action_use_network" msgid="6076184727448466030">"Utilizar esta red tal cual"</string>
-    <string name="action_do_not_use_network" msgid="4577366536956516683">"No utilizar esta red"</string>
-    <string name="action_bar_label" msgid="917235635415966620">"Iniciar sesión en la red"</string>
-    <string name="action_bar_title" msgid="5645564790486983117">"Inicia sesión en %1$s"</string>
-    <string name="ssl_error_warning" msgid="6653188881418638872">"La red a la que intentas unirte tiene problemas de seguridad."</string>
-    <string name="ssl_error_example" msgid="647898534624078900">"Por ejemplo, es posible que la página de inicio de sesión no pertenezca a la organización mostrada."</string>
-    <string name="ssl_error_continue" msgid="6492718244923937110">"Continuar de todos modos a través del navegador"</string>
-    <string name="ssl_error_untrusted" msgid="1496280318271264520">"Este certificado no procede de una entidad de confianza."</string>
-    <string name="ssl_error_mismatch" msgid="3060364165934822383">"El nombre del sitio web no coincide con el del certificado."</string>
-    <string name="ssl_error_expired" msgid="1501588340716182495">"Este certificado ha caducado."</string>
-    <string name="ssl_error_not_yet_valid" msgid="8648649030525886924">"Este certificado aún no es válido."</string>
-    <string name="ssl_error_date_invalid" msgid="88425990680059223">"La fecha de este certificado no es válida."</string>
-    <string name="ssl_error_invalid" msgid="2540546515565633432">"Este certificado no es válido."</string>
-    <string name="ssl_error_unknown" msgid="4405203446079465859">"Error de certificado desconocido."</string>
-    <string name="ssl_security_warning_title" msgid="8768539813847504404">"Advertencia de seguridad"</string>
-    <string name="ssl_error_view_certificate" msgid="5722652540168339333">"Ver certificado"</string>
-    <string name="ok" msgid="2817931639040794018">"Aceptar"</string>
-    <string name="page_info_address" msgid="1261481517455692363">"Dirección:"</string>
-    <string name="page_info" msgid="4416941086705172545">"Información de la página"</string>
-</resources>
diff --git a/packages/CaptivePortalLogin/res/values-et/strings.xml b/packages/CaptivePortalLogin/res/values-et/strings.xml
deleted file mode 100644
index 2894383..0000000
--- a/packages/CaptivePortalLogin/res/values-et/strings.xml
+++ /dev/null
@@ -1,24 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="app_name" msgid="5934709770924185752">"CaptivePortalLogin"</string>
-    <string name="action_use_network" msgid="6076184727448466030">"Kasuta seda võrku olemasoleval kujul"</string>
-    <string name="action_do_not_use_network" msgid="4577366536956516683">"Ära kasuta seda võrku"</string>
-    <string name="action_bar_label" msgid="917235635415966620">"Logi võrku sisse"</string>
-    <string name="action_bar_title" msgid="5645564790486983117">"Logige sisse: %1$s"</string>
-    <string name="ssl_error_warning" msgid="6653188881418638872">"Võrgul, millega üritate ühenduse luua, on turvaprobleeme."</string>
-    <string name="ssl_error_example" msgid="647898534624078900">"Näiteks ei pruugi sisselogimisleht kuuluda kuvatavale organisatsioonile."</string>
-    <string name="ssl_error_continue" msgid="6492718244923937110">"Jätka siiski brauseris"</string>
-    <string name="ssl_error_untrusted" msgid="1496280318271264520">"See sertifikaat ei pärine usaldusväärselt asutuselt."</string>
-    <string name="ssl_error_mismatch" msgid="3060364165934822383">"Saidi nimi ei vasta sertifikaadil olevale nimele."</string>
-    <string name="ssl_error_expired" msgid="1501588340716182495">"See sertifikaat on aegunud."</string>
-    <string name="ssl_error_not_yet_valid" msgid="8648649030525886924">"See sertifikaat pole veel kehtiv."</string>
-    <string name="ssl_error_date_invalid" msgid="88425990680059223">"Sellel sertifikaadil on kehtetu kuupäev."</string>
-    <string name="ssl_error_invalid" msgid="2540546515565633432">"See sertifikaat on kehtetu."</string>
-    <string name="ssl_error_unknown" msgid="4405203446079465859">"Tundmatu sertifikaadiviga."</string>
-    <string name="ssl_security_warning_title" msgid="8768539813847504404">"Turvahoiatus"</string>
-    <string name="ssl_error_view_certificate" msgid="5722652540168339333">"Kuva sertifikaat"</string>
-    <string name="ok" msgid="2817931639040794018">"OK"</string>
-    <string name="page_info_address" msgid="1261481517455692363">"Aadress:"</string>
-    <string name="page_info" msgid="4416941086705172545">"Lehe teave"</string>
-</resources>
diff --git a/packages/CaptivePortalLogin/res/values-eu/strings.xml b/packages/CaptivePortalLogin/res/values-eu/strings.xml
deleted file mode 100644
index b7233ab..0000000
--- a/packages/CaptivePortalLogin/res/values-eu/strings.xml
+++ /dev/null
@@ -1,24 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="app_name" msgid="5934709770924185752">"CaptivePortalLogin"</string>
-    <string name="action_use_network" msgid="6076184727448466030">"Erabili sare hau bere horretan"</string>
-    <string name="action_do_not_use_network" msgid="4577366536956516683">"Ez erabili sare hau"</string>
-    <string name="action_bar_label" msgid="917235635415966620">"Hasi saioa sarean"</string>
-    <string name="action_bar_title" msgid="5645564790486983117">"Hasi saioa %1$s sarean"</string>
-    <string name="ssl_error_warning" msgid="6653188881418638872">"Erabili nahi duzun sareak segurtasun-arazoak ditu."</string>
-    <string name="ssl_error_example" msgid="647898534624078900">"Adibidez, baliteke saioa hasteko orria adierazitako erakundearena ez izatea."</string>
-    <string name="ssl_error_continue" msgid="6492718244923937110">"Jarraitu arakatzailearen bidez, halere"</string>
-    <string name="ssl_error_untrusted" msgid="1496280318271264520">"Ziurtagiria ez da autoritate fidagarri batena."</string>
-    <string name="ssl_error_mismatch" msgid="3060364165934822383">"Webgunearen izena ez dator bat ziurtagirian agertzen den izenarekin."</string>
-    <string name="ssl_error_expired" msgid="1501588340716182495">"Ziurtagiria iraungi da."</string>
-    <string name="ssl_error_not_yet_valid" msgid="8648649030525886924">"Ziurtagiriak ez du balio oraindik."</string>
-    <string name="ssl_error_date_invalid" msgid="88425990680059223">"Ziurtagiriaren datak ez du balio."</string>
-    <string name="ssl_error_invalid" msgid="2540546515565633432">"Ziurtagiriak ez du balio."</string>
-    <string name="ssl_error_unknown" msgid="4405203446079465859">"Errore ezezagun bat gertatu da ziurtagiriarekin."</string>
-    <string name="ssl_security_warning_title" msgid="8768539813847504404">"Segurtasun-abisua"</string>
-    <string name="ssl_error_view_certificate" msgid="5722652540168339333">"Ikusi ziurtagiria"</string>
-    <string name="ok" msgid="2817931639040794018">"Ados"</string>
-    <string name="page_info_address" msgid="1261481517455692363">"Helbidea:"</string>
-    <string name="page_info" msgid="4416941086705172545">"Orriari buruzko informazioa"</string>
-</resources>
diff --git a/packages/CaptivePortalLogin/res/values-fa/strings.xml b/packages/CaptivePortalLogin/res/values-fa/strings.xml
deleted file mode 100644
index db9f7e8..0000000
--- a/packages/CaptivePortalLogin/res/values-fa/strings.xml
+++ /dev/null
@@ -1,24 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="app_name" msgid="5934709770924185752">"CaptivePortalLogin"</string>
-    <string name="action_use_network" msgid="6076184727448466030">"از این شبکه همانطور که هست استفاده شود"</string>
-    <string name="action_do_not_use_network" msgid="4577366536956516683">"از این شبکه استفاده نشود"</string>
-    <string name="action_bar_label" msgid="917235635415966620">"ورود به سیستم شبکه"</string>
-    <string name="action_bar_title" msgid="5645564790486983117">"‏ورود به سیستم %1$s"</string>
-    <string name="ssl_error_warning" msgid="6653188881418638872">"شبکه‌ای که می‌خواهید به آن بپیوندید مشکلات امنیتی دارد."</string>
-    <string name="ssl_error_example" msgid="647898534624078900">"به عنوان مثال، صفحه ورود به سیستم ممکن است متعلق به سازمان نشان داده شده نباشد."</string>
-    <string name="ssl_error_continue" msgid="6492718244923937110">"در هر صورت از طریق مرورگر ادامه یابد"</string>
-    <string name="ssl_error_untrusted" msgid="1496280318271264520">"این گواهی از یک منبع مورد‌اطمینان صادر نشده است."</string>
-    <string name="ssl_error_mismatch" msgid="3060364165934822383">"نام سایت با نام موجود در گواهی مطابقت ندارد."</string>
-    <string name="ssl_error_expired" msgid="1501588340716182495">"این گواهی منقضی شده است."</string>
-    <string name="ssl_error_not_yet_valid" msgid="8648649030525886924">"این گواهی هنوز معتبر نیست."</string>
-    <string name="ssl_error_date_invalid" msgid="88425990680059223">"تاریخ این گواهی نامعتبر است."</string>
-    <string name="ssl_error_invalid" msgid="2540546515565633432">"این گواهی نامعتبر است."</string>
-    <string name="ssl_error_unknown" msgid="4405203446079465859">"خطای ناشناخته در گواهی."</string>
-    <string name="ssl_security_warning_title" msgid="8768539813847504404">"اخطار امنیتی"</string>
-    <string name="ssl_error_view_certificate" msgid="5722652540168339333">"مشاهده گواهی"</string>
-    <string name="ok" msgid="2817931639040794018">"تأیید"</string>
-    <string name="page_info_address" msgid="1261481517455692363">"نشانی:"</string>
-    <string name="page_info" msgid="4416941086705172545">"اطلاعات صفحه"</string>
-</resources>
diff --git a/packages/CaptivePortalLogin/res/values-fi/strings.xml b/packages/CaptivePortalLogin/res/values-fi/strings.xml
deleted file mode 100644
index 1d7fcb0..0000000
--- a/packages/CaptivePortalLogin/res/values-fi/strings.xml
+++ /dev/null
@@ -1,24 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="app_name" msgid="5934709770924185752">"CaptivePortalLogin"</string>
-    <string name="action_use_network" msgid="6076184727448466030">"Käytä tätä verkkoa sellaisenaan"</string>
-    <string name="action_do_not_use_network" msgid="4577366536956516683">"Älä käytä tätä verkkoa"</string>
-    <string name="action_bar_label" msgid="917235635415966620">"Kirjaudu verkkoon"</string>
-    <string name="action_bar_title" msgid="5645564790486983117">"Kirjaudu sisään kohteeseen %1$s"</string>
-    <string name="ssl_error_warning" msgid="6653188881418638872">"Verkossa, johon yrität muodostaa yhteyttä, on turvallisuusongelmia."</string>
-    <string name="ssl_error_example" msgid="647898534624078900">"Kirjautumissivu ei välttämättä kuulu näytetylle organisaatiolle."</string>
-    <string name="ssl_error_continue" msgid="6492718244923937110">"Jatka silti selaimen kautta."</string>
-    <string name="ssl_error_untrusted" msgid="1496280318271264520">"Varmenteen myöntäjä ei ole luotettava taho."</string>
-    <string name="ssl_error_mismatch" msgid="3060364165934822383">"Sivuston nimi ei vastaa varmenteessa olevaa nimeä."</string>
-    <string name="ssl_error_expired" msgid="1501588340716182495">"Varmenne ei ole enää voimassa."</string>
-    <string name="ssl_error_not_yet_valid" msgid="8648649030525886924">"Varmenne ei ole vielä voimassa."</string>
-    <string name="ssl_error_date_invalid" msgid="88425990680059223">"Varmenteen päiväys ei kelpaa."</string>
-    <string name="ssl_error_invalid" msgid="2540546515565633432">"Varmenne on virheellinen."</string>
-    <string name="ssl_error_unknown" msgid="4405203446079465859">"Tuntematon varmennevirhe."</string>
-    <string name="ssl_security_warning_title" msgid="8768539813847504404">"Suojausvaroitus"</string>
-    <string name="ssl_error_view_certificate" msgid="5722652540168339333">"Näytä varmenne"</string>
-    <string name="ok" msgid="2817931639040794018">"OK"</string>
-    <string name="page_info_address" msgid="1261481517455692363">"Osoite:"</string>
-    <string name="page_info" msgid="4416941086705172545">"Sivun tiedot"</string>
-</resources>
diff --git a/packages/CaptivePortalLogin/res/values-fr-rCA/strings.xml b/packages/CaptivePortalLogin/res/values-fr-rCA/strings.xml
deleted file mode 100644
index 979e236..0000000
--- a/packages/CaptivePortalLogin/res/values-fr-rCA/strings.xml
+++ /dev/null
@@ -1,24 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="app_name" msgid="5934709770924185752">"CaptivePortalLogin"</string>
-    <string name="action_use_network" msgid="6076184727448466030">"Utiliser ce réseau tel quel"</string>
-    <string name="action_do_not_use_network" msgid="4577366536956516683">"Ne pas utiliser ce réseau"</string>
-    <string name="action_bar_label" msgid="917235635415966620">"Connectez-vous au réseau"</string>
-    <string name="action_bar_title" msgid="5645564790486983117">"Connexion à %1$s"</string>
-    <string name="ssl_error_warning" msgid="6653188881418638872">"Le réseau que vous essayez de rejoindre présente des problèmes de sécurité."</string>
-    <string name="ssl_error_example" msgid="647898534624078900">"Par exemple, la page de connexion pourrait ne pas appartenir à l\'organisation représentée."</string>
-    <string name="ssl_error_continue" msgid="6492718244923937110">"Continuer quand même dans un navigateur"</string>
-    <string name="ssl_error_untrusted" msgid="1496280318271264520">"Ce certificat ne provient pas d\'une autorité de confiance."</string>
-    <string name="ssl_error_mismatch" msgid="3060364165934822383">"Le nom du site ne correspond pas au nom figurant sur le certificat."</string>
-    <string name="ssl_error_expired" msgid="1501588340716182495">"Ce certificat a expiré."</string>
-    <string name="ssl_error_not_yet_valid" msgid="8648649030525886924">"Ce certificat n\'est pas encore valide."</string>
-    <string name="ssl_error_date_invalid" msgid="88425990680059223">"Ce certificat contient une date non valide."</string>
-    <string name="ssl_error_invalid" msgid="2540546515565633432">"Ce certificat n\'est pas valide."</string>
-    <string name="ssl_error_unknown" msgid="4405203446079465859">"Erreur de certificat inconnue."</string>
-    <string name="ssl_security_warning_title" msgid="8768539813847504404">"Avertissement de sécurité"</string>
-    <string name="ssl_error_view_certificate" msgid="5722652540168339333">"Afficher le certificat"</string>
-    <string name="ok" msgid="2817931639040794018">"OK"</string>
-    <string name="page_info_address" msgid="1261481517455692363">"Adresse :"</string>
-    <string name="page_info" msgid="4416941086705172545">"Renseignements sur la page"</string>
-</resources>
diff --git a/packages/CaptivePortalLogin/res/values-fr/strings.xml b/packages/CaptivePortalLogin/res/values-fr/strings.xml
deleted file mode 100644
index e348a4d..0000000
--- a/packages/CaptivePortalLogin/res/values-fr/strings.xml
+++ /dev/null
@@ -1,24 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="app_name" msgid="5934709770924185752">"CaptivePortalLogin"</string>
-    <string name="action_use_network" msgid="6076184727448466030">"Utiliser ce réseau tel quel"</string>
-    <string name="action_do_not_use_network" msgid="4577366536956516683">"Ne pas utiliser ce réseau"</string>
-    <string name="action_bar_label" msgid="917235635415966620">"Se connecter au réseau"</string>
-    <string name="action_bar_title" msgid="5645564790486983117">"Se connecter à %1$s"</string>
-    <string name="ssl_error_warning" msgid="6653188881418638872">"Le réseau que vous essayez de rejoindre présente des problèmes de sécurité."</string>
-    <string name="ssl_error_example" msgid="647898534624078900">"Par exemple, la page de connexion peut ne pas appartenir à l\'organisation représentée."</string>
-    <string name="ssl_error_continue" msgid="6492718244923937110">"Continuer quand même dans le navigateur"</string>
-    <string name="ssl_error_untrusted" msgid="1496280318271264520">"Ce certificat provient d\'une autorité non approuvée."</string>
-    <string name="ssl_error_mismatch" msgid="3060364165934822383">"Le nom du site ne correspond pas au nom indiqué dans le certificat."</string>
-    <string name="ssl_error_expired" msgid="1501588340716182495">"Ce certificat a expiré."</string>
-    <string name="ssl_error_not_yet_valid" msgid="8648649030525886924">"Ce certificat n\'est pas encore valide."</string>
-    <string name="ssl_error_date_invalid" msgid="88425990680059223">"La date de ce certificat n\'est pas valide."</string>
-    <string name="ssl_error_invalid" msgid="2540546515565633432">"Ce certificat n\'est pas valide."</string>
-    <string name="ssl_error_unknown" msgid="4405203446079465859">"Erreur de certificat inconnue."</string>
-    <string name="ssl_security_warning_title" msgid="8768539813847504404">"Avertissement de sécurité"</string>
-    <string name="ssl_error_view_certificate" msgid="5722652540168339333">"Afficher le certificat"</string>
-    <string name="ok" msgid="2817931639040794018">"OK"</string>
-    <string name="page_info_address" msgid="1261481517455692363">"Adresse :"</string>
-    <string name="page_info" msgid="4416941086705172545">"Informations sur la page"</string>
-</resources>
diff --git a/packages/CaptivePortalLogin/res/values-gl/strings.xml b/packages/CaptivePortalLogin/res/values-gl/strings.xml
deleted file mode 100644
index 6419516..0000000
--- a/packages/CaptivePortalLogin/res/values-gl/strings.xml
+++ /dev/null
@@ -1,24 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="app_name" msgid="5934709770924185752">"CaptivePortalLogin"</string>
-    <string name="action_use_network" msgid="6076184727448466030">"Utilizar esta rede tal como está"</string>
-    <string name="action_do_not_use_network" msgid="4577366536956516683">"Non utilizar esta rede"</string>
-    <string name="action_bar_label" msgid="917235635415966620">"Inicia sesión na rede"</string>
-    <string name="action_bar_title" msgid="5645564790486983117">"Iniciar sesión en %1$s"</string>
-    <string name="ssl_error_warning" msgid="6653188881418638872">"A rede á que tentas unirte ten problemas de seguranza."</string>
-    <string name="ssl_error_example" msgid="647898534624078900">"Por exemplo, é posible que a páxina de inicio de sesión non pertenza á organización que se mostra."</string>
-    <string name="ssl_error_continue" msgid="6492718244923937110">"Continuar igualmente co navegador"</string>
-    <string name="ssl_error_untrusted" msgid="1496280318271264520">"Este certificado non procede dunha autoridade de confianza."</string>
-    <string name="ssl_error_mismatch" msgid="3060364165934822383">"O nome do sitio non coincide co nome que aparece no certificado."</string>
-    <string name="ssl_error_expired" msgid="1501588340716182495">"Este certificado caducou."</string>
-    <string name="ssl_error_not_yet_valid" msgid="8648649030525886924">"Este certificado aínda non é válido."</string>
-    <string name="ssl_error_date_invalid" msgid="88425990680059223">"Este certificado ten unha data non válida."</string>
-    <string name="ssl_error_invalid" msgid="2540546515565633432">"Este certificado non é válido."</string>
-    <string name="ssl_error_unknown" msgid="4405203446079465859">"Produciuse un erro descoñecido relacionado co certificado."</string>
-    <string name="ssl_security_warning_title" msgid="8768539813847504404">"Advertencia de seguranza"</string>
-    <string name="ssl_error_view_certificate" msgid="5722652540168339333">"Ver certificado"</string>
-    <string name="ok" msgid="2817931639040794018">"Aceptar"</string>
-    <string name="page_info_address" msgid="1261481517455692363">"Enderezo:"</string>
-    <string name="page_info" msgid="4416941086705172545">"Información da páxina"</string>
-</resources>
diff --git a/packages/CaptivePortalLogin/res/values-gu/strings.xml b/packages/CaptivePortalLogin/res/values-gu/strings.xml
deleted file mode 100644
index aef043f..0000000
--- a/packages/CaptivePortalLogin/res/values-gu/strings.xml
+++ /dev/null
@@ -1,24 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="app_name" msgid="5934709770924185752">"CaptivePortalLogin"</string>
-    <string name="action_use_network" msgid="6076184727448466030">"આ નેટવર્કનો જેમનો તેમ ઉપયોગ કરો"</string>
-    <string name="action_do_not_use_network" msgid="4577366536956516683">"આ નેટવર્કનો ઉપયોગ કરશો નહીં"</string>
-    <string name="action_bar_label" msgid="917235635415966620">"નેટવર્ક પર સાઇન ઇન કરો"</string>
-    <string name="action_bar_title" msgid="5645564790486983117">"%1$sમાં સઇન ઇન કરો"</string>
-    <string name="ssl_error_warning" msgid="6653188881418638872">"તમે જોડાવાનો પ્રયાસ કરી રહ્યાં છો તે નેટવર્કમાં સુરક્ષા સમસ્યાઓ છે."</string>
-    <string name="ssl_error_example" msgid="647898534624078900">"ઉદાહરણ તરીકે, લોગિન પૃષ્ઠ દર્શાવેલ સંસ્થાનું હોઈ શકતું નથી."</string>
-    <string name="ssl_error_continue" msgid="6492718244923937110">"બ્રાઉઝર મારફતે કોઈપણ રીતે ચાલુ રાખો"</string>
-    <string name="ssl_error_untrusted" msgid="1496280318271264520">"આ પ્રમાણપત્ર વિશ્વસનીય સત્તાધિકારી તરફથી મળ્યું નથી."</string>
-    <string name="ssl_error_mismatch" msgid="3060364165934822383">"સાઇટનું નામ એ પ્રમાણપત્ર પર રહેલાં નામ સાથે મેળ ખાતું નથી."</string>
-    <string name="ssl_error_expired" msgid="1501588340716182495">"આ પ્રમાણપત્રની સમયસીમા સમાપ્ત થઈ ગઈ છે."</string>
-    <string name="ssl_error_not_yet_valid" msgid="8648649030525886924">"આ પ્રમાણપત્ર હજુ માન્ય નથી."</string>
-    <string name="ssl_error_date_invalid" msgid="88425990680059223">"આ પ્રમાણપત્રમાં અમાન્ય તારીખ છે."</string>
-    <string name="ssl_error_invalid" msgid="2540546515565633432">"આ પ્રમાણપત્ર અમાન્ય છે."</string>
-    <string name="ssl_error_unknown" msgid="4405203446079465859">"પ્રમાણપત્રમાં અજાણી ભૂલ."</string>
-    <string name="ssl_security_warning_title" msgid="8768539813847504404">"સુરક્ષા વિશે ચેતવણી"</string>
-    <string name="ssl_error_view_certificate" msgid="5722652540168339333">"પ્રમાણપત્ર જુઓ"</string>
-    <string name="ok" msgid="2817931639040794018">"ઓકે"</string>
-    <string name="page_info_address" msgid="1261481517455692363">"સરનામું:"</string>
-    <string name="page_info" msgid="4416941086705172545">"પેજ વિશે માહિતી"</string>
-</resources>
diff --git a/packages/CaptivePortalLogin/res/values-hi/strings.xml b/packages/CaptivePortalLogin/res/values-hi/strings.xml
deleted file mode 100644
index b8ae82a..0000000
--- a/packages/CaptivePortalLogin/res/values-hi/strings.xml
+++ /dev/null
@@ -1,24 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="app_name" msgid="5934709770924185752">"CaptivePortalLogin"</string>
-    <string name="action_use_network" msgid="6076184727448466030">"इस नेटवर्क का उपयोग जैसा है वैसा ही करें"</string>
-    <string name="action_do_not_use_network" msgid="4577366536956516683">"इस नेटवर्क का उपयोग न करें"</string>
-    <string name="action_bar_label" msgid="917235635415966620">"नेटवर्क में साइन इन करें"</string>
-    <string name="action_bar_title" msgid="5645564790486983117">"%1$s में साइन इन करें"</string>
-    <string name="ssl_error_warning" msgid="6653188881418638872">"आप जिस नेटवर्क में शामिल होने का प्रयास कर रहे हैं उसमें सुरक्षा समस्‍याएं हैं."</string>
-    <string name="ssl_error_example" msgid="647898534624078900">"उदाहरण के लिए, हो सकता है कि लॉगिन पृष्‍ठ दिखाए गए संगठन से संबद्ध ना हो."</string>
-    <string name="ssl_error_continue" msgid="6492718244923937110">"ब्राउज़र के द्वारा फिर जारी रखें"</string>
-    <string name="ssl_error_untrusted" msgid="1496280318271264520">"यह प्रमाणपत्र किसी भरोसेमंद अधिकारी का नहीं है."</string>
-    <string name="ssl_error_mismatch" msgid="3060364165934822383">"साइट के नाम का मिलान प्रमाणपत्र में दिए नाम से नहीं हो रहा है."</string>
-    <string name="ssl_error_expired" msgid="1501588340716182495">"इस प्रमाणपत्र की समय-सीमा खत्म हो चुकी है."</string>
-    <string name="ssl_error_not_yet_valid" msgid="8648649030525886924">"यह प्रमाणपत्र अभी तक मान्य नहीं है."</string>
-    <string name="ssl_error_date_invalid" msgid="88425990680059223">"इस प्रमाणपत्र की तारीख गलत है."</string>
-    <string name="ssl_error_invalid" msgid="2540546515565633432">"यह प्रमाणपत्र अमान्य है."</string>
-    <string name="ssl_error_unknown" msgid="4405203446079465859">"प्रमाणपत्र में अनजान गड़बड़ी."</string>
-    <string name="ssl_security_warning_title" msgid="8768539813847504404">"सुरक्षा चेतावनी"</string>
-    <string name="ssl_error_view_certificate" msgid="5722652540168339333">"प्रमाणपत्र देखें"</string>
-    <string name="ok" msgid="2817931639040794018">"ठीक है"</string>
-    <string name="page_info_address" msgid="1261481517455692363">"पता:"</string>
-    <string name="page_info" msgid="4416941086705172545">"पेज की जानकारी"</string>
-</resources>
diff --git a/packages/CaptivePortalLogin/res/values-hr/strings.xml b/packages/CaptivePortalLogin/res/values-hr/strings.xml
deleted file mode 100644
index f6adcdb..0000000
--- a/packages/CaptivePortalLogin/res/values-hr/strings.xml
+++ /dev/null
@@ -1,24 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="app_name" msgid="5934709770924185752">"CaptivePortalLogin"</string>
-    <string name="action_use_network" msgid="6076184727448466030">"Upotrebljavaj ovu mrežu u zatečenom stanju"</string>
-    <string name="action_do_not_use_network" msgid="4577366536956516683">"Ne upotrebljavaj ovu mrežu"</string>
-    <string name="action_bar_label" msgid="917235635415966620">"Prijava na mrežu"</string>
-    <string name="action_bar_title" msgid="5645564790486983117">"Prijavite se na %1$s"</string>
-    <string name="ssl_error_warning" msgid="6653188881418638872">"Mreža kojoj se pokušavate pridružiti ima sigurnosne poteškoće."</string>
-    <string name="ssl_error_example" msgid="647898534624078900">"Na primjer, stranica za prijavu možda ne pripada prikazanoj organizaciji."</string>
-    <string name="ssl_error_continue" msgid="6492718244923937110">"Ipak nastavi putem preglednika"</string>
-    <string name="ssl_error_untrusted" msgid="1496280318271264520">"Ovaj certifikat ne potječe iz pouzdanog izvora."</string>
-    <string name="ssl_error_mismatch" msgid="3060364165934822383">"Naziv web-lokacije ne podudara se s nazivom na certifikatu."</string>
-    <string name="ssl_error_expired" msgid="1501588340716182495">"Ovaj je certifikat istekao."</string>
-    <string name="ssl_error_not_yet_valid" msgid="8648649030525886924">"Ovaj certifikat još nije važeći."</string>
-    <string name="ssl_error_date_invalid" msgid="88425990680059223">"Ovaj certifikat ima nevažeći datum."</string>
-    <string name="ssl_error_invalid" msgid="2540546515565633432">"Ovaj certifikat nije važeći."</string>
-    <string name="ssl_error_unknown" msgid="4405203446079465859">"Nepoznata pogreška certifikata."</string>
-    <string name="ssl_security_warning_title" msgid="8768539813847504404">"Sigurnosno upozorenje"</string>
-    <string name="ssl_error_view_certificate" msgid="5722652540168339333">"Pregledajte certifikat"</string>
-    <string name="ok" msgid="2817931639040794018">"U redu"</string>
-    <string name="page_info_address" msgid="1261481517455692363">"Adresa:"</string>
-    <string name="page_info" msgid="4416941086705172545">"Informacije o stranici"</string>
-</resources>
diff --git a/packages/CaptivePortalLogin/res/values-hu/strings.xml b/packages/CaptivePortalLogin/res/values-hu/strings.xml
deleted file mode 100644
index ab289d1..0000000
--- a/packages/CaptivePortalLogin/res/values-hu/strings.xml
+++ /dev/null
@@ -1,24 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="app_name" msgid="5934709770924185752">"CaptivePortalLogin"</string>
-    <string name="action_use_network" msgid="6076184727448466030">"Hálózat használata jelen állapotában"</string>
-    <string name="action_do_not_use_network" msgid="4577366536956516683">"Ne használja ezt a hálózatot"</string>
-    <string name="action_bar_label" msgid="917235635415966620">"Bejelentkezés a hálózatba"</string>
-    <string name="action_bar_title" msgid="5645564790486983117">"Bejelentkezés a következőbe: %1$s"</string>
-    <string name="ssl_error_warning" msgid="6653188881418638872">"Biztonsági problémák vannak azzal a hálózattal, amelyhez csatlakozni szeretne."</string>
-    <string name="ssl_error_example" msgid="647898534624078900">"Például lehet, hogy a bejelentkezési oldal nem a megjelenített szervezethez tartozik."</string>
-    <string name="ssl_error_continue" msgid="6492718244923937110">"Folytatás ennek ellenére böngészőn keresztül"</string>
-    <string name="ssl_error_untrusted" msgid="1496280318271264520">"Ez a tanúsítvány nem hiteles tanúsítványkibocsátótól származik."</string>
-    <string name="ssl_error_mismatch" msgid="3060364165934822383">"A webhely neve nem egyezik a tanúsítványon lévő névvel."</string>
-    <string name="ssl_error_expired" msgid="1501588340716182495">"A tanúsítvány lejárt."</string>
-    <string name="ssl_error_not_yet_valid" msgid="8648649030525886924">"A tanúsítvány még nem érvényes."</string>
-    <string name="ssl_error_date_invalid" msgid="88425990680059223">"A tanúsítvány dátuma érvénytelen."</string>
-    <string name="ssl_error_invalid" msgid="2540546515565633432">"Ez a tanúsítvány érvénytelen."</string>
-    <string name="ssl_error_unknown" msgid="4405203446079465859">"Ismeretlen tanúsítványhiba."</string>
-    <string name="ssl_security_warning_title" msgid="8768539813847504404">"Biztonsági figyelmeztetés"</string>
-    <string name="ssl_error_view_certificate" msgid="5722652540168339333">"Tanúsítvány megtekintése"</string>
-    <string name="ok" msgid="2817931639040794018">"OK"</string>
-    <string name="page_info_address" msgid="1261481517455692363">"Cím:"</string>
-    <string name="page_info" msgid="4416941086705172545">"Oldaladatok"</string>
-</resources>
diff --git a/packages/CaptivePortalLogin/res/values-hy/strings.xml b/packages/CaptivePortalLogin/res/values-hy/strings.xml
deleted file mode 100644
index d859d90..0000000
--- a/packages/CaptivePortalLogin/res/values-hy/strings.xml
+++ /dev/null
@@ -1,24 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="app_name" msgid="5934709770924185752">"CaptivePortalLogin"</string>
-    <string name="action_use_network" msgid="6076184727448466030">"Օգտագործել այս ցանցն ինչպես կա"</string>
-    <string name="action_do_not_use_network" msgid="4577366536956516683">"Չօգտագործել այս ցանցը"</string>
-    <string name="action_bar_label" msgid="917235635415966620">"Մուտք գործել ցանց"</string>
-    <string name="action_bar_title" msgid="5645564790486983117">"Մուտք գործել %1$s"</string>
-    <string name="ssl_error_warning" msgid="6653188881418638872">"Ցանցը, որին փորձում եք միանալ, անվտանգության խնդիրներ ունի:"</string>
-    <string name="ssl_error_example" msgid="647898534624078900">"Օրինակ՝ մուտքի էջը կարող է ցուցադրված կազմակերպության էջը չլինել:"</string>
-    <string name="ssl_error_continue" msgid="6492718244923937110">"Շարունակել այնուամենայնիվ դիտարկիչի միջոցով"</string>
-    <string name="ssl_error_untrusted" msgid="1496280318271264520">"Հավաստագրի աղբյուրը վստահելի չէ:"</string>
-    <string name="ssl_error_mismatch" msgid="3060364165934822383">"Կայքի անունը չի համապատասխանում հավաստագրում նշված անվանը:"</string>
-    <string name="ssl_error_expired" msgid="1501588340716182495">"Հավաստագրի ժամկետը լրացել է:"</string>
-    <string name="ssl_error_not_yet_valid" msgid="8648649030525886924">"Հավաստագիրը դեռ վավեր չէ:"</string>
-    <string name="ssl_error_date_invalid" msgid="88425990680059223">"Հավաստագրի ամսաթիվն անվավեր է:"</string>
-    <string name="ssl_error_invalid" msgid="2540546515565633432">"Հավաստագիրն անվավեր է:"</string>
-    <string name="ssl_error_unknown" msgid="4405203446079465859">"Հավաստագրի հետ կապված անհայտ սխալ առաջացավ:"</string>
-    <string name="ssl_security_warning_title" msgid="8768539813847504404">"Զգուշացում"</string>
-    <string name="ssl_error_view_certificate" msgid="5722652540168339333">"Դիտել հավաստագիրը"</string>
-    <string name="ok" msgid="2817931639040794018">"Եղավ"</string>
-    <string name="page_info_address" msgid="1261481517455692363">"Հասցե՝"</string>
-    <string name="page_info" msgid="4416941086705172545">"Էջի մասին"</string>
-</resources>
diff --git a/packages/CaptivePortalLogin/res/values-in/strings.xml b/packages/CaptivePortalLogin/res/values-in/strings.xml
deleted file mode 100644
index 7036318..0000000
--- a/packages/CaptivePortalLogin/res/values-in/strings.xml
+++ /dev/null
@@ -1,24 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="app_name" msgid="5934709770924185752">"CaptivePortalLogin"</string>
-    <string name="action_use_network" msgid="6076184727448466030">"Gunakan jaringan ini sebagaimana adanya"</string>
-    <string name="action_do_not_use_network" msgid="4577366536956516683">"Jangan gunakan jaringan ini"</string>
-    <string name="action_bar_label" msgid="917235635415966620">"Login ke jaringan"</string>
-    <string name="action_bar_title" msgid="5645564790486983117">"Login ke %1$s"</string>
-    <string name="ssl_error_warning" msgid="6653188881418638872">"Jaringan yang ingin Anda masuki mengalami masalah keamanan."</string>
-    <string name="ssl_error_example" msgid="647898534624078900">"Misalnya, halaman masuk mungkin bukan milik organisasi yang ditampilkan."</string>
-    <string name="ssl_error_continue" msgid="6492718244923937110">"Tetap lanjutkan melalui browser"</string>
-    <string name="ssl_error_untrusted" msgid="1496280318271264520">"Sertifikat ini tidak berasal dari otoritas tepercaya."</string>
-    <string name="ssl_error_mismatch" msgid="3060364165934822383">"Nama situs tidak cocok dengan nama pada sertifikat."</string>
-    <string name="ssl_error_expired" msgid="1501588340716182495">"Masa berlaku sertifikat ini telah berakhir."</string>
-    <string name="ssl_error_not_yet_valid" msgid="8648649030525886924">"Sertifikat ini belum valid."</string>
-    <string name="ssl_error_date_invalid" msgid="88425990680059223">"Tanggal sertifikat ini tidak valid."</string>
-    <string name="ssl_error_invalid" msgid="2540546515565633432">"Sertifikat ini tidak valid."</string>
-    <string name="ssl_error_unknown" msgid="4405203446079465859">"Error sertifikat tak dikenal."</string>
-    <string name="ssl_security_warning_title" msgid="8768539813847504404">"Peringatan keamanan"</string>
-    <string name="ssl_error_view_certificate" msgid="5722652540168339333">"Lihat sertifikat"</string>
-    <string name="ok" msgid="2817931639040794018">"Oke"</string>
-    <string name="page_info_address" msgid="1261481517455692363">"Alamat:"</string>
-    <string name="page_info" msgid="4416941086705172545">"Info halaman"</string>
-</resources>
diff --git a/packages/CaptivePortalLogin/res/values-is/strings.xml b/packages/CaptivePortalLogin/res/values-is/strings.xml
deleted file mode 100644
index 7c2a5e4..0000000
--- a/packages/CaptivePortalLogin/res/values-is/strings.xml
+++ /dev/null
@@ -1,24 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="app_name" msgid="5934709770924185752">"CaptivePortalLogin"</string>
-    <string name="action_use_network" msgid="6076184727448466030">"Nota þetta net óbreytt"</string>
-    <string name="action_do_not_use_network" msgid="4577366536956516683">"Ekki nota þetta net"</string>
-    <string name="action_bar_label" msgid="917235635415966620">"Skrá inn á net"</string>
-    <string name="action_bar_title" msgid="5645564790486983117">"Skrá inn á %1$s"</string>
-    <string name="ssl_error_warning" msgid="6653188881418638872">"Öryggisvandamál eru á netinu sem þú ert að reyna að tengjast."</string>
-    <string name="ssl_error_example" msgid="647898534624078900">"Til dæmis getur verið að innskráningarsíðan tilheyri ekki fyrirtækinu sem birtist."</string>
-    <string name="ssl_error_continue" msgid="6492718244923937110">"Halda samt áfram í vafra"</string>
-    <string name="ssl_error_untrusted" msgid="1496280318271264520">"Þetta vottorð er ekki frá traustum aðila."</string>
-    <string name="ssl_error_mismatch" msgid="3060364165934822383">"Nafnið á síðunni passar ekki við nafnið á vottorðinu."</string>
-    <string name="ssl_error_expired" msgid="1501588340716182495">"Þetta vottorð er útrunnið."</string>
-    <string name="ssl_error_not_yet_valid" msgid="8648649030525886924">"Þetta vottorð hefur ekki enn tekið gildi."</string>
-    <string name="ssl_error_date_invalid" msgid="88425990680059223">"Þetta vottorð er með ógilda dagsetningu."</string>
-    <string name="ssl_error_invalid" msgid="2540546515565633432">"Þetta vottorð er ógilt."</string>
-    <string name="ssl_error_unknown" msgid="4405203446079465859">"Óþekkt vottorðsvilla."</string>
-    <string name="ssl_security_warning_title" msgid="8768539813847504404">"Öryggisviðvörun"</string>
-    <string name="ssl_error_view_certificate" msgid="5722652540168339333">"Skoða vottorð"</string>
-    <string name="ok" msgid="2817931639040794018">"Í lagi"</string>
-    <string name="page_info_address" msgid="1261481517455692363">"Netfang:"</string>
-    <string name="page_info" msgid="4416941086705172545">"Upplýsingar um síðu"</string>
-</resources>
diff --git a/packages/CaptivePortalLogin/res/values-it/strings.xml b/packages/CaptivePortalLogin/res/values-it/strings.xml
deleted file mode 100644
index 3896cb4..0000000
--- a/packages/CaptivePortalLogin/res/values-it/strings.xml
+++ /dev/null
@@ -1,24 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="app_name" msgid="5934709770924185752">"CaptivePortalLogin"</string>
-    <string name="action_use_network" msgid="6076184727448466030">"Utilizza questa rete così com\'è"</string>
-    <string name="action_do_not_use_network" msgid="4577366536956516683">"Non utilizzare questa rete"</string>
-    <string name="action_bar_label" msgid="917235635415966620">"Accedi alla rete"</string>
-    <string name="action_bar_title" msgid="5645564790486983117">"Accedi a %1$s"</string>
-    <string name="ssl_error_warning" msgid="6653188881418638872">"La rete a cui stai tentando di accedere presenta problemi di sicurezza."</string>
-    <string name="ssl_error_example" msgid="647898534624078900">"Ad esempio, la pagina di accesso potrebbe non appartenere all\'organizzazione indicata."</string>
-    <string name="ssl_error_continue" msgid="6492718244923937110">"Continua comunque dal browser"</string>
-    <string name="ssl_error_untrusted" msgid="1496280318271264520">"Questo certificato non proviene da un\'autorità attendibile."</string>
-    <string name="ssl_error_mismatch" msgid="3060364165934822383">"Il nome del sito non corrisponde al nome nel certificato."</string>
-    <string name="ssl_error_expired" msgid="1501588340716182495">"Il certificato è scaduto."</string>
-    <string name="ssl_error_not_yet_valid" msgid="8648649030525886924">"Questo certificato non è ancora valido."</string>
-    <string name="ssl_error_date_invalid" msgid="88425990680059223">"Questo certificato presenta una data non valida."</string>
-    <string name="ssl_error_invalid" msgid="2540546515565633432">"Questo certificato non è valido."</string>
-    <string name="ssl_error_unknown" msgid="4405203446079465859">"Errore certificato sconosciuto."</string>
-    <string name="ssl_security_warning_title" msgid="8768539813847504404">"Avviso di sicurezza"</string>
-    <string name="ssl_error_view_certificate" msgid="5722652540168339333">"Visualizza certificato"</string>
-    <string name="ok" msgid="2817931639040794018">"OK"</string>
-    <string name="page_info_address" msgid="1261481517455692363">"Indirizzo:"</string>
-    <string name="page_info" msgid="4416941086705172545">"Informazioni sulla pagina"</string>
-</resources>
diff --git a/packages/CaptivePortalLogin/res/values-iw/strings.xml b/packages/CaptivePortalLogin/res/values-iw/strings.xml
deleted file mode 100644
index 4ce98ee..0000000
--- a/packages/CaptivePortalLogin/res/values-iw/strings.xml
+++ /dev/null
@@ -1,24 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="app_name" msgid="5934709770924185752">"CaptivePortalLogin"</string>
-    <string name="action_use_network" msgid="6076184727448466030">"השתמש ברשת זו כפי שהיא"</string>
-    <string name="action_do_not_use_network" msgid="4577366536956516683">"אל תשתמש ברשת זו"</string>
-    <string name="action_bar_label" msgid="917235635415966620">"היכנס לרשת"</string>
-    <string name="action_bar_title" msgid="5645564790486983117">"‏כניסה אל %1$s"</string>
-    <string name="ssl_error_warning" msgid="6653188881418638872">"יש בעיות אבטחה ברשת שאליה אתה מנסה להתחבר."</string>
-    <string name="ssl_error_example" msgid="647898534624078900">"לדוגמה, ייתכן שדף ההתחברות אינו שייך לארגון המוצג."</string>
-    <string name="ssl_error_continue" msgid="6492718244923937110">"המשך בכל זאת באמצעות דפדפן"</string>
-    <string name="ssl_error_untrusted" msgid="1496280318271264520">"אישור זה אינו מגיע מרשות אמינה."</string>
-    <string name="ssl_error_mismatch" msgid="3060364165934822383">"שם האתר לא תואם לשם באישור."</string>
-    <string name="ssl_error_expired" msgid="1501588340716182495">"פג תוקפו של אישור זה."</string>
-    <string name="ssl_error_not_yet_valid" msgid="8648649030525886924">"אישור זה אינו חוקי עדיין."</string>
-    <string name="ssl_error_date_invalid" msgid="88425990680059223">"לאישור זה יש תאריך בלתי חוקי."</string>
-    <string name="ssl_error_invalid" msgid="2540546515565633432">"אישור זה אינו חוקי."</string>
-    <string name="ssl_error_unknown" msgid="4405203446079465859">"שגיאת אישור לא ידועה."</string>
-    <string name="ssl_security_warning_title" msgid="8768539813847504404">"אזהרת אבטחה"</string>
-    <string name="ssl_error_view_certificate" msgid="5722652540168339333">"הצגת אישור"</string>
-    <string name="ok" msgid="2817931639040794018">"אישור"</string>
-    <string name="page_info_address" msgid="1261481517455692363">"כתובת:"</string>
-    <string name="page_info" msgid="4416941086705172545">"פרטי דף"</string>
-</resources>
diff --git a/packages/CaptivePortalLogin/res/values-ja/strings.xml b/packages/CaptivePortalLogin/res/values-ja/strings.xml
deleted file mode 100644
index bab9026..0000000
--- a/packages/CaptivePortalLogin/res/values-ja/strings.xml
+++ /dev/null
@@ -1,24 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="app_name" msgid="5934709770924185752">"CaptivePortalLogin"</string>
-    <string name="action_use_network" msgid="6076184727448466030">"このネットワークをそのまま使用する"</string>
-    <string name="action_do_not_use_network" msgid="4577366536956516683">"このネットワークを使用しない"</string>
-    <string name="action_bar_label" msgid="917235635415966620">"ネットワークにログイン"</string>
-    <string name="action_bar_title" msgid="5645564790486983117">"%1$s にログイン"</string>
-    <string name="ssl_error_warning" msgid="6653188881418638872">"接続しようとしているネットワークにセキュリティの問題があります。"</string>
-    <string name="ssl_error_example" msgid="647898534624078900">"たとえば、ログインページが表示されている組織に属していない可能性があります。"</string>
-    <string name="ssl_error_continue" msgid="6492718244923937110">"ブラウザから続行"</string>
-    <string name="ssl_error_untrusted" msgid="1496280318271264520">"この証明書は信頼できる認証機関のものではありません。"</string>
-    <string name="ssl_error_mismatch" msgid="3060364165934822383">"サイト名と証明書上の名前が一致しません。"</string>
-    <string name="ssl_error_expired" msgid="1501588340716182495">"この証明書は有効期限切れです。"</string>
-    <string name="ssl_error_not_yet_valid" msgid="8648649030525886924">"この証明書はまだ有効ではありません。"</string>
-    <string name="ssl_error_date_invalid" msgid="88425990680059223">"この証明書の日付は無効です。"</string>
-    <string name="ssl_error_invalid" msgid="2540546515565633432">"この証明書は無効です。"</string>
-    <string name="ssl_error_unknown" msgid="4405203446079465859">"不明な証明書エラーです。"</string>
-    <string name="ssl_security_warning_title" msgid="8768539813847504404">"セキュリティに関する警告"</string>
-    <string name="ssl_error_view_certificate" msgid="5722652540168339333">"証明書を表示"</string>
-    <string name="ok" msgid="2817931639040794018">"OK"</string>
-    <string name="page_info_address" msgid="1261481517455692363">"メールアドレス:"</string>
-    <string name="page_info" msgid="4416941086705172545">"ページ情報"</string>
-</resources>
diff --git a/packages/CaptivePortalLogin/res/values-ka/strings.xml b/packages/CaptivePortalLogin/res/values-ka/strings.xml
deleted file mode 100644
index ec820e5..0000000
--- a/packages/CaptivePortalLogin/res/values-ka/strings.xml
+++ /dev/null
@@ -1,24 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="app_name" msgid="5934709770924185752">"CaptivePortalLogin"</string>
-    <string name="action_use_network" msgid="6076184727448466030">"ამ ქსელის გამოყენება, როგორც არის"</string>
-    <string name="action_do_not_use_network" msgid="4577366536956516683">"ეს ქსელი არ გამოიყენო"</string>
-    <string name="action_bar_label" msgid="917235635415966620">"ქსელში შესვლა"</string>
-    <string name="action_bar_title" msgid="5645564790486983117">"%1$s-ში შესვლა"</string>
-    <string name="ssl_error_warning" msgid="6653188881418638872">"ქსელს, რომელზედაც მიერთებას ცდილობთ, უსაფრთხოების პრობლემები აქვს."</string>
-    <string name="ssl_error_example" msgid="647898534624078900">"მაგალითად, სისტემაში შესვლის გვერდი შეიძლება არ ეკუთვნოდეს ნაჩვენებ ორგანიზაციას."</string>
-    <string name="ssl_error_continue" msgid="6492718244923937110">"ბრაუზერში გაგრძელება"</string>
-    <string name="ssl_error_untrusted" msgid="1496280318271264520">"ეს სერტიფიკატი არ არის გაცემული ნდობით აღჭურვილი ორგანოს მიერ."</string>
-    <string name="ssl_error_mismatch" msgid="3060364165934822383">"საიტის სახელი არ ემთხვევა სერტიფიკატში მითითებულს."</string>
-    <string name="ssl_error_expired" msgid="1501588340716182495">"ეს სერტიფიკატი ვადაგასულია."</string>
-    <string name="ssl_error_not_yet_valid" msgid="8648649030525886924">"ეს სერტიფიკატი ჯერ არ არის ძალაში."</string>
-    <string name="ssl_error_date_invalid" msgid="88425990680059223">"ამ სერტიფიკატში მითითებულია არასწორი თარიღი."</string>
-    <string name="ssl_error_invalid" msgid="2540546515565633432">"ეს სერტიფიკატი არასწორია."</string>
-    <string name="ssl_error_unknown" msgid="4405203446079465859">"წარმოიშვა სერტიფიკატთან დაკავშირებული უცნობი შეცდომა."</string>
-    <string name="ssl_security_warning_title" msgid="8768539813847504404">"გაფრთხილება უსაფრთხოების შესახებ"</string>
-    <string name="ssl_error_view_certificate" msgid="5722652540168339333">"სერტიფიკატის ნახვა"</string>
-    <string name="ok" msgid="2817931639040794018">"კარგი"</string>
-    <string name="page_info_address" msgid="1261481517455692363">"მისამართი:"</string>
-    <string name="page_info" msgid="4416941086705172545">"გვერდის ინფორმაცია"</string>
-</resources>
diff --git a/packages/CaptivePortalLogin/res/values-kk/strings.xml b/packages/CaptivePortalLogin/res/values-kk/strings.xml
deleted file mode 100644
index a23eafd..0000000
--- a/packages/CaptivePortalLogin/res/values-kk/strings.xml
+++ /dev/null
@@ -1,24 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="app_name" msgid="5934709770924185752">"CaptivePortalLogin"</string>
-    <string name="action_use_network" msgid="6076184727448466030">"Осы желіні бар күйінде пайдалану"</string>
-    <string name="action_do_not_use_network" msgid="4577366536956516683">"Осы желіні пайдаланбау"</string>
-    <string name="action_bar_label" msgid="917235635415966620">"Желіге кіру"</string>
-    <string name="action_bar_title" msgid="5645564790486983117">"%1$s жүйесіне кіру"</string>
-    <string name="ssl_error_warning" msgid="6653188881418638872">"Қосылайын деп жатқан желіңіз қауіпсіз болуы мүмкін."</string>
-    <string name="ssl_error_example" msgid="647898534624078900">"Мысалы, кіру беті көрсетілген ұйымға тиесілі болмауы мүмкін."</string>
-    <string name="ssl_error_continue" msgid="6492718244923937110">"Бәрібір браузер арқылы жалғастыру"</string>
-    <string name="ssl_error_untrusted" msgid="1496280318271264520">"Сертификатты сенімді орган бермеген."</string>
-    <string name="ssl_error_mismatch" msgid="3060364165934822383">"Сайттың атауы мен сертификатта көрсетілген атау сәйкес келмейді."</string>
-    <string name="ssl_error_expired" msgid="1501588340716182495">"Сертификаттың жарамдылық мерзімі аяқталған."</string>
-    <string name="ssl_error_not_yet_valid" msgid="8648649030525886924">"Сертификат әлі жарамсыз."</string>
-    <string name="ssl_error_date_invalid" msgid="88425990680059223">"Сертификат күні жарамсыз."</string>
-    <string name="ssl_error_invalid" msgid="2540546515565633432">"Сертификат жарамсыз."</string>
-    <string name="ssl_error_unknown" msgid="4405203446079465859">"Сертификатқа қатысты белгісіз қате."</string>
-    <string name="ssl_security_warning_title" msgid="8768539813847504404">"Қауіпсіздік туралы ескерту"</string>
-    <string name="ssl_error_view_certificate" msgid="5722652540168339333">"Сертификатты көру"</string>
-    <string name="ok" msgid="2817931639040794018">"Жарайды"</string>
-    <string name="page_info_address" msgid="1261481517455692363">"Мекенжай:"</string>
-    <string name="page_info" msgid="4416941086705172545">"Бет туралы ақпарат"</string>
-</resources>
diff --git a/packages/CaptivePortalLogin/res/values-km/strings.xml b/packages/CaptivePortalLogin/res/values-km/strings.xml
deleted file mode 100644
index b4274e9..0000000
--- a/packages/CaptivePortalLogin/res/values-km/strings.xml
+++ /dev/null
@@ -1,24 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="app_name" msgid="5934709770924185752">"CaptivePortalLogin"</string>
-    <string name="action_use_network" msgid="6076184727448466030">"ប្រើ​បណ្ដាញ​នេះ​ជា"</string>
-    <string name="action_do_not_use_network" msgid="4577366536956516683">"កុំ​ប្រើ​បណ្ដាញ​នេះ"</string>
-    <string name="action_bar_label" msgid="917235635415966620">"ចូលទៅបណ្ដាញ"</string>
-    <string name="action_bar_title" msgid="5645564790486983117">"ចូលទៅ %1$s"</string>
-    <string name="ssl_error_warning" msgid="6653188881418638872">"បណ្តាញដែលអ្នកកំពុងព្យាយាមចូលមានបញ្ហាសុវត្ថិភាព។"</string>
-    <string name="ssl_error_example" msgid="647898534624078900">"ឧបករណ៍៖ ទំព័រចូលនេះអាចនឹងមិនមែនជាកម្មសិទ្ធិរបស់ស្ថាប័នដែលបានបង្ហាញនេះទេ។"</string>
-    <string name="ssl_error_continue" msgid="6492718244923937110">"យ៉ាងណាក៏ដោយនៅតែបន្តតាមរយៈកម្មវិធីរុករក"</string>
-    <string name="ssl_error_untrusted" msgid="1496280318271264520">"វិញ្ញាបនបត្រនេះ​មិនបានចេញ​ដោយ​អាជ្ញាធរដែល​គួរ​ឱ្យ​ទុកចិត្ត​ទេ។"</string>
-    <string name="ssl_error_mismatch" msgid="3060364165934822383">"ឈ្មោះ​គេហទំព័រ​នេះ​មិន​ត្រូវនឹង​ឈ្មោះ​នៅលើវិញ្ញាបនបត្រទេ។"</string>
-    <string name="ssl_error_expired" msgid="1501588340716182495">"វិញ្ញាបនបត្រនេះ​ផុត​កំណត់​ហើយ។"</string>
-    <string name="ssl_error_not_yet_valid" msgid="8648649030525886924">"វិញ្ញាបនបត្រនេះមិន​ទាន់​មាន​សុពលភាពនៅ​ឡើយ​ទេ។"</string>
-    <string name="ssl_error_date_invalid" msgid="88425990680059223">"វិញ្ញាបនបត្រនេះ​មាន​កាល​បរិច្ឆេទដែលគ្មាន​សុពលភាព។"</string>
-    <string name="ssl_error_invalid" msgid="2540546515565633432">"វិញ្ញាបនបត្រនេះគ្មាន​សុពលភាពទេ។"</string>
-    <string name="ssl_error_unknown" msgid="4405203446079465859">"មានបញ្ហា​ដោយសារ​មិនស្គាល់វិញ្ញាបនបត្រ។"</string>
-    <string name="ssl_security_warning_title" msgid="8768539813847504404">"ការព្រមានផ្នែកសុវត្ថិភាព"</string>
-    <string name="ssl_error_view_certificate" msgid="5722652540168339333">"មើល​វិញ្ញាបនបត្រ"</string>
-    <string name="ok" msgid="2817931639040794018">"យល់ព្រម"</string>
-    <string name="page_info_address" msgid="1261481517455692363">"អាសយដ្ឋាន៖"</string>
-    <string name="page_info" msgid="4416941086705172545">"ព័ត៌មាន​ទំព័រ"</string>
-</resources>
diff --git a/packages/CaptivePortalLogin/res/values-kn/strings.xml b/packages/CaptivePortalLogin/res/values-kn/strings.xml
deleted file mode 100644
index 731bbcc..0000000
--- a/packages/CaptivePortalLogin/res/values-kn/strings.xml
+++ /dev/null
@@ -1,24 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="app_name" msgid="5934709770924185752">"CaptivePortalLogin"</string>
-    <string name="action_use_network" msgid="6076184727448466030">"ಈ ನೆಟ್‌ವರ್ಕ್ ಅನ್ನು ಹೀಗೆ ಬಳಸಿ"</string>
-    <string name="action_do_not_use_network" msgid="4577366536956516683">"ಈ ನೆಟ್‌ವರ್ಕ್ ಬಳಸಬೇಡಿ"</string>
-    <string name="action_bar_label" msgid="917235635415966620">"ನೆಟ್‌ವರ್ಕ್‌ಗೆ ಸೈನ್ ಇನ್ ಮಾಡಿ"</string>
-    <string name="action_bar_title" msgid="5645564790486983117">"%1$s ಗೆ ಸೈನ್ ಇನ್ ಮಾಡಿ"</string>
-    <string name="ssl_error_warning" msgid="6653188881418638872">"ನೀವು ಸೇರಬೇಕೆಂದಿರುವ ನೆಟ್‌ವರ್ಕ್ ಭದ್ರತೆ ಸಮಸ್ಯೆಗಳನ್ನು ಹೊಂದಿದೆ."</string>
-    <string name="ssl_error_example" msgid="647898534624078900">"ಉದಾಹರಣೆಗೆ, ಲಾಗಿನ್ ಪುಟವು ತೋರಿಸಲಾಗಿರುವ ಸಂಸ್ಥೆಗೆ ಸಂಬಂಧಿಸಿರುವುದಿಲ್ಲ."</string>
-    <string name="ssl_error_continue" msgid="6492718244923937110">"ಹೇಗಾದರೂ ಬ್ರೌಸರ್ ಮೂಲಕ ಮುಂದುವರಿಸಿ"</string>
-    <string name="ssl_error_untrusted" msgid="1496280318271264520">"ಈ ಪ್ರಮಾಣಪತ್ರವು ವಿಶ್ವಾಸಾರ್ಹ ಪ್ರಾಧಿಕಾರದಿಂದ ಬಂದಿಲ್ಲ."</string>
-    <string name="ssl_error_mismatch" msgid="3060364165934822383">"ಸೈಟ್‌ನ ಹೆಸರು ಪ್ರಮಾಣಪತ್ರದಲ್ಲಿನ ಹೆಸರಿನ ಜೊತೆಗೆ ಹೊಂದಾಣಿಕೆಯಾಗುತ್ತಿಲ್ಲ."</string>
-    <string name="ssl_error_expired" msgid="1501588340716182495">"ಈ ಪ್ರಮಾಣಪತ್ರದ ಅವಧಿ ಮೀರಿದೆ."</string>
-    <string name="ssl_error_not_yet_valid" msgid="8648649030525886924">"ಈ ಪ್ರಮಾಣಪತ್ರವು ಇನ್ನೂ ಮಾನ್ಯವಾಗಿಲ್ಲ."</string>
-    <string name="ssl_error_date_invalid" msgid="88425990680059223">"ಈ ಪ್ರಮಾಣಪತ್ರವು ಅಮಾನ್ಯವಾದ ದಿನಾಂಕವನ್ನು ಹೊಂದಿದೆ."</string>
-    <string name="ssl_error_invalid" msgid="2540546515565633432">"ಈ ಪ್ರಮಾಣಪತ್ರವು ಅಮಾನ್ಯವಾಗಿದೆ."</string>
-    <string name="ssl_error_unknown" msgid="4405203446079465859">"ಪ್ರಮಾಣಪತ್ರದ ಅಜ್ಞಾತ ದೋಷ."</string>
-    <string name="ssl_security_warning_title" msgid="8768539813847504404">"ಭದ್ರತಾ ಎಚ್ಚರಿಕೆ"</string>
-    <string name="ssl_error_view_certificate" msgid="5722652540168339333">"ಪ್ರಮಾಣಪತ್ರವನ್ನು ವೀಕ್ಷಿಸಿ"</string>
-    <string name="ok" msgid="2817931639040794018">"ಸರಿ"</string>
-    <string name="page_info_address" msgid="1261481517455692363">"ವಿಳಾಸ:"</string>
-    <string name="page_info" msgid="4416941086705172545">"ಪುಟದ ಮಾಹಿತಿ"</string>
-</resources>
diff --git a/packages/CaptivePortalLogin/res/values-ko/strings.xml b/packages/CaptivePortalLogin/res/values-ko/strings.xml
deleted file mode 100644
index 8c2d9d2..0000000
--- a/packages/CaptivePortalLogin/res/values-ko/strings.xml
+++ /dev/null
@@ -1,24 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="app_name" msgid="5934709770924185752">"CaptivePortalLogin"</string>
-    <string name="action_use_network" msgid="6076184727448466030">"현재 상태로 이 네트워크 사용"</string>
-    <string name="action_do_not_use_network" msgid="4577366536956516683">"이 네트워크 사용 안함"</string>
-    <string name="action_bar_label" msgid="917235635415966620">"네트워크에 로그인"</string>
-    <string name="action_bar_title" msgid="5645564790486983117">"%1$s에 로그인"</string>
-    <string name="ssl_error_warning" msgid="6653188881418638872">"가입하려는 네트워크에 보안 문제가 있습니다."</string>
-    <string name="ssl_error_example" msgid="647898534624078900">"예를 들어 로그인 페이지가 표시된 조직에 속하지 않을 수 있습니다."</string>
-    <string name="ssl_error_continue" msgid="6492718244923937110">"브라우저를 통해 계속하기"</string>
-    <string name="ssl_error_untrusted" msgid="1496280318271264520">"신뢰할 수 있는 인증 기관에서 발급한 인증서가 아닙니다."</string>
-    <string name="ssl_error_mismatch" msgid="3060364165934822383">"사이트 이름이 인증서상의 이름과 일치하지 않습니다."</string>
-    <string name="ssl_error_expired" msgid="1501588340716182495">"인증서가 만료되었습니다."</string>
-    <string name="ssl_error_not_yet_valid" msgid="8648649030525886924">"인증서가 아직 유효하지 않습니다."</string>
-    <string name="ssl_error_date_invalid" msgid="88425990680059223">"인증서의 날짜가 잘못되었습니다."</string>
-    <string name="ssl_error_invalid" msgid="2540546515565633432">"인증서가 잘못되었습니다."</string>
-    <string name="ssl_error_unknown" msgid="4405203446079465859">"알 수 없는 인증서 오류입니다."</string>
-    <string name="ssl_security_warning_title" msgid="8768539813847504404">"보안 경고"</string>
-    <string name="ssl_error_view_certificate" msgid="5722652540168339333">"인증서 보기"</string>
-    <string name="ok" msgid="2817931639040794018">"확인"</string>
-    <string name="page_info_address" msgid="1261481517455692363">"주소:"</string>
-    <string name="page_info" msgid="4416941086705172545">"페이지 정보"</string>
-</resources>
diff --git a/packages/CaptivePortalLogin/res/values-ky/strings.xml b/packages/CaptivePortalLogin/res/values-ky/strings.xml
deleted file mode 100644
index 6d663cb..0000000
--- a/packages/CaptivePortalLogin/res/values-ky/strings.xml
+++ /dev/null
@@ -1,24 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="app_name" msgid="5934709770924185752">"CaptivePortalLogin"</string>
-    <string name="action_use_network" msgid="6076184727448466030">"Бул тармак кандай болсо, ошондой колдонулсун"</string>
-    <string name="action_do_not_use_network" msgid="4577366536956516683">"Бул тармак колдонулбасын"</string>
-    <string name="action_bar_label" msgid="917235635415966620">"Тармакка кирүү"</string>
-    <string name="action_bar_title" msgid="5645564790486983117">"%1$s каттоо эсебине кириңиз"</string>
-    <string name="ssl_error_warning" msgid="6653188881418638872">"Кошулайын деген тармагыңызда коопсуздук көйгөйлөрү бар."</string>
-    <string name="ssl_error_example" msgid="647898534624078900">"Мисалы, каттоо эсебине кирүү баракчасы көрсөтүлгөн уюмга таандык эмес болушу мүмкүн."</string>
-    <string name="ssl_error_continue" msgid="6492718244923937110">"Баары бир серепчи аркылуу улантуу"</string>
-    <string name="ssl_error_untrusted" msgid="1496280318271264520">"Бул тастыктама ишеничтүү мекеме аркылуу берилген эмес."</string>
-    <string name="ssl_error_mismatch" msgid="3060364165934822383">"Сайттын аталышы тастыктаманын аталышына дал келбейт."</string>
-    <string name="ssl_error_expired" msgid="1501588340716182495">"Бул тастыктаманын мөөнөтү өтүп кеткен."</string>
-    <string name="ssl_error_not_yet_valid" msgid="8648649030525886924">"Бул тастыктама азырынча жараксыз."</string>
-    <string name="ssl_error_date_invalid" msgid="88425990680059223">"Бул тастыктаманын күнү жараксыз."</string>
-    <string name="ssl_error_invalid" msgid="2540546515565633432">"Бул тастыктама жараксыз."</string>
-    <string name="ssl_error_unknown" msgid="4405203446079465859">"Тастыктамага байланыштуу белгисиз ката."</string>
-    <string name="ssl_security_warning_title" msgid="8768539813847504404">"Коопсуздук эскертүүсү"</string>
-    <string name="ssl_error_view_certificate" msgid="5722652540168339333">"Тастыктаманы көрүү"</string>
-    <string name="ok" msgid="2817931639040794018">"ЖАРАЙТ"</string>
-    <string name="page_info_address" msgid="1261481517455692363">"Дарек:"</string>
-    <string name="page_info" msgid="4416941086705172545">"Барак жөнүндө маалымат"</string>
-</resources>
diff --git a/packages/CaptivePortalLogin/res/values-lo/strings.xml b/packages/CaptivePortalLogin/res/values-lo/strings.xml
deleted file mode 100644
index 673bf2c..0000000
--- a/packages/CaptivePortalLogin/res/values-lo/strings.xml
+++ /dev/null
@@ -1,24 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="app_name" msgid="5934709770924185752">"CaptivePortalLogin"</string>
-    <string name="action_use_network" msgid="6076184727448466030">"​ໃຊ້​ເຄືອ​ຂ່າຍ​ນີ້​ຕາມ​ທີ່​ມັນ​ເປັນ"</string>
-    <string name="action_do_not_use_network" msgid="4577366536956516683">"ບໍ່​ໃຊ້​ເຄືອ​ຂ່າຍ​ນີ້"</string>
-    <string name="action_bar_label" msgid="917235635415966620">"ລົງຊື່ເຂົ້າເຄືອຂ່າຍ"</string>
-    <string name="action_bar_title" msgid="5645564790486983117">"ເຂົ້າສູ່ລະບົບ %1$s"</string>
-    <string name="ssl_error_warning" msgid="6653188881418638872">"ເຄືອ​ຂ່າຍ​ທີ່​ທ່ານ​ກຳ​ລັງ​ເຂົ້າ​ຮ່ວມ​ມີ​ບັນ​ຫາ​ຄວາມ​ປອດ​ໄພ."</string>
-    <string name="ssl_error_example" msgid="647898534624078900">"ຕົວ​ຢ່າງ, ໜ້າ​ລົງ​ຊື່​ເຂົ້າ​ໃຊ້​ອາດ​ຈະ​ບໍ່​ເປັນ​ຂອງ​ອົງ​ການ​ທີ່​ສະ​ແດງ​ຂຶ້ນ."</string>
-    <string name="ssl_error_continue" msgid="6492718244923937110">"ແນວ​ໃດ​ກໍ່​ສືບ​ຕໍ່​ຜ່ານບ​ຣາວ​ເຊີ"</string>
-    <string name="ssl_error_untrusted" msgid="1496280318271264520">"ໃບຮັບຮອງນີ້ບໍ່ໄດ້ມາຈາກໜ່ວຍງານທີ່ເຊື່ອຖືໄດ້."</string>
-    <string name="ssl_error_mismatch" msgid="3060364165934822383">"ຊື່ຂອງເວັບໄຊບໍ່ກົງກັບຊື່ຢູ່ໃບຮັບຮອງ."</string>
-    <string name="ssl_error_expired" msgid="1501588340716182495">"ໃບຮັບຮອງນີ້ຫມົດອາຍຸແລ້ວ."</string>
-    <string name="ssl_error_not_yet_valid" msgid="8648649030525886924">"ໃບຮັບຮອງນີ້ບໍ່ຖືກຕ້ອງເທື່ອ."</string>
-    <string name="ssl_error_date_invalid" msgid="88425990680059223">"ໃບຮັບຮອງນີ້ມີວັນທີບໍ່ຖືກຕ້ອງ."</string>
-    <string name="ssl_error_invalid" msgid="2540546515565633432">"ໃບຮັບຮອງນີ້ບໍ່ຖືກຕ້ອງ."</string>
-    <string name="ssl_error_unknown" msgid="4405203446079465859">"ໃບຮັບຮອງມີຄວາມຜິດພາດທີ່ບໍ່ຮູ້ຈັກ."</string>
-    <string name="ssl_security_warning_title" msgid="8768539813847504404">"ຄຳເຕືອນຄວາມປອດໄພ"</string>
-    <string name="ssl_error_view_certificate" msgid="5722652540168339333">"ເບິ່ງໃບຮັບຮອງ"</string>
-    <string name="ok" msgid="2817931639040794018">"ຕົກລົງ"</string>
-    <string name="page_info_address" msgid="1261481517455692363">"ທີ່ຢູ່:"</string>
-    <string name="page_info" msgid="4416941086705172545">"ຂໍ້ມູນໜ້າ"</string>
-</resources>
diff --git a/packages/CaptivePortalLogin/res/values-lt/strings.xml b/packages/CaptivePortalLogin/res/values-lt/strings.xml
deleted file mode 100644
index eb4c46c..0000000
--- a/packages/CaptivePortalLogin/res/values-lt/strings.xml
+++ /dev/null
@@ -1,24 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="app_name" msgid="5934709770924185752">"CaptivePortalLogin"</string>
-    <string name="action_use_network" msgid="6076184727448466030">"Naudoti šį tinklą tokį, koks yra"</string>
-    <string name="action_do_not_use_network" msgid="4577366536956516683">"Nenaudoti šio tinklo"</string>
-    <string name="action_bar_label" msgid="917235635415966620">"Prisijungti prie tinklo"</string>
-    <string name="action_bar_title" msgid="5645564790486983117">"Prisijungimas prie „%1$s“"</string>
-    <string name="ssl_error_warning" msgid="6653188881418638872">"Kilo tinklo, prie kurio bandote prisijungti, problemų."</string>
-    <string name="ssl_error_example" msgid="647898534624078900">"Pavyzdžiui, prisijungimo puslapis gali nepriklausyti rodomai organizacijai."</string>
-    <string name="ssl_error_continue" msgid="6492718244923937110">"Vis tiek tęsti naudojant naršyklę"</string>
-    <string name="ssl_error_untrusted" msgid="1496280318271264520">"Šį sertifikatą išdavė nepatikima įstaiga."</string>
-    <string name="ssl_error_mismatch" msgid="3060364165934822383">"Svetainės pavadinimas neatitinka sertifikate nurodyto pavadinimo."</string>
-    <string name="ssl_error_expired" msgid="1501588340716182495">"Šio sertifikato galiojimo laikas baigėsi."</string>
-    <string name="ssl_error_not_yet_valid" msgid="8648649030525886924">"Šis sertifikatas dar negalioja."</string>
-    <string name="ssl_error_date_invalid" msgid="88425990680059223">"Šio sertifikato data netinkama."</string>
-    <string name="ssl_error_invalid" msgid="2540546515565633432">"Šis sertifikatas netinkamas."</string>
-    <string name="ssl_error_unknown" msgid="4405203446079465859">"Nežinoma sertifikato klaida."</string>
-    <string name="ssl_security_warning_title" msgid="8768539813847504404">"Saugos įspėjimas"</string>
-    <string name="ssl_error_view_certificate" msgid="5722652540168339333">"Žiūrėti sertifikatą"</string>
-    <string name="ok" msgid="2817931639040794018">"Gerai"</string>
-    <string name="page_info_address" msgid="1261481517455692363">"Adresas"</string>
-    <string name="page_info" msgid="4416941086705172545">"Puslapio informacija"</string>
-</resources>
diff --git a/packages/CaptivePortalLogin/res/values-lv/strings.xml b/packages/CaptivePortalLogin/res/values-lv/strings.xml
deleted file mode 100644
index 5554343..0000000
--- a/packages/CaptivePortalLogin/res/values-lv/strings.xml
+++ /dev/null
@@ -1,24 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="app_name" msgid="5934709770924185752">"CaptivePortalLogin"</string>
-    <string name="action_use_network" msgid="6076184727448466030">"Izmantot tīklu ar pašreizējiem iestatījumiem"</string>
-    <string name="action_do_not_use_network" msgid="4577366536956516683">"Neizmantot šo tīklu"</string>
-    <string name="action_bar_label" msgid="917235635415966620">"Pierakstīties tīklā"</string>
-    <string name="action_bar_title" msgid="5645564790486983117">"Pierakstieties produktā %1$s"</string>
-    <string name="ssl_error_warning" msgid="6653188881418638872">"Tīklam, kuram mēģināt pievienoties, ir drošības problēmas."</string>
-    <string name="ssl_error_example" msgid="647898534624078900">"Piemēram, pieteikšanās lapa, iespējams, nepieder norādītajai organizācijai."</string>
-    <string name="ssl_error_continue" msgid="6492718244923937110">"Tik un tā turpināt, izmantojot pārlūkprogrammu"</string>
-    <string name="ssl_error_untrusted" msgid="1496280318271264520">"Šo sertifikātu nav izsniegusi uzticama iestāde."</string>
-    <string name="ssl_error_mismatch" msgid="3060364165934822383">"Vietnes nosaukums neatbilst nosaukumam sertifikātā."</string>
-    <string name="ssl_error_expired" msgid="1501588340716182495">"Šī sertifikāta derīguma termiņš ir beidzies."</string>
-    <string name="ssl_error_not_yet_valid" msgid="8648649030525886924">"Šis sertifikāts vēl nav derīgs."</string>
-    <string name="ssl_error_date_invalid" msgid="88425990680059223">"Šī sertifikāta datums nav derīgs."</string>
-    <string name="ssl_error_invalid" msgid="2540546515565633432">"Šis sertifikāts nav derīgs."</string>
-    <string name="ssl_error_unknown" msgid="4405203446079465859">"Nezināma sertifikāta kļūda."</string>
-    <string name="ssl_security_warning_title" msgid="8768539813847504404">"Drošības brīdinājums"</string>
-    <string name="ssl_error_view_certificate" msgid="5722652540168339333">"Skatīt sertifikātu"</string>
-    <string name="ok" msgid="2817931639040794018">"Labi"</string>
-    <string name="page_info_address" msgid="1261481517455692363">"Adrese:"</string>
-    <string name="page_info" msgid="4416941086705172545">"Lapas informācija"</string>
-</resources>
diff --git a/packages/CaptivePortalLogin/res/values-mk/strings.xml b/packages/CaptivePortalLogin/res/values-mk/strings.xml
deleted file mode 100644
index 9a57fca..0000000
--- a/packages/CaptivePortalLogin/res/values-mk/strings.xml
+++ /dev/null
@@ -1,24 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="app_name" msgid="5934709770924185752">"CaptivePortalLogin"</string>
-    <string name="action_use_network" msgid="6076184727448466030">"Користи ја мрежата во оваа состојба"</string>
-    <string name="action_do_not_use_network" msgid="4577366536956516683">"Не ја користи мрежата"</string>
-    <string name="action_bar_label" msgid="917235635415966620">"Најавете се на мрежа"</string>
-    <string name="action_bar_title" msgid="5645564790486983117">"Најавете се на %1$s"</string>
-    <string name="ssl_error_warning" msgid="6653188881418638872">"Мрежата на која се обидувате да се придружите има проблеми со безбедноста."</string>
-    <string name="ssl_error_example" msgid="647898534624078900">"На пример, страницата за најавување може да не припаѓа на организацијата што е прикажана."</string>
-    <string name="ssl_error_continue" msgid="6492718244923937110">"Сепак продолжи преку прелистувач"</string>
-    <string name="ssl_error_untrusted" msgid="1496280318271264520">"Сертификатов не е од доверлив орган."</string>
-    <string name="ssl_error_mismatch" msgid="3060364165934822383">"Името на сајтот не се совпаѓа со името на сертификатот."</string>
-    <string name="ssl_error_expired" msgid="1501588340716182495">"Сертификатов е истечен."</string>
-    <string name="ssl_error_not_yet_valid" msgid="8648649030525886924">"Сертификатов сѐ уште не е важечки."</string>
-    <string name="ssl_error_date_invalid" msgid="88425990680059223">"Сертификатов има неважечки датум."</string>
-    <string name="ssl_error_invalid" msgid="2540546515565633432">"Сертификатов е неважечки."</string>
-    <string name="ssl_error_unknown" msgid="4405203446079465859">"Непозната грешка на сертификатот."</string>
-    <string name="ssl_security_warning_title" msgid="8768539813847504404">"Предупредување за безбедност"</string>
-    <string name="ssl_error_view_certificate" msgid="5722652540168339333">"Прикажи го сертификатот"</string>
-    <string name="ok" msgid="2817931639040794018">"Во ред"</string>
-    <string name="page_info_address" msgid="1261481517455692363">"Адреса:"</string>
-    <string name="page_info" msgid="4416941086705172545">"Информации за страницата"</string>
-</resources>
diff --git a/packages/CaptivePortalLogin/res/values-ml/strings.xml b/packages/CaptivePortalLogin/res/values-ml/strings.xml
deleted file mode 100644
index 8fd74d1..0000000
--- a/packages/CaptivePortalLogin/res/values-ml/strings.xml
+++ /dev/null
@@ -1,24 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="app_name" msgid="5934709770924185752">"CaptivePortalLogin"</string>
-    <string name="action_use_network" msgid="6076184727448466030">"ഈ നെറ്റ്‌വർക്ക് മാറ്റമൊന്നും വരുത്താതെ ഉപയോഗിക്കുക"</string>
-    <string name="action_do_not_use_network" msgid="4577366536956516683">"ഈ നെറ്റ്‌വർക്ക് ഉപയോഗിക്കരുത്"</string>
-    <string name="action_bar_label" msgid="917235635415966620">"നെറ്റ്‌വർക്കിൽ സൈൻ ഇൻ ചെയ്യുക"</string>
-    <string name="action_bar_title" msgid="5645564790486983117">"%1$s എന്നതിലേക്ക് സൈൻ ഇൻ ചെയ്യുക"</string>
-    <string name="ssl_error_warning" msgid="6653188881418638872">"നിങ്ങൾ ചേരാൻ ശ്രമിക്കുന്ന നെറ്റ്‌വർക്കിൽ സുരക്ഷാ പ്രശ്‌നങ്ങളുണ്ടായിരിക്കാം."</string>
-    <string name="ssl_error_example" msgid="647898534624078900">"ഉദാഹരണത്തിന്, കാണിച്ചിരിക്കുന്ന ഓർഗനൈസേഷന്റേതായിരിക്കില്ല ലോഗിൻ പേജ്."</string>
-    <string name="ssl_error_continue" msgid="6492718244923937110">"എന്തായാലും ബ്രൗസർ വഴി തുടരുക"</string>
-    <string name="ssl_error_untrusted" msgid="1496280318271264520">"ഈ സർട്ടിഫിക്കറ്റ്, വിശ്വസനീയ അതോറിറ്റിയിൽ നിന്നുള്ളതല്ല."</string>
-    <string name="ssl_error_mismatch" msgid="3060364165934822383">"സൈറ്റിന്റെ പേര്, സർട്ടിഫിക്കറ്റിലുള്ള പേരുമായി പൊരുത്തപ്പെടുന്നില്ല."</string>
-    <string name="ssl_error_expired" msgid="1501588340716182495">"ഈ സർട്ടിഫിക്കറ്റ് കാലഹരണപ്പെട്ടു."</string>
-    <string name="ssl_error_not_yet_valid" msgid="8648649030525886924">"ഈ സർട്ടിഫിക്കറ്റിന് ഇപ്പോഴും സാധുതയില്ല."</string>
-    <string name="ssl_error_date_invalid" msgid="88425990680059223">"ഈ സർട്ടിഫിക്കറ്റിൽ അസാധുവായ തീയതിയാണുള്ളത്."</string>
-    <string name="ssl_error_invalid" msgid="2540546515565633432">"ഈ സർട്ടിഫിക്കറ്റ് അസാധുവാണ്."</string>
-    <string name="ssl_error_unknown" msgid="4405203446079465859">"അജ്ഞാത സർട്ടിഫിക്കറ്റ് പിശക്."</string>
-    <string name="ssl_security_warning_title" msgid="8768539813847504404">"സുരക്ഷാ മുന്നറിയിപ്പ്"</string>
-    <string name="ssl_error_view_certificate" msgid="5722652540168339333">"സർട്ടിഫിക്കറ്റ് കാണുക"</string>
-    <string name="ok" msgid="2817931639040794018">"ശരി"</string>
-    <string name="page_info_address" msgid="1261481517455692363">"വിലാസം:"</string>
-    <string name="page_info" msgid="4416941086705172545">"പേജ് വിവരം"</string>
-</resources>
diff --git a/packages/CaptivePortalLogin/res/values-mn/strings.xml b/packages/CaptivePortalLogin/res/values-mn/strings.xml
deleted file mode 100644
index f11f1d6..0000000
--- a/packages/CaptivePortalLogin/res/values-mn/strings.xml
+++ /dev/null
@@ -1,24 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="app_name" msgid="5934709770924185752">"CaptivePortalLogin"</string>
-    <string name="action_use_network" msgid="6076184727448466030">"Энэ сүлжээг ашиглана уу"</string>
-    <string name="action_do_not_use_network" msgid="4577366536956516683">"Энэ сүлжээг бүү ашиглана уу"</string>
-    <string name="action_bar_label" msgid="917235635415966620">"Сүлжээнд нэвтэрнэ үү"</string>
-    <string name="action_bar_title" msgid="5645564790486983117">"%1$s-д нэвтрэх"</string>
-    <string name="ssl_error_warning" msgid="6653188881418638872">"Таны нэгдэх гэж буй сүлжээ аюулгүй байдлын асуудалтай байна."</string>
-    <string name="ssl_error_example" msgid="647898534624078900">"Жишээлбэл нэвтрэх хуудас нь харагдах байгууллагынх биш байж болзошгүй."</string>
-    <string name="ssl_error_continue" msgid="6492718244923937110">"Ямартаа ч хөтчөөр үргэлжлүүлэх"</string>
-    <string name="ssl_error_untrusted" msgid="1496280318271264520">"Энэ сертификатыг итгэмжлэгдсэн байгууллагаас олгоогүй байна."</string>
-    <string name="ssl_error_mismatch" msgid="3060364165934822383">"Сайтын нэр сертификат дээрх нэртэй таарахгүй байна."</string>
-    <string name="ssl_error_expired" msgid="1501588340716182495">"Энэ сертификатын хугацаа дууссан байна."</string>
-    <string name="ssl_error_not_yet_valid" msgid="8648649030525886924">"Энэ сертификат одоогоор хүчингүй байна."</string>
-    <string name="ssl_error_date_invalid" msgid="88425990680059223">"Энэ сертификатын огноо хүчингүй байна."</string>
-    <string name="ssl_error_invalid" msgid="2540546515565633432">"Энэ сертификат хүчингүй байна."</string>
-    <string name="ssl_error_unknown" msgid="4405203446079465859">"Сертификатын үл мэдэгдэх алдаа гарлаа."</string>
-    <string name="ssl_security_warning_title" msgid="8768539813847504404">"Аюулгүй байдлын анхааруулга"</string>
-    <string name="ssl_error_view_certificate" msgid="5722652540168339333">"Сертификатыг харах"</string>
-    <string name="ok" msgid="2817931639040794018">"ЗА"</string>
-    <string name="page_info_address" msgid="1261481517455692363">"Хаяг:"</string>
-    <string name="page_info" msgid="4416941086705172545">"Хуудасны мэдээлэл"</string>
-</resources>
diff --git a/packages/CaptivePortalLogin/res/values-mr/strings.xml b/packages/CaptivePortalLogin/res/values-mr/strings.xml
deleted file mode 100644
index 0adc92e..0000000
--- a/packages/CaptivePortalLogin/res/values-mr/strings.xml
+++ /dev/null
@@ -1,24 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="app_name" msgid="5934709770924185752">"CaptivePortalLogin"</string>
-    <string name="action_use_network" msgid="6076184727448466030">"हे नेटवर्क जसेच्या तसे वापरा"</string>
-    <string name="action_do_not_use_network" msgid="4577366536956516683">"हे नेटवर्क वापरू नका"</string>
-    <string name="action_bar_label" msgid="917235635415966620">"नेटवर्क मध्‍ये साइन इन करा"</string>
-    <string name="action_bar_title" msgid="5645564790486983117">"%1$sमध्‍ये साइन इन करा"</string>
-    <string name="ssl_error_warning" msgid="6653188881418638872">"ज्या नेटवर्कमध्‍ये तुम्ही सामील होण्याचा प्रयत्न करीत आहात त्यात सुरक्षितता समस्या आहेत."</string>
-    <string name="ssl_error_example" msgid="647898534624078900">"उदाहरणार्थ, लॉगिन पृष्‍ठ कदाचित दर्शविलेल्या संस्थेच्या मालकीचे नसावे."</string>
-    <string name="ssl_error_continue" msgid="6492718244923937110">"ब्राउझरद्वारे तरीही सुरु ठेवा"</string>
-    <string name="ssl_error_untrusted" msgid="1496280318271264520">"हे प्रमाणपत्र विश्वसनीय संस्थेने दिलेले नाही"</string>
-    <string name="ssl_error_mismatch" msgid="3060364165934822383">"साइटचे नाव प्रमाणपत्रावरील नावाशी जुळत नाही."</string>
-    <string name="ssl_error_expired" msgid="1501588340716182495">"हे प्रमाणपत्र एक्स्पायर झाले आहे."</string>
-    <string name="ssl_error_not_yet_valid" msgid="8648649030525886924">"हे प्रमाणपत्र अजून योग्य नाही."</string>
-    <string name="ssl_error_date_invalid" msgid="88425990680059223">"या प्रमाणपत्राची तारीख चुकीची आहे."</string>
-    <string name="ssl_error_invalid" msgid="2540546515565633432">"हे प्रमाणपत्र चुकीचे आहे."</string>
-    <string name="ssl_error_unknown" msgid="4405203446079465859">"अज्ञात प्रमाणपत्र एरर."</string>
-    <string name="ssl_security_warning_title" msgid="8768539813847504404">"सुरक्षितता चेतावणी"</string>
-    <string name="ssl_error_view_certificate" msgid="5722652540168339333">"प्रमाणपत्र पाहा"</string>
-    <string name="ok" msgid="2817931639040794018">"ठीक आहे"</string>
-    <string name="page_info_address" msgid="1261481517455692363">"पत्ता:"</string>
-    <string name="page_info" msgid="4416941086705172545">"पेज माहिती"</string>
-</resources>
diff --git a/packages/CaptivePortalLogin/res/values-ms/strings.xml b/packages/CaptivePortalLogin/res/values-ms/strings.xml
deleted file mode 100644
index cc4957e..0000000
--- a/packages/CaptivePortalLogin/res/values-ms/strings.xml
+++ /dev/null
@@ -1,24 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="app_name" msgid="5934709770924185752">"CaptivePortalLogin"</string>
-    <string name="action_use_network" msgid="6076184727448466030">"Gunakan rangkaian ini"</string>
-    <string name="action_do_not_use_network" msgid="4577366536956516683">"Jangan gunakan rangkaian ini"</string>
-    <string name="action_bar_label" msgid="917235635415966620">"Log masuk ke rangkaian"</string>
-    <string name="action_bar_title" msgid="5645564790486983117">"Log masuk ke %1$s"</string>
-    <string name="ssl_error_warning" msgid="6653188881418638872">"Rangkaian yang anda cuba sertai mempunyai isu keselamatan."</string>
-    <string name="ssl_error_example" msgid="647898534624078900">"Contohnya, halaman log masuk mungkin bukan milik organisasi yang ditunjukkan."</string>
-    <string name="ssl_error_continue" msgid="6492718244923937110">"Teruskan juga melalui penyemak imbas"</string>
-    <string name="ssl_error_untrusted" msgid="1496280318271264520">"Sijil ini bukan daripada pihak berkuasa yang dipercayai."</string>
-    <string name="ssl_error_mismatch" msgid="3060364165934822383">"Nama tapak tidak sepadan dengan nama pada sijil."</string>
-    <string name="ssl_error_expired" msgid="1501588340716182495">"Sijil ini telah tamat tempoh."</string>
-    <string name="ssl_error_not_yet_valid" msgid="8648649030525886924">"Sijil ini belum sah."</string>
-    <string name="ssl_error_date_invalid" msgid="88425990680059223">"Sijil ini mempunyai tarikh yang tidak sah."</string>
-    <string name="ssl_error_invalid" msgid="2540546515565633432">"Sijil ini tidak sah."</string>
-    <string name="ssl_error_unknown" msgid="4405203446079465859">"Ralat sijil tidak diketahui."</string>
-    <string name="ssl_security_warning_title" msgid="8768539813847504404">"Amaran keselamatan"</string>
-    <string name="ssl_error_view_certificate" msgid="5722652540168339333">"Lihat sijil"</string>
-    <string name="ok" msgid="2817931639040794018">"OK"</string>
-    <string name="page_info_address" msgid="1261481517455692363">"Alamat:"</string>
-    <string name="page_info" msgid="4416941086705172545">"Maklumat halaman"</string>
-</resources>
diff --git a/packages/CaptivePortalLogin/res/values-my/strings.xml b/packages/CaptivePortalLogin/res/values-my/strings.xml
deleted file mode 100644
index 04a07a4..0000000
--- a/packages/CaptivePortalLogin/res/values-my/strings.xml
+++ /dev/null
@@ -1,24 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="app_name" msgid="5934709770924185752">"CaptivePortalLogin"</string>
-    <string name="action_use_network" msgid="6076184727448466030">"ဒီကွန်ရက်ကို လက်ရှိအတိုင်း သုံးရန်"</string>
-    <string name="action_do_not_use_network" msgid="4577366536956516683">"ဒီကွန်ရက်ကို မသုံးပါနှင့်"</string>
-    <string name="action_bar_label" msgid="917235635415966620">"ကွန်ယက်သို့ လက်မှတ်ထိုးဝင်ရန်"</string>
-    <string name="action_bar_title" msgid="5645564790486983117">"%1$s သို့ လက်မှတ်ထိုးဝင်ပါ"</string>
-    <string name="ssl_error_warning" msgid="6653188881418638872">"သင်ချိတ်ဆက်ရန် ကြိုးစားနေသည့် ကွန်ရက်သည် လုံခြုံရေးပြဿနာ ရှိနေသည်။"</string>
-    <string name="ssl_error_example" msgid="647898534624078900">"ဥပမာ၊ ဝင်ရောက်ရန် စာမျက်နှာသည် ပြသထားသည့် အဖွဲ့အစည်းနှင့် သက်ဆိုင်မှု မရှိနိုင်ပါ။"</string>
-    <string name="ssl_error_continue" msgid="6492718244923937110">"ဘရောက်ဇာမှတစ်ဆင့် ဆက်လုပ်ရန်"</string>
-    <string name="ssl_error_untrusted" msgid="1496280318271264520">"ဤအသိအမှတ်ပြုလက်မှတ်သည် ယုံကြည်ရသော စစ်ဆေးရေးအဖွဲ့ထံမှ မဟုတ်ပါ။"</string>
-    <string name="ssl_error_mismatch" msgid="3060364165934822383">"ဝဘ်ဆိုက်အမည်သည် အသိအမှတ်ပြုလက်မှတ်ရှိ အမည်နှင့် မကိုက်ညီပါ။"</string>
-    <string name="ssl_error_expired" msgid="1501588340716182495">"ဤအသိအမှတ်ပြုလက်မှတ် သက်တမ်းကုန်နေပါပြီ။"</string>
-    <string name="ssl_error_not_yet_valid" msgid="8648649030525886924">"ဤအသိအမှတ်ပြုလက်မှတ်သည် မမှန်ကန်သေးပါ။"</string>
-    <string name="ssl_error_date_invalid" msgid="88425990680059223">"ဤအသိအမှတ်ပြုလက်မှတ်ရှိ ရက်စွဲ မမှန်ကန်ပါ။"</string>
-    <string name="ssl_error_invalid" msgid="2540546515565633432">"ဤအသိအမှတ်ပြုလက်မှတ် မမှန်ကန်ပါ။"</string>
-    <string name="ssl_error_unknown" msgid="4405203446079465859">"အသိအမှတ်ပြုလက်မှတ်ဆိုင်ရာ အမျိုးအမည်မသိ အမှား။"</string>
-    <string name="ssl_security_warning_title" msgid="8768539813847504404">"လုံခြုံရေး သတိပေးချက်"</string>
-    <string name="ssl_error_view_certificate" msgid="5722652540168339333">"အသိအမှတ်ပြုလက်မှတ်ကို ကြည့်ရန်"</string>
-    <string name="ok" msgid="2817931639040794018">"OK"</string>
-    <string name="page_info_address" msgid="1261481517455692363">"လိပ်စာ-"</string>
-    <string name="page_info" msgid="4416941086705172545">"စာမျက်နှာ အချက်အလက်"</string>
-</resources>
diff --git a/packages/CaptivePortalLogin/res/values-nb/strings.xml b/packages/CaptivePortalLogin/res/values-nb/strings.xml
deleted file mode 100644
index 29ab438..0000000
--- a/packages/CaptivePortalLogin/res/values-nb/strings.xml
+++ /dev/null
@@ -1,24 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="app_name" msgid="5934709770924185752">"CaptivePortalLogin"</string>
-    <string name="action_use_network" msgid="6076184727448466030">"Bruk dette nettverket som det er"</string>
-    <string name="action_do_not_use_network" msgid="4577366536956516683">"Ikke bruk dette nettverket"</string>
-    <string name="action_bar_label" msgid="917235635415966620">"Logg på nettverk"</string>
-    <string name="action_bar_title" msgid="5645564790486983117">"Logg på %1$s"</string>
-    <string name="ssl_error_warning" msgid="6653188881418638872">"Nettverket du prøver å logge på, har sikkerhetsproblemer."</string>
-    <string name="ssl_error_example" msgid="647898534624078900">"Det er for eksempel mulig at påloggingssiden kanskje ikke tilhører organisasjonen som vises."</string>
-    <string name="ssl_error_continue" msgid="6492718244923937110">"Fortsett likevel via nettleseren"</string>
-    <string name="ssl_error_untrusted" msgid="1496280318271264520">"Sertifikatet er ikke fra en pålitelig myndighet."</string>
-    <string name="ssl_error_mismatch" msgid="3060364165934822383">"Navnet på nettstedet samsvarer ikke med navnet på sertifikatet."</string>
-    <string name="ssl_error_expired" msgid="1501588340716182495">"Sertifikatet er utløpt."</string>
-    <string name="ssl_error_not_yet_valid" msgid="8648649030525886924">"Sertifikatet er ikke gyldig ennå."</string>
-    <string name="ssl_error_date_invalid" msgid="88425990680059223">"Dette sertifikatet har en ugyldig dato."</string>
-    <string name="ssl_error_invalid" msgid="2540546515565633432">"Dette sertifikatet er ugyldig."</string>
-    <string name="ssl_error_unknown" msgid="4405203446079465859">"Ukjent sertifikatfeil."</string>
-    <string name="ssl_security_warning_title" msgid="8768539813847504404">"Sikkerhetsadvarsel"</string>
-    <string name="ssl_error_view_certificate" msgid="5722652540168339333">"Vis sertifikatet"</string>
-    <string name="ok" msgid="2817931639040794018">"OK"</string>
-    <string name="page_info_address" msgid="1261481517455692363">"Adresse:"</string>
-    <string name="page_info" msgid="4416941086705172545">"Sideinformasjon"</string>
-</resources>
diff --git a/packages/CaptivePortalLogin/res/values-ne/strings.xml b/packages/CaptivePortalLogin/res/values-ne/strings.xml
deleted file mode 100644
index 07d7231..0000000
--- a/packages/CaptivePortalLogin/res/values-ne/strings.xml
+++ /dev/null
@@ -1,24 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="app_name" msgid="5934709770924185752">"CaptivePortalLogin"</string>
-    <string name="action_use_network" msgid="6076184727448466030">"यो सञ्जाल जस्तो छ प्रयोग गर्नुहोस्"</string>
-    <string name="action_do_not_use_network" msgid="4577366536956516683">"यो सञ्जाल प्रयोग नगर्नुहोस्"</string>
-    <string name="action_bar_label" msgid="917235635415966620">"सञ्जालमा साइन इन गर्नुहोस्"</string>
-    <string name="action_bar_title" msgid="5645564790486983117">"%1$s मा साइन इन गर्नुहोस्"</string>
-    <string name="ssl_error_warning" msgid="6653188881418638872">"तपाईँले सामेल हुन प्रयास गरिरहनु भएको नेटवर्कमा सुरक्षा मुद्दाहरू छन्।"</string>
-    <string name="ssl_error_example" msgid="647898534624078900">"उदाहरणका लागि, लग इन पृष्ठ देखाइएको संस्थाको नहुन सक्छ।"</string>
-    <string name="ssl_error_continue" msgid="6492718244923937110">"जे भए पनि ब्राउजर मार्फत जारी राख्नुहोस्"</string>
-    <string name="ssl_error_untrusted" msgid="1496280318271264520">"यो विश्वसनीय प्राधिकरणबाट उपलब्ध गराइएको प्रमाणपत्र होइन।"</string>
-    <string name="ssl_error_mismatch" msgid="3060364165934822383">"प्रमाणपत्रमा भएको नाम साइटमा भएको नामसँग मेल खाँदैन।"</string>
-    <string name="ssl_error_expired" msgid="1501588340716182495">"यो प्रमाणपत्रको म्याद समाप्त भयो।"</string>
-    <string name="ssl_error_not_yet_valid" msgid="8648649030525886924">"यो प्रमाणपत्र अझै मान्य छैन।"</string>
-    <string name="ssl_error_date_invalid" msgid="88425990680059223">"यो प्रमाणपत्रमा कुनै अमान्य मिति छ।"</string>
-    <string name="ssl_error_invalid" msgid="2540546515565633432">"यो प्रमाणपत्र अमान्य छ।"</string>
-    <string name="ssl_error_unknown" msgid="4405203446079465859">"प्रमाणपत्रसम्बन्धी अज्ञात त्रुटि।"</string>
-    <string name="ssl_security_warning_title" msgid="8768539813847504404">"सुरक्षासम्बन्धी चेतावनी"</string>
-    <string name="ssl_error_view_certificate" msgid="5722652540168339333">"प्रमाणपत्र हेर्नुहोस्‌"</string>
-    <string name="ok" msgid="2817931639040794018">"ठिक छ"</string>
-    <string name="page_info_address" msgid="1261481517455692363">"ठेगाना:"</string>
-    <string name="page_info" msgid="4416941086705172545">"पृष्ठको जानकारी"</string>
-</resources>
diff --git a/packages/CaptivePortalLogin/res/values-nl/strings.xml b/packages/CaptivePortalLogin/res/values-nl/strings.xml
deleted file mode 100644
index a4df7b7..0000000
--- a/packages/CaptivePortalLogin/res/values-nl/strings.xml
+++ /dev/null
@@ -1,24 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="app_name" msgid="5934709770924185752">"CaptivePortalLogin"</string>
-    <string name="action_use_network" msgid="6076184727448466030">"Dit netwerk in de huidige staat gebruiken"</string>
-    <string name="action_do_not_use_network" msgid="4577366536956516683">"Dit netwerk niet gebruiken"</string>
-    <string name="action_bar_label" msgid="917235635415966620">"Inloggen bij netwerk"</string>
-    <string name="action_bar_title" msgid="5645564790486983117">"Inloggen bij %1$s"</string>
-    <string name="ssl_error_warning" msgid="6653188881418638872">"Het netwerk waarmee u verbinding probeert te maken, heeft beveiligingsproblemen."</string>
-    <string name="ssl_error_example" msgid="647898534624078900">"Zo hoort de weergegeven inlogpagina misschien niet bij de weergegeven organisatie."</string>
-    <string name="ssl_error_continue" msgid="6492718244923937110">"Toch doorgaan via browser"</string>
-    <string name="ssl_error_untrusted" msgid="1496280318271264520">"Dit is geen certificaat van een vertrouwde autoriteit."</string>
-    <string name="ssl_error_mismatch" msgid="3060364165934822383">"De naam van deze site komt niet overeen met de naam op het certificaat."</string>
-    <string name="ssl_error_expired" msgid="1501588340716182495">"Dit certificaat is verlopen."</string>
-    <string name="ssl_error_not_yet_valid" msgid="8648649030525886924">"Dit certificaat is nog niet geldig."</string>
-    <string name="ssl_error_date_invalid" msgid="88425990680059223">"Dit certificaat heeft een ongeldige datum."</string>
-    <string name="ssl_error_invalid" msgid="2540546515565633432">"Dit certificaat is ongeldig."</string>
-    <string name="ssl_error_unknown" msgid="4405203446079465859">"Onbekende certificaatfout."</string>
-    <string name="ssl_security_warning_title" msgid="8768539813847504404">"Beveiligingswaarschuwing"</string>
-    <string name="ssl_error_view_certificate" msgid="5722652540168339333">"Certificaat weergeven"</string>
-    <string name="ok" msgid="2817931639040794018">"OK"</string>
-    <string name="page_info_address" msgid="1261481517455692363">"Adres:"</string>
-    <string name="page_info" msgid="4416941086705172545">"Paginagegevens"</string>
-</resources>
diff --git a/packages/CaptivePortalLogin/res/values-or/strings.xml b/packages/CaptivePortalLogin/res/values-or/strings.xml
deleted file mode 100644
index f4c5dac..0000000
--- a/packages/CaptivePortalLogin/res/values-or/strings.xml
+++ /dev/null
@@ -1,24 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="app_name" msgid="5934709770924185752">"CaptivePortalLogin"</string>
-    <string name="action_use_network" msgid="6076184727448466030">"ଏହି ନେଟ୍‌ୱର୍କ ଯେପରି ଅଛି, ସେହିପରି ବ୍ୟବହାର କରନ୍ତୁ"</string>
-    <string name="action_do_not_use_network" msgid="4577366536956516683">"ଏହି ନେଟ୍‌ୱର୍କକୁ ବ୍ୟବହାର କରନ୍ତୁ ନାହିଁ"</string>
-    <string name="action_bar_label" msgid="917235635415966620">"ନେଟ୍‌ୱର୍କରେ ସାଇନ୍‍ ଇନ୍‍ କରନ୍ତୁ"</string>
-    <string name="action_bar_title" msgid="5645564790486983117">"%1$sରେ ସାଇନ୍‍-ଇନ୍‍ କରନ୍ତୁ"</string>
-    <string name="ssl_error_warning" msgid="6653188881418638872">"ଆପଣ ଯୋଗ ଦେବାକୁ ଚେଷ୍ଟା କରୁଥିବା ନେଟ୍‌ୱର୍କର ସୁରକ୍ଷା ସମସ୍ୟା ଅଛି।"</string>
-    <string name="ssl_error_example" msgid="647898534624078900">"ଉଦାହରଣସ୍ୱରୂପ, ଲଗଇନ୍‍ ପୃଷ୍ଠା ଦେଖାଯାଇଥିବା ସଂସ୍ଥାର ନହୋଇଥାଇପାରେ।"</string>
-    <string name="ssl_error_continue" msgid="6492718244923937110">"ବ୍ରାଉଜର୍‍ ଜରିଆରେ ଯେମିତିବି ହେଉ ଜାରି ରଖନ୍ତୁ"</string>
-    <string name="ssl_error_untrusted" msgid="1496280318271264520">"ଏହି ସାର୍ଟିଫିକେଟ୍‍ ଏକ ବିଶ୍ବସ୍ତ କର୍ତ୍ତୃପକ୍ଷଙ୍କ ଠାରୁ ନୁହେଁ।"</string>
-    <string name="ssl_error_mismatch" msgid="3060364165934822383">"ସାଇଟ୍‍ର ନାମ ସାର୍ଟିଫିକେଟ୍‍‍‍‍ର ନାମ ସହ ମିଶୁ ନାହିଁ।"</string>
-    <string name="ssl_error_expired" msgid="1501588340716182495">"ଏହି ସାର୍ଟିଫିକେଟ୍‍ ସମୟସୀମା ଶେଷ ହୋଇଛି।"</string>
-    <string name="ssl_error_not_yet_valid" msgid="8648649030525886924">"ଏହି ସାର୍ଟିଫିକେଟ୍‍ ବର୍ତ୍ତମାନ ପର୍ଯ୍ୟନ୍ତ ବୈଧ ନୁହେଁ।"</string>
-    <string name="ssl_error_date_invalid" msgid="88425990680059223">"ଏହି ସାର୍ଟିଫିକେଟ୍‍‍‍‍‍ରେ ଏକ ଅବୈଧ ତାରିଖ ରହିଛି।"</string>
-    <string name="ssl_error_invalid" msgid="2540546515565633432">"ଏହି ସାର୍ଟିଫିକେଟ୍‍ ବୈଧ ନୁହେଁ।"</string>
-    <string name="ssl_error_unknown" msgid="4405203446079465859">"ଅଜଣା ସାର୍ଟିଫିକେଟ୍‍ ତ୍ରୁଟି।"</string>
-    <string name="ssl_security_warning_title" msgid="8768539813847504404">"ସୁରକ୍ଷା ଚେତାବନୀ"</string>
-    <string name="ssl_error_view_certificate" msgid="5722652540168339333">"ସାର୍ଟିଫିକେଟ୍‍ ଦେଖନ୍ତୁ"</string>
-    <string name="ok" msgid="2817931639040794018">"ଠିକ୍‍ ଅଛି"</string>
-    <string name="page_info_address" msgid="1261481517455692363">"ଠିକଣା:"</string>
-    <string name="page_info" msgid="4416941086705172545">"ପୃଷ୍ଠା ସୂଚନା"</string>
-</resources>
diff --git a/packages/CaptivePortalLogin/res/values-pa/strings.xml b/packages/CaptivePortalLogin/res/values-pa/strings.xml
deleted file mode 100644
index b0d6187..0000000
--- a/packages/CaptivePortalLogin/res/values-pa/strings.xml
+++ /dev/null
@@ -1,24 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="app_name" msgid="5934709770924185752">"CaptivePortalLogin"</string>
-    <string name="action_use_network" msgid="6076184727448466030">"ਇਸ ਨੈੱਟਵਰਕ ਨੂੰ ਉਵੇਂ ਵਰਤੋ ਜਿਵੇਂ ਇਹ ਹੈ"</string>
-    <string name="action_do_not_use_network" msgid="4577366536956516683">"ਇਹ ਨੈੱਟਵਰਕ ਨਾ ਵਰਤੋ"</string>
-    <string name="action_bar_label" msgid="917235635415966620">"ਨੈੱਟਵਰਕ \'ਤੇ ਸਾਈਨ-ਇਨ ਕਰੋ"</string>
-    <string name="action_bar_title" msgid="5645564790486983117">"%1$s \'ਤੇ ਸਾਈਨ-ਇਨ ਕਰੋ"</string>
-    <string name="ssl_error_warning" msgid="6653188881418638872">"ਤੁਹਾਡੇ ਦੁਆਰਾ ਸ਼ਾਮਿਲ ਹੋਣ ਦੀ ਕੋਸ਼ਿਸ਼ ਕੀਤੇ ਜਾ ਰਹੇ ਨੈੱਟਵਰਕ ਵਿੱਚ ਸੁਰੱਖਿਆ ਸੰਬੰਧੀ ਸਮੱਸਿਆਵਾਂ ਹਨ।"</string>
-    <string name="ssl_error_example" msgid="647898534624078900">"ਉਦਾਹਰਣ ਵੱਜੋਂ, ਲੌਗ-ਇਨ ਪੰਨਾ ਦਿਖਾਈ ਗਈ ਸੰਸਥਾ ਨਾਲ ਸੰਬੰਧਿਤ ਨਹੀਂ ਹੋ ਸਕਦਾ ਹੈ।"</string>
-    <string name="ssl_error_continue" msgid="6492718244923937110">"ਬ੍ਰਾਊਜ਼ਰ ਰਾਹੀਂ ਫਿਰ ਵੀ ਜਾਰੀ ਰੱਖੋ"</string>
-    <string name="ssl_error_untrusted" msgid="1496280318271264520">"ਇਹ ਪ੍ਰਮਾਣ-ਪੱਤਰ ਕਿਸੇ ਭਰੋਸੇਯੋਗ ਅਥਾਰਿਟੀ ਦਾ ਨਹੀਂ ਹੈ।"</string>
-    <string name="ssl_error_mismatch" msgid="3060364165934822383">"ਸਾਈਟ ਦਾ ਨਾਮ ਪ੍ਰਮਾਣ-ਪੱਤਰ \'ਤੇ ਦਿੱਤੇ ਨਾਮ ਨਾਲ ਮੇਲ ਨਹੀਂ ਖਾਂਦਾ ਹੈ।"</string>
-    <string name="ssl_error_expired" msgid="1501588340716182495">"ਇਸ ਪ੍ਰਮਾਣ-ਪੱਤਰ ਦੀ ਮਿਆਦ ਸਮਾਪਤ ਹੋ ਗਈ ਹੈ।"</string>
-    <string name="ssl_error_not_yet_valid" msgid="8648649030525886924">"ਇਹ ਪ੍ਰਮਾਣ-ਪੱਤਰ ਹਾਲੇ ਵੈਧ ਨਹੀਂ ਹੈ।"</string>
-    <string name="ssl_error_date_invalid" msgid="88425990680059223">"ਇਸ ਪ੍ਰਮਾਣ-ਪੱਤਰ ਦੀ ਤਾਰੀਖ ਅਵੈਧ ਹੈ।"</string>
-    <string name="ssl_error_invalid" msgid="2540546515565633432">"ਇਹ ਪ੍ਰਮਾਣ-ਪੱਤਰ ਅਵੈਧ ਹੈ।"</string>
-    <string name="ssl_error_unknown" msgid="4405203446079465859">"ਅਗਿਆਤ ਪ੍ਰਮਾਣ-ਪੱਤਰ ਗੜਬੜ।"</string>
-    <string name="ssl_security_warning_title" msgid="8768539813847504404">"ਸੁਰੱਖਿਆ ਚਿਤਾਵਨੀ"</string>
-    <string name="ssl_error_view_certificate" msgid="5722652540168339333">"ਪ੍ਰਮਾਣ-ਪੱਤਰ ਦੇਖੋ"</string>
-    <string name="ok" msgid="2817931639040794018">"ਠੀਕ ਹੈ"</string>
-    <string name="page_info_address" msgid="1261481517455692363">"ਪਤਾ:"</string>
-    <string name="page_info" msgid="4416941086705172545">"ਪੰਨੇ ਦੀ ਜਾਣਕਾਰੀ"</string>
-</resources>
diff --git a/packages/CaptivePortalLogin/res/values-pl/strings.xml b/packages/CaptivePortalLogin/res/values-pl/strings.xml
deleted file mode 100644
index 178734d..0000000
--- a/packages/CaptivePortalLogin/res/values-pl/strings.xml
+++ /dev/null
@@ -1,24 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="app_name" msgid="5934709770924185752">"CaptivePortalLogin"</string>
-    <string name="action_use_network" msgid="6076184727448466030">"Używaj tej sieci tak jak jest"</string>
-    <string name="action_do_not_use_network" msgid="4577366536956516683">"Nie używaj tej sieci"</string>
-    <string name="action_bar_label" msgid="917235635415966620">"Zaloguj się do sieci"</string>
-    <string name="action_bar_title" msgid="5645564790486983117">"Zaloguj się w aplikacji %1$s"</string>
-    <string name="ssl_error_warning" msgid="6653188881418638872">"W sieci, z którą próbujesz się połączyć, występują problemy z zabezpieczeniami."</string>
-    <string name="ssl_error_example" msgid="647898534624078900">"Na przykład strona logowania może nie należeć do wyświetlanej organizacji."</string>
-    <string name="ssl_error_continue" msgid="6492718244923937110">"Kontynuuj mimo to w przeglądarce"</string>
-    <string name="ssl_error_untrusted" msgid="1496280318271264520">"Certyfikat nie pochodzi od zaufanego urzędu."</string>
-    <string name="ssl_error_mismatch" msgid="3060364165934822383">"Nazwa witryny nie pasuje do nazwy na certyfikacie."</string>
-    <string name="ssl_error_expired" msgid="1501588340716182495">"Certyfikat wygasł."</string>
-    <string name="ssl_error_not_yet_valid" msgid="8648649030525886924">"Certyfikat nie jest jeszcze ważny."</string>
-    <string name="ssl_error_date_invalid" msgid="88425990680059223">"Certyfikat ma nieprawidłową datę."</string>
-    <string name="ssl_error_invalid" msgid="2540546515565633432">"Certyfikat jest nieprawidłowy."</string>
-    <string name="ssl_error_unknown" msgid="4405203446079465859">"Nieznany błąd certyfikatu."</string>
-    <string name="ssl_security_warning_title" msgid="8768539813847504404">"Ostrzeżenie dotyczące bezpieczeństwa"</string>
-    <string name="ssl_error_view_certificate" msgid="5722652540168339333">"Wyświetl certyfikat"</string>
-    <string name="ok" msgid="2817931639040794018">"OK"</string>
-    <string name="page_info_address" msgid="1261481517455692363">"Adres:"</string>
-    <string name="page_info" msgid="4416941086705172545">"Informacje o stronie"</string>
-</resources>
diff --git a/packages/CaptivePortalLogin/res/values-pt-rBR/strings.xml b/packages/CaptivePortalLogin/res/values-pt-rBR/strings.xml
deleted file mode 100644
index 3aa82c4..0000000
--- a/packages/CaptivePortalLogin/res/values-pt-rBR/strings.xml
+++ /dev/null
@@ -1,24 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="app_name" msgid="5934709770924185752">"CaptivePortalLogin"</string>
-    <string name="action_use_network" msgid="6076184727448466030">"Usar esta rede como está"</string>
-    <string name="action_do_not_use_network" msgid="4577366536956516683">"Não usar esta rede"</string>
-    <string name="action_bar_label" msgid="917235635415966620">"Fazer login na rede"</string>
-    <string name="action_bar_title" msgid="5645564790486983117">"Fazer login em %1$s"</string>
-    <string name="ssl_error_warning" msgid="6653188881418638872">"A rede à qual você está tentando se conectar tem problemas de segurança."</string>
-    <string name="ssl_error_example" msgid="647898534624078900">"Por exemplo, a página de login pode não pertencer à organização mostrada."</string>
-    <string name="ssl_error_continue" msgid="6492718244923937110">"Continuar mesmo assim pelo navegador"</string>
-    <string name="ssl_error_untrusted" msgid="1496280318271264520">"Esse certificado não é de uma autoridade confiável."</string>
-    <string name="ssl_error_mismatch" msgid="3060364165934822383">"O nome do site não corresponde ao nome no certificado."</string>
-    <string name="ssl_error_expired" msgid="1501588340716182495">"Esse certificado expirou."</string>
-    <string name="ssl_error_not_yet_valid" msgid="8648649030525886924">"Esse certificado ainda não é válido."</string>
-    <string name="ssl_error_date_invalid" msgid="88425990680059223">"A data desse certificado é inválida."</string>
-    <string name="ssl_error_invalid" msgid="2540546515565633432">"Esse certificado é inválido."</string>
-    <string name="ssl_error_unknown" msgid="4405203446079465859">"Erro de certificado desconhecido."</string>
-    <string name="ssl_security_warning_title" msgid="8768539813847504404">"Aviso de segurança"</string>
-    <string name="ssl_error_view_certificate" msgid="5722652540168339333">"Ver certificado"</string>
-    <string name="ok" msgid="2817931639040794018">"OK"</string>
-    <string name="page_info_address" msgid="1261481517455692363">"Endereço:"</string>
-    <string name="page_info" msgid="4416941086705172545">"Informações da página"</string>
-</resources>
diff --git a/packages/CaptivePortalLogin/res/values-pt-rPT/strings.xml b/packages/CaptivePortalLogin/res/values-pt-rPT/strings.xml
deleted file mode 100644
index 72d62a3..0000000
--- a/packages/CaptivePortalLogin/res/values-pt-rPT/strings.xml
+++ /dev/null
@@ -1,24 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="app_name" msgid="5934709770924185752">"CaptivePortalLogin"</string>
-    <string name="action_use_network" msgid="6076184727448466030">"Utilizar esta rede como está"</string>
-    <string name="action_do_not_use_network" msgid="4577366536956516683">"Não utilizar esta rede"</string>
-    <string name="action_bar_label" msgid="917235635415966620">"Início de sessão na rede"</string>
-    <string name="action_bar_title" msgid="5645564790486983117">"Iniciar sessão em %1$s"</string>
-    <string name="ssl_error_warning" msgid="6653188881418638872">"A rede à qual está a tentar aceder tem problemas de segurança."</string>
-    <string name="ssl_error_example" msgid="647898534624078900">"Por exemplo, a página de início de sessão pode não pertencer à entidade apresentada."</string>
-    <string name="ssl_error_continue" msgid="6492718244923937110">"Continuar mesmo assim através do navegador"</string>
-    <string name="ssl_error_untrusted" msgid="1496280318271264520">"Este certificado não pertence a uma autoridade fidedigna."</string>
-    <string name="ssl_error_mismatch" msgid="3060364165934822383">"O nome do site não corresponde ao nome constante no certificado."</string>
-    <string name="ssl_error_expired" msgid="1501588340716182495">"Este certificado expirou."</string>
-    <string name="ssl_error_not_yet_valid" msgid="8648649030525886924">"Este certificado ainda não é válido."</string>
-    <string name="ssl_error_date_invalid" msgid="88425990680059223">"Este certificado tem uma data inválida."</string>
-    <string name="ssl_error_invalid" msgid="2540546515565633432">"Este certificado é inválido."</string>
-    <string name="ssl_error_unknown" msgid="4405203446079465859">"Erro de certificado desconhecido."</string>
-    <string name="ssl_security_warning_title" msgid="8768539813847504404">"Aviso de segurança"</string>
-    <string name="ssl_error_view_certificate" msgid="5722652540168339333">"Ver certificado"</string>
-    <string name="ok" msgid="2817931639040794018">"OK"</string>
-    <string name="page_info_address" msgid="1261481517455692363">"Endereço:"</string>
-    <string name="page_info" msgid="4416941086705172545">"Informações da página"</string>
-</resources>
diff --git a/packages/CaptivePortalLogin/res/values-pt/strings.xml b/packages/CaptivePortalLogin/res/values-pt/strings.xml
deleted file mode 100644
index 3aa82c4..0000000
--- a/packages/CaptivePortalLogin/res/values-pt/strings.xml
+++ /dev/null
@@ -1,24 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="app_name" msgid="5934709770924185752">"CaptivePortalLogin"</string>
-    <string name="action_use_network" msgid="6076184727448466030">"Usar esta rede como está"</string>
-    <string name="action_do_not_use_network" msgid="4577366536956516683">"Não usar esta rede"</string>
-    <string name="action_bar_label" msgid="917235635415966620">"Fazer login na rede"</string>
-    <string name="action_bar_title" msgid="5645564790486983117">"Fazer login em %1$s"</string>
-    <string name="ssl_error_warning" msgid="6653188881418638872">"A rede à qual você está tentando se conectar tem problemas de segurança."</string>
-    <string name="ssl_error_example" msgid="647898534624078900">"Por exemplo, a página de login pode não pertencer à organização mostrada."</string>
-    <string name="ssl_error_continue" msgid="6492718244923937110">"Continuar mesmo assim pelo navegador"</string>
-    <string name="ssl_error_untrusted" msgid="1496280318271264520">"Esse certificado não é de uma autoridade confiável."</string>
-    <string name="ssl_error_mismatch" msgid="3060364165934822383">"O nome do site não corresponde ao nome no certificado."</string>
-    <string name="ssl_error_expired" msgid="1501588340716182495">"Esse certificado expirou."</string>
-    <string name="ssl_error_not_yet_valid" msgid="8648649030525886924">"Esse certificado ainda não é válido."</string>
-    <string name="ssl_error_date_invalid" msgid="88425990680059223">"A data desse certificado é inválida."</string>
-    <string name="ssl_error_invalid" msgid="2540546515565633432">"Esse certificado é inválido."</string>
-    <string name="ssl_error_unknown" msgid="4405203446079465859">"Erro de certificado desconhecido."</string>
-    <string name="ssl_security_warning_title" msgid="8768539813847504404">"Aviso de segurança"</string>
-    <string name="ssl_error_view_certificate" msgid="5722652540168339333">"Ver certificado"</string>
-    <string name="ok" msgid="2817931639040794018">"OK"</string>
-    <string name="page_info_address" msgid="1261481517455692363">"Endereço:"</string>
-    <string name="page_info" msgid="4416941086705172545">"Informações da página"</string>
-</resources>
diff --git a/packages/CaptivePortalLogin/res/values-ro/strings.xml b/packages/CaptivePortalLogin/res/values-ro/strings.xml
deleted file mode 100644
index e3fc191..0000000
--- a/packages/CaptivePortalLogin/res/values-ro/strings.xml
+++ /dev/null
@@ -1,24 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="app_name" msgid="5934709770924185752">"CaptivePortalLogin"</string>
-    <string name="action_use_network" msgid="6076184727448466030">"Utilizați această rețea în starea actuală"</string>
-    <string name="action_do_not_use_network" msgid="4577366536956516683">"Nu utilizați această rețea"</string>
-    <string name="action_bar_label" msgid="917235635415966620">"Conectați-vă la rețea"</string>
-    <string name="action_bar_title" msgid="5645564790486983117">"Conectați-vă la %1$s"</string>
-    <string name="ssl_error_warning" msgid="6653188881418638872">"Rețeaua la care încercați să vă conectați are probleme de securitate."</string>
-    <string name="ssl_error_example" msgid="647898534624078900">"De exemplu, este posibil ca pagina de conectare să nu aparțină organizației afișate."</string>
-    <string name="ssl_error_continue" msgid="6492718244923937110">"Continuați oricum prin browser"</string>
-    <string name="ssl_error_untrusted" msgid="1496280318271264520">"Acest certificat nu provine de la o autoritate de încredere."</string>
-    <string name="ssl_error_mismatch" msgid="3060364165934822383">"Numele acestui site nu se potrivește cu numele de pe certificat."</string>
-    <string name="ssl_error_expired" msgid="1501588340716182495">"Acest certificat a expirat."</string>
-    <string name="ssl_error_not_yet_valid" msgid="8648649030525886924">"Acest certificat nu este încă valid."</string>
-    <string name="ssl_error_date_invalid" msgid="88425990680059223">"Acest certificat are o dată nevalidă."</string>
-    <string name="ssl_error_invalid" msgid="2540546515565633432">"Acest certificat este nevalid."</string>
-    <string name="ssl_error_unknown" msgid="4405203446079465859">"Eroare de certificat necunoscută."</string>
-    <string name="ssl_security_warning_title" msgid="8768539813847504404">"Avertisment de securitate"</string>
-    <string name="ssl_error_view_certificate" msgid="5722652540168339333">"Vizualizați certificatul"</string>
-    <string name="ok" msgid="2817931639040794018">"OK"</string>
-    <string name="page_info_address" msgid="1261481517455692363">"Adresă:"</string>
-    <string name="page_info" msgid="4416941086705172545">"Informații despre pagină"</string>
-</resources>
diff --git a/packages/CaptivePortalLogin/res/values-ru/strings.xml b/packages/CaptivePortalLogin/res/values-ru/strings.xml
deleted file mode 100644
index a976f57..0000000
--- a/packages/CaptivePortalLogin/res/values-ru/strings.xml
+++ /dev/null
@@ -1,24 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="app_name" msgid="5934709770924185752">"CaptivePortalLogin"</string>
-    <string name="action_use_network" msgid="6076184727448466030">"Использовать эту сеть"</string>
-    <string name="action_do_not_use_network" msgid="4577366536956516683">"Не использовать эту сеть"</string>
-    <string name="action_bar_label" msgid="917235635415966620">"Регистрация в сети"</string>
-    <string name="action_bar_title" msgid="5645564790486983117">"Войти: %1$s"</string>
-    <string name="ssl_error_warning" msgid="6653188881418638872">"Сеть, к которой вы хотите подключиться, небезопасна."</string>
-    <string name="ssl_error_example" msgid="647898534624078900">"Например, страница входа в аккаунт может быть фиктивной."</string>
-    <string name="ssl_error_continue" msgid="6492718244923937110">"Игнорировать и открыть браузер"</string>
-    <string name="ssl_error_untrusted" msgid="1496280318271264520">"Этот сертификат получен из ненадежных источников."</string>
-    <string name="ssl_error_mismatch" msgid="3060364165934822383">"Название сайта отличается от указанного в сертификате."</string>
-    <string name="ssl_error_expired" msgid="1501588340716182495">"Срок действия сертификата истек."</string>
-    <string name="ssl_error_not_yet_valid" msgid="8648649030525886924">"Сертификат ещё не действителен."</string>
-    <string name="ssl_error_date_invalid" msgid="88425990680059223">"Дата сертификата недействительна."</string>
-    <string name="ssl_error_invalid" msgid="2540546515565633432">"Сертификат недействителен."</string>
-    <string name="ssl_error_unknown" msgid="4405203446079465859">"Неизвестная ошибка, связанная с сертификатом."</string>
-    <string name="ssl_security_warning_title" msgid="8768539813847504404">"Предупреждение об опасности"</string>
-    <string name="ssl_error_view_certificate" msgid="5722652540168339333">"Показать сертификат"</string>
-    <string name="ok" msgid="2817931639040794018">"ОК"</string>
-    <string name="page_info_address" msgid="1261481517455692363">"Адрес:"</string>
-    <string name="page_info" msgid="4416941086705172545">"О странице"</string>
-</resources>
diff --git a/packages/CaptivePortalLogin/res/values-si/strings.xml b/packages/CaptivePortalLogin/res/values-si/strings.xml
deleted file mode 100644
index edfe716..0000000
--- a/packages/CaptivePortalLogin/res/values-si/strings.xml
+++ /dev/null
@@ -1,24 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="app_name" msgid="5934709770924185752">"CaptivePortalLogin"</string>
-    <string name="action_use_network" msgid="6076184727448466030">"මෙම ජාලය ලෙසම භාවිතා කරන්න"</string>
-    <string name="action_do_not_use_network" msgid="4577366536956516683">"මෙම ජාලය භාවිතා කරන්න එපා"</string>
-    <string name="action_bar_label" msgid="917235635415966620">"ජාලයට පුරනය වන්න"</string>
-    <string name="action_bar_title" msgid="5645564790486983117">"%1$s වෙත පුරන්න"</string>
-    <string name="ssl_error_warning" msgid="6653188881418638872">"ඔබ සම්බන්ධ වීමට උත්සහ කරන ජාලයේ ආරක්ෂක ගැටළු ඇත."</string>
-    <string name="ssl_error_example" msgid="647898534624078900">"උදාහරණයක් ලෙස, පුරනය වන පිටුව පෙන්වා ඇති සංවිධානයට අයිති නැති විය හැක."</string>
-    <string name="ssl_error_continue" msgid="6492718244923937110">"කෙසේ වුවත් බ්‍රවුසරය හරහා ඉදිරියට යන්න"</string>
-    <string name="ssl_error_untrusted" msgid="1496280318271264520">"මෙම සහතිකය විශ්වාසී අධිකාරියකින් නොවේ."</string>
-    <string name="ssl_error_mismatch" msgid="3060364165934822383">"අඩවියේ නම සහතිකයේ නමට නොගැළපේ."</string>
-    <string name="ssl_error_expired" msgid="1501588340716182495">"මෙම සහතිකය කල් ඉකුත් වී ඇත."</string>
-    <string name="ssl_error_not_yet_valid" msgid="8648649030525886924">"මෙම සහතිකය තවම වලංගු නැත."</string>
-    <string name="ssl_error_date_invalid" msgid="88425990680059223">"මෙම සහතිකයට වලංගු නොවන දිනයක් ඇත."</string>
-    <string name="ssl_error_invalid" msgid="2540546515565633432">"මෙම සහතිකය වලංගු නොවේ."</string>
-    <string name="ssl_error_unknown" msgid="4405203446079465859">"නොදන්නා සහතික දෝෂයකි."</string>
-    <string name="ssl_security_warning_title" msgid="8768539813847504404">"ආරක්ෂක අවවාදයයි"</string>
-    <string name="ssl_error_view_certificate" msgid="5722652540168339333">"සහතිකය බලන්න"</string>
-    <string name="ok" msgid="2817931639040794018">"හරි"</string>
-    <string name="page_info_address" msgid="1261481517455692363">"ලිපිනය:"</string>
-    <string name="page_info" msgid="4416941086705172545">"පිටු තොරතුරු"</string>
-</resources>
diff --git a/packages/CaptivePortalLogin/res/values-sk/strings.xml b/packages/CaptivePortalLogin/res/values-sk/strings.xml
deleted file mode 100644
index c1100b8..0000000
--- a/packages/CaptivePortalLogin/res/values-sk/strings.xml
+++ /dev/null
@@ -1,24 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="app_name" msgid="5934709770924185752">"CaptivePortalLogin"</string>
-    <string name="action_use_network" msgid="6076184727448466030">"Použiť túto sieť tak, ako je"</string>
-    <string name="action_do_not_use_network" msgid="4577366536956516683">"Túto sieť nepoužívať"</string>
-    <string name="action_bar_label" msgid="917235635415966620">"Prihlásiť sa do siete"</string>
-    <string name="action_bar_title" msgid="5645564790486983117">"Prihláste sa do služby %1$s"</string>
-    <string name="ssl_error_warning" msgid="6653188881418638872">"Sieť, ku ktorej sa pokúšate pripojiť, má problémy so zabezpečením"</string>
-    <string name="ssl_error_example" msgid="647898534624078900">"Napríklad prihlasovacia stránka nemusí patriť uvedenej organizácii."</string>
-    <string name="ssl_error_continue" msgid="6492718244923937110">"Pokračovať pomocou prehliadača"</string>
-    <string name="ssl_error_untrusted" msgid="1496280318271264520">"Tento certifikát nepochádza od dôveryhodnej autority."</string>
-    <string name="ssl_error_mismatch" msgid="3060364165934822383">"Názov stránky sa nezhoduje s názvom uvedeným v certifikáte."</string>
-    <string name="ssl_error_expired" msgid="1501588340716182495">"Platnosť certifikátu skončila."</string>
-    <string name="ssl_error_not_yet_valid" msgid="8648649030525886924">"Tento certifikát zatiaľ nie je platný."</string>
-    <string name="ssl_error_date_invalid" msgid="88425990680059223">"Tento certifikát má neplatný dátum."</string>
-    <string name="ssl_error_invalid" msgid="2540546515565633432">"Tento certifikát je neplatný."</string>
-    <string name="ssl_error_unknown" msgid="4405203446079465859">"Neznáma chyba certifikátu."</string>
-    <string name="ssl_security_warning_title" msgid="8768539813847504404">"Bezpečnostné upozornenie"</string>
-    <string name="ssl_error_view_certificate" msgid="5722652540168339333">"Zobraziť certifikát"</string>
-    <string name="ok" msgid="2817931639040794018">"OK"</string>
-    <string name="page_info_address" msgid="1261481517455692363">"Adresa:"</string>
-    <string name="page_info" msgid="4416941086705172545">"Informácie o stránke"</string>
-</resources>
diff --git a/packages/CaptivePortalLogin/res/values-sl/strings.xml b/packages/CaptivePortalLogin/res/values-sl/strings.xml
deleted file mode 100644
index b254240..0000000
--- a/packages/CaptivePortalLogin/res/values-sl/strings.xml
+++ /dev/null
@@ -1,24 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="app_name" msgid="5934709770924185752">"CaptivePortalLogin"</string>
-    <string name="action_use_network" msgid="6076184727448466030">"Uporabljajte to omrežje, »kakršno je«"</string>
-    <string name="action_do_not_use_network" msgid="4577366536956516683">"Ne uporabljajte tega omrežja"</string>
-    <string name="action_bar_label" msgid="917235635415966620">"Prijavite se v omrežje"</string>
-    <string name="action_bar_title" msgid="5645564790486983117">"Prijava v %1$s"</string>
-    <string name="ssl_error_warning" msgid="6653188881418638872">"Omrežje, ki se mu poskušate pridružiti, ima varnostne težave."</string>
-    <string name="ssl_error_example" msgid="647898534624078900">"Stran za prijavo na primer morda ne pripada prikazani organizaciji."</string>
-    <string name="ssl_error_continue" msgid="6492718244923937110">"Vseeno nadaljuj v brskalniku"</string>
-    <string name="ssl_error_untrusted" msgid="1496280318271264520">"Potrdila ni izdal zaupanja vreden overitelj."</string>
-    <string name="ssl_error_mismatch" msgid="3060364165934822383">"Ime spletnega mesta se ne ujema z imenom na potrdilu."</string>
-    <string name="ssl_error_expired" msgid="1501588340716182495">"Potrdilo je poteklo."</string>
-    <string name="ssl_error_not_yet_valid" msgid="8648649030525886924">"To potrdilo še ni veljavno."</string>
-    <string name="ssl_error_date_invalid" msgid="88425990680059223">"To potrdilo ima neveljaven datum."</string>
-    <string name="ssl_error_invalid" msgid="2540546515565633432">"To potrdilo ni veljavno."</string>
-    <string name="ssl_error_unknown" msgid="4405203446079465859">"Neznana napaka potrdila."</string>
-    <string name="ssl_security_warning_title" msgid="8768539813847504404">"Varnostno opozorilo"</string>
-    <string name="ssl_error_view_certificate" msgid="5722652540168339333">"Prikaži potrdilo"</string>
-    <string name="ok" msgid="2817931639040794018">"V redu"</string>
-    <string name="page_info_address" msgid="1261481517455692363">"Naslov:"</string>
-    <string name="page_info" msgid="4416941086705172545">"Podatki o strani"</string>
-</resources>
diff --git a/packages/CaptivePortalLogin/res/values-sq/strings.xml b/packages/CaptivePortalLogin/res/values-sq/strings.xml
deleted file mode 100644
index a178c40..0000000
--- a/packages/CaptivePortalLogin/res/values-sq/strings.xml
+++ /dev/null
@@ -1,24 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="app_name" msgid="5934709770924185752">"CaptivePortalLogin"</string>
-    <string name="action_use_network" msgid="6076184727448466030">"Përdore këtë rrjet siç është"</string>
-    <string name="action_do_not_use_network" msgid="4577366536956516683">"Mos e përdor këtë rrjet"</string>
-    <string name="action_bar_label" msgid="917235635415966620">"Identifikohu në rrjet"</string>
-    <string name="action_bar_title" msgid="5645564790486983117">"Identifikohu në %1$s"</string>
-    <string name="ssl_error_warning" msgid="6653188881418638872">"Rrjeti në të cilin po përpiqesh të bashkohesh ka probleme sigurie."</string>
-    <string name="ssl_error_example" msgid="647898534624078900">"për shembull, faqja e identifikimit mund të mos i përkasë organizatës së shfaqur."</string>
-    <string name="ssl_error_continue" msgid="6492718244923937110">"Vazhdo gjithsesi nëpërmjet shfletuesit"</string>
-    <string name="ssl_error_untrusted" msgid="1496280318271264520">"Kjo certifikatë nuk është nga një autoritet i besuar."</string>
-    <string name="ssl_error_mismatch" msgid="3060364165934822383">"Emri i sajtit nuk përputhet me emrin në certifikatë."</string>
-    <string name="ssl_error_expired" msgid="1501588340716182495">"Kjo certifikatë ka skaduar."</string>
-    <string name="ssl_error_not_yet_valid" msgid="8648649030525886924">"Kjo certifikatë nuk është ende e vlefshme."</string>
-    <string name="ssl_error_date_invalid" msgid="88425990680059223">"Kjo certifikatë ka një datë të pavlefshme."</string>
-    <string name="ssl_error_invalid" msgid="2540546515565633432">"Kjo certifikatë është e pavlefshme."</string>
-    <string name="ssl_error_unknown" msgid="4405203446079465859">"Gabim i panjohur i certifikatës."</string>
-    <string name="ssl_security_warning_title" msgid="8768539813847504404">"Paralajmërim për sigurinë"</string>
-    <string name="ssl_error_view_certificate" msgid="5722652540168339333">"Shiko certifikatën"</string>
-    <string name="ok" msgid="2817931639040794018">"Në rregull"</string>
-    <string name="page_info_address" msgid="1261481517455692363">"Adresa:"</string>
-    <string name="page_info" msgid="4416941086705172545">"Informacionet e faqes"</string>
-</resources>
diff --git a/packages/CaptivePortalLogin/res/values-sr/strings.xml b/packages/CaptivePortalLogin/res/values-sr/strings.xml
deleted file mode 100644
index 6b08369..0000000
--- a/packages/CaptivePortalLogin/res/values-sr/strings.xml
+++ /dev/null
@@ -1,24 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="app_name" msgid="5934709770924185752">"CaptivePortalLogin"</string>
-    <string name="action_use_network" msgid="6076184727448466030">"Користи ову мрежу такву каква је"</string>
-    <string name="action_do_not_use_network" msgid="4577366536956516683">"Не користи ову мрежу"</string>
-    <string name="action_bar_label" msgid="917235635415966620">"Пријави ме на мрежу"</string>
-    <string name="action_bar_title" msgid="5645564790486983117">"Пријавите се у: %1$s"</string>
-    <string name="ssl_error_warning" msgid="6653188881418638872">"Мрежа којој покушавате да се придружите има безбедносних проблема."</string>
-    <string name="ssl_error_example" msgid="647898534624078900">"На пример, страница за пријављивање можда не припада приказаној организацији."</string>
-    <string name="ssl_error_continue" msgid="6492718244923937110">"Ипак настави преко прегледача"</string>
-    <string name="ssl_error_untrusted" msgid="1496280318271264520">"Овај сертификат не потиче из поузданог извора."</string>
-    <string name="ssl_error_mismatch" msgid="3060364165934822383">"Назив сајта се не подудара са називом на сертификату."</string>
-    <string name="ssl_error_expired" msgid="1501588340716182495">"Овај сертификат је истекао."</string>
-    <string name="ssl_error_not_yet_valid" msgid="8648649030525886924">"Овај сертификат још увек није важећи."</string>
-    <string name="ssl_error_date_invalid" msgid="88425990680059223">"Датум овог сертификата је неважећи."</string>
-    <string name="ssl_error_invalid" msgid="2540546515565633432">"Овај сертификат је неважећи."</string>
-    <string name="ssl_error_unknown" msgid="4405203446079465859">"Непозната грешка сертификата."</string>
-    <string name="ssl_security_warning_title" msgid="8768539813847504404">"Безбедносно упозорење"</string>
-    <string name="ssl_error_view_certificate" msgid="5722652540168339333">"Прикажи сертификат"</string>
-    <string name="ok" msgid="2817931639040794018">"Потврди"</string>
-    <string name="page_info_address" msgid="1261481517455692363">"Адреса:"</string>
-    <string name="page_info" msgid="4416941086705172545">"Информације о страници"</string>
-</resources>
diff --git a/packages/CaptivePortalLogin/res/values-sv/strings.xml b/packages/CaptivePortalLogin/res/values-sv/strings.xml
deleted file mode 100644
index 7fe5432..0000000
--- a/packages/CaptivePortalLogin/res/values-sv/strings.xml
+++ /dev/null
@@ -1,24 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="app_name" msgid="5934709770924185752">"CaptivePortalLogin"</string>
-    <string name="action_use_network" msgid="6076184727448466030">"Använd det här nätverket som det är"</string>
-    <string name="action_do_not_use_network" msgid="4577366536956516683">"Använd inte det här nätverket"</string>
-    <string name="action_bar_label" msgid="917235635415966620">"Logga in på nätverket"</string>
-    <string name="action_bar_title" msgid="5645564790486983117">"Logga in på %1$s"</string>
-    <string name="ssl_error_warning" msgid="6653188881418638872">"Nätverket du försöker ansluta till har säkerhetsproblem."</string>
-    <string name="ssl_error_example" msgid="647898534624078900">"Det kan t.ex. hända att inloggningssidan inte tillhör den organisation som visas."</string>
-    <string name="ssl_error_continue" msgid="6492718244923937110">"Fortsätt ändå via webbläsaren"</string>
-    <string name="ssl_error_untrusted" msgid="1496280318271264520">"Certifikatet kommer inte från en betrodd utfärdare."</string>
-    <string name="ssl_error_mismatch" msgid="3060364165934822383">"Webbplatsens namn matchar inte namnet på certifikatet."</string>
-    <string name="ssl_error_expired" msgid="1501588340716182495">"Det här certifikatet har löpt ut."</string>
-    <string name="ssl_error_not_yet_valid" msgid="8648649030525886924">"Det här certifikatet är inte giltigt än."</string>
-    <string name="ssl_error_date_invalid" msgid="88425990680059223">"Datumet för det här certifikatet är ogiltigt."</string>
-    <string name="ssl_error_invalid" msgid="2540546515565633432">"Det här certifikatet är ogiltigt."</string>
-    <string name="ssl_error_unknown" msgid="4405203446079465859">"Okänt certifikatfel."</string>
-    <string name="ssl_security_warning_title" msgid="8768539813847504404">"Säkerhetsvarning"</string>
-    <string name="ssl_error_view_certificate" msgid="5722652540168339333">"Visa certifikat"</string>
-    <string name="ok" msgid="2817931639040794018">"OK"</string>
-    <string name="page_info_address" msgid="1261481517455692363">"Adress:"</string>
-    <string name="page_info" msgid="4416941086705172545">"Sidinformation"</string>
-</resources>
diff --git a/packages/CaptivePortalLogin/res/values-sw/strings.xml b/packages/CaptivePortalLogin/res/values-sw/strings.xml
deleted file mode 100644
index 297b72d..0000000
--- a/packages/CaptivePortalLogin/res/values-sw/strings.xml
+++ /dev/null
@@ -1,24 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="app_name" msgid="5934709770924185752">"CaptivePortalLogin"</string>
-    <string name="action_use_network" msgid="6076184727448466030">"Tumia mtandao huu jinsi ulivyo"</string>
-    <string name="action_do_not_use_network" msgid="4577366536956516683">"Usitumie mtandao huu"</string>
-    <string name="action_bar_label" msgid="917235635415966620">"Ingia katika mtandao"</string>
-    <string name="action_bar_title" msgid="5645564790486983117">"Ingia katika akaunti ya %1$s"</string>
-    <string name="ssl_error_warning" msgid="6653188881418638872">"Mtandao unaojaribu kujiunga nao una matatizo ya usalama."</string>
-    <string name="ssl_error_example" msgid="647898534624078900">"Kwa mfano, ukurasa wa kuingia katika akaunti unaweza usiwe unamilikiwa na shirika lililoonyeshwa."</string>
-    <string name="ssl_error_continue" msgid="6492718244923937110">"Endelea hata hivyo kupitia kivinjari"</string>
-    <string name="ssl_error_untrusted" msgid="1496280318271264520">"Cheti hiki hakijatoka kwa mamlaka inayoaminika."</string>
-    <string name="ssl_error_mismatch" msgid="3060364165934822383">"Jina la tovuti halilingani na jina lililo katika cheti."</string>
-    <string name="ssl_error_expired" msgid="1501588340716182495">"Muda wa kutumia cheti hiki umeisha."</string>
-    <string name="ssl_error_not_yet_valid" msgid="8648649030525886924">"Cheti hiki bado si halali."</string>
-    <string name="ssl_error_date_invalid" msgid="88425990680059223">"Tarehe ya cheti hiki si sahihi."</string>
-    <string name="ssl_error_invalid" msgid="2540546515565633432">"Cheti hiki si sahihi."</string>
-    <string name="ssl_error_unknown" msgid="4405203446079465859">"Hitilafu isiyojulikana ya cheti."</string>
-    <string name="ssl_security_warning_title" msgid="8768539813847504404">"Ilani ya usalama"</string>
-    <string name="ssl_error_view_certificate" msgid="5722652540168339333">"Angalia cheti"</string>
-    <string name="ok" msgid="2817931639040794018">"Sawa"</string>
-    <string name="page_info_address" msgid="1261481517455692363">"Anwani:"</string>
-    <string name="page_info" msgid="4416941086705172545">"Maelezo ya ukurasa"</string>
-</resources>
diff --git a/packages/CaptivePortalLogin/res/values-ta/strings.xml b/packages/CaptivePortalLogin/res/values-ta/strings.xml
deleted file mode 100644
index 4517d15..0000000
--- a/packages/CaptivePortalLogin/res/values-ta/strings.xml
+++ /dev/null
@@ -1,24 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="app_name" msgid="5934709770924185752">"CaptivePortalLogin"</string>
-    <string name="action_use_network" msgid="6076184727448466030">"இந்த நெட்வொர்க்கைப் பயன்படுத்து"</string>
-    <string name="action_do_not_use_network" msgid="4577366536956516683">"இந்த நெட்வொர்க்கைப் பயன்படுத்த வேண்டாம்"</string>
-    <string name="action_bar_label" msgid="917235635415966620">"நெட்வொர்க்கில் உள்நுழையவும்"</string>
-    <string name="action_bar_title" msgid="5645564790486983117">"%1$s இல் உள்நுழைக"</string>
-    <string name="ssl_error_warning" msgid="6653188881418638872">"நீங்கள் சேர முயற்சிக்கும் நெட்வொர்க்கில் பாதுகாப்புச் சிக்கல்கள் உள்ளன."</string>
-    <string name="ssl_error_example" msgid="647898534624078900">"எடுத்துக்காட்டாக, உள்நுழைவுப் பக்கமானது காட்டப்படும் அமைப்பிற்குச் சொந்தமானதாக இல்லாமல் இருக்கலாம்."</string>
-    <string name="ssl_error_continue" msgid="6492718244923937110">"பரவாயில்லை, உலாவி வழியாகத் தொடரவும்"</string>
-    <string name="ssl_error_untrusted" msgid="1496280318271264520">"இந்தச் சான்றிதழ் நம்பகமான நிறுவனத்தால் அங்கீகரிக்கப்படவில்லை."</string>
-    <string name="ssl_error_mismatch" msgid="3060364165934822383">"சான்றிதழிலுள்ள பெயருடன் வலைதளத்தின் பெயர் பொருந்தவில்லை."</string>
-    <string name="ssl_error_expired" msgid="1501588340716182495">"இந்தச் சான்றிதழ் காலாவதியாகிவிட்டது."</string>
-    <string name="ssl_error_not_yet_valid" msgid="8648649030525886924">"இந்தச் சான்றிதழ் இன்னும் செல்லாததாக உள்ளது."</string>
-    <string name="ssl_error_date_invalid" msgid="88425990680059223">"இந்தச் சான்றிதழில் தவறான தேதி உள்ளது."</string>
-    <string name="ssl_error_invalid" msgid="2540546515565633432">"இந்தச் சான்றிதழ் செல்லாதது."</string>
-    <string name="ssl_error_unknown" msgid="4405203446079465859">"சான்றிதழில் அறியப்படாத பிழை உள்ளது."</string>
-    <string name="ssl_security_warning_title" msgid="8768539813847504404">"பாதுகாப்பு எச்சரிக்கை"</string>
-    <string name="ssl_error_view_certificate" msgid="5722652540168339333">"சான்றிதழைக் காட்டு"</string>
-    <string name="ok" msgid="2817931639040794018">"சரி"</string>
-    <string name="page_info_address" msgid="1261481517455692363">"முகவரி:"</string>
-    <string name="page_info" msgid="4416941086705172545">"பக்கத் தகவல்"</string>
-</resources>
diff --git a/packages/CaptivePortalLogin/res/values-te/strings.xml b/packages/CaptivePortalLogin/res/values-te/strings.xml
deleted file mode 100644
index 9bb4c11..0000000
--- a/packages/CaptivePortalLogin/res/values-te/strings.xml
+++ /dev/null
@@ -1,24 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="app_name" msgid="5934709770924185752">"CaptivePortalLogin"</string>
-    <string name="action_use_network" msgid="6076184727448466030">"ఈ నెట్‌వర్క్‌ని యథావిధిగా ఉపయోగించు"</string>
-    <string name="action_do_not_use_network" msgid="4577366536956516683">"ఈ నెట్‌వర్క్‌ని ఉపయోగించవద్దు"</string>
-    <string name="action_bar_label" msgid="917235635415966620">"నెట్‌వర్క్‌కి సైన్ ఇన్ చేయండి"</string>
-    <string name="action_bar_title" msgid="5645564790486983117">"%1$sకి సైన్ ఇన్ చేయండి"</string>
-    <string name="ssl_error_warning" msgid="6653188881418638872">"మీరు చేరడానికి ప్రయత్నిస్తున్న నెట్‌వర్క్ భద్రతా సమస్యలను కలిగి ఉంది."</string>
-    <string name="ssl_error_example" msgid="647898534624078900">"ఉదాహరణకు, లాగిన్ పేజీ చూపిన సంస్థకు చెందినది కాకపోవచ్చు."</string>
-    <string name="ssl_error_continue" msgid="6492718244923937110">"ఏదేమైనా బ్రౌజర్ ద్వారా కొనసాగించు"</string>
-    <string name="ssl_error_untrusted" msgid="1496280318271264520">"ఈ సర్టిఫికెట్ విశ్వసనీయ అధికార సంస్థ నుండి కాదు."</string>
-    <string name="ssl_error_mismatch" msgid="3060364165934822383">"సైట్ యొక్క పేరు సర్టిఫికెట్‌లోని పేరుతో సరిపోలలేదు."</string>
-    <string name="ssl_error_expired" msgid="1501588340716182495">"ఈ సర్టిఫికెట్ గడువు ముగిసింది."</string>
-    <string name="ssl_error_not_yet_valid" msgid="8648649030525886924">"ఈ సర్టిఫికెట్ ఇప్పటికీ చెల్లదు."</string>
-    <string name="ssl_error_date_invalid" msgid="88425990680059223">"ఈ సర్టిఫికెట్ చెల్లని తేదీని కలిగి ఉంది."</string>
-    <string name="ssl_error_invalid" msgid="2540546515565633432">"ఈ సర్టిఫికెట్ చెల్లుబాటు కాదు."</string>
-    <string name="ssl_error_unknown" msgid="4405203446079465859">"తెలియని సర్టిఫికెట్ ఎర్రర్."</string>
-    <string name="ssl_security_warning_title" msgid="8768539813847504404">"భద్రతా హెచ్చరిక"</string>
-    <string name="ssl_error_view_certificate" msgid="5722652540168339333">"సర్టిఫికెట్‌ని చూడండి"</string>
-    <string name="ok" msgid="2817931639040794018">"సరే"</string>
-    <string name="page_info_address" msgid="1261481517455692363">"చిరునామా:"</string>
-    <string name="page_info" msgid="4416941086705172545">"పేజీ సమాచారం"</string>
-</resources>
diff --git a/packages/CaptivePortalLogin/res/values-th/strings.xml b/packages/CaptivePortalLogin/res/values-th/strings.xml
deleted file mode 100644
index 739b505..0000000
--- a/packages/CaptivePortalLogin/res/values-th/strings.xml
+++ /dev/null
@@ -1,24 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="app_name" msgid="5934709770924185752">"CaptivePortalLogin"</string>
-    <string name="action_use_network" msgid="6076184727448466030">"ใช้เครือข่ายนี้ตามที่เป็นอยู่"</string>
-    <string name="action_do_not_use_network" msgid="4577366536956516683">"ไม่ใช้เครือข่ายนี้"</string>
-    <string name="action_bar_label" msgid="917235635415966620">"ลงชื่อเข้าใช้เครือข่าย"</string>
-    <string name="action_bar_title" msgid="5645564790486983117">"ลงชื่อเข้าใช้ %1$s"</string>
-    <string name="ssl_error_warning" msgid="6653188881418638872">"เครือข่ายที่คุณพยายามเข้าร่วมมีปัญหาด้านความปลอดภัย"</string>
-    <string name="ssl_error_example" msgid="647898534624078900">"ตัวอย่างเช่น หน้าเข้าสู่ระบบอาจไม่ใช่ขององค์กรที่แสดงไว้"</string>
-    <string name="ssl_error_continue" msgid="6492718244923937110">"ดำเนินการต่อผ่านเบราว์เซอร์"</string>
-    <string name="ssl_error_untrusted" msgid="1496280318271264520">"ใบรับรองนี้ไม่ได้มาจากผู้ออกที่เชื่อถือได้"</string>
-    <string name="ssl_error_mismatch" msgid="3060364165934822383">"ชื่อเว็บไซต์ไม่ตรงกับในใบรับรอง"</string>
-    <string name="ssl_error_expired" msgid="1501588340716182495">"ใบรับรองนี้หมดอายุแล้ว"</string>
-    <string name="ssl_error_not_yet_valid" msgid="8648649030525886924">"ใบรับรองนี้ยังใช้งานไม่ได้"</string>
-    <string name="ssl_error_date_invalid" msgid="88425990680059223">"วันที่ในใบรับรองนี้ไม่ถูกต้อง"</string>
-    <string name="ssl_error_invalid" msgid="2540546515565633432">"ใบรับรองนี้ไม่ถูกต้อง"</string>
-    <string name="ssl_error_unknown" msgid="4405203446079465859">"ข้อผิดพลาดใบรับรองที่ไม่รู้จัก"</string>
-    <string name="ssl_security_warning_title" msgid="8768539813847504404">"การแจ้งเตือนเกี่ยวกับความปลอดภัย"</string>
-    <string name="ssl_error_view_certificate" msgid="5722652540168339333">"ดูใบรับรอง"</string>
-    <string name="ok" msgid="2817931639040794018">"ตกลง"</string>
-    <string name="page_info_address" msgid="1261481517455692363">"ที่อยู่:"</string>
-    <string name="page_info" msgid="4416941086705172545">"ข้อมูลหน้าเว็บ"</string>
-</resources>
diff --git a/packages/CaptivePortalLogin/res/values-tl/strings.xml b/packages/CaptivePortalLogin/res/values-tl/strings.xml
deleted file mode 100644
index 483a589..0000000
--- a/packages/CaptivePortalLogin/res/values-tl/strings.xml
+++ /dev/null
@@ -1,24 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="app_name" msgid="5934709770924185752">"CaptivePortalLogin"</string>
-    <string name="action_use_network" msgid="6076184727448466030">"Gamitin ang network na ito nang walang pagbabago"</string>
-    <string name="action_do_not_use_network" msgid="4577366536956516683">"Huwag gamitin ang network na ito"</string>
-    <string name="action_bar_label" msgid="917235635415966620">"Mag-sign in sa network"</string>
-    <string name="action_bar_title" msgid="5645564790486983117">"Mag-sign in sa %1$s"</string>
-    <string name="ssl_error_warning" msgid="6653188881418638872">"May mga isyu sa seguridad ang network kung saan mo sinusubukang sumali."</string>
-    <string name="ssl_error_example" msgid="647898534624078900">"Halimbawa, maaaring hindi sa organisasyong ipinapakita ang page sa pag-log in."</string>
-    <string name="ssl_error_continue" msgid="6492718244923937110">"Magpatuloy pa rin sa pamamagitan ng browser"</string>
-    <string name="ssl_error_untrusted" msgid="1496280318271264520">"Ang certificate na ito ay mula sa hindi pinagkakatiwalaang awtoridad."</string>
-    <string name="ssl_error_mismatch" msgid="3060364165934822383">"Ang pangalan ng site ay hindi tumutugma sa pangalan sa certificate."</string>
-    <string name="ssl_error_expired" msgid="1501588340716182495">"Nag-expire na ang certificate na ito."</string>
-    <string name="ssl_error_not_yet_valid" msgid="8648649030525886924">"Hindi pa valid ang certificate na ito."</string>
-    <string name="ssl_error_date_invalid" msgid="88425990680059223">"May invalid na petsa ang certificate na ito."</string>
-    <string name="ssl_error_invalid" msgid="2540546515565633432">"Invalid ang certificate na ito."</string>
-    <string name="ssl_error_unknown" msgid="4405203446079465859">"Hindi kilalang error sa certificate."</string>
-    <string name="ssl_security_warning_title" msgid="8768539813847504404">"Babala sa seguridad"</string>
-    <string name="ssl_error_view_certificate" msgid="5722652540168339333">"Tingnan ang certificate"</string>
-    <string name="ok" msgid="2817931639040794018">"OK"</string>
-    <string name="page_info_address" msgid="1261481517455692363">"Address:"</string>
-    <string name="page_info" msgid="4416941086705172545">"Impormasyon ng page"</string>
-</resources>
diff --git a/packages/CaptivePortalLogin/res/values-tr/strings.xml b/packages/CaptivePortalLogin/res/values-tr/strings.xml
deleted file mode 100644
index f51cfbd..0000000
--- a/packages/CaptivePortalLogin/res/values-tr/strings.xml
+++ /dev/null
@@ -1,24 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="app_name" msgid="5934709770924185752">"CaptivePortalLogin"</string>
-    <string name="action_use_network" msgid="6076184727448466030">"Bu ağı olduğu gibi kullan"</string>
-    <string name="action_do_not_use_network" msgid="4577366536956516683">"Bu ağı kullanma"</string>
-    <string name="action_bar_label" msgid="917235635415966620">"Ağda oturum açın"</string>
-    <string name="action_bar_title" msgid="5645564790486983117">"%1$s üzerinde oturum açın"</string>
-    <string name="ssl_error_warning" msgid="6653188881418638872">"Katılmaya çalıştığınız ağda güvenlik sorunları var."</string>
-    <string name="ssl_error_example" msgid="647898534624078900">"Örneğin, giriş sayfası, gösterilen kuruluşa ait olmayabilir."</string>
-    <string name="ssl_error_continue" msgid="6492718244923937110">"Yine de tarayıcıyla devam et"</string>
-    <string name="ssl_error_untrusted" msgid="1496280318271264520">"Bu sertifika güvenilir bir yetkiliden değil."</string>
-    <string name="ssl_error_mismatch" msgid="3060364165934822383">"Sitenin adı sertifika üzerindeki adla eşleşmiyor."</string>
-    <string name="ssl_error_expired" msgid="1501588340716182495">"Bu sertifikanın süresi dolmuş."</string>
-    <string name="ssl_error_not_yet_valid" msgid="8648649030525886924">"Bu sertifika henüz geçerli değil."</string>
-    <string name="ssl_error_date_invalid" msgid="88425990680059223">"Bu sertifikanın tarihi geçersiz."</string>
-    <string name="ssl_error_invalid" msgid="2540546515565633432">"Bu sertifika geçersiz."</string>
-    <string name="ssl_error_unknown" msgid="4405203446079465859">"Bilinmeyen sertifika hatası."</string>
-    <string name="ssl_security_warning_title" msgid="8768539813847504404">"Güvenlik uyarısı"</string>
-    <string name="ssl_error_view_certificate" msgid="5722652540168339333">"Sertifikayı göster"</string>
-    <string name="ok" msgid="2817931639040794018">"Tamam"</string>
-    <string name="page_info_address" msgid="1261481517455692363">"Adres:"</string>
-    <string name="page_info" msgid="4416941086705172545">"Sayfa bilgileri"</string>
-</resources>
diff --git a/packages/CaptivePortalLogin/res/values-uk/strings.xml b/packages/CaptivePortalLogin/res/values-uk/strings.xml
deleted file mode 100644
index c1a5d05..0000000
--- a/packages/CaptivePortalLogin/res/values-uk/strings.xml
+++ /dev/null
@@ -1,24 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="app_name" msgid="5934709770924185752">"CaptivePortalLogin"</string>
-    <string name="action_use_network" msgid="6076184727448466030">"Використовувати цю мережу як є"</string>
-    <string name="action_do_not_use_network" msgid="4577366536956516683">"Не використовувати цю мережу"</string>
-    <string name="action_bar_label" msgid="917235635415966620">"Увійти в мережу"</string>
-    <string name="action_bar_title" msgid="5645564790486983117">"Увійти в обліковий запис %1$s"</string>
-    <string name="ssl_error_warning" msgid="6653188881418638872">"У мережі, до якої ви намагаєтеся під’єднатись, є проблеми з безпекою."</string>
-    <string name="ssl_error_example" msgid="647898534624078900">"Наприклад, сторінка входу може не належати вказаній організації."</string>
-    <string name="ssl_error_continue" msgid="6492718244923937110">"Усе одно продовжити у веб-переглядачі"</string>
-    <string name="ssl_error_untrusted" msgid="1496280318271264520">"Сертифікат видано ненадійним центром сертифікації."</string>
-    <string name="ssl_error_mismatch" msgid="3060364165934822383">"Назва сайту не збігається з назвою в сертифікаті."</string>
-    <string name="ssl_error_expired" msgid="1501588340716182495">"Термін дії сертифіката закінчився."</string>
-    <string name="ssl_error_not_yet_valid" msgid="8648649030525886924">"Цей сертифікат ще не дійсний."</string>
-    <string name="ssl_error_date_invalid" msgid="88425990680059223">"Цей сертифікат має недійсну дату."</string>
-    <string name="ssl_error_invalid" msgid="2540546515565633432">"Цей сертифікат недійсний."</string>
-    <string name="ssl_error_unknown" msgid="4405203446079465859">"Помилка невідомого сертифіката."</string>
-    <string name="ssl_security_warning_title" msgid="8768539813847504404">"Застереження про небезпеку"</string>
-    <string name="ssl_error_view_certificate" msgid="5722652540168339333">"Переглянути сертифікат"</string>
-    <string name="ok" msgid="2817931639040794018">"OK"</string>
-    <string name="page_info_address" msgid="1261481517455692363">"Адреса:"</string>
-    <string name="page_info" msgid="4416941086705172545">"Інформація про сторінку"</string>
-</resources>
diff --git a/packages/CaptivePortalLogin/res/values-ur/strings.xml b/packages/CaptivePortalLogin/res/values-ur/strings.xml
deleted file mode 100644
index e6f8539..0000000
--- a/packages/CaptivePortalLogin/res/values-ur/strings.xml
+++ /dev/null
@@ -1,24 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="app_name" msgid="5934709770924185752">"CaptivePortalLogin"</string>
-    <string name="action_use_network" msgid="6076184727448466030">"جوں کا توں اس نیٹ ورک کا استعمال کریں"</string>
-    <string name="action_do_not_use_network" msgid="4577366536956516683">"اس نیٹ ورک کا استعمال نہ کریں"</string>
-    <string name="action_bar_label" msgid="917235635415966620">"نیٹ ورک میں سائن ان کریں"</string>
-    <string name="action_bar_title" msgid="5645564790486983117">"‏%1$s میں سائن ان کریں"</string>
-    <string name="ssl_error_warning" msgid="6653188881418638872">"جس نیٹ ورک میں آپ شامل ہونے کی کوشش کر رہے ہیں اس میں سیکیورٹی کے مسائل ہیں۔"</string>
-    <string name="ssl_error_example" msgid="647898534624078900">"مثال کے طور پر ہو سکتا ہے کہ لاگ ان صفحہ دکھائی گئی تنظیم سے تعلق نہ رکھتا ہو۔"</string>
-    <string name="ssl_error_continue" msgid="6492718244923937110">"براؤزر کے ذریعے بہرحال جاری رکھیں"</string>
-    <string name="ssl_error_untrusted" msgid="1496280318271264520">"یہ سرٹیفکیٹ قابل اعتماد اتھارٹی سے حاصل شدہ نہیں ہے۔"</string>
-    <string name="ssl_error_mismatch" msgid="3060364165934822383">"سائٹ کا نام سرٹیفکیٹ پر موجود نام سے مماثل نہیں ہے۔"</string>
-    <string name="ssl_error_expired" msgid="1501588340716182495">"اس سرٹیفکیٹ کی میعاد ختم ہو گئی ہے۔"</string>
-    <string name="ssl_error_not_yet_valid" msgid="8648649030525886924">"یہ سرٹیفکیٹ ابھی تک درست نہیں ہے۔"</string>
-    <string name="ssl_error_date_invalid" msgid="88425990680059223">"اس سرٹیفکیٹ میں ایک غلط تاریخ ہے۔"</string>
-    <string name="ssl_error_invalid" msgid="2540546515565633432">"یہ سرٹیفیکیٹ غلط ہے۔"</string>
-    <string name="ssl_error_unknown" msgid="4405203446079465859">"سرٹیفکیٹ کی نامعلوم خرابی۔"</string>
-    <string name="ssl_security_warning_title" msgid="8768539813847504404">"سیکیورٹی وارننگ"</string>
-    <string name="ssl_error_view_certificate" msgid="5722652540168339333">"سرٹیفکیٹ دیکھیں"</string>
-    <string name="ok" msgid="2817931639040794018">"ٹھیک ہے"</string>
-    <string name="page_info_address" msgid="1261481517455692363">"پتہ:"</string>
-    <string name="page_info" msgid="4416941086705172545">"صفحہ کی معلومات"</string>
-</resources>
diff --git a/packages/CaptivePortalLogin/res/values-uz/strings.xml b/packages/CaptivePortalLogin/res/values-uz/strings.xml
deleted file mode 100644
index 4009db6a..0000000
--- a/packages/CaptivePortalLogin/res/values-uz/strings.xml
+++ /dev/null
@@ -1,24 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="app_name" msgid="5934709770924185752">"CaptivePortalLogin"</string>
-    <string name="action_use_network" msgid="6076184727448466030">"Ushbu tarmoqdan o‘z holicha foydalanilsin"</string>
-    <string name="action_do_not_use_network" msgid="4577366536956516683">"Ushbu tarmoqdan foydalanilmasin"</string>
-    <string name="action_bar_label" msgid="917235635415966620">"Tarmoqqa kirish"</string>
-    <string name="action_bar_title" msgid="5645564790486983117">"%1$s hisobiga kirish"</string>
-    <string name="ssl_error_warning" msgid="6653188881418638872">"Siz ulanmoqchi bo‘lgan tarmoqda xavfsizlik bilan bog‘liq muammolar mavjud."</string>
-    <string name="ssl_error_example" msgid="647898534624078900">"Masalan, tizimga kirish sahifasi ko‘rsatilgan tashkilotga tegishli bo‘lmasligi mumkin."</string>
-    <string name="ssl_error_continue" msgid="6492718244923937110">"E’tiborsiz qoldirilsin va brauzer ochilsin"</string>
-    <string name="ssl_error_untrusted" msgid="1496280318271264520">"Bu sertifikat ishonchsiz manbadan olingan."</string>
-    <string name="ssl_error_mismatch" msgid="3060364165934822383">"Sayt nomi sertifikatdagi nomga mos emas."</string>
-    <string name="ssl_error_expired" msgid="1501588340716182495">"Bu sertifikat muddati tugagan."</string>
-    <string name="ssl_error_not_yet_valid" msgid="8648649030525886924">"Bu sertifikat hali yaroqli emas."</string>
-    <string name="ssl_error_date_invalid" msgid="88425990680059223">"Bu sertifikatdagi sana xato."</string>
-    <string name="ssl_error_invalid" msgid="2540546515565633432">"Bu sertifikat yaroqsiz."</string>
-    <string name="ssl_error_unknown" msgid="4405203446079465859">"Sertifikatga aloqador notanish xato."</string>
-    <string name="ssl_security_warning_title" msgid="8768539813847504404">"Xavfsizlikka oid ogohlantirish"</string>
-    <string name="ssl_error_view_certificate" msgid="5722652540168339333">"Sertifikatni ochish"</string>
-    <string name="ok" msgid="2817931639040794018">"OK"</string>
-    <string name="page_info_address" msgid="1261481517455692363">"Manzil:"</string>
-    <string name="page_info" msgid="4416941086705172545">"Sahifa haqida"</string>
-</resources>
diff --git a/packages/CaptivePortalLogin/res/values-vi/strings.xml b/packages/CaptivePortalLogin/res/values-vi/strings.xml
deleted file mode 100644
index bd4e96a..0000000
--- a/packages/CaptivePortalLogin/res/values-vi/strings.xml
+++ /dev/null
@@ -1,24 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="app_name" msgid="5934709770924185752">"CaptivePortalLogin"</string>
-    <string name="action_use_network" msgid="6076184727448466030">"Sử dụng mạng này"</string>
-    <string name="action_do_not_use_network" msgid="4577366536956516683">"Không sử dụng mạng này"</string>
-    <string name="action_bar_label" msgid="917235635415966620">"Đăng nhập vào mạng"</string>
-    <string name="action_bar_title" msgid="5645564790486983117">"Đăng nhập vào %1$s"</string>
-    <string name="ssl_error_warning" msgid="6653188881418638872">"Mạng mà bạn đang cố gắng tham gia có vấn đề về bảo mật."</string>
-    <string name="ssl_error_example" msgid="647898534624078900">"Ví dụ, trang đăng nhập có thể không thuộc về tổ chức được hiển thị."</string>
-    <string name="ssl_error_continue" msgid="6492718244923937110">"Vẫn tiếp tục qua trình duyệt"</string>
-    <string name="ssl_error_untrusted" msgid="1496280318271264520">"Chứng chỉ này không xuất phát từ tổ chức phát hành đáng tin cậy."</string>
-    <string name="ssl_error_mismatch" msgid="3060364165934822383">"Tên của trang web không khớp với tên trên chứng chỉ."</string>
-    <string name="ssl_error_expired" msgid="1501588340716182495">"Chứng chỉ này đã hết hạn."</string>
-    <string name="ssl_error_not_yet_valid" msgid="8648649030525886924">"Chứng chỉ này chưa hợp lệ."</string>
-    <string name="ssl_error_date_invalid" msgid="88425990680059223">"Chứng chỉ này có ngày không hợp lệ."</string>
-    <string name="ssl_error_invalid" msgid="2540546515565633432">"Chứng chỉ này không hợp lệ."</string>
-    <string name="ssl_error_unknown" msgid="4405203446079465859">"Lỗi chứng chỉ không xác định."</string>
-    <string name="ssl_security_warning_title" msgid="8768539813847504404">"Cảnh báo bảo mật"</string>
-    <string name="ssl_error_view_certificate" msgid="5722652540168339333">"Xem chứng chỉ"</string>
-    <string name="ok" msgid="2817931639040794018">"OK"</string>
-    <string name="page_info_address" msgid="1261481517455692363">"Địa chỉ:"</string>
-    <string name="page_info" msgid="4416941086705172545">"Thông tin trang"</string>
-</resources>
diff --git a/packages/CaptivePortalLogin/res/values-zh-rCN/strings.xml b/packages/CaptivePortalLogin/res/values-zh-rCN/strings.xml
deleted file mode 100644
index 5beaa2e..0000000
--- a/packages/CaptivePortalLogin/res/values-zh-rCN/strings.xml
+++ /dev/null
@@ -1,24 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="app_name" msgid="5934709770924185752">"CaptivePortalLogin"</string>
-    <string name="action_use_network" msgid="6076184727448466030">"直接使用此网络"</string>
-    <string name="action_do_not_use_network" msgid="4577366536956516683">"不要使用此网络"</string>
-    <string name="action_bar_label" msgid="917235635415966620">"登录到网络"</string>
-    <string name="action_bar_title" msgid="5645564790486983117">"登录%1$s"</string>
-    <string name="ssl_error_warning" msgid="6653188881418638872">"您尝试加入的网络存在安全问题。"</string>
-    <string name="ssl_error_example" msgid="647898534624078900">"例如,登录页面可能并不属于页面上显示的单位。"</string>
-    <string name="ssl_error_continue" msgid="6492718244923937110">"仍然通过浏览器继续操作"</string>
-    <string name="ssl_error_untrusted" msgid="1496280318271264520">"该证书并非来自可信的授权中心。"</string>
-    <string name="ssl_error_mismatch" msgid="3060364165934822383">"网站的名称与证书上的名称不一致。"</string>
-    <string name="ssl_error_expired" msgid="1501588340716182495">"该证书已过期。"</string>
-    <string name="ssl_error_not_yet_valid" msgid="8648649030525886924">"该证书尚未生效。"</string>
-    <string name="ssl_error_date_invalid" msgid="88425990680059223">"该证书的日期无效。"</string>
-    <string name="ssl_error_invalid" msgid="2540546515565633432">"该证书无效。"</string>
-    <string name="ssl_error_unknown" msgid="4405203446079465859">"未知证书错误。"</string>
-    <string name="ssl_security_warning_title" msgid="8768539813847504404">"安全警告"</string>
-    <string name="ssl_error_view_certificate" msgid="5722652540168339333">"查看证书"</string>
-    <string name="ok" msgid="2817931639040794018">"确定"</string>
-    <string name="page_info_address" msgid="1261481517455692363">"地址:"</string>
-    <string name="page_info" msgid="4416941086705172545">"页面信息"</string>
-</resources>
diff --git a/packages/CaptivePortalLogin/res/values-zh-rHK/strings.xml b/packages/CaptivePortalLogin/res/values-zh-rHK/strings.xml
deleted file mode 100644
index 7987023..0000000
--- a/packages/CaptivePortalLogin/res/values-zh-rHK/strings.xml
+++ /dev/null
@@ -1,24 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="app_name" msgid="5934709770924185752">"CaptivePortalLogin"</string>
-    <string name="action_use_network" msgid="6076184727448466030">"依照現況使用這個網絡"</string>
-    <string name="action_do_not_use_network" msgid="4577366536956516683">"不要使用這個網絡"</string>
-    <string name="action_bar_label" msgid="917235635415966620">"登入網絡"</string>
-    <string name="action_bar_title" msgid="5645564790486983117">"登入「%1$s」"</string>
-    <string name="ssl_error_warning" msgid="6653188881418638872">"您正在嘗試加入的網絡有安全性問題。"</string>
-    <string name="ssl_error_example" msgid="647898534624078900">"例如,登入頁面並不屬於所顯示的機構。"</string>
-    <string name="ssl_error_continue" msgid="6492718244923937110">"透過瀏覽器繼續"</string>
-    <string name="ssl_error_untrusted" msgid="1496280318271264520">"此憑證並非由信任的機構發出。"</string>
-    <string name="ssl_error_mismatch" msgid="3060364165934822383">"網站名稱與憑證上的名稱不符。"</string>
-    <string name="ssl_error_expired" msgid="1501588340716182495">"此憑證已過期。"</string>
-    <string name="ssl_error_not_yet_valid" msgid="8648649030525886924">"此憑證尚未生效。"</string>
-    <string name="ssl_error_date_invalid" msgid="88425990680059223">"此憑證的日期無效。"</string>
-    <string name="ssl_error_invalid" msgid="2540546515565633432">"此憑證無效。"</string>
-    <string name="ssl_error_unknown" msgid="4405203446079465859">"不明的憑證錯誤。"</string>
-    <string name="ssl_security_warning_title" msgid="8768539813847504404">"安全性警告"</string>
-    <string name="ssl_error_view_certificate" msgid="5722652540168339333">"查看憑證"</string>
-    <string name="ok" msgid="2817931639040794018">"確定"</string>
-    <string name="page_info_address" msgid="1261481517455692363">"電郵地址:"</string>
-    <string name="page_info" msgid="4416941086705172545">"頁面資料"</string>
-</resources>
diff --git a/packages/CaptivePortalLogin/res/values-zh-rTW/strings.xml b/packages/CaptivePortalLogin/res/values-zh-rTW/strings.xml
deleted file mode 100644
index 9f92f39..0000000
--- a/packages/CaptivePortalLogin/res/values-zh-rTW/strings.xml
+++ /dev/null
@@ -1,24 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="app_name" msgid="5934709770924185752">"CaptivePortalLogin"</string>
-    <string name="action_use_network" msgid="6076184727448466030">"依現況使用這個網路"</string>
-    <string name="action_do_not_use_network" msgid="4577366536956516683">"不使用這個網路"</string>
-    <string name="action_bar_label" msgid="917235635415966620">"登入網路"</string>
-    <string name="action_bar_title" msgid="5645564790486983117">"登入 %1$s"</string>
-    <string name="ssl_error_warning" msgid="6653188881418638872">"你嘗試加入的網路有安全問題。"</string>
-    <string name="ssl_error_example" msgid="647898534624078900">"例如,登入網頁中顯示的機構可能並非該網頁實際隸屬的機構。"</string>
-    <string name="ssl_error_continue" msgid="6492718244923937110">"透過瀏覽器繼續"</string>
-    <string name="ssl_error_untrusted" msgid="1496280318271264520">"這個憑證並非來自信任的授權單位。"</string>
-    <string name="ssl_error_mismatch" msgid="3060364165934822383">"網站名稱與憑證上的名稱不相符。"</string>
-    <string name="ssl_error_expired" msgid="1501588340716182495">"這個憑證已過期。"</string>
-    <string name="ssl_error_not_yet_valid" msgid="8648649030525886924">"這個憑證尚未生效。"</string>
-    <string name="ssl_error_date_invalid" msgid="88425990680059223">"這個憑證的日期無效。"</string>
-    <string name="ssl_error_invalid" msgid="2540546515565633432">"這個憑證無效。"</string>
-    <string name="ssl_error_unknown" msgid="4405203446079465859">"不明的憑證錯誤。"</string>
-    <string name="ssl_security_warning_title" msgid="8768539813847504404">"安全性警告"</string>
-    <string name="ssl_error_view_certificate" msgid="5722652540168339333">"查看憑證"</string>
-    <string name="ok" msgid="2817931639040794018">"確定"</string>
-    <string name="page_info_address" msgid="1261481517455692363">"地址:"</string>
-    <string name="page_info" msgid="4416941086705172545">"頁面資訊"</string>
-</resources>
diff --git a/packages/CaptivePortalLogin/res/values-zu/strings.xml b/packages/CaptivePortalLogin/res/values-zu/strings.xml
deleted file mode 100644
index ebb0f54..0000000
--- a/packages/CaptivePortalLogin/res/values-zu/strings.xml
+++ /dev/null
@@ -1,24 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="app_name" msgid="5934709770924185752">"I-CaptivePortalLogin"</string>
-    <string name="action_use_network" msgid="6076184727448466030">"Sebenzisa le nethiwekhi njengoba injalo"</string>
-    <string name="action_do_not_use_network" msgid="4577366536956516683">"Ungasebenzisi le nethiwekhi"</string>
-    <string name="action_bar_label" msgid="917235635415966620">"Ngena ngemvume kunethiwekhi"</string>
-    <string name="action_bar_title" msgid="5645564790486983117">"Ngena ngemvume ku-%1$s"</string>
-    <string name="ssl_error_warning" msgid="6653188881418638872">"Inethiwekhi ozama ukuyijoyina inezinkinga zokuvikela."</string>
-    <string name="ssl_error_example" msgid="647898534624078900">"Isibonelo, ikhasi lokungena ngemvume kungenzeka lingelenhlangano ebonisiwe."</string>
-    <string name="ssl_error_continue" msgid="6492718244923937110">"Qhubeka noma kunjalo ngesiphequluli"</string>
-    <string name="ssl_error_untrusted" msgid="1496280318271264520">"Lesi sitifiketi asisuki kusiphathimandla esithembekile."</string>
-    <string name="ssl_error_mismatch" msgid="3060364165934822383">"Igama lesayithi alifani negama elikusitifiketi."</string>
-    <string name="ssl_error_expired" msgid="1501588340716182495">"Lesi sitifiketi siphelelwe yisikhathi"</string>
-    <string name="ssl_error_not_yet_valid" msgid="8648649030525886924">"Lesi sitifiketi asivumelekile okwamanje."</string>
-    <string name="ssl_error_date_invalid" msgid="88425990680059223">"Lesi sitifiketi sinosuku olungalungile."</string>
-    <string name="ssl_error_invalid" msgid="2540546515565633432">"Lesi sitifiketi asilungile."</string>
-    <string name="ssl_error_unknown" msgid="4405203446079465859">"Iphutha lesitifiketi elingaziwa."</string>
-    <string name="ssl_security_warning_title" msgid="8768539813847504404">"Isexwayiso sokuvikeleka"</string>
-    <string name="ssl_error_view_certificate" msgid="5722652540168339333">"Buka isitifiketi"</string>
-    <string name="ok" msgid="2817931639040794018">"KULUNGILE"</string>
-    <string name="page_info_address" msgid="1261481517455692363">"Ikheli:"</string>
-    <string name="page_info" msgid="4416941086705172545">"Ulwazi lekhasi"</string>
-</resources>
diff --git a/packages/CaptivePortalLogin/res/values/dimens.xml b/packages/CaptivePortalLogin/res/values/dimens.xml
deleted file mode 100644
index 55c1e59..0000000
--- a/packages/CaptivePortalLogin/res/values/dimens.xml
+++ /dev/null
@@ -1,7 +0,0 @@
-<resources>
-
-    <!-- Default screen margins, per the Android Design guidelines. -->
-    <dimen name="activity_horizontal_margin">16dp</dimen>
-    <dimen name="activity_vertical_margin">16dp</dimen>
-
-</resources>
diff --git a/packages/CaptivePortalLogin/res/values/strings.xml b/packages/CaptivePortalLogin/res/values/strings.xml
deleted file mode 100644
index e9698db..0000000
--- a/packages/CaptivePortalLogin/res/values/strings.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<resources>
-
-    <string name="app_name">CaptivePortalLogin</string>
-    <string name="action_use_network">Use this network as is</string>
-    <string name="action_do_not_use_network">Do not use this network</string>
-    <string name="action_bar_label">Sign in to network</string>
-    <string name="action_bar_title">Sign in to %1$s</string>
-    <string name="ssl_error_warning">The network you&#8217;re trying to join has security issues.</string>
-    <string name="ssl_error_example">For example, the login page may not belong to the organization shown.</string>
-    <string name="ssl_error_continue">Continue anyway via browser</string>
-    <string name="ssl_error_untrusted">This certificate isn\'t from a trusted authority.</string>
-    <string name="ssl_error_mismatch">The name of the site doesn\'t match the name on the certificate.</string>
-    <string name="ssl_error_expired">This certificate has expired.</string>
-    <string name="ssl_error_not_yet_valid">This certificate isn\'t valid yet.</string>
-    <string name="ssl_error_date_invalid">This certificate has an invalid date.</string>
-    <string name="ssl_error_invalid">This certificate is invalid.</string>
-    <string name="ssl_error_unknown">Unknown certificate error.</string>
-    <string name="ssl_security_warning_title">Security warning</string>
-    <string name="ssl_error_view_certificate">View certificate</string>
-    <string name="ok">OK</string>
-    <string name="page_info_address">Address:</string>
-    <string name="page_info">Page info</string>
-
-</resources>
diff --git a/packages/CaptivePortalLogin/res/values/styles.xml b/packages/CaptivePortalLogin/res/values/styles.xml
deleted file mode 100644
index f6c2339..0000000
--- a/packages/CaptivePortalLogin/res/values/styles.xml
+++ /dev/null
@@ -1,19 +0,0 @@
-<resources>
-
-    <!--
-        Base application theme, dependent on API level. This theme is replaced
-        by AppBaseTheme from res/values-vXX/styles.xml on newer devices.
-    -->
-    <style name="AppBaseTheme" parent="@android:style/Theme.DeviceDefault.Settings">
-        <!--
-            Theme customizations available in newer API levels can go in
-            res/values-vXX/styles.xml, while customizations related to
-            backward-compatibility can go here.
-        -->
-    </style>
-
-    <!-- Application theme. -->
-    <style name="AppTheme" parent="AppBaseTheme">
-        <!-- All customizations that are NOT specific to a particular API-level can go here. -->
-    </style>
-</resources>
diff --git a/packages/CaptivePortalLogin/src/com/android/captiveportallogin/CaptivePortalLoginActivity.java b/packages/CaptivePortalLogin/src/com/android/captiveportallogin/CaptivePortalLoginActivity.java
deleted file mode 100644
index 23fb7b6..0000000
--- a/packages/CaptivePortalLogin/src/com/android/captiveportallogin/CaptivePortalLoginActivity.java
+++ /dev/null
@@ -1,710 +0,0 @@
-/*
- * Copyright (C) 2014 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.captiveportallogin;
-
-import static android.net.ConnectivityManager.EXTRA_CAPTIVE_PORTAL_PROBE_SPEC;
-
-import android.app.Activity;
-import android.app.AlertDialog;
-import android.app.Application;
-import android.content.Context;
-import android.content.DialogInterface;
-import android.content.Intent;
-import android.graphics.Bitmap;
-import android.net.CaptivePortal;
-import android.net.ConnectivityManager;
-import android.net.ConnectivityManager.NetworkCallback;
-import android.net.Network;
-import android.net.NetworkCapabilities;
-import android.net.NetworkRequest;
-import android.net.Proxy;
-import android.net.Uri;
-import android.net.captiveportal.CaptivePortalProbeSpec;
-import android.net.http.SslCertificate;
-import android.net.http.SslError;
-import android.net.wifi.WifiInfo;
-import android.net.wifi.WifiManager;
-import android.os.Bundle;
-import android.os.SystemProperties;
-import android.text.TextUtils;
-import android.util.ArrayMap;
-import android.util.Log;
-import android.util.SparseArray;
-import android.util.TypedValue;
-import android.view.LayoutInflater;
-import android.view.Menu;
-import android.view.MenuItem;
-import android.view.View;
-import android.webkit.CookieManager;
-import android.webkit.SslErrorHandler;
-import android.webkit.WebChromeClient;
-import android.webkit.WebResourceRequest;
-import android.webkit.WebSettings;
-import android.webkit.WebView;
-import android.webkit.WebViewClient;
-import android.widget.LinearLayout;
-import android.widget.ProgressBar;
-import android.widget.TextView;
-
-import androidx.swiperefreshlayout.widget.SwipeRefreshLayout;
-
-import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
-
-import java.io.IOException;
-import java.lang.reflect.Field;
-import java.lang.reflect.Method;
-import java.net.HttpURLConnection;
-import java.net.MalformedURLException;
-import java.net.URL;
-import java.util.Objects;
-import java.util.Random;
-import java.util.concurrent.atomic.AtomicBoolean;
-
-public class CaptivePortalLoginActivity extends Activity {
-    private static final String TAG = CaptivePortalLoginActivity.class.getSimpleName();
-    private static final boolean DBG = true;
-    private static final boolean VDBG = false;
-
-    private static final int SOCKET_TIMEOUT_MS = 10000;
-    public static final String HTTP_LOCATION_HEADER_NAME = "Location";
-
-    private enum Result {
-        DISMISSED(MetricsEvent.ACTION_CAPTIVE_PORTAL_LOGIN_RESULT_DISMISSED),
-        UNWANTED(MetricsEvent.ACTION_CAPTIVE_PORTAL_LOGIN_RESULT_UNWANTED),
-        WANTED_AS_IS(MetricsEvent.ACTION_CAPTIVE_PORTAL_LOGIN_RESULT_WANTED_AS_IS);
-
-        final int metricsEvent;
-        Result(int metricsEvent) { this.metricsEvent = metricsEvent; }
-    };
-
-    private URL mUrl;
-    private CaptivePortalProbeSpec mProbeSpec;
-    private String mUserAgent;
-    private Network mNetwork;
-    private CaptivePortal mCaptivePortal;
-    private NetworkCallback mNetworkCallback;
-    private ConnectivityManager mCm;
-    private WifiManager mWifiManager;
-    private boolean mLaunchBrowser = false;
-    private MyWebViewClient mWebViewClient;
-    private SwipeRefreshLayout mSwipeRefreshLayout;
-    // Ensures that done() happens once exactly, handling concurrent callers with atomic operations.
-    private final AtomicBoolean isDone = new AtomicBoolean(false);
-
-    @Override
-    protected void onCreate(Bundle savedInstanceState) {
-        super.onCreate(savedInstanceState);
-
-        mCaptivePortal = getIntent().getParcelableExtra(ConnectivityManager.EXTRA_CAPTIVE_PORTAL);
-        logMetricsEvent(MetricsEvent.ACTION_CAPTIVE_PORTAL_LOGIN_ACTIVITY);
-
-        mCm = getSystemService(ConnectivityManager.class);
-        mWifiManager = getSystemService(WifiManager.class);
-        mNetwork = getIntent().getParcelableExtra(ConnectivityManager.EXTRA_NETWORK);
-        mUserAgent =
-                getIntent().getStringExtra(ConnectivityManager.EXTRA_CAPTIVE_PORTAL_USER_AGENT);
-        mUrl = getUrl();
-        if (mUrl == null) {
-            // getUrl() failed to parse the url provided in the intent: bail out in a way that
-            // at least provides network access.
-            done(Result.WANTED_AS_IS);
-            return;
-        }
-        if (DBG) {
-            Log.d(TAG, String.format("onCreate for %s", mUrl.toString()));
-        }
-
-        final String spec = getIntent().getStringExtra(EXTRA_CAPTIVE_PORTAL_PROBE_SPEC);
-        try {
-            mProbeSpec = CaptivePortalProbeSpec.parseSpecOrNull(spec);
-        } catch (Exception e) {
-            // Make extra sure that invalid configurations do not cause crashes
-            mProbeSpec = null;
-        }
-
-        mNetworkCallback = new NetworkCallback() {
-            @Override
-            public void onLost(Network lostNetwork) {
-                // If the network disappears while the app is up, exit.
-                if (mNetwork.equals(lostNetwork)) done(Result.UNWANTED);
-            }
-        };
-        mCm.registerNetworkCallback(new NetworkRequest.Builder().build(), mNetworkCallback);
-
-        // If the network has disappeared, exit.
-        final NetworkCapabilities networkCapabilities = mCm.getNetworkCapabilities(mNetwork);
-        if (networkCapabilities == null) {
-            finishAndRemoveTask();
-            return;
-        }
-
-        // Also initializes proxy system properties.
-        mNetwork = mNetwork.getPrivateDnsBypassingCopy();
-        mCm.bindProcessToNetwork(mNetwork);
-
-        // Proxy system properties must be initialized before setContentView is called because
-        // setContentView initializes the WebView logic which in turn reads the system properties.
-        setContentView(R.layout.activity_captive_portal_login);
-
-        getActionBar().setDisplayShowHomeEnabled(false);
-        getActionBar().setElevation(0); // remove shadow
-        getActionBar().setTitle(getHeaderTitle());
-        getActionBar().setSubtitle("");
-
-        final WebView webview = getWebview();
-        webview.clearCache(true);
-        CookieManager.getInstance().setAcceptThirdPartyCookies(webview, true);
-        WebSettings webSettings = webview.getSettings();
-        webSettings.setJavaScriptEnabled(true);
-        webSettings.setMixedContentMode(WebSettings.MIXED_CONTENT_COMPATIBILITY_MODE);
-        webSettings.setUseWideViewPort(true);
-        webSettings.setLoadWithOverviewMode(true);
-        webSettings.setSupportZoom(true);
-        webSettings.setBuiltInZoomControls(true);
-        webSettings.setDisplayZoomControls(false);
-        webSettings.setDomStorageEnabled(true);
-        mWebViewClient = new MyWebViewClient();
-        webview.setWebViewClient(mWebViewClient);
-        webview.setWebChromeClient(new MyWebChromeClient());
-        // Start initial page load so WebView finishes loading proxy settings.
-        // Actual load of mUrl is initiated by MyWebViewClient.
-        webview.loadData("", "text/html", null);
-
-        mSwipeRefreshLayout = findViewById(R.id.swipe_refresh);
-        mSwipeRefreshLayout.setOnRefreshListener(() -> {
-                webview.reload();
-                mSwipeRefreshLayout.setRefreshing(true);
-            });
-
-    }
-
-    // Find WebView's proxy BroadcastReceiver and prompt it to read proxy system properties.
-    private void setWebViewProxy() {
-        // TODO: migrate to androidx WebView proxy setting API as soon as it is finalized
-        try {
-            final Field loadedApkField = Application.class.getDeclaredField("mLoadedApk");
-            final Class<?> loadedApkClass = loadedApkField.getType();
-            final Object loadedApk = loadedApkField.get(getApplication());
-            Field receiversField = loadedApkClass.getDeclaredField("mReceivers");
-            receiversField.setAccessible(true);
-            ArrayMap receivers = (ArrayMap) receiversField.get(loadedApk);
-            for (Object receiverMap : receivers.values()) {
-                for (Object rec : ((ArrayMap) receiverMap).keySet()) {
-                    Class clazz = rec.getClass();
-                    if (clazz.getName().contains("ProxyChangeListener")) {
-                        Method onReceiveMethod = clazz.getDeclaredMethod("onReceive", Context.class,
-                                Intent.class);
-                        Intent intent = new Intent(Proxy.PROXY_CHANGE_ACTION);
-                        onReceiveMethod.invoke(rec, getApplicationContext(), intent);
-                        Log.v(TAG, "Prompting WebView proxy reload.");
-                    }
-                }
-            }
-        } catch (Exception e) {
-            Log.e(TAG, "Exception while setting WebView proxy: " + e);
-        }
-    }
-
-    private void done(Result result) {
-        if (isDone.getAndSet(true)) {
-            // isDone was already true: done() already called
-            return;
-        }
-        if (DBG) {
-            Log.d(TAG, String.format("Result %s for %s", result.name(), mUrl.toString()));
-        }
-        logMetricsEvent(result.metricsEvent);
-        switch (result) {
-            case DISMISSED:
-                mCaptivePortal.reportCaptivePortalDismissed();
-                break;
-            case UNWANTED:
-                mCaptivePortal.ignoreNetwork();
-                break;
-            case WANTED_AS_IS:
-                mCaptivePortal.useNetwork();
-                break;
-        }
-        finishAndRemoveTask();
-    }
-
-    @Override
-    public boolean onCreateOptionsMenu(Menu menu) {
-        getMenuInflater().inflate(R.menu.captive_portal_login, menu);
-        return true;
-    }
-
-    @Override
-    public void onBackPressed() {
-        WebView myWebView = findViewById(R.id.webview);
-        if (myWebView.canGoBack() && mWebViewClient.allowBack()) {
-            myWebView.goBack();
-        } else {
-            super.onBackPressed();
-        }
-    }
-
-    @Override
-    public boolean onOptionsItemSelected(MenuItem item) {
-        final Result result;
-        final String action;
-        final int id = item.getItemId();
-        switch (id) {
-            case R.id.action_use_network:
-                result = Result.WANTED_AS_IS;
-                action = "USE_NETWORK";
-                break;
-            case R.id.action_do_not_use_network:
-                result = Result.UNWANTED;
-                action = "DO_NOT_USE_NETWORK";
-                break;
-            default:
-                return super.onOptionsItemSelected(item);
-        }
-        if (DBG) {
-            Log.d(TAG, String.format("onOptionsItemSelect %s for %s", action, mUrl.toString()));
-        }
-        done(result);
-        return true;
-    }
-
-    @Override
-    public void onDestroy() {
-        super.onDestroy();
-        final WebView webview = (WebView) findViewById(R.id.webview);
-        if (webview != null) {
-            webview.stopLoading();
-            webview.setWebViewClient(null);
-            webview.setWebChromeClient(null);
-            webview.destroy();
-        }
-        if (mNetworkCallback != null) {
-            // mNetworkCallback is not null if mUrl is not null.
-            mCm.unregisterNetworkCallback(mNetworkCallback);
-        }
-        if (mLaunchBrowser) {
-            // Give time for this network to become default. After 500ms just proceed.
-            for (int i = 0; i < 5; i++) {
-                // TODO: This misses when mNetwork underlies a VPN.
-                if (mNetwork.equals(mCm.getActiveNetwork())) break;
-                try {
-                    Thread.sleep(100);
-                } catch (InterruptedException e) {
-                }
-            }
-            final String url = mUrl.toString();
-            if (DBG) {
-                Log.d(TAG, "starting activity with intent ACTION_VIEW for " + url);
-            }
-            startActivity(new Intent(Intent.ACTION_VIEW, Uri.parse(url)));
-        }
-    }
-
-    private URL getUrl() {
-        String url = getIntent().getStringExtra(ConnectivityManager.EXTRA_CAPTIVE_PORTAL_URL);
-        if (url == null) {
-            url = mCm.getCaptivePortalServerUrl();
-        }
-        return makeURL(url);
-    }
-
-    private static URL makeURL(String url) {
-        try {
-            return new URL(url);
-        } catch (MalformedURLException e) {
-            Log.e(TAG, "Invalid URL " + url);
-        }
-        return null;
-    }
-
-    private static String host(URL url) {
-        if (url == null) {
-            return null;
-        }
-        return url.getHost();
-    }
-
-    private static String sanitizeURL(URL url) {
-        // In non-Debug build, only show host to avoid leaking private info.
-        return isDebuggable() ? Objects.toString(url) : host(url);
-    }
-
-    private static boolean isDebuggable() {
-        return SystemProperties.getInt("ro.debuggable", 0) == 1;
-    }
-
-    private void testForCaptivePortal() {
-        // TODO: reuse NetworkMonitor facilities for consistent captive portal detection.
-        new Thread(new Runnable() {
-            public void run() {
-                // Give time for captive portal to open.
-                try {
-                    Thread.sleep(1000);
-                } catch (InterruptedException e) {
-                }
-                HttpURLConnection urlConnection = null;
-                int httpResponseCode = 500;
-                String locationHeader = null;
-                try {
-                    urlConnection = (HttpURLConnection) mNetwork.openConnection(mUrl);
-                    urlConnection.setInstanceFollowRedirects(false);
-                    urlConnection.setConnectTimeout(SOCKET_TIMEOUT_MS);
-                    urlConnection.setReadTimeout(SOCKET_TIMEOUT_MS);
-                    urlConnection.setUseCaches(false);
-                    if (mUserAgent != null) {
-                       urlConnection.setRequestProperty("User-Agent", mUserAgent);
-                    }
-                    // cannot read request header after connection
-                    String requestHeader = urlConnection.getRequestProperties().toString();
-
-                    urlConnection.getInputStream();
-                    httpResponseCode = urlConnection.getResponseCode();
-                    locationHeader = urlConnection.getHeaderField(HTTP_LOCATION_HEADER_NAME);
-                    if (DBG) {
-                        Log.d(TAG, "probe at " + mUrl +
-                                " ret=" + httpResponseCode +
-                                " request=" + requestHeader +
-                                " headers=" + urlConnection.getHeaderFields());
-                    }
-                } catch (IOException e) {
-                } finally {
-                    if (urlConnection != null) urlConnection.disconnect();
-                }
-                if (isDismissed(httpResponseCode, locationHeader, mProbeSpec)) {
-                    done(Result.DISMISSED);
-                }
-            }
-        }).start();
-    }
-
-    private static boolean isDismissed(
-            int httpResponseCode, String locationHeader, CaptivePortalProbeSpec probeSpec) {
-        return (probeSpec != null)
-                ? probeSpec.getResult(httpResponseCode, locationHeader).isSuccessful()
-                : (httpResponseCode == 204);
-    }
-
-    private class MyWebViewClient extends WebViewClient {
-        private static final String INTERNAL_ASSETS = "file:///android_asset/";
-
-        private final String mBrowserBailOutToken = Long.toString(new Random().nextLong());
-        private final String mCertificateOutToken = Long.toString(new Random().nextLong());
-        // How many Android device-independent-pixels per scaled-pixel
-        // dp/sp = (px/sp) / (px/dp) = (1/sp) / (1/dp)
-        private final float mDpPerSp = TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_SP, 1,
-                    getResources().getDisplayMetrics()) /
-                    TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 1,
-                    getResources().getDisplayMetrics());
-        private int mPagesLoaded;
-        private String mMainFrameUrl;
-
-        // If we haven't finished cleaning up the history, don't allow going back.
-        public boolean allowBack() {
-            return mPagesLoaded > 1;
-        }
-
-        private String mSslErrorTitle = null;
-        private SslErrorHandler mSslErrorHandler = null;
-        private SslError mSslError = null;
-
-        @Override
-        public void onPageStarted(WebView view, String urlString, Bitmap favicon) {
-            if (urlString.contains(mBrowserBailOutToken)) {
-                mLaunchBrowser = true;
-                done(Result.WANTED_AS_IS);
-                return;
-            }
-            // The first page load is used only to cause the WebView to
-            // fetch the proxy settings.  Don't update the URL bar, and
-            // don't check if the captive portal is still there.
-            if (mPagesLoaded == 0) {
-                return;
-            }
-            final URL url = makeURL(urlString);
-            Log.d(TAG, "onPageStarted: " + sanitizeURL(url));
-            // For internally generated pages, leave URL bar listing prior URL as this is the URL
-            // the page refers to.
-            if (!urlString.startsWith(INTERNAL_ASSETS)) {
-                String subtitle = (url != null) ? getHeaderSubtitle(url) : urlString;
-                getActionBar().setSubtitle(subtitle);
-            }
-            getProgressBar().setVisibility(View.VISIBLE);
-            testForCaptivePortal();
-        }
-
-        @Override
-        public void onPageFinished(WebView view, String url) {
-            mPagesLoaded++;
-            getProgressBar().setVisibility(View.INVISIBLE);
-            mSwipeRefreshLayout.setRefreshing(false);
-            if (mPagesLoaded == 1) {
-                // Now that WebView has loaded at least one page we know it has read in the proxy
-                // settings.  Now prompt the WebView read the Network-specific proxy settings.
-                setWebViewProxy();
-                // Load the real page.
-                view.loadUrl(mUrl.toString());
-                return;
-            } else if (mPagesLoaded == 2) {
-                // Prevent going back to empty first page.
-                // Fix for missing focus, see b/62449959 for details. Remove it once we get a
-                // newer version of WebView (60.x.y).
-                view.requestFocus();
-                view.clearHistory();
-            }
-            testForCaptivePortal();
-        }
-
-        // Convert Android scaled-pixels (sp) to HTML size.
-        private String sp(int sp) {
-            // Convert sp to dp's.
-            float dp = sp * mDpPerSp;
-            // Apply a scale factor to make things look right.
-            dp *= 1.3;
-            // Convert dp's to HTML size.
-            // HTML px's are scaled just like dp's, so just add "px" suffix.
-            return Integer.toString((int)dp) + "px";
-        }
-
-        // Check if webview is trying to load the main frame and record its url.
-        @Override
-        public boolean shouldOverrideUrlLoading(WebView view, WebResourceRequest request) {
-            if (request.isForMainFrame()) {
-                mMainFrameUrl = request.getUrl().toString();
-            }
-            // Be careful that two shouldOverrideUrlLoading methods are overridden, but
-            // shouldOverrideUrlLoading(WebView view, String url) was deprecated in API level 24.
-            // TODO: delete deprecated one ??
-            return shouldOverrideUrlLoading(view, mMainFrameUrl);
-        }
-
-        // A web page consisting of a large broken lock icon to indicate SSL failure.
-
-        @Override
-        public void onReceivedSslError(WebView view, SslErrorHandler handler, SslError error) {
-            final URL errorUrl = makeURL(error.getUrl());
-            final URL mainFrameUrl = makeURL(mMainFrameUrl);
-            Log.d(TAG, String.format("SSL error: %s, url: %s, certificate: %s",
-                    sslErrorName(error), sanitizeURL(errorUrl), error.getCertificate()));
-            if (errorUrl == null
-                    // Ignore SSL errors from resources by comparing the main frame url with SSL
-                    // error url.
-                    || !errorUrl.equals(mainFrameUrl)) {
-                Log.d(TAG, "onReceivedSslError: mMainFrameUrl = " + mMainFrameUrl);
-                handler.cancel();
-                return;
-            }
-            logMetricsEvent(MetricsEvent.CAPTIVE_PORTAL_LOGIN_ACTIVITY_SSL_ERROR);
-            final String sslErrorPage = makeSslErrorPage();
-            view.loadDataWithBaseURL(INTERNAL_ASSETS, sslErrorPage, "text/HTML", "UTF-8", null);
-            mSslErrorTitle = view.getTitle() == null ? "" : view.getTitle();
-            mSslErrorHandler = handler;
-            mSslError = error;
-        }
-
-        private String makeSslErrorPage() {
-            final String warningMsg = getString(R.string.ssl_error_warning);
-            final String exampleMsg = getString(R.string.ssl_error_example);
-            final String continueMsg = getString(R.string.ssl_error_continue);
-            final String certificateMsg = getString(R.string.ssl_error_view_certificate);
-            return String.join("\n",
-                    "<html>",
-                    "<head>",
-                    "  <meta name=\"viewport\" content=\"width=device-width, initial-scale=1\">",
-                    "  <style>",
-                    "    body {",
-                    "      background-color:#fafafa;",
-                    "      margin:auto;",
-                    "      width:80%;",
-                    "      margin-top: 96px",
-                    "    }",
-                    "    img {",
-                    "      height:48px;",
-                    "      width:48px;",
-                    "    }",
-                    "    div.warn {",
-                    "      font-size:" + sp(16) + ";",
-                    "      line-height:1.28;",
-                    "      margin-top:16px;",
-                    "      opacity:0.87;",
-                    "    }",
-                    "    div.example {",
-                    "      font-size:" + sp(14) + ";",
-                    "      line-height:1.21905;",
-                    "      margin-top:16px;",
-                    "      opacity:0.54;",
-                    "    }",
-                    "    a {",
-                    "      color:#4285F4;",
-                    "      display:inline-block;",
-                    "      font-size:" + sp(14) + ";",
-                    "      font-weight:bold;",
-                    "      height:48px;",
-                    "      margin-top:24px;",
-                    "      text-decoration:none;",
-                    "      text-transform:uppercase;",
-                    "    }",
-                    "    a.certificate {",
-                    "      margin-top:0px;",
-                    "    }",
-                    "  </style>",
-                    "</head>",
-                    "<body>",
-                    "  <p><img src=quantum_ic_warning_amber_96.png><br>",
-                    "  <div class=warn>" + warningMsg + "</div>",
-                    "  <div class=example>" + exampleMsg + "</div>",
-                    "  <a href=" + mBrowserBailOutToken + ">" + continueMsg + "</a><br>",
-                    "  <a class=certificate href=" + mCertificateOutToken + ">" + certificateMsg +
-                            "</a>",
-                    "</body>",
-                    "</html>");
-        }
-
-        @Override
-        public boolean shouldOverrideUrlLoading (WebView view, String url) {
-            if (url.startsWith("tel:")) {
-                startActivity(new Intent(Intent.ACTION_DIAL, Uri.parse(url)));
-                return true;
-            }
-            if (url.contains(mCertificateOutToken) && mSslError != null) {
-                showSslAlertDialog(mSslErrorHandler, mSslError, mSslErrorTitle);
-                return true;
-            }
-            return false;
-        }
-        private void showSslAlertDialog(SslErrorHandler handler, SslError error, String title) {
-            final LayoutInflater factory = LayoutInflater.from(CaptivePortalLoginActivity.this);
-            final View sslWarningView = factory.inflate(R.layout.ssl_warning, null);
-
-            // Set Security certificate
-            setViewSecurityCertificate(sslWarningView.findViewById(R.id.certificate_layout), error);
-            ((TextView) sslWarningView.findViewById(R.id.ssl_error_type))
-                    .setText(sslErrorName(error));
-            ((TextView) sslWarningView.findViewById(R.id.title)).setText(mSslErrorTitle);
-            ((TextView) sslWarningView.findViewById(R.id.address)).setText(error.getUrl());
-
-            AlertDialog sslAlertDialog = new AlertDialog.Builder(CaptivePortalLoginActivity.this)
-                    .setTitle(R.string.ssl_security_warning_title)
-                    .setView(sslWarningView)
-                    .setPositiveButton(R.string.ok, (DialogInterface dialog, int whichButton) -> {
-                        // handler.cancel is called via OnCancelListener.
-                        dialog.cancel();
-                    })
-                    .setOnCancelListener((DialogInterface dialogInterface) -> handler.cancel())
-                    .create();
-            sslAlertDialog.show();
-        }
-
-        private void setViewSecurityCertificate(LinearLayout certificateLayout, SslError error) {
-            ((TextView) certificateLayout.findViewById(R.id.ssl_error_msg))
-                    .setText(sslErrorMessage(error));
-            SslCertificate cert = error.getCertificate();
-            // TODO: call the method directly once inflateCertificateView is @SystemApi
-            try {
-                final View certificateView = (View) SslCertificate.class.getMethod(
-                        "inflateCertificateView", Context.class)
-                        .invoke(cert, CaptivePortalLoginActivity.this);
-                certificateLayout.addView(certificateView);
-            } catch (ReflectiveOperationException | SecurityException e) {
-                Log.e(TAG, "Could not create certificate view", e);
-            }
-        }
-    }
-
-    private class MyWebChromeClient extends WebChromeClient {
-        @Override
-        public void onProgressChanged(WebView view, int newProgress) {
-            getProgressBar().setProgress(newProgress);
-        }
-    }
-
-    private ProgressBar getProgressBar() {
-        return findViewById(R.id.progress_bar);
-    }
-
-    private WebView getWebview() {
-        return findViewById(R.id.webview);
-    }
-
-    private String getHeaderTitle() {
-        NetworkCapabilities nc = mCm.getNetworkCapabilities(mNetwork);
-        final String ssid = getSsid();
-        if (TextUtils.isEmpty(ssid)
-                || nc == null || !nc.hasTransport(NetworkCapabilities.TRANSPORT_WIFI)) {
-            return getString(R.string.action_bar_label);
-        }
-        return getString(R.string.action_bar_title, ssid);
-    }
-
-    // TODO: remove once SSID is obtained from NetworkCapabilities
-    private String getSsid() {
-        if (mWifiManager == null) {
-            return null;
-        }
-        final WifiInfo wifiInfo = mWifiManager.getConnectionInfo();
-        return removeDoubleQuotes(wifiInfo.getSSID());
-    }
-
-    private static String removeDoubleQuotes(String string) {
-        if (string == null) return null;
-        final int length = string.length();
-        if ((length > 1) && (string.charAt(0) == '"') && (string.charAt(length - 1) == '"')) {
-            return string.substring(1, length - 1);
-        }
-        return string;
-    }
-
-    private String getHeaderSubtitle(URL url) {
-        String host = host(url);
-        final String https = "https";
-        if (https.equals(url.getProtocol())) {
-            return https + "://" + host;
-        }
-        return host;
-    }
-
-    private void logMetricsEvent(int event) {
-        mCaptivePortal.logEvent(event, getPackageName());
-    }
-
-    private static final SparseArray<String> SSL_ERRORS = new SparseArray<>();
-    static {
-        SSL_ERRORS.put(SslError.SSL_NOTYETVALID,  "SSL_NOTYETVALID");
-        SSL_ERRORS.put(SslError.SSL_EXPIRED,      "SSL_EXPIRED");
-        SSL_ERRORS.put(SslError.SSL_IDMISMATCH,   "SSL_IDMISMATCH");
-        SSL_ERRORS.put(SslError.SSL_UNTRUSTED,    "SSL_UNTRUSTED");
-        SSL_ERRORS.put(SslError.SSL_DATE_INVALID, "SSL_DATE_INVALID");
-        SSL_ERRORS.put(SslError.SSL_INVALID,      "SSL_INVALID");
-    }
-
-    private static String sslErrorName(SslError error) {
-        return SSL_ERRORS.get(error.getPrimaryError(), "UNKNOWN");
-    }
-
-    private static final SparseArray<Integer> SSL_ERROR_MSGS = new SparseArray<>();
-    static {
-        SSL_ERROR_MSGS.put(SslError.SSL_NOTYETVALID,  R.string.ssl_error_not_yet_valid);
-        SSL_ERROR_MSGS.put(SslError.SSL_EXPIRED,      R.string.ssl_error_expired);
-        SSL_ERROR_MSGS.put(SslError.SSL_IDMISMATCH,   R.string.ssl_error_mismatch);
-        SSL_ERROR_MSGS.put(SslError.SSL_UNTRUSTED,    R.string.ssl_error_untrusted);
-        SSL_ERROR_MSGS.put(SslError.SSL_DATE_INVALID, R.string.ssl_error_date_invalid);
-        SSL_ERROR_MSGS.put(SslError.SSL_INVALID,      R.string.ssl_error_invalid);
-    }
-
-    private static Integer sslErrorMessage(SslError error) {
-        return SSL_ERROR_MSGS.get(error.getPrimaryError(), R.string.ssl_error_unknown);
-    }
-}
diff --git a/packages/CarSystemUI/res/layout/car_volume_item.xml b/packages/CarSystemUI/res/layout/car_volume_item.xml
index 2275ca6..0b42904 100644
--- a/packages/CarSystemUI/res/layout/car_volume_item.xml
+++ b/packages/CarSystemUI/res/layout/car_volume_item.xml
@@ -19,16 +19,18 @@
     xmlns:android="http://schemas.android.com/apk/res/android"
     android:layout_width="match_parent"
     android:layout_height="wrap_content"
+    android:background="@color/car_volume_dialog_background_color"
+    android:paddingStart="@dimen/car_volume_item_padding_start"
+    android:paddingEnd="@dimen/car_volume_item_padding_end"
     android:minHeight="@dimen/car_volume_item_height">
 
     <!-- Primary Action. -->
     <ImageView
         android:id="@+id/primary_icon"
-        android:layout_width="@dimen/car_primary_icon_size"
+        android:layout_width="@dimen/car_volume_item_icon_size"
         android:layout_centerVertical="true"
-        android:layout_marginStart="@dimen/car_volume_item_margin_horizontal"
         android:layout_alignParentStart="true"
-        android:layout_height="@dimen/car_primary_icon_size"/>
+        android:layout_height="@dimen/car_volume_item_icon_size"/>
 
     <!-- Note: the horizontal padding and offset are set to 0 so that the track and thumb
              aligns with the proper keylines. -->
@@ -61,11 +63,10 @@
         android:background="@color/car_volume_item_divider_color"/>
     <ImageView
         android:id="@+id/supplemental_icon"
-        android:layout_width="@dimen/car_primary_icon_size"
-        android:layout_height="@dimen/car_primary_icon_size"
+        android:layout_width="@dimen/car_volume_item_icon_size"
+        android:layout_height="@dimen/car_volume_item_icon_size"
         android:background="?android:attr/selectableItemBackground"
         android:layout_centerVertical="true"
         android:layout_alignParentEnd="true"
-        android:layout_marginEnd="@dimen/car_volume_item_margin_horizontal"
         android:scaleType="fitCenter"/>
 </RelativeLayout>
diff --git a/packages/CarSystemUI/res/values/colors.xml b/packages/CarSystemUI/res/values/colors.xml
index 72914f7..e13c940 100644
--- a/packages/CarSystemUI/res/values/colors.xml
+++ b/packages/CarSystemUI/res/values/colors.xml
@@ -32,11 +32,14 @@
     <color name="system_bar_background_opaque">#ff172026</color>
 
     <color name="status_bar_background_color">#33000000</color>
-    <drawable name="system_bar_background">@color/status_bar_background_color</drawable>
+    <drawable name="system_bar_background">@android:color/transparent</drawable>
 
     <!-- The background color of the notification shade -->
     <color name="notification_shade_background_color">#DD000000</color>
 
+    <!-- The background color of the car volume dialog -->
+    <color name="car_volume_dialog_background_color">@color/system_bar_background_opaque</color>
+
     <!-- The color of the dividing line between grouped notifications. -->
     <color name="notification_divider_color">@*android:color/notification_action_list</color>
 
diff --git a/packages/CarSystemUI/res/values/dimens.xml b/packages/CarSystemUI/res/values/dimens.xml
index 0358357b..7017484 100644
--- a/packages/CarSystemUI/res/values/dimens.xml
+++ b/packages/CarSystemUI/res/values/dimens.xml
@@ -78,8 +78,10 @@
     <dimen name="ongoing_appops_chip_bg_corner_radius">12dp</dimen>
 
     <!-- Car volume dimens. -->
+    <dimen name="car_volume_item_icon_size">@dimen/car_primary_icon_size</dimen>
     <dimen name="car_volume_item_height">@*android:dimen/car_single_line_list_item_height</dimen>
-    <dimen name="car_volume_item_margin_horizontal">@*android:dimen/car_keyline_1</dimen>
+    <dimen name="car_volume_item_padding_start">@*android:dimen/car_keyline_1</dimen>
+    <dimen name="car_volume_item_padding_end">@*android:dimen/car_keyline_1</dimen>
     <dimen name="car_volume_item_seekbar_margin_vertical">@*android:dimen/car_padding_1</dimen>
     <dimen name="car_volume_item_seekbar_margin_start">@*android:dimen/car_keyline_3</dimen>
     <dimen name="car_volume_item_seekbar_margin_end">@*android:dimen/car_padding_4</dimen>
diff --git a/packages/CarSystemUI/src/com/android/systemui/statusbar/car/CarStatusBar.java b/packages/CarSystemUI/src/com/android/systemui/statusbar/car/CarStatusBar.java
index 7fbdc2e..16b0125 100644
--- a/packages/CarSystemUI/src/com/android/systemui/statusbar/car/CarStatusBar.java
+++ b/packages/CarSystemUI/src/com/android/systemui/statusbar/car/CarStatusBar.java
@@ -63,6 +63,7 @@
 import com.android.systemui.classifier.FalsingLog;
 import com.android.systemui.classifier.FalsingManagerFactory;
 import com.android.systemui.fragments.FragmentHostManager;
+import com.android.systemui.keyguard.ScreenLifecycle;
 import com.android.systemui.plugins.qs.QS;
 import com.android.systemui.qs.car.CarQSFragment;
 import com.android.systemui.shared.system.ActivityManagerWrapper;
@@ -127,6 +128,7 @@
     private SwitchToGuestTimer mSwitchToGuestTimer;
     private NotificationDataManager mNotificationDataManager;
     private NotificationClickHandlerFactory mNotificationClickHandlerFactory;
+    private ScreenLifecycle mScreenLifecycle;
 
     // The container for the notifications.
     private CarNotificationView mNotificationView;
@@ -230,6 +232,9 @@
         mPowerManagerHelper.connectToCarService();
 
         mSwitchToGuestTimer = new SwitchToGuestTimer(mContext);
+
+        mScreenLifecycle = Dependency.get(ScreenLifecycle.class);
+        mScreenLifecycle.addObserver(mScreenObserver);
     }
 
     /**
@@ -315,7 +320,6 @@
     public void showKeyguard() {
         super.showKeyguard();
         updateNavBarForKeyguardContent();
-        dismissKeyguardWhenUserSwitcherNotDisplayed();
     }
 
     /**
@@ -978,6 +982,13 @@
         }
     }
 
+    final ScreenLifecycle.Observer mScreenObserver = new ScreenLifecycle.Observer() {
+        @Override
+        public void onScreenTurnedOn() {
+            dismissKeyguardWhenUserSwitcherNotDisplayed();
+        }
+    };
+
     // We automatically dismiss keyguard unless user switcher is being shown on the keyguard.
     private void dismissKeyguardWhenUserSwitcherNotDisplayed() {
         if (mFullscreenUserSwitcher == null) {
@@ -1000,6 +1011,10 @@
      * Dismisses the keyguard and shows bouncer if authentication is necessary.
      */
     public void dismissKeyguard() {
+        // Don't dismiss keyguard when the screen is off.
+        if (mScreenLifecycle.getScreenState() == ScreenLifecycle.SCREEN_OFF) {
+            return;
+        }
         executeRunnableDismissingKeyguard(null/* runnable */, null /* cancelAction */,
                 true /* dismissShade */, true /* afterKeyguardGone */, true /* deferred */);
     }
@@ -1259,6 +1274,10 @@
 
         @Override
         protected void setHeadsUpVisible() {
+            // if the Notifications panel is showing don't show the Heads up
+            if (mPanelExpanded) {
+                return;
+            }
             super.setHeadsUpVisible();
             if (mHeadsUpPanel.getVisibility() == View.VISIBLE) {
                 mStatusBarWindowController.setHeadsUpShowing(true);
diff --git a/packages/CarSystemUI/src/com/android/systemui/volume/CarVolumeDialogImpl.java b/packages/CarSystemUI/src/com/android/systemui/volume/CarVolumeDialogImpl.java
index 94962f7..d0a63f0 100644
--- a/packages/CarSystemUI/src/com/android/systemui/volume/CarVolumeDialogImpl.java
+++ b/packages/CarSystemUI/src/com/android/systemui/volume/CarVolumeDialogImpl.java
@@ -32,7 +32,9 @@
 import android.content.ServiceConnection;
 import android.content.res.TypedArray;
 import android.content.res.XmlResourceParser;
+import android.graphics.Color;
 import android.graphics.PixelFormat;
+import android.graphics.drawable.ColorDrawable;
 import android.graphics.drawable.Drawable;
 import android.media.AudioManager;
 import android.os.Debug;
@@ -245,6 +247,7 @@
         mExpanded = false;
         mWindow = mDialog.getWindow();
         mWindow.requestFeature(Window.FEATURE_NO_TITLE);
+        mWindow.setBackgroundDrawable(new ColorDrawable(Color.TRANSPARENT));
         mWindow.clearFlags(WindowManager.LayoutParams.FLAG_DIM_BEHIND
                 | WindowManager.LayoutParams.FLAG_LAYOUT_INSET_DECOR);
         mWindow.addFlags(WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
diff --git a/packages/ExtServices/Android.bp b/packages/ExtServices/Android.bp
deleted file mode 100644
index 77972fe..0000000
--- a/packages/ExtServices/Android.bp
+++ /dev/null
@@ -1,11 +0,0 @@
-android_library {
-    name: "ExtServices-core",
-     srcs: [
-         "src/**/*.java",
-     ],
-     resource_dirs: [
-         "res",
-     ],
-
-     manifest: "AndroidManifest.xml",
-}
\ No newline at end of file
diff --git a/packages/ExtServices/Android.mk b/packages/ExtServices/Android.mk
deleted file mode 100644
index a06dd86..0000000
--- a/packages/ExtServices/Android.mk
+++ /dev/null
@@ -1,40 +0,0 @@
-# Copyright (C) 2016 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.
-
-LOCAL_PATH:= $(call my-dir)
-
-include $(CLEAR_VARS)
-
-LOCAL_MODULE_TAGS := optional
-
-LOCAL_SRC_FILES := $(call all-java-files-under, src)
-
-LOCAL_PACKAGE_NAME := ExtServices
-LOCAL_PRIVATE_PLATFORM_APIS := true
-
-LOCAL_CERTIFICATE := platform
-
-LOCAL_PROGUARD_FLAG_FILES := proguard.proguard
-
-LOCAL_PRIVILEGED_MODULE := true
-
-LOCAL_MIN_SDK_VERSION := 28
-
-include $(BUILD_PACKAGE)
-
-# Use the following include to make our test apk.
-ifeq ($(strip $(LOCAL_PACKAGE_OVERRIDES)),)
-include $(call all-makefiles-under, $(LOCAL_PATH))
-endif
-
diff --git a/packages/ExtServices/AndroidManifest.xml b/packages/ExtServices/AndroidManifest.xml
deleted file mode 100644
index 8592fc9..0000000
--- a/packages/ExtServices/AndroidManifest.xml
+++ /dev/null
@@ -1,96 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2016 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.
--->
-
-<manifest xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:androidprv="http://schemas.android.com/apk/prv/res/android"
-    package="android.ext.services"
-    android:versionCode="220000000"
-    android:versionName="1"
-    coreApp="true">
-
-    <uses-permission android:name="android.permission.PROVIDE_RESOLVER_RANKER_SERVICE" />
-    <uses-permission android:name="android.permission.READ_DEVICE_CONFIG" />
-
-    <uses-permission android:name="android.permission.MONITOR_DEFAULT_SMS_PACKAGE" />
-    <uses-permission android:name="android.permission.REQUEST_NOTIFICATION_ASSISTANT_SERVICE" />
-    <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
-
-    <uses-sdk
-        android:targetSdkVersion="28"
-    />
-
-    <application android:label="@string/app_name"
-        android:defaultToDeviceProtectedStorage="true"
-        android:directBootAware="true">
-
-        <service android:name=".storage.CacheQuotaServiceImpl"
-             android:permission="android.permission.BIND_CACHE_QUOTA_SERVICE">
-            <intent-filter>
-                <action android:name="android.app.usage.CacheQuotaService" />
-            </intent-filter>
-        </service>
-
-        <service android:name=".resolver.LRResolverRankerService"
-                 android:permission="android.permission.BIND_RESOLVER_RANKER_SERVICE">
-            <intent-filter android:priority="-1">
-                <action android:name="android.service.resolver.ResolverRankerService" />
-            </intent-filter>
-        </service>
-
-        <service android:name=".notification.Assistant"
-                 android:label="@string/notification_assistant"
-                 android:permission="android.permission.BIND_NOTIFICATION_ASSISTANT_SERVICE"
-                 android:exported="true">
-            <intent-filter>
-                <action android:name="android.service.notification.NotificationAssistantService" />
-            </intent-filter>
-        </service>
-
-        <service android:name=".autofill.AutofillFieldClassificationServiceImpl"
-             android:permission="android.permission.BIND_AUTOFILL_FIELD_CLASSIFICATION_SERVICE">
-            <intent-filter>
-                <action android:name="android.service.autofill.AutofillFieldClassificationService" />
-            </intent-filter>
-            <meta-data
-                android:name="android.autofill.field_classification.default_algorithm"
-                android:resource="@string/autofill_field_classification_default_algorithm" />
-            <meta-data
-                android:name="android.autofill.field_classification.available_algorithms"
-                android:resource="@array/autofill_field_classification_available_algorithms" />
-        </service>
-
-        <service android:name=".sms.FinancialSmsServiceImpl"
-                 android:permission="android.permission.BIND_FINANCIAL_SMS_SERVICE">
-            <intent-filter>
-                <action android:name="android.service.sms.action.FINANCIAL_SERVICE_INTENT" />
-            </intent-filter>
-        </service>
-
-        <service android:name=".watchdog.ExplicitHealthCheckServiceImpl"
-                 android:permission="android.permission.BIND_EXPLICIT_HEALTH_CHECK_SERVICE">
-            <intent-filter>
-                <action android:name="android.service.watchdog.ExplicitHealthCheckService" />
-            </intent-filter>
-        </service>
-
-        <activity android:name=".notification.CopyCodeActivity"
-                  android:exported="false"
-                  android:theme="@android:style/Theme.NoDisplay"/>
-
-        <library android:name="android.ext.services"/>
-    </application>
-
-</manifest>
diff --git a/packages/ExtServices/MODULE_LICENSE_APACHE2 b/packages/ExtServices/MODULE_LICENSE_APACHE2
deleted file mode 100644
index e69de29..0000000
--- a/packages/ExtServices/MODULE_LICENSE_APACHE2
+++ /dev/null
diff --git a/packages/ExtServices/NOTICE b/packages/ExtServices/NOTICE
deleted file mode 100644
index c5b1efa..0000000
--- a/packages/ExtServices/NOTICE
+++ /dev/null
@@ -1,190 +0,0 @@
-
-   Copyright (c) 2005-2008, 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.
-
-   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.
-
-
-                                 Apache License
-                           Version 2.0, January 2004
-                        http://www.apache.org/licenses/
-
-   TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
-
-   1. Definitions.
-
-      "License" shall mean the terms and conditions for use, reproduction,
-      and distribution as defined by Sections 1 through 9 of this document.
-
-      "Licensor" shall mean the copyright owner or entity authorized by
-      the copyright owner that is granting the License.
-
-      "Legal Entity" shall mean the union of the acting entity and all
-      other entities that control, are controlled by, or are under common
-      control with that entity. For the purposes of this definition,
-      "control" means (i) the power, direct or indirect, to cause the
-      direction or management of such entity, whether by contract or
-      otherwise, or (ii) ownership of fifty percent (50%) or more of the
-      outstanding shares, or (iii) beneficial ownership of such entity.
-
-      "You" (or "Your") shall mean an individual or Legal Entity
-      exercising permissions granted by this License.
-
-      "Source" form shall mean the preferred form for making modifications,
-      including but not limited to software source code, documentation
-      source, and configuration files.
-
-      "Object" form shall mean any form resulting from mechanical
-      transformation or translation of a Source form, including but
-      not limited to compiled object code, generated documentation,
-      and conversions to other media types.
-
-      "Work" shall mean the work of authorship, whether in Source or
-      Object form, made available under the License, as indicated by a
-      copyright notice that is included in or attached to the work
-      (an example is provided in the Appendix below).
-
-      "Derivative Works" shall mean any work, whether in Source or Object
-      form, that is based on (or derived from) the Work and for which the
-      editorial revisions, annotations, elaborations, or other modifications
-      represent, as a whole, an original work of authorship. For the purposes
-      of this License, Derivative Works shall not include works that remain
-      separable from, or merely link (or bind by name) to the interfaces of,
-      the Work and Derivative Works thereof.
-
-      "Contribution" shall mean any work of authorship, including
-      the original version of the Work and any modifications or additions
-      to that Work or Derivative Works thereof, that is intentionally
-      submitted to Licensor for inclusion in the Work by the copyright owner
-      or by an individual or Legal Entity authorized to submit on behalf of
-      the copyright owner. For the purposes of this definition, "submitted"
-      means any form of electronic, verbal, or written communication sent
-      to the Licensor or its representatives, including but not limited to
-      communication on electronic mailing lists, source code control systems,
-      and issue tracking systems that are managed by, or on behalf of, the
-      Licensor for the purpose of discussing and improving the Work, but
-      excluding communication that is conspicuously marked or otherwise
-      designated in writing by the copyright owner as "Not a Contribution."
-
-      "Contributor" shall mean Licensor and any individual or Legal Entity
-      on behalf of whom a Contribution has been received by Licensor and
-      subsequently incorporated within the Work.
-
-   2. Grant of Copyright License. Subject to the terms and conditions of
-      this License, each Contributor hereby grants to You a perpetual,
-      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
-      copyright license to reproduce, prepare Derivative Works of,
-      publicly display, publicly perform, sublicense, and distribute the
-      Work and such Derivative Works in Source or Object form.
-
-   3. Grant of Patent License. Subject to the terms and conditions of
-      this License, each Contributor hereby grants to You a perpetual,
-      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
-      (except as stated in this section) patent license to make, have made,
-      use, offer to sell, sell, import, and otherwise transfer the Work,
-      where such license applies only to those patent claims licensable
-      by such Contributor that are necessarily infringed by their
-      Contribution(s) alone or by combination of their Contribution(s)
-      with the Work to which such Contribution(s) was submitted. If You
-      institute patent litigation against any entity (including a
-      cross-claim or counterclaim in a lawsuit) alleging that the Work
-      or a Contribution incorporated within the Work constitutes direct
-      or contributory patent infringement, then any patent licenses
-      granted to You under this License for that Work shall terminate
-      as of the date such litigation is filed.
-
-   4. Redistribution. You may reproduce and distribute copies of the
-      Work or Derivative Works thereof in any medium, with or without
-      modifications, and in Source or Object form, provided that You
-      meet the following conditions:
-
-      (a) You must give any other recipients of the Work or
-          Derivative Works a copy of this License; and
-
-      (b) You must cause any modified files to carry prominent notices
-          stating that You changed the files; and
-
-      (c) You must retain, in the Source form of any Derivative Works
-          that You distribute, all copyright, patent, trademark, and
-          attribution notices from the Source form of the Work,
-          excluding those notices that do not pertain to any part of
-          the Derivative Works; and
-
-      (d) If the Work includes a "NOTICE" text file as part of its
-          distribution, then any Derivative Works that You distribute must
-          include a readable copy of the attribution notices contained
-          within such NOTICE file, excluding those notices that do not
-          pertain to any part of the Derivative Works, in at least one
-          of the following places: within a NOTICE text file distributed
-          as part of the Derivative Works; within the Source form or
-          documentation, if provided along with the Derivative Works; or,
-          within a display generated by the Derivative Works, if and
-          wherever such third-party notices normally appear. The contents
-          of the NOTICE file are for informational purposes only and
-          do not modify the License. You may add Your own attribution
-          notices within Derivative Works that You distribute, alongside
-          or as an addendum to the NOTICE text from the Work, provided
-          that such additional attribution notices cannot be construed
-          as modifying the License.
-
-      You may add Your own copyright statement to Your modifications and
-      may provide additional or different license terms and conditions
-      for use, reproduction, or distribution of Your modifications, or
-      for any such Derivative Works as a whole, provided Your use,
-      reproduction, and distribution of the Work otherwise complies with
-      the conditions stated in this License.
-
-   5. Submission of Contributions. Unless You explicitly state otherwise,
-      any Contribution intentionally submitted for inclusion in the Work
-      by You to the Licensor shall be under the terms and conditions of
-      this License, without any additional terms or conditions.
-      Notwithstanding the above, nothing herein shall supersede or modify
-      the terms of any separate license agreement you may have executed
-      with Licensor regarding such Contributions.
-
-   6. Trademarks. This License does not grant permission to use the trade
-      names, trademarks, service marks, or product names of the Licensor,
-      except as required for reasonable and customary use in describing the
-      origin of the Work and reproducing the content of the NOTICE file.
-
-   7. Disclaimer of Warranty. Unless required by applicable law or
-      agreed to in writing, Licensor provides the Work (and each
-      Contributor provides its Contributions) on an "AS IS" BASIS,
-      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
-      implied, including, without limitation, any warranties or conditions
-      of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
-      PARTICULAR PURPOSE. You are solely responsible for determining the
-      appropriateness of using or redistributing the Work and assume any
-      risks associated with Your exercise of permissions under this License.
-
-   8. Limitation of Liability. In no event and under no legal theory,
-      whether in tort (including negligence), contract, or otherwise,
-      unless required by applicable law (such as deliberate and grossly
-      negligent acts) or agreed to in writing, shall any Contributor be
-      liable to You for damages, including any direct, indirect, special,
-      incidental, or consequential damages of any character arising as a
-      result of this License or out of the use or inability to use the
-      Work (including but not limited to damages for loss of goodwill,
-      work stoppage, computer failure or malfunction, or any and all
-      other commercial damages or losses), even if such Contributor
-      has been advised of the possibility of such damages.
-
-   9. Accepting Warranty or Additional Liability. While redistributing
-      the Work or Derivative Works thereof, You may choose to offer,
-      and charge a fee for, acceptance of support, warranty, indemnity,
-      or other liability obligations and/or rights consistent with this
-      License. However, in accepting such obligations, You may act only
-      on Your own behalf and on Your sole responsibility, not on behalf
-      of any other Contributor, and only if You agree to indemnify,
-      defend, and hold each Contributor harmless for any liability
-      incurred by, or claims asserted against, such Contributor by reason
-      of your accepting any such warranty or additional liability.
-
-   END OF TERMS AND CONDITIONS
-
diff --git a/packages/ExtServices/OWNERS b/packages/ExtServices/OWNERS
deleted file mode 100644
index bf52f35..0000000
--- a/packages/ExtServices/OWNERS
+++ /dev/null
@@ -1,4 +0,0 @@
-set noparent
-
-baligh@google.com
-delphij@google.com
diff --git a/packages/ExtServices/proguard.proguard b/packages/ExtServices/proguard.proguard
deleted file mode 100644
index e5dfbe1..0000000
--- a/packages/ExtServices/proguard.proguard
+++ /dev/null
@@ -1,7 +0,0 @@
--keepparameternames
--keepattributes Exceptions,InnerClasses,Signature,Deprecated,
-                SourceFile,LineNumberTable,*Annotation*,EnclosingMethod
-
--keep public class * {
-    public protected *;
-}
diff --git a/packages/ExtServices/res/values/strings.xml b/packages/ExtServices/res/values/strings.xml
deleted file mode 100644
index 58deb11..0000000
--- a/packages/ExtServices/res/values/strings.xml
+++ /dev/null
@@ -1,33 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2016 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.
--->
-
-<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="app_name">Android Services Library</string>
-
-    <string name="notification_assistant">Android Adaptive Notifications</string>
-
-    <string name="autofill_field_classification_default_algorithm">EDIT_DISTANCE</string>
-    <string-array name="autofill_field_classification_available_algorithms">
-        <item>EDIT_DISTANCE</item>
-        <item>EXACT_MATCH</item>
-    </string-array>
-
-    <!-- Action chip to copy a one time code to the user's clipboard [CHAR LIMIT=NONE]-->
-    <string name="copy_code_desc">Copy \u201c<xliff:g id="code" example="12345">%1$s</xliff:g>\u201c</string>
-    <!-- Toast to display when text is copied to the device clipboard [CHAR LIMIT=64]-->
-    <string name="code_copied_to_clipboard">Code copied</string>
-
-</resources>
diff --git a/packages/ExtServices/src/android/ext/services/Version.java b/packages/ExtServices/src/android/ext/services/Version.java
deleted file mode 100644
index 026cccd..0000000
--- a/packages/ExtServices/src/android/ext/services/Version.java
+++ /dev/null
@@ -1,36 +0,0 @@
-/*
- * Copyright (C) 2016 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.ext.services;
-
-/**
- * Class that provides the version of the library.
- */
-public final class Version {
-
-    private Version() {
-        /* do nothing - hide constructor */
-    }
-
-    /**
-     * Gets the version of the library.
-     *
-     * @return The version.
-     */
-    public static int getVersionCode() {
-        return 1;
-    }
-}
\ No newline at end of file
diff --git a/packages/ExtServices/src/android/ext/services/autofill/AutofillFieldClassificationServiceImpl.java b/packages/ExtServices/src/android/ext/services/autofill/AutofillFieldClassificationServiceImpl.java
deleted file mode 100644
index e379db8..0000000
--- a/packages/ExtServices/src/android/ext/services/autofill/AutofillFieldClassificationServiceImpl.java
+++ /dev/null
@@ -1,95 +0,0 @@
-/*
- * Copyright (C) 2018 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package android.ext.services.autofill;
-
-import android.annotation.NonNull;
-import android.annotation.Nullable;
-import android.os.Bundle;
-import android.service.autofill.AutofillFieldClassificationService;
-import android.util.Log;
-import android.view.autofill.AutofillValue;
-
-import com.android.internal.util.ArrayUtils;
-
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-
-public class AutofillFieldClassificationServiceImpl extends AutofillFieldClassificationService {
-
-    private static final String TAG = "AutofillFieldClassificationServiceImpl";
-
-    private static final String DEFAULT_ALGORITHM = REQUIRED_ALGORITHM_EDIT_DISTANCE;
-
-    @Nullable
-    @Override
-    /** @hide */
-    public float[][] onCalculateScores(@NonNull List<AutofillValue> actualValues,
-            @NonNull List<String> userDataValues, @NonNull List<String> categoryIds,
-            @Nullable String defaultAlgorithm, @Nullable Bundle defaultArgs,
-            @Nullable Map algorithms, @Nullable Map args) {
-        if (ArrayUtils.isEmpty(actualValues) || ArrayUtils.isEmpty(userDataValues)) {
-            Log.w(TAG, "calculateScores(): empty currentvalues (" + actualValues
-                    + ") or userValues (" + userDataValues + ")");
-            return null;
-        }
-
-        return calculateScores(actualValues, userDataValues, categoryIds, defaultAlgorithm,
-                defaultArgs, (HashMap<String, String>) algorithms,
-                (HashMap<String, Bundle>) args);
-    }
-
-    /** @hide */
-    public float[][] calculateScores(@NonNull List<AutofillValue> actualValues,
-            @NonNull List<String> userDataValues, @NonNull List<String> categoryIds,
-            @Nullable String defaultAlgorithm, @Nullable Bundle defaultArgs,
-            @Nullable HashMap<String, String> algorithms,
-            @Nullable HashMap<String, Bundle> args) {
-        final int actualValuesSize = actualValues.size();
-        final int userDataValuesSize = userDataValues.size();
-        final float[][] scores = new float[actualValuesSize][userDataValuesSize];
-
-        for (int j = 0; j < userDataValuesSize; j++) {
-            final String categoryId = categoryIds.get(j);
-            String algorithmName = defaultAlgorithm;
-            Bundle arg = defaultArgs;
-            if (algorithms != null && algorithms.containsKey(categoryId)) {
-                algorithmName = algorithms.get(categoryId);
-            }
-            if (args != null && args.containsKey(categoryId)) {
-                arg = args.get(categoryId);
-            }
-
-            if (algorithmName == null || (!algorithmName.equals(DEFAULT_ALGORITHM)
-                    && !algorithmName.equals(REQUIRED_ALGORITHM_EXACT_MATCH))) {
-                Log.w(TAG, "algorithmName is " + algorithmName + ", defaulting to "
-                        + DEFAULT_ALGORITHM);
-                algorithmName = DEFAULT_ALGORITHM;
-            }
-
-            for (int i = 0; i < actualValuesSize; i++) {
-                if (algorithmName.equals(DEFAULT_ALGORITHM)) {
-                    scores[i][j] = EditDistanceScorer.calculateScore(actualValues.get(i),
-                            userDataValues.get(j));
-                } else {
-                    scores[i][j] = ExactMatch.calculateScore(actualValues.get(i),
-                            userDataValues.get(j), arg);
-                }
-            }
-        }
-        return scores;
-    }
-}
diff --git a/packages/ExtServices/src/android/ext/services/autofill/EditDistanceScorer.java b/packages/ExtServices/src/android/ext/services/autofill/EditDistanceScorer.java
deleted file mode 100644
index 1962571..0000000
--- a/packages/ExtServices/src/android/ext/services/autofill/EditDistanceScorer.java
+++ /dev/null
@@ -1,123 +0,0 @@
-/*
- * Copyright (C) 2017 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.ext.services.autofill;
-
-import android.annotation.NonNull;
-import android.annotation.Nullable;
-import android.view.autofill.AutofillValue;
-
-import com.android.internal.annotations.VisibleForTesting;
-
-final class EditDistanceScorer {
-
-    private static final String TAG = "EditDistanceScorer";
-
-    // TODO(b/70291841): STOPSHIP - set to false before launching
-    private static final boolean DEBUG = true;
-
-    /**
-     * Gets the field classification score of 2 values based on the edit distance between them.
-     *
-     * <p>The score is defined as: @(max_length - edit_distance) / max_length
-     */
-    @VisibleForTesting
-    static float calculateScore(@Nullable AutofillValue actualValue,
-            @Nullable String userDataValue) {
-        if (actualValue == null || !actualValue.isText() || userDataValue == null) return 0;
-
-        final String actualValueText = actualValue.getTextValue().toString();
-        final int actualValueLength = actualValueText.length();
-        final int userDatalength = userDataValue.length();
-        if (userDatalength == 0) {
-            return (actualValueLength == 0) ? 1 : 0;
-        }
-
-        final int distance = editDistance(actualValueText.toLowerCase(),
-                userDataValue.toLowerCase());
-        final int maxLength = Math.max(actualValueLength, userDatalength);
-        return ((float) maxLength - distance) / maxLength;
-    }
-
-    /**
-     * Computes the edit distance (number of insertions, deletions or substitutions to edit one
-     * string into the other) between two strings. In particular, this will compute the Levenshtein
-     * distance.
-     *
-     * <p>See http://en.wikipedia.org/wiki/Levenshtein_distance for details.
-     *
-     * @param s the first string to compare
-     * @param t the second string to compare
-     * @return the edit distance between the two strings
-     */
-    // Note: copied verbatim from com.android.tools.lint.detector.api.LintUtils.java
-    public static int editDistance(@NonNull String s, @NonNull String t) {
-        return editDistance(s, t, Integer.MAX_VALUE);
-    }
-
-    /**
-     * Computes the edit distance (number of insertions, deletions or substitutions to edit one
-     * string into the other) between two strings. In particular, this will compute the Levenshtein
-     * distance.
-     *
-     * <p>See http://en.wikipedia.org/wiki/Levenshtein_distance for details.
-     *
-     * @param s the first string to compare
-     * @param t the second string to compare
-     * @param max the maximum edit distance that we care about; if for example the string length
-     *     delta is greater than this we don't bother computing the exact edit distance since the
-     *     caller has indicated they're not interested in the result
-     * @return the edit distance between the two strings, or some other value greater than that if
-     *     the edit distance is at least as big as the {@code max} parameter
-     */
-    // Note: copied verbatim from com.android.tools.lint.detector.api.LintUtils.java
-    public static int editDistance(@NonNull String s, @NonNull String t, int max) {
-        if (s.equals(t)) {
-            return 0;
-        }
-
-        if (Math.abs(s.length() - t.length()) > max) {
-            // The string lengths differ more than the allowed edit distance;
-            // no point in even attempting to compute the edit distance (requires
-            // O(n*m) storage and O(n*m) speed, where n and m are the string lengths)
-            return Integer.MAX_VALUE;
-        }
-
-        int m = s.length();
-        int n = t.length();
-        int[][] d = new int[m + 1][n + 1];
-        for (int i = 0; i <= m; i++) {
-            d[i][0] = i;
-        }
-        for (int j = 0; j <= n; j++) {
-            d[0][j] = j;
-        }
-        for (int j = 1; j <= n; j++) {
-            for (int i = 1; i <= m; i++) {
-                if (s.charAt(i - 1) == t.charAt(j - 1)) {
-                    d[i][j] = d[i - 1][j - 1];
-                } else {
-                    int deletion = d[i - 1][j] + 1;
-                    int insertion = d[i][j - 1] + 1;
-                    int substitution = d[i - 1][j - 1] + 1;
-                    d[i][j] = Math.min(deletion, Math.min(insertion, substitution));
-                }
-            }
-        }
-
-        return d[m][n];
-    }
-
-}
diff --git a/packages/ExtServices/src/android/ext/services/autofill/ExactMatch.java b/packages/ExtServices/src/android/ext/services/autofill/ExactMatch.java
deleted file mode 100644
index 3e55c5c..0000000
--- a/packages/ExtServices/src/android/ext/services/autofill/ExactMatch.java
+++ /dev/null
@@ -1,67 +0,0 @@
-/*
- * Copyright (C) 2018 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package android.ext.services.autofill;
-
-import android.annotation.Nullable;
-import android.os.Bundle;
-import android.view.autofill.AutofillValue;
-
-import com.android.internal.annotations.VisibleForTesting;
-
-final class ExactMatch {
-
-    /**
-     * Gets the field classification score of 2 values based on whether they are an exact match
-     *
-     * @return {@code 1.0} if the two values are an exact match, {@code 0.0} otherwise.
-     */
-    @VisibleForTesting
-    static float calculateScore(@Nullable AutofillValue actualValue,
-            @Nullable String userDataValue, @Nullable Bundle args) {
-        if (actualValue == null || !actualValue.isText() || userDataValue == null) return 0;
-
-        final String actualValueText = actualValue.getTextValue().toString();
-
-        final int suffixLength;
-        if (args != null) {
-            suffixLength = args.getInt("suffix", -1);
-
-            if (suffixLength < 0) {
-                throw new IllegalArgumentException("suffix argument is invalid");
-            }
-
-            final String actualValueSuffix;
-            if (suffixLength < actualValueText.length()) {
-                actualValueSuffix = actualValueText.substring(actualValueText.length()
-                        - suffixLength);
-            } else {
-                actualValueSuffix = actualValueText;
-            }
-
-            final String userDataValueSuffix;
-            if (suffixLength < userDataValue.length()) {
-                userDataValueSuffix = userDataValue.substring(userDataValue.length()
-                        - suffixLength);
-            } else {
-                userDataValueSuffix = userDataValue;
-            }
-
-            return (actualValueSuffix.equalsIgnoreCase(userDataValueSuffix)) ? 1 : 0;
-        } else {
-            return actualValueText.equalsIgnoreCase(userDataValue) ? 1 : 0;
-        }
-    }
-}
diff --git a/packages/ExtServices/src/android/ext/services/notification/AgingHelper.java b/packages/ExtServices/src/android/ext/services/notification/AgingHelper.java
deleted file mode 100644
index 31c9224..0000000
--- a/packages/ExtServices/src/android/ext/services/notification/AgingHelper.java
+++ /dev/null
@@ -1,172 +0,0 @@
-/**
- * Copyright (C) 2018 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package android.ext.services.notification;
-
-import static android.app.NotificationManager.IMPORTANCE_MIN;
-
-import android.app.AlarmManager;
-import android.app.PendingIntent;
-import android.content.BroadcastReceiver;
-import android.content.Context;
-import android.content.Intent;
-import android.content.IntentFilter;
-import android.ext.services.notification.NotificationCategorizer.Category;
-import android.net.Uri;
-import android.util.ArraySet;
-import android.util.Slog;
-
-import java.util.Set;
-
-public class AgingHelper {
-    private final static String TAG = "AgingHelper";
-    private final boolean DEBUG = false;
-
-    private static final String AGING_ACTION = AgingHelper.class.getSimpleName() + ".EVALUATE";
-    private static final int REQUEST_CODE_AGING = 1;
-    private static final String AGING_SCHEME = "aging";
-    private static final String EXTRA_KEY = "key";
-    private static final String EXTRA_CATEGORY = "category";
-
-    private static final int HOUR_MS = 1000 * 60 * 60;
-    private static final int TWO_HOURS_MS = 2 * HOUR_MS;
-
-    private Context mContext;
-    private NotificationCategorizer mNotificationCategorizer;
-    private AlarmManager mAm;
-    private Callback mCallback;
-
-    // The set of keys we've scheduled alarms for
-    private Set<String> mAging = new ArraySet<>();
-
-    public AgingHelper(Context context, NotificationCategorizer categorizer, Callback callback) {
-        mNotificationCategorizer = categorizer;
-        mContext = context;
-        mAm = mContext.getSystemService(AlarmManager.class);
-        mCallback = callback;
-
-        IntentFilter filter = new IntentFilter(AGING_ACTION);
-        filter.addDataScheme(AGING_SCHEME);
-        mContext.registerReceiver(mBroadcastReceiver, filter);
-    }
-
-    // NAS lifecycle methods
-
-    public void onNotificationSeen(NotificationEntry entry) {
-        // user has strong opinions about this notification. we can't down rank it, so don't bother.
-        if (entry.getChannel().hasUserSetImportance()) {
-            return;
-        }
-
-        @Category int category = mNotificationCategorizer.getCategory(entry);
-
-        // already very low
-        if (category == NotificationCategorizer.CATEGORY_MIN) {
-            return;
-        }
-
-        if (entry.hasSeen()) {
-            if (category == NotificationCategorizer.CATEGORY_ONGOING
-                    || category > NotificationCategorizer.CATEGORY_REMINDER) {
-                scheduleAging(entry.getSbn().getKey(), category, TWO_HOURS_MS);
-            } else {
-                scheduleAging(entry.getSbn().getKey(), category, HOUR_MS);
-            }
-
-            mAging.add(entry.getSbn().getKey());
-        }
-    }
-
-    public void onNotificationPosted(NotificationEntry entry) {
-        cancelAging(entry.getSbn().getKey());
-    }
-
-    public void onNotificationRemoved(String key) {
-        cancelAging(key);
-    }
-
-    public void onDestroy() {
-        mContext.unregisterReceiver(mBroadcastReceiver);
-    }
-
-    // Aging
-
-    private void scheduleAging(String key, @Category int category, long duration) {
-        if (mAging.contains(key)) {
-            // already scheduled. Don't reset aging just because the user saw the noti again.
-            return;
-        }
-        final PendingIntent pi = createPendingIntent(key, category);
-        long time = System.currentTimeMillis() + duration;
-        if (DEBUG) Slog.d(TAG, "Scheduling evaluate for " + key + " in ms: " + duration);
-        mAm.setExactAndAllowWhileIdle(AlarmManager.RTC_WAKEUP, time, pi);
-    }
-
-    private void cancelAging(String key) {
-        final PendingIntent pi = createPendingIntent(key);
-        mAm.cancel(pi);
-        mAging.remove(key);
-    }
-
-    private Intent createBaseIntent(String key) {
-        return new Intent(AGING_ACTION)
-                .setData(new Uri.Builder().scheme(AGING_SCHEME).appendPath(key).build());
-    }
-
-    private Intent createAgingIntent(String key, @Category int category) {
-        Intent intent = createBaseIntent(key);
-        intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND)
-                .putExtra(EXTRA_CATEGORY, category)
-                .putExtra(EXTRA_KEY, key);
-        return intent;
-    }
-
-    private PendingIntent createPendingIntent(String key, @Category int category) {
-        return PendingIntent.getBroadcast(mContext,
-                REQUEST_CODE_AGING,
-                createAgingIntent(key, category),
-                PendingIntent.FLAG_UPDATE_CURRENT);
-    }
-
-    private PendingIntent createPendingIntent(String key) {
-        return PendingIntent.getBroadcast(mContext,
-                REQUEST_CODE_AGING,
-                createBaseIntent(key),
-                PendingIntent.FLAG_UPDATE_CURRENT);
-    }
-
-    private void demote(String key, @Category int category) {
-        int newImportance = IMPORTANCE_MIN;
-        // TODO: Change "aged" importance based on category
-        mCallback.sendAdjustment(key, newImportance);
-    }
-
-    protected interface Callback {
-        void sendAdjustment(String key, int newImportance);
-    }
-
-    private final BroadcastReceiver mBroadcastReceiver = new BroadcastReceiver() {
-        @Override
-        public void onReceive(Context context, Intent intent) {
-            if (DEBUG) {
-                Slog.d(TAG, "Reposting notification");
-            }
-            if (AGING_ACTION.equals(intent.getAction())) {
-                demote(intent.getStringExtra(EXTRA_KEY), intent.getIntExtra(EXTRA_CATEGORY,
-                        NotificationCategorizer.CATEGORY_EVERYTHING_ELSE));
-            }
-        }
-    };
-}
diff --git a/packages/ExtServices/src/android/ext/services/notification/Assistant.java b/packages/ExtServices/src/android/ext/services/notification/Assistant.java
deleted file mode 100644
index d01878a..0000000
--- a/packages/ExtServices/src/android/ext/services/notification/Assistant.java
+++ /dev/null
@@ -1,514 +0,0 @@
-/**
- * Copyright (C) 2017 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.ext.services.notification;
-
-import static android.app.NotificationManager.IMPORTANCE_LOW;
-import static android.app.NotificationManager.IMPORTANCE_MIN;
-import static android.service.notification.Adjustment.KEY_IMPORTANCE;
-import static android.service.notification.NotificationListenerService.Ranking.USER_SENTIMENT_NEGATIVE;
-
-import android.annotation.NonNull;
-import android.annotation.Nullable;
-import android.annotation.SuppressLint;
-import android.app.ActivityThread;
-import android.app.INotificationManager;
-import android.app.Notification;
-import android.app.NotificationChannel;
-import android.content.Context;
-import android.content.pm.IPackageManager;
-import android.os.AsyncTask;
-import android.os.Bundle;
-import android.os.Environment;
-import android.os.UserHandle;
-import android.os.storage.StorageManager;
-import android.service.notification.Adjustment;
-import android.service.notification.NotificationAssistantService;
-import android.service.notification.NotificationStats;
-import android.service.notification.StatusBarNotification;
-import android.util.ArrayMap;
-import android.util.AtomicFile;
-import android.util.Log;
-import android.util.Slog;
-import android.util.Xml;
-
-import com.android.internal.annotations.VisibleForTesting;
-import com.android.internal.util.FastXmlSerializer;
-import com.android.internal.util.XmlUtils;
-
-import libcore.io.IoUtils;
-
-import org.xmlpull.v1.XmlPullParser;
-import org.xmlpull.v1.XmlPullParserException;
-import org.xmlpull.v1.XmlSerializer;
-
-import java.io.File;
-import java.io.FileNotFoundException;
-import java.io.FileOutputStream;
-import java.io.IOException;
-import java.io.InputStream;
-import java.nio.charset.StandardCharsets;
-import java.util.ArrayList;
-import java.util.List;
-import java.util.Map;
-import java.util.concurrent.ExecutorService;
-import java.util.concurrent.Executors;
-
-/**
- * Notification assistant that provides guidance on notification channel blocking
- */
-@SuppressLint("OverrideAbstract")
-public class Assistant extends NotificationAssistantService {
-    private static final String TAG = "ExtAssistant";
-    private static final boolean DEBUG = Log.isLoggable(TAG, Log.DEBUG);
-
-    private static final String TAG_ASSISTANT = "assistant";
-    private static final String TAG_IMPRESSION = "impression-set";
-    private static final String ATT_KEY = "key";
-    private static final int DB_VERSION = 1;
-    private static final String ATTR_VERSION = "version";
-    private final ExecutorService mSingleThreadExecutor = Executors.newSingleThreadExecutor();
-
-    private static final ArrayList<Integer> PREJUDICAL_DISMISSALS = new ArrayList<>();
-    static {
-        PREJUDICAL_DISMISSALS.add(REASON_CANCEL);
-        PREJUDICAL_DISMISSALS.add(REASON_LISTENER_CANCEL);
-    }
-
-    private SmartActionsHelper mSmartActionsHelper;
-    private NotificationCategorizer mNotificationCategorizer;
-
-    // key : impressions tracker
-    // TODO: prune deleted channels and apps
-    private final ArrayMap<String, ChannelImpressions> mkeyToImpressions = new ArrayMap<>();
-    // SBN key : entry
-    protected ArrayMap<String, NotificationEntry> mLiveNotifications = new ArrayMap<>();
-
-    private Ranking mFakeRanking = null;
-    private AtomicFile mFile = null;
-    private IPackageManager mPackageManager;
-
-    @VisibleForTesting
-    protected AssistantSettings.Factory mSettingsFactory = AssistantSettings.FACTORY;
-    @VisibleForTesting
-    protected AssistantSettings mSettings;
-    private SmsHelper mSmsHelper;
-
-    public Assistant() {
-    }
-
-    @Override
-    public void onCreate() {
-        super.onCreate();
-        // Contexts are correctly hooked up by the creation step, which is required for the observer
-        // to be hooked up/initialized.
-        mPackageManager = ActivityThread.getPackageManager();
-        mSettings = mSettingsFactory.createAndRegister(mHandler,
-                getApplicationContext().getContentResolver(), getUserId(), this::updateThresholds);
-        mSmartActionsHelper = new SmartActionsHelper(getContext(), mSettings);
-        mNotificationCategorizer = new NotificationCategorizer();
-        mSmsHelper = new SmsHelper(this);
-        mSmsHelper.initialize();
-    }
-
-    @Override
-    public void onDestroy() {
-        // This null check is only for the unit tests as ServiceTestCase.tearDown calls onDestroy
-        // without having first called onCreate.
-        if (mSmsHelper != null) {
-            mSmsHelper.destroy();
-        }
-        super.onDestroy();
-    }
-
-    private void loadFile() {
-        if (DEBUG) Slog.d(TAG, "loadFile");
-        AsyncTask.execute(() -> {
-            InputStream infile = null;
-            try {
-                infile = mFile.openRead();
-                readXml(infile);
-            } catch (FileNotFoundException e) {
-                Log.d(TAG, "File doesn't exist or isn't readable yet");
-            } catch (IOException e) {
-                Log.e(TAG, "Unable to read channel impressions", e);
-            } catch (NumberFormatException | XmlPullParserException e) {
-                Log.e(TAG, "Unable to parse channel impressions", e);
-            } finally {
-                IoUtils.closeQuietly(infile);
-            }
-        });
-    }
-
-    protected void readXml(InputStream stream)
-            throws XmlPullParserException, NumberFormatException, IOException {
-        final XmlPullParser parser = Xml.newPullParser();
-        parser.setInput(stream, StandardCharsets.UTF_8.name());
-        final int outerDepth = parser.getDepth();
-        while (XmlUtils.nextElementWithin(parser, outerDepth)) {
-            if (!TAG_ASSISTANT.equals(parser.getName())) {
-                continue;
-            }
-            final int impressionOuterDepth = parser.getDepth();
-            while (XmlUtils.nextElementWithin(parser, impressionOuterDepth)) {
-                if (!TAG_IMPRESSION.equals(parser.getName())) {
-                    continue;
-                }
-                String key = parser.getAttributeValue(null, ATT_KEY);
-                ChannelImpressions ci = createChannelImpressionsWithThresholds();
-                ci.populateFromXml(parser);
-                synchronized (mkeyToImpressions) {
-                    ci.append(mkeyToImpressions.get(key));
-                    mkeyToImpressions.put(key, ci);
-                }
-            }
-        }
-    }
-
-    private void saveFile() {
-        AsyncTask.execute(() -> {
-            final FileOutputStream stream;
-            try {
-                stream = mFile.startWrite();
-            } catch (IOException e) {
-                Slog.w(TAG, "Failed to save policy file", e);
-                return;
-            }
-            try {
-                final XmlSerializer out = new FastXmlSerializer();
-                out.setOutput(stream, StandardCharsets.UTF_8.name());
-                writeXml(out);
-                mFile.finishWrite(stream);
-            } catch (IOException e) {
-                Slog.w(TAG, "Failed to save impressions file, restoring backup", e);
-                mFile.failWrite(stream);
-            }
-        });
-    }
-
-    protected void writeXml(XmlSerializer out) throws IOException {
-        out.startDocument(null, true);
-        out.startTag(null, TAG_ASSISTANT);
-        out.attribute(null, ATTR_VERSION, Integer.toString(DB_VERSION));
-        synchronized (mkeyToImpressions) {
-            for (Map.Entry<String, ChannelImpressions> entry
-                    : mkeyToImpressions.entrySet()) {
-                // TODO: ensure channel still exists
-                out.startTag(null, TAG_IMPRESSION);
-                out.attribute(null, ATT_KEY, entry.getKey());
-                entry.getValue().writeXml(out);
-                out.endTag(null, TAG_IMPRESSION);
-            }
-        }
-        out.endTag(null, TAG_ASSISTANT);
-        out.endDocument();
-    }
-
-    @Override
-    public Adjustment onNotificationEnqueued(StatusBarNotification sbn) {
-        // we use the version with channel, so this is never called.
-        return null;
-    }
-
-    @Override
-    public Adjustment onNotificationEnqueued(StatusBarNotification sbn,
-            NotificationChannel channel) {
-        if (DEBUG) Log.i(TAG, "ENQUEUED " + sbn.getKey() + " on " + channel.getId());
-        if (!isForCurrentUser(sbn)) {
-            return null;
-        }
-        mSingleThreadExecutor.submit(() -> {
-            NotificationEntry entry =
-                    new NotificationEntry(getContext(), mPackageManager, sbn, channel, mSmsHelper);
-            SmartActionsHelper.SmartSuggestions suggestions = mSmartActionsHelper.suggest(entry);
-            if (DEBUG) {
-                Log.d(TAG, String.format(
-                        "Creating Adjustment for %s, with %d actions, and %d replies.",
-                        sbn.getKey(), suggestions.actions.size(), suggestions.replies.size()));
-            }
-            Adjustment adjustment = createEnqueuedNotificationAdjustment(
-                    entry, suggestions.actions, suggestions.replies);
-            adjustNotification(adjustment);
-        });
-        return null;
-    }
-
-    /** A convenience helper for creating an adjustment for an SBN. */
-    @VisibleForTesting
-    @Nullable
-    Adjustment createEnqueuedNotificationAdjustment(
-            @NonNull NotificationEntry entry,
-            @NonNull ArrayList<Notification.Action> smartActions,
-            @NonNull ArrayList<CharSequence> smartReplies) {
-        Bundle signals = new Bundle();
-
-        if (!smartActions.isEmpty()) {
-            signals.putParcelableArrayList(Adjustment.KEY_CONTEXTUAL_ACTIONS, smartActions);
-        }
-        if (!smartReplies.isEmpty()) {
-            signals.putCharSequenceArrayList(Adjustment.KEY_TEXT_REPLIES, smartReplies);
-        }
-        if (mSettings.mNewInterruptionModel) {
-            if (mNotificationCategorizer.shouldSilence(entry)) {
-                final int importance = entry.getImportance() < IMPORTANCE_LOW
-                        ? entry.getImportance() : IMPORTANCE_LOW;
-                signals.putInt(KEY_IMPORTANCE, importance);
-            } else {
-                // Even if no change is made, send an identity adjustment for metric logging.
-                signals.putInt(KEY_IMPORTANCE, entry.getImportance());
-            }
-        }
-
-        return new Adjustment(
-                entry.getSbn().getPackageName(),
-                entry.getSbn().getKey(),
-                signals,
-                "",
-                entry.getSbn().getUserId());
-    }
-
-    @Override
-    public void onNotificationPosted(StatusBarNotification sbn, RankingMap rankingMap) {
-        if (DEBUG) Log.i(TAG, "POSTED " + sbn.getKey());
-        try {
-            if (!isForCurrentUser(sbn)) {
-                return;
-            }
-            Ranking ranking = getRanking(sbn.getKey(), rankingMap);
-            if (ranking != null && ranking.getChannel() != null) {
-                NotificationEntry entry = new NotificationEntry(getContext(), mPackageManager,
-                        sbn, ranking.getChannel(), mSmsHelper);
-                String key = getKey(
-                        sbn.getPackageName(), sbn.getUserId(), ranking.getChannel().getId());
-                boolean shouldTriggerBlock;
-                synchronized (mkeyToImpressions) {
-                    ChannelImpressions ci = mkeyToImpressions.getOrDefault(key,
-                            createChannelImpressionsWithThresholds());
-                    mkeyToImpressions.put(key, ci);
-                    shouldTriggerBlock = ci.shouldTriggerBlock();
-                }
-                if (ranking.getImportance() > IMPORTANCE_MIN && shouldTriggerBlock) {
-                    adjustNotification(createNegativeAdjustment(
-                            sbn.getPackageName(), sbn.getKey(), sbn.getUserId()));
-                }
-                mLiveNotifications.put(sbn.getKey(), entry);
-            }
-        } catch (Throwable e) {
-            Log.e(TAG, "Error occurred processing post", e);
-        }
-    }
-
-    @Override
-    public void onNotificationRemoved(StatusBarNotification sbn, RankingMap rankingMap,
-            NotificationStats stats, int reason) {
-        try {
-            if (!isForCurrentUser(sbn)) {
-                return;
-            }
-
-            boolean updatedImpressions = false;
-            String channelId = mLiveNotifications.remove(sbn.getKey()).getChannel().getId();
-            String key = getKey(sbn.getPackageName(), sbn.getUserId(), channelId);
-            synchronized (mkeyToImpressions) {
-                ChannelImpressions ci = mkeyToImpressions.getOrDefault(key,
-                        createChannelImpressionsWithThresholds());
-                if (stats != null && stats.hasSeen()) {
-                    ci.incrementViews();
-                    updatedImpressions = true;
-                }
-                if (PREJUDICAL_DISMISSALS.contains(reason)) {
-                    if ((!sbn.isAppGroup() || sbn.getNotification().isGroupChild())
-                            && !stats.hasInteracted()
-                            && stats.getDismissalSurface() != NotificationStats.DISMISSAL_AOD
-                            && stats.getDismissalSurface() != NotificationStats.DISMISSAL_PEEK
-                            && stats.getDismissalSurface() != NotificationStats.DISMISSAL_OTHER) {
-                        if (DEBUG) Log.i(TAG, "increment dismissals " + key);
-                        ci.incrementDismissals();
-                        updatedImpressions = true;
-                    } else {
-                        if (DEBUG) Slog.i(TAG, "reset streak " + key);
-                        if (ci.getStreak() > 0) {
-                            updatedImpressions = true;
-                        }
-                        ci.resetStreak();
-                    }
-                }
-                mkeyToImpressions.put(key, ci);
-            }
-            if (updatedImpressions) {
-                saveFile();
-            }
-        } catch (Throwable e) {
-            Slog.e(TAG, "Error occurred processing removal of " + sbn, e);
-        }
-    }
-
-    @Override
-    public void onNotificationSnoozedUntilContext(StatusBarNotification sbn,
-            String snoozeCriterionId) {
-    }
-
-    @Override
-    public void onNotificationsSeen(List<String> keys) {
-    }
-
-    @Override
-    public void onNotificationExpansionChanged(@NonNull String key, boolean isUserAction,
-            boolean isExpanded) {
-        if (DEBUG) {
-            Log.d(TAG, "onNotificationExpansionChanged() called with: key = [" + key
-                    + "], isUserAction = [" + isUserAction + "], isExpanded = [" + isExpanded
-                    + "]");
-        }
-        NotificationEntry entry = mLiveNotifications.get(key);
-
-        if (entry != null) {
-            mSingleThreadExecutor.submit(
-                    () -> mSmartActionsHelper.onNotificationExpansionChanged(entry, isExpanded));
-        }
-    }
-
-    @Override
-    public void onNotificationDirectReplied(@NonNull String key) {
-        if (DEBUG) Log.i(TAG, "onNotificationDirectReplied " + key);
-        mSingleThreadExecutor.submit(() -> mSmartActionsHelper.onNotificationDirectReplied(key));
-    }
-
-    @Override
-    public void onSuggestedReplySent(@NonNull String key, @NonNull CharSequence reply,
-            @Source int source) {
-        if (DEBUG) {
-            Log.d(TAG, "onSuggestedReplySent() called with: key = [" + key + "], reply = [" + reply
-                    + "], source = [" + source + "]");
-        }
-        mSingleThreadExecutor.submit(
-                () -> mSmartActionsHelper.onSuggestedReplySent(key, reply, source));
-    }
-
-    @Override
-    public void onActionInvoked(@NonNull String key, @NonNull Notification.Action action,
-            @Source int source) {
-        if (DEBUG) {
-            Log.d(TAG,
-                    "onActionInvoked() called with: key = [" + key + "], action = [" + action.title
-                            + "], source = [" + source + "]");
-        }
-        mSingleThreadExecutor.submit(
-                () -> mSmartActionsHelper.onActionClicked(key, action, source));
-    }
-
-    @Override
-    public void onListenerConnected() {
-        if (DEBUG) Log.i(TAG, "CONNECTED");
-        try {
-            mFile = new AtomicFile(new File(new File(
-                    Environment.getDataUserCePackageDirectory(
-                            StorageManager.UUID_PRIVATE_INTERNAL, getUserId(), getPackageName()),
-                    "assistant"), "blocking_helper_stats.xml"));
-            loadFile();
-            for (StatusBarNotification sbn : getActiveNotifications()) {
-                onNotificationPosted(sbn);
-            }
-        } catch (Throwable e) {
-            Log.e(TAG, "Error occurred on connection", e);
-        }
-    }
-
-    @Override
-    public void onListenerDisconnected() {
-    }
-
-    private boolean isForCurrentUser(StatusBarNotification sbn) {
-        return sbn != null && sbn.getUserId() == UserHandle.myUserId();
-    }
-
-    protected String getKey(String pkg, int userId, String channelId) {
-        return pkg + "|" + userId + "|" + channelId;
-    }
-
-    private Ranking getRanking(String key, RankingMap rankingMap) {
-        if (mFakeRanking != null) {
-            return mFakeRanking;
-        }
-        Ranking ranking = new Ranking();
-        rankingMap.getRanking(key, ranking);
-        return ranking;
-    }
-
-    private Adjustment createNegativeAdjustment(String packageName, String key, int user) {
-        if (DEBUG) Log.d(TAG, "User probably doesn't want " + key);
-        Bundle signals = new Bundle();
-        signals.putInt(Adjustment.KEY_USER_SENTIMENT, USER_SENTIMENT_NEGATIVE);
-        return new Adjustment(packageName, key,  signals, "", user);
-    }
-
-    // for testing
-
-    @VisibleForTesting
-    public void setFile(AtomicFile file) {
-        mFile = file;
-    }
-
-    @VisibleForTesting
-    public void setFakeRanking(Ranking ranking) {
-        mFakeRanking = ranking;
-    }
-
-    @VisibleForTesting
-    public void setNoMan(INotificationManager noMan) {
-        mNoMan = noMan;
-    }
-
-    @VisibleForTesting
-    public void setContext(Context context) {
-        mSystemContext = context;
-    }
-
-    @VisibleForTesting
-    public void setPackageManager(IPackageManager pm) {
-        mPackageManager = pm;
-    }
-
-    @VisibleForTesting
-    public ChannelImpressions getImpressions(String key) {
-        synchronized (mkeyToImpressions) {
-            return mkeyToImpressions.get(key);
-        }
-    }
-
-    @VisibleForTesting
-    public void insertImpressions(String key, ChannelImpressions ci) {
-        synchronized (mkeyToImpressions) {
-            mkeyToImpressions.put(key, ci);
-        }
-    }
-
-    private ChannelImpressions createChannelImpressionsWithThresholds() {
-        ChannelImpressions impressions = new ChannelImpressions();
-        impressions.updateThresholds(mSettings.mDismissToViewRatioLimit, mSettings.mStreakLimit);
-        return impressions;
-    }
-
-    private void updateThresholds() {
-        // Update all existing channel impression objects with any new limits/thresholds.
-        synchronized (mkeyToImpressions) {
-            for (ChannelImpressions channelImpressions: mkeyToImpressions.values()) {
-                channelImpressions.updateThresholds(
-                        mSettings.mDismissToViewRatioLimit, mSettings.mStreakLimit);
-            }
-        }
-    }
-}
diff --git a/packages/ExtServices/src/android/ext/services/notification/AssistantSettings.java b/packages/ExtServices/src/android/ext/services/notification/AssistantSettings.java
deleted file mode 100644
index 296db46..0000000
--- a/packages/ExtServices/src/android/ext/services/notification/AssistantSettings.java
+++ /dev/null
@@ -1,176 +0,0 @@
-/**
- * Copyright (C) 2018 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.ext.services.notification;
-
-import android.content.ContentResolver;
-import android.database.ContentObserver;
-import android.net.Uri;
-import android.os.Handler;
-import android.provider.DeviceConfig;
-import android.provider.Settings;
-import android.util.Log;
-
-import com.android.internal.annotations.VisibleForTesting;
-import com.android.internal.config.sysui.SystemUiDeviceConfigFlags;
-
-/**
- * Observes the settings for {@link Assistant}.
- */
-final class AssistantSettings extends ContentObserver {
-    private static final String LOG_TAG = "AssistantSettings";
-    public static Factory FACTORY = AssistantSettings::createAndRegister;
-    private static final boolean DEFAULT_GENERATE_REPLIES = true;
-    private static final boolean DEFAULT_GENERATE_ACTIONS = true;
-    private static final int DEFAULT_NEW_INTERRUPTION_MODEL_INT = 1;
-    private static final int DEFAULT_MAX_MESSAGES_TO_EXTRACT = 5;
-    @VisibleForTesting
-    static final int DEFAULT_MAX_SUGGESTIONS = 3;
-
-    private static final Uri STREAK_LIMIT_URI =
-            Settings.Global.getUriFor(Settings.Global.BLOCKING_HELPER_STREAK_LIMIT);
-    private static final Uri DISMISS_TO_VIEW_RATIO_LIMIT_URI =
-            Settings.Global.getUriFor(
-                    Settings.Global.BLOCKING_HELPER_DISMISS_TO_VIEW_RATIO_LIMIT);
-    private static final Uri NOTIFICATION_NEW_INTERRUPTION_MODEL_URI =
-            Settings.Secure.getUriFor(Settings.Secure.NOTIFICATION_NEW_INTERRUPTION_MODEL);
-
-    private final ContentResolver mResolver;
-    private final int mUserId;
-
-    private final Handler mHandler;
-
-    @VisibleForTesting
-    protected final Runnable mOnUpdateRunnable;
-
-    // Actual configuration settings.
-    float mDismissToViewRatioLimit;
-    int mStreakLimit;
-    boolean mGenerateReplies = DEFAULT_GENERATE_REPLIES;
-    boolean mGenerateActions = DEFAULT_GENERATE_ACTIONS;
-    boolean mNewInterruptionModel;
-    int mMaxMessagesToExtract = DEFAULT_MAX_MESSAGES_TO_EXTRACT;
-    int mMaxSuggestions = DEFAULT_MAX_SUGGESTIONS;
-
-    private AssistantSettings(Handler handler, ContentResolver resolver, int userId,
-            Runnable onUpdateRunnable) {
-        super(handler);
-        mHandler = handler;
-        mResolver = resolver;
-        mUserId = userId;
-        mOnUpdateRunnable = onUpdateRunnable;
-    }
-
-    private static AssistantSettings createAndRegister(
-            Handler handler, ContentResolver resolver, int userId, Runnable onUpdateRunnable) {
-        AssistantSettings assistantSettings =
-                new AssistantSettings(handler, resolver, userId, onUpdateRunnable);
-        assistantSettings.register();
-        assistantSettings.registerDeviceConfigs();
-        return assistantSettings;
-    }
-
-    /**
-     * Creates an instance but doesn't register it as an observer.
-     */
-    @VisibleForTesting
-    protected static AssistantSettings createForTesting(
-            Handler handler, ContentResolver resolver, int userId, Runnable onUpdateRunnable) {
-        return new AssistantSettings(handler, resolver, userId, onUpdateRunnable);
-    }
-
-    private void register() {
-        mResolver.registerContentObserver(
-                DISMISS_TO_VIEW_RATIO_LIMIT_URI, false, this, mUserId);
-        mResolver.registerContentObserver(STREAK_LIMIT_URI, false, this, mUserId);
-
-        // Update all uris on creation.
-        update(null);
-    }
-
-    private void registerDeviceConfigs() {
-        DeviceConfig.addOnPropertiesChangedListener(
-                DeviceConfig.NAMESPACE_SYSTEMUI,
-                this::postToHandler,
-                (properties) -> onDeviceConfigPropertiesChanged(properties.getNamespace()));
-
-        // Update the fields in this class from the current state of the device config.
-        updateFromDeviceConfigFlags();
-    }
-
-    private void postToHandler(Runnable r) {
-        this.mHandler.post(r);
-    }
-
-    @VisibleForTesting
-    void onDeviceConfigPropertiesChanged(String namespace) {
-        if (!DeviceConfig.NAMESPACE_SYSTEMUI.equals(namespace)) {
-            Log.e(LOG_TAG, "Received update from DeviceConfig for unrelated namespace: "
-                    + namespace);
-            return;
-        }
-
-        updateFromDeviceConfigFlags();
-    }
-
-    private void updateFromDeviceConfigFlags() {
-        mGenerateReplies = DeviceConfig.getBoolean(DeviceConfig.NAMESPACE_SYSTEMUI,
-                SystemUiDeviceConfigFlags.NAS_GENERATE_REPLIES, DEFAULT_GENERATE_REPLIES);
-
-        mGenerateActions = DeviceConfig.getBoolean(DeviceConfig.NAMESPACE_SYSTEMUI,
-                SystemUiDeviceConfigFlags.NAS_GENERATE_ACTIONS, DEFAULT_GENERATE_ACTIONS);
-
-        mMaxMessagesToExtract = DeviceConfig.getInt(DeviceConfig.NAMESPACE_SYSTEMUI,
-                SystemUiDeviceConfigFlags.NAS_MAX_MESSAGES_TO_EXTRACT,
-                DEFAULT_MAX_MESSAGES_TO_EXTRACT);
-
-        mMaxSuggestions = DeviceConfig.getInt(DeviceConfig.NAMESPACE_SYSTEMUI,
-                SystemUiDeviceConfigFlags.NAS_MAX_SUGGESTIONS, DEFAULT_MAX_SUGGESTIONS);
-
-        mOnUpdateRunnable.run();
-    }
-
-    @Override
-    public void onChange(boolean selfChange, Uri uri) {
-        update(uri);
-    }
-
-    private void update(Uri uri) {
-        if (uri == null || DISMISS_TO_VIEW_RATIO_LIMIT_URI.equals(uri)) {
-            mDismissToViewRatioLimit = Settings.Global.getFloat(
-                    mResolver, Settings.Global.BLOCKING_HELPER_DISMISS_TO_VIEW_RATIO_LIMIT,
-                    ChannelImpressions.DEFAULT_DISMISS_TO_VIEW_RATIO_LIMIT);
-        }
-        if (uri == null || STREAK_LIMIT_URI.equals(uri)) {
-            mStreakLimit = Settings.Global.getInt(
-                    mResolver, Settings.Global.BLOCKING_HELPER_STREAK_LIMIT,
-                    ChannelImpressions.DEFAULT_STREAK_LIMIT);
-        }
-        if (uri == null || NOTIFICATION_NEW_INTERRUPTION_MODEL_URI.equals(uri)) {
-            int mNewInterruptionModelInt = Settings.Secure.getInt(
-                    mResolver, Settings.Secure.NOTIFICATION_NEW_INTERRUPTION_MODEL,
-                    DEFAULT_NEW_INTERRUPTION_MODEL_INT);
-            mNewInterruptionModel = mNewInterruptionModelInt == 1;
-        }
-
-        mOnUpdateRunnable.run();
-    }
-
-    public interface Factory {
-        AssistantSettings createAndRegister(Handler handler, ContentResolver resolver, int userId,
-                Runnable onUpdateRunnable);
-    }
-}
diff --git a/packages/ExtServices/src/android/ext/services/notification/ChannelImpressions.java b/packages/ExtServices/src/android/ext/services/notification/ChannelImpressions.java
deleted file mode 100644
index ca3daad..0000000
--- a/packages/ExtServices/src/android/ext/services/notification/ChannelImpressions.java
+++ /dev/null
@@ -1,211 +0,0 @@
-/**
- * Copyright (C) 2017 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.ext.services.notification;
-
-import android.os.Parcel;
-import android.os.Parcelable;
-import android.text.TextUtils;
-import android.util.Log;
-
-import com.android.internal.annotations.VisibleForTesting;
-
-import org.xmlpull.v1.XmlPullParser;
-import org.xmlpull.v1.XmlSerializer;
-
-import java.io.IOException;
-
-public final class ChannelImpressions implements Parcelable {
-    private static final String TAG = "ExtAssistant.CI";
-    private static final boolean DEBUG = Log.isLoggable(TAG, Log.DEBUG);
-
-    static final float DEFAULT_DISMISS_TO_VIEW_RATIO_LIMIT = .8f;
-    static final int DEFAULT_STREAK_LIMIT = 2;
-    static final String ATT_DISMISSALS = "dismisses";
-    static final String ATT_VIEWS = "views";
-    static final String ATT_STREAK = "streak";
-    static final String ATT_SENT = "sent";
-    static final String ATT_INTERRUPTIVE = "interruptive";
-
-    private int mDismissals = 0;
-    private int mViews = 0;
-    private int mStreak = 0;
-
-    private float mDismissToViewRatioLimit;
-    private int mStreakLimit;
-
-    public ChannelImpressions() {
-        mDismissToViewRatioLimit = DEFAULT_DISMISS_TO_VIEW_RATIO_LIMIT;
-        mStreakLimit = DEFAULT_STREAK_LIMIT;
-    }
-
-    protected ChannelImpressions(Parcel in) {
-        mDismissals = in.readInt();
-        mViews = in.readInt();
-        mStreak = in.readInt();
-        mDismissToViewRatioLimit = in.readFloat();
-        mStreakLimit = in.readInt();
-    }
-
-    public int getStreak() {
-        return mStreak;
-    }
-
-    public int getDismissals() {
-        return mDismissals;
-    }
-
-    public int getViews() {
-        return mViews;
-    }
-
-    public void incrementDismissals() {
-        mDismissals++;
-        mStreak++;
-    }
-
-    void updateThresholds(float dismissToViewRatioLimit, int streakLimit) {
-        mDismissToViewRatioLimit = dismissToViewRatioLimit;
-        mStreakLimit = streakLimit;
-    }
-
-    @VisibleForTesting
-    float getDismissToViewRatioLimit() {
-        return mDismissToViewRatioLimit;
-    }
-
-    @VisibleForTesting
-    int getStreakLimit() {
-        return mStreakLimit;
-    }
-
-    public void append(ChannelImpressions additionalImpressions) {
-        if (additionalImpressions != null) {
-            mViews += additionalImpressions.getViews();
-            mStreak += additionalImpressions.getStreak();
-            mDismissals += additionalImpressions.getDismissals();
-        }
-    }
-
-    public void incrementViews() {
-        mViews++;
-    }
-
-    public void resetStreak() {
-        mStreak = 0;
-    }
-
-    public boolean shouldTriggerBlock() {
-        if (getViews() == 0) {
-            return false;
-        }
-        if (DEBUG) {
-            Log.d(TAG, "should trigger? " + getDismissals() + " " + getViews() + " " + getStreak());
-        }
-        return ((float) getDismissals() / getViews()) > mDismissToViewRatioLimit
-                && getStreak() > mStreakLimit;
-    }
-
-    @Override
-    public void writeToParcel(Parcel dest, int flags) {
-        dest.writeInt(mDismissals);
-        dest.writeInt(mViews);
-        dest.writeInt(mStreak);
-        dest.writeFloat(mDismissToViewRatioLimit);
-        dest.writeInt(mStreakLimit);
-    }
-
-    @Override
-    public int describeContents() {
-        return 0;
-    }
-
-    public static final Creator<ChannelImpressions> CREATOR = new Creator<ChannelImpressions>() {
-        @Override
-        public ChannelImpressions createFromParcel(Parcel in) {
-            return new ChannelImpressions(in);
-        }
-
-        @Override
-        public ChannelImpressions[] newArray(int size) {
-            return new ChannelImpressions[size];
-        }
-    };
-
-    @Override
-    public boolean equals(Object o) {
-        if (this == o) return true;
-        if (o == null || getClass() != o.getClass()) return false;
-
-        ChannelImpressions that = (ChannelImpressions) o;
-
-        if (mDismissals != that.mDismissals) return false;
-        if (mViews != that.mViews) return false;
-        return mStreak == that.mStreak;
-    }
-
-    @Override
-    public int hashCode() {
-        int result = mDismissals;
-        result = 31 * result + mViews;
-        result = 31 * result + mStreak;
-        return result;
-    }
-
-    @Override
-    public String toString() {
-        final StringBuilder sb = new StringBuilder("ChannelImpressions{");
-        sb.append("mDismissals=").append(mDismissals);
-        sb.append(", mViews=").append(mViews);
-        sb.append(", mStreak=").append(mStreak);
-        sb.append(", thresholds=(").append(mDismissToViewRatioLimit);
-        sb.append(",").append(mStreakLimit);
-        sb.append(")}");
-        return sb.toString();
-    }
-
-    protected void populateFromXml(XmlPullParser parser) {
-        mDismissals = safeInt(parser, ATT_DISMISSALS, 0);
-        mStreak = safeInt(parser, ATT_STREAK, 0);
-        mViews = safeInt(parser, ATT_VIEWS, 0);
-    }
-
-    protected void writeXml(XmlSerializer out) throws IOException {
-        if (mDismissals != 0) {
-            out.attribute(null, ATT_DISMISSALS, String.valueOf(mDismissals));
-        }
-        if (mStreak != 0) {
-            out.attribute(null, ATT_STREAK, String.valueOf(mStreak));
-        }
-        if (mViews != 0) {
-            out.attribute(null, ATT_VIEWS, String.valueOf(mViews));
-        }
-    }
-
-    private static int safeInt(XmlPullParser parser, String att, int defValue) {
-        final String val = parser.getAttributeValue(null, att);
-        return tryParseInt(val, defValue);
-    }
-
-    private static int tryParseInt(String value, int defValue) {
-        if (TextUtils.isEmpty(value)) return defValue;
-        try {
-            return Integer.parseInt(value);
-        } catch (NumberFormatException e) {
-            return defValue;
-        }
-    }
-}
diff --git a/packages/ExtServices/src/android/ext/services/notification/CopyCodeActivity.java b/packages/ExtServices/src/android/ext/services/notification/CopyCodeActivity.java
deleted file mode 100644
index 6708d4d..0000000
--- a/packages/ExtServices/src/android/ext/services/notification/CopyCodeActivity.java
+++ /dev/null
@@ -1,54 +0,0 @@
-/*
- * Copyright (C) 2019 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.ext.services.notification;
-
-import android.app.Activity;
-import android.content.ClipData;
-import android.content.ClipboardManager;
-import android.content.Intent;
-import android.ext.services.R;
-import android.os.Bundle;
-import android.text.TextUtils;
-import android.util.Log;
-import android.widget.Toast;
-
-/**
- * An activity that copies text in the Bundle.
- */
-public class CopyCodeActivity extends Activity {
-    private static final String TAG = "CopyCodeActivity";
-
-    @Override
-    protected void onCreate(Bundle savedInstanceState) {
-        super.onCreate(savedInstanceState);
-        handleIntent();
-        finish();
-    }
-
-    private void handleIntent() {
-        String code = getIntent().getStringExtra(Intent.EXTRA_TEXT);
-        if (TextUtils.isEmpty(code)) {
-            Log.w(TAG, "handleIntent: empty code");
-            return;
-        }
-        ClipboardManager clipboardManager = getSystemService(ClipboardManager.class);
-        ClipData clipData = ClipData.newPlainText(null, code);
-        clipboardManager.setPrimaryClip(clipData);
-        Toast.makeText(getApplicationContext(), R.string.code_copied_to_clipboard,
-                Toast.LENGTH_SHORT).show();
-    }
-}
diff --git a/packages/ExtServices/src/android/ext/services/notification/EntityTypeCounter.java b/packages/ExtServices/src/android/ext/services/notification/EntityTypeCounter.java
deleted file mode 100644
index 50cb0ab..0000000
--- a/packages/ExtServices/src/android/ext/services/notification/EntityTypeCounter.java
+++ /dev/null
@@ -1,73 +0,0 @@
-/**
- * Copyright (C) 2018 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package android.ext.services.notification;
-
-import android.annotation.NonNull;
-import android.util.ArrayMap;
-import android.view.textclassifier.TextClassifier;
-import android.view.textclassifier.TextLinks;
-
-/**
- * Counts the entity types for smart actions. Some entity types are considered the same
- * type, like {@link TextClassifier#TYPE_DATE} and {@link TextClassifier#TYPE_DATE_TIME}.
- */
-class EntityTypeCounter {
-
-    private static final ArrayMap<String, String> ENTITY_TYPE_MAPPING = new ArrayMap<>();
-
-    static {
-        ENTITY_TYPE_MAPPING.put(TextClassifier.TYPE_DATE_TIME, TextClassifier.TYPE_DATE);
-    }
-
-    private final ArrayMap<String, Integer> mEntityTypeCount = new ArrayMap<>();
-
-
-    void increment(@NonNull String entityType) {
-        entityType = convertToBaseEntityType(entityType);
-        if (mEntityTypeCount.containsKey(entityType)) {
-            mEntityTypeCount.put(entityType, mEntityTypeCount.get(entityType) + 1);
-        } else {
-            mEntityTypeCount.put(entityType, 1);
-        }
-    }
-
-    int getCount(@NonNull String entityType) {
-        entityType = convertToBaseEntityType(entityType);
-        return mEntityTypeCount.getOrDefault(entityType, 0);
-    }
-
-    @NonNull
-    private String convertToBaseEntityType(@NonNull String entityType) {
-        return ENTITY_TYPE_MAPPING.getOrDefault(entityType, entityType);
-    }
-
-    /**
-     * Given the links extracted from a piece of text, returns the frequency of each entity
-     * type.
-     */
-    @NonNull
-    static EntityTypeCounter fromTextLinks(@NonNull TextLinks links) {
-        EntityTypeCounter counter = new EntityTypeCounter();
-        for (TextLinks.TextLink link : links.getLinks()) {
-            if (link.getEntityCount() == 0) {
-                continue;
-            }
-            String entityType = link.getEntity(0);
-            counter.increment(entityType);
-        }
-        return counter;
-    }
-}
diff --git a/packages/ExtServices/src/android/ext/services/notification/NotificationCategorizer.java b/packages/ExtServices/src/android/ext/services/notification/NotificationCategorizer.java
deleted file mode 100644
index f95891c..0000000
--- a/packages/ExtServices/src/android/ext/services/notification/NotificationCategorizer.java
+++ /dev/null
@@ -1,109 +0,0 @@
-/**
- * Copyright (C) 2018 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package android.ext.services.notification;
-
-import static android.app.NotificationManager.IMPORTANCE_DEFAULT;
-import static android.app.NotificationManager.IMPORTANCE_HIGH;
-import static android.app.NotificationManager.IMPORTANCE_MIN;
-
-import android.annotation.IntDef;
-import android.app.Notification;
-import android.media.AudioAttributes;
-import android.os.Process;
-
-import com.android.internal.annotations.VisibleForTesting;
-
-import java.lang.annotation.Retention;
-import java.lang.annotation.RetentionPolicy;
-
-/**
- * Default categorizer for incoming notifications; used to determine what notifications
- * should be silenced.
- */
-// TODO: stop using @hide methods
-public class NotificationCategorizer {
-
-    protected static final int CATEGORY_MIN = -3;
-    protected static final int CATEGORY_EVERYTHING_ELSE = -2;
-    protected static final int CATEGORY_ONGOING = -1;
-    protected static final int CATEGORY_SYSTEM_LOW = 0;
-    protected static final int CATEGORY_EVENT = 1;
-    protected static final int CATEGORY_REMINDER = 2;
-    protected static final int CATEGORY_SYSTEM = 3;
-    protected static final int CATEGORY_PEOPLE = 4;
-    protected static final int CATEGORY_ALARM = 5;
-    protected static final int CATEGORY_CALL = 6;
-    protected static final int CATEGORY_HIGH = 7;
-
-    /** @hide */
-    @IntDef(prefix = { "CATEGORY_" }, value = {
-            CATEGORY_MIN, CATEGORY_EVERYTHING_ELSE, CATEGORY_ONGOING, CATEGORY_CALL,
-            CATEGORY_SYSTEM_LOW, CATEGORY_EVENT, CATEGORY_REMINDER, CATEGORY_SYSTEM,
-            CATEGORY_PEOPLE, CATEGORY_ALARM, CATEGORY_HIGH
-    })
-    @Retention(RetentionPolicy.SOURCE)
-    public @interface Category {}
-
-    public boolean shouldSilence(NotificationEntry entry) {
-        return shouldSilence(getCategory(entry));
-    }
-
-    @VisibleForTesting
-    boolean shouldSilence(int category) {
-        return category < CATEGORY_EVENT;
-    }
-
-    public int getCategory(NotificationEntry entry) {
-        if (entry.getChannel() == null) {
-            return CATEGORY_EVERYTHING_ELSE;
-        }
-        if (entry.getChannel().getImportance() == IMPORTANCE_MIN) {
-            return CATEGORY_MIN;
-        }
-        if (entry.isCategory(Notification.CATEGORY_REMINDER)) {
-            return CATEGORY_REMINDER;
-        }
-        if (entry.isCategory(Notification.CATEGORY_EVENT)) {
-            return CATEGORY_EVENT;
-        }
-        if (entry.isCategory(Notification.CATEGORY_ALARM)
-                || entry.isAudioAttributesUsage(AudioAttributes.USAGE_ALARM)) {
-            return CATEGORY_ALARM;
-        }
-        // TODO: check for default phone app
-        if (entry.isCategory(Notification.CATEGORY_CALL)) {
-            return CATEGORY_CALL;
-        }
-        if (entry.involvesPeople()) {
-            return CATEGORY_PEOPLE;
-        }
-        // TODO: is from signature app
-        if (entry.getSbn().getUid() < Process.FIRST_APPLICATION_UID) {
-            if (entry.getImportance() >= IMPORTANCE_DEFAULT) {
-                return CATEGORY_SYSTEM;
-            } else {
-                return CATEGORY_SYSTEM_LOW;
-            }
-        }
-        if (entry.getChannel().getImportance() == IMPORTANCE_HIGH) {
-            return CATEGORY_HIGH;
-        }
-        if (entry.isOngoing()) {
-            return CATEGORY_ONGOING;
-        }
-        return CATEGORY_EVERYTHING_ELSE;
-    }
-}
diff --git a/packages/ExtServices/src/android/ext/services/notification/NotificationEntry.java b/packages/ExtServices/src/android/ext/services/notification/NotificationEntry.java
deleted file mode 100644
index 1ffbac9..0000000
--- a/packages/ExtServices/src/android/ext/services/notification/NotificationEntry.java
+++ /dev/null
@@ -1,349 +0,0 @@
-/*
- * Copyright (C) 2018 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package android.ext.services.notification;
-
-import static android.app.Notification.CATEGORY_MESSAGE;
-import static android.app.NotificationChannel.USER_LOCKED_IMPORTANCE;
-import static android.app.NotificationManager.IMPORTANCE_DEFAULT;
-import static android.app.NotificationManager.IMPORTANCE_HIGH;
-import static android.app.NotificationManager.IMPORTANCE_LOW;
-import static android.app.NotificationManager.IMPORTANCE_MIN;
-import static android.app.NotificationManager.IMPORTANCE_UNSPECIFIED;
-
-import android.app.Notification;
-import android.app.NotificationChannel;
-import android.app.Person;
-import android.app.RemoteInput;
-import android.content.ComponentName;
-import android.content.Context;
-import android.content.pm.ApplicationInfo;
-import android.content.pm.IPackageManager;
-import android.content.pm.PackageManager;
-import android.graphics.drawable.Icon;
-import android.media.AudioAttributes;
-import android.media.AudioSystem;
-import android.os.Build;
-import android.os.Parcelable;
-import android.os.RemoteException;
-import android.service.notification.StatusBarNotification;
-import android.util.Log;
-import android.util.SparseArray;
-
-import java.util.ArrayList;
-import java.util.Objects;
-import java.util.Set;
-
-/**
- * Holds data about notifications.
- */
-public class NotificationEntry {
-    static final String TAG = "NotificationEntry";
-
-    // Copied from hidden definitions in Notification.TvExtender
-    private static final String EXTRA_TV_EXTENDER = "android.tv.EXTENSIONS";
-
-    private final Context mContext;
-    private final StatusBarNotification mSbn;
-    private final IPackageManager mPackageManager;
-    private int mTargetSdkVersion = Build.VERSION_CODES.N_MR1;
-    private final boolean mPreChannelsNotification;
-    private final AudioAttributes mAttributes;
-    private final NotificationChannel mChannel;
-    private final int mImportance;
-    private boolean mSeen;
-    private boolean mIsShowActionEventLogged;
-    private final SmsHelper mSmsHelper;
-
-    private final Object mLock = new Object();
-
-    public NotificationEntry(Context applicationContext, IPackageManager packageManager,
-            StatusBarNotification sbn, NotificationChannel channel, SmsHelper smsHelper) {
-        mContext = applicationContext;
-        mSbn = cloneStatusBarNotificationLight(sbn);
-        mChannel = channel;
-        mPackageManager = packageManager;
-        mPreChannelsNotification = isPreChannelsNotification();
-        mAttributes = calculateAudioAttributes();
-        mImportance = calculateInitialImportance();
-        mSmsHelper = smsHelper;
-    }
-
-    /** Adapted from {@code Notification.lightenPayload}. */
-    @SuppressWarnings("nullness")
-    private static void lightenNotificationPayload(Notification notification) {
-        notification.tickerView = null;
-        notification.contentView = null;
-        notification.bigContentView = null;
-        notification.headsUpContentView = null;
-        notification.largeIcon = null;
-        if (notification.extras != null && !notification.extras.isEmpty()) {
-            final Set<String> keyset = notification.extras.keySet();
-            final int keysetSize = keyset.size();
-            final String[] keys = keyset.toArray(new String[keysetSize]);
-            for (int i = 0; i < keysetSize; i++) {
-                final String key = keys[i];
-                if (EXTRA_TV_EXTENDER.equals(key)
-                        || Notification.EXTRA_MESSAGES.equals(key)
-                        || Notification.EXTRA_MESSAGING_PERSON.equals(key)
-                        || Notification.EXTRA_PEOPLE_LIST.equals(key)) {
-                    continue;
-                }
-                final Object obj = notification.extras.get(key);
-                if (obj != null
-                        && (obj instanceof Parcelable
-                        || obj instanceof Parcelable[]
-                        || obj instanceof SparseArray
-                        || obj instanceof ArrayList)) {
-                    notification.extras.remove(key);
-                }
-            }
-        }
-    }
-
-    /** An interpretation of {@code Notification.cloneInto} with heavy=false. */
-    private Notification cloneNotificationLight(Notification notification) {
-        // We can't just use clone() here because the only way to remove the icons is with the
-        // builder, which we can only create with a Context.
-        Notification lightNotification =
-                Notification.Builder.recoverBuilder(mContext, notification)
-                        .setSmallIcon(0)
-                        .setLargeIcon((Icon) null)
-                        .build();
-        lightenNotificationPayload(lightNotification);
-        return lightNotification;
-    }
-
-    /** Adapted from {@code StatusBarNotification.cloneLight}. */
-    public StatusBarNotification cloneStatusBarNotificationLight(StatusBarNotification sbn) {
-        return new StatusBarNotification(
-                sbn.getPackageName(),
-                sbn.getOpPkg(),
-                sbn.getId(),
-                sbn.getTag(),
-                sbn.getUid(),
-                /*initialPid=*/ 0,
-                /*score=*/ 0,
-                cloneNotificationLight(sbn.getNotification()),
-                sbn.getUser(),
-                sbn.getPostTime());
-    }
-
-    private boolean isPreChannelsNotification() {
-        try {
-            ApplicationInfo info = mPackageManager.getApplicationInfo(
-                    mSbn.getPackageName(), PackageManager.MATCH_ALL,
-                    mSbn.getUserId());
-            if (info != null) {
-                mTargetSdkVersion = info.targetSdkVersion;
-            }
-        } catch (RemoteException e) {
-            Log.w(TAG, "Couldn't look up " + mSbn.getPackageName());
-        }
-        if (NotificationChannel.DEFAULT_CHANNEL_ID.equals(getChannel().getId())) {
-            if (mTargetSdkVersion < Build.VERSION_CODES.O) {
-                return true;
-            }
-        }
-        return false;
-    }
-
-    private AudioAttributes calculateAudioAttributes() {
-        final Notification n = getNotification();
-        AudioAttributes attributes = getChannel().getAudioAttributes();
-        if (attributes == null) {
-            attributes = Notification.AUDIO_ATTRIBUTES_DEFAULT;
-        }
-
-        if (mPreChannelsNotification
-                && (getChannel().getUserLockedFields()
-                & NotificationChannel.USER_LOCKED_SOUND) == 0) {
-            if (n.audioAttributes != null) {
-                // prefer audio attributes to stream type
-                attributes = n.audioAttributes;
-            } else if (n.audioStreamType >= 0
-                    && n.audioStreamType < AudioSystem.getNumStreamTypes()) {
-                // the stream type is valid, use it
-                attributes = new AudioAttributes.Builder()
-                        .setInternalLegacyStreamType(n.audioStreamType)
-                        .build();
-            } else if (n.audioStreamType != AudioSystem.STREAM_DEFAULT) {
-                Log.w(TAG, String.format("Invalid stream type: %d", n.audioStreamType));
-            }
-        }
-        return attributes;
-    }
-
-    private int calculateInitialImportance() {
-        final Notification n = getNotification();
-        int importance = getChannel().getImportance();
-        int requestedImportance = IMPORTANCE_DEFAULT;
-
-        // Migrate notification flags to scores
-        if ((n.flags & Notification.FLAG_HIGH_PRIORITY) != 0) {
-            n.priority = Notification.PRIORITY_MAX;
-        }
-
-        n.priority = clamp(n.priority, Notification.PRIORITY_MIN,
-                Notification.PRIORITY_MAX);
-        switch (n.priority) {
-            case Notification.PRIORITY_MIN:
-                requestedImportance = IMPORTANCE_MIN;
-                break;
-            case Notification.PRIORITY_LOW:
-                requestedImportance = IMPORTANCE_LOW;
-                break;
-            case Notification.PRIORITY_DEFAULT:
-                requestedImportance = IMPORTANCE_DEFAULT;
-                break;
-            case Notification.PRIORITY_HIGH:
-            case Notification.PRIORITY_MAX:
-                requestedImportance = IMPORTANCE_HIGH;
-                break;
-        }
-
-        if (mPreChannelsNotification
-                && (importance == IMPORTANCE_UNSPECIFIED
-                || (getChannel().getUserLockedFields()
-                & USER_LOCKED_IMPORTANCE) == 0)) {
-            if (n.fullScreenIntent != null) {
-                requestedImportance = IMPORTANCE_HIGH;
-            }
-            importance = requestedImportance;
-        }
-
-        return importance;
-    }
-
-    public boolean isCategory(String category) {
-        return Objects.equals(getNotification().category, category);
-    }
-
-    /**
-     * Similar to {@link #isCategory(String)}, but checking the public version of the notification,
-     * if available.
-     */
-    public boolean isPublicVersionCategory(String category) {
-        Notification publicVersion = getNotification().publicVersion;
-        if (publicVersion == null) {
-            return false;
-        }
-        return Objects.equals(publicVersion.category, category);
-    }
-
-    public boolean isAudioAttributesUsage(int usage) {
-        return mAttributes != null && mAttributes.getUsage() == usage;
-    }
-
-    private boolean hasPerson() {
-        // TODO: cache favorite and recent contacts to check contact affinity
-        ArrayList<Person> people = getNotification().extras.getParcelableArrayList(
-                Notification.EXTRA_PEOPLE_LIST);
-        return people != null && !people.isEmpty();
-    }
-
-    protected boolean hasStyle(Class targetStyle) {
-        Class<? extends Notification.Style> style = getNotification().getNotificationStyle();
-        return targetStyle.equals(style);
-    }
-
-    protected boolean isOngoing() {
-        return (getNotification().flags & Notification.FLAG_FOREGROUND_SERVICE) != 0;
-    }
-
-    protected boolean involvesPeople() {
-        return isMessaging()
-                || hasStyle(Notification.InboxStyle.class)
-                || hasPerson()
-                || isDefaultSmsApp();
-    }
-
-    private boolean isDefaultSmsApp() {
-        ComponentName defaultSmsApp = mSmsHelper.getDefaultSmsApplication();
-        if (defaultSmsApp == null) {
-            return false;
-        }
-        return mSbn.getPackageName().equals(defaultSmsApp.getPackageName());
-    }
-
-    protected boolean isMessaging() {
-        return isCategory(CATEGORY_MESSAGE)
-                || isPublicVersionCategory(CATEGORY_MESSAGE)
-                || hasStyle(Notification.MessagingStyle.class);
-    }
-
-    public boolean hasInlineReply() {
-        Notification.Action[] actions = getNotification().actions;
-        if (actions == null) {
-            return false;
-        }
-        for (Notification.Action action : actions) {
-            RemoteInput[] remoteInputs = action.getRemoteInputs();
-            if (remoteInputs == null) {
-                continue;
-            }
-            for (RemoteInput remoteInput : remoteInputs) {
-                if (remoteInput.getAllowFreeFormInput()) {
-                    return true;
-                }
-            }
-        }
-        return false;
-    }
-
-    public void setSeen() {
-        synchronized (mLock) {
-            mSeen = true;
-        }
-    }
-
-    public void setShowActionEventLogged() {
-        synchronized (mLock) {
-            mIsShowActionEventLogged = true;
-        }
-    }
-
-    public boolean hasSeen() {
-        synchronized (mLock) {
-            return mSeen;
-        }
-    }
-
-    public boolean isShowActionEventLogged() {
-        synchronized (mLock) {
-            return mIsShowActionEventLogged;
-        }
-    }
-
-    public StatusBarNotification getSbn() {
-        return mSbn;
-    }
-
-    public Notification getNotification() {
-        return getSbn().getNotification();
-    }
-
-    public NotificationChannel getChannel() {
-        return mChannel;
-    }
-
-    public int getImportance() {
-        return mImportance;
-    }
-
-    private int clamp(int x, int low, int high) {
-        return (x < low) ? low : ((x > high) ? high : x);
-    }
-}
diff --git a/packages/ExtServices/src/android/ext/services/notification/SmartActionsHelper.java b/packages/ExtServices/src/android/ext/services/notification/SmartActionsHelper.java
deleted file mode 100644
index 93c522e..0000000
--- a/packages/ExtServices/src/android/ext/services/notification/SmartActionsHelper.java
+++ /dev/null
@@ -1,502 +0,0 @@
-/**
- * Copyright (C) 2018 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package android.ext.services.notification;
-
-import android.annotation.Nullable;
-import android.app.Notification;
-import android.app.PendingIntent;
-import android.app.Person;
-import android.app.RemoteAction;
-import android.app.RemoteInput;
-import android.content.Context;
-import android.content.Intent;
-import android.ext.services.R;
-import android.graphics.drawable.Icon;
-import android.os.Bundle;
-import android.os.Parcelable;
-import android.os.Process;
-import android.service.notification.NotificationAssistantService;
-import android.text.TextUtils;
-import android.util.ArrayMap;
-import android.util.LruCache;
-import android.util.Pair;
-import android.view.textclassifier.ConversationAction;
-import android.view.textclassifier.ConversationActions;
-import android.view.textclassifier.TextClassificationContext;
-import android.view.textclassifier.TextClassificationManager;
-import android.view.textclassifier.TextClassifier;
-import android.view.textclassifier.TextClassifierEvent;
-
-import com.android.internal.util.ArrayUtils;
-
-import java.time.Instant;
-import java.time.ZoneOffset;
-import java.time.ZonedDateTime;
-import java.util.ArrayDeque;
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.Deque;
-import java.util.List;
-import java.util.Map;
-import java.util.Objects;
-
-/**
- * Generates suggestions from incoming notifications.
- *
- * Methods in this class should be called in a single worker thread.
- */
-public class SmartActionsHelper {
-    static final String ENTITIES_EXTRAS = "entities-extras";
-    static final String KEY_ACTION_TYPE = "action_type";
-    static final String KEY_ACTION_SCORE = "action_score";
-    static final String KEY_TEXT = "text";
-    // If a notification has any of these flags set, it's inelgibile for actions being added.
-    private static final int FLAG_MASK_INELGIBILE_FOR_ACTIONS =
-            Notification.FLAG_ONGOING_EVENT
-                    | Notification.FLAG_FOREGROUND_SERVICE
-                    | Notification.FLAG_GROUP_SUMMARY
-                    | Notification.FLAG_NO_CLEAR;
-    private static final int MAX_RESULT_ID_TO_CACHE = 20;
-
-    private static final List<String> HINTS =
-            Collections.singletonList(ConversationActions.Request.HINT_FOR_NOTIFICATION);
-    private static final ConversationActions EMPTY_CONVERSATION_ACTIONS =
-            new ConversationActions(Collections.emptyList(), null);
-
-    private Context mContext;
-    private TextClassificationManager mTextClassificationManager;
-    private AssistantSettings mSettings;
-    private LruCache<String, Session> mSessionCache = new LruCache<>(MAX_RESULT_ID_TO_CACHE);
-
-    SmartActionsHelper(Context context, AssistantSettings settings) {
-        mContext = context;
-        mTextClassificationManager = mContext.getSystemService(TextClassificationManager.class);
-        mSettings = settings;
-    }
-
-    SmartSuggestions suggest(NotificationEntry entry) {
-        // Whenever suggest() is called on a notification, its previous session is ended.
-        mSessionCache.remove(entry.getSbn().getKey());
-
-        boolean eligibleForReplyAdjustment =
-                mSettings.mGenerateReplies && isEligibleForReplyAdjustment(entry);
-        boolean eligibleForActionAdjustment =
-                mSettings.mGenerateActions && isEligibleForActionAdjustment(entry);
-
-        ConversationActions conversationActionsResult =
-                suggestConversationActions(
-                        entry,
-                        eligibleForReplyAdjustment,
-                        eligibleForActionAdjustment);
-
-        String resultId = conversationActionsResult.getId();
-        List<ConversationAction> conversationActions =
-                conversationActionsResult.getConversationActions();
-
-        ArrayList<CharSequence> replies = new ArrayList<>();
-        Map<CharSequence, Float> repliesScore = new ArrayMap<>();
-        for (ConversationAction conversationAction : conversationActions) {
-            CharSequence textReply = conversationAction.getTextReply();
-            if (TextUtils.isEmpty(textReply)) {
-                continue;
-            }
-            replies.add(textReply);
-            repliesScore.put(textReply, conversationAction.getConfidenceScore());
-        }
-
-        ArrayList<Notification.Action> actions = new ArrayList<>();
-        for (ConversationAction conversationAction : conversationActions) {
-            if (!TextUtils.isEmpty(conversationAction.getTextReply())) {
-                continue;
-            }
-            Notification.Action notificationAction;
-            if (conversationAction.getAction() == null) {
-                notificationAction =
-                        createNotificationActionWithoutRemoteAction(conversationAction);
-            } else {
-                notificationAction = createNotificationActionFromRemoteAction(
-                        conversationAction.getAction(),
-                        conversationAction.getType(),
-                        conversationAction.getConfidenceScore());
-            }
-            if (notificationAction != null) {
-                actions.add(notificationAction);
-            }
-        }
-
-        // Start a new session for logging if necessary.
-        if (!TextUtils.isEmpty(resultId)
-                && !conversationActions.isEmpty()
-                && suggestionsMightBeUsedInNotification(
-                entry, !actions.isEmpty(), !replies.isEmpty())) {
-            mSessionCache.put(entry.getSbn().getKey(), new Session(resultId, repliesScore));
-        }
-
-        return new SmartSuggestions(replies, actions);
-    }
-
-    /**
-     * Creates notification action from ConversationAction that does not come up a RemoteAction.
-     * It could happen because we don't have common intents for some actions, like copying text.
-     */
-    @Nullable
-    private Notification.Action createNotificationActionWithoutRemoteAction(
-            ConversationAction conversationAction) {
-        if (ConversationAction.TYPE_COPY.equals(conversationAction.getType())) {
-            return createCopyCodeAction(conversationAction);
-        }
-        return null;
-    }
-
-    @Nullable
-    private Notification.Action createCopyCodeAction(ConversationAction conversationAction) {
-        Bundle extras = conversationAction.getExtras();
-        if (extras == null) {
-            return null;
-        }
-        Bundle entitiesExtas = extras.getParcelable(ENTITIES_EXTRAS);
-        if (entitiesExtas == null) {
-            return null;
-        }
-        String code = entitiesExtas.getString(KEY_TEXT);
-        if (TextUtils.isEmpty(code)) {
-            return null;
-        }
-        String contentDescription = mContext.getString(R.string.copy_code_desc, code);
-        Intent intent = new Intent(mContext, CopyCodeActivity.class);
-        intent.putExtra(Intent.EXTRA_TEXT, code);
-
-        RemoteAction remoteAction = new RemoteAction(Icon.createWithResource(
-                mContext.getResources(),
-                com.android.internal.R.drawable.ic_menu_copy_material),
-                code,
-                contentDescription,
-                PendingIntent.getActivity(
-                        mContext,
-                        code.hashCode(),
-                        intent,
-                        PendingIntent.FLAG_UPDATE_CURRENT
-                ));
-
-        return createNotificationActionFromRemoteAction(
-                remoteAction,
-                ConversationAction.TYPE_COPY,
-                conversationAction.getConfidenceScore());
-    }
-
-    /**
-     * Returns whether the suggestion might be used in the notifications in SysUI.
-     * <p>
-     * Currently, NAS has no idea if suggestions will actually be used in the notification, and thus
-     * this function tries to make a heuristic. This function tries to optimize the precision,
-     * that means when it is unsure, it will return false. The objective is to avoid false positive,
-     * which could pollute the log and CTR as we are logging click rate of suggestions that could
-     * be never visible to users. On the other hand, it is fine to have false negative because
-     * it would be just like sampling.
-     */
-    private boolean suggestionsMightBeUsedInNotification(
-            NotificationEntry notificationEntry, boolean hasSmartAction, boolean hasSmartReply) {
-        Notification notification = notificationEntry.getNotification();
-        boolean hasAppGeneratedContextualActions = !notification.getContextualActions().isEmpty();
-
-        Pair<RemoteInput, Notification.Action> freeformRemoteInputAndAction =
-                notification.findRemoteInputActionPair(/* requiresFreeform */ true);
-        boolean hasAppGeneratedReplies = false;
-        boolean allowGeneratedReplies = false;
-        if (freeformRemoteInputAndAction != null) {
-            RemoteInput freeformRemoteInput = freeformRemoteInputAndAction.first;
-            Notification.Action actionWithFreeformRemoteInput = freeformRemoteInputAndAction.second;
-            hasAppGeneratedReplies = !ArrayUtils.isEmpty(freeformRemoteInput.getChoices());
-            allowGeneratedReplies = actionWithFreeformRemoteInput.getAllowGeneratedReplies();
-        }
-
-        if (hasAppGeneratedReplies || hasAppGeneratedContextualActions) {
-            return false;
-        }
-        return hasSmartAction && notification.getAllowSystemGeneratedContextualActions()
-                || hasSmartReply && allowGeneratedReplies;
-    }
-
-    private void reportActionsGenerated(
-            String resultId, List<ConversationAction> conversationActions) {
-        if (TextUtils.isEmpty(resultId)) {
-            return;
-        }
-        TextClassifierEvent textClassifierEvent =
-                createTextClassifierEventBuilder(
-                        TextClassifierEvent.TYPE_ACTIONS_GENERATED, resultId)
-                        .setEntityTypes(conversationActions.stream()
-                                .map(ConversationAction::getType)
-                                .toArray(String[]::new))
-                        .build();
-        getTextClassifier().onTextClassifierEvent(textClassifierEvent);
-    }
-
-    /**
-     * Adds action adjustments based on the notification contents.
-     */
-    private ConversationActions suggestConversationActions(
-            NotificationEntry entry,
-            boolean includeReplies,
-            boolean includeActions) {
-        if (!includeReplies && !includeActions) {
-            return EMPTY_CONVERSATION_ACTIONS;
-        }
-        List<ConversationActions.Message> messages = extractMessages(entry.getNotification());
-        if (messages.isEmpty()) {
-            return EMPTY_CONVERSATION_ACTIONS;
-        }
-        // Do not generate smart actions if the last message is from the local user.
-        ConversationActions.Message lastMessage = messages.get(messages.size() - 1);
-        if (arePersonsEqual(
-                ConversationActions.Message.PERSON_USER_SELF, lastMessage.getAuthor())) {
-            return EMPTY_CONVERSATION_ACTIONS;
-        }
-
-        TextClassifier.EntityConfig.Builder typeConfigBuilder =
-                new TextClassifier.EntityConfig.Builder();
-        if (!includeReplies) {
-            typeConfigBuilder.setExcludedTypes(
-                    Collections.singletonList(ConversationAction.TYPE_TEXT_REPLY));
-        } else if (!includeActions) {
-            typeConfigBuilder
-                    .setIncludedTypes(
-                            Collections.singletonList(ConversationAction.TYPE_TEXT_REPLY))
-                    .includeTypesFromTextClassifier(false);
-        }
-        ConversationActions.Request request =
-                new ConversationActions.Request.Builder(messages)
-                        .setMaxSuggestions(mSettings.mMaxSuggestions)
-                        .setHints(HINTS)
-                        .setTypeConfig(typeConfigBuilder.build())
-                        .build();
-        ConversationActions conversationActions =
-                getTextClassifier().suggestConversationActions(request);
-        reportActionsGenerated(
-                conversationActions.getId(), conversationActions.getConversationActions());
-        return conversationActions;
-    }
-
-    void onNotificationExpansionChanged(NotificationEntry entry, boolean isExpanded) {
-        if (!isExpanded) {
-            return;
-        }
-        Session session = mSessionCache.get(entry.getSbn().getKey());
-        if (session == null) {
-            return;
-        }
-        // Only report if this is the first time the user sees these suggestions.
-        if (entry.isShowActionEventLogged()) {
-            return;
-        }
-        entry.setShowActionEventLogged();
-        TextClassifierEvent textClassifierEvent =
-                createTextClassifierEventBuilder(
-                        TextClassifierEvent.TYPE_ACTIONS_SHOWN, session.resultId)
-                        .build();
-        // TODO: If possible, report which replies / actions are actually seen by user.
-        getTextClassifier().onTextClassifierEvent(textClassifierEvent);
-    }
-
-    void onNotificationDirectReplied(String key) {
-        Session session = mSessionCache.get(key);
-        if (session == null) {
-            return;
-        }
-        TextClassifierEvent textClassifierEvent =
-                createTextClassifierEventBuilder(
-                        TextClassifierEvent.TYPE_MANUAL_REPLY, session.resultId)
-                        .build();
-        getTextClassifier().onTextClassifierEvent(textClassifierEvent);
-    }
-
-    void onSuggestedReplySent(String key, CharSequence reply,
-            @NotificationAssistantService.Source int source) {
-        if (source != NotificationAssistantService.SOURCE_FROM_ASSISTANT) {
-            return;
-        }
-        Session session = mSessionCache.get(key);
-        if (session == null) {
-            return;
-        }
-        TextClassifierEvent textClassifierEvent =
-                createTextClassifierEventBuilder(
-                        TextClassifierEvent.TYPE_SMART_ACTION, session.resultId)
-                        .setEntityTypes(ConversationAction.TYPE_TEXT_REPLY)
-                        .setScores(session.repliesScores.getOrDefault(reply, 0f))
-                        .build();
-        getTextClassifier().onTextClassifierEvent(textClassifierEvent);
-    }
-
-    void onActionClicked(String key, Notification.Action action,
-            @NotificationAssistantService.Source int source) {
-        if (source != NotificationAssistantService.SOURCE_FROM_ASSISTANT) {
-            return;
-        }
-        Session session = mSessionCache.get(key);
-        if (session == null) {
-            return;
-        }
-        String actionType = action.getExtras().getString(KEY_ACTION_TYPE);
-        if (actionType == null) {
-            return;
-        }
-        TextClassifierEvent textClassifierEvent =
-                createTextClassifierEventBuilder(
-                        TextClassifierEvent.TYPE_SMART_ACTION, session.resultId)
-                        .setEntityTypes(actionType)
-                        .build();
-        getTextClassifier().onTextClassifierEvent(textClassifierEvent);
-    }
-
-    private Notification.Action createNotificationActionFromRemoteAction(
-            RemoteAction remoteAction, String actionType, float score) {
-        Icon icon = remoteAction.shouldShowIcon()
-                ? remoteAction.getIcon()
-                : Icon.createWithResource(mContext, com.android.internal.R.drawable.ic_action_open);
-        Bundle extras = new Bundle();
-        extras.putString(KEY_ACTION_TYPE, actionType);
-        extras.putFloat(KEY_ACTION_SCORE, score);
-        return new Notification.Action.Builder(
-                icon,
-                remoteAction.getTitle(),
-                remoteAction.getActionIntent())
-                .setContextual(true)
-                .addExtras(extras)
-                .build();
-    }
-
-    private TextClassifierEvent.ConversationActionsEvent.Builder createTextClassifierEventBuilder(
-            int eventType, String resultId) {
-        return new TextClassifierEvent.ConversationActionsEvent.Builder(eventType)
-                .setEventContext(
-                        new TextClassificationContext.Builder(
-                                mContext.getPackageName(), TextClassifier.WIDGET_TYPE_NOTIFICATION)
-                        .build())
-                .setResultId(resultId);
-    }
-
-    /**
-     * Returns whether a notification is eligible for action adjustments.
-     *
-     * <p>We exclude system notifications, those that get refreshed frequently, or ones that relate
-     * to fundamental phone functionality where any error would result in a very negative user
-     * experience.
-     */
-    private boolean isEligibleForActionAdjustment(NotificationEntry entry) {
-        Notification notification = entry.getNotification();
-        String pkg = entry.getSbn().getPackageName();
-        if (!Process.myUserHandle().equals(entry.getSbn().getUser())) {
-            return false;
-        }
-        if ((notification.flags & FLAG_MASK_INELGIBILE_FOR_ACTIONS) != 0) {
-            return false;
-        }
-        if (TextUtils.isEmpty(pkg) || pkg.equals("android")) {
-            return false;
-        }
-        // For now, we are only interested in messages.
-        return entry.isMessaging();
-    }
-
-    private boolean isEligibleForReplyAdjustment(NotificationEntry entry) {
-        if (!Process.myUserHandle().equals(entry.getSbn().getUser())) {
-            return false;
-        }
-        String pkg = entry.getSbn().getPackageName();
-        if (TextUtils.isEmpty(pkg) || pkg.equals("android")) {
-            return false;
-        }
-        // For now, we are only interested in messages.
-        if (!entry.isMessaging()) {
-            return false;
-        }
-        // Does not make sense to provide suggested replies if it is not something that can be
-        // replied.
-        if (!entry.hasInlineReply()) {
-            return false;
-        }
-        return true;
-    }
-
-    /** Returns the text most salient for action extraction in a notification. */
-    private List<ConversationActions.Message> extractMessages(Notification notification) {
-        Parcelable[] messages = notification.extras.getParcelableArray(Notification.EXTRA_MESSAGES);
-        if (messages == null || messages.length == 0) {
-            return Collections.singletonList(new ConversationActions.Message.Builder(
-                    ConversationActions.Message.PERSON_USER_OTHERS)
-                    .setText(notification.extras.getCharSequence(Notification.EXTRA_TEXT))
-                    .build());
-        }
-        Person localUser = notification.extras.getParcelable(Notification.EXTRA_MESSAGING_PERSON);
-        Deque<ConversationActions.Message> extractMessages = new ArrayDeque<>();
-        for (int i = messages.length - 1; i >= 0; i--) {
-            Notification.MessagingStyle.Message message =
-                    Notification.MessagingStyle.Message.getMessageFromBundle((Bundle) messages[i]);
-            if (message == null) {
-                continue;
-            }
-            // As per the javadoc of Notification.addMessage, null means local user.
-            Person senderPerson = message.getSenderPerson();
-            if (senderPerson == null) {
-                senderPerson = localUser;
-            }
-            Person author = localUser != null && arePersonsEqual(localUser, senderPerson)
-                    ? ConversationActions.Message.PERSON_USER_SELF : senderPerson;
-            extractMessages.push(new ConversationActions.Message.Builder(author)
-                    .setText(message.getText())
-                    .setReferenceTime(
-                            ZonedDateTime.ofInstant(Instant.ofEpochMilli(message.getTimestamp()),
-                                    ZoneOffset.systemDefault()))
-                    .build());
-            if (extractMessages.size() >= mSettings.mMaxMessagesToExtract) {
-                break;
-            }
-        }
-        return new ArrayList<>(extractMessages);
-    }
-
-    private TextClassifier getTextClassifier() {
-        return mTextClassificationManager.getTextClassifier();
-    }
-
-    private static boolean arePersonsEqual(Person left, Person right) {
-        return Objects.equals(left.getKey(), right.getKey())
-                && Objects.equals(left.getName(), right.getName())
-                && Objects.equals(left.getUri(), right.getUri());
-    }
-
-    static class SmartSuggestions {
-        public final ArrayList<CharSequence> replies;
-        public final ArrayList<Notification.Action> actions;
-
-        SmartSuggestions(
-                ArrayList<CharSequence> replies, ArrayList<Notification.Action> actions) {
-            this.replies = replies;
-            this.actions = actions;
-        }
-    }
-
-    private static class Session {
-        public final String resultId;
-        public final Map<CharSequence, Float> repliesScores;
-
-        Session(String resultId, Map<CharSequence, Float> repliesScores) {
-            this.resultId = resultId;
-            this.repliesScores = repliesScores;
-        }
-    }
-}
diff --git a/packages/ExtServices/src/android/ext/services/notification/SmsHelper.java b/packages/ExtServices/src/android/ext/services/notification/SmsHelper.java
deleted file mode 100644
index 07be0b8..0000000
--- a/packages/ExtServices/src/android/ext/services/notification/SmsHelper.java
+++ /dev/null
@@ -1,75 +0,0 @@
-/**
- * Copyright (C) 2019 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package android.ext.services.notification;
-
-import static android.provider.Telephony.Sms.Intents.ACTION_DEFAULT_SMS_PACKAGE_CHANGED_INTERNAL;
-
-import android.annotation.Nullable;
-import android.content.BroadcastReceiver;
-import android.content.ComponentName;
-import android.content.Context;
-import android.content.Intent;
-import android.content.IntentFilter;
-import android.util.Log;
-
-import com.android.internal.telephony.SmsApplication;
-
-/**
- * A helper class for storing and retrieving the default SMS application.
- */
-public class SmsHelper {
-    private static final String TAG = "SmsHelper";
-
-    private final Context mContext;
-    private ComponentName mDefaultSmsApplication;
-    private BroadcastReceiver mBroadcastReceiver;
-
-    SmsHelper(Context context) {
-        mContext = context.getApplicationContext();
-    }
-
-    void initialize() {
-        if (mBroadcastReceiver == null) {
-            mDefaultSmsApplication = SmsApplication.getDefaultSmsApplication(mContext, false);
-            mBroadcastReceiver = new BroadcastReceiver() {
-                @Override
-                public void onReceive(Context context, Intent intent) {
-                    if (ACTION_DEFAULT_SMS_PACKAGE_CHANGED_INTERNAL.equals(intent.getAction())) {
-                        mDefaultSmsApplication =
-                                SmsApplication.getDefaultSmsApplication(mContext, false);
-                    } else {
-                        Log.w(TAG, "Unknown broadcast received: " + intent.getAction());
-                    }
-                }
-            };
-            mContext.registerReceiver(
-                    mBroadcastReceiver,
-                    new IntentFilter(ACTION_DEFAULT_SMS_PACKAGE_CHANGED_INTERNAL));
-        }
-    }
-
-    void destroy() {
-        if (mBroadcastReceiver != null) {
-            mContext.unregisterReceiver(mBroadcastReceiver);
-            mBroadcastReceiver = null;
-        }
-    }
-
-    @Nullable
-    public ComponentName getDefaultSmsApplication() {
-        return mDefaultSmsApplication;
-    }
-}
diff --git a/packages/ExtServices/src/android/ext/services/resolver/LRResolverRankerService.java b/packages/ExtServices/src/android/ext/services/resolver/LRResolverRankerService.java
deleted file mode 100644
index 9d7a568..0000000
--- a/packages/ExtServices/src/android/ext/services/resolver/LRResolverRankerService.java
+++ /dev/null
@@ -1,199 +0,0 @@
-/*
- * Copyright (C) 2017 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.ext.services.resolver;
-
-import android.content.Context;
-import android.content.Intent;
-import android.content.SharedPreferences;
-import android.os.Environment;
-import android.os.IBinder;
-import android.os.storage.StorageManager;
-import android.service.resolver.ResolverRankerService;
-import android.service.resolver.ResolverTarget;
-import android.util.ArrayMap;
-import android.util.Log;
-
-import java.io.File;
-import java.util.Collection;
-import java.util.List;
-import java.util.Map;
-
-/**
- * A Logistic Regression based {@link android.service.resolver.ResolverRankerService}, to be used
- * in {@link ResolverComparator}.
- */
-public final class LRResolverRankerService extends ResolverRankerService {
-    private static final String TAG = "LRResolverRankerService";
-
-    private static final boolean DEBUG = false;
-
-    private static final String PARAM_SHARED_PREF_NAME = "resolver_ranker_params";
-    private static final String BIAS_PREF_KEY = "bias";
-    private static final String VERSION_PREF_KEY = "version";
-
-    private static final String LAUNCH_SCORE = "launch";
-    private static final String TIME_SPENT_SCORE = "timeSpent";
-    private static final String RECENCY_SCORE = "recency";
-    private static final String CHOOSER_SCORE = "chooser";
-
-    // parameters for a pre-trained model, to initialize the app ranker. When updating the
-    // pre-trained model, please update these params, as well as initModel().
-    private static final int CURRENT_VERSION = 1;
-    private static final float LEARNING_RATE = 0.0001f;
-    private static final float REGULARIZER_PARAM = 0.0001f;
-
-    private SharedPreferences mParamSharedPref;
-    private ArrayMap<String, Float> mFeatureWeights;
-    private float mBias;
-
-    @Override
-    public IBinder onBind(Intent intent) {
-        initModel();
-        return super.onBind(intent);
-    }
-
-    @Override
-    public void onPredictSharingProbabilities(List<ResolverTarget> targets) {
-        final int size = targets.size();
-        for (int i = 0; i < size; ++i) {
-            ResolverTarget target = targets.get(i);
-            ArrayMap<String, Float> features = getFeatures(target);
-            target.setSelectProbability(predict(features));
-        }
-    }
-
-    @Override
-    public void onTrainRankingModel(List<ResolverTarget> targets, int selectedPosition) {
-        final int size = targets.size();
-        if (selectedPosition < 0 || selectedPosition >= size) {
-            if (DEBUG) {
-                Log.d(TAG, "Invalid Position of Selected App " + selectedPosition);
-            }
-            return;
-        }
-        final ArrayMap<String, Float> positive = getFeatures(targets.get(selectedPosition));
-        final float positiveProbability = targets.get(selectedPosition).getSelectProbability();
-        final int targetSize = targets.size();
-        for (int i = 0; i < targetSize; ++i) {
-            if (i == selectedPosition) {
-                continue;
-            }
-            final ArrayMap<String, Float> negative = getFeatures(targets.get(i));
-            final float negativeProbability = targets.get(i).getSelectProbability();
-            if (negativeProbability > positiveProbability) {
-                update(negative, negativeProbability, false);
-                update(positive, positiveProbability, true);
-            }
-        }
-        commitUpdate();
-    }
-
-    private void initModel() {
-        mParamSharedPref = getParamSharedPref();
-        mFeatureWeights = new ArrayMap<>(4);
-        if (mParamSharedPref == null ||
-                mParamSharedPref.getInt(VERSION_PREF_KEY, 0) < CURRENT_VERSION) {
-            // Initializing the app ranker to a pre-trained model. When updating the pre-trained
-            // model, please increment CURRENT_VERSION, and update LEARNING_RATE and
-            // REGULARIZER_PARAM.
-            mBias = -1.6568f;
-            mFeatureWeights.put(LAUNCH_SCORE, 2.5543f);
-            mFeatureWeights.put(TIME_SPENT_SCORE, 2.8412f);
-            mFeatureWeights.put(RECENCY_SCORE, 0.269f);
-            mFeatureWeights.put(CHOOSER_SCORE, 4.2222f);
-        } else {
-            mBias = mParamSharedPref.getFloat(BIAS_PREF_KEY, 0.0f);
-            mFeatureWeights.put(LAUNCH_SCORE, mParamSharedPref.getFloat(LAUNCH_SCORE, 0.0f));
-            mFeatureWeights.put(
-                    TIME_SPENT_SCORE, mParamSharedPref.getFloat(TIME_SPENT_SCORE, 0.0f));
-            mFeatureWeights.put(RECENCY_SCORE, mParamSharedPref.getFloat(RECENCY_SCORE, 0.0f));
-            mFeatureWeights.put(CHOOSER_SCORE, mParamSharedPref.getFloat(CHOOSER_SCORE, 0.0f));
-        }
-    }
-
-    private ArrayMap<String, Float> getFeatures(ResolverTarget target) {
-        ArrayMap<String, Float> features = new ArrayMap<>(4);
-        features.put(RECENCY_SCORE, target.getRecencyScore());
-        features.put(TIME_SPENT_SCORE, target.getTimeSpentScore());
-        features.put(LAUNCH_SCORE, target.getLaunchScore());
-        features.put(CHOOSER_SCORE, target.getChooserScore());
-        return features;
-    }
-
-    private float predict(ArrayMap<String, Float> target) {
-        if (target == null) {
-            return 0.0f;
-        }
-        final int featureSize = target.size();
-        float sum = 0.0f;
-        for (int i = 0; i < featureSize; i++) {
-            String featureName = target.keyAt(i);
-            float weight = mFeatureWeights.getOrDefault(featureName, 0.0f);
-            sum += weight * target.valueAt(i);
-        }
-        return (float) (1.0 / (1.0 + Math.exp(-mBias - sum)));
-    }
-
-    private void update(ArrayMap<String, Float> target, float predict, boolean isSelected) {
-        if (target == null) {
-            return;
-        }
-        final int featureSize = target.size();
-        float error = isSelected ? 1.0f - predict : -predict;
-        for (int i = 0; i < featureSize; i++) {
-            String featureName = target.keyAt(i);
-            float currentWeight = mFeatureWeights.getOrDefault(featureName, 0.0f);
-            mBias += LEARNING_RATE * error;
-            currentWeight = currentWeight - LEARNING_RATE * REGULARIZER_PARAM * currentWeight +
-                    LEARNING_RATE * error * target.valueAt(i);
-            mFeatureWeights.put(featureName, currentWeight);
-        }
-        if (DEBUG) {
-            Log.d(TAG, "Weights: " + mFeatureWeights + " Bias: " + mBias);
-        }
-    }
-
-    private void commitUpdate() {
-        try {
-            SharedPreferences.Editor editor = mParamSharedPref.edit();
-            editor.putFloat(BIAS_PREF_KEY, mBias);
-            final int size = mFeatureWeights.size();
-            for (int i = 0; i < size; i++) {
-                editor.putFloat(mFeatureWeights.keyAt(i), mFeatureWeights.valueAt(i));
-            }
-            editor.putInt(VERSION_PREF_KEY, CURRENT_VERSION);
-            editor.apply();
-        } catch (Exception e) {
-            Log.e(TAG, "Failed to commit update" + e);
-        }
-    }
-
-    private SharedPreferences getParamSharedPref() {
-        // The package info in the context isn't initialized in the way it is for normal apps,
-        // so the standard, name-based context.getSharedPreferences doesn't work. Instead, we
-        // build the path manually below using the same policy that appears in ContextImpl.
-        if (DEBUG) {
-            Log.d(TAG, "Context Package Name: " + getPackageName());
-        }
-        final File prefsFile = new File(new File(
-                Environment.getDataUserCePackageDirectory(
-                        StorageManager.UUID_PRIVATE_INTERNAL, getUserId(), getPackageName()),
-                "shared_prefs"),
-                PARAM_SHARED_PREF_NAME + ".xml");
-        return getSharedPreferences(prefsFile, Context.MODE_PRIVATE);
-    }
-}
\ No newline at end of file
diff --git a/packages/ExtServices/src/android/ext/services/sms/FinancialSmsServiceImpl.java b/packages/ExtServices/src/android/ext/services/sms/FinancialSmsServiceImpl.java
deleted file mode 100644
index 81a63dd..0000000
--- a/packages/ExtServices/src/android/ext/services/sms/FinancialSmsServiceImpl.java
+++ /dev/null
@@ -1,37 +0,0 @@
-/*
- * Copyright (C) 2018 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package android.ext.services.sms;
-
-import android.annotation.NonNull;
-import android.annotation.Nullable;
-import android.database.CursorWindow;
-import android.os.Bundle;
-import android.service.sms.FinancialSmsService;
-
-/**
- * Service to provide financial apps access to sms messages.
- */
-public class FinancialSmsServiceImpl extends FinancialSmsService {
-
-    private static final String TAG = "FinancialSmsServiceImpl";
-    private static final String KEY_COLUMN_NAMES = "column_names";
-
-    @Nullable
-    @Override
-    public CursorWindow onGetSmsMessages(@NonNull Bundle params) {
-        return null;
-    }
-}
diff --git a/packages/ExtServices/src/android/ext/services/storage/CacheQuotaServiceImpl.java b/packages/ExtServices/src/android/ext/services/storage/CacheQuotaServiceImpl.java
deleted file mode 100644
index 862f50b2..0000000
--- a/packages/ExtServices/src/android/ext/services/storage/CacheQuotaServiceImpl.java
+++ /dev/null
@@ -1,143 +0,0 @@
-/*
- * Copyright (C) 2017 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.ext.services.storage;
-
-import android.app.usage.CacheQuotaHint;
-import android.app.usage.CacheQuotaService;
-import android.os.Environment;
-import android.os.storage.StorageManager;
-import android.os.storage.VolumeInfo;
-import android.util.ArrayMap;
-
-import java.util.ArrayList;
-import java.util.Comparator;
-import java.util.List;
-import java.util.Map;
-import java.util.stream.Collectors;
-
-/**
- * CacheQuotaServiceImpl implements the CacheQuotaService with a strategy for populating the quota
- * of {@link CacheQuotaHint}.
- */
-public class CacheQuotaServiceImpl extends CacheQuotaService {
-    private static final double CACHE_RESERVE_RATIO = 0.15;
-
-    @Override
-    public List<CacheQuotaHint> onComputeCacheQuotaHints(List<CacheQuotaHint> requests) {
-        ArrayMap<String, List<CacheQuotaHint>> byUuid = new ArrayMap<>();
-        final int requestCount = requests.size();
-        for (int i = 0; i < requestCount; i++) {
-            CacheQuotaHint request = requests.get(i);
-            String uuid = request.getVolumeUuid();
-            List<CacheQuotaHint> listForUuid = byUuid.get(uuid);
-            if (listForUuid == null) {
-                listForUuid = new ArrayList<>();
-                byUuid.put(uuid, listForUuid);
-            }
-            listForUuid.add(request);
-        }
-
-        List<CacheQuotaHint> processed = new ArrayList<>();
-        byUuid.entrySet().forEach(
-                requestListEntry -> {
-                    // Collapse all usage stats to the same uid.
-                    Map<Integer, List<CacheQuotaHint>> byUid = requestListEntry.getValue()
-                            .stream()
-                            .collect(Collectors.groupingBy(CacheQuotaHint::getUid));
-                    byUid.values().forEach(uidGroupedList -> {
-                        int size = uidGroupedList.size();
-                        if (size < 2) {
-                            return;
-                        }
-                        CacheQuotaHint first = uidGroupedList.get(0);
-                        for (int i = 1; i < size; i++) {
-                            /* Note: We can't use the UsageStats built-in addition function because
-                                     UIDs may span multiple packages and usage stats adding has
-                                     matching package names as a precondition. */
-                            first.getUsageStats().mTotalTimeInForeground +=
-                                    uidGroupedList.get(i).getUsageStats().mTotalTimeInForeground;
-                        }
-                    });
-
-                    // Because the foreground stats have been added to the first element, we need
-                    // a list of only the first values (which contain the merged foreground time).
-                    List<CacheQuotaHint> flattenedRequests =
-                            byUid.values()
-                                 .stream()
-                                 .map(entryList -> entryList.get(0))
-                                 .filter(entry -> entry.getUsageStats().mTotalTimeInForeground != 0)
-                                 .sorted(sCacheQuotaRequestComparator)
-                                 .collect(Collectors.toList());
-
-                    // Because the elements are sorted, we can use the index to also be the sorted
-                    // index for cache quota calculation.
-                    double sum = getSumOfFairShares(flattenedRequests.size());
-                    String uuid = requestListEntry.getKey();
-                    long reservedSize = getReservedCacheSize(uuid);
-                    for (int count = 0; count < flattenedRequests.size(); count++) {
-                        double share = getFairShareForPosition(count) / sum;
-                        CacheQuotaHint entry = flattenedRequests.get(count);
-                        CacheQuotaHint.Builder builder = new CacheQuotaHint.Builder(entry);
-                        builder.setQuota(Math.round(share * reservedSize));
-                        processed.add(builder.build());
-                    }
-                }
-        );
-
-        return processed.stream()
-                .filter(request -> request.getQuota() > 0).collect(Collectors.toList());
-    }
-
-    private double getFairShareForPosition(int position) {
-        double value = 1.0 / Math.log(position + 3) - 0.285;
-        return (value > 0.01) ? value : 0.01;
-    }
-
-    private double getSumOfFairShares(int size) {
-        double sum = 0;
-        for (int i = 0; i < size; i++) {
-            sum += getFairShareForPosition(i);
-        }
-        return sum;
-    }
-
-    private long getReservedCacheSize(String uuid) {
-        // TODO: Revisit the cache size after running more storage tests.
-        // TODO: Figure out how to ensure ExtServices has the permissions to call
-        //       StorageStatsManager, because this is ignoring the cache...
-        StorageManager storageManager = getSystemService(StorageManager.class);
-        long freeBytes = 0;
-        if (uuid == StorageManager.UUID_PRIVATE_INTERNAL) { // regular equals because of null
-            freeBytes = Environment.getDataDirectory().getUsableSpace();
-        } else {
-            final VolumeInfo vol = storageManager.findVolumeByUuid(uuid);
-            freeBytes = vol.getPath().getUsableSpace();
-        }
-        return Math.round(freeBytes * CACHE_RESERVE_RATIO);
-    }
-
-    // Compares based upon foreground time.
-    private static Comparator<CacheQuotaHint> sCacheQuotaRequestComparator =
-            new Comparator<CacheQuotaHint>() {
-        @Override
-        public int compare(CacheQuotaHint o, CacheQuotaHint t1) {
-            long x = t1.getUsageStats().getTotalTimeInForeground();
-            long y = o.getUsageStats().getTotalTimeInForeground();
-            return (x < y) ? -1 : ((x == y) ? 0 : 1);
-        }
-    };
-}
diff --git a/packages/ExtServices/src/android/ext/services/watchdog/ExplicitHealthCheckServiceImpl.java b/packages/ExtServices/src/android/ext/services/watchdog/ExplicitHealthCheckServiceImpl.java
deleted file mode 100644
index 670b419..0000000
--- a/packages/ExtServices/src/android/ext/services/watchdog/ExplicitHealthCheckServiceImpl.java
+++ /dev/null
@@ -1,125 +0,0 @@
-/*
- * Copyright (C) 2019 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.ext.services.watchdog;
-
-import static android.service.watchdog.ExplicitHealthCheckService.PackageConfig;
-
-import android.content.ComponentName;
-import android.content.Intent;
-import android.provider.DeviceConfig;
-import android.service.watchdog.ExplicitHealthCheckService;
-import android.util.Log;
-
-import java.util.ArrayList;
-import java.util.Iterator;
-import java.util.List;
-import java.util.Map;
-import java.util.concurrent.ConcurrentHashMap;
-import java.util.concurrent.TimeUnit;
-
-/**
- * Routes explicit health check requests to the appropriate {@link ExplicitHealthChecker}.
- */
-public final class ExplicitHealthCheckServiceImpl extends ExplicitHealthCheckService {
-    private static final String TAG = "ExplicitHealthCheckServiceImpl";
-    // TODO: Add build dependency on NetworkStack stable AIDL so we can stop hard coding class name
-    private static final String NETWORK_STACK_CONNECTOR_CLASS =
-            "android.net.INetworkStackConnector";
-    public static final String PROPERTY_WATCHDOG_REQUEST_TIMEOUT_MILLIS =
-            "watchdog_request_timeout_millis";
-    public static final long DEFAULT_REQUEST_TIMEOUT_MILLIS =
-            TimeUnit.HOURS.toMillis(1);
-    // Modified only #onCreate, using concurrent collection to ensure thread visibility
-    private final Map<String, ExplicitHealthChecker> mSupportedCheckers = new ConcurrentHashMap<>();
-
-    @Override
-    public void onCreate() {
-        super.onCreate();
-        initHealthCheckers();
-    }
-
-    @Override
-    public void onRequestHealthCheck(String packageName) {
-        ExplicitHealthChecker checker = mSupportedCheckers.get(packageName);
-        if (checker != null) {
-            checker.request();
-        } else {
-            Log.w(TAG, "Ignoring request for explicit health check for unsupported package "
-                    + packageName);
-        }
-    }
-
-    @Override
-    public void onCancelHealthCheck(String packageName) {
-        ExplicitHealthChecker checker = mSupportedCheckers.get(packageName);
-        if (checker != null) {
-            checker.cancel();
-        } else {
-            Log.w(TAG, "Ignoring request to cancel explicit health check for unsupported package "
-                    + packageName);
-        }
-    }
-
-    @Override
-    public List<PackageConfig> onGetSupportedPackages() {
-        List<PackageConfig> packages = new ArrayList<>();
-        long requestTimeoutMillis = DeviceConfig.getLong(
-                DeviceConfig.NAMESPACE_ROLLBACK,
-                PROPERTY_WATCHDOG_REQUEST_TIMEOUT_MILLIS,
-                DEFAULT_REQUEST_TIMEOUT_MILLIS);
-        if (requestTimeoutMillis <= 0) {
-            requestTimeoutMillis = DEFAULT_REQUEST_TIMEOUT_MILLIS;
-        }
-        for (ExplicitHealthChecker checker : mSupportedCheckers.values()) {
-            PackageConfig pkg = new PackageConfig(checker.getSupportedPackageName(),
-                    requestTimeoutMillis);
-            packages.add(pkg);
-        }
-        return packages;
-    }
-
-    @Override
-    public List<String> onGetRequestedPackages() {
-        List<String> packages = new ArrayList<>();
-        Iterator<ExplicitHealthChecker> it = mSupportedCheckers.values().iterator();
-        // Could potentially race, where we read a checker#isPending and it changes before we
-        // return list. However, if it races and it is in the list, the caller might call #cancel
-        // which would fail, but that is fine. If it races and it ends up *not* in the list, it was
-        // already cancelled, so there's no need for the caller to cancel it
-        while (it.hasNext()) {
-            ExplicitHealthChecker checker = it.next();
-            if (checker.isPending()) {
-                packages.add(checker.getSupportedPackageName());
-            }
-        }
-        return packages;
-    }
-
-    private void initHealthCheckers() {
-        Intent intent = new Intent(NETWORK_STACK_CONNECTOR_CLASS);
-        ComponentName comp = intent.resolveSystemService(getPackageManager(), 0);
-        if (comp != null) {
-            String networkStackPackageName = comp.getPackageName();
-            mSupportedCheckers.put(networkStackPackageName,
-                    new NetworkChecker(this, networkStackPackageName));
-        } else {
-            // On Go devices, or any device that does not ship the network stack module.
-            // The network stack will live in system_server process, so no need to monitor.
-            Log.i(TAG, "Network stack module not found");
-        }
-    }
-}
diff --git a/packages/ExtServices/src/android/ext/services/watchdog/ExplicitHealthChecker.java b/packages/ExtServices/src/android/ext/services/watchdog/ExplicitHealthChecker.java
deleted file mode 100644
index a982d52..0000000
--- a/packages/ExtServices/src/android/ext/services/watchdog/ExplicitHealthChecker.java
+++ /dev/null
@@ -1,44 +0,0 @@
-/*
- * Copyright (C) 2019 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.ext.services.watchdog;
-
-/**
- * A type of explicit health check that can be performed on a device, e.g network health check
- */
-interface ExplicitHealthChecker {
-    /**
-     * Requests a checker to listen to explicit health checks for {@link #getPackageName}.
-     *  {@link #isPending} will now return {@code true}.
-     */
-    void request();
-
-    /**
-     * Cancels a pending explicit health check request for {@link #getPackageName}.
-     * {@link #isPending} will now return {@code false}.
-     */
-    void cancel();
-
-    /**
-     * Returns {@code true} if a request is pending, {@code false} otherwise.
-     */
-    boolean isPending();
-
-    /**
-     * Returns the name of the package this checker can make requests for.
-     */
-    String getSupportedPackageName();
-}
diff --git a/packages/ExtServices/src/android/ext/services/watchdog/NetworkChecker.java b/packages/ExtServices/src/android/ext/services/watchdog/NetworkChecker.java
deleted file mode 100644
index 5722e09..0000000
--- a/packages/ExtServices/src/android/ext/services/watchdog/NetworkChecker.java
+++ /dev/null
@@ -1,92 +0,0 @@
-/*
- * Copyright (C) 2019 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.ext.services.watchdog;
-
-import android.net.ConnectivityManager;
-import android.net.Network;
-import android.net.NetworkCapabilities;
-import android.net.NetworkRequest;
-import android.service.watchdog.ExplicitHealthCheckService;
-
-import com.android.internal.annotations.GuardedBy;
-
-/**
- * Observes the network stack via the ConnectivityManager.
- */
-final class NetworkChecker extends ConnectivityManager.NetworkCallback
-        implements ExplicitHealthChecker {
-    private static final String TAG = "NetworkChecker";
-
-    private final Object mLock = new Object();
-    private final ExplicitHealthCheckService mService;
-    private final String mPackageName;
-    @GuardedBy("mLock")
-    private boolean mIsPending;
-
-    NetworkChecker(ExplicitHealthCheckService service, String packageName) {
-        mService = service;
-        mPackageName = packageName;
-    }
-
-    @Override
-    public void request() {
-        synchronized (mLock) {
-            if (mIsPending) {
-                return;
-            }
-            mService.getSystemService(ConnectivityManager.class).registerNetworkCallback(
-                    new NetworkRequest.Builder().build(), this);
-            mIsPending = true;
-        }
-    }
-
-    @Override
-    public void cancel() {
-        synchronized (mLock) {
-            if (!mIsPending) {
-                return;
-            }
-            mService.getSystemService(ConnectivityManager.class).unregisterNetworkCallback(this);
-            mIsPending = false;
-        }
-    }
-
-    @Override
-    public boolean isPending() {
-        synchronized (mLock) {
-            return mIsPending;
-        }
-    }
-
-    @Override
-    public String getSupportedPackageName() {
-        return mPackageName;
-    }
-
-    // TODO(b/120598832): Also monitor NetworkCallback#onAvailable to see if we have any
-    // available networks that may be unusable. This could be additional signal to our heuristics
-    @Override
-    public void onCapabilitiesChanged(Network network, NetworkCapabilities capabilities) {
-        synchronized (mLock) {
-            if (mIsPending
-                    && capabilities.hasCapability(NetworkCapabilities.NET_CAPABILITY_VALIDATED)) {
-                mService.notifyHealthCheckPassed(mPackageName);
-                cancel();
-            }
-        }
-    }
-}
diff --git a/packages/ExtServices/tests/Android.bp b/packages/ExtServices/tests/Android.bp
deleted file mode 100644
index ae60d4e..0000000
--- a/packages/ExtServices/tests/Android.bp
+++ /dev/null
@@ -1,27 +0,0 @@
-android_test {
-    name: "ExtServicesUnitTests",
-
-    // Include all test java files.
-    srcs: ["src/**/*.java"],
-
-    // We only want this apk build for tests.
-    certificate: "platform",
-
-    libs: [
-        "android.test.runner",
-        "android.test.base",
-    ],
-
-    static_libs: [
-        "ExtServices-core",
-        "androidx.test.rules",
-        "compatibility-device-util-axt",
-        "mockito-target-minus-junit4",
-        "androidx.test.espresso.core",
-        "truth-prebuilt",
-        "testables",
-        "testng",
-    ],
-
-    platform_apis: true,
-}
diff --git a/packages/ExtServices/tests/AndroidManifest.xml b/packages/ExtServices/tests/AndroidManifest.xml
deleted file mode 100644
index a08a10e..0000000
--- a/packages/ExtServices/tests/AndroidManifest.xml
+++ /dev/null
@@ -1,31 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2016 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.
--->
-
-<manifest xmlns:android="http://schemas.android.com/apk/res/android"
-          package="android.ext.services.tests.unit">
-
-    <uses-permission android:name="android.permission.INTERACT_ACROSS_USERS_FULL" />
-
-    <application>
-        <uses-library android:name="android.test.runner" />
-    </application>
-
-    <instrumentation android:name="androidx.test.runner.AndroidJUnitRunner"
-                     android:targetPackage="android.ext.services.tests.unit"
-                     android:label="ExtServices Test Cases">
-    </instrumentation>
-
-</manifest>
\ No newline at end of file
diff --git a/packages/ExtServices/tests/AndroidTest.xml b/packages/ExtServices/tests/AndroidTest.xml
deleted file mode 100644
index cd26ebc..0000000
--- a/packages/ExtServices/tests/AndroidTest.xml
+++ /dev/null
@@ -1,29 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- 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.
--->
-<configuration description="Runs Tests for ExtServices">
-    <target_preparer class="com.android.tradefed.targetprep.TestAppInstallSetup">
-        <option name="test-file-name" value="ExtServicesUnitTests.apk" />
-    </target_preparer>
-
-    <option name="test-suite-tag" value="apct" />
-    <option name="test-suite-tag" value="framework-base-presubmit" />
-    <option name="test-tag" value="ExtServicesUnitTests" />
-    <test class="com.android.tradefed.testtype.AndroidJUnitTest" >
-        <option name="package" value="android.ext.services.tests.unit" />
-        <option name="runner" value="androidx.test.runner.AndroidJUnitRunner" />
-        <option name="hidden-api-checks" value="false"/>
-    </test>
-</configuration>
\ No newline at end of file
diff --git a/packages/ExtServices/tests/src/android/ext/services/autofill/AutofillFieldClassificationServiceImplTest.java b/packages/ExtServices/tests/src/android/ext/services/autofill/AutofillFieldClassificationServiceImplTest.java
deleted file mode 100644
index 6fda4c7..0000000
--- a/packages/ExtServices/tests/src/android/ext/services/autofill/AutofillFieldClassificationServiceImplTest.java
+++ /dev/null
@@ -1,118 +0,0 @@
-/*
- * Copyright (C) 2018 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.ext.services.autofill;
-
-import static android.service.autofill.AutofillFieldClassificationService.REQUIRED_ALGORITHM_EXACT_MATCH;
-import static android.view.autofill.AutofillValue.forText;
-
-import static com.google.common.truth.Truth.assertThat;
-import static com.google.common.truth.Truth.assertWithMessage;
-
-import android.os.Bundle;
-import android.view.autofill.AutofillValue;
-
-import org.junit.Test;
-
-import java.util.Arrays;
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.List;
-
-/**
- * Contains the base tests that does not rely on the specific algorithm implementation.
- */
-public class AutofillFieldClassificationServiceImplTest {
-
-    private final AutofillFieldClassificationServiceImpl mService =
-            new AutofillFieldClassificationServiceImpl();
-
-    @Test
-    public void testOnCalculateScores_nullActualValues() {
-        assertThat(mService.onCalculateScores(null, null, null, null, null, null, null)).isNull();
-    }
-
-    @Test
-    public void testOnCalculateScores_emptyActualValues() {
-        assertThat(mService.onCalculateScores(Collections.emptyList(), Arrays.asList("whatever"),
-                null, null, null, null, null)).isNull();
-    }
-
-    @Test
-    public void testOnCalculateScores_nullUserDataValues() {
-        assertThat(mService.onCalculateScores(Arrays.asList(AutofillValue.forText("whatever")),
-                null, null, null, null, null, null)).isNull();
-    }
-
-    @Test
-    public void testOnCalculateScores_emptyUserDataValues() {
-        assertThat(mService.onCalculateScores(Arrays.asList(AutofillValue.forText("whatever")),
-                Collections.emptyList(), null, null, null, null, null))
-                .isNull();
-    }
-
-    @Test
-    public void testCalculateScores() {
-        final List<AutofillValue> actualValues = Arrays.asList(forText("A"), forText("b"),
-                forText("dude"));
-        final List<String> userDataValues = Arrays.asList("a", "b", "B", "ab", "c", "dude",
-                "sweet_dude", "dude_sweet");
-        final List<String> categoryIds = Arrays.asList("cat", "cat", "cat", "cat", "cat", "last4",
-                "last4", "last4");
-        final HashMap<String, String> algorithms = new HashMap<>(1);
-        algorithms.put("last4", REQUIRED_ALGORITHM_EXACT_MATCH);
-
-        final Bundle last4Bundle = new Bundle();
-        last4Bundle.putInt("suffix", 4);
-
-        final HashMap<String, Bundle> args = new HashMap<>(1);
-        args.put("last4", last4Bundle);
-
-        final float[][] expectedScores = new float[][] {
-                new float[] { 1F, 0F, 0F, 0.5F, 0F, 0F, 0F, 0F },
-                new float[] { 0F, 1F, 1F, 0.5F, 0F, 0F, 0F, 0F },
-                new float[] { 0F, 0F, 0F, 0F  , 0F, 1F, 1F, 0F }
-        };
-        final float[][] actualScores = mService.onCalculateScores(actualValues, userDataValues,
-                categoryIds, null, null, algorithms, args);
-
-        // Unfortunately, Truth does not have an easy way to compare float matrices and show useful
-        // messages in case of error, so we need to check.
-        assertWithMessage("actual=%s, expected=%s", toString(actualScores),
-                toString(expectedScores)).that(actualScores.length).isEqualTo(3);
-        for (int i = 0; i < 3; i++) {
-            assertWithMessage("actual=%s, expected=%s", toString(actualScores),
-                    toString(expectedScores)).that(actualScores[i].length).isEqualTo(8);
-        }
-
-        for (int i = 0; i < actualScores.length; i++) {
-            final float[] line = actualScores[i];
-            for (int j = 0; j < line.length; j++) {
-                float cell = line[j];
-                assertWithMessage("wrong score at [%s, %s]", i, j).that(cell).isWithin(0.01F)
-                        .of(expectedScores[i][j]);
-            }
-        }
-    }
-
-    public static String toString(float[][] matrix) {
-        final StringBuilder string = new StringBuilder("[ ");
-        for (int i = 0; i < matrix.length; i++) {
-            string.append(Arrays.toString(matrix[i])).append(" ");
-        }
-        return string.append(" ]").toString();
-    }
-}
diff --git a/packages/ExtServices/tests/src/android/ext/services/autofill/EditDistanceScorerTest.java b/packages/ExtServices/tests/src/android/ext/services/autofill/EditDistanceScorerTest.java
deleted file mode 100644
index 3d754f7..0000000
--- a/packages/ExtServices/tests/src/android/ext/services/autofill/EditDistanceScorerTest.java
+++ /dev/null
@@ -1,85 +0,0 @@
-/*
- * Copyright (C) 2018 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package android.ext.services.autofill;
-
-import static android.ext.services.autofill.EditDistanceScorer.calculateScore;
-import static android.ext.services.autofill.EditDistanceScorer.editDistance;
-
-import static com.google.common.truth.Truth.assertThat;
-
-import android.view.autofill.AutofillValue;
-
-import org.junit.Test;
-
-public class EditDistanceScorerTest {
-
-    @Test
-    public void testCalculateScore_nullValue() {
-        assertFloat(calculateScore(null, "D'OH!"), 0);
-    }
-
-    @Test
-    public void testCalculateScore_nonTextValue() {
-        assertFloat(calculateScore(AutofillValue.forToggle(true), "D'OH!"), 0);
-    }
-
-    @Test
-    public void testCalculateScore_nullUserData() {
-        assertFloat(calculateScore(AutofillValue.forText("D'OH!"), null), 0);
-    }
-
-    @Test
-    public void testCalculateScore_fullMatch() {
-        assertFloat(calculateScore(AutofillValue.forText("D'OH!"), "D'OH!"), 1);
-        assertFloat(calculateScore(AutofillValue.forText(""), ""), 1);
-    }
-
-    @Test
-    public void testCalculateScore_fullMatchMixedCase() {
-        assertFloat(calculateScore(AutofillValue.forText("D'OH!"), "D'oH!"), 1);
-    }
-
-    @Test
-    public void testCalculateScore_mismatchDifferentSizes() {
-        assertFloat(calculateScore(AutofillValue.forText("X"), "Xy"), 0.50F);
-        assertFloat(calculateScore(AutofillValue.forText("Xy"), "X"), 0.50F);
-        assertFloat(calculateScore(AutofillValue.forText("One"), "MoreThanOne"), 0.27F);
-        assertFloat(calculateScore(AutofillValue.forText("MoreThanOne"), "One"), 0.27F);
-        assertFloat(calculateScore(AutofillValue.forText("1600 Amphitheatre Parkway"),
-                "1600 Amphitheatre Pkwy"), 0.88F);
-        assertFloat(calculateScore(AutofillValue.forText("1600 Amphitheatre Pkwy"),
-                "1600 Amphitheatre Parkway"), 0.88F);
-    }
-
-    @Test
-    public void testCalculateScore_partialMatch() {
-        assertFloat(calculateScore(AutofillValue.forText("Dude"), "Dxxx"), 0.25F);
-        assertFloat(calculateScore(AutofillValue.forText("Dude"), "DUxx"), 0.50F);
-        assertFloat(calculateScore(AutofillValue.forText("Dude"), "DUDx"), 0.75F);
-        assertFloat(calculateScore(AutofillValue.forText("Dxxx"), "Dude"), 0.25F);
-        assertFloat(calculateScore(AutofillValue.forText("DUxx"), "Dude"), 0.50F);
-        assertFloat(calculateScore(AutofillValue.forText("DUDx"), "Dude"), 0.75F);
-    }
-
-    @Test
-    public void testEditDistance_maxDistance() {
-        assertFloat(editDistance("testing", "b", 4), Integer.MAX_VALUE);
-    }
-
-    public static void assertFloat(float actualValue, float expectedValue) {
-        assertThat(actualValue).isWithin(0.01F).of(expectedValue);
-    }
-}
diff --git a/packages/ExtServices/tests/src/android/ext/services/autofill/ExactMatchTest.java b/packages/ExtServices/tests/src/android/ext/services/autofill/ExactMatchTest.java
deleted file mode 100644
index bf5e160..0000000
--- a/packages/ExtServices/tests/src/android/ext/services/autofill/ExactMatchTest.java
+++ /dev/null
@@ -1,98 +0,0 @@
-/*
- * Copyright (C) 2018 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package android.ext.services.autofill;
-
-import static android.ext.services.autofill.ExactMatch.calculateScore;
-
-import static com.google.common.truth.Truth.assertThat;
-
-import static org.testng.Assert.assertThrows;
-
-import android.os.Bundle;
-import android.view.autofill.AutofillValue;
-
-import org.junit.Test;
-
-public class ExactMatchTest {
-
-    private Bundle last4Bundle() {
-        final Bundle bundle = new Bundle();
-        bundle.putInt("suffix", 4);
-        return bundle;
-    }
-
-    @Test
-    public void testCalculateScore_nullValue() {
-        assertFloat(calculateScore(null, "TEST", null), 0);
-    }
-
-    @Test
-    public void testCalculateScore_nonTextValue() {
-        assertFloat(calculateScore(AutofillValue.forToggle(true), "TEST", null), 0);
-    }
-
-    @Test
-    public void testCalculateScore_nullUserData() {
-        assertFloat(calculateScore(AutofillValue.forText("TEST"), null, null), 0);
-    }
-
-    @Test
-    public void testCalculateScore_succeedMatchMixedCases_last4() {
-        final Bundle last4 = last4Bundle();
-        assertFloat(calculateScore(AutofillValue.forText("TEST"), "1234 test", last4), 1);
-        assertFloat(calculateScore(AutofillValue.forText("test"), "1234 TEST", last4), 1);
-    }
-
-    @Test
-    public void testCalculateScore_mismatchDifferentSizes_last4() {
-        final Bundle last4 = last4Bundle();
-        assertFloat(calculateScore(AutofillValue.forText("TEST"), "TEST1", last4), 0);
-        assertFloat(calculateScore(AutofillValue.forText(""), "TEST", last4), 0);
-        assertFloat(calculateScore(AutofillValue.forText("TEST"), "", last4), 0);
-    }
-
-    @Test
-    public void testCalculateScore_match() {
-        final Bundle last4 = last4Bundle();
-        assertFloat(calculateScore(AutofillValue.forText("1234 1234 1234 1234"),
-                "xxxx xxxx xxxx 1234", last4), 1);
-        assertFloat(calculateScore(AutofillValue.forText("TEST"), "TEST", null), 1);
-        assertFloat(calculateScore(AutofillValue.forText("TEST 1234"), "1234", last4), 1);
-        assertFloat(calculateScore(AutofillValue.forText("TEST"), "test", null), 1);
-    }
-
-    @Test
-    public void testCalculateScore_badBundle() {
-        final Bundle bundle = new Bundle();
-        bundle.putInt("suffix", -2);
-        assertThrows(IllegalArgumentException.class, () -> calculateScore(
-                AutofillValue.forText("TEST"), "TEST", bundle));
-
-        final Bundle largeBundle = new Bundle();
-        largeBundle.putInt("suffix", 10);
-        assertFloat(calculateScore(AutofillValue.forText("TEST"), "TEST", largeBundle), 1);
-
-        final Bundle stringBundle = new Bundle();
-        stringBundle.putString("suffix", "value");
-        assertThrows(IllegalArgumentException.class, () -> calculateScore(
-                AutofillValue.forText("TEST"), "TEST", stringBundle));
-
-    }
-
-    public static void assertFloat(float actualValue, float expectedValue) {
-        assertThat(actualValue).isWithin(0.01F).of(expectedValue);
-    }
-}
diff --git a/packages/ExtServices/tests/src/android/ext/services/notification/AgingHelperTest.java b/packages/ExtServices/tests/src/android/ext/services/notification/AgingHelperTest.java
deleted file mode 100644
index a87d57c..0000000
--- a/packages/ExtServices/tests/src/android/ext/services/notification/AgingHelperTest.java
+++ /dev/null
@@ -1,160 +0,0 @@
-/**
- * Copyright (C) 2018 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.ext.services.notification;
-
-import static android.app.NotificationManager.IMPORTANCE_HIGH;
-import static android.app.NotificationManager.IMPORTANCE_MIN;
-
-import static org.mockito.ArgumentMatchers.any;
-import static org.mockito.ArgumentMatchers.anyInt;
-import static org.mockito.ArgumentMatchers.anyLong;
-import static org.mockito.ArgumentMatchers.anyString;
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.never;
-import static org.mockito.Mockito.times;
-import static org.mockito.Mockito.verify;
-import static org.mockito.Mockito.when;
-
-import android.app.AlarmManager;
-import android.app.Notification;
-import android.app.NotificationChannel;
-import android.app.PendingIntent;
-import android.content.pm.ApplicationInfo;
-import android.content.pm.IPackageManager;
-import android.os.Build;
-import android.os.Process;
-import android.os.UserHandle;
-import android.service.notification.StatusBarNotification;
-import android.testing.TestableContext;
-
-import androidx.test.InstrumentationRegistry;
-import androidx.test.runner.AndroidJUnit4;
-
-import org.junit.Before;
-import org.junit.Rule;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.mockito.Mock;
-import org.mockito.MockitoAnnotations;
-
-@RunWith(AndroidJUnit4.class)
-public class AgingHelperTest {
-    private String mPkg = "pkg";
-    private int mUid = 2018;
-
-    @Rule
-    public final TestableContext mContext =
-            new TestableContext(InstrumentationRegistry.getTargetContext(), null);
-
-    @Mock
-    private NotificationCategorizer mCategorizer;
-    @Mock
-    private AlarmManager mAlarmManager;
-    @Mock
-    private IPackageManager mPackageManager;
-    @Mock
-    private AgingHelper.Callback mCallback;
-    @Mock
-    private SmsHelper mSmsHelper;
-
-    private AgingHelper mAgingHelper;
-
-    private StatusBarNotification generateSbn(String channelId) {
-        Notification n = new Notification.Builder(mContext, channelId)
-                .setContentTitle("foo")
-                .build();
-
-        return new StatusBarNotification(mPkg, mPkg, 0, "tag", mUid, mUid, n,
-                UserHandle.SYSTEM, null, 0);
-    }
-
-    @Before
-    public void setUp() throws Exception {
-        MockitoAnnotations.initMocks(this);
-        mPkg = mContext.getPackageName();
-        mUid = Process.myUid();
-
-        ApplicationInfo info = mock(ApplicationInfo.class);
-        when(mPackageManager.getApplicationInfo(anyString(), anyInt(), anyInt()))
-                .thenReturn(info);
-        info.targetSdkVersion = Build.VERSION_CODES.P;
-
-        mContext.addMockSystemService(AlarmManager.class, mAlarmManager);
-
-        mAgingHelper = new AgingHelper(mContext, mCategorizer, mCallback);
-    }
-
-    @Test
-    public void testNoSnoozingOnPost() {
-        NotificationChannel channel = new NotificationChannel("", "", IMPORTANCE_HIGH);
-        StatusBarNotification sbn = generateSbn(channel.getId());
-        NotificationEntry entry = new NotificationEntry(
-                mContext, mPackageManager, sbn, channel, mSmsHelper);
-
-
-        mAgingHelper.onNotificationPosted(entry);
-        verify(mAlarmManager, never()).setExactAndAllowWhileIdle(anyInt(), anyLong(), any());
-    }
-
-    @Test
-    public void testPostResetsSnooze() {
-        NotificationChannel channel = new NotificationChannel("", "", IMPORTANCE_HIGH);
-        StatusBarNotification sbn = generateSbn(channel.getId());
-        NotificationEntry entry = new NotificationEntry(
-                mContext, mPackageManager, sbn, channel, mSmsHelper);
-
-
-        mAgingHelper.onNotificationPosted(entry);
-        verify(mAlarmManager, times(1)).cancel(any(PendingIntent.class));
-    }
-
-    @Test
-    public void testSnoozingOnSeen() {
-        NotificationChannel channel = new NotificationChannel("", "", IMPORTANCE_HIGH);
-        StatusBarNotification sbn = generateSbn(channel.getId());
-        NotificationEntry entry = new NotificationEntry(
-                mContext, mPackageManager, sbn, channel, mSmsHelper);
-        entry.setSeen();
-        when(mCategorizer.getCategory(entry)).thenReturn(NotificationCategorizer.CATEGORY_PEOPLE);
-
-        mAgingHelper.onNotificationSeen(entry);
-        verify(mAlarmManager, times(1)).setExactAndAllowWhileIdle(anyInt(), anyLong(), any());
-    }
-
-    @Test
-    public void testNoSnoozingOnSeenUserLocked() {
-        NotificationChannel channel = new NotificationChannel("", "", IMPORTANCE_HIGH);
-        channel.lockFields(NotificationChannel.USER_LOCKED_IMPORTANCE);
-        StatusBarNotification sbn = generateSbn(channel.getId());
-        NotificationEntry entry = new NotificationEntry(
-                mContext, mPackageManager, sbn, channel, mSmsHelper);
-        when(mCategorizer.getCategory(entry)).thenReturn(NotificationCategorizer.CATEGORY_PEOPLE);
-
-        mAgingHelper.onNotificationSeen(entry);
-        verify(mAlarmManager, never()).setExactAndAllowWhileIdle(anyInt(), anyLong(), any());
-    }
-
-    @Test
-    public void testNoSnoozingOnSeenAlreadyLow() {
-        NotificationEntry entry = mock(NotificationEntry.class);
-        when(entry.getChannel()).thenReturn(new NotificationChannel("", "", IMPORTANCE_HIGH));
-        when(entry.getImportance()).thenReturn(IMPORTANCE_MIN);
-
-        mAgingHelper.onNotificationSeen(entry);
-        verify(mAlarmManager, never()).setExactAndAllowWhileIdle(anyInt(), anyLong(), any());
-    }
-}
diff --git a/packages/ExtServices/tests/src/android/ext/services/notification/AssistantSettingsTest.java b/packages/ExtServices/tests/src/android/ext/services/notification/AssistantSettingsTest.java
deleted file mode 100644
index 5c877de..0000000
--- a/packages/ExtServices/tests/src/android/ext/services/notification/AssistantSettingsTest.java
+++ /dev/null
@@ -1,263 +0,0 @@
-/**
- * Copyright (C) 2018 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.ext.services.notification;
-
-import static android.ext.services.notification.AssistantSettings.DEFAULT_MAX_SUGGESTIONS;
-import static android.provider.DeviceConfig.setProperty;
-
-import static com.android.compatibility.common.util.SystemUtil.runWithShellPermissionIdentity;
-
-import static junit.framework.Assert.assertFalse;
-import static junit.framework.Assert.assertTrue;
-
-import static org.junit.Assert.assertEquals;
-import static org.mockito.Mockito.never;
-import static org.mockito.Mockito.verify;
-
-import android.content.ContentResolver;
-import android.os.Handler;
-import android.os.Looper;
-import android.provider.DeviceConfig;
-import android.provider.Settings;
-import android.support.test.uiautomator.UiDevice;
-import android.testing.TestableContext;
-
-import androidx.test.InstrumentationRegistry;
-import androidx.test.runner.AndroidJUnit4;
-
-import com.android.internal.config.sysui.SystemUiDeviceConfigFlags;
-
-import org.junit.After;
-import org.junit.Before;
-import org.junit.Rule;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.mockito.Mock;
-import org.mockito.MockitoAnnotations;
-
-import java.io.IOException;
-
-@RunWith(AndroidJUnit4.class)
-public class AssistantSettingsTest {
-    private static final String CLEAR_DEVICE_CONFIG_KEY_CMD =
-            "device_config delete " + DeviceConfig.NAMESPACE_SYSTEMUI;
-
-    private static final int USER_ID = 5;
-
-    @Rule
-    public final TestableContext mContext =
-            new TestableContext(InstrumentationRegistry.getContext(), null);
-
-    @Mock Runnable mOnUpdateRunnable;
-
-    private ContentResolver mResolver;
-    private AssistantSettings mAssistantSettings;
-
-    @Before
-    public void setUp() {
-        MockitoAnnotations.initMocks(this);
-
-        mResolver = mContext.getContentResolver();
-        Handler handler = new Handler(Looper.getMainLooper());
-
-        // To bypass real calls to global settings values, set the Settings values here.
-        Settings.Global.putFloat(mResolver,
-                Settings.Global.BLOCKING_HELPER_DISMISS_TO_VIEW_RATIO_LIMIT, 0.8f);
-        Settings.Global.putInt(mResolver, Settings.Global.BLOCKING_HELPER_STREAK_LIMIT, 2);
-        Settings.Secure.putInt(mResolver, Settings.Secure.NOTIFICATION_NEW_INTERRUPTION_MODEL, 1);
-
-        mAssistantSettings = AssistantSettings.createForTesting(
-                handler, mResolver, USER_ID, mOnUpdateRunnable);
-    }
-
-    @After
-    public void tearDown() throws IOException {
-        clearDeviceConfig();
-    }
-
-    @Test
-    public void testGenerateRepliesDisabled() {
-        runWithShellPermissionIdentity(() -> setProperty(
-                DeviceConfig.NAMESPACE_SYSTEMUI,
-                SystemUiDeviceConfigFlags.NAS_GENERATE_REPLIES,
-                "false",
-                false /* makeDefault */));
-        mAssistantSettings.onDeviceConfigPropertiesChanged(DeviceConfig.NAMESPACE_SYSTEMUI);
-
-        assertFalse(mAssistantSettings.mGenerateReplies);
-    }
-
-    @Test
-    public void testGenerateRepliesEnabled() {
-        runWithShellPermissionIdentity(() -> setProperty(
-                DeviceConfig.NAMESPACE_SYSTEMUI,
-                SystemUiDeviceConfigFlags.NAS_GENERATE_REPLIES,
-                "true",
-                false /* makeDefault */));
-        mAssistantSettings.onDeviceConfigPropertiesChanged(DeviceConfig.NAMESPACE_SYSTEMUI);
-
-        assertTrue(mAssistantSettings.mGenerateReplies);
-    }
-
-    @Test
-    public void testGenerateRepliesNullFlag() {
-        runWithShellPermissionIdentity(() -> setProperty(
-                DeviceConfig.NAMESPACE_SYSTEMUI,
-                SystemUiDeviceConfigFlags.NAS_GENERATE_REPLIES,
-                "false",
-                false /* makeDefault */));
-        mAssistantSettings.onDeviceConfigPropertiesChanged(DeviceConfig.NAMESPACE_SYSTEMUI);
-
-        assertFalse(mAssistantSettings.mGenerateReplies);
-
-        runWithShellPermissionIdentity(() -> setProperty(
-                DeviceConfig.NAMESPACE_SYSTEMUI,
-                SystemUiDeviceConfigFlags.NAS_GENERATE_REPLIES,
-                null,
-                false /* makeDefault */));
-        mAssistantSettings.onDeviceConfigPropertiesChanged(DeviceConfig.NAMESPACE_SYSTEMUI);
-
-        // Go back to the default value.
-        assertTrue(mAssistantSettings.mGenerateReplies);
-    }
-
-    @Test
-    public void testGenerateActionsDisabled() {
-        runWithShellPermissionIdentity(() -> setProperty(
-                DeviceConfig.NAMESPACE_SYSTEMUI,
-                SystemUiDeviceConfigFlags.NAS_GENERATE_ACTIONS,
-                "false",
-                false /* makeDefault */));
-        mAssistantSettings.onDeviceConfigPropertiesChanged(DeviceConfig.NAMESPACE_SYSTEMUI);
-
-        assertFalse(mAssistantSettings.mGenerateActions);
-    }
-
-    @Test
-    public void testGenerateActionsEnabled() {
-        runWithShellPermissionIdentity(() -> setProperty(
-                DeviceConfig.NAMESPACE_SYSTEMUI,
-                SystemUiDeviceConfigFlags.NAS_GENERATE_ACTIONS,
-                "true",
-                false /* makeDefault */));
-        mAssistantSettings.onDeviceConfigPropertiesChanged(DeviceConfig.NAMESPACE_SYSTEMUI);
-
-        assertTrue(mAssistantSettings.mGenerateActions);
-    }
-
-    @Test
-    public void testGenerateActionsNullFlag() {
-        runWithShellPermissionIdentity(() -> setProperty(
-                DeviceConfig.NAMESPACE_SYSTEMUI,
-                SystemUiDeviceConfigFlags.NAS_GENERATE_ACTIONS,
-                "false",
-                false /* makeDefault */));
-        mAssistantSettings.onDeviceConfigPropertiesChanged(DeviceConfig.NAMESPACE_SYSTEMUI);
-
-        assertFalse(mAssistantSettings.mGenerateActions);
-
-        runWithShellPermissionIdentity(() -> setProperty(
-                DeviceConfig.NAMESPACE_SYSTEMUI,
-                SystemUiDeviceConfigFlags.NAS_GENERATE_ACTIONS,
-                null,
-                false /* makeDefault */));
-        mAssistantSettings.onDeviceConfigPropertiesChanged(DeviceConfig.NAMESPACE_SYSTEMUI);
-
-        // Go back to the default value.
-        assertTrue(mAssistantSettings.mGenerateActions);
-    }
-
-    @Test
-    public void testMaxMessagesToExtract() {
-        runWithShellPermissionIdentity(() -> setProperty(
-                DeviceConfig.NAMESPACE_SYSTEMUI,
-                SystemUiDeviceConfigFlags.NAS_MAX_MESSAGES_TO_EXTRACT,
-                "10",
-                false /* makeDefault */));
-        mAssistantSettings.onDeviceConfigPropertiesChanged(DeviceConfig.NAMESPACE_SYSTEMUI);
-
-        assertEquals(10, mAssistantSettings.mMaxMessagesToExtract);
-    }
-
-    @Test
-    public void testMaxSuggestions() {
-        runWithShellPermissionIdentity(() -> setProperty(
-                DeviceConfig.NAMESPACE_SYSTEMUI,
-                SystemUiDeviceConfigFlags.NAS_MAX_SUGGESTIONS,
-                "5",
-                false /* makeDefault */));
-        mAssistantSettings.onDeviceConfigPropertiesChanged(DeviceConfig.NAMESPACE_SYSTEMUI);
-
-        assertEquals(5, mAssistantSettings.mMaxSuggestions);
-    }
-
-    @Test
-    public void testMaxSuggestionsEmpty() {
-        mAssistantSettings.onDeviceConfigPropertiesChanged(DeviceConfig.NAMESPACE_SYSTEMUI);
-
-        assertEquals(DEFAULT_MAX_SUGGESTIONS, mAssistantSettings.mMaxSuggestions);
-    }
-
-    @Test
-    public void testStreakLimit() {
-        verify(mOnUpdateRunnable, never()).run();
-
-        // Update settings value.
-        int newStreakLimit = 4;
-        Settings.Global.putInt(mResolver,
-                Settings.Global.BLOCKING_HELPER_STREAK_LIMIT, newStreakLimit);
-
-        // Notify for the settings value we updated.
-        mAssistantSettings.onChange(false, Settings.Global.getUriFor(
-                Settings.Global.BLOCKING_HELPER_STREAK_LIMIT));
-
-        assertEquals(newStreakLimit, mAssistantSettings.mStreakLimit);
-        verify(mOnUpdateRunnable).run();
-    }
-
-    @Test
-    public void testDismissToViewRatioLimit() {
-        verify(mOnUpdateRunnable, never()).run();
-
-        // Update settings value.
-        float newDismissToViewRatioLimit = 3f;
-        Settings.Global.putFloat(mResolver,
-                Settings.Global.BLOCKING_HELPER_DISMISS_TO_VIEW_RATIO_LIMIT,
-                newDismissToViewRatioLimit);
-
-        // Notify for the settings value we updated.
-        mAssistantSettings.onChange(false, Settings.Global.getUriFor(
-                Settings.Global.BLOCKING_HELPER_DISMISS_TO_VIEW_RATIO_LIMIT));
-
-        assertEquals(newDismissToViewRatioLimit, mAssistantSettings.mDismissToViewRatioLimit, 1e-6);
-        verify(mOnUpdateRunnable).run();
-    }
-
-    private static void clearDeviceConfig() throws IOException {
-        UiDevice uiDevice = UiDevice.getInstance(InstrumentationRegistry.getInstrumentation());
-        uiDevice.executeShellCommand(
-                CLEAR_DEVICE_CONFIG_KEY_CMD + " " + SystemUiDeviceConfigFlags.NAS_GENERATE_ACTIONS);
-        uiDevice.executeShellCommand(
-                CLEAR_DEVICE_CONFIG_KEY_CMD + " " + SystemUiDeviceConfigFlags.NAS_GENERATE_REPLIES);
-        uiDevice.executeShellCommand(
-                CLEAR_DEVICE_CONFIG_KEY_CMD + " "
-                + SystemUiDeviceConfigFlags.NAS_MAX_MESSAGES_TO_EXTRACT);
-        uiDevice.executeShellCommand(
-                CLEAR_DEVICE_CONFIG_KEY_CMD + " " + SystemUiDeviceConfigFlags.NAS_MAX_SUGGESTIONS);
-    }
-
-}
diff --git a/packages/ExtServices/tests/src/android/ext/services/notification/AssistantTest.java b/packages/ExtServices/tests/src/android/ext/services/notification/AssistantTest.java
deleted file mode 100644
index 012dcc0..0000000
--- a/packages/ExtServices/tests/src/android/ext/services/notification/AssistantTest.java
+++ /dev/null
@@ -1,477 +0,0 @@
-/**
- * Copyright (C) 2017 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.ext.services.notification;
-
-import static android.app.NotificationManager.IMPORTANCE_DEFAULT;
-import static android.app.NotificationManager.IMPORTANCE_LOW;
-import static android.app.NotificationManager.IMPORTANCE_MIN;
-
-import static org.mockito.ArgumentMatchers.any;
-import static org.mockito.ArgumentMatchers.anyInt;
-import static org.mockito.ArgumentMatchers.anyString;
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.never;
-import static org.mockito.Mockito.times;
-import static org.mockito.Mockito.verify;
-import static org.mockito.Mockito.when;
-
-import android.app.Application;
-import android.app.INotificationManager;
-import android.app.Notification;
-import android.app.NotificationChannel;
-import android.content.Intent;
-import android.content.pm.ApplicationInfo;
-import android.content.pm.IPackageManager;
-import android.os.Build;
-import android.os.UserHandle;
-import android.service.notification.Adjustment;
-import android.service.notification.NotificationListenerService;
-import android.service.notification.NotificationListenerService.Ranking;
-import android.service.notification.NotificationListenerService.RankingMap;
-import android.service.notification.NotificationStats;
-import android.service.notification.StatusBarNotification;
-import android.test.ServiceTestCase;
-import android.testing.TestableContext;
-import android.util.AtomicFile;
-
-import androidx.test.InstrumentationRegistry;
-
-import com.android.internal.util.FastXmlSerializer;
-
-import org.junit.Before;
-import org.junit.Rule;
-import org.junit.Test;
-import org.mockito.ArgumentCaptor;
-import org.mockito.Mock;
-import org.mockito.MockitoAnnotations;
-import org.xmlpull.v1.XmlSerializer;
-
-import java.io.BufferedInputStream;
-import java.io.BufferedOutputStream;
-import java.io.ByteArrayInputStream;
-import java.io.ByteArrayOutputStream;
-import java.io.FileOutputStream;
-import java.util.ArrayList;
-
-public class AssistantTest extends ServiceTestCase<Assistant> {
-
-    private static final String PKG1 = "pkg1";
-    private static final int UID1 = 1;
-    private static final NotificationChannel P1C1 =
-            new NotificationChannel("one", "", IMPORTANCE_LOW);
-    private static final NotificationChannel P1C2 =
-            new NotificationChannel("p1c2", "", IMPORTANCE_DEFAULT);
-    private static final NotificationChannel P1C3 =
-            new NotificationChannel("p1c3", "", IMPORTANCE_MIN);
-    private static final String PKG2 = "pkg2";
-
-    private static final int UID2 = 2;
-    private static final NotificationChannel P2C1 =
-            new NotificationChannel("one", "", IMPORTANCE_LOW);
-
-    @Mock INotificationManager mNoMan;
-    @Mock AtomicFile mFile;
-    @Mock IPackageManager mPackageManager;
-    @Mock SmsHelper mSmsHelper;
-
-    Assistant mAssistant;
-    Application mApplication;
-
-    @Rule
-    public final TestableContext mContext =
-            new TestableContext(InstrumentationRegistry.getContext(), null);
-
-    public AssistantTest() {
-        super(Assistant.class);
-    }
-
-    @Before
-    public void setUp() throws Exception {
-        MockitoAnnotations.initMocks(this);
-
-        Intent startIntent =
-                new Intent("android.service.notification.NotificationAssistantService");
-        startIntent.setPackage("android.ext.services");
-
-        mApplication = (Application) InstrumentationRegistry.getInstrumentation().
-                getTargetContext().getApplicationContext();
-        // Force the test to use the correct application instead of trying to use a mock application
-        setApplication(mApplication);
-
-        setupService();
-        mAssistant = getService();
-
-        // Override the AssistantSettings factory.
-        mAssistant.mSettingsFactory = AssistantSettings::createForTesting;
-
-        bindService(startIntent);
-
-        mAssistant.mSettings.mDismissToViewRatioLimit = 0.8f;
-        mAssistant.mSettings.mStreakLimit = 2;
-        mAssistant.mSettings.mNewInterruptionModel = true;
-        mAssistant.setNoMan(mNoMan);
-        mAssistant.setFile(mFile);
-        mAssistant.setPackageManager(mPackageManager);
-
-        ApplicationInfo info = mock(ApplicationInfo.class);
-        when(mPackageManager.getApplicationInfo(anyString(), anyInt(), anyInt()))
-                .thenReturn(info);
-        info.targetSdkVersion = Build.VERSION_CODES.P;
-        when(mFile.startWrite()).thenReturn(mock(FileOutputStream.class));
-    }
-
-    private StatusBarNotification generateSbn(String pkg, int uid, NotificationChannel channel,
-            String tag, String groupKey) {
-        Notification n = new Notification.Builder(mContext, channel.getId())
-                .setContentTitle("foo")
-                .setGroup(groupKey)
-                .build();
-
-        StatusBarNotification sbn = new StatusBarNotification(pkg, pkg, 0, tag, uid, uid, n,
-                UserHandle.SYSTEM, null, 0);
-
-        return sbn;
-    }
-
-    private Ranking generateRanking(StatusBarNotification sbn, NotificationChannel channel) {
-        Ranking mockRanking = mock(Ranking.class);
-        when(mockRanking.getChannel()).thenReturn(channel);
-        when(mockRanking.getImportance()).thenReturn(channel.getImportance());
-        when(mockRanking.getKey()).thenReturn(sbn.getKey());
-        when(mockRanking.getOverrideGroupKey()).thenReturn(null);
-        return mockRanking;
-    }
-
-    private void almostBlockChannel(String pkg, int uid, NotificationChannel channel) {
-        for (int i = 0; i < ChannelImpressions.DEFAULT_STREAK_LIMIT; i++) {
-            dismissBadNotification(pkg, uid, channel, String.valueOf(i));
-        }
-    }
-
-    private void dismissBadNotification(String pkg, int uid, NotificationChannel channel,
-            String tag) {
-        StatusBarNotification sbn = generateSbn(pkg, uid, channel, tag, null);
-        mAssistant.setFakeRanking(generateRanking(sbn, channel));
-        mAssistant.onNotificationPosted(sbn, mock(RankingMap.class));
-        mAssistant.setFakeRanking(mock(Ranking.class));
-        NotificationStats stats = new NotificationStats();
-        stats.setDismissalSurface(NotificationStats.DISMISSAL_SHADE);
-        stats.setSeen();
-        mAssistant.onNotificationRemoved(
-                sbn, mock(RankingMap.class), stats, NotificationListenerService.REASON_CANCEL);
-    }
-
-    @Test
-    public void testNoAdjustmentForInitialPost() throws Exception {
-        StatusBarNotification sbn = generateSbn(PKG1, UID1, P1C1, null, null);
-
-        mAssistant.setFakeRanking(generateRanking(sbn, P1C1));
-        mAssistant.onNotificationPosted(sbn, mock(RankingMap.class));
-
-        verify(mNoMan, never()).applyEnqueuedAdjustmentFromAssistant(any(), any());
-    }
-
-    @Test
-    public void testTriggerAdjustment() throws Exception {
-        almostBlockChannel(PKG1, UID1, P1C1);
-        dismissBadNotification(PKG1, UID1, P1C1, "trigger!");
-
-        StatusBarNotification sbn = generateSbn(PKG1, UID1, P1C1, "new one!", null);
-        mAssistant.setFakeRanking(generateRanking(sbn, P1C1));
-        mAssistant.onNotificationPosted(sbn, mock(RankingMap.class));
-
-        ArgumentCaptor<Adjustment> captor = ArgumentCaptor.forClass(Adjustment.class);
-        verify(mNoMan, times(1)).applyEnqueuedAdjustmentFromAssistant(any(), captor.capture());
-        assertEquals(sbn.getKey(), captor.getValue().getKey());
-        assertEquals(Ranking.USER_SENTIMENT_NEGATIVE,
-                captor.getValue().getSignals().getInt(Adjustment.KEY_USER_SENTIMENT));
-    }
-
-    @Test
-    public void testMinCannotTriggerAdjustment() throws Exception {
-        almostBlockChannel(PKG1, UID1, P1C3);
-        dismissBadNotification(PKG1, UID1, P1C3, "trigger!");
-
-        StatusBarNotification sbn = generateSbn(PKG1, UID1, P1C3, "new one!", null);
-        mAssistant.setFakeRanking(generateRanking(sbn, P1C3));
-        mAssistant.onNotificationPosted(sbn, mock(RankingMap.class));
-
-        verify(mNoMan, never()).applyEnqueuedAdjustmentFromAssistant(any(), any());
-    }
-
-    @Test
-    public void testGroupChildCanTriggerAdjustment() throws Exception {
-        almostBlockChannel(PKG1, UID1, P1C1);
-
-        StatusBarNotification sbn = generateSbn(PKG1, UID1, P1C1, "no", "I HAVE A GROUP");
-        mAssistant.setFakeRanking(generateRanking(sbn, P1C1));
-        NotificationStats stats = new NotificationStats();
-        stats.setDismissalSurface(NotificationStats.DISMISSAL_SHADE);
-        stats.setSeen();
-        mAssistant.onNotificationPosted(sbn, mock(RankingMap.class));
-        mAssistant.onNotificationRemoved(
-                sbn, mock(RankingMap.class), stats, NotificationListenerService.REASON_CANCEL);
-
-        sbn = generateSbn(PKG1, UID1, P1C1, "new one!", "group");
-        mAssistant.onNotificationPosted(sbn, mock(RankingMap.class));
-
-        ArgumentCaptor<Adjustment> captor = ArgumentCaptor.forClass(Adjustment.class);
-        verify(mNoMan, times(1)).applyEnqueuedAdjustmentFromAssistant(any(), captor.capture());
-        assertEquals(sbn.getKey(), captor.getValue().getKey());
-        assertEquals(Ranking.USER_SENTIMENT_NEGATIVE,
-                captor.getValue().getSignals().getInt(Adjustment.KEY_USER_SENTIMENT));
-    }
-
-    @Test
-    public void testGroupSummaryCannotTriggerAdjustment() throws Exception {
-        almostBlockChannel(PKG1, UID1, P1C1);
-
-        StatusBarNotification sbn = generateSbn(PKG1, UID1, P1C1, "no", "I HAVE A GROUP");
-        sbn.getNotification().flags |= Notification.FLAG_GROUP_SUMMARY;
-        mAssistant.setFakeRanking(generateRanking(sbn, P1C1));
-        NotificationStats stats = new NotificationStats();
-        stats.setDismissalSurface(NotificationStats.DISMISSAL_SHADE);
-        stats.setSeen();
-        mAssistant.onNotificationPosted(sbn, mock(RankingMap.class));
-        mAssistant.onNotificationRemoved(
-                sbn, mock(RankingMap.class), stats, NotificationListenerService.REASON_CANCEL);
-
-        sbn = generateSbn(PKG1, UID1, P1C1, "new one!", "group");
-        mAssistant.onNotificationPosted(sbn, mock(RankingMap.class));
-
-        verify(mNoMan, never()).applyEnqueuedAdjustmentFromAssistant(any(), any());
-    }
-
-    @Test
-    public void testAodCannotTriggerAdjustment() throws Exception {
-        almostBlockChannel(PKG1, UID1, P1C1);
-
-        StatusBarNotification sbn = generateSbn(PKG1, UID1, P1C1, "no", null);
-        mAssistant.setFakeRanking(generateRanking(sbn, P1C1));
-        NotificationStats stats = new NotificationStats();
-        stats.setDismissalSurface(NotificationStats.DISMISSAL_AOD);
-        stats.setSeen();
-        mAssistant.onNotificationPosted(sbn, mock(RankingMap.class));
-        mAssistant.onNotificationRemoved(
-                sbn, mock(RankingMap.class), stats, NotificationListenerService.REASON_CANCEL);
-
-        sbn = generateSbn(PKG1, UID1, P1C1, "new one!", null);
-        mAssistant.onNotificationPosted(sbn, mock(RankingMap.class));
-
-        verify(mNoMan, never()).applyEnqueuedAdjustmentFromAssistant(any(), any());
-    }
-
-    @Test
-    public void testInteractedCannotTriggerAdjustment() throws Exception {
-        almostBlockChannel(PKG1, UID1, P1C1);
-        StatusBarNotification sbn = generateSbn(PKG1, UID1, P1C1, "no", null);
-        mAssistant.setFakeRanking(generateRanking(sbn, P1C1));
-        NotificationStats stats = new NotificationStats();
-        stats.setDismissalSurface(NotificationStats.DISMISSAL_SHADE);
-        stats.setSeen();
-        stats.setExpanded();
-        mAssistant.onNotificationPosted(sbn, mock(RankingMap.class));
-        mAssistant.onNotificationRemoved(
-                sbn, mock(RankingMap.class), stats, NotificationListenerService.REASON_CANCEL);
-
-        sbn = generateSbn(PKG1, UID1, P1C1, "new one!", null);
-        mAssistant.onNotificationPosted(sbn, mock(RankingMap.class));
-
-        verify(mNoMan, never()).applyEnqueuedAdjustmentFromAssistant(any(), any());
-    }
-
-    @Test
-    public void testAppDismissedCannotTriggerAdjustment() throws Exception {
-        almostBlockChannel(PKG1, UID1, P1C1);
-
-        StatusBarNotification sbn = generateSbn(PKG1, UID1, P1C1, "no", null);
-        mAssistant.setFakeRanking(generateRanking(sbn, P1C1));
-        NotificationStats stats = new NotificationStats();
-        stats.setDismissalSurface(NotificationStats.DISMISSAL_SHADE);
-        stats.setSeen();
-        mAssistant.onNotificationPosted(sbn, mock(RankingMap.class));
-        mAssistant.onNotificationRemoved(
-                sbn, mock(RankingMap.class), stats, NotificationListenerService.REASON_APP_CANCEL);
-
-        sbn = generateSbn(PKG1, UID1, P1C1, "new one!", null);
-        mAssistant.onNotificationPosted(sbn, mock(RankingMap.class));
-
-        verify(mNoMan, never()).applyEnqueuedAdjustmentFromAssistant(any(), any());
-    }
-
-    @Test
-    public void testAppSeparation() throws Exception {
-        almostBlockChannel(PKG1, UID1, P1C1);
-        dismissBadNotification(PKG1, UID1, P1C1, "trigger!");
-
-        StatusBarNotification sbn = generateSbn(PKG2, UID2, P2C1, "new app!", null);
-        mAssistant.setFakeRanking(generateRanking(sbn, P2C1));
-        mAssistant.onNotificationPosted(sbn, mock(RankingMap.class));
-
-        verify(mNoMan, never()).applyEnqueuedAdjustmentFromAssistant(any(), any());
-    }
-
-    @Test
-    public void testChannelSeparation() throws Exception {
-        almostBlockChannel(PKG1, UID1, P1C1);
-        dismissBadNotification(PKG1, UID1, P1C1, "trigger!");
-
-        StatusBarNotification sbn = generateSbn(PKG1, UID1, P1C2, "new app!", null);
-        mAssistant.setFakeRanking(generateRanking(sbn, P1C2));
-        mAssistant.onNotificationPosted(sbn, mock(RankingMap.class));
-
-        verify(mNoMan, never()).applyEnqueuedAdjustmentFromAssistant(any(), any());
-    }
-
-    @Test
-    public void testReadXml() throws Exception {
-        String key1 = mAssistant.getKey("pkg1", 1, "channel1");
-        int streak1 = 2;
-        int views1 = 5;
-        int dismiss1 = 9;
-
-        int streak1a = 3;
-        int views1a = 10;
-        int dismiss1a = 99;
-        String key1a = mAssistant.getKey("pkg1", 1, "channel1a");
-
-        int streak2 = 7;
-        int views2 = 77;
-        int dismiss2 = 777;
-        String key2 = mAssistant.getKey("pkg2", 2, "channel2");
-
-        String xml = "<?xml version='1.0' encoding='utf-8' standalone='yes' ?>"
-                + "<assistant version=\"1\">\n"
-                + "<impression-set key=\"" + key1 + "\" "
-                + "dismisses=\"" + dismiss1 + "\" views=\"" + views1
-                + "\" streak=\"" + streak1 + "\"/>\n"
-                + "<impression-set key=\"" + key1a + "\" "
-                + "dismisses=\"" + dismiss1a + "\" views=\"" + views1a
-                + "\" streak=\"" + streak1a + "\"/>\n"
-                + "<impression-set key=\"" + key2 + "\" "
-                + "dismisses=\"" + dismiss2 + "\" views=\"" + views2
-                + "\" streak=\"" + streak2 + "\"/>\n"
-                + "</assistant>\n";
-        mAssistant.readXml(new BufferedInputStream(new ByteArrayInputStream(xml.getBytes())));
-
-        ChannelImpressions c1 = mAssistant.getImpressions(key1);
-        assertEquals(2, c1.getStreak());
-        assertEquals(5, c1.getViews());
-        assertEquals(9, c1.getDismissals());
-
-        ChannelImpressions c1a = mAssistant.getImpressions(key1a);
-        assertEquals(3, c1a.getStreak());
-        assertEquals(10, c1a.getViews());
-        assertEquals(99, c1a.getDismissals());
-
-        ChannelImpressions c2 = mAssistant.getImpressions(key2);
-        assertEquals(7, c2.getStreak());
-        assertEquals(77, c2.getViews());
-        assertEquals(777, c2.getDismissals());
-    }
-
-    @Test
-    public void testRoundTripXml() throws Exception {
-        String key1 = mAssistant.getKey("pkg1", 1, "channel1");
-        ChannelImpressions ci1 = new ChannelImpressions();
-        String key2 = mAssistant.getKey("pkg1", 1, "channel2");
-        ChannelImpressions ci2 = new ChannelImpressions();
-        for (int i = 0; i < 3; i++) {
-            ci2.incrementViews();
-            ci2.incrementDismissals();
-        }
-        ChannelImpressions ci3 = new ChannelImpressions();
-        String key3 = mAssistant.getKey("pkg3", 3, "channel2");
-        for (int i = 0; i < 9; i++) {
-            ci3.incrementViews();
-            if (i % 3 == 0) {
-                ci3.incrementDismissals();
-            }
-        }
-
-        mAssistant.insertImpressions(key1, ci1);
-        mAssistant.insertImpressions(key2, ci2);
-        mAssistant.insertImpressions(key3, ci3);
-
-        XmlSerializer serializer = new FastXmlSerializer();
-        ByteArrayOutputStream baos = new ByteArrayOutputStream();
-        serializer.setOutput(new BufferedOutputStream(baos), "utf-8");
-        mAssistant.writeXml(serializer);
-
-        Assistant assistant = new Assistant();
-        // onCreate is not invoked, so settings won't be initialised, unless we do it here.
-        assistant.mSettings = mAssistant.mSettings;
-        assistant.readXml(new BufferedInputStream(new ByteArrayInputStream(baos.toByteArray())));
-
-        assertEquals(ci1, assistant.getImpressions(key1));
-        assertEquals(ci2, assistant.getImpressions(key2));
-        assertEquals(ci3, assistant.getImpressions(key3));
-    }
-
-    @Test
-    public void testSettingsProviderUpdate() {
-        // Set up channels
-        String key = mAssistant.getKey("pkg1", 1, "channel1");
-        ChannelImpressions ci = new ChannelImpressions();
-        for (int i = 0; i < 3; i++) {
-            ci.incrementViews();
-            if (i % 2 == 0) {
-                ci.incrementDismissals();
-            }
-        }
-
-        mAssistant.insertImpressions(key, ci);
-
-        // With default values, the blocking helper shouldn't be triggered.
-        assertEquals(false, ci.shouldTriggerBlock());
-
-        // Update settings values.
-        mAssistant.mSettings.mDismissToViewRatioLimit = 0f;
-        mAssistant.mSettings.mStreakLimit = 0;
-
-        // Notify for the settings values we updated.
-        mAssistant.mSettings.mOnUpdateRunnable.run();
-
-        // With the new threshold, the blocking helper should be triggered.
-        assertEquals(true, ci.shouldTriggerBlock());
-    }
-
-    @Test
-    public void testTrimLiveNotifications() {
-        StatusBarNotification sbn = generateSbn(PKG1, UID1, P1C1, "no", null);
-        mAssistant.setFakeRanking(generateRanking(sbn, P1C1));
-
-        mAssistant.onNotificationPosted(sbn, mock(RankingMap.class));
-
-        assertTrue(mAssistant.mLiveNotifications.containsKey(sbn.getKey()));
-
-        mAssistant.onNotificationRemoved(
-                sbn, mock(RankingMap.class), new NotificationStats(), 0);
-
-        assertFalse(mAssistant.mLiveNotifications.containsKey(sbn.getKey()));
-    }
-
-    @Test
-    public void testAssistantNeverIncreasesImportanceWhenSuggestingSilent() throws Exception {
-        StatusBarNotification sbn = generateSbn(PKG1, UID1, P1C3, "min notif!", null);
-        Adjustment adjust = mAssistant.createEnqueuedNotificationAdjustment(
-                new NotificationEntry(mContext, mPackageManager, sbn, P1C3, mSmsHelper),
-                new ArrayList<>(),
-                new ArrayList<>());
-        assertEquals(IMPORTANCE_MIN, adjust.getSignals().getInt(Adjustment.KEY_IMPORTANCE));
-    }
-}
diff --git a/packages/ExtServices/tests/src/android/ext/services/notification/ChannelImpressionsTest.java b/packages/ExtServices/tests/src/android/ext/services/notification/ChannelImpressionsTest.java
deleted file mode 100644
index 3253802..0000000
--- a/packages/ExtServices/tests/src/android/ext/services/notification/ChannelImpressionsTest.java
+++ /dev/null
@@ -1,161 +0,0 @@
-/**
- * Copyright (C) 2017 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.ext.services.notification;
-
-import static android.ext.services.notification.ChannelImpressions.DEFAULT_DISMISS_TO_VIEW_RATIO_LIMIT;
-import static android.ext.services.notification.ChannelImpressions.DEFAULT_STREAK_LIMIT;
-
-import static junit.framework.Assert.assertFalse;
-import static junit.framework.Assert.assertTrue;
-
-import static org.junit.Assert.assertEquals;
-
-import org.junit.Test;
-
-public class ChannelImpressionsTest {
-
-    @Test
-    public void testNoResultNoBlock() {
-        ChannelImpressions ci = new ChannelImpressions();
-        assertFalse(ci.shouldTriggerBlock());
-    }
-
-    @Test
-    public void testNoStreakNoBlock() {
-        ChannelImpressions ci = new ChannelImpressions();
-
-        for (int i = 0; i < DEFAULT_STREAK_LIMIT - 1; i++) {
-            ci.incrementViews();
-            ci.incrementDismissals();
-        }
-
-        assertFalse(ci.shouldTriggerBlock());
-    }
-
-    @Test
-    public void testNoStreakNoBlock_breakStreak() {
-        ChannelImpressions ci = new ChannelImpressions();
-
-        for (int i = 0; i < DEFAULT_STREAK_LIMIT; i++) {
-            ci.incrementViews();
-            ci.incrementDismissals();
-            if (i == DEFAULT_STREAK_LIMIT - 1) {
-                ci.resetStreak();
-            }
-        }
-
-        assertFalse(ci.shouldTriggerBlock());
-    }
-
-    @Test
-    public void testStreakBlock() {
-        ChannelImpressions ci = new ChannelImpressions();
-
-        for (int i = 0; i <= DEFAULT_STREAK_LIMIT; i++) {
-            ci.incrementViews();
-            ci.incrementDismissals();
-        }
-
-        assertTrue(ci.shouldTriggerBlock());
-    }
-
-    @Test
-    public void testRatio_NoBlockEvenWithStreak() {
-        ChannelImpressions ci = new ChannelImpressions();
-
-        for (int i = 0; i < DEFAULT_STREAK_LIMIT; i++) {
-            ci.incrementViews();
-            ci.incrementDismissals();
-            ci.incrementViews();
-        }
-
-        assertFalse(ci.shouldTriggerBlock());
-    }
-
-    @Test
-    public void testAppend() {
-        ChannelImpressions ci = new ChannelImpressions();
-        ci.incrementViews();
-        ci.incrementDismissals();
-
-        ChannelImpressions ci2 = new ChannelImpressions();
-        ci2.incrementViews();
-        ci2.incrementDismissals();
-        ci2.incrementViews();
-
-        ci.append(ci2);
-        assertEquals(3, ci.getViews());
-        assertEquals(2, ci.getDismissals());
-        assertEquals(2, ci.getStreak());
-
-        assertEquals(2, ci2.getViews());
-        assertEquals(1, ci2.getDismissals());
-        assertEquals(1, ci2.getStreak());
-
-        // no crash
-        ci.append(null);
-    }
-
-    @Test
-    public void testUpdateThresholds_streakLimitsCorrectlyApplied() {
-        int updatedStreakLimit = DEFAULT_STREAK_LIMIT + 3;
-        ChannelImpressions ci = new ChannelImpressions();
-        ci.updateThresholds(DEFAULT_DISMISS_TO_VIEW_RATIO_LIMIT, updatedStreakLimit);
-
-        for (int i = 0; i <= updatedStreakLimit; i++) {
-            ci.incrementViews();
-            ci.incrementDismissals();
-        }
-
-        ChannelImpressions ci2 = new ChannelImpressions();
-        ci2.updateThresholds(DEFAULT_DISMISS_TO_VIEW_RATIO_LIMIT, updatedStreakLimit);
-
-        for (int i = 0; i < updatedStreakLimit; i++) {
-            ci2.incrementViews();
-            ci2.incrementDismissals();
-        }
-
-        assertTrue(ci.shouldTriggerBlock());
-        assertFalse(ci2.shouldTriggerBlock());
-    }
-
-    @Test
-    public void testUpdateThresholds_ratioLimitsCorrectlyApplied() {
-        float updatedDismissRatio = .99f;
-        ChannelImpressions ci = new ChannelImpressions();
-        ci.updateThresholds(updatedDismissRatio, DEFAULT_STREAK_LIMIT);
-
-        // N views, N-1 dismissals, which doesn't satisfy the ratio = 1 criteria.
-        for (int i = 0; i <= DEFAULT_STREAK_LIMIT; i++) {
-            ci.incrementViews();
-            if (i != DEFAULT_STREAK_LIMIT) {
-                ci.incrementDismissals();
-            }
-        }
-
-        ChannelImpressions ci2 = new ChannelImpressions();
-        ci2.updateThresholds(updatedDismissRatio, DEFAULT_STREAK_LIMIT);
-
-        for (int i = 0; i <= DEFAULT_STREAK_LIMIT; i++) {
-            ci2.incrementViews();
-            ci2.incrementDismissals();
-        }
-
-        assertFalse(ci.shouldTriggerBlock());
-        assertTrue(ci2.shouldTriggerBlock());
-    }
-}
diff --git a/packages/ExtServices/tests/src/android/ext/services/notification/EntityTypeCounterTest.java b/packages/ExtServices/tests/src/android/ext/services/notification/EntityTypeCounterTest.java
deleted file mode 100644
index ada61d0..0000000
--- a/packages/ExtServices/tests/src/android/ext/services/notification/EntityTypeCounterTest.java
+++ /dev/null
@@ -1,59 +0,0 @@
-/**
- * Copyright (C) 2018 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package android.ext.services.notification;
-
-import static com.google.common.truth.Truth.assertThat;
-
-import android.view.textclassifier.TextClassifier;
-
-import androidx.test.runner.AndroidJUnit4;
-
-import org.junit.Before;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-
-@RunWith(AndroidJUnit4.class)
-public class EntityTypeCounterTest {
-    private EntityTypeCounter mCounter;
-
-    @Before
-    public void setup() {
-        mCounter = new EntityTypeCounter();
-    }
-
-    @Test
-    public void testIncrementAndGetCount() {
-        mCounter.increment(TextClassifier.TYPE_URL);
-        mCounter.increment(TextClassifier.TYPE_URL);
-        mCounter.increment(TextClassifier.TYPE_URL);
-
-        mCounter.increment(TextClassifier.TYPE_PHONE);
-        mCounter.increment(TextClassifier.TYPE_PHONE);
-
-        assertThat(mCounter.getCount(TextClassifier.TYPE_URL)).isEqualTo(3);
-        assertThat(mCounter.getCount(TextClassifier.TYPE_PHONE)).isEqualTo(2);
-        assertThat(mCounter.getCount(TextClassifier.TYPE_DATE_TIME)).isEqualTo(0);
-    }
-
-    @Test
-    public void testIncrementAndGetCount_typeDateAndDateTime() {
-        mCounter.increment(TextClassifier.TYPE_DATE_TIME);
-        mCounter.increment(TextClassifier.TYPE_DATE);
-
-        assertThat(mCounter.getCount(TextClassifier.TYPE_DATE_TIME)).isEqualTo(2);
-        assertThat(mCounter.getCount(TextClassifier.TYPE_DATE)).isEqualTo(2);
-    }
-}
diff --git a/packages/ExtServices/tests/src/android/ext/services/notification/NotificationCategorizerTest.java b/packages/ExtServices/tests/src/android/ext/services/notification/NotificationCategorizerTest.java
deleted file mode 100644
index ea77d31..0000000
--- a/packages/ExtServices/tests/src/android/ext/services/notification/NotificationCategorizerTest.java
+++ /dev/null
@@ -1,202 +0,0 @@
-/**
- * Copyright (C) 2018 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.ext.services.notification;
-
-import static android.app.NotificationManager.IMPORTANCE_DEFAULT;
-import static android.app.NotificationManager.IMPORTANCE_HIGH;
-import static android.app.NotificationManager.IMPORTANCE_LOW;
-import static android.app.NotificationManager.IMPORTANCE_MIN;
-import static android.os.Process.FIRST_APPLICATION_UID;
-
-import static junit.framework.Assert.assertFalse;
-import static junit.framework.Assert.assertTrue;
-
-import static org.junit.Assert.assertEquals;
-import static org.mockito.Mockito.when;
-
-import android.app.Notification;
-import android.app.NotificationChannel;
-import android.os.Process;
-import android.service.notification.StatusBarNotification;
-import android.testing.TestableContext;
-
-import androidx.test.InstrumentationRegistry;
-import androidx.test.runner.AndroidJUnit4;
-
-import org.junit.Before;
-import org.junit.Rule;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.mockito.Mock;
-import org.mockito.MockitoAnnotations;
-
-@RunWith(AndroidJUnit4.class)
-public class NotificationCategorizerTest {
-    @Mock
-    private NotificationEntry mEntry;
-    @Mock
-    private StatusBarNotification mSbn;
-
-    @Rule
-    public final TestableContext mContext =
-            new TestableContext(InstrumentationRegistry.getContext(), null);
-
-    @Before
-    public void setUp() {
-        MockitoAnnotations.initMocks(this);
-
-        when(mEntry.getSbn()).thenReturn(mSbn);
-        when(mSbn.getUid()).thenReturn(Process.myUid());
-        when(mSbn.getPackageName()).thenReturn(mContext.getPackageName());
-    }
-
-    @Test
-    public void testPeopleCategory() {
-        NotificationCategorizer nc = new NotificationCategorizer();
-
-        when(mEntry.getChannel()).thenReturn(new NotificationChannel("", "", IMPORTANCE_DEFAULT));
-        when(mEntry.involvesPeople()).thenReturn(true);
-
-        assertEquals(NotificationCategorizer.CATEGORY_PEOPLE, nc.getCategory(mEntry));
-        assertFalse(nc.shouldSilence(NotificationCategorizer.CATEGORY_PEOPLE));
-    }
-
-    @Test
-    public void testMin() {
-        NotificationCategorizer nc = new NotificationCategorizer();
-
-        when(mEntry.getChannel()).thenReturn(new NotificationChannel("", "", IMPORTANCE_MIN));
-        when(mEntry.involvesPeople()).thenReturn(true);
-
-        assertEquals(NotificationCategorizer.CATEGORY_MIN, nc.getCategory(mEntry));
-        assertTrue(nc.shouldSilence(NotificationCategorizer.CATEGORY_MIN));
-    }
-
-    @Test
-    public void testHigh() {
-        NotificationCategorizer nc = new NotificationCategorizer();
-
-        when(mEntry.getChannel()).thenReturn(new NotificationChannel("", "", IMPORTANCE_HIGH));
-
-        assertEquals(NotificationCategorizer.CATEGORY_HIGH, nc.getCategory(mEntry));
-        assertFalse(nc.shouldSilence(NotificationCategorizer.CATEGORY_HIGH));
-    }
-
-    @Test
-    public void testOngoingCategory() {
-        NotificationCategorizer nc = new NotificationCategorizer();
-
-        when(mEntry.getChannel()).thenReturn(new NotificationChannel("", "", IMPORTANCE_DEFAULT));
-        when(mEntry.isOngoing()).thenReturn(true);
-
-        assertEquals(NotificationCategorizer.CATEGORY_ONGOING, nc.getCategory(mEntry));
-        assertTrue(nc.shouldSilence(NotificationCategorizer.CATEGORY_ONGOING));
-
-        when(mEntry.isOngoing()).thenReturn(false);
-        assertEquals(NotificationCategorizer.CATEGORY_EVERYTHING_ELSE, nc.getCategory(mEntry));
-        assertTrue(nc.shouldSilence(NotificationCategorizer.CATEGORY_EVERYTHING_ELSE));
-    }
-
-    @Test
-    public void testAlarmCategory() {
-        NotificationCategorizer nc = new NotificationCategorizer();
-
-        when(mEntry.getChannel()).thenReturn(new NotificationChannel("", "", IMPORTANCE_DEFAULT));
-        when(mEntry.isCategory(Notification.CATEGORY_ALARM)).thenReturn(true);
-
-        assertEquals(NotificationCategorizer.CATEGORY_ALARM, nc.getCategory(mEntry));
-        assertFalse(nc.shouldSilence(NotificationCategorizer.CATEGORY_ALARM));
-
-        when(mEntry.isCategory(Notification.CATEGORY_ALARM)).thenReturn(false);
-        assertEquals(NotificationCategorizer.CATEGORY_EVERYTHING_ELSE, nc.getCategory(mEntry));
-        assertTrue(nc.shouldSilence(NotificationCategorizer.CATEGORY_EVERYTHING_ELSE));
-    }
-
-    @Test
-    public void testCallCategory() {
-        NotificationCategorizer nc = new NotificationCategorizer();
-
-        when(mEntry.getChannel()).thenReturn(new NotificationChannel("", "", IMPORTANCE_DEFAULT));
-        when(mEntry.isCategory(Notification.CATEGORY_CALL)).thenReturn(true);
-
-        assertEquals(NotificationCategorizer.CATEGORY_CALL, nc.getCategory(mEntry));
-        assertFalse(nc.shouldSilence(NotificationCategorizer.CATEGORY_CALL));
-
-        when(mEntry.isCategory(Notification.CATEGORY_CALL)).thenReturn(false);
-        assertEquals(NotificationCategorizer.CATEGORY_EVERYTHING_ELSE, nc.getCategory(mEntry));
-        assertTrue(nc.shouldSilence(NotificationCategorizer.CATEGORY_EVERYTHING_ELSE));
-    }
-
-    @Test
-    public void testReminderCategory() {
-        NotificationCategorizer nc = new NotificationCategorizer();
-
-        when(mEntry.getChannel()).thenReturn(new NotificationChannel("", "", IMPORTANCE_DEFAULT));
-        when(mEntry.isCategory(Notification.CATEGORY_REMINDER)).thenReturn(true);
-
-        assertEquals(NotificationCategorizer.CATEGORY_REMINDER, nc.getCategory(mEntry));
-        assertFalse(nc.shouldSilence(NotificationCategorizer.CATEGORY_REMINDER));
-
-        when(mEntry.isCategory(Notification.CATEGORY_REMINDER)).thenReturn(false);
-        assertEquals(NotificationCategorizer.CATEGORY_EVERYTHING_ELSE, nc.getCategory(mEntry));
-        assertTrue(nc.shouldSilence(NotificationCategorizer.CATEGORY_EVERYTHING_ELSE));
-    }
-
-    @Test
-    public void testEventCategory() {
-        NotificationCategorizer nc = new NotificationCategorizer();
-
-        when(mEntry.getChannel()).thenReturn(new NotificationChannel("", "", IMPORTANCE_DEFAULT));
-        when(mEntry.isCategory(Notification.CATEGORY_EVENT)).thenReturn(true);
-
-        assertEquals(NotificationCategorizer.CATEGORY_EVENT, nc.getCategory(mEntry));
-        assertFalse(nc.shouldSilence(NotificationCategorizer.CATEGORY_EVENT));
-
-        when(mEntry.isCategory(Notification.CATEGORY_EVENT)).thenReturn(false);
-        assertEquals(NotificationCategorizer.CATEGORY_EVERYTHING_ELSE, nc.getCategory(mEntry));
-    }
-
-    @Test
-    public void testSystemCategory() {
-        NotificationCategorizer nc = new NotificationCategorizer();
-
-        when(mEntry.getChannel()).thenReturn(new NotificationChannel("", "", IMPORTANCE_DEFAULT));
-        when(mEntry.getImportance()).thenReturn(IMPORTANCE_DEFAULT);
-        when(mSbn.getUid()).thenReturn(FIRST_APPLICATION_UID - 1);
-
-        assertEquals(NotificationCategorizer.CATEGORY_SYSTEM, nc.getCategory(mEntry));
-        assertFalse(nc.shouldSilence(NotificationCategorizer.CATEGORY_SYSTEM));
-
-        when(mSbn.getUid()).thenReturn(FIRST_APPLICATION_UID);
-        assertEquals(NotificationCategorizer.CATEGORY_EVERYTHING_ELSE, nc.getCategory(mEntry));
-    }
-
-    @Test
-    public void testSystemLowCategory() {
-        NotificationCategorizer nc = new NotificationCategorizer();
-
-        when(mEntry.getChannel()).thenReturn(new NotificationChannel("", "", IMPORTANCE_LOW));
-        when(mEntry.getImportance()).thenReturn(IMPORTANCE_LOW);
-        when(mSbn.getUid()).thenReturn(FIRST_APPLICATION_UID - 1);
-
-        assertEquals(NotificationCategorizer.CATEGORY_SYSTEM_LOW, nc.getCategory(mEntry));
-        assertTrue(nc.shouldSilence(NotificationCategorizer.CATEGORY_SYSTEM_LOW));
-
-        when(mSbn.getUid()).thenReturn(FIRST_APPLICATION_UID);
-        assertEquals(NotificationCategorizer.CATEGORY_EVERYTHING_ELSE, nc.getCategory(mEntry));
-    }
-}
diff --git a/packages/ExtServices/tests/src/android/ext/services/notification/NotificationEntryTest.java b/packages/ExtServices/tests/src/android/ext/services/notification/NotificationEntryTest.java
deleted file mode 100644
index c026079..0000000
--- a/packages/ExtServices/tests/src/android/ext/services/notification/NotificationEntryTest.java
+++ /dev/null
@@ -1,266 +0,0 @@
-/**
- * Copyright (C) 2018 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.ext.services.notification;
-
-import static android.app.Notification.FLAG_CAN_COLORIZE;
-import static android.app.Notification.FLAG_FOREGROUND_SERVICE;
-import static android.app.NotificationManager.IMPORTANCE_HIGH;
-import static android.media.AudioAttributes.USAGE_ALARM;
-
-import static junit.framework.Assert.assertFalse;
-import static junit.framework.Assert.assertTrue;
-
-import static org.junit.Assert.assertNull;
-import static org.mockito.ArgumentMatchers.anyInt;
-import static org.mockito.ArgumentMatchers.anyString;
-import static org.mockito.Mockito.when;
-
-import android.app.Notification;
-import android.app.NotificationChannel;
-import android.app.Person;
-import android.content.ComponentName;
-import android.content.pm.ApplicationInfo;
-import android.content.pm.IPackageManager;
-import android.graphics.Bitmap;
-import android.graphics.drawable.Icon;
-import android.media.AudioAttributes;
-import android.os.Build;
-import android.os.Process;
-import android.os.UserHandle;
-import android.service.notification.StatusBarNotification;
-import android.testing.TestableContext;
-
-import org.junit.Before;
-import org.junit.Rule;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.mockito.Mock;
-import org.mockito.MockitoAnnotations;
-
-import java.util.ArrayList;
-
-import androidx.test.InstrumentationRegistry;
-import androidx.test.runner.AndroidJUnit4;
-
-@RunWith(AndroidJUnit4.class)
-public class NotificationEntryTest {
-    private String mPkg = "pkg";
-    private int mUid = 2018;
-    @Mock
-    private IPackageManager mPackageManager;
-    @Mock
-    private ApplicationInfo mAppInfo;
-    @Mock
-    private SmsHelper mSmsHelper;
-
-    private static final String DEFAULT_SMS_PACKAGE_NAME = "foo";
-
-    @Rule
-    public final TestableContext mContext =
-            new TestableContext(InstrumentationRegistry.getContext(), null);
-
-    private StatusBarNotification generateSbn(String channelId) {
-        Notification n = new Notification.Builder(mContext, channelId)
-                .setContentTitle("foo")
-                .build();
-
-        return new StatusBarNotification(mPkg, mPkg, 0, "tag", mUid, mUid, n,
-                UserHandle.SYSTEM, null, 0);
-    }
-
-    private StatusBarNotification generateSbn(String channelId, String packageName) {
-        Notification n = new Notification.Builder(mContext, channelId)
-                .setContentTitle("foo")
-                .build();
-
-        return new StatusBarNotification(packageName, packageName, 0, "tag", mUid, mUid, n,
-                UserHandle.SYSTEM, null, 0);
-    }
-
-    private StatusBarNotification generateSbn(Notification n) {
-        return new StatusBarNotification(mPkg, mPkg, 0, "tag", mUid, mUid, n,
-                UserHandle.SYSTEM, null, 0);
-    }
-
-    @Before
-    public void setUp() throws Exception {
-        MockitoAnnotations.initMocks(this);
-        mPkg = mContext.getPackageName();
-        mUid = Process.myUid();
-        when(mPackageManager.getApplicationInfo(anyString(), anyInt(), anyInt()))
-                .thenReturn(mAppInfo);
-        mAppInfo.targetSdkVersion = Build.VERSION_CODES.P;
-        when(mSmsHelper.getDefaultSmsApplication())
-                .thenReturn(new ComponentName(DEFAULT_SMS_PACKAGE_NAME, "bar"));
-    }
-
-    @Test
-    public void testHasPerson() {
-        NotificationChannel channel = new NotificationChannel("", "", IMPORTANCE_HIGH);
-        StatusBarNotification sbn = generateSbn(channel.getId());
-        ArrayList<Person> people = new ArrayList<>();
-        people.add(new Person.Builder().setKey("mailto:testing@android.com").build());
-        sbn.getNotification().extras.putParcelableArrayList(Notification.EXTRA_PEOPLE_LIST, people);
-
-        NotificationEntry entry = new NotificationEntry(
-                mContext, mPackageManager, sbn, channel, mSmsHelper);
-        assertTrue(entry.involvesPeople());
-    }
-
-    @Test
-    public void testNotPerson() {
-        NotificationChannel channel = new NotificationChannel("", "", IMPORTANCE_HIGH);
-        StatusBarNotification sbn = generateSbn(channel.getId());
-        NotificationEntry entry = new NotificationEntry(
-                mContext, mPackageManager, sbn, channel, mSmsHelper);
-        assertFalse(entry.involvesPeople());
-    }
-
-    @Test
-    public void testHasPerson_matchesDefaultSmsApp() {
-        NotificationChannel channel = new NotificationChannel("", "", IMPORTANCE_HIGH);
-        StatusBarNotification sbn = generateSbn(channel.getId(), DEFAULT_SMS_PACKAGE_NAME);
-        NotificationEntry entry = new NotificationEntry(
-                mContext, mPackageManager, sbn, channel, mSmsHelper);
-        assertTrue(entry.involvesPeople());
-    }
-
-    @Test
-    public void testHasPerson_doesntMatchDefaultSmsApp() {
-        NotificationChannel channel = new NotificationChannel("", "", IMPORTANCE_HIGH);
-        StatusBarNotification sbn = generateSbn(channel.getId(), "abc");
-        NotificationEntry entry = new NotificationEntry(
-                mContext, mPackageManager, sbn, channel, mSmsHelper);
-        assertFalse(entry.involvesPeople());
-    }
-
-    @Test
-    public void testIsInboxStyle() {
-        NotificationChannel channel = new NotificationChannel("", "", IMPORTANCE_HIGH);
-
-        Notification n = new Notification.Builder(mContext, channel.getId())
-                .setStyle(new Notification.InboxStyle())
-                .build();
-        NotificationEntry entry = new NotificationEntry(
-                mContext, mPackageManager, generateSbn(n), channel, mSmsHelper);
-        assertTrue(entry.hasStyle(Notification.InboxStyle.class));
-    }
-
-    @Test
-    public void testIsMessagingStyle() {
-        NotificationChannel channel = new NotificationChannel("", "", IMPORTANCE_HIGH);
-
-        Notification n = new Notification.Builder(mContext, channel.getId())
-                .setStyle(new Notification.MessagingStyle(""))
-                .build();
-        NotificationEntry entry = new NotificationEntry(
-                mContext, mPackageManager, generateSbn(n), channel, mSmsHelper);
-        assertTrue(entry.hasStyle(Notification.MessagingStyle.class));
-    }
-
-    @Test
-    public void testIsNotPersonStyle() {
-        NotificationChannel channel = new NotificationChannel("", "", IMPORTANCE_HIGH);
-
-        Notification n = new Notification.Builder(mContext, channel.getId())
-                .setStyle(new Notification.BigPictureStyle())
-                .build();
-        NotificationEntry entry = new NotificationEntry(
-                mContext, mPackageManager, generateSbn(n), channel, mSmsHelper);
-        assertFalse(entry.hasStyle(Notification.InboxStyle.class));
-        assertFalse(entry.hasStyle(Notification.MessagingStyle.class));
-    }
-
-    @Test
-    public void testIsAudioAttributes() {
-        NotificationChannel channel = new NotificationChannel("", "", IMPORTANCE_HIGH);
-        channel.setSound(null, new AudioAttributes.Builder().setUsage(USAGE_ALARM).build());
-
-        NotificationEntry entry = new NotificationEntry(
-                mContext, mPackageManager, generateSbn(channel.getId()), channel, mSmsHelper);
-
-        assertTrue(entry.isAudioAttributesUsage(USAGE_ALARM));
-    }
-
-    @Test
-    public void testIsNotAudioAttributes() {
-        NotificationChannel channel = new NotificationChannel("", "", IMPORTANCE_HIGH);
-        NotificationEntry entry = new NotificationEntry(
-                mContext, mPackageManager, generateSbn(channel.getId()), channel, mSmsHelper);
-
-        assertFalse(entry.isAudioAttributesUsage(USAGE_ALARM));
-    }
-
-    @Test
-    public void testIsCategory() {
-        NotificationChannel channel = new NotificationChannel("", "", IMPORTANCE_HIGH);
-
-        Notification n = new Notification.Builder(mContext, channel.getId())
-                .setCategory(Notification.CATEGORY_EMAIL)
-                .build();
-        NotificationEntry entry = new NotificationEntry(
-                mContext, mPackageManager, generateSbn(n), channel, mSmsHelper);
-
-        assertTrue(entry.isCategory(Notification.CATEGORY_EMAIL));
-        assertFalse(entry.isCategory(Notification.CATEGORY_MESSAGE));
-    }
-
-    @Test
-    public void testIsOngoing() {
-        NotificationChannel channel = new NotificationChannel("", "", IMPORTANCE_HIGH);
-
-        Notification n = new Notification.Builder(mContext, channel.getId())
-                .setFlag(FLAG_FOREGROUND_SERVICE, true)
-                .build();
-        NotificationEntry entry = new NotificationEntry(
-                mContext, mPackageManager, generateSbn(n), channel, mSmsHelper);
-
-        assertTrue(entry.isOngoing());
-    }
-
-    @Test
-    public void testIsNotOngoing() {
-        NotificationChannel channel = new NotificationChannel("", "", IMPORTANCE_HIGH);
-
-        Notification n = new Notification.Builder(mContext, channel.getId())
-                .setFlag(FLAG_CAN_COLORIZE, true)
-                .build();
-        NotificationEntry entry = new NotificationEntry(
-                mContext, mPackageManager, generateSbn(n), channel, mSmsHelper);
-
-        assertFalse(entry.isOngoing());
-    }
-
-    @Test
-    public void testShrinkNotification() {
-        Notification n = new Notification.Builder(mContext, "")
-                .setLargeIcon(Icon.createWithResource(
-                        mContext, android.R.drawable.alert_dark_frame))
-                .setSmallIcon(android.R.drawable.sym_def_app_icon)
-                .build();
-        n.largeIcon = Bitmap.createBitmap(100, 200, Bitmap.Config.RGB_565);
-        NotificationChannel channel = new NotificationChannel("", "", IMPORTANCE_HIGH);
-
-        NotificationEntry entry = new NotificationEntry(
-                mContext, mPackageManager, generateSbn(n), channel, mSmsHelper);
-
-        assertNull(entry.getNotification().getSmallIcon());
-        assertNull(entry.getNotification().getLargeIcon());
-        assertNull(entry.getNotification().largeIcon);
-        assertNull(entry.getNotification().extras.getParcelable(Notification.EXTRA_LARGE_ICON));
-    }
-}
diff --git a/packages/ExtServices/tests/src/android/ext/services/notification/SmartActionsHelperTest.java b/packages/ExtServices/tests/src/android/ext/services/notification/SmartActionsHelperTest.java
deleted file mode 100644
index 69abe87..0000000
--- a/packages/ExtServices/tests/src/android/ext/services/notification/SmartActionsHelperTest.java
+++ /dev/null
@@ -1,564 +0,0 @@
-/**
- * Copyright (C) 2018 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package android.ext.services.notification;
-
-import static com.google.common.truth.Truth.assertAbout;
-import static com.google.common.truth.Truth.assertThat;
-
-import static org.mockito.ArgumentMatchers.any;
-import static org.mockito.ArgumentMatchers.argThat;
-import static org.mockito.Mockito.never;
-import static org.mockito.Mockito.times;
-import static org.mockito.Mockito.verify;
-import static org.mockito.Mockito.when;
-
-import android.annotation.NonNull;
-import android.app.Notification;
-import android.app.NotificationChannel;
-import android.app.NotificationManager;
-import android.app.PendingIntent;
-import android.app.Person;
-import android.app.RemoteInput;
-import android.content.Context;
-import android.content.Intent;
-import android.content.pm.IPackageManager;
-import android.graphics.drawable.Icon;
-import android.os.Bundle;
-import android.os.Process;
-import android.service.notification.NotificationAssistantService;
-import android.service.notification.StatusBarNotification;
-import android.view.textclassifier.ConversationAction;
-import android.view.textclassifier.ConversationActions;
-import android.view.textclassifier.TextClassificationManager;
-import android.view.textclassifier.TextClassifier;
-import android.view.textclassifier.TextClassifierEvent;
-
-import com.google.common.truth.FailureStrategy;
-import com.google.common.truth.Subject;
-import com.google.common.truth.SubjectFactory;
-
-import org.junit.Before;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.mockito.ArgumentCaptor;
-import org.mockito.ArgumentMatcher;
-import org.mockito.Mock;
-import org.mockito.MockitoAnnotations;
-
-import java.time.Instant;
-import java.time.ZoneOffset;
-import java.time.ZonedDateTime;
-import java.util.Arrays;
-import java.util.Collections;
-import java.util.List;
-import java.util.Objects;
-
-import javax.annotation.Nullable;
-
-import androidx.test.InstrumentationRegistry;
-import androidx.test.runner.AndroidJUnit4;
-
-@RunWith(AndroidJUnit4.class)
-public class SmartActionsHelperTest {
-    private static final String RESULT_ID = "id";
-    private static final float SCORE = 0.7f;
-    private static final CharSequence SMART_REPLY = "Home";
-    private static final ConversationAction REPLY_ACTION =
-            new ConversationAction.Builder(ConversationAction.TYPE_TEXT_REPLY)
-                    .setTextReply(SMART_REPLY)
-                    .setConfidenceScore(SCORE)
-                    .build();
-    private static final String MESSAGE = "Where are you?";
-
-    @Mock
-    IPackageManager mIPackageManager;
-    @Mock
-    private TextClassifier mTextClassifier;
-    private StatusBarNotification mStatusBarNotification;
-    @Mock
-    private SmsHelper mSmsHelper;
-
-    private SmartActionsHelper mSmartActionsHelper;
-    private Context mContext;
-    private Notification.Builder mNotificationBuilder;
-    private AssistantSettings mSettings;
-
-    @Before
-    public void setup() {
-        MockitoAnnotations.initMocks(this);
-        mContext = InstrumentationRegistry.getTargetContext();
-
-        mContext.getSystemService(TextClassificationManager.class)
-                .setTextClassifier(mTextClassifier);
-        when(mTextClassifier.suggestConversationActions(any(ConversationActions.Request.class)))
-                .thenReturn(new ConversationActions(Arrays.asList(REPLY_ACTION), RESULT_ID));
-
-        mNotificationBuilder = new Notification.Builder(mContext, "channel");
-        mSettings = AssistantSettings.createForTesting(
-                null, null, Process.myUserHandle().getIdentifier(), null);
-        mSettings.mGenerateActions = true;
-        mSettings.mGenerateReplies = true;
-        mSmartActionsHelper = new SmartActionsHelper(mContext, mSettings);
-    }
-
-    private void setStatusBarNotification(Notification n) {
-        mStatusBarNotification = new StatusBarNotification("random.app", "random.app", 0,
-        "tag", Process.myUid(), Process.myPid(), n, Process.myUserHandle(), null, 0);
-    }
-
-    @Test
-    public void testSuggest_notMessageNotification() {
-        Notification notification = mNotificationBuilder.setContentText(MESSAGE).build();
-        setStatusBarNotification(notification);
-
-        mSmartActionsHelper.suggest(createNotificationEntry());
-
-        verify(mTextClassifier, never())
-                .suggestConversationActions(any(ConversationActions.Request.class));
-    }
-
-    @Test
-    public void testSuggest_noInlineReply() {
-        Notification notification =
-                mNotificationBuilder
-                        .setContentText(MESSAGE)
-                        .setCategory(Notification.CATEGORY_MESSAGE)
-                        .build();
-        setStatusBarNotification(notification);
-
-        ConversationActions.Request request = runSuggestAndCaptureRequest();
-
-        // actions are enabled, but replies are not.
-        assertThat(
-                request.getTypeConfig().resolveEntityListModifications(
-                        Arrays.asList(ConversationAction.TYPE_TEXT_REPLY,
-                                ConversationAction.TYPE_OPEN_URL)))
-                .containsExactly(ConversationAction.TYPE_OPEN_URL);
-    }
-
-    @Test
-    public void testSuggest_settingsOff() {
-        mSettings.mGenerateActions = false;
-        mSettings.mGenerateReplies = false;
-        Notification notification = createMessageNotification();
-        setStatusBarNotification(notification);
-
-        mSmartActionsHelper.suggest(createNotificationEntry());
-
-        verify(mTextClassifier, never())
-                .suggestConversationActions(any(ConversationActions.Request.class));
-    }
-
-    @Test
-    public void testSuggest_settings_repliesOnActionsOff() {
-        mSettings.mGenerateReplies = true;
-        mSettings.mGenerateActions = false;
-        Notification notification = createMessageNotification();
-        setStatusBarNotification(notification);
-
-        ConversationActions.Request request = runSuggestAndCaptureRequest();
-
-        // replies are enabled, but actions are not.
-        assertThat(
-                request.getTypeConfig().resolveEntityListModifications(
-                        Arrays.asList(ConversationAction.TYPE_TEXT_REPLY,
-                                ConversationAction.TYPE_OPEN_URL)))
-                .containsExactly(ConversationAction.TYPE_TEXT_REPLY);
-    }
-
-    @Test
-    public void testSuggest_settings_repliesOffActionsOn() {
-        mSettings.mGenerateReplies = false;
-        mSettings.mGenerateActions = true;
-        Notification notification = createMessageNotification();
-        setStatusBarNotification(notification);
-
-        ConversationActions.Request request = runSuggestAndCaptureRequest();
-
-        // actions are enabled, but replies are not.
-        assertThat(
-                request.getTypeConfig().resolveEntityListModifications(
-                        Arrays.asList(ConversationAction.TYPE_TEXT_REPLY,
-                                ConversationAction.TYPE_OPEN_URL)))
-                .containsExactly(ConversationAction.TYPE_OPEN_URL);
-    }
-
-
-    @Test
-    public void testSuggest_nonMessageStyleMessageNotification() {
-        Notification notification = createMessageNotification();
-        setStatusBarNotification(notification);
-
-        List<ConversationActions.Message> messages =
-                runSuggestAndCaptureRequest().getConversation();
-
-        assertThat(messages).hasSize(1);
-        MessageSubject.assertThat(messages.get(0)).hasText(MESSAGE);
-        ArgumentCaptor<TextClassifierEvent> argumentCaptor =
-                ArgumentCaptor.forClass(TextClassifierEvent.class);
-        verify(mTextClassifier).onTextClassifierEvent(argumentCaptor.capture());
-        TextClassifierEvent textClassifierEvent = argumentCaptor.getValue();
-        assertTextClassifierEvent(textClassifierEvent, TextClassifierEvent.TYPE_ACTIONS_GENERATED);
-        assertThat(textClassifierEvent.getEntityTypes()).asList()
-                .containsExactly(ConversationAction.TYPE_TEXT_REPLY);
-    }
-
-    @Test
-    public void testSuggest_messageStyle() {
-        Person me = new Person.Builder().setName("Me").build();
-        Person userA = new Person.Builder().setName("A").build();
-        Person userB = new Person.Builder().setName("B").build();
-        Notification.MessagingStyle style =
-                new Notification.MessagingStyle(me)
-                        .addMessage("firstMessage", 1000, (Person) null)
-                        .addMessage("secondMessage", 2000, me)
-                        .addMessage("thirdMessage", 3000, userA)
-                        .addMessage("fourthMessage", 4000, userB);
-        Notification notification =
-                mNotificationBuilder
-                        .setContentText("You have three new messages")
-                        .setStyle(style)
-                        .setActions(createReplyAction())
-                        .build();
-        setStatusBarNotification(notification);
-
-        List<ConversationActions.Message> messages =
-                runSuggestAndCaptureRequest().getConversation();
-        assertThat(messages).hasSize(4);
-
-        ConversationActions.Message firstMessage = messages.get(0);
-        MessageSubject.assertThat(firstMessage).hasText("firstMessage");
-        MessageSubject.assertThat(firstMessage)
-                .hasPerson(ConversationActions.Message.PERSON_USER_SELF);
-        MessageSubject.assertThat(firstMessage)
-                .hasReferenceTime(createZonedDateTimeFromMsUtc(1000));
-
-        ConversationActions.Message secondMessage = messages.get(1);
-        MessageSubject.assertThat(secondMessage).hasText("secondMessage");
-        MessageSubject.assertThat(secondMessage)
-                .hasPerson(ConversationActions.Message.PERSON_USER_SELF);
-        MessageSubject.assertThat(secondMessage)
-                .hasReferenceTime(createZonedDateTimeFromMsUtc(2000));
-
-        ConversationActions.Message thirdMessage = messages.get(2);
-        MessageSubject.assertThat(thirdMessage).hasText("thirdMessage");
-        MessageSubject.assertThat(thirdMessage).hasPerson(userA);
-        MessageSubject.assertThat(thirdMessage)
-                .hasReferenceTime(createZonedDateTimeFromMsUtc(3000));
-
-        ConversationActions.Message fourthMessage = messages.get(3);
-        MessageSubject.assertThat(fourthMessage).hasText("fourthMessage");
-        MessageSubject.assertThat(fourthMessage).hasPerson(userB);
-        MessageSubject.assertThat(fourthMessage)
-                .hasReferenceTime(createZonedDateTimeFromMsUtc(4000));
-
-        ArgumentCaptor<TextClassifierEvent> argumentCaptor =
-                ArgumentCaptor.forClass(TextClassifierEvent.class);
-        verify(mTextClassifier).onTextClassifierEvent(argumentCaptor.capture());
-        TextClassifierEvent textClassifierEvent = argumentCaptor.getValue();
-        assertTextClassifierEvent(textClassifierEvent, TextClassifierEvent.TYPE_ACTIONS_GENERATED);
-        assertThat(textClassifierEvent.getEntityTypes()).asList()
-                .containsExactly(ConversationAction.TYPE_TEXT_REPLY);
-    }
-
-    @Test
-    public void testSuggest_lastMessageLocalUser() {
-        Person me = new Person.Builder().setName("Me").build();
-        Person userA = new Person.Builder().setName("A").build();
-        Notification.MessagingStyle style =
-                new Notification.MessagingStyle(me)
-                        .addMessage("firstMessage", 1000, userA)
-                        .addMessage("secondMessage", 2000, me);
-        Notification notification =
-                mNotificationBuilder
-                        .setContentText("You have two new messages")
-                        .setStyle(style)
-                        .setActions(createReplyAction())
-                        .build();
-        setStatusBarNotification(notification);
-
-        mSmartActionsHelper.suggest(createNotificationEntry());
-
-        verify(mTextClassifier, never())
-                .suggestConversationActions(any(ConversationActions.Request.class));
-    }
-
-    @Test
-    public void testSuggest_messageStyle_noPerson() {
-        Person me = new Person.Builder().setName("Me").build();
-        Notification.MessagingStyle style =
-                new Notification.MessagingStyle(me).addMessage("message", 1000, (Person) null);
-        Notification notification =
-                mNotificationBuilder
-                        .setContentText("You have one new message")
-                        .setStyle(style)
-                        .setActions(createReplyAction())
-                        .build();
-        setStatusBarNotification(notification);
-
-        mSmartActionsHelper.suggest(createNotificationEntry());
-
-        verify(mTextClassifier, never())
-                .suggestConversationActions(any(ConversationActions.Request.class));
-    }
-
-    @Test
-    public void testOnSuggestedReplySent() {
-        Notification notification = createMessageNotification();
-        setStatusBarNotification(notification);
-
-        mSmartActionsHelper.suggest(createNotificationEntry());
-        mSmartActionsHelper.onSuggestedReplySent(mStatusBarNotification.getKey(), SMART_REPLY,
-                NotificationAssistantService.SOURCE_FROM_ASSISTANT);
-
-        ArgumentCaptor<TextClassifierEvent> argumentCaptor =
-                ArgumentCaptor.forClass(TextClassifierEvent.class);
-        verify(mTextClassifier, times(2)).onTextClassifierEvent(argumentCaptor.capture());
-        List<TextClassifierEvent> events = argumentCaptor.getAllValues();
-        assertTextClassifierEvent(events.get(0), TextClassifierEvent.TYPE_ACTIONS_GENERATED);
-        assertTextClassifierEvent(events.get(1), TextClassifierEvent.TYPE_SMART_ACTION);
-        float[] scores = events.get(1).getScores();
-        assertThat(scores).hasLength(1);
-        assertThat(scores[0]).isEqualTo(SCORE);
-    }
-
-    @Test
-    public void testOnSuggestedReplySent_anotherNotification() {
-        Notification notification = createMessageNotification();
-        setStatusBarNotification(notification);
-
-        mSmartActionsHelper.suggest(createNotificationEntry());
-        mSmartActionsHelper.onSuggestedReplySent(
-                "something_else", MESSAGE, NotificationAssistantService.SOURCE_FROM_ASSISTANT);
-
-        verify(mTextClassifier, never()).onTextClassifierEvent(
-                argThat(new TextClassifierEventMatcher(TextClassifierEvent.TYPE_SMART_ACTION)));
-    }
-
-    @Test
-    public void testOnSuggestedReplySent_missingResultId() {
-        when(mTextClassifier.suggestConversationActions(any(ConversationActions.Request.class)))
-                .thenReturn(new ConversationActions(Collections.singletonList(REPLY_ACTION), null));
-        Notification notification = createMessageNotification();
-        setStatusBarNotification(notification);
-
-        mSmartActionsHelper.suggest(createNotificationEntry());
-        mSmartActionsHelper.onSuggestedReplySent(mStatusBarNotification.getKey(), SMART_REPLY,
-                NotificationAssistantService.SOURCE_FROM_ASSISTANT);
-
-        verify(mTextClassifier, never()).onTextClassifierEvent(any(TextClassifierEvent.class));
-    }
-
-    @Test
-    public void testOnNotificationDirectReply() {
-        Notification notification = createMessageNotification();
-        setStatusBarNotification(notification);
-
-        mSmartActionsHelper.suggest(createNotificationEntry());
-        mSmartActionsHelper.onNotificationDirectReplied(mStatusBarNotification.getKey());
-
-        ArgumentCaptor<TextClassifierEvent> argumentCaptor =
-                ArgumentCaptor.forClass(TextClassifierEvent.class);
-        verify(mTextClassifier, times(2)).onTextClassifierEvent(argumentCaptor.capture());
-        List<TextClassifierEvent> events = argumentCaptor.getAllValues();
-        assertTextClassifierEvent(events.get(0), TextClassifierEvent.TYPE_ACTIONS_GENERATED);
-        assertTextClassifierEvent(events.get(1), TextClassifierEvent.TYPE_MANUAL_REPLY);
-    }
-
-    @Test
-    public void testOnNotificationExpansionChanged() {
-        Notification notification = createMessageNotification();
-        setStatusBarNotification(notification);
-
-        mSmartActionsHelper.suggest(createNotificationEntry());
-        mSmartActionsHelper.onNotificationExpansionChanged(createNotificationEntry(), true);
-
-        ArgumentCaptor<TextClassifierEvent> argumentCaptor =
-                ArgumentCaptor.forClass(TextClassifierEvent.class);
-        verify(mTextClassifier, times(2)).onTextClassifierEvent(argumentCaptor.capture());
-        List<TextClassifierEvent> events = argumentCaptor.getAllValues();
-        assertTextClassifierEvent(events.get(0), TextClassifierEvent.TYPE_ACTIONS_GENERATED);
-        assertTextClassifierEvent(events.get(1), TextClassifierEvent.TYPE_ACTIONS_SHOWN);
-    }
-
-    @Test
-    public void testOnNotificationsSeen_notExpanded() {
-        Notification notification = createMessageNotification();
-        setStatusBarNotification(notification);
-
-        mSmartActionsHelper.suggest(createNotificationEntry());
-        mSmartActionsHelper.onNotificationExpansionChanged(createNotificationEntry(), false);
-
-        verify(mTextClassifier, never()).onTextClassifierEvent(
-                argThat(new TextClassifierEventMatcher(TextClassifierEvent.TYPE_ACTIONS_SHOWN)));
-    }
-
-    @Test
-    public void testOnNotifications_expanded() {
-        Notification notification = createMessageNotification();
-        setStatusBarNotification(notification);
-
-        mSmartActionsHelper.suggest(createNotificationEntry());
-        mSmartActionsHelper.onNotificationExpansionChanged(createNotificationEntry(), true);
-
-        ArgumentCaptor<TextClassifierEvent> argumentCaptor =
-                ArgumentCaptor.forClass(TextClassifierEvent.class);
-        verify(mTextClassifier, times(2)).onTextClassifierEvent(argumentCaptor.capture());
-        List<TextClassifierEvent> events = argumentCaptor.getAllValues();
-        assertTextClassifierEvent(events.get(0), TextClassifierEvent.TYPE_ACTIONS_GENERATED);
-        assertTextClassifierEvent(events.get(1), TextClassifierEvent.TYPE_ACTIONS_SHOWN);
-    }
-
-    @Test
-    public void testCopyAction() {
-        Bundle extras = new Bundle();
-        Bundle entitiesExtras = new Bundle();
-        entitiesExtras.putString(SmartActionsHelper.KEY_TEXT, "12345");
-        extras.putParcelable(SmartActionsHelper.ENTITIES_EXTRAS, entitiesExtras);
-        ConversationAction conversationAction =
-                new ConversationAction.Builder(ConversationAction.TYPE_COPY)
-                        .setExtras(extras)
-                        .build();
-        when(mTextClassifier.suggestConversationActions(any(ConversationActions.Request.class)))
-                .thenReturn(
-                        new ConversationActions(
-                                Collections.singletonList(conversationAction), null));
-
-        Notification notification = createMessageNotification();
-        setStatusBarNotification(notification);
-        SmartActionsHelper.SmartSuggestions suggestions =
-                mSmartActionsHelper.suggest(createNotificationEntry());
-
-        assertThat(suggestions.actions).hasSize(1);
-        Notification.Action action = suggestions.actions.get(0);
-        assertThat(action.title).isEqualTo("12345");
-    }
-
-    private ZonedDateTime createZonedDateTimeFromMsUtc(long msUtc) {
-        return ZonedDateTime.ofInstant(Instant.ofEpochMilli(msUtc), ZoneOffset.systemDefault());
-    }
-
-    private ConversationActions.Request runSuggestAndCaptureRequest() {
-        mSmartActionsHelper.suggest(createNotificationEntry());
-
-        ArgumentCaptor<ConversationActions.Request> argumentCaptor =
-                ArgumentCaptor.forClass(ConversationActions.Request.class);
-        verify(mTextClassifier).suggestConversationActions(argumentCaptor.capture());
-        return argumentCaptor.getValue();
-    }
-
-    private Notification.Action createReplyAction() {
-        PendingIntent pendingIntent =
-                PendingIntent.getActivity(mContext, 0, new Intent(mContext, this.getClass()), 0);
-        RemoteInput remoteInput = new RemoteInput.Builder("result")
-                .setAllowFreeFormInput(true)
-                .build();
-        return new Notification.Action.Builder(
-                Icon.createWithResource(mContext.getResources(),
-                        android.R.drawable.stat_sys_warning),
-                "Reply", pendingIntent)
-                .addRemoteInput(remoteInput)
-                .build();
-    }
-
-    private NotificationEntry createNotificationEntry() {
-        NotificationChannel channel =
-                new NotificationChannel("id", "name", NotificationManager.IMPORTANCE_DEFAULT);
-        return new NotificationEntry(
-                mContext, mIPackageManager, mStatusBarNotification, channel, mSmsHelper);
-    }
-
-    private Notification createMessageNotification() {
-        return mNotificationBuilder
-                .setContentText(MESSAGE)
-                .setCategory(Notification.CATEGORY_MESSAGE)
-                .setActions(createReplyAction())
-                .build();
-    }
-
-    private void assertTextClassifierEvent(
-            TextClassifierEvent textClassifierEvent, int expectedEventType) {
-        assertThat(textClassifierEvent.getEventCategory())
-                .isEqualTo(TextClassifierEvent.CATEGORY_CONVERSATION_ACTIONS);
-        assertThat(textClassifierEvent.getEventContext().getPackageName())
-                .isEqualTo(InstrumentationRegistry.getTargetContext().getPackageName());
-        assertThat(textClassifierEvent.getEventContext().getWidgetType())
-                .isEqualTo(TextClassifier.WIDGET_TYPE_NOTIFICATION);
-        assertThat(textClassifierEvent.getEventType()).isEqualTo(expectedEventType);
-    }
-
-    private static final class MessageSubject
-            extends Subject<MessageSubject, ConversationActions.Message> {
-
-        private static final SubjectFactory<MessageSubject, ConversationActions.Message> FACTORY =
-                new SubjectFactory<MessageSubject, ConversationActions.Message>() {
-                    @Override
-                    public MessageSubject getSubject(
-                            @NonNull FailureStrategy failureStrategy,
-                            @NonNull ConversationActions.Message subject) {
-                        return new MessageSubject(failureStrategy, subject);
-                    }
-                };
-
-        private MessageSubject(
-                FailureStrategy failureStrategy, @Nullable ConversationActions.Message subject) {
-            super(failureStrategy, subject);
-        }
-
-        private void hasText(String text) {
-            if (!Objects.equals(text, getSubject().getText().toString())) {
-                failWithBadResults("has text", text, "has", getSubject().getText());
-            }
-        }
-
-        private void hasPerson(Person person) {
-            if (!Objects.equals(person, getSubject().getAuthor())) {
-                failWithBadResults("has author", person, "has", getSubject().getAuthor());
-            }
-        }
-
-        private void hasReferenceTime(ZonedDateTime referenceTime) {
-            if (!Objects.equals(referenceTime, getSubject().getReferenceTime())) {
-                failWithBadResults(
-                        "has reference time",
-                        referenceTime,
-                        "has",
-                        getSubject().getReferenceTime());
-            }
-        }
-
-        private static MessageSubject assertThat(ConversationActions.Message message) {
-            return assertAbout(FACTORY).that(message);
-        }
-    }
-
-    private final class TextClassifierEventMatcher implements ArgumentMatcher<TextClassifierEvent> {
-
-        private int mType;
-
-        private TextClassifierEventMatcher(int type) {
-            mType = type;
-        }
-
-        @Override
-        public boolean matches(TextClassifierEvent textClassifierEvent) {
-            if (textClassifierEvent == null) {
-                return false;
-            }
-            return mType == textClassifierEvent.getEventType();
-        }
-    }
-}
diff --git a/packages/ExtServices/tests/src/android/ext/services/sms/FinancialSmsServiceImplTest.java b/packages/ExtServices/tests/src/android/ext/services/sms/FinancialSmsServiceImplTest.java
deleted file mode 100644
index 12575a6..0000000
--- a/packages/ExtServices/tests/src/android/ext/services/sms/FinancialSmsServiceImplTest.java
+++ /dev/null
@@ -1,35 +0,0 @@
-/*
- * Copyright (C) 2018 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package android.ext.services.sms;
-
-import static com.google.common.truth.Truth.assertThat;
-
-import android.os.Bundle;
-
-import org.junit.Test;
-
-/**
- * Contains the base tests for FinancialSmsServiceImpl.
- */
-public class FinancialSmsServiceImplTest {
-
-    private final FinancialSmsServiceImpl mService = new FinancialSmsServiceImpl();
-
-    @Test
-    public void testOnGetSmsMessages_nullWithNoParamData() {
-        assertThat(mService.onGetSmsMessages(new Bundle())).isNull();
-    }
-}
diff --git a/packages/ExtServices/tests/src/android/ext/services/storage/CacheQuotaServiceImplTest.java b/packages/ExtServices/tests/src/android/ext/services/storage/CacheQuotaServiceImplTest.java
deleted file mode 100644
index df4738f..0000000
--- a/packages/ExtServices/tests/src/android/ext/services/storage/CacheQuotaServiceImplTest.java
+++ /dev/null
@@ -1,150 +0,0 @@
-/*
- * Copyright (C) 2017 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.ext.services.storage;
-
-import static com.google.common.truth.Truth.assertThat;
-
-import static org.mockito.Mockito.when;
-
-import android.app.usage.CacheQuotaHint;
-import android.app.usage.UsageStats;
-import android.content.Context;
-import android.content.ContextWrapper;
-import android.content.Intent;
-import android.os.storage.StorageManager;
-import android.os.storage.VolumeInfo;
-import android.test.ServiceTestCase;
-
-import org.junit.Before;
-import org.junit.Test;
-import org.mockito.Answers;
-import org.mockito.Mock;
-import org.mockito.Mockito;
-import org.mockito.MockitoAnnotations;
-
-import java.io.File;
-import java.util.ArrayList;
-import java.util.List;
-
-public class CacheQuotaServiceImplTest extends ServiceTestCase<CacheQuotaServiceImpl> {
-    private static final String sTestVolUuid = "uuid";
-    private static final String sSecondTestVolUuid = "otherUuid";
-
-    @Mock private Context mContext;
-    @Mock private File mFile;
-    @Mock private VolumeInfo mVolume;
-    @Mock(answer = Answers.RETURNS_DEEP_STUBS) private StorageManager mStorageManager;
-
-    public CacheQuotaServiceImplTest() {
-        super(CacheQuotaServiceImpl.class);
-    }
-
-    @Before
-    public void setUp() throws Exception {
-        super.setUp();
-        MockitoAnnotations.initMocks(this);
-        mContext = Mockito.spy(new ContextWrapper(getSystemContext()));
-        setContext(mContext);
-        when(mContext.getSystemService(Context.STORAGE_SERVICE)).thenReturn(mStorageManager);
-
-        when(mFile.getUsableSpace()).thenReturn(10000L);
-        when(mVolume.getPath()).thenReturn(mFile);
-        when(mStorageManager.findVolumeByUuid(sTestVolUuid)).thenReturn(mVolume);
-        when(mStorageManager.findVolumeByUuid(sSecondTestVolUuid)).thenReturn(mVolume);
-
-        Intent intent = new Intent(getContext(), CacheQuotaServiceImpl.class);
-        startService(intent);
-    }
-
-    @Test
-    public void testNoApps() {
-        CacheQuotaServiceImpl service = getService();
-        assertEquals(service.onComputeCacheQuotaHints(new ArrayList()).size(), 0);
-    }
-
-    @Test
-    public void testOneApp() throws Exception {
-        ArrayList<CacheQuotaHint> requests = new ArrayList<>();
-        CacheQuotaHint request = makeNewRequest("com.test", sTestVolUuid, 1001, 100L);
-        requests.add(request);
-
-        List<CacheQuotaHint> output = getService().onComputeCacheQuotaHints(requests);
-
-        assertThat(output).hasSize(1);
-        assertThat(output.get(0).getQuota()).isEqualTo(1500L);
-    }
-
-    @Test
-    public void testTwoAppsOneVolume() throws Exception {
-        ArrayList<CacheQuotaHint> requests = new ArrayList<>();
-        requests.add(makeNewRequest("com.test", sTestVolUuid, 1001, 100L));
-        requests.add(makeNewRequest("com.test2", sTestVolUuid, 1002, 99L));
-
-        List<CacheQuotaHint> output = getService().onComputeCacheQuotaHints(requests);
-
-        // Note that the sizes are just the cache area split up.
-        assertThat(output).hasSize(2);
-        assertThat(output.get(0).getQuota()).isEqualTo(883);
-        assertThat(output.get(1).getQuota()).isEqualTo(1500 - 883);
-    }
-
-    @Test
-    public void testTwoAppsTwoVolumes() throws Exception {
-        ArrayList<CacheQuotaHint> requests = new ArrayList<>();
-        requests.add(makeNewRequest("com.test", sTestVolUuid, 1001, 100L));
-        requests.add(makeNewRequest("com.test2", sSecondTestVolUuid, 1002, 99L));
-
-        List<CacheQuotaHint> output = getService().onComputeCacheQuotaHints(requests);
-
-        assertThat(output).hasSize(2);
-        assertThat(output.get(0).getQuota()).isEqualTo(1500);
-        assertThat(output.get(1).getQuota()).isEqualTo(1500);
-    }
-
-    @Test
-    public void testMultipleAppsPerUidIsCollated() throws Exception {
-        ArrayList<CacheQuotaHint> requests = new ArrayList<>();
-        requests.add(makeNewRequest("com.test", sTestVolUuid, 1001, 100L));
-        requests.add(makeNewRequest("com.test2", sTestVolUuid, 1001, 99L));
-
-        List<CacheQuotaHint> output = getService().onComputeCacheQuotaHints(requests);
-
-        assertThat(output).hasSize(1);
-        assertThat(output.get(0).getQuota()).isEqualTo(1500);
-    }
-
-    @Test
-    public void testTwoAppsTwoVolumesTwoUuidsShouldBESeparate() throws Exception {
-        ArrayList<CacheQuotaHint> requests = new ArrayList<>();
-        requests.add(makeNewRequest("com.test", sTestVolUuid, 1001, 100L));
-        requests.add(makeNewRequest("com.test2", sSecondTestVolUuid, 1001, 99L));
-
-        List<CacheQuotaHint> output = getService().onComputeCacheQuotaHints(requests);
-
-        assertThat(output).hasSize(2);
-        assertThat(output.get(0).getQuota()).isEqualTo(1500);
-        assertThat(output.get(1).getQuota()).isEqualTo(1500);
-    }
-
-    private CacheQuotaHint makeNewRequest(String packageName, String uuid, int uid, long foregroundTime) {
-        UsageStats stats = new UsageStats();
-        stats.mPackageName = packageName;
-        stats.mTotalTimeInForeground = foregroundTime;
-        return new CacheQuotaHint.Builder()
-                .setVolumeUuid(uuid).setUid(uid).setUsageStats(stats).setQuota(-1).build();
-    }
-}
diff --git a/packages/ExtServices/tests/src/android/ext/services/watchdog/ExplicitHealthCheckServiceImplTest.java b/packages/ExtServices/tests/src/android/ext/services/watchdog/ExplicitHealthCheckServiceImplTest.java
deleted file mode 100644
index a9cb63e..0000000
--- a/packages/ExtServices/tests/src/android/ext/services/watchdog/ExplicitHealthCheckServiceImplTest.java
+++ /dev/null
@@ -1,201 +0,0 @@
-/*
- * Copyright (C) 2019 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.ext.services.watchdog;
-
-import static android.service.watchdog.ExplicitHealthCheckService.EXTRA_REQUESTED_PACKAGES;
-import static android.service.watchdog.ExplicitHealthCheckService.EXTRA_SUPPORTED_PACKAGES;
-import static android.service.watchdog.ExplicitHealthCheckService.PackageConfig;
-
-import static com.google.common.truth.Truth.assertThat;
-
-import static org.junit.Assert.fail;
-import static org.junit.Assume.assumeFalse;
-
-import android.Manifest;
-import android.content.ComponentName;
-import android.content.Context;
-import android.content.Intent;
-import android.content.pm.PackageManager;
-import android.content.pm.ResolveInfo;
-import android.content.pm.ServiceInfo;
-import android.os.RemoteCallback;
-import android.service.watchdog.ExplicitHealthCheckService;
-import android.service.watchdog.IExplicitHealthCheckService;
-
-import androidx.test.InstrumentationRegistry;
-import androidx.test.rule.ServiceTestRule;
-
-import org.junit.After;
-import org.junit.Before;
-import org.junit.Rule;
-import org.junit.Test;
-
-import java.util.ArrayList;
-import java.util.List;
-import java.util.concurrent.CountDownLatch;
-
-/**
- * Contains the base tests that does not rely on the specific algorithm implementation.
- */
-public class ExplicitHealthCheckServiceImplTest {
-    private static final String NETWORK_STACK_CONNECTOR_CLASS =
-            "android.net.INetworkStackConnector";
-
-    private final Context mContext = InstrumentationRegistry.getContext();
-    private IExplicitHealthCheckService mService;
-    private String mNetworkStackPackageName;
-
-    @Rule
-    public ServiceTestRule mServiceTestRule;
-
-    @Before
-    public void setUp() throws Exception {
-        InstrumentationRegistry
-                .getInstrumentation()
-                .getUiAutomation()
-                .adoptShellPermissionIdentity(
-                        Manifest.permission.BIND_EXPLICIT_HEALTH_CHECK_SERVICE);
-
-        mServiceTestRule = new ServiceTestRule();
-        mService = IExplicitHealthCheckService.Stub.asInterface(
-                mServiceTestRule.bindService(getExtServiceIntent()));
-        mNetworkStackPackageName = getNetworkStackPackage();
-        assumeFalse(mNetworkStackPackageName == null);
-    }
-
-    @After
-    public void tearDown() {
-        InstrumentationRegistry
-                .getInstrumentation()
-                .getUiAutomation()
-                .dropShellPermissionIdentity();
-    }
-
-    @Test
-    public void testHealthCheckSupportedPackage() throws Exception {
-        List<PackageConfig> supportedPackages = new ArrayList<>();
-        CountDownLatch latch = new CountDownLatch(1);
-
-        mService.getSupportedPackages(new RemoteCallback(result -> {
-            supportedPackages.addAll(result.getParcelableArrayList(EXTRA_SUPPORTED_PACKAGES));
-            latch.countDown();
-        }));
-        latch.await();
-
-        // TODO: Support DeviceConfig changes for the health check timeout
-        assertThat(supportedPackages).hasSize(1);
-        assertThat(supportedPackages.get(0).getPackageName())
-                .isEqualTo(mNetworkStackPackageName);
-        assertThat(supportedPackages.get(0).getHealthCheckTimeoutMillis())
-                .isEqualTo(ExplicitHealthCheckServiceImpl.DEFAULT_REQUEST_TIMEOUT_MILLIS);
-    }
-
-    @Test
-    public void testHealthCheckRequests() throws Exception {
-        List<String> requestedPackages = new ArrayList<>();
-        CountDownLatch latch1 = new CountDownLatch(1);
-        CountDownLatch latch2 = new CountDownLatch(1);
-        CountDownLatch latch3 = new CountDownLatch(1);
-
-        // Initially, no health checks requested
-        mService.getRequestedPackages(new RemoteCallback(result -> {
-            requestedPackages.addAll(result.getParcelableArrayList(EXTRA_REQUESTED_PACKAGES));
-            latch1.countDown();
-        }));
-
-        // Verify that no health checks requested
-        latch1.await();
-        assertThat(requestedPackages).isEmpty();
-
-        // Then request health check
-        mService.request(mNetworkStackPackageName);
-
-        // Verify that health check is requested for network stack
-        mService.getRequestedPackages(new RemoteCallback(result -> {
-            requestedPackages.addAll(result.getParcelableArrayList(EXTRA_REQUESTED_PACKAGES));
-            latch2.countDown();
-        }));
-        latch2.await();
-        assertThat(requestedPackages).hasSize(1);
-        assertThat(requestedPackages.get(0)).isEqualTo(mNetworkStackPackageName);
-
-        // Then cancel health check
-        requestedPackages.clear();
-        mService.cancel(mNetworkStackPackageName);
-
-        // Verify that health check is cancelled for network stack
-        mService.getRequestedPackages(new RemoteCallback(result -> {
-            requestedPackages.addAll(result.getParcelableArrayList(EXTRA_REQUESTED_PACKAGES));
-            latch3.countDown();
-        }));
-        latch3.await();
-        assertThat(requestedPackages).isEmpty();
-    }
-
-    private String getNetworkStackPackage() {
-        Intent intent = new Intent(NETWORK_STACK_CONNECTOR_CLASS);
-        ComponentName comp = intent.resolveSystemService(mContext.getPackageManager(), 0);
-        if (comp != null) {
-            return comp.getPackageName();
-        } else {
-            // On Go devices, or any device that does not ship the network stack module.
-            // The network stack will live in system_server process, so no need to monitor.
-            return null;
-        }
-    }
-
-    private Intent getExtServiceIntent() {
-        ComponentName component = getExtServiceComponentNameLocked();
-        if (component == null) {
-            fail("Health check service not found");
-        }
-        Intent intent = new Intent();
-        intent.setComponent(component);
-        return intent;
-    }
-
-    private ComponentName getExtServiceComponentNameLocked() {
-        ServiceInfo serviceInfo = getExtServiceInfoLocked();
-        if (serviceInfo == null) {
-            return null;
-        }
-
-        final ComponentName name = new ComponentName(serviceInfo.packageName, serviceInfo.name);
-        if (!Manifest.permission.BIND_EXPLICIT_HEALTH_CHECK_SERVICE
-                .equals(serviceInfo.permission)) {
-            return null;
-        }
-        return name;
-    }
-
-    private ServiceInfo getExtServiceInfoLocked() {
-        final String packageName =
-                mContext.getPackageManager().getServicesSystemSharedLibraryPackageName();
-        if (packageName == null) {
-            return null;
-        }
-
-        final Intent intent = new Intent(ExplicitHealthCheckService.SERVICE_INTERFACE);
-        intent.setPackage(packageName);
-        final ResolveInfo resolveInfo = mContext.getPackageManager().resolveService(intent,
-                PackageManager.GET_SERVICES | PackageManager.GET_META_DATA);
-        if (resolveInfo == null || resolveInfo.serviceInfo == null) {
-            return null;
-        }
-        return resolveInfo.serviceInfo;
-    }
-}
diff --git a/packages/InputDevices/res/values-hy/strings.xml b/packages/InputDevices/res/values-hy/strings.xml
index c7523e3..64ddf7a 100644
--- a/packages/InputDevices/res/values-hy/strings.xml
+++ b/packages/InputDevices/res/values-hy/strings.xml
@@ -40,7 +40,7 @@
     <string name="keyboard_layout_hebrew" msgid="7241473985890173812">"Եբրայերեն"</string>
     <string name="keyboard_layout_lithuanian" msgid="6943110873053106534">"Լիտվերեն"</string>
     <string name="keyboard_layout_spanish_latin" msgid="5690539836069535697">"Իսպաներեն (Լատինական)"</string>
-    <string name="keyboard_layout_latvian" msgid="4405417142306250595">"լատիշերեն"</string>
+    <string name="keyboard_layout_latvian" msgid="4405417142306250595">"լատվիերեն"</string>
     <string name="keyboard_layout_persian" msgid="3920643161015888527">"պարսկերեն"</string>
     <string name="keyboard_layout_azerbaijani" msgid="7315895417176467567">"ադրբեջաներեն"</string>
     <string name="keyboard_layout_polish" msgid="1121588624094925325">"լեհերեն"</string>
diff --git a/packages/NetworkPermissionConfig/Android.bp b/packages/NetworkPermissionConfig/Android.bp
deleted file mode 100644
index 6e50459..0000000
--- a/packages/NetworkPermissionConfig/Android.bp
+++ /dev/null
@@ -1,41 +0,0 @@
-//
-// Copyright (C) 2019 The Android Open Source Project
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//      http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-//
-
-java_defaults {
-    name: "NetworkPermissionConfigDefaults",
-    // TODO: mark app as hasCode=false in manifest once soong stops complaining about apps without
-    // a classes.dex.
-    srcs: ["src/**/*.java"],
-    platform_apis: true,
-    min_sdk_version: "28",
-    privileged: true,
-    manifest: "AndroidManifest.xml",
-}
-
-// Stub APK to define permissions for NetworkStack
-android_app {
-    name: "NetworkPermissionConfig",
-    defaults: ["NetworkPermissionConfigDefaults"],
-    certificate: "networkstack",
-}
-
-// Alternative stub APK signed with platform certificate. To use with InProcessNetworkStack.
-android_app {
-    name: "PlatformNetworkPermissionConfig",
-    defaults: ["NetworkPermissionConfigDefaults"],
-    certificate: "platform",
-    overrides: ["NetworkPermissionConfig"],
-}
diff --git a/packages/NetworkPermissionConfig/AndroidManifest.xml b/packages/NetworkPermissionConfig/AndroidManifest.xml
deleted file mode 100644
index 496fa4d..0000000
--- a/packages/NetworkPermissionConfig/AndroidManifest.xml
+++ /dev/null
@@ -1,40 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-/*
- * Copyright (C) 2019 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
--->
-<manifest xmlns:android="http://schemas.android.com/apk/res/android"
-    package="com.android.networkstack.permissionconfig"
-    android:sharedUserId="android.uid.networkstack"
-    android:versionCode="210000000"
-    android:versionName="Q-initial">
-    <uses-sdk android:minSdkVersion="28" android:targetSdkVersion="28" />
-    <!--
-    This package only exists to define the below permissions, and enforce that they are only
-    granted to apps sharing the same signature.
-    Permissions defined here are intended to be used only by the NetworkStack: both
-    NetworkStack and this stub APK are to be signed with a dedicated certificate to ensure
-    that, with the below permissions being signature permissions.
-
-    This APK *must* be installed, even if the NetworkStack app is not installed, because otherwise,
-    any application will be able to define this permission and the system will give that application
-    full access to the network stack.
-     -->
-    <permission android:name="android.permission.MAINLINE_NETWORK_STACK"
-                android:protectionLevel="signature"/>
-
-    <application android:name="com.android.server.NetworkPermissionConfig"/>
-</manifest>
diff --git a/packages/NetworkPermissionConfig/OWNERS b/packages/NetworkPermissionConfig/OWNERS
deleted file mode 100644
index 52193eb..0000000
--- a/packages/NetworkPermissionConfig/OWNERS
+++ /dev/null
@@ -1,5 +0,0 @@
-set noparent
-
-lorenzo@google.com
-baligh@google.com
-delphij@google.com
diff --git a/packages/NetworkPermissionConfig/src/com/android/server/NetworkPermissionConfig.java b/packages/NetworkPermissionConfig/src/com/android/server/NetworkPermissionConfig.java
deleted file mode 100644
index c904e23..0000000
--- a/packages/NetworkPermissionConfig/src/com/android/server/NetworkPermissionConfig.java
+++ /dev/null
@@ -1,26 +0,0 @@
-/*
- * Copyright (C) 2019 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.server;
-
-import android.app.Application;
-
-/**
- * Empty application for NetworkPermissionConfig that only exists because
- * soong builds complain if APKs have no source file.
- */
-public class NetworkPermissionConfig extends Application {
-}
diff --git a/packages/NetworkStack/Android.bp b/packages/NetworkStack/Android.bp
deleted file mode 100644
index c013b8c..0000000
--- a/packages/NetworkStack/Android.bp
+++ /dev/null
@@ -1,134 +0,0 @@
-//
-// Copyright (C) 2018 The Android Open Source Project
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//      http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-//
-
-java_library {
-    name: "captiveportal-lib",
-    srcs: ["common/**/*.java"],
-    libs: [
-        "androidx.annotation_annotation",
-    ],
-    sdk_version: "system_current",
-}
-
-java_defaults {
-    name: "NetworkStackCommon",
-    sdk_version: "system_current",
-    min_sdk_version: "28",
-}
-
-// Library including the network stack, used to compile both variants of the network stack
-android_library {
-    name: "NetworkStackBase",
-    defaults: ["NetworkStackCommon"],
-    srcs: [
-        "src/**/*.java",
-        ":framework-networkstack-shared-srcs",
-        ":services-networkstack-shared-srcs",
-        ":statslog-networkstack-java-gen",
-    ],
-    static_libs: [
-        "androidx.annotation_annotation",
-        "ipmemorystore-client",
-        "netd_aidl_interface-V2-java",
-        "networkstack-aidl-interfaces-V3-java",
-        "datastallprotosnano",
-        "networkstackprotosnano",
-        "captiveportal-lib",
-    ],
-    manifest: "AndroidManifestBase.xml",
-}
-
-cc_library_shared {
-    name: "libnetworkstackutilsjni",
-    srcs: [
-        "jni/network_stack_utils_jni.cpp"
-    ],
-    sdk_version: "current",
-    shared_libs: [
-        "liblog",
-        "libnativehelper_compat_libc++",
-    ],
-
-    // We cannot use plain "libc++" here to link libc++ dynamically because it results in:
-    //   java.lang.UnsatisfiedLinkError: dlopen failed: library "libc++_shared.so" not found
-    // even if "libc++" is added into jni_libs below. Adding "libc++_shared" into jni_libs doesn't
-    // build because soong complains of:
-    //   module NetworkStack missing dependencies: libc++_shared
-    //
-    // So, link libc++ statically. This means that we also need to ensure that all the C++ libraries
-    // we depend on do not dynamically link libc++. This is currently the case, because liblog is
-    // C-only and libnativehelper_compat_libc also uses stl: "c++_static".
-    //
-    // TODO: find a better solution for this in R.
-    stl: "c++_static",
-    cflags: [
-        "-Wall",
-        "-Werror",
-        "-Wno-unused-parameter",
-    ],
-}
-
-java_defaults {
-    name: "NetworkStackAppCommon",
-    defaults: ["NetworkStackCommon"],
-    privileged: true,
-    static_libs: [
-        "NetworkStackBase",
-    ],
-    jni_libs: [
-        "libnativehelper_compat_libc++",
-        "libnetworkstackutilsjni",
-    ],
-    // Resources already included in NetworkStackBase
-    resource_dirs: [],
-    jarjar_rules: "jarjar-rules-shared.txt",
-    optimize: {
-        proguard_flags_files: ["proguard.flags"],
-    },
-}
-
-// Non-updatable network stack running in the system server process for devices not using the module
-android_app {
-    name: "InProcessNetworkStack",
-    defaults: ["NetworkStackAppCommon"],
-    certificate: "platform",
-    manifest: "AndroidManifest_InProcess.xml",
-    // InProcessNetworkStack is a replacement for NetworkStack
-    overrides: ["NetworkStack"],
-    // The permission configuration *must* be included to ensure security of the device
-    // The InProcessNetworkStack goes together with the PlatformCaptivePortalLogin, which replaces
-    // the default CaptivePortalLogin.
-    required: ["PlatformNetworkPermissionConfig", "PlatformCaptivePortalLogin"],
-}
-
-// Updatable network stack packaged as an application
-android_app {
-    name: "NetworkStack",
-    defaults: ["NetworkStackAppCommon"],
-    certificate: "networkstack",
-    manifest: "AndroidManifest.xml",
-    use_embedded_native_libs: true,
-    // The permission configuration *must* be included to ensure security of the device
-    required: ["NetworkPermissionConfig"],
-}
-
-genrule {
-    name: "statslog-networkstack-java-gen",
-    tools: ["stats-log-api-gen"],
-    cmd: "$(location stats-log-api-gen) --java $(out) --module network_stack" +
-         " --javaPackage com.android.networkstack.metrics --javaClass NetworkStackStatsLog",
-    out: ["com/android/networkstack/metrics/NetworkStackStatsLog.java"],
-}
diff --git a/packages/NetworkStack/AndroidManifest.xml b/packages/NetworkStack/AndroidManifest.xml
deleted file mode 100644
index 6166c66..0000000
--- a/packages/NetworkStack/AndroidManifest.xml
+++ /dev/null
@@ -1,56 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-/*
- * Copyright (C) 2019 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
--->
-<manifest xmlns:android="http://schemas.android.com/apk/res/android"
-  package="com.android.networkstack"
-  android:sharedUserId="android.uid.networkstack"
-  android:versionCode="220000000"
-  android:versionName="29 system image"
->
-
-    <uses-sdk android:minSdkVersion="28" android:targetSdkVersion="28" />
-
-    <!-- Permissions must be defined here, and not in the base manifest, as the network stack
-         running in the system server process does not need any permission, and having privileged
-         permissions added would cause crashes on startup unless they are also added to the
-         privileged permissions whitelist for that package. -->
-    <uses-permission android:name="android.permission.INTERNET" />
-    <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
-    <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
-    <uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
-    <uses-permission android:name="android.permission.CONNECTIVITY_INTERNAL" />
-    <!-- Send latency broadcast as current user -->
-    <uses-permission android:name="android.permission.INTERACT_ACROSS_USERS" />
-    <uses-permission android:name="android.permission.WAKE_LOCK" />
-    <uses-permission android:name="android.permission.READ_PRIVILEGED_PHONE_STATE" />
-    <uses-permission android:name="android.permission.READ_DEVICE_CONFIG" />
-    <!-- Signature permission defined in NetworkStackStub -->
-    <uses-permission android:name="android.permission.MAINLINE_NETWORK_STACK" />
-    <application
-        android:extractNativeLibs="false"
-        android:persistent="true">
-        <service android:name="com.android.server.NetworkStackService">
-            <intent-filter>
-                <action android:name="android.net.INetworkStackConnector"/>
-            </intent-filter>
-        </service>
-        <service android:name="com.android.server.connectivity.ipmemorystore.RegularMaintenanceJobService"
-                 android:permission="android.permission.BIND_JOB_SERVICE" >
-        </service>
-    </application>
-</manifest>
diff --git a/packages/NetworkStack/AndroidManifestBase.xml b/packages/NetworkStack/AndroidManifestBase.xml
deleted file mode 100644
index 69a4da4..0000000
--- a/packages/NetworkStack/AndroidManifestBase.xml
+++ /dev/null
@@ -1,29 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-/*
- * Copyright (C) 2019 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
--->
-<manifest xmlns:android="http://schemas.android.com/apk/res/android"
-          package="com.android.networkstack"
-          android:versionCode="11"
-          android:versionName="Q-initial">
-    <application
-        android:label="NetworkStack"
-        android:defaultToDeviceProtectedStorage="true"
-        android:directBootAware="true"
-        android:usesCleartextTraffic="true">
-    </application>
-</manifest>
diff --git a/packages/NetworkStack/AndroidManifest_InProcess.xml b/packages/NetworkStack/AndroidManifest_InProcess.xml
deleted file mode 100644
index 2778a2a..0000000
--- a/packages/NetworkStack/AndroidManifest_InProcess.xml
+++ /dev/null
@@ -1,35 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-/*
- * Copyright (C) 2019 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
--->
-<manifest xmlns:android="http://schemas.android.com/apk/res/android"
-          package="com.android.networkstack.inprocess"
-          android:sharedUserId="android.uid.system"
-          android:process="system">
-    <uses-sdk android:minSdkVersion="28" android:targetSdkVersion="28" />
-    <application>
-        <service android:name="com.android.server.NetworkStackService" android:process="system">
-            <intent-filter>
-                <action android:name="android.net.INetworkStackConnector.InProcess"/>
-            </intent-filter>
-        </service>
-        <service android:name="com.android.server.connectivity.ipmemorystore.RegularMaintenanceJobService"
-                 android:process="system"
-                 android:permission="android.permission.BIND_JOB_SERVICE" >
-        </service>
-    </application>
-</manifest>
diff --git a/packages/NetworkStack/OWNERS b/packages/NetworkStack/OWNERS
deleted file mode 100644
index 52193eb..0000000
--- a/packages/NetworkStack/OWNERS
+++ /dev/null
@@ -1,5 +0,0 @@
-set noparent
-
-lorenzo@google.com
-baligh@google.com
-delphij@google.com
diff --git a/packages/NetworkStack/TEST_MAPPING b/packages/NetworkStack/TEST_MAPPING
deleted file mode 100644
index fe9731fe..0000000
--- a/packages/NetworkStack/TEST_MAPPING
+++ /dev/null
@@ -1,7 +0,0 @@
-{
-  "presubmit": [
-    {
-      "name": "NetworkStackTests"
-    }
-  ]
-}
\ No newline at end of file
diff --git a/packages/NetworkStack/common/CaptivePortalProbeResult.java b/packages/NetworkStack/common/CaptivePortalProbeResult.java
deleted file mode 100644
index 48cd48b..0000000
--- a/packages/NetworkStack/common/CaptivePortalProbeResult.java
+++ /dev/null
@@ -1,88 +0,0 @@
-/*
- * Copyright (C) 2018 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.net.captiveportal;
-
-import androidx.annotation.NonNull;
-import androidx.annotation.Nullable;
-
-/**
- * Result of calling isCaptivePortal().
- * @hide
- */
-public final class CaptivePortalProbeResult {
-    public static final int SUCCESS_CODE = 204;
-    public static final int FAILED_CODE = 599;
-    public static final int PORTAL_CODE = 302;
-    // Set partial connectivity http response code to -1 to prevent conflict with the other http
-    // response codes. Besides the default http response code of probe result is set as 599 in
-    // NetworkMonitor#sendParallelHttpProbes(), so response code will be set as -1 only when
-    // NetworkMonitor detects partial connectivity.
-    /**
-     * @hide
-     */
-    public static final int PARTIAL_CODE = -1;
-
-    @NonNull
-    public static final CaptivePortalProbeResult FAILED = new CaptivePortalProbeResult(FAILED_CODE);
-    @NonNull
-    public static final CaptivePortalProbeResult SUCCESS =
-            new CaptivePortalProbeResult(SUCCESS_CODE);
-    public static final CaptivePortalProbeResult PARTIAL =
-            new CaptivePortalProbeResult(PARTIAL_CODE);
-
-    private final int mHttpResponseCode;  // HTTP response code returned from Internet probe.
-    @Nullable
-    public final String redirectUrl;      // Redirect destination returned from Internet probe.
-    @Nullable
-    public final String detectUrl;        // URL where a 204 response code indicates
-                                          // captive portal has been appeased.
-    @Nullable
-    public final CaptivePortalProbeSpec probeSpec;
-
-    public CaptivePortalProbeResult(int httpResponseCode) {
-        this(httpResponseCode, null, null);
-    }
-
-    public CaptivePortalProbeResult(int httpResponseCode, @Nullable String redirectUrl,
-            @Nullable String detectUrl) {
-        this(httpResponseCode, redirectUrl, detectUrl, null);
-    }
-
-    public CaptivePortalProbeResult(int httpResponseCode, @Nullable String redirectUrl,
-            @Nullable String detectUrl, @Nullable CaptivePortalProbeSpec probeSpec) {
-        mHttpResponseCode = httpResponseCode;
-        this.redirectUrl = redirectUrl;
-        this.detectUrl = detectUrl;
-        this.probeSpec = probeSpec;
-    }
-
-    public boolean isSuccessful() {
-        return mHttpResponseCode == SUCCESS_CODE;
-    }
-
-    public boolean isPortal() {
-        return !isSuccessful() && (mHttpResponseCode >= 200) && (mHttpResponseCode <= 399);
-    }
-
-    public boolean isFailed() {
-        return !isSuccessful() && !isPortal();
-    }
-
-    public boolean isPartialConnectivity() {
-        return mHttpResponseCode == PARTIAL_CODE;
-    }
-}
diff --git a/packages/NetworkStack/common/CaptivePortalProbeSpec.java b/packages/NetworkStack/common/CaptivePortalProbeSpec.java
deleted file mode 100644
index bf983a5..0000000
--- a/packages/NetworkStack/common/CaptivePortalProbeSpec.java
+++ /dev/null
@@ -1,195 +0,0 @@
-/*
- * Copyright (C) 2018 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.net.captiveportal;
-
-import static android.net.captiveportal.CaptivePortalProbeResult.PORTAL_CODE;
-import static android.net.captiveportal.CaptivePortalProbeResult.SUCCESS_CODE;
-
-import android.text.TextUtils;
-import android.util.Log;
-
-import androidx.annotation.NonNull;
-import androidx.annotation.Nullable;
-import androidx.annotation.VisibleForTesting;
-
-import java.net.MalformedURLException;
-import java.net.URL;
-import java.text.ParseException;
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.List;
-import java.util.regex.Pattern;
-import java.util.regex.PatternSyntaxException;
-
-/** @hide */
-public abstract class CaptivePortalProbeSpec {
-    private static final String TAG = CaptivePortalProbeSpec.class.getSimpleName();
-    private static final String REGEX_SEPARATOR = "@@/@@";
-    private static final String SPEC_SEPARATOR = "@@,@@";
-
-    private final String mEncodedSpec;
-    private final URL mUrl;
-
-    CaptivePortalProbeSpec(@NonNull String encodedSpec, @NonNull URL url) {
-        mEncodedSpec = checkNotNull(encodedSpec);
-        mUrl = checkNotNull(url);
-    }
-
-    /**
-     * Parse a {@link CaptivePortalProbeSpec} from a {@link String}.
-     *
-     * <p>The valid format is a URL followed by two regular expressions, each separated by "@@/@@".
-     * @throws MalformedURLException The URL has invalid format for {@link URL#URL(String)}.
-     * @throws ParseException The string is empty, does not match the above format, or a regular
-     * expression is invalid for {@link Pattern#compile(String)}.
-     * @hide
-     */
-    @VisibleForTesting
-    @NonNull
-    public static CaptivePortalProbeSpec parseSpec(@NonNull String spec) throws ParseException,
-            MalformedURLException {
-        if (TextUtils.isEmpty(spec)) {
-            throw new ParseException("Empty probe spec", 0 /* errorOffset */);
-        }
-
-        String[] splits = TextUtils.split(spec, REGEX_SEPARATOR);
-        if (splits.length != 3) {
-            throw new ParseException("Probe spec does not have 3 parts", 0 /* errorOffset */);
-        }
-
-        final int statusRegexPos = splits[0].length() + REGEX_SEPARATOR.length();
-        final int locationRegexPos = statusRegexPos + splits[1].length() + REGEX_SEPARATOR.length();
-        final Pattern statusRegex = parsePatternIfNonEmpty(splits[1], statusRegexPos);
-        final Pattern locationRegex = parsePatternIfNonEmpty(splits[2], locationRegexPos);
-
-        return new RegexMatchProbeSpec(spec, new URL(splits[0]), statusRegex, locationRegex);
-    }
-
-    @Nullable
-    private static Pattern parsePatternIfNonEmpty(@Nullable String pattern, int pos)
-            throws ParseException {
-        if (TextUtils.isEmpty(pattern)) {
-            return null;
-        }
-        try {
-            return Pattern.compile(pattern);
-        } catch (PatternSyntaxException e) {
-            throw new ParseException(
-                    String.format("Invalid status pattern [%s]: %s", pattern, e),
-                    pos /* errorOffset */);
-        }
-    }
-
-    /**
-     * Parse a {@link CaptivePortalProbeSpec} from a {@link String}, or return a fallback spec
-     * based on the status code of the provided URL if the spec cannot be parsed.
-     */
-    @Nullable
-    public static CaptivePortalProbeSpec parseSpecOrNull(@Nullable String spec) {
-        if (spec != null) {
-            try {
-                return parseSpec(spec);
-            } catch (ParseException | MalformedURLException e) {
-                Log.e(TAG, "Invalid probe spec: " + spec, e);
-                // Fall through
-            }
-        }
-        return null;
-    }
-
-    /**
-     * Parse a config String to build an array of {@link CaptivePortalProbeSpec}.
-     *
-     * <p>Each spec is separated by @@,@@ and follows the format for {@link #parseSpec(String)}.
-     * <p>This method does not throw but ignores any entry that could not be parsed.
-     */
-    @NonNull
-    public static Collection<CaptivePortalProbeSpec> parseCaptivePortalProbeSpecs(
-            @NonNull String settingsVal) {
-        List<CaptivePortalProbeSpec> specs = new ArrayList<>();
-        if (settingsVal != null) {
-            for (String spec : TextUtils.split(settingsVal, SPEC_SEPARATOR)) {
-                try {
-                    specs.add(parseSpec(spec));
-                } catch (ParseException | MalformedURLException e) {
-                    Log.e(TAG, "Invalid probe spec: " + spec, e);
-                }
-            }
-        }
-
-        if (specs.isEmpty()) {
-            Log.e(TAG, String.format("could not create any validation spec from %s", settingsVal));
-        }
-        return specs;
-    }
-
-    /**
-     * Get the probe result from HTTP status and location header.
-     */
-    @NonNull
-    public abstract CaptivePortalProbeResult getResult(int status, @Nullable String locationHeader);
-
-    @NonNull
-    public String getEncodedSpec() {
-        return mEncodedSpec;
-    }
-
-    @NonNull
-    public URL getUrl() {
-        return mUrl;
-    }
-
-    /**
-     * Implementation of {@link CaptivePortalProbeSpec} that is based on configurable regular
-     * expressions for the HTTP status code and location header (if any). Matches indicate that
-     * the page is not a portal.
-     * This probe cannot fail: it always returns SUCCESS_CODE or PORTAL_CODE
-     */
-    private static class RegexMatchProbeSpec extends CaptivePortalProbeSpec {
-        @Nullable
-        final Pattern mStatusRegex;
-        @Nullable
-        final Pattern mLocationHeaderRegex;
-
-        RegexMatchProbeSpec(
-                String spec, URL url, Pattern statusRegex, Pattern locationHeaderRegex) {
-            super(spec, url);
-            mStatusRegex = statusRegex;
-            mLocationHeaderRegex = locationHeaderRegex;
-        }
-
-        @Override
-        public CaptivePortalProbeResult getResult(int status, String locationHeader) {
-            final boolean statusMatch = safeMatch(String.valueOf(status), mStatusRegex);
-            final boolean locationMatch = safeMatch(locationHeader, mLocationHeaderRegex);
-            final int returnCode = statusMatch && locationMatch ? SUCCESS_CODE : PORTAL_CODE;
-            return new CaptivePortalProbeResult(
-                    returnCode, locationHeader, getUrl().toString(), this);
-        }
-    }
-
-    private static boolean safeMatch(@Nullable String value, @Nullable Pattern pattern) {
-        // No value is a match ("no location header" passes the location rule for non-redirects)
-        return pattern == null || TextUtils.isEmpty(value) || pattern.matcher(value).matches();
-    }
-
-    // Throws NullPointerException if the input is null.
-    private static <T> T checkNotNull(T object) {
-        if (object == null) throw new NullPointerException();
-        return object;
-    }
-}
diff --git a/packages/NetworkStack/jarjar-rules-shared.txt b/packages/NetworkStack/jarjar-rules-shared.txt
deleted file mode 100644
index 7346b1a..0000000
--- a/packages/NetworkStack/jarjar-rules-shared.txt
+++ /dev/null
@@ -1,10 +0,0 @@
-rule com.android.internal.util.** android.net.networkstack.util.@1
-
-rule android.net.shared.Inet4AddressUtils* android.net.networkstack.shared.Inet4AddressUtils@1
-rule android.net.shared.InetAddressUtils* android.net.networkstack.shared.InetAddressUtils@1
-
-# Ignore DhcpResultsParcelable, but jarjar DhcpResults
-# TODO: move DhcpResults into services.net and delete from here
-rule android.net.DhcpResultsParcelable* @0
-rule android.net.DhcpResults* android.net.networkstack.DhcpResults@1
-rule android.net.LocalLog* android.net.networkstack.LocalLog@1
diff --git a/packages/NetworkStack/jni/network_stack_utils_jni.cpp b/packages/NetworkStack/jni/network_stack_utils_jni.cpp
deleted file mode 100644
index f2ba575..0000000
--- a/packages/NetworkStack/jni/network_stack_utils_jni.cpp
+++ /dev/null
@@ -1,264 +0,0 @@
-/*
- * Copyright 2019, The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#define LOG_TAG "NetworkStackUtils-JNI"
-
-#include <errno.h>
-#include <jni.h>
-#include <linux/filter.h>
-#include <linux/if_arp.h>
-#include <net/if.h>
-#include <netinet/ether.h>
-#include <netinet/icmp6.h>
-#include <netinet/ip.h>
-#include <netinet/ip6.h>
-#include <netinet/udp.h>
-#include <stdlib.h>
-
-#include <string>
-
-#include <nativehelper/JNIHelp.h>
-#include <android/log.h>
-
-namespace android {
-constexpr const char NETWORKSTACKUTILS_PKG_NAME[] = "android/net/util/NetworkStackUtils";
-
-static const uint32_t kEtherTypeOffset = offsetof(ether_header, ether_type);
-static const uint32_t kEtherHeaderLen = sizeof(ether_header);
-static const uint32_t kIPv4Protocol = kEtherHeaderLen + offsetof(iphdr, protocol);
-static const uint32_t kIPv4FlagsOffset = kEtherHeaderLen + offsetof(iphdr, frag_off);
-static const uint32_t kIPv6NextHeader = kEtherHeaderLen + offsetof(ip6_hdr, ip6_nxt);
-static const uint32_t kIPv6PayloadStart = kEtherHeaderLen + sizeof(ip6_hdr);
-static const uint32_t kICMPv6TypeOffset = kIPv6PayloadStart + offsetof(icmp6_hdr, icmp6_type);
-static const uint32_t kUDPSrcPortIndirectOffset = kEtherHeaderLen + offsetof(udphdr, source);
-static const uint32_t kUDPDstPortIndirectOffset = kEtherHeaderLen + offsetof(udphdr, dest);
-static const uint16_t kDhcpClientPort = 68;
-
-static bool checkLenAndCopy(JNIEnv* env, const jbyteArray& addr, int len, void* dst) {
-    if (env->GetArrayLength(addr) != len) {
-        return false;
-    }
-    env->GetByteArrayRegion(addr, 0, len, reinterpret_cast<jbyte*>(dst));
-    return true;
-}
-
-static void network_stack_utils_addArpEntry(JNIEnv *env, jobject thiz, jbyteArray ethAddr,
-        jbyteArray ipv4Addr, jstring ifname, jobject javaFd) {
-    arpreq req = {};
-    sockaddr_in& netAddrStruct = *reinterpret_cast<sockaddr_in*>(&req.arp_pa);
-    sockaddr& ethAddrStruct = req.arp_ha;
-
-    ethAddrStruct.sa_family = ARPHRD_ETHER;
-    if (!checkLenAndCopy(env, ethAddr, ETH_ALEN, ethAddrStruct.sa_data)) {
-        jniThrowException(env, "java/io/IOException", "Invalid ethAddr length");
-        return;
-    }
-
-    netAddrStruct.sin_family = AF_INET;
-    if (!checkLenAndCopy(env, ipv4Addr, sizeof(in_addr), &netAddrStruct.sin_addr)) {
-        jniThrowException(env, "java/io/IOException", "Invalid ipv4Addr length");
-        return;
-    }
-
-    int ifLen = env->GetStringLength(ifname);
-    // IFNAMSIZ includes the terminating NULL character
-    if (ifLen >= IFNAMSIZ) {
-        jniThrowException(env, "java/io/IOException", "ifname too long");
-        return;
-    }
-    env->GetStringUTFRegion(ifname, 0, ifLen, req.arp_dev);
-
-    req.arp_flags = ATF_COM;  // Completed entry (ha valid)
-    int fd = jniGetFDFromFileDescriptor(env, javaFd);
-    if (fd < 0) {
-        jniThrowExceptionFmt(env, "java/io/IOException", "Invalid file descriptor");
-        return;
-    }
-    // See also: man 7 arp
-    if (ioctl(fd, SIOCSARP, &req)) {
-        jniThrowExceptionFmt(env, "java/io/IOException", "ioctl error: %s", strerror(errno));
-        return;
-    }
-}
-
-static void network_stack_utils_attachDhcpFilter(JNIEnv *env, jobject clazz, jobject javaFd) {
-    static sock_filter filter_code[] = {
-        // Check the protocol is UDP.
-        BPF_STMT(BPF_LD  | BPF_B    | BPF_ABS, kIPv4Protocol),
-        BPF_JUMP(BPF_JMP | BPF_JEQ  | BPF_K,   IPPROTO_UDP, 0, 6),
-
-        // Check this is not a fragment.
-        BPF_STMT(BPF_LD  | BPF_H    | BPF_ABS, kIPv4FlagsOffset),
-        BPF_JUMP(BPF_JMP | BPF_JSET | BPF_K,   IP_OFFMASK, 4, 0),
-
-        // Get the IP header length.
-        BPF_STMT(BPF_LDX | BPF_B    | BPF_MSH, kEtherHeaderLen),
-
-        // Check the destination port.
-        BPF_STMT(BPF_LD  | BPF_H    | BPF_IND, kUDPDstPortIndirectOffset),
-        BPF_JUMP(BPF_JMP | BPF_JEQ  | BPF_K,   kDhcpClientPort, 0, 1),
-
-        // Accept or reject.
-        BPF_STMT(BPF_RET | BPF_K,              0xffff),
-        BPF_STMT(BPF_RET | BPF_K,              0)
-    };
-    static const sock_fprog filter = {
-        sizeof(filter_code) / sizeof(filter_code[0]),
-        filter_code,
-    };
-
-    int fd = jniGetFDFromFileDescriptor(env, javaFd);
-    if (setsockopt(fd, SOL_SOCKET, SO_ATTACH_FILTER, &filter, sizeof(filter)) != 0) {
-        jniThrowExceptionFmt(env, "java/net/SocketException",
-                "setsockopt(SO_ATTACH_FILTER): %s", strerror(errno));
-    }
-}
-
-static void network_stack_utils_attachRaFilter(JNIEnv *env, jobject clazz, jobject javaFd,
-        jint hardwareAddressType) {
-    if (hardwareAddressType != ARPHRD_ETHER) {
-        jniThrowExceptionFmt(env, "java/net/SocketException",
-                "attachRaFilter only supports ARPHRD_ETHER");
-        return;
-    }
-
-    static sock_filter filter_code[] = {
-        // Check IPv6 Next Header is ICMPv6.
-        BPF_STMT(BPF_LD  | BPF_B   | BPF_ABS,  kIPv6NextHeader),
-        BPF_JUMP(BPF_JMP | BPF_JEQ | BPF_K,    IPPROTO_ICMPV6, 0, 3),
-
-        // Check ICMPv6 type is Router Advertisement.
-        BPF_STMT(BPF_LD  | BPF_B   | BPF_ABS,  kICMPv6TypeOffset),
-        BPF_JUMP(BPF_JMP | BPF_JEQ | BPF_K,    ND_ROUTER_ADVERT, 0, 1),
-
-        // Accept or reject.
-        BPF_STMT(BPF_RET | BPF_K,              0xffff),
-        BPF_STMT(BPF_RET | BPF_K,              0)
-    };
-    static const sock_fprog filter = {
-        sizeof(filter_code) / sizeof(filter_code[0]),
-        filter_code,
-    };
-
-    int fd = jniGetFDFromFileDescriptor(env, javaFd);
-    if (setsockopt(fd, SOL_SOCKET, SO_ATTACH_FILTER, &filter, sizeof(filter)) != 0) {
-        jniThrowExceptionFmt(env, "java/net/SocketException",
-                "setsockopt(SO_ATTACH_FILTER): %s", strerror(errno));
-    }
-}
-
-// TODO: Move all this filter code into libnetutils.
-static void network_stack_utils_attachControlPacketFilter(
-        JNIEnv *env, jobject clazz, jobject javaFd, jint hardwareAddressType) {
-    if (hardwareAddressType != ARPHRD_ETHER) {
-        jniThrowExceptionFmt(env, "java/net/SocketException",
-                "attachControlPacketFilter only supports ARPHRD_ETHER");
-        return;
-    }
-
-    // Capture all:
-    //     - ARPs
-    //     - DHCPv4 packets
-    //     - Router Advertisements & Solicitations
-    //     - Neighbor Advertisements & Solicitations
-    //
-    // tcpdump:
-    //     arp or
-    //     '(ip and udp port 68)' or
-    //     '(icmp6 and ip6[40] >= 133 and ip6[40] <= 136)'
-    static sock_filter filter_code[] = {
-        // Load the link layer next payload field.
-        BPF_STMT(BPF_LD  | BPF_H    | BPF_ABS,  kEtherTypeOffset),
-
-        // Accept all ARP.
-        // TODO: Figure out how to better filter ARPs on noisy networks.
-        BPF_JUMP(BPF_JMP | BPF_JEQ  | BPF_K,   ETHERTYPE_ARP, 16, 0),
-
-        // If IPv4:
-        BPF_JUMP(BPF_JMP | BPF_JEQ  | BPF_K,   ETHERTYPE_IP, 0, 9),
-
-        // Check the protocol is UDP.
-        BPF_STMT(BPF_LD  | BPF_B    | BPF_ABS, kIPv4Protocol),
-        BPF_JUMP(BPF_JMP | BPF_JEQ  | BPF_K,   IPPROTO_UDP, 0, 14),
-
-        // Check this is not a fragment.
-        BPF_STMT(BPF_LD  | BPF_H    | BPF_ABS, kIPv4FlagsOffset),
-        BPF_JUMP(BPF_JMP | BPF_JSET | BPF_K,   IP_OFFMASK, 12, 0),
-
-        // Get the IP header length.
-        BPF_STMT(BPF_LDX | BPF_B    | BPF_MSH, kEtherHeaderLen),
-
-        // Check the source port.
-        BPF_STMT(BPF_LD  | BPF_H    | BPF_IND, kUDPSrcPortIndirectOffset),
-        BPF_JUMP(BPF_JMP | BPF_JEQ  | BPF_K,   kDhcpClientPort, 8, 0),
-
-        // Check the destination port.
-        BPF_STMT(BPF_LD  | BPF_H    | BPF_IND, kUDPDstPortIndirectOffset),
-        BPF_JUMP(BPF_JMP | BPF_JEQ  | BPF_K,   kDhcpClientPort, 6, 7),
-
-        // IPv6 ...
-        BPF_JUMP(BPF_JMP | BPF_JEQ  | BPF_K,   ETHERTYPE_IPV6, 0, 6),
-        // ... check IPv6 Next Header is ICMPv6 (ignore fragments), ...
-        BPF_STMT(BPF_LD  | BPF_B    | BPF_ABS, kIPv6NextHeader),
-        BPF_JUMP(BPF_JMP | BPF_JEQ  | BPF_K,   IPPROTO_ICMPV6, 0, 4),
-        // ... and check the ICMPv6 type is one of RS/RA/NS/NA.
-        BPF_STMT(BPF_LD  | BPF_B    | BPF_ABS, kICMPv6TypeOffset),
-        BPF_JUMP(BPF_JMP | BPF_JGE  | BPF_K,   ND_ROUTER_SOLICIT, 0, 2),
-        BPF_JUMP(BPF_JMP | BPF_JGT  | BPF_K,   ND_NEIGHBOR_ADVERT, 1, 0),
-
-        // Accept or reject.
-        BPF_STMT(BPF_RET | BPF_K,              0xffff),
-        BPF_STMT(BPF_RET | BPF_K,              0)
-    };
-    static const sock_fprog filter = {
-        sizeof(filter_code) / sizeof(filter_code[0]),
-        filter_code,
-    };
-
-    int fd = jniGetFDFromFileDescriptor(env, javaFd);
-    if (setsockopt(fd, SOL_SOCKET, SO_ATTACH_FILTER, &filter, sizeof(filter)) != 0) {
-        jniThrowExceptionFmt(env, "java/net/SocketException",
-                "setsockopt(SO_ATTACH_FILTER): %s", strerror(errno));
-    }
-}
-
-/*
- * JNI registration.
- */
-static const JNINativeMethod gNetworkStackUtilsMethods[] = {
-    /* name, signature, funcPtr */
-    { "addArpEntry", "([B[BLjava/lang/String;Ljava/io/FileDescriptor;)V", (void*) network_stack_utils_addArpEntry },
-    { "attachDhcpFilter", "(Ljava/io/FileDescriptor;)V", (void*) network_stack_utils_attachDhcpFilter },
-    { "attachRaFilter", "(Ljava/io/FileDescriptor;I)V", (void*) network_stack_utils_attachRaFilter },
-    { "attachControlPacketFilter", "(Ljava/io/FileDescriptor;I)V", (void*) network_stack_utils_attachControlPacketFilter },
-};
-
-extern "C" jint JNI_OnLoad(JavaVM* vm, void*) {
-    JNIEnv *env;
-    if (vm->GetEnv(reinterpret_cast<void**>(&env), JNI_VERSION_1_6) != JNI_OK) {
-        __android_log_print(ANDROID_LOG_ERROR, LOG_TAG, "ERROR: GetEnv failed");
-        return JNI_ERR;
-    }
-
-    if (jniRegisterNativeMethods(env, NETWORKSTACKUTILS_PKG_NAME,
-            gNetworkStackUtilsMethods, NELEM(gNetworkStackUtilsMethods)) < 0) {
-        return JNI_ERR;
-    }
-
-    return JNI_VERSION_1_6;
-
-}
-}; // namespace android
diff --git a/packages/NetworkStack/proguard.flags b/packages/NetworkStack/proguard.flags
deleted file mode 100644
index c60f6c3..0000000
--- a/packages/NetworkStack/proguard.flags
+++ /dev/null
@@ -1,9 +0,0 @@
--keepclassmembers class android.net.ip.IpClient {
-    static final int CMD_*;
-    static final int EVENT_*;
-}
-
--keepclassmembers class android.net.dhcp.DhcpClient {
-    static final int CMD_*;
-    static final int EVENT_*;
-}
diff --git a/packages/NetworkStack/res/values-mcc460/config.xml b/packages/NetworkStack/res/values-mcc460/config.xml
deleted file mode 100644
index fd4a848..0000000
--- a/packages/NetworkStack/res/values-mcc460/config.xml
+++ /dev/null
@@ -1,12 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<resources>
-    <!-- Network validation URL configuration for devices using a Chinese SIM (MCC 460).
-         The below URLs are often whitelisted by captive portals, so they should not be used in the
-         general case as this could degrade the user experience (portals not detected properly).
-         However in China the default URLs are not accessible in general. The below alternatives
-         should allow users to connect to local networks normally. -->
-    <string name="default_captive_portal_https_url" translatable="false">https://connectivitycheck.gstatic.com/generate_204</string>
-    <string-array name="default_captive_portal_fallback_urls" translatable="false">
-        <item>http://www.googleapis.cn/generate_204</item>
-    </string-array>
-</resources>
diff --git a/packages/NetworkStack/res/values/config.xml b/packages/NetworkStack/res/values/config.xml
deleted file mode 100644
index 478ed6b..0000000
--- a/packages/NetworkStack/res/values/config.xml
+++ /dev/null
@@ -1,46 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<resources>
-    <!--
-    OEMs that wish to change the below settings must do so via a runtime resource overlay package
-    and *NOT* by changing this file. This file is part of the NetworkStack mainline module.
-    The overlays must apply to the config_* values, not the default_* values. The default_*
-    values are meant to be the default when no other configuration is specified.
-    -->
-
-    <!-- DNS probe timeout for network validation. Enough for 3 DNS queries 5 seconds apart. -->
-    <integer name="default_captive_portal_dns_probe_timeout">12500</integer>
-
-    <!-- HTTP URL for network validation, to use for detecting captive portals. -->
-    <string name="default_captive_portal_http_url" translatable="false">http://connectivitycheck.gstatic.com/generate_204</string>
-
-    <!-- HTTPS URL for network validation, to use for confirming internet connectivity. -->
-    <string name="default_captive_portal_https_url" translatable="false">https://www.google.com/generate_204</string>
-
-    <!-- List of fallback URLs to use for detecting captive portals. -->
-    <string-array name="default_captive_portal_fallback_urls" translatable="false">
-        <item>http://www.google.com/gen_204</item>
-        <item>http://play.googleapis.com/generate_204</item>
-    </string-array>
-
-    <!-- List of fallback probe specs to use for detecting captive portals.
-         This is an alternative to fallback URLs that provides more flexibility on detection rules.
-         Empty, so unused by default. -->
-    <string-array name="default_captive_portal_fallback_probe_specs" translatable="false">
-    </string-array>
-
-    <!-- Configuration hooks for the above settings.
-         Empty by default but may be overridden by RROs. -->
-    <integer name="config_captive_portal_dns_probe_timeout"></integer>
-    <!--suppress CheckTagEmptyBody: overlayable resource to use as configuration hook -->
-    <string name="config_captive_portal_http_url" translatable="false"></string>
-    <!--suppress CheckTagEmptyBody: overlayable resource to use as configuration hook -->
-    <string name="config_captive_portal_https_url" translatable="false"></string>
-    <string-array name="config_captive_portal_fallback_urls" translatable="false">
-    </string-array>
-    <string-array name="config_captive_portal_fallback_probe_specs" translatable="false">
-    </string-array>
-
-    <!-- Customized default DNS Servers address. -->
-    <string-array name="config_default_dns_servers" translatable="false">
-    </string-array>
-</resources>
diff --git a/packages/NetworkStack/res/values/overlayable.xml b/packages/NetworkStack/res/values/overlayable.xml
deleted file mode 100644
index b9d5337..0000000
--- a/packages/NetworkStack/res/values/overlayable.xml
+++ /dev/null
@@ -1,28 +0,0 @@
-<?xml version="1.0" encoding="utf-8" ?>
-<!-- Copyright (C) 2019 The Android Open Source Project
-
-     Licensed under the Apache License, Version 2.0 (the "License");
-     you may not use this file except in compliance with the License.
-     You may obtain a copy of the License at
-
-          http://www.apache.org/licenses/LICENSE-2.0
-
-     Unless required by applicable law or agreed to in writing, software
-     distributed under the License is distributed on an "AS IS" BASIS,
-     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-     See the License for the specific language governing permissions and
-     limitations under the License.
--->
-<resources xmlns:android="http://schemas.android.com/apk/res/android">
-    <overlayable name="NetworkStackConfig">
-        <policy type="product|system|vendor">
-            <!-- Configuration values for NetworkMonitor -->
-            <item type="integer" name="config_captive_portal_dns_probe_timeout"/>
-            <item type="string" name="config_captive_portal_http_url"/>
-            <item type="string" name="config_captive_portal_https_url"/>
-            <item type="array" name="config_captive_portal_fallback_urls"/>
-            <!-- Configuration value for DhcpResults -->
-            <item type="array" name="config_default_dns_servers"/>
-        </policy>
-    </overlayable>
-</resources>
diff --git a/packages/NetworkStack/src/android/net/NetworkStackIpMemoryStore.java b/packages/NetworkStack/src/android/net/NetworkStackIpMemoryStore.java
deleted file mode 100644
index 41715b2..0000000
--- a/packages/NetworkStack/src/android/net/NetworkStackIpMemoryStore.java
+++ /dev/null
@@ -1,44 +0,0 @@
-/*
- * Copyright (C) 2019 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.net;
-
-import android.annotation.NonNull;
-import android.content.Context;
-
-import java.util.concurrent.ExecutionException;
-import java.util.function.Consumer;
-
-/**
- * service used to communicate with the ip memory store service in network stack,
- * which is running in the same module.
- * @see com.android.server.connectivity.ipmemorystore.IpMemoryStoreService
- * @hide
- */
-public class NetworkStackIpMemoryStore extends IpMemoryStoreClient {
-    @NonNull private final IIpMemoryStore mService;
-
-    public NetworkStackIpMemoryStore(@NonNull final Context context,
-            @NonNull final IIpMemoryStore service) {
-        super(context);
-        mService = service;
-    }
-
-    @Override
-    protected void runWhenServiceReady(Consumer<IIpMemoryStore> cb) throws ExecutionException {
-        cb.accept(mService);
-    }
-}
diff --git a/packages/NetworkStack/src/android/net/apf/ApfFilter.java b/packages/NetworkStack/src/android/net/apf/ApfFilter.java
deleted file mode 100644
index f054319..0000000
--- a/packages/NetworkStack/src/android/net/apf/ApfFilter.java
+++ /dev/null
@@ -1,1981 +0,0 @@
-/*
- * Copyright (C) 2016 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.net.apf;
-
-import static android.net.util.SocketUtils.makePacketSocketAddress;
-import static android.system.OsConstants.AF_PACKET;
-import static android.system.OsConstants.ARPHRD_ETHER;
-import static android.system.OsConstants.ETH_P_ARP;
-import static android.system.OsConstants.ETH_P_IP;
-import static android.system.OsConstants.ETH_P_IPV6;
-import static android.system.OsConstants.IPPROTO_ICMPV6;
-import static android.system.OsConstants.IPPROTO_TCP;
-import static android.system.OsConstants.IPPROTO_UDP;
-import static android.system.OsConstants.SOCK_RAW;
-
-import static com.android.server.util.NetworkStackConstants.ICMPV6_ECHO_REQUEST_TYPE;
-import static com.android.server.util.NetworkStackConstants.ICMPV6_NEIGHBOR_ADVERTISEMENT;
-import static com.android.server.util.NetworkStackConstants.ICMPV6_ROUTER_ADVERTISEMENT;
-import static com.android.server.util.NetworkStackConstants.ICMPV6_ROUTER_SOLICITATION;
-
-import android.annotation.Nullable;
-import android.content.BroadcastReceiver;
-import android.content.Context;
-import android.content.Intent;
-import android.content.IntentFilter;
-import android.net.LinkAddress;
-import android.net.LinkProperties;
-import android.net.NattKeepalivePacketDataParcelable;
-import android.net.TcpKeepalivePacketDataParcelable;
-import android.net.apf.ApfGenerator.IllegalInstructionException;
-import android.net.apf.ApfGenerator.Register;
-import android.net.ip.IpClient.IpClientCallbacksWrapper;
-import android.net.metrics.ApfProgramEvent;
-import android.net.metrics.ApfStats;
-import android.net.metrics.IpConnectivityLog;
-import android.net.metrics.RaEvent;
-import android.net.util.InterfaceParams;
-import android.net.util.NetworkStackUtils;
-import android.os.PowerManager;
-import android.os.SystemClock;
-import android.system.ErrnoException;
-import android.system.Os;
-import android.text.format.DateUtils;
-import android.util.Log;
-import android.util.Pair;
-import android.util.SparseArray;
-
-import com.android.internal.annotations.GuardedBy;
-import com.android.internal.annotations.VisibleForTesting;
-import com.android.internal.util.HexDump;
-import com.android.internal.util.IndentingPrintWriter;
-
-import java.io.FileDescriptor;
-import java.io.IOException;
-import java.net.Inet4Address;
-import java.net.Inet6Address;
-import java.net.InetAddress;
-import java.net.SocketAddress;
-import java.net.SocketException;
-import java.net.UnknownHostException;
-import java.nio.BufferUnderflowException;
-import java.nio.ByteBuffer;
-import java.nio.ByteOrder;
-import java.util.ArrayList;
-import java.util.Arrays;
-
-/**
- * For networks that support packet filtering via APF programs, {@code ApfFilter}
- * listens for IPv6 ICMPv6 router advertisements (RAs) and generates APF programs to
- * filter out redundant duplicate ones.
- *
- * Threading model:
- * A collection of RAs we've received is kept in mRas. Generating APF programs uses mRas to
- * know what RAs to filter for, thus generating APF programs is dependent on mRas.
- * mRas can be accessed by multiple threads:
- * - ReceiveThread, which listens for RAs and adds them to mRas, and generates APF programs.
- * - callers of:
- *    - setMulticastFilter(), which can cause an APF program to be generated.
- *    - dump(), which dumps mRas among other things.
- *    - shutdown(), which clears mRas.
- * So access to mRas is synchronized.
- *
- * @hide
- */
-public class ApfFilter {
-
-    // Helper class for specifying functional filter parameters.
-    public static class ApfConfiguration {
-        public ApfCapabilities apfCapabilities;
-        public boolean multicastFilter;
-        public boolean ieee802_3Filter;
-        public int[] ethTypeBlackList;
-    }
-
-    // Enums describing the outcome of receiving an RA packet.
-    private static enum ProcessRaResult {
-        MATCH,          // Received RA matched a known RA
-        DROPPED,        // Received RA ignored due to MAX_RAS
-        PARSE_ERROR,    // Received RA could not be parsed
-        ZERO_LIFETIME,  // Received RA had 0 lifetime
-        UPDATE_NEW_RA,  // APF program updated for new RA
-        UPDATE_EXPIRY   // APF program updated for expiry
-    }
-
-    /**
-     * APF packet counters.
-     *
-     * Packet counters are 32bit big-endian values, and allocated near the end of the APF data
-     * buffer, using negative byte offsets, where -4 is equivalent to maximumApfProgramSize - 4,
-     * the last writable 32bit word.
-     */
-    @VisibleForTesting
-    public static enum Counter {
-        RESERVED_OOB,  // Points to offset 0 from the end of the buffer (out-of-bounds)
-        TOTAL_PACKETS,
-        PASSED_ARP,
-        PASSED_DHCP,
-        PASSED_IPV4,
-        PASSED_IPV6_NON_ICMP,
-        PASSED_IPV4_UNICAST,
-        PASSED_IPV6_ICMP,
-        PASSED_IPV6_UNICAST_NON_ICMP,
-        PASSED_ARP_NON_IPV4,
-        PASSED_ARP_UNKNOWN,
-        PASSED_ARP_UNICAST_REPLY,
-        PASSED_NON_IP_UNICAST,
-        DROPPED_ETH_BROADCAST,
-        DROPPED_RA,
-        DROPPED_GARP_REPLY,
-        DROPPED_ARP_OTHER_HOST,
-        DROPPED_IPV4_L2_BROADCAST,
-        DROPPED_IPV4_BROADCAST_ADDR,
-        DROPPED_IPV4_BROADCAST_NET,
-        DROPPED_IPV4_MULTICAST,
-        DROPPED_IPV6_ROUTER_SOLICITATION,
-        DROPPED_IPV6_MULTICAST_NA,
-        DROPPED_IPV6_MULTICAST,
-        DROPPED_IPV6_MULTICAST_PING,
-        DROPPED_IPV6_NON_ICMP_MULTICAST,
-        DROPPED_802_3_FRAME,
-        DROPPED_ETHERTYPE_BLACKLISTED,
-        DROPPED_ARP_REPLY_SPA_NO_HOST,
-        DROPPED_IPV4_KEEPALIVE_ACK,
-        DROPPED_IPV6_KEEPALIVE_ACK,
-        DROPPED_IPV4_NATT_KEEPALIVE;
-
-        // Returns the negative byte offset from the end of the APF data segment for
-        // a given counter.
-        public int offset() {
-            return - this.ordinal() * 4;  // Currently, all counters are 32bit long.
-        }
-
-        // Returns the total size of the data segment in bytes.
-        public static int totalSize() {
-            return (Counter.class.getEnumConstants().length - 1) * 4;
-        }
-    }
-
-    /**
-     * When APFv4 is supported, loads R1 with the offset of the specified counter.
-     */
-    private void maybeSetupCounter(ApfGenerator gen, Counter c) {
-        if (mApfCapabilities.hasDataAccess()) {
-            gen.addLoadImmediate(Register.R1, c.offset());
-        }
-    }
-
-    // When APFv4 is supported, these point to the trampolines generated by emitEpilogue().
-    // Otherwise, they're just aliases for PASS_LABEL and DROP_LABEL.
-    private final String mCountAndPassLabel;
-    private final String mCountAndDropLabel;
-
-    // Thread to listen for RAs.
-    @VisibleForTesting
-    class ReceiveThread extends Thread {
-        private final byte[] mPacket = new byte[1514];
-        private final FileDescriptor mSocket;
-        private final long mStart = SystemClock.elapsedRealtime();
-
-        private int mReceivedRas = 0;
-        private int mMatchingRas = 0;
-        private int mDroppedRas = 0;
-        private int mParseErrors = 0;
-        private int mZeroLifetimeRas = 0;
-        private int mProgramUpdates = 0;
-
-        private volatile boolean mStopped;
-
-        public ReceiveThread(FileDescriptor socket) {
-            mSocket = socket;
-        }
-
-        public void halt() {
-            mStopped = true;
-            // Interrupts the read() call the thread is blocked in.
-            NetworkStackUtils.closeSocketQuietly(mSocket);
-        }
-
-        @Override
-        public void run() {
-            log("begin monitoring");
-            while (!mStopped) {
-                try {
-                    int length = Os.read(mSocket, mPacket, 0, mPacket.length);
-                    updateStats(processRa(mPacket, length));
-                } catch (IOException|ErrnoException e) {
-                    if (!mStopped) {
-                        Log.e(TAG, "Read error", e);
-                    }
-                }
-            }
-            logStats();
-        }
-
-        private void updateStats(ProcessRaResult result) {
-            mReceivedRas++;
-            switch(result) {
-                case MATCH:
-                    mMatchingRas++;
-                    return;
-                case DROPPED:
-                    mDroppedRas++;
-                    return;
-                case PARSE_ERROR:
-                    mParseErrors++;
-                    return;
-                case ZERO_LIFETIME:
-                    mZeroLifetimeRas++;
-                    return;
-                case UPDATE_EXPIRY:
-                    mMatchingRas++;
-                    mProgramUpdates++;
-                    return;
-                case UPDATE_NEW_RA:
-                    mProgramUpdates++;
-                    return;
-            }
-        }
-
-        private void logStats() {
-            final long nowMs = SystemClock.elapsedRealtime();
-            synchronized (this) {
-                final ApfStats stats = new ApfStats.Builder()
-                        .setReceivedRas(mReceivedRas)
-                        .setMatchingRas(mMatchingRas)
-                        .setDroppedRas(mDroppedRas)
-                        .setParseErrors(mParseErrors)
-                        .setZeroLifetimeRas(mZeroLifetimeRas)
-                        .setProgramUpdates(mProgramUpdates)
-                        .setDurationMs(nowMs - mStart)
-                        .setMaxProgramSize(mApfCapabilities.maximumApfProgramSize)
-                        .setProgramUpdatesAll(mNumProgramUpdates)
-                        .setProgramUpdatesAllowingMulticast(mNumProgramUpdatesAllowingMulticast)
-                        .build();
-                mMetricsLog.log(stats);
-                logApfProgramEventLocked(nowMs / DateUtils.SECOND_IN_MILLIS);
-            }
-        }
-    }
-
-    private static final String TAG = "ApfFilter";
-    private static final boolean DBG = true;
-    private static final boolean VDBG = false;
-
-    private static final int ETH_HEADER_LEN = 14;
-    private static final int ETH_DEST_ADDR_OFFSET = 0;
-    private static final int ETH_ETHERTYPE_OFFSET = 12;
-    private static final int ETH_TYPE_MIN = 0x0600;
-    private static final int ETH_TYPE_MAX = 0xFFFF;
-    private static final byte[] ETH_BROADCAST_MAC_ADDRESS =
-            {(byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff };
-    // TODO: Make these offsets relative to end of link-layer header; don't include ETH_HEADER_LEN.
-    private static final int IPV4_TOTAL_LENGTH_OFFSET = ETH_HEADER_LEN + 2;
-    private static final int IPV4_FRAGMENT_OFFSET_OFFSET = ETH_HEADER_LEN + 6;
-    // Endianness is not an issue for this constant because the APF interpreter always operates in
-    // network byte order.
-    private static final int IPV4_FRAGMENT_OFFSET_MASK = 0x1fff;
-    private static final int IPV4_PROTOCOL_OFFSET = ETH_HEADER_LEN + 9;
-    private static final int IPV4_DEST_ADDR_OFFSET = ETH_HEADER_LEN + 16;
-    private static final int IPV4_ANY_HOST_ADDRESS = 0;
-    private static final int IPV4_BROADCAST_ADDRESS = -1; // 255.255.255.255
-    private static final int IPV4_HEADER_LEN = 20; // Without options
-
-    // Traffic class and Flow label are not byte aligned. Luckily we
-    // don't care about either value so we'll consider bytes 1-3 of the
-    // IPv6 header as don't care.
-    private static final int IPV6_FLOW_LABEL_OFFSET = ETH_HEADER_LEN + 1;
-    private static final int IPV6_FLOW_LABEL_LEN = 3;
-    private static final int IPV6_NEXT_HEADER_OFFSET = ETH_HEADER_LEN + 6;
-    private static final int IPV6_SRC_ADDR_OFFSET = ETH_HEADER_LEN + 8;
-    private static final int IPV6_DEST_ADDR_OFFSET = ETH_HEADER_LEN + 24;
-    private static final int IPV6_HEADER_LEN = 40;
-    // The IPv6 all nodes address ff02::1
-    private static final byte[] IPV6_ALL_NODES_ADDRESS =
-            { (byte) 0xff, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1 };
-
-    private static final int ICMP6_TYPE_OFFSET = ETH_HEADER_LEN + IPV6_HEADER_LEN;
-
-    // NOTE: this must be added to the IPv4 header length in IPV4_HEADER_SIZE_MEMORY_SLOT
-    private static final int UDP_DESTINATION_PORT_OFFSET = ETH_HEADER_LEN + 2;
-    private static final int UDP_HEADER_LEN = 8;
-
-    private static final int TCP_HEADER_SIZE_OFFSET = 12;
-
-    private static final int DHCP_CLIENT_PORT = 68;
-    // NOTE: this must be added to the IPv4 header length in IPV4_HEADER_SIZE_MEMORY_SLOT
-    private static final int DHCP_CLIENT_MAC_OFFSET = ETH_HEADER_LEN + UDP_HEADER_LEN + 28;
-
-    private static final int ARP_HEADER_OFFSET = ETH_HEADER_LEN;
-    private static final byte[] ARP_IPV4_HEADER = {
-            0, 1, // Hardware type: Ethernet (1)
-            8, 0, // Protocol type: IP (0x0800)
-            6,    // Hardware size: 6
-            4,    // Protocol size: 4
-    };
-    private static final int ARP_OPCODE_OFFSET = ARP_HEADER_OFFSET + 6;
-    // Opcode: ARP request (0x0001), ARP reply (0x0002)
-    private static final short ARP_OPCODE_REQUEST = 1;
-    private static final short ARP_OPCODE_REPLY = 2;
-    private static final int ARP_SOURCE_IP_ADDRESS_OFFSET = ARP_HEADER_OFFSET + 14;
-    private static final int ARP_TARGET_IP_ADDRESS_OFFSET = ARP_HEADER_OFFSET + 24;
-    // Do not log ApfProgramEvents whose actual lifetimes was less than this.
-    private static final int APF_PROGRAM_EVENT_LIFETIME_THRESHOLD = 2;
-    // Limit on the Black List size to cap on program usage for this
-    // TODO: Select a proper max length
-    private static final int APF_MAX_ETH_TYPE_BLACK_LIST_LEN = 20;
-
-    private final ApfCapabilities mApfCapabilities;
-    private final IpClientCallbacksWrapper mIpClientCallback;
-    private final InterfaceParams mInterfaceParams;
-    private final IpConnectivityLog mMetricsLog;
-
-    @VisibleForTesting
-    byte[] mHardwareAddress;
-    @VisibleForTesting
-    ReceiveThread mReceiveThread;
-    @GuardedBy("this")
-    private long mUniqueCounter;
-    @GuardedBy("this")
-    private boolean mMulticastFilter;
-    @GuardedBy("this")
-    private boolean mInDozeMode;
-    private final boolean mDrop802_3Frames;
-    private final int[] mEthTypeBlackList;
-
-    // Detects doze mode state transitions.
-    private final BroadcastReceiver mDeviceIdleReceiver = new BroadcastReceiver() {
-        @Override
-        public void onReceive(Context context, Intent intent) {
-            String action = intent.getAction();
-            if (action.equals(PowerManager.ACTION_DEVICE_IDLE_MODE_CHANGED)) {
-                PowerManager powerManager =
-                        (PowerManager) context.getSystemService(Context.POWER_SERVICE);
-                final boolean deviceIdle = powerManager.isDeviceIdleMode();
-                setDozeMode(deviceIdle);
-            }
-        }
-    };
-    private final Context mContext;
-
-    // Our IPv4 address, if we have just one, otherwise null.
-    @GuardedBy("this")
-    private byte[] mIPv4Address;
-    // The subnet prefix length of our IPv4 network. Only valid if mIPv4Address is not null.
-    @GuardedBy("this")
-    private int mIPv4PrefixLength;
-
-    @VisibleForTesting
-    ApfFilter(Context context, ApfConfiguration config, InterfaceParams ifParams,
-            IpClientCallbacksWrapper ipClientCallback, IpConnectivityLog log) {
-        mApfCapabilities = config.apfCapabilities;
-        mIpClientCallback = ipClientCallback;
-        mInterfaceParams = ifParams;
-        mMulticastFilter = config.multicastFilter;
-        mDrop802_3Frames = config.ieee802_3Filter;
-        mContext = context;
-
-        if (mApfCapabilities.hasDataAccess()) {
-            mCountAndPassLabel = "countAndPass";
-            mCountAndDropLabel = "countAndDrop";
-        } else {
-            // APFv4 unsupported: turn jumps to the counter trampolines to immediately PASS or DROP,
-            // preserving the original pre-APFv4 behavior.
-            mCountAndPassLabel = ApfGenerator.PASS_LABEL;
-            mCountAndDropLabel = ApfGenerator.DROP_LABEL;
-        }
-
-        // Now fill the black list from the passed array
-        mEthTypeBlackList = filterEthTypeBlackList(config.ethTypeBlackList);
-
-        mMetricsLog = log;
-
-        // TODO: ApfFilter should not generate programs until IpClient sends provisioning success.
-        maybeStartFilter();
-
-        // Listen for doze-mode transition changes to enable/disable the IPv6 multicast filter.
-        mContext.registerReceiver(mDeviceIdleReceiver,
-                new IntentFilter(PowerManager.ACTION_DEVICE_IDLE_MODE_CHANGED));
-    }
-
-    public synchronized void setDataSnapshot(byte[] data) {
-        mDataSnapshot = data;
-    }
-
-    private void log(String s) {
-        Log.d(TAG, "(" + mInterfaceParams.name + "): " + s);
-    }
-
-    @GuardedBy("this")
-    private long getUniqueNumberLocked() {
-        return mUniqueCounter++;
-    }
-
-    @GuardedBy("this")
-    private static int[] filterEthTypeBlackList(int[] ethTypeBlackList) {
-        ArrayList<Integer> bl = new ArrayList<Integer>();
-
-        for (int p : ethTypeBlackList) {
-            // Check if the protocol is a valid ether type
-            if ((p < ETH_TYPE_MIN) || (p > ETH_TYPE_MAX)) {
-                continue;
-            }
-
-            // Check if the protocol is not repeated in the passed array
-            if (bl.contains(p)) {
-                continue;
-            }
-
-            // Check if list reach its max size
-            if (bl.size() == APF_MAX_ETH_TYPE_BLACK_LIST_LEN) {
-                Log.w(TAG, "Passed EthType Black List size too large (" + bl.size() +
-                        ") using top " + APF_MAX_ETH_TYPE_BLACK_LIST_LEN + " protocols");
-                break;
-            }
-
-            // Now add the protocol to the list
-            bl.add(p);
-        }
-
-        return bl.stream().mapToInt(Integer::intValue).toArray();
-    }
-
-    /**
-     * Attempt to start listening for RAs and, if RAs are received, generating and installing
-     * filters to ignore useless RAs.
-     */
-    @VisibleForTesting
-    void maybeStartFilter() {
-        FileDescriptor socket;
-        try {
-            mHardwareAddress = mInterfaceParams.macAddr.toByteArray();
-            synchronized(this) {
-                // Clear the APF memory to reset all counters upon connecting to the first AP
-                // in an SSID. This is limited to APFv4 devices because this large write triggers
-                // a crash on some older devices (b/78905546).
-                if (mApfCapabilities.hasDataAccess()) {
-                    byte[] zeroes = new byte[mApfCapabilities.maximumApfProgramSize];
-                    mIpClientCallback.installPacketFilter(zeroes);
-                }
-
-                // Install basic filters
-                installNewProgramLocked();
-            }
-            socket = Os.socket(AF_PACKET, SOCK_RAW, ETH_P_IPV6);
-            SocketAddress addr = makePacketSocketAddress(
-                    (short) ETH_P_IPV6, mInterfaceParams.index);
-            Os.bind(socket, addr);
-            NetworkStackUtils.attachRaFilter(socket, mApfCapabilities.apfPacketFormat);
-        } catch(SocketException|ErrnoException e) {
-            Log.e(TAG, "Error starting filter", e);
-            return;
-        }
-        mReceiveThread = new ReceiveThread(socket);
-        mReceiveThread.start();
-    }
-
-    // Returns seconds since device boot.
-    @VisibleForTesting
-    protected long currentTimeSeconds() {
-        return SystemClock.elapsedRealtime() / DateUtils.SECOND_IN_MILLIS;
-    }
-
-    public static class InvalidRaException extends Exception {
-        public InvalidRaException(String m) {
-            super(m);
-        }
-    }
-
-    // A class to hold information about an RA.
-    @VisibleForTesting
-    class Ra {
-        // From RFC4861:
-        private static final int ICMP6_RA_HEADER_LEN = 16;
-        private static final int ICMP6_RA_CHECKSUM_OFFSET =
-                ETH_HEADER_LEN + IPV6_HEADER_LEN + 2;
-        private static final int ICMP6_RA_CHECKSUM_LEN = 2;
-        private static final int ICMP6_RA_OPTION_OFFSET =
-                ETH_HEADER_LEN + IPV6_HEADER_LEN + ICMP6_RA_HEADER_LEN;
-        private static final int ICMP6_RA_ROUTER_LIFETIME_OFFSET =
-                ETH_HEADER_LEN + IPV6_HEADER_LEN + 6;
-        private static final int ICMP6_RA_ROUTER_LIFETIME_LEN = 2;
-        // Prefix information option.
-        private static final int ICMP6_PREFIX_OPTION_TYPE = 3;
-        private static final int ICMP6_PREFIX_OPTION_LEN = 32;
-        private static final int ICMP6_PREFIX_OPTION_VALID_LIFETIME_OFFSET = 4;
-        private static final int ICMP6_PREFIX_OPTION_VALID_LIFETIME_LEN = 4;
-        private static final int ICMP6_PREFIX_OPTION_PREFERRED_LIFETIME_OFFSET = 8;
-        private static final int ICMP6_PREFIX_OPTION_PREFERRED_LIFETIME_LEN = 4;
-
-        // From RFC6106: Recursive DNS Server option
-        private static final int ICMP6_RDNSS_OPTION_TYPE = 25;
-        // From RFC6106: DNS Search List option
-        private static final int ICMP6_DNSSL_OPTION_TYPE = 31;
-
-        // From RFC4191: Route Information option
-        private static final int ICMP6_ROUTE_INFO_OPTION_TYPE = 24;
-        // Above three options all have the same format:
-        private static final int ICMP6_4_BYTE_LIFETIME_OFFSET = 4;
-        private static final int ICMP6_4_BYTE_LIFETIME_LEN = 4;
-
-        // Note: mPacket's position() cannot be assumed to be reset.
-        private final ByteBuffer mPacket;
-        // List of binary ranges that include the whole packet except the lifetimes.
-        // Pairs consist of offset and length.
-        private final ArrayList<Pair<Integer, Integer>> mNonLifetimes =
-                new ArrayList<Pair<Integer, Integer>>();
-        // Minimum lifetime in packet
-        long mMinLifetime;
-        // When the packet was last captured, in seconds since Unix Epoch
-        long mLastSeen;
-
-        // For debugging only. Offsets into the packet where PIOs are.
-        private final ArrayList<Integer> mPrefixOptionOffsets = new ArrayList<>();
-
-        // For debugging only. Offsets into the packet where RDNSS options are.
-        private final ArrayList<Integer> mRdnssOptionOffsets = new ArrayList<>();
-
-        // For debugging only. How many times this RA was seen.
-        int seenCount = 0;
-
-        // For debugging only. Returns the hex representation of the last matching packet.
-        String getLastMatchingPacket() {
-            return HexDump.toHexString(mPacket.array(), 0, mPacket.capacity(),
-                    false /* lowercase */);
-        }
-
-        // For debugging only. Returns the string representation of the IPv6 address starting at
-        // position pos in the packet.
-        private String IPv6AddresstoString(int pos) {
-            try {
-                byte[] array = mPacket.array();
-                // Can't just call copyOfRange() and see if it throws, because if it reads past the
-                // end it pads with zeros instead of throwing.
-                if (pos < 0 || pos + 16 > array.length || pos + 16 < pos) {
-                    return "???";
-                }
-                byte[] addressBytes = Arrays.copyOfRange(array, pos, pos + 16);
-                InetAddress address = (Inet6Address) InetAddress.getByAddress(addressBytes);
-                return address.getHostAddress();
-            } catch (UnsupportedOperationException e) {
-                // array() failed. Cannot happen, mPacket is array-backed and read-write.
-                return "???";
-            } catch (ClassCastException|UnknownHostException e) {
-                // Cannot happen.
-                return "???";
-            }
-        }
-
-        // Can't be static because it's in a non-static inner class.
-        // TODO: Make this static once RA is its own class.
-        private void prefixOptionToString(StringBuffer sb, int offset) {
-            String prefix = IPv6AddresstoString(offset + 16);
-            int length = getUint8(mPacket, offset + 2);
-            long valid = getUint32(mPacket, offset + 4);
-            long preferred = getUint32(mPacket, offset + 8);
-            sb.append(String.format("%s/%d %ds/%ds ", prefix, length, valid, preferred));
-        }
-
-        private void rdnssOptionToString(StringBuffer sb, int offset) {
-            int optLen = getUint8(mPacket, offset + 1) * 8;
-            if (optLen < 24) return;  // Malformed or empty.
-            long lifetime = getUint32(mPacket, offset + 4);
-            int numServers = (optLen - 8) / 16;
-            sb.append("DNS ").append(lifetime).append("s");
-            for (int server = 0; server < numServers; server++) {
-                sb.append(" ").append(IPv6AddresstoString(offset + 8 + 16 * server));
-            }
-        }
-
-        public String toString() {
-            try {
-                StringBuffer sb = new StringBuffer();
-                sb.append(String.format("RA %s -> %s %ds ",
-                        IPv6AddresstoString(IPV6_SRC_ADDR_OFFSET),
-                        IPv6AddresstoString(IPV6_DEST_ADDR_OFFSET),
-                        getUint16(mPacket, ICMP6_RA_ROUTER_LIFETIME_OFFSET)));
-                for (int i: mPrefixOptionOffsets) {
-                    prefixOptionToString(sb, i);
-                }
-                for (int i: mRdnssOptionOffsets) {
-                    rdnssOptionToString(sb, i);
-                }
-                return sb.toString();
-            } catch (BufferUnderflowException|IndexOutOfBoundsException e) {
-                return "<Malformed RA>";
-            }
-        }
-
-        /**
-         * Add a binary range of the packet that does not include a lifetime to mNonLifetimes.
-         * Assumes mPacket.position() is as far as we've parsed the packet.
-         * @param lastNonLifetimeStart offset within packet of where the last binary range of
-         *                             data not including a lifetime.
-         * @param lifetimeOffset offset from mPacket.position() to the next lifetime data.
-         * @param lifetimeLength length of the next lifetime data.
-         * @return offset within packet of where the next binary range of data not including
-         *         a lifetime. This can be passed into the next invocation of this function
-         *         via {@code lastNonLifetimeStart}.
-         */
-        private int addNonLifetime(int lastNonLifetimeStart, int lifetimeOffset,
-                int lifetimeLength) {
-            lifetimeOffset += mPacket.position();
-            mNonLifetimes.add(new Pair<Integer, Integer>(lastNonLifetimeStart,
-                    lifetimeOffset - lastNonLifetimeStart));
-            return lifetimeOffset + lifetimeLength;
-        }
-
-        private int addNonLifetimeU32(int lastNonLifetimeStart) {
-            return addNonLifetime(lastNonLifetimeStart,
-                    ICMP6_4_BYTE_LIFETIME_OFFSET, ICMP6_4_BYTE_LIFETIME_LEN);
-        }
-
-        // Note that this parses RA and may throw InvalidRaException (from
-        // Buffer.position(int) or due to an invalid-length option) or IndexOutOfBoundsException
-        // (from ByteBuffer.get(int) ) if parsing encounters something non-compliant with
-        // specifications.
-        Ra(byte[] packet, int length) throws InvalidRaException {
-            if (length < ICMP6_RA_OPTION_OFFSET) {
-                throw new InvalidRaException("Not an ICMP6 router advertisement");
-            }
-
-            mPacket = ByteBuffer.wrap(Arrays.copyOf(packet, length));
-            mLastSeen = currentTimeSeconds();
-
-            // Sanity check packet in case a packet arrives before we attach RA filter
-            // to our packet socket. b/29586253
-            if (getUint16(mPacket, ETH_ETHERTYPE_OFFSET) != ETH_P_IPV6 ||
-                    getUint8(mPacket, IPV6_NEXT_HEADER_OFFSET) != IPPROTO_ICMPV6 ||
-                    getUint8(mPacket, ICMP6_TYPE_OFFSET) != ICMPV6_ROUTER_ADVERTISEMENT) {
-                throw new InvalidRaException("Not an ICMP6 router advertisement");
-            }
-
-
-            RaEvent.Builder builder = new RaEvent.Builder();
-
-            // Ignore the flow label and low 4 bits of traffic class.
-            int lastNonLifetimeStart = addNonLifetime(0,
-                    IPV6_FLOW_LABEL_OFFSET,
-                    IPV6_FLOW_LABEL_LEN);
-
-            // Ignore the checksum.
-            lastNonLifetimeStart = addNonLifetime(lastNonLifetimeStart,
-                    ICMP6_RA_CHECKSUM_OFFSET,
-                    ICMP6_RA_CHECKSUM_LEN);
-
-            // Parse router lifetime
-            lastNonLifetimeStart = addNonLifetime(lastNonLifetimeStart,
-                    ICMP6_RA_ROUTER_LIFETIME_OFFSET,
-                    ICMP6_RA_ROUTER_LIFETIME_LEN);
-            builder.updateRouterLifetime(getUint16(mPacket, ICMP6_RA_ROUTER_LIFETIME_OFFSET));
-
-            // Ensures that the RA is not truncated.
-            mPacket.position(ICMP6_RA_OPTION_OFFSET);
-            while (mPacket.hasRemaining()) {
-                final int position = mPacket.position();
-                final int optionType = getUint8(mPacket, position);
-                final int optionLength = getUint8(mPacket, position + 1) * 8;
-                long lifetime;
-                switch (optionType) {
-                    case ICMP6_PREFIX_OPTION_TYPE:
-                        // Parse valid lifetime
-                        lastNonLifetimeStart = addNonLifetime(lastNonLifetimeStart,
-                                ICMP6_PREFIX_OPTION_VALID_LIFETIME_OFFSET,
-                                ICMP6_PREFIX_OPTION_VALID_LIFETIME_LEN);
-                        lifetime = getUint32(mPacket,
-                                position + ICMP6_PREFIX_OPTION_VALID_LIFETIME_OFFSET);
-                        builder.updatePrefixValidLifetime(lifetime);
-                        // Parse preferred lifetime
-                        lastNonLifetimeStart = addNonLifetime(lastNonLifetimeStart,
-                                ICMP6_PREFIX_OPTION_PREFERRED_LIFETIME_OFFSET,
-                                ICMP6_PREFIX_OPTION_PREFERRED_LIFETIME_LEN);
-                        lifetime = getUint32(mPacket,
-                                position + ICMP6_PREFIX_OPTION_PREFERRED_LIFETIME_OFFSET);
-                        builder.updatePrefixPreferredLifetime(lifetime);
-                        mPrefixOptionOffsets.add(position);
-                        break;
-                    // These three options have the same lifetime offset and size, and
-                    // are processed with the same specialized addNonLifetimeU32:
-                    case ICMP6_RDNSS_OPTION_TYPE:
-                        mRdnssOptionOffsets.add(position);
-                        lastNonLifetimeStart = addNonLifetimeU32(lastNonLifetimeStart);
-                        lifetime = getUint32(mPacket, position + ICMP6_4_BYTE_LIFETIME_OFFSET);
-                        builder.updateRdnssLifetime(lifetime);
-                        break;
-                    case ICMP6_ROUTE_INFO_OPTION_TYPE:
-                        lastNonLifetimeStart = addNonLifetimeU32(lastNonLifetimeStart);
-                        lifetime = getUint32(mPacket, position + ICMP6_4_BYTE_LIFETIME_OFFSET);
-                        builder.updateRouteInfoLifetime(lifetime);
-                        break;
-                    case ICMP6_DNSSL_OPTION_TYPE:
-                        lastNonLifetimeStart = addNonLifetimeU32(lastNonLifetimeStart);
-                        lifetime = getUint32(mPacket, position + ICMP6_4_BYTE_LIFETIME_OFFSET);
-                        builder.updateDnsslLifetime(lifetime);
-                        break;
-                    default:
-                        // RFC4861 section 4.2 dictates we ignore unknown options for fowards
-                        // compatibility.
-                        break;
-                }
-                if (optionLength <= 0) {
-                    throw new InvalidRaException(String.format(
-                        "Invalid option length opt=%d len=%d", optionType, optionLength));
-                }
-                mPacket.position(position + optionLength);
-            }
-            // Mark non-lifetime bytes since last lifetime.
-            addNonLifetime(lastNonLifetimeStart, 0, 0);
-            mMinLifetime = minLifetime(packet, length);
-            mMetricsLog.log(builder.build());
-        }
-
-        // Ignoring lifetimes (which may change) does {@code packet} match this RA?
-        boolean matches(byte[] packet, int length) {
-            if (length != mPacket.capacity()) return false;
-            byte[] referencePacket = mPacket.array();
-            for (Pair<Integer, Integer> nonLifetime : mNonLifetimes) {
-                for (int i = nonLifetime.first; i < (nonLifetime.first + nonLifetime.second); i++) {
-                    if (packet[i] != referencePacket[i]) return false;
-                }
-            }
-            return true;
-        }
-
-        // What is the minimum of all lifetimes within {@code packet} in seconds?
-        // Precondition: matches(packet, length) already returned true.
-        long minLifetime(byte[] packet, int length) {
-            long minLifetime = Long.MAX_VALUE;
-            // Wrap packet in ByteBuffer so we can read big-endian values easily
-            ByteBuffer byteBuffer = ByteBuffer.wrap(packet);
-            for (int i = 0; (i + 1) < mNonLifetimes.size(); i++) {
-                int offset = mNonLifetimes.get(i).first + mNonLifetimes.get(i).second;
-
-                // The flow label is in mNonLifetimes, but it's not a lifetime.
-                if (offset == IPV6_FLOW_LABEL_OFFSET) {
-                    continue;
-                }
-
-                // The checksum is in mNonLifetimes, but it's not a lifetime.
-                if (offset == ICMP6_RA_CHECKSUM_OFFSET) {
-                    continue;
-                }
-
-                final int lifetimeLength = mNonLifetimes.get(i+1).first - offset;
-                final long optionLifetime;
-                switch (lifetimeLength) {
-                    case 2:
-                        optionLifetime = getUint16(byteBuffer, offset);
-                        break;
-                    case 4:
-                        optionLifetime = getUint32(byteBuffer, offset);
-                        break;
-                    default:
-                        throw new IllegalStateException("bogus lifetime size " + lifetimeLength);
-                }
-                minLifetime = Math.min(minLifetime, optionLifetime);
-            }
-            return minLifetime;
-        }
-
-        // How many seconds does this RA's have to live, taking into account the fact
-        // that we might have seen it a while ago.
-        long currentLifetime() {
-            return mMinLifetime - (currentTimeSeconds() - mLastSeen);
-        }
-
-        boolean isExpired() {
-            // TODO: We may want to handle 0 lifetime RAs differently, if they are common. We'll
-            // have to calculate the filter lifetime specially as a fraction of 0 is still 0.
-            return currentLifetime() <= 0;
-        }
-
-        // Append a filter for this RA to {@code gen}. Jump to DROP_LABEL if it should be dropped.
-        // Jump to the next filter if packet doesn't match this RA.
-        @GuardedBy("ApfFilter.this")
-        long generateFilterLocked(ApfGenerator gen) throws IllegalInstructionException {
-            String nextFilterLabel = "Ra" + getUniqueNumberLocked();
-            // Skip if packet is not the right size
-            gen.addLoadFromMemory(Register.R0, gen.PACKET_SIZE_MEMORY_SLOT);
-            gen.addJumpIfR0NotEquals(mPacket.capacity(), nextFilterLabel);
-            int filterLifetime = (int)(currentLifetime() / FRACTION_OF_LIFETIME_TO_FILTER);
-            // Skip filter if expired
-            gen.addLoadFromMemory(Register.R0, gen.FILTER_AGE_MEMORY_SLOT);
-            gen.addJumpIfR0GreaterThan(filterLifetime, nextFilterLabel);
-            for (int i = 0; i < mNonLifetimes.size(); i++) {
-                // Generate code to match the packet bytes
-                Pair<Integer, Integer> nonLifetime = mNonLifetimes.get(i);
-                // Don't generate JNEBS instruction for 0 bytes as it always fails the
-                // ASSERT_FORWARD_IN_PROGRAM(pc + cmp_imm - 1) check where cmp_imm is
-                // the number of bytes to compare. nonLifetime is zero between the
-                // valid and preferred lifetimes in the prefix option.
-                if (nonLifetime.second != 0) {
-                    gen.addLoadImmediate(Register.R0, nonLifetime.first);
-                    gen.addJumpIfBytesNotEqual(Register.R0,
-                            Arrays.copyOfRange(mPacket.array(), nonLifetime.first,
-                                               nonLifetime.first + nonLifetime.second),
-                            nextFilterLabel);
-                }
-                // Generate code to test the lifetimes haven't gone down too far
-                if ((i + 1) < mNonLifetimes.size()) {
-                    Pair<Integer, Integer> nextNonLifetime = mNonLifetimes.get(i + 1);
-                    int offset = nonLifetime.first + nonLifetime.second;
-
-                    // Skip the Flow label.
-                    if (offset == IPV6_FLOW_LABEL_OFFSET) {
-                        continue;
-                    }
-                    // Skip the checksum.
-                    if (offset == ICMP6_RA_CHECKSUM_OFFSET) {
-                        continue;
-                    }
-                    int length = nextNonLifetime.first - offset;
-                    switch (length) {
-                        case 4: gen.addLoad32(Register.R0, offset); break;
-                        case 2: gen.addLoad16(Register.R0, offset); break;
-                        default: throw new IllegalStateException("bogus lifetime size " + length);
-                    }
-                    gen.addJumpIfR0LessThan(filterLifetime, nextFilterLabel);
-                }
-            }
-            maybeSetupCounter(gen, Counter.DROPPED_RA);
-            gen.addJump(mCountAndDropLabel);
-            gen.defineLabel(nextFilterLabel);
-            return filterLifetime;
-        }
-    }
-
-    // TODO: Refactor these subclasses to avoid so much repetition.
-    private abstract static class KeepalivePacket {
-        // Note that the offset starts from IP header.
-        // These must be added ether header length when generating program.
-        static final int IP_HEADER_OFFSET = 0;
-        static final int IPV4_SRC_ADDR_OFFSET = IP_HEADER_OFFSET + 12;
-
-        // Append a filter for this keepalive ack to {@code gen}.
-        // Jump to drop if it matches the keepalive ack.
-        // Jump to the next filter if packet doesn't match the keepalive ack.
-        abstract void generateFilterLocked(ApfGenerator gen) throws IllegalInstructionException;
-    }
-
-    // A class to hold NAT-T keepalive ack information.
-    private class NattKeepaliveResponse extends KeepalivePacket {
-        static final int UDP_LENGTH_OFFSET = 4;
-        static final int UDP_HEADER_LEN = 8;
-
-        protected class NattKeepaliveResponseData {
-            public final byte[] srcAddress;
-            public final int srcPort;
-            public final byte[] dstAddress;
-            public final int dstPort;
-
-            NattKeepaliveResponseData(final NattKeepalivePacketDataParcelable sentKeepalivePacket) {
-                srcAddress = sentKeepalivePacket.dstAddress;
-                srcPort = sentKeepalivePacket.dstPort;
-                dstAddress = sentKeepalivePacket.srcAddress;
-                dstPort = sentKeepalivePacket.srcPort;
-            }
-        }
-
-        protected final NattKeepaliveResponseData mPacket;
-        protected final byte[] mSrcDstAddr;
-        protected final byte[] mPortFingerprint;
-        // NAT-T keepalive packet
-        protected final byte[] mPayload = {(byte) 0xff};
-
-        NattKeepaliveResponse(final NattKeepalivePacketDataParcelable sentKeepalivePacket) {
-            mPacket = new NattKeepaliveResponseData(sentKeepalivePacket);
-            mSrcDstAddr = concatArrays(mPacket.srcAddress, mPacket.dstAddress);
-            mPortFingerprint = generatePortFingerprint(mPacket.srcPort, mPacket.dstPort);
-        }
-
-        byte[] generatePortFingerprint(int srcPort, int dstPort) {
-            final ByteBuffer fp = ByteBuffer.allocate(4);
-            fp.order(ByteOrder.BIG_ENDIAN);
-            fp.putShort((short) srcPort);
-            fp.putShort((short) dstPort);
-            return fp.array();
-        }
-
-        @Override
-        void generateFilterLocked(ApfGenerator gen) throws IllegalInstructionException {
-            final String nextFilterLabel = "natt_keepalive_filter" + getUniqueNumberLocked();
-
-            gen.addLoadImmediate(Register.R0, ETH_HEADER_LEN + IPV4_SRC_ADDR_OFFSET);
-            gen.addJumpIfBytesNotEqual(Register.R0, mSrcDstAddr, nextFilterLabel);
-
-            // A NAT-T keepalive packet contains 1 byte payload with the value 0xff
-            // Check payload length is 1
-            gen.addLoadFromMemory(Register.R0, gen.IPV4_HEADER_SIZE_MEMORY_SLOT);
-            gen.addAdd(UDP_HEADER_LEN);
-            gen.addSwap();
-            gen.addLoad16(Register.R0, IPV4_TOTAL_LENGTH_OFFSET);
-            gen.addNeg(Register.R1);
-            gen.addAddR1();
-            gen.addJumpIfR0NotEquals(1, nextFilterLabel);
-
-            // Check that the ports match
-            gen.addLoadFromMemory(Register.R0, gen.IPV4_HEADER_SIZE_MEMORY_SLOT);
-            gen.addAdd(ETH_HEADER_LEN);
-            gen.addJumpIfBytesNotEqual(Register.R0, mPortFingerprint, nextFilterLabel);
-
-            // Payload offset = R0 + UDP header length
-            gen.addAdd(UDP_HEADER_LEN);
-            gen.addJumpIfBytesNotEqual(Register.R0, mPayload, nextFilterLabel);
-
-            maybeSetupCounter(gen, Counter.DROPPED_IPV4_NATT_KEEPALIVE);
-            gen.addJump(mCountAndDropLabel);
-            gen.defineLabel(nextFilterLabel);
-        }
-
-        public String toString() {
-            try {
-                return String.format("%s -> %s",
-                        NetworkStackUtils.addressAndPortToString(
-                                InetAddress.getByAddress(mPacket.srcAddress), mPacket.srcPort),
-                        NetworkStackUtils.addressAndPortToString(
-                                InetAddress.getByAddress(mPacket.dstAddress), mPacket.dstPort));
-            } catch (UnknownHostException e) {
-                return "Unknown host";
-            }
-        }
-    }
-
-    // A class to hold TCP keepalive ack information.
-    private abstract static class TcpKeepaliveAck extends KeepalivePacket {
-        protected static class TcpKeepaliveAckData {
-            public final byte[] srcAddress;
-            public final int srcPort;
-            public final byte[] dstAddress;
-            public final int dstPort;
-            public final int seq;
-            public final int ack;
-
-            // Create the characteristics of the ack packet from the sent keepalive packet.
-            TcpKeepaliveAckData(final TcpKeepalivePacketDataParcelable sentKeepalivePacket) {
-                srcAddress = sentKeepalivePacket.dstAddress;
-                srcPort = sentKeepalivePacket.dstPort;
-                dstAddress = sentKeepalivePacket.srcAddress;
-                dstPort = sentKeepalivePacket.srcPort;
-                seq = sentKeepalivePacket.ack;
-                ack = sentKeepalivePacket.seq + 1;
-            }
-        }
-
-        protected final TcpKeepaliveAckData mPacket;
-        protected final byte[] mSrcDstAddr;
-        protected final byte[] mPortSeqAckFingerprint;
-
-        TcpKeepaliveAck(final TcpKeepaliveAckData packet, final byte[] srcDstAddr) {
-            mPacket = packet;
-            mSrcDstAddr = srcDstAddr;
-            mPortSeqAckFingerprint = generatePortSeqAckFingerprint(mPacket.srcPort,
-                    mPacket.dstPort, mPacket.seq, mPacket.ack);
-        }
-
-        static byte[] generatePortSeqAckFingerprint(int srcPort, int dstPort, int seq, int ack) {
-            final ByteBuffer fp = ByteBuffer.allocate(12);
-            fp.order(ByteOrder.BIG_ENDIAN);
-            fp.putShort((short) srcPort);
-            fp.putShort((short) dstPort);
-            fp.putInt(seq);
-            fp.putInt(ack);
-            return fp.array();
-        }
-
-        public String toString() {
-            try {
-                return String.format("%s -> %s , seq=%d, ack=%d",
-                        NetworkStackUtils.addressAndPortToString(
-                                InetAddress.getByAddress(mPacket.srcAddress), mPacket.srcPort),
-                        NetworkStackUtils.addressAndPortToString(
-                                InetAddress.getByAddress(mPacket.dstAddress), mPacket.dstPort),
-                        Integer.toUnsignedLong(mPacket.seq),
-                        Integer.toUnsignedLong(mPacket.ack));
-            } catch (UnknownHostException e) {
-                return "Unknown host";
-            }
-        }
-
-        // Append a filter for this keepalive ack to {@code gen}.
-        // Jump to drop if it matches the keepalive ack.
-        // Jump to the next filter if packet doesn't match the keepalive ack.
-        abstract void generateFilterLocked(ApfGenerator gen) throws IllegalInstructionException;
-    }
-
-    private class TcpKeepaliveAckV4 extends TcpKeepaliveAck {
-
-        TcpKeepaliveAckV4(final TcpKeepalivePacketDataParcelable sentKeepalivePacket) {
-            this(new TcpKeepaliveAckData(sentKeepalivePacket));
-        }
-        TcpKeepaliveAckV4(final TcpKeepaliveAckData packet) {
-            super(packet, concatArrays(packet.srcAddress, packet.dstAddress) /* srcDstAddr */);
-        }
-
-        @Override
-        void generateFilterLocked(ApfGenerator gen) throws IllegalInstructionException {
-            final String nextFilterLabel = "keepalive_ack" + getUniqueNumberLocked();
-
-            gen.addLoadImmediate(Register.R0, ETH_HEADER_LEN + IPV4_SRC_ADDR_OFFSET);
-            gen.addJumpIfBytesNotEqual(Register.R0, mSrcDstAddr, nextFilterLabel);
-
-            // Skip to the next filter if it's not zero-sized :
-            // TCP_HEADER_SIZE + IPV4_HEADER_SIZE - ipv4_total_length == 0
-            // Load the IP header size into R1
-            gen.addLoadFromMemory(Register.R1, gen.IPV4_HEADER_SIZE_MEMORY_SLOT);
-            // Load the TCP header size into R0 (it's indexed by R1)
-            gen.addLoad8Indexed(Register.R0, ETH_HEADER_LEN + TCP_HEADER_SIZE_OFFSET);
-            // Size offset is in the top nibble, but it must be multiplied by 4, and the two
-            // top bits of the low nibble are guaranteed to be zeroes. Right-shift R0 by 2.
-            gen.addRightShift(2);
-            // R0 += R1 -> R0 contains TCP + IP headers length
-            gen.addAddR1();
-            // Load IPv4 total length
-            gen.addLoad16(Register.R1, IPV4_TOTAL_LENGTH_OFFSET);
-            gen.addNeg(Register.R0);
-            gen.addAddR1();
-            gen.addJumpIfR0NotEquals(0, nextFilterLabel);
-            // Add IPv4 header length
-            gen.addLoadFromMemory(Register.R1, gen.IPV4_HEADER_SIZE_MEMORY_SLOT);
-            gen.addLoadImmediate(Register.R0, ETH_HEADER_LEN);
-            gen.addAddR1();
-            gen.addJumpIfBytesNotEqual(Register.R0, mPortSeqAckFingerprint, nextFilterLabel);
-
-            maybeSetupCounter(gen, Counter.DROPPED_IPV4_KEEPALIVE_ACK);
-            gen.addJump(mCountAndDropLabel);
-            gen.defineLabel(nextFilterLabel);
-        }
-    }
-
-    private class TcpKeepaliveAckV6 extends TcpKeepaliveAck {
-        TcpKeepaliveAckV6(final TcpKeepalivePacketDataParcelable sentKeepalivePacket) {
-            this(new TcpKeepaliveAckData(sentKeepalivePacket));
-        }
-        TcpKeepaliveAckV6(final TcpKeepaliveAckData packet) {
-            super(packet, concatArrays(packet.srcAddress, packet.dstAddress) /* srcDstAddr */);
-        }
-
-        @Override
-        void generateFilterLocked(ApfGenerator gen) throws IllegalInstructionException {
-            throw new UnsupportedOperationException("IPv6 TCP Keepalive is not supported yet");
-        }
-    }
-
-    // Maximum number of RAs to filter for.
-    private static final int MAX_RAS = 10;
-
-    @GuardedBy("this")
-    private ArrayList<Ra> mRas = new ArrayList<>();
-    @GuardedBy("this")
-    private SparseArray<KeepalivePacket> mKeepalivePackets = new SparseArray<>();
-
-    // There is always some marginal benefit to updating the installed APF program when an RA is
-    // seen because we can extend the program's lifetime slightly, but there is some cost to
-    // updating the program, so don't bother unless the program is going to expire soon. This
-    // constant defines "soon" in seconds.
-    private static final long MAX_PROGRAM_LIFETIME_WORTH_REFRESHING = 30;
-    // We don't want to filter an RA for it's whole lifetime as it'll be expired by the time we ever
-    // see a refresh.  Using half the lifetime might be a good idea except for the fact that
-    // packets may be dropped, so let's use 6.
-    private static final int FRACTION_OF_LIFETIME_TO_FILTER = 6;
-
-    // When did we last install a filter program? In seconds since Unix Epoch.
-    @GuardedBy("this")
-    private long mLastTimeInstalledProgram;
-    // How long should the last installed filter program live for? In seconds.
-    @GuardedBy("this")
-    private long mLastInstalledProgramMinLifetime;
-    @GuardedBy("this")
-    private ApfProgramEvent.Builder mLastInstallEvent;
-
-    // For debugging only. The last program installed.
-    @GuardedBy("this")
-    private byte[] mLastInstalledProgram;
-
-    /**
-     * For debugging only. Contains the latest APF buffer snapshot captured from the firmware.
-     *
-     * A typical size for this buffer is 4KB. It is present only if the WiFi HAL supports
-     * IWifiStaIface#readApfPacketFilterData(), and the APF interpreter advertised support for
-     * the opcodes to access the data buffer (LDDW and STDW).
-     */
-    @GuardedBy("this") @Nullable
-    private byte[] mDataSnapshot;
-
-    // How many times the program was updated since we started.
-    @GuardedBy("this")
-    private int mNumProgramUpdates = 0;
-    // How many times the program was updated since we started for allowing multicast traffic.
-    @GuardedBy("this")
-    private int mNumProgramUpdatesAllowingMulticast = 0;
-
-    /**
-     * Generate filter code to process ARP packets. Execution of this code ends in either the
-     * DROP_LABEL or PASS_LABEL and does not fall off the end.
-     * Preconditions:
-     *  - Packet being filtered is ARP
-     */
-    @GuardedBy("this")
-    private void generateArpFilterLocked(ApfGenerator gen) throws IllegalInstructionException {
-        // Here's a basic summary of what the ARP filter program does:
-        //
-        // if not ARP IPv4
-        //   pass
-        // if not ARP IPv4 reply or request
-        //   pass
-        // if ARP reply source ip is 0.0.0.0
-        //   drop
-        // if unicast ARP reply
-        //   pass
-        // if interface has no IPv4 address
-        //   if target ip is 0.0.0.0
-        //      drop
-        // else
-        //   if target ip is not the interface ip
-        //      drop
-        // pass
-
-        final String checkTargetIPv4 = "checkTargetIPv4";
-
-        // Pass if not ARP IPv4.
-        gen.addLoadImmediate(Register.R0, ARP_HEADER_OFFSET);
-        maybeSetupCounter(gen, Counter.PASSED_ARP_NON_IPV4);
-        gen.addJumpIfBytesNotEqual(Register.R0, ARP_IPV4_HEADER, mCountAndPassLabel);
-
-        // Pass if unknown ARP opcode.
-        gen.addLoad16(Register.R0, ARP_OPCODE_OFFSET);
-        gen.addJumpIfR0Equals(ARP_OPCODE_REQUEST, checkTargetIPv4); // Skip to unicast check
-        maybeSetupCounter(gen, Counter.PASSED_ARP_UNKNOWN);
-        gen.addJumpIfR0NotEquals(ARP_OPCODE_REPLY, mCountAndPassLabel);
-
-        // Drop if ARP reply source IP is 0.0.0.0
-        gen.addLoad32(Register.R0, ARP_SOURCE_IP_ADDRESS_OFFSET);
-        maybeSetupCounter(gen, Counter.DROPPED_ARP_REPLY_SPA_NO_HOST);
-        gen.addJumpIfR0Equals(IPV4_ANY_HOST_ADDRESS, mCountAndDropLabel);
-
-        // Pass if unicast reply.
-        gen.addLoadImmediate(Register.R0, ETH_DEST_ADDR_OFFSET);
-        maybeSetupCounter(gen, Counter.PASSED_ARP_UNICAST_REPLY);
-        gen.addJumpIfBytesNotEqual(Register.R0, ETH_BROADCAST_MAC_ADDRESS, mCountAndPassLabel);
-
-        // Either a unicast request, a unicast reply, or a broadcast reply.
-        gen.defineLabel(checkTargetIPv4);
-        if (mIPv4Address == null) {
-            // When there is no IPv4 address, drop GARP replies (b/29404209).
-            gen.addLoad32(Register.R0, ARP_TARGET_IP_ADDRESS_OFFSET);
-            maybeSetupCounter(gen, Counter.DROPPED_GARP_REPLY);
-            gen.addJumpIfR0Equals(IPV4_ANY_HOST_ADDRESS, mCountAndDropLabel);
-        } else {
-            // When there is an IPv4 address, drop unicast/broadcast requests
-            // and broadcast replies with a different target IPv4 address.
-            gen.addLoadImmediate(Register.R0, ARP_TARGET_IP_ADDRESS_OFFSET);
-            maybeSetupCounter(gen, Counter.DROPPED_ARP_OTHER_HOST);
-            gen.addJumpIfBytesNotEqual(Register.R0, mIPv4Address, mCountAndDropLabel);
-        }
-
-        maybeSetupCounter(gen, Counter.PASSED_ARP);
-        gen.addJump(mCountAndPassLabel);
-    }
-
-    /**
-     * Generate filter code to process IPv4 packets. Execution of this code ends in either the
-     * DROP_LABEL or PASS_LABEL and does not fall off the end.
-     * Preconditions:
-     *  - Packet being filtered is IPv4
-     */
-    @GuardedBy("this")
-    private void generateIPv4FilterLocked(ApfGenerator gen) throws IllegalInstructionException {
-        // Here's a basic summary of what the IPv4 filter program does:
-        //
-        // if filtering multicast (i.e. multicast lock not held):
-        //   if it's DHCP destined to our MAC:
-        //     pass
-        //   if it's L2 broadcast:
-        //     drop
-        //   if it's IPv4 multicast:
-        //     drop
-        //   if it's IPv4 broadcast:
-        //     drop
-        // if keepalive ack
-        //   drop
-        // pass
-
-        if (mMulticastFilter) {
-            final String skipDhcpv4Filter = "skip_dhcp_v4_filter";
-
-            // Pass DHCP addressed to us.
-            // Check it's UDP.
-            gen.addLoad8(Register.R0, IPV4_PROTOCOL_OFFSET);
-            gen.addJumpIfR0NotEquals(IPPROTO_UDP, skipDhcpv4Filter);
-            // Check it's not a fragment. This matches the BPF filter installed by the DHCP client.
-            gen.addLoad16(Register.R0, IPV4_FRAGMENT_OFFSET_OFFSET);
-            gen.addJumpIfR0AnyBitsSet(IPV4_FRAGMENT_OFFSET_MASK, skipDhcpv4Filter);
-            // Check it's addressed to DHCP client port.
-            gen.addLoadFromMemory(Register.R1, gen.IPV4_HEADER_SIZE_MEMORY_SLOT);
-            gen.addLoad16Indexed(Register.R0, UDP_DESTINATION_PORT_OFFSET);
-            gen.addJumpIfR0NotEquals(DHCP_CLIENT_PORT, skipDhcpv4Filter);
-            // Check it's DHCP to our MAC address.
-            gen.addLoadImmediate(Register.R0, DHCP_CLIENT_MAC_OFFSET);
-            // NOTE: Relies on R1 containing IPv4 header offset.
-            gen.addAddR1();
-            gen.addJumpIfBytesNotEqual(Register.R0, mHardwareAddress, skipDhcpv4Filter);
-            maybeSetupCounter(gen, Counter.PASSED_DHCP);
-            gen.addJump(mCountAndPassLabel);
-
-            // Drop all multicasts/broadcasts.
-            gen.defineLabel(skipDhcpv4Filter);
-
-            // If IPv4 destination address is in multicast range, drop.
-            gen.addLoad8(Register.R0, IPV4_DEST_ADDR_OFFSET);
-            gen.addAnd(0xf0);
-            maybeSetupCounter(gen, Counter.DROPPED_IPV4_MULTICAST);
-            gen.addJumpIfR0Equals(0xe0, mCountAndDropLabel);
-
-            // If IPv4 broadcast packet, drop regardless of L2 (b/30231088).
-            maybeSetupCounter(gen, Counter.DROPPED_IPV4_BROADCAST_ADDR);
-            gen.addLoad32(Register.R0, IPV4_DEST_ADDR_OFFSET);
-            gen.addJumpIfR0Equals(IPV4_BROADCAST_ADDRESS, mCountAndDropLabel);
-            if (mIPv4Address != null && mIPv4PrefixLength < 31) {
-                maybeSetupCounter(gen, Counter.DROPPED_IPV4_BROADCAST_NET);
-                int broadcastAddr = ipv4BroadcastAddress(mIPv4Address, mIPv4PrefixLength);
-                gen.addJumpIfR0Equals(broadcastAddr, mCountAndDropLabel);
-            }
-
-            // If any TCP keepalive filter matches, drop
-            generateV4KeepaliveFilters(gen);
-
-            // If any NAT-T keepalive filter matches, drop
-            generateV4NattKeepaliveFilters(gen);
-
-            // Otherwise, this is an IPv4 unicast, pass
-            // If L2 broadcast packet, drop.
-            // TODO: can we invert this condition to fall through to the common pass case below?
-            maybeSetupCounter(gen, Counter.PASSED_IPV4_UNICAST);
-            gen.addLoadImmediate(Register.R0, ETH_DEST_ADDR_OFFSET);
-            gen.addJumpIfBytesNotEqual(Register.R0, ETH_BROADCAST_MAC_ADDRESS, mCountAndPassLabel);
-            maybeSetupCounter(gen, Counter.DROPPED_IPV4_L2_BROADCAST);
-            gen.addJump(mCountAndDropLabel);
-        } else {
-            generateV4KeepaliveFilters(gen);
-            generateV4NattKeepaliveFilters(gen);
-        }
-
-        // Otherwise, pass
-        maybeSetupCounter(gen, Counter.PASSED_IPV4);
-        gen.addJump(mCountAndPassLabel);
-    }
-
-    private void generateKeepaliveFilters(ApfGenerator gen, Class<?> filterType, int proto,
-            int offset, String label) throws IllegalInstructionException {
-        final boolean haveKeepaliveResponses = NetworkStackUtils.any(mKeepalivePackets,
-                ack -> filterType.isInstance(ack));
-
-        // If no keepalive packets of this type
-        if (!haveKeepaliveResponses) return;
-
-        // If not the right proto, skip keepalive filters
-        gen.addLoad8(Register.R0, offset);
-        gen.addJumpIfR0NotEquals(proto, label);
-
-        // Drop Keepalive responses
-        for (int i = 0; i < mKeepalivePackets.size(); ++i) {
-            final KeepalivePacket response = mKeepalivePackets.valueAt(i);
-            if (filterType.isInstance(response)) response.generateFilterLocked(gen);
-        }
-
-        gen.defineLabel(label);
-    }
-
-    private void generateV4KeepaliveFilters(ApfGenerator gen) throws IllegalInstructionException {
-        generateKeepaliveFilters(gen, TcpKeepaliveAckV4.class, IPPROTO_TCP, IPV4_PROTOCOL_OFFSET,
-                "skip_v4_keepalive_filter");
-    }
-
-    private void generateV4NattKeepaliveFilters(ApfGenerator gen)
-            throws IllegalInstructionException {
-        generateKeepaliveFilters(gen, NattKeepaliveResponse.class,
-                IPPROTO_UDP, IPV4_PROTOCOL_OFFSET, "skip_v4_nattkeepalive_filter");
-    }
-
-    /**
-     * Generate filter code to process IPv6 packets. Execution of this code ends in either the
-     * DROP_LABEL or PASS_LABEL, or falls off the end for ICMPv6 packets.
-     * Preconditions:
-     *  - Packet being filtered is IPv6
-     */
-    @GuardedBy("this")
-    private void generateIPv6FilterLocked(ApfGenerator gen) throws IllegalInstructionException {
-        // Here's a basic summary of what the IPv6 filter program does:
-        //
-        // if we're dropping multicast
-        //   if it's not IPCMv6 or it's ICMPv6 but we're in doze mode:
-        //     if it's multicast:
-        //       drop
-        //     pass
-        // if it's ICMPv6 RS to any:
-        //   drop
-        // if it's ICMPv6 NA to ff02::1:
-        //   drop
-        // if keepalive ack
-        //   drop
-
-        gen.addLoad8(Register.R0, IPV6_NEXT_HEADER_OFFSET);
-
-        // Drop multicast if the multicast filter is enabled.
-        if (mMulticastFilter) {
-            final String skipIPv6MulticastFilterLabel = "skipIPv6MulticastFilter";
-            final String dropAllIPv6MulticastsLabel = "dropAllIPv6Multicast";
-
-            // While in doze mode, drop ICMPv6 multicast pings, let the others pass.
-            // While awake, let all ICMPv6 multicasts through.
-            if (mInDozeMode) {
-                // Not ICMPv6? -> Proceed to multicast filtering
-                gen.addJumpIfR0NotEquals(IPPROTO_ICMPV6, dropAllIPv6MulticastsLabel);
-
-                // ICMPv6 but not ECHO? -> Skip the multicast filter.
-                // (ICMPv6 ECHO requests will go through the multicast filter below).
-                gen.addLoad8(Register.R0, ICMP6_TYPE_OFFSET);
-                gen.addJumpIfR0NotEquals(ICMPV6_ECHO_REQUEST_TYPE, skipIPv6MulticastFilterLabel);
-            } else {
-                gen.addJumpIfR0Equals(IPPROTO_ICMPV6, skipIPv6MulticastFilterLabel);
-            }
-
-            // Drop all other packets sent to ff00::/8 (multicast prefix).
-            gen.defineLabel(dropAllIPv6MulticastsLabel);
-            maybeSetupCounter(gen, Counter.DROPPED_IPV6_NON_ICMP_MULTICAST);
-            gen.addLoad8(Register.R0, IPV6_DEST_ADDR_OFFSET);
-            gen.addJumpIfR0Equals(0xff, mCountAndDropLabel);
-            // If any keepalive filter matches, drop
-            generateV6KeepaliveFilters(gen);
-            // Not multicast. Pass.
-            maybeSetupCounter(gen, Counter.PASSED_IPV6_UNICAST_NON_ICMP);
-            gen.addJump(mCountAndPassLabel);
-            gen.defineLabel(skipIPv6MulticastFilterLabel);
-        } else {
-            generateV6KeepaliveFilters(gen);
-            // If not ICMPv6, pass.
-            maybeSetupCounter(gen, Counter.PASSED_IPV6_NON_ICMP);
-            gen.addJumpIfR0NotEquals(IPPROTO_ICMPV6, mCountAndPassLabel);
-        }
-
-        // If we got this far, the packet is ICMPv6.  Drop some specific types.
-
-        // Add unsolicited multicast neighbor announcements filter
-        String skipUnsolicitedMulticastNALabel = "skipUnsolicitedMulticastNA";
-        gen.addLoad8(Register.R0, ICMP6_TYPE_OFFSET);
-        // Drop all router solicitations (b/32833400)
-        maybeSetupCounter(gen, Counter.DROPPED_IPV6_ROUTER_SOLICITATION);
-        gen.addJumpIfR0Equals(ICMPV6_ROUTER_SOLICITATION, mCountAndDropLabel);
-        // If not neighbor announcements, skip filter.
-        gen.addJumpIfR0NotEquals(ICMPV6_NEIGHBOR_ADVERTISEMENT, skipUnsolicitedMulticastNALabel);
-        // If to ff02::1, drop.
-        // TODO: Drop only if they don't contain the address of on-link neighbours.
-        gen.addLoadImmediate(Register.R0, IPV6_DEST_ADDR_OFFSET);
-        gen.addJumpIfBytesNotEqual(Register.R0, IPV6_ALL_NODES_ADDRESS,
-                skipUnsolicitedMulticastNALabel);
-        maybeSetupCounter(gen, Counter.DROPPED_IPV6_MULTICAST_NA);
-        gen.addJump(mCountAndDropLabel);
-        gen.defineLabel(skipUnsolicitedMulticastNALabel);
-    }
-
-    private void generateV6KeepaliveFilters(ApfGenerator gen) throws IllegalInstructionException {
-        generateKeepaliveFilters(gen, TcpKeepaliveAckV6.class, IPPROTO_TCP, IPV6_NEXT_HEADER_OFFSET,
-                "skip_v6_keepalive_filter");
-    }
-
-    /**
-     * Begin generating an APF program to:
-     * <ul>
-     * <li>Drop/Pass 802.3 frames (based on policy)
-     * <li>Drop packets with EtherType within the Black List
-     * <li>Drop ARP requests not for us, if mIPv4Address is set,
-     * <li>Drop IPv4 broadcast packets, except DHCP destined to our MAC,
-     * <li>Drop IPv4 multicast packets, if mMulticastFilter,
-     * <li>Pass all other IPv4 packets,
-     * <li>Drop all broadcast non-IP non-ARP packets.
-     * <li>Pass all non-ICMPv6 IPv6 packets,
-     * <li>Pass all non-IPv4 and non-IPv6 packets,
-     * <li>Drop IPv6 ICMPv6 NAs to ff02::1.
-     * <li>Drop IPv6 ICMPv6 RSs.
-     * <li>Filter IPv4 packets (see generateIPv4FilterLocked())
-     * <li>Filter IPv6 packets (see generateIPv6FilterLocked())
-     * <li>Let execution continue off the end of the program for IPv6 ICMPv6 packets. This allows
-     *     insertion of RA filters here, or if there aren't any, just passes the packets.
-     * </ul>
-     */
-    @GuardedBy("this")
-    private ApfGenerator emitPrologueLocked() throws IllegalInstructionException {
-        // This is guaranteed to succeed because of the check in maybeCreate.
-        ApfGenerator gen = new ApfGenerator(mApfCapabilities.apfVersionSupported);
-
-        if (mApfCapabilities.hasDataAccess()) {
-            // Increment TOTAL_PACKETS
-            maybeSetupCounter(gen, Counter.TOTAL_PACKETS);
-            gen.addLoadData(Register.R0, 0);  // load counter
-            gen.addAdd(1);
-            gen.addStoreData(Register.R0, 0);  // write-back counter
-        }
-
-        // Here's a basic summary of what the initial program does:
-        //
-        // if it's a 802.3 Frame (ethtype < 0x0600):
-        //    drop or pass based on configurations
-        // if it has a ether-type that belongs to the black list
-        //    drop
-        // if it's ARP:
-        //   insert ARP filter to drop or pass these appropriately
-        // if it's IPv4:
-        //   insert IPv4 filter to drop or pass these appropriately
-        // if it's not IPv6:
-        //   if it's broadcast:
-        //     drop
-        //   pass
-        // insert IPv6 filter to drop, pass, or fall off the end for ICMPv6 packets
-
-        gen.addLoad16(Register.R0, ETH_ETHERTYPE_OFFSET);
-
-        if (mDrop802_3Frames) {
-            // drop 802.3 frames (ethtype < 0x0600)
-            maybeSetupCounter(gen, Counter.DROPPED_802_3_FRAME);
-            gen.addJumpIfR0LessThan(ETH_TYPE_MIN, mCountAndDropLabel);
-        }
-
-        // Handle ether-type black list
-        maybeSetupCounter(gen, Counter.DROPPED_ETHERTYPE_BLACKLISTED);
-        for (int p : mEthTypeBlackList) {
-            gen.addJumpIfR0Equals(p, mCountAndDropLabel);
-        }
-
-        // Add ARP filters:
-        String skipArpFiltersLabel = "skipArpFilters";
-        gen.addJumpIfR0NotEquals(ETH_P_ARP, skipArpFiltersLabel);
-        generateArpFilterLocked(gen);
-        gen.defineLabel(skipArpFiltersLabel);
-
-        // Add IPv4 filters:
-        String skipIPv4FiltersLabel = "skipIPv4Filters";
-        // NOTE: Relies on R0 containing ethertype. This is safe because if we got here, we did not
-        // execute the ARP filter, since that filter does not fall through, but either drops or
-        // passes.
-        gen.addJumpIfR0NotEquals(ETH_P_IP, skipIPv4FiltersLabel);
-        generateIPv4FilterLocked(gen);
-        gen.defineLabel(skipIPv4FiltersLabel);
-
-        // Check for IPv6:
-        // NOTE: Relies on R0 containing ethertype. This is safe because if we got here, we did not
-        // execute the ARP or IPv4 filters, since those filters do not fall through, but either
-        // drop or pass.
-        String ipv6FilterLabel = "IPv6Filters";
-        gen.addJumpIfR0Equals(ETH_P_IPV6, ipv6FilterLabel);
-
-        // Drop non-IP non-ARP broadcasts, pass the rest
-        gen.addLoadImmediate(Register.R0, ETH_DEST_ADDR_OFFSET);
-        maybeSetupCounter(gen, Counter.PASSED_NON_IP_UNICAST);
-        gen.addJumpIfBytesNotEqual(Register.R0, ETH_BROADCAST_MAC_ADDRESS, mCountAndPassLabel);
-        maybeSetupCounter(gen, Counter.DROPPED_ETH_BROADCAST);
-        gen.addJump(mCountAndDropLabel);
-
-        // Add IPv6 filters:
-        gen.defineLabel(ipv6FilterLabel);
-        generateIPv6FilterLocked(gen);
-        return gen;
-    }
-
-    /**
-     * Append packet counting epilogue to the APF program.
-     *
-     * Currently, the epilogue consists of two trampolines which count passed and dropped packets
-     * before jumping to the actual PASS and DROP labels.
-     */
-    @GuardedBy("this")
-    private void emitEpilogue(ApfGenerator gen) throws IllegalInstructionException {
-        // If APFv4 is unsupported, no epilogue is necessary: if execution reached this far, it
-        // will just fall-through to the PASS label.
-        if (!mApfCapabilities.hasDataAccess()) return;
-
-        // Execution will reach the bottom of the program if none of the filters match,
-        // which will pass the packet to the application processor.
-        maybeSetupCounter(gen, Counter.PASSED_IPV6_ICMP);
-
-        // Append the count & pass trampoline, which increments the counter at the data address
-        // pointed to by R1, then jumps to the pass label. This saves a few bytes over inserting
-        // the entire sequence inline for every counter.
-        gen.defineLabel(mCountAndPassLabel);
-        gen.addLoadData(Register.R0, 0);   // R0 = *(R1 + 0)
-        gen.addAdd(1);                     // R0++
-        gen.addStoreData(Register.R0, 0);  // *(R1 + 0) = R0
-        gen.addJump(gen.PASS_LABEL);
-
-        // Same as above for the count & drop trampoline.
-        gen.defineLabel(mCountAndDropLabel);
-        gen.addLoadData(Register.R0, 0);   // R0 = *(R1 + 0)
-        gen.addAdd(1);                     // R0++
-        gen.addStoreData(Register.R0, 0);  // *(R1 + 0) = R0
-        gen.addJump(gen.DROP_LABEL);
-    }
-
-    /**
-     * Generate and install a new filter program.
-     */
-    @GuardedBy("this")
-    @VisibleForTesting
-    void installNewProgramLocked() {
-        purgeExpiredRasLocked();
-        ArrayList<Ra> rasToFilter = new ArrayList<>();
-        final byte[] program;
-        long programMinLifetime = Long.MAX_VALUE;
-        long maximumApfProgramSize = mApfCapabilities.maximumApfProgramSize;
-        if (mApfCapabilities.hasDataAccess()) {
-            // Reserve space for the counters.
-            maximumApfProgramSize -= Counter.totalSize();
-        }
-
-        try {
-            // Step 1: Determine how many RA filters we can fit in the program.
-            ApfGenerator gen = emitPrologueLocked();
-
-            // The epilogue normally goes after the RA filters, but add it early to include its
-            // length when estimating the total.
-            emitEpilogue(gen);
-
-            // Can't fit the program even without any RA filters?
-            if (gen.programLengthOverEstimate() > maximumApfProgramSize) {
-                Log.e(TAG, "Program exceeds maximum size " + maximumApfProgramSize);
-                return;
-            }
-
-            for (Ra ra : mRas) {
-                ra.generateFilterLocked(gen);
-                // Stop if we get too big.
-                if (gen.programLengthOverEstimate() > maximumApfProgramSize) break;
-                rasToFilter.add(ra);
-            }
-
-            // Step 2: Actually generate the program
-            gen = emitPrologueLocked();
-            for (Ra ra : rasToFilter) {
-                programMinLifetime = Math.min(programMinLifetime, ra.generateFilterLocked(gen));
-            }
-            emitEpilogue(gen);
-            program = gen.generate();
-        } catch (IllegalInstructionException|IllegalStateException e) {
-            Log.e(TAG, "Failed to generate APF program.", e);
-            return;
-        }
-        final long now = currentTimeSeconds();
-        mLastTimeInstalledProgram = now;
-        mLastInstalledProgramMinLifetime = programMinLifetime;
-        mLastInstalledProgram = program;
-        mNumProgramUpdates++;
-
-        if (VDBG) {
-            hexDump("Installing filter: ", program, program.length);
-        }
-        mIpClientCallback.installPacketFilter(program);
-        logApfProgramEventLocked(now);
-        mLastInstallEvent = new ApfProgramEvent.Builder()
-                .setLifetime(programMinLifetime)
-                .setFilteredRas(rasToFilter.size())
-                .setCurrentRas(mRas.size())
-                .setProgramLength(program.length)
-                .setFlags(mIPv4Address != null, mMulticastFilter);
-    }
-
-    @GuardedBy("this")
-    private void logApfProgramEventLocked(long now) {
-        if (mLastInstallEvent == null) {
-            return;
-        }
-        ApfProgramEvent.Builder ev = mLastInstallEvent;
-        mLastInstallEvent = null;
-        final long actualLifetime = now - mLastTimeInstalledProgram;
-        ev.setActualLifetime(actualLifetime);
-        if (actualLifetime < APF_PROGRAM_EVENT_LIFETIME_THRESHOLD) {
-            return;
-        }
-        mMetricsLog.log(ev.build());
-    }
-
-    /**
-     * Returns {@code true} if a new program should be installed because the current one dies soon.
-     */
-    private boolean shouldInstallnewProgram() {
-        long expiry = mLastTimeInstalledProgram + mLastInstalledProgramMinLifetime;
-        return expiry < currentTimeSeconds() + MAX_PROGRAM_LIFETIME_WORTH_REFRESHING;
-    }
-
-    private void hexDump(String msg, byte[] packet, int length) {
-        log(msg + HexDump.toHexString(packet, 0, length, false /* lowercase */));
-    }
-
-    @GuardedBy("this")
-    private void purgeExpiredRasLocked() {
-        for (int i = 0; i < mRas.size();) {
-            if (mRas.get(i).isExpired()) {
-                log("Expiring " + mRas.get(i));
-                mRas.remove(i);
-            } else {
-                i++;
-            }
-        }
-    }
-
-    /**
-     * Process an RA packet, updating the list of known RAs and installing a new APF program
-     * if the current APF program should be updated.
-     * @return a ProcessRaResult enum describing what action was performed.
-     */
-    @VisibleForTesting
-    synchronized ProcessRaResult processRa(byte[] packet, int length) {
-        if (VDBG) hexDump("Read packet = ", packet, length);
-
-        // Have we seen this RA before?
-        for (int i = 0; i < mRas.size(); i++) {
-            Ra ra = mRas.get(i);
-            if (ra.matches(packet, length)) {
-                if (VDBG) log("matched RA " + ra);
-                // Update lifetimes.
-                ra.mLastSeen = currentTimeSeconds();
-                ra.mMinLifetime = ra.minLifetime(packet, length);
-                ra.seenCount++;
-
-                // Keep mRas in LRU order so as to prioritize generating filters for recently seen
-                // RAs. LRU prioritizes this because RA filters are generated in order from mRas
-                // until the filter program exceeds the maximum filter program size allowed by the
-                // chipset, so RAs appearing earlier in mRas are more likely to make it into the
-                // filter program.
-                // TODO: consider sorting the RAs in order of increasing expiry time as well.
-                // Swap to front of array.
-                mRas.add(0, mRas.remove(i));
-
-                // If the current program doesn't expire for a while, don't update.
-                if (shouldInstallnewProgram()) {
-                    installNewProgramLocked();
-                    return ProcessRaResult.UPDATE_EXPIRY;
-                }
-                return ProcessRaResult.MATCH;
-            }
-        }
-        purgeExpiredRasLocked();
-        // TODO: figure out how to proceed when we've received more then MAX_RAS RAs.
-        if (mRas.size() >= MAX_RAS) {
-            return ProcessRaResult.DROPPED;
-        }
-        final Ra ra;
-        try {
-            ra = new Ra(packet, length);
-        } catch (Exception e) {
-            Log.e(TAG, "Error parsing RA", e);
-            return ProcessRaResult.PARSE_ERROR;
-        }
-        // Ignore 0 lifetime RAs.
-        if (ra.isExpired()) {
-            return ProcessRaResult.ZERO_LIFETIME;
-        }
-        log("Adding " + ra);
-        mRas.add(ra);
-        installNewProgramLocked();
-        return ProcessRaResult.UPDATE_NEW_RA;
-    }
-
-    /**
-     * Create an {@link ApfFilter} if {@code apfCapabilities} indicates support for packet
-     * filtering using APF programs.
-     */
-    public static ApfFilter maybeCreate(Context context, ApfConfiguration config,
-            InterfaceParams ifParams, IpClientCallbacksWrapper ipClientCallback) {
-        if (context == null || config == null || ifParams == null) return null;
-        ApfCapabilities apfCapabilities =  config.apfCapabilities;
-        if (apfCapabilities == null) return null;
-        if (apfCapabilities.apfVersionSupported == 0) return null;
-        if (apfCapabilities.maximumApfProgramSize < 512) {
-            Log.e(TAG, "Unacceptably small APF limit: " + apfCapabilities.maximumApfProgramSize);
-            return null;
-        }
-        // For now only support generating programs for Ethernet frames. If this restriction is
-        // lifted:
-        //   1. the program generator will need its offsets adjusted.
-        //   2. the packet filter attached to our packet socket will need its offset adjusted.
-        if (apfCapabilities.apfPacketFormat != ARPHRD_ETHER) return null;
-        if (!ApfGenerator.supportsVersion(apfCapabilities.apfVersionSupported)) {
-            Log.e(TAG, "Unsupported APF version: " + apfCapabilities.apfVersionSupported);
-            return null;
-        }
-
-        return new ApfFilter(context, config, ifParams, ipClientCallback, new IpConnectivityLog());
-    }
-
-    public synchronized void shutdown() {
-        if (mReceiveThread != null) {
-            log("shutting down");
-            mReceiveThread.halt();  // Also closes socket.
-            mReceiveThread = null;
-        }
-        mRas.clear();
-        mContext.unregisterReceiver(mDeviceIdleReceiver);
-    }
-
-    public synchronized void setMulticastFilter(boolean isEnabled) {
-        if (mMulticastFilter == isEnabled) return;
-        mMulticastFilter = isEnabled;
-        if (!isEnabled) {
-            mNumProgramUpdatesAllowingMulticast++;
-        }
-        installNewProgramLocked();
-    }
-
-    @VisibleForTesting
-    public synchronized void setDozeMode(boolean isEnabled) {
-        if (mInDozeMode == isEnabled) return;
-        mInDozeMode = isEnabled;
-        installNewProgramLocked();
-    }
-
-    /** Find the single IPv4 LinkAddress if there is one, otherwise return null. */
-    private static LinkAddress findIPv4LinkAddress(LinkProperties lp) {
-        LinkAddress ipv4Address = null;
-        for (LinkAddress address : lp.getLinkAddresses()) {
-            if (!(address.getAddress() instanceof Inet4Address)) {
-                continue;
-            }
-            if (ipv4Address != null && !ipv4Address.isSameAddressAs(address)) {
-                // More than one IPv4 address, abort.
-                return null;
-            }
-            ipv4Address = address;
-        }
-        return ipv4Address;
-    }
-
-    public synchronized void setLinkProperties(LinkProperties lp) {
-        // NOTE: Do not keep a copy of LinkProperties as it would further duplicate state.
-        final LinkAddress ipv4Address = findIPv4LinkAddress(lp);
-        final byte[] addr = (ipv4Address != null) ? ipv4Address.getAddress().getAddress() : null;
-        final int prefix = (ipv4Address != null) ? ipv4Address.getPrefixLength() : 0;
-        if ((prefix == mIPv4PrefixLength) && Arrays.equals(addr, mIPv4Address)) {
-            return;
-        }
-        mIPv4Address = addr;
-        mIPv4PrefixLength = prefix;
-        installNewProgramLocked();
-    }
-
-    /**
-     * Add TCP keepalive ack packet filter.
-     * This will add a filter to drop acks to the keepalive packet passed as an argument.
-     *
-     * @param slot The index used to access the filter.
-     * @param sentKeepalivePacket The attributes of the sent keepalive packet.
-     */
-    public synchronized void addTcpKeepalivePacketFilter(final int slot,
-            final TcpKeepalivePacketDataParcelable sentKeepalivePacket) {
-        log("Adding keepalive ack(" + slot + ")");
-        if (null != mKeepalivePackets.get(slot)) {
-            throw new IllegalArgumentException("Keepalive slot " + slot + " is occupied");
-        }
-        final int ipVersion = sentKeepalivePacket.srcAddress.length == 4 ? 4 : 6;
-        mKeepalivePackets.put(slot, (ipVersion == 4)
-                ? new TcpKeepaliveAckV4(sentKeepalivePacket)
-                : new TcpKeepaliveAckV6(sentKeepalivePacket));
-        installNewProgramLocked();
-    }
-
-    /**
-     * Add NAT-T keepalive packet filter.
-     * This will add a filter to drop NAT-T keepalive packet which is passed as an argument.
-     *
-     * @param slot The index used to access the filter.
-     * @param sentKeepalivePacket The attributes of the sent keepalive packet.
-     */
-    public synchronized void addNattKeepalivePacketFilter(final int slot,
-            final NattKeepalivePacketDataParcelable sentKeepalivePacket) {
-        log("Adding NAT-T keepalive packet(" + slot + ")");
-        if (null != mKeepalivePackets.get(slot)) {
-            throw new IllegalArgumentException("NAT-T Keepalive slot " + slot + " is occupied");
-        }
-        if (sentKeepalivePacket.srcAddress.length != 4) {
-            throw new IllegalArgumentException("NAT-T keepalive is only supported on IPv4");
-        }
-        mKeepalivePackets.put(slot, new NattKeepaliveResponse(sentKeepalivePacket));
-        installNewProgramLocked();
-    }
-
-    /**
-     * Remove keepalive packet filter.
-     *
-     * @param slot The index used to access the filter.
-     */
-    public synchronized void removeKeepalivePacketFilter(int slot) {
-        log("Removing keepalive packet(" + slot + ")");
-        mKeepalivePackets.remove(slot);
-        installNewProgramLocked();
-    }
-
-    static public long counterValue(byte[] data, Counter counter)
-            throws ArrayIndexOutOfBoundsException {
-        // Follow the same wrap-around addressing scheme of the interpreter.
-        int offset = counter.offset();
-        if (offset < 0) {
-            offset = data.length + offset;
-        }
-
-        // Decode 32bit big-endian integer into a long so we can count up beyond 2^31.
-        long value = 0;
-        for (int i = 0; i < 4; i++) {
-            value = value << 8 | (data[offset] & 0xFF);
-            offset++;
-        }
-        return value;
-    }
-
-    public synchronized void dump(IndentingPrintWriter pw) {
-        pw.println("Capabilities: " + mApfCapabilities);
-        pw.println("Receive thread: " + (mReceiveThread != null ? "RUNNING" : "STOPPED"));
-        pw.println("Multicast: " + (mMulticastFilter ? "DROP" : "ALLOW"));
-        try {
-            pw.println("IPv4 address: " + InetAddress.getByAddress(mIPv4Address).getHostAddress());
-        } catch (UnknownHostException|NullPointerException e) {}
-
-        if (mLastTimeInstalledProgram == 0) {
-            pw.println("No program installed.");
-            return;
-        }
-        pw.println("Program updates: " + mNumProgramUpdates);
-        pw.println(String.format(
-                "Last program length %d, installed %ds ago, lifetime %ds",
-                mLastInstalledProgram.length, currentTimeSeconds() - mLastTimeInstalledProgram,
-                mLastInstalledProgramMinLifetime));
-
-        pw.println("RA filters:");
-        pw.increaseIndent();
-        for (Ra ra: mRas) {
-            pw.println(ra);
-            pw.increaseIndent();
-            pw.println(String.format(
-                    "Seen: %d, last %ds ago", ra.seenCount, currentTimeSeconds() - ra.mLastSeen));
-            if (DBG) {
-                pw.println("Last match:");
-                pw.increaseIndent();
-                pw.println(ra.getLastMatchingPacket());
-                pw.decreaseIndent();
-            }
-            pw.decreaseIndent();
-        }
-        pw.decreaseIndent();
-
-        pw.println("TCP Keepalive filters:");
-        pw.increaseIndent();
-        for (int i = 0; i < mKeepalivePackets.size(); ++i) {
-            final KeepalivePacket keepalivePacket = mKeepalivePackets.valueAt(i);
-            if (keepalivePacket instanceof TcpKeepaliveAck) {
-                pw.print("Slot ");
-                pw.print(mKeepalivePackets.keyAt(i));
-                pw.print(": ");
-                pw.println(keepalivePacket);
-            }
-        }
-        pw.decreaseIndent();
-
-        pw.println("NAT-T Keepalive filters:");
-        pw.increaseIndent();
-        for (int i = 0; i < mKeepalivePackets.size(); ++i) {
-            final KeepalivePacket keepalivePacket = mKeepalivePackets.valueAt(i);
-            if (keepalivePacket instanceof NattKeepaliveResponse) {
-                pw.print("Slot ");
-                pw.print(mKeepalivePackets.keyAt(i));
-                pw.print(": ");
-                pw.println(keepalivePacket);
-            }
-        }
-        pw.decreaseIndent();
-
-        if (DBG) {
-            pw.println("Last program:");
-            pw.increaseIndent();
-            pw.println(HexDump.toHexString(mLastInstalledProgram, false /* lowercase */));
-            pw.decreaseIndent();
-        }
-
-        pw.println("APF packet counters: ");
-        pw.increaseIndent();
-        if (!mApfCapabilities.hasDataAccess()) {
-            pw.println("APF counters not supported");
-        } else if (mDataSnapshot == null) {
-            pw.println("No last snapshot.");
-        } else {
-            try {
-                Counter[] counters = Counter.class.getEnumConstants();
-                for (Counter c : Arrays.asList(counters).subList(1, counters.length)) {
-                    long value = counterValue(mDataSnapshot, c);
-                    // Only print non-zero counters
-                    if (value != 0) {
-                        pw.println(c.toString() + ": " + value);
-                    }
-                }
-            } catch (ArrayIndexOutOfBoundsException e) {
-                pw.println("Uh-oh: " + e);
-            }
-            if (VDBG) {
-                pw.println("Raw data dump: ");
-                pw.println(HexDump.dumpHexString(mDataSnapshot));
-            }
-        }
-        pw.decreaseIndent();
-    }
-
-    // TODO: move to android.net.NetworkUtils
-    @VisibleForTesting
-    public static int ipv4BroadcastAddress(byte[] addrBytes, int prefixLength) {
-        return bytesToBEInt(addrBytes) | (int) (Integer.toUnsignedLong(-1) >>> prefixLength);
-    }
-
-    private static int uint8(byte b) {
-        return b & 0xff;
-    }
-
-    private static int getUint16(ByteBuffer buffer, int position) {
-        return buffer.getShort(position) & 0xffff;
-    }
-
-    private static long getUint32(ByteBuffer buffer, int position) {
-        return Integer.toUnsignedLong(buffer.getInt(position));
-    }
-
-    private static int getUint8(ByteBuffer buffer, int position) {
-        return uint8(buffer.get(position));
-    }
-
-    private static int bytesToBEInt(byte[] bytes) {
-        return (uint8(bytes[0]) << 24)
-                + (uint8(bytes[1]) << 16)
-                + (uint8(bytes[2]) << 8)
-                + (uint8(bytes[3]));
-    }
-
-    private static byte[] concatArrays(final byte[]... arr) {
-        int size = 0;
-        for (byte[] a : arr) {
-            size += a.length;
-        }
-        final byte[] result = new byte[size];
-        int offset = 0;
-        for (byte[] a : arr) {
-            System.arraycopy(a, 0, result, offset, a.length);
-            offset += a.length;
-        }
-        return result;
-    }
-}
diff --git a/packages/NetworkStack/src/android/net/apf/ApfGenerator.java b/packages/NetworkStack/src/android/net/apf/ApfGenerator.java
deleted file mode 100644
index 44ce2db..0000000
--- a/packages/NetworkStack/src/android/net/apf/ApfGenerator.java
+++ /dev/null
@@ -1,937 +0,0 @@
-/*
- * Copyright (C) 2016 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.net.apf;
-
-import java.util.ArrayList;
-import java.util.HashMap;
-
-/**
- * APF assembler/generator.  A tool for generating an APF program.
- *
- * Call add*() functions to add instructions to the program, then call
- * {@link generate} to get the APF bytecode for the program.
- *
- * @hide
- */
-public class ApfGenerator {
-    /**
-     * This exception is thrown when an attempt is made to generate an illegal instruction.
-     */
-    public static class IllegalInstructionException extends Exception {
-        IllegalInstructionException(String msg) {
-            super(msg);
-        }
-    }
-    private enum Opcodes {
-        LABEL(-1),
-        LDB(1),    // Load 1 byte from immediate offset, e.g. "ldb R0, [5]"
-        LDH(2),    // Load 2 bytes from immediate offset, e.g. "ldh R0, [5]"
-        LDW(3),    // Load 4 bytes from immediate offset, e.g. "ldw R0, [5]"
-        LDBX(4),   // Load 1 byte from immediate offset plus register, e.g. "ldbx R0, [5]R0"
-        LDHX(5),   // Load 2 byte from immediate offset plus register, e.g. "ldhx R0, [5]R0"
-        LDWX(6),   // Load 4 byte from immediate offset plus register, e.g. "ldwx R0, [5]R0"
-        ADD(7),    // Add, e.g. "add R0,5"
-        MUL(8),    // Multiply, e.g. "mul R0,5"
-        DIV(9),    // Divide, e.g. "div R0,5"
-        AND(10),   // And, e.g. "and R0,5"
-        OR(11),    // Or, e.g. "or R0,5"
-        SH(12),    // Left shift, e.g, "sh R0, 5" or "sh R0, -5" (shifts right)
-        LI(13),    // Load immediate, e.g. "li R0,5" (immediate encoded as signed value)
-        JMP(14),   // Jump, e.g. "jmp label"
-        JEQ(15),   // Compare equal and branch, e.g. "jeq R0,5,label"
-        JNE(16),   // Compare not equal and branch, e.g. "jne R0,5,label"
-        JGT(17),   // Compare greater than and branch, e.g. "jgt R0,5,label"
-        JLT(18),   // Compare less than and branch, e.g. "jlt R0,5,label"
-        JSET(19),  // Compare any bits set and branch, e.g. "jset R0,5,label"
-        JNEBS(20), // Compare not equal byte sequence, e.g. "jnebs R0,5,label,0x1122334455"
-        EXT(21),   // Followed by immediate indicating ExtendedOpcodes.
-        LDDW(22),  // Load 4 bytes from data memory address (register + immediate): "lddw R0, [5]R1"
-        STDW(23);  // Store 4 bytes to data memory address (register + immediate): "stdw R0, [5]R1"
-
-        final int value;
-
-        private Opcodes(int value) {
-            this.value = value;
-        }
-    }
-    // Extended opcodes. Primary opcode is Opcodes.EXT. ExtendedOpcodes are encoded in the immediate
-    // field.
-    private enum ExtendedOpcodes {
-        LDM(0),   // Load from memory, e.g. "ldm R0,5"
-        STM(16),  // Store to memory, e.g. "stm R0,5"
-        NOT(32),  // Not, e.g. "not R0"
-        NEG(33),  // Negate, e.g. "neg R0"
-        SWAP(34), // Swap, e.g. "swap R0,R1"
-        MOVE(35);  // Move, e.g. "move R0,R1"
-
-        final int value;
-
-        private ExtendedOpcodes(int value) {
-            this.value = value;
-        }
-    }
-    public enum Register {
-        R0(0),
-        R1(1);
-
-        final int value;
-
-        private Register(int value) {
-            this.value = value;
-        }
-    }
-    private class Instruction {
-        private final byte mOpcode;   // A "Opcode" value.
-        private final byte mRegister; // A "Register" value.
-        private boolean mHasImm;
-        private byte mImmSize;
-        private boolean mImmSigned;
-        private int mImm;
-        // When mOpcode is a jump:
-        private byte mTargetLabelSize;
-        private String mTargetLabel;
-        // When mOpcode == Opcodes.LABEL:
-        private String mLabel;
-        // When mOpcode == Opcodes.JNEBS:
-        private byte[] mCompareBytes;
-        // Offset in bytes from the beginning of this program. Set by {@link ApfGenerator#generate}.
-        int offset;
-
-        Instruction(Opcodes opcode, Register register) {
-            mOpcode = (byte)opcode.value;
-            mRegister = (byte)register.value;
-        }
-
-        Instruction(Opcodes opcode) {
-            this(opcode, Register.R0);
-        }
-
-        void setImm(int imm, boolean signed) {
-            mHasImm = true;
-            mImm = imm;
-            mImmSigned = signed;
-            mImmSize = calculateImmSize(imm, signed);
-        }
-
-        void setUnsignedImm(int imm) {
-            setImm(imm, false);
-        }
-
-        void setSignedImm(int imm) {
-            setImm(imm, true);
-        }
-
-        void setLabel(String label) throws IllegalInstructionException {
-            if (mLabels.containsKey(label)) {
-                throw new IllegalInstructionException("duplicate label " + label);
-            }
-            if (mOpcode != Opcodes.LABEL.value) {
-                throw new IllegalStateException("adding label to non-label instruction");
-            }
-            mLabel = label;
-            mLabels.put(label, this);
-        }
-
-        void setTargetLabel(String label) {
-            mTargetLabel = label;
-            mTargetLabelSize = 4; // May shrink later on in generate().
-        }
-
-        void setCompareBytes(byte[] bytes) {
-            if (mOpcode != Opcodes.JNEBS.value) {
-                throw new IllegalStateException("adding compare bytes to non-JNEBS instruction");
-            }
-            mCompareBytes = bytes;
-        }
-
-        /**
-         * @return size of instruction in bytes.
-         */
-        int size() {
-            if (mOpcode == Opcodes.LABEL.value) {
-                return 0;
-            }
-            int size = 1;
-            if (mHasImm) {
-                size += generatedImmSize();
-            }
-            if (mTargetLabel != null) {
-                size += generatedImmSize();
-            }
-            if (mCompareBytes != null) {
-                size += mCompareBytes.length;
-            }
-            return size;
-        }
-
-        /**
-         * Resize immediate value field so that it's only as big as required to
-         * contain the offset of the jump destination.
-         * @return {@code true} if shrunk.
-         */
-        boolean shrink() throws IllegalInstructionException {
-            if (mTargetLabel == null) {
-                return false;
-            }
-            int oldSize = size();
-            int oldTargetLabelSize = mTargetLabelSize;
-            mTargetLabelSize = calculateImmSize(calculateTargetLabelOffset(), false);
-            if (mTargetLabelSize > oldTargetLabelSize) {
-                throw new IllegalStateException("instruction grew");
-            }
-            return size() < oldSize;
-        }
-
-        /**
-         * Assemble value for instruction size field.
-         */
-        private byte generateImmSizeField() {
-            byte immSize = generatedImmSize();
-            // Encode size field to fit in 2 bits: 0->0, 1->1, 2->2, 3->4.
-            return immSize == 4 ? 3 : immSize;
-        }
-
-        /**
-         * Assemble first byte of generated instruction.
-         */
-        private byte generateInstructionByte() {
-            byte sizeField = generateImmSizeField();
-            return (byte)((mOpcode << 3) | (sizeField << 1) | mRegister);
-        }
-
-        /**
-         * Write {@code value} at offset {@code writingOffset} into {@code bytecode}.
-         * {@link generatedImmSize} bytes are written. {@code value} is truncated to
-         * {@code generatedImmSize} bytes. {@code value} is treated simply as a
-         * 32-bit value, so unsigned values should be zero extended and the truncation
-         * should simply throw away their zero-ed upper bits, and signed values should
-         * be sign extended and the truncation should simply throw away their signed
-         * upper bits.
-         */
-        private int writeValue(int value, byte[] bytecode, int writingOffset) {
-            for (int i = generatedImmSize() - 1; i >= 0; i--) {
-                bytecode[writingOffset++] = (byte)((value >> (i * 8)) & 255);
-            }
-            return writingOffset;
-        }
-
-        /**
-         * Generate bytecode for this instruction at offset {@link offset}.
-         */
-        void generate(byte[] bytecode) throws IllegalInstructionException {
-            if (mOpcode == Opcodes.LABEL.value) {
-                return;
-            }
-            int writingOffset = offset;
-            bytecode[writingOffset++] = generateInstructionByte();
-            if (mTargetLabel != null) {
-                writingOffset = writeValue(calculateTargetLabelOffset(), bytecode, writingOffset);
-            }
-            if (mHasImm) {
-                writingOffset = writeValue(mImm, bytecode, writingOffset);
-            }
-            if (mCompareBytes != null) {
-                System.arraycopy(mCompareBytes, 0, bytecode, writingOffset, mCompareBytes.length);
-                writingOffset += mCompareBytes.length;
-            }
-            if ((writingOffset - offset) != size()) {
-                throw new IllegalStateException("wrote " + (writingOffset - offset) +
-                        " but should have written " + size());
-            }
-        }
-
-        /**
-         * Calculate the size of either the immediate field or the target label field, if either is
-         * present. Most instructions have either an immediate or a target label field, but for the
-         * instructions that have both, the size of the target label field must be the same as the
-         * size of the immediate field, because there is only one length field in the instruction
-         * byte, hence why this function simply takes the maximum of the two sizes, so neither is
-         * truncated.
-         */
-        private byte generatedImmSize() {
-            return mImmSize > mTargetLabelSize ? mImmSize : mTargetLabelSize;
-        }
-
-        private int calculateTargetLabelOffset() throws IllegalInstructionException {
-            Instruction targetLabelInstruction;
-            if (mTargetLabel == DROP_LABEL) {
-                targetLabelInstruction = mDropLabel;
-            } else if (mTargetLabel == PASS_LABEL) {
-                targetLabelInstruction = mPassLabel;
-            } else {
-                targetLabelInstruction = mLabels.get(mTargetLabel);
-            }
-            if (targetLabelInstruction == null) {
-                throw new IllegalInstructionException("label not found: " + mTargetLabel);
-            }
-            // Calculate distance from end of this instruction to instruction.offset.
-            final int targetLabelOffset = targetLabelInstruction.offset - (offset + size());
-            if (targetLabelOffset < 0) {
-                throw new IllegalInstructionException("backward branches disallowed; label: " +
-                        mTargetLabel);
-            }
-            return targetLabelOffset;
-        }
-
-        private byte calculateImmSize(int imm, boolean signed) {
-            if (imm == 0) {
-                return 0;
-            }
-            if (signed && (imm >= -128 && imm <= 127) ||
-                    !signed && (imm >= 0 && imm <= 255)) {
-                return 1;
-            }
-            if (signed && (imm >= -32768 && imm <= 32767) ||
-                    !signed && (imm >= 0 && imm <= 65535)) {
-                return 2;
-            }
-            return 4;
-        }
-    }
-
-    /**
-     * Jump to this label to terminate the program and indicate the packet
-     * should be dropped.
-     */
-    public static final String DROP_LABEL = "__DROP__";
-
-    /**
-     * Jump to this label to terminate the program and indicate the packet
-     * should be passed to the AP.
-     */
-    public static final String PASS_LABEL = "__PASS__";
-
-    /**
-     * Number of memory slots available for access via APF stores to memory and loads from memory.
-     * The memory slots are numbered 0 to {@code MEMORY_SLOTS} - 1. This must be kept in sync with
-     * the APF interpreter.
-     */
-    public static final int MEMORY_SLOTS = 16;
-
-    /**
-     * Memory slot number that is prefilled with the IPv4 header length.
-     * Note that this memory slot may be overwritten by a program that
-     * executes stores to this memory slot. This must be kept in sync with
-     * the APF interpreter.
-     */
-    public static final int IPV4_HEADER_SIZE_MEMORY_SLOT = 13;
-
-    /**
-     * Memory slot number that is prefilled with the size of the packet being filtered in bytes.
-     * Note that this memory slot may be overwritten by a program that
-     * executes stores to this memory slot. This must be kept in sync with the APF interpreter.
-     */
-    public static final int PACKET_SIZE_MEMORY_SLOT = 14;
-
-    /**
-     * Memory slot number that is prefilled with the age of the filter in seconds. The age of the
-     * filter is the time since the filter was installed until now.
-     * Note that this memory slot may be overwritten by a program that
-     * executes stores to this memory slot. This must be kept in sync with the APF interpreter.
-     */
-    public static final int FILTER_AGE_MEMORY_SLOT = 15;
-
-    /**
-     * First memory slot containing prefilled values. Can be used in range comparisons to determine
-     * if memory slot index is within prefilled slots.
-     */
-    public static final int FIRST_PREFILLED_MEMORY_SLOT = IPV4_HEADER_SIZE_MEMORY_SLOT;
-
-    /**
-     * Last memory slot containing prefilled values. Can be used in range comparisons to determine
-     * if memory slot index is within prefilled slots.
-     */
-    public static final int LAST_PREFILLED_MEMORY_SLOT = FILTER_AGE_MEMORY_SLOT;
-
-    // This version number syncs up with APF_VERSION in hardware/google/apf/apf_interpreter.h
-    private static final int MIN_APF_VERSION = 2;
-
-    private final ArrayList<Instruction> mInstructions = new ArrayList<Instruction>();
-    private final HashMap<String, Instruction> mLabels = new HashMap<String, Instruction>();
-    private final Instruction mDropLabel = new Instruction(Opcodes.LABEL);
-    private final Instruction mPassLabel = new Instruction(Opcodes.LABEL);
-    private final int mVersion;
-    private boolean mGenerated;
-
-    /**
-     * Creates an ApfGenerator instance which is able to emit instructions for the specified
-     * {@code version} of the APF interpreter. Throws {@code IllegalInstructionException} if
-     * the requested version is unsupported.
-     */
-    ApfGenerator(int version) throws IllegalInstructionException {
-        mVersion = version;
-        requireApfVersion(MIN_APF_VERSION);
-    }
-
-    /**
-     * Returns true if the ApfGenerator supports the specified {@code version}, otherwise false.
-     */
-    public static boolean supportsVersion(int version) {
-        return version >= MIN_APF_VERSION;
-    }
-
-    private void requireApfVersion(int minimumVersion) throws IllegalInstructionException {
-        if (mVersion < minimumVersion) {
-            throw new IllegalInstructionException("Requires APF >= " + minimumVersion);
-        }
-    }
-
-    private void addInstruction(Instruction instruction) {
-        if (mGenerated) {
-            throw new IllegalStateException("Program already generated");
-        }
-        mInstructions.add(instruction);
-    }
-
-    /**
-     * Define a label at the current end of the program. Jumps can jump to this label. Labels are
-     * their own separate instructions, though with size 0. This facilitates having labels with
-     * no corresponding code to execute, for example a label at the end of a program. For example
-     * an {@link ApfGenerator} might be passed to a function that adds a filter like so:
-     * <pre>
-     *   load from packet
-     *   compare loaded data, jump if not equal to "next_filter"
-     *   load from packet
-     *   compare loaded data, jump if not equal to "next_filter"
-     *   jump to drop label
-     *   define "next_filter" here
-     * </pre>
-     * In this case "next_filter" may not have any generated code associated with it.
-     */
-    public ApfGenerator defineLabel(String name) throws IllegalInstructionException {
-        Instruction instruction = new Instruction(Opcodes.LABEL);
-        instruction.setLabel(name);
-        addInstruction(instruction);
-        return this;
-    }
-
-    /**
-     * Add an unconditional jump instruction to the end of the program.
-     */
-    public ApfGenerator addJump(String target) {
-        Instruction instruction = new Instruction(Opcodes.JMP);
-        instruction.setTargetLabel(target);
-        addInstruction(instruction);
-        return this;
-    }
-
-    /**
-     * Add an instruction to the end of the program to load the byte at offset {@code offset}
-     * bytes from the beginning of the packet into {@code register}.
-     */
-    public ApfGenerator addLoad8(Register register, int offset) {
-        Instruction instruction = new Instruction(Opcodes.LDB, register);
-        instruction.setUnsignedImm(offset);
-        addInstruction(instruction);
-        return this;
-    }
-
-    /**
-     * Add an instruction to the end of the program to load 16-bits at offset {@code offset}
-     * bytes from the beginning of the packet into {@code register}.
-     */
-    public ApfGenerator addLoad16(Register register, int offset) {
-        Instruction instruction = new Instruction(Opcodes.LDH, register);
-        instruction.setUnsignedImm(offset);
-        addInstruction(instruction);
-        return this;
-    }
-
-    /**
-     * Add an instruction to the end of the program to load 32-bits at offset {@code offset}
-     * bytes from the beginning of the packet into {@code register}.
-     */
-    public ApfGenerator addLoad32(Register register, int offset) {
-        Instruction instruction = new Instruction(Opcodes.LDW, register);
-        instruction.setUnsignedImm(offset);
-        addInstruction(instruction);
-        return this;
-    }
-
-    /**
-     * Add an instruction to the end of the program to load a byte from the packet into
-     * {@code register}. The offset of the loaded byte from the beginning of the packet is
-     * the sum of {@code offset} and the value in register R1.
-     */
-    public ApfGenerator addLoad8Indexed(Register register, int offset) {
-        Instruction instruction = new Instruction(Opcodes.LDBX, register);
-        instruction.setUnsignedImm(offset);
-        addInstruction(instruction);
-        return this;
-    }
-
-    /**
-     * Add an instruction to the end of the program to load 16-bits from the packet into
-     * {@code register}. The offset of the loaded 16-bits from the beginning of the packet is
-     * the sum of {@code offset} and the value in register R1.
-     */
-    public ApfGenerator addLoad16Indexed(Register register, int offset) {
-        Instruction instruction = new Instruction(Opcodes.LDHX, register);
-        instruction.setUnsignedImm(offset);
-        addInstruction(instruction);
-        return this;
-    }
-
-    /**
-     * Add an instruction to the end of the program to load 32-bits from the packet into
-     * {@code register}. The offset of the loaded 32-bits from the beginning of the packet is
-     * the sum of {@code offset} and the value in register R1.
-     */
-    public ApfGenerator addLoad32Indexed(Register register, int offset) {
-        Instruction instruction = new Instruction(Opcodes.LDWX, register);
-        instruction.setUnsignedImm(offset);
-        addInstruction(instruction);
-        return this;
-    }
-
-    /**
-     * Add an instruction to the end of the program to add {@code value} to register R0.
-     */
-    public ApfGenerator addAdd(int value) {
-        Instruction instruction = new Instruction(Opcodes.ADD);
-        instruction.setSignedImm(value);
-        addInstruction(instruction);
-        return this;
-    }
-
-    /**
-     * Add an instruction to the end of the program to multiply register R0 by {@code value}.
-     */
-    public ApfGenerator addMul(int value) {
-        Instruction instruction = new Instruction(Opcodes.MUL);
-        instruction.setSignedImm(value);
-        addInstruction(instruction);
-        return this;
-    }
-
-    /**
-     * Add an instruction to the end of the program to divide register R0 by {@code value}.
-     */
-    public ApfGenerator addDiv(int value) {
-        Instruction instruction = new Instruction(Opcodes.DIV);
-        instruction.setSignedImm(value);
-        addInstruction(instruction);
-        return this;
-    }
-
-    /**
-     * Add an instruction to the end of the program to logically and register R0 with {@code value}.
-     */
-    public ApfGenerator addAnd(int value) {
-        Instruction instruction = new Instruction(Opcodes.AND);
-        instruction.setUnsignedImm(value);
-        addInstruction(instruction);
-        return this;
-    }
-
-    /**
-     * Add an instruction to the end of the program to logically or register R0 with {@code value}.
-     */
-    public ApfGenerator addOr(int value) {
-        Instruction instruction = new Instruction(Opcodes.OR);
-        instruction.setUnsignedImm(value);
-        addInstruction(instruction);
-        return this;
-    }
-
-    /**
-     * Add an instruction to the end of the program to shift left register R0 by {@code value} bits.
-     */
-    public ApfGenerator addLeftShift(int value) {
-        Instruction instruction = new Instruction(Opcodes.SH);
-        instruction.setSignedImm(value);
-        addInstruction(instruction);
-        return this;
-    }
-
-    /**
-     * Add an instruction to the end of the program to shift right register R0 by {@code value}
-     * bits.
-     */
-    public ApfGenerator addRightShift(int value) {
-        Instruction instruction = new Instruction(Opcodes.SH);
-        instruction.setSignedImm(-value);
-        addInstruction(instruction);
-        return this;
-    }
-
-    /**
-     * Add an instruction to the end of the program to add register R1 to register R0.
-     */
-    public ApfGenerator addAddR1() {
-        Instruction instruction = new Instruction(Opcodes.ADD, Register.R1);
-        addInstruction(instruction);
-        return this;
-    }
-
-    /**
-     * Add an instruction to the end of the program to multiply register R0 by register R1.
-     */
-    public ApfGenerator addMulR1() {
-        Instruction instruction = new Instruction(Opcodes.MUL, Register.R1);
-        addInstruction(instruction);
-        return this;
-    }
-
-    /**
-     * Add an instruction to the end of the program to divide register R0 by register R1.
-     */
-    public ApfGenerator addDivR1() {
-        Instruction instruction = new Instruction(Opcodes.DIV, Register.R1);
-        addInstruction(instruction);
-        return this;
-    }
-
-    /**
-     * Add an instruction to the end of the program to logically and register R0 with register R1
-     * and store the result back into register R0.
-     */
-    public ApfGenerator addAndR1() {
-        Instruction instruction = new Instruction(Opcodes.AND, Register.R1);
-        addInstruction(instruction);
-        return this;
-    }
-
-    /**
-     * Add an instruction to the end of the program to logically or register R0 with register R1
-     * and store the result back into register R0.
-     */
-    public ApfGenerator addOrR1() {
-        Instruction instruction = new Instruction(Opcodes.OR, Register.R1);
-        addInstruction(instruction);
-        return this;
-    }
-
-    /**
-     * Add an instruction to the end of the program to shift register R0 left by the value in
-     * register R1.
-     */
-    public ApfGenerator addLeftShiftR1() {
-        Instruction instruction = new Instruction(Opcodes.SH, Register.R1);
-        addInstruction(instruction);
-        return this;
-    }
-
-    /**
-     * Add an instruction to the end of the program to move {@code value} into {@code register}.
-     */
-    public ApfGenerator addLoadImmediate(Register register, int value) {
-        Instruction instruction = new Instruction(Opcodes.LI, register);
-        instruction.setSignedImm(value);
-        addInstruction(instruction);
-        return this;
-    }
-
-    /**
-     * Add an instruction to the end of the program to jump to {@code target} if register R0's
-     * value equals {@code value}.
-     */
-    public ApfGenerator addJumpIfR0Equals(int value, String target) {
-        Instruction instruction = new Instruction(Opcodes.JEQ);
-        instruction.setUnsignedImm(value);
-        instruction.setTargetLabel(target);
-        addInstruction(instruction);
-        return this;
-    }
-
-    /**
-     * Add an instruction to the end of the program to jump to {@code target} if register R0's
-     * value does not equal {@code value}.
-     */
-    public ApfGenerator addJumpIfR0NotEquals(int value, String target) {
-        Instruction instruction = new Instruction(Opcodes.JNE);
-        instruction.setUnsignedImm(value);
-        instruction.setTargetLabel(target);
-        addInstruction(instruction);
-        return this;
-    }
-
-    /**
-     * Add an instruction to the end of the program to jump to {@code target} if register R0's
-     * value is greater than {@code value}.
-     */
-    public ApfGenerator addJumpIfR0GreaterThan(int value, String target) {
-        Instruction instruction = new Instruction(Opcodes.JGT);
-        instruction.setUnsignedImm(value);
-        instruction.setTargetLabel(target);
-        addInstruction(instruction);
-        return this;
-    }
-
-    /**
-     * Add an instruction to the end of the program to jump to {@code target} if register R0's
-     * value is less than {@code value}.
-     */
-    public ApfGenerator addJumpIfR0LessThan(int value, String target) {
-        Instruction instruction = new Instruction(Opcodes.JLT);
-        instruction.setUnsignedImm(value);
-        instruction.setTargetLabel(target);
-        addInstruction(instruction);
-        return this;
-    }
-
-    /**
-     * Add an instruction to the end of the program to jump to {@code target} if register R0's
-     * value has any bits set that are also set in {@code value}.
-     */
-    public ApfGenerator addJumpIfR0AnyBitsSet(int value, String target) {
-        Instruction instruction = new Instruction(Opcodes.JSET);
-        instruction.setUnsignedImm(value);
-        instruction.setTargetLabel(target);
-        addInstruction(instruction);
-        return this;
-    }
-    /**
-     * Add an instruction to the end of the program to jump to {@code target} if register R0's
-     * value equals register R1's value.
-     */
-    public ApfGenerator addJumpIfR0EqualsR1(String target) {
-        Instruction instruction = new Instruction(Opcodes.JEQ, Register.R1);
-        instruction.setTargetLabel(target);
-        addInstruction(instruction);
-        return this;
-    }
-
-    /**
-     * Add an instruction to the end of the program to jump to {@code target} if register R0's
-     * value does not equal register R1's value.
-     */
-    public ApfGenerator addJumpIfR0NotEqualsR1(String target) {
-        Instruction instruction = new Instruction(Opcodes.JNE, Register.R1);
-        instruction.setTargetLabel(target);
-        addInstruction(instruction);
-        return this;
-    }
-
-    /**
-     * Add an instruction to the end of the program to jump to {@code target} if register R0's
-     * value is greater than register R1's value.
-     */
-    public ApfGenerator addJumpIfR0GreaterThanR1(String target) {
-        Instruction instruction = new Instruction(Opcodes.JGT, Register.R1);
-        instruction.setTargetLabel(target);
-        addInstruction(instruction);
-        return this;
-    }
-
-    /**
-     * Add an instruction to the end of the program to jump to {@code target} if register R0's
-     * value is less than register R1's value.
-     */
-    public ApfGenerator addJumpIfR0LessThanR1(String target) {
-        Instruction instruction = new Instruction(Opcodes.JLT, Register.R1);
-        instruction.setTargetLabel(target);
-        addInstruction(instruction);
-        return this;
-    }
-
-    /**
-     * Add an instruction to the end of the program to jump to {@code target} if register R0's
-     * value has any bits set that are also set in R1's value.
-     */
-    public ApfGenerator addJumpIfR0AnyBitsSetR1(String target) {
-        Instruction instruction = new Instruction(Opcodes.JSET, Register.R1);
-        instruction.setTargetLabel(target);
-        addInstruction(instruction);
-        return this;
-    }
-
-    /**
-     * Add an instruction to the end of the program to jump to {@code target} if the bytes of the
-     * packet at an offset specified by {@code register} match {@code bytes}.
-     */
-    public ApfGenerator addJumpIfBytesNotEqual(Register register, byte[] bytes, String target)
-            throws IllegalInstructionException {
-        if (register == Register.R1) {
-            throw new IllegalInstructionException("JNEBS fails with R1");
-        }
-        Instruction instruction = new Instruction(Opcodes.JNEBS, register);
-        instruction.setUnsignedImm(bytes.length);
-        instruction.setTargetLabel(target);
-        instruction.setCompareBytes(bytes);
-        addInstruction(instruction);
-        return this;
-    }
-
-    /**
-     * Add an instruction to the end of the program to load memory slot {@code slot} into
-     * {@code register}.
-     */
-    public ApfGenerator addLoadFromMemory(Register register, int slot)
-            throws IllegalInstructionException {
-        if (slot < 0 || slot > (MEMORY_SLOTS - 1)) {
-            throw new IllegalInstructionException("illegal memory slot number: " + slot);
-        }
-        Instruction instruction = new Instruction(Opcodes.EXT, register);
-        instruction.setUnsignedImm(ExtendedOpcodes.LDM.value + slot);
-        addInstruction(instruction);
-        return this;
-    }
-
-    /**
-     * Add an instruction to the end of the program to store {@code register} into memory slot
-     * {@code slot}.
-     */
-    public ApfGenerator addStoreToMemory(Register register, int slot)
-            throws IllegalInstructionException {
-        if (slot < 0 || slot > (MEMORY_SLOTS - 1)) {
-            throw new IllegalInstructionException("illegal memory slot number: " + slot);
-        }
-        Instruction instruction = new Instruction(Opcodes.EXT, register);
-        instruction.setUnsignedImm(ExtendedOpcodes.STM.value + slot);
-        addInstruction(instruction);
-        return this;
-    }
-
-    /**
-     * Add an instruction to the end of the program to logically not {@code register}.
-     */
-    public ApfGenerator addNot(Register register) {
-        Instruction instruction = new Instruction(Opcodes.EXT, register);
-        instruction.setUnsignedImm(ExtendedOpcodes.NOT.value);
-        addInstruction(instruction);
-        return this;
-    }
-
-    /**
-     * Add an instruction to the end of the program to negate {@code register}.
-     */
-    public ApfGenerator addNeg(Register register) {
-        Instruction instruction = new Instruction(Opcodes.EXT, register);
-        instruction.setUnsignedImm(ExtendedOpcodes.NEG.value);
-        addInstruction(instruction);
-        return this;
-    }
-
-    /**
-     * Add an instruction to swap the values in register R0 and register R1.
-     */
-    public ApfGenerator addSwap() {
-        Instruction instruction = new Instruction(Opcodes.EXT);
-        instruction.setUnsignedImm(ExtendedOpcodes.SWAP.value);
-        addInstruction(instruction);
-        return this;
-    }
-
-    /**
-     * Add an instruction to the end of the program to move the value into
-     * {@code register} from the other register.
-     */
-    public ApfGenerator addMove(Register register) {
-        Instruction instruction = new Instruction(Opcodes.EXT, register);
-        instruction.setUnsignedImm(ExtendedOpcodes.MOVE.value);
-        addInstruction(instruction);
-        return this;
-    }
-
-    /**
-     * Add an instruction to the end of the program to load 32 bits from the data memory into
-     * {@code register}. The source address is computed by adding the signed immediate
-     * @{code offset} to the other register.
-     * Requires APF v3 or greater.
-     */
-    public ApfGenerator addLoadData(Register destinationRegister, int offset)
-            throws IllegalInstructionException {
-        requireApfVersion(3);
-        Instruction instruction = new Instruction(Opcodes.LDDW, destinationRegister);
-        instruction.setSignedImm(offset);
-        addInstruction(instruction);
-        return this;
-    }
-
-    /**
-     * Add an instruction to the end of the program to store 32 bits from {@code register} into the
-     * data memory. The destination address is computed by adding the signed immediate
-     * @{code offset} to the other register.
-     * Requires APF v3 or greater.
-     */
-    public ApfGenerator addStoreData(Register sourceRegister, int offset)
-            throws IllegalInstructionException {
-        requireApfVersion(3);
-        Instruction instruction = new Instruction(Opcodes.STDW, sourceRegister);
-        instruction.setSignedImm(offset);
-        addInstruction(instruction);
-        return this;
-    }
-
-    /**
-     * Updates instruction offset fields using latest instruction sizes.
-     * @return current program length in bytes.
-     */
-    private int updateInstructionOffsets() {
-        int offset = 0;
-        for (Instruction instruction : mInstructions) {
-            instruction.offset = offset;
-            offset += instruction.size();
-        }
-        return offset;
-    }
-
-    /**
-     * Returns an overestimate of the size of the generated program. {@link #generate} may return
-     * a program that is smaller.
-     */
-    public int programLengthOverEstimate() {
-        return updateInstructionOffsets();
-    }
-
-    /**
-     * Generate the bytecode for the APF program.
-     * @return the bytecode.
-     * @throws IllegalStateException if a label is referenced but not defined.
-     */
-    public byte[] generate() throws IllegalInstructionException {
-        // Enforce that we can only generate once because we cannot unshrink instructions and
-        // PASS/DROP labels may move further away requiring unshrinking if we add further
-        // instructions.
-        if (mGenerated) {
-            throw new IllegalStateException("Can only generate() once!");
-        }
-        mGenerated = true;
-        int total_size;
-        boolean shrunk;
-        // Shrink the immediate value fields of instructions.
-        // As we shrink the instructions some branch offset
-        // fields may shrink also, thereby shrinking the
-        // instructions further. Loop until we've reached the
-        // minimum size. Rarely will this loop more than a few times.
-        // Limit iterations to avoid O(n^2) behavior.
-        int iterations_remaining = 10;
-        do {
-            total_size = updateInstructionOffsets();
-            // Update drop and pass label offsets.
-            mDropLabel.offset = total_size + 1;
-            mPassLabel.offset = total_size;
-            // Limit run-time in aberant circumstances.
-            if (iterations_remaining-- == 0) break;
-            // Attempt to shrink instructions.
-            shrunk = false;
-            for (Instruction instruction : mInstructions) {
-                if (instruction.shrink()) {
-                    shrunk = true;
-                }
-            }
-        } while (shrunk);
-        // Generate bytecode for instructions.
-        byte[] bytecode = new byte[total_size];
-        for (Instruction instruction : mInstructions) {
-            instruction.generate(bytecode);
-        }
-        return bytecode;
-    }
-}
-
diff --git a/packages/NetworkStack/src/android/net/dhcp/DhcpAckPacket.java b/packages/NetworkStack/src/android/net/dhcp/DhcpAckPacket.java
deleted file mode 100644
index b2eb4e2..0000000
--- a/packages/NetworkStack/src/android/net/dhcp/DhcpAckPacket.java
+++ /dev/null
@@ -1,88 +0,0 @@
-/*
- * 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 android.net.dhcp;
-
-import java.net.Inet4Address;
-import java.nio.ByteBuffer;
-
-/**
- * This class implements the DHCP-ACK packet.
- */
-class DhcpAckPacket extends DhcpPacket {
-
-    /**
-     * The address of the server which sent this packet.
-     */
-    private final Inet4Address mSrcIp;
-
-    DhcpAckPacket(int transId, short secs, boolean broadcast, Inet4Address serverAddress,
-            Inet4Address relayIp, Inet4Address clientIp, Inet4Address yourIp, byte[] clientMac) {
-        super(transId, secs, clientIp, yourIp, serverAddress, relayIp, clientMac, broadcast);
-        mBroadcast = broadcast;
-        mSrcIp = serverAddress;
-    }
-
-    public String toString() {
-        String s = super.toString();
-        String dnsServers = " DNS servers: ";
-
-        for (Inet4Address dnsServer: mDnsServers) {
-            dnsServers += dnsServer.toString() + " ";
-        }
-
-        return s + " ACK: your new IP " + mYourIp +
-                ", netmask " + mSubnetMask +
-                ", gateways " + mGateways + dnsServers +
-                ", lease time " + mLeaseTime;
-    }
-
-    /**
-     * Fills in a packet with the requested ACK parameters.
-     */
-    public ByteBuffer buildPacket(int encap, short destUdp, short srcUdp) {
-        ByteBuffer result = ByteBuffer.allocate(MAX_LENGTH);
-        Inet4Address destIp = mBroadcast ? INADDR_BROADCAST : mYourIp;
-        Inet4Address srcIp = mBroadcast ? INADDR_ANY : mSrcIp;
-
-        fillInPacket(encap, destIp, srcIp, destUdp, srcUdp, result,
-            DHCP_BOOTREPLY, mBroadcast);
-        result.flip();
-        return result;
-    }
-
-    /**
-     * Adds the optional parameters to the client-generated ACK packet.
-     */
-    void finishPacket(ByteBuffer buffer) {
-        addTlv(buffer, DHCP_MESSAGE_TYPE, DHCP_MESSAGE_TYPE_ACK);
-        addTlv(buffer, DHCP_SERVER_IDENTIFIER, mServerIdentifier);
-
-        addCommonServerTlvs(buffer);
-        addTlvEnd(buffer);
-    }
-
-    /**
-     * Un-boxes an Integer, returning 0 if a null reference is supplied.
-     */
-    private static final int getInt(Integer v) {
-        if (v == null) {
-            return 0;
-        } else {
-            return v.intValue();
-        }
-    }
-}
diff --git a/packages/NetworkStack/src/android/net/dhcp/DhcpClient.java b/packages/NetworkStack/src/android/net/dhcp/DhcpClient.java
deleted file mode 100644
index ca6c17a..0000000
--- a/packages/NetworkStack/src/android/net/dhcp/DhcpClient.java
+++ /dev/null
@@ -1,1070 +0,0 @@
-/*
- * Copyright (C) 2015 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.net.dhcp;
-
-import static android.net.dhcp.DhcpPacket.DHCP_BROADCAST_ADDRESS;
-import static android.net.dhcp.DhcpPacket.DHCP_DNS_SERVER;
-import static android.net.dhcp.DhcpPacket.DHCP_DOMAIN_NAME;
-import static android.net.dhcp.DhcpPacket.DHCP_LEASE_TIME;
-import static android.net.dhcp.DhcpPacket.DHCP_MTU;
-import static android.net.dhcp.DhcpPacket.DHCP_REBINDING_TIME;
-import static android.net.dhcp.DhcpPacket.DHCP_RENEWAL_TIME;
-import static android.net.dhcp.DhcpPacket.DHCP_ROUTER;
-import static android.net.dhcp.DhcpPacket.DHCP_SUBNET_MASK;
-import static android.net.dhcp.DhcpPacket.DHCP_VENDOR_INFO;
-import static android.net.dhcp.DhcpPacket.INADDR_ANY;
-import static android.net.dhcp.DhcpPacket.INADDR_BROADCAST;
-import static android.net.util.NetworkStackUtils.closeSocketQuietly;
-import static android.net.util.SocketUtils.makePacketSocketAddress;
-import static android.system.OsConstants.AF_INET;
-import static android.system.OsConstants.AF_PACKET;
-import static android.system.OsConstants.ETH_P_IP;
-import static android.system.OsConstants.IPPROTO_UDP;
-import static android.system.OsConstants.SOCK_DGRAM;
-import static android.system.OsConstants.SOCK_RAW;
-import static android.system.OsConstants.SOL_SOCKET;
-import static android.system.OsConstants.SO_BROADCAST;
-import static android.system.OsConstants.SO_RCVBUF;
-import static android.system.OsConstants.SO_REUSEADDR;
-
-import static com.android.server.util.NetworkStackConstants.IPV4_ADDR_ANY;
-
-import android.content.Context;
-import android.net.DhcpResults;
-import android.net.InetAddresses;
-import android.net.TrafficStats;
-import android.net.ip.IpClient;
-import android.net.metrics.DhcpClientEvent;
-import android.net.metrics.DhcpErrorEvent;
-import android.net.metrics.IpConnectivityLog;
-import android.net.util.InterfaceParams;
-import android.net.util.NetworkStackUtils;
-import android.net.util.SocketUtils;
-import android.os.Message;
-import android.os.SystemClock;
-import android.system.ErrnoException;
-import android.system.Os;
-import android.util.EventLog;
-import android.util.Log;
-import android.util.SparseArray;
-
-import com.android.internal.util.HexDump;
-import com.android.internal.util.MessageUtils;
-import com.android.internal.util.State;
-import com.android.internal.util.StateMachine;
-import com.android.internal.util.TrafficStatsConstants;
-import com.android.internal.util.WakeupMessage;
-import com.android.networkstack.R;
-
-import java.io.FileDescriptor;
-import java.io.IOException;
-import java.net.Inet4Address;
-import java.net.SocketAddress;
-import java.net.SocketException;
-import java.nio.ByteBuffer;
-import java.util.Arrays;
-import java.util.Random;
-
-/**
- * A DHCPv4 client.
- *
- * Written to behave similarly to the DhcpStateMachine + dhcpcd 5.5.6 combination used in Android
- * 5.1 and below, as configured on Nexus 6. The interface is the same as DhcpStateMachine.
- *
- * TODO:
- *
- * - Exponential backoff when receiving NAKs (not specified by the RFC, but current behaviour).
- * - Support persisting lease state and support INIT-REBOOT. Android 5.1 does this, but it does not
- *   do so correctly: instead of requesting the lease last obtained on a particular network (e.g., a
- *   given SSID), it requests the last-leased IP address on the same interface, causing a delay if
- *   the server NAKs or a timeout if it doesn't.
- *
- * Known differences from current behaviour:
- *
- * - Does not request the "static routes" option.
- * - Does not support BOOTP servers. DHCP has been around since 1993, should be everywhere now.
- * - Requests the "broadcast" option, but does nothing with it.
- * - Rejects invalid subnet masks such as 255.255.255.1 (current code treats that as 255.255.255.0).
- *
- * @hide
- */
-public class DhcpClient extends StateMachine {
-
-    private static final String TAG = "DhcpClient";
-    private static final boolean DBG = true;
-    private static final boolean STATE_DBG = Log.isLoggable(TAG, Log.DEBUG);
-    private static final boolean MSG_DBG = Log.isLoggable(TAG, Log.DEBUG);
-    private static final boolean PACKET_DBG = Log.isLoggable(TAG, Log.DEBUG);
-
-    // Metrics events: must be kept in sync with server-side aggregation code.
-    /** Represents transitions from DhcpInitState to DhcpBoundState */
-    private static final String EVENT_INITIAL_BOUND = "InitialBoundState";
-    /** Represents transitions from and to DhcpBoundState via DhcpRenewingState */
-    private static final String EVENT_RENEWING_BOUND = "RenewingBoundState";
-
-    // Timers and timeouts.
-    private static final int SECONDS = 1000;
-    private static final int FIRST_TIMEOUT_MS   =   2 * SECONDS;
-    private static final int MAX_TIMEOUT_MS     = 128 * SECONDS;
-
-    // This is not strictly needed, since the client is asynchronous and implements exponential
-    // backoff. It's maintained for backwards compatibility with the previous DHCP code, which was
-    // a blocking operation with a 30-second timeout. We pick 36 seconds so we can send packets at
-    // t=0, t=2, t=6, t=14, t=30, allowing for 10% jitter.
-    private static final int DHCP_TIMEOUT_MS    =  36 * SECONDS;
-
-    // DhcpClient uses IpClient's handler.
-    private static final int PUBLIC_BASE = IpClient.DHCPCLIENT_CMD_BASE;
-
-    // Below constants are picked up by MessageUtils and exempt from ProGuard optimization.
-    /* Commands from controller to start/stop DHCP */
-    public static final int CMD_START_DHCP                  = PUBLIC_BASE + 1;
-    public static final int CMD_STOP_DHCP                   = PUBLIC_BASE + 2;
-
-    /* Notification from DHCP state machine prior to DHCP discovery/renewal */
-    public static final int CMD_PRE_DHCP_ACTION             = PUBLIC_BASE + 3;
-    /* Notification from DHCP state machine post DHCP discovery/renewal. Indicates
-     * success/failure */
-    public static final int CMD_POST_DHCP_ACTION            = PUBLIC_BASE + 4;
-    /* Notification from DHCP state machine before quitting */
-    public static final int CMD_ON_QUIT                     = PUBLIC_BASE + 5;
-
-    /* Command from controller to indicate DHCP discovery/renewal can continue
-     * after pre DHCP action is complete */
-    public static final int CMD_PRE_DHCP_ACTION_COMPLETE    = PUBLIC_BASE + 6;
-
-    /* Command and event notification to/from IpManager requesting the setting
-     * (or clearing) of an IPv4 LinkAddress.
-     */
-    public static final int CMD_CLEAR_LINKADDRESS           = PUBLIC_BASE + 7;
-    public static final int CMD_CONFIGURE_LINKADDRESS       = PUBLIC_BASE + 8;
-    public static final int EVENT_LINKADDRESS_CONFIGURED    = PUBLIC_BASE + 9;
-
-    /* Message.arg1 arguments to CMD_POST_DHCP_ACTION notification */
-    public static final int DHCP_SUCCESS = 1;
-    public static final int DHCP_FAILURE = 2;
-
-    // Internal messages.
-    private static final int PRIVATE_BASE         = IpClient.DHCPCLIENT_CMD_BASE + 100;
-    private static final int CMD_KICK             = PRIVATE_BASE + 1;
-    private static final int CMD_RECEIVED_PACKET  = PRIVATE_BASE + 2;
-    private static final int CMD_TIMEOUT          = PRIVATE_BASE + 3;
-    private static final int CMD_RENEW_DHCP       = PRIVATE_BASE + 4;
-    private static final int CMD_REBIND_DHCP      = PRIVATE_BASE + 5;
-    private static final int CMD_EXPIRE_DHCP      = PRIVATE_BASE + 6;
-
-    // For message logging.
-    private static final Class[] sMessageClasses = { DhcpClient.class };
-    private static final SparseArray<String> sMessageNames =
-            MessageUtils.findMessageNames(sMessageClasses);
-
-    // DHCP parameters that we request.
-    /* package */ static final byte[] REQUESTED_PARAMS = new byte[] {
-        DHCP_SUBNET_MASK,
-        DHCP_ROUTER,
-        DHCP_DNS_SERVER,
-        DHCP_DOMAIN_NAME,
-        DHCP_MTU,
-        DHCP_BROADCAST_ADDRESS,  // TODO: currently ignored.
-        DHCP_LEASE_TIME,
-        DHCP_RENEWAL_TIME,
-        DHCP_REBINDING_TIME,
-        DHCP_VENDOR_INFO,
-    };
-
-    // DHCP flag that means "yes, we support unicast."
-    private static final boolean DO_UNICAST   = false;
-
-    // System services / libraries we use.
-    private final Context mContext;
-    private final Random mRandom;
-    private final IpConnectivityLog mMetricsLog = new IpConnectivityLog();
-
-    // Sockets.
-    // - We use a packet socket to receive, because servers send us packets bound for IP addresses
-    //   which we have not yet configured, and the kernel protocol stack drops these.
-    // - We use a UDP socket to send, so the kernel handles ARP and routing for us (DHCP servers can
-    //   be off-link as well as on-link).
-    private FileDescriptor mPacketSock;
-    private FileDescriptor mUdpSock;
-    private ReceiveThread mReceiveThread;
-
-    // State variables.
-    private final StateMachine mController;
-    private final WakeupMessage mKickAlarm;
-    private final WakeupMessage mTimeoutAlarm;
-    private final WakeupMessage mRenewAlarm;
-    private final WakeupMessage mRebindAlarm;
-    private final WakeupMessage mExpiryAlarm;
-    private final String mIfaceName;
-
-    private boolean mRegisteredForPreDhcpNotification;
-    private InterfaceParams mIface;
-    // TODO: MacAddress-ify more of this class hierarchy.
-    private byte[] mHwAddr;
-    private SocketAddress mInterfaceBroadcastAddr;
-    private int mTransactionId;
-    private long mTransactionStartMillis;
-    private DhcpResults mDhcpLease;
-    private long mDhcpLeaseExpiry;
-    private DhcpResults mOffer;
-
-    // Milliseconds SystemClock timestamps used to record transition times to DhcpBoundState.
-    private long mLastInitEnterTime;
-    private long mLastBoundExitTime;
-
-    // States.
-    private State mStoppedState = new StoppedState();
-    private State mDhcpState = new DhcpState();
-    private State mDhcpInitState = new DhcpInitState();
-    private State mDhcpSelectingState = new DhcpSelectingState();
-    private State mDhcpRequestingState = new DhcpRequestingState();
-    private State mDhcpHaveLeaseState = new DhcpHaveLeaseState();
-    private State mConfiguringInterfaceState = new ConfiguringInterfaceState();
-    private State mDhcpBoundState = new DhcpBoundState();
-    private State mDhcpRenewingState = new DhcpRenewingState();
-    private State mDhcpRebindingState = new DhcpRebindingState();
-    private State mDhcpInitRebootState = new DhcpInitRebootState();
-    private State mDhcpRebootingState = new DhcpRebootingState();
-    private State mWaitBeforeStartState = new WaitBeforeStartState(mDhcpInitState);
-    private State mWaitBeforeRenewalState = new WaitBeforeRenewalState(mDhcpRenewingState);
-
-    private WakeupMessage makeWakeupMessage(String cmdName, int cmd) {
-        cmdName = DhcpClient.class.getSimpleName() + "." + mIfaceName + "." + cmdName;
-        return new WakeupMessage(mContext, getHandler(), cmdName, cmd);
-    }
-
-    // TODO: Take an InterfaceParams instance instead of an interface name String.
-    private DhcpClient(Context context, StateMachine controller, String iface) {
-        super(TAG, controller.getHandler());
-
-        mContext = context;
-        mController = controller;
-        mIfaceName = iface;
-
-        addState(mStoppedState);
-        addState(mDhcpState);
-            addState(mDhcpInitState, mDhcpState);
-            addState(mWaitBeforeStartState, mDhcpState);
-            addState(mDhcpSelectingState, mDhcpState);
-            addState(mDhcpRequestingState, mDhcpState);
-            addState(mDhcpHaveLeaseState, mDhcpState);
-                addState(mConfiguringInterfaceState, mDhcpHaveLeaseState);
-                addState(mDhcpBoundState, mDhcpHaveLeaseState);
-                addState(mWaitBeforeRenewalState, mDhcpHaveLeaseState);
-                addState(mDhcpRenewingState, mDhcpHaveLeaseState);
-                addState(mDhcpRebindingState, mDhcpHaveLeaseState);
-            addState(mDhcpInitRebootState, mDhcpState);
-            addState(mDhcpRebootingState, mDhcpState);
-
-        setInitialState(mStoppedState);
-
-        mRandom = new Random();
-
-        // Used to schedule packet retransmissions.
-        mKickAlarm = makeWakeupMessage("KICK", CMD_KICK);
-        // Used to time out PacketRetransmittingStates.
-        mTimeoutAlarm = makeWakeupMessage("TIMEOUT", CMD_TIMEOUT);
-        // Used to schedule DHCP reacquisition.
-        mRenewAlarm = makeWakeupMessage("RENEW", CMD_RENEW_DHCP);
-        mRebindAlarm = makeWakeupMessage("REBIND", CMD_REBIND_DHCP);
-        mExpiryAlarm = makeWakeupMessage("EXPIRY", CMD_EXPIRE_DHCP);
-    }
-
-    public void registerForPreDhcpNotification() {
-        mRegisteredForPreDhcpNotification = true;
-    }
-
-    public static DhcpClient makeDhcpClient(
-            Context context, StateMachine controller, InterfaceParams ifParams) {
-        DhcpClient client = new DhcpClient(context, controller, ifParams.name);
-        client.mIface = ifParams;
-        client.start();
-        return client;
-    }
-
-    private boolean initInterface() {
-        if (mIface == null) mIface = InterfaceParams.getByName(mIfaceName);
-        if (mIface == null) {
-            Log.e(TAG, "Can't determine InterfaceParams for " + mIfaceName);
-            return false;
-        }
-
-        mHwAddr = mIface.macAddr.toByteArray();
-        mInterfaceBroadcastAddr = makePacketSocketAddress(mIface.index, DhcpPacket.ETHER_BROADCAST);
-        return true;
-    }
-
-    private void startNewTransaction() {
-        mTransactionId = mRandom.nextInt();
-        mTransactionStartMillis = SystemClock.elapsedRealtime();
-    }
-
-    private boolean initSockets() {
-        return initPacketSocket() && initUdpSocket();
-    }
-
-    private boolean initPacketSocket() {
-        try {
-            mPacketSock = Os.socket(AF_PACKET, SOCK_RAW, ETH_P_IP);
-            SocketAddress addr = makePacketSocketAddress((short) ETH_P_IP, mIface.index);
-            Os.bind(mPacketSock, addr);
-            NetworkStackUtils.attachDhcpFilter(mPacketSock);
-        } catch(SocketException|ErrnoException e) {
-            Log.e(TAG, "Error creating packet socket", e);
-            return false;
-        }
-        return true;
-    }
-
-    private boolean initUdpSocket() {
-        final int oldTag = TrafficStats.getAndSetThreadStatsTag(
-                TrafficStatsConstants.TAG_SYSTEM_DHCP);
-        try {
-            mUdpSock = Os.socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
-            SocketUtils.bindSocketToInterface(mUdpSock, mIfaceName);
-            Os.setsockoptInt(mUdpSock, SOL_SOCKET, SO_REUSEADDR, 1);
-            Os.setsockoptInt(mUdpSock, SOL_SOCKET, SO_BROADCAST, 1);
-            Os.setsockoptInt(mUdpSock, SOL_SOCKET, SO_RCVBUF, 0);
-            Os.bind(mUdpSock, IPV4_ADDR_ANY, DhcpPacket.DHCP_CLIENT);
-        } catch(SocketException|ErrnoException e) {
-            Log.e(TAG, "Error creating UDP socket", e);
-            return false;
-        } finally {
-            TrafficStats.setThreadStatsTag(oldTag);
-        }
-        return true;
-    }
-
-    private boolean connectUdpSock(Inet4Address to) {
-        try {
-            Os.connect(mUdpSock, to, DhcpPacket.DHCP_SERVER);
-            return true;
-        } catch (SocketException|ErrnoException e) {
-            Log.e(TAG, "Error connecting UDP socket", e);
-            return false;
-        }
-    }
-
-    private void closeSockets() {
-        closeSocketQuietly(mUdpSock);
-        closeSocketQuietly(mPacketSock);
-    }
-
-    class ReceiveThread extends Thread {
-
-        private final byte[] mPacket = new byte[DhcpPacket.MAX_LENGTH];
-        private volatile boolean mStopped = false;
-
-        public void halt() {
-            mStopped = true;
-            closeSockets();  // Interrupts the read() call the thread is blocked in.
-        }
-
-        @Override
-        public void run() {
-            if (DBG) Log.d(TAG, "Receive thread started");
-            while (!mStopped) {
-                int length = 0;  // Or compiler can't tell it's initialized if a parse error occurs.
-                try {
-                    length = Os.read(mPacketSock, mPacket, 0, mPacket.length);
-                    DhcpPacket packet = null;
-                    packet = DhcpPacket.decodeFullPacket(mPacket, length, DhcpPacket.ENCAP_L2);
-                    if (DBG) Log.d(TAG, "Received packet: " + packet);
-                    sendMessage(CMD_RECEIVED_PACKET, packet);
-                } catch (IOException|ErrnoException e) {
-                    if (!mStopped) {
-                        Log.e(TAG, "Read error", e);
-                        logError(DhcpErrorEvent.RECEIVE_ERROR);
-                    }
-                } catch (DhcpPacket.ParseException e) {
-                    Log.e(TAG, "Can't parse packet: " + e.getMessage());
-                    if (PACKET_DBG) {
-                        Log.d(TAG, HexDump.dumpHexString(mPacket, 0, length));
-                    }
-                    if (e.errorCode == DhcpErrorEvent.DHCP_NO_COOKIE) {
-                        int snetTagId = 0x534e4554;
-                        String bugId = "31850211";
-                        int uid = -1;
-                        String data = DhcpPacket.ParseException.class.getName();
-                        EventLog.writeEvent(snetTagId, bugId, uid, data);
-                    }
-                    logError(e.errorCode);
-                }
-            }
-            if (DBG) Log.d(TAG, "Receive thread stopped");
-        }
-    }
-
-    private short getSecs() {
-        return (short) ((SystemClock.elapsedRealtime() - mTransactionStartMillis) / 1000);
-    }
-
-    private boolean transmitPacket(ByteBuffer buf, String description, int encap, Inet4Address to) {
-        try {
-            if (encap == DhcpPacket.ENCAP_L2) {
-                if (DBG) Log.d(TAG, "Broadcasting " + description);
-                Os.sendto(mPacketSock, buf.array(), 0, buf.limit(), 0, mInterfaceBroadcastAddr);
-            } else if (encap == DhcpPacket.ENCAP_BOOTP && to.equals(INADDR_BROADCAST)) {
-                if (DBG) Log.d(TAG, "Broadcasting " + description);
-                // We only send L3-encapped broadcasts in DhcpRebindingState,
-                // where we have an IP address and an unconnected UDP socket.
-                //
-                // N.B.: We only need this codepath because DhcpRequestPacket
-                // hardcodes the source IP address to 0.0.0.0. We could reuse
-                // the packet socket if this ever changes.
-                Os.sendto(mUdpSock, buf, 0, to, DhcpPacket.DHCP_SERVER);
-            } else {
-                // It's safe to call getpeername here, because we only send unicast packets if we
-                // have an IP address, and we connect the UDP socket in DhcpBoundState#enter.
-                if (DBG) Log.d(TAG, String.format("Unicasting %s to %s",
-                        description, Os.getpeername(mUdpSock)));
-                Os.write(mUdpSock, buf);
-            }
-        } catch(ErrnoException|IOException e) {
-            Log.e(TAG, "Can't send packet: ", e);
-            return false;
-        }
-        return true;
-    }
-
-    private boolean sendDiscoverPacket() {
-        ByteBuffer packet = DhcpPacket.buildDiscoverPacket(
-                DhcpPacket.ENCAP_L2, mTransactionId, getSecs(), mHwAddr,
-                DO_UNICAST, REQUESTED_PARAMS);
-        return transmitPacket(packet, "DHCPDISCOVER", DhcpPacket.ENCAP_L2, INADDR_BROADCAST);
-    }
-
-    private boolean sendRequestPacket(
-            Inet4Address clientAddress, Inet4Address requestedAddress,
-            Inet4Address serverAddress, Inet4Address to) {
-        // TODO: should we use the transaction ID from the server?
-        final int encap = INADDR_ANY.equals(clientAddress)
-                ? DhcpPacket.ENCAP_L2 : DhcpPacket.ENCAP_BOOTP;
-
-        ByteBuffer packet = DhcpPacket.buildRequestPacket(
-                encap, mTransactionId, getSecs(), clientAddress,
-                DO_UNICAST, mHwAddr, requestedAddress,
-                serverAddress, REQUESTED_PARAMS, null);
-        String serverStr = (serverAddress != null) ? serverAddress.getHostAddress() : null;
-        String description = "DHCPREQUEST ciaddr=" + clientAddress.getHostAddress() +
-                             " request=" + requestedAddress.getHostAddress() +
-                             " serverid=" + serverStr;
-        return transmitPacket(packet, description, encap, to);
-    }
-
-    private void scheduleLeaseTimers() {
-        if (mDhcpLeaseExpiry == 0) {
-            Log.d(TAG, "Infinite lease, no timer scheduling needed");
-            return;
-        }
-
-        final long now = SystemClock.elapsedRealtime();
-
-        // TODO: consider getting the renew and rebind timers from T1 and T2.
-        // See also:
-        //     https://tools.ietf.org/html/rfc2131#section-4.4.5
-        //     https://tools.ietf.org/html/rfc1533#section-9.9
-        //     https://tools.ietf.org/html/rfc1533#section-9.10
-        final long remainingDelay = mDhcpLeaseExpiry - now;
-        final long renewDelay = remainingDelay / 2;
-        final long rebindDelay = remainingDelay * 7 / 8;
-        mRenewAlarm.schedule(now + renewDelay);
-        mRebindAlarm.schedule(now + rebindDelay);
-        mExpiryAlarm.schedule(now + remainingDelay);
-        Log.d(TAG, "Scheduling renewal in " + (renewDelay / 1000) + "s");
-        Log.d(TAG, "Scheduling rebind in " + (rebindDelay / 1000) + "s");
-        Log.d(TAG, "Scheduling expiry in " + (remainingDelay / 1000) + "s");
-    }
-
-    private void notifySuccess() {
-        mController.sendMessage(
-                CMD_POST_DHCP_ACTION, DHCP_SUCCESS, 0, new DhcpResults(mDhcpLease));
-    }
-
-    private void notifyFailure() {
-        mController.sendMessage(CMD_POST_DHCP_ACTION, DHCP_FAILURE, 0, null);
-    }
-
-    private void acceptDhcpResults(DhcpResults results, String msg) {
-        mDhcpLease = results;
-        if (mDhcpLease.dnsServers.isEmpty()) {
-            // supplement customized dns servers
-            String[] dnsServersList =
-                    mContext.getResources().getStringArray(R.array.config_default_dns_servers);
-            for (final String dnsServer : dnsServersList) {
-                try {
-                    mDhcpLease.dnsServers.add(InetAddresses.parseNumericAddress(dnsServer));
-                } catch (IllegalArgumentException e) {
-                    Log.e(TAG, "Invalid default DNS server: " + dnsServer, e);
-                }
-            }
-        }
-        mOffer = null;
-        Log.d(TAG, msg + " lease: " + mDhcpLease);
-        notifySuccess();
-    }
-
-    private void clearDhcpState() {
-        mDhcpLease = null;
-        mDhcpLeaseExpiry = 0;
-        mOffer = null;
-    }
-
-    /**
-     * Quit the DhcpStateMachine.
-     *
-     * @hide
-     */
-    public void doQuit() {
-        Log.d(TAG, "doQuit");
-        quit();
-    }
-
-    @Override
-    protected void onQuitting() {
-        Log.d(TAG, "onQuitting");
-        mController.sendMessage(CMD_ON_QUIT);
-    }
-
-    abstract class LoggingState extends State {
-        private long mEnterTimeMs;
-
-        @Override
-        public void enter() {
-            if (STATE_DBG) Log.d(TAG, "Entering state " + getName());
-            mEnterTimeMs = SystemClock.elapsedRealtime();
-        }
-
-        @Override
-        public void exit() {
-            long durationMs = SystemClock.elapsedRealtime() - mEnterTimeMs;
-            logState(getName(), (int) durationMs);
-        }
-
-        private String messageName(int what) {
-            return sMessageNames.get(what, Integer.toString(what));
-        }
-
-        private String messageToString(Message message) {
-            long now = SystemClock.uptimeMillis();
-            return new StringBuilder(" ")
-                    .append(message.getWhen() - now)
-                    .append(messageName(message.what))
-                    .append(" ").append(message.arg1)
-                    .append(" ").append(message.arg2)
-                    .append(" ").append(message.obj)
-                    .toString();
-        }
-
-        @Override
-        public boolean processMessage(Message message) {
-            if (MSG_DBG) {
-                Log.d(TAG, getName() + messageToString(message));
-            }
-            return NOT_HANDLED;
-        }
-
-        @Override
-        public String getName() {
-            // All DhcpClient's states are inner classes with a well defined name.
-            // Use getSimpleName() and avoid super's getName() creating new String instances.
-            return getClass().getSimpleName();
-        }
-    }
-
-    // Sends CMD_PRE_DHCP_ACTION to the controller, waits for the controller to respond with
-    // CMD_PRE_DHCP_ACTION_COMPLETE, and then transitions to mOtherState.
-    abstract class WaitBeforeOtherState extends LoggingState {
-        protected State mOtherState;
-
-        @Override
-        public void enter() {
-            super.enter();
-            mController.sendMessage(CMD_PRE_DHCP_ACTION);
-        }
-
-        @Override
-        public boolean processMessage(Message message) {
-            super.processMessage(message);
-            switch (message.what) {
-                case CMD_PRE_DHCP_ACTION_COMPLETE:
-                    transitionTo(mOtherState);
-                    return HANDLED;
-                default:
-                    return NOT_HANDLED;
-            }
-        }
-    }
-
-    class StoppedState extends State {
-        @Override
-        public boolean processMessage(Message message) {
-            switch (message.what) {
-                case CMD_START_DHCP:
-                    if (mRegisteredForPreDhcpNotification) {
-                        transitionTo(mWaitBeforeStartState);
-                    } else {
-                        transitionTo(mDhcpInitState);
-                    }
-                    return HANDLED;
-                default:
-                    return NOT_HANDLED;
-            }
-        }
-    }
-
-    class WaitBeforeStartState extends WaitBeforeOtherState {
-        public WaitBeforeStartState(State otherState) {
-            super();
-            mOtherState = otherState;
-        }
-    }
-
-    class WaitBeforeRenewalState extends WaitBeforeOtherState {
-        public WaitBeforeRenewalState(State otherState) {
-            super();
-            mOtherState = otherState;
-        }
-    }
-
-    class DhcpState extends State {
-        @Override
-        public void enter() {
-            clearDhcpState();
-            if (initInterface() && initSockets()) {
-                mReceiveThread = new ReceiveThread();
-                mReceiveThread.start();
-            } else {
-                notifyFailure();
-                transitionTo(mStoppedState);
-            }
-        }
-
-        @Override
-        public void exit() {
-            if (mReceiveThread != null) {
-                mReceiveThread.halt();  // Also closes sockets.
-                mReceiveThread = null;
-            }
-            clearDhcpState();
-        }
-
-        @Override
-        public boolean processMessage(Message message) {
-            super.processMessage(message);
-            switch (message.what) {
-                case CMD_STOP_DHCP:
-                    transitionTo(mStoppedState);
-                    return HANDLED;
-                default:
-                    return NOT_HANDLED;
-            }
-        }
-    }
-
-    public boolean isValidPacket(DhcpPacket packet) {
-        // TODO: check checksum.
-        int xid = packet.getTransactionId();
-        if (xid != mTransactionId) {
-            Log.d(TAG, "Unexpected transaction ID " + xid + ", expected " + mTransactionId);
-            return false;
-        }
-        if (!Arrays.equals(packet.getClientMac(), mHwAddr)) {
-            Log.d(TAG, "MAC addr mismatch: got " +
-                    HexDump.toHexString(packet.getClientMac()) + ", expected " +
-                    HexDump.toHexString(packet.getClientMac()));
-            return false;
-        }
-        return true;
-    }
-
-    public void setDhcpLeaseExpiry(DhcpPacket packet) {
-        long leaseTimeMillis = packet.getLeaseTimeMillis();
-        mDhcpLeaseExpiry =
-                (leaseTimeMillis > 0) ? SystemClock.elapsedRealtime() + leaseTimeMillis : 0;
-    }
-
-    /**
-     * Retransmits packets using jittered exponential backoff with an optional timeout. Packet
-     * transmission is triggered by CMD_KICK, which is sent by an AlarmManager alarm. If a subclass
-     * sets mTimeout to a positive value, then timeout() is called by an AlarmManager alarm mTimeout
-     * milliseconds after entering the state. Kicks and timeouts are cancelled when leaving the
-     * state.
-     *
-     * Concrete subclasses must implement sendPacket, which is called when the alarm fires and a
-     * packet needs to be transmitted, and receivePacket, which is triggered by CMD_RECEIVED_PACKET
-     * sent by the receive thread. They may also set mTimeout and implement timeout.
-     */
-    abstract class PacketRetransmittingState extends LoggingState {
-
-        private int mTimer;
-        protected int mTimeout = 0;
-
-        @Override
-        public void enter() {
-            super.enter();
-            initTimer();
-            maybeInitTimeout();
-            sendMessage(CMD_KICK);
-        }
-
-        @Override
-        public boolean processMessage(Message message) {
-            super.processMessage(message);
-            switch (message.what) {
-                case CMD_KICK:
-                    sendPacket();
-                    scheduleKick();
-                    return HANDLED;
-                case CMD_RECEIVED_PACKET:
-                    receivePacket((DhcpPacket) message.obj);
-                    return HANDLED;
-                case CMD_TIMEOUT:
-                    timeout();
-                    return HANDLED;
-                default:
-                    return NOT_HANDLED;
-            }
-        }
-
-        @Override
-        public void exit() {
-            super.exit();
-            mKickAlarm.cancel();
-            mTimeoutAlarm.cancel();
-        }
-
-        abstract protected boolean sendPacket();
-        abstract protected void receivePacket(DhcpPacket packet);
-        protected void timeout() {}
-
-        protected void initTimer() {
-            mTimer = FIRST_TIMEOUT_MS;
-        }
-
-        protected int jitterTimer(int baseTimer) {
-            int maxJitter = baseTimer / 10;
-            int jitter = mRandom.nextInt(2 * maxJitter) - maxJitter;
-            return baseTimer + jitter;
-        }
-
-        protected void scheduleKick() {
-            long now = SystemClock.elapsedRealtime();
-            long timeout = jitterTimer(mTimer);
-            long alarmTime = now + timeout;
-            mKickAlarm.schedule(alarmTime);
-            mTimer *= 2;
-            if (mTimer > MAX_TIMEOUT_MS) {
-                mTimer = MAX_TIMEOUT_MS;
-            }
-        }
-
-        protected void maybeInitTimeout() {
-            if (mTimeout > 0) {
-                long alarmTime = SystemClock.elapsedRealtime() + mTimeout;
-                mTimeoutAlarm.schedule(alarmTime);
-            }
-        }
-    }
-
-    class DhcpInitState extends PacketRetransmittingState {
-        public DhcpInitState() {
-            super();
-        }
-
-        @Override
-        public void enter() {
-            super.enter();
-            startNewTransaction();
-            mLastInitEnterTime = SystemClock.elapsedRealtime();
-        }
-
-        protected boolean sendPacket() {
-            return sendDiscoverPacket();
-        }
-
-        protected void receivePacket(DhcpPacket packet) {
-            if (!isValidPacket(packet)) return;
-            if (!(packet instanceof DhcpOfferPacket)) return;
-            mOffer = packet.toDhcpResults();
-            if (mOffer != null) {
-                Log.d(TAG, "Got pending lease: " + mOffer);
-                transitionTo(mDhcpRequestingState);
-            }
-        }
-    }
-
-    // Not implemented. We request the first offer we receive.
-    class DhcpSelectingState extends LoggingState {
-    }
-
-    class DhcpRequestingState extends PacketRetransmittingState {
-        public DhcpRequestingState() {
-            mTimeout = DHCP_TIMEOUT_MS / 2;
-        }
-
-        protected boolean sendPacket() {
-            return sendRequestPacket(
-                    INADDR_ANY,                                    // ciaddr
-                    (Inet4Address) mOffer.ipAddress.getAddress(),  // DHCP_REQUESTED_IP
-                    (Inet4Address) mOffer.serverAddress,           // DHCP_SERVER_IDENTIFIER
-                    INADDR_BROADCAST);                             // packet destination address
-        }
-
-        protected void receivePacket(DhcpPacket packet) {
-            if (!isValidPacket(packet)) return;
-            if ((packet instanceof DhcpAckPacket)) {
-                DhcpResults results = packet.toDhcpResults();
-                if (results != null) {
-                    setDhcpLeaseExpiry(packet);
-                    acceptDhcpResults(results, "Confirmed");
-                    transitionTo(mConfiguringInterfaceState);
-                }
-            } else if (packet instanceof DhcpNakPacket) {
-                // TODO: Wait a while before returning into INIT state.
-                Log.d(TAG, "Received NAK, returning to INIT");
-                mOffer = null;
-                transitionTo(mDhcpInitState);
-            }
-        }
-
-        @Override
-        protected void timeout() {
-            // After sending REQUESTs unsuccessfully for a while, go back to init.
-            transitionTo(mDhcpInitState);
-        }
-    }
-
-    class DhcpHaveLeaseState extends State {
-        @Override
-        public boolean processMessage(Message message) {
-            switch (message.what) {
-                case CMD_EXPIRE_DHCP:
-                    Log.d(TAG, "Lease expired!");
-                    notifyFailure();
-                    transitionTo(mDhcpInitState);
-                    return HANDLED;
-                default:
-                    return NOT_HANDLED;
-            }
-        }
-
-        @Override
-        public void exit() {
-            // Clear any extant alarms.
-            mRenewAlarm.cancel();
-            mRebindAlarm.cancel();
-            mExpiryAlarm.cancel();
-            clearDhcpState();
-            // Tell IpManager to clear the IPv4 address. There is no need to
-            // wait for confirmation since any subsequent packets are sent from
-            // INADDR_ANY anyway (DISCOVER, REQUEST).
-            mController.sendMessage(CMD_CLEAR_LINKADDRESS);
-        }
-    }
-
-    class ConfiguringInterfaceState extends LoggingState {
-        @Override
-        public void enter() {
-            super.enter();
-            mController.sendMessage(CMD_CONFIGURE_LINKADDRESS, mDhcpLease.ipAddress);
-        }
-
-        @Override
-        public boolean processMessage(Message message) {
-            super.processMessage(message);
-            switch (message.what) {
-                case EVENT_LINKADDRESS_CONFIGURED:
-                    transitionTo(mDhcpBoundState);
-                    return HANDLED;
-                default:
-                    return NOT_HANDLED;
-            }
-        }
-    }
-
-    class DhcpBoundState extends LoggingState {
-        @Override
-        public void enter() {
-            super.enter();
-            if (mDhcpLease.serverAddress != null && !connectUdpSock(mDhcpLease.serverAddress)) {
-                // There's likely no point in going into DhcpInitState here, we'll probably
-                // just repeat the transaction, get the same IP address as before, and fail.
-                //
-                // NOTE: It is observed that connectUdpSock() basically never fails, due to
-                // SO_BINDTODEVICE. Examining the local socket address shows it will happily
-                // return an IPv4 address from another interface, or even return "0.0.0.0".
-                //
-                // TODO: Consider deleting this check, following testing on several kernels.
-                notifyFailure();
-                transitionTo(mStoppedState);
-            }
-
-            scheduleLeaseTimers();
-            logTimeToBoundState();
-        }
-
-        @Override
-        public void exit() {
-            super.exit();
-            mLastBoundExitTime = SystemClock.elapsedRealtime();
-        }
-
-        @Override
-        public boolean processMessage(Message message) {
-            super.processMessage(message);
-            switch (message.what) {
-                case CMD_RENEW_DHCP:
-                    if (mRegisteredForPreDhcpNotification) {
-                        transitionTo(mWaitBeforeRenewalState);
-                    } else {
-                        transitionTo(mDhcpRenewingState);
-                    }
-                    return HANDLED;
-                default:
-                    return NOT_HANDLED;
-            }
-        }
-
-        private void logTimeToBoundState() {
-            long now = SystemClock.elapsedRealtime();
-            if (mLastBoundExitTime > mLastInitEnterTime) {
-                logState(EVENT_RENEWING_BOUND, (int) (now - mLastBoundExitTime));
-            } else {
-                logState(EVENT_INITIAL_BOUND, (int) (now - mLastInitEnterTime));
-            }
-        }
-    }
-
-    abstract class DhcpReacquiringState extends PacketRetransmittingState {
-        protected String mLeaseMsg;
-
-        @Override
-        public void enter() {
-            super.enter();
-            startNewTransaction();
-        }
-
-        abstract protected Inet4Address packetDestination();
-
-        protected boolean sendPacket() {
-            return sendRequestPacket(
-                    (Inet4Address) mDhcpLease.ipAddress.getAddress(),  // ciaddr
-                    INADDR_ANY,                                        // DHCP_REQUESTED_IP
-                    null,                                              // DHCP_SERVER_IDENTIFIER
-                    packetDestination());                              // packet destination address
-        }
-
-        protected void receivePacket(DhcpPacket packet) {
-            if (!isValidPacket(packet)) return;
-            if ((packet instanceof DhcpAckPacket)) {
-                final DhcpResults results = packet.toDhcpResults();
-                if (results != null) {
-                    if (!mDhcpLease.ipAddress.equals(results.ipAddress)) {
-                        Log.d(TAG, "Renewed lease not for our current IP address!");
-                        notifyFailure();
-                        transitionTo(mDhcpInitState);
-                    }
-                    setDhcpLeaseExpiry(packet);
-                    // Updating our notion of DhcpResults here only causes the
-                    // DNS servers and routes to be updated in LinkProperties
-                    // in IpManager and by any overridden relevant handlers of
-                    // the registered IpManager.Callback.  IP address changes
-                    // are not supported here.
-                    acceptDhcpResults(results, mLeaseMsg);
-                    transitionTo(mDhcpBoundState);
-                }
-            } else if (packet instanceof DhcpNakPacket) {
-                Log.d(TAG, "Received NAK, returning to INIT");
-                notifyFailure();
-                transitionTo(mDhcpInitState);
-            }
-        }
-    }
-
-    class DhcpRenewingState extends DhcpReacquiringState {
-        public DhcpRenewingState() {
-            mLeaseMsg = "Renewed";
-        }
-
-        @Override
-        public boolean processMessage(Message message) {
-            if (super.processMessage(message) == HANDLED) {
-                return HANDLED;
-            }
-
-            switch (message.what) {
-                case CMD_REBIND_DHCP:
-                    transitionTo(mDhcpRebindingState);
-                    return HANDLED;
-                default:
-                    return NOT_HANDLED;
-            }
-        }
-
-        @Override
-        protected Inet4Address packetDestination() {
-            // Not specifying a SERVER_IDENTIFIER option is a violation of RFC 2131, but...
-            // http://b/25343517 . Try to make things work anyway by using broadcast renews.
-            return (mDhcpLease.serverAddress != null) ?
-                    mDhcpLease.serverAddress : INADDR_BROADCAST;
-        }
-    }
-
-    class DhcpRebindingState extends DhcpReacquiringState {
-        public DhcpRebindingState() {
-            mLeaseMsg = "Rebound";
-        }
-
-        @Override
-        public void enter() {
-            super.enter();
-
-            // We need to broadcast and possibly reconnect the socket to a
-            // completely different server.
-            closeSocketQuietly(mUdpSock);
-            if (!initUdpSocket()) {
-                Log.e(TAG, "Failed to recreate UDP socket");
-                transitionTo(mDhcpInitState);
-            }
-        }
-
-        @Override
-        protected Inet4Address packetDestination() {
-            return INADDR_BROADCAST;
-        }
-    }
-
-    class DhcpInitRebootState extends LoggingState {
-    }
-
-    class DhcpRebootingState extends LoggingState {
-    }
-
-    private void logError(int errorCode) {
-        mMetricsLog.log(mIfaceName, new DhcpErrorEvent(errorCode));
-    }
-
-    private void logState(String name, int durationMs) {
-        final DhcpClientEvent event = new DhcpClientEvent.Builder()
-                .setMsg(name)
-                .setDurationMs(durationMs)
-                .build();
-        mMetricsLog.log(mIfaceName, event);
-    }
-}
diff --git a/packages/NetworkStack/src/android/net/dhcp/DhcpDeclinePacket.java b/packages/NetworkStack/src/android/net/dhcp/DhcpDeclinePacket.java
deleted file mode 100644
index 7ecdea7..0000000
--- a/packages/NetworkStack/src/android/net/dhcp/DhcpDeclinePacket.java
+++ /dev/null
@@ -1,61 +0,0 @@
-/*
- * 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 android.net.dhcp;
-
-import java.net.Inet4Address;
-import java.nio.ByteBuffer;
-
-/**
- * This class implements the DHCP-DECLINE packet.
- */
-class DhcpDeclinePacket extends DhcpPacket {
-    /**
-     * Generates a DECLINE packet with the specified parameters.
-     */
-    DhcpDeclinePacket(int transId, short secs, Inet4Address clientIp, Inet4Address yourIp,
-                      Inet4Address nextIp, Inet4Address relayIp,
-                      byte[] clientMac) {
-        super(transId, secs, clientIp, yourIp, nextIp, relayIp, clientMac, false);
-    }
-
-    public String toString() {
-        String s = super.toString();
-        return s + " DECLINE";
-    }
-
-    /**
-     * Fills in a packet with the requested DECLINE attributes.
-     */
-    public ByteBuffer buildPacket(int encap, short destUdp, short srcUdp) {
-        ByteBuffer result = ByteBuffer.allocate(MAX_LENGTH);
-
-        fillInPacket(encap, mClientIp, mYourIp, destUdp, srcUdp, result,
-            DHCP_BOOTREQUEST, false);
-        result.flip();
-        return result;
-    }
-
-    /**
-     * Adds optional parameters to the DECLINE packet.
-     */
-    void finishPacket(ByteBuffer buffer) {
-        addTlv(buffer, DHCP_MESSAGE_TYPE, DHCP_MESSAGE_TYPE_DECLINE);
-        addTlv(buffer, DHCP_CLIENT_IDENTIFIER, getClientId());
-        // RFC 2131 says we MUST NOT include our common client TLVs or the parameter request list.
-        addTlvEnd(buffer);
-    }
-}
diff --git a/packages/NetworkStack/src/android/net/dhcp/DhcpDiscoverPacket.java b/packages/NetworkStack/src/android/net/dhcp/DhcpDiscoverPacket.java
deleted file mode 100644
index 11f2b61..0000000
--- a/packages/NetworkStack/src/android/net/dhcp/DhcpDiscoverPacket.java
+++ /dev/null
@@ -1,67 +0,0 @@
-/*
- * 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 android.net.dhcp;
-
-import java.net.Inet4Address;
-import java.nio.ByteBuffer;
-
-/**
- * This class implements the DHCP-DISCOVER packet.
- */
-class DhcpDiscoverPacket extends DhcpPacket {
-    /**
-     * The IP address of the client which sent this packet.
-     */
-    final Inet4Address mSrcIp;
-
-    /**
-     * Generates a DISCOVER packet with the specified parameters.
-     */
-    DhcpDiscoverPacket(int transId, short secs, Inet4Address relayIp, byte[] clientMac,
-            boolean broadcast, Inet4Address srcIp) {
-        super(transId, secs, INADDR_ANY, INADDR_ANY, INADDR_ANY, relayIp, clientMac, broadcast);
-        mSrcIp = srcIp;
-    }
-
-    public String toString() {
-        String s = super.toString();
-        return s + " DISCOVER " +
-                (mBroadcast ? "broadcast " : "unicast ");
-    }
-
-    /**
-     * Fills in a packet with the requested DISCOVER parameters.
-     */
-    public ByteBuffer buildPacket(int encap, short destUdp, short srcUdp) {
-        ByteBuffer result = ByteBuffer.allocate(MAX_LENGTH);
-        fillInPacket(encap, INADDR_BROADCAST, mSrcIp, destUdp, srcUdp, result, DHCP_BOOTREQUEST,
-                mBroadcast);
-        result.flip();
-        return result;
-    }
-
-    /**
-     * Adds optional parameters to a DISCOVER packet.
-     */
-    void finishPacket(ByteBuffer buffer) {
-        addTlv(buffer, DHCP_MESSAGE_TYPE, DHCP_MESSAGE_TYPE_DISCOVER);
-        addTlv(buffer, DHCP_CLIENT_IDENTIFIER, getClientId());
-        addCommonClientTlvs(buffer);
-        addTlv(buffer, DHCP_PARAMETER_LIST, mRequestedParams);
-        addTlvEnd(buffer);
-    }
-}
diff --git a/packages/NetworkStack/src/android/net/dhcp/DhcpInformPacket.java b/packages/NetworkStack/src/android/net/dhcp/DhcpInformPacket.java
deleted file mode 100644
index 7a83466..0000000
--- a/packages/NetworkStack/src/android/net/dhcp/DhcpInformPacket.java
+++ /dev/null
@@ -1,62 +0,0 @@
-/*
- * 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 android.net.dhcp;
-
-import java.net.Inet4Address;
-import java.nio.ByteBuffer;
-
-/**
- * This class implements the (unused) DHCP-INFORM packet.
- */
-class DhcpInformPacket extends DhcpPacket {
-    /**
-     * Generates an INFORM packet with the specified parameters.
-     */
-    DhcpInformPacket(int transId, short secs, Inet4Address clientIp, Inet4Address yourIp,
-                     Inet4Address nextIp, Inet4Address relayIp,
-                     byte[] clientMac) {
-        super(transId, secs, clientIp, yourIp, nextIp, relayIp, clientMac, false);
-    }
-
-    public String toString() {
-        String s = super.toString();
-        return s + " INFORM";
-    }
-
-    /**
-     * Builds an INFORM packet.
-     */
-    public ByteBuffer buildPacket(int encap, short destUdp, short srcUdp) {
-        ByteBuffer result = ByteBuffer.allocate(MAX_LENGTH);
-
-        fillInPacket(encap, mClientIp, mYourIp, destUdp, srcUdp, result,
-            DHCP_BOOTREQUEST, false);
-        result.flip();
-        return result;
-    }
-
-    /**
-     * Adds additional parameters to the INFORM packet.
-     */
-    void finishPacket(ByteBuffer buffer) {
-        addTlv(buffer, DHCP_MESSAGE_TYPE, DHCP_MESSAGE_TYPE_INFORM);
-        addTlv(buffer, DHCP_CLIENT_IDENTIFIER, getClientId());
-        addCommonClientTlvs(buffer);
-        addTlv(buffer, DHCP_PARAMETER_LIST, mRequestedParams);
-        addTlvEnd(buffer);
-    }
-}
diff --git a/packages/NetworkStack/src/android/net/dhcp/DhcpLease.java b/packages/NetworkStack/src/android/net/dhcp/DhcpLease.java
deleted file mode 100644
index 6849cfa..0000000
--- a/packages/NetworkStack/src/android/net/dhcp/DhcpLease.java
+++ /dev/null
@@ -1,153 +0,0 @@
-/*
- * Copyright (C) 2018 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.net.dhcp;
-
-import android.annotation.NonNull;
-import android.annotation.Nullable;
-import android.net.MacAddress;
-import android.os.SystemClock;
-import android.text.TextUtils;
-
-import com.android.internal.util.HexDump;
-
-import java.net.Inet4Address;
-import java.util.Arrays;
-import java.util.Objects;
-
-/**
- * An IPv4 address assignment done through DHCPv4.
- * @hide
- */
-public class DhcpLease {
-    public static final long EXPIRATION_NEVER = Long.MAX_VALUE;
-    public static final String HOSTNAME_NONE = null;
-
-    @Nullable
-    private final byte[] mClientId;
-    @NonNull
-    private final MacAddress mHwAddr;
-    @NonNull
-    private final Inet4Address mNetAddr;
-    /**
-     * Expiration time for the lease, to compare with {@link SystemClock#elapsedRealtime()}.
-     */
-    private final long mExpTime;
-    @Nullable
-    private final String mHostname;
-
-    public DhcpLease(@Nullable byte[] clientId, @NonNull MacAddress hwAddr,
-            @NonNull Inet4Address netAddr, long expTime, @Nullable String hostname) {
-        mClientId = (clientId == null ? null : Arrays.copyOf(clientId, clientId.length));
-        mHwAddr = hwAddr;
-        mNetAddr = netAddr;
-        mExpTime = expTime;
-        mHostname = hostname;
-    }
-
-    /**
-     * Get the clientId associated with this lease, if any.
-     *
-     * <p>If the lease is not associated to a clientId, this returns null.
-     */
-    @Nullable
-    public byte[] getClientId() {
-        if (mClientId == null) {
-            return null;
-        }
-        return Arrays.copyOf(mClientId, mClientId.length);
-    }
-
-    @NonNull
-    public MacAddress getHwAddr() {
-        return mHwAddr;
-    }
-
-    @Nullable
-    public String getHostname() {
-        return mHostname;
-    }
-
-    @NonNull
-    public Inet4Address getNetAddr() {
-        return mNetAddr;
-    }
-
-    public long getExpTime() {
-        return mExpTime;
-    }
-
-    /**
-     * Push back the expiration time of this lease. If the provided time is sooner than the original
-     * expiration time, the lease time will not be updated.
-     *
-     * <p>The lease hostname is updated with the provided one if set.
-     * @return A {@link DhcpLease} with expiration time set to max(expTime, currentExpTime)
-     */
-    public DhcpLease renewedLease(long expTime, @Nullable String hostname) {
-        return new DhcpLease(mClientId, mHwAddr, mNetAddr, Math.max(expTime, mExpTime),
-                (hostname == null ? mHostname : hostname));
-    }
-
-    /**
-     * Determine whether this lease matches a client with the specified parameters.
-     * @param clientId clientId of the client if any, or null otherwise.
-     * @param hwAddr Hardware address of the client.
-     */
-    public boolean matchesClient(@Nullable byte[] clientId, @NonNull MacAddress hwAddr) {
-        if (mClientId != null) {
-            return Arrays.equals(mClientId, clientId);
-        } else {
-            return clientId == null && mHwAddr.equals(hwAddr);
-        }
-    }
-
-    @Override
-    public boolean equals(Object obj) {
-        if (!(obj instanceof DhcpLease)) {
-            return false;
-        }
-        final DhcpLease other = (DhcpLease) obj;
-        return Arrays.equals(mClientId, other.mClientId)
-                && mHwAddr.equals(other.mHwAddr)
-                && mNetAddr.equals(other.mNetAddr)
-                && mExpTime == other.mExpTime
-                && TextUtils.equals(mHostname, other.mHostname);
-    }
-
-    @Override
-    public int hashCode() {
-        return Objects.hash(mClientId, mHwAddr, mNetAddr, mHostname, mExpTime);
-    }
-
-    static String clientIdToString(byte[] bytes) {
-        if (bytes == null) {
-            return "null";
-        }
-        return HexDump.toHexString(bytes);
-    }
-
-    static String inet4AddrToString(@Nullable Inet4Address addr) {
-        return (addr == null) ? "null" : addr.getHostAddress();
-    }
-
-    @Override
-    public String toString() {
-        return String.format("clientId: %s, hwAddr: %s, netAddr: %s, expTime: %d, hostname: %s",
-                clientIdToString(mClientId), mHwAddr.toString(), inet4AddrToString(mNetAddr),
-                mExpTime, mHostname);
-    }
-}
diff --git a/packages/NetworkStack/src/android/net/dhcp/DhcpLeaseRepository.java b/packages/NetworkStack/src/android/net/dhcp/DhcpLeaseRepository.java
deleted file mode 100644
index 0a15cd7..0000000
--- a/packages/NetworkStack/src/android/net/dhcp/DhcpLeaseRepository.java
+++ /dev/null
@@ -1,546 +0,0 @@
-/*
- * Copyright (C) 2018 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.net.dhcp;
-
-import static android.net.dhcp.DhcpLease.EXPIRATION_NEVER;
-import static android.net.dhcp.DhcpLease.inet4AddrToString;
-import static android.net.shared.Inet4AddressUtils.inet4AddressToIntHTH;
-import static android.net.shared.Inet4AddressUtils.intToInet4AddressHTH;
-import static android.net.shared.Inet4AddressUtils.prefixLengthToV4NetmaskIntHTH;
-
-import static com.android.server.util.NetworkStackConstants.IPV4_ADDR_ANY;
-import static com.android.server.util.NetworkStackConstants.IPV4_ADDR_BITS;
-
-import static java.lang.Math.min;
-
-import android.annotation.NonNull;
-import android.annotation.Nullable;
-import android.net.IpPrefix;
-import android.net.MacAddress;
-import android.net.dhcp.DhcpServer.Clock;
-import android.net.util.SharedLog;
-import android.util.ArrayMap;
-
-import java.net.Inet4Address;
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.HashSet;
-import java.util.Iterator;
-import java.util.LinkedHashMap;
-import java.util.List;
-import java.util.Map;
-import java.util.Map.Entry;
-import java.util.Set;
-import java.util.function.Function;
-
-/**
- * A repository managing IPv4 address assignments through DHCPv4.
- *
- * <p>This class is not thread-safe. All public methods should be called on a common thread or
- * use some synchronization mechanism.
- *
- * <p>Methods are optimized for a small number of allocated leases, assuming that most of the time
- * only 2~10 addresses will be allocated, which is the common case. Managing a large number of
- * addresses is supported but will be slower: some operations have complexity in O(num_leases).
- * @hide
- */
-class DhcpLeaseRepository {
-    public static final byte[] CLIENTID_UNSPEC = null;
-    public static final Inet4Address INETADDR_UNSPEC = null;
-
-    @NonNull
-    private final SharedLog mLog;
-    @NonNull
-    private final Clock mClock;
-
-    @NonNull
-    private IpPrefix mPrefix;
-    @NonNull
-    private Set<Inet4Address> mReservedAddrs;
-    private int mSubnetAddr;
-    private int mSubnetMask;
-    private int mNumAddresses;
-    private long mLeaseTimeMs;
-
-    /**
-     * Next timestamp when committed or declined leases should be checked for expired ones. This
-     * will always be lower than or equal to the time for the first lease to expire: it's OK not to
-     * update this when removing entries, but it must always be updated when adding/updating.
-     */
-    private long mNextExpirationCheck = EXPIRATION_NEVER;
-
-    static class DhcpLeaseException extends Exception {
-        DhcpLeaseException(String message) {
-            super(message);
-        }
-    }
-
-    static class OutOfAddressesException extends DhcpLeaseException {
-        OutOfAddressesException(String message) {
-            super(message);
-        }
-    }
-
-    static class InvalidAddressException extends DhcpLeaseException {
-        InvalidAddressException(String message) {
-            super(message);
-        }
-    }
-
-    static class InvalidSubnetException extends DhcpLeaseException {
-        InvalidSubnetException(String message) {
-            super(message);
-        }
-    }
-
-    /**
-     * Leases by IP address
-     */
-    private final ArrayMap<Inet4Address, DhcpLease> mCommittedLeases = new ArrayMap<>();
-
-    /**
-     * Map address -> expiration timestamp in ms. Addresses are guaranteed to be valid as defined
-     * by {@link #isValidAddress(Inet4Address)}, but are not necessarily otherwise available for
-     * assignment.
-     */
-    private final LinkedHashMap<Inet4Address, Long> mDeclinedAddrs = new LinkedHashMap<>();
-
-    DhcpLeaseRepository(@NonNull IpPrefix prefix, @NonNull Set<Inet4Address> reservedAddrs,
-            long leaseTimeMs, @NonNull SharedLog log, @NonNull Clock clock) {
-        updateParams(prefix, reservedAddrs, leaseTimeMs);
-        mLog = log;
-        mClock = clock;
-    }
-
-    public void updateParams(@NonNull IpPrefix prefix, @NonNull Set<Inet4Address> reservedAddrs,
-            long leaseTimeMs) {
-        mPrefix = prefix;
-        mReservedAddrs = Collections.unmodifiableSet(new HashSet<>(reservedAddrs));
-        mSubnetMask = prefixLengthToV4NetmaskIntHTH(prefix.getPrefixLength());
-        mSubnetAddr = inet4AddressToIntHTH((Inet4Address) prefix.getAddress()) & mSubnetMask;
-        mNumAddresses = 1 << (IPV4_ADDR_BITS - prefix.getPrefixLength());
-        mLeaseTimeMs = leaseTimeMs;
-
-        cleanMap(mCommittedLeases);
-        cleanMap(mDeclinedAddrs);
-    }
-
-    /**
-     * From a map keyed by {@link Inet4Address}, remove entries where the key is invalid (as
-     * specified by {@link #isValidAddress(Inet4Address)}), or is a reserved address.
-     */
-    private <T> void cleanMap(Map<Inet4Address, T> map) {
-        final Iterator<Entry<Inet4Address, T>> it = map.entrySet().iterator();
-        while (it.hasNext()) {
-            final Inet4Address addr = it.next().getKey();
-            if (!isValidAddress(addr) || mReservedAddrs.contains(addr)) {
-                it.remove();
-            }
-        }
-    }
-
-    /**
-     * Get a DHCP offer, to reply to a DHCPDISCOVER. Follows RFC2131 #4.3.1.
-     *
-     * @param clientId Client identifier option if specified, or {@link #CLIENTID_UNSPEC}
-     * @param relayAddr Internet address of the relay (giaddr), can be {@link Inet4Address#ANY}
-     * @param reqAddr Requested address by the client (option 50), or {@link #INETADDR_UNSPEC}
-     * @param hostname Client-provided hostname, or {@link DhcpLease#HOSTNAME_NONE}
-     * @throws OutOfAddressesException The server does not have any available address
-     * @throws InvalidSubnetException The lease was requested from an unsupported subnet
-     */
-    @NonNull
-    public DhcpLease getOffer(@Nullable byte[] clientId, @NonNull MacAddress hwAddr,
-            @NonNull Inet4Address relayAddr, @Nullable Inet4Address reqAddr,
-            @Nullable String hostname) throws OutOfAddressesException, InvalidSubnetException {
-        final long currentTime = mClock.elapsedRealtime();
-        final long expTime = currentTime + mLeaseTimeMs;
-
-        removeExpiredLeases(currentTime);
-        checkValidRelayAddr(relayAddr);
-
-        final DhcpLease currentLease = findByClient(clientId, hwAddr);
-        final DhcpLease newLease;
-        if (currentLease != null) {
-            newLease = currentLease.renewedLease(expTime, hostname);
-            mLog.log("Offering extended lease " + newLease);
-            // Do not update lease time in the map: the offer is not committed yet.
-        } else if (reqAddr != null && isValidAddress(reqAddr) && isAvailable(reqAddr)) {
-            newLease = new DhcpLease(clientId, hwAddr, reqAddr, expTime, hostname);
-            mLog.log("Offering requested lease " + newLease);
-        } else {
-            newLease = makeNewOffer(clientId, hwAddr, expTime, hostname);
-            mLog.log("Offering new generated lease " + newLease);
-        }
-        return newLease;
-    }
-
-    private void checkValidRelayAddr(@Nullable Inet4Address relayAddr)
-            throws InvalidSubnetException {
-        // As per #4.3.1, addresses are assigned based on the relay address if present. This
-        // implementation only assigns addresses if the relayAddr is inside our configured subnet.
-        // This also applies when the client requested a specific address for consistency between
-        // requests, and with older behavior.
-        if (isIpAddrOutsidePrefix(mPrefix, relayAddr)) {
-            throw new InvalidSubnetException("Lease requested by relay from outside of subnet");
-        }
-    }
-
-    private static boolean isIpAddrOutsidePrefix(@NonNull IpPrefix prefix,
-            @Nullable Inet4Address addr) {
-        return addr != null && !addr.equals(IPV4_ADDR_ANY) && !prefix.contains(addr);
-    }
-
-    @Nullable
-    private DhcpLease findByClient(@Nullable byte[] clientId, @NonNull MacAddress hwAddr) {
-        for (DhcpLease lease : mCommittedLeases.values()) {
-            if (lease.matchesClient(clientId, hwAddr)) {
-                return lease;
-            }
-        }
-
-        // Note this differs from dnsmasq behavior, which would match by hwAddr if clientId was
-        // given but no lease keyed on clientId matched. This would prevent one interface from
-        // obtaining multiple leases with different clientId.
-        return null;
-    }
-
-    /**
-     * Make a lease conformant to a client DHCPREQUEST or renew the client's existing lease,
-     * commit it to the repository and return it.
-     *
-     * <p>This method always succeeds and commits the lease if it does not throw, and has no side
-     * effects if it throws.
-     *
-     * @param clientId Client identifier option if specified, or {@link #CLIENTID_UNSPEC}
-     * @param reqAddr Requested address by the client (option 50), or {@link #INETADDR_UNSPEC}
-     * @param sidSet Whether the server identifier was set in the request
-     * @return The newly created or renewed lease
-     * @throws InvalidAddressException The client provided an address that conflicts with its
-     *                                 current configuration, or other committed/reserved leases.
-     */
-    @NonNull
-    public DhcpLease requestLease(@Nullable byte[] clientId, @NonNull MacAddress hwAddr,
-            @NonNull Inet4Address clientAddr, @NonNull Inet4Address relayAddr,
-            @Nullable Inet4Address reqAddr, boolean sidSet, @Nullable String hostname)
-            throws InvalidAddressException, InvalidSubnetException {
-        final long currentTime = mClock.elapsedRealtime();
-        removeExpiredLeases(currentTime);
-        checkValidRelayAddr(relayAddr);
-        final DhcpLease assignedLease = findByClient(clientId, hwAddr);
-
-        final Inet4Address leaseAddr = reqAddr != null ? reqAddr : clientAddr;
-        if (assignedLease != null) {
-            if (sidSet && reqAddr != null) {
-                // Client in SELECTING state; remove any current lease before creating a new one.
-                mCommittedLeases.remove(assignedLease.getNetAddr());
-            } else if (!assignedLease.getNetAddr().equals(leaseAddr)) {
-                // reqAddr null (RENEWING/REBINDING): client renewing its own lease for clientAddr.
-                // reqAddr set with sid not set (INIT-REBOOT): client verifying configuration.
-                // In both cases, throw if clientAddr or reqAddr does not match the known lease.
-                throw new InvalidAddressException("Incorrect address for client in "
-                        + (reqAddr != null ? "INIT-REBOOT" : "RENEWING/REBINDING"));
-            }
-        }
-
-        // In the init-reboot case, RFC2131 #4.3.2 says that the server must not reply if
-        // assignedLease == null, but dnsmasq will let the client use the requested address if
-        // available, when configured with --dhcp-authoritative. This is preferable to avoid issues
-        // if the server lost the lease DB: the client would not get a reply because the server
-        // does not know their lease.
-        // Similarly in RENEWING/REBINDING state, create a lease when possible if the
-        // client-provided lease is unknown.
-        final DhcpLease lease =
-                checkClientAndMakeLease(clientId, hwAddr, leaseAddr, hostname, currentTime);
-        mLog.logf("DHCPREQUEST assignedLease %s, reqAddr=%s, sidSet=%s: created/renewed lease %s",
-                assignedLease, inet4AddrToString(reqAddr), sidSet, lease);
-        return lease;
-    }
-
-    /**
-     * Check that the client can request the specified address, make or renew the lease if yes, and
-     * commit it.
-     *
-     * <p>This method always succeeds and returns the lease if it does not throw, and has no
-     * side-effect if it throws.
-     *
-     * @return The newly created or renewed, committed lease
-     * @throws InvalidAddressException The client provided an address that conflicts with its
-     *                                 current configuration, or other committed/reserved leases.
-     */
-    private DhcpLease checkClientAndMakeLease(@Nullable byte[] clientId, @NonNull MacAddress hwAddr,
-            @NonNull Inet4Address addr, @Nullable String hostname, long currentTime)
-            throws InvalidAddressException {
-        final long expTime = currentTime + mLeaseTimeMs;
-        final DhcpLease currentLease = mCommittedLeases.getOrDefault(addr, null);
-        if (currentLease != null && !currentLease.matchesClient(clientId, hwAddr)) {
-            throw new InvalidAddressException("Address in use");
-        }
-
-        final DhcpLease lease;
-        if (currentLease == null) {
-            if (isValidAddress(addr) && !mReservedAddrs.contains(addr)) {
-                lease = new DhcpLease(clientId, hwAddr, addr, expTime, hostname);
-            } else {
-                throw new InvalidAddressException("Lease not found and address unavailable");
-            }
-        } else {
-            lease = currentLease.renewedLease(expTime, hostname);
-        }
-        commitLease(lease);
-        return lease;
-    }
-
-    private void commitLease(@NonNull DhcpLease lease) {
-        mCommittedLeases.put(lease.getNetAddr(), lease);
-        maybeUpdateEarliestExpiration(lease.getExpTime());
-    }
-
-    /**
-     * Delete a committed lease from the repository.
-     *
-     * @return true if a lease matching parameters was found.
-     */
-    public boolean releaseLease(@Nullable byte[] clientId, @NonNull MacAddress hwAddr,
-            @NonNull Inet4Address addr) {
-        final DhcpLease currentLease = mCommittedLeases.getOrDefault(addr, null);
-        if (currentLease == null) {
-            mLog.w("Could not release unknown lease for " + inet4AddrToString(addr));
-            return false;
-        }
-        if (currentLease.matchesClient(clientId, hwAddr)) {
-            mCommittedLeases.remove(addr);
-            mLog.log("Released lease " + currentLease);
-            return true;
-        }
-        mLog.w(String.format("Not releasing lease %s: does not match client (cid %s, hwAddr %s)",
-                currentLease, DhcpLease.clientIdToString(clientId), hwAddr));
-        return false;
-    }
-
-    public void markLeaseDeclined(@NonNull Inet4Address addr) {
-        if (mDeclinedAddrs.containsKey(addr) || !isValidAddress(addr)) {
-            mLog.logf("Not marking %s as declined: already declined or not assignable",
-                    inet4AddrToString(addr));
-            return;
-        }
-        final long expTime = mClock.elapsedRealtime() + mLeaseTimeMs;
-        mDeclinedAddrs.put(addr, expTime);
-        mLog.logf("Marked %s as declined expiring %d", inet4AddrToString(addr), expTime);
-        maybeUpdateEarliestExpiration(expTime);
-    }
-
-    /**
-     * Get the list of currently valid committed leases in the repository.
-     */
-    @NonNull
-    public List<DhcpLease> getCommittedLeases() {
-        removeExpiredLeases(mClock.elapsedRealtime());
-        return new ArrayList<>(mCommittedLeases.values());
-    }
-
-    /**
-     * Get the set of addresses that have been marked as declined in the repository.
-     */
-    @NonNull
-    public Set<Inet4Address> getDeclinedAddresses() {
-        removeExpiredLeases(mClock.elapsedRealtime());
-        return new HashSet<>(mDeclinedAddrs.keySet());
-    }
-
-    /**
-     * Given the expiration time of a new committed lease or declined address, update
-     * {@link #mNextExpirationCheck} so it stays lower than or equal to the time for the first lease
-     * to expire.
-     */
-    private void maybeUpdateEarliestExpiration(long expTime) {
-        if (expTime < mNextExpirationCheck) {
-            mNextExpirationCheck = expTime;
-        }
-    }
-
-    /**
-     * Remove expired entries from a map keyed by {@link Inet4Address}.
-     *
-     * @param tag Type of lease in the map, for logging
-     * @param getExpTime Functor returning the expiration time for an object in the map.
-     *                   Must not return null.
-     * @return The lowest expiration time among entries remaining in the map
-     */
-    private <T> long removeExpired(long currentTime, @NonNull Map<Inet4Address, T> map,
-            @NonNull String tag, @NonNull Function<T, Long> getExpTime) {
-        final Iterator<Entry<Inet4Address, T>> it = map.entrySet().iterator();
-        long firstExpiration = EXPIRATION_NEVER;
-        while (it.hasNext()) {
-            final Entry<Inet4Address, T> lease = it.next();
-            final long expTime = getExpTime.apply(lease.getValue());
-            if (expTime <= currentTime) {
-                mLog.logf("Removing expired %s lease for %s (expTime=%s, currentTime=%s)",
-                        tag, lease.getKey(), expTime, currentTime);
-                it.remove();
-            } else {
-                firstExpiration = min(firstExpiration, expTime);
-            }
-        }
-        return firstExpiration;
-    }
-
-    /**
-     * Go through committed and declined leases and remove the expired ones.
-     */
-    private void removeExpiredLeases(long currentTime) {
-        if (currentTime < mNextExpirationCheck) {
-            return;
-        }
-
-        final long commExp = removeExpired(
-                currentTime, mCommittedLeases, "committed", DhcpLease::getExpTime);
-        final long declExp = removeExpired(
-                currentTime, mDeclinedAddrs, "declined", Function.identity());
-
-        mNextExpirationCheck = min(commExp, declExp);
-    }
-
-    private boolean isAvailable(@NonNull Inet4Address addr) {
-        return !mReservedAddrs.contains(addr) && !mCommittedLeases.containsKey(addr);
-    }
-
-    /**
-     * Get the 0-based index of an address in the subnet.
-     *
-     * <p>Given ordering of addresses 5.6.7.8 < 5.6.7.9 < 5.6.8.0, the index on a subnet is defined
-     * so that the first address is 0, the second 1, etc. For example on a /16, 192.168.0.0 -> 0,
-     * 192.168.0.1 -> 1, 192.168.1.0 -> 256
-     *
-     */
-    private int getAddrIndex(int addr) {
-        return addr & ~mSubnetMask;
-    }
-
-    private int getAddrByIndex(int index) {
-        return mSubnetAddr | index;
-    }
-
-    /**
-     * Get a valid address starting from the supplied one.
-     *
-     * <p>This only checks that the address is numerically valid for assignment, not whether it is
-     * already in use. The return value is always inside the configured prefix, even if the supplied
-     * address is not.
-     *
-     * <p>If the provided address is valid, it is returned as-is. Otherwise, the next valid
-     * address (with the ordering in {@link #getAddrIndex(int)}) is returned.
-     */
-    private int getValidAddress(int addr) {
-        final int lastByteMask = 0xff;
-        int addrIndex = getAddrIndex(addr); // 0-based index of the address in the subnet
-
-        // Some OSes do not handle addresses in .255 or .0 correctly: avoid those.
-        final int lastByte = getAddrByIndex(addrIndex) & lastByteMask;
-        if (lastByte == lastByteMask) {
-            // Avoid .255 address, and .0 address that follows
-            addrIndex = (addrIndex + 2) % mNumAddresses;
-        } else if (lastByte == 0) {
-            // Avoid .0 address
-            addrIndex = (addrIndex + 1) % mNumAddresses;
-        }
-
-        // Do not use first or last address of range
-        if (addrIndex == 0 || addrIndex == mNumAddresses - 1) {
-            // Always valid and not end of range since prefixLength is at most 30 in serving params
-            addrIndex = 1;
-        }
-        return getAddrByIndex(addrIndex);
-    }
-
-    /**
-     * Returns whether the address is in the configured subnet and part of the assignable range.
-     */
-    private boolean isValidAddress(Inet4Address addr) {
-        final int intAddr = inet4AddressToIntHTH(addr);
-        return getValidAddress(intAddr) == intAddr;
-    }
-
-    private int getNextAddress(int addr) {
-        final int addrIndex = getAddrIndex(addr);
-        final int nextAddress = getAddrByIndex((addrIndex + 1) % mNumAddresses);
-        return getValidAddress(nextAddress);
-    }
-
-    /**
-     * Calculate a first candidate address for a client by hashing the hardware address.
-     *
-     * <p>This will be a valid address as checked by {@link #getValidAddress(int)}, but may be
-     * in use.
-     *
-     * @return An IPv4 address encoded as 32-bit int
-     */
-    private int getFirstClientAddress(MacAddress hwAddr) {
-        // This follows dnsmasq behavior. Advantages are: clients will often get the same
-        // offers for different DISCOVER even if the lease was not yet accepted or has expired,
-        // and address generation will generally not need to loop through many allocated addresses
-        // until it finds a free one.
-        int hash = 0;
-        for (byte b : hwAddr.toByteArray()) {
-            hash += b + (b << 8) + (b << 16);
-        }
-        // This implementation will not always result in the same IPs as dnsmasq would give out in
-        // Android <= P, because it includes invalid and reserved addresses in mNumAddresses while
-        // the configured ranges for dnsmasq did not.
-        final int addrIndex = hash % mNumAddresses;
-        return getValidAddress(getAddrByIndex(addrIndex));
-    }
-
-    /**
-     * Create a lease that can be offered to respond to a client DISCOVER.
-     *
-     * <p>This method always succeeds and returns the lease if it does not throw. If no non-declined
-     * address is available, it will try to offer the oldest declined address if valid.
-     *
-     * @throws OutOfAddressesException The server has no address left to offer
-     */
-    private DhcpLease makeNewOffer(@Nullable byte[] clientId, @NonNull MacAddress hwAddr,
-            long expTime, @Nullable String hostname) throws OutOfAddressesException {
-        int intAddr = getFirstClientAddress(hwAddr);
-        // Loop until a free address is found, or there are no more addresses.
-        // There is slightly less than this many usable addresses, but some extra looping is OK
-        for (int i = 0; i < mNumAddresses; i++) {
-            final Inet4Address addr = intToInet4AddressHTH(intAddr);
-            if (isAvailable(addr) && !mDeclinedAddrs.containsKey(addr)) {
-                return new DhcpLease(clientId, hwAddr, addr, expTime, hostname);
-            }
-            intAddr = getNextAddress(intAddr);
-        }
-
-        // Try freeing DECLINEd addresses if out of addresses.
-        final Iterator<Inet4Address> it = mDeclinedAddrs.keySet().iterator();
-        while (it.hasNext()) {
-            final Inet4Address addr = it.next();
-            it.remove();
-            mLog.logf("Out of addresses in address pool: dropped declined addr %s",
-                    inet4AddrToString(addr));
-            // isValidAddress() is always verified for entries in mDeclinedAddrs.
-            // However declined addresses may have been requested (typically by the machine that was
-            // already using the address) after being declined.
-            if (isAvailable(addr)) {
-                return new DhcpLease(clientId, hwAddr, addr, expTime, hostname);
-            }
-        }
-
-        throw new OutOfAddressesException("No address available for offer");
-    }
-}
diff --git a/packages/NetworkStack/src/android/net/dhcp/DhcpNakPacket.java b/packages/NetworkStack/src/android/net/dhcp/DhcpNakPacket.java
deleted file mode 100644
index 1da0b73..0000000
--- a/packages/NetworkStack/src/android/net/dhcp/DhcpNakPacket.java
+++ /dev/null
@@ -1,63 +0,0 @@
-/*
- * 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 android.net.dhcp;
-
-import java.net.Inet4Address;
-import java.nio.ByteBuffer;
-
-/**
- * This class implements the DHCP-NAK packet.
- */
-class DhcpNakPacket extends DhcpPacket {
-    /**
-     * Generates a NAK packet with the specified parameters.
-     */
-    DhcpNakPacket(int transId, short secs, Inet4Address relayIp, byte[] clientMac,
-            boolean broadcast) {
-        super(transId, secs, INADDR_ANY /* clientIp */, INADDR_ANY /* yourIp */,
-                INADDR_ANY /* nextIp */, relayIp, clientMac, broadcast);
-    }
-
-    public String toString() {
-        String s = super.toString();
-        return s + " NAK, reason " + (mMessage == null ? "(none)" : mMessage);
-    }
-
-    /**
-     * Fills in a packet with the requested NAK attributes.
-     */
-    public ByteBuffer buildPacket(int encap, short destUdp, short srcUdp) {
-        ByteBuffer result = ByteBuffer.allocate(MAX_LENGTH);
-        // Constructor does not set values for layers <= 3: use empty values
-        Inet4Address destIp = INADDR_ANY;
-        Inet4Address srcIp = INADDR_ANY;
-
-        fillInPacket(encap, destIp, srcIp, destUdp, srcUdp, result, DHCP_BOOTREPLY, mBroadcast);
-        result.flip();
-        return result;
-    }
-
-    /**
-     * Adds the optional parameters to the client-generated NAK packet.
-     */
-    void finishPacket(ByteBuffer buffer) {
-        addTlv(buffer, DHCP_MESSAGE_TYPE, DHCP_MESSAGE_TYPE_NAK);
-        addTlv(buffer, DHCP_SERVER_IDENTIFIER, mServerIdentifier);
-        addTlv(buffer, DHCP_MESSAGE, mMessage);
-        addTlvEnd(buffer);
-    }
-}
diff --git a/packages/NetworkStack/src/android/net/dhcp/DhcpOfferPacket.java b/packages/NetworkStack/src/android/net/dhcp/DhcpOfferPacket.java
deleted file mode 100644
index 0eba77e..0000000
--- a/packages/NetworkStack/src/android/net/dhcp/DhcpOfferPacket.java
+++ /dev/null
@@ -1,79 +0,0 @@
-/*
- * 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 android.net.dhcp;
-
-import java.net.Inet4Address;
-import java.nio.ByteBuffer;
-
-/**
- * This class implements the DHCP-OFFER packet.
- */
-class DhcpOfferPacket extends DhcpPacket {
-    /**
-     * The IP address of the server which sent this packet.
-     */
-    private final Inet4Address mSrcIp;
-
-    /**
-     * Generates a OFFER packet with the specified parameters.
-     */
-    DhcpOfferPacket(int transId, short secs, boolean broadcast, Inet4Address serverAddress,
-            Inet4Address relayIp, Inet4Address clientIp, Inet4Address yourIp, byte[] clientMac) {
-        super(transId, secs, clientIp, yourIp, serverAddress, relayIp, clientMac, broadcast);
-        mSrcIp = serverAddress;
-    }
-
-    public String toString() {
-        String s = super.toString();
-        String dnsServers = ", DNS servers: ";
-
-        if (mDnsServers != null) {
-            for (Inet4Address dnsServer: mDnsServers) {
-                dnsServers += dnsServer + " ";
-            }
-        }
-
-        return s + " OFFER, ip " + mYourIp + ", mask " + mSubnetMask +
-                dnsServers + ", gateways " + mGateways +
-                " lease time " + mLeaseTime + ", domain " + mDomainName;
-    }
-
-    /**
-     * Fills in a packet with the specified OFFER attributes.
-     */
-    public ByteBuffer buildPacket(int encap, short destUdp, short srcUdp) {
-        ByteBuffer result = ByteBuffer.allocate(MAX_LENGTH);
-        Inet4Address destIp = mBroadcast ? INADDR_BROADCAST : mYourIp;
-        Inet4Address srcIp = mBroadcast ? INADDR_ANY : mSrcIp;
-
-        fillInPacket(encap, destIp, srcIp, destUdp, srcUdp, result,
-            DHCP_BOOTREPLY, mBroadcast);
-        result.flip();
-        return result;
-    }
-
-    /**
-     * Adds the optional parameters to the server-generated OFFER packet.
-     */
-    void finishPacket(ByteBuffer buffer) {
-        addTlv(buffer, DHCP_MESSAGE_TYPE, DHCP_MESSAGE_TYPE_OFFER);
-        addTlv(buffer, DHCP_SERVER_IDENTIFIER, mServerIdentifier);
-
-        addCommonServerTlvs(buffer);
-        addTlvEnd(buffer);
-    }
-}
diff --git a/packages/NetworkStack/src/android/net/dhcp/DhcpPacket.java b/packages/NetworkStack/src/android/net/dhcp/DhcpPacket.java
deleted file mode 100644
index a15d423..0000000
--- a/packages/NetworkStack/src/android/net/dhcp/DhcpPacket.java
+++ /dev/null
@@ -1,1397 +0,0 @@
-package android.net.dhcp;
-
-import static com.android.server.util.NetworkStackConstants.IPV4_ADDR_ALL;
-import static com.android.server.util.NetworkStackConstants.IPV4_ADDR_ANY;
-
-import android.annotation.Nullable;
-import android.net.DhcpResults;
-import android.net.LinkAddress;
-import android.net.metrics.DhcpErrorEvent;
-import android.net.shared.Inet4AddressUtils;
-import android.os.Build;
-import android.os.SystemProperties;
-import android.system.OsConstants;
-import android.text.TextUtils;
-
-import com.android.internal.annotations.VisibleForTesting;
-
-import java.io.UnsupportedEncodingException;
-import java.net.Inet4Address;
-import java.net.UnknownHostException;
-import java.nio.BufferUnderflowException;
-import java.nio.ByteBuffer;
-import java.nio.ByteOrder;
-import java.nio.ShortBuffer;
-import java.nio.charset.StandardCharsets;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.List;
-
-/**
- * Defines basic data and operations needed to build and use packets for the
- * DHCP protocol.  Subclasses create the specific packets used at each
- * stage of the negotiation.
- *
- * @hide
- */
-public abstract class DhcpPacket {
-    protected static final String TAG = "DhcpPacket";
-
-    // TODO: use NetworkStackConstants.IPV4_MIN_MTU once this class is moved to the network stack.
-    private static final int IPV4_MIN_MTU = 68;
-
-    // dhcpcd has a minimum lease of 20 seconds, but DhcpStateMachine would refuse to wake up the
-    // CPU for anything shorter than 5 minutes. For sanity's sake, this must be higher than the
-    // DHCP client timeout.
-    public static final int MINIMUM_LEASE = 60;
-    public static final int INFINITE_LEASE = (int) 0xffffffff;
-
-    public static final Inet4Address INADDR_ANY = IPV4_ADDR_ANY;
-    public static final Inet4Address INADDR_BROADCAST = IPV4_ADDR_ALL;
-    public static final byte[] ETHER_BROADCAST = new byte[] {
-            (byte) 0xff, (byte) 0xff, (byte) 0xff,
-            (byte) 0xff, (byte) 0xff, (byte) 0xff,
-    };
-
-    /**
-     * Packet encapsulations.
-     */
-    public static final int ENCAP_L2 = 0;    // EthernetII header included
-    public static final int ENCAP_L3 = 1;    // IP/UDP header included
-    public static final int ENCAP_BOOTP = 2; // BOOTP contents only
-
-    /**
-     * Minimum length of a DHCP packet, excluding options, in the above encapsulations.
-     */
-    public static final int MIN_PACKET_LENGTH_BOOTP = 236;  // See diagram in RFC 2131, section 2.
-    public static final int MIN_PACKET_LENGTH_L3 = MIN_PACKET_LENGTH_BOOTP + 20 + 8;
-    public static final int MIN_PACKET_LENGTH_L2 = MIN_PACKET_LENGTH_L3 + 14;
-
-    public static final int HWADDR_LEN = 16;
-    public static final int MAX_OPTION_LEN = 255;
-
-    /**
-     * The minimum and maximum MTU that we are prepared to use. We set the minimum to the minimum
-     * IPv6 MTU because the IPv6 stack enters unusual codepaths when the link MTU drops below 1280,
-     * and does not recover if the MTU is brought above 1280 again. We set the maximum to 1500
-     * because in general it is risky to assume that the hardware is able to send/receive packets
-     * larger than 1500 bytes even if the network supports it.
-     */
-    private static final int MIN_MTU = 1280;
-    private static final int MAX_MTU = 1500;
-
-    /**
-     * IP layer definitions.
-     */
-    private static final byte IP_TYPE_UDP = (byte) 0x11;
-
-    /**
-     * IP: Version 4, Header Length 20 bytes
-     */
-    private static final byte IP_VERSION_HEADER_LEN = (byte) 0x45;
-
-    /**
-     * IP: Flags 0, Fragment Offset 0, Don't Fragment
-     */
-    private static final short IP_FLAGS_OFFSET = (short) 0x4000;
-
-    /**
-     * IP: TOS
-     */
-    private static final byte IP_TOS_LOWDELAY = (byte) 0x10;
-
-    /**
-     * IP: TTL -- use default 64 from RFC1340
-     */
-    private static final byte IP_TTL = (byte) 0x40;
-
-    /**
-     * The client DHCP port.
-     */
-    static final short DHCP_CLIENT = (short) 68;
-
-    /**
-     * The server DHCP port.
-     */
-    static final short DHCP_SERVER = (short) 67;
-
-    /**
-     * The message op code indicating a request from a client.
-     */
-    protected static final byte DHCP_BOOTREQUEST = (byte) 1;
-
-    /**
-     * The message op code indicating a response from the server.
-     */
-    protected static final byte DHCP_BOOTREPLY = (byte) 2;
-
-    /**
-     * The code type used to identify an Ethernet MAC address in the
-     * Client-ID field.
-     */
-    protected static final byte CLIENT_ID_ETHER = (byte) 1;
-
-    /**
-     * The maximum length of a packet that can be constructed.
-     */
-    protected static final int MAX_LENGTH = 1500;
-
-    /**
-     * The magic cookie that identifies this as a DHCP packet instead of BOOTP.
-     */
-    private static final int DHCP_MAGIC_COOKIE = 0x63825363;
-
-    /**
-     * DHCP Optional Type: DHCP Subnet Mask
-     */
-    protected static final byte DHCP_SUBNET_MASK = 1;
-    protected Inet4Address mSubnetMask;
-
-    /**
-     * DHCP Optional Type: DHCP Router
-     */
-    protected static final byte DHCP_ROUTER = 3;
-    protected List <Inet4Address> mGateways;
-
-    /**
-     * DHCP Optional Type: DHCP DNS Server
-     */
-    protected static final byte DHCP_DNS_SERVER = 6;
-    protected List<Inet4Address> mDnsServers;
-
-    /**
-     * DHCP Optional Type: DHCP Host Name
-     */
-    protected static final byte DHCP_HOST_NAME = 12;
-    protected String mHostName;
-
-    /**
-     * DHCP Optional Type: DHCP DOMAIN NAME
-     */
-    protected static final byte DHCP_DOMAIN_NAME = 15;
-    protected String mDomainName;
-
-    /**
-     * DHCP Optional Type: DHCP Interface MTU
-     */
-    protected static final byte DHCP_MTU = 26;
-    protected Short mMtu;
-
-    /**
-     * DHCP Optional Type: DHCP BROADCAST ADDRESS
-     */
-    protected static final byte DHCP_BROADCAST_ADDRESS = 28;
-    protected Inet4Address mBroadcastAddress;
-
-    /**
-     * DHCP Optional Type: Vendor specific information
-     */
-    protected static final byte DHCP_VENDOR_INFO = 43;
-    protected String mVendorInfo;
-
-    /**
-     * Value of the vendor specific option used to indicate that the network is metered
-     */
-    public static final String VENDOR_INFO_ANDROID_METERED = "ANDROID_METERED";
-
-    /**
-     * DHCP Optional Type: Option overload option
-     */
-    protected static final byte DHCP_OPTION_OVERLOAD = 52;
-
-    /**
-     * Possible values of the option overload option.
-     */
-    private static final byte OPTION_OVERLOAD_FILE = 1;
-    private static final byte OPTION_OVERLOAD_SNAME = 2;
-    private static final byte OPTION_OVERLOAD_BOTH = 3;
-
-    /**
-     * DHCP Optional Type: DHCP Requested IP Address
-     */
-    protected static final byte DHCP_REQUESTED_IP = 50;
-    protected Inet4Address mRequestedIp;
-
-    /**
-     * DHCP Optional Type: DHCP Lease Time
-     */
-    protected static final byte DHCP_LEASE_TIME = 51;
-    protected Integer mLeaseTime;
-
-    /**
-     * DHCP Optional Type: DHCP Message Type
-     */
-    protected static final byte DHCP_MESSAGE_TYPE = 53;
-    // the actual type values
-    protected static final byte DHCP_MESSAGE_TYPE_DISCOVER = 1;
-    protected static final byte DHCP_MESSAGE_TYPE_OFFER = 2;
-    protected static final byte DHCP_MESSAGE_TYPE_REQUEST = 3;
-    protected static final byte DHCP_MESSAGE_TYPE_DECLINE = 4;
-    protected static final byte DHCP_MESSAGE_TYPE_ACK = 5;
-    protected static final byte DHCP_MESSAGE_TYPE_NAK = 6;
-    protected static final byte DHCP_MESSAGE_TYPE_RELEASE = 7;
-    protected static final byte DHCP_MESSAGE_TYPE_INFORM = 8;
-
-    /**
-     * DHCP Optional Type: DHCP Server Identifier
-     */
-    protected static final byte DHCP_SERVER_IDENTIFIER = 54;
-    protected Inet4Address mServerIdentifier;
-
-    /**
-     * DHCP Optional Type: DHCP Parameter List
-     */
-    protected static final byte DHCP_PARAMETER_LIST = 55;
-    protected byte[] mRequestedParams;
-
-    /**
-     * DHCP Optional Type: DHCP MESSAGE
-     */
-    protected static final byte DHCP_MESSAGE = 56;
-    protected String mMessage;
-
-    /**
-     * DHCP Optional Type: Maximum DHCP Message Size
-     */
-    protected static final byte DHCP_MAX_MESSAGE_SIZE = 57;
-    protected Short mMaxMessageSize;
-
-    /**
-     * DHCP Optional Type: DHCP Renewal Time Value
-     */
-    protected static final byte DHCP_RENEWAL_TIME = 58;
-    protected Integer mT1;
-
-    /**
-     * DHCP Optional Type: Rebinding Time Value
-     */
-    protected static final byte DHCP_REBINDING_TIME = 59;
-    protected Integer mT2;
-
-    /**
-     * DHCP Optional Type: Vendor Class Identifier
-     */
-    protected static final byte DHCP_VENDOR_CLASS_ID = 60;
-    protected String mVendorId;
-
-    /**
-     * DHCP Optional Type: DHCP Client Identifier
-     */
-    protected static final byte DHCP_CLIENT_IDENTIFIER = 61;
-    protected byte[] mClientId;
-
-    /**
-     * DHCP zero-length option code: pad
-     */
-    protected static final byte DHCP_OPTION_PAD = 0x00;
-
-    /**
-     * DHCP zero-length option code: end of options
-     */
-    protected static final byte DHCP_OPTION_END = (byte) 0xff;
-
-    /**
-     * The transaction identifier used in this particular DHCP negotiation
-     */
-    protected final int mTransId;
-
-    /**
-     * The seconds field in the BOOTP header. Per RFC, should be nonzero in client requests only.
-     */
-    protected final short mSecs;
-
-    /**
-     * The IP address of the client host.  This address is typically
-     * proposed by the client (from an earlier DHCP negotiation) or
-     * supplied by the server.
-     */
-    protected final Inet4Address mClientIp;
-    protected final Inet4Address mYourIp;
-    private final Inet4Address mNextIp;
-    protected final Inet4Address mRelayIp;
-
-    /**
-     * Does the client request a broadcast response?
-     */
-    protected boolean mBroadcast;
-
-    /**
-     * The six-octet MAC of the client.
-     */
-    protected final byte[] mClientMac;
-
-    /**
-     * The server host name from server.
-     */
-    protected String mServerHostName;
-
-    /**
-     * Asks the packet object to create a ByteBuffer serialization of
-     * the packet for transmission.
-     */
-    public abstract ByteBuffer buildPacket(int encap, short destUdp,
-        short srcUdp);
-
-    /**
-     * Allows the concrete class to fill in packet-type-specific details,
-     * typically optional parameters at the end of the packet.
-     */
-    abstract void finishPacket(ByteBuffer buffer);
-
-    // Set in unit tests, to ensure that the test does not break when run on different devices and
-    // on different releases.
-    static String testOverrideVendorId = null;
-    static String testOverrideHostname = null;
-
-    protected DhcpPacket(int transId, short secs, Inet4Address clientIp, Inet4Address yourIp,
-                         Inet4Address nextIp, Inet4Address relayIp,
-                         byte[] clientMac, boolean broadcast) {
-        mTransId = transId;
-        mSecs = secs;
-        mClientIp = clientIp;
-        mYourIp = yourIp;
-        mNextIp = nextIp;
-        mRelayIp = relayIp;
-        mClientMac = clientMac;
-        mBroadcast = broadcast;
-    }
-
-    /**
-     * Returns the transaction ID.
-     */
-    public int getTransactionId() {
-        return mTransId;
-    }
-
-    /**
-     * Returns the client MAC.
-     */
-    public byte[] getClientMac() {
-        return mClientMac;
-    }
-
-    // TODO: refactor DhcpClient to set clientId when constructing packets and remove
-    // hasExplicitClientId logic
-    /**
-     * Returns whether a client ID was set in the options for this packet.
-     */
-    public boolean hasExplicitClientId() {
-        return mClientId != null;
-    }
-
-    /**
-     * Convenience method to return the client ID if it was set explicitly, or null otherwise.
-     */
-    @Nullable
-    public byte[] getExplicitClientIdOrNull() {
-        return hasExplicitClientId() ? getClientId() : null;
-    }
-
-    /**
-     * Returns the client ID. If not set explicitly, this follows RFC 2132 and creates a client ID
-     * based on the hardware address.
-     */
-    public byte[] getClientId() {
-        final byte[] clientId;
-        if (hasExplicitClientId()) {
-            clientId = Arrays.copyOf(mClientId, mClientId.length);
-        } else {
-            clientId = new byte[mClientMac.length + 1];
-            clientId[0] = CLIENT_ID_ETHER;
-            System.arraycopy(mClientMac, 0, clientId, 1, mClientMac.length);
-        }
-        return clientId;
-    }
-
-    /**
-     * Returns whether a parameter is included in the parameter request list option of this packet.
-     *
-     * <p>If there is no parameter request list option in the packet, false is returned.
-     *
-     * @param paramId ID of the parameter, such as {@link #DHCP_MTU} or {@link #DHCP_HOST_NAME}.
-     */
-    public boolean hasRequestedParam(byte paramId) {
-        if (mRequestedParams == null) {
-            return false;
-        }
-
-        for (byte reqParam : mRequestedParams) {
-            if (reqParam == paramId) {
-                return true;
-            }
-        }
-        return false;
-    }
-
-    /**
-     * Creates a new L3 packet (including IP header) containing the
-     * DHCP udp packet.  This method relies upon the delegated method
-     * finishPacket() to insert the per-packet contents.
-     */
-    protected void fillInPacket(int encap, Inet4Address destIp,
-        Inet4Address srcIp, short destUdp, short srcUdp, ByteBuffer buf,
-        byte requestCode, boolean broadcast) {
-        byte[] destIpArray = destIp.getAddress();
-        byte[] srcIpArray = srcIp.getAddress();
-        int ipHeaderOffset = 0;
-        int ipLengthOffset = 0;
-        int ipChecksumOffset = 0;
-        int endIpHeader = 0;
-        int udpHeaderOffset = 0;
-        int udpLengthOffset = 0;
-        int udpChecksumOffset = 0;
-
-        buf.clear();
-        buf.order(ByteOrder.BIG_ENDIAN);
-
-        if (encap == ENCAP_L2) {
-            buf.put(ETHER_BROADCAST);
-            buf.put(mClientMac);
-            buf.putShort((short) OsConstants.ETH_P_IP);
-        }
-
-        // if a full IP packet needs to be generated, put the IP & UDP
-        // headers in place, and pre-populate with artificial values
-        // needed to seed the IP checksum.
-        if (encap <= ENCAP_L3) {
-            ipHeaderOffset = buf.position();
-            buf.put(IP_VERSION_HEADER_LEN);
-            buf.put(IP_TOS_LOWDELAY);    // tos: IPTOS_LOWDELAY
-            ipLengthOffset = buf.position();
-            buf.putShort((short)0);  // length
-            buf.putShort((short)0);  // id
-            buf.putShort(IP_FLAGS_OFFSET); // ip offset: don't fragment
-            buf.put(IP_TTL);    // TTL: use default 64 from RFC1340
-            buf.put(IP_TYPE_UDP);
-            ipChecksumOffset = buf.position();
-            buf.putShort((short) 0); // checksum
-
-            buf.put(srcIpArray);
-            buf.put(destIpArray);
-            endIpHeader = buf.position();
-
-            // UDP header
-            udpHeaderOffset = buf.position();
-            buf.putShort(srcUdp);
-            buf.putShort(destUdp);
-            udpLengthOffset = buf.position();
-            buf.putShort((short) 0); // length
-            udpChecksumOffset = buf.position();
-            buf.putShort((short) 0); // UDP checksum -- initially zero
-        }
-
-        // DHCP payload
-        buf.put(requestCode);
-        buf.put((byte) 1); // Hardware Type: Ethernet
-        buf.put((byte) mClientMac.length); // Hardware Address Length
-        buf.put((byte) 0); // Hop Count
-        buf.putInt(mTransId);  // Transaction ID
-        buf.putShort(mSecs); // Elapsed Seconds
-
-        if (broadcast) {
-            buf.putShort((short) 0x8000); // Flags
-        } else {
-            buf.putShort((short) 0x0000); // Flags
-        }
-
-        buf.put(mClientIp.getAddress());
-        buf.put(mYourIp.getAddress());
-        buf.put(mNextIp.getAddress());
-        buf.put(mRelayIp.getAddress());
-        buf.put(mClientMac);
-        buf.position(buf.position() +
-                     (HWADDR_LEN - mClientMac.length) // pad addr to 16 bytes
-                     + 64     // empty server host name (64 bytes)
-                     + 128);  // empty boot file name (128 bytes)
-        buf.putInt(DHCP_MAGIC_COOKIE); // magic number
-        finishPacket(buf);
-
-        // round up to an even number of octets
-        if ((buf.position() & 1) == 1) {
-            buf.put((byte) 0);
-        }
-
-        // If an IP packet is being built, the IP & UDP checksums must be
-        // computed.
-        if (encap <= ENCAP_L3) {
-            // fix UDP header: insert length
-            short udpLen = (short)(buf.position() - udpHeaderOffset);
-            buf.putShort(udpLengthOffset, udpLen);
-            // fix UDP header: checksum
-            // checksum for UDP at udpChecksumOffset
-            int udpSeed = 0;
-
-            // apply IPv4 pseudo-header.  Read IP address src and destination
-            // values from the IP header and accumulate checksum.
-            udpSeed += intAbs(buf.getShort(ipChecksumOffset + 2));
-            udpSeed += intAbs(buf.getShort(ipChecksumOffset + 4));
-            udpSeed += intAbs(buf.getShort(ipChecksumOffset + 6));
-            udpSeed += intAbs(buf.getShort(ipChecksumOffset + 8));
-
-            // accumulate extra data for the pseudo-header
-            udpSeed += IP_TYPE_UDP;
-            udpSeed += udpLen;
-            // and compute UDP checksum
-            buf.putShort(udpChecksumOffset, (short) checksum(buf, udpSeed,
-                                                             udpHeaderOffset,
-                                                             buf.position()));
-            // fix IP header: insert length
-            buf.putShort(ipLengthOffset, (short)(buf.position() - ipHeaderOffset));
-            // fixup IP-header checksum
-            buf.putShort(ipChecksumOffset,
-                         (short) checksum(buf, 0, ipHeaderOffset, endIpHeader));
-        }
-    }
-
-    /**
-     * Converts a signed short value to an unsigned int value.  Needed
-     * because Java does not have unsigned types.
-     */
-    private static int intAbs(short v) {
-        return v & 0xFFFF;
-    }
-
-    /**
-     * Performs an IP checksum (used in IP header and across UDP
-     * payload) on the specified portion of a ByteBuffer.  The seed
-     * allows the checksum to commence with a specified value.
-     */
-    private int checksum(ByteBuffer buf, int seed, int start, int end) {
-        int sum = seed;
-        int bufPosition = buf.position();
-
-        // set position of original ByteBuffer, so that the ShortBuffer
-        // will be correctly initialized
-        buf.position(start);
-        ShortBuffer shortBuf = buf.asShortBuffer();
-
-        // re-set ByteBuffer position
-        buf.position(bufPosition);
-
-        short[] shortArray = new short[(end - start) / 2];
-        shortBuf.get(shortArray);
-
-        for (short s : shortArray) {
-            sum += intAbs(s);
-        }
-
-        start += shortArray.length * 2;
-
-        // see if a singleton byte remains
-        if (end != start) {
-            short b = buf.get(start);
-
-            // make it unsigned
-            if (b < 0) {
-                b += 256;
-            }
-
-            sum += b * 256;
-        }
-
-        sum = ((sum >> 16) & 0xFFFF) + (sum & 0xFFFF);
-        sum = ((sum + ((sum >> 16) & 0xFFFF)) & 0xFFFF);
-        int negated = ~sum;
-        return intAbs((short) negated);
-    }
-
-    /**
-     * Adds an optional parameter containing a single byte value.
-     */
-    protected static void addTlv(ByteBuffer buf, byte type, byte value) {
-        buf.put(type);
-        buf.put((byte) 1);
-        buf.put(value);
-    }
-
-    /**
-     * Adds an optional parameter containing an array of bytes.
-     *
-     * <p>This method is a no-op if the payload argument is null.
-     */
-    protected static void addTlv(ByteBuffer buf, byte type, @Nullable byte[] payload) {
-        if (payload != null) {
-            if (payload.length > MAX_OPTION_LEN) {
-                throw new IllegalArgumentException("DHCP option too long: "
-                        + payload.length + " vs. " + MAX_OPTION_LEN);
-            }
-            buf.put(type);
-            buf.put((byte) payload.length);
-            buf.put(payload);
-        }
-    }
-
-    /**
-     * Adds an optional parameter containing an IP address.
-     *
-     * <p>This method is a no-op if the address argument is null.
-     */
-    protected static void addTlv(ByteBuffer buf, byte type, @Nullable Inet4Address addr) {
-        if (addr != null) {
-            addTlv(buf, type, addr.getAddress());
-        }
-    }
-
-    /**
-     * Adds an optional parameter containing a list of IP addresses.
-     *
-     * <p>This method is a no-op if the addresses argument is null or empty.
-     */
-    protected static void addTlv(ByteBuffer buf, byte type, @Nullable List<Inet4Address> addrs) {
-        if (addrs == null || addrs.size() == 0) return;
-
-        int optionLen = 4 * addrs.size();
-        if (optionLen > MAX_OPTION_LEN) {
-            throw new IllegalArgumentException("DHCP option too long: "
-                    + optionLen + " vs. " + MAX_OPTION_LEN);
-        }
-
-        buf.put(type);
-        buf.put((byte)(optionLen));
-
-        for (Inet4Address addr : addrs) {
-            buf.put(addr.getAddress());
-        }
-    }
-
-    /**
-     * Adds an optional parameter containing a short integer.
-     *
-     * <p>This method is a no-op if the value argument is null.
-     */
-    protected static void addTlv(ByteBuffer buf, byte type, @Nullable Short value) {
-        if (value != null) {
-            buf.put(type);
-            buf.put((byte) 2);
-            buf.putShort(value.shortValue());
-        }
-    }
-
-    /**
-     * Adds an optional parameter containing a simple integer.
-     *
-     * <p>This method is a no-op if the value argument is null.
-     */
-    protected static void addTlv(ByteBuffer buf, byte type, @Nullable Integer value) {
-        if (value != null) {
-            buf.put(type);
-            buf.put((byte) 4);
-            buf.putInt(value.intValue());
-        }
-    }
-
-    /**
-     * Adds an optional parameter containing an ASCII string.
-     *
-     * <p>This method is a no-op if the string argument is null.
-     */
-    protected static void addTlv(ByteBuffer buf, byte type, @Nullable String str) {
-        if (str != null) {
-            try {
-                addTlv(buf, type, str.getBytes("US-ASCII"));
-            } catch (UnsupportedEncodingException e) {
-                throw new IllegalArgumentException("String is not US-ASCII: " + str);
-            }
-        }
-    }
-
-    /**
-     * Adds the special end-of-optional-parameters indicator.
-     */
-    protected static void addTlvEnd(ByteBuffer buf) {
-        buf.put((byte) 0xFF);
-    }
-
-    private String getVendorId() {
-        if (testOverrideVendorId != null) return testOverrideVendorId;
-        return "android-dhcp-" + Build.VERSION.RELEASE;
-    }
-
-    private String getHostname() {
-        if (testOverrideHostname != null) return testOverrideHostname;
-        return SystemProperties.get("net.hostname");
-    }
-
-    /**
-     * Adds common client TLVs.
-     *
-     * TODO: Does this belong here? The alternative would be to modify all the buildXyzPacket
-     * methods to take them.
-     */
-    protected void addCommonClientTlvs(ByteBuffer buf) {
-        addTlv(buf, DHCP_MAX_MESSAGE_SIZE, (short) MAX_LENGTH);
-        addTlv(buf, DHCP_VENDOR_CLASS_ID, getVendorId());
-        final String hn = getHostname();
-        if (!TextUtils.isEmpty(hn)) addTlv(buf, DHCP_HOST_NAME, hn);
-    }
-
-    protected void addCommonServerTlvs(ByteBuffer buf) {
-        addTlv(buf, DHCP_LEASE_TIME, mLeaseTime);
-        if (mLeaseTime != null && mLeaseTime != INFINITE_LEASE) {
-            // The client should renew at 1/2 the lease-expiry interval
-            addTlv(buf, DHCP_RENEWAL_TIME, (int) (Integer.toUnsignedLong(mLeaseTime) / 2));
-            // Default rebinding time is set as below by RFC2131
-            addTlv(buf, DHCP_REBINDING_TIME,
-                    (int) (Integer.toUnsignedLong(mLeaseTime) * 875L / 1000L));
-        }
-        addTlv(buf, DHCP_SUBNET_MASK, mSubnetMask);
-        addTlv(buf, DHCP_BROADCAST_ADDRESS, mBroadcastAddress);
-        addTlv(buf, DHCP_ROUTER, mGateways);
-        addTlv(buf, DHCP_DNS_SERVER, mDnsServers);
-        addTlv(buf, DHCP_DOMAIN_NAME, mDomainName);
-        addTlv(buf, DHCP_HOST_NAME, mHostName);
-        addTlv(buf, DHCP_VENDOR_INFO, mVendorInfo);
-        if (mMtu != null && Short.toUnsignedInt(mMtu) >= IPV4_MIN_MTU) {
-            addTlv(buf, DHCP_MTU, mMtu);
-        }
-    }
-
-    /**
-     * Converts a MAC from an array of octets to an ASCII string.
-     */
-    public static String macToString(byte[] mac) {
-        String macAddr = "";
-
-        for (int i = 0; i < mac.length; i++) {
-            String hexString = "0" + Integer.toHexString(mac[i]);
-
-            // substring operation grabs the last 2 digits: this
-            // allows signed bytes to be converted correctly.
-            macAddr += hexString.substring(hexString.length() - 2);
-
-            if (i != (mac.length - 1)) {
-                macAddr += ":";
-            }
-        }
-
-        return macAddr;
-    }
-
-    public String toString() {
-        String macAddr = macToString(mClientMac);
-
-        return macAddr;
-    }
-
-    /**
-     * Reads a four-octet value from a ByteBuffer and construct
-     * an IPv4 address from that value.
-     */
-    private static Inet4Address readIpAddress(ByteBuffer packet) {
-        Inet4Address result = null;
-        byte[] ipAddr = new byte[4];
-        packet.get(ipAddr);
-
-        try {
-            result = (Inet4Address) Inet4Address.getByAddress(ipAddr);
-        } catch (UnknownHostException ex) {
-            // ipAddr is numeric, so this should not be
-            // triggered.  However, if it is, just nullify
-            result = null;
-        }
-
-        return result;
-    }
-
-    /**
-     * Reads a string of specified length from the buffer.
-     */
-    private static String readAsciiString(ByteBuffer buf, int byteCount, boolean nullOk) {
-        byte[] bytes = new byte[byteCount];
-        buf.get(bytes);
-        int length = bytes.length;
-        if (!nullOk) {
-            // Stop at the first null byte. This is because some DHCP options (e.g., the domain
-            // name) are passed to netd via FrameworkListener, which refuses arguments containing
-            // null bytes. We don't do this by default because vendorInfo is an opaque string which
-            // could in theory contain null bytes.
-            for (length = 0; length < bytes.length; length++) {
-                if (bytes[length] == 0) {
-                    break;
-                }
-            }
-        }
-        return new String(bytes, 0, length, StandardCharsets.US_ASCII);
-    }
-
-    private static boolean isPacketToOrFromClient(short udpSrcPort, short udpDstPort) {
-        return (udpSrcPort == DHCP_CLIENT) || (udpDstPort == DHCP_CLIENT);
-    }
-
-    private static boolean isPacketServerToServer(short udpSrcPort, short udpDstPort) {
-        return (udpSrcPort == DHCP_SERVER) && (udpDstPort == DHCP_SERVER);
-    }
-
-    public static class ParseException extends Exception {
-        public final int errorCode;
-        public ParseException(int errorCode, String msg, Object... args) {
-            super(String.format(msg, args));
-            this.errorCode = errorCode;
-        }
-    }
-
-    /**
-     * Creates a concrete DhcpPacket from the supplied ByteBuffer.  The
-     * buffer may have an L2 encapsulation (which is the full EthernetII
-     * format starting with the source-address MAC) or an L3 encapsulation
-     * (which starts with the IP header).
-     * <br>
-     * A subset of the optional parameters are parsed and are stored
-     * in object fields.
-     */
-    @VisibleForTesting
-    static DhcpPacket decodeFullPacket(ByteBuffer packet, int pktType) throws ParseException
-    {
-        // bootp parameters
-        int transactionId;
-        short secs;
-        Inet4Address clientIp;
-        Inet4Address yourIp;
-        Inet4Address nextIp;
-        Inet4Address relayIp;
-        byte[] clientMac;
-        byte[] clientId = null;
-        List<Inet4Address> dnsServers = new ArrayList<>();
-        List<Inet4Address> gateways = new ArrayList<>();  // aka router
-        Inet4Address serverIdentifier = null;
-        Inet4Address netMask = null;
-        String message = null;
-        String vendorId = null;
-        String vendorInfo = null;
-        byte[] expectedParams = null;
-        String hostName = null;
-        String domainName = null;
-        Inet4Address ipSrc = null;
-        Inet4Address ipDst = null;
-        Inet4Address bcAddr = null;
-        Inet4Address requestedIp = null;
-        String serverHostName;
-        byte optionOverload = 0;
-
-        // The following are all unsigned integers. Internally we store them as signed integers of
-        // the same length because that way we're guaranteed that they can't be out of the range of
-        // the unsigned field in the packet. Callers wanting to pass in an unsigned value will need
-        // to cast it.
-        Short mtu = null;
-        Short maxMessageSize = null;
-        Integer leaseTime = null;
-        Integer T1 = null;
-        Integer T2 = null;
-
-        // dhcp options
-        byte dhcpType = (byte) 0xFF;
-
-        packet.order(ByteOrder.BIG_ENDIAN);
-
-        // check to see if we need to parse L2, IP, and UDP encaps
-        if (pktType == ENCAP_L2) {
-            if (packet.remaining() < MIN_PACKET_LENGTH_L2) {
-                throw new ParseException(DhcpErrorEvent.L2_TOO_SHORT,
-                        "L2 packet too short, %d < %d", packet.remaining(), MIN_PACKET_LENGTH_L2);
-            }
-
-            byte[] l2dst = new byte[6];
-            byte[] l2src = new byte[6];
-
-            packet.get(l2dst);
-            packet.get(l2src);
-
-            short l2type = packet.getShort();
-
-            if (l2type != OsConstants.ETH_P_IP) {
-                throw new ParseException(DhcpErrorEvent.L2_WRONG_ETH_TYPE,
-                        "Unexpected L2 type 0x%04x, expected 0x%04x", l2type, OsConstants.ETH_P_IP);
-            }
-        }
-
-        if (pktType <= ENCAP_L3) {
-            if (packet.remaining() < MIN_PACKET_LENGTH_L3) {
-                throw new ParseException(DhcpErrorEvent.L3_TOO_SHORT,
-                        "L3 packet too short, %d < %d", packet.remaining(), MIN_PACKET_LENGTH_L3);
-            }
-
-            byte ipTypeAndLength = packet.get();
-            int ipVersion = (ipTypeAndLength & 0xf0) >> 4;
-            if (ipVersion != 4) {
-                throw new ParseException(
-                        DhcpErrorEvent.L3_NOT_IPV4, "Invalid IP version %d", ipVersion);
-            }
-
-            // System.out.println("ipType is " + ipType);
-            byte ipDiffServicesField = packet.get();
-            short ipTotalLength = packet.getShort();
-            short ipIdentification = packet.getShort();
-            byte ipFlags = packet.get();
-            byte ipFragOffset = packet.get();
-            byte ipTTL = packet.get();
-            byte ipProto = packet.get();
-            short ipChksm = packet.getShort();
-
-            ipSrc = readIpAddress(packet);
-            ipDst = readIpAddress(packet);
-
-            if (ipProto != IP_TYPE_UDP) {
-                throw new ParseException(
-                        DhcpErrorEvent.L4_NOT_UDP, "Protocol not UDP: %d", ipProto);
-            }
-
-            // Skip options. This cannot cause us to read beyond the end of the buffer because the
-            // IPv4 header cannot be more than (0x0f * 4) = 60 bytes long, and that is less than
-            // MIN_PACKET_LENGTH_L3.
-            int optionWords = ((ipTypeAndLength & 0x0f) - 5);
-            for (int i = 0; i < optionWords; i++) {
-                packet.getInt();
-            }
-
-            // assume UDP
-            short udpSrcPort = packet.getShort();
-            short udpDstPort = packet.getShort();
-            short udpLen = packet.getShort();
-            short udpChkSum = packet.getShort();
-
-            // Only accept packets to or from the well-known client port (expressly permitting
-            // packets from ports other than the well-known server port; http://b/24687559), and
-            // server-to-server packets, e.g. for relays.
-            if (!isPacketToOrFromClient(udpSrcPort, udpDstPort) &&
-                !isPacketServerToServer(udpSrcPort, udpDstPort)) {
-                // This should almost never happen because we use SO_ATTACH_FILTER on the packet
-                // socket to drop packets that don't have the right source ports. However, it's
-                // possible that a packet arrives between when the socket is bound and when the
-                // filter is set. http://b/26696823 .
-                throw new ParseException(DhcpErrorEvent.L4_WRONG_PORT,
-                        "Unexpected UDP ports %d->%d", udpSrcPort, udpDstPort);
-            }
-        }
-
-        // We need to check the length even for ENCAP_L3 because the IPv4 header is variable-length.
-        if (pktType > ENCAP_BOOTP || packet.remaining() < MIN_PACKET_LENGTH_BOOTP) {
-            throw new ParseException(DhcpErrorEvent.BOOTP_TOO_SHORT,
-                        "Invalid type or BOOTP packet too short, %d < %d",
-                        packet.remaining(), MIN_PACKET_LENGTH_BOOTP);
-        }
-
-        byte type = packet.get();
-        byte hwType = packet.get();
-        int addrLen = packet.get() & 0xff;
-        byte hops = packet.get();
-        transactionId = packet.getInt();
-        secs = packet.getShort();
-        short bootpFlags = packet.getShort();
-        boolean broadcast = (bootpFlags & 0x8000) != 0;
-        byte[] ipv4addr = new byte[4];
-
-        try {
-            packet.get(ipv4addr);
-            clientIp = (Inet4Address) Inet4Address.getByAddress(ipv4addr);
-            packet.get(ipv4addr);
-            yourIp = (Inet4Address) Inet4Address.getByAddress(ipv4addr);
-            packet.get(ipv4addr);
-            nextIp = (Inet4Address) Inet4Address.getByAddress(ipv4addr);
-            packet.get(ipv4addr);
-            relayIp = (Inet4Address) Inet4Address.getByAddress(ipv4addr);
-        } catch (UnknownHostException ex) {
-            throw new ParseException(DhcpErrorEvent.L3_INVALID_IP,
-                    "Invalid IPv4 address: %s", Arrays.toString(ipv4addr));
-        }
-
-        // Some DHCP servers have been known to announce invalid client hardware address values such
-        // as 0xff. The legacy DHCP client accepted these becuause it does not check the length at
-        // all but only checks that the interface MAC address matches the first bytes of the address
-        // in the packets. We're a bit stricter: if the length is obviously invalid (i.e., bigger
-        // than the size of the field), we fudge it to 6 (Ethernet). http://b/23725795
-        // TODO: evaluate whether to make this test more liberal.
-        if (addrLen > HWADDR_LEN) {
-            addrLen = ETHER_BROADCAST.length;
-        }
-
-        clientMac = new byte[addrLen];
-        packet.get(clientMac);
-
-        // skip over address padding (16 octets allocated)
-        packet.position(packet.position() + (16 - addrLen));
-        serverHostName = readAsciiString(packet, 64, false);
-        packet.position(packet.position() + 128);
-
-        // Ensure this is a DHCP packet with a magic cookie, and not BOOTP. http://b/31850211
-        if (packet.remaining() < 4) {
-            throw new ParseException(DhcpErrorEvent.DHCP_NO_COOKIE, "not a DHCP message");
-        }
-
-        int dhcpMagicCookie = packet.getInt();
-        if (dhcpMagicCookie != DHCP_MAGIC_COOKIE) {
-            throw new ParseException(DhcpErrorEvent.DHCP_BAD_MAGIC_COOKIE,
-                    "Bad magic cookie 0x%08x, should be 0x%08x",
-                    dhcpMagicCookie, DHCP_MAGIC_COOKIE);
-        }
-
-        // parse options
-        boolean notFinishedOptions = true;
-
-        while ((packet.position() < packet.limit()) && notFinishedOptions) {
-            final byte optionType = packet.get(); // cannot underflow because position < limit
-            try {
-                if (optionType == DHCP_OPTION_END) {
-                    notFinishedOptions = false;
-                } else if (optionType == DHCP_OPTION_PAD) {
-                    // The pad option doesn't have a length field. Nothing to do.
-                } else {
-                    int optionLen = packet.get() & 0xFF;
-                    int expectedLen = 0;
-
-                    switch(optionType) {
-                        case DHCP_SUBNET_MASK:
-                            netMask = readIpAddress(packet);
-                            expectedLen = 4;
-                            break;
-                        case DHCP_ROUTER:
-                            for (expectedLen = 0; expectedLen < optionLen; expectedLen += 4) {
-                                gateways.add(readIpAddress(packet));
-                            }
-                            break;
-                        case DHCP_DNS_SERVER:
-                            for (expectedLen = 0; expectedLen < optionLen; expectedLen += 4) {
-                                dnsServers.add(readIpAddress(packet));
-                            }
-                            break;
-                        case DHCP_HOST_NAME:
-                            expectedLen = optionLen;
-                            hostName = readAsciiString(packet, optionLen, false);
-                            break;
-                        case DHCP_MTU:
-                            expectedLen = 2;
-                            mtu = packet.getShort();
-                            break;
-                        case DHCP_DOMAIN_NAME:
-                            expectedLen = optionLen;
-                            domainName = readAsciiString(packet, optionLen, false);
-                            break;
-                        case DHCP_BROADCAST_ADDRESS:
-                            bcAddr = readIpAddress(packet);
-                            expectedLen = 4;
-                            break;
-                        case DHCP_REQUESTED_IP:
-                            requestedIp = readIpAddress(packet);
-                            expectedLen = 4;
-                            break;
-                        case DHCP_LEASE_TIME:
-                            leaseTime = Integer.valueOf(packet.getInt());
-                            expectedLen = 4;
-                            break;
-                        case DHCP_MESSAGE_TYPE:
-                            dhcpType = packet.get();
-                            expectedLen = 1;
-                            break;
-                        case DHCP_SERVER_IDENTIFIER:
-                            serverIdentifier = readIpAddress(packet);
-                            expectedLen = 4;
-                            break;
-                        case DHCP_PARAMETER_LIST:
-                            expectedParams = new byte[optionLen];
-                            packet.get(expectedParams);
-                            expectedLen = optionLen;
-                            break;
-                        case DHCP_MESSAGE:
-                            expectedLen = optionLen;
-                            message = readAsciiString(packet, optionLen, false);
-                            break;
-                        case DHCP_MAX_MESSAGE_SIZE:
-                            expectedLen = 2;
-                            maxMessageSize = Short.valueOf(packet.getShort());
-                            break;
-                        case DHCP_RENEWAL_TIME:
-                            expectedLen = 4;
-                            T1 = Integer.valueOf(packet.getInt());
-                            break;
-                        case DHCP_REBINDING_TIME:
-                            expectedLen = 4;
-                            T2 = Integer.valueOf(packet.getInt());
-                            break;
-                        case DHCP_VENDOR_CLASS_ID:
-                            expectedLen = optionLen;
-                            // Embedded nulls are safe as this does not get passed to netd.
-                            vendorId = readAsciiString(packet, optionLen, true);
-                            break;
-                        case DHCP_CLIENT_IDENTIFIER: { // Client identifier
-                            byte[] id = new byte[optionLen];
-                            packet.get(id);
-                            expectedLen = optionLen;
-                        } break;
-                        case DHCP_VENDOR_INFO:
-                            expectedLen = optionLen;
-                            // Embedded nulls are safe as this does not get passed to netd.
-                            vendorInfo = readAsciiString(packet, optionLen, true);
-                            break;
-                        case DHCP_OPTION_OVERLOAD:
-                            expectedLen = 1;
-                            optionOverload = packet.get();
-                            optionOverload &= OPTION_OVERLOAD_BOTH;
-                            break;
-                        default:
-                            // ignore any other parameters
-                            for (int i = 0; i < optionLen; i++) {
-                                expectedLen++;
-                                byte throwaway = packet.get();
-                            }
-                    }
-
-                    if (expectedLen != optionLen) {
-                        final int errorCode = DhcpErrorEvent.errorCodeWithOption(
-                                DhcpErrorEvent.DHCP_INVALID_OPTION_LENGTH, optionType);
-                        throw new ParseException(errorCode,
-                                "Invalid length %d for option %d, expected %d",
-                                optionLen, optionType, expectedLen);
-                    }
-                }
-            } catch (BufferUnderflowException e) {
-                final int errorCode = DhcpErrorEvent.errorCodeWithOption(
-                        DhcpErrorEvent.BUFFER_UNDERFLOW, optionType);
-                throw new ParseException(errorCode, "BufferUnderflowException");
-            }
-        }
-
-        DhcpPacket newPacket;
-
-        switch(dhcpType) {
-            case (byte) 0xFF:
-                throw new ParseException(DhcpErrorEvent.DHCP_NO_MSG_TYPE,
-                        "No DHCP message type option");
-            case DHCP_MESSAGE_TYPE_DISCOVER:
-                newPacket = new DhcpDiscoverPacket(transactionId, secs, relayIp, clientMac,
-                        broadcast, ipSrc);
-                break;
-            case DHCP_MESSAGE_TYPE_OFFER:
-                newPacket = new DhcpOfferPacket(
-                    transactionId, secs, broadcast, ipSrc, relayIp, clientIp, yourIp, clientMac);
-                break;
-            case DHCP_MESSAGE_TYPE_REQUEST:
-                newPacket = new DhcpRequestPacket(
-                    transactionId, secs, clientIp, relayIp, clientMac, broadcast);
-                break;
-            case DHCP_MESSAGE_TYPE_DECLINE:
-                newPacket = new DhcpDeclinePacket(
-                    transactionId, secs, clientIp, yourIp, nextIp, relayIp,
-                    clientMac);
-                break;
-            case DHCP_MESSAGE_TYPE_ACK:
-                newPacket = new DhcpAckPacket(
-                    transactionId, secs, broadcast, ipSrc, relayIp, clientIp, yourIp, clientMac);
-                break;
-            case DHCP_MESSAGE_TYPE_NAK:
-                newPacket = new DhcpNakPacket(
-                        transactionId, secs, relayIp, clientMac, broadcast);
-                break;
-            case DHCP_MESSAGE_TYPE_RELEASE:
-                if (serverIdentifier == null) {
-                    throw new ParseException(DhcpErrorEvent.MISC_ERROR,
-                            "DHCPRELEASE without server identifier");
-                }
-                newPacket = new DhcpReleasePacket(
-                        transactionId, serverIdentifier, clientIp, relayIp, clientMac);
-                break;
-            case DHCP_MESSAGE_TYPE_INFORM:
-                newPacket = new DhcpInformPacket(
-                    transactionId, secs, clientIp, yourIp, nextIp, relayIp,
-                    clientMac);
-                break;
-            default:
-                throw new ParseException(DhcpErrorEvent.DHCP_UNKNOWN_MSG_TYPE,
-                        "Unimplemented DHCP type %d", dhcpType);
-        }
-
-        newPacket.mBroadcastAddress = bcAddr;
-        newPacket.mClientId = clientId;
-        newPacket.mDnsServers = dnsServers;
-        newPacket.mDomainName = domainName;
-        newPacket.mGateways = gateways;
-        newPacket.mHostName = hostName;
-        newPacket.mLeaseTime = leaseTime;
-        newPacket.mMessage = message;
-        newPacket.mMtu = mtu;
-        newPacket.mRequestedIp = requestedIp;
-        newPacket.mRequestedParams = expectedParams;
-        newPacket.mServerIdentifier = serverIdentifier;
-        newPacket.mSubnetMask = netMask;
-        newPacket.mMaxMessageSize = maxMessageSize;
-        newPacket.mT1 = T1;
-        newPacket.mT2 = T2;
-        newPacket.mVendorId = vendorId;
-        newPacket.mVendorInfo = vendorInfo;
-        if ((optionOverload & OPTION_OVERLOAD_SNAME) == 0) {
-            newPacket.mServerHostName = serverHostName;
-        } else {
-            newPacket.mServerHostName = "";
-        }
-        return newPacket;
-    }
-
-    /**
-     * Parse a packet from an array of bytes, stopping at the given length.
-     */
-    public static DhcpPacket decodeFullPacket(byte[] packet, int length, int pktType)
-            throws ParseException {
-        ByteBuffer buffer = ByteBuffer.wrap(packet, 0, length).order(ByteOrder.BIG_ENDIAN);
-        try {
-            return decodeFullPacket(buffer, pktType);
-        } catch (ParseException e) {
-            throw e;
-        } catch (Exception e) {
-            throw new ParseException(DhcpErrorEvent.PARSING_ERROR, e.getMessage());
-        }
-    }
-
-    /**
-     *  Construct a DhcpResults object from a DHCP reply packet.
-     */
-    public DhcpResults toDhcpResults() {
-        Inet4Address ipAddress = mYourIp;
-        if (ipAddress.equals(IPV4_ADDR_ANY)) {
-            ipAddress = mClientIp;
-            if (ipAddress.equals(IPV4_ADDR_ANY)) {
-                return null;
-            }
-        }
-
-        int prefixLength;
-        if (mSubnetMask != null) {
-            try {
-                prefixLength = Inet4AddressUtils.netmaskToPrefixLength(mSubnetMask);
-            } catch (IllegalArgumentException e) {
-                // Non-contiguous netmask.
-                return null;
-            }
-        } else {
-            prefixLength = Inet4AddressUtils.getImplicitNetmask(ipAddress);
-        }
-
-        DhcpResults results = new DhcpResults();
-        try {
-            results.ipAddress = new LinkAddress(ipAddress, prefixLength);
-        } catch (IllegalArgumentException e) {
-            return null;
-        }
-
-        if (mGateways.size() > 0) {
-            results.gateway = mGateways.get(0);
-        }
-
-        results.dnsServers.addAll(mDnsServers);
-        results.domains = mDomainName;
-        results.serverAddress = mServerIdentifier;
-        results.vendorInfo = mVendorInfo;
-        results.leaseDuration = (mLeaseTime != null) ? mLeaseTime : INFINITE_LEASE;
-        results.mtu = (mMtu != null && MIN_MTU <= mMtu && mMtu <= MAX_MTU) ? mMtu : 0;
-        results.serverHostName = mServerHostName;
-
-        return results;
-    }
-
-    /**
-     * Returns the parsed lease time, in milliseconds, or 0 for infinite.
-     */
-    public long getLeaseTimeMillis() {
-        // dhcpcd treats the lack of a lease time option as an infinite lease.
-        if (mLeaseTime == null || mLeaseTime == INFINITE_LEASE) {
-            return 0;
-        } else if (0 <= mLeaseTime && mLeaseTime < MINIMUM_LEASE) {
-            return MINIMUM_LEASE * 1000;
-        } else {
-            return (mLeaseTime & 0xffffffffL) * 1000;
-        }
-    }
-
-    /**
-     * Builds a DHCP-DISCOVER packet from the required specified
-     * parameters.
-     */
-    public static ByteBuffer buildDiscoverPacket(int encap, int transactionId,
-        short secs, byte[] clientMac, boolean broadcast, byte[] expectedParams) {
-        DhcpPacket pkt = new DhcpDiscoverPacket(transactionId, secs, INADDR_ANY /* relayIp */,
-                clientMac, broadcast, INADDR_ANY /* srcIp */);
-        pkt.mRequestedParams = expectedParams;
-        return pkt.buildPacket(encap, DHCP_SERVER, DHCP_CLIENT);
-    }
-
-    /**
-     * Builds a DHCP-OFFER packet from the required specified
-     * parameters.
-     */
-    public static ByteBuffer buildOfferPacket(int encap, int transactionId,
-        boolean broadcast, Inet4Address serverIpAddr, Inet4Address relayIp,
-        Inet4Address yourIp, byte[] mac, Integer timeout, Inet4Address netMask,
-        Inet4Address bcAddr, List<Inet4Address> gateways, List<Inet4Address> dnsServers,
-        Inet4Address dhcpServerIdentifier, String domainName, String hostname, boolean metered,
-        short mtu) {
-        DhcpPacket pkt = new DhcpOfferPacket(
-                transactionId, (short) 0, broadcast, serverIpAddr, relayIp,
-                INADDR_ANY /* clientIp */, yourIp, mac);
-        pkt.mGateways = gateways;
-        pkt.mDnsServers = dnsServers;
-        pkt.mLeaseTime = timeout;
-        pkt.mDomainName = domainName;
-        pkt.mHostName = hostname;
-        pkt.mServerIdentifier = dhcpServerIdentifier;
-        pkt.mSubnetMask = netMask;
-        pkt.mBroadcastAddress = bcAddr;
-        pkt.mMtu = mtu;
-        if (metered) {
-            pkt.mVendorInfo = VENDOR_INFO_ANDROID_METERED;
-        }
-        return pkt.buildPacket(encap, DHCP_CLIENT, DHCP_SERVER);
-    }
-
-    /**
-     * Builds a DHCP-ACK packet from the required specified parameters.
-     */
-    public static ByteBuffer buildAckPacket(int encap, int transactionId,
-        boolean broadcast, Inet4Address serverIpAddr, Inet4Address relayIp, Inet4Address yourIp,
-        Inet4Address requestClientIp, byte[] mac, Integer timeout, Inet4Address netMask,
-        Inet4Address bcAddr, List<Inet4Address> gateways, List<Inet4Address> dnsServers,
-        Inet4Address dhcpServerIdentifier, String domainName, String hostname, boolean metered,
-        short mtu) {
-        DhcpPacket pkt = new DhcpAckPacket(
-                transactionId, (short) 0, broadcast, serverIpAddr, relayIp, requestClientIp, yourIp,
-                mac);
-        pkt.mGateways = gateways;
-        pkt.mDnsServers = dnsServers;
-        pkt.mLeaseTime = timeout;
-        pkt.mDomainName = domainName;
-        pkt.mHostName = hostname;
-        pkt.mSubnetMask = netMask;
-        pkt.mServerIdentifier = dhcpServerIdentifier;
-        pkt.mBroadcastAddress = bcAddr;
-        pkt.mMtu = mtu;
-        if (metered) {
-            pkt.mVendorInfo = VENDOR_INFO_ANDROID_METERED;
-        }
-        return pkt.buildPacket(encap, DHCP_CLIENT, DHCP_SERVER);
-    }
-
-    /**
-     * Builds a DHCP-NAK packet from the required specified parameters.
-     */
-    public static ByteBuffer buildNakPacket(int encap, int transactionId, Inet4Address serverIpAddr,
-            Inet4Address relayIp, byte[] mac, boolean broadcast, String message) {
-        DhcpPacket pkt = new DhcpNakPacket(
-                transactionId, (short) 0, relayIp, mac, broadcast);
-        pkt.mMessage = message;
-        pkt.mServerIdentifier = serverIpAddr;
-        return pkt.buildPacket(encap, DHCP_CLIENT, DHCP_SERVER);
-    }
-
-    /**
-     * Builds a DHCP-REQUEST packet from the required specified parameters.
-     */
-    public static ByteBuffer buildRequestPacket(int encap,
-        int transactionId, short secs, Inet4Address clientIp, boolean broadcast,
-        byte[] clientMac, Inet4Address requestedIpAddress,
-        Inet4Address serverIdentifier, byte[] requestedParams, String hostName) {
-        DhcpPacket pkt = new DhcpRequestPacket(transactionId, secs, clientIp,
-                INADDR_ANY /* relayIp */, clientMac, broadcast);
-        pkt.mRequestedIp = requestedIpAddress;
-        pkt.mServerIdentifier = serverIdentifier;
-        pkt.mHostName = hostName;
-        pkt.mRequestedParams = requestedParams;
-        ByteBuffer result = pkt.buildPacket(encap, DHCP_SERVER, DHCP_CLIENT);
-        return result;
-    }
-}
diff --git a/packages/NetworkStack/src/android/net/dhcp/DhcpPacketListener.java b/packages/NetworkStack/src/android/net/dhcp/DhcpPacketListener.java
deleted file mode 100644
index 97d26c7..0000000
--- a/packages/NetworkStack/src/android/net/dhcp/DhcpPacketListener.java
+++ /dev/null
@@ -1,88 +0,0 @@
-/*
- * Copyright (C) 2018 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.net.dhcp;
-
-import android.annotation.NonNull;
-import android.annotation.Nullable;
-import android.net.util.FdEventsReader;
-import android.os.Handler;
-import android.system.Os;
-
-import java.io.FileDescriptor;
-import java.net.Inet4Address;
-import java.net.InetSocketAddress;
-
-/**
- * A {@link FdEventsReader} to receive and parse {@link DhcpPacket}.
- * @hide
- */
-abstract class DhcpPacketListener extends FdEventsReader<DhcpPacketListener.Payload> {
-    static final class Payload {
-        protected final byte[] mBytes = new byte[DhcpPacket.MAX_LENGTH];
-        protected Inet4Address mSrcAddr;
-        protected int mSrcPort;
-    }
-
-    DhcpPacketListener(@NonNull Handler handler) {
-        super(handler, new Payload());
-    }
-
-    @Override
-    protected int recvBufSize(@NonNull Payload buffer) {
-        return buffer.mBytes.length;
-    }
-
-    @Override
-    protected final void handlePacket(@NonNull Payload recvbuf, int length) {
-        if (recvbuf.mSrcAddr == null) {
-            return;
-        }
-
-        try {
-            final DhcpPacket packet = DhcpPacket.decodeFullPacket(recvbuf.mBytes, length,
-                    DhcpPacket.ENCAP_BOOTP);
-            onReceive(packet, recvbuf.mSrcAddr, recvbuf.mSrcPort);
-        } catch (DhcpPacket.ParseException e) {
-            logParseError(recvbuf.mBytes, length, e);
-        }
-    }
-
-    @Override
-    protected int readPacket(@NonNull FileDescriptor fd, @NonNull Payload packetBuffer)
-            throws Exception {
-        final InetSocketAddress addr = new InetSocketAddress(0);
-        final int read = Os.recvfrom(
-                fd, packetBuffer.mBytes, 0, packetBuffer.mBytes.length, 0 /* flags */, addr);
-
-        // Buffers with null srcAddr will be dropped in handlePacket()
-        packetBuffer.mSrcAddr = inet4AddrOrNull(addr);
-        packetBuffer.mSrcPort = addr.getPort();
-        return read;
-    }
-
-    @Nullable
-    private static Inet4Address inet4AddrOrNull(@NonNull InetSocketAddress addr) {
-        return addr.getAddress() instanceof Inet4Address
-                ? (Inet4Address) addr.getAddress()
-                : null;
-    }
-
-    protected abstract void onReceive(@NonNull DhcpPacket packet, @NonNull Inet4Address srcAddr,
-            int srcPort);
-    protected abstract void logParseError(@NonNull byte[] packet, int length,
-            @NonNull DhcpPacket.ParseException e);
-}
diff --git a/packages/NetworkStack/src/android/net/dhcp/DhcpReleasePacket.java b/packages/NetworkStack/src/android/net/dhcp/DhcpReleasePacket.java
deleted file mode 100644
index 3958303..0000000
--- a/packages/NetworkStack/src/android/net/dhcp/DhcpReleasePacket.java
+++ /dev/null
@@ -1,58 +0,0 @@
-/*
- * Copyright (C) 2018 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.net.dhcp;
-
-import java.net.Inet4Address;
-import java.nio.ByteBuffer;
-
-/**
- * Implements DHCP-RELEASE
- */
-class DhcpReleasePacket extends DhcpPacket {
-
-    final Inet4Address mClientAddr;
-
-    /**
-     * Generates a RELEASE packet with the specified parameters.
-     */
-    public DhcpReleasePacket(int transId, Inet4Address serverId, Inet4Address clientAddr,
-            Inet4Address relayIp, byte[] clientMac) {
-        super(transId, (short)0, clientAddr, INADDR_ANY /* yourIp */, INADDR_ANY /* nextIp */,
-                relayIp, clientMac, false /* broadcast */);
-        mServerIdentifier = serverId;
-        mClientAddr = clientAddr;
-    }
-
-
-    @Override
-    public ByteBuffer buildPacket(int encap, short destUdp, short srcUdp) {
-        ByteBuffer result = ByteBuffer.allocate(MAX_LENGTH);
-        fillInPacket(encap, mServerIdentifier /* destIp */, mClientIp /* srcIp */, destUdp, srcUdp,
-                result, DHCP_BOOTREPLY, mBroadcast);
-        result.flip();
-        return result;
-    }
-
-    @Override
-    void finishPacket(ByteBuffer buffer) {
-        addTlv(buffer, DHCP_MESSAGE_TYPE, DHCP_MESSAGE_TYPE_RELEASE);
-        addTlv(buffer, DHCP_CLIENT_IDENTIFIER, getClientId());
-        addTlv(buffer, DHCP_SERVER_IDENTIFIER, mServerIdentifier);
-        addCommonClientTlvs(buffer);
-        addTlvEnd(buffer);
-    }
-}
diff --git a/packages/NetworkStack/src/android/net/dhcp/DhcpRequestPacket.java b/packages/NetworkStack/src/android/net/dhcp/DhcpRequestPacket.java
deleted file mode 100644
index 231d0457..0000000
--- a/packages/NetworkStack/src/android/net/dhcp/DhcpRequestPacket.java
+++ /dev/null
@@ -1,71 +0,0 @@
-/*
- * 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 android.net.dhcp;
-
-import android.util.Log;
-
-import java.net.Inet4Address;
-import java.nio.ByteBuffer;
-
-/**
- * This class implements the DHCP-REQUEST packet.
- */
-class DhcpRequestPacket extends DhcpPacket {
-    /**
-     * Generates a REQUEST packet with the specified parameters.
-     */
-    DhcpRequestPacket(int transId, short secs, Inet4Address clientIp, Inet4Address relayIp,
-            byte[] clientMac, boolean broadcast) {
-        super(transId, secs, clientIp, INADDR_ANY, INADDR_ANY, relayIp, clientMac, broadcast);
-    }
-
-    public String toString() {
-        String s = super.toString();
-        return s + " REQUEST, desired IP " + mRequestedIp + " from host '"
-            + mHostName + "', param list length "
-            + (mRequestedParams == null ? 0 : mRequestedParams.length);
-    }
-
-    /**
-     * Fills in a packet with the requested REQUEST attributes.
-     */
-    public ByteBuffer buildPacket(int encap, short destUdp, short srcUdp) {
-        ByteBuffer result = ByteBuffer.allocate(MAX_LENGTH);
-
-        fillInPacket(encap, INADDR_BROADCAST, INADDR_ANY, destUdp, srcUdp,
-            result, DHCP_BOOTREQUEST, mBroadcast);
-        result.flip();
-        return result;
-    }
-
-    /**
-     * Adds the optional parameters to the client-generated REQUEST packet.
-     */
-    void finishPacket(ByteBuffer buffer) {
-        addTlv(buffer, DHCP_MESSAGE_TYPE, DHCP_MESSAGE_TYPE_REQUEST);
-        addTlv(buffer, DHCP_CLIENT_IDENTIFIER, getClientId());
-        if (!INADDR_ANY.equals(mRequestedIp)) {
-            addTlv(buffer, DHCP_REQUESTED_IP, mRequestedIp);
-        }
-        if (!INADDR_ANY.equals(mServerIdentifier)) {
-            addTlv(buffer, DHCP_SERVER_IDENTIFIER, mServerIdentifier);
-        }
-        addCommonClientTlvs(buffer);
-        addTlv(buffer, DHCP_PARAMETER_LIST, mRequestedParams);
-        addTlvEnd(buffer);
-    }
-}
diff --git a/packages/NetworkStack/src/android/net/dhcp/DhcpServer.java b/packages/NetworkStack/src/android/net/dhcp/DhcpServer.java
deleted file mode 100644
index b8ab94c..0000000
--- a/packages/NetworkStack/src/android/net/dhcp/DhcpServer.java
+++ /dev/null
@@ -1,655 +0,0 @@
-/*
- * Copyright (C) 2018 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.net.dhcp;
-
-import static android.net.dhcp.DhcpPacket.DHCP_CLIENT;
-import static android.net.dhcp.DhcpPacket.DHCP_HOST_NAME;
-import static android.net.dhcp.DhcpPacket.DHCP_SERVER;
-import static android.net.dhcp.DhcpPacket.ENCAP_BOOTP;
-import static android.net.dhcp.IDhcpServer.STATUS_INVALID_ARGUMENT;
-import static android.net.dhcp.IDhcpServer.STATUS_SUCCESS;
-import static android.net.shared.Inet4AddressUtils.getBroadcastAddress;
-import static android.net.shared.Inet4AddressUtils.getPrefixMaskAsInet4Address;
-import static android.system.OsConstants.AF_INET;
-import static android.system.OsConstants.IPPROTO_UDP;
-import static android.system.OsConstants.SOCK_DGRAM;
-import static android.system.OsConstants.SOCK_NONBLOCK;
-import static android.system.OsConstants.SOL_SOCKET;
-import static android.system.OsConstants.SO_BROADCAST;
-import static android.system.OsConstants.SO_REUSEADDR;
-
-import static com.android.internal.util.TrafficStatsConstants.TAG_SYSTEM_DHCP_SERVER;
-import static com.android.server.util.NetworkStackConstants.INFINITE_LEASE;
-import static com.android.server.util.NetworkStackConstants.IPV4_ADDR_ALL;
-import static com.android.server.util.NetworkStackConstants.IPV4_ADDR_ANY;
-import static com.android.server.util.PermissionUtil.checkNetworkStackCallingPermission;
-
-import static java.lang.Integer.toUnsignedLong;
-
-import android.annotation.NonNull;
-import android.annotation.Nullable;
-import android.net.INetworkStackStatusCallback;
-import android.net.MacAddress;
-import android.net.TrafficStats;
-import android.net.util.NetworkStackUtils;
-import android.net.util.SharedLog;
-import android.net.util.SocketUtils;
-import android.os.Handler;
-import android.os.HandlerThread;
-import android.os.Looper;
-import android.os.Message;
-import android.os.RemoteException;
-import android.os.SystemClock;
-import android.system.ErrnoException;
-import android.system.Os;
-import android.text.TextUtils;
-import android.util.Pair;
-
-import com.android.internal.annotations.VisibleForTesting;
-import com.android.internal.util.HexDump;
-
-import java.io.FileDescriptor;
-import java.io.IOException;
-import java.net.Inet4Address;
-import java.net.InetAddress;
-import java.nio.ByteBuffer;
-import java.util.ArrayList;
-
-/**
- * A DHCPv4 server.
- *
- * <p>This server listens for and responds to packets on a single interface. It considers itself
- * authoritative for all leases on the subnet, which means that DHCP requests for unknown leases of
- * unknown hosts receive a reply instead of being ignored.
- *
- * <p>The server is single-threaded (including send/receive operations): all internal operations are
- * done on the provided {@link Looper}. Public methods are thread-safe and will schedule operations
- * on the looper asynchronously.
- * @hide
- */
-public class DhcpServer extends IDhcpServer.Stub {
-    private static final String REPO_TAG = "Repository";
-
-    // Lease time to transmit to client instead of a negative time in case a lease expired before
-    // the server could send it (if the server process is suspended for example).
-    private static final int EXPIRED_FALLBACK_LEASE_TIME_SECS = 120;
-
-    private static final int CMD_START_DHCP_SERVER = 1;
-    private static final int CMD_STOP_DHCP_SERVER = 2;
-    private static final int CMD_UPDATE_PARAMS = 3;
-
-    @NonNull
-    private final HandlerThread mHandlerThread;
-    @NonNull
-    private final String mIfName;
-    @NonNull
-    private final DhcpLeaseRepository mLeaseRepo;
-    @NonNull
-    private final SharedLog mLog;
-    @NonNull
-    private final Dependencies mDeps;
-    @NonNull
-    private final Clock mClock;
-
-    @Nullable
-    private volatile ServerHandler mHandler;
-
-    // Accessed only on the handler thread
-    @Nullable
-    private DhcpPacketListener mPacketListener;
-    @Nullable
-    private FileDescriptor mSocket;
-    @NonNull
-    private DhcpServingParams mServingParams;
-
-    /**
-     * Clock to be used by DhcpServer to track time for lease expiration.
-     *
-     * <p>The clock should track time as may be measured by clients obtaining a lease. It does not
-     * need to be monotonous across restarts of the server as long as leases are cleared when the
-     * server is stopped.
-     */
-    public static class Clock {
-        /**
-         * @see SystemClock#elapsedRealtime()
-         */
-        public long elapsedRealtime() {
-            return SystemClock.elapsedRealtime();
-        }
-    }
-
-    /**
-     * Dependencies for the DhcpServer. Useful to be mocked in tests.
-     */
-    public interface Dependencies {
-        /**
-         * Send a packet to the specified datagram socket.
-         *
-         * @param fd File descriptor of the socket.
-         * @param buffer Data to be sent.
-         * @param dst Destination address of the packet.
-         */
-        void sendPacket(@NonNull FileDescriptor fd, @NonNull ByteBuffer buffer,
-                @NonNull InetAddress dst) throws ErrnoException, IOException;
-
-        /**
-         * Create a DhcpLeaseRepository for the server.
-         * @param servingParams Parameters used to serve DHCP requests.
-         * @param log Log to be used by the repository.
-         * @param clock Clock that the repository must use to track time.
-         */
-        DhcpLeaseRepository makeLeaseRepository(@NonNull DhcpServingParams servingParams,
-                @NonNull SharedLog log, @NonNull Clock clock);
-
-        /**
-         * Create a packet listener that will send packets to be processed.
-         */
-        DhcpPacketListener makePacketListener();
-
-        /**
-         * Create a clock that the server will use to track time.
-         */
-        Clock makeClock();
-
-        /**
-         * Add an entry to the ARP cache table.
-         * @param fd Datagram socket file descriptor that must use the new entry.
-         */
-        void addArpEntry(@NonNull Inet4Address ipv4Addr, @NonNull MacAddress ethAddr,
-                @NonNull String ifname, @NonNull FileDescriptor fd) throws IOException;
-
-        /**
-         * Verify that the caller is allowed to call public methods on DhcpServer.
-         * @throws SecurityException The caller is not allowed to call public methods on DhcpServer.
-         */
-        void checkCaller() throws SecurityException;
-    }
-
-    private class DependenciesImpl implements Dependencies {
-        @Override
-        public void sendPacket(@NonNull FileDescriptor fd, @NonNull ByteBuffer buffer,
-                @NonNull InetAddress dst) throws ErrnoException, IOException {
-            Os.sendto(fd, buffer, 0, dst, DhcpPacket.DHCP_CLIENT);
-        }
-
-        @Override
-        public DhcpLeaseRepository makeLeaseRepository(@NonNull DhcpServingParams servingParams,
-                @NonNull SharedLog log, @NonNull Clock clock) {
-            return new DhcpLeaseRepository(
-                    DhcpServingParams.makeIpPrefix(servingParams.serverAddr),
-                    servingParams.excludedAddrs,
-                    servingParams.dhcpLeaseTimeSecs * 1000, log.forSubComponent(REPO_TAG), clock);
-        }
-
-        @Override
-        public DhcpPacketListener makePacketListener() {
-            return new PacketListener();
-        }
-
-        @Override
-        public Clock makeClock() {
-            return new Clock();
-        }
-
-        @Override
-        public void addArpEntry(@NonNull Inet4Address ipv4Addr, @NonNull MacAddress ethAddr,
-                @NonNull String ifname, @NonNull FileDescriptor fd) throws IOException {
-            NetworkStackUtils.addArpEntry(ipv4Addr, ethAddr, ifname, fd);
-        }
-
-        @Override
-        public void checkCaller() {
-            checkNetworkStackCallingPermission();
-        }
-    }
-
-    private static class MalformedPacketException extends Exception {
-        MalformedPacketException(String message, Throwable t) {
-            super(message, t);
-        }
-    }
-
-    public DhcpServer(@NonNull String ifName,
-            @NonNull DhcpServingParams params, @NonNull SharedLog log) {
-        this(new HandlerThread(DhcpServer.class.getSimpleName() + "." + ifName),
-                ifName, params, log, null);
-    }
-
-    @VisibleForTesting
-    DhcpServer(@NonNull HandlerThread handlerThread, @NonNull String ifName,
-            @NonNull DhcpServingParams params, @NonNull SharedLog log,
-            @Nullable Dependencies deps) {
-        if (deps == null) {
-            deps = new DependenciesImpl();
-        }
-        mHandlerThread = handlerThread;
-        mIfName = ifName;
-        mServingParams = params;
-        mLog = log;
-        mDeps = deps;
-        mClock = deps.makeClock();
-        mLeaseRepo = deps.makeLeaseRepository(mServingParams, mLog, mClock);
-    }
-
-    /**
-     * Start listening for and responding to packets.
-     *
-     * <p>It is not legal to call this method more than once; in particular the server cannot be
-     * restarted after being stopped.
-     */
-    @Override
-    public void start(@Nullable INetworkStackStatusCallback cb) {
-        mDeps.checkCaller();
-        mHandlerThread.start();
-        mHandler = new ServerHandler(mHandlerThread.getLooper());
-        sendMessage(CMD_START_DHCP_SERVER, cb);
-    }
-
-    /**
-     * Update serving parameters. All subsequently received requests will be handled with the new
-     * parameters, and current leases that are incompatible with the new parameters are dropped.
-     */
-    @Override
-    public void updateParams(@Nullable DhcpServingParamsParcel params,
-            @Nullable INetworkStackStatusCallback cb) throws RemoteException {
-        mDeps.checkCaller();
-        final DhcpServingParams parsedParams;
-        try {
-            // throws InvalidParameterException with null params
-            parsedParams = DhcpServingParams.fromParcelableObject(params);
-        } catch (DhcpServingParams.InvalidParameterException e) {
-            mLog.e("Invalid parameters sent to DhcpServer", e);
-            if (cb != null) {
-                cb.onStatusAvailable(STATUS_INVALID_ARGUMENT);
-            }
-            return;
-        }
-        sendMessage(CMD_UPDATE_PARAMS, new Pair<>(parsedParams, cb));
-    }
-
-    /**
-     * Stop listening for packets.
-     *
-     * <p>As the server is stopped asynchronously, some packets may still be processed shortly after
-     * calling this method.
-     */
-    @Override
-    public void stop(@Nullable INetworkStackStatusCallback cb) {
-        mDeps.checkCaller();
-        sendMessage(CMD_STOP_DHCP_SERVER, cb);
-    }
-
-    private void sendMessage(int what, @Nullable Object obj) {
-        if (mHandler == null) {
-            mLog.e("Attempting to send a command to stopped DhcpServer: " + what);
-            return;
-        }
-        mHandler.sendMessage(mHandler.obtainMessage(what, obj));
-    }
-
-    private class ServerHandler extends Handler {
-        ServerHandler(@NonNull Looper looper) {
-            super(looper);
-        }
-
-        @Override
-        public void handleMessage(@NonNull Message msg) {
-            final INetworkStackStatusCallback cb;
-            switch (msg.what) {
-                case CMD_UPDATE_PARAMS:
-                    final Pair<DhcpServingParams, INetworkStackStatusCallback> pair =
-                            (Pair<DhcpServingParams, INetworkStackStatusCallback>) msg.obj;
-                    final DhcpServingParams params = pair.first;
-                    mServingParams = params;
-                    mLeaseRepo.updateParams(
-                            DhcpServingParams.makeIpPrefix(mServingParams.serverAddr),
-                            params.excludedAddrs,
-                            params.dhcpLeaseTimeSecs);
-
-                    cb = pair.second;
-                    break;
-                case CMD_START_DHCP_SERVER:
-                    mPacketListener = mDeps.makePacketListener();
-                    mPacketListener.start();
-                    cb = (INetworkStackStatusCallback) msg.obj;
-                    break;
-                case CMD_STOP_DHCP_SERVER:
-                    if (mPacketListener != null) {
-                        mPacketListener.stop();
-                        mPacketListener = null;
-                    }
-                    mHandlerThread.quitSafely();
-                    cb = (INetworkStackStatusCallback) msg.obj;
-                    break;
-                default:
-                    return;
-            }
-            if (cb != null) {
-                try {
-                    cb.onStatusAvailable(STATUS_SUCCESS);
-                } catch (RemoteException e) {
-                    mLog.e("Could not send status back to caller", e);
-                }
-            }
-        }
-    }
-
-    @VisibleForTesting
-    void processPacket(@NonNull DhcpPacket packet, int srcPort) {
-        final String packetType = packet.getClass().getSimpleName();
-        if (srcPort != DHCP_CLIENT) {
-            mLog.logf("Ignored packet of type %s sent from client port %d", packetType, srcPort);
-            return;
-        }
-
-        mLog.log("Received packet of type " + packetType);
-        final Inet4Address sid = packet.mServerIdentifier;
-        if (sid != null && !sid.equals(mServingParams.serverAddr.getAddress())) {
-            mLog.log("Packet ignored due to wrong server identifier: " + sid);
-            return;
-        }
-
-        try {
-            if (packet instanceof DhcpDiscoverPacket) {
-                processDiscover((DhcpDiscoverPacket) packet);
-            } else if (packet instanceof DhcpRequestPacket) {
-                processRequest((DhcpRequestPacket) packet);
-            } else if (packet instanceof DhcpReleasePacket) {
-                processRelease((DhcpReleasePacket) packet);
-            } else {
-                mLog.e("Unknown packet type: " + packet.getClass().getSimpleName());
-            }
-        } catch (MalformedPacketException e) {
-            // Not an internal error: only logging exception message, not stacktrace
-            mLog.e("Ignored malformed packet: " + e.getMessage());
-        }
-    }
-
-    private void logIgnoredPacketInvalidSubnet(DhcpLeaseRepository.InvalidSubnetException e) {
-        // Not an internal error: only logging exception message, not stacktrace
-        mLog.e("Ignored packet from invalid subnet: " + e.getMessage());
-    }
-
-    private void processDiscover(@NonNull DhcpDiscoverPacket packet)
-            throws MalformedPacketException {
-        final DhcpLease lease;
-        final MacAddress clientMac = getMacAddr(packet);
-        try {
-            lease = mLeaseRepo.getOffer(packet.getExplicitClientIdOrNull(), clientMac,
-                    packet.mRelayIp, packet.mRequestedIp, packet.mHostName);
-        } catch (DhcpLeaseRepository.OutOfAddressesException e) {
-            transmitNak(packet, "Out of addresses to offer");
-            return;
-        } catch (DhcpLeaseRepository.InvalidSubnetException e) {
-            logIgnoredPacketInvalidSubnet(e);
-            return;
-        }
-
-        transmitOffer(packet, lease, clientMac);
-    }
-
-    private void processRequest(@NonNull DhcpRequestPacket packet) throws MalformedPacketException {
-        // If set, packet SID matches with this server's ID as checked in processPacket().
-        final boolean sidSet = packet.mServerIdentifier != null;
-        final DhcpLease lease;
-        final MacAddress clientMac = getMacAddr(packet);
-        try {
-            lease = mLeaseRepo.requestLease(packet.getExplicitClientIdOrNull(), clientMac,
-                    packet.mClientIp, packet.mRelayIp, packet.mRequestedIp, sidSet,
-                    packet.mHostName);
-        } catch (DhcpLeaseRepository.InvalidAddressException e) {
-            transmitNak(packet, "Invalid requested address");
-            return;
-        } catch (DhcpLeaseRepository.InvalidSubnetException e) {
-            logIgnoredPacketInvalidSubnet(e);
-            return;
-        }
-
-        transmitAck(packet, lease, clientMac);
-    }
-
-    private void processRelease(@NonNull DhcpReleasePacket packet)
-            throws MalformedPacketException {
-        final byte[] clientId = packet.getExplicitClientIdOrNull();
-        final MacAddress macAddr = getMacAddr(packet);
-        // Don't care about success (there is no ACK/NAK); logging is already done in the repository
-        mLeaseRepo.releaseLease(clientId, macAddr, packet.mClientIp);
-    }
-
-    private Inet4Address getAckOrOfferDst(@NonNull DhcpPacket request, @NonNull DhcpLease lease,
-            boolean broadcastFlag) {
-        // Unless relayed or broadcast, send to client IP if already configured on the client, or to
-        // the lease address if the client has no configured address
-        if (!isEmpty(request.mRelayIp)) {
-            return request.mRelayIp;
-        } else if (broadcastFlag) {
-            return IPV4_ADDR_ALL;
-        } else if (!isEmpty(request.mClientIp)) {
-            return request.mClientIp;
-        } else {
-            return lease.getNetAddr();
-        }
-    }
-
-    /**
-     * Determine whether the broadcast flag should be set in the BOOTP packet flags. This does not
-     * apply to NAK responses, which should always have it set.
-     */
-    private static boolean getBroadcastFlag(@NonNull DhcpPacket request, @NonNull DhcpLease lease) {
-        // No broadcast flag if the client already has a configured IP to unicast to. RFC2131 #4.1
-        // has some contradictions regarding broadcast behavior if a client already has an IP
-        // configured and sends a request with both ciaddr (renew/rebind) and the broadcast flag
-        // set. Sending a unicast response to ciaddr matches previous behavior and is more
-        // efficient.
-        // If the client has no configured IP, broadcast if requested by the client or if the lease
-        // address cannot be used to send a unicast reply either.
-        return isEmpty(request.mClientIp) && (request.mBroadcast || isEmpty(lease.getNetAddr()));
-    }
-
-    /**
-     * Get the hostname from a lease if non-empty and requested in the incoming request.
-     * @param request The incoming request.
-     * @return The hostname, or null if not requested or empty.
-     */
-    @Nullable
-    private static String getHostnameIfRequested(@NonNull DhcpPacket request,
-            @NonNull DhcpLease lease) {
-        return request.hasRequestedParam(DHCP_HOST_NAME) && !TextUtils.isEmpty(lease.getHostname())
-                ? lease.getHostname()
-                : null;
-    }
-
-    private boolean transmitOffer(@NonNull DhcpPacket request, @NonNull DhcpLease lease,
-            @NonNull MacAddress clientMac) {
-        final boolean broadcastFlag = getBroadcastFlag(request, lease);
-        final int timeout = getLeaseTimeout(lease);
-        final Inet4Address prefixMask =
-                getPrefixMaskAsInet4Address(mServingParams.serverAddr.getPrefixLength());
-        final Inet4Address broadcastAddr = getBroadcastAddress(
-                mServingParams.getServerInet4Addr(), mServingParams.serverAddr.getPrefixLength());
-        final String hostname = getHostnameIfRequested(request, lease);
-        final ByteBuffer offerPacket = DhcpPacket.buildOfferPacket(
-                ENCAP_BOOTP, request.mTransId, broadcastFlag, mServingParams.getServerInet4Addr(),
-                request.mRelayIp, lease.getNetAddr(), request.mClientMac, timeout, prefixMask,
-                broadcastAddr, new ArrayList<>(mServingParams.defaultRouters),
-                new ArrayList<>(mServingParams.dnsServers),
-                mServingParams.getServerInet4Addr(), null /* domainName */, hostname,
-                mServingParams.metered, (short) mServingParams.linkMtu);
-
-        return transmitOfferOrAckPacket(offerPacket, request, lease, clientMac, broadcastFlag);
-    }
-
-    private boolean transmitAck(@NonNull DhcpPacket request, @NonNull DhcpLease lease,
-            @NonNull MacAddress clientMac) {
-        // TODO: replace DhcpPacket's build methods with real builders and use common code with
-        // transmitOffer above
-        final boolean broadcastFlag = getBroadcastFlag(request, lease);
-        final int timeout = getLeaseTimeout(lease);
-        final String hostname = getHostnameIfRequested(request, lease);
-        final ByteBuffer ackPacket = DhcpPacket.buildAckPacket(ENCAP_BOOTP, request.mTransId,
-                broadcastFlag, mServingParams.getServerInet4Addr(), request.mRelayIp,
-                lease.getNetAddr(), request.mClientIp, request.mClientMac, timeout,
-                mServingParams.getPrefixMaskAsAddress(), mServingParams.getBroadcastAddress(),
-                new ArrayList<>(mServingParams.defaultRouters),
-                new ArrayList<>(mServingParams.dnsServers),
-                mServingParams.getServerInet4Addr(), null /* domainName */, hostname,
-                mServingParams.metered, (short) mServingParams.linkMtu);
-
-        return transmitOfferOrAckPacket(ackPacket, request, lease, clientMac, broadcastFlag);
-    }
-
-    private boolean transmitNak(DhcpPacket request, String message) {
-        mLog.w("Transmitting NAK: " + message);
-        // Always set broadcast flag for NAK: client may not have a correct IP
-        final ByteBuffer nakPacket = DhcpPacket.buildNakPacket(
-                ENCAP_BOOTP, request.mTransId, mServingParams.getServerInet4Addr(),
-                request.mRelayIp, request.mClientMac, true /* broadcast */, message);
-
-        final Inet4Address dst = isEmpty(request.mRelayIp)
-                ? IPV4_ADDR_ALL
-                : request.mRelayIp;
-        return transmitPacket(nakPacket, DhcpNakPacket.class.getSimpleName(), dst);
-    }
-
-    private boolean transmitOfferOrAckPacket(@NonNull ByteBuffer buf, @NonNull DhcpPacket request,
-            @NonNull DhcpLease lease, @NonNull MacAddress clientMac, boolean broadcastFlag) {
-        mLog.logf("Transmitting %s with lease %s", request.getClass().getSimpleName(), lease);
-        // Client may not yet respond to ARP for the lease address, which may be the destination
-        // address. Add an entry to the ARP cache to save future ARP probes and make sure the
-        // packet reaches its destination.
-        if (!addArpEntry(clientMac, lease.getNetAddr())) {
-            // Logging for error already done
-            return false;
-        }
-        final Inet4Address dst = getAckOrOfferDst(request, lease, broadcastFlag);
-        return transmitPacket(buf, request.getClass().getSimpleName(), dst);
-    }
-
-    private boolean transmitPacket(@NonNull ByteBuffer buf, @NonNull String packetTypeTag,
-            @NonNull Inet4Address dst) {
-        try {
-            mDeps.sendPacket(mSocket, buf, dst);
-        } catch (ErrnoException | IOException e) {
-            mLog.e("Can't send packet " + packetTypeTag, e);
-            return false;
-        }
-        return true;
-    }
-
-    private boolean addArpEntry(@NonNull MacAddress macAddr, @NonNull Inet4Address inetAddr) {
-        try {
-            mDeps.addArpEntry(inetAddr, macAddr, mIfName, mSocket);
-            return true;
-        } catch (IOException e) {
-            mLog.e("Error adding client to ARP table", e);
-            return false;
-        }
-    }
-
-    /**
-     * Get the remaining lease time in seconds, starting from {@link Clock#elapsedRealtime()}.
-     *
-     * <p>This is an unsigned 32-bit integer, so it cannot be read as a standard (signed) Java int.
-     * The return value is only intended to be used to populate the lease time field in a DHCP
-     * response, considering that lease time is an unsigned 32-bit integer field in DHCP packets.
-     *
-     * <p>Lease expiration times are tracked internally with millisecond precision: this method
-     * returns a rounded down value.
-     */
-    private int getLeaseTimeout(@NonNull DhcpLease lease) {
-        final long remainingTimeSecs = (lease.getExpTime() - mClock.elapsedRealtime()) / 1000;
-        if (remainingTimeSecs < 0) {
-            mLog.e("Processing expired lease " + lease);
-            return EXPIRED_FALLBACK_LEASE_TIME_SECS;
-        }
-
-        if (remainingTimeSecs >= toUnsignedLong(INFINITE_LEASE)) {
-            return INFINITE_LEASE;
-        }
-
-        return (int) remainingTimeSecs;
-    }
-
-    /**
-     * Get the client MAC address from a packet.
-     *
-     * @throws MalformedPacketException The address in the packet uses an unsupported format.
-     */
-    @NonNull
-    private MacAddress getMacAddr(@NonNull DhcpPacket packet) throws MalformedPacketException {
-        try {
-            return MacAddress.fromBytes(packet.getClientMac());
-        } catch (IllegalArgumentException e) {
-            final String message = "Invalid MAC address in packet: "
-                    + HexDump.dumpHexString(packet.getClientMac());
-            throw new MalformedPacketException(message, e);
-        }
-    }
-
-    private static boolean isEmpty(@Nullable Inet4Address address) {
-        return address == null || IPV4_ADDR_ANY.equals(address);
-    }
-
-    private class PacketListener extends DhcpPacketListener {
-        PacketListener() {
-            super(mHandler);
-        }
-
-        @Override
-        protected void onReceive(@NonNull DhcpPacket packet, @NonNull Inet4Address srcAddr,
-                int srcPort) {
-            processPacket(packet, srcPort);
-        }
-
-        @Override
-        protected void logError(@NonNull String msg, Exception e) {
-            mLog.e("Error receiving packet: " + msg, e);
-        }
-
-        @Override
-        protected void logParseError(@NonNull byte[] packet, int length,
-                @NonNull DhcpPacket.ParseException e) {
-            mLog.e("Error parsing packet", e);
-        }
-
-        @Override
-        protected FileDescriptor createFd() {
-            // TODO: have and use an API to set a socket tag without going through the thread tag
-            final int oldTag = TrafficStats.getAndSetThreadStatsTag(TAG_SYSTEM_DHCP_SERVER);
-            try {
-                mSocket = Os.socket(AF_INET, SOCK_DGRAM | SOCK_NONBLOCK, IPPROTO_UDP);
-                SocketUtils.bindSocketToInterface(mSocket, mIfName);
-                Os.setsockoptInt(mSocket, SOL_SOCKET, SO_REUSEADDR, 1);
-                Os.setsockoptInt(mSocket, SOL_SOCKET, SO_BROADCAST, 1);
-                Os.bind(mSocket, IPV4_ADDR_ANY, DHCP_SERVER);
-
-                return mSocket;
-            } catch (IOException | ErrnoException e) {
-                mLog.e("Error creating UDP socket", e);
-                DhcpServer.this.stop(null);
-                return null;
-            } finally {
-                TrafficStats.setThreadStatsTag(oldTag);
-            }
-        }
-    }
-
-    @Override
-    public int getInterfaceVersion() {
-        return this.VERSION;
-    }
-}
diff --git a/packages/NetworkStack/src/android/net/dhcp/DhcpServingParams.java b/packages/NetworkStack/src/android/net/dhcp/DhcpServingParams.java
deleted file mode 100644
index 230b693..0000000
--- a/packages/NetworkStack/src/android/net/dhcp/DhcpServingParams.java
+++ /dev/null
@@ -1,377 +0,0 @@
-/*
- * Copyright (C) 2018 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.net.dhcp;
-
-import static android.net.shared.Inet4AddressUtils.getPrefixMaskAsInet4Address;
-import static android.net.shared.Inet4AddressUtils.intToInet4AddressHTH;
-
-import static com.android.server.util.NetworkStackConstants.INFINITE_LEASE;
-import static com.android.server.util.NetworkStackConstants.IPV4_MAX_MTU;
-import static com.android.server.util.NetworkStackConstants.IPV4_MIN_MTU;
-
-import static java.lang.Integer.toUnsignedLong;
-
-import android.annotation.NonNull;
-import android.annotation.Nullable;
-import android.net.IpPrefix;
-import android.net.LinkAddress;
-import android.net.shared.Inet4AddressUtils;
-import android.util.ArraySet;
-
-import java.net.Inet4Address;
-import java.util.Arrays;
-import java.util.Collections;
-import java.util.HashSet;
-import java.util.Set;
-
-/**
- * Parameters used by the DhcpServer to serve requests.
- *
- * <p>Instances are immutable. Use {@link DhcpServingParams.Builder} to instantiate.
- * @hide
- */
-public class DhcpServingParams {
-    public static final int MTU_UNSET = 0;
-    public static final int MIN_PREFIX_LENGTH = 16;
-    public static final int MAX_PREFIX_LENGTH = 30;
-
-    /** Server inet address and prefix to serve */
-    @NonNull
-    public final LinkAddress serverAddr;
-
-    /**
-     * Default routers to be advertised to DHCP clients. May be empty.
-     * This set is provided by {@link DhcpServingParams.Builder} and is immutable.
-     */
-    @NonNull
-    public final Set<Inet4Address> defaultRouters;
-
-    /**
-     * DNS servers to be advertised to DHCP clients. May be empty.
-     * This set is provided by {@link DhcpServingParams.Builder} and is immutable.
-     */
-    @NonNull
-    public final Set<Inet4Address> dnsServers;
-
-    /**
-     * Excluded addresses that the DHCP server is not allowed to assign to clients.
-     * This set is provided by {@link DhcpServingParams.Builder} and is immutable.
-     */
-    @NonNull
-    public final Set<Inet4Address> excludedAddrs;
-
-    // DHCP uses uint32. Use long for clearer code, and check range when building.
-    public final long dhcpLeaseTimeSecs;
-    public final int linkMtu;
-
-    /**
-     * Indicates whether the DHCP server should send the ANDROID_METERED vendor-specific option.
-     */
-    public final boolean metered;
-
-    /**
-     * Checked exception thrown when some parameters used to build {@link DhcpServingParams} are
-     * missing or invalid.
-     */
-    public static class InvalidParameterException extends Exception {
-        public InvalidParameterException(String message) {
-            super(message);
-        }
-    }
-
-    private DhcpServingParams(@NonNull LinkAddress serverAddr,
-            @NonNull Set<Inet4Address> defaultRouters,
-            @NonNull Set<Inet4Address> dnsServers, @NonNull Set<Inet4Address> excludedAddrs,
-            long dhcpLeaseTimeSecs, int linkMtu, boolean metered) {
-        this.serverAddr = serverAddr;
-        this.defaultRouters = defaultRouters;
-        this.dnsServers = dnsServers;
-        this.excludedAddrs = excludedAddrs;
-        this.dhcpLeaseTimeSecs = dhcpLeaseTimeSecs;
-        this.linkMtu = linkMtu;
-        this.metered = metered;
-    }
-
-    /**
-     * Create parameters from a stable AIDL-compatible parcel.
-     * @throws InvalidParameterException The parameters parcelable is null or invalid.
-     */
-    public static DhcpServingParams fromParcelableObject(@Nullable DhcpServingParamsParcel parcel)
-            throws InvalidParameterException {
-        if (parcel == null) {
-            throw new InvalidParameterException("Null serving parameters");
-        }
-        final LinkAddress serverAddr = new LinkAddress(
-                intToInet4AddressHTH(parcel.serverAddr),
-                parcel.serverAddrPrefixLength);
-        return new Builder()
-                .setServerAddr(serverAddr)
-                .setDefaultRouters(toInet4AddressSet(parcel.defaultRouters))
-                .setDnsServers(toInet4AddressSet(parcel.dnsServers))
-                .setExcludedAddrs(toInet4AddressSet(parcel.excludedAddrs))
-                .setDhcpLeaseTimeSecs(parcel.dhcpLeaseTimeSecs)
-                .setLinkMtu(parcel.linkMtu)
-                .setMetered(parcel.metered)
-                .build();
-    }
-
-    private static Set<Inet4Address> toInet4AddressSet(@Nullable int[] addrs) {
-        if (addrs == null) {
-            return new HashSet<>(0);
-        }
-
-        final HashSet<Inet4Address> res = new HashSet<>();
-        for (int addr : addrs) {
-            res.add(intToInet4AddressHTH(addr));
-        }
-        return res;
-    }
-
-    @NonNull
-    public Inet4Address getServerInet4Addr() {
-        return (Inet4Address) serverAddr.getAddress();
-    }
-
-    /**
-     * Get the served prefix mask as an IPv4 address.
-     *
-     * <p>For example, if the served prefix is 192.168.42.0/24, this will return 255.255.255.0.
-     */
-    @NonNull
-    public Inet4Address getPrefixMaskAsAddress() {
-        return getPrefixMaskAsInet4Address(serverAddr.getPrefixLength());
-    }
-
-    /**
-     * Get the server broadcast address.
-     *
-     * <p>For example, if the server {@link LinkAddress} is 192.168.42.1/24, this will return
-     * 192.168.42.255.
-     */
-    @NonNull
-    public Inet4Address getBroadcastAddress() {
-        return Inet4AddressUtils.getBroadcastAddress(
-                getServerInet4Addr(), serverAddr.getPrefixLength());
-    }
-
-    /**
-     * Utility class to create new instances of {@link DhcpServingParams} while checking validity
-     * of the parameters.
-     */
-    public static class Builder {
-        private LinkAddress mServerAddr;
-        private Set<Inet4Address> mDefaultRouters;
-        private Set<Inet4Address> mDnsServers;
-        private Set<Inet4Address> mExcludedAddrs;
-        private long mDhcpLeaseTimeSecs;
-        private int mLinkMtu = MTU_UNSET;
-        private boolean mMetered;
-
-        /**
-         * Set the server address and served prefix for the DHCP server.
-         *
-         * <p>This parameter is required.
-         */
-        public Builder setServerAddr(@NonNull LinkAddress serverAddr) {
-            this.mServerAddr = serverAddr;
-            return this;
-        }
-
-        /**
-         * Set the default routers to be advertised to DHCP clients.
-         *
-         * <p>Each router must be inside the served prefix. This may be an empty set, but it must
-         * always be set explicitly before building the {@link DhcpServingParams}.
-         */
-        public Builder setDefaultRouters(@NonNull Set<Inet4Address> defaultRouters) {
-            this.mDefaultRouters = defaultRouters;
-            return this;
-        }
-
-        /**
-         * Set the default routers to be advertised to DHCP clients.
-         *
-         * <p>Each router must be inside the served prefix. This may be an empty list of routers,
-         * but it must always be set explicitly before building the {@link DhcpServingParams}.
-         */
-        public Builder setDefaultRouters(@NonNull Inet4Address... defaultRouters) {
-            return setDefaultRouters(makeArraySet(defaultRouters));
-        }
-
-        /**
-         * Convenience method to build the parameters with no default router.
-         *
-         * <p>Equivalent to calling {@link #setDefaultRouters(Inet4Address...)} with no address.
-         */
-        public Builder withNoDefaultRouter() {
-            return setDefaultRouters();
-        }
-
-        /**
-         * Set the DNS servers to be advertised to DHCP clients.
-         *
-         * <p>This may be an empty set, but it must always be set explicitly before building the
-         * {@link DhcpServingParams}.
-         */
-        public Builder setDnsServers(@NonNull Set<Inet4Address> dnsServers) {
-            this.mDnsServers = dnsServers;
-            return this;
-        }
-
-        /**
-         * Set the DNS servers to be advertised to DHCP clients.
-         *
-         * <p>This may be an empty list of servers, but it must always be set explicitly before
-         * building the {@link DhcpServingParams}.
-         */
-        public Builder setDnsServers(@NonNull Inet4Address... dnsServers) {
-            return setDnsServers(makeArraySet(dnsServers));
-        }
-
-        /**
-         * Convenience method to build the parameters with no DNS server.
-         *
-         * <p>Equivalent to calling {@link #setDnsServers(Inet4Address...)} with no address.
-         */
-        public Builder withNoDnsServer() {
-            return setDnsServers();
-        }
-
-        /**
-         * Set excluded addresses that the DHCP server is not allowed to assign to clients.
-         *
-         * <p>This parameter is optional. DNS servers and default routers are always excluded
-         * and do not need to be set here.
-         */
-        public Builder setExcludedAddrs(@NonNull Set<Inet4Address> excludedAddrs) {
-            this.mExcludedAddrs = excludedAddrs;
-            return this;
-        }
-
-        /**
-         * Set excluded addresses that the DHCP server is not allowed to assign to clients.
-         *
-         * <p>This parameter is optional. DNS servers and default routers are always excluded
-         * and do not need to be set here.
-         */
-        public Builder setExcludedAddrs(@NonNull Inet4Address... excludedAddrs) {
-            return setExcludedAddrs(makeArraySet(excludedAddrs));
-        }
-
-        /**
-         * Set the lease time for leases assigned by the DHCP server.
-         *
-         * <p>This parameter is required.
-         */
-        public Builder setDhcpLeaseTimeSecs(long dhcpLeaseTimeSecs) {
-            this.mDhcpLeaseTimeSecs = dhcpLeaseTimeSecs;
-            return this;
-        }
-
-        /**
-         * Set the link MTU to be advertised to DHCP clients.
-         *
-         * <p>If set to {@link #MTU_UNSET}, no MTU will be advertised to clients. This parameter
-         * is optional and defaults to {@link #MTU_UNSET}.
-         */
-        public Builder setLinkMtu(int linkMtu) {
-            this.mLinkMtu = linkMtu;
-            return this;
-        }
-
-        /**
-         * Set whether the DHCP server should send the ANDROID_METERED vendor-specific option.
-         *
-         * <p>If not set, the default value is false.
-         */
-        public Builder setMetered(boolean metered) {
-            this.mMetered = metered;
-            return this;
-        }
-
-        /**
-         * Create a new {@link DhcpServingParams} instance based on parameters set in the builder.
-         *
-         * <p>This method has no side-effects. If it does not throw, a valid
-         * {@link DhcpServingParams} is returned.
-         * @return The constructed parameters.
-         * @throws InvalidParameterException At least one parameter is missing or invalid.
-         */
-        @NonNull
-        public DhcpServingParams build() throws InvalidParameterException {
-            if (mServerAddr == null) {
-                throw new InvalidParameterException("Missing serverAddr");
-            }
-            if (mDefaultRouters == null) {
-                throw new InvalidParameterException("Missing defaultRouters");
-            }
-            if (mDnsServers == null) {
-                // Empty set is OK, but enforce explicitly setting it
-                throw new InvalidParameterException("Missing dnsServers");
-            }
-            if (mDhcpLeaseTimeSecs <= 0 || mDhcpLeaseTimeSecs > toUnsignedLong(INFINITE_LEASE)) {
-                throw new InvalidParameterException("Invalid lease time: " + mDhcpLeaseTimeSecs);
-            }
-            if (mLinkMtu != MTU_UNSET && (mLinkMtu < IPV4_MIN_MTU || mLinkMtu > IPV4_MAX_MTU)) {
-                throw new InvalidParameterException("Invalid link MTU: " + mLinkMtu);
-            }
-            if (!mServerAddr.isIpv4()) {
-                throw new InvalidParameterException("serverAddr must be IPv4");
-            }
-            if (mServerAddr.getPrefixLength() < MIN_PREFIX_LENGTH
-                    || mServerAddr.getPrefixLength() > MAX_PREFIX_LENGTH) {
-                throw new InvalidParameterException("Prefix length is not in supported range");
-            }
-
-            final IpPrefix prefix = makeIpPrefix(mServerAddr);
-            for (Inet4Address addr : mDefaultRouters) {
-                if (!prefix.contains(addr)) {
-                    throw new InvalidParameterException(String.format(
-                            "Default router %s is not in server prefix %s", addr, mServerAddr));
-                }
-            }
-
-            final Set<Inet4Address> excl = new HashSet<>();
-            if (mExcludedAddrs != null) {
-                excl.addAll(mExcludedAddrs);
-            }
-            excl.add((Inet4Address) mServerAddr.getAddress());
-            excl.addAll(mDefaultRouters);
-            excl.addAll(mDnsServers);
-
-            return new DhcpServingParams(mServerAddr,
-                    Collections.unmodifiableSet(new HashSet<>(mDefaultRouters)),
-                    Collections.unmodifiableSet(new HashSet<>(mDnsServers)),
-                    Collections.unmodifiableSet(excl),
-                    mDhcpLeaseTimeSecs, mLinkMtu, mMetered);
-        }
-    }
-
-    /**
-     * Utility method to create an IpPrefix with the address and prefix length of a LinkAddress.
-     */
-    @NonNull
-    static IpPrefix makeIpPrefix(@NonNull LinkAddress addr) {
-        return new IpPrefix(addr.getAddress(), addr.getPrefixLength());
-    }
-
-    private static <T> ArraySet<T> makeArraySet(T[] elements) {
-        final ArraySet<T> set = new ArraySet<>(elements.length);
-        set.addAll(Arrays.asList(elements));
-        return set;
-    }
-}
diff --git a/packages/NetworkStack/src/android/net/ip/ConnectivityPacketTracker.java b/packages/NetworkStack/src/android/net/ip/ConnectivityPacketTracker.java
deleted file mode 100644
index eb49218..0000000
--- a/packages/NetworkStack/src/android/net/ip/ConnectivityPacketTracker.java
+++ /dev/null
@@ -1,153 +0,0 @@
-/*
- * Copyright (C) 2016 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.net.ip;
-
-import static android.net.util.SocketUtils.makePacketSocketAddress;
-import static android.system.OsConstants.AF_PACKET;
-import static android.system.OsConstants.ARPHRD_ETHER;
-import static android.system.OsConstants.ETH_P_ALL;
-import static android.system.OsConstants.SOCK_NONBLOCK;
-import static android.system.OsConstants.SOCK_RAW;
-
-import android.net.util.ConnectivityPacketSummary;
-import android.net.util.InterfaceParams;
-import android.net.util.NetworkStackUtils;
-import android.net.util.PacketReader;
-import android.os.Handler;
-import android.system.ErrnoException;
-import android.system.Os;
-import android.text.TextUtils;
-import android.util.LocalLog;
-import android.util.Log;
-
-import com.android.internal.util.HexDump;
-
-import java.io.FileDescriptor;
-import java.io.IOException;
-
-
-/**
- * Critical connectivity packet tracking daemon.
- *
- * Tracks ARP, DHCPv4, and IPv6 RS/RA/NS/NA packets.
- *
- * This class's constructor, start() and stop() methods must only be called
- * from the same thread on which the passed in |log| is accessed.
- *
- * Log lines include a hexdump of the packet, which can be decoded via:
- *
- *     echo -n H3XSTR1NG | sed -e 's/\([0-9A-F][0-9A-F]\)/\1 /g' -e 's/^/000000 /'
- *                       | text2pcap - -
- *                       | tcpdump -n -vv -e -r -
- *
- * @hide
- */
-public class ConnectivityPacketTracker {
-    private static final String TAG = ConnectivityPacketTracker.class.getSimpleName();
-    private static final boolean DBG = false;
-    private static final String MARK_START = "--- START ---";
-    private static final String MARK_STOP = "--- STOP ---";
-    private static final String MARK_NAMED_START = "--- START (%s) ---";
-    private static final String MARK_NAMED_STOP = "--- STOP (%s) ---";
-
-    private final String mTag;
-    private final LocalLog mLog;
-    private final PacketReader mPacketListener;
-    private boolean mRunning;
-    private String mDisplayName;
-
-    public ConnectivityPacketTracker(Handler h, InterfaceParams ifParams, LocalLog log) {
-        if (ifParams == null) throw new IllegalArgumentException("null InterfaceParams");
-
-        mTag = TAG + "." + ifParams.name;
-        mLog = log;
-        mPacketListener = new PacketListener(h, ifParams);
-    }
-
-    public void start(String displayName) {
-        mRunning = true;
-        mDisplayName = displayName;
-        mPacketListener.start();
-    }
-
-    public void stop() {
-        mPacketListener.stop();
-        mRunning = false;
-        mDisplayName = null;
-    }
-
-    private final class PacketListener extends PacketReader {
-        private final InterfaceParams mInterface;
-
-        PacketListener(Handler h, InterfaceParams ifParams) {
-            super(h, ifParams.defaultMtu);
-            mInterface = ifParams;
-        }
-
-        @Override
-        protected FileDescriptor createFd() {
-            FileDescriptor s = null;
-            try {
-                s = Os.socket(AF_PACKET, SOCK_RAW | SOCK_NONBLOCK, 0);
-                NetworkStackUtils.attachControlPacketFilter(s, ARPHRD_ETHER);
-                Os.bind(s, makePacketSocketAddress((short) ETH_P_ALL, mInterface.index));
-            } catch (ErrnoException | IOException e) {
-                logError("Failed to create packet tracking socket: ", e);
-                closeFd(s);
-                return null;
-            }
-            return s;
-        }
-
-        @Override
-        protected void handlePacket(byte[] recvbuf, int length) {
-            final String summary = ConnectivityPacketSummary.summarize(
-                    mInterface.macAddr, recvbuf, length);
-            if (summary == null) return;
-
-            if (DBG) Log.d(mTag, summary);
-            addLogEntry(summary + "\n[" + HexDump.toHexString(recvbuf, 0, length) + "]");
-        }
-
-        @Override
-        protected void onStart() {
-            final String msg = TextUtils.isEmpty(mDisplayName)
-                    ? MARK_START
-                    : String.format(MARK_NAMED_START, mDisplayName);
-            mLog.log(msg);
-        }
-
-        @Override
-        protected void onStop() {
-            String msg = TextUtils.isEmpty(mDisplayName)
-                    ? MARK_STOP
-                    : String.format(MARK_NAMED_STOP, mDisplayName);
-            if (!mRunning) msg += " (packet listener stopped unexpectedly)";
-            mLog.log(msg);
-        }
-
-        @Override
-        protected void logError(String msg, Exception e) {
-            Log.e(mTag, msg, e);
-            addLogEntry(msg + e);
-        }
-
-        private void addLogEntry(String entry) {
-            mLog.log(entry);
-        }
-    }
-}
diff --git a/packages/NetworkStack/src/android/net/ip/IpClient.java b/packages/NetworkStack/src/android/net/ip/IpClient.java
deleted file mode 100644
index 266b1b0..0000000
--- a/packages/NetworkStack/src/android/net/ip/IpClient.java
+++ /dev/null
@@ -1,1784 +0,0 @@
-/*
- * Copyright (C) 2017 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.net.ip;
-
-import static android.net.RouteInfo.RTN_UNICAST;
-import static android.net.shared.IpConfigurationParcelableUtil.toStableParcelable;
-
-import static com.android.server.util.PermissionUtil.checkNetworkStackCallingPermission;
-
-import android.annotation.NonNull;
-import android.content.Context;
-import android.net.ConnectivityManager;
-import android.net.DhcpResults;
-import android.net.INetd;
-import android.net.IpPrefix;
-import android.net.LinkAddress;
-import android.net.LinkProperties;
-import android.net.NattKeepalivePacketDataParcelable;
-import android.net.NetworkStackIpMemoryStore;
-import android.net.ProvisioningConfigurationParcelable;
-import android.net.ProxyInfo;
-import android.net.RouteInfo;
-import android.net.TcpKeepalivePacketDataParcelable;
-import android.net.apf.ApfCapabilities;
-import android.net.apf.ApfFilter;
-import android.net.dhcp.DhcpClient;
-import android.net.metrics.IpConnectivityLog;
-import android.net.metrics.IpManagerEvent;
-import android.net.shared.InitialConfiguration;
-import android.net.shared.ProvisioningConfiguration;
-import android.net.util.InterfaceParams;
-import android.net.util.SharedLog;
-import android.os.ConditionVariable;
-import android.os.IBinder;
-import android.os.Message;
-import android.os.RemoteException;
-import android.os.SystemClock;
-import android.text.TextUtils;
-import android.util.LocalLog;
-import android.util.Log;
-import android.util.Pair;
-import android.util.SparseArray;
-
-import com.android.internal.annotations.VisibleForTesting;
-import com.android.internal.util.IState;
-import com.android.internal.util.IndentingPrintWriter;
-import com.android.internal.util.MessageUtils;
-import com.android.internal.util.Preconditions;
-import com.android.internal.util.State;
-import com.android.internal.util.StateMachine;
-import com.android.internal.util.WakeupMessage;
-import com.android.server.NetworkObserverRegistry;
-import com.android.server.NetworkStackService.NetworkStackServiceManager;
-
-import java.io.FileDescriptor;
-import java.io.PrintWriter;
-import java.net.InetAddress;
-import java.util.Collection;
-import java.util.List;
-import java.util.Objects;
-import java.util.Set;
-import java.util.concurrent.ConcurrentHashMap;
-import java.util.concurrent.CountDownLatch;
-import java.util.function.Predicate;
-import java.util.stream.Collectors;
-
-
-/**
- * IpClient
- *
- * This class provides the interface to IP-layer provisioning and maintenance
- * functionality that can be used by transport layers like Wi-Fi, Ethernet,
- * et cetera.
- *
- * [ Lifetime ]
- * IpClient is designed to be instantiated as soon as the interface name is
- * known and can be as long-lived as the class containing it (i.e. declaring
- * it "private final" is okay).
- *
- * @hide
- */
-public class IpClient extends StateMachine {
-    private static final boolean DBG = false;
-
-    // For message logging.
-    private static final Class[] sMessageClasses = { IpClient.class, DhcpClient.class };
-    private static final SparseArray<String> sWhatToString =
-            MessageUtils.findMessageNames(sMessageClasses);
-    // Two static concurrent hashmaps of interface name to logging classes.
-    // One holds StateMachine logs and the other connectivity packet logs.
-    private static final ConcurrentHashMap<String, SharedLog> sSmLogs = new ConcurrentHashMap<>();
-    private static final ConcurrentHashMap<String, LocalLog> sPktLogs = new ConcurrentHashMap<>();
-    private final NetworkStackIpMemoryStore mIpMemoryStore;
-
-    /**
-     * Dump all state machine and connectivity packet logs to the specified writer.
-     * @param skippedIfaces Interfaces for which logs should not be dumped.
-     */
-    public static void dumpAllLogs(PrintWriter writer, Set<String> skippedIfaces) {
-        for (String ifname : sSmLogs.keySet()) {
-            if (skippedIfaces.contains(ifname)) continue;
-
-            writer.println(String.format("--- BEGIN %s ---", ifname));
-
-            final SharedLog smLog = sSmLogs.get(ifname);
-            if (smLog != null) {
-                writer.println("State machine log:");
-                smLog.dump(null, writer, null);
-            }
-
-            writer.println("");
-
-            final LocalLog pktLog = sPktLogs.get(ifname);
-            if (pktLog != null) {
-                writer.println("Connectivity packet log:");
-                pktLog.readOnlyLocalLog().dump(null, writer, null);
-            }
-
-            writer.println(String.format("--- END %s ---", ifname));
-        }
-    }
-
-    // Use a wrapper class to log in order to ensure complete and detailed
-    // logging. This method is lighter weight than annotations/reflection
-    // and has the following benefits:
-    //
-    //     - No invoked method can be forgotten.
-    //       Any new method added to IpClient.Callback must be overridden
-    //       here or it will never be called.
-    //
-    //     - No invoking call site can be forgotten.
-    //       Centralized logging in this way means call sites don't need to
-    //       remember to log, and therefore no call site can be forgotten.
-    //
-    //     - No variation in log format among call sites.
-    //       Encourages logging of any available arguments, and all call sites
-    //       are necessarily logged identically.
-    //
-    // NOTE: Log first because passed objects may or may not be thread-safe and
-    // once passed on to the callback they may be modified by another thread.
-    //
-    // TODO: Find an lighter weight approach.
-    public static class IpClientCallbacksWrapper {
-        private static final String PREFIX = "INVOKE ";
-        private final IIpClientCallbacks mCallback;
-        private final SharedLog mLog;
-
-        @VisibleForTesting
-        protected IpClientCallbacksWrapper(IIpClientCallbacks callback, SharedLog log) {
-            mCallback = callback;
-            mLog = log;
-        }
-
-        private void log(String msg) {
-            mLog.log(PREFIX + msg);
-        }
-
-        private void log(String msg, Throwable e) {
-            mLog.e(PREFIX + msg, e);
-        }
-
-        public void onPreDhcpAction() {
-            log("onPreDhcpAction()");
-            try {
-                mCallback.onPreDhcpAction();
-            } catch (RemoteException e) {
-                log("Failed to call onPreDhcpAction", e);
-            }
-        }
-
-        public void onPostDhcpAction() {
-            log("onPostDhcpAction()");
-            try {
-                mCallback.onPostDhcpAction();
-            } catch (RemoteException e) {
-                log("Failed to call onPostDhcpAction", e);
-            }
-        }
-
-        public void onNewDhcpResults(DhcpResults dhcpResults) {
-            log("onNewDhcpResults({" + dhcpResults + "})");
-            try {
-                mCallback.onNewDhcpResults(toStableParcelable(dhcpResults));
-            } catch (RemoteException e) {
-                log("Failed to call onNewDhcpResults", e);
-            }
-        }
-
-        public void onProvisioningSuccess(LinkProperties newLp) {
-            log("onProvisioningSuccess({" + newLp + "})");
-            try {
-                mCallback.onProvisioningSuccess(newLp);
-            } catch (RemoteException e) {
-                log("Failed to call onProvisioningSuccess", e);
-            }
-        }
-
-        public void onProvisioningFailure(LinkProperties newLp) {
-            log("onProvisioningFailure({" + newLp + "})");
-            try {
-                mCallback.onProvisioningFailure(newLp);
-            } catch (RemoteException e) {
-                log("Failed to call onProvisioningFailure", e);
-            }
-        }
-
-        public void onLinkPropertiesChange(LinkProperties newLp) {
-            log("onLinkPropertiesChange({" + newLp + "})");
-            try {
-                mCallback.onLinkPropertiesChange(newLp);
-            } catch (RemoteException e) {
-                log("Failed to call onLinkPropertiesChange", e);
-            }
-        }
-
-        public void onReachabilityLost(String logMsg) {
-            log("onReachabilityLost(" + logMsg + ")");
-            try {
-                mCallback.onReachabilityLost(logMsg);
-            } catch (RemoteException e) {
-                log("Failed to call onReachabilityLost", e);
-            }
-        }
-
-        public void onQuit() {
-            log("onQuit()");
-            try {
-                mCallback.onQuit();
-            } catch (RemoteException e) {
-                log("Failed to call onQuit", e);
-            }
-        }
-
-        public void installPacketFilter(byte[] filter) {
-            log("installPacketFilter(byte[" + filter.length + "])");
-            try {
-                mCallback.installPacketFilter(filter);
-            } catch (RemoteException e) {
-                log("Failed to call installPacketFilter", e);
-            }
-        }
-
-        public void startReadPacketFilter() {
-            log("startReadPacketFilter()");
-            try {
-                mCallback.startReadPacketFilter();
-            } catch (RemoteException e) {
-                log("Failed to call startReadPacketFilter", e);
-            }
-        }
-
-        public void setFallbackMulticastFilter(boolean enabled) {
-            log("setFallbackMulticastFilter(" + enabled + ")");
-            try {
-                mCallback.setFallbackMulticastFilter(enabled);
-            } catch (RemoteException e) {
-                log("Failed to call setFallbackMulticastFilter", e);
-            }
-        }
-
-        public void setNeighborDiscoveryOffload(boolean enable) {
-            log("setNeighborDiscoveryOffload(" + enable + ")");
-            try {
-                mCallback.setNeighborDiscoveryOffload(enable);
-            } catch (RemoteException e) {
-                log("Failed to call setNeighborDiscoveryOffload", e);
-            }
-        }
-    }
-
-    public static final String DUMP_ARG_CONFIRM = "confirm";
-
-    // Below constants are picked up by MessageUtils and exempt from ProGuard optimization.
-    private static final int CMD_TERMINATE_AFTER_STOP             = 1;
-    private static final int CMD_STOP                             = 2;
-    private static final int CMD_START                            = 3;
-    private static final int CMD_CONFIRM                          = 4;
-    private static final int EVENT_PRE_DHCP_ACTION_COMPLETE       = 5;
-    // Triggered by NetlinkTracker to communicate netlink events.
-    private static final int EVENT_NETLINK_LINKPROPERTIES_CHANGED = 6;
-    private static final int CMD_UPDATE_TCP_BUFFER_SIZES          = 7;
-    private static final int CMD_UPDATE_HTTP_PROXY                = 8;
-    private static final int CMD_SET_MULTICAST_FILTER             = 9;
-    private static final int EVENT_PROVISIONING_TIMEOUT           = 10;
-    private static final int EVENT_DHCPACTION_TIMEOUT             = 11;
-    private static final int EVENT_READ_PACKET_FILTER_COMPLETE    = 12;
-    private static final int CMD_ADD_KEEPALIVE_PACKET_FILTER_TO_APF = 13;
-    private static final int CMD_REMOVE_KEEPALIVE_PACKET_FILTER_FROM_APF = 14;
-    private static final int CMD_UPDATE_L2KEY_GROUPHINT = 15;
-
-    // Internal commands to use instead of trying to call transitionTo() inside
-    // a given State's enter() method. Calling transitionTo() from enter/exit
-    // encounters a Log.wtf() that can cause trouble on eng builds.
-    private static final int CMD_JUMP_STARTED_TO_RUNNING          = 100;
-    private static final int CMD_JUMP_RUNNING_TO_STOPPING         = 101;
-    private static final int CMD_JUMP_STOPPING_TO_STOPPED         = 102;
-
-    // IpClient shares a handler with DhcpClient: commands must not overlap
-    public static final int DHCPCLIENT_CMD_BASE = 1000;
-
-    private static final int MAX_LOG_RECORDS = 500;
-    private static final int MAX_PACKET_RECORDS = 100;
-
-    private static final boolean NO_CALLBACKS = false;
-    private static final boolean SEND_CALLBACKS = true;
-
-    // This must match the interface prefix in clatd.c.
-    // TODO: Revert this hack once IpClient and Nat464Xlat work in concert.
-    private static final String CLAT_PREFIX = "v4-";
-
-    private static final int IMMEDIATE_FAILURE_DURATION = 0;
-
-    private static final int PROV_CHANGE_STILL_NOT_PROVISIONED = 1;
-    private static final int PROV_CHANGE_LOST_PROVISIONING = 2;
-    private static final int PROV_CHANGE_GAINED_PROVISIONING = 3;
-    private static final int PROV_CHANGE_STILL_PROVISIONED = 4;
-
-    private final State mStoppedState = new StoppedState();
-    private final State mStoppingState = new StoppingState();
-    private final State mStartedState = new StartedState();
-    private final State mRunningState = new RunningState();
-
-    private final String mTag;
-    private final Context mContext;
-    private final String mInterfaceName;
-    private final String mClatInterfaceName;
-    @VisibleForTesting
-    protected final IpClientCallbacksWrapper mCallback;
-    private final Dependencies mDependencies;
-    private final CountDownLatch mShutdownLatch;
-    private final ConnectivityManager mCm;
-    private final INetd mNetd;
-    private final NetworkObserverRegistry mObserverRegistry;
-    private final IpClientLinkObserver mLinkObserver;
-    private final WakeupMessage mProvisioningTimeoutAlarm;
-    private final WakeupMessage mDhcpActionTimeoutAlarm;
-    private final SharedLog mLog;
-    private final LocalLog mConnectivityPacketLog;
-    private final MessageHandlingLogger mMsgStateLogger;
-    private final IpConnectivityLog mMetricsLog = new IpConnectivityLog();
-    private final InterfaceController mInterfaceCtrl;
-
-    private InterfaceParams mInterfaceParams;
-
-    /**
-     * Non-final member variables accessed only from within our StateMachine.
-     */
-    private LinkProperties mLinkProperties;
-    private android.net.shared.ProvisioningConfiguration mConfiguration;
-    private IpReachabilityMonitor mIpReachabilityMonitor;
-    private DhcpClient mDhcpClient;
-    private DhcpResults mDhcpResults;
-    private String mTcpBufferSizes;
-    private ProxyInfo mHttpProxy;
-    private ApfFilter mApfFilter;
-    private String mL2Key; // The L2 key for this network, for writing into the memory store
-    private String mGroupHint; // The group hint for this network, for writing into the memory store
-    private boolean mMulticastFiltering;
-    private long mStartTimeMillis;
-
-    /**
-     * Reading the snapshot is an asynchronous operation initiated by invoking
-     * Callback.startReadPacketFilter() and completed when the WiFi Service responds with an
-     * EVENT_READ_PACKET_FILTER_COMPLETE message. The mApfDataSnapshotComplete condition variable
-     * signals when a new snapshot is ready.
-     */
-    private final ConditionVariable mApfDataSnapshotComplete = new ConditionVariable();
-
-    public static class Dependencies {
-        /**
-         * Get interface parameters for the specified interface.
-         */
-        public InterfaceParams getInterfaceParams(String ifname) {
-            return InterfaceParams.getByName(ifname);
-        }
-
-        /**
-         * Get a INetd connector.
-         */
-        public INetd getNetd(Context context) {
-            return INetd.Stub.asInterface((IBinder) context.getSystemService(Context.NETD_SERVICE));
-        }
-    }
-
-    public IpClient(Context context, String ifName, IIpClientCallbacks callback,
-            NetworkObserverRegistry observerRegistry, NetworkStackServiceManager nssManager) {
-        this(context, ifName, callback, observerRegistry, nssManager, new Dependencies());
-    }
-
-    @VisibleForTesting
-    IpClient(Context context, String ifName, IIpClientCallbacks callback,
-            NetworkObserverRegistry observerRegistry, NetworkStackServiceManager nssManager,
-            Dependencies deps) {
-        super(IpClient.class.getSimpleName() + "." + ifName);
-        Preconditions.checkNotNull(ifName);
-        Preconditions.checkNotNull(callback);
-
-        mTag = getName();
-
-        mContext = context;
-        mInterfaceName = ifName;
-        mClatInterfaceName = CLAT_PREFIX + ifName;
-        mDependencies = deps;
-        mShutdownLatch = new CountDownLatch(1);
-        mCm = mContext.getSystemService(ConnectivityManager.class);
-        mObserverRegistry = observerRegistry;
-        mIpMemoryStore =
-                new NetworkStackIpMemoryStore(context, nssManager.getIpMemoryStoreService());
-
-        sSmLogs.putIfAbsent(mInterfaceName, new SharedLog(MAX_LOG_RECORDS, mTag));
-        mLog = sSmLogs.get(mInterfaceName);
-        sPktLogs.putIfAbsent(mInterfaceName, new LocalLog(MAX_PACKET_RECORDS));
-        mConnectivityPacketLog = sPktLogs.get(mInterfaceName);
-        mMsgStateLogger = new MessageHandlingLogger();
-        mCallback = new IpClientCallbacksWrapper(callback, mLog);
-
-        // TODO: Consider creating, constructing, and passing in some kind of
-        // InterfaceController.Dependencies class.
-        mNetd = deps.getNetd(mContext);
-        mInterfaceCtrl = new InterfaceController(mInterfaceName, mNetd, mLog);
-
-        mLinkObserver = new IpClientLinkObserver(
-                mInterfaceName,
-                () -> sendMessage(EVENT_NETLINK_LINKPROPERTIES_CHANGED)) {
-            @Override
-            public void onInterfaceAdded(String iface) {
-                super.onInterfaceAdded(iface);
-                if (mClatInterfaceName.equals(iface)) {
-                    mCallback.setNeighborDiscoveryOffload(false);
-                } else if (!mInterfaceName.equals(iface)) {
-                    return;
-                }
-
-                final String msg = "interfaceAdded(" + iface + ")";
-                logMsg(msg);
-            }
-
-            @Override
-            public void onInterfaceRemoved(String iface) {
-                super.onInterfaceRemoved(iface);
-                // TODO: Also observe mInterfaceName going down and take some
-                // kind of appropriate action.
-                if (mClatInterfaceName.equals(iface)) {
-                    // TODO: consider sending a message to the IpClient main
-                    // StateMachine thread, in case "NDO enabled" state becomes
-                    // tied to more things that 464xlat operation.
-                    mCallback.setNeighborDiscoveryOffload(true);
-                } else if (!mInterfaceName.equals(iface)) {
-                    return;
-                }
-
-                final String msg = "interfaceRemoved(" + iface + ")";
-                logMsg(msg);
-            }
-
-            private void logMsg(String msg) {
-                Log.d(mTag, msg);
-                getHandler().post(() -> mLog.log("OBSERVED " + msg));
-            }
-        };
-
-        mLinkProperties = new LinkProperties();
-        mLinkProperties.setInterfaceName(mInterfaceName);
-
-        mProvisioningTimeoutAlarm = new WakeupMessage(mContext, getHandler(),
-                mTag + ".EVENT_PROVISIONING_TIMEOUT", EVENT_PROVISIONING_TIMEOUT);
-        mDhcpActionTimeoutAlarm = new WakeupMessage(mContext, getHandler(),
-                mTag + ".EVENT_DHCPACTION_TIMEOUT", EVENT_DHCPACTION_TIMEOUT);
-
-        // Anything the StateMachine may access must have been instantiated
-        // before this point.
-        configureAndStartStateMachine();
-
-        // Anything that may send messages to the StateMachine must only be
-        // configured to do so after the StateMachine has started (above).
-        startStateMachineUpdaters();
-    }
-
-    /**
-     * Make a IIpClient connector to communicate with this IpClient.
-     */
-    public IIpClient makeConnector() {
-        return new IpClientConnector();
-    }
-
-    class IpClientConnector extends IIpClient.Stub {
-        @Override
-        public void completedPreDhcpAction() {
-            checkNetworkStackCallingPermission();
-            IpClient.this.completedPreDhcpAction();
-        }
-        @Override
-        public void confirmConfiguration() {
-            checkNetworkStackCallingPermission();
-            IpClient.this.confirmConfiguration();
-        }
-        @Override
-        public void readPacketFilterComplete(byte[] data) {
-            checkNetworkStackCallingPermission();
-            IpClient.this.readPacketFilterComplete(data);
-        }
-        @Override
-        public void shutdown() {
-            checkNetworkStackCallingPermission();
-            IpClient.this.shutdown();
-        }
-        @Override
-        public void startProvisioning(ProvisioningConfigurationParcelable req) {
-            checkNetworkStackCallingPermission();
-            IpClient.this.startProvisioning(ProvisioningConfiguration.fromStableParcelable(req));
-        }
-        @Override
-        public void stop() {
-            checkNetworkStackCallingPermission();
-            IpClient.this.stop();
-        }
-        @Override
-        public void setL2KeyAndGroupHint(String l2Key, String groupHint) {
-            checkNetworkStackCallingPermission();
-            IpClient.this.setL2KeyAndGroupHint(l2Key, groupHint);
-        }
-        @Override
-        public void setTcpBufferSizes(String tcpBufferSizes) {
-            checkNetworkStackCallingPermission();
-            IpClient.this.setTcpBufferSizes(tcpBufferSizes);
-        }
-        @Override
-        public void setHttpProxy(ProxyInfo proxyInfo) {
-            checkNetworkStackCallingPermission();
-            IpClient.this.setHttpProxy(proxyInfo);
-        }
-        @Override
-        public void setMulticastFilter(boolean enabled) {
-            checkNetworkStackCallingPermission();
-            IpClient.this.setMulticastFilter(enabled);
-        }
-        @Override
-        public void addKeepalivePacketFilter(int slot, TcpKeepalivePacketDataParcelable pkt) {
-            checkNetworkStackCallingPermission();
-            IpClient.this.addKeepalivePacketFilter(slot, pkt);
-        }
-        @Override
-        public void addNattKeepalivePacketFilter(int slot, NattKeepalivePacketDataParcelable pkt) {
-            checkNetworkStackCallingPermission();
-            IpClient.this.addNattKeepalivePacketFilter(slot, pkt);
-        }
-        @Override
-        public void removeKeepalivePacketFilter(int slot) {
-            checkNetworkStackCallingPermission();
-            IpClient.this.removeKeepalivePacketFilter(slot);
-        }
-
-        @Override
-        public int getInterfaceVersion() {
-            return this.VERSION;
-        }
-    }
-
-    public String getInterfaceName() {
-        return mInterfaceName;
-    }
-
-    private void configureAndStartStateMachine() {
-        // CHECKSTYLE:OFF IndentationCheck
-        addState(mStoppedState);
-        addState(mStartedState);
-            addState(mRunningState, mStartedState);
-        addState(mStoppingState);
-        // CHECKSTYLE:ON IndentationCheck
-
-        setInitialState(mStoppedState);
-
-        super.start();
-    }
-
-    private void startStateMachineUpdaters() {
-        mObserverRegistry.registerObserverForNonblockingCallback(mLinkObserver);
-    }
-
-    private void stopStateMachineUpdaters() {
-        mObserverRegistry.unregisterObserver(mLinkObserver);
-    }
-
-    @Override
-    protected void onQuitting() {
-        mCallback.onQuit();
-        mShutdownLatch.countDown();
-    }
-
-    /**
-     * Shut down this IpClient instance altogether.
-     */
-    public void shutdown() {
-        stop();
-        sendMessage(CMD_TERMINATE_AFTER_STOP);
-    }
-
-    /**
-     * Start provisioning with the provided parameters.
-     */
-    public void startProvisioning(ProvisioningConfiguration req) {
-        if (!req.isValid()) {
-            doImmediateProvisioningFailure(IpManagerEvent.ERROR_INVALID_PROVISIONING);
-            return;
-        }
-
-        mInterfaceParams = mDependencies.getInterfaceParams(mInterfaceName);
-        if (mInterfaceParams == null) {
-            logError("Failed to find InterfaceParams for " + mInterfaceName);
-            doImmediateProvisioningFailure(IpManagerEvent.ERROR_INTERFACE_NOT_FOUND);
-            return;
-        }
-
-        mCallback.setNeighborDiscoveryOffload(true);
-        sendMessage(CMD_START, new android.net.shared.ProvisioningConfiguration(req));
-    }
-
-    /**
-     * Stop this IpClient.
-     *
-     * <p>This does not shut down the StateMachine itself, which is handled by {@link #shutdown()}.
-     */
-    public void stop() {
-        sendMessage(CMD_STOP);
-    }
-
-    /**
-     * Confirm the provisioning configuration.
-     */
-    public void confirmConfiguration() {
-        sendMessage(CMD_CONFIRM);
-    }
-
-    /**
-     * For clients using {@link ProvisioningConfiguration.Builder#withPreDhcpAction()}, must be
-     * called after {@link IIpClientCallbacks#onPreDhcpAction} to indicate that DHCP is clear to
-     * proceed.
-     */
-    public void completedPreDhcpAction() {
-        sendMessage(EVENT_PRE_DHCP_ACTION_COMPLETE);
-    }
-
-    /**
-     * Indicate that packet filter read is complete.
-     */
-    public void readPacketFilterComplete(byte[] data) {
-        sendMessage(EVENT_READ_PACKET_FILTER_COMPLETE, data);
-    }
-
-    /**
-     * Set the TCP buffer sizes to use.
-     *
-     * This may be called, repeatedly, at any time before or after a call to
-     * #startProvisioning(). The setting is cleared upon calling #stop().
-     */
-    public void setTcpBufferSizes(String tcpBufferSizes) {
-        sendMessage(CMD_UPDATE_TCP_BUFFER_SIZES, tcpBufferSizes);
-    }
-
-    /**
-     * Set the L2 key and group hint for storing info into the memory store.
-     */
-    public void setL2KeyAndGroupHint(String l2Key, String groupHint) {
-        sendMessage(CMD_UPDATE_L2KEY_GROUPHINT, new Pair<>(l2Key, groupHint));
-    }
-
-    /**
-     * Set the HTTP Proxy configuration to use.
-     *
-     * This may be called, repeatedly, at any time before or after a call to
-     * #startProvisioning(). The setting is cleared upon calling #stop().
-     */
-    public void setHttpProxy(ProxyInfo proxyInfo) {
-        sendMessage(CMD_UPDATE_HTTP_PROXY, proxyInfo);
-    }
-
-    /**
-     * Enable or disable the multicast filter.  Attempts to use APF to accomplish the filtering,
-     * if not, Callback.setFallbackMulticastFilter() is called.
-     */
-    public void setMulticastFilter(boolean enabled) {
-        sendMessage(CMD_SET_MULTICAST_FILTER, enabled);
-    }
-
-    /**
-     * Called by WifiStateMachine to add TCP keepalive packet filter before setting up
-     * keepalive offload.
-     */
-    public void addKeepalivePacketFilter(int slot, @NonNull TcpKeepalivePacketDataParcelable pkt) {
-        sendMessage(CMD_ADD_KEEPALIVE_PACKET_FILTER_TO_APF, slot, 0 /* Unused */, pkt);
-    }
-
-    /**
-     *  Called by WifiStateMachine to add NATT keepalive packet filter before setting up
-     *  keepalive offload.
-     */
-    public void addNattKeepalivePacketFilter(int slot,
-            @NonNull NattKeepalivePacketDataParcelable pkt) {
-        sendMessage(CMD_ADD_KEEPALIVE_PACKET_FILTER_TO_APF, slot, 0 /* Unused */ , pkt);
-    }
-
-    /**
-     * Called by WifiStateMachine to remove keepalive packet filter after stopping keepalive
-     * offload.
-     */
-    public void removeKeepalivePacketFilter(int slot) {
-        sendMessage(CMD_REMOVE_KEEPALIVE_PACKET_FILTER_FROM_APF, slot, 0 /* Unused */);
-    }
-
-    /**
-     * Dump logs of this IpClient.
-     */
-    public void dump(FileDescriptor fd, PrintWriter writer, String[] args) {
-        if (args != null && args.length > 0 && DUMP_ARG_CONFIRM.equals(args[0])) {
-            // Execute confirmConfiguration() and take no further action.
-            confirmConfiguration();
-            return;
-        }
-
-        // Thread-unsafe access to mApfFilter but just used for debugging.
-        final ApfFilter apfFilter = mApfFilter;
-        final android.net.shared.ProvisioningConfiguration provisioningConfig = mConfiguration;
-        final ApfCapabilities apfCapabilities = (provisioningConfig != null)
-                ? provisioningConfig.mApfCapabilities : null;
-
-        IndentingPrintWriter pw = new IndentingPrintWriter(writer, "  ");
-        pw.println(mTag + " APF dump:");
-        pw.increaseIndent();
-        if (apfFilter != null) {
-            if (apfCapabilities.hasDataAccess()) {
-                // Request a new snapshot, then wait for it.
-                mApfDataSnapshotComplete.close();
-                mCallback.startReadPacketFilter();
-                if (!mApfDataSnapshotComplete.block(1000)) {
-                    pw.print("TIMEOUT: DUMPING STALE APF SNAPSHOT");
-                }
-            }
-            apfFilter.dump(pw);
-
-        } else {
-            pw.print("No active ApfFilter; ");
-            if (provisioningConfig == null) {
-                pw.println("IpClient not yet started.");
-            } else if (apfCapabilities == null || apfCapabilities.apfVersionSupported == 0) {
-                pw.println("Hardware does not support APF.");
-            } else {
-                pw.println("ApfFilter not yet started, APF capabilities: " + apfCapabilities);
-            }
-        }
-        pw.decreaseIndent();
-        pw.println();
-        pw.println(mTag + " current ProvisioningConfiguration:");
-        pw.increaseIndent();
-        pw.println(Objects.toString(provisioningConfig, "N/A"));
-        pw.decreaseIndent();
-
-        final IpReachabilityMonitor iprm = mIpReachabilityMonitor;
-        if (iprm != null) {
-            pw.println();
-            pw.println(mTag + " current IpReachabilityMonitor state:");
-            pw.increaseIndent();
-            iprm.dump(pw);
-            pw.decreaseIndent();
-        }
-
-        pw.println();
-        pw.println(mTag + " StateMachine dump:");
-        pw.increaseIndent();
-        mLog.dump(fd, pw, args);
-        pw.decreaseIndent();
-
-        pw.println();
-        pw.println(mTag + " connectivity packet log:");
-        pw.println();
-        pw.println("Debug with python and scapy via:");
-        pw.println("shell$ python");
-        pw.println(">>> from scapy import all as scapy");
-        pw.println(">>> scapy.Ether(\"<paste_hex_string>\".decode(\"hex\")).show2()");
-        pw.println();
-
-        pw.increaseIndent();
-        mConnectivityPacketLog.readOnlyLocalLog().dump(fd, pw, args);
-        pw.decreaseIndent();
-    }
-
-
-    /**
-     * Internals.
-     */
-
-    @Override
-    protected String getWhatToString(int what) {
-        return sWhatToString.get(what, "UNKNOWN: " + Integer.toString(what));
-    }
-
-    @Override
-    protected String getLogRecString(Message msg) {
-        final String logLine = String.format(
-                "%s/%d %d %d %s [%s]",
-                mInterfaceName, (mInterfaceParams == null) ? -1 : mInterfaceParams.index,
-                msg.arg1, msg.arg2, Objects.toString(msg.obj), mMsgStateLogger);
-
-        final String richerLogLine = getWhatToString(msg.what) + " " + logLine;
-        mLog.log(richerLogLine);
-        if (DBG) {
-            Log.d(mTag, richerLogLine);
-        }
-
-        mMsgStateLogger.reset();
-        return logLine;
-    }
-
-    @Override
-    protected boolean recordLogRec(Message msg) {
-        // Don't log EVENT_NETLINK_LINKPROPERTIES_CHANGED. They can be noisy,
-        // and we already log any LinkProperties change that results in an
-        // invocation of IpClient.Callback#onLinkPropertiesChange().
-        final boolean shouldLog = (msg.what != EVENT_NETLINK_LINKPROPERTIES_CHANGED);
-        if (!shouldLog) {
-            mMsgStateLogger.reset();
-        }
-        return shouldLog;
-    }
-
-    private void logError(String fmt, Object... args) {
-        final String msg = "ERROR " + String.format(fmt, args);
-        Log.e(mTag, msg);
-        mLog.log(msg);
-    }
-
-    // This needs to be called with care to ensure that our LinkProperties
-    // are in sync with the actual LinkProperties of the interface. For example,
-    // we should only call this if we know for sure that there are no IP addresses
-    // assigned to the interface, etc.
-    private void resetLinkProperties() {
-        mLinkObserver.clearLinkProperties();
-        mConfiguration = null;
-        mDhcpResults = null;
-        mTcpBufferSizes = "";
-        mHttpProxy = null;
-
-        mLinkProperties = new LinkProperties();
-        mLinkProperties.setInterfaceName(mInterfaceName);
-    }
-
-    private void recordMetric(final int type) {
-        // We may record error metrics prior to starting.
-        // Map this to IMMEDIATE_FAILURE_DURATION.
-        final long duration = (mStartTimeMillis > 0)
-                ? (SystemClock.elapsedRealtime() - mStartTimeMillis)
-                : IMMEDIATE_FAILURE_DURATION;
-        mMetricsLog.log(mInterfaceName, new IpManagerEvent(type, duration));
-    }
-
-    // For now: use WifiStateMachine's historical notion of provisioned.
-    @VisibleForTesting
-    static boolean isProvisioned(LinkProperties lp, InitialConfiguration config) {
-        // For historical reasons, we should connect even if all we have is
-        // an IPv4 address and nothing else.
-        if (lp.hasIpv4Address() || lp.isProvisioned()) {
-            return true;
-        }
-        if (config == null) {
-            return false;
-        }
-
-        // When an InitialConfiguration is specified, ignore any difference with previous
-        // properties and instead check if properties observed match the desired properties.
-        return config.isProvisionedBy(lp.getLinkAddresses(), lp.getRoutes());
-    }
-
-    // TODO: Investigate folding all this into the existing static function
-    // LinkProperties.compareProvisioning() or some other single function that
-    // takes two LinkProperties objects and returns a ProvisioningChange
-    // object that is a correct and complete assessment of what changed, taking
-    // account of the asymmetries described in the comments in this function.
-    // Then switch to using it everywhere (IpReachabilityMonitor, etc.).
-    private int compareProvisioning(LinkProperties oldLp, LinkProperties newLp) {
-        int delta;
-        InitialConfiguration config = mConfiguration != null ? mConfiguration.mInitialConfig : null;
-        final boolean wasProvisioned = isProvisioned(oldLp, config);
-        final boolean isProvisioned = isProvisioned(newLp, config);
-
-        if (!wasProvisioned && isProvisioned) {
-            delta = PROV_CHANGE_GAINED_PROVISIONING;
-        } else if (wasProvisioned && isProvisioned) {
-            delta = PROV_CHANGE_STILL_PROVISIONED;
-        } else if (!wasProvisioned && !isProvisioned) {
-            delta = PROV_CHANGE_STILL_NOT_PROVISIONED;
-        } else {
-            // (wasProvisioned && !isProvisioned)
-            //
-            // Note that this is true even if we lose a configuration element
-            // (e.g., a default gateway) that would not be required to advance
-            // into provisioned state. This is intended: if we have a default
-            // router and we lose it, that's a sure sign of a problem, but if
-            // we connect to a network with no IPv4 DNS servers, we consider
-            // that to be a network without DNS servers and connect anyway.
-            //
-            // See the comment below.
-            delta = PROV_CHANGE_LOST_PROVISIONING;
-        }
-
-        final boolean lostIPv6 = oldLp.isIpv6Provisioned() && !newLp.isIpv6Provisioned();
-        final boolean lostIPv4Address = oldLp.hasIpv4Address() && !newLp.hasIpv4Address();
-        final boolean lostIPv6Router = oldLp.hasIpv6DefaultRoute() && !newLp.hasIpv6DefaultRoute();
-
-        // If bad wifi avoidance is disabled, then ignore IPv6 loss of
-        // provisioning. Otherwise, when a hotspot that loses Internet
-        // access sends out a 0-lifetime RA to its clients, the clients
-        // will disconnect and then reconnect, avoiding the bad hotspot,
-        // instead of getting stuck on the bad hotspot. http://b/31827713 .
-        //
-        // This is incorrect because if the hotspot then regains Internet
-        // access with a different prefix, TCP connections on the
-        // deprecated addresses will remain stuck.
-        //
-        // Note that we can still be disconnected by IpReachabilityMonitor
-        // if the IPv6 default gateway (but not the IPv6 DNS servers; see
-        // accompanying code in IpReachabilityMonitor) is unreachable.
-        final boolean ignoreIPv6ProvisioningLoss =
-                mConfiguration != null && mConfiguration.mUsingMultinetworkPolicyTracker
-                && mCm.shouldAvoidBadWifi();
-
-        // Additionally:
-        //
-        // Partial configurations (e.g., only an IPv4 address with no DNS
-        // servers and no default route) are accepted as long as DHCPv4
-        // succeeds. On such a network, isProvisioned() will always return
-        // false, because the configuration is not complete, but we want to
-        // connect anyway. It might be a disconnected network such as a
-        // Chromecast or a wireless printer, for example.
-        //
-        // Because on such a network isProvisioned() will always return false,
-        // delta will never be LOST_PROVISIONING. So check for loss of
-        // provisioning here too.
-        if (lostIPv4Address || (lostIPv6 && !ignoreIPv6ProvisioningLoss)) {
-            delta = PROV_CHANGE_LOST_PROVISIONING;
-        }
-
-        // Additionally:
-        //
-        // If the previous link properties had a global IPv6 address and an
-        // IPv6 default route then also consider the loss of that default route
-        // to be a loss of provisioning. See b/27962810.
-        if (oldLp.hasGlobalIpv6Address() && (lostIPv6Router && !ignoreIPv6ProvisioningLoss)) {
-            delta = PROV_CHANGE_LOST_PROVISIONING;
-        }
-
-        return delta;
-    }
-
-    private void dispatchCallback(int delta, LinkProperties newLp) {
-        switch (delta) {
-            case PROV_CHANGE_GAINED_PROVISIONING:
-                if (DBG) {
-                    Log.d(mTag, "onProvisioningSuccess()");
-                }
-                recordMetric(IpManagerEvent.PROVISIONING_OK);
-                mCallback.onProvisioningSuccess(newLp);
-                break;
-
-            case PROV_CHANGE_LOST_PROVISIONING:
-                if (DBG) {
-                    Log.d(mTag, "onProvisioningFailure()");
-                }
-                recordMetric(IpManagerEvent.PROVISIONING_FAIL);
-                mCallback.onProvisioningFailure(newLp);
-                break;
-
-            default:
-                if (DBG) {
-                    Log.d(mTag, "onLinkPropertiesChange()");
-                }
-                mCallback.onLinkPropertiesChange(newLp);
-                break;
-        }
-    }
-
-    // Updates all IpClient-related state concerned with LinkProperties.
-    // Returns a ProvisioningChange for possibly notifying other interested
-    // parties that are not fronted by IpClient.
-    private int setLinkProperties(LinkProperties newLp) {
-        if (mApfFilter != null) {
-            mApfFilter.setLinkProperties(newLp);
-        }
-        if (mIpReachabilityMonitor != null) {
-            mIpReachabilityMonitor.updateLinkProperties(newLp);
-        }
-
-        int delta = compareProvisioning(mLinkProperties, newLp);
-        mLinkProperties = new LinkProperties(newLp);
-
-        if (delta == PROV_CHANGE_GAINED_PROVISIONING) {
-            // TODO: Add a proper ProvisionedState and cancel the alarm in
-            // its enter() method.
-            mProvisioningTimeoutAlarm.cancel();
-        }
-
-        return delta;
-    }
-
-    private LinkProperties assembleLinkProperties() {
-        // [1] Create a new LinkProperties object to populate.
-        LinkProperties newLp = new LinkProperties();
-        newLp.setInterfaceName(mInterfaceName);
-
-        // [2] Pull in data from netlink:
-        //         - IPv4 addresses
-        //         - IPv6 addresses
-        //         - IPv6 routes
-        //         - IPv6 DNS servers
-        //
-        // N.B.: this is fundamentally race-prone and should be fixed by
-        // changing IpClientLinkObserver from a hybrid edge/level model to an
-        // edge-only model, or by giving IpClient its own netlink socket(s)
-        // so as to track all required information directly.
-        LinkProperties netlinkLinkProperties = mLinkObserver.getLinkProperties();
-        newLp.setLinkAddresses(netlinkLinkProperties.getLinkAddresses());
-        for (RouteInfo route : netlinkLinkProperties.getRoutes()) {
-            newLp.addRoute(route);
-        }
-        addAllReachableDnsServers(newLp, netlinkLinkProperties.getDnsServers());
-
-        // [3] Add in data from DHCPv4, if available.
-        //
-        // mDhcpResults is never shared with any other owner so we don't have
-        // to worry about concurrent modification.
-        if (mDhcpResults != null) {
-            final List<RouteInfo> routes =
-                    mDhcpResults.toStaticIpConfiguration().getRoutes(mInterfaceName);
-            for (RouteInfo route : routes) {
-                newLp.addRoute(route);
-            }
-            addAllReachableDnsServers(newLp, mDhcpResults.dnsServers);
-            newLp.setDomains(mDhcpResults.domains);
-
-            if (mDhcpResults.mtu != 0) {
-                newLp.setMtu(mDhcpResults.mtu);
-            }
-        }
-
-        // [4] Add in TCP buffer sizes and HTTP Proxy config, if available.
-        if (!TextUtils.isEmpty(mTcpBufferSizes)) {
-            newLp.setTcpBufferSizes(mTcpBufferSizes);
-        }
-        if (mHttpProxy != null) {
-            newLp.setHttpProxy(mHttpProxy);
-        }
-
-        // [5] Add data from InitialConfiguration
-        if (mConfiguration != null && mConfiguration.mInitialConfig != null) {
-            InitialConfiguration config = mConfiguration.mInitialConfig;
-            // Add InitialConfiguration routes and dns server addresses once all addresses
-            // specified in the InitialConfiguration have been observed with Netlink.
-            if (config.isProvisionedBy(newLp.getLinkAddresses(), null)) {
-                for (IpPrefix prefix : config.directlyConnectedRoutes) {
-                    newLp.addRoute(new RouteInfo(prefix, null, mInterfaceName, RTN_UNICAST));
-                }
-            }
-            addAllReachableDnsServers(newLp, config.dnsServers);
-        }
-        final LinkProperties oldLp = mLinkProperties;
-        if (DBG) {
-            Log.d(mTag, String.format("Netlink-seen LPs: %s, new LPs: %s; old LPs: %s",
-                    netlinkLinkProperties, newLp, oldLp));
-        }
-
-        // TODO: also learn via netlink routes specified by an InitialConfiguration and specified
-        // from a static IP v4 config instead of manually patching them in in steps [3] and [5].
-        return newLp;
-    }
-
-    private static void addAllReachableDnsServers(
-            LinkProperties lp, Iterable<InetAddress> dnses) {
-        // TODO: Investigate deleting this reachability check.  We should be
-        // able to pass everything down to netd and let netd do evaluation
-        // and RFC6724-style sorting.
-        for (InetAddress dns : dnses) {
-            if (!dns.isAnyLocalAddress() && lp.isReachable(dns)) {
-                lp.addDnsServer(dns);
-            }
-        }
-    }
-
-    // Returns false if we have lost provisioning, true otherwise.
-    private boolean handleLinkPropertiesUpdate(boolean sendCallbacks) {
-        final LinkProperties newLp = assembleLinkProperties();
-        if (Objects.equals(newLp, mLinkProperties)) {
-            return true;
-        }
-        final int delta = setLinkProperties(newLp);
-        // Most of the attributes stored in the memory store are deduced from
-        // the link properties, therefore when the properties update the memory
-        // store record should be updated too.
-        maybeSaveNetworkToIpMemoryStore();
-        if (sendCallbacks) {
-            dispatchCallback(delta, newLp);
-        }
-        return (delta != PROV_CHANGE_LOST_PROVISIONING);
-    }
-
-    private void handleIPv4Success(DhcpResults dhcpResults) {
-        mDhcpResults = new DhcpResults(dhcpResults);
-        final LinkProperties newLp = assembleLinkProperties();
-        final int delta = setLinkProperties(newLp);
-
-        if (DBG) {
-            Log.d(mTag, "onNewDhcpResults(" + Objects.toString(dhcpResults) + ")");
-        }
-        mCallback.onNewDhcpResults(dhcpResults);
-        maybeSaveNetworkToIpMemoryStore();
-        dispatchCallback(delta, newLp);
-    }
-
-    private void handleIPv4Failure() {
-        // TODO: Investigate deleting this clearIPv4Address() call.
-        //
-        // DhcpClient will send us CMD_CLEAR_LINKADDRESS in all circumstances
-        // that could trigger a call to this function. If we missed handling
-        // that message in StartedState for some reason we would still clear
-        // any addresses upon entry to StoppedState.
-        mInterfaceCtrl.clearIPv4Address();
-        mDhcpResults = null;
-        if (DBG) {
-            Log.d(mTag, "onNewDhcpResults(null)");
-        }
-        mCallback.onNewDhcpResults(null);
-
-        handleProvisioningFailure();
-    }
-
-    private void handleProvisioningFailure() {
-        final LinkProperties newLp = assembleLinkProperties();
-        int delta = setLinkProperties(newLp);
-        // If we've gotten here and we're still not provisioned treat that as
-        // a total loss of provisioning.
-        //
-        // Either (a) static IP configuration failed or (b) DHCPv4 failed AND
-        // there was no usable IPv6 obtained before a non-zero provisioning
-        // timeout expired.
-        //
-        // Regardless: GAME OVER.
-        if (delta == PROV_CHANGE_STILL_NOT_PROVISIONED) {
-            delta = PROV_CHANGE_LOST_PROVISIONING;
-        }
-
-        dispatchCallback(delta, newLp);
-        if (delta == PROV_CHANGE_LOST_PROVISIONING) {
-            transitionTo(mStoppingState);
-        }
-    }
-
-    private void doImmediateProvisioningFailure(int failureType) {
-        logError("onProvisioningFailure(): %s", failureType);
-        recordMetric(failureType);
-        mCallback.onProvisioningFailure(new LinkProperties(mLinkProperties));
-    }
-
-    private boolean startIPv4() {
-        // If we have a StaticIpConfiguration attempt to apply it and
-        // handle the result accordingly.
-        if (mConfiguration.mStaticIpConfig != null) {
-            if (mInterfaceCtrl.setIPv4Address(mConfiguration.mStaticIpConfig.getIpAddress())) {
-                handleIPv4Success(new DhcpResults(mConfiguration.mStaticIpConfig));
-            } else {
-                return false;
-            }
-        } else {
-            // Start DHCPv4.
-            mDhcpClient = DhcpClient.makeDhcpClient(mContext, IpClient.this, mInterfaceParams);
-            mDhcpClient.registerForPreDhcpNotification();
-            mDhcpClient.sendMessage(DhcpClient.CMD_START_DHCP);
-        }
-
-        return true;
-    }
-
-    private boolean startIPv6() {
-        return mInterfaceCtrl.setIPv6PrivacyExtensions(true)
-                && mInterfaceCtrl.setIPv6AddrGenModeIfSupported(mConfiguration.mIPv6AddrGenMode)
-                && mInterfaceCtrl.enableIPv6();
-    }
-
-    private boolean applyInitialConfig(InitialConfiguration config) {
-        // TODO: also support specifying a static IPv4 configuration in InitialConfiguration.
-        for (LinkAddress addr : findAll(config.ipAddresses, LinkAddress::isIpv6)) {
-            if (!mInterfaceCtrl.addAddress(addr)) return false;
-        }
-
-        return true;
-    }
-
-    private boolean startIpReachabilityMonitor() {
-        try {
-            // TODO: Fetch these parameters from settings, and install a
-            // settings observer to watch for update and re-program these
-            // parameters (Q: is this level of dynamic updatability really
-            // necessary or does reading from settings at startup suffice?).
-            final int numSolicits = 5;
-            final int interSolicitIntervalMs = 750;
-            setNeighborParameters(mNetd, mInterfaceName, numSolicits, interSolicitIntervalMs);
-        } catch (Exception e) {
-            mLog.e("Failed to adjust neighbor parameters", e);
-            // Carry on using the system defaults (currently: 3, 1000);
-        }
-
-        try {
-            mIpReachabilityMonitor = new IpReachabilityMonitor(
-                    mContext,
-                    mInterfaceParams,
-                    getHandler(),
-                    mLog,
-                    new IpReachabilityMonitor.Callback() {
-                        @Override
-                        public void notifyLost(InetAddress ip, String logMsg) {
-                            mCallback.onReachabilityLost(logMsg);
-                        }
-                    },
-                    mConfiguration.mUsingMultinetworkPolicyTracker);
-        } catch (IllegalArgumentException iae) {
-            // Failed to start IpReachabilityMonitor. Log it and call
-            // onProvisioningFailure() immediately.
-            //
-            // See http://b/31038971.
-            logError("IpReachabilityMonitor failure: %s", iae);
-            mIpReachabilityMonitor = null;
-        }
-
-        return (mIpReachabilityMonitor != null);
-    }
-
-    private void stopAllIP() {
-        // We don't need to worry about routes, just addresses, because:
-        //     - disableIpv6() will clear autoconf IPv6 routes as well, and
-        //     - we don't get IPv4 routes from netlink
-        // so we neither react to nor need to wait for changes in either.
-
-        mInterfaceCtrl.disableIPv6();
-        mInterfaceCtrl.clearAllAddresses();
-    }
-
-    private void maybeSaveNetworkToIpMemoryStore() {
-        // TODO : implement this
-    }
-
-    class StoppedState extends State {
-        @Override
-        public void enter() {
-            stopAllIP();
-
-            resetLinkProperties();
-            if (mStartTimeMillis > 0) {
-                // Completed a life-cycle; send a final empty LinkProperties
-                // (cleared in resetLinkProperties() above) and record an event.
-                mCallback.onLinkPropertiesChange(new LinkProperties(mLinkProperties));
-                recordMetric(IpManagerEvent.COMPLETE_LIFECYCLE);
-                mStartTimeMillis = 0;
-            }
-        }
-
-        @Override
-        public boolean processMessage(Message msg) {
-            switch (msg.what) {
-                case CMD_TERMINATE_AFTER_STOP:
-                    stopStateMachineUpdaters();
-                    quit();
-                    break;
-
-                case CMD_STOP:
-                    break;
-
-                case CMD_START:
-                    mConfiguration = (android.net.shared.ProvisioningConfiguration) msg.obj;
-                    transitionTo(mStartedState);
-                    break;
-
-                case EVENT_NETLINK_LINKPROPERTIES_CHANGED:
-                    handleLinkPropertiesUpdate(NO_CALLBACKS);
-                    break;
-
-                case CMD_UPDATE_TCP_BUFFER_SIZES:
-                    mTcpBufferSizes = (String) msg.obj;
-                    handleLinkPropertiesUpdate(NO_CALLBACKS);
-                    break;
-
-                case CMD_UPDATE_HTTP_PROXY:
-                    mHttpProxy = (ProxyInfo) msg.obj;
-                    handleLinkPropertiesUpdate(NO_CALLBACKS);
-                    break;
-
-                case CMD_UPDATE_L2KEY_GROUPHINT: {
-                    final Pair<String, String> args = (Pair<String, String>) msg.obj;
-                    mL2Key = args.first;
-                    mGroupHint = args.second;
-                    break;
-                }
-
-                case CMD_SET_MULTICAST_FILTER:
-                    mMulticastFiltering = (boolean) msg.obj;
-                    break;
-
-                case DhcpClient.CMD_ON_QUIT:
-                    // Everything is already stopped.
-                    logError("Unexpected CMD_ON_QUIT (already stopped).");
-                    break;
-
-                default:
-                    return NOT_HANDLED;
-            }
-
-            mMsgStateLogger.handled(this, getCurrentState());
-            return HANDLED;
-        }
-    }
-
-    class StoppingState extends State {
-        @Override
-        public void enter() {
-            if (mDhcpClient == null) {
-                // There's no DHCPv4 for which to wait; proceed to stopped.
-                deferMessage(obtainMessage(CMD_JUMP_STOPPING_TO_STOPPED));
-            }
-        }
-
-        @Override
-        public boolean processMessage(Message msg) {
-            switch (msg.what) {
-                case CMD_JUMP_STOPPING_TO_STOPPED:
-                    transitionTo(mStoppedState);
-                    break;
-
-                case CMD_STOP:
-                    break;
-
-                case DhcpClient.CMD_CLEAR_LINKADDRESS:
-                    mInterfaceCtrl.clearIPv4Address();
-                    break;
-
-                case DhcpClient.CMD_ON_QUIT:
-                    mDhcpClient = null;
-                    transitionTo(mStoppedState);
-                    break;
-
-                default:
-                    deferMessage(msg);
-            }
-
-            mMsgStateLogger.handled(this, getCurrentState());
-            return HANDLED;
-        }
-    }
-
-    class StartedState extends State {
-        @Override
-        public void enter() {
-            mStartTimeMillis = SystemClock.elapsedRealtime();
-
-            if (mConfiguration.mProvisioningTimeoutMs > 0) {
-                final long alarmTime = SystemClock.elapsedRealtime()
-                        + mConfiguration.mProvisioningTimeoutMs;
-                mProvisioningTimeoutAlarm.schedule(alarmTime);
-            }
-
-            if (readyToProceed()) {
-                deferMessage(obtainMessage(CMD_JUMP_STARTED_TO_RUNNING));
-            } else {
-                // Clear all IPv4 and IPv6 before proceeding to RunningState.
-                // Clean up any leftover state from an abnormal exit from
-                // tethering or during an IpClient restart.
-                stopAllIP();
-            }
-        }
-
-        @Override
-        public void exit() {
-            mProvisioningTimeoutAlarm.cancel();
-        }
-
-        @Override
-        public boolean processMessage(Message msg) {
-            switch (msg.what) {
-                case CMD_JUMP_STARTED_TO_RUNNING:
-                    transitionTo(mRunningState);
-                    break;
-
-                case CMD_STOP:
-                    transitionTo(mStoppingState);
-                    break;
-
-                case EVENT_NETLINK_LINKPROPERTIES_CHANGED:
-                    handleLinkPropertiesUpdate(NO_CALLBACKS);
-                    if (readyToProceed()) {
-                        transitionTo(mRunningState);
-                    }
-                    break;
-
-                case CMD_UPDATE_L2KEY_GROUPHINT: {
-                    final Pair<String, String> args = (Pair<String, String>) msg.obj;
-                    mL2Key = args.first;
-                    mGroupHint = args.second;
-                    // TODO : attributes should be saved to the memory store with
-                    // these new values if they differ from the previous ones.
-                    // If the state machine is in pure StartedState, then the values to input
-                    // are not known yet and should be updated when the LinkProperties are updated.
-                    // If the state machine is in RunningState (which is a child of StartedState)
-                    // then the next NUD check should be used to store the new values to avoid
-                    // inputting current values for what may be a different L3 network.
-                    break;
-                }
-
-                case EVENT_PROVISIONING_TIMEOUT:
-                    handleProvisioningFailure();
-                    break;
-
-                default:
-                    // It's safe to process messages out of order because the
-                    // only message that can both
-                    //     a) be received at this time and
-                    //     b) affect provisioning state
-                    // is EVENT_NETLINK_LINKPROPERTIES_CHANGED (handled above).
-                    deferMessage(msg);
-            }
-
-            mMsgStateLogger.handled(this, getCurrentState());
-            return HANDLED;
-        }
-
-        private boolean readyToProceed() {
-            return (!mLinkProperties.hasIpv4Address() && !mLinkProperties.hasGlobalIpv6Address());
-        }
-    }
-
-    class RunningState extends State {
-        private ConnectivityPacketTracker mPacketTracker;
-        private boolean mDhcpActionInFlight;
-
-        @Override
-        public void enter() {
-            ApfFilter.ApfConfiguration apfConfig = new ApfFilter.ApfConfiguration();
-            apfConfig.apfCapabilities = mConfiguration.mApfCapabilities;
-            apfConfig.multicastFilter = mMulticastFiltering;
-            // Get the Configuration for ApfFilter from Context
-            apfConfig.ieee802_3Filter = ApfCapabilities.getApfDrop8023Frames();
-            apfConfig.ethTypeBlackList = ApfCapabilities.getApfEtherTypeBlackList();
-            mApfFilter = ApfFilter.maybeCreate(mContext, apfConfig, mInterfaceParams, mCallback);
-            // TODO: investigate the effects of any multicast filtering racing/interfering with the
-            // rest of this IP configuration startup.
-            if (mApfFilter == null) {
-                mCallback.setFallbackMulticastFilter(mMulticastFiltering);
-            }
-
-            mPacketTracker = createPacketTracker();
-            if (mPacketTracker != null) mPacketTracker.start(mConfiguration.mDisplayName);
-
-            if (mConfiguration.mEnableIPv6 && !startIPv6()) {
-                doImmediateProvisioningFailure(IpManagerEvent.ERROR_STARTING_IPV6);
-                enqueueJumpToStoppingState();
-                return;
-            }
-
-            if (mConfiguration.mEnableIPv4 && !startIPv4()) {
-                doImmediateProvisioningFailure(IpManagerEvent.ERROR_STARTING_IPV4);
-                enqueueJumpToStoppingState();
-                return;
-            }
-
-            final InitialConfiguration config = mConfiguration.mInitialConfig;
-            if ((config != null) && !applyInitialConfig(config)) {
-                // TODO introduce a new IpManagerEvent constant to distinguish this error case.
-                doImmediateProvisioningFailure(IpManagerEvent.ERROR_INVALID_PROVISIONING);
-                enqueueJumpToStoppingState();
-                return;
-            }
-
-            if (mConfiguration.mUsingIpReachabilityMonitor && !startIpReachabilityMonitor()) {
-                doImmediateProvisioningFailure(
-                        IpManagerEvent.ERROR_STARTING_IPREACHABILITYMONITOR);
-                enqueueJumpToStoppingState();
-                return;
-            }
-        }
-
-        @Override
-        public void exit() {
-            stopDhcpAction();
-
-            if (mIpReachabilityMonitor != null) {
-                mIpReachabilityMonitor.stop();
-                mIpReachabilityMonitor = null;
-            }
-
-            if (mDhcpClient != null) {
-                mDhcpClient.sendMessage(DhcpClient.CMD_STOP_DHCP);
-                mDhcpClient.doQuit();
-            }
-
-            if (mPacketTracker != null) {
-                mPacketTracker.stop();
-                mPacketTracker = null;
-            }
-
-            if (mApfFilter != null) {
-                mApfFilter.shutdown();
-                mApfFilter = null;
-            }
-
-            resetLinkProperties();
-        }
-
-        private void enqueueJumpToStoppingState() {
-            deferMessage(obtainMessage(CMD_JUMP_RUNNING_TO_STOPPING));
-        }
-
-        private ConnectivityPacketTracker createPacketTracker() {
-            try {
-                return new ConnectivityPacketTracker(
-                        getHandler(), mInterfaceParams, mConnectivityPacketLog);
-            } catch (IllegalArgumentException e) {
-                return null;
-            }
-        }
-
-        private void ensureDhcpAction() {
-            if (!mDhcpActionInFlight) {
-                mCallback.onPreDhcpAction();
-                mDhcpActionInFlight = true;
-                final long alarmTime = SystemClock.elapsedRealtime()
-                        + mConfiguration.mRequestedPreDhcpActionMs;
-                mDhcpActionTimeoutAlarm.schedule(alarmTime);
-            }
-        }
-
-        private void stopDhcpAction() {
-            mDhcpActionTimeoutAlarm.cancel();
-            if (mDhcpActionInFlight) {
-                mCallback.onPostDhcpAction();
-                mDhcpActionInFlight = false;
-            }
-        }
-
-        @Override
-        public boolean processMessage(Message msg) {
-            switch (msg.what) {
-                case CMD_JUMP_RUNNING_TO_STOPPING:
-                case CMD_STOP:
-                    transitionTo(mStoppingState);
-                    break;
-
-                case CMD_START:
-                    logError("ALERT: START received in StartedState. Please fix caller.");
-                    break;
-
-                case CMD_CONFIRM:
-                    // TODO: Possibly introduce a second type of confirmation
-                    // that both probes (a) on-link neighbors and (b) does
-                    // a DHCPv4 RENEW.  We used to do this on Wi-Fi framework
-                    // roams.
-                    if (mIpReachabilityMonitor != null) {
-                        mIpReachabilityMonitor.probeAll();
-                    }
-                    break;
-
-                case EVENT_PRE_DHCP_ACTION_COMPLETE:
-                    // It's possible to reach here if, for example, someone
-                    // calls completedPreDhcpAction() after provisioning with
-                    // a static IP configuration.
-                    if (mDhcpClient != null) {
-                        mDhcpClient.sendMessage(DhcpClient.CMD_PRE_DHCP_ACTION_COMPLETE);
-                    }
-                    break;
-
-                case EVENT_NETLINK_LINKPROPERTIES_CHANGED:
-                    if (!handleLinkPropertiesUpdate(SEND_CALLBACKS)) {
-                        transitionTo(mStoppingState);
-                    }
-                    break;
-
-                case CMD_UPDATE_TCP_BUFFER_SIZES:
-                    mTcpBufferSizes = (String) msg.obj;
-                    // This cannot possibly change provisioning state.
-                    handleLinkPropertiesUpdate(SEND_CALLBACKS);
-                    break;
-
-                case CMD_UPDATE_HTTP_PROXY:
-                    mHttpProxy = (ProxyInfo) msg.obj;
-                    // This cannot possibly change provisioning state.
-                    handleLinkPropertiesUpdate(SEND_CALLBACKS);
-                    break;
-
-                case CMD_SET_MULTICAST_FILTER: {
-                    mMulticastFiltering = (boolean) msg.obj;
-                    if (mApfFilter != null) {
-                        mApfFilter.setMulticastFilter(mMulticastFiltering);
-                    } else {
-                        mCallback.setFallbackMulticastFilter(mMulticastFiltering);
-                    }
-                    break;
-                }
-
-                case EVENT_READ_PACKET_FILTER_COMPLETE: {
-                    if (mApfFilter != null) {
-                        mApfFilter.setDataSnapshot((byte[]) msg.obj);
-                    }
-                    mApfDataSnapshotComplete.open();
-                    break;
-                }
-
-                case CMD_ADD_KEEPALIVE_PACKET_FILTER_TO_APF: {
-                    final int slot = msg.arg1;
-
-                    if (mApfFilter != null) {
-                        if (msg.obj instanceof NattKeepalivePacketDataParcelable) {
-                            mApfFilter.addNattKeepalivePacketFilter(slot,
-                                    (NattKeepalivePacketDataParcelable) msg.obj);
-                        } else if (msg.obj instanceof TcpKeepalivePacketDataParcelable) {
-                            mApfFilter.addTcpKeepalivePacketFilter(slot,
-                                    (TcpKeepalivePacketDataParcelable) msg.obj);
-                        }
-                    }
-                    break;
-                }
-
-                case CMD_REMOVE_KEEPALIVE_PACKET_FILTER_FROM_APF: {
-                    final int slot = msg.arg1;
-                    if (mApfFilter != null) {
-                        mApfFilter.removeKeepalivePacketFilter(slot);
-                    }
-                    break;
-                }
-
-                case EVENT_DHCPACTION_TIMEOUT:
-                    stopDhcpAction();
-                    break;
-
-                case DhcpClient.CMD_PRE_DHCP_ACTION:
-                    if (mConfiguration.mRequestedPreDhcpActionMs > 0) {
-                        ensureDhcpAction();
-                    } else {
-                        sendMessage(EVENT_PRE_DHCP_ACTION_COMPLETE);
-                    }
-                    break;
-
-                case DhcpClient.CMD_CLEAR_LINKADDRESS:
-                    mInterfaceCtrl.clearIPv4Address();
-                    break;
-
-                case DhcpClient.CMD_CONFIGURE_LINKADDRESS: {
-                    final LinkAddress ipAddress = (LinkAddress) msg.obj;
-                    if (mInterfaceCtrl.setIPv4Address(ipAddress)) {
-                        mDhcpClient.sendMessage(DhcpClient.EVENT_LINKADDRESS_CONFIGURED);
-                    } else {
-                        logError("Failed to set IPv4 address.");
-                        dispatchCallback(PROV_CHANGE_LOST_PROVISIONING,
-                                new LinkProperties(mLinkProperties));
-                        transitionTo(mStoppingState);
-                    }
-                    break;
-                }
-
-                // This message is only received when:
-                //
-                //     a) initial address acquisition succeeds,
-                //     b) renew succeeds or is NAK'd,
-                //     c) rebind succeeds or is NAK'd, or
-                //     c) the lease expires,
-                //
-                // but never when initial address acquisition fails. The latter
-                // condition is now governed by the provisioning timeout.
-                case DhcpClient.CMD_POST_DHCP_ACTION:
-                    stopDhcpAction();
-
-                    switch (msg.arg1) {
-                        case DhcpClient.DHCP_SUCCESS:
-                            handleIPv4Success((DhcpResults) msg.obj);
-                            break;
-                        case DhcpClient.DHCP_FAILURE:
-                            handleIPv4Failure();
-                            break;
-                        default:
-                            logError("Unknown CMD_POST_DHCP_ACTION status: %s", msg.arg1);
-                    }
-                    break;
-
-                case DhcpClient.CMD_ON_QUIT:
-                    // DHCPv4 quit early for some reason.
-                    logError("Unexpected CMD_ON_QUIT.");
-                    mDhcpClient = null;
-                    break;
-
-                default:
-                    return NOT_HANDLED;
-            }
-
-            mMsgStateLogger.handled(this, getCurrentState());
-            return HANDLED;
-        }
-    }
-
-    private static class MessageHandlingLogger {
-        public String processedInState;
-        public String receivedInState;
-
-        public void reset() {
-            processedInState = null;
-            receivedInState = null;
-        }
-
-        public void handled(State processedIn, IState receivedIn) {
-            processedInState = processedIn.getClass().getSimpleName();
-            receivedInState = receivedIn.getName();
-        }
-
-        public String toString() {
-            return String.format("rcvd_in=%s, proc_in=%s",
-                                 receivedInState, processedInState);
-        }
-    }
-
-    private static void setNeighborParameters(
-            INetd netd, String ifName, int numSolicits, int interSolicitIntervalMs)
-            throws RemoteException, IllegalArgumentException {
-        Preconditions.checkNotNull(netd);
-        Preconditions.checkArgument(!TextUtils.isEmpty(ifName));
-        Preconditions.checkArgument(numSolicits > 0);
-        Preconditions.checkArgument(interSolicitIntervalMs > 0);
-
-        for (int family : new Integer[]{INetd.IPV4, INetd.IPV6}) {
-            netd.setProcSysNet(family, INetd.NEIGH, ifName, "retrans_time_ms",
-                    Integer.toString(interSolicitIntervalMs));
-            netd.setProcSysNet(family, INetd.NEIGH, ifName, "ucast_solicit",
-                    Integer.toString(numSolicits));
-        }
-    }
-
-    // TODO: extract out into CollectionUtils.
-    static <T> boolean any(Iterable<T> coll, Predicate<T> fn) {
-        for (T t : coll) {
-            if (fn.test(t)) {
-                return true;
-            }
-        }
-        return false;
-    }
-
-    static <T> boolean all(Iterable<T> coll, Predicate<T> fn) {
-        return !any(coll, not(fn));
-    }
-
-    static <T> Predicate<T> not(Predicate<T> fn) {
-        return (t) -> !fn.test(t);
-    }
-
-    static <T> String join(String delimiter, Collection<T> coll) {
-        return coll.stream().map(Object::toString).collect(Collectors.joining(delimiter));
-    }
-
-    static <T> T find(Iterable<T> coll, Predicate<T> fn) {
-        for (T t: coll) {
-            if (fn.test(t)) {
-                return t;
-            }
-        }
-        return null;
-    }
-
-    static <T> List<T> findAll(Collection<T> coll, Predicate<T> fn) {
-        return coll.stream().filter(fn).collect(Collectors.toList());
-    }
-}
diff --git a/packages/NetworkStack/src/android/net/ip/IpClientLinkObserver.java b/packages/NetworkStack/src/android/net/ip/IpClientLinkObserver.java
deleted file mode 100644
index 8ad99aa0..0000000
--- a/packages/NetworkStack/src/android/net/ip/IpClientLinkObserver.java
+++ /dev/null
@@ -1,378 +0,0 @@
-/*
- * Copyright (C) 2014 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.net.ip;
-
-import android.net.InetAddresses;
-import android.net.LinkAddress;
-import android.net.LinkProperties;
-import android.net.RouteInfo;
-import android.util.Log;
-
-import com.android.server.NetworkObserver;
-
-import java.net.InetAddress;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.Set;
-
-/**
- * Keeps track of link configuration received from Netd.
- *
- * An instance of this class is constructed by passing in an interface name and a callback. The
- * owner is then responsible for registering the tracker with NetworkObserverRegistry. When the
- * class receives update notifications, it applies the update to its local LinkProperties, and if
- * something has changed, notifies its owner of the update via the callback.
- *
- * The owner can then call {@code getLinkProperties()} in order to find out
- * what changed. If in the meantime the LinkProperties stored here have changed,
- * this class will return the current LinkProperties. Because each change
- * triggers an update callback after the change is made, the owner may get more
- * callbacks than strictly necessary (some of which may be no-ops), but will not
- * be out of sync once all callbacks have been processed.
- *
- * Threading model:
- *
- * - The owner of this class is expected to create it, register it, and call
- *   getLinkProperties or clearLinkProperties on its thread.
- * - Most of the methods in the class are implementing NetworkObserver and are called
- *   on the handler used to register the observer.
- * - All accesses to mLinkProperties must be synchronized(this). All the other
- *   member variables are immutable once the object is constructed.
- *
- * @hide
- */
-public class IpClientLinkObserver implements NetworkObserver {
-    private final String mTag;
-
-    /**
-     * Callback used by {@link IpClientLinkObserver} to send update notifications.
-     */
-    public interface Callback {
-        /**
-         * Called when some properties of the link were updated.
-         */
-        void update();
-    }
-
-    private final String mInterfaceName;
-    private final Callback mCallback;
-    private final LinkProperties mLinkProperties;
-    private DnsServerRepository mDnsServerRepository;
-
-    private static final boolean DBG = false;
-
-    public IpClientLinkObserver(String iface, Callback callback) {
-        mTag = "NetlinkTracker/" + iface;
-        mInterfaceName = iface;
-        mCallback = callback;
-        mLinkProperties = new LinkProperties();
-        mLinkProperties.setInterfaceName(mInterfaceName);
-        mDnsServerRepository = new DnsServerRepository();
-    }
-
-    private void maybeLog(String operation, String iface, LinkAddress address) {
-        if (DBG) {
-            Log.d(mTag, operation + ": " + address + " on " + iface
-                    + " flags " + address.getFlags() + " scope " + address.getScope());
-        }
-    }
-
-    private void maybeLog(String operation, Object o) {
-        if (DBG) {
-            Log.d(mTag, operation + ": " + o.toString());
-        }
-    }
-
-    @Override
-    public void onInterfaceRemoved(String iface) {
-        maybeLog("interfaceRemoved", iface);
-        if (mInterfaceName.equals(iface)) {
-            // Our interface was removed. Clear our LinkProperties and tell our owner that they are
-            // now empty. Note that from the moment that the interface is removed, any further
-            // interface-specific messages (e.g., RTM_DELADDR) will not reach us, because the netd
-            // code that parses them will not be able to resolve the ifindex to an interface name.
-            clearLinkProperties();
-            mCallback.update();
-        }
-    }
-
-    @Override
-    public void onInterfaceAddressUpdated(LinkAddress address, String iface) {
-        if (mInterfaceName.equals(iface)) {
-            maybeLog("addressUpdated", iface, address);
-            boolean changed;
-            synchronized (this) {
-                changed = mLinkProperties.addLinkAddress(address);
-            }
-            if (changed) {
-                mCallback.update();
-            }
-        }
-    }
-
-    @Override
-    public void onInterfaceAddressRemoved(LinkAddress address, String iface) {
-        if (mInterfaceName.equals(iface)) {
-            maybeLog("addressRemoved", iface, address);
-            boolean changed;
-            synchronized (this) {
-                changed = mLinkProperties.removeLinkAddress(address);
-            }
-            if (changed) {
-                mCallback.update();
-            }
-        }
-    }
-
-    @Override
-    public void onRouteUpdated(RouteInfo route) {
-        if (mInterfaceName.equals(route.getInterface())) {
-            maybeLog("routeUpdated", route);
-            boolean changed;
-            synchronized (this) {
-                changed = mLinkProperties.addRoute(route);
-            }
-            if (changed) {
-                mCallback.update();
-            }
-        }
-    }
-
-    @Override
-    public void onRouteRemoved(RouteInfo route) {
-        if (mInterfaceName.equals(route.getInterface())) {
-            maybeLog("routeRemoved", route);
-            boolean changed;
-            synchronized (this) {
-                changed = mLinkProperties.removeRoute(route);
-            }
-            if (changed) {
-                mCallback.update();
-            }
-        }
-    }
-
-    @Override
-    public void onInterfaceDnsServerInfo(String iface, long lifetime, String[] addresses) {
-        if (mInterfaceName.equals(iface)) {
-            maybeLog("interfaceDnsServerInfo", Arrays.toString(addresses));
-            boolean changed = mDnsServerRepository.addServers(lifetime, addresses);
-            if (changed) {
-                synchronized (this) {
-                    mDnsServerRepository.setDnsServersOn(mLinkProperties);
-                }
-                mCallback.update();
-            }
-        }
-    }
-
-    /**
-     * Returns a copy of this object's LinkProperties.
-     */
-    public synchronized LinkProperties getLinkProperties() {
-        return new LinkProperties(mLinkProperties);
-    }
-
-    /**
-     * Reset this object's LinkProperties.
-     */
-    public synchronized void clearLinkProperties() {
-        // Clear the repository before clearing mLinkProperties. That way, if a clear() happens
-        // while interfaceDnsServerInfo() is being called, we'll end up with no DNS servers in
-        // mLinkProperties, as desired.
-        mDnsServerRepository = new DnsServerRepository();
-        mLinkProperties.clear();
-        mLinkProperties.setInterfaceName(mInterfaceName);
-    }
-
-    /**
-     * Tracks DNS server updates received from Netlink.
-     *
-     * The network may announce an arbitrary number of DNS servers in Router Advertisements at any
-     * time. Each announcement has a lifetime; when the lifetime expires, the servers should not be
-     * used any more. In this way, the network can gracefully migrate clients from one set of DNS
-     * servers to another. Announcements can both raise and lower the lifetime, and an announcement
-     * can expire servers by announcing them with a lifetime of zero.
-     *
-     * Typically the system will only use a small number (2 or 3; {@code NUM_CURRENT_SERVERS}) of
-     * DNS servers at any given time. These are referred to as the current servers. In case all the
-     * current servers expire, the class also keeps track of a larger (but limited) number of
-     * servers that are promoted to current servers when the current ones expire. In order to
-     * minimize updates to the rest of the system (and potentially expensive cache flushes) this
-     * class attempts to keep the list of current servers constant where possible. More
-     * specifically, the list of current servers is only updated if a new server is learned and
-     * there are not yet {@code NUM_CURRENT_SERVERS} current servers, or if one or more of the
-     * current servers expires or is pushed out of the set. Therefore, the current servers will not
-     * necessarily be the ones with the highest lifetime, but the ones learned first.
-     *
-     * This is by design: if instead the class always preferred the servers with the highest
-     * lifetime, a (misconfigured?) network where two or more routers announce more than
-     * {@code NUM_CURRENT_SERVERS} unique servers would cause persistent oscillations.
-     *
-     * TODO: Currently servers are only expired when a new DNS update is received.
-     * Update them using timers, or possibly on every notification received by NetlinkTracker.
-     *
-     * Threading model: run by NetlinkTracker. Methods are synchronized(this) just in case netlink
-     * notifications are sent by multiple threads. If future threads use alarms to expire, those
-     * alarms must also be synchronized(this).
-     *
-     */
-    private static class DnsServerRepository {
-
-        /** How many DNS servers we will use. 3 is suggested by RFC 6106. */
-        static final int NUM_CURRENT_SERVERS = 3;
-
-        /** How many DNS servers we'll keep track of, in total. */
-        static final int NUM_SERVERS = 12;
-
-        /** Stores up to {@code NUM_CURRENT_SERVERS} DNS servers we're currently using. */
-        private Set<InetAddress> mCurrentServers;
-
-        public static final String TAG = "DnsServerRepository";
-
-        /**
-         * Stores all the DNS servers we know about, for use when the current servers expire.
-         * Always sorted in order of decreasing expiry. The elements in this list are also the
-         * values of mIndex, and may be elements in mCurrentServers.
-         */
-        private ArrayList<DnsServerEntry> mAllServers;
-
-        /**
-         * Indexes the servers so we can update their lifetimes more quickly in the common case
-         * where servers are not being added, but only being refreshed.
-         */
-        private HashMap<InetAddress, DnsServerEntry> mIndex;
-
-        DnsServerRepository() {
-            mCurrentServers = new HashSet<>();
-            mAllServers = new ArrayList<>(NUM_SERVERS);
-            mIndex = new HashMap<>(NUM_SERVERS);
-        }
-
-        /** Sets the DNS servers of the provided LinkProperties object to the current servers. */
-        public synchronized void setDnsServersOn(LinkProperties lp) {
-            lp.setDnsServers(mCurrentServers);
-        }
-
-        /**
-         * Notifies the class of new DNS server information.
-         * @param lifetime the time in seconds that the DNS servers are valid.
-         * @param addresses the string representations of the IP addresses of DNS servers to use.
-         */
-        public synchronized boolean addServers(long lifetime, String[] addresses) {
-            // The lifetime is actually an unsigned 32-bit number, but Java doesn't have unsigned.
-            // Technically 0xffffffff (the maximum) is special and means "forever", but 2^32 seconds
-            // (136 years) is close enough.
-            long now = System.currentTimeMillis();
-            long expiry = now + 1000 * lifetime;
-
-            // Go through the list of servers. For each one, update the entry if one exists, and
-            // create one if it doesn't.
-            for (String addressString : addresses) {
-                InetAddress address;
-                try {
-                    address = InetAddresses.parseNumericAddress(addressString);
-                } catch (IllegalArgumentException ex) {
-                    continue;
-                }
-
-                if (!updateExistingEntry(address, expiry)) {
-                    // There was no entry for this server. Create one, unless it's already expired
-                    // (i.e., if the lifetime is zero; it cannot be < 0 because it's unsigned).
-                    if (expiry > now) {
-                        DnsServerEntry entry = new DnsServerEntry(address, expiry);
-                        mAllServers.add(entry);
-                        mIndex.put(address, entry);
-                    }
-                }
-            }
-
-            // Sort the servers by expiry.
-            Collections.sort(mAllServers);
-
-            // Prune excess entries and update the current server list.
-            return updateCurrentServers();
-        }
-
-        private synchronized boolean updateExistingEntry(InetAddress address, long expiry) {
-            DnsServerEntry existing = mIndex.get(address);
-            if (existing != null) {
-                existing.expiry = expiry;
-                return true;
-            }
-            return false;
-        }
-
-        private synchronized boolean updateCurrentServers() {
-            long now = System.currentTimeMillis();
-            boolean changed = false;
-
-            // Prune excess or expired entries.
-            for (int i = mAllServers.size() - 1; i >= 0; i--) {
-                if (i >= NUM_SERVERS || mAllServers.get(i).expiry < now) {
-                    DnsServerEntry removed = mAllServers.remove(i);
-                    mIndex.remove(removed.address);
-                    changed |= mCurrentServers.remove(removed.address);
-                } else {
-                    break;
-                }
-            }
-
-            // Add servers to the current set, in order of decreasing lifetime, until it has enough.
-            // Prefer existing servers over new servers in order to minimize updates to the rest of
-            // the system and avoid persistent oscillations.
-            for (DnsServerEntry entry : mAllServers) {
-                if (mCurrentServers.size() < NUM_CURRENT_SERVERS) {
-                    changed |= mCurrentServers.add(entry.address);
-                } else {
-                    break;
-                }
-            }
-            return changed;
-        }
-    }
-
-    /**
-     * Represents a DNS server entry with an expiry time.
-     *
-     * Implements Comparable so DNS server entries can be sorted by lifetime, longest-lived first.
-     * The ordering of entries with the same lifetime is unspecified, because given two servers with
-     * identical lifetimes, we don't care which one we use, and only comparing the lifetime is much
-     * faster than comparing the IP address as well.
-     *
-     * Note: this class has a natural ordering that is inconsistent with equals.
-     */
-    private static class DnsServerEntry implements Comparable<DnsServerEntry> {
-        /** The IP address of the DNS server. */
-        public final InetAddress address;
-        /** The time until which the DNS server may be used. A Java millisecond time as might be
-         * returned by currentTimeMillis(). */
-        public long expiry;
-
-        DnsServerEntry(InetAddress address, long expiry) throws IllegalArgumentException {
-            this.address = address;
-            this.expiry = expiry;
-        }
-
-        public int compareTo(DnsServerEntry other) {
-            return Long.compare(other.expiry, this.expiry);
-        }
-    }
-}
diff --git a/packages/NetworkStack/src/android/net/ip/IpNeighborMonitor.java b/packages/NetworkStack/src/android/net/ip/IpNeighborMonitor.java
deleted file mode 100644
index 6ae9a2b..0000000
--- a/packages/NetworkStack/src/android/net/ip/IpNeighborMonitor.java
+++ /dev/null
@@ -1,247 +0,0 @@
-/*
- * Copyright (C) 2017 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.net.ip;
-
-import static android.net.netlink.NetlinkConstants.RTM_DELNEIGH;
-import static android.net.netlink.NetlinkConstants.hexify;
-import static android.net.netlink.NetlinkConstants.stringForNlMsgType;
-import static android.net.util.SocketUtils.makeNetlinkSocketAddress;
-import static android.system.OsConstants.AF_NETLINK;
-import static android.system.OsConstants.NETLINK_ROUTE;
-import static android.system.OsConstants.SOCK_DGRAM;
-import static android.system.OsConstants.SOCK_NONBLOCK;
-
-import android.net.MacAddress;
-import android.net.netlink.NetlinkErrorMessage;
-import android.net.netlink.NetlinkMessage;
-import android.net.netlink.NetlinkSocket;
-import android.net.netlink.RtNetlinkNeighborMessage;
-import android.net.netlink.StructNdMsg;
-import android.net.util.NetworkStackUtils;
-import android.net.util.PacketReader;
-import android.net.util.SharedLog;
-import android.os.Handler;
-import android.os.SystemClock;
-import android.system.ErrnoException;
-import android.system.Os;
-import android.system.OsConstants;
-import android.util.Log;
-
-import java.io.FileDescriptor;
-import java.net.InetAddress;
-import java.net.SocketAddress;
-import java.net.SocketException;
-import java.nio.ByteBuffer;
-import java.nio.ByteOrder;
-import java.util.StringJoiner;
-
-
-/**
- * IpNeighborMonitor.
- *
- * Monitors the kernel rtnetlink neighbor notifications and presents to callers
- * NeighborEvents describing each event. Callers can provide a consumer instance
- * to both filter (e.g. by interface index and IP address) and handle the
- * generated NeighborEvents.
- *
- * @hide
- */
-public class IpNeighborMonitor extends PacketReader {
-    private static final String TAG = IpNeighborMonitor.class.getSimpleName();
-    private static final boolean DBG = false;
-    private static final boolean VDBG = false;
-
-    /**
-     * Make the kernel perform neighbor reachability detection (IPv4 ARP or IPv6 ND)
-     * for the given IP address on the specified interface index.
-     *
-     * @return 0 if the request was successfully passed to the kernel; otherwise return
-     *         a non-zero error code.
-     */
-    public static int startKernelNeighborProbe(int ifIndex, InetAddress ip) {
-        final String msgSnippet = "probing ip=" + ip.getHostAddress() + "%" + ifIndex;
-        if (DBG) { Log.d(TAG, msgSnippet); }
-
-        final byte[] msg = RtNetlinkNeighborMessage.newNewNeighborMessage(
-                1, ip, StructNdMsg.NUD_PROBE, ifIndex, null);
-
-        try {
-            NetlinkSocket.sendOneShotKernelMessage(NETLINK_ROUTE, msg);
-        } catch (ErrnoException e) {
-            Log.e(TAG, "Error " + msgSnippet + ": " + e);
-            return -e.errno;
-        }
-
-        return 0;
-    }
-
-    public static class NeighborEvent {
-        final long elapsedMs;
-        final short msgType;
-        final int ifindex;
-        final InetAddress ip;
-        final short nudState;
-        final MacAddress macAddr;
-
-        public NeighborEvent(long elapsedMs, short msgType, int ifindex, InetAddress ip,
-                short nudState, MacAddress macAddr) {
-            this.elapsedMs = elapsedMs;
-            this.msgType = msgType;
-            this.ifindex = ifindex;
-            this.ip = ip;
-            this.nudState = nudState;
-            this.macAddr = macAddr;
-        }
-
-        boolean isConnected() {
-            return (msgType != RTM_DELNEIGH) && StructNdMsg.isNudStateConnected(nudState);
-        }
-
-        boolean isValid() {
-            return (msgType != RTM_DELNEIGH) && StructNdMsg.isNudStateValid(nudState);
-        }
-
-        @Override
-        public String toString() {
-            final StringJoiner j = new StringJoiner(",", "NeighborEvent{", "}");
-            return j.add("@" + elapsedMs)
-                    .add(stringForNlMsgType(msgType))
-                    .add("if=" + ifindex)
-                    .add(ip.getHostAddress())
-                    .add(StructNdMsg.stringForNudState(nudState))
-                    .add("[" + macAddr + "]")
-                    .toString();
-        }
-    }
-
-    public interface NeighborEventConsumer {
-        // Every neighbor event received on the netlink socket is passed in
-        // here. Subclasses should filter for events of interest.
-        public void accept(NeighborEvent event);
-    }
-
-    private final SharedLog mLog;
-    private final NeighborEventConsumer mConsumer;
-
-    public IpNeighborMonitor(Handler h, SharedLog log, NeighborEventConsumer cb) {
-        super(h, NetlinkSocket.DEFAULT_RECV_BUFSIZE);
-        mLog = log.forSubComponent(TAG);
-        mConsumer = (cb != null) ? cb : (event) -> { /* discard */ };
-    }
-
-    @Override
-    protected FileDescriptor createFd() {
-        FileDescriptor fd = null;
-
-        try {
-            fd = Os.socket(AF_NETLINK, SOCK_DGRAM | SOCK_NONBLOCK, NETLINK_ROUTE);
-            Os.bind(fd, makeNetlinkSocketAddress(0, OsConstants.RTMGRP_NEIGH));
-            NetlinkSocket.connectToKernel(fd);
-
-            if (VDBG) {
-                final SocketAddress nlAddr = Os.getsockname(fd);
-                Log.d(TAG, "bound to sockaddr_nl{" + nlAddr.toString() + "}");
-            }
-        } catch (ErrnoException|SocketException e) {
-            logError("Failed to create rtnetlink socket", e);
-            NetworkStackUtils.closeSocketQuietly(fd);
-            return null;
-        }
-
-        return fd;
-    }
-
-    @Override
-    protected void handlePacket(byte[] recvbuf, int length) {
-        final long whenMs = SystemClock.elapsedRealtime();
-
-        final ByteBuffer byteBuffer = ByteBuffer.wrap(recvbuf, 0, length);
-        byteBuffer.order(ByteOrder.nativeOrder());
-
-        parseNetlinkMessageBuffer(byteBuffer, whenMs);
-    }
-
-    private void parseNetlinkMessageBuffer(ByteBuffer byteBuffer, long whenMs) {
-        while (byteBuffer.remaining() > 0) {
-            final int position = byteBuffer.position();
-            final NetlinkMessage nlMsg = NetlinkMessage.parse(byteBuffer);
-            if (nlMsg == null || nlMsg.getHeader() == null) {
-                byteBuffer.position(position);
-                mLog.e("unparsable netlink msg: " + hexify(byteBuffer));
-                break;
-            }
-
-            final int srcPortId = nlMsg.getHeader().nlmsg_pid;
-            if (srcPortId !=  0) {
-                mLog.e("non-kernel source portId: " + Integer.toUnsignedLong(srcPortId));
-                break;
-            }
-
-            if (nlMsg instanceof NetlinkErrorMessage) {
-                mLog.e("netlink error: " + nlMsg);
-                continue;
-            } else if (!(nlMsg instanceof RtNetlinkNeighborMessage)) {
-                mLog.i("non-rtnetlink neighbor msg: " + nlMsg);
-                continue;
-            }
-
-            evaluateRtNetlinkNeighborMessage((RtNetlinkNeighborMessage) nlMsg, whenMs);
-        }
-    }
-
-    private void evaluateRtNetlinkNeighborMessage(
-            RtNetlinkNeighborMessage neighMsg, long whenMs) {
-        final short msgType = neighMsg.getHeader().nlmsg_type;
-        final StructNdMsg ndMsg = neighMsg.getNdHeader();
-        if (ndMsg == null) {
-            mLog.e("RtNetlinkNeighborMessage without ND message header!");
-            return;
-        }
-
-        final int ifindex = ndMsg.ndm_ifindex;
-        final InetAddress destination = neighMsg.getDestination();
-        final short nudState =
-                (msgType == RTM_DELNEIGH)
-                ? StructNdMsg.NUD_NONE
-                : ndMsg.ndm_state;
-
-        final NeighborEvent event = new NeighborEvent(
-                whenMs, msgType, ifindex, destination, nudState,
-                getMacAddress(neighMsg.getLinkLayerAddress()));
-
-        if (VDBG) {
-            Log.d(TAG, neighMsg.toString());
-        }
-        if (DBG) {
-            Log.d(TAG, event.toString());
-        }
-
-        mConsumer.accept(event);
-    }
-
-    private static MacAddress getMacAddress(byte[] linkLayerAddress) {
-        if (linkLayerAddress != null) {
-            try {
-                return MacAddress.fromBytes(linkLayerAddress);
-            } catch (IllegalArgumentException e) {
-                Log.e(TAG, "Failed to parse link-layer address: " + hexify(linkLayerAddress));
-            }
-        }
-
-        return null;
-    }
-}
diff --git a/packages/NetworkStack/src/android/net/ip/IpReachabilityMonitor.java b/packages/NetworkStack/src/android/net/ip/IpReachabilityMonitor.java
deleted file mode 100644
index c19a24e..0000000
--- a/packages/NetworkStack/src/android/net/ip/IpReachabilityMonitor.java
+++ /dev/null
@@ -1,398 +0,0 @@
-/*
- * Copyright (C) 2015 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.net.ip;
-
-import static android.net.metrics.IpReachabilityEvent.NUD_FAILED;
-import static android.net.metrics.IpReachabilityEvent.NUD_FAILED_ORGANIC;
-import static android.net.metrics.IpReachabilityEvent.PROVISIONING_LOST;
-import static android.net.metrics.IpReachabilityEvent.PROVISIONING_LOST_ORGANIC;
-
-import android.content.Context;
-import android.net.ConnectivityManager;
-import android.net.LinkProperties;
-import android.net.RouteInfo;
-import android.net.ip.IpNeighborMonitor.NeighborEvent;
-import android.net.metrics.IpConnectivityLog;
-import android.net.metrics.IpReachabilityEvent;
-import android.net.netlink.StructNdMsg;
-import android.net.util.InterfaceParams;
-import android.net.util.SharedLog;
-import android.os.ConditionVariable;
-import android.os.Handler;
-import android.os.Looper;
-import android.os.PowerManager;
-import android.os.PowerManager.WakeLock;
-import android.os.SystemClock;
-import android.util.Log;
-
-import com.android.internal.annotations.VisibleForTesting;
-
-import java.io.PrintWriter;
-import java.net.Inet6Address;
-import java.net.InetAddress;
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-
-
-/**
- * IpReachabilityMonitor.
- *
- * Monitors on-link IP reachability and notifies callers whenever any on-link
- * addresses of interest appear to have become unresponsive.
- *
- * This code does not concern itself with "why" a neighbour might have become
- * unreachable. Instead, it primarily reacts to the kernel's notion of IP
- * reachability for each of the neighbours we know to be critically important
- * to normal network connectivity. As such, it is often "just the messenger":
- * the neighbours about which it warns are already deemed by the kernel to have
- * become unreachable.
- *
- *
- * How it works:
- *
- *   1. The "on-link neighbours of interest" found in a given LinkProperties
- *      instance are added to a "watch list" via #updateLinkProperties().
- *      This usually means all default gateways and any on-link DNS servers.
- *
- *   2. We listen continuously for netlink neighbour messages (RTM_NEWNEIGH,
- *      RTM_DELNEIGH), watching only for neighbours in the watch list.
- *
- *        - A neighbour going into NUD_REACHABLE, NUD_STALE, NUD_DELAY, and
- *          even NUD_PROBE is perfectly normal; we merely record the new state.
- *
- *        - A neighbour's entry may be deleted (RTM_DELNEIGH), for example due
- *          to garbage collection.  This is not necessarily of immediate
- *          concern; we record the neighbour as moving to NUD_NONE.
- *
- *        - A neighbour transitioning to NUD_FAILED (for any reason) is
- *          critically important and is handled as described below in #4.
- *
- *   3. All on-link neighbours in the watch list can be forcibly "probed" by
- *      calling #probeAll(). This should be called whenever it is important to
- *      verify that critical neighbours on the link are still reachable, e.g.
- *      when roaming between BSSIDs.
- *
- *        - The kernel will send unicast ARP requests for IPv4 neighbours and
- *          unicast NS packets for IPv6 neighbours.  The expected replies will
- *          likely be unicast.
- *
- *        - The forced probing is done holding a wakelock. The kernel may,
- *          however, initiate probing of a neighbor on its own, i.e. whenever
- *          a neighbour has expired from NUD_DELAY.
- *
- *        - The kernel sends:
- *
- *              /proc/sys/net/ipv{4,6}/neigh/<ifname>/ucast_solicit
- *
- *          number of probes (usually 3) every:
- *
- *              /proc/sys/net/ipv{4,6}/neigh/<ifname>/retrans_time_ms
- *
- *          number of milliseconds (usually 1000ms). This normally results in
- *          3 unicast packets, 1 per second.
- *
- *        - If no response is received to any of the probe packets, the kernel
- *          marks the neighbour as being in state NUD_FAILED, and the listening
- *          process in #2 will learn of it.
- *
- *   4. We call the supplied Callback#notifyLost() function if the loss of a
- *      neighbour in NUD_FAILED would cause IPv4 or IPv6 configuration to
- *      become incomplete (a loss of provisioning).
- *
- *        - For example, losing all our IPv4 on-link DNS servers (or losing
- *          our only IPv6 default gateway) constitutes a loss of IPv4 (IPv6)
- *          provisioning; Callback#notifyLost() would be called.
- *
- *        - Since it can be non-trivial to reacquire certain IP provisioning
- *          state it may be best for the link to disconnect completely and
- *          reconnect afresh.
- *
- * Accessing an instance of this class from multiple threads is NOT safe.
- *
- * @hide
- */
-public class IpReachabilityMonitor {
-    private static final String TAG = "IpReachabilityMonitor";
-    private static final boolean DBG = Log.isLoggable(TAG, Log.DEBUG);
-    private static final boolean VDBG = Log.isLoggable(TAG, Log.VERBOSE);
-
-    public interface Callback {
-        // This callback function must execute as quickly as possible as it is
-        // run on the same thread that listens to kernel neighbor updates.
-        //
-        // TODO: refactor to something like notifyProvisioningLost(String msg).
-        public void notifyLost(InetAddress ip, String logMsg);
-    }
-
-    /**
-     * Encapsulates IpReachabilityMonitor depencencies on systems that hinder unit testing.
-     * TODO: consider also wrapping MultinetworkPolicyTracker in this interface.
-     */
-    interface Dependencies {
-        void acquireWakeLock(long durationMs);
-
-        static Dependencies makeDefault(Context context, String iface) {
-            final String lockName = TAG + "." + iface;
-            final PowerManager pm = (PowerManager) context.getSystemService(Context.POWER_SERVICE);
-            final WakeLock lock = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, lockName);
-
-            return new Dependencies() {
-                public void acquireWakeLock(long durationMs) {
-                    lock.acquire(durationMs);
-                }
-            };
-        }
-    }
-
-    private final InterfaceParams mInterfaceParams;
-    private final IpNeighborMonitor mIpNeighborMonitor;
-    private final SharedLog mLog;
-    private final Callback mCallback;
-    private final Dependencies mDependencies;
-    private final boolean mUsingMultinetworkPolicyTracker;
-    private final ConnectivityManager mCm;
-    private final IpConnectivityLog mMetricsLog = new IpConnectivityLog();
-    private LinkProperties mLinkProperties = new LinkProperties();
-    private Map<InetAddress, NeighborEvent> mNeighborWatchList = new HashMap<>();
-    // Time in milliseconds of the last forced probe request.
-    private volatile long mLastProbeTimeMs;
-
-    public IpReachabilityMonitor(
-            Context context, InterfaceParams ifParams, Handler h, SharedLog log, Callback callback,
-            boolean usingMultinetworkPolicyTracker) {
-        this(context, ifParams, h, log, callback, usingMultinetworkPolicyTracker,
-                Dependencies.makeDefault(context, ifParams.name));
-    }
-
-    @VisibleForTesting
-    IpReachabilityMonitor(Context context, InterfaceParams ifParams, Handler h, SharedLog log,
-            Callback callback, boolean usingMultinetworkPolicyTracker, Dependencies dependencies) {
-        if (ifParams == null) throw new IllegalArgumentException("null InterfaceParams");
-
-        mInterfaceParams = ifParams;
-        mLog = log.forSubComponent(TAG);
-        mCallback = callback;
-        mUsingMultinetworkPolicyTracker = usingMultinetworkPolicyTracker;
-        mCm = context.getSystemService(ConnectivityManager.class);
-        mDependencies = dependencies;
-
-        mIpNeighborMonitor = new IpNeighborMonitor(h, mLog,
-                (NeighborEvent event) -> {
-                    if (mInterfaceParams.index != event.ifindex) return;
-                    if (!mNeighborWatchList.containsKey(event.ip)) return;
-
-                    final NeighborEvent prev = mNeighborWatchList.put(event.ip, event);
-
-                    // TODO: Consider what to do with other states that are not within
-                    // NeighborEvent#isValid() (i.e. NUD_NONE, NUD_INCOMPLETE).
-                    if (event.nudState == StructNdMsg.NUD_FAILED) {
-                        mLog.w("ALERT neighbor went from: " + prev + " to: " + event);
-                        handleNeighborLost(event);
-                    }
-                });
-        mIpNeighborMonitor.start();
-    }
-
-    public void stop() {
-        mIpNeighborMonitor.stop();
-        clearLinkProperties();
-    }
-
-    public void dump(PrintWriter pw) {
-        if (Looper.myLooper() == mIpNeighborMonitor.getHandler().getLooper()) {
-            pw.println(describeWatchList("\n"));
-            return;
-        }
-
-        final ConditionVariable cv = new ConditionVariable(false);
-        mIpNeighborMonitor.getHandler().post(() -> {
-            pw.println(describeWatchList("\n"));
-            cv.open();
-        });
-
-        if (!cv.block(1000)) {
-            pw.println("Timed out waiting for IpReachabilityMonitor dump");
-        }
-    }
-
-    private String describeWatchList() { return describeWatchList(" "); }
-
-    private String describeWatchList(String sep) {
-        final StringBuilder sb = new StringBuilder();
-        sb.append("iface{" + mInterfaceParams + "}," + sep);
-        sb.append("ntable=[" + sep);
-        String delimiter = "";
-        for (Map.Entry<InetAddress, NeighborEvent> entry : mNeighborWatchList.entrySet()) {
-            sb.append(delimiter).append(entry.getKey().getHostAddress() + "/" + entry.getValue());
-            delimiter = "," + sep;
-        }
-        sb.append("]");
-        return sb.toString();
-    }
-
-    private static boolean isOnLink(List<RouteInfo> routes, InetAddress ip) {
-        for (RouteInfo route : routes) {
-            if (!route.hasGateway() && route.matches(ip)) {
-                return true;
-            }
-        }
-        return false;
-    }
-
-    public void updateLinkProperties(LinkProperties lp) {
-        if (!mInterfaceParams.name.equals(lp.getInterfaceName())) {
-            // TODO: figure out whether / how to cope with interface changes.
-            Log.wtf(TAG, "requested LinkProperties interface '" + lp.getInterfaceName() +
-                    "' does not match: " + mInterfaceParams.name);
-            return;
-        }
-
-        mLinkProperties = new LinkProperties(lp);
-        Map<InetAddress, NeighborEvent> newNeighborWatchList = new HashMap<>();
-
-        final List<RouteInfo> routes = mLinkProperties.getRoutes();
-        for (RouteInfo route : routes) {
-            if (route.hasGateway()) {
-                InetAddress gw = route.getGateway();
-                if (isOnLink(routes, gw)) {
-                    newNeighborWatchList.put(gw, mNeighborWatchList.getOrDefault(gw, null));
-                }
-            }
-        }
-
-        for (InetAddress dns : lp.getDnsServers()) {
-            if (isOnLink(routes, dns)) {
-                newNeighborWatchList.put(dns, mNeighborWatchList.getOrDefault(dns, null));
-            }
-        }
-
-        mNeighborWatchList = newNeighborWatchList;
-        if (DBG) { Log.d(TAG, "watch: " + describeWatchList()); }
-    }
-
-    public void clearLinkProperties() {
-        mLinkProperties.clear();
-        mNeighborWatchList.clear();
-        if (DBG) { Log.d(TAG, "clear: " + describeWatchList()); }
-    }
-
-    private void handleNeighborLost(NeighborEvent event) {
-        final LinkProperties whatIfLp = new LinkProperties(mLinkProperties);
-
-        InetAddress ip = null;
-        for (Map.Entry<InetAddress, NeighborEvent> entry : mNeighborWatchList.entrySet()) {
-            // TODO: Consider using NeighborEvent#isValid() here; it's more
-            // strict but may interact badly if other entries are somehow in
-            // NUD_INCOMPLETE (say, during network attach).
-            if (entry.getValue().nudState != StructNdMsg.NUD_FAILED) continue;
-
-            ip = entry.getKey();
-            for (RouteInfo route : mLinkProperties.getRoutes()) {
-                if (ip.equals(route.getGateway())) {
-                    whatIfLp.removeRoute(route);
-                }
-            }
-
-            if (avoidingBadLinks() || !(ip instanceof Inet6Address)) {
-                // We should do this unconditionally, but alas we cannot: b/31827713.
-                whatIfLp.removeDnsServer(ip);
-            }
-        }
-
-        final boolean lostProvisioning =
-                (mLinkProperties.isIpv4Provisioned() && !whatIfLp.isIpv4Provisioned())
-                || (mLinkProperties.isIpv6Provisioned() && !whatIfLp.isIpv6Provisioned());
-
-        if (lostProvisioning) {
-            final String logMsg = "FAILURE: LOST_PROVISIONING, " + event;
-            Log.w(TAG, logMsg);
-            if (mCallback != null) {
-                // TODO: remove |ip| when the callback signature no longer has
-                // an InetAddress argument.
-                mCallback.notifyLost(ip, logMsg);
-            }
-        }
-        logNudFailed(lostProvisioning);
-    }
-
-    private boolean avoidingBadLinks() {
-        return !mUsingMultinetworkPolicyTracker || mCm.shouldAvoidBadWifi();
-    }
-
-    public void probeAll() {
-        final List<InetAddress> ipProbeList = new ArrayList<>(mNeighborWatchList.keySet());
-
-        if (!ipProbeList.isEmpty()) {
-            // Keep the CPU awake long enough to allow all ARP/ND
-            // probes a reasonable chance at success. See b/23197666.
-            //
-            // The wakelock we use is (by default) refcounted, and this version
-            // of acquire(timeout) queues a release message to keep acquisitions
-            // and releases balanced.
-            mDependencies.acquireWakeLock(getProbeWakeLockDuration());
-        }
-
-        for (InetAddress ip : ipProbeList) {
-            final int rval = IpNeighborMonitor.startKernelNeighborProbe(mInterfaceParams.index, ip);
-            mLog.log(String.format("put neighbor %s into NUD_PROBE state (rval=%d)",
-                     ip.getHostAddress(), rval));
-            logEvent(IpReachabilityEvent.PROBE, rval);
-        }
-        mLastProbeTimeMs = SystemClock.elapsedRealtime();
-    }
-
-    private static long getProbeWakeLockDuration() {
-        // Ideally, this would be computed by examining the values of:
-        //
-        //     /proc/sys/net/ipv[46]/neigh/<ifname>/ucast_solicit
-        //
-        // and:
-        //
-        //     /proc/sys/net/ipv[46]/neigh/<ifname>/retrans_time_ms
-        //
-        // For now, just make some assumptions.
-        final long numUnicastProbes = 3;
-        final long retransTimeMs = 1000;
-        final long gracePeriodMs = 500;
-        return (numUnicastProbes * retransTimeMs) + gracePeriodMs;
-    }
-
-    private void logEvent(int probeType, int errorCode) {
-        int eventType = probeType | (errorCode & 0xff);
-        mMetricsLog.log(mInterfaceParams.name, new IpReachabilityEvent(eventType));
-    }
-
-    private void logNudFailed(boolean lostProvisioning) {
-        long duration = SystemClock.elapsedRealtime() - mLastProbeTimeMs;
-        boolean isFromProbe = (duration < getProbeWakeLockDuration());
-        int eventType = nudFailureEventType(isFromProbe, lostProvisioning);
-        mMetricsLog.log(mInterfaceParams.name, new IpReachabilityEvent(eventType));
-    }
-
-    /**
-     * Returns the NUD failure event type code corresponding to the given conditions.
-     */
-    private static int nudFailureEventType(boolean isFromProbe, boolean isProvisioningLost) {
-        if (isFromProbe) {
-            return isProvisioningLost ? PROVISIONING_LOST : NUD_FAILED;
-        } else {
-            return isProvisioningLost ? PROVISIONING_LOST_ORGANIC : NUD_FAILED_ORGANIC;
-        }
-    }
-}
diff --git a/packages/NetworkStack/src/android/net/util/ConnectivityPacketSummary.java b/packages/NetworkStack/src/android/net/util/ConnectivityPacketSummary.java
deleted file mode 100644
index 08c3f60..0000000
--- a/packages/NetworkStack/src/android/net/util/ConnectivityPacketSummary.java
+++ /dev/null
@@ -1,435 +0,0 @@
-/*
- * Copyright (C) 2016 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.net.util;
-
-import static android.system.OsConstants.IPPROTO_ICMPV6;
-import static android.system.OsConstants.IPPROTO_UDP;
-
-import static com.android.server.util.NetworkStackConstants.ARP_HWTYPE_ETHER;
-import static com.android.server.util.NetworkStackConstants.ARP_PAYLOAD_LEN;
-import static com.android.server.util.NetworkStackConstants.ARP_REPLY;
-import static com.android.server.util.NetworkStackConstants.ARP_REQUEST;
-import static com.android.server.util.NetworkStackConstants.DHCP4_CLIENT_PORT;
-import static com.android.server.util.NetworkStackConstants.ETHER_ADDR_LEN;
-import static com.android.server.util.NetworkStackConstants.ETHER_DST_ADDR_OFFSET;
-import static com.android.server.util.NetworkStackConstants.ETHER_HEADER_LEN;
-import static com.android.server.util.NetworkStackConstants.ETHER_SRC_ADDR_OFFSET;
-import static com.android.server.util.NetworkStackConstants.ETHER_TYPE_ARP;
-import static com.android.server.util.NetworkStackConstants.ETHER_TYPE_IPV4;
-import static com.android.server.util.NetworkStackConstants.ETHER_TYPE_IPV6;
-import static com.android.server.util.NetworkStackConstants.ETHER_TYPE_OFFSET;
-import static com.android.server.util.NetworkStackConstants.ICMPV6_HEADER_MIN_LEN;
-import static com.android.server.util.NetworkStackConstants.ICMPV6_ND_OPTION_LENGTH_SCALING_FACTOR;
-import static com.android.server.util.NetworkStackConstants.ICMPV6_ND_OPTION_MIN_LENGTH;
-import static com.android.server.util.NetworkStackConstants.ICMPV6_ND_OPTION_MTU;
-import static com.android.server.util.NetworkStackConstants.ICMPV6_ND_OPTION_SLLA;
-import static com.android.server.util.NetworkStackConstants.ICMPV6_ND_OPTION_TLLA;
-import static com.android.server.util.NetworkStackConstants.ICMPV6_NEIGHBOR_ADVERTISEMENT;
-import static com.android.server.util.NetworkStackConstants.ICMPV6_NEIGHBOR_SOLICITATION;
-import static com.android.server.util.NetworkStackConstants.ICMPV6_ROUTER_ADVERTISEMENT;
-import static com.android.server.util.NetworkStackConstants.ICMPV6_ROUTER_SOLICITATION;
-import static com.android.server.util.NetworkStackConstants.IPV4_ADDR_LEN;
-import static com.android.server.util.NetworkStackConstants.IPV4_DST_ADDR_OFFSET;
-import static com.android.server.util.NetworkStackConstants.IPV4_FLAGS_OFFSET;
-import static com.android.server.util.NetworkStackConstants.IPV4_FRAGMENT_MASK;
-import static com.android.server.util.NetworkStackConstants.IPV4_HEADER_MIN_LEN;
-import static com.android.server.util.NetworkStackConstants.IPV4_IHL_MASK;
-import static com.android.server.util.NetworkStackConstants.IPV4_PROTOCOL_OFFSET;
-import static com.android.server.util.NetworkStackConstants.IPV4_SRC_ADDR_OFFSET;
-import static com.android.server.util.NetworkStackConstants.IPV6_ADDR_LEN;
-import static com.android.server.util.NetworkStackConstants.IPV6_HEADER_LEN;
-import static com.android.server.util.NetworkStackConstants.IPV6_PROTOCOL_OFFSET;
-import static com.android.server.util.NetworkStackConstants.IPV6_SRC_ADDR_OFFSET;
-import static com.android.server.util.NetworkStackConstants.UDP_HEADER_LEN;
-
-import android.net.MacAddress;
-import android.net.dhcp.DhcpPacket;
-
-import java.net.InetAddress;
-import java.net.UnknownHostException;
-import java.nio.ByteBuffer;
-import java.nio.ByteOrder;
-import java.util.StringJoiner;
-
-
-/**
- * Critical connectivity packet summarizing class.
- *
- * Outputs short descriptions of ARP, DHCPv4, and IPv6 RS/RA/NS/NA packets.
- *
- * @hide
- */
-public class ConnectivityPacketSummary {
-    private static final String TAG = ConnectivityPacketSummary.class.getSimpleName();
-
-    private final byte[] mHwAddr;
-    private final byte[] mBytes;
-    private final int mLength;
-    private final ByteBuffer mPacket;
-    private final String mSummary;
-
-    public static String summarize(MacAddress hwaddr, byte[] buffer) {
-        return summarize(hwaddr, buffer, buffer.length);
-    }
-
-    // Methods called herein perform some but by no means all error checking.
-    // They may throw runtime exceptions on malformed packets.
-    public static String summarize(MacAddress macAddr, byte[] buffer, int length) {
-        if ((macAddr == null) || (buffer == null)) return null;
-        length = Math.min(length, buffer.length);
-        return (new ConnectivityPacketSummary(macAddr, buffer, length)).toString();
-    }
-
-    private ConnectivityPacketSummary(MacAddress macAddr, byte[] buffer, int length) {
-        mHwAddr = macAddr.toByteArray();
-        mBytes = buffer;
-        mLength = Math.min(length, mBytes.length);
-        mPacket = ByteBuffer.wrap(mBytes, 0, mLength);
-        mPacket.order(ByteOrder.BIG_ENDIAN);
-
-        final StringJoiner sj = new StringJoiner(" ");
-        // TODO: support other link-layers, or even no link-layer header.
-        parseEther(sj);
-        mSummary = sj.toString();
-    }
-
-    public String toString() {
-        return mSummary;
-    }
-
-    private void parseEther(StringJoiner sj) {
-        if (mPacket.remaining() < ETHER_HEADER_LEN) {
-            sj.add("runt:").add(asString(mPacket.remaining()));
-            return;
-        }
-
-        mPacket.position(ETHER_SRC_ADDR_OFFSET);
-        final ByteBuffer srcMac = (ByteBuffer) mPacket.slice().limit(ETHER_ADDR_LEN);
-        sj.add(ByteBuffer.wrap(mHwAddr).equals(srcMac) ? "TX" : "RX");
-        sj.add(getMacAddressString(srcMac));
-
-        mPacket.position(ETHER_DST_ADDR_OFFSET);
-        final ByteBuffer dstMac = (ByteBuffer) mPacket.slice().limit(ETHER_ADDR_LEN);
-        sj.add(">").add(getMacAddressString(dstMac));
-
-        mPacket.position(ETHER_TYPE_OFFSET);
-        final int etherType = asUint(mPacket.getShort());
-        switch (etherType) {
-            case ETHER_TYPE_ARP:
-                sj.add("arp");
-                parseARP(sj);
-                break;
-            case ETHER_TYPE_IPV4:
-                sj.add("ipv4");
-                parseIPv4(sj);
-                break;
-            case ETHER_TYPE_IPV6:
-                sj.add("ipv6");
-                parseIPv6(sj);
-                break;
-            default:
-                // Unknown ether type.
-                sj.add("ethtype").add(asString(etherType));
-                break;
-        }
-    }
-
-    private void parseARP(StringJoiner sj) {
-        if (mPacket.remaining() < ARP_PAYLOAD_LEN) {
-            sj.add("runt:").add(asString(mPacket.remaining()));
-            return;
-        }
-
-        if (asUint(mPacket.getShort()) != ARP_HWTYPE_ETHER ||
-            asUint(mPacket.getShort()) != ETHER_TYPE_IPV4 ||
-            asUint(mPacket.get()) != ETHER_ADDR_LEN ||
-            asUint(mPacket.get()) != IPV4_ADDR_LEN) {
-            sj.add("unexpected header");
-            return;
-        }
-
-        final int opCode = asUint(mPacket.getShort());
-
-        final String senderHwAddr = getMacAddressString(mPacket);
-        final String senderIPv4 = getIPv4AddressString(mPacket);
-        getMacAddressString(mPacket);  // target hardware address, unused
-        final String targetIPv4 = getIPv4AddressString(mPacket);
-
-        if (opCode == ARP_REQUEST) {
-            sj.add("who-has").add(targetIPv4);
-        } else if (opCode == ARP_REPLY) {
-            sj.add("reply").add(senderIPv4).add(senderHwAddr);
-        } else {
-            sj.add("unknown opcode").add(asString(opCode));
-        }
-    }
-
-    private void parseIPv4(StringJoiner sj) {
-        if (!mPacket.hasRemaining()) {
-            sj.add("runt");
-            return;
-        }
-
-        final int startOfIpLayer = mPacket.position();
-        final int ipv4HeaderLength = (mPacket.get(startOfIpLayer) & IPV4_IHL_MASK) * 4;
-        if (mPacket.remaining() < ipv4HeaderLength ||
-            mPacket.remaining() < IPV4_HEADER_MIN_LEN) {
-            sj.add("runt:").add(asString(mPacket.remaining()));
-            return;
-        }
-        final int startOfTransportLayer = startOfIpLayer + ipv4HeaderLength;
-
-        mPacket.position(startOfIpLayer + IPV4_FLAGS_OFFSET);
-        final int flagsAndFragment = asUint(mPacket.getShort());
-        final boolean isFragment = (flagsAndFragment & IPV4_FRAGMENT_MASK) != 0;
-
-        mPacket.position(startOfIpLayer + IPV4_PROTOCOL_OFFSET);
-        final int protocol = asUint(mPacket.get());
-
-        mPacket.position(startOfIpLayer + IPV4_SRC_ADDR_OFFSET);
-        final String srcAddr = getIPv4AddressString(mPacket);
-
-        mPacket.position(startOfIpLayer + IPV4_DST_ADDR_OFFSET);
-        final String dstAddr = getIPv4AddressString(mPacket);
-
-        sj.add(srcAddr).add(">").add(dstAddr);
-
-        mPacket.position(startOfTransportLayer);
-        if (protocol == IPPROTO_UDP) {
-            sj.add("udp");
-            if (isFragment) sj.add("fragment");
-            else parseUDP(sj);
-        } else {
-            sj.add("proto").add(asString(protocol));
-            if (isFragment) sj.add("fragment");
-        }
-    }
-
-    private void parseIPv6(StringJoiner sj) {
-        if (mPacket.remaining() < IPV6_HEADER_LEN) {
-            sj.add("runt:").add(asString(mPacket.remaining()));
-            return;
-        }
-
-        final int startOfIpLayer = mPacket.position();
-
-        mPacket.position(startOfIpLayer + IPV6_PROTOCOL_OFFSET);
-        final int protocol = asUint(mPacket.get());
-
-        mPacket.position(startOfIpLayer + IPV6_SRC_ADDR_OFFSET);
-        final String srcAddr = getIPv6AddressString(mPacket);
-        final String dstAddr = getIPv6AddressString(mPacket);
-
-        sj.add(srcAddr).add(">").add(dstAddr);
-
-        mPacket.position(startOfIpLayer + IPV6_HEADER_LEN);
-        if (protocol == IPPROTO_ICMPV6) {
-            sj.add("icmp6");
-            parseICMPv6(sj);
-        } else {
-            sj.add("proto").add(asString(protocol));
-        }
-    }
-
-    private void parseICMPv6(StringJoiner sj) {
-        if (mPacket.remaining() < ICMPV6_HEADER_MIN_LEN) {
-            sj.add("runt:").add(asString(mPacket.remaining()));
-            return;
-        }
-
-        final int icmp6Type = asUint(mPacket.get());
-        final int icmp6Code = asUint(mPacket.get());
-        mPacket.getShort();  // checksum, unused
-
-        switch (icmp6Type) {
-            case ICMPV6_ROUTER_SOLICITATION:
-                sj.add("rs");
-                parseICMPv6RouterSolicitation(sj);
-                break;
-            case ICMPV6_ROUTER_ADVERTISEMENT:
-                sj.add("ra");
-                parseICMPv6RouterAdvertisement(sj);
-                break;
-            case ICMPV6_NEIGHBOR_SOLICITATION:
-                sj.add("ns");
-                parseICMPv6NeighborMessage(sj);
-                break;
-            case ICMPV6_NEIGHBOR_ADVERTISEMENT:
-                sj.add("na");
-                parseICMPv6NeighborMessage(sj);
-                break;
-            default:
-                sj.add("type").add(asString(icmp6Type));
-                sj.add("code").add(asString(icmp6Code));
-                break;
-        }
-    }
-
-    private void parseICMPv6RouterSolicitation(StringJoiner sj) {
-        final int RESERVED = 4;
-        if (mPacket.remaining() < RESERVED) {
-            sj.add("runt:").add(asString(mPacket.remaining()));
-            return;
-        }
-
-        mPacket.position(mPacket.position() + RESERVED);
-        parseICMPv6NeighborDiscoveryOptions(sj);
-    }
-
-    private void parseICMPv6RouterAdvertisement(StringJoiner sj) {
-        final int FLAGS_AND_TIMERS = 3 * 4;
-        if (mPacket.remaining() < FLAGS_AND_TIMERS) {
-            sj.add("runt:").add(asString(mPacket.remaining()));
-            return;
-        }
-
-        mPacket.position(mPacket.position() + FLAGS_AND_TIMERS);
-        parseICMPv6NeighborDiscoveryOptions(sj);
-    }
-
-    private void parseICMPv6NeighborMessage(StringJoiner sj) {
-        final int RESERVED = 4;
-        final int minReq = RESERVED + IPV6_ADDR_LEN;
-        if (mPacket.remaining() < minReq) {
-            sj.add("runt:").add(asString(mPacket.remaining()));
-            return;
-        }
-
-        mPacket.position(mPacket.position() + RESERVED);
-        sj.add(getIPv6AddressString(mPacket));
-        parseICMPv6NeighborDiscoveryOptions(sj);
-    }
-
-    private void parseICMPv6NeighborDiscoveryOptions(StringJoiner sj) {
-        // All ND options are TLV, where T is one byte and L is one byte equal
-        // to the length of T + L + V in units of 8 octets.
-        while (mPacket.remaining() >= ICMPV6_ND_OPTION_MIN_LENGTH) {
-            final int ndType = asUint(mPacket.get());
-            final int ndLength = asUint(mPacket.get());
-            final int ndBytes = ndLength * ICMPV6_ND_OPTION_LENGTH_SCALING_FACTOR - 2;
-            if (ndBytes < 0 || ndBytes > mPacket.remaining()) {
-                sj.add("<malformed>");
-                break;
-            }
-            final int position = mPacket.position();
-
-            switch (ndType) {
-                    case ICMPV6_ND_OPTION_SLLA:
-                        sj.add("slla");
-                        sj.add(getMacAddressString(mPacket));
-                        break;
-                    case ICMPV6_ND_OPTION_TLLA:
-                        sj.add("tlla");
-                        sj.add(getMacAddressString(mPacket));
-                        break;
-                    case ICMPV6_ND_OPTION_MTU:
-                        sj.add("mtu");
-                        final short reserved = mPacket.getShort();
-                        sj.add(asString(mPacket.getInt()));
-                        break;
-                    default:
-                        // Skip.
-                        break;
-            }
-
-            mPacket.position(position + ndBytes);
-        }
-    }
-
-    private void parseUDP(StringJoiner sj) {
-        if (mPacket.remaining() < UDP_HEADER_LEN) {
-            sj.add("runt:").add(asString(mPacket.remaining()));
-            return;
-        }
-
-        final int previous = mPacket.position();
-        final int srcPort = asUint(mPacket.getShort());
-        final int dstPort = asUint(mPacket.getShort());
-        sj.add(asString(srcPort)).add(">").add(asString(dstPort));
-
-        mPacket.position(previous + UDP_HEADER_LEN);
-        if (srcPort == DHCP4_CLIENT_PORT || dstPort == DHCP4_CLIENT_PORT) {
-            sj.add("dhcp4");
-            parseDHCPv4(sj);
-        }
-    }
-
-    private void parseDHCPv4(StringJoiner sj) {
-        final DhcpPacket dhcpPacket;
-        try {
-            dhcpPacket = DhcpPacket.decodeFullPacket(mBytes, mLength, DhcpPacket.ENCAP_L2);
-            sj.add(dhcpPacket.toString());
-        } catch (DhcpPacket.ParseException e) {
-            sj.add("parse error: " + e);
-        }
-    }
-
-    private static String getIPv4AddressString(ByteBuffer ipv4) {
-        return getIpAddressString(ipv4, IPV4_ADDR_LEN);
-    }
-
-    private static String getIPv6AddressString(ByteBuffer ipv6) {
-        return getIpAddressString(ipv6, IPV6_ADDR_LEN);
-    }
-
-    private static String getIpAddressString(ByteBuffer ip, int byteLength) {
-        if (ip == null || ip.remaining() < byteLength) return "invalid";
-
-        byte[] bytes = new byte[byteLength];
-        ip.get(bytes, 0, byteLength);
-        try {
-            InetAddress addr = InetAddress.getByAddress(bytes);
-            return addr.getHostAddress();
-        } catch (UnknownHostException uhe) {
-            return "unknown";
-        }
-    }
-
-    private static String getMacAddressString(ByteBuffer mac) {
-        if (mac == null || mac.remaining() < ETHER_ADDR_LEN) return "invalid";
-
-        byte[] bytes = new byte[ETHER_ADDR_LEN];
-        mac.get(bytes, 0, bytes.length);
-        Object[] printableBytes = new Object[bytes.length];
-        int i = 0;
-        for (byte b : bytes) printableBytes[i++] = new Byte(b);
-
-        final String MAC48_FORMAT = "%02x:%02x:%02x:%02x:%02x:%02x";
-        return String.format(MAC48_FORMAT, printableBytes);
-    }
-
-    /**
-     * Convenience method to convert an int to a String.
-     */
-    public static String asString(int i) {
-        return Integer.toString(i);
-    }
-
-    /**
-     * Convenience method to read a byte as an unsigned int.
-     */
-    public static int asUint(byte b) {
-        return (b & 0xff);
-    }
-
-    /**
-     * Convenience method to read a short as an unsigned int.
-     */
-    public static int asUint(short s) {
-        return (s & 0xffff);
-    }
-}
diff --git a/packages/NetworkStack/src/android/net/util/DataStallUtils.java b/packages/NetworkStack/src/android/net/util/DataStallUtils.java
deleted file mode 100644
index b6dbeb1..0000000
--- a/packages/NetworkStack/src/android/net/util/DataStallUtils.java
+++ /dev/null
@@ -1,72 +0,0 @@
-/*
- * Copyright (C) 2019 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.net.util;
-
-/**
- * Collection of utilities for data stall.
- */
-public class DataStallUtils {
-    /**
-     * Detect data stall via using dns timeout counts.
-     */
-    public static final int DATA_STALL_EVALUATION_TYPE_DNS = 1;
-    // Default configuration values for data stall detection.
-    public static final int DEFAULT_CONSECUTIVE_DNS_TIMEOUT_THRESHOLD = 5;
-    public static final int DEFAULT_DATA_STALL_MIN_EVALUATE_TIME_MS = 60 * 1000;
-    public static final int DEFAULT_DATA_STALL_VALID_DNS_TIME_THRESHOLD_MS = 30 * 60 * 1000;
-    /**
-     * The threshold value for the number of consecutive dns timeout events received to be a
-     * signal of data stall. The number of consecutive timeouts needs to be {@code >=} this
-     * threshold to be considered a data stall. Set the value to {@code <= 0} to disable. Note
-     * that the value should be {@code > 0} if the DNS data stall detection is enabled.
-     *
-     */
-    public static final String CONFIG_DATA_STALL_CONSECUTIVE_DNS_TIMEOUT_THRESHOLD =
-            "data_stall_consecutive_dns_timeout_threshold";
-
-    /**
-     * The minimal time interval in milliseconds for data stall reevaluation.
-     *
-     */
-    public static final String CONFIG_DATA_STALL_MIN_EVALUATE_INTERVAL =
-            "data_stall_min_evaluate_interval";
-
-    /**
-     * DNS timeouts older than this timeout (in milliseconds) are not considered for detecting
-     * a data stall.
-     *
-     */
-    public static final String CONFIG_DATA_STALL_VALID_DNS_TIME_THRESHOLD =
-            "data_stall_valid_dns_time_threshold";
-
-    /**
-     * Which data stall detection signal to use. This is a bitmask constructed by bitwise-or-ing
-     * (i.e. {@code |}) the DATA_STALL_EVALUATION_TYPE_* values.
-     *
-     * Type: int
-     * Valid values:
-     *   {@link #DATA_STALL_EVALUATION_TYPE_DNS} : Use dns as a signal.
-     */
-    public static final String CONFIG_DATA_STALL_EVALUATION_TYPE = "data_stall_evaluation_type";
-    public static final int DEFAULT_DATA_STALL_EVALUATION_TYPES = DATA_STALL_EVALUATION_TYPE_DNS;
-    // The default number of DNS events kept of the log kept for dns signal evaluation. Each event
-    // is represented by a {@link com.android.server.connectivity.NetworkMonitor#DnsResult} objects.
-    // It's also the size of array of {@link com.android.server.connectivity.nano.DnsEvent} kept in
-    // metrics. Note that increasing the size may cause statsd log buffer bust. Need to check the
-    // design in statsd when you try to increase the size.
-    public static final int DEFAULT_DNS_LOG_SIZE = 20;
-}
diff --git a/packages/NetworkStack/src/android/net/util/FdEventsReader.java b/packages/NetworkStack/src/android/net/util/FdEventsReader.java
deleted file mode 100644
index 1380ea7..0000000
--- a/packages/NetworkStack/src/android/net/util/FdEventsReader.java
+++ /dev/null
@@ -1,264 +0,0 @@
-/*
- * Copyright (C) 2016 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.net.util;
-
-import static android.os.MessageQueue.OnFileDescriptorEventListener.EVENT_ERROR;
-import static android.os.MessageQueue.OnFileDescriptorEventListener.EVENT_INPUT;
-
-import android.annotation.NonNull;
-import android.annotation.Nullable;
-import android.os.Handler;
-import android.os.Looper;
-import android.os.MessageQueue;
-import android.system.ErrnoException;
-import android.system.OsConstants;
-
-import java.io.FileDescriptor;
-import java.io.IOException;
-
-
-/**
- * This class encapsulates the mechanics of registering a file descriptor
- * with a thread's Looper and handling read events (and errors).
- *
- * Subclasses MUST implement createFd() and SHOULD override handlePacket(). They MAY override
- * onStop() and onStart().
- *
- * Subclasses can expect a call life-cycle like the following:
- *
- *     [1] when a client calls start(), createFd() is called, followed by the onStart() hook if all
- *         goes well. Implementations may override onStart() for additional initialization.
- *
- *     [2] yield, waiting for read event or error notification:
- *
- *             [a] readPacket() && handlePacket()
- *
- *             [b] if (no error):
- *                     goto 2
- *                 else:
- *                     goto 3
- *
- *     [3] when a client calls stop(), the onStop() hook is called (unless already stopped or never
- *         started). Implementations may override onStop() for additional cleanup.
- *
- * The packet receive buffer is recycled on every read call, so subclasses
- * should make any copies they would like inside their handlePacket()
- * implementation.
- *
- * All public methods MUST only be called from the same thread with which
- * the Handler constructor argument is associated.
- *
- * @param <BufferType> the type of the buffer used to read data.
- * @hide
- */
-public abstract class FdEventsReader<BufferType> {
-    private static final int FD_EVENTS = EVENT_INPUT | EVENT_ERROR;
-    private static final int UNREGISTER_THIS_FD = 0;
-
-    @NonNull
-    private final Handler mHandler;
-    @NonNull
-    private final MessageQueue mQueue;
-    @NonNull
-    private final BufferType mBuffer;
-    @Nullable
-    private FileDescriptor mFd;
-    private long mPacketsReceived;
-
-    protected static void closeFd(FileDescriptor fd) {
-        try {
-            SocketUtils.closeSocket(fd);
-        } catch (IOException ignored) {
-        }
-    }
-
-    protected FdEventsReader(@NonNull Handler h, @NonNull BufferType buffer) {
-        mHandler = h;
-        mQueue = mHandler.getLooper().getQueue();
-        mBuffer = buffer;
-    }
-
-    /** Start this FdEventsReader. */
-    public void start() {
-        if (onCorrectThread()) {
-            createAndRegisterFd();
-        } else {
-            mHandler.post(() -> {
-                logError("start() called from off-thread", null);
-                createAndRegisterFd();
-            });
-        }
-    }
-
-    /** Stop this FdEventsReader and destroy the file descriptor. */
-    public void stop() {
-        if (onCorrectThread()) {
-            unregisterAndDestroyFd();
-        } else {
-            mHandler.post(() -> {
-                logError("stop() called from off-thread", null);
-                unregisterAndDestroyFd();
-            });
-        }
-    }
-
-    @NonNull
-    public Handler getHandler() {
-        return mHandler;
-    }
-
-    protected abstract int recvBufSize(@NonNull BufferType buffer);
-
-    /** Returns the size of the receive buffer. */
-    public int recvBufSize() {
-        return recvBufSize(mBuffer);
-    }
-
-    /**
-     * Get the number of successful calls to {@link #readPacket(FileDescriptor, Object)}.
-     *
-     * <p>A call was successful if {@link #readPacket(FileDescriptor, Object)} returned a value > 0.
-     */
-    public final long numPacketsReceived() {
-        return mPacketsReceived;
-    }
-
-    /**
-     * Subclasses MUST create the listening socket here, including setting all desired socket
-     * options, interface or address/port binding, etc. The socket MUST be created nonblocking.
-     */
-    @Nullable
-    protected abstract FileDescriptor createFd();
-
-    /**
-     * Implementations MUST return the bytes read or throw an Exception.
-     *
-     * <p>The caller may throw a {@link ErrnoException} with {@link OsConstants#EAGAIN} or
-     * {@link OsConstants#EINTR}, in which case {@link FdEventsReader} will ignore the buffer
-     * contents and respectively wait for further input or retry the read immediately. For all other
-     * exceptions, the {@link FdEventsReader} will be stopped with no more interactions with this
-     * method.
-     */
-    protected abstract int readPacket(@NonNull FileDescriptor fd, @NonNull BufferType buffer)
-            throws Exception;
-
-    /**
-     * Called by the main loop for every packet.  Any desired copies of
-     * |recvbuf| should be made in here, as the underlying byte array is
-     * reused across all reads.
-     */
-    protected void handlePacket(@NonNull BufferType recvbuf, int length) {}
-
-    /**
-     * Called by the main loop to log errors.  In some cases |e| may be null.
-     */
-    protected void logError(@NonNull String msg, @Nullable Exception e) {}
-
-    /**
-     * Called by start(), if successful, just prior to returning.
-     */
-    protected void onStart() {}
-
-    /**
-     * Called by stop() just prior to returning.
-     */
-    protected void onStop() {}
-
-    private void createAndRegisterFd() {
-        if (mFd != null) return;
-
-        try {
-            mFd = createFd();
-        } catch (Exception e) {
-            logError("Failed to create socket: ", e);
-            closeFd(mFd);
-            mFd = null;
-        }
-
-        if (mFd == null) return;
-
-        mQueue.addOnFileDescriptorEventListener(
-                mFd,
-                FD_EVENTS,
-                (fd, events) -> {
-                    // Always call handleInput() so read/recvfrom are given
-                    // a proper chance to encounter a meaningful errno and
-                    // perhaps log a useful error message.
-                    if (!isRunning() || !handleInput()) {
-                        unregisterAndDestroyFd();
-                        return UNREGISTER_THIS_FD;
-                    }
-                    return FD_EVENTS;
-                });
-        onStart();
-    }
-
-    private boolean isRunning() {
-        return (mFd != null) && mFd.valid();
-    }
-
-    // Keep trying to read until we get EAGAIN/EWOULDBLOCK or some fatal error.
-    private boolean handleInput() {
-        while (isRunning()) {
-            final int bytesRead;
-
-            try {
-                bytesRead = readPacket(mFd, mBuffer);
-                if (bytesRead < 1) {
-                    if (isRunning()) logError("Socket closed, exiting", null);
-                    break;
-                }
-                mPacketsReceived++;
-            } catch (ErrnoException e) {
-                if (e.errno == OsConstants.EAGAIN) {
-                    // We've read everything there is to read this time around.
-                    return true;
-                } else if (e.errno == OsConstants.EINTR) {
-                    continue;
-                } else {
-                    if (isRunning()) logError("readPacket error: ", e);
-                    break;
-                }
-            } catch (Exception e) {
-                if (isRunning()) logError("readPacket error: ", e);
-                break;
-            }
-
-            try {
-                handlePacket(mBuffer, bytesRead);
-            } catch (Exception e) {
-                logError("handlePacket error: ", e);
-                break;
-            }
-        }
-
-        return false;
-    }
-
-    private void unregisterAndDestroyFd() {
-        if (mFd == null) return;
-
-        mQueue.removeOnFileDescriptorEventListener(mFd);
-        closeFd(mFd);
-        mFd = null;
-        onStop();
-    }
-
-    private boolean onCorrectThread() {
-        return (mHandler.getLooper() == Looper.myLooper());
-    }
-}
diff --git a/packages/NetworkStack/src/android/net/util/NetworkStackUtils.java b/packages/NetworkStack/src/android/net/util/NetworkStackUtils.java
deleted file mode 100644
index 9bf1b96..0000000
--- a/packages/NetworkStack/src/android/net/util/NetworkStackUtils.java
+++ /dev/null
@@ -1,242 +0,0 @@
-/*
- * Copyright (C) 2019 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.net.util;
-
-import android.annotation.NonNull;
-import android.annotation.Nullable;
-import android.provider.DeviceConfig;
-import android.util.SparseArray;
-
-import java.io.FileDescriptor;
-import java.io.IOException;
-import java.net.Inet4Address;
-import java.net.Inet6Address;
-import java.net.InetAddress;
-import java.net.SocketException;
-import java.util.List;
-import java.util.function.Predicate;
-
-/**
- * Collection of utilities for the network stack.
- */
-public class NetworkStackUtils {
-    // TODO: Refer to DeviceConfig definition.
-    public static final String NAMESPACE_CONNECTIVITY = "connectivity";
-
-    /**
-     * A list of captive portal detection specifications used in addition to the fallback URLs.
-     * Each spec has the format url@@/@@statusCodeRegex@@/@@contentRegex. Specs are separated
-     * by "@@,@@".
-     */
-    public static final String CAPTIVE_PORTAL_FALLBACK_PROBE_SPECS =
-            "captive_portal_fallback_probe_specs";
-
-    /**
-     * A comma separated list of URLs used for captive portal detection in addition to the
-     * fallback HTTP url associated with the CAPTIVE_PORTAL_FALLBACK_URL settings.
-     */
-    public static final String CAPTIVE_PORTAL_OTHER_FALLBACK_URLS =
-            "captive_portal_other_fallback_urls";
-
-    /**
-     * Which User-Agent string to use in the header of the captive portal detection probes.
-     * The User-Agent field is unset when this setting has no value (HttpUrlConnection default).
-     */
-    public static final String CAPTIVE_PORTAL_USER_AGENT = "captive_portal_user_agent";
-
-    /**
-     * Whether to use HTTPS for network validation. This is enabled by default and the setting
-     * needs to be set to 0 to disable it. This setting is a misnomer because captive portals
-     * don't actually use HTTPS, but it's consistent with the other settings.
-     */
-    public static final String CAPTIVE_PORTAL_USE_HTTPS = "captive_portal_use_https";
-
-    /**
-     * The URL used for HTTPS captive portal detection upon a new connection.
-     * A 204 response code from the server is used for validation.
-     */
-    public static final String CAPTIVE_PORTAL_HTTPS_URL = "captive_portal_https_url";
-
-    /**
-     * The URL used for HTTP captive portal detection upon a new connection.
-     * A 204 response code from the server is used for validation.
-     */
-    public static final String CAPTIVE_PORTAL_HTTP_URL = "captive_portal_http_url";
-
-    /**
-     * The URL used for fallback HTTP captive portal detection when previous HTTP
-     * and HTTPS captive portal detection attemps did not return a conclusive answer.
-     */
-    public static final String CAPTIVE_PORTAL_FALLBACK_URL = "captive_portal_fallback_url";
-
-    /**
-     * What to do when connecting a network that presents a captive portal.
-     * Must be one of the CAPTIVE_PORTAL_MODE_* constants above.
-     *
-     * The default for this setting is CAPTIVE_PORTAL_MODE_PROMPT.
-     */
-    public static final String CAPTIVE_PORTAL_MODE = "captive_portal_mode";
-
-    /**
-     * Don't attempt to detect captive portals.
-     */
-    public static final int CAPTIVE_PORTAL_MODE_IGNORE = 0;
-
-    /**
-     * When detecting a captive portal, display a notification that
-     * prompts the user to sign in.
-     */
-    public static final int CAPTIVE_PORTAL_MODE_PROMPT = 1;
-
-    /**
-     * When detecting a captive portal, immediately disconnect from the
-     * network and do not reconnect to that network in the future.
-     */
-    public static final int CAPTIVE_PORTAL_MODE_AVOID = 2;
-
-    static {
-        System.loadLibrary("networkstackutilsjni");
-    }
-
-    /**
-     * @return True if the array is null or 0-length.
-     */
-    public static <T> boolean isEmpty(T[] array) {
-        return array == null || array.length == 0;
-    }
-
-    /**
-     * Close a socket, ignoring any exception while closing.
-     */
-    public static void closeSocketQuietly(FileDescriptor fd) {
-        try {
-            SocketUtils.closeSocket(fd);
-        } catch (IOException ignored) {
-        }
-    }
-
-    /**
-     * Returns an int array from the given Integer list.
-     */
-    public static int[] convertToIntArray(@NonNull List<Integer> list) {
-        int[] array = new int[list.size()];
-        for (int i = 0; i < list.size(); i++) {
-            array[i] = list.get(i);
-        }
-        return array;
-    }
-
-    /**
-     * Returns a long array from the given long list.
-     */
-    public static long[] convertToLongArray(@NonNull List<Long> list) {
-        long[] array = new long[list.size()];
-        for (int i = 0; i < list.size(); i++) {
-            array[i] = list.get(i);
-        }
-        return array;
-    }
-
-    /**
-     * @return True if there exists at least one element in the sparse array for which
-     * condition {@code predicate}
-     */
-    public static <T> boolean any(SparseArray<T> array, Predicate<T> predicate) {
-        for (int i = 0; i < array.size(); ++i) {
-            if (predicate.test(array.valueAt(i))) {
-                return true;
-            }
-        }
-        return false;
-    }
-
-    /**
-     * Look up the value of a property for a particular namespace from {@link DeviceConfig}.
-     * @param namespace The namespace containing the property to look up.
-     * @param name The name of the property to look up.
-     * @param defaultValue The value to return if the property does not exist or has no valid value.
-     * @return the corresponding value, or defaultValue if none exists.
-     */
-    @Nullable
-    public static String getDeviceConfigProperty(@NonNull String namespace, @NonNull String name,
-            @Nullable String defaultValue) {
-        String value = DeviceConfig.getProperty(namespace, name);
-        return value != null ? value : defaultValue;
-    }
-
-    /**
-     * Look up the value of a property for a particular namespace from {@link DeviceConfig}.
-     * @param namespace The namespace containing the property to look up.
-     * @param name The name of the property to look up.
-     * @param defaultValue The value to return if the property does not exist or has no non-null
-     *                     value.
-     * @return the corresponding value, or defaultValue if none exists.
-     */
-    public static int getDeviceConfigPropertyInt(@NonNull String namespace, @NonNull String name,
-            int defaultValue) {
-        String value = getDeviceConfigProperty(namespace, name, null /* defaultValue */);
-        try {
-            return (value != null) ? Integer.parseInt(value) : defaultValue;
-        } catch (NumberFormatException e) {
-            return defaultValue;
-        }
-    }
-
-    /**
-     * Attaches a socket filter that accepts DHCP packets to the given socket.
-     */
-    public static native void attachDhcpFilter(FileDescriptor fd) throws SocketException;
-
-    /**
-     * Attaches a socket filter that accepts ICMPv6 router advertisements to the given socket.
-     * @param fd the socket's {@link FileDescriptor}.
-     * @param packetType the hardware address type, one of ARPHRD_*.
-     */
-    public static native void attachRaFilter(FileDescriptor fd, int packetType)
-            throws SocketException;
-
-    /**
-     * Attaches a socket filter that accepts L2-L4 signaling traffic required for IP connectivity.
-     *
-     * This includes: all ARP, ICMPv6 RS/RA/NS/NA messages, and DHCPv4 exchanges.
-     *
-     * @param fd the socket's {@link FileDescriptor}.
-     * @param packetType the hardware address type, one of ARPHRD_*.
-     */
-    public static native void attachControlPacketFilter(FileDescriptor fd, int packetType)
-            throws SocketException;
-
-    /**
-     * Add an entry into the ARP cache.
-     */
-    public static void addArpEntry(Inet4Address ipv4Addr, android.net.MacAddress ethAddr,
-            String ifname, FileDescriptor fd) throws IOException {
-        addArpEntry(ethAddr.toByteArray(), ipv4Addr.getAddress(), ifname, fd);
-    }
-
-    private static native void addArpEntry(byte[] ethAddr, byte[] netAddr, String ifname,
-            FileDescriptor fd) throws IOException;
-
-    /**
-     * Return IP address and port in a string format.
-     */
-    public static String addressAndPortToString(InetAddress address, int port) {
-        return String.format(
-                (address instanceof Inet6Address) ? "[%s]:%d" : "%s:%d",
-                        address.getHostAddress(), port);
-    }
-}
diff --git a/packages/NetworkStack/src/android/net/util/PacketReader.java b/packages/NetworkStack/src/android/net/util/PacketReader.java
deleted file mode 100644
index 4aec6b6..0000000
--- a/packages/NetworkStack/src/android/net/util/PacketReader.java
+++ /dev/null
@@ -1,61 +0,0 @@
-/*
- * Copyright (C) 2018 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.net.util;
-
-import static java.lang.Math.max;
-
-import android.os.Handler;
-import android.system.Os;
-
-import java.io.FileDescriptor;
-
-/**
- * Specialization of {@link FdEventsReader} that reads packets into a byte array.
- *
- * TODO: rename this class to something more correctly descriptive (something
- * like [or less horrible than] FdReadEventsHandler?).
- *
- * @hide
- */
-public abstract class PacketReader extends FdEventsReader<byte[]> {
-
-    public static final int DEFAULT_RECV_BUF_SIZE = 2 * 1024;
-
-    protected PacketReader(Handler h) {
-        this(h, DEFAULT_RECV_BUF_SIZE);
-    }
-
-    protected PacketReader(Handler h, int recvBufSize) {
-        super(h, new byte[max(recvBufSize, DEFAULT_RECV_BUF_SIZE)]);
-    }
-
-    @Override
-    protected final int recvBufSize(byte[] buffer) {
-        return buffer.length;
-    }
-
-    /**
-     * Subclasses MAY override this to change the default read() implementation
-     * in favour of, say, recvfrom().
-     *
-     * Implementations MUST return the bytes read or throw an Exception.
-     */
-    @Override
-    protected int readPacket(FileDescriptor fd, byte[] packetBuffer) throws Exception {
-        return Os.read(fd, packetBuffer, 0, packetBuffer.length);
-    }
-}
diff --git a/packages/NetworkStack/src/android/net/util/SharedLog.java b/packages/NetworkStack/src/android/net/util/SharedLog.java
deleted file mode 100644
index 4fabf10..0000000
--- a/packages/NetworkStack/src/android/net/util/SharedLog.java
+++ /dev/null
@@ -1,201 +0,0 @@
-/*
- * Copyright (C) 2017 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.net.util;
-
-import android.annotation.NonNull;
-import android.annotation.Nullable;
-import android.text.TextUtils;
-import android.util.LocalLog;
-import android.util.Log;
-
-import java.io.FileDescriptor;
-import java.io.PrintWriter;
-import java.util.StringJoiner;
-
-
-/**
- * Class to centralize logging functionality for tethering.
- *
- * All access to class methods other than dump() must be on the same thread.
- *
- * @hide
- */
-public class SharedLog {
-    private static final int DEFAULT_MAX_RECORDS = 500;
-    private static final String COMPONENT_DELIMITER = ".";
-
-    private enum Category {
-        NONE,
-        ERROR,
-        MARK,
-        WARN,
-    };
-
-    private final LocalLog mLocalLog;
-    // The tag to use for output to the system log. This is not output to the
-    // LocalLog because that would be redundant.
-    private final String mTag;
-    // The component (or subcomponent) of a system that is sharing this log.
-    // This can grow in depth if components call forSubComponent() to obtain
-    // their SharedLog instance. The tag is not included in the component for
-    // brevity.
-    private final String mComponent;
-
-    public SharedLog(String tag) {
-        this(DEFAULT_MAX_RECORDS, tag);
-    }
-
-    public SharedLog(int maxRecords, String tag) {
-        this(new LocalLog(maxRecords), tag, tag);
-    }
-
-    private SharedLog(LocalLog localLog, String tag, String component) {
-        mLocalLog = localLog;
-        mTag = tag;
-        mComponent = component;
-    }
-
-    public String getTag() {
-        return mTag;
-    }
-
-    /**
-     * Create a SharedLog based on this log with an additional component prefix on each logged line.
-     */
-    public SharedLog forSubComponent(String component) {
-        if (!isRootLogInstance()) {
-            component = mComponent + COMPONENT_DELIMITER + component;
-        }
-        return new SharedLog(mLocalLog, mTag, component);
-    }
-
-    /**
-     * Dump the contents of this log.
-     *
-     * <p>This method may be called on any thread.
-     */
-    public void dump(FileDescriptor fd, PrintWriter writer, String[] args) {
-        mLocalLog.readOnlyLocalLog().dump(fd, writer, args);
-    }
-
-    //////
-    // Methods that both log an entry and emit it to the system log.
-    //////
-
-    /**
-     * Log an error due to an exception. This does not include the exception stacktrace.
-     *
-     * <p>The log entry will be also added to the system log.
-     * @see #e(String, Throwable)
-     */
-    public void e(Exception e) {
-        Log.e(mTag, record(Category.ERROR, e.toString()));
-    }
-
-    /**
-     * Log an error message.
-     *
-     * <p>The log entry will be also added to the system log.
-     */
-    public void e(String msg) {
-        Log.e(mTag, record(Category.ERROR, msg));
-    }
-
-    /**
-     * Log an error due to an exception, with the exception stacktrace if provided.
-     *
-     * <p>The error and exception message appear in the shared log, but the stacktrace is only
-     * logged in general log output (logcat). The log entry will be also added to the system log.
-     */
-    public void e(@NonNull String msg, @Nullable Throwable exception) {
-        if (exception == null) {
-            e(msg);
-            return;
-        }
-        Log.e(mTag, record(Category.ERROR, msg + ": " + exception.getMessage()), exception);
-    }
-
-    /**
-     * Log an informational message.
-     *
-     * <p>The log entry will be also added to the system log.
-     */
-    public void i(String msg) {
-        Log.i(mTag, record(Category.NONE, msg));
-    }
-
-    /**
-     * Log a warning message.
-     *
-     * <p>The log entry will be also added to the system log.
-     */
-    public void w(String msg) {
-        Log.w(mTag, record(Category.WARN, msg));
-    }
-
-    //////
-    // Methods that only log an entry (and do NOT emit to the system log).
-    //////
-
-    /**
-     * Log a general message to be only included in the in-memory log.
-     *
-     * <p>The log entry will *not* be added to the system log.
-     */
-    public void log(String msg) {
-        record(Category.NONE, msg);
-    }
-
-    /**
-     * Log a general, formatted message to be only included in the in-memory log.
-     *
-     * <p>The log entry will *not* be added to the system log.
-     * @see String#format(String, Object...)
-     */
-    public void logf(String fmt, Object... args) {
-        log(String.format(fmt, args));
-    }
-
-    /**
-     * Log a message with MARK level.
-     *
-     * <p>The log entry will *not* be added to the system log.
-     */
-    public void mark(String msg) {
-        record(Category.MARK, msg);
-    }
-
-    private String record(Category category, String msg) {
-        final String entry = logLine(category, msg);
-        mLocalLog.log(entry);
-        return entry;
-    }
-
-    private String logLine(Category category, String msg) {
-        final StringJoiner sj = new StringJoiner(" ");
-        if (!isRootLogInstance()) sj.add("[" + mComponent + "]");
-        if (category != Category.NONE) sj.add(category.toString());
-        return sj.add(msg).toString();
-    }
-
-    // Check whether this SharedLog instance is nominally the top level in
-    // a potential hierarchy of shared logs (the root of a tree),
-    // or is a subcomponent within the hierarchy.
-    private boolean isRootLogInstance() {
-        return TextUtils.isEmpty(mComponent) || mComponent.equals(mTag);
-    }
-}
diff --git a/packages/NetworkStack/src/android/net/util/Stopwatch.java b/packages/NetworkStack/src/android/net/util/Stopwatch.java
deleted file mode 100644
index c316699..0000000
--- a/packages/NetworkStack/src/android/net/util/Stopwatch.java
+++ /dev/null
@@ -1,83 +0,0 @@
-/*
- * Copyright (C) 2016 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.net.util;
-
-import android.os.SystemClock;
-
-
-/**
- * @hide
- */
-public class Stopwatch {
-    private long mStartTimeMs;
-    private long mStopTimeMs;
-
-    public boolean isStarted() {
-        return (mStartTimeMs > 0);
-    }
-
-    public boolean isStopped() {
-        return (mStopTimeMs > 0);
-    }
-
-    public boolean isRunning() {
-        return (isStarted() && !isStopped());
-    }
-
-    /**
-     * Start the Stopwatch.
-     */
-    public Stopwatch start() {
-        if (!isStarted()) {
-            mStartTimeMs = SystemClock.elapsedRealtime();
-        }
-        return this;
-    }
-
-    /**
-     * Stop the Stopwatch.
-     * @return the total time recorded, in milliseconds, or 0 if not started.
-     */
-    public long stop() {
-        if (isRunning()) {
-            mStopTimeMs = SystemClock.elapsedRealtime();
-        }
-        // Return either the delta after having stopped, or 0.
-        return (mStopTimeMs - mStartTimeMs);
-    }
-
-    /**
-     * Return the total time recorded to date, in milliseconds.
-     * If the Stopwatch is not running, returns the same value as stop(),
-     * i.e. either the total time recorded before stopping or 0.
-     */
-    public long lap() {
-        if (isRunning()) {
-            return (SystemClock.elapsedRealtime() - mStartTimeMs);
-        } else {
-            return stop();
-        }
-    }
-
-    /**
-     * Reset the Stopwatch. It will be stopped when this method returns.
-     */
-    public void reset() {
-        mStartTimeMs = 0;
-        mStopTimeMs = 0;
-    }
-}
diff --git a/packages/NetworkStack/src/com/android/networkstack/metrics/DataStallDetectionStats.java b/packages/NetworkStack/src/com/android/networkstack/metrics/DataStallDetectionStats.java
deleted file mode 100644
index 2523ecd..0000000
--- a/packages/NetworkStack/src/com/android/networkstack/metrics/DataStallDetectionStats.java
+++ /dev/null
@@ -1,228 +0,0 @@
-/*
- * Copyright (C) 2019 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.networkstack.metrics;
-
-import android.annotation.NonNull;
-import android.annotation.Nullable;
-import android.net.util.NetworkStackUtils;
-import android.net.wifi.WifiInfo;
-
-import com.android.internal.util.HexDump;
-import com.android.server.connectivity.nano.CellularData;
-import com.android.server.connectivity.nano.DataStallEventProto;
-import com.android.server.connectivity.nano.DnsEvent;
-import com.android.server.connectivity.nano.WifiData;
-
-import com.google.protobuf.nano.MessageNano;
-
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.List;
-import java.util.Objects;
-
-/**
- * Class to record the stats of detection level information for data stall.
- *
- * @hide
- */
-public final class DataStallDetectionStats {
-    private static final int UNKNOWN_SIGNAL_STRENGTH = -1;
-    @NonNull
-    final byte[] mCellularInfo;
-    @NonNull
-    final byte[] mWifiInfo;
-    @NonNull
-    final byte[] mDns;
-    final int mEvaluationType;
-    final int mNetworkType;
-
-    public DataStallDetectionStats(@Nullable byte[] cell, @Nullable byte[] wifi,
-                @NonNull int[] returnCode, @NonNull long[] dnsTime, int evalType, int netType) {
-        mCellularInfo = emptyCellDataIfNull(cell);
-        mWifiInfo = emptyWifiInfoIfNull(wifi);
-
-        DnsEvent dns = new DnsEvent();
-        dns.dnsReturnCode = returnCode;
-        dns.dnsTime = dnsTime;
-        mDns = MessageNano.toByteArray(dns);
-        mEvaluationType = evalType;
-        mNetworkType = netType;
-    }
-
-    private byte[] emptyCellDataIfNull(@Nullable byte[] cell) {
-        if (cell != null) return cell;
-
-        CellularData data  = new CellularData();
-        data.ratType = DataStallEventProto.RADIO_TECHNOLOGY_UNKNOWN;
-        data.networkMccmnc = "";
-        data.simMccmnc = "";
-        data.signalStrength = UNKNOWN_SIGNAL_STRENGTH;
-        return MessageNano.toByteArray(data);
-    }
-
-    private byte[] emptyWifiInfoIfNull(@Nullable byte[] wifi) {
-        if (wifi != null) return wifi;
-
-        WifiData data = new WifiData();
-        data.wifiBand = DataStallEventProto.AP_BAND_UNKNOWN;
-        data.signalStrength = UNKNOWN_SIGNAL_STRENGTH;
-        return MessageNano.toByteArray(data);
-    }
-
-    @Override
-    public String toString() {
-        StringBuilder sb = new StringBuilder();
-        sb.append("type: ").append(mNetworkType)
-          .append(", evaluation type: ")
-          .append(mEvaluationType)
-          .append(", wifi info: ")
-          .append(HexDump.toHexString(mWifiInfo))
-          .append(", cell info: ")
-          .append(HexDump.toHexString(mCellularInfo))
-          .append(", dns: ")
-          .append(HexDump.toHexString(mDns));
-        return sb.toString();
-    }
-
-    @Override
-    public boolean equals(@Nullable final Object o) {
-        if (!(o instanceof DataStallDetectionStats)) return false;
-        final DataStallDetectionStats other = (DataStallDetectionStats) o;
-        return (mNetworkType == other.mNetworkType)
-            && (mEvaluationType == other.mEvaluationType)
-            && Arrays.equals(mWifiInfo, other.mWifiInfo)
-            && Arrays.equals(mCellularInfo, other.mCellularInfo)
-            && Arrays.equals(mDns, other.mDns);
-    }
-
-    @Override
-    public int hashCode() {
-        return Objects.hash(mNetworkType, mEvaluationType, mWifiInfo, mCellularInfo, mDns);
-    }
-
-    /**
-     * Utility to create an instance of {@Link DataStallDetectionStats}
-     *
-     * @hide
-     */
-    public static class Builder {
-        @Nullable
-        private byte[] mCellularInfo;
-        @Nullable
-        private byte[] mWifiInfo;
-        @NonNull
-        private final List<Integer> mDnsReturnCode = new ArrayList<Integer>();
-        @NonNull
-        private final List<Long> mDnsTimeStamp = new ArrayList<Long>();
-        private int mEvaluationType;
-        private int mNetworkType;
-
-        /**
-         * Add a dns event into Builder.
-         *
-         * @param code the return code of the dns event.
-         * @param timeMs the elapsedRealtime in ms that the the dns event was received from netd.
-         * @return {@code this} {@link Builder} instance.
-         */
-        public Builder addDnsEvent(int code, long timeMs) {
-            mDnsReturnCode.add(code);
-            mDnsTimeStamp.add(timeMs);
-            return this;
-        }
-
-        /**
-         * Set the dns evaluation type into Builder.
-         *
-         * @param type the return code of the dns event.
-         * @return {@code this} {@link Builder} instance.
-         */
-        public Builder setEvaluationType(int type) {
-            mEvaluationType = type;
-            return this;
-        }
-
-        /**
-         * Set the network type into Builder.
-         *
-         * @param type the network type of the logged network.
-         * @return {@code this} {@link Builder} instance.
-         */
-        public Builder setNetworkType(int type) {
-            mNetworkType = type;
-            return this;
-        }
-
-        /**
-         * Set the wifi data into Builder.
-         *
-         * @param info a {@link WifiInfo} of the connected wifi network.
-         * @return {@code this} {@link Builder} instance.
-         */
-        public Builder setWiFiData(@Nullable final WifiInfo info) {
-            WifiData data = new WifiData();
-            data.wifiBand = getWifiBand(info);
-            data.signalStrength = (info != null) ? info.getRssi() : UNKNOWN_SIGNAL_STRENGTH;
-            mWifiInfo = MessageNano.toByteArray(data);
-            return this;
-        }
-
-        private static int getWifiBand(@Nullable final WifiInfo info) {
-            if (info == null) return DataStallEventProto.AP_BAND_UNKNOWN;
-
-            int freq = info.getFrequency();
-            // Refer to ScanResult.is5GHz() and ScanResult.is24GHz().
-            if (freq > 4900 && freq < 5900) {
-                return DataStallEventProto.AP_BAND_5GHZ;
-            } else if (freq > 2400 && freq < 2500) {
-                return DataStallEventProto.AP_BAND_2GHZ;
-            } else {
-                return DataStallEventProto.AP_BAND_UNKNOWN;
-            }
-        }
-
-        /**
-         * Set the cellular data into Builder.
-         *
-         * @param radioType the radio technology of the logged cellular network.
-         * @param roaming a boolean indicates if logged cellular network is roaming or not.
-         * @param networkMccmnc the mccmnc of the camped network.
-         * @param simMccmnc the mccmnc of the sim.
-         * @return {@code this} {@link Builder} instance.
-         */
-        public Builder setCellData(int radioType, boolean roaming,
-                @NonNull String networkMccmnc, @NonNull String simMccmnc, int ss) {
-            CellularData data  = new CellularData();
-            data.ratType = radioType;
-            data.isRoaming = roaming;
-            data.networkMccmnc = networkMccmnc;
-            data.simMccmnc = simMccmnc;
-            data.signalStrength = ss;
-            mCellularInfo = MessageNano.toByteArray(data);
-            return this;
-        }
-
-        /**
-         * Create a new {@Link DataStallDetectionStats}.
-         */
-        public DataStallDetectionStats build() {
-            return new DataStallDetectionStats(mCellularInfo, mWifiInfo,
-                    NetworkStackUtils.convertToIntArray(mDnsReturnCode),
-                    NetworkStackUtils.convertToLongArray(mDnsTimeStamp),
-                    mEvaluationType, mNetworkType);
-        }
-    }
-}
diff --git a/packages/NetworkStack/src/com/android/networkstack/metrics/DataStallStatsUtils.java b/packages/NetworkStack/src/com/android/networkstack/metrics/DataStallStatsUtils.java
deleted file mode 100644
index 9308901..0000000
--- a/packages/NetworkStack/src/com/android/networkstack/metrics/DataStallStatsUtils.java
+++ /dev/null
@@ -1,73 +0,0 @@
-/*
- * Copyright (C) 2019 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.networkstack.metrics;
-
-import android.annotation.NonNull;
-import android.annotation.Nullable;
-import android.net.captiveportal.CaptivePortalProbeResult;
-import android.util.Log;
-
-import com.android.internal.util.HexDump;
-import com.android.server.connectivity.nano.DataStallEventProto;
-
-/**
- * Collection of utilities for data stall metrics.
- *
- * To see if the logs are properly sent to statsd, execute following command.
- *
- * $ adb shell cmd stats print-logs
- * $ adb logcat | grep statsd  OR $ adb logcat -b stats
- *
- * @hide
- */
-public class DataStallStatsUtils {
-    private static final String TAG = DataStallStatsUtils.class.getSimpleName();
-    private static final boolean DBG = false;
-
-    private static int probeResultToEnum(@Nullable final CaptivePortalProbeResult result) {
-        if (result == null) return DataStallEventProto.INVALID;
-
-        if (result.isSuccessful()) {
-            return DataStallEventProto.VALID;
-        } else if (result.isPortal()) {
-            return DataStallEventProto.PORTAL;
-        } else if (result.isPartialConnectivity()) {
-            return DataStallEventProto.PARTIAL;
-        } else {
-            return DataStallEventProto.INVALID;
-        }
-    }
-
-    /**
-     * Write the metric to {@link StatsLog}.
-     */
-    public static void write(@NonNull final DataStallDetectionStats stats,
-            @NonNull final CaptivePortalProbeResult result) {
-        int validationResult = probeResultToEnum(result);
-        if (DBG) {
-            Log.d(TAG, "write: " + stats + " with result: " + validationResult
-                    + ", dns: " + HexDump.toHexString(stats.mDns));
-        }
-        NetworkStackStatsLog.write(NetworkStackStatsLog.DATA_STALL_EVENT,
-                stats.mEvaluationType,
-                validationResult,
-                stats.mNetworkType,
-                stats.mWifiInfo,
-                stats.mCellularInfo,
-                stats.mDns);
-    }
-}
diff --git a/packages/NetworkStack/src/com/android/networkstack/util/DnsUtils.java b/packages/NetworkStack/src/com/android/networkstack/util/DnsUtils.java
deleted file mode 100644
index 4767d55..0000000
--- a/packages/NetworkStack/src/com/android/networkstack/util/DnsUtils.java
+++ /dev/null
@@ -1,130 +0,0 @@
-/*
- * Copyright (C) 2019 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.networkstack.util;
-
-import static android.net.DnsResolver.FLAG_NO_CACHE_LOOKUP;
-import static android.net.DnsResolver.TYPE_A;
-import static android.net.DnsResolver.TYPE_AAAA;
-
-import android.annotation.NonNull;
-import android.net.DnsResolver;
-import android.net.Network;
-import android.net.TrafficStats;
-import android.util.Log;
-
-import com.android.internal.util.TrafficStatsConstants;
-
-import java.net.InetAddress;
-import java.net.UnknownHostException;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.List;
-import java.util.concurrent.CountDownLatch;
-import java.util.concurrent.TimeUnit;
-import java.util.concurrent.atomic.AtomicReference;
-
-/**
- * Collection of utilities for dns query.
- */
-public class DnsUtils {
-    // Decide what queries to make depending on what IP addresses are on the system.
-    public static final int TYPE_ADDRCONFIG = -1;
-    private static final String TAG = DnsUtils.class.getSimpleName();
-
-    /**
-     * Return both A and AAAA query results regardless the ip address type of the giving network.
-     * Used for probing in NetworkMonitor.
-     */
-    @NonNull
-    public static InetAddress[] getAllByName(@NonNull final DnsResolver dnsResolver,
-            @NonNull final Network network, @NonNull String host, int timeout)
-            throws UnknownHostException {
-        final List<InetAddress> result = new ArrayList<InetAddress>();
-
-        try {
-            result.addAll(Arrays.asList(
-                    getAllByName(dnsResolver, network, host, TYPE_AAAA, FLAG_NO_CACHE_LOOKUP,
-                    timeout)));
-        } catch (UnknownHostException e) {
-            // Might happen if the host is v4-only, still need to query TYPE_A
-        }
-        try {
-            result.addAll(Arrays.asList(
-                    getAllByName(dnsResolver, network, host, TYPE_A, FLAG_NO_CACHE_LOOKUP,
-                    timeout)));
-        } catch (UnknownHostException e) {
-            // Might happen if the host is v6-only, still need to return AAAA answers
-        }
-        if (result.size() == 0) {
-            throw new UnknownHostException(host);
-        }
-        return result.toArray(new InetAddress[0]);
-    }
-
-    /**
-     * Return dns query result based on the given QueryType(TYPE_A, TYPE_AAAA) or TYPE_ADDRCONFIG.
-     * Used for probing in NetworkMonitor.
-     */
-    @NonNull
-    public static InetAddress[] getAllByName(@NonNull final DnsResolver dnsResolver,
-            @NonNull final Network network, @NonNull final String host, int type, int flag,
-            int timeoutMs) throws UnknownHostException {
-        final CountDownLatch latch = new CountDownLatch(1);
-        final AtomicReference<List<InetAddress>> resultRef = new AtomicReference<>();
-
-        final DnsResolver.Callback<List<InetAddress>> callback =
-                new DnsResolver.Callback<List<InetAddress>>() {
-            @Override
-            public void onAnswer(List<InetAddress> answer, int rcode) {
-                if (rcode == 0) {
-                    resultRef.set(answer);
-                }
-                latch.countDown();
-            }
-
-            @Override
-            public void onError(@NonNull DnsResolver.DnsException e) {
-                Log.d(TAG, "DNS error resolving " + host + ": " + e.getMessage());
-                latch.countDown();
-            }
-        };
-        final int oldTag = TrafficStats.getAndSetThreadStatsTag(
-                TrafficStatsConstants.TAG_SYSTEM_PROBE);
-
-        if (type == TYPE_ADDRCONFIG) {
-            dnsResolver.query(network, host, flag, r -> r.run(), null /* cancellationSignal */,
-                    callback);
-        } else {
-            dnsResolver.query(network, host, type, flag, r -> r.run(),
-                    null /* cancellationSignal */, callback);
-        }
-
-        TrafficStats.setThreadStatsTag(oldTag);
-
-        try {
-            latch.await(timeoutMs, TimeUnit.MILLISECONDS);
-        } catch (InterruptedException e) {
-        }
-
-        final List<InetAddress> result = resultRef.get();
-        if (result == null || result.size() == 0) {
-            throw new UnknownHostException(host);
-        }
-
-        return result.toArray(new InetAddress[0]);
-    }
-}
diff --git a/packages/NetworkStack/src/com/android/server/NetworkObserver.java b/packages/NetworkStack/src/com/android/server/NetworkObserver.java
deleted file mode 100644
index cccec0b..0000000
--- a/packages/NetworkStack/src/com/android/server/NetworkObserver.java
+++ /dev/null
@@ -1,88 +0,0 @@
-/*
- * Copyright (C) 2019 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.server;
-
-import android.net.LinkAddress;
-import android.net.RouteInfo;
-
-/**
- * Observer for network events, to use with {@link NetworkObserverRegistry}.
- */
-public interface NetworkObserver {
-
-    /**
-     * @see android.net.INetdUnsolicitedEventListener#onInterfaceChanged(java.lang.String, boolean)
-     */
-    default void onInterfaceChanged(String ifName, boolean up) {}
-
-    /**
-     * @see android.net.INetdUnsolicitedEventListener#onInterfaceRemoved(String)
-     */
-    default void onInterfaceRemoved(String ifName) {}
-
-    /**
-     * @see android.net.INetdUnsolicitedEventListener
-     *          #onInterfaceAddressUpdated(String, String, int, int)
-     */
-    default void onInterfaceAddressUpdated(LinkAddress address, String ifName) {}
-
-    /**
-     * @see android.net.INetdUnsolicitedEventListener
-     *          #onInterfaceAddressRemoved(String, String, int, int)
-     */
-    default void onInterfaceAddressRemoved(LinkAddress address, String ifName) {}
-
-    /**
-     * @see android.net.INetdUnsolicitedEventListener#onInterfaceLinkStateChanged(String, boolean)
-     */
-    default void onInterfaceLinkStateChanged(String ifName, boolean up) {}
-
-    /**
-     * @see android.net.INetdUnsolicitedEventListener#onInterfaceAdded(String)
-     */
-    default void onInterfaceAdded(String ifName) {}
-
-    /**
-     * @see android.net.INetdUnsolicitedEventListener
-     *          #onInterfaceClassActivityChanged(boolean, int, long, int)
-     */
-    default void onInterfaceClassActivityChanged(
-            boolean isActive, int label, long timestamp, int uid) {}
-
-    /**
-     * @see android.net.INetdUnsolicitedEventListener#onQuotaLimitReached(String, String)
-     */
-    default void onQuotaLimitReached(String alertName, String ifName) {}
-
-    /**
-     * @see android.net.INetdUnsolicitedEventListener
-     *          #onInterfaceDnsServerInfo(String, long, String[])
-     */
-    default void onInterfaceDnsServerInfo(String ifName, long lifetime, String[] servers) {}
-
-    /**
-     * @see android.net.INetdUnsolicitedEventListener
-     *          #onRouteChanged(boolean, String, String, String)
-     */
-    default void onRouteUpdated(RouteInfo route) {}
-
-    /**
-     * @see android.net.INetdUnsolicitedEventListener
-     *          #onRouteChanged(boolean, String, String, String)
-     */
-    default void onRouteRemoved(RouteInfo route) {}
-}
diff --git a/packages/NetworkStack/src/com/android/server/NetworkObserverRegistry.java b/packages/NetworkStack/src/com/android/server/NetworkObserverRegistry.java
deleted file mode 100644
index afe166b..0000000
--- a/packages/NetworkStack/src/com/android/server/NetworkObserverRegistry.java
+++ /dev/null
@@ -1,189 +0,0 @@
-/*
- * Copyright (C) 2019 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package com.android.server;
-
-import static android.net.RouteInfo.RTN_UNICAST;
-
-import android.annotation.NonNull;
-import android.net.INetd;
-import android.net.INetdUnsolicitedEventListener;
-import android.net.InetAddresses;
-import android.net.IpPrefix;
-import android.net.LinkAddress;
-import android.net.RouteInfo;
-import android.os.Handler;
-import android.os.RemoteException;
-import android.util.Log;
-
-import java.util.Map;
-import java.util.Optional;
-import java.util.concurrent.ConcurrentHashMap;
-
-/**
- * A class for reporting network events to clients.
- *
- * Implements INetdUnsolicitedEventListener and registers with netd, and relays those events to
- * all INetworkManagementEventObserver objects that have registered with it.
- */
-public class NetworkObserverRegistry extends INetdUnsolicitedEventListener.Stub {
-    private static final String TAG = NetworkObserverRegistry.class.getSimpleName();
-
-    /**
-     * Constructs a new NetworkObserverRegistry.
-     *
-     * <p>Only one registry should be used per process since netd will silently ignore multiple
-     * registrations from the same process.
-     */
-    NetworkObserverRegistry() {}
-
-    /**
-     * Start listening for Netd events.
-     *
-     * <p>This should be called before allowing any observer to be registered.
-     */
-    void register(@NonNull INetd netd) throws RemoteException {
-        netd.registerUnsolicitedEventListener(this);
-    }
-
-    private final ConcurrentHashMap<NetworkObserver, Optional<Handler>> mObservers =
-            new ConcurrentHashMap<>();
-
-    /**
-     * Registers the specified observer and start sending callbacks to it.
-     * This method may be called on any thread.
-     */
-    public void registerObserver(@NonNull NetworkObserver observer, @NonNull Handler handler) {
-        if (handler == null) {
-            throw new IllegalArgumentException("handler must be non-null");
-        }
-        mObservers.put(observer, Optional.of(handler));
-    }
-
-    /**
-     * Registers the specified observer, and start sending callbacks to it.
-     *
-     * <p>This method must only be called with callbacks that are nonblocking, such as callbacks
-     * that only send a message to a StateMachine.
-     */
-    public void registerObserverForNonblockingCallback(@NonNull NetworkObserver observer) {
-        mObservers.put(observer, Optional.empty());
-    }
-
-    /**
-     * Unregisters the specified observer and stop sending callbacks to it.
-     * This method may be called on any thread.
-     */
-    public void unregisterObserver(@NonNull NetworkObserver observer) {
-        mObservers.remove(observer);
-    }
-
-    @FunctionalInterface
-    private interface NetworkObserverEventCallback {
-        void sendCallback(NetworkObserver o);
-    }
-
-    private void invokeForAllObservers(@NonNull final NetworkObserverEventCallback callback) {
-        // ConcurrentHashMap#entrySet is weakly consistent: observers that were in the map before
-        // creation will be processed, those added during traversal may or may not.
-        for (Map.Entry<NetworkObserver, Optional<Handler>> entry : mObservers.entrySet()) {
-            final NetworkObserver observer = entry.getKey();
-            final Optional<Handler> handler = entry.getValue();
-            if (handler.isPresent()) {
-                handler.get().post(() -> callback.sendCallback(observer));
-                return;
-            }
-
-            try {
-                callback.sendCallback(observer);
-            } catch (RuntimeException e) {
-                Log.e(TAG, "Error sending callback to observer", e);
-            }
-        }
-    }
-
-    @Override
-    public void onInterfaceClassActivityChanged(boolean isActive,
-            int label, long timestamp, int uid) {
-        invokeForAllObservers(o -> o.onInterfaceClassActivityChanged(
-                isActive, label, timestamp, uid));
-    }
-
-    /**
-     * Notify our observers of a limit reached.
-     */
-    @Override
-    public void onQuotaLimitReached(String alertName, String ifName) {
-        invokeForAllObservers(o -> o.onQuotaLimitReached(alertName, ifName));
-    }
-
-    @Override
-    public void onInterfaceDnsServerInfo(String ifName, long lifetime, String[] servers) {
-        invokeForAllObservers(o -> o.onInterfaceDnsServerInfo(ifName, lifetime, servers));
-    }
-
-    @Override
-    public void onInterfaceAddressUpdated(String addr, String ifName, int flags, int scope) {
-        final LinkAddress address = new LinkAddress(addr, flags, scope);
-        invokeForAllObservers(o -> o.onInterfaceAddressUpdated(address, ifName));
-    }
-
-    @Override
-    public void onInterfaceAddressRemoved(String addr,
-            String ifName, int flags, int scope) {
-        final LinkAddress address = new LinkAddress(addr, flags, scope);
-        invokeForAllObservers(o -> o.onInterfaceAddressRemoved(address, ifName));
-    }
-
-    @Override
-    public void onInterfaceAdded(String ifName) {
-        invokeForAllObservers(o -> o.onInterfaceAdded(ifName));
-    }
-
-    @Override
-    public void onInterfaceRemoved(String ifName) {
-        invokeForAllObservers(o -> o.onInterfaceRemoved(ifName));
-    }
-
-    @Override
-    public void onInterfaceChanged(String ifName, boolean up) {
-        invokeForAllObservers(o -> o.onInterfaceChanged(ifName, up));
-    }
-
-    @Override
-    public void onInterfaceLinkStateChanged(String ifName, boolean up) {
-        invokeForAllObservers(o -> o.onInterfaceLinkStateChanged(ifName, up));
-    }
-
-    @Override
-    public void onRouteChanged(boolean updated, String route, String gateway, String ifName) {
-        final RouteInfo processRoute = new RouteInfo(new IpPrefix(route),
-                ("".equals(gateway)) ? null : InetAddresses.parseNumericAddress(gateway),
-                ifName, RTN_UNICAST);
-        if (updated) {
-            invokeForAllObservers(o -> o.onRouteUpdated(processRoute));
-        } else {
-            invokeForAllObservers(o -> o.onRouteRemoved(processRoute));
-        }
-    }
-
-    @Override
-    public void onStrictCleartextDetected(int uid, String hex) {}
-
-    @Override
-    public int getInterfaceVersion() {
-        return INetdUnsolicitedEventListener.VERSION;
-    }
-}
diff --git a/packages/NetworkStack/src/com/android/server/NetworkStackService.java b/packages/NetworkStack/src/com/android/server/NetworkStackService.java
deleted file mode 100644
index 9bf4457..0000000
--- a/packages/NetworkStack/src/com/android/server/NetworkStackService.java
+++ /dev/null
@@ -1,389 +0,0 @@
-/*
- * Copyright (C) 2018 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.server;
-
-import static android.net.dhcp.IDhcpServer.STATUS_INVALID_ARGUMENT;
-import static android.net.dhcp.IDhcpServer.STATUS_SUCCESS;
-import static android.net.dhcp.IDhcpServer.STATUS_UNKNOWN_ERROR;
-
-import static com.android.server.util.PermissionUtil.checkDumpPermission;
-import static com.android.server.util.PermissionUtil.checkNetworkStackCallingPermission;
-
-import android.annotation.NonNull;
-import android.annotation.Nullable;
-import android.app.Service;
-import android.content.Context;
-import android.content.Intent;
-import android.net.ConnectivityManager;
-import android.net.IIpMemoryStore;
-import android.net.IIpMemoryStoreCallbacks;
-import android.net.INetd;
-import android.net.INetworkMonitor;
-import android.net.INetworkMonitorCallbacks;
-import android.net.INetworkStackConnector;
-import android.net.LinkProperties;
-import android.net.Network;
-import android.net.NetworkCapabilities;
-import android.net.PrivateDnsConfigParcel;
-import android.net.dhcp.DhcpServer;
-import android.net.dhcp.DhcpServingParams;
-import android.net.dhcp.DhcpServingParamsParcel;
-import android.net.dhcp.IDhcpServerCallbacks;
-import android.net.ip.IIpClientCallbacks;
-import android.net.ip.IpClient;
-import android.net.shared.PrivateDnsConfig;
-import android.net.util.SharedLog;
-import android.os.IBinder;
-import android.os.RemoteException;
-import android.util.ArraySet;
-
-import com.android.internal.annotations.GuardedBy;
-import com.android.internal.util.IndentingPrintWriter;
-import com.android.server.connectivity.NetworkMonitor;
-import com.android.server.connectivity.ipmemorystore.IpMemoryStoreService;
-
-import java.io.FileDescriptor;
-import java.io.PrintWriter;
-import java.lang.ref.WeakReference;
-import java.util.ArrayDeque;
-import java.util.ArrayList;
-import java.util.HashSet;
-import java.util.Iterator;
-
-/**
- * Android service used to start the network stack when bound to via an intent.
- *
- * <p>The service returns a binder for the system server to communicate with the network stack.
- */
-public class NetworkStackService extends Service {
-    private static final String TAG = NetworkStackService.class.getSimpleName();
-    private static NetworkStackConnector sConnector;
-
-    /**
-     * Create a binder connector for the system server to communicate with the network stack.
-     *
-     * <p>On platforms where the network stack runs in the system server process, this method may
-     * be called directly instead of obtaining the connector by binding to the service.
-     */
-    public static synchronized IBinder makeConnector(Context context) {
-        if (sConnector == null) {
-            sConnector = new NetworkStackConnector(context);
-        }
-        return sConnector;
-    }
-
-    @NonNull
-    @Override
-    public IBinder onBind(Intent intent) {
-        return makeConnector(this);
-    }
-
-    /**
-     * An interface for internal clients of the network stack service that can return
-     * or create inline instances of the service it manages.
-     */
-    public interface NetworkStackServiceManager {
-        /**
-         * Get an instance of the IpMemoryStoreService.
-         */
-        IIpMemoryStore getIpMemoryStoreService();
-    }
-
-    private static class NetworkStackConnector extends INetworkStackConnector.Stub
-            implements NetworkStackServiceManager {
-        private static final int NUM_VALIDATION_LOG_LINES = 20;
-        private final Context mContext;
-        private final INetd mNetd;
-        private final NetworkObserverRegistry mObserverRegistry;
-        private final ConnectivityManager mCm;
-        @GuardedBy("mIpClients")
-        private final ArrayList<WeakReference<IpClient>> mIpClients = new ArrayList<>();
-        private final IpMemoryStoreService mIpMemoryStoreService;
-
-        private static final int MAX_VALIDATION_LOGS = 10;
-        @GuardedBy("mValidationLogs")
-        private final ArrayDeque<SharedLog> mValidationLogs = new ArrayDeque<>(MAX_VALIDATION_LOGS);
-
-        private static final String DUMPSYS_ARG_VERSION = "version";
-
-        /** Version of the framework AIDL interfaces observed. Should hold only one value. */
-        @GuardedBy("mFrameworkAidlVersions")
-        private final ArraySet<Integer> mFrameworkAidlVersions = new ArraySet<>(1);
-        private final int mNetdAidlVersion;
-
-        private SharedLog addValidationLogs(Network network, String name) {
-            final SharedLog log = new SharedLog(NUM_VALIDATION_LOG_LINES, network + " - " + name);
-            synchronized (mValidationLogs) {
-                while (mValidationLogs.size() >= MAX_VALIDATION_LOGS) {
-                    mValidationLogs.removeLast();
-                }
-                mValidationLogs.addFirst(log);
-            }
-            return log;
-        }
-
-        NetworkStackConnector(Context context) {
-            mContext = context;
-            mNetd = INetd.Stub.asInterface(
-                    (IBinder) context.getSystemService(Context.NETD_SERVICE));
-            mObserverRegistry = new NetworkObserverRegistry();
-            mCm = context.getSystemService(ConnectivityManager.class);
-            mIpMemoryStoreService = new IpMemoryStoreService(context);
-
-            int netdVersion;
-            try {
-                netdVersion = mNetd.getInterfaceVersion();
-            } catch (RemoteException e) {
-                mLog.e("Error obtaining INetd version", e);
-                netdVersion = -1;
-            }
-            mNetdAidlVersion = netdVersion;
-
-            try {
-                mObserverRegistry.register(mNetd);
-            } catch (RemoteException e) {
-                mLog.e("Error registering observer on Netd", e);
-            }
-        }
-
-        private void updateSystemAidlVersion(final int version) {
-            synchronized (mFrameworkAidlVersions) {
-                mFrameworkAidlVersions.add(version);
-            }
-        }
-
-        @NonNull
-        private final SharedLog mLog = new SharedLog(TAG);
-
-        @Override
-        public void makeDhcpServer(@NonNull String ifName, @NonNull DhcpServingParamsParcel params,
-                @NonNull IDhcpServerCallbacks cb) throws RemoteException {
-            checkNetworkStackCallingPermission();
-            updateSystemAidlVersion(cb.getInterfaceVersion());
-            final DhcpServer server;
-            try {
-                server = new DhcpServer(
-                        ifName,
-                        DhcpServingParams.fromParcelableObject(params),
-                        mLog.forSubComponent(ifName + ".DHCP"));
-            } catch (DhcpServingParams.InvalidParameterException e) {
-                mLog.e("Invalid DhcpServingParams", e);
-                cb.onDhcpServerCreated(STATUS_INVALID_ARGUMENT, null);
-                return;
-            } catch (Exception e) {
-                mLog.e("Unknown error starting DhcpServer", e);
-                cb.onDhcpServerCreated(STATUS_UNKNOWN_ERROR, null);
-                return;
-            }
-            cb.onDhcpServerCreated(STATUS_SUCCESS, server);
-        }
-
-        @Override
-        public void makeNetworkMonitor(Network network, String name, INetworkMonitorCallbacks cb)
-                throws RemoteException {
-            checkNetworkStackCallingPermission();
-            updateSystemAidlVersion(cb.getInterfaceVersion());
-            final SharedLog log = addValidationLogs(network, name);
-            final NetworkMonitor nm = new NetworkMonitor(mContext, cb, network, log);
-            cb.onNetworkMonitorCreated(new NetworkMonitorImpl(nm));
-        }
-
-        @Override
-        public void makeIpClient(String ifName, IIpClientCallbacks cb) throws RemoteException {
-            checkNetworkStackCallingPermission();
-            updateSystemAidlVersion(cb.getInterfaceVersion());
-            final IpClient ipClient = new IpClient(mContext, ifName, cb, mObserverRegistry, this);
-
-            synchronized (mIpClients) {
-                final Iterator<WeakReference<IpClient>> it = mIpClients.iterator();
-                while (it.hasNext()) {
-                    final IpClient ipc = it.next().get();
-                    if (ipc == null) {
-                        it.remove();
-                    }
-                }
-                mIpClients.add(new WeakReference<>(ipClient));
-            }
-
-            cb.onIpClientCreated(ipClient.makeConnector());
-        }
-
-        @Override
-        public IIpMemoryStore getIpMemoryStoreService() {
-            return mIpMemoryStoreService;
-        }
-
-        @Override
-        public void fetchIpMemoryStore(@NonNull final IIpMemoryStoreCallbacks cb)
-                throws RemoteException {
-            checkNetworkStackCallingPermission();
-            updateSystemAidlVersion(cb.getInterfaceVersion());
-            cb.onIpMemoryStoreFetched(mIpMemoryStoreService);
-        }
-
-        @Override
-        protected void dump(@NonNull FileDescriptor fd, @NonNull PrintWriter fout,
-                @Nullable String[] args) {
-            checkDumpPermission();
-
-            final IndentingPrintWriter pw = new IndentingPrintWriter(fout, "  ");
-            pw.println("NetworkStack version:");
-            dumpVersion(pw);
-            pw.println();
-
-            if (args != null && args.length >= 1 && DUMPSYS_ARG_VERSION.equals(args[0])) {
-                return;
-            }
-
-            pw.println("NetworkStack logs:");
-            mLog.dump(fd, pw, args);
-
-            // Dump full IpClient logs for non-GCed clients
-            pw.println();
-            pw.println("Recently active IpClient logs:");
-            final ArrayList<IpClient> ipClients = new ArrayList<>();
-            final HashSet<String> dumpedIpClientIfaces = new HashSet<>();
-            synchronized (mIpClients) {
-                for (WeakReference<IpClient> ipcRef : mIpClients) {
-                    final IpClient ipc = ipcRef.get();
-                    if (ipc != null) {
-                        ipClients.add(ipc);
-                    }
-                }
-            }
-
-            for (IpClient ipc : ipClients) {
-                pw.println(ipc.getName());
-                pw.increaseIndent();
-                ipc.dump(fd, pw, args);
-                pw.decreaseIndent();
-                dumpedIpClientIfaces.add(ipc.getInterfaceName());
-            }
-
-            // State machine and connectivity metrics logs are kept for GCed IpClients
-            pw.println();
-            pw.println("Other IpClient logs:");
-            IpClient.dumpAllLogs(fout, dumpedIpClientIfaces);
-
-            pw.println();
-            pw.println("Validation logs (most recent first):");
-            synchronized (mValidationLogs) {
-                for (SharedLog p : mValidationLogs) {
-                    pw.println(p.getTag());
-                    pw.increaseIndent();
-                    p.dump(fd, pw, args);
-                    pw.decreaseIndent();
-                }
-            }
-        }
-
-        /**
-         * Dump version information of the module and detected system version.
-         */
-        private void dumpVersion(@NonNull PrintWriter fout) {
-            fout.println("NetworkStackConnector: " + this.VERSION);
-            synchronized (mFrameworkAidlVersions) {
-                fout.println("SystemServer: " + mFrameworkAidlVersions);
-            }
-            fout.println("Netd: " + mNetdAidlVersion);
-        }
-
-        @Override
-        public int getInterfaceVersion() {
-            return this.VERSION;
-        }
-    }
-
-    private static class NetworkMonitorImpl extends INetworkMonitor.Stub {
-        private final NetworkMonitor mNm;
-
-        NetworkMonitorImpl(NetworkMonitor nm) {
-            mNm = nm;
-        }
-
-        @Override
-        public void start() {
-            checkNetworkStackCallingPermission();
-            mNm.start();
-        }
-
-        @Override
-        public void launchCaptivePortalApp() {
-            checkNetworkStackCallingPermission();
-            mNm.launchCaptivePortalApp();
-        }
-
-        @Override
-        public void notifyCaptivePortalAppFinished(int response) {
-            checkNetworkStackCallingPermission();
-            mNm.notifyCaptivePortalAppFinished(response);
-        }
-
-        @Override
-        public void setAcceptPartialConnectivity() {
-            checkNetworkStackCallingPermission();
-            mNm.setAcceptPartialConnectivity();
-        }
-
-        @Override
-        public void forceReevaluation(int uid) {
-            checkNetworkStackCallingPermission();
-            mNm.forceReevaluation(uid);
-        }
-
-        @Override
-        public void notifyPrivateDnsChanged(PrivateDnsConfigParcel config) {
-            checkNetworkStackCallingPermission();
-            mNm.notifyPrivateDnsSettingsChanged(PrivateDnsConfig.fromParcel(config));
-        }
-
-        @Override
-        public void notifyDnsResponse(int returnCode) {
-            checkNetworkStackCallingPermission();
-            mNm.notifyDnsResponse(returnCode);
-        }
-
-        @Override
-        public void notifyNetworkConnected(LinkProperties lp, NetworkCapabilities nc) {
-            checkNetworkStackCallingPermission();
-            mNm.notifyNetworkConnected(lp, nc);
-        }
-
-        @Override
-        public void notifyNetworkDisconnected() {
-            checkNetworkStackCallingPermission();
-            mNm.notifyNetworkDisconnected();
-        }
-
-        @Override
-        public void notifyLinkPropertiesChanged(LinkProperties lp) {
-            checkNetworkStackCallingPermission();
-            mNm.notifyLinkPropertiesChanged(lp);
-        }
-
-        @Override
-        public void notifyNetworkCapabilitiesChanged(NetworkCapabilities nc) {
-            checkNetworkStackCallingPermission();
-            mNm.notifyNetworkCapabilitiesChanged(nc);
-        }
-
-        @Override
-        public int getInterfaceVersion() {
-            return this.VERSION;
-        }
-    }
-}
diff --git a/packages/NetworkStack/src/com/android/server/connectivity/NetworkMonitor.java b/packages/NetworkStack/src/com/android/server/connectivity/NetworkMonitor.java
deleted file mode 100644
index 4e40ba4..0000000
--- a/packages/NetworkStack/src/com/android/server/connectivity/NetworkMonitor.java
+++ /dev/null
@@ -1,2143 +0,0 @@
-/*
- * Copyright (C) 2014 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.connectivity;
-
-import static android.net.CaptivePortal.APP_RETURN_DISMISSED;
-import static android.net.CaptivePortal.APP_RETURN_UNWANTED;
-import static android.net.CaptivePortal.APP_RETURN_WANTED_AS_IS;
-import static android.net.ConnectivityManager.EXTRA_CAPTIVE_PORTAL_PROBE_SPEC;
-import static android.net.ConnectivityManager.EXTRA_CAPTIVE_PORTAL_URL;
-import static android.net.ConnectivityManager.TYPE_MOBILE;
-import static android.net.ConnectivityManager.TYPE_WIFI;
-import static android.net.DnsResolver.FLAG_EMPTY;
-import static android.net.INetworkMonitor.NETWORK_VALIDATION_PROBE_DNS;
-import static android.net.INetworkMonitor.NETWORK_VALIDATION_PROBE_FALLBACK;
-import static android.net.INetworkMonitor.NETWORK_VALIDATION_PROBE_HTTP;
-import static android.net.INetworkMonitor.NETWORK_VALIDATION_PROBE_HTTPS;
-import static android.net.INetworkMonitor.NETWORK_VALIDATION_PROBE_PRIVDNS;
-import static android.net.INetworkMonitor.NETWORK_VALIDATION_RESULT_PARTIAL;
-import static android.net.INetworkMonitor.NETWORK_VALIDATION_RESULT_VALID;
-import static android.net.NetworkCapabilities.NET_CAPABILITY_NOT_METERED;
-import static android.net.NetworkCapabilities.TRANSPORT_CELLULAR;
-import static android.net.NetworkCapabilities.TRANSPORT_WIFI;
-import static android.net.captiveportal.CaptivePortalProbeSpec.parseCaptivePortalProbeSpecs;
-import static android.net.metrics.ValidationProbeEvent.DNS_FAILURE;
-import static android.net.metrics.ValidationProbeEvent.DNS_SUCCESS;
-import static android.net.metrics.ValidationProbeEvent.PROBE_FALLBACK;
-import static android.net.metrics.ValidationProbeEvent.PROBE_PRIVDNS;
-import static android.net.util.DataStallUtils.CONFIG_DATA_STALL_CONSECUTIVE_DNS_TIMEOUT_THRESHOLD;
-import static android.net.util.DataStallUtils.CONFIG_DATA_STALL_EVALUATION_TYPE;
-import static android.net.util.DataStallUtils.CONFIG_DATA_STALL_MIN_EVALUATE_INTERVAL;
-import static android.net.util.DataStallUtils.CONFIG_DATA_STALL_VALID_DNS_TIME_THRESHOLD;
-import static android.net.util.DataStallUtils.DATA_STALL_EVALUATION_TYPE_DNS;
-import static android.net.util.DataStallUtils.DEFAULT_CONSECUTIVE_DNS_TIMEOUT_THRESHOLD;
-import static android.net.util.DataStallUtils.DEFAULT_DATA_STALL_EVALUATION_TYPES;
-import static android.net.util.DataStallUtils.DEFAULT_DATA_STALL_MIN_EVALUATE_TIME_MS;
-import static android.net.util.DataStallUtils.DEFAULT_DATA_STALL_VALID_DNS_TIME_THRESHOLD_MS;
-import static android.net.util.DataStallUtils.DEFAULT_DNS_LOG_SIZE;
-import static android.net.util.NetworkStackUtils.CAPTIVE_PORTAL_FALLBACK_PROBE_SPECS;
-import static android.net.util.NetworkStackUtils.CAPTIVE_PORTAL_FALLBACK_URL;
-import static android.net.util.NetworkStackUtils.CAPTIVE_PORTAL_HTTPS_URL;
-import static android.net.util.NetworkStackUtils.CAPTIVE_PORTAL_HTTP_URL;
-import static android.net.util.NetworkStackUtils.CAPTIVE_PORTAL_MODE;
-import static android.net.util.NetworkStackUtils.CAPTIVE_PORTAL_MODE_IGNORE;
-import static android.net.util.NetworkStackUtils.CAPTIVE_PORTAL_MODE_PROMPT;
-import static android.net.util.NetworkStackUtils.CAPTIVE_PORTAL_OTHER_FALLBACK_URLS;
-import static android.net.util.NetworkStackUtils.CAPTIVE_PORTAL_USER_AGENT;
-import static android.net.util.NetworkStackUtils.CAPTIVE_PORTAL_USE_HTTPS;
-import static android.net.util.NetworkStackUtils.NAMESPACE_CONNECTIVITY;
-import static android.net.util.NetworkStackUtils.isEmpty;
-
-import static com.android.networkstack.util.DnsUtils.TYPE_ADDRCONFIG;
-
-import android.annotation.NonNull;
-import android.annotation.Nullable;
-import android.app.PendingIntent;
-import android.content.BroadcastReceiver;
-import android.content.Context;
-import android.content.Intent;
-import android.content.IntentFilter;
-import android.content.res.Resources;
-import android.net.ConnectivityManager;
-import android.net.DnsResolver;
-import android.net.INetworkMonitorCallbacks;
-import android.net.LinkProperties;
-import android.net.Network;
-import android.net.NetworkCapabilities;
-import android.net.ProxyInfo;
-import android.net.TrafficStats;
-import android.net.Uri;
-import android.net.captiveportal.CaptivePortalProbeResult;
-import android.net.captiveportal.CaptivePortalProbeSpec;
-import android.net.metrics.IpConnectivityLog;
-import android.net.metrics.NetworkEvent;
-import android.net.metrics.ValidationProbeEvent;
-import android.net.shared.NetworkMonitorUtils;
-import android.net.shared.PrivateDnsConfig;
-import android.net.util.NetworkStackUtils;
-import android.net.util.SharedLog;
-import android.net.util.Stopwatch;
-import android.net.wifi.WifiInfo;
-import android.net.wifi.WifiManager;
-import android.os.Bundle;
-import android.os.Message;
-import android.os.RemoteException;
-import android.os.SystemClock;
-import android.os.UserHandle;
-import android.provider.Settings;
-import android.telephony.AccessNetworkConstants;
-import android.telephony.CellSignalStrength;
-import android.telephony.NetworkRegistrationInfo;
-import android.telephony.ServiceState;
-import android.telephony.SignalStrength;
-import android.telephony.TelephonyManager;
-import android.text.TextUtils;
-import android.util.Log;
-import android.util.Pair;
-
-import androidx.annotation.ArrayRes;
-import androidx.annotation.StringRes;
-
-import com.android.internal.annotations.VisibleForTesting;
-import com.android.internal.util.RingBufferIndices;
-import com.android.internal.util.State;
-import com.android.internal.util.StateMachine;
-import com.android.internal.util.TrafficStatsConstants;
-import com.android.networkstack.R;
-import com.android.networkstack.metrics.DataStallDetectionStats;
-import com.android.networkstack.metrics.DataStallStatsUtils;
-import com.android.networkstack.util.DnsUtils;
-
-import java.io.IOException;
-import java.net.HttpURLConnection;
-import java.net.InetAddress;
-import java.net.MalformedURLException;
-import java.net.URL;
-import java.net.UnknownHostException;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Collections;
-import java.util.LinkedHashMap;
-import java.util.List;
-import java.util.Random;
-import java.util.UUID;
-import java.util.concurrent.CountDownLatch;
-import java.util.concurrent.TimeUnit;
-import java.util.function.Function;
-
-/**
- * {@hide}
- */
-public class NetworkMonitor extends StateMachine {
-    private static final String TAG = NetworkMonitor.class.getSimpleName();
-    private static final boolean DBG  = true;
-    private static final boolean VDBG = false;
-    private static final boolean VDBG_STALL = Log.isLoggable(TAG, Log.DEBUG);
-    private static final String DEFAULT_USER_AGENT    = "Mozilla/5.0 (X11; Linux x86_64) "
-                                                      + "AppleWebKit/537.36 (KHTML, like Gecko) "
-                                                      + "Chrome/60.0.3112.32 Safari/537.36";
-
-    @VisibleForTesting
-    static final String CONFIG_CAPTIVE_PORTAL_DNS_PROBE_TIMEOUT =
-            "captive_portal_dns_probe_timeout";
-
-    private static final int SOCKET_TIMEOUT_MS = 10000;
-    private static final int PROBE_TIMEOUT_MS  = 3000;
-
-    enum EvaluationResult {
-        VALIDATED(true),
-        CAPTIVE_PORTAL(false);
-        final boolean mIsValidated;
-        EvaluationResult(boolean isValidated) {
-            this.mIsValidated = isValidated;
-        }
-    }
-
-    enum ValidationStage {
-        FIRST_VALIDATION(true),
-        REVALIDATION(false);
-        final boolean mIsFirstValidation;
-        ValidationStage(boolean isFirstValidation) {
-            this.mIsFirstValidation = isFirstValidation;
-        }
-    }
-
-    /**
-     * ConnectivityService has sent a notification to indicate that network has connected.
-     * Initiates Network Validation.
-     */
-    private static final int CMD_NETWORK_CONNECTED = 1;
-
-    /**
-     * Message to self indicating it's time to evaluate a network's connectivity.
-     * arg1 = Token to ignore old messages.
-     */
-    private static final int CMD_REEVALUATE = 6;
-
-    /**
-     * ConnectivityService has sent a notification to indicate that network has disconnected.
-     */
-    private static final int CMD_NETWORK_DISCONNECTED = 7;
-
-    /**
-     * Force evaluation even if it has succeeded in the past.
-     * arg1 = UID responsible for requesting this reeval.  Will be billed for data.
-     */
-    private static final int CMD_FORCE_REEVALUATION = 8;
-
-    /**
-     * Message to self indicating captive portal app finished.
-     * arg1 = one of: APP_RETURN_DISMISSED,
-     *                APP_RETURN_UNWANTED,
-     *                APP_RETURN_WANTED_AS_IS
-     * obj = mCaptivePortalLoggedInResponseToken as String
-     */
-    private static final int CMD_CAPTIVE_PORTAL_APP_FINISHED = 9;
-
-    /**
-     * Message indicating sign-in app should be launched.
-     * Sent by mLaunchCaptivePortalAppBroadcastReceiver when the
-     * user touches the sign in notification, or sent by
-     * ConnectivityService when the user touches the "sign into
-     * network" button in the wifi access point detail page.
-     */
-    private static final int CMD_LAUNCH_CAPTIVE_PORTAL_APP = 11;
-
-    /**
-     * Retest network to see if captive portal is still in place.
-     * arg1 = UID responsible for requesting this reeval.  Will be billed for data.
-     *        0 indicates self-initiated, so nobody to blame.
-     */
-    private static final int CMD_CAPTIVE_PORTAL_RECHECK = 12;
-
-    /**
-     * ConnectivityService notifies NetworkMonitor of settings changes to
-     * Private DNS. If a DNS resolution is required, e.g. for DNS-over-TLS in
-     * strict mode, then an event is sent back to ConnectivityService with the
-     * result of the resolution attempt.
-     *
-     * A separate message is used to trigger (re)evaluation of the Private DNS
-     * configuration, so that the message can be handled as needed in different
-     * states, including being ignored until after an ongoing captive portal
-     * validation phase is completed.
-     */
-    private static final int CMD_PRIVATE_DNS_SETTINGS_CHANGED = 13;
-    private static final int CMD_EVALUATE_PRIVATE_DNS = 15;
-
-    /**
-     * Message to self indicating captive portal detection is completed.
-     * obj = CaptivePortalProbeResult for detection result;
-     */
-    private static final int CMD_PROBE_COMPLETE = 16;
-
-    /**
-     * ConnectivityService notifies NetworkMonitor of DNS query responses event.
-     * arg1 = returncode in OnDnsEvent which indicates the response code for the DNS query.
-     */
-    private static final int EVENT_DNS_NOTIFICATION = 17;
-
-    /**
-     * ConnectivityService notifies NetworkMonitor that the user accepts partial connectivity and
-     * NetworkMonitor should ignore the https probe.
-     */
-    private static final int EVENT_ACCEPT_PARTIAL_CONNECTIVITY = 18;
-
-    /**
-     * ConnectivityService notifies NetworkMonitor of changed LinkProperties.
-     * obj = new LinkProperties.
-     */
-    private static final int EVENT_LINK_PROPERTIES_CHANGED = 19;
-
-    /**
-     * ConnectivityService notifies NetworkMonitor of changed NetworkCapabilities.
-     * obj = new NetworkCapabilities.
-     */
-    private static final int EVENT_NETWORK_CAPABILITIES_CHANGED = 20;
-
-    // Start mReevaluateDelayMs at this value and double.
-    private static final int INITIAL_REEVALUATE_DELAY_MS = 1000;
-    private static final int MAX_REEVALUATE_DELAY_MS = 10 * 60 * 1000;
-    // Before network has been evaluated this many times, ignore repeated reevaluate requests.
-    private static final int IGNORE_REEVALUATE_ATTEMPTS = 5;
-    private int mReevaluateToken = 0;
-    private static final int NO_UID = 0;
-    private static final int INVALID_UID = -1;
-    private int mUidResponsibleForReeval = INVALID_UID;
-    // Stop blaming UID that requested re-evaluation after this many attempts.
-    private static final int BLAME_FOR_EVALUATION_ATTEMPTS = 5;
-    // Delay between reevaluations once a captive portal has been found.
-    private static final int CAPTIVE_PORTAL_REEVALUATE_DELAY_MS = 10 * 60 * 1000;
-    private static final int NETWORK_VALIDATION_RESULT_INVALID = 0;
-    private String mPrivateDnsProviderHostname = "";
-
-    private final Context mContext;
-    private final INetworkMonitorCallbacks mCallback;
-    private final Network mCleartextDnsNetwork;
-    private final Network mNetwork;
-    private final TelephonyManager mTelephonyManager;
-    private final WifiManager mWifiManager;
-    private final ConnectivityManager mCm;
-    private final IpConnectivityLog mMetricsLog;
-    private final Dependencies mDependencies;
-    private final DataStallStatsUtils mDetectionStatsUtils;
-
-    // Configuration values for captive portal detection probes.
-    private final String mCaptivePortalUserAgent;
-    private final URL mCaptivePortalHttpsUrl;
-    private final URL mCaptivePortalHttpUrl;
-    private final URL[] mCaptivePortalFallbackUrls;
-    @Nullable
-    private final CaptivePortalProbeSpec[] mCaptivePortalFallbackSpecs;
-
-    private NetworkCapabilities mNetworkCapabilities;
-    private LinkProperties mLinkProperties;
-
-    @VisibleForTesting
-    protected boolean mIsCaptivePortalCheckEnabled;
-
-    private boolean mUseHttps;
-    // The total number of captive portal detection attempts for this NetworkMonitor instance.
-    private int mValidations = 0;
-
-    // Set if the user explicitly selected "Do not use this network" in captive portal sign-in app.
-    private boolean mUserDoesNotWant = false;
-    // Avoids surfacing "Sign in to network" notification.
-    private boolean mDontDisplaySigninNotification = false;
-
-    private final State mDefaultState = new DefaultState();
-    private final State mValidatedState = new ValidatedState();
-    private final State mMaybeNotifyState = new MaybeNotifyState();
-    private final State mEvaluatingState = new EvaluatingState();
-    private final State mCaptivePortalState = new CaptivePortalState();
-    private final State mEvaluatingPrivateDnsState = new EvaluatingPrivateDnsState();
-    private final State mProbingState = new ProbingState();
-    private final State mWaitingForNextProbeState = new WaitingForNextProbeState();
-
-    private CustomIntentReceiver mLaunchCaptivePortalAppBroadcastReceiver = null;
-
-    private final SharedLog mValidationLogs;
-
-    private final Stopwatch mEvaluationTimer = new Stopwatch();
-
-    // This variable is set before transitioning to the mCaptivePortalState.
-    private CaptivePortalProbeResult mLastPortalProbeResult = CaptivePortalProbeResult.FAILED;
-
-    // Random generator to select fallback URL index
-    private final Random mRandom;
-    private int mNextFallbackUrlIndex = 0;
-
-
-    private int mReevaluateDelayMs = INITIAL_REEVALUATE_DELAY_MS;
-    private int mEvaluateAttempts = 0;
-    private volatile int mProbeToken = 0;
-    private final int mConsecutiveDnsTimeoutThreshold;
-    private final int mDataStallMinEvaluateTime;
-    private final int mDataStallValidDnsTimeThreshold;
-    private final int mDataStallEvaluationType;
-    private final DnsStallDetector mDnsStallDetector;
-    private long mLastProbeTime;
-    // Set to true if data stall is suspected and reset to false after metrics are sent to statsd.
-    private boolean mCollectDataStallMetrics;
-    private boolean mAcceptPartialConnectivity = false;
-    private final EvaluationState mEvaluationState = new EvaluationState();
-
-    public NetworkMonitor(Context context, INetworkMonitorCallbacks cb, Network network,
-            SharedLog validationLog) {
-        this(context, cb, network, new IpConnectivityLog(), validationLog,
-                Dependencies.DEFAULT, new DataStallStatsUtils());
-    }
-
-    @VisibleForTesting
-    protected NetworkMonitor(Context context, INetworkMonitorCallbacks cb, Network network,
-            IpConnectivityLog logger, SharedLog validationLogs,
-            Dependencies deps, DataStallStatsUtils detectionStatsUtils) {
-        // Add suffix indicating which NetworkMonitor we're talking about.
-        super(TAG + "/" + network.toString());
-
-        // Logs with a tag of the form given just above, e.g.
-        //     <timestamp>   862  2402 D NetworkMonitor/NetworkAgentInfo [WIFI () - 100]: ...
-        setDbg(VDBG);
-
-        mContext = context;
-        mMetricsLog = logger;
-        mValidationLogs = validationLogs;
-        mCallback = cb;
-        mDependencies = deps;
-        mDetectionStatsUtils = detectionStatsUtils;
-        mNetwork = network;
-        mCleartextDnsNetwork = deps.getPrivateDnsBypassNetwork(network);
-        mTelephonyManager = (TelephonyManager) context.getSystemService(Context.TELEPHONY_SERVICE);
-        mWifiManager = (WifiManager) context.getSystemService(Context.WIFI_SERVICE);
-        mCm = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
-
-        // CHECKSTYLE:OFF IndentationCheck
-        addState(mDefaultState);
-        addState(mMaybeNotifyState, mDefaultState);
-            addState(mEvaluatingState, mMaybeNotifyState);
-                addState(mProbingState, mEvaluatingState);
-                addState(mWaitingForNextProbeState, mEvaluatingState);
-            addState(mCaptivePortalState, mMaybeNotifyState);
-        addState(mEvaluatingPrivateDnsState, mDefaultState);
-        addState(mValidatedState, mDefaultState);
-        setInitialState(mDefaultState);
-        // CHECKSTYLE:ON IndentationCheck
-
-        mIsCaptivePortalCheckEnabled = getIsCaptivePortalCheckEnabled();
-        mUseHttps = getUseHttpsValidation();
-        mCaptivePortalUserAgent = getCaptivePortalUserAgent();
-        mCaptivePortalHttpsUrl = makeURL(getCaptivePortalServerHttpsUrl());
-        mCaptivePortalHttpUrl = makeURL(getCaptivePortalServerHttpUrl());
-        mCaptivePortalFallbackUrls = makeCaptivePortalFallbackUrls();
-        mCaptivePortalFallbackSpecs = makeCaptivePortalFallbackProbeSpecs();
-        mRandom = deps.getRandom();
-        // TODO: Evaluate to move data stall configuration to a specific class.
-        mConsecutiveDnsTimeoutThreshold = getConsecutiveDnsTimeoutThreshold();
-        mDnsStallDetector = new DnsStallDetector(mConsecutiveDnsTimeoutThreshold);
-        mDataStallMinEvaluateTime = getDataStallMinEvaluateTime();
-        mDataStallValidDnsTimeThreshold = getDataStallValidDnsTimeThreshold();
-        mDataStallEvaluationType = getDataStallEvaluationType();
-
-        // Provide empty LinkProperties and NetworkCapabilities to make sure they are never null,
-        // even before notifyNetworkConnected.
-        mLinkProperties = new LinkProperties();
-        mNetworkCapabilities = new NetworkCapabilities(null);
-    }
-
-    /**
-     * ConnectivityService notifies NetworkMonitor that the user already accepted partial
-     * connectivity previously, so NetworkMonitor can validate the network even if it has partial
-     * connectivity.
-     */
-    public void setAcceptPartialConnectivity() {
-        sendMessage(EVENT_ACCEPT_PARTIAL_CONNECTIVITY);
-    }
-
-    /**
-     * Request the NetworkMonitor to reevaluate the network.
-     */
-    public void forceReevaluation(int responsibleUid) {
-        sendMessage(CMD_FORCE_REEVALUATION, responsibleUid, 0);
-    }
-
-    /**
-     * Send a notification to NetworkMonitor indicating that there was a DNS query response event.
-     * @param returnCode the DNS return code of the response.
-     */
-    public void notifyDnsResponse(int returnCode) {
-        sendMessage(EVENT_DNS_NOTIFICATION, returnCode);
-    }
-
-    /**
-     * Send a notification to NetworkMonitor indicating that private DNS settings have changed.
-     * @param newCfg The new private DNS configuration.
-     */
-    public void notifyPrivateDnsSettingsChanged(PrivateDnsConfig newCfg) {
-        // Cancel any outstanding resolutions.
-        removeMessages(CMD_PRIVATE_DNS_SETTINGS_CHANGED);
-        // Send the update to the proper thread.
-        sendMessage(CMD_PRIVATE_DNS_SETTINGS_CHANGED, newCfg);
-    }
-
-    /**
-     * Send a notification to NetworkMonitor indicating that the network is now connected.
-     */
-    public void notifyNetworkConnected(LinkProperties lp, NetworkCapabilities nc) {
-        sendMessage(CMD_NETWORK_CONNECTED, new Pair<>(
-                new LinkProperties(lp), new NetworkCapabilities(nc)));
-    }
-
-    private void updateConnectedNetworkAttributes(Message connectedMsg) {
-        final Pair<LinkProperties, NetworkCapabilities> attrs =
-                (Pair<LinkProperties, NetworkCapabilities>) connectedMsg.obj;
-        mLinkProperties = attrs.first;
-        mNetworkCapabilities = attrs.second;
-    }
-
-    /**
-     * Send a notification to NetworkMonitor indicating that the network is now disconnected.
-     */
-    public void notifyNetworkDisconnected() {
-        sendMessage(CMD_NETWORK_DISCONNECTED);
-    }
-
-    /**
-     * Send a notification to NetworkMonitor indicating that link properties have changed.
-     */
-    public void notifyLinkPropertiesChanged(final LinkProperties lp) {
-        sendMessage(EVENT_LINK_PROPERTIES_CHANGED, new LinkProperties(lp));
-    }
-
-    /**
-     * Send a notification to NetworkMonitor indicating that network capabilities have changed.
-     */
-    public void notifyNetworkCapabilitiesChanged(final NetworkCapabilities nc) {
-        sendMessage(EVENT_NETWORK_CAPABILITIES_CHANGED, new NetworkCapabilities(nc));
-    }
-
-    /**
-     * Request the captive portal application to be launched.
-     */
-    public void launchCaptivePortalApp() {
-        sendMessage(CMD_LAUNCH_CAPTIVE_PORTAL_APP);
-    }
-
-    /**
-     * Notify that the captive portal app was closed with the provided response code.
-     */
-    public void notifyCaptivePortalAppFinished(int response) {
-        sendMessage(CMD_CAPTIVE_PORTAL_APP_FINISHED, response);
-    }
-
-    @Override
-    protected void log(String s) {
-        if (DBG) Log.d(TAG + "/" + mCleartextDnsNetwork.toString(), s);
-    }
-
-    private void validationLog(int probeType, Object url, String msg) {
-        String probeName = ValidationProbeEvent.getProbeName(probeType);
-        validationLog(String.format("%s %s %s", probeName, url, msg));
-    }
-
-    private void validationLog(String s) {
-        if (DBG) log(s);
-        mValidationLogs.log(s);
-    }
-
-    private ValidationStage validationStage() {
-        return 0 == mValidations ? ValidationStage.FIRST_VALIDATION : ValidationStage.REVALIDATION;
-    }
-
-    private boolean isValidationRequired() {
-        return NetworkMonitorUtils.isValidationRequired(mNetworkCapabilities);
-    }
-
-    private boolean isPrivateDnsValidationRequired() {
-        return NetworkMonitorUtils.isPrivateDnsValidationRequired(mNetworkCapabilities);
-    }
-
-    private void notifyNetworkTested(int result, @Nullable String redirectUrl) {
-        try {
-            mCallback.notifyNetworkTested(result, redirectUrl);
-        } catch (RemoteException e) {
-            Log.e(TAG, "Error sending network test result", e);
-        }
-    }
-
-    private void showProvisioningNotification(String action) {
-        try {
-            mCallback.showProvisioningNotification(action, mContext.getPackageName());
-        } catch (RemoteException e) {
-            Log.e(TAG, "Error showing provisioning notification", e);
-        }
-    }
-
-    private void hideProvisioningNotification() {
-        try {
-            mCallback.hideProvisioningNotification();
-        } catch (RemoteException e) {
-            Log.e(TAG, "Error hiding provisioning notification", e);
-        }
-    }
-
-    // DefaultState is the parent of all States.  It exists only to handle CMD_* messages but
-    // does not entail any real state (hence no enter() or exit() routines).
-    private class DefaultState extends State {
-        @Override
-        public boolean processMessage(Message message) {
-            switch (message.what) {
-                case CMD_NETWORK_CONNECTED:
-                    updateConnectedNetworkAttributes(message);
-                    logNetworkEvent(NetworkEvent.NETWORK_CONNECTED);
-                    transitionTo(mEvaluatingState);
-                    return HANDLED;
-                case CMD_NETWORK_DISCONNECTED:
-                    logNetworkEvent(NetworkEvent.NETWORK_DISCONNECTED);
-                    quit();
-                    return HANDLED;
-                case CMD_FORCE_REEVALUATION:
-                case CMD_CAPTIVE_PORTAL_RECHECK:
-                    final int dnsCount = mDnsStallDetector.getConsecutiveTimeoutCount();
-                    validationLog("Forcing reevaluation for UID " + message.arg1
-                            + ". Dns signal count: " + dnsCount);
-                    mUidResponsibleForReeval = message.arg1;
-                    transitionTo(mEvaluatingState);
-                    return HANDLED;
-                case CMD_CAPTIVE_PORTAL_APP_FINISHED:
-                    log("CaptivePortal App responded with " + message.arg1);
-
-                    // If the user has seen and acted on a captive portal notification, and the
-                    // captive portal app is now closed, disable HTTPS probes. This avoids the
-                    // following pathological situation:
-                    //
-                    // 1. HTTP probe returns a captive portal, HTTPS probe fails or times out.
-                    // 2. User opens the app and logs into the captive portal.
-                    // 3. HTTP starts working, but HTTPS still doesn't work for some other reason -
-                    //    perhaps due to the network blocking HTTPS?
-                    //
-                    // In this case, we'll fail to validate the network even after the app is
-                    // dismissed. There is now no way to use this network, because the app is now
-                    // gone, so the user cannot select "Use this network as is".
-                    mUseHttps = false;
-
-                    switch (message.arg1) {
-                        case APP_RETURN_DISMISSED:
-                            sendMessage(CMD_FORCE_REEVALUATION, NO_UID, 0);
-                            break;
-                        case APP_RETURN_WANTED_AS_IS:
-                            mDontDisplaySigninNotification = true;
-                            // TODO: Distinguish this from a network that actually validates.
-                            // Displaying the "x" on the system UI icon may still be a good idea.
-                            transitionTo(mEvaluatingPrivateDnsState);
-                            break;
-                        case APP_RETURN_UNWANTED:
-                            mDontDisplaySigninNotification = true;
-                            mUserDoesNotWant = true;
-                            mEvaluationState.reportEvaluationResult(
-                                    NETWORK_VALIDATION_RESULT_INVALID, null);
-                            // TODO: Should teardown network.
-                            mUidResponsibleForReeval = 0;
-                            transitionTo(mEvaluatingState);
-                            break;
-                    }
-                    return HANDLED;
-                case CMD_PRIVATE_DNS_SETTINGS_CHANGED: {
-                    final PrivateDnsConfig cfg = (PrivateDnsConfig) message.obj;
-                    if (!isPrivateDnsValidationRequired() || cfg == null || !cfg.inStrictMode()) {
-                        // No DNS resolution required.
-                        //
-                        // We don't force any validation in opportunistic mode
-                        // here. Opportunistic mode nameservers are validated
-                        // separately within netd.
-                        //
-                        // Reset Private DNS settings state.
-                        mPrivateDnsProviderHostname = "";
-                        break;
-                    }
-
-                    mPrivateDnsProviderHostname = cfg.hostname;
-
-                    // DNS resolutions via Private DNS strict mode block for a
-                    // few seconds (~4.2) checking for any IP addresses to
-                    // arrive and validate. Initiating a (re)evaluation now
-                    // should not significantly alter the validation outcome.
-                    //
-                    // No matter what: enqueue a validation request; one of
-                    // three things can happen with this request:
-                    //     [1] ignored (EvaluatingState or CaptivePortalState)
-                    //     [2] transition to EvaluatingPrivateDnsState
-                    //         (DefaultState and ValidatedState)
-                    //     [3] handled (EvaluatingPrivateDnsState)
-                    //
-                    // The Private DNS configuration to be evaluated will:
-                    //     [1] be skipped (not in strict mode), or
-                    //     [2] validate (huzzah), or
-                    //     [3] encounter some problem (invalid hostname,
-                    //         no resolved IP addresses, IPs unreachable,
-                    //         port 853 unreachable, port 853 is not running a
-                    //         DNS-over-TLS server, et cetera).
-                    sendMessage(CMD_EVALUATE_PRIVATE_DNS);
-                    break;
-                }
-                case EVENT_DNS_NOTIFICATION:
-                    mDnsStallDetector.accumulateConsecutiveDnsTimeoutCount(message.arg1);
-                    break;
-                // Set mAcceptPartialConnectivity to true and if network start evaluating or
-                // re-evaluating and get the result of partial connectivity, ProbingState will
-                // disable HTTPS probe and transition to EvaluatingPrivateDnsState.
-                case EVENT_ACCEPT_PARTIAL_CONNECTIVITY:
-                    maybeDisableHttpsProbing(true /* acceptPartial */);
-                    break;
-                case EVENT_LINK_PROPERTIES_CHANGED:
-                    mLinkProperties = (LinkProperties) message.obj;
-                    break;
-                case EVENT_NETWORK_CAPABILITIES_CHANGED:
-                    mNetworkCapabilities = (NetworkCapabilities) message.obj;
-                    break;
-                default:
-                    break;
-            }
-            return HANDLED;
-        }
-    }
-
-    // Being in the ValidatedState State indicates a Network is:
-    // - Successfully validated, or
-    // - Wanted "as is" by the user, or
-    // - Does not satisfy the default NetworkRequest and so validation has been skipped.
-    private class ValidatedState extends State {
-        @Override
-        public void enter() {
-            maybeLogEvaluationResult(
-                    networkEventType(validationStage(), EvaluationResult.VALIDATED));
-            // If the user has accepted partial connectivity and HTTPS probing is disabled, then
-            // mark the network as validated and partial so that settings can keep informing the
-            // user that the connection is limited.
-            int result = NETWORK_VALIDATION_RESULT_VALID;
-            if (!mUseHttps && mAcceptPartialConnectivity) {
-                result |= NETWORK_VALIDATION_RESULT_PARTIAL;
-            }
-            mEvaluationState.reportEvaluationResult(result, null /* redirectUrl */);
-            mValidations++;
-        }
-
-        @Override
-        public boolean processMessage(Message message) {
-            switch (message.what) {
-                case CMD_NETWORK_CONNECTED:
-                    updateConnectedNetworkAttributes(message);
-                    transitionTo(mValidatedState);
-                    break;
-                case CMD_EVALUATE_PRIVATE_DNS:
-                    transitionTo(mEvaluatingPrivateDnsState);
-                    break;
-                case EVENT_DNS_NOTIFICATION:
-                    mDnsStallDetector.accumulateConsecutiveDnsTimeoutCount(message.arg1);
-                    if (isDataStall()) {
-                        mCollectDataStallMetrics = true;
-                        validationLog("Suspecting data stall, reevaluate");
-                        transitionTo(mEvaluatingState);
-                    }
-                    break;
-                default:
-                    return NOT_HANDLED;
-            }
-            return HANDLED;
-        }
-    }
-
-    private void writeDataStallStats(@NonNull final CaptivePortalProbeResult result) {
-        /*
-         * Collect data stall detection level information for each transport type. Collect type
-         * specific information for cellular and wifi only currently. Generate
-         * DataStallDetectionStats for each transport type. E.g., if a network supports both
-         * TRANSPORT_WIFI and TRANSPORT_VPN, two DataStallDetectionStats will be generated.
-         */
-        final int[] transports = mNetworkCapabilities.getTransportTypes();
-
-        for (int i = 0; i < transports.length; i++) {
-            DataStallStatsUtils.write(buildDataStallDetectionStats(transports[i]), result);
-        }
-        mCollectDataStallMetrics = false;
-    }
-
-    @VisibleForTesting
-    protected DataStallDetectionStats buildDataStallDetectionStats(int transport) {
-        final DataStallDetectionStats.Builder stats = new DataStallDetectionStats.Builder();
-        if (VDBG_STALL) log("collectDataStallMetrics: type=" + transport);
-        stats.setEvaluationType(DATA_STALL_EVALUATION_TYPE_DNS);
-        stats.setNetworkType(transport);
-        switch (transport) {
-            case NetworkCapabilities.TRANSPORT_WIFI:
-                // TODO: Update it if status query in dual wifi is supported.
-                final WifiInfo wifiInfo = mWifiManager.getConnectionInfo();
-                stats.setWiFiData(wifiInfo);
-                break;
-            case NetworkCapabilities.TRANSPORT_CELLULAR:
-                final boolean isRoaming = !mNetworkCapabilities.hasCapability(
-                        NetworkCapabilities.NET_CAPABILITY_NOT_ROAMING);
-                final SignalStrength ss = mTelephonyManager.getSignalStrength();
-                // TODO(b/120452078): Support multi-sim.
-                stats.setCellData(
-                        mTelephonyManager.getDataNetworkType(),
-                        isRoaming,
-                        mTelephonyManager.getNetworkOperator(),
-                        mTelephonyManager.getSimOperator(),
-                        (ss != null)
-                        ? ss.getLevel() : CellSignalStrength.SIGNAL_STRENGTH_NONE_OR_UNKNOWN);
-                break;
-            default:
-                // No transport type specific information for the other types.
-                break;
-        }
-        addDnsEvents(stats);
-
-        return stats.build();
-    }
-
-    @VisibleForTesting
-    protected void addDnsEvents(@NonNull final DataStallDetectionStats.Builder stats) {
-        final int size = mDnsStallDetector.mResultIndices.size();
-        for (int i = 1; i <= DEFAULT_DNS_LOG_SIZE && i <= size; i++) {
-            final int index = mDnsStallDetector.mResultIndices.indexOf(size - i);
-            stats.addDnsEvent(mDnsStallDetector.mDnsEvents[index].mReturnCode,
-                    mDnsStallDetector.mDnsEvents[index].mTimeStamp);
-        }
-    }
-
-
-    // Being in the MaybeNotifyState State indicates the user may have been notified that sign-in
-    // is required.  This State takes care to clear the notification upon exit from the State.
-    private class MaybeNotifyState extends State {
-        @Override
-        public boolean processMessage(Message message) {
-            switch (message.what) {
-                case CMD_LAUNCH_CAPTIVE_PORTAL_APP:
-                    final Bundle appExtras = new Bundle();
-                    // OneAddressPerFamilyNetwork is not parcelable across processes.
-                    final Network network = new Network(mCleartextDnsNetwork);
-                    appExtras.putParcelable(ConnectivityManager.EXTRA_NETWORK, network);
-                    final CaptivePortalProbeResult probeRes = mLastPortalProbeResult;
-                    appExtras.putString(EXTRA_CAPTIVE_PORTAL_URL, probeRes.detectUrl);
-                    if (probeRes.probeSpec != null) {
-                        final String encodedSpec = probeRes.probeSpec.getEncodedSpec();
-                        appExtras.putString(EXTRA_CAPTIVE_PORTAL_PROBE_SPEC, encodedSpec);
-                    }
-                    appExtras.putString(ConnectivityManager.EXTRA_CAPTIVE_PORTAL_USER_AGENT,
-                            mCaptivePortalUserAgent);
-                    mCm.startCaptivePortalApp(network, appExtras);
-                    return HANDLED;
-                default:
-                    return NOT_HANDLED;
-            }
-        }
-
-        @Override
-        public void exit() {
-            if (mLaunchCaptivePortalAppBroadcastReceiver != null) {
-                mContext.unregisterReceiver(mLaunchCaptivePortalAppBroadcastReceiver);
-                mLaunchCaptivePortalAppBroadcastReceiver = null;
-            }
-            hideProvisioningNotification();
-        }
-    }
-
-    // Being in the EvaluatingState State indicates the Network is being evaluated for internet
-    // connectivity, or that the user has indicated that this network is unwanted.
-    private class EvaluatingState extends State {
-        @Override
-        public void enter() {
-            // If we have already started to track time spent in EvaluatingState
-            // don't reset the timer due simply to, say, commands or events that
-            // cause us to exit and re-enter EvaluatingState.
-            if (!mEvaluationTimer.isStarted()) {
-                mEvaluationTimer.start();
-            }
-            sendMessage(CMD_REEVALUATE, ++mReevaluateToken, 0);
-            if (mUidResponsibleForReeval != INVALID_UID) {
-                TrafficStats.setThreadStatsUid(mUidResponsibleForReeval);
-                mUidResponsibleForReeval = INVALID_UID;
-            }
-            mReevaluateDelayMs = INITIAL_REEVALUATE_DELAY_MS;
-            mEvaluateAttempts = 0;
-            // Reset all current probe results to zero, but retain current validation state until
-            // validation succeeds or fails.
-            mEvaluationState.clearProbeResults();
-        }
-
-        @Override
-        public boolean processMessage(Message message) {
-            switch (message.what) {
-                case CMD_REEVALUATE:
-                    if (message.arg1 != mReevaluateToken || mUserDoesNotWant) {
-                        return HANDLED;
-                    }
-                    // Don't bother validating networks that don't satisfy the default request.
-                    // This includes:
-                    //  - VPNs which can be considered explicitly desired by the user and the
-                    //    user's desire trumps whether the network validates.
-                    //  - Networks that don't provide Internet access.  It's unclear how to
-                    //    validate such networks.
-                    //  - Untrusted networks.  It's unsafe to prompt the user to sign-in to
-                    //    such networks and the user didn't express interest in connecting to
-                    //    such networks (an app did) so the user may be unhappily surprised when
-                    //    asked to sign-in to a network they didn't want to connect to in the
-                    //    first place.  Validation could be done to adjust the network scores
-                    //    however these networks are app-requested and may not be intended for
-                    //    general usage, in which case general validation may not be an accurate
-                    //    measure of the network's quality.  Only the app knows how to evaluate
-                    //    the network so don't bother validating here.  Furthermore sending HTTP
-                    //    packets over the network may be undesirable, for example an extremely
-                    //    expensive metered network, or unwanted leaking of the User Agent string.
-                    //
-                    // On networks that need to support private DNS in strict mode (e.g., VPNs, but
-                    // not networks that don't provide Internet access), we still need to perform
-                    // private DNS server resolution.
-                    if (!isValidationRequired()) {
-                        if (isPrivateDnsValidationRequired()) {
-                            validationLog("Network would not satisfy default request, "
-                                    + "resolving private DNS");
-                            transitionTo(mEvaluatingPrivateDnsState);
-                        } else {
-                            validationLog("Network would not satisfy default request, "
-                                    + "not validating");
-                            transitionTo(mValidatedState);
-                        }
-                        return HANDLED;
-                    }
-                    mEvaluateAttempts++;
-
-                    transitionTo(mProbingState);
-                    return HANDLED;
-                case CMD_FORCE_REEVALUATION:
-                    // Before IGNORE_REEVALUATE_ATTEMPTS attempts are made,
-                    // ignore any re-evaluation requests. After, restart the
-                    // evaluation process via EvaluatingState#enter.
-                    return (mEvaluateAttempts < IGNORE_REEVALUATE_ATTEMPTS) ? HANDLED : NOT_HANDLED;
-                // Disable HTTPS probe and transition to EvaluatingPrivateDnsState because:
-                // 1. Network is connected and finish the network validation.
-                // 2. NetworkMonitor detects network is partial connectivity and user accepts it.
-                case EVENT_ACCEPT_PARTIAL_CONNECTIVITY:
-                    maybeDisableHttpsProbing(true /* acceptPartial */);
-                    transitionTo(mEvaluatingPrivateDnsState);
-                    return HANDLED;
-                default:
-                    return NOT_HANDLED;
-            }
-        }
-
-        @Override
-        public void exit() {
-            TrafficStats.clearThreadStatsUid();
-        }
-    }
-
-    // BroadcastReceiver that waits for a particular Intent and then posts a message.
-    private class CustomIntentReceiver extends BroadcastReceiver {
-        private final int mToken;
-        private final int mWhat;
-        private final String mAction;
-        CustomIntentReceiver(String action, int token, int what) {
-            mToken = token;
-            mWhat = what;
-            mAction = action + "_" + mCleartextDnsNetwork.getNetworkHandle() + "_" + token;
-            mContext.registerReceiver(this, new IntentFilter(mAction));
-        }
-        public PendingIntent getPendingIntent() {
-            final Intent intent = new Intent(mAction);
-            intent.setPackage(mContext.getPackageName());
-            return PendingIntent.getBroadcast(mContext, 0, intent, 0);
-        }
-        @Override
-        public void onReceive(Context context, Intent intent) {
-            if (intent.getAction().equals(mAction)) sendMessage(obtainMessage(mWhat, mToken));
-        }
-    }
-
-    // Being in the CaptivePortalState State indicates a captive portal was detected and the user
-    // has been shown a notification to sign-in.
-    private class CaptivePortalState extends State {
-        private static final String ACTION_LAUNCH_CAPTIVE_PORTAL_APP =
-                "android.net.netmon.launchCaptivePortalApp";
-
-        @Override
-        public void enter() {
-            maybeLogEvaluationResult(
-                    networkEventType(validationStage(), EvaluationResult.CAPTIVE_PORTAL));
-            // Don't annoy user with sign-in notifications.
-            if (mDontDisplaySigninNotification) return;
-            // Create a CustomIntentReceiver that sends us a
-            // CMD_LAUNCH_CAPTIVE_PORTAL_APP message when the user
-            // touches the notification.
-            if (mLaunchCaptivePortalAppBroadcastReceiver == null) {
-                // Wait for result.
-                mLaunchCaptivePortalAppBroadcastReceiver = new CustomIntentReceiver(
-                        ACTION_LAUNCH_CAPTIVE_PORTAL_APP, new Random().nextInt(),
-                        CMD_LAUNCH_CAPTIVE_PORTAL_APP);
-                // Display the sign in notification.
-                // Only do this once for every time we enter MaybeNotifyState. b/122164725
-                showProvisioningNotification(mLaunchCaptivePortalAppBroadcastReceiver.mAction);
-            }
-            // Retest for captive portal occasionally.
-            sendMessageDelayed(CMD_CAPTIVE_PORTAL_RECHECK, 0 /* no UID */,
-                    CAPTIVE_PORTAL_REEVALUATE_DELAY_MS);
-            mValidations++;
-        }
-
-        @Override
-        public void exit() {
-            removeMessages(CMD_CAPTIVE_PORTAL_RECHECK);
-        }
-    }
-
-    private class EvaluatingPrivateDnsState extends State {
-        private int mPrivateDnsReevalDelayMs;
-        private PrivateDnsConfig mPrivateDnsConfig;
-
-        @Override
-        public void enter() {
-            mPrivateDnsReevalDelayMs = INITIAL_REEVALUATE_DELAY_MS;
-            mPrivateDnsConfig = null;
-            sendMessage(CMD_EVALUATE_PRIVATE_DNS);
-        }
-
-        @Override
-        public boolean processMessage(Message msg) {
-            switch (msg.what) {
-                case CMD_EVALUATE_PRIVATE_DNS:
-                    if (inStrictMode()) {
-                        if (!isStrictModeHostnameResolved()) {
-                            resolveStrictModeHostname();
-
-                            if (isStrictModeHostnameResolved()) {
-                                notifyPrivateDnsConfigResolved();
-                            } else {
-                                handlePrivateDnsEvaluationFailure();
-                                break;
-                            }
-                        }
-
-                        // Look up a one-time hostname, to bypass caching.
-                        //
-                        // Note that this will race with ConnectivityService
-                        // code programming the DNS-over-TLS server IP addresses
-                        // into netd (if invoked, above). If netd doesn't know
-                        // the IP addresses yet, or if the connections to the IP
-                        // addresses haven't yet been validated, netd will block
-                        // for up to a few seconds before failing the lookup.
-                        if (!sendPrivateDnsProbe()) {
-                            handlePrivateDnsEvaluationFailure();
-                            break;
-                        }
-                    }
-
-                    // All good!
-                    transitionTo(mValidatedState);
-                    break;
-                default:
-                    return NOT_HANDLED;
-            }
-            return HANDLED;
-        }
-
-        private boolean inStrictMode() {
-            return !TextUtils.isEmpty(mPrivateDnsProviderHostname);
-        }
-
-        private boolean isStrictModeHostnameResolved() {
-            return (mPrivateDnsConfig != null)
-                    && mPrivateDnsConfig.hostname.equals(mPrivateDnsProviderHostname)
-                    && (mPrivateDnsConfig.ips.length > 0);
-        }
-
-        private void resolveStrictModeHostname() {
-            try {
-                // Do a blocking DNS resolution using the network-assigned nameservers.
-                final InetAddress[] ips = DnsUtils.getAllByName(mDependencies.getDnsResolver(),
-                        mCleartextDnsNetwork, mPrivateDnsProviderHostname, getDnsProbeTimeout());
-                mPrivateDnsConfig = new PrivateDnsConfig(mPrivateDnsProviderHostname, ips);
-                validationLog("Strict mode hostname resolved: " + mPrivateDnsConfig);
-            } catch (UnknownHostException uhe) {
-                mPrivateDnsConfig = null;
-                validationLog("Strict mode hostname resolution failed: " + uhe.getMessage());
-            }
-            mEvaluationState.reportProbeResult(NETWORK_VALIDATION_PROBE_PRIVDNS,
-                    (mPrivateDnsConfig != null) /* succeeded */);
-        }
-
-        private void notifyPrivateDnsConfigResolved() {
-            try {
-                mCallback.notifyPrivateDnsConfigResolved(mPrivateDnsConfig.toParcel());
-            } catch (RemoteException e) {
-                Log.e(TAG, "Error sending private DNS config resolved notification", e);
-            }
-        }
-
-        private void handlePrivateDnsEvaluationFailure() {
-            mEvaluationState.reportEvaluationResult(NETWORK_VALIDATION_RESULT_INVALID,
-                    null /* redirectUrl */);
-            // Queue up a re-evaluation with backoff.
-            //
-            // TODO: Consider abandoning this state after a few attempts and
-            // transitioning back to EvaluatingState, to perhaps give ourselves
-            // the opportunity to (re)detect a captive portal or something.
-            //
-            // TODO: distinguish between CMD_EVALUATE_PRIVATE_DNS messages that are caused by server
-            // lookup failures (which should continue to do exponential backoff) and
-            // CMD_EVALUATE_PRIVATE_DNS messages that are caused by user reconfiguration (which
-            // should be processed immediately.
-            sendMessageDelayed(CMD_EVALUATE_PRIVATE_DNS, mPrivateDnsReevalDelayMs);
-            mPrivateDnsReevalDelayMs *= 2;
-            if (mPrivateDnsReevalDelayMs > MAX_REEVALUATE_DELAY_MS) {
-                mPrivateDnsReevalDelayMs = MAX_REEVALUATE_DELAY_MS;
-            }
-        }
-
-        private boolean sendPrivateDnsProbe() {
-            // q.v. system/netd/server/dns/DnsTlsTransport.cpp
-            final String oneTimeHostnameSuffix = "-dnsotls-ds.metric.gstatic.com";
-            final String host = UUID.randomUUID().toString().substring(0, 8)
-                    + oneTimeHostnameSuffix;
-            final Stopwatch watch = new Stopwatch().start();
-            boolean success = false;
-            long time;
-            try {
-                final InetAddress[] ips = mNetwork.getAllByName(host);
-                time = watch.stop();
-                final String strIps = Arrays.toString(ips);
-                success = (ips != null && ips.length > 0);
-                validationLog(PROBE_PRIVDNS, host, String.format("%dms: %s", time, strIps));
-            } catch (UnknownHostException uhe) {
-                time = watch.stop();
-                validationLog(PROBE_PRIVDNS, host,
-                        String.format("%dms - Error: %s", time, uhe.getMessage()));
-            }
-            logValidationProbe(time, PROBE_PRIVDNS, success ? DNS_SUCCESS : DNS_FAILURE);
-            mEvaluationState.reportProbeResult(NETWORK_VALIDATION_PROBE_PRIVDNS, success);
-            return success;
-        }
-    }
-
-    private class ProbingState extends State {
-        private Thread mThread;
-
-        @Override
-        public void enter() {
-            if (mEvaluateAttempts >= BLAME_FOR_EVALUATION_ATTEMPTS) {
-                //Don't continue to blame UID forever.
-                TrafficStats.clearThreadStatsUid();
-            }
-
-            final int token = ++mProbeToken;
-            mThread = new Thread(() -> sendMessage(obtainMessage(CMD_PROBE_COMPLETE, token, 0,
-                    isCaptivePortal())));
-            mThread.start();
-        }
-
-        @Override
-        public boolean processMessage(Message message) {
-            switch (message.what) {
-                case CMD_PROBE_COMPLETE:
-                    // Ensure that CMD_PROBE_COMPLETE from stale threads are ignored.
-                    if (message.arg1 != mProbeToken) {
-                        return HANDLED;
-                    }
-
-                    final CaptivePortalProbeResult probeResult =
-                            (CaptivePortalProbeResult) message.obj;
-                    mLastProbeTime = SystemClock.elapsedRealtime();
-
-                    if (mCollectDataStallMetrics) {
-                        writeDataStallStats(probeResult);
-                    }
-
-                    if (probeResult.isSuccessful()) {
-                        // Transit EvaluatingPrivateDnsState to get to Validated
-                        // state (even if no Private DNS validation required).
-                        transitionTo(mEvaluatingPrivateDnsState);
-                    } else if (probeResult.isPortal()) {
-                        mEvaluationState.reportEvaluationResult(NETWORK_VALIDATION_RESULT_INVALID,
-                                probeResult.redirectUrl);
-                        mLastPortalProbeResult = probeResult;
-                        transitionTo(mCaptivePortalState);
-                    } else if (probeResult.isPartialConnectivity()) {
-                        mEvaluationState.reportEvaluationResult(NETWORK_VALIDATION_RESULT_PARTIAL,
-                                null /* redirectUrl */);
-                        // Check if disable https probing needed.
-                        maybeDisableHttpsProbing(mAcceptPartialConnectivity);
-                        if (mAcceptPartialConnectivity) {
-                            transitionTo(mEvaluatingPrivateDnsState);
-                        } else {
-                            transitionTo(mWaitingForNextProbeState);
-                        }
-                    } else {
-                        logNetworkEvent(NetworkEvent.NETWORK_VALIDATION_FAILED);
-                        mEvaluationState.reportEvaluationResult(NETWORK_VALIDATION_RESULT_INVALID,
-                                null /* redirectUrl */);
-                        transitionTo(mWaitingForNextProbeState);
-                    }
-                    return HANDLED;
-                case EVENT_DNS_NOTIFICATION:
-                case EVENT_ACCEPT_PARTIAL_CONNECTIVITY:
-                    // Leave the event to DefaultState.
-                    return NOT_HANDLED;
-                default:
-                    // Wait for probe result and defer events to next state by default.
-                    deferMessage(message);
-                    return HANDLED;
-            }
-        }
-
-        @Override
-        public void exit() {
-            if (mThread.isAlive()) {
-                mThread.interrupt();
-            }
-            mThread = null;
-        }
-    }
-
-    // Being in the WaitingForNextProbeState indicates that evaluating probes failed and state is
-    // transited from ProbingState. This ensures that the state machine is only in ProbingState
-    // while a probe is in progress, not while waiting to perform the next probe. That allows
-    // ProbingState to defer most messages until the probe is complete, which keeps the code simple
-    // and matches the pre-Q behaviour where probes were a blocking operation performed on the state
-    // machine thread.
-    private class WaitingForNextProbeState extends State {
-        @Override
-        public void enter() {
-            scheduleNextProbe();
-        }
-
-        private void scheduleNextProbe() {
-            final Message msg = obtainMessage(CMD_REEVALUATE, ++mReevaluateToken, 0);
-            sendMessageDelayed(msg, mReevaluateDelayMs);
-            mReevaluateDelayMs *= 2;
-            if (mReevaluateDelayMs > MAX_REEVALUATE_DELAY_MS) {
-                mReevaluateDelayMs = MAX_REEVALUATE_DELAY_MS;
-            }
-        }
-
-        @Override
-        public boolean processMessage(Message message) {
-            return NOT_HANDLED;
-        }
-    }
-
-    // Limits the list of IP addresses returned by getAllByName or tried by openConnection to at
-    // most one per address family. This ensures we only wait up to 20 seconds for TCP connections
-    // to complete, regardless of how many IP addresses a host has.
-    private static class OneAddressPerFamilyNetwork extends Network {
-        OneAddressPerFamilyNetwork(Network network) {
-            // Always bypass Private DNS.
-            super(network.getPrivateDnsBypassingCopy());
-        }
-
-        @Override
-        public InetAddress[] getAllByName(String host) throws UnknownHostException {
-            final List<InetAddress> addrs = Arrays.asList(super.getAllByName(host));
-
-            // Ensure the address family of the first address is tried first.
-            LinkedHashMap<Class, InetAddress> addressByFamily = new LinkedHashMap<>();
-            addressByFamily.put(addrs.get(0).getClass(), addrs.get(0));
-            Collections.shuffle(addrs);
-
-            for (InetAddress addr : addrs) {
-                addressByFamily.put(addr.getClass(), addr);
-            }
-
-            return addressByFamily.values().toArray(new InetAddress[addressByFamily.size()]);
-        }
-    }
-
-    private boolean getIsCaptivePortalCheckEnabled() {
-        String symbol = CAPTIVE_PORTAL_MODE;
-        int defaultValue = CAPTIVE_PORTAL_MODE_PROMPT;
-        int mode = mDependencies.getSetting(mContext, symbol, defaultValue);
-        return mode != CAPTIVE_PORTAL_MODE_IGNORE;
-    }
-
-    private boolean getUseHttpsValidation() {
-        return mDependencies.getDeviceConfigPropertyInt(NAMESPACE_CONNECTIVITY,
-                CAPTIVE_PORTAL_USE_HTTPS, 1) == 1;
-    }
-
-    private String getCaptivePortalServerHttpsUrl() {
-        return getSettingFromResource(mContext, R.string.config_captive_portal_https_url,
-                R.string.default_captive_portal_https_url, CAPTIVE_PORTAL_HTTPS_URL);
-    }
-
-    private int getDnsProbeTimeout() {
-        return getIntSetting(mContext, R.integer.config_captive_portal_dns_probe_timeout,
-                CONFIG_CAPTIVE_PORTAL_DNS_PROBE_TIMEOUT,
-                R.integer.default_captive_portal_dns_probe_timeout);
-    }
-
-    /**
-     * Gets an integer setting from resources or device config
-     *
-     * configResource is used if set, followed by device config if set, followed by defaultResource.
-     * If none of these are set then an exception is thrown.
-     *
-     * TODO: move to a common location such as a ConfigUtils class.
-     * TODO(b/130324939): test that the resources can be overlayed by an RRO package.
-     */
-    @VisibleForTesting
-    int getIntSetting(@NonNull final Context context, @StringRes int configResource,
-            @NonNull String symbol, @StringRes int defaultResource) {
-        final Resources res = context.getResources();
-        try {
-            return res.getInteger(configResource);
-        } catch (Resources.NotFoundException e) {
-            return mDependencies.getDeviceConfigPropertyInt(NAMESPACE_CONNECTIVITY,
-                    symbol, res.getInteger(defaultResource));
-        }
-    }
-
-    /**
-     * Get the captive portal server HTTP URL that is configured on the device.
-     *
-     * NetworkMonitor does not use {@link ConnectivityManager#getCaptivePortalServerUrl()} as
-     * it has its own updatable strategies to detect captive portals. The framework only advises
-     * on one URL that can be used, while NetworkMonitor may implement more complex logic.
-     */
-    public String getCaptivePortalServerHttpUrl() {
-        return getSettingFromResource(mContext, R.string.config_captive_portal_http_url,
-                R.string.default_captive_portal_http_url, CAPTIVE_PORTAL_HTTP_URL);
-    }
-
-    private int getConsecutiveDnsTimeoutThreshold() {
-        return mDependencies.getDeviceConfigPropertyInt(NAMESPACE_CONNECTIVITY,
-                CONFIG_DATA_STALL_CONSECUTIVE_DNS_TIMEOUT_THRESHOLD,
-                DEFAULT_CONSECUTIVE_DNS_TIMEOUT_THRESHOLD);
-    }
-
-    private int getDataStallMinEvaluateTime() {
-        return mDependencies.getDeviceConfigPropertyInt(NAMESPACE_CONNECTIVITY,
-                CONFIG_DATA_STALL_MIN_EVALUATE_INTERVAL,
-                DEFAULT_DATA_STALL_MIN_EVALUATE_TIME_MS);
-    }
-
-    private int getDataStallValidDnsTimeThreshold() {
-        return mDependencies.getDeviceConfigPropertyInt(NAMESPACE_CONNECTIVITY,
-                CONFIG_DATA_STALL_VALID_DNS_TIME_THRESHOLD,
-                DEFAULT_DATA_STALL_VALID_DNS_TIME_THRESHOLD_MS);
-    }
-
-    private int getDataStallEvaluationType() {
-        return mDependencies.getDeviceConfigPropertyInt(NAMESPACE_CONNECTIVITY,
-                CONFIG_DATA_STALL_EVALUATION_TYPE,
-                DEFAULT_DATA_STALL_EVALUATION_TYPES);
-    }
-
-    private URL[] makeCaptivePortalFallbackUrls() {
-        try {
-            final String firstUrl = mDependencies.getSetting(mContext, CAPTIVE_PORTAL_FALLBACK_URL,
-                    null);
-
-            final URL[] settingProviderUrls;
-            if (!TextUtils.isEmpty(firstUrl)) {
-                final String otherUrls = mDependencies.getDeviceConfigProperty(
-                        NAMESPACE_CONNECTIVITY, CAPTIVE_PORTAL_OTHER_FALLBACK_URLS, "");
-                // otherUrls may be empty, but .split() ignores trailing empty strings
-                final String separator = ",";
-                final String[] urls = (firstUrl + separator + otherUrls).split(separator);
-                settingProviderUrls = convertStrings(urls, this::makeURL, new URL[0]);
-            } else {
-                settingProviderUrls = new URL[0];
-            }
-
-            return getArrayConfig(settingProviderUrls, R.array.config_captive_portal_fallback_urls,
-                    R.array.default_captive_portal_fallback_urls, this::makeURL);
-        } catch (Exception e) {
-            // Don't let a misconfiguration bootloop the system.
-            Log.e(TAG, "Error parsing configured fallback URLs", e);
-            return new URL[0];
-        }
-    }
-
-    private CaptivePortalProbeSpec[] makeCaptivePortalFallbackProbeSpecs() {
-        try {
-            final String settingsValue = mDependencies.getDeviceConfigProperty(
-                    NAMESPACE_CONNECTIVITY, CAPTIVE_PORTAL_FALLBACK_PROBE_SPECS, null);
-
-            final CaptivePortalProbeSpec[] emptySpecs = new CaptivePortalProbeSpec[0];
-            final CaptivePortalProbeSpec[] providerValue = TextUtils.isEmpty(settingsValue)
-                    ? emptySpecs
-                    : parseCaptivePortalProbeSpecs(settingsValue).toArray(emptySpecs);
-
-            return getArrayConfig(providerValue, R.array.config_captive_portal_fallback_probe_specs,
-                    R.array.default_captive_portal_fallback_probe_specs,
-                    CaptivePortalProbeSpec::parseSpecOrNull);
-        } catch (Exception e) {
-            // Don't let a misconfiguration bootloop the system.
-            Log.e(TAG, "Error parsing configured fallback probe specs", e);
-            return null;
-        }
-    }
-
-    /**
-     * Read a setting from a resource or the settings provider.
-     *
-     * <p>The configuration resource is prioritized, then the provider value, then the default
-     * resource value.
-     * @param context The context
-     * @param configResource The resource id for the configuration parameter
-     * @param defaultResource The resource id for the default value
-     * @param symbol The symbol in the settings provider
-     * @return The best available value
-     */
-    @NonNull
-    private String getSettingFromResource(@NonNull final Context context,
-            @StringRes int configResource, @StringRes int defaultResource,
-            @NonNull String symbol) {
-        final Resources res = context.getResources();
-        String setting = res.getString(configResource);
-
-        if (!TextUtils.isEmpty(setting)) return setting;
-
-        setting = mDependencies.getSetting(context, symbol, null);
-        if (!TextUtils.isEmpty(setting)) return setting;
-
-        return res.getString(defaultResource);
-    }
-
-    /**
-     * Get an array configuration from resources or the settings provider.
-     *
-     * <p>The configuration resource is prioritized, then the provider values, then the default
-     * resource values.
-     * @param providerValue Values obtained from the setting provider.
-     * @param configResId ID of the configuration resource.
-     * @param defaultResId ID of the default resource.
-     * @param resourceConverter Converter from the resource strings to stored setting class. Null
-     *                          return values are ignored.
-     */
-    private <T> T[] getArrayConfig(@NonNull T[] providerValue, @ArrayRes int configResId,
-            @ArrayRes int defaultResId, @NonNull Function<String, T> resourceConverter) {
-        final Resources res = mContext.getResources();
-        String[] configValue = res.getStringArray(configResId);
-
-        if (configValue.length == 0) {
-            if (providerValue.length > 0) {
-                return providerValue;
-            }
-
-            configValue = res.getStringArray(defaultResId);
-        }
-
-        return convertStrings(configValue, resourceConverter, Arrays.copyOf(providerValue, 0));
-    }
-
-    /**
-     * Convert a String array to an array of some other type using the specified converter.
-     *
-     * <p>Any null value, or value for which the converter throws a {@link RuntimeException}, will
-     * not be added to the output array, so the output array may be smaller than the input.
-     */
-    private <T> T[] convertStrings(
-            @NonNull String[] strings, Function<String, T> converter, T[] emptyArray) {
-        final ArrayList<T> convertedValues = new ArrayList<>(strings.length);
-        for (String configString : strings) {
-            T convertedValue = null;
-            try {
-                convertedValue = converter.apply(configString);
-            } catch (Exception e) {
-                Log.e(TAG, "Error parsing configuration", e);
-                // Fall through
-            }
-            if (convertedValue != null) {
-                convertedValues.add(convertedValue);
-            }
-        }
-        return convertedValues.toArray(emptyArray);
-    }
-
-    private String getCaptivePortalUserAgent() {
-        return mDependencies.getDeviceConfigProperty(NAMESPACE_CONNECTIVITY,
-                CAPTIVE_PORTAL_USER_AGENT, DEFAULT_USER_AGENT);
-    }
-
-    private URL nextFallbackUrl() {
-        if (mCaptivePortalFallbackUrls.length == 0) {
-            return null;
-        }
-        int idx = Math.abs(mNextFallbackUrlIndex) % mCaptivePortalFallbackUrls.length;
-        mNextFallbackUrlIndex += mRandom.nextInt(); // randomly change url without memory.
-        return mCaptivePortalFallbackUrls[idx];
-    }
-
-    private CaptivePortalProbeSpec nextFallbackSpec() {
-        if (isEmpty(mCaptivePortalFallbackSpecs)) {
-            return null;
-        }
-        // Randomly change spec without memory. Also randomize the first attempt.
-        final int idx = Math.abs(mRandom.nextInt()) % mCaptivePortalFallbackSpecs.length;
-        return mCaptivePortalFallbackSpecs[idx];
-    }
-
-    @VisibleForTesting
-    protected CaptivePortalProbeResult isCaptivePortal() {
-        if (!mIsCaptivePortalCheckEnabled) {
-            validationLog("Validation disabled.");
-            return CaptivePortalProbeResult.SUCCESS;
-        }
-
-        URL pacUrl = null;
-        URL httpsUrl = mCaptivePortalHttpsUrl;
-        URL httpUrl = mCaptivePortalHttpUrl;
-
-        // On networks with a PAC instead of fetching a URL that should result in a 204
-        // response, we instead simply fetch the PAC script.  This is done for a few reasons:
-        // 1. At present our PAC code does not yet handle multiple PACs on multiple networks
-        //    until something like https://android-review.googlesource.com/#/c/115180/ lands.
-        //    Network.openConnection() will ignore network-specific PACs and instead fetch
-        //    using NO_PROXY.  If a PAC is in place, the only fetch we know will succeed with
-        //    NO_PROXY is the fetch of the PAC itself.
-        // 2. To proxy the generate_204 fetch through a PAC would require a number of things
-        //    happen before the fetch can commence, namely:
-        //        a) the PAC script be fetched
-        //        b) a PAC script resolver service be fired up and resolve the captive portal
-        //           server.
-        //    Network validation could be delayed until these prerequisities are satisifed or
-        //    could simply be left to race them.  Neither is an optimal solution.
-        // 3. PAC scripts are sometimes used to block or restrict Internet access and may in
-        //    fact block fetching of the generate_204 URL which would lead to false negative
-        //    results for network validation.
-        final ProxyInfo proxyInfo = mLinkProperties.getHttpProxy();
-        if (proxyInfo != null && !Uri.EMPTY.equals(proxyInfo.getPacFileUrl())) {
-            pacUrl = makeURL(proxyInfo.getPacFileUrl().toString());
-            if (pacUrl == null) {
-                return CaptivePortalProbeResult.FAILED;
-            }
-        }
-
-        if ((pacUrl == null) && (httpUrl == null || httpsUrl == null)) {
-            return CaptivePortalProbeResult.FAILED;
-        }
-
-        long startTime = SystemClock.elapsedRealtime();
-
-        final CaptivePortalProbeResult result;
-        if (pacUrl != null) {
-            result = sendDnsAndHttpProbes(null, pacUrl, ValidationProbeEvent.PROBE_PAC);
-            reportHttpProbeResult(NETWORK_VALIDATION_PROBE_HTTP, result);
-        } else if (mUseHttps) {
-            // Probe results are reported inside sendParallelHttpProbes.
-            result = sendParallelHttpProbes(proxyInfo, httpsUrl, httpUrl);
-        } else {
-            result = sendDnsAndHttpProbes(proxyInfo, httpUrl, ValidationProbeEvent.PROBE_HTTP);
-            reportHttpProbeResult(NETWORK_VALIDATION_PROBE_HTTP, result);
-        }
-
-        long endTime = SystemClock.elapsedRealtime();
-
-        sendNetworkConditionsBroadcast(true /* response received */,
-                result.isPortal() /* isCaptivePortal */,
-                startTime, endTime);
-
-        log("isCaptivePortal: isSuccessful()=" + result.isSuccessful()
-                + " isPortal()=" + result.isPortal()
-                + " RedirectUrl=" + result.redirectUrl
-                + " isPartialConnectivity()=" + result.isPartialConnectivity()
-                + " Time=" + (endTime - startTime) + "ms");
-
-        return result;
-    }
-
-    /**
-     * Do a DNS resolution and URL fetch on a known web server to see if we get the data we expect.
-     * @return a CaptivePortalProbeResult inferred from the HTTP response.
-     */
-    private CaptivePortalProbeResult sendDnsAndHttpProbes(ProxyInfo proxy, URL url, int probeType) {
-        // Pre-resolve the captive portal server host so we can log it.
-        // Only do this if HttpURLConnection is about to, to avoid any potentially
-        // unnecessary resolution.
-        final String host = (proxy != null) ? proxy.getHost() : url.getHost();
-        // This method cannot safely report probe results because it might not be running on the
-        // state machine thread. Reporting results here would cause races and potentially send
-        // information to callers that does not make sense because the state machine has already
-        // changed state.
-        sendDnsProbe(host);
-        return sendHttpProbe(url, probeType, null);
-    }
-
-    /** Do a DNS lookup for the given server, or throw UnknownHostException after timeoutMs */
-    @VisibleForTesting
-    protected InetAddress[] sendDnsProbeWithTimeout(String host, int timeoutMs)
-                throws UnknownHostException {
-        return DnsUtils.getAllByName(mDependencies.getDnsResolver(), mCleartextDnsNetwork, host,
-                TYPE_ADDRCONFIG, FLAG_EMPTY, timeoutMs);
-    }
-
-    /** Do a DNS resolution of the given server. */
-    private void sendDnsProbe(String host) {
-        if (TextUtils.isEmpty(host)) {
-            return;
-        }
-
-        final String name = ValidationProbeEvent.getProbeName(ValidationProbeEvent.PROBE_DNS);
-        final Stopwatch watch = new Stopwatch().start();
-        int result;
-        String connectInfo;
-        try {
-            InetAddress[] addresses = sendDnsProbeWithTimeout(host, getDnsProbeTimeout());
-            StringBuffer buffer = new StringBuffer();
-            for (InetAddress address : addresses) {
-                buffer.append(',').append(address.getHostAddress());
-            }
-            result = ValidationProbeEvent.DNS_SUCCESS;
-            connectInfo = "OK " + buffer.substring(1);
-        } catch (UnknownHostException e) {
-            result = ValidationProbeEvent.DNS_FAILURE;
-            connectInfo = "FAIL";
-        }
-        final long latency = watch.stop();
-        validationLog(ValidationProbeEvent.PROBE_DNS, host,
-                String.format("%dms %s", latency, connectInfo));
-        logValidationProbe(latency, ValidationProbeEvent.PROBE_DNS, result);
-    }
-
-    /**
-     * Do a URL fetch on a known web server to see if we get the data we expect.
-     * @return a CaptivePortalProbeResult inferred from the HTTP response.
-     */
-    @VisibleForTesting
-    protected CaptivePortalProbeResult sendHttpProbe(URL url, int probeType,
-            @Nullable CaptivePortalProbeSpec probeSpec) {
-        HttpURLConnection urlConnection = null;
-        int httpResponseCode = CaptivePortalProbeResult.FAILED_CODE;
-        String redirectUrl = null;
-        final Stopwatch probeTimer = new Stopwatch().start();
-        final int oldTag = TrafficStats.getAndSetThreadStatsTag(
-                TrafficStatsConstants.TAG_SYSTEM_PROBE);
-        try {
-            urlConnection = (HttpURLConnection) mCleartextDnsNetwork.openConnection(url);
-            urlConnection.setInstanceFollowRedirects(probeType == ValidationProbeEvent.PROBE_PAC);
-            urlConnection.setConnectTimeout(SOCKET_TIMEOUT_MS);
-            urlConnection.setReadTimeout(SOCKET_TIMEOUT_MS);
-            urlConnection.setRequestProperty("Connection", "close");
-            urlConnection.setUseCaches(false);
-            if (mCaptivePortalUserAgent != null) {
-                urlConnection.setRequestProperty("User-Agent", mCaptivePortalUserAgent);
-            }
-            // cannot read request header after connection
-            String requestHeader = urlConnection.getRequestProperties().toString();
-
-            // Time how long it takes to get a response to our request
-            long requestTimestamp = SystemClock.elapsedRealtime();
-
-            httpResponseCode = urlConnection.getResponseCode();
-            redirectUrl = urlConnection.getHeaderField("location");
-
-            // Time how long it takes to get a response to our request
-            long responseTimestamp = SystemClock.elapsedRealtime();
-
-            validationLog(probeType, url, "time=" + (responseTimestamp - requestTimestamp) + "ms"
-                    + " ret=" + httpResponseCode
-                    + " request=" + requestHeader
-                    + " headers=" + urlConnection.getHeaderFields());
-            // NOTE: We may want to consider an "HTTP/1.0 204" response to be a captive
-            // portal.  The only example of this seen so far was a captive portal.  For
-            // the time being go with prior behavior of assuming it's not a captive
-            // portal.  If it is considered a captive portal, a different sign-in URL
-            // is needed (i.e. can't browse a 204).  This could be the result of an HTTP
-            // proxy server.
-            if (httpResponseCode == 200) {
-                long contentLength = urlConnection.getContentLengthLong();
-                if (probeType == ValidationProbeEvent.PROBE_PAC) {
-                    validationLog(
-                            probeType, url, "PAC fetch 200 response interpreted as 204 response.");
-                    httpResponseCode = CaptivePortalProbeResult.SUCCESS_CODE;
-                } else if (contentLength == -1) {
-                    // When no Content-length (default value == -1), attempt to read a byte
-                    // from the response. Do not use available() as it is unreliable.
-                    // See http://b/33498325.
-                    if (urlConnection.getInputStream().read() == -1) {
-                        validationLog(probeType, url,
-                                "Empty 200 response interpreted as failed response.");
-                        httpResponseCode = CaptivePortalProbeResult.FAILED_CODE;
-                    }
-                } else if (contentLength <= 4) {
-                    // Consider 200 response with "Content-length <= 4" to not be a captive
-                    // portal. There's no point in considering this a captive portal as the
-                    // user cannot sign-in to an empty page. Probably the result of a broken
-                    // transparent proxy. See http://b/9972012 and http://b/122999481.
-                    validationLog(probeType, url, "200 response with Content-length <= 4"
-                            + " interpreted as failed response.");
-                    httpResponseCode = CaptivePortalProbeResult.FAILED_CODE;
-                }
-            }
-        } catch (IOException e) {
-            validationLog(probeType, url, "Probe failed with exception " + e);
-            if (httpResponseCode == CaptivePortalProbeResult.FAILED_CODE) {
-                // TODO: Ping gateway and DNS server and log results.
-            }
-        } finally {
-            if (urlConnection != null) {
-                urlConnection.disconnect();
-            }
-            TrafficStats.setThreadStatsTag(oldTag);
-        }
-        logValidationProbe(probeTimer.stop(), probeType, httpResponseCode);
-
-        if (probeSpec == null) {
-            return new CaptivePortalProbeResult(httpResponseCode, redirectUrl, url.toString());
-        } else {
-            return probeSpec.getResult(httpResponseCode, redirectUrl);
-        }
-    }
-
-    private CaptivePortalProbeResult sendParallelHttpProbes(
-            ProxyInfo proxy, URL httpsUrl, URL httpUrl) {
-        // Number of probes to wait for. If a probe completes with a conclusive answer
-        // it shortcuts the latch immediately by forcing the count to 0.
-        final CountDownLatch latch = new CountDownLatch(2);
-
-        final class ProbeThread extends Thread {
-            private final boolean mIsHttps;
-            private volatile CaptivePortalProbeResult mResult = CaptivePortalProbeResult.FAILED;
-
-            ProbeThread(boolean isHttps) {
-                mIsHttps = isHttps;
-            }
-
-            public CaptivePortalProbeResult result() {
-                return mResult;
-            }
-
-            @Override
-            public void run() {
-                if (mIsHttps) {
-                    mResult =
-                            sendDnsAndHttpProbes(proxy, httpsUrl, ValidationProbeEvent.PROBE_HTTPS);
-                } else {
-                    mResult = sendDnsAndHttpProbes(proxy, httpUrl, ValidationProbeEvent.PROBE_HTTP);
-                }
-                if ((mIsHttps && mResult.isSuccessful()) || (!mIsHttps && mResult.isPortal())) {
-                    // Stop waiting immediately if https succeeds or if http finds a portal.
-                    while (latch.getCount() > 0) {
-                        latch.countDown();
-                    }
-                }
-                // Signal this probe has completed.
-                latch.countDown();
-            }
-        }
-
-        final ProbeThread httpsProbe = new ProbeThread(true);
-        final ProbeThread httpProbe = new ProbeThread(false);
-
-        try {
-            httpsProbe.start();
-            httpProbe.start();
-            latch.await(PROBE_TIMEOUT_MS, TimeUnit.MILLISECONDS);
-        } catch (InterruptedException e) {
-            validationLog("Error: probes wait interrupted!");
-            return CaptivePortalProbeResult.FAILED;
-        }
-
-        final CaptivePortalProbeResult httpsResult = httpsProbe.result();
-        final CaptivePortalProbeResult httpResult = httpProbe.result();
-
-        // Look for a conclusive probe result first.
-        if (httpResult.isPortal()) {
-            reportHttpProbeResult(NETWORK_VALIDATION_PROBE_HTTP, httpResult);
-            return httpResult;
-        }
-        // httpsResult.isPortal() is not expected, but check it nonetheless.
-        if (httpsResult.isPortal() || httpsResult.isSuccessful()) {
-            reportHttpProbeResult(NETWORK_VALIDATION_PROBE_HTTPS, httpsResult);
-            return httpsResult;
-        }
-        // If a fallback method exists, use it to retry portal detection.
-        // If we have new-style probe specs, use those. Otherwise, use the fallback URLs.
-        final CaptivePortalProbeSpec probeSpec = nextFallbackSpec();
-        final URL fallbackUrl = (probeSpec != null) ? probeSpec.getUrl() : nextFallbackUrl();
-        CaptivePortalProbeResult fallbackProbeResult = null;
-        if (fallbackUrl != null) {
-            fallbackProbeResult = sendHttpProbe(fallbackUrl, PROBE_FALLBACK, probeSpec);
-            reportHttpProbeResult(NETWORK_VALIDATION_PROBE_FALLBACK, fallbackProbeResult);
-            if (fallbackProbeResult.isPortal()) {
-                return fallbackProbeResult;
-            }
-        }
-        // Otherwise wait until http and https probes completes and use their results.
-        try {
-            httpProbe.join();
-            reportHttpProbeResult(NETWORK_VALIDATION_PROBE_HTTP, httpProbe.result());
-
-            if (httpProbe.result().isPortal()) {
-                return httpProbe.result();
-            }
-
-            httpsProbe.join();
-            reportHttpProbeResult(NETWORK_VALIDATION_PROBE_HTTPS, httpsProbe.result());
-
-            final boolean isHttpSuccessful =
-                    (httpProbe.result().isSuccessful()
-                    || (fallbackProbeResult != null && fallbackProbeResult.isSuccessful()));
-            if (httpsProbe.result().isFailed() && isHttpSuccessful) {
-                return CaptivePortalProbeResult.PARTIAL;
-            }
-            return httpsProbe.result();
-        } catch (InterruptedException e) {
-            validationLog("Error: http or https probe wait interrupted!");
-            return CaptivePortalProbeResult.FAILED;
-        }
-    }
-
-    private URL makeURL(String url) {
-        if (url != null) {
-            try {
-                return new URL(url);
-            } catch (MalformedURLException e) {
-                validationLog("Bad URL: " + url);
-            }
-        }
-        return null;
-    }
-
-    /**
-     * @param responseReceived - whether or not we received a valid HTTP response to our request.
-     * If false, isCaptivePortal and responseTimestampMs are ignored
-     * TODO: This should be moved to the transports.  The latency could be passed to the transports
-     * along with the captive portal result.  Currently the TYPE_MOBILE broadcasts appear unused so
-     * perhaps this could just be added to the WiFi transport only.
-     */
-    private void sendNetworkConditionsBroadcast(boolean responseReceived, boolean isCaptivePortal,
-            long requestTimestampMs, long responseTimestampMs) {
-        Intent latencyBroadcast =
-                new Intent(NetworkMonitorUtils.ACTION_NETWORK_CONDITIONS_MEASURED);
-        if (mNetworkCapabilities.hasTransport(TRANSPORT_WIFI)) {
-            if (!mWifiManager.isScanAlwaysAvailable()) {
-                return;
-            }
-
-            WifiInfo currentWifiInfo = mWifiManager.getConnectionInfo();
-            if (currentWifiInfo != null) {
-                // NOTE: getSSID()'s behavior changed in API 17; before that, SSIDs were not
-                // surrounded by double quotation marks (thus violating the Javadoc), but this
-                // was changed to match the Javadoc in API 17. Since clients may have started
-                // sanitizing the output of this method since API 17 was released, we should
-                // not change it here as it would become impossible to tell whether the SSID is
-                // simply being surrounded by quotes due to the API, or whether those quotes
-                // are actually part of the SSID.
-                latencyBroadcast.putExtra(NetworkMonitorUtils.EXTRA_SSID,
-                        currentWifiInfo.getSSID());
-                latencyBroadcast.putExtra(NetworkMonitorUtils.EXTRA_BSSID,
-                        currentWifiInfo.getBSSID());
-            } else {
-                if (VDBG) logw("network info is TYPE_WIFI but no ConnectionInfo found");
-                return;
-            }
-            latencyBroadcast.putExtra(NetworkMonitorUtils.EXTRA_CONNECTIVITY_TYPE, TYPE_WIFI);
-        } else if (mNetworkCapabilities.hasTransport(TRANSPORT_CELLULAR)) {
-            // TODO(b/123893112): Support multi-sim.
-            latencyBroadcast.putExtra(NetworkMonitorUtils.EXTRA_NETWORK_TYPE,
-                    mTelephonyManager.getNetworkType());
-            final ServiceState dataSs = mTelephonyManager.getServiceState();
-            if (dataSs == null) {
-                logw("failed to retrieve ServiceState");
-                return;
-            }
-            // See if the data sub is registered for PS services on cell.
-            final NetworkRegistrationInfo nri = dataSs.getNetworkRegistrationInfo(
-                    NetworkRegistrationInfo.DOMAIN_PS,
-                    AccessNetworkConstants.TRANSPORT_TYPE_WWAN);
-            latencyBroadcast.putExtra(
-                    NetworkMonitorUtils.EXTRA_CELL_ID,
-                    nri == null ? null : nri.getCellIdentity());
-            latencyBroadcast.putExtra(NetworkMonitorUtils.EXTRA_CONNECTIVITY_TYPE, TYPE_MOBILE);
-        } else {
-            return;
-        }
-        latencyBroadcast.putExtra(NetworkMonitorUtils.EXTRA_RESPONSE_RECEIVED,
-                responseReceived);
-        latencyBroadcast.putExtra(NetworkMonitorUtils.EXTRA_REQUEST_TIMESTAMP_MS,
-                requestTimestampMs);
-
-        if (responseReceived) {
-            latencyBroadcast.putExtra(NetworkMonitorUtils.EXTRA_IS_CAPTIVE_PORTAL,
-                    isCaptivePortal);
-            latencyBroadcast.putExtra(NetworkMonitorUtils.EXTRA_RESPONSE_TIMESTAMP_MS,
-                    responseTimestampMs);
-        }
-        mContext.sendBroadcastAsUser(latencyBroadcast, UserHandle.CURRENT,
-                NetworkMonitorUtils.PERMISSION_ACCESS_NETWORK_CONDITIONS);
-    }
-
-    private void logNetworkEvent(int evtype) {
-        int[] transports = mNetworkCapabilities.getTransportTypes();
-        mMetricsLog.log(mCleartextDnsNetwork, transports, new NetworkEvent(evtype));
-    }
-
-    private int networkEventType(ValidationStage s, EvaluationResult r) {
-        if (s.mIsFirstValidation) {
-            if (r.mIsValidated) {
-                return NetworkEvent.NETWORK_FIRST_VALIDATION_SUCCESS;
-            } else {
-                return NetworkEvent.NETWORK_FIRST_VALIDATION_PORTAL_FOUND;
-            }
-        } else {
-            if (r.mIsValidated) {
-                return NetworkEvent.NETWORK_REVALIDATION_SUCCESS;
-            } else {
-                return NetworkEvent.NETWORK_REVALIDATION_PORTAL_FOUND;
-            }
-        }
-    }
-
-    private void maybeLogEvaluationResult(int evtype) {
-        if (mEvaluationTimer.isRunning()) {
-            int[] transports = mNetworkCapabilities.getTransportTypes();
-            mMetricsLog.log(mCleartextDnsNetwork, transports,
-                    new NetworkEvent(evtype, mEvaluationTimer.stop()));
-            mEvaluationTimer.reset();
-        }
-    }
-
-    private void logValidationProbe(long durationMs, int probeType, int probeResult) {
-        int[] transports = mNetworkCapabilities.getTransportTypes();
-        boolean isFirstValidation = validationStage().mIsFirstValidation;
-        ValidationProbeEvent ev = new ValidationProbeEvent.Builder()
-                .setProbeType(probeType, isFirstValidation)
-                .setReturnCode(probeResult)
-                .setDurationMs(durationMs)
-                .build();
-        mMetricsLog.log(mCleartextDnsNetwork, transports, ev);
-    }
-
-    @VisibleForTesting
-    static class Dependencies {
-        public Network getPrivateDnsBypassNetwork(Network network) {
-            return new OneAddressPerFamilyNetwork(network);
-        }
-
-        public DnsResolver getDnsResolver() {
-            return DnsResolver.getInstance();
-        }
-
-        public Random getRandom() {
-            return new Random();
-        }
-
-        /**
-         * Get the value of a global integer setting.
-         * @param symbol Name of the setting
-         * @param defaultValue Value to return if the setting is not defined.
-         */
-        public int getSetting(Context context, String symbol, int defaultValue) {
-            return Settings.Global.getInt(context.getContentResolver(), symbol, defaultValue);
-        }
-
-        /**
-         * Get the value of a global String setting.
-         * @param symbol Name of the setting
-         * @param defaultValue Value to return if the setting is not defined.
-         */
-        public String getSetting(Context context, String symbol, String defaultValue) {
-            final String value = Settings.Global.getString(context.getContentResolver(), symbol);
-            return value != null ? value : defaultValue;
-        }
-
-        /**
-         * Look up the value of a property in DeviceConfig.
-         * @param namespace The namespace containing the property to look up.
-         * @param name The name of the property to look up.
-         * @param defaultValue The value to return if the property does not exist or has no non-null
-         *                     value.
-         * @return the corresponding value, or defaultValue if none exists.
-         */
-        @Nullable
-        public String getDeviceConfigProperty(@NonNull String namespace, @NonNull String name,
-                @Nullable String defaultValue) {
-            return NetworkStackUtils.getDeviceConfigProperty(namespace, name, defaultValue);
-        }
-
-        /**
-         * Look up the value of a property in DeviceConfig.
-         * @param namespace The namespace containing the property to look up.
-         * @param name The name of the property to look up.
-         * @param defaultValue The value to return if the property does not exist or has no non-null
-         *                     value.
-         * @return the corresponding value, or defaultValue if none exists.
-         */
-        public int getDeviceConfigPropertyInt(@NonNull String namespace, @NonNull String name,
-                int defaultValue) {
-            return NetworkStackUtils.getDeviceConfigPropertyInt(namespace, name, defaultValue);
-        }
-
-        public static final Dependencies DEFAULT = new Dependencies();
-    }
-
-    /**
-     * Methods in this class perform no locking because all accesses are performed on the state
-     * machine's thread. Need to consider the thread safety if it ever could be accessed outside the
-     * state machine.
-     */
-    @VisibleForTesting
-    protected class DnsStallDetector {
-        private int mConsecutiveTimeoutCount = 0;
-        private int mSize;
-        final DnsResult[] mDnsEvents;
-        final RingBufferIndices mResultIndices;
-
-        DnsStallDetector(int size) {
-            mSize = Math.max(DEFAULT_DNS_LOG_SIZE, size);
-            mDnsEvents = new DnsResult[mSize];
-            mResultIndices = new RingBufferIndices(mSize);
-        }
-
-        @VisibleForTesting
-        protected void accumulateConsecutiveDnsTimeoutCount(int code) {
-            final DnsResult result = new DnsResult(code);
-            mDnsEvents[mResultIndices.add()] = result;
-            if (result.isTimeout()) {
-                mConsecutiveTimeoutCount++;
-            } else {
-                // Keep the event in mDnsEvents without clearing it so that there are logs to do the
-                // simulation and analysis.
-                mConsecutiveTimeoutCount = 0;
-            }
-        }
-
-        private boolean isDataStallSuspected(int timeoutCountThreshold, int validTime) {
-            if (timeoutCountThreshold <= 0) {
-                Log.wtf(TAG, "Timeout count threshold should be larger than 0.");
-                return false;
-            }
-
-            // Check if the consecutive timeout count reach the threshold or not.
-            if (mConsecutiveTimeoutCount < timeoutCountThreshold) {
-                return false;
-            }
-
-            // Check if the target dns event index is valid or not.
-            final int firstConsecutiveTimeoutIndex =
-                    mResultIndices.indexOf(mResultIndices.size() - timeoutCountThreshold);
-
-            // If the dns timeout events happened long time ago, the events are meaningless for
-            // data stall evaluation. Thus, check if the first consecutive timeout dns event
-            // considered in the evaluation happened in defined threshold time.
-            final long now = SystemClock.elapsedRealtime();
-            final long firstTimeoutTime = now - mDnsEvents[firstConsecutiveTimeoutIndex].mTimeStamp;
-            return (firstTimeoutTime < validTime);
-        }
-
-        int getConsecutiveTimeoutCount() {
-            return mConsecutiveTimeoutCount;
-        }
-    }
-
-    private static class DnsResult {
-        // TODO: Need to move the DNS return code definition to a specific class once unify DNS
-        // response code is done.
-        private static final int RETURN_CODE_DNS_TIMEOUT = 255;
-
-        private final long mTimeStamp;
-        private final int mReturnCode;
-
-        DnsResult(int code) {
-            mTimeStamp = SystemClock.elapsedRealtime();
-            mReturnCode = code;
-        }
-
-        private boolean isTimeout() {
-            return mReturnCode == RETURN_CODE_DNS_TIMEOUT;
-        }
-    }
-
-
-    @VisibleForTesting
-    protected DnsStallDetector getDnsStallDetector() {
-        return mDnsStallDetector;
-    }
-
-    private boolean dataStallEvaluateTypeEnabled(int type) {
-        return (mDataStallEvaluationType & type) != 0;
-    }
-
-    @VisibleForTesting
-    protected long getLastProbeTime() {
-        return mLastProbeTime;
-    }
-
-    @VisibleForTesting
-    protected boolean isDataStall() {
-        boolean result = false;
-        // Reevaluation will generate traffic. Thus, set a minimal reevaluation timer to limit the
-        // possible traffic cost in metered network.
-        if (!mNetworkCapabilities.hasCapability(NET_CAPABILITY_NOT_METERED)
-                && (SystemClock.elapsedRealtime() - getLastProbeTime()
-                < mDataStallMinEvaluateTime)) {
-            return false;
-        }
-
-        // Check dns signal. Suspect it may be a data stall if both :
-        // 1. The number of consecutive DNS query timeouts >= mConsecutiveDnsTimeoutThreshold.
-        // 2. Those consecutive DNS queries happened in the last mValidDataStallDnsTimeThreshold ms.
-        if (dataStallEvaluateTypeEnabled(DATA_STALL_EVALUATION_TYPE_DNS)) {
-            if (mDnsStallDetector.isDataStallSuspected(mConsecutiveDnsTimeoutThreshold,
-                    mDataStallValidDnsTimeThreshold)) {
-                result = true;
-                logNetworkEvent(NetworkEvent.NETWORK_CONSECUTIVE_DNS_TIMEOUT_FOUND);
-            }
-        }
-
-        if (VDBG_STALL) {
-            log("isDataStall: result=" + result + ", consecutive dns timeout count="
-                    + mDnsStallDetector.getConsecutiveTimeoutCount());
-        }
-
-        return result;
-    }
-
-    // Class to keep state of evaluation results and probe results.
-    // The main purpose is to ensure NetworkMonitor can notify ConnectivityService of probe results
-    // as soon as they happen, without triggering any other changes. This requires keeping state on
-    // the most recent evaluation result. Calling reportProbeResult will ensure that the results
-    // reported to ConnectivityService contain the previous evaluation result, and thus won't
-    // trigger a validation or partial connectivity state change.
-    @VisibleForTesting
-    protected class EvaluationState {
-        // The latest validation result for this network. This is a bitmask of
-        // INetworkMonitor.NETWORK_VALIDATION_RESULT_* constants.
-        private int mEvaluationResult = NETWORK_VALIDATION_RESULT_INVALID;
-        // Indicates which probes have completed since clearProbeResults was called.
-        // This is a bitmask of INetworkMonitor.NETWORK_VALIDATION_PROBE_* constants.
-        private int mProbeResults = 0;
-        // The latest redirect URL.
-        private String mRedirectUrl;
-
-        protected void clearProbeResults() {
-            mProbeResults = 0;
-        }
-
-        // Probe result for http probe should be updated from reportHttpProbeResult().
-        protected void reportProbeResult(int probeResult, boolean succeeded) {
-            if (succeeded) {
-                mProbeResults |= probeResult;
-            } else {
-                mProbeResults &= ~probeResult;
-            }
-            notifyNetworkTested(getNetworkTestResult(), mRedirectUrl);
-        }
-
-        protected void reportEvaluationResult(int result, @Nullable String redirectUrl) {
-            mEvaluationResult = result;
-            mRedirectUrl = redirectUrl;
-            notifyNetworkTested(getNetworkTestResult(), mRedirectUrl);
-        }
-
-        protected int getNetworkTestResult() {
-            return mEvaluationResult | mProbeResults;
-        }
-    }
-
-    @VisibleForTesting
-    protected EvaluationState getEvaluationState() {
-        return mEvaluationState;
-    }
-
-    private void maybeDisableHttpsProbing(boolean acceptPartial) {
-        mAcceptPartialConnectivity = acceptPartial;
-        // Ignore https probe in next validation if user accept partial connectivity on a partial
-        // connectivity network.
-        if (((mEvaluationState.getNetworkTestResult() & NETWORK_VALIDATION_RESULT_PARTIAL) != 0)
-                && mAcceptPartialConnectivity) {
-            mUseHttps = false;
-        }
-    }
-
-    // Report HTTP, HTTP or FALLBACK probe result.
-    @VisibleForTesting
-    protected void reportHttpProbeResult(int probeResult,
-                @NonNull final CaptivePortalProbeResult result) {
-        boolean succeeded = result.isSuccessful();
-        // The success of a HTTP probe does not tell us whether the DNS probe succeeded.
-        // The DNS and HTTP probes run one after the other in sendDnsAndHttpProbes, and that
-        // method cannot report the result of the DNS probe because that it could be running
-        // on a different thread which is racing with the main state machine thread. So, if
-        // an HTTP or HTTPS probe succeeded, assume that the DNS probe succeeded. But if an
-        // HTTP or HTTPS probe failed, don't assume that DNS is not working.
-        // TODO: fix this.
-        if (succeeded) {
-            probeResult |= NETWORK_VALIDATION_PROBE_DNS;
-        }
-        mEvaluationState.reportProbeResult(probeResult, succeeded);
-    }
-}
diff --git a/packages/NetworkStack/src/com/android/server/connectivity/ipmemorystore/IpMemoryStoreDatabase.java b/packages/NetworkStack/src/com/android/server/connectivity/ipmemorystore/IpMemoryStoreDatabase.java
deleted file mode 100644
index a538a5b..0000000
--- a/packages/NetworkStack/src/com/android/server/connectivity/ipmemorystore/IpMemoryStoreDatabase.java
+++ /dev/null
@@ -1,703 +0,0 @@
-/*
- * Copyright (C) 2019 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.server.connectivity.ipmemorystore;
-
-import static android.net.shared.Inet4AddressUtils.inet4AddressToIntHTH;
-import static android.net.shared.Inet4AddressUtils.intToInet4AddressHTH;
-
-import android.annotation.NonNull;
-import android.annotation.Nullable;
-import android.content.ContentValues;
-import android.content.Context;
-import android.database.Cursor;
-import android.database.sqlite.SQLiteCursor;
-import android.database.sqlite.SQLiteCursorDriver;
-import android.database.sqlite.SQLiteDatabase;
-import android.database.sqlite.SQLiteException;
-import android.database.sqlite.SQLiteOpenHelper;
-import android.database.sqlite.SQLiteQuery;
-import android.net.ipmemorystore.NetworkAttributes;
-import android.net.ipmemorystore.Status;
-import android.util.Log;
-
-import java.io.ByteArrayInputStream;
-import java.io.ByteArrayOutputStream;
-import java.net.InetAddress;
-import java.net.UnknownHostException;
-import java.util.ArrayList;
-import java.util.List;
-import java.util.StringJoiner;
-
-/**
- * Encapsulating class for using the SQLite database backing the memory store.
- *
- * This class groups together the contracts and the SQLite helper used to
- * use the database.
- *
- * @hide
- */
-public class IpMemoryStoreDatabase {
-    private static final String TAG = IpMemoryStoreDatabase.class.getSimpleName();
-    // A pair of NetworkAttributes objects is group-close if the confidence that they are
-    // the same is above this cutoff. See NetworkAttributes and SameL3NetworkResponse.
-    private static final float GROUPCLOSE_CONFIDENCE = 0.5f;
-
-    /**
-     * Contract class for the Network Attributes table.
-     */
-    public static class NetworkAttributesContract {
-        public static final String TABLENAME = "NetworkAttributes";
-
-        public static final String COLNAME_L2KEY = "l2Key";
-        public static final String COLTYPE_L2KEY = "TEXT NOT NULL";
-
-        public static final String COLNAME_EXPIRYDATE = "expiryDate";
-        // Milliseconds since the Epoch, in true Java style
-        public static final String COLTYPE_EXPIRYDATE = "BIGINT";
-
-        public static final String COLNAME_ASSIGNEDV4ADDRESS = "assignedV4Address";
-        public static final String COLTYPE_ASSIGNEDV4ADDRESS = "INTEGER";
-
-        public static final String COLNAME_ASSIGNEDV4ADDRESSEXPIRY = "assignedV4AddressExpiry";
-        // The lease expiry timestamp in uint of milliseconds
-        public static final String COLTYPE_ASSIGNEDV4ADDRESSEXPIRY = "BIGINT";
-
-        // Please note that the group hint is only a *hint*, hence its name. The client can offer
-        // this information to nudge the grouping in the decision it thinks is right, but it can't
-        // decide for the memory store what is the same L3 network.
-        public static final String COLNAME_GROUPHINT = "groupHint";
-        public static final String COLTYPE_GROUPHINT = "TEXT";
-
-        public static final String COLNAME_DNSADDRESSES = "dnsAddresses";
-        // Stored in marshalled form as is
-        public static final String COLTYPE_DNSADDRESSES = "BLOB";
-
-        public static final String COLNAME_MTU = "mtu";
-        public static final String COLTYPE_MTU = "INTEGER DEFAULT -1";
-
-        public static final String CREATE_TABLE = "CREATE TABLE IF NOT EXISTS "
-                + TABLENAME                       + " ("
-                + COLNAME_L2KEY                   + " " + COLTYPE_L2KEY + " PRIMARY KEY NOT NULL, "
-                + COLNAME_EXPIRYDATE              + " " + COLTYPE_EXPIRYDATE              + ", "
-                + COLNAME_ASSIGNEDV4ADDRESS       + " " + COLTYPE_ASSIGNEDV4ADDRESS       + ", "
-                + COLNAME_ASSIGNEDV4ADDRESSEXPIRY + " " + COLTYPE_ASSIGNEDV4ADDRESSEXPIRY + ", "
-                + COLNAME_GROUPHINT               + " " + COLTYPE_GROUPHINT               + ", "
-                + COLNAME_DNSADDRESSES            + " " + COLTYPE_DNSADDRESSES            + ", "
-                + COLNAME_MTU                     + " " + COLTYPE_MTU                     + ")";
-        public static final String DROP_TABLE = "DROP TABLE IF EXISTS " + TABLENAME;
-    }
-
-    /**
-     * Contract class for the Private Data table.
-     */
-    public static class PrivateDataContract {
-        public static final String TABLENAME = "PrivateData";
-
-        public static final String COLNAME_L2KEY = "l2Key";
-        public static final String COLTYPE_L2KEY = "TEXT NOT NULL";
-
-        public static final String COLNAME_CLIENT = "client";
-        public static final String COLTYPE_CLIENT = "TEXT NOT NULL";
-
-        public static final String COLNAME_DATANAME = "dataName";
-        public static final String COLTYPE_DATANAME = "TEXT NOT NULL";
-
-        public static final String COLNAME_DATA = "data";
-        public static final String COLTYPE_DATA = "BLOB NOT NULL";
-
-        public static final String CREATE_TABLE = "CREATE TABLE IF NOT EXISTS "
-                + TABLENAME        + " ("
-                + COLNAME_L2KEY    + " " + COLTYPE_L2KEY    + ", "
-                + COLNAME_CLIENT   + " " + COLTYPE_CLIENT   + ", "
-                + COLNAME_DATANAME + " " + COLTYPE_DATANAME + ", "
-                + COLNAME_DATA     + " " + COLTYPE_DATA     + ", "
-                + "PRIMARY KEY ("
-                + COLNAME_L2KEY    + ", "
-                + COLNAME_CLIENT   + ", "
-                + COLNAME_DATANAME + "))";
-        public static final String DROP_TABLE = "DROP TABLE IF EXISTS " + TABLENAME;
-    }
-
-    // To save memory when the DB is not used, close it after 30s of inactivity. This is
-    // determined manually based on what feels right.
-    private static final long IDLE_CONNECTION_TIMEOUT_MS = 30_000;
-
-    /** The SQLite DB helper */
-    public static class DbHelper extends SQLiteOpenHelper {
-        // Update this whenever changing the schema.
-        private static final int SCHEMA_VERSION = 4;
-        private static final String DATABASE_FILENAME = "IpMemoryStore.db";
-        private static final String TRIGGER_NAME = "delete_cascade_to_private";
-
-        public DbHelper(@NonNull final Context context) {
-            super(context, DATABASE_FILENAME, null, SCHEMA_VERSION);
-            setIdleConnectionTimeout(IDLE_CONNECTION_TIMEOUT_MS);
-        }
-
-        /** Called when the database is created */
-        @Override
-        public void onCreate(@NonNull final SQLiteDatabase db) {
-            db.execSQL(NetworkAttributesContract.CREATE_TABLE);
-            db.execSQL(PrivateDataContract.CREATE_TABLE);
-            createTrigger(db);
-        }
-
-        /** Called when the database is upgraded */
-        @Override
-        public void onUpgrade(@NonNull final SQLiteDatabase db, final int oldVersion,
-                final int newVersion) {
-            try {
-                if (oldVersion < 2) {
-                    // upgrade from version 1 to version 2
-                    // since we starts from version 2, do nothing here
-                }
-
-                if (oldVersion < 3) {
-                    // upgrade from version 2 to version 3
-                    final String sqlUpgradeAddressExpiry = "alter table"
-                            + " " + NetworkAttributesContract.TABLENAME + " ADD"
-                            + " " + NetworkAttributesContract.COLNAME_ASSIGNEDV4ADDRESSEXPIRY
-                            + " " + NetworkAttributesContract.COLTYPE_ASSIGNEDV4ADDRESSEXPIRY;
-                    db.execSQL(sqlUpgradeAddressExpiry);
-                }
-
-                if (oldVersion < 4) {
-                    createTrigger(db);
-                }
-            } catch (SQLiteException e) {
-                Log.e(TAG, "Could not upgrade to the new version", e);
-                // create database with new version
-                db.execSQL(NetworkAttributesContract.DROP_TABLE);
-                db.execSQL(PrivateDataContract.DROP_TABLE);
-                onCreate(db);
-            }
-        }
-
-        /** Called when the database is downgraded */
-        @Override
-        public void onDowngrade(@NonNull final SQLiteDatabase db, final int oldVersion,
-                final int newVersion) {
-            // Downgrades always nuke all data and recreate an empty table.
-            db.execSQL(NetworkAttributesContract.DROP_TABLE);
-            db.execSQL(PrivateDataContract.DROP_TABLE);
-            db.execSQL("DROP TRIGGER " + TRIGGER_NAME);
-            onCreate(db);
-        }
-
-        private void createTrigger(@NonNull final SQLiteDatabase db) {
-            final String createTrigger = "CREATE TRIGGER " + TRIGGER_NAME
-                    + " DELETE ON " + NetworkAttributesContract.TABLENAME
-                    + " BEGIN"
-                    + " DELETE FROM " + PrivateDataContract.TABLENAME + " WHERE OLD."
-                    + NetworkAttributesContract.COLNAME_L2KEY
-                    + "=" + PrivateDataContract.COLNAME_L2KEY
-                    + "; END;";
-            db.execSQL(createTrigger);
-        }
-    }
-
-    @NonNull
-    private static byte[] encodeAddressList(@NonNull final List<InetAddress> addresses) {
-        final ByteArrayOutputStream os = new ByteArrayOutputStream();
-        for (final InetAddress address : addresses) {
-            final byte[] b = address.getAddress();
-            os.write(b.length);
-            os.write(b, 0, b.length);
-        }
-        return os.toByteArray();
-    }
-
-    @NonNull
-    private static ArrayList<InetAddress> decodeAddressList(@NonNull final byte[] encoded) {
-        final ByteArrayInputStream is = new ByteArrayInputStream(encoded);
-        final ArrayList<InetAddress> addresses = new ArrayList<>();
-        int d = -1;
-        while ((d = is.read()) != -1) {
-            final byte[] bytes = new byte[d];
-            is.read(bytes, 0, d);
-            try {
-                addresses.add(InetAddress.getByAddress(bytes));
-            } catch (UnknownHostException e) { /* Hopefully impossible */ }
-        }
-        return addresses;
-    }
-
-    @NonNull
-    private static ContentValues toContentValues(@Nullable final NetworkAttributes attributes) {
-        final ContentValues values = new ContentValues();
-        if (null == attributes) return values;
-        if (null != attributes.assignedV4Address) {
-            values.put(NetworkAttributesContract.COLNAME_ASSIGNEDV4ADDRESS,
-                    inet4AddressToIntHTH(attributes.assignedV4Address));
-        }
-        if (null != attributes.assignedV4AddressExpiry) {
-            values.put(NetworkAttributesContract.COLNAME_ASSIGNEDV4ADDRESSEXPIRY,
-                    attributes.assignedV4AddressExpiry);
-        }
-        if (null != attributes.groupHint) {
-            values.put(NetworkAttributesContract.COLNAME_GROUPHINT, attributes.groupHint);
-        }
-        if (null != attributes.dnsAddresses) {
-            values.put(NetworkAttributesContract.COLNAME_DNSADDRESSES,
-                    encodeAddressList(attributes.dnsAddresses));
-        }
-        if (null != attributes.mtu) {
-            values.put(NetworkAttributesContract.COLNAME_MTU, attributes.mtu);
-        }
-        return values;
-    }
-
-    // Convert a NetworkAttributes object to content values to store them in a table compliant
-    // with the contract defined in NetworkAttributesContract.
-    @NonNull
-    private static ContentValues toContentValues(@NonNull final String key,
-            @Nullable final NetworkAttributes attributes, final long expiry) {
-        final ContentValues values = toContentValues(attributes);
-        values.put(NetworkAttributesContract.COLNAME_L2KEY, key);
-        values.put(NetworkAttributesContract.COLNAME_EXPIRYDATE, expiry);
-        return values;
-    }
-
-    // Convert a byte array into content values to store it in a table compliant with the
-    // contract defined in PrivateDataContract.
-    @NonNull
-    private static ContentValues toContentValues(@NonNull final String key,
-            @NonNull final String clientId, @NonNull final String name,
-            @NonNull final byte[] data) {
-        final ContentValues values = new ContentValues();
-        values.put(PrivateDataContract.COLNAME_L2KEY, key);
-        values.put(PrivateDataContract.COLNAME_CLIENT, clientId);
-        values.put(PrivateDataContract.COLNAME_DATANAME, name);
-        values.put(PrivateDataContract.COLNAME_DATA, data);
-        return values;
-    }
-
-    @Nullable
-    private static NetworkAttributes readNetworkAttributesLine(@NonNull final Cursor cursor) {
-        // Make sure the data hasn't expired
-        final long expiry = getLong(cursor, NetworkAttributesContract.COLNAME_EXPIRYDATE, -1L);
-        if (expiry < System.currentTimeMillis()) return null;
-
-        final NetworkAttributes.Builder builder = new NetworkAttributes.Builder();
-        final int assignedV4AddressInt = getInt(cursor,
-                NetworkAttributesContract.COLNAME_ASSIGNEDV4ADDRESS, 0);
-        final long assignedV4AddressExpiry = getLong(cursor,
-                NetworkAttributesContract.COLNAME_ASSIGNEDV4ADDRESSEXPIRY, 0);
-        final String groupHint = getString(cursor, NetworkAttributesContract.COLNAME_GROUPHINT);
-        final byte[] dnsAddressesBlob =
-                getBlob(cursor, NetworkAttributesContract.COLNAME_DNSADDRESSES);
-        final int mtu = getInt(cursor, NetworkAttributesContract.COLNAME_MTU, -1);
-        if (0 != assignedV4AddressInt) {
-            builder.setAssignedV4Address(intToInet4AddressHTH(assignedV4AddressInt));
-        }
-        if (0 != assignedV4AddressExpiry) {
-            builder.setAssignedV4AddressExpiry(assignedV4AddressExpiry);
-        }
-        builder.setGroupHint(groupHint);
-        if (null != dnsAddressesBlob) {
-            builder.setDnsAddresses(decodeAddressList(dnsAddressesBlob));
-        }
-        if (mtu >= 0) {
-            builder.setMtu(mtu);
-        }
-        return builder.build();
-    }
-
-    private static final String[] EXPIRY_COLUMN = new String[] {
-        NetworkAttributesContract.COLNAME_EXPIRYDATE
-    };
-    static final int EXPIRY_ERROR = -1; // Legal values for expiry are positive
-
-    static final String SELECT_L2KEY = NetworkAttributesContract.COLNAME_L2KEY + " = ?";
-
-    // Returns the expiry date of the specified row, or one of the error codes above if the
-    // row is not found or some other error
-    static long getExpiry(@NonNull final SQLiteDatabase db, @NonNull final String key) {
-        final Cursor cursor = db.query(NetworkAttributesContract.TABLENAME,
-                EXPIRY_COLUMN, // columns
-                SELECT_L2KEY, // selection
-                new String[] { key }, // selectionArgs
-                null, // groupBy
-                null, // having
-                null // orderBy
-        );
-        // L2KEY is the primary key ; it should not be possible to get more than one
-        // result here. 0 results means the key was not found.
-        if (cursor.getCount() != 1) return EXPIRY_ERROR;
-        cursor.moveToFirst();
-        final long result = cursor.getLong(0); // index in the EXPIRY_COLUMN array
-        cursor.close();
-        return result;
-    }
-
-    static final int RELEVANCE_ERROR = -1; // Legal values for relevance are positive
-
-    // Returns the relevance of the specified row, or one of the error codes above if the
-    // row is not found or some other error
-    static int getRelevance(@NonNull final SQLiteDatabase db, @NonNull final String key) {
-        final long expiry = getExpiry(db, key);
-        return expiry < 0 ? (int) expiry : RelevanceUtils.computeRelevanceForNow(expiry);
-    }
-
-    // If the attributes are null, this will only write the expiry.
-    // Returns an int out of Status.{SUCCESS, ERROR_*}
-    static int storeNetworkAttributes(@NonNull final SQLiteDatabase db, @NonNull final String key,
-            final long expiry, @Nullable final NetworkAttributes attributes) {
-        final ContentValues cv = toContentValues(key, attributes, expiry);
-        db.beginTransaction();
-        try {
-            // Unfortunately SQLite does not have any way to do INSERT OR UPDATE. Options are
-            // to either insert with on conflict ignore then update (like done here), or to
-            // construct a custom SQL INSERT statement with nested select.
-            final long resultId = db.insertWithOnConflict(NetworkAttributesContract.TABLENAME,
-                    null, cv, SQLiteDatabase.CONFLICT_IGNORE);
-            if (resultId < 0) {
-                db.update(NetworkAttributesContract.TABLENAME, cv, SELECT_L2KEY, new String[]{key});
-            }
-            db.setTransactionSuccessful();
-            return Status.SUCCESS;
-        } catch (SQLiteException e) {
-            // No space left on disk or something
-            Log.e(TAG, "Could not write to the memory store", e);
-        } finally {
-            db.endTransaction();
-        }
-        return Status.ERROR_STORAGE;
-    }
-
-    // Returns an int out of Status.{SUCCESS, ERROR_*}
-    static int storeBlob(@NonNull final SQLiteDatabase db, @NonNull final String key,
-            @NonNull final String clientId, @NonNull final String name,
-            @NonNull final byte[] data) {
-        final long res = db.insertWithOnConflict(PrivateDataContract.TABLENAME, null,
-                toContentValues(key, clientId, name, data), SQLiteDatabase.CONFLICT_REPLACE);
-        return (res == -1) ? Status.ERROR_STORAGE : Status.SUCCESS;
-    }
-
-    @Nullable
-    static NetworkAttributes retrieveNetworkAttributes(@NonNull final SQLiteDatabase db,
-            @NonNull final String key) {
-        final Cursor cursor = db.query(NetworkAttributesContract.TABLENAME,
-                null, // columns, null means everything
-                NetworkAttributesContract.COLNAME_L2KEY + " = ?", // selection
-                new String[] { key }, // selectionArgs
-                null, // groupBy
-                null, // having
-                null); // orderBy
-        // L2KEY is the primary key ; it should not be possible to get more than one
-        // result here. 0 results means the key was not found.
-        if (cursor.getCount() != 1) return null;
-        cursor.moveToFirst();
-        final NetworkAttributes attributes = readNetworkAttributesLine(cursor);
-        cursor.close();
-        return attributes;
-    }
-
-    private static final String[] DATA_COLUMN = new String[] {
-            PrivateDataContract.COLNAME_DATA
-    };
-
-    @Nullable
-    static byte[] retrieveBlob(@NonNull final SQLiteDatabase db, @NonNull final String key,
-            @NonNull final String clientId, @NonNull final String name) {
-        final Cursor cursor = db.query(PrivateDataContract.TABLENAME,
-                DATA_COLUMN, // columns
-                PrivateDataContract.COLNAME_L2KEY + " = ? AND " // selection
-                + PrivateDataContract.COLNAME_CLIENT + " = ? AND "
-                + PrivateDataContract.COLNAME_DATANAME + " = ?",
-                new String[] { key, clientId, name }, // selectionArgs
-                null, // groupBy
-                null, // having
-                null); // orderBy
-        // The query above is querying by (composite) primary key, so it should not be possible to
-        // get more than one result here. 0 results means the key was not found.
-        if (cursor.getCount() != 1) return null;
-        cursor.moveToFirst();
-        final byte[] result = cursor.getBlob(0); // index in the DATA_COLUMN array
-        cursor.close();
-        return result;
-    }
-
-    /**
-     * Wipe all data in tables when network factory reset occurs.
-     */
-    static void wipeDataUponNetworkReset(@NonNull final SQLiteDatabase db) {
-        for (int remainingRetries = 3; remainingRetries > 0; --remainingRetries) {
-            db.beginTransaction();
-            try {
-                db.delete(NetworkAttributesContract.TABLENAME, null, null);
-                db.delete(PrivateDataContract.TABLENAME, null, null);
-                final Cursor cursorNetworkAttributes = db.query(
-                        // table name
-                        NetworkAttributesContract.TABLENAME,
-                        // column name
-                        new String[] { NetworkAttributesContract.COLNAME_L2KEY },
-                        null, // selection
-                        null, // selectionArgs
-                        null, // groupBy
-                        null, // having
-                        null, // orderBy
-                        "1"); // limit
-                if (0 != cursorNetworkAttributes.getCount()) {
-                    cursorNetworkAttributes.close();
-                    continue;
-                }
-                cursorNetworkAttributes.close();
-                final Cursor cursorPrivateData = db.query(
-                        // table name
-                        PrivateDataContract.TABLENAME,
-                        // column name
-                        new String[] { PrivateDataContract.COLNAME_L2KEY },
-                        null, // selection
-                        null, // selectionArgs
-                        null, // groupBy
-                        null, // having
-                        null, // orderBy
-                        "1"); // limit
-                if (0 != cursorPrivateData.getCount()) {
-                    cursorPrivateData.close();
-                    continue;
-                }
-                cursorPrivateData.close();
-                db.setTransactionSuccessful();
-                return;
-            } catch (SQLiteException e) {
-                Log.e(TAG, "Could not wipe the data in database", e);
-            } finally {
-                db.endTransaction();
-            }
-        }
-    }
-
-    /**
-     * The following is a horrible hack that is necessary because the Android SQLite API does not
-     * have a way to query a binary blob. This, almost certainly, is an overlook.
-     *
-     * The Android SQLite API has two family of methods : one for query that returns data, and
-     * one for more general SQL statements that can execute any statement but may not return
-     * anything. All the query methods, however, take only String[] for the arguments.
-     *
-     * In principle it is simple to write a function that will encode the binary blob in the
-     * way SQLite expects it. However, because the API forces the argument to be coerced into a
-     * String, the SQLiteQuery object generated by the default query methods will bind all
-     * arguments as Strings and SQL will *sanitize* them. This works okay for numeric types,
-     * but the format for blobs is x'<hex string>'. Note the presence of quotes, which will
-     * be sanitized, changing the contents of the field, and the query will fail to match the
-     * blob.
-     *
-     * As far as I can tell, there are two possible ways around this problem. The first one
-     * is to put the data in the query string and eschew it being an argument. This would
-     * require doing the sanitizing by hand. The other is to call bindBlob directly on the
-     * generated SQLiteQuery object, which not only is a lot less dangerous than rolling out
-     * sanitizing, but also will do the right thing if the underlying format ever changes.
-     *
-     * But none of the methods that take an SQLiteQuery object can return data ; this *must*
-     * be called with SQLiteDatabase#query. This object is not accessible from outside.
-     * However, there is a #query version that accepts a CursorFactory and this is pretty
-     * straightforward to implement as all the arguments are coming in and the SQLiteCursor
-     * class is public API.
-     * With this, it's possible to intercept the SQLiteQuery object, and assuming the args
-     * are available, to bind them directly and work around the API's oblivious coercion into
-     * Strings.
-     *
-     * This is really sad, but I don't see another way of having this work than this or the
-     * hand-rolled sanitizing, and this is the lesser evil.
-     */
-    private static class CustomCursorFactory implements SQLiteDatabase.CursorFactory {
-        @NonNull
-        private final ArrayList<Object> mArgs;
-        CustomCursorFactory(@NonNull final ArrayList<Object> args) {
-            mArgs = args;
-        }
-        @Override
-        public Cursor newCursor(final SQLiteDatabase db, final SQLiteCursorDriver masterQuery,
-                final String editTable,
-                final SQLiteQuery query) {
-            int index = 1; // bind is 1-indexed
-            for (final Object arg : mArgs) {
-                if (arg instanceof String) {
-                    query.bindString(index++, (String) arg);
-                } else if (arg instanceof Long) {
-                    query.bindLong(index++, (Long) arg);
-                } else if (arg instanceof Integer) {
-                    query.bindLong(index++, Long.valueOf((Integer) arg));
-                } else if (arg instanceof byte[]) {
-                    query.bindBlob(index++, (byte[]) arg);
-                } else {
-                    throw new IllegalStateException("Unsupported type CustomCursorFactory "
-                            + arg.getClass().toString());
-                }
-            }
-            return new SQLiteCursor(masterQuery, editTable, query);
-        }
-    }
-
-    // Returns the l2key of the closest match, if and only if it matches
-    // closely enough (as determined by group-closeness).
-    @Nullable
-    static String findClosestAttributes(@NonNull final SQLiteDatabase db,
-            @NonNull final NetworkAttributes attr) {
-        if (attr.isEmpty()) return null;
-        final ContentValues values = toContentValues(attr);
-
-        // Build the selection and args. To cut down on the number of lines to search, limit
-        // the search to those with at least one argument equals to the requested attributes.
-        // This works only because null attributes match only will not result in group-closeness.
-        final StringJoiner sj = new StringJoiner(" OR ");
-        final ArrayList<Object> args = new ArrayList<>();
-        args.add(System.currentTimeMillis());
-        for (final String field : values.keySet()) {
-            sj.add(field + " = ?");
-            args.add(values.get(field));
-        }
-
-        final String selection = NetworkAttributesContract.COLNAME_EXPIRYDATE + " > ? AND ("
-                + sj.toString() + ")";
-        final Cursor cursor = db.queryWithFactory(new CustomCursorFactory(args),
-                false, // distinct
-                NetworkAttributesContract.TABLENAME,
-                null, // columns, null means everything
-                selection, // selection
-                null, // selectionArgs, horrendously passed to the cursor factory instead
-                null, // groupBy
-                null, // having
-                null, // orderBy
-                null); // limit
-        if (cursor.getCount() <= 0) return null;
-        cursor.moveToFirst();
-        String bestKey = null;
-        float bestMatchConfidence = GROUPCLOSE_CONFIDENCE; // Never return a match worse than this.
-        while (!cursor.isAfterLast()) {
-            final NetworkAttributes read = readNetworkAttributesLine(cursor);
-            final float confidence = read.getNetworkGroupSamenessConfidence(attr);
-            if (confidence > bestMatchConfidence) {
-                bestKey = getString(cursor, NetworkAttributesContract.COLNAME_L2KEY);
-                bestMatchConfidence = confidence;
-            }
-            cursor.moveToNext();
-        }
-        cursor.close();
-        return bestKey;
-    }
-
-    // Drops all records that are expired. Relevance has decayed to zero of these records. Returns
-    // an int out of Status.{SUCCESS, ERROR_*}
-    static int dropAllExpiredRecords(@NonNull final SQLiteDatabase db) {
-        db.beginTransaction();
-        try {
-            // Deletes NetworkAttributes that have expired.
-            db.delete(NetworkAttributesContract.TABLENAME,
-                    NetworkAttributesContract.COLNAME_EXPIRYDATE + " < ?",
-                    new String[]{Long.toString(System.currentTimeMillis())});
-            db.setTransactionSuccessful();
-        } catch (SQLiteException e) {
-            Log.e(TAG, "Could not delete data from memory store", e);
-            return Status.ERROR_STORAGE;
-        } finally {
-            db.endTransaction();
-        }
-
-        // Execute vacuuming here if above operation has no exception. If above operation got
-        // exception, vacuuming can be ignored for reducing unnecessary consumption.
-        try {
-            db.execSQL("VACUUM");
-        } catch (SQLiteException e) {
-            // Do nothing.
-        }
-        return Status.SUCCESS;
-    }
-
-    // Drops number of records that start from the lowest expiryDate. Returns an int out of
-    // Status.{SUCCESS, ERROR_*}
-    static int dropNumberOfRecords(@NonNull final SQLiteDatabase db, int number) {
-        if (number <= 0) {
-            return Status.ERROR_ILLEGAL_ARGUMENT;
-        }
-
-        // Queries number of NetworkAttributes that start from the lowest expiryDate.
-        final Cursor cursor = db.query(NetworkAttributesContract.TABLENAME,
-                new String[] {NetworkAttributesContract.COLNAME_EXPIRYDATE}, // columns
-                null, // selection
-                null, // selectionArgs
-                null, // groupBy
-                null, // having
-                NetworkAttributesContract.COLNAME_EXPIRYDATE, // orderBy
-                Integer.toString(number)); // limit
-        if (cursor == null || cursor.getCount() <= 0) return Status.ERROR_GENERIC;
-        cursor.moveToLast();
-
-        //Get the expiryDate from last record.
-        final long expiryDate = getLong(cursor, NetworkAttributesContract.COLNAME_EXPIRYDATE, 0);
-        cursor.close();
-
-        db.beginTransaction();
-        try {
-            // Deletes NetworkAttributes that expiryDate are lower than given value.
-            db.delete(NetworkAttributesContract.TABLENAME,
-                    NetworkAttributesContract.COLNAME_EXPIRYDATE + " <= ?",
-                    new String[]{Long.toString(expiryDate)});
-            db.setTransactionSuccessful();
-        } catch (SQLiteException e) {
-            Log.e(TAG, "Could not delete data from memory store", e);
-            return Status.ERROR_STORAGE;
-        } finally {
-            db.endTransaction();
-        }
-
-        // Execute vacuuming here if above operation has no exception. If above operation got
-        // exception, vacuuming can be ignored for reducing unnecessary consumption.
-        try {
-            db.execSQL("VACUUM");
-        } catch (SQLiteException e) {
-            // Do nothing.
-        }
-        return Status.SUCCESS;
-    }
-
-    static int getTotalRecordNumber(@NonNull final SQLiteDatabase db) {
-        // Query the total number of NetworkAttributes
-        final Cursor cursor = db.query(NetworkAttributesContract.TABLENAME,
-                new String[] {"COUNT(*)"}, // columns
-                null, // selection
-                null, // selectionArgs
-                null, // groupBy
-                null, // having
-                null); // orderBy
-        cursor.moveToFirst();
-        return cursor == null ? 0 : cursor.getInt(0);
-    }
-
-    // Helper methods
-    private static String getString(final Cursor cursor, final String columnName) {
-        final int columnIndex = cursor.getColumnIndex(columnName);
-        return (columnIndex >= 0) ? cursor.getString(columnIndex) : null;
-    }
-    private static byte[] getBlob(final Cursor cursor, final String columnName) {
-        final int columnIndex = cursor.getColumnIndex(columnName);
-        return (columnIndex >= 0) ? cursor.getBlob(columnIndex) : null;
-    }
-    private static int getInt(final Cursor cursor, final String columnName,
-            final int defaultValue) {
-        final int columnIndex = cursor.getColumnIndex(columnName);
-        return (columnIndex >= 0) ? cursor.getInt(columnIndex) : defaultValue;
-    }
-    private static long getLong(final Cursor cursor, final String columnName,
-            final long defaultValue) {
-        final int columnIndex = cursor.getColumnIndex(columnName);
-        return (columnIndex >= 0) ? cursor.getLong(columnIndex) : defaultValue;
-    }
-}
diff --git a/packages/NetworkStack/src/com/android/server/connectivity/ipmemorystore/IpMemoryStoreService.java b/packages/NetworkStack/src/com/android/server/connectivity/ipmemorystore/IpMemoryStoreService.java
deleted file mode 100644
index 55ab8d4..0000000
--- a/packages/NetworkStack/src/com/android/server/connectivity/ipmemorystore/IpMemoryStoreService.java
+++ /dev/null
@@ -1,503 +0,0 @@
-/*
- * Copyright (C) 2018 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.server.connectivity.ipmemorystore;
-
-import static android.net.ipmemorystore.Status.ERROR_DATABASE_CANNOT_BE_OPENED;
-import static android.net.ipmemorystore.Status.ERROR_GENERIC;
-import static android.net.ipmemorystore.Status.ERROR_ILLEGAL_ARGUMENT;
-import static android.net.ipmemorystore.Status.SUCCESS;
-
-import static com.android.server.connectivity.ipmemorystore.IpMemoryStoreDatabase.EXPIRY_ERROR;
-import static com.android.server.connectivity.ipmemorystore.RegularMaintenanceJobService.InterruptMaintenance;
-
-import android.annotation.NonNull;
-import android.annotation.Nullable;
-import android.content.Context;
-import android.database.SQLException;
-import android.database.sqlite.SQLiteDatabase;
-import android.net.IIpMemoryStore;
-import android.net.ipmemorystore.Blob;
-import android.net.ipmemorystore.IOnBlobRetrievedListener;
-import android.net.ipmemorystore.IOnL2KeyResponseListener;
-import android.net.ipmemorystore.IOnNetworkAttributesRetrievedListener;
-import android.net.ipmemorystore.IOnSameL3NetworkResponseListener;
-import android.net.ipmemorystore.IOnStatusListener;
-import android.net.ipmemorystore.NetworkAttributes;
-import android.net.ipmemorystore.NetworkAttributesParcelable;
-import android.net.ipmemorystore.SameL3NetworkResponse;
-import android.net.ipmemorystore.Status;
-import android.net.ipmemorystore.StatusParcelable;
-import android.os.RemoteException;
-import android.util.Log;
-
-import com.android.internal.annotations.VisibleForTesting;
-
-import java.io.File;
-import java.util.concurrent.ExecutorService;
-import java.util.concurrent.Executors;
-
-/**
- * Implementation for the IP memory store.
- * This component offers specialized services for network components to store and retrieve
- * knowledge about networks, and provides intelligence that groups level 2 networks together
- * into level 3 networks.
- *
- * @hide
- */
-public class IpMemoryStoreService extends IIpMemoryStore.Stub {
-    private static final String TAG = IpMemoryStoreService.class.getSimpleName();
-    private static final int DATABASE_SIZE_THRESHOLD = 10 * 1024 * 1024; //10MB
-    private static final int MAX_DROP_RECORD_TIMES = 500;
-    private static final int MIN_DELETE_NUM = 5;
-    private static final boolean DBG = true;
-
-    // Error codes below are internal and used for notifying status beteween IpMemoryStore modules.
-    static final int ERROR_INTERNAL_BASE = -1_000_000_000;
-    // This error code is used for maintenance only to notify RegularMaintenanceJobService that
-    // full maintenance job has been interrupted.
-    static final int ERROR_INTERNAL_INTERRUPTED = ERROR_INTERNAL_BASE - 1;
-
-    @NonNull
-    final Context mContext;
-    @Nullable
-    final SQLiteDatabase mDb;
-    @NonNull
-    final ExecutorService mExecutor;
-
-    /**
-     * Construct an IpMemoryStoreService object.
-     * This constructor will block on disk access to open the database.
-     * @param context the context to access storage with.
-     */
-    public IpMemoryStoreService(@NonNull final Context context) {
-        // Note that constructing the service will access the disk and block
-        // for some time, but it should make no difference to the clients. Because
-        // the interface is one-way, clients fire and forget requests, and the callback
-        // will get called eventually in any case, and the framework will wait for the
-        // service to be created to deliver subsequent requests.
-        // Avoiding this would mean the mDb member can't be final, which means the service would
-        // have to test for nullity, care for failure, and allow for a wait at every single access,
-        // which would make the code a lot more complex and require all methods to possibly block.
-        mContext = context;
-        SQLiteDatabase db;
-        final IpMemoryStoreDatabase.DbHelper helper = new IpMemoryStoreDatabase.DbHelper(context);
-        try {
-            db = helper.getWritableDatabase();
-            if (null == db) Log.e(TAG, "Unexpected null return of getWriteableDatabase");
-        } catch (final SQLException e) {
-            Log.e(TAG, "Can't open the Ip Memory Store database", e);
-            db = null;
-        } catch (final Exception e) {
-            Log.wtf(TAG, "Impossible exception Ip Memory Store database", e);
-            db = null;
-        }
-        mDb = db;
-        // The single thread executor guarantees that all work is executed sequentially on the
-        // same thread, and no two tasks can be active at the same time. This is required to
-        // ensure operations from multiple clients don't interfere with each other (in particular,
-        // operations involving a transaction must not run concurrently with other operations
-        // as the other operations might be taken as part of the transaction). By default, the
-        // single thread executor runs off an unbounded queue.
-        // TODO : investigate replacing this scheme with a scheme where each thread has its own
-        // instance of the database, as it may be faster. It is likely however that IpMemoryStore
-        // operations are mostly IO-bound anyway, and additional contention is unlikely to bring
-        // benefits. Alternatively, a read-write lock might increase throughput.
-        mExecutor = Executors.newSingleThreadExecutor();
-        RegularMaintenanceJobService.schedule(mContext, this);
-    }
-
-    /**
-     * Shutdown the memory store service, cancelling running tasks and dropping queued tasks.
-     *
-     * This is provided to give a way to clean up, and is meant to be available in case of an
-     * emergency shutdown.
-     */
-    public void shutdown() {
-        // By contrast with ExecutorService#shutdown, ExecutorService#shutdownNow tries
-        // to cancel the existing tasks, and does not wait for completion. It does not
-        // guarantee the threads can be terminated in any given amount of time.
-        mExecutor.shutdownNow();
-        if (mDb != null) mDb.close();
-        RegularMaintenanceJobService.unschedule(mContext);
-    }
-
-    /** Helper function to make a status object */
-    private StatusParcelable makeStatus(final int code) {
-        return new Status(code).toParcelable();
-    }
-
-    /**
-     * Store network attributes for a given L2 key.
-     *
-     * @param l2Key The L2 key for the L2 network. Clients that don't know or care about the L2
-     *              key and only care about grouping can pass a unique ID here like the ones
-     *              generated by {@code java.util.UUID.randomUUID()}, but keep in mind the low
-     *              relevance of such a network will lead to it being evicted soon if it's not
-     *              refreshed. Use findL2Key to try and find a similar L2Key to these attributes.
-     * @param attributes The attributes for this network.
-     * @param listener A listener to inform of the completion of this call, or null if the client
-     *        is not interested in learning about success/failure.
-     * Through the listener, returns the L2 key. This is useful if the L2 key was not specified.
-     * If the call failed, the L2 key will be null.
-     */
-    // Note that while l2Key and attributes are non-null in spirit, they are received from
-    // another process. If the remote process decides to ignore everything and send null, this
-    // process should still not crash.
-    @Override
-    public void storeNetworkAttributes(@Nullable final String l2Key,
-            @Nullable final NetworkAttributesParcelable attributes,
-            @Nullable final IOnStatusListener listener) {
-        // Because the parcelable is 100% mutable, the thread may not see its members initialized.
-        // Therefore either an immutable object is created on this same thread before it's passed
-        // to the executor, or there need to be a write barrier here and a read barrier in the
-        // remote thread.
-        final NetworkAttributes na = null == attributes ? null : new NetworkAttributes(attributes);
-        mExecutor.execute(() -> {
-            try {
-                final int code = storeNetworkAttributesAndBlobSync(l2Key, na,
-                        null /* clientId */, null /* name */, null /* data */);
-                if (null != listener) listener.onComplete(makeStatus(code));
-            } catch (final RemoteException e) {
-                // Client at the other end died
-            }
-        });
-    }
-
-    /**
-     * Store a binary blob associated with an L2 key and a name.
-     *
-     * @param l2Key The L2 key for this network.
-     * @param clientId The ID of the client.
-     * @param name The name of this data.
-     * @param blob The data to store.
-     * @param listener The listener that will be invoked to return the answer, or null if the
-     *        is not interested in learning about success/failure.
-     * Through the listener, returns a status to indicate success or failure.
-     */
-    @Override
-    public void storeBlob(@Nullable final String l2Key, @Nullable final String clientId,
-            @Nullable final String name, @Nullable final Blob blob,
-            @Nullable final IOnStatusListener listener) {
-        final byte[] data = null == blob ? null : blob.data;
-        mExecutor.execute(() -> {
-            try {
-                final int code = storeNetworkAttributesAndBlobSync(l2Key,
-                        null /* NetworkAttributes */, clientId, name, data);
-                if (null != listener) listener.onComplete(makeStatus(code));
-            } catch (final RemoteException e) {
-                // Client at the other end died
-            }
-        });
-    }
-
-    /**
-     * Helper method for storeNetworkAttributes and storeBlob.
-     *
-     * Either attributes or none of clientId, name and data may be null. This will write the
-     * passed data if non-null, and will write attributes if non-null, but in any case it will
-     * bump the relevance up.
-     * Returns a success code from Status.
-     */
-    private int storeNetworkAttributesAndBlobSync(@Nullable final String l2Key,
-            @Nullable final NetworkAttributes attributes,
-            @Nullable final String clientId,
-            @Nullable final String name, @Nullable final byte[] data) {
-        if (null == l2Key) return ERROR_ILLEGAL_ARGUMENT;
-        if (null == attributes && null == data) return ERROR_ILLEGAL_ARGUMENT;
-        if (null != data && (null == clientId || null == name)) return ERROR_ILLEGAL_ARGUMENT;
-        if (null == mDb) return ERROR_DATABASE_CANNOT_BE_OPENED;
-        try {
-            final long oldExpiry = IpMemoryStoreDatabase.getExpiry(mDb, l2Key);
-            final long newExpiry = RelevanceUtils.bumpExpiryDate(
-                    oldExpiry == EXPIRY_ERROR ? System.currentTimeMillis() : oldExpiry);
-            final int errorCode =
-                    IpMemoryStoreDatabase.storeNetworkAttributes(mDb, l2Key, newExpiry, attributes);
-            // If no blob to store, the client is interested in the result of storing the attributes
-            if (null == data) return errorCode;
-            // Otherwise it's interested in the result of storing the blob
-            return IpMemoryStoreDatabase.storeBlob(mDb, l2Key, clientId, name, data);
-        } catch (Exception e) {
-            if (DBG) {
-                Log.e(TAG, "Exception while storing for key {" + l2Key
-                        + "} ; NetworkAttributes {" + (null == attributes ? "null" : attributes)
-                        + "} ; clientId {" + (null == clientId ? "null" : clientId)
-                        + "} ; name {" + (null == name ? "null" : name)
-                        + "} ; data {" + Utils.byteArrayToString(data) + "}", e);
-            }
-        }
-        return ERROR_GENERIC;
-    }
-
-    /**
-     * Returns the best L2 key associated with the attributes.
-     *
-     * This will find a record that would be in the same group as the passed attributes. This is
-     * useful to choose the key for storing a sample or private data when the L2 key is not known.
-     * If multiple records are group-close to these attributes, the closest match is returned.
-     * If multiple records have the same closeness, the one with the smaller (unicode codepoint
-     * order) L2 key is returned.
-     * If no record matches these attributes, null is returned.
-     *
-     * @param attributes The attributes of the network to find.
-     * @param listener The listener that will be invoked to return the answer.
-     * Through the listener, returns the L2 key if one matched, or null.
-     */
-    @Override
-    public void findL2Key(@Nullable final NetworkAttributesParcelable attributes,
-            @Nullable final IOnL2KeyResponseListener listener) {
-        if (null == listener) return;
-        mExecutor.execute(() -> {
-            try {
-                if (null == attributes) {
-                    listener.onL2KeyResponse(makeStatus(ERROR_ILLEGAL_ARGUMENT), null);
-                    return;
-                }
-                if (null == mDb) {
-                    listener.onL2KeyResponse(makeStatus(ERROR_ILLEGAL_ARGUMENT), null);
-                    return;
-                }
-                final String key = IpMemoryStoreDatabase.findClosestAttributes(mDb,
-                        new NetworkAttributes(attributes));
-                listener.onL2KeyResponse(makeStatus(SUCCESS), key);
-            } catch (final RemoteException e) {
-                // Client at the other end died
-            }
-        });
-    }
-
-    /**
-     * Returns whether, to the best of the store's ability to tell, the two specified L2 keys point
-     * to the same L3 network. Group-closeness is used to determine this.
-     *
-     * @param l2Key1 The key for the first network.
-     * @param l2Key2 The key for the second network.
-     * @param listener The listener that will be invoked to return the answer.
-     * Through the listener, a SameL3NetworkResponse containing the answer and confidence.
-     */
-    @Override
-    public void isSameNetwork(@Nullable final String l2Key1, @Nullable final String l2Key2,
-            @Nullable final IOnSameL3NetworkResponseListener listener) {
-        if (null == listener) return;
-        mExecutor.execute(() -> {
-            try {
-                if (null == l2Key1 || null == l2Key2) {
-                    listener.onSameL3NetworkResponse(makeStatus(ERROR_ILLEGAL_ARGUMENT), null);
-                    return;
-                }
-                if (null == mDb) {
-                    listener.onSameL3NetworkResponse(makeStatus(ERROR_ILLEGAL_ARGUMENT), null);
-                    return;
-                }
-                try {
-                    final NetworkAttributes attr1 =
-                            IpMemoryStoreDatabase.retrieveNetworkAttributes(mDb, l2Key1);
-                    final NetworkAttributes attr2 =
-                            IpMemoryStoreDatabase.retrieveNetworkAttributes(mDb, l2Key2);
-                    if (null == attr1 || null == attr2) {
-                        listener.onSameL3NetworkResponse(makeStatus(SUCCESS),
-                                new SameL3NetworkResponse(l2Key1, l2Key2,
-                                        -1f /* never connected */).toParcelable());
-                        return;
-                    }
-                    final float confidence = attr1.getNetworkGroupSamenessConfidence(attr2);
-                    listener.onSameL3NetworkResponse(makeStatus(SUCCESS),
-                            new SameL3NetworkResponse(l2Key1, l2Key2, confidence).toParcelable());
-                } catch (Exception e) {
-                    listener.onSameL3NetworkResponse(makeStatus(ERROR_GENERIC), null);
-                }
-            } catch (final RemoteException e) {
-                // Client at the other end died
-            }
-        });
-    }
-
-    /**
-     * Retrieve the network attributes for a key.
-     * If no record is present for this key, this will return null attributes.
-     *
-     * @param l2Key The key of the network to query.
-     * @param listener The listener that will be invoked to return the answer.
-     * Through the listener, returns the network attributes and the L2 key associated with
-     *         the query.
-     */
-    @Override
-    public void retrieveNetworkAttributes(@Nullable final String l2Key,
-            @Nullable final IOnNetworkAttributesRetrievedListener listener) {
-        if (null == listener) return;
-        mExecutor.execute(() -> {
-            try {
-                if (null == l2Key) {
-                    listener.onNetworkAttributesRetrieved(
-                            makeStatus(ERROR_ILLEGAL_ARGUMENT), l2Key, null);
-                    return;
-                }
-                if (null == mDb) {
-                    listener.onNetworkAttributesRetrieved(
-                            makeStatus(ERROR_DATABASE_CANNOT_BE_OPENED), l2Key, null);
-                    return;
-                }
-                try {
-                    final NetworkAttributes attributes =
-                            IpMemoryStoreDatabase.retrieveNetworkAttributes(mDb, l2Key);
-                    listener.onNetworkAttributesRetrieved(makeStatus(SUCCESS), l2Key,
-                            null == attributes ? null : attributes.toParcelable());
-                } catch (final Exception e) {
-                    listener.onNetworkAttributesRetrieved(makeStatus(ERROR_GENERIC), l2Key, null);
-                }
-            } catch (final RemoteException e) {
-                // Client at the other end died
-            }
-        });
-    }
-
-    /**
-     * Retrieve previously stored private data.
-     * If no data was stored for this L2 key and name this will return null.
-     *
-     * @param l2Key The L2 key.
-     * @param clientId The id of the client that stored this data.
-     * @param name The name of the data.
-     * @param listener The listener that will be invoked to return the answer.
-     * Through the listener, returns the private data if any or null if none, with the L2 key
-     *         and the name of the data associated with the query.
-     */
-    @Override
-    public void retrieveBlob(@NonNull final String l2Key, @NonNull final String clientId,
-            @NonNull final String name, @NonNull final IOnBlobRetrievedListener listener) {
-        if (null == listener) return;
-        mExecutor.execute(() -> {
-            try {
-                if (null == l2Key) {
-                    listener.onBlobRetrieved(makeStatus(ERROR_ILLEGAL_ARGUMENT), l2Key, name, null);
-                    return;
-                }
-                if (null == mDb) {
-                    listener.onBlobRetrieved(makeStatus(ERROR_DATABASE_CANNOT_BE_OPENED), l2Key,
-                            name, null);
-                    return;
-                }
-                try {
-                    final Blob b = new Blob();
-                    b.data = IpMemoryStoreDatabase.retrieveBlob(mDb, l2Key, clientId, name);
-                    listener.onBlobRetrieved(makeStatus(SUCCESS), l2Key, name, b);
-                } catch (final Exception e) {
-                    listener.onBlobRetrieved(makeStatus(ERROR_GENERIC), l2Key, name, null);
-                }
-            } catch (final RemoteException e) {
-                // Client at the other end died
-            }
-        });
-    }
-
-    /**
-     * Wipe the data in IpMemoryStore database upon network factory reset.
-     */
-    @Override
-    public void factoryReset() {
-        mExecutor.execute(() -> IpMemoryStoreDatabase.wipeDataUponNetworkReset(mDb));
-    }
-
-    /** Get db size threshold. */
-    @VisibleForTesting
-    protected int getDbSizeThreshold() {
-        return DATABASE_SIZE_THRESHOLD;
-    }
-
-    private long getDbSize() {
-        final File dbFile = new File(mDb.getPath());
-        try {
-            return dbFile.length();
-        } catch (final SecurityException e) {
-            if (DBG) Log.e(TAG, "Read db size access deny.", e);
-            // Return zero value if can't get disk usage exactly.
-            return 0;
-        }
-    }
-
-    /** Check if db size is over the threshold. */
-    @VisibleForTesting
-    boolean isDbSizeOverThreshold() {
-        return getDbSize() > getDbSizeThreshold();
-    }
-
-    /**
-     * Full maintenance.
-     *
-     * @param listener A listener to inform of the completion of this call.
-     */
-    void fullMaintenance(@NonNull final IOnStatusListener listener,
-            @NonNull final InterruptMaintenance interrupt) {
-        mExecutor.execute(() -> {
-            try {
-                if (null == mDb) {
-                    listener.onComplete(makeStatus(ERROR_DATABASE_CANNOT_BE_OPENED));
-                    return;
-                }
-
-                // Interrupt maintenance because the scheduling job has been canceled.
-                if (checkForInterrupt(listener, interrupt)) return;
-
-                int result = SUCCESS;
-                // Drop all records whose relevance has decayed to zero.
-                // This is the first step to decrease memory store size.
-                result = IpMemoryStoreDatabase.dropAllExpiredRecords(mDb);
-
-                if (checkForInterrupt(listener, interrupt)) return;
-
-                // Aggregate historical data in passes
-                // TODO : Waiting for historical data implement.
-
-                // Check if db size meets the storage goal(10MB). If not, keep dropping records and
-                // aggregate historical data until the storage goal is met. Use for loop with 500
-                // times restriction to prevent infinite loop (Deleting records always fail and db
-                // size is still over the threshold)
-                for (int i = 0; isDbSizeOverThreshold() && i < MAX_DROP_RECORD_TIMES; i++) {
-                    if (checkForInterrupt(listener, interrupt)) return;
-
-                    final int totalNumber = IpMemoryStoreDatabase.getTotalRecordNumber(mDb);
-                    final long dbSize = getDbSize();
-                    final float decreaseRate = (dbSize == 0)
-                            ? 0 : (float) (dbSize - getDbSizeThreshold()) / (float) dbSize;
-                    final int deleteNumber = Math.max(
-                            (int) (totalNumber * decreaseRate), MIN_DELETE_NUM);
-
-                    result = IpMemoryStoreDatabase.dropNumberOfRecords(mDb, deleteNumber);
-
-                    if (checkForInterrupt(listener, interrupt)) return;
-
-                    // Aggregate historical data
-                    // TODO : Waiting for historical data implement.
-                }
-                listener.onComplete(makeStatus(result));
-            } catch (final RemoteException e) {
-                // Client at the other end died
-            }
-        });
-    }
-
-    private boolean checkForInterrupt(@NonNull final IOnStatusListener listener,
-            @NonNull final InterruptMaintenance interrupt) throws RemoteException {
-        if (!interrupt.isInterrupted()) return false;
-        listener.onComplete(makeStatus(ERROR_INTERNAL_INTERRUPTED));
-        return true;
-    }
-
-    @Override
-    public int getInterfaceVersion() {
-        return this.VERSION;
-    }
-}
diff --git a/packages/NetworkStack/src/com/android/server/connectivity/ipmemorystore/RegularMaintenanceJobService.java b/packages/NetworkStack/src/com/android/server/connectivity/ipmemorystore/RegularMaintenanceJobService.java
deleted file mode 100644
index bea7052..0000000
--- a/packages/NetworkStack/src/com/android/server/connectivity/ipmemorystore/RegularMaintenanceJobService.java
+++ /dev/null
@@ -1,145 +0,0 @@
-/*
- * Copyright (C) 2019 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.server.connectivity.ipmemorystore;
-
-import android.app.job.JobInfo;
-import android.app.job.JobParameters;
-import android.app.job.JobScheduler;
-import android.app.job.JobService;
-import android.content.ComponentName;
-import android.content.Context;
-import android.net.ipmemorystore.IOnStatusListener;
-import android.net.ipmemorystore.Status;
-import android.net.ipmemorystore.StatusParcelable;
-import android.os.IBinder;
-import android.os.RemoteException;
-import android.util.Log;
-
-import java.util.ArrayList;
-import java.util.concurrent.TimeUnit;
-
-/**
- * Regular maintenance job service.
- * @hide
- */
-public final class RegularMaintenanceJobService extends JobService {
-    // Must be unique within the system server uid.
-    public static final int REGULAR_MAINTENANCE_ID = 3345678;
-
-    /**
-     * Class for interrupt check of maintenance job.
-     */
-    public static final class InterruptMaintenance {
-        private volatile boolean mIsInterrupted;
-        private final int mJobId;
-
-        public InterruptMaintenance(int jobId) {
-            mJobId = jobId;
-            mIsInterrupted = false;
-        }
-
-        public int getJobId() {
-            return mJobId;
-        }
-
-        public void setInterrupted(boolean interrupt) {
-            mIsInterrupted = interrupt;
-        }
-
-        public boolean isInterrupted() {
-            return mIsInterrupted;
-        }
-    }
-
-    private static final ArrayList<InterruptMaintenance> sInterruptList = new ArrayList<>();
-    private static IpMemoryStoreService sIpMemoryStoreService;
-
-    @Override
-    public boolean onStartJob(JobParameters params) {
-        if (sIpMemoryStoreService == null) {
-            Log.wtf("RegularMaintenanceJobService",
-                    "Can not start job because sIpMemoryStoreService is null.");
-            return false;
-        }
-        final InterruptMaintenance im = new InterruptMaintenance(params.getJobId());
-        sInterruptList.add(im);
-
-        sIpMemoryStoreService.fullMaintenance(new IOnStatusListener() {
-            @Override
-            public void onComplete(final StatusParcelable statusParcelable) throws RemoteException {
-                final Status result = new Status(statusParcelable);
-                if (!result.isSuccess()) {
-                    Log.e("RegularMaintenanceJobService", "Regular maintenance failed."
-                            + " Error is " + result.resultCode);
-                }
-                sInterruptList.remove(im);
-                jobFinished(params, !result.isSuccess());
-            }
-
-            @Override
-            public int getInterfaceVersion() {
-                return this.VERSION;
-            }
-
-            @Override
-            public IBinder asBinder() {
-                return null;
-            }
-        }, im);
-        return true;
-    }
-
-    @Override
-    public boolean onStopJob(JobParameters params) {
-        final int jobId = params.getJobId();
-        for (InterruptMaintenance im : sInterruptList) {
-            if (im.getJobId() == jobId) {
-                im.setInterrupted(true);
-            }
-        }
-        return true;
-    }
-
-    /** Schedule regular maintenance job */
-    static void schedule(Context context, IpMemoryStoreService ipMemoryStoreService) {
-        final JobScheduler jobScheduler =
-                (JobScheduler) context.getSystemService(Context.JOB_SCHEDULER_SERVICE);
-
-        final ComponentName maintenanceJobName =
-                new ComponentName(context, RegularMaintenanceJobService.class);
-
-        // Regular maintenance is scheduled for when the device is idle with access power and a
-        // minimum interval of one day.
-        final JobInfo regularMaintenanceJob =
-                new JobInfo.Builder(REGULAR_MAINTENANCE_ID, maintenanceJobName)
-                        .setRequiresDeviceIdle(true)
-                        .setRequiresCharging(true)
-                        .setRequiresBatteryNotLow(true)
-                        .setPeriodic(TimeUnit.HOURS.toMillis(24)).build();
-
-        jobScheduler.schedule(regularMaintenanceJob);
-        sIpMemoryStoreService = ipMemoryStoreService;
-    }
-
-    /** Unschedule regular maintenance job */
-    static void unschedule(Context context) {
-        final JobScheduler jobScheduler =
-                (JobScheduler) context.getSystemService(Context.JOB_SCHEDULER_SERVICE);
-        jobScheduler.cancel(REGULAR_MAINTENANCE_ID);
-        sIpMemoryStoreService = null;
-    }
-}
diff --git a/packages/NetworkStack/src/com/android/server/connectivity/ipmemorystore/RelevanceUtils.java b/packages/NetworkStack/src/com/android/server/connectivity/ipmemorystore/RelevanceUtils.java
deleted file mode 100644
index 38d5544..0000000
--- a/packages/NetworkStack/src/com/android/server/connectivity/ipmemorystore/RelevanceUtils.java
+++ /dev/null
@@ -1,307 +0,0 @@
-/*
- * Copyright (C) 2018 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.server.connectivity.ipmemorystore;
-
-import com.android.internal.annotations.VisibleForTesting;
-
-/**
- * A class containing the logic around the relevance value for
- * IP Memory Store.
- *
- * @hide
- */
-public class RelevanceUtils {
-    /**
-     * The relevance is a decaying value that gets lower and lower until it
-     * reaches 0 after some time passes. It follows an exponential decay law,
-     * dropping slowly at first then faster and faster, because a network is
-     * likely to be visited again if it was visited not long ago, and the longer
-     * it hasn't been visited the more likely it is that it won't be visited
-     * again. For example, a network visited on holiday should stay fresh for
-     * the duration of the holiday and persist for a while, but after the venue
-     * hasn't been visited for a while it should quickly be discarded. What
-     * should accelerate forgetting the network is extended periods without
-     * visits, so that occasional venues get discarded but regular visits keep
-     * the network relevant, even if the visits are infrequent.
-     *
-     * This function must be stable by iteration, meaning that adjusting the same value
-     * for different dates iteratively multiple times should give the same result.
-     * Formally, if f is the decay function that associates a relevance x at a date d1
-     * to the value at ulterior date d3, then for any date d2 between d1 and d3 :
-     * f(x, d3 - d1) = f(f(x, d3 - d2), d2 - d1). Intuitively, this property simply
-     * means it should be the same to compute and store back the value after two months,
-     * or to do it once after one month, store it back, and do it again after another
-     * months has passed.
-     * The pair of the relevance and date define the entire curve, so any pair
-     * of values on the curve will define the same curve. Setting one of them to a
-     * constant, so as not to have to store it, means the other one will always suffice
-     * to describe the curve. For example, only storing the date for a known, constant
-     * value of the relevance is an efficient way of remembering this information (and
-     * to compare relevances together, as f is monotonically decreasing).
-     *
-     *** Choosing the function :
-     * Functions of the kind described above are standard exponential decay functions
-     * like the ones that govern atomic decay where the value at any given date can be
-     * computed uniformly from the value at a previous date and the time elapsed since
-     * that date. It is simple to picture this kind of function as one where after a
-     * given period of time called the half-life, the relevance value will have been
-     * halved. Decay of this kind is expressed in function of the previous value by
-     * functions like
-     * f(x, t) = x * F ^ (t / L)
-     * ...where x is the value, t is the elapsed time, L is the half-life (or more
-     * generally the F-th-life) and F the decay factor (typically 0.5, hence why L is
-     * usually called the half-life). The ^ symbol here is used for exponentiation.
-     * Or, starting at a given M for t = 0 :
-     * f(t) = M * F ^ (t / L)
-     *
-     * Because a line in the store needs to become irrelevant at some point but
-     * this class of functions never go to 0, a minimum cutoff has to be chosen to
-     * represent irrelevance. The simpler way of doing this is to simply add this
-     * minimum cutoff to the computation before and removing it after.
-     * Thus the function becomes :
-     * f(x, t) = ((x + K) * F ^ (t / L)) - K
-     * ...where K is the minimum cutoff, L the half-life, and F the factor between
-     * the original x and x after its half-life. Strictly speaking using the word
-     * "half-life" implies that F = 0.5, but the relation works for any value of F.
-     *
-     * It is easy enough to check that this function satisfies the stability
-     * relation that was given above for any value of F, L and K, which become
-     * parameters that can be defined at will.
-     *
-     * relevance
-     *  1.0 |
-     *      |\
-     *      | \
-     *      |  \            (this graph rendered with L = 75 days and K = 1/40)
-     *  0.75|   ',
-     *      |     \
-     *      |      '.
-     *      |        \.
-     *      |          \
-     *  0.5 |           '\
-     *      |             ''.
-     *      |                ''.
-     *      |                   ''.
-     *  0.25|                      '''..
-     *      |                           '''..
-     *      |                                ''''....
-     *      |                                        '''''..........
-     *    0 +-------------------------------------------------------''''''''''----
-     *      0       50       100      150     200      250     300      350     400 days
-     *
-     *** Choosing the parameters
-     * The maximum M is an arbitrary parameter that simply scales the curve.
-     * The tradeoff for M is pretty simple : if the relevance is going to be an
-     * integer, the bigger M is the more precision there is in the relevance.
-     * However, values of M that are easy for humans to read are preferable to
-     * help debugging, and a suitably low value may be enough to ensure there
-     * won't be integer overflows in intermediate computations.
-     * A value of 1_000_000 probably is plenty for precision, while still in the
-     * low range of what ints can represent.
-     *
-     * F and L are parameters to be chosen arbitrarily and have an impact on how
-     * fast the relevance will be decaying at first, keeping in mind that
-     * the 400 days value and the cap stay the same. In simpler words, F and L
-     * define the steepness of the curve.
-     * To keep things simple (and familiar) F is arbitrarily chosen to be 0.5, and
-     * L is set to 200 days visually to achieve the desired effect. Refer to the
-     * illustration above to get a feel of how that feels.
-     *
-     * Moreover, the memory store works on an assumption that the relevance should
-     * be capped, and that an entry with capped relevance should decay in 400 days.
-     * This is on premises that the networks a device will need to remember the
-     * longest should be networks visited about once a year.
-     * For this reason, the relevance is at the maximum M 400 days before expiry :
-     * f(M, 400 days) = 0
-     * From replacing this with the value of the function, K can then be derived
-     * from the values of M, F and L :
-     * (M + K) * F ^ (t / L) - K = 0
-     * K = M * F ^ (400 days / L) / (1 - F ^ (400 days / L))
-     * Replacing with actual values this gives :
-     * K = 1_000_000 * 0.5 ^ (400 / 200) / (1 - 0.5 ^ (400 / 200))
-     *   = 1_000_000 / 3 ≈ 333_333.3
-     * This ensures the function has the desired profile, the desired value at
-     * cap, and the desired value at expiry.
-     *
-     *** Useful relations
-     * Let's define the expiry time for any given relevance x as the interval of
-     * time such as :
-     * f(x, expiry) = 0
-     * which can be rewritten
-     * ((x + K) * F ^ (expiry / L)) = K
-     * ...giving an expression of the expiry in function of the relevance x as
-     * expiry = L * logF(K / (x + K))
-     * Conversely the relevance x can be expressed in function of the expiry as
-     * x = K / F ^ (expiry / L) - K
-     * These relations are useful in utility functions.
-     *
-     *** Bumping things up
-     * The last issue therefore is to decide how to bump up the relevance. The
-     * simple approach is to simply lift up the curve a little bit by a constant
-     * normalized amount, delaying the time of expiry. For example increasing
-     * the relevance by an amount I gives :
-     * x2 = x1 + I
-     * x2 and x1 correspond to two different expiry times expiry2 and expiry1,
-     * and replacing x1 and x2 in the relation above with their expression in
-     * function of the expiry comes :
-     * K / F ^ (expiry2 / L) - K = K / F ^ (expiry1 / L) - K + I
-     * which resolves to :
-     * expiry2 = L * logF(K / (I + K / F ^ (expiry1 / L)))
-     *
-     * In this implementation, the bump is defined as 1/25th of the cap for
-     * the relevance. This means a network will be remembered for the maximum
-     * period of 400 days if connected 25 times in succession not accounting
-     * for decay. Of course decay actually happens so it will take more than 25
-     * connections for any given network to actually reach the cap, but because
-     * decay is slow at first, it is a good estimate of how fast cap happens.
-     *
-     * Specifically, it gives the following four results :
-     * - A network that a device connects to once hits irrelevance about 32.7 days after
-     *   it was first registered if never connected again.
-     * - A network that a device connects to once a day at a fixed hour will hit the cap
-     *   on the 27th connection.
-     * - A network that a device connects to once a week at a fixed hour will hit the cap
-     *   on the 57th connection.
-     * - A network that a device connects to every day for 7 straight days then never again
-     *   expires 144 days after the last connection.
-     * These metrics tend to match pretty well the requirements.
-     */
-
-    // TODO : make these constants configurable at runtime. Don't forget to build it so that
-    // changes will wipe the database, migrate the values, or otherwise make sure the relevance
-    // values are still meaningful.
-
-    // How long, in milliseconds, is a capped relevance valid for, or in other
-    // words how many milliseconds after its relevance was set to RELEVANCE_CAP does
-    // any given line expire. 400 days.
-    @VisibleForTesting
-    public static final long CAPPED_RELEVANCE_LIFETIME_MS = 400L * 24 * 60 * 60 * 1000;
-
-    // The constant that represents a normalized 1.0 value for the relevance. In other words,
-    // the cap for the relevance. This is referred to as M in the explanation above.
-    @VisibleForTesting
-    public static final int CAPPED_RELEVANCE = 1_000_000;
-
-    // The decay factor. After a half-life, the relevance will have decayed by this value.
-    // This is referred to as F in the explanation above.
-    private static final double DECAY_FACTOR = 0.5;
-
-    // The half-life. After this time, the relevance will have decayed by a factor DECAY_FACTOR.
-    // This is referred to as L in the explanation above.
-    private static final long HALF_LIFE_MS = 200L * 24 * 60 * 60 * 1000;
-
-    // The value of the frame change. This is referred to as K in the explanation above.
-    private static final double IRRELEVANCE_FLOOR =
-            CAPPED_RELEVANCE * powF((double) CAPPED_RELEVANCE_LIFETIME_MS / HALF_LIFE_MS)
-            / (1 - powF((double) CAPPED_RELEVANCE_LIFETIME_MS / HALF_LIFE_MS));
-
-    // How much to bump the relevance by every time a line is written to.
-    @VisibleForTesting
-    public static final int RELEVANCE_BUMP = CAPPED_RELEVANCE / 25;
-
-    // Java doesn't include a function for the logarithm in an arbitrary base, so implement it
-    private static final double LOG_DECAY_FACTOR = Math.log(DECAY_FACTOR);
-    private static double logF(final double value) {
-        return Math.log(value) / LOG_DECAY_FACTOR;
-    }
-
-    // Utility function to get a power of the decay factor, to simplify the code.
-    private static double powF(final double value) {
-        return Math.pow(DECAY_FACTOR, value);
-    }
-
-    /**
-     * Compute the value of the relevance now given an expiry date.
-     *
-     * @param expiry the date at which the column in the database expires.
-     * @return the adjusted value of the relevance for this moment in time.
-     */
-    public static int computeRelevanceForNow(final long expiry) {
-        return computeRelevanceForTargetDate(expiry, System.currentTimeMillis());
-    }
-
-    /**
-     * Compute the value of the relevance at a given date from an expiry date.
-     *
-     * Because relevance decays with time, a relevance in the past corresponds to
-     * a different relevance later.
-     *
-     * Relevance is always a positive value. 0 means not relevant at all.
-     *
-     * See the explanation at the top of this file to get the justification for this
-     * computation.
-     *
-     * @param expiry the date at which the column in the database expires.
-     * @param target the target date to adjust the relevance to.
-     * @return the adjusted value of the relevance for the target moment.
-     */
-    public static int computeRelevanceForTargetDate(final long expiry, final long target) {
-        final long delay = expiry - target;
-        if (delay >= CAPPED_RELEVANCE_LIFETIME_MS) return CAPPED_RELEVANCE;
-        if (delay <= 0) return 0;
-        return (int) (IRRELEVANCE_FLOOR / powF((float) delay / HALF_LIFE_MS) - IRRELEVANCE_FLOOR);
-    }
-
-    /**
-     * Compute the expiry duration adjusted up for a new fresh write.
-     *
-     * Every time data is written to the memory store for a given line, the
-     * relevance is bumped up by a certain amount, which will boost the priority
-     * of this line for computation of group attributes, and delay (possibly
-     * indefinitely, if the line is accessed regularly) forgetting the data stored
-     * in that line.
-     * As opposed to bumpExpiryDate, this function uses a duration from now to expiry.
-     *
-     * See the explanation at the top of this file for a justification of this computation.
-     *
-     * @param oldExpiryDuration the old expiry duration in milliseconds from now.
-     * @return the expiry duration representing a bumped up relevance value.
-     */
-    public static long bumpExpiryDuration(final long oldExpiryDuration) {
-        // L * logF(K / (I + K / F ^ (expiry1 / L))), as documented above
-        final double divisionFactor = powF(((double) oldExpiryDuration) / HALF_LIFE_MS);
-        final double oldRelevance = IRRELEVANCE_FLOOR / divisionFactor;
-        final long newDuration =
-                (long) (HALF_LIFE_MS * logF(IRRELEVANCE_FLOOR / (RELEVANCE_BUMP + oldRelevance)));
-        return Math.min(newDuration, CAPPED_RELEVANCE_LIFETIME_MS);
-    }
-
-    /**
-     * Compute the new expiry date adjusted up for a new fresh write.
-     *
-     * Every time data is written to the memory store for a given line, the
-     * relevance is bumped up by a certain amount, which will boost the priority
-     * of this line for computation of group attributes, and delay (possibly
-     * indefinitely, if the line is accessed regularly) forgetting the data stored
-     * in that line.
-     * As opposed to bumpExpiryDuration, this function takes the old timestamp and returns the
-     * new timestamp.
-     *
-     * {@see bumpExpiryDuration}, and keep in mind that the bump depends on when this is called,
-     * because the relevance decays exponentially, therefore bumping up a high relevance (for a
-     * date far in the future) is less potent than bumping up a low relevance (for a date in
-     * a close future).
-     *
-     * @param oldExpiryDate the old date of expiration.
-     * @return the new expiration date after the relevance bump.
-     */
-    public static long bumpExpiryDate(final long oldExpiryDate) {
-        final long now = System.currentTimeMillis();
-        final long newDuration = bumpExpiryDuration(oldExpiryDate - now);
-        return now + newDuration;
-    }
-}
diff --git a/packages/NetworkStack/src/com/android/server/connectivity/ipmemorystore/Utils.java b/packages/NetworkStack/src/com/android/server/connectivity/ipmemorystore/Utils.java
deleted file mode 100644
index 9cbf490..0000000
--- a/packages/NetworkStack/src/com/android/server/connectivity/ipmemorystore/Utils.java
+++ /dev/null
@@ -1,52 +0,0 @@
-/*
- * Copyright (C) 2018 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.server.connectivity.ipmemorystore;
-
-import android.annotation.NonNull;
-import android.annotation.Nullable;
-import android.net.ipmemorystore.Blob;
-
-/** {@hide} */
-public class Utils {
-    /** Pretty print */
-    public static String blobToString(@Nullable final Blob blob) {
-        return "Blob : " + byteArrayToString(null == blob ? null : blob.data);
-    }
-
-    /** Pretty print */
-    public static String byteArrayToString(@Nullable final byte[] data) {
-        if (null == data) return "null";
-        final StringBuilder sb = new StringBuilder("[");
-        if (data.length <= 24) {
-            appendByteArray(sb, data, 0, data.length);
-        } else {
-            appendByteArray(sb, data, 0, 16);
-            sb.append("...");
-            appendByteArray(sb, data, data.length - 8, data.length);
-        }
-        sb.append("]");
-        return sb.toString();
-    }
-
-    // Adds the hex representation of the array between the specified indices (inclusive, exclusive)
-    private static void appendByteArray(@NonNull final StringBuilder sb, @NonNull final byte[] ar,
-            final int from, final int to) {
-        for (int i = from; i < to; ++i) {
-            sb.append(String.format("%02X", ar[i]));
-        }
-    }
-}
diff --git a/packages/NetworkStack/src/com/android/server/util/NetworkStackConstants.java b/packages/NetworkStack/src/com/android/server/util/NetworkStackConstants.java
deleted file mode 100644
index 804765e..0000000
--- a/packages/NetworkStack/src/com/android/server/util/NetworkStackConstants.java
+++ /dev/null
@@ -1,142 +0,0 @@
-/*
- * Copyright (C) 2018 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.server.util;
-
-import static android.net.shared.Inet4AddressUtils.intToInet4AddressHTH;
-
-import java.net.Inet4Address;
-
-/**
- * Network constants used by the network stack.
- */
-public final class NetworkStackConstants {
-
-    /**
-     * IPv4 constants.
-     *
-     * See also:
-     *     - https://tools.ietf.org/html/rfc791
-     */
-    public static final int IPV4_ADDR_BITS = 32;
-    public static final int IPV4_MIN_MTU = 68;
-    public static final int IPV4_MAX_MTU = 65_535;
-
-    /**
-     * Ethernet constants.
-     *
-     * See also:
-     *     - https://tools.ietf.org/html/rfc894
-     *     - https://tools.ietf.org/html/rfc2464
-     *     - https://tools.ietf.org/html/rfc7042
-     *     - http://www.iana.org/assignments/ethernet-numbers/ethernet-numbers.xhtml
-     *     - http://www.iana.org/assignments/ieee-802-numbers/ieee-802-numbers.xhtml
-     */
-    public static final int ETHER_DST_ADDR_OFFSET = 0;
-    public static final int ETHER_SRC_ADDR_OFFSET = 6;
-    public static final int ETHER_ADDR_LEN = 6;
-    public static final int ETHER_TYPE_OFFSET = 12;
-    public static final int ETHER_TYPE_LENGTH = 2;
-    public static final int ETHER_TYPE_ARP  = 0x0806;
-    public static final int ETHER_TYPE_IPV4 = 0x0800;
-    public static final int ETHER_TYPE_IPV6 = 0x86dd;
-    public static final int ETHER_HEADER_LEN = 14;
-
-    /**
-     * ARP constants.
-     *
-     * See also:
-     *     - https://tools.ietf.org/html/rfc826
-     *     - http://www.iana.org/assignments/arp-parameters/arp-parameters.xhtml
-     */
-    public static final int ARP_PAYLOAD_LEN = 28;  // For Ethernet+IPv4.
-    public static final int ARP_REQUEST = 1;
-    public static final int ARP_REPLY   = 2;
-    public static final int ARP_HWTYPE_RESERVED_LO = 0;
-    public static final int ARP_HWTYPE_ETHER       = 1;
-    public static final int ARP_HWTYPE_RESERVED_HI = 0xffff;
-
-    /**
-     * IPv4 constants.
-     *
-     * See also:
-     *     - https://tools.ietf.org/html/rfc791
-     */
-    public static final int IPV4_HEADER_MIN_LEN = 20;
-    public static final int IPV4_IHL_MASK = 0xf;
-    public static final int IPV4_FLAGS_OFFSET = 6;
-    public static final int IPV4_FRAGMENT_MASK = 0x1fff;
-    public static final int IPV4_PROTOCOL_OFFSET = 9;
-    public static final int IPV4_SRC_ADDR_OFFSET = 12;
-    public static final int IPV4_DST_ADDR_OFFSET = 16;
-    public static final int IPV4_ADDR_LEN = 4;
-    public static final Inet4Address IPV4_ADDR_ALL = intToInet4AddressHTH(0xffffffff);
-    public static final Inet4Address IPV4_ADDR_ANY = intToInet4AddressHTH(0x0);
-
-    /**
-     * IPv6 constants.
-     *
-     * See also:
-     *     - https://tools.ietf.org/html/rfc2460
-     */
-    public static final int IPV6_ADDR_LEN = 16;
-    public static final int IPV6_HEADER_LEN = 40;
-    public static final int IPV6_PROTOCOL_OFFSET = 6;
-    public static final int IPV6_SRC_ADDR_OFFSET = 8;
-    public static final int IPV6_DST_ADDR_OFFSET = 24;
-
-    /**
-     * ICMPv6 constants.
-     *
-     * See also:
-     *     - https://tools.ietf.org/html/rfc4443
-     *     - https://tools.ietf.org/html/rfc4861
-     */
-    public static final int ICMPV6_HEADER_MIN_LEN = 4;
-    public static final int ICMPV6_ECHO_REPLY_TYPE = 129;
-    public static final int ICMPV6_ECHO_REQUEST_TYPE = 128;
-    public static final int ICMPV6_ROUTER_SOLICITATION    = 133;
-    public static final int ICMPV6_ROUTER_ADVERTISEMENT   = 134;
-    public static final int ICMPV6_NEIGHBOR_SOLICITATION  = 135;
-    public static final int ICMPV6_NEIGHBOR_ADVERTISEMENT = 136;
-    public static final int ICMPV6_ND_OPTION_MIN_LENGTH = 8;
-    public static final int ICMPV6_ND_OPTION_LENGTH_SCALING_FACTOR = 8;
-    public static final int ICMPV6_ND_OPTION_SLLA = 1;
-    public static final int ICMPV6_ND_OPTION_TLLA = 2;
-    public static final int ICMPV6_ND_OPTION_MTU  = 5;
-
-    /**
-     * UDP constants.
-     *
-     * See also:
-     *     - https://tools.ietf.org/html/rfc768
-     */
-    public static final int UDP_HEADER_LEN = 8;
-
-
-    /**
-     * DHCP constants.
-     *
-     * See also:
-     *     - https://tools.ietf.org/html/rfc2131
-     */
-    public static final int INFINITE_LEASE = 0xffffffff;
-    public static final int DHCP4_CLIENT_PORT = 68;
-
-    private NetworkStackConstants() {
-        throw new UnsupportedOperationException("This class is not to be instantiated");
-    }
-}
diff --git a/packages/NetworkStack/src/com/android/server/util/PermissionUtil.java b/packages/NetworkStack/src/com/android/server/util/PermissionUtil.java
deleted file mode 100644
index 6701384..0000000
--- a/packages/NetworkStack/src/com/android/server/util/PermissionUtil.java
+++ /dev/null
@@ -1,84 +0,0 @@
-/*
- * Copyright (C) 2018 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.server.util;
-
-import static android.os.Binder.getCallingPid;
-import static android.os.Binder.getCallingUid;
-
-import android.os.Process;
-import android.os.UserHandle;
-
-import java.util.concurrent.atomic.AtomicInteger;
-
-/**
- * Utility class to check calling permissions on the network stack.
- */
-public final class PermissionUtil {
-    private static final AtomicInteger sSystemPid = new AtomicInteger(-1);
-
-    /**
-     * Check that the caller is allowed to communicate with the network stack.
-     * @throws SecurityException The caller is not allowed to communicate with the network stack.
-     */
-    public static void checkNetworkStackCallingPermission() {
-        final int caller = getCallingUid();
-        if (caller == Process.SYSTEM_UID) {
-            checkConsistentSystemPid();
-            return;
-        }
-
-        if (UserHandle.getAppId(caller) != Process.BLUETOOTH_UID) {
-            throw new SecurityException("Invalid caller: " + caller);
-        }
-    }
-
-    private static void checkConsistentSystemPid() {
-        // Apart from the system server process, no process with a system UID should try to
-        // communicate with the network stack. This is to ensure that the network stack does not
-        // need to maintain behavior for clients it was not designed to work with.
-        // Checking that all calls from a system UID originate from the same PID loosely enforces
-        // this restriction as if another system process calls the network stack first, the system
-        // server would lose access to the network stack and cause obvious failures. If the system
-        // server calls the network stack first, other clients would lose access as expected.
-        final int systemPid = getCallingPid();
-        if (sSystemPid.compareAndSet(-1, systemPid)) {
-            // sSystemPid was unset (-1): this was the first call
-            return;
-        }
-
-        if (sSystemPid.get() != systemPid) {
-            throw new SecurityException("Invalid PID for the system server, expected "
-                    + sSystemPid.get() + " but was called from " + systemPid);
-        }
-    }
-
-    /**
-     * Check that the caller is allowed to dump the network stack, e.g. dumpsys.
-     * @throws SecurityException The caller is not allowed to dump the network stack.
-     */
-    public static void checkDumpPermission() {
-        final int caller = getCallingUid();
-        if (caller != Process.SYSTEM_UID && caller != Process.ROOT_UID
-                && caller != Process.SHELL_UID) {
-            throw new SecurityException("No dump permissions for caller: " + caller);
-        }
-    }
-
-    private PermissionUtil() {
-        throw new UnsupportedOperationException("This class is not to be instantiated");
-    }
-}
diff --git a/packages/NetworkStack/tests/unit/Android.bp b/packages/NetworkStack/tests/unit/Android.bp
deleted file mode 100644
index 6cc8054..0000000
--- a/packages/NetworkStack/tests/unit/Android.bp
+++ /dev/null
@@ -1,103 +0,0 @@
-//
-// Copyright (C) 2018 The Android Open Source Project
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//      http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-//
-
-android_test {
-    name: "NetworkStackTests",
-    certificate: "platform",
-    srcs: ["src/**/*.java"],
-    test_suites: ["device-tests"],
-    resource_dirs: ["res"],
-    static_libs: [
-        "androidx.test.rules",
-        "mockito-target-extended-minus-junit4",
-        "NetworkStackBase",
-        "testables",
-    ],
-    libs: [
-        "android.test.runner",
-        "android.test.base",
-        "android.test.mock",
-    ],
-    jni_libs: [
-        // For mockito extended
-        "libdexmakerjvmtiagent",
-        "libstaticjvmtiagent",
-        // For ApfTest
-        "libartbase",
-        "libbacktrace",
-        "libbase",
-        "libbinder",
-        "libbinderthreadstate",
-        "libc++",
-        "libcgrouprc",
-        "libcrypto",
-        "libcutils",
-        "libdexfile",
-        "ld-android",
-        "libdl_android",
-        "libhidl-gen-utils",
-        "libhidlbase",
-        "libhidltransport",
-        "libhwbinder",
-        "libjsoncpp",
-        "liblog",
-        "liblzma",
-        "libnativehelper",
-        "libnativehelper_compat_libc++",
-        "libnetworkstacktestsjni",
-        "libnetworkstackutilsjni",
-        "libpackagelistparser",
-        "libpcre2",
-        "libprocessgroup",
-        "libselinux",
-        "libui",
-        "libutils",
-        "libvintf",
-        "libvndksupport",
-        "libtinyxml2",
-        "libunwindstack",
-        "libutilscallstack",
-        "libziparchive",
-        "libz",
-        "netd_aidl_interface-V2-cpp",
-    ],
-}
-
-cc_library_shared {
-    name: "libnetworkstacktestsjni",
-    srcs: [
-        "jni/**/*.cpp"
-    ],
-    cflags: [
-        "-Wall",
-        "-Wextra",
-        "-Werror",
-    ],
-    include_dirs: [
-        "hardware/google/apf",
-    ],
-    shared_libs: [
-        "libbinder",
-        "liblog",
-        "libcutils",
-        "libnativehelper",
-        "netd_aidl_interface-V2-cpp",
-    ],
-    static_libs: [
-        "libapf",
-        "libpcap",
-    ],
-}
diff --git a/packages/NetworkStack/tests/unit/AndroidManifest.xml b/packages/NetworkStack/tests/unit/AndroidManifest.xml
deleted file mode 100644
index 5dcf6ff..0000000
--- a/packages/NetworkStack/tests/unit/AndroidManifest.xml
+++ /dev/null
@@ -1,54 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- 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.
--->
-<manifest xmlns:android="http://schemas.android.com/apk/res/android"
-          package="com.android.server.networkstack.tests">
-
-    <uses-permission android:name="android.permission.READ_LOGS" />
-    <uses-permission android:name="android.permission.WRITE_SETTINGS" />
-    <uses-permission android:name="android.permission.WRITE_SECURE_SETTINGS" />
-    <uses-permission android:name="android.permission.READ_PHONE_STATE" />
-    <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
-    <uses-permission android:name="android.permission.BROADCAST_STICKY" />
-    <uses-permission android:name="android.permission.UPDATE_DEVICE_STATS" />
-    <uses-permission android:name="android.permission.MANAGE_APP_TOKENS" />
-    <uses-permission android:name="android.permission.WAKE_LOCK" />
-    <uses-permission android:name="android.permission.INTERACT_ACROSS_USERS" />
-    <uses-permission android:name="android.permission.REAL_GET_TASKS" />
-    <uses-permission android:name="android.permission.GET_DETAILED_TASKS" />
-    <uses-permission android:name="android.permission.MANAGE_NETWORK_POLICY" />
-    <uses-permission android:name="android.permission.READ_NETWORK_USAGE_HISTORY" />
-    <uses-permission android:name="android.permission.CONNECTIVITY_INTERNAL" />
-    <uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
-    <uses-permission android:name="android.permission.MANAGE_USERS" />
-    <uses-permission android:name="android.permission.INTERACT_ACROSS_USERS_FULL" />
-    <uses-permission android:name="android.permission.MANAGE_DEVICE_ADMINS" />
-    <uses-permission android:name="android.permission.MODIFY_PHONE_STATE" />
-    <uses-permission android:name="android.permission.INTERNET" />
-    <uses-permission android:name="android.permission.CHANGE_NETWORK_STATE" />
-    <uses-permission android:name="android.permission.PACKET_KEEPALIVE_OFFLOAD" />
-    <uses-permission android:name="android.permission.GET_INTENT_SENDER_INTENT" />
-    <uses-permission android:name="android.permission.MANAGE_ACTIVITY_STACKS" />
-    <uses-permission android:name="android.permission.INSTALL_PACKAGES" />
-    <uses-permission android:name="android.permission.NETWORK_STACK" />
-
-    <application android:debuggable="true">
-        <uses-library android:name="android.test.runner" />
-    </application>
-    <instrumentation android:name="androidx.test.runner.AndroidJUnitRunner"
-        android:targetPackage="com.android.server.networkstack.tests"
-        android:label="Networking service tests">
-    </instrumentation>
-</manifest>
\ No newline at end of file
diff --git a/packages/NetworkStack/tests/unit/AndroidTest.xml b/packages/NetworkStack/tests/unit/AndroidTest.xml
deleted file mode 100644
index 047bc2e..0000000
--- a/packages/NetworkStack/tests/unit/AndroidTest.xml
+++ /dev/null
@@ -1,29 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- 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.
--->
-<configuration description="Runs Tests for NetworkStack">
-    <target_preparer class="com.android.tradefed.targetprep.TestAppInstallSetup">
-        <option name="test-file-name" value="NetworkStackTests.apk" />
-    </target_preparer>
-
-    <option name="test-suite-tag" value="apct" />
-    <option name="test-suite-tag" value="framework-base-presubmit" />
-    <option name="test-tag" value="NetworkStackTests" />
-    <test class="com.android.tradefed.testtype.AndroidJUnitTest" >
-        <option name="package" value="com.android.server.networkstack.tests" />
-        <option name="runner" value="androidx.test.runner.AndroidJUnitRunner" />
-        <option name="hidden-api-checks" value="false"/>
-    </test>
-</configuration>
\ No newline at end of file
diff --git a/packages/NetworkStack/tests/unit/jni/apf_jni.cpp b/packages/NetworkStack/tests/unit/jni/apf_jni.cpp
deleted file mode 100644
index 4222adf..0000000
--- a/packages/NetworkStack/tests/unit/jni/apf_jni.cpp
+++ /dev/null
@@ -1,248 +0,0 @@
-/*
- * Copyright 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.
- */
-
-#include <nativehelper/JNIHelp.h>
-#include <nativehelper/ScopedUtfChars.h>
-#include <jni.h>
-#include <pcap.h>
-#include <stdlib.h>
-#include <string>
-#include <utils/Log.h>
-#include <vector>
-
-#include "apf_interpreter.h"
-#include "nativehelper/scoped_primitive_array.h"
-
-#define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0]))
-
-// JNI function acting as simply call-through to native APF interpreter.
-static jint com_android_server_ApfTest_apfSimulate(
-        JNIEnv* env, jclass, jbyteArray jprogram, jbyteArray jpacket,
-        jbyteArray jdata, jint filter_age) {
-
-    ScopedByteArrayRO packet(env, jpacket);
-    uint32_t packet_len = (uint32_t)packet.size();
-    uint32_t program_len = env->GetArrayLength(jprogram);
-    uint32_t data_len = jdata ? env->GetArrayLength(jdata) : 0;
-    std::vector<uint8_t> buf(program_len + data_len, 0);
-
-    env->GetByteArrayRegion(jprogram, 0, program_len, reinterpret_cast<jbyte*>(buf.data()));
-    if (jdata) {
-        // Merge program and data into a single buffer.
-        env->GetByteArrayRegion(jdata, 0, data_len,
-                                reinterpret_cast<jbyte*>(buf.data() + program_len));
-    }
-
-    jint result =
-        accept_packet(buf.data(), program_len, program_len + data_len,
-                        reinterpret_cast<const uint8_t*>(packet.get()), packet_len, filter_age);
-
-    if (jdata) {
-        env->SetByteArrayRegion(jdata, 0, data_len,
-                                reinterpret_cast<jbyte*>(buf.data() + program_len));
-    }
-
-    return result;
-}
-
-class ScopedPcap {
-  public:
-    explicit ScopedPcap(pcap_t* pcap) : pcap_ptr(pcap) {}
-    ~ScopedPcap() {
-        pcap_close(pcap_ptr);
-    }
-
-    pcap_t* get() const { return pcap_ptr; };
-  private:
-    pcap_t* const pcap_ptr;
-};
-
-class ScopedFILE {
-  public:
-    explicit ScopedFILE(FILE* fp) : file(fp) {}
-    ~ScopedFILE() {
-        fclose(file);
-    }
-
-    FILE* get() const { return file; };
-  private:
-    FILE* const file;
-};
-
-static void throwException(JNIEnv* env, const std::string& error) {
-    jclass newExcCls = env->FindClass("java/lang/IllegalStateException");
-    if (newExcCls == 0) {
-      abort();
-      return;
-    }
-    env->ThrowNew(newExcCls, error.c_str());
-}
-
-static jstring com_android_server_ApfTest_compileToBpf(JNIEnv* env, jclass, jstring jfilter) {
-    ScopedUtfChars filter(env, jfilter);
-    std::string bpf_string;
-    ScopedPcap pcap(pcap_open_dead(DLT_EN10MB, 65535));
-    if (pcap.get() == NULL) {
-        throwException(env, "pcap_open_dead failed");
-        return NULL;
-    }
-
-    // Compile "filter" to a BPF program
-    bpf_program bpf;
-    if (pcap_compile(pcap.get(), &bpf, filter.c_str(), 0, PCAP_NETMASK_UNKNOWN)) {
-        throwException(env, "pcap_compile failed");
-        return NULL;
-    }
-
-    // Translate BPF program to human-readable format
-    const struct bpf_insn* insn = bpf.bf_insns;
-    for (uint32_t i = 0; i < bpf.bf_len; i++) {
-        bpf_string += bpf_image(insn++, i);
-        bpf_string += "\n";
-    }
-
-    return env->NewStringUTF(bpf_string.c_str());
-}
-
-static jboolean com_android_server_ApfTest_compareBpfApf(JNIEnv* env, jclass, jstring jfilter,
-        jstring jpcap_filename, jbyteArray japf_program) {
-    ScopedUtfChars filter(env, jfilter);
-    ScopedUtfChars pcap_filename(env, jpcap_filename);
-    ScopedByteArrayRO apf_program(env, japf_program);
-
-    // Open pcap file for BPF filtering
-    ScopedFILE bpf_fp(fopen(pcap_filename.c_str(), "rb"));
-    char pcap_error[PCAP_ERRBUF_SIZE];
-    ScopedPcap bpf_pcap(pcap_fopen_offline(bpf_fp.get(), pcap_error));
-    if (bpf_pcap.get() == NULL) {
-        throwException(env, "pcap_fopen_offline failed: " + std::string(pcap_error));
-        return false;
-    }
-
-    // Open pcap file for APF filtering
-    ScopedFILE apf_fp(fopen(pcap_filename.c_str(), "rb"));
-    ScopedPcap apf_pcap(pcap_fopen_offline(apf_fp.get(), pcap_error));
-    if (apf_pcap.get() == NULL) {
-        throwException(env, "pcap_fopen_offline failed: " + std::string(pcap_error));
-        return false;
-    }
-
-    // Compile "filter" to a BPF program
-    bpf_program bpf;
-    if (pcap_compile(bpf_pcap.get(), &bpf, filter.c_str(), 0, PCAP_NETMASK_UNKNOWN)) {
-        throwException(env, "pcap_compile failed");
-        return false;
-    }
-
-    // Install BPF filter on bpf_pcap
-    if (pcap_setfilter(bpf_pcap.get(), &bpf)) {
-        throwException(env, "pcap_setfilter failed");
-        return false;
-    }
-
-    while (1) {
-        pcap_pkthdr bpf_header, apf_header;
-        // Run BPF filter to the next matching packet.
-        const uint8_t* bpf_packet = pcap_next(bpf_pcap.get(), &bpf_header);
-
-        // Run APF filter to the next matching packet.
-        const uint8_t* apf_packet;
-        do {
-            apf_packet = pcap_next(apf_pcap.get(), &apf_header);
-        } while (apf_packet != NULL && !accept_packet(
-                reinterpret_cast<uint8_t*>(const_cast<int8_t*>(apf_program.get())),
-                apf_program.size(), 0 /* data_len */,
-                apf_packet, apf_header.len, 0 /* filter_age */));
-
-        // Make sure both filters matched the same packet.
-        if (apf_packet == NULL && bpf_packet == NULL)
-            break;
-        if (apf_packet == NULL || bpf_packet == NULL)
-            return false;
-        if (apf_header.len != bpf_header.len ||
-                apf_header.ts.tv_sec != bpf_header.ts.tv_sec ||
-                apf_header.ts.tv_usec != bpf_header.ts.tv_usec ||
-                memcmp(apf_packet, bpf_packet, apf_header.len))
-            return false;
-    }
-    return true;
-}
-
-static jboolean com_android_server_ApfTest_dropsAllPackets(JNIEnv* env, jclass, jbyteArray jprogram,
-        jbyteArray jdata, jstring jpcap_filename) {
-    ScopedUtfChars pcap_filename(env, jpcap_filename);
-    ScopedByteArrayRO apf_program(env, jprogram);
-    uint32_t apf_program_len = (uint32_t)apf_program.size();
-    uint32_t data_len = env->GetArrayLength(jdata);
-    pcap_pkthdr apf_header;
-    const uint8_t* apf_packet;
-    char pcap_error[PCAP_ERRBUF_SIZE];
-    std::vector<uint8_t> buf(apf_program_len + data_len, 0);
-
-    // Merge program and data into a single buffer.
-    env->GetByteArrayRegion(jprogram, 0, apf_program_len, reinterpret_cast<jbyte*>(buf.data()));
-    env->GetByteArrayRegion(jdata, 0, data_len,
-                            reinterpret_cast<jbyte*>(buf.data() + apf_program_len));
-
-    // Open pcap file
-    ScopedFILE apf_fp(fopen(pcap_filename.c_str(), "rb"));
-    ScopedPcap apf_pcap(pcap_fopen_offline(apf_fp.get(), pcap_error));
-
-    if (apf_pcap.get() == NULL) {
-        throwException(env, "pcap_fopen_offline failed: " + std::string(pcap_error));
-        return false;
-    }
-
-    while ((apf_packet = pcap_next(apf_pcap.get(), &apf_header)) != NULL) {
-        int result = accept_packet(buf.data(), apf_program_len,
-                                    apf_program_len + data_len, apf_packet, apf_header.len, 0);
-
-        // Return false once packet passes the filter
-        if (result) {
-            env->SetByteArrayRegion(jdata, 0, data_len,
-                                    reinterpret_cast<jbyte*>(buf.data() + apf_program_len));
-            return false;
-         }
-    }
-
-    env->SetByteArrayRegion(jdata, 0, data_len,
-                            reinterpret_cast<jbyte*>(buf.data() + apf_program_len));
-    return true;
-}
-
-extern "C" jint JNI_OnLoad(JavaVM* vm, void*) {
-    JNIEnv *env;
-    if (vm->GetEnv(reinterpret_cast<void**>(&env), JNI_VERSION_1_6) != JNI_OK) {
-        ALOGE("ERROR: GetEnv failed");
-        return -1;
-    }
-
-    static JNINativeMethod gMethods[] = {
-            { "apfSimulate", "([B[B[BI)I",
-                    (void*)com_android_server_ApfTest_apfSimulate },
-            { "compileToBpf", "(Ljava/lang/String;)Ljava/lang/String;",
-                    (void*)com_android_server_ApfTest_compileToBpf },
-            { "compareBpfApf", "(Ljava/lang/String;Ljava/lang/String;[B)Z",
-                    (void*)com_android_server_ApfTest_compareBpfApf },
-            { "dropsAllPackets", "([B[BLjava/lang/String;)Z",
-                    (void*)com_android_server_ApfTest_dropsAllPackets },
-    };
-
-    jniRegisterNativeMethods(env, "android/net/apf/ApfTest",
-            gMethods, ARRAY_SIZE(gMethods));
-
-    return JNI_VERSION_1_6;
-}
diff --git a/packages/NetworkStack/tests/unit/res/raw/apf.pcap b/packages/NetworkStack/tests/unit/res/raw/apf.pcap
deleted file mode 100644
index 963165f..0000000
--- a/packages/NetworkStack/tests/unit/res/raw/apf.pcap
+++ /dev/null
Binary files differ
diff --git a/packages/NetworkStack/tests/unit/res/raw/apfPcap.pcap b/packages/NetworkStack/tests/unit/res/raw/apfPcap.pcap
deleted file mode 100644
index 6f69c4a..0000000
--- a/packages/NetworkStack/tests/unit/res/raw/apfPcap.pcap
+++ /dev/null
Binary files differ
diff --git a/packages/NetworkStack/tests/unit/src/android/net/apf/ApfTest.java b/packages/NetworkStack/tests/unit/src/android/net/apf/ApfTest.java
deleted file mode 100644
index 8f2b968..0000000
--- a/packages/NetworkStack/tests/unit/src/android/net/apf/ApfTest.java
+++ /dev/null
@@ -1,2110 +0,0 @@
-/*
- * Copyright (C) 2012 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.net.apf;
-
-import static android.system.OsConstants.AF_UNIX;
-import static android.system.OsConstants.ARPHRD_ETHER;
-import static android.system.OsConstants.ETH_P_ARP;
-import static android.system.OsConstants.ETH_P_IP;
-import static android.system.OsConstants.ETH_P_IPV6;
-import static android.system.OsConstants.IPPROTO_ICMPV6;
-import static android.system.OsConstants.IPPROTO_TCP;
-import static android.system.OsConstants.IPPROTO_UDP;
-import static android.system.OsConstants.SOCK_STREAM;
-
-import static com.android.internal.util.BitUtils.bytesToBEInt;
-import static com.android.server.util.NetworkStackConstants.ICMPV6_ECHO_REQUEST_TYPE;
-
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertFalse;
-import static org.junit.Assert.assertTrue;
-import static org.junit.Assert.fail;
-import static org.mockito.Mockito.atLeastOnce;
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.verify;
-
-import android.content.Context;
-import android.net.LinkAddress;
-import android.net.LinkProperties;
-import android.net.NattKeepalivePacketDataParcelable;
-import android.net.TcpKeepalivePacketDataParcelable;
-import android.net.apf.ApfFilter.ApfConfiguration;
-import android.net.apf.ApfGenerator.IllegalInstructionException;
-import android.net.apf.ApfGenerator.Register;
-import android.net.ip.IIpClientCallbacks;
-import android.net.ip.IpClient.IpClientCallbacksWrapper;
-import android.net.metrics.IpConnectivityLog;
-import android.net.metrics.RaEvent;
-import android.net.util.InterfaceParams;
-import android.net.util.SharedLog;
-import android.os.ConditionVariable;
-import android.os.Parcelable;
-import android.os.SystemClock;
-import android.system.ErrnoException;
-import android.system.Os;
-import android.text.format.DateUtils;
-import android.util.Log;
-
-import androidx.test.InstrumentationRegistry;
-import androidx.test.filters.SmallTest;
-import androidx.test.runner.AndroidJUnit4;
-
-import com.android.internal.util.HexDump;
-import com.android.server.networkstack.tests.R;
-import com.android.server.util.NetworkStackConstants;
-
-import libcore.io.IoUtils;
-import libcore.io.Streams;
-
-import org.junit.Before;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.mockito.ArgumentCaptor;
-import org.mockito.Mock;
-import org.mockito.MockitoAnnotations;
-
-import java.io.File;
-import java.io.FileDescriptor;
-import java.io.FileOutputStream;
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.OutputStream;
-import java.net.InetAddress;
-import java.nio.ByteBuffer;
-import java.util.List;
-import java.util.Random;
-
-/**
- * Tests for APF program generator and interpreter.
- *
- * Build, install and run with:
- *  runtest frameworks-net -c android.net.apf.ApfTest
- */
-@RunWith(AndroidJUnit4.class)
-@SmallTest
-public class ApfTest {
-    private static final int TIMEOUT_MS = 500;
-    private static final int MIN_APF_VERSION = 2;
-
-    @Mock IpConnectivityLog mLog;
-    @Mock Context mContext;
-
-    @Before
-    public void setUp() throws Exception {
-        MockitoAnnotations.initMocks(this);
-        // Load up native shared library containing APF interpreter exposed via JNI.
-        System.loadLibrary("networkstacktestsjni");
-    }
-
-    private static final String TAG = "ApfTest";
-    // Expected return codes from APF interpreter.
-    private static final int PASS = 1;
-    private static final int DROP = 0;
-    // Interpreter will just accept packets without link layer headers, so pad fake packet to at
-    // least the minimum packet size.
-    private static final int MIN_PKT_SIZE = 15;
-
-    private static final ApfCapabilities MOCK_APF_CAPABILITIES =
-      new ApfCapabilities(2, 1700, ARPHRD_ETHER);
-
-    private static final boolean DROP_MULTICAST = true;
-    private static final boolean ALLOW_MULTICAST = false;
-
-    private static final boolean DROP_802_3_FRAMES = true;
-    private static final boolean ALLOW_802_3_FRAMES = false;
-
-    // Constants for opcode encoding
-    private static final byte LI_OP   = (byte)(13 << 3);
-    private static final byte LDDW_OP = (byte)(22 << 3);
-    private static final byte STDW_OP = (byte)(23 << 3);
-    private static final byte SIZE0   = (byte)(0 << 1);
-    private static final byte SIZE8   = (byte)(1 << 1);
-    private static final byte SIZE16  = (byte)(2 << 1);
-    private static final byte SIZE32  = (byte)(3 << 1);
-    private static final byte R1 = 1;
-
-    private static ApfConfiguration getDefaultConfig() {
-        ApfFilter.ApfConfiguration config = new ApfConfiguration();
-        config.apfCapabilities = MOCK_APF_CAPABILITIES;
-        config.multicastFilter = ALLOW_MULTICAST;
-        config.ieee802_3Filter = ALLOW_802_3_FRAMES;
-        config.ethTypeBlackList = new int[0];
-        return config;
-    }
-
-    private static String label(int code) {
-        switch (code) {
-            case PASS: return "PASS";
-            case DROP: return "DROP";
-            default:   return "UNKNOWN";
-        }
-    }
-
-    private static void assertReturnCodesEqual(int expected, int got) {
-        assertEquals(label(expected), label(got));
-    }
-
-    private void assertVerdict(int expected, byte[] program, byte[] packet, int filterAge) {
-        assertReturnCodesEqual(expected, apfSimulate(program, packet, null, filterAge));
-    }
-
-    private void assertVerdict(int expected, byte[] program, byte[] packet) {
-        assertReturnCodesEqual(expected, apfSimulate(program, packet, null, 0));
-    }
-
-    private void assertPass(byte[] program, byte[] packet, int filterAge) {
-        assertVerdict(PASS, program, packet, filterAge);
-    }
-
-    private void assertPass(byte[] program, byte[] packet) {
-        assertVerdict(PASS, program, packet);
-    }
-
-    private void assertDrop(byte[] program, byte[] packet, int filterAge) {
-        assertVerdict(DROP, program, packet, filterAge);
-    }
-
-    private void assertDrop(byte[] program, byte[] packet) {
-        assertVerdict(DROP, program, packet);
-    }
-
-    private void assertProgramEquals(byte[] expected, byte[] program) throws AssertionError {
-        // assertArrayEquals() would only print one byte, making debugging difficult.
-        if (!java.util.Arrays.equals(expected, program)) {
-            throw new AssertionError(
-                    "\nexpected: " + HexDump.toHexString(expected) +
-                    "\nactual:   " + HexDump.toHexString(program));
-        }
-    }
-
-    private void assertDataMemoryContents(
-            int expected, byte[] program, byte[] packet, byte[] data, byte[] expected_data)
-            throws IllegalInstructionException, Exception {
-        assertReturnCodesEqual(expected, apfSimulate(program, packet, data, 0 /* filterAge */));
-
-        // assertArrayEquals() would only print one byte, making debugging difficult.
-        if (!java.util.Arrays.equals(expected_data, data)) {
-            throw new Exception(
-                    "\nprogram:     " + HexDump.toHexString(program) +
-                    "\ndata memory: " + HexDump.toHexString(data) +
-                    "\nexpected:    " + HexDump.toHexString(expected_data));
-        }
-    }
-
-    private void assertVerdict(int expected, ApfGenerator gen, byte[] packet, int filterAge)
-            throws IllegalInstructionException {
-        assertReturnCodesEqual(expected, apfSimulate(gen.generate(), packet, null,
-              filterAge));
-    }
-
-    private void assertPass(ApfGenerator gen, byte[] packet, int filterAge)
-            throws IllegalInstructionException {
-        assertVerdict(PASS, gen, packet, filterAge);
-    }
-
-    private void assertDrop(ApfGenerator gen, byte[] packet, int filterAge)
-            throws IllegalInstructionException {
-        assertVerdict(DROP, gen, packet, filterAge);
-    }
-
-    private void assertPass(ApfGenerator gen)
-            throws IllegalInstructionException {
-        assertVerdict(PASS, gen, new byte[MIN_PKT_SIZE], 0);
-    }
-
-    private void assertDrop(ApfGenerator gen)
-            throws IllegalInstructionException {
-        assertVerdict(DROP, gen, new byte[MIN_PKT_SIZE], 0);
-    }
-
-    /**
-     * Test each instruction by generating a program containing the instruction,
-     * generating bytecode for that program and running it through the
-     * interpreter to verify it functions correctly.
-     */
-    @Test
-    public void testApfInstructions() throws IllegalInstructionException {
-        // Empty program should pass because having the program counter reach the
-        // location immediately after the program indicates the packet should be
-        // passed to the AP.
-        ApfGenerator gen = new ApfGenerator(MIN_APF_VERSION);
-        assertPass(gen);
-
-        // Test jumping to pass label.
-        gen = new ApfGenerator(MIN_APF_VERSION);
-        gen.addJump(gen.PASS_LABEL);
-        byte[] program = gen.generate();
-        assertEquals(1, program.length);
-        assertEquals((14 << 3) | (0 << 1) | 0, program[0]);
-        assertPass(program, new byte[MIN_PKT_SIZE], 0);
-
-        // Test jumping to drop label.
-        gen = new ApfGenerator(MIN_APF_VERSION);
-        gen.addJump(gen.DROP_LABEL);
-        program = gen.generate();
-        assertEquals(2, program.length);
-        assertEquals((14 << 3) | (1 << 1) | 0, program[0]);
-        assertEquals(1, program[1]);
-        assertDrop(program, new byte[15], 15);
-
-        // Test jumping if equal to 0.
-        gen = new ApfGenerator(MIN_APF_VERSION);
-        gen.addJumpIfR0Equals(0, gen.DROP_LABEL);
-        assertDrop(gen);
-
-        // Test jumping if not equal to 0.
-        gen = new ApfGenerator(MIN_APF_VERSION);
-        gen.addJumpIfR0NotEquals(0, gen.DROP_LABEL);
-        assertPass(gen);
-        gen = new ApfGenerator(MIN_APF_VERSION);
-        gen.addLoadImmediate(Register.R0, 1);
-        gen.addJumpIfR0NotEquals(0, gen.DROP_LABEL);
-        assertDrop(gen);
-
-        // Test jumping if registers equal.
-        gen = new ApfGenerator(MIN_APF_VERSION);
-        gen.addJumpIfR0EqualsR1(gen.DROP_LABEL);
-        assertDrop(gen);
-
-        // Test jumping if registers not equal.
-        gen = new ApfGenerator(MIN_APF_VERSION);
-        gen.addJumpIfR0NotEqualsR1(gen.DROP_LABEL);
-        assertPass(gen);
-        gen = new ApfGenerator(MIN_APF_VERSION);
-        gen.addLoadImmediate(Register.R0, 1);
-        gen.addJumpIfR0NotEqualsR1(gen.DROP_LABEL);
-        assertDrop(gen);
-
-        // Test load immediate.
-        gen = new ApfGenerator(MIN_APF_VERSION);
-        gen.addLoadImmediate(Register.R0, 1234567890);
-        gen.addJumpIfR0Equals(1234567890, gen.DROP_LABEL);
-        assertDrop(gen);
-
-        // Test add.
-        gen = new ApfGenerator(MIN_APF_VERSION);
-        gen.addAdd(1234567890);
-        gen.addJumpIfR0Equals(1234567890, gen.DROP_LABEL);
-        assertDrop(gen);
-
-        // Test subtract.
-        gen = new ApfGenerator(MIN_APF_VERSION);
-        gen.addAdd(-1234567890);
-        gen.addJumpIfR0Equals(-1234567890, gen.DROP_LABEL);
-        assertDrop(gen);
-
-        // Test or.
-        gen = new ApfGenerator(MIN_APF_VERSION);
-        gen.addOr(1234567890);
-        gen.addJumpIfR0Equals(1234567890, gen.DROP_LABEL);
-        assertDrop(gen);
-
-        // Test and.
-        gen = new ApfGenerator(MIN_APF_VERSION);
-        gen.addLoadImmediate(Register.R0, 1234567890);
-        gen.addAnd(123456789);
-        gen.addJumpIfR0Equals(1234567890 & 123456789, gen.DROP_LABEL);
-        assertDrop(gen);
-
-        // Test left shift.
-        gen = new ApfGenerator(MIN_APF_VERSION);
-        gen.addLoadImmediate(Register.R0, 1234567890);
-        gen.addLeftShift(1);
-        gen.addJumpIfR0Equals(1234567890 << 1, gen.DROP_LABEL);
-        assertDrop(gen);
-
-        // Test right shift.
-        gen = new ApfGenerator(MIN_APF_VERSION);
-        gen.addLoadImmediate(Register.R0, 1234567890);
-        gen.addRightShift(1);
-        gen.addJumpIfR0Equals(1234567890 >> 1, gen.DROP_LABEL);
-        assertDrop(gen);
-
-        // Test multiply.
-        gen = new ApfGenerator(MIN_APF_VERSION);
-        gen.addLoadImmediate(Register.R0, 123456789);
-        gen.addMul(2);
-        gen.addJumpIfR0Equals(123456789 * 2, gen.DROP_LABEL);
-        assertDrop(gen);
-
-        // Test divide.
-        gen = new ApfGenerator(MIN_APF_VERSION);
-        gen.addLoadImmediate(Register.R0, 1234567890);
-        gen.addDiv(2);
-        gen.addJumpIfR0Equals(1234567890 / 2, gen.DROP_LABEL);
-        assertDrop(gen);
-
-        // Test divide by zero.
-        gen = new ApfGenerator(MIN_APF_VERSION);
-        gen.addDiv(0);
-        gen.addJump(gen.DROP_LABEL);
-        assertPass(gen);
-
-        // Test add.
-        gen = new ApfGenerator(MIN_APF_VERSION);
-        gen.addLoadImmediate(Register.R1, 1234567890);
-        gen.addAddR1();
-        gen.addJumpIfR0Equals(1234567890, gen.DROP_LABEL);
-        assertDrop(gen);
-
-        // Test subtract.
-        gen = new ApfGenerator(MIN_APF_VERSION);
-        gen.addLoadImmediate(Register.R1, -1234567890);
-        gen.addAddR1();
-        gen.addJumpIfR0Equals(-1234567890, gen.DROP_LABEL);
-        assertDrop(gen);
-
-        // Test or.
-        gen = new ApfGenerator(MIN_APF_VERSION);
-        gen.addLoadImmediate(Register.R1, 1234567890);
-        gen.addOrR1();
-        gen.addJumpIfR0Equals(1234567890, gen.DROP_LABEL);
-        assertDrop(gen);
-
-        // Test and.
-        gen = new ApfGenerator(MIN_APF_VERSION);
-        gen.addLoadImmediate(Register.R0, 1234567890);
-        gen.addLoadImmediate(Register.R1, 123456789);
-        gen.addAndR1();
-        gen.addJumpIfR0Equals(1234567890 & 123456789, gen.DROP_LABEL);
-        assertDrop(gen);
-
-        // Test left shift.
-        gen = new ApfGenerator(MIN_APF_VERSION);
-        gen.addLoadImmediate(Register.R0, 1234567890);
-        gen.addLoadImmediate(Register.R1, 1);
-        gen.addLeftShiftR1();
-        gen.addJumpIfR0Equals(1234567890 << 1, gen.DROP_LABEL);
-        assertDrop(gen);
-
-        // Test right shift.
-        gen = new ApfGenerator(MIN_APF_VERSION);
-        gen.addLoadImmediate(Register.R0, 1234567890);
-        gen.addLoadImmediate(Register.R1, -1);
-        gen.addLeftShiftR1();
-        gen.addJumpIfR0Equals(1234567890 >> 1, gen.DROP_LABEL);
-        assertDrop(gen);
-
-        // Test multiply.
-        gen = new ApfGenerator(MIN_APF_VERSION);
-        gen.addLoadImmediate(Register.R0, 123456789);
-        gen.addLoadImmediate(Register.R1, 2);
-        gen.addMulR1();
-        gen.addJumpIfR0Equals(123456789 * 2, gen.DROP_LABEL);
-        assertDrop(gen);
-
-        // Test divide.
-        gen = new ApfGenerator(MIN_APF_VERSION);
-        gen.addLoadImmediate(Register.R0, 1234567890);
-        gen.addLoadImmediate(Register.R1, 2);
-        gen.addDivR1();
-        gen.addJumpIfR0Equals(1234567890 / 2, gen.DROP_LABEL);
-        assertDrop(gen);
-
-        // Test divide by zero.
-        gen = new ApfGenerator(MIN_APF_VERSION);
-        gen.addDivR1();
-        gen.addJump(gen.DROP_LABEL);
-        assertPass(gen);
-
-        // Test byte load.
-        gen = new ApfGenerator(MIN_APF_VERSION);
-        gen.addLoad8(Register.R0, 1);
-        gen.addJumpIfR0Equals(45, gen.DROP_LABEL);
-        assertDrop(gen, new byte[]{123,45,0,0,0,0,0,0,0,0,0,0,0,0,0}, 0);
-
-        // Test out of bounds load.
-        gen = new ApfGenerator(MIN_APF_VERSION);
-        gen.addLoad8(Register.R0, 16);
-        gen.addJumpIfR0Equals(0, gen.DROP_LABEL);
-        assertPass(gen, new byte[]{123,45,0,0,0,0,0,0,0,0,0,0,0,0,0}, 0);
-
-        // Test half-word load.
-        gen = new ApfGenerator(MIN_APF_VERSION);
-        gen.addLoad16(Register.R0, 1);
-        gen.addJumpIfR0Equals((45 << 8) | 67, gen.DROP_LABEL);
-        assertDrop(gen, new byte[]{123,45,67,0,0,0,0,0,0,0,0,0,0,0,0}, 0);
-
-        // Test word load.
-        gen = new ApfGenerator(MIN_APF_VERSION);
-        gen.addLoad32(Register.R0, 1);
-        gen.addJumpIfR0Equals((45 << 24) | (67 << 16) | (89 << 8) | 12, gen.DROP_LABEL);
-        assertDrop(gen, new byte[]{123,45,67,89,12,0,0,0,0,0,0,0,0,0,0}, 0);
-
-        // Test byte indexed load.
-        gen = new ApfGenerator(MIN_APF_VERSION);
-        gen.addLoadImmediate(Register.R1, 1);
-        gen.addLoad8Indexed(Register.R0, 0);
-        gen.addJumpIfR0Equals(45, gen.DROP_LABEL);
-        assertDrop(gen, new byte[]{123,45,0,0,0,0,0,0,0,0,0,0,0,0,0}, 0);
-
-        // Test out of bounds indexed load.
-        gen = new ApfGenerator(MIN_APF_VERSION);
-        gen.addLoadImmediate(Register.R1, 8);
-        gen.addLoad8Indexed(Register.R0, 8);
-        gen.addJumpIfR0Equals(0, gen.DROP_LABEL);
-        assertPass(gen, new byte[]{123,45,0,0,0,0,0,0,0,0,0,0,0,0,0}, 0);
-
-        // Test half-word indexed load.
-        gen = new ApfGenerator(MIN_APF_VERSION);
-        gen.addLoadImmediate(Register.R1, 1);
-        gen.addLoad16Indexed(Register.R0, 0);
-        gen.addJumpIfR0Equals((45 << 8) | 67, gen.DROP_LABEL);
-        assertDrop(gen, new byte[]{123,45,67,0,0,0,0,0,0,0,0,0,0,0,0}, 0);
-
-        // Test word indexed load.
-        gen = new ApfGenerator(MIN_APF_VERSION);
-        gen.addLoadImmediate(Register.R1, 1);
-        gen.addLoad32Indexed(Register.R0, 0);
-        gen.addJumpIfR0Equals((45 << 24) | (67 << 16) | (89 << 8) | 12, gen.DROP_LABEL);
-        assertDrop(gen, new byte[]{123,45,67,89,12,0,0,0,0,0,0,0,0,0,0}, 0);
-
-        // Test jumping if greater than.
-        gen = new ApfGenerator(MIN_APF_VERSION);
-        gen.addJumpIfR0GreaterThan(0, gen.DROP_LABEL);
-        assertPass(gen);
-        gen = new ApfGenerator(MIN_APF_VERSION);
-        gen.addLoadImmediate(Register.R0, 1);
-        gen.addJumpIfR0GreaterThan(0, gen.DROP_LABEL);
-        assertDrop(gen);
-
-        // Test jumping if less than.
-        gen = new ApfGenerator(MIN_APF_VERSION);
-        gen.addJumpIfR0LessThan(0, gen.DROP_LABEL);
-        assertPass(gen);
-        gen = new ApfGenerator(MIN_APF_VERSION);
-        gen.addJumpIfR0LessThan(1, gen.DROP_LABEL);
-        assertDrop(gen);
-
-        // Test jumping if any bits set.
-        gen = new ApfGenerator(MIN_APF_VERSION);
-        gen.addJumpIfR0AnyBitsSet(3, gen.DROP_LABEL);
-        assertPass(gen);
-        gen = new ApfGenerator(MIN_APF_VERSION);
-        gen.addLoadImmediate(Register.R0, 1);
-        gen.addJumpIfR0AnyBitsSet(3, gen.DROP_LABEL);
-        assertDrop(gen);
-        gen = new ApfGenerator(MIN_APF_VERSION);
-        gen.addLoadImmediate(Register.R0, 3);
-        gen.addJumpIfR0AnyBitsSet(3, gen.DROP_LABEL);
-        assertDrop(gen);
-
-        // Test jumping if register greater than.
-        gen = new ApfGenerator(MIN_APF_VERSION);
-        gen.addJumpIfR0GreaterThanR1(gen.DROP_LABEL);
-        assertPass(gen);
-        gen = new ApfGenerator(MIN_APF_VERSION);
-        gen.addLoadImmediate(Register.R0, 2);
-        gen.addLoadImmediate(Register.R1, 1);
-        gen.addJumpIfR0GreaterThanR1(gen.DROP_LABEL);
-        assertDrop(gen);
-
-        // Test jumping if register less than.
-        gen = new ApfGenerator(MIN_APF_VERSION);
-        gen.addJumpIfR0LessThanR1(gen.DROP_LABEL);
-        assertPass(gen);
-        gen = new ApfGenerator(MIN_APF_VERSION);
-        gen.addLoadImmediate(Register.R1, 1);
-        gen.addJumpIfR0LessThanR1(gen.DROP_LABEL);
-        assertDrop(gen);
-
-        // Test jumping if any bits set in register.
-        gen = new ApfGenerator(MIN_APF_VERSION);
-        gen.addLoadImmediate(Register.R1, 3);
-        gen.addJumpIfR0AnyBitsSetR1(gen.DROP_LABEL);
-        assertPass(gen);
-        gen = new ApfGenerator(MIN_APF_VERSION);
-        gen.addLoadImmediate(Register.R1, 3);
-        gen.addLoadImmediate(Register.R0, 1);
-        gen.addJumpIfR0AnyBitsSetR1(gen.DROP_LABEL);
-        assertDrop(gen);
-        gen = new ApfGenerator(MIN_APF_VERSION);
-        gen.addLoadImmediate(Register.R1, 3);
-        gen.addLoadImmediate(Register.R0, 3);
-        gen.addJumpIfR0AnyBitsSetR1(gen.DROP_LABEL);
-        assertDrop(gen);
-
-        // Test load from memory.
-        gen = new ApfGenerator(MIN_APF_VERSION);
-        gen.addLoadFromMemory(Register.R0, 0);
-        gen.addJumpIfR0Equals(0, gen.DROP_LABEL);
-        assertDrop(gen);
-
-        // Test store to memory.
-        gen = new ApfGenerator(MIN_APF_VERSION);
-        gen.addLoadImmediate(Register.R1, 1234567890);
-        gen.addStoreToMemory(Register.R1, 12);
-        gen.addLoadFromMemory(Register.R0, 12);
-        gen.addJumpIfR0Equals(1234567890, gen.DROP_LABEL);
-        assertDrop(gen);
-
-        // Test filter age pre-filled memory.
-        gen = new ApfGenerator(MIN_APF_VERSION);
-        gen.addLoadFromMemory(Register.R0, gen.FILTER_AGE_MEMORY_SLOT);
-        gen.addJumpIfR0Equals(1234567890, gen.DROP_LABEL);
-        assertDrop(gen, new byte[MIN_PKT_SIZE], 1234567890);
-
-        // Test packet size pre-filled memory.
-        gen = new ApfGenerator(MIN_APF_VERSION);
-        gen.addLoadFromMemory(Register.R0, gen.PACKET_SIZE_MEMORY_SLOT);
-        gen.addJumpIfR0Equals(MIN_PKT_SIZE, gen.DROP_LABEL);
-        assertDrop(gen);
-
-        // Test IPv4 header size pre-filled memory.
-        gen = new ApfGenerator(MIN_APF_VERSION);
-        gen.addLoadFromMemory(Register.R0, gen.IPV4_HEADER_SIZE_MEMORY_SLOT);
-        gen.addJumpIfR0Equals(20, gen.DROP_LABEL);
-        assertDrop(gen, new byte[]{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0x45}, 0);
-
-        // Test not.
-        gen = new ApfGenerator(MIN_APF_VERSION);
-        gen.addLoadImmediate(Register.R0, 1234567890);
-        gen.addNot(Register.R0);
-        gen.addJumpIfR0Equals(~1234567890, gen.DROP_LABEL);
-        assertDrop(gen);
-
-        // Test negate.
-        gen = new ApfGenerator(MIN_APF_VERSION);
-        gen.addLoadImmediate(Register.R0, 1234567890);
-        gen.addNeg(Register.R0);
-        gen.addJumpIfR0Equals(-1234567890, gen.DROP_LABEL);
-        assertDrop(gen);
-
-        // Test move.
-        gen = new ApfGenerator(MIN_APF_VERSION);
-        gen.addLoadImmediate(Register.R1, 1234567890);
-        gen.addMove(Register.R0);
-        gen.addJumpIfR0Equals(1234567890, gen.DROP_LABEL);
-        assertDrop(gen);
-        gen = new ApfGenerator(MIN_APF_VERSION);
-        gen.addLoadImmediate(Register.R0, 1234567890);
-        gen.addMove(Register.R1);
-        gen.addJumpIfR0Equals(1234567890, gen.DROP_LABEL);
-        assertDrop(gen);
-
-        // Test swap.
-        gen = new ApfGenerator(MIN_APF_VERSION);
-        gen.addLoadImmediate(Register.R1, 1234567890);
-        gen.addSwap();
-        gen.addJumpIfR0Equals(1234567890, gen.DROP_LABEL);
-        assertDrop(gen);
-        gen = new ApfGenerator(MIN_APF_VERSION);
-        gen.addLoadImmediate(Register.R0, 1234567890);
-        gen.addSwap();
-        gen.addJumpIfR0Equals(0, gen.DROP_LABEL);
-        assertDrop(gen);
-
-        // Test jump if bytes not equal.
-        gen = new ApfGenerator(MIN_APF_VERSION);
-        gen.addLoadImmediate(Register.R0, 1);
-        gen.addJumpIfBytesNotEqual(Register.R0, new byte[]{123}, gen.DROP_LABEL);
-        program = gen.generate();
-        assertEquals(6, program.length);
-        assertEquals((13 << 3) | (1 << 1) | 0, program[0]);
-        assertEquals(1, program[1]);
-        assertEquals(((20 << 3) | (1 << 1) | 0) - 256, program[2]);
-        assertEquals(1, program[3]);
-        assertEquals(1, program[4]);
-        assertEquals(123, program[5]);
-        assertDrop(program, new byte[MIN_PKT_SIZE], 0);
-        gen = new ApfGenerator(MIN_APF_VERSION);
-        gen.addLoadImmediate(Register.R0, 1);
-        gen.addJumpIfBytesNotEqual(Register.R0, new byte[]{123}, gen.DROP_LABEL);
-        byte[] packet123 = {0,123,0,0,0,0,0,0,0,0,0,0,0,0,0};
-        assertPass(gen, packet123, 0);
-        gen = new ApfGenerator(MIN_APF_VERSION);
-        gen.addJumpIfBytesNotEqual(Register.R0, new byte[]{123}, gen.DROP_LABEL);
-        assertDrop(gen, packet123, 0);
-        gen = new ApfGenerator(MIN_APF_VERSION);
-        gen.addLoadImmediate(Register.R0, 1);
-        gen.addJumpIfBytesNotEqual(Register.R0, new byte[]{1,2,30,4,5}, gen.DROP_LABEL);
-        byte[] packet12345 = {0,1,2,3,4,5,0,0,0,0,0,0,0,0,0};
-        assertDrop(gen, packet12345, 0);
-        gen = new ApfGenerator(MIN_APF_VERSION);
-        gen.addLoadImmediate(Register.R0, 1);
-        gen.addJumpIfBytesNotEqual(Register.R0, new byte[]{1,2,3,4,5}, gen.DROP_LABEL);
-        assertPass(gen, packet12345, 0);
-    }
-
-    @Test(expected = ApfGenerator.IllegalInstructionException.class)
-    public void testApfGeneratorWantsV2OrGreater() throws Exception {
-        // The minimum supported APF version is 2.
-        new ApfGenerator(1);
-    }
-
-    @Test
-    public void testApfDataOpcodesWantApfV3() throws IllegalInstructionException, Exception {
-        ApfGenerator gen = new ApfGenerator(MIN_APF_VERSION);
-        try {
-            gen.addStoreData(Register.R0, 0);
-            fail();
-        } catch (IllegalInstructionException expected) {
-            /* pass */
-        }
-        try {
-            gen.addLoadData(Register.R0, 0);
-            fail();
-        } catch (IllegalInstructionException expected) {
-            /* pass */
-        }
-    }
-
-    /**
-     * Test that the generator emits immediates using the shortest possible encoding.
-     */
-    @Test
-    public void testImmediateEncoding() throws IllegalInstructionException {
-        ApfGenerator gen;
-
-        // 0-byte immediate: li R0, 0
-        gen = new ApfGenerator(4);
-        gen.addLoadImmediate(Register.R0, 0);
-        assertProgramEquals(new byte[]{LI_OP | SIZE0}, gen.generate());
-
-        // 1-byte immediate: li R0, 42
-        gen = new ApfGenerator(4);
-        gen.addLoadImmediate(Register.R0, 42);
-        assertProgramEquals(new byte[]{LI_OP | SIZE8, 42}, gen.generate());
-
-        // 2-byte immediate: li R1, 0x1234
-        gen = new ApfGenerator(4);
-        gen.addLoadImmediate(Register.R1, 0x1234);
-        assertProgramEquals(new byte[]{LI_OP | SIZE16 | R1, 0x12, 0x34}, gen.generate());
-
-        // 4-byte immediate: li R0, 0x12345678
-        gen = new ApfGenerator(3);
-        gen.addLoadImmediate(Register.R0, 0x12345678);
-        assertProgramEquals(
-                new byte[]{LI_OP | SIZE32, 0x12, 0x34, 0x56, 0x78},
-                gen.generate());
-    }
-
-    /**
-     * Test that the generator emits negative immediates using the shortest possible encoding.
-     */
-    @Test
-    public void testNegativeImmediateEncoding() throws IllegalInstructionException {
-        ApfGenerator gen;
-
-        // 1-byte negative immediate: li R0, -42
-        gen = new ApfGenerator(3);
-        gen.addLoadImmediate(Register.R0, -42);
-        assertProgramEquals(new byte[]{LI_OP | SIZE8, -42}, gen.generate());
-
-        // 2-byte negative immediate: li R1, -0x1122
-        gen = new ApfGenerator(3);
-        gen.addLoadImmediate(Register.R1, -0x1122);
-        assertProgramEquals(new byte[]{LI_OP | SIZE16 | R1, (byte)0xEE, (byte)0xDE},
-                gen.generate());
-
-        // 4-byte negative immediate: li R0, -0x11223344
-        gen = new ApfGenerator(3);
-        gen.addLoadImmediate(Register.R0, -0x11223344);
-        assertProgramEquals(
-                new byte[]{LI_OP | SIZE32, (byte)0xEE, (byte)0xDD, (byte)0xCC, (byte)0xBC},
-                gen.generate());
-    }
-
-    /**
-     * Test that the generator correctly emits positive and negative immediates for LDDW/STDW.
-     */
-    @Test
-    public void testLoadStoreDataEncoding() throws IllegalInstructionException {
-        ApfGenerator gen;
-
-        // Load data with no offset: lddw R0, [0 + r1]
-        gen = new ApfGenerator(3);
-        gen.addLoadData(Register.R0, 0);
-        assertProgramEquals(new byte[]{LDDW_OP | SIZE0}, gen.generate());
-
-        // Store data with 8bit negative offset: lddw r0, [-42 + r1]
-        gen = new ApfGenerator(3);
-        gen.addStoreData(Register.R0, -42);
-        assertProgramEquals(new byte[]{STDW_OP | SIZE8, -42}, gen.generate());
-
-        // Store data to R1 with 16bit negative offset: stdw r1, [-0x1122 + r0]
-        gen = new ApfGenerator(3);
-        gen.addStoreData(Register.R1, -0x1122);
-        assertProgramEquals(new byte[]{STDW_OP | SIZE16 | R1, (byte)0xEE, (byte)0xDE},
-                gen.generate());
-
-        // Load data to R1 with 32bit negative offset: lddw r1, [0xDEADBEEF + r0]
-        gen = new ApfGenerator(3);
-        gen.addLoadData(Register.R1, 0xDEADBEEF);
-        assertProgramEquals(
-                new byte[]{LDDW_OP | SIZE32 | R1, (byte)0xDE, (byte)0xAD, (byte)0xBE, (byte)0xEF},
-                gen.generate());
-    }
-
-    /**
-     * Test that the interpreter correctly executes STDW with a negative 8bit offset
-     */
-    @Test
-    public void testApfDataWrite() throws IllegalInstructionException, Exception {
-        byte[] packet = new byte[MIN_PKT_SIZE];
-        byte[] data = {0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15};
-        byte[] expected_data = data.clone();
-
-        // No memory access instructions: should leave the data segment untouched.
-        ApfGenerator gen = new ApfGenerator(3);
-        assertDataMemoryContents(PASS, gen.generate(), packet, data, expected_data);
-
-        // Expect value 0x87654321 to be stored starting from address -11 from the end of the
-        // data buffer, in big-endian order.
-        gen = new ApfGenerator(3);
-        gen.addLoadImmediate(Register.R0, 0x87654321);
-        gen.addLoadImmediate(Register.R1, -5);
-        gen.addStoreData(Register.R0, -6);  // -5 + -6 = -11 (offset +5 with data_len=16)
-        expected_data[5] = (byte)0x87;
-        expected_data[6] = (byte)0x65;
-        expected_data[7] = (byte)0x43;
-        expected_data[8] = (byte)0x21;
-        assertDataMemoryContents(PASS, gen.generate(), packet, data, expected_data);
-    }
-
-    /**
-     * Test that the interpreter correctly executes LDDW with a negative 16bit offset
-     */
-    @Test
-    public void testApfDataRead() throws IllegalInstructionException, Exception {
-        // Program that DROPs if address 10 (-6) contains 0x87654321.
-        ApfGenerator gen = new ApfGenerator(3);
-        gen.addLoadImmediate(Register.R1, 1000);
-        gen.addLoadData(Register.R0, -1006);  // 1000 + -1006 = -6 (offset +10 with data_len=16)
-        gen.addJumpIfR0Equals(0x87654321, gen.DROP_LABEL);
-        byte[] program = gen.generate();
-        byte[] packet = new byte[MIN_PKT_SIZE];
-
-        // Content is incorrect (last byte does not match) -> PASS
-        byte[] data = new byte[16];
-        data[10] = (byte)0x87;
-        data[11] = (byte)0x65;
-        data[12] = (byte)0x43;
-        data[13] = (byte)0x00;  // != 0x21
-        byte[] expected_data = data.clone();
-        assertDataMemoryContents(PASS, program, packet, data, expected_data);
-
-        // Fix the last byte -> conditional jump taken -> DROP
-        data[13] = (byte)0x21;
-        expected_data = data;
-        assertDataMemoryContents(DROP, program, packet, data, expected_data);
-    }
-
-    /**
-     * Test that the interpreter correctly executes LDDW followed by a STDW.
-     * To cover a few more edge cases, LDDW has a 0bit offset, while STDW has a positive 8bit
-     * offset.
-     */
-    @Test
-    public void testApfDataReadModifyWrite() throws IllegalInstructionException, Exception {
-        ApfGenerator gen = new ApfGenerator(3);
-        gen.addLoadImmediate(Register.R1, -22);
-        gen.addLoadData(Register.R0, 0);  // Load from address 32 -22 + 0 = 10
-        gen.addAdd(0x78453412);  // 87654321 + 78453412 = FFAA7733
-        gen.addStoreData(Register.R0, 4);  // Write back to address 32 -22 + 4 = 14
-
-        byte[] packet = new byte[MIN_PKT_SIZE];
-        byte[] data = new byte[32];
-        data[10] = (byte)0x87;
-        data[11] = (byte)0x65;
-        data[12] = (byte)0x43;
-        data[13] = (byte)0x21;
-        byte[] expected_data = data.clone();
-        expected_data[14] = (byte)0xFF;
-        expected_data[15] = (byte)0xAA;
-        expected_data[16] = (byte)0x77;
-        expected_data[17] = (byte)0x33;
-        assertDataMemoryContents(PASS, gen.generate(), packet, data, expected_data);
-    }
-
-    @Test
-    public void testApfDataBoundChecking() throws IllegalInstructionException, Exception {
-        byte[] packet = new byte[MIN_PKT_SIZE];
-        byte[] data = new byte[32];
-        byte[] expected_data = data;
-
-        // Program that DROPs unconditionally. This is our the baseline.
-        ApfGenerator gen = new ApfGenerator(3);
-        gen.addLoadImmediate(Register.R0, 3);
-        gen.addLoadData(Register.R1, 7);
-        gen.addJump(gen.DROP_LABEL);
-        assertDataMemoryContents(DROP, gen.generate(), packet, data, expected_data);
-
-        // Same program as before, but this time we're trying to load past the end of the data.
-        gen = new ApfGenerator(3);
-        gen.addLoadImmediate(Register.R0, 20);
-        gen.addLoadData(Register.R1, 15);  // 20 + 15 > 32
-        gen.addJump(gen.DROP_LABEL);  // Not reached.
-        assertDataMemoryContents(PASS, gen.generate(), packet, data, expected_data);
-
-        // Subtracting an immediate should work...
-        gen = new ApfGenerator(3);
-        gen.addLoadImmediate(Register.R0, 20);
-        gen.addLoadData(Register.R1, -4);
-        gen.addJump(gen.DROP_LABEL);
-        assertDataMemoryContents(DROP, gen.generate(), packet, data, expected_data);
-
-        // ...and underflowing simply wraps around to the end of the buffer...
-        gen = new ApfGenerator(3);
-        gen.addLoadImmediate(Register.R0, 20);
-        gen.addLoadData(Register.R1, -30);
-        gen.addJump(gen.DROP_LABEL);
-        assertDataMemoryContents(DROP, gen.generate(), packet, data, expected_data);
-
-        // ...but doesn't allow accesses before the start of the buffer
-        gen = new ApfGenerator(3);
-        gen.addLoadImmediate(Register.R0, 20);
-        gen.addLoadData(Register.R1, -1000);
-        gen.addJump(gen.DROP_LABEL);  // Not reached.
-        assertDataMemoryContents(PASS, gen.generate(), packet, data, expected_data);
-    }
-
-    /**
-     * Generate some BPF programs, translate them to APF, then run APF and BPF programs
-     * over packet traces and verify both programs filter out the same packets.
-     */
-    @Test
-    public void testApfAgainstBpf() throws Exception {
-        String[] tcpdump_filters = new String[]{ "udp", "tcp", "icmp", "icmp6", "udp port 53",
-                "arp", "dst 239.255.255.250", "arp or tcp or udp port 53", "net 192.168.1.0/24",
-                "arp or icmp6 or portrange 53-54", "portrange 53-54 or portrange 100-50000",
-                "tcp[tcpflags] & (tcp-ack|tcp-fin) != 0 and (ip[2:2] > 57 or icmp)" };
-        String pcap_filename = stageFile(R.raw.apf);
-        for (String tcpdump_filter : tcpdump_filters) {
-            byte[] apf_program = Bpf2Apf.convert(compileToBpf(tcpdump_filter));
-            assertTrue("Failed to match for filter: " + tcpdump_filter,
-                    compareBpfApf(tcpdump_filter, pcap_filename, apf_program));
-        }
-    }
-
-    /**
-     * Generate APF program, run pcap file though APF filter, then check all the packets in the file
-     * should be dropped.
-     */
-    @Test
-    public void testApfFilterPcapFile() throws Exception {
-        final byte[] MOCK_PCAP_IPV4_ADDR = {(byte) 172, 16, 7, (byte) 151};
-        String pcapFilename = stageFile(R.raw.apfPcap);
-        MockIpClientCallback ipClientCallback = new MockIpClientCallback();
-        LinkAddress link = new LinkAddress(InetAddress.getByAddress(MOCK_PCAP_IPV4_ADDR), 16);
-        LinkProperties lp = new LinkProperties();
-        lp.addLinkAddress(link);
-
-        ApfConfiguration config = getDefaultConfig();
-        ApfCapabilities MOCK_APF_PCAP_CAPABILITIES = new ApfCapabilities(4, 1700, ARPHRD_ETHER);
-        config.apfCapabilities = MOCK_APF_PCAP_CAPABILITIES;
-        config.multicastFilter = DROP_MULTICAST;
-        config.ieee802_3Filter = DROP_802_3_FRAMES;
-        TestApfFilter apfFilter = new TestApfFilter(mContext, config, ipClientCallback, mLog);
-        apfFilter.setLinkProperties(lp);
-        byte[] program = ipClientCallback.getApfProgram();
-        byte[] data = new byte[ApfFilter.Counter.totalSize()];
-        final boolean result;
-
-        result = dropsAllPackets(program, data, pcapFilename);
-        Log.i(TAG, "testApfFilterPcapFile(): Data counters: " + HexDump.toHexString(data, false));
-
-        assertTrue("Failed to drop all packets by filter. \nAPF counters:" +
-            HexDump.toHexString(data, false), result);
-    }
-
-    private class MockIpClientCallback extends IpClientCallbacksWrapper {
-        private final ConditionVariable mGotApfProgram = new ConditionVariable();
-        private byte[] mLastApfProgram;
-
-        MockIpClientCallback() {
-            super(mock(IIpClientCallbacks.class), mock(SharedLog.class));
-        }
-
-        @Override
-        public void installPacketFilter(byte[] filter) {
-            mLastApfProgram = filter;
-            mGotApfProgram.open();
-        }
-
-        public void resetApfProgramWait() {
-            mGotApfProgram.close();
-        }
-
-        public byte[] getApfProgram() {
-            assertTrue(mGotApfProgram.block(TIMEOUT_MS));
-            return mLastApfProgram;
-        }
-
-        public void assertNoProgramUpdate() {
-            assertFalse(mGotApfProgram.block(TIMEOUT_MS));
-        }
-    }
-
-    private static class TestApfFilter extends ApfFilter {
-        public static final byte[] MOCK_MAC_ADDR = {1,2,3,4,5,6};
-
-        private FileDescriptor mWriteSocket;
-        private final long mFixedTimeMs = SystemClock.elapsedRealtime();
-
-        public TestApfFilter(Context context, ApfConfiguration config,
-                IpClientCallbacksWrapper ipClientCallback, IpConnectivityLog log) throws Exception {
-            super(context, config, InterfaceParams.getByName("lo"), ipClientCallback, log);
-        }
-
-        // Pretend an RA packet has been received and show it to ApfFilter.
-        public void pretendPacketReceived(byte[] packet) throws IOException, ErrnoException {
-            // ApfFilter's ReceiveThread will be waiting to read this.
-            Os.write(mWriteSocket, packet, 0, packet.length);
-        }
-
-        @Override
-        protected long currentTimeSeconds() {
-            return mFixedTimeMs / DateUtils.SECOND_IN_MILLIS;
-        }
-
-        @Override
-        void maybeStartFilter() {
-            mHardwareAddress = MOCK_MAC_ADDR;
-            installNewProgramLocked();
-
-            // Create two sockets, "readSocket" and "mWriteSocket" and connect them together.
-            FileDescriptor readSocket = new FileDescriptor();
-            mWriteSocket = new FileDescriptor();
-            try {
-                Os.socketpair(AF_UNIX, SOCK_STREAM, 0, mWriteSocket, readSocket);
-            } catch (ErrnoException e) {
-                fail();
-                return;
-            }
-            // Now pass readSocket to ReceiveThread as if it was setup to read raw RAs.
-            // This allows us to pretend RA packets have been recieved via pretendPacketReceived().
-            mReceiveThread = new ReceiveThread(readSocket);
-            mReceiveThread.start();
-        }
-
-        @Override
-        public void shutdown() {
-            super.shutdown();
-            IoUtils.closeQuietly(mWriteSocket);
-        }
-    }
-
-    private static final int ETH_HEADER_LEN               = 14;
-    private static final int ETH_DEST_ADDR_OFFSET         = 0;
-    private static final int ETH_ETHERTYPE_OFFSET         = 12;
-    private static final byte[] ETH_BROADCAST_MAC_ADDRESS =
-            {(byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff };
-
-    private static final int IPV4_HEADER_LEN          = 20;
-    private static final int IPV4_VERSION_IHL_OFFSET  = ETH_HEADER_LEN + 0;
-    private static final int IPV4_TOTAL_LENGTH_OFFSET = ETH_HEADER_LEN + 2;
-    private static final int IPV4_PROTOCOL_OFFSET     = ETH_HEADER_LEN + 9;
-    private static final int IPV4_SRC_ADDR_OFFSET     = ETH_HEADER_LEN + 12;
-    private static final int IPV4_DEST_ADDR_OFFSET    = ETH_HEADER_LEN + 16;
-
-    private static final int IPV4_TCP_HEADER_LEN           = 20;
-    private static final int IPV4_TCP_HEADER_OFFSET        = ETH_HEADER_LEN + IPV4_HEADER_LEN;
-    private static final int IPV4_TCP_SRC_PORT_OFFSET      = IPV4_TCP_HEADER_OFFSET + 0;
-    private static final int IPV4_TCP_DEST_PORT_OFFSET     = IPV4_TCP_HEADER_OFFSET + 2;
-    private static final int IPV4_TCP_SEQ_NUM_OFFSET       = IPV4_TCP_HEADER_OFFSET + 4;
-    private static final int IPV4_TCP_ACK_NUM_OFFSET       = IPV4_TCP_HEADER_OFFSET + 8;
-    private static final int IPV4_TCP_HEADER_LENGTH_OFFSET = IPV4_TCP_HEADER_OFFSET + 12;
-    private static final int IPV4_TCP_HEADER_FLAG_OFFSET   = IPV4_TCP_HEADER_OFFSET + 13;
-
-    private static final int IPV4_UDP_HEADER_OFFSET    = ETH_HEADER_LEN + IPV4_HEADER_LEN;;
-    private static final int IPV4_UDP_SRC_PORT_OFFSET  = IPV4_UDP_HEADER_OFFSET + 0;
-    private static final int IPV4_UDP_DEST_PORT_OFFSET = IPV4_UDP_HEADER_OFFSET + 2;
-    private static final int IPV4_UDP_LENGTH_OFFSET    = IPV4_UDP_HEADER_OFFSET + 4;
-    private static final int IPV4_UDP_PAYLOAD_OFFSET   = IPV4_UDP_HEADER_OFFSET + 8;
-    private static final byte[] IPV4_BROADCAST_ADDRESS =
-            {(byte) 255, (byte) 255, (byte) 255, (byte) 255};
-
-    private static final int IPV6_HEADER_LEN             = 40;
-    private static final int IPV6_NEXT_HEADER_OFFSET     = ETH_HEADER_LEN + 6;
-    private static final int IPV6_SRC_ADDR_OFFSET        = ETH_HEADER_LEN + 8;
-    private static final int IPV6_DEST_ADDR_OFFSET       = ETH_HEADER_LEN + 24;
-    private static final int IPV6_TCP_HEADER_OFFSET      = ETH_HEADER_LEN + IPV6_HEADER_LEN;
-    private static final int IPV6_TCP_SRC_PORT_OFFSET    = IPV6_TCP_HEADER_OFFSET + 0;
-    private static final int IPV6_TCP_DEST_PORT_OFFSET   = IPV6_TCP_HEADER_OFFSET + 2;
-    private static final int IPV6_TCP_SEQ_NUM_OFFSET     = IPV6_TCP_HEADER_OFFSET + 4;
-    private static final int IPV6_TCP_ACK_NUM_OFFSET     = IPV6_TCP_HEADER_OFFSET + 8;
-    // The IPv6 all nodes address ff02::1
-    private static final byte[] IPV6_ALL_NODES_ADDRESS   =
-            { (byte) 0xff, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1 };
-    private static final byte[] IPV6_ALL_ROUTERS_ADDRESS =
-            { (byte) 0xff, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2 };
-
-    private static final int ICMP6_TYPE_OFFSET           = ETH_HEADER_LEN + IPV6_HEADER_LEN;
-    private static final int ICMP6_ROUTER_SOLICITATION   = 133;
-    private static final int ICMP6_ROUTER_ADVERTISEMENT  = 134;
-    private static final int ICMP6_NEIGHBOR_SOLICITATION = 135;
-    private static final int ICMP6_NEIGHBOR_ANNOUNCEMENT = 136;
-
-    private static final int ICMP6_RA_HEADER_LEN = 16;
-    private static final int ICMP6_RA_ROUTER_LIFETIME_OFFSET =
-            ETH_HEADER_LEN + IPV6_HEADER_LEN + 6;
-    private static final int ICMP6_RA_CHECKSUM_OFFSET =
-            ETH_HEADER_LEN + IPV6_HEADER_LEN + 2;
-    private static final int ICMP6_RA_OPTION_OFFSET =
-            ETH_HEADER_LEN + IPV6_HEADER_LEN + ICMP6_RA_HEADER_LEN;
-
-    private static final int ICMP6_PREFIX_OPTION_TYPE                      = 3;
-    private static final int ICMP6_PREFIX_OPTION_LEN                       = 32;
-    private static final int ICMP6_PREFIX_OPTION_VALID_LIFETIME_OFFSET     = 4;
-    private static final int ICMP6_PREFIX_OPTION_PREFERRED_LIFETIME_OFFSET = 8;
-
-    // From RFC6106: Recursive DNS Server option
-    private static final int ICMP6_RDNSS_OPTION_TYPE = 25;
-    // From RFC6106: DNS Search List option
-    private static final int ICMP6_DNSSL_OPTION_TYPE = 31;
-
-    // From RFC4191: Route Information option
-    private static final int ICMP6_ROUTE_INFO_OPTION_TYPE = 24;
-    // Above three options all have the same format:
-    private static final int ICMP6_4_BYTE_OPTION_LEN      = 8;
-    private static final int ICMP6_4_BYTE_LIFETIME_OFFSET = 4;
-    private static final int ICMP6_4_BYTE_LIFETIME_LEN    = 4;
-
-    private static final int UDP_HEADER_LEN              = 8;
-    private static final int UDP_DESTINATION_PORT_OFFSET = ETH_HEADER_LEN + 22;
-
-    private static final int DHCP_CLIENT_PORT       = 68;
-    private static final int DHCP_CLIENT_MAC_OFFSET = ETH_HEADER_LEN + UDP_HEADER_LEN + 48;
-
-    private static final int ARP_HEADER_OFFSET          = ETH_HEADER_LEN;
-    private static final byte[] ARP_IPV4_REQUEST_HEADER = {
-            0, 1, // Hardware type: Ethernet (1)
-            8, 0, // Protocol type: IP (0x0800)
-            6,    // Hardware size: 6
-            4,    // Protocol size: 4
-            0, 1  // Opcode: request (1)
-    };
-    private static final byte[] ARP_IPV4_REPLY_HEADER = {
-            0, 1, // Hardware type: Ethernet (1)
-            8, 0, // Protocol type: IP (0x0800)
-            6,    // Hardware size: 6
-            4,    // Protocol size: 4
-            0, 2  // Opcode: reply (2)
-    };
-    private static final int ARP_SOURCE_IP_ADDRESS_OFFSET = ARP_HEADER_OFFSET + 14;
-    private static final int ARP_TARGET_IP_ADDRESS_OFFSET = ARP_HEADER_OFFSET + 24;
-
-    private static final byte[] MOCK_IPV4_ADDR           = {10, 0, 0, 1};
-    private static final byte[] MOCK_BROADCAST_IPV4_ADDR = {10, 0, 31, (byte) 255}; // prefix = 19
-    private static final byte[] MOCK_MULTICAST_IPV4_ADDR = {(byte) 224, 0, 0, 1};
-    private static final byte[] ANOTHER_IPV4_ADDR        = {10, 0, 0, 2};
-    private static final byte[] IPV4_SOURCE_ADDR         = {10, 0, 0, 3};
-    private static final byte[] ANOTHER_IPV4_SOURCE_ADDR = {(byte) 192, 0, 2, 1};
-    private static final byte[] BUG_PROBE_SOURCE_ADDR1   = {0, 0, 1, 2};
-    private static final byte[] BUG_PROBE_SOURCE_ADDR2   = {3, 4, 0, 0};
-    private static final byte[] IPV4_ANY_HOST_ADDR       = {0, 0, 0, 0};
-
-    // Helper to initialize a default apfFilter.
-    private ApfFilter setupApfFilter(
-            IpClientCallbacksWrapper ipClientCallback, ApfConfiguration config) throws Exception {
-        LinkAddress link = new LinkAddress(InetAddress.getByAddress(MOCK_IPV4_ADDR), 19);
-        LinkProperties lp = new LinkProperties();
-        lp.addLinkAddress(link);
-        TestApfFilter apfFilter = new TestApfFilter(mContext, config, ipClientCallback, mLog);
-        apfFilter.setLinkProperties(lp);
-        return apfFilter;
-    }
-
-    @Test
-    public void testApfFilterIPv4() throws Exception {
-        MockIpClientCallback ipClientCallback = new MockIpClientCallback();
-        LinkAddress link = new LinkAddress(InetAddress.getByAddress(MOCK_IPV4_ADDR), 19);
-        LinkProperties lp = new LinkProperties();
-        lp.addLinkAddress(link);
-
-        ApfConfiguration config = getDefaultConfig();
-        config.multicastFilter = DROP_MULTICAST;
-        TestApfFilter apfFilter = new TestApfFilter(mContext, config, ipClientCallback, mLog);
-        apfFilter.setLinkProperties(lp);
-
-        byte[] program = ipClientCallback.getApfProgram();
-
-        // Verify empty packet of 100 zero bytes is passed
-        ByteBuffer packet = ByteBuffer.wrap(new byte[100]);
-        assertPass(program, packet.array());
-
-        // Verify unicast IPv4 packet is passed
-        put(packet, ETH_DEST_ADDR_OFFSET, TestApfFilter.MOCK_MAC_ADDR);
-        packet.putShort(ETH_ETHERTYPE_OFFSET, (short)ETH_P_IP);
-        put(packet, IPV4_DEST_ADDR_OFFSET, MOCK_IPV4_ADDR);
-        assertPass(program, packet.array());
-
-        // Verify L2 unicast to IPv4 broadcast addresses is dropped (b/30231088)
-        put(packet, IPV4_DEST_ADDR_OFFSET, IPV4_BROADCAST_ADDRESS);
-        assertDrop(program, packet.array());
-        put(packet, IPV4_DEST_ADDR_OFFSET, MOCK_BROADCAST_IPV4_ADDR);
-        assertDrop(program, packet.array());
-
-        // Verify multicast/broadcast IPv4, not DHCP to us, is dropped
-        put(packet, ETH_DEST_ADDR_OFFSET, ETH_BROADCAST_MAC_ADDRESS);
-        assertDrop(program, packet.array());
-        packet.put(IPV4_VERSION_IHL_OFFSET, (byte)0x45);
-        assertDrop(program, packet.array());
-        packet.put(IPV4_PROTOCOL_OFFSET, (byte)IPPROTO_UDP);
-        assertDrop(program, packet.array());
-        packet.putShort(UDP_DESTINATION_PORT_OFFSET, (short)DHCP_CLIENT_PORT);
-        assertDrop(program, packet.array());
-        put(packet, IPV4_DEST_ADDR_OFFSET, MOCK_MULTICAST_IPV4_ADDR);
-        assertDrop(program, packet.array());
-        put(packet, IPV4_DEST_ADDR_OFFSET, MOCK_BROADCAST_IPV4_ADDR);
-        assertDrop(program, packet.array());
-        put(packet, IPV4_DEST_ADDR_OFFSET, IPV4_BROADCAST_ADDRESS);
-        assertDrop(program, packet.array());
-
-        // Verify broadcast IPv4 DHCP to us is passed
-        put(packet, DHCP_CLIENT_MAC_OFFSET, TestApfFilter.MOCK_MAC_ADDR);
-        assertPass(program, packet.array());
-
-        // Verify unicast IPv4 DHCP to us is passed
-        put(packet, ETH_DEST_ADDR_OFFSET, TestApfFilter.MOCK_MAC_ADDR);
-        assertPass(program, packet.array());
-
-        apfFilter.shutdown();
-    }
-
-    @Test
-    public void testApfFilterIPv6() throws Exception {
-        MockIpClientCallback ipClientCallback = new MockIpClientCallback();
-        ApfConfiguration config = getDefaultConfig();
-        TestApfFilter apfFilter = new TestApfFilter(mContext, config, ipClientCallback, mLog);
-        byte[] program = ipClientCallback.getApfProgram();
-
-        // Verify empty IPv6 packet is passed
-        ByteBuffer packet = ByteBuffer.wrap(new byte[100]);
-        packet.putShort(ETH_ETHERTYPE_OFFSET, (short)ETH_P_IPV6);
-        assertPass(program, packet.array());
-
-        // Verify empty ICMPv6 packet is passed
-        packet.put(IPV6_NEXT_HEADER_OFFSET, (byte)IPPROTO_ICMPV6);
-        assertPass(program, packet.array());
-
-        // Verify empty ICMPv6 NA packet is passed
-        packet.put(ICMP6_TYPE_OFFSET, (byte)ICMP6_NEIGHBOR_ANNOUNCEMENT);
-        assertPass(program, packet.array());
-
-        // Verify ICMPv6 NA to ff02::1 is dropped
-        put(packet, IPV6_DEST_ADDR_OFFSET, IPV6_ALL_NODES_ADDRESS);
-        assertDrop(program, packet.array());
-
-        // Verify ICMPv6 RS to any is dropped
-        packet.put(ICMP6_TYPE_OFFSET, (byte)ICMP6_ROUTER_SOLICITATION);
-        assertDrop(program, packet.array());
-        put(packet, IPV6_DEST_ADDR_OFFSET, IPV6_ALL_ROUTERS_ADDRESS);
-        assertDrop(program, packet.array());
-
-        apfFilter.shutdown();
-    }
-
-    @Test
-    public void testApfFilterMulticast() throws Exception {
-        final byte[] unicastIpv4Addr   = {(byte)192,0,2,63};
-        final byte[] broadcastIpv4Addr = {(byte)192,0,2,(byte)255};
-        final byte[] multicastIpv4Addr = {(byte)224,0,0,1};
-        final byte[] multicastIpv6Addr = {(byte)0xff,2,0,0,0,0,0,0,0,0,0,0,0,0,0,(byte)0xfb};
-
-        MockIpClientCallback ipClientCallback = new MockIpClientCallback();
-        LinkAddress link = new LinkAddress(InetAddress.getByAddress(unicastIpv4Addr), 24);
-        LinkProperties lp = new LinkProperties();
-        lp.addLinkAddress(link);
-
-        ApfConfiguration config = getDefaultConfig();
-        config.ieee802_3Filter = DROP_802_3_FRAMES;
-        TestApfFilter apfFilter = new TestApfFilter(mContext, config, ipClientCallback, mLog);
-        apfFilter.setLinkProperties(lp);
-
-        byte[] program = ipClientCallback.getApfProgram();
-
-        // Construct IPv4 and IPv6 multicast packets.
-        ByteBuffer mcastv4packet = ByteBuffer.wrap(new byte[100]);
-        mcastv4packet.putShort(ETH_ETHERTYPE_OFFSET, (short)ETH_P_IP);
-        put(mcastv4packet, IPV4_DEST_ADDR_OFFSET, multicastIpv4Addr);
-
-        ByteBuffer mcastv6packet = ByteBuffer.wrap(new byte[100]);
-        mcastv6packet.putShort(ETH_ETHERTYPE_OFFSET, (short)ETH_P_IPV6);
-        mcastv6packet.put(IPV6_NEXT_HEADER_OFFSET, (byte)IPPROTO_UDP);
-        put(mcastv6packet, IPV6_DEST_ADDR_OFFSET, multicastIpv6Addr);
-
-        // Construct IPv4 broadcast packet.
-        ByteBuffer bcastv4packet1 = ByteBuffer.wrap(new byte[100]);
-        bcastv4packet1.put(ETH_BROADCAST_MAC_ADDRESS);
-        bcastv4packet1.putShort(ETH_ETHERTYPE_OFFSET, (short)ETH_P_IP);
-        put(bcastv4packet1, IPV4_DEST_ADDR_OFFSET, multicastIpv4Addr);
-
-        ByteBuffer bcastv4packet2 = ByteBuffer.wrap(new byte[100]);
-        bcastv4packet2.put(ETH_BROADCAST_MAC_ADDRESS);
-        bcastv4packet2.putShort(ETH_ETHERTYPE_OFFSET, (short)ETH_P_IP);
-        put(bcastv4packet2, IPV4_DEST_ADDR_OFFSET, IPV4_BROADCAST_ADDRESS);
-
-        // Construct IPv4 broadcast with L2 unicast address packet (b/30231088).
-        ByteBuffer bcastv4unicastl2packet = ByteBuffer.wrap(new byte[100]);
-        bcastv4unicastl2packet.put(TestApfFilter.MOCK_MAC_ADDR);
-        bcastv4unicastl2packet.putShort(ETH_ETHERTYPE_OFFSET, (short)ETH_P_IP);
-        put(bcastv4unicastl2packet, IPV4_DEST_ADDR_OFFSET, broadcastIpv4Addr);
-
-        // Verify initially disabled multicast filter is off
-        assertPass(program, mcastv4packet.array());
-        assertPass(program, mcastv6packet.array());
-        assertPass(program, bcastv4packet1.array());
-        assertPass(program, bcastv4packet2.array());
-        assertPass(program, bcastv4unicastl2packet.array());
-
-        // Turn on multicast filter and verify it works
-        ipClientCallback.resetApfProgramWait();
-        apfFilter.setMulticastFilter(true);
-        program = ipClientCallback.getApfProgram();
-        assertDrop(program, mcastv4packet.array());
-        assertDrop(program, mcastv6packet.array());
-        assertDrop(program, bcastv4packet1.array());
-        assertDrop(program, bcastv4packet2.array());
-        assertDrop(program, bcastv4unicastl2packet.array());
-
-        // Turn off multicast filter and verify it's off
-        ipClientCallback.resetApfProgramWait();
-        apfFilter.setMulticastFilter(false);
-        program = ipClientCallback.getApfProgram();
-        assertPass(program, mcastv4packet.array());
-        assertPass(program, mcastv6packet.array());
-        assertPass(program, bcastv4packet1.array());
-        assertPass(program, bcastv4packet2.array());
-        assertPass(program, bcastv4unicastl2packet.array());
-
-        // Verify it can be initialized to on
-        ipClientCallback.resetApfProgramWait();
-        apfFilter.shutdown();
-        config.multicastFilter = DROP_MULTICAST;
-        config.ieee802_3Filter = DROP_802_3_FRAMES;
-        apfFilter = new TestApfFilter(mContext, config, ipClientCallback, mLog);
-        apfFilter.setLinkProperties(lp);
-        program = ipClientCallback.getApfProgram();
-        assertDrop(program, mcastv4packet.array());
-        assertDrop(program, mcastv6packet.array());
-        assertDrop(program, bcastv4packet1.array());
-        assertDrop(program, bcastv4unicastl2packet.array());
-
-        // Verify that ICMPv6 multicast is not dropped.
-        mcastv6packet.put(IPV6_NEXT_HEADER_OFFSET, (byte)IPPROTO_ICMPV6);
-        assertPass(program, mcastv6packet.array());
-
-        apfFilter.shutdown();
-    }
-
-    @Test
-    public void testApfFilterMulticastPingWhileDozing() throws Exception {
-        MockIpClientCallback ipClientCallback = new MockIpClientCallback();
-        ApfFilter apfFilter = setupApfFilter(ipClientCallback, getDefaultConfig());
-
-        // Construct a multicast ICMPv6 ECHO request.
-        final byte[] multicastIpv6Addr = {(byte)0xff,2,0,0,0,0,0,0,0,0,0,0,0,0,0,(byte)0xfb};
-        ByteBuffer packet = ByteBuffer.wrap(new byte[100]);
-        packet.putShort(ETH_ETHERTYPE_OFFSET, (short)ETH_P_IPV6);
-        packet.put(IPV6_NEXT_HEADER_OFFSET, (byte)IPPROTO_ICMPV6);
-        packet.put(ICMP6_TYPE_OFFSET, (byte)ICMPV6_ECHO_REQUEST_TYPE);
-        put(packet, IPV6_DEST_ADDR_OFFSET, multicastIpv6Addr);
-
-        // Normally, we let multicast pings alone...
-        assertPass(ipClientCallback.getApfProgram(), packet.array());
-
-        // ...and even while dozing...
-        apfFilter.setDozeMode(true);
-        assertPass(ipClientCallback.getApfProgram(), packet.array());
-
-        // ...but when the multicast filter is also enabled, drop the multicast pings to save power.
-        apfFilter.setMulticastFilter(true);
-        assertDrop(ipClientCallback.getApfProgram(), packet.array());
-
-        // However, we should still let through all other ICMPv6 types.
-        ByteBuffer raPacket = ByteBuffer.wrap(packet.array().clone());
-        raPacket.put(ICMP6_TYPE_OFFSET, (byte) NetworkStackConstants.ICMPV6_ROUTER_ADVERTISEMENT);
-        assertPass(ipClientCallback.getApfProgram(), raPacket.array());
-
-        // Now wake up from doze mode to ensure that we no longer drop the packets.
-        // (The multicast filter is still enabled at this point).
-        apfFilter.setDozeMode(false);
-        assertPass(ipClientCallback.getApfProgram(), packet.array());
-
-        apfFilter.shutdown();
-    }
-
-    @Test
-    public void testApfFilter802_3() throws Exception {
-        MockIpClientCallback ipClientCallback = new MockIpClientCallback();
-        ApfConfiguration config = getDefaultConfig();
-        ApfFilter apfFilter = setupApfFilter(ipClientCallback, config);
-        byte[] program = ipClientCallback.getApfProgram();
-
-        // Verify empty packet of 100 zero bytes is passed
-        // Note that eth-type = 0 makes it an IEEE802.3 frame
-        ByteBuffer packet = ByteBuffer.wrap(new byte[100]);
-        assertPass(program, packet.array());
-
-        // Verify empty packet with IPv4 is passed
-        packet.putShort(ETH_ETHERTYPE_OFFSET, (short)ETH_P_IP);
-        assertPass(program, packet.array());
-
-        // Verify empty IPv6 packet is passed
-        packet.putShort(ETH_ETHERTYPE_OFFSET, (short)ETH_P_IPV6);
-        assertPass(program, packet.array());
-
-        // Now turn on the filter
-        ipClientCallback.resetApfProgramWait();
-        apfFilter.shutdown();
-        config.ieee802_3Filter = DROP_802_3_FRAMES;
-        apfFilter = setupApfFilter(ipClientCallback, config);
-        program = ipClientCallback.getApfProgram();
-
-        // Verify that IEEE802.3 frame is dropped
-        // In this case ethtype is used for payload length
-        packet.putShort(ETH_ETHERTYPE_OFFSET, (short)(100 - 14));
-        assertDrop(program, packet.array());
-
-        // Verify that IPv4 (as example of Ethernet II) frame will pass
-        packet.putShort(ETH_ETHERTYPE_OFFSET, (short)ETH_P_IP);
-        assertPass(program, packet.array());
-
-        // Verify that IPv6 (as example of Ethernet II) frame will pass
-        packet.putShort(ETH_ETHERTYPE_OFFSET, (short)ETH_P_IPV6);
-        assertPass(program, packet.array());
-
-        apfFilter.shutdown();
-    }
-
-    @Test
-    public void testApfFilterEthTypeBL() throws Exception {
-        final int[] emptyBlackList = {};
-        final int[] ipv4BlackList = {ETH_P_IP};
-        final int[] ipv4Ipv6BlackList = {ETH_P_IP, ETH_P_IPV6};
-
-        MockIpClientCallback ipClientCallback = new MockIpClientCallback();
-        ApfConfiguration config = getDefaultConfig();
-        ApfFilter apfFilter = setupApfFilter(ipClientCallback, config);
-        byte[] program = ipClientCallback.getApfProgram();
-
-        // Verify empty packet of 100 zero bytes is passed
-        // Note that eth-type = 0 makes it an IEEE802.3 frame
-        ByteBuffer packet = ByteBuffer.wrap(new byte[100]);
-        assertPass(program, packet.array());
-
-        // Verify empty packet with IPv4 is passed
-        packet.putShort(ETH_ETHERTYPE_OFFSET, (short)ETH_P_IP);
-        assertPass(program, packet.array());
-
-        // Verify empty IPv6 packet is passed
-        packet.putShort(ETH_ETHERTYPE_OFFSET, (short)ETH_P_IPV6);
-        assertPass(program, packet.array());
-
-        // Now add IPv4 to the black list
-        ipClientCallback.resetApfProgramWait();
-        apfFilter.shutdown();
-        config.ethTypeBlackList = ipv4BlackList;
-        apfFilter = setupApfFilter(ipClientCallback, config);
-        program = ipClientCallback.getApfProgram();
-
-        // Verify that IPv4 frame will be dropped
-        packet.putShort(ETH_ETHERTYPE_OFFSET, (short)ETH_P_IP);
-        assertDrop(program, packet.array());
-
-        // Verify that IPv6 frame will pass
-        packet.putShort(ETH_ETHERTYPE_OFFSET, (short)ETH_P_IPV6);
-        assertPass(program, packet.array());
-
-        // Now let us have both IPv4 and IPv6 in the black list
-        ipClientCallback.resetApfProgramWait();
-        apfFilter.shutdown();
-        config.ethTypeBlackList = ipv4Ipv6BlackList;
-        apfFilter = setupApfFilter(ipClientCallback, config);
-        program = ipClientCallback.getApfProgram();
-
-        // Verify that IPv4 frame will be dropped
-        packet.putShort(ETH_ETHERTYPE_OFFSET, (short)ETH_P_IP);
-        assertDrop(program, packet.array());
-
-        // Verify that IPv6 frame will be dropped
-        packet.putShort(ETH_ETHERTYPE_OFFSET, (short)ETH_P_IPV6);
-        assertDrop(program, packet.array());
-
-        apfFilter.shutdown();
-    }
-
-    private byte[] getProgram(MockIpClientCallback cb, ApfFilter filter, LinkProperties lp) {
-        cb.resetApfProgramWait();
-        filter.setLinkProperties(lp);
-        return cb.getApfProgram();
-    }
-
-    private void verifyArpFilter(byte[] program, int filterResult) {
-        // Verify ARP request packet
-        assertPass(program, arpRequestBroadcast(MOCK_IPV4_ADDR));
-        assertVerdict(filterResult, program, arpRequestBroadcast(ANOTHER_IPV4_ADDR));
-        assertDrop(program, arpRequestBroadcast(IPV4_ANY_HOST_ADDR));
-
-        // Verify ARP reply packets from different source ip
-        assertDrop(program, arpReply(IPV4_ANY_HOST_ADDR, IPV4_ANY_HOST_ADDR));
-        assertPass(program, arpReply(ANOTHER_IPV4_SOURCE_ADDR, IPV4_ANY_HOST_ADDR));
-        assertPass(program, arpReply(BUG_PROBE_SOURCE_ADDR1, IPV4_ANY_HOST_ADDR));
-        assertPass(program, arpReply(BUG_PROBE_SOURCE_ADDR2, IPV4_ANY_HOST_ADDR));
-
-        // Verify unicast ARP reply packet is always accepted.
-        assertPass(program, arpReply(IPV4_SOURCE_ADDR, MOCK_IPV4_ADDR));
-        assertPass(program, arpReply(IPV4_SOURCE_ADDR, ANOTHER_IPV4_ADDR));
-        assertPass(program, arpReply(IPV4_SOURCE_ADDR, IPV4_ANY_HOST_ADDR));
-
-        // Verify GARP reply packets are always filtered
-        assertDrop(program, garpReply());
-    }
-
-    @Test
-    public void testApfFilterArp() throws Exception {
-        MockIpClientCallback ipClientCallback = new MockIpClientCallback();
-        ApfConfiguration config = getDefaultConfig();
-        config.multicastFilter = DROP_MULTICAST;
-        config.ieee802_3Filter = DROP_802_3_FRAMES;
-        TestApfFilter apfFilter = new TestApfFilter(mContext, config, ipClientCallback, mLog);
-
-        // Verify initially ARP request filter is off, and GARP filter is on.
-        verifyArpFilter(ipClientCallback.getApfProgram(), PASS);
-
-        // Inform ApfFilter of our address and verify ARP filtering is on
-        LinkAddress linkAddress = new LinkAddress(InetAddress.getByAddress(MOCK_IPV4_ADDR), 24);
-        LinkProperties lp = new LinkProperties();
-        assertTrue(lp.addLinkAddress(linkAddress));
-        verifyArpFilter(getProgram(ipClientCallback, apfFilter, lp), DROP);
-
-        // Inform ApfFilter of loss of IP and verify ARP filtering is off
-        verifyArpFilter(getProgram(ipClientCallback, apfFilter, new LinkProperties()), PASS);
-
-        apfFilter.shutdown();
-    }
-
-    private static byte[] arpReply(byte[] sip, byte[] tip) {
-        ByteBuffer packet = ByteBuffer.wrap(new byte[100]);
-        packet.putShort(ETH_ETHERTYPE_OFFSET, (short)ETH_P_ARP);
-        put(packet, ARP_HEADER_OFFSET, ARP_IPV4_REPLY_HEADER);
-        put(packet, ARP_SOURCE_IP_ADDRESS_OFFSET, sip);
-        put(packet, ARP_TARGET_IP_ADDRESS_OFFSET, tip);
-        return packet.array();
-    }
-
-    private static byte[] arpRequestBroadcast(byte[] tip) {
-        ByteBuffer packet = ByteBuffer.wrap(new byte[100]);
-        packet.putShort(ETH_ETHERTYPE_OFFSET, (short)ETH_P_ARP);
-        put(packet, ETH_DEST_ADDR_OFFSET, ETH_BROADCAST_MAC_ADDRESS);
-        put(packet, ARP_HEADER_OFFSET, ARP_IPV4_REQUEST_HEADER);
-        put(packet, ARP_TARGET_IP_ADDRESS_OFFSET, tip);
-        return packet.array();
-    }
-
-    private static byte[] garpReply() {
-        ByteBuffer packet = ByteBuffer.wrap(new byte[100]);
-        packet.putShort(ETH_ETHERTYPE_OFFSET, (short)ETH_P_ARP);
-        put(packet, ETH_DEST_ADDR_OFFSET, ETH_BROADCAST_MAC_ADDRESS);
-        put(packet, ARP_HEADER_OFFSET, ARP_IPV4_REPLY_HEADER);
-        put(packet, ARP_TARGET_IP_ADDRESS_OFFSET, IPV4_ANY_HOST_ADDR);
-        return packet.array();
-    }
-
-    private static final byte[] IPV4_KEEPALIVE_SRC_ADDR = {10, 0, 0, 5};
-    private static final byte[] IPV4_KEEPALIVE_DST_ADDR = {10, 0, 0, 6};
-    private static final byte[] IPV4_ANOTHER_ADDR = {10, 0 , 0, 7};
-    private static final byte[] IPV6_KEEPALIVE_SRC_ADDR =
-            {(byte) 0x24, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, (byte) 0xfa, (byte) 0xf1};
-    private static final byte[] IPV6_KEEPALIVE_DST_ADDR =
-            {(byte) 0x24, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, (byte) 0xfa, (byte) 0xf2};
-    private static final byte[] IPV6_ANOTHER_ADDR =
-            {(byte) 0x24, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, (byte) 0xfa, (byte) 0xf5};
-
-    @Test
-    public void testApfFilterKeepaliveAck() throws Exception {
-        final MockIpClientCallback cb = new MockIpClientCallback();
-        final ApfConfiguration config = getDefaultConfig();
-        config.multicastFilter = DROP_MULTICAST;
-        config.ieee802_3Filter = DROP_802_3_FRAMES;
-        final TestApfFilter apfFilter = new TestApfFilter(mContext, config, cb, mLog);
-        byte[] program;
-        final int srcPort = 12345;
-        final int dstPort = 54321;
-        final int seqNum = 2123456789;
-        final int ackNum = 1234567890;
-        final int anotherSrcPort = 23456;
-        final int anotherDstPort = 65432;
-        final int anotherSeqNum = 2123456780;
-        final int anotherAckNum = 1123456789;
-        final int slot1 = 1;
-        final int slot2 = 2;
-        final int window = 14480;
-        final int windowScale = 4;
-
-        // src: 10.0.0.5, port: 12345
-        // dst: 10.0.0.6, port: 54321
-        InetAddress srcAddr = InetAddress.getByAddress(IPV4_KEEPALIVE_SRC_ADDR);
-        InetAddress dstAddr = InetAddress.getByAddress(IPV4_KEEPALIVE_DST_ADDR);
-
-        final TcpKeepalivePacketDataParcelable parcel = new TcpKeepalivePacketDataParcelable();
-        parcel.srcAddress = srcAddr.getAddress();
-        parcel.srcPort = srcPort;
-        parcel.dstAddress = dstAddr.getAddress();
-        parcel.dstPort = dstPort;
-        parcel.seq = seqNum;
-        parcel.ack = ackNum;
-
-        apfFilter.addTcpKeepalivePacketFilter(slot1, parcel);
-        program = cb.getApfProgram();
-
-        // Verify IPv4 keepalive ack packet is dropped
-        // src: 10.0.0.6, port: 54321
-        // dst: 10.0.0.5, port: 12345
-        assertDrop(program,
-                ipv4Packet(IPV4_KEEPALIVE_DST_ADDR, IPV4_KEEPALIVE_SRC_ADDR,
-                        dstPort, srcPort, ackNum, seqNum + 1, 0 /* dataLength */));
-        // Verify IPv4 non-keepalive ack packet from the same source address is passed
-        assertPass(program,
-                ipv4Packet(IPV4_KEEPALIVE_DST_ADDR, IPV4_KEEPALIVE_SRC_ADDR,
-                        dstPort, srcPort, ackNum + 100, seqNum, 0 /* dataLength */));
-        assertPass(program,
-                ipv4Packet(IPV4_KEEPALIVE_DST_ADDR, IPV4_KEEPALIVE_SRC_ADDR,
-                        dstPort, srcPort, ackNum, seqNum + 1, 10 /* dataLength */));
-        // Verify IPv4 packet from another address is passed
-        assertPass(program,
-                ipv4Packet(IPV4_ANOTHER_ADDR, IPV4_KEEPALIVE_SRC_ADDR, anotherSrcPort,
-                        anotherDstPort, anotherSeqNum, anotherAckNum, 0 /* dataLength */));
-
-        // Remove IPv4 keepalive filter
-        apfFilter.removeKeepalivePacketFilter(slot1);
-
-        try {
-            // src: 2404:0:0:0:0:0:faf1, port: 12345
-            // dst: 2404:0:0:0:0:0:faf2, port: 54321
-            srcAddr = InetAddress.getByAddress(IPV6_KEEPALIVE_SRC_ADDR);
-            dstAddr = InetAddress.getByAddress(IPV6_KEEPALIVE_DST_ADDR);
-
-            final TcpKeepalivePacketDataParcelable ipv6Parcel =
-                    new TcpKeepalivePacketDataParcelable();
-            ipv6Parcel.srcAddress = srcAddr.getAddress();
-            ipv6Parcel.srcPort = srcPort;
-            ipv6Parcel.dstAddress = dstAddr.getAddress();
-            ipv6Parcel.dstPort = dstPort;
-            ipv6Parcel.seq = seqNum;
-            ipv6Parcel.ack = ackNum;
-
-            apfFilter.addTcpKeepalivePacketFilter(slot1, ipv6Parcel);
-            program = cb.getApfProgram();
-
-            // Verify IPv6 keepalive ack packet is dropped
-            // src: 2404:0:0:0:0:0:faf2, port: 54321
-            // dst: 2404:0:0:0:0:0:faf1, port: 12345
-            assertDrop(program,
-                    ipv6Packet(IPV6_KEEPALIVE_DST_ADDR, IPV6_KEEPALIVE_SRC_ADDR,
-                            dstPort, srcPort, ackNum, seqNum + 1));
-            // Verify IPv6 non-keepalive ack packet from the same source address is passed
-            assertPass(program,
-                    ipv6Packet(IPV6_KEEPALIVE_DST_ADDR, IPV6_KEEPALIVE_SRC_ADDR,
-                            dstPort, srcPort, ackNum + 100, seqNum));
-            // Verify IPv6 packet from another address is passed
-            assertPass(program,
-                    ipv6Packet(IPV6_ANOTHER_ADDR, IPV6_KEEPALIVE_SRC_ADDR, anotherSrcPort,
-                            anotherDstPort, anotherSeqNum, anotherAckNum));
-
-            // Remove IPv6 keepalive filter
-            apfFilter.removeKeepalivePacketFilter(slot1);
-
-            // Verify multiple filters
-            apfFilter.addTcpKeepalivePacketFilter(slot1, parcel);
-            apfFilter.addTcpKeepalivePacketFilter(slot2, ipv6Parcel);
-            program = cb.getApfProgram();
-
-            // Verify IPv4 keepalive ack packet is dropped
-            // src: 10.0.0.6, port: 54321
-            // dst: 10.0.0.5, port: 12345
-            assertDrop(program,
-                    ipv4Packet(IPV4_KEEPALIVE_DST_ADDR, IPV4_KEEPALIVE_SRC_ADDR,
-                            dstPort, srcPort, ackNum, seqNum + 1, 0 /* dataLength */));
-            // Verify IPv4 non-keepalive ack packet from the same source address is passed
-            assertPass(program,
-                    ipv4Packet(IPV4_KEEPALIVE_DST_ADDR, IPV4_KEEPALIVE_SRC_ADDR,
-                            dstPort, srcPort, ackNum + 100, seqNum, 0 /* dataLength */));
-            // Verify IPv4 packet from another address is passed
-            assertPass(program,
-                    ipv4Packet(IPV4_ANOTHER_ADDR, IPV4_KEEPALIVE_SRC_ADDR, anotherSrcPort,
-                            anotherDstPort, anotherSeqNum, anotherAckNum, 0 /* dataLength */));
-
-            // Verify IPv6 keepalive ack packet is dropped
-            // src: 2404:0:0:0:0:0:faf2, port: 54321
-            // dst: 2404:0:0:0:0:0:faf1, port: 12345
-            assertDrop(program,
-                    ipv6Packet(IPV6_KEEPALIVE_DST_ADDR, IPV6_KEEPALIVE_SRC_ADDR,
-                            dstPort, srcPort, ackNum, seqNum + 1));
-            // Verify IPv6 non-keepalive ack packet from the same source address is passed
-            assertPass(program,
-                    ipv6Packet(IPV6_KEEPALIVE_DST_ADDR, IPV6_KEEPALIVE_SRC_ADDR,
-                            dstPort, srcPort, ackNum + 100, seqNum));
-            // Verify IPv6 packet from another address is passed
-            assertPass(program,
-                    ipv6Packet(IPV6_ANOTHER_ADDR, IPV6_KEEPALIVE_SRC_ADDR, anotherSrcPort,
-                            anotherDstPort, anotherSeqNum, anotherAckNum));
-
-            // Remove keepalive filters
-            apfFilter.removeKeepalivePacketFilter(slot1);
-            apfFilter.removeKeepalivePacketFilter(slot2);
-        } catch (UnsupportedOperationException e) {
-            // TODO: support V6 packets
-        }
-
-        program = cb.getApfProgram();
-
-        // Verify IPv4, IPv6 packets are passed
-        assertPass(program,
-                ipv4Packet(IPV4_KEEPALIVE_DST_ADDR, IPV4_KEEPALIVE_SRC_ADDR,
-                        dstPort, srcPort, ackNum, seqNum + 1, 0 /* dataLength */));
-        assertPass(program,
-                ipv6Packet(IPV6_KEEPALIVE_DST_ADDR, IPV6_KEEPALIVE_SRC_ADDR,
-                        dstPort, srcPort, ackNum, seqNum + 1));
-        assertPass(program,
-                ipv4Packet(IPV4_ANOTHER_ADDR, IPV4_KEEPALIVE_SRC_ADDR, srcPort,
-                        dstPort, anotherSeqNum, anotherAckNum, 0 /* dataLength */));
-        assertPass(program,
-                ipv6Packet(IPV6_ANOTHER_ADDR, IPV6_KEEPALIVE_SRC_ADDR, srcPort,
-                        dstPort, anotherSeqNum, anotherAckNum));
-
-        apfFilter.shutdown();
-    }
-
-    private static byte[] ipv4Packet(byte[] sip, byte[] dip, int sport,
-            int dport, int seq, int ack, int dataLength) {
-        final int totalLength = dataLength + IPV4_HEADER_LEN + IPV4_TCP_HEADER_LEN;
-
-        ByteBuffer packet = ByteBuffer.wrap(new byte[totalLength + ETH_HEADER_LEN]);
-
-        // ether type
-        packet.putShort(ETH_ETHERTYPE_OFFSET, (short) ETH_P_IP);
-
-        // IPv4 header
-        packet.put(IPV4_VERSION_IHL_OFFSET, (byte) 0x45);
-        packet.putShort(IPV4_TOTAL_LENGTH_OFFSET, (short) totalLength);
-        packet.put(IPV4_PROTOCOL_OFFSET, (byte) IPPROTO_TCP);
-        put(packet, IPV4_SRC_ADDR_OFFSET, sip);
-        put(packet, IPV4_DEST_ADDR_OFFSET, dip);
-        packet.putShort(IPV4_TCP_SRC_PORT_OFFSET, (short) sport);
-        packet.putShort(IPV4_TCP_DEST_PORT_OFFSET, (short) dport);
-        packet.putInt(IPV4_TCP_SEQ_NUM_OFFSET, seq);
-        packet.putInt(IPV4_TCP_ACK_NUM_OFFSET, ack);
-
-        // TCP header length 5(20 bytes), reserved 3 bits, NS=0
-        packet.put(IPV4_TCP_HEADER_LENGTH_OFFSET, (byte) 0x50);
-        // TCP flags: ACK set
-        packet.put(IPV4_TCP_HEADER_FLAG_OFFSET, (byte) 0x10);
-        return packet.array();
-    }
-
-    private static byte[] ipv6Packet(byte[] sip, byte[] tip, int sport,
-            int dport, int seq, int ack) {
-        ByteBuffer packet = ByteBuffer.wrap(new byte[100]);
-        packet.putShort(ETH_ETHERTYPE_OFFSET, (short) ETH_P_IPV6);
-        put(packet, IPV6_SRC_ADDR_OFFSET, sip);
-        put(packet, IPV6_DEST_ADDR_OFFSET, tip);
-        packet.putShort(IPV6_TCP_SRC_PORT_OFFSET, (short) sport);
-        packet.putShort(IPV6_TCP_DEST_PORT_OFFSET, (short) dport);
-        packet.putInt(IPV6_TCP_SEQ_NUM_OFFSET, seq);
-        packet.putInt(IPV6_TCP_ACK_NUM_OFFSET, ack);
-        return packet.array();
-    }
-
-    @Test
-    public void testApfFilterNattKeepalivePacket() throws Exception {
-        final MockIpClientCallback cb = new MockIpClientCallback();
-        final ApfConfiguration config = getDefaultConfig();
-        config.multicastFilter = DROP_MULTICAST;
-        config.ieee802_3Filter = DROP_802_3_FRAMES;
-        final TestApfFilter apfFilter = new TestApfFilter(mContext, config, cb, mLog);
-        byte[] program;
-        final int srcPort = 1024;
-        final int dstPort = 4500;
-        final int slot1 = 1;
-        // NAT-T keepalive
-        final byte[] kaPayload = {(byte) 0xff};
-        final byte[] nonKaPayload = {(byte) 0xfe};
-
-        // src: 10.0.0.5, port: 1024
-        // dst: 10.0.0.6, port: 4500
-        InetAddress srcAddr = InetAddress.getByAddress(IPV4_KEEPALIVE_SRC_ADDR);
-        InetAddress dstAddr = InetAddress.getByAddress(IPV4_KEEPALIVE_DST_ADDR);
-
-        final NattKeepalivePacketDataParcelable parcel = new NattKeepalivePacketDataParcelable();
-        parcel.srcAddress = srcAddr.getAddress();
-        parcel.srcPort = srcPort;
-        parcel.dstAddress = dstAddr.getAddress();
-        parcel.dstPort = dstPort;
-
-        apfFilter.addNattKeepalivePacketFilter(slot1, parcel);
-        program = cb.getApfProgram();
-
-        // Verify IPv4 keepalive packet is dropped
-        // src: 10.0.0.6, port: 4500
-        // dst: 10.0.0.5, port: 1024
-        byte[] pkt = ipv4UdpPacket(IPV4_KEEPALIVE_DST_ADDR,
-                    IPV4_KEEPALIVE_SRC_ADDR, dstPort, srcPort, 1 /* dataLength */);
-        System.arraycopy(kaPayload, 0, pkt, IPV4_UDP_PAYLOAD_OFFSET, kaPayload.length);
-        assertDrop(program, pkt);
-
-        // Verify a packet with payload length 1 byte but it is not 0xff will pass the filter.
-        System.arraycopy(nonKaPayload, 0, pkt, IPV4_UDP_PAYLOAD_OFFSET, nonKaPayload.length);
-        assertPass(program, pkt);
-
-        // Verify IPv4 non-keepalive response packet from the same source address is passed
-        assertPass(program,
-                ipv4UdpPacket(IPV4_KEEPALIVE_DST_ADDR, IPV4_KEEPALIVE_SRC_ADDR,
-                        dstPort, srcPort, 10 /* dataLength */));
-
-        // Verify IPv4 non-keepalive response packet from other source address is passed
-        assertPass(program,
-                ipv4UdpPacket(IPV4_ANOTHER_ADDR, IPV4_KEEPALIVE_SRC_ADDR,
-                        dstPort, srcPort, 10 /* dataLength */));
-
-        apfFilter.removeKeepalivePacketFilter(slot1);
-        apfFilter.shutdown();
-    }
-
-    private static byte[] ipv4UdpPacket(byte[] sip, byte[] dip, int sport,
-            int dport, int dataLength) {
-        final int totalLength = dataLength + IPV4_HEADER_LEN + UDP_HEADER_LEN;
-        final int udpLength = UDP_HEADER_LEN + dataLength;
-        ByteBuffer packet = ByteBuffer.wrap(new byte[totalLength + ETH_HEADER_LEN]);
-
-        // ether type
-        packet.putShort(ETH_ETHERTYPE_OFFSET, (short) ETH_P_IP);
-
-        // IPv4 header
-        packet.put(IPV4_VERSION_IHL_OFFSET, (byte) 0x45);
-        packet.putShort(IPV4_TOTAL_LENGTH_OFFSET, (short) totalLength);
-        packet.put(IPV4_PROTOCOL_OFFSET, (byte) IPPROTO_UDP);
-        put(packet, IPV4_SRC_ADDR_OFFSET, sip);
-        put(packet, IPV4_DEST_ADDR_OFFSET, dip);
-        packet.putShort(IPV4_UDP_SRC_PORT_OFFSET, (short) sport);
-        packet.putShort(IPV4_UDP_DEST_PORT_OFFSET, (short) dport);
-        packet.putShort(IPV4_UDP_LENGTH_OFFSET, (short) udpLength);
-
-        return packet.array();
-    }
-
-    // Verify that the last program pushed to the IpClient.Callback properly filters the
-    // given packet for the given lifetime.
-    private void verifyRaLifetime(byte[] program, ByteBuffer packet, int lifetime) {
-        final int FRACTION_OF_LIFETIME = 6;
-        final int ageLimit = lifetime / FRACTION_OF_LIFETIME;
-
-        // Verify new program should drop RA for 1/6th its lifetime and pass afterwards.
-        assertDrop(program, packet.array());
-        assertDrop(program, packet.array(), ageLimit);
-        assertPass(program, packet.array(), ageLimit + 1);
-        assertPass(program, packet.array(), lifetime);
-        // Verify RA checksum is ignored
-        final short originalChecksum = packet.getShort(ICMP6_RA_CHECKSUM_OFFSET);
-        packet.putShort(ICMP6_RA_CHECKSUM_OFFSET, (short)12345);
-        assertDrop(program, packet.array());
-        packet.putShort(ICMP6_RA_CHECKSUM_OFFSET, (short)-12345);
-        assertDrop(program, packet.array());
-        packet.putShort(ICMP6_RA_CHECKSUM_OFFSET, originalChecksum);
-
-        // Verify other changes to RA make it not match filter
-        final byte originalFirstByte = packet.get(0);
-        packet.put(0, (byte)-1);
-        assertPass(program, packet.array());
-        packet.put(0, (byte)0);
-        assertDrop(program, packet.array());
-        packet.put(0, originalFirstByte);
-    }
-
-    // Test that when ApfFilter is shown the given packet, it generates a program to filter it
-    // for the given lifetime.
-    private void verifyRaLifetime(TestApfFilter apfFilter, MockIpClientCallback ipClientCallback,
-            ByteBuffer packet, int lifetime) throws IOException, ErrnoException {
-        // Verify new program generated if ApfFilter witnesses RA
-        ipClientCallback.resetApfProgramWait();
-        apfFilter.pretendPacketReceived(packet.array());
-        byte[] program = ipClientCallback.getApfProgram();
-        verifyRaLifetime(program, packet, lifetime);
-    }
-
-    private void verifyRaEvent(RaEvent expected) {
-        ArgumentCaptor<IpConnectivityLog.Event> captor =
-                ArgumentCaptor.forClass(IpConnectivityLog.Event.class);
-        verify(mLog, atLeastOnce()).log(captor.capture());
-        RaEvent got = lastRaEvent(captor.getAllValues());
-        if (!raEventEquals(expected, got)) {
-            assertEquals(expected, got);  // fail for printing an assertion error message.
-        }
-    }
-
-    private RaEvent lastRaEvent(List<IpConnectivityLog.Event> events) {
-        RaEvent got = null;
-        for (Parcelable ev : events) {
-            if (ev instanceof RaEvent) {
-                got = (RaEvent) ev;
-            }
-        }
-        return got;
-    }
-
-    private boolean raEventEquals(RaEvent ev1, RaEvent ev2) {
-        return (ev1 != null) && (ev2 != null)
-                && (ev1.routerLifetime == ev2.routerLifetime)
-                && (ev1.prefixValidLifetime == ev2.prefixValidLifetime)
-                && (ev1.prefixPreferredLifetime == ev2.prefixPreferredLifetime)
-                && (ev1.routeInfoLifetime == ev2.routeInfoLifetime)
-                && (ev1.rdnssLifetime == ev2.rdnssLifetime)
-                && (ev1.dnsslLifetime == ev2.dnsslLifetime);
-    }
-
-    private void assertInvalidRa(TestApfFilter apfFilter, MockIpClientCallback ipClientCallback,
-            ByteBuffer packet) throws IOException, ErrnoException {
-        ipClientCallback.resetApfProgramWait();
-        apfFilter.pretendPacketReceived(packet.array());
-        ipClientCallback.assertNoProgramUpdate();
-    }
-
-    @Test
-    public void testApfFilterRa() throws Exception {
-        MockIpClientCallback ipClientCallback = new MockIpClientCallback();
-        ApfConfiguration config = getDefaultConfig();
-        config.multicastFilter = DROP_MULTICAST;
-        config.ieee802_3Filter = DROP_802_3_FRAMES;
-        TestApfFilter apfFilter = new TestApfFilter(mContext, config, ipClientCallback, mLog);
-        byte[] program = ipClientCallback.getApfProgram();
-
-        final int ROUTER_LIFETIME = 1000;
-        final int PREFIX_VALID_LIFETIME = 200;
-        final int PREFIX_PREFERRED_LIFETIME = 100;
-        final int RDNSS_LIFETIME  = 300;
-        final int ROUTE_LIFETIME  = 400;
-        // Note that lifetime of 2000 will be ignored in favor of shorter route lifetime of 1000.
-        final int DNSSL_LIFETIME  = 2000;
-        final int VERSION_TRAFFIC_CLASS_FLOW_LABEL_OFFSET = ETH_HEADER_LEN;
-        // IPv6, traffic class = 0, flow label = 0x12345
-        final int VERSION_TRAFFIC_CLASS_FLOW_LABEL = 0x60012345;
-
-        // Verify RA is passed the first time
-        ByteBuffer basePacket = ByteBuffer.wrap(new byte[ICMP6_RA_OPTION_OFFSET]);
-        basePacket.putShort(ETH_ETHERTYPE_OFFSET, (short)ETH_P_IPV6);
-        basePacket.putInt(VERSION_TRAFFIC_CLASS_FLOW_LABEL_OFFSET,
-                VERSION_TRAFFIC_CLASS_FLOW_LABEL);
-        basePacket.put(IPV6_NEXT_HEADER_OFFSET, (byte)IPPROTO_ICMPV6);
-        basePacket.put(ICMP6_TYPE_OFFSET, (byte)ICMP6_ROUTER_ADVERTISEMENT);
-        basePacket.putShort(ICMP6_RA_ROUTER_LIFETIME_OFFSET, (short)ROUTER_LIFETIME);
-        basePacket.position(IPV6_DEST_ADDR_OFFSET);
-        basePacket.put(IPV6_ALL_NODES_ADDRESS);
-        assertPass(program, basePacket.array());
-
-        verifyRaLifetime(apfFilter, ipClientCallback, basePacket, ROUTER_LIFETIME);
-        verifyRaEvent(new RaEvent(ROUTER_LIFETIME, -1, -1, -1, -1, -1));
-
-        ByteBuffer newFlowLabelPacket = ByteBuffer.wrap(new byte[ICMP6_RA_OPTION_OFFSET]);
-        basePacket.clear();
-        newFlowLabelPacket.put(basePacket);
-        // Check that changes are ignored in every byte of the flow label.
-        newFlowLabelPacket.putInt(VERSION_TRAFFIC_CLASS_FLOW_LABEL_OFFSET,
-                VERSION_TRAFFIC_CLASS_FLOW_LABEL + 0x11111);
-
-        // Ensure zero-length options cause the packet to be silently skipped.
-        // Do this before we test other packets. http://b/29586253
-        ByteBuffer zeroLengthOptionPacket = ByteBuffer.wrap(
-                new byte[ICMP6_RA_OPTION_OFFSET + ICMP6_4_BYTE_OPTION_LEN]);
-        basePacket.clear();
-        zeroLengthOptionPacket.put(basePacket);
-        zeroLengthOptionPacket.put((byte)ICMP6_PREFIX_OPTION_TYPE);
-        zeroLengthOptionPacket.put((byte)0);
-        assertInvalidRa(apfFilter, ipClientCallback, zeroLengthOptionPacket);
-
-        // Generate several RAs with different options and lifetimes, and verify when
-        // ApfFilter is shown these packets, it generates programs to filter them for the
-        // appropriate lifetime.
-        ByteBuffer prefixOptionPacket = ByteBuffer.wrap(
-                new byte[ICMP6_RA_OPTION_OFFSET + ICMP6_PREFIX_OPTION_LEN]);
-        basePacket.clear();
-        prefixOptionPacket.put(basePacket);
-        prefixOptionPacket.put((byte)ICMP6_PREFIX_OPTION_TYPE);
-        prefixOptionPacket.put((byte)(ICMP6_PREFIX_OPTION_LEN / 8));
-        prefixOptionPacket.putInt(
-                ICMP6_RA_OPTION_OFFSET + ICMP6_PREFIX_OPTION_PREFERRED_LIFETIME_OFFSET,
-                PREFIX_PREFERRED_LIFETIME);
-        prefixOptionPacket.putInt(
-                ICMP6_RA_OPTION_OFFSET + ICMP6_PREFIX_OPTION_VALID_LIFETIME_OFFSET,
-                PREFIX_VALID_LIFETIME);
-        verifyRaLifetime(
-                apfFilter, ipClientCallback, prefixOptionPacket, PREFIX_PREFERRED_LIFETIME);
-        verifyRaEvent(new RaEvent(
-                ROUTER_LIFETIME, PREFIX_VALID_LIFETIME, PREFIX_PREFERRED_LIFETIME, -1, -1, -1));
-
-        ByteBuffer rdnssOptionPacket = ByteBuffer.wrap(
-                new byte[ICMP6_RA_OPTION_OFFSET + ICMP6_4_BYTE_OPTION_LEN]);
-        basePacket.clear();
-        rdnssOptionPacket.put(basePacket);
-        rdnssOptionPacket.put((byte)ICMP6_RDNSS_OPTION_TYPE);
-        rdnssOptionPacket.put((byte)(ICMP6_4_BYTE_OPTION_LEN / 8));
-        rdnssOptionPacket.putInt(
-                ICMP6_RA_OPTION_OFFSET + ICMP6_4_BYTE_LIFETIME_OFFSET, RDNSS_LIFETIME);
-        verifyRaLifetime(apfFilter, ipClientCallback, rdnssOptionPacket, RDNSS_LIFETIME);
-        verifyRaEvent(new RaEvent(ROUTER_LIFETIME, -1, -1, -1, RDNSS_LIFETIME, -1));
-
-        ByteBuffer routeInfoOptionPacket = ByteBuffer.wrap(
-                new byte[ICMP6_RA_OPTION_OFFSET + ICMP6_4_BYTE_OPTION_LEN]);
-        basePacket.clear();
-        routeInfoOptionPacket.put(basePacket);
-        routeInfoOptionPacket.put((byte)ICMP6_ROUTE_INFO_OPTION_TYPE);
-        routeInfoOptionPacket.put((byte)(ICMP6_4_BYTE_OPTION_LEN / 8));
-        routeInfoOptionPacket.putInt(
-                ICMP6_RA_OPTION_OFFSET + ICMP6_4_BYTE_LIFETIME_OFFSET, ROUTE_LIFETIME);
-        verifyRaLifetime(apfFilter, ipClientCallback, routeInfoOptionPacket, ROUTE_LIFETIME);
-        verifyRaEvent(new RaEvent(ROUTER_LIFETIME, -1, -1, ROUTE_LIFETIME, -1, -1));
-
-        ByteBuffer dnsslOptionPacket = ByteBuffer.wrap(
-                new byte[ICMP6_RA_OPTION_OFFSET + ICMP6_4_BYTE_OPTION_LEN]);
-        basePacket.clear();
-        dnsslOptionPacket.put(basePacket);
-        dnsslOptionPacket.put((byte)ICMP6_DNSSL_OPTION_TYPE);
-        dnsslOptionPacket.put((byte)(ICMP6_4_BYTE_OPTION_LEN / 8));
-        dnsslOptionPacket.putInt(
-                ICMP6_RA_OPTION_OFFSET + ICMP6_4_BYTE_LIFETIME_OFFSET, DNSSL_LIFETIME);
-        verifyRaLifetime(apfFilter, ipClientCallback, dnsslOptionPacket, ROUTER_LIFETIME);
-        verifyRaEvent(new RaEvent(ROUTER_LIFETIME, -1, -1, -1, -1, DNSSL_LIFETIME));
-
-        // Verify that current program filters all five RAs:
-        program = ipClientCallback.getApfProgram();
-        verifyRaLifetime(program, basePacket, ROUTER_LIFETIME);
-        verifyRaLifetime(program, newFlowLabelPacket, ROUTER_LIFETIME);
-        verifyRaLifetime(program, prefixOptionPacket, PREFIX_PREFERRED_LIFETIME);
-        verifyRaLifetime(program, rdnssOptionPacket, RDNSS_LIFETIME);
-        verifyRaLifetime(program, routeInfoOptionPacket, ROUTE_LIFETIME);
-        verifyRaLifetime(program, dnsslOptionPacket, ROUTER_LIFETIME);
-
-        apfFilter.shutdown();
-    }
-
-    /**
-     * Stage a file for testing, i.e. make it native accessible. Given a resource ID,
-     * copy that resource into the app's data directory and return the path to it.
-     */
-    private String stageFile(int rawId) throws Exception {
-        File file = new File(InstrumentationRegistry.getContext().getFilesDir(), "staged_file");
-        new File(file.getParent()).mkdirs();
-        InputStream in = null;
-        OutputStream out = null;
-        try {
-            in = InstrumentationRegistry.getContext().getResources().openRawResource(rawId);
-            out = new FileOutputStream(file);
-            Streams.copy(in, out);
-        } finally {
-            if (in != null) in.close();
-            if (out != null) out.close();
-        }
-        return file.getAbsolutePath();
-    }
-
-    private static void put(ByteBuffer buffer, int position, byte[] bytes) {
-        final int original = buffer.position();
-        buffer.position(position);
-        buffer.put(bytes);
-        buffer.position(original);
-    }
-
-    @Test
-    public void testRaParsing() throws Exception {
-        final int maxRandomPacketSize = 512;
-        final Random r = new Random();
-        MockIpClientCallback cb = new MockIpClientCallback();
-        ApfConfiguration config = getDefaultConfig();
-        config.multicastFilter = DROP_MULTICAST;
-        config.ieee802_3Filter = DROP_802_3_FRAMES;
-        TestApfFilter apfFilter = new TestApfFilter(mContext, config, cb, mLog);
-        for (int i = 0; i < 1000; i++) {
-            byte[] packet = new byte[r.nextInt(maxRandomPacketSize + 1)];
-            r.nextBytes(packet);
-            try {
-                apfFilter.new Ra(packet, packet.length);
-            } catch (ApfFilter.InvalidRaException e) {
-            } catch (Exception e) {
-                throw new Exception("bad packet: " + HexDump.toHexString(packet), e);
-            }
-        }
-    }
-
-    @Test
-    public void testRaProcessing() throws Exception {
-        final int maxRandomPacketSize = 512;
-        final Random r = new Random();
-        MockIpClientCallback cb = new MockIpClientCallback();
-        ApfConfiguration config = getDefaultConfig();
-        config.multicastFilter = DROP_MULTICAST;
-        config.ieee802_3Filter = DROP_802_3_FRAMES;
-        TestApfFilter apfFilter = new TestApfFilter(mContext, config, cb, mLog);
-        for (int i = 0; i < 1000; i++) {
-            byte[] packet = new byte[r.nextInt(maxRandomPacketSize + 1)];
-            r.nextBytes(packet);
-            try {
-                apfFilter.processRa(packet, packet.length);
-            } catch (Exception e) {
-                throw new Exception("bad packet: " + HexDump.toHexString(packet), e);
-            }
-        }
-    }
-
-    /**
-     * Call the APF interpreter to run {@code program} on {@code packet} with persistent memory
-     * segment {@data} pretending the filter was installed {@code filter_age} seconds ago.
-     */
-    private native static int apfSimulate(byte[] program, byte[] packet, byte[] data,
-        int filter_age);
-
-    /**
-     * Compile a tcpdump human-readable filter (e.g. "icmp" or "tcp port 54") into a BPF
-     * prorgam and return a human-readable dump of the BPF program identical to "tcpdump -d".
-     */
-    private native static String compileToBpf(String filter);
-
-    /**
-     * Open packet capture file {@code pcap_filename} and filter the packets using tcpdump
-     * human-readable filter (e.g. "icmp" or "tcp port 54") compiled to a BPF program and
-     * at the same time using APF program {@code apf_program}.  Return {@code true} if
-     * both APF and BPF programs filter out exactly the same packets.
-     */
-    private native static boolean compareBpfApf(String filter, String pcap_filename,
-            byte[] apf_program);
-
-
-    /**
-     * Open packet capture file {@code pcapFilename} and run it through APF filter. Then
-     * checks whether all the packets are dropped and populates data[] {@code data} with
-     * the APF counters.
-     */
-    private native static boolean dropsAllPackets(byte[] program, byte[] data, String pcapFilename);
-
-    @Test
-    public void testBroadcastAddress() throws Exception {
-        assertEqualsIp("255.255.255.255", ApfFilter.ipv4BroadcastAddress(IPV4_ANY_HOST_ADDR, 0));
-        assertEqualsIp("0.0.0.0", ApfFilter.ipv4BroadcastAddress(IPV4_ANY_HOST_ADDR, 32));
-        assertEqualsIp("0.0.3.255", ApfFilter.ipv4BroadcastAddress(IPV4_ANY_HOST_ADDR, 22));
-        assertEqualsIp("0.255.255.255", ApfFilter.ipv4BroadcastAddress(IPV4_ANY_HOST_ADDR, 8));
-
-        assertEqualsIp("255.255.255.255", ApfFilter.ipv4BroadcastAddress(MOCK_IPV4_ADDR, 0));
-        assertEqualsIp("10.0.0.1", ApfFilter.ipv4BroadcastAddress(MOCK_IPV4_ADDR, 32));
-        assertEqualsIp("10.0.0.255", ApfFilter.ipv4BroadcastAddress(MOCK_IPV4_ADDR, 24));
-        assertEqualsIp("10.0.255.255", ApfFilter.ipv4BroadcastAddress(MOCK_IPV4_ADDR, 16));
-    }
-
-    public void assertEqualsIp(String expected, int got) throws Exception {
-        int want = bytesToBEInt(InetAddress.getByName(expected).getAddress());
-        assertEquals(want, got);
-    }
-}
diff --git a/packages/NetworkStack/tests/unit/src/android/net/apf/Bpf2Apf.java b/packages/NetworkStack/tests/unit/src/android/net/apf/Bpf2Apf.java
deleted file mode 100644
index 5d57cde..0000000
--- a/packages/NetworkStack/tests/unit/src/android/net/apf/Bpf2Apf.java
+++ /dev/null
@@ -1,327 +0,0 @@
-/*
- * Copyright (C) 2015 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.net.apf;
-
-import android.net.apf.ApfGenerator;
-import android.net.apf.ApfGenerator.IllegalInstructionException;
-import android.net.apf.ApfGenerator.Register;
-
-import java.io.BufferedReader;
-import java.io.InputStreamReader;
-
-/**
- * BPF to APF translator.
- *
- * Note: This is for testing purposes only and is not guaranteed to support
- *       translation of all BPF programs.
- *
- * Example usage:
- *   javac net/java/android/net/apf/ApfGenerator.java \
- *         tests/servicestests/src/android/net/apf/Bpf2Apf.java
- *   sudo tcpdump -i em1 -d icmp | java -classpath tests/servicestests/src:net/java \
- *                                      android.net.apf.Bpf2Apf
- */
-public class Bpf2Apf {
-    private static int parseImm(String line, String arg) {
-        if (!arg.startsWith("#0x")) {
-            throw new IllegalArgumentException("Unhandled instruction: " + line);
-        }
-        final long val_long = Long.parseLong(arg.substring(3), 16);
-        if (val_long < 0 || val_long > Long.parseLong("ffffffff", 16)) {
-            throw new IllegalArgumentException("Unhandled instruction: " + line);
-        }
-        return new Long((val_long << 32) >> 32).intValue();
-    }
-
-    /**
-     * Convert a single line of "tcpdump -d" (human readable BPF program dump) {@code line} into
-     * APF instruction(s) and append them to {@code gen}. Here's an example line:
-     * (001) jeq      #0x86dd          jt 2    jf 7
-     */
-    private static void convertLine(String line, ApfGenerator gen)
-            throws IllegalInstructionException {
-        if (line.indexOf("(") != 0 || line.indexOf(")") != 4 || line.indexOf(" ") != 5) {
-            throw new IllegalArgumentException("Unhandled instruction: " + line);
-        }
-        int label = Integer.parseInt(line.substring(1, 4));
-        gen.defineLabel(Integer.toString(label));
-        String opcode = line.substring(6, 10).trim();
-        String arg = line.substring(15, Math.min(32, line.length())).trim();
-        switch (opcode) {
-            case "ld":
-            case "ldh":
-            case "ldb":
-            case "ldx":
-            case "ldxb":
-            case "ldxh":
-                Register dest = opcode.contains("x") ? Register.R1 : Register.R0;
-                if (arg.equals("4*([14]&0xf)")) {
-                    if (!opcode.equals("ldxb")) {
-                        throw new IllegalArgumentException("Unhandled instruction: " + line);
-                    }
-                    gen.addLoadFromMemory(dest, gen.IPV4_HEADER_SIZE_MEMORY_SLOT);
-                    break;
-                }
-                if (arg.equals("#pktlen")) {
-                    if (!opcode.equals("ld")) {
-                        throw new IllegalArgumentException("Unhandled instruction: " + line);
-                    }
-                    gen.addLoadFromMemory(dest, gen.PACKET_SIZE_MEMORY_SLOT);
-                    break;
-                }
-                if (arg.startsWith("#0x")) {
-                    if (!opcode.equals("ld")) {
-                        throw new IllegalArgumentException("Unhandled instruction: " + line);
-                    }
-                    gen.addLoadImmediate(dest, parseImm(line, arg));
-                    break;
-                }
-                if (arg.startsWith("M[")) {
-                    if (!opcode.startsWith("ld")) {
-                        throw new IllegalArgumentException("Unhandled instruction: " + line);
-                    }
-                    int memory_slot = Integer.parseInt(arg.substring(2, arg.length() - 1));
-                    if (memory_slot < 0 || memory_slot >= gen.MEMORY_SLOTS ||
-                            // Disallow use of pre-filled slots as BPF programs might
-                            // wrongfully assume they're initialized to 0.
-                            (memory_slot >= gen.FIRST_PREFILLED_MEMORY_SLOT &&
-                                    memory_slot <= gen.LAST_PREFILLED_MEMORY_SLOT)) {
-                        throw new IllegalArgumentException("Unhandled instruction: " + line);
-                    }
-                    gen.addLoadFromMemory(dest, memory_slot);
-                    break;
-                }
-                if (arg.startsWith("[x + ")) {
-                    int offset = Integer.parseInt(arg.substring(5, arg.length() - 1));
-                    switch (opcode) {
-                        case "ld":
-                        case "ldx":
-                            gen.addLoad32Indexed(dest, offset);
-                            break;
-                        case "ldh":
-                        case "ldxh":
-                            gen.addLoad16Indexed(dest, offset);
-                            break;
-                        case "ldb":
-                        case "ldxb":
-                            gen.addLoad8Indexed(dest, offset);
-                            break;
-                    }
-                } else {
-                    int offset = Integer.parseInt(arg.substring(1, arg.length() - 1));
-                    switch (opcode) {
-                        case "ld":
-                        case "ldx":
-                            gen.addLoad32(dest, offset);
-                            break;
-                        case "ldh":
-                        case "ldxh":
-                            gen.addLoad16(dest, offset);
-                            break;
-                        case "ldb":
-                        case "ldxb":
-                            gen.addLoad8(dest, offset);
-                            break;
-                    }
-                }
-                break;
-            case "st":
-            case "stx":
-                Register src = opcode.contains("x") ? Register.R1 : Register.R0;
-                if (!arg.startsWith("M[")) {
-                    throw new IllegalArgumentException("Unhandled instruction: " + line);
-                }
-                int memory_slot = Integer.parseInt(arg.substring(2, arg.length() - 1));
-                if (memory_slot < 0 || memory_slot >= gen.MEMORY_SLOTS ||
-                        // Disallow overwriting pre-filled slots
-                        (memory_slot >= gen.FIRST_PREFILLED_MEMORY_SLOT &&
-                                memory_slot <= gen.LAST_PREFILLED_MEMORY_SLOT)) {
-                    throw new IllegalArgumentException("Unhandled instruction: " + line);
-                }
-                gen.addStoreToMemory(src, memory_slot);
-                break;
-            case "add":
-            case "and":
-            case "or":
-            case "sub":
-                if (arg.equals("x")) {
-                    switch(opcode) {
-                        case "add":
-                            gen.addAddR1();
-                            break;
-                        case "and":
-                            gen.addAndR1();
-                            break;
-                        case "or":
-                            gen.addOrR1();
-                            break;
-                        case "sub":
-                            gen.addNeg(Register.R1);
-                            gen.addAddR1();
-                            gen.addNeg(Register.R1);
-                            break;
-                    }
-                } else {
-                    int imm = parseImm(line, arg);
-                    switch(opcode) {
-                        case "add":
-                            gen.addAdd(imm);
-                            break;
-                        case "and":
-                            gen.addAnd(imm);
-                            break;
-                        case "or":
-                            gen.addOr(imm);
-                            break;
-                        case "sub":
-                            gen.addAdd(-imm);
-                            break;
-                    }
-                }
-                break;
-            case "jeq":
-            case "jset":
-            case "jgt":
-            case "jge":
-                int val = 0;
-                boolean reg_compare;
-                if (arg.startsWith("x")) {
-                    reg_compare = true;
-                } else {
-                    reg_compare = false;
-                    val = parseImm(line, arg);
-                }
-                int jt_offset = line.indexOf("jt");
-                int jf_offset = line.indexOf("jf");
-                String true_label = line.substring(jt_offset + 2, jf_offset).trim();
-                String false_label = line.substring(jf_offset + 2).trim();
-                boolean true_label_is_fallthrough = Integer.parseInt(true_label) == label + 1;
-                boolean false_label_is_fallthrough = Integer.parseInt(false_label) == label + 1;
-                if (true_label_is_fallthrough && false_label_is_fallthrough)
-                    break;
-                switch (opcode) {
-                    case "jeq":
-                        if (!true_label_is_fallthrough) {
-                            if (reg_compare) {
-                                gen.addJumpIfR0EqualsR1(true_label);
-                            } else {
-                                gen.addJumpIfR0Equals(val, true_label);
-                            }
-                        }
-                        if (!false_label_is_fallthrough) {
-                            if (!true_label_is_fallthrough) {
-                                gen.addJump(false_label);
-                            } else if (reg_compare) {
-                                gen.addJumpIfR0NotEqualsR1(false_label);
-                            } else {
-                                gen.addJumpIfR0NotEquals(val, false_label);
-                            }
-                        }
-                        break;
-                    case "jset":
-                        if (reg_compare) {
-                            gen.addJumpIfR0AnyBitsSetR1(true_label);
-                        } else {
-                            gen.addJumpIfR0AnyBitsSet(val, true_label);
-                        }
-                        if (!false_label_is_fallthrough) {
-                            gen.addJump(false_label);
-                        }
-                        break;
-                    case "jgt":
-                        if (!true_label_is_fallthrough ||
-                                // We have no less-than-or-equal-to register to register
-                                // comparison instruction, so in this case we'll jump
-                                // around an unconditional jump.
-                                (!false_label_is_fallthrough && reg_compare)) {
-                            if (reg_compare) {
-                                gen.addJumpIfR0GreaterThanR1(true_label);
-                            } else {
-                                gen.addJumpIfR0GreaterThan(val, true_label);
-                            }
-                        }
-                        if (!false_label_is_fallthrough) {
-                            if (!true_label_is_fallthrough || reg_compare) {
-                                gen.addJump(false_label);
-                            } else {
-                                gen.addJumpIfR0LessThan(val + 1, false_label);
-                            }
-                        }
-                        break;
-                    case "jge":
-                        if (!false_label_is_fallthrough ||
-                                // We have no greater-than-or-equal-to register to register
-                                // comparison instruction, so in this case we'll jump
-                                // around an unconditional jump.
-                                (!true_label_is_fallthrough && reg_compare)) {
-                            if (reg_compare) {
-                                gen.addJumpIfR0LessThanR1(false_label);
-                            } else {
-                                gen.addJumpIfR0LessThan(val, false_label);
-                            }
-                        }
-                        if (!true_label_is_fallthrough) {
-                            if (!false_label_is_fallthrough || reg_compare) {
-                                gen.addJump(true_label);
-                            } else {
-                                gen.addJumpIfR0GreaterThan(val - 1, true_label);
-                            }
-                        }
-                        break;
-                }
-                break;
-            case "ret":
-                if (arg.equals("#0")) {
-                    gen.addJump(gen.DROP_LABEL);
-                } else {
-                    gen.addJump(gen.PASS_LABEL);
-                }
-                break;
-            case "tax":
-                gen.addMove(Register.R1);
-                break;
-            case "txa":
-                gen.addMove(Register.R0);
-                break;
-            default:
-                throw new IllegalArgumentException("Unhandled instruction: " + line);
-        }
-    }
-
-    /**
-     * Convert the output of "tcpdump -d" (human readable BPF program dump) {@code bpf} into an APF
-     * program and return it.
-     */
-    public static byte[] convert(String bpf) throws IllegalInstructionException {
-        ApfGenerator gen = new ApfGenerator(3);
-        for (String line : bpf.split("\\n")) convertLine(line, gen);
-        return gen.generate();
-    }
-
-    /**
-     * Convert the output of "tcpdump -d" (human readable BPF program dump) piped in stdin into an
-     * APF program and output it via stdout.
-     */
-    public static void main(String[] args) throws Exception {
-        BufferedReader in = new BufferedReader(new InputStreamReader(System.in));
-        String line = null;
-        StringBuilder responseData = new StringBuilder();
-        ApfGenerator gen = new ApfGenerator(3);
-        while ((line = in.readLine()) != null) convertLine(line, gen);
-        System.out.write(gen.generate());
-    }
-}
diff --git a/packages/NetworkStack/tests/unit/src/android/net/captiveportal/CaptivePortalProbeSpecTest.java b/packages/NetworkStack/tests/unit/src/android/net/captiveportal/CaptivePortalProbeSpecTest.java
deleted file mode 100644
index f948086..0000000
--- a/packages/NetworkStack/tests/unit/src/android/net/captiveportal/CaptivePortalProbeSpecTest.java
+++ /dev/null
@@ -1,170 +0,0 @@
-/*
- * Copyright (C) 2018 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.net.captiveportal;
-
-import static junit.framework.Assert.assertEquals;
-import static junit.framework.Assert.assertNull;
-import static junit.framework.Assert.assertTrue;
-
-import androidx.test.filters.SmallTest;
-import androidx.test.runner.AndroidJUnit4;
-
-import org.junit.Test;
-import org.junit.runner.RunWith;
-
-import java.net.MalformedURLException;
-import java.text.ParseException;
-
-@RunWith(AndroidJUnit4.class)
-@SmallTest
-public class CaptivePortalProbeSpecTest {
-
-    @Test
-    public void testGetResult_Regex() throws MalformedURLException, ParseException {
-        // 2xx status or 404, with an empty (match everything) location regex
-        CaptivePortalProbeSpec statusRegexSpec = CaptivePortalProbeSpec.parseSpec(
-                "http://www.google.com@@/@@2[0-9]{2}|404@@/@@");
-
-        // 404, or 301/302 redirect to some HTTPS page under google.com
-        CaptivePortalProbeSpec redirectSpec = CaptivePortalProbeSpec.parseSpec(
-                "http://google.com@@/@@404|30[12]@@/@@https://([0-9a-z]+\\.)*google\\.com.*");
-
-        assertSuccess(statusRegexSpec.getResult(200, null));
-        assertSuccess(statusRegexSpec.getResult(299, "qwer"));
-        assertSuccess(statusRegexSpec.getResult(404, null));
-        assertSuccess(statusRegexSpec.getResult(404, ""));
-
-        assertPortal(statusRegexSpec.getResult(300, null));
-        assertPortal(statusRegexSpec.getResult(399, "qwer"));
-        assertPortal(statusRegexSpec.getResult(500, null));
-
-        assertSuccess(redirectSpec.getResult(404, null));
-        assertSuccess(redirectSpec.getResult(404, ""));
-        assertSuccess(redirectSpec.getResult(301, "https://www.google.com"));
-        assertSuccess(redirectSpec.getResult(301, "https://www.google.com/test?q=3"));
-        assertSuccess(redirectSpec.getResult(302, "https://google.com/test?q=3"));
-
-        assertPortal(redirectSpec.getResult(299, "https://google.com/test?q=3"));
-        assertPortal(redirectSpec.getResult(299, ""));
-        assertPortal(redirectSpec.getResult(499, null));
-        assertPortal(redirectSpec.getResult(301, "http://login.portal.example.com/loginpage"));
-        assertPortal(redirectSpec.getResult(302, "http://www.google.com/test?q=3"));
-    }
-
-    @Test(expected = ParseException.class)
-    public void testParseSpec_Empty() throws MalformedURLException, ParseException {
-        CaptivePortalProbeSpec.parseSpec("");
-    }
-
-    @Test(expected = ParseException.class)
-    public void testParseSpec_Null() throws MalformedURLException, ParseException {
-        CaptivePortalProbeSpec.parseSpec(null);
-    }
-
-    @Test(expected = ParseException.class)
-    public void testParseSpec_MissingParts() throws MalformedURLException, ParseException {
-        CaptivePortalProbeSpec.parseSpec("http://google.com/@@/@@123");
-    }
-
-    @Test(expected = ParseException.class)
-    public void testParseSpec_TooManyParts() throws MalformedURLException, ParseException {
-        CaptivePortalProbeSpec.parseSpec("http://google.com/@@/@@123@@/@@456@@/@@extra");
-    }
-
-    @Test(expected = ParseException.class)
-    public void testParseSpec_InvalidStatusRegex() throws MalformedURLException, ParseException {
-        CaptivePortalProbeSpec.parseSpec("http://google.com/@@/@@unmatched(parenthesis@@/@@456");
-    }
-
-    @Test(expected = ParseException.class)
-    public void testParseSpec_InvalidLocationRegex() throws MalformedURLException, ParseException {
-        CaptivePortalProbeSpec.parseSpec("http://google.com/@@/@@123@@/@@unmatched[[]bracket");
-    }
-
-    @Test(expected = MalformedURLException.class)
-    public void testParseSpec_EmptyURL() throws MalformedURLException, ParseException {
-        CaptivePortalProbeSpec.parseSpec("@@/@@123@@/@@123");
-    }
-
-    @Test(expected = ParseException.class)
-    public void testParseSpec_NoParts() throws MalformedURLException, ParseException {
-        CaptivePortalProbeSpec.parseSpec("invalid");
-    }
-
-    @Test(expected = MalformedURLException.class)
-    public void testParseSpec_RegexInvalidUrl() throws MalformedURLException, ParseException {
-        CaptivePortalProbeSpec.parseSpec("notaurl@@/@@123@@/@@123");
-    }
-
-    @Test
-    public void testParseSpecOrNull_UsesSpec() {
-        final String specUrl = "http://google.com/probe";
-        final String redirectUrl = "https://google.com/probe";
-        CaptivePortalProbeSpec spec = CaptivePortalProbeSpec.parseSpecOrNull(
-                specUrl + "@@/@@302@@/@@" + redirectUrl);
-        assertEquals(specUrl, spec.getUrl().toString());
-
-        assertPortal(spec.getResult(302, "http://portal.example.com"));
-        assertSuccess(spec.getResult(302, redirectUrl));
-    }
-
-    @Test
-    public void testParseSpecOrNull_UsesFallback() throws MalformedURLException {
-        CaptivePortalProbeSpec spec = CaptivePortalProbeSpec.parseSpecOrNull(null);
-        assertNull(spec);
-
-        spec = CaptivePortalProbeSpec.parseSpecOrNull("");
-        assertNull(spec);
-
-        spec = CaptivePortalProbeSpec.parseSpecOrNull("@@/@@ @@/@@ @@/@@");
-        assertNull(spec);
-
-        spec = CaptivePortalProbeSpec.parseSpecOrNull("invalid@@/@@123@@/@@456");
-        assertNull(spec);
-    }
-
-    @Test
-    public void testParseSpecOrUseStatusCodeFallback_EmptySpec() throws MalformedURLException {
-        CaptivePortalProbeSpec spec = CaptivePortalProbeSpec.parseSpecOrNull("");
-        assertNull(spec);
-    }
-
-    private void assertIsStatusSpec(CaptivePortalProbeSpec spec) {
-        assertSuccess(spec.getResult(204, null));
-        assertSuccess(spec.getResult(204, "1234"));
-
-        assertPortal(spec.getResult(200, null));
-        assertPortal(spec.getResult(301, null));
-        assertPortal(spec.getResult(302, "1234"));
-        assertPortal(spec.getResult(399, ""));
-
-        assertFailed(spec.getResult(404, null));
-        assertFailed(spec.getResult(500, "1234"));
-    }
-
-    private void assertPortal(CaptivePortalProbeResult result) {
-        assertTrue(result.isPortal());
-    }
-
-    private void assertSuccess(CaptivePortalProbeResult result) {
-        assertTrue(result.isSuccessful());
-    }
-
-    private void assertFailed(CaptivePortalProbeResult result) {
-        assertTrue(result.isFailed());
-    }
-}
diff --git a/packages/NetworkStack/tests/unit/src/android/net/dhcp/DhcpLeaseRepositoryTest.java b/packages/NetworkStack/tests/unit/src/android/net/dhcp/DhcpLeaseRepositoryTest.java
deleted file mode 100644
index 27d7255..0000000
--- a/packages/NetworkStack/tests/unit/src/android/net/dhcp/DhcpLeaseRepositoryTest.java
+++ /dev/null
@@ -1,544 +0,0 @@
-/*
- * Copyright (C) 2018 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.net.dhcp;
-
-import static android.net.InetAddresses.parseNumericAddress;
-import static android.net.dhcp.DhcpLease.HOSTNAME_NONE;
-import static android.net.dhcp.DhcpLeaseRepository.CLIENTID_UNSPEC;
-import static android.net.dhcp.DhcpLeaseRepository.INETADDR_UNSPEC;
-
-import static com.android.server.util.NetworkStackConstants.IPV4_ADDR_ANY;
-
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertFalse;
-import static org.junit.Assert.assertNotEquals;
-import static org.junit.Assert.assertNotNull;
-import static org.junit.Assert.assertTrue;
-import static org.junit.Assert.fail;
-import static org.mockito.Mockito.when;
-
-import android.annotation.NonNull;
-import android.annotation.Nullable;
-import android.net.IpPrefix;
-import android.net.MacAddress;
-import android.net.dhcp.DhcpServer.Clock;
-import android.net.util.SharedLog;
-
-import androidx.test.filters.SmallTest;
-import androidx.test.runner.AndroidJUnit4;
-
-import org.junit.Before;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.mockito.Mock;
-import org.mockito.MockitoAnnotations;
-
-import static java.lang.String.format;
-
-import java.net.Inet4Address;
-import java.util.Arrays;
-import java.util.Collections;
-import java.util.HashSet;
-import java.util.Set;
-
-@RunWith(AndroidJUnit4.class)
-@SmallTest
-public class DhcpLeaseRepositoryTest {
-    private static final Inet4Address TEST_DEF_ROUTER = parseAddr4("192.168.42.247");
-    private static final Inet4Address TEST_SERVER_ADDR = parseAddr4("192.168.42.241");
-    private static final Inet4Address TEST_RESERVED_ADDR = parseAddr4("192.168.42.243");
-    private static final MacAddress TEST_MAC_1 = MacAddress.fromBytes(
-            new byte[] { 5, 4, 3, 2, 1, 0 });
-    private static final MacAddress TEST_MAC_2 = MacAddress.fromBytes(
-            new byte[] { 0, 1, 2, 3, 4, 5 });
-    private static final MacAddress TEST_MAC_3 = MacAddress.fromBytes(
-            new byte[] { 0, 1, 2, 3, 4, 6 });
-    private static final Inet4Address TEST_INETADDR_1 = parseAddr4("192.168.42.248");
-    private static final Inet4Address TEST_INETADDR_2 = parseAddr4("192.168.42.249");
-    private static final String TEST_HOSTNAME_1 = "hostname1";
-    private static final String TEST_HOSTNAME_2 = "hostname2";
-    private static final IpPrefix TEST_IP_PREFIX = new IpPrefix(TEST_SERVER_ADDR, 22);
-    private static final long TEST_TIME = 100L;
-    private static final int TEST_LEASE_TIME_MS = 3_600_000;
-    private static final Set<Inet4Address> TEST_EXCL_SET =
-            Collections.unmodifiableSet(new HashSet<>(Arrays.asList(
-                TEST_SERVER_ADDR, TEST_DEF_ROUTER, TEST_RESERVED_ADDR)));
-
-    @NonNull
-    private SharedLog mLog;
-    @NonNull @Mock
-    private Clock mClock;
-    @NonNull
-    private DhcpLeaseRepository mRepo;
-
-    private static Inet4Address parseAddr4(String inet4Addr) {
-        return (Inet4Address) parseNumericAddress(inet4Addr);
-    }
-
-    @Before
-    public void setUp() {
-        MockitoAnnotations.initMocks(this);
-        mLog = new SharedLog("DhcpLeaseRepositoryTest");
-        when(mClock.elapsedRealtime()).thenReturn(TEST_TIME);
-        mRepo = new DhcpLeaseRepository(
-                TEST_IP_PREFIX, TEST_EXCL_SET, TEST_LEASE_TIME_MS, mLog, mClock);
-    }
-
-    /**
-     * Request a number of addresses through offer/request. Useful to test address exhaustion.
-     * @param nAddr Number of addresses to request.
-     */
-    private void requestAddresses(byte nAddr) throws Exception {
-        final HashSet<Inet4Address> addrs = new HashSet<>();
-        byte[] hwAddrBytes = new byte[] { 8, 4, 3, 2, 1, 0 };
-        for (byte i = 0; i < nAddr; i++) {
-            hwAddrBytes[5] = i;
-            MacAddress newMac = MacAddress.fromBytes(hwAddrBytes);
-            final String hostname = "host_" + i;
-            final DhcpLease lease = mRepo.getOffer(CLIENTID_UNSPEC, newMac,
-                    IPV4_ADDR_ANY /* relayAddr */, INETADDR_UNSPEC /* reqAddr */, hostname);
-
-            assertNotNull(lease);
-            assertEquals(newMac, lease.getHwAddr());
-            assertEquals(hostname, lease.getHostname());
-            assertTrue(format("Duplicate address allocated: %s in %s", lease.getNetAddr(), addrs),
-                    addrs.add(lease.getNetAddr()));
-
-            requestLeaseSelecting(newMac, lease.getNetAddr(), hostname);
-        }
-    }
-
-    @Test
-    public void testAddressExhaustion() throws Exception {
-        // Use a /28 to quickly run out of addresses
-        mRepo.updateParams(new IpPrefix(TEST_SERVER_ADDR, 28), TEST_EXCL_SET, TEST_LEASE_TIME_MS);
-
-        // /28 should have 16 addresses, 14 w/o the first/last, 11 w/o excluded addresses
-        requestAddresses((byte) 11);
-
-        try {
-            mRepo.getOffer(null, TEST_MAC_2,
-                    IPV4_ADDR_ANY /* relayAddr */, INETADDR_UNSPEC /* reqAddr */, HOSTNAME_NONE);
-            fail("Should be out of addresses");
-        } catch (DhcpLeaseRepository.OutOfAddressesException e) {
-            // Expected
-        }
-    }
-
-    @Test
-    public void testUpdateParams_LeaseCleanup() throws Exception {
-        // Inside /28:
-        final Inet4Address reqAddrIn28 = parseAddr4("192.168.42.242");
-        final Inet4Address declinedAddrIn28 = parseAddr4("192.168.42.245");
-
-        // Inside /28, but not available there (first address of the range)
-        final Inet4Address declinedFirstAddrIn28 = parseAddr4("192.168.42.240");
-
-        final DhcpLease reqAddrIn28Lease = requestLeaseSelecting(TEST_MAC_1, reqAddrIn28);
-        mRepo.markLeaseDeclined(declinedAddrIn28);
-        mRepo.markLeaseDeclined(declinedFirstAddrIn28);
-
-        // Inside /22, but outside /28:
-        final Inet4Address reqAddrIn22 = parseAddr4("192.168.42.3");
-        final Inet4Address declinedAddrIn22 = parseAddr4("192.168.42.4");
-
-        final DhcpLease reqAddrIn22Lease = requestLeaseSelecting(TEST_MAC_3, reqAddrIn22);
-        mRepo.markLeaseDeclined(declinedAddrIn22);
-
-        // Address that will be reserved in the updateParams call below
-        final Inet4Address reservedAddr = parseAddr4("192.168.42.244");
-        final DhcpLease reservedAddrLease = requestLeaseSelecting(TEST_MAC_2, reservedAddr);
-
-        // Update from /22 to /28 and add another reserved address
-        Set<Inet4Address> newReserved = new HashSet<>(TEST_EXCL_SET);
-        newReserved.add(reservedAddr);
-        mRepo.updateParams(new IpPrefix(TEST_SERVER_ADDR, 28), newReserved, TEST_LEASE_TIME_MS);
-
-        assertHasLease(reqAddrIn28Lease);
-        assertDeclined(declinedAddrIn28);
-
-        assertNotDeclined(declinedFirstAddrIn28);
-
-        assertNoLease(reqAddrIn22Lease);
-        assertNotDeclined(declinedAddrIn22);
-
-        assertNoLease(reservedAddrLease);
-    }
-
-    @Test
-    public void testGetOffer_StableAddress() throws Exception {
-        for (final MacAddress macAddr : new MacAddress[] { TEST_MAC_1, TEST_MAC_2, TEST_MAC_3 }) {
-            final DhcpLease lease = mRepo.getOffer(CLIENTID_UNSPEC, macAddr,
-                    IPV4_ADDR_ANY /* relayAddr */, INETADDR_UNSPEC /* reqAddr */, HOSTNAME_NONE);
-
-            // Same lease is offered twice
-            final DhcpLease newLease = mRepo.getOffer(CLIENTID_UNSPEC, macAddr,
-                    IPV4_ADDR_ANY /* relayAddr */, INETADDR_UNSPEC /* reqAddr */, HOSTNAME_NONE);
-            assertEquals(lease, newLease);
-        }
-    }
-
-    @Test
-    public void testUpdateParams_UsesNewPrefix() throws Exception {
-        final IpPrefix newPrefix = new IpPrefix(parseAddr4("192.168.123.0"), 24);
-        mRepo.updateParams(newPrefix, TEST_EXCL_SET, TEST_LEASE_TIME_MS);
-
-        DhcpLease lease = mRepo.getOffer(CLIENTID_UNSPEC, TEST_MAC_1,
-                IPV4_ADDR_ANY /* relayAddr */, INETADDR_UNSPEC /* reqAddr */, HOSTNAME_NONE);
-        assertTrue(newPrefix.contains(lease.getNetAddr()));
-    }
-
-    @Test
-    public void testGetOffer_ExistingLease() throws Exception {
-        requestLeaseSelecting(TEST_MAC_1, TEST_INETADDR_1, TEST_HOSTNAME_1);
-
-        DhcpLease offer = mRepo.getOffer(CLIENTID_UNSPEC, TEST_MAC_1,
-                IPV4_ADDR_ANY /* relayAddr */, INETADDR_UNSPEC /* reqAddr */, HOSTNAME_NONE);
-        assertEquals(TEST_INETADDR_1, offer.getNetAddr());
-        assertEquals(TEST_HOSTNAME_1, offer.getHostname());
-    }
-
-    @Test
-    public void testGetOffer_ClientIdHasExistingLease() throws Exception {
-        final byte[] clientId = new byte[] { 1, 2 };
-        mRepo.requestLease(clientId, TEST_MAC_1, IPV4_ADDR_ANY /* clientAddr */,
-                IPV4_ADDR_ANY /* relayAddr */, TEST_INETADDR_1 /* reqAddr */, false,
-                TEST_HOSTNAME_1);
-
-        // Different MAC, but same clientId
-        DhcpLease offer = mRepo.getOffer(clientId, TEST_MAC_2,
-                IPV4_ADDR_ANY /* relayAddr */, INETADDR_UNSPEC /* reqAddr */, HOSTNAME_NONE);
-        assertEquals(TEST_INETADDR_1, offer.getNetAddr());
-        assertEquals(TEST_HOSTNAME_1, offer.getHostname());
-    }
-
-    @Test
-    public void testGetOffer_DifferentClientId() throws Exception {
-        final byte[] clientId1 = new byte[] { 1, 2 };
-        final byte[] clientId2 = new byte[] { 3, 4 };
-        mRepo.requestLease(clientId1, TEST_MAC_1, IPV4_ADDR_ANY /* clientAddr */,
-                IPV4_ADDR_ANY /* relayAddr */, TEST_INETADDR_1 /* reqAddr */, false,
-                TEST_HOSTNAME_1);
-
-        // Same MAC, different client ID
-        DhcpLease offer = mRepo.getOffer(clientId2, TEST_MAC_1,
-                IPV4_ADDR_ANY /* relayAddr */, INETADDR_UNSPEC /* reqAddr */, HOSTNAME_NONE);
-        // Obtains a different address
-        assertNotEquals(TEST_INETADDR_1, offer.getNetAddr());
-        assertEquals(HOSTNAME_NONE, offer.getHostname());
-        assertEquals(TEST_MAC_1, offer.getHwAddr());
-    }
-
-    @Test
-    public void testGetOffer_RequestedAddress() throws Exception {
-        DhcpLease offer = mRepo.getOffer(CLIENTID_UNSPEC, TEST_MAC_1, IPV4_ADDR_ANY /* relayAddr */,
-                TEST_INETADDR_1 /* reqAddr */, TEST_HOSTNAME_1);
-        assertEquals(TEST_INETADDR_1, offer.getNetAddr());
-        assertEquals(TEST_HOSTNAME_1, offer.getHostname());
-    }
-
-    @Test
-    public void testGetOffer_RequestedAddressInUse() throws Exception {
-        requestLeaseSelecting(TEST_MAC_1, TEST_INETADDR_1);
-        DhcpLease offer = mRepo.getOffer(CLIENTID_UNSPEC, TEST_MAC_2, IPV4_ADDR_ANY /* relayAddr */,
-                TEST_INETADDR_1 /* reqAddr */, HOSTNAME_NONE);
-        assertNotEquals(TEST_INETADDR_1, offer.getNetAddr());
-    }
-
-    @Test
-    public void testGetOffer_RequestedAddressReserved() throws Exception {
-        DhcpLease offer = mRepo.getOffer(CLIENTID_UNSPEC, TEST_MAC_1, IPV4_ADDR_ANY /* relayAddr */,
-                TEST_RESERVED_ADDR /* reqAddr */, HOSTNAME_NONE);
-        assertNotEquals(TEST_RESERVED_ADDR, offer.getNetAddr());
-    }
-
-    @Test
-    public void testGetOffer_RequestedAddressInvalid() throws Exception {
-        final Inet4Address invalidAddr = parseAddr4("192.168.42.0");
-        DhcpLease offer = mRepo.getOffer(CLIENTID_UNSPEC, TEST_MAC_1, IPV4_ADDR_ANY /* relayAddr */,
-                invalidAddr /* reqAddr */, HOSTNAME_NONE);
-        assertNotEquals(invalidAddr, offer.getNetAddr());
-    }
-
-    @Test
-    public void testGetOffer_RequestedAddressOutsideSubnet() throws Exception {
-        final Inet4Address invalidAddr = parseAddr4("192.168.254.2");
-        DhcpLease offer = mRepo.getOffer(CLIENTID_UNSPEC, TEST_MAC_1, IPV4_ADDR_ANY /* relayAddr */,
-                invalidAddr /* reqAddr */, HOSTNAME_NONE);
-        assertNotEquals(invalidAddr, offer.getNetAddr());
-    }
-
-    @Test(expected = DhcpLeaseRepository.InvalidSubnetException.class)
-    public void testGetOffer_RelayInInvalidSubnet() throws Exception {
-        mRepo.getOffer(CLIENTID_UNSPEC, TEST_MAC_1, parseAddr4("192.168.254.2") /* relayAddr */,
-                INETADDR_UNSPEC /* reqAddr */, HOSTNAME_NONE);
-    }
-
-    @Test
-    public void testRequestLease_SelectingTwice() throws Exception {
-        final DhcpLease lease1 = requestLeaseSelecting(TEST_MAC_1, TEST_INETADDR_1,
-                TEST_HOSTNAME_1);
-
-        // Second request from same client for a different address
-        final DhcpLease lease2 = requestLeaseSelecting(TEST_MAC_1, TEST_INETADDR_2,
-                TEST_HOSTNAME_2);
-
-        assertEquals(TEST_INETADDR_1, lease1.getNetAddr());
-        assertEquals(TEST_HOSTNAME_1, lease1.getHostname());
-
-        assertEquals(TEST_INETADDR_2, lease2.getNetAddr());
-        assertEquals(TEST_HOSTNAME_2, lease2.getHostname());
-
-        // First address freed when client requested a different one: another client can request it
-        final DhcpLease lease3 = requestLeaseSelecting(TEST_MAC_2, TEST_INETADDR_1, HOSTNAME_NONE);
-        assertEquals(TEST_INETADDR_1, lease3.getNetAddr());
-    }
-
-    @Test(expected = DhcpLeaseRepository.InvalidAddressException.class)
-    public void testRequestLease_SelectingInvalid() throws Exception {
-        requestLeaseSelecting(TEST_MAC_1, parseAddr4("192.168.254.5"));
-    }
-
-    @Test(expected = DhcpLeaseRepository.InvalidAddressException.class)
-    public void testRequestLease_SelectingInUse() throws Exception {
-        requestLeaseSelecting(TEST_MAC_1, TEST_INETADDR_1);
-        requestLeaseSelecting(TEST_MAC_2, TEST_INETADDR_1);
-    }
-
-    @Test(expected = DhcpLeaseRepository.InvalidAddressException.class)
-    public void testRequestLease_SelectingReserved() throws Exception {
-        requestLeaseSelecting(TEST_MAC_1, TEST_RESERVED_ADDR);
-    }
-
-    @Test(expected = DhcpLeaseRepository.InvalidSubnetException.class)
-    public void testRequestLease_SelectingRelayInInvalidSubnet() throws  Exception {
-        mRepo.requestLease(CLIENTID_UNSPEC, TEST_MAC_1, IPV4_ADDR_ANY /* clientAddr */,
-                parseAddr4("192.168.128.1") /* relayAddr */, TEST_INETADDR_1 /* reqAddr */,
-                true /* sidSet */, HOSTNAME_NONE);
-    }
-
-    @Test
-    public void testRequestLease_InitReboot() throws Exception {
-        // Request address once
-        requestLeaseSelecting(TEST_MAC_1, TEST_INETADDR_1);
-
-        final long newTime = TEST_TIME + 100;
-        when(mClock.elapsedRealtime()).thenReturn(newTime);
-
-        // init-reboot (sidSet == false): verify configuration
-        final DhcpLease lease = requestLeaseInitReboot(TEST_MAC_1, TEST_INETADDR_1);
-        assertEquals(TEST_INETADDR_1, lease.getNetAddr());
-        assertEquals(newTime + TEST_LEASE_TIME_MS, lease.getExpTime());
-    }
-
-    @Test(expected = DhcpLeaseRepository.InvalidAddressException.class)
-    public void testRequestLease_InitRebootWrongAddr() throws Exception {
-        // Request address once
-        requestLeaseSelecting(TEST_MAC_1, TEST_INETADDR_1);
-        // init-reboot with different requested address
-        requestLeaseInitReboot(TEST_MAC_1, TEST_INETADDR_2);
-    }
-
-    @Test
-    public void testRequestLease_InitRebootUnknownAddr() throws Exception {
-        // init-reboot with unknown requested address
-        final DhcpLease lease = requestLeaseInitReboot(TEST_MAC_1, TEST_INETADDR_2);
-        // RFC2131 says we should not reply to accommodate other servers, but since we are
-        // authoritative we allow creating the lease to avoid issues with lost lease DB (same as
-        // dnsmasq behavior)
-        assertEquals(TEST_INETADDR_2, lease.getNetAddr());
-    }
-
-    @Test(expected = DhcpLeaseRepository.InvalidAddressException.class)
-    public void testRequestLease_InitRebootWrongSubnet() throws Exception {
-        requestLeaseInitReboot(TEST_MAC_1, parseAddr4("192.168.254.2"));
-    }
-
-    @Test
-    public void testRequestLease_Renewing() throws Exception {
-        requestLeaseSelecting(TEST_MAC_1, TEST_INETADDR_1);
-
-        final long newTime = TEST_TIME + 100;
-        when(mClock.elapsedRealtime()).thenReturn(newTime);
-
-        final DhcpLease lease = requestLeaseRenewing(TEST_MAC_1, TEST_INETADDR_1);
-
-        assertEquals(TEST_INETADDR_1, lease.getNetAddr());
-        assertEquals(newTime + TEST_LEASE_TIME_MS, lease.getExpTime());
-    }
-
-    @Test
-    public void testRequestLease_RenewingUnknownAddr() throws Exception {
-        final long newTime = TEST_TIME + 100;
-        when(mClock.elapsedRealtime()).thenReturn(newTime);
-        final DhcpLease lease = requestLeaseRenewing(TEST_MAC_1, TEST_INETADDR_1);
-        // Allows renewing an unknown address if available
-        assertEquals(TEST_INETADDR_1, lease.getNetAddr());
-        assertEquals(newTime + TEST_LEASE_TIME_MS, lease.getExpTime());
-    }
-
-    @Test(expected = DhcpLeaseRepository.InvalidAddressException.class)
-    public void testRequestLease_RenewingAddrInUse() throws Exception {
-        requestLeaseSelecting(TEST_MAC_2, TEST_INETADDR_1);
-        requestLeaseRenewing(TEST_MAC_1, TEST_INETADDR_1);
-    }
-
-    @Test(expected = DhcpLeaseRepository.InvalidAddressException.class)
-    public void testRequestLease_RenewingInvalidAddr() throws Exception {
-        requestLeaseRenewing(TEST_MAC_1, parseAddr4("192.168.254.2"));
-    }
-
-    @Test
-    public void testReleaseLease() throws Exception {
-        final DhcpLease lease1 = requestLeaseSelecting(TEST_MAC_1, TEST_INETADDR_1);
-
-        assertHasLease(lease1);
-        assertTrue(mRepo.releaseLease(CLIENTID_UNSPEC, TEST_MAC_1, TEST_INETADDR_1));
-        assertNoLease(lease1);
-
-        final DhcpLease lease2 = requestLeaseSelecting(TEST_MAC_2, TEST_INETADDR_1);
-        assertEquals(TEST_INETADDR_1, lease2.getNetAddr());
-    }
-
-    @Test
-    public void testReleaseLease_UnknownLease() {
-        assertFalse(mRepo.releaseLease(CLIENTID_UNSPEC, TEST_MAC_1, TEST_INETADDR_1));
-    }
-
-    @Test
-    public void testReleaseLease_StableOffer() throws Exception {
-        for (MacAddress mac : new MacAddress[] { TEST_MAC_1, TEST_MAC_2, TEST_MAC_3 }) {
-            final DhcpLease lease = mRepo.getOffer(CLIENTID_UNSPEC, mac,
-                    IPV4_ADDR_ANY /* relayAddr */, INETADDR_UNSPEC /* reqAddr */, HOSTNAME_NONE);
-
-            requestLeaseSelecting(mac, lease.getNetAddr());
-            mRepo.releaseLease(CLIENTID_UNSPEC, mac, lease.getNetAddr());
-
-            // Same lease is offered after it was released
-            final DhcpLease newLease = mRepo.getOffer(CLIENTID_UNSPEC, mac,
-                    IPV4_ADDR_ANY /* relayAddr */, INETADDR_UNSPEC /* reqAddr */, HOSTNAME_NONE);
-            assertEquals(lease.getNetAddr(), newLease.getNetAddr());
-        }
-    }
-
-    @Test
-    public void testMarkLeaseDeclined() throws Exception {
-        final DhcpLease lease = mRepo.getOffer(CLIENTID_UNSPEC, TEST_MAC_1,
-                IPV4_ADDR_ANY /* relayAddr */, INETADDR_UNSPEC /* reqAddr */, HOSTNAME_NONE);
-
-        mRepo.markLeaseDeclined(lease.getNetAddr());
-
-        // Same lease is not offered again
-        final DhcpLease newLease = mRepo.getOffer(CLIENTID_UNSPEC, TEST_MAC_1,
-                IPV4_ADDR_ANY /* relayAddr */, INETADDR_UNSPEC /* reqAddr */, HOSTNAME_NONE);
-        assertNotEquals(lease.getNetAddr(), newLease.getNetAddr());
-    }
-
-    @Test
-    public void testMarkLeaseDeclined_UsedIfOutOfAddresses() throws Exception {
-        // Use a /28 to quickly run out of addresses
-        mRepo.updateParams(new IpPrefix(TEST_SERVER_ADDR, 28), TEST_EXCL_SET, TEST_LEASE_TIME_MS);
-
-        mRepo.markLeaseDeclined(TEST_INETADDR_1);
-        mRepo.markLeaseDeclined(TEST_INETADDR_2);
-
-        // /28 should have 16 addresses, 14 w/o the first/last, 11 w/o excluded addresses
-        requestAddresses((byte) 9);
-
-        // Last 2 addresses: addresses marked declined should be used
-        final DhcpLease firstLease = mRepo.getOffer(CLIENTID_UNSPEC, TEST_MAC_1,
-                IPV4_ADDR_ANY /* relayAddr */, INETADDR_UNSPEC /* reqAddr */, TEST_HOSTNAME_1);
-        requestLeaseSelecting(TEST_MAC_1, firstLease.getNetAddr());
-
-        final DhcpLease secondLease = mRepo.getOffer(CLIENTID_UNSPEC, TEST_MAC_2,
-                IPV4_ADDR_ANY /* relayAddr */, INETADDR_UNSPEC /* reqAddr */, TEST_HOSTNAME_2);
-        requestLeaseSelecting(TEST_MAC_2, secondLease.getNetAddr());
-
-        // Now out of addresses
-        try {
-            mRepo.getOffer(CLIENTID_UNSPEC, TEST_MAC_3, IPV4_ADDR_ANY /* relayAddr */,
-                    INETADDR_UNSPEC /* reqAddr */, HOSTNAME_NONE);
-            fail("Repository should be out of addresses and throw");
-        } catch (DhcpLeaseRepository.OutOfAddressesException e) { /* expected */ }
-
-        assertEquals(TEST_INETADDR_1, firstLease.getNetAddr());
-        assertEquals(TEST_HOSTNAME_1, firstLease.getHostname());
-        assertEquals(TEST_INETADDR_2, secondLease.getNetAddr());
-        assertEquals(TEST_HOSTNAME_2, secondLease.getHostname());
-    }
-
-    private DhcpLease requestLease(@NonNull MacAddress macAddr, @NonNull Inet4Address clientAddr,
-            @Nullable Inet4Address reqAddr, @Nullable String hostname, boolean sidSet)
-            throws DhcpLeaseRepository.DhcpLeaseException {
-        return mRepo.requestLease(CLIENTID_UNSPEC, macAddr, clientAddr,
-                IPV4_ADDR_ANY /* relayAddr */,
-                reqAddr, sidSet, hostname);
-    }
-
-    /**
-     * Request a lease simulating a client in the SELECTING state.
-     */
-    private DhcpLease requestLeaseSelecting(@NonNull MacAddress macAddr,
-            @NonNull Inet4Address reqAddr, @Nullable String hostname)
-            throws DhcpLeaseRepository.DhcpLeaseException {
-        return requestLease(macAddr, IPV4_ADDR_ANY /* clientAddr */, reqAddr, hostname,
-                true /* sidSet */);
-    }
-
-    /**
-     * Request a lease simulating a client in the SELECTING state.
-     */
-    private DhcpLease requestLeaseSelecting(@NonNull MacAddress macAddr,
-            @NonNull Inet4Address reqAddr) throws DhcpLeaseRepository.DhcpLeaseException {
-        return requestLeaseSelecting(macAddr, reqAddr, HOSTNAME_NONE);
-    }
-
-    /**
-     * Request a lease simulating a client in the INIT-REBOOT state.
-     */
-    private DhcpLease requestLeaseInitReboot(@NonNull MacAddress macAddr,
-            @NonNull Inet4Address reqAddr) throws DhcpLeaseRepository.DhcpLeaseException {
-        return requestLease(macAddr, IPV4_ADDR_ANY /* clientAddr */, reqAddr, HOSTNAME_NONE,
-                false /* sidSet */);
-    }
-
-    /**
-     * Request a lease simulating a client in the RENEWING state.
-     */
-    private DhcpLease requestLeaseRenewing(@NonNull MacAddress macAddr,
-            @NonNull Inet4Address clientAddr) throws DhcpLeaseRepository.DhcpLeaseException {
-        // Renewing: clientAddr filled in, no reqAddr
-        return requestLease(macAddr, clientAddr, INETADDR_UNSPEC /* reqAddr */, HOSTNAME_NONE,
-                true /* sidSet */);
-    }
-
-    private void assertNoLease(DhcpLease lease) {
-        assertFalse("Leases contain " + lease, mRepo.getCommittedLeases().contains(lease));
-    }
-
-    private void assertHasLease(DhcpLease lease) {
-        assertTrue("Leases do not contain " + lease, mRepo.getCommittedLeases().contains(lease));
-    }
-
-    private void assertNotDeclined(Inet4Address addr) {
-        assertFalse("Address is declined: " + addr, mRepo.getDeclinedAddresses().contains(addr));
-    }
-
-    private void assertDeclined(Inet4Address addr) {
-        assertTrue("Address is not declined: " + addr, mRepo.getDeclinedAddresses().contains(addr));
-    }
-}
diff --git a/packages/NetworkStack/tests/unit/src/android/net/dhcp/DhcpPacketTest.java b/packages/NetworkStack/tests/unit/src/android/net/dhcp/DhcpPacketTest.java
deleted file mode 100644
index a30d3e4..0000000
--- a/packages/NetworkStack/tests/unit/src/android/net/dhcp/DhcpPacketTest.java
+++ /dev/null
@@ -1,1117 +0,0 @@
-/*
- * Copyright (C) 2015 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.net.dhcp;
-
-import static android.net.dhcp.DhcpPacket.DHCP_BROADCAST_ADDRESS;
-import static android.net.dhcp.DhcpPacket.DHCP_DNS_SERVER;
-import static android.net.dhcp.DhcpPacket.DHCP_DOMAIN_NAME;
-import static android.net.dhcp.DhcpPacket.DHCP_LEASE_TIME;
-import static android.net.dhcp.DhcpPacket.DHCP_MESSAGE_TYPE_ACK;
-import static android.net.dhcp.DhcpPacket.DHCP_MESSAGE_TYPE_OFFER;
-import static android.net.dhcp.DhcpPacket.DHCP_MTU;
-import static android.net.dhcp.DhcpPacket.DHCP_REBINDING_TIME;
-import static android.net.dhcp.DhcpPacket.DHCP_RENEWAL_TIME;
-import static android.net.dhcp.DhcpPacket.DHCP_ROUTER;
-import static android.net.dhcp.DhcpPacket.DHCP_SUBNET_MASK;
-import static android.net.dhcp.DhcpPacket.DHCP_VENDOR_INFO;
-import static android.net.dhcp.DhcpPacket.ENCAP_BOOTP;
-import static android.net.dhcp.DhcpPacket.ENCAP_L2;
-import static android.net.dhcp.DhcpPacket.ENCAP_L3;
-import static android.net.dhcp.DhcpPacket.INADDR_ANY;
-import static android.net.dhcp.DhcpPacket.INFINITE_LEASE;
-import static android.net.dhcp.DhcpPacket.ParseException;
-import static android.net.shared.Inet4AddressUtils.getBroadcastAddress;
-import static android.net.shared.Inet4AddressUtils.getPrefixMaskAsInet4Address;
-
-import static org.junit.Assert.assertEquals;
-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.annotation.Nullable;
-import android.net.DhcpResults;
-import android.net.LinkAddress;
-import android.net.NetworkUtils;
-import android.net.metrics.DhcpErrorEvent;
-
-import androidx.test.filters.SmallTest;
-import androidx.test.runner.AndroidJUnit4;
-
-import com.android.internal.util.HexDump;
-
-import org.junit.Before;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-
-import java.io.ByteArrayOutputStream;
-import java.net.Inet4Address;
-import java.nio.ByteBuffer;
-import java.nio.charset.Charset;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Collections;
-import java.util.Random;
-
-@RunWith(AndroidJUnit4.class)
-@SmallTest
-public class DhcpPacketTest {
-
-    private static final Inet4Address SERVER_ADDR = v4Address("192.0.2.1");
-    private static final Inet4Address CLIENT_ADDR = v4Address("192.0.2.234");
-    private static final int PREFIX_LENGTH = 22;
-    private static final Inet4Address NETMASK = getPrefixMaskAsInet4Address(PREFIX_LENGTH);
-    private static final Inet4Address BROADCAST_ADDR = getBroadcastAddress(
-            SERVER_ADDR, PREFIX_LENGTH);
-    private static final String HOSTNAME = "testhostname";
-    private static final short MTU = 1500;
-    // Use our own empty address instead of IPV4_ADDR_ANY or INADDR_ANY to ensure that the code
-    // doesn't use == instead of equals when comparing addresses.
-    private static final Inet4Address ANY = v4Address("0.0.0.0");
-
-    private static final byte[] CLIENT_MAC = new byte[] { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05 };
-
-    private static final Inet4Address v4Address(String addrString) throws IllegalArgumentException {
-        return (Inet4Address) NetworkUtils.numericToInetAddress(addrString);
-    }
-
-    @Before
-    public void setUp() {
-        DhcpPacket.testOverrideVendorId = "android-dhcp-???";
-        DhcpPacket.testOverrideHostname = "android-01234567890abcde";
-    }
-
-    class TestDhcpPacket extends DhcpPacket {
-        private byte mType;
-        // TODO: Make this a map of option numbers to bytes instead.
-        private byte[] mDomainBytes, mVendorInfoBytes, mLeaseTimeBytes, mNetmaskBytes;
-
-        public TestDhcpPacket(byte type, Inet4Address clientIp, Inet4Address yourIp) {
-            super(0xdeadbeef, (short) 0, clientIp, yourIp, INADDR_ANY, INADDR_ANY,
-                  CLIENT_MAC, true);
-            mType = type;
-        }
-
-        public TestDhcpPacket(byte type) {
-            this(type, INADDR_ANY, CLIENT_ADDR);
-        }
-
-        public TestDhcpPacket setDomainBytes(byte[] domainBytes) {
-            mDomainBytes = domainBytes;
-            return this;
-        }
-
-        public TestDhcpPacket setVendorInfoBytes(byte[] vendorInfoBytes) {
-            mVendorInfoBytes = vendorInfoBytes;
-            return this;
-        }
-
-        public TestDhcpPacket setLeaseTimeBytes(byte[] leaseTimeBytes) {
-            mLeaseTimeBytes = leaseTimeBytes;
-            return this;
-        }
-
-        public TestDhcpPacket setNetmaskBytes(byte[] netmaskBytes) {
-            mNetmaskBytes = netmaskBytes;
-            return this;
-        }
-
-        public ByteBuffer buildPacket(int encap, short unusedDestUdp, short unusedSrcUdp) {
-            ByteBuffer result = ByteBuffer.allocate(MAX_LENGTH);
-            fillInPacket(encap, CLIENT_ADDR, SERVER_ADDR,
-                         DHCP_CLIENT, DHCP_SERVER, result, DHCP_BOOTREPLY, false);
-            return result;
-        }
-
-        public void finishPacket(ByteBuffer buffer) {
-            addTlv(buffer, DHCP_MESSAGE_TYPE, mType);
-            if (mDomainBytes != null) {
-                addTlv(buffer, DHCP_DOMAIN_NAME, mDomainBytes);
-            }
-            if (mVendorInfoBytes != null) {
-                addTlv(buffer, DHCP_VENDOR_INFO, mVendorInfoBytes);
-            }
-            if (mLeaseTimeBytes != null) {
-                addTlv(buffer, DHCP_LEASE_TIME, mLeaseTimeBytes);
-            }
-            if (mNetmaskBytes != null) {
-                addTlv(buffer, DHCP_SUBNET_MASK, mNetmaskBytes);
-            }
-            addTlvEnd(buffer);
-        }
-
-        // Convenience method.
-        public ByteBuffer build() {
-            // ENCAP_BOOTP packets don't contain ports, so just pass in 0.
-            ByteBuffer pkt = buildPacket(ENCAP_BOOTP, (short) 0, (short) 0);
-            pkt.flip();
-            return pkt;
-        }
-    }
-
-    private void assertDomainAndVendorInfoParses(
-            String expectedDomain, byte[] domainBytes,
-            String expectedVendorInfo, byte[] vendorInfoBytes) throws Exception {
-        ByteBuffer packet = new TestDhcpPacket(DHCP_MESSAGE_TYPE_OFFER)
-                .setDomainBytes(domainBytes)
-                .setVendorInfoBytes(vendorInfoBytes)
-                .build();
-        DhcpPacket offerPacket = DhcpPacket.decodeFullPacket(packet, ENCAP_BOOTP);
-        assertEquals(expectedDomain, offerPacket.mDomainName);
-        assertEquals(expectedVendorInfo, offerPacket.mVendorInfo);
-    }
-
-    @Test
-    public void testDomainName() throws Exception {
-        byte[] nullByte = new byte[] { 0x00 };
-        byte[] twoNullBytes = new byte[] { 0x00, 0x00 };
-        byte[] nonNullDomain = new byte[] {
-            (byte) 'g', (byte) 'o', (byte) 'o', (byte) '.', (byte) 'g', (byte) 'l'
-        };
-        byte[] trailingNullDomain = new byte[] {
-            (byte) 'g', (byte) 'o', (byte) 'o', (byte) '.', (byte) 'g', (byte) 'l', 0x00
-        };
-        byte[] embeddedNullsDomain = new byte[] {
-            (byte) 'g', (byte) 'o', (byte) 'o', 0x00, 0x00, (byte) 'g', (byte) 'l'
-        };
-        byte[] metered = "ANDROID_METERED".getBytes("US-ASCII");
-
-        byte[] meteredEmbeddedNull = metered.clone();
-        meteredEmbeddedNull[7] = (char) 0;
-
-        byte[] meteredTrailingNull = metered.clone();
-        meteredTrailingNull[meteredTrailingNull.length - 1] = (char) 0;
-
-        assertDomainAndVendorInfoParses("", nullByte, "\u0000", nullByte);
-        assertDomainAndVendorInfoParses("", twoNullBytes, "\u0000\u0000", twoNullBytes);
-        assertDomainAndVendorInfoParses("goo.gl", nonNullDomain, "ANDROID_METERED", metered);
-        assertDomainAndVendorInfoParses("goo", embeddedNullsDomain,
-                                        "ANDROID\u0000METERED", meteredEmbeddedNull);
-        assertDomainAndVendorInfoParses("goo.gl", trailingNullDomain,
-                                        "ANDROID_METERE\u0000", meteredTrailingNull);
-    }
-
-    private void assertLeaseTimeParses(boolean expectValid, Integer rawLeaseTime,
-            long leaseTimeMillis, byte[] leaseTimeBytes) throws Exception {
-        TestDhcpPacket testPacket = new TestDhcpPacket(DHCP_MESSAGE_TYPE_OFFER);
-        if (leaseTimeBytes != null) {
-            testPacket.setLeaseTimeBytes(leaseTimeBytes);
-        }
-        ByteBuffer packet = testPacket.build();
-        DhcpPacket offerPacket = null;
-
-        if (!expectValid) {
-            try {
-                offerPacket = DhcpPacket.decodeFullPacket(packet, ENCAP_BOOTP);
-                fail("Invalid packet parsed successfully: " + offerPacket);
-            } catch (ParseException expected) {
-            }
-            return;
-        }
-
-        offerPacket = DhcpPacket.decodeFullPacket(packet, ENCAP_BOOTP);
-        assertNotNull(offerPacket);
-        assertEquals(rawLeaseTime, offerPacket.mLeaseTime);
-        DhcpResults dhcpResults = offerPacket.toDhcpResults();  // Just check this doesn't crash.
-        assertEquals(leaseTimeMillis, offerPacket.getLeaseTimeMillis());
-    }
-
-    @Test
-    public void testLeaseTime() throws Exception {
-        byte[] noLease = null;
-        byte[] tooShortLease = new byte[] { 0x00, 0x00 };
-        byte[] tooLongLease = new byte[] { 0x00, 0x00, 0x00, 60, 0x01 };
-        byte[] zeroLease = new byte[] { 0x00, 0x00, 0x00, 0x00 };
-        byte[] tenSecondLease = new byte[] { 0x00, 0x00, 0x00, 10 };
-        byte[] oneMinuteLease = new byte[] { 0x00, 0x00, 0x00, 60 };
-        byte[] fiveMinuteLease = new byte[] { 0x00, 0x00, 0x01, 0x2c };
-        byte[] oneDayLease = new byte[] { 0x00, 0x01, 0x51, (byte) 0x80 };
-        byte[] maxIntPlusOneLease = new byte[] { (byte) 0x80, 0x00, 0x00, 0x01 };
-        byte[] infiniteLease = new byte[] { (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff };
-
-        assertLeaseTimeParses(true, null, 0, noLease);
-        assertLeaseTimeParses(false, null, 0, tooShortLease);
-        assertLeaseTimeParses(false, null, 0, tooLongLease);
-        assertLeaseTimeParses(true, 0, 60 * 1000, zeroLease);
-        assertLeaseTimeParses(true, 10, 60 * 1000, tenSecondLease);
-        assertLeaseTimeParses(true, 60, 60 * 1000, oneMinuteLease);
-        assertLeaseTimeParses(true, 300, 300 * 1000, fiveMinuteLease);
-        assertLeaseTimeParses(true, 86400, 86400 * 1000, oneDayLease);
-        assertLeaseTimeParses(true, -2147483647, 2147483649L * 1000, maxIntPlusOneLease);
-        assertLeaseTimeParses(true, DhcpPacket.INFINITE_LEASE, 0, infiniteLease);
-    }
-
-    private void checkIpAddress(String expected, Inet4Address clientIp, Inet4Address yourIp,
-                                byte[] netmaskBytes) throws Exception {
-        checkIpAddress(expected, DHCP_MESSAGE_TYPE_OFFER, clientIp, yourIp, netmaskBytes);
-        checkIpAddress(expected, DHCP_MESSAGE_TYPE_ACK, clientIp, yourIp, netmaskBytes);
-    }
-
-    private void checkIpAddress(String expected, byte type,
-                                Inet4Address clientIp, Inet4Address yourIp,
-                                byte[] netmaskBytes) throws Exception {
-        ByteBuffer packet = new TestDhcpPacket(type, clientIp, yourIp)
-                .setNetmaskBytes(netmaskBytes)
-                .build();
-        DhcpPacket offerPacket = DhcpPacket.decodeFullPacket(packet, ENCAP_BOOTP);
-        DhcpResults results = offerPacket.toDhcpResults();
-
-        if (expected != null) {
-            LinkAddress expectedAddress = new LinkAddress(expected);
-            assertEquals(expectedAddress, results.ipAddress);
-        } else {
-            assertNull(results);
-        }
-    }
-
-    @Test
-    public void testIpAddress() throws Exception {
-        byte[] slash11Netmask = new byte[] { (byte) 0xff, (byte) 0xe0, 0x00, 0x00 };
-        byte[] slash24Netmask = new byte[] { (byte) 0xff, (byte) 0xff, (byte) 0xff, 0x00 };
-        byte[] invalidNetmask = new byte[] { (byte) 0xff, (byte) 0xfb, (byte) 0xff, 0x00 };
-        Inet4Address example1 = v4Address("192.0.2.1");
-        Inet4Address example2 = v4Address("192.0.2.43");
-
-        // A packet without any addresses is not valid.
-        checkIpAddress(null, ANY, ANY, slash24Netmask);
-
-        // ClientIP is used iff YourIP is not present.
-        checkIpAddress("192.0.2.1/24", example2, example1, slash24Netmask);
-        checkIpAddress("192.0.2.43/11", example2, ANY, slash11Netmask);
-        checkIpAddress("192.0.2.43/11", ANY, example2, slash11Netmask);
-
-        // Invalid netmasks are ignored.
-        checkIpAddress(null, example2, ANY, invalidNetmask);
-
-        // If there is no netmask, implicit netmasks are used.
-        checkIpAddress("192.0.2.43/24", ANY, example2, null);
-    }
-
-    private void assertDhcpResults(String ipAddress, String gateway, String dnsServersString,
-            String domains, String serverAddress, String serverHostName, String vendorInfo,
-            int leaseDuration, boolean hasMeteredHint, int mtu, DhcpResults dhcpResults)
-                    throws Exception {
-        assertEquals(new LinkAddress(ipAddress), dhcpResults.ipAddress);
-        assertEquals(v4Address(gateway), dhcpResults.gateway);
-
-        String[] dnsServerStrings = dnsServersString.split(",");
-        ArrayList dnsServers = new ArrayList();
-        for (String dnsServerString : dnsServerStrings) {
-            dnsServers.add(v4Address(dnsServerString));
-        }
-        assertEquals(dnsServers, dhcpResults.dnsServers);
-
-        assertEquals(domains, dhcpResults.domains);
-        assertEquals(v4Address(serverAddress), dhcpResults.serverAddress);
-        assertEquals(serverHostName, dhcpResults.serverHostName);
-        assertEquals(vendorInfo, dhcpResults.vendorInfo);
-        assertEquals(leaseDuration, dhcpResults.leaseDuration);
-        assertEquals(hasMeteredHint, dhcpResults.hasMeteredHint());
-        assertEquals(mtu, dhcpResults.mtu);
-    }
-
-    @Test
-    public void testOffer1() throws Exception {
-        // TODO: Turn all of these into golden files. This will probably require using
-        // androidx.test.InstrumentationRegistry for obtaining a Context object
-        // to read such golden files, along with an appropriate Android.mk.
-        // CHECKSTYLE:OFF Generated code
-        final ByteBuffer packet = ByteBuffer.wrap(HexDump.hexStringToByteArray(
-            // IP header.
-            "451001480000000080118849c0a89003c0a89ff7" +
-            // UDP header.
-            "004300440134dcfa" +
-            // BOOTP header.
-            "02010600c997a63b0000000000000000c0a89ff70000000000000000" +
-            // MAC address.
-            "30766ff2a90c00000000000000000000" +
-            // Server name.
-            "0000000000000000000000000000000000000000000000000000000000000000" +
-            "0000000000000000000000000000000000000000000000000000000000000000" +
-            // File.
-            "0000000000000000000000000000000000000000000000000000000000000000" +
-            "0000000000000000000000000000000000000000000000000000000000000000" +
-            "0000000000000000000000000000000000000000000000000000000000000000" +
-            "0000000000000000000000000000000000000000000000000000000000000000" +
-            // Options
-            "638253633501023604c0a89003330400001c200104fffff0000304c0a89ffe06080808080808080404" +
-            "3a0400000e103b040000189cff00000000000000000000"));
-        // CHECKSTYLE:ON Generated code
-
-        DhcpPacket offerPacket = DhcpPacket.decodeFullPacket(packet, ENCAP_L3);
-        assertTrue(offerPacket instanceof DhcpOfferPacket);  // Implicitly checks it's non-null.
-        DhcpResults dhcpResults = offerPacket.toDhcpResults();
-        assertDhcpResults("192.168.159.247/20", "192.168.159.254", "8.8.8.8,8.8.4.4",
-                null, "192.168.144.3", "", null, 7200, false, 0, dhcpResults);
-    }
-
-    @Test
-    public void testOffer2() throws Exception {
-        // CHECKSTYLE:OFF Generated code
-        final ByteBuffer packet = ByteBuffer.wrap(HexDump.hexStringToByteArray(
-            // IP header.
-            "450001518d0600004011144dc0a82b01c0a82bf7" +
-            // UDP header.
-            "00430044013d9ac7" +
-            // BOOTP header.
-            "02010600dfc23d1f0002000000000000c0a82bf7c0a82b0100000000" +
-            // MAC address.
-            "30766ff2a90c00000000000000000000" +
-            // Server name ("dhcp.android.com" plus invalid "AAAA" after null terminator).
-            "646863702e616e64726f69642e636f6d00000000000000000000000000000000" +
-            "0000000000004141414100000000000000000000000000000000000000000000" +
-            // File.
-            "0000000000000000000000000000000000000000000000000000000000000000" +
-            "0000000000000000000000000000000000000000000000000000000000000000" +
-            "0000000000000000000000000000000000000000000000000000000000000000" +
-            "0000000000000000000000000000000000000000000000000000000000000000" +
-            // Options
-            "638253633501023604c0a82b01330400000e103a04000007083b0400000c4e0104ffffff00" +
-            "1c04c0a82bff0304c0a82b010604c0a82b012b0f414e44524f49445f4d455445524544ff"));
-        // CHECKSTYLE:ON Generated code
-
-        assertEquals(337, packet.limit());
-        DhcpPacket offerPacket = DhcpPacket.decodeFullPacket(packet, ENCAP_L3);
-        assertTrue(offerPacket instanceof DhcpOfferPacket);  // Implicitly checks it's non-null.
-        DhcpResults dhcpResults = offerPacket.toDhcpResults();
-        assertDhcpResults("192.168.43.247/24", "192.168.43.1", "192.168.43.1",
-                null, "192.168.43.1", "dhcp.android.com", "ANDROID_METERED", 3600, true, 0,
-                dhcpResults);
-        assertTrue(dhcpResults.hasMeteredHint());
-    }
-
-    @Test
-    public void testBadIpPacket() throws Exception {
-        final byte[] packet = HexDump.hexStringToByteArray(
-            // IP header.
-            "450001518d0600004011144dc0a82b01c0a82bf7");
-
-        try {
-            DhcpPacket offerPacket = DhcpPacket.decodeFullPacket(packet, packet.length, ENCAP_L3);
-        } catch (DhcpPacket.ParseException expected) {
-            assertDhcpErrorCodes(DhcpErrorEvent.L3_TOO_SHORT, expected.errorCode);
-            return;
-        }
-        fail("Dhcp packet parsing should have failed");
-    }
-
-    @Test
-    public void testBadDhcpPacket() throws Exception {
-        final byte[] packet = HexDump.hexStringToByteArray(
-            // IP header.
-            "450001518d0600004011144dc0a82b01c0a82bf7" +
-            // UDP header.
-            "00430044013d9ac7" +
-            // BOOTP header.
-            "02010600dfc23d1f0002000000000000c0a82bf7c0a82b0100000000");
-
-        try {
-            DhcpPacket offerPacket = DhcpPacket.decodeFullPacket(packet, packet.length, ENCAP_L3);
-        } catch (DhcpPacket.ParseException expected) {
-            assertDhcpErrorCodes(DhcpErrorEvent.L3_TOO_SHORT, expected.errorCode);
-            return;
-        }
-        fail("Dhcp packet parsing should have failed");
-    }
-
-    @Test
-    public void testBadTruncatedOffer() throws Exception {
-        final byte[] packet = HexDump.hexStringToByteArray(
-            // IP header.
-            "450001518d0600004011144dc0a82b01c0a82bf7" +
-            // UDP header.
-            "00430044013d9ac7" +
-            // BOOTP header.
-            "02010600dfc23d1f0002000000000000c0a82bf7c0a82b0100000000" +
-            // MAC address.
-            "30766ff2a90c00000000000000000000" +
-            // Server name.
-            "0000000000000000000000000000000000000000000000000000000000000000" +
-            "0000000000000000000000000000000000000000000000000000000000000000" +
-            // File, missing one byte
-            "0000000000000000000000000000000000000000000000000000000000000000" +
-            "0000000000000000000000000000000000000000000000000000000000000000" +
-            "0000000000000000000000000000000000000000000000000000000000000000" +
-            "00000000000000000000000000000000000000000000000000000000000000");
-
-        try {
-            DhcpPacket offerPacket = DhcpPacket.decodeFullPacket(packet, packet.length, ENCAP_L3);
-        } catch (DhcpPacket.ParseException expected) {
-            assertDhcpErrorCodes(DhcpErrorEvent.L3_TOO_SHORT, expected.errorCode);
-            return;
-        }
-        fail("Dhcp packet parsing should have failed");
-    }
-
-    @Test
-    public void testBadOfferWithoutACookie() throws Exception {
-        final byte[] packet = HexDump.hexStringToByteArray(
-            // IP header.
-            "450001518d0600004011144dc0a82b01c0a82bf7" +
-            // UDP header.
-            "00430044013d9ac7" +
-            // BOOTP header.
-            "02010600dfc23d1f0002000000000000c0a82bf7c0a82b0100000000" +
-            // MAC address.
-            "30766ff2a90c00000000000000000000" +
-            // Server name.
-            "0000000000000000000000000000000000000000000000000000000000000000" +
-            "0000000000000000000000000000000000000000000000000000000000000000" +
-            // File.
-            "0000000000000000000000000000000000000000000000000000000000000000" +
-            "0000000000000000000000000000000000000000000000000000000000000000" +
-            "0000000000000000000000000000000000000000000000000000000000000000" +
-            "0000000000000000000000000000000000000000000000000000000000000000"
-            // No options
-            );
-
-        try {
-            DhcpPacket offerPacket = DhcpPacket.decodeFullPacket(packet, packet.length, ENCAP_L3);
-        } catch (DhcpPacket.ParseException expected) {
-            assertDhcpErrorCodes(DhcpErrorEvent.DHCP_NO_COOKIE, expected.errorCode);
-            return;
-        }
-        fail("Dhcp packet parsing should have failed");
-    }
-
-    @Test
-    public void testOfferWithBadCookie() throws Exception {
-        final byte[] packet = HexDump.hexStringToByteArray(
-            // IP header.
-            "450001518d0600004011144dc0a82b01c0a82bf7" +
-            // UDP header.
-            "00430044013d9ac7" +
-            // BOOTP header.
-            "02010600dfc23d1f0002000000000000c0a82bf7c0a82b0100000000" +
-            // MAC address.
-            "30766ff2a90c00000000000000000000" +
-            // Server name.
-            "0000000000000000000000000000000000000000000000000000000000000000" +
-            "0000000000000000000000000000000000000000000000000000000000000000" +
-            // File.
-            "0000000000000000000000000000000000000000000000000000000000000000" +
-            "0000000000000000000000000000000000000000000000000000000000000000" +
-            "0000000000000000000000000000000000000000000000000000000000000000" +
-            "0000000000000000000000000000000000000000000000000000000000000000" +
-            // Bad cookie
-            "DEADBEEF3501023604c0a82b01330400000e103a04000007083b0400000c4e0104ffffff00" +
-            "1c04c0a82bff0304c0a82b010604c0a82b012b0f414e44524f49445f4d455445524544ff");
-
-        try {
-            DhcpPacket offerPacket = DhcpPacket.decodeFullPacket(packet, packet.length, ENCAP_L3);
-        } catch (DhcpPacket.ParseException expected) {
-            assertDhcpErrorCodes(DhcpErrorEvent.DHCP_BAD_MAGIC_COOKIE, expected.errorCode);
-            return;
-        }
-        fail("Dhcp packet parsing should have failed");
-    }
-
-    private void assertDhcpErrorCodes(int expected, int got) {
-        assertEquals(Integer.toHexString(expected), Integer.toHexString(got));
-    }
-
-    @Test
-    public void testTruncatedOfferPackets() throws Exception {
-        final byte[] packet = HexDump.hexStringToByteArray(
-            // IP header.
-            "450001518d0600004011144dc0a82b01c0a82bf7" +
-            // UDP header.
-            "00430044013d9ac7" +
-            // BOOTP header.
-            "02010600dfc23d1f0002000000000000c0a82bf7c0a82b0100000000" +
-            // MAC address.
-            "30766ff2a90c00000000000000000000" +
-            // Server name.
-            "0000000000000000000000000000000000000000000000000000000000000000" +
-            "0000000000000000000000000000000000000000000000000000000000000000" +
-            // File.
-            "0000000000000000000000000000000000000000000000000000000000000000" +
-            "0000000000000000000000000000000000000000000000000000000000000000" +
-            "0000000000000000000000000000000000000000000000000000000000000000" +
-            "0000000000000000000000000000000000000000000000000000000000000000" +
-            // Options
-            "638253633501023604c0a82b01330400000e103a04000007083b0400000c4e0104ffffff00" +
-            "1c04c0a82bff0304c0a82b010604c0a82b012b0f414e44524f49445f4d455445524544ff");
-
-        for (int len = 0; len < packet.length; len++) {
-            try {
-                DhcpPacket.decodeFullPacket(packet, len, ENCAP_L3);
-            } catch (ParseException e) {
-                if (e.errorCode == DhcpErrorEvent.PARSING_ERROR) {
-                    fail(String.format("bad truncated packet of length %d", len));
-                }
-            }
-        }
-    }
-
-    @Test
-    public void testRandomPackets() throws Exception {
-        final int maxRandomPacketSize = 512;
-        final Random r = new Random();
-        for (int i = 0; i < 10000; i++) {
-            byte[] packet = new byte[r.nextInt(maxRandomPacketSize + 1)];
-            r.nextBytes(packet);
-            try {
-                DhcpPacket.decodeFullPacket(packet, packet.length, ENCAP_L3);
-            } catch (ParseException e) {
-                if (e.errorCode == DhcpErrorEvent.PARSING_ERROR) {
-                    fail("bad packet: " + HexDump.toHexString(packet));
-                }
-            }
-        }
-    }
-
-    private byte[] mtuBytes(int mtu) {
-        // 0x1a02: option 26, length 2. 0xff: no more options.
-        if (mtu > Short.MAX_VALUE - Short.MIN_VALUE) {
-            throw new IllegalArgumentException(
-                String.format("Invalid MTU %d, must be 16-bit unsigned", mtu));
-        }
-        String hexString = String.format("1a02%04xff", mtu);
-        return HexDump.hexStringToByteArray(hexString);
-    }
-
-    private void checkMtu(ByteBuffer packet, int expectedMtu, byte[] mtuBytes) throws Exception {
-        if (mtuBytes != null) {
-            packet.position(packet.capacity() - mtuBytes.length);
-            packet.put(mtuBytes);
-            packet.clear();
-        }
-        DhcpPacket offerPacket = DhcpPacket.decodeFullPacket(packet, ENCAP_L3);
-        assertTrue(offerPacket instanceof DhcpOfferPacket);  // Implicitly checks it's non-null.
-        DhcpResults dhcpResults = offerPacket.toDhcpResults();
-        assertDhcpResults("192.168.159.247/20", "192.168.159.254", "8.8.8.8,8.8.4.4",
-                null, "192.168.144.3", "", null, 7200, false, expectedMtu, dhcpResults);
-    }
-
-    @Test
-    public void testMtu() throws Exception {
-        // CHECKSTYLE:OFF Generated code
-        final ByteBuffer packet = ByteBuffer.wrap(HexDump.hexStringToByteArray(
-            // IP header.
-            "451001480000000080118849c0a89003c0a89ff7" +
-            // UDP header.
-            "004300440134dcfa" +
-            // BOOTP header.
-            "02010600c997a63b0000000000000000c0a89ff70000000000000000" +
-            // MAC address.
-            "30766ff2a90c00000000000000000000" +
-            // Server name.
-            "0000000000000000000000000000000000000000000000000000000000000000" +
-            "0000000000000000000000000000000000000000000000000000000000000000" +
-            // File.
-            "0000000000000000000000000000000000000000000000000000000000000000" +
-            "0000000000000000000000000000000000000000000000000000000000000000" +
-            "0000000000000000000000000000000000000000000000000000000000000000" +
-            "0000000000000000000000000000000000000000000000000000000000000000" +
-            // Options
-            "638253633501023604c0a89003330400001c200104fffff0000304c0a89ffe06080808080808080404" +
-            "3a0400000e103b040000189cff00000000"));
-        // CHECKSTYLE:ON Generated code
-
-        checkMtu(packet, 0, null);
-        checkMtu(packet, 0, mtuBytes(1501));
-        checkMtu(packet, 1500, mtuBytes(1500));
-        checkMtu(packet, 1499, mtuBytes(1499));
-        checkMtu(packet, 1280, mtuBytes(1280));
-        checkMtu(packet, 0, mtuBytes(1279));
-        checkMtu(packet, 0, mtuBytes(576));
-        checkMtu(packet, 0, mtuBytes(68));
-        checkMtu(packet, 0, mtuBytes(Short.MIN_VALUE));
-        checkMtu(packet, 0, mtuBytes(Short.MAX_VALUE + 3));
-        checkMtu(packet, 0, mtuBytes(-1));
-    }
-
-    @Test
-    public void testBadHwaddrLength() throws Exception {
-        // CHECKSTYLE:OFF Generated code
-        final ByteBuffer packet = ByteBuffer.wrap(HexDump.hexStringToByteArray(
-            // IP header.
-            "450001518d0600004011144dc0a82b01c0a82bf7" +
-            // UDP header.
-            "00430044013d9ac7" +
-            // BOOTP header.
-            "02010600dfc23d1f0002000000000000c0a82bf7c0a82b0100000000" +
-            // MAC address.
-            "30766ff2a90c00000000000000000000" +
-            // Server name.
-            "0000000000000000000000000000000000000000000000000000000000000000" +
-            "0000000000000000000000000000000000000000000000000000000000000000" +
-            // File.
-            "0000000000000000000000000000000000000000000000000000000000000000" +
-            "0000000000000000000000000000000000000000000000000000000000000000" +
-            "0000000000000000000000000000000000000000000000000000000000000000" +
-            "0000000000000000000000000000000000000000000000000000000000000000" +
-            // Options
-            "638253633501023604c0a82b01330400000e103a04000007083b0400000c4e0104ffffff00" +
-            "1c04c0a82bff0304c0a82b010604c0a82b012b0f414e44524f49445f4d455445524544ff"));
-        // CHECKSTYLE:ON Generated code
-        String expectedClientMac = "30766FF2A90C";
-
-        final int hwAddrLenOffset = 20 + 8 + 2;
-        assertEquals(6, packet.get(hwAddrLenOffset));
-
-        // Expect the expected.
-        DhcpPacket offerPacket = DhcpPacket.decodeFullPacket(packet, ENCAP_L3);
-        assertNotNull(offerPacket);
-        assertEquals(6, offerPacket.getClientMac().length);
-        assertEquals(expectedClientMac, HexDump.toHexString(offerPacket.getClientMac()));
-
-        // Reduce the hardware address length and verify that it shortens the client MAC.
-        packet.flip();
-        packet.put(hwAddrLenOffset, (byte) 5);
-        offerPacket = DhcpPacket.decodeFullPacket(packet, ENCAP_L3);
-        assertNotNull(offerPacket);
-        assertEquals(5, offerPacket.getClientMac().length);
-        assertEquals(expectedClientMac.substring(0, 10),
-                HexDump.toHexString(offerPacket.getClientMac()));
-
-        packet.flip();
-        packet.put(hwAddrLenOffset, (byte) 3);
-        offerPacket = DhcpPacket.decodeFullPacket(packet, ENCAP_L3);
-        assertNotNull(offerPacket);
-        assertEquals(3, offerPacket.getClientMac().length);
-        assertEquals(expectedClientMac.substring(0, 6),
-                HexDump.toHexString(offerPacket.getClientMac()));
-
-        // Set the the hardware address length to 0xff and verify that we a) don't treat it as -1
-        // and crash, and b) hardcode it to 6.
-        packet.flip();
-        packet.put(hwAddrLenOffset, (byte) -1);
-        offerPacket = DhcpPacket.decodeFullPacket(packet, ENCAP_L3);
-        assertNotNull(offerPacket);
-        assertEquals(6, offerPacket.getClientMac().length);
-        assertEquals(expectedClientMac, HexDump.toHexString(offerPacket.getClientMac()));
-
-        // Set the the hardware address length to a positive invalid value (> 16) and verify that we
-        // hardcode it to 6.
-        packet.flip();
-        packet.put(hwAddrLenOffset, (byte) 17);
-        offerPacket = DhcpPacket.decodeFullPacket(packet, ENCAP_L3);
-        assertNotNull(offerPacket);
-        assertEquals(6, offerPacket.getClientMac().length);
-        assertEquals(expectedClientMac, HexDump.toHexString(offerPacket.getClientMac()));
-    }
-
-    @Test
-    public void testPadAndOverloadedOptionsOffer() throws Exception {
-        // A packet observed in the real world that is interesting for two reasons:
-        //
-        // 1. It uses pad bytes, which we previously didn't support correctly.
-        // 2. It uses DHCP option overloading, which we don't currently support (but it doesn't
-        //    store any information in the overloaded fields).
-        //
-        // For now, we just check that it parses correctly.
-        // CHECKSTYLE:OFF Generated code
-        final ByteBuffer packet = ByteBuffer.wrap(HexDump.hexStringToByteArray(
-            // Ethernet header.
-            "b4cef6000000e80462236e300800" +
-            // IP header.
-            "4500014c00000000ff11741701010101ac119876" +
-            // UDP header. TODO: fix invalid checksum (due to MAC address obfuscation).
-            "004300440138ae5a" +
-            // BOOTP header.
-            "020106000fa0059f0000000000000000ac1198760000000000000000" +
-            // MAC address.
-            "b4cef600000000000000000000000000" +
-            // Server name.
-            "ff00000000000000000000000000000000000000000000000000000000000000" +
-            "0000000000000000000000000000000000000000000000000000000000000000" +
-            // File.
-            "ff00000000000000000000000000000000000000000000000000000000000000" +
-            "0000000000000000000000000000000000000000000000000000000000000000" +
-            "0000000000000000000000000000000000000000000000000000000000000000" +
-            "0000000000000000000000000000000000000000000000000000000000000000" +
-            // Options
-            "638253633501023604010101010104ffff000033040000a8c03401030304ac1101010604ac110101" +
-            "0000000000000000000000000000000000000000000000ff000000"));
-        // CHECKSTYLE:ON Generated code
-
-        DhcpPacket offerPacket = DhcpPacket.decodeFullPacket(packet, ENCAP_L2);
-        assertTrue(offerPacket instanceof DhcpOfferPacket);
-        DhcpResults dhcpResults = offerPacket.toDhcpResults();
-        assertDhcpResults("172.17.152.118/16", "172.17.1.1", "172.17.1.1",
-                null, "1.1.1.1", "", null, 43200, false, 0, dhcpResults);
-    }
-
-    @Test
-    public void testBug2111() throws Exception {
-        // CHECKSTYLE:OFF Generated code
-        final ByteBuffer packet = ByteBuffer.wrap(HexDump.hexStringToByteArray(
-            // IP header.
-            "4500014c00000000ff119beac3eaf3880a3f5d04" +
-            // UDP header. TODO: fix invalid checksum (due to MAC address obfuscation).
-            "0043004401387464" +
-            // BOOTP header.
-            "0201060002554812000a0000000000000a3f5d040000000000000000" +
-            // MAC address.
-            "00904c00000000000000000000000000" +
-            // Server name.
-            "0000000000000000000000000000000000000000000000000000000000000000" +
-            "0000000000000000000000000000000000000000000000000000000000000000" +
-            // File.
-            "0000000000000000000000000000000000000000000000000000000000000000" +
-            "0000000000000000000000000000000000000000000000000000000000000000" +
-            "0000000000000000000000000000000000000000000000000000000000000000" +
-            "0000000000000000000000000000000000000000000000000000000000000000" +
-            // Options.
-            "638253633501023604c00002fe33040000bfc60104fffff00003040a3f50010608c0000201c0000202" +
-            "0f0f646f6d61696e3132332e636f2e756b0000000000ff00000000"));
-        // CHECKSTYLE:ON Generated code
-
-        DhcpPacket offerPacket = DhcpPacket.decodeFullPacket(packet, ENCAP_L3);
-        assertTrue(offerPacket instanceof DhcpOfferPacket);
-        DhcpResults dhcpResults = offerPacket.toDhcpResults();
-        assertDhcpResults("10.63.93.4/20", "10.63.80.1", "192.0.2.1,192.0.2.2",
-                "domain123.co.uk", "192.0.2.254", "", null, 49094, false, 0, dhcpResults);
-    }
-
-    @Test
-    public void testBug2136() throws Exception {
-        // CHECKSTYLE:OFF Generated code
-        final ByteBuffer packet = ByteBuffer.wrap(HexDump.hexStringToByteArray(
-            // Ethernet header.
-            "bcf5ac000000d0c7890000000800" +
-            // IP header.
-            "4500014c00000000ff119beac3eaf3880a3f5d04" +
-            // UDP header. TODO: fix invalid checksum (due to MAC address obfuscation).
-            "0043004401387574" +
-            // BOOTP header.
-            "0201060163339a3000050000000000000a209ecd0000000000000000" +
-            // MAC address.
-            "bcf5ac00000000000000000000000000" +
-            // Server name.
-            "0000000000000000000000000000000000000000000000000000000000000000" +
-            "0000000000000000000000000000000000000000000000000000000000000000" +
-            // File.
-            "0000000000000000000000000000000000000000000000000000000000000000" +
-            "0000000000000000000000000000000000000000000000000000000000000000" +
-            "0000000000000000000000000000000000000000000000000000000000000000" +
-            "0000000000000000000000000000000000000000000000000000000000000000" +
-            // Options.
-            "6382536335010236040a20ff80330400001c200104fffff00003040a20900106089458413494584135" +
-            "0f0b6c616e63732e61632e756b000000000000000000ff00000000"));
-        // CHECKSTYLE:ON Generated code
-
-        DhcpPacket offerPacket = DhcpPacket.decodeFullPacket(packet, ENCAP_L2);
-        assertTrue(offerPacket instanceof DhcpOfferPacket);
-        assertEquals("BCF5AC000000", HexDump.toHexString(offerPacket.getClientMac()));
-        DhcpResults dhcpResults = offerPacket.toDhcpResults();
-        assertDhcpResults("10.32.158.205/20", "10.32.144.1", "148.88.65.52,148.88.65.53",
-                "lancs.ac.uk", "10.32.255.128", "", null, 7200, false, 0, dhcpResults);
-    }
-
-    @Test
-    public void testUdpServerAnySourcePort() throws Exception {
-        // CHECKSTYLE:OFF Generated code
-        final ByteBuffer packet = ByteBuffer.wrap(HexDump.hexStringToByteArray(
-            // Ethernet header.
-            "9cd917000000001c2e0000000800" +
-            // IP header.
-            "45a00148000040003d115087d18194fb0a0f7af2" +
-            // UDP header. TODO: fix invalid checksum (due to MAC address obfuscation).
-            // NOTE: The server source port is not the canonical port 67.
-            "C29F004401341268" +
-            // BOOTP header.
-            "02010600d628ba8200000000000000000a0f7af2000000000a0fc818" +
-            // MAC address.
-            "9cd91700000000000000000000000000" +
-            // Server name.
-            "0000000000000000000000000000000000000000000000000000000000000000" +
-            "0000000000000000000000000000000000000000000000000000000000000000" +
-            // File.
-            "0000000000000000000000000000000000000000000000000000000000000000" +
-            "0000000000000000000000000000000000000000000000000000000000000000" +
-            "0000000000000000000000000000000000000000000000000000000000000000" +
-            "0000000000000000000000000000000000000000000000000000000000000000" +
-            // Options.
-            "6382536335010236040a0169fc3304000151800104ffff000003040a0fc817060cd1818003d1819403" +
-            "d18180060f0777766d2e6564751c040a0fffffff000000"));
-        // CHECKSTYLE:ON Generated code
-
-        DhcpPacket offerPacket = DhcpPacket.decodeFullPacket(packet, ENCAP_L2);
-        assertTrue(offerPacket instanceof DhcpOfferPacket);
-        assertEquals("9CD917000000", HexDump.toHexString(offerPacket.getClientMac()));
-        DhcpResults dhcpResults = offerPacket.toDhcpResults();
-        assertDhcpResults("10.15.122.242/16", "10.15.200.23",
-                "209.129.128.3,209.129.148.3,209.129.128.6",
-                "wvm.edu", "10.1.105.252", "", null, 86400, false, 0, dhcpResults);
-    }
-
-    @Test
-    public void testUdpInvalidDstPort() throws Exception {
-        // CHECKSTYLE:OFF Generated code
-        final ByteBuffer packet = ByteBuffer.wrap(HexDump.hexStringToByteArray(
-            // Ethernet header.
-            "9cd917000000001c2e0000000800" +
-            // IP header.
-            "45a00148000040003d115087d18194fb0a0f7af2" +
-            // UDP header. TODO: fix invalid checksum (due to MAC address obfuscation).
-            // NOTE: The destination port is a non-DHCP port.
-            "0043aaaa01341268" +
-            // BOOTP header.
-            "02010600d628ba8200000000000000000a0f7af2000000000a0fc818" +
-            // MAC address.
-            "9cd91700000000000000000000000000" +
-            // Server name.
-            "0000000000000000000000000000000000000000000000000000000000000000" +
-            "0000000000000000000000000000000000000000000000000000000000000000" +
-            // File.
-            "0000000000000000000000000000000000000000000000000000000000000000" +
-            "0000000000000000000000000000000000000000000000000000000000000000" +
-            "0000000000000000000000000000000000000000000000000000000000000000" +
-            "0000000000000000000000000000000000000000000000000000000000000000" +
-            // Options.
-            "6382536335010236040a0169fc3304000151800104ffff000003040a0fc817060cd1818003d1819403" +
-            "d18180060f0777766d2e6564751c040a0fffffff000000"));
-        // CHECKSTYLE:ON Generated code
-
-        try {
-            DhcpPacket.decodeFullPacket(packet, ENCAP_L2);
-            fail("Packet with invalid dst port did not throw ParseException");
-        } catch (ParseException expected) {}
-    }
-
-    @Test
-    public void testMultipleRouters() throws Exception {
-        // CHECKSTYLE:OFF Generated code
-        final ByteBuffer packet = ByteBuffer.wrap(HexDump.hexStringToByteArray(
-            // Ethernet header.
-            "fc3d93000000" + "081735000000" + "0800" +
-            // IP header.
-            "45000148c2370000ff117ac2c0a8bd02ffffffff" +
-            // UDP header. TODO: fix invalid checksum (due to MAC address obfuscation).
-            "0043004401343beb" +
-            // BOOTP header.
-            "0201060027f518e20000800000000000c0a8bd310000000000000000" +
-            // MAC address.
-            "fc3d9300000000000000000000000000" +
-            // Server name.
-            "0000000000000000000000000000000000000000000000000000000000000000" +
-            "0000000000000000000000000000000000000000000000000000000000000000" +
-            // File.
-            "0000000000000000000000000000000000000000000000000000000000000000" +
-            "0000000000000000000000000000000000000000000000000000000000000000" +
-            "0000000000000000000000000000000000000000000000000000000000000000" +
-            "0000000000000000000000000000000000000000000000000000000000000000" +
-            // Options.
-            "638253633501023604c0abbd023304000070803a04000038403b04000062700104ffffff00" +
-            "0308c0a8bd01ffffff0006080808080808080404ff000000000000"));
-        // CHECKSTYLE:ON Generated code
-
-        DhcpPacket offerPacket = DhcpPacket.decodeFullPacket(packet, ENCAP_L2);
-        assertTrue(offerPacket instanceof DhcpOfferPacket);
-        assertEquals("FC3D93000000", HexDump.toHexString(offerPacket.getClientMac()));
-        DhcpResults dhcpResults = offerPacket.toDhcpResults();
-        assertDhcpResults("192.168.189.49/24", "192.168.189.1", "8.8.8.8,8.8.4.4",
-                null, "192.171.189.2", "", null, 28800, false, 0, dhcpResults);
-    }
-
-    @Test
-    public void testDiscoverPacket() throws Exception {
-        short secs = 7;
-        int transactionId = 0xdeadbeef;
-        byte[] hwaddr = {
-                (byte) 0xda, (byte) 0x01, (byte) 0x19, (byte) 0x5b, (byte) 0xb1, (byte) 0x7a
-        };
-
-        ByteBuffer packet = DhcpPacket.buildDiscoverPacket(
-                DhcpPacket.ENCAP_L2, transactionId, secs, hwaddr,
-                false /* do unicast */, DhcpClient.REQUESTED_PARAMS);
-
-        byte[] headers = new byte[] {
-            // Ethernet header.
-            (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff,
-            (byte) 0xda, (byte) 0x01, (byte) 0x19, (byte) 0x5b, (byte) 0xb1, (byte) 0x7a,
-            (byte) 0x08, (byte) 0x00,
-            // IP header.
-            (byte) 0x45, (byte) 0x10, (byte) 0x01, (byte) 0x56,
-            (byte) 0x00, (byte) 0x00, (byte) 0x40, (byte) 0x00,
-            (byte) 0x40, (byte) 0x11, (byte) 0x39, (byte) 0x88,
-            (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00,
-            (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff,
-            // UDP header.
-            (byte) 0x00, (byte) 0x44, (byte) 0x00, (byte) 0x43,
-            (byte) 0x01, (byte) 0x42, (byte) 0x6a, (byte) 0x4a,
-            // BOOTP.
-            (byte) 0x01, (byte) 0x01, (byte) 0x06, (byte) 0x00,
-            (byte) 0xde, (byte) 0xad, (byte) 0xbe, (byte) 0xef,
-            (byte) 0x00, (byte) 0x07, (byte) 0x00, (byte) 0x00,
-            (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00,
-            (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00,
-            (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00,
-            (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00,
-            (byte) 0xda, (byte) 0x01, (byte) 0x19, (byte) 0x5b,
-            (byte) 0xb1, (byte) 0x7a
-        };
-        byte[] options = new byte[] {
-            // Magic cookie 0x63825363.
-            (byte) 0x63, (byte) 0x82, (byte) 0x53, (byte) 0x63,
-            // Message type DISCOVER.
-            (byte) 0x35, (byte) 0x01, (byte) 0x01,
-            // Client identifier Ethernet, da:01:19:5b:b1:7a.
-            (byte) 0x3d, (byte) 0x07,
-                    (byte) 0x01,
-                    (byte) 0xda, (byte) 0x01, (byte) 0x19, (byte) 0x5b, (byte) 0xb1, (byte) 0x7a,
-            // Max message size 1500.
-            (byte) 0x39, (byte) 0x02, (byte) 0x05, (byte) 0xdc,
-            // Version "android-dhcp-???".
-            (byte) 0x3c, (byte) 0x10,
-                    'a', 'n', 'd', 'r', 'o', 'i', 'd', '-', 'd', 'h', 'c', 'p', '-', '?', '?', '?',
-            // Hostname "android-01234567890abcde"
-            (byte) 0x0c, (byte) 0x18,
-                    'a', 'n', 'd', 'r', 'o', 'i', 'd', '-',
-                    '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', 'a', 'b', 'c', 'd', 'e',
-            // Requested parameter list.
-            (byte) 0x37, (byte) 0x0a,
-                DHCP_SUBNET_MASK,
-                DHCP_ROUTER,
-                DHCP_DNS_SERVER,
-                DHCP_DOMAIN_NAME,
-                DHCP_MTU,
-                DHCP_BROADCAST_ADDRESS,
-                DHCP_LEASE_TIME,
-                DHCP_RENEWAL_TIME,
-                DHCP_REBINDING_TIME,
-                DHCP_VENDOR_INFO,
-            // End options.
-            (byte) 0xff,
-            // Our packets are always of even length. TODO: find out why and possibly fix it.
-            (byte) 0x00
-        };
-        byte[] expected = new byte[DhcpPacket.MIN_PACKET_LENGTH_L2 + options.length];
-        assertTrue((expected.length & 1) == 0);
-        System.arraycopy(headers, 0, expected, 0, headers.length);
-        System.arraycopy(options, 0, expected, DhcpPacket.MIN_PACKET_LENGTH_L2, options.length);
-
-        byte[] actual = new byte[packet.limit()];
-        packet.get(actual);
-        String msg =
-                "Expected:\n  " + Arrays.toString(expected) +
-                "\nActual:\n  " + Arrays.toString(actual);
-        assertTrue(msg, Arrays.equals(expected, actual));
-    }
-
-    public void checkBuildOfferPacket(int leaseTimeSecs, @Nullable String hostname)
-            throws Exception {
-        final int renewalTime = (int) (Integer.toUnsignedLong(leaseTimeSecs) / 2);
-        final int rebindingTime = (int) (Integer.toUnsignedLong(leaseTimeSecs) * 875 / 1000);
-        final int transactionId = 0xdeadbeef;
-
-        final ByteBuffer packet = DhcpPacket.buildOfferPacket(
-                DhcpPacket.ENCAP_BOOTP, transactionId, false /* broadcast */,
-                SERVER_ADDR, INADDR_ANY /* relayIp */, CLIENT_ADDR /* yourIp */,
-                CLIENT_MAC, leaseTimeSecs, NETMASK /* netMask */,
-                BROADCAST_ADDR /* bcAddr */, Collections.singletonList(SERVER_ADDR) /* gateways */,
-                Collections.singletonList(SERVER_ADDR) /* dnsServers */,
-                SERVER_ADDR /* dhcpServerIdentifier */, null /* domainName */, hostname,
-                false /* metered */, MTU);
-
-        ByteArrayOutputStream bos = new ByteArrayOutputStream();
-        // BOOTP headers
-        bos.write(new byte[] {
-                (byte) 0x02, (byte) 0x01, (byte) 0x06, (byte) 0x00,
-                (byte) 0xde, (byte) 0xad, (byte) 0xbe, (byte) 0xef,
-                (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00,
-                // ciaddr
-                (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00,
-        });
-        // yiaddr
-        bos.write(CLIENT_ADDR.getAddress());
-        // siaddr
-        bos.write(SERVER_ADDR.getAddress());
-        // giaddr
-        bos.write(INADDR_ANY.getAddress());
-        // chaddr
-        bos.write(CLIENT_MAC);
-
-        // Padding
-        bos.write(new byte[202]);
-
-        // Options
-        bos.write(new byte[]{
-                // Magic cookie 0x63825363.
-                (byte) 0x63, (byte) 0x82, (byte) 0x53, (byte) 0x63,
-                // Message type OFFER.
-                (byte) 0x35, (byte) 0x01, (byte) 0x02,
-        });
-        // Server ID
-        bos.write(new byte[] { (byte) 0x36, (byte) 0x04 });
-        bos.write(SERVER_ADDR.getAddress());
-        // Lease time
-        bos.write(new byte[] { (byte) 0x33, (byte) 0x04 });
-        bos.write(intToByteArray(leaseTimeSecs));
-        if (leaseTimeSecs != INFINITE_LEASE) {
-            // Renewal time
-            bos.write(new byte[]{(byte) 0x3a, (byte) 0x04});
-            bos.write(intToByteArray(renewalTime));
-            // Rebinding time
-            bos.write(new byte[]{(byte) 0x3b, (byte) 0x04});
-            bos.write(intToByteArray(rebindingTime));
-        }
-        // Subnet mask
-        bos.write(new byte[] { (byte) 0x01, (byte) 0x04 });
-        bos.write(NETMASK.getAddress());
-        // Broadcast address
-        bos.write(new byte[] { (byte) 0x1c, (byte) 0x04 });
-        bos.write(BROADCAST_ADDR.getAddress());
-        // Router
-        bos.write(new byte[] { (byte) 0x03, (byte) 0x04 });
-        bos.write(SERVER_ADDR.getAddress());
-        // Nameserver
-        bos.write(new byte[] { (byte) 0x06, (byte) 0x04 });
-        bos.write(SERVER_ADDR.getAddress());
-        // Hostname
-        if (hostname != null) {
-            bos.write(new byte[]{(byte) 0x0c, (byte) hostname.length()});
-            bos.write(hostname.getBytes(Charset.forName("US-ASCII")));
-        }
-        // MTU
-        bos.write(new byte[] { (byte) 0x1a, (byte) 0x02 });
-        bos.write(shortToByteArray(MTU));
-        // End options.
-        bos.write(0xff);
-
-        if ((bos.size() & 1) != 0) {
-            bos.write(0x00);
-        }
-
-        final byte[] expected = bos.toByteArray();
-        final byte[] actual = new byte[packet.limit()];
-        packet.get(actual);
-        final String msg = "Expected:\n  " + HexDump.dumpHexString(expected) +
-                "\nActual:\n  " + HexDump.dumpHexString(actual);
-        assertTrue(msg, Arrays.equals(expected, actual));
-    }
-
-    @Test
-    public void testOfferPacket() throws Exception {
-        checkBuildOfferPacket(3600, HOSTNAME);
-        checkBuildOfferPacket(Integer.MAX_VALUE, HOSTNAME);
-        checkBuildOfferPacket(0x80000000, HOSTNAME);
-        checkBuildOfferPacket(INFINITE_LEASE, HOSTNAME);
-        checkBuildOfferPacket(3600, null);
-    }
-
-    private static byte[] intToByteArray(int val) {
-        return ByteBuffer.allocate(4).putInt(val).array();
-    }
-
-    private static byte[] shortToByteArray(short val) {
-        return ByteBuffer.allocate(2).putShort(val).array();
-    }
-}
diff --git a/packages/NetworkStack/tests/unit/src/android/net/dhcp/DhcpServerTest.java b/packages/NetworkStack/tests/unit/src/android/net/dhcp/DhcpServerTest.java
deleted file mode 100644
index f0e2f1b..0000000
--- a/packages/NetworkStack/tests/unit/src/android/net/dhcp/DhcpServerTest.java
+++ /dev/null
@@ -1,333 +0,0 @@
-/*
- * Copyright (C) 2018 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.net.dhcp;
-
-import static android.net.InetAddresses.parseNumericAddress;
-import static android.net.dhcp.DhcpPacket.DHCP_CLIENT;
-import static android.net.dhcp.DhcpPacket.DHCP_HOST_NAME;
-import static android.net.dhcp.DhcpPacket.ENCAP_BOOTP;
-import static android.net.dhcp.DhcpPacket.INADDR_ANY;
-import static android.net.dhcp.DhcpPacket.INADDR_BROADCAST;
-import static android.net.dhcp.IDhcpServer.STATUS_SUCCESS;
-
-import static junit.framework.Assert.assertEquals;
-import static junit.framework.Assert.assertFalse;
-import static junit.framework.Assert.assertNotNull;
-import static junit.framework.Assert.assertTrue;
-
-import static org.mockito.ArgumentMatchers.any;
-import static org.mockito.ArgumentMatchers.anyBoolean;
-import static org.mockito.ArgumentMatchers.eq;
-import static org.mockito.ArgumentMatchers.isNull;
-import static org.mockito.Mockito.doNothing;
-import static org.mockito.Mockito.never;
-import static org.mockito.Mockito.spy;
-import static org.mockito.Mockito.times;
-import static org.mockito.Mockito.verify;
-import static org.mockito.Mockito.when;
-
-import android.annotation.NonNull;
-import android.annotation.Nullable;
-import android.net.INetworkStackStatusCallback;
-import android.net.LinkAddress;
-import android.net.MacAddress;
-import android.net.dhcp.DhcpLeaseRepository.InvalidAddressException;
-import android.net.dhcp.DhcpLeaseRepository.OutOfAddressesException;
-import android.net.dhcp.DhcpServer.Clock;
-import android.net.dhcp.DhcpServer.Dependencies;
-import android.net.util.SharedLog;
-import android.os.HandlerThread;
-import android.testing.AndroidTestingRunner;
-import android.testing.TestableLooper;
-import android.testing.TestableLooper.RunWithLooper;
-
-import androidx.test.filters.SmallTest;
-
-import org.junit.After;
-import org.junit.Before;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.mockito.ArgumentCaptor;
-import org.mockito.Captor;
-import org.mockito.Mock;
-import org.mockito.MockitoAnnotations;
-
-import java.net.Inet4Address;
-import java.nio.ByteBuffer;
-import java.util.Arrays;
-import java.util.HashSet;
-import java.util.Set;
-
-@RunWith(AndroidTestingRunner.class)
-@SmallTest
-@RunWithLooper
-public class DhcpServerTest {
-    private static final String TEST_IFACE = "testiface";
-
-    private static final Inet4Address TEST_SERVER_ADDR = parseAddr("192.168.0.2");
-    private static final LinkAddress TEST_SERVER_LINKADDR = new LinkAddress(TEST_SERVER_ADDR, 20);
-    private static final Set<Inet4Address> TEST_DEFAULT_ROUTERS = new HashSet<>(
-            Arrays.asList(parseAddr("192.168.0.123"), parseAddr("192.168.0.124")));
-    private static final Set<Inet4Address> TEST_DNS_SERVERS = new HashSet<>(
-            Arrays.asList(parseAddr("192.168.0.126"), parseAddr("192.168.0.127")));
-    private static final Set<Inet4Address> TEST_EXCLUDED_ADDRS = new HashSet<>(
-            Arrays.asList(parseAddr("192.168.0.200"), parseAddr("192.168.0.201")));
-    private static final long TEST_LEASE_TIME_SECS = 3600L;
-    private static final int TEST_MTU = 1500;
-    private static final String TEST_HOSTNAME = "testhostname";
-
-    private static final int TEST_TRANSACTION_ID = 123;
-    private static final byte[] TEST_CLIENT_MAC_BYTES = new byte [] { 1, 2, 3, 4, 5, 6 };
-    private static final MacAddress TEST_CLIENT_MAC = MacAddress.fromBytes(TEST_CLIENT_MAC_BYTES);
-    private static final Inet4Address TEST_CLIENT_ADDR = parseAddr("192.168.0.42");
-
-    private static final long TEST_CLOCK_TIME = 1234L;
-    private static final int TEST_LEASE_EXPTIME_SECS = 3600;
-    private static final DhcpLease TEST_LEASE = new DhcpLease(null, TEST_CLIENT_MAC,
-            TEST_CLIENT_ADDR, TEST_LEASE_EXPTIME_SECS * 1000L + TEST_CLOCK_TIME,
-            null /* hostname */);
-    private static final DhcpLease TEST_LEASE_WITH_HOSTNAME = new DhcpLease(null, TEST_CLIENT_MAC,
-            TEST_CLIENT_ADDR, TEST_LEASE_EXPTIME_SECS * 1000L + TEST_CLOCK_TIME, TEST_HOSTNAME);
-
-    @NonNull @Mock
-    private Dependencies mDeps;
-    @NonNull @Mock
-    private DhcpLeaseRepository mRepository;
-    @NonNull @Mock
-    private Clock mClock;
-    @NonNull @Mock
-    private DhcpPacketListener mPacketListener;
-
-    @NonNull @Captor
-    private ArgumentCaptor<ByteBuffer> mSentPacketCaptor;
-    @NonNull @Captor
-    private ArgumentCaptor<Inet4Address> mResponseDstAddrCaptor;
-
-    @NonNull
-    private HandlerThread mHandlerThread;
-    @NonNull
-    private TestableLooper mLooper;
-    @NonNull
-    private DhcpServer mServer;
-
-    @Nullable
-    private String mPrevShareClassloaderProp;
-
-    private final INetworkStackStatusCallback mAssertSuccessCallback =
-            new INetworkStackStatusCallback.Stub() {
-        @Override
-        public void onStatusAvailable(int statusCode) {
-            assertEquals(STATUS_SUCCESS, statusCode);
-        }
-
-        @Override
-        public int getInterfaceVersion() {
-            return this.VERSION;
-        }
-    };
-
-    @Before
-    public void setUp() throws Exception {
-        MockitoAnnotations.initMocks(this);
-
-        when(mDeps.makeLeaseRepository(any(), any(), any())).thenReturn(mRepository);
-        when(mDeps.makeClock()).thenReturn(mClock);
-        when(mDeps.makePacketListener()).thenReturn(mPacketListener);
-        doNothing().when(mDeps)
-                .sendPacket(any(), mSentPacketCaptor.capture(), mResponseDstAddrCaptor.capture());
-        when(mClock.elapsedRealtime()).thenReturn(TEST_CLOCK_TIME);
-
-        final DhcpServingParams servingParams = new DhcpServingParams.Builder()
-                .setDefaultRouters(TEST_DEFAULT_ROUTERS)
-                .setDhcpLeaseTimeSecs(TEST_LEASE_TIME_SECS)
-                .setDnsServers(TEST_DNS_SERVERS)
-                .setServerAddr(TEST_SERVER_LINKADDR)
-                .setLinkMtu(TEST_MTU)
-                .setExcludedAddrs(TEST_EXCLUDED_ADDRS)
-                .build();
-
-        mLooper = TestableLooper.get(this);
-        mHandlerThread = spy(new HandlerThread("TestDhcpServer"));
-        when(mHandlerThread.getLooper()).thenReturn(mLooper.getLooper());
-        mServer = new DhcpServer(mHandlerThread, TEST_IFACE, servingParams,
-                new SharedLog(DhcpServerTest.class.getSimpleName()), mDeps);
-
-        mServer.start(mAssertSuccessCallback);
-        mLooper.processAllMessages();
-    }
-
-    @After
-    public void tearDown() throws Exception {
-        mServer.stop(mAssertSuccessCallback);
-        mLooper.processMessages(1);
-        verify(mPacketListener, times(1)).stop();
-        verify(mHandlerThread, times(1)).quitSafely();
-    }
-
-    @Test
-    public void testStart() throws Exception {
-        verify(mPacketListener, times(1)).start();
-    }
-
-    @Test
-    public void testDiscover() throws Exception {
-        // TODO: refactor packet construction to eliminate unnecessary/confusing/duplicate fields
-        when(mRepository.getOffer(isNull() /* clientId */, eq(TEST_CLIENT_MAC),
-                eq(INADDR_ANY) /* relayAddr */, isNull() /* reqAddr */, isNull() /* hostname */))
-                .thenReturn(TEST_LEASE);
-
-        final DhcpDiscoverPacket discover = new DhcpDiscoverPacket(TEST_TRANSACTION_ID,
-                (short) 0 /* secs */, INADDR_ANY /* relayIp */, TEST_CLIENT_MAC_BYTES,
-                false /* broadcast */, INADDR_ANY /* srcIp */);
-        mServer.processPacket(discover, DHCP_CLIENT);
-
-        assertResponseSentTo(TEST_CLIENT_ADDR);
-        final DhcpOfferPacket packet = assertOffer(getPacket());
-        assertMatchesTestLease(packet);
-    }
-
-    @Test
-    public void testDiscover_OutOfAddresses() throws Exception {
-        when(mRepository.getOffer(isNull() /* clientId */, eq(TEST_CLIENT_MAC),
-                eq(INADDR_ANY) /* relayAddr */, isNull() /* reqAddr */, isNull() /* hostname */))
-                .thenThrow(new OutOfAddressesException("Test exception"));
-
-        final DhcpDiscoverPacket discover = new DhcpDiscoverPacket(TEST_TRANSACTION_ID,
-                (short) 0 /* secs */, INADDR_ANY /* relayIp */, TEST_CLIENT_MAC_BYTES,
-                false /* broadcast */, INADDR_ANY /* srcIp */);
-        mServer.processPacket(discover, DHCP_CLIENT);
-
-        assertResponseSentTo(INADDR_BROADCAST);
-        final DhcpNakPacket packet = assertNak(getPacket());
-        assertMatchesClient(packet);
-    }
-
-    private DhcpRequestPacket makeRequestSelectingPacket() {
-        final DhcpRequestPacket request = new DhcpRequestPacket(TEST_TRANSACTION_ID,
-                (short) 0 /* secs */, INADDR_ANY /* clientIp */, INADDR_ANY /* relayIp */,
-                TEST_CLIENT_MAC_BYTES, false /* broadcast */);
-        request.mServerIdentifier = TEST_SERVER_ADDR;
-        request.mRequestedIp = TEST_CLIENT_ADDR;
-        return request;
-    }
-
-    @Test
-    public void testRequest_Selecting_Ack() throws Exception {
-        when(mRepository.requestLease(isNull() /* clientId */, eq(TEST_CLIENT_MAC),
-                eq(INADDR_ANY) /* clientAddr */, eq(INADDR_ANY) /* relayAddr */,
-                eq(TEST_CLIENT_ADDR) /* reqAddr */, eq(true) /* sidSet */, eq(TEST_HOSTNAME)))
-                .thenReturn(TEST_LEASE_WITH_HOSTNAME);
-
-        final DhcpRequestPacket request = makeRequestSelectingPacket();
-        request.mHostName = TEST_HOSTNAME;
-        request.mRequestedParams = new byte[] { DHCP_HOST_NAME };
-        mServer.processPacket(request, DHCP_CLIENT);
-
-        assertResponseSentTo(TEST_CLIENT_ADDR);
-        final DhcpAckPacket packet = assertAck(getPacket());
-        assertMatchesTestLease(packet, TEST_HOSTNAME);
-    }
-
-    @Test
-    public void testRequest_Selecting_Nak() throws Exception {
-        when(mRepository.requestLease(isNull(), eq(TEST_CLIENT_MAC),
-                eq(INADDR_ANY) /* clientAddr */, eq(INADDR_ANY) /* relayAddr */,
-                eq(TEST_CLIENT_ADDR) /* reqAddr */, eq(true) /* sidSet */, isNull() /* hostname */))
-                .thenThrow(new InvalidAddressException("Test error"));
-
-        final DhcpRequestPacket request = makeRequestSelectingPacket();
-        mServer.processPacket(request, DHCP_CLIENT);
-
-        assertResponseSentTo(INADDR_BROADCAST);
-        final DhcpNakPacket packet = assertNak(getPacket());
-        assertMatchesClient(packet);
-    }
-
-    @Test
-    public void testRequest_Selecting_WrongClientPort() throws Exception {
-        final DhcpRequestPacket request = makeRequestSelectingPacket();
-        mServer.processPacket(request, 50000);
-
-        verify(mRepository, never())
-                .requestLease(any(), any(), any(), any(), any(), anyBoolean(), any());
-        verify(mDeps, never()).sendPacket(any(), any(), any());
-    }
-
-    @Test
-    public void testRelease() throws Exception {
-        final DhcpReleasePacket release = new DhcpReleasePacket(TEST_TRANSACTION_ID,
-                TEST_SERVER_ADDR, TEST_CLIENT_ADDR,
-                INADDR_ANY /* relayIp */, TEST_CLIENT_MAC_BYTES);
-        mServer.processPacket(release, DHCP_CLIENT);
-
-        verify(mRepository, times(1))
-                .releaseLease(isNull(), eq(TEST_CLIENT_MAC), eq(TEST_CLIENT_ADDR));
-    }
-
-    /* TODO: add more tests once packet construction is refactored, including:
-     *  - usage of giaddr
-     *  - usage of broadcast bit
-     *  - other request states (init-reboot/renewing/rebinding)
-     */
-
-    private void assertMatchesTestLease(@NonNull DhcpPacket packet, @Nullable String hostname) {
-        assertMatchesClient(packet);
-        assertFalse(packet.hasExplicitClientId());
-        assertEquals(TEST_SERVER_ADDR, packet.mServerIdentifier);
-        assertEquals(TEST_CLIENT_ADDR, packet.mYourIp);
-        assertNotNull(packet.mLeaseTime);
-        assertEquals(TEST_LEASE_EXPTIME_SECS, (int) packet.mLeaseTime);
-        assertEquals(hostname, packet.mHostName);
-    }
-
-    private void assertMatchesTestLease(@NonNull DhcpPacket packet) {
-        assertMatchesTestLease(packet, null);
-    }
-
-    private void assertMatchesClient(@NonNull DhcpPacket packet) {
-        assertEquals(TEST_TRANSACTION_ID, packet.mTransId);
-        assertEquals(TEST_CLIENT_MAC, MacAddress.fromBytes(packet.mClientMac));
-    }
-
-    private void assertResponseSentTo(@NonNull Inet4Address addr) {
-        assertEquals(addr, mResponseDstAddrCaptor.getValue());
-    }
-
-    private static DhcpNakPacket assertNak(@Nullable DhcpPacket packet) {
-        assertTrue(packet instanceof DhcpNakPacket);
-        return (DhcpNakPacket) packet;
-    }
-
-    private static DhcpAckPacket assertAck(@Nullable DhcpPacket packet) {
-        assertTrue(packet instanceof DhcpAckPacket);
-        return (DhcpAckPacket) packet;
-    }
-
-    private static DhcpOfferPacket assertOffer(@Nullable DhcpPacket packet) {
-        assertTrue(packet instanceof DhcpOfferPacket);
-        return (DhcpOfferPacket) packet;
-    }
-
-    private DhcpPacket getPacket() throws Exception {
-        verify(mDeps, times(1)).sendPacket(any(), any(), any());
-        return DhcpPacket.decodeFullPacket(mSentPacketCaptor.getValue(), ENCAP_BOOTP);
-    }
-
-    private static Inet4Address parseAddr(@Nullable String inet4Addr) {
-        return (Inet4Address) parseNumericAddress(inet4Addr);
-    }
-}
diff --git a/packages/NetworkStack/tests/unit/src/android/net/dhcp/DhcpServingParamsTest.java b/packages/NetworkStack/tests/unit/src/android/net/dhcp/DhcpServingParamsTest.java
deleted file mode 100644
index 57a87a4..0000000
--- a/packages/NetworkStack/tests/unit/src/android/net/dhcp/DhcpServingParamsTest.java
+++ /dev/null
@@ -1,221 +0,0 @@
-/*
- * Copyright (C) 2018 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.net.dhcp;
-
-import static android.net.InetAddresses.parseNumericAddress;
-import static android.net.dhcp.DhcpServingParams.MTU_UNSET;
-import static android.net.shared.Inet4AddressUtils.inet4AddressToIntHTH;
-
-import static junit.framework.Assert.assertEquals;
-import static junit.framework.Assert.assertFalse;
-import static junit.framework.Assert.assertTrue;
-
-import android.annotation.NonNull;
-import android.annotation.Nullable;
-import android.net.LinkAddress;
-import android.net.dhcp.DhcpServingParams.InvalidParameterException;
-import android.net.shared.Inet4AddressUtils;
-
-import androidx.test.filters.SmallTest;
-import androidx.test.runner.AndroidJUnit4;
-
-import org.junit.Before;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-
-import java.lang.reflect.Modifier;
-import java.net.Inet4Address;
-import java.util.Arrays;
-import java.util.Collection;
-import java.util.HashSet;
-import java.util.Set;
-
-@RunWith(AndroidJUnit4.class)
-@SmallTest
-public class DhcpServingParamsTest {
-    @NonNull
-    private DhcpServingParams.Builder mBuilder;
-
-    private static final Set<Inet4Address> TEST_DEFAULT_ROUTERS = new HashSet<>(
-            Arrays.asList(parseAddr("192.168.0.123"), parseAddr("192.168.0.124")));
-    private static final long TEST_LEASE_TIME_SECS = 3600L;
-    private static final Set<Inet4Address> TEST_DNS_SERVERS = new HashSet<>(
-            Arrays.asList(parseAddr("192.168.0.126"), parseAddr("192.168.0.127")));
-    private static final Inet4Address TEST_SERVER_ADDR = parseAddr("192.168.0.2");
-    private static final LinkAddress TEST_LINKADDR = new LinkAddress(TEST_SERVER_ADDR, 20);
-    private static final int TEST_MTU = 1500;
-    private static final Set<Inet4Address> TEST_EXCLUDED_ADDRS = new HashSet<>(
-            Arrays.asList(parseAddr("192.168.0.200"), parseAddr("192.168.0.201")));
-    private static final boolean TEST_METERED = true;
-
-    @Before
-    public void setUp() {
-        mBuilder = new DhcpServingParams.Builder()
-                .setDefaultRouters(TEST_DEFAULT_ROUTERS)
-                .setDhcpLeaseTimeSecs(TEST_LEASE_TIME_SECS)
-                .setDnsServers(TEST_DNS_SERVERS)
-                .setServerAddr(TEST_LINKADDR)
-                .setLinkMtu(TEST_MTU)
-                .setExcludedAddrs(TEST_EXCLUDED_ADDRS)
-                .setMetered(TEST_METERED);
-    }
-
-    @Test
-    public void testBuild_Immutable() throws InvalidParameterException {
-        final Set<Inet4Address> routers = new HashSet<>(TEST_DEFAULT_ROUTERS);
-        final Set<Inet4Address> dnsServers = new HashSet<>(TEST_DNS_SERVERS);
-        final Set<Inet4Address> excludedAddrs = new HashSet<>(TEST_EXCLUDED_ADDRS);
-
-        final DhcpServingParams params = mBuilder
-                .setDefaultRouters(routers)
-                .setDnsServers(dnsServers)
-                .setExcludedAddrs(excludedAddrs)
-                .build();
-
-        // Modifications to source objects should not affect builder or final parameters
-        final Inet4Address addedAddr = parseAddr("192.168.0.223");
-        routers.add(addedAddr);
-        dnsServers.add(addedAddr);
-        excludedAddrs.add(addedAddr);
-
-        assertEquals(TEST_DEFAULT_ROUTERS, params.defaultRouters);
-        assertEquals(TEST_LEASE_TIME_SECS, params.dhcpLeaseTimeSecs);
-        assertEquals(TEST_DNS_SERVERS, params.dnsServers);
-        assertEquals(TEST_LINKADDR, params.serverAddr);
-        assertEquals(TEST_MTU, params.linkMtu);
-        assertEquals(TEST_METERED, params.metered);
-
-        assertContains(params.excludedAddrs, TEST_EXCLUDED_ADDRS);
-        assertContains(params.excludedAddrs, TEST_DEFAULT_ROUTERS);
-        assertContains(params.excludedAddrs, TEST_DNS_SERVERS);
-        assertContains(params.excludedAddrs, TEST_SERVER_ADDR);
-
-        assertFalse("excludedAddrs should not contain " + addedAddr,
-                params.excludedAddrs.contains(addedAddr));
-    }
-
-    @Test(expected = InvalidParameterException.class)
-    public void testBuild_NegativeLeaseTime() throws InvalidParameterException {
-        mBuilder.setDhcpLeaseTimeSecs(-1).build();
-    }
-
-    @Test(expected = InvalidParameterException.class)
-    public void testBuild_LeaseTimeTooLarge() throws InvalidParameterException {
-        // Set lease time larger than max value for uint32
-        mBuilder.setDhcpLeaseTimeSecs(1L << 32).build();
-    }
-
-    @Test
-    public void testBuild_InfiniteLeaseTime() throws InvalidParameterException {
-        final long infiniteLeaseTime = 0xffffffffL;
-        final DhcpServingParams params = mBuilder
-                .setDhcpLeaseTimeSecs(infiniteLeaseTime).build();
-        assertEquals(infiniteLeaseTime, params.dhcpLeaseTimeSecs);
-        assertTrue(params.dhcpLeaseTimeSecs > 0L);
-    }
-
-    @Test
-    public void testBuild_UnsetMtu() throws InvalidParameterException {
-        final DhcpServingParams params = mBuilder.setLinkMtu(MTU_UNSET).build();
-        assertEquals(MTU_UNSET, params.linkMtu);
-    }
-
-    @Test(expected = InvalidParameterException.class)
-    public void testBuild_MtuTooSmall() throws InvalidParameterException {
-        mBuilder.setLinkMtu(20).build();
-    }
-
-    @Test(expected = InvalidParameterException.class)
-    public void testBuild_MtuTooLarge() throws InvalidParameterException {
-        mBuilder.setLinkMtu(65_536).build();
-    }
-
-    @Test(expected = InvalidParameterException.class)
-    public void testBuild_IPv6Addr() throws InvalidParameterException {
-        mBuilder.setServerAddr(new LinkAddress(parseNumericAddress("fe80::1111"), 120)).build();
-    }
-
-    @Test(expected = InvalidParameterException.class)
-    public void testBuild_PrefixTooLarge() throws InvalidParameterException {
-        mBuilder.setServerAddr(new LinkAddress(TEST_SERVER_ADDR, 15)).build();
-    }
-
-    @Test(expected = InvalidParameterException.class)
-    public void testBuild_PrefixTooSmall() throws InvalidParameterException {
-        mBuilder.setDefaultRouters(parseAddr("192.168.0.254"))
-                .setServerAddr(new LinkAddress(TEST_SERVER_ADDR, 31))
-                .build();
-    }
-
-    @Test(expected = InvalidParameterException.class)
-    public void testBuild_RouterNotInPrefix() throws InvalidParameterException {
-        mBuilder.setDefaultRouters(parseAddr("192.168.254.254")).build();
-    }
-
-    @Test
-    public void testFromParcelableObject() throws InvalidParameterException {
-        final DhcpServingParams params = mBuilder.build();
-        final DhcpServingParamsParcel parcel = new DhcpServingParamsParcel();
-        parcel.defaultRouters = toIntArray(TEST_DEFAULT_ROUTERS);
-        parcel.dhcpLeaseTimeSecs = TEST_LEASE_TIME_SECS;
-        parcel.dnsServers = toIntArray(TEST_DNS_SERVERS);
-        parcel.serverAddr = inet4AddressToIntHTH(TEST_SERVER_ADDR);
-        parcel.serverAddrPrefixLength = TEST_LINKADDR.getPrefixLength();
-        parcel.linkMtu = TEST_MTU;
-        parcel.excludedAddrs = toIntArray(TEST_EXCLUDED_ADDRS);
-        parcel.metered = TEST_METERED;
-        final DhcpServingParams parceled = DhcpServingParams.fromParcelableObject(parcel);
-
-        assertEquals(params.defaultRouters, parceled.defaultRouters);
-        assertEquals(params.dhcpLeaseTimeSecs, parceled.dhcpLeaseTimeSecs);
-        assertEquals(params.dnsServers, parceled.dnsServers);
-        assertEquals(params.serverAddr, parceled.serverAddr);
-        assertEquals(params.linkMtu, parceled.linkMtu);
-        assertEquals(params.excludedAddrs, parceled.excludedAddrs);
-        assertEquals(params.metered, parceled.metered);
-
-        // Ensure that we do not miss any field if added in the future
-        final long numFields = Arrays.stream(DhcpServingParams.class.getDeclaredFields())
-                .filter(f -> !Modifier.isStatic(f.getModifiers()))
-                .count();
-        assertEquals(7, numFields);
-    }
-
-    @Test(expected = InvalidParameterException.class)
-    public void testFromParcelableObject_NullArgument() throws InvalidParameterException {
-        DhcpServingParams.fromParcelableObject(null);
-    }
-
-    private static int[] toIntArray(Collection<Inet4Address> addrs) {
-        return addrs.stream().mapToInt(Inet4AddressUtils::inet4AddressToIntHTH).toArray();
-    }
-
-    private static <T> void assertContains(@NonNull Set<T> set, @NonNull Set<T> subset) {
-        for (final T elem : subset) {
-            assertContains(set, elem);
-        }
-    }
-
-    private static <T> void assertContains(@NonNull Set<T> set, @Nullable T elem) {
-        assertTrue("Set does not contain " + elem, set.contains(elem));
-    }
-
-    @NonNull
-    private static Inet4Address parseAddr(@NonNull String inet4Addr) {
-        return (Inet4Address) parseNumericAddress(inet4Addr);
-    }
-}
diff --git a/packages/NetworkStack/tests/unit/src/android/net/ip/IpClientTest.java b/packages/NetworkStack/tests/unit/src/android/net/ip/IpClientTest.java
deleted file mode 100644
index 5f80006..0000000
--- a/packages/NetworkStack/tests/unit/src/android/net/ip/IpClientTest.java
+++ /dev/null
@@ -1,547 +0,0 @@
-/*
- * Copyright (C) 2017 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.net.ip;
-
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertFalse;
-import static org.junit.Assert.assertTrue;
-import static org.junit.Assert.fail;
-import static org.mockito.Mockito.any;
-import static org.mockito.Mockito.anyString;
-import static org.mockito.Mockito.eq;
-import static org.mockito.Mockito.never;
-import static org.mockito.Mockito.reset;
-import static org.mockito.Mockito.timeout;
-import static org.mockito.Mockito.times;
-import static org.mockito.Mockito.verify;
-import static org.mockito.Mockito.verifyNoMoreInteractions;
-import static org.mockito.Mockito.when;
-
-import android.app.AlarmManager;
-import android.content.ContentResolver;
-import android.content.Context;
-import android.content.res.Resources;
-import android.net.ConnectivityManager;
-import android.net.INetd;
-import android.net.IpPrefix;
-import android.net.LinkAddress;
-import android.net.LinkProperties;
-import android.net.MacAddress;
-import android.net.NetworkStackIpMemoryStore;
-import android.net.RouteInfo;
-import android.net.ipmemorystore.NetworkAttributes;
-import android.net.shared.InitialConfiguration;
-import android.net.shared.ProvisioningConfiguration;
-import android.net.util.InterfaceParams;
-
-import androidx.test.filters.SmallTest;
-import androidx.test.runner.AndroidJUnit4;
-
-import com.android.internal.R;
-import com.android.server.NetworkObserver;
-import com.android.server.NetworkObserverRegistry;
-import com.android.server.NetworkStackService;
-
-import org.junit.Before;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.mockito.ArgumentCaptor;
-import org.mockito.Mock;
-import org.mockito.MockitoAnnotations;
-
-import java.net.InetAddress;
-import java.util.Arrays;
-import java.util.HashSet;
-import java.util.List;
-import java.util.Set;
-
-/**
- * Tests for IpClient.
- */
-@RunWith(AndroidJUnit4.class)
-@SmallTest
-public class IpClientTest {
-    private static final int DEFAULT_AVOIDBADWIFI_CONFIG_VALUE = 1;
-
-    private static final String VALID = "VALID";
-    private static final String INVALID = "INVALID";
-    private static final String TEST_IFNAME = "test_wlan0";
-    private static final int TEST_IFINDEX = 1001;
-    // See RFC 7042#section-2.1.2 for EUI-48 documentation values.
-    private static final MacAddress TEST_MAC = MacAddress.fromString("00:00:5E:00:53:01");
-    private static final int TEST_TIMEOUT_MS = 400;
-    private static final String TEST_L2KEY = "some l2key";
-    private static final String TEST_GROUPHINT = "some grouphint";
-
-    @Mock private Context mContext;
-    @Mock private ConnectivityManager mCm;
-    @Mock private NetworkObserverRegistry mObserverRegistry;
-    @Mock private INetd mNetd;
-    @Mock private Resources mResources;
-    @Mock private IIpClientCallbacks mCb;
-    @Mock private AlarmManager mAlarm;
-    @Mock private IpClient.Dependencies mDependencies;
-    @Mock private ContentResolver mContentResolver;
-    @Mock private NetworkStackService.NetworkStackServiceManager mNetworkStackServiceManager;
-    @Mock private NetworkStackIpMemoryStore mIpMemoryStore;
-
-    private NetworkObserver mObserver;
-    private InterfaceParams mIfParams;
-
-    @Before
-    public void setUp() throws Exception {
-        MockitoAnnotations.initMocks(this);
-
-        when(mContext.getSystemService(eq(Context.ALARM_SERVICE))).thenReturn(mAlarm);
-        when(mContext.getSystemService(eq(ConnectivityManager.class))).thenReturn(mCm);
-        when(mContext.getResources()).thenReturn(mResources);
-        when(mDependencies.getNetd(any())).thenReturn(mNetd);
-        when(mResources.getInteger(R.integer.config_networkAvoidBadWifi))
-                .thenReturn(DEFAULT_AVOIDBADWIFI_CONFIG_VALUE);
-        when(mContext.getContentResolver()).thenReturn(mContentResolver);
-
-        mIfParams = null;
-    }
-
-    private void setTestInterfaceParams(String ifname) {
-        mIfParams = (ifname != null)
-                ? new InterfaceParams(ifname, TEST_IFINDEX, TEST_MAC)
-                : null;
-        when(mDependencies.getInterfaceParams(anyString())).thenReturn(mIfParams);
-    }
-
-    private IpClient makeIpClient(String ifname) throws Exception {
-        setTestInterfaceParams(ifname);
-        final IpClient ipc = new IpClient(mContext, ifname, mCb, mObserverRegistry,
-                mNetworkStackServiceManager, mDependencies);
-        verify(mNetd, timeout(TEST_TIMEOUT_MS).times(1)).interfaceSetEnableIPv6(ifname, false);
-        verify(mNetd, timeout(TEST_TIMEOUT_MS).times(1)).interfaceClearAddrs(ifname);
-        ArgumentCaptor<NetworkObserver> arg = ArgumentCaptor.forClass(NetworkObserver.class);
-        verify(mObserverRegistry, times(1)).registerObserverForNonblockingCallback(arg.capture());
-        mObserver = arg.getValue();
-        reset(mObserverRegistry);
-        reset(mNetd);
-        // Verify IpClient doesn't call onLinkPropertiesChange() when it starts.
-        verify(mCb, never()).onLinkPropertiesChange(any());
-        reset(mCb);
-        return ipc;
-    }
-
-    private static LinkProperties makeEmptyLinkProperties(String iface) {
-        final LinkProperties empty = new LinkProperties();
-        empty.setInterfaceName(iface);
-        return empty;
-    }
-
-    private void verifyNetworkAttributesStored(final String l2Key,
-            final NetworkAttributes attributes) {
-        // TODO : when storing is implemented, turn this on
-        // verify(mIpMemoryStore).storeNetworkAttributes(eq(l2Key), eq(attributes), any());
-    }
-
-    @Test
-    public void testNullInterfaceNameMostDefinitelyThrows() throws Exception {
-        setTestInterfaceParams(null);
-        try {
-            final IpClient ipc = new IpClient(mContext, null, mCb, mObserverRegistry,
-                    mNetworkStackServiceManager, mDependencies);
-            ipc.shutdown();
-            fail();
-        } catch (NullPointerException npe) {
-            // Phew; null interface names not allowed.
-        }
-    }
-
-    @Test
-    public void testNullCallbackMostDefinitelyThrows() throws Exception {
-        final String ifname = "lo";
-        setTestInterfaceParams(ifname);
-        try {
-            final IpClient ipc = new IpClient(mContext, ifname, null, mObserverRegistry,
-                    mNetworkStackServiceManager, mDependencies);
-            ipc.shutdown();
-            fail();
-        } catch (NullPointerException npe) {
-            // Phew; null callbacks not allowed.
-        }
-    }
-
-    @Test
-    public void testInvalidInterfaceDoesNotThrow() throws Exception {
-        setTestInterfaceParams(TEST_IFNAME);
-        final IpClient ipc = new IpClient(mContext, TEST_IFNAME, mCb, mObserverRegistry,
-                mNetworkStackServiceManager, mDependencies);
-        verifyNoMoreInteractions(mIpMemoryStore);
-        ipc.shutdown();
-    }
-
-    @Test
-    public void testInterfaceNotFoundFailsImmediately() throws Exception {
-        setTestInterfaceParams(null);
-        final IpClient ipc = new IpClient(mContext, TEST_IFNAME, mCb, mObserverRegistry,
-                mNetworkStackServiceManager, mDependencies);
-        ipc.startProvisioning(new ProvisioningConfiguration());
-        verify(mCb, times(1)).onProvisioningFailure(any());
-        verify(mIpMemoryStore, never()).storeNetworkAttributes(any(), any(), any());
-        ipc.shutdown();
-    }
-
-    @Test
-    public void testDefaultProvisioningConfiguration() throws Exception {
-        final String iface = TEST_IFNAME;
-        final IpClient ipc = makeIpClient(iface);
-
-        ProvisioningConfiguration config = new ProvisioningConfiguration.Builder()
-                .withoutIPv4()
-                // TODO: mock IpReachabilityMonitor's dependencies (NetworkInterface, PowerManager)
-                // and enable it in this test
-                .withoutIpReachabilityMonitor()
-                .build();
-
-        ipc.startProvisioning(config);
-        verify(mCb, times(1)).setNeighborDiscoveryOffload(true);
-        verify(mCb, timeout(TEST_TIMEOUT_MS).times(1)).setFallbackMulticastFilter(false);
-        verify(mCb, never()).onProvisioningFailure(any());
-        verify(mIpMemoryStore, never()).storeNetworkAttributes(any(), any(), any());
-
-        ipc.shutdown();
-        verify(mNetd, timeout(TEST_TIMEOUT_MS).times(1)).interfaceSetEnableIPv6(iface, false);
-        verify(mNetd, timeout(TEST_TIMEOUT_MS).times(1)).interfaceClearAddrs(iface);
-        verify(mCb, timeout(TEST_TIMEOUT_MS).times(1))
-                .onLinkPropertiesChange(makeEmptyLinkProperties(iface));
-    }
-
-    @Test
-    public void testProvisioningWithInitialConfiguration() throws Exception {
-        final String iface = TEST_IFNAME;
-        final IpClient ipc = makeIpClient(iface);
-        final String l2Key = TEST_L2KEY;
-        final String groupHint = TEST_GROUPHINT;
-
-        String[] addresses = {
-            "fe80::a4be:f92:e1f7:22d1/64",
-            "fe80::f04a:8f6:6a32:d756/64",
-            "fd2c:4e57:8e3c:0:548d:2db2:4fcf:ef75/64"
-        };
-        String[] prefixes = { "fe80::/64", "fd2c:4e57:8e3c::/64" };
-
-        ProvisioningConfiguration config = new ProvisioningConfiguration.Builder()
-                .withoutIPv4()
-                .withoutIpReachabilityMonitor()
-                .withInitialConfiguration(conf(links(addresses), prefixes(prefixes), ips()))
-                .build();
-
-        ipc.startProvisioning(config);
-        verify(mCb, times(1)).setNeighborDiscoveryOffload(true);
-        verify(mCb, timeout(TEST_TIMEOUT_MS).times(1)).setFallbackMulticastFilter(false);
-        verify(mCb, never()).onProvisioningFailure(any());
-        ipc.setL2KeyAndGroupHint(l2Key, groupHint);
-
-        for (String addr : addresses) {
-            String[] parts = addr.split("/");
-            verify(mNetd, timeout(TEST_TIMEOUT_MS).times(1))
-                    .interfaceAddAddress(iface, parts[0], Integer.parseInt(parts[1]));
-        }
-
-        final int lastAddr = addresses.length - 1;
-
-        // Add N - 1 addresses
-        for (int i = 0; i < lastAddr; i++) {
-            mObserver.onInterfaceAddressUpdated(new LinkAddress(addresses[i]), iface);
-            verify(mCb, timeout(TEST_TIMEOUT_MS)).onLinkPropertiesChange(any());
-            reset(mCb);
-        }
-
-        // Add Nth address
-        mObserver.onInterfaceAddressUpdated(new LinkAddress(addresses[lastAddr]), iface);
-        LinkProperties want = linkproperties(links(addresses), routes(prefixes));
-        want.setInterfaceName(iface);
-        verify(mCb, timeout(TEST_TIMEOUT_MS).times(1)).onProvisioningSuccess(want);
-        verifyNetworkAttributesStored(l2Key, new NetworkAttributes.Builder()
-                .setGroupHint(groupHint)
-                .build());
-
-        ipc.shutdown();
-        verify(mNetd, timeout(TEST_TIMEOUT_MS).times(1)).interfaceSetEnableIPv6(iface, false);
-        verify(mNetd, timeout(TEST_TIMEOUT_MS).times(1)).interfaceClearAddrs(iface);
-        verify(mCb, timeout(TEST_TIMEOUT_MS).times(1))
-                .onLinkPropertiesChange(makeEmptyLinkProperties(iface));
-        verifyNoMoreInteractions(mIpMemoryStore);
-    }
-
-    @Test
-    public void testIsProvisioned() throws Exception {
-        InitialConfiguration empty = conf(links(), prefixes());
-        IsProvisionedTestCase[] testcases = {
-            // nothing
-            notProvisionedCase(links(), routes(), dns(), null),
-            notProvisionedCase(links(), routes(), dns(), empty),
-
-            // IPv4
-            provisionedCase(links("192.0.2.12/24"), routes(), dns(), empty),
-
-            // IPv6
-            notProvisionedCase(
-                    links("fe80::a4be:f92:e1f7:22d1/64", "fd2c:4e57:8e3c:0:548d:2db2:4fcf:ef75/64"),
-                    routes(), dns(), empty),
-            notProvisionedCase(
-                    links("fe80::a4be:f92:e1f7:22d1/64", "fd2c:4e57:8e3c:0:548d:2db2:4fcf:ef75/64"),
-                    routes("fe80::/64", "fd2c:4e57:8e3c::/64"), dns("fd00:1234:5678::1000"), empty),
-            provisionedCase(
-                    links("2001:db8:dead:beef:f00::a0/64", "fe80::1/64"),
-                    routes("::/0"),
-                    dns("2001:db8:dead:beef:f00::02"), empty),
-
-            // Initial configuration
-            provisionedCase(
-                    links("fe80::e1f7:22d1/64", "fd2c:4e57:8e3c:0:548d:2db2:4fcf:ef75/64"),
-                    routes("fe80::/64", "fd2c:4e57:8e3c::/64"),
-                    dns(),
-                    conf(links("fe80::e1f7:22d1/64", "fd2c:4e57:8e3c:0:548d:2db2:4fcf:ef75/64"),
-                        prefixes( "fe80::/64", "fd2c:4e57:8e3c::/64"), ips()))
-        };
-
-        for (IsProvisionedTestCase testcase : testcases) {
-            if (IpClient.isProvisioned(testcase.lp, testcase.config) != testcase.isProvisioned) {
-                fail(testcase.errorMessage());
-            }
-        }
-    }
-
-    static class IsProvisionedTestCase {
-        boolean isProvisioned;
-        LinkProperties lp;
-        InitialConfiguration config;
-
-        String errorMessage() {
-            return String.format("expected %s with config %s to be %s, but was %s",
-                     lp, config, provisioned(isProvisioned), provisioned(!isProvisioned));
-        }
-
-        static String provisioned(boolean isProvisioned) {
-            return isProvisioned ? "provisioned" : "not provisioned";
-        }
-    }
-
-    static IsProvisionedTestCase provisionedCase(Set<LinkAddress> lpAddrs, Set<RouteInfo> lpRoutes,
-            Set<InetAddress> lpDns, InitialConfiguration config) {
-        return provisioningTest(true, lpAddrs, lpRoutes, lpDns, config);
-    }
-
-    static IsProvisionedTestCase notProvisionedCase(Set<LinkAddress> lpAddrs,
-            Set<RouteInfo> lpRoutes, Set<InetAddress> lpDns, InitialConfiguration config) {
-        return provisioningTest(false, lpAddrs, lpRoutes, lpDns, config);
-    }
-
-    static IsProvisionedTestCase provisioningTest(boolean isProvisioned, Set<LinkAddress> lpAddrs,
-            Set<RouteInfo> lpRoutes, Set<InetAddress> lpDns, InitialConfiguration config) {
-        IsProvisionedTestCase testcase = new IsProvisionedTestCase();
-        testcase.isProvisioned = isProvisioned;
-        testcase.lp = new LinkProperties();
-        testcase.lp.setLinkAddresses(lpAddrs);
-        for (RouteInfo route : lpRoutes) {
-            testcase.lp.addRoute(route);
-        }
-        for (InetAddress dns : lpDns) {
-            testcase.lp.addDnsServer(dns);
-        }
-        testcase.config = config;
-        return testcase;
-    }
-
-    @Test
-    public void testInitialConfigurations() throws Exception {
-        InitialConfigurationTestCase[] testcases = {
-            validConf("valid IPv4 configuration",
-                    links("192.0.2.12/24"), prefixes("192.0.2.0/24"), dns("192.0.2.2")),
-            validConf("another valid IPv4 configuration",
-                    links("192.0.2.12/24"), prefixes("192.0.2.0/24"), dns()),
-            validConf("valid IPv6 configurations",
-                    links("2001:db8:dead:beef:f00::a0/64", "fe80::1/64"),
-                    prefixes("2001:db8:dead:beef::/64", "fe80::/64"),
-                    dns("2001:db8:dead:beef:f00::02")),
-            validConf("valid IPv6 configurations",
-                    links("fe80::1/64"), prefixes("fe80::/64"), dns()),
-            validConf("valid IPv6/v4 configuration",
-                    links("2001:db8:dead:beef:f00::a0/48", "192.0.2.12/24"),
-                    prefixes("2001:db8:dead:beef::/64", "192.0.2.0/24"),
-                    dns("192.0.2.2", "2001:db8:dead:beef:f00::02")),
-            validConf("valid IPv6 configuration without any GUA.",
-                    links("fd00:1234:5678::1/48"),
-                    prefixes("fd00:1234:5678::/48"),
-                    dns("fd00:1234:5678::1000")),
-
-            invalidConf("empty configuration", links(), prefixes(), dns()),
-            invalidConf("v4 addr and dns not in any prefix",
-                    links("192.0.2.12/24"), prefixes("198.51.100.0/24"), dns("192.0.2.2")),
-            invalidConf("v4 addr not in any prefix",
-                    links("198.51.2.12/24"), prefixes("198.51.100.0/24"), dns("192.0.2.2")),
-            invalidConf("v4 dns addr not in any prefix",
-                    links("192.0.2.12/24"), prefixes("192.0.2.0/24"), dns("198.51.100.2")),
-            invalidConf("v6 addr not in any prefix",
-                    links("2001:db8:dead:beef:f00::a0/64", "fe80::1/64"),
-                    prefixes("2001:db8:dead:beef::/64"),
-                    dns("2001:db8:dead:beef:f00::02")),
-            invalidConf("v6 dns addr not in any prefix",
-                    links("fe80::1/64"), prefixes("fe80::/64"), dns("2001:db8:dead:beef:f00::02")),
-            invalidConf("default ipv6 route and no GUA",
-                    links("fd01:1111:2222:3333::a0/128"), prefixes("::/0"), dns()),
-            invalidConf("invalid v6 prefix length",
-                    links("2001:db8:dead:beef:f00::a0/128"), prefixes("2001:db8:dead:beef::/32"),
-                    dns()),
-            invalidConf("another invalid v6 prefix length",
-                    links("2001:db8:dead:beef:f00::a0/128"), prefixes("2001:db8:dead:beef::/72"),
-                    dns())
-        };
-
-        for (InitialConfigurationTestCase testcase : testcases) {
-            if (testcase.config.isValid() != testcase.isValid) {
-                fail(testcase.errorMessage());
-            }
-        }
-    }
-
-    static class InitialConfigurationTestCase {
-        String descr;
-        boolean isValid;
-        InitialConfiguration config;
-        public String errorMessage() {
-            return String.format("%s: expected configuration %s to be %s, but was %s",
-                    descr, config, validString(isValid), validString(!isValid));
-        }
-        static String validString(boolean isValid) {
-            return isValid ? VALID : INVALID;
-        }
-    }
-
-    static InitialConfigurationTestCase validConf(String descr, Set<LinkAddress> links,
-            Set<IpPrefix> prefixes, Set<InetAddress> dns) {
-        return confTestCase(descr, true, conf(links, prefixes, dns));
-    }
-
-    static InitialConfigurationTestCase invalidConf(String descr, Set<LinkAddress> links,
-            Set<IpPrefix> prefixes, Set<InetAddress> dns) {
-        return confTestCase(descr, false, conf(links, prefixes, dns));
-    }
-
-    static InitialConfigurationTestCase confTestCase(
-            String descr, boolean isValid, InitialConfiguration config) {
-        InitialConfigurationTestCase testcase = new InitialConfigurationTestCase();
-        testcase.descr = descr;
-        testcase.isValid = isValid;
-        testcase.config = config;
-        return testcase;
-    }
-
-    static LinkProperties linkproperties(Set<LinkAddress> addresses, Set<RouteInfo> routes) {
-        LinkProperties lp = new LinkProperties();
-        lp.setLinkAddresses(addresses);
-        for (RouteInfo route : routes) {
-            lp.addRoute(route);
-        }
-        return lp;
-    }
-
-    static InitialConfiguration conf(Set<LinkAddress> links, Set<IpPrefix> prefixes) {
-        return conf(links, prefixes, new HashSet<>());
-    }
-
-    static InitialConfiguration conf(
-            Set<LinkAddress> links, Set<IpPrefix> prefixes, Set<InetAddress> dns) {
-        InitialConfiguration conf = new InitialConfiguration();
-        conf.ipAddresses.addAll(links);
-        conf.directlyConnectedRoutes.addAll(prefixes);
-        conf.dnsServers.addAll(dns);
-        return conf;
-    }
-
-    static Set<RouteInfo> routes(String... routes) {
-        return mapIntoSet(routes, (r) -> new RouteInfo(new IpPrefix(r)));
-    }
-
-    static Set<IpPrefix> prefixes(String... prefixes) {
-        return mapIntoSet(prefixes, IpPrefix::new);
-    }
-
-    static Set<LinkAddress> links(String... addresses) {
-        return mapIntoSet(addresses, LinkAddress::new);
-    }
-
-    static Set<InetAddress> ips(String... addresses) {
-        return mapIntoSet(addresses, InetAddress::getByName);
-    }
-
-    static Set<InetAddress> dns(String... addresses) {
-        return ips(addresses);
-    }
-
-    static <A, B> Set<B> mapIntoSet(A[] in, Fn<A, B> fn) {
-        Set<B> out = new HashSet<>(in.length);
-        for (A item : in) {
-            try {
-                out.add(fn.call(item));
-            } catch (Exception e) {
-                throw new RuntimeException(e);
-            }
-        }
-        return out;
-    }
-
-    interface Fn<A,B> {
-        B call(A a) throws Exception;
-    }
-
-    @Test
-    public void testAll() {
-        List<String> list1 = Arrays.asList();
-        List<String> list2 = Arrays.asList("foo");
-        List<String> list3 = Arrays.asList("bar", "baz");
-        List<String> list4 = Arrays.asList("foo", "bar", "baz");
-
-        assertTrue(InitialConfiguration.all(list1, (x) -> false));
-        assertFalse(InitialConfiguration.all(list2, (x) -> false));
-        assertTrue(InitialConfiguration.all(list3, (x) -> true));
-        assertTrue(InitialConfiguration.all(list2, (x) -> x.charAt(0) == 'f'));
-        assertFalse(InitialConfiguration.all(list4, (x) -> x.charAt(0) == 'f'));
-    }
-
-    @Test
-    public void testAny() {
-        List<String> list1 = Arrays.asList();
-        List<String> list2 = Arrays.asList("foo");
-        List<String> list3 = Arrays.asList("bar", "baz");
-        List<String> list4 = Arrays.asList("foo", "bar", "baz");
-
-        assertFalse(InitialConfiguration.any(list1, (x) -> true));
-        assertTrue(InitialConfiguration.any(list2, (x) -> true));
-        assertTrue(InitialConfiguration.any(list2, (x) -> x.charAt(0) == 'f'));
-        assertFalse(InitialConfiguration.any(list3, (x) -> x.charAt(0) == 'f'));
-        assertTrue(InitialConfiguration.any(list4, (x) -> x.charAt(0) == 'f'));
-    }
-
-    @Test
-    public void testFindAll() {
-        List<String> list1 = Arrays.asList();
-        List<String> list2 = Arrays.asList("foo");
-        List<String> list3 = Arrays.asList("foo", "bar", "baz");
-
-        assertEquals(list1, IpClient.findAll(list1, (x) -> true));
-        assertEquals(list1, IpClient.findAll(list3, (x) -> false));
-        assertEquals(list3, IpClient.findAll(list3, (x) -> true));
-        assertEquals(list2, IpClient.findAll(list3, (x) -> x.charAt(0) == 'f'));
-    }
-}
diff --git a/packages/NetworkStack/tests/unit/src/android/net/ip/IpReachabilityMonitorTest.java b/packages/NetworkStack/tests/unit/src/android/net/ip/IpReachabilityMonitorTest.java
deleted file mode 100644
index 64b168a..0000000
--- a/packages/NetworkStack/tests/unit/src/android/net/ip/IpReachabilityMonitorTest.java
+++ /dev/null
@@ -1,67 +0,0 @@
-/*
- * Copyright (C) 2017 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.net.ip;
-
-import static org.mockito.Mockito.anyString;
-import static org.mockito.Mockito.when;
-
-import android.content.Context;
-import android.net.util.InterfaceParams;
-import android.net.util.SharedLog;
-import android.os.Handler;
-import android.os.Looper;
-
-import androidx.test.filters.SmallTest;
-import androidx.test.runner.AndroidJUnit4;
-
-import org.junit.Before;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.mockito.Mock;
-import org.mockito.MockitoAnnotations;
-
-/**
- * Tests for IpReachabilityMonitor.
- */
-@RunWith(AndroidJUnit4.class)
-@SmallTest
-public class IpReachabilityMonitorTest {
-
-    @Mock IpReachabilityMonitor.Callback mCallback;
-    @Mock IpReachabilityMonitor.Dependencies mDependencies;
-    @Mock SharedLog mLog;
-    @Mock Context mContext;
-    Handler mHandler;
-
-    @Before
-    public void setUp() {
-        MockitoAnnotations.initMocks(this);
-        when(mLog.forSubComponent(anyString())).thenReturn(mLog);
-        mHandler = new Handler(Looper.getMainLooper());
-    }
-
-    IpReachabilityMonitor makeMonitor() {
-        final InterfaceParams ifParams = new InterfaceParams("fake0", 1, null);
-        return new IpReachabilityMonitor(
-                mContext, ifParams, mHandler, mLog, mCallback, false, mDependencies);
-    }
-
-    @Test
-    public void testNothing() {
-        IpReachabilityMonitor monitor = makeMonitor();
-    }
-}
diff --git a/packages/NetworkStack/tests/unit/src/android/net/util/ConnectivityPacketSummaryTest.java b/packages/NetworkStack/tests/unit/src/android/net/util/ConnectivityPacketSummaryTest.java
deleted file mode 100644
index 71be8b3..0000000
--- a/packages/NetworkStack/tests/unit/src/android/net/util/ConnectivityPacketSummaryTest.java
+++ /dev/null
@@ -1,419 +0,0 @@
-/*
- * Copyright (C) 2016 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.net.util;
-
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertTrue;
-
-import android.net.MacAddress;
-
-import androidx.test.filters.SmallTest;
-import androidx.test.runner.AndroidJUnit4;
-
-import libcore.util.HexEncoding;
-
-import org.junit.Test;
-import org.junit.runner.RunWith;
-
-/**
- * Tests for ConnectivityPacketSummary.
- *
- * @hide
- */
-@RunWith(AndroidJUnit4.class)
-@SmallTest
-public class ConnectivityPacketSummaryTest {
-    private static final MacAddress MYHWADDR = MacAddress.fromString("80:7a:bf:6f:48:f3");
-
-    private String getSummary(String hexBytes) {
-        hexBytes = hexBytes.replaceAll("\\s+", "");
-        final byte[] bytes = HexEncoding.decode(hexBytes.toCharArray(), false);
-        return ConnectivityPacketSummary.summarize(MYHWADDR, bytes);
-    }
-
-    @Test
-    public void testParseICMPv6DADProbe() {
-        final String packet =
-                // Ethernet
-                "3333FF6F48F3 807ABF6F48F3 86DD" +
-                // IPv6
-                "600000000018 3A FF" +
-                "00000000000000000000000000000000" +
-                "FF0200000000000000000001FF6F48F3" +
-                // ICMPv6
-                "87 00 A8E7" +
-                "00000000" +
-                "FE80000000000000827ABFFFFE6F48F3";
-
-        final String expected =
-                "TX 80:7a:bf:6f:48:f3 > 33:33:ff:6f:48:f3 ipv6" +
-                " :: > ff02::1:ff6f:48f3 icmp6" +
-                " ns fe80::827a:bfff:fe6f:48f3";
-
-        assertEquals(expected, getSummary(packet));
-    }
-
-    @Test
-    public void testParseICMPv6RS() {
-        final String packet =
-                // Ethernet
-                "333300000002 807ABF6F48F3 86DD" +
-                // IPv6
-                "600000000010 3A FF" +
-                "FE80000000000000827ABFFFFE6F48F3" +
-                "FF020000000000000000000000000002" +
-                // ICMPv6 RS
-                "85 00 6973" +
-                "00000000" +
-                "01 01 807ABF6F48F3";
-
-        final String expected =
-                "TX 80:7a:bf:6f:48:f3 > 33:33:00:00:00:02 ipv6" +
-                " fe80::827a:bfff:fe6f:48f3 > ff02::2 icmp6" +
-                " rs slla 80:7a:bf:6f:48:f3";
-
-        assertEquals(expected, getSummary(packet));
-    }
-
-    @Test
-    public void testParseICMPv6RA() {
-        final String packet =
-                // Ethernet
-                "807ABF6F48F3 100E7E263FC1 86DD" +
-                // IPv6
-                "600000000068 3A FF" +
-                "FE80000000000000FA000004FD000001" +
-                "FE80000000000000827ABFFFFE6F48F3" +
-                // ICMPv6 RA
-                "86 00 8141" +
-                "40 00 0E10" +
-                "00000000" +
-                "00000000" +
-                "01 01 00005E000265" +
-                "05 01 0000000005DC" +
-                "19 05 000000000E10" +
-                "      20014860486000000000000000008844" +
-                "      20014860486000000000000000008888" +
-                "03 04 40 C0" +
-                "      00278D00" +
-                "      00093A80" +
-                "      00000000" +
-                "      2401FA000004FD000000000000000000";
-
-        final String expected =
-                "RX 10:0e:7e:26:3f:c1 > 80:7a:bf:6f:48:f3 ipv6" +
-                " fe80::fa00:4:fd00:1 > fe80::827a:bfff:fe6f:48f3 icmp6" +
-                " ra slla 00:00:5e:00:02:65 mtu 1500";
-
-        assertEquals(expected, getSummary(packet));
-    }
-
-    @Test
-    public void testParseICMPv6NS() {
-        final String packet =
-                // Ethernet
-                  "807ABF6F48F3 100E7E263FC1 86DD" +
-                  // IPv6
-                  "6C0000000020 3A FF" +
-                  "FE80000000000000FA000004FD000001" +
-                  "FF0200000000000000000001FF01C146" +
-                  // ICMPv6 NS
-                  "87 00 8AD4" +
-                  "00000000" +
-                  "2401FA000004FD0015EA6A5C7B01C146" +
-                  "01 01 00005E000265";
-
-        final String expected =
-                "RX 10:0e:7e:26:3f:c1 > 80:7a:bf:6f:48:f3 ipv6" +
-                " fe80::fa00:4:fd00:1 > ff02::1:ff01:c146 icmp6" +
-                " ns 2401:fa00:4:fd00:15ea:6a5c:7b01:c146 slla 00:00:5e:00:02:65";
-
-        assertEquals(expected, getSummary(packet));
-    }
-
-    @Test
-    public void testInvalidICMPv6NDLength() {
-        final String packet =
-                // Ethernet
-                "807ABF6F48F3 100E7E263FC1 86DD" +
-                // IPv6
-                "600000000068 3A FF" +
-                "FE80000000000000FA000004FD000001" +
-                "FE80000000000000827ABFFFFE6F48F3" +
-                // ICMPv6 RA
-                "86 00 8141" +
-                "40 00 0E10" +
-                "00000000" +
-                "00000000" +
-                "01 01 00005E000265" +
-                "00 00 0102030405D6";
-
-        final String expected =
-                "RX 10:0e:7e:26:3f:c1 > 80:7a:bf:6f:48:f3 ipv6" +
-                " fe80::fa00:4:fd00:1 > fe80::827a:bfff:fe6f:48f3 icmp6" +
-                " ra slla 00:00:5e:00:02:65 <malformed>";
-
-        assertEquals(expected, getSummary(packet));
-    }
-
-    @Test
-    public void testParseICMPv6NA() {
-        final String packet =
-                // Ethernet
-                "00005E000265 807ABF6F48F3 86DD" +
-                "600000000020 3A FF" +
-                "2401FA000004FD0015EA6A5C7B01C146" +
-                "FE80000000000000FA000004FD000001" +
-                "88 00 E8126" +
-                "0000000" +
-                "2401FA000004FD0015EA6A5C7B01C146" +
-                "02 01 807ABF6F48F3";
-
-        final String expected =
-                "TX 80:7a:bf:6f:48:f3 > 00:00:5e:00:02:65 ipv6" +
-                " 2401:fa00:4:fd00:15ea:6a5c:7b01:c146 > fe80::fa00:4:fd00:1 icmp6" +
-                " na 2401:fa00:4:fd00:15ea:6a5c:7b01:c146 tlla 80:7a:bf:6f:48:f3";
-
-        assertEquals(expected, getSummary(packet));
-    }
-
-    @Test
-    public void testParseARPRequest() {
-        final String packet =
-                // Ethernet
-                  "FFFFFFFFFFFF 807ABF6F48F3 0806" +
-                  // ARP
-                  "0001 0800 06 04" +
-                  // Request
-                  "0001" +
-                  "807ABF6F48F3 64706ADB" +
-                  "000000000000 64706FFD";
-
-        final String expected =
-                "TX 80:7a:bf:6f:48:f3 > ff:ff:ff:ff:ff:ff arp" +
-                " who-has 100.112.111.253";
-
-        assertEquals(expected, getSummary(packet));
-    }
-
-    @Test
-    public void testParseARPReply() {
-        final String packet =
-                // Ethernet
-                  "807ABF6F48F3 288A1CA8DFC1 0806" +
-                  // ARP
-                  "0001 0800 06 04" +
-                  // Reply
-                  "0002" +
-                  "288A1CA8DFC1 64706FFD"+
-                  "807ABF6F48F3 64706ADB" +
-                  // Ethernet padding to packet min size.
-                  "0000000000000000000000000000";
-
-        final String expected =
-                "RX 28:8a:1c:a8:df:c1 > 80:7a:bf:6f:48:f3 arp" +
-                " reply 100.112.111.253 28:8a:1c:a8:df:c1";
-
-        assertEquals(expected, getSummary(packet));
-    }
-
-    @Test
-    public void testParseDHCPv4Discover() {
-        final String packet =
-                // Ethernet
-                "FFFFFFFFFFFF 807ABF6F48F3 0800" +
-                // IPv4
-                "451001580000400040113986" +
-                "00000000" +
-                "FFFFFFFF" +
-                // UDP
-                "0044 0043" +
-                "0144 5559" +
-                // DHCPv4
-                "01 01 06 00" +
-                "79F7ACA4" +
-                "0000 0000" +
-                "00000000" +
-                "00000000" +
-                "00000000" +
-                "00000000" +
-                "807ABF6F48F300000000000000000000" +
-                "0000000000000000000000000000000000000000000000000000000000000000" +
-                "0000000000000000000000000000000000000000000000000000000000000000" +
-                "0000000000000000000000000000000000000000000000000000000000000000" +
-                "0000000000000000000000000000000000000000000000000000000000000000" +
-                "0000000000000000000000000000000000000000000000000000000000000000" +
-                "0000000000000000000000000000000000000000000000000000000000000000" +
-                "63 82 53 63" +
-                "35 01 01" +
-                "3D 07 01807ABF6F48F3" +
-                "39 02 05DC" +
-                "3C 12 616E64726F69642D646863702D372E312E32" +
-                "0C 18 616E64726F69642D36623030366333313333393835343139" +
-                "37 0A 01 03 06 0F 1A 1C 33 3A 3B 2B" +
-                "FF" +
-                "00";
-
-        final String expectedPrefix =
-                "TX 80:7a:bf:6f:48:f3 > ff:ff:ff:ff:ff:ff ipv4" +
-                " 0.0.0.0 > 255.255.255.255 udp" +
-                " 68 > 67 dhcp4" +
-                " 80:7a:bf:6f:48:f3 DISCOVER";
-
-        assertTrue(getSummary(packet).startsWith(expectedPrefix));
-    }
-
-    @Test
-    public void testParseDHCPv4Offer() {
-        final String packet =
-                // Ethernet
-                "807ABF6F48F3 288A1CA8DFC1 0800" +
-                // IPv4
-                "4500013D4D2C0000401188CB" +
-                "64706FFD" +
-                "64706ADB" +
-                // UDP
-                "0043 0044" +
-                "0129 371D" +
-                // DHCPv4
-                "02 01 06 01" +
-                "79F7ACA4" +
-                "0000 0000" +
-                "00000000" +
-                "64706ADB" +
-                "00000000" +
-                "00000000" +
-                "807ABF6F48F300000000000000000000" +
-                "0000000000000000000000000000000000000000000000000000000000000000" +
-                "0000000000000000000000000000000000000000000000000000000000000000" +
-                "0000000000000000000000000000000000000000000000000000000000000000" +
-                "0000000000000000000000000000000000000000000000000000000000000000" +
-                "0000000000000000000000000000000000000000000000000000000000000000" +
-                "0000000000000000000000000000000000000000000000000000000000000000" +
-                "63 82 53 63" +
-                "35 01 02" +
-                "36 04 AC188A0B" +
-                "33 04 00000708" +
-                "01 04 FFFFF000" +
-                "03 04 64706FFE" +
-                "06 08 08080808" +
-                "      08080404" +
-                "FF0001076165313A363636FF";
-
-        final String expectedPrefix =
-                "RX 28:8a:1c:a8:df:c1 > 80:7a:bf:6f:48:f3 ipv4" +
-                " 100.112.111.253 > 100.112.106.219 udp" +
-                " 67 > 68 dhcp4" +
-                " 80:7a:bf:6f:48:f3 OFFER";
-
-        assertTrue(getSummary(packet).startsWith(expectedPrefix));
-    }
-
-    @Test
-    public void testParseDHCPv4Request() {
-        final String packet =
-                // Ethernet
-                "FFFFFFFFFFFF 807ABF6F48F3 0800" +
-                // IPv4
-                "45100164000040004011397A" +
-                "00000000" +
-                "FFFFFFFF" +
-                // UDP
-                "0044 0043" +
-                "0150 E5C7" +
-                // DHCPv4
-                "01 01 06 00" +
-                "79F7ACA4" +
-                "0001 0000" +
-                "00000000" +
-                "00000000" +
-                "00000000" +
-                "00000000" +
-                "807ABF6F48F300000000000000000000" +
-                "0000000000000000000000000000000000000000000000000000000000000000" +
-                "0000000000000000000000000000000000000000000000000000000000000000" +
-                "0000000000000000000000000000000000000000000000000000000000000000" +
-                "0000000000000000000000000000000000000000000000000000000000000000" +
-                "0000000000000000000000000000000000000000000000000000000000000000" +
-                "0000000000000000000000000000000000000000000000000000000000000000" +
-                "63 82 53 63" +
-                "35 01 03" +
-                "3D 07 01807ABF6F48F3" +
-                "32 04 64706ADB" +
-                "36 04 AC188A0B" +
-                "39 02 05DC" +
-                "3C 12 616E64726F69642D646863702D372E312E32" +
-                "0C 18 616E64726F69642D36623030366333313333393835343139" +
-                "37 0A 01 03 06 0F 1A 1C 33 3A 3B 2B" +
-                "FF" +
-                "00";
-
-        final String expectedPrefix =
-                "TX 80:7a:bf:6f:48:f3 > ff:ff:ff:ff:ff:ff ipv4" +
-                " 0.0.0.0 > 255.255.255.255 udp" +
-                " 68 > 67 dhcp4" +
-                " 80:7a:bf:6f:48:f3 REQUEST";
-
-        assertTrue(getSummary(packet).startsWith(expectedPrefix));
-    }
-
-    @Test
-    public void testParseDHCPv4Ack() {
-        final String packet =
-                // Ethernet
-                "807ABF6F48F3 288A1CA8DFC1 0800" +
-                // IPv4
-                "4500013D4D3B0000401188BC" +
-                "64706FFD" +
-                "64706ADB" +
-                // UDP
-                "0043 0044" +
-                "0129 341C" +
-                // DHCPv4
-                "02 01 06 01" +
-                "79F7ACA4" +
-                "0001 0000" +
-                "00000000" +
-                "64706ADB" +
-                "00000000" +
-                "00000000" +
-                "807ABF6F48F300000000000000000000" +
-                "0000000000000000000000000000000000000000000000000000000000000000" +
-                "0000000000000000000000000000000000000000000000000000000000000000" +
-                "0000000000000000000000000000000000000000000000000000000000000000" +
-                "0000000000000000000000000000000000000000000000000000000000000000" +
-                "0000000000000000000000000000000000000000000000000000000000000000" +
-                "0000000000000000000000000000000000000000000000000000000000000000" +
-                "63 82 53 63" +
-                "35 01 05" +
-                "36 04 AC188A0B" +
-                "33 04 00000708" +
-                "01 04 FFFFF000" +
-                "03 04 64706FFE" +
-                "06 08 08080808" +
-                "      08080404" +
-                "FF0001076165313A363636FF";
-
-        final String expectedPrefix =
-                "RX 28:8a:1c:a8:df:c1 > 80:7a:bf:6f:48:f3 ipv4" +
-                " 100.112.111.253 > 100.112.106.219 udp" +
-                " 67 > 68 dhcp4" +
-                " 80:7a:bf:6f:48:f3 ACK";
-
-        assertTrue(getSummary(packet).startsWith(expectedPrefix));
-    }
-}
diff --git a/packages/NetworkStack/tests/unit/src/android/net/util/PacketReaderTest.java b/packages/NetworkStack/tests/unit/src/android/net/util/PacketReaderTest.java
deleted file mode 100644
index 289dcad..0000000
--- a/packages/NetworkStack/tests/unit/src/android/net/util/PacketReaderTest.java
+++ /dev/null
@@ -1,211 +0,0 @@
-/*
- * Copyright (C) 2016 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.net.util;
-
-import static android.net.util.PacketReader.DEFAULT_RECV_BUF_SIZE;
-import static android.system.OsConstants.AF_INET6;
-import static android.system.OsConstants.IPPROTO_UDP;
-import static android.system.OsConstants.SOCK_DGRAM;
-import static android.system.OsConstants.SOCK_NONBLOCK;
-import static android.system.OsConstants.SOL_SOCKET;
-import static android.system.OsConstants.SO_SNDTIMEO;
-
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertFalse;
-import static org.junit.Assert.assertTrue;
-import static org.junit.Assert.fail;
-
-import android.os.Handler;
-import android.os.HandlerThread;
-import android.system.ErrnoException;
-import android.system.Os;
-import android.system.StructTimeval;
-
-import androidx.test.filters.SmallTest;
-import androidx.test.runner.AndroidJUnit4;
-
-import org.junit.After;
-import org.junit.Before;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-
-import java.io.FileDescriptor;
-import java.net.DatagramPacket;
-import java.net.DatagramSocket;
-import java.net.Inet6Address;
-import java.net.InetAddress;
-import java.net.InetSocketAddress;
-import java.net.SocketException;
-import java.util.Arrays;
-import java.util.concurrent.CountDownLatch;
-import java.util.concurrent.TimeUnit;
-
-/**
- * Tests for PacketReader.
- *
- * @hide
- */
-@RunWith(AndroidJUnit4.class)
-@SmallTest
-public class PacketReaderTest {
-    static final InetAddress LOOPBACK6 = Inet6Address.getLoopbackAddress();
-    static final StructTimeval TIMEO = StructTimeval.fromMillis(500);
-
-    protected CountDownLatch mLatch;
-    protected FileDescriptor mLocalSocket;
-    protected InetSocketAddress mLocalSockName;
-    protected byte[] mLastRecvBuf;
-    protected boolean mStopped;
-    protected HandlerThread mHandlerThread;
-    protected PacketReader mReceiver;
-
-    class UdpLoopbackReader extends PacketReader {
-        public UdpLoopbackReader(Handler h) {
-            super(h);
-        }
-
-        @Override
-        protected FileDescriptor createFd() {
-            FileDescriptor s = null;
-            try {
-                s = Os.socket(AF_INET6, SOCK_DGRAM | SOCK_NONBLOCK, IPPROTO_UDP);
-                Os.bind(s, LOOPBACK6, 0);
-                mLocalSockName = (InetSocketAddress) Os.getsockname(s);
-                Os.setsockoptTimeval(s, SOL_SOCKET, SO_SNDTIMEO, TIMEO);
-            } catch (ErrnoException|SocketException e) {
-                closeFd(s);
-                fail();
-                return null;
-            }
-
-            mLocalSocket = s;
-            return s;
-        }
-
-        @Override
-        protected void handlePacket(byte[] recvbuf, int length) {
-            mLastRecvBuf = Arrays.copyOf(recvbuf, length);
-            mLatch.countDown();
-        }
-
-        @Override
-        protected void onStart() {
-            mStopped = false;
-            mLatch.countDown();
-        }
-
-        @Override
-        protected void onStop() {
-            mStopped = true;
-            mLatch.countDown();
-        }
-    };
-
-    @Before
-    public void setUp() {
-        resetLatch();
-        mLocalSocket = null;
-        mLocalSockName = null;
-        mLastRecvBuf = null;
-        mStopped = false;
-
-        mHandlerThread = new HandlerThread(PacketReaderTest.class.getSimpleName());
-        mHandlerThread.start();
-    }
-
-    @After
-    public void tearDown() throws Exception {
-        if (mReceiver != null) {
-            mHandlerThread.getThreadHandler().post(() -> { mReceiver.stop(); });
-            waitForActivity();
-        }
-        mReceiver = null;
-        mHandlerThread.quit();
-        mHandlerThread = null;
-    }
-
-    void resetLatch() { mLatch = new CountDownLatch(1); }
-
-    void waitForActivity() throws Exception {
-        try {
-            mLatch.await(1000, TimeUnit.MILLISECONDS);
-        } finally {
-            resetLatch();
-        }
-    }
-
-    void sendPacket(byte[] contents) throws Exception {
-        final DatagramSocket sender = new DatagramSocket();
-        sender.connect(mLocalSockName);
-        sender.send(new DatagramPacket(contents, contents.length));
-        sender.close();
-    }
-
-    @Test
-    public void testBasicWorking() throws Exception {
-        final Handler h = mHandlerThread.getThreadHandler();
-        mReceiver = new UdpLoopbackReader(h);
-
-        h.post(() -> { mReceiver.start(); });
-        waitForActivity();
-        assertTrue(mLocalSockName != null);
-        assertEquals(LOOPBACK6, mLocalSockName.getAddress());
-        assertTrue(0 < mLocalSockName.getPort());
-        assertTrue(mLocalSocket != null);
-        assertFalse(mStopped);
-
-        final byte[] one = "one 1".getBytes("UTF-8");
-        sendPacket(one);
-        waitForActivity();
-        assertEquals(1, mReceiver.numPacketsReceived());
-        assertTrue(Arrays.equals(one, mLastRecvBuf));
-        assertFalse(mStopped);
-
-        final byte[] two = "two 2".getBytes("UTF-8");
-        sendPacket(two);
-        waitForActivity();
-        assertEquals(2, mReceiver.numPacketsReceived());
-        assertTrue(Arrays.equals(two, mLastRecvBuf));
-        assertFalse(mStopped);
-
-        mReceiver.stop();
-        waitForActivity();
-        assertEquals(2, mReceiver.numPacketsReceived());
-        assertTrue(Arrays.equals(two, mLastRecvBuf));
-        assertTrue(mStopped);
-        mReceiver = null;
-    }
-
-    class NullPacketReader extends PacketReader {
-        public NullPacketReader(Handler h, int recvbufsize) {
-            super(h, recvbufsize);
-        }
-
-        @Override
-        public FileDescriptor createFd() { return null; }
-    }
-
-    @Test
-    public void testMinimalRecvBufSize() throws Exception {
-        final Handler h = mHandlerThread.getThreadHandler();
-
-        for (int i : new int[]{-1, 0, 1, DEFAULT_RECV_BUF_SIZE-1}) {
-            final PacketReader b = new NullPacketReader(h, i);
-            assertEquals(DEFAULT_RECV_BUF_SIZE, b.recvBufSize());
-        }
-    }
-}
diff --git a/packages/NetworkStack/tests/unit/src/com/android/server/connectivity/NetworkMonitorTest.java b/packages/NetworkStack/tests/unit/src/com/android/server/connectivity/NetworkMonitorTest.java
deleted file mode 100644
index 262641d..0000000
--- a/packages/NetworkStack/tests/unit/src/com/android/server/connectivity/NetworkMonitorTest.java
+++ /dev/null
@@ -1,1161 +0,0 @@
-/*
- * Copyright (C) 2017 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.connectivity;
-
-import static android.net.CaptivePortal.APP_RETURN_DISMISSED;
-import static android.net.INetworkMonitor.NETWORK_VALIDATION_PROBE_DNS;
-import static android.net.INetworkMonitor.NETWORK_VALIDATION_PROBE_FALLBACK;
-import static android.net.INetworkMonitor.NETWORK_VALIDATION_PROBE_HTTP;
-import static android.net.INetworkMonitor.NETWORK_VALIDATION_PROBE_HTTPS;
-import static android.net.INetworkMonitor.NETWORK_VALIDATION_PROBE_PRIVDNS;
-import static android.net.INetworkMonitor.NETWORK_VALIDATION_RESULT_PARTIAL;
-import static android.net.INetworkMonitor.NETWORK_VALIDATION_RESULT_VALID;
-import static android.net.NetworkCapabilities.NET_CAPABILITY_INTERNET;
-import static android.net.util.DataStallUtils.CONFIG_DATA_STALL_CONSECUTIVE_DNS_TIMEOUT_THRESHOLD;
-import static android.net.util.DataStallUtils.CONFIG_DATA_STALL_EVALUATION_TYPE;
-import static android.net.util.DataStallUtils.CONFIG_DATA_STALL_MIN_EVALUATE_INTERVAL;
-import static android.net.util.DataStallUtils.CONFIG_DATA_STALL_VALID_DNS_TIME_THRESHOLD;
-import static android.net.util.DataStallUtils.DATA_STALL_EVALUATION_TYPE_DNS;
-import static android.net.util.NetworkStackUtils.CAPTIVE_PORTAL_FALLBACK_PROBE_SPECS;
-import static android.net.util.NetworkStackUtils.CAPTIVE_PORTAL_OTHER_FALLBACK_URLS;
-import static android.net.util.NetworkStackUtils.CAPTIVE_PORTAL_USE_HTTPS;
-
-import static junit.framework.Assert.assertEquals;
-import static junit.framework.Assert.assertFalse;
-
-import static org.junit.Assert.assertArrayEquals;
-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 static org.mockito.ArgumentMatchers.eq;
-import static org.mockito.Mockito.any;
-import static org.mockito.Mockito.anyInt;
-import static org.mockito.Mockito.doAnswer;
-import static org.mockito.Mockito.doReturn;
-import static org.mockito.Mockito.doThrow;
-import static org.mockito.Mockito.never;
-import static org.mockito.Mockito.reset;
-import static org.mockito.Mockito.timeout;
-import static org.mockito.Mockito.times;
-import static org.mockito.Mockito.verify;
-import static org.mockito.Mockito.when;
-
-import android.annotation.NonNull;
-import android.content.BroadcastReceiver;
-import android.content.Context;
-import android.content.Intent;
-import android.content.res.Resources;
-import android.net.ConnectivityManager;
-import android.net.DnsResolver;
-import android.net.INetworkMonitorCallbacks;
-import android.net.InetAddresses;
-import android.net.LinkProperties;
-import android.net.Network;
-import android.net.NetworkCapabilities;
-import android.net.NetworkInfo;
-import android.net.captiveportal.CaptivePortalProbeResult;
-import android.net.metrics.IpConnectivityLog;
-import android.net.shared.PrivateDnsConfig;
-import android.net.util.SharedLog;
-import android.net.wifi.WifiInfo;
-import android.net.wifi.WifiManager;
-import android.os.Bundle;
-import android.os.ConditionVariable;
-import android.os.Handler;
-import android.os.Looper;
-import android.os.Process;
-import android.os.RemoteException;
-import android.os.SystemClock;
-import android.provider.Settings;
-import android.telephony.CellSignalStrength;
-import android.telephony.TelephonyManager;
-import android.util.ArrayMap;
-
-import androidx.test.filters.SmallTest;
-import androidx.test.runner.AndroidJUnit4;
-
-import com.android.networkstack.R;
-import com.android.networkstack.metrics.DataStallDetectionStats;
-import com.android.networkstack.metrics.DataStallStatsUtils;
-
-import org.junit.After;
-import org.junit.Before;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.mockito.ArgumentCaptor;
-import org.mockito.Captor;
-import org.mockito.Mock;
-import org.mockito.MockitoAnnotations;
-import org.mockito.Spy;
-import org.mockito.verification.VerificationWithTimeout;
-
-import java.io.IOException;
-import java.net.HttpURLConnection;
-import java.net.InetAddress;
-import java.net.URL;
-import java.net.UnknownHostException;
-import java.util.ArrayList;
-import java.util.HashSet;
-import java.util.List;
-import java.util.Random;
-import java.util.concurrent.Executor;
-
-import javax.net.ssl.SSLHandshakeException;
-
-@RunWith(AndroidJUnit4.class)
-@SmallTest
-public class NetworkMonitorTest {
-    private static final String LOCATION_HEADER = "location";
-
-    private @Mock Context mContext;
-    private @Mock Resources mResources;
-    private @Mock IpConnectivityLog mLogger;
-    private @Mock SharedLog mValidationLogger;
-    private @Mock NetworkInfo mNetworkInfo;
-    private @Mock DnsResolver mDnsResolver;
-    private @Mock ConnectivityManager mCm;
-    private @Mock TelephonyManager mTelephony;
-    private @Mock WifiManager mWifi;
-    private @Mock HttpURLConnection mHttpConnection;
-    private @Mock HttpURLConnection mHttpsConnection;
-    private @Mock HttpURLConnection mFallbackConnection;
-    private @Mock HttpURLConnection mOtherFallbackConnection;
-    private @Mock Random mRandom;
-    private @Mock NetworkMonitor.Dependencies mDependencies;
-    private @Mock INetworkMonitorCallbacks mCallbacks;
-    private @Spy Network mCleartextDnsNetwork = new Network(TEST_NETID);
-    private @Mock Network mNetwork;
-    private @Mock DataStallStatsUtils mDataStallStatsUtils;
-    private @Mock WifiInfo mWifiInfo;
-    private @Captor ArgumentCaptor<String> mNetworkTestedRedirectUrlCaptor;
-
-    private HashSet<WrappedNetworkMonitor> mCreatedNetworkMonitors;
-    private HashSet<BroadcastReceiver> mRegisteredReceivers;
-
-    private static final int TEST_NETID = 4242;
-    private static final String TEST_HTTP_URL = "http://www.google.com/gen_204";
-    private static final String TEST_HTTPS_URL = "https://www.google.com/gen_204";
-    private static final String TEST_FALLBACK_URL = "http://fallback.google.com/gen_204";
-    private static final String TEST_OTHER_FALLBACK_URL = "http://otherfallback.google.com/gen_204";
-    private static final String TEST_MCCMNC = "123456";
-
-    private static final int VALIDATION_RESULT_INVALID = 0;
-    private static final int VALIDATION_RESULT_PORTAL = 0;
-    private static final String TEST_REDIRECT_URL = "android.com";
-    private static final int VALIDATION_RESULT_PARTIAL = NETWORK_VALIDATION_PROBE_DNS
-            | NETWORK_VALIDATION_PROBE_HTTP
-            | NETWORK_VALIDATION_RESULT_PARTIAL;
-    private static final int VALIDATION_RESULT_FALLBACK_PARTIAL = NETWORK_VALIDATION_PROBE_DNS
-            | NETWORK_VALIDATION_PROBE_FALLBACK
-            | NETWORK_VALIDATION_RESULT_PARTIAL;
-    private static final int VALIDATION_RESULT_VALID = NETWORK_VALIDATION_PROBE_DNS
-            | NETWORK_VALIDATION_PROBE_HTTPS
-            | NETWORK_VALIDATION_RESULT_VALID;
-
-    private static final int RETURN_CODE_DNS_SUCCESS = 0;
-    private static final int RETURN_CODE_DNS_TIMEOUT = 255;
-    private static final int DEFAULT_DNS_TIMEOUT_THRESHOLD = 5;
-
-    private static final int HANDLER_TIMEOUT_MS = 1000;
-
-    private static final LinkProperties TEST_LINK_PROPERTIES = new LinkProperties();
-
-    private static final NetworkCapabilities METERED_CAPABILITIES = new NetworkCapabilities()
-            .addTransportType(NetworkCapabilities.TRANSPORT_CELLULAR)
-            .addCapability(NET_CAPABILITY_INTERNET);
-
-    private static final NetworkCapabilities NOT_METERED_CAPABILITIES = new NetworkCapabilities()
-            .addTransportType(NetworkCapabilities.TRANSPORT_CELLULAR)
-            .addCapability(NET_CAPABILITY_INTERNET)
-            .addCapability(NetworkCapabilities.NET_CAPABILITY_NOT_METERED);
-
-    private static final NetworkCapabilities NO_INTERNET_CAPABILITIES = new NetworkCapabilities()
-            .addTransportType(NetworkCapabilities.TRANSPORT_CELLULAR);
-
-    /**
-     * Fakes DNS responses.
-     *
-     * Allows test methods to configure the IP addresses that will be resolved by
-     * Network#getAllByName and by DnsResolver#query.
-     */
-    class FakeDns {
-        private final ArrayMap<String, List<InetAddress>> mAnswers = new ArrayMap<>();
-        private boolean mNonBypassPrivateDnsWorking = true;
-
-        /** Whether DNS queries on mNonBypassPrivateDnsWorking should succeed. */
-        private void setNonBypassPrivateDnsWorking(boolean working) {
-            mNonBypassPrivateDnsWorking = working;
-        }
-
-        /** Clears all DNS entries. */
-        private synchronized void clearAll() {
-            mAnswers.clear();
-        }
-
-        /** Returns the answer for a given name on the given mock network. */
-        private synchronized List<InetAddress> getAnswer(Object mock, String hostname) {
-            if (mock == mNetwork && !mNonBypassPrivateDnsWorking) {
-                return null;
-            }
-            if (mAnswers.containsKey(hostname)) {
-                return mAnswers.get(hostname);
-            }
-            return mAnswers.get("*");
-        }
-
-        /** Sets the answer for a given name. */
-        private synchronized void setAnswer(String hostname, String[] answer)
-                throws UnknownHostException {
-            if (answer == null) {
-                mAnswers.remove(hostname);
-            } else {
-                List<InetAddress> answerList = new ArrayList<>();
-                for (String addr : answer) {
-                    answerList.add(InetAddresses.parseNumericAddress(addr));
-                }
-                mAnswers.put(hostname, answerList);
-            }
-        }
-
-        /** Simulates a getAllByName call for the specified name on the specified mock network. */
-        private InetAddress[] getAllByName(Object mock, String hostname)
-                throws UnknownHostException {
-            List<InetAddress> answer = getAnswer(mock, hostname);
-            if (answer == null || answer.size() == 0) {
-                throw new UnknownHostException(hostname);
-            }
-            return answer.toArray(new InetAddress[0]);
-        }
-
-        /** Starts mocking DNS queries. */
-        private void startMocking() throws UnknownHostException {
-            // Queries on mNetwork using getAllByName.
-            doAnswer(invocation -> {
-                return getAllByName(invocation.getMock(), invocation.getArgument(0));
-            }).when(mNetwork).getAllByName(any());
-
-            // Queries on mCleartextDnsNetwork using DnsResolver#query.
-            doAnswer(invocation -> {
-                String hostname = (String) invocation.getArgument(1);
-                Executor executor = (Executor) invocation.getArgument(3);
-                DnsResolver.Callback<List<InetAddress>> callback = invocation.getArgument(5);
-
-                List<InetAddress> answer = getAnswer(invocation.getMock(), hostname);
-                if (answer != null && answer.size() > 0) {
-                    new Handler(Looper.getMainLooper()).post(() -> {
-                        executor.execute(() -> callback.onAnswer(answer, 0));
-                    });
-                }
-                // If no answers, do nothing. sendDnsProbeWithTimeout will time out and throw UHE.
-                return null;
-            }).when(mDnsResolver).query(any(), any(), anyInt(), any(), any(), any());
-
-            // Queries on mCleartextDnsNetwork using using DnsResolver#query with QueryType.
-            doAnswer(invocation -> {
-                String hostname = (String) invocation.getArgument(1);
-                Executor executor = (Executor) invocation.getArgument(4);
-                DnsResolver.Callback<List<InetAddress>> callback = invocation.getArgument(6);
-
-                List<InetAddress> answer = getAnswer(invocation.getMock(), hostname);
-                if (answer != null && answer.size() > 0) {
-                    new Handler(Looper.getMainLooper()).post(() -> {
-                        executor.execute(() -> callback.onAnswer(answer, 0));
-                    });
-                }
-                // If no answers, do nothing. sendDnsProbeWithTimeout will time out and throw UHE.
-                return null;
-            }).when(mDnsResolver).query(any(), any(), anyInt(), anyInt(), any(), any(), any());
-        }
-    }
-
-    private FakeDns mFakeDns;
-
-    @Before
-    public void setUp() throws IOException {
-        MockitoAnnotations.initMocks(this);
-        when(mDependencies.getPrivateDnsBypassNetwork(any())).thenReturn(mCleartextDnsNetwork);
-        when(mDependencies.getDnsResolver()).thenReturn(mDnsResolver);
-        when(mDependencies.getRandom()).thenReturn(mRandom);
-        when(mDependencies.getSetting(any(), eq(Settings.Global.CAPTIVE_PORTAL_MODE), anyInt()))
-                .thenReturn(Settings.Global.CAPTIVE_PORTAL_MODE_PROMPT);
-        when(mDependencies.getDeviceConfigPropertyInt(any(), eq(CAPTIVE_PORTAL_USE_HTTPS),
-                anyInt())).thenReturn(1);
-        when(mDependencies.getSetting(any(), eq(Settings.Global.CAPTIVE_PORTAL_HTTP_URL), any()))
-                .thenReturn(TEST_HTTP_URL);
-        when(mDependencies.getSetting(any(), eq(Settings.Global.CAPTIVE_PORTAL_HTTPS_URL), any()))
-                .thenReturn(TEST_HTTPS_URL);
-
-        doReturn(mCleartextDnsNetwork).when(mNetwork).getPrivateDnsBypassingCopy();
-
-        when(mContext.getSystemService(Context.CONNECTIVITY_SERVICE)).thenReturn(mCm);
-        when(mContext.getSystemService(Context.TELEPHONY_SERVICE)).thenReturn(mTelephony);
-        when(mContext.getSystemService(Context.WIFI_SERVICE)).thenReturn(mWifi);
-        when(mContext.getResources()).thenReturn(mResources);
-
-        when(mResources.getString(anyInt())).thenReturn("");
-        when(mResources.getStringArray(anyInt())).thenReturn(new String[0]);
-
-        when(mNetworkInfo.getType()).thenReturn(ConnectivityManager.TYPE_WIFI);
-        setFallbackUrl(TEST_FALLBACK_URL);
-        setOtherFallbackUrls(TEST_OTHER_FALLBACK_URL);
-        setFallbackSpecs(null); // Test with no fallback spec by default
-        when(mRandom.nextInt()).thenReturn(0);
-
-        // DNS probe timeout should not be defined more than half of HANDLER_TIMEOUT_MS. Otherwise,
-        // it will fail the test because of timeout expired for querying AAAA and A sequentially.
-        when(mResources.getInteger(eq(R.integer.config_captive_portal_dns_probe_timeout)))
-                .thenReturn(200);
-
-        doAnswer((invocation) -> {
-            URL url = invocation.getArgument(0);
-            switch(url.toString()) {
-                case TEST_HTTP_URL:
-                    return mHttpConnection;
-                case TEST_HTTPS_URL:
-                    return mHttpsConnection;
-                case TEST_FALLBACK_URL:
-                    return mFallbackConnection;
-                case TEST_OTHER_FALLBACK_URL:
-                    return mOtherFallbackConnection;
-                default:
-                    fail("URL not mocked: " + url.toString());
-                    return null;
-            }
-        }).when(mCleartextDnsNetwork).openConnection(any());
-        when(mHttpConnection.getRequestProperties()).thenReturn(new ArrayMap<>());
-        when(mHttpsConnection.getRequestProperties()).thenReturn(new ArrayMap<>());
-
-        mFakeDns = new FakeDns();
-        mFakeDns.startMocking();
-        mFakeDns.setAnswer("*", new String[]{"2001:db8::1", "192.0.2.2"});
-
-        when(mContext.registerReceiver(any(BroadcastReceiver.class), any())).then((invocation) -> {
-            mRegisteredReceivers.add(invocation.getArgument(0));
-            return new Intent();
-        });
-
-        doAnswer((invocation) -> {
-            mRegisteredReceivers.remove(invocation.getArgument(0));
-            return null;
-        }).when(mContext).unregisterReceiver(any());
-
-        setMinDataStallEvaluateInterval(500);
-        setDataStallEvaluationType(DATA_STALL_EVALUATION_TYPE_DNS);
-        setValidDataStallDnsTimeThreshold(500);
-        setConsecutiveDnsTimeoutThreshold(5);
-
-        mCreatedNetworkMonitors = new HashSet<>();
-        mRegisteredReceivers = new HashSet<>();
-    }
-
-    @After
-    public void tearDown() {
-        mFakeDns.clearAll();
-        assertTrue(mCreatedNetworkMonitors.size() > 0);
-        // Make a local copy of mCreatedNetworkMonitors because during the iteration below,
-        // WrappedNetworkMonitor#onQuitting will delete elements from it on the handler threads.
-        WrappedNetworkMonitor[] networkMonitors = mCreatedNetworkMonitors.toArray(
-                new WrappedNetworkMonitor[0]);
-        for (WrappedNetworkMonitor nm : networkMonitors) {
-            nm.notifyNetworkDisconnected();
-            nm.awaitQuit();
-        }
-        assertEquals("NetworkMonitor still running after disconnect",
-                0, mCreatedNetworkMonitors.size());
-        assertEquals("BroadcastReceiver still registered after disconnect",
-                0, mRegisteredReceivers.size());
-    }
-
-    private class WrappedNetworkMonitor extends NetworkMonitor {
-        private long mProbeTime = 0;
-        private final ConditionVariable mQuitCv = new ConditionVariable(false);
-
-        WrappedNetworkMonitor() {
-            super(mContext, mCallbacks, mNetwork, mLogger, mValidationLogger,
-                    mDependencies, mDataStallStatsUtils);
-        }
-
-        @Override
-        protected long getLastProbeTime() {
-            return mProbeTime;
-        }
-
-        protected void setLastProbeTime(long time) {
-            mProbeTime = time;
-        }
-
-        @Override
-        protected void addDnsEvents(@NonNull final DataStallDetectionStats.Builder stats) {
-            generateTimeoutDnsEvent(stats, DEFAULT_DNS_TIMEOUT_THRESHOLD);
-        }
-
-        @Override
-        protected void onQuitting() {
-            assertTrue(mCreatedNetworkMonitors.remove(this));
-            mQuitCv.open();
-        }
-
-        protected void awaitQuit() {
-            assertTrue("NetworkMonitor did not quit after " + HANDLER_TIMEOUT_MS + "ms",
-                    mQuitCv.block(HANDLER_TIMEOUT_MS));
-        }
-    }
-
-    private WrappedNetworkMonitor makeMonitor(NetworkCapabilities nc) {
-        final WrappedNetworkMonitor nm = new WrappedNetworkMonitor();
-        nm.start();
-        setNetworkCapabilities(nm, nc);
-        waitForIdle(nm.getHandler());
-        mCreatedNetworkMonitors.add(nm);
-        return nm;
-    }
-
-    private WrappedNetworkMonitor makeMeteredNetworkMonitor() {
-        final WrappedNetworkMonitor nm = makeMonitor(METERED_CAPABILITIES);
-        return nm;
-    }
-
-    private WrappedNetworkMonitor makeNotMeteredNetworkMonitor() {
-        final WrappedNetworkMonitor nm = makeMonitor(NOT_METERED_CAPABILITIES);
-        return nm;
-    }
-
-    private void setNetworkCapabilities(NetworkMonitor nm, NetworkCapabilities nc) {
-        nm.notifyNetworkCapabilitiesChanged(nc);
-        waitForIdle(nm.getHandler());
-    }
-
-    private void waitForIdle(Handler handler) {
-        final ConditionVariable cv = new ConditionVariable(false);
-        handler.post(cv::open);
-        if (!cv.block(HANDLER_TIMEOUT_MS)) {
-            fail("Timed out waiting for handler");
-        }
-    }
-
-    @Test
-    public void testGetIntSetting() throws Exception {
-        WrappedNetworkMonitor wnm = makeNotMeteredNetworkMonitor();
-
-        // No config resource, no device config. Expect to get default resource.
-        doThrow(new Resources.NotFoundException())
-                .when(mResources).getInteger(eq(R.integer.config_captive_portal_dns_probe_timeout));
-        doAnswer(invocation -> {
-            int defaultValue = invocation.getArgument(2);
-            return defaultValue;
-        }).when(mDependencies).getDeviceConfigPropertyInt(any(),
-                eq(NetworkMonitor.CONFIG_CAPTIVE_PORTAL_DNS_PROBE_TIMEOUT),
-                anyInt());
-        when(mResources.getInteger(eq(R.integer.default_captive_portal_dns_probe_timeout)))
-                .thenReturn(42);
-        assertEquals(42, wnm.getIntSetting(mContext,
-                R.integer.config_captive_portal_dns_probe_timeout,
-                NetworkMonitor.CONFIG_CAPTIVE_PORTAL_DNS_PROBE_TIMEOUT,
-                R.integer.default_captive_portal_dns_probe_timeout));
-
-        // Set device config. Expect to get device config.
-        when(mDependencies.getDeviceConfigPropertyInt(any(),
-                eq(NetworkMonitor.CONFIG_CAPTIVE_PORTAL_DNS_PROBE_TIMEOUT), anyInt()))
-                        .thenReturn(1234);
-        assertEquals(1234, wnm.getIntSetting(mContext,
-                R.integer.config_captive_portal_dns_probe_timeout,
-                NetworkMonitor.CONFIG_CAPTIVE_PORTAL_DNS_PROBE_TIMEOUT,
-                R.integer.default_captive_portal_dns_probe_timeout));
-
-        // Set config resource. Expect to get config resource.
-        when(mResources.getInteger(eq(R.integer.config_captive_portal_dns_probe_timeout)))
-                .thenReturn(5678);
-        assertEquals(5678, wnm.getIntSetting(mContext,
-                R.integer.config_captive_portal_dns_probe_timeout,
-                NetworkMonitor.CONFIG_CAPTIVE_PORTAL_DNS_PROBE_TIMEOUT,
-                R.integer.default_captive_portal_dns_probe_timeout));
-    }
-
-    @Test
-    public void testIsCaptivePortal_HttpProbeIsPortal() throws IOException {
-        setSslException(mHttpsConnection);
-        setPortal302(mHttpConnection);
-        runPortalNetworkTest(VALIDATION_RESULT_PORTAL);
-    }
-
-    @Test
-    public void testIsCaptivePortal_HttpsProbeIsNotPortal() throws IOException {
-        setStatus(mHttpsConnection, 204);
-        setStatus(mHttpConnection, 500);
-
-        runNotPortalNetworkTest();
-    }
-
-    @Test
-    public void testIsCaptivePortal_FallbackProbeIsPortal() throws IOException {
-        setSslException(mHttpsConnection);
-        setStatus(mHttpConnection, 500);
-        setPortal302(mFallbackConnection);
-        runPortalNetworkTest(VALIDATION_RESULT_INVALID);
-    }
-
-    @Test
-    public void testIsCaptivePortal_FallbackProbeIsNotPortal() throws IOException {
-        setSslException(mHttpsConnection);
-        setStatus(mHttpConnection, 500);
-        setStatus(mFallbackConnection, 500);
-
-        // Fallback probe did not see portal, HTTPS failed -> inconclusive
-        runFailedNetworkTest();
-    }
-
-    @Test
-    public void testIsCaptivePortal_OtherFallbackProbeIsPortal() throws IOException {
-        // Set all fallback probes but one to invalid URLs to verify they are being skipped
-        setFallbackUrl(TEST_FALLBACK_URL);
-        setOtherFallbackUrls(TEST_FALLBACK_URL + "," + TEST_OTHER_FALLBACK_URL);
-
-        setSslException(mHttpsConnection);
-        setStatus(mHttpConnection, 500);
-        setStatus(mFallbackConnection, 500);
-        setPortal302(mOtherFallbackConnection);
-
-        // TEST_OTHER_FALLBACK_URL is third
-        when(mRandom.nextInt()).thenReturn(2);
-
-        // First check always uses the first fallback URL: inconclusive
-        final NetworkMonitor monitor = runNetworkTest(VALIDATION_RESULT_INVALID);
-        assertNull(mNetworkTestedRedirectUrlCaptor.getValue());
-        verify(mFallbackConnection, times(1)).getResponseCode();
-        verify(mOtherFallbackConnection, never()).getResponseCode();
-
-        // Second check uses the URL chosen by Random
-        final CaptivePortalProbeResult result = monitor.isCaptivePortal();
-        assertTrue(result.isPortal());
-        verify(mOtherFallbackConnection, times(1)).getResponseCode();
-    }
-
-    @Test
-    public void testIsCaptivePortal_AllProbesFailed() throws IOException {
-        setSslException(mHttpsConnection);
-        setStatus(mHttpConnection, 500);
-        setStatus(mFallbackConnection, 404);
-
-        runFailedNetworkTest();
-        verify(mFallbackConnection, times(1)).getResponseCode();
-        verify(mOtherFallbackConnection, never()).getResponseCode();
-    }
-
-    @Test
-    public void testIsCaptivePortal_InvalidUrlSkipped() throws IOException {
-        setFallbackUrl("invalid");
-        setOtherFallbackUrls("otherinvalid," + TEST_OTHER_FALLBACK_URL + ",yetanotherinvalid");
-
-        setSslException(mHttpsConnection);
-        setStatus(mHttpConnection, 500);
-        setPortal302(mOtherFallbackConnection);
-        runPortalNetworkTest(VALIDATION_RESULT_INVALID);
-        verify(mOtherFallbackConnection, times(1)).getResponseCode();
-        verify(mFallbackConnection, never()).getResponseCode();
-    }
-
-    private void setupFallbackSpec() throws IOException {
-        setFallbackSpecs("http://example.com@@/@@204@@/@@"
-                + "@@,@@"
-                + TEST_OTHER_FALLBACK_URL + "@@/@@30[12]@@/@@https://(www\\.)?google.com/?.*");
-
-        setSslException(mHttpsConnection);
-        setStatus(mHttpConnection, 500);
-
-        // Use the 2nd fallback spec
-        when(mRandom.nextInt()).thenReturn(1);
-    }
-
-    @Test
-    public void testIsCaptivePortal_FallbackSpecIsPartial() throws IOException {
-        setupFallbackSpec();
-        set302(mOtherFallbackConnection, "https://www.google.com/test?q=3");
-
-        // HTTPS failed, fallback spec went through -> partial connectivity
-        runPartialConnectivityNetworkTest(VALIDATION_RESULT_FALLBACK_PARTIAL);
-        verify(mOtherFallbackConnection, times(1)).getResponseCode();
-        verify(mFallbackConnection, never()).getResponseCode();
-    }
-
-    @Test
-    public void testIsCaptivePortal_FallbackSpecIsPortal() throws IOException {
-        setupFallbackSpec();
-        set302(mOtherFallbackConnection, "http://login.portal.example.com");
-        runPortalNetworkTest(VALIDATION_RESULT_INVALID);
-    }
-
-    @Test
-    public void testIsCaptivePortal_IgnorePortals() throws IOException {
-        setCaptivePortalMode(Settings.Global.CAPTIVE_PORTAL_MODE_IGNORE);
-        setSslException(mHttpsConnection);
-        setPortal302(mHttpConnection);
-
-        runNoValidationNetworkTest();
-    }
-
-    @Test
-    public void testIsDataStall_EvaluationDisabled() {
-        setDataStallEvaluationType(0);
-        WrappedNetworkMonitor wrappedMonitor = makeMeteredNetworkMonitor();
-        wrappedMonitor.setLastProbeTime(SystemClock.elapsedRealtime() - 100);
-        assertFalse(wrappedMonitor.isDataStall());
-    }
-
-    @Test
-    public void testIsDataStall_EvaluationDnsOnNotMeteredNetwork() {
-        WrappedNetworkMonitor wrappedMonitor = makeNotMeteredNetworkMonitor();
-        wrappedMonitor.setLastProbeTime(SystemClock.elapsedRealtime() - 100);
-        makeDnsTimeoutEvent(wrappedMonitor, DEFAULT_DNS_TIMEOUT_THRESHOLD);
-        assertTrue(wrappedMonitor.isDataStall());
-    }
-
-    @Test
-    public void testIsDataStall_EvaluationDnsOnMeteredNetwork() {
-        WrappedNetworkMonitor wrappedMonitor = makeMeteredNetworkMonitor();
-        wrappedMonitor.setLastProbeTime(SystemClock.elapsedRealtime() - 100);
-        assertFalse(wrappedMonitor.isDataStall());
-
-        wrappedMonitor.setLastProbeTime(SystemClock.elapsedRealtime() - 1000);
-        makeDnsTimeoutEvent(wrappedMonitor, DEFAULT_DNS_TIMEOUT_THRESHOLD);
-        assertTrue(wrappedMonitor.isDataStall());
-    }
-
-    @Test
-    public void testIsDataStall_EvaluationDnsWithDnsTimeoutCount() {
-        WrappedNetworkMonitor wrappedMonitor = makeMeteredNetworkMonitor();
-        wrappedMonitor.setLastProbeTime(SystemClock.elapsedRealtime() - 1000);
-        makeDnsTimeoutEvent(wrappedMonitor, 3);
-        assertFalse(wrappedMonitor.isDataStall());
-        // Reset consecutive timeout counts.
-        makeDnsSuccessEvent(wrappedMonitor, 1);
-        makeDnsTimeoutEvent(wrappedMonitor, 2);
-        assertFalse(wrappedMonitor.isDataStall());
-
-        makeDnsTimeoutEvent(wrappedMonitor, 3);
-        assertTrue(wrappedMonitor.isDataStall());
-
-        // Set the value to larger than the default dns log size.
-        setConsecutiveDnsTimeoutThreshold(51);
-        wrappedMonitor = makeMeteredNetworkMonitor();
-        wrappedMonitor.setLastProbeTime(SystemClock.elapsedRealtime() - 1000);
-        makeDnsTimeoutEvent(wrappedMonitor, 50);
-        assertFalse(wrappedMonitor.isDataStall());
-
-        makeDnsTimeoutEvent(wrappedMonitor, 1);
-        assertTrue(wrappedMonitor.isDataStall());
-    }
-
-    @Test
-    public void testIsDataStall_EvaluationDnsWithDnsTimeThreshold() {
-        // Test dns events happened in valid dns time threshold.
-        WrappedNetworkMonitor wrappedMonitor = makeMeteredNetworkMonitor();
-        wrappedMonitor.setLastProbeTime(SystemClock.elapsedRealtime() - 100);
-        makeDnsTimeoutEvent(wrappedMonitor, DEFAULT_DNS_TIMEOUT_THRESHOLD);
-        assertFalse(wrappedMonitor.isDataStall());
-        wrappedMonitor.setLastProbeTime(SystemClock.elapsedRealtime() - 1000);
-        assertTrue(wrappedMonitor.isDataStall());
-
-        // Test dns events happened before valid dns time threshold.
-        setValidDataStallDnsTimeThreshold(0);
-        wrappedMonitor = makeMeteredNetworkMonitor();
-        wrappedMonitor.setLastProbeTime(SystemClock.elapsedRealtime() - 100);
-        makeDnsTimeoutEvent(wrappedMonitor, DEFAULT_DNS_TIMEOUT_THRESHOLD);
-        assertFalse(wrappedMonitor.isDataStall());
-        wrappedMonitor.setLastProbeTime(SystemClock.elapsedRealtime() - 1000);
-        assertFalse(wrappedMonitor.isDataStall());
-    }
-
-    @Test
-    public void testBrokenNetworkNotValidated() throws Exception {
-        setSslException(mHttpsConnection);
-        setStatus(mHttpConnection, 500);
-        setStatus(mFallbackConnection, 404);
-
-        runFailedNetworkTest();
-    }
-
-    @Test
-    public void testNoInternetCapabilityValidated() throws Exception {
-        runNetworkTest(NO_INTERNET_CAPABILITIES, NETWORK_VALIDATION_RESULT_VALID,
-                getGeneralVerification());
-        verify(mCleartextDnsNetwork, never()).openConnection(any());
-    }
-
-    @Test
-    public void testLaunchCaptivePortalApp() throws Exception {
-        setSslException(mHttpsConnection);
-        setPortal302(mHttpConnection);
-
-        final NetworkMonitor nm = makeMonitor(METERED_CAPABILITIES);
-        nm.notifyNetworkConnected(TEST_LINK_PROPERTIES, METERED_CAPABILITIES);
-
-        verify(mCallbacks, timeout(HANDLER_TIMEOUT_MS).times(1))
-                .showProvisioningNotification(any(), any());
-
-        assertEquals(1, mRegisteredReceivers.size());
-
-        // Check that startCaptivePortalApp sends the expected intent.
-        nm.launchCaptivePortalApp();
-
-        final ArgumentCaptor<Bundle> bundleCaptor = ArgumentCaptor.forClass(Bundle.class);
-        final ArgumentCaptor<Network> networkCaptor = ArgumentCaptor.forClass(Network.class);
-        verify(mCm, timeout(HANDLER_TIMEOUT_MS).times(1))
-                .startCaptivePortalApp(networkCaptor.capture(), bundleCaptor.capture());
-        final Bundle bundle = bundleCaptor.getValue();
-        final Network bundleNetwork = bundle.getParcelable(ConnectivityManager.EXTRA_NETWORK);
-        assertEquals(TEST_NETID, bundleNetwork.netId);
-        // network is passed both in bundle and as parameter, as the bundle is opaque to the
-        // framework and only intended for the captive portal app, but the framework needs
-        // the network to identify the right NetworkMonitor.
-        assertEquals(TEST_NETID, networkCaptor.getValue().netId);
-
-        // Have the app report that the captive portal is dismissed, and check that we revalidate.
-        setStatus(mHttpsConnection, 204);
-        setStatus(mHttpConnection, 204);
-
-        reset(mCallbacks);
-        nm.notifyCaptivePortalAppFinished(APP_RETURN_DISMISSED);
-        verify(mCallbacks, timeout(HANDLER_TIMEOUT_MS).atLeastOnce())
-                .notifyNetworkTested(eq(NETWORK_VALIDATION_PROBE_DNS | NETWORK_VALIDATION_PROBE_HTTP
-                        | NETWORK_VALIDATION_RESULT_VALID), any());
-        assertEquals(0, mRegisteredReceivers.size());
-    }
-
-    @Test
-    public void testPrivateDnsSuccess() throws Exception {
-        setStatus(mHttpsConnection, 204);
-        setStatus(mHttpConnection, 204);
-        mFakeDns.setAnswer("dns.google", new String[]{"2001:db8::53"});
-
-        WrappedNetworkMonitor wnm = makeNotMeteredNetworkMonitor();
-        wnm.notifyPrivateDnsSettingsChanged(new PrivateDnsConfig("dns.google", new InetAddress[0]));
-        wnm.notifyNetworkConnected(TEST_LINK_PROPERTIES, NOT_METERED_CAPABILITIES);
-        verify(mCallbacks, timeout(HANDLER_TIMEOUT_MS).times(1))
-                .notifyNetworkTested(eq(VALIDATION_RESULT_VALID | NETWORK_VALIDATION_PROBE_PRIVDNS),
-                        eq(null));
-    }
-
-    @Test
-    public void testPrivateDnsResolutionRetryUpdate() throws Exception {
-        // Set a private DNS hostname that doesn't resolve and expect validation to fail.
-        mFakeDns.setAnswer("dns.google", new String[0]);
-        setStatus(mHttpsConnection, 204);
-        setStatus(mHttpConnection, 204);
-
-        WrappedNetworkMonitor wnm = makeNotMeteredNetworkMonitor();
-        wnm.notifyPrivateDnsSettingsChanged(new PrivateDnsConfig("dns.google", new InetAddress[0]));
-        wnm.notifyNetworkConnected(TEST_LINK_PROPERTIES, NOT_METERED_CAPABILITIES);
-        verify(mCallbacks, timeout(HANDLER_TIMEOUT_MS).atLeastOnce())
-                .notifyNetworkTested(
-                        eq(NETWORK_VALIDATION_PROBE_DNS | NETWORK_VALIDATION_PROBE_HTTPS),
-                        eq(null));
-
-        // Fix DNS and retry, expect validation to succeed.
-        reset(mCallbacks);
-        mFakeDns.setAnswer("dns.google", new String[]{"2001:db8::1"});
-
-        wnm.forceReevaluation(Process.myUid());
-        verify(mCallbacks, timeout(HANDLER_TIMEOUT_MS).atLeastOnce())
-                .notifyNetworkTested(eq(VALIDATION_RESULT_VALID | NETWORK_VALIDATION_PROBE_PRIVDNS),
-                        eq(null));
-
-        // Change configuration to an invalid DNS name, expect validation to fail.
-        reset(mCallbacks);
-        mFakeDns.setAnswer("dns.bad", new String[0]);
-        wnm.notifyPrivateDnsSettingsChanged(new PrivateDnsConfig("dns.bad", new InetAddress[0]));
-        // Strict mode hostname resolve fail. Expect only notification for evaluation fail. No probe
-        // notification.
-        verify(mCallbacks, timeout(HANDLER_TIMEOUT_MS).times(1))
-                .notifyNetworkTested(eq(VALIDATION_RESULT_VALID), eq(null));
-
-        // Change configuration back to working again, but make private DNS not work.
-        // Expect validation to fail.
-        reset(mCallbacks);
-        mFakeDns.setNonBypassPrivateDnsWorking(false);
-        wnm.notifyPrivateDnsSettingsChanged(new PrivateDnsConfig("dns.google",
-                new InetAddress[0]));
-        verify(mCallbacks, timeout(HANDLER_TIMEOUT_MS).atLeastOnce())
-                .notifyNetworkTested(
-                        eq(NETWORK_VALIDATION_PROBE_DNS | NETWORK_VALIDATION_PROBE_HTTPS),
-                        eq(null));
-
-        // Make private DNS work again. Expect validation to succeed.
-        reset(mCallbacks);
-        mFakeDns.setNonBypassPrivateDnsWorking(true);
-        wnm.forceReevaluation(Process.myUid());
-        verify(mCallbacks, timeout(HANDLER_TIMEOUT_MS).atLeastOnce())
-                .notifyNetworkTested(
-                        eq(VALIDATION_RESULT_VALID | NETWORK_VALIDATION_PROBE_PRIVDNS), eq(null));
-    }
-
-    @Test
-    public void testDataStall_StallSuspectedAndSendMetrics() throws IOException {
-        WrappedNetworkMonitor wrappedMonitor = makeNotMeteredNetworkMonitor();
-        wrappedMonitor.setLastProbeTime(SystemClock.elapsedRealtime() - 1000);
-        makeDnsTimeoutEvent(wrappedMonitor, 5);
-        assertTrue(wrappedMonitor.isDataStall());
-        verify(mDataStallStatsUtils, times(1)).write(makeEmptyDataStallDetectionStats(), any());
-    }
-
-    @Test
-    public void testDataStall_NoStallSuspectedAndSendMetrics() throws IOException {
-        WrappedNetworkMonitor wrappedMonitor = makeNotMeteredNetworkMonitor();
-        wrappedMonitor.setLastProbeTime(SystemClock.elapsedRealtime() - 1000);
-        makeDnsTimeoutEvent(wrappedMonitor, 3);
-        assertFalse(wrappedMonitor.isDataStall());
-        verify(mDataStallStatsUtils, never()).write(makeEmptyDataStallDetectionStats(), any());
-    }
-
-    @Test
-    public void testCollectDataStallMetrics() {
-        WrappedNetworkMonitor wrappedMonitor = makeNotMeteredNetworkMonitor();
-
-        when(mTelephony.getDataNetworkType()).thenReturn(TelephonyManager.NETWORK_TYPE_LTE);
-        when(mTelephony.getNetworkOperator()).thenReturn(TEST_MCCMNC);
-        when(mTelephony.getSimOperator()).thenReturn(TEST_MCCMNC);
-
-        DataStallDetectionStats.Builder stats =
-                new DataStallDetectionStats.Builder()
-                .setEvaluationType(DATA_STALL_EVALUATION_TYPE_DNS)
-                .setNetworkType(NetworkCapabilities.TRANSPORT_CELLULAR)
-                .setCellData(TelephonyManager.NETWORK_TYPE_LTE /* radioType */,
-                        true /* roaming */,
-                        TEST_MCCMNC /* networkMccmnc */,
-                        TEST_MCCMNC /* simMccmnc */,
-                        CellSignalStrength.SIGNAL_STRENGTH_NONE_OR_UNKNOWN /* signalStrength */);
-        generateTimeoutDnsEvent(stats, DEFAULT_DNS_TIMEOUT_THRESHOLD);
-
-        assertEquals(wrappedMonitor.buildDataStallDetectionStats(
-                 NetworkCapabilities.TRANSPORT_CELLULAR), stats.build());
-
-        when(mWifi.getConnectionInfo()).thenReturn(mWifiInfo);
-
-        stats = new DataStallDetectionStats.Builder()
-                .setEvaluationType(DATA_STALL_EVALUATION_TYPE_DNS)
-                .setNetworkType(NetworkCapabilities.TRANSPORT_WIFI)
-                .setWiFiData(mWifiInfo);
-        generateTimeoutDnsEvent(stats, DEFAULT_DNS_TIMEOUT_THRESHOLD);
-
-        assertEquals(
-                wrappedMonitor.buildDataStallDetectionStats(NetworkCapabilities.TRANSPORT_WIFI),
-                stats.build());
-    }
-
-    @Test
-    public void testIgnoreHttpsProbe() throws Exception {
-        setSslException(mHttpsConnection);
-        setStatus(mHttpConnection, 204);
-        // Expect to send HTTP, HTTPS, FALLBACK probe and evaluation result notifications to CS.
-        final NetworkMonitor nm = runNetworkTest(VALIDATION_RESULT_PARTIAL);
-
-        reset(mCallbacks);
-        nm.setAcceptPartialConnectivity();
-        // Expect to update evaluation result notifications to CS.
-        verify(mCallbacks, timeout(HANDLER_TIMEOUT_MS).times(1)).notifyNetworkTested(
-                eq(VALIDATION_RESULT_PARTIAL | NETWORK_VALIDATION_RESULT_VALID), eq(null));
-    }
-
-    @Test
-    public void testIsPartialConnectivity() throws IOException {
-        setStatus(mHttpsConnection, 500);
-        setStatus(mHttpConnection, 204);
-        setStatus(mFallbackConnection, 500);
-        runPartialConnectivityNetworkTest(VALIDATION_RESULT_PARTIAL);
-
-        reset(mCallbacks);
-        setStatus(mHttpsConnection, 500);
-        setStatus(mHttpConnection, 500);
-        setStatus(mFallbackConnection, 204);
-        runPartialConnectivityNetworkTest(VALIDATION_RESULT_FALLBACK_PARTIAL);
-    }
-
-    private void assertIpAddressArrayEquals(String[] expected, InetAddress[] actual) {
-        String[] actualStrings = new String[actual.length];
-        for (int i = 0; i < actual.length; i++) {
-            actualStrings[i] = actual[i].getHostAddress();
-        }
-        assertArrayEquals("Array of IP addresses differs", expected, actualStrings);
-    }
-
-    @Test
-    public void testSendDnsProbeWithTimeout() throws Exception {
-        WrappedNetworkMonitor wnm = makeNotMeteredNetworkMonitor();
-        final int shortTimeoutMs = 200;
-
-        // Clear the wildcard DNS response created in setUp.
-        mFakeDns.setAnswer("*", null);
-
-        String[] expected = new String[]{"2001:db8::"};
-        mFakeDns.setAnswer("www.google.com", expected);
-        InetAddress[] actual = wnm.sendDnsProbeWithTimeout("www.google.com", shortTimeoutMs);
-        assertIpAddressArrayEquals(expected, actual);
-
-        expected = new String[]{"2001:db8::", "192.0.2.1"};
-        mFakeDns.setAnswer("www.googleapis.com", expected);
-        actual = wnm.sendDnsProbeWithTimeout("www.googleapis.com", shortTimeoutMs);
-        assertIpAddressArrayEquals(expected, actual);
-
-        mFakeDns.setAnswer("www.google.com", new String[0]);
-        try {
-            wnm.sendDnsProbeWithTimeout("www.google.com", shortTimeoutMs);
-            fail("No DNS results, expected UnknownHostException");
-        } catch (UnknownHostException e) {
-        }
-
-        mFakeDns.setAnswer("www.google.com", null);
-        try {
-            wnm.sendDnsProbeWithTimeout("www.google.com", shortTimeoutMs);
-            fail("DNS query timed out, expected UnknownHostException");
-        } catch (UnknownHostException e) {
-        }
-    }
-
-    @Test
-    public void testNotifyNetwork_WithforceReevaluation() throws Exception {
-        final NetworkMonitor nm = runValidatedNetworkTest();
-        // Verify forceReevalution will not reset the validation result but only probe result until
-        // getting the validation result.
-        reset(mCallbacks);
-        setSslException(mHttpsConnection);
-        setStatus(mHttpConnection, 500);
-        setStatus(mFallbackConnection, 204);
-        nm.forceReevaluation(Process.myUid());
-        final ArgumentCaptor<Integer> intCaptor = ArgumentCaptor.forClass(Integer.class);
-        // Expect to send HTTP, HTTPs, FALLBACK and evaluation results.
-        verify(mCallbacks, timeout(HANDLER_TIMEOUT_MS).times(4))
-            .notifyNetworkTested(intCaptor.capture(), any());
-        List<Integer> intArgs = intCaptor.getAllValues();
-
-        // None of these exact values can be known in advance except for intArgs.get(0) because the
-        // HTTP and HTTPS probes race and the order in which they complete is non-deterministic.
-        // Thus, check only exact value for intArgs.get(0) and only check the validation result for
-        // the rest ones.
-        assertEquals(Integer.valueOf(NETWORK_VALIDATION_PROBE_DNS
-                | NETWORK_VALIDATION_PROBE_FALLBACK | NETWORK_VALIDATION_RESULT_VALID),
-                intArgs.get(0));
-        assertTrue((intArgs.get(1) & NETWORK_VALIDATION_RESULT_VALID) != 0);
-        assertTrue((intArgs.get(2) & NETWORK_VALIDATION_RESULT_VALID) != 0);
-        assertTrue((intArgs.get(3) & NETWORK_VALIDATION_RESULT_PARTIAL) != 0);
-        assertTrue((intArgs.get(3) & NETWORK_VALIDATION_RESULT_VALID) == 0);
-    }
-
-    @Test
-    public void testEvaluationState_clearProbeResults() throws Exception {
-        final NetworkMonitor nm = runValidatedNetworkTest();
-        nm.getEvaluationState().clearProbeResults();
-        // Verify probe results are all reset and only evaluation result left.
-        assertEquals(NETWORK_VALIDATION_RESULT_VALID,
-                nm.getEvaluationState().getNetworkTestResult());
-    }
-
-    @Test
-    public void testEvaluationState_reportProbeResult() throws Exception {
-        final NetworkMonitor nm = runValidatedNetworkTest();
-
-        reset(mCallbacks);
-
-        nm.reportHttpProbeResult(NETWORK_VALIDATION_PROBE_HTTP, CaptivePortalProbeResult.SUCCESS);
-        // Verify result should be appended and notifyNetworkTested callback is triggered once.
-        assertEquals(nm.getEvaluationState().getNetworkTestResult(),
-                VALIDATION_RESULT_VALID | NETWORK_VALIDATION_PROBE_HTTP);
-        verify(mCallbacks, timeout(HANDLER_TIMEOUT_MS).times(1)).notifyNetworkTested(
-                eq(VALIDATION_RESULT_VALID | NETWORK_VALIDATION_PROBE_HTTP), any());
-
-        nm.reportHttpProbeResult(NETWORK_VALIDATION_PROBE_HTTP, CaptivePortalProbeResult.FAILED);
-        // Verify DNS probe result should not be cleared.
-        assertTrue((nm.getEvaluationState().getNetworkTestResult() & NETWORK_VALIDATION_PROBE_DNS)
-                == NETWORK_VALIDATION_PROBE_DNS);
-    }
-
-    @Test
-    public void testEvaluationState_reportEvaluationResult() throws Exception {
-        final NetworkMonitor nm = runValidatedNetworkTest();
-
-        nm.getEvaluationState().reportEvaluationResult(NETWORK_VALIDATION_RESULT_PARTIAL,
-                null /* redirectUrl */);
-        verify(mCallbacks, timeout(HANDLER_TIMEOUT_MS).times(1)).notifyNetworkTested(
-                eq(NETWORK_VALIDATION_PROBE_DNS | NETWORK_VALIDATION_PROBE_HTTPS
-                | NETWORK_VALIDATION_RESULT_PARTIAL), eq(null));
-
-        nm.getEvaluationState().reportEvaluationResult(
-                NETWORK_VALIDATION_RESULT_VALID | NETWORK_VALIDATION_RESULT_PARTIAL,
-                null /* redirectUrl */);
-        verify(mCallbacks, timeout(HANDLER_TIMEOUT_MS).times(1)).notifyNetworkTested(
-                eq(VALIDATION_RESULT_VALID | NETWORK_VALIDATION_RESULT_PARTIAL), eq(null));
-
-        nm.getEvaluationState().reportEvaluationResult(VALIDATION_RESULT_INVALID,
-                TEST_REDIRECT_URL);
-        verify(mCallbacks, timeout(HANDLER_TIMEOUT_MS).times(1)).notifyNetworkTested(
-                eq(NETWORK_VALIDATION_PROBE_DNS | NETWORK_VALIDATION_PROBE_HTTPS),
-                eq(TEST_REDIRECT_URL));
-    }
-
-    private void makeDnsTimeoutEvent(WrappedNetworkMonitor wrappedMonitor, int count) {
-        for (int i = 0; i < count; i++) {
-            wrappedMonitor.getDnsStallDetector().accumulateConsecutiveDnsTimeoutCount(
-                    RETURN_CODE_DNS_TIMEOUT);
-        }
-    }
-
-    private void makeDnsSuccessEvent(WrappedNetworkMonitor wrappedMonitor, int count) {
-        for (int i = 0; i < count; i++) {
-            wrappedMonitor.getDnsStallDetector().accumulateConsecutiveDnsTimeoutCount(
-                    RETURN_CODE_DNS_SUCCESS);
-        }
-    }
-
-    private DataStallDetectionStats makeEmptyDataStallDetectionStats() {
-        return new DataStallDetectionStats.Builder().build();
-    }
-
-    private void setDataStallEvaluationType(int type) {
-        when(mDependencies.getDeviceConfigPropertyInt(any(),
-            eq(CONFIG_DATA_STALL_EVALUATION_TYPE), anyInt())).thenReturn(type);
-    }
-
-    private void setMinDataStallEvaluateInterval(int time) {
-        when(mDependencies.getDeviceConfigPropertyInt(any(),
-            eq(CONFIG_DATA_STALL_MIN_EVALUATE_INTERVAL), anyInt())).thenReturn(time);
-    }
-
-    private void setValidDataStallDnsTimeThreshold(int time) {
-        when(mDependencies.getDeviceConfigPropertyInt(any(),
-            eq(CONFIG_DATA_STALL_VALID_DNS_TIME_THRESHOLD), anyInt())).thenReturn(time);
-    }
-
-    private void setConsecutiveDnsTimeoutThreshold(int num) {
-        when(mDependencies.getDeviceConfigPropertyInt(any(),
-            eq(CONFIG_DATA_STALL_CONSECUTIVE_DNS_TIMEOUT_THRESHOLD), anyInt())).thenReturn(num);
-    }
-
-    private void setFallbackUrl(String url) {
-        when(mDependencies.getSetting(any(),
-                eq(Settings.Global.CAPTIVE_PORTAL_FALLBACK_URL), any())).thenReturn(url);
-    }
-
-    private void setOtherFallbackUrls(String urls) {
-        when(mDependencies.getDeviceConfigProperty(any(),
-                eq(CAPTIVE_PORTAL_OTHER_FALLBACK_URLS), any())).thenReturn(urls);
-    }
-
-    private void setFallbackSpecs(String specs) {
-        when(mDependencies.getDeviceConfigProperty(any(),
-                eq(CAPTIVE_PORTAL_FALLBACK_PROBE_SPECS), any())).thenReturn(specs);
-    }
-
-    private void setCaptivePortalMode(int mode) {
-        when(mDependencies.getSetting(any(),
-                eq(Settings.Global.CAPTIVE_PORTAL_MODE), anyInt())).thenReturn(mode);
-    }
-
-    private void runPortalNetworkTest(int result) {
-        // The network test event will be triggered twice with the same result. Expect to capture
-        // the second one with direct url.
-        runPortalNetworkTest(result,
-                (VerificationWithTimeout) timeout(HANDLER_TIMEOUT_MS).times(2));
-    }
-
-    private void runPortalNetworkTest(int result, VerificationWithTimeout mode) {
-        runNetworkTest(result, mode);
-        assertEquals(1, mRegisteredReceivers.size());
-        assertNotNull(mNetworkTestedRedirectUrlCaptor.getValue());
-    }
-
-    private void runNotPortalNetworkTest() {
-        runNetworkTest(VALIDATION_RESULT_VALID);
-        assertEquals(0, mRegisteredReceivers.size());
-        assertNull(mNetworkTestedRedirectUrlCaptor.getValue());
-    }
-
-    private void runNoValidationNetworkTest() {
-        runNetworkTest(NETWORK_VALIDATION_RESULT_VALID);
-        assertEquals(0, mRegisteredReceivers.size());
-        assertNull(mNetworkTestedRedirectUrlCaptor.getValue());
-    }
-
-    private void runFailedNetworkTest() {
-        runNetworkTest(VALIDATION_RESULT_INVALID);
-        assertEquals(0, mRegisteredReceivers.size());
-        assertNull(mNetworkTestedRedirectUrlCaptor.getValue());
-    }
-
-    private void runPartialConnectivityNetworkTest(int result) {
-        runNetworkTest(result);
-        assertEquals(0, mRegisteredReceivers.size());
-        assertNull(mNetworkTestedRedirectUrlCaptor.getValue());
-    }
-
-    private NetworkMonitor runValidatedNetworkTest() throws Exception {
-        setStatus(mHttpsConnection, 204);
-        setStatus(mHttpConnection, 204);
-        // Expect to send HTTPs and evaluation results.
-        return runNetworkTest(VALIDATION_RESULT_VALID);
-    }
-
-    private NetworkMonitor runNetworkTest(int testResult) {
-        return runNetworkTest(METERED_CAPABILITIES, testResult, getGeneralVerification());
-    }
-
-    private NetworkMonitor runNetworkTest(int testResult, VerificationWithTimeout mode) {
-        return runNetworkTest(METERED_CAPABILITIES, testResult, mode);
-    }
-
-    private NetworkMonitor runNetworkTest(NetworkCapabilities nc, int testResult,
-            VerificationWithTimeout mode) {
-        final NetworkMonitor monitor = makeMonitor(nc);
-        monitor.notifyNetworkConnected(TEST_LINK_PROPERTIES, nc);
-        try {
-            verify(mCallbacks, mode)
-                    .notifyNetworkTested(eq(testResult), mNetworkTestedRedirectUrlCaptor.capture());
-        } catch (RemoteException e) {
-            fail("Unexpected exception: " + e);
-        }
-        waitForIdle(monitor.getHandler());
-
-        return monitor;
-    }
-
-    private void setSslException(HttpURLConnection connection) throws IOException {
-        doThrow(new SSLHandshakeException("Invalid cert")).when(connection).getResponseCode();
-    }
-
-    private void set302(HttpURLConnection connection, String location) throws IOException {
-        setStatus(connection, 302);
-        doReturn(location).when(connection).getHeaderField(LOCATION_HEADER);
-    }
-
-    private void setPortal302(HttpURLConnection connection) throws IOException {
-        set302(connection, "http://login.example.com");
-    }
-
-    private void setStatus(HttpURLConnection connection, int status) throws IOException {
-        doReturn(status).when(connection).getResponseCode();
-    }
-
-    private void generateTimeoutDnsEvent(DataStallDetectionStats.Builder stats, int num) {
-        for (int i = 0; i < num; i++) {
-            stats.addDnsEvent(RETURN_CODE_DNS_TIMEOUT, 123456789 /* timeMs */);
-        }
-    }
-
-    private VerificationWithTimeout getGeneralVerification() {
-        return (VerificationWithTimeout) timeout(HANDLER_TIMEOUT_MS).atLeastOnce();
-    }
-
-}
-
diff --git a/packages/NetworkStack/tests/unit/src/com/android/server/connectivity/ipmemorystore/IpMemoryStoreServiceTest.java b/packages/NetworkStack/tests/unit/src/com/android/server/connectivity/ipmemorystore/IpMemoryStoreServiceTest.java
deleted file mode 100644
index 64fe3a6..0000000
--- a/packages/NetworkStack/tests/unit/src/com/android/server/connectivity/ipmemorystore/IpMemoryStoreServiceTest.java
+++ /dev/null
@@ -1,756 +0,0 @@
-/*
- * Copyright (C) 2018 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.server.connectivity.ipmemorystore;
-
-import static com.android.server.connectivity.ipmemorystore.RegularMaintenanceJobService.InterruptMaintenance;
-
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertFalse;
-import static org.junit.Assert.assertNull;
-import static org.junit.Assert.assertTrue;
-import static org.junit.Assert.fail;
-import static org.mockito.ArgumentMatchers.anyString;
-import static org.mockito.Mockito.doReturn;
-
-import android.app.job.JobScheduler;
-import android.content.Context;
-import android.net.ipmemorystore.Blob;
-import android.net.ipmemorystore.IOnBlobRetrievedListener;
-import android.net.ipmemorystore.IOnL2KeyResponseListener;
-import android.net.ipmemorystore.IOnNetworkAttributesRetrievedListener;
-import android.net.ipmemorystore.IOnSameL3NetworkResponseListener;
-import android.net.ipmemorystore.IOnStatusListener;
-import android.net.ipmemorystore.NetworkAttributes;
-import android.net.ipmemorystore.NetworkAttributesParcelable;
-import android.net.ipmemorystore.SameL3NetworkResponse;
-import android.net.ipmemorystore.SameL3NetworkResponseParcelable;
-import android.net.ipmemorystore.Status;
-import android.net.ipmemorystore.StatusParcelable;
-import android.os.ConditionVariable;
-import android.os.IBinder;
-import android.os.RemoteException;
-
-import androidx.test.InstrumentationRegistry;
-import androidx.test.filters.SmallTest;
-import androidx.test.runner.AndroidJUnit4;
-
-import org.junit.After;
-import org.junit.Before;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.mockito.Mock;
-import org.mockito.MockitoAnnotations;
-
-import java.io.File;
-import java.lang.reflect.Modifier;
-import java.net.Inet4Address;
-import java.net.Inet6Address;
-import java.net.InetAddress;
-import java.net.UnknownHostException;
-import java.util.Arrays;
-import java.util.List;
-import java.util.concurrent.CountDownLatch;
-import java.util.concurrent.TimeUnit;
-import java.util.function.Consumer;
-
-/** Unit tests for {@link IpMemoryStoreService}. */
-@SmallTest
-@RunWith(AndroidJUnit4.class)
-public class IpMemoryStoreServiceTest {
-    private static final String TEST_CLIENT_ID = "testClientId";
-    private static final String TEST_DATA_NAME = "testData";
-
-    private static final int TEST_DATABASE_SIZE_THRESHOLD = 100 * 1024; //100KB
-    private static final int DEFAULT_TIMEOUT_MS = 5000;
-    private static final int LONG_TIMEOUT_MS = 30000;
-    private static final int FAKE_KEY_COUNT = 20;
-    private static final long LEASE_EXPIRY_NULL = -1L;
-    private static final int MTU_NULL = -1;
-    private static final String[] FAKE_KEYS;
-    private static final byte[] TEST_BLOB_DATA = new byte[] { -3, 6, 8, -9, 12,
-            -128, 0, 89, 112, 91, -34 };
-    static {
-        FAKE_KEYS = new String[FAKE_KEY_COUNT];
-        for (int i = 0; i < FAKE_KEYS.length; ++i) {
-            FAKE_KEYS[i] = "fakeKey" + i;
-        }
-    }
-
-    @Mock
-    private Context mMockContext;
-    @Mock
-    private JobScheduler mMockJobScheduler;
-    private File mDbFile;
-
-    private IpMemoryStoreService mService;
-
-    @Before
-    public void setUp() {
-        MockitoAnnotations.initMocks(this);
-        final Context context = InstrumentationRegistry.getContext();
-        final File dir = context.getFilesDir();
-        mDbFile = new File(dir, "test.db");
-        doReturn(mDbFile).when(mMockContext).getDatabasePath(anyString());
-        doReturn(mMockJobScheduler).when(mMockContext)
-                .getSystemService(Context.JOB_SCHEDULER_SERVICE);
-        mService = new IpMemoryStoreService(mMockContext) {
-            @Override
-            protected int getDbSizeThreshold() {
-                return TEST_DATABASE_SIZE_THRESHOLD;
-            }
-
-            @Override
-            boolean isDbSizeOverThreshold() {
-                // Add a 100ms delay here for pausing maintenance job a while. Interrupted flag can
-                // be set at this time.
-                waitForMs(100);
-                return super.isDbSizeOverThreshold();
-            }
-        };
-    }
-
-    @After
-    public void tearDown() {
-        mService.shutdown();
-        mDbFile.delete();
-    }
-
-    /** Helper method to build test network attributes */
-    private static NetworkAttributes.Builder buildTestNetworkAttributes(
-            final Inet4Address ipAddress, final long expiry, final String hint,
-            final List<InetAddress> dnsServers, final int mtu) {
-        final NetworkAttributes.Builder na = new NetworkAttributes.Builder();
-        if (null != ipAddress) {
-            na.setAssignedV4Address(ipAddress);
-        }
-        if (LEASE_EXPIRY_NULL != expiry) {
-            na.setAssignedV4AddressExpiry(expiry);
-        }
-        if (null != hint) {
-            na.setGroupHint(hint);
-        }
-        if (null != dnsServers) {
-            na.setDnsAddresses(dnsServers);
-        }
-        if (MTU_NULL != mtu) {
-            na.setMtu(mtu);
-        }
-        return na;
-    }
-
-    /** Helper method to make a vanilla IOnStatusListener */
-    private IOnStatusListener onStatus(Consumer<Status> functor) {
-        return new IOnStatusListener() {
-            @Override
-            public void onComplete(final StatusParcelable statusParcelable) throws RemoteException {
-                functor.accept(new Status(statusParcelable));
-            }
-
-            @Override
-            public IBinder asBinder() {
-                return null;
-            }
-
-            @Override
-            public int getInterfaceVersion() {
-                return this.VERSION;
-            }
-        };
-    }
-
-    /** Helper method to make an IOnBlobRetrievedListener */
-    private interface OnBlobRetrievedListener {
-        void onBlobRetrieved(Status status, String l2Key, String name, byte[] data);
-    }
-    private IOnBlobRetrievedListener onBlobRetrieved(final OnBlobRetrievedListener functor) {
-        return new IOnBlobRetrievedListener() {
-            @Override
-            public void onBlobRetrieved(final StatusParcelable statusParcelable,
-                    final String l2Key, final String name, final Blob blob) throws RemoteException {
-                functor.onBlobRetrieved(new Status(statusParcelable), l2Key, name,
-                        null == blob ? null : blob.data);
-            }
-
-            @Override
-            public IBinder asBinder() {
-                return null;
-            }
-
-            @Override
-            public int getInterfaceVersion() {
-                return this.VERSION;
-            }
-        };
-    }
-
-    /** Helper method to make an IOnNetworkAttributesRetrievedListener */
-    private interface OnNetworkAttributesRetrievedListener  {
-        void onNetworkAttributesRetrieved(Status status, String l2Key, NetworkAttributes attr);
-    }
-    private IOnNetworkAttributesRetrievedListener onNetworkAttributesRetrieved(
-            final OnNetworkAttributesRetrievedListener functor) {
-        return new IOnNetworkAttributesRetrievedListener() {
-            @Override
-            public void onNetworkAttributesRetrieved(final StatusParcelable status,
-                    final String l2Key, final NetworkAttributesParcelable attributes)
-                    throws RemoteException {
-                functor.onNetworkAttributesRetrieved(new Status(status), l2Key,
-                        null == attributes ? null : new NetworkAttributes(attributes));
-            }
-
-            @Override
-            public IBinder asBinder() {
-                return null;
-            }
-
-            @Override
-            public int getInterfaceVersion() {
-                return this.VERSION;
-            }
-        };
-    }
-
-    /** Helper method to make an IOnSameNetworkResponseListener */
-    private interface OnSameL3NetworkResponseListener {
-        void onSameL3NetworkResponse(Status status, SameL3NetworkResponse answer);
-    }
-    private IOnSameL3NetworkResponseListener onSameResponse(
-            final OnSameL3NetworkResponseListener functor) {
-        return new IOnSameL3NetworkResponseListener() {
-            @Override
-            public void onSameL3NetworkResponse(final StatusParcelable status,
-                    final SameL3NetworkResponseParcelable sameL3Network)
-                    throws RemoteException {
-                functor.onSameL3NetworkResponse(new Status(status),
-                        null == sameL3Network ? null : new SameL3NetworkResponse(sameL3Network));
-            }
-
-            @Override
-            public IBinder asBinder() {
-                return null;
-            }
-
-            @Override
-            public int getInterfaceVersion() {
-                return this.VERSION;
-            }
-        };
-    }
-
-    /** Helper method to make an IOnL2KeyResponseListener */
-    private interface OnL2KeyResponseListener {
-        void onL2KeyResponse(Status status, String key);
-    }
-    private IOnL2KeyResponseListener onL2KeyResponse(final OnL2KeyResponseListener functor) {
-        return new IOnL2KeyResponseListener() {
-            @Override
-            public void onL2KeyResponse(final StatusParcelable status, final String key)
-                    throws RemoteException {
-                functor.onL2KeyResponse(new Status(status), key);
-            }
-
-            @Override
-            public IBinder asBinder() {
-                return null;
-            }
-
-            @Override
-            public int getInterfaceVersion() {
-                return this.VERSION;
-            }
-        };
-    }
-
-    // Helper method to factorize some boilerplate
-    private void doLatched(final String timeoutMessage, final Consumer<CountDownLatch> functor) {
-        doLatched(timeoutMessage, functor, DEFAULT_TIMEOUT_MS);
-    }
-
-    private void doLatched(final String timeoutMessage, final Consumer<CountDownLatch> functor,
-            final int timeout) {
-        final CountDownLatch latch = new CountDownLatch(1);
-        functor.accept(latch);
-        try {
-            if (!latch.await(timeout, TimeUnit.MILLISECONDS)) {
-                fail(timeoutMessage);
-            }
-        } catch (InterruptedException e) {
-            fail("Thread was interrupted");
-        }
-    }
-
-    // Helper method to store network attributes to database
-    private void storeAttributes(final String l2Key, final NetworkAttributes na) {
-        storeAttributes("Did not complete storing attributes", l2Key, na);
-    }
-    private void storeAttributes(final String timeoutMessage, final String l2Key,
-            final NetworkAttributes na) {
-        doLatched(timeoutMessage, latch -> mService.storeNetworkAttributes(l2Key, na.toParcelable(),
-                onStatus(status -> {
-                    assertTrue("Store not successful : " + status.resultCode, status.isSuccess());
-                    latch.countDown();
-                })));
-    }
-
-    // Helper method to store blob data to database
-    private void storeBlobOrFail(final String l2Key, final Blob b, final byte[] data) {
-        storeBlobOrFail("Did not complete storing private data", l2Key, b, data);
-    }
-    private void storeBlobOrFail(final String timeoutMessage, final String l2Key, final Blob b,
-            final byte[] data) {
-        b.data = data;
-        doLatched(timeoutMessage, latch -> mService.storeBlob(l2Key, TEST_CLIENT_ID, TEST_DATA_NAME,
-                b, onStatus(status -> {
-                    assertTrue("Store status not successful : " + status.resultCode,
-                            status.isSuccess());
-                    latch.countDown();
-                })));
-    }
-
-    /** Insert large data that db size will be over threshold for maintenance test usage. */
-    private void insertFakeDataAndOverThreshold() {
-        try {
-            final NetworkAttributes.Builder na = buildTestNetworkAttributes(
-                    (Inet4Address) Inet4Address.getByName("1.2.3.4"), LEASE_EXPIRY_NULL,
-                    "hint1", Arrays.asList(Inet6Address.getByName("0A1C:2E40:480A::1CA6")),
-                    219);
-            final long time = System.currentTimeMillis() - 1;
-            for (int i = 0; i < 1000; i++) {
-                int errorCode = IpMemoryStoreDatabase.storeNetworkAttributes(
-                        mService.mDb,
-                        "fakeKey" + i,
-                        // Let first 100 records get expiry.
-                        i < 100 ? time : time + TimeUnit.HOURS.toMillis(i),
-                        na.build());
-                assertEquals(errorCode, Status.SUCCESS);
-
-                errorCode = IpMemoryStoreDatabase.storeBlob(
-                        mService.mDb, "fakeKey" + i, TEST_CLIENT_ID, TEST_DATA_NAME,
-                        TEST_BLOB_DATA);
-                assertEquals(errorCode, Status.SUCCESS);
-            }
-
-            // After added 5000 records, db size is larger than fake threshold(100KB).
-            assertTrue(mService.isDbSizeOverThreshold());
-        } catch (final UnknownHostException e) {
-            fail("Insert fake data fail");
-        }
-    }
-
-    /** Wait for assigned time. */
-    private void waitForMs(long ms) {
-        try {
-            Thread.sleep(ms);
-        } catch (final InterruptedException e) {
-            fail("Thread was interrupted");
-        }
-    }
-
-    @Test
-    public void testNetworkAttributes() throws UnknownHostException {
-        final String l2Key = FAKE_KEYS[0];
-        final NetworkAttributes.Builder na = buildTestNetworkAttributes(
-                (Inet4Address) Inet4Address.getByName("1.2.3.4"),
-                System.currentTimeMillis() + 7_200_000, "hint1", null, 219);
-        NetworkAttributes attributes = na.build();
-        storeAttributes(l2Key, attributes);
-
-        doLatched("Did not complete retrieving attributes", latch ->
-                mService.retrieveNetworkAttributes(l2Key, onNetworkAttributesRetrieved(
-                        (status, key, attr) -> {
-                            assertTrue("Retrieve network attributes not successful : "
-                                    + status.resultCode, status.isSuccess());
-                            assertEquals(l2Key, key);
-                            assertEquals(attributes, attr);
-                            latch.countDown();
-                        })));
-
-        final NetworkAttributes.Builder na2 = new NetworkAttributes.Builder();
-        na.setDnsAddresses(Arrays.asList(
-                new InetAddress[] {Inet6Address.getByName("0A1C:2E40:480A::1CA6")}));
-        final NetworkAttributes attributes2 = na2.build();
-        storeAttributes("Did not complete storing attributes 2", l2Key, attributes2);
-
-        doLatched("Did not complete retrieving attributes 2", latch ->
-                mService.retrieveNetworkAttributes(l2Key, onNetworkAttributesRetrieved(
-                        (status, key, attr) -> {
-                            assertTrue("Retrieve network attributes not successful : "
-                                    + status.resultCode, status.isSuccess());
-                            assertEquals(l2Key, key);
-                            assertEquals(attributes.assignedV4Address, attr.assignedV4Address);
-                            assertEquals(attributes.assignedV4AddressExpiry,
-                                    attr.assignedV4AddressExpiry);
-                            assertEquals(attributes.groupHint, attr.groupHint);
-                            assertEquals(attributes.mtu, attr.mtu);
-                            assertEquals(attributes2.dnsAddresses, attr.dnsAddresses);
-                            latch.countDown();
-                        })));
-
-        doLatched("Did not complete retrieving attributes 3", latch ->
-                mService.retrieveNetworkAttributes(l2Key + "nonexistent",
-                        onNetworkAttributesRetrieved(
-                                (status, key, attr) -> {
-                                    assertTrue("Retrieve network attributes not successful : "
-                                            + status.resultCode, status.isSuccess());
-                                    assertEquals(l2Key + "nonexistent", key);
-                                    assertNull("Retrieved data not stored", attr);
-                                    latch.countDown();
-                                }
-                        )));
-
-        // Verify that this test does not miss any new field added later.
-        // If any field is added to NetworkAttributes it must be tested here for storing
-        // and retrieving.
-        assertEquals(5, Arrays.stream(NetworkAttributes.class.getDeclaredFields())
-                .filter(f -> !Modifier.isStatic(f.getModifiers())).count());
-    }
-
-    @Test
-    public void testInvalidAttributes() {
-        doLatched("Did not complete storing bad attributes", latch ->
-                mService.storeNetworkAttributes("key", null, onStatus(status -> {
-                    assertFalse("Success storing on a null key",
-                            status.isSuccess());
-                    assertEquals(Status.ERROR_ILLEGAL_ARGUMENT, status.resultCode);
-                    latch.countDown();
-                })));
-
-        final NetworkAttributes na = new NetworkAttributes.Builder().setMtu(2).build();
-        doLatched("Did not complete storing bad attributes", latch ->
-                mService.storeNetworkAttributes(null, na.toParcelable(), onStatus(status -> {
-                    assertFalse("Success storing null attributes on a null key",
-                            status.isSuccess());
-                    assertEquals(Status.ERROR_ILLEGAL_ARGUMENT, status.resultCode);
-                    latch.countDown();
-                })));
-
-        doLatched("Did not complete storing bad attributes", latch ->
-                mService.storeNetworkAttributes(null, null, onStatus(status -> {
-                    assertFalse("Success storing null attributes on a null key",
-                            status.isSuccess());
-                    assertEquals(Status.ERROR_ILLEGAL_ARGUMENT, status.resultCode);
-                    latch.countDown();
-                })));
-
-        doLatched("Did not complete retrieving bad attributes", latch ->
-                mService.retrieveNetworkAttributes(null, onNetworkAttributesRetrieved(
-                        (status, key, attr) -> {
-                            assertFalse("Success retrieving attributes for a null key",
-                                    status.isSuccess());
-                            assertEquals(Status.ERROR_ILLEGAL_ARGUMENT, status.resultCode);
-                            assertNull(key);
-                            assertNull(attr);
-                            latch.countDown();
-                        })));
-    }
-
-    @Test
-    public void testPrivateData() {
-        final String l2Key = FAKE_KEYS[0];
-        final Blob b = new Blob();
-        storeBlobOrFail(l2Key, b, TEST_BLOB_DATA);
-
-        doLatched("Did not complete retrieving private data", latch ->
-                mService.retrieveBlob(l2Key, TEST_CLIENT_ID, TEST_DATA_NAME, onBlobRetrieved(
-                        (status, key, name, data) -> {
-                            assertTrue("Retrieve blob status not successful : " + status.resultCode,
-                                    status.isSuccess());
-                            assertEquals(l2Key, key);
-                            assertEquals(name, TEST_DATA_NAME);
-                            assertTrue(Arrays.equals(b.data, data));
-                            latch.countDown();
-                        })));
-
-        // Most puzzling error message ever
-        doLatched("Did not complete retrieving nothing", latch ->
-                mService.retrieveBlob(l2Key, TEST_CLIENT_ID, TEST_DATA_NAME + "2", onBlobRetrieved(
-                        (status, key, name, data) -> {
-                            assertTrue("Retrieve blob status not successful : " + status.resultCode,
-                                    status.isSuccess());
-                            assertEquals(l2Key, key);
-                            assertEquals(name, TEST_DATA_NAME + "2");
-                            assertNull(data);
-                            latch.countDown();
-                        })));
-    }
-
-    @Test
-    public void testFindL2Key() throws UnknownHostException {
-        final NetworkAttributes.Builder na = new NetworkAttributes.Builder();
-        na.setGroupHint("hint0");
-        storeAttributes(FAKE_KEYS[0], na.build());
-
-        na.setDnsAddresses(Arrays.asList(
-                new InetAddress[] {Inet6Address.getByName("8D56:9AF1::08EE:20F1")}));
-        na.setMtu(219);
-        storeAttributes(FAKE_KEYS[1], na.build());
-        na.setMtu(null);
-        na.setAssignedV4Address((Inet4Address) Inet4Address.getByName("1.2.3.4"));
-        na.setDnsAddresses(Arrays.asList(
-                new InetAddress[] {Inet6Address.getByName("0A1C:2E40:480A::1CA6")}));
-        na.setGroupHint("hint1");
-        storeAttributes(FAKE_KEYS[2], na.build());
-        na.setMtu(219);
-        storeAttributes(FAKE_KEYS[3], na.build());
-        na.setMtu(240);
-        storeAttributes(FAKE_KEYS[4], na.build());
-        na.setAssignedV4Address((Inet4Address) Inet4Address.getByName("5.6.7.8"));
-        storeAttributes(FAKE_KEYS[5], na.build());
-
-        // Matches key 5 exactly
-        doLatched("Did not finish finding L2Key", latch ->
-                mService.findL2Key(na.build().toParcelable(), onL2KeyResponse((status, key) -> {
-                    assertTrue("Retrieve network sameness not successful : " + status.resultCode,
-                            status.isSuccess());
-                    assertEquals(FAKE_KEYS[5], key);
-                    latch.countDown();
-                })));
-
-        // MTU matches key 4 but v4 address matches key 5. The latter is stronger.
-        na.setMtu(240);
-        doLatched("Did not finish finding L2Key", latch ->
-                mService.findL2Key(na.build().toParcelable(), onL2KeyResponse((status, key) -> {
-                    assertTrue("Retrieve network sameness not successful : " + status.resultCode,
-                            status.isSuccess());
-                    assertEquals(FAKE_KEYS[5], key);
-                    latch.countDown();
-                })));
-
-        // Closest to key 3 (indeed, identical)
-        na.setAssignedV4Address((Inet4Address) Inet4Address.getByName("1.2.3.4"));
-        na.setMtu(219);
-        doLatched("Did not finish finding L2Key", latch ->
-                mService.findL2Key(na.build().toParcelable(), onL2KeyResponse((status, key) -> {
-                    assertTrue("Retrieve network sameness not successful : " + status.resultCode,
-                            status.isSuccess());
-                    assertEquals(FAKE_KEYS[3], key);
-                    latch.countDown();
-                })));
-
-        // Group hint alone must not be strong enough to override the rest
-        na.setGroupHint("hint0");
-        doLatched("Did not finish finding L2Key", latch ->
-                mService.findL2Key(na.build().toParcelable(), onL2KeyResponse((status, key) -> {
-                    assertTrue("Retrieve network sameness not successful : " + status.resultCode,
-                            status.isSuccess());
-                    assertEquals(FAKE_KEYS[3], key);
-                    latch.countDown();
-                })));
-
-        // Still closest to key 3, though confidence is lower
-        na.setGroupHint("hint1");
-        na.setDnsAddresses(null);
-        doLatched("Did not finish finding L2Key", latch ->
-                mService.findL2Key(na.build().toParcelable(), onL2KeyResponse((status, key) -> {
-                    assertTrue("Retrieve network sameness not successful : " + status.resultCode,
-                            status.isSuccess());
-                    assertEquals(FAKE_KEYS[3], key);
-                    latch.countDown();
-                })));
-
-        // But changing the MTU makes this closer to key 4
-        na.setMtu(240);
-        doLatched("Did not finish finding L2Key", latch ->
-                mService.findL2Key(na.build().toParcelable(), onL2KeyResponse((status, key) -> {
-                    assertTrue("Retrieve network sameness not successful : " + status.resultCode,
-                            status.isSuccess());
-                    assertEquals(FAKE_KEYS[4], key);
-                    latch.countDown();
-                })));
-
-        // MTU alone not strong enough to make this group-close
-        na.setGroupHint(null);
-        na.setDnsAddresses(null);
-        na.setAssignedV4Address(null);
-        doLatched("Did not finish finding L2Key", latch ->
-                mService.findL2Key(na.build().toParcelable(), onL2KeyResponse((status, key) -> {
-                    assertTrue("Retrieve network sameness not successful : " + status.resultCode,
-                            status.isSuccess());
-                    assertNull(key);
-                    latch.countDown();
-                })));
-    }
-
-    private void assertNetworksSameness(final String key1, final String key2, final int sameness) {
-        doLatched("Did not finish evaluating sameness", latch ->
-                mService.isSameNetwork(key1, key2, onSameResponse((status, answer) -> {
-                    assertTrue("Retrieve network sameness not successful : " + status.resultCode,
-                            status.isSuccess());
-                    assertEquals(sameness, answer.getNetworkSameness());
-                    latch.countDown();
-                })));
-    }
-
-    @Test
-    public void testIsSameNetwork() throws UnknownHostException {
-        final NetworkAttributes.Builder na = buildTestNetworkAttributes(
-                (Inet4Address) Inet4Address.getByName("1.2.3.4"), LEASE_EXPIRY_NULL,
-                "hint1", Arrays.asList(Inet6Address.getByName("0A1C:2E40:480A::1CA6")),
-                219);
-
-        storeAttributes(FAKE_KEYS[0], na.build());
-        // 0 and 1 have identical attributes
-        storeAttributes(FAKE_KEYS[1], na.build());
-
-        // Hopefully only the MTU being different still means it's the same network
-        na.setMtu(200);
-        storeAttributes(FAKE_KEYS[2], na.build());
-
-        // Hopefully different MTU, assigned V4 address and grouphint make a different network,
-        // even with identical DNS addresses
-        na.setAssignedV4Address(null);
-        na.setGroupHint("hint2");
-        storeAttributes(FAKE_KEYS[3], na.build());
-
-        assertNetworksSameness(FAKE_KEYS[0], FAKE_KEYS[1], SameL3NetworkResponse.NETWORK_SAME);
-        assertNetworksSameness(FAKE_KEYS[0], FAKE_KEYS[2], SameL3NetworkResponse.NETWORK_SAME);
-        assertNetworksSameness(FAKE_KEYS[1], FAKE_KEYS[2], SameL3NetworkResponse.NETWORK_SAME);
-        assertNetworksSameness(FAKE_KEYS[0], FAKE_KEYS[3], SameL3NetworkResponse.NETWORK_DIFFERENT);
-        assertNetworksSameness(FAKE_KEYS[0], "neverInsertedKey",
-                SameL3NetworkResponse.NETWORK_NEVER_CONNECTED);
-
-        doLatched("Did not finish evaluating sameness", latch ->
-                mService.isSameNetwork(null, null, onSameResponse((status, answer) -> {
-                    assertFalse("Retrieve network sameness suspiciously successful : "
-                            + status.resultCode, status.isSuccess());
-                    assertEquals(Status.ERROR_ILLEGAL_ARGUMENT, status.resultCode);
-                    assertNull(answer);
-                    latch.countDown();
-                })));
-    }
-
-    @Test
-    public void testFullMaintenance() {
-        insertFakeDataAndOverThreshold();
-
-        final InterruptMaintenance im = new InterruptMaintenance(0/* Fake JobId */);
-        // Do full maintenance and then db size should go down and meet the threshold.
-        doLatched("Maintenance unexpectedly completed successfully", latch ->
-                mService.fullMaintenance(onStatus((status) -> {
-                    assertTrue("Execute full maintenance failed: "
-                            + status.resultCode, status.isSuccess());
-                    latch.countDown();
-                }), im), LONG_TIMEOUT_MS);
-
-        // Assume that maintenance is successful, db size shall meet the threshold.
-        assertFalse(mService.isDbSizeOverThreshold());
-    }
-
-    @Test
-    public void testInterruptMaintenance() {
-        insertFakeDataAndOverThreshold();
-
-        final InterruptMaintenance im = new InterruptMaintenance(0/* Fake JobId */);
-
-        // Test interruption immediately.
-        im.setInterrupted(true);
-        // Do full maintenance and the expectation is not completed by interruption.
-        doLatched("Maintenance unexpectedly completed successfully", latch ->
-                mService.fullMaintenance(onStatus((status) -> {
-                    assertFalse(status.isSuccess());
-                    latch.countDown();
-                }), im), LONG_TIMEOUT_MS);
-
-        // Assume that no data are removed, db size shall be over the threshold.
-        assertTrue(mService.isDbSizeOverThreshold());
-
-        // Reset the flag and test interruption during maintenance.
-        im.setInterrupted(false);
-
-        final ConditionVariable latch = new ConditionVariable();
-        // Do full maintenance and the expectation is not completed by interruption.
-        mService.fullMaintenance(onStatus((status) -> {
-            assertFalse(status.isSuccess());
-            latch.open();
-        }), im);
-
-        // Give a little bit of time for maintenance to start up for realism
-        waitForMs(50);
-        // Interrupt maintenance job.
-        im.setInterrupted(true);
-
-        if (!latch.block(LONG_TIMEOUT_MS)) {
-            fail("Maintenance unexpectedly completed successfully");
-        }
-
-        // Assume that only do dropAllExpiredRecords method in previous maintenance, db size shall
-        // still be over the threshold.
-        assertTrue(mService.isDbSizeOverThreshold());
-    }
-
-    @Test
-    public void testFactoryReset() throws UnknownHostException {
-        final String l2Key = FAKE_KEYS[0];
-
-        // store network attributes
-        final NetworkAttributes.Builder na = buildTestNetworkAttributes(
-                (Inet4Address) Inet4Address.getByName("1.2.3.4"),
-                System.currentTimeMillis() + 7_200_000, "hint1", null, 219);
-        storeAttributes(l2Key, na.build());
-
-        // store private data blob
-        final Blob b = new Blob();
-        storeBlobOrFail(l2Key, b, TEST_BLOB_DATA);
-
-        // wipe all data in Database
-        mService.factoryReset();
-
-        // retrieved network attributes should be null
-        doLatched("Did not complete retrieving attributes", latch ->
-                mService.retrieveNetworkAttributes(l2Key, onNetworkAttributesRetrieved(
-                        (status, key, attr) -> {
-                            assertTrue("Retrieve network attributes not successful : "
-                                    + status.resultCode, status.isSuccess());
-                            assertEquals(l2Key, key);
-                            assertNull(attr);
-                            latch.countDown();
-                        })));
-
-        // retrieved private data blob should be null
-        doLatched("Did not complete retrieving private data", latch ->
-                mService.retrieveBlob(l2Key, TEST_CLIENT_ID, TEST_DATA_NAME, onBlobRetrieved(
-                        (status, key, name, data) -> {
-                            assertTrue("Retrieve blob status not successful : " + status.resultCode,
-                                    status.isSuccess());
-                            assertEquals(l2Key, key);
-                            assertEquals(name, TEST_DATA_NAME);
-                            assertNull(data);
-                            latch.countDown();
-                        })));
-    }
-
-    public void testTasksAreSerial() {
-        final long sleepTimeMs = 1000;
-        final long startTime = System.currentTimeMillis();
-        mService.retrieveNetworkAttributes("somekey", onNetworkAttributesRetrieved(
-                (status, key, attr) -> {
-                    assertTrue("Unexpected status : " + status.resultCode, status.isSuccess());
-                    try {
-                        Thread.sleep(sleepTimeMs);
-                    } catch (InterruptedException e) {
-                        fail("InterruptedException");
-                    }
-                }));
-        doLatched("Serial tasks timing out", latch ->
-                mService.retrieveNetworkAttributes("somekey", onNetworkAttributesRetrieved(
-                        (status, key, attr) -> {
-                            assertTrue("Unexpected status : " + status.resultCode,
-                                    status.isSuccess());
-                            assertTrue(System.currentTimeMillis() >= startTime + sleepTimeMs);
-                        })), DEFAULT_TIMEOUT_MS);
-    }
-}
diff --git a/packages/NetworkStack/tests/unit/src/com/android/server/connectivity/ipmemorystore/RelevanceUtilsTests.java b/packages/NetworkStack/tests/unit/src/com/android/server/connectivity/ipmemorystore/RelevanceUtilsTests.java
deleted file mode 100644
index 3d3aabc..0000000
--- a/packages/NetworkStack/tests/unit/src/com/android/server/connectivity/ipmemorystore/RelevanceUtilsTests.java
+++ /dev/null
@@ -1,149 +0,0 @@
-/*
- * Copyright (C) 2018 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.server.connectivity.ipmemorystore;
-
-import static com.android.server.connectivity.ipmemorystore.RelevanceUtils.CAPPED_RELEVANCE;
-
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertTrue;
-import static org.junit.Assert.fail;
-
-import androidx.test.filters.SmallTest;
-import androidx.test.runner.AndroidJUnit4;
-
-import org.junit.Test;
-import org.junit.runner.RunWith;
-
-/** Unit tests for {@link RelevanceUtils}. */
-@SmallTest
-@RunWith(AndroidJUnit4.class)
-public class RelevanceUtilsTests {
-    @Test
-    public void testComputeRelevanceForTargetDate() {
-        final long dayInMillis = 24L * 60 * 60 * 1000;
-        final long base = 1_000_000L; // any given point in time
-        // Relevance when the network expires in 1000 years must be capped
-        assertEquals(CAPPED_RELEVANCE, RelevanceUtils.computeRelevanceForTargetDate(
-                base + 1000L * dayInMillis, base));
-        // Relevance when expiry is before the date must be 0
-        assertEquals(0, RelevanceUtils.computeRelevanceForTargetDate(base - 1, base));
-        // Make sure the relevance for a given target date is higher if the expiry is further
-        // in the future
-        assertTrue(RelevanceUtils.computeRelevanceForTargetDate(base + 100 * dayInMillis, base)
-                < RelevanceUtils.computeRelevanceForTargetDate(base + 150 * dayInMillis, base));
-
-        // Make sure the relevance falls slower as the expiry is closing in. This is to ensure
-        // the decay is indeed logarithmic.
-        final int relevanceAtExpiry = RelevanceUtils.computeRelevanceForTargetDate(base, base);
-        final int relevance50DaysBeforeExpiry =
-                RelevanceUtils.computeRelevanceForTargetDate(base + 50 * dayInMillis, base);
-        final int relevance100DaysBeforeExpiry =
-                RelevanceUtils.computeRelevanceForTargetDate(base + 100 * dayInMillis, base);
-        final int relevance150DaysBeforeExpiry =
-                RelevanceUtils.computeRelevanceForTargetDate(base + 150 * dayInMillis, base);
-        assertEquals(0, relevanceAtExpiry);
-        assertTrue(relevance50DaysBeforeExpiry - relevanceAtExpiry
-                < relevance100DaysBeforeExpiry - relevance50DaysBeforeExpiry);
-        assertTrue(relevance100DaysBeforeExpiry - relevance50DaysBeforeExpiry
-                < relevance150DaysBeforeExpiry - relevance100DaysBeforeExpiry);
-    }
-
-    @Test
-    public void testIncreaseRelevance() {
-        long expiry = System.currentTimeMillis();
-
-        final long firstBump = RelevanceUtils.bumpExpiryDate(expiry);
-        // Though a few milliseconds might have elapsed, the first bump should push the duration
-        // to days in the future, so unless this test takes literal days between these two lines,
-        // this should always pass.
-        assertTrue(firstBump > expiry);
-
-        expiry = 0;
-        long lastDifference = Long.MAX_VALUE;
-        // The relevance should be capped in at most this many steps. Otherwise, fail.
-        final int steps = 1000;
-        for (int i = 0; i < steps; ++i) {
-            final long newExpiry = RelevanceUtils.bumpExpiryDuration(expiry);
-            if (newExpiry == expiry) {
-                // The relevance should be capped. Make sure it is, then exit without failure.
-                assertEquals(newExpiry, RelevanceUtils.CAPPED_RELEVANCE_LIFETIME_MS);
-                return;
-            }
-            // Make sure the new expiry is further in the future than last time.
-            assertTrue(newExpiry > expiry);
-            // Also check that it was not bumped as much as the last bump, because the
-            // decay must be exponential.
-            assertTrue(newExpiry - expiry < lastDifference);
-            lastDifference = newExpiry - expiry;
-            expiry = newExpiry;
-        }
-        fail("Relevance failed to go to the maximum value after " + steps + " bumps");
-    }
-
-    @Test
-    public void testContinuity() {
-        final long expiry = System.currentTimeMillis();
-
-        // Relevance at expiry and after expiry should be the cap.
-        final int relevanceBeforeMaxLifetime = RelevanceUtils.computeRelevanceForTargetDate(expiry,
-                expiry - (RelevanceUtils.CAPPED_RELEVANCE_LIFETIME_MS + 1_000_000));
-        assertEquals(relevanceBeforeMaxLifetime, CAPPED_RELEVANCE);
-        final int relevanceForMaxLifetime = RelevanceUtils.computeRelevanceForTargetDate(expiry,
-                expiry - RelevanceUtils.CAPPED_RELEVANCE_LIFETIME_MS);
-        assertEquals(relevanceForMaxLifetime, CAPPED_RELEVANCE);
-
-        // If the max relevance is reached at the cap lifetime, one millisecond less than this
-        // should be very close. Strictly speaking this is a bit brittle, but it should be
-        // good enough for the purposes of the memory store.
-        final int relevanceForOneMillisecLessThanCap = RelevanceUtils.computeRelevanceForTargetDate(
-                expiry, expiry - RelevanceUtils.CAPPED_RELEVANCE_LIFETIME_MS + 1);
-        assertTrue(relevanceForOneMillisecLessThanCap <= CAPPED_RELEVANCE);
-        assertTrue(relevanceForOneMillisecLessThanCap >= CAPPED_RELEVANCE - 10);
-
-        // Likewise the relevance one millisecond before expiry should be very close to 0. It's
-        // fine if it rounds down to 0.
-        final int relevanceOneMillisecBeforeExpiry = RelevanceUtils.computeRelevanceForTargetDate(
-                expiry, expiry - 1);
-        assertTrue(relevanceOneMillisecBeforeExpiry <= 10);
-        assertTrue(relevanceOneMillisecBeforeExpiry >= 0);
-
-        final int relevanceAtExpiry = RelevanceUtils.computeRelevanceForTargetDate(expiry, expiry);
-        assertEquals(relevanceAtExpiry, 0);
-        final int relevanceAfterExpiry = RelevanceUtils.computeRelevanceForTargetDate(expiry,
-                expiry + 1_000_000);
-        assertEquals(relevanceAfterExpiry, 0);
-    }
-
-    // testIncreaseRelevance makes sure bumping the expiry continuously always yields a
-    // monotonically increasing date as a side effect, but this tests that the relevance (as
-    // opposed to the expiry date) increases monotonically with increasing periods.
-    @Test
-    public void testMonotonicity() {
-        // Hopefully the relevance is granular enough to give a different value for every one
-        // of this number of steps.
-        final int steps = 40;
-        final long expiry = System.currentTimeMillis();
-
-        int lastRelevance = -1;
-        for (int i = 0; i < steps; ++i) {
-            final long date = expiry - i * (RelevanceUtils.CAPPED_RELEVANCE_LIFETIME_MS / steps);
-            final int relevance = RelevanceUtils.computeRelevanceForTargetDate(expiry, date);
-            assertTrue(relevance > lastRelevance);
-            lastRelevance = relevance;
-        }
-    }
-}
diff --git a/packages/NetworkStack/tests/unit/src/com/android/server/util/SharedLogTest.java b/packages/NetworkStack/tests/unit/src/com/android/server/util/SharedLogTest.java
deleted file mode 100644
index b1db051..0000000
--- a/packages/NetworkStack/tests/unit/src/com/android/server/util/SharedLogTest.java
+++ /dev/null
@@ -1,97 +0,0 @@
-/*
- * Copyright (C) 2017 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.util;
-
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertTrue;
-
-import android.net.util.SharedLog;
-
-import androidx.test.filters.SmallTest;
-import androidx.test.runner.AndroidJUnit4;
-
-import org.junit.Test;
-import org.junit.runner.RunWith;
-
-import java.io.ByteArrayOutputStream;
-import java.io.PrintWriter;
-
-@RunWith(AndroidJUnit4.class)
-@SmallTest
-public class SharedLogTest {
-    private static final String TIMESTAMP_PATTERN = "\\d{2}:\\d{2}:\\d{2}";
-    private static final String TIMESTAMP = "HH:MM:SS";
-
-    @Test
-    public void testBasicOperation() {
-        final SharedLog logTop = new SharedLog("top");
-        logTop.mark("first post!");
-
-        final SharedLog logLevel2a = logTop.forSubComponent("twoA");
-        final SharedLog logLevel2b = logTop.forSubComponent("twoB");
-        logLevel2b.e("2b or not 2b");
-        logLevel2b.e("No exception", null);
-        logLevel2b.e("Wait, here's one", new Exception("Test"));
-        logLevel2a.w("second post?");
-
-        final SharedLog logLevel3 = logLevel2a.forSubComponent("three");
-        logTop.log("still logging");
-        logLevel3.log("3 >> 2");
-        logLevel2a.mark("ok: last post");
-
-        final String[] expected = {
-            " - MARK first post!",
-            " - [twoB] ERROR 2b or not 2b",
-            " - [twoB] ERROR No exception",
-            // No stacktrace in shared log, only in logcat
-            " - [twoB] ERROR Wait, here's one: Test",
-            " - [twoA] WARN second post?",
-            " - still logging",
-            " - [twoA.three] 3 >> 2",
-            " - [twoA] MARK ok: last post",
-        };
-        // Verify the logs are all there and in the correct order.
-        verifyLogLines(expected, logTop);
-
-        // In fact, because they all share the same underlying LocalLog,
-        // every subcomponent SharedLog's dump() is identical.
-        verifyLogLines(expected, logLevel2a);
-        verifyLogLines(expected, logLevel2b);
-        verifyLogLines(expected, logLevel3);
-    }
-
-    private static void verifyLogLines(String[] expected, SharedLog log) {
-        final ByteArrayOutputStream ostream = new ByteArrayOutputStream();
-        final PrintWriter pw = new PrintWriter(ostream, true);
-        log.dump(null, pw, null);
-
-        final String dumpOutput = ostream.toString();
-        assertTrue(dumpOutput != null);
-        assertTrue(!"".equals(dumpOutput));
-
-        final String[] lines = dumpOutput.split("\n");
-        assertEquals(expected.length, lines.length);
-
-        for (int i = 0; i < expected.length; i++) {
-            String got = lines[i];
-            String want = expected[i];
-            assertTrue(String.format("'%s' did not contain '%s'", got, want), got.endsWith(want));
-            assertTrue(String.format("'%s' did not contain a %s timestamp", got, TIMESTAMP),
-                    got.replaceFirst(TIMESTAMP_PATTERN, TIMESTAMP).contains(TIMESTAMP));
-        }
-    }
-}
diff --git a/packages/PackageInstaller/src/com/android/packageinstaller/InstallInstalling.java b/packages/PackageInstaller/src/com/android/packageinstaller/InstallInstalling.java
index 93f24f7..4f85eea 100755
--- a/packages/PackageInstaller/src/com/android/packageinstaller/InstallInstalling.java
+++ b/packages/PackageInstaller/src/com/android/packageinstaller/InstallInstalling.java
@@ -130,18 +130,15 @@
             } else {
                 PackageInstaller.SessionParams params = new PackageInstaller.SessionParams(
                         PackageInstaller.SessionParams.MODE_FULL_INSTALL);
-                params.installFlags = PackageManager.INSTALL_FULL_APP;
-                params.referrerUri = getIntent().getParcelableExtra(Intent.EXTRA_REFERRER);
-                params.originatingUri = getIntent()
-                        .getParcelableExtra(Intent.EXTRA_ORIGINATING_URI);
-                params.originatingUid = getIntent().getIntExtra(Intent.EXTRA_ORIGINATING_UID,
-                        UID_UNKNOWN);
-                params.installerPackageName =
-                        getIntent().getStringExtra(Intent.EXTRA_INSTALLER_PACKAGE_NAME);
-                params.installReason = PackageManager.INSTALL_REASON_USER;
-
-                // Whitelist all restricted permissions.
-                params.setWhitelistedRestrictedPermissions(null /*permissions*/);
+                params.setInstallAsInstantApp(false);
+                params.setReferrerUri(getIntent().getParcelableExtra(Intent.EXTRA_REFERRER));
+                params.setOriginatingUri(getIntent()
+                        .getParcelableExtra(Intent.EXTRA_ORIGINATING_URI));
+                params.setOriginatingUid(getIntent().getIntExtra(Intent.EXTRA_ORIGINATING_UID,
+                        UID_UNKNOWN));
+                params.setInstallerPackageName(getIntent().getStringExtra(
+                        Intent.EXTRA_INSTALLER_PACKAGE_NAME));
+                params.setInstallReason(PackageManager.INSTALL_REASON_USER);
 
                 File file = new File(mPackageURI.getPath());
                 try {
diff --git a/packages/SettingsLib/res/values-af/strings.xml b/packages/SettingsLib/res/values-af/strings.xml
index 0116d0d..4cedc93 100644
--- a/packages/SettingsLib/res/values-af/strings.xml
+++ b/packages/SettingsLib/res/values-af/strings.xml
@@ -220,6 +220,7 @@
     <string name="debug_networking_category" msgid="7044075693643009662">"Inligtingruiling"</string>
     <string name="wifi_display_certification" msgid="8611569543791307533">"Draadlose skermsertifisering"</string>
     <string name="wifi_verbose_logging" msgid="4203729756047242344">"Aktiveer Wi-Fi-woordryke aanmelding"</string>
+    <string name="wifi_scan_throttling" msgid="160014287416479843">"Regulering van Wi-Fi-opsporing"</string>
     <string name="mobile_data_always_on" msgid="8774857027458200434">"Mobiele data is altyd aktief"</string>
     <string name="tethering_hardware_offload" msgid="7470077827090325814">"Hardewareversnelling vir verbinding"</string>
     <string name="bluetooth_show_devices_without_names" msgid="4708446092962060176">"Wys Bluetooth-toestelle sonder name"</string>
@@ -246,6 +247,7 @@
     <string name="private_dns_mode_provider_failure" msgid="231837290365031223">"Kon nie koppel nie"</string>
     <string name="wifi_display_certification_summary" msgid="1155182309166746973">"Wys opsies vir draadlose skermsertifisering"</string>
     <string name="wifi_verbose_logging_summary" msgid="6615071616111731958">"Verhoog Wi-Fi-aantekeningvlak, wys per SSID RSSI in Wi‑Fi-kieser"</string>
+    <string name="wifi_scan_throttling_summary" msgid="4461922728822495763">"Verlaag batteryverbruik en verbeter netwerk se werkverrigting"</string>
     <string name="wifi_metered_label" msgid="4514924227256839725">"Beperk"</string>
     <string name="wifi_unmetered_label" msgid="6124098729457992931">"Onbeperk"</string>
     <string name="select_logd_size_title" msgid="7433137108348553508">"Loggerbuffer se groottes"</string>
diff --git a/packages/SettingsLib/res/values-am/strings.xml b/packages/SettingsLib/res/values-am/strings.xml
index b914b07..3b7abdb 100644
--- a/packages/SettingsLib/res/values-am/strings.xml
+++ b/packages/SettingsLib/res/values-am/strings.xml
@@ -220,6 +220,7 @@
     <string name="debug_networking_category" msgid="7044075693643009662">"አውታረ መረብ"</string>
     <string name="wifi_display_certification" msgid="8611569543791307533">"የገመድ አልባ ማሳያ እውቅና ማረጋገጫ"</string>
     <string name="wifi_verbose_logging" msgid="4203729756047242344">"የWi‑Fi ተጨማሪ ቃላት ምዝግብ ማስታወሻ መያዝ"</string>
+    <string name="wifi_scan_throttling" msgid="160014287416479843">"Wi‑Fi scan throttling"</string>
     <string name="mobile_data_always_on" msgid="8774857027458200434">"የተንቀሳቃሽ ስልክ ውሂብ ሁልጊዜ ገቢር ነው"</string>
     <string name="tethering_hardware_offload" msgid="7470077827090325814">"የሃርድዌር ማቀላጠፊያን በማስተሳሰር ላይ"</string>
     <string name="bluetooth_show_devices_without_names" msgid="4708446092962060176">"የብሉቱዝ መሣሪያዎችን ያለ ስሞች አሳይ"</string>
@@ -246,6 +247,7 @@
     <string name="private_dns_mode_provider_failure" msgid="231837290365031223">"መገናኘት አልተቻለም"</string>
     <string name="wifi_display_certification_summary" msgid="1155182309166746973">"የገመድ አልባ ማሳያ እውቅና ማረጋገጫ አማራጮችን አሳይ"</string>
     <string name="wifi_verbose_logging_summary" msgid="6615071616111731958">"የWi‑Fi ምዝግብ ማስታወሻ አያያዝ ደረጃ ጨምር፣ በWi‑Fi መምረጫ ውስጥ በአንድ SSID RSSI አሳይ"</string>
+    <string name="wifi_scan_throttling_summary" msgid="4461922728822495763">"የባትሪ መላሸቅን ይቀንሳል እንዲሁም የአውታረ መረብ አፈጻጸም ብቃትን ያሻሽላል"</string>
     <string name="wifi_metered_label" msgid="4514924227256839725">"የሚለካ"</string>
     <string name="wifi_unmetered_label" msgid="6124098729457992931">"ያልተለካ"</string>
     <string name="select_logd_size_title" msgid="7433137108348553508">"የምዝግብ ማስታወሻ ያዥ መጠኖች"</string>
diff --git a/packages/SettingsLib/res/values-ar/strings.xml b/packages/SettingsLib/res/values-ar/strings.xml
index 0a9edb5..df1ec30 100644
--- a/packages/SettingsLib/res/values-ar/strings.xml
+++ b/packages/SettingsLib/res/values-ar/strings.xml
@@ -220,6 +220,7 @@
     <string name="debug_networking_category" msgid="7044075693643009662">"الشبكات"</string>
     <string name="wifi_display_certification" msgid="8611569543791307533">"شهادة عرض شاشة لاسلكي"</string>
     <string name="wifi_verbose_logging" msgid="4203729756047242344">"‏تفعيل تسجيل Wi‑Fi Verbose"</string>
+    <string name="wifi_scan_throttling" msgid="160014287416479843">"‏تقييد البحث عن شبكات Wi-Fi"</string>
     <string name="mobile_data_always_on" msgid="8774857027458200434">"بيانات الجوّال نشطة دائمًا"</string>
     <string name="tethering_hardware_offload" msgid="7470077827090325814">"تسريع الأجهزة للتوصيل"</string>
     <string name="bluetooth_show_devices_without_names" msgid="4708446092962060176">"عرض أجهزة البلوتوث بدون أسماء"</string>
@@ -246,6 +247,7 @@
     <string name="private_dns_mode_provider_failure" msgid="231837290365031223">"تعذّر الاتصال"</string>
     <string name="wifi_display_certification_summary" msgid="1155182309166746973">"عرض خيارات شهادة عرض شاشة لاسلكي"</string>
     <string name="wifi_verbose_logging_summary" msgid="6615071616111731958">"‏زيادة مستوى تسجيل Wi-Fi، وعرض لكل SSID RSSI في منتقي Wi-Fi"</string>
+    <string name="wifi_scan_throttling_summary" msgid="4461922728822495763">"لتقليل استنفاد البطارية وتحسين أداء الشبكة."</string>
     <string name="wifi_metered_label" msgid="4514924227256839725">"تفرض تكلفة استخدام"</string>
     <string name="wifi_unmetered_label" msgid="6124098729457992931">"بدون قياس"</string>
     <string name="select_logd_size_title" msgid="7433137108348553508">"أحجام ذاكرة التخزين المؤقت للتسجيل"</string>
diff --git a/packages/SettingsLib/res/values-as/strings.xml b/packages/SettingsLib/res/values-as/strings.xml
index fddfb05..9c25b66 100644
--- a/packages/SettingsLib/res/values-as/strings.xml
+++ b/packages/SettingsLib/res/values-as/strings.xml
@@ -220,6 +220,7 @@
     <string name="debug_networking_category" msgid="7044075693643009662">"নেটৱৰ্কিং"</string>
     <string name="wifi_display_certification" msgid="8611569543791307533">"বেতাঁৰ ডিছপ্লে’ প্ৰমাণীকৰণ"</string>
     <string name="wifi_verbose_logging" msgid="4203729756047242344">"ৱাই-ফাই ভাৰ্ব\'ছ লগিং সক্ষম কৰক"</string>
+    <string name="wifi_scan_throttling" msgid="160014287416479843">"ৱাই-ফাই স্কেনৰ নিয়ন্ত্ৰণ"</string>
     <string name="mobile_data_always_on" msgid="8774857027458200434">"ম’বাইল ডেটা সদা-সক্ৰিয়"</string>
     <string name="tethering_hardware_offload" msgid="7470077827090325814">"টেডাৰিং হাৰ্ডৱেৰ ত্বৰণ"</string>
     <string name="bluetooth_show_devices_without_names" msgid="4708446092962060176">"নামবিহীন ব্লুটুথ ডিভাইচসমূহ দেখুৱাওক"</string>
@@ -246,6 +247,7 @@
     <string name="private_dns_mode_provider_failure" msgid="231837290365031223">"সংযোগ কৰিব পৰা নগ\'ল"</string>
     <string name="wifi_display_certification_summary" msgid="1155182309166746973">"বেতাঁৰ ডিছপ্লে’ প্ৰমাণপত্ৰৰ বাবে বিকল্পসমূহ দেখুৱাওক"</string>
     <string name="wifi_verbose_logging_summary" msgid="6615071616111731958">"ৱাই-ফাই লগিঙৰ মাত্ৰা বঢ়াওক, Wi‑Fi পিকাৰত প্ৰতি SSID RSSI দেখুৱাওক"</string>
+    <string name="wifi_scan_throttling_summary" msgid="4461922728822495763">"বেটাৰীৰ খৰচ কমায় আৰু নেটৱৰ্কৰ কাৰ্যক্ষমতা বৃদ্ধি কৰে"</string>
     <string name="wifi_metered_label" msgid="4514924227256839725">"নিৰিখ-নিৰ্দিষ্ট"</string>
     <string name="wifi_unmetered_label" msgid="6124098729457992931">"নিৰিখ অনিৰ্দিষ্ট"</string>
     <string name="select_logd_size_title" msgid="7433137108348553508">"লগাৰৰ বাফাৰৰ আকাৰ"</string>
diff --git a/packages/SettingsLib/res/values-az/strings.xml b/packages/SettingsLib/res/values-az/strings.xml
index 642b81c..3a6d301 100644
--- a/packages/SettingsLib/res/values-az/strings.xml
+++ b/packages/SettingsLib/res/values-az/strings.xml
@@ -220,6 +220,7 @@
     <string name="debug_networking_category" msgid="7044075693643009662">"Şəbəkələşmə"</string>
     <string name="wifi_display_certification" msgid="8611569543791307533">"Simsiz displey sertifikatlaşması"</string>
     <string name="wifi_verbose_logging" msgid="4203729756047242344">"Wi‑Fi Çoxsözlü Girişə icazə verin"</string>
+    <string name="wifi_scan_throttling" msgid="160014287416479843">"Wi‑Fi skanlamasının tənzimlənməsi"</string>
     <string name="mobile_data_always_on" msgid="8774857027458200434">"Mobil data həmişə aktiv"</string>
     <string name="tethering_hardware_offload" msgid="7470077827090325814">"Birləşmə üçün avadanlıq akselerasiyası"</string>
     <string name="bluetooth_show_devices_without_names" msgid="4708446092962060176">"Bluetooth cihazlarını adsız göstərin"</string>
@@ -246,6 +247,7 @@
     <string name="private_dns_mode_provider_failure" msgid="231837290365031223">"Qoşulmaq mümkün olmadı"</string>
     <string name="wifi_display_certification_summary" msgid="1155182309166746973">"Simsiz displey sertifikatlaşması üçün seçimləri göstərir"</string>
     <string name="wifi_verbose_logging_summary" msgid="6615071616111731958">"Wi‑Fi giriş səviyyəsini qaldırın, Wi‑Fi seçəndə hər SSID RSSI üzrə göstərin"</string>
+    <string name="wifi_scan_throttling_summary" msgid="4461922728822495763">"Batareya istifadəsini azaldır &amp; şəbəkə performansını yaxşılaşdırır"</string>
     <string name="wifi_metered_label" msgid="4514924227256839725">"Ödənişli"</string>
     <string name="wifi_unmetered_label" msgid="6124098729457992931">"Limitsiz"</string>
     <string name="select_logd_size_title" msgid="7433137108348553508">"Logger bufer ölçüləri"</string>
diff --git a/packages/SettingsLib/res/values-b+sr+Latn/strings.xml b/packages/SettingsLib/res/values-b+sr+Latn/strings.xml
index 4fea77a..a8808fa 100644
--- a/packages/SettingsLib/res/values-b+sr+Latn/strings.xml
+++ b/packages/SettingsLib/res/values-b+sr+Latn/strings.xml
@@ -220,6 +220,7 @@
     <string name="debug_networking_category" msgid="7044075693643009662">"Umrežavanje"</string>
     <string name="wifi_display_certification" msgid="8611569543791307533">"Sertifikacija bežičnog ekrana"</string>
     <string name="wifi_verbose_logging" msgid="4203729756047242344">"Omogući detaljniju evidenciju za Wi‑Fi"</string>
+    <string name="wifi_scan_throttling" msgid="160014287416479843">"Usporavanje Wi-Fi skeniranja"</string>
     <string name="mobile_data_always_on" msgid="8774857027458200434">"Mobilni podaci su uvek aktivni"</string>
     <string name="tethering_hardware_offload" msgid="7470077827090325814">"Hardversko ubrzanje privezivanja"</string>
     <string name="bluetooth_show_devices_without_names" msgid="4708446092962060176">"Prikaži Bluetooth uređaje bez naziva"</string>
@@ -246,6 +247,7 @@
     <string name="private_dns_mode_provider_failure" msgid="231837290365031223">"Povezivanje nije uspelo"</string>
     <string name="wifi_display_certification_summary" msgid="1155182309166746973">"Prikaz opcija za sertifikaciju bežičnog ekrana"</string>
     <string name="wifi_verbose_logging_summary" msgid="6615071616111731958">"Povećava nivo evidentiranja za Wi‑Fi. Prikaz po SSID RSSI-u u biraču Wi‑Fi mreže"</string>
+    <string name="wifi_scan_throttling_summary" msgid="4461922728822495763">"Smanjuje potrošnju baterije i poboljšava učinak mreže"</string>
     <string name="wifi_metered_label" msgid="4514924227256839725">"Sa ograničenjem"</string>
     <string name="wifi_unmetered_label" msgid="6124098729457992931">"Bez ograničenja"</string>
     <string name="select_logd_size_title" msgid="7433137108348553508">"Veličine bafera podataka u programu za evidentiranje"</string>
diff --git a/packages/SettingsLib/res/values-be/strings.xml b/packages/SettingsLib/res/values-be/strings.xml
index 5ba5e82..05d9a5d 100644
--- a/packages/SettingsLib/res/values-be/strings.xml
+++ b/packages/SettingsLib/res/values-be/strings.xml
@@ -220,6 +220,7 @@
     <string name="debug_networking_category" msgid="7044075693643009662">"Сеткі"</string>
     <string name="wifi_display_certification" msgid="8611569543791307533">"Сертыфікацыя бесправаднога экрана"</string>
     <string name="wifi_verbose_logging" msgid="4203729756047242344">"Уключыць падрабязны журнал Wi‑Fi"</string>
+    <string name="wifi_scan_throttling" msgid="160014287416479843">"Рэгуляванне пошуку сетак Wi‑Fi"</string>
     <string name="mobile_data_always_on" msgid="8774857027458200434">"Мабільная перадача даных заўсёды актыўная"</string>
     <string name="tethering_hardware_offload" msgid="7470077827090325814">"Апаратнае паскарэнне ў рэжыме мадэма"</string>
     <string name="bluetooth_show_devices_without_names" msgid="4708446092962060176">"Паказваць прылады Bluetooth без назваў"</string>
@@ -246,6 +247,7 @@
     <string name="private_dns_mode_provider_failure" msgid="231837290365031223">"Не атрымалася падключыцца"</string>
     <string name="wifi_display_certification_summary" msgid="1155182309166746973">"Паказаць опцыі сертыфікацыі бесправаднога экрана"</string>
     <string name="wifi_verbose_logging_summary" msgid="6615071616111731958">"Пры выбары сеткі Wi-Fi указваць у журнале RSSI для кожнага SSID"</string>
+    <string name="wifi_scan_throttling_summary" msgid="4461922728822495763">"Зніжае расход зараду акумулятара і павышае прадукцыйнасць мабільных сетак"</string>
     <string name="wifi_metered_label" msgid="4514924227256839725">"Сетка з улікам трафіка"</string>
     <string name="wifi_unmetered_label" msgid="6124098729457992931">"Сетка без уліку трафіка"</string>
     <string name="select_logd_size_title" msgid="7433137108348553508">"Памеры буфера журнала"</string>
diff --git a/packages/SettingsLib/res/values-bg/strings.xml b/packages/SettingsLib/res/values-bg/strings.xml
index 54bbffa..7fa5b06 100644
--- a/packages/SettingsLib/res/values-bg/strings.xml
+++ b/packages/SettingsLib/res/values-bg/strings.xml
@@ -220,6 +220,7 @@
     <string name="debug_networking_category" msgid="7044075693643009662">"Мрежи"</string>
     <string name="wifi_display_certification" msgid="8611569543791307533">"Безжичен дисплей"</string>
     <string name="wifi_verbose_logging" msgid="4203729756047242344">"„Многословно“ регистр. на Wi‑Fi: Актив."</string>
+    <string name="wifi_scan_throttling" msgid="160014287416479843">"Ограничаване на сканирането за Wi-Fi"</string>
     <string name="mobile_data_always_on" msgid="8774857027458200434">"Винаги активни мобилни данни"</string>
     <string name="tethering_hardware_offload" msgid="7470077827090325814">"Хардуерно ускорение за тетъринга"</string>
     <string name="bluetooth_show_devices_without_names" msgid="4708446092962060176">"Показване на устройствата с Bluetooth без имена"</string>
@@ -246,6 +247,7 @@
     <string name="private_dns_mode_provider_failure" msgid="231837290365031223">"Не можа да се установи връзка"</string>
     <string name="wifi_display_certification_summary" msgid="1155182309166746973">"Показване на опциите за сертифициране на безжичния дисплей"</string>
     <string name="wifi_verbose_logging_summary" msgid="6615071616111731958">"По-подробно регистр. на Wi‑Fi – данни за RSSI на SSID в инстр. за избор на Wi‑Fi"</string>
+    <string name="wifi_scan_throttling_summary" msgid="4461922728822495763">"Намалява изразходването на батерията и подобрява ефективността на мрежата"</string>
     <string name="wifi_metered_label" msgid="4514924227256839725">"С отчитане"</string>
     <string name="wifi_unmetered_label" msgid="6124098729457992931">"Без отчитане"</string>
     <string name="select_logd_size_title" msgid="7433137108348553508">"Размери на регистрац. буфери"</string>
diff --git a/packages/SettingsLib/res/values-bn/strings.xml b/packages/SettingsLib/res/values-bn/strings.xml
index 9f9bf04..bdbde46 100644
--- a/packages/SettingsLib/res/values-bn/strings.xml
+++ b/packages/SettingsLib/res/values-bn/strings.xml
@@ -220,6 +220,7 @@
     <string name="debug_networking_category" msgid="7044075693643009662">"নেটওয়ার্কিং"</string>
     <string name="wifi_display_certification" msgid="8611569543791307533">"ওয়্যারলেস ডিসপ্লে সার্টিফিকেশন"</string>
     <string name="wifi_verbose_logging" msgid="4203729756047242344">"ওয়াই-ফাই ভারবোস লগিং সক্ষম করুন"</string>
+    <string name="wifi_scan_throttling" msgid="160014287416479843">"ওয়াই-ফাই স্ক্যান থ্রোটলিং"</string>
     <string name="mobile_data_always_on" msgid="8774857027458200434">"মোবাইল ডেটা সব সময় সক্রিয় থাক"</string>
     <string name="tethering_hardware_offload" msgid="7470077827090325814">"টিথারিং হার্ডওয়্যার অ্যাক্সিলারেশন"</string>
     <string name="bluetooth_show_devices_without_names" msgid="4708446092962060176">"নামহীন ব্লুটুথ ডিভাইসগুলি দেখুন"</string>
@@ -246,6 +247,7 @@
     <string name="private_dns_mode_provider_failure" msgid="231837290365031223">"কানেক্ট করা যায়নি"</string>
     <string name="wifi_display_certification_summary" msgid="1155182309166746973">"ওয়্যারলেস প্রদর্শন সার্টিফিকেশন জন্য বিকল্পগুলি দেখান"</string>
     <string name="wifi_verbose_logging_summary" msgid="6615071616111731958">"ওয়াই-ফাই লগিং স্তর বাড়ান, ওয়াই-ফাই চয়নকারীতে SSID RSSI অনুযায়ী দেখান"</string>
+    <string name="wifi_scan_throttling_summary" msgid="4461922728822495763">"ব্যাটারির খরচ কমায় এবং নেটওয়ার্কের পারফর্ম্যান্স উন্নত করে"</string>
     <string name="wifi_metered_label" msgid="4514924227256839725">"মিটার্ড"</string>
     <string name="wifi_unmetered_label" msgid="6124098729457992931">"পরিমাপ করা নয়"</string>
     <string name="select_logd_size_title" msgid="7433137108348553508">"লগার বাফারের আকারগুলি"</string>
diff --git a/packages/SettingsLib/res/values-bs/strings.xml b/packages/SettingsLib/res/values-bs/strings.xml
index 91d7581..02b2a8b 100644
--- a/packages/SettingsLib/res/values-bs/strings.xml
+++ b/packages/SettingsLib/res/values-bs/strings.xml
@@ -220,6 +220,7 @@
     <string name="debug_networking_category" msgid="7044075693643009662">"Umrežavanje"</string>
     <string name="wifi_display_certification" msgid="8611569543791307533">"Certifikacija bežičnog prikaza"</string>
     <string name="wifi_verbose_logging" msgid="4203729756047242344">"Omogući detaljni zapisnik za WiFi"</string>
+    <string name="wifi_scan_throttling" msgid="160014287416479843">"Reguliranje skeniranja WiFi mreže"</string>
     <string name="mobile_data_always_on" msgid="8774857027458200434">"Prijenos podataka na mobilnoj mreži je uvijek aktivan"</string>
     <string name="tethering_hardware_offload" msgid="7470077827090325814">"Hardversko ubrzavanje za povezivanje putem mobitela"</string>
     <string name="bluetooth_show_devices_without_names" msgid="4708446092962060176">"Prikaži Bluetooth uređaje bez naziva"</string>
@@ -246,6 +247,7 @@
     <string name="private_dns_mode_provider_failure" msgid="231837290365031223">"Povezivanje nije uspjelo"</string>
     <string name="wifi_display_certification_summary" msgid="1155182309166746973">"Prikaz opcija za certifikaciju bežičnog prikaza"</string>
     <string name="wifi_verbose_logging_summary" msgid="6615071616111731958">"Povećani nivo zapisnika za WiFi. Prikaz po SSID RSSI-ju u Biraču WiFi-ja"</string>
+    <string name="wifi_scan_throttling_summary" msgid="4461922728822495763">"Smanjuje potrošnju baterije i poboljšava performanse mreže"</string>
     <string name="wifi_metered_label" msgid="4514924227256839725">"S naplatom"</string>
     <string name="wifi_unmetered_label" msgid="6124098729457992931">"Mreža bez naplate"</string>
     <string name="select_logd_size_title" msgid="7433137108348553508">"Veličine međumemorije zapisnika"</string>
diff --git a/packages/SettingsLib/res/values-ca/arrays.xml b/packages/SettingsLib/res/values-ca/arrays.xml
index 15100bf..59b8c8a 100644
--- a/packages/SettingsLib/res/values-ca/arrays.xml
+++ b/packages/SettingsLib/res/values-ca/arrays.xml
@@ -233,7 +233,7 @@
   <string-array name="show_non_rect_clip_entries">
     <item msgid="993742912147090253">"Desactivat"</item>
     <item msgid="675719912558941285">"Dibuixa àrea retall no rectangular en blau"</item>
-    <item msgid="1064373276095698656">"Ressalta ordres de dibuix provats en verd"</item>
+    <item msgid="1064373276095698656">"Marca ordres de dibuix provats en verd"</item>
   </string-array>
   <string-array name="track_frame_time_entries">
     <item msgid="2193584639058893150">"Desactivat"</item>
diff --git a/packages/SettingsLib/res/values-ca/strings.xml b/packages/SettingsLib/res/values-ca/strings.xml
index 8a4ab91..d464256 100644
--- a/packages/SettingsLib/res/values-ca/strings.xml
+++ b/packages/SettingsLib/res/values-ca/strings.xml
@@ -155,7 +155,7 @@
     <string name="tts_settings" msgid="8186971894801348327">"Configuració de text a parla"</string>
     <string name="tts_settings_title" msgid="1237820681016639683">"Sortida de text a parla"</string>
     <string name="tts_default_rate_title" msgid="6030550998379310088">"Velocitat de parla"</string>
-    <string name="tts_default_rate_summary" msgid="4061815292287182801">"Velocitat de lectura del text"</string>
+    <string name="tts_default_rate_summary" msgid="4061815292287182801">"Velocitat a què s\'enuncia el text"</string>
     <string name="tts_default_pitch_title" msgid="6135942113172488671">"To"</string>
     <string name="tts_default_pitch_summary" msgid="1944885882882650009">"Afecta el to de la veu sintetitzada"</string>
     <string name="tts_default_lang_title" msgid="8018087612299820556">"Idioma"</string>
@@ -179,7 +179,7 @@
     <string name="tts_engine_preference_section_title" msgid="448294500990971413">"Motor preferent"</string>
     <string name="tts_general_section_title" msgid="4402572014604490502">"General"</string>
     <string name="tts_reset_speech_pitch_title" msgid="5789394019544785915">"Restableix el to de la veu"</string>
-    <string name="tts_reset_speech_pitch_summary" msgid="8700539616245004418">"Restableix el to predeterminat amb què es llegeix el text."</string>
+    <string name="tts_reset_speech_pitch_summary" msgid="8700539616245004418">"Restableix a predeterminat el to amb què s\'enuncia el text."</string>
   <string-array name="tts_rate_entries">
     <item msgid="6695494874362656215">"Molt lenta"</item>
     <item msgid="4795095314303559268">"Lenta"</item>
@@ -220,6 +220,7 @@
     <string name="debug_networking_category" msgid="7044075693643009662">"Xarxes"</string>
     <string name="wifi_display_certification" msgid="8611569543791307533">"Certificació de pantalla sense fil"</string>
     <string name="wifi_verbose_logging" msgid="4203729756047242344">"Activa el registre Wi‑Fi detallat"</string>
+    <string name="wifi_scan_throttling" msgid="160014287416479843">"Regulació de la cerca de xarxes Wi‑Fi"</string>
     <string name="mobile_data_always_on" msgid="8774857027458200434">"Dades mòbils sempre actives"</string>
     <string name="tethering_hardware_offload" msgid="7470077827090325814">"Acceleració per maquinari per a compartició de xarxa"</string>
     <string name="bluetooth_show_devices_without_names" msgid="4708446092962060176">"Mostra els dispositius Bluetooth sense el nom"</string>
@@ -246,6 +247,7 @@
     <string name="private_dns_mode_provider_failure" msgid="231837290365031223">"No s\'ha pogut connectar"</string>
     <string name="wifi_display_certification_summary" msgid="1155182309166746973">"Mostra les opcions per a la certificació de pantalla sense fil"</string>
     <string name="wifi_verbose_logging_summary" msgid="6615071616111731958">"Augmenta nivell de registre Wi‑Fi, mostra\'l per SSID RSSI al selector de Wi‑Fi"</string>
+    <string name="wifi_scan_throttling_summary" msgid="4461922728822495763">"Redueix el consum de bateria i millora el rendiment de la xarxa"</string>
     <string name="wifi_metered_label" msgid="4514924227256839725">"D\'ús mesurat"</string>
     <string name="wifi_unmetered_label" msgid="6124098729457992931">"D\'ús no mesurat"</string>
     <string name="select_logd_size_title" msgid="7433137108348553508">"Mides de la mem. intermèdia del registrador"</string>
diff --git a/packages/SettingsLib/res/values-cs/strings.xml b/packages/SettingsLib/res/values-cs/strings.xml
index 8827c9f..5256399 100644
--- a/packages/SettingsLib/res/values-cs/strings.xml
+++ b/packages/SettingsLib/res/values-cs/strings.xml
@@ -220,6 +220,7 @@
     <string name="debug_networking_category" msgid="7044075693643009662">"Sítě"</string>
     <string name="wifi_display_certification" msgid="8611569543791307533">"Certifikace bezdrát. displeje"</string>
     <string name="wifi_verbose_logging" msgid="4203729756047242344">"Podrobné protokolování Wi‑Fi"</string>
+    <string name="wifi_scan_throttling" msgid="160014287416479843">"Přibrždění vyhledávání Wi‑Fi"</string>
     <string name="mobile_data_always_on" msgid="8774857027458200434">"Mobilní data jsou vždy aktivní"</string>
     <string name="tethering_hardware_offload" msgid="7470077827090325814">"Hardwarová akcelerace tetheringu"</string>
     <string name="bluetooth_show_devices_without_names" msgid="4708446092962060176">"Zobrazovat zařízení Bluetooth bez názvů"</string>
@@ -246,6 +247,7 @@
     <string name="private_dns_mode_provider_failure" msgid="231837290365031223">"Nelze se připojit"</string>
     <string name="wifi_display_certification_summary" msgid="1155182309166746973">"Zobrazit možnosti certifikace bezdrátového displeje"</string>
     <string name="wifi_verbose_logging_summary" msgid="6615071616111731958">"Zvýšit úroveň protokolování Wi‑Fi zobrazenou v SSID a RSSI při výběru sítě Wi‑Fi."</string>
+    <string name="wifi_scan_throttling_summary" msgid="4461922728822495763">"Snižuje vyčerpávání baterie a vylepšuje výkon sítě"</string>
     <string name="wifi_metered_label" msgid="4514924227256839725">"Měřená"</string>
     <string name="wifi_unmetered_label" msgid="6124098729457992931">"Neměřená"</string>
     <string name="select_logd_size_title" msgid="7433137108348553508">"Vyrovnávací paměť protokol. nástroje"</string>
@@ -419,7 +421,7 @@
     <item msgid="8934126114226089439">"50 %"</item>
     <item msgid="1286113608943010849">"100 %"</item>
   </string-array>
-    <string name="charge_length_format" msgid="8978516217024434156">"před <xliff:g id="ID_1">%1$s</xliff:g>"</string>
+    <string name="charge_length_format" msgid="8978516217024434156">"Před <xliff:g id="ID_1">%1$s</xliff:g>"</string>
     <string name="remaining_length_format" msgid="7886337596669190587">"zbývá: <xliff:g id="ID_1">%1$s</xliff:g>"</string>
     <string name="screen_zoom_summary_small" msgid="5867245310241621570">"Malé"</string>
     <string name="screen_zoom_summary_default" msgid="2247006805614056507">"Výchozí"</string>
diff --git a/packages/SettingsLib/res/values-da/strings.xml b/packages/SettingsLib/res/values-da/strings.xml
index 04ef33d..1884f64 100644
--- a/packages/SettingsLib/res/values-da/strings.xml
+++ b/packages/SettingsLib/res/values-da/strings.xml
@@ -78,7 +78,7 @@
     <string name="bluetooth_active_battery_level_untethered" msgid="6662649951391456747">"Aktivt – venstre: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE_0">%1$s</xliff:g> batteri. Højre: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE_1">%2$s</xliff:g> batteri"</string>
     <string name="bluetooth_battery_level" msgid="1447164613319663655">"<xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g> batteri"</string>
     <string name="bluetooth_battery_level_untethered" msgid="5974406100211667177">"Venstre: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE_0">%1$s</xliff:g> batteri. Højre: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE_1">%2$s</xliff:g> batteri"</string>
-    <string name="bluetooth_active_no_battery_level" msgid="8380223546730241956">"Aktivt"</string>
+    <string name="bluetooth_active_no_battery_level" msgid="8380223546730241956">"Aktiv"</string>
     <string name="bluetooth_profile_a2dp" msgid="2031475486179830674">"Medielyd"</string>
     <string name="bluetooth_profile_headset" msgid="7815495680863246034">"Telefonopkald"</string>
     <string name="bluetooth_profile_opp" msgid="9168139293654233697">"Filoverførsel"</string>
@@ -220,6 +220,7 @@
     <string name="debug_networking_category" msgid="7044075693643009662">"Netværk"</string>
     <string name="wifi_display_certification" msgid="8611569543791307533">"Certificering af trådløs skærm"</string>
     <string name="wifi_verbose_logging" msgid="4203729756047242344">"Aktivér detaljeret Wi-Fi-logføring"</string>
+    <string name="wifi_scan_throttling" msgid="160014287416479843">"Begrænsning af Wi-Fi-scanning"</string>
     <string name="mobile_data_always_on" msgid="8774857027458200434">"Mobildata er altid aktiveret"</string>
     <string name="tethering_hardware_offload" msgid="7470077827090325814">"Hardwareacceleration ved netdeling"</string>
     <string name="bluetooth_show_devices_without_names" msgid="4708446092962060176">"Vis Bluetooth-enheder uden navne"</string>
@@ -246,6 +247,7 @@
     <string name="private_dns_mode_provider_failure" msgid="231837290365031223">"Der kunne ikke oprettes forbindelse"</string>
     <string name="wifi_display_certification_summary" msgid="1155182309166746973">"Vis valgmuligheder for certificering af trådløs skærm"</string>
     <string name="wifi_verbose_logging_summary" msgid="6615071616111731958">"Øg mængden af Wi‑Fi-logføring. Vis opdelt efter SSID RSSI i Wi‑Fi-vælgeren"</string>
+    <string name="wifi_scan_throttling_summary" msgid="4461922728822495763">"Reducerer batteriforbruget og forbedrer netværkets effektivitet"</string>
     <string name="wifi_metered_label" msgid="4514924227256839725">"Forbrugsafregnet"</string>
     <string name="wifi_unmetered_label" msgid="6124098729457992931">"Ikke forbrugsafregnet"</string>
     <string name="select_logd_size_title" msgid="7433137108348553508">"Størrelser for Logger-buffer"</string>
diff --git a/packages/SettingsLib/res/values-de/strings.xml b/packages/SettingsLib/res/values-de/strings.xml
index 92413a7..7c03afb 100644
--- a/packages/SettingsLib/res/values-de/strings.xml
+++ b/packages/SettingsLib/res/values-de/strings.xml
@@ -153,7 +153,7 @@
     <string name="launch_defaults_some" msgid="313159469856372621">"Einige Standardeinstellungen festgelegt"</string>
     <string name="launch_defaults_none" msgid="4241129108140034876">"Keine Standardeinstellungen festgelegt"</string>
     <string name="tts_settings" msgid="8186971894801348327">"Sprachausgabe"</string>
-    <string name="tts_settings_title" msgid="1237820681016639683">"Sprachausgabe-Einstellungen"</string>
+    <string name="tts_settings_title" msgid="1237820681016639683">"Sprachausgabe"</string>
     <string name="tts_default_rate_title" msgid="6030550998379310088">"Sprechgeschwindigkeit"</string>
     <string name="tts_default_rate_summary" msgid="4061815292287182801">"Geschwindigkeit, mit der der Text gesprochen wird"</string>
     <string name="tts_default_pitch_title" msgid="6135942113172488671">"Tonlage"</string>
@@ -220,6 +220,7 @@
     <string name="debug_networking_category" msgid="7044075693643009662">"Netzwerke"</string>
     <string name="wifi_display_certification" msgid="8611569543791307533">"Zertifizierung für kabellose Übertragung"</string>
     <string name="wifi_verbose_logging" msgid="4203729756047242344">"Ausführliche WLAN-Protokollierung aktivieren"</string>
+    <string name="wifi_scan_throttling" msgid="160014287416479843">"Drosselung der WLAN-Suche"</string>
     <string name="mobile_data_always_on" msgid="8774857027458200434">"Mobile Datennutzung immer aktiviert"</string>
     <string name="tethering_hardware_offload" msgid="7470077827090325814">"Hardwarebeschleunigung für Tethering"</string>
     <string name="bluetooth_show_devices_without_names" msgid="4708446092962060176">"Bluetooth-Geräte ohne Namen anzeigen"</string>
@@ -246,6 +247,7 @@
     <string name="private_dns_mode_provider_failure" msgid="231837290365031223">"Verbindung nicht möglich"</string>
     <string name="wifi_display_certification_summary" msgid="1155182309166746973">"Optionen zur Zertifizierung für kabellose Übertragung anzeigen"</string>
     <string name="wifi_verbose_logging_summary" msgid="6615071616111731958">"WLAN-Protokollierungsebene erhöhen, in WiFi Picker pro SSID RSSI anzeigen"</string>
+    <string name="wifi_scan_throttling_summary" msgid="4461922728822495763">"Verringert den Akkuverbrauch und verbessert die Netzwerkleistung"</string>
     <string name="wifi_metered_label" msgid="4514924227256839725">"Kostenpflichtig"</string>
     <string name="wifi_unmetered_label" msgid="6124098729457992931">"Kostenlos"</string>
     <string name="select_logd_size_title" msgid="7433137108348553508">"Logger-Puffergrößen"</string>
@@ -326,7 +328,7 @@
     <string name="app_process_limit_title" msgid="4280600650253107163">"Limit für Hintergrundprozesse"</string>
     <string name="show_all_anrs" msgid="4924885492787069007">"Absturzmeldungen für Hintergrund-Apps anzeigen"</string>
     <string name="show_all_anrs_summary" msgid="6636514318275139826">"Bei Abstürzen von Hintergrund-Apps \"App reagiert nicht\"-Dialog anzeigen"</string>
-    <string name="show_notification_channel_warnings" msgid="1399948193466922683">"Benachrichtigungskanal-Warnungen anzeigen"</string>
+    <string name="show_notification_channel_warnings" msgid="1399948193466922683">"Benachrichtigungskanal- Warnungen anzeigen"</string>
     <string name="show_notification_channel_warnings_summary" msgid="5536803251863694895">"Bei Benachrichtigungen ohne gültigen Kanal wird eine Warnung angezeigt"</string>
     <string name="force_allow_on_external" msgid="3215759785081916381">"Sperrung des externen Speichers für alle Apps aufheben"</string>
     <string name="force_allow_on_external_summary" msgid="3640752408258034689">"Jede App kann, ungeachtet der Manifestwerte, in den externen Speicher geschrieben werden"</string>
@@ -379,12 +381,12 @@
     <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">"Noch etwa <xliff:g id="TIME_REMAINING">%1$s</xliff:g>"</string>
     <string name="power_discharging_duration" msgid="8848256785736335185">"Noch etwa <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">"Noch etwa <xliff:g id="TIME_REMAINING">%1$s</xliff:g>, basierend auf deiner Nutzung"</string>
-    <string name="power_discharging_duration_enhanced" msgid="1992003260664804080">"Noch etwa <xliff:g id="TIME_REMAINING">%1$s</xliff:g>, basierend auf deiner Nutzung (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string>
+    <string name="power_remaining_duration_only_enhanced" msgid="4189311599812296592">"Bei deinem Nutzungsmuster hast du noch ca. <xliff:g id="TIME_REMAINING">%1$s</xliff:g>"</string>
+    <string name="power_discharging_duration_enhanced" msgid="1992003260664804080">"Bei deinem Nutzungsmuster hast du noch ca. <xliff:g id="TIME_REMAINING">%1$s</xliff:g> (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string>
     <!-- no translation found for power_remaining_duration_only_short (9183070574408359726) -->
     <skip />
-    <string name="power_discharge_by_enhanced" msgid="2095821536747992464">"Sollte basierend auf deiner Nutzung etwa bis <xliff:g id="TIME">%1$s</xliff:g> reichen (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string>
-    <string name="power_discharge_by_only_enhanced" msgid="2175151772952365149">"Sollte basierend auf deiner Nutzung etwa bis <xliff:g id="TIME">%1$s</xliff:g> reichen"</string>
+    <string name="power_discharge_by_enhanced" msgid="2095821536747992464">"Bei deinem Nutzungsmuster dürfte der Akku bis ca. <xliff:g id="TIME">%1$s</xliff:g> reichen (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string>
+    <string name="power_discharge_by_only_enhanced" msgid="2175151772952365149">"Bei deinem Nutzungsmuster dürfte der Akku bis ca. <xliff:g id="TIME">%1$s</xliff:g> reichen"</string>
     <string name="power_discharge_by" msgid="6453537733650125582">"Sollte etwa bis <xliff:g id="TIME">%1$s</xliff:g> reichen (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string>
     <string name="power_discharge_by_only" msgid="107616694963545745">"Sollte etwa bis <xliff:g id="TIME">%1$s</xliff:g> reichen"</string>
     <string name="power_discharge_by_only_short" msgid="1372817269546888804">"Bis <xliff:g id="TIME">%1$s</xliff:g>"</string>
diff --git a/packages/SettingsLib/res/values-el/strings.xml b/packages/SettingsLib/res/values-el/strings.xml
index 031cd0d..b1b1be6 100644
--- a/packages/SettingsLib/res/values-el/strings.xml
+++ b/packages/SettingsLib/res/values-el/strings.xml
@@ -220,6 +220,7 @@
     <string name="debug_networking_category" msgid="7044075693643009662">"Δικτύωση"</string>
     <string name="wifi_display_certification" msgid="8611569543791307533">"Πιστοποίηση ασύρματης οθόνης"</string>
     <string name="wifi_verbose_logging" msgid="4203729756047242344">"Ενεργοποίηση λεπτομερ. καταγραφής Wi-Fi"</string>
+    <string name="wifi_scan_throttling" msgid="160014287416479843">"Περιορισμός σάρωσης Wi-Fi"</string>
     <string name="mobile_data_always_on" msgid="8774857027458200434">"Πάντα ενεργά δεδομένα κινητής τηλεφωνίας"</string>
     <string name="tethering_hardware_offload" msgid="7470077827090325814">"Σύνδεση επιτάχυνσης υλικού"</string>
     <string name="bluetooth_show_devices_without_names" msgid="4708446092962060176">"Εμφάνιση συσκευών Bluetooth χωρίς ονόματα"</string>
@@ -246,6 +247,7 @@
     <string name="private_dns_mode_provider_failure" msgid="231837290365031223">"Δεν ήταν δυνατή η σύνδεση"</string>
     <string name="wifi_display_certification_summary" msgid="1155182309166746973">"Εμφάνιση επιλογών για πιστοποίηση ασύρματης οθόνης"</string>
     <string name="wifi_verbose_logging_summary" msgid="6615071616111731958">"Αύξηση επιπέδου καταγ. Wi-Fi, εμφάνιση ανά SSID RSSI στο εργαλείο επιλογής Wi-Fi"</string>
+    <string name="wifi_scan_throttling_summary" msgid="4461922728822495763">"Περιορίζει την κατανάλωση της μπαταρίας και βελτιώνει την απόδοση του δικτύου"</string>
     <string name="wifi_metered_label" msgid="4514924227256839725">"Μέτρηση με βάση τη χρήση"</string>
     <string name="wifi_unmetered_label" msgid="6124098729457992931">"Χωρίς μέτρηση με βάση τη χρήση"</string>
     <string name="select_logd_size_title" msgid="7433137108348553508">"Μέγεθος προσωρινής μνήμης για τη λειτουργία καταγραφής"</string>
diff --git a/packages/SettingsLib/res/values-en-rAU/strings.xml b/packages/SettingsLib/res/values-en-rAU/strings.xml
index 5728800..57f5d5a 100644
--- a/packages/SettingsLib/res/values-en-rAU/strings.xml
+++ b/packages/SettingsLib/res/values-en-rAU/strings.xml
@@ -220,6 +220,7 @@
     <string name="debug_networking_category" msgid="7044075693643009662">"Networking"</string>
     <string name="wifi_display_certification" msgid="8611569543791307533">"Wireless display certification"</string>
     <string name="wifi_verbose_logging" msgid="4203729756047242344">"Enable Wi‑Fi verbose logging"</string>
+    <string name="wifi_scan_throttling" msgid="160014287416479843">"Wi‑Fi scan throttling"</string>
     <string name="mobile_data_always_on" msgid="8774857027458200434">"Mobile data always active"</string>
     <string name="tethering_hardware_offload" msgid="7470077827090325814">"Tethering hardware acceleration"</string>
     <string name="bluetooth_show_devices_without_names" msgid="4708446092962060176">"Show Bluetooth devices without names"</string>
@@ -246,6 +247,7 @@
     <string name="private_dns_mode_provider_failure" msgid="231837290365031223">"Couldn\'t connect"</string>
     <string name="wifi_display_certification_summary" msgid="1155182309166746973">"Show options for wireless display certification"</string>
     <string name="wifi_verbose_logging_summary" msgid="6615071616111731958">"Increase Wi‑Fi logging level, show per SSID RSSI in Wi‑Fi Picker"</string>
+    <string name="wifi_scan_throttling_summary" msgid="4461922728822495763">"Reduces battery drain and improves network performance"</string>
     <string name="wifi_metered_label" msgid="4514924227256839725">"Metered"</string>
     <string name="wifi_unmetered_label" msgid="6124098729457992931">"Unmetered"</string>
     <string name="select_logd_size_title" msgid="7433137108348553508">"Logger buffer sizes"</string>
diff --git a/packages/SettingsLib/res/values-en-rCA/strings.xml b/packages/SettingsLib/res/values-en-rCA/strings.xml
index 5728800..57f5d5a 100644
--- a/packages/SettingsLib/res/values-en-rCA/strings.xml
+++ b/packages/SettingsLib/res/values-en-rCA/strings.xml
@@ -220,6 +220,7 @@
     <string name="debug_networking_category" msgid="7044075693643009662">"Networking"</string>
     <string name="wifi_display_certification" msgid="8611569543791307533">"Wireless display certification"</string>
     <string name="wifi_verbose_logging" msgid="4203729756047242344">"Enable Wi‑Fi verbose logging"</string>
+    <string name="wifi_scan_throttling" msgid="160014287416479843">"Wi‑Fi scan throttling"</string>
     <string name="mobile_data_always_on" msgid="8774857027458200434">"Mobile data always active"</string>
     <string name="tethering_hardware_offload" msgid="7470077827090325814">"Tethering hardware acceleration"</string>
     <string name="bluetooth_show_devices_without_names" msgid="4708446092962060176">"Show Bluetooth devices without names"</string>
@@ -246,6 +247,7 @@
     <string name="private_dns_mode_provider_failure" msgid="231837290365031223">"Couldn\'t connect"</string>
     <string name="wifi_display_certification_summary" msgid="1155182309166746973">"Show options for wireless display certification"</string>
     <string name="wifi_verbose_logging_summary" msgid="6615071616111731958">"Increase Wi‑Fi logging level, show per SSID RSSI in Wi‑Fi Picker"</string>
+    <string name="wifi_scan_throttling_summary" msgid="4461922728822495763">"Reduces battery drain and improves network performance"</string>
     <string name="wifi_metered_label" msgid="4514924227256839725">"Metered"</string>
     <string name="wifi_unmetered_label" msgid="6124098729457992931">"Unmetered"</string>
     <string name="select_logd_size_title" msgid="7433137108348553508">"Logger buffer sizes"</string>
diff --git a/packages/SettingsLib/res/values-en-rGB/strings.xml b/packages/SettingsLib/res/values-en-rGB/strings.xml
index 5728800..57f5d5a 100644
--- a/packages/SettingsLib/res/values-en-rGB/strings.xml
+++ b/packages/SettingsLib/res/values-en-rGB/strings.xml
@@ -220,6 +220,7 @@
     <string name="debug_networking_category" msgid="7044075693643009662">"Networking"</string>
     <string name="wifi_display_certification" msgid="8611569543791307533">"Wireless display certification"</string>
     <string name="wifi_verbose_logging" msgid="4203729756047242344">"Enable Wi‑Fi verbose logging"</string>
+    <string name="wifi_scan_throttling" msgid="160014287416479843">"Wi‑Fi scan throttling"</string>
     <string name="mobile_data_always_on" msgid="8774857027458200434">"Mobile data always active"</string>
     <string name="tethering_hardware_offload" msgid="7470077827090325814">"Tethering hardware acceleration"</string>
     <string name="bluetooth_show_devices_without_names" msgid="4708446092962060176">"Show Bluetooth devices without names"</string>
@@ -246,6 +247,7 @@
     <string name="private_dns_mode_provider_failure" msgid="231837290365031223">"Couldn\'t connect"</string>
     <string name="wifi_display_certification_summary" msgid="1155182309166746973">"Show options for wireless display certification"</string>
     <string name="wifi_verbose_logging_summary" msgid="6615071616111731958">"Increase Wi‑Fi logging level, show per SSID RSSI in Wi‑Fi Picker"</string>
+    <string name="wifi_scan_throttling_summary" msgid="4461922728822495763">"Reduces battery drain and improves network performance"</string>
     <string name="wifi_metered_label" msgid="4514924227256839725">"Metered"</string>
     <string name="wifi_unmetered_label" msgid="6124098729457992931">"Unmetered"</string>
     <string name="select_logd_size_title" msgid="7433137108348553508">"Logger buffer sizes"</string>
diff --git a/packages/SettingsLib/res/values-en-rIN/strings.xml b/packages/SettingsLib/res/values-en-rIN/strings.xml
index 5728800..57f5d5a 100644
--- a/packages/SettingsLib/res/values-en-rIN/strings.xml
+++ b/packages/SettingsLib/res/values-en-rIN/strings.xml
@@ -220,6 +220,7 @@
     <string name="debug_networking_category" msgid="7044075693643009662">"Networking"</string>
     <string name="wifi_display_certification" msgid="8611569543791307533">"Wireless display certification"</string>
     <string name="wifi_verbose_logging" msgid="4203729756047242344">"Enable Wi‑Fi verbose logging"</string>
+    <string name="wifi_scan_throttling" msgid="160014287416479843">"Wi‑Fi scan throttling"</string>
     <string name="mobile_data_always_on" msgid="8774857027458200434">"Mobile data always active"</string>
     <string name="tethering_hardware_offload" msgid="7470077827090325814">"Tethering hardware acceleration"</string>
     <string name="bluetooth_show_devices_without_names" msgid="4708446092962060176">"Show Bluetooth devices without names"</string>
@@ -246,6 +247,7 @@
     <string name="private_dns_mode_provider_failure" msgid="231837290365031223">"Couldn\'t connect"</string>
     <string name="wifi_display_certification_summary" msgid="1155182309166746973">"Show options for wireless display certification"</string>
     <string name="wifi_verbose_logging_summary" msgid="6615071616111731958">"Increase Wi‑Fi logging level, show per SSID RSSI in Wi‑Fi Picker"</string>
+    <string name="wifi_scan_throttling_summary" msgid="4461922728822495763">"Reduces battery drain and improves network performance"</string>
     <string name="wifi_metered_label" msgid="4514924227256839725">"Metered"</string>
     <string name="wifi_unmetered_label" msgid="6124098729457992931">"Unmetered"</string>
     <string name="select_logd_size_title" msgid="7433137108348553508">"Logger buffer sizes"</string>
diff --git a/packages/SettingsLib/res/values-en-rXC/strings.xml b/packages/SettingsLib/res/values-en-rXC/strings.xml
index 460442b..e5a0bda 100644
--- a/packages/SettingsLib/res/values-en-rXC/strings.xml
+++ b/packages/SettingsLib/res/values-en-rXC/strings.xml
@@ -220,6 +220,7 @@
     <string name="debug_networking_category" msgid="7044075693643009662">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‏‎‏‏‏‏‏‏‏‏‎‎‎‎‏‏‏‎‎‎‎‎‏‏‎‎‏‎‏‎‏‏‎‎‎‎‏‎‏‏‎‏‏‎‎‏‎‏‎‎‎‏‏‏‎‎‎‎‎‏‏‏‎‎‏‏‏‏‏‏‎‎Networking‎‏‎‎‏‎"</string>
     <string name="wifi_display_certification" msgid="8611569543791307533">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‏‎‏‏‏‏‏‏‏‏‏‎‏‏‏‏‎‎‎‎‎‏‎‎‏‏‏‎‎‎‎‏‏‎‏‏‏‏‏‏‏‎‎‎‎‎‎‎‏‎‎‎‎‎‎‏‏‏‎‏‎‏‏‎‎‎‎‏‏‎‏‎Wireless display certification‎‏‎‎‏‎"</string>
     <string name="wifi_verbose_logging" msgid="4203729756047242344">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‏‎‏‏‏‏‏‎‏‏‏‎‏‎‎‏‎‏‎‏‏‎‏‎‏‎‎‏‎‏‏‏‏‏‎‎‎‎‏‏‎‏‏‎‎‎‏‏‏‎‏‏‏‏‎‏‏‏‎‏‎‎‎‏‏‎‏‎‎‎‎Enable Wi‑Fi Verbose Logging‎‏‎‎‏‎"</string>
+    <string name="wifi_scan_throttling" msgid="160014287416479843">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‏‎‏‏‏‎‏‎‏‎‎‎‏‏‏‎‎‎‎‏‏‏‏‏‎‎‎‎‏‎‎‏‎‏‏‎‎‎‏‎‎‎‎‏‏‏‎‎‏‎‎‏‎‏‎‎‎‎‎‏‏‎‎‎‏‏‎Wi‑Fi scan throttling‎‏‎‎‏‎"</string>
     <string name="mobile_data_always_on" msgid="8774857027458200434">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‏‎‏‏‏‏‏‏‏‏‏‏‎‎‏‏‏‎‎‎‏‏‎‏‎‎‎‏‏‎‏‏‏‏‏‏‎‎‏‏‎‏‎‏‏‎‎‎‏‏‏‏‏‎‎‎‏‏‏‎‎‏‏‎‏‏‏‎‎‏‎‎Mobile data always active‎‏‎‎‏‎"</string>
     <string name="tethering_hardware_offload" msgid="7470077827090325814">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‏‎‏‏‏‏‏‏‏‏‎‎‏‏‏‏‎‏‎‏‎‏‏‎‎‎‎‏‏‎‎‎‎‏‏‎‏‎‎‏‎‏‎‎‎‎‎‎‎‏‏‏‏‎‏‏‎‏‎‎‎‎‏‎‎‏‏‎‏‏‎‎Tethering hardware acceleration‎‏‎‎‏‎"</string>
     <string name="bluetooth_show_devices_without_names" msgid="4708446092962060176">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‏‎‏‏‏‏‏‏‏‎‎‎‎‎‏‎‏‎‏‎‏‏‏‏‏‎‎‎‎‏‎‏‏‎‎‎‏‏‎‎‏‏‎‏‏‏‏‎‎‎‏‎‏‎‎‎‏‎‏‎‏‏‏‏‎‎‏‎‎‎‎‎Show Bluetooth devices without names‎‏‎‎‏‎"</string>
@@ -246,6 +247,7 @@
     <string name="private_dns_mode_provider_failure" msgid="231837290365031223">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‏‎‏‏‏‎‏‎‏‏‎‎‏‏‎‏‏‏‏‎‏‎‎‏‏‎‏‏‎‎‏‎‎‏‏‎‎‎‏‎‎‏‏‏‏‎‎‏‎‏‏‎‎‏‎‎‏‏‎‎‏‏‎‏‏‏‎Couldn\'t connect‎‏‎‎‏‎"</string>
     <string name="wifi_display_certification_summary" msgid="1155182309166746973">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‏‎‏‏‏‏‎‏‏‎‎‎‎‎‎‎‎‏‎‎‎‎‎‎‎‏‎‎‎‎‎‏‏‎‎‎‎‏‎‎‏‎‏‎‎‏‎‏‏‎‎‏‏‎‎‎‎‏‏‎‏‎‏‎‏‏‏‎‏‎Show options for wireless display certification‎‏‎‎‏‎"</string>
     <string name="wifi_verbose_logging_summary" msgid="6615071616111731958">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‏‎‏‏‏‏‏‏‏‎‏‏‎‏‏‏‏‎‎‏‏‎‏‎‏‏‏‎‏‎‎‏‎‎‏‎‏‏‎‎‎‏‏‎‎‏‎‎‎‎‏‏‎‏‏‏‏‏‎‎‏‎‎‏‏‏‏‎‏‏‎‎Increase Wi‑Fi logging level, show per SSID RSSI in Wi‑Fi Picker‎‏‎‎‏‎"</string>
+    <string name="wifi_scan_throttling_summary" msgid="4461922728822495763">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‏‎‏‏‏‏‏‎‏‏‏‏‎‏‏‏‏‎‏‎‏‏‏‏‏‎‏‏‏‏‎‎‎‏‎‏‎‎‏‏‏‎‎‎‏‎‏‎‏‏‎‏‎‎‏‏‎‏‏‎‏‎‎‎‎‏‎‎‏‏‎Reduces battery drain &amp; improves network performance‎‏‎‎‏‎"</string>
     <string name="wifi_metered_label" msgid="4514924227256839725">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‏‎‏‏‏‏‏‎‏‏‏‏‏‎‏‎‏‎‏‎‎‎‎‎‏‏‏‎‏‏‏‎‏‎‏‎‎‏‏‏‏‎‎‎‎‏‎‏‏‏‎‎‏‎‏‏‏‎‏‏‏‎‎‎‏‎‏‏‎‏‎Metered‎‏‎‎‏‎"</string>
     <string name="wifi_unmetered_label" msgid="6124098729457992931">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‏‎‏‏‏‏‏‏‏‎‏‎‏‎‎‏‏‏‏‏‏‎‏‎‎‏‎‏‎‏‏‎‏‎‏‏‎‎‎‏‏‏‏‏‎‏‎‏‏‎‎‎‎‏‏‏‏‎‎‎‏‎‎‏‏‏‎‎‎‏‏‎Unmetered‎‏‎‎‏‎"</string>
     <string name="select_logd_size_title" msgid="7433137108348553508">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‏‎‏‏‏‏‏‏‏‏‎‎‏‏‏‎‎‏‎‎‏‏‏‏‏‎‎‏‏‏‎‏‏‎‏‎‎‎‏‎‏‎‎‏‏‎‏‏‏‏‎‎‎‏‏‏‏‎‎‏‎‎‏‎‎‏‎‎‏‎‎‎Logger buffer sizes‎‏‎‎‏‎"</string>
diff --git a/packages/SettingsLib/res/values-es-rUS/strings.xml b/packages/SettingsLib/res/values-es-rUS/strings.xml
index a939050..beb1ac5 100644
--- a/packages/SettingsLib/res/values-es-rUS/strings.xml
+++ b/packages/SettingsLib/res/values-es-rUS/strings.xml
@@ -220,6 +220,7 @@
     <string name="debug_networking_category" msgid="7044075693643009662">"Redes"</string>
     <string name="wifi_display_certification" msgid="8611569543791307533">"Certificación de pantalla inalámbrica"</string>
     <string name="wifi_verbose_logging" msgid="4203729756047242344">"Habilitar registro detallado de Wi-Fi"</string>
+    <string name="wifi_scan_throttling" msgid="160014287416479843">"Limitación de búsqueda de Wi-Fi"</string>
     <string name="mobile_data_always_on" msgid="8774857027458200434">"Datos móviles siempre activados"</string>
     <string name="tethering_hardware_offload" msgid="7470077827090325814">"Aceleración de hardware de conexión mediante dispositivo portátil"</string>
     <string name="bluetooth_show_devices_without_names" msgid="4708446092962060176">"Mostrar dispositivos Bluetooth sin nombre"</string>
@@ -246,6 +247,7 @@
     <string name="private_dns_mode_provider_failure" msgid="231837290365031223">"No se pudo establecer conexión"</string>
     <string name="wifi_display_certification_summary" msgid="1155182309166746973">"Mostrar opciones de certificación de pantalla inalámbrica"</string>
     <string name="wifi_verbose_logging_summary" msgid="6615071616111731958">"Aumentar nivel de registro Wi-Fi; mostrar por SSID RSSI en el selector de Wi-Fi"</string>
+    <string name="wifi_scan_throttling_summary" msgid="4461922728822495763">"Reduce el consumo de batería y mejora el rendimiento de la red"</string>
     <string name="wifi_metered_label" msgid="4514924227256839725">"Con uso medido"</string>
     <string name="wifi_unmetered_label" msgid="6124098729457992931">"Sin tarifa plana"</string>
     <string name="select_logd_size_title" msgid="7433137108348553508">"Tamaños de búfer de Logger"</string>
diff --git a/packages/SettingsLib/res/values-es/strings.xml b/packages/SettingsLib/res/values-es/strings.xml
index 533296c..e1277d8 100644
--- a/packages/SettingsLib/res/values-es/strings.xml
+++ b/packages/SettingsLib/res/values-es/strings.xml
@@ -220,6 +220,7 @@
     <string name="debug_networking_category" msgid="7044075693643009662">"Redes"</string>
     <string name="wifi_display_certification" msgid="8611569543791307533">"Certificación de pantalla inalámbrica"</string>
     <string name="wifi_verbose_logging" msgid="4203729756047242344">"Habilitar registro de Wi-Fi detallado"</string>
+    <string name="wifi_scan_throttling" msgid="160014287416479843">"Limitación de búsqueda de redes Wi‑Fi"</string>
     <string name="mobile_data_always_on" msgid="8774857027458200434">"Datos móviles siempre activos"</string>
     <string name="tethering_hardware_offload" msgid="7470077827090325814">"Aceleración por hardware para conexión compartida"</string>
     <string name="bluetooth_show_devices_without_names" msgid="4708446092962060176">"Mostrar dispositivos Bluetooth sin nombre"</string>
@@ -246,6 +247,7 @@
     <string name="private_dns_mode_provider_failure" msgid="231837290365031223">"No se ha podido establecer la conexión"</string>
     <string name="wifi_display_certification_summary" msgid="1155182309166746973">"Mostrar opciones para la certificación de la pantalla inalámbrica"</string>
     <string name="wifi_verbose_logging_summary" msgid="6615071616111731958">"Aumentar el nivel de registro de Wi-Fi y mostrar por SSID RSSI en el selector Wi-Fi"</string>
+    <string name="wifi_scan_throttling_summary" msgid="4461922728822495763">"Reduce el consumo de batería y mejora el rendimiento de las redes"</string>
     <string name="wifi_metered_label" msgid="4514924227256839725">"Medida"</string>
     <string name="wifi_unmetered_label" msgid="6124098729457992931">"No medida"</string>
     <string name="select_logd_size_title" msgid="7433137108348553508">"Tamaños del búfer para registrar"</string>
diff --git a/packages/SettingsLib/res/values-et/strings.xml b/packages/SettingsLib/res/values-et/strings.xml
index e5e8f56..090b28d 100644
--- a/packages/SettingsLib/res/values-et/strings.xml
+++ b/packages/SettingsLib/res/values-et/strings.xml
@@ -220,6 +220,7 @@
     <string name="debug_networking_category" msgid="7044075693643009662">"Võrgundus"</string>
     <string name="wifi_display_certification" msgid="8611569543791307533">"Juhtmeta ekraaniühenduse sertifitseerimine"</string>
     <string name="wifi_verbose_logging" msgid="4203729756047242344">"Luba WiFi sõnaline logimine"</string>
+    <string name="wifi_scan_throttling" msgid="160014287416479843">"WiFi-skannimise ahendamine"</string>
     <string name="mobile_data_always_on" msgid="8774857027458200434">"Hoia mobiilne andmeside alati aktiivne"</string>
     <string name="tethering_hardware_offload" msgid="7470077827090325814">"Ühenduse jagamise riistvaraline kiirendus"</string>
     <string name="bluetooth_show_devices_without_names" msgid="4708446092962060176">"Kuva ilma nimedeta Bluetoothi seadmed"</string>
@@ -246,6 +247,7 @@
     <string name="private_dns_mode_provider_failure" msgid="231837290365031223">"Ühendamine ebaõnnestus"</string>
     <string name="wifi_display_certification_summary" msgid="1155182309166746973">"Juhtmeta ekraaniühenduse sertifitseerimisvalikute kuvamine"</string>
     <string name="wifi_verbose_logging_summary" msgid="6615071616111731958">"Suurenda WiFi logimistaset, kuva WiFi valijas SSID RSSI järgi"</string>
+    <string name="wifi_scan_throttling_summary" msgid="4461922728822495763">"Aeglustab aku tühjenemist ja parandab võrgu toimivust"</string>
     <string name="wifi_metered_label" msgid="4514924227256839725">"Mahupõhine"</string>
     <string name="wifi_unmetered_label" msgid="6124098729457992931">"Mittemahupõhine"</string>
     <string name="select_logd_size_title" msgid="7433137108348553508">"Logija puhvri suurused"</string>
diff --git a/packages/SettingsLib/res/values-eu/strings.xml b/packages/SettingsLib/res/values-eu/strings.xml
index 3c11efd..d2e3a38 100644
--- a/packages/SettingsLib/res/values-eu/strings.xml
+++ b/packages/SettingsLib/res/values-eu/strings.xml
@@ -220,6 +220,7 @@
     <string name="debug_networking_category" msgid="7044075693643009662">"Sareak"</string>
     <string name="wifi_display_certification" msgid="8611569543791307533">"Hari gabe bistaratzeko ziurtagiria"</string>
     <string name="wifi_verbose_logging" msgid="4203729756047242344">"Gaitu wifi-sareetan saioa hasteko modu xehatua"</string>
+    <string name="wifi_scan_throttling" msgid="160014287416479843">"Wifi-sareen bilaketaren muga"</string>
     <string name="mobile_data_always_on" msgid="8774857027458200434">"Datu-konexioa beti aktibo"</string>
     <string name="tethering_hardware_offload" msgid="7470077827090325814">"Konexioa partekatzeko hardwarearen azelerazioa"</string>
     <string name="bluetooth_show_devices_without_names" msgid="4708446092962060176">"Erakutsi Bluetooth gailuak izenik gabe"</string>
@@ -246,6 +247,7 @@
     <string name="private_dns_mode_provider_failure" msgid="231837290365031223">"Ezin izan da konektatu"</string>
     <string name="wifi_display_certification_summary" msgid="1155182309166746973">"Erakutsi hari gabe bistaratzeko ziurtagiriaren aukerak"</string>
     <string name="wifi_verbose_logging_summary" msgid="6615071616111731958">"Erakutsi datu gehiago wifi-sareetan saioa hastean. Erakutsi sarearen identifikatzailea eta seinalearen indarra wifi-sareen hautagailuan."</string>
+    <string name="wifi_scan_throttling_summary" msgid="4461922728822495763">"Bateria gutxiago kontsumituko da, eta sarearen errendimendua hobetuko."</string>
     <string name="wifi_metered_label" msgid="4514924227256839725">"Sare neurtua"</string>
     <string name="wifi_unmetered_label" msgid="6124098729457992931">"Neurtu gabeko sarea"</string>
     <string name="select_logd_size_title" msgid="7433137108348553508">"Erregistroen buffer-tamainak"</string>
diff --git a/packages/SettingsLib/res/values-fa/strings.xml b/packages/SettingsLib/res/values-fa/strings.xml
index 9a3061d..6632752 100644
--- a/packages/SettingsLib/res/values-fa/strings.xml
+++ b/packages/SettingsLib/res/values-fa/strings.xml
@@ -220,6 +220,7 @@
     <string name="debug_networking_category" msgid="7044075693643009662">"شبکه"</string>
     <string name="wifi_display_certification" msgid="8611569543791307533">"گواهینامه نمایش بی‌سیم"</string>
     <string name="wifi_verbose_logging" msgid="4203729756047242344">"‏فعال کردن گزارش‌گیری طولانی Wi‑Fi"</string>
+    <string name="wifi_scan_throttling" msgid="160014287416479843">"‏محدود کردن اسکن کردن Wi‑Fi"</string>
     <string name="mobile_data_always_on" msgid="8774857027458200434">"داده تلفن همراه همیشه فعال باشد"</string>
     <string name="tethering_hardware_offload" msgid="7470077827090325814">"شتاب سخت‌افزاری اتصال به اینترنت با تلفن همراه"</string>
     <string name="bluetooth_show_devices_without_names" msgid="4708446092962060176">"نمایش دستگاه‌های بلوتوث بدون نام"</string>
@@ -246,6 +247,7 @@
     <string name="private_dns_mode_provider_failure" msgid="231837290365031223">"متصل نشد"</string>
     <string name="wifi_display_certification_summary" msgid="1155182309166746973">"نمایش گزینه‌ها برای گواهینامه نمایش بی‌سیم"</string>
     <string name="wifi_verbose_logging_summary" msgid="6615071616111731958">"‏افزایش سطح گزارش‌گیری Wi‑Fi، نمایش به ازای SSID RSSI در انتخاب‌کننده Wi‑Fi"</string>
+    <string name="wifi_scan_throttling_summary" msgid="4461922728822495763">"تخلیه باتری راکاهش می‌دهد و عملکرد شبکه را بهبود می‌بخشد"</string>
     <string name="wifi_metered_label" msgid="4514924227256839725">"محدودشده"</string>
     <string name="wifi_unmetered_label" msgid="6124098729457992931">"محدودنشده"</string>
     <string name="select_logd_size_title" msgid="7433137108348553508">"اندازه‌های حافظه موقت ثبت‌کننده"</string>
diff --git a/packages/SettingsLib/res/values-fi/strings.xml b/packages/SettingsLib/res/values-fi/strings.xml
index b166cb0..0d522c4 100644
--- a/packages/SettingsLib/res/values-fi/strings.xml
+++ b/packages/SettingsLib/res/values-fi/strings.xml
@@ -220,6 +220,7 @@
     <string name="debug_networking_category" msgid="7044075693643009662">"Yhteysominaisuudet"</string>
     <string name="wifi_display_certification" msgid="8611569543791307533">"Langattoman näytön sertifiointi"</string>
     <string name="wifi_verbose_logging" msgid="4203729756047242344">"Käytä Wi-Fin laajennettua lokikirjausta"</string>
+    <string name="wifi_scan_throttling" msgid="160014287416479843">"Wi‑Fi-haun rajoitus"</string>
     <string name="mobile_data_always_on" msgid="8774857027458200434">"Mobiilidata aina käytössä"</string>
     <string name="tethering_hardware_offload" msgid="7470077827090325814">"Laitteistokiihdytyksen yhteyden jakaminen"</string>
     <string name="bluetooth_show_devices_without_names" msgid="4708446092962060176">"Näytä nimettömät Bluetooth-laitteet"</string>
@@ -246,6 +247,7 @@
     <string name="private_dns_mode_provider_failure" msgid="231837290365031223">"Ei yhteyttä"</string>
     <string name="wifi_display_certification_summary" msgid="1155182309166746973">"Näytä langattoman näytön sertifiointiin liittyvät asetukset."</string>
     <string name="wifi_verbose_logging_summary" msgid="6615071616111731958">"Lisää Wi‑Fin lokikirjaustasoa, näytä SSID RSSI -kohtaisesti Wi‑Fi-valitsimessa."</string>
+    <string name="wifi_scan_throttling_summary" msgid="4461922728822495763">"Vähentää virrankulutusta ja parantaa verkon toimintaa"</string>
     <string name="wifi_metered_label" msgid="4514924227256839725">"Maksullinen"</string>
     <string name="wifi_unmetered_label" msgid="6124098729457992931">"Maksuton"</string>
     <string name="select_logd_size_title" msgid="7433137108348553508">"Lokipuskurien koot"</string>
diff --git a/packages/SettingsLib/res/values-fr-rCA/strings.xml b/packages/SettingsLib/res/values-fr-rCA/strings.xml
index 9983337..1dde863 100644
--- a/packages/SettingsLib/res/values-fr-rCA/strings.xml
+++ b/packages/SettingsLib/res/values-fr-rCA/strings.xml
@@ -153,7 +153,7 @@
     <string name="launch_defaults_some" msgid="313159469856372621">"Certaines préférences par défaut définies"</string>
     <string name="launch_defaults_none" msgid="4241129108140034876">"Aucune préférence par défaut définie"</string>
     <string name="tts_settings" msgid="8186971894801348327">"Synthèse vocale"</string>
-    <string name="tts_settings_title" msgid="1237820681016639683">"Sortie de la synthèse vocale"</string>
+    <string name="tts_settings_title" msgid="1237820681016639683">"Synthèse vocale"</string>
     <string name="tts_default_rate_title" msgid="6030550998379310088">"Cadence"</string>
     <string name="tts_default_rate_summary" msgid="4061815292287182801">"Vitesse à laquelle le texte est énoncé"</string>
     <string name="tts_default_pitch_title" msgid="6135942113172488671">"Ton"</string>
@@ -220,6 +220,7 @@
     <string name="debug_networking_category" msgid="7044075693643009662">"Réseautage"</string>
     <string name="wifi_display_certification" msgid="8611569543791307533">"Certification de l\'affichage sans fil"</string>
     <string name="wifi_verbose_logging" msgid="4203729756047242344">"Autoriser enreg. données Wi-Fi détaillées"</string>
+    <string name="wifi_scan_throttling" msgid="160014287416479843">"Limiter la recherche de réseaux Wi-Fi"</string>
     <string name="mobile_data_always_on" msgid="8774857027458200434">"Données cellulaires toujours actives"</string>
     <string name="tethering_hardware_offload" msgid="7470077827090325814">"Accélération matérielle pour le partage de connexion"</string>
     <string name="bluetooth_show_devices_without_names" msgid="4708446092962060176">"Afficher les appareils Bluetooth sans nom"</string>
@@ -246,6 +247,7 @@
     <string name="private_dns_mode_provider_failure" msgid="231837290365031223">"Impossible de se connecter"</string>
     <string name="wifi_display_certification_summary" msgid="1155182309166746973">"Afficher les options pour la certification d\'affichage sans fil"</string>
     <string name="wifi_verbose_logging_summary" msgid="6615071616111731958">"Détailler davantage les données Wi-Fi, afficher par SSID RSSI dans sélect. Wi-Fi"</string>
+    <string name="wifi_scan_throttling_summary" msgid="4461922728822495763">"Réduit l\'utilisation de la pile et améliore les performances réseau"</string>
     <string name="wifi_metered_label" msgid="4514924227256839725">"Facturé à l\'usage"</string>
     <string name="wifi_unmetered_label" msgid="6124098729457992931">"Non mesuré"</string>
     <string name="select_logd_size_title" msgid="7433137108348553508">"Tailles des mémoires tampons d\'enregistreur"</string>
diff --git a/packages/SettingsLib/res/values-fr/strings.xml b/packages/SettingsLib/res/values-fr/strings.xml
index 79c762e..3aa8db9 100644
--- a/packages/SettingsLib/res/values-fr/strings.xml
+++ b/packages/SettingsLib/res/values-fr/strings.xml
@@ -220,6 +220,7 @@
     <string name="debug_networking_category" msgid="7044075693643009662">"Mise en réseau"</string>
     <string name="wifi_display_certification" msgid="8611569543791307533">"Certification affichage sans fil"</string>
     <string name="wifi_verbose_logging" msgid="4203729756047242344">"Autoriser l\'enregistrement d\'infos Wi-Fi détaillées"</string>
+    <string name="wifi_scan_throttling" msgid="160014287416479843">"Limiter la recherche Wi‑Fi"</string>
     <string name="mobile_data_always_on" msgid="8774857027458200434">"Données mobiles toujours actives"</string>
     <string name="tethering_hardware_offload" msgid="7470077827090325814">"Accélération matérielle pour le partage de connexion"</string>
     <string name="bluetooth_show_devices_without_names" msgid="4708446092962060176">"Afficher les appareils Bluetooth sans nom"</string>
@@ -246,6 +247,7 @@
     <string name="private_dns_mode_provider_failure" msgid="231837290365031223">"Impossible de se connecter"</string>
     <string name="wifi_display_certification_summary" msgid="1155182309166746973">"Afficher les options pour la certification de l\'affichage sans fil"</string>
     <string name="wifi_verbose_logging_summary" msgid="6615071616111731958">"Détailler les infos Wi-Fi, afficher par RSSI de SSID dans l\'outil de sélection Wi-Fi"</string>
+    <string name="wifi_scan_throttling_summary" msgid="4461922728822495763">"Réduit la décharge de la batterie et améliore les performances du réseau"</string>
     <string name="wifi_metered_label" msgid="4514924227256839725">"Facturé à l\'usage"</string>
     <string name="wifi_unmetered_label" msgid="6124098729457992931">"Non facturé à l\'usage"</string>
     <string name="select_logd_size_title" msgid="7433137108348553508">"Tailles des tampons de l\'enregistreur"</string>
diff --git a/packages/SettingsLib/res/values-gl/strings.xml b/packages/SettingsLib/res/values-gl/strings.xml
index f41be39..4bd1c78 100644
--- a/packages/SettingsLib/res/values-gl/strings.xml
+++ b/packages/SettingsLib/res/values-gl/strings.xml
@@ -220,6 +220,7 @@
     <string name="debug_networking_category" msgid="7044075693643009662">"Redes"</string>
     <string name="wifi_display_certification" msgid="8611569543791307533">"Certificado de visualización sen fíos"</string>
     <string name="wifi_verbose_logging" msgid="4203729756047242344">"Activar rexistro detallado da wifi"</string>
+    <string name="wifi_scan_throttling" msgid="160014287416479843">"Limitación da busca de wifi"</string>
     <string name="mobile_data_always_on" msgid="8774857027458200434">"Datos móbiles sempre activados"</string>
     <string name="tethering_hardware_offload" msgid="7470077827090325814">"Aceleración de hardware para conexión compartida"</string>
     <string name="bluetooth_show_devices_without_names" msgid="4708446092962060176">"Mostrar dispositivos Bluetooth sen nomes"</string>
@@ -246,6 +247,7 @@
     <string name="private_dns_mode_provider_failure" msgid="231837290365031223">"Non se puido conectar"</string>
     <string name="wifi_display_certification_summary" msgid="1155182309166746973">"Mostra opcións para o certificado de visualización sen fíos"</string>
     <string name="wifi_verbose_logging_summary" msgid="6615071616111731958">"Aumenta o nivel de rexistro da wifi, móstrao por SSID RSSI no selector de wifi"</string>
+    <string name="wifi_scan_throttling_summary" msgid="4461922728822495763">"Reduce o consumo de batería e mellora o rendemento da rede"</string>
     <string name="wifi_metered_label" msgid="4514924227256839725">"Sen tarifa plana"</string>
     <string name="wifi_unmetered_label" msgid="6124098729457992931">"Con tarifa plana"</string>
     <string name="select_logd_size_title" msgid="7433137108348553508">"Tamaño dos búfers do rexistrador"</string>
diff --git a/packages/SettingsLib/res/values-gu/strings.xml b/packages/SettingsLib/res/values-gu/strings.xml
index a411a05..cf0e201 100644
--- a/packages/SettingsLib/res/values-gu/strings.xml
+++ b/packages/SettingsLib/res/values-gu/strings.xml
@@ -220,6 +220,7 @@
     <string name="debug_networking_category" msgid="7044075693643009662">"નેટવર્કિંગ"</string>
     <string name="wifi_display_certification" msgid="8611569543791307533">"વાયરલેસ ડિસ્પ્લે પ્રમાણન"</string>
     <string name="wifi_verbose_logging" msgid="4203729756047242344">"વાઇ-ફાઇ વર્બોઝ લૉગિંગ ચાલુ કરો"</string>
+    <string name="wifi_scan_throttling" msgid="160014287416479843">"વાઇ-ફાઇ સ્કૅનની ક્ષમતા મર્યાદિત કરવી"</string>
     <string name="mobile_data_always_on" msgid="8774857027458200434">"મોબાઇલ ડેટા હંમેશાં સક્રિય"</string>
     <string name="tethering_hardware_offload" msgid="7470077827090325814">"ટિથરિંગ માટે હાર્ડવેર ગતિવૃદ્ધિ"</string>
     <string name="bluetooth_show_devices_without_names" msgid="4708446092962060176">"નામ વિનાના બ્લૂટૂથ ઉપકરણો બતાવો"</string>
@@ -246,6 +247,7 @@
     <string name="private_dns_mode_provider_failure" msgid="231837290365031223">"કનેક્ટ કરી શકાયું નથી"</string>
     <string name="wifi_display_certification_summary" msgid="1155182309166746973">"વાયરલેસ ડિસ્પ્લે પ્રમાણપત્ર માટેના વિકલ્પો બતાવો"</string>
     <string name="wifi_verbose_logging_summary" msgid="6615071616111731958">"વાઇ-ફાઇ લોગિંગ સ્તર વધારો, વાઇ-ફાઇ પીકરમાં SSID RSSI દીઠ બતાવો"</string>
+    <string name="wifi_scan_throttling_summary" msgid="4461922728822495763">"બૅટરીનો ચાર્જ ઝડપથી ઓછો થવાનું ટાળે છે અને નેટવર્કની કાર્યક્ષમતામાં સુધારો કરે છે"</string>
     <string name="wifi_metered_label" msgid="4514924227256839725">"મીટર કરેલ"</string>
     <string name="wifi_unmetered_label" msgid="6124098729457992931">"મીટર ન કરેલ"</string>
     <string name="select_logd_size_title" msgid="7433137108348553508">"લોગર બફર કદ"</string>
diff --git a/packages/SettingsLib/res/values-hi/strings.xml b/packages/SettingsLib/res/values-hi/strings.xml
index 2c37efa9..8c6ff8e 100644
--- a/packages/SettingsLib/res/values-hi/strings.xml
+++ b/packages/SettingsLib/res/values-hi/strings.xml
@@ -220,6 +220,7 @@
     <string name="debug_networking_category" msgid="7044075693643009662">"नेटवर्किंग"</string>
     <string name="wifi_display_certification" msgid="8611569543791307533">"वायरलेस डिसप्ले सर्टिफ़िकेशन"</string>
     <string name="wifi_verbose_logging" msgid="4203729756047242344">"वाई-फ़ाई वर्बोस लॉगिंग चालू करें"</string>
+    <string name="wifi_scan_throttling" msgid="160014287416479843">"वाई-फ़ाई के लिए स्कैन की संख्या कम करें"</string>
     <string name="mobile_data_always_on" msgid="8774857027458200434">"मोबाइल डेटा हमेशा चालू"</string>
     <string name="tethering_hardware_offload" msgid="7470077827090325814">"हार्डवेयर से तेज़ी लाने के लिए टेदर करें"</string>
     <string name="bluetooth_show_devices_without_names" msgid="4708446092962060176">"बिना नाम वाले ब्लूटूथ डिवाइस दिखाएं"</string>
@@ -246,6 +247,7 @@
     <string name="private_dns_mode_provider_failure" msgid="231837290365031223">"कनेक्‍ट नहीं हो सका"</string>
     <string name="wifi_display_certification_summary" msgid="1155182309166746973">"वायरलेस डिसप्ले सर्टिफ़िकेशन के विकल्प दिखाएं"</string>
     <string name="wifi_verbose_logging_summary" msgid="6615071616111731958">"वाई-फ़ाई लॉगिंग का स्तर बढ़ाएं, वाई-फ़ाई पिकर में प्रति SSID RSSI दिखाएं"</string>
+    <string name="wifi_scan_throttling_summary" msgid="4461922728822495763">"बैटरी की खपत कम और नेटवर्क की परफ़ॉर्मेंस बेहतर होती है"</string>
     <string name="wifi_metered_label" msgid="4514924227256839725">"डेटा इस्तेमाल करने की सीमा तय की गई है"</string>
     <string name="wifi_unmetered_label" msgid="6124098729457992931">"डेटा इस्तेमाल करने की सीमा तय नहीं की गई है"</string>
     <string name="select_logd_size_title" msgid="7433137108348553508">"लॉगर बफ़र आकार"</string>
diff --git a/packages/SettingsLib/res/values-hr/strings.xml b/packages/SettingsLib/res/values-hr/strings.xml
index ea4a688..6d957dc 100644
--- a/packages/SettingsLib/res/values-hr/strings.xml
+++ b/packages/SettingsLib/res/values-hr/strings.xml
@@ -220,6 +220,7 @@
     <string name="debug_networking_category" msgid="7044075693643009662">"Umrežavanje"</string>
     <string name="wifi_display_certification" msgid="8611569543791307533">"Certifikacija bežičnog prikaza"</string>
     <string name="wifi_verbose_logging" msgid="4203729756047242344">"Omogući opširnu prijavu na Wi-Fi"</string>
+    <string name="wifi_scan_throttling" msgid="160014287416479843">"Usporavanje traženja Wi-Fija"</string>
     <string name="mobile_data_always_on" msgid="8774857027458200434">"Mobilni podaci uvijek aktivni"</string>
     <string name="tethering_hardware_offload" msgid="7470077827090325814">"Hardversko ubrzanje za modemsko povezivanje"</string>
     <string name="bluetooth_show_devices_without_names" msgid="4708446092962060176">"Prikaži Bluetooth uređaje bez naziva"</string>
@@ -246,6 +247,7 @@
     <string name="private_dns_mode_provider_failure" msgid="231837290365031223">"Povezivanje nije moguće"</string>
     <string name="wifi_display_certification_summary" msgid="1155182309166746973">"Prikaz opcija za certifikaciju bežičnog prikaza"</string>
     <string name="wifi_verbose_logging_summary" msgid="6615071616111731958">"Povećana razina prijave na Wi‑Fi, prikaz po SSID RSSI-ju u Biraču Wi‑Fi-ja"</string>
+    <string name="wifi_scan_throttling_summary" msgid="4461922728822495763">"Smanjuje potrošnju baterije i poboljšava rad mreže"</string>
     <string name="wifi_metered_label" msgid="4514924227256839725">"S ograničenim prometom"</string>
     <string name="wifi_unmetered_label" msgid="6124098729457992931">"Bez ograničenja prometa"</string>
     <string name="select_logd_size_title" msgid="7433137108348553508">"Veličine međuspremnika zapisnika"</string>
diff --git a/packages/SettingsLib/res/values-hu/strings.xml b/packages/SettingsLib/res/values-hu/strings.xml
index d4fc9a7..39b5da2 100644
--- a/packages/SettingsLib/res/values-hu/strings.xml
+++ b/packages/SettingsLib/res/values-hu/strings.xml
@@ -220,6 +220,7 @@
     <string name="debug_networking_category" msgid="7044075693643009662">"Hálózatok"</string>
     <string name="wifi_display_certification" msgid="8611569543791307533">"Vezeték nélküli kijelző tanúsítványa"</string>
     <string name="wifi_verbose_logging" msgid="4203729756047242344">"Részletes Wi-Fi-naplózás engedélyezése"</string>
+    <string name="wifi_scan_throttling" msgid="160014287416479843">"Wi-Fi-hálózat szabályozása"</string>
     <string name="mobile_data_always_on" msgid="8774857027458200434">"A mobilhálózati kapcsolat mindig aktív"</string>
     <string name="tethering_hardware_offload" msgid="7470077827090325814">"Internetmegosztás hardveres gyorsítása"</string>
     <string name="bluetooth_show_devices_without_names" msgid="4708446092962060176">"Név nélküli Bluetooth-eszközök megjelenítése"</string>
@@ -246,6 +247,7 @@
     <string name="private_dns_mode_provider_failure" msgid="231837290365031223">"Nem sikerült kapcsolódni"</string>
     <string name="wifi_display_certification_summary" msgid="1155182309166746973">"Vezeték nélküli kijelző tanúsítványával kapcsolatos lehetőségek megjelenítése"</string>
     <string name="wifi_verbose_logging_summary" msgid="6615071616111731958">"Wi‑Fi-naplózási szint növelése, RSSI/SSID megjelenítése a Wi‑Fi-választóban"</string>
+    <string name="wifi_scan_throttling_summary" msgid="4461922728822495763">"Csökkenti az akkumulátorhasználatot, és javítja a hálózat teljesítményét"</string>
     <string name="wifi_metered_label" msgid="4514924227256839725">"Forgalomkorlátos"</string>
     <string name="wifi_unmetered_label" msgid="6124098729457992931">"Nem forgalomkorlátos"</string>
     <string name="select_logd_size_title" msgid="7433137108348553508">"Naplózási puffer mérete"</string>
diff --git a/packages/SettingsLib/res/values-hy/strings.xml b/packages/SettingsLib/res/values-hy/strings.xml
index 9ae2fa2..bf58740 100644
--- a/packages/SettingsLib/res/values-hy/strings.xml
+++ b/packages/SettingsLib/res/values-hy/strings.xml
@@ -220,6 +220,7 @@
     <string name="debug_networking_category" msgid="7044075693643009662">"Ցանց"</string>
     <string name="wifi_display_certification" msgid="8611569543791307533">"Անլար էկրանների հավաստագրում"</string>
     <string name="wifi_verbose_logging" msgid="4203729756047242344">"Միացնել Wi‑Fi մանրամասն գրանցամատյանները"</string>
+    <string name="wifi_scan_throttling" msgid="160014287416479843">"Wi‑Fi-ի որոնման սահմանափակում"</string>
     <string name="mobile_data_always_on" msgid="8774857027458200434">"Բջջային ինտերնետը միշտ ակտիվ է"</string>
     <string name="tethering_hardware_offload" msgid="7470077827090325814">"Սարքակազմի արագացման միացում"</string>
     <string name="bluetooth_show_devices_without_names" msgid="4708446092962060176">"Ցուցադրել Bluetooth սարքերն առանց անունների"</string>
@@ -246,6 +247,7 @@
     <string name="private_dns_mode_provider_failure" msgid="231837290365031223">"Չհաջողվեց միանալ"</string>
     <string name="wifi_display_certification_summary" msgid="1155182309166746973">"Ցույց տալ անլար էկրանների հավաստագրման ընտրանքները"</string>
     <string name="wifi_verbose_logging_summary" msgid="6615071616111731958">"Բարձրացնել մակարդակը, Wi‑Fi ընտրիչում ամեն մի SSID-ի համար ցույց տալ RSSI"</string>
+    <string name="wifi_scan_throttling_summary" msgid="4461922728822495763">"Նվազեցնում է մարտկոցի սպառումը և լավացնում ցանցի աշխատանքը"</string>
     <string name="wifi_metered_label" msgid="4514924227256839725">"Վճարովի թրաֆիկ"</string>
     <string name="wifi_unmetered_label" msgid="6124098729457992931">"Անսահմանափակ թրաֆիկ"</string>
     <string name="select_logd_size_title" msgid="7433137108348553508">"Մատյանի բուֆերի չափերը"</string>
diff --git a/packages/SettingsLib/res/values-in/strings.xml b/packages/SettingsLib/res/values-in/strings.xml
index 4b4efb3..0684b3d 100644
--- a/packages/SettingsLib/res/values-in/strings.xml
+++ b/packages/SettingsLib/res/values-in/strings.xml
@@ -220,6 +220,7 @@
     <string name="debug_networking_category" msgid="7044075693643009662">"Jaringan"</string>
     <string name="wifi_display_certification" msgid="8611569543791307533">"Sertifikasi layar nirkabel"</string>
     <string name="wifi_verbose_logging" msgid="4203729756047242344">"Aktifkan Pencatatan Log Panjang Wi-Fi"</string>
+    <string name="wifi_scan_throttling" msgid="160014287416479843">"Pembatasan pemindaian Wi‑Fi"</string>
     <string name="mobile_data_always_on" msgid="8774857027458200434">"Kuota selalu aktif"</string>
     <string name="tethering_hardware_offload" msgid="7470077827090325814">"Akselerasi hardware tethering"</string>
     <string name="bluetooth_show_devices_without_names" msgid="4708446092962060176">"Tampilkan perangkat Bluetooth tanpa nama"</string>
@@ -246,6 +247,7 @@
     <string name="private_dns_mode_provider_failure" msgid="231837290365031223">"Tidak dapat terhubung"</string>
     <string name="wifi_display_certification_summary" msgid="1155182309166746973">"Tampilkan opsi untuk sertifikasi layar nirkabel"</string>
     <string name="wifi_verbose_logging_summary" msgid="6615071616111731958">"Tingkatkan level pencatatan log Wi-Fi, tampilkan per SSID RSSI di Pemilih Wi‑Fi"</string>
+    <string name="wifi_scan_throttling_summary" msgid="4461922728822495763">"Memperlambat kehabisan baterai &amp; meningkatkan performa jaringan"</string>
     <string name="wifi_metered_label" msgid="4514924227256839725">"Berbayar"</string>
     <string name="wifi_unmetered_label" msgid="6124098729457992931">"Tidak berbayar"</string>
     <string name="select_logd_size_title" msgid="7433137108348553508">"Ukuran buffer pencatat log"</string>
diff --git a/packages/SettingsLib/res/values-is/strings.xml b/packages/SettingsLib/res/values-is/strings.xml
index 8333a59..11d69571 100644
--- a/packages/SettingsLib/res/values-is/strings.xml
+++ b/packages/SettingsLib/res/values-is/strings.xml
@@ -220,6 +220,7 @@
     <string name="debug_networking_category" msgid="7044075693643009662">"Netkerfi"</string>
     <string name="wifi_display_certification" msgid="8611569543791307533">"Vottun þráðlausra skjáa"</string>
     <string name="wifi_verbose_logging" msgid="4203729756047242344">"Kveikja á ítarlegri skráningu Wi-Fi"</string>
+    <string name="wifi_scan_throttling" msgid="160014287416479843">"Hægja á Wi‑Fi leit"</string>
     <string name="mobile_data_always_on" msgid="8774857027458200434">"Alltaf kveikt á farsímagögnum"</string>
     <string name="tethering_hardware_offload" msgid="7470077827090325814">"Vélbúnaðarhröðun fyrir tjóðrun"</string>
     <string name="bluetooth_show_devices_without_names" msgid="4708446092962060176">"Sýna Bluetooth-tæki án heita"</string>
@@ -246,6 +247,7 @@
     <string name="private_dns_mode_provider_failure" msgid="231837290365031223">"Tenging mistókst"</string>
     <string name="wifi_display_certification_summary" msgid="1155182309166746973">"Sýna valkosti fyrir vottun þráðlausra skjáa"</string>
     <string name="wifi_verbose_logging_summary" msgid="6615071616111731958">"Auka skráningarstig Wi-Fi, sýna RSSI fyrir hvert SSID í Wi-Fi vali"</string>
+    <string name="wifi_scan_throttling_summary" msgid="4461922728822495763">"Dregur úr rafhlöðunotkun og eykur netafköst"</string>
     <string name="wifi_metered_label" msgid="4514924227256839725">"Mæld notkun"</string>
     <string name="wifi_unmetered_label" msgid="6124098729457992931">"Notkun ekki mæld"</string>
     <string name="select_logd_size_title" msgid="7433137108348553508">"Annálsritastærðir biðminna"</string>
diff --git a/packages/SettingsLib/res/values-it/strings.xml b/packages/SettingsLib/res/values-it/strings.xml
index 633b721..c5176b0 100644
--- a/packages/SettingsLib/res/values-it/strings.xml
+++ b/packages/SettingsLib/res/values-it/strings.xml
@@ -220,6 +220,7 @@
     <string name="debug_networking_category" msgid="7044075693643009662">"Reti"</string>
     <string name="wifi_display_certification" msgid="8611569543791307533">"Certificazione display wireless"</string>
     <string name="wifi_verbose_logging" msgid="4203729756047242344">"Attiva logging dettagliato Wi-Fi"</string>
+    <string name="wifi_scan_throttling" msgid="160014287416479843">"Limitazione della ricerca di reti Wi‑Fi"</string>
     <string name="mobile_data_always_on" msgid="8774857027458200434">"Dati mobili sempre attivi"</string>
     <string name="tethering_hardware_offload" msgid="7470077827090325814">"Tethering accelerazione hardware"</string>
     <string name="bluetooth_show_devices_without_names" msgid="4708446092962060176">"Mostra dispositivi Bluetooth senza nome"</string>
@@ -246,6 +247,7 @@
     <string name="private_dns_mode_provider_failure" msgid="231837290365031223">"Impossibile collegarsi"</string>
     <string name="wifi_display_certification_summary" msgid="1155182309166746973">"Mostra opzioni per la certificazione display wireless"</string>
     <string name="wifi_verbose_logging_summary" msgid="6615071616111731958">"Aumenta livello di logging Wi-Fi, mostra SSID RSSI nel selettore Wi-Fi"</string>
+    <string name="wifi_scan_throttling_summary" msgid="4461922728822495763">"Riduce il consumo della batteria e migliora le prestazioni della rete"</string>
     <string name="wifi_metered_label" msgid="4514924227256839725">"A consumo"</string>
     <string name="wifi_unmetered_label" msgid="6124098729457992931">"Non a consumo"</string>
     <string name="select_logd_size_title" msgid="7433137108348553508">"Dimensioni buffer logger"</string>
diff --git a/packages/SettingsLib/res/values-iw/strings.xml b/packages/SettingsLib/res/values-iw/strings.xml
index 9352479..ead0bfb 100644
--- a/packages/SettingsLib/res/values-iw/strings.xml
+++ b/packages/SettingsLib/res/values-iw/strings.xml
@@ -220,6 +220,7 @@
     <string name="debug_networking_category" msgid="7044075693643009662">"תקשורת רשתות"</string>
     <string name="wifi_display_certification" msgid="8611569543791307533">"‏אישור של תצוגת WiFi"</string>
     <string name="wifi_verbose_logging" msgid="4203729756047242344">"‏הפעלת רישום מפורט של Wi‑Fi ביומן"</string>
+    <string name="wifi_scan_throttling" msgid="160014287416479843">"‏ויסות סריקה לנקודות Wi-Fi"</string>
     <string name="mobile_data_always_on" msgid="8774857027458200434">"חבילת הגלישה פעילה תמיד"</string>
     <string name="tethering_hardware_offload" msgid="7470077827090325814">"שיפור מהירות באמצעות חומרה לצורך שיתוף אינטרנט בין ניידים"</string>
     <string name="bluetooth_show_devices_without_names" msgid="4708446092962060176">"‏הצגת מכשירי Bluetooth ללא שמות"</string>
@@ -246,6 +247,7 @@
     <string name="private_dns_mode_provider_failure" msgid="231837290365031223">"לא ניתן היה להתחבר"</string>
     <string name="wifi_display_certification_summary" msgid="1155182309166746973">"‏הצג אפשרויות עבור אישור של תצוגת WiFi"</string>
     <string name="wifi_verbose_logging_summary" msgid="6615071616111731958">"‏העלה את רמת הרישום של Wi‑Fi ביומן, הצג לכל SSID RSSI ב-Wi‑Fi Picker"</string>
+    <string name="wifi_scan_throttling_summary" msgid="4461922728822495763">"מפחית את קצב התרוקנות הסוללה ומשפר את ביצועי הרשת"</string>
     <string name="wifi_metered_label" msgid="4514924227256839725">"נמדדת"</string>
     <string name="wifi_unmetered_label" msgid="6124098729457992931">"לא נמדדת"</string>
     <string name="select_logd_size_title" msgid="7433137108348553508">"גדלי מאגר של יומן רישום"</string>
@@ -407,7 +409,7 @@
     <string name="battery_info_status_charging_lower" msgid="8689770213898117994">"בטעינה"</string>
     <string name="battery_info_status_discharging" msgid="310932812698268588">"לא בטעינה"</string>
     <string name="battery_info_status_not_charging" msgid="8523453668342598579">"המכשיר מחובר, אבל לא ניתן לטעון עכשיו"</string>
-    <string name="battery_info_status_full" msgid="2824614753861462808">"מלא"</string>
+    <string name="battery_info_status_full" msgid="2824614753861462808">"מלאה"</string>
     <string name="disabled_by_admin_summary_text" msgid="6750513964908334617">"נמצא בשליטת מנהל מערכת"</string>
     <string name="disabled" msgid="9206776641295849915">"מושבת"</string>
     <string name="external_source_trusted" msgid="2707996266575928037">"מורשה"</string>
diff --git a/packages/SettingsLib/res/values-ja/strings.xml b/packages/SettingsLib/res/values-ja/strings.xml
index b032aad..e5d29bf 100644
--- a/packages/SettingsLib/res/values-ja/strings.xml
+++ b/packages/SettingsLib/res/values-ja/strings.xml
@@ -220,6 +220,7 @@
     <string name="debug_networking_category" msgid="7044075693643009662">"ネットワーク"</string>
     <string name="wifi_display_certification" msgid="8611569543791307533">"ワイヤレスディスプレイ認証"</string>
     <string name="wifi_verbose_logging" msgid="4203729756047242344">"Wi-Fi詳細ログの有効化"</string>
+    <string name="wifi_scan_throttling" msgid="160014287416479843">"Wi‑Fi スキャン スロットリング"</string>
     <string name="mobile_data_always_on" msgid="8774857027458200434">"モバイルデータを常に ON にする"</string>
     <string name="tethering_hardware_offload" msgid="7470077827090325814">"テザリング時のハードウェア アクセラレーション"</string>
     <string name="bluetooth_show_devices_without_names" msgid="4708446092962060176">"Bluetooth デバイスを名前なしで表示"</string>
@@ -246,6 +247,7 @@
     <string name="private_dns_mode_provider_failure" msgid="231837290365031223">"接続できませんでした"</string>
     <string name="wifi_display_certification_summary" msgid="1155182309166746973">"ワイヤレスディスプレイ認証のオプションを表示"</string>
     <string name="wifi_verbose_logging_summary" msgid="6615071616111731958">"Wi-Fiログレベルを上げて、Wi-Fi選択ツールでSSID RSSIごとに表示します"</string>
+    <string name="wifi_scan_throttling_summary" msgid="4461922728822495763">"電池の消耗が軽減され、ネットワーク パフォーマンスが改善されます"</string>
     <string name="wifi_metered_label" msgid="4514924227256839725">"従量制"</string>
     <string name="wifi_unmetered_label" msgid="6124098729457992931">"定額制"</string>
     <string name="select_logd_size_title" msgid="7433137108348553508">"ログバッファのサイズ"</string>
diff --git a/packages/SettingsLib/res/values-ka/strings.xml b/packages/SettingsLib/res/values-ka/strings.xml
index 2c1d7c0..8b9b6b6 100644
--- a/packages/SettingsLib/res/values-ka/strings.xml
+++ b/packages/SettingsLib/res/values-ka/strings.xml
@@ -220,6 +220,7 @@
     <string name="debug_networking_category" msgid="7044075693643009662">"ქსელი"</string>
     <string name="wifi_display_certification" msgid="8611569543791307533">"უსადენო ეკრანის სერტიფიცირება"</string>
     <string name="wifi_verbose_logging" msgid="4203729756047242344">"Wi‑Fi-ს დაწვრილებითი აღრიცხვის ჩართვა"</string>
+    <string name="wifi_scan_throttling" msgid="160014287416479843">"Wi‑Fi სკანირების რეგულირება"</string>
     <string name="mobile_data_always_on" msgid="8774857027458200434">"მობილური ინტერნეტის ყოველთვის გააქტიურება"</string>
     <string name="tethering_hardware_offload" msgid="7470077827090325814">"ტეტერინგის აპარატურული აჩქარება"</string>
     <string name="bluetooth_show_devices_without_names" msgid="4708446092962060176">"Bluetooth-მოწყობილობების ჩვენება სახელების გარეშე"</string>
@@ -246,6 +247,7 @@
     <string name="private_dns_mode_provider_failure" msgid="231837290365031223">"დაკავშირება ვერ მოხერხდა"</string>
     <string name="wifi_display_certification_summary" msgid="1155182309166746973">"უსადენო ეკრანის სერტიფიცირების ვარიანტების ჩვენება"</string>
     <string name="wifi_verbose_logging_summary" msgid="6615071616111731958">"Wi‑Fi-ს აღრიცხვის დონის გაზრდა, Wi‑Fi ამომრჩეველში ყოველ SSID RSSI-ზე ჩვენება"</string>
+    <string name="wifi_scan_throttling_summary" msgid="4461922728822495763">"ამცირებს ბატარეის ხარჯვას და აუმჯობესებს ქსელის მუშაობას"</string>
     <string name="wifi_metered_label" msgid="4514924227256839725">"ლიმიტირებული"</string>
     <string name="wifi_unmetered_label" msgid="6124098729457992931">"არალიმიტირებული"</string>
     <string name="select_logd_size_title" msgid="7433137108348553508">"ჟურნალიზაციის ბუფერის ზომები"</string>
diff --git a/packages/SettingsLib/res/values-kk/strings.xml b/packages/SettingsLib/res/values-kk/strings.xml
index 5ae201e..1e57297 100644
--- a/packages/SettingsLib/res/values-kk/strings.xml
+++ b/packages/SettingsLib/res/values-kk/strings.xml
@@ -220,6 +220,7 @@
     <string name="debug_networking_category" msgid="7044075693643009662">"Желі орнату"</string>
     <string name="wifi_display_certification" msgid="8611569543791307533">"Сымсыз дисплей сертификаты"</string>
     <string name="wifi_verbose_logging" msgid="4203729756047242344">"Wi‑Fi егжей-тегжейлі журналы"</string>
+    <string name="wifi_scan_throttling" msgid="160014287416479843">"Wi‑Fi іздеуін шектеу"</string>
     <string name="mobile_data_always_on" msgid="8774857027458200434">"Мобильдік деректер әрқашан қосулы"</string>
     <string name="tethering_hardware_offload" msgid="7470077827090325814">"Тетеринг режиміндегі аппараттық жеделдету"</string>
     <string name="bluetooth_show_devices_without_names" msgid="4708446092962060176">"Bluetooth құрылғыларын атаусыз көрсету"</string>
@@ -246,6 +247,7 @@
     <string name="private_dns_mode_provider_failure" msgid="231837290365031223">"Қосылмады"</string>
     <string name="wifi_display_certification_summary" msgid="1155182309166746973">"Сымсыз дисплей сертификаты опцияларын көрсету"</string>
     <string name="wifi_verbose_logging_summary" msgid="6615071616111731958">"Wi‑Fi тіркеу деңгейін арттыру, Wi‑Fi таңдағанда әр SSID RSSI бойынша көрсету"</string>
+    <string name="wifi_scan_throttling_summary" msgid="4461922728822495763">"Батарея зарядының шығынын азайтады және желі жұмысын жақсартады."</string>
     <string name="wifi_metered_label" msgid="4514924227256839725">"Трафик саналады"</string>
     <string name="wifi_unmetered_label" msgid="6124098729457992931">"Трафик саналмайды"</string>
     <string name="select_logd_size_title" msgid="7433137108348553508">"Журналға тіркеуші буферінің өлшемдері"</string>
diff --git a/packages/SettingsLib/res/values-km/strings.xml b/packages/SettingsLib/res/values-km/strings.xml
index ed00b68..fb09c2f 100644
--- a/packages/SettingsLib/res/values-km/strings.xml
+++ b/packages/SettingsLib/res/values-km/strings.xml
@@ -220,6 +220,7 @@
     <string name="debug_networking_category" msgid="7044075693643009662">"ការភ្ជាប់បណ្ដាញ"</string>
     <string name="wifi_display_certification" msgid="8611569543791307533">"សេចក្តីបញ្ជាក់ការបង្ហាញ​ឥត​ខ្សែ"</string>
     <string name="wifi_verbose_logging" msgid="4203729756047242344">"បើក​កំណត់ហេតុ​រៀបរាប់​ Wi-Fi"</string>
+    <string name="wifi_scan_throttling" msgid="160014287416479843">"ការពន្យឺតការស្កេន Wi‑Fi"</string>
     <string name="mobile_data_always_on" msgid="8774857027458200434">"ទិន្នន័យទូរសព្ទចល័តដំណើរការជានិច្ច"</string>
     <string name="tethering_hardware_offload" msgid="7470077827090325814">"ការ​បង្កើនល្បឿន​ផ្នែករឹងសម្រាប់​ការភ្ជាប់"</string>
     <string name="bluetooth_show_devices_without_names" msgid="4708446092962060176">"បង្ហាញ​ឧបករណ៍​ប្ល៊ូធូស​គ្មានឈ្មោះ"</string>
@@ -246,6 +247,7 @@
     <string name="private_dns_mode_provider_failure" msgid="231837290365031223">"មិន​អាចភ្ជាប់​បានទេ"</string>
     <string name="wifi_display_certification_summary" msgid="1155182309166746973">"បង្ហាញ​ជម្រើស​សម្រាប់​សេចក្តីបញ្ជាក់ការបង្ហាញ​ឥត​ខ្សែ"</string>
     <string name="wifi_verbose_logging_summary" msgid="6615071616111731958">"បង្កើនកម្រិតកំណត់ហេតុ Wi-Fi បង្ហាញក្នុង SSID RSSI ក្នុងកម្មវិធីជ្រើសរើស Wi-Fi"</string>
+    <string name="wifi_scan_throttling_summary" msgid="4461922728822495763">"កាត់បន្ថយ​ការប្រើប្រាស់ថ្ម និងកែលម្អប្រតិបត្តិការ​បណ្ដាញ"</string>
     <string name="wifi_metered_label" msgid="4514924227256839725">"មានការកំណត់"</string>
     <string name="wifi_unmetered_label" msgid="6124098729457992931">"មិនមានការកំណត់"</string>
     <string name="select_logd_size_title" msgid="7433137108348553508">"ទំហំកន្លែងផ្ទុករបស់ logger"</string>
diff --git a/packages/SettingsLib/res/values-kn/strings.xml b/packages/SettingsLib/res/values-kn/strings.xml
index 59adfb7..97eed0f 100644
--- a/packages/SettingsLib/res/values-kn/strings.xml
+++ b/packages/SettingsLib/res/values-kn/strings.xml
@@ -220,6 +220,7 @@
     <string name="debug_networking_category" msgid="7044075693643009662">"ನೆಟ್‌ವರ್ಕಿಂಗ್"</string>
     <string name="wifi_display_certification" msgid="8611569543791307533">"ವೈರ್‌ಲೆಸ್ ಪ್ರದರ್ಶನ ಪ್ರಮಾಣೀಕರಣ"</string>
     <string name="wifi_verbose_logging" msgid="4203729756047242344">"Wi‑Fi ವೆರ್ಬೋಸ್ ಲಾಗಿಂಗ್ ಸಕ್ರಿಯಗೊಳಿಸಿ"</string>
+    <string name="wifi_scan_throttling" msgid="160014287416479843">"ವೈ-ಫೈ ಸ್ಕ್ಯಾನ್ ನಿರ್ಬಂಧಿಸಲಾಗುತ್ತಿದೆ"</string>
     <string name="mobile_data_always_on" msgid="8774857027458200434">"ಮೊಬೈಲ್ ಡೇಟಾ ಯಾವಾಗಲೂ ಸಕ್ರಿಯ"</string>
     <string name="tethering_hardware_offload" msgid="7470077827090325814">"ಟೆಥರಿಂಗ್‍‍ಗಾಗಿ ಹಾರ್ಡ್‍ವೇರ್ ವೇಗವರ್ಧನೆ"</string>
     <string name="bluetooth_show_devices_without_names" msgid="4708446092962060176">"ಹೆಸರುಗಳಿಲ್ಲದ ಬ್ಲೂಟೂತ್ ಸಾಧನಗಳನ್ನು ತೋರಿಸಿ"</string>
@@ -246,6 +247,7 @@
     <string name="private_dns_mode_provider_failure" msgid="231837290365031223">"ಸಂಪರ್ಕಿಸಲು ಸಾಧ್ಯವಾಗುತ್ತಿಲ್ಲ"</string>
     <string name="wifi_display_certification_summary" msgid="1155182309166746973">"ವೈರ್‌ಲೆಸ್‌‌‌ ಪ್ರದರ್ಶನ ಪ್ರಮಾಣೀಕರಣಕ್ಕಾಗಿ ಆಯ್ಕೆಗಳನ್ನು ತೋರಿಸು"</string>
     <string name="wifi_verbose_logging_summary" msgid="6615071616111731958">"Wi‑Fi ಲಾಗಿಂಗ್ ಮಟ್ಟನ್ನು ಹೆಚ್ಚಿಸಿ, Wi‑Fi ಆಯ್ಕೆಯಲ್ಲಿ ಪ್ರತಿಯೊಂದು SSID RSSI ತೋರಿಸಿ"</string>
+    <string name="wifi_scan_throttling_summary" msgid="4461922728822495763">"ಬ್ಯಾಟರಿ ಹೆಚ್ಚು ಬಾಳಿಕೆ ಬರುವಂತೆ ಮಾಡುತ್ತದೆ ಮತ್ತು ನೆಟ್‌ವರ್ಕ್‌ ಕಾರ್ಯಕ್ಷಮತೆಯನ್ನು ಸುಧಾರಿಸುತ್ತದೆ"</string>
     <string name="wifi_metered_label" msgid="4514924227256839725">"ಮೀಟರ್ ಮಾಡಲಾಗಿದೆ"</string>
     <string name="wifi_unmetered_label" msgid="6124098729457992931">"ಮೀಟರ್ ಮಾಡಲಾಗಿಲ್ಲ"</string>
     <string name="select_logd_size_title" msgid="7433137108348553508">"ಲಾಗರ್ ಬಫರ್ ಗಾತ್ರಗಳು"</string>
diff --git a/packages/SettingsLib/res/values-ko/strings.xml b/packages/SettingsLib/res/values-ko/strings.xml
index f195b33..abdfa04 100644
--- a/packages/SettingsLib/res/values-ko/strings.xml
+++ b/packages/SettingsLib/res/values-ko/strings.xml
@@ -220,6 +220,7 @@
     <string name="debug_networking_category" msgid="7044075693643009662">"네트워크"</string>
     <string name="wifi_display_certification" msgid="8611569543791307533">"무선 디스플레이 인증서"</string>
     <string name="wifi_verbose_logging" msgid="4203729756047242344">"Wi-Fi 상세 로깅 사용"</string>
+    <string name="wifi_scan_throttling" msgid="160014287416479843">"Wi‑Fi 검색 제한"</string>
     <string name="mobile_data_always_on" msgid="8774857027458200434">"항상 모바일 데이터 활성화"</string>
     <string name="tethering_hardware_offload" msgid="7470077827090325814">"테더링 하드웨어 가속"</string>
     <string name="bluetooth_show_devices_without_names" msgid="4708446092962060176">"이름이 없는 블루투스 기기 표시"</string>
@@ -246,6 +247,7 @@
     <string name="private_dns_mode_provider_failure" msgid="231837290365031223">"연결할 수 없음"</string>
     <string name="wifi_display_certification_summary" msgid="1155182309166746973">"무선 디스플레이 인증서 옵션 표시"</string>
     <string name="wifi_verbose_logging_summary" msgid="6615071616111731958">"Wi‑Fi 로깅 수준을 높이고, Wi‑Fi 선택도구에서 SSID RSSI당 값을 표시"</string>
+    <string name="wifi_scan_throttling_summary" msgid="4461922728822495763">"배터리 소모를 줄이고 네트워크 성능을 개선합니다."</string>
     <string name="wifi_metered_label" msgid="4514924227256839725">"종량제 네트워크"</string>
     <string name="wifi_unmetered_label" msgid="6124098729457992931">"무제한 네트워크"</string>
     <string name="select_logd_size_title" msgid="7433137108348553508">"로거 버퍼 크기"</string>
diff --git a/packages/SettingsLib/res/values-ky/strings.xml b/packages/SettingsLib/res/values-ky/strings.xml
index 187c0f7..435ce53 100644
--- a/packages/SettingsLib/res/values-ky/strings.xml
+++ b/packages/SettingsLib/res/values-ky/strings.xml
@@ -220,6 +220,7 @@
     <string name="debug_networking_category" msgid="7044075693643009662">"Тармактар"</string>
     <string name="wifi_display_certification" msgid="8611569543791307533">"Зымсыз мониторлорду тастыктамалоо"</string>
     <string name="wifi_verbose_logging" msgid="4203729756047242344">"Wi‑Fi дайын-даректүү журналы"</string>
+    <string name="wifi_scan_throttling" msgid="160014287416479843">"Wi‑Fi тармактарын издөөнү жөнгө салуу"</string>
     <string name="mobile_data_always_on" msgid="8774857027458200434">"Мобилдик Интернет иштей берет"</string>
     <string name="tethering_hardware_offload" msgid="7470077827090325814">"Модем режиминде аппараттын иштешин тездетүү"</string>
     <string name="bluetooth_show_devices_without_names" msgid="4708446092962060176">"Аталышсыз Bluetooth түзмөктөрү көрсөтүлсүн"</string>
@@ -246,6 +247,7 @@
     <string name="private_dns_mode_provider_failure" msgid="231837290365031223">"Туташпай койду"</string>
     <string name="wifi_display_certification_summary" msgid="1155182309166746973">"Зымсыз мониторлорду тастыктамалоо параметрлери көрүнүп турат"</string>
     <string name="wifi_verbose_logging_summary" msgid="6615071616111731958">"Wi-Fi тандалганда ар бир SSID үчүн RSSI көрүнүп турат"</string>
+    <string name="wifi_scan_throttling_summary" msgid="4461922728822495763">"Батареянын коротулушун чектеп, тармактын иштешин жакшыртат"</string>
     <string name="wifi_metered_label" msgid="4514924227256839725">"Трафик ченелет"</string>
     <string name="wifi_unmetered_label" msgid="6124098729457992931">"Чектелбеген тармак"</string>
     <string name="select_logd_size_title" msgid="7433137108348553508">"Журнал буферинин өлчөмү"</string>
diff --git a/packages/SettingsLib/res/values-lo/strings.xml b/packages/SettingsLib/res/values-lo/strings.xml
index 59ad7cc..ed88bc5 100644
--- a/packages/SettingsLib/res/values-lo/strings.xml
+++ b/packages/SettingsLib/res/values-lo/strings.xml
@@ -220,6 +220,7 @@
     <string name="debug_networking_category" msgid="7044075693643009662">"ການ​ສ້າງເຄືອຂ່າຍ"</string>
     <string name="wifi_display_certification" msgid="8611569543791307533">"ສະແດງການຮັບຮອງຂອງລະບົບໄຮ້ສາຍ"</string>
     <string name="wifi_verbose_logging" msgid="4203729756047242344">"​ເປີດ​ນຳ​ໃຊ້ການ​ເກັບ​ປະ​ຫວັດ​ Verbose Wi‑Fi"</string>
+    <string name="wifi_scan_throttling" msgid="160014287416479843">"ການຈຳກັດການສະແກນ Wi‑Fi"</string>
     <string name="mobile_data_always_on" msgid="8774857027458200434">"ເປີດໃຊ້ອິນເຕີເນັດມືຖືຕະຫຼອດເວລາ"</string>
     <string name="tethering_hardware_offload" msgid="7470077827090325814">"ເປີດໃຊ້ການເລັ່ງຄວາມໄວດ້ວຍຮາດແວ"</string>
     <string name="bluetooth_show_devices_without_names" msgid="4708446092962060176">"ສະແດງອຸປະກອນ Bluetooth ທີ່ບໍ່ມີຊື່"</string>
@@ -246,6 +247,7 @@
     <string name="private_dns_mode_provider_failure" msgid="231837290365031223">"ບໍ່ສາມາດເຊື່ອມຕໍ່ໄດ້"</string>
     <string name="wifi_display_certification_summary" msgid="1155182309166746973">"ສະແດງໂຕເລືອກສຳລັບການສະແດງການຮັບຮອງລະບົບໄຮ້ສາຍ"</string>
     <string name="wifi_verbose_logging_summary" msgid="6615071616111731958">"ເພີ່ມ​ລະ​ດັບ​ການ​ເກັບ​ປະ​ຫວັດ Wi‑Fi, ສະ​ແດງ​ຕໍ່ SSID RSSI ​ໃນ​ Wi‑Fi Picker"</string>
+    <string name="wifi_scan_throttling_summary" msgid="4461922728822495763">"ຫຼຸດການໃຊ້ແບັດເຕີຣີ ແລະ ປັບປຸງປະສິດທິພາບເຄືອຂ່າຍ"</string>
     <string name="wifi_metered_label" msgid="4514924227256839725">"ມີການວັດແທກ"</string>
     <string name="wifi_unmetered_label" msgid="6124098729457992931">"ບໍ່ໄດ້ວັດແທກ"</string>
     <string name="select_logd_size_title" msgid="7433137108348553508">"ຂະໜາດບັບເຟີຕົວບັນທຶກ"</string>
diff --git a/packages/SettingsLib/res/values-lt/strings.xml b/packages/SettingsLib/res/values-lt/strings.xml
index bde71e3..c10bd00 100644
--- a/packages/SettingsLib/res/values-lt/strings.xml
+++ b/packages/SettingsLib/res/values-lt/strings.xml
@@ -220,6 +220,7 @@
     <string name="debug_networking_category" msgid="7044075693643009662">"Tinklai"</string>
     <string name="wifi_display_certification" msgid="8611569543791307533">"Belaidžio rodymo sertifikavimas"</string>
     <string name="wifi_verbose_logging" msgid="4203729756047242344">"Įgal. „Wi‑Fi“ daugiaž. įraš. į žurnalą"</string>
+    <string name="wifi_scan_throttling" msgid="160014287416479843">"„Wi‑Fi“ nuskaitymo ribojimas"</string>
     <string name="mobile_data_always_on" msgid="8774857027458200434">"Mobiliojo ryšio duomenys visada suaktyvinti"</string>
     <string name="tethering_hardware_offload" msgid="7470077827090325814">"Įrenginio kaip modemo naudojimo aparatinės įrangos spartinimas"</string>
     <string name="bluetooth_show_devices_without_names" msgid="4708446092962060176">"Rodyti „Bluetooth“ įrenginius be pavadinimų"</string>
@@ -246,6 +247,7 @@
     <string name="private_dns_mode_provider_failure" msgid="231837290365031223">"Prisijungti nepavyko"</string>
     <string name="wifi_display_certification_summary" msgid="1155182309166746973">"Rodyti belaidžio rodymo sertifikavimo parinktis"</string>
     <string name="wifi_verbose_logging_summary" msgid="6615071616111731958">"Padidinti „Wi‑Fi“ įrašymo į žurnalą lygį, rodyti SSID RSSI „Wi-Fi“ rinkiklyje"</string>
+    <string name="wifi_scan_throttling_summary" msgid="4461922728822495763">"Sumažinamas akumuliatoriaus eikvojimas ir patobulinamas tinklo našumas"</string>
     <string name="wifi_metered_label" msgid="4514924227256839725">"Matuojamas"</string>
     <string name="wifi_unmetered_label" msgid="6124098729457992931">"Neišmatuotas"</string>
     <string name="select_logd_size_title" msgid="7433137108348553508">"Registruotuvo buferio dydžiai"</string>
diff --git a/packages/SettingsLib/res/values-lv/strings.xml b/packages/SettingsLib/res/values-lv/strings.xml
index 5a1805a..8feb5ab 100644
--- a/packages/SettingsLib/res/values-lv/strings.xml
+++ b/packages/SettingsLib/res/values-lv/strings.xml
@@ -220,6 +220,7 @@
     <string name="debug_networking_category" msgid="7044075693643009662">"Tīklošana"</string>
     <string name="wifi_display_certification" msgid="8611569543791307533">"Bezvadu attēlošanas sertifikācija"</string>
     <string name="wifi_verbose_logging" msgid="4203729756047242344">"Iespējot Wi‑Fi detalizēto reģistrēšanu"</string>
+    <string name="wifi_scan_throttling" msgid="160014287416479843">"Wi‑Fi meklēšanas ierobežošana"</string>
     <string name="mobile_data_always_on" msgid="8774857027458200434">"Vienmēr aktīvs mobilo datu savienojums"</string>
     <string name="tethering_hardware_offload" msgid="7470077827090325814">"Paātrināta aparatūras darbība piesaistei"</string>
     <string name="bluetooth_show_devices_without_names" msgid="4708446092962060176">"Rādīt Bluetooth ierīces bez nosaukumiem"</string>
@@ -246,6 +247,7 @@
     <string name="private_dns_mode_provider_failure" msgid="231837290365031223">"Nevarēja izveidot savienojumu."</string>
     <string name="wifi_display_certification_summary" msgid="1155182309166746973">"Rādīt bezvadu attēlošanas sertifikācijas iespējas"</string>
     <string name="wifi_verbose_logging_summary" msgid="6615071616111731958">"Palieliniet Wi‑Fi reģistrēšanas līmeni; rādīt katram SSID RSSI Wi‑Fi atlasītājā."</string>
+    <string name="wifi_scan_throttling_summary" msgid="4461922728822495763">"Samazina akumulatora izlādi un uzlabo tīkla veiktspēju"</string>
     <string name="wifi_metered_label" msgid="4514924227256839725">"Maksas"</string>
     <string name="wifi_unmetered_label" msgid="6124098729457992931">"Bezmaksas"</string>
     <string name="select_logd_size_title" msgid="7433137108348553508">"Reģistrētāja buferu lielumi"</string>
diff --git a/packages/SettingsLib/res/values-mk/strings.xml b/packages/SettingsLib/res/values-mk/strings.xml
index 5be177d..8bed22f 100644
--- a/packages/SettingsLib/res/values-mk/strings.xml
+++ b/packages/SettingsLib/res/values-mk/strings.xml
@@ -220,6 +220,7 @@
     <string name="debug_networking_category" msgid="7044075693643009662">"Вмрежување"</string>
     <string name="wifi_display_certification" msgid="8611569543791307533">"Приказ на сертификација на безжична мрежа"</string>
     <string name="wifi_verbose_logging" msgid="4203729756047242344">"Овозможи преопширно пријавување Wi‑Fi"</string>
+    <string name="wifi_scan_throttling" msgid="160014287416479843">"Регулирање на скенирањето за Wi‑Fi"</string>
     <string name="mobile_data_always_on" msgid="8774857027458200434">"Мобилниот интернет е секогаш активен"</string>
     <string name="tethering_hardware_offload" msgid="7470077827090325814">"Хардверско забрзување за врзување"</string>
     <string name="bluetooth_show_devices_without_names" msgid="4708446092962060176">"Прикажувај уреди со Bluetooth без имиња"</string>
@@ -246,6 +247,7 @@
     <string name="private_dns_mode_provider_failure" msgid="231837290365031223">"Не може да се поврзе"</string>
     <string name="wifi_display_certification_summary" msgid="1155182309166746973">"Покажи ги опциите за безжичен приказ на сертификат"</string>
     <string name="wifi_verbose_logging_summary" msgid="6615071616111731958">"Зголеми Wi‑Fi ниво на пријавување, прикажи по SSID RSSI во Wi‑Fi бирач"</string>
+    <string name="wifi_scan_throttling_summary" msgid="4461922728822495763">"Го намалува искористувањето на батеријата и ја подобрува изведбата на мрежата"</string>
     <string name="wifi_metered_label" msgid="4514924227256839725">"Со ограничен интернет"</string>
     <string name="wifi_unmetered_label" msgid="6124098729457992931">"Без ограничен интернет"</string>
     <string name="select_logd_size_title" msgid="7433137108348553508">"Величини на меѓумеморија за дневникот"</string>
diff --git a/packages/SettingsLib/res/values-ml/strings.xml b/packages/SettingsLib/res/values-ml/strings.xml
index d3ebd99..7016b7f 100644
--- a/packages/SettingsLib/res/values-ml/strings.xml
+++ b/packages/SettingsLib/res/values-ml/strings.xml
@@ -220,6 +220,7 @@
     <string name="debug_networking_category" msgid="7044075693643009662">"നെറ്റ്‍വര്‍ക്കിംഗ്"</string>
     <string name="wifi_display_certification" msgid="8611569543791307533">"വയർലെസ് ഡിസ്‌പ്ലേ സർട്ടിഫിക്കേഷൻ"</string>
     <string name="wifi_verbose_logging" msgid="4203729756047242344">"വൈഫൈ വെർബോസ് ലോഗിംഗ് പ്രവർത്തനക്ഷമമാക്കുക"</string>
+    <string name="wifi_scan_throttling" msgid="160014287416479843">"വൈഫൈ സ്‌കാൻ പ്രവർത്തനരഹിതമാക്കുന്നു"</string>
     <string name="mobile_data_always_on" msgid="8774857027458200434">"മൊബൈൽ ഡാറ്റ എല്ലായ്‌പ്പോഴും സജീവം"</string>
     <string name="tethering_hardware_offload" msgid="7470077827090325814">"ടെതറിംഗ് ഹാർഡ്‌വെയർ ത്വരിതപ്പെടുത്തൽ"</string>
     <string name="bluetooth_show_devices_without_names" msgid="4708446092962060176">"പേരില്ലാത്ത Bluetooth ഉപകരണങ്ങൾ കാണിക്കുക"</string>
@@ -246,6 +247,7 @@
     <string name="private_dns_mode_provider_failure" msgid="231837290365031223">"കണക്റ്റ് ചെയ്യാനായില്ല"</string>
     <string name="wifi_display_certification_summary" msgid="1155182309166746973">"വയർലെസ് ഡിസ്‌പ്ലേ സർട്ടിഫിക്കേഷനായി ഓപ്‌ഷനുകൾ ദൃശ്യമാക്കുക"</string>
     <string name="wifi_verbose_logging_summary" msgid="6615071616111731958">"വൈഫൈ പിക്കറിൽ ഓരോ SSID RSSI പ്രകാരം കാണിക്കാൻ വൈഫൈ ലോഗിംഗ് നില വർദ്ധിപ്പിക്കുക"</string>
+    <string name="wifi_scan_throttling_summary" msgid="4461922728822495763">"ബാറ്ററി ചാർജ് വേഗത്തിൽ തീരുന്ന അവസ്ഥ കുറച്ച് നെറ്റ്‌വർക്ക് പ്രകടനം മെച്ചപ്പെടുത്തുന്നു"</string>
     <string name="wifi_metered_label" msgid="4514924227256839725">"മീറ്റർചെയ്ത"</string>
     <string name="wifi_unmetered_label" msgid="6124098729457992931">"മീറ്റർമാപകമല്ലാത്തത്"</string>
     <string name="select_logd_size_title" msgid="7433137108348553508">"ലോഗർ ബഫർ വലുപ്പം"</string>
diff --git a/packages/SettingsLib/res/values-mn/strings.xml b/packages/SettingsLib/res/values-mn/strings.xml
index 46029c7..80e78a3 100644
--- a/packages/SettingsLib/res/values-mn/strings.xml
+++ b/packages/SettingsLib/res/values-mn/strings.xml
@@ -220,6 +220,7 @@
     <string name="debug_networking_category" msgid="7044075693643009662">"Сүлжээ"</string>
     <string name="wifi_display_certification" msgid="8611569543791307533">"Утасгүй дэлгэцийн сертификат"</string>
     <string name="wifi_verbose_logging" msgid="4203729756047242344">"Wi‑Fi дэлгэрэнгүй лог-г идэвхжүүлэх"</string>
+    <string name="wifi_scan_throttling" msgid="160014287416479843">"Wi‑Fi скан бууруулалт"</string>
     <string name="mobile_data_always_on" msgid="8774857027458200434">"Мобайл дата байнга идэвхтэй"</string>
     <string name="tethering_hardware_offload" msgid="7470077827090325814">"Модем болгох техник хангамжийн хурдасгуур"</string>
     <string name="bluetooth_show_devices_without_names" msgid="4708446092962060176">"Нэргүй Bluetooth төхөөрөмжийг харуулах"</string>
@@ -246,6 +247,7 @@
     <string name="private_dns_mode_provider_failure" msgid="231837290365031223">"Холбогдож чадсангүй"</string>
     <string name="wifi_display_certification_summary" msgid="1155182309166746973">"Утасгүй дэлгэцийн сертификатын сонголтыг харуулах"</string>
     <string name="wifi_verbose_logging_summary" msgid="6615071616111731958">"Wi‑Fi лог-н түвшинг нэмэгдүүлэх, Wi‑Fi Сонгогч дээрх SSID-д ногдох RSSI-г харуулах"</string>
+    <string name="wifi_scan_throttling_summary" msgid="4461922728822495763">"Батарей зарцуулалтыг бууруулж, сүлжээний гүйцэтгэлийг сайжруулдаг"</string>
     <string name="wifi_metered_label" msgid="4514924227256839725">"Хязгаартай"</string>
     <string name="wifi_unmetered_label" msgid="6124098729457992931">"Хязгааргүй"</string>
     <string name="select_logd_size_title" msgid="7433137108348553508">"Логгерын буферын хэмжээ"</string>
diff --git a/packages/SettingsLib/res/values-mr/strings.xml b/packages/SettingsLib/res/values-mr/strings.xml
index 5f6acf1..367b13d 100644
--- a/packages/SettingsLib/res/values-mr/strings.xml
+++ b/packages/SettingsLib/res/values-mr/strings.xml
@@ -78,7 +78,7 @@
     <string name="bluetooth_active_battery_level_untethered" msgid="6662649951391456747">"अॅक्टिव्ह, L: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE_0">%1$s</xliff:g> बॅटरी, R: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE_1">%2$s</xliff:g> बॅटरी"</string>
     <string name="bluetooth_battery_level" msgid="1447164613319663655">"<xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g> बॅटरी"</string>
     <string name="bluetooth_battery_level_untethered" msgid="5974406100211667177">"L: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE_0">%1$s</xliff:g> बॅटरी, R: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE_1">%2$s</xliff:g> बॅटरी"</string>
-    <string name="bluetooth_active_no_battery_level" msgid="8380223546730241956">"अॅक्टिव्ह"</string>
+    <string name="bluetooth_active_no_battery_level" msgid="8380223546730241956">"अ‍ॅक्टिव्ह"</string>
     <string name="bluetooth_profile_a2dp" msgid="2031475486179830674">"मीडिया ऑडिओ"</string>
     <string name="bluetooth_profile_headset" msgid="7815495680863246034">"फोन कॉल"</string>
     <string name="bluetooth_profile_opp" msgid="9168139293654233697">"फाइल स्थानांतरण"</string>
@@ -220,6 +220,7 @@
     <string name="debug_networking_category" msgid="7044075693643009662">"नेटवर्किंग"</string>
     <string name="wifi_display_certification" msgid="8611569543791307533">"वायरलेस डिस्प्ले प्रमाणीकरण"</string>
     <string name="wifi_verbose_logging" msgid="4203729756047242344">"वाय-फाय व्हर्बोझ लॉगिंग सुरू करा"</string>
+    <string name="wifi_scan_throttling" msgid="160014287416479843">"वाय-फाय स्कॅन थ्रॉटलिंग"</string>
     <string name="mobile_data_always_on" msgid="8774857027458200434">"मोबाइल डेटा नेहमी सक्रिय"</string>
     <string name="tethering_hardware_offload" msgid="7470077827090325814">"टेदरिंग हार्डवेअर प्रवेग"</string>
     <string name="bluetooth_show_devices_without_names" msgid="4708446092962060176">"नावांशिवाय ब्‍लूटूथ डिव्‍हाइस दाखवा"</string>
@@ -246,6 +247,7 @@
     <string name="private_dns_mode_provider_failure" msgid="231837290365031223">"कनेक्ट करू शकलो नाही"</string>
     <string name="wifi_display_certification_summary" msgid="1155182309166746973">"वायरलेस डिस्प्ले प्रमाणिकरणाचे पर्याय दाखवा"</string>
     <string name="wifi_verbose_logging_summary" msgid="6615071616111731958">"वाय-फाय लॉगिंग स्‍तर वाढवा, वाय-फाय सिलेक्टरमध्‍ये प्रति SSID RSSI दर्शवा"</string>
+    <string name="wifi_scan_throttling_summary" msgid="4461922728822495763">"बॅटरी जलदरीतीने संपण्यापासून रोखते आणि नेटवर्क परफॉर्मन्समध्ये सुधारणा करते"</string>
     <string name="wifi_metered_label" msgid="4514924227256839725">"मीटरने मोजलेले"</string>
     <string name="wifi_unmetered_label" msgid="6124098729457992931">"मीटरने न मोजलेले"</string>
     <string name="select_logd_size_title" msgid="7433137108348553508">"लॉगर बफर आकार"</string>
diff --git a/packages/SettingsLib/res/values-ms/strings.xml b/packages/SettingsLib/res/values-ms/strings.xml
index 03ff0bb..3841a3b 100644
--- a/packages/SettingsLib/res/values-ms/strings.xml
+++ b/packages/SettingsLib/res/values-ms/strings.xml
@@ -220,6 +220,7 @@
     <string name="debug_networking_category" msgid="7044075693643009662">"Perangkaian"</string>
     <string name="wifi_display_certification" msgid="8611569543791307533">"Pensijilan paparan wayarles"</string>
     <string name="wifi_verbose_logging" msgid="4203729756047242344">"Dayakan Pengelogan Berjela-jela Wi-Fi"</string>
+    <string name="wifi_scan_throttling" msgid="160014287416479843">"Pendikitan pengimbasan Wi-Fi"</string>
     <string name="mobile_data_always_on" msgid="8774857027458200434">"Data mudah alih sentiasa aktif"</string>
     <string name="tethering_hardware_offload" msgid="7470077827090325814">"Pecutan perkakasan penambatan"</string>
     <string name="bluetooth_show_devices_without_names" msgid="4708446092962060176">"Tunjukkan peranti Bluetooth tanpa nama"</string>
@@ -246,6 +247,7 @@
     <string name="private_dns_mode_provider_failure" msgid="231837290365031223">"Tidak dapat menyambung"</string>
     <string name="wifi_display_certification_summary" msgid="1155182309166746973">"Tunjukkan pilihan untuk pensijilan paparan wayarles"</string>
     <string name="wifi_verbose_logging_summary" msgid="6615071616111731958">"Tingkatkan tahap pengelogan Wi-Fi, tunjuk setiap SSID RSSI dalam Pemilih Wi-Fi"</string>
+    <string name="wifi_scan_throttling_summary" msgid="4461922728822495763">"Mengurangkan penyusutan bateri &amp; meningkatkan prestasi rangkaian"</string>
     <string name="wifi_metered_label" msgid="4514924227256839725">"Bermeter"</string>
     <string name="wifi_unmetered_label" msgid="6124098729457992931">"Tidak bermeter"</string>
     <string name="select_logd_size_title" msgid="7433137108348553508">"Saiz penimbal pengelog"</string>
diff --git a/packages/SettingsLib/res/values-my/strings.xml b/packages/SettingsLib/res/values-my/strings.xml
index 1db26b4..38f128a 100644
--- a/packages/SettingsLib/res/values-my/strings.xml
+++ b/packages/SettingsLib/res/values-my/strings.xml
@@ -153,7 +153,7 @@
     <string name="launch_defaults_some" msgid="313159469856372621">"မူရင်းအချို့ သတ်မှတ်ပြီး"</string>
     <string name="launch_defaults_none" msgid="4241129108140034876">"ပုံမှန်သတ်မှတ်ထားခြင်းမရှိ"</string>
     <string name="tts_settings" msgid="8186971894801348327">"စာသားမှစကားပြောပြောင်း ဆက်တင်များ"</string>
-    <string name="tts_settings_title" msgid="1237820681016639683">"စာသားမှ အသံထွက်စေခြင်း"</string>
+    <string name="tts_settings_title" msgid="1237820681016639683">"စာသားမှ စကားပြောသို့ အထွက်"</string>
     <string name="tts_default_rate_title" msgid="6030550998379310088">"စကားပြောနှုန်း"</string>
     <string name="tts_default_rate_summary" msgid="4061815292287182801">"စာတမ်းအားပြောဆိုသော အမြန်နှုန်း"</string>
     <string name="tts_default_pitch_title" msgid="6135942113172488671">"အသံအနိမ့်အမြင့်"</string>
@@ -220,6 +220,7 @@
     <string name="debug_networking_category" msgid="7044075693643009662">"ချိတ်ဆက်ဆောင်ရွက်ခြင်း"</string>
     <string name="wifi_display_certification" msgid="8611569543791307533">"ကြိုးမဲ့ပြသမှု အသိအမှတ်ပြုလက်မှတ်"</string>
     <string name="wifi_verbose_logging" msgid="4203729756047242344">"Wi‑Fi Verbose မှတ်တမ်းတင်ခြင်းအား ဖွင့်မည်"</string>
+    <string name="wifi_scan_throttling" msgid="160014287416479843">"Wi‑Fi ရှာဖွေခြင်း ထိန်းချုပ်မှု"</string>
     <string name="mobile_data_always_on" msgid="8774857027458200434">"မိုဘိုင်းဒေတာကို အမြဲဖွင့်ထားရန်"</string>
     <string name="tethering_hardware_offload" msgid="7470077827090325814">"ဖုန်းကို မိုဒမ်အဖြစ်အသုံးပြုမှု စက်ပစ္စည်းဖြင့် အရှိန်မြှင့်တင်ခြင်း"</string>
     <string name="bluetooth_show_devices_without_names" msgid="4708446092962060176">"အမည်မရှိသော ဘလူးတုသ်စက်ပစ္စည်းများကို ပြသရန်"</string>
@@ -246,6 +247,7 @@
     <string name="private_dns_mode_provider_failure" msgid="231837290365031223">"ချိတ်ဆက်၍ မရပါ"</string>
     <string name="wifi_display_certification_summary" msgid="1155182309166746973">"ကြိုးမဲ့ အခင်းအကျင်း အသိအမှတ်ပြုလက်မှတ်အတွက် ရွေးချယ်စရာများပြရန်"</string>
     <string name="wifi_verbose_logging_summary" msgid="6615071616111731958">"Wi‑Fi မှတ်တမ်းတင်ခြင်း နှုန်းအားမြင့်ကာ၊ Wi‑Fi ရွေးရာတွင် SSID RSSI ဖြင့်ပြပါ"</string>
+    <string name="wifi_scan_throttling_summary" msgid="4461922728822495763">"ဘက်ထရီ အသုံးပြုမှုကို လျှော့ကျစေပြီး ကွန်ရက်စွမ်းဆောင်ရည်ကို ပိုမိုကောင်းမွန်စေသည်"</string>
     <string name="wifi_metered_label" msgid="4514924227256839725">"အခမဲ့ မဟုတ်ပါ"</string>
     <string name="wifi_unmetered_label" msgid="6124098729457992931">"အခမဲ့"</string>
     <string name="select_logd_size_title" msgid="7433137108348553508">"မှတ်တမ်းကြားခံနယ် အရွယ်အစားများ"</string>
diff --git a/packages/SettingsLib/res/values-nb/strings.xml b/packages/SettingsLib/res/values-nb/strings.xml
index abb3410..144d4c2 100644
--- a/packages/SettingsLib/res/values-nb/strings.xml
+++ b/packages/SettingsLib/res/values-nb/strings.xml
@@ -220,6 +220,7 @@
     <string name="debug_networking_category" msgid="7044075693643009662">"Nettverk"</string>
     <string name="wifi_display_certification" msgid="8611569543791307533">"Trådløs skjermsertifisering"</string>
     <string name="wifi_verbose_logging" msgid="4203729756047242344">"Slå på detaljert Wi-Fi-loggføring"</string>
+    <string name="wifi_scan_throttling" msgid="160014287416479843">"Begrensning av Wi‑Fi-skanning"</string>
     <string name="mobile_data_always_on" msgid="8774857027458200434">"Mobildata er alltid aktiv"</string>
     <string name="tethering_hardware_offload" msgid="7470077827090325814">"Maskinvareakselerasjon for internettdeling"</string>
     <string name="bluetooth_show_devices_without_names" msgid="4708446092962060176">"Vis Bluetooth-enheter uten navn"</string>
@@ -246,6 +247,7 @@
     <string name="private_dns_mode_provider_failure" msgid="231837290365031223">"Kunne ikke koble til"</string>
     <string name="wifi_display_certification_summary" msgid="1155182309166746973">"Vis alternativer for sertifisering av trådløs skjerm"</string>
     <string name="wifi_verbose_logging_summary" msgid="6615071616111731958">"Øk Wi-Fi-loggenivå – vis per SSID RSSI i Wi-Fi-velgeren"</string>
+    <string name="wifi_scan_throttling_summary" msgid="4461922728822495763">"Reduserer batteriforbruket og forbedrer nettverksytelsen"</string>
     <string name="wifi_metered_label" msgid="4514924227256839725">"Med datamåling"</string>
     <string name="wifi_unmetered_label" msgid="6124098729457992931">"Uten datamåling"</string>
     <string name="select_logd_size_title" msgid="7433137108348553508">"Bufferstørrelser for logg"</string>
diff --git a/packages/SettingsLib/res/values-ne/strings.xml b/packages/SettingsLib/res/values-ne/strings.xml
index 7d71fdc..fd45cb0 100644
--- a/packages/SettingsLib/res/values-ne/strings.xml
+++ b/packages/SettingsLib/res/values-ne/strings.xml
@@ -220,6 +220,7 @@
     <string name="debug_networking_category" msgid="7044075693643009662">"नेटवर्किङ"</string>
     <string name="wifi_display_certification" msgid="8611569543791307533">"ताररहित प्रदर्शन प्रमाणीकरण"</string>
     <string name="wifi_verbose_logging" msgid="4203729756047242344">"Wi-Fi वर्बोज लग सक्षम पार्नुहोस्"</string>
+    <string name="wifi_scan_throttling" msgid="160014287416479843">"Wi‑Fi स्क्यान थ्रोटलिङ"</string>
     <string name="mobile_data_always_on" msgid="8774857027458200434">"मोबाइल डेटा सधैँ सक्रिय राख्नुहोस्"</string>
     <string name="tethering_hardware_offload" msgid="7470077827090325814">"टेदरिङको लागि हार्डवेयरको प्रवेग"</string>
     <string name="bluetooth_show_devices_without_names" msgid="4708446092962060176">"नामकरण नगरिएका ब्लुटुथ यन्त्रहरू देखाउनुहोस्"</string>
@@ -246,6 +247,7 @@
     <string name="private_dns_mode_provider_failure" msgid="231837290365031223">"जडान गर्न सकिएन"</string>
     <string name="wifi_display_certification_summary" msgid="1155182309166746973">"ताररहित प्रदर्शन प्रमाणीकरणका लागि विकल्पहरू देखाउनुहोस्"</string>
     <string name="wifi_verbose_logging_summary" msgid="6615071616111731958">"Wi-Fi लग स्तर बढाउनुहोस्, Wi-Fi चयनकर्तामा प्रति SSID RSSI देखाइन्छ"</string>
+    <string name="wifi_scan_throttling_summary" msgid="4461922728822495763">"ब्याट्रीको खपत कम गरी नेटवर्कको कार्यसम्पादनमा सुधार गर्दछ"</string>
     <string name="wifi_metered_label" msgid="4514924227256839725">"मिटर गरिएको जडान भनी चिन्ह लगाइएको"</string>
     <string name="wifi_unmetered_label" msgid="6124098729457992931">"मिटर नगरिएको"</string>
     <string name="select_logd_size_title" msgid="7433137108348553508">"लगर बफर आकारहरू"</string>
diff --git a/packages/SettingsLib/res/values-nl/strings.xml b/packages/SettingsLib/res/values-nl/strings.xml
index 6771da1..c50b43a 100644
--- a/packages/SettingsLib/res/values-nl/strings.xml
+++ b/packages/SettingsLib/res/values-nl/strings.xml
@@ -220,6 +220,7 @@
     <string name="debug_networking_category" msgid="7044075693643009662">"Netwerken"</string>
     <string name="wifi_display_certification" msgid="8611569543791307533">"Certificering van draadloze weergave"</string>
     <string name="wifi_verbose_logging" msgid="4203729756047242344">"Uitgebreide wifi-logregistratie insch."</string>
+    <string name="wifi_scan_throttling" msgid="160014287416479843">"Wifi-scannen beperken"</string>
     <string name="mobile_data_always_on" msgid="8774857027458200434">"Mobiele data altijd actief"</string>
     <string name="tethering_hardware_offload" msgid="7470077827090325814">"Hardwareversnelling voor tethering"</string>
     <string name="bluetooth_show_devices_without_names" msgid="4708446092962060176">"Bluetooth-apparaten zonder namen weergeven"</string>
@@ -246,6 +247,7 @@
     <string name="private_dns_mode_provider_failure" msgid="231837290365031223">"Kan geen verbinding maken"</string>
     <string name="wifi_display_certification_summary" msgid="1155182309166746973">"Opties weergeven voor certificering van draadloze weergave"</string>
     <string name="wifi_verbose_logging_summary" msgid="6615071616111731958">"Logniveau voor wifi verhogen, weergeven per SSID RSSI in wifi-kiezer"</string>
+    <string name="wifi_scan_throttling_summary" msgid="4461922728822495763">"Verlaagt het batterijverbruik en verbetert de netwerkprestaties"</string>
     <string name="wifi_metered_label" msgid="4514924227256839725">"Met datalimiet"</string>
     <string name="wifi_unmetered_label" msgid="6124098729457992931">"Gratis"</string>
     <string name="select_logd_size_title" msgid="7433137108348553508">"Logger-buffergrootten"</string>
diff --git a/packages/SettingsLib/res/values-or/strings.xml b/packages/SettingsLib/res/values-or/strings.xml
index c4e554b..648cc4a 100644
--- a/packages/SettingsLib/res/values-or/strings.xml
+++ b/packages/SettingsLib/res/values-or/strings.xml
@@ -220,6 +220,7 @@
     <string name="debug_networking_category" msgid="7044075693643009662">"ନେଟ୍‌ୱର୍କିଙ୍ଗ"</string>
     <string name="wifi_display_certification" msgid="8611569543791307533">"ୱାୟରଲେସ୍‌ ଡିସ୍‌ପ୍ଲେ ସାର୍ଟିଫିକେସନ୍"</string>
     <string name="wifi_verbose_logging" msgid="4203729756047242344">"ୱାଇ-ଫାଇ ଭର୍ବୋସ୍‌ ଲଗିଙ୍ଗ ସକ୍ଷମ କରନ୍ତୁ"</string>
+    <string name="wifi_scan_throttling" msgid="160014287416479843">"ୱାଇ-ଫାଇ ସ୍କାନ୍ ନିୟନ୍ତ୍ରଣ"</string>
     <string name="mobile_data_always_on" msgid="8774857027458200434">"ମୋବାଇଲ୍‌ ଡାଟା ସର୍ବଦା ସକ୍ରିୟ"</string>
     <string name="tethering_hardware_offload" msgid="7470077827090325814">"ଟିଥରିଙ୍ଗ ହାର୍ଡୱେର ଆକ୍ସିଲିରେସନ୍"</string>
     <string name="bluetooth_show_devices_without_names" msgid="4708446092962060176">"ବ୍ଲୁଟୂଥ୍‍‌ ଡିଭାଇସ୍‌ଗୁଡ଼ିକୁ ନାମ ବିନା ଦେଖନ୍ତୁ"</string>
@@ -246,6 +247,7 @@
     <string name="private_dns_mode_provider_failure" msgid="231837290365031223">"କନେକ୍ଟ କରିହେଲା ନାହିଁ"</string>
     <string name="wifi_display_certification_summary" msgid="1155182309166746973">"ୱେୟାରଲେସ୍‌ ଡିସ୍‌ପ୍ଲେ ସାର୍ଟିଫିକେସନ୍ ପାଇଁ ବିକଳ୍ପ ଦେଖାନ୍ତୁ"</string>
     <string name="wifi_verbose_logging_summary" msgid="6615071616111731958">"ୱାଇ-ଫାଇ ଲଗିଙ୍ଗ ସ୍ତର ବଢ଼ାନ୍ତୁ, ୱାଇ-ଫାଇ ପିକର୍‌ରେ ପ୍ରତି SSID RSSI ଦେଖାନ୍ତୁ"</string>
+    <string name="wifi_scan_throttling_summary" msgid="4461922728822495763">"ବ୍ୟାଟେରୀ ଖର୍ଚ୍ଚ କମ୍ ଏବଂ ନେଟ୍‌ୱାର୍କ ପ୍ରଦର୍ଶନ ଉନ୍ନତ କରିଥାଏ"</string>
     <string name="wifi_metered_label" msgid="4514924227256839725">"ମପାଯାଉଥିବା"</string>
     <string name="wifi_unmetered_label" msgid="6124098729457992931">"ମପାଯାଉନଥିବା"</string>
     <string name="select_logd_size_title" msgid="7433137108348553508">"ଲଗର୍‌ ବଫର୍‌ ସାଇଜ୍"</string>
diff --git a/packages/SettingsLib/res/values-pa/strings.xml b/packages/SettingsLib/res/values-pa/strings.xml
index 6fff4d8..7967c71 100644
--- a/packages/SettingsLib/res/values-pa/strings.xml
+++ b/packages/SettingsLib/res/values-pa/strings.xml
@@ -220,6 +220,7 @@
     <string name="debug_networking_category" msgid="7044075693643009662">"ਨੈੱਟਵਰਕਿੰਗ"</string>
     <string name="wifi_display_certification" msgid="8611569543791307533">"ਵਾਇਰਲੈੱਸ ਡਿਸਪਲੇ ਪ੍ਰਮਾਣੀਕਰਨ"</string>
     <string name="wifi_verbose_logging" msgid="4203729756047242344">"ਵਾਈ-ਫਾਈ ਵਰਬੋਸ ਲੌਗਿੰਗ ਚਾਲੂ ਕਰੋ"</string>
+    <string name="wifi_scan_throttling" msgid="160014287416479843">"ਸੀਮਤ ਵਾਈ‑ਫਾਈ ਸਕੈਨ"</string>
     <string name="mobile_data_always_on" msgid="8774857027458200434">"ਮੋਬਾਈਲ ਡਾਟਾ ਹਮੇਸ਼ਾਂ ਕਿਰਿਆਸ਼ੀਲ"</string>
     <string name="tethering_hardware_offload" msgid="7470077827090325814">"ਟੈਦਰਿੰਗ ਹਾਰਡਵੇਅਰ ਐਕਸੈੱਲਰੇਸ਼ਨ"</string>
     <string name="bluetooth_show_devices_without_names" msgid="4708446092962060176">"ਅਨਾਮ ਬਲੂਟੁੱਥ ਡੀਵਾਈਸਾਂ ਦਿਖਾਓ"</string>
@@ -246,6 +247,7 @@
     <string name="private_dns_mode_provider_failure" msgid="231837290365031223">"ਕਨੈਕਟ ਨਹੀਂ ਕੀਤਾ ਜਾ ਸਕਿਆ"</string>
     <string name="wifi_display_certification_summary" msgid="1155182309166746973">"ਵਾਇਰਲੈੱਸ ਡਿਸਪਲੇ ਪ੍ਰਮਾਣੀਕਰਨ ਲਈ ਚੋਣਾਂ ਪ੍ਰਦਰਸ਼ਿਤ ਕਰੋ"</string>
     <string name="wifi_verbose_logging_summary" msgid="6615071616111731958">"ਵਾਈ‑ਫਾਈ ਲੌਗਿੰਗ ਪੱਧਰ ਵਧਾਓ, ਵਾਈ‑ਫਾਈ Picker ਵਿੱਚ ਪ੍ਰਤੀ SSID RSSI ਦਿਖਾਓ"</string>
+    <string name="wifi_scan_throttling_summary" msgid="4461922728822495763">"ਬੈਟਰੀ ਦੀ ਵਰਤੋਂ ਘਟਾ ਕੇ ਨੈੱਟਵਰਕ ਕਾਰਗੁਜ਼ਾਰੀ ਨੂੰ ਬਿਹਤਰ ਬਣਾਉਂਦਾ ਹੈ"</string>
     <string name="wifi_metered_label" msgid="4514924227256839725">"ਮੀਟਰਬੱਧ ਕੀਤਾ ਗਿਆ"</string>
     <string name="wifi_unmetered_label" msgid="6124098729457992931">"ਗੈਰ-ਮੀਟਰਬੱਧ ਕੀਤਾ ਗਿਆ"</string>
     <string name="select_logd_size_title" msgid="7433137108348553508">"ਲੌਗਰ ਬਫ਼ਰ ਆਕਾਰ"</string>
diff --git a/packages/SettingsLib/res/values-pl/strings.xml b/packages/SettingsLib/res/values-pl/strings.xml
index bed4d63..60a4c53 100644
--- a/packages/SettingsLib/res/values-pl/strings.xml
+++ b/packages/SettingsLib/res/values-pl/strings.xml
@@ -220,6 +220,7 @@
     <string name="debug_networking_category" msgid="7044075693643009662">"Sieci"</string>
     <string name="wifi_display_certification" msgid="8611569543791307533">"Wyświetlacz bezprzewodowy"</string>
     <string name="wifi_verbose_logging" msgid="4203729756047242344">"Szczegółowy dziennik Wi-Fi"</string>
+    <string name="wifi_scan_throttling" msgid="160014287416479843">"Ograniczanie skanowania Wi-Fi"</string>
     <string name="mobile_data_always_on" msgid="8774857027458200434">"Mobilna transmisja danych zawsze aktywna"</string>
     <string name="tethering_hardware_offload" msgid="7470077827090325814">"Akceleracja sprzętowa tetheringu"</string>
     <string name="bluetooth_show_devices_without_names" msgid="4708446092962060176">"Pokaż urządzenia Bluetooth bez nazw"</string>
@@ -246,6 +247,7 @@
     <string name="private_dns_mode_provider_failure" msgid="231837290365031223">"Nie udało się połączyć"</string>
     <string name="wifi_display_certification_summary" msgid="1155182309166746973">"Pokaż opcje certyfikacji wyświetlacza bezprzewodowego"</string>
     <string name="wifi_verbose_logging_summary" msgid="6615071616111731958">"Zwiększ poziom rejestrowania Wi‑Fi, pokazuj według RSSI SSID w selektorze Wi‑Fi"</string>
+    <string name="wifi_scan_throttling_summary" msgid="4461922728822495763">"Zmniejsza zużycie baterii i zwiększa wydajność sieci"</string>
     <string name="wifi_metered_label" msgid="4514924227256839725">"Użycie danych jest mierzone"</string>
     <string name="wifi_unmetered_label" msgid="6124098729457992931">"Użycie danych nie jest mierzone"</string>
     <string name="select_logd_size_title" msgid="7433137108348553508">"Rozmiary bufora rejestratora"</string>
diff --git a/packages/SettingsLib/res/values-pt-rBR/strings.xml b/packages/SettingsLib/res/values-pt-rBR/strings.xml
index 7a5522e..dd0a75b 100644
--- a/packages/SettingsLib/res/values-pt-rBR/strings.xml
+++ b/packages/SettingsLib/res/values-pt-rBR/strings.xml
@@ -220,6 +220,7 @@
     <string name="debug_networking_category" msgid="7044075693643009662">"Redes"</string>
     <string name="wifi_display_certification" msgid="8611569543791307533">"Certificação de Display sem fio"</string>
     <string name="wifi_verbose_logging" msgid="4203729756047242344">"Ativar registro detalhado de Wi-Fi"</string>
+    <string name="wifi_scan_throttling" msgid="160014287416479843">"Limitar busca por Wi-Fi"</string>
     <string name="mobile_data_always_on" msgid="8774857027458200434">"Dados móveis sempre ativos"</string>
     <string name="tethering_hardware_offload" msgid="7470077827090325814">"Aceleração de hardware de tethering"</string>
     <string name="bluetooth_show_devices_without_names" msgid="4708446092962060176">"Mostrar dispositivos Bluetooth sem nomes"</string>
@@ -246,6 +247,7 @@
     <string name="private_dns_mode_provider_failure" msgid="231837290365031223">"Não foi possível conectar"</string>
     <string name="wifi_display_certification_summary" msgid="1155182309166746973">"Mostrar opções de certificação de Display sem fio"</string>
     <string name="wifi_verbose_logging_summary" msgid="6615071616111731958">"Aumentar o nível de registro de Wi-Fi; mostrar conforme o RSSI do SSID no seletor de Wi-Fi"</string>
+    <string name="wifi_scan_throttling_summary" msgid="4461922728822495763">"Reduz o consumo de bateria e melhora o desempenho da rede"</string>
     <string name="wifi_metered_label" msgid="4514924227256839725">"Limitada"</string>
     <string name="wifi_unmetered_label" msgid="6124098729457992931">"Ilimitada"</string>
     <string name="select_logd_size_title" msgid="7433137108348553508">"Tamanhos de buffer de logger"</string>
diff --git a/packages/SettingsLib/res/values-pt-rPT/strings.xml b/packages/SettingsLib/res/values-pt-rPT/strings.xml
index 3b0b86c..501cf50 100644
--- a/packages/SettingsLib/res/values-pt-rPT/strings.xml
+++ b/packages/SettingsLib/res/values-pt-rPT/strings.xml
@@ -220,6 +220,7 @@
     <string name="debug_networking_category" msgid="7044075693643009662">"Redes"</string>
     <string name="wifi_display_certification" msgid="8611569543791307533">"Certificação de display sem fios"</string>
     <string name="wifi_verbose_logging" msgid="4203729756047242344">"Ativar o registo verboso de Wi-Fi"</string>
+    <string name="wifi_scan_throttling" msgid="160014287416479843">"Controlo da procura de Wi‑Fi"</string>
     <string name="mobile_data_always_on" msgid="8774857027458200434">"Dados móveis sempre ativos"</string>
     <string name="tethering_hardware_offload" msgid="7470077827090325814">"Aceleração de hardware para ligação (à Internet) via telemóvel"</string>
     <string name="bluetooth_show_devices_without_names" msgid="4708446092962060176">"Mostrar dispositivos Bluetooth sem nomes"</string>
@@ -246,6 +247,7 @@
     <string name="private_dns_mode_provider_failure" msgid="231837290365031223">"Não foi possível estabelecer ligação"</string>
     <string name="wifi_display_certification_summary" msgid="1155182309166746973">"Mostrar opções da certificação de display sem fios"</string>
     <string name="wifi_verbose_logging_summary" msgid="6615071616111731958">"Aumentar o nível de reg. de Wi-Fi, mostrar por RSSI de SSID no Selec. de Wi-Fi"</string>
+    <string name="wifi_scan_throttling_summary" msgid="4461922728822495763">"Reduz o consumo rápido da bateria e melhora o desempenho da rede"</string>
     <string name="wifi_metered_label" msgid="4514924227256839725">"Acesso limitado"</string>
     <string name="wifi_unmetered_label" msgid="6124098729457992931">"Acesso ilimitado"</string>
     <string name="select_logd_size_title" msgid="7433137108348553508">"Tamanhos da memória intermédia do registo"</string>
diff --git a/packages/SettingsLib/res/values-pt/strings.xml b/packages/SettingsLib/res/values-pt/strings.xml
index 7a5522e..dd0a75b 100644
--- a/packages/SettingsLib/res/values-pt/strings.xml
+++ b/packages/SettingsLib/res/values-pt/strings.xml
@@ -220,6 +220,7 @@
     <string name="debug_networking_category" msgid="7044075693643009662">"Redes"</string>
     <string name="wifi_display_certification" msgid="8611569543791307533">"Certificação de Display sem fio"</string>
     <string name="wifi_verbose_logging" msgid="4203729756047242344">"Ativar registro detalhado de Wi-Fi"</string>
+    <string name="wifi_scan_throttling" msgid="160014287416479843">"Limitar busca por Wi-Fi"</string>
     <string name="mobile_data_always_on" msgid="8774857027458200434">"Dados móveis sempre ativos"</string>
     <string name="tethering_hardware_offload" msgid="7470077827090325814">"Aceleração de hardware de tethering"</string>
     <string name="bluetooth_show_devices_without_names" msgid="4708446092962060176">"Mostrar dispositivos Bluetooth sem nomes"</string>
@@ -246,6 +247,7 @@
     <string name="private_dns_mode_provider_failure" msgid="231837290365031223">"Não foi possível conectar"</string>
     <string name="wifi_display_certification_summary" msgid="1155182309166746973">"Mostrar opções de certificação de Display sem fio"</string>
     <string name="wifi_verbose_logging_summary" msgid="6615071616111731958">"Aumentar o nível de registro de Wi-Fi; mostrar conforme o RSSI do SSID no seletor de Wi-Fi"</string>
+    <string name="wifi_scan_throttling_summary" msgid="4461922728822495763">"Reduz o consumo de bateria e melhora o desempenho da rede"</string>
     <string name="wifi_metered_label" msgid="4514924227256839725">"Limitada"</string>
     <string name="wifi_unmetered_label" msgid="6124098729457992931">"Ilimitada"</string>
     <string name="select_logd_size_title" msgid="7433137108348553508">"Tamanhos de buffer de logger"</string>
diff --git a/packages/SettingsLib/res/values-ro/strings.xml b/packages/SettingsLib/res/values-ro/strings.xml
index b4fd3fa..fb020e2 100644
--- a/packages/SettingsLib/res/values-ro/strings.xml
+++ b/packages/SettingsLib/res/values-ro/strings.xml
@@ -220,6 +220,7 @@
     <string name="debug_networking_category" msgid="7044075693643009662">"Conectare la rețele"</string>
     <string name="wifi_display_certification" msgid="8611569543791307533">"Certificare Ecran wireless"</string>
     <string name="wifi_verbose_logging" msgid="4203729756047242344">"Înregistrare prin Wi-Fi de volume mari de date"</string>
+    <string name="wifi_scan_throttling" msgid="160014287416479843">"Limitare căutare de rețele Wi-Fi"</string>
     <string name="mobile_data_always_on" msgid="8774857027458200434">"Date mobile permanent active"</string>
     <string name="tethering_hardware_offload" msgid="7470077827090325814">"Accelerare hardware pentru tethering"</string>
     <string name="bluetooth_show_devices_without_names" msgid="4708446092962060176">"Afișați dispozitivele Bluetooth fără nume"</string>
@@ -246,6 +247,7 @@
     <string name="private_dns_mode_provider_failure" msgid="231837290365031223">"Nu s-a putut conecta"</string>
     <string name="wifi_display_certification_summary" msgid="1155182309166746973">"Afișați opțiunile pentru certificarea Ecran wireless"</string>
     <string name="wifi_verbose_logging_summary" msgid="6615071616111731958">"Măriți niv. de înr. prin Wi‑Fi, afișați în fcț. de SSID RSSI în Selectorul Wi‑Fi"</string>
+    <string name="wifi_scan_throttling_summary" msgid="4461922728822495763">"Reduce descărcarea bateriei și îmbunătățește performanța rețelei"</string>
     <string name="wifi_metered_label" msgid="4514924227256839725">"Contorizată"</string>
     <string name="wifi_unmetered_label" msgid="6124098729457992931">"Necontorizată"</string>
     <string name="select_logd_size_title" msgid="7433137108348553508">"Dimensiunile memoriei temporare a jurnalului"</string>
diff --git a/packages/SettingsLib/res/values-ru/strings.xml b/packages/SettingsLib/res/values-ru/strings.xml
index 657e6a9..0401e7f 100644
--- a/packages/SettingsLib/res/values-ru/strings.xml
+++ b/packages/SettingsLib/res/values-ru/strings.xml
@@ -60,7 +60,7 @@
     <string name="speed_label_medium" msgid="3175763313268941953">"Средняя"</string>
     <string name="speed_label_fast" msgid="7715732164050975057">"Быстрая"</string>
     <string name="speed_label_very_fast" msgid="2265363430784523409">"Очень быстрая"</string>
-    <string name="preference_summary_default_combination" msgid="8532964268242666060">"<xliff:g id="DESCRIPTION">%2$s</xliff:g>: <xliff:g id="STATE">%1$s</xliff:g>"</string>
+    <string name="preference_summary_default_combination" msgid="8532964268242666060">"<xliff:g id="STATE">%1$s</xliff:g> / <xliff:g id="DESCRIPTION">%2$s</xliff:g>"</string>
     <string name="bluetooth_disconnected" msgid="6557104142667339895">"Нет подключения"</string>
     <string name="bluetooth_disconnecting" msgid="8913264760027764974">"Отключение..."</string>
     <string name="bluetooth_connecting" msgid="8555009514614320497">"Подключение..."</string>
@@ -220,6 +220,7 @@
     <string name="debug_networking_category" msgid="7044075693643009662">"Сети"</string>
     <string name="wifi_display_certification" msgid="8611569543791307533">"Серт. беспроводн. мониторов"</string>
     <string name="wifi_verbose_logging" msgid="4203729756047242344">"Подробный журнал Wi‑Fi"</string>
+    <string name="wifi_scan_throttling" msgid="160014287416479843">"Регулирование поиска сетей Wi‑Fi"</string>
     <string name="mobile_data_always_on" msgid="8774857027458200434">"Не отключать мобильный Интернет"</string>
     <string name="tethering_hardware_offload" msgid="7470077827090325814">"Аппаратное ускорение в режиме модема"</string>
     <string name="bluetooth_show_devices_without_names" msgid="4708446092962060176">"Показывать Bluetooth-устройства без названий"</string>
@@ -246,6 +247,7 @@
     <string name="private_dns_mode_provider_failure" msgid="231837290365031223">"Ошибка подключения"</string>
     <string name="wifi_display_certification_summary" msgid="1155182309166746973">"Показывать параметры сертификации беспроводных мониторов"</string>
     <string name="wifi_verbose_logging_summary" msgid="6615071616111731958">"Вести подробный журнал, показывать RSSI для каждого SSID при выборе сети"</string>
+    <string name="wifi_scan_throttling_summary" msgid="4461922728822495763">"Уменьшает расход заряда батареи и улучшает работу сетей."</string>
     <string name="wifi_metered_label" msgid="4514924227256839725">"Сеть с тарификацией трафика"</string>
     <string name="wifi_unmetered_label" msgid="6124098729457992931">"Сеть без тарификации трафика"</string>
     <string name="select_logd_size_title" msgid="7433137108348553508">"Размер буфера журнала"</string>
diff --git a/packages/SettingsLib/res/values-si/strings.xml b/packages/SettingsLib/res/values-si/strings.xml
index f499253..925d5b4 100644
--- a/packages/SettingsLib/res/values-si/strings.xml
+++ b/packages/SettingsLib/res/values-si/strings.xml
@@ -220,6 +220,7 @@
     <string name="debug_networking_category" msgid="7044075693643009662">"ජාලකරණය"</string>
     <string name="wifi_display_certification" msgid="8611569543791307533">"නොරැහැන් සංදර්ශක සහතිකය"</string>
     <string name="wifi_verbose_logging" msgid="4203729756047242344">"විස්තරාත්මක Wi‑Fi ලොග් කිරීම සබල කරන්න"</string>
+    <string name="wifi_scan_throttling" msgid="160014287416479843">"Wi‑Fi ස්කෑන් අවකරණය"</string>
     <string name="mobile_data_always_on" msgid="8774857027458200434">"ජංගම දත්ත සැමවිට ක්‍රියාකාරීය"</string>
     <string name="tethering_hardware_offload" msgid="7470077827090325814">"ටෙදරින් දෘඪාංග ත්වරණය"</string>
     <string name="bluetooth_show_devices_without_names" msgid="4708446092962060176">"නම් නොමැති බ්ලූටූත් උපාංග පෙන්වන්න"</string>
@@ -246,6 +247,7 @@
     <string name="private_dns_mode_provider_failure" msgid="231837290365031223">"සම්බන්ධ වීමට නොහැකි විය"</string>
     <string name="wifi_display_certification_summary" msgid="1155182309166746973">"නොරැහැන් සංදර්ශක සහතිකය සඳහා විකල්ප පෙන්වන්න"</string>
     <string name="wifi_verbose_logging_summary" msgid="6615071616111731958">"Wi‑Fi ලොග් මට්ටම වැඩි කරන්න, Wi‑Fi තෝරනයෙහි SSID RSSI අනුව පෙන්වන්න"</string>
+    <string name="wifi_scan_throttling_summary" msgid="4461922728822495763">"බැටරි බැසීම අඩු කරන අතර ජාල කාර්ය සාධනය වැඩි දියුණු කරයි"</string>
     <string name="wifi_metered_label" msgid="4514924227256839725">"මනිනු ලැබේ"</string>
     <string name="wifi_unmetered_label" msgid="6124098729457992931">"මනින්නේ නැත"</string>
     <string name="select_logd_size_title" msgid="7433137108348553508">"ලෝගයේ අන්තරාවක ප්‍රමාණය"</string>
diff --git a/packages/SettingsLib/res/values-sk/strings.xml b/packages/SettingsLib/res/values-sk/strings.xml
index a7895c4..e28825c 100644
--- a/packages/SettingsLib/res/values-sk/strings.xml
+++ b/packages/SettingsLib/res/values-sk/strings.xml
@@ -91,8 +91,8 @@
     <string name="bluetooth_profile_sap" msgid="5764222021851283125">"Prístup k SIM karte"</string>
     <string name="bluetooth_profile_a2dp_high_quality" msgid="5444517801472820055">"HD zvuk: <xliff:g id="CODEC_NAME">%1$s</xliff:g>"</string>
     <string name="bluetooth_profile_a2dp_high_quality_unknown_codec" msgid="8510588052415438887">"HD zvuk"</string>
-    <string name="bluetooth_profile_hearing_aid" msgid="6680721080542444257">"Načúvacie pomôcky"</string>
-    <string name="bluetooth_hearing_aid_profile_summary_connected" msgid="3051944447369418317">"Pripojené k načúvacím pomôckam"</string>
+    <string name="bluetooth_profile_hearing_aid" msgid="6680721080542444257">"Načúvadlá"</string>
+    <string name="bluetooth_hearing_aid_profile_summary_connected" msgid="3051944447369418317">"Pripojené k načúvadlám"</string>
     <string name="bluetooth_a2dp_profile_summary_connected" msgid="963376081347721598">"Pripojené ku zvukovému médiu"</string>
     <string name="bluetooth_headset_profile_summary_connected" msgid="7661070206715520671">"Pripojené ku zvuku telefónu"</string>
     <string name="bluetooth_opp_profile_summary_connected" msgid="2611913495968309066">"Pripojené na server pre prenos údajov"</string>
@@ -109,7 +109,7 @@
     <string name="bluetooth_headset_profile_summary_use_for" msgid="8705753622443862627">"Použiť pre zvuk telefónu"</string>
     <string name="bluetooth_opp_profile_summary_use_for" msgid="1255674547144769756">"Použiť na prenos súborov"</string>
     <string name="bluetooth_hid_profile_summary_use_for" msgid="232727040453645139">"Použiť pre vstup"</string>
-    <string name="bluetooth_hearing_aid_profile_summary_use_for" msgid="8843499209204010224">"Použiť pre načúvacie pomôcky"</string>
+    <string name="bluetooth_hearing_aid_profile_summary_use_for" msgid="8843499209204010224">"Použiť pre načúvadlá"</string>
     <string name="bluetooth_pairing_accept" msgid="6163520056536604875">"Párovať"</string>
     <string name="bluetooth_pairing_accept_all_caps" msgid="6061699265220789149">"PÁROVAŤ"</string>
     <string name="bluetooth_pairing_decline" msgid="4185420413578948140">"Zrušiť"</string>
@@ -220,6 +220,7 @@
     <string name="debug_networking_category" msgid="7044075693643009662">"Siete"</string>
     <string name="wifi_display_certification" msgid="8611569543791307533">"Certifikácia bezdrôtového zobrazenia"</string>
     <string name="wifi_verbose_logging" msgid="4203729756047242344">"Podrobné denníky Wi‑Fi"</string>
+    <string name="wifi_scan_throttling" msgid="160014287416479843">"Pribrzdenie vyhľadávania sietí Wi‑Fi"</string>
     <string name="mobile_data_always_on" msgid="8774857027458200434">"Mobilné dáta ponechať vždy aktívne"</string>
     <string name="tethering_hardware_offload" msgid="7470077827090325814">"Hardvérová akcelerácia tetheringu"</string>
     <string name="bluetooth_show_devices_without_names" msgid="4708446092962060176">"Zobrazovať zariadenia Bluetooth bez názvov"</string>
@@ -246,6 +247,7 @@
     <string name="private_dns_mode_provider_failure" msgid="231837290365031223">"Nepodarilo sa pripojiť"</string>
     <string name="wifi_display_certification_summary" msgid="1155182309166746973">"Zobraziť možnosti certifikácie bezdrôtového zobrazenia"</string>
     <string name="wifi_verbose_logging_summary" msgid="6615071616111731958">"Zvýšiť úroveň denníkov Wi‑Fi, zobrazovať podľa SSID RSSI pri výbere siete Wi‑Fi"</string>
+    <string name="wifi_scan_throttling_summary" msgid="4461922728822495763">"Znižuje používanie batérie a zlepšuje výkon siete"</string>
     <string name="wifi_metered_label" msgid="4514924227256839725">"Merané"</string>
     <string name="wifi_unmetered_label" msgid="6124098729457992931">"Bez merania dát"</string>
     <string name="select_logd_size_title" msgid="7433137108348553508">"Vyrovnávacia pamäť nástroja denníkov"</string>
diff --git a/packages/SettingsLib/res/values-sl/strings.xml b/packages/SettingsLib/res/values-sl/strings.xml
index 4c2441a..213b285 100644
--- a/packages/SettingsLib/res/values-sl/strings.xml
+++ b/packages/SettingsLib/res/values-sl/strings.xml
@@ -220,6 +220,7 @@
     <string name="debug_networking_category" msgid="7044075693643009662">"Omrežja"</string>
     <string name="wifi_display_certification" msgid="8611569543791307533">"Potrdilo brezžičnega zaslona"</string>
     <string name="wifi_verbose_logging" msgid="4203729756047242344">"Omogoči podrobno zapisovanje dnevnika za Wi-Fi"</string>
+    <string name="wifi_scan_throttling" msgid="160014287416479843">"Omejevanje iskanja omrežij Wi-Fi"</string>
     <string name="mobile_data_always_on" msgid="8774857027458200434">"Prenos podatkov v mobilnem omrežju je vedno aktiven"</string>
     <string name="tethering_hardware_offload" msgid="7470077827090325814">"Strojno pospeševanje za internetno povezavo prek mobilnega telefona"</string>
     <string name="bluetooth_show_devices_without_names" msgid="4708446092962060176">"Prikaži naprave Bluetooth brez imen"</string>
@@ -246,6 +247,7 @@
     <string name="private_dns_mode_provider_failure" msgid="231837290365031223">"Povezave ni bilo mogoče vzpostaviti"</string>
     <string name="wifi_display_certification_summary" msgid="1155182309166746973">"Pokaži možnosti za potrdilo brezžičnega zaslona"</string>
     <string name="wifi_verbose_logging_summary" msgid="6615071616111731958">"Povečaj raven zapis. dnev. za Wi-Fi; v izbir. Wi‑Fi-ja pokaži glede na SSID RSSI"</string>
+    <string name="wifi_scan_throttling_summary" msgid="4461922728822495763">"Zmanjša porabo energije akumulatorja in izboljša delovanje omrežja"</string>
     <string name="wifi_metered_label" msgid="4514924227256839725">"Omejen prenos podatkov"</string>
     <string name="wifi_unmetered_label" msgid="6124098729457992931">"Z neomejenim prenosom podatkov"</string>
     <string name="select_logd_size_title" msgid="7433137108348553508">"Velikosti medpomnilnikov zapisovalnika dnevnika"</string>
diff --git a/packages/SettingsLib/res/values-sq/strings.xml b/packages/SettingsLib/res/values-sq/strings.xml
index b5f93e4..4b38383 100644
--- a/packages/SettingsLib/res/values-sq/strings.xml
+++ b/packages/SettingsLib/res/values-sq/strings.xml
@@ -220,6 +220,7 @@
     <string name="debug_networking_category" msgid="7044075693643009662">"Rrjetet"</string>
     <string name="wifi_display_certification" msgid="8611569543791307533">"Certifikimi i ekranit valor"</string>
     <string name="wifi_verbose_logging" msgid="4203729756047242344">"Aktivizo hyrjen Wi-Fi Verbose"</string>
+    <string name="wifi_scan_throttling" msgid="160014287416479843">"Përshpejtimi i skanimit të Wi‑Fi"</string>
     <string name="mobile_data_always_on" msgid="8774857027458200434">"Të dhënat celulare gjithmonë aktive"</string>
     <string name="tethering_hardware_offload" msgid="7470077827090325814">"Përshpejtimi i harduerit për ndarjen e lidhjes (internet)"</string>
     <string name="bluetooth_show_devices_without_names" msgid="4708446092962060176">"Shfaq pajisjet me Bluetooth pa emra"</string>
@@ -246,6 +247,7 @@
     <string name="private_dns_mode_provider_failure" msgid="231837290365031223">"Nuk mund të lidhej"</string>
     <string name="wifi_display_certification_summary" msgid="1155182309166746973">"Shfaq opsionet për certifikimin e ekranit valor"</string>
     <string name="wifi_verbose_logging_summary" msgid="6615071616111731958">"Rrit nivelin regjistrues të Wi‑Fi duke shfaqur SSID RSSI-në te Zgjedhësi i Wi‑Fi"</string>
+    <string name="wifi_scan_throttling_summary" msgid="4461922728822495763">"Zvogëlon shkarkimin e baterisë dhe përmirëson cilësinë e funksionimit të rrjetit"</string>
     <string name="wifi_metered_label" msgid="4514924227256839725">"Me matje"</string>
     <string name="wifi_unmetered_label" msgid="6124098729457992931">"Pa matje"</string>
     <string name="select_logd_size_title" msgid="7433137108348553508">"Madhësitë e regjistruesit"</string>
diff --git a/packages/SettingsLib/res/values-sr/strings.xml b/packages/SettingsLib/res/values-sr/strings.xml
index 2a6e328..0edc985 100644
--- a/packages/SettingsLib/res/values-sr/strings.xml
+++ b/packages/SettingsLib/res/values-sr/strings.xml
@@ -220,6 +220,7 @@
     <string name="debug_networking_category" msgid="7044075693643009662">"Умрежавање"</string>
     <string name="wifi_display_certification" msgid="8611569543791307533">"Сертификација бежичног екрана"</string>
     <string name="wifi_verbose_logging" msgid="4203729756047242344">"Омогући детаљнију евиденцију за Wi‑Fi"</string>
+    <string name="wifi_scan_throttling" msgid="160014287416479843">"Успоравање Wi-Fi скенирања"</string>
     <string name="mobile_data_always_on" msgid="8774857027458200434">"Мобилни подаци су увек активни"</string>
     <string name="tethering_hardware_offload" msgid="7470077827090325814">"Хардверско убрзање привезивања"</string>
     <string name="bluetooth_show_devices_without_names" msgid="4708446092962060176">"Прикажи Bluetooth уређаје без назива"</string>
@@ -246,6 +247,7 @@
     <string name="private_dns_mode_provider_failure" msgid="231837290365031223">"Повезивање није успело"</string>
     <string name="wifi_display_certification_summary" msgid="1155182309166746973">"Приказ опција за сертификацију бежичног екрана"</string>
     <string name="wifi_verbose_logging_summary" msgid="6615071616111731958">"Повећава ниво евидентирања за Wi‑Fi. Приказ по SSID RSSI-у у бирачу Wi‑Fi мреже"</string>
+    <string name="wifi_scan_throttling_summary" msgid="4461922728822495763">"Смањује потрошњу батерије и побољшава учинак мреже"</string>
     <string name="wifi_metered_label" msgid="4514924227256839725">"Са ограничењем"</string>
     <string name="wifi_unmetered_label" msgid="6124098729457992931">"Без ограничења"</string>
     <string name="select_logd_size_title" msgid="7433137108348553508">"Величине бафера података у програму за евидентирање"</string>
diff --git a/packages/SettingsLib/res/values-sv/strings.xml b/packages/SettingsLib/res/values-sv/strings.xml
index 9778516..862fc6c 100644
--- a/packages/SettingsLib/res/values-sv/strings.xml
+++ b/packages/SettingsLib/res/values-sv/strings.xml
@@ -220,6 +220,7 @@
     <string name="debug_networking_category" msgid="7044075693643009662">"Nätverk"</string>
     <string name="wifi_display_certification" msgid="8611569543791307533">"Certifiering för Wi-Fi-skärmdelning"</string>
     <string name="wifi_verbose_logging" msgid="4203729756047242344">"Aktivera utförlig loggning för Wi-Fi"</string>
+    <string name="wifi_scan_throttling" msgid="160014287416479843">"Begränsning av Wi-Fi-sökning"</string>
     <string name="mobile_data_always_on" msgid="8774857027458200434">"Mobildata alltid aktiverad"</string>
     <string name="tethering_hardware_offload" msgid="7470077827090325814">"Maskinvaruacceleration för internetdelning"</string>
     <string name="bluetooth_show_devices_without_names" msgid="4708446092962060176">"Visa namnlösa Bluetooth-enheter"</string>
@@ -246,6 +247,7 @@
     <string name="private_dns_mode_provider_failure" msgid="231837290365031223">"Kan inte ansluta"</string>
     <string name="wifi_display_certification_summary" msgid="1155182309166746973">"Visa certifieringsalternativ för Wi-Fi-skärmdelning"</string>
     <string name="wifi_verbose_logging_summary" msgid="6615071616111731958">"Öka loggningsnivån för Wi-Fi, visa per SSID RSSI i Wi‑Fi Picker"</string>
+    <string name="wifi_scan_throttling_summary" msgid="4461922728822495763">"Sänker batteriförbrukningen och förbättrar nätverksprestandan"</string>
     <string name="wifi_metered_label" msgid="4514924227256839725">"Med datapriser"</string>
     <string name="wifi_unmetered_label" msgid="6124098729457992931">"Utan datapriser"</string>
     <string name="select_logd_size_title" msgid="7433137108348553508">"Buffertstorlekar för logg"</string>
diff --git a/packages/SettingsLib/res/values-sw/strings.xml b/packages/SettingsLib/res/values-sw/strings.xml
index 35a9954..12922ca 100644
--- a/packages/SettingsLib/res/values-sw/strings.xml
+++ b/packages/SettingsLib/res/values-sw/strings.xml
@@ -78,7 +78,7 @@
     <string name="bluetooth_active_battery_level_untethered" msgid="6662649951391456747">"Inatumika, L: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE_0">%1$s</xliff:g> ya betri, R: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE_1">%2$s</xliff:g> ya betri"</string>
     <string name="bluetooth_battery_level" msgid="1447164613319663655">"Chaji ya betri ni <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
     <string name="bluetooth_battery_level_untethered" msgid="5974406100211667177">"L: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE_0">%1$s</xliff:g> ya betri, R: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE_1">%2$s</xliff:g> ya betri"</string>
-    <string name="bluetooth_active_no_battery_level" msgid="8380223546730241956">"Unaendelea"</string>
+    <string name="bluetooth_active_no_battery_level" msgid="8380223546730241956">"Kimeunganishwa"</string>
     <string name="bluetooth_profile_a2dp" msgid="2031475486179830674">"Media ya sauti"</string>
     <string name="bluetooth_profile_headset" msgid="7815495680863246034">"Simu"</string>
     <string name="bluetooth_profile_opp" msgid="9168139293654233697">"Uhamishaji wa faili"</string>
@@ -220,6 +220,7 @@
     <string name="debug_networking_category" msgid="7044075693643009662">"Mtandao"</string>
     <string name="wifi_display_certification" msgid="8611569543791307533">"Chaguo za cheti cha kuonyesha pasiwaya"</string>
     <string name="wifi_verbose_logging" msgid="4203729756047242344">"Washa Uwekaji kumbukumbu za WiFi kutumia Sauti"</string>
+    <string name="wifi_scan_throttling" msgid="160014287416479843">"Kudhibiti utafutaji wa Wi-Fi"</string>
     <string name="mobile_data_always_on" msgid="8774857027458200434">"Iendelee kutumia data ya simu"</string>
     <string name="tethering_hardware_offload" msgid="7470077827090325814">"Kuongeza kasi kwa kutumia maunzi ili kusambaza mtandao"</string>
     <string name="bluetooth_show_devices_without_names" msgid="4708446092962060176">"Onyesha vifaa vya Bluetooth visivyo na majina"</string>
@@ -246,6 +247,7 @@
     <string name="private_dns_mode_provider_failure" msgid="231837290365031223">"Imeshindwa kuunganisha"</string>
     <string name="wifi_display_certification_summary" msgid="1155182309166746973">"Onyesha chaguo za cheti cha kuonyesha pasiwaya"</string>
     <string name="wifi_verbose_logging_summary" msgid="6615071616111731958">"Ongeza hatua ya uwekaji kumbukumbu ya Wi-Fi, onyesha kwa kila SSID RSSI kwenye Kichukuzi cha Wi-Fi"</string>
+    <string name="wifi_scan_throttling_summary" msgid="4461922728822495763">"Hupunguza matumizi ya chaji ya betri na kuboresha utendaji wa mtandao"</string>
     <string name="wifi_metered_label" msgid="4514924227256839725">"Mtandao unapima data"</string>
     <string name="wifi_unmetered_label" msgid="6124098729457992931">"Mtandao usiopima data"</string>
     <string name="select_logd_size_title" msgid="7433137108348553508">"Ukubwa wa kiweka bafa ya kumbukumbu"</string>
diff --git a/packages/SettingsLib/res/values-ta/strings.xml b/packages/SettingsLib/res/values-ta/strings.xml
index 6b5b056..cf442b7 100644
--- a/packages/SettingsLib/res/values-ta/strings.xml
+++ b/packages/SettingsLib/res/values-ta/strings.xml
@@ -220,6 +220,7 @@
     <string name="debug_networking_category" msgid="7044075693643009662">"நெட்வொர்க்கிங்"</string>
     <string name="wifi_display_certification" msgid="8611569543791307533">"வயர்லெஸ் காட்சிக்கான சான்றிதழ்"</string>
     <string name="wifi_verbose_logging" msgid="4203729756047242344">"வைஃபை அதிவிவர நுழைவை இயக்கு"</string>
+    <string name="wifi_scan_throttling" msgid="160014287416479843">"வைஃபை ஸ்கேனிங்கை வரம்பிடுதல்"</string>
     <string name="mobile_data_always_on" msgid="8774857027458200434">"மொபைல் டேட்டாவை எப்போதும் இயக்கத்திலேயே வை"</string>
     <string name="tethering_hardware_offload" msgid="7470077827090325814">"வன்பொருள் விரைவுப்படுத்துதல் இணைப்பு முறை"</string>
     <string name="bluetooth_show_devices_without_names" msgid="4708446092962060176">"பெயர்கள் இல்லாத புளூடூத் சாதனங்களைக் காட்டு"</string>
@@ -246,6 +247,7 @@
     <string name="private_dns_mode_provider_failure" msgid="231837290365031223">"இணைக்க முடியவில்லை"</string>
     <string name="wifi_display_certification_summary" msgid="1155182309166746973">"வயர்லெஸ் காட்சி சான்றுக்கான விருப்பங்களைக் காட்டு"</string>
     <string name="wifi_verbose_logging_summary" msgid="6615071616111731958">"வைஃபை நுழைவு அளவை அதிகரித்து, வைஃபை தேர்வியில் ஒவ்வொன்றிற்கும் SSID RSSI ஐ காட்டுக"</string>
+    <string name="wifi_scan_throttling_summary" msgid="4461922728822495763">"பேட்டரி தீர்ந்துபோவதைக் குறைத்து நெட்வொர்க்கின் செயல்திறனை மேம்படுத்தும்"</string>
     <string name="wifi_metered_label" msgid="4514924227256839725">"கட்டண நெட்வொர்க்"</string>
     <string name="wifi_unmetered_label" msgid="6124098729457992931">"கட்டணமில்லா நெட்வொர்க்"</string>
     <string name="select_logd_size_title" msgid="7433137108348553508">"லாகர் பஃபர் அளவுகள்"</string>
diff --git a/packages/SettingsLib/res/values-te/strings.xml b/packages/SettingsLib/res/values-te/strings.xml
index d3dfda3..83636dc 100644
--- a/packages/SettingsLib/res/values-te/strings.xml
+++ b/packages/SettingsLib/res/values-te/strings.xml
@@ -220,6 +220,7 @@
     <string name="debug_networking_category" msgid="7044075693643009662">"నెట్‌వర్కింగ్"</string>
     <string name="wifi_display_certification" msgid="8611569543791307533">"వైర్‌లెస్ ప్రదర్శన ప్రామాణీకరణ"</string>
     <string name="wifi_verbose_logging" msgid="4203729756047242344">"Wi‑Fi విశదీకృత లాగింగ్‌ను ప్రారంభించండి"</string>
+    <string name="wifi_scan_throttling" msgid="160014287416479843">"Wi‑Fi స్కాన్ కుదింపు"</string>
     <string name="mobile_data_always_on" msgid="8774857027458200434">"మొబైల్ డేటాని ఎల్లప్పుడూ యాక్టివ్‌గా ఉంచు"</string>
     <string name="tethering_hardware_offload" msgid="7470077827090325814">"టెథెరింగ్ హార్డ్‌వేర్ వేగవృద్ధి"</string>
     <string name="bluetooth_show_devices_without_names" msgid="4708446092962060176">"పేర్లు లేని బ్లూటూత్ పరికరాలు  చూపించు"</string>
@@ -246,6 +247,7 @@
     <string name="private_dns_mode_provider_failure" msgid="231837290365031223">"కనెక్ట్ చేయడం సాధ్యపడలేదు"</string>
     <string name="wifi_display_certification_summary" msgid="1155182309166746973">"వైర్‌లెస్ ప్రదర్శన సర్టిఫికెట్ కోసం ఎంపికలను చూపు"</string>
     <string name="wifi_verbose_logging_summary" msgid="6615071616111731958">"Wi‑Fi ఎంపికలో SSID RSSI ప్రకారం చూపబడే Wi‑Fi లాగింగ్ స్థాయిని పెంచండి"</string>
+    <string name="wifi_scan_throttling_summary" msgid="4461922728822495763">"బ్యాటరీ శక్తి వినియోగాన్ని తగ్గించి &amp; నెట్‌వర్క్ పనితీరును మెరుగుపరుస్తుంది"</string>
     <string name="wifi_metered_label" msgid="4514924227256839725">"గణించబడుతోంది"</string>
     <string name="wifi_unmetered_label" msgid="6124098729457992931">"గణించబడటం లేదు"</string>
     <string name="select_logd_size_title" msgid="7433137108348553508">"లాగర్ బఫర్ పరిమాణాలు"</string>
diff --git a/packages/SettingsLib/res/values-th/strings.xml b/packages/SettingsLib/res/values-th/strings.xml
index 4f8b9e4..910b94e 100644
--- a/packages/SettingsLib/res/values-th/strings.xml
+++ b/packages/SettingsLib/res/values-th/strings.xml
@@ -220,6 +220,7 @@
     <string name="debug_networking_category" msgid="7044075693643009662">"เครือข่าย"</string>
     <string name="wifi_display_certification" msgid="8611569543791307533">"การรับรองการแสดงผลแบบไร้สาย"</string>
     <string name="wifi_verbose_logging" msgid="4203729756047242344">"เปิดใช้การบันทึกรายละเอียด Wi-Fi"</string>
+    <string name="wifi_scan_throttling" msgid="160014287416479843">"การควบคุมการสแกนหา Wi‑Fi"</string>
     <string name="mobile_data_always_on" msgid="8774857027458200434">"เปิดใช้เน็ตมือถือเสมอ"</string>
     <string name="tethering_hardware_offload" msgid="7470077827090325814">"การเร่งฮาร์ดแวร์การเชื่อมต่ออินเทอร์เน็ตผ่านมือถือ"</string>
     <string name="bluetooth_show_devices_without_names" msgid="4708446092962060176">"แสดงอุปกรณ์บลูทูธที่ไม่มีชื่อ"</string>
@@ -246,6 +247,7 @@
     <string name="private_dns_mode_provider_failure" msgid="231837290365031223">"เชื่อมต่อไม่ได้"</string>
     <string name="wifi_display_certification_summary" msgid="1155182309166746973">"แสดงตัวเลือกสำหรับการรับรองการแสดงผล แบบไร้สาย"</string>
     <string name="wifi_verbose_logging_summary" msgid="6615071616111731958">"เพิ่มระดับการบันทึก Wi‑Fi แสดงต่อ SSID RSSI ในตัวเลือก Wi‑Fi"</string>
+    <string name="wifi_scan_throttling_summary" msgid="4461922728822495763">"ลดการหมดเปลืองแบตเตอรี่และเพิ่มประสิทธิภาพเครือข่าย"</string>
     <string name="wifi_metered_label" msgid="4514924227256839725">"มีการวัดปริมาณอินเทอร์เน็ต"</string>
     <string name="wifi_unmetered_label" msgid="6124098729457992931">"ไม่มีการวัดปริมาณอินเทอร์เน็ต"</string>
     <string name="select_logd_size_title" msgid="7433137108348553508">"ขนาดบัฟเฟอร์ของตัวบันทึก"</string>
diff --git a/packages/SettingsLib/res/values-tl/strings.xml b/packages/SettingsLib/res/values-tl/strings.xml
index bc33509..85b6438 100644
--- a/packages/SettingsLib/res/values-tl/strings.xml
+++ b/packages/SettingsLib/res/values-tl/strings.xml
@@ -220,6 +220,7 @@
     <string name="debug_networking_category" msgid="7044075693643009662">"Networking"</string>
     <string name="wifi_display_certification" msgid="8611569543791307533">"Certification ng wireless display"</string>
     <string name="wifi_verbose_logging" msgid="4203729756047242344">"I-enable ang Pagla-log sa Wi‑Fi Verbose"</string>
+    <string name="wifi_scan_throttling" msgid="160014287416479843">"Pag-throttle ng pag-scan ng Wi‑Fi"</string>
     <string name="mobile_data_always_on" msgid="8774857027458200434">"Palaging aktibo ang mobile data"</string>
     <string name="tethering_hardware_offload" msgid="7470077827090325814">"Hardware acceleration para sa pag-tether"</string>
     <string name="bluetooth_show_devices_without_names" msgid="4708446092962060176">"Ipakita ang mga Bluetooth device na walang pangalan"</string>
@@ -246,6 +247,7 @@
     <string name="private_dns_mode_provider_failure" msgid="231837290365031223">"Hindi makakonekta"</string>
     <string name="wifi_display_certification_summary" msgid="1155182309166746973">"Ipakita ang mga opsyon para sa certification ng wireless display"</string>
     <string name="wifi_verbose_logging_summary" msgid="6615071616111731958">"Pataasin ang antas ng Wi‑Fi logging, ipakita sa bawat SSID RSSI sa Wi‑Fi Picker"</string>
+    <string name="wifi_scan_throttling_summary" msgid="4461922728822495763">"Binabawasan ang pagkaubos ng baterya at pinapahusay ang performance ng network"</string>
     <string name="wifi_metered_label" msgid="4514924227256839725">"Nakametro"</string>
     <string name="wifi_unmetered_label" msgid="6124098729457992931">"Hindi Nakametro"</string>
     <string name="select_logd_size_title" msgid="7433137108348553508">"Mga laki ng buffer ng Logger"</string>
diff --git a/packages/SettingsLib/res/values-tr/strings.xml b/packages/SettingsLib/res/values-tr/strings.xml
index 9c89b58..6031eca 100644
--- a/packages/SettingsLib/res/values-tr/strings.xml
+++ b/packages/SettingsLib/res/values-tr/strings.xml
@@ -220,6 +220,7 @@
     <string name="debug_networking_category" msgid="7044075693643009662">"Ağ işlemleri"</string>
     <string name="wifi_display_certification" msgid="8611569543791307533">"Kablosuz ekran sertifikası"</string>
     <string name="wifi_verbose_logging" msgid="4203729756047242344">"Kablosuz Ayrıntılı Günlük Kaydını etkinleştir"</string>
+    <string name="wifi_scan_throttling" msgid="160014287416479843">"Kablosuz ağ taramasını kısma"</string>
     <string name="mobile_data_always_on" msgid="8774857027458200434">"Mobil veri her zaman etkin"</string>
     <string name="tethering_hardware_offload" msgid="7470077827090325814">"Tethering donanım hızlandırıcısı"</string>
     <string name="bluetooth_show_devices_without_names" msgid="4708446092962060176">"Adsız Bluetooth cihazlarını göster"</string>
@@ -246,6 +247,7 @@
     <string name="private_dns_mode_provider_failure" msgid="231837290365031223">"Bağlanılamadı"</string>
     <string name="wifi_display_certification_summary" msgid="1155182309166746973">"Kablosuz ekran sertifikası seçeneklerini göster"</string>
     <string name="wifi_verbose_logging_summary" msgid="6615071616111731958">"Kablosuz günlük kaydı seviyesini artır. Kablosuz Seçici\'de her bir SSID RSSI için göster."</string>
+    <string name="wifi_scan_throttling_summary" msgid="4461922728822495763">"Pili daha az harcar ve ağ performansını iyileştirir"</string>
     <string name="wifi_metered_label" msgid="4514924227256839725">"Sayaçlı"</string>
     <string name="wifi_unmetered_label" msgid="6124098729457992931">"Sayaçsız"</string>
     <string name="select_logd_size_title" msgid="7433137108348553508">"Günlük Kaydedici arabellek boyutları"</string>
diff --git a/packages/SettingsLib/res/values-uk/strings.xml b/packages/SettingsLib/res/values-uk/strings.xml
index 278928b..5f3c6a6 100644
--- a/packages/SettingsLib/res/values-uk/strings.xml
+++ b/packages/SettingsLib/res/values-uk/strings.xml
@@ -220,6 +220,7 @@
     <string name="debug_networking_category" msgid="7044075693643009662">"Мережі"</string>
     <string name="wifi_display_certification" msgid="8611569543791307533">"Сертифікація бездрот. екрана"</string>
     <string name="wifi_verbose_logging" msgid="4203729756047242344">"Докладний запис у журнал Wi-Fi"</string>
+    <string name="wifi_scan_throttling" msgid="160014287416479843">"Зменшити радіус пошуку мереж Wi‑Fi"</string>
     <string name="mobile_data_always_on" msgid="8774857027458200434">"Не вимикати мобільне передавання даних"</string>
     <string name="tethering_hardware_offload" msgid="7470077827090325814">"Апаратне прискорення під час використання телефона в режимі модема"</string>
     <string name="bluetooth_show_devices_without_names" msgid="4708446092962060176">"Показувати пристрої Bluetooth без назв"</string>
@@ -246,6 +247,7 @@
     <string name="private_dns_mode_provider_failure" msgid="231837290365031223">"Не вдалося під’єднатися"</string>
     <string name="wifi_display_certification_summary" msgid="1155182309166746973">"Показати параметри сертифікації бездротового екрана"</string>
     <string name="wifi_verbose_logging_summary" msgid="6615071616111731958">"Показувати в журналі RSSI для кожного SSID під час вибору Wi-Fi"</string>
+    <string name="wifi_scan_throttling_summary" msgid="4461922728822495763">"Зменшує споживання заряду акумулятора й підвищує ефективність роботи мережі"</string>
     <string name="wifi_metered_label" msgid="4514924227256839725">"З тарифікацією трафіку"</string>
     <string name="wifi_unmetered_label" msgid="6124098729457992931">"Без тарифікації трафіку"</string>
     <string name="select_logd_size_title" msgid="7433137108348553508">"Розміри буфера журналу"</string>
diff --git a/packages/SettingsLib/res/values-ur/strings.xml b/packages/SettingsLib/res/values-ur/strings.xml
index 8ab1c23..82d9b3f 100644
--- a/packages/SettingsLib/res/values-ur/strings.xml
+++ b/packages/SettingsLib/res/values-ur/strings.xml
@@ -220,6 +220,7 @@
     <string name="debug_networking_category" msgid="7044075693643009662">"نیٹ ورکنگ"</string>
     <string name="wifi_display_certification" msgid="8611569543791307533">"وائرلیس ڈسپلے سرٹیفیکیشن"</string>
     <string name="wifi_verbose_logging" msgid="4203729756047242344">"‏Wi‑Fi وربوس لاگنگ فعال کریں"</string>
+    <string name="wifi_scan_throttling" msgid="160014287416479843">"‏Wi‑Fi اسکین کو زبردستی روکا جا رہا ہے"</string>
     <string name="mobile_data_always_on" msgid="8774857027458200434">"موبائل ڈیٹا ہمیشہ فعال رکھیں"</string>
     <string name="tethering_hardware_offload" msgid="7470077827090325814">"ٹیدرنگ ہارڈویئر سرعت کاری"</string>
     <string name="bluetooth_show_devices_without_names" msgid="4708446092962060176">"بغیر نام والے بلوٹوتھ آلات دکھائیں"</string>
@@ -246,6 +247,7 @@
     <string name="private_dns_mode_provider_failure" msgid="231837290365031223">"منسلک نہیں ہو سکا"</string>
     <string name="wifi_display_certification_summary" msgid="1155182309166746973">"وائرلیس ڈسپلے سرٹیفیکیشن کیلئے اختیارات دکھائیں"</string>
     <string name="wifi_verbose_logging_summary" msgid="6615071616111731958">"‏Wi‑Fi لاگنگ لیول میں اضافہ کریں، Wi‑Fi منتخب کنندہ میں فی SSID RSSI دکھائیں"</string>
+    <string name="wifi_scan_throttling_summary" msgid="4461922728822495763">"بیٹری ڈرین کم کرتا ہے اور نیٹ ورک کارکردگی کو بہتر بناتا ہے"</string>
     <string name="wifi_metered_label" msgid="4514924227256839725">"میٹرڈ"</string>
     <string name="wifi_unmetered_label" msgid="6124098729457992931">"غیر میٹر شدہ"</string>
     <string name="select_logd_size_title" msgid="7433137108348553508">"لاگر بفر کے سائز"</string>
diff --git a/packages/SettingsLib/res/values-uz/strings.xml b/packages/SettingsLib/res/values-uz/strings.xml
index 2bcb450..5dca475 100644
--- a/packages/SettingsLib/res/values-uz/strings.xml
+++ b/packages/SettingsLib/res/values-uz/strings.xml
@@ -220,6 +220,7 @@
     <string name="debug_networking_category" msgid="7044075693643009662">"Tarmoqlar"</string>
     <string name="wifi_display_certification" msgid="8611569543791307533">"Simsiz monitor sertifikatlari"</string>
     <string name="wifi_verbose_logging" msgid="4203729756047242344">"Batafsil Wi-Fi jurnali"</string>
+    <string name="wifi_scan_throttling" msgid="160014287416479843">"Wi‑Fi tarmoqni taqsimlab skanlash"</string>
     <string name="mobile_data_always_on" msgid="8774857027458200434">"Mobil internet doim yoniq tursin"</string>
     <string name="tethering_hardware_offload" msgid="7470077827090325814">"Modem rejimida apparatli tezlashtirish"</string>
     <string name="bluetooth_show_devices_without_names" msgid="4708446092962060176">"Bluetooth qurilmalarini nomlarisiz ko‘rsatish"</string>
@@ -246,6 +247,7 @@
     <string name="private_dns_mode_provider_failure" msgid="231837290365031223">"Ulanmadi"</string>
     <string name="wifi_display_certification_summary" msgid="1155182309166746973">"Simsiz monitorlarni sertifikatlash parametrini ko‘rsatish"</string>
     <string name="wifi_verbose_logging_summary" msgid="6615071616111731958">"Wi-Fi ulanishini tanlashda har bir SSID uchun jurnalda ko‘rsatilsin"</string>
+    <string name="wifi_scan_throttling_summary" msgid="4461922728822495763">"Batareya sarfini tejaydi va tarmoq samaradorligini oshiradi"</string>
     <string name="wifi_metered_label" msgid="4514924227256839725">"Trafik hisoblanadigan tarmoq"</string>
     <string name="wifi_unmetered_label" msgid="6124098729457992931">"Trafik hisobi yuritilmaydigan tarmoq"</string>
     <string name="select_logd_size_title" msgid="7433137108348553508">"Jurnal buferi hajmi"</string>
diff --git a/packages/SettingsLib/res/values-vi/strings.xml b/packages/SettingsLib/res/values-vi/strings.xml
index 26fa772..4e2d6fa 100644
--- a/packages/SettingsLib/res/values-vi/strings.xml
+++ b/packages/SettingsLib/res/values-vi/strings.xml
@@ -220,6 +220,7 @@
     <string name="debug_networking_category" msgid="7044075693643009662">"Mạng"</string>
     <string name="wifi_display_certification" msgid="8611569543791307533">"Chứng nhận hiển thị không dây"</string>
     <string name="wifi_verbose_logging" msgid="4203729756047242344">"Bật ghi nhật ký chi tiết Wi‑Fi"</string>
+    <string name="wifi_scan_throttling" msgid="160014287416479843">"Hạn chế quét tìm Wi-Fi"</string>
     <string name="mobile_data_always_on" msgid="8774857027458200434">"Dữ liệu di động luôn hoạt động"</string>
     <string name="tethering_hardware_offload" msgid="7470077827090325814">"Tăng tốc phần cứng khi chia sẻ kết nối"</string>
     <string name="bluetooth_show_devices_without_names" msgid="4708446092962060176">"Hiển thị các thiết bị Bluetooth không có tên"</string>
@@ -246,6 +247,7 @@
     <string name="private_dns_mode_provider_failure" msgid="231837290365031223">"Không thể kết nối"</string>
     <string name="wifi_display_certification_summary" msgid="1155182309166746973">"Hiển thị tùy chọn chứng nhận hiển thị không dây"</string>
     <string name="wifi_verbose_logging_summary" msgid="6615071616111731958">"Tăng mức ghi nhật ký Wi‑Fi, hiển thị mỗi SSID RSSI trong bộ chọn Wi‑Fi"</string>
+    <string name="wifi_scan_throttling_summary" msgid="4461922728822495763">"Giảm hao pin và cải thiện hiệu suất mạng"</string>
     <string name="wifi_metered_label" msgid="4514924227256839725">"Đo lượng dữ liệu"</string>
     <string name="wifi_unmetered_label" msgid="6124098729457992931">"Không đo lượng dữ liệu"</string>
     <string name="select_logd_size_title" msgid="7433137108348553508">"Kích thước bộ đệm của trình ghi nhật ký"</string>
diff --git a/packages/SettingsLib/res/values-zh-rCN/strings.xml b/packages/SettingsLib/res/values-zh-rCN/strings.xml
index 8685c10..460142c 100644
--- a/packages/SettingsLib/res/values-zh-rCN/strings.xml
+++ b/packages/SettingsLib/res/values-zh-rCN/strings.xml
@@ -220,6 +220,7 @@
     <string name="debug_networking_category" msgid="7044075693643009662">"网络"</string>
     <string name="wifi_display_certification" msgid="8611569543791307533">"无线显示认证"</string>
     <string name="wifi_verbose_logging" msgid="4203729756047242344">"启用 WLAN 详细日志记录功能"</string>
+    <string name="wifi_scan_throttling" msgid="160014287416479843">"WLAN 扫描调节"</string>
     <string name="mobile_data_always_on" msgid="8774857027458200434">"始终开启移动数据网络"</string>
     <string name="tethering_hardware_offload" msgid="7470077827090325814">"网络共享硬件加速"</string>
     <string name="bluetooth_show_devices_without_names" msgid="4708446092962060176">"显示没有名称的蓝牙设备"</string>
@@ -246,6 +247,7 @@
     <string name="private_dns_mode_provider_failure" msgid="231837290365031223">"无法连接"</string>
     <string name="wifi_display_certification_summary" msgid="1155182309166746973">"显示无线显示认证选项"</string>
     <string name="wifi_verbose_logging_summary" msgid="6615071616111731958">"提升 WLAN 日志记录级别(在 WLAN 选择器中显示每个 SSID 的 RSSI)"</string>
+    <string name="wifi_scan_throttling_summary" msgid="4461922728822495763">"降低耗电量以及改善网络性能"</string>
     <string name="wifi_metered_label" msgid="4514924227256839725">"按流量计费"</string>
     <string name="wifi_unmetered_label" msgid="6124098729457992931">"不按流量计费"</string>
     <string name="select_logd_size_title" msgid="7433137108348553508">"日志记录器缓冲区大小"</string>
diff --git a/packages/SettingsLib/res/values-zh-rHK/strings.xml b/packages/SettingsLib/res/values-zh-rHK/strings.xml
index 9cc87bd..286765d 100644
--- a/packages/SettingsLib/res/values-zh-rHK/strings.xml
+++ b/packages/SettingsLib/res/values-zh-rHK/strings.xml
@@ -220,6 +220,7 @@
     <string name="debug_networking_category" msgid="7044075693643009662">"網絡"</string>
     <string name="wifi_display_certification" msgid="8611569543791307533">"無線螢幕分享認證"</string>
     <string name="wifi_verbose_logging" msgid="4203729756047242344">"啟用 Wi‑Fi 詳細記錄"</string>
+    <string name="wifi_scan_throttling" msgid="160014287416479843">"Wi‑Fi 掃瞄限流"</string>
     <string name="mobile_data_always_on" msgid="8774857027458200434">"一律保持啟用流動數據"</string>
     <string name="tethering_hardware_offload" msgid="7470077827090325814">"網絡共享硬件加速"</string>
     <string name="bluetooth_show_devices_without_names" msgid="4708446092962060176">"顯示沒有名稱的藍牙裝置"</string>
@@ -246,6 +247,7 @@
     <string name="private_dns_mode_provider_failure" msgid="231837290365031223">"無法連線"</string>
     <string name="wifi_display_certification_summary" msgid="1155182309166746973">"顯示無線螢幕分享認證的選項"</string>
     <string name="wifi_verbose_logging_summary" msgid="6615071616111731958">"讓 Wi‑Fi 記錄功能升級,在 Wi‑Fi 選擇器中依每個 SSID RSSI 顯示 Wi‑Fi 詳細紀錄"</string>
+    <string name="wifi_scan_throttling_summary" msgid="4461922728822495763">"減低耗電量並改善網絡表現"</string>
     <string name="wifi_metered_label" msgid="4514924227256839725">"按用量收費"</string>
     <string name="wifi_unmetered_label" msgid="6124098729457992931">"不限數據用量收費"</string>
     <string name="select_logd_size_title" msgid="7433137108348553508">"記錄器緩衝區空間"</string>
diff --git a/packages/SettingsLib/res/values-zh-rTW/strings.xml b/packages/SettingsLib/res/values-zh-rTW/strings.xml
index 1201938..e85199f 100644
--- a/packages/SettingsLib/res/values-zh-rTW/strings.xml
+++ b/packages/SettingsLib/res/values-zh-rTW/strings.xml
@@ -220,6 +220,7 @@
     <string name="debug_networking_category" msgid="7044075693643009662">"網路連線"</string>
     <string name="wifi_display_certification" msgid="8611569543791307533">"無線螢幕分享認證"</string>
     <string name="wifi_verbose_logging" msgid="4203729756047242344">"啟用 Wi‑Fi 詳細記錄設定"</string>
+    <string name="wifi_scan_throttling" msgid="160014287416479843">"Wi-Fi 掃描調節"</string>
     <string name="mobile_data_always_on" msgid="8774857027458200434">"行動數據連線一律保持啟用狀態"</string>
     <string name="tethering_hardware_offload" msgid="7470077827090325814">"數據連線硬體加速"</string>
     <string name="bluetooth_show_devices_without_names" msgid="4708446092962060176">"顯示沒有名稱的藍牙裝置"</string>
@@ -246,6 +247,7 @@
     <string name="private_dns_mode_provider_failure" msgid="231837290365031223">"無法連線"</string>
     <string name="wifi_display_certification_summary" msgid="1155182309166746973">"顯示無線螢幕分享認證的選項"</string>
     <string name="wifi_verbose_logging_summary" msgid="6615071616111731958">"讓 Wi‑Fi 記錄功能升級,在 Wi‑Fi 選擇器中依每個 SSID RSSI 顯示 Wi‑Fi 詳細記錄"</string>
+    <string name="wifi_scan_throttling_summary" msgid="4461922728822495763">"降低耗電量以及改善網路效能"</string>
     <string name="wifi_metered_label" msgid="4514924227256839725">"計量付費"</string>
     <string name="wifi_unmetered_label" msgid="6124098729457992931">"非計量付費"</string>
     <string name="select_logd_size_title" msgid="7433137108348553508">"記錄器緩衝區空間"</string>
diff --git a/packages/SettingsLib/res/values-zu/strings.xml b/packages/SettingsLib/res/values-zu/strings.xml
index 9ea73fa..1bfbf07 100644
--- a/packages/SettingsLib/res/values-zu/strings.xml
+++ b/packages/SettingsLib/res/values-zu/strings.xml
@@ -220,6 +220,7 @@
     <string name="debug_networking_category" msgid="7044075693643009662">"Ukunethiwekha"</string>
     <string name="wifi_display_certification" msgid="8611569543791307533">"Ukunikezwa isitifiketi sokubukeka okungenantambo"</string>
     <string name="wifi_verbose_logging" msgid="4203729756047242344">"Nika amandlaukungena kwe-Wi-Fi Verbose"</string>
+    <string name="wifi_scan_throttling" msgid="160014287416479843">"I-throttling yokuskena kwe-Wi-Fi"</string>
     <string name="mobile_data_always_on" msgid="8774857027458200434">"Idatha yeselula ihlala isebenza"</string>
     <string name="tethering_hardware_offload" msgid="7470077827090325814">"I-Tethering hardware acceleration"</string>
     <string name="bluetooth_show_devices_without_names" msgid="4708446092962060176">"Bonisa amadivayisi e-Bluetooth ngaphandle kwamagama"</string>
@@ -246,6 +247,7 @@
     <string name="private_dns_mode_provider_failure" msgid="231837290365031223">"Ayikwazanga ukuxhuma"</string>
     <string name="wifi_display_certification_summary" msgid="1155182309166746973">"Bonisa izinketho zokunikeza isitifiketi ukubukeka okungenantambo"</string>
     <string name="wifi_verbose_logging_summary" msgid="6615071616111731958">"khuphula izinga lokungena le-Wi-Fi, bonisa nge-SSID RSSI engayodwana kusikhethi se-Wi-Fi"</string>
+    <string name="wifi_scan_throttling_summary" msgid="4461922728822495763">"Yehlisa ukuphela kwebhethri futhi ithuthukise ukusebenza kwenethiwekhi"</string>
     <string name="wifi_metered_label" msgid="4514924227256839725">"Kulinganisiwe"</string>
     <string name="wifi_unmetered_label" msgid="6124098729457992931">"Akulinganiselwa"</string>
     <string name="select_logd_size_title" msgid="7433137108348553508">"Amasayizi weloga ngebhafa"</string>
diff --git a/packages/SettingsLib/src/com/android/settingslib/graph/SignalDrawable.java b/packages/SettingsLib/src/com/android/settingslib/graph/SignalDrawable.java
index 98eb573..c7380c58 100644
--- a/packages/SettingsLib/src/com/android/settingslib/graph/SignalDrawable.java
+++ b/packages/SettingsLib/src/com/android/settingslib/graph/SignalDrawable.java
@@ -132,6 +132,7 @@
         super.onLevelChange(unpackLevel(packedState));
         updateAnimation();
         setTintList(ColorStateList.valueOf(mForegroundPaint.getColor()));
+        invalidateSelf();
         return true;
     }
 
diff --git a/packages/SettingsLib/src/com/android/settingslib/net/DataUsageController.java b/packages/SettingsLib/src/com/android/settingslib/net/DataUsageController.java
index f30de13..ea3c1d9 100644
--- a/packages/SettingsLib/src/com/android/settingslib/net/DataUsageController.java
+++ b/packages/SettingsLib/src/com/android/settingslib/net/DataUsageController.java
@@ -110,13 +110,7 @@
     }
 
     public DataUsageInfo getDataUsageInfo() {
-        final String subscriberId = getActiveSubscriberId();
-        if (subscriberId == null) {
-            return warn("no subscriber id");
-        }
-        NetworkTemplate template = NetworkTemplate.buildTemplateMobileAll(subscriberId);
-        template = NetworkTemplate.normalize(template, getTelephonyManager()
-                .getMergedSubscriberIds());
+        NetworkTemplate template = DataUsageUtils.getMobileTemplate(mContext, mSubscriptionId);
 
         return getDataUsageInfo(template);
     }
diff --git a/packages/SettingsLib/src/com/android/settingslib/net/DataUsageUtils.java b/packages/SettingsLib/src/com/android/settingslib/net/DataUsageUtils.java
new file mode 100644
index 0000000..de38e8a
--- /dev/null
+++ b/packages/SettingsLib/src/com/android/settingslib/net/DataUsageUtils.java
@@ -0,0 +1,71 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.settingslib.net;
+
+import android.content.Context;
+import android.net.NetworkTemplate;
+import android.os.ParcelUuid;
+import android.telephony.SubscriptionInfo;
+import android.telephony.SubscriptionManager;
+import android.telephony.TelephonyManager;
+import android.util.Log;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * Utils class for data usage
+ */
+public class DataUsageUtils {
+    private static final String TAG = "DataUsageUtils";
+
+    /**
+     * Return mobile NetworkTemplate based on {@code subId}
+     */
+    public static NetworkTemplate getMobileTemplate(Context context, int subId) {
+        final TelephonyManager telephonyManager = context.getSystemService(
+                TelephonyManager.class);
+        final SubscriptionManager subscriptionManager = context.getSystemService(
+                SubscriptionManager.class);
+        final SubscriptionInfo info = subscriptionManager.getActiveSubscriptionInfo(subId);
+        final NetworkTemplate mobileAll = NetworkTemplate.buildTemplateMobileAll(
+                telephonyManager.getSubscriberId(subId));
+
+        if (info == null) {
+            Log.i(TAG, "Subscription is not active: " + subId);
+            return mobileAll;
+        }
+        final ParcelUuid groupUuid = info.getGroupUuid();
+        if (groupUuid == null) {
+            Log.i(TAG, "Subscription doesn't have valid group uuid: " + subId);
+            return mobileAll;
+        }
+
+        // Otherwise merge other subscriberId to create new NetworkTemplate
+        final List<SubscriptionInfo> groupInfos = subscriptionManager.getSubscriptionsInGroup(
+                groupUuid);
+        final List<String> mergedSubscriberIds = new ArrayList<>();
+        for (SubscriptionInfo subInfo : groupInfos) {
+            final String subscriberId = telephonyManager.getSubscriberId(
+                    subInfo.getSubscriptionId());
+            if (subscriberId != null) {
+                mergedSubscriberIds.add(subscriberId);
+            }
+        }
+        return NetworkTemplate.normalize(mobileAll, mergedSubscriberIds.toArray(new String[0]));
+    }
+}
diff --git a/packages/SettingsLib/src/com/android/settingslib/wifi/AccessPoint.java b/packages/SettingsLib/src/com/android/settingslib/wifi/AccessPoint.java
index e28c612..ab174f4 100644
--- a/packages/SettingsLib/src/com/android/settingslib/wifi/AccessPoint.java
+++ b/packages/SettingsLib/src/com/android/settingslib/wifi/AccessPoint.java
@@ -55,6 +55,7 @@
 import android.util.Log;
 import android.util.Pair;
 
+import androidx.annotation.GuardedBy;
 import androidx.annotation.NonNull;
 
 import com.android.internal.annotations.VisibleForTesting;
@@ -108,6 +109,14 @@
     /** The key which identifies this AccessPoint grouping. */
     private String mKey;
 
+    /**
+     * Synchronization lock for managing concurrency between main and worker threads.
+     *
+     * <p>This lock should be held for all modifications to {@link #mScanResults} and
+     * {@link #mExtraScanResults}.
+     */
+    private final Object mLock = new Object();
+
     @IntDef({Speed.NONE, Speed.SLOW, Speed.MODERATE, Speed.FAST, Speed.VERY_FAST})
     @Retention(RetentionPolicy.SOURCE)
     public @interface Speed {
@@ -134,12 +143,14 @@
     }
 
     /** The underlying set of scan results comprising this AccessPoint. */
+    @GuardedBy("mLock")
     private final ArraySet<ScanResult> mScanResults = new ArraySet<>();
 
     /**
      * Extra set of unused scan results corresponding to this AccessPoint for verbose logging
      * purposes, such as a set of Passpoint roaming scan results when home scans are available.
      */
+    @GuardedBy("mLock")
     private final ArraySet<ScanResult> mExtraScanResults = new ArraySet<>();
 
     /**
@@ -489,8 +500,10 @@
 
         if (isVerboseLoggingEnabled()) {
             builder.append(",rssi=").append(mRssi);
-            builder.append(",scan cache size=").append(mScanResults.size()
-                    + mExtraScanResults.size());
+            synchronized (mLock) {
+                builder.append(",scan cache size=").append(mScanResults.size()
+                        + mExtraScanResults.size());
+            }
         }
 
         return builder.append(')').toString();
@@ -532,18 +545,20 @@
      */
     private boolean updateScores(WifiNetworkScoreCache scoreCache, long maxScoreCacheAgeMillis) {
         long nowMillis = SystemClock.elapsedRealtime();
-        for (ScanResult result : mScanResults) {
-            ScoredNetwork score = scoreCache.getScoredNetwork(result);
-            if (score == null) {
-                continue;
-            }
-            TimestampedScoredNetwork timedScore = mScoredNetworkCache.get(result.BSSID);
-            if (timedScore == null) {
-                mScoredNetworkCache.put(
-                        result.BSSID, new TimestampedScoredNetwork(score, nowMillis));
-            } else {
-                // Update data since the has been seen in the score cache
-                timedScore.update(score, nowMillis);
+        synchronized (mLock) {
+            for (ScanResult result : mScanResults) {
+                ScoredNetwork score = scoreCache.getScoredNetwork(result);
+                if (score == null) {
+                    continue;
+                }
+                TimestampedScoredNetwork timedScore = mScoredNetworkCache.get(result.BSSID);
+                if (timedScore == null) {
+                    mScoredNetworkCache.put(
+                            result.BSSID, new TimestampedScoredNetwork(score, nowMillis));
+                } else {
+                    // Update data since the has been seen in the score cache
+                    timedScore.update(score, nowMillis);
+                }
             }
         }
 
@@ -619,12 +634,14 @@
                 mIsScoredNetworkMetered |= score.meteredHint;
             }
         } else {
-            for (ScanResult result : mScanResults) {
-                ScoredNetwork score = scoreCache.getScoredNetwork(result);
-                if (score == null) {
-                    continue;
+            synchronized (mLock) {
+                for (ScanResult result : mScanResults) {
+                    ScoredNetwork score = scoreCache.getScoredNetwork(result);
+                    if (score == null) {
+                        continue;
+                    }
+                    mIsScoredNetworkMetered |= score.meteredHint;
                 }
-                mIsScoredNetworkMetered |= score.meteredHint;
             }
         }
         return oldMetering == mIsScoredNetworkMetered;
@@ -741,8 +758,10 @@
      */
     public Set<ScanResult> getScanResults() {
         Set<ScanResult> allScans = new ArraySet<>();
-        allScans.addAll(mScanResults);
-        allScans.addAll(mExtraScanResults);
+        synchronized (mLock) {
+            allScans.addAll(mScanResults);
+            allScans.addAll(mExtraScanResults);
+        }
         return allScans;
     }
 
@@ -766,10 +785,12 @@
 
         ScanResult bestResult = null;
         int bestRssi = UNREACHABLE_RSSI;
-        for (ScanResult result : mScanResults) {
-            if (result.level > bestRssi) {
-                bestRssi = result.level;
-                bestResult = result;
+        synchronized (mLock) {
+            for (ScanResult result : mScanResults) {
+                if (result.level > bestRssi) {
+                    bestRssi = result.level;
+                    bestResult = result;
+                }
             }
         }
 
@@ -999,8 +1020,7 @@
                 summary.append(mContext.getString(R.string.tap_to_sign_up));
             }
         } else if (isActive()) {
-            if (mConfig != null && getDetailedState() == DetailedState.CONNECTED
-                    && mIsCarrierAp) {
+            if (getDetailedState() == DetailedState.CONNECTED && mIsCarrierAp) {
                 // This is the active connection on a carrier AP
                 summary.append(String.format(mContext.getString(R.string.connected_via_carrier),
                         mCarrierName));
@@ -1211,9 +1231,11 @@
         savedState.putInt(KEY_EAPTYPE, mEapType);
         if (mConfig != null) savedState.putParcelable(KEY_CONFIG, mConfig);
         savedState.putParcelable(KEY_WIFIINFO, mInfo);
-        savedState.putParcelableArray(KEY_SCANRESULTS,
-                mScanResults.toArray(new Parcelable[mScanResults.size()
-                        + mExtraScanResults.size()]));
+        synchronized (mLock) {
+            savedState.putParcelableArray(KEY_SCANRESULTS,
+                    mScanResults.toArray(new Parcelable[mScanResults.size()
+                            + mExtraScanResults.size()]));
+        }
         savedState.putParcelableArrayList(KEY_SCOREDNETWORKCACHE,
                 new ArrayList<>(mScoredNetworkCache.values()));
         if (mNetworkInfo != null) {
@@ -1292,8 +1314,10 @@
         }
 
         int oldLevel = getLevel();
-        mScanResults.clear();
-        mScanResults.addAll(scanResults);
+        synchronized (mLock) {
+            mScanResults.clear();
+            mScanResults.addAll(scanResults);
+        }
         updateBestRssiInfo();
         int newLevel = getLevel();
 
@@ -1324,16 +1348,18 @@
     void setScanResultsPasspoint(
             @Nullable Collection<ScanResult> homeScans,
             @Nullable Collection<ScanResult> roamingScans) {
-        mExtraScanResults.clear();
-        if (!CollectionUtils.isEmpty(homeScans)) {
-            if (!CollectionUtils.isEmpty(roamingScans)) {
-                mExtraScanResults.addAll(roamingScans);
+        synchronized (mLock) {
+            mExtraScanResults.clear();
+            if (!CollectionUtils.isEmpty(homeScans)) {
+                mIsRoaming = false;
+                if (!CollectionUtils.isEmpty(roamingScans)) {
+                    mExtraScanResults.addAll(roamingScans);
+                }
+                setScanResults(homeScans);
+            } else if (!CollectionUtils.isEmpty(roamingScans)) {
+                mIsRoaming = true;
+                setScanResults(roamingScans);
             }
-            mIsRoaming = false;
-            setScanResults(homeScans);
-        } else if (!CollectionUtils.isEmpty(roamingScans)) {
-            mIsRoaming = true;
-            setScanResults(roamingScans);
         }
     }
 
diff --git a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/net/DataUsageUtilsTest.java b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/net/DataUsageUtilsTest.java
new file mode 100644
index 0000000..dc33cfe
--- /dev/null
+++ b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/net/DataUsageUtilsTest.java
@@ -0,0 +1,110 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.settingslib.net;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import static org.mockito.Mockito.spy;
+import static org.mockito.Mockito.when;
+
+import android.content.Context;
+import android.net.NetworkTemplate;
+import android.os.ParcelUuid;
+import android.os.RemoteException;
+import android.telephony.SubscriptionInfo;
+import android.telephony.SubscriptionManager;
+import android.telephony.TelephonyManager;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
+import org.robolectric.RobolectricTestRunner;
+import org.robolectric.RuntimeEnvironment;
+
+import java.util.ArrayList;
+import java.util.List;
+
+@RunWith(RobolectricTestRunner.class)
+public class DataUsageUtilsTest {
+
+    private static final int SUB_ID = 1;
+    private static final int SUB_ID_2 = 2;
+    private static final String SUBSCRIBER_ID = "Test Subscriber";
+    private static final String SUBSCRIBER_ID_2 = "Test Subscriber 2";
+
+    @Mock
+    private TelephonyManager mTelephonyManager;
+    @Mock
+    private SubscriptionManager mSubscriptionManager;
+    @Mock
+    private SubscriptionInfo mInfo1;
+    @Mock
+    private SubscriptionInfo mInfo2;
+    @Mock
+    private ParcelUuid mParcelUuid;
+    private Context mContext;
+    private List<SubscriptionInfo> mInfos;
+
+    @Before
+    public void setUp() throws RemoteException {
+        MockitoAnnotations.initMocks(this);
+
+        mContext = spy(RuntimeEnvironment.application);
+        when(mContext.getSystemService(TelephonyManager.class)).thenReturn(mTelephonyManager);
+        when(mContext.getSystemService(SubscriptionManager.class)).thenReturn(mSubscriptionManager);
+        when(mTelephonyManager.getSubscriberId(SUB_ID)).thenReturn(SUBSCRIBER_ID);
+        when(mTelephonyManager.getSubscriberId(SUB_ID_2)).thenReturn(SUBSCRIBER_ID_2);
+        when(mInfo1.getSubscriptionId()).thenReturn(SUB_ID);
+        when(mInfo2.getSubscriptionId()).thenReturn(SUB_ID_2);
+
+        mInfos = new ArrayList<>();
+        mInfos.add(mInfo1);
+        mInfos.add(mInfo2);
+        when(mSubscriptionManager.getSubscriptionsInGroup(mParcelUuid)).thenReturn(mInfos);
+    }
+
+    @Test
+    public void getMobileTemplate_infoNull_returnMobileAll() {
+        when(mSubscriptionManager.getActiveSubscriptionInfo(SUB_ID)).thenReturn(null);
+
+        final NetworkTemplate networkTemplate = DataUsageUtils.getMobileTemplate(mContext, SUB_ID);
+        assertThat(networkTemplate.matchesSubscriberId(SUBSCRIBER_ID)).isTrue();
+        assertThat(networkTemplate.matchesSubscriberId(SUBSCRIBER_ID_2)).isFalse();
+    }
+
+    @Test
+    public void getMobileTemplate_groupUuidNull_returnMobileAll() {
+        when(mSubscriptionManager.getActiveSubscriptionInfo(SUB_ID)).thenReturn(mInfo1);
+        when(mInfo1.getGroupUuid()).thenReturn(null);
+
+        final NetworkTemplate networkTemplate = DataUsageUtils.getMobileTemplate(mContext, SUB_ID);
+        assertThat(networkTemplate.matchesSubscriberId(SUBSCRIBER_ID)).isTrue();
+        assertThat(networkTemplate.matchesSubscriberId(SUBSCRIBER_ID_2)).isFalse();
+    }
+
+    @Test
+    public void getMobileTemplate_groupUuidExist_returnMobileMerged() {
+        when(mSubscriptionManager.getActiveSubscriptionInfo(SUB_ID)).thenReturn(mInfo1);
+        when(mInfo1.getGroupUuid()).thenReturn(mParcelUuid);
+
+        final NetworkTemplate networkTemplate = DataUsageUtils.getMobileTemplate(mContext, SUB_ID);
+        assertThat(networkTemplate.matchesSubscriberId(SUBSCRIBER_ID)).isTrue();
+        assertThat(networkTemplate.matchesSubscriberId(SUBSCRIBER_ID_2)).isTrue();
+    }
+}
diff --git a/packages/SettingsProvider/src/com/android/providers/settings/SettingsProtoDumpUtil.java b/packages/SettingsProvider/src/com/android/providers/settings/SettingsProtoDumpUtil.java
index 636808e..3cd82df 100644
--- a/packages/SettingsProvider/src/com/android/providers/settings/SettingsProtoDumpUtil.java
+++ b/packages/SettingsProvider/src/com/android/providers/settings/SettingsProtoDumpUtil.java
@@ -716,6 +716,9 @@
                 Settings.Global.GAME_DRIVER_OPT_IN_APPS,
                 GlobalSettingsProto.Gpu.GAME_DRIVER_OPT_IN_APPS);
         dumpSetting(s, p,
+                Settings.Global.GAME_DRIVER_PRERELEASE_OPT_IN_APPS,
+                GlobalSettingsProto.Gpu.GAME_DRIVER_PRERELEASE_OPT_IN_APPS);
+        dumpSetting(s, p,
                 Settings.Global.GAME_DRIVER_OPT_OUT_APPS,
                 GlobalSettingsProto.Gpu.GAME_DRIVER_OPT_OUT_APPS);
         dumpSetting(s, p,
diff --git a/packages/SystemUI/AndroidManifest.xml b/packages/SystemUI/AndroidManifest.xml
index 7db8969..4b4912c 100644
--- a/packages/SystemUI/AndroidManifest.xml
+++ b/packages/SystemUI/AndroidManifest.xml
@@ -222,6 +222,9 @@
     <!-- to change themes - light or dark -->
     <uses-permission android:name="android.permission.CHANGE_OVERLAY_PACKAGES" />
 
+    <!-- Listen app op changes -->
+    <uses-permission android:name="android.permission.WATCH_APPOPS" />
+
     <!-- to read and change hvac values in a car -->
     <uses-permission android:name="android.car.permission.CONTROL_CAR_CLIMATE" />
 
diff --git a/packages/SystemUI/legacy/recents/res/values-de/strings.xml b/packages/SystemUI/legacy/recents/res/values-de/strings.xml
index 97a6366..4a089bf 100644
--- a/packages/SystemUI/legacy/recents/res/values-de/strings.xml
+++ b/packages/SystemUI/legacy/recents/res/values-de/strings.xml
@@ -28,7 +28,7 @@
     <string name="recents_empty_message" msgid="7967713254531861311">"Keine kürzlich verwendeten Elemente"</string>
     <string name="recents_empty_message_dismissed_all" msgid="1850214584987361375">"Du hast alles gelöscht"</string>
     <string name="recents_app_info_button_label" msgid="8732926607391786762">"App-Info"</string>
-    <string name="recents_lock_to_app_button_label" msgid="6087750201863853365">"Bildschirmfixierung"</string>
+    <string name="recents_lock_to_app_button_label" msgid="6087750201863853365">"Bildschirm anpinnen"</string>
     <string name="recents_search_bar_label" msgid="638132045925945941">"Suchen"</string>
     <string name="recents_launch_error_message" msgid="9107963563503438012">"<xliff:g id="APP">%s</xliff:g> konnte nicht gestartet werden."</string>
     <string name="recents_launch_disabled_message" msgid="826461671965217243">"<xliff:g id="APP">%s</xliff:g> ist im abgesicherten Modus deaktiviert."</string>
diff --git a/packages/SystemUI/legacy/recents/res/values-es/strings.xml b/packages/SystemUI/legacy/recents/res/values-es/strings.xml
index 43fb3ad..8bcfe84 100644
--- a/packages/SystemUI/legacy/recents/res/values-es/strings.xml
+++ b/packages/SystemUI/legacy/recents/res/values-es/strings.xml
@@ -28,7 +28,7 @@
     <string name="recents_empty_message" msgid="7967713254531861311">"No hay elementos recientes"</string>
     <string name="recents_empty_message_dismissed_all" msgid="1850214584987361375">"Has borrado todo"</string>
     <string name="recents_app_info_button_label" msgid="8732926607391786762">"Información de la aplicación"</string>
-    <string name="recents_lock_to_app_button_label" msgid="6087750201863853365">"fijación de pantalla"</string>
+    <string name="recents_lock_to_app_button_label" msgid="6087750201863853365">"fijar pantalla"</string>
     <string name="recents_search_bar_label" msgid="638132045925945941">"buscar"</string>
     <string name="recents_launch_error_message" msgid="9107963563503438012">"No se ha podido iniciar la aplicación <xliff:g id="APP">%s</xliff:g>."</string>
     <string name="recents_launch_disabled_message" msgid="826461671965217243">"La aplicación <xliff:g id="APP">%s</xliff:g> se ha inhabilitado en modo seguro."</string>
diff --git a/packages/SystemUI/legacy/recents/src/com/android/systemui/recents/RecentsActivity.java b/packages/SystemUI/legacy/recents/src/com/android/systemui/recents/RecentsActivity.java
index 79c691c..a7ccc3a 100644
--- a/packages/SystemUI/legacy/recents/src/com/android/systemui/recents/RecentsActivity.java
+++ b/packages/SystemUI/legacy/recents/src/com/android/systemui/recents/RecentsActivity.java
@@ -323,7 +323,7 @@
         mColorExtractor = Dependency.get(SysuiColorExtractor.class);
         mColorExtractor.addOnColorsChangedListener(this);
         mUsingDarkText = mColorExtractor.getColors(ColorExtractor.TYPE_DARK,
-                WallpaperManager.FLAG_SYSTEM, true).supportsDarkText();
+                WallpaperManager.FLAG_SYSTEM).supportsDarkText();
         setTheme(mUsingDarkText ? R.style.RecentsTheme_Wallpaper_Light
                 : R.style.RecentsTheme_Wallpaper);
 
@@ -394,8 +394,6 @@
     @Override
     public void onColorsChanged(ColorExtractor colorExtractor, int which) {
         if ((which & WallpaperManager.FLAG_SYSTEM) != 0) {
-            // Recents doesn't care about the wallpaper being visible or not, it always
-            // wants to scrim with wallpaper colors
             ColorExtractor.GradientColors colors = mColorExtractor.getNeutralColors();
             boolean darkText = colors.supportsDarkText();
             if (darkText != mUsingDarkText) {
diff --git a/packages/SystemUI/res-keyguard/values/styles.xml b/packages/SystemUI/res-keyguard/values/styles.xml
index 9a04222..67c4458 100644
--- a/packages/SystemUI/res-keyguard/values/styles.xml
+++ b/packages/SystemUI/res-keyguard/values/styles.xml
@@ -111,7 +111,7 @@
         <item name="android:colorBackground">@*android:color/background_material_dark</item>
     </style>
 
-    <style name="TextAppearance.Keyguard" parent="Theme.SystemUI">
+    <style name="TextAppearance.Keyguard">
         <item name="android:textSize">@dimen/widget_title_font_size</item>
         <item name="android:gravity">center</item>
         <item name="android:ellipsize">end</item>
diff --git a/packages/SystemUI/res/drawable/privacy_chip_bg.xml b/packages/SystemUI/res/drawable/privacy_chip_bg.xml
deleted file mode 100644
index b7b21fa..0000000
--- a/packages/SystemUI/res/drawable/privacy_chip_bg.xml
+++ /dev/null
@@ -1,23 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-     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.
--->
-
-<shape xmlns:android="http://schemas.android.com/apk/res/android">
-    <solid android:color="#242424" /> <!-- 14% of white -->
-    <padding android:paddingTop="@dimen/ongoing_appops_chip_bg_padding"
-        android:paddingBottom="@dimen/ongoing_appops_chip_bg_padding" />
-    <corners android:radius="@dimen/ongoing_appops_chip_bg_corner_radius" />
-</shape>
\ No newline at end of file
diff --git a/packages/SystemUI/res/layout/notif_half_shelf.xml b/packages/SystemUI/res/layout/notif_half_shelf.xml
index a563bb5..26c8872 100644
--- a/packages/SystemUI/res/layout/notif_half_shelf.xml
+++ b/packages/SystemUI/res/layout/notif_half_shelf.xml
@@ -69,7 +69,7 @@
 
                 <Switch
                     android:id="@+id/toggle"
-                    android:layout_height="wrap_content"
+                    android:layout_height="48dp"
                     android:layout_width="wrap_content"
                     android:layout_gravity="center_vertical"
                     android:padding="8dp" />
diff --git a/packages/SystemUI/res/layout/notif_half_shelf_row.xml b/packages/SystemUI/res/layout/notif_half_shelf_row.xml
index 1b80455..b95d5e9 100644
--- a/packages/SystemUI/res/layout/notif_half_shelf_row.xml
+++ b/packages/SystemUI/res/layout/notif_half_shelf_row.xml
@@ -71,7 +71,7 @@
 
     <Switch
         android:id="@+id/toggle"
-        android:layout_height="wrap_content"
+        android:layout_height="48dp"
         android:layout_width="wrap_content"
         android:layout_gravity="center_vertical"
         android:padding="8dp"
diff --git a/packages/SystemUI/res/layout/ongoing_privacy_chip.xml b/packages/SystemUI/res/layout/ongoing_privacy_chip.xml
deleted file mode 100644
index dce9ce1..0000000
--- a/packages/SystemUI/res/layout/ongoing_privacy_chip.xml
+++ /dev/null
@@ -1,41 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-     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.
--->
-
-
-<com.android.systemui.privacy.OngoingPrivacyChip
-    xmlns:android="http://schemas.android.com/apk/res/android"
-    android:id="@+id/privacy_chip"
-    android:layout_height="match_parent"
-    android:layout_width="wrap_content"
-    android:layout_gravity="center_vertical|end"
-    android:gravity="center_vertical"
-    android:orientation="horizontal"
-    android:focusable="true" >
-
-        <FrameLayout
-            android:id="@+id/background"
-            android:layout_height="@dimen/ongoing_appops_chip_height"
-            android:minWidth="48dp"
-            android:layout_width="wrap_content" >
-                <LinearLayout
-                    android:id="@+id/icons_container"
-                    android:layout_height="match_parent"
-                    android:layout_width="wrap_content"
-                    android:gravity="center_vertical"
-                    />
-          </FrameLayout>
-</com.android.systemui.privacy.OngoingPrivacyChip>
\ No newline at end of file
diff --git a/packages/SystemUI/res/layout/ongoing_privacy_text_item.xml b/packages/SystemUI/res/layout/ongoing_privacy_text_item.xml
deleted file mode 100644
index 5595b13..0000000
--- a/packages/SystemUI/res/layout/ongoing_privacy_text_item.xml
+++ /dev/null
@@ -1,24 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-     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.
--->
-
-<TextView
-    xmlns:android="http://schemas.android.com/apk/res/android"
-    android:layout_width="match_parent"
-    android:layout_height="wrap_content"
-    android:textDirection="locale"
-    android:textAppearance="@style/TextAppearance.QS.DetailItemPrimary"
-/>
\ No newline at end of file
diff --git a/packages/SystemUI/res/layout/quick_status_bar_header_system_icons.xml b/packages/SystemUI/res/layout/quick_status_bar_header_system_icons.xml
index cd9f780..54fb216 100644
--- a/packages/SystemUI/res/layout/quick_status_bar_header_system_icons.xml
+++ b/packages/SystemUI/res/layout/quick_status_bar_header_system_icons.xml
@@ -22,19 +22,11 @@
     android:layout_height="@*android:dimen/quick_qs_offset_height"
     android:clipChildren="false"
     android:clipToPadding="false"
-    android:gravity="center"
     android:orientation="horizontal"
     android:clickable="true"
     android:paddingStart="@dimen/status_bar_padding_start"
     android:paddingEnd="@dimen/status_bar_padding_end" >
 
-    <LinearLayout
-        android:layout_width="0dp"
-        android:layout_height="match_parent"
-        android:layout_weight="1"
-        android:orientation="horizontal"
-        android:gravity="center_vertical|start" >
-
     <com.android.systemui.statusbar.policy.Clock
         android:id="@+id/clock"
         android:layout_width="wrap_content"
@@ -46,23 +38,4 @@
         android:singleLine="true"
         android:textAppearance="@style/TextAppearance.StatusBar.Clock"
         systemui:showDark="false" />
-    </LinearLayout>
-
-    <android.widget.Space
-        android:id="@+id/space"
-        android:layout_width="0dp"
-        android:layout_height="match_parent"
-        android:layout_gravity="center_vertical|center_horizontal"
-        android:visibility="gone" />
-
-    <LinearLayout
-        android:layout_width="0dp"
-        android:layout_height="match_parent"
-        android:layout_weight="1"
-        android:orientation="horizontal"
-        android:gravity="center_vertical|end" >
-
-    <include layout="@layout/ongoing_privacy_chip" />
-
-    </LinearLayout>
 </LinearLayout>
diff --git a/packages/SystemUI/res/values-af/strings.xml b/packages/SystemUI/res/values-af/strings.xml
index e6579da..ed29a08 100644
--- a/packages/SystemUI/res/values-af/strings.xml
+++ b/packages/SystemUI/res/values-af/strings.xml
@@ -197,6 +197,7 @@
     <string name="carrier_network_change_mode" msgid="8149202439957837762">"Diensverskaffernetwerk verander tans"</string>
     <string name="accessibility_battery_details" msgid="7645516654955025422">"Maak batterybesonderhede oop"</string>
     <string name="accessibility_battery_level" msgid="7451474187113371965">"Battery <xliff:g id="NUMBER">%d</xliff:g> persent."</string>
+    <string name="accessibility_battery_level_with_estimate" msgid="9033100930684311630">"Battery <xliff:g id="PERCENTAGE">%1$s</xliff:g> persent, ongeveer <xliff:g id="TIME">%2$s</xliff:g> oor gegrond op jou gebruik"</string>
     <string name="accessibility_battery_level_charging" msgid="1147587904439319646">"Battery laai tans, <xliff:g id="BATTERY_PERCENTAGE">%d</xliff:g>%%."</string>
     <string name="accessibility_settings_button" msgid="799583911231893380">"Stelselinstellings"</string>
     <string name="accessibility_notifications_button" msgid="4498000369779421892">"Kennisgewings"</string>
@@ -647,13 +648,10 @@
     <string name="inline_silent_button_keep_alerting" msgid="327696842264359693">"Hou aan waarsku"</string>
     <string name="inline_turn_off_notifications" msgid="8635596135532202355">"Skakel kennisgewings af"</string>
     <string name="inline_keep_showing_app" msgid="1723113469580031041">"Hou aan om kennisgewings van hierdie program af te wys?"</string>
-    <string name="notification_silence_title" msgid="7352089096356977930">"Lig"</string>
-    <string name="notification_alert_title" msgid="3966526305405016221">"Geprioritiseerd"</string>
-    <string name="notification_channel_summary_low" msgid="1065819618107531284">"Help jou om te fokus met kennisgewings wat net op die aftrekskerm is. Altyd stil."</string>
-    <string name="notification_channel_summary_low_status" msgid="2702170424808743755">"Wys prioriteitkennisgewings hieronder. Altyd stil."</string>
-    <string name="notification_channel_summary_low_lock" msgid="7966605244472624458">"Wys prioriteitkennisgewings hieronder. Altyd stil."</string>
-    <string name="notification_channel_summary_low_status_lock" msgid="7012562768950012739">"Wys prioriteitkennisgewings hieronder. Altyd stil."</string>
-    <string name="notification_channel_summary_default" msgid="3847289783382316019">"Trek jou aandag met klank en \'n statusbalk-ikoon. Wys op sluitskerm."</string>
+    <string name="notification_silence_title" msgid="5763240612242137433">"Stil"</string>
+    <string name="notification_alert_title" msgid="8031196611815490340">"Waarskuwings"</string>
+    <string name="notification_channel_summary_low" msgid="3387466082089715555">"Help jou om te fokus sonder klank of vibrasie."</string>
+    <string name="notification_channel_summary_default" msgid="5994062840431965586">"Kry jou aandag met klank of vibrasie."</string>
     <string name="notification_unblockable_desc" msgid="4556908766584964102">"Hierdie kennisgewings kan nie gewysig word nie."</string>
     <string name="notification_multichannel_desc" msgid="4695920306092240550">"Hierdie groep kennisgewings kan nie hier opgestel word nie"</string>
     <string name="notification_delegate_header" msgid="2857691673814814270">"Instaanbediener-kennisgewing"</string>
@@ -935,4 +933,6 @@
     <string name="bubble_accessibility_action_move_bottom_left" msgid="206369104473183217">"Beweeg na links onder"</string>
     <string name="bubble_accessibility_action_move_bottom_right" msgid="8705660152384312329">"Beweeg na regs onder"</string>
     <string name="bubble_dismiss_text" msgid="8028337712674081668">"Maak toe"</string>
+    <string name="notification_content_system_nav_changed" msgid="7218093915747788444">"Stelselnavigasie is opgedateer. Gaan na Instellings toe om veranderinge te maak."</string>
+    <string name="notification_content_gesture_nav_available" msgid="8111130443656460792">"Gaan na Instellings toe om stelselnavigasie op te dateer"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-am/strings.xml b/packages/SystemUI/res/values-am/strings.xml
index 4789789..ae79feb 100644
--- a/packages/SystemUI/res/values-am/strings.xml
+++ b/packages/SystemUI/res/values-am/strings.xml
@@ -62,12 +62,10 @@
     <string name="usb_debugging_secondary_user_title" msgid="6353808721761220421">"የዩኤስቢ እርማት አይፈቀድም"</string>
     <string name="usb_debugging_secondary_user_message" msgid="6067122453571699801">"አሁን ወደዚህ መሣሪያ የገባው ተጠቃሚ የዩኤስቢ እርማትን ማብራት አይችልም። ይህን ባህሪ ለመጠቀም ወደ ዋና ተጠቃሚ ይቀይሩ።"</string>
     <string name="usb_contaminant_title" msgid="206854874263058490">"የዩኤስቢ ወደብ ተሰናክሏል"</string>
-    <!-- no translation found for usb_contaminant_message (7379089091591609111) -->
-    <skip />
+    <string name="usb_contaminant_message" msgid="7379089091591609111">"መሣሪያዎን ከፈሳሽ ወይም ፍርስራሽ ለመጠበቅ ሲባል የዩኤስቢ ወደቡ ተሰናክሏል፣ እና ማናቸውም ተቀጥላዎችን አያገኝም።\n\nየዩኤስቢ ወደቡን እንደገና መጠቀም ችግር በማይኖረው ጊዜ ማሳወቂያ ይደርሰዎታል።"</string>
     <string name="usb_port_enabled" msgid="7906141351687694867">"ኃይል መሙያዎችን እና ተጨማሪ መሣሪያዎችን ፈልጎ ለማግኘት የነቃ የዩኤስቢ ወደብ"</string>
     <string name="usb_disable_contaminant_detection" msgid="2103905315747120033">"ዩኤስቢ አንቃ"</string>
-    <!-- no translation found for learn_more (5000517160980853569) -->
-    <skip />
+    <string name="learn_more" msgid="5000517160980853569">"የበለጠ መረዳት"</string>
     <string name="compat_mode_on" msgid="6623839244840638213">"ማያ እንዲሞላ አጉላ"</string>
     <string name="compat_mode_off" msgid="4434467572461327898">"ማያ ለመሙለት ሳብ"</string>
     <string name="global_action_screenshot" msgid="8329831278085426283">"ቅጽበታዊ ገጽ እይታ"</string>
@@ -199,6 +197,7 @@
     <string name="carrier_network_change_mode" msgid="8149202439957837762">"የአገልግሎት አቅራቢ አውታረ መረብን በመቀየር ላይ"</string>
     <string name="accessibility_battery_details" msgid="7645516654955025422">"የባትሪ ዝርዝሮችን ክፈት"</string>
     <string name="accessibility_battery_level" msgid="7451474187113371965">"የባትሪ <xliff:g id="NUMBER">%d</xliff:g> መቶኛ።"</string>
+    <string name="accessibility_battery_level_with_estimate" msgid="9033100930684311630">"ባትሪ <xliff:g id="PERCENTAGE">%1$s</xliff:g> በመቶ፣ በአጠቃቀምዎ ላይ በመመስረት <xliff:g id="TIME">%2$s</xliff:g> ገደማ ይቀራል"</string>
     <string name="accessibility_battery_level_charging" msgid="1147587904439319646">"ባትሪ ኃይል በመሙላት ላይ፣ <xliff:g id="BATTERY_PERCENTAGE">%d</xliff:g> %%."</string>
     <string name="accessibility_settings_button" msgid="799583911231893380">"የስርዓት ቅንብሮች"</string>
     <string name="accessibility_notifications_button" msgid="4498000369779421892">"ማሳወቂያዎች"</string>
@@ -458,10 +457,8 @@
     <string name="media_projection_remember_text" msgid="3103510882172746752">"ዳግመኛ አታሳይ"</string>
     <string name="clear_all_notifications_text" msgid="814192889771462828">"ሁሉንም አጽዳ"</string>
     <string name="manage_notifications_text" msgid="2386728145475108753">"ያቀናብሩ"</string>
-    <!-- no translation found for notification_section_header_gentle (4372438504154095677) -->
-    <skip />
-    <!-- no translation found for accessibility_notification_section_header_gentle_clear_all (4286716295850400959) -->
-    <skip />
+    <string name="notification_section_header_gentle" msgid="4372438504154095677">"ጸጥ ያሉ ማሳወቂያዎች"</string>
+    <string name="accessibility_notification_section_header_gentle_clear_all" msgid="4286716295850400959">"ሁሉንም ጸጥ ያሉ ማሳወቂያዎችን ያጽዱ"</string>
     <string name="dnd_suppressing_shade_text" msgid="1904574852846769301">"ማሳወቂያዎች በአትረብሽ ባሉበት ቆመዋል"</string>
     <string name="media_projection_action_text" msgid="8470872969457985954">"አሁን ጀምር"</string>
     <string name="empty_shade_text" msgid="708135716272867002">"ምንም ማሳወቂያ የለም"</string>
@@ -645,21 +642,16 @@
     <string name="inline_block_button" msgid="8735843688021655065">"አግድ"</string>
     <string name="inline_keep_button" msgid="6665940297019018232">"ማሳየትን ቀጥል"</string>
     <string name="inline_minimize_button" msgid="966233327974702195">"አሳንስ"</string>
-    <!-- no translation found for inline_silent_button_silent (5315879183296940969) -->
-    <skip />
+    <string name="inline_silent_button_silent" msgid="5315879183296940969">"ፀጥ ያለ"</string>
     <string name="inline_silent_button_stay_silent" msgid="6308371431217601009">"ጸጥ እንዳለ ቆይ"</string>
-    <!-- no translation found for inline_silent_button_alert (6008435419895088034) -->
-    <skip />
+    <string name="inline_silent_button_alert" msgid="6008435419895088034">"ማንቃት"</string>
     <string name="inline_silent_button_keep_alerting" msgid="327696842264359693">"ማንቃቱን ቀጥል"</string>
     <string name="inline_turn_off_notifications" msgid="8635596135532202355">"ማሳወቂያዎችን አጥፋ"</string>
     <string name="inline_keep_showing_app" msgid="1723113469580031041">"ከዚህ መተግበሪያ ማሳወቂያዎችን ማሳየት ይቀጥል?"</string>
-    <string name="notification_silence_title" msgid="7352089096356977930">"ረጋ ያለ"</string>
-    <string name="notification_alert_title" msgid="3966526305405016221">"ቅድሚያ የተሰጠው"</string>
-    <string name="notification_channel_summary_low" msgid="1065819618107531284">"በወደታች ተጎችታች ጥላ ውስጥ ብቻ በማሳወቂያዎች ላይ እንዲያተኩሩ ያግዝዎታል። ሁልጊዜ ጸጥታ።"</string>
-    <string name="notification_channel_summary_low_status" msgid="2702170424808743755">"ከዚህ በታች ቅድሚያ ተሰጪ ማሳወቂያዎችን ያሳያል። ሁልጊዜ ጸጥታ።"</string>
-    <string name="notification_channel_summary_low_lock" msgid="7966605244472624458">"ከዚህ በታች ቅድሚያ ተሰጪ ማሳወቂያዎችን ያሳያል። ሁልጊዜ ጸጥታ።"</string>
-    <string name="notification_channel_summary_low_status_lock" msgid="7012562768950012739">"ከዚህ በታች ቅድሚያ ተሰጪ ማሳወቂያዎችን ያሳያል። ሁልጊዜ ጸጥታ።"</string>
-    <string name="notification_channel_summary_default" msgid="3847289783382316019">"ከድምፅ እና የሁኔታ አሞሌ አዶ ጋር የእርስዎን ትኩረት ይስባል። በማያ ገጽ ቁልፍ ላይ ያሳያል።"</string>
+    <string name="notification_silence_title" msgid="5763240612242137433">"ፀጥ ያለ"</string>
+    <string name="notification_alert_title" msgid="8031196611815490340">"ማንቃት"</string>
+    <string name="notification_channel_summary_low" msgid="3387466082089715555">"ያለ ድምፅ ወይም ንዝረት እርስዎ ትኩረት እንዲያደርጉ ያግዛል።"</string>
+    <string name="notification_channel_summary_default" msgid="5994062840431965586">"ከድምፅ ወይም ንዝረት ጋር የእርስዎን ትኩረት ይስባል።"</string>
     <string name="notification_unblockable_desc" msgid="4556908766584964102">"እነዚህ ማሳወቂያዎች ሊሻሻሉ አይችሉም።"</string>
     <string name="notification_multichannel_desc" msgid="4695920306092240550">"የማሳወቂያዎች ይህ ቡድን እዚህ ላይ ሊዋቀር አይችልም"</string>
     <string name="notification_delegate_header" msgid="2857691673814814270">"ተኪ ማሳወቂያ"</string>
@@ -908,8 +900,7 @@
     <string name="slice_permission_allow" msgid="2340244901366722709">"ፍቀድ"</string>
     <string name="slice_permission_deny" msgid="7683681514008048807">"ከልክል"</string>
     <string name="auto_saver_title" msgid="1217959994732964228">"ለባትሪ ቆጣቢ መርሐግብርን ለማስያዝ መታ ያድርጉ"</string>
-    <!-- no translation found for auto_saver_text (2563289953551438248) -->
-    <skip />
+    <string name="auto_saver_text" msgid="2563289953551438248">"ባትሪው የማለቅ ዕድሉ ከፍ ያለ ከሆነ ያብሩት"</string>
     <string name="no_auto_saver_action" msgid="8086002101711328500">"አይ፣ አመሰግናለሁ"</string>
     <string name="auto_saver_enabled_title" msgid="6726474226058316862">"የባትሪ ቆጣቢ መርሐግብር በርቷል"</string>
     <string name="auto_saver_enabled_text" msgid="874711029884777579">"ባትሪ ልክ ከ<xliff:g id="PERCENTAGE">%d</xliff:g>%% በታች ሲሆን ባትሪ ቆጣቢ በራስ-ሰር ይበራል።"</string>
@@ -942,4 +933,6 @@
     <string name="bubble_accessibility_action_move_bottom_left" msgid="206369104473183217">"የግርጌውን ግራ አንቀሳቅስ"</string>
     <string name="bubble_accessibility_action_move_bottom_right" msgid="8705660152384312329">"ታችኛውን ቀኝ ያንቀሳቅሱ"</string>
     <string name="bubble_dismiss_text" msgid="8028337712674081668">"አሰናብት"</string>
+    <string name="notification_content_system_nav_changed" msgid="7218093915747788444">"የስርዓት ዳሰሳ ተዘምኗል። ለውጦችን ለማድረግ ወደ ቅንብሮች ይሂዱ።"</string>
+    <string name="notification_content_gesture_nav_available" msgid="8111130443656460792">"የስርዓት ዳሰሳን ለማዘመን ወደ ቅንብሮች ይሂዱ"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-ar/strings.xml b/packages/SystemUI/res/values-ar/strings.xml
index 42879a4..46d5390 100644
--- a/packages/SystemUI/res/values-ar/strings.xml
+++ b/packages/SystemUI/res/values-ar/strings.xml
@@ -62,12 +62,10 @@
     <string name="usb_debugging_secondary_user_title" msgid="6353808721761220421">"‏لا يُسمح بتصحيح أخطاء USB"</string>
     <string name="usb_debugging_secondary_user_message" msgid="6067122453571699801">"‏لا يمكن للمستخدم الذي يسجّل دخوله حاليًا إلى هذا الجهاز تشغيل تصحيح أخطاء USB. لاستخدام هذه الميزة، يمكنك التبديل إلى المستخدم الأساسي."</string>
     <string name="usb_contaminant_title" msgid="206854874263058490">"‏تمّ إيقاف منفذ USB"</string>
-    <!-- no translation found for usb_contaminant_message (7379089091591609111) -->
-    <skip />
+    <string name="usb_contaminant_message" msgid="7379089091591609111">"‏لحماية جهازك من السوائل أو الشوائب، سيتمّ إيقاف منفذ USB ولن يتم رصد أيّ ملحقات.\n\nوسيتمّ إعلامك عندما يُسمح باستخدام منفذ USB مرة أخرى."</string>
     <string name="usb_port_enabled" msgid="7906141351687694867">"‏تم تفعيل منفذ USB لاكتشاف أجهزة الشحن والملحقات."</string>
     <string name="usb_disable_contaminant_detection" msgid="2103905315747120033">"‏تفعيل USB"</string>
-    <!-- no translation found for learn_more (5000517160980853569) -->
-    <skip />
+    <string name="learn_more" msgid="5000517160980853569">"مزيد من المعلومات"</string>
     <string name="compat_mode_on" msgid="6623839244840638213">"تكبير/تصغير لملء الشاشة"</string>
     <string name="compat_mode_off" msgid="4434467572461327898">"توسيع بملء الشاشة"</string>
     <string name="global_action_screenshot" msgid="8329831278085426283">"لقطة شاشة"</string>
@@ -199,6 +197,7 @@
     <string name="carrier_network_change_mode" msgid="8149202439957837762">"جارٍ تغيير شبكة مشغِّل شبكة الجوّال."</string>
     <string name="accessibility_battery_details" msgid="7645516654955025422">"فتح تفاصيل البطارية"</string>
     <string name="accessibility_battery_level" msgid="7451474187113371965">"مستوى البطارية <xliff:g id="NUMBER">%d</xliff:g> في المائة."</string>
+    <string name="accessibility_battery_level_with_estimate" msgid="9033100930684311630">"نسبة الشحن بالبطارية <xliff:g id="PERCENTAGE">%1$s</xliff:g> بالمائة، ويتبقى <xliff:g id="TIME">%2$s</xliff:g> تقريبًا بناءً على استخدامك."</string>
     <string name="accessibility_battery_level_charging" msgid="1147587904439319646">"جارٍ شحن البطارية، <xliff:g id="BATTERY_PERCENTAGE">%d</xliff:g>%%."</string>
     <string name="accessibility_settings_button" msgid="799583911231893380">"إعدادات النظام."</string>
     <string name="accessibility_notifications_button" msgid="4498000369779421892">"الإشعارات."</string>
@@ -470,10 +469,8 @@
     <string name="media_projection_remember_text" msgid="3103510882172746752">"عدم الإظهار مرة أخرى"</string>
     <string name="clear_all_notifications_text" msgid="814192889771462828">"محو الكل"</string>
     <string name="manage_notifications_text" msgid="2386728145475108753">"إدارة"</string>
-    <!-- no translation found for notification_section_header_gentle (4372438504154095677) -->
-    <skip />
-    <!-- no translation found for accessibility_notification_section_header_gentle_clear_all (4286716295850400959) -->
-    <skip />
+    <string name="notification_section_header_gentle" msgid="4372438504154095677">"الإشعارات الصامتة"</string>
+    <string name="accessibility_notification_section_header_gentle_clear_all" msgid="4286716295850400959">"محو جميع الإشعارات الصامتة"</string>
     <string name="dnd_suppressing_shade_text" msgid="1904574852846769301">"تم إيقاف الإشعارات مؤقتًا وفقًا لإعداد \"الرجاء عدم الإزعاج\""</string>
     <string name="media_projection_action_text" msgid="8470872969457985954">"البدء الآن"</string>
     <string name="empty_shade_text" msgid="708135716272867002">"ليس هناك أي اشعارات"</string>
@@ -657,21 +654,16 @@
     <string name="inline_block_button" msgid="8735843688021655065">"حظر"</string>
     <string name="inline_keep_button" msgid="6665940297019018232">"الاستمرار في تلقّي الإشعارات"</string>
     <string name="inline_minimize_button" msgid="966233327974702195">"تصغير"</string>
-    <!-- no translation found for inline_silent_button_silent (5315879183296940969) -->
-    <skip />
+    <string name="inline_silent_button_silent" msgid="5315879183296940969">"صامت"</string>
     <string name="inline_silent_button_stay_silent" msgid="6308371431217601009">"متابعة عرض الإشعارات بدون صوت"</string>
-    <!-- no translation found for inline_silent_button_alert (6008435419895088034) -->
-    <skip />
+    <string name="inline_silent_button_alert" msgid="6008435419895088034">"تنبيه"</string>
     <string name="inline_silent_button_keep_alerting" msgid="327696842264359693">"متابعة إرسال التنبيهات"</string>
     <string name="inline_turn_off_notifications" msgid="8635596135532202355">"إيقاف الإشعارات"</string>
     <string name="inline_keep_showing_app" msgid="1723113469580031041">"هل تريد الاستمرار في تلقي إشعارات من هذا التطبيق؟"</string>
-    <string name="notification_silence_title" msgid="7352089096356977930">"الإشعارات الهادئة"</string>
-    <string name="notification_alert_title" msgid="3966526305405016221">"لها الأولوية"</string>
-    <string name="notification_channel_summary_low" msgid="1065819618107531284">"لمساعدتك على التركيز، يتم عرض هذه الإشعارات ضمن \"مركز الإشعارات\" فقط. كتم الصوت دائمًا."</string>
-    <string name="notification_channel_summary_low_status" msgid="2702170424808743755">"يتم عرض هذه الإشعارات تحت الإشعارات ذات الأولوية، مع كتم صوتها دائمًا."</string>
-    <string name="notification_channel_summary_low_lock" msgid="7966605244472624458">"يتم عرض هذه الإشعارات تحت الإشعارات ذات الأولوية، مع كتم صوتها دائمًا."</string>
-    <string name="notification_channel_summary_low_status_lock" msgid="7012562768950012739">"يتم عرض هذه الإشعارات تحت الإشعارات ذات الأولوية، مع كتم صوتها دائمًا."</string>
-    <string name="notification_channel_summary_default" msgid="3847289783382316019">"عند تلقّي هذه الإشعارات، سيظهر رمز في شريط الحالة مع صوت للفت انتباهك. ويتم عرض هذه الإشعارات على شاشة التأمين."</string>
+    <string name="notification_silence_title" msgid="5763240612242137433">"إشعار صامت"</string>
+    <string name="notification_alert_title" msgid="8031196611815490340">"إشعار مصحوب بتنبيه صوتي"</string>
+    <string name="notification_channel_summary_low" msgid="3387466082089715555">"يساعدك هذا الإشعار على التركيز بدون صوت أو اهتزاز."</string>
+    <string name="notification_channel_summary_default" msgid="5994062840431965586">"يلفت هذا الإشعار انتباهك باستخدام الصوت والاهتزاز."</string>
     <string name="notification_unblockable_desc" msgid="4556908766584964102">"يتعذّر تعديل هذه الإشعارات."</string>
     <string name="notification_multichannel_desc" msgid="4695920306092240550">"يتعذّر ضبط مجموعة الإشعارات هذه هنا."</string>
     <string name="notification_delegate_header" msgid="2857691673814814270">"إشعار مستند إلى خادم وكيل"</string>
@@ -928,8 +920,7 @@
     <string name="slice_permission_allow" msgid="2340244901366722709">"سماح"</string>
     <string name="slice_permission_deny" msgid="7683681514008048807">"رفض"</string>
     <string name="auto_saver_title" msgid="1217959994732964228">"انقر لجدولة \"توفير شحن البطارية\"."</string>
-    <!-- no translation found for auto_saver_text (2563289953551438248) -->
-    <skip />
+    <string name="auto_saver_text" msgid="2563289953551438248">"فعِّل الميزة إذا كان من المرجح نفاد شحن البطارية."</string>
     <string name="no_auto_saver_action" msgid="8086002101711328500">"لا، شكرًا"</string>
     <string name="auto_saver_enabled_title" msgid="6726474226058316862">"تم تفعيل جدولة \"توفير شحن البطارية\"."</string>
     <string name="auto_saver_enabled_text" msgid="874711029884777579">"سيتم تفعيل ميزة \"توفير شحن البطارية\" عندما تنخفض البطارية عن <xliff:g id="PERCENTAGE">%d</xliff:g>%%."</string>
@@ -962,4 +953,6 @@
     <string name="bubble_accessibility_action_move_bottom_left" msgid="206369104473183217">"نقل إلى أسفل يمين الشاشة"</string>
     <string name="bubble_accessibility_action_move_bottom_right" msgid="8705660152384312329">"نقل إلى أسفل اليسار"</string>
     <string name="bubble_dismiss_text" msgid="8028337712674081668">"تجاهل"</string>
+    <string name="notification_content_system_nav_changed" msgid="7218093915747788444">"تم تحديث التنقل داخل النظام. لإجراء التغييرات، يُرجى الانتقال إلى \"الإعدادات\"."</string>
+    <string name="notification_content_gesture_nav_available" msgid="8111130443656460792">"الانتقال إلى \"الإعدادات\" لتعديل التنقل داخل النظام"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-as/strings.xml b/packages/SystemUI/res/values-as/strings.xml
index de2b933..f7c11a9 100644
--- a/packages/SystemUI/res/values-as/strings.xml
+++ b/packages/SystemUI/res/values-as/strings.xml
@@ -62,12 +62,10 @@
     <string name="usb_debugging_secondary_user_title" msgid="6353808721761220421">"ইউএছবি ডিবাগিঙৰ অনুমতি নাই"</string>
     <string name="usb_debugging_secondary_user_message" msgid="6067122453571699801">"এই ডিভাইচটোত বর্তমান ছাইন ইন হৈ থকা ব্যৱহাৰকাৰীজনে ইউএছবি ডিবাগিং অন কৰিব নোৱাৰে। এই সুবিধাটো ব্যৱহাৰ কৰিবলৈ হ\'লে মুখ্য ব্যৱহাৰকাৰী হিচাপে ছাইন ইন কৰক।"</string>
     <string name="usb_contaminant_title" msgid="206854874263058490">"ইউএছবি প’ৰ্ট অক্ষম কৰা হ’ল"</string>
-    <!-- no translation found for usb_contaminant_message (7379089091591609111) -->
-    <skip />
+    <string name="usb_contaminant_message" msgid="7379089091591609111">"আপোনাৰ ডিভাইচটো তৰল বা ধূলি-মাকতিৰ পৰা ৰক্ষা কৰিবলৈ ইউএছবি প’ৰ্টটো অক্ষম কৰি ৰখা হৈছে ফলত ই কোনো আনুষংগিক সামগ্ৰী ধৰা পেলাব নোৱাৰে।\n\nযেতিয়া ইউএছবি প’ৰ্টটো নিৰাপদভাৱে ব্যৱহাৰ কৰিব পৰা হ’ব তেতিয়া আপোনাক জনোৱা হ’ব।"</string>
     <string name="usb_port_enabled" msgid="7906141351687694867">"চাৰ্জাৰ আৰু আনুষংগিক সামগ্ৰী চিনাক্ত কৰিবলৈ USB প’ৰ্ট সক্ষম কৰা হ’ল"</string>
     <string name="usb_disable_contaminant_detection" msgid="2103905315747120033">"USB সক্ষম কৰক"</string>
-    <!-- no translation found for learn_more (5000517160980853569) -->
-    <skip />
+    <string name="learn_more" msgid="5000517160980853569">"অধিক জানক"</string>
     <string name="compat_mode_on" msgid="6623839244840638213">"স্ক্ৰীণ পূর্ণ কৰিবলৈ জুম কৰক"</string>
     <string name="compat_mode_off" msgid="4434467572461327898">"স্ক্ৰীণ পূর্ণ কৰিবলৈ প্ৰসাৰিত কৰক"</string>
     <string name="global_action_screenshot" msgid="8329831278085426283">"স্ক্ৰীণশ্বট"</string>
@@ -199,6 +197,7 @@
     <string name="carrier_network_change_mode" msgid="8149202439957837762">"বাহক নেটৱৰ্কৰ পৰিৱৰ্তন"</string>
     <string name="accessibility_battery_details" msgid="7645516654955025422">"বেটাৰিৰ বিৱৰণসমূহ খোলক"</string>
     <string name="accessibility_battery_level" msgid="7451474187113371965">"<xliff:g id="NUMBER">%d</xliff:g> শতাংশ বেটাৰি।"</string>
+    <string name="accessibility_battery_level_with_estimate" msgid="9033100930684311630">"আপোনাৰ ব্যৱহাৰৰ ওপৰত ভিত্তি কৰি বেটাৰী <xliff:g id="PERCENTAGE">%1$s</xliff:g> শতাংশ, প্ৰায় <xliff:g id="TIME">%2$s</xliff:g> বাকী আছে"</string>
     <string name="accessibility_battery_level_charging" msgid="1147587904439319646">"বেটাৰি চ্চাৰ্জ কৰি থকা হৈছে, <xliff:g id="BATTERY_PERCENTAGE">%d</xliff:g> শতাংশ।"</string>
     <string name="accessibility_settings_button" msgid="799583911231893380">"ছিষ্টেমৰ ছেটিংসমূহ৷"</string>
     <string name="accessibility_notifications_button" msgid="4498000369779421892">"জাননীসমূহ।"</string>
@@ -458,10 +457,8 @@
     <string name="media_projection_remember_text" msgid="3103510882172746752">"পুনৰাই নেদেখুৱাব"</string>
     <string name="clear_all_notifications_text" msgid="814192889771462828">"সকলো মচক"</string>
     <string name="manage_notifications_text" msgid="2386728145475108753">"পৰিচালনা"</string>
-    <!-- no translation found for notification_section_header_gentle (4372438504154095677) -->
-    <skip />
-    <!-- no translation found for accessibility_notification_section_header_gentle_clear_all (4286716295850400959) -->
-    <skip />
+    <string name="notification_section_header_gentle" msgid="4372438504154095677">"নীৰৱ জাননীসমূহ"</string>
+    <string name="accessibility_notification_section_header_gentle_clear_all" msgid="4286716295850400959">"সকলো নীৰৱ জাননী মচক"</string>
     <string name="dnd_suppressing_shade_text" msgid="1904574852846769301">"অসুবিধা নিদিব-ই জাননী পজ কৰিছে"</string>
     <string name="media_projection_action_text" msgid="8470872969457985954">"এতিয়াই আৰম্ভ কৰক"</string>
     <string name="empty_shade_text" msgid="708135716272867002">"কোনো জাননী নাই"</string>
@@ -645,21 +642,16 @@
     <string name="inline_block_button" msgid="8735843688021655065">"অৱৰোধ কৰক"</string>
     <string name="inline_keep_button" msgid="6665940297019018232">"দেখুওৱাই থাকক"</string>
     <string name="inline_minimize_button" msgid="966233327974702195">"সৰু কৰক"</string>
-    <!-- no translation found for inline_silent_button_silent (5315879183296940969) -->
-    <skip />
+    <string name="inline_silent_button_silent" msgid="5315879183296940969">"নিৰৱ"</string>
     <string name="inline_silent_button_stay_silent" msgid="6308371431217601009">"নীৰৱ হৈ থাকক"</string>
-    <!-- no translation found for inline_silent_button_alert (6008435419895088034) -->
-    <skip />
+    <string name="inline_silent_button_alert" msgid="6008435419895088034">"সতৰ্ক কৰক"</string>
     <string name="inline_silent_button_keep_alerting" msgid="327696842264359693">"সতৰ্ক কৰি থাকক"</string>
     <string name="inline_turn_off_notifications" msgid="8635596135532202355">"জাননী অফ কৰক"</string>
     <string name="inline_keep_showing_app" msgid="1723113469580031041">"এই এপটোৰ জাননী দেখুওৱাই থাকিব লাগিবনে?"</string>
-    <string name="notification_silence_title" msgid="7352089096356977930">"সাধাৰণ"</string>
-    <string name="notification_alert_title" msgid="3966526305405016221">"অগ্ৰাধিকাৰপ্ৰাপ্ত"</string>
-    <string name="notification_channel_summary_low" msgid="1065819618107531284">"আপুনি যাতে অসুবিধা নাপায়, তাৰ বাবে কেৱল পুল-ডাউন শ্বেডত এই জাননী দেখুৱায়। সদায় নিৰৱ।"</string>
-    <string name="notification_channel_summary_low_status" msgid="2702170424808743755">"অগ্ৰাধিকাৰপ্ৰাপ্ত জাননীসমূহৰ তলত দেখুৱায়। সদায় নিৰৱ।"</string>
-    <string name="notification_channel_summary_low_lock" msgid="7966605244472624458">"অগ্ৰাধিকাৰপ্ৰাপ্ত জাননীসমূহৰ তলত দেখুৱায়। সদায় নিৰৱ।"</string>
-    <string name="notification_channel_summary_low_status_lock" msgid="7012562768950012739">"অগ্ৰাধিকাৰপ্ৰাপ্ত জাননীসমূহৰ তলত দেখুৱায়। সদায় নিৰৱ।"</string>
-    <string name="notification_channel_summary_default" msgid="3847289783382316019">"ধ্বনি আৰু স্থিতি দণ্ডৰ আইকনৰ জৰিয়তে আপোনাৰ মনোযোগ আকৰ্ষণ কৰে। লক স্ক্ৰীণত দেখুৱায়।"</string>
+    <string name="notification_silence_title" msgid="5763240612242137433">"নীৰৱ"</string>
+    <string name="notification_alert_title" msgid="8031196611815490340">"সতৰ্ক কৰক"</string>
+    <string name="notification_channel_summary_low" msgid="3387466082089715555">"কোনো ধ্বনি অথবা কম্পন অবিহনে আপোনাক মনোযোগ দিয়াত সহায় কৰে।"</string>
+    <string name="notification_channel_summary_default" msgid="5994062840431965586">"ধ্বনি অথবা কম্পনৰ জৰিয়তে আপোনাৰ মনোযোগ আকৰ্ষণ কৰে।"</string>
     <string name="notification_unblockable_desc" msgid="4556908766584964102">"এই জাননীসমূহ সংশোধন কৰিব নোৱাৰি।"</string>
     <string name="notification_multichannel_desc" msgid="4695920306092240550">"এই ধৰণৰ জাননীবোৰ ইয়াত কনফিগাৰ কৰিব পৰা নাযায়"</string>
     <string name="notification_delegate_header" msgid="2857691673814814270">"প্ৰক্সি হিচাপে পঠিওৱা জাননী"</string>
@@ -908,8 +900,7 @@
     <string name="slice_permission_allow" msgid="2340244901366722709">"অনুমতি দিয়ক"</string>
     <string name="slice_permission_deny" msgid="7683681514008048807">"অস্বীকাৰ কৰক"</string>
     <string name="auto_saver_title" msgid="1217959994732964228">"বেটাৰি সঞ্চয়কাৰীৰ সময়সূচী সক্ৰিয় কৰিবলৈ টিপক"</string>
-    <!-- no translation found for auto_saver_text (2563289953551438248) -->
-    <skip />
+    <string name="auto_saver_text" msgid="2563289953551438248">"বেটাৰি শেষ হোৱাৰ সম্ভাৱনা থাকিলে অন কৰক"</string>
     <string name="no_auto_saver_action" msgid="8086002101711328500">"নালাগে, ধন্যবাদ"</string>
     <string name="auto_saver_enabled_title" msgid="6726474226058316862">"বেটাৰি সঞ্চয়কাৰীৰ সময়সূচী অন কৰা অৱস্থাত আছে"</string>
     <string name="auto_saver_enabled_text" msgid="874711029884777579">"বেটাৰি চ্চাৰ্জৰ স্তৰ <xliff:g id="PERCENTAGE">%d</xliff:g>%%তকৈ কম হোৱাৰ লগে লগে বেটাৰি সঞ্চয়কাৰী স্বয়ংক্ৰিয়ভাৱে অন হ’ব।"</string>
@@ -942,4 +933,6 @@
     <string name="bubble_accessibility_action_move_bottom_left" msgid="206369104473183217">"বুটামটো বাওঁফালে নিয়ক"</string>
     <string name="bubble_accessibility_action_move_bottom_right" msgid="8705660152384312329">"তলৰ সোঁফালে নিয়ক"</string>
     <string name="bubble_dismiss_text" msgid="8028337712674081668">"অগ্ৰাহ্য কৰক"</string>
+    <string name="notification_content_system_nav_changed" msgid="7218093915747788444">"ছিষ্টেম নেভিগেশ্বন আপডে’ট কৰা হ’ল। সলনি কৰিবলৈ ছেটিংসমূহ-লৈ যাওক।"</string>
+    <string name="notification_content_gesture_nav_available" msgid="8111130443656460792">"ছিষ্টেম নেভিগেশ্বন আপডে’ট কৰিবলৈ ছেটিংসমূহ-লৈ যাওক"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-az/strings.xml b/packages/SystemUI/res/values-az/strings.xml
index f27bc4b..64d2b7e 100644
--- a/packages/SystemUI/res/values-az/strings.xml
+++ b/packages/SystemUI/res/values-az/strings.xml
@@ -62,12 +62,10 @@
     <string name="usb_debugging_secondary_user_title" msgid="6353808721761220421">"USB debaq prosesinə icazə verilmir"</string>
     <string name="usb_debugging_secondary_user_message" msgid="6067122453571699801">"Hazırda bu cihaza daxil olmuş istifadəçi USB sazlama prosesini aktiv edə bilməz. Bu funksiyadan istifadə etmək üçün əsas istifadəçi hesaba daxil olmalıdır."</string>
     <string name="usb_contaminant_title" msgid="206854874263058490">"USB portu deaktiv edildi"</string>
-    <!-- no translation found for usb_contaminant_message (7379089091591609111) -->
-    <skip />
+    <string name="usb_contaminant_message" msgid="7379089091591609111">"USB portu deaktivdir. Cihazı maye və zərbədən qorumaq üçün aksesuar aşkarlanmayacaq.\n\nUSB portu yenidən istifadə üçün təhlükəsiz olduqda bildiriş göndəriləcək."</string>
     <string name="usb_port_enabled" msgid="7906141351687694867">"Adapter və aksesuarları aşkarlamaq üçün USB portu aktiv edildi"</string>
     <string name="usb_disable_contaminant_detection" msgid="2103905315747120033">"USB-ni aktiv edin"</string>
-    <!-- no translation found for learn_more (5000517160980853569) -->
-    <skip />
+    <string name="learn_more" msgid="5000517160980853569">"Ətraflı məlumat"</string>
     <string name="compat_mode_on" msgid="6623839244840638213">"Ekranı doldurmaq üçün yaxınlaşdır"</string>
     <string name="compat_mode_off" msgid="4434467572461327898">"Ekranı doldurmaq üçün uzat"</string>
     <string name="global_action_screenshot" msgid="8329831278085426283">"Skrinşot"</string>
@@ -199,6 +197,7 @@
     <string name="carrier_network_change_mode" msgid="8149202439957837762">"Operator şəbəkəsinin dəyişilməsi"</string>
     <string name="accessibility_battery_details" msgid="7645516654955025422">"Batareya detallarını açın"</string>
     <string name="accessibility_battery_level" msgid="7451474187113371965">"Batareya <xliff:g id="NUMBER">%d</xliff:g> faizdir."</string>
+    <string name="accessibility_battery_level_with_estimate" msgid="9033100930684311630">"Batareya <xliff:g id="PERCENTAGE">%1$s</xliff:g> faizdir, istifadəyə əsasən təxminən <xliff:g id="TIME">%2$s</xliff:g> qalıb"</string>
     <string name="accessibility_battery_level_charging" msgid="1147587904439319646">"Batareya doldurulur, <xliff:g id="BATTERY_PERCENTAGE">%d</xliff:g>%% faiz."</string>
     <string name="accessibility_settings_button" msgid="799583911231893380">"Sistem parametrləri"</string>
     <string name="accessibility_notifications_button" msgid="4498000369779421892">"Bildirişlər."</string>
@@ -458,10 +457,8 @@
     <string name="media_projection_remember_text" msgid="3103510882172746752">"Daha göstərmə"</string>
     <string name="clear_all_notifications_text" msgid="814192889771462828">"Hamısını silin"</string>
     <string name="manage_notifications_text" msgid="2386728145475108753">"İdarə edin"</string>
-    <!-- no translation found for notification_section_header_gentle (4372438504154095677) -->
-    <skip />
-    <!-- no translation found for accessibility_notification_section_header_gentle_clear_all (4286716295850400959) -->
-    <skip />
+    <string name="notification_section_header_gentle" msgid="4372438504154095677">"Səssiz bildirişlər"</string>
+    <string name="accessibility_notification_section_header_gentle_clear_all" msgid="4286716295850400959">"Səssiz bildirişlərin hamısını silin"</string>
     <string name="dnd_suppressing_shade_text" msgid="1904574852846769301">"Bildirişlər \"Narahat Etməyin\" rejimi tərəfindən dayandırıldı"</string>
     <string name="media_projection_action_text" msgid="8470872969457985954">"İndi başlayın"</string>
     <string name="empty_shade_text" msgid="708135716272867002">"Heç bir bildiriş yoxdur"</string>
@@ -645,21 +642,16 @@
     <string name="inline_block_button" msgid="8735843688021655065">"Blok edin"</string>
     <string name="inline_keep_button" msgid="6665940297019018232">"Göstərməyə davam edin"</string>
     <string name="inline_minimize_button" msgid="966233327974702195">"Kiçildin"</string>
-    <!-- no translation found for inline_silent_button_silent (5315879183296940969) -->
-    <skip />
+    <string name="inline_silent_button_silent" msgid="5315879183296940969">"Səssiz"</string>
     <string name="inline_silent_button_stay_silent" msgid="6308371431217601009">"Səssiz göstərilsin"</string>
-    <!-- no translation found for inline_silent_button_alert (6008435419895088034) -->
-    <skip />
+    <string name="inline_silent_button_alert" msgid="6008435419895088034">"Siqnal"</string>
     <string name="inline_silent_button_keep_alerting" msgid="327696842264359693">"Xəbərdarlıq göndərməyə davam edin"</string>
     <string name="inline_turn_off_notifications" msgid="8635596135532202355">"Bildirişləri deaktiv edin"</string>
     <string name="inline_keep_showing_app" msgid="1723113469580031041">"Bu tətbiqin bildirişləri göstərilməyə davam edilsin?"</string>
-    <string name="notification_silence_title" msgid="7352089096356977930">"Daha az əhəmiyyətli"</string>
-    <string name="notification_alert_title" msgid="3966526305405016221">"Mühüm"</string>
-    <string name="notification_channel_summary_low" msgid="1065819618107531284">"Yalnız aşağı açılan siyahıda bildirişlərə fokuslanmağınıza kömək edir. Həmişə səssiz."</string>
-    <string name="notification_channel_summary_low_status" msgid="2702170424808743755">"Mühüm bildirişlərin aşağısında göstərilir. Həmişə səssiz."</string>
-    <string name="notification_channel_summary_low_lock" msgid="7966605244472624458">"Mühüm bildirişlərin aşağısında göstərilir. Həmişə səssiz."</string>
-    <string name="notification_channel_summary_low_status_lock" msgid="7012562768950012739">"Mühüm bildirişlərin aşağısında göstərilir. Həmişə səssiz."</string>
-    <string name="notification_channel_summary_default" msgid="3847289783382316019">"Səs &amp; status paneli ikonası ilə diqqətinizi cəlb edir. Ekran kilidini göstərir."</string>
+    <string name="notification_silence_title" msgid="5763240612242137433">"Səssiz"</string>
+    <string name="notification_alert_title" msgid="8031196611815490340">"Siqnal"</string>
+    <string name="notification_channel_summary_low" msgid="3387466082089715555">"Səs və ya vibrasiya olmadan fokuslanmağınıza kömək edir."</string>
+    <string name="notification_channel_summary_default" msgid="5994062840431965586">"Səs və ya vibrasiya ilə diqqətinizi çəkir."</string>
     <string name="notification_unblockable_desc" msgid="4556908766584964102">"Bu bildirişlər dəyişdirilə bilməz."</string>
     <string name="notification_multichannel_desc" msgid="4695920306092240550">"Bu bildiriş qrupunu burada konfiqurasiya etmək olmaz"</string>
     <string name="notification_delegate_header" msgid="2857691673814814270">"Proksi bildirişi"</string>
@@ -908,8 +900,7 @@
     <string name="slice_permission_allow" msgid="2340244901366722709">"İcazə verin"</string>
     <string name="slice_permission_deny" msgid="7683681514008048807">"Rədd edin"</string>
     <string name="auto_saver_title" msgid="1217959994732964228">"Batareya Qənaətini planlaşdırmaq üçün klikləyin"</string>
-    <!-- no translation found for auto_saver_text (2563289953551438248) -->
-    <skip />
+    <string name="auto_saver_text" msgid="2563289953551438248">"Batareya bitmək üzrə olduqda aktiv edin"</string>
     <string name="no_auto_saver_action" msgid="8086002101711328500">"Xeyr, təşəkkür"</string>
     <string name="auto_saver_enabled_title" msgid="6726474226058316862">"Batareya Qənaəti aktivdir"</string>
     <string name="auto_saver_enabled_text" msgid="874711029884777579">"Batareya <xliff:g id="PERCENTAGE">%d</xliff:g>%%-dən aşağı düşdükdə Batareya Qənaəti avtomatik aktiv ediləcək."</string>
@@ -942,4 +933,6 @@
     <string name="bubble_accessibility_action_move_bottom_left" msgid="206369104473183217">"Aşağıya sola köçürün"</string>
     <string name="bubble_accessibility_action_move_bottom_right" msgid="8705660152384312329">"Aşağıya sağa köçürün"</string>
     <string name="bubble_dismiss_text" msgid="8028337712674081668">"Kənarlaşdırın"</string>
+    <string name="notification_content_system_nav_changed" msgid="7218093915747788444">"Sistem naviqasiyası yeniləndi. Dəyişiklik etmək üçün Ayarlara daxil olun."</string>
+    <string name="notification_content_gesture_nav_available" msgid="8111130443656460792">"Sistem naviqasiyasını yeniləmək üçün Ayarlara keçin"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-b+sr+Latn/strings.xml b/packages/SystemUI/res/values-b+sr+Latn/strings.xml
index afe84d0..70f94f3 100644
--- a/packages/SystemUI/res/values-b+sr+Latn/strings.xml
+++ b/packages/SystemUI/res/values-b+sr+Latn/strings.xml
@@ -62,12 +62,10 @@
     <string name="usb_debugging_secondary_user_title" msgid="6353808721761220421">"Otklanjanje grešaka na USB-u nije dozvoljeno"</string>
     <string name="usb_debugging_secondary_user_message" msgid="6067122453571699801">"Korisnik koji je trenutno prijavljen na ovaj uređaj ne može da uključi otklanjanje grešaka na USB-u. Da biste koristili ovu funkciju, prebacite na primarnog korisnika."</string>
     <string name="usb_contaminant_title" msgid="206854874263058490">"USB port je onemogućen"</string>
-    <!-- no translation found for usb_contaminant_message (7379089091591609111) -->
-    <skip />
+    <string name="usb_contaminant_message" msgid="7379089091591609111">"Da bi se uređaj zaštitio od tečnosti ili nečistoće, USB port je onemogućen i neće otkrivati dodatnu opremu.\n\nObavestićemo vas kada ponovo budete mogli da koristite USB port."</string>
     <string name="usb_port_enabled" msgid="7906141351687694867">"USB port je omogućen radi otkrivanja punjača i dodatne opreme"</string>
     <string name="usb_disable_contaminant_detection" msgid="2103905315747120033">"Omogući USB"</string>
-    <!-- no translation found for learn_more (5000517160980853569) -->
-    <skip />
+    <string name="learn_more" msgid="5000517160980853569">"Saznajte više"</string>
     <string name="compat_mode_on" msgid="6623839244840638213">"Zumiraj na celom ekranu"</string>
     <string name="compat_mode_off" msgid="4434467572461327898">"Razvuci na ceo ekran"</string>
     <string name="global_action_screenshot" msgid="8329831278085426283">"Snimak ekrana"</string>
@@ -199,6 +197,7 @@
     <string name="carrier_network_change_mode" msgid="8149202439957837762">"Promena mreže mobilnog operatera"</string>
     <string name="accessibility_battery_details" msgid="7645516654955025422">"Otvori detalje o bateriji"</string>
     <string name="accessibility_battery_level" msgid="7451474187113371965">"Baterija je na <xliff:g id="NUMBER">%d</xliff:g> posto."</string>
+    <string name="accessibility_battery_level_with_estimate" msgid="9033100930684311630">"Baterija je na <xliff:g id="PERCENTAGE">%1$s</xliff:g> posto, preostalo vreme na osnovu korišćenja je <xliff:g id="TIME">%2$s</xliff:g>"</string>
     <string name="accessibility_battery_level_charging" msgid="1147587904439319646">"Baterija se puni, <xliff:g id="BATTERY_PERCENTAGE">%d</xliff:g>%%."</string>
     <string name="accessibility_settings_button" msgid="799583911231893380">"Sistemska podešavanja."</string>
     <string name="accessibility_notifications_button" msgid="4498000369779421892">"Obaveštenja."</string>
@@ -461,10 +460,8 @@
     <string name="media_projection_remember_text" msgid="3103510882172746752">"Ne prikazuj ponovo"</string>
     <string name="clear_all_notifications_text" msgid="814192889771462828">"Obriši sve"</string>
     <string name="manage_notifications_text" msgid="2386728145475108753">"Upravljajte"</string>
-    <!-- no translation found for notification_section_header_gentle (4372438504154095677) -->
-    <skip />
-    <!-- no translation found for accessibility_notification_section_header_gentle_clear_all (4286716295850400959) -->
-    <skip />
+    <string name="notification_section_header_gentle" msgid="4372438504154095677">"Nečujna obaveštenja"</string>
+    <string name="accessibility_notification_section_header_gentle_clear_all" msgid="4286716295850400959">"Obrišite sva nečujna obaveštenja"</string>
     <string name="dnd_suppressing_shade_text" msgid="1904574852846769301">"Obaveštenja su pauzirana režimom Ne uznemiravaj"</string>
     <string name="media_projection_action_text" msgid="8470872969457985954">"Započni odmah"</string>
     <string name="empty_shade_text" msgid="708135716272867002">"Nema obaveštenja"</string>
@@ -648,21 +645,16 @@
     <string name="inline_block_button" msgid="8735843688021655065">"Blokiraj"</string>
     <string name="inline_keep_button" msgid="6665940297019018232">"Nastavi da prikazuješ"</string>
     <string name="inline_minimize_button" msgid="966233327974702195">"Umanji"</string>
-    <!-- no translation found for inline_silent_button_silent (5315879183296940969) -->
-    <skip />
+    <string name="inline_silent_button_silent" msgid="5315879183296940969">"Nečujno"</string>
     <string name="inline_silent_button_stay_silent" msgid="6308371431217601009">"Ne uključuj zvuk"</string>
-    <!-- no translation found for inline_silent_button_alert (6008435419895088034) -->
-    <skip />
+    <string name="inline_silent_button_alert" msgid="6008435419895088034">"Upozoravanje"</string>
     <string name="inline_silent_button_keep_alerting" msgid="327696842264359693">"Nastavi sa obaveštenjima"</string>
     <string name="inline_turn_off_notifications" msgid="8635596135532202355">"Isključi obaveštenja"</string>
     <string name="inline_keep_showing_app" msgid="1723113469580031041">"Želite li da se obaveštenja iz ove aplikacije i dalje prikazuju?"</string>
-    <string name="notification_silence_title" msgid="7352089096356977930">"Diskretno"</string>
-    <string name="notification_alert_title" msgid="3966526305405016221">"Prioritetno"</string>
-    <string name="notification_channel_summary_low" msgid="1065819618107531284">"Pomaže vam da se fokusirate. Obaveštenja su samo na padajućoj traci. Uvek nečujno."</string>
-    <string name="notification_channel_summary_low_status" msgid="2702170424808743755">"Prikazuje se ispod prioritetnih obaveštenja. Uvek nečujno."</string>
-    <string name="notification_channel_summary_low_lock" msgid="7966605244472624458">"Prikazuje se ispod prioritetnih obaveštenja. Uvek nečujno."</string>
-    <string name="notification_channel_summary_low_status_lock" msgid="7012562768950012739">"Prikazuje se ispod prioritetnih obaveštenja. Uvek nečujno."</string>
-    <string name="notification_channel_summary_default" msgid="3847289783382316019">"Privlači vam pažnju pomoću zvuka i ikone statusne trake. Prikazuje se na zaključanom ekranu."</string>
+    <string name="notification_silence_title" msgid="5763240612242137433">"Nečujno"</string>
+    <string name="notification_alert_title" msgid="8031196611815490340">"Upozoravanje"</string>
+    <string name="notification_channel_summary_low" msgid="3387466082089715555">"Pomaže vam da se koncentrišete bez zvuka ili vibracije."</string>
+    <string name="notification_channel_summary_default" msgid="5994062840431965586">"Privlači vam pažnju pomoću zvuka ili vibracije."</string>
     <string name="notification_unblockable_desc" msgid="4556908766584964102">"Ova obaveštenja ne mogu da se menjaju."</string>
     <string name="notification_multichannel_desc" msgid="4695920306092240550">"Ova grupa obaveštenja ne može da se konfiguriše ovde"</string>
     <string name="notification_delegate_header" msgid="2857691673814814270">"Obaveštenje preko proksija"</string>
@@ -913,8 +905,7 @@
     <string name="slice_permission_allow" msgid="2340244901366722709">"Dozvoli"</string>
     <string name="slice_permission_deny" msgid="7683681514008048807">"Odbij"</string>
     <string name="auto_saver_title" msgid="1217959994732964228">"Dodirnite da biste napravili raspored za uštedu baterije"</string>
-    <!-- no translation found for auto_saver_text (2563289953551438248) -->
-    <skip />
+    <string name="auto_saver_text" msgid="2563289953551438248">"Uključite ako će baterija verovatno da se isprazni"</string>
     <string name="no_auto_saver_action" msgid="8086002101711328500">"Ne, hvala"</string>
     <string name="auto_saver_enabled_title" msgid="6726474226058316862">"Raspored za uštedu baterije je uključen"</string>
     <string name="auto_saver_enabled_text" msgid="874711029884777579">"Ušteda baterije će se automatski uključivati kada baterija padne ispod <xliff:g id="PERCENTAGE">%d</xliff:g>%%."</string>
@@ -947,4 +938,6 @@
     <string name="bubble_accessibility_action_move_bottom_left" msgid="206369104473183217">"Premesti dole levo"</string>
     <string name="bubble_accessibility_action_move_bottom_right" msgid="8705660152384312329">"Premesti dole desno"</string>
     <string name="bubble_dismiss_text" msgid="8028337712674081668">"Odbaci"</string>
+    <string name="notification_content_system_nav_changed" msgid="7218093915747788444">"Navigacija sistema je ažurirana. Da biste uneli izmene, idite u Podešavanja."</string>
+    <string name="notification_content_gesture_nav_available" msgid="8111130443656460792">"Idite u Podešavanja da biste ažurirali navigaciju sistema"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-be/strings.xml b/packages/SystemUI/res/values-be/strings.xml
index 4c459f2..0612acb 100644
--- a/packages/SystemUI/res/values-be/strings.xml
+++ b/packages/SystemUI/res/values-be/strings.xml
@@ -62,12 +62,10 @@
     <string name="usb_debugging_secondary_user_title" msgid="6353808721761220421">"Адладка USB не дапускаецца"</string>
     <string name="usb_debugging_secondary_user_message" msgid="6067122453571699801">"Карыстальнік, які зараз увайшоў у гэту прыладу, не можа ўключыць адладку USB. Каб выкарыстоўваць гэту функцыю, пераключыцеся на асноўнага карыстальніка."</string>
     <string name="usb_contaminant_title" msgid="206854874263058490">"Порт USB адключаны"</string>
-    <!-- no translation found for usb_contaminant_message (7379089091591609111) -->
-    <skip />
+    <string name="usb_contaminant_message" msgid="7379089091591609111">"Порт USB адключаны, каб засцерагчы прыладу ад вадкасці і смецця, таму дадатковае абсталяванне не будзе выяўлена.\n\nВы атрымаеце апавяшчэнне, калі порт USB можна будзе выкарыстоўваць зноў."</string>
     <string name="usb_port_enabled" msgid="7906141351687694867">"USB-порту дазволена вызначаць зарадныя прылады і аксесуары"</string>
     <string name="usb_disable_contaminant_detection" msgid="2103905315747120033">"Уключыць USB"</string>
-    <!-- no translation found for learn_more (5000517160980853569) -->
-    <skip />
+    <string name="learn_more" msgid="5000517160980853569">"Даведацца больш"</string>
     <string name="compat_mode_on" msgid="6623839244840638213">"Павял. на ўвесь экран"</string>
     <string name="compat_mode_off" msgid="4434467572461327898">"Расцягн. на ўвесь экран"</string>
     <string name="global_action_screenshot" msgid="8329831278085426283">"Здымак экрана"</string>
@@ -201,6 +199,7 @@
     <!-- String.format failed for translation -->
     <!-- no translation found for accessibility_battery_level (7451474187113371965) -->
     <skip />
+    <string name="accessibility_battery_level_with_estimate" msgid="9033100930684311630">"Зарад акумулятара ў працэнтах: <xliff:g id="PERCENTAGE">%1$s</xliff:g>. Пры такім выкарыстанні яго хопіць прыблізна на <xliff:g id="TIME">%2$s</xliff:g>"</string>
     <string name="accessibility_battery_level_charging" msgid="1147587904439319646">"Зарадка акумулятара: <xliff:g id="BATTERY_PERCENTAGE">%d</xliff:g>%%."</string>
     <string name="accessibility_settings_button" msgid="799583911231893380">"Сістэмныя налады."</string>
     <string name="accessibility_notifications_button" msgid="4498000369779421892">"Апавяшчэнні."</string>
@@ -466,10 +465,8 @@
     <string name="media_projection_remember_text" msgid="3103510882172746752">"Не паказваць зноў"</string>
     <string name="clear_all_notifications_text" msgid="814192889771462828">"Ачысціць усё"</string>
     <string name="manage_notifications_text" msgid="2386728145475108753">"Кіраваць"</string>
-    <!-- no translation found for notification_section_header_gentle (4372438504154095677) -->
-    <skip />
-    <!-- no translation found for accessibility_notification_section_header_gentle_clear_all (4286716295850400959) -->
-    <skip />
+    <string name="notification_section_header_gentle" msgid="4372438504154095677">"Апавяшчэнні без гуку"</string>
+    <string name="accessibility_notification_section_header_gentle_clear_all" msgid="4286716295850400959">"Выдаліць усе апавяшчэнні без гуку"</string>
     <string name="dnd_suppressing_shade_text" msgid="1904574852846769301">"Паказ апавяшчэнняў прыпынены ў рэжыме \"Не турбаваць\""</string>
     <string name="media_projection_action_text" msgid="8470872969457985954">"Пачаць зараз"</string>
     <string name="empty_shade_text" msgid="708135716272867002">"Апавяшчэнняў няма"</string>
@@ -653,21 +650,16 @@
     <string name="inline_block_button" msgid="8735843688021655065">"Заблакіраваць"</string>
     <string name="inline_keep_button" msgid="6665940297019018232">"Працягваць паказваць"</string>
     <string name="inline_minimize_button" msgid="966233327974702195">"Згарнуць"</string>
-    <!-- no translation found for inline_silent_button_silent (5315879183296940969) -->
-    <skip />
+    <string name="inline_silent_button_silent" msgid="5315879183296940969">"Бязгучны рэжым"</string>
     <string name="inline_silent_button_stay_silent" msgid="6308371431217601009">"Не ўключаць гук"</string>
-    <!-- no translation found for inline_silent_button_alert (6008435419895088034) -->
-    <skip />
+    <string name="inline_silent_button_alert" msgid="6008435419895088034">"Апавяшчаць"</string>
     <string name="inline_silent_button_keep_alerting" msgid="327696842264359693">"Апавяшчаць далей"</string>
     <string name="inline_turn_off_notifications" msgid="8635596135532202355">"Выключыць апавяшчэнні"</string>
     <string name="inline_keep_showing_app" msgid="1723113469580031041">"Працягваць паказваць апавяшчэнні гэтай праграмы?"</string>
-    <string name="notification_silence_title" msgid="7352089096356977930">"Ціхі рэжым"</string>
-    <string name="notification_alert_title" msgid="3966526305405016221">"Прыярытэтныя"</string>
-    <string name="notification_channel_summary_low" msgid="1065819618107531284">"Дапамагае не адцягваць увагу, паказваючы апавяшчэнні толькі на апушчанай шторцы. Заўсёды без гуку."</string>
-    <string name="notification_channel_summary_low_status" msgid="2702170424808743755">"Паказвае ўнізе апавяшчэнні з высокім прыярытэтам. Заўсёды без гуку."</string>
-    <string name="notification_channel_summary_low_lock" msgid="7966605244472624458">"Паказвае ўнізе апавяшчэнні з высокім прыярытэтам. Заўсёды без гуку."</string>
-    <string name="notification_channel_summary_low_status_lock" msgid="7012562768950012739">"Паказвае ўнізе апавяшчэнні з высокім прыярытэтам. Заўсёды без гуку."</string>
-    <string name="notification_channel_summary_default" msgid="3847289783382316019">"Прываблівае ўвагу гукам і значком на панэлі стану. Паказвае на экране блакіроўкі."</string>
+    <string name="notification_silence_title" msgid="5763240612242137433">"Бязгучны рэжым"</string>
+    <string name="notification_alert_title" msgid="8031196611815490340">"Абвесткі"</string>
+    <string name="notification_channel_summary_low" msgid="3387466082089715555">"Не адцягвае ўвагу дзякуючы выключаным гуку і вібрацыі."</string>
+    <string name="notification_channel_summary_default" msgid="5994062840431965586">"Прыцягвае ўвагу гукам і вібрацыяй."</string>
     <string name="notification_unblockable_desc" msgid="4556908766584964102">"Гэтыя апавяшчэнні нельга змяніць."</string>
     <string name="notification_multichannel_desc" msgid="4695920306092240550">"Тут канфігурыраваць гэту групу апавяшчэнняў забаронена"</string>
     <string name="notification_delegate_header" msgid="2857691673814814270">"Праксіраванае апавяшчэнне"</string>
@@ -920,8 +912,7 @@
     <string name="slice_permission_allow" msgid="2340244901366722709">"Дазволіць"</string>
     <string name="slice_permission_deny" msgid="7683681514008048807">"Адмовіць"</string>
     <string name="auto_saver_title" msgid="1217959994732964228">"Націсніце, каб уключыць рэжым эканоміі зараду"</string>
-    <!-- no translation found for auto_saver_text (2563289953551438248) -->
-    <skip />
+    <string name="auto_saver_text" msgid="2563289953551438248">"Уключыце, калі зарад акумулятара заканчваецца"</string>
     <string name="no_auto_saver_action" msgid="8086002101711328500">"Не, дзякуй"</string>
     <string name="auto_saver_enabled_title" msgid="6726474226058316862">"Уключаны рэжым эканоміі зараду"</string>
     <string name="auto_saver_enabled_text" msgid="874711029884777579">"Калі ўзровень зараду акумулятара знізіцца да <xliff:g id="PERCENTAGE">%d</xliff:g>%%, аўтаматычна ўключыцца рэжым эканоміі энергіі."</string>
@@ -954,4 +945,6 @@
     <string name="bubble_accessibility_action_move_bottom_left" msgid="206369104473183217">"Перамясціць лявей і ніжэй"</string>
     <string name="bubble_accessibility_action_move_bottom_right" msgid="8705660152384312329">"Перамясціць правей і ніжэй"</string>
     <string name="bubble_dismiss_text" msgid="8028337712674081668">"Адхіліць"</string>
+    <string name="notification_content_system_nav_changed" msgid="7218093915747788444">"Навігацыя ў сістэме абноўлена. Каб унесці змяненні, перайдзіце ў Налады."</string>
+    <string name="notification_content_gesture_nav_available" msgid="8111130443656460792">"Перайдзіце ў Налады, каб абнавіць параметры навігацыі ў сістэме"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-bg/strings.xml b/packages/SystemUI/res/values-bg/strings.xml
index ee07f5d..02768d1 100644
--- a/packages/SystemUI/res/values-bg/strings.xml
+++ b/packages/SystemUI/res/values-bg/strings.xml
@@ -62,12 +62,10 @@
     <string name="usb_debugging_secondary_user_title" msgid="6353808721761220421">"Отстраняването на грешки през USB не е разрешено"</string>
     <string name="usb_debugging_secondary_user_message" msgid="6067122453571699801">"Потребителят, който понастоящем е влязъл в това устройство, не може да включи функцията за отстраняване на грешки през USB. За да я използвате, превключете към основния потребител."</string>
     <string name="usb_contaminant_title" msgid="206854874263058490">"USB портът е деактивиран"</string>
-    <!-- no translation found for usb_contaminant_message (7379089091591609111) -->
-    <skip />
+    <string name="usb_contaminant_message" msgid="7379089091591609111">"С цел защита на устройството ви от течности и замърсяване USB портът е деактивиран и няма да открива аксесоари.\n\nЩе получите известие, когато можете отново да използвате USB порта."</string>
     <string name="usb_port_enabled" msgid="7906141351687694867">"USB портът може да разпознава зарядни устройства и аксесоари"</string>
     <string name="usb_disable_contaminant_detection" msgid="2103905315747120033">"Активиране на USB"</string>
-    <!-- no translation found for learn_more (5000517160980853569) -->
-    <skip />
+    <string name="learn_more" msgid="5000517160980853569">"Научете повече"</string>
     <string name="compat_mode_on" msgid="6623839244840638213">"Мащаб – запълва екрана"</string>
     <string name="compat_mode_off" msgid="4434467572461327898">"Разпъване – запълва екрана"</string>
     <string name="global_action_screenshot" msgid="8329831278085426283">"Екранна снимка"</string>
@@ -199,6 +197,7 @@
     <string name="carrier_network_change_mode" msgid="8149202439957837762">"Промяна на мрежата на оператора"</string>
     <string name="accessibility_battery_details" msgid="7645516654955025422">"Отваряне на подробностите за батерията"</string>
     <string name="accessibility_battery_level" msgid="7451474187113371965">"<xliff:g id="NUMBER">%d</xliff:g> процента батерия."</string>
+    <string name="accessibility_battery_level_with_estimate" msgid="9033100930684311630">"Батерията е на <xliff:g id="PERCENTAGE">%1$s</xliff:g> процента. Още около <xliff:g id="TIME">%2$s</xliff:g> въз основа на използването"</string>
     <string name="accessibility_battery_level_charging" msgid="1147587904439319646">"Батерията се зарежда – <xliff:g id="BATTERY_PERCENTAGE">%d</xliff:g>%%."</string>
     <string name="accessibility_settings_button" msgid="799583911231893380">"Системни настройки."</string>
     <string name="accessibility_notifications_button" msgid="4498000369779421892">"Известия."</string>
@@ -458,10 +457,8 @@
     <string name="media_projection_remember_text" msgid="3103510882172746752">"Да не се показва отново"</string>
     <string name="clear_all_notifications_text" msgid="814192889771462828">"Изчистване на всички"</string>
     <string name="manage_notifications_text" msgid="2386728145475108753">"Управление"</string>
-    <!-- no translation found for notification_section_header_gentle (4372438504154095677) -->
-    <skip />
-    <!-- no translation found for accessibility_notification_section_header_gentle_clear_all (4286716295850400959) -->
-    <skip />
+    <string name="notification_section_header_gentle" msgid="4372438504154095677">"Беззвучни известия"</string>
+    <string name="accessibility_notification_section_header_gentle_clear_all" msgid="4286716295850400959">"Изчистване на всички беззвучни известия"</string>
     <string name="dnd_suppressing_shade_text" msgid="1904574852846769301">"Известията са поставени на пауза от режима „Не безпокойте“"</string>
     <string name="media_projection_action_text" msgid="8470872969457985954">"Стартиране сега"</string>
     <string name="empty_shade_text" msgid="708135716272867002">"Няма известия"</string>
@@ -645,21 +642,16 @@
     <string name="inline_block_button" msgid="8735843688021655065">"Блокиране"</string>
     <string name="inline_keep_button" msgid="6665940297019018232">"Да продължат да се показват"</string>
     <string name="inline_minimize_button" msgid="966233327974702195">"Намаляване"</string>
-    <!-- no translation found for inline_silent_button_silent (5315879183296940969) -->
-    <skip />
+    <string name="inline_silent_button_silent" msgid="5315879183296940969">"Тих режим"</string>
     <string name="inline_silent_button_stay_silent" msgid="6308371431217601009">"Показване на известията без звук"</string>
-    <!-- no translation found for inline_silent_button_alert (6008435419895088034) -->
-    <skip />
+    <string name="inline_silent_button_alert" msgid="6008435419895088034">"Сигнализиране"</string>
     <string name="inline_silent_button_keep_alerting" msgid="327696842264359693">"Продължаване на сигнализирането"</string>
     <string name="inline_turn_off_notifications" msgid="8635596135532202355">"Изключване на известията"</string>
     <string name="inline_keep_showing_app" msgid="1723113469580031041">"Да продължат ли да се показват известията от това приложение?"</string>
-    <string name="notification_silence_title" msgid="7352089096356977930">"Ненатрапчиви известия"</string>
-    <string name="notification_alert_title" msgid="3966526305405016221">"Приоритетни известия"</string>
-    <string name="notification_channel_summary_low" msgid="1065819618107531284">"Помага ви да се съсредоточите, като известията се показват само в падащия панел. Винаги в тих режим."</string>
-    <string name="notification_channel_summary_low_status" msgid="2702170424808743755">"Показва се под приоритетните известия. Винаги в тих режим."</string>
-    <string name="notification_channel_summary_low_lock" msgid="7966605244472624458">"Показва се под приоритетните известия. Винаги в тих режим."</string>
-    <string name="notification_channel_summary_low_status_lock" msgid="7012562768950012739">"Показва се под приоритетните известия. Винаги в тих режим."</string>
-    <string name="notification_channel_summary_default" msgid="3847289783382316019">"Привлича вниманието ви със звук и икона в лентата на състоянието. Показва се на заключения екран."</string>
+    <string name="notification_silence_title" msgid="5763240612242137433">"Тих режим"</string>
+    <string name="notification_alert_title" msgid="8031196611815490340">"Сигнализиране"</string>
+    <string name="notification_channel_summary_low" msgid="3387466082089715555">"Помага ви да се фокусирате без звук или вибриране."</string>
+    <string name="notification_channel_summary_default" msgid="5994062840431965586">"Привлича вниманието ви със звук или вибриране."</string>
     <string name="notification_unblockable_desc" msgid="4556908766584964102">"Тези известия не могат да бъдат променяни."</string>
     <string name="notification_multichannel_desc" msgid="4695920306092240550">"Тази група от известия не може да бъде конфигурирана тук"</string>
     <string name="notification_delegate_header" msgid="2857691673814814270">"Известие, получено чрез делегиране"</string>
@@ -908,8 +900,7 @@
     <string name="slice_permission_allow" msgid="2340244901366722709">"Разрешаване"</string>
     <string name="slice_permission_deny" msgid="7683681514008048807">"Отказ"</string>
     <string name="auto_saver_title" msgid="1217959994732964228">"Докоснете, за да активирате автоматичния режим за запазване на батерията"</string>
-    <!-- no translation found for auto_saver_text (2563289953551438248) -->
-    <skip />
+    <string name="auto_saver_text" msgid="2563289953551438248">"Включване, когато е вероятно батерията да се изтощи"</string>
     <string name="no_auto_saver_action" msgid="8086002101711328500">"Не, благодаря"</string>
     <string name="auto_saver_enabled_title" msgid="6726474226058316862">"Включен е автоматичен режим за запазване на батерията"</string>
     <string name="auto_saver_enabled_text" msgid="874711029884777579">"Режимът за запазване на батерията ще се включи автоматично, след като нивото й премине под <xliff:g id="PERCENTAGE">%d</xliff:g>%%."</string>
@@ -942,4 +933,6 @@
     <string name="bubble_accessibility_action_move_bottom_left" msgid="206369104473183217">"Преместване долу вляво"</string>
     <string name="bubble_accessibility_action_move_bottom_right" msgid="8705660152384312329">"Преместване долу вдясно"</string>
     <string name="bubble_dismiss_text" msgid="8028337712674081668">"Отхвърляне"</string>
+    <string name="notification_content_system_nav_changed" msgid="7218093915747788444">"Режимът за навигиране в системата е актуализиран. За да извършите промени, отворете настройките."</string>
+    <string name="notification_content_gesture_nav_available" msgid="8111130443656460792">"Отворете настройките, за да актуализирате режима за навигиране в системата"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-bn/strings.xml b/packages/SystemUI/res/values-bn/strings.xml
index c04093a..8a8687f 100644
--- a/packages/SystemUI/res/values-bn/strings.xml
+++ b/packages/SystemUI/res/values-bn/strings.xml
@@ -62,12 +62,10 @@
     <string name="usb_debugging_secondary_user_title" msgid="6353808721761220421">"USB ডিবাগিং অনুমোদিত নয়"</string>
     <string name="usb_debugging_secondary_user_message" msgid="6067122453571699801">"ব্যবহারকারী এখন এই ডিভাইসে সাইন-ইন করেছেন তাই USB ডিবাগিং চালু করা যাবে না। এই বৈশিষ্ট্যটি ব্যবহার করতে, প্রাথমিক ব্যবহারকারীতে পাল্টে নিন।"</string>
     <string name="usb_contaminant_title" msgid="206854874263058490">"ইউএসবি পোর্ট বন্ধ করা হয়েছে"</string>
-    <!-- no translation found for usb_contaminant_message (7379089091591609111) -->
-    <skip />
+    <string name="usb_contaminant_message" msgid="7379089091591609111">"কোনও তরল পদার্থ ও ধুলো থেকে আপনার ডিভাইসকে সুরক্ষিত রাখতে, ইউএসবি পোর্ট বন্ধ করা আছে, তাই কোনও অ্যাক্সেসরির শনাক্ত করা যাবে না।\n\nইউএসবি পোর্ট আবার ব্যবহার করা নিরাপদ হলে, আপনাকে জানানো হবে।"</string>
     <string name="usb_port_enabled" msgid="7906141351687694867">"চার্জার ও আনুষঙ্গিক আইটেম শনাক্ত করার জন্য ইউএসবি চালু করা হয়েছে"</string>
     <string name="usb_disable_contaminant_detection" msgid="2103905315747120033">"ইউএসবি চালু করুন"</string>
-    <!-- no translation found for learn_more (5000517160980853569) -->
-    <skip />
+    <string name="learn_more" msgid="5000517160980853569">"আরও জানুন"</string>
     <string name="compat_mode_on" msgid="6623839244840638213">"স্ক্রীণ পূরণ করতে জুম করুন"</string>
     <string name="compat_mode_off" msgid="4434467572461327898">"ফুল স্ক্রিন করুন"</string>
     <string name="global_action_screenshot" msgid="8329831278085426283">"স্ক্রিনশট নিন"</string>
@@ -199,6 +197,7 @@
     <string name="carrier_network_change_mode" msgid="8149202439957837762">"পরিষেবা প্রদানকারীর নেটওয়ার্ক পরিবর্তন করা হচ্ছে"</string>
     <string name="accessibility_battery_details" msgid="7645516654955025422">"ব্যাটারির বিশদ বিবরণ খুলুন"</string>
     <string name="accessibility_battery_level" msgid="7451474187113371965">"<xliff:g id="NUMBER">%d</xliff:g> শতাংশ ব্যাটারি রয়েছে৷"</string>
+    <string name="accessibility_battery_level_with_estimate" msgid="9033100930684311630">"ব্যাটারি <xliff:g id="PERCENTAGE">%1$s</xliff:g> শতাংশ, বর্তমান ব্যবহারের উপর ভিত্তি করে আর <xliff:g id="TIME">%2$s</xliff:g> চলবে"</string>
     <string name="accessibility_battery_level_charging" msgid="1147587904439319646">"ব্যাটারি চার্জ হচ্ছে, <xliff:g id="BATTERY_PERCENTAGE">%d</xliff:g> শতাংশ৷"</string>
     <string name="accessibility_settings_button" msgid="799583911231893380">"সিস্টেম সেটিংস৷"</string>
     <string name="accessibility_notifications_button" msgid="4498000369779421892">"বিজ্ঞপ্তি৷"</string>
@@ -458,10 +457,8 @@
     <string name="media_projection_remember_text" msgid="3103510882172746752">"আর দেখাবেন না"</string>
     <string name="clear_all_notifications_text" msgid="814192889771462828">"সবকিছু সাফ করুন"</string>
     <string name="manage_notifications_text" msgid="2386728145475108753">"পরিচালনা করুন"</string>
-    <!-- no translation found for notification_section_header_gentle (4372438504154095677) -->
-    <skip />
-    <!-- no translation found for accessibility_notification_section_header_gentle_clear_all (4286716295850400959) -->
-    <skip />
+    <string name="notification_section_header_gentle" msgid="4372438504154095677">"নীরব বিজ্ঞপ্তি"</string>
+    <string name="accessibility_notification_section_header_gentle_clear_all" msgid="4286716295850400959">"সব নীরব বিজ্ঞপ্তি মুছুন"</string>
     <string name="dnd_suppressing_shade_text" msgid="1904574852846769301">"\'বিরক্ত করবেন না\' দিয়ে বিজ্ঞপ্তি পজ করা হয়েছে"</string>
     <string name="media_projection_action_text" msgid="8470872969457985954">"এখন শুরু করুন"</string>
     <string name="empty_shade_text" msgid="708135716272867002">"কোনো বিজ্ঞপ্তি নেই"</string>
@@ -645,21 +642,16 @@
     <string name="inline_block_button" msgid="8735843688021655065">"ব্লক করুন"</string>
     <string name="inline_keep_button" msgid="6665940297019018232">"দেখতে থাকুন"</string>
     <string name="inline_minimize_button" msgid="966233327974702195">"ছোট করে দিন"</string>
-    <!-- no translation found for inline_silent_button_silent (5315879183296940969) -->
-    <skip />
+    <string name="inline_silent_button_silent" msgid="5315879183296940969">"নীরব রাখুন"</string>
     <string name="inline_silent_button_stay_silent" msgid="6308371431217601009">"বিজ্ঞপ্তি মিউট করুন"</string>
-    <!-- no translation found for inline_silent_button_alert (6008435419895088034) -->
-    <skip />
+    <string name="inline_silent_button_alert" msgid="6008435419895088034">"সতর্ক করুন"</string>
     <string name="inline_silent_button_keep_alerting" msgid="327696842264359693">"বিজ্ঞপ্তি পান"</string>
     <string name="inline_turn_off_notifications" msgid="8635596135532202355">"বিজ্ঞপ্তি বন্ধ করুন"</string>
     <string name="inline_keep_showing_app" msgid="1723113469580031041">"এই অ্যাপের বিজ্ঞপ্তি পরেও দেখে যেতে চান?"</string>
-    <string name="notification_silence_title" msgid="7352089096356977930">"সাইলেন্ট মোডে"</string>
-    <string name="notification_alert_title" msgid="3966526305405016221">"অগ্রাধিকার দেওয়া হয়েছে"</string>
-    <string name="notification_channel_summary_low" msgid="1065819618107531284">"আপনি যাতে বিরক্ত না হন, তার জন্য শুধুমাত্র পুল-ডাউন শেডে এই বিজ্ঞপ্তি দেখায়। সবসময় সাইলেন্ট।"</string>
-    <string name="notification_channel_summary_low_status" msgid="2702170424808743755">"অগ্রাধিকারযুক্ত বিজ্ঞপ্তির নিচে দেখানো হয়। সবসময় সাইলেন্ট।"</string>
-    <string name="notification_channel_summary_low_lock" msgid="7966605244472624458">"অগ্রাধিকারযুক্ত বিজ্ঞপ্তির নিচে দেখানো হয়। সবসময় সাইলেন্ট।"</string>
-    <string name="notification_channel_summary_low_status_lock" msgid="7012562768950012739">"অগ্রাধিকারযুক্ত বিজ্ঞপ্তির নিচে দেখানো হয়। সবসময় সাইলেন্ট।"</string>
-    <string name="notification_channel_summary_default" msgid="3847289783382316019">"সাউন্ড ও স্ট্যাটাস বার আইকনের সাহায্যে দৃষ্টি আকর্ষণ করে। এটি লক স্ক্রিনে দেখা যায়।"</string>
+    <string name="notification_silence_title" msgid="5763240612242137433">"সাইলেন্ট"</string>
+    <string name="notification_alert_title" msgid="8031196611815490340">"সতর্ক করুন"</string>
+    <string name="notification_channel_summary_low" msgid="3387466082089715555">"সাউন্ড বা ভাইব্রেশন ছাড়া ফোকাস করতে আপনাকে সাহায্য করে।"</string>
+    <string name="notification_channel_summary_default" msgid="5994062840431965586">"সাউন্ড বা ভাইব্রেশনের সাহায্যে দৃষ্টি আকর্ষণ করে।"</string>
     <string name="notification_unblockable_desc" msgid="4556908766584964102">"এই বিজ্ঞপ্তিগুলি পরিবর্তন করা যাবে না।"</string>
     <string name="notification_multichannel_desc" msgid="4695920306092240550">"এই সমস্ত বিজ্ঞপ্তিকে এখানে কনফিগার করা যাবে না"</string>
     <string name="notification_delegate_header" msgid="2857691673814814270">"প্রক্সি করা বিজ্ঞপ্তি"</string>
@@ -908,8 +900,7 @@
     <string name="slice_permission_allow" msgid="2340244901366722709">"অনুমতি দিন"</string>
     <string name="slice_permission_deny" msgid="7683681514008048807">"খারিজ করুন"</string>
     <string name="auto_saver_title" msgid="1217959994732964228">"ব্যাটারি সেভার চালু হওয়ার সময় সেট করতে ট্যাপ করুন"</string>
-    <!-- no translation found for auto_saver_text (2563289953551438248) -->
-    <skip />
+    <string name="auto_saver_text" msgid="2563289953551438248">"ব্যাটারির চার্জ শেষ হয়ে যাওয়ার সম্ভাবনা দেখা দিলে চালু করুন"</string>
     <string name="no_auto_saver_action" msgid="8086002101711328500">"না থাক"</string>
     <string name="auto_saver_enabled_title" msgid="6726474226058316862">"আগে সেট করা সময় অনুযায়ী ব্যাটারি সেভার চালু হয়েছে"</string>
     <string name="auto_saver_enabled_text" msgid="874711029884777579">"চার্জ <xliff:g id="PERCENTAGE">%d</xliff:g>%%-এর নিচে চলে গেলে ব্যাটারি সেভার নিজে থেকেই চালু হয়ে যাবে।"</string>
@@ -942,4 +933,6 @@
     <string name="bubble_accessibility_action_move_bottom_left" msgid="206369104473183217">"নিচে বাঁদিকে সরান"</string>
     <string name="bubble_accessibility_action_move_bottom_right" msgid="8705660152384312329">"নিচে ডান দিকে সরান"</string>
     <string name="bubble_dismiss_text" msgid="8028337712674081668">"খারিজ করুন"</string>
+    <string name="notification_content_system_nav_changed" msgid="7218093915747788444">"সিস্টেম নেভিগেশন আপডেট হয়েছে। পরিবর্তন করার জন্য সেটিংসে যান।"</string>
+    <string name="notification_content_gesture_nav_available" msgid="8111130443656460792">"সিস্টেম নেভিগেশন আপডেট করতে সেটিংসে যান"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-bs/strings.xml b/packages/SystemUI/res/values-bs/strings.xml
index e0ef1bd..75e0ba93 100644
--- a/packages/SystemUI/res/values-bs/strings.xml
+++ b/packages/SystemUI/res/values-bs/strings.xml
@@ -62,12 +62,10 @@
     <string name="usb_debugging_secondary_user_title" msgid="6353808721761220421">"Otklanjanje grešaka putem uređaja spojenog na USB nije dozvoljeno"</string>
     <string name="usb_debugging_secondary_user_message" msgid="6067122453571699801">"Korisnik koji je trenutno prijavljen na ovaj uređaj ne može uključiti opciju za otklanjanje grešaka koristeći USB. Da koristite tu funkciju, prebacite se na primarnog korisnika."</string>
     <string name="usb_contaminant_title" msgid="206854874263058490">"USB priključak je onemogućen"</string>
-    <!-- no translation found for usb_contaminant_message (7379089091591609111) -->
-    <skip />
+    <string name="usb_contaminant_message" msgid="7379089091591609111">"USB priključak je onemogućen kako bi se vaš uređaj zaštitio od tečnosti i nečistoća i neće detektirati priključene uređaje.\n\nDobit ćete obavještenje kada ponovo bude sigurno koristiti USB priključak."</string>
     <string name="usb_port_enabled" msgid="7906141351687694867">"USB priključak je omogućen za prepoznavanje punjača i pribora"</string>
     <string name="usb_disable_contaminant_detection" msgid="2103905315747120033">"Omogući USB"</string>
-    <!-- no translation found for learn_more (5000517160980853569) -->
-    <skip />
+    <string name="learn_more" msgid="5000517160980853569">"Saznajte više"</string>
     <string name="compat_mode_on" msgid="6623839244840638213">"Uvećaj prikaz na ekran"</string>
     <string name="compat_mode_off" msgid="4434467572461327898">"Razvuci prikaz na ekran"</string>
     <string name="global_action_screenshot" msgid="8329831278085426283">"Snimak ekrana"</string>
@@ -199,6 +197,7 @@
     <string name="carrier_network_change_mode" msgid="8149202439957837762">"Promjena mreže mobilnog operatera"</string>
     <string name="accessibility_battery_details" msgid="7645516654955025422">"Otvori detalje o potrošnji baterije"</string>
     <string name="accessibility_battery_level" msgid="7451474187113371965">"Baterija na <xliff:g id="NUMBER">%d</xliff:g> posto."</string>
+    <string name="accessibility_battery_level_with_estimate" msgid="9033100930684311630">"Baterija je na <xliff:g id="PERCENTAGE">%1$s</xliff:g> posto. Na osnovu vaše potrošnje preostalo vam je otprilike <xliff:g id="TIME">%2$s</xliff:g>"</string>
     <string name="accessibility_battery_level_charging" msgid="1147587904439319646">"Punjenje baterije, <xliff:g id="BATTERY_PERCENTAGE">%d</xliff:g>%%."</string>
     <string name="accessibility_settings_button" msgid="799583911231893380">"Postavke sistema."</string>
     <string name="accessibility_notifications_button" msgid="4498000369779421892">"Obavještenja."</string>
@@ -461,10 +460,8 @@
     <string name="media_projection_remember_text" msgid="3103510882172746752">"Ne prikazuj opet"</string>
     <string name="clear_all_notifications_text" msgid="814192889771462828">"Očisti sve"</string>
     <string name="manage_notifications_text" msgid="2386728145475108753">"Upravljaj"</string>
-    <!-- no translation found for notification_section_header_gentle (4372438504154095677) -->
-    <skip />
-    <!-- no translation found for accessibility_notification_section_header_gentle_clear_all (4286716295850400959) -->
-    <skip />
+    <string name="notification_section_header_gentle" msgid="4372438504154095677">"Nečujna obavještenja"</string>
+    <string name="accessibility_notification_section_header_gentle_clear_all" msgid="4286716295850400959">"Obriši sva nečujna obavještenja"</string>
     <string name="dnd_suppressing_shade_text" msgid="1904574852846769301">"Obavještenja su pauzirana načinom rada Ne ometaj"</string>
     <string name="media_projection_action_text" msgid="8470872969457985954">"Započni odmah"</string>
     <string name="empty_shade_text" msgid="708135716272867002">"Nema obavještenja"</string>
@@ -650,21 +647,16 @@
     <string name="inline_block_button" msgid="8735843688021655065">"Blokiraj"</string>
     <string name="inline_keep_button" msgid="6665940297019018232">"Nastavi prikazivanje"</string>
     <string name="inline_minimize_button" msgid="966233327974702195">"Minimiziraj"</string>
-    <!-- no translation found for inline_silent_button_silent (5315879183296940969) -->
-    <skip />
+    <string name="inline_silent_button_silent" msgid="5315879183296940969">"Nečujno"</string>
     <string name="inline_silent_button_stay_silent" msgid="6308371431217601009">"Ostani u nečujnom načinu rada"</string>
-    <!-- no translation found for inline_silent_button_alert (6008435419895088034) -->
-    <skip />
+    <string name="inline_silent_button_alert" msgid="6008435419895088034">"Upozorenja"</string>
     <string name="inline_silent_button_keep_alerting" msgid="327696842264359693">"Nastavi upozoravati"</string>
     <string name="inline_turn_off_notifications" msgid="8635596135532202355">"Isključi obavještenja"</string>
     <string name="inline_keep_showing_app" msgid="1723113469580031041">"Nastaviti prikazivanje obavještenja iz ove aplikacije?"</string>
-    <string name="notification_silence_title" msgid="7352089096356977930">"Diskretno"</string>
-    <string name="notification_alert_title" msgid="3966526305405016221">"Prioritetno"</string>
-    <string name="notification_channel_summary_low" msgid="1065819618107531284">"Pomaže vam da se fokusirate prikazujući obavještenja samo na padajućoj traci. Uvijek nečujno."</string>
-    <string name="notification_channel_summary_low_status" msgid="2702170424808743755">"Prikazuje se ispod prioritetnih obavještenja. Uvijek nečujno."</string>
-    <string name="notification_channel_summary_low_lock" msgid="7966605244472624458">"Prikazuje se ispod prioritetnih obavještenja. Uvijek nečujno."</string>
-    <string name="notification_channel_summary_low_status_lock" msgid="7012562768950012739">"Prikazuje se ispod prioritetnih obavještenja. Uvijek nečujno."</string>
-    <string name="notification_channel_summary_default" msgid="3847289783382316019">"Privlači vašu pažnju pomoću zvuka i ikone na statusnoj traci. Prikazuje se na zaključanom ekranu."</string>
+    <string name="notification_silence_title" msgid="5763240612242137433">"Nečujno"</string>
+    <string name="notification_alert_title" msgid="8031196611815490340">"Upozorenja"</string>
+    <string name="notification_channel_summary_low" msgid="3387466082089715555">"Pomaže vam da se koncentrirate bez zvuka ili vibracije."</string>
+    <string name="notification_channel_summary_default" msgid="5994062840431965586">"Privlači vašu pažnju pomoću zvuka ili vibracije."</string>
     <string name="notification_unblockable_desc" msgid="4556908766584964102">"Ta obavještenja se ne mogu izmijeniti."</string>
     <string name="notification_multichannel_desc" msgid="4695920306092240550">"Ovdje nije moguće konfigurirati ovu grupu obavještenja"</string>
     <string name="notification_delegate_header" msgid="2857691673814814270">"Obavještenje preko proksi servera"</string>
@@ -915,8 +907,7 @@
     <string name="slice_permission_allow" msgid="2340244901366722709">"Dozvoli"</string>
     <string name="slice_permission_deny" msgid="7683681514008048807">"Odbij"</string>
     <string name="auto_saver_title" msgid="1217959994732964228">"Dodirnite da zakažete Uštedu baterije"</string>
-    <!-- no translation found for auto_saver_text (2563289953551438248) -->
-    <skip />
+    <string name="auto_saver_text" msgid="2563289953551438248">"Uključite ako je vjerovatno da će se baterija istrošiti"</string>
     <string name="no_auto_saver_action" msgid="8086002101711328500">"Ne, hvala"</string>
     <string name="auto_saver_enabled_title" msgid="6726474226058316862">"Zakazivanje Uštede baterije je uključeno"</string>
     <string name="auto_saver_enabled_text" msgid="874711029884777579">"Kada je baterija ispod <xliff:g id="PERCENTAGE">%d</xliff:g>%%, Ušteda baterije se automatski uključuje."</string>
@@ -949,4 +940,6 @@
     <string name="bubble_accessibility_action_move_bottom_left" msgid="206369104473183217">"Pomjeri dolje lijevo"</string>
     <string name="bubble_accessibility_action_move_bottom_right" msgid="8705660152384312329">"Pomjerite dolje desno"</string>
     <string name="bubble_dismiss_text" msgid="8028337712674081668">"Odbaci"</string>
+    <string name="notification_content_system_nav_changed" msgid="7218093915747788444">"Navigiranje sistemom je ažurirano. Da izvršite promjene, idite u Postavke."</string>
+    <string name="notification_content_gesture_nav_available" msgid="8111130443656460792">"Idite u Postavke da ažurirate navigiranje sistemom"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-ca/strings.xml b/packages/SystemUI/res/values-ca/strings.xml
index 19be829..da625fa 100644
--- a/packages/SystemUI/res/values-ca/strings.xml
+++ b/packages/SystemUI/res/values-ca/strings.xml
@@ -62,12 +62,10 @@
     <string name="usb_debugging_secondary_user_title" msgid="6353808721761220421">"No es permet la depuració per USB"</string>
     <string name="usb_debugging_secondary_user_message" msgid="6067122453571699801">"L\'usuari que té iniciada la sessió al dispositiu en aquest moment no pot activar la depuració per USB. Per utilitzar aquesta funció, cal canviar a l\'usuari principal."</string>
     <string name="usb_contaminant_title" msgid="206854874263058490">"El port USB està desactivat"</string>
-    <!-- no translation found for usb_contaminant_message (7379089091591609111) -->
-    <skip />
+    <string name="usb_contaminant_message" msgid="7379089091591609111">"Per protegir el teu dispositiu dels líquids o de la pols, el port USB s\'ha desactivat i no detectarà cap accessori.\n\nRebràs una notificació quan puguis tornar a utilitzar-lo."</string>
     <string name="usb_port_enabled" msgid="7906141351687694867">"S\'ha activat el port USB per detectar carregadors i accessoris"</string>
     <string name="usb_disable_contaminant_detection" msgid="2103905315747120033">"Activa l\'USB"</string>
-    <!-- no translation found for learn_more (5000517160980853569) -->
-    <skip />
+    <string name="learn_more" msgid="5000517160980853569">"Més informació"</string>
     <string name="compat_mode_on" msgid="6623839244840638213">"Zoom per omplir pantalla"</string>
     <string name="compat_mode_off" msgid="4434467572461327898">"Estira per omplir pant."</string>
     <string name="global_action_screenshot" msgid="8329831278085426283">"Captura de pantalla"</string>
@@ -199,6 +197,7 @@
     <string name="carrier_network_change_mode" msgid="8149202439957837762">"S\'està canviant la xarxa de l\'operador de telefonia mòbil"</string>
     <string name="accessibility_battery_details" msgid="7645516654955025422">"Obre els detalls de la bateria"</string>
     <string name="accessibility_battery_level" msgid="7451474187113371965">"<xliff:g id="NUMBER">%d</xliff:g> per cent de bateria."</string>
+    <string name="accessibility_battery_level_with_estimate" msgid="9033100930684311630">"<xliff:g id="PERCENTAGE">%1$s</xliff:g> per cent de bateria amb aproximadament <xliff:g id="TIME">%2$s</xliff:g> de temps restant segons l\'ús que en fas"</string>
     <string name="accessibility_battery_level_charging" msgid="1147587904439319646">"La bateria s\'està carregant, <xliff:g id="BATTERY_PERCENTAGE">%d</xliff:g>%%."</string>
     <string name="accessibility_settings_button" msgid="799583911231893380">"Configuració del sistema."</string>
     <string name="accessibility_notifications_button" msgid="4498000369779421892">"Notificacions."</string>
@@ -413,10 +412,10 @@
     <string name="interruption_level_none_twoline" msgid="3957581548190765889">"Silenci\ntotal"</string>
     <string name="interruption_level_priority_twoline" msgid="1564715335217164124">"Només\ninterr. prior."</string>
     <string name="interruption_level_alarms_twoline" msgid="3266909566410106146">"Només\nalarmes"</string>
-    <string name="keyguard_indication_charging_time_wireless" msgid="6959284458466962592">"<xliff:g id="PERCENTAGE">%2$s</xliff:g> • S\'està carregant sense fil (temps restant: <xliff:g id="CHARGING_TIME_LEFT">%1$s</xliff:g>)"</string>
-    <string name="keyguard_indication_charging_time" msgid="2056340799276374421">"<xliff:g id="PERCENTAGE">%2$s</xliff:g> • S\'està carregant (temps restant: <xliff:g id="CHARGING_TIME_LEFT">%1$s</xliff:g>)"</string>
+    <string name="keyguard_indication_charging_time_wireless" msgid="6959284458466962592">"<xliff:g id="PERCENTAGE">%2$s</xliff:g> • S\'està carregant sense fil (<xliff:g id="CHARGING_TIME_LEFT">%1$s</xliff:g> per completar la càrrega)"</string>
+    <string name="keyguard_indication_charging_time" msgid="2056340799276374421">"<xliff:g id="PERCENTAGE">%2$s</xliff:g> • S\'està carregant (<xliff:g id="CHARGING_TIME_LEFT">%1$s</xliff:g> per completar la càrrega)"</string>
     <string name="keyguard_indication_charging_time_fast" msgid="7767562163577492332">"<xliff:g id="PERCENTAGE">%2$s</xliff:g> • Carregant ràpidament (temps restant: <xliff:g id="CHARGING_TIME_LEFT">%1$s</xliff:g>)"</string>
-    <string name="keyguard_indication_charging_time_slowly" msgid="3769655133567307069">"<xliff:g id="PERCENTAGE">%2$s</xliff:g> • Carregant lentament (temps restant: <xliff:g id="CHARGING_TIME_LEFT">%1$s</xliff:g>)"</string>
+    <string name="keyguard_indication_charging_time_slowly" msgid="3769655133567307069">"<xliff:g id="PERCENTAGE">%2$s</xliff:g> • Carregant lentament (<xliff:g id="CHARGING_TIME_LEFT">%1$s</xliff:g> per completar la càrrega)"</string>
     <string name="accessibility_multi_user_switch_switcher" msgid="7305948938141024937">"Canvia d\'usuari"</string>
     <string name="accessibility_multi_user_switch_switcher_with_current" msgid="8434880595284601601">"Canvia d\'usuari. Usuari actual: <xliff:g id="CURRENT_USER_NAME">%s</xliff:g>"</string>
     <string name="accessibility_multi_user_switch_inactive" msgid="1424081831468083402">"Usuari actual: <xliff:g id="CURRENT_USER_NAME">%s</xliff:g>"</string>
@@ -458,10 +457,8 @@
     <string name="media_projection_remember_text" msgid="3103510882172746752">"No ho tornis a mostrar"</string>
     <string name="clear_all_notifications_text" msgid="814192889771462828">"Esborra-ho tot"</string>
     <string name="manage_notifications_text" msgid="2386728145475108753">"Gestió"</string>
-    <!-- no translation found for notification_section_header_gentle (4372438504154095677) -->
-    <skip />
-    <!-- no translation found for accessibility_notification_section_header_gentle_clear_all (4286716295850400959) -->
-    <skip />
+    <string name="notification_section_header_gentle" msgid="4372438504154095677">"Notificacions silencioses"</string>
+    <string name="accessibility_notification_section_header_gentle_clear_all" msgid="4286716295850400959">"Esborra totes les notificacions silencioses"</string>
     <string name="dnd_suppressing_shade_text" msgid="1904574852846769301">"Notificacions pausades pel mode No molestis"</string>
     <string name="media_projection_action_text" msgid="8470872969457985954">"Comença ara"</string>
     <string name="empty_shade_text" msgid="708135716272867002">"Cap notificació"</string>
@@ -546,7 +543,7 @@
     <string name="screen_pinning_description_recents_invisible_accessible" msgid="6134833683151189507">"Aquest element es continuarà mostrant fins que deixis de fixar-lo. Per fer-ho, mantén premut el botó d\'inici."</string>
     <string name="screen_pinning_toast" msgid="2266705122951934150">"Per deixar de fixar aquesta pantalla, mantén premuts els botons Enrere i Aplicacions recents"</string>
     <string name="screen_pinning_toast_recents_invisible" msgid="8252402309499161281">"Per deixar de fixar aquesta pantalla, mantén premuts els botons Enrere i Inici"</string>
-    <string name="screen_pinning_positive" msgid="3783985798366751226">"D\'acord"</string>
+    <string name="screen_pinning_positive" msgid="3783985798366751226">"Entesos"</string>
     <string name="screen_pinning_negative" msgid="3741602308343880268">"No, gràcies"</string>
     <string name="screen_pinning_start" msgid="1022122128489278317">"S\'ha fitxat la pantalla"</string>
     <string name="screen_pinning_exit" msgid="5187339744262325372">"S\'ha deixat de fixar la pantalla"</string>
@@ -610,7 +607,7 @@
     <string name="tuner_warning_title" msgid="7094689930793031682">"Diversió per a uns quants, però no per a tothom"</string>
     <string name="tuner_warning" msgid="8730648121973575701">"El Personalitzador d\'interfície d\'usuari presenta opcions addicionals per canviar i personalitzar la interfície d\'usuari d\'Android. És possible que aquestes funcions experimentals canviïn, deixin de funcionar o desapareguin en versions futures. Continua amb precaució."</string>
     <string name="tuner_persistent_warning" msgid="8597333795565621795">"És possible que aquestes funcions experimentals canviïn, deixin de funcionar o desapareguin en versions futures. Continua amb precaució."</string>
-    <string name="got_it" msgid="2239653834387972602">"D\'acord"</string>
+    <string name="got_it" msgid="2239653834387972602">"Entesos"</string>
     <string name="tuner_toast" msgid="603429811084428439">"Enhorabona! El Personalitzador d\'interfície d\'usuari s\'ha afegit a Configuració."</string>
     <string name="remove_from_settings" msgid="8389591916603406378">"Treu de Configuració"</string>
     <string name="remove_from_settings_prompt" msgid="6069085993355887748">"Vols suprimir el Personalitzador d\'interfície d\'usuari de Configuració i deixar d\'utilitzar-ne totes les funcions?"</string>
@@ -645,21 +642,16 @@
     <string name="inline_block_button" msgid="8735843688021655065">"Bloqueja"</string>
     <string name="inline_keep_button" msgid="6665940297019018232">"Continua rebent"</string>
     <string name="inline_minimize_button" msgid="966233327974702195">"Minimitza"</string>
-    <!-- no translation found for inline_silent_button_silent (5315879183296940969) -->
-    <skip />
+    <string name="inline_silent_button_silent" msgid="5315879183296940969">"Silencioses"</string>
     <string name="inline_silent_button_stay_silent" msgid="6308371431217601009">"Continua silenciant"</string>
-    <!-- no translation found for inline_silent_button_alert (6008435419895088034) -->
-    <skip />
+    <string name="inline_silent_button_alert" msgid="6008435419895088034">"Alertes"</string>
     <string name="inline_silent_button_keep_alerting" msgid="327696842264359693">"Continua avisant-me"</string>
     <string name="inline_turn_off_notifications" msgid="8635596135532202355">"Desactiva les notificacions"</string>
     <string name="inline_keep_showing_app" msgid="1723113469580031041">"Vols continuar rebent notificacions d\'aquesta aplicació?"</string>
-    <string name="notification_silence_title" msgid="7352089096356977930">"Discreta"</string>
-    <string name="notification_alert_title" msgid="3966526305405016221">"Prioritàries"</string>
-    <string name="notification_channel_summary_low" msgid="1065819618107531284">"T\'ajuda a concentrar-te perquè les notificacions només es mostren a l\'àrea desplegable. Sempre en silenci."</string>
-    <string name="notification_channel_summary_low_status" msgid="2702170424808743755">"Es mostren a sota de les notificacions prioritàries. Sempre silencioses."</string>
-    <string name="notification_channel_summary_low_lock" msgid="7966605244472624458">"Es mostren a sota de les notificacions prioritàries. Sempre silencioses."</string>
-    <string name="notification_channel_summary_low_status_lock" msgid="7012562768950012739">"Es mostren a sota de les notificacions prioritàries. Sempre silencioses."</string>
-    <string name="notification_channel_summary_default" msgid="3847289783382316019">"Atrauen la teva atenció amb un so i una icona a la barra d\'estat. Es mostren a la pantalla de bloqueig."</string>
+    <string name="notification_silence_title" msgid="5763240612242137433">"Silenci"</string>
+    <string name="notification_alert_title" msgid="8031196611815490340">"Alertes"</string>
+    <string name="notification_channel_summary_low" msgid="3387466082089715555">"T\'ajuda a concentrar-te sense so ni vibració."</string>
+    <string name="notification_channel_summary_default" msgid="5994062840431965586">"Atrau la teva atenció amb so i vibració."</string>
     <string name="notification_unblockable_desc" msgid="4556908766584964102">"Aquestes notificacions no es poden modificar."</string>
     <string name="notification_multichannel_desc" msgid="4695920306092240550">"Aquest grup de notificacions no es pot configurar aquí"</string>
     <string name="notification_delegate_header" msgid="2857691673814814270">"Notificació mitjançant aplicació intermediària"</string>
@@ -908,13 +900,12 @@
     <string name="slice_permission_allow" msgid="2340244901366722709">"Permet"</string>
     <string name="slice_permission_deny" msgid="7683681514008048807">"Denega"</string>
     <string name="auto_saver_title" msgid="1217959994732964228">"Toca per programar l\'estalvi de bateria"</string>
-    <!-- no translation found for auto_saver_text (2563289953551438248) -->
-    <skip />
+    <string name="auto_saver_text" msgid="2563289953551438248">"Activa\'l quan sigui probable que et quedis sense bateria"</string>
     <string name="no_auto_saver_action" msgid="8086002101711328500">"No"</string>
     <string name="auto_saver_enabled_title" msgid="6726474226058316862">"S\'ha activat la programació de l\'estalvi de bateria"</string>
     <string name="auto_saver_enabled_text" msgid="874711029884777579">"L\'estalvi de bateria s\'activarà automàticament quan el nivell de bateria sigui inferior al <xliff:g id="PERCENTAGE">%d</xliff:g>%%."</string>
     <string name="open_saver_setting_action" msgid="8314624730997322529">"Configuració"</string>
-    <string name="auto_saver_okay_action" msgid="2701221740227683650">"D\'acord"</string>
+    <string name="auto_saver_okay_action" msgid="2701221740227683650">"Entesos"</string>
     <string name="heap_dump_tile_name" msgid="9141031328971226374">"Aboca espai de SysUI"</string>
     <string name="ongoing_privacy_chip_content_single_app" msgid="4479560741898690064">"<xliff:g id="APP">%1$s</xliff:g> està fent servir el següent: <xliff:g id="TYPES_LIST">%2$s</xliff:g>."</string>
     <string name="ongoing_privacy_chip_content_multiple_apps" msgid="8640691753867990511">"Algunes aplicacions estan fent servir el següent: <xliff:g id="TYPES_LIST">%s</xliff:g>."</string>
@@ -942,4 +933,6 @@
     <string name="bubble_accessibility_action_move_bottom_left" msgid="206369104473183217">"Mou a baix a l\'esquerra"</string>
     <string name="bubble_accessibility_action_move_bottom_right" msgid="8705660152384312329">"Mou a baix a la dreta"</string>
     <string name="bubble_dismiss_text" msgid="8028337712674081668">"Omet"</string>
+    <string name="notification_content_system_nav_changed" msgid="7218093915747788444">"S\'ha actualitzat el sistema de navegació. Per fer canvis, ves a Configuració."</string>
+    <string name="notification_content_gesture_nav_available" msgid="8111130443656460792">"Ves a Configuració per actualitzar el sistema de navegació"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-cs/strings.xml b/packages/SystemUI/res/values-cs/strings.xml
index 266ba15..5861873 100644
--- a/packages/SystemUI/res/values-cs/strings.xml
+++ b/packages/SystemUI/res/values-cs/strings.xml
@@ -62,12 +62,10 @@
     <string name="usb_debugging_secondary_user_title" msgid="6353808721761220421">"Ladění přes USB není povoleno"</string>
     <string name="usb_debugging_secondary_user_message" msgid="6067122453571699801">"Uživatel aktuálně přihlášený k tomuto zařízení nemůže zapnout ladění přes USB. Chcete-li tuto funkci použít, přepněte na primárního uživatele."</string>
     <string name="usb_contaminant_title" msgid="206854874263058490">"Port USB je deaktivován"</string>
-    <!-- no translation found for usb_contaminant_message (7379089091591609111) -->
-    <skip />
+    <string name="usb_contaminant_message" msgid="7379089091591609111">"Kvůli ochraně vašeho zařízení před tekutinami a nečistotami je port USB zakázán a nerozpozná žádné příslušenství.\n\nAž bude opět bezpečné port USB použít, budeme vás informovat."</string>
     <string name="usb_port_enabled" msgid="7906141351687694867">"Port USB může zjišťovat nabíječky a příslušenství"</string>
     <string name="usb_disable_contaminant_detection" msgid="2103905315747120033">"Aktivovat USB"</string>
-    <!-- no translation found for learn_more (5000517160980853569) -->
-    <skip />
+    <string name="learn_more" msgid="5000517160980853569">"Další informace"</string>
     <string name="compat_mode_on" msgid="6623839244840638213">"Přiblížit na celou obrazovku"</string>
     <string name="compat_mode_off" msgid="4434467572461327898">"Na celou obrazovku"</string>
     <string name="global_action_screenshot" msgid="8329831278085426283">"Snímek obrazovky"</string>
@@ -199,6 +197,7 @@
     <string name="carrier_network_change_mode" msgid="8149202439957837762">"Probíhá změna sítě operátora"</string>
     <string name="accessibility_battery_details" msgid="7645516654955025422">"Otevřít podrobnosti o baterii"</string>
     <string name="accessibility_battery_level" msgid="7451474187113371965">"Stav baterie: <xliff:g id="NUMBER">%d</xliff:g> procent."</string>
+    <string name="accessibility_battery_level_with_estimate" msgid="9033100930684311630">"Baterie je nabitá na <xliff:g id="PERCENTAGE">%1$s</xliff:g> %, při vašem používání vydrží ještě <xliff:g id="TIME">%2$s</xliff:g>"</string>
     <string name="accessibility_battery_level_charging" msgid="1147587904439319646">"Baterie se nabíjí. Nabito: <xliff:g id="BATTERY_PERCENTAGE">%d</xliff:g> %%"</string>
     <string name="accessibility_settings_button" msgid="799583911231893380">"Systémová nastavení."</string>
     <string name="accessibility_notifications_button" msgid="4498000369779421892">"Oznámení."</string>
@@ -464,10 +463,8 @@
     <string name="media_projection_remember_text" msgid="3103510882172746752">"Tuto zprávu příště nezobrazovat"</string>
     <string name="clear_all_notifications_text" msgid="814192889771462828">"Smazat vše"</string>
     <string name="manage_notifications_text" msgid="2386728145475108753">"Spravovat"</string>
-    <!-- no translation found for notification_section_header_gentle (4372438504154095677) -->
-    <skip />
-    <!-- no translation found for accessibility_notification_section_header_gentle_clear_all (4286716295850400959) -->
-    <skip />
+    <string name="notification_section_header_gentle" msgid="4372438504154095677">"Tichá oznámení"</string>
+    <string name="accessibility_notification_section_header_gentle_clear_all" msgid="4286716295850400959">"Vymazat všechna tichá oznámení"</string>
     <string name="dnd_suppressing_shade_text" msgid="1904574852846769301">"Oznámení jsou pozastavena režimem Nerušit"</string>
     <string name="media_projection_action_text" msgid="8470872969457985954">"Spustit"</string>
     <string name="empty_shade_text" msgid="708135716272867002">"Žádná oznámení"</string>
@@ -651,21 +648,16 @@
     <string name="inline_block_button" msgid="8735843688021655065">"Blokovat"</string>
     <string name="inline_keep_button" msgid="6665940297019018232">"Nadále zobrazovat"</string>
     <string name="inline_minimize_button" msgid="966233327974702195">"Minimalizovat"</string>
-    <!-- no translation found for inline_silent_button_silent (5315879183296940969) -->
-    <skip />
+    <string name="inline_silent_button_silent" msgid="5315879183296940969">"Tiché"</string>
     <string name="inline_silent_button_stay_silent" msgid="6308371431217601009">"Nadále bez zvuku"</string>
-    <!-- no translation found for inline_silent_button_alert (6008435419895088034) -->
-    <skip />
+    <string name="inline_silent_button_alert" msgid="6008435419895088034">"Upozorňovat"</string>
     <string name="inline_silent_button_keep_alerting" msgid="327696842264359693">"Dál upozorňovat"</string>
     <string name="inline_turn_off_notifications" msgid="8635596135532202355">"Vypnout oznámení"</string>
     <string name="inline_keep_showing_app" msgid="1723113469580031041">"Mají se oznámení z této aplikace nadále zobrazovat?"</string>
-    <string name="notification_silence_title" msgid="7352089096356977930">"Nenápadná"</string>
-    <string name="notification_alert_title" msgid="3966526305405016221">"Prioritní"</string>
-    <string name="notification_channel_summary_low" msgid="1065819618107531284">"Budete se moci lépe soustředit, protože oznámení se budou zobrazovat pouze na vysouvacím panelu. Vždy tichý režim."</string>
-    <string name="notification_channel_summary_low_status" msgid="2702170424808743755">"Níže zobrazit prioritní oznámení. Vždy tichý režim."</string>
-    <string name="notification_channel_summary_low_lock" msgid="7966605244472624458">"Níže zobrazit prioritní oznámení. Vždy tichý režim."</string>
-    <string name="notification_channel_summary_low_status_lock" msgid="7012562768950012739">"Níže zobrazit prioritní oznámení. Vždy tichý režim."</string>
-    <string name="notification_channel_summary_default" msgid="3847289783382316019">"Upozorní vás pomocí zvuku a ikony na stavovém řádku. Zobrazit na obrazovce uzamčení."</string>
+    <string name="notification_silence_title" msgid="5763240612242137433">"Ticho"</string>
+    <string name="notification_alert_title" msgid="8031196611815490340">"Upozornění"</string>
+    <string name="notification_channel_summary_low" msgid="3387466082089715555">"Pomáhá vám soustředit se vypnutím zvuku a vibrací."</string>
+    <string name="notification_channel_summary_default" msgid="5994062840431965586">"Upozorňuje vás pomocí zvuku a vibrací."</string>
     <string name="notification_unblockable_desc" msgid="4556908766584964102">"Tato oznámení nelze upravit."</string>
     <string name="notification_multichannel_desc" msgid="4695920306092240550">"Tuto skupinu oznámení tady nelze nakonfigurovat"</string>
     <string name="notification_delegate_header" msgid="2857691673814814270">"Zprostředkované oznámení"</string>
@@ -918,8 +910,7 @@
     <string name="slice_permission_allow" msgid="2340244901366722709">"Povolit"</string>
     <string name="slice_permission_deny" msgid="7683681514008048807">"Zamítnout"</string>
     <string name="auto_saver_title" msgid="1217959994732964228">"Klepnutím naplánujete aktivování spořiče baterie"</string>
-    <!-- no translation found for auto_saver_text (2563289953551438248) -->
-    <skip />
+    <string name="auto_saver_text" msgid="2563289953551438248">"Zapnout, když bude pravděpodobné, že se vybije baterie"</string>
     <string name="no_auto_saver_action" msgid="8086002101711328500">"Ne, díky"</string>
     <string name="auto_saver_enabled_title" msgid="6726474226058316862">"Plánované aktivování spořiče baterie je zapnuté"</string>
     <string name="auto_saver_enabled_text" msgid="874711029884777579">"Spořič baterie se automaticky aktivuje, jakmile baterie klesne pod <xliff:g id="PERCENTAGE">%d</xliff:g> %%."</string>
@@ -952,4 +943,6 @@
     <string name="bubble_accessibility_action_move_bottom_left" msgid="206369104473183217">"Přesunout vlevo dolů"</string>
     <string name="bubble_accessibility_action_move_bottom_right" msgid="8705660152384312329">"Přesunout vpravo dolů"</string>
     <string name="bubble_dismiss_text" msgid="8028337712674081668">"Zavřít"</string>
+    <string name="notification_content_system_nav_changed" msgid="7218093915747788444">"Systémová navigace byla aktualizována. Chcete-li provést změny, přejděte do Nastavení."</string>
+    <string name="notification_content_gesture_nav_available" msgid="8111130443656460792">"Přejděte do Nastavení a aktualizujte systémovou navigaci"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-da/strings.xml b/packages/SystemUI/res/values-da/strings.xml
index 0bf19be..489b785 100644
--- a/packages/SystemUI/res/values-da/strings.xml
+++ b/packages/SystemUI/res/values-da/strings.xml
@@ -62,12 +62,10 @@
     <string name="usb_debugging_secondary_user_title" msgid="6353808721761220421">"USB-fejlretning er ikke tilladt"</string>
     <string name="usb_debugging_secondary_user_message" msgid="6067122453571699801">"Den bruger, der i øjeblikket er logget ind på denne enhed, kan ikke aktivere USB-fejlretning. Skift til den primære bruger for at bruge denne funktion."</string>
     <string name="usb_contaminant_title" msgid="206854874263058490">"USB-porten er deaktiveret"</string>
-    <!-- no translation found for usb_contaminant_message (7379089091591609111) -->
-    <skip />
+    <string name="usb_contaminant_message" msgid="7379089091591609111">"USB-porten er blevet deaktiveret for at beskytte din enhed mod væske og snavs. Den kan derfor ikke registrere noget tilbehør.\n\nDu får besked, når du kan bruge USB-porten igen."</string>
     <string name="usb_port_enabled" msgid="7906141351687694867">"USB-porten er aktiveret for at registrere opladere og tilbehør"</string>
     <string name="usb_disable_contaminant_detection" msgid="2103905315747120033">"Aktivér USB"</string>
-    <!-- no translation found for learn_more (5000517160980853569) -->
-    <skip />
+    <string name="learn_more" msgid="5000517160980853569">"Få flere oplysninger"</string>
     <string name="compat_mode_on" msgid="6623839244840638213">"Zoom til fuld skærm"</string>
     <string name="compat_mode_off" msgid="4434467572461327898">"Stræk til fuld skærm"</string>
     <string name="global_action_screenshot" msgid="8329831278085426283">"Screenshot"</string>
@@ -100,7 +98,7 @@
     <string name="use_ptp_button_title" msgid="7517127540301625751">"Isæt som et kamera (PTP)"</string>
     <string name="installer_cd_button_title" msgid="2312667578562201583">"Installer appen Android Filoverførsel til Mac"</string>
     <string name="accessibility_back" msgid="567011538994429120">"Tilbage"</string>
-    <string name="accessibility_home" msgid="8217216074895377641">"Startskærm"</string>
+    <string name="accessibility_home" msgid="8217216074895377641">"Hjem"</string>
     <string name="accessibility_menu" msgid="316839303324695949">"Menu"</string>
     <string name="accessibility_accessibility_button" msgid="7601252764577607915">"Hjælpefunktioner"</string>
     <string name="accessibility_rotate_button" msgid="7402949513740253006">"Roter skærmen"</string>
@@ -199,6 +197,7 @@
     <string name="carrier_network_change_mode" msgid="8149202439957837762">"Skift af mobilnetværk"</string>
     <string name="accessibility_battery_details" msgid="7645516654955025422">"Åbn oplysninger om batteri"</string>
     <string name="accessibility_battery_level" msgid="7451474187113371965">"Batteri <xliff:g id="NUMBER">%d</xliff:g> procent."</string>
+    <string name="accessibility_battery_level_with_estimate" msgid="9033100930684311630">"Batteriniveauet er på <xliff:g id="PERCENTAGE">%1$s</xliff:g> procent, så du har ca. <xliff:g id="TIME">%2$s</xliff:g> tilbage, alt efter hvordan du bruger enheden"</string>
     <string name="accessibility_battery_level_charging" msgid="1147587904439319646">"Batteriet oplades. <xliff:g id="BATTERY_PERCENTAGE">%d</xliff:g> %%."</string>
     <string name="accessibility_settings_button" msgid="799583911231893380">"Systemindstillinger."</string>
     <string name="accessibility_notifications_button" msgid="4498000369779421892">"Notifikationer."</string>
@@ -458,10 +457,8 @@
     <string name="media_projection_remember_text" msgid="3103510882172746752">"Vis ikke igen"</string>
     <string name="clear_all_notifications_text" msgid="814192889771462828">"Ryd alle"</string>
     <string name="manage_notifications_text" msgid="2386728145475108753">"Administrer"</string>
-    <!-- no translation found for notification_section_header_gentle (4372438504154095677) -->
-    <skip />
-    <!-- no translation found for accessibility_notification_section_header_gentle_clear_all (4286716295850400959) -->
-    <skip />
+    <string name="notification_section_header_gentle" msgid="4372438504154095677">"Lydløse notifikationer"</string>
+    <string name="accessibility_notification_section_header_gentle_clear_all" msgid="4286716295850400959">"Ryd alle lydløse notifikationer"</string>
     <string name="dnd_suppressing_shade_text" msgid="1904574852846769301">"Notifikationer er sat på pause af Forstyr ikke"</string>
     <string name="media_projection_action_text" msgid="8470872969457985954">"Start nu"</string>
     <string name="empty_shade_text" msgid="708135716272867002">"Ingen notifikationer"</string>
@@ -645,21 +642,16 @@
     <string name="inline_block_button" msgid="8735843688021655065">"Bloker"</string>
     <string name="inline_keep_button" msgid="6665940297019018232">"Fortsæt med at vise notifikationer"</string>
     <string name="inline_minimize_button" msgid="966233327974702195">"Minimer"</string>
-    <!-- no translation found for inline_silent_button_silent (5315879183296940969) -->
-    <skip />
+    <string name="inline_silent_button_silent" msgid="5315879183296940969">"Lydløs"</string>
     <string name="inline_silent_button_stay_silent" msgid="6308371431217601009">"Fortsæt med lydløse notifikationer"</string>
-    <!-- no translation found for inline_silent_button_alert (6008435419895088034) -->
-    <skip />
+    <string name="inline_silent_button_alert" msgid="6008435419895088034">"Underretninger"</string>
     <string name="inline_silent_button_keep_alerting" msgid="327696842264359693">"Fortsæt med at underrette"</string>
     <string name="inline_turn_off_notifications" msgid="8635596135532202355">"Deaktiver notifikationer"</string>
     <string name="inline_keep_showing_app" msgid="1723113469580031041">"Vil du fortsætte med at se notifikationer fra denne app?"</string>
-    <string name="notification_silence_title" msgid="7352089096356977930">"Diskret"</string>
-    <string name="notification_alert_title" msgid="3966526305405016221">"Prioriteret"</string>
-    <string name="notification_channel_summary_low" msgid="1065819618107531284">"Hjælper dig med at fokusere på de vigtige ting, da notifikationerne kun vises i panelet, der trækkes ned. Altid lydløs."</string>
-    <string name="notification_channel_summary_low_status" msgid="2702170424808743755">"Viser notifikationer med lav prioritet. Altid lydløs."</string>
-    <string name="notification_channel_summary_low_lock" msgid="7966605244472624458">"Viser notifikationer med lav prioritet. Altid lydløs."</string>
-    <string name="notification_channel_summary_low_status_lock" msgid="7012562768950012739">"Viser notifikationer med lav prioritet. Altid lydløs."</string>
-    <string name="notification_channel_summary_default" msgid="3847289783382316019">"Fanger din opmærksomhed med lyd og ikoner i statusbjælken. Vises på låseskærmen."</string>
+    <string name="notification_silence_title" msgid="5763240612242137433">"Lydløs"</string>
+    <string name="notification_alert_title" msgid="8031196611815490340">"Underretninger"</string>
+    <string name="notification_channel_summary_low" msgid="3387466082089715555">"Ingen lyde eller vibrationer, der forstyrrer dig."</string>
+    <string name="notification_channel_summary_default" msgid="5994062840431965586">"Fanger din opmærksomhed med lyd eller vibration."</string>
     <string name="notification_unblockable_desc" msgid="4556908766584964102">"Disse notifikationer kan ikke redigeres."</string>
     <string name="notification_multichannel_desc" msgid="4695920306092240550">"Du kan ikke konfigurere denne gruppe notifikationer her"</string>
     <string name="notification_delegate_header" msgid="2857691673814814270">"Proxyforbundet notifikation"</string>
@@ -908,8 +900,7 @@
     <string name="slice_permission_allow" msgid="2340244901366722709">"Tillad"</string>
     <string name="slice_permission_deny" msgid="7683681514008048807">"Afvis"</string>
     <string name="auto_saver_title" msgid="1217959994732964228">"Tryk for at fastsætte en tidsplan for batterisparefunktionen"</string>
-    <!-- no translation found for auto_saver_text (2563289953551438248) -->
-    <skip />
+    <string name="auto_saver_text" msgid="2563289953551438248">"Aktivér, når det ser ud til, at batteriet løber tør"</string>
     <string name="no_auto_saver_action" msgid="8086002101711328500">"Nej tak"</string>
     <string name="auto_saver_enabled_title" msgid="6726474226058316862">"Tidsplanen for batterisparefunktionen er aktiveret"</string>
     <string name="auto_saver_enabled_text" msgid="874711029884777579">"Batterisparefunktionen aktiveres automatisk, når batteriniveauet når under <xliff:g id="PERCENTAGE">%d</xliff:g> %%."</string>
@@ -942,4 +933,6 @@
     <string name="bubble_accessibility_action_move_bottom_left" msgid="206369104473183217">"Flyt ned til venstre"</string>
     <string name="bubble_accessibility_action_move_bottom_right" msgid="8705660152384312329">"Flyt ned til højre"</string>
     <string name="bubble_dismiss_text" msgid="8028337712674081668">"Afvis"</string>
+    <string name="notification_content_system_nav_changed" msgid="7218093915747788444">"Systemnavigationen blev opdateret. Gå til Indstillinger for at foretage ændringer."</string>
+    <string name="notification_content_gesture_nav_available" msgid="8111130443656460792">"Gå til Indstillinger for at opdatere systemnavigationen"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-de/strings.xml b/packages/SystemUI/res/values-de/strings.xml
index 5c21ea3..f495c43 100644
--- a/packages/SystemUI/res/values-de/strings.xml
+++ b/packages/SystemUI/res/values-de/strings.xml
@@ -26,7 +26,7 @@
     <string name="status_bar_latest_events_title" msgid="6594767438577593172">"Benachrichtigungen"</string>
     <string name="battery_low_title" msgid="9187898087363540349">"Der Akku ist fast leer"</string>
     <string name="battery_low_percent_format" msgid="2900940511201380775">"<xliff:g id="PERCENTAGE">%s</xliff:g> verbleibend"</string>
-    <string name="battery_low_percent_format_hybrid" msgid="6838677459286775617">"<xliff:g id="PERCENTAGE">%1$s</xliff:g> ausstehend; noch ca. <xliff:g id="TIME">%2$s</xliff:g>, basierend auf deiner Nutzung"</string>
+    <string name="battery_low_percent_format_hybrid" msgid="6838677459286775617">"Noch <xliff:g id="PERCENTAGE">%1$s</xliff:g> übrig; bei deinem Nutzungsmuster hast du noch ca. <xliff:g id="TIME">%2$s</xliff:g>"</string>
     <string name="battery_low_percent_format_hybrid_short" msgid="9025795469949145586">"<xliff:g id="PERCENTAGE">%1$s</xliff:g> ausstehend; noch ca. <xliff:g id="TIME">%2$s</xliff:g>"</string>
     <string name="battery_low_percent_format_saver_started" msgid="7879389868952879166">"Noch <xliff:g id="PERCENTAGE">%s</xliff:g>. Der Energiesparmodus ist aktiviert."</string>
     <string name="invalid_charger" msgid="2741987096648693172">"Aufladen über USB nicht möglich. Verwende das mit dem Gerät gelieferte Ladegerät."</string>
@@ -62,12 +62,10 @@
     <string name="usb_debugging_secondary_user_title" msgid="6353808721761220421">"USB-Debugging nicht zulässig"</string>
     <string name="usb_debugging_secondary_user_message" msgid="6067122453571699801">"Der momentan auf diesem Gerät angemeldete Nutzer kann das USB-Debugging nicht aktivieren. Um diese Funktion verwenden zu können, wechsle zum primären Nutzer."</string>
     <string name="usb_contaminant_title" msgid="206854874263058490">"USB-Port deaktiviert"</string>
-    <!-- no translation found for usb_contaminant_message (7379089091591609111) -->
-    <skip />
+    <string name="usb_contaminant_message" msgid="7379089091591609111">"Zum Schutz deines Geräts vor Flüssigkeiten oder Fremdkörpern ist der USB-Port zurzeit deaktiviert und erkennt kein Zubehör.\n\nDu wirst benachrichtigt, wenn der USB-Port wieder verwendet werden kann."</string>
     <string name="usb_port_enabled" msgid="7906141351687694867">"Erkennung von Ladegeräten und Zubehör am USB-Port aktiviert"</string>
     <string name="usb_disable_contaminant_detection" msgid="2103905315747120033">"USB aktivieren"</string>
-    <!-- no translation found for learn_more (5000517160980853569) -->
-    <skip />
+    <string name="learn_more" msgid="5000517160980853569">"Weitere Informationen"</string>
     <string name="compat_mode_on" msgid="6623839244840638213">"Zoom auf Bildschirmgröße"</string>
     <string name="compat_mode_off" msgid="4434467572461327898">"Auf Bildschirmgröße anpassen"</string>
     <string name="global_action_screenshot" msgid="8329831278085426283">"Screenshot"</string>
@@ -201,6 +199,7 @@
     <!-- String.format failed for translation -->
     <!-- no translation found for accessibility_battery_level (7451474187113371965) -->
     <skip />
+    <string name="accessibility_battery_level_with_estimate" msgid="9033100930684311630">"Akku bei <xliff:g id="PERCENTAGE">%1$s</xliff:g> %, bei deinem Nutzungsmuster hast du noch ca. <xliff:g id="TIME">%2$s</xliff:g>"</string>
     <!-- String.format failed for translation -->
     <!-- no translation found for accessibility_battery_level_charging (1147587904439319646) -->
     <skip />
@@ -462,10 +461,8 @@
     <string name="media_projection_remember_text" msgid="3103510882172746752">"Nicht mehr anzeigen"</string>
     <string name="clear_all_notifications_text" msgid="814192889771462828">"Alle löschen"</string>
     <string name="manage_notifications_text" msgid="2386728145475108753">"Verwalten"</string>
-    <!-- no translation found for notification_section_header_gentle (4372438504154095677) -->
-    <skip />
-    <!-- no translation found for accessibility_notification_section_header_gentle_clear_all (4286716295850400959) -->
-    <skip />
+    <string name="notification_section_header_gentle" msgid="4372438504154095677">"Lautlose Benachrichtigungen"</string>
+    <string name="accessibility_notification_section_header_gentle_clear_all" msgid="4286716295850400959">"Alle lautlosen Benachrichtigungen löschen"</string>
     <string name="dnd_suppressing_shade_text" msgid="1904574852846769301">"Benachrichtigungen durch \"Bitte nicht stören\" pausiert"</string>
     <string name="media_projection_action_text" msgid="8470872969457985954">"Jetzt starten"</string>
     <string name="empty_shade_text" msgid="708135716272867002">"Keine Benachrichtigungen"</string>
@@ -542,7 +539,7 @@
     <string name="volume_odi_captions_hint_enable" msgid="49750248924730302">"aktivieren"</string>
     <string name="volume_odi_captions_hint_disable" msgid="8980842810619956593">"deaktivieren"</string>
     <string name="accessibility_output_chooser" msgid="8185317493017988680">"Ausgabegerät wechseln"</string>
-    <string name="screen_pinning_title" msgid="3273740381976175811">"Bildschirm ist fixiert"</string>
+    <string name="screen_pinning_title" msgid="3273740381976175811">"Der Bildschirm ist angpinnt"</string>
     <string name="screen_pinning_description" msgid="8909878447196419623">"Der Bildschirm bleibt so lange eingeblendet, bis du die Fixierung aufhebst. Berühre und halte dazu \"Zurück\" und \"Übersicht\"."</string>
     <string name="screen_pinning_description_recents_invisible" msgid="8281145542163727971">"Der Bildschirm wird so lange angezeigt, bis du die Fixierung aufhebst. Berühre und halte dazu \"Zurück\" und \"Startbildschirm\"."</string>
     <string name="screen_pinning_description_gestural" msgid="1191513974909607884">"Der Bildschirm wird so lange angezeigt, bis du die Fixierung aufhebst. Dazu wischst du nach oben und hältst den Bildschirm gedrückt"</string>
@@ -552,7 +549,7 @@
     <string name="screen_pinning_toast_recents_invisible" msgid="8252402309499161281">"Um die Fixierung für diesen Bildschirm aufzuheben, berühre und halte \"Zurück\" und \"Startbildschirm\""</string>
     <string name="screen_pinning_positive" msgid="3783985798366751226">"Ok"</string>
     <string name="screen_pinning_negative" msgid="3741602308343880268">"Nein danke"</string>
-    <string name="screen_pinning_start" msgid="1022122128489278317">"Bildschirm fixiert"</string>
+    <string name="screen_pinning_start" msgid="1022122128489278317">"Der Bildschirm ist angepinnt"</string>
     <string name="screen_pinning_exit" msgid="5187339744262325372">"Fixierung für Bildschirm aufgehoben"</string>
     <string name="quick_settings_reset_confirmation_title" msgid="748792586749897883">"<xliff:g id="TILE_LABEL">%1$s</xliff:g> ausblenden?"</string>
     <string name="quick_settings_reset_confirmation_message" msgid="2235970126803317374">"Sie wird wieder eingeblendet, wenn du sie in den Einstellungen erneut aktivierst."</string>
@@ -649,21 +646,16 @@
     <string name="inline_block_button" msgid="8735843688021655065">"Blockieren"</string>
     <string name="inline_keep_button" msgid="6665940297019018232">"Weiterhin anzeigen"</string>
     <string name="inline_minimize_button" msgid="966233327974702195">"Minimieren"</string>
-    <!-- no translation found for inline_silent_button_silent (5315879183296940969) -->
-    <skip />
+    <string name="inline_silent_button_silent" msgid="5315879183296940969">"Lautlos"</string>
     <string name="inline_silent_button_stay_silent" msgid="6308371431217601009">"Weiter lautlos bleiben"</string>
-    <!-- no translation found for inline_silent_button_alert (6008435419895088034) -->
-    <skip />
+    <string name="inline_silent_button_alert" msgid="6008435419895088034">"Benachrichtigen"</string>
     <string name="inline_silent_button_keep_alerting" msgid="327696842264359693">"Weiterhin Benachrichtigungen senden"</string>
     <string name="inline_turn_off_notifications" msgid="8635596135532202355">"Benachrichtigungen deaktivieren"</string>
     <string name="inline_keep_showing_app" msgid="1723113469580031041">"Benachrichtigungen dieser App weiterhin anzeigen?"</string>
-    <string name="notification_silence_title" msgid="7352089096356977930">"Stumm"</string>
-    <string name="notification_alert_title" msgid="3966526305405016221">"Priorisiert"</string>
-    <string name="notification_channel_summary_low" msgid="1065819618107531284">"Benachrichtigungen erscheinen nur in der Benachrichtigungsleiste. So kannst du dich besser konzentrieren. Immer lautlos."</string>
-    <string name="notification_channel_summary_low_status" msgid="2702170424808743755">"Erscheinen unter den wichtigen Benachrichtigungen. Immer lautlos."</string>
-    <string name="notification_channel_summary_low_lock" msgid="7966605244472624458">"Erscheinen unter den wichtigen Benachrichtigungen. Immer lautlos."</string>
-    <string name="notification_channel_summary_low_status_lock" msgid="7012562768950012739">"Erscheinen unter den wichtigen Benachrichtigungen. Immer lautlos."</string>
-    <string name="notification_channel_summary_default" msgid="3847289783382316019">"Benachrichtigungen werden mit einem Ton und einem Statusleistensymbol angekündigt. Erscheinen auf dem Sperrbildschirm."</string>
+    <string name="notification_silence_title" msgid="5763240612242137433">"Lautlos"</string>
+    <string name="notification_alert_title" msgid="8031196611815490340">"Benachrichtigen"</string>
+    <string name="notification_channel_summary_low" msgid="3387466082089715555">"Benachrichtigungen werden ohne Ton oder Vibration angekündigt, um deine Konzentration nicht zu stören."</string>
+    <string name="notification_channel_summary_default" msgid="5994062840431965586">"Benachrichtigungen werden mit einem Ton oder einer Vibration angekündigt, um dich auf sie aufmerksam zu machen."</string>
     <string name="notification_unblockable_desc" msgid="4556908766584964102">"Diese Benachrichtigungen können nicht geändert werden."</string>
     <string name="notification_multichannel_desc" msgid="4695920306092240550">"Die Benachrichtigungsgruppe kann hier nicht konfiguriert werden"</string>
     <string name="notification_delegate_header" msgid="2857691673814814270">"Weitergeleitete Benachrichtigung"</string>
@@ -912,8 +904,7 @@
     <string name="slice_permission_allow" msgid="2340244901366722709">"Zulassen"</string>
     <string name="slice_permission_deny" msgid="7683681514008048807">"Ablehnen"</string>
     <string name="auto_saver_title" msgid="1217959994732964228">"Tippen zum Planen des Energiesparmodus"</string>
-    <!-- no translation found for auto_saver_text (2563289953551438248) -->
-    <skip />
+    <string name="auto_saver_text" msgid="2563289953551438248">"Aktivieren, wenn der Akku wahrscheinlich nicht mehr lange hält"</string>
     <string name="no_auto_saver_action" msgid="8086002101711328500">"Nein danke"</string>
     <string name="auto_saver_enabled_title" msgid="6726474226058316862">"Geplanter Energiesparmodus aktiviert"</string>
     <string name="auto_saver_enabled_text" msgid="874711029884777579">"Der Energiesparmodus wird bei einem Akkustand von <xliff:g id="PERCENTAGE">%d</xliff:g> %% automatisch aktiviert."</string>
@@ -946,4 +937,6 @@
     <string name="bubble_accessibility_action_move_bottom_left" msgid="206369104473183217">"Nach unten links verschieben"</string>
     <string name="bubble_accessibility_action_move_bottom_right" msgid="8705660152384312329">"Nach unten rechts verschieben"</string>
     <string name="bubble_dismiss_text" msgid="8028337712674081668">"Schließen"</string>
+    <string name="notification_content_system_nav_changed" msgid="7218093915747788444">"Systemsteuerungseinstellungen wurden angepasst. Änderungen kannst du in den Einstellungen vornehmen."</string>
+    <string name="notification_content_gesture_nav_available" msgid="8111130443656460792">"Gehe zu den Einstellungen, um die Systemsteuerung anzupassen"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-el/strings.xml b/packages/SystemUI/res/values-el/strings.xml
index 775f9b1..63a16f4 100644
--- a/packages/SystemUI/res/values-el/strings.xml
+++ b/packages/SystemUI/res/values-el/strings.xml
@@ -197,6 +197,7 @@
     <string name="carrier_network_change_mode" msgid="8149202439957837762">"Αλλαγή δικτύου εταιρείας κινητής τηλεφωνίας"</string>
     <string name="accessibility_battery_details" msgid="7645516654955025422">"Άνοιγμα λεπτομερειών μπαταρίας"</string>
     <string name="accessibility_battery_level" msgid="7451474187113371965">"Μπαταρία <xliff:g id="NUMBER">%d</xliff:g> τοις εκατό."</string>
+    <string name="accessibility_battery_level_with_estimate" msgid="9033100930684311630">"Μπαταρία στο <xliff:g id="PERCENTAGE">%1$s</xliff:g> τοις εκατό. Περίπου <xliff:g id="TIME">%2$s</xliff:g> ακόμη, βάσει της χρήσης σας"</string>
     <string name="accessibility_battery_level_charging" msgid="1147587904439319646">"Φόρτιση μπαταρίας, <xliff:g id="BATTERY_PERCENTAGE">%d</xliff:g>%% τοις εκατό."</string>
     <string name="accessibility_settings_button" msgid="799583911231893380">"Ρυθμίσεις συστήματος."</string>
     <string name="accessibility_notifications_button" msgid="4498000369779421892">"Ειδοποιήσεις."</string>
@@ -647,13 +648,10 @@
     <string name="inline_silent_button_keep_alerting" msgid="327696842264359693">"Να συνεχιστούν οι ειδοποιήσεις"</string>
     <string name="inline_turn_off_notifications" msgid="8635596135532202355">"Απενεργοποίηση ειδοποιήσεων"</string>
     <string name="inline_keep_showing_app" msgid="1723113469580031041">"Να συνεχίσουν να εμφανίζονται ειδοποιήσεις από αυτήν την εφαρμογή;"</string>
-    <string name="notification_silence_title" msgid="7352089096356977930">"Διακριτικές"</string>
-    <string name="notification_alert_title" msgid="3966526305405016221">"Προτεραιότητας"</string>
-    <string name="notification_channel_summary_low" msgid="1065819618107531284">"Σας βοηθάει να συγκεντρωθείτε με ειδοποιήσεις που εμφανίζονται μόνο στο αναπτυσσόμενο πλαίσιο σκίασης. Πάντα σε σίγαση."</string>
-    <string name="notification_channel_summary_low_status" msgid="2702170424808743755">"Εμφανίζεται κάτω από ειδοποιήσεις προτεραιότητας. Πάντα σε σίγαση."</string>
-    <string name="notification_channel_summary_low_lock" msgid="7966605244472624458">"Εμφανίζεται κάτω από ειδοποιήσεις προτεραιότητας. Πάντα σε σίγαση."</string>
-    <string name="notification_channel_summary_low_status_lock" msgid="7012562768950012739">"Εμφανίζεται κάτω από ειδοποιήσεις προτεραιότητας. Πάντα σε σίγαση."</string>
-    <string name="notification_channel_summary_default" msgid="3847289783382316019">"Τραβάει την προσοχή σας με ήχους και ένα εικονίδιο γραμμής κατάστασης. Εμφανίζεται στην οθόνη κλειδώματος."</string>
+    <string name="notification_silence_title" msgid="5763240612242137433">"Σίγαση"</string>
+    <string name="notification_alert_title" msgid="8031196611815490340">"Ειδοποίηση"</string>
+    <string name="notification_channel_summary_low" msgid="3387466082089715555">"Σας βοηθά να συγκεντρωθείτε χωρίς ήχο και δόνηση."</string>
+    <string name="notification_channel_summary_default" msgid="5994062840431965586">"Τραβά την προσοχή σας με ήχο ή δόνηση."</string>
     <string name="notification_unblockable_desc" msgid="4556908766584964102">"Δεν είναι δυνατή η τροποποίηση αυτών των ειδοποιήσεων"</string>
     <string name="notification_multichannel_desc" msgid="4695920306092240550">"Δεν είναι δυνατή η διαμόρφωση αυτής της ομάδας ειδοποιήσεων εδώ"</string>
     <string name="notification_delegate_header" msgid="2857691673814814270">"Ειδοποίηση μέσω διακομιστή μεσολάβησης"</string>
@@ -935,4 +933,6 @@
     <string name="bubble_accessibility_action_move_bottom_left" msgid="206369104473183217">"Μετακίνηση κάτω αριστερά"</string>
     <string name="bubble_accessibility_action_move_bottom_right" msgid="8705660152384312329">"Μετακίνηση κάτω δεξιά"</string>
     <string name="bubble_dismiss_text" msgid="8028337712674081668">"Παράβλεψη"</string>
+    <string name="notification_content_system_nav_changed" msgid="7218093915747788444">"Η πλοήγηση συστήματος ενημερώθηκε. Για να κάνετε αλλαγές, μεταβείτε στις Ρυθμίσεις."</string>
+    <string name="notification_content_gesture_nav_available" msgid="8111130443656460792">"Μεταβείτε στις Ρυθμίσεις για να ενημερώσετε την πλοήγηση συστήματος"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-en-rAU/strings.xml b/packages/SystemUI/res/values-en-rAU/strings.xml
index ed2c0a07..db9ed9c 100644
--- a/packages/SystemUI/res/values-en-rAU/strings.xml
+++ b/packages/SystemUI/res/values-en-rAU/strings.xml
@@ -197,6 +197,7 @@
     <string name="carrier_network_change_mode" msgid="8149202439957837762">"Operator network changing"</string>
     <string name="accessibility_battery_details" msgid="7645516654955025422">"Open battery details"</string>
     <string name="accessibility_battery_level" msgid="7451474187113371965">"Battery <xliff:g id="NUMBER">%d</xliff:g> per cent."</string>
+    <string name="accessibility_battery_level_with_estimate" msgid="9033100930684311630">"Battery <xliff:g id="PERCENTAGE">%1$s</xliff:g> percentage, about <xliff:g id="TIME">%2$s</xliff:g> left based on your usage"</string>
     <string name="accessibility_battery_level_charging" msgid="1147587904439319646">"Battery charging, <xliff:g id="BATTERY_PERCENTAGE">%d</xliff:g> percent."</string>
     <string name="accessibility_settings_button" msgid="799583911231893380">"System settings"</string>
     <string name="accessibility_notifications_button" msgid="4498000369779421892">"Notifications."</string>
@@ -647,13 +648,10 @@
     <string name="inline_silent_button_keep_alerting" msgid="327696842264359693">"Keep alerting"</string>
     <string name="inline_turn_off_notifications" msgid="8635596135532202355">"Turn off notifications"</string>
     <string name="inline_keep_showing_app" msgid="1723113469580031041">"Keep showing notifications from this app?"</string>
-    <string name="notification_silence_title" msgid="7352089096356977930">"Gentle"</string>
-    <string name="notification_alert_title" msgid="3966526305405016221">"Prioritised"</string>
-    <string name="notification_channel_summary_low" msgid="1065819618107531284">"Helps you focus with notifications only in the pull-down shade. Always silent."</string>
-    <string name="notification_channel_summary_low_status" msgid="2702170424808743755">"Displays below priority notifications. Always silent."</string>
-    <string name="notification_channel_summary_low_lock" msgid="7966605244472624458">"Displays below priority notifications. Always silent."</string>
-    <string name="notification_channel_summary_low_status_lock" msgid="7012562768950012739">"Displays below priority notifications. Always silent."</string>
-    <string name="notification_channel_summary_default" msgid="3847289783382316019">"Gets your attention with sound and a status bar icon. Shows on lock screen."</string>
+    <string name="notification_silence_title" msgid="5763240612242137433">"Silent"</string>
+    <string name="notification_alert_title" msgid="8031196611815490340">"Alerting"</string>
+    <string name="notification_channel_summary_low" msgid="3387466082089715555">"Helps you focus without sound or vibration."</string>
+    <string name="notification_channel_summary_default" msgid="5994062840431965586">"Gets your attention with sound or vibration."</string>
     <string name="notification_unblockable_desc" msgid="4556908766584964102">"These notifications can\'t be modified."</string>
     <string name="notification_multichannel_desc" msgid="4695920306092240550">"This group of notifications cannot be configured here"</string>
     <string name="notification_delegate_header" msgid="2857691673814814270">"Proxied notification"</string>
@@ -935,4 +933,6 @@
     <string name="bubble_accessibility_action_move_bottom_left" msgid="206369104473183217">"Move bottom left"</string>
     <string name="bubble_accessibility_action_move_bottom_right" msgid="8705660152384312329">"Move bottom right"</string>
     <string name="bubble_dismiss_text" msgid="8028337712674081668">"Dismiss"</string>
+    <string name="notification_content_system_nav_changed" msgid="7218093915747788444">"System navigation updated. To make changes, go to Settings."</string>
+    <string name="notification_content_gesture_nav_available" msgid="8111130443656460792">"Go to Settings to update system navigation"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-en-rCA/strings.xml b/packages/SystemUI/res/values-en-rCA/strings.xml
index c67a491..1a85de5 100644
--- a/packages/SystemUI/res/values-en-rCA/strings.xml
+++ b/packages/SystemUI/res/values-en-rCA/strings.xml
@@ -197,6 +197,7 @@
     <string name="carrier_network_change_mode" msgid="8149202439957837762">"Operator network changing"</string>
     <string name="accessibility_battery_details" msgid="7645516654955025422">"Open battery details"</string>
     <string name="accessibility_battery_level" msgid="7451474187113371965">"Battery <xliff:g id="NUMBER">%d</xliff:g> per cent."</string>
+    <string name="accessibility_battery_level_with_estimate" msgid="9033100930684311630">"Battery <xliff:g id="PERCENTAGE">%1$s</xliff:g> percentage, about <xliff:g id="TIME">%2$s</xliff:g> left based on your usage"</string>
     <string name="accessibility_battery_level_charging" msgid="1147587904439319646">"Battery charging, <xliff:g id="BATTERY_PERCENTAGE">%d</xliff:g> percent."</string>
     <string name="accessibility_settings_button" msgid="799583911231893380">"System settings"</string>
     <string name="accessibility_notifications_button" msgid="4498000369779421892">"Notifications."</string>
@@ -647,13 +648,10 @@
     <string name="inline_silent_button_keep_alerting" msgid="327696842264359693">"Keep alerting"</string>
     <string name="inline_turn_off_notifications" msgid="8635596135532202355">"Turn off notifications"</string>
     <string name="inline_keep_showing_app" msgid="1723113469580031041">"Keep showing notifications from this app?"</string>
-    <string name="notification_silence_title" msgid="7352089096356977930">"Gentle"</string>
-    <string name="notification_alert_title" msgid="3966526305405016221">"Prioritised"</string>
-    <string name="notification_channel_summary_low" msgid="1065819618107531284">"Helps you focus with notifications only in the pull-down shade. Always silent."</string>
-    <string name="notification_channel_summary_low_status" msgid="2702170424808743755">"Displays below priority notifications. Always silent."</string>
-    <string name="notification_channel_summary_low_lock" msgid="7966605244472624458">"Displays below priority notifications. Always silent."</string>
-    <string name="notification_channel_summary_low_status_lock" msgid="7012562768950012739">"Displays below priority notifications. Always silent."</string>
-    <string name="notification_channel_summary_default" msgid="3847289783382316019">"Gets your attention with sound and a status bar icon. Shows on lock screen."</string>
+    <string name="notification_silence_title" msgid="5763240612242137433">"Silent"</string>
+    <string name="notification_alert_title" msgid="8031196611815490340">"Alerting"</string>
+    <string name="notification_channel_summary_low" msgid="3387466082089715555">"Helps you focus without sound or vibration."</string>
+    <string name="notification_channel_summary_default" msgid="5994062840431965586">"Gets your attention with sound or vibration."</string>
     <string name="notification_unblockable_desc" msgid="4556908766584964102">"These notifications can\'t be modified."</string>
     <string name="notification_multichannel_desc" msgid="4695920306092240550">"This group of notifications cannot be configured here"</string>
     <string name="notification_delegate_header" msgid="2857691673814814270">"Proxied notification"</string>
@@ -935,4 +933,6 @@
     <string name="bubble_accessibility_action_move_bottom_left" msgid="206369104473183217">"Move bottom left"</string>
     <string name="bubble_accessibility_action_move_bottom_right" msgid="8705660152384312329">"Move bottom right"</string>
     <string name="bubble_dismiss_text" msgid="8028337712674081668">"Dismiss"</string>
+    <string name="notification_content_system_nav_changed" msgid="7218093915747788444">"System navigation updated. To make changes, go to Settings."</string>
+    <string name="notification_content_gesture_nav_available" msgid="8111130443656460792">"Go to Settings to update system navigation"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-en-rGB/strings.xml b/packages/SystemUI/res/values-en-rGB/strings.xml
index ed2c0a07..db9ed9c 100644
--- a/packages/SystemUI/res/values-en-rGB/strings.xml
+++ b/packages/SystemUI/res/values-en-rGB/strings.xml
@@ -197,6 +197,7 @@
     <string name="carrier_network_change_mode" msgid="8149202439957837762">"Operator network changing"</string>
     <string name="accessibility_battery_details" msgid="7645516654955025422">"Open battery details"</string>
     <string name="accessibility_battery_level" msgid="7451474187113371965">"Battery <xliff:g id="NUMBER">%d</xliff:g> per cent."</string>
+    <string name="accessibility_battery_level_with_estimate" msgid="9033100930684311630">"Battery <xliff:g id="PERCENTAGE">%1$s</xliff:g> percentage, about <xliff:g id="TIME">%2$s</xliff:g> left based on your usage"</string>
     <string name="accessibility_battery_level_charging" msgid="1147587904439319646">"Battery charging, <xliff:g id="BATTERY_PERCENTAGE">%d</xliff:g> percent."</string>
     <string name="accessibility_settings_button" msgid="799583911231893380">"System settings"</string>
     <string name="accessibility_notifications_button" msgid="4498000369779421892">"Notifications."</string>
@@ -647,13 +648,10 @@
     <string name="inline_silent_button_keep_alerting" msgid="327696842264359693">"Keep alerting"</string>
     <string name="inline_turn_off_notifications" msgid="8635596135532202355">"Turn off notifications"</string>
     <string name="inline_keep_showing_app" msgid="1723113469580031041">"Keep showing notifications from this app?"</string>
-    <string name="notification_silence_title" msgid="7352089096356977930">"Gentle"</string>
-    <string name="notification_alert_title" msgid="3966526305405016221">"Prioritised"</string>
-    <string name="notification_channel_summary_low" msgid="1065819618107531284">"Helps you focus with notifications only in the pull-down shade. Always silent."</string>
-    <string name="notification_channel_summary_low_status" msgid="2702170424808743755">"Displays below priority notifications. Always silent."</string>
-    <string name="notification_channel_summary_low_lock" msgid="7966605244472624458">"Displays below priority notifications. Always silent."</string>
-    <string name="notification_channel_summary_low_status_lock" msgid="7012562768950012739">"Displays below priority notifications. Always silent."</string>
-    <string name="notification_channel_summary_default" msgid="3847289783382316019">"Gets your attention with sound and a status bar icon. Shows on lock screen."</string>
+    <string name="notification_silence_title" msgid="5763240612242137433">"Silent"</string>
+    <string name="notification_alert_title" msgid="8031196611815490340">"Alerting"</string>
+    <string name="notification_channel_summary_low" msgid="3387466082089715555">"Helps you focus without sound or vibration."</string>
+    <string name="notification_channel_summary_default" msgid="5994062840431965586">"Gets your attention with sound or vibration."</string>
     <string name="notification_unblockable_desc" msgid="4556908766584964102">"These notifications can\'t be modified."</string>
     <string name="notification_multichannel_desc" msgid="4695920306092240550">"This group of notifications cannot be configured here"</string>
     <string name="notification_delegate_header" msgid="2857691673814814270">"Proxied notification"</string>
@@ -935,4 +933,6 @@
     <string name="bubble_accessibility_action_move_bottom_left" msgid="206369104473183217">"Move bottom left"</string>
     <string name="bubble_accessibility_action_move_bottom_right" msgid="8705660152384312329">"Move bottom right"</string>
     <string name="bubble_dismiss_text" msgid="8028337712674081668">"Dismiss"</string>
+    <string name="notification_content_system_nav_changed" msgid="7218093915747788444">"System navigation updated. To make changes, go to Settings."</string>
+    <string name="notification_content_gesture_nav_available" msgid="8111130443656460792">"Go to Settings to update system navigation"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-en-rIN/strings.xml b/packages/SystemUI/res/values-en-rIN/strings.xml
index ed2c0a07..db9ed9c 100644
--- a/packages/SystemUI/res/values-en-rIN/strings.xml
+++ b/packages/SystemUI/res/values-en-rIN/strings.xml
@@ -197,6 +197,7 @@
     <string name="carrier_network_change_mode" msgid="8149202439957837762">"Operator network changing"</string>
     <string name="accessibility_battery_details" msgid="7645516654955025422">"Open battery details"</string>
     <string name="accessibility_battery_level" msgid="7451474187113371965">"Battery <xliff:g id="NUMBER">%d</xliff:g> per cent."</string>
+    <string name="accessibility_battery_level_with_estimate" msgid="9033100930684311630">"Battery <xliff:g id="PERCENTAGE">%1$s</xliff:g> percentage, about <xliff:g id="TIME">%2$s</xliff:g> left based on your usage"</string>
     <string name="accessibility_battery_level_charging" msgid="1147587904439319646">"Battery charging, <xliff:g id="BATTERY_PERCENTAGE">%d</xliff:g> percent."</string>
     <string name="accessibility_settings_button" msgid="799583911231893380">"System settings"</string>
     <string name="accessibility_notifications_button" msgid="4498000369779421892">"Notifications."</string>
@@ -647,13 +648,10 @@
     <string name="inline_silent_button_keep_alerting" msgid="327696842264359693">"Keep alerting"</string>
     <string name="inline_turn_off_notifications" msgid="8635596135532202355">"Turn off notifications"</string>
     <string name="inline_keep_showing_app" msgid="1723113469580031041">"Keep showing notifications from this app?"</string>
-    <string name="notification_silence_title" msgid="7352089096356977930">"Gentle"</string>
-    <string name="notification_alert_title" msgid="3966526305405016221">"Prioritised"</string>
-    <string name="notification_channel_summary_low" msgid="1065819618107531284">"Helps you focus with notifications only in the pull-down shade. Always silent."</string>
-    <string name="notification_channel_summary_low_status" msgid="2702170424808743755">"Displays below priority notifications. Always silent."</string>
-    <string name="notification_channel_summary_low_lock" msgid="7966605244472624458">"Displays below priority notifications. Always silent."</string>
-    <string name="notification_channel_summary_low_status_lock" msgid="7012562768950012739">"Displays below priority notifications. Always silent."</string>
-    <string name="notification_channel_summary_default" msgid="3847289783382316019">"Gets your attention with sound and a status bar icon. Shows on lock screen."</string>
+    <string name="notification_silence_title" msgid="5763240612242137433">"Silent"</string>
+    <string name="notification_alert_title" msgid="8031196611815490340">"Alerting"</string>
+    <string name="notification_channel_summary_low" msgid="3387466082089715555">"Helps you focus without sound or vibration."</string>
+    <string name="notification_channel_summary_default" msgid="5994062840431965586">"Gets your attention with sound or vibration."</string>
     <string name="notification_unblockable_desc" msgid="4556908766584964102">"These notifications can\'t be modified."</string>
     <string name="notification_multichannel_desc" msgid="4695920306092240550">"This group of notifications cannot be configured here"</string>
     <string name="notification_delegate_header" msgid="2857691673814814270">"Proxied notification"</string>
@@ -935,4 +933,6 @@
     <string name="bubble_accessibility_action_move_bottom_left" msgid="206369104473183217">"Move bottom left"</string>
     <string name="bubble_accessibility_action_move_bottom_right" msgid="8705660152384312329">"Move bottom right"</string>
     <string name="bubble_dismiss_text" msgid="8028337712674081668">"Dismiss"</string>
+    <string name="notification_content_system_nav_changed" msgid="7218093915747788444">"System navigation updated. To make changes, go to Settings."</string>
+    <string name="notification_content_gesture_nav_available" msgid="8111130443656460792">"Go to Settings to update system navigation"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-en-rXC/strings.xml b/packages/SystemUI/res/values-en-rXC/strings.xml
index d5c5a44..c176856 100644
--- a/packages/SystemUI/res/values-en-rXC/strings.xml
+++ b/packages/SystemUI/res/values-en-rXC/strings.xml
@@ -197,6 +197,7 @@
     <string name="carrier_network_change_mode" msgid="8149202439957837762">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‏‎‎‎‏‎‎‎‏‎‏‏‏‏‏‎‎‏‎‎‎‎‏‏‏‎‎‎‏‎‏‎‏‏‏‎‎‎‏‏‎‏‏‏‎‏‏‏‏‎‏‏‏‏‏‎‎‎‎‏‎‎Carrier network changing‎‏‎‎‏‎"</string>
     <string name="accessibility_battery_details" msgid="7645516654955025422">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‎‏‎‏‎‎‎‎‏‏‎‏‎‎‏‎‏‎‏‎‎‏‏‏‎‎‎‏‏‏‏‎‏‎‏‏‎‏‏‏‎‏‏‎‏‎‏‎‏‎‏‎‎‎‎‎‎‏‏‏‎‎Open battery details‎‏‎‎‏‎"</string>
     <string name="accessibility_battery_level" msgid="7451474187113371965">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‎‎‏‏‏‎‏‏‎‏‎‎‎‏‏‏‏‎‏‎‎‎‏‎‎‏‎‏‏‎‎‏‎‎‏‏‏‏‏‏‎‎‎‏‎‏‎‎‏‏‎‎‏‎‎‏‏‏‏‎‏‎Battery ‎‏‎‎‏‏‎<xliff:g id="NUMBER">%d</xliff:g>‎‏‎‎‏‏‏‎ percent.‎‏‎‎‏‎"</string>
+    <string name="accessibility_battery_level_with_estimate" msgid="9033100930684311630">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‏‏‏‎‏‎‏‎‏‏‏‎‎‎‎‎‎‎‏‎‏‎‏‏‎‏‏‏‏‏‏‏‎‎‎‎‏‏‎‏‏‎‎‎‎‎‏‎‏‏‎‎‎‎‏‎‎‏‏‏‎‎Battery ‎‏‎‎‏‏‎<xliff:g id="PERCENTAGE">%1$s</xliff:g>‎‏‎‎‏‏‏‎ percent, about ‎‏‎‎‏‏‎<xliff:g id="TIME">%2$s</xliff:g>‎‏‎‎‏‏‏‎ left based on your usage‎‏‎‎‏‎"</string>
     <string name="accessibility_battery_level_charging" msgid="1147587904439319646">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‎‏‏‏‏‏‏‏‎‏‏‎‏‎‎‎‎‏‏‎‏‎‎‎‏‏‏‏‎‎‏‏‏‎‎‎‎‏‎‏‎‎‎‏‏‏‏‏‏‏‏‎‎‎‏‎‏‏‏‏‎‎Battery charging, ‎‏‎‎‏‏‎<xliff:g id="BATTERY_PERCENTAGE">%d</xliff:g>‎‏‎‎‏‏‏‎ percent.‎‏‎‎‏‎"</string>
     <string name="accessibility_settings_button" msgid="799583911231893380">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‎‏‎‏‏‎‎‎‏‏‎‎‎‏‎‏‏‎‎‎‏‎‏‎‏‎‏‎‎‏‎‏‏‎‏‎‏‎‎‎‏‏‎‎‎‎‎‏‎‏‏‏‏‏‎‎‎‎‏‎‎‎System settings.‎‏‎‎‏‎"</string>
     <string name="accessibility_notifications_button" msgid="4498000369779421892">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‏‏‏‏‎‎‏‏‎‏‏‎‎‎‎‎‏‏‎‏‏‏‎‎‎‎‎‎‏‎‏‎‎‎‎‎‎‎‏‎‎‎‏‏‏‎‎‏‏‎‎‏‎‏‏‎‎‎‏‎‎‎Notifications.‎‏‎‎‏‎"</string>
@@ -647,13 +648,10 @@
     <string name="inline_silent_button_keep_alerting" msgid="327696842264359693">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‎‏‏‏‎‎‏‎‎‎‏‏‎‎‎‎‏‏‎‏‏‎‏‎‎‎‏‎‏‎‏‎‏‏‎‏‎‏‎‎‏‎‏‏‏‏‎‎‏‏‎‎‏‏‎‎‎‎‏‏‎‏‎Keep alerting‎‏‎‎‏‎"</string>
     <string name="inline_turn_off_notifications" msgid="8635596135532202355">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‏‎‏‏‏‏‏‎‏‎‏‏‏‏‏‎‎‏‏‎‎‏‏‏‎‏‏‏‎‏‎‎‏‎‎‏‎‎‎‏‎‎‎‏‎‎‎‎‎‏‎‎‏‎‏‏‏‎‎‏‏‎Turn off notifications‎‏‎‎‏‎"</string>
     <string name="inline_keep_showing_app" msgid="1723113469580031041">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‏‏‎‏‏‏‏‏‏‎‏‎‎‏‏‎‏‏‏‎‏‎‏‎‎‏‎‎‏‎‎‎‏‏‎‏‏‎‎‎‎‎‎‎‏‎‎‎‏‏‎‏‎‎‎‏‎‎‎‎‎‏‎Keep showing notifications from this app?‎‏‎‎‏‎"</string>
-    <string name="notification_silence_title" msgid="7352089096356977930">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‎‎‏‏‎‎‎‎‎‎‏‏‏‏‏‎‏‏‏‏‎‎‎‎‏‎‏‎‎‏‎‎‎‎‎‎‏‎‏‏‎‎‎‎‏‎‏‎‏‏‏‎‏‎‎‎‎‏‎‏‎‎Gentle‎‏‎‎‏‎"</string>
-    <string name="notification_alert_title" msgid="3966526305405016221">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‏‎‏‏‏‎‎‎‎‏‎‏‏‏‏‏‎‏‏‏‎‏‎‏‎‏‎‎‎‏‏‎‎‎‎‎‏‏‏‏‎‏‎‎‎‏‎‎‏‏‎‎‎‏‎‎‏‏‏‎‏‎Prioritized‎‏‎‎‏‎"</string>
-    <string name="notification_channel_summary_low" msgid="1065819618107531284">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‎‏‏‏‎‏‏‎‎‏‎‏‎‏‎‎‎‏‏‎‏‎‏‎‎‏‎‏‏‏‎‏‏‎‎‏‏‏‏‏‏‎‎‎‏‎‎‏‎‎‎‎‎‎‎‎‏‎‏‎‎‎Helps you focus with notifications only in the pull-down shade. Always silent.‎‏‎‎‏‎"</string>
-    <string name="notification_channel_summary_low_status" msgid="2702170424808743755">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‎‎‏‎‏‏‎‎‎‎‎‎‎‎‎‎‎‏‎‎‏‏‎‏‎‏‏‏‏‎‏‎‎‎‏‎‏‎‏‎‎‏‎‏‎‏‎‏‎‎‎‏‏‎‏‎‎‏‎‏‏‎Displays below priority notifications. Always silent.‎‏‎‎‏‎"</string>
-    <string name="notification_channel_summary_low_lock" msgid="7966605244472624458">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‎‏‏‏‎‏‎‎‎‏‏‏‏‎‎‎‏‎‎‎‏‎‏‎‎‎‎‏‎‏‏‎‎‏‏‏‎‏‎‎‎‏‏‏‎‎‎‎‎‎‏‎‏‎‏‎‎‏‎‏‎‎Displays below priority notifications. Always silent.‎‏‎‎‏‎"</string>
-    <string name="notification_channel_summary_low_status_lock" msgid="7012562768950012739">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‎‎‎‎‏‎‏‎‏‎‎‎‏‏‎‏‎‎‎‎‎‏‎‏‎‏‏‏‏‎‎‏‎‏‎‎‎‎‏‏‎‎‏‎‏‎‎‏‎‏‎‏‏‎‏‎‎‎‎‏‏‎Displays below priority notifications. Always silent.‎‏‎‎‏‎"</string>
-    <string name="notification_channel_summary_default" msgid="3847289783382316019">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‏‎‏‎‏‎‏‏‎‎‏‎‎‎‏‎‏‎‎‎‏‏‎‏‎‏‏‎‎‏‎‎‏‎‏‏‎‎‏‏‏‏‏‏‎‎‎‎‏‎‎‏‏‏‏‏‏‎‎‏‏‎Gets your attention with sound &amp; a status bar icon. Shows on lock screen.‎‏‎‎‏‎"</string>
+    <string name="notification_silence_title" msgid="5763240612242137433">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‎‏‏‏‏‏‏‏‏‏‎‏‏‎‎‏‎‎‏‎‎‏‏‎‎‏‏‎‏‎‏‎‎‎‏‏‏‏‏‎‎‏‏‎‎‎‎‏‎‎‎‎‏‎‏‎‏‏‎‎‏‎Silent‎‏‎‎‏‎"</string>
+    <string name="notification_alert_title" msgid="8031196611815490340">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‎‏‏‏‏‎‏‏‏‎‏‎‎‏‎‎‎‏‎‏‎‏‏‎‎‎‏‎‎‎‏‏‏‎‎‎‎‏‎‎‏‎‏‎‏‎‏‎‎‎‎‏‏‎‎‏‎‎‏‎‎‎Alerting‎‏‎‎‏‎"</string>
+    <string name="notification_channel_summary_low" msgid="3387466082089715555">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‎‏‏‏‏‎‎‎‎‎‎‏‎‏‎‏‏‎‎‏‎‎‏‏‏‎‏‎‎‎‎‏‏‏‏‏‏‏‎‏‎‎‏‎‎‎‏‎‎‎‏‏‏‎‏‏‎‎‎‏‏‎Helps you focus without sound or vibration.‎‏‎‎‏‎"</string>
+    <string name="notification_channel_summary_default" msgid="5994062840431965586">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‏‎‎‏‏‎‎‏‎‏‏‏‏‎‎‏‏‎‎‎‎‎‏‏‎‎‏‎‏‎‎‏‏‏‏‎‏‎‏‎‏‎‎‎‎‏‏‏‏‎‏‎‏‏‎‎‏‎‎‏‎‎Gets your attention with sound or vibration.‎‏‎‎‏‎"</string>
     <string name="notification_unblockable_desc" msgid="4556908766584964102">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‏‏‏‏‏‎‎‏‏‏‏‎‏‎‏‏‎‎‏‎‎‎‏‏‎‎‎‎‏‎‎‏‏‎‎‏‎‎‎‏‎‏‎‎‏‎‎‎‎‎‏‎‎‎‎‎‎‎‏‏‎‎These notifications can\'t be modified.‎‏‎‎‏‎"</string>
     <string name="notification_multichannel_desc" msgid="4695920306092240550">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‎‎‎‎‏‎‎‏‎‏‎‏‏‎‏‎‎‎‎‏‎‏‎‏‎‎‎‏‏‎‏‏‎‏‎‏‎‎‎‏‎‏‎‏‏‏‏‏‎‏‏‏‎‏‎‏‎‎‏‏‎‎This group of notifications cannot be configured here‎‏‎‎‏‎"</string>
     <string name="notification_delegate_header" msgid="2857691673814814270">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‎‎‏‏‏‏‎‏‎‏‎‎‎‏‎‎‎‏‏‏‏‎‏‏‎‏‏‏‏‏‏‎‎‎‏‏‏‎‏‎‏‎‎‏‎‏‏‎‎‏‏‏‎‎‎‏‏‏‏‏‎‎Proxied notification‎‏‎‎‏‎"</string>
@@ -935,4 +933,6 @@
     <string name="bubble_accessibility_action_move_bottom_left" msgid="206369104473183217">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‎‏‎‏‎‏‏‎‏‏‏‎‏‎‎‏‎‏‎‏‏‏‎‎‏‏‎‏‏‎‏‏‎‏‏‎‎‏‎‏‏‏‏‎‏‎‏‎‏‎‎‏‏‏‏‏‏‎‎‎‏‎Move bottom left‎‏‎‎‏‎"</string>
     <string name="bubble_accessibility_action_move_bottom_right" msgid="8705660152384312329">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‏‏‎‎‎‏‏‎‏‎‎‎‎‏‎‏‏‎‏‏‏‏‏‎‎‏‎‎‎‏‎‏‏‎‏‏‎‎‎‏‎‎‎‏‏‏‏‎‏‎‏‎‎‎‎‎‎‏‎‎‏‎Move bottom right‎‏‎‎‏‎"</string>
     <string name="bubble_dismiss_text" msgid="8028337712674081668">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‎‏‏‏‏‎‏‏‎‏‎‏‎‎‏‏‎‎‎‏‎‏‎‎‏‏‏‎‏‎‎‎‏‏‏‎‎‏‏‎‎‏‏‏‏‏‎‎‎‏‎‏‏‏‎‎‎‎‏‎‎‎Dismiss‎‏‎‎‏‎"</string>
+    <string name="notification_content_system_nav_changed" msgid="7218093915747788444">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‎‎‏‎‎‎‎‏‎‏‎‏‏‏‏‎‏‎‎‏‎‎‎‏‎‏‏‎‎‎‏‎‏‏‎‏‏‏‎‎‎‏‏‏‎‎‎‏‎‎‏‏‎‏‎‎‏‏‏‎‎‎System navigation updated. To make changes, go to Settings.‎‏‎‎‏‎"</string>
+    <string name="notification_content_gesture_nav_available" msgid="8111130443656460792">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‏‎‎‎‎‏‎‎‏‎‎‎‎‏‎‎‎‎‏‏‎‎‎‏‎‏‎‎‏‏‏‏‏‎‏‎‎‏‏‏‏‏‏‏‏‏‏‏‏‏‎‎‏‏‏‏‏‏‎‎‎‎Go to Settings to update system navigation‎‏‎‎‏‎"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-es-rUS/strings.xml b/packages/SystemUI/res/values-es-rUS/strings.xml
index 924e596..de09ed8 100644
--- a/packages/SystemUI/res/values-es-rUS/strings.xml
+++ b/packages/SystemUI/res/values-es-rUS/strings.xml
@@ -62,12 +62,10 @@
     <string name="usb_debugging_secondary_user_title" msgid="6353808721761220421">"No tienes permitida la depuración por USB"</string>
     <string name="usb_debugging_secondary_user_message" msgid="6067122453571699801">"El usuario al que accediste en este dispositivo no puede activar la depuración por USB. Para usar esta función, debes cambiar al usuario principal."</string>
     <string name="usb_contaminant_title" msgid="206854874263058490">"Puerto USB inhabilitado"</string>
-    <!-- no translation found for usb_contaminant_message (7379089091591609111) -->
-    <skip />
+    <string name="usb_contaminant_message" msgid="7379089091591609111">"Para proteger tu dispositivo de líquidos o suciedad, el puerto USB está inhabilitado y no detectará ningún accesorio.\n\nTe avisaremos cuando puedas usar el puerto USB de nuevo."</string>
     <string name="usb_port_enabled" msgid="7906141351687694867">"Se habilitó el puerto USB para detectar cargadores y accesorios"</string>
     <string name="usb_disable_contaminant_detection" msgid="2103905315747120033">"Habilitar USB"</string>
-    <!-- no translation found for learn_more (5000517160980853569) -->
-    <skip />
+    <string name="learn_more" msgid="5000517160980853569">"Más información"</string>
     <string name="compat_mode_on" msgid="6623839244840638213">"Zoom para ocupar la pantalla"</string>
     <string name="compat_mode_off" msgid="4434467572461327898">"Estirar p/ ocupar la pantalla"</string>
     <string name="global_action_screenshot" msgid="8329831278085426283">"Captura de pantalla"</string>
@@ -199,6 +197,7 @@
     <string name="carrier_network_change_mode" msgid="8149202439957837762">"Cambio de proveedor de red"</string>
     <string name="accessibility_battery_details" msgid="7645516654955025422">"Abrir detalles de la batería"</string>
     <string name="accessibility_battery_level" msgid="7451474187113371965">"Batería <xliff:g id="NUMBER">%d</xliff:g> por ciento"</string>
+    <string name="accessibility_battery_level_with_estimate" msgid="9033100930684311630">"Batería: <xliff:g id="PERCENTAGE">%1$s</xliff:g> por ciento; tiempo restante: aproximadamente <xliff:g id="TIME">%2$s</xliff:g> en función del uso"</string>
     <string name="accessibility_battery_level_charging" msgid="1147587904439319646">"Cargando batería: <xliff:g id="BATTERY_PERCENTAGE">%d</xliff:g>%%"</string>
     <string name="accessibility_settings_button" msgid="799583911231893380">"Configuración del sistema"</string>
     <string name="accessibility_notifications_button" msgid="4498000369779421892">"Notificaciones"</string>
@@ -458,10 +457,8 @@
     <string name="media_projection_remember_text" msgid="3103510882172746752">"No volver a mostrar"</string>
     <string name="clear_all_notifications_text" msgid="814192889771462828">"Borrar todo"</string>
     <string name="manage_notifications_text" msgid="2386728145475108753">"Administrar"</string>
-    <!-- no translation found for notification_section_header_gentle (4372438504154095677) -->
-    <skip />
-    <!-- no translation found for accessibility_notification_section_header_gentle_clear_all (4286716295850400959) -->
-    <skip />
+    <string name="notification_section_header_gentle" msgid="4372438504154095677">"Notificaciones silenciosas"</string>
+    <string name="accessibility_notification_section_header_gentle_clear_all" msgid="4286716295850400959">"Borrar todas las notificaciones silenciosas"</string>
     <string name="dnd_suppressing_shade_text" msgid="1904574852846769301">"Notificaciones pausadas por el modo \"No interrumpir\""</string>
     <string name="media_projection_action_text" msgid="8470872969457985954">"Comenzar ahora"</string>
     <string name="empty_shade_text" msgid="708135716272867002">"No hay notificaciones"</string>
@@ -645,21 +642,16 @@
     <string name="inline_block_button" msgid="8735843688021655065">"Bloquear"</string>
     <string name="inline_keep_button" msgid="6665940297019018232">"Seguir viendo"</string>
     <string name="inline_minimize_button" msgid="966233327974702195">"Minimizar"</string>
-    <!-- no translation found for inline_silent_button_silent (5315879183296940969) -->
-    <skip />
+    <string name="inline_silent_button_silent" msgid="5315879183296940969">"Silencio"</string>
     <string name="inline_silent_button_stay_silent" msgid="6308371431217601009">"Silenciar notificaciones"</string>
-    <!-- no translation found for inline_silent_button_alert (6008435419895088034) -->
-    <skip />
+    <string name="inline_silent_button_alert" msgid="6008435419895088034">"Alertas"</string>
     <string name="inline_silent_button_keep_alerting" msgid="327696842264359693">"Seguir recibiendo alertas"</string>
     <string name="inline_turn_off_notifications" msgid="8635596135532202355">"Desactivar notificaciones"</string>
     <string name="inline_keep_showing_app" msgid="1723113469580031041">"¿Quieres seguir viendo las notificaciones de esta app?"</string>
-    <string name="notification_silence_title" msgid="7352089096356977930">"Discretas"</string>
-    <string name="notification_alert_title" msgid="3966526305405016221">"Priorizadas"</string>
-    <string name="notification_channel_summary_low" msgid="1065819618107531284">"Te ayuda a concentrarte, ya que las notificaciones se muestran solo como banner desplegable. Siempre en silencio."</string>
-    <string name="notification_channel_summary_low_status" msgid="2702170424808743755">"Se muestra debajo de las notificaciones de prioridad. Siempre en silencio."</string>
-    <string name="notification_channel_summary_low_lock" msgid="7966605244472624458">"Se muestra debajo de las notificaciones de prioridad. Siempre en silencio."</string>
-    <string name="notification_channel_summary_low_status_lock" msgid="7012562768950012739">"Se muestra debajo de las notificaciones de prioridad. Siempre en silencio."</string>
-    <string name="notification_channel_summary_default" msgid="3847289783382316019">"Notificaciones que llaman la atención con sonido y un ícono en la barra de estado. Se muestra en la pantalla bloqueada."</string>
+    <string name="notification_silence_title" msgid="5763240612242137433">"Silencio"</string>
+    <string name="notification_alert_title" msgid="8031196611815490340">"Alertas"</string>
+    <string name="notification_channel_summary_low" msgid="3387466082089715555">"Te ayuda a concentrarte sin sonar ni vibrar."</string>
+    <string name="notification_channel_summary_default" msgid="5994062840431965586">"Capta tu atención con sonido o vibración."</string>
     <string name="notification_unblockable_desc" msgid="4556908766584964102">"No se pueden modificar estas notificaciones."</string>
     <string name="notification_multichannel_desc" msgid="4695920306092240550">"No se puede configurar aquí este grupo de notificaciones"</string>
     <string name="notification_delegate_header" msgid="2857691673814814270">"Notificación almacenada en proxy"</string>
@@ -908,8 +900,7 @@
     <string name="slice_permission_allow" msgid="2340244901366722709">"Permitir"</string>
     <string name="slice_permission_deny" msgid="7683681514008048807">"Rechazar"</string>
     <string name="auto_saver_title" msgid="1217959994732964228">"Presiona para programar el Ahorro de batería"</string>
-    <!-- no translation found for auto_saver_text (2563289953551438248) -->
-    <skip />
+    <string name="auto_saver_text" msgid="2563289953551438248">"Actívalo cuando la batería se esté por acabar"</string>
     <string name="no_auto_saver_action" msgid="8086002101711328500">"No, gracias"</string>
     <string name="auto_saver_enabled_title" msgid="6726474226058316862">"Se activó la programación del Ahorro de batería"</string>
     <string name="auto_saver_enabled_text" msgid="874711029884777579">"El Ahorro de batería se activará automáticamente cuando quede menos de <xliff:g id="PERCENTAGE">%d</xliff:g>%% de batería."</string>
@@ -942,4 +933,6 @@
     <string name="bubble_accessibility_action_move_bottom_left" msgid="206369104473183217">"Ubicar abajo a la izquierda"</string>
     <string name="bubble_accessibility_action_move_bottom_right" msgid="8705660152384312329">"Ubicar abajo a la derecha"</string>
     <string name="bubble_dismiss_text" msgid="8028337712674081668">"Ignorar"</string>
+    <string name="notification_content_system_nav_changed" msgid="7218093915747788444">"Se actualizó el sistema de navegación. Para hacer cambios, ve a Configuración."</string>
+    <string name="notification_content_gesture_nav_available" msgid="8111130443656460792">"Ve a Configuración para actualizar la navegación del sistema"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-es/strings.xml b/packages/SystemUI/res/values-es/strings.xml
index 25611bd..a6bd968 100644
--- a/packages/SystemUI/res/values-es/strings.xml
+++ b/packages/SystemUI/res/values-es/strings.xml
@@ -62,12 +62,10 @@
     <string name="usb_debugging_secondary_user_title" msgid="6353808721761220421">"Depuración USB no permitida"</string>
     <string name="usb_debugging_secondary_user_message" msgid="6067122453571699801">"El usuario con el que se ha iniciado sesión en este dispositivo no puede activar la depuración USB. Para utilizar esta función, inicia sesión con la cuenta de usuario principal."</string>
     <string name="usb_contaminant_title" msgid="206854874263058490">"Puerto USB inhabilitado"</string>
-    <!-- no translation found for usb_contaminant_message (7379089091591609111) -->
-    <skip />
+    <string name="usb_contaminant_message" msgid="7379089091591609111">"Para proteger tu dispositivo de los líquidos y la suciedad, el puerto USB se ha inhabilitado y no detectará ningún accesorio.\n\nRecibirás una notificación cuando puedas volver a usarlo."</string>
     <string name="usb_port_enabled" msgid="7906141351687694867">"Puerto USB habilitado para detectar cargadores y accesorios"</string>
     <string name="usb_disable_contaminant_detection" msgid="2103905315747120033">"Habilitar USB"</string>
-    <!-- no translation found for learn_more (5000517160980853569) -->
-    <skip />
+    <string name="learn_more" msgid="5000517160980853569">"Más información"</string>
     <string name="compat_mode_on" msgid="6623839244840638213">"Zoom para ajustar"</string>
     <string name="compat_mode_off" msgid="4434467572461327898">"Expandir para ajustar"</string>
     <string name="global_action_screenshot" msgid="8329831278085426283">"Captura de pantalla"</string>
@@ -199,6 +197,7 @@
     <string name="carrier_network_change_mode" msgid="8149202439957837762">"Cambiando la red del operador"</string>
     <string name="accessibility_battery_details" msgid="7645516654955025422">"Abrir detalles de la batería"</string>
     <string name="accessibility_battery_level" msgid="7451474187113371965">"<xliff:g id="NUMBER">%d</xliff:g> por ciento de batería"</string>
+    <string name="accessibility_battery_level_with_estimate" msgid="9033100930684311630">"Queda un <xliff:g id="PERCENTAGE">%1$s</xliff:g> por ciento de batería (<xliff:g id="TIME">%2$s</xliff:g> aproximadamente según tu uso)"</string>
     <string name="accessibility_battery_level_charging" msgid="1147587904439319646">"Batería cargando (<xliff:g id="BATTERY_PERCENTAGE">%d</xliff:g> %%)."</string>
     <string name="accessibility_settings_button" msgid="799583911231893380">"Ajustes del sistema"</string>
     <string name="accessibility_notifications_button" msgid="4498000369779421892">"Notificaciones"</string>
@@ -458,10 +457,8 @@
     <string name="media_projection_remember_text" msgid="3103510882172746752">"No volver a mostrar"</string>
     <string name="clear_all_notifications_text" msgid="814192889771462828">"Borrar todo"</string>
     <string name="manage_notifications_text" msgid="2386728145475108753">"Gestionar"</string>
-    <!-- no translation found for notification_section_header_gentle (4372438504154095677) -->
-    <skip />
-    <!-- no translation found for accessibility_notification_section_header_gentle_clear_all (4286716295850400959) -->
-    <skip />
+    <string name="notification_section_header_gentle" msgid="4372438504154095677">"Notificaciones silenciadas"</string>
+    <string name="accessibility_notification_section_header_gentle_clear_all" msgid="4286716295850400959">"Borrar todas las notificaciones silenciadas"</string>
     <string name="dnd_suppressing_shade_text" msgid="1904574852846769301">"Notificaciones pausadas por el modo No molestar"</string>
     <string name="media_projection_action_text" msgid="8470872969457985954">"Iniciar ahora"</string>
     <string name="empty_shade_text" msgid="708135716272867002">"No hay notificaciones"</string>
@@ -645,21 +642,16 @@
     <string name="inline_block_button" msgid="8735843688021655065">"Bloquear"</string>
     <string name="inline_keep_button" msgid="6665940297019018232">"Seguir mostrando"</string>
     <string name="inline_minimize_button" msgid="966233327974702195">"Minimizar"</string>
-    <!-- no translation found for inline_silent_button_silent (5315879183296940969) -->
-    <skip />
+    <string name="inline_silent_button_silent" msgid="5315879183296940969">"Silencio"</string>
     <string name="inline_silent_button_stay_silent" msgid="6308371431217601009">"Silenciar notificaciones"</string>
-    <!-- no translation found for inline_silent_button_alert (6008435419895088034) -->
-    <skip />
+    <string name="inline_silent_button_alert" msgid="6008435419895088034">"Alertas"</string>
     <string name="inline_silent_button_keep_alerting" msgid="327696842264359693">"Quiero seguir recibiendo alertas"</string>
     <string name="inline_turn_off_notifications" msgid="8635596135532202355">"Desactivar notificaciones"</string>
     <string name="inline_keep_showing_app" msgid="1723113469580031041">"¿Quieres seguir viendo las notificaciones de esta aplicación?"</string>
-    <string name="notification_silence_title" msgid="7352089096356977930">"Discretas"</string>
-    <string name="notification_alert_title" msgid="3966526305405016221">"Priorizadas"</string>
-    <string name="notification_channel_summary_low" msgid="1065819618107531284">"Las notificaciones solo se muestran en la pantalla desplegable para que puedas concentrarte. Siempre en silencio."</string>
-    <string name="notification_channel_summary_low_status" msgid="2702170424808743755">"Muestra las notificaciones con prioridad baja. Siempre en silencio."</string>
-    <string name="notification_channel_summary_low_lock" msgid="7966605244472624458">"Muestra las notificaciones con prioridad baja. Siempre en silencio."</string>
-    <string name="notification_channel_summary_low_status_lock" msgid="7012562768950012739">"Muestra las notificaciones con prioridad baja. Siempre en silencio."</string>
-    <string name="notification_channel_summary_default" msgid="3847289783382316019">"Llama tu atención con sonido y un icono en la barra de estado. Se muestra en la pantalla de bloqueo."</string>
+    <string name="notification_silence_title" msgid="5763240612242137433">"Silencio"</string>
+    <string name="notification_alert_title" msgid="8031196611815490340">"Alertas"</string>
+    <string name="notification_channel_summary_low" msgid="3387466082089715555">"Te ayuda a concentrarte sin sonido ni vibración."</string>
+    <string name="notification_channel_summary_default" msgid="5994062840431965586">"Llama tu atención con sonido o vibración."</string>
     <string name="notification_unblockable_desc" msgid="4556908766584964102">"Estas notificaciones no se pueden modificar."</string>
     <string name="notification_multichannel_desc" msgid="4695920306092240550">"Este grupo de notificaciones no se puede configurar aquí"</string>
     <string name="notification_delegate_header" msgid="2857691673814814270">"Notificación mediante proxy"</string>
@@ -908,8 +900,7 @@
     <string name="slice_permission_allow" msgid="2340244901366722709">"Permitir"</string>
     <string name="slice_permission_deny" msgid="7683681514008048807">"Denegar"</string>
     <string name="auto_saver_title" msgid="1217959994732964228">"Tocar para programar el modo Ahorro de batería"</string>
-    <!-- no translation found for auto_saver_text (2563289953551438248) -->
-    <skip />
+    <string name="auto_saver_text" msgid="2563289953551438248">"Activar cuando sea probable que se quede sin batería"</string>
     <string name="no_auto_saver_action" msgid="8086002101711328500">"No, gracias"</string>
     <string name="auto_saver_enabled_title" msgid="6726474226058316862">"Se ha activado la programación del modo Ahorro de batería"</string>
     <string name="auto_saver_enabled_text" msgid="874711029884777579">"El modo Ahorro de batería se activará automáticamente cuando quede menos de un <xliff:g id="PERCENTAGE">%d</xliff:g> %% de batería."</string>
@@ -942,4 +933,6 @@
     <string name="bubble_accessibility_action_move_bottom_left" msgid="206369104473183217">"Mover abajo a la izquierda."</string>
     <string name="bubble_accessibility_action_move_bottom_right" msgid="8705660152384312329">"Mover abajo a la derecha"</string>
     <string name="bubble_dismiss_text" msgid="8028337712674081668">"Cerrar"</string>
+    <string name="notification_content_system_nav_changed" msgid="7218093915747788444">"Se ha actualizado la navegación del sistema. Para hacer cambios, ve a Ajustes."</string>
+    <string name="notification_content_gesture_nav_available" msgid="8111130443656460792">"Ve a Ajustes para actualizar la navegación del sistema"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-et/strings.xml b/packages/SystemUI/res/values-et/strings.xml
index 2864128..aa45855 100644
--- a/packages/SystemUI/res/values-et/strings.xml
+++ b/packages/SystemUI/res/values-et/strings.xml
@@ -62,12 +62,10 @@
     <string name="usb_debugging_secondary_user_title" msgid="6353808721761220421">"USB-silumine pole lubatud"</string>
     <string name="usb_debugging_secondary_user_message" msgid="6067122453571699801">"Sellesse seadmesse praegu sisse logitud kasutaja ei saa USB-silumist sisse lülitada. Selle funktsiooni kasutamiseks vahetage peamisele kasutajale."</string>
     <string name="usb_contaminant_title" msgid="206854874263058490">"USB-port on keelatud"</string>
-    <!-- no translation found for usb_contaminant_message (7379089091591609111) -->
-    <skip />
+    <string name="usb_contaminant_message" msgid="7379089091591609111">"Selleks et kaitsta teie seadet vedeliku või mustuse eest, on USB-port keelatud ja see ei tuvasta lisatarvikuid.\n\nKui USB-porti tohib taas kasutada, saate selle kohta märguande."</string>
     <string name="usb_port_enabled" msgid="7906141351687694867">"USB-pordil on lubatud tuvastada laadijaid ja tarvikuid"</string>
     <string name="usb_disable_contaminant_detection" msgid="2103905315747120033">"Luba USB"</string>
-    <!-- no translation found for learn_more (5000517160980853569) -->
-    <skip />
+    <string name="learn_more" msgid="5000517160980853569">"Lisateave"</string>
     <string name="compat_mode_on" msgid="6623839244840638213">"Suumi ekraani täitmiseks"</string>
     <string name="compat_mode_off" msgid="4434467572461327898">"Venita ekraani täitmiseks"</string>
     <string name="global_action_screenshot" msgid="8329831278085426283">"Ekraanipilt"</string>
@@ -199,6 +197,7 @@
     <string name="carrier_network_change_mode" msgid="8149202439957837762">"Operaatori võrku muudetakse"</string>
     <string name="accessibility_battery_details" msgid="7645516654955025422">"Aku üksikasjade avamine"</string>
     <string name="accessibility_battery_level" msgid="7451474187113371965">"Aku: <xliff:g id="NUMBER">%d</xliff:g> protsenti."</string>
+    <string name="accessibility_battery_level_with_estimate" msgid="9033100930684311630">"Aku protsent <xliff:g id="PERCENTAGE">%1$s</xliff:g>, teie kasutuse põhjal on jäänud ligikaudu <xliff:g id="TIME">%2$s</xliff:g>"</string>
     <string name="accessibility_battery_level_charging" msgid="1147587904439319646">"Akut laetakse (<xliff:g id="BATTERY_PERCENTAGE">%d</xliff:g>%%)."</string>
     <string name="accessibility_settings_button" msgid="799583911231893380">"Süsteemiseaded"</string>
     <string name="accessibility_notifications_button" msgid="4498000369779421892">"Märguanded"</string>
@@ -458,10 +457,8 @@
     <string name="media_projection_remember_text" msgid="3103510882172746752">"Ära kuva uuesti"</string>
     <string name="clear_all_notifications_text" msgid="814192889771462828">"Tühjenda kõik"</string>
     <string name="manage_notifications_text" msgid="2386728145475108753">"Haldamine"</string>
-    <!-- no translation found for notification_section_header_gentle (4372438504154095677) -->
-    <skip />
-    <!-- no translation found for accessibility_notification_section_header_gentle_clear_all (4286716295850400959) -->
-    <skip />
+    <string name="notification_section_header_gentle" msgid="4372438504154095677">"Hääletud märguanded"</string>
+    <string name="accessibility_notification_section_header_gentle_clear_all" msgid="4286716295850400959">"Kustuta kõik hääletud märguanded"</string>
     <string name="dnd_suppressing_shade_text" msgid="1904574852846769301">"Režiim Mitte segada peatas märguanded"</string>
     <string name="media_projection_action_text" msgid="8470872969457985954">"Alusta kohe"</string>
     <string name="empty_shade_text" msgid="708135716272867002">"Märguandeid pole"</string>
@@ -645,21 +642,16 @@
     <string name="inline_block_button" msgid="8735843688021655065">"Blokeeri"</string>
     <string name="inline_keep_button" msgid="6665940297019018232">"Jätka kuvamist"</string>
     <string name="inline_minimize_button" msgid="966233327974702195">"Minimeeri"</string>
-    <!-- no translation found for inline_silent_button_silent (5315879183296940969) -->
-    <skip />
+    <string name="inline_silent_button_silent" msgid="5315879183296940969">"Hääletu"</string>
     <string name="inline_silent_button_stay_silent" msgid="6308371431217601009">"Kuva helita"</string>
-    <!-- no translation found for inline_silent_button_alert (6008435419895088034) -->
-    <skip />
+    <string name="inline_silent_button_alert" msgid="6008435419895088034">"Teavitamine"</string>
     <string name="inline_silent_button_keep_alerting" msgid="327696842264359693">"Teavita ka edaspidi"</string>
     <string name="inline_turn_off_notifications" msgid="8635596135532202355">"Lülita märguanded välja"</string>
     <string name="inline_keep_showing_app" msgid="1723113469580031041">"Kas jätkata selle rakenduse märguannete kuvamist?"</string>
-    <string name="notification_silence_title" msgid="7352089096356977930">"Leebe"</string>
-    <string name="notification_alert_title" msgid="3966526305405016221">"Prioriseeritud"</string>
-    <string name="notification_channel_summary_low" msgid="1065819618107531284">"Aitab teil allatõmmatavas menüüs ainult märguannetele keskenduda. Alati vaikne."</string>
-    <string name="notification_channel_summary_low_status" msgid="2702170424808743755">"Kuvatakse prioriteetsete märguannete all. Alati vaikne."</string>
-    <string name="notification_channel_summary_low_lock" msgid="7966605244472624458">"Kuvatakse prioriteetsete märguannete all. Alati vaikne."</string>
-    <string name="notification_channel_summary_low_status_lock" msgid="7012562768950012739">"Kuvatakse prioriteetsete märguannete all. Alati vaikne."</string>
-    <string name="notification_channel_summary_default" msgid="3847289783382316019">"Haarab teie tähelepanu heli ja olekuriba ikooni abil. Kuvatakse lukustuskuval."</string>
+    <string name="notification_silence_title" msgid="5763240612242137433">"Hääletu"</string>
+    <string name="notification_alert_title" msgid="8031196611815490340">"Teavitamine"</string>
+    <string name="notification_channel_summary_low" msgid="3387466082089715555">"Aitab teil keskenduda (heli või vibreerimine puudub)."</string>
+    <string name="notification_channel_summary_default" msgid="5994062840431965586">"Haarab heli või vibreerimisega teie tähelepanu."</string>
     <string name="notification_unblockable_desc" msgid="4556908766584964102">"Neid märguandeid ei saa muuta."</string>
     <string name="notification_multichannel_desc" msgid="4695920306092240550">"Seda märguannete rühma ei saa siin seadistada"</string>
     <string name="notification_delegate_header" msgid="2857691673814814270">"Puhvriga märguanne"</string>
@@ -908,8 +900,7 @@
     <string name="slice_permission_allow" msgid="2340244901366722709">"Luba"</string>
     <string name="slice_permission_deny" msgid="7683681514008048807">"Keela"</string>
     <string name="auto_saver_title" msgid="1217959994732964228">"Puudutage akusäästja ajastamiseks"</string>
-    <!-- no translation found for auto_saver_text (2563289953551438248) -->
-    <skip />
+    <string name="auto_saver_text" msgid="2563289953551438248">"Lülitatakse sisse, kui aku hakkab tühjaks saama"</string>
     <string name="no_auto_saver_action" msgid="8086002101711328500">"Tänan, ei"</string>
     <string name="auto_saver_enabled_title" msgid="6726474226058316862">"Automaatne akusäästja on sisse lülitatud"</string>
     <string name="auto_saver_enabled_text" msgid="874711029884777579">"Kui aku tase langeb alla <xliff:g id="PERCENTAGE">%d</xliff:g>%%, lülitub akusäästja automaatselt sisse."</string>
@@ -942,4 +933,6 @@
     <string name="bubble_accessibility_action_move_bottom_left" msgid="206369104473183217">"Teisalda alla vasakule"</string>
     <string name="bubble_accessibility_action_move_bottom_right" msgid="8705660152384312329">"Teisalda alla paremale"</string>
     <string name="bubble_dismiss_text" msgid="8028337712674081668">"Loobu"</string>
+    <string name="notification_content_system_nav_changed" msgid="7218093915747788444">"Süsteemis navigeerimine on värskendatud. Muutmiseks avage jaotis Seaded."</string>
+    <string name="notification_content_gesture_nav_available" msgid="8111130443656460792">"Süsteemi navigeerimise värskendamiseks avage jaotis Seaded"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-eu/strings.xml b/packages/SystemUI/res/values-eu/strings.xml
index 1feb1b1..542ec43 100644
--- a/packages/SystemUI/res/values-eu/strings.xml
+++ b/packages/SystemUI/res/values-eu/strings.xml
@@ -62,12 +62,10 @@
     <string name="usb_debugging_secondary_user_title" msgid="6353808721761220421">"Ez da onartzen USB arazketa"</string>
     <string name="usb_debugging_secondary_user_message" msgid="6067122453571699801">"Gailu honetan saioa hasita duen erabiltzaileak ezin du aktibatu USB arazketa. Eginbide hori erabiltzeko, aldatu erabiltzaile nagusira."</string>
     <string name="usb_contaminant_title" msgid="206854874263058490">"Desgaitu egin da USB ataka"</string>
-    <!-- no translation found for usb_contaminant_message (7379089091591609111) -->
-    <skip />
+    <string name="usb_contaminant_message" msgid="7379089091591609111">"USB ataka desgaitu egin da gailua likido edo zikinkeriengandik babesteko, eta ez du hautemango osagarririk.\n\nJakinarazpen bat jasoko duzu USB ataka berriz erabiltzeko moduan dagoenean."</string>
     <string name="usb_port_enabled" msgid="7906141351687694867">"USB ataka gaitu da kargagailuak eta osagarriak hautemateko"</string>
     <string name="usb_disable_contaminant_detection" msgid="2103905315747120033">"Gaitu USB ataka"</string>
-    <!-- no translation found for learn_more (5000517160980853569) -->
-    <skip />
+    <string name="learn_more" msgid="5000517160980853569">"Lortu informazio gehiago"</string>
     <string name="compat_mode_on" msgid="6623839244840638213">"Handiagotu pantaila betetzeko"</string>
     <string name="compat_mode_off" msgid="4434467572461327898">"Luzatu pantaila betetzeko"</string>
     <string name="global_action_screenshot" msgid="8329831278085426283">"Pantaila-argazkia"</string>
@@ -199,6 +197,7 @@
     <string name="carrier_network_change_mode" msgid="8149202439957837762">"Operadorearen sarea aldatzen"</string>
     <string name="accessibility_battery_details" msgid="7645516654955025422">"Ireki bateriaren xehetasunak"</string>
     <string name="accessibility_battery_level" msgid="7451474187113371965">"Bateriaren karga: <xliff:g id="NUMBER">%d</xliff:g>."</string>
+    <string name="accessibility_battery_level_with_estimate" msgid="9033100930684311630">"Bateriak ehuneko <xliff:g id="PERCENTAGE">%1$s</xliff:g> dauka kargatuta. Zure erabilera kontuan izanda, <xliff:g id="TIME">%2$s</xliff:g> inguru gelditzen zaizkio."</string>
     <string name="accessibility_battery_level_charging" msgid="1147587904439319646">"Kargatzen ari da bateria. %% <xliff:g id="BATTERY_PERCENTAGE">%d</xliff:g> arte kargatu da oraingoz."</string>
     <string name="accessibility_settings_button" msgid="799583911231893380">"Sistemaren ezarpenak."</string>
     <string name="accessibility_notifications_button" msgid="4498000369779421892">"Jakinarazpenak."</string>
@@ -458,10 +457,8 @@
     <string name="media_projection_remember_text" msgid="3103510882172746752">"Ez erakutsi berriro"</string>
     <string name="clear_all_notifications_text" msgid="814192889771462828">"Garbitu guztiak"</string>
     <string name="manage_notifications_text" msgid="2386728145475108753">"Kudeatu"</string>
-    <!-- no translation found for notification_section_header_gentle (4372438504154095677) -->
-    <skip />
-    <!-- no translation found for accessibility_notification_section_header_gentle_clear_all (4286716295850400959) -->
-    <skip />
+    <string name="notification_section_header_gentle" msgid="4372438504154095677">"Soinurik gabeko jakinarazpenak"</string>
+    <string name="accessibility_notification_section_header_gentle_clear_all" msgid="4286716295850400959">"Garbitu soinurik gabeko jakinarazpen guztiak"</string>
     <string name="dnd_suppressing_shade_text" msgid="1904574852846769301">"\"Ez molestatu\" moduak pausatu egin ditu jakinarazpenak"</string>
     <string name="media_projection_action_text" msgid="8470872969457985954">"Hasi"</string>
     <string name="empty_shade_text" msgid="708135716272867002">"Ez dago jakinarazpenik"</string>
@@ -645,21 +642,16 @@
     <string name="inline_block_button" msgid="8735843688021655065">"Blokeatu"</string>
     <string name="inline_keep_button" msgid="6665940297019018232">"Jarraitu erakusten"</string>
     <string name="inline_minimize_button" msgid="966233327974702195">"Minimizatu"</string>
-    <!-- no translation found for inline_silent_button_silent (5315879183296940969) -->
-    <skip />
+    <string name="inline_silent_button_silent" msgid="5315879183296940969">"Soinurik gabe"</string>
     <string name="inline_silent_button_stay_silent" msgid="6308371431217601009">"Jarraitu isilik"</string>
-    <!-- no translation found for inline_silent_button_alert (6008435419895088034) -->
-    <skip />
+    <string name="inline_silent_button_alert" msgid="6008435419895088034">"Alertak"</string>
     <string name="inline_silent_button_keep_alerting" msgid="327696842264359693">"Jarraitu jakinarazpenak bidaltzen"</string>
     <string name="inline_turn_off_notifications" msgid="8635596135532202355">"Desaktibatu jakinarazpenak"</string>
     <string name="inline_keep_showing_app" msgid="1723113469580031041">"Aplikazio honen jakinarazpenak erakusten jarraitzea nahi duzu?"</string>
-    <string name="notification_silence_title" msgid="7352089096356977930">"Jakinarazi soinurik gabe"</string>
-    <string name="notification_alert_title" msgid="3966526305405016221">"Lehentasunezkoak"</string>
-    <string name="notification_channel_summary_low" msgid="1065819618107531284">"Pantailaren goialdeko goitibeherako barran bakarrik erakusten ditu jakinarazpenak, arretarik gal ez dezazun. Beti isilik."</string>
-    <string name="notification_channel_summary_low_status" msgid="2702170424808743755">"Lehentasunik ez duten jakinarazpenak erakusten ditu. Beti isilik."</string>
-    <string name="notification_channel_summary_low_lock" msgid="7966605244472624458">"Lehentasunik ez duten jakinarazpenak erakusten ditu. Beti isilik."</string>
-    <string name="notification_channel_summary_low_status_lock" msgid="7012562768950012739">"Lehentasunik ez duten jakinarazpenak erakusten ditu. Beti isilik."</string>
-    <string name="notification_channel_summary_default" msgid="3847289783382316019">"Arretari dei egiten dio soinua eginda eta egoera-barran ikonoa erakutsita. Pantaila blokeatua agertzen da."</string>
+    <string name="notification_silence_title" msgid="5763240612242137433">"Isila"</string>
+    <string name="notification_alert_title" msgid="8031196611815490340">"Ohartarazlea"</string>
+    <string name="notification_channel_summary_low" msgid="3387466082089715555">"Ez du egiten soinu edo dardararik, arretarik gal ez dezazun."</string>
+    <string name="notification_channel_summary_default" msgid="5994062840431965586">"Arreta erakartzen du soinua eta dardara eginda."</string>
     <string name="notification_unblockable_desc" msgid="4556908766584964102">"Jakinarazpen horiek ezin dira aldatu."</string>
     <string name="notification_multichannel_desc" msgid="4695920306092240550">"Jakinarazpen talde hau ezin da konfiguratu hemen"</string>
     <string name="notification_delegate_header" msgid="2857691673814814270">"Proxy bidezko jakinarazpena"</string>
@@ -908,8 +900,7 @@
     <string name="slice_permission_allow" msgid="2340244901366722709">"Baimendu"</string>
     <string name="slice_permission_deny" msgid="7683681514008048807">"Ukatu"</string>
     <string name="auto_saver_title" msgid="1217959994732964228">"Sakatu bateria-aurrezlea noiz aktibatu antolatzeko"</string>
-    <!-- no translation found for auto_saver_text (2563289953551438248) -->
-    <skip />
+    <string name="auto_saver_text" msgid="2563289953551438248">"Aktibatu aurrezlea bateria agortzeko arriskua dagoenean"</string>
     <string name="no_auto_saver_action" msgid="8086002101711328500">"Ez"</string>
     <string name="auto_saver_enabled_title" msgid="6726474226058316862">"Bateria-aurrezlea aktibatu da"</string>
     <string name="auto_saver_enabled_text" msgid="874711029884777579">"Bateria-aurrezlea automatikoki aktibatuko da bateriaren %% <xliff:g id="PERCENTAGE">%d</xliff:g> gelditzen denean."</string>
@@ -942,4 +933,6 @@
     <string name="bubble_accessibility_action_move_bottom_left" msgid="206369104473183217">"Eraman behealdera, ezkerretara"</string>
     <string name="bubble_accessibility_action_move_bottom_right" msgid="8705660152384312329">"Eraman behealdera, eskuinetara"</string>
     <string name="bubble_dismiss_text" msgid="8028337712674081668">"Baztertu"</string>
+    <string name="notification_content_system_nav_changed" msgid="7218093915747788444">"Eguneratu da sistemaren nabigazioa. Aldaketak egiteko, joan Ezarpenak atalera."</string>
+    <string name="notification_content_gesture_nav_available" msgid="8111130443656460792">"Sistemaren nabigazioa eguneratzeko, joan Ezarpenak atalera"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-fa/strings.xml b/packages/SystemUI/res/values-fa/strings.xml
index e161b77..02e017e 100644
--- a/packages/SystemUI/res/values-fa/strings.xml
+++ b/packages/SystemUI/res/values-fa/strings.xml
@@ -62,12 +62,10 @@
     <string name="usb_debugging_secondary_user_title" msgid="6353808721761220421">"‏اشکال‌زدایی USB مجاز نیست"</string>
     <string name="usb_debugging_secondary_user_message" msgid="6067122453571699801">"‏کاربری که درحال حاضر در این دستگاه وارد سیستم شده است نمی‌تواند اشکال‌زدایی USB را روشن کند. برای استفاده از این قابلیت، به کاربر اصلی تغییر وضعیت دهید."</string>
     <string name="usb_contaminant_title" msgid="206854874263058490">"‏درگاه USB غیرفعال شده است"</string>
-    <!-- no translation found for usb_contaminant_message (7379089091591609111) -->
-    <skip />
+    <string name="usb_contaminant_message" msgid="7379089091591609111">"‏برای محافظت از دستگاهتان دربرابر مایعات یا خاکروبه، درگاه USB غیرفعال شده است و هیچ‌کدام از لوازم جانبی را شناسایی نخواهد کرد.\n\nهرزمان که استفاده از درگاه USB امکان‌پذیر باشد، به شما اطلاع داده می‌شود."</string>
     <string name="usb_port_enabled" msgid="7906141351687694867">"‏درگاه USB برای تشخیص شارژرها و لوازم جانبی فعال شد"</string>
     <string name="usb_disable_contaminant_detection" msgid="2103905315747120033">"‏فعال کردن USB"</string>
-    <!-- no translation found for learn_more (5000517160980853569) -->
-    <skip />
+    <string name="learn_more" msgid="5000517160980853569">"بیشتر بدانید"</string>
     <string name="compat_mode_on" msgid="6623839244840638213">"بزرگ‌نمایی برای پر کردن صفحه"</string>
     <string name="compat_mode_off" msgid="4434467572461327898">"گسترده کردن برای پر کردن صفحه"</string>
     <string name="global_action_screenshot" msgid="8329831278085426283">"عکس صفحه‌نمایش"</string>
@@ -199,6 +197,7 @@
     <string name="carrier_network_change_mode" msgid="8149202439957837762">"تغییر شبکه شرکت مخابراتی"</string>
     <string name="accessibility_battery_details" msgid="7645516654955025422">"باز کردن جزئیات باتری"</string>
     <string name="accessibility_battery_level" msgid="7451474187113371965">"باتری <xliff:g id="NUMBER">%d</xliff:g> درصد."</string>
+    <string name="accessibility_battery_level_with_estimate" msgid="9033100930684311630">"باتری <xliff:g id="PERCENTAGE">%1$s</xliff:g> درصد شارژ دارد، براساس مصرفتان تقریباً <xliff:g id="TIME">%2$s</xliff:g> شارژ باقی‌مانده است"</string>
     <string name="accessibility_battery_level_charging" msgid="1147587904439319646">"در حال شارژ باتری، <xliff:g id="BATTERY_PERCENTAGE">%d</xliff:g> درصد"</string>
     <string name="accessibility_settings_button" msgid="799583911231893380">"تنظیمات سیستم."</string>
     <string name="accessibility_notifications_button" msgid="4498000369779421892">"اعلان‌ها."</string>
@@ -458,10 +457,8 @@
     <string name="media_projection_remember_text" msgid="3103510882172746752">"دوباره نشان داده نشود"</string>
     <string name="clear_all_notifications_text" msgid="814192889771462828">"پاک کردن همه موارد"</string>
     <string name="manage_notifications_text" msgid="2386728145475108753">"مدیریت"</string>
-    <!-- no translation found for notification_section_header_gentle (4372438504154095677) -->
-    <skip />
-    <!-- no translation found for accessibility_notification_section_header_gentle_clear_all (4286716295850400959) -->
-    <skip />
+    <string name="notification_section_header_gentle" msgid="4372438504154095677">"اعلان‌های بی‌صدا"</string>
+    <string name="accessibility_notification_section_header_gentle_clear_all" msgid="4286716295850400959">"پاک کردن همه اعلان‌های بی‌صدا"</string>
     <string name="dnd_suppressing_shade_text" msgid="1904574852846769301">"اعلان‌ها توسط «مزاحم نشوید» موقتاً متوقف شدند"</string>
     <string name="media_projection_action_text" msgid="8470872969457985954">"اکنون شروع شود"</string>
     <string name="empty_shade_text" msgid="708135716272867002">"اعلانی موجود نیست"</string>
@@ -645,21 +642,16 @@
     <string name="inline_block_button" msgid="8735843688021655065">"مسدود کردن"</string>
     <string name="inline_keep_button" msgid="6665940297019018232">"همچنان نشان داده شود"</string>
     <string name="inline_minimize_button" msgid="966233327974702195">"کوچک کردن"</string>
-    <!-- no translation found for inline_silent_button_silent (5315879183296940969) -->
-    <skip />
+    <string name="inline_silent_button_silent" msgid="5315879183296940969">"بی‌صدا"</string>
     <string name="inline_silent_button_stay_silent" msgid="6308371431217601009">"بی‌صدا بماند"</string>
-    <!-- no translation found for inline_silent_button_alert (6008435419895088034) -->
-    <skip />
+    <string name="inline_silent_button_alert" msgid="6008435419895088034">"هشدار دادن"</string>
     <string name="inline_silent_button_keep_alerting" msgid="327696842264359693">"همچنان اطلاع داده شود"</string>
     <string name="inline_turn_off_notifications" msgid="8635596135532202355">"خاموش کردن اعلان‌ها"</string>
     <string name="inline_keep_showing_app" msgid="1723113469580031041">"نمایش اعلان از این برنامه ادامه یابد؟"</string>
-    <string name="notification_silence_title" msgid="7352089096356977930">"آرام"</string>
-    <string name="notification_alert_title" msgid="3966526305405016221">"دراولویت"</string>
-    <string name="notification_channel_summary_low" msgid="1065819618107531284">"با فقط نمایش اعلان در کشوی اعلان‌های پایین‌کش، به شما کمک می‌کند تمرکزتان را ازدست ندهید همیشه بی‌صدا."</string>
-    <string name="notification_channel_summary_low_status" msgid="2702170424808743755">"اعلان‌های با اولویت پایین را نشان می‌دهد. همیشه بی‌صدا."</string>
-    <string name="notification_channel_summary_low_lock" msgid="7966605244472624458">"اعلان‌های با اولویت پایین را نشان می‌دهد. همیشه بی‌صدا."</string>
-    <string name="notification_channel_summary_low_status_lock" msgid="7012562768950012739">"اعلان‌های با اولویت پایین را نشان می‌دهد. همیشه بی‌صدا."</string>
-    <string name="notification_channel_summary_default" msgid="3847289783382316019">"با صدا و نماد نوار وضعیت توجه شما را جلب می‌کند. در صفحه قفل نشان داده می‌شود."</string>
+    <string name="notification_silence_title" msgid="5763240612242137433">"بی‌صدا"</string>
+    <string name="notification_alert_title" msgid="8031196611815490340">"هشدار دادن"</string>
+    <string name="notification_channel_summary_low" msgid="3387466082089715555">"به شما کمک می‌کند بدون صدا یا لرزش تمرکز کنید."</string>
+    <string name="notification_channel_summary_default" msgid="5994062840431965586">"با صدا یا لرزش توجه شما را جلب می‌کند."</string>
     <string name="notification_unblockable_desc" msgid="4556908766584964102">"این اعلان‌ها قابل اصلاح نیستند."</string>
     <string name="notification_multichannel_desc" msgid="4695920306092240550">"نمی‌توانید این گروه اعلان‌ها را در اینجا پیکربندی کنید"</string>
     <string name="notification_delegate_header" msgid="2857691673814814270">"اعلان‌های دارای پراکسی"</string>
@@ -908,8 +900,7 @@
     <string name="slice_permission_allow" msgid="2340244901366722709">"مجاز"</string>
     <string name="slice_permission_deny" msgid="7683681514008048807">"رد کردن"</string>
     <string name="auto_saver_title" msgid="1217959994732964228">"برای زمان‌بندی «بهینه‌سازی باتری» ضربه بزنید"</string>
-    <!-- no translation found for auto_saver_text (2563289953551438248) -->
-    <skip />
+    <string name="auto_saver_text" msgid="2563289953551438248">"وقتی باتری روبه‌اتمام است، بهینه‌سازی باتری را روشن کنید"</string>
     <string name="no_auto_saver_action" msgid="8086002101711328500">"نه متشکرم"</string>
     <string name="auto_saver_enabled_title" msgid="6726474226058316862">"زمان‌بندی «بهینه‌سازی باتری» روشن شد"</string>
     <string name="auto_saver_enabled_text" msgid="874711029884777579">"وقتی شارژ باتری به زیر <xliff:g id="PERCENTAGE">%d</xliff:g>%% برسد، «بهینه‌سازی باتری» به‌طور خودکار روشن می‌شود."</string>
@@ -942,4 +933,6 @@
     <string name="bubble_accessibility_action_move_bottom_left" msgid="206369104473183217">"انتقال به پایین سمت راست"</string>
     <string name="bubble_accessibility_action_move_bottom_right" msgid="8705660152384312329">"انتقال به پایین سمت چپ"</string>
     <string name="bubble_dismiss_text" msgid="8028337712674081668">"رد کردن"</string>
+    <string name="notification_content_system_nav_changed" msgid="7218093915747788444">"پیمایش سیستم به‌روزرسانی شد. برای انجام تغییرات به «تنظیمات» بروید."</string>
+    <string name="notification_content_gesture_nav_available" msgid="8111130443656460792">"برای به‌روزرسانی پیمایش سیستم، به «تنظیمات» بروید"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-fi/strings.xml b/packages/SystemUI/res/values-fi/strings.xml
index 54d2d93..85a89ef 100644
--- a/packages/SystemUI/res/values-fi/strings.xml
+++ b/packages/SystemUI/res/values-fi/strings.xml
@@ -62,12 +62,10 @@
     <string name="usb_debugging_secondary_user_title" msgid="6353808721761220421">"USB-vianetsintää ei sallita"</string>
     <string name="usb_debugging_secondary_user_message" msgid="6067122453571699801">"Laitteelle tällä hetkellä kirjautunut käyttäjä ei voi ottaa USB-vianetsintää käyttöön. Vaihda käyttäjäksi ensisijainen käyttäjä, jotta voit käyttää tätä ominaisuutta."</string>
     <string name="usb_contaminant_title" msgid="206854874263058490">"USB-portti poistettu käytöstä"</string>
-    <!-- no translation found for usb_contaminant_message (7379089091591609111) -->
-    <skip />
+    <string name="usb_contaminant_message" msgid="7379089091591609111">"Laitteen suojaamiseksi nesteiltä ja lialta USB-portti on poistettu käytöstä, eikä se havaitse lisävarusteita.\n\nSaat ilmoituksen, kun USB-porttia voi taas käyttää."</string>
     <string name="usb_port_enabled" msgid="7906141351687694867">"USB-portti on käytössä ja voi havaita latureita sekä lisävarusteita"</string>
     <string name="usb_disable_contaminant_detection" msgid="2103905315747120033">"Ota USB käyttöön"</string>
-    <!-- no translation found for learn_more (5000517160980853569) -->
-    <skip />
+    <string name="learn_more" msgid="5000517160980853569">"Lue lisää"</string>
     <string name="compat_mode_on" msgid="6623839244840638213">"Zoomaa koko näyttöön"</string>
     <string name="compat_mode_off" msgid="4434467572461327898">"Venytä koko näyttöön"</string>
     <string name="global_action_screenshot" msgid="8329831278085426283">"Kuvakaappaus"</string>
@@ -199,6 +197,7 @@
     <string name="carrier_network_change_mode" msgid="8149202439957837762">"Operaattorin verkko muuttuu"</string>
     <string name="accessibility_battery_details" msgid="7645516654955025422">"Avaa akun tiedot."</string>
     <string name="accessibility_battery_level" msgid="7451474187113371965">"Akun virta <xliff:g id="NUMBER">%d</xliff:g> prosenttia."</string>
+    <string name="accessibility_battery_level_with_estimate" msgid="9033100930684311630">"Akkua jäljellä <xliff:g id="PERCENTAGE">%1$s</xliff:g> % eli noin <xliff:g id="TIME">%2$s</xliff:g> käyttösi perusteella"</string>
     <string name="accessibility_battery_level_charging" msgid="1147587904439319646">"Akku latautuu: <xliff:g id="BATTERY_PERCENTAGE">%d</xliff:g> prosenttia"</string>
     <string name="accessibility_settings_button" msgid="799583911231893380">"Järjestelmän asetukset"</string>
     <string name="accessibility_notifications_button" msgid="4498000369779421892">"Ilmoitukset"</string>
@@ -458,10 +457,8 @@
     <string name="media_projection_remember_text" msgid="3103510882172746752">"Älä näytä uudelleen"</string>
     <string name="clear_all_notifications_text" msgid="814192889771462828">"Poista kaikki"</string>
     <string name="manage_notifications_text" msgid="2386728145475108753">"Muuta asetuksia"</string>
-    <!-- no translation found for notification_section_header_gentle (4372438504154095677) -->
-    <skip />
-    <!-- no translation found for accessibility_notification_section_header_gentle_clear_all (4286716295850400959) -->
-    <skip />
+    <string name="notification_section_header_gentle" msgid="4372438504154095677">"Hiljaiset ilmoitukset"</string>
+    <string name="accessibility_notification_section_header_gentle_clear_all" msgid="4286716295850400959">"Tyhjennä kaikki hiljaiset ilmoitukset"</string>
     <string name="dnd_suppressing_shade_text" msgid="1904574852846769301">"Älä häiritse ‑tila keskeytti ilmoitukset"</string>
     <string name="media_projection_action_text" msgid="8470872969457985954">"Aloita nyt"</string>
     <string name="empty_shade_text" msgid="708135716272867002">"Ei ilmoituksia"</string>
@@ -645,21 +642,16 @@
     <string name="inline_block_button" msgid="8735843688021655065">"Estä"</string>
     <string name="inline_keep_button" msgid="6665940297019018232">"Jatka näyttämistä"</string>
     <string name="inline_minimize_button" msgid="966233327974702195">"Pienennä"</string>
-    <!-- no translation found for inline_silent_button_silent (5315879183296940969) -->
-    <skip />
+    <string name="inline_silent_button_silent" msgid="5315879183296940969">"Äänetön"</string>
     <string name="inline_silent_button_stay_silent" msgid="6308371431217601009">"Jatka äänettömyyttä"</string>
-    <!-- no translation found for inline_silent_button_alert (6008435419895088034) -->
-    <skip />
+    <string name="inline_silent_button_alert" msgid="6008435419895088034">"Hälyttää"</string>
     <string name="inline_silent_button_keep_alerting" msgid="327696842264359693">"Jatka ilmoituksista hälyttämistä"</string>
     <string name="inline_turn_off_notifications" msgid="8635596135532202355">"Poista ilmoitukset käytöstä"</string>
     <string name="inline_keep_showing_app" msgid="1723113469580031041">"Jatketaanko ilmoitusten näyttämistä tästä sovelluksesta?"</string>
-    <string name="notification_silence_title" msgid="7352089096356977930">"Varovainen"</string>
-    <string name="notification_alert_title" msgid="3966526305405016221">"Priorisoitu"</string>
-    <string name="notification_channel_summary_low" msgid="1065819618107531284">"Keskittyminen on helpompaa, sillä ilmoitukset näkyvät vain alas vedettävällä alueella. Aina äänetön."</string>
-    <string name="notification_channel_summary_low_status" msgid="2702170424808743755">"Näytetään priorisoitujen ilmoitusten alapuolella. Aina äänetön."</string>
-    <string name="notification_channel_summary_low_lock" msgid="7966605244472624458">"Näytetään priorisoitujen ilmoitusten alapuolella. Aina äänetön."</string>
-    <string name="notification_channel_summary_low_status_lock" msgid="7012562768950012739">"Näytetään priorisoitujen ilmoitusten alapuolella. Aina äänetön."</string>
-    <string name="notification_channel_summary_default" msgid="3847289783382316019">"Kiinnittää huomion äänellä ja tilapalkin kuvakkeella. Näkyy lukitusnäytöllä."</string>
+    <string name="notification_silence_title" msgid="5763240612242137433">"Äänetön"</string>
+    <string name="notification_alert_title" msgid="8031196611815490340">"Hälyttää"</string>
+    <string name="notification_channel_summary_low" msgid="3387466082089715555">"Keskittyminen on helpompaa ilman ääntä tai värinää."</string>
+    <string name="notification_channel_summary_default" msgid="5994062840431965586">"Kiinnittää huomion ilman ääntä tai värinää."</string>
     <string name="notification_unblockable_desc" msgid="4556908766584964102">"Näitä ilmoituksia ei voi muokata"</string>
     <string name="notification_multichannel_desc" msgid="4695920306092240550">"Tätä ilmoitusryhmää ei voi määrittää tässä"</string>
     <string name="notification_delegate_header" msgid="2857691673814814270">"Välitetty ilmoitus"</string>
@@ -908,8 +900,7 @@
     <string name="slice_permission_allow" msgid="2340244901366722709">"Salli"</string>
     <string name="slice_permission_deny" msgid="7683681514008048807">"Estä"</string>
     <string name="auto_saver_title" msgid="1217959994732964228">"Ajoita virransäästö napauttamalla"</string>
-    <!-- no translation found for auto_saver_text (2563289953551438248) -->
-    <skip />
+    <string name="auto_saver_text" msgid="2563289953551438248">"Ota käyttöön, jos akku todennäköisesti loppuu"</string>
     <string name="no_auto_saver_action" msgid="8086002101711328500">"Ei kiitos"</string>
     <string name="auto_saver_enabled_title" msgid="6726474226058316862">"Virransäästön ajoitus otettu käyttöön"</string>
     <string name="auto_saver_enabled_text" msgid="874711029884777579">"Virransäästö käynnistyy automaattisesti, kun akun lataustaso on alle <xliff:g id="PERCENTAGE">%d</xliff:g> %%."</string>
@@ -942,4 +933,6 @@
     <string name="bubble_accessibility_action_move_bottom_left" msgid="206369104473183217">"Siirrä vasempaan alareunaan"</string>
     <string name="bubble_accessibility_action_move_bottom_right" msgid="8705660152384312329">"Siirrä oikeaan alareunaan"</string>
     <string name="bubble_dismiss_text" msgid="8028337712674081668">"Ohita"</string>
+    <string name="notification_content_system_nav_changed" msgid="7218093915747788444">"Järjestelmän navigointitapa vaihdettu. Voit muuttaa sitä asetuksista."</string>
+    <string name="notification_content_gesture_nav_available" msgid="8111130443656460792">"Vaihda järjestelmän navigointitapaa asetuksista"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-fr-rCA/strings.xml b/packages/SystemUI/res/values-fr-rCA/strings.xml
index a904d30..ae288c9 100644
--- a/packages/SystemUI/res/values-fr-rCA/strings.xml
+++ b/packages/SystemUI/res/values-fr-rCA/strings.xml
@@ -62,12 +62,10 @@
     <string name="usb_debugging_secondary_user_title" msgid="6353808721761220421">"Débogage USB non autorisé"</string>
     <string name="usb_debugging_secondary_user_message" msgid="6067122453571699801">"L\'utilisateur actuellement connecté sur cet appareil ne peut pas activer le débogage USB. Pour utiliser cette fonctionnalité, l\'utilisateur principal doit se connecter."</string>
     <string name="usb_contaminant_title" msgid="206854874263058490">"Le port USB a été désactivé"</string>
-    <!-- no translation found for usb_contaminant_message (7379089091591609111) -->
-    <skip />
+    <string name="usb_contaminant_message" msgid="7379089091591609111">"Pour protéger votre appareil des liquides et des débris, le port USB est désactivé et ne pourra pas détecter les accessoires.\n\nVous verrez une notification lorsque vous pourrez utiliser le port USB à nouveau."</string>
     <string name="usb_port_enabled" msgid="7906141351687694867">"Le port USB a été activé afin de détecté les chargeurs et les accessoires"</string>
     <string name="usb_disable_contaminant_detection" msgid="2103905315747120033">"Activer l\'USB"</string>
-    <!-- no translation found for learn_more (5000517160980853569) -->
-    <skip />
+    <string name="learn_more" msgid="5000517160980853569">"En savoir plus"</string>
     <string name="compat_mode_on" msgid="6623839244840638213">"Zoomer pour remplir l\'écran"</string>
     <string name="compat_mode_off" msgid="4434467572461327898">"Étirer pour remplir l\'écran"</string>
     <string name="global_action_screenshot" msgid="8329831278085426283">"Capture d\'écran"</string>
@@ -199,6 +197,7 @@
     <string name="carrier_network_change_mode" msgid="8149202439957837762">"Changer de réseau de fournisseur de services"</string>
     <string name="accessibility_battery_details" msgid="7645516654955025422">"Ouvrir les détails de la pile"</string>
     <string name="accessibility_battery_level" msgid="7451474187113371965">"Pile : <xliff:g id="NUMBER">%d</xliff:g> pour cent"</string>
+    <string name="accessibility_battery_level_with_estimate" msgid="9033100930684311630">"Pile chargée à <xliff:g id="PERCENTAGE">%1$s</xliff:g> % (environ <xliff:g id="TIME">%2$s</xliff:g> d\'autonomie en fonction de votre usage)"</string>
     <string name="accessibility_battery_level_charging" msgid="1147587904439319646">"La pile est en cours de charge : <xliff:g id="BATTERY_PERCENTAGE">%d</xliff:g> %%."</string>
     <string name="accessibility_settings_button" msgid="799583911231893380">"Paramètres système"</string>
     <string name="accessibility_notifications_button" msgid="4498000369779421892">"Notifications"</string>
@@ -458,10 +457,8 @@
     <string name="media_projection_remember_text" msgid="3103510882172746752">"Ne plus afficher"</string>
     <string name="clear_all_notifications_text" msgid="814192889771462828">"Tout effacer"</string>
     <string name="manage_notifications_text" msgid="2386728145475108753">"Gérer"</string>
-    <!-- no translation found for notification_section_header_gentle (4372438504154095677) -->
-    <skip />
-    <!-- no translation found for accessibility_notification_section_header_gentle_clear_all (4286716295850400959) -->
-    <skip />
+    <string name="notification_section_header_gentle" msgid="4372438504154095677">"Notifications silencieuses"</string>
+    <string name="accessibility_notification_section_header_gentle_clear_all" msgid="4286716295850400959">"Effacer toutes les notifications silencieuses"</string>
     <string name="dnd_suppressing_shade_text" msgid="1904574852846769301">"Les notifications sont suspendues par le mode Ne pas déranger"</string>
     <string name="media_projection_action_text" msgid="8470872969457985954">"Commencer"</string>
     <string name="empty_shade_text" msgid="708135716272867002">"Aucune notification"</string>
@@ -645,21 +642,16 @@
     <string name="inline_block_button" msgid="8735843688021655065">"Bloquer"</string>
     <string name="inline_keep_button" msgid="6665940297019018232">"Continuer à afficher"</string>
     <string name="inline_minimize_button" msgid="966233327974702195">"Réduire"</string>
-    <!-- no translation found for inline_silent_button_silent (5315879183296940969) -->
-    <skip />
+    <string name="inline_silent_button_silent" msgid="5315879183296940969">"Mode silencieux"</string>
     <string name="inline_silent_button_stay_silent" msgid="6308371431217601009">"Continuer d\'util. mode silencieux"</string>
-    <!-- no translation found for inline_silent_button_alert (6008435419895088034) -->
-    <skip />
+    <string name="inline_silent_button_alert" msgid="6008435419895088034">"Alertes"</string>
     <string name="inline_silent_button_keep_alerting" msgid="327696842264359693">"Continuer d\'envoyer des alertes"</string>
     <string name="inline_turn_off_notifications" msgid="8635596135532202355">"Désactiver les notifications"</string>
     <string name="inline_keep_showing_app" msgid="1723113469580031041">"Continuer à afficher les notifications de cette application?"</string>
-    <string name="notification_silence_title" msgid="7352089096356977930">"Discrètes"</string>
-    <string name="notification_alert_title" msgid="3966526305405016221">"Priorisées"</string>
-    <string name="notification_channel_summary_low" msgid="1065819618107531284">"Vous aide à vous concentrer en affichant seulement les notifications dans le volet déroulant. Toujours silencieux."</string>
-    <string name="notification_channel_summary_low_status" msgid="2702170424808743755">"S\'affiche sous les notifications prioritaires. Toujours silencieux."</string>
-    <string name="notification_channel_summary_low_lock" msgid="7966605244472624458">"S\'affiche sous les notifications prioritaires. Toujours silencieux."</string>
-    <string name="notification_channel_summary_low_status_lock" msgid="7012562768950012739">"S\'affiche sous les notifications prioritaires. Toujours silencieux."</string>
-    <string name="notification_channel_summary_default" msgid="3847289783382316019">"Attire votre attention à l\'aide de sons et d\'une icône dans la barre d\'état. S\'affiche sur l\'écran de verrouillage."</string>
+    <string name="notification_silence_title" msgid="5763240612242137433">"Mode silencieux"</string>
+    <string name="notification_alert_title" msgid="8031196611815490340">"Alertes"</string>
+    <string name="notification_channel_summary_low" msgid="3387466082089715555">"Vous aider à vous concentrer, sans son ni vibration."</string>
+    <string name="notification_channel_summary_default" msgid="5994062840431965586">"Attire votre attention à l\'aide de sons et de vibrations."</string>
     <string name="notification_unblockable_desc" msgid="4556908766584964102">"Ces notifications ne peuvent pas être modifiées"</string>
     <string name="notification_multichannel_desc" msgid="4695920306092240550">"Ce groupe de notifications ne peut pas être configuré ici"</string>
     <string name="notification_delegate_header" msgid="2857691673814814270">"Notification par mandataire"</string>
@@ -908,8 +900,7 @@
     <string name="slice_permission_allow" msgid="2340244901366722709">"Autoriser"</string>
     <string name="slice_permission_deny" msgid="7683681514008048807">"Refuser"</string>
     <string name="auto_saver_title" msgid="1217959994732964228">"Toucher pour activer la fonction Économie d\'énergie"</string>
-    <!-- no translation found for auto_saver_text (2563289953551438248) -->
-    <skip />
+    <string name="auto_saver_text" msgid="2563289953551438248">"Activer si la pile est susceptible de s\'épuiser totalement"</string>
     <string name="no_auto_saver_action" msgid="8086002101711328500">"Non merci"</string>
     <string name="auto_saver_enabled_title" msgid="6726474226058316862">"La fonction Économie d\'énergie est activée"</string>
     <string name="auto_saver_enabled_text" msgid="874711029884777579">"La fonction Économie d\'énergie s\'activera automatiquement une fois que la pile sera en dessous de <xliff:g id="PERCENTAGE">%d</xliff:g> %%."</string>
@@ -942,4 +933,6 @@
     <string name="bubble_accessibility_action_move_bottom_left" msgid="206369104473183217">"Déplacer dans coin inf. gauche"</string>
     <string name="bubble_accessibility_action_move_bottom_right" msgid="8705660152384312329">"Déplacer dans coin inf. droit"</string>
     <string name="bubble_dismiss_text" msgid="8028337712674081668">"Fermer"</string>
+    <string name="notification_content_system_nav_changed" msgid="7218093915747788444">"La navigation système a été mise à jour. Pour apporter des modifications, accédez au menu Paramètres."</string>
+    <string name="notification_content_gesture_nav_available" msgid="8111130443656460792">"Accédez au menu Paramètres pour mettre à jour la navigation système"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-fr/strings.xml b/packages/SystemUI/res/values-fr/strings.xml
index 23f601c..4aedbcd 100644
--- a/packages/SystemUI/res/values-fr/strings.xml
+++ b/packages/SystemUI/res/values-fr/strings.xml
@@ -62,12 +62,10 @@
     <string name="usb_debugging_secondary_user_title" msgid="6353808721761220421">"Débogage USB non autorisé"</string>
     <string name="usb_debugging_secondary_user_message" msgid="6067122453571699801">"L\'utilisateur actuellement connecté sur cet appareil ne peut pas activer le débogage USB. Pour utiliser cette fonctionnalité, l\'utilisateur principal doit se connecter."</string>
     <string name="usb_contaminant_title" msgid="206854874263058490">"Port USB désactivé"</string>
-    <!-- no translation found for usb_contaminant_message (7379089091591609111) -->
-    <skip />
+    <string name="usb_contaminant_message" msgid="7379089091591609111">"Pour protéger votre appareil des liquides et des saletés, le port USB est désactivé et ne détecte plus les accessoires.\n\nVous recevrez une notification lorsque vous pourrez de nouveau utiliser le port USB."</string>
     <string name="usb_port_enabled" msgid="7906141351687694867">"Port USB activé pour détecter les chargeurs et les accessoires"</string>
     <string name="usb_disable_contaminant_detection" msgid="2103905315747120033">"Activer le port USB"</string>
-    <!-- no translation found for learn_more (5000517160980853569) -->
-    <skip />
+    <string name="learn_more" msgid="5000517160980853569">"En savoir plus"</string>
     <string name="compat_mode_on" msgid="6623839244840638213">"Zoomer pour remplir l\'écran"</string>
     <string name="compat_mode_off" msgid="4434467572461327898">"Étirer pour remplir l\'écran"</string>
     <string name="global_action_screenshot" msgid="8329831278085426283">"Capture"</string>
@@ -199,6 +197,7 @@
     <string name="carrier_network_change_mode" msgid="8149202439957837762">"Modification du réseau de l\'opérateur"</string>
     <string name="accessibility_battery_details" msgid="7645516654955025422">"Ouvrir les détails de la batterie"</string>
     <string name="accessibility_battery_level" msgid="7451474187113371965">"Batterie : <xliff:g id="NUMBER">%d</xliff:g> pour cent"</string>
+    <string name="accessibility_battery_level_with_estimate" msgid="9033100930684311630">"<xliff:g id="PERCENTAGE">%1$s</xliff:g> pour cent de batterie : il reste environ <xliff:g id="TIME">%2$s</xliff:g>, en fonction de votre utilisation"</string>
     <string name="accessibility_battery_level_charging" msgid="1147587904439319646">"Batterie en charge : <xliff:g id="BATTERY_PERCENTAGE">%d</xliff:g> %%."</string>
     <string name="accessibility_settings_button" msgid="799583911231893380">"Paramètres système"</string>
     <string name="accessibility_notifications_button" msgid="4498000369779421892">"Notifications"</string>
@@ -376,7 +375,7 @@
     <string name="quick_settings_night_secondary_label_until_sunrise" msgid="4453017157391574402">"Jusqu\'à l\'aube"</string>
     <string name="quick_settings_night_secondary_label_on_at" msgid="6256314040368487637">"À partir de <xliff:g id="TIME">%s</xliff:g>"</string>
     <string name="quick_settings_secondary_label_until" msgid="2749196569462600150">"Jusqu\'à <xliff:g id="TIME">%s</xliff:g>"</string>
-    <string name="quick_settings_ui_mode_night_label" msgid="512534812963862137">"Thème foncé"</string>
+    <string name="quick_settings_ui_mode_night_label" msgid="512534812963862137">"Mode sombre"</string>
     <string name="quick_settings_ui_mode_night_label_battery_saver" msgid="3496696903886673256">"Thème foncé\nÉconomiseur de batterie"</string>
     <string name="quick_settings_nfc_label" msgid="9012153754816969325">"NFC"</string>
     <string name="quick_settings_nfc_off" msgid="6883274004315134333">"La technologie NFC est désactivée"</string>
@@ -458,10 +457,8 @@
     <string name="media_projection_remember_text" msgid="3103510882172746752">"Ne plus afficher"</string>
     <string name="clear_all_notifications_text" msgid="814192889771462828">"Tout effacer"</string>
     <string name="manage_notifications_text" msgid="2386728145475108753">"Gérer"</string>
-    <!-- no translation found for notification_section_header_gentle (4372438504154095677) -->
-    <skip />
-    <!-- no translation found for accessibility_notification_section_header_gentle_clear_all (4286716295850400959) -->
-    <skip />
+    <string name="notification_section_header_gentle" msgid="4372438504154095677">"Notifications silencieuses"</string>
+    <string name="accessibility_notification_section_header_gentle_clear_all" msgid="4286716295850400959">"Effacer toutes les notifications silencieuses"</string>
     <string name="dnd_suppressing_shade_text" msgid="1904574852846769301">"Notifications suspendues par le mode Ne pas déranger"</string>
     <string name="media_projection_action_text" msgid="8470872969457985954">"Commencer"</string>
     <string name="empty_shade_text" msgid="708135716272867002">"Aucune notification"</string>
@@ -645,21 +642,16 @@
     <string name="inline_block_button" msgid="8735843688021655065">"Bloquer"</string>
     <string name="inline_keep_button" msgid="6665940297019018232">"Continuer d\'afficher les notifications"</string>
     <string name="inline_minimize_button" msgid="966233327974702195">"Réduire"</string>
-    <!-- no translation found for inline_silent_button_silent (5315879183296940969) -->
-    <skip />
+    <string name="inline_silent_button_silent" msgid="5315879183296940969">"Mode silencieux"</string>
     <string name="inline_silent_button_stay_silent" msgid="6308371431217601009">"Notifications silencieuses"</string>
-    <!-- no translation found for inline_silent_button_alert (6008435419895088034) -->
-    <skip />
+    <string name="inline_silent_button_alert" msgid="6008435419895088034">"Alertes"</string>
     <string name="inline_silent_button_keep_alerting" msgid="327696842264359693">"Continuer de m\'avertir"</string>
     <string name="inline_turn_off_notifications" msgid="8635596135532202355">"Désactiver les notifications"</string>
     <string name="inline_keep_showing_app" msgid="1723113469580031041">"Continuer d\'afficher les notifications de cette application ?"</string>
-    <string name="notification_silence_title" msgid="7352089096356977930">"Discret"</string>
-    <string name="notification_alert_title" msgid="3966526305405016221">"Prioritaire"</string>
-    <string name="notification_channel_summary_low" msgid="1065819618107531284">"Vous aide à vous concentrer en affichant les notifications seulement dans le volet déroulant. Toujours silencieux."</string>
-    <string name="notification_channel_summary_low_status" msgid="2702170424808743755">"S\'affiche sous les notifications prioritaires. Toujours silencieux."</string>
-    <string name="notification_channel_summary_low_lock" msgid="7966605244472624458">"S\'affiche sous les notifications prioritaires. Toujours silencieux."</string>
-    <string name="notification_channel_summary_low_status_lock" msgid="7012562768950012739">"S\'affiche sous les notifications prioritaires. Toujours silencieux."</string>
-    <string name="notification_channel_summary_default" msgid="3847289783382316019">"Attire votre attention à l\'aide d\'un son et d\'une icône dans la barre d\'état. S\'affiche sur l\'écran de verrouillage."</string>
+    <string name="notification_silence_title" msgid="5763240612242137433">"Silencieux"</string>
+    <string name="notification_alert_title" msgid="8031196611815490340">"Alertes"</string>
+    <string name="notification_channel_summary_low" msgid="3387466082089715555">"Sans sons ni vibrations, vous aide à vous concentrer."</string>
+    <string name="notification_channel_summary_default" msgid="5994062840431965586">"Attire votre attention à l\'aide de sons ou de vibrations."</string>
     <string name="notification_unblockable_desc" msgid="4556908766584964102">"Impossible de modifier ces notifications."</string>
     <string name="notification_multichannel_desc" msgid="4695920306092240550">"Vous ne pouvez pas configurer ce groupe de notifications ici"</string>
     <string name="notification_delegate_header" msgid="2857691673814814270">"Notification de proxy"</string>
@@ -908,8 +900,7 @@
     <string name="slice_permission_allow" msgid="2340244901366722709">"Autoriser"</string>
     <string name="slice_permission_deny" msgid="7683681514008048807">"Refuser"</string>
     <string name="auto_saver_title" msgid="1217959994732964228">"Appuyez ici pour programmer l\'économiseur de batterie"</string>
-    <!-- no translation found for auto_saver_text (2563289953551438248) -->
-    <skip />
+    <string name="auto_saver_text" msgid="2563289953551438248">"Activer l\'économiseur de batterie si l\'autonomie restante risque d\'être insuffisante"</string>
     <string name="no_auto_saver_action" msgid="8086002101711328500">"Non, merci"</string>
     <string name="auto_saver_enabled_title" msgid="6726474226058316862">"Programmation de l\'économiseur de batterie activée"</string>
     <string name="auto_saver_enabled_text" msgid="874711029884777579">"L\'économiseur de batterie s\'active automatiquement lorsque l\'autonomie de la batterie est inférieure à <xliff:g id="PERCENTAGE">%d</xliff:g> %%."</string>
@@ -942,4 +933,6 @@
     <string name="bubble_accessibility_action_move_bottom_left" msgid="206369104473183217">"Déplacer en bas à gauche"</string>
     <string name="bubble_accessibility_action_move_bottom_right" msgid="8705660152384312329">"Déplacer en bas à droite"</string>
     <string name="bubble_dismiss_text" msgid="8028337712674081668">"Ignorer"</string>
+    <string name="notification_content_system_nav_changed" msgid="7218093915747788444">"Navigation système mise à jour. Pour apporter des modifications, accédez aux paramètres."</string>
+    <string name="notification_content_gesture_nav_available" msgid="8111130443656460792">"Accédez aux paramètres pour mettre à jour la navigation système"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-gl/strings.xml b/packages/SystemUI/res/values-gl/strings.xml
index fcb82e6..9bbb170 100644
--- a/packages/SystemUI/res/values-gl/strings.xml
+++ b/packages/SystemUI/res/values-gl/strings.xml
@@ -62,12 +62,10 @@
     <string name="usb_debugging_secondary_user_title" msgid="6353808721761220421">"Non se permite a depuración por USB"</string>
     <string name="usb_debugging_secondary_user_message" msgid="6067122453571699801">"O usuario coa sesión iniciada actualmente neste dispositivo non pode activar a depuración por USB. Para utilizar esta función, cambia ao usuario principal."</string>
     <string name="usb_contaminant_title" msgid="206854874263058490">"O porto USB está desactivado"</string>
-    <!-- no translation found for usb_contaminant_message (7379089091591609111) -->
-    <skip />
+    <string name="usb_contaminant_message" msgid="7379089091591609111">"Para protexer o dispositivo de líquidos ou residuos, desactivouse o porto USB e non detectará ningún accesorio.\n\nRecibirás unha notificación cando o poidas utilizar de novo."</string>
     <string name="usb_port_enabled" msgid="7906141351687694867">"Activouse o porto USB para detectar cargadores e accesorios"</string>
     <string name="usb_disable_contaminant_detection" msgid="2103905315747120033">"Activar USB"</string>
-    <!-- no translation found for learn_more (5000517160980853569) -->
-    <skip />
+    <string name="learn_more" msgid="5000517160980853569">"Máis información"</string>
     <string name="compat_mode_on" msgid="6623839244840638213">"Ampliar ata ocupar todo"</string>
     <string name="compat_mode_off" msgid="4434467572461327898">"Estirar ata ocupar todo"</string>
     <string name="global_action_screenshot" msgid="8329831278085426283">"Capt. pantalla"</string>
@@ -199,6 +197,7 @@
     <string name="carrier_network_change_mode" msgid="8149202439957837762">"Cambio de rede do operador"</string>
     <string name="accessibility_battery_details" msgid="7645516654955025422">"Abrir os detalles da batería"</string>
     <string name="accessibility_battery_level" msgid="7451474187113371965">"Carga da batería: <xliff:g id="NUMBER">%d</xliff:g> por cento."</string>
+    <string name="accessibility_battery_level_with_estimate" msgid="9033100930684311630">"Batería: <xliff:g id="PERCENTAGE">%1$s</xliff:g> %, durará <xliff:g id="TIME">%2$s</xliff:g> co uso que adoitas darlle"</string>
     <string name="accessibility_battery_level_charging" msgid="1147587904439319646">"A batería está cargando. Nivel: <xliff:g id="BATTERY_PERCENTAGE">%d</xliff:g> %%."</string>
     <string name="accessibility_settings_button" msgid="799583911231893380">"Configuración do sistema"</string>
     <string name="accessibility_notifications_button" msgid="4498000369779421892">"Notificacións"</string>
@@ -214,7 +213,7 @@
     <!-- no translation found for accessibility_work_mode (702887484664647430) -->
     <skip />
     <string name="accessibility_notification_dismissed" msgid="854211387186306927">"Notificación rexeitada"</string>
-    <string name="accessibility_desc_notification_shade" msgid="4690274844447504208">"Sombra de notificación"</string>
+    <string name="accessibility_desc_notification_shade" msgid="4690274844447504208">"Panel despregable"</string>
     <string name="accessibility_desc_quick_settings" msgid="6186378411582437046">"Configuración rápida"</string>
     <string name="accessibility_desc_lock_screen" msgid="5625143713611759164">"Pantalla de bloqueo."</string>
     <string name="accessibility_desc_settings" msgid="3417884241751434521">"Configuración"</string>
@@ -391,7 +390,7 @@
     <string name="ssl_ca_cert_warning" msgid="9005954106902053641">"É posible que se\nsupervise a rede"</string>
     <string name="description_target_search" msgid="3091587249776033139">"Buscar"</string>
     <string name="description_direction_up" msgid="7169032478259485180">"Pasa o dedo cara arriba para <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
-    <string name="description_direction_left" msgid="7207478719805562165">"Pasa o dedo cara a esquerda para <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
+    <string name="description_direction_left" msgid="7207478719805562165">"Pasa o dedo cara á esquerda para <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
     <string name="zen_priority_introduction" msgid="1149025108714420281">"Non te molestará ningún son nin vibración, agás os procedentes de alarmas, recordatorios, eventos e os emisores de chamada especificados. Seguirás escoitando todo aquilo que decidas reproducir, mesmo a música, os vídeos e os xogos."</string>
     <string name="zen_alarms_introduction" msgid="4934328096749380201">"Non te molestará ningún son nin vibración, agás os procedentes de alarmas. Seguirás escoitando todo aquilo que decidas reproducir, mesmo a música, os vídeos e os xogos."</string>
     <string name="zen_priority_customize_button" msgid="7948043278226955063">"Personalizar"</string>
@@ -458,10 +457,8 @@
     <string name="media_projection_remember_text" msgid="3103510882172746752">"Non mostrar outra vez"</string>
     <string name="clear_all_notifications_text" msgid="814192889771462828">"Eliminar todas"</string>
     <string name="manage_notifications_text" msgid="2386728145475108753">"Xestionar"</string>
-    <!-- no translation found for notification_section_header_gentle (4372438504154095677) -->
-    <skip />
-    <!-- no translation found for accessibility_notification_section_header_gentle_clear_all (4286716295850400959) -->
-    <skip />
+    <string name="notification_section_header_gentle" msgid="4372438504154095677">"Notificacións silenciadas"</string>
+    <string name="accessibility_notification_section_header_gentle_clear_all" msgid="4286716295850400959">"Borra todas as notificacións silenciadas"</string>
     <string name="dnd_suppressing_shade_text" msgid="1904574852846769301">"O modo Non molestar puxo en pausa as notificacións"</string>
     <string name="media_projection_action_text" msgid="8470872969457985954">"Iniciar agora"</string>
     <string name="empty_shade_text" msgid="708135716272867002">"Non hai notificacións"</string>
@@ -645,21 +642,16 @@
     <string name="inline_block_button" msgid="8735843688021655065">"Bloquear"</string>
     <string name="inline_keep_button" msgid="6665940297019018232">"Continuar mostrando notificacións"</string>
     <string name="inline_minimize_button" msgid="966233327974702195">"Minimizar"</string>
-    <!-- no translation found for inline_silent_button_silent (5315879183296940969) -->
-    <skip />
+    <string name="inline_silent_button_silent" msgid="5315879183296940969">"Silencio"</string>
     <string name="inline_silent_button_stay_silent" msgid="6308371431217601009">"Notificacións silenciosas"</string>
-    <!-- no translation found for inline_silent_button_alert (6008435419895088034) -->
-    <skip />
+    <string name="inline_silent_button_alert" msgid="6008435419895088034">"Alertando"</string>
     <string name="inline_silent_button_keep_alerting" msgid="327696842264359693">"Continuar recibindo notificacións"</string>
     <string name="inline_turn_off_notifications" msgid="8635596135532202355">"Desactivar notificacións"</string>
     <string name="inline_keep_showing_app" msgid="1723113469580031041">"Queres seguir mostrando as notificacións desta aplicación?"</string>
-    <string name="notification_silence_title" msgid="7352089096356977930">"Discretas"</string>
-    <string name="notification_alert_title" msgid="3966526305405016221">"Prioritarias"</string>
-    <string name="notification_channel_summary_low" msgid="1065819618107531284">"Permíteche centrarte con notificacións só no panel despregable. Sempre en silencio."</string>
-    <string name="notification_channel_summary_low_status" msgid="2702170424808743755">"Mostra as notificacións con prioridade baixa. Sempre en silencio."</string>
-    <string name="notification_channel_summary_low_lock" msgid="7966605244472624458">"Mostra as notificacións con prioridade baixa. Sempre en silencio."</string>
-    <string name="notification_channel_summary_low_status_lock" msgid="7012562768950012739">"Mostra as notificacións con prioridade baixa. Sempre en silencio."</string>
-    <string name="notification_channel_summary_default" msgid="3847289783382316019">"Chama a túa atención cun son e cunha icona na barra de estado. Móstrase na pantalla de bloqueo."</string>
+    <string name="notification_silence_title" msgid="5763240612242137433">"Silenciosas"</string>
+    <string name="notification_alert_title" msgid="8031196611815490340">"Con alertas"</string>
+    <string name="notification_channel_summary_low" msgid="3387466082089715555">"Axúdache a centrarte sen son nin vibración."</string>
+    <string name="notification_channel_summary_default" msgid="5994062840431965586">"Chama a túa atención con son ou vibración."</string>
     <string name="notification_unblockable_desc" msgid="4556908766584964102">"Estas notificacións non se poden modificar."</string>
     <string name="notification_multichannel_desc" msgid="4695920306092240550">"Aquí non se pode configurar este grupo de notificacións"</string>
     <string name="notification_delegate_header" msgid="2857691673814814270">"Notificación mediante proxy"</string>
@@ -908,8 +900,7 @@
     <string name="slice_permission_allow" msgid="2340244901366722709">"Permitir"</string>
     <string name="slice_permission_deny" msgid="7683681514008048807">"Denegar"</string>
     <string name="auto_saver_title" msgid="1217959994732964228">"Tocar para programar a función Aforro de batería"</string>
-    <!-- no translation found for auto_saver_text (2563289953551438248) -->
-    <skip />
+    <string name="auto_saver_text" msgid="2563289953551438248">"Activa a función se prevés que a batería pode esgotarse"</string>
     <string name="no_auto_saver_action" msgid="8086002101711328500">"Non, grazas"</string>
     <string name="auto_saver_enabled_title" msgid="6726474226058316862">"Activouse o programa da función Aforro de batería"</string>
     <string name="auto_saver_enabled_text" msgid="874711029884777579">"Activarase automaticamente a función Aforro de batería en canto o nivel de carga sexa inferior ao <xliff:g id="PERCENTAGE">%d</xliff:g> %%."</string>
@@ -942,4 +933,6 @@
     <string name="bubble_accessibility_action_move_bottom_left" msgid="206369104473183217">"Mover á parte infer. esquerda"</string>
     <string name="bubble_accessibility_action_move_bottom_right" msgid="8705660152384312329">"Mover á parte inferior dereita"</string>
     <string name="bubble_dismiss_text" msgid="8028337712674081668">"Ignorar"</string>
+    <string name="notification_content_system_nav_changed" msgid="7218093915747788444">"Actualizouse a navegación do sistema. Para facer cambios, vai a Configuración."</string>
+    <string name="notification_content_gesture_nav_available" msgid="8111130443656460792">"Para actualizar a navegación do sistema, vai a Configuración"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-gu/strings.xml b/packages/SystemUI/res/values-gu/strings.xml
index 7b2c6d3..2319ad8 100644
--- a/packages/SystemUI/res/values-gu/strings.xml
+++ b/packages/SystemUI/res/values-gu/strings.xml
@@ -62,12 +62,10 @@
     <string name="usb_debugging_secondary_user_title" msgid="6353808721761220421">"USB ડીબગિંગની મંજૂરી નથી"</string>
     <string name="usb_debugging_secondary_user_message" msgid="6067122453571699801">"હાલમાં આ ઉપકરણમાં સાઇન ઇન થયેલ વપરાશકર્તા USB ડિબગીંગ ચાલુ કરી શકતા નથી. આ સુવિધાનો ઉપયોગ કરવા માટે પ્રાથમિક વપરાશકર્તા પર સ્વિચ કરો."</string>
     <string name="usb_contaminant_title" msgid="206854874263058490">"USB પોર્ટ બંધ કરવામાં આવ્યો છે"</string>
-    <!-- no translation found for usb_contaminant_message (7379089091591609111) -->
-    <skip />
+    <string name="usb_contaminant_message" msgid="7379089091591609111">"પ્રવાહી અથવા ધૂળથી તમારા ડિવાઇસનું રક્ષણ કરવા માટે, USB પોર્ટ બંધ કરવામાં આવ્યો છે અને કોઈ ઍક્સેસરી શોધશે નહીં.\n\nજ્યારે ફરીથી USB પોર્ટને ઉપયોગમાં લેવાનું સુરક્ષિત હશે ત્યારે તમને નોટિફિકેશન આપવામાં આવશે."</string>
     <string name="usb_port_enabled" msgid="7906141351687694867">"ચાર્જર અને ઍક્સેસરીની ઓળખ માટે USB પોર્ટ ચાલુ કર્યું"</string>
     <string name="usb_disable_contaminant_detection" msgid="2103905315747120033">"USB ચાલુ કરો"</string>
-    <!-- no translation found for learn_more (5000517160980853569) -->
-    <skip />
+    <string name="learn_more" msgid="5000517160980853569">"વધુ જાણો"</string>
     <string name="compat_mode_on" msgid="6623839244840638213">"સ્ક્રીન ભરવા માટે ઝૂમ કરો"</string>
     <string name="compat_mode_off" msgid="4434467572461327898">"સ્ક્રીન ભરવા માટે ખેંચો"</string>
     <string name="global_action_screenshot" msgid="8329831278085426283">"સ્ક્રીનશૉટ"</string>
@@ -199,6 +197,7 @@
     <string name="carrier_network_change_mode" msgid="8149202439957837762">"કૅરીઅર નેટવર્કમાં ફેરફાર થઈ રહ્યો છે"</string>
     <string name="accessibility_battery_details" msgid="7645516654955025422">"બૅટરીની વિગતો ખોલો"</string>
     <string name="accessibility_battery_level" msgid="7451474187113371965">"બૅટરી <xliff:g id="NUMBER">%d</xliff:g> ટકા."</string>
+    <string name="accessibility_battery_level_with_estimate" msgid="9033100930684311630">"તમારા વપરાશના આધારે બૅટરી <xliff:g id="PERCENTAGE">%1$s</xliff:g> ટકા, જે લગભગ <xliff:g id="TIME">%2$s</xliff:g> સુધી ચાલે તેટલી બચી છે"</string>
     <string name="accessibility_battery_level_charging" msgid="1147587904439319646">"બૅટરી ચાર્જ થઈ રહી છે, <xliff:g id="BATTERY_PERCENTAGE">%d</xliff:g>%%."</string>
     <string name="accessibility_settings_button" msgid="799583911231893380">"સિસ્ટમ સેટિંગ્સ."</string>
     <string name="accessibility_notifications_button" msgid="4498000369779421892">"નોટિફિકેશનો."</string>
@@ -458,10 +457,8 @@
     <string name="media_projection_remember_text" msgid="3103510882172746752">"ફરીથી બતાવશો નહીં"</string>
     <string name="clear_all_notifications_text" msgid="814192889771462828">"બધુ સાફ કરો"</string>
     <string name="manage_notifications_text" msgid="2386728145475108753">"મેનેજ કરો"</string>
-    <!-- no translation found for notification_section_header_gentle (4372438504154095677) -->
-    <skip />
-    <!-- no translation found for accessibility_notification_section_header_gentle_clear_all (4286716295850400959) -->
-    <skip />
+    <string name="notification_section_header_gentle" msgid="4372438504154095677">"સાઇલન્ટ નોટિફિકેશન"</string>
+    <string name="accessibility_notification_section_header_gentle_clear_all" msgid="4286716295850400959">"બધા સાઇલન્ટ નોટિફિકેશન સાફ કરો"</string>
     <string name="dnd_suppressing_shade_text" msgid="1904574852846769301">"ખલેલ પાડશો નહીં દ્વારા થોભાવેલ નોટિફિકેશન"</string>
     <string name="media_projection_action_text" msgid="8470872969457985954">"હવે પ્રારંભ કરો"</string>
     <string name="empty_shade_text" msgid="708135716272867002">"કોઈ સૂચનાઓ નથી"</string>
@@ -645,21 +642,16 @@
     <string name="inline_block_button" msgid="8735843688021655065">"બ્લૉક કરો"</string>
     <string name="inline_keep_button" msgid="6665940297019018232">"બતાવવાનું ચાલુ રાખો"</string>
     <string name="inline_minimize_button" msgid="966233327974702195">"નાનું કરો"</string>
-    <!-- no translation found for inline_silent_button_silent (5315879183296940969) -->
-    <skip />
+    <string name="inline_silent_button_silent" msgid="5315879183296940969">"સાઇલન્ટ"</string>
     <string name="inline_silent_button_stay_silent" msgid="6308371431217601009">"સાઇલન્ટ મોડ ચાલુ રાખો"</string>
-    <!-- no translation found for inline_silent_button_alert (6008435419895088034) -->
-    <skip />
+    <string name="inline_silent_button_alert" msgid="6008435419895088034">"અલર્ટ કરતા રહો"</string>
     <string name="inline_silent_button_keep_alerting" msgid="327696842264359693">"અલર્ટ કરવાનું ચાલુ રાખો"</string>
     <string name="inline_turn_off_notifications" msgid="8635596135532202355">"નોટિફિકેશન બંધ કરો"</string>
     <string name="inline_keep_showing_app" msgid="1723113469580031041">"આ ઍપમાંથી નોટિફિકેશન બતાવવાનું ચાલુ રાખીએ?"</string>
-    <string name="notification_silence_title" msgid="7352089096356977930">"સામાન્ય નોટિફિકેશન"</string>
-    <string name="notification_alert_title" msgid="3966526305405016221">"મહત્ત્વના નોટિફિકેશન"</string>
-    <string name="notification_channel_summary_low" msgid="1065819618107531284">"નીચે દેખાતા શેડમાં માત્ર નોટિફિકેશન પર ફોકસ કરવામાં તમને સહાય કરે છે. હંમેશાં સાઇલન્ટ."</string>
-    <string name="notification_channel_summary_low_status" msgid="2702170424808743755">"પ્રાધાન્યતાવાળા નોટિફિકેશન નીચે બતાવે છે. હંમેશાં સાઇલન્ટ."</string>
-    <string name="notification_channel_summary_low_lock" msgid="7966605244472624458">"પ્રાધાન્યતાવાળા નોટિફિકેશન નીચે બતાવે છે. હંમેશાં સાઇલન્ટ."</string>
-    <string name="notification_channel_summary_low_status_lock" msgid="7012562768950012739">"પ્રાધાન્યતાવાળા નોટિફિકેશન નીચે બતાવે છે. હંમેશાં સાઇલન્ટ."</string>
-    <string name="notification_channel_summary_default" msgid="3847289783382316019">"સાઉન્ડ અને સ્ટેટસ બાર આઇકન તમારું ધ્યાન દોરે છે. લૉક સ્ક્રીન પર બતાવે છે."</string>
+    <string name="notification_silence_title" msgid="5763240612242137433">"સાઇલન્ટ"</string>
+    <string name="notification_alert_title" msgid="8031196611815490340">"અલર્ટ કરવાનું ચાલુ રાખો"</string>
+    <string name="notification_channel_summary_low" msgid="3387466082089715555">"તમને સાઉન્ડ અથવા વાઇબ્રેશન વિના ફોકસ કરવામાં સહાય કરે છે."</string>
+    <string name="notification_channel_summary_default" msgid="5994062840431965586">"સાઉન્ડ અથવા વાઇબ્રેશન વિના તમારું ધ્યાન દોરે છે."</string>
     <string name="notification_unblockable_desc" msgid="4556908766584964102">"આ નોટિફિકેશનમાં કોઈ ફેરફાર થઈ શકશે નહીં."</string>
     <string name="notification_multichannel_desc" msgid="4695920306092240550">"નોટિફિકેશનના આ ગ્રૂપની ગોઠવણી અહીં કરી શકાશે નહીં"</string>
     <string name="notification_delegate_header" msgid="2857691673814814270">"પ્રૉક્સી નોટિફિકેશન"</string>
@@ -908,8 +900,7 @@
     <string name="slice_permission_allow" msgid="2340244901366722709">"મંજૂરી આપો"</string>
     <string name="slice_permission_deny" msgid="7683681514008048807">"નકારો"</string>
     <string name="auto_saver_title" msgid="1217959994732964228">"બૅટરી સેવર શેડ્યૂલ કરવા માટે ટૅપ કરો"</string>
-    <!-- no translation found for auto_saver_text (2563289953551438248) -->
-    <skip />
+    <string name="auto_saver_text" msgid="2563289953551438248">"જ્યારે બૅટરી સંભવિત રૂપે પૂરી થવામાં હોય ત્યારે બૅટરી સેવર ચાલુ કરો"</string>
     <string name="no_auto_saver_action" msgid="8086002101711328500">"ના, આભાર"</string>
     <string name="auto_saver_enabled_title" msgid="6726474226058316862">"બૅટરી સેવર શેડ્યૂલ ચાલુ થયું"</string>
     <string name="auto_saver_enabled_text" msgid="874711029884777579">"બૅટરીનું સ્તર એકવાર <xliff:g id="PERCENTAGE">%d</xliff:g>%% કરતાં ઓછું થાય તે પછી બૅટરી સેવર ઑટોમૅટિક રીતે ચાલુ થશે."</string>
@@ -942,4 +933,6 @@
     <string name="bubble_accessibility_action_move_bottom_left" msgid="206369104473183217">"નીચે ડાબે ખસેડો"</string>
     <string name="bubble_accessibility_action_move_bottom_right" msgid="8705660152384312329">"નીચે જમણે ખસેડો"</string>
     <string name="bubble_dismiss_text" msgid="8028337712674081668">"છોડી દો"</string>
+    <string name="notification_content_system_nav_changed" msgid="7218093915747788444">"સિસ્ટમ નૅવિગેશન અપડેટ કર્યું. ફેરફારો કરવા માટે, સેટિંગ પર જાઓ."</string>
+    <string name="notification_content_gesture_nav_available" msgid="8111130443656460792">"સિસ્ટમ નૅવિગેશનને અપડેટ કરવા માટે સેટિંગ પર જાઓ"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-hi/strings.xml b/packages/SystemUI/res/values-hi/strings.xml
index 941ca05..7fd0926 100644
--- a/packages/SystemUI/res/values-hi/strings.xml
+++ b/packages/SystemUI/res/values-hi/strings.xml
@@ -62,12 +62,10 @@
     <string name="usb_debugging_secondary_user_title" msgid="6353808721761220421">"USB डीबगिंग की अनुमति नहीं है"</string>
     <string name="usb_debugging_secondary_user_message" msgid="6067122453571699801">"अभी इस डिवाइस में जिस उपयोगकर्ता ने साइन इन किया है, वो USB डीबगिंग चालू नहीं कर सकता. इस सुविधा का इस्तेमाल करने के लिए, प्राथमिक उपयोगकर्ता में बदलें."</string>
     <string name="usb_contaminant_title" msgid="206854874263058490">"यूएसबी पोर्ट बंद है"</string>
-    <!-- no translation found for usb_contaminant_message (7379089091591609111) -->
-    <skip />
+    <string name="usb_contaminant_message" msgid="7379089091591609111">"तरल चीज़ या कचरे से आपके डिवाइस की सुरक्षा करने के लिए, यूएसबी पोर्ट को बंद कर दिया गया है. साथ ही, इससे किसी भी एक्सेसरी की पहचान नहीं की जा सकेगी.\n\nयूएसबी पोर्ट का दोबारा इस्तेमाल करना सुरक्षित होने पर आपको सूचित किया जाएगा."</string>
     <string name="usb_port_enabled" msgid="7906141351687694867">"चार्जर और एक्सेसरी पहचानने के लिए यूएसबी पोर्ट को चालू कर दिया गया है"</string>
     <string name="usb_disable_contaminant_detection" msgid="2103905315747120033">"यूएसबी चालू करें"</string>
-    <!-- no translation found for learn_more (5000517160980853569) -->
-    <skip />
+    <string name="learn_more" msgid="5000517160980853569">"ज़्यादा जानें"</string>
     <string name="compat_mode_on" msgid="6623839244840638213">"स्‍क्रीन भरने के लिए ज़ूम करें"</string>
     <string name="compat_mode_off" msgid="4434467572461327898">"स्‍क्रीन भरने के लिए खींचें"</string>
     <string name="global_action_screenshot" msgid="8329831278085426283">"स्क्रीनशॉट"</string>
@@ -199,6 +197,7 @@
     <string name="carrier_network_change_mode" msgid="8149202439957837762">"मोबाइल और इंटरनेट सेवा देने वाली कंपनी का नेटवर्क बदल रहा है"</string>
     <string name="accessibility_battery_details" msgid="7645516654955025422">"बैटरी का विवरण खोलें"</string>
     <string name="accessibility_battery_level" msgid="7451474187113371965">"<xliff:g id="NUMBER">%d</xliff:g> प्रति‍शत बैटरी."</string>
+    <string name="accessibility_battery_level_with_estimate" msgid="9033100930684311630">"<xliff:g id="PERCENTAGE">%1$s</xliff:g> प्रतिशत बैटरी बची है और आपके इस्तेमाल के हिसाब से यह <xliff:g id="TIME">%2$s</xliff:g> में खत्म हो जाएगी"</string>
     <string name="accessibility_battery_level_charging" msgid="1147587904439319646">"बैटरी चार्ज हो रही है, <xliff:g id="BATTERY_PERCENTAGE">%d</xliff:g>%%."</string>
     <string name="accessibility_settings_button" msgid="799583911231893380">"सिस्टम सेटिंग."</string>
     <string name="accessibility_notifications_button" msgid="4498000369779421892">"सूचनाएं."</string>
@@ -458,10 +457,8 @@
     <string name="media_projection_remember_text" msgid="3103510882172746752">"फिर से न दिखाएं"</string>
     <string name="clear_all_notifications_text" msgid="814192889771462828">"सभी को हटाएं"</string>
     <string name="manage_notifications_text" msgid="2386728145475108753">"प्रबंधित करें"</string>
-    <!-- no translation found for notification_section_header_gentle (4372438504154095677) -->
-    <skip />
-    <!-- no translation found for accessibility_notification_section_header_gentle_clear_all (4286716295850400959) -->
-    <skip />
+    <string name="notification_section_header_gentle" msgid="4372438504154095677">"बिना आवाज़ या वाइब्रेशन वाली सूचनाएं"</string>
+    <string name="accessibility_notification_section_header_gentle_clear_all" msgid="4286716295850400959">"बिना आवाज़ की सभी सूचनाएं हटाएं"</string>
     <string name="dnd_suppressing_shade_text" msgid="1904574852846769301">"\'परेशान न करें\' सुविधा के ज़रिए कुछ समय के लिए सूचनाएं दिखाना रोक दिया गया है"</string>
     <string name="media_projection_action_text" msgid="8470872969457985954">"अब शुरू करें"</string>
     <string name="empty_shade_text" msgid="708135716272867002">"कोई सूचना नहीं मिली"</string>
@@ -645,21 +642,16 @@
     <string name="inline_block_button" msgid="8735843688021655065">"ब्लॉक करें"</string>
     <string name="inline_keep_button" msgid="6665940297019018232">"दिखाना जारी रखें"</string>
     <string name="inline_minimize_button" msgid="966233327974702195">"सूचनाएं छोटी करें"</string>
-    <!-- no translation found for inline_silent_button_silent (5315879183296940969) -->
-    <skip />
+    <string name="inline_silent_button_silent" msgid="5315879183296940969">"बिना आवाज़ के सूचनाएं दिखाएं"</string>
     <string name="inline_silent_button_stay_silent" msgid="6308371431217601009">"साइलेंट मोड में सूचनाएं पाएं"</string>
-    <!-- no translation found for inline_silent_button_alert (6008435419895088034) -->
-    <skip />
+    <string name="inline_silent_button_alert" msgid="6008435419895088034">"चेतावनी देना"</string>
     <string name="inline_silent_button_keep_alerting" msgid="327696842264359693">"सूचना देना जारी रखें"</string>
     <string name="inline_turn_off_notifications" msgid="8635596135532202355">"सूचनाएं बंद करें"</string>
     <string name="inline_keep_showing_app" msgid="1723113469580031041">"इस ऐप्लिकेशन से जुड़ी सूचनाएं दिखाना जारी रखें?"</string>
-    <string name="notification_silence_title" msgid="7352089096356977930">"बिना आवाज़ के"</string>
-    <string name="notification_alert_title" msgid="3966526305405016221">"ज़रूरी"</string>
-    <string name="notification_channel_summary_low" msgid="1065819618107531284">"सिर्फ़ नीचे खिंचने वाली सूची में सूचनाएं दिखती हैं ताकि आप उन पर पूरा ध्यान दे सकें. दिखते समय आवाज़ और वाइब्रेशन हमेशा बंद रहते हैं."</string>
-    <string name="notification_channel_summary_low_status" msgid="2702170424808743755">"कम ज़रूरी सूचनाएं दिखती हैं. दिखते समय आवाज़ और वाइब्रेशन हमेशा बंद रहते हैं."</string>
-    <string name="notification_channel_summary_low_lock" msgid="7966605244472624458">"कम ज़रूरी सूचनाएं दिखती हैं. दिखते समय आवाज़ और वाइब्रेशन हमेशा बंद रहते हैं."</string>
-    <string name="notification_channel_summary_low_status_lock" msgid="7012562768950012739">"कम ज़रूरी सूचनाएं दिखती हैं. दिखते समय आवाज़ और वाइब्रेशन हमेशा बंद रहते हैं."</string>
-    <string name="notification_channel_summary_default" msgid="3847289783382316019">"आवाज़ और स्टेटस बार के आइकॉन की मदद से सूचनाओं पर आपका ध्यान खिंचता है. लॉक स्क्रीन पर दिखाई देता है."</string>
+    <string name="notification_silence_title" msgid="5763240612242137433">"आवाज़ के बिना सूचनाएं दिखाएं"</string>
+    <string name="notification_alert_title" msgid="8031196611815490340">"चेतावनी वाली सूचनाएं"</string>
+    <string name="notification_channel_summary_low" msgid="3387466082089715555">"आवाज़ या वाइब्रेशन न होने की वजह से आप काम में ध्यान लगा पाते हैं."</string>
+    <string name="notification_channel_summary_default" msgid="5994062840431965586">"आवाज़ या वाइब्रेशन होने की वजह से आपका ध्यान सूचनाओं पर जाता है."</string>
     <string name="notification_unblockable_desc" msgid="4556908766584964102">"ये सूचनाएं नहीं बदली जा सकती हैं."</string>
     <string name="notification_multichannel_desc" msgid="4695920306092240550">"सूचनाओं के इस समूह को यहां कॉन्फ़िगर नहीं किया जा सकता"</string>
     <string name="notification_delegate_header" msgid="2857691673814814270">"प्रॉक्सी सूचना"</string>
@@ -908,8 +900,7 @@
     <string name="slice_permission_allow" msgid="2340244901366722709">"मंज़ूरी दें"</string>
     <string name="slice_permission_deny" msgid="7683681514008048807">"नामंज़ूर करें"</string>
     <string name="auto_saver_title" msgid="1217959994732964228">"बैटरी सेवर शेड्यूल करने के लिए टैप करें"</string>
-    <!-- no translation found for auto_saver_text (2563289953551438248) -->
-    <skip />
+    <string name="auto_saver_text" msgid="2563289953551438248">"जब बैटरी खत्म होने वाली हो तब \'बैटरी सेवर\' चालू करें"</string>
     <string name="no_auto_saver_action" msgid="8086002101711328500">"जी नहीं, शुक्रिया"</string>
     <string name="auto_saver_enabled_title" msgid="6726474226058316862">"शेड्यूल किया गया बैटरी सेवर चालू हो गया"</string>
     <string name="auto_saver_enabled_text" msgid="874711029884777579">"बैटरी के <xliff:g id="PERCENTAGE">%d</xliff:g>%% से कम होने पर बैटरी सेवर अपने आप चालू हो जाएगा."</string>
@@ -942,4 +933,6 @@
     <string name="bubble_accessibility_action_move_bottom_left" msgid="206369104473183217">"बाईं ओर सबसे नीचे ले जाएं"</string>
     <string name="bubble_accessibility_action_move_bottom_right" msgid="8705660152384312329">"सबसे नीचे दाईं ओर ले जाएं"</string>
     <string name="bubble_dismiss_text" msgid="8028337712674081668">"खारिज करें"</string>
+    <string name="notification_content_system_nav_changed" msgid="7218093915747788444">"सिस्टम नेविगेशन अपडेट हो गया. बदलाव करने के लिए \'सेटिंग\' पर जाएं."</string>
+    <string name="notification_content_gesture_nav_available" msgid="8111130443656460792">"सिस्टम नेविगेशन अपडेट करने के लिए \'सेटिंग\' में जाएं"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-hr/strings.xml b/packages/SystemUI/res/values-hr/strings.xml
index ba0d1fb..28da89e 100644
--- a/packages/SystemUI/res/values-hr/strings.xml
+++ b/packages/SystemUI/res/values-hr/strings.xml
@@ -62,12 +62,10 @@
     <string name="usb_debugging_secondary_user_title" msgid="6353808721761220421">"Otklanjanje pogrešaka putem USB-a nije dopušteno"</string>
     <string name="usb_debugging_secondary_user_message" msgid="6067122453571699801">"Korisnik koji je trenutačno prijavljen na ovaj uređaj ne može uključiti otklanjanje pogrešaka putem USB-a. Da biste upotrebljavali tu značajku, prijeđite na primarnog korisnika."</string>
     <string name="usb_contaminant_title" msgid="206854874263058490">"Onemogućen je USB priključak"</string>
-    <!-- no translation found for usb_contaminant_message (7379089091591609111) -->
-    <skip />
+    <string name="usb_contaminant_message" msgid="7379089091591609111">"Radi zaštite uređaja od tekućine ili prljavštine USB priključak onemogućen je i neće otkrivati pribor.\n\nPrimit ćete obavijest kad upotreba USB priključka ponovo bude sigurna."</string>
     <string name="usb_port_enabled" msgid="7906141351687694867">"USB priključak omogućen za otkrivanje punjača i opreme"</string>
     <string name="usb_disable_contaminant_detection" msgid="2103905315747120033">"Omogući USB"</string>
-    <!-- no translation found for learn_more (5000517160980853569) -->
-    <skip />
+    <string name="learn_more" msgid="5000517160980853569">"Saznajte više"</string>
     <string name="compat_mode_on" msgid="6623839244840638213">"Zumiraj i ispuni zaslon"</string>
     <string name="compat_mode_off" msgid="4434467572461327898">"Rastegni i ispuni zaslon"</string>
     <string name="global_action_screenshot" msgid="8329831278085426283">"Snimka zaslona"</string>
@@ -199,6 +197,7 @@
     <string name="carrier_network_change_mode" msgid="8149202439957837762">"Promjena mreže mobilnog operatera"</string>
     <string name="accessibility_battery_details" msgid="7645516654955025422">"Otvaranje pojedinosti o bateriji"</string>
     <string name="accessibility_battery_level" msgid="7451474187113371965">"Baterija <xliff:g id="NUMBER">%d</xliff:g> posto."</string>
+    <string name="accessibility_battery_level_with_estimate" msgid="9033100930684311630">"Baterija je na <xliff:g id="PERCENTAGE">%1$s</xliff:g> posto, još otprilike <xliff:g id="TIME">%2$s</xliff:g> na temelju vaše upotrebe"</string>
     <string name="accessibility_battery_level_charging" msgid="1147587904439319646">"Baterija se puni, <xliff:g id="BATTERY_PERCENTAGE">%d</xliff:g> posto."</string>
     <string name="accessibility_settings_button" msgid="799583911231893380">"Postavke sustava."</string>
     <string name="accessibility_notifications_button" msgid="4498000369779421892">"Obavijesti."</string>
@@ -461,10 +460,8 @@
     <string name="media_projection_remember_text" msgid="3103510882172746752">"Ne prikazuj ponovo"</string>
     <string name="clear_all_notifications_text" msgid="814192889771462828">"Izbriši sve"</string>
     <string name="manage_notifications_text" msgid="2386728145475108753">"Upravljajte"</string>
-    <!-- no translation found for notification_section_header_gentle (4372438504154095677) -->
-    <skip />
-    <!-- no translation found for accessibility_notification_section_header_gentle_clear_all (4286716295850400959) -->
-    <skip />
+    <string name="notification_section_header_gentle" msgid="4372438504154095677">"Bešumne obavijesti"</string>
+    <string name="accessibility_notification_section_header_gentle_clear_all" msgid="4286716295850400959">"Izbriši sve bešumne obavijesti"</string>
     <string name="dnd_suppressing_shade_text" msgid="1904574852846769301">"Značajka Ne uznemiravaj pauzirala je Obavijesti"</string>
     <string name="media_projection_action_text" msgid="8470872969457985954">"Započni sad"</string>
     <string name="empty_shade_text" msgid="708135716272867002">"Nema obavijesti"</string>
@@ -648,21 +645,16 @@
     <string name="inline_block_button" msgid="8735843688021655065">"Blokiraj"</string>
     <string name="inline_keep_button" msgid="6665940297019018232">"Nastavi prikazivati"</string>
     <string name="inline_minimize_button" msgid="966233327974702195">"Minimiziraj"</string>
-    <!-- no translation found for inline_silent_button_silent (5315879183296940969) -->
-    <skip />
+    <string name="inline_silent_button_silent" msgid="5315879183296940969">"Bešumno"</string>
     <string name="inline_silent_button_stay_silent" msgid="6308371431217601009">"Nastavi tiho"</string>
-    <!-- no translation found for inline_silent_button_alert (6008435419895088034) -->
-    <skip />
+    <string name="inline_silent_button_alert" msgid="6008435419895088034">"Obavještavanje"</string>
     <string name="inline_silent_button_keep_alerting" msgid="327696842264359693">"Nastavi obavještavati"</string>
     <string name="inline_turn_off_notifications" msgid="8635596135532202355">"Isključi obavijesti"</string>
     <string name="inline_keep_showing_app" msgid="1723113469580031041">"Želite li da se obavijesti te aplikacije nastave prikazivati?"</string>
-    <string name="notification_silence_title" msgid="7352089096356977930">"Neupadljivo"</string>
-    <string name="notification_alert_title" msgid="3966526305405016221">"Prioritetno"</string>
-    <string name="notification_channel_summary_low" msgid="1065819618107531284">"Pomaže vam da se usredotočite prikazujući obavijesti samo na zaslonu obavijesti. Uvijek bešumno."</string>
-    <string name="notification_channel_summary_low_status" msgid="2702170424808743755">"Prikazuje se ispod prioritetnih obavijesti. Uvijek bešumno."</string>
-    <string name="notification_channel_summary_low_lock" msgid="7966605244472624458">"Prikazuje se ispod prioritetnih obavijesti. Uvijek bešumno."</string>
-    <string name="notification_channel_summary_low_status_lock" msgid="7012562768950012739">"Prikazuje se ispod prioritetnih obavijesti. Uvijek bešumno."</string>
-    <string name="notification_channel_summary_default" msgid="3847289783382316019">"Privlači vašu pažnju zvučnim signalom i ikonom na traci statusa. Prikazuje se na zaključanom zaslonu."</string>
+    <string name="notification_silence_title" msgid="5763240612242137433">"Bešumno"</string>
+    <string name="notification_alert_title" msgid="8031196611815490340">"Upozoravanje"</string>
+    <string name="notification_channel_summary_low" msgid="3387466082089715555">"Pomaže vam da se usredotočite bez zvučnih signala i vibracija."</string>
+    <string name="notification_channel_summary_default" msgid="5994062840431965586">"Privlači vašu pažnju zvučnim signalima ili vibracijama."</string>
     <string name="notification_unblockable_desc" msgid="4556908766584964102">"Te se obavijesti ne mogu izmijeniti."</string>
     <string name="notification_multichannel_desc" msgid="4695920306092240550">"Ta se grupa obavijesti ne može konfigurirati ovdje"</string>
     <string name="notification_delegate_header" msgid="2857691673814814270">"Obavijest poslana putem proxyja"</string>
@@ -913,8 +905,7 @@
     <string name="slice_permission_allow" msgid="2340244901366722709">"Dopusti"</string>
     <string name="slice_permission_deny" msgid="7683681514008048807">"Odbij"</string>
     <string name="auto_saver_title" msgid="1217959994732964228">"Dodirnite za zakazivanje štednje baterije"</string>
-    <!-- no translation found for auto_saver_text (2563289953551438248) -->
-    <skip />
+    <string name="auto_saver_text" msgid="2563289953551438248">"Uključite kad bi se baterija mogla isprazniti"</string>
     <string name="no_auto_saver_action" msgid="8086002101711328500">"Ne, hvala"</string>
     <string name="auto_saver_enabled_title" msgid="6726474226058316862">"Uključen je raspored štednje baterije"</string>
     <string name="auto_saver_enabled_text" msgid="874711029884777579">"Štednja baterije uključit će se automatski kad razina baterije padne ispod <xliff:g id="PERCENTAGE">%d</xliff:g>%%."</string>
@@ -947,4 +938,6 @@
     <string name="bubble_accessibility_action_move_bottom_left" msgid="206369104473183217">"Premjesti u donji lijevi kut"</string>
     <string name="bubble_accessibility_action_move_bottom_right" msgid="8705660152384312329">"Premjestite u donji desni kut"</string>
     <string name="bubble_dismiss_text" msgid="8028337712674081668">"Odbaci"</string>
+    <string name="notification_content_system_nav_changed" msgid="7218093915747788444">"Ažurirana je navigacija sustavom. Možete je promijeniti u Postavkama."</string>
+    <string name="notification_content_gesture_nav_available" msgid="8111130443656460792">"Navigaciju sustavom možete ažurirati u Postavkama"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-hu/strings.xml b/packages/SystemUI/res/values-hu/strings.xml
index 941e229..c7eb051 100644
--- a/packages/SystemUI/res/values-hu/strings.xml
+++ b/packages/SystemUI/res/values-hu/strings.xml
@@ -62,12 +62,10 @@
     <string name="usb_debugging_secondary_user_title" msgid="6353808721761220421">"Az USB hibakeresése nem engedélyezett"</string>
     <string name="usb_debugging_secondary_user_message" msgid="6067122453571699801">"Az eszközre jelenleg bejelentkezett felhasználó nem engedélyezheti az USB-hibakeresést. A funkció használatához váltson az elsődleges felhasználóra."</string>
     <string name="usb_contaminant_title" msgid="206854874263058490">"USB-port letiltva"</string>
-    <!-- no translation found for usb_contaminant_message (7379089091591609111) -->
-    <skip />
+    <string name="usb_contaminant_message" msgid="7379089091591609111">"Az eszköz folyadéktól és szennyeződésektől való megóvása érdekében az USB-portot letiltottuk, így az nem észleli a kiegészítőket.\n\nÉrtesítést küldünk, amikor ismét rendben használhatja az USB-portot."</string>
     <string name="usb_port_enabled" msgid="7906141351687694867">"Az USB-csatlakozó számára engedélyezve van a töltők és más tartozékok észlelése"</string>
     <string name="usb_disable_contaminant_detection" msgid="2103905315747120033">"USB engedélyezése"</string>
-    <!-- no translation found for learn_more (5000517160980853569) -->
-    <skip />
+    <string name="learn_more" msgid="5000517160980853569">"Részletek"</string>
     <string name="compat_mode_on" msgid="6623839244840638213">"Nagyítás a kitöltéshez"</string>
     <string name="compat_mode_off" msgid="4434467572461327898">"Nyújtás kitöltéshez"</string>
     <string name="global_action_screenshot" msgid="8329831278085426283">"Képernyőkép"</string>
@@ -199,6 +197,7 @@
     <string name="carrier_network_change_mode" msgid="8149202439957837762">"Szolgáltatói hálózat váltása"</string>
     <string name="accessibility_battery_details" msgid="7645516654955025422">"Az akkumulátorral kapcsolatos részletek megnyitása"</string>
     <string name="accessibility_battery_level" msgid="7451474187113371965">"Akkumulátor <xliff:g id="NUMBER">%d</xliff:g> százalék."</string>
+    <string name="accessibility_battery_level_with_estimate" msgid="9033100930684311630">"Az akkumulátor <xliff:g id="PERCENTAGE">%1$s</xliff:g> százalékon áll, a használati adatok alapján körülbelül <xliff:g id="TIME">%2$s</xliff:g> múlva merül le"</string>
     <string name="accessibility_battery_level_charging" msgid="1147587904439319646">"Akkumulátor töltése folyamatban, <xliff:g id="BATTERY_PERCENTAGE">%d</xliff:g> százalék."</string>
     <string name="accessibility_settings_button" msgid="799583911231893380">"Rendszerbeállítások"</string>
     <string name="accessibility_notifications_button" msgid="4498000369779421892">"Értesítések"</string>
@@ -458,10 +457,8 @@
     <string name="media_projection_remember_text" msgid="3103510882172746752">"Ne jelenjen meg többé"</string>
     <string name="clear_all_notifications_text" msgid="814192889771462828">"Az összes törlése"</string>
     <string name="manage_notifications_text" msgid="2386728145475108753">"Kezelés"</string>
-    <!-- no translation found for notification_section_header_gentle (4372438504154095677) -->
-    <skip />
-    <!-- no translation found for accessibility_notification_section_header_gentle_clear_all (4286716295850400959) -->
-    <skip />
+    <string name="notification_section_header_gentle" msgid="4372438504154095677">"Néma értesítések"</string>
+    <string name="accessibility_notification_section_header_gentle_clear_all" msgid="4286716295850400959">"Az összes néma értesítés törlése"</string>
     <string name="dnd_suppressing_shade_text" msgid="1904574852846769301">"Ne zavarjanak funkcióval szüneteltetett értesítések"</string>
     <string name="media_projection_action_text" msgid="8470872969457985954">"Indítás most"</string>
     <string name="empty_shade_text" msgid="708135716272867002">"Nincs értesítés"</string>
@@ -645,21 +642,16 @@
     <string name="inline_block_button" msgid="8735843688021655065">"Tiltás"</string>
     <string name="inline_keep_button" msgid="6665940297019018232">"Megjelenítés továbbra is"</string>
     <string name="inline_minimize_button" msgid="966233327974702195">"Kis méret"</string>
-    <!-- no translation found for inline_silent_button_silent (5315879183296940969) -->
-    <skip />
+    <string name="inline_silent_button_silent" msgid="5315879183296940969">"Néma"</string>
     <string name="inline_silent_button_stay_silent" msgid="6308371431217601009">"Néma megjelenítés"</string>
-    <!-- no translation found for inline_silent_button_alert (6008435419895088034) -->
-    <skip />
+    <string name="inline_silent_button_alert" msgid="6008435419895088034">"Értesítések"</string>
     <string name="inline_silent_button_keep_alerting" msgid="327696842264359693">"Értesítések folytatása"</string>
     <string name="inline_turn_off_notifications" msgid="8635596135532202355">"Az értesítések kikapcsolása"</string>
     <string name="inline_keep_showing_app" msgid="1723113469580031041">"Továbbra is megjelenjenek az alkalmazás értesítései?"</string>
-    <string name="notification_silence_title" msgid="7352089096356977930">"Diszkrét"</string>
-    <string name="notification_alert_title" msgid="3966526305405016221">"Prioritásos"</string>
-    <string name="notification_channel_summary_low" msgid="1065819618107531284">"Segítségével a fontos dolgokra koncentrálhat, az értesítések csak a lehúzható értesítési felületen jelennek meg. Mindig némítva van."</string>
-    <string name="notification_channel_summary_low_status" msgid="2702170424808743755">"Az elsőbbségi értesítések alatt jelenik meg. Mindig némítva van."</string>
-    <string name="notification_channel_summary_low_lock" msgid="7966605244472624458">"Az elsőbbségi értesítések alatt jelenik meg. Mindig némítva van."</string>
-    <string name="notification_channel_summary_low_status_lock" msgid="7012562768950012739">"Az elsőbbségi értesítések alatt jelenik meg. Mindig némítva van."</string>
-    <string name="notification_channel_summary_default" msgid="3847289783382316019">"Figyelemfelkeltő a hangjelzésnek és az állapotsávon megjelenő ikonnak köszönhetően. Megjelenik a lezárási képernyőn."</string>
+    <string name="notification_silence_title" msgid="5763240612242137433">"Néma"</string>
+    <string name="notification_alert_title" msgid="8031196611815490340">"Figyelemfelkeltő"</string>
+    <string name="notification_channel_summary_low" msgid="3387466082089715555">"Hangjelzés és rezgés nélkül segít a koncentrálásban."</string>
+    <string name="notification_channel_summary_default" msgid="5994062840431965586">"Figyelemfelkeltő a hangjelzésnek és rezgésnek köszönhetően."</string>
     <string name="notification_unblockable_desc" msgid="4556908766584964102">"Ezeket az értesítéseket nem lehet módosítani."</string>
     <string name="notification_multichannel_desc" msgid="4695920306092240550">"Az értesítések jelen csoportját itt nem lehet beállítani"</string>
     <string name="notification_delegate_header" msgid="2857691673814814270">"Továbbított értesítés"</string>
@@ -908,8 +900,7 @@
     <string name="slice_permission_allow" msgid="2340244901366722709">"Engedélyezés"</string>
     <string name="slice_permission_deny" msgid="7683681514008048807">"Elutasítás"</string>
     <string name="auto_saver_title" msgid="1217959994732964228">"Koppintson az akkumulátorkímélő mód ütemezéséhez"</string>
-    <!-- no translation found for auto_saver_text (2563289953551438248) -->
-    <skip />
+    <string name="auto_saver_text" msgid="2563289953551438248">"Kapcsolja be, ha az akkumulátor hamarosan lemerül"</string>
     <string name="no_auto_saver_action" msgid="8086002101711328500">"Nem"</string>
     <string name="auto_saver_enabled_title" msgid="6726474226058316862">"Akkumulátorkímélő mód ütemezése bekapcsolva"</string>
     <string name="auto_saver_enabled_text" msgid="874711029884777579">"Az akkumulátorkímélő mód automatikusan bekapcsol, ha az akkumulátor töltöttsége <xliff:g id="PERCENTAGE">%d</xliff:g>%% alá esik."</string>
@@ -942,4 +933,6 @@
     <string name="bubble_accessibility_action_move_bottom_left" msgid="206369104473183217">"Áthelyezés le és balra"</string>
     <string name="bubble_accessibility_action_move_bottom_right" msgid="8705660152384312329">"Áthelyezés le és jobbra"</string>
     <string name="bubble_dismiss_text" msgid="8028337712674081668">"Elvetés"</string>
+    <string name="notification_content_system_nav_changed" msgid="7218093915747788444">"A rendszer-navigáció módja megváltozott. Módosításához nyissa meg a Beállításokat."</string>
+    <string name="notification_content_gesture_nav_available" msgid="8111130443656460792">"A rendszer-navigációs lehetőségeket a Beállításokban módosíthatja"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-hy/strings.xml b/packages/SystemUI/res/values-hy/strings.xml
index 9ebd2d6..7d31eca 100644
--- a/packages/SystemUI/res/values-hy/strings.xml
+++ b/packages/SystemUI/res/values-hy/strings.xml
@@ -62,12 +62,10 @@
     <string name="usb_debugging_secondary_user_title" msgid="6353808721761220421">"USB վրիպազերծումը արգելված է"</string>
     <string name="usb_debugging_secondary_user_message" msgid="6067122453571699801">"Ընթացիկ հաշվի օգտատերը չի կարող միացնել USB վրիպազերծումը: Այս գործառույթը միացնելու համար մուտք գործեք հիմնական օգտատիրոջ հաշվով:"</string>
     <string name="usb_contaminant_title" msgid="206854874263058490">"USB միացքն անջատված է"</string>
-    <!-- no translation found for usb_contaminant_message (7379089091591609111) -->
-    <skip />
+    <string name="usb_contaminant_message" msgid="7379089091591609111">"USB միացքն անջատվել է, որպեսզի ձեր սարքը չթրջվի կամ չաղտոտվի: Այժմ USB միացքի միջոցով հնարավոր չէ միացնել այլ սարքեր:\n\nԴուք ծանուցում կստանաք, երբ այն նորից անվտանգ լինի օգտագործել:"</string>
     <string name="usb_port_enabled" msgid="7906141351687694867">"USB միացքը միացվել է՝ լիցքավորիչներն ու լրասարքերը հայտնաբերելու համար"</string>
     <string name="usb_disable_contaminant_detection" msgid="2103905315747120033">"Միացնել USB-ն"</string>
-    <!-- no translation found for learn_more (5000517160980853569) -->
-    <skip />
+    <string name="learn_more" msgid="5000517160980853569">"Իմանալ ավելին"</string>
     <string name="compat_mode_on" msgid="6623839244840638213">"Խոշորացնել` էկրանը լցնելու համար"</string>
     <string name="compat_mode_off" msgid="4434467572461327898">"Ձգել` էկրանը լցնելու համար"</string>
     <string name="global_action_screenshot" msgid="8329831278085426283">"Սքրինշոթ"</string>
@@ -199,6 +197,7 @@
     <string name="carrier_network_change_mode" msgid="8149202439957837762">"Օպերատորի ցանցի փոփոխություն"</string>
     <string name="accessibility_battery_details" msgid="7645516654955025422">"Բացել մարտկոցի տվյալները"</string>
     <string name="accessibility_battery_level" msgid="7451474187113371965">"Մարտկոցը <xliff:g id="NUMBER">%d</xliff:g> տոկոս է:"</string>
+    <string name="accessibility_battery_level_with_estimate" msgid="9033100930684311630">"Մարտկոցի լիցքը <xliff:g id="PERCENTAGE">%1$s</xliff:g> տոկոս է և կբավարարի մոտ <xliff:g id="TIME">%2$s</xliff:g>՝ կախված օգտագործման եղանակից:"</string>
     <string name="accessibility_battery_level_charging" msgid="1147587904439319646">"Մարտկոցը լիցքավորվում է: Լիցքը <xliff:g id="BATTERY_PERCENTAGE">%d</xliff:g> տոկոս է:"</string>
     <string name="accessibility_settings_button" msgid="799583911231893380">"Համակարգի կարգավորումներ:"</string>
     <string name="accessibility_notifications_button" msgid="4498000369779421892">"Ծանուցումներ:"</string>
@@ -458,10 +457,8 @@
     <string name="media_projection_remember_text" msgid="3103510882172746752">"Այլևս ցույց չտալ"</string>
     <string name="clear_all_notifications_text" msgid="814192889771462828">"Մաքրել բոլորը"</string>
     <string name="manage_notifications_text" msgid="2386728145475108753">"Կառավարել"</string>
-    <!-- no translation found for notification_section_header_gentle (4372438504154095677) -->
-    <skip />
-    <!-- no translation found for accessibility_notification_section_header_gentle_clear_all (4286716295850400959) -->
-    <skip />
+    <string name="notification_section_header_gentle" msgid="4372438504154095677">"Անձայն ծանուցումներ"</string>
+    <string name="accessibility_notification_section_header_gentle_clear_all" msgid="4286716295850400959">"Ջնջել բոլոր անձայն ծանուցումները"</string>
     <string name="dnd_suppressing_shade_text" msgid="1904574852846769301">"Ծանուցումները չեն ցուցադրվի «Չանհանգստացնել» ռեժիմում"</string>
     <string name="media_projection_action_text" msgid="8470872969457985954">"Սկսել հիմա"</string>
     <string name="empty_shade_text" msgid="708135716272867002">"Ծանուցումներ չկան"</string>
@@ -645,21 +642,16 @@
     <string name="inline_block_button" msgid="8735843688021655065">"Արգելափակել"</string>
     <string name="inline_keep_button" msgid="6665940297019018232">"Ցուցադրել"</string>
     <string name="inline_minimize_button" msgid="966233327974702195">"Ծալել"</string>
-    <!-- no translation found for inline_silent_button_silent (5315879183296940969) -->
-    <skip />
+    <string name="inline_silent_button_silent" msgid="5315879183296940969">"Անձայն"</string>
     <string name="inline_silent_button_stay_silent" msgid="6308371431217601009">"Չմիացնել ձայնը"</string>
-    <!-- no translation found for inline_silent_button_alert (6008435419895088034) -->
-    <skip />
+    <string name="inline_silent_button_alert" msgid="6008435419895088034">"Ծանուցել"</string>
     <string name="inline_silent_button_keep_alerting" msgid="327696842264359693">"Ծանուցել"</string>
     <string name="inline_turn_off_notifications" msgid="8635596135532202355">"Անջատել ծանուցումները"</string>
     <string name="inline_keep_showing_app" msgid="1723113469580031041">"Ցուցադրե՞լ ծանուցումներ այս հավելվածից։"</string>
-    <string name="notification_silence_title" msgid="7352089096356977930">"Անձայն"</string>
-    <string name="notification_alert_title" msgid="3966526305405016221">"Առաջնահերթ"</string>
-    <string name="notification_channel_summary_low" msgid="1065819618107531284">"Ծանուցումները ցուցադրվում են միայն իջնող վահանակի վրա, որպեսզի դուք չշեղվեք ձեր աշխատանքից: Միշտ անձայն:"</string>
-    <string name="notification_channel_summary_low_status" msgid="2702170424808743755">"Ցուցադրվում են կարևոր ծանուցումների տակ: Միշտ անձայն:"</string>
-    <string name="notification_channel_summary_low_lock" msgid="7966605244472624458">"Ցուցադրվում են կարևոր ծանուցումների տակ: Միշտ անձայն:"</string>
-    <string name="notification_channel_summary_low_status_lock" msgid="7012562768950012739">"Ցուցադրվում են կարևոր ծանուցումների տակ: Միշտ անձայն:"</string>
-    <string name="notification_channel_summary_default" msgid="3847289783382316019">"Ծանուցումները ձեր ուշադրությունն են գրավում ազդանշանով և կարգավիճակի գոտում ցուցադրվող պատկերակով: Ցուցադրվում են կողպէկրանին:"</string>
+    <string name="notification_silence_title" msgid="5763240612242137433">"Անձայն"</string>
+    <string name="notification_alert_title" msgid="8031196611815490340">"Ծանուցումներ"</string>
+    <string name="notification_channel_summary_low" msgid="3387466082089715555">"Ծանուցումները գալիս են առանց ձայնի և թրթռոցի։"</string>
+    <string name="notification_channel_summary_default" msgid="5994062840431965586">"Ծանուցումները գալիս են ձայնով կամ թրթռոցով։"</string>
     <string name="notification_unblockable_desc" msgid="4556908766584964102">"Այս ծանուցումները չեն կարող փոփոխվել:"</string>
     <string name="notification_multichannel_desc" msgid="4695920306092240550">"Ծանուցումների տվյալ խումբը հնարավոր չէ կարգավորել այստեղ"</string>
     <string name="notification_delegate_header" msgid="2857691673814814270">"Ծանուցումն ուղարկվել է պրոքսի սերվերի միջոցով"</string>
@@ -908,8 +900,7 @@
     <string name="slice_permission_allow" msgid="2340244901366722709">"Թույլատրել"</string>
     <string name="slice_permission_deny" msgid="7683681514008048807">"Մերժել"</string>
     <string name="auto_saver_title" msgid="1217959994732964228">"Հպեք՝ մարտկոցի տնտեսման ռեժիմը կարգավորելու համար"</string>
-    <!-- no translation found for auto_saver_text (2563289953551438248) -->
-    <skip />
+    <string name="auto_saver_text" msgid="2563289953551438248">"Միացնել էներգախնայումը, երբ մարտկոցի լիցքը գրեթե սպառված է"</string>
     <string name="no_auto_saver_action" msgid="8086002101711328500">"Ոչ"</string>
     <string name="auto_saver_enabled_title" msgid="6726474226058316862">"Մարտկոցի տնտեսման ռեժիմին ավտոմատ անցումը միացված է"</string>
     <string name="auto_saver_enabled_text" msgid="874711029884777579">"Մարտկոցի տնտեսման ռեժիմն ավտոմատ կմիանա, երբ մարտկոցի լիցքը <xliff:g id="PERCENTAGE">%d</xliff:g>%%-ից պակասի:"</string>
@@ -942,4 +933,6 @@
     <string name="bubble_accessibility_action_move_bottom_left" msgid="206369104473183217">"Տեղափոխել ներքև՝ ձախ"</string>
     <string name="bubble_accessibility_action_move_bottom_right" msgid="8705660152384312329">"Տեղափոխել ներքև՝ աջ"</string>
     <string name="bubble_dismiss_text" msgid="8028337712674081668">"Փակել"</string>
+    <string name="notification_content_system_nav_changed" msgid="7218093915747788444">"Համակարգի նավիգացիան թարմացվեց: Փոփոխություններ անելու համար անցեք կարգավորումներ:"</string>
+    <string name="notification_content_gesture_nav_available" msgid="8111130443656460792">"Թարմացրեք համակարգի նավիգացիան կարգավորումներում"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-in/strings.xml b/packages/SystemUI/res/values-in/strings.xml
index bf5d3a1..f0c9f1e 100644
--- a/packages/SystemUI/res/values-in/strings.xml
+++ b/packages/SystemUI/res/values-in/strings.xml
@@ -62,7 +62,7 @@
     <string name="usb_debugging_secondary_user_title" msgid="6353808721761220421">"Debug USB tidak diizinkan"</string>
     <string name="usb_debugging_secondary_user_message" msgid="6067122453571699801">"Pengguna yang sedang login ke perangkat ini tidak dapat mengaktifkan proses debug USB. Beralihlah ke pengguna utama untuk menggunakan fitur ini."</string>
     <string name="usb_contaminant_title" msgid="206854874263058490">"Port USB dinonaktifkan"</string>
-    <string name="usb_contaminant_message" msgid="7379089091591609111">"Untuk melindungi perangkat dari cairan atau kotoran, port USB dinonaktifkan dan tidak akan mendeteksi aksesori apa pun.\n\nAnda akan diberi tahu jika sudah diperbolehkan menggunakan port USB kembali."</string>
+    <string name="usb_contaminant_message" msgid="7379089091591609111">"Untuk melindungi perangkat dari cairan atau kotoran, port USB dinonaktifkan dan tidak akan mendeteksi aksesori apa pun.\n\nAnda akan diberi tahu jika port USB sudah dapat digunakan kembali."</string>
     <string name="usb_port_enabled" msgid="7906141351687694867">"Port USB diaktifkan untuk mendeteksi pengisi daya dan aksesori"</string>
     <string name="usb_disable_contaminant_detection" msgid="2103905315747120033">"Aktifkan USB"</string>
     <string name="learn_more" msgid="5000517160980853569">"Pelajari lebih lanjut"</string>
@@ -197,6 +197,7 @@
     <string name="carrier_network_change_mode" msgid="8149202439957837762">"Jaringan operator berubah"</string>
     <string name="accessibility_battery_details" msgid="7645516654955025422">"Membuka detail baterai"</string>
     <string name="accessibility_battery_level" msgid="7451474187113371965">"Baterai <xliff:g id="NUMBER">%d</xliff:g> persen."</string>
+    <string name="accessibility_battery_level_with_estimate" msgid="9033100930684311630">"Baterai <xliff:g id="PERCENTAGE">%1$s</xliff:g> persen, sekitar <xliff:g id="TIME">%2$s</xliff:g> lagi berdasarkan penggunaan Anda"</string>
     <string name="accessibility_battery_level_charging" msgid="1147587904439319646">"Mengisi daya baterai, <xliff:g id="BATTERY_PERCENTAGE">%d</xliff:g> persen."</string>
     <string name="accessibility_settings_button" msgid="799583911231893380">"Setelan sistem."</string>
     <string name="accessibility_notifications_button" msgid="4498000369779421892">"Notifikasi."</string>
@@ -647,13 +648,10 @@
     <string name="inline_silent_button_keep_alerting" msgid="327696842264359693">"Terus beri tahu"</string>
     <string name="inline_turn_off_notifications" msgid="8635596135532202355">"Nonaktifkan notifikasi"</string>
     <string name="inline_keep_showing_app" msgid="1723113469580031041">"Terus tampilkan notifikasi dari aplikasi ini?"</string>
-    <string name="notification_silence_title" msgid="7352089096356977930">"Senyap"</string>
-    <string name="notification_alert_title" msgid="3966526305405016221">"Diprioritaskan"</string>
-    <string name="notification_channel_summary_low" msgid="1065819618107531284">"Membantu Anda berfokus hanya pada notifikasi di bayangan pull-down. Selalu senyap."</string>
-    <string name="notification_channel_summary_low_status" msgid="2702170424808743755">"Ditampilkan di bawah notifikasi prioritas. Selalu senyap."</string>
-    <string name="notification_channel_summary_low_lock" msgid="7966605244472624458">"Ditampilkan di bawah notifikasi prioritas. Selalu senyap."</string>
-    <string name="notification_channel_summary_low_status_lock" msgid="7012562768950012739">"Ditampilkan di bawah notifikasi prioritas. Selalu senyap."</string>
-    <string name="notification_channel_summary_default" msgid="3847289783382316019">"Menarik perhatian Anda dengan suara &amp; ikon status bar. Ditampilkan di layar kunci."</string>
+    <string name="notification_silence_title" msgid="5763240612242137433">"Senyap"</string>
+    <string name="notification_alert_title" msgid="8031196611815490340">"Pemberitahuan"</string>
+    <string name="notification_channel_summary_low" msgid="3387466082089715555">"Membantu Anda tetap fokus tanpa suara atau getaran."</string>
+    <string name="notification_channel_summary_default" msgid="5994062840431965586">"Menarik perhatian Anda dengan suara atau getaran."</string>
     <string name="notification_unblockable_desc" msgid="4556908766584964102">"Notifikasi ini tidak dapat diubah."</string>
     <string name="notification_multichannel_desc" msgid="4695920306092240550">"Grup notifikasi ini tidak dapat dikonfigurasi di sini"</string>
     <string name="notification_delegate_header" msgid="2857691673814814270">"Notifikasi proxy"</string>
@@ -935,4 +933,6 @@
     <string name="bubble_accessibility_action_move_bottom_left" msgid="206369104473183217">"Pindahkan ke kiri bawah"</string>
     <string name="bubble_accessibility_action_move_bottom_right" msgid="8705660152384312329">"Pindahkan ke kanan bawah"</string>
     <string name="bubble_dismiss_text" msgid="8028337712674081668">"Tutup"</string>
+    <string name="notification_content_system_nav_changed" msgid="7218093915747788444">"Navigasi sistem diupdate. Untuk melakukan perubahan, buka Setelan."</string>
+    <string name="notification_content_gesture_nav_available" msgid="8111130443656460792">"Buka Setelan untuk mengupdate navigasi sistem"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-is/strings.xml b/packages/SystemUI/res/values-is/strings.xml
index b4b9be9..bd160e7 100644
--- a/packages/SystemUI/res/values-is/strings.xml
+++ b/packages/SystemUI/res/values-is/strings.xml
@@ -62,12 +62,10 @@
     <string name="usb_debugging_secondary_user_title" msgid="6353808721761220421">"USB-villuleit ekki leyfð"</string>
     <string name="usb_debugging_secondary_user_message" msgid="6067122453571699801">"Notandinn sem er skráður inn í þetta tæki núna getur ekki kveikt á USB-villuleit. Til þess að nota þennan eiginleika skaltu skipta yfir í aðalnotandann."</string>
     <string name="usb_contaminant_title" msgid="206854874263058490">"USB-tengi gert óvirkt"</string>
-    <!-- no translation found for usb_contaminant_message (7379089091591609111) -->
-    <skip />
+    <string name="usb_contaminant_message" msgid="7379089091591609111">"Til að vernda tækið fyrir vökva og óhreinindum er USB-tengið óvirkt og mun ekki greina aukabúnað.\n\nÞú færð tilkynningu þegar öruggt er að nota USB-tengið aftur."</string>
     <string name="usb_port_enabled" msgid="7906141351687694867">"Kveikt var á USB-tengi til að greina hleðslutæki og aukabúnað"</string>
     <string name="usb_disable_contaminant_detection" msgid="2103905315747120033">"Virkja USB"</string>
-    <!-- no translation found for learn_more (5000517160980853569) -->
-    <skip />
+    <string name="learn_more" msgid="5000517160980853569">"Frekari upplýsingar"</string>
     <string name="compat_mode_on" msgid="6623839244840638213">"Fylla skjá með aðdrætti"</string>
     <string name="compat_mode_off" msgid="4434467572461327898">"Teygja yfir allan skjáinn"</string>
     <string name="global_action_screenshot" msgid="8329831278085426283">"Skjámynd"</string>
@@ -199,6 +197,7 @@
     <string name="carrier_network_change_mode" msgid="8149202439957837762">"Skiptir um farsímakerfi"</string>
     <string name="accessibility_battery_details" msgid="7645516654955025422">"Opna upplýsingar um rafhlöðu"</string>
     <string name="accessibility_battery_level" msgid="7451474187113371965">"<xliff:g id="NUMBER">%d</xliff:g> prósent á rafhlöðu."</string>
+    <string name="accessibility_battery_level_with_estimate" msgid="9033100930684311630">"Rafhlaða í <xliff:g id="PERCENTAGE">%1$s</xliff:g>%, um það bil <xliff:g id="TIME">%2$s</xliff:g> eftir miðað við notkun þína"</string>
     <string name="accessibility_battery_level_charging" msgid="1147587904439319646">"Rafhlaða í hleðslu, <xliff:g id="BATTERY_PERCENTAGE">%d</xliff:g>%%."</string>
     <string name="accessibility_settings_button" msgid="799583911231893380">"Kerfisstillingar."</string>
     <string name="accessibility_notifications_button" msgid="4498000369779421892">"Tilkynningar."</string>
@@ -458,10 +457,8 @@
     <string name="media_projection_remember_text" msgid="3103510882172746752">"Ekki sýna þetta aftur"</string>
     <string name="clear_all_notifications_text" msgid="814192889771462828">"Hreinsa allt"</string>
     <string name="manage_notifications_text" msgid="2386728145475108753">"Stjórna"</string>
-    <!-- no translation found for notification_section_header_gentle (4372438504154095677) -->
-    <skip />
-    <!-- no translation found for accessibility_notification_section_header_gentle_clear_all (4286716295850400959) -->
-    <skip />
+    <string name="notification_section_header_gentle" msgid="4372438504154095677">"Þöglar tilkynningar"</string>
+    <string name="accessibility_notification_section_header_gentle_clear_all" msgid="4286716295850400959">"Hreinsa allar þöglar tilkynningar"</string>
     <string name="dnd_suppressing_shade_text" msgid="1904574852846769301">"Hlé gert á tilkynningum þar sem stillt er á „Ónáðið ekki“"</string>
     <string name="media_projection_action_text" msgid="8470872969457985954">"Byrja núna"</string>
     <string name="empty_shade_text" msgid="708135716272867002">"Engar tilkynningar"</string>
@@ -645,21 +642,16 @@
     <string name="inline_block_button" msgid="8735843688021655065">"Loka á"</string>
     <string name="inline_keep_button" msgid="6665940297019018232">"Sýna áfram"</string>
     <string name="inline_minimize_button" msgid="966233327974702195">"Minnka"</string>
-    <!-- no translation found for inline_silent_button_silent (5315879183296940969) -->
-    <skip />
+    <string name="inline_silent_button_silent" msgid="5315879183296940969">"Hljóðlaust"</string>
     <string name="inline_silent_button_stay_silent" msgid="6308371431217601009">"Áfram hljóðlaust"</string>
-    <!-- no translation found for inline_silent_button_alert (6008435419895088034) -->
-    <skip />
+    <string name="inline_silent_button_alert" msgid="6008435419895088034">"Tilkynna"</string>
     <string name="inline_silent_button_keep_alerting" msgid="327696842264359693">"Halda áfram að gera viðvart"</string>
     <string name="inline_turn_off_notifications" msgid="8635596135532202355">"Slökkva á tilkynningum"</string>
     <string name="inline_keep_showing_app" msgid="1723113469580031041">"Sýna áfram tilkynningar frá þessu forriti?"</string>
-    <string name="notification_silence_title" msgid="7352089096356977930">"Lágstemmdar"</string>
-    <string name="notification_alert_title" msgid="3966526305405016221">"Í forgangi"</string>
-    <string name="notification_channel_summary_low" msgid="1065819618107531284">"Auðveldar þér að einbeita þér með tilkynningum sem birtast aðeins á fellisvæði. Alltaf án hljóðs."</string>
-    <string name="notification_channel_summary_low_status" msgid="2702170424808743755">"Birtir tilkynningar með lítinn forgang. Alltaf án hljóðs."</string>
-    <string name="notification_channel_summary_low_lock" msgid="7966605244472624458">"Birtir tilkynningar með lítinn forgang. Alltaf án hljóðs."</string>
-    <string name="notification_channel_summary_low_status_lock" msgid="7012562768950012739">"Birtir tilkynningar með lítinn forgang. Alltaf án hljóðs."</string>
-    <string name="notification_channel_summary_default" msgid="3847289783382316019">"Fangar athygli þína með hljóði og stöðustikutákni. Sést á lásskjánum."</string>
+    <string name="notification_silence_title" msgid="5763240612242137433">"Hljóðlaust"</string>
+    <string name="notification_alert_title" msgid="8031196611815490340">"Viðvörun"</string>
+    <string name="notification_channel_summary_low" msgid="3387466082089715555">"Auðveldar þér að einbeita þér án hljóðs eða titrings."</string>
+    <string name="notification_channel_summary_default" msgid="5994062840431965586">"Fangar athygli þína með hljóði eða titringi."</string>
     <string name="notification_unblockable_desc" msgid="4556908766584964102">"Ekki er hægt að breyta þessum tilkynningum."</string>
     <string name="notification_multichannel_desc" msgid="4695920306092240550">"Ekki er hægt að stilla þessar tilkynningar hér"</string>
     <string name="notification_delegate_header" msgid="2857691673814814270">"Staðgengilstilkynning"</string>
@@ -908,8 +900,7 @@
     <string name="slice_permission_allow" msgid="2340244901366722709">"Leyfa"</string>
     <string name="slice_permission_deny" msgid="7683681514008048807">"Hafna"</string>
     <string name="auto_saver_title" msgid="1217959994732964228">"Pikka til að stilla rafhlöðusparnað"</string>
-    <!-- no translation found for auto_saver_text (2563289953551438248) -->
-    <skip />
+    <string name="auto_saver_text" msgid="2563289953551438248">"Kveikja þegar rafhlaða er við það að klárast"</string>
     <string name="no_auto_saver_action" msgid="8086002101711328500">"Nei, takk"</string>
     <string name="auto_saver_enabled_title" msgid="6726474226058316862">"Kveikt á rafhlöðusparnaði"</string>
     <string name="auto_saver_enabled_text" msgid="874711029884777579">"Sjálfkrafa verður kveikt á rafhlöðusparnaði þegar hleðsla rafhlöðunnar fer niður fyrir <xliff:g id="PERCENTAGE">%d</xliff:g>%%."</string>
@@ -942,4 +933,6 @@
     <string name="bubble_accessibility_action_move_bottom_left" msgid="206369104473183217">"Færa neðst til vinstri"</string>
     <string name="bubble_accessibility_action_move_bottom_right" msgid="8705660152384312329">"Færðu neðst til hægri"</string>
     <string name="bubble_dismiss_text" msgid="8028337712674081668">"Hunsa"</string>
+    <string name="notification_content_system_nav_changed" msgid="7218093915747788444">"Kerfisstjórnun uppfærð. Þú getur breytt þessu í stillingunum."</string>
+    <string name="notification_content_gesture_nav_available" msgid="8111130443656460792">"Farðu í stillingar til að uppfæra kerfisstjórnun"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-it/strings.xml b/packages/SystemUI/res/values-it/strings.xml
index 52b915a..8167084 100644
--- a/packages/SystemUI/res/values-it/strings.xml
+++ b/packages/SystemUI/res/values-it/strings.xml
@@ -197,6 +197,7 @@
     <string name="carrier_network_change_mode" msgid="8149202439957837762">"Cambio della rete dell\'operatore"</string>
     <string name="accessibility_battery_details" msgid="7645516654955025422">"Visualizza i dettagli relativi alla batteria"</string>
     <string name="accessibility_battery_level" msgid="7451474187113371965">"Batteria: <xliff:g id="NUMBER">%d</xliff:g> percento."</string>
+    <string name="accessibility_battery_level_with_estimate" msgid="9033100930684311630">"Livello della batteria: <xliff:g id="PERCENTAGE">%1$s</xliff:g> percento. Tempo rimanente in base al tuo utilizzo: <xliff:g id="TIME">%2$s</xliff:g>"</string>
     <string name="accessibility_battery_level_charging" msgid="1147587904439319646">"Batteria in carica, <xliff:g id="BATTERY_PERCENTAGE">%d</xliff:g>%%."</string>
     <string name="accessibility_settings_button" msgid="799583911231893380">"Impostazioni di sistema."</string>
     <string name="accessibility_notifications_button" msgid="4498000369779421892">"Notifiche."</string>
@@ -647,13 +648,10 @@
     <string name="inline_silent_button_keep_alerting" msgid="327696842264359693">"Continua ad avvisare"</string>
     <string name="inline_turn_off_notifications" msgid="8635596135532202355">"Disattiva notifiche"</string>
     <string name="inline_keep_showing_app" msgid="1723113469580031041">"Continuare a ricevere notifiche da questa app?"</string>
-    <string name="notification_silence_title" msgid="7352089096356977930">"Silenziose"</string>
-    <string name="notification_alert_title" msgid="3966526305405016221">"Con priorità"</string>
-    <string name="notification_channel_summary_low" msgid="1065819618107531284">"Puoi concentrarti perché le notifiche sono visualizzate solo nell\'area a discesa. Sempre silenziose."</string>
-    <string name="notification_channel_summary_low_status" msgid="2702170424808743755">"Vengono mostrate le notifiche con priorità bassa. Sempre silenziose."</string>
-    <string name="notification_channel_summary_low_lock" msgid="7966605244472624458">"Vengono mostrate le notifiche con priorità bassa. Sempre silenziose."</string>
-    <string name="notification_channel_summary_low_status_lock" msgid="7012562768950012739">"Vengono mostrate le notifiche con priorità bassa. Sempre silenziose."</string>
-    <string name="notification_channel_summary_default" msgid="3847289783382316019">"Attirano la tua attenzione con un suono e un\'icona nella barra di stato. Le notifiche sono mostrate nella schermata di blocco."</string>
+    <string name="notification_silence_title" msgid="5763240612242137433">"Modalità silenziosa"</string>
+    <string name="notification_alert_title" msgid="8031196611815490340">"Avvisi"</string>
+    <string name="notification_channel_summary_low" msgid="3387466082089715555">"Favorisce la tua concentrazione grazie all\'assenza di suono o vibrazione."</string>
+    <string name="notification_channel_summary_default" msgid="5994062840431965586">"Richiama la tua attenzione con suono o vibrazione."</string>
     <string name="notification_unblockable_desc" msgid="4556908766584964102">"Impossibile modificare queste notifiche."</string>
     <string name="notification_multichannel_desc" msgid="4695920306092240550">"Qui non è possibile configurare questo gruppo di notifiche"</string>
     <string name="notification_delegate_header" msgid="2857691673814814270">"Notifica inviata al proxy"</string>
@@ -935,4 +933,6 @@
     <string name="bubble_accessibility_action_move_bottom_left" msgid="206369104473183217">"Sposta in basso a sinistra"</string>
     <string name="bubble_accessibility_action_move_bottom_right" msgid="8705660152384312329">"Sposta in basso a destra"</string>
     <string name="bubble_dismiss_text" msgid="8028337712674081668">"Ignora"</string>
+    <string name="notification_content_system_nav_changed" msgid="7218093915747788444">"Navigazione del sistema aggiornata. Per apportare modifiche, usa le Impostazioni."</string>
+    <string name="notification_content_gesture_nav_available" msgid="8111130443656460792">"Usa le Impostazioni per aggiornare la navigazione del sistema"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-iw/strings.xml b/packages/SystemUI/res/values-iw/strings.xml
index 684398d7..3468f01 100644
--- a/packages/SystemUI/res/values-iw/strings.xml
+++ b/packages/SystemUI/res/values-iw/strings.xml
@@ -62,12 +62,10 @@
     <string name="usb_debugging_secondary_user_title" msgid="6353808721761220421">"‏לא ניתן לבצע ניפוי באגים ב-USB"</string>
     <string name="usb_debugging_secondary_user_message" msgid="6067122453571699801">"‏למשתמש המחובר לחשבון במכשיר הזה אין אפשרות להפעיל ניפוי באגים ב-USB. כדי להשתמש בתכונה הזו יש לעבור אל המשתמש הראשי."</string>
     <string name="usb_contaminant_title" msgid="206854874263058490">"‏יציאת ה-USB מושבתת"</string>
-    <!-- no translation found for usb_contaminant_message (7379089091591609111) -->
-    <skip />
+    <string name="usb_contaminant_message" msgid="7379089091591609111">"‏כדי להגן על המכשיר שלך מנוזלים או חלקיקים, יציאת ה-USB מושבתת ולא מזהה אביזרים כלל.\n\nתתקבל התראה כשניתן יהיה להשתמש ביציאת ה-USB."</string>
     <string name="usb_port_enabled" msgid="7906141351687694867">"‏יציאת USB הופעלה לזיהוי מטענים ואביזרים"</string>
     <string name="usb_disable_contaminant_detection" msgid="2103905315747120033">"‏הפעלת USB"</string>
-    <!-- no translation found for learn_more (5000517160980853569) -->
-    <skip />
+    <string name="learn_more" msgid="5000517160980853569">"מידע נוסף"</string>
     <string name="compat_mode_on" msgid="6623839244840638213">"הגדל תצוגה כדי למלא את המסך"</string>
     <string name="compat_mode_off" msgid="4434467572461327898">"מתח כדי למלא את המסך"</string>
     <string name="global_action_screenshot" msgid="8329831278085426283">"צילום מסך"</string>
@@ -199,6 +197,7 @@
     <string name="carrier_network_change_mode" msgid="8149202439957837762">"רשת ספק משתנה"</string>
     <string name="accessibility_battery_details" msgid="7645516654955025422">"פתיחת פרטי סוללה"</string>
     <string name="accessibility_battery_level" msgid="7451474187113371965">"<xliff:g id="NUMBER">%d</xliff:g> אחוזים של סוללה."</string>
+    <string name="accessibility_battery_level_with_estimate" msgid="9033100930684311630">"רמת הטעינה בסוללה: <xliff:g id="PERCENTAGE">%1$s</xliff:g> אחוזים, הזמן הנותר המשוער על סמך השימוש שלך:<xliff:g id="TIME">%2$s</xliff:g>"</string>
     <string name="accessibility_battery_level_charging" msgid="1147587904439319646">"טעינת סוללה, <xliff:g id="BATTERY_PERCENTAGE">%d</xliff:g>%%."</string>
     <string name="accessibility_settings_button" msgid="799583911231893380">"הגדרות מערכת"</string>
     <string name="accessibility_notifications_button" msgid="4498000369779421892">"התראות"</string>
@@ -464,10 +463,8 @@
     <string name="media_projection_remember_text" msgid="3103510882172746752">"אל תציג שוב"</string>
     <string name="clear_all_notifications_text" msgid="814192889771462828">"נקה הכל"</string>
     <string name="manage_notifications_text" msgid="2386728145475108753">"ניהול"</string>
-    <!-- no translation found for notification_section_header_gentle (4372438504154095677) -->
-    <skip />
-    <!-- no translation found for accessibility_notification_section_header_gentle_clear_all (4286716295850400959) -->
-    <skip />
+    <string name="notification_section_header_gentle" msgid="4372438504154095677">"התראות שקטות"</string>
+    <string name="accessibility_notification_section_header_gentle_clear_all" msgid="4286716295850400959">"ניקוי כל ההתראות השקטות"</string>
     <string name="dnd_suppressing_shade_text" msgid="1904574852846769301">"התראות הושהו על ידי מצב \'נא לא להפריע\'"</string>
     <string name="media_projection_action_text" msgid="8470872969457985954">"התחל כעת"</string>
     <string name="empty_shade_text" msgid="708135716272867002">"אין התראות"</string>
@@ -651,21 +648,16 @@
     <string name="inline_block_button" msgid="8735843688021655065">"חסימה"</string>
     <string name="inline_keep_button" msgid="6665940297019018232">"כן, המשיכו"</string>
     <string name="inline_minimize_button" msgid="966233327974702195">"מזעור"</string>
-    <!-- no translation found for inline_silent_button_silent (5315879183296940969) -->
-    <skip />
+    <string name="inline_silent_button_silent" msgid="5315879183296940969">"שקטה"</string>
     <string name="inline_silent_button_stay_silent" msgid="6308371431217601009">"בשקט"</string>
-    <!-- no translation found for inline_silent_button_alert (6008435419895088034) -->
-    <skip />
+    <string name="inline_silent_button_alert" msgid="6008435419895088034">"שליחת התראות"</string>
     <string name="inline_silent_button_keep_alerting" msgid="327696842264359693">"המשך שליחת התראות"</string>
     <string name="inline_turn_off_notifications" msgid="8635596135532202355">"השבתת ההתראות"</string>
     <string name="inline_keep_showing_app" msgid="1723113469580031041">"שנמשיך להציג לך התראות מהאפליקציה הזאת?"</string>
-    <string name="notification_silence_title" msgid="7352089096356977930">"ברמה מתונה"</string>
-    <string name="notification_alert_title" msgid="3966526305405016221">"בעדיפות"</string>
-    <string name="notification_channel_summary_low" msgid="1065819618107531284">"עוזרת לריכוז באמצעות הצגת התראות בלוח ההתראות הנפתח בלבד. תמיד שקטה."</string>
-    <string name="notification_channel_summary_low_status" msgid="2702170424808743755">"יופיעו התראות בעדיפות נמוכה. תמיד בשקט."</string>
-    <string name="notification_channel_summary_low_lock" msgid="7966605244472624458">"יופיעו התראות בעדיפות נמוכה. תמיד בשקט."</string>
-    <string name="notification_channel_summary_low_status_lock" msgid="7012562768950012739">"יופיעו התראות בעדיפות נמוכה. תמיד בשקט."</string>
-    <string name="notification_channel_summary_default" msgid="3847289783382316019">"מעוררת תשומת לב באמצעות צלילים וסמל בשורת הסטטוס. מוצגת במסך הנעילה."</string>
+    <string name="notification_silence_title" msgid="5763240612242137433">"שקט"</string>
+    <string name="notification_alert_title" msgid="8031196611815490340">"שליחת התראות"</string>
+    <string name="notification_channel_summary_low" msgid="3387466082089715555">"עוזרת להתרכז ללא צלילים או רטט."</string>
+    <string name="notification_channel_summary_default" msgid="5994062840431965586">"מעוררת תשומת לב באמצעות צלילים או רטט."</string>
     <string name="notification_unblockable_desc" msgid="4556908766584964102">"לא ניתן לשנות את ההתראות האלה."</string>
     <string name="notification_multichannel_desc" msgid="4695920306092240550">"לא ניתן להגדיר כאן את קבוצת ההתראות הזו"</string>
     <string name="notification_delegate_header" msgid="2857691673814814270">"‏התראה דרך שרת proxy"</string>
@@ -918,8 +910,7 @@
     <string name="slice_permission_allow" msgid="2340244901366722709">"אני רוצה לאשר"</string>
     <string name="slice_permission_deny" msgid="7683681514008048807">"אני לא מרשה"</string>
     <string name="auto_saver_title" msgid="1217959994732964228">"יש להקיש כדי לתזמן את מצב החיסכון בסוללה"</string>
-    <!-- no translation found for auto_saver_text (2563289953551438248) -->
-    <skip />
+    <string name="auto_saver_text" msgid="2563289953551438248">"מומלץ להפעיל את התכונה כשיש סבירות גבוהה שהסוללה תתרוקן"</string>
     <string name="no_auto_saver_action" msgid="8086002101711328500">"לא תודה"</string>
     <string name="auto_saver_enabled_title" msgid="6726474226058316862">"הופעל תזמון של חיסכון בסוללה"</string>
     <string name="auto_saver_enabled_text" msgid="874711029884777579">"מצב חיסכון בסוללה יופעל באופן אוטומטי כשרמת טעינת הסוללה תהיה נמוכה מ-<xliff:g id="PERCENTAGE">%d</xliff:g>%%."</string>
@@ -952,4 +943,6 @@
     <string name="bubble_accessibility_action_move_bottom_left" msgid="206369104473183217">"העברה לפינה השמאלית התחתונה"</string>
     <string name="bubble_accessibility_action_move_bottom_right" msgid="8705660152384312329">"העברה לפינה הימנית התחתונה"</string>
     <string name="bubble_dismiss_text" msgid="8028337712674081668">"סגירה"</string>
+    <string name="notification_content_system_nav_changed" msgid="7218093915747788444">"הניווט במערכת עודכן. אפשר לערוך שינויים דרך ההגדרות."</string>
+    <string name="notification_content_gesture_nav_available" msgid="8111130443656460792">"יש לעבור להגדרות כדי לעדכן את הניווט במערכת"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-ja/strings.xml b/packages/SystemUI/res/values-ja/strings.xml
index 39a8419..78bb013 100644
--- a/packages/SystemUI/res/values-ja/strings.xml
+++ b/packages/SystemUI/res/values-ja/strings.xml
@@ -62,12 +62,10 @@
     <string name="usb_debugging_secondary_user_title" msgid="6353808721761220421">"USBデバッグは許可されていません"</string>
     <string name="usb_debugging_secondary_user_message" msgid="6067122453571699801">"このデバイスに現在ログインしているユーザーでは、USB デバッグを ON にすることはできません。この機能を使用するには、メインユーザーに切り替えてください。"</string>
     <string name="usb_contaminant_title" msgid="206854874263058490">"USB ポート無効"</string>
-    <!-- no translation found for usb_contaminant_message (7379089091591609111) -->
-    <skip />
+    <string name="usb_contaminant_message" msgid="7379089091591609111">"液体やゴミからデバイスを保護するため、USB ポートは無効になっています。アクセサリの検出は行われません。\n\nUSB ポートを再び安全に使用できるようになりましたらお知らせします。"</string>
     <string name="usb_port_enabled" msgid="7906141351687694867">"USB ポートが有効になり、充電器やアクセサリを検出できるようになりました"</string>
     <string name="usb_disable_contaminant_detection" msgid="2103905315747120033">"USB を有効にする"</string>
-    <!-- no translation found for learn_more (5000517160980853569) -->
-    <skip />
+    <string name="learn_more" msgid="5000517160980853569">"詳細"</string>
     <string name="compat_mode_on" msgid="6623839244840638213">"画面サイズに合わせて拡大"</string>
     <string name="compat_mode_off" msgid="4434467572461327898">"画面サイズに合わせて拡大"</string>
     <string name="global_action_screenshot" msgid="8329831278085426283">"画面の保存"</string>
@@ -199,6 +197,7 @@
     <string name="carrier_network_change_mode" msgid="8149202439957837762">"携帯通信会社のネットワークを変更します"</string>
     <string name="accessibility_battery_details" msgid="7645516654955025422">"電池の詳細情報を開きます"</string>
     <string name="accessibility_battery_level" msgid="7451474187113371965">"電池残量: <xliff:g id="NUMBER">%d</xliff:g>パーセント"</string>
+    <string name="accessibility_battery_level_with_estimate" msgid="9033100930684311630">"電池残量: <xliff:g id="PERCENTAGE">%1$s</xliff:g>、およそ <xliff:g id="TIME">%2$s</xliff:g> に電池切れ(使用状況に基づく)"</string>
     <string name="accessibility_battery_level_charging" msgid="1147587904439319646">"電池充電中: <xliff:g id="BATTERY_PERCENTAGE">%d</xliff:g>%%"</string>
     <string name="accessibility_settings_button" msgid="799583911231893380">"システム設定。"</string>
     <string name="accessibility_notifications_button" msgid="4498000369779421892">"通知。"</string>
@@ -458,10 +457,8 @@
     <string name="media_projection_remember_text" msgid="3103510882172746752">"次回から表示しない"</string>
     <string name="clear_all_notifications_text" msgid="814192889771462828">"すべて消去"</string>
     <string name="manage_notifications_text" msgid="2386728145475108753">"管理"</string>
-    <!-- no translation found for notification_section_header_gentle (4372438504154095677) -->
-    <skip />
-    <!-- no translation found for accessibility_notification_section_header_gentle_clear_all (4286716295850400959) -->
-    <skip />
+    <string name="notification_section_header_gentle" msgid="4372438504154095677">"サイレント通知"</string>
+    <string name="accessibility_notification_section_header_gentle_clear_all" msgid="4286716295850400959">"サイレント通知がすべて消去されます"</string>
     <string name="dnd_suppressing_shade_text" msgid="1904574852846769301">"サイレント モードにより通知は一時停止中です"</string>
     <string name="media_projection_action_text" msgid="8470872969457985954">"今すぐ開始"</string>
     <string name="empty_shade_text" msgid="708135716272867002">"通知はありません"</string>
@@ -645,21 +642,16 @@
     <string name="inline_block_button" msgid="8735843688021655065">"ブロック"</string>
     <string name="inline_keep_button" msgid="6665940297019018232">"今後も表示する"</string>
     <string name="inline_minimize_button" msgid="966233327974702195">"最小化"</string>
-    <!-- no translation found for inline_silent_button_silent (5315879183296940969) -->
-    <skip />
+    <string name="inline_silent_button_silent" msgid="5315879183296940969">"サイレント"</string>
     <string name="inline_silent_button_stay_silent" msgid="6308371431217601009">"音なしで通知"</string>
-    <!-- no translation found for inline_silent_button_alert (6008435419895088034) -->
-    <skip />
+    <string name="inline_silent_button_alert" msgid="6008435419895088034">"アラートを受け取る"</string>
     <string name="inline_silent_button_keep_alerting" msgid="327696842264359693">"今後もアラートを受け取る"</string>
     <string name="inline_turn_off_notifications" msgid="8635596135532202355">"通知を OFF にする"</string>
     <string name="inline_keep_showing_app" msgid="1723113469580031041">"このアプリからの通知を今後も表示しますか?"</string>
-    <string name="notification_silence_title" msgid="7352089096356977930">"通知音なし"</string>
-    <string name="notification_alert_title" msgid="3966526305405016221">"優先"</string>
-    <string name="notification_channel_summary_low" msgid="1065819618107531284">"プルダウン シェードでのみ通知を確認できます。常に通知音は鳴りません。"</string>
-    <string name="notification_channel_summary_low_status" msgid="2702170424808743755">"優先度の低い通知を表示します。常に通知音は鳴りません。"</string>
-    <string name="notification_channel_summary_low_lock" msgid="7966605244472624458">"優先度の低い通知を表示します。常に通知音は鳴りません。"</string>
-    <string name="notification_channel_summary_low_status_lock" msgid="7012562768950012739">"優先度の低い通知を表示します。常に通知音は鳴りません。"</string>
-    <string name="notification_channel_summary_default" msgid="3847289783382316019">"通知音とステータスバーのアイコンで注意を促します。ロック画面に表示されます。"</string>
+    <string name="notification_silence_title" msgid="5763240612242137433">"サイレント"</string>
+    <string name="notification_alert_title" msgid="8031196611815490340">"アラートを受け取る"</string>
+    <string name="notification_channel_summary_low" msgid="3387466082089715555">"音やバイブレーションが作動しないため、通知に煩わされずに済みます。"</string>
+    <string name="notification_channel_summary_default" msgid="5994062840431965586">"音やバイブレーションで通知をお知らせします。"</string>
     <string name="notification_unblockable_desc" msgid="4556908766584964102">"これらの通知は変更できません。"</string>
     <string name="notification_multichannel_desc" msgid="4695920306092240550">"このグループの通知はここでは設定できません"</string>
     <string name="notification_delegate_header" msgid="2857691673814814270">"代理通知"</string>
@@ -908,8 +900,7 @@
     <string name="slice_permission_allow" msgid="2340244901366722709">"許可"</string>
     <string name="slice_permission_deny" msgid="7683681514008048807">"拒否"</string>
     <string name="auto_saver_title" msgid="1217959994732964228">"タップしてバッテリー セーバーのスケジュールを設定"</string>
-    <!-- no translation found for auto_saver_text (2563289953551438248) -->
-    <skip />
+    <string name="auto_saver_text" msgid="2563289953551438248">"電池切れになる可能性が高くなると有効になります"</string>
     <string name="no_auto_saver_action" msgid="8086002101711328500">"いいえ"</string>
     <string name="auto_saver_enabled_title" msgid="6726474226058316862">"バッテリー セーバーのスケジュール設定 ON"</string>
     <string name="auto_saver_enabled_text" msgid="874711029884777579">"電池が <xliff:g id="PERCENTAGE">%d</xliff:g>%% を下回ると、バッテリー セーバーが自動的に ON になります。"</string>
@@ -942,4 +933,6 @@
     <string name="bubble_accessibility_action_move_bottom_left" msgid="206369104473183217">"左下に移動"</string>
     <string name="bubble_accessibility_action_move_bottom_right" msgid="8705660152384312329">"右下に移動"</string>
     <string name="bubble_dismiss_text" msgid="8028337712674081668">"閉じる"</string>
+    <string name="notification_content_system_nav_changed" msgid="7218093915747788444">"システム ナビゲーションを更新しました。変更するには [設定] に移動してください。"</string>
+    <string name="notification_content_gesture_nav_available" msgid="8111130443656460792">"システム ナビゲーションを更新するには [設定] に移動してください"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-ka/strings.xml b/packages/SystemUI/res/values-ka/strings.xml
index 0cc5c5e..eec2f4b 100644
--- a/packages/SystemUI/res/values-ka/strings.xml
+++ b/packages/SystemUI/res/values-ka/strings.xml
@@ -62,12 +62,10 @@
     <string name="usb_debugging_secondary_user_title" msgid="6353808721761220421">"USB ხარვეზების გამართვა ნებადართული არაა"</string>
     <string name="usb_debugging_secondary_user_message" msgid="6067122453571699801">"ამ მოწყობილობაზე ამჟამად შესულ მომხმარებელს არ შეუძლია USB ხარვეზების გამართვის ფუნქციის ჩართვა. ამ ფუნქციის გამოსაყენებლად, მიუერთდით მთავარ მომხმარებელს."</string>
     <string name="usb_contaminant_title" msgid="206854874263058490">"USB პორტი გათიშულია"</string>
-    <!-- no translation found for usb_contaminant_message (7379089091591609111) -->
-    <skip />
+    <string name="usb_contaminant_message" msgid="7379089091591609111">"თქვენი მოწყობილობის სითხის ან ნადებისგან დასაცავად, USB პორტი გათიშულია და ვერცერთი აქსესუარის აღმოჩენას ვერ შეძლებს.\n\nთქვენ მიიღებთ შეტყობინებას, როდესაც USB პორტის გამოყენება კვლავ შესაძლებელი იქნება."</string>
     <string name="usb_port_enabled" msgid="7906141351687694867">"USB პორტი ჩართულია დამტენებისა და აქსესუარების აღმოსაჩენად"</string>
     <string name="usb_disable_contaminant_detection" msgid="2103905315747120033">"USB-ის ჩართვა"</string>
-    <!-- no translation found for learn_more (5000517160980853569) -->
-    <skip />
+    <string name="learn_more" msgid="5000517160980853569">"შეიტყვეთ მეტი"</string>
     <string name="compat_mode_on" msgid="6623839244840638213">"მასშტაბი შეცვალეთ ეკრანის შესავსებად."</string>
     <string name="compat_mode_off" msgid="4434467572461327898">"გაწიეთ ეკრანის შესავსებად."</string>
     <string name="global_action_screenshot" msgid="8329831278085426283">"ეკრანის ანაბეჭდი"</string>
@@ -199,6 +197,7 @@
     <string name="carrier_network_change_mode" msgid="8149202439957837762">"ოპერატორის ქსელის შეცვლა"</string>
     <string name="accessibility_battery_details" msgid="7645516654955025422">"ბატარეის დეტალების გახსნა"</string>
     <string name="accessibility_battery_level" msgid="7451474187113371965">"ბატარეა: <xliff:g id="NUMBER">%d</xliff:g> პროცენტი."</string>
+    <string name="accessibility_battery_level_with_estimate" msgid="9033100930684311630">"ბატარეა <xliff:g id="PERCENTAGE">%1$s</xliff:g> პროცენტზეა, მოხმარების გათვალისწინებით დარჩა დაახლოებით <xliff:g id="TIME">%2$s</xliff:g>"</string>
     <string name="accessibility_battery_level_charging" msgid="1147587904439319646">"ბატარეა იტენება, <xliff:g id="BATTERY_PERCENTAGE">%d</xliff:g> %%."</string>
     <string name="accessibility_settings_button" msgid="799583911231893380">"სისტემის პარამეტრები."</string>
     <string name="accessibility_notifications_button" msgid="4498000369779421892">"შეტყობინებები"</string>
@@ -458,10 +457,8 @@
     <string name="media_projection_remember_text" msgid="3103510882172746752">"აღარ მაჩვენო"</string>
     <string name="clear_all_notifications_text" msgid="814192889771462828">"ყველას გასუფთავება"</string>
     <string name="manage_notifications_text" msgid="2386728145475108753">"მართვა"</string>
-    <!-- no translation found for notification_section_header_gentle (4372438504154095677) -->
-    <skip />
-    <!-- no translation found for accessibility_notification_section_header_gentle_clear_all (4286716295850400959) -->
-    <skip />
+    <string name="notification_section_header_gentle" msgid="4372438504154095677">"ჩუმი შეტყობინებები"</string>
+    <string name="accessibility_notification_section_header_gentle_clear_all" msgid="4286716295850400959">"ყველა ჩუმი შეტყობინების გასუფთავება"</string>
     <string name="dnd_suppressing_shade_text" msgid="1904574852846769301">"შეტყობინებები დაპაუზდა „არ შემაწუხოთ“ რეჟიმის მეშვეობით"</string>
     <string name="media_projection_action_text" msgid="8470872969457985954">"დაწყება ახლავე"</string>
     <string name="empty_shade_text" msgid="708135716272867002">"შეტყობინებები არ არის."</string>
@@ -645,21 +642,16 @@
     <string name="inline_block_button" msgid="8735843688021655065">"დაბლოკვა"</string>
     <string name="inline_keep_button" msgid="6665940297019018232">"ჩვენების გაგრძელება"</string>
     <string name="inline_minimize_button" msgid="966233327974702195">"ჩაკეცვა"</string>
-    <!-- no translation found for inline_silent_button_silent (5315879183296940969) -->
-    <skip />
+    <string name="inline_silent_button_silent" msgid="5315879183296940969">"ჩუმი"</string>
     <string name="inline_silent_button_stay_silent" msgid="6308371431217601009">"კვლავ ჩუმად ჩვენება"</string>
-    <!-- no translation found for inline_silent_button_alert (6008435419895088034) -->
-    <skip />
+    <string name="inline_silent_button_alert" msgid="6008435419895088034">"გაფრთხილება"</string>
     <string name="inline_silent_button_keep_alerting" msgid="327696842264359693">"გაფრთხილების გაგრძელება"</string>
     <string name="inline_turn_off_notifications" msgid="8635596135532202355">"შეტყობინებების გამორთვა"</string>
     <string name="inline_keep_showing_app" msgid="1723113469580031041">"გაგრძელდეს შეტყობინებათა ჩვენება ამ აპიდან?"</string>
-    <string name="notification_silence_title" msgid="7352089096356977930">"მსუბუქი"</string>
-    <string name="notification_alert_title" msgid="3966526305405016221">"პრიორიტეტული"</string>
-    <string name="notification_channel_summary_low" msgid="1065819618107531284">"გეხმარებათ იმ შეტყობინებებზე ყურადღების გამახვილებაში, რომლებიც ჩამოსაწევ ფარდაში ჩანს. ყოველთვის ჩუმი."</string>
-    <string name="notification_channel_summary_low_status" msgid="2702170424808743755">"აჩვენებს ნაკლებად პრიორიტეტულ შეტყობინებებს. ყოველთვის ჩუმი."</string>
-    <string name="notification_channel_summary_low_lock" msgid="7966605244472624458">"აჩვენებს ნაკლებად პრიორიტეტულ შეტყობინებებს. ყოველთვის ჩუმი."</string>
-    <string name="notification_channel_summary_low_status_lock" msgid="7012562768950012739">"აჩვენებს ნაკლებად პრიორიტეტულ შეტყობინებებს. ყოველთვის ჩუმი."</string>
-    <string name="notification_channel_summary_default" msgid="3847289783382316019">"იქცევს თქვენს ყურადღებას ხმით &amp; სტატუსის ზოლის ხატულით. ჩნდება ჩაკეტილ ეკრანზე."</string>
+    <string name="notification_silence_title" msgid="5763240612242137433">"ჩუმი"</string>
+    <string name="notification_alert_title" msgid="8031196611815490340">"გამაფრთხილებელი"</string>
+    <string name="notification_channel_summary_low" msgid="3387466082089715555">"გეხმარებათ ფოკუსირებაში ხმის ან ვიბრაციის უქონლობის გამო."</string>
+    <string name="notification_channel_summary_default" msgid="5994062840431965586">"იპყრობს თქვენს ყურადღებას ხმით ან ვიბრაციით."</string>
     <string name="notification_unblockable_desc" msgid="4556908766584964102">"ამ შეტყობინებების შეცვლა შეუძლებელია."</string>
     <string name="notification_multichannel_desc" msgid="4695920306092240550">"შეტყობინებების ამ ჯგუფის კონფიგურირება აქ შეუძლებელია"</string>
     <string name="notification_delegate_header" msgid="2857691673814814270">"პროქსირებული შეტყობინება"</string>
@@ -908,8 +900,7 @@
     <string name="slice_permission_allow" msgid="2340244901366722709">"დაშვება"</string>
     <string name="slice_permission_deny" msgid="7683681514008048807">"უარყოფა"</string>
     <string name="auto_saver_title" msgid="1217959994732964228">"შეეხეთ ბატარეის დამზოგის დასაგეგმად"</string>
-    <!-- no translation found for auto_saver_text (2563289953551438248) -->
-    <skip />
+    <string name="auto_saver_text" msgid="2563289953551438248">"ჩაირთოს, როცა ბატარეა დაცლის პირას არის"</string>
     <string name="no_auto_saver_action" msgid="8086002101711328500">"არა, გმადლობთ"</string>
     <string name="auto_saver_enabled_title" msgid="6726474226058316862">"ბატარეის დამზოგის განრიგი ჩართულია"</string>
     <string name="auto_saver_enabled_text" msgid="874711029884777579">"ბატარეის დამზოგი ავტომატურად ჩაირთვება, როცა ბატარეა ჩამოსცდება <xliff:g id="PERCENTAGE">%d</xliff:g>%%-ს."</string>
@@ -942,4 +933,6 @@
     <string name="bubble_accessibility_action_move_bottom_left" msgid="206369104473183217">"ქვევით და მარცხნივ გადატანა"</string>
     <string name="bubble_accessibility_action_move_bottom_right" msgid="8705660152384312329">"გადაანაცვ. ქვემოთ და მარჯვნივ"</string>
     <string name="bubble_dismiss_text" msgid="8028337712674081668">"დახურვა"</string>
+    <string name="notification_content_system_nav_changed" msgid="7218093915747788444">"სისტემური ნავიგაცია განახლდა. ცვლილებების შესატანად გადადით პარამეტრებზე."</string>
+    <string name="notification_content_gesture_nav_available" msgid="8111130443656460792">"სისტემური ნავიგაციის გასაახლებლად გადადით პარამეტრებზე"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-kk/strings.xml b/packages/SystemUI/res/values-kk/strings.xml
index bb14876..bdb03bc 100644
--- a/packages/SystemUI/res/values-kk/strings.xml
+++ b/packages/SystemUI/res/values-kk/strings.xml
@@ -62,12 +62,10 @@
     <string name="usb_debugging_secondary_user_title" msgid="6353808721761220421">"USB жөндеу рұқсат етілмеген"</string>
     <string name="usb_debugging_secondary_user_message" msgid="6067122453571699801">"Бұл құрылғыға жаңа кірген пайдаланушы USB түзетуін іске қосылмайды. Бұл мүмкіндікті пайдалану үшін негізгі пайдаланушыға ауысыңыз."</string>
     <string name="usb_contaminant_title" msgid="206854874263058490">"USB порты өшірілді"</string>
-    <!-- no translation found for usb_contaminant_message (7379089091591609111) -->
-    <skip />
+    <string name="usb_contaminant_message" msgid="7379089091591609111">"Құрылғыңызға сұйықтық немесе қоқыс кіріп кетпеуі үшін, USB порты өшірілген және ешқандай керек-жарақты анықтамайды.\n\nUSB портын қайта пайдалануға болатын кезде хабарландыру аласыз."</string>
     <string name="usb_port_enabled" msgid="7906141351687694867">"Зарядтағыштар мен аксессуарларды анықтау үшін USB порты қосылды."</string>
     <string name="usb_disable_contaminant_detection" msgid="2103905315747120033">"USB қосу"</string>
-    <!-- no translation found for learn_more (5000517160980853569) -->
-    <skip />
+    <string name="learn_more" msgid="5000517160980853569">"Толығырақ"</string>
     <string name="compat_mode_on" msgid="6623839244840638213">"Экранды толтыру үшін ұлғайту"</string>
     <string name="compat_mode_off" msgid="4434467572461327898">"Экранды толтыру үшін созу"</string>
     <string name="global_action_screenshot" msgid="8329831278085426283">"Скриншот"</string>
@@ -199,6 +197,7 @@
     <string name="carrier_network_change_mode" msgid="8149202439957837762">"Оператор желісін өзгерту"</string>
     <string name="accessibility_battery_details" msgid="7645516654955025422">"Батарея мәліметтерін ашу"</string>
     <string name="accessibility_battery_level" msgid="7451474187113371965">"Батарея <xliff:g id="NUMBER">%d</xliff:g> пайыз."</string>
+    <string name="accessibility_battery_level_with_estimate" msgid="9033100930684311630">"Батарея заряды: <xliff:g id="PERCENTAGE">%1$s</xliff:g> пайыз. Пайдалануға байланысты шамамен <xliff:g id="TIME">%2$s</xliff:g> уақытқа жетеді."</string>
     <string name="accessibility_battery_level_charging" msgid="1147587904439319646">"Батарея зарядталуда, <xliff:g id="BATTERY_PERCENTAGE">%d</xliff:g> %%."</string>
     <string name="accessibility_settings_button" msgid="799583911231893380">"Жүйе параметрлері."</string>
     <string name="accessibility_notifications_button" msgid="4498000369779421892">"Хабарлар."</string>
@@ -458,10 +457,8 @@
     <string name="media_projection_remember_text" msgid="3103510882172746752">"Қайта көрсетпеу"</string>
     <string name="clear_all_notifications_text" msgid="814192889771462828">"Барлығын тазалау"</string>
     <string name="manage_notifications_text" msgid="2386728145475108753">"Басқару"</string>
-    <!-- no translation found for notification_section_header_gentle (4372438504154095677) -->
-    <skip />
-    <!-- no translation found for accessibility_notification_section_header_gentle_clear_all (4286716295850400959) -->
-    <skip />
+    <string name="notification_section_header_gentle" msgid="4372438504154095677">"Дыбыссыз хабарландырулар"</string>
+    <string name="accessibility_notification_section_header_gentle_clear_all" msgid="4286716295850400959">"Барлық дыбыссыз хабарландыруларды өшіру"</string>
     <string name="dnd_suppressing_shade_text" msgid="1904574852846769301">"Хабарландырулар \"Мазаламау\" режимінде кідіртілді"</string>
     <string name="media_projection_action_text" msgid="8470872969457985954">"Қазір бастау"</string>
     <string name="empty_shade_text" msgid="708135716272867002">"Хабарландырулар жоқ"</string>
@@ -645,21 +642,16 @@
     <string name="inline_block_button" msgid="8735843688021655065">"Бөгеу"</string>
     <string name="inline_keep_button" msgid="6665940297019018232">"Көрсету"</string>
     <string name="inline_minimize_button" msgid="966233327974702195">"Жасыру"</string>
-    <!-- no translation found for inline_silent_button_silent (5315879183296940969) -->
-    <skip />
+    <string name="inline_silent_button_silent" msgid="5315879183296940969">"Дыбыссыз"</string>
     <string name="inline_silent_button_stay_silent" msgid="6308371431217601009">"Хабарландырулар алғым келмейді"</string>
-    <!-- no translation found for inline_silent_button_alert (6008435419895088034) -->
-    <skip />
+    <string name="inline_silent_button_alert" msgid="6008435419895088034">"Ескерту"</string>
     <string name="inline_silent_button_keep_alerting" msgid="327696842264359693">"Хабарландырулар келе берсін"</string>
     <string name="inline_turn_off_notifications" msgid="8635596135532202355">"Хабарландыруларды өшіру"</string>
     <string name="inline_keep_showing_app" msgid="1723113469580031041">"Осы қолданбаның хабарландырулары көрсетілсін бе?"</string>
-    <string name="notification_silence_title" msgid="7352089096356977930">"Дыбыссыз"</string>
-    <string name="notification_alert_title" msgid="3966526305405016221">"Маңызды"</string>
-    <string name="notification_channel_summary_low" msgid="1065819618107531284">"Ашылмалы панельдегі хабарландырулар ғана көрсетіледі. Үнемі дыбыссыз режимде болады."</string>
-    <string name="notification_channel_summary_low_status" msgid="2702170424808743755">"Маңыздылығы төмен хабарландыруларды көрсетеді. Үнемі дыбыссыз режимде болады."</string>
-    <string name="notification_channel_summary_low_lock" msgid="7966605244472624458">"Маңыздылығы төмен хабарландыруларды көрсетеді. Үнемі дыбыссыз режимде болады."</string>
-    <string name="notification_channel_summary_low_status_lock" msgid="7012562768950012739">"Маңыздылығы төмен хабарландыруларды көрсетеді. Үнемі дыбыссыз режимде болады."</string>
-    <string name="notification_channel_summary_default" msgid="3847289783382316019">"Дыбыс және күй жолағы белгішесі арқылы ескертеді. Құлыптаулы экранда көрсетіледі."</string>
+    <string name="notification_silence_title" msgid="5763240612242137433">"Дыбыссыз"</string>
+    <string name="notification_alert_title" msgid="8031196611815490340">"Ескертулер"</string>
+    <string name="notification_channel_summary_low" msgid="3387466082089715555">"Хабарландырулар келгенде, дыбыс шықпайды не дірілдемейді"</string>
+    <string name="notification_channel_summary_default" msgid="5994062840431965586">"Хабарландырулар келгенде, дыбыс шығады не дірілдейді"</string>
     <string name="notification_unblockable_desc" msgid="4556908766584964102">"Бұл хабарландыруларды өзгерту мүмкін емес."</string>
     <string name="notification_multichannel_desc" msgid="4695920306092240550">"Мұндай хабарландырулар бұл жерде конфигурацияланбайды."</string>
     <string name="notification_delegate_header" msgid="2857691673814814270">"Прокси-сервер арқылы жіберілген хабарландыру"</string>
@@ -908,8 +900,7 @@
     <string name="slice_permission_allow" msgid="2340244901366722709">"Рұқсат беру"</string>
     <string name="slice_permission_deny" msgid="7683681514008048807">"Тыйым салу"</string>
     <string name="auto_saver_title" msgid="1217959994732964228">"Түймені түртіп, Battery Saver функциясын реттеңіз"</string>
-    <!-- no translation found for auto_saver_text (2563289953551438248) -->
-    <skip />
+    <string name="auto_saver_text" msgid="2563289953551438248">"Батареяның заряды бітуге жақындағанда қосыңыз."</string>
     <string name="no_auto_saver_action" msgid="8086002101711328500">"Жоқ, рақмет"</string>
     <string name="auto_saver_enabled_title" msgid="6726474226058316862">"Battery Saver кестесі қосылды"</string>
     <string name="auto_saver_enabled_text" msgid="874711029884777579">"Батарея заряды <xliff:g id="PERCENTAGE">%d</xliff:g>%% деңгейінен төмендегенде, Battery Saver автоматты түрде қосылады."</string>
@@ -942,4 +933,6 @@
     <string name="bubble_accessibility_action_move_bottom_left" msgid="206369104473183217">"Төменгі сол жаққа жылжыту"</string>
     <string name="bubble_accessibility_action_move_bottom_right" msgid="8705660152384312329">"Төменгі оң жаққа жылжыту"</string>
     <string name="bubble_dismiss_text" msgid="8028337712674081668">"Жабу"</string>
+    <string name="notification_content_system_nav_changed" msgid="7218093915747788444">"Жүйе навигациясы жаңартылды. Өзгерту енгізу үшін \"Параметрлер\" бөліміне өтіңіз."</string>
+    <string name="notification_content_gesture_nav_available" msgid="8111130443656460792">"Жүйе навигациясын жаңарту үшін \"Параметрлер\" бөліміне өтіңіз."</string>
 </resources>
diff --git a/packages/SystemUI/res/values-km/strings.xml b/packages/SystemUI/res/values-km/strings.xml
index 2c42f6a..13a0f1f 100644
--- a/packages/SystemUI/res/values-km/strings.xml
+++ b/packages/SystemUI/res/values-km/strings.xml
@@ -62,12 +62,10 @@
     <string name="usb_debugging_secondary_user_title" msgid="6353808721761220421">"មិនអនុញ្ញាតការកែកំហុសតាម USB ទេ"</string>
     <string name="usb_debugging_secondary_user_message" msgid="6067122453571699801">"អ្នកប្រើ​ដែលបច្ចុប្បន្ន​បានចូលគណនី​នៅលើឧបករណ៍នេះ​មិនអាចបើកការកែកំហុស USB បានទេ។ ដើម្បីប្រើមុខងារនេះ សូមប្តូរទៅអ្នកប្រើចម្បង។"</string>
     <string name="usb_contaminant_title" msgid="206854874263058490">"បានបិទរន្ធ USB"</string>
-    <!-- no translation found for usb_contaminant_message (7379089091591609111) -->
-    <skip />
+    <string name="usb_contaminant_message" msgid="7379089091591609111">"ដើម្បី​ការពារ​ឧបករណ៍​របស់អ្នកកុំឱ្យ​ចូលទឹក ឬ​កម្ទេចផ្សេងៗ រន្ធ USB ត្រូវបានបិទ ហើយ​នឹង​មិនស្គាល់​គ្រឿង​បរិក្ខារ​នោះទេ។\n\nអ្នកនឹង​ទទួលបាន​ការជូនដំណឺង នៅពេល​អ្នកអាច​ប្រើប្រាស់​រន្ធ USB ម្ដងទៀត។"</string>
     <string name="usb_port_enabled" msgid="7906141351687694867">"បាន​បើក​រន្ធ USB ដើម្បី​សម្គាល់​ឆ្នាំងសាក និងគ្រឿងផ្សេងៗ"</string>
     <string name="usb_disable_contaminant_detection" msgid="2103905315747120033">"បើក USB"</string>
-    <!-- no translation found for learn_more (5000517160980853569) -->
-    <skip />
+    <string name="learn_more" msgid="5000517160980853569">"ស្វែងយល់​បន្ថែម"</string>
     <string name="compat_mode_on" msgid="6623839244840638213">"ពង្រីក​​ដើម្បី​ឲ្យ​ពេញ​អេក្រង់"</string>
     <string name="compat_mode_off" msgid="4434467572461327898">"ទាញ​ដើម្បី​ឲ្យ​ពេញ​អេក្រង់"</string>
     <string name="global_action_screenshot" msgid="8329831278085426283">"រូបថតអេក្រង់"</string>
@@ -199,6 +197,7 @@
     <string name="carrier_network_change_mode" msgid="8149202439957837762">"បណ្តាញ​ក្រុមហ៊ុនសេវាទូរសព្ទ​កំពុងផ្លាស់ប្តូរ"</string>
     <string name="accessibility_battery_details" msgid="7645516654955025422">"បើកព័ត៌មានលម្អិតអំពីថ្ម"</string>
     <string name="accessibility_battery_level" msgid="7451474187113371965">"ថ្ម <xliff:g id="NUMBER">%d</xliff:g> ភាគរយ។"</string>
+    <string name="accessibility_battery_level_with_estimate" msgid="9033100930684311630">"ថ្ម <xliff:g id="PERCENTAGE">%1$s</xliff:g> ភាគរយ អាចប្រើបាន​ប្រហែល <xliff:g id="TIME">%2$s</xliff:g> ទៀត ផ្អែក​លើការ​ប្រើប្រាស់​របស់អ្នក"</string>
     <string name="accessibility_battery_level_charging" msgid="1147587904439319646">"កំពុងសាកថ្ម <xliff:g id="BATTERY_PERCENTAGE">%d</xliff:g> ភាគរយ"</string>
     <string name="accessibility_settings_button" msgid="799583911231893380">"ការ​កំណត់​ប្រព័ន្ធ​។"</string>
     <string name="accessibility_notifications_button" msgid="4498000369779421892">"ការ​ជូន​ដំណឹង។"</string>
@@ -458,10 +457,8 @@
     <string name="media_projection_remember_text" msgid="3103510882172746752">"កុំ​បង្ហាញ​ម្ដងទៀត"</string>
     <string name="clear_all_notifications_text" msgid="814192889771462828">"សម្អាត​ទាំងអស់"</string>
     <string name="manage_notifications_text" msgid="2386728145475108753">"គ្រប់គ្រង"</string>
-    <!-- no translation found for notification_section_header_gentle (4372438504154095677) -->
-    <skip />
-    <!-- no translation found for accessibility_notification_section_header_gentle_clear_all (4286716295850400959) -->
-    <skip />
+    <string name="notification_section_header_gentle" msgid="4372438504154095677">"ការជូនដំណឹង​ស្ងាត់"</string>
+    <string name="accessibility_notification_section_header_gentle_clear_all" msgid="4286716295850400959">"សម្អាត​ការជូនដំណឹង​ស្ងាត់ទាំងអស់"</string>
     <string name="dnd_suppressing_shade_text" msgid="1904574852846769301">"ការជូនដំណឹង​បានផ្អាក​ដោយ​មុខងារកុំរំខាន"</string>
     <string name="media_projection_action_text" msgid="8470872969457985954">"ចាប់ផ្ដើម​ឥឡូវ"</string>
     <string name="empty_shade_text" msgid="708135716272867002">"គ្មាន​ការ​ជូនដំណឹង"</string>
@@ -645,21 +642,16 @@
     <string name="inline_block_button" msgid="8735843688021655065">"ទប់ស្កាត់"</string>
     <string name="inline_keep_button" msgid="6665940297019018232">"បន្ត​បង្ហាញ"</string>
     <string name="inline_minimize_button" msgid="966233327974702195">"បង្រួម"</string>
-    <!-- no translation found for inline_silent_button_silent (5315879183296940969) -->
-    <skip />
+    <string name="inline_silent_button_silent" msgid="5315879183296940969">"ស្ងាត់"</string>
     <string name="inline_silent_button_stay_silent" msgid="6308371431217601009">"បន្ត​បិទសំឡេង"</string>
-    <!-- no translation found for inline_silent_button_alert (6008435419895088034) -->
-    <skip />
+    <string name="inline_silent_button_alert" msgid="6008435419895088034">"ការជូនដំណឹង"</string>
     <string name="inline_silent_button_keep_alerting" msgid="327696842264359693">"បន្ត​ជូនដំណឹង"</string>
     <string name="inline_turn_off_notifications" msgid="8635596135532202355">"បិទ​ការជូន​ដំណឹង"</string>
     <string name="inline_keep_showing_app" msgid="1723113469580031041">"បន្ត​បង្ហាញ​ការជូនដំណឹង​ពីកម្មវិធីនេះ?"</string>
-    <string name="notification_silence_title" msgid="7352089096356977930">"ស្ងាត់ៗ"</string>
-    <string name="notification_alert_title" msgid="3966526305405016221">"ជា​អាទិភាព"</string>
-    <string name="notification_channel_summary_low" msgid="1065819618107531284">"ជួយ​ឱ្យអ្នក​ផ្ដោត​តាមរយៈការជូនដំណឹង​តែនៅក្នុង​ផ្ទាំងជូនដំណឹងធ្លាក់ចុះ​ប៉ុណ្ណោះ។ បិទសំឡេង​ជានិច្ច។"</string>
-    <string name="notification_channel_summary_low_status" msgid="2702170424808743755">"បង្ហាញ​ការជូនដំណឹង​អាទិភាព​ខាងក្រោម។ បិទសំឡេង​ជានិច្ច។"</string>
-    <string name="notification_channel_summary_low_lock" msgid="7966605244472624458">"បង្ហាញ​ការជូនដំណឹង​អាទិភាព​ខាងក្រោម។ បិទសំឡេង​ជានិច្ច។"</string>
-    <string name="notification_channel_summary_low_status_lock" msgid="7012562768950012739">"បង្ហាញ​ការជូនដំណឹង​អាទិភាព​ខាងក្រោម។ បិទសំឡេង​ជានិច្ច។"</string>
-    <string name="notification_channel_summary_default" msgid="3847289783382316019">"ធ្វើឱ្យអ្នកចាប់អារម្មណ៍តាមរយៈ​សំឡេង និងរូបរបារស្ថានភាព។ បង្ហាញ​នៅលើ​អេក្រង់ចាក់សោ។"</string>
+    <string name="notification_silence_title" msgid="5763240612242137433">"ស្ងាត់"</string>
+    <string name="notification_alert_title" msgid="8031196611815490340">"បញ្ចេញ​សំឡេង"</string>
+    <string name="notification_channel_summary_low" msgid="3387466082089715555">"ជួយឱ្យ​អ្នក​ផ្តោតអារម្មណ៍ ដោយមិនឮសំឡេង ឬ​ការញ័រ។"</string>
+    <string name="notification_channel_summary_default" msgid="5994062840431965586">"ធ្វើឱ្យ​អ្នក​ចាប់អារម្មណ៍​តាមរយៈ​សំឡេង ឬ​ការញ័រ។"</string>
     <string name="notification_unblockable_desc" msgid="4556908766584964102">"មិនអាច​កែប្រែ​ការជូនដំណឹង​ទាំងនេះ​បានទេ។"</string>
     <string name="notification_multichannel_desc" msgid="4695920306092240550">"មិនអាច​កំណត់​រចនាសម្ព័ន្ធ​ក្រុមការជូនដំណឹងនេះ​នៅទីនេះ​បានទេ"</string>
     <string name="notification_delegate_header" msgid="2857691673814814270">"ការជូនដំណឹង​ជា​ប្រូកស៊ី"</string>
@@ -908,8 +900,7 @@
     <string name="slice_permission_allow" msgid="2340244901366722709">"អនុញ្ញាត"</string>
     <string name="slice_permission_deny" msgid="7683681514008048807">"បដិសេធ"</string>
     <string name="auto_saver_title" msgid="1217959994732964228">"ចុច​ដើម្បី​កំណត់​កាលវិភាគ​កម្មវិធី​សន្សំ​ថ្ម"</string>
-    <!-- no translation found for auto_saver_text (2563289953551438248) -->
-    <skip />
+    <string name="auto_saver_text" msgid="2563289953551438248">"បើក​នៅពេល​ថ្ម​ទំនងជា​អស់"</string>
     <string name="no_auto_saver_action" msgid="8086002101711328500">"ទេ អរគុណ"</string>
     <string name="auto_saver_enabled_title" msgid="6726474226058316862">"កាលវិភាគ​កម្មវិធី​សន្សំ​ថ្ម​បាន​បើក​ហើយ"</string>
     <string name="auto_saver_enabled_text" msgid="874711029884777579">"កម្មវិធី​សន្សំ​ថ្ម​នឹង​បើក​ដោយ​ស្វ័យ​ប្រវត្តិ​ នៅពេល​ថ្ម​នៅ​សល់​តិច​ជាង <xliff:g id="PERCENTAGE">%d</xliff:g>%% ។"</string>
@@ -942,4 +933,6 @@
     <string name="bubble_accessibility_action_move_bottom_left" msgid="206369104473183217">"ផ្លាស់ទីទៅផ្នែកខាងក្រោមខាងឆ្វេង​"</string>
     <string name="bubble_accessibility_action_move_bottom_right" msgid="8705660152384312329">"ផ្លាស់ទីទៅផ្នែកខាងក្រោម​ខាងស្ដាំ"</string>
     <string name="bubble_dismiss_text" msgid="8028337712674081668">"ច្រានចោល"</string>
+    <string name="notification_content_system_nav_changed" msgid="7218093915747788444">"បានធ្វើ​បច្ចុប្បន្នភាព​ការរុករកក្នុង​ប្រព័ន្ធ។ ដើម្បីធ្វើការផ្លាស់ប្ដូរ សូមចូលទៅ​កាន់ការកំណត់។"</string>
+    <string name="notification_content_gesture_nav_available" msgid="8111130443656460792">"ចូល​ទៅកាន់​ការកំណត់ ដើម្បី​ធ្វើបច្ចុប្បន្នភាព​ការរុករក​ក្នុង​ប្រព័ន្ធ"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-kn/strings.xml b/packages/SystemUI/res/values-kn/strings.xml
index f14998d..63d9680 100644
--- a/packages/SystemUI/res/values-kn/strings.xml
+++ b/packages/SystemUI/res/values-kn/strings.xml
@@ -197,6 +197,7 @@
     <string name="carrier_network_change_mode" msgid="8149202439957837762">"ವಾಹಕ ನೆಟ್‌ವರ್ಕ್ ಬದಲಾಯಿಸುವಿಕೆ"</string>
     <string name="accessibility_battery_details" msgid="7645516654955025422">"ಬ್ಯಾಟರಿ ವಿವರಗಳನ್ನು ತೆರೆಯಿರಿ"</string>
     <string name="accessibility_battery_level" msgid="7451474187113371965">"ಬ್ಯಾಟರಿ <xliff:g id="NUMBER">%d</xliff:g> ಪ್ರತಿಶತ."</string>
+    <string name="accessibility_battery_level_with_estimate" msgid="9033100930684311630">"ನಿಮ್ಮ ಬಳಕೆಯ ಆಧಾರದ ಮೇಲೆ ಬ್ಯಾಟರಿಯು ಪ್ರತಿಶತ <xliff:g id="PERCENTAGE">%1$s</xliff:g> ರಷ್ಟು ಮತ್ತು <xliff:g id="TIME">%2$s</xliff:g> ಸಮಯ ಬಾಕಿ ಉಳಿದಿದೆ"</string>
     <string name="accessibility_battery_level_charging" msgid="1147587904439319646">"ಬ್ಯಾಟರಿ <xliff:g id="BATTERY_PERCENTAGE">%d</xliff:g> ಪ್ರತಿಶತ ಚಾರ್ಜ್ ಆಗುತ್ತಿದೆ."</string>
     <string name="accessibility_settings_button" msgid="799583911231893380">"ಸಿಸ್ಟಂ ಸೆಟ್ಟಿಂಗ್‌ಗಳು."</string>
     <string name="accessibility_notifications_button" msgid="4498000369779421892">"ಅಧಿಸೂಚನೆಗಳು."</string>
@@ -647,13 +648,10 @@
     <string name="inline_silent_button_keep_alerting" msgid="327696842264359693">"ಎಚ್ಚರಿಸುತ್ತಿರಿ"</string>
     <string name="inline_turn_off_notifications" msgid="8635596135532202355">"ಅಧಿಸೂಚನೆಗಳನ್ನು ಆಫ್ ಮಾಡಿ"</string>
     <string name="inline_keep_showing_app" msgid="1723113469580031041">"ಈ ಅಪ್ಲಿಕೇಶನ್‌ನಿಂದ ಅಧಿಸೂಚನೆಗಳನ್ನು ತೋರಿಸುತ್ತಲೇ ಇರಬೇಕೆ?"</string>
-    <string name="notification_silence_title" msgid="7352089096356977930">"ಸಾಮಾನ್ಯ"</string>
-    <string name="notification_alert_title" msgid="3966526305405016221">"ಆದ್ಯತೆಗೊಳಿಸಿದ"</string>
-    <string name="notification_channel_summary_low" msgid="1065819618107531284">"ಪುಲ್-ಡೌನ್ ಶೇಡ್‌ನಲ್ಲಿರುವ ಅಧಿಸೂಚನೆಗಳ ಕಡೆಗೆ ಮಾತ್ರ ಗಮನಹರಿಸಲು ಸಹಾಯ ಮಾಡುತ್ತದೆ. ಯಾವಾಗಲೂ ನಿಶ್ಯಬ್ದ."</string>
-    <string name="notification_channel_summary_low_status" msgid="2702170424808743755">"ಪ್ರಾಶಸ್ತ್ಯದ ಅಧಿಸೂಚನೆಗಳ ಕೆಳಗೆ ಪ್ರದರ್ಶಿತವಾಗುತ್ತದೆ. ಯಾವಾಗಲೂ ನಿಶ್ಯಬ್ದ."</string>
-    <string name="notification_channel_summary_low_lock" msgid="7966605244472624458">"ಪ್ರಾಶಸ್ತ್ಯದ ಅಧಿಸೂಚನೆಗಳ ಕೆಳಗೆ ಪ್ರದರ್ಶಿತವಾಗುತ್ತದೆ. ಯಾವಾಗಲೂ ನಿಶ್ಯಬ್ದ."</string>
-    <string name="notification_channel_summary_low_status_lock" msgid="7012562768950012739">"ಪ್ರಾಶಸ್ತ್ಯದ ಅಧಿಸೂಚನೆಗಳ ಕೆಳಗೆ ಪ್ರದರ್ಶಿತವಾಗುತ್ತದೆ. ಯಾವಾಗಲೂ ನಿಶ್ಯಬ್ದ."</string>
-    <string name="notification_channel_summary_default" msgid="3847289783382316019">"ಧ್ವನಿ ಮತ್ತು ಸ್ಥಿತಿ ಪಟ್ಟಿ ಐಕಾನ್ ಮೂಲಕ ನಿಮ್ಮ ಗಮನವನ್ನು ಸೆಳೆಯುತ್ತದೆ. ಲಾಕ್ ಸ್ಕ್ರೀನ್ ಮೇಲೆ ತೋರಿಸುತ್ತದೆ."</string>
+    <string name="notification_silence_title" msgid="5763240612242137433">"ನಿಶ್ಶಬ್ದ"</string>
+    <string name="notification_alert_title" msgid="8031196611815490340">"ಎಚ್ಚರಿಸಲಾಗುತ್ತಿದೆ"</string>
+    <string name="notification_channel_summary_low" msgid="3387466082089715555">"ಶಬ್ದ ಅಥವಾ ವೈಬ್ರೇಷನ್ ಇರದಂತೆ ನಿಮಗೆ ಗಮನಹರಿಸಲು ಸಹಾಯ ಮಾಡುತ್ತದೆ."</string>
+    <string name="notification_channel_summary_default" msgid="5994062840431965586">"ಧ್ವನಿ ಅಥವಾ ವೈಬ್ರೇಷನ್ ಮೂಲಕ ನಿಮ್ಮ ಗಮನವನ್ನು ಸೆಳೆಯುತ್ತದೆ."</string>
     <string name="notification_unblockable_desc" msgid="4556908766584964102">"ಈ ಅಧಿಸೂಚನೆಗಳನ್ನು ಮಾರ್ಪಡಿಸಲು ಸಾಧ್ಯವಿಲ್ಲ."</string>
     <string name="notification_multichannel_desc" msgid="4695920306092240550">"ಈ ಗುಂಪಿನ ಅಧಿಸೂಚನೆಗಳನ್ನು ಇಲ್ಲಿ ಕಾನ್ಫಿಗರ್‌ ಮಾಡಲಾಗಿರುವುದಿಲ್ಲ"</string>
     <string name="notification_delegate_header" msgid="2857691673814814270">"ಪ್ರಾಕ್ಸಿ ಮಾಡಿದ ಅಧಿಸೂಚನೆಗಳು"</string>
@@ -935,4 +933,6 @@
     <string name="bubble_accessibility_action_move_bottom_left" msgid="206369104473183217">"ಸ್ಕ್ರೀನ್‌ನ ಎಡ ಕೆಳಭಾಗಕ್ಕೆ ಸರಿಸಿ"</string>
     <string name="bubble_accessibility_action_move_bottom_right" msgid="8705660152384312329">"ಕೆಳಗಿನ ಬಲಭಾಗಕ್ಕೆ ಸರಿಸಿ"</string>
     <string name="bubble_dismiss_text" msgid="8028337712674081668">"ವಜಾಗೊಳಿಸಿ"</string>
+    <string name="notification_content_system_nav_changed" msgid="7218093915747788444">"ಸಿಸ್ಟಂ ನ್ಯಾವಿಗೇಷನ ಅಪ್‌ಡೇಟ್ ಮಾಡಲಾಗಿದೆ ಬದಲಾವಣೆಗಳನ್ನು ಮಾಡಲು, ಸೆಟ್ಟಿಂಗ್‌ಗಳಿಗೆ ಹೋಗಿ."</string>
+    <string name="notification_content_gesture_nav_available" msgid="8111130443656460792">"ಸಿಸ್ಟಂ ನ್ಯಾವಿಗೇಷನ್ ಅಪ್‌ಡೇಟ್ ಮಾಡಲು ಸೆಟ್ಟಿಂಗ್‌ಗಳಿಗೆ ಹೋಗಿ"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-ko/strings.xml b/packages/SystemUI/res/values-ko/strings.xml
index e40ab6f..e162fa0 100644
--- a/packages/SystemUI/res/values-ko/strings.xml
+++ b/packages/SystemUI/res/values-ko/strings.xml
@@ -62,12 +62,10 @@
     <string name="usb_debugging_secondary_user_title" msgid="6353808721761220421">"USB 디버깅이 허용되지 않음"</string>
     <string name="usb_debugging_secondary_user_message" msgid="6067122453571699801">"현재 이 기기에 로그인한 사용자는 USB 디버깅을 사용 설정할 수 없습니다. 이 기능을 사용하려면 기본 사용자로 전환하세요."</string>
     <string name="usb_contaminant_title" msgid="206854874263058490">"USB 포트 비활성화됨"</string>
-    <!-- no translation found for usb_contaminant_message (7379089091591609111) -->
-    <skip />
+    <string name="usb_contaminant_message" msgid="7379089091591609111">"기기를 액체나 이물질로부터 보호하기 위해 USB 포트가 사용 중지되었으며 액세서리를 연결할 수 없습니다.\n\nUSB 포트를 다시 안전하게 사용할 수 있게 되면 알려 드리겠습니다."</string>
     <string name="usb_port_enabled" msgid="7906141351687694867">"충전기와 액세서리를 감지할 수 있도록 USB 포트가 사용 설정됨"</string>
     <string name="usb_disable_contaminant_detection" msgid="2103905315747120033">"USB 사용"</string>
-    <!-- no translation found for learn_more (5000517160980853569) -->
-    <skip />
+    <string name="learn_more" msgid="5000517160980853569">"자세히 알아보기"</string>
     <string name="compat_mode_on" msgid="6623839244840638213">"전체화면 모드로 확대"</string>
     <string name="compat_mode_off" msgid="4434467572461327898">"전체화면 모드로 확대"</string>
     <string name="global_action_screenshot" msgid="8329831278085426283">"스크린샷"</string>
@@ -199,6 +197,7 @@
     <string name="carrier_network_change_mode" msgid="8149202439957837762">"이동통신사 네트워크 변경"</string>
     <string name="accessibility_battery_details" msgid="7645516654955025422">"배터리 세부정보 열기"</string>
     <string name="accessibility_battery_level" msgid="7451474187113371965">"배터리 <xliff:g id="NUMBER">%d</xliff:g>퍼센트"</string>
+    <string name="accessibility_battery_level_with_estimate" msgid="9033100930684311630">"배터리 <xliff:g id="PERCENTAGE">%1$s</xliff:g>퍼센트, 평소 사용량 기준 약 <xliff:g id="TIME">%2$s</xliff:g> 남음"</string>
     <string name="accessibility_battery_level_charging" msgid="1147587904439319646">"배터리 충전 중, <xliff:g id="BATTERY_PERCENTAGE">%d</xliff:g>%%입니다."</string>
     <string name="accessibility_settings_button" msgid="799583911231893380">"시스템 설정"</string>
     <string name="accessibility_notifications_button" msgid="4498000369779421892">"알림"</string>
@@ -458,10 +457,8 @@
     <string name="media_projection_remember_text" msgid="3103510882172746752">"다시 표시 안함"</string>
     <string name="clear_all_notifications_text" msgid="814192889771462828">"모두 지우기"</string>
     <string name="manage_notifications_text" msgid="2386728145475108753">"관리"</string>
-    <!-- no translation found for notification_section_header_gentle (4372438504154095677) -->
-    <skip />
-    <!-- no translation found for accessibility_notification_section_header_gentle_clear_all (4286716295850400959) -->
-    <skip />
+    <string name="notification_section_header_gentle" msgid="4372438504154095677">"무음 알림"</string>
+    <string name="accessibility_notification_section_header_gentle_clear_all" msgid="4286716295850400959">"무음 알림 모두 삭제"</string>
     <string name="dnd_suppressing_shade_text" msgid="1904574852846769301">"방해 금지 모드로 일시중지된 알림"</string>
     <string name="media_projection_action_text" msgid="8470872969457985954">"시작하기"</string>
     <string name="empty_shade_text" msgid="708135716272867002">"알림 없음"</string>
@@ -645,21 +642,16 @@
     <string name="inline_block_button" msgid="8735843688021655065">"차단"</string>
     <string name="inline_keep_button" msgid="6665940297019018232">"계속 표시하기"</string>
     <string name="inline_minimize_button" msgid="966233327974702195">"최소화"</string>
-    <!-- no translation found for inline_silent_button_silent (5315879183296940969) -->
-    <skip />
+    <string name="inline_silent_button_silent" msgid="5315879183296940969">"무음"</string>
     <string name="inline_silent_button_stay_silent" msgid="6308371431217601009">"계속 무음으로 알림"</string>
-    <!-- no translation found for inline_silent_button_alert (6008435419895088034) -->
-    <skip />
+    <string name="inline_silent_button_alert" msgid="6008435419895088034">"알림"</string>
     <string name="inline_silent_button_keep_alerting" msgid="327696842264359693">"계속 알림"</string>
     <string name="inline_turn_off_notifications" msgid="8635596135532202355">"알림 사용 중지"</string>
     <string name="inline_keep_showing_app" msgid="1723113469580031041">"이 앱의 알림을 계속 표시하시겠습니까?"</string>
-    <string name="notification_silence_title" msgid="7352089096356977930">"조용히 표시됨"</string>
-    <string name="notification_alert_title" msgid="3966526305405016221">"우선순위 지정됨"</string>
-    <string name="notification_channel_summary_low" msgid="1065819618107531284">"풀다운 창에만 알림을 표시하여 집중에 방해가 되지 않습니다. 항상 음소거됩니다."</string>
-    <string name="notification_channel_summary_low_status" msgid="2702170424808743755">"우선순위 알림 아래에 표시됩니다. 항상 음소거됩니다."</string>
-    <string name="notification_channel_summary_low_lock" msgid="7966605244472624458">"우선순위 알림 아래에 표시됩니다. 항상 음소거됩니다."</string>
-    <string name="notification_channel_summary_low_status_lock" msgid="7012562768950012739">"우선순위 알림 아래에 표시됩니다. 항상 음소거됩니다."</string>
-    <string name="notification_channel_summary_default" msgid="3847289783382316019">"소리 및 상태 표시줄 아이콘으로 주의를 끕니다. 잠금 화면에 표시됩니다."</string>
+    <string name="notification_silence_title" msgid="5763240612242137433">"무음"</string>
+    <string name="notification_alert_title" msgid="8031196611815490340">"주의를 끄는 알림"</string>
+    <string name="notification_channel_summary_low" msgid="3387466082089715555">"소리나 진동 없이 집중할 수 있도록 도와줍니다"</string>
+    <string name="notification_channel_summary_default" msgid="5994062840431965586">"소리나 진동으로 주의를 끕니다"</string>
     <string name="notification_unblockable_desc" msgid="4556908766584964102">"이 알림은 수정할 수 없습니다."</string>
     <string name="notification_multichannel_desc" msgid="4695920306092240550">"이 알림 그룹은 여기에서 설정할 수 없습니다."</string>
     <string name="notification_delegate_header" msgid="2857691673814814270">"프록시를 통한 알림"</string>
@@ -908,8 +900,7 @@
     <string name="slice_permission_allow" msgid="2340244901366722709">"허용"</string>
     <string name="slice_permission_deny" msgid="7683681514008048807">"거부"</string>
     <string name="auto_saver_title" msgid="1217959994732964228">"탭하여 절전 모드 예약"</string>
-    <!-- no translation found for auto_saver_text (2563289953551438248) -->
-    <skip />
+    <string name="auto_saver_text" msgid="2563289953551438248">"배터리가 소진될 것 같으면 사용 설정"</string>
     <string name="no_auto_saver_action" msgid="8086002101711328500">"사용 안함"</string>
     <string name="auto_saver_enabled_title" msgid="6726474226058316862">"절전 모드 예약 사용 설정됨"</string>
     <string name="auto_saver_enabled_text" msgid="874711029884777579">"배터리가 <xliff:g id="PERCENTAGE">%d</xliff:g>%% 아래로 내려가면 절전 모드가 자동으로 켜집니다."</string>
@@ -942,4 +933,6 @@
     <string name="bubble_accessibility_action_move_bottom_left" msgid="206369104473183217">"왼쪽 하단으로 이동"</string>
     <string name="bubble_accessibility_action_move_bottom_right" msgid="8705660152384312329">"오른쪽 하단으로 이동"</string>
     <string name="bubble_dismiss_text" msgid="8028337712674081668">"닫기"</string>
+    <string name="notification_content_system_nav_changed" msgid="7218093915747788444">"시스템 탐색이 업데이트되었습니다. 변경하려면 설정으로 이동하세요."</string>
+    <string name="notification_content_gesture_nav_available" msgid="8111130443656460792">"설정으로 이동하여 시스템 탐색을 업데이트하세요."</string>
 </resources>
diff --git a/packages/SystemUI/res/values-ky/strings.xml b/packages/SystemUI/res/values-ky/strings.xml
index dbeea5b..eb160f3 100644
--- a/packages/SystemUI/res/values-ky/strings.xml
+++ b/packages/SystemUI/res/values-ky/strings.xml
@@ -62,12 +62,10 @@
     <string name="usb_debugging_secondary_user_title" msgid="6353808721761220421">"USB мүчүлүштүктөрүн оңдоого уруксат жок"</string>
     <string name="usb_debugging_secondary_user_message" msgid="6067122453571699801">"Учурда бул аккаунтта USB аркылуу мүчүлүштүктөрдү оңдоо функциясын иштетүүгө болбойт. Негизги колдонуучунун аккаунтуна кириңиз."</string>
     <string name="usb_contaminant_title" msgid="206854874263058490">"USB порту өчүрүлдү"</string>
-    <!-- no translation found for usb_contaminant_message (7379089091591609111) -->
-    <skip />
+    <string name="usb_contaminant_message" msgid="7379089091591609111">"Түзмөгүңүздүн ичине суюктук же булганч нерселер кирип кетпеши үчүн USB порту өчүрүлдү. Азырынча ал аркылуу башка түзмөктөргө туташууга болбойт.\n\nUSB портун кайра колдонуу мүмкүн болгондо, билдирме аласыз."</string>
     <string name="usb_port_enabled" msgid="7906141351687694867">"Кубаттагычтарды жана аксессуарларды аныктоо үчүн USB оюкчасы иштетилди"</string>
     <string name="usb_disable_contaminant_detection" msgid="2103905315747120033">"USB’ни иштетүү"</string>
-    <!-- no translation found for learn_more (5000517160980853569) -->
-    <skip />
+    <string name="learn_more" msgid="5000517160980853569">"Кененирээк"</string>
     <string name="compat_mode_on" msgid="6623839244840638213">"Экрнд тлтр ү. чен өлч өзг"</string>
     <string name="compat_mode_off" msgid="4434467572461327898">"Экранды толтуруу ү-н чоюу"</string>
     <string name="global_action_screenshot" msgid="8329831278085426283">"Скриншот"</string>
@@ -199,6 +197,7 @@
     <string name="carrier_network_change_mode" msgid="8149202439957837762">"Байланыш оператору өзгөртүлүүдө"</string>
     <string name="accessibility_battery_details" msgid="7645516654955025422">"Батареянын чоо-жайын ачуу"</string>
     <string name="accessibility_battery_level" msgid="7451474187113371965">"Батарея <xliff:g id="NUMBER">%d</xliff:g> пайыз."</string>
+    <string name="accessibility_battery_level_with_estimate" msgid="9033100930684311630">"Батареянын деңгээли <xliff:g id="PERCENTAGE">%1$s</xliff:g> пайыз, колдонгонуңузга караганда болжол менен <xliff:g id="TIME">%2$s</xliff:g> калды"</string>
     <string name="accessibility_battery_level_charging" msgid="1147587904439319646">"Батарея кубатталууда, <xliff:g id="BATTERY_PERCENTAGE">%d</xliff:g>%%."</string>
     <string name="accessibility_settings_button" msgid="799583911231893380">"Система тууралоолору."</string>
     <string name="accessibility_notifications_button" msgid="4498000369779421892">"Билдирмелер"</string>
@@ -458,10 +457,8 @@
     <string name="media_projection_remember_text" msgid="3103510882172746752">"Экинчи көрсөтүлбөсүн"</string>
     <string name="clear_all_notifications_text" msgid="814192889771462828">"Бардыгын тазалап салуу"</string>
     <string name="manage_notifications_text" msgid="2386728145475108753">"Башкаруу"</string>
-    <!-- no translation found for notification_section_header_gentle (4372438504154095677) -->
-    <skip />
-    <!-- no translation found for accessibility_notification_section_header_gentle_clear_all (4286716295850400959) -->
-    <skip />
+    <string name="notification_section_header_gentle" msgid="4372438504154095677">"Үнсүз билдирмелер"</string>
+    <string name="accessibility_notification_section_header_gentle_clear_all" msgid="4286716295850400959">"Маанилүү эмес билдирмелердин баарын өчүрүү"</string>
     <string name="dnd_suppressing_shade_text" msgid="1904574852846769301">"\"Тынчымды алба\" режиминде билдирмелер тындырылды"</string>
     <string name="media_projection_action_text" msgid="8470872969457985954">"Азыр баштоо"</string>
     <string name="empty_shade_text" msgid="708135716272867002">"Билдирме жок"</string>
@@ -645,21 +642,16 @@
     <string name="inline_block_button" msgid="8735843688021655065">"Бөгөттөө"</string>
     <string name="inline_keep_button" msgid="6665940297019018232">"Көрсөтүлө берсин"</string>
     <string name="inline_minimize_button" msgid="966233327974702195">"Кичирейтүү"</string>
-    <!-- no translation found for inline_silent_button_silent (5315879183296940969) -->
-    <skip />
+    <string name="inline_silent_button_silent" msgid="5315879183296940969">"Үнсүз"</string>
     <string name="inline_silent_button_stay_silent" msgid="6308371431217601009">"Үнү чыкпасын"</string>
-    <!-- no translation found for inline_silent_button_alert (6008435419895088034) -->
-    <skip />
+    <string name="inline_silent_button_alert" msgid="6008435419895088034">"Билдирүү"</string>
     <string name="inline_silent_button_keep_alerting" msgid="327696842264359693">"Кабар бериле берсин"</string>
     <string name="inline_turn_off_notifications" msgid="8635596135532202355">"Билдирмелерди өчүрүү"</string>
     <string name="inline_keep_showing_app" msgid="1723113469580031041">"Бул колдонмонун эскертмелери көрсөтүлө берсинби?"</string>
-    <string name="notification_silence_title" msgid="7352089096356977930">"Маанилүү эмес"</string>
-    <string name="notification_alert_title" msgid="3966526305405016221">"Маанилүү"</string>
-    <string name="notification_channel_summary_low" msgid="1065819618107531284">"Тигинен жайгашкан экрандагы билдирмелерге гана фокустоого жардам берет. Ар дайым үнсүз."</string>
-    <string name="notification_channel_summary_low_status" msgid="2702170424808743755">"Маанилүү билдирмелердин ылдый жагында чагылдырылат. Ар дайым үнсүз."</string>
-    <string name="notification_channel_summary_low_lock" msgid="7966605244472624458">"Маанилүү билдирмелердин ылдый жагында чагылдырылат. Ар дайым үнсүз."</string>
-    <string name="notification_channel_summary_low_status_lock" msgid="7012562768950012739">"Маанилүү билдирмелердин ылдый жагында чагылдырылат. Ар дайым үнсүз."</string>
-    <string name="notification_channel_summary_default" msgid="3847289783382316019">"Билдирме келгенде атайын үн чыгат же абал тилкесинде сүрөтчө пайда болот. Билдирмелер кулпуланган экранда көрүнөт."</string>
+    <string name="notification_silence_title" msgid="5763240612242137433">"Үнсүз"</string>
+    <string name="notification_alert_title" msgid="8031196611815490340">"Шашылыш билдирме"</string>
+    <string name="notification_channel_summary_low" msgid="3387466082089715555">"Үн же дирилдөөсүз ой топтоого жардам берет."</string>
+    <string name="notification_channel_summary_default" msgid="5994062840431965586">"Үн чыгарып же дирилдеп көңүлүңүздү бурат."</string>
     <string name="notification_unblockable_desc" msgid="4556908766584964102">"Бул билдирмелерди өзгөртүүгө болбойт."</string>
     <string name="notification_multichannel_desc" msgid="4695920306092240550">"Бул билдирмелердин тобун бул жерде конфигурациялоого болбойт"</string>
     <string name="notification_delegate_header" msgid="2857691673814814270">"Прокси билдирмеси"</string>
@@ -908,8 +900,7 @@
     <string name="slice_permission_allow" msgid="2340244901366722709">"Уруксат берүү"</string>
     <string name="slice_permission_deny" msgid="7683681514008048807">"Жок"</string>
     <string name="auto_saver_title" msgid="1217959994732964228">"Батареяны үнөмдөгүчтүн тартибин жөндөө үчүн басыңыз"</string>
-    <!-- no translation found for auto_saver_text (2563289953551438248) -->
-    <skip />
+    <string name="auto_saver_text" msgid="2563289953551438248">"Батареянын кубаты түгөнүп калганда, күйгүзүлсүн"</string>
     <string name="no_auto_saver_action" msgid="8086002101711328500">"Жок, рахмат"</string>
     <string name="auto_saver_enabled_title" msgid="6726474226058316862">"Батареяны үнөмдөгүчтүн тартиби күйгүзүлдү"</string>
     <string name="auto_saver_enabled_text" msgid="874711029884777579">"Батареянын деңгээли <xliff:g id="PERCENTAGE">%d</xliff:g>%% төмөндөгөндө, Батареяны үнөмдөгүч режими автоматтык түрдө күйөт."</string>
@@ -942,4 +933,6 @@
     <string name="bubble_accessibility_action_move_bottom_left" msgid="206369104473183217">"Төмөнкү сол жакка жылдыруу"</string>
     <string name="bubble_accessibility_action_move_bottom_right" msgid="8705660152384312329">"Төмөнкү оң жакка жылдырыңыз"</string>
     <string name="bubble_dismiss_text" msgid="8028337712674081668">"Жабуу"</string>
+    <string name="notification_content_system_nav_changed" msgid="7218093915747788444">"Тутум чабыттоосу жаңыртылды. Өзгөртүү үчүн, Жөндөөлөргө өтүңүз."</string>
+    <string name="notification_content_gesture_nav_available" msgid="8111130443656460792">"Тутум чабыттоосун жаңыртуу үчүн Жөндөөлөргө өтүңүз"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-lo/strings.xml b/packages/SystemUI/res/values-lo/strings.xml
index fa1c32a..69de4fd 100644
--- a/packages/SystemUI/res/values-lo/strings.xml
+++ b/packages/SystemUI/res/values-lo/strings.xml
@@ -62,12 +62,10 @@
     <string name="usb_debugging_secondary_user_title" msgid="6353808721761220421">"ບໍ່​ອະ​ນຸ​ຍາດ​ໃຫ້​ມີ​ການ​ແກ້​ໄຂ​ບັນ​ຫາ USB"</string>
     <string name="usb_debugging_secondary_user_message" msgid="6067122453571699801">"ຜູ້ໃຊ້ທີ່ກຳລັງເຂົ້າສູ່ລະບົບອຸປະກອນຢູ່ໃນຕອນນີ້ບໍ່ສາມາດເປີດໃຊ້ການດີບັກ USB ໄດ້. ເພື່ອໃຊ້ຄຸນສົມບັດນີ້, ໃຫ້ສະຫຼັບໄປໃຊ້ຜູ້ໃຊ້ຫຼັກ."</string>
     <string name="usb_contaminant_title" msgid="206854874263058490">"ປິດການນຳໃຊ້ຜອດ USB ແລ້ວ"</string>
-    <!-- no translation found for usb_contaminant_message (7379089091591609111) -->
-    <skip />
+    <string name="usb_contaminant_message" msgid="7379089091591609111">"ເພື່ອປົກປ້ອງອຸປະກອນຂອງທ່ານຈາກຂອງແຫລວ ຫຼື ເສດດິນຕ່າງໆ, ຜອດ USB ຈຶ່ງຖືກປິດການນຳໃຊ້ ແລະ ຈະບໍ່ກວດຫາອຸປະກອນເສີມໃດໆ.\n\nທ່ານຈະໄດ້ຮັບການແຈ້ງເຕືອນເມື່ອສາມາດໃຊ້ຜອດ USB ໄດ້ອີກເທື່ອໜຶ່ງ."</string>
     <string name="usb_port_enabled" msgid="7906141351687694867">"ເປີດນຳໃຊ້ USB ແລ້ວເພື່ອກວດຫາສາຍສາກ ແລະ ອຸປະກອນເສີມ"</string>
     <string name="usb_disable_contaminant_detection" msgid="2103905315747120033">"ເປີດໃຊ້ USB"</string>
-    <!-- no translation found for learn_more (5000517160980853569) -->
-    <skip />
+    <string name="learn_more" msgid="5000517160980853569">"ສຶກສາເພີ່ມເຕີມ"</string>
     <string name="compat_mode_on" msgid="6623839244840638213">"ຊູມໃຫ້ເຕັມໜ້າຈໍ"</string>
     <string name="compat_mode_off" msgid="4434467572461327898">"ປັບໃຫ້ເຕັມໜ້າຈໍ"</string>
     <string name="global_action_screenshot" msgid="8329831278085426283">"ພາບໜ້າຈໍ"</string>
@@ -199,6 +197,7 @@
     <string name="carrier_network_change_mode" msgid="8149202439957837762">"ການປ່ຽນເຄືອຂ່າຍຜູ້ໃຫ້ບໍລິການ"</string>
     <string name="accessibility_battery_details" msgid="7645516654955025422">"ເປີດລາຍລະອຽດແບັດເຕີຣີ"</string>
     <string name="accessibility_battery_level" msgid="7451474187113371965">"ແບັດເຕີຣີ <xliff:g id="NUMBER">%d</xliff:g> ເປີເຊັນ."</string>
+    <string name="accessibility_battery_level_with_estimate" msgid="9033100930684311630">"ແບັດເຕີຣີ <xliff:g id="PERCENTAGE">%1$s</xliff:g> ເປີເຊັນ, ເຫຼືອປະມານ <xliff:g id="TIME">%2$s</xliff:g> ອ້າງອີງຈາກການນຳໃຊ້ຂອງທ່ານ"</string>
     <string name="accessibility_battery_level_charging" msgid="1147587904439319646">"ກຳລັງສາກແບັດເຕີຣີ, <xliff:g id="BATTERY_PERCENTAGE">%d</xliff:g> ເປີເຊັນ."</string>
     <string name="accessibility_settings_button" msgid="799583911231893380">"ການຕັ້ງຄ່າລະບົບ."</string>
     <string name="accessibility_notifications_button" msgid="4498000369779421892">"ການແຈ້ງເຕືອນ."</string>
@@ -458,10 +457,8 @@
     <string name="media_projection_remember_text" msgid="3103510882172746752">"ບໍ່​ຕ້ອງ​ສະ​ແດງ​ອີກ"</string>
     <string name="clear_all_notifications_text" msgid="814192889771462828">"ລຶບລ້າງທັງໝົດ"</string>
     <string name="manage_notifications_text" msgid="2386728145475108753">"ຈັດການ"</string>
-    <!-- no translation found for notification_section_header_gentle (4372438504154095677) -->
-    <skip />
-    <!-- no translation found for accessibility_notification_section_header_gentle_clear_all (4286716295850400959) -->
-    <skip />
+    <string name="notification_section_header_gentle" msgid="4372438504154095677">"ການແຈ້ງເຕືອນແບບງຽບ"</string>
+    <string name="accessibility_notification_section_header_gentle_clear_all" msgid="4286716295850400959">"ລຶບລ້າງການແຈ້ງເຕືອນແບບງຽບທັງໝົດ"</string>
     <string name="dnd_suppressing_shade_text" msgid="1904574852846769301">"ຢຸດການແຈ້ງເຕືອນໂດຍໂໝດຫ້າມລົບກວນແລ້ວ"</string>
     <string name="media_projection_action_text" msgid="8470872969457985954">"ເລີ່ມດຽວນີ້"</string>
     <string name="empty_shade_text" msgid="708135716272867002">"ບໍ່ມີການແຈ້ງເຕືອນ"</string>
@@ -645,21 +642,16 @@
     <string name="inline_block_button" msgid="8735843688021655065">"ບລັອກ"</string>
     <string name="inline_keep_button" msgid="6665940297019018232">"ສະແດງຕໍ່ໄປ"</string>
     <string name="inline_minimize_button" msgid="966233327974702195">"ຫຍໍ້"</string>
-    <!-- no translation found for inline_silent_button_silent (5315879183296940969) -->
-    <skip />
+    <string name="inline_silent_button_silent" msgid="5315879183296940969">"ປິດສຽງ"</string>
     <string name="inline_silent_button_stay_silent" msgid="6308371431217601009">"ສືບຕໍ່ມິດງຽບ"</string>
-    <!-- no translation found for inline_silent_button_alert (6008435419895088034) -->
-    <skip />
+    <string name="inline_silent_button_alert" msgid="6008435419895088034">"ການເຕືອນ"</string>
     <string name="inline_silent_button_keep_alerting" msgid="327696842264359693">"ສືບຕໍ່ແຈ້ງເຕືອນ"</string>
     <string name="inline_turn_off_notifications" msgid="8635596135532202355">"ປິດການແຈ້ງເຕືອນ"</string>
     <string name="inline_keep_showing_app" msgid="1723113469580031041">"ສະແດງການແຈ້ງເຕືອນຈາກແອັບນີ້ຕໍ່ໄປບໍ?"</string>
-    <string name="notification_silence_title" msgid="7352089096356977930">"ສຸພາບ"</string>
-    <string name="notification_alert_title" msgid="3966526305405016221">"ສຳຄັນ"</string>
-    <string name="notification_channel_summary_low" msgid="1065819618107531284">"ຊ່ວຍທ່ານມີສະມາທິກກັບການແຈ້ງເຕືອນສະເພາະໃນແຖບເລື່ອນລົງເທົ່ານັ້ນ. ປິດສຽງຕະຫຼອດ."</string>
-    <string name="notification_channel_summary_low_status" msgid="2702170424808743755">"ສະແດງການແຈ້ງເຕືອນທີ່ຄວາມສຳຄັນຕ່ຳລົງ. ປິດສຽງຕະຫຼອດ."</string>
-    <string name="notification_channel_summary_low_lock" msgid="7966605244472624458">"ສະແດງການແຈ້ງເຕືອນທີ່ຄວາມສຳຄັນຕ່ຳລົງ. ປິດສຽງຕະຫຼອດ."</string>
-    <string name="notification_channel_summary_low_status_lock" msgid="7012562768950012739">"ສະແດງການແຈ້ງເຕືອນທີ່ຄວາມສຳຄັນຕ່ຳລົງ. ປິດສຽງຕະຫຼອດ."</string>
-    <string name="notification_channel_summary_default" msgid="3847289783382316019">"ດຶງຄວາມສົນໃຈຂອງທ່ານດ້ວຍສຽງ ແລະ ໄອຄອນແຖບສະຖານະ. ສະແດງຢູ່ໜ້າຈໍລັອກ."</string>
+    <string name="notification_silence_title" msgid="5763240612242137433">"ປິດສຽງ"</string>
+    <string name="notification_alert_title" msgid="8031196611815490340">"ການເຕືອນ"</string>
+    <string name="notification_channel_summary_low" msgid="3387466082089715555">"ຊ່ວຍທ່ານມີສະມາທິໂດຍບໍ່ໃຊ້ສຽງ ຫຼື ການສັ່ນເຕືອນ."</string>
+    <string name="notification_channel_summary_default" msgid="5994062840431965586">"ດຶງຄວາມສົນໃຈຂອງທ່ານດ້ວຍສຽງ ຫຼື ການສັ່ນເຕືອນ."</string>
     <string name="notification_unblockable_desc" msgid="4556908766584964102">"ບໍ່ສາມາດແກ້ໄຂການແຈ້ງເຕືອນເຫຼົ່ານີ້ໄດ້."</string>
     <string name="notification_multichannel_desc" msgid="4695920306092240550">"ບໍ່ສາມາດຕັ້ງຄ່າກຸ່ມການແຈ້ງເຕືອນນີ້ຢູ່ບ່ອນນີ້ໄດ້"</string>
     <string name="notification_delegate_header" msgid="2857691673814814270">"ການແຈ້ງເຕືອນແບບພຣັອກຊີ"</string>
@@ -908,8 +900,7 @@
     <string name="slice_permission_allow" msgid="2340244901366722709">"ອະນຸຍາດ"</string>
     <string name="slice_permission_deny" msgid="7683681514008048807">"ປະຕິເສດ"</string>
     <string name="auto_saver_title" msgid="1217959994732964228">"ແຕະເພື່ອຕັ້ງການເປີດຕົວປະຢັດແບັດເຕີຣີ"</string>
-    <!-- no translation found for auto_saver_text (2563289953551438248) -->
-    <skip />
+    <string name="auto_saver_text" msgid="2563289953551438248">"ເປີດໃຊ້ເມື່ອແບັດເຕີຣີໜ້າຈະໃກ້ໝົດ"</string>
     <string name="no_auto_saver_action" msgid="8086002101711328500">"ບໍ່, ຂອບໃຈ"</string>
     <string name="auto_saver_enabled_title" msgid="6726474226058316862">"ຕັ້ງໃຫ້ເປີດຕົວປະຢັດແບັດເຕີຣີແລ້ວ"</string>
     <string name="auto_saver_enabled_text" msgid="874711029884777579">"ຕົວປະຢັດແບັດເຕີຣີຈະເປີດຂຶ້ນມາໂດຍອັດຕະໂນມັດເມື່ອແບັດເຕີຣີຕ່ຳກວ່າ <xliff:g id="PERCENTAGE">%d</xliff:g>%%."</string>
@@ -942,4 +933,6 @@
     <string name="bubble_accessibility_action_move_bottom_left" msgid="206369104473183217">"ຍ້າຍຊ້າຍລຸ່ມ"</string>
     <string name="bubble_accessibility_action_move_bottom_right" msgid="8705660152384312329">"ຍ້າຍຂວາລຸ່ມ"</string>
     <string name="bubble_dismiss_text" msgid="8028337712674081668">"ປິດໄວ້"</string>
+    <string name="notification_content_system_nav_changed" msgid="7218093915747788444">"ອັບເດດການນຳທາງລະບົບແລ້ວ. ເພື່ອປ່ຽນແປງ, ກະລຸນາໄປທີ່ການຕັ້ງຄ່າ."</string>
+    <string name="notification_content_gesture_nav_available" msgid="8111130443656460792">"ໄປທີ່ການຕັ້ງຄ່າເພື່ອອັບເດດການນຳທາງລະບົບ"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-lt/strings.xml b/packages/SystemUI/res/values-lt/strings.xml
index 88846d9..0c444ca 100644
--- a/packages/SystemUI/res/values-lt/strings.xml
+++ b/packages/SystemUI/res/values-lt/strings.xml
@@ -62,12 +62,10 @@
     <string name="usb_debugging_secondary_user_title" msgid="6353808721761220421">"USB derinimas neleidžiamas"</string>
     <string name="usb_debugging_secondary_user_message" msgid="6067122453571699801">"Šiuo metu prie įrenginio prisijungęs naudotojas negali įjungti USB derinimo. Kad galėtumėte naudoti šią funkciją, perjunkite į pagrindinį naudotoją."</string>
     <string name="usb_contaminant_title" msgid="206854874263058490">"USB prievadas išjungtas"</string>
-    <!-- no translation found for usb_contaminant_message (7379089091591609111) -->
-    <skip />
+    <string name="usb_contaminant_message" msgid="7379089091591609111">"Siekiant apsaugoti įrenginį nuo skysčių ar smulkių dalelių, USB prievadas buvo išjungtas ir neaptiks jokių priedų.\n\nJums bus pranešta, kai galėsite vėl saugiai naudoti USB prievadą."</string>
     <string name="usb_port_enabled" msgid="7906141351687694867">"USB prievadas įgalintas aptikti kroviklius ir priedus"</string>
     <string name="usb_disable_contaminant_detection" msgid="2103905315747120033">"Įgalinti USB"</string>
-    <!-- no translation found for learn_more (5000517160980853569) -->
-    <skip />
+    <string name="learn_more" msgid="5000517160980853569">"Sužinokite daugiau"</string>
     <string name="compat_mode_on" msgid="6623839244840638213">"Keisti mast., kad atit. ekr."</string>
     <string name="compat_mode_off" msgid="4434467572461327898">"Ištempti, kad atit. ekr."</string>
     <string name="global_action_screenshot" msgid="8329831278085426283">"Ekrano kopija"</string>
@@ -199,6 +197,7 @@
     <string name="carrier_network_change_mode" msgid="8149202439957837762">"Keičiamas operatoriaus tinklas"</string>
     <string name="accessibility_battery_details" msgid="7645516654955025422">"Atidaryti išsamią akumuliatoriaus informaciją"</string>
     <string name="accessibility_battery_level" msgid="7451474187113371965">"Akumuliatorius: <xliff:g id="NUMBER">%d</xliff:g> proc."</string>
+    <string name="accessibility_battery_level_with_estimate" msgid="9033100930684311630">"<xliff:g id="PERCENTAGE">%1$s</xliff:g> proc. akumuliatoriaus energijos – liko maždaug <xliff:g id="TIME">%2$s</xliff:g>, atsižvelgiant į naudojimą"</string>
     <string name="accessibility_battery_level_charging" msgid="1147587904439319646">"Įkraunamas akumuliatorius, <xliff:g id="BATTERY_PERCENTAGE">%d</xliff:g>%%."</string>
     <string name="accessibility_settings_button" msgid="799583911231893380">"Sistemos nustatymai"</string>
     <string name="accessibility_notifications_button" msgid="4498000369779421892">"Pranešimai."</string>
@@ -464,10 +463,8 @@
     <string name="media_projection_remember_text" msgid="3103510882172746752">"Daugiau neberodyti"</string>
     <string name="clear_all_notifications_text" msgid="814192889771462828">"Viską išvalyti"</string>
     <string name="manage_notifications_text" msgid="2386728145475108753">"Tvarkyti"</string>
-    <!-- no translation found for notification_section_header_gentle (4372438504154095677) -->
-    <skip />
-    <!-- no translation found for accessibility_notification_section_header_gentle_clear_all (4286716295850400959) -->
-    <skip />
+    <string name="notification_section_header_gentle" msgid="4372438504154095677">"Tylūs pranešimai"</string>
+    <string name="accessibility_notification_section_header_gentle_clear_all" msgid="4286716295850400959">"Išvalyti visus tylius pranešimus"</string>
     <string name="dnd_suppressing_shade_text" msgid="1904574852846769301">"Pranešimai pristabdyti naudojant netrukdymo režimą"</string>
     <string name="media_projection_action_text" msgid="8470872969457985954">"Pradėti dabar"</string>
     <string name="empty_shade_text" msgid="708135716272867002">"Nėra įspėjimų"</string>
@@ -651,21 +648,16 @@
     <string name="inline_block_button" msgid="8735843688021655065">"Blokuoti"</string>
     <string name="inline_keep_button" msgid="6665940297019018232">"Toliau rodyti"</string>
     <string name="inline_minimize_button" msgid="966233327974702195">"Sumažinti"</string>
-    <!-- no translation found for inline_silent_button_silent (5315879183296940969) -->
-    <skip />
+    <string name="inline_silent_button_silent" msgid="5315879183296940969">"Tylūs"</string>
     <string name="inline_silent_button_stay_silent" msgid="6308371431217601009">"Neskambėti"</string>
-    <!-- no translation found for inline_silent_button_alert (6008435419895088034) -->
-    <skip />
+    <string name="inline_silent_button_alert" msgid="6008435419895088034">"Įspėti"</string>
     <string name="inline_silent_button_keep_alerting" msgid="327696842264359693">"Toliau įspėti"</string>
     <string name="inline_turn_off_notifications" msgid="8635596135532202355">"Išjungti pranešimus"</string>
     <string name="inline_keep_showing_app" msgid="1723113469580031041">"Toliau rodyti iš šios programos gautus pranešimus?"</string>
-    <string name="notification_silence_title" msgid="7352089096356977930">"Netrikdantys"</string>
-    <string name="notification_alert_title" msgid="3966526305405016221">"Pirmenybiniai"</string>
-    <string name="notification_channel_summary_low" msgid="1065819618107531284">"Padeda susikaupti, nes pranešimai pateikiami tik išskleidžiamajame skydelyje. Visada nutildyti."</string>
-    <string name="notification_channel_summary_low_status" msgid="2702170424808743755">"Pateikiami po prioritetiniais pranešimais. Visada nutildyti."</string>
-    <string name="notification_channel_summary_low_lock" msgid="7966605244472624458">"Pateikiami po prioritetiniais pranešimais. Visada nutildyti."</string>
-    <string name="notification_channel_summary_low_status_lock" msgid="7012562768950012739">"Pateikiami po prioritetiniais pranešimais. Visada nutildyti."</string>
-    <string name="notification_channel_summary_default" msgid="3847289783382316019">"Dėmesį atkreipia garsas ir būsenos juostos piktograma. Rodomi užrakintame ekrane."</string>
+    <string name="notification_silence_title" msgid="5763240612242137433">"Tylūs"</string>
+    <string name="notification_alert_title" msgid="8031196611815490340">"Įspėti"</string>
+    <string name="notification_channel_summary_low" msgid="3387466082089715555">"Padeda atkreipti dėmesį be garso arba vibravimo."</string>
+    <string name="notification_channel_summary_default" msgid="5994062840431965586">"Atkreipia dėmesį garsu arba vibravimu."</string>
     <string name="notification_unblockable_desc" msgid="4556908766584964102">"Šių pranešimų keisti negalima."</string>
     <string name="notification_multichannel_desc" msgid="4695920306092240550">"Šios grupės pranešimai čia nekonfigūruojami"</string>
     <string name="notification_delegate_header" msgid="2857691673814814270">"Per tarpinį serverį gautas pranešimas"</string>
@@ -918,8 +910,7 @@
     <string name="slice_permission_allow" msgid="2340244901366722709">"Leisti"</string>
     <string name="slice_permission_deny" msgid="7683681514008048807">"Neleisti"</string>
     <string name="auto_saver_title" msgid="1217959994732964228">"Palietę planuokite akumuliatoriaus tausojimo priemonės veikimą"</string>
-    <!-- no translation found for auto_saver_text (2563289953551438248) -->
-    <skip />
+    <string name="auto_saver_text" msgid="2563289953551438248">"Įjunkite, jei akumuliatorius gali greitai išsekti"</string>
     <string name="no_auto_saver_action" msgid="8086002101711328500">"Ne, ačiū"</string>
     <string name="auto_saver_enabled_title" msgid="6726474226058316862">"Akumuliatoriaus tausojimo priemonės veikimas suplanuotas"</string>
     <string name="auto_saver_enabled_text" msgid="874711029884777579">"Akumuliatoriaus tausojimo priemonė bus įjungta automatiškai akumuliatoriaus įkrovai pasiekus mažiau nei <xliff:g id="PERCENTAGE">%d</xliff:g>%%."</string>
@@ -952,4 +943,6 @@
     <string name="bubble_accessibility_action_move_bottom_left" msgid="206369104473183217">"Perkelti į apačią kairėje"</string>
     <string name="bubble_accessibility_action_move_bottom_right" msgid="8705660152384312329">"Perkelti į apačią dešinėje"</string>
     <string name="bubble_dismiss_text" msgid="8028337712674081668">"Atmesti"</string>
+    <string name="notification_content_system_nav_changed" msgid="7218093915747788444">"Sistemos naršymo funkcijos atnaujintos. Jei norite pakeisti, eikite į skiltį „Nustatymai“."</string>
+    <string name="notification_content_gesture_nav_available" msgid="8111130443656460792">"Eikite į skiltį „Nustatymai“, kad atnaujintumėte sistemos naršymo funkcijas"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-lv/strings.xml b/packages/SystemUI/res/values-lv/strings.xml
index 5719dc1..876ba84 100644
--- a/packages/SystemUI/res/values-lv/strings.xml
+++ b/packages/SystemUI/res/values-lv/strings.xml
@@ -62,12 +62,10 @@
     <string name="usb_debugging_secondary_user_title" msgid="6353808721761220421">"USB atkļūdošana nav atļauta"</string>
     <string name="usb_debugging_secondary_user_message" msgid="6067122453571699801">"Lietotājs, kurš pašlaik ir pierakstījies šajā ierīcē, nevar iespējot USB atkļūdošanu. Lai izmantotu šo funkciju, pārslēdzieties uz galveno lietotāju."</string>
     <string name="usb_contaminant_title" msgid="206854874263058490">"USB pieslēgvieta atspējota"</string>
-    <!-- no translation found for usb_contaminant_message (7379089091591609111) -->
-    <skip />
+    <string name="usb_contaminant_message" msgid="7379089091591609111">"Lai aizsargātu ierīci no šķidruma un gružiem, USB pieslēgvieta ir atspējota un tajā nevarēs noteikt pieslēgtus piederumus.\n\nKad USB pieslēgvietu atkal drīkstēs izmantot, saņemsiet paziņojumu."</string>
     <string name="usb_port_enabled" msgid="7906141351687694867">"USB portam ir iespējota uzlādes ierīču un piederumu noteikšana"</string>
     <string name="usb_disable_contaminant_detection" msgid="2103905315747120033">"Iespējot USB portu"</string>
-    <!-- no translation found for learn_more (5000517160980853569) -->
-    <skip />
+    <string name="learn_more" msgid="5000517160980853569">"Uzzināt vairāk"</string>
     <string name="compat_mode_on" msgid="6623839244840638213">"Tālumm., lai aizp. ekr."</string>
     <string name="compat_mode_off" msgid="4434467572461327898">"Stiepiet, lai aizp. ekr."</string>
     <string name="global_action_screenshot" msgid="8329831278085426283">"Ekrānuzņēmums"</string>
@@ -199,6 +197,7 @@
     <string name="carrier_network_change_mode" msgid="8149202439957837762">"Mobilo sakaru operatora tīkla mainīšana"</string>
     <string name="accessibility_battery_details" msgid="7645516654955025422">"Atvērt akumulatora informāciju"</string>
     <string name="accessibility_battery_level" msgid="7451474187113371965">"Akumulators: <xliff:g id="NUMBER">%d</xliff:g> procenti"</string>
+    <string name="accessibility_battery_level_with_estimate" msgid="9033100930684311630">"Akumulatora uzlādes līmenis: <xliff:g id="PERCENTAGE">%1$s</xliff:g> procenti. Ņemot vērā lietojumu, atlikušais laiks ir apmēram <xliff:g id="TIME">%2$s</xliff:g>"</string>
     <string name="accessibility_battery_level_charging" msgid="1147587904439319646">"Notiek akumulatora uzlāde, <xliff:g id="BATTERY_PERCENTAGE">%d</xliff:g>%%."</string>
     <string name="accessibility_settings_button" msgid="799583911231893380">"Sistēmas iestatījumi"</string>
     <string name="accessibility_notifications_button" msgid="4498000369779421892">"Paziņojumi"</string>
@@ -461,10 +460,8 @@
     <string name="media_projection_remember_text" msgid="3103510882172746752">"Vairs nerādīt"</string>
     <string name="clear_all_notifications_text" msgid="814192889771462828">"Dzēst visu"</string>
     <string name="manage_notifications_text" msgid="2386728145475108753">"Pārvaldīt"</string>
-    <!-- no translation found for notification_section_header_gentle (4372438504154095677) -->
-    <skip />
-    <!-- no translation found for accessibility_notification_section_header_gentle_clear_all (4286716295850400959) -->
-    <skip />
+    <string name="notification_section_header_gentle" msgid="4372438504154095677">"Klusie paziņojumi"</string>
+    <string name="accessibility_notification_section_header_gentle_clear_all" msgid="4286716295850400959">"Notīrīt visus klusos paziņojumus"</string>
     <string name="dnd_suppressing_shade_text" msgid="1904574852846769301">"Paziņojumi pārtraukti, izmantojot iestatījumu “Netraucēt”"</string>
     <string name="media_projection_action_text" msgid="8470872969457985954">"Sākt tūlīt"</string>
     <string name="empty_shade_text" msgid="708135716272867002">"Nav paziņojumu"</string>
@@ -648,21 +645,16 @@
     <string name="inline_block_button" msgid="8735843688021655065">"Bloķēt"</string>
     <string name="inline_keep_button" msgid="6665940297019018232">"Turpināt rādīt"</string>
     <string name="inline_minimize_button" msgid="966233327974702195">"Minimizēt"</string>
-    <!-- no translation found for inline_silent_button_silent (5315879183296940969) -->
-    <skip />
+    <string name="inline_silent_button_silent" msgid="5315879183296940969">"Klusums"</string>
     <string name="inline_silent_button_stay_silent" msgid="6308371431217601009">"Neslēgt skaļumu"</string>
-    <!-- no translation found for inline_silent_button_alert (6008435419895088034) -->
-    <skip />
+    <string name="inline_silent_button_alert" msgid="6008435419895088034">"Saņemt brīdinājumus"</string>
     <string name="inline_silent_button_keep_alerting" msgid="327696842264359693">"Turpināt paziņošanu"</string>
     <string name="inline_turn_off_notifications" msgid="8635596135532202355">"Izslēgt paziņojumus"</string>
     <string name="inline_keep_showing_app" msgid="1723113469580031041">"Vai turpināt rādīt paziņojumus no šīs lietotnes?"</string>
-    <string name="notification_silence_title" msgid="7352089096356977930">"Neuzkrītoši"</string>
-    <string name="notification_alert_title" msgid="3966526305405016221">"Prioritāri"</string>
-    <string name="notification_channel_summary_low" msgid="1065819618107531284">"Lai netraucētu jums koncentrēties, paziņojumi tiek rādīti tikai nolaižamajā panelī. Vienmēr bez skaņas."</string>
-    <string name="notification_channel_summary_low_status" msgid="2702170424808743755">"Tiek rādīts zem prioritārajiem paziņojumiem. Vienmēr bez skaņas."</string>
-    <string name="notification_channel_summary_low_lock" msgid="7966605244472624458">"Tiek rādīts zem prioritārajiem paziņojumiem. Vienmēr bez skaņas."</string>
-    <string name="notification_channel_summary_low_status_lock" msgid="7012562768950012739">"Tiek rādīts zem prioritārajiem paziņojumiem. Vienmēr bez skaņas."</string>
-    <string name="notification_channel_summary_default" msgid="3847289783382316019">"Lai piesaistītu jūsu uzmanību, tiek atskaņots signāls un tiek rādīta statusa joslas ikona. Paziņojums ir redzams bloķēšanas ekrānā."</string>
+    <string name="notification_silence_title" msgid="5763240612242137433">"Klusums"</string>
+    <string name="notification_alert_title" msgid="8031196611815490340">"Brīdinājumu saņemšana"</string>
+    <string name="notification_channel_summary_low" msgid="3387466082089715555">"Palīdz jums koncentrēties, nenovēršot uzmanību ar skaņu vai vibrāciju."</string>
+    <string name="notification_channel_summary_default" msgid="5994062840431965586">"Jūsu uzmanība tiek piesaistīta ar skaņas vai vibrācijas signālu."</string>
     <string name="notification_unblockable_desc" msgid="4556908766584964102">"Šos paziņojumus nevar modificēt."</string>
     <string name="notification_multichannel_desc" msgid="4695920306092240550">"Šeit nevar konfigurēt šo paziņojumu grupu."</string>
     <string name="notification_delegate_header" msgid="2857691673814814270">"Starpniekservera paziņojums"</string>
@@ -913,8 +905,7 @@
     <string name="slice_permission_allow" msgid="2340244901366722709">"Atļaut"</string>
     <string name="slice_permission_deny" msgid="7683681514008048807">"Neatļaut"</string>
     <string name="auto_saver_title" msgid="1217959994732964228">"Pieskarieties, lai iestatītu akumulatora jaudas taupīšanas režīma grafiku"</string>
-    <!-- no translation found for auto_saver_text (2563289953551438248) -->
-    <skip />
+    <string name="auto_saver_text" msgid="2563289953551438248">"Ieslēgt, ja akumulators var izlādēties"</string>
     <string name="no_auto_saver_action" msgid="8086002101711328500">"Nē, paldies"</string>
     <string name="auto_saver_enabled_title" msgid="6726474226058316862">"Ieslēgts akumulatora enerģijas taupīšanas režīma grafiks"</string>
     <string name="auto_saver_enabled_text" msgid="874711029884777579">"Tiklīdz akumulatora uzlādes līmenis būs zemāks nekā <xliff:g id="PERCENTAGE">%d</xliff:g>%%, tiks automātiski ieslēgts akumulatora jaudas taupīšanas režīms."</string>
@@ -947,4 +938,6 @@
     <string name="bubble_accessibility_action_move_bottom_left" msgid="206369104473183217">"Pārvietot apakšpusē pa kreisi"</string>
     <string name="bubble_accessibility_action_move_bottom_right" msgid="8705660152384312329">"Pārvietot apakšpusē pa labi"</string>
     <string name="bubble_dismiss_text" msgid="8028337712674081668">"Nerādīt"</string>
+    <string name="notification_content_system_nav_changed" msgid="7218093915747788444">"Sistēmas navigācija ir atjaunināta. Lai veiktu izmaiņas, atveriet iestatījumus."</string>
+    <string name="notification_content_gesture_nav_available" msgid="8111130443656460792">"Atveriet iestatījumus, lai atjauninātu sistēmas navigāciju"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-mk/strings.xml b/packages/SystemUI/res/values-mk/strings.xml
index 86109b8..e98d0ab 100644
--- a/packages/SystemUI/res/values-mk/strings.xml
+++ b/packages/SystemUI/res/values-mk/strings.xml
@@ -62,12 +62,10 @@
     <string name="usb_debugging_secondary_user_title" msgid="6353808721761220421">"Отстранувањето грешки на USB не е дозволено"</string>
     <string name="usb_debugging_secondary_user_message" msgid="6067122453571699801">"Корисникот што моментално е најавен на уредов не може да вклучи отстранување грешки на USB. За да ја користите функцијава, префрлете се на примарниот корисник."</string>
     <string name="usb_contaminant_title" msgid="206854874263058490">"USB-портата е оневозможена"</string>
-    <!-- no translation found for usb_contaminant_message (7379089091591609111) -->
-    <skip />
+    <string name="usb_contaminant_message" msgid="7379089091591609111">"За да го заштитиме уредот од течност или нечистотија, USB-портата е оневозможена и нема да ги открива додатоците.\n\nЌе ве известиме кога ќе биде во ред да ја користите USB-портата повторно."</string>
     <string name="usb_port_enabled" msgid="7906141351687694867">"USB-портата е овозможена за откривање полначи и додатоци"</string>
     <string name="usb_disable_contaminant_detection" msgid="2103905315747120033">"Овозможи USB"</string>
-    <!-- no translation found for learn_more (5000517160980853569) -->
-    <skip />
+    <string name="learn_more" msgid="5000517160980853569">"Дознајте повеќе"</string>
     <string name="compat_mode_on" msgid="6623839244840638213">"Зумирај да се исполни екранот"</string>
     <string name="compat_mode_off" msgid="4434467572461327898">"Растегни да се исполни екранот"</string>
     <string name="global_action_screenshot" msgid="8329831278085426283">"Слика од екранот"</string>
@@ -199,6 +197,7 @@
     <string name="carrier_network_change_mode" msgid="8149202439957837762">"Променување на мрежата на операторот"</string>
     <string name="accessibility_battery_details" msgid="7645516654955025422">"Отвори ги деталите за батеријата"</string>
     <string name="accessibility_battery_level" msgid="7451474187113371965">"Батерија <xliff:g id="NUMBER">%d</xliff:g> проценти."</string>
+    <string name="accessibility_battery_level_with_estimate" msgid="9033100930684311630">"Батерија <xliff:g id="PERCENTAGE">%1$s</xliff:g> отсто, уште околу <xliff:g id="TIME">%2$s</xliff:g> според вашето користење"</string>
     <string name="accessibility_battery_level_charging" msgid="1147587904439319646">"Полнење на батеријата, <xliff:g id="BATTERY_PERCENTAGE">%d</xliff:g> %%."</string>
     <string name="accessibility_settings_button" msgid="799583911231893380">"Поставки на систем."</string>
     <string name="accessibility_notifications_button" msgid="4498000369779421892">"Известувања"</string>
@@ -458,10 +457,8 @@
     <string name="media_projection_remember_text" msgid="3103510882172746752">"Не покажувај повторно"</string>
     <string name="clear_all_notifications_text" msgid="814192889771462828">"Исчисти сè"</string>
     <string name="manage_notifications_text" msgid="2386728145475108753">"Управувајте"</string>
-    <!-- no translation found for notification_section_header_gentle (4372438504154095677) -->
-    <skip />
-    <!-- no translation found for accessibility_notification_section_header_gentle_clear_all (4286716295850400959) -->
-    <skip />
+    <string name="notification_section_header_gentle" msgid="4372438504154095677">"Тивки известувања"</string>
+    <string name="accessibility_notification_section_header_gentle_clear_all" msgid="4286716295850400959">"Исчисти ги сите тивки известувања"</string>
     <string name="dnd_suppressing_shade_text" msgid="1904574852846769301">"Известувањата се паузирани од „Не вознемирувај“"</string>
     <string name="media_projection_action_text" msgid="8470872969457985954">"Започни сега"</string>
     <string name="empty_shade_text" msgid="708135716272867002">"Нема известувања"</string>
@@ -645,21 +642,16 @@
     <string name="inline_block_button" msgid="8735843688021655065">"Блокирај"</string>
     <string name="inline_keep_button" msgid="6665940297019018232">"Продолжи да ги прикажуваш"</string>
     <string name="inline_minimize_button" msgid="966233327974702195">"Минимизирај"</string>
-    <!-- no translation found for inline_silent_button_silent (5315879183296940969) -->
-    <skip />
+    <string name="inline_silent_button_silent" msgid="5315879183296940969">"Тивко"</string>
     <string name="inline_silent_button_stay_silent" msgid="6308371431217601009">"Продолжи со безгласно прикажување"</string>
-    <!-- no translation found for inline_silent_button_alert (6008435419895088034) -->
-    <skip />
+    <string name="inline_silent_button_alert" msgid="6008435419895088034">"Предупредувај"</string>
     <string name="inline_silent_button_keep_alerting" msgid="327696842264359693">"Продолжи да ме предупредуваш"</string>
     <string name="inline_turn_off_notifications" msgid="8635596135532202355">"Исклучи известувања"</string>
     <string name="inline_keep_showing_app" msgid="1723113469580031041">"Дали да продолжат да се прикажуваат известувања од апликацијава?"</string>
-    <string name="notification_silence_title" msgid="7352089096356977930">"Тивко"</string>
-    <string name="notification_alert_title" msgid="3966526305405016221">"Приоритетно"</string>
-    <string name="notification_channel_summary_low" msgid="1065819618107531284">"Не ви го одвлекува вниманието прикажувајќи известувања само во списокот со известувања. Секогаш безгласно."</string>
-    <string name="notification_channel_summary_low_status" msgid="2702170424808743755">"Се прикажува под приоритетните известувања. Секогаш безгласно."</string>
-    <string name="notification_channel_summary_low_lock" msgid="7966605244472624458">"Се прикажува под приоритетните известувања. Секогаш безгласно."</string>
-    <string name="notification_channel_summary_low_status_lock" msgid="7012562768950012739">"Се прикажува под приоритетните известувања. Секогаш безгласно."</string>
-    <string name="notification_channel_summary_default" msgid="3847289783382316019">"Ви го привлекува вниманието со звук и икона во статусната лента. Се прикажува на заклучен екран."</string>
+    <string name="notification_silence_title" msgid="5763240612242137433">"Тивко"</string>
+    <string name="notification_alert_title" msgid="8031196611815490340">"Предупредувај"</string>
+    <string name="notification_channel_summary_low" msgid="3387466082089715555">"Ви помага да се концентрирате без звук или вибрации."</string>
+    <string name="notification_channel_summary_default" msgid="5994062840431965586">"Ви го привлекува вниманието со звук или вибрации."</string>
     <string name="notification_unblockable_desc" msgid="4556908766584964102">"Овие известувања не може да се изменат"</string>
     <string name="notification_multichannel_desc" msgid="4695920306092240550">"Оваа група известувања не може да се конфигурира тука"</string>
     <string name="notification_delegate_header" msgid="2857691673814814270">"Известување преку прокси"</string>
@@ -908,8 +900,7 @@
     <string name="slice_permission_allow" msgid="2340244901366722709">"Дозволи"</string>
     <string name="slice_permission_deny" msgid="7683681514008048807">"Одбиј"</string>
     <string name="auto_saver_title" msgid="1217959994732964228">"Допрете за да закажете „Штедач на батерија“"</string>
-    <!-- no translation found for auto_saver_text (2563289953551438248) -->
-    <skip />
+    <string name="auto_saver_text" msgid="2563289953551438248">"Вклучи ако е веројатно дека батеријата ќе се испразни"</string>
     <string name="no_auto_saver_action" msgid="8086002101711328500">"Не, фала"</string>
     <string name="auto_saver_enabled_title" msgid="6726474226058316862">"Распоредот за „Штедач на батерија“ е вклучен"</string>
     <string name="auto_saver_enabled_text" msgid="874711029884777579">"Штедачот на батерија ќе се вклучи автоматски кога батеријата ќе падне под <xliff:g id="PERCENTAGE">%d</xliff:g> %%."</string>
@@ -942,4 +933,6 @@
     <string name="bubble_accessibility_action_move_bottom_left" msgid="206369104473183217">"Премести долу лево"</string>
     <string name="bubble_accessibility_action_move_bottom_right" msgid="8705660152384312329">"Премести долу десно"</string>
     <string name="bubble_dismiss_text" msgid="8028337712674081668">"Отфрли"</string>
+    <string name="notification_content_system_nav_changed" msgid="7218093915747788444">"Навигацијата на системот е ажурирана. За да извршите промени, одете во „Поставки“."</string>
+    <string name="notification_content_gesture_nav_available" msgid="8111130443656460792">"Одете во „Поставки“ за да ја ажурирате навигацијата на системот"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-ml/strings.xml b/packages/SystemUI/res/values-ml/strings.xml
index cd7cb67..7367fa5 100644
--- a/packages/SystemUI/res/values-ml/strings.xml
+++ b/packages/SystemUI/res/values-ml/strings.xml
@@ -62,12 +62,10 @@
     <string name="usb_debugging_secondary_user_title" msgid="6353808721761220421">"USB ഡീബഗ്ഗിംഗ് അനുവദനീയമല്ല"</string>
     <string name="usb_debugging_secondary_user_message" msgid="6067122453571699801">"ഉപകരണത്തിൽ ഇപ്പോൾ സൈൻ ഇൻ ചെയ്‌തിരിക്കുന്ന ഉപയോക്താവിന് USB ഡീബഗ്ഗിംഗ് ഓണാക്കാനാകില്ല. ഈ ഫീച്ചർ ഉപയോഗിക്കാൻ പ്രാഥമിക ഉപയോക്താവിലേക്ക് മാറുക."</string>
     <string name="usb_contaminant_title" msgid="206854874263058490">"USB പോർട്ട് പ്രവർത്തനരഹിതമാക്കി"</string>
-    <!-- no translation found for usb_contaminant_message (7379089091591609111) -->
-    <skip />
+    <string name="usb_contaminant_message" msgid="7379089091591609111">"ദ്രാവകത്തിൽ നിന്നോ പൊടിയിൽ നിന്നോ നിങ്ങളുടെ ഉപകരണത്തെ പരിരക്ഷിക്കാനായി USB പോർട്ട് പ്രവർത്തനരഹിതമാക്കിയിരിക്കുന്നതിനാൽ അത് ആക്‌സസറികളൊന്നും തിരിച്ചറിയില്ല.\n\n USB പോർട്ട് വീണ്ടും ഉപയോഗിക്കാനാകുമ്പോൾ നിങ്ങളെ അറിയിക്കും."</string>
     <string name="usb_port_enabled" msgid="7906141351687694867">"ആക്‌സസറികളും ചാർജറുകളും കണ്ടെത്താൻ USB പോർട്ട് പ്രവർത്തനക്ഷമമാക്കുക"</string>
     <string name="usb_disable_contaminant_detection" msgid="2103905315747120033">"USB പ്രവർത്തനക്ഷമമാക്കുക"</string>
-    <!-- no translation found for learn_more (5000517160980853569) -->
-    <skip />
+    <string name="learn_more" msgid="5000517160980853569">"കൂടുതലറിയുക"</string>
     <string name="compat_mode_on" msgid="6623839244840638213">"സ്‌ക്രീനിൽ ഉൾക്കൊള്ളിക്കാൻ സൂം ചെയ്യുക"</string>
     <string name="compat_mode_off" msgid="4434467572461327898">"സ്‌ക്രീനിൽ ഉൾക്കൊള്ളിക്കാൻ വലിച്ചുനീട്ടുക"</string>
     <string name="global_action_screenshot" msgid="8329831278085426283">"സ്‌ക്രീൻഷോട്ട്"</string>
@@ -199,6 +197,7 @@
     <string name="carrier_network_change_mode" msgid="8149202439957837762">"കാരിയർ നെറ്റ്‌വർക്ക് മാറ്റൽ"</string>
     <string name="accessibility_battery_details" msgid="7645516654955025422">"ബാറ്ററി വിശദാംശങ്ങൾ തുറക്കുക"</string>
     <string name="accessibility_battery_level" msgid="7451474187113371965">"ബാറ്ററി <xliff:g id="NUMBER">%d</xliff:g> ശതമാനം."</string>
+    <string name="accessibility_battery_level_with_estimate" msgid="9033100930684311630">"ബാറ്ററി <xliff:g id="PERCENTAGE">%1$s</xliff:g> ശതമാനം, നിങ്ങളുടെ ഉപയോഗത്തിൻ്റെ അടിസ്ഥാനത്തിൽ ഏകദേശം <xliff:g id="TIME">%2$s</xliff:g> സമയം കൂടി ശേഷിക്കുന്നു"</string>
     <string name="accessibility_battery_level_charging" msgid="1147587904439319646">"ബാറ്ററി ചാർജുചെയ്യുന്നു, <xliff:g id="BATTERY_PERCENTAGE">%d</xliff:g>%%."</string>
     <string name="accessibility_settings_button" msgid="799583911231893380">"സിസ്‌റ്റം ക്രമീകരണങ്ങൾ."</string>
     <string name="accessibility_notifications_button" msgid="4498000369779421892">"അറിയിപ്പുകൾ."</string>
@@ -458,10 +457,8 @@
     <string name="media_projection_remember_text" msgid="3103510882172746752">"വീണ്ടും കാണിക്കരുത്"</string>
     <string name="clear_all_notifications_text" msgid="814192889771462828">"എല്ലാം മായ്‌ക്കുക"</string>
     <string name="manage_notifications_text" msgid="2386728145475108753">"മാനേജ് ചെയ്യുക"</string>
-    <!-- no translation found for notification_section_header_gentle (4372438504154095677) -->
-    <skip />
-    <!-- no translation found for accessibility_notification_section_header_gentle_clear_all (4286716295850400959) -->
-    <skip />
+    <string name="notification_section_header_gentle" msgid="4372438504154095677">"നിശബ്‌ദ അറിയിപ്പുകൾ"</string>
+    <string name="accessibility_notification_section_header_gentle_clear_all" msgid="4286716295850400959">"എല്ലാ നിശബ്‌ദ അറിയിപ്പുകളും മായ്ക്കുക"</string>
     <string name="dnd_suppressing_shade_text" msgid="1904574852846769301">"\'ശല്യപ്പെടുത്തരുത്\' വഴി അറിയിപ്പുകൾ താൽക്കാലികമായി നിർത്തി"</string>
     <string name="media_projection_action_text" msgid="8470872969457985954">"ഇപ്പോൾ ആരംഭിക്കുക"</string>
     <string name="empty_shade_text" msgid="708135716272867002">"അറിയിപ്പുകൾ ഒന്നുമില്ല"</string>
@@ -645,21 +642,16 @@
     <string name="inline_block_button" msgid="8735843688021655065">"ബ്ലോക്ക് ചെയ്യുക"</string>
     <string name="inline_keep_button" msgid="6665940297019018232">"തുടർന്നും കാണിക്കുക"</string>
     <string name="inline_minimize_button" msgid="966233327974702195">"ചെറുതാക്കുക‍"</string>
-    <!-- no translation found for inline_silent_button_silent (5315879183296940969) -->
-    <skip />
+    <string name="inline_silent_button_silent" msgid="5315879183296940969">"നിശബ്‌ദം"</string>
     <string name="inline_silent_button_stay_silent" msgid="6308371431217601009">"നിശബ്‌ദമായ നിലയിൽ തുടരുക"</string>
-    <!-- no translation found for inline_silent_button_alert (6008435419895088034) -->
-    <skip />
+    <string name="inline_silent_button_alert" msgid="6008435419895088034">"മുന്നറിയിപ്പ് നൽകൽ"</string>
     <string name="inline_silent_button_keep_alerting" msgid="327696842264359693">"മുന്നറിയിപ്പ് നൽകുന്നത് തുടരുക"</string>
     <string name="inline_turn_off_notifications" msgid="8635596135532202355">"അറിയിപ്പുകൾ ഓഫാക്കുക"</string>
     <string name="inline_keep_showing_app" msgid="1723113469580031041">"ഈ ആപ്പിൽ നിന്നുള്ള അറിയിപ്പുകൾ തുടർന്നും കാണിക്കണോ?"</string>
-    <string name="notification_silence_title" msgid="7352089096356977930">"സൗമ്യമായ"</string>
-    <string name="notification_alert_title" msgid="3966526305405016221">"മുൻഗണനയുള്ള"</string>
-    <string name="notification_channel_summary_low" msgid="1065819618107531284">"പുൾ ഡൗൺ ഷെയ്‌ഡിൽ മാത്രമുള്ള അറിയിപ്പുകളിൽ ശ്രദ്ധ കേന്ദ്രീകരിക്കാൻ നിങ്ങളെ സഹായിക്കുന്നു. എപ്പോഴും നിശബ്‌ദം."</string>
-    <string name="notification_channel_summary_low_status" msgid="2702170424808743755">"കുറഞ്ഞ പ്രാധാന്യമുള്ള മുൻഗണനാ അറിയിപ്പുകൾ പ്രദർശിപ്പിക്കുന്നു. എപ്പോഴും നിശബ്‌ദം."</string>
-    <string name="notification_channel_summary_low_lock" msgid="7966605244472624458">"കുറഞ്ഞ പ്രാധാന്യമുള്ള മുൻഗണനാ അറിയിപ്പുകൾ പ്രദർശിപ്പിക്കുന്നു. എപ്പോഴും നിശബ്‌ദം."</string>
-    <string name="notification_channel_summary_low_status_lock" msgid="7012562768950012739">"കുറഞ്ഞ പ്രാധാന്യമുള്ള മുൻഗണനാ അറിയിപ്പുകൾ പ്രദർശിപ്പിക്കുന്നു. എപ്പോഴും നിശബ്‌ദം."</string>
-    <string name="notification_channel_summary_default" msgid="3847289783382316019">"ശബ്‌ദവും സ്‌റ്റാറ്റസ് ബാർ ഐക്കണും ഉപയോഗിച്ച് ശ്രദ്ധ ക്ഷണിക്കുന്നു. ലോക്ക് സ്‌ക്രീനിൽ കാണിക്കും."</string>
+    <string name="notification_silence_title" msgid="5763240612242137433">"നിശബ്‌ദം"</string>
+    <string name="notification_alert_title" msgid="8031196611815490340">"മുന്നറിയിപ്പ് നൽകൽ"</string>
+    <string name="notification_channel_summary_low" msgid="3387466082089715555">"ശബ്‌ദമോ വൈബ്രേഷനോ ഇല്ലാതെ ശ്രദ്ധ കേന്ദ്രീകരിക്കാൻ നിങ്ങളെ സഹായിക്കുന്നു."</string>
+    <string name="notification_channel_summary_default" msgid="5994062840431965586">"ശബ്‌ദമോ വെെബ്രേഷനോ ഉപയോഗിച്ച് നിങ്ങളുടെ ശ്രദ്ധ ക്ഷണിക്കുന്നു."</string>
     <string name="notification_unblockable_desc" msgid="4556908766584964102">"ഈ അറിയിപ്പുകൾ പരിഷ്ക്കരിക്കാനാവില്ല."</string>
     <string name="notification_multichannel_desc" msgid="4695920306092240550">"അറിയിപ്പുകളുടെ ഈ ഗ്രൂപ്പ് ഇവിടെ കോണ്‍ഫിഗര്‍ ചെയ്യാൻ കഴിയില്ല"</string>
     <string name="notification_delegate_header" msgid="2857691673814814270">"പ്രോക്‌സി അറിയിപ്പ്"</string>
@@ -908,8 +900,7 @@
     <string name="slice_permission_allow" msgid="2340244901366722709">"അനുവദിക്കുക"</string>
     <string name="slice_permission_deny" msgid="7683681514008048807">"നിരസിക്കുക"</string>
     <string name="auto_saver_title" msgid="1217959994732964228">"ബാറ്ററി ലാഭിക്കൽ ഷെഡ്യൂൾ ചെയ്യാൻ ടാപ്പ് ചെയ്യുക"</string>
-    <!-- no translation found for auto_saver_text (2563289953551438248) -->
-    <skip />
+    <string name="auto_saver_text" msgid="2563289953551438248">"ബാറ്ററി ചാർജ് തീരാൻ സാധ്യതയുണ്ടെങ്കിൽ ഓണാക്കുക"</string>
     <string name="no_auto_saver_action" msgid="8086002101711328500">"വേണ്ട"</string>
     <string name="auto_saver_enabled_title" msgid="6726474226058316862">"ബാറ്ററി ലാഭിക്കൽ ഷെഡ്യൂൾ ഓണാക്കുക"</string>
     <string name="auto_saver_enabled_text" msgid="874711029884777579">"ബാറ്ററി <xliff:g id="PERCENTAGE">%d</xliff:g>%% ൽ താഴെയാകുമ്പോൾ, ബാറ്ററി ലാഭിക്കൽ സ്വമേധയാ ഓണാകും."</string>
@@ -942,4 +933,6 @@
     <string name="bubble_accessibility_action_move_bottom_left" msgid="206369104473183217">"ചുവടെ ഇടതുഭാഗത്തേക്ക് നീക്കുക"</string>
     <string name="bubble_accessibility_action_move_bottom_right" msgid="8705660152384312329">"ചുവടെ വലതുഭാഗത്തേക്ക് നീക്കുക"</string>
     <string name="bubble_dismiss_text" msgid="8028337712674081668">"ഡിസ്‌മിസ് ചെയ്യുക"</string>
+    <string name="notification_content_system_nav_changed" msgid="7218093915747788444">"സിസ്‌റ്റം നാവിഗേഷൻ അപ്‌ഡേറ്റ് ചെയ്‌തു. മാറ്റങ്ങൾ വരുത്താൻ ക്രമീകരണത്തിലേക്ക് പോവുക."</string>
+    <string name="notification_content_gesture_nav_available" msgid="8111130443656460792">"സിസ്‌റ്റം നാവിഗേഷൻ അപ്‌ഡേറ്റ് ചെയ്യാൻ ക്രമീകരണത്തിലേക്ക് പോവുക"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-mn/strings.xml b/packages/SystemUI/res/values-mn/strings.xml
index 5630e0d..1f70348 100644
--- a/packages/SystemUI/res/values-mn/strings.xml
+++ b/packages/SystemUI/res/values-mn/strings.xml
@@ -62,12 +62,10 @@
     <string name="usb_debugging_secondary_user_title" msgid="6353808721761220421">"USB алдаа засалт хийх боломжгүй"</string>
     <string name="usb_debugging_secondary_user_message" msgid="6067122453571699801">"Энэ төхөөрөмжид нэвтэрсэн хэрэглэгч USB дебаг хийх онцлогийг асаах боломжгүй байна. Энэ онцлогийг ашиглахын тулд үндсэн хэрэглэгч рүү сэлгэнэ үү."</string>
     <string name="usb_contaminant_title" msgid="206854874263058490">"USB портыг идэвхгүй болгосон"</string>
-    <!-- no translation found for usb_contaminant_message (7379089091591609111) -->
-    <skip />
+    <string name="usb_contaminant_message" msgid="7379089091591609111">"Таны төхөөрөмжийг шингэн зүйл эсвэл бохирдлоос хамгаалахын тулд USB портыг идэвхгүй болгосон бөгөөд энэ нь ямар ч дагалдах хэрэгслийг илрүүлэхгүй.\n\nТанд USB портыг дахин ашиглахад аюулгүй болох үед мэдэгдэх болно."</string>
     <string name="usb_port_enabled" msgid="7906141351687694867">"Цэнэглэгч болон нэмэлт хэрэгслийг илрүүлэхийн тулд USB портыг идэвхжүүлсэн"</string>
     <string name="usb_disable_contaminant_detection" msgid="2103905315747120033">"USB-г идэвхжүүлэх"</string>
-    <!-- no translation found for learn_more (5000517160980853569) -->
-    <skip />
+    <string name="learn_more" msgid="5000517160980853569">"Нэмэлт мэдээлэл авах"</string>
     <string name="compat_mode_on" msgid="6623839244840638213">"Дэлгэц дүүргэх бол өсгөнө үү"</string>
     <string name="compat_mode_off" msgid="4434467572461327898">"Дэлгэц дүүргэх бол татна уу"</string>
     <string name="global_action_screenshot" msgid="8329831278085426283">"Дэлгэцийн зураг дарах"</string>
@@ -199,6 +197,7 @@
     <string name="carrier_network_change_mode" msgid="8149202439957837762">"Оператор компанийн сүлжээг өөрчилж байна"</string>
     <string name="accessibility_battery_details" msgid="7645516654955025422">"Тэжээлийн дэлгэрэнгүй мэдээллийг нээх"</string>
     <string name="accessibility_battery_level" msgid="7451474187113371965">"Батерей <xliff:g id="NUMBER">%d</xliff:g> хувьтай."</string>
+    <string name="accessibility_battery_level_with_estimate" msgid="9033100930684311630">"Батарей <xliff:g id="PERCENTAGE">%1$s</xliff:g> хувьтай байна. Таны хэрэглээнд тулгуурлан ойролцоогоор <xliff:g id="TIME">%2$s</xliff:g> үлдсэн"</string>
     <string name="accessibility_battery_level_charging" msgid="1147587904439319646">"Батарейг цэнэглэж байна, <xliff:g id="BATTERY_PERCENTAGE">%d</xliff:g>%%."</string>
     <string name="accessibility_settings_button" msgid="799583911231893380">"Системийн тохиргоо."</string>
     <string name="accessibility_notifications_button" msgid="4498000369779421892">"Мэдэгдэл."</string>
@@ -458,10 +457,8 @@
     <string name="media_projection_remember_text" msgid="3103510882172746752">"Дахиж үл харуулах"</string>
     <string name="clear_all_notifications_text" msgid="814192889771462828">"Бүгдийг арилгах"</string>
     <string name="manage_notifications_text" msgid="2386728145475108753">"Удирдах"</string>
-    <!-- no translation found for notification_section_header_gentle (4372438504154095677) -->
-    <skip />
-    <!-- no translation found for accessibility_notification_section_header_gentle_clear_all (4286716295850400959) -->
-    <skip />
+    <string name="notification_section_header_gentle" msgid="4372438504154095677">"Чимээгүй мэдэгдэл"</string>
+    <string name="accessibility_notification_section_header_gentle_clear_all" msgid="4286716295850400959">"Бүх чимээгүй мэдэгдлийг арилгах"</string>
     <string name="dnd_suppressing_shade_text" msgid="1904574852846769301">"Бүү саад бол горимын түр зогсоосон мэдэгдэл"</string>
     <string name="media_projection_action_text" msgid="8470872969457985954">"Одоо эхлүүлэх"</string>
     <string name="empty_shade_text" msgid="708135716272867002">"Мэдэгдэл байхгүй"</string>
@@ -645,21 +642,16 @@
     <string name="inline_block_button" msgid="8735843688021655065">"Блоклох"</string>
     <string name="inline_keep_button" msgid="6665940297019018232">"Харуулсан хэвээр байх"</string>
     <string name="inline_minimize_button" msgid="966233327974702195">"Багасгах"</string>
-    <!-- no translation found for inline_silent_button_silent (5315879183296940969) -->
-    <skip />
+    <string name="inline_silent_button_silent" msgid="5315879183296940969">"Чимээгүй"</string>
     <string name="inline_silent_button_stay_silent" msgid="6308371431217601009">"Чимээгүй хэвээр харуулах"</string>
-    <!-- no translation found for inline_silent_button_alert (6008435419895088034) -->
-    <skip />
+    <string name="inline_silent_button_alert" msgid="6008435419895088034">"Сэрэмжлүүлж байна"</string>
     <string name="inline_silent_button_keep_alerting" msgid="327696842264359693">"Үргэлжлүүлэн сануулах"</string>
     <string name="inline_turn_off_notifications" msgid="8635596135532202355">"Мэдэгдлийг унтраах"</string>
     <string name="inline_keep_showing_app" msgid="1723113469580031041">"Энэ аппаас мэдэгдэл харуулсан хэвээр байх уу?"</string>
-    <string name="notification_silence_title" msgid="7352089096356977930">"Бага ач холбогдолтой"</string>
-    <string name="notification_alert_title" msgid="3966526305405016221">"Чухал ач холбогдолтой"</string>
-    <string name="notification_channel_summary_low" msgid="1065819618107531284">"Танд зөвхөн доош татдаг сүүдрийн мэдэгдлээр төвлөрөхөд тусалдаг. Үргэлж чимээгүй байна."</string>
-    <string name="notification_channel_summary_low_status" msgid="2702170424808743755">"Доорх ач холбогдолтой мэдэгдлийг харуулдаг. Үргэлж чимээгүй байна."</string>
-    <string name="notification_channel_summary_low_lock" msgid="7966605244472624458">"Доорх ач холбогдолтой мэдэгдлийг харуулдаг. Үргэлж чимээгүй байна."</string>
-    <string name="notification_channel_summary_low_status_lock" msgid="7012562768950012739">"Доорх ач холбогдолтой мэдэгдлийг харуулдаг. Үргэлж чимээгүй байна."</string>
-    <string name="notification_channel_summary_default" msgid="3847289783382316019">"Таны анхаарлыг дуу болон статус самбарын дүрс тэмдгээр татдаг. Түгжигдсэн дэлгэц дээр харуулдаг."</string>
+    <string name="notification_silence_title" msgid="5763240612242137433">"Чимээгүй"</string>
+    <string name="notification_alert_title" msgid="8031196611815490340">"Дуутай"</string>
+    <string name="notification_channel_summary_low" msgid="3387466082089715555">"Дуу эсвэл чичиргээгүйгээр танд төвлөрөхөд тусална."</string>
+    <string name="notification_channel_summary_default" msgid="5994062840431965586">"Дуу эсвэл чичиргээгүйгээр таны анхаарлыг татна."</string>
     <string name="notification_unblockable_desc" msgid="4556908766584964102">"Эдгээр мэдэгдлийг өөрчлөх боломжгүй."</string>
     <string name="notification_multichannel_desc" msgid="4695920306092240550">"Энэ бүлэг мэдэгдлийг энд тохируулах боломжгүй байна"</string>
     <string name="notification_delegate_header" msgid="2857691673814814270">"Прокси хийсэн мэдэгдэл"</string>
@@ -908,8 +900,7 @@
     <string name="slice_permission_allow" msgid="2340244901366722709">"Зөвшөөрөх"</string>
     <string name="slice_permission_deny" msgid="7683681514008048807">"Татгалзах"</string>
     <string name="auto_saver_title" msgid="1217959994732964228">"Тэжээл хэмнэгч онцлогийг хуваарилахын тулд товших"</string>
-    <!-- no translation found for auto_saver_text (2563289953551438248) -->
-    <skip />
+    <string name="auto_saver_text" msgid="2563289953551438248">"Батарей дуусах гэж байгаа үед асаана уу"</string>
     <string name="no_auto_saver_action" msgid="8086002101711328500">"Үгүй, баярлалаа"</string>
     <string name="auto_saver_enabled_title" msgid="6726474226058316862">"Тэжээл хэмнэгч онцлогийн хуваарийг асаасан"</string>
     <string name="auto_saver_enabled_text" msgid="874711029884777579">"Батарей <xliff:g id="PERCENTAGE">%d</xliff:g>%%-с бага болсон үед Тэжээл хэмнэгч автоматаар асна."</string>
@@ -942,4 +933,6 @@
     <string name="bubble_accessibility_action_move_bottom_left" msgid="206369104473183217">"Зүүн доош зөөх"</string>
     <string name="bubble_accessibility_action_move_bottom_right" msgid="8705660152384312329">"Баруун доош зөөх"</string>
     <string name="bubble_dismiss_text" msgid="8028337712674081668">"Үл хэрэгсэх"</string>
+    <string name="notification_content_system_nav_changed" msgid="7218093915747788444">"Системийн навигацыг шинэчиллээ. Өөрчлөхийн тулд Тохиргоо руу очно уу."</string>
+    <string name="notification_content_gesture_nav_available" msgid="8111130443656460792">"Системийн навигацыг шинэчлэхийн тулд Тохиргоо руу очно уу"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-mr/strings.xml b/packages/SystemUI/res/values-mr/strings.xml
index 34c31e1..48966f0 100644
--- a/packages/SystemUI/res/values-mr/strings.xml
+++ b/packages/SystemUI/res/values-mr/strings.xml
@@ -62,12 +62,10 @@
     <string name="usb_debugging_secondary_user_title" msgid="6353808721761220421">"USB डीबग करण्‍यास अनुमती नाही"</string>
     <string name="usb_debugging_secondary_user_message" msgid="6067122453571699801">"सध्‍या या डीव्हाइसमध्‍ये साइन इन केलेला वापरकर्ता USB डीबग करणे चालू करू शकत नाही. हे वैशिष्‍ट्य वापरण्‍यासाठी, प्राथमिक वापरकर्त्‍यावर स्विच करा."</string>
     <string name="usb_contaminant_title" msgid="206854874263058490">"USB पोर्ट बंद करा"</string>
-    <!-- no translation found for usb_contaminant_message (7379089091591609111) -->
-    <skip />
+    <string name="usb_contaminant_message" msgid="7379089091591609111">"तुमच्या डिव्हाइसला ओलावा किंवा धूळीपासून संरक्षित करण्यासाठी, USB पोर्ट बंद आहे आणि अ‍ॅक्सेसरी डिटेक्ट करणार नाही. \n\n तुम्हाला USB पोर्ट पुन्हा वापरणे ठीक आहे तेव्हा सूचित केले जाईल."</string>
     <string name="usb_port_enabled" msgid="7906141351687694867">"चार्जर आणि अ‍ॅक्सेसरी शोधण्यासाठी USB पोर्ट सुरू केलेले आहे"</string>
     <string name="usb_disable_contaminant_detection" msgid="2103905315747120033">"USB सुरू करा"</string>
-    <!-- no translation found for learn_more (5000517160980853569) -->
-    <skip />
+    <string name="learn_more" msgid="5000517160980853569">"अधिक जाणून घ्या"</string>
     <string name="compat_mode_on" msgid="6623839244840638213">"स्क्रीन भरण्यासाठी झूम करा"</string>
     <string name="compat_mode_off" msgid="4434467572461327898">"स्क्रीन भरण्यासाठी ताणा"</string>
     <string name="global_action_screenshot" msgid="8329831278085426283">"स्क्रीनशॉट"</string>
@@ -199,6 +197,7 @@
     <string name="carrier_network_change_mode" msgid="8149202439957837762">"वाहक नेटवर्क बदलत आहे"</string>
     <string name="accessibility_battery_details" msgid="7645516654955025422">"बॅटरी तपशील उघडा"</string>
     <string name="accessibility_battery_level" msgid="7451474187113371965">"बॅटरी <xliff:g id="NUMBER">%d</xliff:g> टक्के."</string>
+    <string name="accessibility_battery_level_with_estimate" msgid="9033100930684311630">"बॅटरी <xliff:g id="PERCENTAGE">%1$s</xliff:g> टक्के, तुमच्या वापराच्या आधारावर सुमारे <xliff:g id="TIME">%2$s</xliff:g> शिल्लक आहे"</string>
     <string name="accessibility_battery_level_charging" msgid="1147587904439319646">"बॅटरी चार्ज होत आहे, <xliff:g id="BATTERY_PERCENTAGE">%d</xliff:g> टक्के."</string>
     <string name="accessibility_settings_button" msgid="799583911231893380">"सिस्‍टम सेटिंग्‍ज."</string>
     <string name="accessibility_notifications_button" msgid="4498000369779421892">"सूचना."</string>
@@ -458,10 +457,8 @@
     <string name="media_projection_remember_text" msgid="3103510882172746752">"पुन्हा दर्शवू नका"</string>
     <string name="clear_all_notifications_text" msgid="814192889771462828">"सर्व साफ करा"</string>
     <string name="manage_notifications_text" msgid="2386728145475108753">"व्यवस्थापित करा"</string>
-    <!-- no translation found for notification_section_header_gentle (4372438504154095677) -->
-    <skip />
-    <!-- no translation found for accessibility_notification_section_header_gentle_clear_all (4286716295850400959) -->
-    <skip />
+    <string name="notification_section_header_gentle" msgid="4372438504154095677">"सायलंट सूचना"</string>
+    <string name="accessibility_notification_section_header_gentle_clear_all" msgid="4286716295850400959">"सर्व सायलंट सूचना साफ करा"</string>
     <string name="dnd_suppressing_shade_text" msgid="1904574852846769301">"व्यत्यय आणून नकाद्वारे सूचना थांबवल्या"</string>
     <string name="media_projection_action_text" msgid="8470872969457985954">"आता सुरू करा"</string>
     <string name="empty_shade_text" msgid="708135716272867002">"सूचना नाहीत"</string>
@@ -645,21 +642,16 @@
     <string name="inline_block_button" msgid="8735843688021655065">"ब्लॉक करा"</string>
     <string name="inline_keep_button" msgid="6665940297019018232">"दाखवणे सुरू ठेवा"</string>
     <string name="inline_minimize_button" msgid="966233327974702195">"लहान करा"</string>
-    <!-- no translation found for inline_silent_button_silent (5315879183296940969) -->
-    <skip />
+    <string name="inline_silent_button_silent" msgid="5315879183296940969">"सायलंट"</string>
     <string name="inline_silent_button_stay_silent" msgid="6308371431217601009">"सायलंट रहा"</string>
-    <!-- no translation found for inline_silent_button_alert (6008435419895088034) -->
-    <skip />
+    <string name="inline_silent_button_alert" msgid="6008435419895088034">"सूचना देत आहे"</string>
     <string name="inline_silent_button_keep_alerting" msgid="327696842264359693">"सूचना देत रहा"</string>
     <string name="inline_turn_off_notifications" msgid="8635596135532202355">"सूचना बंद करा"</string>
     <string name="inline_keep_showing_app" msgid="1723113469580031041">"या अ‍ॅपकडील सूचना दाखवणे सुरू ठेवायचे?"</string>
-    <string name="notification_silence_title" msgid="7352089096356977930">"हळू आवाजातील"</string>
-    <string name="notification_alert_title" msgid="3966526305405016221">"प्राधान्यकृत"</string>
-    <string name="notification_channel_summary_low" msgid="1065819618107531284">"फक्त पुल डाउन शेडमध्ये सूचनांवर लक्ष केंद्रीत करण्यात मदत करते. नेहमी सायलंट."</string>
-    <string name="notification_channel_summary_low_status" msgid="2702170424808743755">"कमी प्राधान्य असलेल्या सूचना दाखवते. नेहमी सायलंट."</string>
-    <string name="notification_channel_summary_low_lock" msgid="7966605244472624458">"कमी प्राधान्य असलेल्या सूचना दाखवते. नेहमी सायलंट."</string>
-    <string name="notification_channel_summary_low_status_lock" msgid="7012562768950012739">"कमी प्राधान्य असलेल्या सूचना दाखवते. नेहमी सायलंट."</string>
-    <string name="notification_channel_summary_default" msgid="3847289783382316019">"आवाज आणि स्टेटस बार आयकनसह तुमचे लक्ष वेधून घेते. लॉक स्‍क्रीनवर दाखवते."</string>
+    <string name="notification_silence_title" msgid="5763240612242137433">"सायलंट"</string>
+    <string name="notification_alert_title" msgid="8031196611815490340">"सूचना देत आहे"</string>
+    <string name="notification_channel_summary_low" msgid="3387466082089715555">"आवाज किंवा व्हायब्रेशनशिवाय तुम्हाला लक्ष केंद्रित करण्यास मदत करते."</string>
+    <string name="notification_channel_summary_default" msgid="5994062840431965586">"आवाज किंवा व्हायब्रेशनने तुमचे लक्ष वेधून घेते."</string>
     <string name="notification_unblockable_desc" msgid="4556908766584964102">"या सूचनांमध्ये सुधारणा केली जाऊ शकत नाही."</string>
     <string name="notification_multichannel_desc" msgid="4695920306092240550">"या सूचनांचा संच येथे कॉन्फिगर केला जाऊ शकत नाही"</string>
     <string name="notification_delegate_header" msgid="2857691673814814270">"प्रॉक्सी केलेल्या सूचना"</string>
@@ -908,8 +900,7 @@
     <string name="slice_permission_allow" msgid="2340244901366722709">"अनुमती द्या"</string>
     <string name="slice_permission_deny" msgid="7683681514008048807">"नकार द्या"</string>
     <string name="auto_saver_title" msgid="1217959994732964228">"बॅटरी बचतकर्ता शेड्यूल करण्यासाठी टॅप करा"</string>
-    <!-- no translation found for auto_saver_text (2563289953551438248) -->
-    <skip />
+    <string name="auto_saver_text" msgid="2563289953551438248">"बॅटरी संपण्याची शक्यता असल्यास सुरू करा"</string>
     <string name="no_auto_saver_action" msgid="8086002101711328500">"नाही नको"</string>
     <string name="auto_saver_enabled_title" msgid="6726474226058316862">"बॅटरी बचतकर्ता शेड्यूल सुरू केले आहे"</string>
     <string name="auto_saver_enabled_text" msgid="874711029884777579">"बॅटरी <xliff:g id="PERCENTAGE">%d</xliff:g>%% पेक्षा खाली गेल्यास बॅटरी सेव्हर आपोआप सुरू होईल."</string>
@@ -942,4 +933,6 @@
     <string name="bubble_accessibility_action_move_bottom_left" msgid="206369104473183217">"तळाशी डावीकडे हलवा"</string>
     <string name="bubble_accessibility_action_move_bottom_right" msgid="8705660152384312329">"तळाशी उजवीकडे हलवा"</string>
     <string name="bubble_dismiss_text" msgid="8028337712674081668">"डिसमिस करा"</string>
+    <string name="notification_content_system_nav_changed" msgid="7218093915747788444">"सिस्टम नेव्हिगेशन अपडेट केले. बदल करण्यासाठी, सेटिंग्जवर जा."</string>
+    <string name="notification_content_gesture_nav_available" msgid="8111130443656460792">"सिस्टम नेव्हिगेशन अपडेट करण्यासाठी सेटिंग्जवर जा"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-ms/strings.xml b/packages/SystemUI/res/values-ms/strings.xml
index 716c24f..d0f9448 100644
--- a/packages/SystemUI/res/values-ms/strings.xml
+++ b/packages/SystemUI/res/values-ms/strings.xml
@@ -62,12 +62,10 @@
     <string name="usb_debugging_secondary_user_title" msgid="6353808721761220421">"Penyahpepijatan USB tidak dibenarkan"</string>
     <string name="usb_debugging_secondary_user_message" msgid="6067122453571699801">"Pengguna yang log masuk ke peranti ini pada masa ini tidak boleh menghidupkan penyahpepijatan USB. Untuk menggunakan ciri ini, tukar kepada pengguna utama."</string>
     <string name="usb_contaminant_title" msgid="206854874263058490">"Port USB dilumpuhkan"</string>
-    <!-- no translation found for usb_contaminant_message (7379089091591609111) -->
-    <skip />
+    <string name="usb_contaminant_message" msgid="7379089091591609111">"Untuk melindungi peranti anda daripada cecair atau serpihan, port USB dilumpuhkan dan tidak akan mengesan sebarang aksesori.\n\nAnda akan dimaklumi apabila selamat untuk menggunakan port USB lagi."</string>
     <string name="usb_port_enabled" msgid="7906141351687694867">"Port USB didayakan untuk mengesan pengecas dan aksesori"</string>
     <string name="usb_disable_contaminant_detection" msgid="2103905315747120033">"Dayakan USB"</string>
-    <!-- no translation found for learn_more (5000517160980853569) -->
-    <skip />
+    <string name="learn_more" msgid="5000517160980853569">"Ketahui lebih lanjut"</string>
     <string name="compat_mode_on" msgid="6623839244840638213">"Zum untuk memenuhi skrin"</string>
     <string name="compat_mode_off" msgid="4434467572461327898">"Regang utk memenuhi skrin"</string>
     <string name="global_action_screenshot" msgid="8329831278085426283">"Tangkapan skrin"</string>
@@ -199,6 +197,7 @@
     <string name="carrier_network_change_mode" msgid="8149202439957837762">"Rangkaian pembawa berubah"</string>
     <string name="accessibility_battery_details" msgid="7645516654955025422">"Buka butiran bateri"</string>
     <string name="accessibility_battery_level" msgid="7451474187113371965">"Bateri <xliff:g id="NUMBER">%d</xliff:g> peratus."</string>
+    <string name="accessibility_battery_level_with_estimate" msgid="9033100930684311630">"Bateri <xliff:g id="PERCENTAGE">%1$s</xliff:g> peratus, tinggal kira-kira <xliff:g id="TIME">%2$s</xliff:g> lagi berdasarkan penggunaan anda"</string>
     <string name="accessibility_battery_level_charging" msgid="1147587904439319646">"Bateri mengecas, <xliff:g id="BATTERY_PERCENTAGE">%d</xliff:g> peratus."</string>
     <string name="accessibility_settings_button" msgid="799583911231893380">"Tetapan sistem."</string>
     <string name="accessibility_notifications_button" msgid="4498000369779421892">"Pemberitahuan."</string>
@@ -458,10 +457,8 @@
     <string name="media_projection_remember_text" msgid="3103510882172746752">"Jangan tunjukkan lagi"</string>
     <string name="clear_all_notifications_text" msgid="814192889771462828">"Kosongkan semua"</string>
     <string name="manage_notifications_text" msgid="2386728145475108753">"Urus"</string>
-    <!-- no translation found for notification_section_header_gentle (4372438504154095677) -->
-    <skip />
-    <!-- no translation found for accessibility_notification_section_header_gentle_clear_all (4286716295850400959) -->
-    <skip />
+    <string name="notification_section_header_gentle" msgid="4372438504154095677">"Pemberitahuan senyap"</string>
+    <string name="accessibility_notification_section_header_gentle_clear_all" msgid="4286716295850400959">"Kosongkan semua pemberitahuan senyap"</string>
     <string name="dnd_suppressing_shade_text" msgid="1904574852846769301">"Pemberitahuan dijeda oleh Jangan Ganggu"</string>
     <string name="media_projection_action_text" msgid="8470872969457985954">"Mulakan sekarang"</string>
     <string name="empty_shade_text" msgid="708135716272867002">"Tiada pemberitahuan"</string>
@@ -645,21 +642,16 @@
     <string name="inline_block_button" msgid="8735843688021655065">"Sekat"</string>
     <string name="inline_keep_button" msgid="6665940297019018232">"Terus tunjukkan"</string>
     <string name="inline_minimize_button" msgid="966233327974702195">"Minimumkan"</string>
-    <!-- no translation found for inline_silent_button_silent (5315879183296940969) -->
-    <skip />
+    <string name="inline_silent_button_silent" msgid="5315879183296940969">"Senyap"</string>
     <string name="inline_silent_button_stay_silent" msgid="6308371431217601009">"Kekal senyap"</string>
-    <!-- no translation found for inline_silent_button_alert (6008435419895088034) -->
-    <skip />
+    <string name="inline_silent_button_alert" msgid="6008435419895088034">"Memaklumi"</string>
     <string name="inline_silent_button_keep_alerting" msgid="327696842264359693">"Teruskan memberikan makluman"</string>
     <string name="inline_turn_off_notifications" msgid="8635596135532202355">"Matikan pemberitahuan"</string>
     <string name="inline_keep_showing_app" msgid="1723113469580031041">"Terus tunjukkan pemberitahuan daripada apl ini?"</string>
-    <string name="notification_silence_title" msgid="7352089096356977930">"Lembut"</string>
-    <string name="notification_alert_title" msgid="3966526305405016221">"Diutamakan"</string>
-    <string name="notification_channel_summary_low" msgid="1065819618107531284">"Membantu anda fokus dengan memaparkan pemberitahuan sahaja dalam bidai tarik turun. Sentiasa senyap."</string>
-    <string name="notification_channel_summary_low_status" msgid="2702170424808743755">"Dipaparkan di bawah pemberitahuan keutamaan. Sentiasa senyap."</string>
-    <string name="notification_channel_summary_low_lock" msgid="7966605244472624458">"Dipaparkan di bawah pemberitahuan keutamaan. Sentiasa senyap."</string>
-    <string name="notification_channel_summary_low_status_lock" msgid="7012562768950012739">"Dipaparkan di bawah pemberitahuan keutamaan. Sentiasa senyap."</string>
-    <string name="notification_channel_summary_default" msgid="3847289783382316019">"Menarik perhatian anda dengan bunyi &amp; ikon bar status. Ditunjukkan pada skrin kunci."</string>
+    <string name="notification_silence_title" msgid="5763240612242137433">"Senyap"</string>
+    <string name="notification_alert_title" msgid="8031196611815490340">"Memaklumi"</string>
+    <string name="notification_channel_summary_low" msgid="3387466082089715555">"Membantu anda fokus tanpa bunyi atau getaran."</string>
+    <string name="notification_channel_summary_default" msgid="5994062840431965586">"Menarik perhatian anda dengan bunyi atau getaran."</string>
     <string name="notification_unblockable_desc" msgid="4556908766584964102">"Pemberitahuan ini tidak boleh diubah suai."</string>
     <string name="notification_multichannel_desc" msgid="4695920306092240550">"Kumpulan pemberitahuan ini tidak boleh dikonfigurasikan di sini"</string>
     <string name="notification_delegate_header" msgid="2857691673814814270">"Pemberitahuan berproksi"</string>
@@ -908,8 +900,7 @@
     <string name="slice_permission_allow" msgid="2340244901366722709">"Benarkan"</string>
     <string name="slice_permission_deny" msgid="7683681514008048807">"Tolak"</string>
     <string name="auto_saver_title" msgid="1217959994732964228">"Ketik untuk menjadualkan Penjimat Bateri"</string>
-    <!-- no translation found for auto_saver_text (2563289953551438248) -->
-    <skip />
+    <string name="auto_saver_text" msgid="2563289953551438248">"Hidupkan apabila bateri berkemungkinan habis"</string>
     <string name="no_auto_saver_action" msgid="8086002101711328500">"Tidak perlu"</string>
     <string name="auto_saver_enabled_title" msgid="6726474226058316862">"Jadual Penjimat Bateri dihidupkan"</string>
     <string name="auto_saver_enabled_text" msgid="874711029884777579">"Penjimat Bateri akan dihidupkan secara automatik setelah kuasa bateri kurang daripada <xliff:g id="PERCENTAGE">%d</xliff:g>%%."</string>
@@ -942,4 +933,6 @@
     <string name="bubble_accessibility_action_move_bottom_left" msgid="206369104473183217">"Alihkan ke bawah sebelah kiri"</string>
     <string name="bubble_accessibility_action_move_bottom_right" msgid="8705660152384312329">"Alihkan ke bawah sebelah kanan"</string>
     <string name="bubble_dismiss_text" msgid="8028337712674081668">"Ketepikan"</string>
+    <string name="notification_content_system_nav_changed" msgid="7218093915747788444">"Navigasi sistem dikemas kini. Untuk membuat perubahan, pergi ke Tetapan."</string>
+    <string name="notification_content_gesture_nav_available" msgid="8111130443656460792">"Pergi ke Tetapan untuk mengemas kini navigasi sistem"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-my/strings.xml b/packages/SystemUI/res/values-my/strings.xml
index ef095b3..650f35e 100644
--- a/packages/SystemUI/res/values-my/strings.xml
+++ b/packages/SystemUI/res/values-my/strings.xml
@@ -197,6 +197,7 @@
     <string name="carrier_network_change_mode" msgid="8149202439957837762">"ဝန်ဆောင်မှုပေးသူ ကွန်ရက် ပြောင်းလဲနေသည်။"</string>
     <string name="accessibility_battery_details" msgid="7645516654955025422">"ဘက်ထရီ အသေးစိတ် အချက်အလက်များကို ဖွင့်ပါ"</string>
     <string name="accessibility_battery_level" msgid="7451474187113371965">"ဘတ္တရီ <xliff:g id="NUMBER">%d</xliff:g> ရာခိုင်နှုန်း။"</string>
+    <string name="accessibility_battery_level_with_estimate" msgid="9033100930684311630">"ဘက်ထရီ <xliff:g id="PERCENTAGE">%1$s</xliff:g> ရာခိုင်နှုန်း၊ သင်၏ အသုံးပြုမှုအပေါ် မူတည်၍ <xliff:g id="TIME">%2$s</xliff:g> ခန့်ကျန်သည်"</string>
     <string name="accessibility_battery_level_charging" msgid="1147587904439319646">"ဘက်ထရီအားသွင်းနေသည်၊ <xliff:g id="BATTERY_PERCENTAGE">%d</xliff:g> %%။"</string>
     <string name="accessibility_settings_button" msgid="799583911231893380">"စနစ်အပြင်အဆင်များ"</string>
     <string name="accessibility_notifications_button" msgid="4498000369779421892">"အကြောင်းကြားချက်များ။"</string>
@@ -586,7 +587,7 @@
     <string name="show_battery_percentage_summary" msgid="3215025775576786037">"အားမသွင်းနေစဉ်တွင် ဘတ်ထရီအဆင့် ရာခိုင်နှုန်းကို အခြေနေပြဘား အိုင်ကွန်တွင် ပြပါ"</string>
     <string name="quick_settings" msgid="10042998191725428">"အမြန် ဆက်တင်များ"</string>
     <string name="status_bar" msgid="4877645476959324760">"အခြေအနေပြနေရာ"</string>
-    <string name="overview" msgid="4018602013895926956">"ခြုံငုံသုံးသပ်ချက်"</string>
+    <string name="overview" msgid="4018602013895926956">"အကျဉ်း"</string>
     <string name="demo_mode" msgid="2532177350215638026">"စနစ် UI စရုပ်ပြမုဒ်"</string>
     <string name="enable_demo_mode" msgid="4844205668718636518">"သရုပ်ပြမုဒ်ကို ဖွင့်ရန်"</string>
     <string name="show_demo_mode" msgid="2018336697782464029">"သရုပ်ပြမုဒ် ပြရန်"</string>
@@ -647,13 +648,10 @@
     <string name="inline_silent_button_keep_alerting" msgid="327696842264359693">"ဆက်လက် သတိပေးရန်"</string>
     <string name="inline_turn_off_notifications" msgid="8635596135532202355">"အကြောင်းကြားချက်များ ပိတ်ရန်"</string>
     <string name="inline_keep_showing_app" msgid="1723113469580031041">"ဤအက်ပ်ထံမှ အကြောင်းကြားချက်များကို ဆက်ပြလိုပါသလား။"</string>
-    <string name="notification_silence_title" msgid="7352089096356977930">"မသိမသာ"</string>
-    <string name="notification_alert_title" msgid="3966526305405016221">"ဦးစားပေး"</string>
-    <string name="notification_channel_summary_low" msgid="1065819618107531284">"အပေါ်မှဆွဲချသည့် နေရာတွင်သာ အကြောင်းကြားချက်များကို အာရုံစိုက်ရန် အထောက်ကူပြုပေးသည်။ အမြဲ အသံတိတ်ရန်။"</string>
-    <string name="notification_channel_summary_low_status" msgid="2702170424808743755">"ဦးစားပေးအကြောင်းကြားချက်များ၏ အောက်တွင်ဖော်ပြသည်။ အမြဲ အသံတိတ်ရန်။"</string>
-    <string name="notification_channel_summary_low_lock" msgid="7966605244472624458">"ဦးစားပေးအကြောင်းကြားချက်များ၏ အောက်တွင်ဖော်ပြသည်။ အမြဲ အသံတိတ်ရန်။"</string>
-    <string name="notification_channel_summary_low_status_lock" msgid="7012562768950012739">"ဦးစားပေးအကြောင်းကြားချက်များ၏ အောက်တွင်ဖော်ပြသည်။ အမြဲ အသံတိတ်ရန်။"</string>
-    <string name="notification_channel_summary_default" msgid="3847289783382316019">"အသံ၊ အခြေအနေပြဘား သင်္ကေတတို့ဖြင့် သတိပေးသည်။ လော့ခ်ချထားချိန်မျက်နှာပြင်တွင် ပြသည်။"</string>
+    <string name="notification_silence_title" msgid="5763240612242137433">"အသံတိတ်ရန်"</string>
+    <string name="notification_alert_title" msgid="8031196611815490340">"သတိပေးခြင်း"</string>
+    <string name="notification_channel_summary_low" msgid="3387466082089715555">"အသံ သို့မဟုတ် တုန်ခါမှု မပါဘဲ အာရုံစိုက်နိုင်စေရန် ကူညီပေးသည်။"</string>
+    <string name="notification_channel_summary_default" msgid="5994062840431965586">"အသံ သို့မဟုတ် တုန်ခါမှုဖြင့် အာရုံစိုက်လာအောင် ပြုလုပ်သည်။"</string>
     <string name="notification_unblockable_desc" msgid="4556908766584964102">"ဤအကြောင်းကြားချက်များကို ပြုပြင်၍ မရပါ။"</string>
     <string name="notification_multichannel_desc" msgid="4695920306092240550">"ဤအကြောင်းကြားချက်အုပ်စုကို ဤနေရာတွင် စီစဉ်သတ်မှတ်၍ မရပါ"</string>
     <string name="notification_delegate_header" msgid="2857691673814814270">"ပရောက်စီထည့်ထားသော အကြောင်းကြားချက်"</string>
@@ -935,4 +933,6 @@
     <string name="bubble_accessibility_action_move_bottom_left" msgid="206369104473183217">"ဘယ်အောက်ခြေသို့ ရွှေ့ရန်"</string>
     <string name="bubble_accessibility_action_move_bottom_right" msgid="8705660152384312329">"ညာအောက်ခြေသို့ ရွှေ့ပါ"</string>
     <string name="bubble_dismiss_text" msgid="8028337712674081668">"ပယ်ရန်"</string>
+    <string name="notification_content_system_nav_changed" msgid="7218093915747788444">"စနစ်လမ်းညွှန်ခြင်း အပ်ဒိတ်လုပ်ပြီးပါပြီ။ အပြောင်းအလဲများ ပြုလုပ်ရန် \'ဆက်တင်များ\' သို့သွားပါ။"</string>
+    <string name="notification_content_gesture_nav_available" msgid="8111130443656460792">"စနစ်လမ်းညွှန်ခြင်း အပ်ဒိတ်လုပ်ရန် \'ဆက်တင်များ\' သို့သွားပါ"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-nb/strings.xml b/packages/SystemUI/res/values-nb/strings.xml
index 70c0bb2..c24fee5 100644
--- a/packages/SystemUI/res/values-nb/strings.xml
+++ b/packages/SystemUI/res/values-nb/strings.xml
@@ -62,12 +62,10 @@
     <string name="usb_debugging_secondary_user_title" msgid="6353808721761220421">"USB-feilsøking er ikke tillatt"</string>
     <string name="usb_debugging_secondary_user_message" msgid="6067122453571699801">"Brukeren som for øyeblikket er logget på denne enheten, kan ikke slå på USB-feilsøking. For å bruke denne funksjonen, bytt til hovedbrukeren."</string>
     <string name="usb_contaminant_title" msgid="206854874263058490">"USB-porten er deaktivert"</string>
-    <!-- no translation found for usb_contaminant_message (7379089091591609111) -->
-    <skip />
+    <string name="usb_contaminant_message" msgid="7379089091591609111">"For å beskytte enheten din mot væsker eller rusk er USB-porten deaktivert og kan ikke oppdage tilbehør.\n\nDu blir varslet når det er trygt å bruke USB-porten igjen."</string>
     <string name="usb_port_enabled" msgid="7906141351687694867">"Registrering av ladere og tilbehør er slått på for USB-porten"</string>
     <string name="usb_disable_contaminant_detection" msgid="2103905315747120033">"Slå på USB"</string>
-    <!-- no translation found for learn_more (5000517160980853569) -->
-    <skip />
+    <string name="learn_more" msgid="5000517160980853569">"Finn ut mer"</string>
     <string name="compat_mode_on" msgid="6623839244840638213">"Zoom for å fylle skjermen"</string>
     <string name="compat_mode_off" msgid="4434467572461327898">"Strekk for å fylle skjerm"</string>
     <string name="global_action_screenshot" msgid="8329831278085426283">"Skjermdump"</string>
@@ -199,6 +197,7 @@
     <string name="carrier_network_change_mode" msgid="8149202439957837762">"Bytting av operatørnettverk"</string>
     <string name="accessibility_battery_details" msgid="7645516654955025422">"Åpne informasjon om batteriet"</string>
     <string name="accessibility_battery_level" msgid="7451474187113371965">"Batteri – <xliff:g id="NUMBER">%d</xliff:g> prosent."</string>
+    <string name="accessibility_battery_level_with_estimate" msgid="9033100930684311630">"Batterinivået er <xliff:g id="PERCENTAGE">%1$s</xliff:g> prosent – omtrent <xliff:g id="TIME">%2$s</xliff:g> gjenstår basert på bruken din"</string>
     <string name="accessibility_battery_level_charging" msgid="1147587904439319646">"Batteriet lades – <xliff:g id="BATTERY_PERCENTAGE">%d</xliff:g> prosent."</string>
     <string name="accessibility_settings_button" msgid="799583911231893380">"Systeminnstillinger."</string>
     <string name="accessibility_notifications_button" msgid="4498000369779421892">"Varsler."</string>
@@ -458,10 +457,8 @@
     <string name="media_projection_remember_text" msgid="3103510882172746752">"Ikke vis igjen"</string>
     <string name="clear_all_notifications_text" msgid="814192889771462828">"Fjern alt"</string>
     <string name="manage_notifications_text" msgid="2386728145475108753">"Administrer"</string>
-    <!-- no translation found for notification_section_header_gentle (4372438504154095677) -->
-    <skip />
-    <!-- no translation found for accessibility_notification_section_header_gentle_clear_all (4286716295850400959) -->
-    <skip />
+    <string name="notification_section_header_gentle" msgid="4372438504154095677">"Lydløse varsler"</string>
+    <string name="accessibility_notification_section_header_gentle_clear_all" msgid="4286716295850400959">"Fjern alle lydløse varsler"</string>
     <string name="dnd_suppressing_shade_text" msgid="1904574852846769301">"Varsler er satt på pause av «Ikke forstyrr»"</string>
     <string name="media_projection_action_text" msgid="8470872969457985954">"Start nå"</string>
     <string name="empty_shade_text" msgid="708135716272867002">"Ingen varsler"</string>
@@ -645,21 +642,16 @@
     <string name="inline_block_button" msgid="8735843688021655065">"Blokkér"</string>
     <string name="inline_keep_button" msgid="6665940297019018232">"Fortsett å vise"</string>
     <string name="inline_minimize_button" msgid="966233327974702195">"Minimer"</string>
-    <!-- no translation found for inline_silent_button_silent (5315879183296940969) -->
-    <skip />
+    <string name="inline_silent_button_silent" msgid="5315879183296940969">"Lydløs"</string>
     <string name="inline_silent_button_stay_silent" msgid="6308371431217601009">"Forbli lydløs"</string>
-    <!-- no translation found for inline_silent_button_alert (6008435419895088034) -->
-    <skip />
+    <string name="inline_silent_button_alert" msgid="6008435419895088034">"Varsling"</string>
     <string name="inline_silent_button_keep_alerting" msgid="327696842264359693">"Fortsett å varsle"</string>
     <string name="inline_turn_off_notifications" msgid="8635596135532202355">"Slå av varsler"</string>
     <string name="inline_keep_showing_app" msgid="1723113469580031041">"Vil du fortsette å vise varsler fra denne appen?"</string>
-    <string name="notification_silence_title" msgid="7352089096356977930">"Diskré"</string>
-    <string name="notification_alert_title" msgid="3966526305405016221">"Prioritert"</string>
-    <string name="notification_channel_summary_low" msgid="1065819618107531284">"Hjelper deg med å fokusere, med varsler bare i nedtrekkspanelet. Alltid lydløs."</string>
-    <string name="notification_channel_summary_low_status" msgid="2702170424808743755">"Vises under prioritetsvarsler. Alltid lydløs."</string>
-    <string name="notification_channel_summary_low_lock" msgid="7966605244472624458">"Vises under prioritetsvarsler. Alltid lydløs."</string>
-    <string name="notification_channel_summary_low_status_lock" msgid="7012562768950012739">"Vises under prioritetsvarsler. Alltid lydløs."</string>
-    <string name="notification_channel_summary_default" msgid="3847289783382316019">"Får oppmerksomheten din med lyd og et ikon i statusfeltet. Vises på låseskjermen."</string>
+    <string name="notification_silence_title" msgid="5763240612242137433">"Lydløs"</string>
+    <string name="notification_alert_title" msgid="8031196611815490340">"Varsling"</string>
+    <string name="notification_channel_summary_low" msgid="3387466082089715555">"Hjelper deg med å fokusere uten lyd eller vibrering."</string>
+    <string name="notification_channel_summary_default" msgid="5994062840431965586">"Får oppmerksomheten din med lyd eller vibrering."</string>
     <string name="notification_unblockable_desc" msgid="4556908766584964102">"Disse varslene kan ikke endres."</string>
     <string name="notification_multichannel_desc" msgid="4695920306092240550">"Denne varselgruppen kan ikke konfigureres her"</string>
     <string name="notification_delegate_header" msgid="2857691673814814270">"Omdirigert varsel"</string>
@@ -908,8 +900,7 @@
     <string name="slice_permission_allow" msgid="2340244901366722709">"Tillat"</string>
     <string name="slice_permission_deny" msgid="7683681514008048807">"Avvis"</string>
     <string name="auto_saver_title" msgid="1217959994732964228">"Trykk for å planlegge batterisparing"</string>
-    <!-- no translation found for auto_saver_text (2563289953551438248) -->
-    <skip />
+    <string name="auto_saver_text" msgid="2563289953551438248">"Slå på når det er sannsynlig at du går tom for batteri"</string>
     <string name="no_auto_saver_action" msgid="8086002101711328500">"Nei takk"</string>
     <string name="auto_saver_enabled_title" msgid="6726474226058316862">"Tidsplan for batterisparing er slått på"</string>
     <string name="auto_saver_enabled_text" msgid="874711029884777579">"Batterisparing slås på automatisk når batteriet er lavere enn <xliff:g id="PERCENTAGE">%d</xliff:g> %%."</string>
@@ -942,4 +933,6 @@
     <string name="bubble_accessibility_action_move_bottom_left" msgid="206369104473183217">"Flytt til nederst til venstre"</string>
     <string name="bubble_accessibility_action_move_bottom_right" msgid="8705660152384312329">"Flytt til nederst til høyre"</string>
     <string name="bubble_dismiss_text" msgid="8028337712674081668">"Avvis"</string>
+    <string name="notification_content_system_nav_changed" msgid="7218093915747788444">"Systemnavigeringen er oppdatert. For å gjøre endringer, gå til Innstillinger."</string>
+    <string name="notification_content_gesture_nav_available" msgid="8111130443656460792">"Gå til Innstillinger for å oppdatere systemnavigeringen"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-ne/strings.xml b/packages/SystemUI/res/values-ne/strings.xml
index 84989ee..4f6ffa5 100644
--- a/packages/SystemUI/res/values-ne/strings.xml
+++ b/packages/SystemUI/res/values-ne/strings.xml
@@ -62,12 +62,10 @@
     <string name="usb_debugging_secondary_user_title" msgid="6353808721761220421">"USB डिबग गर्न अनुमति छैन"</string>
     <string name="usb_debugging_secondary_user_message" msgid="6067122453571699801">"हाल यस यन्त्रमा साइन इन हुनुभएको प्रयोगकर्ताले USB डिबग सक्रिय गर्न सक्नुहुन्न। यो सुविधाको प्रयोग गर्न प्राथमिक प्रयोगकर्तामा बदल्नुहोस्‌।"</string>
     <string name="usb_contaminant_title" msgid="206854874263058490">"USB पोर्ट असक्षम पारियो"</string>
-    <!-- no translation found for usb_contaminant_message (7379089091591609111) -->
-    <skip />
+    <string name="usb_contaminant_message" msgid="7379089091591609111">"तपाईंको यन्त्रलाई तरल पदार्थ वा धुलोबाट जोगाउन यसको USB पोर्ट असक्षम पारिएको छ र यसले कुनै पनि सहायक उपकरणहरू पहिचान गर्ने छैन।\n\nउक्त USB पोर्ट फेरि प्रयोग गर्दा हुन्छ भने तपाईंलाई यसबारे सूचित गरिने छ।"</string>
     <string name="usb_port_enabled" msgid="7906141351687694867">"चार्जर तथा सामानहरू पत्ता लगाउन सक्षम पारिएको USB पोर्ट"</string>
     <string name="usb_disable_contaminant_detection" msgid="2103905315747120033">"USB सक्षम पार्नुहोस्"</string>
-    <!-- no translation found for learn_more (5000517160980853569) -->
-    <skip />
+    <string name="learn_more" msgid="5000517160980853569">"थप जान्नुहोस्"</string>
     <string name="compat_mode_on" msgid="6623839244840638213">"स्क्रिन भर्न जुम गर्नुहोस्"</string>
     <string name="compat_mode_off" msgid="4434467572461327898">"स्क्रिन भर्न तन्काउनुहोस्"</string>
     <string name="global_action_screenshot" msgid="8329831278085426283">"स्क्रिनसट"</string>
@@ -199,6 +197,7 @@
     <string name="carrier_network_change_mode" msgid="8149202439957837762">"सेवा प्रदायकको नेटवर्क परिवर्तन गर्ने आइकन"</string>
     <string name="accessibility_battery_details" msgid="7645516654955025422">"ब्याट्री सम्बन्धी विवरणहरूलाई खोल्नुहोस्"</string>
     <string name="accessibility_battery_level" msgid="7451474187113371965">"ब्याट्री <xliff:g id="NUMBER">%d</xliff:g> प्रतिशत"</string>
+    <string name="accessibility_battery_level_with_estimate" msgid="9033100930684311630">"ब्याट्रीको चार्ज <xliff:g id="PERCENTAGE">%1$s</xliff:g> प्रतिशत छ, तपाईंको प्रयोगका आधारमा <xliff:g id="TIME">%2$s</xliff:g> बाँकी छ"</string>
     <string name="accessibility_battery_level_charging" msgid="1147587904439319646">"ब्याट्री चार्ज हुँदैछ, <xliff:g id="BATTERY_PERCENTAGE">%d</xliff:g> प्रतिशत।"</string>
     <string name="accessibility_settings_button" msgid="799583911231893380">"प्रणाली सेटिङहरू"</string>
     <string name="accessibility_notifications_button" msgid="4498000369779421892">"सूचनाहरू।"</string>
@@ -458,10 +457,8 @@
     <string name="media_projection_remember_text" msgid="3103510882172746752">"फेरि नदेखाउनुहोस्"</string>
     <string name="clear_all_notifications_text" msgid="814192889771462828">"सबै हटाउनुहोस्"</string>
     <string name="manage_notifications_text" msgid="2386728145475108753">"व्यवस्थित गर्नुहोस्"</string>
-    <!-- no translation found for notification_section_header_gentle (4372438504154095677) -->
-    <skip />
-    <!-- no translation found for accessibility_notification_section_header_gentle_clear_all (4286716295850400959) -->
-    <skip />
+    <string name="notification_section_header_gentle" msgid="4372438504154095677">"मौन सूचनाहरू"</string>
+    <string name="accessibility_notification_section_header_gentle_clear_all" msgid="4286716295850400959">"सबै मौन सूचनाहरू हटाउनुहोस्"</string>
     <string name="dnd_suppressing_shade_text" msgid="1904574852846769301">"बाधा नपुऱ्याउनुहोस् नामक मोडमार्फत पज पारिएका सूचनाहरू"</string>
     <string name="media_projection_action_text" msgid="8470872969457985954">"अहिले सुरु गर्नुहोस्"</string>
     <string name="empty_shade_text" msgid="708135716272867002">"कुनै सूचनाहरू छैनन्"</string>
@@ -645,21 +642,16 @@
     <string name="inline_block_button" msgid="8735843688021655065">"रोक लगाउनुहोस्"</string>
     <string name="inline_keep_button" msgid="6665940297019018232">"देखाउने क्रम जारी राख्नुहोस्"</string>
     <string name="inline_minimize_button" msgid="966233327974702195">"सानो बनाउनुहोस्"</string>
-    <!-- no translation found for inline_silent_button_silent (5315879183296940969) -->
-    <skip />
+    <string name="inline_silent_button_silent" msgid="5315879183296940969">"मौन"</string>
     <string name="inline_silent_button_stay_silent" msgid="6308371431217601009">"मौन रहनुहोस्"</string>
-    <!-- no translation found for inline_silent_button_alert (6008435419895088034) -->
-    <skip />
+    <string name="inline_silent_button_alert" msgid="6008435419895088034">"सतर्क गराउने"</string>
     <string name="inline_silent_button_keep_alerting" msgid="327696842264359693">"सर्तक गराइरहनुहोस्"</string>
     <string name="inline_turn_off_notifications" msgid="8635596135532202355">"सूचनाहरू निष्क्रिय पार्नुहोस्"</string>
     <string name="inline_keep_showing_app" msgid="1723113469580031041">"यो अनुप्रयोगका सूचनाहरू देखाउने क्रम जारी राख्ने हो?"</string>
-    <string name="notification_silence_title" msgid="7352089096356977930">"मौन"</string>
-    <string name="notification_alert_title" msgid="3966526305405016221">"प्राथमिकता दिइएको"</string>
-    <string name="notification_channel_summary_low" msgid="1065819618107531284">"तपाईंलाई पुल डाउन सेडमा रहेका सूचनाहरूमा मात्र केन्द्रित हुन मद्दत गर्छ। सधैँ मौन।"</string>
-    <string name="notification_channel_summary_low_status" msgid="2702170424808743755">"न्यून प्राथमिकताका सूचनाहरू देखाउँछ। सधैँ मौन।"</string>
-    <string name="notification_channel_summary_low_lock" msgid="7966605244472624458">"न्यून प्राथमिकताका सूचनाहरू देखाउँछ। सधैँ मौन।"</string>
-    <string name="notification_channel_summary_low_status_lock" msgid="7012562768950012739">"न्यून प्राथमिकताका सूचनाहरू देखाउँछ। सधैँ मौन।"</string>
-    <string name="notification_channel_summary_default" msgid="3847289783382316019">"ध्वनि र वस्तुस्थिति पट्टीको आइकनमार्फत तपाईंको ध्यान खिच्छ। लक स्क्रिनमा देखाउँछ।"</string>
+    <string name="notification_silence_title" msgid="5763240612242137433">"मौन"</string>
+    <string name="notification_alert_title" msgid="8031196611815490340">"सतर्क गराउँदै"</string>
+    <string name="notification_channel_summary_low" msgid="3387466082089715555">"तपाईंलाई आवाज वा कम्पनविना ध्यान केन्द्रित गर्न मद्दत गर्छ।"</string>
+    <string name="notification_channel_summary_default" msgid="5994062840431965586">"ध्वनि वा कम्पनमार्फत तपाईंको ध्यान आकर्षित गर्छ।"</string>
     <string name="notification_unblockable_desc" msgid="4556908766584964102">"यी सूचनाहरू परिमार्जन गर्न मिल्दैन।"</string>
     <string name="notification_multichannel_desc" msgid="4695920306092240550">"यहाँबाट सूचनाहरूको यो समूह कन्फिगर गर्न सकिँदैन"</string>
     <string name="notification_delegate_header" msgid="2857691673814814270">"प्रोक्सीमार्फत आउने सूचना"</string>
@@ -908,8 +900,7 @@
     <string name="slice_permission_allow" msgid="2340244901366722709">"अनुमति दिनुहोस्"</string>
     <string name="slice_permission_deny" msgid="7683681514008048807">"अस्वीकार गर्नु…"</string>
     <string name="auto_saver_title" msgid="1217959994732964228">"ब्याट्री सेभरको समयतालिका बनाउन ट्याप गर्नुहोस्"</string>
-    <!-- no translation found for auto_saver_text (2563289953551438248) -->
-    <skip />
+    <string name="auto_saver_text" msgid="2563289953551438248">"ब्याट्री सकिने सम्भावना भएमा सक्रिय गर्नुहोस्"</string>
     <string name="no_auto_saver_action" msgid="8086002101711328500">"पर्दैन धन्यवाद"</string>
     <string name="auto_saver_enabled_title" msgid="6726474226058316862">"ब्याट्री सेभरको समयतालिका सक्रिय गरियो"</string>
     <string name="auto_saver_enabled_text" msgid="874711029884777579">"ब्याट्री <xliff:g id="PERCENTAGE">%d</xliff:g>%% भन्दा कम भएको बेला ब्याट्री सेभर स्वतः सक्रिय हुने छ।"</string>
@@ -942,4 +933,6 @@
     <string name="bubble_accessibility_action_move_bottom_left" msgid="206369104473183217">"पुछारमा बायाँतिर सार्नुहोस्"</string>
     <string name="bubble_accessibility_action_move_bottom_right" msgid="8705660152384312329">"पुछारमा दायाँतिर सार्नुहोस्"</string>
     <string name="bubble_dismiss_text" msgid="8028337712674081668">"हटाउनुहोस्"</string>
+    <string name="notification_content_system_nav_changed" msgid="7218093915747788444">"प्रणालीको नेभिगेसन अद्यावधिक गरियो। परिवर्तन गर्न सेटिङमा जानुहोस्।"</string>
+    <string name="notification_content_gesture_nav_available" msgid="8111130443656460792">"प्रणालीको नेभिगेसन अद्यावधिक गर्न सेटिङमा जानुहोस्"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-nl/strings.xml b/packages/SystemUI/res/values-nl/strings.xml
index 26e4845..8a9061a 100644
--- a/packages/SystemUI/res/values-nl/strings.xml
+++ b/packages/SystemUI/res/values-nl/strings.xml
@@ -62,12 +62,10 @@
     <string name="usb_debugging_secondary_user_title" msgid="6353808721761220421">"USB-foutopsporing niet toegestaan"</string>
     <string name="usb_debugging_secondary_user_message" msgid="6067122453571699801">"De gebruiker die momenteel is ingelogd op dit apparaat, kan USB-foutopsporing niet inschakelen. Als je deze functie wilt gebruiken, schakel je naar de primaire gebruiker."</string>
     <string name="usb_contaminant_title" msgid="206854874263058490">"USB-poort uitgeschakeld"</string>
-    <!-- no translation found for usb_contaminant_message (7379089091591609111) -->
-    <skip />
+    <string name="usb_contaminant_message" msgid="7379089091591609111">"De USB-poort is uitgeschakeld en detecteert geen accessoires, zodat je apparaat wordt beschermd tegen vloeistof en vuil.\n\nJe ontvangt een melding wanneer je de USB-poort weer kunt gebruiken."</string>
     <string name="usb_port_enabled" msgid="7906141351687694867">"USB-poort kan opladers en accessoires detecteren"</string>
     <string name="usb_disable_contaminant_detection" msgid="2103905315747120033">"USB inschakelen"</string>
-    <!-- no translation found for learn_more (5000517160980853569) -->
-    <skip />
+    <string name="learn_more" msgid="5000517160980853569">"Meer informatie"</string>
     <string name="compat_mode_on" msgid="6623839244840638213">"Zoom om scherm te vullen"</string>
     <string name="compat_mode_off" msgid="4434467572461327898">"Rek uit v. schermvulling"</string>
     <string name="global_action_screenshot" msgid="8329831278085426283">"Screenshot"</string>
@@ -199,6 +197,7 @@
     <string name="carrier_network_change_mode" msgid="8149202439957837762">"Netwerk van provider wordt gewijzigd"</string>
     <string name="accessibility_battery_details" msgid="7645516654955025422">"Accudetails openen"</string>
     <string name="accessibility_battery_level" msgid="7451474187113371965">"Batterij: <xliff:g id="NUMBER">%d</xliff:g> procent."</string>
+    <string name="accessibility_battery_level_with_estimate" msgid="9033100930684311630">"Batterij op <xliff:g id="PERCENTAGE">%1$s</xliff:g> procent, nog ongeveer <xliff:g id="TIME">%2$s</xliff:g> op basis van je gebruik"</string>
     <string name="accessibility_battery_level_charging" msgid="1147587904439319646">"Batterij wordt opgeladen, <xliff:g id="BATTERY_PERCENTAGE">%d</xliff:g>%% procent."</string>
     <string name="accessibility_settings_button" msgid="799583911231893380">"Systeeminstellingen."</string>
     <string name="accessibility_notifications_button" msgid="4498000369779421892">"Meldingen."</string>
@@ -458,10 +457,8 @@
     <string name="media_projection_remember_text" msgid="3103510882172746752">"Niet opnieuw weergeven"</string>
     <string name="clear_all_notifications_text" msgid="814192889771462828">"Alles wissen"</string>
     <string name="manage_notifications_text" msgid="2386728145475108753">"Beheren"</string>
-    <!-- no translation found for notification_section_header_gentle (4372438504154095677) -->
-    <skip />
-    <!-- no translation found for accessibility_notification_section_header_gentle_clear_all (4286716295850400959) -->
-    <skip />
+    <string name="notification_section_header_gentle" msgid="4372438504154095677">"Stille meldingen"</string>
+    <string name="accessibility_notification_section_header_gentle_clear_all" msgid="4286716295850400959">"Alle stille meldingen wissen"</string>
     <string name="dnd_suppressing_shade_text" msgid="1904574852846769301">"Meldingen onderbroken door \'Niet storen\'"</string>
     <string name="media_projection_action_text" msgid="8470872969457985954">"Nu starten"</string>
     <string name="empty_shade_text" msgid="708135716272867002">"Geen meldingen"</string>
@@ -645,21 +642,16 @@
     <string name="inline_block_button" msgid="8735843688021655065">"Blokkeren"</string>
     <string name="inline_keep_button" msgid="6665940297019018232">"Blijven weergeven"</string>
     <string name="inline_minimize_button" msgid="966233327974702195">"Minimaliseren"</string>
-    <!-- no translation found for inline_silent_button_silent (5315879183296940969) -->
-    <skip />
+    <string name="inline_silent_button_silent" msgid="5315879183296940969">"Stil"</string>
     <string name="inline_silent_button_stay_silent" msgid="6308371431217601009">"Stil blijven"</string>
-    <!-- no translation found for inline_silent_button_alert (6008435419895088034) -->
-    <skip />
+    <string name="inline_silent_button_alert" msgid="6008435419895088034">"Waarschuwen"</string>
     <string name="inline_silent_button_keep_alerting" msgid="327696842264359693">"Blijven waarschuwen"</string>
     <string name="inline_turn_off_notifications" msgid="8635596135532202355">"Meldingen uitschakelen"</string>
     <string name="inline_keep_showing_app" msgid="1723113469580031041">"Meldingen van deze app blijven weergeven?"</string>
-    <string name="notification_silence_title" msgid="7352089096356977930">"Vriendelijk"</string>
-    <string name="notification_alert_title" msgid="3966526305405016221">"Met prioriteit"</string>
-    <string name="notification_channel_summary_low" msgid="1065819618107531284">"Helpt je focussen doordat meldingen alleen in het pull-downvenster worden weergegeven. Altijd stil."</string>
-    <string name="notification_channel_summary_low_status" msgid="2702170424808743755">"Wordt weergegeven onder de prioriteitsmeldingen. Altijd stil."</string>
-    <string name="notification_channel_summary_low_lock" msgid="7966605244472624458">"Wordt weergegeven onder de prioriteitsmeldingen. Altijd stil."</string>
-    <string name="notification_channel_summary_low_status_lock" msgid="7012562768950012739">"Wordt weergegeven onder de prioriteitsmeldingen. Altijd stil."</string>
-    <string name="notification_channel_summary_default" msgid="3847289783382316019">"Trekt de aandacht met geluid en een pictogram in de statusbalk. Wordt weergegeven op het vergrendelingsscherm."</string>
+    <string name="notification_silence_title" msgid="5763240612242137433">"Stil"</string>
+    <string name="notification_alert_title" msgid="8031196611815490340">"Waarschuwen"</string>
+    <string name="notification_channel_summary_low" msgid="3387466082089715555">"Helpt je focussen zonder geluid of trilling."</string>
+    <string name="notification_channel_summary_default" msgid="5994062840431965586">"Trekt je aandacht met geluid of trillingen."</string>
     <string name="notification_unblockable_desc" msgid="4556908766584964102">"Deze meldingen kunnen niet worden aangepast."</string>
     <string name="notification_multichannel_desc" msgid="4695920306092240550">"Deze groep meldingen kan hier niet worden geconfigureerd"</string>
     <string name="notification_delegate_header" msgid="2857691673814814270">"Melding via proxy"</string>
@@ -908,8 +900,7 @@
     <string name="slice_permission_allow" msgid="2340244901366722709">"Toestaan"</string>
     <string name="slice_permission_deny" msgid="7683681514008048807">"Weigeren"</string>
     <string name="auto_saver_title" msgid="1217959994732964228">"Tikken om Batterijbesparing in te schakelen"</string>
-    <!-- no translation found for auto_saver_text (2563289953551438248) -->
-    <skip />
+    <string name="auto_saver_text" msgid="2563289953551438248">"Inschakelen wanneer de batterij waarschijnlijk leeg raakt"</string>
     <string name="no_auto_saver_action" msgid="8086002101711328500">"Nee"</string>
     <string name="auto_saver_enabled_title" msgid="6726474226058316862">"Batterijbesparing is ingeschakeld"</string>
     <string name="auto_saver_enabled_text" msgid="874711029884777579">"Batterijbesparing wordt automatisch ingeschakeld wanneer de batterijstatus lager is dan <xliff:g id="PERCENTAGE">%d</xliff:g>%%."</string>
@@ -942,4 +933,6 @@
     <string name="bubble_accessibility_action_move_bottom_left" msgid="206369104473183217">"Naar linksonder verplaatsen"</string>
     <string name="bubble_accessibility_action_move_bottom_right" msgid="8705660152384312329">"Naar rechtsonder verplaatsen"</string>
     <string name="bubble_dismiss_text" msgid="8028337712674081668">"Sluiten"</string>
+    <string name="notification_content_system_nav_changed" msgid="7218093915747788444">"Systeemnavigatie geüpdatet. Als je wijzigingen wilt aanbrengen, ga je naar Instellingen."</string>
+    <string name="notification_content_gesture_nav_available" msgid="8111130443656460792">"Ga naar Instellingen om de systeemnavigatie te updaten"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-or/strings.xml b/packages/SystemUI/res/values-or/strings.xml
index 1de3ea3..71eca74 100644
--- a/packages/SystemUI/res/values-or/strings.xml
+++ b/packages/SystemUI/res/values-or/strings.xml
@@ -62,12 +62,10 @@
     <string name="usb_debugging_secondary_user_title" msgid="6353808721761220421">"USBରେ ଡିବଗ୍‍ କରାଯାଇପାରିବ ନାହିଁ"</string>
     <string name="usb_debugging_secondary_user_message" msgid="6067122453571699801">"ସମ୍ପ୍ରତି ସାଇନ୍‍-ଇନ୍‍ କରିଥିବା ୟୁଜର୍‍ ଜଣକ ଏହି ଡିଭାଇସରେ USB ଡିବଗିଙ୍ଗ ଅନ୍‍ କରିପାରିବେ ନାହିଁ। ଏହି ବୈଶିଷ୍ଟ୍ୟ ବ୍ୟବହାର କରିବାକୁ, ପ୍ରାଥମିକ ୟୁଜର୍‍ରେ ସାଇନ୍‍-ଇନ୍‍ କରନ୍ତୁ।"</string>
     <string name="usb_contaminant_title" msgid="206854874263058490">"USB ପୋର୍ଟକୁ ଅକ୍ଷମ କରାଯାଇଛି"</string>
-    <!-- no translation found for usb_contaminant_message (7379089091591609111) -->
-    <skip />
+    <string name="usb_contaminant_message" msgid="7379089091591609111">"ଆପଣଙ୍କ ଡିଭାଇସ୍‌କୁ ତରଳ ପଦାର୍ଥ ଏବଂ ଧୂଳିରୁ ସୁରକ୍ଷିତ ରଖିବା ପାଇଁ, USB ପୋର୍ଟକୁ ଅକ୍ଷମ କରାଯାଇଛି ଏବଂ ଏହା କୌଣସି ଉପକରଣ ଚିହ୍ନଟ କରିବ ନାହିଁ। \n\n ଯେତେବେଳେ USB ପୋର୍ଟ ପୁଣିି ବ୍ୟବହାର କରିବାକୁ ସୁରକ୍ଷିତ ହେବ, ସେତେବେଳେ ଆପଣଙ୍କୁ ସୂଚିତ କରାଯିବ।"</string>
     <string name="usb_port_enabled" msgid="7906141351687694867">"ଚାର୍ଜର୍‍ ଏବଂ ଆକ୍ସେସରିଗୁଡ଼ିକୁ ଚିହ୍ନଟ କରିବାକୁ USB ପୋର୍ଟ ସକ୍ଷମ କରାଯାଇଛି"</string>
     <string name="usb_disable_contaminant_detection" msgid="2103905315747120033">"USB ସକ୍ଷମ କରନ୍ତୁ"</string>
-    <!-- no translation found for learn_more (5000517160980853569) -->
-    <skip />
+    <string name="learn_more" msgid="5000517160980853569">"ଅଧିକ ଜାଣନ୍ତୁ"</string>
     <string name="compat_mode_on" msgid="6623839244840638213">"ସ୍କ୍ରୀନ ଭରିବା ପାଇଁ ଜୁମ୍ କରନ୍ତୁ"</string>
     <string name="compat_mode_off" msgid="4434467572461327898">"ସ୍କ୍ରୀନ୍‌କୁ ଭରିବା ପାଇଁ ଟାଣନ୍ତୁ"</string>
     <string name="global_action_screenshot" msgid="8329831278085426283">"ସ୍କ୍ରୀନଶଟ୍‌"</string>
@@ -199,6 +197,7 @@
     <string name="carrier_network_change_mode" msgid="8149202439957837762">"କେରିଅର୍‍ ନେଟ୍‌ୱର୍କ ବଦଳୁଛି"</string>
     <string name="accessibility_battery_details" msgid="7645516654955025422">"ବ୍ୟାଟେରୀ ବିବରଣୀ ଖୋଲନ୍ତୁ"</string>
     <string name="accessibility_battery_level" msgid="7451474187113371965">"ବ୍ୟାଟେରୀ <xliff:g id="NUMBER">%d</xliff:g> ଶତକଡ଼ା ଅଛି।"</string>
+    <string name="accessibility_battery_level_with_estimate" msgid="9033100930684311630">"ବ୍ୟାଟେରୀ <xliff:g id="PERCENTAGE">%1$s</xliff:g> ଶତକଡା, ଆପଣଙ୍କର ବ୍ୟବହାରକୁ ଆଧାର କରି ପାଖାପାଖି <xliff:g id="TIME">%2$s</xliff:g> ବାକି ଅଛି"</string>
     <string name="accessibility_battery_level_charging" msgid="1147587904439319646">"ବ୍ୟାଟେରୀ ଚାର୍ଜ ହେଉଛି, <xliff:g id="BATTERY_PERCENTAGE">%d</xliff:g> ଶତକଡ଼ା।"</string>
     <string name="accessibility_settings_button" msgid="799583911231893380">"ସିଷ୍ଟମ୍‍ ସେଟିଙ୍ଗ।"</string>
     <string name="accessibility_notifications_button" msgid="4498000369779421892">"ବିଜ୍ଞପ୍ତି"</string>
@@ -458,10 +457,8 @@
     <string name="media_projection_remember_text" msgid="3103510882172746752">"ପୁଣି ଦେଖାନ୍ତୁ ନାହିଁ"</string>
     <string name="clear_all_notifications_text" msgid="814192889771462828">"ସମସ୍ତ ଖାଲି କରନ୍ତୁ"</string>
     <string name="manage_notifications_text" msgid="2386728145475108753">"ପରିଚାଳନା କରନ୍ତୁ"</string>
-    <!-- no translation found for notification_section_header_gentle (4372438504154095677) -->
-    <skip />
-    <!-- no translation found for accessibility_notification_section_header_gentle_clear_all (4286716295850400959) -->
-    <skip />
+    <string name="notification_section_header_gentle" msgid="4372438504154095677">"ନୀରବ ବିଜ୍ଞପ୍ତିଗୁଡ଼ିକ"</string>
+    <string name="accessibility_notification_section_header_gentle_clear_all" msgid="4286716295850400959">"ସମସ୍ତ ନୀରବ ବିଜ୍ଞପ୍ତିଗୁଡ଼ିକ ଖାଲି କରନ୍ତୁ"</string>
     <string name="dnd_suppressing_shade_text" msgid="1904574852846769301">"\"ବିରକ୍ତ କରନ୍ତୁ ନାହିଁ\" ବିକଳ୍ପ ଦ୍ୱାରା ବିଜ୍ଞପ୍ତି ପଜ୍‍ ହୋଇଛି"</string>
     <string name="media_projection_action_text" msgid="8470872969457985954">"ବର୍ତ୍ତମାନ ଆରମ୍ଭ କରନ୍ତୁ"</string>
     <string name="empty_shade_text" msgid="708135716272867002">"କୌଣସି ବିଜ୍ଞପ୍ତି ନାହିଁ"</string>
@@ -645,21 +642,16 @@
     <string name="inline_block_button" msgid="8735843688021655065">"ବ୍ଲକ୍ କରନ୍ତୁ"</string>
     <string name="inline_keep_button" msgid="6665940297019018232">"ଦେଖାଇବା ଜାରି ରଖନ୍ତୁ"</string>
     <string name="inline_minimize_button" msgid="966233327974702195">"ଛୋଟ କରନ୍ତୁ"</string>
-    <!-- no translation found for inline_silent_button_silent (5315879183296940969) -->
-    <skip />
+    <string name="inline_silent_button_silent" msgid="5315879183296940969">"ନୀରବ"</string>
     <string name="inline_silent_button_stay_silent" msgid="6308371431217601009">"ନୀରବ ରହନ୍ତୁ"</string>
-    <!-- no translation found for inline_silent_button_alert (6008435419895088034) -->
-    <skip />
+    <string name="inline_silent_button_alert" msgid="6008435419895088034">"ଆଲର୍ଟ କରିବା"</string>
     <string name="inline_silent_button_keep_alerting" msgid="327696842264359693">"ଆଲର୍ଟ କରିବା ଜାରି ରଖନ୍ତୁ"</string>
     <string name="inline_turn_off_notifications" msgid="8635596135532202355">"ବିଜ୍ଞପ୍ତି ବନ୍ଦ କରନ୍ତୁ"</string>
     <string name="inline_keep_showing_app" msgid="1723113469580031041">"ଏହି ଆପ୍‌ରୁ ବିଜ୍ଞପ୍ତିଗୁଡ଼ିକୁ ଦେଖାଇବା ଜାରି ରଖିବେ?"</string>
-    <string name="notification_silence_title" msgid="7352089096356977930">"ଧିରେ"</string>
-    <string name="notification_alert_title" msgid="3966526305405016221">"ପ୍ରାଥମିକତା ଭିତ୍ତିକ"</string>
-    <string name="notification_channel_summary_low" msgid="1065819618107531284">"କେବଳ ପୁଲ୍-ଡାଉନ୍ ସେଡ୍‌ରେ ବିଜ୍ଞପ୍ତିଗୁଡ଼ିକ ଉପରେ ଫୋକସ୍ ରହିବା ପାଇଁ ଆପଣଙ୍କୁ ସାହାଯ୍ୟ କରିଥାଏ। ସର୍ବଦା ନୀରବ।"</string>
-    <string name="notification_channel_summary_low_status" msgid="2702170424808743755">"ପ୍ରାଥମିକତା ବିଜ୍ଞପ୍ତିଗୁଡ଼ିକର ତଳେ ଡିସ୍‌ପ୍ଲେ ହୁଏ। ସର୍ବଦା ନିରବ।"</string>
-    <string name="notification_channel_summary_low_lock" msgid="7966605244472624458">"ପ୍ରାଥମିକତା ବିଜ୍ଞପ୍ତିଗୁଡ଼ିକର ତଳେ ଡିସ୍‌ପ୍ଲେ ହୁଏ। ସର୍ବଦା ନିରବ।"</string>
-    <string name="notification_channel_summary_low_status_lock" msgid="7012562768950012739">"ପ୍ରାଥମିକତା ବିଜ୍ଞପ୍ତିଗୁଡ଼ିକର ତଳେ ଡିସ୍‌ପ୍ଲେ ହୁଏ। ସର୍ବଦା ନିରବ।"</string>
-    <string name="notification_channel_summary_default" msgid="3847289783382316019">"ସାଉଣ୍ଡ୍ ଏବଂ ଏକ ଷ୍ଟାଟସ୍ ବାର୍ ଆଇକନ୍ ମାଧ୍ୟମରେ ଆପଣଙ୍କର ଧ୍ୟାନ ଆକର୍ଷିତ କରିଥାଏ। ଲକ୍ ସ୍କ୍ରିନ୍‌ରେ ଦେଖାଯାଇଥାଏ।"</string>
+    <string name="notification_silence_title" msgid="5763240612242137433">"ନୀରବ"</string>
+    <string name="notification_alert_title" msgid="8031196611815490340">"ଆଲର୍ଟ କରିବା"</string>
+    <string name="notification_channel_summary_low" msgid="3387466082089715555">"ବିନା ସାଉଣ୍ଡ କିମ୍ବା ଭାଇବ୍ରେସନ୍‌ରେ ଆପଣଙ୍କୁ ଫୋକସ୍ କରିବାରେ ସାହାଯ୍ୟ କରେ।"</string>
+    <string name="notification_channel_summary_default" msgid="5994062840431965586">"ସାଉଣ୍ଡ କିମ୍ବା ଭାଇବ୍ରେସନ୍ ମାଧ୍ୟମରେ ଆପଣଙ୍କର ଧ୍ୟାନ ଆକର୍ଷିତ କରିଥାଏ।"</string>
     <string name="notification_unblockable_desc" msgid="4556908766584964102">"ଏହି ବିଜ୍ଞପ୍ତିଗୁଡ଼ିକ ପରିବର୍ତ୍ତନ କରିହେବ ନାହିଁ।"</string>
     <string name="notification_multichannel_desc" msgid="4695920306092240550">"ଏଠାରେ ଏହି ବିଜ୍ଞପ୍ତିଗୁଡ଼ିକର ଗ୍ରୁପ୍ କନଫ୍ୟୁଗର୍ କରାଯାଇପାରିବ ନାହିଁ"</string>
     <string name="notification_delegate_header" msgid="2857691673814814270">"ବିଜ୍ଞପ୍ତି ପ୍ରକ୍ସୀ ହୋଇଛି"</string>
@@ -755,7 +747,7 @@
     <string name="accessibility_data_saver_on" msgid="8454111686783887148">"ଡାଟା ସେଭର୍‌ ଅନ୍‌ ଅଛି"</string>
     <string name="accessibility_data_saver_off" msgid="8841582529453005337">"ଡାଟା ସେଭର୍‍ ଅଫ୍ ଅଛି"</string>
     <string name="switch_bar_on" msgid="1142437840752794229">"ଅନ୍"</string>
-    <string name="switch_bar_off" msgid="8803270596930432874">"ଅଫ୍"</string>
+    <string name="switch_bar_off" msgid="8803270596930432874">"ବନ୍ଦ"</string>
     <string name="nav_bar" msgid="1993221402773877607">"ନାଭିଗେଶନ୍ ବାର୍‍"</string>
     <string name="nav_bar_layout" msgid="3664072994198772020">"ଲେଆଉଟ୍"</string>
     <string name="left_nav_bar_button_type" msgid="8555981238887546528">"ସମ୍ପୂର୍ଣ୍ଣ ବାମ ବଟନ୍‍ ପ୍ରକାର"</string>
@@ -908,8 +900,7 @@
     <string name="slice_permission_allow" msgid="2340244901366722709">"ଅନୁମତି ଦିଅନ୍ତୁ"</string>
     <string name="slice_permission_deny" msgid="7683681514008048807">"ଅସ୍ଵୀକାର କରନ୍ତୁ"</string>
     <string name="auto_saver_title" msgid="1217959994732964228">"ବ୍ୟାଟେରୀ ସେଭର୍‌ ଅନ୍‌ ହେବାର ସମୟ ସେଟ୍‌ କରିବାକୁ ଟାପ୍‌ କରନ୍ତୁ"</string>
-    <!-- no translation found for auto_saver_text (2563289953551438248) -->
-    <skip />
+    <string name="auto_saver_text" msgid="2563289953551438248">"ବ୍ୟାଟେରୀ ସରିବାକୁ ଥିବା ସମୟରେ ଚାଲୁ କରନ୍ତୁ"</string>
     <string name="no_auto_saver_action" msgid="8086002101711328500">"ନାହିଁ, ଥାଉ"</string>
     <string name="auto_saver_enabled_title" msgid="6726474226058316862">"ଆଗରୁ ସେଟ୍‌ କରିଥିବା ସମୟ ଅନୁସାରେ ବ୍ୟାଟେରୀ ସେଭର୍‌ ଅନ୍‌ ହୋଇଛି"</string>
     <string name="auto_saver_enabled_text" msgid="874711029884777579">"ଚାର୍ଜ <xliff:g id="PERCENTAGE">%d</xliff:g>%%ରୁ କମ୍‌ ହେଲେ ବ୍ୟାଟେରୀ ସେଭର୍‌ ଆପେ ଅନ୍‌ ହୋଇଯିବ।"</string>
@@ -942,4 +933,6 @@
     <string name="bubble_accessibility_action_move_bottom_left" msgid="206369104473183217">"ତଳ ବାମକୁ ନିଅନ୍ତୁ"</string>
     <string name="bubble_accessibility_action_move_bottom_right" msgid="8705660152384312329">"ତଳ ଡାହାଣକୁ ନିଅନ୍ତୁ"</string>
     <string name="bubble_dismiss_text" msgid="8028337712674081668">"ଖାରଜ କରନ୍ତୁ"</string>
+    <string name="notification_content_system_nav_changed" msgid="7218093915747788444">"ସିଷ୍ଟମ୍ ନାଭିଗେସନ୍ ଅପ୍‌ଡେଟ୍ ହୋଇଛି। ପରିବର୍ତ୍ତନ କରିବା ପାଇଁ, ସେଟିଂସ୍‌କୁ ଯାଆନ୍ତୁ।"</string>
+    <string name="notification_content_gesture_nav_available" msgid="8111130443656460792">"ସିଷ୍ଟମ୍ ନାଭିଗେସନ୍ ଅପ୍‌ଡେଟ୍ କରିବା ପାଇଁ ସେଟିଂସ୍‍କୁ ଯାଆନ୍ତୁ"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-pa/strings.xml b/packages/SystemUI/res/values-pa/strings.xml
index bb8bfb0..4be4ca3 100644
--- a/packages/SystemUI/res/values-pa/strings.xml
+++ b/packages/SystemUI/res/values-pa/strings.xml
@@ -62,12 +62,10 @@
     <string name="usb_debugging_secondary_user_title" msgid="6353808721761220421">"USB ਡਿਬੱਗਿੰਗ ਦੀ ਆਗਿਆ ਨਹੀਂ"</string>
     <string name="usb_debugging_secondary_user_message" msgid="6067122453571699801">"The user currently signed in to this device can\'t turn on USB debugging. To use this feature, switch to the primary user."</string>
     <string name="usb_contaminant_title" msgid="206854874263058490">"USB ਪੋਰਟ ਬੰਦ ਕੀਤਾ ਗਿਆ"</string>
-    <!-- no translation found for usb_contaminant_message (7379089091591609111) -->
-    <skip />
+    <string name="usb_contaminant_message" msgid="7379089091591609111">"ਤੁਹਾਡੇ ਡੀਵਾਈਸ ਨੂੰ ਪਾਣੀ ਅਤੇ ਧੂੜ-ਮਿੱਟੀ ਤੋਂ ਬਚਾਉਣ ਲਈ, USB ਪੋਰਟ ਨੂੰ ਬੰਦ ਕੀਤਾ ਗਿਆ ਹੈ ਅਤੇ ਕੋਈ ਵੀ ਐਕਸੈਸਰੀ ਪਛਾਣੀ ਨਹੀਂ ਜਾਵੇਗੀ।\n\nUSB ਪੋਰਟ ਨੂੰ ਦੁਬਾਰਾ ਵਰਤਣਾ ਠੀਕ ਹੋਣ \'ਤੇ ਤੁਹਾਨੂੰ ਸੂਚਿਤ ਕੀਤਾ ਜਾਵੇਗਾ।"</string>
     <string name="usb_port_enabled" msgid="7906141351687694867">"ਚਾਰਜਰਾਂ ਅਤੇ ਉਪਸਾਧਨਾਂ ਦੀ ਪਛਾਣ ਕਰਨ ਲਈ USB ਪੋਰਟ ਚਾਲੂ ਹੈ"</string>
     <string name="usb_disable_contaminant_detection" msgid="2103905315747120033">"USB ਚਾਲੂ ਕਰੋ"</string>
-    <!-- no translation found for learn_more (5000517160980853569) -->
-    <skip />
+    <string name="learn_more" msgid="5000517160980853569">"ਹੋਰ ਜਾਣੋ"</string>
     <string name="compat_mode_on" msgid="6623839244840638213">"ਸਕ੍ਰੀਨ ਭਰਨ ਲਈ ਜ਼ੂਮ ਕਰੋ"</string>
     <string name="compat_mode_off" msgid="4434467572461327898">"ਸਕ੍ਰੀਨ ਭਰਨ ਲਈ ਸਟ੍ਰੈਚ ਕਰੋ"</string>
     <string name="global_action_screenshot" msgid="8329831278085426283">"ਸਕ੍ਰੀਨਸ਼ਾਟ ਲਵੋ"</string>
@@ -199,6 +197,7 @@
     <string name="carrier_network_change_mode" msgid="8149202439957837762">"ਕੈਰੀਅਰ ਨੈੱਟਵਰਕ ਦੀ ਬਦਲੀ"</string>
     <string name="accessibility_battery_details" msgid="7645516654955025422">"ਬੈਟਰੀ ਵੇਰਵੇ ਖੋਲ੍ਹੋ"</string>
     <string name="accessibility_battery_level" msgid="7451474187113371965">"ਬੈਟਰੀ <xliff:g id="NUMBER">%d</xliff:g> ਪ੍ਰਤੀਸ਼ਤ ਹੈ।"</string>
+    <string name="accessibility_battery_level_with_estimate" msgid="9033100930684311630">"ਬੈਟਰੀ <xliff:g id="PERCENTAGE">%1$s</xliff:g> ਫ਼ੀਸਦ, ਤੁਹਾਡੀ ਵਰਤੋਂ ਦੇ ਆਧਾਰ \'ਤੇ ਲਗਭਗ <xliff:g id="TIME">%2$s</xliff:g> ਬਾਕੀ"</string>
     <string name="accessibility_battery_level_charging" msgid="1147587904439319646">"ਬੈਟਰੀ ਚਾਰਜ ਹੋ ਰਹੀ ਹੈ, <xliff:g id="BATTERY_PERCENTAGE">%d</xliff:g> ਪ੍ਰਤੀਸ਼ਤ।"</string>
     <string name="accessibility_settings_button" msgid="799583911231893380">"ਸਿਸਟਮ ਸੈਟਿੰਗਾਂ।"</string>
     <string name="accessibility_notifications_button" msgid="4498000369779421892">"ਸੂਚਨਾਵਾਂ।"</string>
@@ -458,10 +457,8 @@
     <string name="media_projection_remember_text" msgid="3103510882172746752">"ਦੁਬਾਰਾ ਨਾ ਦਿਖਾਓ"</string>
     <string name="clear_all_notifications_text" msgid="814192889771462828">"ਸਭ ਕਲੀਅਰ ਕਰੋ"</string>
     <string name="manage_notifications_text" msgid="2386728145475108753">"ਪ੍ਰਬੰਧਨ ਕਰੋ"</string>
-    <!-- no translation found for notification_section_header_gentle (4372438504154095677) -->
-    <skip />
-    <!-- no translation found for accessibility_notification_section_header_gentle_clear_all (4286716295850400959) -->
-    <skip />
+    <string name="notification_section_header_gentle" msgid="4372438504154095677">"ਖਾਮੋਸ਼ ਸੂਚਨਾਵਾਂ"</string>
+    <string name="accessibility_notification_section_header_gentle_clear_all" msgid="4286716295850400959">"ਸਾਰੀਆਂ ਖਾਮੋਸ਼ ਸੂਚਨਾਵਾਂ ਕਲੀਅਰ ਕਰੋ"</string>
     <string name="dnd_suppressing_shade_text" msgid="1904574852846769301">"\'ਪਰੇਸ਼ਾਨ ਨਾ ਕਰੋ\' ਵੱਲੋਂ ਸੂਚਨਾਵਾਂ ਨੂੰ ਰੋਕਿਆ ਗਿਆ"</string>
     <string name="media_projection_action_text" msgid="8470872969457985954">"ਹੁਣ ਚਾਲੂ ਕਰੋ"</string>
     <string name="empty_shade_text" msgid="708135716272867002">"ਕੋਈ ਸੂਚਨਾਵਾਂ ਨਹੀਂ"</string>
@@ -645,21 +642,16 @@
     <string name="inline_block_button" msgid="8735843688021655065">"ਬਲਾਕ ਕਰੋ"</string>
     <string name="inline_keep_button" msgid="6665940297019018232">"ਦਿਖਾਉਣਾ ਜਾਰੀ ਰੱਖੋ"</string>
     <string name="inline_minimize_button" msgid="966233327974702195">"ਛੋਟਾ ਕਰੋ"</string>
-    <!-- no translation found for inline_silent_button_silent (5315879183296940969) -->
-    <skip />
+    <string name="inline_silent_button_silent" msgid="5315879183296940969">"ਖਾਮੋਸ਼"</string>
     <string name="inline_silent_button_stay_silent" msgid="6308371431217601009">"ਚੁੱਪ ਰਹੋ"</string>
-    <!-- no translation found for inline_silent_button_alert (6008435419895088034) -->
-    <skip />
+    <string name="inline_silent_button_alert" msgid="6008435419895088034">"ਸੁਚੇਤਨਾ"</string>
     <string name="inline_silent_button_keep_alerting" msgid="327696842264359693">"ਸੁਚੇਤ ਰਖੋ"</string>
     <string name="inline_turn_off_notifications" msgid="8635596135532202355">"ਸੂਚਨਾਵਾਂ ਬੰਦ ਕਰੋ"</string>
     <string name="inline_keep_showing_app" msgid="1723113469580031041">"ਕੀ ਇਸ ਐਪ ਤੋਂ ਸੂਚਨਾਵਾਂ ਨੂੰ ਦਿਖਾਉਣਾ ਜਾਰੀ ਰੱਖਣਾ ਹੈ?"</string>
-    <string name="notification_silence_title" msgid="7352089096356977930">"ਸਰਲ"</string>
-    <string name="notification_alert_title" msgid="3966526305405016221">"ਤਰਜੀਹੀ"</string>
-    <string name="notification_channel_summary_low" msgid="1065819618107531284">"ਸਿਰਫ਼ ਹੇਠਾਂ ਖਿੱਚੀ ਜਾਣ ਵਾਲੀ ਸੂਚੀ ਵਿਚਲੀਆਂ ਸੂਚਨਾਵਾਂ ਨਾਲ ਧਿਆਨ ਦੇਣ ਵਿੱਚ ਤੁਹਾਡੀ ਮਦਦ ਕੀਤੀ ਜਾਂਦੀ ਹੈ। ਹਮੇਸ਼ਾਂ ਖਮੋਸ਼।"</string>
-    <string name="notification_channel_summary_low_status" msgid="2702170424808743755">"ਘੱਟ ਤਰਜੀਹ ਵਾਲੀਆਂ ਸੂਚਨਾਵਾਂ ਦਿਖਾਓ। ਹਮੇਸ਼ਾਂ ਖਮੋਸ਼।"</string>
-    <string name="notification_channel_summary_low_lock" msgid="7966605244472624458">"ਘੱਟ ਤਰਜੀਹ ਵਾਲੀਆਂ ਸੂਚਨਾਵਾਂ ਦਿਖਾਓ। ਹਮੇਸ਼ਾਂ ਖਮੋਸ਼।"</string>
-    <string name="notification_channel_summary_low_status_lock" msgid="7012562768950012739">"ਘੱਟ ਤਰਜੀਹ ਵਾਲੀਆਂ ਸੂਚਨਾਵਾਂ ਦਿਖਾਓ। ਹਮੇਸ਼ਾਂ ਖਮੋਸ਼।"</string>
-    <string name="notification_channel_summary_default" msgid="3847289783382316019">"ਧੁਨੀ ਅਤੇ ਸਥਿਤੀ ਪੱਟੀ ਪ੍ਰਤੀਕ ਨਾਲ ਤੁਹਾਡਾ ਧਿਆਨ ਖਿੱਚਦੀ ਹੈ। ਲਾਕ ਸਕ੍ਰੀਨ \'ਤੇ ਦਿਖਾਓ।"</string>
+    <string name="notification_silence_title" msgid="5763240612242137433">"ਖਮੋਸ਼"</string>
+    <string name="notification_alert_title" msgid="8031196611815490340">"ਸੁਚੇਤਨਾ"</string>
+    <string name="notification_channel_summary_low" msgid="3387466082089715555">"ਤੁਹਾਨੂੰ ਬਿਨਾਂ ਧੁਨੀ ਅਤੇ ਥਰਥਰਾਹਟ ਦੇ ਫੋਕਸ ਕਰਨ ਵਿੱਚ ਮਦਦ ਕਰਦਾ ਹੈ।"</string>
+    <string name="notification_channel_summary_default" msgid="5994062840431965586">"ਧੁਨੀ ਅਤੇ ਥਰਥਰਾਹਟ ਨਾਲ ਤੁਹਾਡਾ ਧਿਆਨ ਖਿੱਚਦੀ ਹੈ।"</string>
     <string name="notification_unblockable_desc" msgid="4556908766584964102">"ਇਹਨਾਂ ਸੂਚਨਾਵਾਂ ਨੂੰ ਸੋਧਿਆ ਨਹੀਂ ਜਾ ਸਕਦਾ।"</string>
     <string name="notification_multichannel_desc" msgid="4695920306092240550">"ਇਹ ਸੂਚਨਾਵਾਂ ਦਾ ਗਰੁੱਪ ਇੱਥੇ ਸੰਰੂਪਿਤ ਨਹੀਂ ਕੀਤਾ ਜਾ ਸਕਦਾ"</string>
     <string name="notification_delegate_header" msgid="2857691673814814270">"ਇੱਕ ਐਪ ਦੀ ਥਾਂ \'ਤੇ ਦੂਜੀ ਐਪ ਰਾਹੀਂ ਦਿੱਤੀ ਗਈ ਸੂਚਨਾ"</string>
@@ -908,8 +900,7 @@
     <string name="slice_permission_allow" msgid="2340244901366722709">"ਕਰਨ ਦਿਓ"</string>
     <string name="slice_permission_deny" msgid="7683681514008048807">"ਅਸਵੀਕਾਰ ਕਰੋ"</string>
     <string name="auto_saver_title" msgid="1217959994732964228">"ਬੈਟਰੀ ਸੇਵਰ ਦੀ ਸਮਾਂ-ਸੂਚੀ ਤਿਆਰ ਕਰਨ ਲਈ ਟੈਪ ਕਰੋ"</string>
-    <!-- no translation found for auto_saver_text (2563289953551438248) -->
-    <skip />
+    <string name="auto_saver_text" msgid="2563289953551438248">"ਬੈਟਰੀ ਖਤਮ ਹੋਣ ਦੀ ਸੰਭਾਵਨਾ \'ਤੇ ਚਾਲੂ ਹੁੰਦਾ ਹੈ"</string>
     <string name="no_auto_saver_action" msgid="8086002101711328500">"ਨਹੀਂ ਧੰਨਵਾਦ"</string>
     <string name="auto_saver_enabled_title" msgid="6726474226058316862">"ਬੈਟਰੀ ਸੇਵਰ ਸਮਾਂ-ਸੂਚੀ ਚਾਲੂ ਕੀਤੀ ਗਈ"</string>
     <string name="auto_saver_enabled_text" msgid="874711029884777579">"ਬੈਟਰੀ ਦਾ ਪੱਧਰ <xliff:g id="PERCENTAGE">%d</xliff:g>%% ਤੋਂ ਘੱਟ ਹੋ ਜਾਣ \'ਤੇ ਬੈਟਰੀ ਸੇਵਰ ਸਵੈਚਲਿਤ ਤੌਰ \'ਤੇ ਚਾਲੂ ਹੋ ਜਾਵੇਗਾ।"</string>
@@ -942,4 +933,6 @@
     <string name="bubble_accessibility_action_move_bottom_left" msgid="206369104473183217">"ਹੇਠਾਂ ਵੱਲ ਖੱਬੇ ਲਿਜਾਓ"</string>
     <string name="bubble_accessibility_action_move_bottom_right" msgid="8705660152384312329">"ਹੇਠਾਂ ਵੱਲ ਸੱਜੇ ਲਿਜਾਓ"</string>
     <string name="bubble_dismiss_text" msgid="8028337712674081668">"ਖਾਰਜ ਕਰੋ"</string>
+    <string name="notification_content_system_nav_changed" msgid="7218093915747788444">"ਸਿਸਟਮ ਨੈਵੀਗੇਸ਼ਨ ਅੱਪਡੇਟ ਹੋ ਗਿਆ। ਤਬਦੀਲੀਆਂ ਕਰਨ ਲਈ, ਸੈਟਿੰਗਾਂ \'ਤੇ ਜਾਓ।"</string>
+    <string name="notification_content_gesture_nav_available" msgid="8111130443656460792">"ਸਿਸਟਮ ਨੈਵੀਗੇਸ਼ਨ ਨੂੰ ਅੱਪਡੇਟ ਕਰਨ ਲਈ ਸੈਟਿੰਗਾਂ \'ਤੇ ਜਾਓ"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-pl/strings.xml b/packages/SystemUI/res/values-pl/strings.xml
index fdb4a3b..29c423a 100644
--- a/packages/SystemUI/res/values-pl/strings.xml
+++ b/packages/SystemUI/res/values-pl/strings.xml
@@ -62,12 +62,10 @@
     <string name="usb_debugging_secondary_user_title" msgid="6353808721761220421">"Debugowanie USB jest niedozwolone"</string>
     <string name="usb_debugging_secondary_user_message" msgid="6067122453571699801">"Użytkownik obecnie zalogowany na tym urządzeniu nie może włączyć debugowania USB. Aby użyć tej funkcji, przełącz się na użytkownika głównego."</string>
     <string name="usb_contaminant_title" msgid="206854874263058490">"Port USB wyłączony"</string>
-    <!-- no translation found for usb_contaminant_message (7379089091591609111) -->
-    <skip />
+    <string name="usb_contaminant_message" msgid="7379089091591609111">"Aby chronić urządzenie przed wilgocią i zanieczyszczeniami, port USB został wyłączony i nie wykryje żadnych akcesoriów.\n\nOtrzymasz powiadomienie, gdy będzie można znów używać portu."</string>
     <string name="usb_port_enabled" msgid="7906141351687694867">"Port USB włączony, by wykrywać ładowarki i akcesoria"</string>
     <string name="usb_disable_contaminant_detection" msgid="2103905315747120033">"Włącz USB"</string>
-    <!-- no translation found for learn_more (5000517160980853569) -->
-    <skip />
+    <string name="learn_more" msgid="5000517160980853569">"Więcej informacji"</string>
     <string name="compat_mode_on" msgid="6623839244840638213">"Powiększ, aby wypełnić ekran"</string>
     <string name="compat_mode_off" msgid="4434467572461327898">"Rozciągnij, aby wypełnić ekran"</string>
     <string name="global_action_screenshot" msgid="8329831278085426283">"Zrzut ekranu"</string>
@@ -201,6 +199,7 @@
     <string name="carrier_network_change_mode" msgid="8149202439957837762">"Zmiana sieci operatora"</string>
     <string name="accessibility_battery_details" msgid="7645516654955025422">"Zobacz szczegóły baterii"</string>
     <string name="accessibility_battery_level" msgid="7451474187113371965">"Bateria: <xliff:g id="NUMBER">%d</xliff:g> procent."</string>
+    <string name="accessibility_battery_level_with_estimate" msgid="9033100930684311630">"Bateria <xliff:g id="PERCENTAGE">%1$s</xliff:g> procent, jeszcze <xliff:g id="TIME">%2$s</xliff:g> (na podstawie Twojego sposobu korzystania)"</string>
     <string name="accessibility_battery_level_charging" msgid="1147587904439319646">"Ładuję baterię, <xliff:g id="BATTERY_PERCENTAGE">%d</xliff:g> procent."</string>
     <string name="accessibility_settings_button" msgid="799583911231893380">"Ustawienia systemu."</string>
     <string name="accessibility_notifications_button" msgid="4498000369779421892">"Powiadomienia."</string>
@@ -466,10 +465,8 @@
     <string name="media_projection_remember_text" msgid="3103510882172746752">"Nie pokazuj ponownie"</string>
     <string name="clear_all_notifications_text" msgid="814192889771462828">"Ukryj wszystkie"</string>
     <string name="manage_notifications_text" msgid="2386728145475108753">"Zarządzaj"</string>
-    <!-- no translation found for notification_section_header_gentle (4372438504154095677) -->
-    <skip />
-    <!-- no translation found for accessibility_notification_section_header_gentle_clear_all (4286716295850400959) -->
-    <skip />
+    <string name="notification_section_header_gentle" msgid="4372438504154095677">"Powiadomienia ciche"</string>
+    <string name="accessibility_notification_section_header_gentle_clear_all" msgid="4286716295850400959">"Wyczyść wszystkie ciche powiadomienia"</string>
     <string name="dnd_suppressing_shade_text" msgid="1904574852846769301">"Powiadomienia wstrzymane przez tryb Nie przeszkadzać"</string>
     <string name="media_projection_action_text" msgid="8470872969457985954">"Rozpocznij teraz"</string>
     <string name="empty_shade_text" msgid="708135716272867002">"Brak powiadomień"</string>
@@ -653,21 +650,16 @@
     <string name="inline_block_button" msgid="8735843688021655065">"Zablokuj"</string>
     <string name="inline_keep_button" msgid="6665940297019018232">"Pokazuj nadal"</string>
     <string name="inline_minimize_button" msgid="966233327974702195">"Minimalizuj"</string>
-    <!-- no translation found for inline_silent_button_silent (5315879183296940969) -->
-    <skip />
+    <string name="inline_silent_button_silent" msgid="5315879183296940969">"Bez dźwięku"</string>
     <string name="inline_silent_button_stay_silent" msgid="6308371431217601009">"Zachowaj wyciszenie"</string>
-    <!-- no translation found for inline_silent_button_alert (6008435419895088034) -->
-    <skip />
+    <string name="inline_silent_button_alert" msgid="6008435419895088034">"Alerty"</string>
     <string name="inline_silent_button_keep_alerting" msgid="327696842264359693">"Powiadamiaj dalej"</string>
     <string name="inline_turn_off_notifications" msgid="8635596135532202355">"Wyłącz powiadomienia"</string>
     <string name="inline_keep_showing_app" msgid="1723113469580031041">"Nadal pokazywać powiadomienia z tej aplikacji?"</string>
-    <string name="notification_silence_title" msgid="7352089096356977930">"Subtelne"</string>
-    <string name="notification_alert_title" msgid="3966526305405016221">"Priorytetowe"</string>
-    <string name="notification_channel_summary_low" msgid="1065819618107531284">"Pomaga Ci się skupić, wyświetlając powiadomienia tylko w obszarze powiadomień. Zawsze wyciszone."</string>
-    <string name="notification_channel_summary_low_status" msgid="2702170424808743755">"Wyświetla pod powiadomieniami priorytetowymi. Zawsze wyciszone."</string>
-    <string name="notification_channel_summary_low_lock" msgid="7966605244472624458">"Wyświetla pod powiadomieniami priorytetowymi. Zawsze wyciszone."</string>
-    <string name="notification_channel_summary_low_status_lock" msgid="7012562768950012739">"Wyświetla pod powiadomieniami priorytetowymi. Zawsze wyciszone."</string>
-    <string name="notification_channel_summary_default" msgid="3847289783382316019">"Zwraca Twoją uwagę dźwiękiem i ikoną na pasku stanu. Wyświetla na ekranie blokady."</string>
+    <string name="notification_silence_title" msgid="5763240612242137433">"Bez dźwięku"</string>
+    <string name="notification_alert_title" msgid="8031196611815490340">"Alert"</string>
+    <string name="notification_channel_summary_low" msgid="3387466082089715555">"Pomaga Ci się skupić, nie sygnalizując niczego dźwiękiem ani wibracjami."</string>
+    <string name="notification_channel_summary_default" msgid="5994062840431965586">"Przyciąga uwagę dźwiękiem lub wibracjami."</string>
     <string name="notification_unblockable_desc" msgid="4556908766584964102">"Tych powiadomień nie można zmodyfikować."</string>
     <string name="notification_multichannel_desc" msgid="4695920306092240550">"Tej grupy powiadomień nie można tu skonfigurować"</string>
     <string name="notification_delegate_header" msgid="2857691673814814270">"Powiadomienie w zastępstwie"</string>
@@ -920,8 +912,7 @@
     <string name="slice_permission_allow" msgid="2340244901366722709">"Zezwól"</string>
     <string name="slice_permission_deny" msgid="7683681514008048807">"Odmów"</string>
     <string name="auto_saver_title" msgid="1217959994732964228">"Kliknij, by zaplanować działanie oszczędzania baterii"</string>
-    <!-- no translation found for auto_saver_text (2563289953551438248) -->
-    <skip />
+    <string name="auto_saver_text" msgid="2563289953551438248">"Oszczędzanie baterii włącza się, jeśli bateria jest prawie wyczerpana"</string>
     <string name="no_auto_saver_action" msgid="8086002101711328500">"Nie"</string>
     <string name="auto_saver_enabled_title" msgid="6726474226058316862">"Harmonogram oszczędzania baterii jest aktywny"</string>
     <string name="auto_saver_enabled_text" msgid="874711029884777579">"Oszczędzanie baterii włączy się automatycznie, gdy poziom naładowania baterii spadnie poniżej <xliff:g id="PERCENTAGE">%d</xliff:g>%%."</string>
@@ -954,4 +945,6 @@
     <string name="bubble_accessibility_action_move_bottom_left" msgid="206369104473183217">"Przenieś w lewy dolny róg"</string>
     <string name="bubble_accessibility_action_move_bottom_right" msgid="8705660152384312329">"Przenieś w prawy dolny róg"</string>
     <string name="bubble_dismiss_text" msgid="8028337712674081668">"Zamknij"</string>
+    <string name="notification_content_system_nav_changed" msgid="7218093915747788444">"Nawigacja w systemie została zaktualizowana. Aby wprowadzić zmiany, otwórz Ustawienia."</string>
+    <string name="notification_content_gesture_nav_available" msgid="8111130443656460792">"Otwórz Ustawienia, by zaktualizować nawigację w systemie"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-pt-rBR/strings.xml b/packages/SystemUI/res/values-pt-rBR/strings.xml
index 6edbced..4d65512 100644
--- a/packages/SystemUI/res/values-pt-rBR/strings.xml
+++ b/packages/SystemUI/res/values-pt-rBR/strings.xml
@@ -62,12 +62,10 @@
     <string name="usb_debugging_secondary_user_title" msgid="6353808721761220421">"Depuração USB não permitida"</string>
     <string name="usb_debugging_secondary_user_message" msgid="6067122453571699801">"O usuário conectado a este dispositivo não pode ativar a depuração USB. Para usar esse recurso, mude para o usuário principal \"NAME\"."</string>
     <string name="usb_contaminant_title" msgid="206854874263058490">"Porta USB desativada"</string>
-    <!-- no translation found for usb_contaminant_message (7379089091591609111) -->
-    <skip />
+    <string name="usb_contaminant_message" msgid="7379089091591609111">"Para proteger seu dispositivo de líquidos e detritos, a porta USB está desativada e não detectará nenhum acessório.\n\nVocê receberá uma notificação quando for seguro usar a porta USB novamente."</string>
     <string name="usb_port_enabled" msgid="7906141351687694867">"Porta USB ativada para detectar carregadores e acessórios"</string>
     <string name="usb_disable_contaminant_detection" msgid="2103905315747120033">"Ativar USB"</string>
-    <!-- no translation found for learn_more (5000517160980853569) -->
-    <skip />
+    <string name="learn_more" msgid="5000517160980853569">"Saiba mais"</string>
     <string name="compat_mode_on" msgid="6623839244840638213">"Zoom p/ preencher a tela"</string>
     <string name="compat_mode_off" msgid="4434467572461327898">"Ampliar p/ preencher tela"</string>
     <string name="global_action_screenshot" msgid="8329831278085426283">"Captura de tela"</string>
@@ -199,6 +197,7 @@
     <string name="carrier_network_change_mode" msgid="8149202439957837762">"Alteração de rede da operadora"</string>
     <string name="accessibility_battery_details" msgid="7645516654955025422">"Abrir detalhes da bateria"</string>
     <string name="accessibility_battery_level" msgid="7451474187113371965">"Bateria em <xliff:g id="NUMBER">%d</xliff:g> por cento."</string>
+    <string name="accessibility_battery_level_with_estimate" msgid="9033100930684311630">"Bateria com <xliff:g id="PERCENTAGE">%1$s</xliff:g> de carga, tempo restante aproximado, com base no seu uso: <xliff:g id="TIME">%2$s</xliff:g>"</string>
     <string name="accessibility_battery_level_charging" msgid="1147587904439319646">"Bateria carregando: <xliff:g id="BATTERY_PERCENTAGE">%d</xliff:g>%%."</string>
     <string name="accessibility_settings_button" msgid="799583911231893380">"Configurações do sistema"</string>
     <string name="accessibility_notifications_button" msgid="4498000369779421892">"Notificações."</string>
@@ -458,10 +457,8 @@
     <string name="media_projection_remember_text" msgid="3103510882172746752">"Não mostrar novamente"</string>
     <string name="clear_all_notifications_text" msgid="814192889771462828">"Limpar tudo"</string>
     <string name="manage_notifications_text" msgid="2386728145475108753">"Gerenciar"</string>
-    <!-- no translation found for notification_section_header_gentle (4372438504154095677) -->
-    <skip />
-    <!-- no translation found for accessibility_notification_section_header_gentle_clear_all (4286716295850400959) -->
-    <skip />
+    <string name="notification_section_header_gentle" msgid="4372438504154095677">"Notificações silenciosas"</string>
+    <string name="accessibility_notification_section_header_gentle_clear_all" msgid="4286716295850400959">"Apagar todas as notificações silenciosas"</string>
     <string name="dnd_suppressing_shade_text" msgid="1904574852846769301">"Notificações pausadas pelo modo \"Não perturbe\""</string>
     <string name="media_projection_action_text" msgid="8470872969457985954">"Iniciar agora"</string>
     <string name="empty_shade_text" msgid="708135716272867002">"Sem notificações"</string>
@@ -645,21 +642,16 @@
     <string name="inline_block_button" msgid="8735843688021655065">"Bloquear"</string>
     <string name="inline_keep_button" msgid="6665940297019018232">"Continuar mostrando"</string>
     <string name="inline_minimize_button" msgid="966233327974702195">"Minimizar"</string>
-    <!-- no translation found for inline_silent_button_silent (5315879183296940969) -->
-    <skip />
+    <string name="inline_silent_button_silent" msgid="5315879183296940969">"Silencioso"</string>
     <string name="inline_silent_button_stay_silent" msgid="6308371431217601009">"Continuar sem som"</string>
-    <!-- no translation found for inline_silent_button_alert (6008435419895088034) -->
-    <skip />
+    <string name="inline_silent_button_alert" msgid="6008435419895088034">"Alertar"</string>
     <string name="inline_silent_button_keep_alerting" msgid="327696842264359693">"Continuar alertando"</string>
     <string name="inline_turn_off_notifications" msgid="8635596135532202355">"Desativar notificações"</string>
     <string name="inline_keep_showing_app" msgid="1723113469580031041">"Continuar mostrando notificações desse app?"</string>
-    <string name="notification_silence_title" msgid="7352089096356977930">"Discreta"</string>
-    <string name="notification_alert_title" msgid="3966526305405016221">"Priorizada"</string>
-    <string name="notification_channel_summary_low" msgid="1065819618107531284">"Ajuda você a se concentrar, já que as notificações são exibidas apenas na aba suspensa. Sempre silenciosa."</string>
-    <string name="notification_channel_summary_low_status" msgid="2702170424808743755">"Exibida abaixo das notificações prioritárias. Sempre silenciosa."</string>
-    <string name="notification_channel_summary_low_lock" msgid="7966605244472624458">"Exibida abaixo das notificações prioritárias. Sempre silenciosa."</string>
-    <string name="notification_channel_summary_low_status_lock" msgid="7012562768950012739">"Exibida abaixo das notificações prioritárias. Sempre silenciosa."</string>
-    <string name="notification_channel_summary_default" msgid="3847289783382316019">"Chama sua atenção com sons e um ícone na barra de status. Exibida na tela de bloqueio."</string>
+    <string name="notification_silence_title" msgid="5763240612242137433">"Silenciosa"</string>
+    <string name="notification_alert_title" msgid="8031196611815490340">"Alertar"</string>
+    <string name="notification_channel_summary_low" msgid="3387466082089715555">"Ajuda você a manter o foco sem som ou vibração."</string>
+    <string name="notification_channel_summary_default" msgid="5994062840431965586">"Chama sua atenção com som ou vibração."</string>
     <string name="notification_unblockable_desc" msgid="4556908766584964102">"Não é possível modificar essas notificações."</string>
     <string name="notification_multichannel_desc" msgid="4695920306092240550">"Não é possível configurar esse grupo de notificações aqui"</string>
     <string name="notification_delegate_header" msgid="2857691673814814270">"Notificação salva no proxy"</string>
@@ -908,8 +900,7 @@
     <string name="slice_permission_allow" msgid="2340244901366722709">"Permitir"</string>
     <string name="slice_permission_deny" msgid="7683681514008048807">"Negar"</string>
     <string name="auto_saver_title" msgid="1217959994732964228">"Toque para programar o recurso Economia de bateria"</string>
-    <!-- no translation found for auto_saver_text (2563289953551438248) -->
-    <skip />
+    <string name="auto_saver_text" msgid="2563289953551438248">"Ativada quando há possibilidade de a bateria acabar"</string>
     <string name="no_auto_saver_action" msgid="8086002101711328500">"Não"</string>
     <string name="auto_saver_enabled_title" msgid="6726474226058316862">"Programação do recurso Economia de bateria ativada"</string>
     <string name="auto_saver_enabled_text" msgid="874711029884777579">"O recurso Economia de bateria será ativado automaticamente depois que a bateria ficar abaixo de <xliff:g id="PERCENTAGE">%d</xliff:g>%%."</string>
@@ -942,4 +933,6 @@
     <string name="bubble_accessibility_action_move_bottom_left" msgid="206369104473183217">"Mover para canto inferior esquerdo"</string>
     <string name="bubble_accessibility_action_move_bottom_right" msgid="8705660152384312329">"Mover para canto inferior direito"</string>
     <string name="bubble_dismiss_text" msgid="8028337712674081668">"Dispensar"</string>
+    <string name="notification_content_system_nav_changed" msgid="7218093915747788444">"Navegação no sistema atualizada. Se quiser alterá-la, acesse as configurações."</string>
+    <string name="notification_content_gesture_nav_available" msgid="8111130443656460792">"Acesse as configurações para atualizar a navegação no sistema"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-pt-rPT/strings.xml b/packages/SystemUI/res/values-pt-rPT/strings.xml
index e373b3b..4a08f2e 100644
--- a/packages/SystemUI/res/values-pt-rPT/strings.xml
+++ b/packages/SystemUI/res/values-pt-rPT/strings.xml
@@ -62,12 +62,10 @@
     <string name="usb_debugging_secondary_user_title" msgid="6353808721761220421">"Depuração USB não permitida"</string>
     <string name="usb_debugging_secondary_user_message" msgid="6067122453571699801">"O utilizador com sessão iniciada atualmente neste dispositivo não pode ativar a depuração USB. Para utilizar esta funcionalidade, mude para o utilizador principal."</string>
     <string name="usb_contaminant_title" msgid="206854874263058490">"Porta USB desativada"</string>
-    <!-- no translation found for usb_contaminant_message (7379089091591609111) -->
-    <skip />
+    <string name="usb_contaminant_message" msgid="7379089091591609111">"Para proteger o dispositivo contra líquidos ou resíduos, a porta USB está desativada e não irá detetar quaisquer acessórios.\n\nSerá notificado quando for seguro utilizar a porta USB novamente."</string>
     <string name="usb_port_enabled" msgid="7906141351687694867">"Porta USB ativada para detetar carregadores e acessórios"</string>
     <string name="usb_disable_contaminant_detection" msgid="2103905315747120033">"Ativar USB"</string>
-    <!-- no translation found for learn_more (5000517160980853569) -->
-    <skip />
+    <string name="learn_more" msgid="5000517160980853569">"Saiba mais"</string>
     <string name="compat_mode_on" msgid="6623839244840638213">"Zoom para preencher o ecrã"</string>
     <string name="compat_mode_off" msgid="4434467572461327898">"Esticar p. caber em ec. int."</string>
     <string name="global_action_screenshot" msgid="8329831278085426283">"Captura de ecrã"</string>
@@ -199,6 +197,7 @@
     <string name="carrier_network_change_mode" msgid="8149202439957837762">"Rede do operador em mudança."</string>
     <string name="accessibility_battery_details" msgid="7645516654955025422">"Abrir detalhes da bateria"</string>
     <string name="accessibility_battery_level" msgid="7451474187113371965">"Bateria a <xliff:g id="NUMBER">%d</xliff:g> por cento."</string>
+    <string name="accessibility_battery_level_with_estimate" msgid="9033100930684311630">"Bateria a <xliff:g id="PERCENTAGE">%1$s</xliff:g> por cento, resta(m) cerca de <xliff:g id="TIME">%2$s</xliff:g> com base na sua utilização."</string>
     <string name="accessibility_battery_level_charging" msgid="1147587904439319646">"A bateria está a carregar, <xliff:g id="BATTERY_PERCENTAGE">%d</xliff:g> por cento."</string>
     <string name="accessibility_settings_button" msgid="799583911231893380">"Definições do sistema"</string>
     <string name="accessibility_notifications_button" msgid="4498000369779421892">"Notificações."</string>
@@ -458,10 +457,8 @@
     <string name="media_projection_remember_text" msgid="3103510882172746752">"Não mostrar de novo"</string>
     <string name="clear_all_notifications_text" msgid="814192889771462828">"Limpar tudo"</string>
     <string name="manage_notifications_text" msgid="2386728145475108753">"Gerir"</string>
-    <!-- no translation found for notification_section_header_gentle (4372438504154095677) -->
-    <skip />
-    <!-- no translation found for accessibility_notification_section_header_gentle_clear_all (4286716295850400959) -->
-    <skip />
+    <string name="notification_section_header_gentle" msgid="4372438504154095677">"Notificações silenciosas"</string>
+    <string name="accessibility_notification_section_header_gentle_clear_all" msgid="4286716295850400959">"Limpar todas as notificações silenciosas"</string>
     <string name="dnd_suppressing_shade_text" msgid="1904574852846769301">"Notificações colocadas em pausa pelo modo Não incomodar."</string>
     <string name="media_projection_action_text" msgid="8470872969457985954">"Começar agora"</string>
     <string name="empty_shade_text" msgid="708135716272867002">"Sem notificações"</string>
@@ -645,21 +642,16 @@
     <string name="inline_block_button" msgid="8735843688021655065">"Bloquear"</string>
     <string name="inline_keep_button" msgid="6665940297019018232">"Continuar a mostrar"</string>
     <string name="inline_minimize_button" msgid="966233327974702195">"Minimizar"</string>
-    <!-- no translation found for inline_silent_button_silent (5315879183296940969) -->
-    <skip />
+    <string name="inline_silent_button_silent" msgid="5315879183296940969">"Silencioso"</string>
     <string name="inline_silent_button_stay_silent" msgid="6308371431217601009">"Continuar sem som"</string>
-    <!-- no translation found for inline_silent_button_alert (6008435419895088034) -->
-    <skip />
+    <string name="inline_silent_button_alert" msgid="6008435419895088034">"Alertar"</string>
     <string name="inline_silent_button_keep_alerting" msgid="327696842264359693">"Continuar a alertar"</string>
     <string name="inline_turn_off_notifications" msgid="8635596135532202355">"Desativar notificações"</string>
     <string name="inline_keep_showing_app" msgid="1723113469580031041">"Pretende continuar a ver notificações desta aplicação?"</string>
-    <string name="notification_silence_title" msgid="7352089096356977930">"Discretas"</string>
-    <string name="notification_alert_title" msgid="3966526305405016221">"Prioritárias"</string>
-    <string name="notification_channel_summary_low" msgid="1065819618107531284">"Ajuda-o a concentrar-se com notificações apenas no painel pendente. Sempre silenciosa."</string>
-    <string name="notification_channel_summary_low_status" msgid="2702170424808743755">"É apresentada abaixo das notificações prioritárias. Sempre silenciosa."</string>
-    <string name="notification_channel_summary_low_lock" msgid="7966605244472624458">"É apresentada abaixo das notificações prioritárias. Sempre silenciosa."</string>
-    <string name="notification_channel_summary_low_status_lock" msgid="7012562768950012739">"Apresentadas abaixo das notificações prioritárias. Sempre silenciosas."</string>
-    <string name="notification_channel_summary_default" msgid="3847289783382316019">"Chamam à atenção com som e ícones na barra de estado. Apresentadas no ecrã de bloqueio."</string>
+    <string name="notification_silence_title" msgid="5763240612242137433">"Silencioso"</string>
+    <string name="notification_alert_title" msgid="8031196611815490340">"Alertar"</string>
+    <string name="notification_channel_summary_low" msgid="3387466082089715555">"Ajuda-o a focar-se sem som ou vibração."</string>
+    <string name="notification_channel_summary_default" msgid="5994062840431965586">"Chama a sua atenção com som ou vibração."</string>
     <string name="notification_unblockable_desc" msgid="4556908766584964102">"Não é possível modificar estas notificações."</string>
     <string name="notification_multichannel_desc" msgid="4695920306092240550">"Não é possível configurar este grupo de notificações aqui."</string>
     <string name="notification_delegate_header" msgid="2857691673814814270">"Notificação de aplicação proxy"</string>
@@ -908,8 +900,7 @@
     <string name="slice_permission_allow" msgid="2340244901366722709">"Permitir"</string>
     <string name="slice_permission_deny" msgid="7683681514008048807">"Recusar"</string>
     <string name="auto_saver_title" msgid="1217959994732964228">"Tocar para agendar a Poupança de bateria"</string>
-    <!-- no translation found for auto_saver_text (2563289953551438248) -->
-    <skip />
+    <string name="auto_saver_text" msgid="2563289953551438248">"Ativar quando for provável que a bateria se esgote"</string>
     <string name="no_auto_saver_action" msgid="8086002101711328500">"Não, obrigado"</string>
     <string name="auto_saver_enabled_title" msgid="6726474226058316862">"Poupança de bateria agendada ativada"</string>
     <string name="auto_saver_enabled_text" msgid="874711029884777579">"A Poupança de bateria é ativada automaticamente quando o nível de bateria está abaixo de <xliff:g id="PERCENTAGE">%d</xliff:g>%%."</string>
@@ -942,4 +933,6 @@
     <string name="bubble_accessibility_action_move_bottom_left" msgid="206369104473183217">"Mover p/ parte infer. esquerda"</string>
     <string name="bubble_accessibility_action_move_bottom_right" msgid="8705660152384312329">"Mover parte inferior direita"</string>
     <string name="bubble_dismiss_text" msgid="8028337712674081668">"Ignorar"</string>
+    <string name="notification_content_system_nav_changed" msgid="7218093915747788444">"A navegação no sistema foi atualizada. Para efetuar alterações, aceda às Definições."</string>
+    <string name="notification_content_gesture_nav_available" msgid="8111130443656460792">"Aceda às Definições para atualizar a navegação no sistema."</string>
 </resources>
diff --git a/packages/SystemUI/res/values-pt/strings.xml b/packages/SystemUI/res/values-pt/strings.xml
index 6edbced..4d65512 100644
--- a/packages/SystemUI/res/values-pt/strings.xml
+++ b/packages/SystemUI/res/values-pt/strings.xml
@@ -62,12 +62,10 @@
     <string name="usb_debugging_secondary_user_title" msgid="6353808721761220421">"Depuração USB não permitida"</string>
     <string name="usb_debugging_secondary_user_message" msgid="6067122453571699801">"O usuário conectado a este dispositivo não pode ativar a depuração USB. Para usar esse recurso, mude para o usuário principal \"NAME\"."</string>
     <string name="usb_contaminant_title" msgid="206854874263058490">"Porta USB desativada"</string>
-    <!-- no translation found for usb_contaminant_message (7379089091591609111) -->
-    <skip />
+    <string name="usb_contaminant_message" msgid="7379089091591609111">"Para proteger seu dispositivo de líquidos e detritos, a porta USB está desativada e não detectará nenhum acessório.\n\nVocê receberá uma notificação quando for seguro usar a porta USB novamente."</string>
     <string name="usb_port_enabled" msgid="7906141351687694867">"Porta USB ativada para detectar carregadores e acessórios"</string>
     <string name="usb_disable_contaminant_detection" msgid="2103905315747120033">"Ativar USB"</string>
-    <!-- no translation found for learn_more (5000517160980853569) -->
-    <skip />
+    <string name="learn_more" msgid="5000517160980853569">"Saiba mais"</string>
     <string name="compat_mode_on" msgid="6623839244840638213">"Zoom p/ preencher a tela"</string>
     <string name="compat_mode_off" msgid="4434467572461327898">"Ampliar p/ preencher tela"</string>
     <string name="global_action_screenshot" msgid="8329831278085426283">"Captura de tela"</string>
@@ -199,6 +197,7 @@
     <string name="carrier_network_change_mode" msgid="8149202439957837762">"Alteração de rede da operadora"</string>
     <string name="accessibility_battery_details" msgid="7645516654955025422">"Abrir detalhes da bateria"</string>
     <string name="accessibility_battery_level" msgid="7451474187113371965">"Bateria em <xliff:g id="NUMBER">%d</xliff:g> por cento."</string>
+    <string name="accessibility_battery_level_with_estimate" msgid="9033100930684311630">"Bateria com <xliff:g id="PERCENTAGE">%1$s</xliff:g> de carga, tempo restante aproximado, com base no seu uso: <xliff:g id="TIME">%2$s</xliff:g>"</string>
     <string name="accessibility_battery_level_charging" msgid="1147587904439319646">"Bateria carregando: <xliff:g id="BATTERY_PERCENTAGE">%d</xliff:g>%%."</string>
     <string name="accessibility_settings_button" msgid="799583911231893380">"Configurações do sistema"</string>
     <string name="accessibility_notifications_button" msgid="4498000369779421892">"Notificações."</string>
@@ -458,10 +457,8 @@
     <string name="media_projection_remember_text" msgid="3103510882172746752">"Não mostrar novamente"</string>
     <string name="clear_all_notifications_text" msgid="814192889771462828">"Limpar tudo"</string>
     <string name="manage_notifications_text" msgid="2386728145475108753">"Gerenciar"</string>
-    <!-- no translation found for notification_section_header_gentle (4372438504154095677) -->
-    <skip />
-    <!-- no translation found for accessibility_notification_section_header_gentle_clear_all (4286716295850400959) -->
-    <skip />
+    <string name="notification_section_header_gentle" msgid="4372438504154095677">"Notificações silenciosas"</string>
+    <string name="accessibility_notification_section_header_gentle_clear_all" msgid="4286716295850400959">"Apagar todas as notificações silenciosas"</string>
     <string name="dnd_suppressing_shade_text" msgid="1904574852846769301">"Notificações pausadas pelo modo \"Não perturbe\""</string>
     <string name="media_projection_action_text" msgid="8470872969457985954">"Iniciar agora"</string>
     <string name="empty_shade_text" msgid="708135716272867002">"Sem notificações"</string>
@@ -645,21 +642,16 @@
     <string name="inline_block_button" msgid="8735843688021655065">"Bloquear"</string>
     <string name="inline_keep_button" msgid="6665940297019018232">"Continuar mostrando"</string>
     <string name="inline_minimize_button" msgid="966233327974702195">"Minimizar"</string>
-    <!-- no translation found for inline_silent_button_silent (5315879183296940969) -->
-    <skip />
+    <string name="inline_silent_button_silent" msgid="5315879183296940969">"Silencioso"</string>
     <string name="inline_silent_button_stay_silent" msgid="6308371431217601009">"Continuar sem som"</string>
-    <!-- no translation found for inline_silent_button_alert (6008435419895088034) -->
-    <skip />
+    <string name="inline_silent_button_alert" msgid="6008435419895088034">"Alertar"</string>
     <string name="inline_silent_button_keep_alerting" msgid="327696842264359693">"Continuar alertando"</string>
     <string name="inline_turn_off_notifications" msgid="8635596135532202355">"Desativar notificações"</string>
     <string name="inline_keep_showing_app" msgid="1723113469580031041">"Continuar mostrando notificações desse app?"</string>
-    <string name="notification_silence_title" msgid="7352089096356977930">"Discreta"</string>
-    <string name="notification_alert_title" msgid="3966526305405016221">"Priorizada"</string>
-    <string name="notification_channel_summary_low" msgid="1065819618107531284">"Ajuda você a se concentrar, já que as notificações são exibidas apenas na aba suspensa. Sempre silenciosa."</string>
-    <string name="notification_channel_summary_low_status" msgid="2702170424808743755">"Exibida abaixo das notificações prioritárias. Sempre silenciosa."</string>
-    <string name="notification_channel_summary_low_lock" msgid="7966605244472624458">"Exibida abaixo das notificações prioritárias. Sempre silenciosa."</string>
-    <string name="notification_channel_summary_low_status_lock" msgid="7012562768950012739">"Exibida abaixo das notificações prioritárias. Sempre silenciosa."</string>
-    <string name="notification_channel_summary_default" msgid="3847289783382316019">"Chama sua atenção com sons e um ícone na barra de status. Exibida na tela de bloqueio."</string>
+    <string name="notification_silence_title" msgid="5763240612242137433">"Silenciosa"</string>
+    <string name="notification_alert_title" msgid="8031196611815490340">"Alertar"</string>
+    <string name="notification_channel_summary_low" msgid="3387466082089715555">"Ajuda você a manter o foco sem som ou vibração."</string>
+    <string name="notification_channel_summary_default" msgid="5994062840431965586">"Chama sua atenção com som ou vibração."</string>
     <string name="notification_unblockable_desc" msgid="4556908766584964102">"Não é possível modificar essas notificações."</string>
     <string name="notification_multichannel_desc" msgid="4695920306092240550">"Não é possível configurar esse grupo de notificações aqui"</string>
     <string name="notification_delegate_header" msgid="2857691673814814270">"Notificação salva no proxy"</string>
@@ -908,8 +900,7 @@
     <string name="slice_permission_allow" msgid="2340244901366722709">"Permitir"</string>
     <string name="slice_permission_deny" msgid="7683681514008048807">"Negar"</string>
     <string name="auto_saver_title" msgid="1217959994732964228">"Toque para programar o recurso Economia de bateria"</string>
-    <!-- no translation found for auto_saver_text (2563289953551438248) -->
-    <skip />
+    <string name="auto_saver_text" msgid="2563289953551438248">"Ativada quando há possibilidade de a bateria acabar"</string>
     <string name="no_auto_saver_action" msgid="8086002101711328500">"Não"</string>
     <string name="auto_saver_enabled_title" msgid="6726474226058316862">"Programação do recurso Economia de bateria ativada"</string>
     <string name="auto_saver_enabled_text" msgid="874711029884777579">"O recurso Economia de bateria será ativado automaticamente depois que a bateria ficar abaixo de <xliff:g id="PERCENTAGE">%d</xliff:g>%%."</string>
@@ -942,4 +933,6 @@
     <string name="bubble_accessibility_action_move_bottom_left" msgid="206369104473183217">"Mover para canto inferior esquerdo"</string>
     <string name="bubble_accessibility_action_move_bottom_right" msgid="8705660152384312329">"Mover para canto inferior direito"</string>
     <string name="bubble_dismiss_text" msgid="8028337712674081668">"Dispensar"</string>
+    <string name="notification_content_system_nav_changed" msgid="7218093915747788444">"Navegação no sistema atualizada. Se quiser alterá-la, acesse as configurações."</string>
+    <string name="notification_content_gesture_nav_available" msgid="8111130443656460792">"Acesse as configurações para atualizar a navegação no sistema"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-ro/strings.xml b/packages/SystemUI/res/values-ro/strings.xml
index db853a0..5fa5233 100644
--- a/packages/SystemUI/res/values-ro/strings.xml
+++ b/packages/SystemUI/res/values-ro/strings.xml
@@ -62,12 +62,10 @@
     <string name="usb_debugging_secondary_user_title" msgid="6353808721761220421">"Remedierea erorilor prin USB nu este permisă"</string>
     <string name="usb_debugging_secondary_user_message" msgid="6067122453571699801">"Utilizatorul conectat momentan pe acest dispozitiv nu poate activa remedierea erorilor prin USB. Pentru a folosi această funcție, comutați la utilizatorul principal."</string>
     <string name="usb_contaminant_title" msgid="206854874263058490">"Portul USB a fost dezactivat"</string>
-    <!-- no translation found for usb_contaminant_message (7379089091591609111) -->
-    <skip />
+    <string name="usb_contaminant_message" msgid="7379089091591609111">"Pentru a vă proteja dispozitivul de lichide sau reziduuri, portul USB este dezactivat și nu va detecta niciun accesoriu.\n\nVeți primi o notificare când puteți folosi din nou portul USB."</string>
     <string name="usb_port_enabled" msgid="7906141351687694867">"Portul USB a fost activat pentru a detecta încărcătoarele și accesoriile"</string>
     <string name="usb_disable_contaminant_detection" msgid="2103905315747120033">"Activați USB"</string>
-    <!-- no translation found for learn_more (5000517160980853569) -->
-    <skip />
+    <string name="learn_more" msgid="5000517160980853569">"Mai multe"</string>
     <string name="compat_mode_on" msgid="6623839244840638213">"Zoom pt. a umple ecranul"</string>
     <string name="compat_mode_off" msgid="4434467572461327898">"Înt. pt. a umple ecranul"</string>
     <string name="global_action_screenshot" msgid="8329831278085426283">"Instantaneu"</string>
@@ -199,6 +197,7 @@
     <string name="carrier_network_change_mode" msgid="8149202439957837762">"Se schimbă rețeaua operatorului"</string>
     <string name="accessibility_battery_details" msgid="7645516654955025422">"Deschideți detaliile privind bateria"</string>
     <string name="accessibility_battery_level" msgid="7451474187113371965">"Baterie: <xliff:g id="NUMBER">%d</xliff:g> la sută."</string>
+    <string name="accessibility_battery_level_with_estimate" msgid="9033100930684311630">"Procentul rămas din baterie este <xliff:g id="PERCENTAGE">%1$s</xliff:g>. În baza utilizării, timpul rămas este de aproximativ <xliff:g id="TIME">%2$s</xliff:g>"</string>
     <string name="accessibility_battery_level_charging" msgid="1147587904439319646">"Se încarcă bateria, <xliff:g id="BATTERY_PERCENTAGE">%d</xliff:g>%%."</string>
     <string name="accessibility_settings_button" msgid="799583911231893380">"Setări de sistem."</string>
     <string name="accessibility_notifications_button" msgid="4498000369779421892">"Notificări."</string>
@@ -461,10 +460,8 @@
     <string name="media_projection_remember_text" msgid="3103510882172746752">"Nu se mai afișează"</string>
     <string name="clear_all_notifications_text" msgid="814192889771462828">"Ștergeți toate notificările"</string>
     <string name="manage_notifications_text" msgid="2386728145475108753">"Gestionați"</string>
-    <!-- no translation found for notification_section_header_gentle (4372438504154095677) -->
-    <skip />
-    <!-- no translation found for accessibility_notification_section_header_gentle_clear_all (4286716295850400959) -->
-    <skip />
+    <string name="notification_section_header_gentle" msgid="4372438504154095677">"Notificări silențioase"</string>
+    <string name="accessibility_notification_section_header_gentle_clear_all" msgid="4286716295850400959">"Ștergeți toate notificările silențioase"</string>
     <string name="dnd_suppressing_shade_text" msgid="1904574852846769301">"Notificări întrerupte prin „Nu deranja”"</string>
     <string name="media_projection_action_text" msgid="8470872969457985954">"Începeți acum"</string>
     <string name="empty_shade_text" msgid="708135716272867002">"Nicio notificare"</string>
@@ -648,21 +645,16 @@
     <string name="inline_block_button" msgid="8735843688021655065">"Blocați"</string>
     <string name="inline_keep_button" msgid="6665940297019018232">"Continuați afișarea"</string>
     <string name="inline_minimize_button" msgid="966233327974702195">"Minimizați"</string>
-    <!-- no translation found for inline_silent_button_silent (5315879183296940969) -->
-    <skip />
+    <string name="inline_silent_button_silent" msgid="5315879183296940969">"Silențios"</string>
     <string name="inline_silent_button_stay_silent" msgid="6308371431217601009">"Păstrați modul silențios"</string>
-    <!-- no translation found for inline_silent_button_alert (6008435419895088034) -->
-    <skip />
+    <string name="inline_silent_button_alert" msgid="6008435419895088034">"Alertare"</string>
     <string name="inline_silent_button_keep_alerting" msgid="327696842264359693">"Păstrați alerta"</string>
     <string name="inline_turn_off_notifications" msgid="8635596135532202355">"Dezactivați notificările"</string>
     <string name="inline_keep_showing_app" msgid="1723113469580031041">"Doriți să continuați afișarea notificărilor de la această aplicație?"</string>
-    <string name="notification_silence_title" msgid="7352089096356977930">"Discret"</string>
-    <string name="notification_alert_title" msgid="3966526305405016221">"Cu prioritate"</string>
-    <string name="notification_channel_summary_low" msgid="1065819618107531284">"Vă ajută să vă concentrați cu notificări doar în fereastra trasă în jos. Întotdeauna silențios."</string>
-    <string name="notification_channel_summary_low_status" msgid="2702170424808743755">"Se afișează sub notificările prioritare. Întotdeauna silențios."</string>
-    <string name="notification_channel_summary_low_lock" msgid="7966605244472624458">"Se afișează sub notificările prioritare. Întotdeauna silențios."</string>
-    <string name="notification_channel_summary_low_status_lock" msgid="7012562768950012739">"Se afișează sub notificările prioritare. Întotdeauna silențios."</string>
-    <string name="notification_channel_summary_default" msgid="3847289783382316019">"Vă atrage atenția cu sunete și o pictogramă în bara de stare. Se afișează pe ecranul de blocare."</string>
+    <string name="notification_silence_title" msgid="5763240612242137433">"Silențios"</string>
+    <string name="notification_alert_title" msgid="8031196611815490340">"Alertare"</string>
+    <string name="notification_channel_summary_low" msgid="3387466082089715555">"Vă ajută să vă concentrați fără sunet sau vibrare."</string>
+    <string name="notification_channel_summary_default" msgid="5994062840431965586">"Vă atrage atenția fără sunet sau vibrare."</string>
     <string name="notification_unblockable_desc" msgid="4556908766584964102">"Aceste notificări nu pot fi modificate."</string>
     <string name="notification_multichannel_desc" msgid="4695920306092240550">"Acest grup de notificări nu poate fi configurat aici"</string>
     <string name="notification_delegate_header" msgid="2857691673814814270">"Notificare prin proxy"</string>
@@ -913,8 +905,7 @@
     <string name="slice_permission_allow" msgid="2340244901366722709">"Permiteți"</string>
     <string name="slice_permission_deny" msgid="7683681514008048807">"Refuzați"</string>
     <string name="auto_saver_title" msgid="1217959994732964228">"Atingeți pentru a programa Economisirea energiei"</string>
-    <!-- no translation found for auto_saver_text (2563289953551438248) -->
-    <skip />
+    <string name="auto_saver_text" msgid="2563289953551438248">"Porniți dacă este probabil ca bateria să se descarce"</string>
     <string name="no_auto_saver_action" msgid="8086002101711328500">"Nu, mulțumesc"</string>
     <string name="auto_saver_enabled_title" msgid="6726474226058316862">"S-a activat programarea pentru Economisirea bateriei"</string>
     <string name="auto_saver_enabled_text" msgid="874711029884777579">"Economisirea bateriei se va activa automat imediat ce bateria scade sub <xliff:g id="PERCENTAGE">%d</xliff:g>%%."</string>
@@ -947,4 +938,6 @@
     <string name="bubble_accessibility_action_move_bottom_left" msgid="206369104473183217">"Mutați în stânga jos"</string>
     <string name="bubble_accessibility_action_move_bottom_right" msgid="8705660152384312329">"Mutați în dreapta jos"</string>
     <string name="bubble_dismiss_text" msgid="8028337712674081668">"Închideți"</string>
+    <string name="notification_content_system_nav_changed" msgid="7218093915747788444">"Navigarea în sistem a fost actualizată. Pentru a face modificări, accesați Setările."</string>
+    <string name="notification_content_gesture_nav_available" msgid="8111130443656460792">"Accesați Setările pentru a actualiza navigarea în sistem"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-ru/strings.xml b/packages/SystemUI/res/values-ru/strings.xml
index 98b1868..c03c108 100644
--- a/packages/SystemUI/res/values-ru/strings.xml
+++ b/packages/SystemUI/res/values-ru/strings.xml
@@ -62,12 +62,10 @@
     <string name="usb_debugging_secondary_user_title" msgid="6353808721761220421">"Отладка по USB запрещена"</string>
     <string name="usb_debugging_secondary_user_message" msgid="6067122453571699801">"В этом аккаунте нельзя включить отладку по USB. Перейдите в аккаунт основного пользователя."</string>
     <string name="usb_contaminant_title" msgid="206854874263058490">"USB-порт отключен"</string>
-    <!-- no translation found for usb_contaminant_message (7379089091591609111) -->
-    <skip />
+    <string name="usb_contaminant_message" msgid="7379089091591609111">"Чтобы внутрь устройства не попала вода или грязь, USB-порт был отключен. Сейчас через него нельзя подсоединять другие устройства.\n\nКогда USB-порт снова можно будет использовать, вы получите уведомление."</string>
     <string name="usb_port_enabled" msgid="7906141351687694867">"USB-порт активен и может распознавать аксессуары и зарядные устройства."</string>
     <string name="usb_disable_contaminant_detection" msgid="2103905315747120033">"Включить USB-порт"</string>
-    <!-- no translation found for learn_more (5000517160980853569) -->
-    <skip />
+    <string name="learn_more" msgid="5000517160980853569">"Подробнее"</string>
     <string name="compat_mode_on" msgid="6623839244840638213">"Подогнать по размерам экрана"</string>
     <string name="compat_mode_off" msgid="4434467572461327898">"Растянуть на весь экран"</string>
     <string name="global_action_screenshot" msgid="8329831278085426283">"Скриншот"</string>
@@ -199,6 +197,7 @@
     <string name="carrier_network_change_mode" msgid="8149202439957837762">"Сменить сеть"</string>
     <string name="accessibility_battery_details" msgid="7645516654955025422">"Сведения о расходе заряда батареи"</string>
     <string name="accessibility_battery_level" msgid="7451474187113371965">"Заряд батареи в процентах: <xliff:g id="NUMBER">%d</xliff:g>."</string>
+    <string name="accessibility_battery_level_with_estimate" msgid="9033100930684311630">"Заряд батареи – <xliff:g id="PERCENTAGE">%1$s</xliff:g> %. При текущем уровне расхода его хватит примерно на такое время: <xliff:g id="TIME">%2$s</xliff:g>."</string>
     <string name="accessibility_battery_level_charging" msgid="1147587904439319646">"Зарядка батареи. Текущий заряд: <xliff:g id="BATTERY_PERCENTAGE">%d</xliff:g> %%."</string>
     <string name="accessibility_settings_button" msgid="799583911231893380">"Настройки"</string>
     <string name="accessibility_notifications_button" msgid="4498000369779421892">"Уведомления"</string>
@@ -464,10 +463,8 @@
     <string name="media_projection_remember_text" msgid="3103510882172746752">"Больше не показывать"</string>
     <string name="clear_all_notifications_text" msgid="814192889771462828">"Очистить все"</string>
     <string name="manage_notifications_text" msgid="2386728145475108753">"Настроить"</string>
-    <!-- no translation found for notification_section_header_gentle (4372438504154095677) -->
-    <skip />
-    <!-- no translation found for accessibility_notification_section_header_gentle_clear_all (4286716295850400959) -->
-    <skip />
+    <string name="notification_section_header_gentle" msgid="4372438504154095677">"Беззвучные уведомления"</string>
+    <string name="accessibility_notification_section_header_gentle_clear_all" msgid="4286716295850400959">"Отклонить все беззвучные уведомления"</string>
     <string name="dnd_suppressing_shade_text" msgid="1904574852846769301">"В режиме \"Не беспокоить\" уведомления заблокированы"</string>
     <string name="media_projection_action_text" msgid="8470872969457985954">"Начать"</string>
     <string name="empty_shade_text" msgid="708135716272867002">"Нет уведомлений"</string>
@@ -651,21 +648,16 @@
     <string name="inline_block_button" msgid="8735843688021655065">"Заблокировать"</string>
     <string name="inline_keep_button" msgid="6665940297019018232">"Показывать"</string>
     <string name="inline_minimize_button" msgid="966233327974702195">"Свернуть"</string>
-    <!-- no translation found for inline_silent_button_silent (5315879183296940969) -->
-    <skip />
+    <string name="inline_silent_button_silent" msgid="5315879183296940969">"Без звука"</string>
     <string name="inline_silent_button_stay_silent" msgid="6308371431217601009">"Не включать звук"</string>
-    <!-- no translation found for inline_silent_button_alert (6008435419895088034) -->
-    <skip />
+    <string name="inline_silent_button_alert" msgid="6008435419895088034">"Присылать оповещения"</string>
     <string name="inline_silent_button_keep_alerting" msgid="327696842264359693">"Присылать уведомления"</string>
     <string name="inline_turn_off_notifications" msgid="8635596135532202355">"Выключить уведомления"</string>
     <string name="inline_keep_showing_app" msgid="1723113469580031041">"Показывать уведомления от этого приложения?"</string>
-    <string name="notification_silence_title" msgid="7352089096356977930">"Беззвучные"</string>
-    <string name="notification_alert_title" msgid="3966526305405016221">"Приоритетные"</string>
-    <string name="notification_channel_summary_low" msgid="1065819618107531284">"Уведомления появляются только на специальной панели, чтобы вы не отвлекались. Всегда без звука."</string>
-    <string name="notification_channel_summary_low_status" msgid="2702170424808743755">"Показ уведомлений с низким приоритетом. Всегда без звука."</string>
-    <string name="notification_channel_summary_low_lock" msgid="7966605244472624458">"Показ уведомлений с низким приоритетом. Всегда без звука."</string>
-    <string name="notification_channel_summary_low_status_lock" msgid="7012562768950012739">"Показ уведомлений с низким приоритетом. Всегда без звука."</string>
-    <string name="notification_channel_summary_default" msgid="3847289783382316019">"Со звуком и значком в строке состояния. Появляются на заблокированном экране."</string>
+    <string name="notification_silence_title" msgid="5763240612242137433">"Без звука"</string>
+    <string name="notification_alert_title" msgid="8031196611815490340">"Оповещения"</string>
+    <string name="notification_channel_summary_low" msgid="3387466082089715555">"Уведомления приходят без звука и вибрации"</string>
+    <string name="notification_channel_summary_default" msgid="5994062840431965586">"Уведомления приходят со звуком или вибрацией"</string>
     <string name="notification_unblockable_desc" msgid="4556908766584964102">"Эти уведомления нельзя изменить."</string>
     <string name="notification_multichannel_desc" msgid="4695920306092240550">"Эту группу уведомлений нельзя настроить здесь."</string>
     <string name="notification_delegate_header" msgid="2857691673814814270">"Уведомление отправлено через прокси-сервер."</string>
@@ -918,8 +910,7 @@
     <string name="slice_permission_allow" msgid="2340244901366722709">"Да"</string>
     <string name="slice_permission_deny" msgid="7683681514008048807">"Нет"</string>
     <string name="auto_saver_title" msgid="1217959994732964228">"Нажмите, чтобы настроить режим энергосбережения"</string>
-    <!-- no translation found for auto_saver_text (2563289953551438248) -->
-    <skip />
+    <string name="auto_saver_text" msgid="2563289953551438248">"Включать, если высока вероятность, что батарея скоро разрядится"</string>
     <string name="no_auto_saver_action" msgid="8086002101711328500">"Отмена"</string>
     <string name="auto_saver_enabled_title" msgid="6726474226058316862">"Автоматический переход в режим энергосбережения включен"</string>
     <string name="auto_saver_enabled_text" msgid="874711029884777579">"Режим энергосбережения активируется при заряде батареи ниже <xliff:g id="PERCENTAGE">%d</xliff:g> %%."</string>
@@ -952,4 +943,6 @@
     <string name="bubble_accessibility_action_move_bottom_left" msgid="206369104473183217">"Перенести в левый нижний угол"</string>
     <string name="bubble_accessibility_action_move_bottom_right" msgid="8705660152384312329">"Перенести в правый нижний угол"</string>
     <string name="bubble_dismiss_text" msgid="8028337712674081668">"Закрыть"</string>
+    <string name="notification_content_system_nav_changed" msgid="7218093915747788444">"Параметры навигации в системе обновлены. Чтобы изменить их, перейдите в настройки."</string>
+    <string name="notification_content_gesture_nav_available" msgid="8111130443656460792">"Чтобы обновить параметры навигации в системе, перейдите в настройки."</string>
 </resources>
diff --git a/packages/SystemUI/res/values-si/strings.xml b/packages/SystemUI/res/values-si/strings.xml
index a2be259..f347e03 100644
--- a/packages/SystemUI/res/values-si/strings.xml
+++ b/packages/SystemUI/res/values-si/strings.xml
@@ -197,6 +197,7 @@
     <string name="carrier_network_change_mode" msgid="8149202439957837762">"වාහක ජාලය වෙනස් වෙමින්"</string>
     <string name="accessibility_battery_details" msgid="7645516654955025422">"බැටරි විස්තර විවෘත කරන්න"</string>
     <string name="accessibility_battery_level" msgid="7451474187113371965">"බැටරි ප්‍රතිශතය <xliff:g id="NUMBER">%d</xliff:g>"</string>
+    <string name="accessibility_battery_level_with_estimate" msgid="9033100930684311630">"බැටරි ප්‍රතිශතය <xliff:g id="PERCENTAGE">%1$s</xliff:g>, ඔබේ භාවිතයට අනුව <xliff:g id="TIME">%2$s</xliff:g> ක් පමණ ඉතුරුයි"</string>
     <string name="accessibility_battery_level_charging" msgid="1147587904439319646">"බැටරිය ආරෝපණය කරමින්, <xliff:g id="BATTERY_PERCENTAGE">%d</xliff:g>%%."</string>
     <string name="accessibility_settings_button" msgid="799583911231893380">"පද්ධති සැකසීම්."</string>
     <string name="accessibility_notifications_button" msgid="4498000369779421892">"දැනුම්දීම්."</string>
@@ -647,13 +648,10 @@
     <string name="inline_silent_button_keep_alerting" msgid="327696842264359693">"අඟවමින් සිටින්න"</string>
     <string name="inline_turn_off_notifications" msgid="8635596135532202355">"දැනුම්දීම් අක්‍රිය කරන්න"</string>
     <string name="inline_keep_showing_app" msgid="1723113469580031041">"මෙම යෙදුම වෙතින් දැනුම්දීම් පෙන්වමින් තබන්නද?"</string>
-    <string name="notification_silence_title" msgid="7352089096356977930">"මෘදු"</string>
-    <string name="notification_alert_title" msgid="3966526305405016221">"ප්‍රමුඛ කළ"</string>
-    <string name="notification_channel_summary_low" msgid="1065819618107531284">"ඔබට පහළට-ඇදීමේ වැස්මේ පමණක් දැනුම්දීම් සමඟ අවධානය යොමු කිරීමට උදවු කරයි. සැම විටම නිහඬයි."</string>
-    <string name="notification_channel_summary_low_status" msgid="2702170424808743755">"ප්‍රමුඛතා දැනුම්දීම්වලට පහළින් සංදර්ශනය වේ. සැම විටම නිහඬයි."</string>
-    <string name="notification_channel_summary_low_lock" msgid="7966605244472624458">"ප්‍රමුඛතා දැනුම්දීම්වලට පහළින් සංදර්ශනය වේ. සැම විටම නිහඬයි."</string>
-    <string name="notification_channel_summary_low_status_lock" msgid="7012562768950012739">"ප්‍රමුඛතා දැනුම්දීම්වලට පහළින් සංදර්ශනය වේ. සැම විටම නිහඬයි."</string>
-    <string name="notification_channel_summary_default" msgid="3847289783382316019">"ශබ්දයක් සහ තත්ත්ව තීරු නිරූපකයක් සමඟින් ඔබේ අවධානය ලබා ගනී. අගුළු තිරයෙහි පෙන්වයි."</string>
+    <string name="notification_silence_title" msgid="5763240612242137433">"නිහඬ"</string>
+    <string name="notification_alert_title" msgid="8031196611815490340">"ඇඟවීම"</string>
+    <string name="notification_channel_summary_low" msgid="3387466082089715555">"ඔබට ශබ්දය හෝ කම්පනය නොමැතිව අවධානය යොමු කිරීමට උදවු කරයි."</string>
+    <string name="notification_channel_summary_default" msgid="5994062840431965586">"ශබ්දය හෝ කම්පනය සමඟ ඔබේ අවධානය ලබා ගනී."</string>
     <string name="notification_unblockable_desc" msgid="4556908766584964102">"මෙම දැනුම්දීම් වෙනස් කළ නොහැක."</string>
     <string name="notification_multichannel_desc" msgid="4695920306092240550">"මෙම දැනුම්දීම් සමූහය මෙහි වින්‍යාස කළ නොහැක"</string>
     <string name="notification_delegate_header" msgid="2857691673814814270">"ප්‍රොක්සි කළ දැනුම්දීම"</string>
@@ -935,4 +933,6 @@
     <string name="bubble_accessibility_action_move_bottom_left" msgid="206369104473183217">"පහළ වමට ගෙන යන්න"</string>
     <string name="bubble_accessibility_action_move_bottom_right" msgid="8705660152384312329">"පහළ දකුණට ගෙන යන්න"</string>
     <string name="bubble_dismiss_text" msgid="8028337712674081668">"ඉවතලන්න"</string>
+    <string name="notification_content_system_nav_changed" msgid="7218093915747788444">"පද්ධති සංචලනය යාවත්කාලීන කළා. වෙනස්කම් සිදු කිරීමට, සැකසීම් වෙත යන්න."</string>
+    <string name="notification_content_gesture_nav_available" msgid="8111130443656460792">"පද්ධති සංචලනය යාවත්කාලීන කිරීමට සැකසීම් වෙත යන්න"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-sk/strings.xml b/packages/SystemUI/res/values-sk/strings.xml
index f4712e3..18a7b38 100644
--- a/packages/SystemUI/res/values-sk/strings.xml
+++ b/packages/SystemUI/res/values-sk/strings.xml
@@ -62,12 +62,10 @@
     <string name="usb_debugging_secondary_user_title" msgid="6353808721761220421">"Ladenie cez USB nie je povolené"</string>
     <string name="usb_debugging_secondary_user_message" msgid="6067122453571699801">"Používateľ, ktorý je práve prihlásený v tomto zariadení, nemôže zapnúť ladenie USB. Ak chcete použiť túto funkciu, prepnite na hlavného používateľa."</string>
     <string name="usb_contaminant_title" msgid="206854874263058490">"Port USB je deaktivovaný"</string>
-    <!-- no translation found for usb_contaminant_message (7379089091591609111) -->
-    <skip />
+    <string name="usb_contaminant_message" msgid="7379089091591609111">"Port USB je deaktivovaný na zaistenie ochrany zariadenia pred tekutinami alebo nečistotami a nerozpoznáva príslušenstvo.\n\nKeď ho budete môcť znova použiť, upozorníme vás."</string>
     <string name="usb_port_enabled" msgid="7906141351687694867">"Bol povolený port USB na zisťovanie nabíjačiek a príslušenstva"</string>
     <string name="usb_disable_contaminant_detection" msgid="2103905315747120033">"Povoliť USB"</string>
-    <!-- no translation found for learn_more (5000517160980853569) -->
-    <skip />
+    <string name="learn_more" msgid="5000517160980853569">"Ďalšie informácie"</string>
     <string name="compat_mode_on" msgid="6623839244840638213">"Priblížiť na celú obrazovku"</string>
     <string name="compat_mode_off" msgid="4434467572461327898">"Na celú obrazovku"</string>
     <string name="global_action_screenshot" msgid="8329831278085426283">"Snímka"</string>
@@ -199,6 +197,7 @@
     <string name="carrier_network_change_mode" msgid="8149202439957837762">"Mení sa sieť operátora"</string>
     <string name="accessibility_battery_details" msgid="7645516654955025422">"Otvoriť podrobnosti o batérii"</string>
     <string name="accessibility_battery_level" msgid="7451474187113371965">"Batéria <xliff:g id="NUMBER">%d</xliff:g> percent."</string>
+    <string name="accessibility_battery_level_with_estimate" msgid="9033100930684311630">"Percentá batérie: <xliff:g id="PERCENTAGE">%1$s</xliff:g>. Na základe vášho používania zostáva <xliff:g id="TIME">%2$s</xliff:g>."</string>
     <string name="accessibility_battery_level_charging" msgid="1147587904439319646">"Nabíja sa batéria, <xliff:g id="BATTERY_PERCENTAGE">%d</xliff:g> %%."</string>
     <string name="accessibility_settings_button" msgid="799583911231893380">"Nastavenia systému."</string>
     <string name="accessibility_notifications_button" msgid="4498000369779421892">"Upozornenia."</string>
@@ -313,7 +312,7 @@
     <string name="quick_settings_bluetooth_secondary_label_audio" msgid="5673845963301132071">"Zvuk"</string>
     <string name="quick_settings_bluetooth_secondary_label_headset" msgid="1880572731276240588">"Náhlavná súprava"</string>
     <string name="quick_settings_bluetooth_secondary_label_input" msgid="2173322305072945905">"Vstup"</string>
-    <string name="quick_settings_bluetooth_secondary_label_hearing_aids" msgid="4930931771490695395">"Načúvacie pomôcky"</string>
+    <string name="quick_settings_bluetooth_secondary_label_hearing_aids" msgid="4930931771490695395">"Načúvadlá"</string>
     <string name="quick_settings_bluetooth_secondary_label_transient" msgid="4551281899312150640">"Zapína sa…"</string>
     <string name="quick_settings_brightness_label" msgid="6968372297018755815">"Jas"</string>
     <string name="quick_settings_rotation_unlocked_label" msgid="7305323031808150099">"Automatické otáčanie"</string>
@@ -464,10 +463,8 @@
     <string name="media_projection_remember_text" msgid="3103510882172746752">"Nabudúce nezobrazovať"</string>
     <string name="clear_all_notifications_text" msgid="814192889771462828">"Vymazať všetko"</string>
     <string name="manage_notifications_text" msgid="2386728145475108753">"Spravovať"</string>
-    <!-- no translation found for notification_section_header_gentle (4372438504154095677) -->
-    <skip />
-    <!-- no translation found for accessibility_notification_section_header_gentle_clear_all (4286716295850400959) -->
-    <skip />
+    <string name="notification_section_header_gentle" msgid="4372438504154095677">"Tiché upozornenia"</string>
+    <string name="accessibility_notification_section_header_gentle_clear_all" msgid="4286716295850400959">"Vymazať všetky tiché upozornenia"</string>
     <string name="dnd_suppressing_shade_text" msgid="1904574852846769301">"Upozornenia sú pozastavené režimom bez vyrušení"</string>
     <string name="media_projection_action_text" msgid="8470872969457985954">"Spustiť"</string>
     <string name="empty_shade_text" msgid="708135716272867002">"Žiadne upozornenia"</string>
@@ -651,21 +648,16 @@
     <string name="inline_block_button" msgid="8735843688021655065">"Blokovať"</string>
     <string name="inline_keep_button" msgid="6665940297019018232">"Naďalej zobrazovať"</string>
     <string name="inline_minimize_button" msgid="966233327974702195">"Minimalizovať"</string>
-    <!-- no translation found for inline_silent_button_silent (5315879183296940969) -->
-    <skip />
+    <string name="inline_silent_button_silent" msgid="5315879183296940969">"Tichý"</string>
     <string name="inline_silent_button_stay_silent" msgid="6308371431217601009">"Naďalej upozorňovať potichu"</string>
-    <!-- no translation found for inline_silent_button_alert (6008435419895088034) -->
-    <skip />
+    <string name="inline_silent_button_alert" msgid="6008435419895088034">"Upozorňovanie"</string>
     <string name="inline_silent_button_keep_alerting" msgid="327696842264359693">"Naďalej upozorňovať"</string>
     <string name="inline_turn_off_notifications" msgid="8635596135532202355">"Vypnúť upozornenia"</string>
     <string name="inline_keep_showing_app" msgid="1723113469580031041">"Majú sa upozornenia z tejto aplikácie naďalej zobrazovať?"</string>
-    <string name="notification_silence_title" msgid="7352089096356977930">"Nenápadné"</string>
-    <string name="notification_alert_title" msgid="3966526305405016221">"Prioritné"</string>
-    <string name="notification_channel_summary_low" msgid="1065819618107531284">"Pomáha sústrediť sa zobrazovaním upozornení iba v rozbaľovacom paneli. Vždy potichu."</string>
-    <string name="notification_channel_summary_low_status" msgid="2702170424808743755">"Zobrazuje sa pod prioritnými upozorneniami. Vždy potichu."</string>
-    <string name="notification_channel_summary_low_lock" msgid="7966605244472624458">"Zobrazuje sa pod prioritnými upozorneniami. Vždy potichu."</string>
-    <string name="notification_channel_summary_low_status_lock" msgid="7012562768950012739">"Zobrazuje sa pod prioritnými upozorneniami. Vždy potichu."</string>
-    <string name="notification_channel_summary_default" msgid="3847289783382316019">"Upúta zvukom a zobrazením ikony v stavovom riadku. Zobrazuje sa na uzamknutej obrazovke."</string>
+    <string name="notification_silence_title" msgid="5763240612242137433">"Tiché"</string>
+    <string name="notification_alert_title" msgid="8031196611815490340">"Varovné"</string>
+    <string name="notification_channel_summary_low" msgid="3387466082089715555">"Pomáha vám sústrediť sa bez zvukov či vibrácií."</string>
+    <string name="notification_channel_summary_default" msgid="5994062840431965586">"Upúta vás zvukom alebo vibráciami."</string>
     <string name="notification_unblockable_desc" msgid="4556908766584964102">"Tieto upozornenia sa nedajú upraviť."</string>
     <string name="notification_multichannel_desc" msgid="4695920306092240550">"Túto skupinu upozornení nejde na tomto mieste konfigurovať"</string>
     <string name="notification_delegate_header" msgid="2857691673814814270">"Približné upozornenie"</string>
@@ -918,8 +910,7 @@
     <string name="slice_permission_allow" msgid="2340244901366722709">"Povoliť"</string>
     <string name="slice_permission_deny" msgid="7683681514008048807">"Zamietnuť"</string>
     <string name="auto_saver_title" msgid="1217959994732964228">"Klepnutím naplánujete aktivovanie Šetriča batérie"</string>
-    <!-- no translation found for auto_saver_text (2563289953551438248) -->
-    <skip />
+    <string name="auto_saver_text" msgid="2563289953551438248">"Zapnite, keď je batéria takmer vybitá"</string>
     <string name="no_auto_saver_action" msgid="8086002101711328500">"Nie, vďaka"</string>
     <string name="auto_saver_enabled_title" msgid="6726474226058316862">"Plánované aktivovanie Šetriča batérie bolo zapnuté"</string>
     <string name="auto_saver_enabled_text" msgid="874711029884777579">"Keď batéria klesne pod <xliff:g id="PERCENTAGE">%d</xliff:g> %%, automaticky sa aktivujte Šetrič batérie."</string>
@@ -952,4 +943,6 @@
     <string name="bubble_accessibility_action_move_bottom_left" msgid="206369104473183217">"Presunúť doľava nadol"</string>
     <string name="bubble_accessibility_action_move_bottom_right" msgid="8705660152384312329">"Presunúť doprava nadol"</string>
     <string name="bubble_dismiss_text" msgid="8028337712674081668">"Zavrieť"</string>
+    <string name="notification_content_system_nav_changed" msgid="7218093915747788444">"Navigácia v systéme bola aktualizovaná. Ak chcete vykonať zmeny, prejdite do Nastavení."</string>
+    <string name="notification_content_gesture_nav_available" msgid="8111130443656460792">"Prejdite do Nastavení a aktualizujte navigáciu v systéme"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-sl/strings.xml b/packages/SystemUI/res/values-sl/strings.xml
index 58ff074..e8a9889 100644
--- a/packages/SystemUI/res/values-sl/strings.xml
+++ b/packages/SystemUI/res/values-sl/strings.xml
@@ -62,12 +62,10 @@
     <string name="usb_debugging_secondary_user_title" msgid="6353808721761220421">"Odpravljanje napak s povezavo USB ni dovoljeno"</string>
     <string name="usb_debugging_secondary_user_message" msgid="6067122453571699801">"Uporabnik, trenutno prijavljen v napravo, ne more vklopiti odpravljanja napak s povezavo USB. Če želite uporabljati to funkcijo, preklopite na primarnega uporabnika."</string>
     <string name="usb_contaminant_title" msgid="206854874263058490">"Vrata USB so onemogočena"</string>
-    <!-- no translation found for usb_contaminant_message (7379089091591609111) -->
-    <skip />
+    <string name="usb_contaminant_message" msgid="7379089091591609111">"Zaradi zaščite naprave pred tekočino ali umazanijo so vrata USB onemogočena in ne bodo zaznala nobene dodatne opreme.\n\nKo bo znova varno uporabljati vrata USB, boste obveščeni."</string>
     <string name="usb_port_enabled" msgid="7906141351687694867">"Vrata USB so omogočena za zaznavanje polnilnikov in dodatne opreme"</string>
     <string name="usb_disable_contaminant_detection" msgid="2103905315747120033">"Omogoči USB"</string>
-    <!-- no translation found for learn_more (5000517160980853569) -->
-    <skip />
+    <string name="learn_more" msgid="5000517160980853569">"Več o tem"</string>
     <string name="compat_mode_on" msgid="6623839244840638213">"Povečava čez cel zaslon"</string>
     <string name="compat_mode_off" msgid="4434467572461327898">"Raztegnitev čez zaslon"</string>
     <string name="global_action_screenshot" msgid="8329831278085426283">"Posnetek"</string>
@@ -199,6 +197,7 @@
     <string name="carrier_network_change_mode" msgid="8149202439957837762">"Spreminjanje omrežja operaterja"</string>
     <string name="accessibility_battery_details" msgid="7645516654955025422">"Odpiranje podrobnosti o akumulatorju"</string>
     <string name="accessibility_battery_level" msgid="7451474187113371965">"Baterija <xliff:g id="NUMBER">%d</xliff:g> odstotkov."</string>
+    <string name="accessibility_battery_level_with_estimate" msgid="9033100930684311630">"Napolnjenost akumulatorja je <xliff:g id="PERCENTAGE">%1$s</xliff:g>, glede na način uporabe imate na voljo še približno <xliff:g id="TIME">%2$s</xliff:g>"</string>
     <string name="accessibility_battery_level_charging" msgid="1147587904439319646">"Polnjenje akumulatorja, <xliff:g id="BATTERY_PERCENTAGE">%d</xliff:g> %%."</string>
     <string name="accessibility_settings_button" msgid="799583911231893380">"Sistemske nastavitve."</string>
     <string name="accessibility_notifications_button" msgid="4498000369779421892">"Obvestila."</string>
@@ -464,10 +463,8 @@
     <string name="media_projection_remember_text" msgid="3103510882172746752">"Tega ne prikaži več"</string>
     <string name="clear_all_notifications_text" msgid="814192889771462828">"Izbriši vse"</string>
     <string name="manage_notifications_text" msgid="2386728145475108753">"Upravljanje"</string>
-    <!-- no translation found for notification_section_header_gentle (4372438504154095677) -->
-    <skip />
-    <!-- no translation found for accessibility_notification_section_header_gentle_clear_all (4286716295850400959) -->
-    <skip />
+    <string name="notification_section_header_gentle" msgid="4372438504154095677">"Tiha obvestila"</string>
+    <string name="accessibility_notification_section_header_gentle_clear_all" msgid="4286716295850400959">"Brisanje vseh tihih obvestil"</string>
     <string name="dnd_suppressing_shade_text" msgid="1904574852846769301">"Prikazovanje obvestil je začasno zaustavljeno z načinom »ne moti«"</string>
     <string name="media_projection_action_text" msgid="8470872969457985954">"Začni zdaj"</string>
     <string name="empty_shade_text" msgid="708135716272867002">"Ni obvestil"</string>
@@ -651,21 +648,16 @@
     <string name="inline_block_button" msgid="8735843688021655065">"Blokiraj"</string>
     <string name="inline_keep_button" msgid="6665940297019018232">"Prikazuj še naprej"</string>
     <string name="inline_minimize_button" msgid="966233327974702195">"Minimiraj"</string>
-    <!-- no translation found for inline_silent_button_silent (5315879183296940969) -->
-    <skip />
+    <string name="inline_silent_button_silent" msgid="5315879183296940969">"Tiho"</string>
     <string name="inline_silent_button_stay_silent" msgid="6308371431217601009">"Še naprej prikazuj brez zvoka"</string>
-    <!-- no translation found for inline_silent_button_alert (6008435419895088034) -->
-    <skip />
+    <string name="inline_silent_button_alert" msgid="6008435419895088034">"Z zvočnim opozorilom"</string>
     <string name="inline_silent_button_keep_alerting" msgid="327696842264359693">"Še naprej opozarjaj"</string>
     <string name="inline_turn_off_notifications" msgid="8635596135532202355">"Izklopi obvestila"</string>
     <string name="inline_keep_showing_app" msgid="1723113469580031041">"Želite, da so obvestila te aplikacije še naprej prikazana?"</string>
-    <string name="notification_silence_title" msgid="7352089096356977930">"Diskretno"</string>
-    <string name="notification_alert_title" msgid="3966526305405016221">"Prednostno"</string>
-    <string name="notification_channel_summary_low" msgid="1065819618107531284">"Nemoteč prikaz samo na poteznem zaslonu z obvestili. Vedno tiho."</string>
-    <string name="notification_channel_summary_low_status" msgid="2702170424808743755">"Prikaz pod prednostnimi obvestili. Vedno tiho."</string>
-    <string name="notification_channel_summary_low_lock" msgid="7966605244472624458">"Prikaz pod prednostnimi obvestili. Vedno tiho."</string>
-    <string name="notification_channel_summary_low_status_lock" msgid="7012562768950012739">"Prikaz pod prednostnimi obvestili. Vedno tiho."</string>
-    <string name="notification_channel_summary_default" msgid="3847289783382316019">"Opozarjanje z zvokom in ikono v vrstici stanja. Prikaz na zaklenjenem zaslonu."</string>
+    <string name="notification_silence_title" msgid="5763240612242137433">"Tiho"</string>
+    <string name="notification_alert_title" msgid="8031196611815490340">"Z zvočnim opozorilom"</string>
+    <string name="notification_channel_summary_low" msgid="3387466082089715555">"Nemoteč prikaz brez zvoka ali vibriranja"</string>
+    <string name="notification_channel_summary_default" msgid="5994062840431965586">"Pritegnitev pozornosti z zvokom ali vibriranjem"</string>
     <string name="notification_unblockable_desc" msgid="4556908766584964102">"Za ta obvestila ni mogoče spremeniti nastavitev."</string>
     <string name="notification_multichannel_desc" msgid="4695920306092240550">"Te skupine obvestil ni mogoče konfigurirati tukaj"</string>
     <string name="notification_delegate_header" msgid="2857691673814814270">"Posredovano obvestilo"</string>
@@ -918,8 +910,7 @@
     <string name="slice_permission_allow" msgid="2340244901366722709">"Dovoli"</string>
     <string name="slice_permission_deny" msgid="7683681514008048807">"Zavrni"</string>
     <string name="auto_saver_title" msgid="1217959994732964228">"Dotaknite se za načrtovanje varčevanja z energijo akumulatorja"</string>
-    <!-- no translation found for auto_saver_text (2563289953551438248) -->
-    <skip />
+    <string name="auto_saver_text" msgid="2563289953551438248">"Vklop, če je verjetno, da se bo akumulator izpraznil"</string>
     <string name="no_auto_saver_action" msgid="8086002101711328500">"Ne, hvala"</string>
     <string name="auto_saver_enabled_title" msgid="6726474226058316862">"Urnik varčevanja z energijo akumulatorja je vklopljen"</string>
     <string name="auto_saver_enabled_text" msgid="874711029884777579">"Varčevanje z energijo akumulatorja se bo samodejno vklopilo, ko bo energija akumulatorja pod <xliff:g id="PERCENTAGE">%d</xliff:g> %%."</string>
@@ -952,4 +943,6 @@
     <string name="bubble_accessibility_action_move_bottom_left" msgid="206369104473183217">"Premakni spodaj levo"</string>
     <string name="bubble_accessibility_action_move_bottom_right" msgid="8705660152384312329">"Premakni spodaj desno"</string>
     <string name="bubble_dismiss_text" msgid="8028337712674081668">"Opusti"</string>
+    <string name="notification_content_system_nav_changed" msgid="7218093915747788444">"Krmarjenje po sistemu je posodobljeno. Če želite opraviti spremembe, odprite nastavitve."</string>
+    <string name="notification_content_gesture_nav_available" msgid="8111130443656460792">"Če želite posodobiti krmarjenje po sistemu, odprite nastavitve"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-sq/strings.xml b/packages/SystemUI/res/values-sq/strings.xml
index 592915b..a2694b8 100644
--- a/packages/SystemUI/res/values-sq/strings.xml
+++ b/packages/SystemUI/res/values-sq/strings.xml
@@ -62,12 +62,10 @@
     <string name="usb_debugging_secondary_user_title" msgid="6353808721761220421">"Korrigjimi i USB-së nuk lejohet"</string>
     <string name="usb_debugging_secondary_user_message" msgid="6067122453571699801">"Përdoruesi i identifikuar aktualisht në këtë pajisje nuk mund ta aktivizojë korrigjimin e USB-së. Për ta përdorur këtë funksion, kalo te përdoruesi parësor."</string>
     <string name="usb_contaminant_title" msgid="206854874263058490">"Porta e USB-së është çaktivizuar"</string>
-    <!-- no translation found for usb_contaminant_message (7379089091591609111) -->
-    <skip />
+    <string name="usb_contaminant_message" msgid="7379089091591609111">"Për të mbrojtur pajisjen tënde nga lëngjet apo papastërtitë, porta e USB-së është çaktivizuar dhe nuk do t\'i dallojë aksesorët.\n\nDo të njoftohesh kur të mos jetë problem përdorimi përsëri i portës USB."</string>
     <string name="usb_port_enabled" msgid="7906141351687694867">"Porta USB është aktivizuar për të zbuluar karikuesit dhe aksesorët"</string>
     <string name="usb_disable_contaminant_detection" msgid="2103905315747120033">"Aktivizo USB-në"</string>
-    <!-- no translation found for learn_more (5000517160980853569) -->
-    <skip />
+    <string name="learn_more" msgid="5000517160980853569">"Mëso më shumë"</string>
     <string name="compat_mode_on" msgid="6623839244840638213">"Zmadho për të mbushur ekranin"</string>
     <string name="compat_mode_off" msgid="4434467572461327898">"Shtrije për të mbushur ekranin"</string>
     <string name="global_action_screenshot" msgid="8329831278085426283">"Pamja e ekranit"</string>
@@ -199,6 +197,7 @@
     <string name="carrier_network_change_mode" msgid="8149202439957837762">"Rrjeti i operatorit celular po ndryshohet"</string>
     <string name="accessibility_battery_details" msgid="7645516654955025422">"Hap detajet e baterisë"</string>
     <string name="accessibility_battery_level" msgid="7451474187113371965">"Bateria ka edhe <xliff:g id="NUMBER">%d</xliff:g> për qind."</string>
+    <string name="accessibility_battery_level_with_estimate" msgid="9033100930684311630">"Bateria <xliff:g id="PERCENTAGE">%1$s</xliff:g> përqind, rreth <xliff:g id="TIME">%2$s</xliff:g> të mbetura bazuar në përdorimin tënd"</string>
     <string name="accessibility_battery_level_charging" msgid="1147587904439319646">"Bateria po karikohet, <xliff:g id="BATTERY_PERCENTAGE">%d</xliff:g>%%."</string>
     <string name="accessibility_settings_button" msgid="799583911231893380">"Cilësimet e sistemit."</string>
     <string name="accessibility_notifications_button" msgid="4498000369779421892">"Njoftimet."</string>
@@ -458,10 +457,8 @@
     <string name="media_projection_remember_text" msgid="3103510882172746752">"Mos e shfaq sërish"</string>
     <string name="clear_all_notifications_text" msgid="814192889771462828">"Pastroji të gjitha"</string>
     <string name="manage_notifications_text" msgid="2386728145475108753">"Menaxho"</string>
-    <!-- no translation found for notification_section_header_gentle (4372438504154095677) -->
-    <skip />
-    <!-- no translation found for accessibility_notification_section_header_gentle_clear_all (4286716295850400959) -->
-    <skip />
+    <string name="notification_section_header_gentle" msgid="4372438504154095677">"Njoftimet në heshtje"</string>
+    <string name="accessibility_notification_section_header_gentle_clear_all" msgid="4286716295850400959">"Pastro të gjitha njoftimet në heshtje"</string>
     <string name="dnd_suppressing_shade_text" msgid="1904574852846769301">"Njoftimet janë vendosur në pauzë nga modaliteti \"Mos shqetëso\""</string>
     <string name="media_projection_action_text" msgid="8470872969457985954">"Fillo tani"</string>
     <string name="empty_shade_text" msgid="708135716272867002">"Asnjë njoftim"</string>
@@ -645,21 +642,16 @@
     <string name="inline_block_button" msgid="8735843688021655065">"Blloko"</string>
     <string name="inline_keep_button" msgid="6665940297019018232">"Vazhdo të shfaqësh"</string>
     <string name="inline_minimize_button" msgid="966233327974702195">"Minimizo"</string>
-    <!-- no translation found for inline_silent_button_silent (5315879183296940969) -->
-    <skip />
+    <string name="inline_silent_button_silent" msgid="5315879183296940969">"Në heshtje"</string>
     <string name="inline_silent_button_stay_silent" msgid="6308371431217601009">"Qëndro në heshtje"</string>
-    <!-- no translation found for inline_silent_button_alert (6008435419895088034) -->
-    <skip />
+    <string name="inline_silent_button_alert" msgid="6008435419895088034">"Sinjalizimi"</string>
     <string name="inline_silent_button_keep_alerting" msgid="327696842264359693">"Vazhdo të sinjalizosh"</string>
     <string name="inline_turn_off_notifications" msgid="8635596135532202355">"Çaktivizo njoftimet"</string>
     <string name="inline_keep_showing_app" msgid="1723113469580031041">"Do të vazhdosh t\'i shfaqësh njoftimet nga ky aplikacion?"</string>
-    <string name="notification_silence_title" msgid="7352089096356977930">"Me rëndësi të ulët"</string>
-    <string name="notification_alert_title" msgid="3966526305405016221">"Me prioritet"</string>
-    <string name="notification_channel_summary_low" msgid="1065819618107531284">"Të ndihmon të përqendrohesh me njoftimet vetëm në panelin zbritës. Gjithmonë në heshtje."</string>
-    <string name="notification_channel_summary_low_status" msgid="2702170424808743755">"Shfaqet nën njoftimet me përparësi. Gjithmonë në heshtje."</string>
-    <string name="notification_channel_summary_low_lock" msgid="7966605244472624458">"Shfaqet nën njoftimet me përparësi. Gjithmonë në heshtje."</string>
-    <string name="notification_channel_summary_low_status_lock" msgid="7012562768950012739">"Shfaqet nën njoftimet me përparësi. Gjithmonë në heshtje."</string>
-    <string name="notification_channel_summary_default" msgid="3847289783382316019">"Të tërheq vëmendjen me tingull dhe një ikonë në shiritin e statusit. Shfaqet në ekranin e kyçjes."</string>
+    <string name="notification_silence_title" msgid="5763240612242137433">"Në heshtje"</string>
+    <string name="notification_alert_title" msgid="8031196611815490340">"Sinjalizimi"</string>
+    <string name="notification_channel_summary_low" msgid="3387466082089715555">"Të ndihmon të fokusohesh pa tinguj ose dridhje."</string>
+    <string name="notification_channel_summary_default" msgid="5994062840431965586">"Të tërheq vëmendjen me tinguj ose dridhje."</string>
     <string name="notification_unblockable_desc" msgid="4556908766584964102">"Këto njoftime nuk mund të modifikohen."</string>
     <string name="notification_multichannel_desc" msgid="4695920306092240550">"Ky grup njoftimesh nuk mund të konfigurohet këtu"</string>
     <string name="notification_delegate_header" msgid="2857691673814814270">"Njoftim i dërguar me përfaqësues"</string>
@@ -908,8 +900,7 @@
     <string name="slice_permission_allow" msgid="2340244901366722709">"Lejo"</string>
     <string name="slice_permission_deny" msgid="7683681514008048807">"Refuzo"</string>
     <string name="auto_saver_title" msgid="1217959994732964228">"Trokit për të planifikuar \"Kursyesin e baterisë\""</string>
-    <!-- no translation found for auto_saver_text (2563289953551438248) -->
-    <skip />
+    <string name="auto_saver_text" msgid="2563289953551438248">"Aktivizoje kur bateria mund të mbarojë"</string>
     <string name="no_auto_saver_action" msgid="8086002101711328500">"Jo"</string>
     <string name="auto_saver_enabled_title" msgid="6726474226058316862">"Planifikimi i \"Kursyesit të baterisë\" është aktivizuar"</string>
     <string name="auto_saver_enabled_text" msgid="874711029884777579">"\"Kursyesi i baterisë\" do të aktivizohet automatikisht kur bateria të jetë nën <xliff:g id="PERCENTAGE">%d</xliff:g>%%."</string>
@@ -942,4 +933,6 @@
     <string name="bubble_accessibility_action_move_bottom_left" msgid="206369104473183217">"Zhvendos poshtë majtas"</string>
     <string name="bubble_accessibility_action_move_bottom_right" msgid="8705660152384312329">"Lëvize poshtë djathtas"</string>
     <string name="bubble_dismiss_text" msgid="8028337712674081668">"Hiq"</string>
+    <string name="notification_content_system_nav_changed" msgid="7218093915747788444">"Navigimi i sistemit u përditësua. Për të bërë ndryshime, shko te \"Cilësimet\"."</string>
+    <string name="notification_content_gesture_nav_available" msgid="8111130443656460792">"Shko te \"Cilësimet\" për të përditësuar navigimin e sistemit"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-sr/strings.xml b/packages/SystemUI/res/values-sr/strings.xml
index c71bbf6..6914991 100644
--- a/packages/SystemUI/res/values-sr/strings.xml
+++ b/packages/SystemUI/res/values-sr/strings.xml
@@ -62,12 +62,10 @@
     <string name="usb_debugging_secondary_user_title" msgid="6353808721761220421">"Отклањање грешака на USB-у није дозвољено"</string>
     <string name="usb_debugging_secondary_user_message" msgid="6067122453571699801">"Корисник који је тренутно пријављен на овај уређај не може да укључи отклањање грешака на USB-у. Да бисте користили ову функцију, пребаците на примарног корисника."</string>
     <string name="usb_contaminant_title" msgid="206854874263058490">"USB порт је онемогућен"</string>
-    <!-- no translation found for usb_contaminant_message (7379089091591609111) -->
-    <skip />
+    <string name="usb_contaminant_message" msgid="7379089091591609111">"Да би се уређај заштитио од течности или нечистоће, USB порт је онемогућен и неће откривати додатну опрему.\n\nОбавестићемо вас када поново будете могли да користите USB порт."</string>
     <string name="usb_port_enabled" msgid="7906141351687694867">"USB порт је омогућен ради откривања пуњача и додатне опреме"</string>
     <string name="usb_disable_contaminant_detection" msgid="2103905315747120033">"Омогући USB"</string>
-    <!-- no translation found for learn_more (5000517160980853569) -->
-    <skip />
+    <string name="learn_more" msgid="5000517160980853569">"Сазнајте више"</string>
     <string name="compat_mode_on" msgid="6623839244840638213">"Зумирај на целом екрану"</string>
     <string name="compat_mode_off" msgid="4434467572461327898">"Развуци на цео екран"</string>
     <string name="global_action_screenshot" msgid="8329831278085426283">"Снимак екрана"</string>
@@ -199,6 +197,7 @@
     <string name="carrier_network_change_mode" msgid="8149202439957837762">"Промена мреже мобилног оператера"</string>
     <string name="accessibility_battery_details" msgid="7645516654955025422">"Отвори детаље о батерији"</string>
     <string name="accessibility_battery_level" msgid="7451474187113371965">"Батерија је на <xliff:g id="NUMBER">%d</xliff:g> посто."</string>
+    <string name="accessibility_battery_level_with_estimate" msgid="9033100930684311630">"Батерија је на <xliff:g id="PERCENTAGE">%1$s</xliff:g> посто, преостало време на основу коришћења је <xliff:g id="TIME">%2$s</xliff:g>"</string>
     <string name="accessibility_battery_level_charging" msgid="1147587904439319646">"Батерија се пуни, <xliff:g id="BATTERY_PERCENTAGE">%d</xliff:g>%%."</string>
     <string name="accessibility_settings_button" msgid="799583911231893380">"Системска подешавања."</string>
     <string name="accessibility_notifications_button" msgid="4498000369779421892">"Обавештења."</string>
@@ -461,10 +460,8 @@
     <string name="media_projection_remember_text" msgid="3103510882172746752">"Не приказуј поново"</string>
     <string name="clear_all_notifications_text" msgid="814192889771462828">"Обриши све"</string>
     <string name="manage_notifications_text" msgid="2386728145475108753">"Управљајте"</string>
-    <!-- no translation found for notification_section_header_gentle (4372438504154095677) -->
-    <skip />
-    <!-- no translation found for accessibility_notification_section_header_gentle_clear_all (4286716295850400959) -->
-    <skip />
+    <string name="notification_section_header_gentle" msgid="4372438504154095677">"Нечујна обавештења"</string>
+    <string name="accessibility_notification_section_header_gentle_clear_all" msgid="4286716295850400959">"Обришите сва нечујна обавештења"</string>
     <string name="dnd_suppressing_shade_text" msgid="1904574852846769301">"Обавештења су паузирана режимом Не узнемиравај"</string>
     <string name="media_projection_action_text" msgid="8470872969457985954">"Започни одмах"</string>
     <string name="empty_shade_text" msgid="708135716272867002">"Нема обавештења"</string>
@@ -648,21 +645,16 @@
     <string name="inline_block_button" msgid="8735843688021655065">"Блокирај"</string>
     <string name="inline_keep_button" msgid="6665940297019018232">"Настави да приказујеш"</string>
     <string name="inline_minimize_button" msgid="966233327974702195">"Умањи"</string>
-    <!-- no translation found for inline_silent_button_silent (5315879183296940969) -->
-    <skip />
+    <string name="inline_silent_button_silent" msgid="5315879183296940969">"Нечујно"</string>
     <string name="inline_silent_button_stay_silent" msgid="6308371431217601009">"Не укључуј звук"</string>
-    <!-- no translation found for inline_silent_button_alert (6008435419895088034) -->
-    <skip />
+    <string name="inline_silent_button_alert" msgid="6008435419895088034">"Упозоравање"</string>
     <string name="inline_silent_button_keep_alerting" msgid="327696842264359693">"Настави са обавештењима"</string>
     <string name="inline_turn_off_notifications" msgid="8635596135532202355">"Искључи обавештења"</string>
     <string name="inline_keep_showing_app" msgid="1723113469580031041">"Желите ли да се обавештења из ове апликације и даље приказују?"</string>
-    <string name="notification_silence_title" msgid="7352089096356977930">"Дискретно"</string>
-    <string name="notification_alert_title" msgid="3966526305405016221">"Приоритетно"</string>
-    <string name="notification_channel_summary_low" msgid="1065819618107531284">"Помаже вам да се фокусирате. Обавештења су само на падајућој траци. Увек нечујно."</string>
-    <string name="notification_channel_summary_low_status" msgid="2702170424808743755">"Приказује се испод приоритетних обавештења. Увек нечујно."</string>
-    <string name="notification_channel_summary_low_lock" msgid="7966605244472624458">"Приказује се испод приоритетних обавештења. Увек нечујно."</string>
-    <string name="notification_channel_summary_low_status_lock" msgid="7012562768950012739">"Приказује се испод приоритетних обавештења. Увек нечујно."</string>
-    <string name="notification_channel_summary_default" msgid="3847289783382316019">"Привлачи вам пажњу помоћу звука и иконе статусне траке. Приказује се на закључаном екрану."</string>
+    <string name="notification_silence_title" msgid="5763240612242137433">"Нечујно"</string>
+    <string name="notification_alert_title" msgid="8031196611815490340">"Упозоравање"</string>
+    <string name="notification_channel_summary_low" msgid="3387466082089715555">"Помаже вам да се концентришете без звука или вибрације."</string>
+    <string name="notification_channel_summary_default" msgid="5994062840431965586">"Привлачи вам пажњу помоћу звука или вибрације."</string>
     <string name="notification_unblockable_desc" msgid="4556908766584964102">"Ова обавештења не могу да се мењају."</string>
     <string name="notification_multichannel_desc" msgid="4695920306092240550">"Ова група обавештења не може да се конфигурише овде"</string>
     <string name="notification_delegate_header" msgid="2857691673814814270">"Обавештење преко проксија"</string>
@@ -913,8 +905,7 @@
     <string name="slice_permission_allow" msgid="2340244901366722709">"Дозволи"</string>
     <string name="slice_permission_deny" msgid="7683681514008048807">"Одбиј"</string>
     <string name="auto_saver_title" msgid="1217959994732964228">"Додирните да бисте направили распоред за уштеду батерије"</string>
-    <!-- no translation found for auto_saver_text (2563289953551438248) -->
-    <skip />
+    <string name="auto_saver_text" msgid="2563289953551438248">"Укључите ако ће батерија вероватно да се испразни"</string>
     <string name="no_auto_saver_action" msgid="8086002101711328500">"Не, хвала"</string>
     <string name="auto_saver_enabled_title" msgid="6726474226058316862">"Распоред за уштеду батерије је укључен"</string>
     <string name="auto_saver_enabled_text" msgid="874711029884777579">"Уштеда батерије ће се аутоматски укључивати када батерија падне испод <xliff:g id="PERCENTAGE">%d</xliff:g>%%."</string>
@@ -947,4 +938,6 @@
     <string name="bubble_accessibility_action_move_bottom_left" msgid="206369104473183217">"Премести доле лево"</string>
     <string name="bubble_accessibility_action_move_bottom_right" msgid="8705660152384312329">"Премести доле десно"</string>
     <string name="bubble_dismiss_text" msgid="8028337712674081668">"Одбаци"</string>
+    <string name="notification_content_system_nav_changed" msgid="7218093915747788444">"Навигација система је ажурирана. Да бисте унели измене, идите у Подешавања."</string>
+    <string name="notification_content_gesture_nav_available" msgid="8111130443656460792">"Идите у Подешавања да бисте ажурирали навигацију система"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-sv/strings.xml b/packages/SystemUI/res/values-sv/strings.xml
index 0f39fc2..6a9d3d3 100644
--- a/packages/SystemUI/res/values-sv/strings.xml
+++ b/packages/SystemUI/res/values-sv/strings.xml
@@ -62,12 +62,10 @@
     <string name="usb_debugging_secondary_user_title" msgid="6353808721761220421">"USB-felsökning är inte tillåtet"</string>
     <string name="usb_debugging_secondary_user_message" msgid="6067122453571699801">"Användaren som är inloggad på enheten för närvarande kan inte aktivera USB-felsökning. Byt till den primära användaren om du vill använda den här funktionen."</string>
     <string name="usb_contaminant_title" msgid="206854874263058490">"USB-porten har inaktiverats"</string>
-    <!-- no translation found for usb_contaminant_message (7379089091591609111) -->
-    <skip />
+    <string name="usb_contaminant_message" msgid="7379089091591609111">"USB-porten har inaktiverats för att skydda enheten mot vätska eller smuts. Inga tillbehör kommer att hittas.\n\nDu meddelas när det går att använda USB-porten igen."</string>
     <string name="usb_port_enabled" msgid="7906141351687694867">"USB-porten har aktiverats för identifiering av laddare och tillbehör"</string>
     <string name="usb_disable_contaminant_detection" msgid="2103905315747120033">"Aktivera USB"</string>
-    <!-- no translation found for learn_more (5000517160980853569) -->
-    <skip />
+    <string name="learn_more" msgid="5000517160980853569">"Läs mer"</string>
     <string name="compat_mode_on" msgid="6623839244840638213">"Zooma för att fylla skärm"</string>
     <string name="compat_mode_off" msgid="4434467572461327898">"Dra för att fylla skärmen"</string>
     <string name="global_action_screenshot" msgid="8329831278085426283">"Skärmdump"</string>
@@ -199,6 +197,7 @@
     <string name="carrier_network_change_mode" msgid="8149202439957837762">"Byter leverantörsnätverk"</string>
     <string name="accessibility_battery_details" msgid="7645516654955025422">"Visa uppgifter om batteri"</string>
     <string name="accessibility_battery_level" msgid="7451474187113371965">"Batteri <xliff:g id="NUMBER">%d</xliff:g> procent."</string>
+    <string name="accessibility_battery_level_with_estimate" msgid="9033100930684311630">"Batteri: <xliff:g id="PERCENTAGE">%1$s</xliff:g> procent, cirka <xliff:g id="TIME">%2$s</xliff:g> kvar utifrån din användning"</string>
     <string name="accessibility_battery_level_charging" msgid="1147587904439319646">"Batteriet laddas, <xliff:g id="BATTERY_PERCENTAGE">%d</xliff:g> procent."</string>
     <string name="accessibility_settings_button" msgid="799583911231893380">"Systeminställningar."</string>
     <string name="accessibility_notifications_button" msgid="4498000369779421892">"Meddelanden."</string>
@@ -458,10 +457,8 @@
     <string name="media_projection_remember_text" msgid="3103510882172746752">"Visa inte igen"</string>
     <string name="clear_all_notifications_text" msgid="814192889771462828">"Rensa alla"</string>
     <string name="manage_notifications_text" msgid="2386728145475108753">"Hantera"</string>
-    <!-- no translation found for notification_section_header_gentle (4372438504154095677) -->
-    <skip />
-    <!-- no translation found for accessibility_notification_section_header_gentle_clear_all (4286716295850400959) -->
-    <skip />
+    <string name="notification_section_header_gentle" msgid="4372438504154095677">"Ljudlösa aviseringar"</string>
+    <string name="accessibility_notification_section_header_gentle_clear_all" msgid="4286716295850400959">"Rensa alla ljudlösa aviseringar"</string>
     <string name="dnd_suppressing_shade_text" msgid="1904574852846769301">"Aviseringar har pausats via Stör ej"</string>
     <string name="media_projection_action_text" msgid="8470872969457985954">"Starta nu"</string>
     <string name="empty_shade_text" msgid="708135716272867002">"Inga aviseringar"</string>
@@ -645,21 +642,16 @@
     <string name="inline_block_button" msgid="8735843688021655065">"Blockera"</string>
     <string name="inline_keep_button" msgid="6665940297019018232">"Fortsätt visa"</string>
     <string name="inline_minimize_button" msgid="966233327974702195">"Minimera"</string>
-    <!-- no translation found for inline_silent_button_silent (5315879183296940969) -->
-    <skip />
+    <string name="inline_silent_button_silent" msgid="5315879183296940969">"Ljudlöst"</string>
     <string name="inline_silent_button_stay_silent" msgid="6308371431217601009">"Fortsätt visa utan ljud"</string>
-    <!-- no translation found for inline_silent_button_alert (6008435419895088034) -->
-    <skip />
+    <string name="inline_silent_button_alert" msgid="6008435419895088034">"Med avisering"</string>
     <string name="inline_silent_button_keep_alerting" msgid="327696842264359693">"Fortsätt meddela"</string>
     <string name="inline_turn_off_notifications" msgid="8635596135532202355">"Inaktivera aviseringar"</string>
     <string name="inline_keep_showing_app" msgid="1723113469580031041">"Vill du fortsätta visa aviseringar för den här appen?"</string>
-    <string name="notification_silence_title" msgid="7352089096356977930">"Utan avbrott"</string>
-    <string name="notification_alert_title" msgid="3966526305405016221">"Prioriterade"</string>
-    <string name="notification_channel_summary_low" msgid="1065819618107531284">"Aviseringar visas bara på aviseringspanelen så att du kan fokusera på det viktigaste. Alltid tyst."</string>
-    <string name="notification_channel_summary_low_status" msgid="2702170424808743755">"Aviseringar med låg prioritet visas. Alltid tyst."</string>
-    <string name="notification_channel_summary_low_lock" msgid="7966605244472624458">"Aviseringar med låg prioritet visas. Alltid tyst."</string>
-    <string name="notification_channel_summary_low_status_lock" msgid="7012562768950012739">"Aviseringar med låg prioritet visas. Alltid tyst."</string>
-    <string name="notification_channel_summary_default" msgid="3847289783382316019">"Fångar din uppmärksamhet med ljud och en ikon i statusfältet. Visas på låsskärmen."</string>
+    <string name="notification_silence_title" msgid="5763240612242137433">"Tyst"</string>
+    <string name="notification_alert_title" msgid="8031196611815490340">"Påkallar uppmärksamhet"</string>
+    <string name="notification_channel_summary_low" msgid="3387466082089715555">"Inga ljud eller vibrationer som stör koncentrationen."</string>
+    <string name="notification_channel_summary_default" msgid="5994062840431965586">"Påkallar uppmärksamhet med ljud eller vibrationer."</string>
     <string name="notification_unblockable_desc" msgid="4556908766584964102">"Det går inte att ändra de här aviseringarna."</string>
     <string name="notification_multichannel_desc" msgid="4695920306092240550">"Den här aviseringsgruppen kan inte konfigureras här"</string>
     <string name="notification_delegate_header" msgid="2857691673814814270">"Avisering via proxy"</string>
@@ -908,8 +900,7 @@
     <string name="slice_permission_allow" msgid="2340244901366722709">"Tillåt"</string>
     <string name="slice_permission_deny" msgid="7683681514008048807">"Neka"</string>
     <string name="auto_saver_title" msgid="1217959994732964228">"Tryck för att skapa ett schema för batterisparläget"</string>
-    <!-- no translation found for auto_saver_text (2563289953551438248) -->
-    <skip />
+    <string name="auto_saver_text" msgid="2563289953551438248">"Aktivera när batteriet håller på att ta slut"</string>
     <string name="no_auto_saver_action" msgid="8086002101711328500">"Nej tack"</string>
     <string name="auto_saver_enabled_title" msgid="6726474226058316862">"Schema för Batterisparläge aktiverat"</string>
     <string name="auto_saver_enabled_text" msgid="874711029884777579">"Batterisparläget aktiveras automatiskt när batterinivån är under <xliff:g id="PERCENTAGE">%d</xliff:g> %%."</string>
@@ -942,4 +933,6 @@
     <string name="bubble_accessibility_action_move_bottom_left" msgid="206369104473183217">"Flytta längst ned till vänster"</string>
     <string name="bubble_accessibility_action_move_bottom_right" msgid="8705660152384312329">"Flytta längst ned till höger"</string>
     <string name="bubble_dismiss_text" msgid="8028337712674081668">"Stäng"</string>
+    <string name="notification_content_system_nav_changed" msgid="7218093915747788444">"Systemnavigeringen har uppdaterats. Öppna inställningarna om du vill ändra något."</string>
+    <string name="notification_content_gesture_nav_available" msgid="8111130443656460792">"Öppna inställningarna och uppdatera systemnavigeringen"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-sw/strings.xml b/packages/SystemUI/res/values-sw/strings.xml
index d91ba6d..0acb6018 100644
--- a/packages/SystemUI/res/values-sw/strings.xml
+++ b/packages/SystemUI/res/values-sw/strings.xml
@@ -62,12 +62,10 @@
     <string name="usb_debugging_secondary_user_title" msgid="6353808721761220421">"Utatuzi wa USB hauruhusiwi"</string>
     <string name="usb_debugging_secondary_user_message" msgid="6067122453571699801">"Mtumiaji aliyeingia katika akaunti kwa kutumia kifaa hiki kwa sasa hawezi kuwasha utatuzi wa USB. Ili utumie kipengele hiki, tumia akaunti ya mtumiaji wa msingi."</string>
     <string name="usb_contaminant_title" msgid="206854874263058490">"Mlango wa USB umezimwa"</string>
-    <!-- no translation found for usb_contaminant_message (7379089091591609111) -->
-    <skip />
+    <string name="usb_contaminant_message" msgid="7379089091591609111">"Ili ulinde kifaa chako dhidi ya vitu vyenye unyevu au uchafu, mlango wa USB umezimwa na hautatambua vifaa vyovyote.\n\nUtaarifiwa itapokuwa sawa kutumia mlango wa USB tena."</string>
     <string name="usb_port_enabled" msgid="7906141351687694867">"Mlango wa USB umewezeshwa ili utambue chaja na vifuasi"</string>
     <string name="usb_disable_contaminant_detection" msgid="2103905315747120033">"Washa kipengele cha USB"</string>
-    <!-- no translation found for learn_more (5000517160980853569) -->
-    <skip />
+    <string name="learn_more" msgid="5000517160980853569">"Pata maelezo zaidi"</string>
     <string name="compat_mode_on" msgid="6623839244840638213">"Kuza ili kujaza skrini"</string>
     <string name="compat_mode_off" msgid="4434467572461327898">"Tanua ili kujaza skrini"</string>
     <string name="global_action_screenshot" msgid="8329831278085426283">"Pichaskrini"</string>
@@ -199,6 +197,7 @@
     <string name="carrier_network_change_mode" msgid="8149202439957837762">"Mabadiliko katika mtandao wa mtoa huduma"</string>
     <string name="accessibility_battery_details" msgid="7645516654955025422">"Fungua maelezo ya betri"</string>
     <string name="accessibility_battery_level" msgid="7451474187113371965">"Asilimia <xliff:g id="NUMBER">%d</xliff:g> ya betri"</string>
+    <string name="accessibility_battery_level_with_estimate" msgid="9033100930684311630">"Betri ina asilimia <xliff:g id="PERCENTAGE">%1$s</xliff:g>, zimesalia takribani <xliff:g id="TIME">%2$s</xliff:g> kulingana na jinsi unavyoitumia"</string>
     <string name="accessibility_battery_level_charging" msgid="1147587904439319646">"Betri inachaji, asilimia <xliff:g id="BATTERY_PERCENTAGE">%d</xliff:g>."</string>
     <string name="accessibility_settings_button" msgid="799583911231893380">"Mipangilio ya mfumo."</string>
     <string name="accessibility_notifications_button" msgid="4498000369779421892">"Arifa."</string>
@@ -458,10 +457,8 @@
     <string name="media_projection_remember_text" msgid="3103510882172746752">"Usionyeshe tena"</string>
     <string name="clear_all_notifications_text" msgid="814192889771462828">"Futa zote"</string>
     <string name="manage_notifications_text" msgid="2386728145475108753">"Dhibiti"</string>
-    <!-- no translation found for notification_section_header_gentle (4372438504154095677) -->
-    <skip />
-    <!-- no translation found for accessibility_notification_section_header_gentle_clear_all (4286716295850400959) -->
-    <skip />
+    <string name="notification_section_header_gentle" msgid="4372438504154095677">"Arifa zisizo na sauti"</string>
+    <string name="accessibility_notification_section_header_gentle_clear_all" msgid="4286716295850400959">"Futa arifa zote zisizo na sauti"</string>
     <string name="dnd_suppressing_shade_text" msgid="1904574852846769301">"Kipengele cha Usinisumbue kimesitisha arifa"</string>
     <string name="media_projection_action_text" msgid="8470872969457985954">"Anza sasa"</string>
     <string name="empty_shade_text" msgid="708135716272867002">"Hakuna arifa"</string>
@@ -645,21 +642,16 @@
     <string name="inline_block_button" msgid="8735843688021655065">"Zuia"</string>
     <string name="inline_keep_button" msgid="6665940297019018232">"Endelea kuonyesha"</string>
     <string name="inline_minimize_button" msgid="966233327974702195">"Punguza"</string>
-    <!-- no translation found for inline_silent_button_silent (5315879183296940969) -->
-    <skip />
+    <string name="inline_silent_button_silent" msgid="5315879183296940969">"Kimya"</string>
     <string name="inline_silent_button_stay_silent" msgid="6308371431217601009">"Isitoe sauti"</string>
-    <!-- no translation found for inline_silent_button_alert (6008435419895088034) -->
-    <skip />
+    <string name="inline_silent_button_alert" msgid="6008435419895088034">"Kutoa arifa"</string>
     <string name="inline_silent_button_keep_alerting" msgid="327696842264359693">"Endelea kutoa arifa"</string>
     <string name="inline_turn_off_notifications" msgid="8635596135532202355">"Zima arifa"</string>
     <string name="inline_keep_showing_app" msgid="1723113469580031041">"Ungependa kuendelea kuonyesha arifa kutoka programu hii?"</string>
-    <string name="notification_silence_title" msgid="7352089096356977930">"Bila sauti"</string>
-    <string name="notification_alert_title" msgid="3966526305405016221">"Zilizopewa kipaumbele"</string>
-    <string name="notification_channel_summary_low" msgid="1065819618107531284">"Hukusaidia kuangazia arifa pekee kwenye orodha kunjuzi. Kimya kila wakati."</string>
-    <string name="notification_channel_summary_low_status" msgid="2702170424808743755">"Huonyeshwa chini ya arifa za kipaumbele. Kimya kila wakati."</string>
-    <string name="notification_channel_summary_low_lock" msgid="7966605244472624458">"Huonyeshwa chini ya arifa za kipaumbele. Kimya kila wakati."</string>
-    <string name="notification_channel_summary_low_status_lock" msgid="7012562768950012739">"Huonyeshwa chini ya arifa za kipaumbele. Kimya kila wakati."</string>
-    <string name="notification_channel_summary_default" msgid="3847289783382316019">"Hupata umakinifu wako kwa sauti na aikoni ya sehemu ya arifa. Huonyeshwa kwenye skrini iliyofungwa."</string>
+    <string name="notification_silence_title" msgid="5763240612242137433">"Kimya"</string>
+    <string name="notification_alert_title" msgid="8031196611815490340">"Kutoa arifa"</string>
+    <string name="notification_channel_summary_low" msgid="3387466082089715555">"Hukusaidia kuwa makini bila sauti au mtetemo."</string>
+    <string name="notification_channel_summary_default" msgid="5994062840431965586">"Hupata umakinifu wako kwa sauti na mtetemo."</string>
     <string name="notification_unblockable_desc" msgid="4556908766584964102">"Arifa hizi haziwezi kubadilishwa."</string>
     <string name="notification_multichannel_desc" msgid="4695920306092240550">"Kikundi hiki cha arifa hakiwezi kuwekewa mipangilio hapa"</string>
     <string name="notification_delegate_header" msgid="2857691673814814270">"Arifa wakilishi"</string>
@@ -908,8 +900,7 @@
     <string name="slice_permission_allow" msgid="2340244901366722709">"Ruhusu"</string>
     <string name="slice_permission_deny" msgid="7683681514008048807">"Kataa"</string>
     <string name="auto_saver_title" msgid="1217959994732964228">"Gusa ili uratibu wakati wa kuwasha Kiokoa Betri"</string>
-    <!-- no translation found for auto_saver_text (2563289953551438248) -->
-    <skip />
+    <string name="auto_saver_text" msgid="2563289953551438248">"Washa wakati betri inakaribia kuisha"</string>
     <string name="no_auto_saver_action" msgid="8086002101711328500">"Hapana, asante"</string>
     <string name="auto_saver_enabled_title" msgid="6726474226058316862">"Ratiba ya Kiokoa Betri imewashwa"</string>
     <string name="auto_saver_enabled_text" msgid="874711029884777579">"Kiokoa Betri kitawaka kiotomatiki baada ya chaji ya betri kufika chini ya <xliff:g id="PERCENTAGE">%d</xliff:g>%%."</string>
@@ -942,4 +933,6 @@
     <string name="bubble_accessibility_action_move_bottom_left" msgid="206369104473183217">"Sogeza chini kushoto"</string>
     <string name="bubble_accessibility_action_move_bottom_right" msgid="8705660152384312329">"Sogeza chini kulia"</string>
     <string name="bubble_dismiss_text" msgid="8028337712674081668">"Ondoa"</string>
+    <string name="notification_content_system_nav_changed" msgid="7218093915747788444">"Umesasisha usogezaji kwenye mfumo. Ili ufanye mabadiliko, nenda kwenye Mipangilio."</string>
+    <string name="notification_content_gesture_nav_available" msgid="8111130443656460792">"Nenda kwenye mipangilio ili usasishe usogezaji kwenye mfumo"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-ta/strings.xml b/packages/SystemUI/res/values-ta/strings.xml
index 172b62c..600c767 100644
--- a/packages/SystemUI/res/values-ta/strings.xml
+++ b/packages/SystemUI/res/values-ta/strings.xml
@@ -62,12 +62,10 @@
     <string name="usb_debugging_secondary_user_title" msgid="6353808721761220421">"USB பிழைதிருத்தம் அனுமதிக்கப்படவில்லை"</string>
     <string name="usb_debugging_secondary_user_message" msgid="6067122453571699801">"தற்போது இந்தச் சாதனத்தில் உள்நுழைந்துள்ள பயனரால் USB பிழைதிருத்தத்தை இயக்க முடியாது. இந்த அம்சத்தை இயக்க, முதன்மைப் பயனருக்கு மாறவும்."</string>
     <string name="usb_contaminant_title" msgid="206854874263058490">"USB போர்ட் முடக்கப்பட்டது"</string>
-    <!-- no translation found for usb_contaminant_message (7379089091591609111) -->
-    <skip />
+    <string name="usb_contaminant_message" msgid="7379089091591609111">"தேவையற்றவையில் இருந்து உங்கள் சாதனத்தைப் பாதுகாக்க USB போர்ட் முடக்கப்பட்டுள்ளது. மேலும் எந்தத் துணைக் கருவிகளையும் அது கண்டறியாது.\n\nUSB போர்ட்டை மீண்டும் எப்போது பயன்படுத்தலாம் என்பதைப் பற்றி உங்களுக்குத் தெரிவிக்கப்படும்."</string>
     <string name="usb_port_enabled" msgid="7906141351687694867">"சார்ஜர்களையும் துணைக்கருவிகளையும் கண்டறிவதற்காக USB போர்ட் இயக்கப்பட்டுள்ளது"</string>
     <string name="usb_disable_contaminant_detection" msgid="2103905315747120033">"USBயை இயக்கு"</string>
-    <!-- no translation found for learn_more (5000517160980853569) -->
-    <skip />
+    <string name="learn_more" msgid="5000517160980853569">"மேலும் அறிக"</string>
     <string name="compat_mode_on" msgid="6623839244840638213">"திரையை நிரப்ப அளவை மாற்று"</string>
     <string name="compat_mode_off" msgid="4434467572461327898">"திரையை நிரப்ப இழு"</string>
     <string name="global_action_screenshot" msgid="8329831278085426283">"ஸ்கிரீன்ஷாட்"</string>
@@ -199,6 +197,7 @@
     <string name="carrier_network_change_mode" msgid="8149202439957837762">"மொபைல் நிறுவன நெட்வொர்க்கை மாற்றும்"</string>
     <string name="accessibility_battery_details" msgid="7645516654955025422">"பேட்டரி விவரங்களைத் திறக்கும்"</string>
     <string name="accessibility_battery_level" msgid="7451474187113371965">"பேட்டரி சக்தி <xliff:g id="NUMBER">%d</xliff:g> சதவிகிதம் உள்ளது."</string>
+    <string name="accessibility_battery_level_with_estimate" msgid="9033100930684311630">"பேட்டரி: <xliff:g id="PERCENTAGE">%1$s</xliff:g> சதவீதம், உபயோகத்தின் அடிப்படையில் <xliff:g id="TIME">%2$s</xliff:g> மீதமுள்ளது"</string>
     <string name="accessibility_battery_level_charging" msgid="1147587904439319646">"பேட்டரி சார்ஜ் செய்யப்படுகிறது, <xliff:g id="BATTERY_PERCENTAGE">%d</xliff:g> சதவீதம்."</string>
     <string name="accessibility_settings_button" msgid="799583911231893380">"கணினி அமைப்பு."</string>
     <string name="accessibility_notifications_button" msgid="4498000369779421892">"அறிவிப்புகள்."</string>
@@ -458,10 +457,8 @@
     <string name="media_projection_remember_text" msgid="3103510882172746752">"மீண்டும் காட்டாதே"</string>
     <string name="clear_all_notifications_text" msgid="814192889771462828">"எல்லாவற்றையும் அழி"</string>
     <string name="manage_notifications_text" msgid="2386728145475108753">"அறிவிப்புகளை நிர்வகி"</string>
-    <!-- no translation found for notification_section_header_gentle (4372438504154095677) -->
-    <skip />
-    <!-- no translation found for accessibility_notification_section_header_gentle_clear_all (4286716295850400959) -->
-    <skip />
+    <string name="notification_section_header_gentle" msgid="4372438504154095677">"ஒலியில்லாத அறிவிப்புகள்"</string>
+    <string name="accessibility_notification_section_header_gentle_clear_all" msgid="4286716295850400959">"ஒலியில்லாத அழைப்புகள் அனைத்தையும் அழிக்கும்"</string>
     <string name="dnd_suppressing_shade_text" msgid="1904574852846769301">"\'தொந்தரவு செய்ய வேண்டாம்\' அம்சத்தின் மூலம் அறிவிப்புகள் இடைநிறுத்தப்பட்டுள்ளன"</string>
     <string name="media_projection_action_text" msgid="8470872969457985954">"இப்போது தொடங்கு"</string>
     <string name="empty_shade_text" msgid="708135716272867002">"அறிவிப்புகள் இல்லை"</string>
@@ -645,21 +642,16 @@
     <string name="inline_block_button" msgid="8735843688021655065">"தடு"</string>
     <string name="inline_keep_button" msgid="6665940297019018232">"அறிவிப்புகளைத் தொடர்ந்து காட்டு"</string>
     <string name="inline_minimize_button" msgid="966233327974702195">"சிறிதாக்கு"</string>
-    <!-- no translation found for inline_silent_button_silent (5315879183296940969) -->
-    <skip />
+    <string name="inline_silent_button_silent" msgid="5315879183296940969">"நிசப்தம்"</string>
     <string name="inline_silent_button_stay_silent" msgid="6308371431217601009">"அறிவிப்புகளை ஒலியின்றிக் காட்டு"</string>
-    <!-- no translation found for inline_silent_button_alert (6008435419895088034) -->
-    <skip />
+    <string name="inline_silent_button_alert" msgid="6008435419895088034">"விழிப்பூட்டல்"</string>
     <string name="inline_silent_button_keep_alerting" msgid="327696842264359693">"தொடர்ந்து விழிப்பூட்டு"</string>
     <string name="inline_turn_off_notifications" msgid="8635596135532202355">"அறிவிப்புகளை முடக்கு"</string>
     <string name="inline_keep_showing_app" msgid="1723113469580031041">"இந்த ஆப்ஸின் அறிவிப்புகளைத் தொடர்ந்து காட்டவா?"</string>
-    <string name="notification_silence_title" msgid="7352089096356977930">"ஜென்டில்"</string>
-    <string name="notification_alert_title" msgid="3966526305405016221">"முன்னுரிமைப்படுத்தப்பட்டது"</string>
-    <string name="notification_channel_summary_low" msgid="1065819618107531284">"கீழ் இழுக்கும் ஷேடில் வரும் அறிவிப்புகளில் மட்டும் கவனம் செலுத்த உதவுகிறது. எப்போதும் நிசப்தம்."</string>
-    <string name="notification_channel_summary_low_status" msgid="2702170424808743755">"குறைந்த முன்னுரிமைப் பெற்ற அறிவிப்புகளைக் காட்டும். எப்போதும் நிசப்தம்."</string>
-    <string name="notification_channel_summary_low_lock" msgid="7966605244472624458">"குறைந்த முன்னுரிமைப் பெற்ற அறிவிப்புகளைக் காட்டும். எப்போதும் நிசப்தம்."</string>
-    <string name="notification_channel_summary_low_status_lock" msgid="7012562768950012739">"குறைந்த முன்னுரிமைப் பெற்ற அறிவிப்புகளைக் காட்டும். எப்போதும் நிசப்தம்."</string>
-    <string name="notification_channel_summary_default" msgid="3847289783382316019">"ஒலி &amp; நிலைப் பட்டி ஐகான் மூலம் உங்கள் கவனத்தைப் பெறுகிறது. பூட்டுத் திரையில் காட்டும்."</string>
+    <string name="notification_silence_title" msgid="5763240612242137433">"நிசப்தம்"</string>
+    <string name="notification_alert_title" msgid="8031196611815490340">"விழிப்பூட்டல்"</string>
+    <string name="notification_channel_summary_low" msgid="3387466082089715555">"ஒலியோ அதிர்வோ இல்லாமல் முழு கவனம் செலுத்த உதவும்."</string>
+    <string name="notification_channel_summary_default" msgid="5994062840431965586">"ஒலியோ அதிர்வோ ஏற்படுத்தி உங்கள் கவனத்தை ஈர்க்கும்."</string>
     <string name="notification_unblockable_desc" msgid="4556908766584964102">"இந்த அறிவிப்புகளை மாற்ற இயலாது."</string>
     <string name="notification_multichannel_desc" msgid="4695920306092240550">"இந்த அறிவுப்புக் குழுக்களை இங்கே உள்ளமைக்க இயலாது"</string>
     <string name="notification_delegate_header" msgid="2857691673814814270">"ப்ராக்ஸியான அறிவிப்பு"</string>
@@ -908,8 +900,7 @@
     <string name="slice_permission_allow" msgid="2340244901366722709">"அனுமதி"</string>
     <string name="slice_permission_deny" msgid="7683681514008048807">"நிராகரி"</string>
     <string name="auto_saver_title" msgid="1217959994732964228">"பேட்டரி சேமிப்பானை ஆன் செய்வது தொடர்பாகத் திட்டமிட, தட்டவும்"</string>
-    <!-- no translation found for auto_saver_text (2563289953551438248) -->
-    <skip />
+    <string name="auto_saver_text" msgid="2563289953551438248">"பேட்டரி தீர்ந்துபோகும் நிலையில் இருக்கும் போது ஆன் செய்யப்படும்"</string>
     <string name="no_auto_saver_action" msgid="8086002101711328500">"வேண்டாம்"</string>
     <string name="auto_saver_enabled_title" msgid="6726474226058316862">"திட்டமிட்ட பேட்டரி சேமிப்பான் ஆன் செய்யப்பட்டது"</string>
     <string name="auto_saver_enabled_text" msgid="874711029884777579">"பேட்டரியின் அளவு <xliff:g id="PERCENTAGE">%d</xliff:g>%%க்குக் கீழ் குறையும்போது, பேட்டரி சேமிப்பான் தானாகவே ஆன் செய்யப்படும்."</string>
@@ -942,4 +933,6 @@
     <string name="bubble_accessibility_action_move_bottom_left" msgid="206369104473183217">"கீழே இடப்புறமாக நகர்த்து"</string>
     <string name="bubble_accessibility_action_move_bottom_right" msgid="8705660152384312329">"கீழே வலதுபுறமாக நகர்த்து"</string>
     <string name="bubble_dismiss_text" msgid="8028337712674081668">"மூடுக"</string>
+    <string name="notification_content_system_nav_changed" msgid="7218093915747788444">"சிஸ்டம் நேவிகேஷன் மாற்றப்பட்டது. மாற்றங்களைச் செய்ய ‘அமைப்புகளுக்குச்’ செல்லவும்."</string>
+    <string name="notification_content_gesture_nav_available" msgid="8111130443656460792">"சிஸ்டம் நேவிகேஷனை மாற்ற ’அமைப்புகளுக்குச்’ செல்லவும்"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-te/strings.xml b/packages/SystemUI/res/values-te/strings.xml
index 033fce4..d576475 100644
--- a/packages/SystemUI/res/values-te/strings.xml
+++ b/packages/SystemUI/res/values-te/strings.xml
@@ -62,12 +62,10 @@
     <string name="usb_debugging_secondary_user_title" msgid="6353808721761220421">"USB డీబగ్గింగ్‌కి అనుమతి లేదు"</string>
     <string name="usb_debugging_secondary_user_message" msgid="6067122453571699801">"ఈ పరికరానికి ప్రస్తుతం సైన్ ఇన్ చేసిన వినియోగదారు USB డీబగ్గింగ్ ఆన్ చేయలేరు. ఈ ఫీచర్ ఉపయోగించడానికి, ప్రాథమిక వినియోగదారుకి మారాలి."</string>
     <string name="usb_contaminant_title" msgid="206854874263058490">"USB పోర్ట్‌ నిలిపివేయబడింది"</string>
-    <!-- no translation found for usb_contaminant_message (7379089091591609111) -->
-    <skip />
+    <string name="usb_contaminant_message" msgid="7379089091591609111">"మీ పరికరంలోకి నీరు లేదా చెత్తాచెదారం చేరిపోకుండా కాపాడటానికి, USB పోర్ట్ నిలిపివేయబడుతుంది, అలాగే యాక్సెసరీలు వేటిని గుర్తించదు.\n\nUSB పోర్ట్‌ను ఉపయోగించడం సురక్షితమేనని నిర్ధారించుకున్న తర్వాత, మళ్లీ మీకో నోటిఫికేషన్‌ రూపంలో తెలియజేయబడుతుంది."</string>
     <string name="usb_port_enabled" msgid="7906141351687694867">"ఛార్జర్‌లు, యాక్సెసరీలను గుర్తించే విధంగా USB పోర్ట్ ప్రారంభించబడింది"</string>
     <string name="usb_disable_contaminant_detection" msgid="2103905315747120033">"USBని ప్రారంభించు"</string>
-    <!-- no translation found for learn_more (5000517160980853569) -->
-    <skip />
+    <string name="learn_more" msgid="5000517160980853569">"మరింత తెలుసుకోండి"</string>
     <string name="compat_mode_on" msgid="6623839244840638213">"స్క్రీన్‌కు నింపేలా జూమ్ చేయండి"</string>
     <string name="compat_mode_off" msgid="4434467572461327898">"స్క్రీన్‌కు నింపేలా విస్తరించండి"</string>
     <string name="global_action_screenshot" msgid="8329831278085426283">"స్క్రీన్‌షాట్"</string>
@@ -199,6 +197,7 @@
     <string name="carrier_network_change_mode" msgid="8149202439957837762">"క్యారియర్ నెట్‌వర్క్ మారుతోంది"</string>
     <string name="accessibility_battery_details" msgid="7645516654955025422">"బ్యాటరీ వివరాలను తెరుస్తుంది"</string>
     <string name="accessibility_battery_level" msgid="7451474187113371965">"బ్యాటరీ <xliff:g id="NUMBER">%d</xliff:g> శాతం."</string>
+    <string name="accessibility_battery_level_with_estimate" msgid="9033100930684311630">"బ్యాటరీ <xliff:g id="PERCENTAGE">%1$s</xliff:g> శాతం ఉంది, మీ వినియోగాన్ని బట్టి <xliff:g id="TIME">%2$s</xliff:g> పని చేస్తుంది"</string>
     <string name="accessibility_battery_level_charging" msgid="1147587904439319646">"బ్యాటరీ ఛార్జ్ అవుతోంది, <xliff:g id="BATTERY_PERCENTAGE">%d</xliff:g> %%."</string>
     <string name="accessibility_settings_button" msgid="799583911231893380">"సిస్టమ్ సెట్టింగ్‌లు."</string>
     <string name="accessibility_notifications_button" msgid="4498000369779421892">"నోటిఫికేషన్‌లు."</string>
@@ -458,10 +457,8 @@
     <string name="media_projection_remember_text" msgid="3103510882172746752">"మళ్లీ చూపవద్దు"</string>
     <string name="clear_all_notifications_text" msgid="814192889771462828">"అన్నీ క్లియర్ చేయండి"</string>
     <string name="manage_notifications_text" msgid="2386728145475108753">"నిర్వహించండి"</string>
-    <!-- no translation found for notification_section_header_gentle (4372438504154095677) -->
-    <skip />
-    <!-- no translation found for accessibility_notification_section_header_gentle_clear_all (4286716295850400959) -->
-    <skip />
+    <string name="notification_section_header_gentle" msgid="4372438504154095677">"నిశ్శబ్ద నోటిఫికేషన్‌లు"</string>
+    <string name="accessibility_notification_section_header_gentle_clear_all" msgid="4286716295850400959">"అన్ని నిశ్శబ్ద నోటిఫికేషన్‌లను క్లియర్ చేస్తుంది"</string>
     <string name="dnd_suppressing_shade_text" msgid="1904574852846769301">"అంతరాయం కలిగించవద్దు ద్వారా నోటిఫికేషన్‌లు పాజ్ చేయబడ్డాయి"</string>
     <string name="media_projection_action_text" msgid="8470872969457985954">"ఇప్పుడే ప్రారంభించు"</string>
     <string name="empty_shade_text" msgid="708135716272867002">"నోటిఫికేషన్‌లు లేవు"</string>
@@ -645,21 +642,16 @@
     <string name="inline_block_button" msgid="8735843688021655065">"బ్లాక్ చేయి"</string>
     <string name="inline_keep_button" msgid="6665940297019018232">"చూపిస్తూనే ఉండు"</string>
     <string name="inline_minimize_button" msgid="966233327974702195">"కుదించు"</string>
-    <!-- no translation found for inline_silent_button_silent (5315879183296940969) -->
-    <skip />
+    <string name="inline_silent_button_silent" msgid="5315879183296940969">"నిశ్శబ్దం"</string>
     <string name="inline_silent_button_stay_silent" msgid="6308371431217601009">"నిశబ్దంగా తెలియజేయి"</string>
-    <!-- no translation found for inline_silent_button_alert (6008435419895088034) -->
-    <skip />
+    <string name="inline_silent_button_alert" msgid="6008435419895088034">"హెచ్చరించడం"</string>
     <string name="inline_silent_button_keep_alerting" msgid="327696842264359693">"ఎప్పటికప్పుడు హెచ్చరించు"</string>
     <string name="inline_turn_off_notifications" msgid="8635596135532202355">"నోటిఫికేషన్‌లను ఆఫ్ చేయి"</string>
     <string name="inline_keep_showing_app" msgid="1723113469580031041">"ఈ యాప్ నుండి నోటిఫికేషన్‌లను చూపిస్తూ ఉండాలా?"</string>
-    <string name="notification_silence_title" msgid="7352089096356977930">"సాధారణ"</string>
-    <string name="notification_alert_title" msgid="3966526305405016221">"ప్రాధాన్యం గలవి"</string>
-    <string name="notification_channel_summary_low" msgid="1065819618107531284">"కిందకు-లాగే షేడ్‌లో కనిపించే నోటిఫికేషన్‌ల మాత్రమే ద్వారా దృష్టి కేంద్రీకరించడానికి మీకు సహాయపడుతుంది. ఎల్లప్పుడూ నిశబ్దంగా ఉంచు."</string>
-    <string name="notification_channel_summary_low_status" msgid="2702170424808743755">"ప్రాధాన్యత గల నోటిఫికేషన్‌ల దిగువన ప్రదర్శిస్తుంది. ఎల్లప్పుడూ నిశబ్దంగా ఉంచు."</string>
-    <string name="notification_channel_summary_low_lock" msgid="7966605244472624458">"ప్రాధాన్యత గల నోటిఫికేషన్‌ల దిగువన ప్రదర్శిస్తుంది. ఎల్లప్పుడూ నిశబ్దంగా ఉంచు."</string>
-    <string name="notification_channel_summary_low_status_lock" msgid="7012562768950012739">"ప్రాధాన్యత గల నోటిఫికేషన్‌ల దిగువన ప్రదర్శిస్తుంది. ఎల్లప్పుడూ నిశబ్దంగా ఉంచు."</string>
-    <string name="notification_channel_summary_default" msgid="3847289783382316019">"శబ్దం &amp; స్టేటస్ బార్ చిహ్నం ద్వారా మీరు దృష్టి సారించేలా చేస్తుంది. లాక్ స్క్రీన్‌‌పై చూపుతుంది."</string>
+    <string name="notification_silence_title" msgid="5763240612242137433">"నిశ్శబ్దం"</string>
+    <string name="notification_alert_title" msgid="8031196611815490340">"హెచ్చరించడం"</string>
+    <string name="notification_channel_summary_low" msgid="3387466082089715555">"శబ్దం లేదా వైబ్రేషన్ లేకుండా దృష్టి కేంద్రీకరించడానికి మీకు సహాయపడుతుంది."</string>
+    <string name="notification_channel_summary_default" msgid="5994062840431965586">"శబ్దం లేదా వైబ్రేషన్‌తో మీరు దృష్టి సారించేలా చేస్తుంది."</string>
     <string name="notification_unblockable_desc" msgid="4556908766584964102">"ఈ నోటిఫికేషన్‌లను సవరించడం వీలుపడదు."</string>
     <string name="notification_multichannel_desc" msgid="4695920306092240550">"ఈ నోటిఫికేషన్‌ల సమూహాన్ని ఇక్కడ కాన్ఫిగర్ చేయలేము"</string>
     <string name="notification_delegate_header" msgid="2857691673814814270">"ప్రాక్సీ చేయబడిన నోటిఫికేషన్"</string>
@@ -908,8 +900,7 @@
     <string name="slice_permission_allow" msgid="2340244901366722709">"అనుమతించు"</string>
     <string name="slice_permission_deny" msgid="7683681514008048807">"తిరస్కరించు"</string>
     <string name="auto_saver_title" msgid="1217959994732964228">"బ్యాటరీ సేవర్‌ని షెడ్యూల్ చేయడానికి నొక్కండి"</string>
-    <!-- no translation found for auto_saver_text (2563289953551438248) -->
-    <skip />
+    <string name="auto_saver_text" msgid="2563289953551438248">"బ్యాటరీ ఛార్జింగ్ పూర్తిగా అయిపోతున్న తరుణంలో ఆన్ చేస్తుంది"</string>
     <string name="no_auto_saver_action" msgid="8086002101711328500">"వద్దు, ధన్యవాదాలు"</string>
     <string name="auto_saver_enabled_title" msgid="6726474226058316862">"బ్యాటరీ సేవర్ షెడ్యూల్ ఆన్ చేయబడింది"</string>
     <string name="auto_saver_enabled_text" msgid="874711029884777579">"బ్యాటరీ <xliff:g id="PERCENTAGE">%d</xliff:g>%% కంటే తగ్గినప్పుడు బ్యాటరీ సేవర్ ఆటోమేటిక్‌గా ఆన్ అవుతుంది."</string>
@@ -942,4 +933,6 @@
     <string name="bubble_accessibility_action_move_bottom_left" msgid="206369104473183217">"దిగువ ఎడమవైపునకు తరలించు"</string>
     <string name="bubble_accessibility_action_move_bottom_right" msgid="8705660152384312329">"దిగవు కుడివైపునకు జరుపు"</string>
     <string name="bubble_dismiss_text" msgid="8028337712674081668">"విస్మరించు"</string>
+    <string name="notification_content_system_nav_changed" msgid="7218093915747788444">"సిస్టమ్ నావిగేషన్ అప్‌డేట్ చేయబడింది. మార్పులు చేయడానికి, సెట్టింగ్‌లకు వెళ్లండి."</string>
+    <string name="notification_content_gesture_nav_available" msgid="8111130443656460792">"సిస్టమ్ నావిగేషన్‌ను అప్‌డేట్ చేయడానికి సెట్టింగ్‌లకు వెళ్లండి"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-th/strings.xml b/packages/SystemUI/res/values-th/strings.xml
index 465a2b8..81c6e0d 100644
--- a/packages/SystemUI/res/values-th/strings.xml
+++ b/packages/SystemUI/res/values-th/strings.xml
@@ -62,12 +62,10 @@
     <string name="usb_debugging_secondary_user_title" msgid="6353808721761220421">"ไม่อนุญาตให้แก้ไขข้อบกพร่องผ่าน USB"</string>
     <string name="usb_debugging_secondary_user_message" msgid="6067122453571699801">"ผู้ใช้ที่ลงชื่อเข้าใช้อุปกรณ์อยู่ในขณะนี้ไม่สามารถเปิดการแก้ไขข้อบกพร่องผ่าน USB ได้ หากต้องการใช้ฟีเจอร์นี้ ให้เปลี่ยนไปเป็นผู้ใช้หลัก"</string>
     <string name="usb_contaminant_title" msgid="206854874263058490">"พอร์ต USB ถูกปิดใช้"</string>
-    <!-- no translation found for usb_contaminant_message (7379089091591609111) -->
-    <skip />
+    <string name="usb_contaminant_message" msgid="7379089091591609111">"พอร์ต USB ปิดใช้อยู่และจะไม่ตรวจหาอุปกรณ์เสริมใดๆ เพื่อปกป้องอุปกรณ์จากของเหลวและฝุ่นละออง \n\nคุณจะได้รับแจ้งเมื่อใช้พอร์ต USB ได้อีกครั้ง"</string>
     <string name="usb_port_enabled" msgid="7906141351687694867">"เปิดใช้พอร์ต USB แล้วเพื่อตรวจหาที่ชาร์จและอุปกรณ์เสริม"</string>
     <string name="usb_disable_contaminant_detection" msgid="2103905315747120033">"เปิดใช้ USB"</string>
-    <!-- no translation found for learn_more (5000517160980853569) -->
-    <skip />
+    <string name="learn_more" msgid="5000517160980853569">"ดูข้อมูลเพิ่มเติม"</string>
     <string name="compat_mode_on" msgid="6623839244840638213">"ขยายจนเต็มหน้าจอ"</string>
     <string name="compat_mode_off" msgid="4434467572461327898">"ยืดจนเต็มหน้าจอ"</string>
     <string name="global_action_screenshot" msgid="8329831278085426283">"ภาพหน้าจอ"</string>
@@ -199,6 +197,7 @@
     <string name="carrier_network_change_mode" msgid="8149202439957837762">"การเปลี่ยนเครือข่ายผู้ให้บริการ"</string>
     <string name="accessibility_battery_details" msgid="7645516654955025422">"เปิดรายละเอียดแบตเตอรี่"</string>
     <string name="accessibility_battery_level" msgid="7451474187113371965">"แบตเตอรี่ <xliff:g id="NUMBER">%d</xliff:g> เปอร์เซ็นต์"</string>
+    <string name="accessibility_battery_level_with_estimate" msgid="9033100930684311630">"แบตเตอรี่ <xliff:g id="PERCENTAGE">%1$s</xliff:g> เปอร์เซ็นต์ ใช้ได้อีกประมาณ <xliff:g id="TIME">%2$s</xliff:g> ทั้งนี้ขึ้นอยู่กับการใช้งานของคุณ"</string>
     <string name="accessibility_battery_level_charging" msgid="1147587904439319646">"กำลังชาร์จแบตเตอรี่ <xliff:g id="BATTERY_PERCENTAGE">%d</xliff:g> เปอร์เซ็นต์"</string>
     <string name="accessibility_settings_button" msgid="799583911231893380">"การตั้งค่าระบบ"</string>
     <string name="accessibility_notifications_button" msgid="4498000369779421892">"การแจ้งเตือน"</string>
@@ -458,10 +457,8 @@
     <string name="media_projection_remember_text" msgid="3103510882172746752">"ไม่ต้องแสดงข้อความนี้อีก"</string>
     <string name="clear_all_notifications_text" msgid="814192889771462828">"ล้างทั้งหมด"</string>
     <string name="manage_notifications_text" msgid="2386728145475108753">"จัดการ"</string>
-    <!-- no translation found for notification_section_header_gentle (4372438504154095677) -->
-    <skip />
-    <!-- no translation found for accessibility_notification_section_header_gentle_clear_all (4286716295850400959) -->
-    <skip />
+    <string name="notification_section_header_gentle" msgid="4372438504154095677">"การแจ้งเตือนแบบไม่มีเสียง"</string>
+    <string name="accessibility_notification_section_header_gentle_clear_all" msgid="4286716295850400959">"ล้างการแจ้งเตือนแบบไม่มีเสียงทั้งหมด"</string>
     <string name="dnd_suppressing_shade_text" msgid="1904574852846769301">"หยุดการแจ้งเตือนชั่วคราวโดย \"ห้ามรบกวน\""</string>
     <string name="media_projection_action_text" msgid="8470872969457985954">"เริ่มเลย"</string>
     <string name="empty_shade_text" msgid="708135716272867002">"ไม่มีการแจ้งเตือน"</string>
@@ -645,21 +642,16 @@
     <string name="inline_block_button" msgid="8735843688021655065">"บล็อก"</string>
     <string name="inline_keep_button" msgid="6665940297019018232">"แสดงต่อไป"</string>
     <string name="inline_minimize_button" msgid="966233327974702195">"ย่อเล็กสุด"</string>
-    <!-- no translation found for inline_silent_button_silent (5315879183296940969) -->
-    <skip />
+    <string name="inline_silent_button_silent" msgid="5315879183296940969">"ปิดเสียง"</string>
     <string name="inline_silent_button_stay_silent" msgid="6308371431217601009">"ปิดเสียงไว้"</string>
-    <!-- no translation found for inline_silent_button_alert (6008435419895088034) -->
-    <skip />
+    <string name="inline_silent_button_alert" msgid="6008435419895088034">"แจ้งเตือน"</string>
     <string name="inline_silent_button_keep_alerting" msgid="327696842264359693">"แจ้งเตือนต่อไป"</string>
     <string name="inline_turn_off_notifications" msgid="8635596135532202355">"ปิดการแจ้งเตือน"</string>
     <string name="inline_keep_showing_app" msgid="1723113469580031041">"แสดงการแจ้งเตือนจากแอปนี้ต่อไปไหม"</string>
-    <string name="notification_silence_title" msgid="7352089096356977930">"แจ้งเตือนเบาๆ"</string>
-    <string name="notification_alert_title" msgid="3966526305405016221">"สำคัญ"</string>
-    <string name="notification_channel_summary_low" msgid="1065819618107531284">"ช่วยให้คุณโฟกัสกับการแจ้งเตือนในหน้าต่างแบบเลื่อนลงเท่านั้น ปิดเสียงตลอดเวลา"</string>
-    <string name="notification_channel_summary_low_status" msgid="2702170424808743755">"แสดงใต้การแจ้งเตือนเรื่องสำคัญ ปิดเสียงตลอดเวลา"</string>
-    <string name="notification_channel_summary_low_lock" msgid="7966605244472624458">"แสดงใต้การแจ้งเตือนเรื่องสำคัญ ปิดเสียงตลอดเวลา"</string>
-    <string name="notification_channel_summary_low_status_lock" msgid="7012562768950012739">"แสดงใต้การแจ้งเตือนเรื่องสำคัญ ปิดเสียงตลอดเวลา"</string>
-    <string name="notification_channel_summary_default" msgid="3847289783382316019">"ดึงความสนใจของคุณด้วยเสียงและไอคอนในแถบสถานะ แสดงในหน้าจอล็อก"</string>
+    <string name="notification_silence_title" msgid="5763240612242137433">"เงียบ"</string>
+    <string name="notification_alert_title" msgid="8031196611815490340">"แจ้งเตือน"</string>
+    <string name="notification_channel_summary_low" msgid="3387466082089715555">"ช่วยรักษาสมาธิของคุณด้วยการไม่ส่งเสียงหรือสั่น"</string>
+    <string name="notification_channel_summary_default" msgid="5994062840431965586">"ดึงความสนใจของคุณด้วยเสียงและการสั่น"</string>
     <string name="notification_unblockable_desc" msgid="4556908766584964102">"แก้ไขการแจ้งเตือนเหล่านี้ไม่ได้"</string>
     <string name="notification_multichannel_desc" msgid="4695920306092240550">"การแจ้งเตือนกลุ่มนี้กำหนดค่าที่นี่ไม่ได้"</string>
     <string name="notification_delegate_header" msgid="2857691673814814270">"การแจ้งเตือนที่ผ่านพร็อกซี"</string>
@@ -908,8 +900,7 @@
     <string name="slice_permission_allow" msgid="2340244901366722709">"อนุญาต"</string>
     <string name="slice_permission_deny" msgid="7683681514008048807">"ปฏิเสธ"</string>
     <string name="auto_saver_title" msgid="1217959994732964228">"แตะเพื่อตั้งเวลาโหมดประหยัดแบตเตอรี่"</string>
-    <!-- no translation found for auto_saver_text (2563289953551438248) -->
-    <skip />
+    <string name="auto_saver_text" msgid="2563289953551438248">"เปิดเมื่อมีแนวโน้มว่าแบตเตอรี่จะหมด"</string>
     <string name="no_auto_saver_action" msgid="8086002101711328500">"ไม่เป็นไร"</string>
     <string name="auto_saver_enabled_title" msgid="6726474226058316862">"เปิดใช้กำหนดเวลาโหมดประหยัดแบตเตอรี่อยู่"</string>
     <string name="auto_saver_enabled_text" msgid="874711029884777579">"โหมดประหยัดแบตเตอรี่จะเปิดโดยอัตโนมัติเมื่อแบตเตอรี่เหลือไม่ถึง <xliff:g id="PERCENTAGE">%d</xliff:g>%%"</string>
@@ -942,4 +933,6 @@
     <string name="bubble_accessibility_action_move_bottom_left" msgid="206369104473183217">"ย้ายไปด้านซ้ายล่าง"</string>
     <string name="bubble_accessibility_action_move_bottom_right" msgid="8705660152384312329">"ย้ายไปด้านขาวล่าง"</string>
     <string name="bubble_dismiss_text" msgid="8028337712674081668">"ปิด"</string>
+    <string name="notification_content_system_nav_changed" msgid="7218093915747788444">"อัปเดตการไปยังส่วนต่างๆ ของระบบแล้ว หากต้องการเปลี่ยนแปลง ให้ไปที่การตั้งค่า"</string>
+    <string name="notification_content_gesture_nav_available" msgid="8111130443656460792">"ไปที่การตั้งค่าเพื่ออัปเดตการไปยังส่วนต่างๆ ของระบบ"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-tl/strings.xml b/packages/SystemUI/res/values-tl/strings.xml
index 8a832b0..f89061e 100644
--- a/packages/SystemUI/res/values-tl/strings.xml
+++ b/packages/SystemUI/res/values-tl/strings.xml
@@ -62,12 +62,10 @@
     <string name="usb_debugging_secondary_user_title" msgid="6353808721761220421">"Hindi pinapayagan ang pagde-debug sa pamamagitan ng USB"</string>
     <string name="usb_debugging_secondary_user_message" msgid="6067122453571699801">"Hindi mao-on ng user na kasalukuyang naka-sign in sa device na ito ang pag-debug ng USB. Upang magamit ang feature na ito, lumipat sa pangunahing user."</string>
     <string name="usb_contaminant_title" msgid="206854874263058490">"Na-disable ang USB port"</string>
-    <!-- no translation found for usb_contaminant_message (7379089091591609111) -->
-    <skip />
+    <string name="usb_contaminant_message" msgid="7379089091591609111">"Para protektahan ang iyong device sa likido o dumi, na-disable ang USB port at hindi ito makaka-detect ng anumang accessory.\n\nAabisuhan ka kapag ayos nang gamitin ulit ang USB port."</string>
     <string name="usb_port_enabled" msgid="7906141351687694867">"Na-enable ang USB port para ma-detect ang mga charger at accessory"</string>
     <string name="usb_disable_contaminant_detection" msgid="2103905315747120033">"I-enable ang USB"</string>
-    <!-- no translation found for learn_more (5000517160980853569) -->
-    <skip />
+    <string name="learn_more" msgid="5000517160980853569">"Matuto pa"</string>
     <string name="compat_mode_on" msgid="6623839244840638213">"I-zoom upang punan screen"</string>
     <string name="compat_mode_off" msgid="4434467572461327898">"I-stretch upang mapuno screen"</string>
     <string name="global_action_screenshot" msgid="8329831278085426283">"Screenshot"</string>
@@ -199,6 +197,7 @@
     <string name="carrier_network_change_mode" msgid="8149202439957837762">"Nagpapalit ng carrier network"</string>
     <string name="accessibility_battery_details" msgid="7645516654955025422">"Buksan ang mga detalye ng baterya"</string>
     <string name="accessibility_battery_level" msgid="7451474187113371965">"Baterya <xliff:g id="NUMBER">%d</xliff:g> (na) porsyento."</string>
+    <string name="accessibility_battery_level_with_estimate" msgid="9033100930684311630">"<xliff:g id="PERCENTAGE">%1$s</xliff:g> (na) porsyento ang baterya, nasa <xliff:g id="TIME">%2$s</xliff:g> ang natitira batay sa paggamit mo"</string>
     <string name="accessibility_battery_level_charging" msgid="1147587904439319646">"Nagcha-charge ang baterya, <xliff:g id="BATTERY_PERCENTAGE">%d</xliff:g> (na) porsyento."</string>
     <string name="accessibility_settings_button" msgid="799583911231893380">"Mga setting ng system."</string>
     <string name="accessibility_notifications_button" msgid="4498000369779421892">"Mga Notification."</string>
@@ -458,10 +457,8 @@
     <string name="media_projection_remember_text" msgid="3103510882172746752">"Huwag ipakitang muli"</string>
     <string name="clear_all_notifications_text" msgid="814192889771462828">"I-clear lahat"</string>
     <string name="manage_notifications_text" msgid="2386728145475108753">"Pamahalaan"</string>
-    <!-- no translation found for notification_section_header_gentle (4372438504154095677) -->
-    <skip />
-    <!-- no translation found for accessibility_notification_section_header_gentle_clear_all (4286716295850400959) -->
-    <skip />
+    <string name="notification_section_header_gentle" msgid="4372438504154095677">"Mga silent na notification"</string>
+    <string name="accessibility_notification_section_header_gentle_clear_all" msgid="4286716295850400959">"I-clear ang lahat ng silent na notification"</string>
     <string name="dnd_suppressing_shade_text" msgid="1904574852846769301">"Mga notification na na-pause ng Huwag Istorbohin"</string>
     <string name="media_projection_action_text" msgid="8470872969457985954">"Magsimula ngayon"</string>
     <string name="empty_shade_text" msgid="708135716272867002">"Walang mga notification"</string>
@@ -645,21 +642,16 @@
     <string name="inline_block_button" msgid="8735843688021655065">"I-block"</string>
     <string name="inline_keep_button" msgid="6665940297019018232">"Patuloy na ipakita"</string>
     <string name="inline_minimize_button" msgid="966233327974702195">"I-minimize"</string>
-    <!-- no translation found for inline_silent_button_silent (5315879183296940969) -->
-    <skip />
+    <string name="inline_silent_button_silent" msgid="5315879183296940969">"Silent"</string>
     <string name="inline_silent_button_stay_silent" msgid="6308371431217601009">"Manatiling naka-silent"</string>
-    <!-- no translation found for inline_silent_button_alert (6008435419895088034) -->
-    <skip />
+    <string name="inline_silent_button_alert" msgid="6008435419895088034">"Mag-alerto"</string>
     <string name="inline_silent_button_keep_alerting" msgid="327696842264359693">"Patuloy na mag-alerto"</string>
     <string name="inline_turn_off_notifications" msgid="8635596135532202355">"I-off ang mga notification"</string>
     <string name="inline_keep_showing_app" msgid="1723113469580031041">"Patuloy na ipakita ang mga notification mula sa app na ito?"</string>
-    <string name="notification_silence_title" msgid="7352089096356977930">"Malumanay"</string>
-    <string name="notification_alert_title" msgid="3966526305405016221">"Priyoridad"</string>
-    <string name="notification_channel_summary_low" msgid="1065819618107531284">"Nakakatulong para hindi ka maabala dahil sa pull-down na shade lang lalabas ang mga notification. Palaging naka-silent."</string>
-    <string name="notification_channel_summary_low_status" msgid="2702170424808743755">"Ipinapakita sa ibaba ng mga priyoridad na notification. Palaging naka-silent."</string>
-    <string name="notification_channel_summary_low_lock" msgid="7966605244472624458">"Ipinapakita sa ibaba ng mga priyoridad na notification. Palaging naka-silent."</string>
-    <string name="notification_channel_summary_low_status_lock" msgid="7012562768950012739">"Ipinapakita sa ibaba ng mga priyoridad na notification. Palaging naka-silent."</string>
-    <string name="notification_channel_summary_default" msgid="3847289783382316019">"Kinukuha ang iyong atensyon gamit ang tunog at icon sa status bar. Ipinapakita sa lock screen."</string>
+    <string name="notification_silence_title" msgid="5763240612242137433">"Naka-silent"</string>
+    <string name="notification_alert_title" msgid="8031196611815490340">"Mag-alerto"</string>
+    <string name="notification_channel_summary_low" msgid="3387466082089715555">"Nakakatulong sa iyong tumuon nang walang tunog o pag-vibrate."</string>
+    <string name="notification_channel_summary_default" msgid="5994062840431965586">"Kinukuha ang iyong atensyon sa pamamagitan ng tunog o pag-vibrate."</string>
     <string name="notification_unblockable_desc" msgid="4556908766584964102">"Hindi puwedeng baguhin ang mga notification na ito."</string>
     <string name="notification_multichannel_desc" msgid="4695920306092240550">"Hindi mako-configure dito ang pangkat na ito ng mga notification"</string>
     <string name="notification_delegate_header" msgid="2857691673814814270">"Na-proxy na notification"</string>
@@ -908,8 +900,7 @@
     <string name="slice_permission_allow" msgid="2340244901366722709">"Payagan"</string>
     <string name="slice_permission_deny" msgid="7683681514008048807">"Tanggihan"</string>
     <string name="auto_saver_title" msgid="1217959994732964228">"I-tap para iiskedyul ang Pangtipid sa Baterya"</string>
-    <!-- no translation found for auto_saver_text (2563289953551438248) -->
-    <skip />
+    <string name="auto_saver_text" msgid="2563289953551438248">"I-on kapag malamang na maubos ang baterya"</string>
     <string name="no_auto_saver_action" msgid="8086002101711328500">"Hindi, salamat na lang"</string>
     <string name="auto_saver_enabled_title" msgid="6726474226058316862">"Na-on ang iskedyul ng Pangtipid sa Baterya"</string>
     <string name="auto_saver_enabled_text" msgid="874711029884777579">"Awtomatikong mao-on ang Pangtipid sa Baterya kapag mas mababa na sa <xliff:g id="PERCENTAGE">%d</xliff:g>%% ang baterya."</string>
@@ -942,4 +933,6 @@
     <string name="bubble_accessibility_action_move_bottom_left" msgid="206369104473183217">"Ilipat sa kaliwa sa ibaba"</string>
     <string name="bubble_accessibility_action_move_bottom_right" msgid="8705660152384312329">"Ilipat sa kanan sa ibaba"</string>
     <string name="bubble_dismiss_text" msgid="8028337712674081668">"I-dismiss"</string>
+    <string name="notification_content_system_nav_changed" msgid="7218093915747788444">"Na-update na ang pag-navigate ng system. Para gumawa ng mga pagbabago, pumunta sa Mga Setting."</string>
+    <string name="notification_content_gesture_nav_available" msgid="8111130443656460792">"Pumunta sa Mga Setting para i-update ang pag-navigate sa system"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-tr/strings.xml b/packages/SystemUI/res/values-tr/strings.xml
index c91b551..63d9f10 100644
--- a/packages/SystemUI/res/values-tr/strings.xml
+++ b/packages/SystemUI/res/values-tr/strings.xml
@@ -62,12 +62,10 @@
     <string name="usb_debugging_secondary_user_title" msgid="6353808721761220421">"USB hata ayıklama işlevine izin verilmiyor"</string>
     <string name="usb_debugging_secondary_user_message" msgid="6067122453571699801">"Bu cihazda geçerli olarak oturum açmış olan kullanıcı, USB hata ayıklama özelliğini açamaz. Bu özelliği kullanmak için birincil kullanıcıya geçin."</string>
     <string name="usb_contaminant_title" msgid="206854874263058490">"USB bağlantı noktası devre dışı bırakıldı"</string>
-    <!-- no translation found for usb_contaminant_message (7379089091591609111) -->
-    <skip />
+    <string name="usb_contaminant_message" msgid="7379089091591609111">"Cihazınızı sıvılardan veya tozlardan korumak için USB bağlantı noktası devre dışı bırakıldı ve aksesuarları algılamayacak.\n\nUSB bağlantı noktasını tekrar sorunsuz kullanabileceğiniz zaman bilgilendirileceksiniz."</string>
     <string name="usb_port_enabled" msgid="7906141351687694867">"USB bağlantı noktası, şarj cihazlarını ve aksesuarları algılamak üzere etkinleştirildi"</string>
     <string name="usb_disable_contaminant_detection" msgid="2103905315747120033">"USB\'yi etkinleştir"</string>
-    <!-- no translation found for learn_more (5000517160980853569) -->
-    <skip />
+    <string name="learn_more" msgid="5000517160980853569">"Daha fazla bilgi"</string>
     <string name="compat_mode_on" msgid="6623839244840638213">"Yakınlaştır (ekranı kaplasın)"</string>
     <string name="compat_mode_off" msgid="4434467572461327898">"Genişlet (ekran kapansın)"</string>
     <string name="global_action_screenshot" msgid="8329831278085426283">"Ekran görüntüsü"</string>
@@ -199,6 +197,7 @@
     <string name="carrier_network_change_mode" msgid="8149202439957837762">"Operatör ağı değiştiriliyor"</string>
     <string name="accessibility_battery_details" msgid="7645516654955025422">"Pil ayrıntılarını aç"</string>
     <string name="accessibility_battery_level" msgid="7451474187113371965">"Pil yüzdesi: <xliff:g id="NUMBER">%d</xliff:g>"</string>
+    <string name="accessibility_battery_level_with_estimate" msgid="9033100930684311630">"Pil yüzde <xliff:g id="PERCENTAGE">%1$s</xliff:g> dolu. Kullanımınıza göre yaklaşık <xliff:g id="TIME">%2$s</xliff:g> süresi kaldı"</string>
     <string name="accessibility_battery_level_charging" msgid="1147587904439319646">"Pil şarj oluyor, yüzde <xliff:g id="BATTERY_PERCENTAGE">%d</xliff:g>."</string>
     <string name="accessibility_settings_button" msgid="799583911231893380">"Sistem ayarları."</string>
     <string name="accessibility_notifications_button" msgid="4498000369779421892">"Bildirimler."</string>
@@ -458,10 +457,8 @@
     <string name="media_projection_remember_text" msgid="3103510882172746752">"Bir daha gösterme"</string>
     <string name="clear_all_notifications_text" msgid="814192889771462828">"Tümünü temizle"</string>
     <string name="manage_notifications_text" msgid="2386728145475108753">"Yönet"</string>
-    <!-- no translation found for notification_section_header_gentle (4372438504154095677) -->
-    <skip />
-    <!-- no translation found for accessibility_notification_section_header_gentle_clear_all (4286716295850400959) -->
-    <skip />
+    <string name="notification_section_header_gentle" msgid="4372438504154095677">"Sessiz bildirimler"</string>
+    <string name="accessibility_notification_section_header_gentle_clear_all" msgid="4286716295850400959">"Sessiz bildirimlerin tümünü temizle"</string>
     <string name="dnd_suppressing_shade_text" msgid="1904574852846769301">"Bildirimler, Rahatsız Etmeyin özelliği tarafından duraklatıldı"</string>
     <string name="media_projection_action_text" msgid="8470872969457985954">"Şimdi başlat"</string>
     <string name="empty_shade_text" msgid="708135716272867002">"Bildirim yok"</string>
@@ -645,21 +642,16 @@
     <string name="inline_block_button" msgid="8735843688021655065">"Engelle"</string>
     <string name="inline_keep_button" msgid="6665940297019018232">"Göstermeye devam et"</string>
     <string name="inline_minimize_button" msgid="966233327974702195">"Küçült"</string>
-    <!-- no translation found for inline_silent_button_silent (5315879183296940969) -->
-    <skip />
+    <string name="inline_silent_button_silent" msgid="5315879183296940969">"Sessiz"</string>
     <string name="inline_silent_button_stay_silent" msgid="6308371431217601009">"Sessiz uyarı göster"</string>
-    <!-- no translation found for inline_silent_button_alert (6008435419895088034) -->
-    <skip />
+    <string name="inline_silent_button_alert" msgid="6008435419895088034">"Uyarı"</string>
     <string name="inline_silent_button_keep_alerting" msgid="327696842264359693">"Uyarıda bulunmaya devam et"</string>
     <string name="inline_turn_off_notifications" msgid="8635596135532202355">"Bildirimleri kapat"</string>
     <string name="inline_keep_showing_app" msgid="1723113469580031041">"Bu uygulamadan gelen bildirimler gösterilmeye devam edilsin mi?"</string>
-    <string name="notification_silence_title" msgid="7352089096356977930">"Sessiz"</string>
-    <string name="notification_alert_title" msgid="3966526305405016221">"Öncelikli"</string>
-    <string name="notification_channel_summary_low" msgid="1065819618107531284">"Bildirimleri yalnızca aşağıya açılır gölgede göstererek işinize odaklanmanızı sağlar. Her zaman sessizdir."</string>
-    <string name="notification_channel_summary_low_status" msgid="2702170424808743755">"Öncelikli bildirimlerin altında görüntülenir. Her zaman sessizdir."</string>
-    <string name="notification_channel_summary_low_lock" msgid="7966605244472624458">"Öncelikli bildirimlerin altında görüntülenir. Her zaman sessizdir."</string>
-    <string name="notification_channel_summary_low_status_lock" msgid="7012562768950012739">"Öncelikli bildirimlerin altında görüntülenir. Her zaman sessizdir."</string>
-    <string name="notification_channel_summary_default" msgid="3847289783382316019">"Ses ve bir durum çubuğu simgesiyle dikkatinizi çeker. Kilit ekranında gösterilir."</string>
+    <string name="notification_silence_title" msgid="5763240612242137433">"Sessiz"</string>
+    <string name="notification_alert_title" msgid="8031196611815490340">"Uyarı"</string>
+    <string name="notification_channel_summary_low" msgid="3387466082089715555">"Ses veya titreşim olmadan odaklanmanıza yardımcı olur."</string>
+    <string name="notification_channel_summary_default" msgid="5994062840431965586">"Ses veya titreşimle dikkatinizi çeker."</string>
     <string name="notification_unblockable_desc" msgid="4556908766584964102">"Bu bildirimler değiştirilemez."</string>
     <string name="notification_multichannel_desc" msgid="4695920306092240550">"Bu bildirim grubu burada yapılandırılamaz"</string>
     <string name="notification_delegate_header" msgid="2857691673814814270">"Proxy uygulanan bildirim"</string>
@@ -908,8 +900,7 @@
     <string name="slice_permission_allow" msgid="2340244901366722709">"İzin ver"</string>
     <string name="slice_permission_deny" msgid="7683681514008048807">"Reddet"</string>
     <string name="auto_saver_title" msgid="1217959994732964228">"Pil Tasarrufunu programlamak için dokunun"</string>
-    <!-- no translation found for auto_saver_text (2563289953551438248) -->
-    <skip />
+    <string name="auto_saver_text" msgid="2563289953551438248">"Piliniz bitecek gibiyse bu özelliği açın"</string>
     <string name="no_auto_saver_action" msgid="8086002101711328500">"Hayır, teşekkürler"</string>
     <string name="auto_saver_enabled_title" msgid="6726474226058316862">"Pil Tasarruf programı açık"</string>
     <string name="auto_saver_enabled_text" msgid="874711029884777579">"Pil %%<xliff:g id="PERCENTAGE">%d</xliff:g> düzeyinin altına düştüğünde Pil Tasarrufu otomatik olarak açılacaktır."</string>
@@ -942,4 +933,6 @@
     <string name="bubble_accessibility_action_move_bottom_left" msgid="206369104473183217">"Sol alta taşı"</string>
     <string name="bubble_accessibility_action_move_bottom_right" msgid="8705660152384312329">"Sağ alta taşı"</string>
     <string name="bubble_dismiss_text" msgid="8028337712674081668">"Kapat"</string>
+    <string name="notification_content_system_nav_changed" msgid="7218093915747788444">"Sistemde gezinme yöntemi güncellendi. Değişiklik yapmak için Ayarlar\'a gidin."</string>
+    <string name="notification_content_gesture_nav_available" msgid="8111130443656460792">"Sistemde gezinme yöntemini güncellemek için Ayarlar\'a gidin"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-uk/strings.xml b/packages/SystemUI/res/values-uk/strings.xml
index 7af05cd..9e04fbe 100644
--- a/packages/SystemUI/res/values-uk/strings.xml
+++ b/packages/SystemUI/res/values-uk/strings.xml
@@ -62,12 +62,10 @@
     <string name="usb_debugging_secondary_user_title" msgid="6353808721761220421">"Ви не можете вмикати налагодження USB"</string>
     <string name="usb_debugging_secondary_user_message" msgid="6067122453571699801">"Користувач поточного облікового запису не може вмикати налагодження USB. Щоб увімкнути цю функцію, увійдіть в обліковий запис основного користувача."</string>
     <string name="usb_contaminant_title" msgid="206854874263058490">"USB-порт вимкнено"</string>
-    <!-- no translation found for usb_contaminant_message (7379089091591609111) -->
-    <skip />
+    <string name="usb_contaminant_message" msgid="7379089091591609111">"Щоб захистити ваш пристрій від рідини та сміття, USB-порт вимкнено. Він не виявлятиме жодних аксесуарів.\n\nКоли USB-порт можна буде використовувати, ви отримаєте сповіщення."</string>
     <string name="usb_port_enabled" msgid="7906141351687694867">"Порт USB виявлятиме зарядні пристрої та аксесуари"</string>
     <string name="usb_disable_contaminant_detection" msgid="2103905315747120033">"Увімкнути USB"</string>
-    <!-- no translation found for learn_more (5000517160980853569) -->
-    <skip />
+    <string name="learn_more" msgid="5000517160980853569">"Докладніше"</string>
     <string name="compat_mode_on" msgid="6623839244840638213">"Масштабув. на весь екран"</string>
     <string name="compat_mode_off" msgid="4434467572461327898">"Розтягнути на весь екран"</string>
     <string name="global_action_screenshot" msgid="8329831278085426283">"Знімок екрана"</string>
@@ -199,6 +197,7 @@
     <string name="carrier_network_change_mode" msgid="8149202439957837762">"Змінення мережі оператора"</string>
     <string name="accessibility_battery_details" msgid="7645516654955025422">"Відкрити деталі акумулятора"</string>
     <string name="accessibility_battery_level" msgid="7451474187113371965">"Заряд акумулятора у відсотках: <xliff:g id="NUMBER">%d</xliff:g>."</string>
+    <string name="accessibility_battery_level_with_estimate" msgid="9033100930684311630">"Згідно з даними про використання залишилося <xliff:g id="PERCENTAGE">%1$s</xliff:g> заряду акумулятора – близько <xliff:g id="TIME">%2$s</xliff:g>"</string>
     <string name="accessibility_battery_level_charging" msgid="1147587904439319646">"Акумулятор заряджається: <xliff:g id="BATTERY_PERCENTAGE">%d</xliff:g>%%."</string>
     <string name="accessibility_settings_button" msgid="799583911231893380">"Налаштування системи."</string>
     <string name="accessibility_notifications_button" msgid="4498000369779421892">"Сповіщення."</string>
@@ -464,10 +463,8 @@
     <string name="media_projection_remember_text" msgid="3103510882172746752">"Більше не показувати"</string>
     <string name="clear_all_notifications_text" msgid="814192889771462828">"Очистити все"</string>
     <string name="manage_notifications_text" msgid="2386728145475108753">"Керувати"</string>
-    <!-- no translation found for notification_section_header_gentle (4372438504154095677) -->
-    <skip />
-    <!-- no translation found for accessibility_notification_section_header_gentle_clear_all (4286716295850400959) -->
-    <skip />
+    <string name="notification_section_header_gentle" msgid="4372438504154095677">"Беззвучні сповіщення"</string>
+    <string name="accessibility_notification_section_header_gentle_clear_all" msgid="4286716295850400959">"Очистити всі беззвучні сповіщення"</string>
     <string name="dnd_suppressing_shade_text" msgid="1904574852846769301">"Режим \"Не турбувати\" призупинив сповіщення"</string>
     <string name="media_projection_action_text" msgid="8470872969457985954">"Почати зараз"</string>
     <string name="empty_shade_text" msgid="708135716272867002">"Сповіщень немає"</string>
@@ -651,21 +648,16 @@
     <string name="inline_block_button" msgid="8735843688021655065">"Блокувати"</string>
     <string name="inline_keep_button" msgid="6665940297019018232">"Показувати надалі"</string>
     <string name="inline_minimize_button" msgid="966233327974702195">"Згорнути"</string>
-    <!-- no translation found for inline_silent_button_silent (5315879183296940969) -->
-    <skip />
+    <string name="inline_silent_button_silent" msgid="5315879183296940969">"Без звуку"</string>
     <string name="inline_silent_button_stay_silent" msgid="6308371431217601009">"Без звуку"</string>
-    <!-- no translation found for inline_silent_button_alert (6008435419895088034) -->
-    <skip />
+    <string name="inline_silent_button_alert" msgid="6008435419895088034">"Сповіщення"</string>
     <string name="inline_silent_button_keep_alerting" msgid="327696842264359693">"Отримувати сповіщення"</string>
     <string name="inline_turn_off_notifications" msgid="8635596135532202355">"Вимкнути сповіщення"</string>
     <string name="inline_keep_showing_app" msgid="1723113469580031041">"Чи показувати сповіщення з цього додатка надалі?"</string>
-    <string name="notification_silence_title" msgid="7352089096356977930">"Тихі сповіщення"</string>
-    <string name="notification_alert_title" msgid="3966526305405016221">"Пріоритетні сповіщення"</string>
-    <string name="notification_channel_summary_low" msgid="1065819618107531284">"Сповіщення показуються лише на розкривній панелі, щоб не відволікати. Завжди без звуку."</string>
-    <string name="notification_channel_summary_low_status" msgid="2702170424808743755">"Показуються під пріоритетними сповіщеннями. Завжди без звуку."</string>
-    <string name="notification_channel_summary_low_lock" msgid="7966605244472624458">"Показуються під пріоритетними сповіщеннями. Завжди без звуку."</string>
-    <string name="notification_channel_summary_low_status_lock" msgid="7012562768950012739">"Показуються під пріоритетними сповіщеннями. Завжди без звуку."</string>
-    <string name="notification_channel_summary_default" msgid="3847289783382316019">"Привертають увагу сигналом і значком у рядку стану. Показуються на заблокованому екрані."</string>
+    <string name="notification_silence_title" msgid="5763240612242137433">"Без звуку"</string>
+    <string name="notification_alert_title" msgid="8031196611815490340">"Зі звуком"</string>
+    <string name="notification_channel_summary_low" msgid="3387466082089715555">"Не відволікає увагу звуковим сигналом або вібрацією."</string>
+    <string name="notification_channel_summary_default" msgid="5994062840431965586">"Привертає увагу звуковим сигналом або вібрацією."</string>
     <string name="notification_unblockable_desc" msgid="4556908766584964102">"Ці сповіщення не можна змінити."</string>
     <string name="notification_multichannel_desc" msgid="4695920306092240550">"Цю групу сповіщень не можна налаштувати тут"</string>
     <string name="notification_delegate_header" msgid="2857691673814814270">"Проксі-сповіщення"</string>
@@ -918,8 +910,7 @@
     <string name="slice_permission_allow" msgid="2340244901366722709">"Дозволити"</string>
     <string name="slice_permission_deny" msgid="7683681514008048807">"Відмовити"</string>
     <string name="auto_saver_title" msgid="1217959994732964228">"Торкніться, щоб увімкнути автоматичний режим економії заряду акумулятора"</string>
-    <!-- no translation found for auto_saver_text (2563289953551438248) -->
-    <skip />
+    <string name="auto_saver_text" msgid="2563289953551438248">"Вмикати, коли заряд акумулятора закінчується"</string>
     <string name="no_auto_saver_action" msgid="8086002101711328500">"Ні, дякую"</string>
     <string name="auto_saver_enabled_title" msgid="6726474226058316862">"Автоматичний режим економії заряду акумулятора ввімкнено"</string>
     <string name="auto_saver_enabled_text" msgid="874711029884777579">"Режим економії заряду акумулятора вмикається автоматично, коли рівень заряду нижчий за <xliff:g id="PERCENTAGE">%d</xliff:g>%%."</string>
@@ -952,4 +943,6 @@
     <string name="bubble_accessibility_action_move_bottom_left" msgid="206369104473183217">"Перемістити ліворуч униз"</string>
     <string name="bubble_accessibility_action_move_bottom_right" msgid="8705660152384312329">"Перемістити праворуч униз"</string>
     <string name="bubble_dismiss_text" msgid="8028337712674081668">"Закрити"</string>
+    <string name="notification_content_system_nav_changed" msgid="7218093915747788444">"Навігацію в системі оновлено. Щоб внести зміни, перейдіть у налаштування."</string>
+    <string name="notification_content_gesture_nav_available" msgid="8111130443656460792">"Перейдіть у налаштування, щоб оновити навігацію в системі"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-ur/strings.xml b/packages/SystemUI/res/values-ur/strings.xml
index 05f90f9..38fb1a8 100644
--- a/packages/SystemUI/res/values-ur/strings.xml
+++ b/packages/SystemUI/res/values-ur/strings.xml
@@ -62,12 +62,10 @@
     <string name="usb_debugging_secondary_user_title" msgid="6353808721761220421">"‏USB ڈیبگ کرنے کی اجازت نہیں ہے"</string>
     <string name="usb_debugging_secondary_user_message" msgid="6067122453571699801">"‏اس آلہ پر فی الحال سائن ان کردہ صارف USB ڈیبگنگ آن نہیں کر سکتا۔ اس خصوصیت کا استعمال کرنے کیلئے، ابتدائی صارف پر سوئچ کریں۔"</string>
     <string name="usb_contaminant_title" msgid="206854874263058490">"‏USB پورٹ غیر فعال ہو گیا"</string>
-    <!-- no translation found for usb_contaminant_message (7379089091591609111) -->
-    <skip />
+    <string name="usb_contaminant_message" msgid="7379089091591609111">"‏آپ کے آلے کی سیال یا دھول سے حفاظت کرنے کے لیے، USB پورٹ کو غیر فعال کر دیا گیا ہے اور یہ کسی لوازم کا پتہ نہیں لگا پائے گا۔\n\nUSB پورٹ کا دوبارہ استعمال کرنا ٹھیک ہونے پر آپ کو مطلع کیا جائے گا۔"</string>
     <string name="usb_port_enabled" msgid="7906141351687694867">"‏چارجرز اور لوازمات کا پتا لگانے کے لیے USB پورٹ فعال ہے"</string>
     <string name="usb_disable_contaminant_detection" msgid="2103905315747120033">"‏USB پورٹ فعال کریں"</string>
-    <!-- no translation found for learn_more (5000517160980853569) -->
-    <skip />
+    <string name="learn_more" msgid="5000517160980853569">"مزید جانیں"</string>
     <string name="compat_mode_on" msgid="6623839244840638213">"پوری سکرین پر زوم کریں"</string>
     <string name="compat_mode_off" msgid="4434467572461327898">"پوری سکرین پر پھیلائیں"</string>
     <string name="global_action_screenshot" msgid="8329831278085426283">"اسکرین شاٹ"</string>
@@ -199,6 +197,7 @@
     <string name="carrier_network_change_mode" msgid="8149202439957837762">"کیریئر نیٹ ورک کی تبدیلی"</string>
     <string name="accessibility_battery_details" msgid="7645516654955025422">"بیٹری کی تفصیلات کھولیں"</string>
     <string name="accessibility_battery_level" msgid="7451474187113371965">"بیٹری <xliff:g id="NUMBER">%d</xliff:g> فیصد۔"</string>
+    <string name="accessibility_battery_level_with_estimate" msgid="9033100930684311630">"آپ کے استعمال کی بنیاد پر بیٹری <xliff:g id="PERCENTAGE">%1$s</xliff:g> فیصد، تقریباً <xliff:g id="TIME">%2$s</xliff:g> باقی ہے"</string>
     <string name="accessibility_battery_level_charging" msgid="1147587904439319646">"بیٹری چارج ہو رہی ہے، <xliff:g id="BATTERY_PERCENTAGE">%d</xliff:g>%%"</string>
     <string name="accessibility_settings_button" msgid="799583911231893380">"سسٹم کی ترتیبات۔"</string>
     <string name="accessibility_notifications_button" msgid="4498000369779421892">"اطلاعات۔"</string>
@@ -458,10 +457,8 @@
     <string name="media_projection_remember_text" msgid="3103510882172746752">"دوبارہ نہ دکھائیں"</string>
     <string name="clear_all_notifications_text" msgid="814192889771462828">"سبھی کو صاف کریں"</string>
     <string name="manage_notifications_text" msgid="2386728145475108753">"نظم کریں"</string>
-    <!-- no translation found for notification_section_header_gentle (4372438504154095677) -->
-    <skip />
-    <!-- no translation found for accessibility_notification_section_header_gentle_clear_all (4286716295850400959) -->
-    <skip />
+    <string name="notification_section_header_gentle" msgid="4372438504154095677">"اطلاعات خاموش کریں"</string>
+    <string name="accessibility_notification_section_header_gentle_clear_all" msgid="4286716295850400959">"سبھی خاموش اطلاعات کو صاف کریں"</string>
     <string name="dnd_suppressing_shade_text" msgid="1904574852846769301">"\'ڈسٹرب نہ کریں\' کے ذریعے اطلاعات کو موقوف کیا گیا"</string>
     <string name="media_projection_action_text" msgid="8470872969457985954">"ابھی شروع کریں"</string>
     <string name="empty_shade_text" msgid="708135716272867002">"کوئی اطلاعات نہیں ہیں"</string>
@@ -645,21 +642,16 @@
     <string name="inline_block_button" msgid="8735843688021655065">"مسدود کریں"</string>
     <string name="inline_keep_button" msgid="6665940297019018232">"دکھانا جاری رکھیں"</string>
     <string name="inline_minimize_button" msgid="966233327974702195">"چھوٹا کریں"</string>
-    <!-- no translation found for inline_silent_button_silent (5315879183296940969) -->
-    <skip />
+    <string name="inline_silent_button_silent" msgid="5315879183296940969">"خاموش کریں"</string>
     <string name="inline_silent_button_stay_silent" msgid="6308371431217601009">"خاموش رہیں"</string>
-    <!-- no translation found for inline_silent_button_alert (6008435419895088034) -->
-    <skip />
+    <string name="inline_silent_button_alert" msgid="6008435419895088034">"الرٹ کرنا"</string>
     <string name="inline_silent_button_keep_alerting" msgid="327696842264359693">"متنبہ کرنا جاری رکھیں"</string>
     <string name="inline_turn_off_notifications" msgid="8635596135532202355">"اطلاعات کو آف کریں"</string>
     <string name="inline_keep_showing_app" msgid="1723113469580031041">"اس ایپ کی طرف سے اطلاعات دکھانا جاری رکھیں؟"</string>
-    <string name="notification_silence_title" msgid="7352089096356977930">"لطیف"</string>
-    <string name="notification_alert_title" msgid="3966526305405016221">"ترجیحی"</string>
-    <string name="notification_channel_summary_low" msgid="1065819618107531284">"صرف نیچے کی طرف کھینچیں شیڈ میں اطلاعات کے ساتھ فوکس کرنے میں آپ کی مدد کرتا ہے۔ ہمیشہ خاموش۔"</string>
-    <string name="notification_channel_summary_low_status" msgid="2702170424808743755">"کم ترجیحی اطلاعات ڈسپلے کرتا ہے۔ ہمیشہ خاموش۔"</string>
-    <string name="notification_channel_summary_low_lock" msgid="7966605244472624458">"کم ترجیحی اطلاعات ڈسپلے کرتا ہے۔ ہمیشہ خاموش۔"</string>
-    <string name="notification_channel_summary_low_status_lock" msgid="7012562768950012739">"کم ترجیحی اطلاعات ڈسپلے کرتا ہے۔ ہمیشہ خاموش۔"</string>
-    <string name="notification_channel_summary_default" msgid="3847289783382316019">"آواز اور اسٹیٹس بار کے آئیکن کے ساتھ آپ کی توجہ حاصل کرتا ہے۔ مقفل اسکرین پر دکھاتا ہے۔"</string>
+    <string name="notification_silence_title" msgid="5763240612242137433">"خاموش"</string>
+    <string name="notification_alert_title" msgid="8031196611815490340">"الرٹ کرنا"</string>
+    <string name="notification_channel_summary_low" msgid="3387466082089715555">"بغیر آواز یا وائبریشن کے آپ کو فوکس کرنے میں مدد کرتا ہے۔"</string>
+    <string name="notification_channel_summary_default" msgid="5994062840431965586">"آواز اور وائبریشن کے ذریعے آپ کی توجہ حاصل کرتا ہے۔"</string>
     <string name="notification_unblockable_desc" msgid="4556908766584964102">"ان اطلاعات کی ترمیم نہیں کی جا سکتی۔"</string>
     <string name="notification_multichannel_desc" msgid="4695920306092240550">"اطلاعات کے اس گروپ کو یہاں کنفیگر نہیں کیا جا سکتا"</string>
     <string name="notification_delegate_header" msgid="2857691673814814270">"پراکسی اطلاع"</string>
@@ -908,8 +900,7 @@
     <string name="slice_permission_allow" msgid="2340244901366722709">"اجازت دیں"</string>
     <string name="slice_permission_deny" msgid="7683681514008048807">"مسترد کریں"</string>
     <string name="auto_saver_title" msgid="1217959994732964228">"بیٹری سیور شیڈول کرنے کے لیے تھپتھپائیں"</string>
-    <!-- no translation found for auto_saver_text (2563289953551438248) -->
-    <skip />
+    <string name="auto_saver_text" msgid="2563289953551438248">"جب بیٹری کے ختم ہونے کا امکان ہو تو آن کریں"</string>
     <string name="no_auto_saver_action" msgid="8086002101711328500">"نہیں شکریہ"</string>
     <string name="auto_saver_enabled_title" msgid="6726474226058316862">"بیٹری سیور شیڈول آن ہو گیا"</string>
     <string name="auto_saver_enabled_text" msgid="874711029884777579">"بیٹری کے <xliff:g id="PERCENTAGE">%d</xliff:g>%% سے کم ہونے پر بیٹری سیور خودکار طور پر آن ہو جائے گا۔"</string>
@@ -942,4 +933,6 @@
     <string name="bubble_accessibility_action_move_bottom_left" msgid="206369104473183217">"نیچے بائیں جانب لے جائیں"</string>
     <string name="bubble_accessibility_action_move_bottom_right" msgid="8705660152384312329">"نیچے دائیں جانب لے جائیں"</string>
     <string name="bubble_dismiss_text" msgid="8028337712674081668">"برخاست کریں"</string>
+    <string name="notification_content_system_nav_changed" msgid="7218093915747788444">"سسٹم نیویگیشن اپ ڈیٹ کیا گیا۔ تبدیلیاں کرنے کے لیے، ترتیبات پر جائیں۔"</string>
+    <string name="notification_content_gesture_nav_available" msgid="8111130443656460792">"سسٹم نیویگیشن اپ ڈیٹ کرنے کے لیے ترتیبات پر جائیں"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-uz/strings.xml b/packages/SystemUI/res/values-uz/strings.xml
index 2161527..0f93809 100644
--- a/packages/SystemUI/res/values-uz/strings.xml
+++ b/packages/SystemUI/res/values-uz/strings.xml
@@ -62,12 +62,10 @@
     <string name="usb_debugging_secondary_user_title" msgid="6353808721761220421">"USB orqali nosozliklarni tuzatishga ruxsat berilmagan"</string>
     <string name="usb_debugging_secondary_user_message" msgid="6067122453571699801">"Ayni paytda ushbu qurilmaga o‘z hisobi bilan kirgan foydalanuvchi USB orqali nosozliklarni tuzatish funksiyasini yoqa olmaydi. Bu funksiyadan foydalanish uchun asosiy foydalanuvchi profiliga o‘ting."</string>
     <string name="usb_contaminant_title" msgid="206854874263058490">"USB port faolsizlashtirildi"</string>
-    <!-- no translation found for usb_contaminant_message (7379089091591609111) -->
-    <skip />
+    <string name="usb_contaminant_message" msgid="7379089091591609111">"Qurilmangizni suyuqlik va turli parchalardan himoya qilish uchun USB port faolsizlashtiriladi va hech qanday aksessuarni aniqlay olmaydi.\n\nUSB portdan xavfsiz foydalanish mumkin boʻlganda, sizga xabar beriladi."</string>
     <string name="usb_port_enabled" msgid="7906141351687694867">"Quvvatlash moslamalari va aksessuarlarni aniqlash uchun USB port yoqildi"</string>
     <string name="usb_disable_contaminant_detection" msgid="2103905315747120033">"USB xususiyatini yoqish"</string>
-    <!-- no translation found for learn_more (5000517160980853569) -->
-    <skip />
+    <string name="learn_more" msgid="5000517160980853569">"Batafsil"</string>
     <string name="compat_mode_on" msgid="6623839244840638213">"Ekranga moslashtirish"</string>
     <string name="compat_mode_off" msgid="4434467572461327898">"Ekran hajmida cho‘zish"</string>
     <string name="global_action_screenshot" msgid="8329831278085426283">"Skrinshot"</string>
@@ -199,6 +197,7 @@
     <string name="carrier_network_change_mode" msgid="8149202439957837762">"Mobil tarmoqni o‘zgartirish"</string>
     <string name="accessibility_battery_details" msgid="7645516654955025422">"Quvvat sarfi tafsilotlari"</string>
     <string name="accessibility_battery_level" msgid="7451474187113371965">"Batareya <xliff:g id="NUMBER">%d</xliff:g> foiz."</string>
+    <string name="accessibility_battery_level_with_estimate" msgid="9033100930684311630">"Batareya quvvati <xliff:g id="PERCENTAGE">%1$s</xliff:g> foiz, joriy holatda yana <xliff:g id="TIME">%2$s</xliff:g> qoldi"</string>
     <string name="accessibility_battery_level_charging" msgid="1147587904439319646">"Batareya quvvat olmoqda (<xliff:g id="BATTERY_PERCENTAGE">%d</xliff:g>%%)."</string>
     <string name="accessibility_settings_button" msgid="799583911231893380">"Tizim sozlamalari."</string>
     <string name="accessibility_notifications_button" msgid="4498000369779421892">"Eslatmalar."</string>
@@ -458,10 +457,8 @@
     <string name="media_projection_remember_text" msgid="3103510882172746752">"Boshqa ko‘rsatilmasin"</string>
     <string name="clear_all_notifications_text" msgid="814192889771462828">"Hammasini tozalash"</string>
     <string name="manage_notifications_text" msgid="2386728145475108753">"Boshqarish"</string>
-    <!-- no translation found for notification_section_header_gentle (4372438504154095677) -->
-    <skip />
-    <!-- no translation found for accessibility_notification_section_header_gentle_clear_all (4286716295850400959) -->
-    <skip />
+    <string name="notification_section_header_gentle" msgid="4372438504154095677">"Ovozsiz bildirishnomalar"</string>
+    <string name="accessibility_notification_section_header_gentle_clear_all" msgid="4286716295850400959">"Barcha tovushsiz bildirishnomalarni tozalash"</string>
     <string name="dnd_suppressing_shade_text" msgid="1904574852846769301">"Bezovta qilinmasin rejimida bildirishnomalar pauza qilingan"</string>
     <string name="media_projection_action_text" msgid="8470872969457985954">"Boshlash"</string>
     <string name="empty_shade_text" msgid="708135716272867002">"Bildirishnomalar yo‘q"</string>
@@ -590,7 +587,7 @@
     <string name="show_battery_percentage_summary" msgid="3215025775576786037">"Quvvat olmayotgan vaqtda batareya foizi holat qatorida chiqib turadi"</string>
     <string name="quick_settings" msgid="10042998191725428">"Tezkor sozlamalar"</string>
     <string name="status_bar" msgid="4877645476959324760">"Holat qatori"</string>
-    <string name="overview" msgid="4018602013895926956">"Umumiy ma’lumot"</string>
+    <string name="overview" msgid="4018602013895926956">"Umumiy"</string>
     <string name="demo_mode" msgid="2532177350215638026">"Tizim interfeysi demo rejimi"</string>
     <string name="enable_demo_mode" msgid="4844205668718636518">"Demo rejimni yoqish"</string>
     <string name="show_demo_mode" msgid="2018336697782464029">"Demo rejimni ko‘rsatish"</string>
@@ -645,21 +642,16 @@
     <string name="inline_block_button" msgid="8735843688021655065">"Bloklash"</string>
     <string name="inline_keep_button" msgid="6665940297019018232">"Ha"</string>
     <string name="inline_minimize_button" msgid="966233327974702195">"Kichraytirish"</string>
-    <!-- no translation found for inline_silent_button_silent (5315879183296940969) -->
-    <skip />
+    <string name="inline_silent_button_silent" msgid="5315879183296940969">"Tovushsiz"</string>
     <string name="inline_silent_button_stay_silent" msgid="6308371431217601009">"Ovozsiz qolsin"</string>
-    <!-- no translation found for inline_silent_button_alert (6008435419895088034) -->
-    <skip />
+    <string name="inline_silent_button_alert" msgid="6008435419895088034">"Bildirishnoma yuborish"</string>
     <string name="inline_silent_button_keep_alerting" msgid="327696842264359693">"Signal berishda davom etilsin"</string>
     <string name="inline_turn_off_notifications" msgid="8635596135532202355">"Bildirishnoma kelmasin"</string>
     <string name="inline_keep_showing_app" msgid="1723113469580031041">"Bu ilovadan keladigan bildirishnomalar chiqaversinmi?"</string>
-    <string name="notification_silence_title" msgid="7352089096356977930">"Tovushsiz"</string>
-    <string name="notification_alert_title" msgid="3966526305405016221">"Muhim"</string>
-    <string name="notification_channel_summary_low" msgid="1065819618107531284">"Bildirishnomalar faqat maxsus panelda chiqadi. Doim tovushsiz."</string>
-    <string name="notification_channel_summary_low_status" msgid="2702170424808743755">"Muhimlik darajasi past bildirishnomalarning chiqishi. Doim tovushsiz."</string>
-    <string name="notification_channel_summary_low_lock" msgid="7966605244472624458">"Muhimlik darajasi past bildirishnomalarning chiqishi. Doim tovushsiz."</string>
-    <string name="notification_channel_summary_low_status_lock" msgid="7012562768950012739">"Muhimlik darajasi past bildirishnomalarning chiqishi. Doim tovushsiz."</string>
-    <string name="notification_channel_summary_default" msgid="3847289783382316019">"Kelgan bildirishnomalarni maxsus tovush va holat paneliga chiqadigan nishoncha orqali bilish mumkin. Bildirishnomalar ekran qulfida ham chiqadi."</string>
+    <string name="notification_silence_title" msgid="5763240612242137433">"Tovushsiz"</string>
+    <string name="notification_alert_title" msgid="8031196611815490340">"Bildirishnoma yuborish"</string>
+    <string name="notification_channel_summary_low" msgid="3387466082089715555">"Bildirishnomalar tovush va tebranishsiz keladi."</string>
+    <string name="notification_channel_summary_default" msgid="5994062840431965586">"Bildirishnomalar tovush va tebranish bilan keladi."</string>
     <string name="notification_unblockable_desc" msgid="4556908766584964102">"Bu bildirishnomalarni tahrirlash imkonsiz."</string>
     <string name="notification_multichannel_desc" msgid="4695920306092240550">"Ushbu bildirishnomalar guruhi bu yerda sozlanmaydi"</string>
     <string name="notification_delegate_header" msgid="2857691673814814270">"Ishonchli bildirishnoma"</string>
@@ -908,8 +900,7 @@
     <string name="slice_permission_allow" msgid="2340244901366722709">"Ruxsat"</string>
     <string name="slice_permission_deny" msgid="7683681514008048807">"Rad etish"</string>
     <string name="auto_saver_title" msgid="1217959994732964228">"Quvvat tejash rejimini rejalashtirish uchun bosing"</string>
-    <!-- no translation found for auto_saver_text (2563289953551438248) -->
-    <skip />
+    <string name="auto_saver_text" msgid="2563289953551438248">"Batareya quvvati kamayishi aniqlanganda yoqilsin"</string>
     <string name="no_auto_saver_action" msgid="8086002101711328500">"Kerak emas"</string>
     <string name="auto_saver_enabled_title" msgid="6726474226058316862">"Quvvat tejash rejimi jadvali faollashtirildi"</string>
     <string name="auto_saver_enabled_text" msgid="874711029884777579">"Batareya quvvati <xliff:g id="PERCENTAGE">%d</xliff:g>%% ga tushsa, quvvat tejash rejimi avtomatik ravishda yoqiladi."</string>
@@ -942,4 +933,6 @@
     <string name="bubble_accessibility_action_move_bottom_left" msgid="206369104473183217">"Quyi chapga surish"</string>
     <string name="bubble_accessibility_action_move_bottom_right" msgid="8705660152384312329">"Quyi oʻngga surish"</string>
     <string name="bubble_dismiss_text" msgid="8028337712674081668">"Yopish"</string>
+    <string name="notification_content_system_nav_changed" msgid="7218093915747788444">"Tizim navigatsiyasi yangilandi. Buni Sozlamalar orqali oʻzgartirishingiz mumkin."</string>
+    <string name="notification_content_gesture_nav_available" msgid="8111130443656460792">"Tizim navigatsiyasini yangilash uchun Sozlamalarni oching"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-vi/strings.xml b/packages/SystemUI/res/values-vi/strings.xml
index ace5215..d1a2fdc 100644
--- a/packages/SystemUI/res/values-vi/strings.xml
+++ b/packages/SystemUI/res/values-vi/strings.xml
@@ -62,12 +62,10 @@
     <string name="usb_debugging_secondary_user_title" msgid="6353808721761220421">"Tính năng gỡ lỗi USB không được phép"</string>
     <string name="usb_debugging_secondary_user_message" msgid="6067122453571699801">"Người dùng hiện đã đăng nhập vào thiết bị này không thể bật tính năng gỡ lỗi USB. Để sử dụng tính năng này, hãy chuyển sang người dùng chính."</string>
     <string name="usb_contaminant_title" msgid="206854874263058490">"Đã tắt cổng USB"</string>
-    <!-- no translation found for usb_contaminant_message (7379089091591609111) -->
-    <skip />
+    <string name="usb_contaminant_message" msgid="7379089091591609111">"Để bảo vệ thiết bị của bạn khỏi chất lỏng hay mảnh vỡ, cổng USB sẽ tắt và không phát hiện được bất kỳ phụ kiện nào.\n\nBạn sẽ nhận được thông báo khi có thể sử dụng lại cổng USB."</string>
     <string name="usb_port_enabled" msgid="7906141351687694867">"Đã bật cổng USB để phát hiện bộ sạc và phụ kiện"</string>
     <string name="usb_disable_contaminant_detection" msgid="2103905315747120033">"Bật USB"</string>
-    <!-- no translation found for learn_more (5000517160980853569) -->
-    <skip />
+    <string name="learn_more" msgid="5000517160980853569">"Tìm hiểu thêm"</string>
     <string name="compat_mode_on" msgid="6623839244840638213">"T.phóng để lấp đầy m.hình"</string>
     <string name="compat_mode_off" msgid="4434467572461327898">"Giãn ra để lấp đầy m.hình"</string>
     <string name="global_action_screenshot" msgid="8329831278085426283">"Chụp màn hình"</string>
@@ -199,6 +197,7 @@
     <string name="carrier_network_change_mode" msgid="8149202439957837762">"Thay đổi mạng của nhà mạng"</string>
     <string name="accessibility_battery_details" msgid="7645516654955025422">"Mở chi tiết về pin"</string>
     <string name="accessibility_battery_level" msgid="7451474187113371965">"<xliff:g id="NUMBER">%d</xliff:g> phần trăm pin."</string>
+    <string name="accessibility_battery_level_with_estimate" msgid="9033100930684311630">"<xliff:g id="PERCENTAGE">%1$s</xliff:g> phần trăm pin, còn khoảng <xliff:g id="TIME">%2$s</xliff:g> dựa trên mức sử dụng của bạn"</string>
     <string name="accessibility_battery_level_charging" msgid="1147587904439319646">"Đang sạc pin, <xliff:g id="BATTERY_PERCENTAGE">%d</xliff:g>%%."</string>
     <string name="accessibility_settings_button" msgid="799583911231893380">"Cài đặt hệ thống"</string>
     <string name="accessibility_notifications_button" msgid="4498000369779421892">"Thông báo."</string>
@@ -458,10 +457,8 @@
     <string name="media_projection_remember_text" msgid="3103510882172746752">"Không hiển thị lại"</string>
     <string name="clear_all_notifications_text" msgid="814192889771462828">"Xóa tất cả"</string>
     <string name="manage_notifications_text" msgid="2386728145475108753">"Quản lý"</string>
-    <!-- no translation found for notification_section_header_gentle (4372438504154095677) -->
-    <skip />
-    <!-- no translation found for accessibility_notification_section_header_gentle_clear_all (4286716295850400959) -->
-    <skip />
+    <string name="notification_section_header_gentle" msgid="4372438504154095677">"Thông báo im lặng"</string>
+    <string name="accessibility_notification_section_header_gentle_clear_all" msgid="4286716295850400959">"Xóa tất cả thông báo im lặng"</string>
     <string name="dnd_suppressing_shade_text" msgid="1904574852846769301">"Chế độ Không làm phiền đã tạm dừng thông báo"</string>
     <string name="media_projection_action_text" msgid="8470872969457985954">"Bắt đầu ngay"</string>
     <string name="empty_shade_text" msgid="708135716272867002">"Không có thông báo nào"</string>
@@ -645,21 +642,16 @@
     <string name="inline_block_button" msgid="8735843688021655065">"Chặn"</string>
     <string name="inline_keep_button" msgid="6665940297019018232">"Tiếp tục hiển thị"</string>
     <string name="inline_minimize_button" msgid="966233327974702195">"Thu nhỏ"</string>
-    <!-- no translation found for inline_silent_button_silent (5315879183296940969) -->
-    <skip />
+    <string name="inline_silent_button_silent" msgid="5315879183296940969">"Im lặng"</string>
     <string name="inline_silent_button_stay_silent" msgid="6308371431217601009">"Tiếp tục chế độ im lặng"</string>
-    <!-- no translation found for inline_silent_button_alert (6008435419895088034) -->
-    <skip />
+    <string name="inline_silent_button_alert" msgid="6008435419895088034">"Cảnh báo"</string>
     <string name="inline_silent_button_keep_alerting" msgid="327696842264359693">"Tiếp tục cảnh báo"</string>
     <string name="inline_turn_off_notifications" msgid="8635596135532202355">"Tắt thông báo"</string>
     <string name="inline_keep_showing_app" msgid="1723113469580031041">"Tiếp tục hiển thị các thông báo từ ứng dụng này?"</string>
-    <string name="notification_silence_title" msgid="7352089096356977930">"Nhẹ nhàng"</string>
-    <string name="notification_alert_title" msgid="3966526305405016221">"Ưu tiên"</string>
-    <string name="notification_channel_summary_low" msgid="1065819618107531284">"Giúp bạn chỉ tập trung vào thông báo trong danh sách kéo xuống. Luôn im lặng."</string>
-    <string name="notification_channel_summary_low_status" msgid="2702170424808743755">"Hiển thị bên dưới thông báo mức độ ưu tiên. Luôn im lặng."</string>
-    <string name="notification_channel_summary_low_lock" msgid="7966605244472624458">"Hiển thị bên dưới thông báo mức độ ưu tiên. Luôn im lặng."</string>
-    <string name="notification_channel_summary_low_status_lock" msgid="7012562768950012739">"Hiển thị bên dưới thông báo mức độ ưu tiên. Luôn im lặng."</string>
-    <string name="notification_channel_summary_default" msgid="3847289783382316019">"Thu hút sự chú ý của bạn bằng biểu tượng thanh trạng thái và âm thanh. Hiển thị trên màn hình khóa."</string>
+    <string name="notification_silence_title" msgid="5763240612242137433">"Im lặng"</string>
+    <string name="notification_alert_title" msgid="8031196611815490340">"Cảnh báo"</string>
+    <string name="notification_channel_summary_low" msgid="3387466082089715555">"Giúp bạn tập trung bằng cách tắt tiếng hoặc không rung."</string>
+    <string name="notification_channel_summary_default" msgid="5994062840431965586">"Thu hút sự chú ý của bạn bằng cách bật tiếng hoặc rung."</string>
     <string name="notification_unblockable_desc" msgid="4556908766584964102">"Không thể sửa đổi các thông báo này."</string>
     <string name="notification_multichannel_desc" msgid="4695920306092240550">"Không thể định cấu hình nhóm thông báo này tại đây"</string>
     <string name="notification_delegate_header" msgid="2857691673814814270">"Thông báo đã xử lý qua máy chủ proxy"</string>
@@ -908,8 +900,7 @@
     <string name="slice_permission_allow" msgid="2340244901366722709">"Cho phép"</string>
     <string name="slice_permission_deny" msgid="7683681514008048807">"Từ chối"</string>
     <string name="auto_saver_title" msgid="1217959994732964228">"Nhấn để lên lịch Trình tiết kiệm pin"</string>
-    <!-- no translation found for auto_saver_text (2563289953551438248) -->
-    <skip />
+    <string name="auto_saver_text" msgid="2563289953551438248">"Bật khi pin sắp hết"</string>
     <string name="no_auto_saver_action" msgid="8086002101711328500">"Không, cảm ơn"</string>
     <string name="auto_saver_enabled_title" msgid="6726474226058316862">"Đã bật Trình tiết kiệm pin được lên lịch"</string>
     <string name="auto_saver_enabled_text" msgid="874711029884777579">"Trình tiết kiệm pin sẽ tự động bật khi mức pin thấp hơn <xliff:g id="PERCENTAGE">%d</xliff:g>%%."</string>
@@ -942,4 +933,6 @@
     <string name="bubble_accessibility_action_move_bottom_left" msgid="206369104473183217">"Chuyển tới dưới cùng bên trái"</string>
     <string name="bubble_accessibility_action_move_bottom_right" msgid="8705660152384312329">"Chuyển tới dưới cùng bên phải"</string>
     <string name="bubble_dismiss_text" msgid="8028337712674081668">"Loại bỏ"</string>
+    <string name="notification_content_system_nav_changed" msgid="7218093915747788444">"Đã cập nhật chế độ di chuyển trên hệ thống. Để thay đổi, hãy chuyển đến phần Cài đặt."</string>
+    <string name="notification_content_gesture_nav_available" msgid="8111130443656460792">"Chuyển đến phần Cài đặt để cập nhật chế độ di chuyển trên hệ thống"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-zh-rCN/strings.xml b/packages/SystemUI/res/values-zh-rCN/strings.xml
index 8675e31..69d7157 100644
--- a/packages/SystemUI/res/values-zh-rCN/strings.xml
+++ b/packages/SystemUI/res/values-zh-rCN/strings.xml
@@ -62,12 +62,10 @@
     <string name="usb_debugging_secondary_user_title" msgid="6353808721761220421">"不允许使用 USB 调试功能"</string>
     <string name="usb_debugging_secondary_user_message" msgid="6067122453571699801">"目前已登录此设备的用户无法开启 USB 调试功能。要使用此功能,请切换为主要用户的帐号。"</string>
     <string name="usb_contaminant_title" msgid="206854874263058490">"USB 端口已停用"</string>
-    <!-- no translation found for usb_contaminant_message (7379089091591609111) -->
-    <skip />
+    <string name="usb_contaminant_message" msgid="7379089091591609111">"为避免液体或碎屑导致您的设备受损,系统已停用 USB 端口,因此目前无法检测任何配件。\n\n系统会在重新允许使用 USB 端口时通知您。"</string>
     <string name="usb_port_enabled" msgid="7906141351687694867">"USB 端口已启用,可检测充电器和配件"</string>
     <string name="usb_disable_contaminant_detection" msgid="2103905315747120033">"启用 USB"</string>
-    <!-- no translation found for learn_more (5000517160980853569) -->
-    <skip />
+    <string name="learn_more" msgid="5000517160980853569">"了解详情"</string>
     <string name="compat_mode_on" msgid="6623839244840638213">"缩放以填满屏幕"</string>
     <string name="compat_mode_off" msgid="4434467572461327898">"拉伸以填满屏幕"</string>
     <string name="global_action_screenshot" msgid="8329831278085426283">"屏幕截图"</string>
@@ -199,6 +197,7 @@
     <string name="carrier_network_change_mode" msgid="8149202439957837762">"运营商网络正在更改"</string>
     <string name="accessibility_battery_details" msgid="7645516654955025422">"打开电量详情"</string>
     <string name="accessibility_battery_level" msgid="7451474187113371965">"电池电量为百分之 <xliff:g id="NUMBER">%d</xliff:g>。"</string>
+    <string name="accessibility_battery_level_with_estimate" msgid="9033100930684311630">"电池电量为 <xliff:g id="PERCENTAGE">%1$s</xliff:g>,根据您的使用情况,大约还可使用 <xliff:g id="TIME">%2$s</xliff:g>"</string>
     <string name="accessibility_battery_level_charging" msgid="1147587904439319646">"正在充电,已完成 <xliff:g id="BATTERY_PERCENTAGE">%d</xliff:g>%%。"</string>
     <string name="accessibility_settings_button" msgid="799583911231893380">"系统设置。"</string>
     <string name="accessibility_notifications_button" msgid="4498000369779421892">"通知。"</string>
@@ -458,10 +457,8 @@
     <string name="media_projection_remember_text" msgid="3103510882172746752">"不再显示"</string>
     <string name="clear_all_notifications_text" msgid="814192889771462828">"全部清除"</string>
     <string name="manage_notifications_text" msgid="2386728145475108753">"管理"</string>
-    <!-- no translation found for notification_section_header_gentle (4372438504154095677) -->
-    <skip />
-    <!-- no translation found for accessibility_notification_section_header_gentle_clear_all (4286716295850400959) -->
-    <skip />
+    <string name="notification_section_header_gentle" msgid="4372438504154095677">"无声通知"</string>
+    <string name="accessibility_notification_section_header_gentle_clear_all" msgid="4286716295850400959">"清除所有无声通知"</string>
     <string name="dnd_suppressing_shade_text" msgid="1904574852846769301">"勿扰模式暂停的通知"</string>
     <string name="media_projection_action_text" msgid="8470872969457985954">"立即开始"</string>
     <string name="empty_shade_text" msgid="708135716272867002">"没有通知"</string>
@@ -645,21 +642,16 @@
     <string name="inline_block_button" msgid="8735843688021655065">"屏蔽"</string>
     <string name="inline_keep_button" msgid="6665940297019018232">"继续显示"</string>
     <string name="inline_minimize_button" msgid="966233327974702195">"最小化"</string>
-    <!-- no translation found for inline_silent_button_silent (5315879183296940969) -->
-    <skip />
+    <string name="inline_silent_button_silent" msgid="5315879183296940969">"静音"</string>
     <string name="inline_silent_button_stay_silent" msgid="6308371431217601009">"显示通知但不发出提示音"</string>
-    <!-- no translation found for inline_silent_button_alert (6008435419895088034) -->
-    <skip />
+    <string name="inline_silent_button_alert" msgid="6008435419895088034">"提醒"</string>
     <string name="inline_silent_button_keep_alerting" msgid="327696842264359693">"继续提醒"</string>
     <string name="inline_turn_off_notifications" msgid="8635596135532202355">"关闭通知"</string>
     <string name="inline_keep_showing_app" msgid="1723113469580031041">"要继续显示来自此应用的通知吗?"</string>
-    <string name="notification_silence_title" msgid="7352089096356977930">"无声通知"</string>
-    <string name="notification_alert_title" msgid="3966526305405016221">"已设为优先"</string>
-    <string name="notification_channel_summary_low" msgid="1065819618107531284">"只会在下拉通知栏中显示通知,引起您的注意。一律不发出提示音。"</string>
-    <string name="notification_channel_summary_low_status" msgid="2702170424808743755">"显示在优先通知下方。一律不发出提示音。"</string>
-    <string name="notification_channel_summary_low_lock" msgid="7966605244472624458">"显示在优先通知下方。一律不发出提示音。"</string>
-    <string name="notification_channel_summary_low_status_lock" msgid="7012562768950012739">"显示在优先通知下方。一律不发出提示音。"</string>
-    <string name="notification_channel_summary_default" msgid="3847289783382316019">"通过提示音和状态栏图标吸引您的注意。这类通知会显示在锁定屏幕上。"</string>
+    <string name="notification_silence_title" msgid="5763240612242137433">"静音"</string>
+    <string name="notification_alert_title" msgid="8031196611815490340">"提醒"</string>
+    <string name="notification_channel_summary_low" msgid="3387466082089715555">"不会发出提示音或振动,可帮助您保持专注。"</string>
+    <string name="notification_channel_summary_default" msgid="5994062840431965586">"通过提示音或振动吸引您的注意。"</string>
     <string name="notification_unblockable_desc" msgid="4556908766584964102">"无法修改这些通知。"</string>
     <string name="notification_multichannel_desc" msgid="4695920306092240550">"您无法在此处配置这组通知"</string>
     <string name="notification_delegate_header" msgid="2857691673814814270">"代理通知"</string>
@@ -908,8 +900,7 @@
     <string name="slice_permission_allow" msgid="2340244901366722709">"允许"</string>
     <string name="slice_permission_deny" msgid="7683681514008048807">"拒绝"</string>
     <string name="auto_saver_title" msgid="1217959994732964228">"点按即可预设省电模式"</string>
-    <!-- no translation found for auto_saver_text (2563289953551438248) -->
-    <skip />
+    <string name="auto_saver_text" msgid="2563289953551438248">"在电池电量可能会耗尽时,系统会开启此模式"</string>
     <string name="no_auto_saver_action" msgid="8086002101711328500">"不用了"</string>
     <string name="auto_saver_enabled_title" msgid="6726474226058316862">"预设的省电模式已开启"</string>
     <string name="auto_saver_enabled_text" msgid="874711029884777579">"一旦电池电量降到 <xliff:g id="PERCENTAGE">%d</xliff:g>%% 以下,省电模式就会自动开启。"</string>
@@ -942,4 +933,6 @@
     <string name="bubble_accessibility_action_move_bottom_left" msgid="206369104473183217">"移至左下角"</string>
     <string name="bubble_accessibility_action_move_bottom_right" msgid="8705660152384312329">"移至右下角"</string>
     <string name="bubble_dismiss_text" msgid="8028337712674081668">"关闭"</string>
+    <string name="notification_content_system_nav_changed" msgid="7218093915747788444">"系统导航已更新。要进行更改,请转到“设置”。"</string>
+    <string name="notification_content_gesture_nav_available" msgid="8111130443656460792">"转到“设置”即可更新系统导航"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-zh-rHK/strings.xml b/packages/SystemUI/res/values-zh-rHK/strings.xml
index 002e40c..814ae2e 100644
--- a/packages/SystemUI/res/values-zh-rHK/strings.xml
+++ b/packages/SystemUI/res/values-zh-rHK/strings.xml
@@ -62,12 +62,10 @@
     <string name="usb_debugging_secondary_user_title" msgid="6353808721761220421">"不允許 USB 偵錯"</string>
     <string name="usb_debugging_secondary_user_message" msgid="6067122453571699801">"目前登入此裝置的使用者無法啟用 USB 偵錯功能。如要使用此功能,請切換至主要使用者。"</string>
     <string name="usb_contaminant_title" msgid="206854874263058490">"已停用 USB 連接埠"</string>
-    <!-- no translation found for usb_contaminant_message (7379089091591609111) -->
-    <skip />
+    <string name="usb_contaminant_message" msgid="7379089091591609111">"為了保護您的裝置免受液體或碎片損害,USB 連接埠已停用,因此不會偵測到任何配件。\n\nUSB 連接埠可安全使用時,您會收到通知。"</string>
     <string name="usb_port_enabled" msgid="7906141351687694867">"已啟用 USB 連接埠以偵測充電器和配件"</string>
     <string name="usb_disable_contaminant_detection" msgid="2103905315747120033">"啟用 USB"</string>
-    <!-- no translation found for learn_more (5000517160980853569) -->
-    <skip />
+    <string name="learn_more" msgid="5000517160980853569">"瞭解詳情"</string>
     <string name="compat_mode_on" msgid="6623839244840638213">"放大為全螢幕"</string>
     <string name="compat_mode_off" msgid="4434467572461327898">"放大為全螢幕"</string>
     <string name="global_action_screenshot" msgid="8329831278085426283">"螢幕截圖"</string>
@@ -199,6 +197,7 @@
     <string name="carrier_network_change_mode" msgid="8149202439957837762">"流動網絡供應商網絡正在變更"</string>
     <string name="accessibility_battery_details" msgid="7645516654955025422">"開啟電池詳細資料"</string>
     <string name="accessibility_battery_level" msgid="7451474187113371965">"電池電量為百分之 <xliff:g id="NUMBER">%d</xliff:g>。"</string>
+    <string name="accessibility_battery_level_with_estimate" msgid="9033100930684311630">"電量仲剩番 <xliff:g id="PERCENTAGE">%1$s</xliff:g>。根據你嘅使用情況,仲可以用大約 <xliff:g id="TIME">%2$s</xliff:g>"</string>
     <string name="accessibility_battery_level_charging" msgid="1147587904439319646">"正在充電:<xliff:g id="BATTERY_PERCENTAGE">%d</xliff:g>%%。"</string>
     <string name="accessibility_settings_button" msgid="799583911231893380">"系統設定"</string>
     <string name="accessibility_notifications_button" msgid="4498000369779421892">"通知。"</string>
@@ -458,10 +457,8 @@
     <string name="media_projection_remember_text" msgid="3103510882172746752">"不用再顯示"</string>
     <string name="clear_all_notifications_text" msgid="814192889771462828">"全部清除"</string>
     <string name="manage_notifications_text" msgid="2386728145475108753">"管理"</string>
-    <!-- no translation found for notification_section_header_gentle (4372438504154095677) -->
-    <skip />
-    <!-- no translation found for accessibility_notification_section_header_gentle_clear_all (4286716295850400959) -->
-    <skip />
+    <string name="notification_section_header_gentle" msgid="4372438504154095677">"靜音通知"</string>
+    <string name="accessibility_notification_section_header_gentle_clear_all" msgid="4286716295850400959">"清除所有靜音通知"</string>
     <string name="dnd_suppressing_shade_text" msgid="1904574852846769301">"「請勿騷擾」模式已將通知暫停"</string>
     <string name="media_projection_action_text" msgid="8470872969457985954">"立即開始"</string>
     <string name="empty_shade_text" msgid="708135716272867002">"沒有通知"</string>
@@ -645,21 +642,16 @@
     <string name="inline_block_button" msgid="8735843688021655065">"封鎖"</string>
     <string name="inline_keep_button" msgid="6665940297019018232">"繼續顯示"</string>
     <string name="inline_minimize_button" msgid="966233327974702195">"最小化"</string>
-    <!-- no translation found for inline_silent_button_silent (5315879183296940969) -->
-    <skip />
+    <string name="inline_silent_button_silent" msgid="5315879183296940969">"靜音"</string>
     <string name="inline_silent_button_stay_silent" msgid="6308371431217601009">"保持靜音"</string>
-    <!-- no translation found for inline_silent_button_alert (6008435419895088034) -->
-    <skip />
+    <string name="inline_silent_button_alert" msgid="6008435419895088034">"發出提醒"</string>
     <string name="inline_silent_button_keep_alerting" msgid="327696842264359693">"繼續提示"</string>
     <string name="inline_turn_off_notifications" msgid="8635596135532202355">"關閉通知"</string>
     <string name="inline_keep_showing_app" msgid="1723113469580031041">"要繼續顯示此應用程式的通知嗎?"</string>
-    <string name="notification_silence_title" msgid="7352089096356977930">"低重要性"</string>
-    <string name="notification_alert_title" msgid="3966526305405016221">"優先"</string>
-    <string name="notification_channel_summary_low" msgid="1065819618107531284">"協助您只查看下拉式通知欄中的通知。一律靜音。"</string>
-    <string name="notification_channel_summary_low_status" msgid="2702170424808743755">"顯示不重要的通知。一律靜音。"</string>
-    <string name="notification_channel_summary_low_lock" msgid="7966605244472624458">"顯示不重要的通知。一律靜音。"</string>
-    <string name="notification_channel_summary_low_status_lock" msgid="7012562768950012739">"顯示不重要的通知。一律靜音。"</string>
-    <string name="notification_channel_summary_default" msgid="3847289783382316019">"透過聲音和狀態列圖示引起您的注意,並在上鎖畫面顯示。"</string>
+    <string name="notification_silence_title" msgid="5763240612242137433">"靜音"</string>
+    <string name="notification_alert_title" msgid="8031196611815490340">"發出提醒"</string>
+    <string name="notification_channel_summary_low" msgid="3387466082089715555">"助您保持專注,不會發出聲音或震動。"</string>
+    <string name="notification_channel_summary_default" msgid="5994062840431965586">"發出聲音或震動來吸引您的注意。"</string>
     <string name="notification_unblockable_desc" msgid="4556908766584964102">"無法修改這些通知。"</string>
     <string name="notification_multichannel_desc" msgid="4695920306092240550">"無法在此設定這組通知"</string>
     <string name="notification_delegate_header" msgid="2857691673814814270">"代理通知"</string>
@@ -908,8 +900,7 @@
     <string name="slice_permission_allow" msgid="2340244901366722709">"允許"</string>
     <string name="slice_permission_deny" msgid="7683681514008048807">"拒絕"</string>
     <string name="auto_saver_title" msgid="1217959994732964228">"輕按即可預定省電模式自動開啟時間"</string>
-    <!-- no translation found for auto_saver_text (2563289953551438248) -->
-    <skip />
+    <string name="auto_saver_text" msgid="2563289953551438248">"在電池電量可能耗盡前啟用「省電模式」"</string>
     <string name="no_auto_saver_action" msgid="8086002101711328500">"不用了,謝謝"</string>
     <string name="auto_saver_enabled_title" msgid="6726474226058316862">"已預定省電模式開啟時間"</string>
     <string name="auto_saver_enabled_text" msgid="874711029884777579">"省電模式將會在電量低於 <xliff:g id="PERCENTAGE">%d</xliff:g>%% 時自動開啟。"</string>
@@ -942,4 +933,6 @@
     <string name="bubble_accessibility_action_move_bottom_left" msgid="206369104473183217">"移去左下角"</string>
     <string name="bubble_accessibility_action_move_bottom_right" msgid="8705660152384312329">"移去右下角"</string>
     <string name="bubble_dismiss_text" msgid="8028337712674081668">"關閉"</string>
+    <string name="notification_content_system_nav_changed" msgid="7218093915747788444">"系統導覽已更新。如需變更,請前往「設定」。"</string>
+    <string name="notification_content_gesture_nav_available" msgid="8111130443656460792">"前往「設定」更新系統導覽"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-zh-rTW/strings.xml b/packages/SystemUI/res/values-zh-rTW/strings.xml
index 3824e23..029e00f 100644
--- a/packages/SystemUI/res/values-zh-rTW/strings.xml
+++ b/packages/SystemUI/res/values-zh-rTW/strings.xml
@@ -62,12 +62,10 @@
     <string name="usb_debugging_secondary_user_title" msgid="6353808721761220421">"無權使用 USB 偵錯功能"</string>
     <string name="usb_debugging_secondary_user_message" msgid="6067122453571699801">"目前登入這個裝置的使用者無法啟用 USB 偵錯功能。如要使用這項功能,請切換到主要使用者。"</string>
     <string name="usb_contaminant_title" msgid="206854874263058490">"USB 連接埠已停用"</string>
-    <!-- no translation found for usb_contaminant_message (7379089091591609111) -->
-    <skip />
+    <string name="usb_contaminant_message" msgid="7379089091591609111">"為了避免液體或灰塵導致你的裝置受損,系統已停用 USB 連接埠,因此目前無法偵測任何配件。\n\n系統會在可繼續使用 USB 連接埠時通知你。"</string>
     <string name="usb_port_enabled" msgid="7906141351687694867">"USB 通訊埠已啟用,可偵測充電器和配件"</string>
     <string name="usb_disable_contaminant_detection" msgid="2103905315747120033">"啟用 USB 連接埠"</string>
-    <!-- no translation found for learn_more (5000517160980853569) -->
-    <skip />
+    <string name="learn_more" msgid="5000517160980853569">"瞭解詳情"</string>
     <string name="compat_mode_on" msgid="6623839244840638213">"放大為全螢幕"</string>
     <string name="compat_mode_off" msgid="4434467572461327898">"放大為全螢幕"</string>
     <string name="global_action_screenshot" msgid="8329831278085426283">"擷取螢幕畫面"</string>
@@ -199,6 +197,7 @@
     <string name="carrier_network_change_mode" msgid="8149202439957837762">"電信業者網路正在進行變更"</string>
     <string name="accessibility_battery_details" msgid="7645516654955025422">"開啟電量詳細資料"</string>
     <string name="accessibility_battery_level" msgid="7451474187113371965">"電池電量為百分之 <xliff:g id="NUMBER">%d</xliff:g>。"</string>
+    <string name="accessibility_battery_level_with_estimate" msgid="9033100930684311630">"目前的電量為 <xliff:g id="PERCENTAGE">%1$s</xliff:g>。根據你的使用情形,大約還能使用到<xliff:g id="TIME">%2$s</xliff:g>"</string>
     <string name="accessibility_battery_level_charging" msgid="1147587904439319646">"充電中,已完成 <xliff:g id="BATTERY_PERCENTAGE">%d</xliff:g>%%。"</string>
     <string name="accessibility_settings_button" msgid="799583911231893380">"系統設定"</string>
     <string name="accessibility_notifications_button" msgid="4498000369779421892">"通知。"</string>
@@ -458,10 +457,8 @@
     <string name="media_projection_remember_text" msgid="3103510882172746752">"不要再顯示"</string>
     <string name="clear_all_notifications_text" msgid="814192889771462828">"全部清除"</string>
     <string name="manage_notifications_text" msgid="2386728145475108753">"管理"</string>
-    <!-- no translation found for notification_section_header_gentle (4372438504154095677) -->
-    <skip />
-    <!-- no translation found for accessibility_notification_section_header_gentle_clear_all (4286716295850400959) -->
-    <skip />
+    <string name="notification_section_header_gentle" msgid="4372438504154095677">"無聲通知"</string>
+    <string name="accessibility_notification_section_header_gentle_clear_all" msgid="4286716295850400959">"清除所有無聲通知"</string>
     <string name="dnd_suppressing_shade_text" msgid="1904574852846769301">"「零打擾」模式已將通知設為暫停"</string>
     <string name="media_projection_action_text" msgid="8470872969457985954">"立即開始"</string>
     <string name="empty_shade_text" msgid="708135716272867002">"沒有通知"</string>
@@ -645,21 +642,16 @@
     <string name="inline_block_button" msgid="8735843688021655065">"封鎖"</string>
     <string name="inline_keep_button" msgid="6665940297019018232">"繼續顯示"</string>
     <string name="inline_minimize_button" msgid="966233327974702195">"最小化"</string>
-    <!-- no translation found for inline_silent_button_silent (5315879183296940969) -->
-    <skip />
+    <string name="inline_silent_button_silent" msgid="5315879183296940969">"無聲"</string>
     <string name="inline_silent_button_stay_silent" msgid="6308371431217601009">"繼續顯示通知但不發出音效"</string>
-    <!-- no translation found for inline_silent_button_alert (6008435419895088034) -->
-    <skip />
+    <string name="inline_silent_button_alert" msgid="6008435419895088034">"快訊"</string>
     <string name="inline_silent_button_keep_alerting" msgid="327696842264359693">"繼續顯示通知"</string>
     <string name="inline_turn_off_notifications" msgid="8635596135532202355">"關閉通知"</string>
     <string name="inline_keep_showing_app" msgid="1723113469580031041">"要繼續顯示這個應用程式的通知嗎?"</string>
-    <string name="notification_silence_title" msgid="7352089096356977930">"無聲通知"</string>
-    <string name="notification_alert_title" msgid="3966526305405016221">"已設為優先"</string>
-    <string name="notification_channel_summary_low" msgid="1065819618107531284">"只會在下拉式通知欄中顯示通知,且一律不發出音效。"</string>
-    <string name="notification_channel_summary_low_status" msgid="2702170424808743755">"顯示在優先通知下方,且一律不發出音效。"</string>
-    <string name="notification_channel_summary_low_lock" msgid="7966605244472624458">"顯示在優先通知下方,且一律不發出音效。"</string>
-    <string name="notification_channel_summary_low_status_lock" msgid="7012562768950012739">"顯示在優先通知下方,且一律不發出音效。"</string>
-    <string name="notification_channel_summary_default" msgid="3847289783382316019">"發出音效並顯示「狀態列」圖示吸引你的注意力。這類通知會顯示在螢幕鎖定畫面上。"</string>
+    <string name="notification_silence_title" msgid="5763240612242137433">"靜音"</string>
+    <string name="notification_alert_title" msgid="8031196611815490340">"快訊"</string>
+    <string name="notification_channel_summary_low" msgid="3387466082089715555">"協助你不受音效或震動干擾。"</string>
+    <string name="notification_channel_summary_default" msgid="5994062840431965586">"發出音效或震動吸引你的注意力。"</string>
     <string name="notification_unblockable_desc" msgid="4556908766584964102">"無法修改這些通知。"</string>
     <string name="notification_multichannel_desc" msgid="4695920306092240550">"無法在這裡設定這個通知群組"</string>
     <string name="notification_delegate_header" msgid="2857691673814814270">"經過 Proxy 處理的通知"</string>
@@ -726,7 +718,7 @@
     <string name="keyboard_key_num_lock" msgid="5052537581246772117">"Num Lock 鍵"</string>
     <string name="keyboard_key_numpad_template" msgid="8729216555174634026">"數字鍵 <xliff:g id="NAME">%1$s</xliff:g>"</string>
     <string name="keyboard_shortcut_group_system" msgid="6472647649616541064">"系統"</string>
-    <string name="keyboard_shortcut_group_system_home" msgid="3054369431319891965">"主畫面"</string>
+    <string name="keyboard_shortcut_group_system_home" msgid="3054369431319891965">"主螢幕"</string>
     <string name="keyboard_shortcut_group_system_recents" msgid="3154851905021926744">"最近"</string>
     <string name="keyboard_shortcut_group_system_back" msgid="2207004531216446378">"返回"</string>
     <string name="keyboard_shortcut_group_system_notifications" msgid="8366964080041773224">"通知"</string>
@@ -908,8 +900,7 @@
     <string name="slice_permission_allow" msgid="2340244901366722709">"允許"</string>
     <string name="slice_permission_deny" msgid="7683681514008048807">"拒絕"</string>
     <string name="auto_saver_title" msgid="1217959994732964228">"輕觸即可排定節約耗電量模式自動開啟的情況"</string>
-    <!-- no translation found for auto_saver_text (2563289953551438248) -->
-    <skip />
+    <string name="auto_saver_text" msgid="2563289953551438248">"在電池電量即將耗盡時開啟"</string>
     <string name="no_auto_saver_action" msgid="8086002101711328500">"不用了,謝謝"</string>
     <string name="auto_saver_enabled_title" msgid="6726474226058316862">"已按照排定開啟節約耗電量模式"</string>
     <string name="auto_saver_enabled_text" msgid="874711029884777579">"節約耗電量模式會在電量低於 <xliff:g id="PERCENTAGE">%d</xliff:g>%% 時自動開啟。"</string>
@@ -942,4 +933,6 @@
     <string name="bubble_accessibility_action_move_bottom_left" msgid="206369104473183217">"移至左下方"</string>
     <string name="bubble_accessibility_action_move_bottom_right" msgid="8705660152384312329">"移至右下方"</string>
     <string name="bubble_dismiss_text" msgid="8028337712674081668">"關閉"</string>
+    <string name="notification_content_system_nav_changed" msgid="7218093915747788444">"系統操作機制已更新。如要進行變更,請前往「設定」。"</string>
+    <string name="notification_content_gesture_nav_available" msgid="8111130443656460792">"請前往「設定」更新系統操作機制"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-zu/strings.xml b/packages/SystemUI/res/values-zu/strings.xml
index 30b2e6e..8447ef8 100644
--- a/packages/SystemUI/res/values-zu/strings.xml
+++ b/packages/SystemUI/res/values-zu/strings.xml
@@ -197,6 +197,7 @@
     <string name="carrier_network_change_mode" msgid="8149202439957837762">"Inethiwekhi yenkampani yenethiwekhi iyashintsha"</string>
     <string name="accessibility_battery_details" msgid="7645516654955025422">"Vula imininingwane yebhethri"</string>
     <string name="accessibility_battery_level" msgid="7451474187113371965">"Iphesenti <xliff:g id="NUMBER">%d</xliff:g> lebhethri"</string>
+    <string name="accessibility_battery_level_with_estimate" msgid="9033100930684311630">"Amaphesenti ebhethri ngu-<xliff:g id="PERCENTAGE">%1$s</xliff:g>, cishe kusele okungu-<xliff:g id="TIME">%2$s</xliff:g> kusukela ekusetshenzisweni kwakho"</string>
     <string name="accessibility_battery_level_charging" msgid="1147587904439319646">"Ibhethri liyashaja, <xliff:g id="BATTERY_PERCENTAGE">%d</xliff:g> iphesenti."</string>
     <string name="accessibility_settings_button" msgid="799583911231893380">"Izilungiselelo zesistimu"</string>
     <string name="accessibility_notifications_button" msgid="4498000369779421892">"Izaziso"</string>
@@ -647,13 +648,10 @@
     <string name="inline_silent_button_keep_alerting" msgid="327696842264359693">"Qhubeka wazise"</string>
     <string name="inline_turn_off_notifications" msgid="8635596135532202355">"Vala izaziso"</string>
     <string name="inline_keep_showing_app" msgid="1723113469580031041">"Qhubeka nokubonisa izaziso kusuka kulolu hlelo lokusebenza?"</string>
-    <string name="notification_silence_title" msgid="7352089096356977930">"Okumnene"</string>
-    <string name="notification_alert_title" msgid="3966526305405016221">"Okwenziwe kwabaluleka"</string>
-    <string name="notification_channel_summary_low" msgid="1065819618107531284">"Ikusiza ukuthi ugxile ngezaziso kuphela kumthunzi wokudonsela phansi. Ihlala ithulile."</string>
-    <string name="notification_channel_summary_low_status" msgid="2702170424808743755">"Ibonisa izaziso ezibalulekile ezingezansi. Ihlala ithulile."</string>
-    <string name="notification_channel_summary_low_lock" msgid="7966605244472624458">"Ibonisa izaziso ezibalulekile ezingezansi. Ihlala ithulile."</string>
-    <string name="notification_channel_summary_low_status_lock" msgid="7012562768950012739">"Ibonisa izaziso ezibalulekile ezingezansi. Ihlala ithulile."</string>
-    <string name="notification_channel_summary_default" msgid="3847289783382316019">"Yenza uyinake ngomsindo nesithonjana sebha yesimo. Iboniswa kusikrini sokukhiya."</string>
+    <string name="notification_silence_title" msgid="5763240612242137433">"Kuthulile"</string>
+    <string name="notification_alert_title" msgid="8031196611815490340">"Iyazisa"</string>
+    <string name="notification_channel_summary_low" msgid="3387466082089715555">"Ikusiza ukuthi ugxile ngaphandle komsindo noma ukudlidliza."</string>
+    <string name="notification_channel_summary_default" msgid="5994062840431965586">"Ithola ukunaka kwakho ngomsindo noma ukudlidliza."</string>
     <string name="notification_unblockable_desc" msgid="4556908766584964102">"Lezi zaziso azikwazi ukushintshwa."</string>
     <string name="notification_multichannel_desc" msgid="4695920306092240550">"Leli qembu lezaziso alikwazi ukulungiselelwa lapha"</string>
     <string name="notification_delegate_header" msgid="2857691673814814270">"Isaziso sommeli"</string>
@@ -935,4 +933,6 @@
     <string name="bubble_accessibility_action_move_bottom_left" msgid="206369104473183217">"Hambisa inkinobho ngakwesokunxele"</string>
     <string name="bubble_accessibility_action_move_bottom_right" msgid="8705660152384312329">"Hambisa inkinobho ngakwesokudla"</string>
     <string name="bubble_dismiss_text" msgid="8028337712674081668">"Cashisa"</string>
+    <string name="notification_content_system_nav_changed" msgid="7218093915747788444">"Ukuzulazula kwesistimu kubuyekeziwe. Ukuze wenze ushintsho, hamba kokuthi Izilungiselelo."</string>
+    <string name="notification_content_gesture_nav_available" msgid="8111130443656460792">"Hamba kuzilungiselelo ukuze ubuyekeze ukuzulazula kwesistimu"</string>
 </resources>
diff --git a/packages/SystemUI/res/values/styles.xml b/packages/SystemUI/res/values/styles.xml
index b387793..2f1770a 100644
--- a/packages/SystemUI/res/values/styles.xml
+++ b/packages/SystemUI/res/values/styles.xml
@@ -450,7 +450,7 @@
 
     <style name="TextAppearance.NotificationInfo.Secondary">
         <item name="android:textSize">14sp</item>
-        <item name="android:alpha">0.54</item>
+        <item name="android:alpha">0.62</item>
     </style>
 
     <style name="TextAppearance.NotificationInfo.Title">
diff --git a/packages/SystemUI/shared/src/com/android/systemui/shared/plugins/PluginManagerImpl.java b/packages/SystemUI/shared/src/com/android/systemui/shared/plugins/PluginManagerImpl.java
index 7139708..53403aa 100644
--- a/packages/SystemUI/shared/src/com/android/systemui/shared/plugins/PluginManagerImpl.java
+++ b/packages/SystemUI/shared/src/com/android/systemui/shared/plugins/PluginManagerImpl.java
@@ -215,7 +215,7 @@
             Uri uri = intent.getData();
             ComponentName component = ComponentName.unflattenFromString(
                     uri.toString().substring(10));
-            if (mWhitelistedPlugins.contains(component.getPackageName())) {
+            if (isPluginWhitelisted(component)) {
                 // Don't disable whitelisted plugins as they are a part of the OS.
                 return;
             }
@@ -288,7 +288,7 @@
 
     /** Returns class loader specific for the given plugin. */
     public ClassLoader getClassLoader(ApplicationInfo appInfo) {
-        if (!isDebuggable && !mWhitelistedPlugins.contains(appInfo.packageName)) {
+        if (!isDebuggable && !isPluginPackageWhitelisted(appInfo.packageName)) {
             Log.w(TAG, "Cannot get class loader for non-whitelisted plugin. Src:"
                     + appInfo.sourceDir + ", pkg: " + appInfo.packageName);
             return null;
@@ -352,6 +352,34 @@
         }
     }
 
+    private boolean isPluginPackageWhitelisted(String packageName) {
+        for (String componentNameOrPackage : mWhitelistedPlugins) {
+            ComponentName componentName = ComponentName.unflattenFromString(componentNameOrPackage);
+            if (componentName != null) {
+                if (componentName.getPackageName().equals(packageName)) {
+                    return true;
+                }
+            } else if (componentNameOrPackage.equals(packageName)) {
+                return true;
+            }
+        }
+        return false;
+    }
+
+    private boolean isPluginWhitelisted(ComponentName pluginName) {
+        for (String componentNameOrPackage : mWhitelistedPlugins) {
+            ComponentName componentName = ComponentName.unflattenFromString(componentNameOrPackage);
+            if (componentName != null) {
+                if (componentName.equals(pluginName)) {
+                    return true;
+                }
+            } else if (componentNameOrPackage.equals(pluginName.getPackageName())) {
+                return true;
+            }
+        }
+        return false;
+    }
+
     // This allows plugins to include any libraries or copied code they want by only including
     // classes from the plugin library.
     private static class ClassLoaderFilter extends ClassLoader {
diff --git a/packages/SystemUI/shared/src/com/android/systemui/shared/system/ActivityManagerWrapper.java b/packages/SystemUI/shared/src/com/android/systemui/shared/system/ActivityManagerWrapper.java
index 6b07ed8..a2abb4b 100644
--- a/packages/SystemUI/shared/src/com/android/systemui/shared/system/ActivityManagerWrapper.java
+++ b/packages/SystemUI/shared/src/com/android/systemui/shared/system/ActivityManagerWrapper.java
@@ -64,6 +64,7 @@
 
 import java.util.ArrayList;
 import java.util.List;
+import java.util.concurrent.Future;
 import java.util.function.Consumer;
 
 public class ActivityManagerWrapper {
@@ -380,8 +381,8 @@
     /**
      * Requests that the system close any open system windows (including other SystemUI).
      */
-    public void closeSystemWindows(final String reason) {
-        mBackgroundExecutor.submit(new Runnable() {
+    public Future<?> closeSystemWindows(final String reason) {
+        return mBackgroundExecutor.submit(new Runnable() {
             @Override
             public void run() {
                 try {
diff --git a/packages/SystemUI/shared/src/com/android/systemui/shared/system/QuickStepContract.java b/packages/SystemUI/shared/src/com/android/systemui/shared/system/QuickStepContract.java
index cc3a67c..db13ef4 100644
--- a/packages/SystemUI/shared/src/com/android/systemui/shared/system/QuickStepContract.java
+++ b/packages/SystemUI/shared/src/com/android/systemui/shared/system/QuickStepContract.java
@@ -61,12 +61,14 @@
     public static final int SYSUI_STATE_A11Y_BUTTON_CLICKABLE = 1 << 4;
     // The navigation bar a11y button shortcut is available
     public static final int SYSUI_STATE_A11Y_BUTTON_LONG_CLICKABLE = 1 << 5;
-    // The keyguard is showing
+    // The keyguard is showing and not occluded
     public static final int SYSUI_STATE_STATUS_BAR_KEYGUARD_SHOWING = 1 << 6;
     // The recents feature is disabled (either by SUW/SysUI/device policy)
     public static final int SYSUI_STATE_OVERVIEW_DISABLED = 1 << 7;
     // The home feature is disabled (either by SUW/SysUI/device policy)
     public static final int SYSUI_STATE_HOME_DISABLED = 1 << 8;
+    // The keyguard is showing, but occluded
+    public static final int SYSUI_STATE_STATUS_BAR_KEYGUARD_SHOWING_OCCLUDED = 1 << 9;
 
     @Retention(RetentionPolicy.SOURCE)
     @IntDef({SYSUI_STATE_SCREEN_PINNING,
@@ -76,6 +78,7 @@
             SYSUI_STATE_A11Y_BUTTON_CLICKABLE,
             SYSUI_STATE_A11Y_BUTTON_LONG_CLICKABLE,
             SYSUI_STATE_STATUS_BAR_KEYGUARD_SHOWING,
+            SYSUI_STATE_STATUS_BAR_KEYGUARD_SHOWING_OCCLUDED,
             SYSUI_STATE_OVERVIEW_DISABLED,
             SYSUI_STATE_HOME_DISABLED
     })
@@ -89,6 +92,8 @@
         str.add((flags & SYSUI_STATE_NAV_BAR_HIDDEN) != 0 ? "navbar_hidden" : "");
         str.add((flags & SYSUI_STATE_NOTIFICATION_PANEL_EXPANDED) != 0 ? "notif_visible" : "");
         str.add((flags & SYSUI_STATE_STATUS_BAR_KEYGUARD_SHOWING) != 0 ? "keygrd_visible" : "");
+        str.add((flags & SYSUI_STATE_STATUS_BAR_KEYGUARD_SHOWING_OCCLUDED) != 0
+                ? "keygrd_occluded" : "");
         str.add((flags & SYSUI_STATE_BOUNCER_SHOWING) != 0 ? "bouncer_visible" : "");
         str.add((flags & SYSUI_STATE_A11Y_BUTTON_CLICKABLE) != 0 ? "a11y_click" : "");
         str.add((flags & SYSUI_STATE_A11Y_BUTTON_LONG_CLICKABLE) != 0 ? "a11y_long_click" : "");
@@ -122,13 +127,21 @@
      * disabled.
      */
     public static boolean isAssistantGestureDisabled(int sysuiStateFlags) {
-        // Disable when in screen pinning, immersive, the bouncer is showing, or the notifications
-        // are interactive
+        // Disable when in screen pinning, immersive, the bouncer is showing
         int disableFlags = SYSUI_STATE_SCREEN_PINNING
                 | SYSUI_STATE_NAV_BAR_HIDDEN
-                | SYSUI_STATE_BOUNCER_SHOWING
-                | SYSUI_STATE_NOTIFICATION_PANEL_EXPANDED;
-        return (sysuiStateFlags & disableFlags) != 0;
+                | SYSUI_STATE_BOUNCER_SHOWING;
+        if ((sysuiStateFlags & disableFlags) != 0) {
+            return true;
+        }
+
+        // Disable when notifications are showing (only if unlocked)
+        if ((sysuiStateFlags & SYSUI_STATE_NOTIFICATION_PANEL_EXPANDED) != 0
+                && (sysuiStateFlags & SYSUI_STATE_STATUS_BAR_KEYGUARD_SHOWING) == 0) {
+            return true;
+        }
+
+        return false;
     }
 
     /**
diff --git a/packages/SystemUI/shared/src/com/android/systemui/shared/system/SyncRtSurfaceTransactionApplierCompat.java b/packages/SystemUI/shared/src/com/android/systemui/shared/system/SyncRtSurfaceTransactionApplierCompat.java
index bd7b3d5..9ba21a3 100644
--- a/packages/SystemUI/shared/src/com/android/systemui/shared/system/SyncRtSurfaceTransactionApplierCompat.java
+++ b/packages/SystemUI/shared/src/com/android/systemui/shared/system/SyncRtSurfaceTransactionApplierCompat.java
@@ -22,6 +22,7 @@
 import android.os.Handler;
 import android.os.Handler.Callback;
 import android.os.Message;
+import android.os.Trace;
 import android.view.Surface;
 import android.view.View;
 import android.view.ViewRootImpl;
@@ -95,6 +96,7 @@
                             .sendToTarget();
                     return;
                 }
+                Trace.traceBegin(Trace.TRACE_TAG_VIEW, "Sync transaction frameNumber=" + frame);
                 TransactionCompat t = new TransactionCompat();
                 for (int i = params.length - 1; i >= 0; i--) {
                     SyncRtSurfaceTransactionApplierCompat.SurfaceParams surfaceParams =
@@ -105,6 +107,7 @@
                 }
                 t.setEarlyWakeup();
                 t.apply();
+                Trace.traceEnd(Trace.TRACE_TAG_VIEW);
                 Message.obtain(mApplyHandler, MSG_UPDATE_SEQUENCE_NUMBER, toApplySeqNo, 0)
                         .sendToTarget();
             }
diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardClockSwitch.java b/packages/SystemUI/src/com/android/keyguard/KeyguardClockSwitch.java
index 0bb9e744..7ec1bda 100644
--- a/packages/SystemUI/src/com/android/keyguard/KeyguardClockSwitch.java
+++ b/packages/SystemUI/src/com/android/keyguard/KeyguardClockSwitch.java
@@ -374,7 +374,7 @@
 
     private void updateColors() {
         ColorExtractor.GradientColors colors = mSysuiColorExtractor.getColors(
-                WallpaperManager.FLAG_LOCK, true);
+                WallpaperManager.FLAG_LOCK);
         mSupportsDarkText = colors.supportsDarkText();
         mColorPalette = colors.getColorPalette();
         if (mClockPlugin != null) {
diff --git a/packages/SystemUI/src/com/android/keyguard/clock/AnalogClockController.java b/packages/SystemUI/src/com/android/keyguard/clock/AnalogClockController.java
index f468eca..558ac4b 100644
--- a/packages/SystemUI/src/com/android/keyguard/clock/AnalogClockController.java
+++ b/packages/SystemUI/src/com/android/keyguard/clock/AnalogClockController.java
@@ -130,7 +130,7 @@
         setDarkAmount(1f);
         setTextColor(Color.WHITE);
         ColorExtractor.GradientColors colors = mColorExtractor.getColors(
-                WallpaperManager.FLAG_LOCK, true);
+                WallpaperManager.FLAG_LOCK);
         setColorPalette(colors.supportsDarkText(), colors.getColorPalette());
         onTimeTick();
 
diff --git a/packages/SystemUI/src/com/android/keyguard/clock/BubbleClockController.java b/packages/SystemUI/src/com/android/keyguard/clock/BubbleClockController.java
index 61a6952..bdf9dc4 100644
--- a/packages/SystemUI/src/com/android/keyguard/clock/BubbleClockController.java
+++ b/packages/SystemUI/src/com/android/keyguard/clock/BubbleClockController.java
@@ -130,7 +130,7 @@
         setDarkAmount(1f);
         setTextColor(Color.WHITE);
         ColorExtractor.GradientColors colors = mColorExtractor.getColors(
-                WallpaperManager.FLAG_LOCK, true);
+                WallpaperManager.FLAG_LOCK);
         setColorPalette(colors.supportsDarkText(), colors.getColorPalette());
         onTimeTick();
 
diff --git a/packages/SystemUI/src/com/android/keyguard/clock/DefaultClockController.java b/packages/SystemUI/src/com/android/keyguard/clock/DefaultClockController.java
index ce1f09c..98679ade 100644
--- a/packages/SystemUI/src/com/android/keyguard/clock/DefaultClockController.java
+++ b/packages/SystemUI/src/com/android/keyguard/clock/DefaultClockController.java
@@ -124,7 +124,7 @@
         setDarkAmount(1f);
         setTextColor(Color.WHITE);
         ColorExtractor.GradientColors colors = mColorExtractor.getColors(
-                WallpaperManager.FLAG_LOCK, true);
+                WallpaperManager.FLAG_LOCK);
         setColorPalette(colors.supportsDarkText(), colors.getColorPalette());
         onTimeTick();
 
diff --git a/packages/SystemUI/src/com/android/systemui/CornerHandleView.java b/packages/SystemUI/src/com/android/systemui/CornerHandleView.java
index 691c3f9..54a3635 100644
--- a/packages/SystemUI/src/com/android/systemui/CornerHandleView.java
+++ b/packages/SystemUI/src/com/android/systemui/CornerHandleView.java
@@ -20,8 +20,8 @@
 import android.content.Context;
 import android.graphics.Canvas;
 import android.graphics.Paint;
+import android.graphics.Path;
 import android.graphics.RectF;
-import android.os.SystemProperties;
 import android.util.AttributeSet;
 import android.util.DisplayMetrics;
 import android.view.ContextThemeWrapper;
@@ -34,17 +34,19 @@
  * corners.
  */
 public class CornerHandleView extends View {
-    private static final boolean ALLOW_TUNING = false;
-    private static final int ANGLE_DEGREES = 50;
-    private static final float STROKE_DP = 2.5f;
+    private static final float STROKE_DP_LARGE = 2f;
+    private static final float STROKE_DP_SMALL = 1.95f;
     // Radius to use if none is available.
     private static final int FALLBACK_RADIUS_DP = 15;
+    private static final float MARGIN_DP = 8;
+    private static final int MAX_ARC_DEGREES = 90;
+    // Arc length along the phone's perimeter used to measure the desired angle.
+    private static final float ARC_LENGTH_DP = 31f;
 
     private Paint mPaint;
     private int mLightColor;
     private int mDarkColor;
-    private RectF mOval;
-
+    private Path mPath;
 
     public CornerHandleView(Context context, AttributeSet attrs) {
         super(context, attrs);
@@ -55,18 +57,46 @@
         mPaint.setStrokeCap(Paint.Cap.ROUND);
         mPaint.setStrokeWidth(getStrokePx());
 
-        final int dualToneDarkTheme = Utils.getThemeAttr(mContext,
-                R.attr.darkIconTheme);
-        final int dualToneLightTheme = Utils.getThemeAttr(mContext,
-                R.attr.lightIconTheme);
+        final int dualToneDarkTheme = Utils.getThemeAttr(mContext, R.attr.darkIconTheme);
+        final int dualToneLightTheme = Utils.getThemeAttr(mContext, R.attr.lightIconTheme);
         Context lightContext = new ContextThemeWrapper(mContext, dualToneLightTheme);
         Context darkContext = new ContextThemeWrapper(mContext, dualToneDarkTheme);
-        mLightColor = Utils.getColorAttrDefaultColor(lightContext,
-                R.attr.singleToneColor);
-        mDarkColor = Utils.getColorAttrDefaultColor(darkContext,
-                R.attr.singleToneColor);
+        mLightColor = Utils.getColorAttrDefaultColor(lightContext, R.attr.singleToneColor);
+        mDarkColor = Utils.getColorAttrDefaultColor(darkContext, R.attr.singleToneColor);
 
-        updateOval();
+        updatePath();
+    }
+
+    private void updatePath() {
+        mPath = new Path();
+
+        float marginPx = getMarginPx();
+        float radiusPx = getInnerRadiusPx();
+        float halfStrokePx = getStrokePx() / 2f;
+        float angle = getAngle();
+        float startAngle = 180 + ((90 - angle) / 2);
+        RectF circle = new RectF(marginPx + halfStrokePx,
+                marginPx + halfStrokePx,
+                marginPx + 2 * radiusPx - halfStrokePx,
+                marginPx + 2 * radiusPx - halfStrokePx);
+
+        if (angle >= 90f) {
+            float innerCircumferenceDp = convertPixelToDp(radiusPx * 2 * (float) Math.PI,
+                    mContext);
+            float arcDp = innerCircumferenceDp * getAngle() / 360f;
+            // Add additional "arms" to the two ends of the arc. The length computation is
+            // hand-tuned.
+            float lineLengthPx = convertDpToPixel((ARC_LENGTH_DP - arcDp - MARGIN_DP) / 2,
+                    mContext);
+
+            mPath.moveTo(marginPx + halfStrokePx, marginPx + radiusPx + lineLengthPx);
+            mPath.lineTo(marginPx + halfStrokePx, marginPx + radiusPx);
+            mPath.arcTo(circle, startAngle, angle);
+            mPath.moveTo(marginPx + radiusPx, marginPx + halfStrokePx);
+            mPath.lineTo(marginPx + radiusPx + lineLengthPx, marginPx + halfStrokePx);
+        } else {
+            mPath.arcTo(circle, startAngle, angle);
+        }
     }
 
     /**
@@ -83,50 +113,40 @@
     @Override
     public void onDraw(Canvas canvas) {
         super.onDraw(canvas);
-
-        if (ALLOW_TUNING) {
-            mPaint.setStrokeWidth(getStrokePx());
-            updateOval();
-        }
-
-        canvas.drawArc(mOval, 180 + ((90 - getAngle()) / 2), getAngle(), false,
-                mPaint);
+        canvas.drawPath(mPath, mPaint);
     }
 
-    // TODO(b/133834204): Remove tweaking of corner handles
     private static float convertDpToPixel(float dp, Context context) {
         return dp * ((float) context.getResources().getDisplayMetrics().densityDpi
                 / DisplayMetrics.DENSITY_DEFAULT);
     }
 
-    private void updateOval() {
-        mOval = new RectF(getMarginPx() - (getStrokePx() / 2.f),
-                getMarginPx() - (getStrokePx() / 2.f),
-                getMarginPx() + (2 * (getRadiusPx()) + (getStrokePx() / 2.f)),
-                getMarginPx() + 2 * getRadiusPx() + (getStrokePx() / 2.f));
+    private static float convertPixelToDp(float px, Context context) {
+        return px * DisplayMetrics.DENSITY_DEFAULT
+                / ((float) context.getResources().getDisplayMetrics().densityDpi);
     }
 
-    private int getAngle() {
-        if (ALLOW_TUNING) {
-            return SystemProperties.getInt("CORNER_HANDLE_ANGLE_DEGREES", ANGLE_DEGREES);
-        } else {
-            return ANGLE_DEGREES;
+    private float getAngle() {
+        // Measure a length of ARC_LENGTH_DP along the *screen's* perimeter, get the angle and cap
+        // it at 90.
+        float circumferenceDp = convertPixelToDp((
+                getOuterRadiusPx()) * 2 * (float) Math.PI, mContext);
+        float angleDeg = (ARC_LENGTH_DP / circumferenceDp) * 360;
+        if (angleDeg > MAX_ARC_DEGREES) {
+            angleDeg = MAX_ARC_DEGREES;
         }
+        return angleDeg;
     }
 
-    private int getMarginPx() {
-        // Hand-derived function to map radiusPx to the margin amount.
-        // https://www.wolframalpha.com/input/?i=0.001402+*+x+%5E2%E2%88%920.08661+*+x%2B17.20+from+40+to+180
-        int radius = getRadiusPx();
-        int marginPx = (int) (0.001402f * radius * radius - 0.08661f * radius + 17.2f);
-        if (ALLOW_TUNING) {
-            return SystemProperties.getInt("CORNER_HANDLE_MARGIN_PX", marginPx);
-        } else {
-            return marginPx;
-        }
+    private float getMarginPx() {
+        return convertDpToPixel(MARGIN_DP, mContext);
     }
 
-    private int getRadiusPx() {
+    private float getInnerRadiusPx() {
+        return getOuterRadiusPx() - getMarginPx();
+    }
+
+    private float getOuterRadiusPx() {
         // Attempt to get the bottom corner radius, otherwise fall back on the generic or top
         // values. If none are available, use the FALLBACK_RADIUS_DP.
         int radius = getResources().getDimensionPixelSize(
@@ -142,19 +162,12 @@
         if (radius == 0) {
             radius = (int) convertDpToPixel(FALLBACK_RADIUS_DP, mContext);
         }
-        if (ALLOW_TUNING) {
-            return SystemProperties.getInt("CORNER_HANDLE_RADIUS_PX", radius);
-        } else {
-            return radius;
-        }
+        return radius;
     }
 
-    private int getStrokePx() {
-        if (ALLOW_TUNING) {
-            return SystemProperties.getInt("CORNER_HANDLE_STROKE_PX",
-                    (int) convertDpToPixel(STROKE_DP, getContext()));
-        } else {
-            return (int) convertDpToPixel(STROKE_DP, getContext());
-        }
+    private float getStrokePx() {
+        // Use a slightly smaller stroke if we need to cover the full corner angle.
+        return convertDpToPixel((getAngle() < 90) ? STROKE_DP_LARGE : STROKE_DP_SMALL,
+                getContext());
     }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/Dependency.java b/packages/SystemUI/src/com/android/systemui/Dependency.java
index 7a82402..9f4a4e0 100644
--- a/packages/SystemUI/src/com/android/systemui/Dependency.java
+++ b/packages/SystemUI/src/com/android/systemui/Dependency.java
@@ -48,7 +48,6 @@
 import com.android.systemui.plugins.statusbar.StatusBarStateController;
 import com.android.systemui.power.EnhancedEstimates;
 import com.android.systemui.power.PowerUI;
-import com.android.systemui.privacy.PrivacyItemController;
 import com.android.systemui.recents.OverviewProxyService;
 import com.android.systemui.shared.plugins.PluginManager;
 import com.android.systemui.shared.system.ActivityManagerWrapper;
@@ -287,7 +286,6 @@
     @Inject Lazy<SensorPrivacyManager> mSensorPrivacyManager;
     @Inject Lazy<AutoHideController> mAutoHideController;
     @Inject Lazy<ForegroundServiceNotificationListener> mForegroundServiceNotificationListener;
-    @Inject Lazy<PrivacyItemController> mPrivacyItemController;
     @Inject @Named(BG_LOOPER_NAME) Lazy<Looper> mBgLooper;
     @Inject @Named(BG_HANDLER_NAME) Lazy<Handler> mBgHandler;
     @Inject @Named(MAIN_HANDLER_NAME) Lazy<Handler> mMainHandler;
@@ -472,7 +470,6 @@
         mProviders.put(ForegroundServiceNotificationListener.class,
                 mForegroundServiceNotificationListener::get);
         mProviders.put(ClockManager.class, mClockManager::get);
-        mProviders.put(PrivacyItemController.class, mPrivacyItemController::get);
         mProviders.put(ActivityManagerWrapper.class, mActivityManagerWrapper::get);
         mProviders.put(DevicePolicyManagerWrapper.class, mDevicePolicyManagerWrapper::get);
         mProviders.put(PackageManagerWrapper.class, mPackageManagerWrapper::get);
diff --git a/packages/SystemUI/src/com/android/systemui/ImageWallpaper.java b/packages/SystemUI/src/com/android/systemui/ImageWallpaper.java
index 8484256..e9eda4f 100644
--- a/packages/SystemUI/src/com/android/systemui/ImageWallpaper.java
+++ b/packages/SystemUI/src/com/android/systemui/ImageWallpaper.java
@@ -83,7 +83,7 @@
         @Override
         public void onCreate(SurfaceHolder surfaceHolder) {
             setFixedSizeAllowed(true);
-            setOffsetNotificationsEnabled(false);
+            setOffsetNotificationsEnabled(true);
             updateSurfaceSize();
         }
 
@@ -96,6 +96,12 @@
         }
 
         @Override
+        public void onOffsetsChanged(float xOffset, float yOffset, float xOffsetStep,
+                float yOffsetStep, int xPixelOffset, int yPixelOffset) {
+            mRenderer.updateOffsets(xOffset, yOffset);
+        }
+
+        @Override
         public void onAmbientModeChanged(boolean inAmbientMode, long animationDuration) {
             mRenderer.updateAmbientMode(inAmbientMode,
                     (mNeedTransition || animationDuration != 0) ? animationDuration : 0);
diff --git a/packages/SystemUI/src/com/android/systemui/ScreenDecorations.java b/packages/SystemUI/src/com/android/systemui/ScreenDecorations.java
index 4aaf85a..eff7054 100644
--- a/packages/SystemUI/src/com/android/systemui/ScreenDecorations.java
+++ b/packages/SystemUI/src/com/android/systemui/ScreenDecorations.java
@@ -25,6 +25,9 @@
 import static com.android.systemui.tuner.TunablePadding.FLAG_END;
 import static com.android.systemui.tuner.TunablePadding.FLAG_START;
 
+import android.animation.Animator;
+import android.animation.AnimatorSet;
+import android.animation.ObjectAnimator;
 import android.annotation.Dimension;
 import android.app.ActivityManager;
 import android.app.Fragment;
@@ -49,6 +52,7 @@
 import android.provider.Settings.Secure;
 import android.util.DisplayMetrics;
 import android.util.Log;
+import android.util.MathUtils;
 import android.view.DisplayCutout;
 import android.view.DisplayInfo;
 import android.view.Gravity;
@@ -60,12 +64,9 @@
 import android.view.ViewGroup.LayoutParams;
 import android.view.ViewTreeObserver;
 import android.view.WindowManager;
-import android.view.animation.Animation;
-import android.view.animation.AnimationSet;
-import android.view.animation.OvershootInterpolator;
+import android.view.animation.AccelerateInterpolator;
+import android.view.animation.Interpolator;
 import android.view.animation.PathInterpolator;
-import android.view.animation.ScaleAnimation;
-import android.view.animation.TranslateAnimation;
 import android.widget.FrameLayout;
 import android.widget.ImageView;
 
@@ -77,8 +78,10 @@
 import com.android.systemui.fragments.FragmentHostManager.FragmentListener;
 import com.android.systemui.plugins.qs.QS;
 import com.android.systemui.qs.SecureSetting;
+import com.android.systemui.shared.system.QuickStepContract;
 import com.android.systemui.statusbar.phone.CollapsedStatusBarFragment;
 import com.android.systemui.statusbar.phone.NavigationBarTransitions;
+import com.android.systemui.statusbar.phone.NavigationModeController;
 import com.android.systemui.statusbar.phone.StatusBar;
 import com.android.systemui.tuner.TunablePadding;
 import com.android.systemui.tuner.TunerService;
@@ -125,6 +128,7 @@
     private Handler mHandler;
     private boolean mAssistHintBlocked = false;
     private boolean mIsReceivingNavBarColor = false;
+    private boolean mInGesturalMode;
 
     /**
      * Converts a set of {@link Rect}s into a {@link Region}
@@ -149,6 +153,58 @@
         mHandler.post(this::startOnScreenDecorationsThread);
         setupStatusBarPaddingIfNeeded();
         putComponent(ScreenDecorations.class, this);
+        mInGesturalMode = QuickStepContract.isGesturalMode(
+                Dependency.get(NavigationModeController.class)
+                        .addListener(this::handleNavigationModeChange));
+    }
+
+    @VisibleForTesting
+    void handleNavigationModeChange(int navigationMode) {
+        if (!mHandler.getLooper().isCurrentThread()) {
+            mHandler.post(() -> handleNavigationModeChange(navigationMode));
+            return;
+        }
+        boolean inGesturalMode = QuickStepContract.isGesturalMode(navigationMode);
+        if (mInGesturalMode != inGesturalMode) {
+            mInGesturalMode = inGesturalMode;
+
+            if (mInGesturalMode && mOverlay == null) {
+                setupDecorations();
+                if (mOverlay != null) {
+                    updateLayoutParams();
+                }
+            }
+        }
+    }
+
+    /**
+     * Returns an animator that animates the given view from start to end over durationMs. Start and
+     * end represent total animation progress: 0 is the start, 1 is the end, 1.1 would be an
+     * overshoot.
+     */
+    Animator getHandleAnimator(View view, float start, float end, boolean isLeft, long durationMs,
+            Interpolator interpolator) {
+        // Note that lerp does allow overshoot, in cases where start and end are outside of [0,1].
+        float scaleStart = MathUtils.lerp(2f, 1f, start);
+        float scaleEnd = MathUtils.lerp(2f, 1f, end);
+        Animator scaleX = ObjectAnimator.ofFloat(view, View.SCALE_X, scaleStart, scaleEnd);
+        Animator scaleY = ObjectAnimator.ofFloat(view, View.SCALE_Y, scaleStart, scaleEnd);
+        float translationStart = MathUtils.lerp(0.2f, 0f, start);
+        float translationEnd = MathUtils.lerp(0.2f, 0f, end);
+        int xDirection = isLeft ? -1 : 1;
+        Animator translateX = ObjectAnimator.ofFloat(view, View.TRANSLATION_X,
+                xDirection * translationStart * view.getWidth(),
+                xDirection * translationEnd * view.getWidth());
+        Animator translateY = ObjectAnimator.ofFloat(view, View.TRANSLATION_Y,
+                translationStart * view.getHeight(), translationEnd * view.getHeight());
+
+        AnimatorSet set = new AnimatorSet();
+        set.play(scaleX).with(scaleY);
+        set.play(scaleX).with(translateX);
+        set.play(scaleX).with(translateY);
+        set.setDuration(durationMs);
+        set.setInterpolator(interpolator);
+        return set;
     }
 
     private void fade(View view, boolean fadeIn, boolean isLeft) {
@@ -157,26 +213,29 @@
             view.setAlpha(1f);
             view.setVisibility(View.VISIBLE);
 
-            AnimationSet anim = new AnimationSet(true);
-            anim.setDuration(900);
-
-            Animation scaleAnimation = new ScaleAnimation(2f, 1f, 2f, 1f,
-                    ScaleAnimation.RELATIVE_TO_SELF, 0.5f, ScaleAnimation.RELATIVE_TO_SELF, 0.5f);
-            anim.addAnimation(scaleAnimation);
-            anim.setInterpolator(new PathInterpolator(0.02f, 0.44f, 0.67f, 1.00f));
-
-            Animation translateAnimation = new TranslateAnimation(
-                    TranslateAnimation.RELATIVE_TO_SELF, isLeft ? -0.2f : 0.2f,
-                    TranslateAnimation.RELATIVE_TO_SELF,
-                    0f,
-                    TranslateAnimation.RELATIVE_TO_SELF, 0.2f, TranslateAnimation.RELATIVE_TO_SELF,
-                    0f);
-            anim.addAnimation(translateAnimation);
-            anim.setInterpolator(new OvershootInterpolator());
-            view.startAnimation(anim);
+            // A piecewise spring-like interpolation.
+            // End value in one animator call must match the start value in the next, otherwise
+            // there will be a discontinuity.
+            AnimatorSet anim = new AnimatorSet();
+            Animator first = getHandleAnimator(view, 0, 1.1f, isLeft, 750,
+                    new PathInterpolator(0, 0.45f, .67f, 1f));
+            Interpolator secondInterpolator = new PathInterpolator(0.33f, 0, 0.67f, 1f);
+            Animator second = getHandleAnimator(view, 1.1f, 0.97f, isLeft, 400,
+                    secondInterpolator);
+            Animator third = getHandleAnimator(view, 0.97f, 1.02f, isLeft, 400,
+                    secondInterpolator);
+            Animator fourth = getHandleAnimator(view, 1.02f, 1f, isLeft, 400,
+                    secondInterpolator);
+            anim.play(first).before(second);
+            anim.play(second).before(third);
+            anim.play(third).before(fourth);
+            anim.start();
         } else {
             view.animate().cancel();
-            view.animate().setDuration(400).alpha(0f);
+            view.animate()
+                    .setInterpolator(new AccelerateInterpolator(1.5f))
+                    .setDuration(250)
+                    .alpha(0f);
         }
 
     }
@@ -199,6 +258,10 @@
             return;
         }
 
+        if (mOverlay == null || mBottomOverlay == null) {
+            return;
+        }
+
         if (mAssistHintVisible != visible) {
             mAssistHintVisible = visible;
 
@@ -228,6 +291,7 @@
                     break;
             }
         }
+        updateWindowVisibilities();
     }
 
     /**
@@ -252,11 +316,15 @@
         return thread.getThreadHandler();
     }
 
+    private boolean shouldHostHandles() {
+        return mInGesturalMode;
+    }
+
     private void startOnScreenDecorationsThread() {
         mRotation = RotationUtils.getExactRotation(mContext);
         mWindowManager = mContext.getSystemService(WindowManager.class);
         updateRoundedCornerRadii();
-        if (hasRoundedCorners() || shouldDrawCutout()) {
+        if (hasRoundedCorners() || shouldDrawCutout() || shouldHostHandles()) {
             setupDecorations();
         }
 
@@ -561,7 +629,10 @@
         boolean visibleForCutout = shouldDrawCutout()
                 && overlay.findViewById(R.id.display_cutout).getVisibility() == View.VISIBLE;
         boolean visibleForRoundedCorners = hasRoundedCorners();
-        overlay.setVisibility(visibleForCutout || visibleForRoundedCorners
+        boolean visibleForHandles = overlay.findViewById(R.id.assist_hint_left).getVisibility()
+                == View.VISIBLE || overlay.findViewById(R.id.assist_hint_right).getVisibility()
+                == View.VISIBLE;
+        overlay.setVisibility(visibleForCutout || visibleForRoundedCorners || visibleForHandles
                 ? View.VISIBLE : View.GONE);
     }
 
@@ -684,10 +755,6 @@
                 setSize(mOverlay.findViewById(R.id.right), sizeTop);
                 setSize(mBottomOverlay.findViewById(R.id.left), sizeBottom);
                 setSize(mBottomOverlay.findViewById(R.id.right), sizeBottom);
-                setSize(mOverlay.findViewById(R.id.assist_hint_left), sizeTop * 2);
-                setSize(mOverlay.findViewById(R.id.assist_hint_right), sizeTop * 2);
-                setSize(mBottomOverlay.findViewById(R.id.assist_hint_left), sizeBottom * 2);
-                setSize(mBottomOverlay.findViewById(R.id.assist_hint_right), sizeBottom * 2);
             }
         });
     }
@@ -848,6 +915,7 @@
             if (shouldDrawCutout(getContext()) && hasCutout()) {
                 mBounds.addAll(mInfo.displayCutout.getBoundingRects());
                 localBounds(mBoundingRect);
+                updateGravity();
                 updateBoundingPath();
                 invalidate();
                 newVisible = VISIBLE;
@@ -898,6 +966,18 @@
             }
         }
 
+        private void updateGravity() {
+            LayoutParams lp = getLayoutParams();
+            if (lp instanceof FrameLayout.LayoutParams) {
+                FrameLayout.LayoutParams flp = (FrameLayout.LayoutParams) lp;
+                int newGravity = getGravity(mInfo.displayCutout);
+                if (flp.gravity != newGravity) {
+                    flp.gravity = newGravity;
+                    setLayoutParams(flp);
+                }
+            }
+        }
+
         private boolean hasCutout() {
             final DisplayCutout displayCutout = mInfo.displayCutout;
             if (displayCutout == null) {
@@ -944,21 +1024,25 @@
         }
 
         private void localBounds(Rect out) {
-            final DisplayCutout displayCutout = mInfo.displayCutout;
+            DisplayCutout displayCutout = mInfo.displayCutout;
+            boundsFromDirection(displayCutout, getGravity(displayCutout), out);
+        }
 
+        private int getGravity(DisplayCutout displayCutout) {
             if (mStart) {
                 if (displayCutout.getSafeInsetLeft() > 0) {
-                    boundsFromDirection(displayCutout, Gravity.LEFT, out);
+                    return Gravity.LEFT;
                 } else if (displayCutout.getSafeInsetTop() > 0) {
-                    boundsFromDirection(displayCutout, Gravity.TOP, out);
+                    return Gravity.TOP;
                 }
             } else {
                 if (displayCutout.getSafeInsetRight() > 0) {
-                    boundsFromDirection(displayCutout, Gravity.RIGHT, out);
+                    return Gravity.RIGHT;
                 } else if (displayCutout.getSafeInsetBottom() > 0) {
-                    boundsFromDirection(displayCutout, Gravity.BOTTOM, out);
+                    return Gravity.BOTTOM;
                 }
             }
+            return Gravity.NO_GRAVITY;
         }
 
         @Override
diff --git a/packages/SystemUI/src/com/android/systemui/appops/AppOpsControllerImpl.java b/packages/SystemUI/src/com/android/systemui/appops/AppOpsControllerImpl.java
index 49bd5bd..afb8e74 100644
--- a/packages/SystemUI/src/com/android/systemui/appops/AppOpsControllerImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/appops/AppOpsControllerImpl.java
@@ -20,7 +20,6 @@
 
 import android.app.AppOpsManager;
 import android.content.Context;
-import android.content.pm.PackageManager;
 import android.os.Handler;
 import android.os.Looper;
 import android.os.UserHandle;
@@ -211,59 +210,6 @@
     }
 
     /**
-     * Does the app-op code refer to a user sensitive permission for the specified user id
-     * and package. Only user sensitive permission should be shown to the user by default.
-     *
-     * @param appOpCode The code of the app-op.
-     * @param uid The uid of the user.
-     * @param packageName The name of the package.
-     *
-     * @return {@code true} iff the app-op item is user sensitive
-     */
-    private boolean isUserSensitive(int appOpCode, int uid, String packageName) {
-        String permission = AppOpsManager.opToPermission(appOpCode);
-        if (permission == null) {
-            return false;
-        }
-        int permFlags = mContext.getPackageManager().getPermissionFlags(permission,
-                packageName, UserHandle.getUserHandleForUid(uid));
-        return (permFlags & PackageManager.FLAG_PERMISSION_USER_SENSITIVE_WHEN_GRANTED) != 0;
-    }
-
-    /**
-     * Does the app-op item refer to an operation that should be shown to the user.
-     * Only specficic ops (like SYSTEM_ALERT_WINDOW) or ops that refer to user sensitive
-     * permission should be shown to the user by default.
-     *
-     * @param item The item
-     *
-     * @return {@code true} iff the app-op item should be shown to the user
-     */
-    private boolean isUserVisible(AppOpItem item) {
-        return isUserVisible(item.getCode(), item.getUid(), item.getPackageName());
-    }
-
-
-    /**
-     * Does the app-op, uid and package name, refer to an operation that should be shown to the
-     * user. Only specficic ops (like {@link AppOpsManager.OP_SYSTEM_ALERT_WINDOW}) or
-     * ops that refer to user sensitive permission should be shown to the user by default.
-     *
-     * @param item The item
-     *
-     * @return {@code true} iff the app-op for should be shown to the user
-     */
-    private boolean isUserVisible(int appOpCode, int uid, String packageName) {
-        // currently OP_SYSTEM_ALERT_WINDOW does not correspond to a platform permission
-        // which may be user senstive, so for now always show it to the user.
-        if (appOpCode == AppOpsManager.OP_SYSTEM_ALERT_WINDOW) {
-            return true;
-        }
-
-        return isUserSensitive(appOpCode, uid, packageName);
-    }
-
-    /**
      * Returns a copy of the list containing all the active AppOps that the controller tracks.
      *
      * @return List of active AppOps information
@@ -286,8 +232,8 @@
             final int numActiveItems = mActiveItems.size();
             for (int i = 0; i < numActiveItems; i++) {
                 AppOpItem item = mActiveItems.get(i);
-                if ((userId == UserHandle.USER_ALL || UserHandle.getUserId(item.getUid()) == userId)
-                        && isUserVisible(item)) {
+                if ((userId == UserHandle.USER_ALL
+                        || UserHandle.getUserId(item.getUid()) == userId)) {
                     list.add(item);
                 }
             }
@@ -296,8 +242,8 @@
             final int numNotedItems = mNotedItems.size();
             for (int i = 0; i < numNotedItems; i++) {
                 AppOpItem item = mNotedItems.get(i);
-                if ((userId == UserHandle.USER_ALL || UserHandle.getUserId(item.getUid()) == userId)
-                        && isUserVisible(item)) {
+                if ((userId == UserHandle.USER_ALL
+                        || UserHandle.getUserId(item.getUid()) == userId)) {
                     list.add(item);
                 }
             }
@@ -323,8 +269,7 @@
     }
 
     private void notifySuscribers(int code, int uid, String packageName, boolean active) {
-        if (mCallbacksByCode.containsKey(code)
-                && isUserVisible(code, uid, packageName)) {
+        if (mCallbacksByCode.containsKey(code)) {
             for (Callback cb: mCallbacksByCode.get(code)) {
                 cb.onActiveStateChanged(code, uid, packageName, active);
             }
diff --git a/packages/SystemUI/src/com/android/systemui/assist/AssistHandleBehaviorController.java b/packages/SystemUI/src/com/android/systemui/assist/AssistHandleBehaviorController.java
index 01deb03..002d4f3 100644
--- a/packages/SystemUI/src/com/android/systemui/assist/AssistHandleBehaviorController.java
+++ b/packages/SystemUI/src/com/android/systemui/assist/AssistHandleBehaviorController.java
@@ -20,7 +20,6 @@
 import android.content.Context;
 import android.os.Handler;
 import android.os.SystemClock;
-import android.provider.DeviceConfig;
 import android.util.Log;
 
 import androidx.annotation.Nullable;
@@ -30,11 +29,15 @@
 import com.android.internal.config.sysui.SystemUiDeviceConfigFlags;
 import com.android.keyguard.KeyguardUpdateMonitor;
 import com.android.systemui.Dependency;
+import com.android.systemui.DumpController;
+import com.android.systemui.Dumpable;
 import com.android.systemui.ScreenDecorations;
 import com.android.systemui.SysUiServiceProvider;
 import com.android.systemui.shared.system.QuickStepContract;
 import com.android.systemui.statusbar.phone.NavigationModeController;
 
+import java.io.FileDescriptor;
+import java.io.PrintWriter;
 import java.util.EnumMap;
 import java.util.Map;
 import java.util.concurrent.TimeUnit;
@@ -46,11 +49,11 @@
  * Controls when visual handles for Assistant gesture affordance should be shown or hidden using an
  * {@link AssistHandleBehavior}.
  */
-public final class AssistHandleBehaviorController implements AssistHandleCallbacks {
+public final class AssistHandleBehaviorController implements AssistHandleCallbacks, Dumpable {
 
     private static final String TAG = "AssistHandleBehavior";
 
-    private static final long DEFAULT_SHOWN_FREQUENCY_THRESHOLD_MS = TimeUnit.SECONDS.toMillis(10);
+    private static final long DEFAULT_SHOWN_FREQUENCY_THRESHOLD_MS = 0;
     private static final long DEFAULT_SHOW_AND_GO_DURATION_MS = TimeUnit.SECONDS.toMillis(3);
 
     /**
@@ -63,7 +66,9 @@
     private final AssistUtils mAssistUtils;
     private final Handler mHandler;
     private final Runnable mHideHandles = this::hideHandles;
+    private final Runnable mShowAndGo = this::showAndGoInternal;
     private final Supplier<ScreenDecorations> mScreenDecorationsSupplier;
+    private final PhenotypeHelper mPhenotypeHelper;
     private final Map<AssistHandleBehavior, BehaviorController> mBehaviorMap =
             new EnumMap<>(AssistHandleBehavior.class);
 
@@ -80,7 +85,9 @@
         this(
                 context,
                 assistUtils,
-                handler, () -> SysUiServiceProvider.getComponent(context, ScreenDecorations.class),
+                handler,
+                () -> SysUiServiceProvider.getComponent(context, ScreenDecorations.class),
+                new PhenotypeHelper(),
                 /* testBehavior = */ null);
     }
 
@@ -90,15 +97,18 @@
             AssistUtils assistUtils,
             Handler handler,
             Supplier<ScreenDecorations> screenDecorationsSupplier,
+            PhenotypeHelper phenotypeHelper,
             @Nullable BehaviorController testBehavior) {
         mContext = context;
         mAssistUtils = assistUtils;
         mHandler = handler;
         mScreenDecorationsSupplier = screenDecorationsSupplier;
-
+        mPhenotypeHelper = phenotypeHelper;
         mBehaviorMap.put(AssistHandleBehavior.OFF, new AssistHandleOffBehavior());
         mBehaviorMap.put(AssistHandleBehavior.LIKE_HOME, new AssistHandleLikeHomeBehavior());
-        mBehaviorMap.put(AssistHandleBehavior.REMINDER_EXP, new AssistHandleReminderExpBehavior());
+        mBehaviorMap.put(
+                AssistHandleBehavior.REMINDER_EXP,
+                new AssistHandleReminderExpBehavior(handler, phenotypeHelper));
         if (testBehavior != null) {
             mBehaviorMap.put(AssistHandleBehavior.TEST, testBehavior);
         }
@@ -107,41 +117,55 @@
                 Dependency.get(NavigationModeController.class)
                         .addListener(this::handleNavigationModeChange));
 
-        setBehavior(DeviceConfig.getString(
-                DeviceConfig.NAMESPACE_SYSTEMUI,
-                SystemUiDeviceConfigFlags.ASSIST_HANDLES_BEHAVIOR_MODE,
-                DEFAULT_BEHAVIOR.toString()));
-        DeviceConfig.addOnPropertyChangedListener(
-                DeviceConfig.NAMESPACE_SYSTEMUI,
+        setBehavior(getBehaviorMode());
+        mPhenotypeHelper.addOnPropertiesChangedListener(
                 mHandler::post,
-                (namespace, name, value) -> {
-                    if (SystemUiDeviceConfigFlags.ASSIST_HANDLES_BEHAVIOR_MODE.equals(name)) {
-                        setBehavior(value);
+                (properties) -> {
+                    if (properties.getKeyset().contains(
+                            SystemUiDeviceConfigFlags.ASSIST_HANDLES_BEHAVIOR_MODE)) {
+                        setBehavior(properties.getString(
+                                SystemUiDeviceConfigFlags.ASSIST_HANDLES_BEHAVIOR_MODE, null));
                     }
                 });
+        Dependency.get(DumpController.class).addListener(this);
     }
 
-    @Override
+    @Override // AssistHandleCallbacks
     public void hide() {
-        mHandler.removeCallbacks(mHideHandles);
+        clearPendingCommands();
         mHandler.post(mHideHandles);
     }
 
-    @Override
+    @Override // AssistHandleCallbacks
     public void showAndGo() {
-        mHandler.removeCallbacks(mHideHandles);
-        mHandler.post(() -> {
-            maybeShowHandles(/* ignoreThreshold = */ false);
-            mHandler.postDelayed(mHideHandles, getShowAndGoDuration());
-        });
+        clearPendingCommands();
+        mHandler.post(mShowAndGo);
     }
 
-    @Override
+    private void showAndGoInternal() {
+        maybeShowHandles(/* ignoreThreshold = */ false);
+        mHandler.postDelayed(mHideHandles, getShowAndGoDuration());
+    }
+
+    @Override // AssistHandleCallbacks
+    public void showAndGoDelayed(long delayMs, boolean hideIfShowing) {
+        clearPendingCommands();
+        if (hideIfShowing) {
+            mHandler.post(mHideHandles);
+        }
+        mHandler.postDelayed(mShowAndGo, delayMs);
+    }
+
+    @Override // AssistHandleCallbacks
     public void showAndStay() {
-        mHandler.removeCallbacks(mHideHandles);
+        clearPendingCommands();
         mHandler.post(() -> maybeShowHandles(/* ignoreThreshold = */ true));
     }
 
+    boolean areHandlesShowing() {
+        return mHandlesShowing;
+    }
+
     void onAssistantGesturePerformed() {
         mBehaviorMap.get(mCurrentBehavior).onAssistantGesturePerformed();
     }
@@ -174,37 +198,41 @@
 
     private boolean handlesUnblocked(boolean ignoreThreshold) {
         long timeSinceHidden = SystemClock.elapsedRealtime() - mHandlesLastHiddenAt;
-        boolean notThrottled = ignoreThreshold || timeSinceHidden > getShownFrequencyThreshold();
+        boolean notThrottled = ignoreThreshold || timeSinceHidden >= getShownFrequencyThreshold();
         ComponentName assistantComponent =
                 mAssistUtils.getAssistComponentForUser(KeyguardUpdateMonitor.getCurrentUser());
         return notThrottled && assistantComponent != null;
     }
 
     private long getShownFrequencyThreshold() {
-        return DeviceConfig.getLong(
-                DeviceConfig.NAMESPACE_SYSTEMUI,
+        return mPhenotypeHelper.getLong(
                 SystemUiDeviceConfigFlags.ASSIST_HANDLES_SHOWN_FREQUENCY_THRESHOLD_MS,
                 DEFAULT_SHOWN_FREQUENCY_THRESHOLD_MS);
     }
 
     private long getShowAndGoDuration() {
-        return DeviceConfig.getLong(
-                DeviceConfig.NAMESPACE_SYSTEMUI,
+        return mPhenotypeHelper.getLong(
                 SystemUiDeviceConfigFlags.ASSIST_HANDLES_SHOW_AND_GO_DURATION_MS,
                 DEFAULT_SHOW_AND_GO_DURATION_MS);
     }
 
+    private String getBehaviorMode() {
+        return mPhenotypeHelper.getString(
+                SystemUiDeviceConfigFlags.ASSIST_HANDLES_BEHAVIOR_MODE,
+                DEFAULT_BEHAVIOR.toString());
+    }
+
     private void maybeShowHandles(boolean ignoreThreshold) {
         if (mHandlesShowing) {
             return;
         }
 
         if (handlesUnblocked(ignoreThreshold)) {
-            mHandlesShowing = true;
             ScreenDecorations screenDecorations = mScreenDecorationsSupplier.get();
             if (screenDecorations == null) {
                 Log.w(TAG, "Couldn't show handles, ScreenDecorations unavailable");
             } else {
+                mHandlesShowing = true;
                 screenDecorations.setAssistHintVisible(true);
             }
         }
@@ -215,12 +243,12 @@
             return;
         }
 
-        mHandlesShowing = false;
-        mHandlesLastHiddenAt = SystemClock.elapsedRealtime();
         ScreenDecorations screenDecorations = mScreenDecorationsSupplier.get();
         if (screenDecorations == null) {
             Log.w(TAG, "Couldn't hide handles, ScreenDecorations unavailable");
         } else {
+            mHandlesShowing = false;
+            mHandlesLastHiddenAt = SystemClock.elapsedRealtime();
             screenDecorations.setAssistHintVisible(false);
         }
     }
@@ -240,14 +268,46 @@
         }
     }
 
+    private void clearPendingCommands() {
+        mHandler.removeCallbacks(mHideHandles);
+        mHandler.removeCallbacks(mShowAndGo);
+    }
+
     @VisibleForTesting
     void setInGesturalModeForTest(boolean inGesturalMode) {
         mInGesturalMode = inGesturalMode;
     }
 
+    @Override // Dumpable
+    public void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
+        pw.println("Current AssistHandleBehaviorController State:");
+
+        pw.println("   mHandlesShowing=" + mHandlesShowing);
+        pw.println("   mHandlesLastHiddenAt=" + mHandlesLastHiddenAt);
+        pw.println("   mInGesturalMode=" + mInGesturalMode);
+
+        pw.println("   Phenotype Flags:");
+        pw.println("      "
+                + SystemUiDeviceConfigFlags.ASSIST_HANDLES_SHOW_AND_GO_DURATION_MS
+                + "="
+                + getShowAndGoDuration());
+        pw.println("      "
+                + SystemUiDeviceConfigFlags.ASSIST_HANDLES_SHOWN_FREQUENCY_THRESHOLD_MS
+                + "="
+                + getShownFrequencyThreshold());
+        pw.println("      "
+                + SystemUiDeviceConfigFlags.ASSIST_HANDLES_BEHAVIOR_MODE
+                + "="
+                + getBehaviorMode());
+
+        pw.println("   mCurrentBehavior=" + mCurrentBehavior.toString());
+        mBehaviorMap.get(mCurrentBehavior).dump(pw, "   ");
+    }
+
     interface BehaviorController {
         void onModeActivated(Context context, AssistHandleCallbacks callbacks);
         default void onModeDeactivated() {}
         default void onAssistantGesturePerformed() {}
+        default void dump(PrintWriter pw, String prefix) {}
     }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/assist/AssistHandleCallbacks.java b/packages/SystemUI/src/com/android/systemui/assist/AssistHandleCallbacks.java
index 0577d37..3db861d 100644
--- a/packages/SystemUI/src/com/android/systemui/assist/AssistHandleCallbacks.java
+++ b/packages/SystemUI/src/com/android/systemui/assist/AssistHandleCallbacks.java
@@ -29,6 +29,13 @@
      */
     void showAndGo();
 
+    /**
+     * Same as show and go, but will not do anything until a delay has elapsed.
+     *
+     * Will be cancelled if another command is given during the delay.
+     */
+    void showAndGoDelayed(long delayMs, boolean hideIfShowing);
+
     /** Show the Assistant handles. */
     void showAndStay();
 }
diff --git a/packages/SystemUI/src/com/android/systemui/assist/AssistHandleLikeHomeBehavior.java b/packages/SystemUI/src/com/android/systemui/assist/AssistHandleLikeHomeBehavior.java
index 05e504c..6cf2034 100644
--- a/packages/SystemUI/src/com/android/systemui/assist/AssistHandleLikeHomeBehavior.java
+++ b/packages/SystemUI/src/com/android/systemui/assist/AssistHandleLikeHomeBehavior.java
@@ -26,6 +26,8 @@
 import com.android.systemui.recents.OverviewProxyService;
 import com.android.systemui.shared.system.QuickStepContract;
 
+import java.io.PrintWriter;
+
 /**
  * Assistant Handle behavior that makes Assistant handles show/hide when the home handle is
  * shown/hidden, respectively.
@@ -108,4 +110,12 @@
             mAssistHandleCallbacks.showAndStay();
         }
     }
+
+    @Override
+    public void dump(PrintWriter pw, String prefix) {
+        pw.println("Current AssistHandleLikeHomeBehavior State:");
+
+        pw.println(prefix + "   mIsDozing=" + mIsDozing);
+        pw.println(prefix + "   mIsHomeHandleHiding=" + mIsHomeHandleHiding);
+    }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/assist/AssistHandleReminderExpBehavior.java b/packages/SystemUI/src/com/android/systemui/assist/AssistHandleReminderExpBehavior.java
index 4b6a6dc..909b68b 100644
--- a/packages/SystemUI/src/com/android/systemui/assist/AssistHandleReminderExpBehavior.java
+++ b/packages/SystemUI/src/com/android/systemui/assist/AssistHandleReminderExpBehavior.java
@@ -17,10 +17,14 @@
 package com.android.systemui.assist;
 
 import android.app.ActivityManager;
+import android.content.BroadcastReceiver;
 import android.content.ComponentName;
 import android.content.Context;
+import android.content.Intent;
+import android.content.IntentFilter;
+import android.content.pm.ResolveInfo;
+import android.os.Handler;
 import android.os.SystemClock;
-import android.provider.DeviceConfig;
 import android.provider.Settings;
 
 import androidx.annotation.Nullable;
@@ -31,10 +35,15 @@
 import com.android.systemui.plugins.statusbar.StatusBarStateController;
 import com.android.systemui.recents.OverviewProxyService;
 import com.android.systemui.shared.system.ActivityManagerWrapper;
+import com.android.systemui.shared.system.PackageManagerWrapper;
 import com.android.systemui.shared.system.QuickStepContract;
 import com.android.systemui.shared.system.TaskStackChangeListener;
 import com.android.systemui.statusbar.StatusBarState;
 
+import java.io.PrintWriter;
+import java.time.LocalDate;
+import java.util.ArrayList;
+import java.util.List;
 import java.util.concurrent.TimeUnit;
 
 /**
@@ -46,8 +55,26 @@
 
     private static final String LEARNING_TIME_ELAPSED_KEY = "reminder_exp_learning_time_elapsed";
     private static final String LEARNING_EVENT_COUNT_KEY = "reminder_exp_learning_event_count";
-    private static final long DEFAULT_LEARNING_TIME_MS = TimeUnit.DAYS.toMillis(3);
-    private static final int DEFAULT_LEARNING_COUNT = 3;
+    private static final String LEARNED_HINT_LAST_SHOWN_KEY =
+            "reminder_exp_learned_hint_last_shown";
+    private static final long DEFAULT_LEARNING_TIME_MS = TimeUnit.DAYS.toMillis(200);
+    private static final int DEFAULT_LEARNING_COUNT = 30000;
+    private static final long DEFAULT_SHOW_AND_GO_DELAYED_SHORT_DELAY_MS = 150;
+    private static final long DEFAULT_SHOW_AND_GO_DELAYED_LONG_DELAY_MS =
+            TimeUnit.SECONDS.toMillis(1);
+    private static final long DEFAULT_SHOW_AND_GO_DELAY_RESET_TIMEOUT_MS =
+            TimeUnit.SECONDS.toMillis(3);
+    private static final boolean DEFAULT_SUPPRESS_ON_LOCKSCREEN = false;
+    private static final boolean DEFAULT_SUPPRESS_ON_LAUNCHER = false;
+    private static final boolean DEFAULT_SUPPRESS_ON_APPS = false;
+
+    private static final String[] DEFAULT_HOME_CHANGE_ACTIONS = new String[] {
+            PackageManagerWrapper.ACTION_PREFERRED_ACTIVITY_CHANGED,
+            Intent.ACTION_BOOT_COMPLETED,
+            Intent.ACTION_PACKAGE_ADDED,
+            Intent.ACTION_PACKAGE_CHANGED,
+            Intent.ACTION_PACKAGE_REMOVED
+    };
 
     private final StatusBarStateController.StateListener mStatusBarStateListener =
             new StatusBarStateController.StateListener() {
@@ -64,13 +91,13 @@
     private final TaskStackChangeListener mTaskStackChangeListener =
             new TaskStackChangeListener() {
                 @Override
-                public void onTaskMovedToFront(int taskId) {
-                    handleTaskStackTopChanged(taskId);
+                public void onTaskMovedToFront(ActivityManager.RunningTaskInfo taskInfo) {
+                    handleTaskStackTopChanged(taskInfo.taskId, taskInfo.topActivity);
                 }
 
                 @Override
                 public void onTaskCreated(int taskId, ComponentName componentName) {
-                    handleTaskStackTopChanged(taskId);
+                    handleTaskStackTopChanged(taskId, componentName);
                 }
             };
     private final OverviewProxyService.OverviewProxyListener mOverviewProxyListener =
@@ -85,7 +112,17 @@
                     handleSystemUiStateChanged(sysuiStateFlags);
                 }
             };
+    private final BroadcastReceiver mDefaultHomeBroadcastReceiver = new BroadcastReceiver() {
+        @Override
+        public void onReceive(Context context, Intent intent) {
+            mDefaultHome = getCurrentDefaultHome();
+        }
+    };
+    private final IntentFilter mDefaultHomeIntentFilter;
+    private final Runnable mResetConsecutiveTaskSwitches = this::resetConsecutiveTaskSwitches;
 
+    private final Handler mHandler;
+    private final PhenotypeHelper mPhenotypeHelper;
     private final StatusBarStateController mStatusBarStateController;
     private final ActivityManagerWrapper mActivityManagerWrapper;
     private final OverviewProxyService mOverviewProxyService;
@@ -94,6 +131,8 @@
     private boolean mIsDozing;
     private int mRunningTaskId;
     private boolean mIsNavBarHidden;
+    private boolean mIsLauncherShowing;
+    private int mConsecutiveTaskSwitches;
 
     /** Whether user has learned the gesture. */
     private boolean mIsLearned;
@@ -102,20 +141,31 @@
     private long mLearningTimeElapsed;
     /** Number of successful Assistant invocations while in this behavior. */
     private int mLearningCount;
+    private long mLearnedHintLastShownEpochDay;
 
     @Nullable private Context mContext;
     @Nullable private AssistHandleCallbacks mAssistHandleCallbacks;
+    @Nullable private ComponentName mDefaultHome;
 
-    AssistHandleReminderExpBehavior() {
+    AssistHandleReminderExpBehavior(Handler handler, PhenotypeHelper phenotypeHelper) {
+        mHandler = handler;
+        mPhenotypeHelper = phenotypeHelper;
         mStatusBarStateController = Dependency.get(StatusBarStateController.class);
         mActivityManagerWrapper = ActivityManagerWrapper.getInstance();
         mOverviewProxyService = Dependency.get(OverviewProxyService.class);
+        mDefaultHomeIntentFilter = new IntentFilter();
+        for (String action : DEFAULT_HOME_CHANGE_ACTIONS) {
+            mDefaultHomeIntentFilter.addAction(action);
+        }
     }
 
     @Override
     public void onModeActivated(Context context, AssistHandleCallbacks callbacks) {
         mContext = context;
         mAssistHandleCallbacks = callbacks;
+        mConsecutiveTaskSwitches = 0;
+        mDefaultHome = getCurrentDefaultHome();
+        context.registerReceiver(mDefaultHomeBroadcastReceiver, mDefaultHomeIntentFilter);
         mOnLockscreen = onLockscreen(mStatusBarStateController.getState());
         mIsDozing = mStatusBarStateController.isDozing();
         mStatusBarStateController.addCallback(mStatusBarStateListener);
@@ -128,6 +178,8 @@
                 context.getContentResolver(), LEARNING_TIME_ELAPSED_KEY, /* default = */ 0);
         mLearningCount = Settings.Secure.getInt(
                 context.getContentResolver(), LEARNING_EVENT_COUNT_KEY, /* default = */ 0);
+        mLearnedHintLastShownEpochDay = Settings.Secure.getLong(
+                context.getContentResolver(), LEARNED_HINT_LAST_SHOWN_KEY, /* default = */ 0);
         mLastLearningTimestamp = SystemClock.uptimeMillis();
 
         callbackForCurrentState(/* justUnlocked = */ false);
@@ -137,10 +189,10 @@
     public void onModeDeactivated() {
         mAssistHandleCallbacks = null;
         if (mContext != null) {
-            Settings.Secure.putLong(
-                    mContext.getContentResolver(), LEARNING_TIME_ELAPSED_KEY, mLearningTimeElapsed);
-            Settings.Secure.putInt(
-                    mContext.getContentResolver(), LEARNING_EVENT_COUNT_KEY, mLearningCount);
+            mContext.unregisterReceiver(mDefaultHomeBroadcastReceiver);
+            Settings.Secure.putLong(mContext.getContentResolver(), LEARNING_TIME_ELAPSED_KEY, 0);
+            Settings.Secure.putInt(mContext.getContentResolver(), LEARNING_EVENT_COUNT_KEY, 0);
+            Settings.Secure.putLong(mContext.getContentResolver(), LEARNED_HINT_LAST_SHOWN_KEY, 0);
             mContext = null;
         }
         mStatusBarStateController.removeCallback(mStatusBarStateListener);
@@ -162,12 +214,35 @@
         return (sysuiStateFlags & QuickStepContract.SYSUI_STATE_NAV_BAR_HIDDEN) != 0;
     }
 
+    @Nullable
+    private static ComponentName getCurrentDefaultHome() {
+        List<ResolveInfo> homeActivities = new ArrayList<>();
+        ComponentName defaultHome =
+                PackageManagerWrapper.getInstance().getHomeActivities(homeActivities);
+        if (defaultHome != null) {
+            return defaultHome;
+        }
+
+        int topPriority = Integer.MIN_VALUE;
+        ComponentName topComponent = null;
+        for (ResolveInfo resolveInfo : homeActivities) {
+            if (resolveInfo.priority > topPriority) {
+                topComponent = resolveInfo.activityInfo.getComponentName();
+                topPriority = resolveInfo.priority;
+            } else if (resolveInfo.priority == topPriority) {
+                topComponent = null;
+            }
+        }
+        return topComponent;
+    }
+
     private void handleStatusBarStateChanged(int newState) {
         boolean onLockscreen = onLockscreen(newState);
         if (mOnLockscreen == onLockscreen) {
             return;
         }
 
+        resetConsecutiveTaskSwitches();
         mOnLockscreen = onLockscreen;
         callbackForCurrentState(!onLockscreen);
     }
@@ -177,16 +252,24 @@
             return;
         }
 
+        resetConsecutiveTaskSwitches();
         mIsDozing = isDozing;
         callbackForCurrentState(/* justUnlocked = */ false);
     }
 
-    private void handleTaskStackTopChanged(int taskId) {
-        if (mRunningTaskId == taskId) {
+    private void handleTaskStackTopChanged(int taskId, @Nullable ComponentName taskComponentName) {
+        if (mRunningTaskId == taskId || taskComponentName == null) {
             return;
         }
 
         mRunningTaskId = taskId;
+        mIsLauncherShowing = taskComponentName.equals(mDefaultHome);
+        if (mIsLauncherShowing) {
+            resetConsecutiveTaskSwitches();
+        } else {
+            rescheduleConsecutiveTaskSwitchesReset();
+            mConsecutiveTaskSwitches++;
+        }
         callbackForCurrentState(/* justUnlocked = */ false);
     }
 
@@ -196,11 +279,13 @@
             return;
         }
 
+        resetConsecutiveTaskSwitches();
         mIsNavBarHidden = isNavBarHidden;
         callbackForCurrentState(/* justUnlocked = */ false);
     }
 
     private void handleOverviewShown() {
+        resetConsecutiveTaskSwitches();
         callbackForCurrentState(/* justUnlocked = */ false);
     }
 
@@ -227,7 +312,17 @@
         if (mIsDozing || mIsNavBarHidden || mOnLockscreen) {
             mAssistHandleCallbacks.hide();
         } else if (justUnlocked) {
-            mAssistHandleCallbacks.showAndGo();
+            long currentEpochDay = LocalDate.now().toEpochDay();
+            if (mLearnedHintLastShownEpochDay < currentEpochDay) {
+                if (mContext != null) {
+                    Settings.Secure.putLong(
+                            mContext.getContentResolver(),
+                            LEARNED_HINT_LAST_SHOWN_KEY,
+                            currentEpochDay);
+                }
+                mLearnedHintLastShownEpochDay = currentEpochDay;
+                mAssistHandleCallbacks.showAndGo();
+            }
         }
     }
 
@@ -236,12 +331,28 @@
             return;
         }
 
-        if (mIsDozing || mIsNavBarHidden) {
+        if (mIsDozing || mIsNavBarHidden || isSuppressed()) {
             mAssistHandleCallbacks.hide();
         } else if (mOnLockscreen) {
             mAssistHandleCallbacks.showAndStay();
-        } else {
+        } else if (mIsLauncherShowing) {
             mAssistHandleCallbacks.showAndGo();
+        } else if (mConsecutiveTaskSwitches == 1) {
+            mAssistHandleCallbacks.showAndGoDelayed(
+                    getShowAndGoDelayedShortDelayMs(), /* hideIfShowing = */ false);
+        } else {
+            mAssistHandleCallbacks.showAndGoDelayed(
+                    getShowAndGoDelayedLongDelayMs(), /* hideIfShowing = */ true);
+        }
+    }
+
+    private boolean isSuppressed() {
+        if (mOnLockscreen) {
+            return getSuppressOnLockscreen();
+        } else if (mIsLauncherShowing) {
+            return getSuppressOnLauncher();
+        } else {
+            return getSuppressOnApps();
         }
     }
 
@@ -260,17 +371,114 @@
                 mLearningCount >= getLearningCount() || mLearningTimeElapsed >= getLearningTimeMs();
     }
 
+    private void resetConsecutiveTaskSwitches() {
+        mHandler.removeCallbacks(mResetConsecutiveTaskSwitches);
+        mConsecutiveTaskSwitches = 0;
+    }
+
+    private void rescheduleConsecutiveTaskSwitchesReset() {
+        mHandler.removeCallbacks(mResetConsecutiveTaskSwitches);
+        mHandler.postDelayed(mResetConsecutiveTaskSwitches, getShowAndGoDelayResetTimeoutMs());
+    }
+
     private long getLearningTimeMs() {
-        return DeviceConfig.getLong(
-                DeviceConfig.NAMESPACE_SYSTEMUI,
+        return mPhenotypeHelper.getLong(
                 SystemUiDeviceConfigFlags.ASSIST_HANDLES_LEARN_TIME_MS,
                 DEFAULT_LEARNING_TIME_MS);
     }
 
     private int getLearningCount() {
-        return DeviceConfig.getInt(
-                DeviceConfig.NAMESPACE_SYSTEMUI,
+        return mPhenotypeHelper.getInt(
                 SystemUiDeviceConfigFlags.ASSIST_HANDLES_LEARN_COUNT,
                 DEFAULT_LEARNING_COUNT);
     }
+
+    private long getShowAndGoDelayedShortDelayMs() {
+        return mPhenotypeHelper.getLong(
+                SystemUiDeviceConfigFlags.ASSIST_HANDLES_SHOW_AND_GO_DELAYED_SHORT_DELAY_MS,
+                DEFAULT_SHOW_AND_GO_DELAYED_SHORT_DELAY_MS);
+    }
+
+    private long getShowAndGoDelayedLongDelayMs() {
+        return mPhenotypeHelper.getLong(
+                SystemUiDeviceConfigFlags.ASSIST_HANDLES_SHOW_AND_GO_DELAYED_LONG_DELAY_MS,
+                DEFAULT_SHOW_AND_GO_DELAYED_LONG_DELAY_MS);
+    }
+
+    private long getShowAndGoDelayResetTimeoutMs() {
+        return mPhenotypeHelper.getLong(
+                SystemUiDeviceConfigFlags.ASSIST_HANDLES_SHOW_AND_GO_DELAY_RESET_TIMEOUT_MS,
+                DEFAULT_SHOW_AND_GO_DELAY_RESET_TIMEOUT_MS);
+    }
+
+    private boolean getSuppressOnLockscreen() {
+        return mPhenotypeHelper.getBoolean(
+                SystemUiDeviceConfigFlags.ASSIST_HANDLES_SUPPRESS_ON_LOCKSCREEN,
+                DEFAULT_SUPPRESS_ON_LOCKSCREEN);
+    }
+
+    private boolean getSuppressOnLauncher() {
+        return mPhenotypeHelper.getBoolean(
+                SystemUiDeviceConfigFlags.ASSIST_HANDLES_SUPPRESS_ON_LAUNCHER,
+                DEFAULT_SUPPRESS_ON_LAUNCHER);
+    }
+
+    private boolean getSuppressOnApps() {
+        return mPhenotypeHelper.getBoolean(
+                SystemUiDeviceConfigFlags.ASSIST_HANDLES_SUPPRESS_ON_APPS,
+                DEFAULT_SUPPRESS_ON_APPS);
+    }
+
+    @Override
+    public void dump(PrintWriter pw, String prefix) {
+        pw.println(prefix + "Current AssistHandleReminderExpBehavior State:");
+        pw.println(prefix + "   mOnLockscreen=" + mOnLockscreen);
+        pw.println(prefix + "   mIsDozing=" + mIsDozing);
+        pw.println(prefix + "   mRunningTaskId=" + mRunningTaskId);
+        pw.println(prefix + "   mDefaultHome=" + mDefaultHome);
+        pw.println(prefix + "   mIsNavBarHidden=" + mIsNavBarHidden);
+        pw.println(prefix + "   mIsLauncherShowing=" + mIsLauncherShowing);
+        pw.println(prefix + "   mConsecutiveTaskSwitches=" + mConsecutiveTaskSwitches);
+        pw.println(prefix + "   mIsLearned=" + mIsLearned);
+        pw.println(prefix + "   mLastLearningTimestamp=" + mLastLearningTimestamp);
+        pw.println(prefix + "   mLearningTimeElapsed=" + mLearningTimeElapsed);
+        pw.println(prefix + "   mLearningCount=" + mLearningCount);
+        pw.println(prefix + "   mLearnedHintLastShownEpochDay=" + mLearnedHintLastShownEpochDay);
+        pw.println(
+                prefix + "   mAssistHandleCallbacks present: " + (mAssistHandleCallbacks != null));
+
+        pw.println(prefix + "   Phenotype Flags:");
+        pw.println(prefix + "      "
+                + SystemUiDeviceConfigFlags.ASSIST_HANDLES_LEARN_TIME_MS
+                + "="
+                + getLearningTimeMs());
+        pw.println(prefix + "      "
+                + SystemUiDeviceConfigFlags.ASSIST_HANDLES_LEARN_COUNT
+                + "="
+                + getLearningCount());
+        pw.println(prefix + "      "
+                + SystemUiDeviceConfigFlags.ASSIST_HANDLES_SHOW_AND_GO_DELAYED_SHORT_DELAY_MS
+                + "="
+                + getShowAndGoDelayedShortDelayMs());
+        pw.println(prefix + "      "
+                + SystemUiDeviceConfigFlags.ASSIST_HANDLES_SHOW_AND_GO_DELAYED_LONG_DELAY_MS
+                + "="
+                + getShowAndGoDelayedLongDelayMs());
+        pw.println(prefix + "      "
+                + SystemUiDeviceConfigFlags.ASSIST_HANDLES_SHOW_AND_GO_DELAY_RESET_TIMEOUT_MS
+                + "="
+                + getShowAndGoDelayResetTimeoutMs());
+        pw.println(prefix + "      "
+                + SystemUiDeviceConfigFlags.ASSIST_HANDLES_SUPPRESS_ON_LOCKSCREEN
+                + "="
+                + getSuppressOnLockscreen());
+        pw.println(prefix + "      "
+                + SystemUiDeviceConfigFlags.ASSIST_HANDLES_SUPPRESS_ON_LAUNCHER
+                + "="
+                + getSuppressOnLauncher());
+        pw.println(prefix + "      "
+                + SystemUiDeviceConfigFlags.ASSIST_HANDLES_SUPPRESS_ON_APPS
+                + "="
+                + getSuppressOnApps());
+    }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/assist/AssistManager.java b/packages/SystemUI/src/com/android/systemui/assist/AssistManager.java
index 2fc79d6..67fcd68 100644
--- a/packages/SystemUI/src/com/android/systemui/assist/AssistManager.java
+++ b/packages/SystemUI/src/com/android/systemui/assist/AssistManager.java
@@ -104,6 +104,11 @@
     public static final int INVOCATION_TYPE_QUICK_SEARCH_BAR = 4;
     public static final int INVOCATION_HOME_BUTTON_LONG_PRESS = 5;
 
+    public static final int DISMISS_REASON_INVOCATION_CANCELLED = 1;
+    public static final int DISMISS_REASON_TAP = 2;
+    public static final int DISMISS_REASON_BACK = 3;
+    public static final int DISMISS_REASON_TIMEOUT = 4;
+
     private static final long TIMEOUT_SERVICE = 2500;
     private static final long TIMEOUT_ACTIVITY = 1000;
 
@@ -251,13 +256,14 @@
         if (invocationType == INVOCATION_TYPE_GESTURE) {
             mHandleController.onAssistantGesturePerformed();
         }
-        args.putInt(INVOCATION_PHONE_STATE_KEY, mPhoneStateMonitor.getPhoneState());
+        int phoneState = mPhoneStateMonitor.getPhoneState();
+        args.putInt(INVOCATION_PHONE_STATE_KEY, phoneState);
         args.putLong(INVOCATION_TIME_MS_KEY, SystemClock.uptimeMillis());
         // Logs assistant start with invocation type.
         MetricsLogger.action(
                 new LogMaker(MetricsEvent.ASSISTANT)
-                        .setType(MetricsEvent.TYPE_OPEN).setSubtype(
-                        invocationType));
+                        .setType(MetricsEvent.TYPE_OPEN)
+                        .setSubtype(toLoggingSubType(invocationType, phoneState)));
         startAssistInternal(args, assistComponent, isService);
     }
 
@@ -437,4 +443,19 @@
     public void onLockscreenShown() {
         mAssistUtils.onLockscreenShown();
     }
+
+    /** Returns the logging flags for the given Assistant invocation type. */
+    public int toLoggingSubType(int invocationType) {
+        return toLoggingSubType(invocationType, mPhoneStateMonitor.getPhoneState());
+    }
+
+    private int toLoggingSubType(int invocationType, int phoneState) {
+        // Note that this logic will break if the number of Assistant invocation types exceeds 7.
+        // There are currently 5 invocation types, but we will be migrating to the new logging
+        // framework in the next update.
+        int subType = mHandleController.areHandlesShowing() ? 0 : 1;
+        subType |= invocationType << 1;
+        subType |= phoneState << 4;
+        return subType;
+    }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/assist/PhenotypeHelper.java b/packages/SystemUI/src/com/android/systemui/assist/PhenotypeHelper.java
new file mode 100644
index 0000000..61395f1
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/assist/PhenotypeHelper.java
@@ -0,0 +1,51 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.assist;
+
+import android.provider.DeviceConfig;
+
+import androidx.annotation.Nullable;
+
+import java.util.concurrent.Executor;
+
+class PhenotypeHelper {
+
+    PhenotypeHelper() {}
+
+    long getLong(String name, long defaultValue) {
+        return DeviceConfig.getLong(DeviceConfig.NAMESPACE_SYSTEMUI, name, defaultValue);
+    }
+
+    int getInt(String name, int defaultValue) {
+        return DeviceConfig.getInt(DeviceConfig.NAMESPACE_SYSTEMUI, name, defaultValue);
+    }
+
+    @Nullable
+    String getString(String name, @Nullable String defaultValue) {
+        return DeviceConfig.getString(DeviceConfig.NAMESPACE_SYSTEMUI, name, defaultValue);
+    }
+
+    boolean getBoolean(String name, boolean defaultValue) {
+        return DeviceConfig.getBoolean(DeviceConfig.NAMESPACE_SYSTEMUI, name, defaultValue);
+    }
+
+    void addOnPropertiesChangedListener(
+            Executor executor, DeviceConfig.OnPropertiesChangedListener listener) {
+        DeviceConfig.addOnPropertiesChangedListener(
+                DeviceConfig.NAMESPACE_SYSTEMUI, executor, listener);
+    }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/assist/PhoneStateMonitor.java b/packages/SystemUI/src/com/android/systemui/assist/PhoneStateMonitor.java
index 1fd3089..e73dc4a 100644
--- a/packages/SystemUI/src/com/android/systemui/assist/PhoneStateMonitor.java
+++ b/packages/SystemUI/src/com/android/systemui/assist/PhoneStateMonitor.java
@@ -16,8 +16,6 @@
 
 package com.android.systemui.assist;
 
-import static com.android.systemui.shared.system.PackageManagerWrapper.ACTION_PREFERRED_ACTIVITY_CHANGED;
-
 import android.app.ActivityManager;
 import android.app.KeyguardManager;
 import android.content.BroadcastReceiver;
@@ -25,6 +23,7 @@
 import android.content.Context;
 import android.content.Intent;
 import android.content.IntentFilter;
+import android.content.pm.ResolveInfo;
 
 import androidx.annotation.Nullable;
 
@@ -38,6 +37,7 @@
 import com.android.systemui.statusbar.phone.StatusBar;
 
 import java.util.ArrayList;
+import java.util.List;
 
 /** Class to monitor and report the state of the phone. */
 final class PhoneStateMonitor {
@@ -53,6 +53,14 @@
     private static final int PHONE_STATE_APP_IMMERSIVE = 9;
     private static final int PHONE_STATE_APP_FULLSCREEN = 10;
 
+    private static final String[] DEFAULT_HOME_CHANGE_ACTIONS = new String[] {
+            PackageManagerWrapper.ACTION_PREFERRED_ACTIVITY_CHANGED,
+            Intent.ACTION_BOOT_COMPLETED,
+            Intent.ACTION_PACKAGE_ADDED,
+            Intent.ACTION_PACKAGE_CHANGED,
+            Intent.ACTION_PACKAGE_REMOVED
+    };
+
     private final Context mContext;
     private final StatusBarStateController mStatusBarStateController;
 
@@ -64,14 +72,17 @@
         mStatusBarStateController = Dependency.get(StatusBarStateController.class);
 
         ActivityManagerWrapper activityManagerWrapper = ActivityManagerWrapper.getInstance();
-        mDefaultHome = PackageManagerWrapper.getInstance().getHomeActivities(new ArrayList<>());
+        mDefaultHome = getCurrentDefaultHome();
+        IntentFilter intentFilter = new IntentFilter();
+        for (String action : DEFAULT_HOME_CHANGE_ACTIONS) {
+            intentFilter.addAction(action);
+        }
         mContext.registerReceiver(new BroadcastReceiver() {
             @Override
             public void onReceive(Context context, Intent intent) {
-                mDefaultHome =
-                        PackageManagerWrapper.getInstance().getHomeActivities(new ArrayList<>());
+                mDefaultHome = getCurrentDefaultHome();
             }
-        }, new IntentFilter(ACTION_PREFERRED_ACTIVITY_CHANGED));
+        }, intentFilter);
         mLauncherShowing = isLauncherShowing(activityManagerWrapper.getRunningTask());
         activityManagerWrapper.registerTaskStackListener(new TaskStackChangeListener() {
             @Override
@@ -93,6 +104,28 @@
         return phoneState;
     }
 
+    @Nullable
+    private static ComponentName getCurrentDefaultHome() {
+        List<ResolveInfo> homeActivities = new ArrayList<>();
+        ComponentName defaultHome =
+                PackageManagerWrapper.getInstance().getHomeActivities(homeActivities);
+        if (defaultHome != null) {
+            return defaultHome;
+        }
+
+        int topPriority = Integer.MIN_VALUE;
+        ComponentName topComponent = null;
+        for (ResolveInfo resolveInfo : homeActivities) {
+            if (resolveInfo.priority > topPriority) {
+                topComponent = resolveInfo.activityInfo.getComponentName();
+                topPriority = resolveInfo.priority;
+            } else if (resolveInfo.priority == topPriority) {
+                topComponent = null;
+            }
+        }
+        return topComponent;
+    }
+
     private int getPhoneLockscreenState() {
         if (isDozing()) {
             return PHONE_STATE_AOD1;
diff --git a/packages/SystemUI/src/com/android/systemui/assist/ui/DefaultUiController.java b/packages/SystemUI/src/com/android/systemui/assist/ui/DefaultUiController.java
index b1be811..662de3a 100644
--- a/packages/SystemUI/src/com/android/systemui/assist/ui/DefaultUiController.java
+++ b/packages/SystemUI/src/com/android/systemui/assist/ui/DefaultUiController.java
@@ -16,10 +16,11 @@
 
 package com.android.systemui.assist.ui;
 
+import static com.android.systemui.assist.AssistManager.DISMISS_REASON_INVOCATION_CANCELLED;
+
 import android.animation.Animator;
 import android.animation.AnimatorListenerAdapter;
 import android.animation.ValueAnimator;
-import android.annotation.ColorInt;
 import android.content.Context;
 import android.graphics.PixelFormat;
 import android.metrics.LogMaker;
@@ -50,6 +51,7 @@
     private static final long ANIM_DURATION_MS = 200;
 
     protected final FrameLayout mRoot;
+    protected InvocationLightsView mInvocationLightsView;
 
     private final WindowManager mWindowManager;
     private final WindowManager.LayoutParams mLayoutParams;
@@ -60,7 +62,6 @@
     private float mLastInvocationProgress = 0;
 
     private ValueAnimator mInvocationAnimator = new ValueAnimator();
-    private InvocationLightsView mInvocationLightsView;
 
     public DefaultUiController(Context context) {
         mRoot = new FrameLayout(context);
@@ -91,6 +92,8 @@
 
     @Override // AssistManager.UiController
     public void onInvocationProgress(int type, float progress) {
+        boolean invocationWasInProgress = mInvocationInProgress;
+
         if (progress == 1) {
             animateInvocationCompletion(type, 0);
         } else if (progress == 0) {
@@ -105,16 +108,7 @@
         }
         mLastInvocationProgress = progress;
 
-        // Logs assistant invocation start.
-        if (!mInvocationInProgress && progress > 0.f) {
-            MetricsLogger.action(new LogMaker(MetricsEvent.ASSISTANT)
-                    .setType(MetricsEvent.TYPE_ACTION));
-        }
-        // Logs assistant invocation cancelled.
-        if (mInvocationInProgress && progress == 0f) {
-            MetricsLogger.action(new LogMaker(MetricsEvent.ASSISTANT)
-                    .setType(MetricsEvent.TYPE_DISMISS).setSubtype(0));
-        }
+        logInvocationProgressMetrics(type, progress, invocationWasInProgress);
     }
 
     @Override // AssistManager.UiController
@@ -134,12 +128,20 @@
         updateAssistHandleVisibility();
     }
 
-    /**
-     * Sets the colors of the four invocation lights, from left to right.
-     */
-    public void setInvocationColors(@ColorInt int color1, @ColorInt int color2,
-            @ColorInt int color3, @ColorInt int color4) {
-        mInvocationLightsView.setColors(color1, color2, color3, color4);
+    protected static void logInvocationProgressMetrics(
+            int type, float progress, boolean invocationWasInProgress) {
+        // Logs assistant invocation start.
+        if (!invocationWasInProgress && progress > 0.f) {
+            MetricsLogger.action(new LogMaker(MetricsEvent.ASSISTANT)
+                    .setType(MetricsEvent.TYPE_ACTION)
+                    .setSubtype(Dependency.get(AssistManager.class).toLoggingSubType(type)));
+        }
+        // Logs assistant invocation cancelled.
+        if (invocationWasInProgress && progress == 0f) {
+            MetricsLogger.action(new LogMaker(MetricsEvent.ASSISTANT)
+                    .setType(MetricsEvent.TYPE_DISMISS)
+                    .setSubtype(DISMISS_REASON_INVOCATION_CANCELLED));
+        }
     }
 
     private void updateAssistHandleVisibility() {
diff --git a/packages/SystemUI/src/com/android/systemui/assist/ui/InvocationLightsView.java b/packages/SystemUI/src/com/android/systemui/assist/ui/InvocationLightsView.java
index de1d7c8..178f4c3 100644
--- a/packages/SystemUI/src/com/android/systemui/assist/ui/InvocationLightsView.java
+++ b/packages/SystemUI/src/com/android/systemui/assist/ui/InvocationLightsView.java
@@ -16,24 +16,34 @@
 
 package com.android.systemui.assist.ui;
 
+import android.animation.ArgbEvaluator;
 import android.annotation.ColorInt;
+import android.annotation.Nullable;
 import android.content.Context;
 import android.graphics.Canvas;
+import android.graphics.Color;
 import android.graphics.Paint;
 import android.graphics.Path;
 import android.util.AttributeSet;
 import android.util.Log;
 import android.util.MathUtils;
+import android.view.ContextThemeWrapper;
 import android.view.View;
 
+import com.android.settingslib.Utils;
+import com.android.systemui.Dependency;
 import com.android.systemui.R;
+import com.android.systemui.statusbar.NavigationBarController;
+import com.android.systemui.statusbar.phone.NavigationBarFragment;
+import com.android.systemui.statusbar.phone.NavigationBarTransitions;
 
 import java.util.ArrayList;
 
 /**
  * Shows lights at the bottom of the phone, marking the invocation progress.
  */
-public class InvocationLightsView extends View {
+public class InvocationLightsView extends View
+        implements NavigationBarTransitions.DarkIntensityListener {
 
     private static final String TAG = "InvocationLightsView";
 
@@ -49,9 +59,16 @@
     // allocation on each frame.
     private final Path mPath = new Path();
     private final int mViewHeight;
+    private final int mStrokeWidth;
+    @ColorInt
+    private final int mLightColor;
+    @ColorInt
+    private final int mDarkColor;
 
     // Allocate variable for screen location lookup to avoid memory alloc onDraw()
     private int[] mScreenLocation = new int[2];
+    private boolean mRegistered = false;
+    private boolean mUseNavBarColor = true;
 
     public InvocationLightsView(Context context) {
         this(context, null);
@@ -69,8 +86,8 @@
             int defStyleRes) {
         super(context, attrs, defStyleAttr, defStyleRes);
 
-        int strokeWidth = DisplayUtils.convertDpToPx(LIGHT_HEIGHT_DP, context);
-        mPaint.setStrokeWidth(strokeWidth);
+        mStrokeWidth = DisplayUtils.convertDpToPx(LIGHT_HEIGHT_DP, context);
+        mPaint.setStrokeWidth(mStrokeWidth);
         mPaint.setStyle(Paint.Style.STROKE);
         mPaint.setStrokeJoin(Paint.Join.MITER);
         mPaint.setAntiAlias(true);
@@ -82,13 +99,19 @@
         CircularCornerPathRenderer cornerPathRenderer = new CircularCornerPathRenderer(
                 cornerRadiusBottom, cornerRadiusTop, displayWidth, displayHeight);
         mGuide = new PerimeterPathGuide(context, cornerPathRenderer,
-                strokeWidth / 2, displayWidth, displayHeight);
+                mStrokeWidth / 2, displayWidth, displayHeight);
 
         mViewHeight = Math.max(cornerRadiusBottom, cornerRadiusTop);
 
-        @ColorInt int lightColor = getResources().getColor(R.color.default_invocation_lights_color);
+        final int dualToneDarkTheme = Utils.getThemeAttr(mContext, R.attr.darkIconTheme);
+        final int dualToneLightTheme = Utils.getThemeAttr(mContext, R.attr.lightIconTheme);
+        Context lightContext = new ContextThemeWrapper(mContext, dualToneLightTheme);
+        Context darkContext = new ContextThemeWrapper(mContext, dualToneDarkTheme);
+        mLightColor = Utils.getColorAttrDefaultColor(lightContext, R.attr.singleToneColor);
+        mDarkColor = Utils.getColorAttrDefaultColor(darkContext, R.attr.singleToneColor);
+
         for (int i = 0; i < 4; i++) {
-            mAssistInvocationLights.add(new EdgeLight(lightColor, 0, 0));
+            mAssistInvocationLights.add(new EdgeLight(Color.TRANSPARENT, 0, 0));
         }
     }
 
@@ -100,6 +123,8 @@
         if (progress == 0) {
             setVisibility(View.GONE);
         } else {
+            attemptRegisterNavBarListener();
+
             float cornerLengthNormalized =
                     mGuide.getRegionWidth(PerimeterPathGuide.Region.BOTTOM_LEFT);
             float arcLengthNormalized = cornerLengthNormalized * MINIMUM_CORNER_RATIO;
@@ -131,6 +156,21 @@
         for (EdgeLight light : mAssistInvocationLights) {
             light.setLength(0);
         }
+        attemptUnregisterNavBarListener();
+    }
+
+    /**
+     * Sets all invocation lights to a single color. If color is null, uses the navigation bar
+     * color (updated when the nav bar color changes).
+     */
+    public void setColors(@Nullable @ColorInt Integer color) {
+        if (color == null) {
+            mUseNavBarColor = true;
+            mPaint.setStrokeCap(Paint.Cap.BUTT);
+            attemptRegisterNavBarListener();
+        } else {
+            setColors(color, color, color, color);
+        }
     }
 
     /**
@@ -138,12 +178,25 @@
      */
     public void setColors(@ColorInt int color1, @ColorInt int color2,
             @ColorInt int color3, @ColorInt int color4) {
+        mUseNavBarColor = false;
+        attemptUnregisterNavBarListener();
         mAssistInvocationLights.get(0).setColor(color1);
         mAssistInvocationLights.get(1).setColor(color2);
         mAssistInvocationLights.get(2).setColor(color3);
         mAssistInvocationLights.get(3).setColor(color4);
     }
 
+    /**
+     * Reacts to changes in the navigation bar color
+     *
+     * @param darkIntensity 0 is the lightest color, 1 is the darkest.
+     */
+    @Override // NavigationBarTransitions.DarkIntensityListener
+    public void onDarkIntensity(float darkIntensity) {
+        updateDarkness(darkIntensity);
+    }
+
+
     @Override
     protected void onFinishInflate() {
         getLayoutParams().height = mViewHeight;
@@ -166,15 +219,19 @@
         getLocationOnScreen(mScreenLocation);
         canvas.translate(-mScreenLocation[0], -mScreenLocation[1]);
 
-        // if the lights are different colors, the inner ones need to be drawn last and with a
-        // square cap so that the join between lights is straight
-        mPaint.setStrokeCap(Paint.Cap.ROUND);
-        renderLight(mAssistInvocationLights.get(0), canvas);
-        renderLight(mAssistInvocationLights.get(3), canvas);
+        if (mUseNavBarColor) {
+            for (EdgeLight light : mAssistInvocationLights) {
+                renderLight(light, canvas);
+            }
+        } else {
+            mPaint.setStrokeCap(Paint.Cap.ROUND);
+            renderLight(mAssistInvocationLights.get(0), canvas);
+            renderLight(mAssistInvocationLights.get(3), canvas);
 
-        mPaint.setStrokeCap(Paint.Cap.SQUARE);
-        renderLight(mAssistInvocationLights.get(1), canvas);
-        renderLight(mAssistInvocationLights.get(2), canvas);
+            mPaint.setStrokeCap(Paint.Cap.BUTT);
+            renderLight(mAssistInvocationLights.get(1), canvas);
+            renderLight(mAssistInvocationLights.get(2), canvas);
+        }
     }
 
     protected void setLight(int index, float offset, float length) {
@@ -185,10 +242,58 @@
         mAssistInvocationLights.get(index).setLength(length);
     }
 
+    /**
+     * Receives an intensity from 0 (lightest) to 1 (darkest) and sets the handle color
+     * appropriately. Intention is to match the home handle color.
+     */
+    protected void updateDarkness(float darkIntensity) {
+        if (mUseNavBarColor) {
+            @ColorInt int invocationColor = (int) ArgbEvaluator.getInstance().evaluate(
+                    darkIntensity, mLightColor, mDarkColor);
+            for (EdgeLight light : mAssistInvocationLights) {
+                light.setColor(invocationColor);
+            }
+            invalidate();
+        }
+    }
+
     private void renderLight(EdgeLight light, Canvas canvas) {
         mGuide.strokeSegment(mPath, light.getOffset(), light.getOffset() + light.getLength());
         mPaint.setColor(light.getColor());
         canvas.drawPath(mPath, mPaint);
     }
 
+    private void attemptRegisterNavBarListener() {
+        if (!mRegistered) {
+            NavigationBarController controller = Dependency.get(NavigationBarController.class);
+            if (controller == null) {
+                return;
+            }
+
+            NavigationBarFragment navBar = controller.getDefaultNavigationBarFragment();
+            if (navBar == null) {
+                return;
+            }
+
+            updateDarkness(navBar.getBarTransitions().addDarkIntensityListener(this));
+            mRegistered = true;
+        }
+    }
+
+    private void attemptUnregisterNavBarListener() {
+        if (mRegistered) {
+            NavigationBarController controller = Dependency.get(NavigationBarController.class);
+            if (controller == null) {
+                return;
+            }
+
+            NavigationBarFragment navBar = controller.getDefaultNavigationBarFragment();
+            if (navBar == null) {
+                return;
+            }
+
+            navBar.getBarTransitions().removeDarkIntensityListener(this);
+            mRegistered = false;
+        }
+    }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/BiometricDialogView.java b/packages/SystemUI/src/com/android/systemui/biometrics/BiometricDialogView.java
index 5717a54..18b8a9c 100644
--- a/packages/SystemUI/src/com/android/systemui/biometrics/BiometricDialogView.java
+++ b/packages/SystemUI/src/com/android/systemui/biometrics/BiometricDialogView.java
@@ -228,6 +228,10 @@
             showTryAgainButton(false /* show */);
             mCallback.onTryAgainPressed();
         });
+
+        // Must set these in order for the back button events to be received.
+        mLayout.setFocusableInTouchMode(true);
+        mLayout.requestFocus();
     }
 
     public void onSaveState(Bundle bundle) {
diff --git a/packages/SystemUI/src/com/android/systemui/colorextraction/SysuiColorExtractor.java b/packages/SystemUI/src/com/android/systemui/colorextraction/SysuiColorExtractor.java
index 835ffc9..6f56a53 100644
--- a/packages/SystemUI/src/com/android/systemui/colorextraction/SysuiColorExtractor.java
+++ b/packages/SystemUI/src/com/android/systemui/colorextraction/SysuiColorExtractor.java
@@ -16,18 +16,11 @@
 
 package com.android.systemui.colorextraction;
 
-import android.annotation.ColorInt;
 import android.app.WallpaperColors;
 import android.app.WallpaperManager;
 import android.content.Context;
-import android.os.Handler;
-import android.os.RemoteException;
+import android.graphics.Color;
 import android.os.UserHandle;
-import android.util.Log;
-import android.view.Display;
-import android.view.IWallpaperVisibilityListener;
-import android.view.IWindowManager;
-import android.view.WindowManagerGlobal;
 
 import com.android.internal.annotations.VisibleForTesting;
 import com.android.internal.colorextraction.ColorExtractor;
@@ -52,46 +45,28 @@
         ConfigurationController.ConfigurationListener {
     private static final String TAG = "SysuiColorExtractor";
     private final Tonal mTonal;
-    private boolean mWallpaperVisible;
-    private boolean mHasBackdrop;
-    // Colors to return when the wallpaper isn't visible
-    private final GradientColors mWpHiddenColors;
+    private boolean mHasMediaArtwork;
+    private final GradientColors mNeutralColorsLock;
+    private final GradientColors mBackdropColors;
 
     @Inject
     public SysuiColorExtractor(Context context, ConfigurationController configurationController) {
-        this(context, new Tonal(context), configurationController, true);
+        this(context, new Tonal(context), configurationController,
+                context.getSystemService(WallpaperManager.class), false /* immediately */);
     }
 
     @VisibleForTesting
     public SysuiColorExtractor(Context context, ExtractionType type,
-            ConfigurationController configurationController, boolean registerVisibility) {
-        super(context, type, false /* immediately */);
+            ConfigurationController configurationController,
+            WallpaperManager wallpaperManager, boolean immediately) {
+        super(context, type, immediately, wallpaperManager);
         mTonal = type instanceof Tonal ? (Tonal) type : new Tonal(context);
-        mWpHiddenColors = new GradientColors();
+        mNeutralColorsLock = new GradientColors();
         configurationController.addCallback(this);
 
-        WallpaperColors systemColors = getWallpaperColors(WallpaperManager.FLAG_SYSTEM);
-        updateDefaultGradients(systemColors);
+        mBackdropColors = new GradientColors();
+        mBackdropColors.setMainColor(Color.BLACK);
 
-        if (registerVisibility) {
-            try {
-                IWindowManager windowManagerService = WindowManagerGlobal.getWindowManagerService();
-                Handler handler = Handler.getMain();
-                boolean visible = windowManagerService.registerWallpaperVisibilityListener(
-                        new IWallpaperVisibilityListener.Stub() {
-                            @Override
-                            public void onWallpaperVisibilityChanged(boolean newVisibility,
-                                    int displayId) throws RemoteException {
-                                handler.post(() -> setWallpaperVisible(newVisibility));
-                            }
-                        }, Display.DEFAULT_DISPLAY);
-                setWallpaperVisible(visible);
-            } catch (RemoteException e) {
-                Log.w(TAG, "Can't listen to wallpaper visibility changes", e);
-            }
-        }
-
-        WallpaperManager wallpaperManager = context.getSystemService(WallpaperManager.class);
         if (wallpaperManager != null) {
             // Listen to all users instead of only the current one.
             wallpaperManager.removeOnColorsChangedListener(this);
@@ -100,8 +75,14 @@
         }
     }
 
-    private void updateDefaultGradients(WallpaperColors colors) {
-        mTonal.applyFallback(colors, mWpHiddenColors);
+    @Override
+    protected void extractWallpaperColors() {
+        super.extractWallpaperColors();
+        // mTonal is final but this method will be invoked by the base class during its ctor.
+        if (mTonal == null) {
+            return;
+        }
+        mTonal.applyFallback(mLockColors == null ? mSystemColors : mLockColors, mNeutralColorsLock);
     }
 
     @Override
@@ -110,27 +91,28 @@
             // Colors do not belong to current user, ignoring.
             return;
         }
-
-        super.onColorsChanged(colors, which);
-
-        if ((which & WallpaperManager.FLAG_SYSTEM) != 0) {
-            @ColorInt int oldColor = mWpHiddenColors.getMainColor();
-            updateDefaultGradients(colors);
-            if (oldColor != mWpHiddenColors.getMainColor()) {
-                triggerColorsChanged(WallpaperManager.FLAG_SYSTEM);
-            }
+        if ((which & WallpaperManager.FLAG_LOCK) != 0) {
+            mTonal.applyFallback(colors, mNeutralColorsLock);
         }
+        super.onColorsChanged(colors, which);
     }
 
     @Override
     public void onUiModeChanged() {
-        WallpaperColors systemColors = getWallpaperColors(WallpaperManager.FLAG_SYSTEM);
-        updateDefaultGradients(systemColors);
-        triggerColorsChanged(WallpaperManager.FLAG_SYSTEM);
+        extractWallpaperColors();
+        triggerColorsChanged(WallpaperManager.FLAG_SYSTEM | WallpaperManager.FLAG_LOCK);
+    }
+
+    @Override
+    public GradientColors getColors(int which, int type) {
+        if (mHasMediaArtwork && (which & WallpaperManager.FLAG_LOCK) != 0) {
+            return mBackdropColors;
+        }
+        return super.getColors(which, type);
     }
 
     /**
-     * Colors the should be using for scrims.
+     * Colors that should be using for scrims.
      *
      * They will be:
      * - A light gray if the wallpaper is light
@@ -138,81 +120,12 @@
      * - Black otherwise
      */
     public GradientColors getNeutralColors() {
-        return mWpHiddenColors;
+        return mHasMediaArtwork ? mBackdropColors : mNeutralColorsLock;
     }
 
-    /**
-     * Get TYPE_NORMAL colors when wallpaper is visible, or fallback otherwise.
-     *
-     * @param which FLAG_LOCK or FLAG_SYSTEM
-     * @return colors
-     */
-    @Override
-    public GradientColors getColors(int which) {
-        return getColors(which, TYPE_DARK);
-    }
-
-    /**
-     * Wallpaper colors when the wallpaper is visible, fallback otherwise.
-     *
-     * @param which FLAG_LOCK or FLAG_SYSTEM
-     * @param type TYPE_NORMAL, TYPE_DARK or TYPE_EXTRA_DARK
-     * @return colors
-     */
-    @Override
-    public GradientColors getColors(int which, int type) {
-        return getColors(which, type, false /* ignoreVisibility */);
-    }
-
-    /**
-     * Get TYPE_NORMAL colors, possibly ignoring wallpaper visibility.
-     *
-     * @param which FLAG_LOCK or FLAG_SYSTEM
-     * @param ignoreWallpaperVisibility whether you want fallback colors or not if the wallpaper
-     *                                  isn't visible
-     * @return
-     */
-    public GradientColors getColors(int which, boolean ignoreWallpaperVisibility) {
-        return getColors(which, TYPE_NORMAL, ignoreWallpaperVisibility);
-    }
-
-    /**
-     *
-     * @param which FLAG_LOCK or FLAG_SYSTEM
-     * @param type TYPE_NORMAL, TYPE_DARK or TYPE_EXTRA_DARK
-     * @param ignoreWallpaperVisibility true if true wallpaper colors should be returning
-     *                                  if it's visible or not
-     * @return colors
-     */
-    public GradientColors getColors(int which, int type, boolean ignoreWallpaperVisibility) {
-        // mWallpaperVisible only handles the "system wallpaper" and will be always set to false
-        // if we have different lock and system wallpapers.
-        if (which == WallpaperManager.FLAG_SYSTEM) {
-            if (mWallpaperVisible || ignoreWallpaperVisibility) {
-                return super.getColors(which, type);
-            } else {
-                return mWpHiddenColors;
-            }
-        } else {
-            if (mHasBackdrop) {
-                return mWpHiddenColors;
-            } else {
-                return super.getColors(which, type);
-            }
-        }
-    }
-
-    @VisibleForTesting
-    void setWallpaperVisible(boolean visible) {
-        if (mWallpaperVisible != visible) {
-            mWallpaperVisible = visible;
-            triggerColorsChanged(WallpaperManager.FLAG_SYSTEM);
-        }
-    }
-
-    public void setHasBackdrop(boolean hasBackdrop) {
-        if (mHasBackdrop != hasBackdrop) {
-            mHasBackdrop = hasBackdrop;
+    public void setHasMediaArtwork(boolean hasBackdrop) {
+        if (mHasMediaArtwork != hasBackdrop) {
+            mHasMediaArtwork = hasBackdrop;
             triggerColorsChanged(WallpaperManager.FLAG_LOCK);
         }
     }
@@ -230,7 +143,8 @@
         pw.println("  Gradients:");
         pw.println("    system: " + Arrays.toString(system));
         pw.println("    lock: " + Arrays.toString(lock));
-        pw.println("  Default scrim: " + mWpHiddenColors);
+        pw.println("  Neutral colors: " + mNeutralColorsLock);
+        pw.println("  Has media backdrop: " + mHasMediaArtwork);
 
     }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/doze/DozeSensors.java b/packages/SystemUI/src/com/android/systemui/doze/DozeSensors.java
index 831d074..5f52486 100644
--- a/packages/SystemUI/src/com/android/systemui/doze/DozeSensors.java
+++ b/packages/SystemUI/src/com/android/systemui/doze/DozeSensors.java
@@ -70,11 +70,12 @@
     private final Consumer<Boolean> mProxCallback;
     private final Callback mCallback;
     @VisibleForTesting
-    protected final TriggerSensor[] mSensors;
+    protected TriggerSensor[] mSensors;
 
     private final Handler mHandler = new Handler();
     private final ProxSensor mProxSensor;
     private long mDebounceFrom;
+    private boolean mSettingRegistered;
 
     public DozeSensors(Context context, AlarmManager alarmManager, SensorManager sensorManager,
             DozeParameters dozeParameters, AmbientDisplayConfiguration config, WakeLock wakeLock,
@@ -172,13 +173,8 @@
     public void setListening(boolean listen) {
         for (TriggerSensor s : mSensors) {
             s.setListening(listen);
-            if (listen) {
-                s.registerSettingsObserver(mSettingsObserver);
-            }
         }
-        if (!listen) {
-            mResolver.unregisterContentObserver(mSettingsObserver);
-        }
+        registerSettingsObserverIfNeeded(listen);
     }
 
     /** Set the listening state of only the sensors that require the touchscreen. */
@@ -240,6 +236,17 @@
         return mProxSensor.mCurrentlyFar;
     }
 
+    private void registerSettingsObserverIfNeeded(boolean register) {
+        if (!register) {
+            mResolver.unregisterContentObserver(mSettingsObserver);
+        } else if (!mSettingRegistered) {
+            for (TriggerSensor s : mSensors) {
+                s.registerSettingsObserver(mSettingsObserver);
+            }
+        }
+        mSettingRegistered = register;
+    }
+
     private class ProxSensor implements SensorEventListener {
 
         boolean mRequested;
diff --git a/packages/SystemUI/src/com/android/systemui/glwallpaper/GLWallpaperRenderer.java b/packages/SystemUI/src/com/android/systemui/glwallpaper/GLWallpaperRenderer.java
index 5d85cbf..b615a5f 100644
--- a/packages/SystemUI/src/com/android/systemui/glwallpaper/GLWallpaperRenderer.java
+++ b/packages/SystemUI/src/com/android/systemui/glwallpaper/GLWallpaperRenderer.java
@@ -52,6 +52,13 @@
     void updateAmbientMode(boolean inAmbientMode, long duration);
 
     /**
+     * Notify the wallpaper offsets changed.
+     * @param xOffset offset along x axis.
+     * @param yOffset offset along y axis.
+     */
+    void updateOffsets(float xOffset, float yOffset);
+
+    /**
      * Ask renderer to report the surface size it needs.
      */
     Size reportSurfaceSize();
diff --git a/packages/SystemUI/src/com/android/systemui/glwallpaper/ImageGLWallpaper.java b/packages/SystemUI/src/com/android/systemui/glwallpaper/ImageGLWallpaper.java
index 4be7623..626d0cf 100644
--- a/packages/SystemUI/src/com/android/systemui/glwallpaper/ImageGLWallpaper.java
+++ b/packages/SystemUI/src/com/android/systemui/glwallpaper/ImageGLWallpaper.java
@@ -33,9 +33,12 @@
 import static android.opengl.GLES20.glVertexAttribPointer;
 
 import android.graphics.Bitmap;
+import android.graphics.Rect;
 import android.opengl.GLUtils;
 import android.util.Log;
 
+import java.io.FileDescriptor;
+import java.io.PrintWriter;
 import java.nio.ByteBuffer;
 import java.nio.ByteOrder;
 import java.nio.FloatBuffer;
@@ -91,6 +94,8 @@
     private int mUniTexture;
     private int mTextureId;
 
+    private float[] mCurrentTexCoordinate;
+
     ImageGLWallpaper(ImageGLProgram program) {
         mProgram = program;
 
@@ -195,4 +200,106 @@
         glUniform1i(mUniTexture, 0);
     }
 
+    /**
+     * This method adjust s(x-axis), t(y-axis) texture coordinates to get current display area
+     * of texture and will be used during transition.
+     * The adjustment happens if either the width or height of the surface is larger than
+     * corresponding size of the display area.
+     * If both width and height are larger than corresponding size of the display area,
+     * the adjustment will happen at both s, t side.
+     *
+     * @param surface The size of the surface.
+     * @param scissor The display area.
+     * @param xOffset The offset amount along s axis.
+     * @param yOffset The offset amount along t axis.
+     */
+    void adjustTextureCoordinates(Rect surface, Rect scissor, float xOffset, float yOffset) {
+        mCurrentTexCoordinate = TEXTURES.clone();
+
+        if (surface == null || scissor == null) {
+            mTextureBuffer.put(mCurrentTexCoordinate);
+            mTextureBuffer.position(0);
+            return;
+        }
+
+        int surfaceWidth = surface.width();
+        int surfaceHeight = surface.height();
+        int scissorWidth = scissor.width();
+        int scissorHeight = scissor.height();
+
+        if (surfaceWidth > scissorWidth) {
+            // Calculate the new s pos in pixels.
+            float pixelS = (float) Math.round((surfaceWidth - scissorWidth) * xOffset);
+            // Calculate the s pos in texture coordinate.
+            float coordinateS = pixelS / surfaceWidth;
+            // Calculate the percentage occupied by the scissor width in surface width.
+            float surfacePercentageW = (float) scissorWidth / surfaceWidth;
+            // Need also consider the case if surface height is smaller than scissor height.
+            if (surfaceHeight < scissorHeight) {
+                // We will narrow the surface percentage to keep aspect ratio.
+                surfacePercentageW *= (float) surfaceHeight / scissorHeight;
+            }
+            // Determine the final s pos, also limit the legal s pos to prevent from out of range.
+            float s = coordinateS + surfacePercentageW > 1f ? 1f - surfacePercentageW : coordinateS;
+            // Traverse the s pos in texture coordinates array and adjust the s pos accordingly.
+            for (int i = 0; i < mCurrentTexCoordinate.length; i += 2) {
+                // indices 2, 4 and 6 are the end of s coordinates.
+                if (i == 2 || i == 4 || i == 6) {
+                    mCurrentTexCoordinate[i] = Math.min(1f, s + surfacePercentageW);
+                } else {
+                    mCurrentTexCoordinate[i] = s;
+                }
+            }
+        }
+
+        if (surfaceHeight > scissorHeight) {
+            // Calculate the new t pos in pixels.
+            float pixelT = (float) Math.round((surfaceHeight - scissorHeight) * yOffset);
+            // Calculate the t pos in texture coordinate.
+            float coordinateT = pixelT / surfaceHeight;
+            // Calculate the percentage occupied by the scissor height in surface height.
+            float surfacePercentageH = (float) scissorHeight / surfaceHeight;
+            // Need also consider the case if surface width is smaller than scissor width.
+            if (surfaceWidth < scissorWidth) {
+                // We will narrow the surface percentage to keep aspect ratio.
+                surfacePercentageH *= (float) surfaceWidth / scissorWidth;
+            }
+            // Determine the final t pos, also limit the legal t pos to prevent from out of range.
+            float t = coordinateT + surfacePercentageH > 1f ? 1f - surfacePercentageH : coordinateT;
+            // Traverse the t pos in texture coordinates array and adjust the t pos accordingly.
+            for (int i = 1; i < mCurrentTexCoordinate.length; i += 2) {
+                // indices 1, 3 and 11 are the end of t coordinates.
+                if (i == 1 || i == 3 || i == 11) {
+                    mCurrentTexCoordinate[i] = Math.min(1f, t + surfacePercentageH);
+                } else {
+                    mCurrentTexCoordinate[i] = t;
+                }
+            }
+        }
+
+        mTextureBuffer.put(mCurrentTexCoordinate);
+        mTextureBuffer.position(0);
+    }
+
+    /**
+     * Called to dump current state.
+     * @param prefix prefix.
+     * @param fd fd.
+     * @param out out.
+     * @param args args.
+     */
+    public void dump(String prefix, FileDescriptor fd, PrintWriter out, String[] args) {
+        StringBuilder sb = new StringBuilder();
+        sb.append('{');
+        if (mCurrentTexCoordinate != null) {
+            for (int i = 0; i < mCurrentTexCoordinate.length; i++) {
+                sb.append(mCurrentTexCoordinate[i]).append(',');
+                if (i == mCurrentTexCoordinate.length - 1) {
+                    sb.deleteCharAt(sb.length() - 1);
+                }
+            }
+        }
+        sb.append('}');
+        out.print(prefix); out.print("mTexCoordinates="); out.println(sb.toString());
+    }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/glwallpaper/ImageWallpaperRenderer.java b/packages/SystemUI/src/com/android/systemui/glwallpaper/ImageWallpaperRenderer.java
index 21711fb..93d8dd6 100644
--- a/packages/SystemUI/src/com/android/systemui/glwallpaper/ImageWallpaperRenderer.java
+++ b/packages/SystemUI/src/com/android/systemui/glwallpaper/ImageWallpaperRenderer.java
@@ -29,6 +29,8 @@
 import android.util.Log;
 import android.util.MathUtils;
 import android.util.Size;
+import android.view.DisplayInfo;
+import android.view.WindowManager;
 
 import com.android.systemui.R;
 
@@ -41,8 +43,8 @@
 public class ImageWallpaperRenderer implements GLWallpaperRenderer,
         ImageRevealHelper.RevealStateListener {
     private static final String TAG = ImageWallpaperRenderer.class.getSimpleName();
-    private static final float SCALE_VIEWPORT_MIN = 0.98f;
-    private static final float SCALE_VIEWPORT_MAX = 1f;
+    private static final float SCALE_VIEWPORT_MIN = 1f;
+    private static final float SCALE_VIEWPORT_MAX = 1.1f;
 
     private final WallpaperManager mWallpaperManager;
     private final ImageGLProgram mProgram;
@@ -51,8 +53,13 @@
     private final ImageRevealHelper mImageRevealHelper;
 
     private SurfaceProxy mProxy;
-    private Rect mSurfaceSize;
+    private final Rect mScissor;
+    private final Rect mSurfaceSize = new Rect();
+    private final Rect mViewport = new Rect();
     private Bitmap mBitmap;
+    private boolean mScissorMode;
+    private float mXOffset;
+    private float mYOffset;
 
     public ImageWallpaperRenderer(Context context, SurfaceProxy proxy) {
         mWallpaperManager = context.getSystemService(WallpaperManager.class);
@@ -60,6 +67,11 @@
             Log.w(TAG, "WallpaperManager not available");
         }
 
+        DisplayInfo displayInfo = new DisplayInfo();
+        WindowManager wm = context.getSystemService(WindowManager.class);
+        wm.getDefaultDisplay().getDisplayInfo(displayInfo);
+        mScissor = new Rect(0, 0, displayInfo.logicalWidth, displayInfo.logicalHeight);
+
         mProxy = proxy;
         mProgram = new ImageGLProgram(context);
         mWallpaper = new ImageGLWallpaper(mProgram);
@@ -91,7 +103,7 @@
             mBitmap = mWallpaperManager.getBitmap();
             mWallpaperManager.forgetLoadedWallpaper();
             if (mBitmap != null) {
-                mSurfaceSize = new Rect(0, 0, mBitmap.getWidth(), mBitmap.getHeight());
+                mSurfaceSize.set(0, 0, mBitmap.getWidth(), mBitmap.getHeight());
             }
         }
         return mBitmap != null;
@@ -107,13 +119,17 @@
         float threshold = mImageProcessHelper.getThreshold();
         float reveal = mImageRevealHelper.getReveal();
 
-        glClear(GL_COLOR_BUFFER_BIT);
-
         glUniform1f(mWallpaper.getHandle(ImageGLWallpaper.U_AOD2OPACITY), 1);
         glUniform1f(mWallpaper.getHandle(ImageGLWallpaper.U_PER85), threshold);
         glUniform1f(mWallpaper.getHandle(ImageGLWallpaper.U_REVEAL), reveal);
 
-        scaleViewport(reveal);
+        glClear(GL_COLOR_BUFFER_BIT);
+        // We only need to scale viewport while doing transition.
+        if (mScissorMode) {
+            scaleViewport(reveal);
+        } else {
+            glViewport(0, 0, mSurfaceSize.width(), mSurfaceSize.height());
+        }
         mWallpaper.useTexture();
         mWallpaper.draw();
     }
@@ -124,6 +140,15 @@
     }
 
     @Override
+    public void updateOffsets(float xOffset, float yOffset) {
+        mXOffset = xOffset;
+        mYOffset = yOffset;
+        int left = (int) ((mSurfaceSize.width() - mScissor.width()) * xOffset);
+        int right = left + mScissor.width();
+        mScissor.set(left, mScissor.top, right, mScissor.bottom);
+    }
+
+    @Override
     public Size reportSurfaceSize() {
         return new Size(mSurfaceSize.width(), mSurfaceSize.height());
     }
@@ -134,15 +159,18 @@
     }
 
     private void scaleViewport(float reveal) {
-        int width = mSurfaceSize.width();
-        int height = mSurfaceSize.height();
+        int left = mScissor.left;
+        int top = mScissor.top;
+        int width = mScissor.width();
+        int height = mScissor.height();
         // Interpolation between SCALE_VIEWPORT_MAX and SCALE_VIEWPORT_MIN by reveal.
-        float vpScaled = MathUtils.lerp(SCALE_VIEWPORT_MAX, SCALE_VIEWPORT_MIN, reveal);
+        float vpScaled = MathUtils.lerp(SCALE_VIEWPORT_MIN, SCALE_VIEWPORT_MAX, reveal);
         // Calculate the offset amount from the lower left corner.
-        float offset = (SCALE_VIEWPORT_MAX - vpScaled) / 2;
+        float offset = (SCALE_VIEWPORT_MIN - vpScaled) / 2;
         // Change the viewport.
-        glViewport((int) (width * offset), (int) (height * offset),
+        mViewport.set((int) (left + width * offset), (int) (top + height * offset),
                 (int) (width * vpScaled), (int) (height * vpScaled));
+        glViewport(mViewport.left, mViewport.top, mViewport.right, mViewport.bottom);
     }
 
     @Override
@@ -152,11 +180,19 @@
 
     @Override
     public void onRevealStart() {
+        mScissorMode = true;
+        // Use current display area of texture.
+        mWallpaper.adjustTextureCoordinates(mSurfaceSize, mScissor, mXOffset, mYOffset);
         mProxy.preRender();
     }
 
     @Override
     public void onRevealEnd() {
+        mScissorMode = false;
+        // reset texture coordinates to use full texture.
+        mWallpaper.adjustTextureCoordinates(null, null, 0, 0);
+        // We need draw full texture back before finishing render.
+        mProxy.requestRender();
         mProxy.postRender();
     }
 
@@ -164,6 +200,12 @@
     public void dump(String prefix, FileDescriptor fd, PrintWriter out, String[] args) {
         out.print(prefix); out.print("mProxy="); out.print(mProxy);
         out.print(prefix); out.print("mSurfaceSize="); out.print(mSurfaceSize);
+        out.print(prefix); out.print("mScissor="); out.print(mScissor);
+        out.print(prefix); out.print("mViewport="); out.print(mViewport);
+        out.print(prefix); out.print("mScissorMode="); out.print(mScissorMode);
+        out.print(prefix); out.print("mXOffset="); out.print(mXOffset);
+        out.print(prefix); out.print("mYOffset="); out.print(mYOffset);
         out.print(prefix); out.print("threshold="); out.print(mImageProcessHelper.getThreshold());
+        mWallpaper.dump(prefix, fd, out, args);
     }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/pip/phone/PipTouchHandler.java b/packages/SystemUI/src/com/android/systemui/pip/phone/PipTouchHandler.java
index 3ec6cb7..b05058a 100644
--- a/packages/SystemUI/src/com/android/systemui/pip/phone/PipTouchHandler.java
+++ b/packages/SystemUI/src/com/android/systemui/pip/phone/PipTouchHandler.java
@@ -125,6 +125,7 @@
     private int mImeOffset;
     private boolean mIsShelfShowing;
     private int mShelfHeight;
+    private int mMovementBoundsExtraOffsets;
     private float mSavedSnapFraction = -1f;
     private boolean mSendingHoverAccessibilityEvents;
     private boolean mMovementWithinMinimize;
@@ -262,7 +263,7 @@
         mShelfHeight = shelfHeight;
     }
 
-    public void onMovementBoundsChanged(Rect insetBounds, Rect normalBounds, Rect animatingBounds,
+    public void onMovementBoundsChanged(Rect insetBounds, Rect normalBounds, Rect curBounds,
             boolean fromImeAdjustment, boolean fromShelfAdjustment, int displayRotation) {
         final int bottomOffset = mIsImeShowing ? mImeHeight : 0;
 
@@ -283,6 +284,12 @@
         mSnapAlgorithm.getMovementBounds(mExpandedBounds, insetBounds, expandedMovementBounds,
                 bottomOffset);
 
+        // The extra offset does not really affect the movement bounds, but are applied based on the
+        // current state (ime showing, or shelf offset) when we need to actually shift
+        int extraOffset = Math.max(
+                mIsImeShowing ? mImeOffset : 0,
+                !mIsImeShowing && mIsShelfShowing ? mShelfHeight : 0);
+
         // If this is from an IME or shelf adjustment, then we should move the PiP so that it is not
         // occluded by the IME or shelf.
         if (fromImeAdjustment || fromShelfAdjustment) {
@@ -290,41 +297,19 @@
                 // Defer the update of the current movement bounds until after the user finishes
                 // touching the screen
             } else {
-                final int adjustedOffset = Math.max(mIsImeShowing ? mImeHeight + mImeOffset : 0,
-                        mIsShelfShowing ? mShelfHeight : 0);
-                Rect normalAdjustedBounds = new Rect();
-                mSnapAlgorithm.getMovementBounds(mNormalBounds, insetBounds, normalAdjustedBounds,
-                        adjustedOffset);
-                Rect expandedAdjustedBounds = new Rect();
-                mSnapAlgorithm.getMovementBounds(mExpandedBounds, insetBounds,
-                        expandedAdjustedBounds, adjustedOffset);
-                final Rect toAdjustedBounds = mMenuState == MENU_STATE_FULL
-                        ? expandedAdjustedBounds
-                        : normalAdjustedBounds;
-                final Rect toMovementBounds = mMenuState == MENU_STATE_FULL
-                        ? expandedMovementBounds
-                        : normalMovementBounds;
-
-                // If the PIP window needs to shift to right above shelf/IME and it's already above
-                // that, don't move the PIP window.
-                if (toAdjustedBounds.bottom < mMovementBounds.bottom
-                        && animatingBounds.top < toAdjustedBounds.bottom) {
-                    return;
-                }
-
-                // If the PIP window needs to shift down due to dismissal of shelf/IME but it's way
-                // above the position as if shelf/IME shows, don't move the PIP window.
-                int movementBoundsAdjustment = toMovementBounds.bottom - mMovementBounds.bottom;
-                int offsetAdjustment = fromImeAdjustment ? mImeOffset : mShelfHeight;
-                final float bottomOffsetBufferInPx = BOTTOM_OFFSET_BUFFER_DP
+                final float offsetBufferPx = BOTTOM_OFFSET_BUFFER_DP
                         * mContext.getResources().getDisplayMetrics().density;
-                if (toAdjustedBounds.bottom >= mMovementBounds.bottom
-                        && animatingBounds.top + Math.round(bottomOffsetBufferInPx)
-                        < toAdjustedBounds.bottom - movementBoundsAdjustment - offsetAdjustment) {
-                    return;
+                final Rect toMovementBounds = mMenuState == MENU_STATE_FULL
+                        ? new Rect(expandedMovementBounds)
+                        : new Rect(normalMovementBounds);
+                final int prevBottom = mMovementBounds.bottom - mMovementBoundsExtraOffsets;
+                final int toBottom = toMovementBounds.bottom < toMovementBounds.top
+                        ? toMovementBounds.bottom
+                        : toMovementBounds.bottom - extraOffset;
+                if ((Math.min(prevBottom, toBottom) - offsetBufferPx) <= curBounds.top
+                        && curBounds.top <= (Math.max(prevBottom, toBottom) + offsetBufferPx)) {
+                    mMotionHelper.animateToOffset(curBounds, toBottom - curBounds.top);
                 }
-
-                animateToOffset(animatingBounds, toAdjustedBounds);
             }
         }
 
@@ -335,6 +320,7 @@
         mDisplayRotation = displayRotation;
         mInsetBounds.set(insetBounds);
         updateMovementBounds(mMenuState);
+        mMovementBoundsExtraOffsets = extraOffset;
 
         // If we have a deferred resize, apply it now
         if (mDeferResizeToNormalBoundsUntilRotation == displayRotation) {
@@ -346,14 +332,6 @@
         }
     }
 
-    private void animateToOffset(Rect animatingBounds, Rect toAdjustedBounds) {
-        int offset = toAdjustedBounds.bottom - animatingBounds.top;
-        // In landscape mode, PIP window can go offset while launching IME. We want to align the
-        // the top of the PIP window with the top of the movement bounds in that case.
-        offset += Math.max(0, mMovementBounds.top - animatingBounds.top);
-        mMotionHelper.animateToOffset(animatingBounds, offset);
-    }
-
     private void onRegistrationChanged(boolean isRegistered) {
         mAccessibilityManager.setPictureInPictureActionReplacingConnection(isRegistered
                 ? new PipAccessibilityInteractionConnection(mMotionHelper,
diff --git a/packages/SystemUI/src/com/android/systemui/privacy/OngoingPrivacyChip.kt b/packages/SystemUI/src/com/android/systemui/privacy/OngoingPrivacyChip.kt
deleted file mode 100644
index a5a915b..0000000
--- a/packages/SystemUI/src/com/android/systemui/privacy/OngoingPrivacyChip.kt
+++ /dev/null
@@ -1,110 +0,0 @@
-/*
- * Copyright (C) 2018 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file
- * except in compliance with the License. You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software distributed under the
- * License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the specific language governing
- * permissions and limitations under the License.
- */
-
-package com.android.systemui.privacy
-
-import android.content.Context
-import android.util.AttributeSet
-import android.view.Gravity
-import android.view.ViewGroup
-import android.widget.FrameLayout
-import android.widget.ImageView
-import android.widget.LinearLayout
-import com.android.systemui.R
-
-class OngoingPrivacyChip @JvmOverloads constructor(
-    context: Context,
-    attrs: AttributeSet? = null,
-    defStyleAttrs: Int = 0,
-    defStyleRes: Int = 0
-) : LinearLayout(context, attrs, defStyleAttrs, defStyleRes) {
-
-    private val iconMarginExpanded = context.resources.getDimensionPixelSize(
-                    R.dimen.ongoing_appops_chip_icon_margin_expanded)
-    private val iconMarginCollapsed = context.resources.getDimensionPixelSize(
-                    R.dimen.ongoing_appops_chip_icon_margin_collapsed)
-    private val iconSize =
-            context.resources.getDimensionPixelSize(R.dimen.ongoing_appops_chip_icon_size)
-    private val iconColor = context.resources.getColor(
-            R.color.status_bar_clock_color, context.theme)
-    private val sidePadding =
-            context.resources.getDimensionPixelSize(R.dimen.ongoing_appops_chip_side_padding)
-    private val backgroundDrawable = context.getDrawable(R.drawable.privacy_chip_bg)
-    private lateinit var iconsContainer: LinearLayout
-    private lateinit var back: FrameLayout
-    var expanded = false
-        set(value) {
-            if (value != field) {
-                field = value
-                updateView()
-            }
-        }
-
-    var builder = PrivacyDialogBuilder(context, emptyList<PrivacyItem>())
-    var privacyList = emptyList<PrivacyItem>()
-        set(value) {
-            field = value
-            builder = PrivacyDialogBuilder(context, value)
-            updateView()
-        }
-
-    override fun onFinishInflate() {
-        super.onFinishInflate()
-
-        back = findViewById(R.id.background)
-        iconsContainer = findViewById(R.id.icons_container)
-    }
-
-    // Should only be called if the builder icons or app changed
-    private fun updateView() {
-        back.background = if (expanded) backgroundDrawable else null
-        val padding = if (expanded) sidePadding else 0
-        back.setPaddingRelative(padding, 0, padding, 0)
-        fun setIcons(dialogBuilder: PrivacyDialogBuilder, iconsContainer: ViewGroup) {
-            iconsContainer.removeAllViews()
-            dialogBuilder.generateIcons().forEachIndexed { i, it ->
-                it.mutate()
-                it.setTint(iconColor)
-                val image = ImageView(context).apply {
-                    setImageDrawable(it)
-                    scaleType = ImageView.ScaleType.CENTER_INSIDE
-                }
-                iconsContainer.addView(image, iconSize, iconSize)
-                if (i != 0) {
-                    val lp = image.layoutParams as MarginLayoutParams
-                    lp.marginStart = if (expanded) iconMarginExpanded else iconMarginCollapsed
-                    image.layoutParams = lp
-                }
-            }
-        }
-
-        if (!privacyList.isEmpty()) {
-            generateContentDescription()
-            setIcons(builder, iconsContainer)
-            val lp = iconsContainer.layoutParams as FrameLayout.LayoutParams
-            lp.gravity = Gravity.CENTER_VERTICAL or
-                    (if (expanded) Gravity.CENTER_HORIZONTAL else Gravity.END)
-            iconsContainer.layoutParams = lp
-        } else {
-            iconsContainer.removeAllViews()
-        }
-        requestLayout()
-    }
-
-    private fun generateContentDescription() {
-        val typesText = builder.joinTypes()
-        contentDescription = context.getString(
-                R.string.ongoing_privacy_chip_content_multiple_apps, typesText)
-    }
-}
\ No newline at end of file
diff --git a/packages/SystemUI/src/com/android/systemui/privacy/PrivacyDialogBuilder.kt b/packages/SystemUI/src/com/android/systemui/privacy/PrivacyDialogBuilder.kt
deleted file mode 100644
index d08a373..0000000
--- a/packages/SystemUI/src/com/android/systemui/privacy/PrivacyDialogBuilder.kt
+++ /dev/null
@@ -1,56 +0,0 @@
-/*
- * Copyright (C) 2018 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file
- * except in compliance with the License. You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software distributed under the
- * License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the specific language governing
- * permissions and limitations under the License.
- */
-
-package com.android.systemui.privacy
-
-import android.content.Context
-import android.graphics.drawable.Drawable
-import com.android.systemui.R
-
-class PrivacyDialogBuilder(private val context: Context, itemsList: List<PrivacyItem>) {
-
-    val appsAndTypes: List<Pair<PrivacyApplication, List<PrivacyType>>>
-    val types: List<PrivacyType>
-    private val separator = context.getString(R.string.ongoing_privacy_dialog_separator)
-    private val lastSeparator = context.getString(R.string.ongoing_privacy_dialog_last_separator)
-
-    init {
-        appsAndTypes = itemsList.groupBy({ it.application }, { it.privacyType })
-                .toList()
-                .sortedWith(compareBy({ -it.second.size }, // Sort by number of AppOps
-                        { it.second.min() })) // Sort by "smallest" AppOpp (Location is largest)
-        types = itemsList.map { it.privacyType }.distinct().sorted()
-    }
-
-    fun generateIconsForApp(types: List<PrivacyType>): List<Drawable> {
-        return types.sorted().map { it.getIcon(context) }
-    }
-
-    fun generateIcons() = types.map { it.getIcon(context) }
-
-    private fun <T> List<T>.joinWithAnd(): StringBuilder {
-        return subList(0, size - 1).joinTo(StringBuilder(), separator = separator).apply {
-            append(lastSeparator)
-            append(this@joinWithAnd.last())
-        }
-    }
-
-    fun joinTypes(): String {
-        return when (types.size) {
-            0 -> ""
-            1 -> types[0].getName(context)
-            else -> types.map { it.getName(context) }.joinWithAnd().toString()
-        }
-    }
-}
diff --git a/packages/SystemUI/src/com/android/systemui/privacy/PrivacyItem.kt b/packages/SystemUI/src/com/android/systemui/privacy/PrivacyItem.kt
deleted file mode 100644
index 2909424..0000000
--- a/packages/SystemUI/src/com/android/systemui/privacy/PrivacyItem.kt
+++ /dev/null
@@ -1,80 +0,0 @@
-/*
- * Copyright (C) 2018 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file
- * except in compliance with the License. You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software distributed under the
- * License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the specific language governing
- * permissions and limitations under the License.
- */
-
-package com.android.systemui.privacy
-
-import android.content.Context
-import android.content.pm.ApplicationInfo
-import android.content.pm.PackageManager
-import android.graphics.drawable.Drawable
-import android.os.UserHandle
-import android.util.IconDrawableFactory
-import com.android.systemui.R
-
-typealias Privacy = PrivacyType
-
-enum class PrivacyType(private val nameId: Int, val iconId: Int) {
-    // This is uses the icons used by the corresponding permission groups in the AndroidManifest
-    TYPE_CAMERA(R.string.privacy_type_camera,
-            com.android.internal.R.drawable.perm_group_camera),
-    TYPE_MICROPHONE(R.string.privacy_type_microphone,
-            com.android.internal.R.drawable.perm_group_microphone),
-    TYPE_LOCATION(R.string.privacy_type_location,
-            com.android.internal.R.drawable.perm_group_location);
-
-    fun getName(context: Context) = context.resources.getString(nameId)
-
-    fun getIcon(context: Context) = context.resources.getDrawable(iconId, context.theme)
-}
-
-data class PrivacyItem(
-    val privacyType: PrivacyType,
-    val application: PrivacyApplication
-)
-
-data class PrivacyApplication(val packageName: String, val uid: Int, val context: Context)
-    : Comparable<PrivacyApplication> {
-
-    override fun compareTo(other: PrivacyApplication): Int {
-        return applicationName.compareTo(other.applicationName)
-    }
-
-    private val applicationInfo: ApplicationInfo? by lazy {
-        try {
-            val userHandle = UserHandle.getUserHandleForUid(uid)
-            context.createPackageContextAsUser(packageName, 0, userHandle).getPackageManager()
-                    .getApplicationInfo(packageName, 0)
-        } catch (_: PackageManager.NameNotFoundException) {
-            null
-        }
-    }
-    val icon: Drawable by lazy {
-        applicationInfo?.let {
-            try {
-                val iconFactory = IconDrawableFactory.newInstance(context, true)
-                iconFactory.getBadgedIcon(it, UserHandle.getUserId(uid))
-            } catch (_: Exception) {
-                null
-            }
-        } ?: context.getDrawable(android.R.drawable.sym_def_app_icon)
-    }
-
-    val applicationName: String by lazy {
-        applicationInfo?.let {
-            context.packageManager.getApplicationLabel(it) as String
-        } ?: packageName
-    }
-
-    override fun toString() = "PrivacyApplication(packageName=$packageName, uid=$uid)"
-}
diff --git a/packages/SystemUI/src/com/android/systemui/privacy/PrivacyItemController.kt b/packages/SystemUI/src/com/android/systemui/privacy/PrivacyItemController.kt
deleted file mode 100644
index 82a2c1f..0000000
--- a/packages/SystemUI/src/com/android/systemui/privacy/PrivacyItemController.kt
+++ /dev/null
@@ -1,294 +0,0 @@
-/*
- * Copyright (C) 2018 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.systemui.privacy
-
-import android.app.ActivityManager
-import android.app.AppOpsManager
-import android.content.BroadcastReceiver
-import android.content.Context
-import android.content.Intent
-import android.content.IntentFilter
-import android.os.Handler
-import android.os.Looper
-import android.os.Message
-import android.os.UserHandle
-import android.os.UserManager
-import android.provider.DeviceConfig
-import com.android.internal.annotations.VisibleForTesting
-import com.android.internal.config.sysui.SystemUiDeviceConfigFlags
-import com.android.systemui.Dependency.BG_HANDLER_NAME
-import com.android.systemui.Dependency.MAIN_HANDLER_NAME
-import com.android.systemui.R
-import com.android.systemui.appops.AppOpItem
-import com.android.systemui.appops.AppOpsController
-import com.android.systemui.Dumpable
-import java.io.FileDescriptor
-import java.io.PrintWriter
-import java.lang.ref.WeakReference
-import javax.inject.Inject
-import javax.inject.Named
-import javax.inject.Singleton
-
-fun isPermissionsHubEnabled() = DeviceConfig.getBoolean(DeviceConfig.NAMESPACE_PRIVACY,
-                SystemUiDeviceConfigFlags.PROPERTY_PERMISSIONS_HUB_ENABLED, false)
-
-@Singleton
-class PrivacyItemController @Inject constructor(
-        val context: Context,
-        private val appOpsController: AppOpsController,
-        @Named(MAIN_HANDLER_NAME) private val uiHandler: Handler,
-        @Named(BG_HANDLER_NAME) private val bgHandler: Handler
-) : Dumpable {
-
-    @VisibleForTesting
-    internal companion object {
-        val OPS = intArrayOf(AppOpsManager.OP_CAMERA,
-                AppOpsManager.OP_RECORD_AUDIO,
-                AppOpsManager.OP_COARSE_LOCATION,
-                AppOpsManager.OP_FINE_LOCATION)
-        val intents = listOf(Intent.ACTION_USER_FOREGROUND,
-                Intent.ACTION_MANAGED_PROFILE_ADDED,
-                Intent.ACTION_MANAGED_PROFILE_REMOVED)
-        const val TAG = "PrivacyItemController"
-        const val SYSTEM_UID = 1000
-        const val MSG_ADD_CALLBACK = 0
-        const val MSG_REMOVE_CALLBACK = 1
-        const val MSG_UPDATE_LISTENING_STATE = 2
-    }
-
-    @VisibleForTesting
-    internal var privacyList = emptyList<PrivacyItem>()
-        @Synchronized get() = field.toList() // Returns a shallow copy of the list
-        @Synchronized set
-
-    private val userManager = context.getSystemService(UserManager::class.java)
-    private var currentUserIds = emptyList<Int>()
-    private var listening = false
-    val systemApp =
-            PrivacyApplication(context.getString(R.string.device_services), SYSTEM_UID, context)
-    private val callbacks = mutableListOf<WeakReference<Callback>>()
-    private val messageHandler = H(WeakReference(this), uiHandler.looper)
-
-    private val notifyChanges = Runnable {
-        val list = privacyList
-        callbacks.forEach { it.get()?.privacyChanged(list) }
-    }
-
-    private val updateListAndNotifyChanges = Runnable {
-        updatePrivacyList()
-        uiHandler.post(notifyChanges)
-    }
-
-    private var indicatorsAvailable = isPermissionsHubEnabled()
-    @VisibleForTesting
-    internal val devicePropertyChangedListener =
-            object : DeviceConfig.OnPropertyChangedListener {
-        override fun onPropertyChanged(namespace: String, name: String, value: String?) {
-            if (DeviceConfig.NAMESPACE_PRIVACY.equals(namespace) &&
-                    SystemUiDeviceConfigFlags.PROPERTY_PERMISSIONS_HUB_ENABLED.equals(name)) {
-                indicatorsAvailable = java.lang.Boolean.parseBoolean(value)
-                messageHandler.removeMessages(MSG_UPDATE_LISTENING_STATE)
-                messageHandler.sendEmptyMessage(MSG_UPDATE_LISTENING_STATE)
-            }
-        }
-    }
-
-    private val cb = object : AppOpsController.Callback {
-        override fun onActiveStateChanged(
-            code: Int,
-            uid: Int,
-            packageName: String,
-            active: Boolean
-        ) {
-            val userId = UserHandle.getUserId(uid)
-            if (userId in currentUserIds) {
-                update(false)
-            }
-        }
-    }
-
-    @VisibleForTesting
-    internal var userSwitcherReceiver = Receiver()
-        set(value) {
-            context.unregisterReceiver(field)
-            field = value
-            registerReceiver()
-        }
-
-    init {
-        DeviceConfig.addOnPropertyChangedListener(
-                DeviceConfig.NAMESPACE_PRIVACY, context.mainExecutor, devicePropertyChangedListener)
-    }
-
-    private fun unregisterReceiver() {
-        context.unregisterReceiver(userSwitcherReceiver)
-    }
-
-    private fun registerReceiver() {
-        context.registerReceiverAsUser(userSwitcherReceiver, UserHandle.ALL, IntentFilter().apply {
-            intents.forEach {
-                addAction(it)
-            }
-        }, null, null)
-    }
-
-    private fun update(updateUsers: Boolean) {
-        if (updateUsers) {
-            val currentUser = ActivityManager.getCurrentUser()
-            currentUserIds = userManager.getProfiles(currentUser).map { it.id }
-        }
-        bgHandler.post(updateListAndNotifyChanges)
-    }
-
-    /**
-     * Updates listening status based on whether there are callbacks and the indicators are enabled
-     *
-     * This is only called from private (add/remove)Callback and from the config listener, all in
-     * main thread.
-     */
-    private fun setListeningState() {
-        val listen = !callbacks.isEmpty() and indicatorsAvailable
-        if (listening == listen) return
-        listening = listen
-        if (listening) {
-            appOpsController.addCallback(OPS, cb)
-            registerReceiver()
-            update(true)
-        } else {
-            appOpsController.removeCallback(OPS, cb)
-            unregisterReceiver()
-            // Make sure that we remove all indicators and notify listeners if we are not
-            // listening anymore due to indicators being disabled
-            update(false)
-        }
-    }
-
-    private fun addCallback(callback: WeakReference<Callback>) {
-        callbacks.add(callback)
-        if (callbacks.isNotEmpty() && !listening) {
-            messageHandler.removeMessages(MSG_UPDATE_LISTENING_STATE)
-            messageHandler.sendEmptyMessage(MSG_UPDATE_LISTENING_STATE)
-        }
-        // Notify this callback if we didn't set to listening
-        else if (listening) uiHandler.post(NotifyChangesToCallback(callback.get(), privacyList))
-    }
-
-    private fun removeCallback(callback: WeakReference<Callback>) {
-        // Removes also if the callback is null
-        callbacks.removeIf { it.get()?.equals(callback.get()) ?: true }
-        if (callbacks.isEmpty()) {
-            messageHandler.removeMessages(MSG_UPDATE_LISTENING_STATE)
-            messageHandler.sendEmptyMessage(MSG_UPDATE_LISTENING_STATE)
-        }
-    }
-
-    fun addCallback(callback: Callback) {
-        messageHandler.obtainMessage(MSG_ADD_CALLBACK, callback).sendToTarget()
-    }
-
-    fun removeCallback(callback: Callback) {
-        messageHandler.obtainMessage(MSG_REMOVE_CALLBACK, callback).sendToTarget()
-    }
-
-    private fun updatePrivacyList() {
-        if (!listening) {
-            privacyList = emptyList()
-            return
-        }
-        val list = currentUserIds.flatMap { appOpsController.getActiveAppOpsForUser(it) }
-                .mapNotNull { toPrivacyItem(it) }.distinct()
-        privacyList = list
-    }
-
-    private fun toPrivacyItem(appOpItem: AppOpItem): PrivacyItem? {
-        val type: PrivacyType = when (appOpItem.code) {
-            AppOpsManager.OP_CAMERA -> PrivacyType.TYPE_CAMERA
-            AppOpsManager.OP_COARSE_LOCATION -> PrivacyType.TYPE_LOCATION
-            AppOpsManager.OP_FINE_LOCATION -> PrivacyType.TYPE_LOCATION
-            AppOpsManager.OP_RECORD_AUDIO -> PrivacyType.TYPE_MICROPHONE
-            else -> return null
-        }
-        if (appOpItem.uid == SYSTEM_UID) return PrivacyItem(type, systemApp)
-        val app = PrivacyApplication(appOpItem.packageName, appOpItem.uid, context)
-        return PrivacyItem(type, app)
-    }
-
-    // Used by containing class to get notified of changes
-    interface Callback {
-        fun privacyChanged(privacyItems: List<PrivacyItem>)
-    }
-
-    internal inner class Receiver : BroadcastReceiver() {
-        override fun onReceive(context: Context?, intent: Intent?) {
-            if (intent?.action in intents) {
-                update(true)
-            }
-        }
-    }
-
-    private class NotifyChangesToCallback(
-        private val callback: Callback?,
-        private val list: List<PrivacyItem>
-    ) : Runnable {
-        override fun run() {
-            callback?.privacyChanged(list)
-        }
-    }
-
-    override fun dump(fd: FileDescriptor?, pw: PrintWriter?, args: Array<out String>?) {
-        pw?.println("PrivacyItemController state:")
-        pw?.println("  Listening: $listening")
-        pw?.println("  Current user ids: $currentUserIds")
-        pw?.println("  Privacy Items:")
-        privacyList.forEach {
-            pw?.print("    ")
-            pw?.println(it.toString())
-        }
-        pw?.println("  Callbacks:")
-        callbacks.forEach {
-            it.get()?.let {
-                pw?.print("    ")
-                pw?.println(it.toString())
-            }
-        }
-    }
-
-    private class H(
-            private val outerClass: WeakReference<PrivacyItemController>,
-            looper: Looper
-    ) : Handler(looper) {
-        override fun handleMessage(msg: Message) {
-            super.handleMessage(msg)
-            when (msg.what) {
-                MSG_UPDATE_LISTENING_STATE -> outerClass.get()?.setListeningState()
-
-                MSG_ADD_CALLBACK -> {
-                    if (msg.obj !is PrivacyItemController.Callback) return
-                    outerClass.get()?.addCallback(
-                            WeakReference(msg.obj as PrivacyItemController.Callback))
-                }
-
-                MSG_REMOVE_CALLBACK -> {
-                    if (msg.obj !is PrivacyItemController.Callback) return
-                    outerClass.get()?.removeCallback(
-                            WeakReference(msg.obj as PrivacyItemController.Callback))
-                }
-                else -> {}
-            }
-        }
-    }
-}
\ No newline at end of file
diff --git a/packages/SystemUI/src/com/android/systemui/qs/QSTileHost.java b/packages/SystemUI/src/com/android/systemui/qs/QSTileHost.java
index 3c4898c..af7de0e6 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/QSTileHost.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/QSTileHost.java
@@ -19,6 +19,7 @@
 import android.content.Context;
 import android.content.Intent;
 import android.content.res.Resources;
+import android.os.Build;
 import android.os.Handler;
 import android.os.Looper;
 import android.os.UserHandle;
@@ -48,6 +49,7 @@
 import com.android.systemui.statusbar.phone.StatusBarIconController;
 import com.android.systemui.tuner.TunerService;
 import com.android.systemui.tuner.TunerService.Tunable;
+import com.android.systemui.util.leak.GarbageMonitor;
 
 import java.io.FileDescriptor;
 import java.io.PrintWriter;
@@ -364,6 +366,10 @@
             if (tile.equals("default")) {
                 if (!addedDefault) {
                     tiles.addAll(Arrays.asList(defaultTileList.split(",")));
+                    if (Build.IS_DEBUGGABLE
+                            && GarbageMonitor.MemoryTile.ADD_TO_DEFAULT_ON_DEBUGGABLE_BUILDS) {
+                        tiles.add(GarbageMonitor.MemoryTile.TILE_SPEC);
+                    }
                     addedDefault = true;
                 }
             } else {
diff --git a/packages/SystemUI/src/com/android/systemui/qs/QuickStatusBarHeader.java b/packages/SystemUI/src/com/android/systemui/qs/QuickStatusBarHeader.java
index 410a13e..d59e251 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/QuickStatusBarHeader.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/QuickStatusBarHeader.java
@@ -32,30 +32,24 @@
 import android.graphics.Rect;
 import android.media.AudioManager;
 import android.os.Handler;
-import android.os.Looper;
 import android.provider.AlarmClock;
-import android.provider.DeviceConfig;
 import android.provider.Settings;
 import android.service.notification.ZenModeConfig;
 import android.text.format.DateUtils;
 import android.util.AttributeSet;
 import android.util.Log;
 import android.util.Pair;
-import android.util.StatsLog;
 import android.view.ContextThemeWrapper;
 import android.view.DisplayCutout;
 import android.view.View;
 import android.view.WindowInsets;
 import android.widget.FrameLayout;
 import android.widget.ImageView;
-import android.widget.LinearLayout;
 import android.widget.RelativeLayout;
-import android.widget.Space;
 import android.widget.TextView;
 
 import androidx.annotation.VisibleForTesting;
 
-import com.android.internal.config.sysui.SystemUiDeviceConfigFlags;
 import com.android.settingslib.Utils;
 import com.android.systemui.BatteryMeterView;
 import com.android.systemui.DualToneHandler;
@@ -63,11 +57,6 @@
 import com.android.systemui.plugins.ActivityStarter;
 import com.android.systemui.plugins.DarkIconDispatcher;
 import com.android.systemui.plugins.DarkIconDispatcher.DarkReceiver;
-import com.android.systemui.privacy.OngoingPrivacyChip;
-import com.android.systemui.privacy.PrivacyDialogBuilder;
-import com.android.systemui.privacy.PrivacyItem;
-import com.android.systemui.privacy.PrivacyItemController;
-import com.android.systemui.privacy.PrivacyItemControllerKt;
 import com.android.systemui.qs.QSDetail.Callback;
 import com.android.systemui.statusbar.phone.PhoneStatusBarView;
 import com.android.systemui.statusbar.phone.StatusBarIconController;
@@ -78,8 +67,6 @@
 import com.android.systemui.statusbar.policy.NextAlarmController;
 import com.android.systemui.statusbar.policy.ZenModeController;
 
-import java.util.ArrayList;
-import java.util.List;
 import java.util.Locale;
 import java.util.Objects;
 
@@ -121,7 +108,6 @@
     private TintedIconManager mIconManager;
     private TouchAnimator mStatusIconsAlphaAnimator;
     private TouchAnimator mHeaderTextContainerAlphaAnimator;
-    private TouchAnimator mPrivacyChipAlphaAnimator;
     private DualToneHandler mDualToneHandler;
 
     private View mSystemIconsView;
@@ -141,12 +127,7 @@
     private View mRingerContainer;
     private Clock mClockView;
     private DateView mDateView;
-    private OngoingPrivacyChip mPrivacyChip;
-    private Space mSpace;
     private BatteryMeterView mBatteryRemainingIcon;
-    private boolean mPermissionsHubEnabled;
-
-    private PrivacyItemController mPrivacyItemController;
 
     private final BroadcastReceiver mRingerReceiver = new BroadcastReceiver() {
         @Override
@@ -156,41 +137,17 @@
         }
     };
     private boolean mHasTopCutout = false;
-    private boolean mPrivacyChipLogged = false;
-
-    private final DeviceConfig.OnPropertyChangedListener mPropertyListener =
-            new DeviceConfig.OnPropertyChangedListener() {
-                @Override
-                public void onPropertyChanged(String namespace, String name, String value) {
-                    if (DeviceConfig.NAMESPACE_PRIVACY.equals(namespace)
-                            && SystemUiDeviceConfigFlags.PROPERTY_PERMISSIONS_HUB_ENABLED.equals(
-                            name)) {
-                        mPermissionsHubEnabled = Boolean.valueOf(value);
-                        StatusIconContainer iconContainer = findViewById(R.id.statusIcons);
-                        iconContainer.setIgnoredSlots(getIgnoredIconSlots());
-                    }
-                }
-            };
-
-    private PrivacyItemController.Callback mPICCallback = new PrivacyItemController.Callback() {
-        @Override
-        public void privacyChanged(List<PrivacyItem> privacyItems) {
-            mPrivacyChip.setPrivacyList(privacyItems);
-            setChipVisibility(!privacyItems.isEmpty());
-        }
-    };
 
     @Inject
     public QuickStatusBarHeader(@Named(VIEW_CONTEXT) Context context, AttributeSet attrs,
             NextAlarmController nextAlarmController, ZenModeController zenModeController,
             StatusBarIconController statusBarIconController,
-            ActivityStarter activityStarter, PrivacyItemController privacyItemController) {
+            ActivityStarter activityStarter) {
         super(context, attrs);
         mAlarmController = nextAlarmController;
         mZenController = zenModeController;
         mStatusBarIconController = statusBarIconController;
         mActivityStarter = activityStarter;
-        mPrivacyItemController = privacyItemController;
         mDualToneHandler = new DualToneHandler(
                 new ContextThemeWrapper(context, R.style.QSHeaderTheme));
     }
@@ -203,8 +160,6 @@
         mSystemIconsView = findViewById(R.id.quick_status_bar_system_icons);
         mQuickQsStatusIcons = findViewById(R.id.quick_qs_status_icons);
         StatusIconContainer iconContainer = findViewById(R.id.statusIcons);
-        // Ignore privacy icons because they show in the space above QQS
-        iconContainer.addIgnoredSlots(getIgnoredIconSlots());
         iconContainer.setShouldRestrictIcons(false);
         mIconManager = new TintedIconManager(iconContainer);
 
@@ -218,9 +173,6 @@
         mRingerModeIcon = findViewById(R.id.ringer_mode_icon);
         mRingerModeTextView = findViewById(R.id.ringer_mode_text);
         mRingerContainer = findViewById(R.id.ringer_container);
-        mRingerContainer.setOnClickListener(this::onClick);
-        mPrivacyChip = findViewById(R.id.privacy_chip);
-        mPrivacyChip.setOnClickListener(this::onClick);
         mCarrierGroup = findViewById(R.id.carrier_group);
 
 
@@ -243,7 +195,6 @@
         mClockView = findViewById(R.id.clock);
         mClockView.setOnClickListener(this);
         mDateView = findViewById(R.id.date);
-        mSpace = findViewById(R.id.space);
 
         // Tint for the battery icons are handled in setupHost()
         mBatteryRemainingIcon = findViewById(R.id.batteryRemainingIcon);
@@ -254,26 +205,6 @@
         mBatteryRemainingIcon.setPercentShowMode(BatteryMeterView.MODE_ESTIMATE);
         mRingerModeTextView.setSelected(true);
         mNextAlarmTextView.setSelected(true);
-
-        mPermissionsHubEnabled = PrivacyItemControllerKt.isPermissionsHubEnabled();
-        // Change the ignored slots when DeviceConfig flag changes
-        DeviceConfig.addOnPropertyChangedListener(DeviceConfig.NAMESPACE_PRIVACY,
-                mContext.getMainExecutor(), mPropertyListener);
-
-    }
-
-    private List<String> getIgnoredIconSlots() {
-        ArrayList<String> ignored = new ArrayList<>();
-        ignored.add(mContext.getResources().getString(
-                com.android.internal.R.string.status_bar_camera));
-        ignored.add(mContext.getResources().getString(
-                com.android.internal.R.string.status_bar_microphone));
-        if (mPermissionsHubEnabled) {
-            ignored.add(mContext.getResources().getString(
-                    com.android.internal.R.string.status_bar_location));
-        }
-
-        return ignored;
     }
 
     private void updateStatusText() {
@@ -287,21 +218,6 @@
         }
     }
 
-    private void setChipVisibility(boolean chipVisible) {
-        if (chipVisible && mPermissionsHubEnabled) {
-            mPrivacyChip.setVisibility(View.VISIBLE);
-            // Makes sure that the chip is logged as viewed at most once each time QS is opened
-            // mListening makes sure that the callback didn't return after the user closed QS
-            if (!mPrivacyChipLogged && mListening) {
-                mPrivacyChipLogged = true;
-                StatsLog.write(StatsLog.PRIVACY_INDICATORS_INTERACTED,
-                        StatsLog.PRIVACY_INDICATORS_INTERACTED__TYPE__CHIP_VIEWED);
-            }
-        } else {
-            mPrivacyChip.setVisibility(View.GONE);
-        }
-    }
-
     private boolean updateRingerStatus() {
         boolean isOriginalVisible = mRingerModeTextView.getVisibility() == View.VISIBLE;
         CharSequence originalRingerText = mRingerModeTextView.getText();
@@ -408,7 +324,6 @@
 
         updateStatusIconAlphaAnimator();
         updateHeaderTextContainerAlphaAnimator();
-        updatePrivacyChipAlphaAnimator();
     }
 
     private void updateStatusIconAlphaAnimator() {
@@ -423,12 +338,6 @@
                 .build();
     }
 
-    private void updatePrivacyChipAlphaAnimator() {
-        mPrivacyChipAlphaAnimator = new TouchAnimator.Builder()
-                .addFloat(mPrivacyChip, "alpha", 1, 0, 1)
-                .build();
-    }
-
     public void setExpanded(boolean expanded) {
         if (mExpanded == expanded) return;
         mExpanded = expanded;
@@ -467,10 +376,6 @@
                 mHeaderTextContainerView.setVisibility(INVISIBLE);
             }
         }
-        if (mPrivacyChipAlphaAnimator != null) {
-            mPrivacyChip.setExpanded(expansionFraction > 0.5);
-            mPrivacyChipAlphaAnimator.setPosition(keyguardExpansionFraction);
-        }
     }
 
     public void disable(int state1, int state2, boolean animate) {
@@ -503,21 +408,6 @@
             mSystemIconsView.setPadding(padding.first, 0, padding.second, 0);
 
         }
-        LinearLayout.LayoutParams lp = (LinearLayout.LayoutParams) mSpace.getLayoutParams();
-        if (cutout != null) {
-            Rect topCutout = cutout.getBoundingRectTop();
-            if (topCutout.isEmpty()) {
-                mHasTopCutout = false;
-                lp.width = 0;
-                mSpace.setVisibility(View.GONE);
-            } else {
-                mHasTopCutout = true;
-                lp.width = topCutout.width();
-                mSpace.setVisibility(View.VISIBLE);
-            }
-        }
-        mSpace.setLayoutParams(lp);
-        setChipVisibility(mPrivacyChip.getVisibility() == View.VISIBLE);
         return super.onApplyWindowInsets(insets);
     }
 
@@ -542,13 +432,10 @@
             mAlarmController.addCallback(this);
             mContext.registerReceiver(mRingerReceiver,
                     new IntentFilter(AudioManager.INTERNAL_RINGER_MODE_CHANGED_ACTION));
-            mPrivacyItemController.addCallback(mPICCallback);
         } else {
             mZenController.removeCallback(this);
             mAlarmController.removeCallback(this);
-            mPrivacyItemController.removeCallback(mPICCallback);
             mContext.unregisterReceiver(mRingerReceiver);
-            mPrivacyChipLogged = false;
         }
     }
 
@@ -566,18 +453,6 @@
                 mActivityStarter.postStartActivityDismissingKeyguard(new Intent(
                         AlarmClock.ACTION_SHOW_ALARMS), 0);
             }
-        } else if (v == mPrivacyChip) {
-            // Makes sure that the builder is grabbed as soon as the chip is pressed
-            PrivacyDialogBuilder builder = mPrivacyChip.getBuilder();
-            if (builder.getAppsAndTypes().size() == 0) return;
-            Handler mUiHandler = new Handler(Looper.getMainLooper());
-            StatsLog.write(StatsLog.PRIVACY_INDICATORS_INTERACTED,
-                    StatsLog.PRIVACY_INDICATORS_INTERACTED__TYPE__CHIP_CLICKED);
-            mUiHandler.post(() -> {
-                mActivityStarter.postStartActivityDismissingKeyguard(
-                        new Intent(Intent.ACTION_REVIEW_ONGOING_PERMISSION_USAGE), 0);
-                mHost.collapsePanels();
-            });
         } else if (v == mRingerContainer && mRingerContainer.isVisibleToUser()) {
             mActivityStarter.postStartActivityDismissingKeyguard(new Intent(
                     Settings.ACTION_SOUND_SETTINGS), 0);
diff --git a/packages/SystemUI/src/com/android/systemui/recents/OverviewProxyService.java b/packages/SystemUI/src/com/android/systemui/recents/OverviewProxyService.java
index 1848219..88a8b31 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/OverviewProxyService.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/OverviewProxyService.java
@@ -41,7 +41,6 @@
 import android.hardware.input.InputManager;
 import android.os.Binder;
 import android.os.Bundle;
-import android.os.Debug;
 import android.os.Handler;
 import android.os.IBinder;
 import android.os.Looper;
@@ -54,7 +53,6 @@
 import android.view.accessibility.AccessibilityManager;
 
 import com.android.internal.policy.ScreenDecorationsUtils;
-import com.android.systemui.Dependency;
 import com.android.systemui.Dumpable;
 import com.android.systemui.SysUiServiceProvider;
 import com.android.systemui.recents.OverviewProxyService.OverviewProxyListener;
@@ -69,6 +67,7 @@
 import com.android.systemui.statusbar.phone.NavigationBarView;
 import com.android.systemui.statusbar.phone.NavigationModeController;
 import com.android.systemui.statusbar.phone.StatusBar;
+import com.android.systemui.statusbar.phone.StatusBarWindowController;
 import com.android.systemui.statusbar.policy.CallbackController;
 import com.android.systemui.statusbar.policy.DeviceProvisionedController;
 import com.android.systemui.statusbar.policy.DeviceProvisionedController.DeviceProvisionedListener;
@@ -100,6 +99,8 @@
 
     private final Context mContext;
     private final Handler mHandler;
+    private final NavigationBarController mNavBarController;
+    private final StatusBarWindowController mStatusBarWinController;
     private final Runnable mConnectionRunnable = this::internalConnectToCurrentUser;
     private final ComponentName mRecentsComponentName;
     private final DeviceProvisionedController mDeviceProvisionedController;
@@ -446,9 +447,13 @@
             = this::cleanupAfterDeath;
 
     @Inject
-    public OverviewProxyService(Context context, DeviceProvisionedController provisionController) {
+    public OverviewProxyService(Context context, DeviceProvisionedController provisionController,
+            NavigationBarController navBarController, NavigationModeController navModeController,
+            StatusBarWindowController statusBarWinController) {
         mContext = context;
         mHandler = new Handler();
+        mNavBarController = navBarController;
+        mStatusBarWinController = statusBarWinController;
         mDeviceProvisionedController = provisionController;
         mConnectionBackoffAttempts = 0;
         mRecentsComponentName = ComponentName.unflattenFromString(context.getString(
@@ -463,7 +468,7 @@
         mBackButtonAlpha = 1.0f;
 
         // Listen for nav bar mode changes
-        mNavBarMode = Dependency.get(NavigationModeController.class).addListener(this);
+        mNavBarMode = navModeController.addListener(this);
 
         // Listen for device provisioned/user setup
         updateEnabledState();
@@ -513,10 +518,10 @@
     }
 
     private void updateSystemUiStateFlags() {
-        final NavigationBarController navBar = Dependency.get(NavigationBarController.class);
-        final NavigationBarFragment navBarFragment = navBar.getDefaultNavigationBarFragment();
-        final NavigationBarView navBarView = navBar.getNavigationBarView(mContext.getDisplayId());
-        final StatusBar statusBar = SysUiServiceProvider.getComponent(mContext, StatusBar.class);
+        final NavigationBarFragment navBarFragment =
+                mNavBarController.getDefaultNavigationBarFragment();
+        final NavigationBarView navBarView =
+                mNavBarController.getNavigationBarView(mContext.getDisplayId());
 
         mSysUiStateFlags = 0;
         if (navBarFragment != null) {
@@ -525,8 +530,8 @@
         if (navBarView != null) {
             navBarView.updateSystemUiStateFlags();
         }
-        if (statusBar != null) {
-            statusBar.updateSystemUiStateFlags();
+        if (mStatusBarWinController != null) {
+            mStatusBarWinController.updateSystemUiStateFlags();
         }
         notifySystemUiStateFlags(mSysUiStateFlags);
     }
diff --git a/packages/SystemUI/src/com/android/systemui/screenshot/GlobalScreenshot.java b/packages/SystemUI/src/com/android/systemui/screenshot/GlobalScreenshot.java
index 341461b..11ca94f 100644
--- a/packages/SystemUI/src/com/android/systemui/screenshot/GlobalScreenshot.java
+++ b/packages/SystemUI/src/com/android/systemui/screenshot/GlobalScreenshot.java
@@ -92,6 +92,11 @@
 import java.text.DateFormat;
 import java.text.SimpleDateFormat;
 import java.util.Date;
+import java.util.concurrent.ExecutionException;
+import java.util.concurrent.TimeUnit;
+import java.util.concurrent.TimeoutException;
+
+
 
 /**
  * POD used in the AsyncTask which saves an image in the background.
@@ -446,6 +451,8 @@
     static final String EXTRA_CANCEL_NOTIFICATION = "android:screenshot_cancel_notification";
     static final String EXTRA_DISALLOW_ENTER_PIP = "android:screenshot_disallow_enter_pip";
 
+    private static final String TAG = "GlobalScreenshot";
+
     private static final int SCREENSHOT_FLASH_TO_PEAK_DURATION = 130;
     private static final int SCREENSHOT_DROP_IN_DURATION = 430;
     private static final int SCREENSHOT_DROP_OUT_DELAY = 500;
@@ -902,11 +909,19 @@
      * appropriate signals to the system (ie. to dismiss the keyguard if necessary).
      */
     public static class ActionProxyReceiver extends BroadcastReceiver {
+        static final int CLOSE_WINDOWS_TIMEOUT_MILLIS = 3000;
+
         @Override
         public void onReceive(Context context, final Intent intent) {
             Runnable startActivityRunnable = () -> {
-                ActivityManagerWrapper.getInstance().closeSystemWindows(
-                        SYSTEM_DIALOG_REASON_SCREENSHOT);
+                try {
+                    ActivityManagerWrapper.getInstance().closeSystemWindows(
+                            SYSTEM_DIALOG_REASON_SCREENSHOT).get(
+                            CLOSE_WINDOWS_TIMEOUT_MILLIS, TimeUnit.MILLISECONDS);
+                } catch (TimeoutException | InterruptedException | ExecutionException e) {
+                    Slog.e(TAG, "Unable to share screenshot", e);
+                    return;
+                }
 
                 Intent actionIntent = intent.getParcelableExtra(EXTRA_ACTION_INTENT);
                 if (intent.getBooleanExtra(EXTRA_CANCEL_NOTIFICATION, false)) {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/KeyguardIndicationController.java b/packages/SystemUI/src/com/android/systemui/statusbar/KeyguardIndicationController.java
index fd76a79..ca12deb 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/KeyguardIndicationController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/KeyguardIndicationController.java
@@ -43,6 +43,7 @@
 import com.android.internal.app.IBatteryStats;
 import com.android.internal.logging.nano.MetricsProto;
 import com.android.internal.widget.LockPatternUtils;
+import com.android.internal.widget.ViewClippingUtil;
 import com.android.keyguard.KeyguardUpdateMonitor;
 import com.android.keyguard.KeyguardUpdateMonitorCallback;
 import com.android.settingslib.Utils;
@@ -118,6 +119,13 @@
 
     private final DevicePolicyManager mDevicePolicyManager;
     private boolean mDozing;
+    private final ViewClippingUtil.ClippingParameters mClippingParams =
+            new ViewClippingUtil.ClippingParameters() {
+                @Override
+                public boolean shouldFinish(View view) {
+                    return view == mIndicationArea;
+                }
+            };
 
     /**
      * Creates a new KeyguardIndicationController and registers callbacks.
@@ -413,6 +421,7 @@
                 R.integer.wired_charging_keyguard_text_animation_duration_down);
         textView.animate().cancel();
         float translation = textView.getTranslationY();
+        ViewClippingUtil.setClippingDeactivated(textView, true, mClippingParams);
         textView.animate()
                 .translationYBy(yTranslation)
                 .setInterpolator(Interpolators.LINEAR)
@@ -434,6 +443,8 @@
                     @Override
                     public void onAnimationEnd(Animator animation) {
                         if (mCancelled) {
+                            ViewClippingUtil.setClippingDeactivated(textView, false,
+                                    mClippingParams);
                             return;
                         }
                         textView.animate()
@@ -445,6 +456,12 @@
                                     public void onAnimationCancel(Animator animation) {
                                         textView.setTranslationY(translation);
                                     }
+
+                                    @Override
+                                    public void onAnimationEnd(Animator animation) {
+                                        ViewClippingUtil.setClippingDeactivated(textView, false,
+                                                mClippingParams);
+                                    }
                                 });
                     }
                 });
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationLockscreenUserManagerImpl.java b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationLockscreenUserManagerImpl.java
index 905a8e6..4ea1ed5 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationLockscreenUserManagerImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationLockscreenUserManagerImpl.java
@@ -320,7 +320,7 @@
 
     private boolean hideSilentNotificationsOnLockscreen() {
         return Settings.Secure.getInt(mContext.getContentResolver(),
-                Settings.Secure.LOCK_SCREEN_SHOW_SILENT_NOTIFICATIONS, 0) == 0;
+                Settings.Secure.LOCK_SCREEN_SHOW_SILENT_NOTIFICATIONS, 1) == 0;
     }
 
     private void setShowLockscreenNotifications(boolean show) {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationMediaManager.java b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationMediaManager.java
index 75ef185..6c36ab9 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationMediaManager.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationMediaManager.java
@@ -488,6 +488,7 @@
         if (bmp != null) {
             artworkDrawable = new BitmapDrawable(mBackdropBack.getResources(), bmp);
         }
+        boolean hasMediaArtwork = artworkDrawable != null;
         boolean allowWhenShade = false;
         if (ENABLE_LOCKSCREEN_WALLPAPER && artworkDrawable == null) {
             Bitmap lockWallpaper =
@@ -506,7 +507,7 @@
         boolean hideBecauseOccluded = shadeController != null && shadeController.isOccluded();
 
         final boolean hasArtwork = artworkDrawable != null;
-        mColorExtractor.setHasBackdrop(hasArtwork);
+        mColorExtractor.setHasMediaArtwork(hasMediaArtwork);
         if (mScrimController != null) {
             mScrimController.setHasBackdrop(hasArtwork);
         }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationShelf.java b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationShelf.java
index fc2705f..312ea47 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationShelf.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationShelf.java
@@ -929,7 +929,6 @@
 
     public void setAnimationsEnabled(boolean enabled) {
         mAnimationsEnabled = enabled;
-        mCollapsedIcons.setAnimationsEnabled(enabled);
         if (!enabled) {
             // we need to wait with enabling the animations until the first frame has passed
             mShelfIcons.setAnimationsEnabled(false);
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/VisualStabilityManager.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/VisualStabilityManager.java
index 396a3a7..4a6c7d2 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/VisualStabilityManager.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/VisualStabilityManager.java
@@ -16,18 +16,26 @@
 
 package com.android.systemui.statusbar.notification;
 
+import static com.android.systemui.Dependency.MAIN_HANDLER_NAME;
+
+import android.os.Handler;
+import android.os.SystemClock;
 import android.view.View;
 
 import androidx.collection.ArraySet;
 
+import com.android.systemui.Dumpable;
 import com.android.systemui.statusbar.NotificationPresenter;
 import com.android.systemui.statusbar.notification.collection.NotificationEntry;
 import com.android.systemui.statusbar.notification.row.ExpandableNotificationRow;
 import com.android.systemui.statusbar.policy.OnHeadsUpChangedListener;
 
+import java.io.FileDescriptor;
+import java.io.PrintWriter;
 import java.util.ArrayList;
 
 import javax.inject.Inject;
+import javax.inject.Named;
 import javax.inject.Singleton;
 
 /**
@@ -35,14 +43,19 @@
  * and reorder at the right time when they are out of view.
  */
 @Singleton
-public class VisualStabilityManager implements OnHeadsUpChangedListener {
+public class VisualStabilityManager implements OnHeadsUpChangedListener, Dumpable {
+
+    private static final long TEMPORARY_REORDERING_ALLOWED_DURATION = 1000;
 
     private final ArrayList<Callback> mCallbacks =  new ArrayList<>();
+    private final Handler mHandler;
 
     private NotificationPresenter mPresenter;
     private boolean mPanelExpanded;
     private boolean mScreenOn;
     private boolean mReorderingAllowed;
+    private boolean mIsTemporaryReorderingAllowed;
+    private long mTemporaryReorderingStart;
     private VisibilityLocationProvider mVisibilityLocationProvider;
     private ArraySet<View> mAllowedReorderViews = new ArraySet<>();
     private ArraySet<NotificationEntry> mLowPriorityReorderingViews = new ArraySet<>();
@@ -50,7 +63,12 @@
     private boolean mPulsing;
 
     @Inject
-    public VisualStabilityManager(NotificationEntryManager notificationEntryManager) {
+    public VisualStabilityManager(
+            NotificationEntryManager notificationEntryManager,
+            @Named(MAIN_HANDLER_NAME) Handler handler) {
+
+        mHandler = handler;
+
         notificationEntryManager.addNotificationEntryListener(new NotificationEntryListener() {
             @Override
             public void onPreEntryUpdated(NotificationEntry entry) {
@@ -114,10 +132,11 @@
     }
 
     private void updateReorderingAllowed() {
-        boolean reorderingAllowed = (!mScreenOn || !mPanelExpanded) && !mPulsing;
-        boolean changed = reorderingAllowed && !mReorderingAllowed;
+        boolean reorderingAllowed =
+                (!mScreenOn || !mPanelExpanded || mIsTemporaryReorderingAllowed) && !mPulsing;
+        boolean changedToTrue = reorderingAllowed && !mReorderingAllowed;
         mReorderingAllowed = reorderingAllowed;
-        if (changed) {
+        if (changedToTrue) {
             notifyCallbacks();
         }
     }
@@ -180,6 +199,25 @@
     }
 
     /**
+     * Temporarily allows reordering of the entire shade for a period of 1000ms. Subsequent calls
+     * to this method will extend the timer.
+     */
+    public void temporarilyAllowReordering() {
+        mHandler.removeCallbacks(mOnTemporaryReorderingExpired);
+        mHandler.postDelayed(mOnTemporaryReorderingExpired, TEMPORARY_REORDERING_ALLOWED_DURATION);
+        if (!mIsTemporaryReorderingAllowed) {
+            mTemporaryReorderingStart = SystemClock.elapsedRealtime();
+        }
+        mIsTemporaryReorderingAllowed = true;
+        updateReorderingAllowed();
+    }
+
+    private final Runnable mOnTemporaryReorderingExpired = () -> {
+        mIsTemporaryReorderingAllowed = false;
+        updateReorderingAllowed();
+    };
+
+    /**
      * Notify the visual stability manager that a new view was added and should be allowed to
      * reorder next time.
      */
@@ -187,6 +225,20 @@
         mAddedChildren.add(view);
     }
 
+    @Override
+    public void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
+        pw.println("VisualStabilityManager state:");
+        pw.print("  mIsTemporaryReorderingAllowed="); pw.println(mIsTemporaryReorderingAllowed);
+        pw.print("  mTemporaryReorderingStart="); pw.println(mTemporaryReorderingStart);
+
+        long now = SystemClock.elapsedRealtime();
+        pw.print("    Temporary reordering window has been open for ");
+        pw.print(now - (mIsTemporaryReorderingAllowed ? mTemporaryReorderingStart : now));
+        pw.println("ms");
+
+        pw.println();
+    }
+
     public interface Callback {
         /**
          * Called when reordering is allowed again.
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ChannelEditorDialogController.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ChannelEditorDialogController.kt
index 83a4319..8e68227 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ChannelEditorDialogController.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ChannelEditorDialogController.kt
@@ -29,6 +29,7 @@
 import android.graphics.drawable.ColorDrawable
 import android.util.Log
 import android.view.Gravity
+import android.view.View
 import android.view.ViewGroup.LayoutParams.MATCH_PARENT
 import android.view.ViewGroup.LayoutParams.WRAP_CONTENT
 import android.view.Window
@@ -43,6 +44,18 @@
 
 const val TAG = "ChannelDialogController"
 
+/**
+ * ChannelEditorDialogController is the controller for the dialog half-shelf
+ * that allows users to quickly turn off channels. It is launched from the NotificationInfo
+ * guts view and displays controls for toggling app notifications as well as up to 4 channels
+ * from that app like so:
+ *
+ *   APP TOGGLE                                                 <on/off>
+ *   - Channel from which we launched                           <on/off>
+ *   -                                                          <on/off>
+ *   - the next 3 channels sorted alphabetically for that app   <on/off>
+ *   -                                                          <on/off>
+ */
 @Singleton
 class ChannelEditorDialogController @Inject constructor(
     c: Context,
@@ -58,6 +71,9 @@
     private var appName: String? = null
     private var onSettingsClickListener: NotificationInfo.OnSettingsClickListener? = null
 
+    // Caller should set this if they care about when we dismiss
+    var onFinishListener: OnChannelEditorDialogFinishedListener? = null
+
     // Channels handed to us from NotificationInfo
     @VisibleForTesting
     internal val providedChannels = mutableListOf<NotificationChannel>()
@@ -71,13 +87,17 @@
     internal val groupNameLookup = hashMapOf<String, CharSequence>()
     private val channelGroupList = mutableListOf<NotificationChannelGroup>()
 
+    /**
+     * Give the controller all of the information it needs to present the dialog
+     * for a given app. Does a bunch of querying of NoMan, but won't present anything yet
+     */
     fun prepareDialogForApp(
         appName: String,
         packageName: String,
         uid: Int,
         channels: Set<NotificationChannel>,
         appIcon: Drawable,
-        onSettingsClickListener: NotificationInfo.OnSettingsClickListener
+        onSettingsClickListener: NotificationInfo.OnSettingsClickListener?
     ) {
         this.appName = appName
         this.packageName = packageName
@@ -141,9 +161,17 @@
         dialog.show()
     }
 
+    /**
+     * Close the dialog without saving. For external callers
+     */
+    fun close() {
+        done()
+    }
+
     private fun done() {
         resetState()
         dialog.dismiss()
+        onFinishListener?.onChannelEditorDialogFinished()
     }
 
     private fun resetState() {
@@ -219,6 +247,11 @@
         }
     }
 
+    @VisibleForTesting
+    fun launchSettings(sender: View) {
+        onSettingsClickListener?.onClick(sender, null, appUid!!)
+    }
+
     private fun initDialog() {
         dialog = Dialog(context)
 
@@ -241,8 +274,8 @@
             }
 
             findViewById<TextView>(R.id.see_more_button)?.setOnClickListener {
-                onSettingsClickListener?.onClick(it, null, appUid!!)
-                dismiss()
+                launchSettings(it)
+                done()
             }
 
             window?.apply {
@@ -267,3 +300,7 @@
             or WindowManager.LayoutParams.FLAG_WATCH_OUTSIDE_TOUCH
             or WindowManager.LayoutParams.FLAG_HARDWARE_ACCELERATED)
 }
+
+interface OnChannelEditorDialogFinishedListener {
+    fun onChannelEditorDialogFinished()
+}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ChannelEditorListView.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ChannelEditorListView.kt
index 6fe1477..6faf77e 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ChannelEditorListView.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ChannelEditorListView.kt
@@ -24,6 +24,7 @@
 import android.graphics.drawable.Drawable
 import android.text.TextUtils
 import android.transition.AutoTransition
+import android.transition.Transition
 import android.transition.TransitionManager
 import android.util.AttributeSet
 import android.view.LayoutInflater
@@ -62,6 +63,23 @@
 
         val transition = AutoTransition()
         transition.duration = 200
+        transition.addListener(object : Transition.TransitionListener {
+            override fun onTransitionEnd(p0: Transition?) {
+                notifySubtreeAccessibilityStateChangedIfNeeded()
+            }
+
+            override fun onTransitionResume(p0: Transition?) {
+            }
+
+            override fun onTransitionPause(p0: Transition?) {
+            }
+
+            override fun onTransitionCancel(p0: Transition?) {
+            }
+
+            override fun onTransitionStart(p0: Transition?) {
+            }
+        })
         TransitionManager.beginDelayedTransition(this, transition)
 
         // Remove any rows
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationGutsManager.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationGutsManager.java
index f15d6b7..b5a8aad 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationGutsManager.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationGutsManager.java
@@ -41,13 +41,16 @@
 import com.android.internal.logging.nano.MetricsProto;
 import com.android.systemui.Dependency;
 import com.android.systemui.Dumpable;
+import com.android.systemui.SysUiServiceProvider;
 import com.android.systemui.plugins.statusbar.NotificationMenuRowPlugin;
 import com.android.systemui.plugins.statusbar.StatusBarStateController;
 import com.android.systemui.statusbar.NotificationLifetimeExtender;
 import com.android.systemui.statusbar.NotificationLockscreenUserManager;
 import com.android.systemui.statusbar.NotificationPresenter;
 import com.android.systemui.statusbar.StatusBarState;
+import com.android.systemui.statusbar.StatusBarStateControllerImpl;
 import com.android.systemui.statusbar.notification.NotificationActivityStarter;
+import com.android.systemui.statusbar.notification.VisualStabilityManager;
 import com.android.systemui.statusbar.notification.collection.NotificationEntry;
 import com.android.systemui.statusbar.notification.row.NotificationInfo.CheckSaveListener;
 import com.android.systemui.statusbar.notification.stack.NotificationListContainer;
@@ -73,6 +76,7 @@
 
     private final MetricsLogger mMetricsLogger = Dependency.get(MetricsLogger.class);
     private final Context mContext;
+    private final VisualStabilityManager mVisualStabilityManager;
     private final AccessibilityManager mAccessibilityManager;
 
     // Dependencies:
@@ -95,9 +99,14 @@
     @VisibleForTesting
     protected String mKeyToRemoveOnGutsClosed;
 
+    private StatusBar mStatusBar;
+
     @Inject
-    public NotificationGutsManager(Context context) {
+    public NotificationGutsManager(
+            Context context,
+            VisualStabilityManager visualStabilityManager) {
         mContext = context;
+        mVisualStabilityManager = visualStabilityManager;
         mAccessibilityManager = (AccessibilityManager)
                 mContext.getSystemService(Context.ACCESSIBILITY_SERVICE);
     }
@@ -109,6 +118,7 @@
         mListContainer = listContainer;
         mCheckSaveListener = checkSave;
         mOnSettingsClickListener = onSettingsClick;
+        mStatusBar = SysUiServiceProvider.getComponent(mContext, StatusBar.class);
     }
 
     public void setNotificationActivityStarter(
@@ -304,6 +314,7 @@
         notificationInfoView.bindNotification(
                 pmUser,
                 iNotificationManager,
+                mVisualStabilityManager,
                 packageName,
                 row.getEntry().channel,
                 row.getUniqueChannels(),
@@ -370,6 +381,34 @@
             int x,
             int y,
             NotificationMenuRowPlugin.MenuItem menuItem) {
+        if (menuItem.getGutsView() instanceof NotificationInfo) {
+            if (mStatusBarStateController instanceof StatusBarStateControllerImpl) {
+                ((StatusBarStateControllerImpl) mStatusBarStateController)
+                        .setLeaveOpenOnKeyguardHide(true);
+            }
+
+            Runnable r = () -> Dependency.get(Dependency.MAIN_HANDLER).post(
+                    () -> openGutsInternal(view, x, y, menuItem));
+
+            mStatusBar.executeRunnableDismissingKeyguard(
+                    r,
+                    null /* cancelAction */,
+                    false /* dismissShade */,
+                    true /* afterKeyguardGone */,
+                    true /* deferred */);
+
+            return true;
+        }
+        return openGutsInternal(view, x, y, menuItem);
+    }
+
+    @VisibleForTesting
+    boolean openGutsInternal(
+            View view,
+            int x,
+            int y,
+            NotificationMenuRowPlugin.MenuItem menuItem) {
+
         if (!(view instanceof ExpandableNotificationRow)) {
             return false;
         }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationInfo.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationInfo.java
index 1dc96b8..148d83b 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationInfo.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationInfo.java
@@ -65,6 +65,7 @@
 import com.android.systemui.Dependency;
 import com.android.systemui.Interpolators;
 import com.android.systemui.R;
+import com.android.systemui.statusbar.notification.VisualStabilityManager;
 import com.android.systemui.statusbar.notification.logging.NotificationCounters;
 
 import java.lang.annotation.Retention;
@@ -104,6 +105,7 @@
     private INotificationManager mINotificationManager;
     private PackageManager mPm;
     private MetricsLogger mMetricsLogger;
+    private VisualStabilityManager mVisualStabilityManager;
     private ChannelEditorDialogController mChannelEditorDialogController;
 
     private String mPackageName;
@@ -116,6 +118,7 @@
     private int mStartingChannelImportance;
     private boolean mWasShownHighPriority;
     private boolean mPressedApply;
+    private boolean mPresentingChannelEditorDialog = false;
 
     /**
      * The last importance level chosen by the user.  Null if the user has not chosen an importance
@@ -159,13 +162,13 @@
     // used by standard ui
     private OnClickListener mOnDismissSettings = v -> {
         mPressedApply = true;
-        closeControls(v);
+        closeControls(v, true);
     };
 
     // used by blocking helper
     private OnClickListener mOnKeepShowing = v -> {
         mExitReason = NotificationCounters.BLOCKING_HELPER_KEEP_SHOWING;
-        closeControls(v);
+        closeControls(v, true);
         mMetricsLogger.write(getLogMaker().setCategory(
                 MetricsEvent.NOTIFICATION_BLOCKING_HELPER)
                 .setType(MetricsEvent.TYPE_ACTION)
@@ -244,6 +247,7 @@
     void bindNotification(
             final PackageManager pm,
             final INotificationManager iNotificationManager,
+            final VisualStabilityManager visualStabilityManager,
             final String pkg,
             final NotificationChannel notificationChannel,
             final Set<NotificationChannel> uniqueChannelsInRow,
@@ -256,7 +260,7 @@
             int importance,
             boolean wasShownHighPriority)
             throws RemoteException {
-        bindNotification(pm, iNotificationManager, pkg, notificationChannel,
+        bindNotification(pm, iNotificationManager, visualStabilityManager, pkg, notificationChannel,
                 uniqueChannelsInRow, sbn, checkSaveListener, onSettingsClick,
                 onAppSettingsClick, isDeviceProvisioned, isNonblockable,
                 false /* isBlockingHelper */,
@@ -266,6 +270,7 @@
     public void bindNotification(
             PackageManager pm,
             INotificationManager iNotificationManager,
+            VisualStabilityManager visualStabilityManager,
             String pkg,
             NotificationChannel notificationChannel,
             Set<NotificationChannel> uniqueChannelsInRow,
@@ -281,6 +286,7 @@
             throws RemoteException {
         mINotificationManager = iNotificationManager;
         mMetricsLogger = Dependency.get(MetricsLogger.class);
+        mVisualStabilityManager = visualStabilityManager;
         mChannelEditorDialogController = Dependency.get(ChannelEditorDialogController.class);
         mPackageName = pkg;
         mUniqueChannelsInRow = uniqueChannelsInRow;
@@ -442,9 +448,15 @@
 
     private OnClickListener getTurnOffNotificationsClickListener() {
         return ((View view) -> {
-            if (mChannelEditorDialogController != null) {
+            if (!mPresentingChannelEditorDialog && mChannelEditorDialogController != null) {
+                mPresentingChannelEditorDialog = true;
+
                 mChannelEditorDialogController.prepareDialogForApp(mAppName, mPackageName, mAppUid,
                         mUniqueChannelsInRow, mPkgIcon, mOnSettingsClickListener);
+                mChannelEditorDialogController.setOnFinishListener(() -> {
+                    mPresentingChannelEditorDialog = false;
+                    closeControls(this, false);
+                });
                 mChannelEditorDialogController.show();
             }
         });
@@ -537,6 +549,7 @@
                     new UpdateImportanceRunnable(mINotificationManager, mPackageName, mAppUid,
                             mNumUniqueChannelsInRow == 1 ? mSingleNotificationChannel : null,
                             mStartingChannelImportance, newImportance));
+            mVisualStabilityManager.temporarilyAllowReordering();
         }
     }
 
@@ -561,16 +574,21 @@
 
         switch (behavior) {
             case BEHAVIOR_ALERTING:
-                alert.setSelected(true);
-                silence.setSelected(false);
                 mPriorityDescriptionView.setVisibility(VISIBLE);
                 mSilentDescriptionView.setVisibility(GONE);
+                post(() -> {
+                    alert.setSelected(true);
+                    silence.setSelected(false);
+                });
                 break;
             case BEHAVIOR_SILENT:
-                alert.setSelected(false);
-                silence.setSelected(true);
+
                 mSilentDescriptionView.setVisibility(VISIBLE);
                 mPriorityDescriptionView.setVisibility(GONE);
+                post(() -> {
+                    alert.setSelected(false);
+                    silence.setSelected(true);
+                });
                 break;
             default:
                 throw new IllegalArgumentException("Unrecognized alerting behavior: " + behavior);
@@ -725,7 +743,7 @@
      * {@link #swapContent(boolean, boolean)} for where undo is handled.
      */
     @VisibleForTesting
-    void closeControls(View v) {
+    void closeControls(View v, boolean save) {
         int[] parentLoc = new int[2];
         int[] targetLoc = new int[2];
         mGutsContainer.getLocationOnScreen(parentLoc);
@@ -734,7 +752,7 @@
         final int centerY = v.getHeight() / 2;
         final int x = targetLoc[0] - parentLoc[0] + centerX;
         final int y = targetLoc[1] - parentLoc[1] + centerY;
-        mGutsContainer.closeControls(x, y, true /* save */, false /* force */);
+        mGutsContainer.closeControls(x, y, save, false /* force */);
     }
 
     @Override
@@ -759,6 +777,13 @@
 
     @Override
     public boolean handleCloseControls(boolean save, boolean force) {
+        if (mPresentingChannelEditorDialog && mChannelEditorDialogController != null) {
+            mPresentingChannelEditorDialog = false;
+            // No need for the finish listener because we're closing
+            mChannelEditorDialogController.setOnFinishListener(null);
+            mChannelEditorDialogController.close();
+        }
+
         // Save regardless of the importance so we can lock the importance field if the user wants
         // to keep getting notifications
         if (save) {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/wrapper/NotificationMediaTemplateViewWrapper.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/wrapper/NotificationMediaTemplateViewWrapper.java
index 4526eaf..20e8b73 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/wrapper/NotificationMediaTemplateViewWrapper.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/wrapper/NotificationMediaTemplateViewWrapper.java
@@ -18,6 +18,7 @@
 
 import static com.android.systemui.Dependency.MAIN_HANDLER;
 
+import android.annotation.Nullable;
 import android.app.Notification;
 import android.content.Context;
 import android.content.res.ColorStateList;
@@ -28,7 +29,6 @@
 import android.metrics.LogMaker;
 import android.os.Handler;
 import android.text.format.DateUtils;
-import android.util.Log;
 import android.view.LayoutInflater;
 import android.view.View;
 import android.view.ViewStub;
@@ -52,7 +52,6 @@
  */
 public class NotificationMediaTemplateViewWrapper extends NotificationTemplateViewWrapper {
 
-    private static final String TAG = "NotificationMediaTVW";
     private static final long PROGRESS_UPDATE_INTERVAL = 1000; // 1s
     private static final String COMPACT_MEDIA_TAG = "media";
     private final Handler mHandler = Dependency.get(MAIN_HANDLER);
@@ -63,6 +62,7 @@
     private TextView mSeekBarTotalTime;
     private long mDuration = 0;
     private MediaController mMediaController;
+    private MediaMetadata mMediaMetadata;
     private NotificationMediaManager mMediaManager;
     private View mSeekBarView;
     private Context mContext;
@@ -81,7 +81,7 @@
 
         @Override
         public void onStopTrackingTouch(SeekBar seekBar) {
-            if (mMediaController != null && canSeekMedia()) {
+            if (mMediaController != null) {
                 mMediaController.getTransportControls().seekTo(mSeekBar.getProgress());
                 mMetricsLogger.write(newLog(MetricsEvent.TYPE_UPDATE));
             }
@@ -96,16 +96,28 @@
         }
 
         @Override
-        public void onPlaybackStateChanged(PlaybackState state) {
+        public void onPlaybackStateChanged(@Nullable PlaybackState state) {
+            if (state == null) {
+                return;
+            }
+
             if (state.getState() != PlaybackState.STATE_PLAYING) {
                 // Update the UI once, in case playback info changed while we were paused
-                mUpdatePlaybackUi.run();
+                updatePlaybackUi(state);
                 clearTimer();
             } else if (mSeekBarTimer == null && mSeekBarView != null
                     && mSeekBarView.getVisibility() != View.GONE) {
                 startTimer();
             }
         }
+
+        @Override
+        public void onMetadataChanged(@Nullable MediaMetadata metadata) {
+            if (mMediaMetadata == null || !mMediaMetadata.equals(metadata)) {
+                mMediaMetadata = metadata;
+                updateDuration();
+            }
+        }
     };
 
     protected NotificationMediaTemplateViewWrapper(Context ctx, View view,
@@ -140,12 +152,11 @@
             controllerUpdated = true;
         }
 
-        if (mMediaController.getMetadata() != null) {
-            long duration = mMediaController.getMetadata().getLong(
-                    MediaMetadata.METADATA_KEY_DURATION);
+        mMediaMetadata = mMediaController.getMetadata();
+        if (mMediaMetadata != null) {
+            long duration = mMediaMetadata.getLong(MediaMetadata.METADATA_KEY_DURATION);
             if (duration <= 0) {
                 // Don't include the seekbar if this is a livestream
-                Log.d(TAG, "removing seekbar");
                 if (mSeekBarView != null && mSeekBarView.getVisibility() != View.GONE) {
                     mSeekBarView.setVisibility(View.GONE);
                     mMetricsLogger.write(newLog(MetricsEvent.TYPE_CLOSE));
@@ -156,12 +167,12 @@
                     mMetricsLogger.write(newLog(MetricsEvent.TYPE_CLOSE));
                 }
                 return;
-            } else {
+            } else if (mSeekBarView != null && mSeekBarView.getVisibility() == View.GONE) {
                 // Otherwise, make sure the seekbar is visible
-                if (mSeekBarView != null && mSeekBarView.getVisibility() == View.GONE) {
-                    mSeekBarView.setVisibility(View.VISIBLE);
-                    mMetricsLogger.write(newLog(MetricsEvent.TYPE_OPEN));
-                }
+                mSeekBarView.setVisibility(View.VISIBLE);
+                mMetricsLogger.write(newLog(MetricsEvent.TYPE_OPEN));
+                updateDuration();
+                startTimer();
             }
         }
 
@@ -181,13 +192,13 @@
             mSeekBarTotalTime = mSeekBarView.findViewById(R.id.notification_media_total_time);
 
             if (mSeekBarTimer == null) {
-                if (canSeekMedia()) {
+                if (mMediaController != null && canSeekMedia(mMediaController.getPlaybackState())) {
                     // Log initial state, since it will not be updated
                     mMetricsLogger.write(newLog(MetricsEvent.TYPE_DETAIL, 1));
                 } else {
                     setScrubberVisible(false);
                 }
-
+                updateDuration();
                 startTimer();
                 mMediaController.registerCallback(mMediaCallback);
             }
@@ -201,7 +212,7 @@
         mSeekBarTimer.schedule(new TimerTask() {
             @Override
             public void run() {
-                mHandler.post(mUpdatePlaybackUi);
+                mHandler.post(mOnUpdateTimerTick);
             }
         }, 0, PROGRESS_UPDATE_INTERVAL);
     }
@@ -215,14 +226,12 @@
         }
     }
 
-    private boolean canSeekMedia() {
-        if (mMediaController == null || mMediaController.getPlaybackState() == null) {
-            Log.d(TAG, "Cannot seek media because the controller is invalid");
+    private boolean canSeekMedia(@Nullable PlaybackState state) {
+        if (state == null) {
             return false;
         }
 
-        long actions = mMediaController.getPlaybackState().getActions();
-        Log.d(TAG, "Playback state actions are " + actions);
+        long actions = state.getActions();
         return ((actions & PlaybackState.ACTION_SEEK_TO) != 0);
     }
 
@@ -236,39 +245,44 @@
         mMetricsLogger.write(newLog(MetricsEvent.TYPE_DETAIL, isVisible ? 1 : 0));
     }
 
-    protected final Runnable mUpdatePlaybackUi = new Runnable() {
+    private void updateDuration() {
+        if (mMediaMetadata != null && mSeekBar != null) {
+            long duration = mMediaMetadata.getLong(MediaMetadata.METADATA_KEY_DURATION);
+            if (mDuration != duration) {
+                mDuration = duration;
+                mSeekBar.setMax((int) mDuration);
+                mSeekBarTotalTime.setText(millisecondsToTimeString(duration));
+            }
+        }
+    }
+
+    protected final Runnable mOnUpdateTimerTick = new Runnable() {
         @Override
         public void run() {
             if (mMediaController != null && mSeekBar != null) {
-                MediaMetadata metadata = mMediaController.getMetadata();
                 PlaybackState playbackState = mMediaController.getPlaybackState();
 
-                if (metadata != null && playbackState != null) {
-                    long position = playbackState.getPosition();
-                    long duration = metadata.getLong(MediaMetadata.METADATA_KEY_DURATION);
-
-                    if (mDuration != duration) {
-                        mDuration = duration;
-                        mSeekBar.setMax((int) mDuration);
-                        mSeekBarTotalTime.setText(millisecondsToTimeString(duration));
-                    }
-                    mSeekBar.setProgress((int) position);
-
-                    mSeekBarElapsedTime.setText(millisecondsToTimeString(position));
-
-                    // Update scrubber in case available actions have changed
-                    setScrubberVisible(canSeekMedia());
+                if (playbackState != null) {
+                    updatePlaybackUi(playbackState);
                 } else {
-                    Log.d(TAG, "Controller missing data " + metadata + " " + playbackState);
                     clearTimer();
                 }
             } else {
-                Log.d(TAG, "No longer have a valid media controller");
                 clearTimer();
             }
         }
     };
 
+    private void updatePlaybackUi(PlaybackState state) {
+        long position = state.getPosition();
+        mSeekBar.setProgress((int) position);
+
+        mSeekBarElapsedTime.setText(millisecondsToTimeString(position));
+
+        // Update scrubber in case available actions have changed
+        setScrubberVisible(canSeekMedia(state));
+    }
+
     private String millisecondsToTimeString(long milliseconds) {
         long seconds = milliseconds / 1000;
         String text = DateUtils.formatElapsedTime(seconds);
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayout.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayout.java
index e6f4731..c214431 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayout.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayout.java
@@ -20,7 +20,7 @@
 import static com.android.systemui.statusbar.notification.ActivityLaunchAnimator.ExpandAnimationParameters;
 import static com.android.systemui.statusbar.notification.stack.StackScrollAlgorithm.ANCHOR_SCROLLING;
 import static com.android.systemui.statusbar.notification.stack.StackStateAnimator.ANIMATION_DURATION_SWIPE;
-import static com.android.systemui.statusbar.phone.NotificationIconAreaController.LOW_PRIORITY;
+import static com.android.systemui.statusbar.phone.NotificationIconAreaController.HIGH_PRIORITY;
 import static com.android.systemui.util.InjectionInflationController.VIEW_CONTEXT;
 
 import static java.lang.annotation.RetentionPolicy.SOURCE;
@@ -187,7 +187,7 @@
     private int mCurrentStackHeight = Integer.MAX_VALUE;
     private final Paint mBackgroundPaint = new Paint();
     private final boolean mShouldDrawNotificationBackground;
-    private boolean mLowPriorityBeforeSpeedBump;
+    private boolean mHighPriorityBeforeSpeedBump;
     private final boolean mAllowLongPress;
     private boolean mDismissRtl;
 
@@ -477,8 +477,6 @@
     private float mHorizontalPanelTranslation;
     private final NotificationLockscreenUserManager mLockscreenUserManager =
             Dependency.get(NotificationLockscreenUserManager.class);
-    protected final NotificationGutsManager mGutsManager =
-            Dependency.get(NotificationGutsManager.class);
     private final Rect mTmpRect = new Rect();
     private final NotificationEntryManager mEntryManager =
             Dependency.get(NotificationEntryManager.class);
@@ -586,12 +584,12 @@
 
         TunerService tunerService = Dependency.get(TunerService.class);
         tunerService.addTunable((key, newValue) -> {
-            if (key.equals(LOW_PRIORITY)) {
-                mLowPriorityBeforeSpeedBump = "1".equals(newValue);
+            if (key.equals(HIGH_PRIORITY)) {
+                mHighPriorityBeforeSpeedBump = "1".equals(newValue);
             } else if (key.equals(Settings.Secure.NOTIFICATION_DISMISS_RTL)) {
                 updateDismissRtlSetting("1".equals(newValue));
             }
-        }, LOW_PRIORITY, Settings.Secure.NOTIFICATION_DISMISS_RTL);
+        }, HIGH_PRIORITY, Settings.Secure.NOTIFICATION_DISMISS_RTL);
 
         mEntryManager.addNotificationEntryListener(new NotificationEntryListener() {
             @Override
@@ -625,7 +623,7 @@
         inflateFooterView();
         mVisualStabilityManager.setVisibilityLocationProvider(this::isInVisibleLocation);
         if (mAllowLongPress) {
-            setLongPressListener(mGutsManager::openGuts);
+            setLongPressListener(mNotificationGutsManager::openGuts);
         }
     }
 
@@ -656,15 +654,7 @@
     @Override
     @ShadeViewRefactor(RefactorComponent.SHADE_VIEW)
     public void onThemeChanged() {
-        int which;
-        if (mStatusBarState == StatusBarState.KEYGUARD
-                || mStatusBarState == StatusBarState.SHADE_LOCKED) {
-            which = WallpaperManager.FLAG_LOCK;
-        } else {
-            which = WallpaperManager.FLAG_SYSTEM;
-        }
-        final boolean useDarkText = mColorExtractor.getColors(which,
-                true /* ignoreVisibility */).supportsDarkText();
+        final boolean useDarkText = mColorExtractor.getNeutralColors().supportsDarkText();
         updateDecorViews(useDarkText);
 
         updateFooter();
@@ -870,8 +860,8 @@
         int backgroundRectTop = top;
         int lastSectionBottom =
                 mSections[0].getCurrentBounds().bottom + animationYOffset;
-        int previousLeft = left;
-        int previousRight = right;
+        int currentLeft = left;
+        int currentRight = right;
         boolean first = true;
         for (NotificationSection section : mSections) {
             if (section.getFirstVisibleChild() == null) {
@@ -884,23 +874,23 @@
             // as separate roundrects, as the rounded corners right next to each other look
             // bad.
             if (sectionTop - lastSectionBottom > DISTANCE_BETWEEN_ADJACENT_SECTIONS_PX
-                    || (previousLeft != ownLeft && !first)) {
-                canvas.drawRoundRect(ownLeft,
+                    || ((currentLeft != ownLeft || currentRight != ownRight) && !first)) {
+                canvas.drawRoundRect(currentLeft,
                         backgroundRectTop,
-                        ownRight,
+                        currentRight,
                         lastSectionBottom,
                         mCornerRadius, mCornerRadius, mBackgroundPaint);
                 backgroundRectTop = sectionTop;
             }
-            previousLeft = ownLeft;
-            previousRight = ownRight;
+            currentLeft = ownLeft;
+            currentRight = ownRight;
             lastSectionBottom =
                     section.getCurrentBounds().bottom + animationYOffset;
             first = false;
         }
-        canvas.drawRoundRect(previousLeft,
+        canvas.drawRoundRect(currentLeft,
                 backgroundRectTop,
-                previousRight,
+                currentRight,
                 lastSectionBottom,
                 mCornerRadius, mCornerRadius, mBackgroundPaint);
     }
@@ -3225,6 +3215,7 @@
     private void updateNotificationAnimationStates() {
         boolean running = mAnimationsEnabled || hasPulsingNotifications();
         mShelf.setAnimationsEnabled(running);
+        mIconAreaController.setAnimationsEnabled(running);
         int childCount = getChildCount();
         for (int i = 0; i < childCount; i++) {
             View child = getChildAt(i);
@@ -5766,10 +5757,10 @@
             ExpandableNotificationRow row = (ExpandableNotificationRow) view;
             currentIndex++;
             boolean beforeSpeedBump;
-            if (mLowPriorityBeforeSpeedBump) {
-                beforeSpeedBump = !row.getEntry().ambient;
-            } else {
+            if (mHighPriorityBeforeSpeedBump) {
                 beforeSpeedBump = row.getEntry().isHighPriority();
+            } else {
+                beforeSpeedBump = !row.getEntry().ambient;
             }
             if (beforeSpeedBump) {
                 speedBumpIndex = currentIndex;
@@ -6145,6 +6136,9 @@
                         .setType(MetricsEvent.TYPE_ACTION));
                 mHeadsUpManager.setMenuShown(notificationRow.getEntry(), true);
                 mSwipeHelper.onMenuShown(row);
+                mNotificationGutsManager.closeAndSaveGuts(true /* removeLeavebehind */,
+                        false /* force */, false /* removeControls */, -1 /* x */, -1 /* y */,
+                        false /* resetMenu */);
 
                 // Check to see if we want to go directly to the notfication guts
                 NotificationMenuRowPlugin provider = notificationRow.getProvider();
@@ -6152,7 +6146,7 @@
                     MenuItem item = provider.menuItemToExposeOnSnap();
                     if (item != null) {
                         Point origin = provider.getRevealAnimationOrigin();
-                        mGutsManager.openGuts(row, origin.x, origin.y, item);
+                        mNotificationGutsManager.openGuts(row, origin.x, origin.y, item);
                     } else  {
                         Log.e(TAG, "Provider has shouldShowGutsOnSnapOpen, but provided no "
                                 + "menu item in menuItemtoExposeOnSnap. Skipping.");
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/EdgeBackGestureHandler.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/EdgeBackGestureHandler.java
index 05a86fa..38ff468 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/EdgeBackGestureHandler.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/EdgeBackGestureHandler.java
@@ -152,6 +152,8 @@
     private WindowManager.LayoutParams mEdgePanelLp;
     private final Rect mSamplingRect = new Rect();
     private RegionSamplingHelper mRegionSamplingHelper;
+    private int mLeftInset;
+    private int mRightInset;
 
     public EdgeBackGestureHandler(Context context, OverviewProxyService overviewProxyService) {
         final Resources res = context.getResources();
@@ -299,7 +301,7 @@
             return false;
         }
 
-        if (x > mEdgeWidth && x < (mDisplaySize.x - mEdgeWidth)) {
+        if (x > mEdgeWidth + mLeftInset && x < (mDisplaySize.x - mEdgeWidth - mRightInset)) {
             return false;
         }
         boolean isInExcludedRegion = mExcludeRegion.contains(x, y);
@@ -325,7 +327,7 @@
             // Verify if this is in within the touch region and we aren't in immersive mode, and
             // either the bouncer is showing or the notification panel is hidden
             int stateFlags = mOverviewProxyService.getSystemUiStateFlags();
-            mIsOnLeftEdge = ev.getX() <= mEdgeWidth;
+            mIsOnLeftEdge = ev.getX() <= mEdgeWidth + mLeftInset;
             mAllowGesture = !QuickStepContract.isBackGestureDisabled(stateFlags)
                     && isWithinTouchRegion((int) ev.getX(), (int) ev.getY());
             if (mAllowGesture) {
@@ -400,7 +402,7 @@
 
     private void updateSamplingRect() {
         int top = mEdgePanelLp.y;
-        int left = mIsOnLeftEdge ? 0 : mDisplaySize.x - mEdgePanelLp.width;
+        int left = mIsOnLeftEdge ? mLeftInset : mDisplaySize.x - mRightInset - mEdgePanelLp.width;
         int right = left + mEdgePanelLp.width;
         int bottom = top + mEdgePanelLp.height;
         mSamplingRect.set(left, top, right, bottom);
@@ -442,6 +444,11 @@
         InputManager.getInstance().injectInputEvent(ev, InputManager.INJECT_INPUT_EVENT_MODE_ASYNC);
     }
 
+    public void setInsets(int leftInset, int rightInset) {
+        mLeftInset = leftInset;
+        mRightInset = rightInset;
+    }
+
     class SysUiInputEventReceiver extends InputEventReceiver {
         SysUiInputEventReceiver(InputChannel channel, Looper looper) {
             super(channel, looper);
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/FloatingRotationButton.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/FloatingRotationButton.java
index a4965ba..6bbeffa 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/FloatingRotationButton.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/FloatingRotationButton.java
@@ -16,8 +16,10 @@
 
 package com.android.systemui.statusbar.phone;
 
+import android.annotation.ColorInt;
 import android.content.Context;
 import android.content.res.Resources;
+import android.graphics.Color;
 import android.graphics.PixelFormat;
 import android.view.ContextThemeWrapper;
 import android.view.Gravity;
@@ -26,6 +28,7 @@
 import android.view.View;
 import android.view.WindowManager;
 
+import com.android.settingslib.Utils;
 import com.android.systemui.R;
 import com.android.systemui.statusbar.policy.KeyButtonDrawable;
 import com.android.systemui.statusbar.policy.KeyButtonView;
@@ -33,6 +36,8 @@
 /** Containing logic for the rotation button on the physical left bottom corner of the screen. */
 public class FloatingRotationButton implements RotationButton {
 
+    private static final float BACKGROUND_ALPHA = 0.92f;
+
     private final Context mContext;
     private final WindowManager mWindowManager;
     private final KeyButtonView mKeyButtonView;
@@ -73,8 +78,7 @@
             return false;
         }
         mIsShowing = true;
-        int flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
-                | WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN;
+        int flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE;
         final WindowManager.LayoutParams lp = new WindowManager.LayoutParams(mDiameter, mDiameter,
                 mMargin, mMargin, WindowManager.LayoutParams.TYPE_NAVIGATION_BAR_PANEL, flags,
                 PixelFormat.TRANSLUCENT);
@@ -152,8 +156,18 @@
     public KeyButtonDrawable getImageDrawable() {
         Context context = new ContextThemeWrapper(mContext.getApplicationContext(),
                 mRotationButtonController.getStyleRes());
-        return KeyButtonDrawable.create(context, R.drawable.ic_sysbar_rotate_button,
-                false /* shadow */, true /* hasOvalBg */);
+        final int dualToneDarkTheme = Utils.getThemeAttr(context, R.attr.darkIconTheme);
+        final int dualToneLightTheme = Utils.getThemeAttr(context, R.attr.lightIconTheme);
+        Context lightContext = new ContextThemeWrapper(context, dualToneLightTheme);
+        Context darkContext = new ContextThemeWrapper(context, dualToneDarkTheme);
+        @ColorInt int darkColor = Utils.getColorAttrDefaultColor(darkContext,
+                R.attr.singleToneColor);
+        Color ovalBackgroundColor = Color.valueOf(Color.red(darkColor), Color.green(darkColor),
+                Color.blue(darkColor), BACKGROUND_ALPHA);
+
+        return KeyButtonDrawable.create(lightContext,
+                Utils.getColorAttrDefaultColor(lightContext, R.attr.singleToneColor), darkColor,
+                R.drawable.ic_sysbar_rotate_button, false /* shadow */, ovalBackgroundColor);
     }
 
     @Override
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/LockIcon.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/LockIcon.java
index 61a3940..3d0c9e8 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/LockIcon.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/LockIcon.java
@@ -60,8 +60,6 @@
         StatusBarStateController.StateListener, ConfigurationController.ConfigurationListener,
         UnlockMethodCache.OnUnlockMethodChangedListener {
 
-    private static final int FP_DRAW_OFF_TIMEOUT = 800;
-
     private static final int STATE_LOCKED = 0;
     private static final int STATE_LOCK_OPEN = 1;
     private static final int STATE_SCANNING_FACE = 2;
@@ -77,8 +75,6 @@
 
     private int mLastState = 0;
     private boolean mTransientBiometricsError;
-    private boolean mScreenOn;
-    private boolean mLastScreenOn;
     private boolean mIsFaceUnlockState;
     private boolean mSimLocked;
     private int mDensity;
@@ -105,7 +101,6 @@
                     update(false /* force */);
                 }
             };
-    private final Runnable mDrawOffTimeout = () -> update(true /* forceUpdate */);
     private final DockManager.DockEventListener mDockEventListener =
             new DockManager.DockEventListener() {
                 @Override
@@ -122,18 +117,6 @@
     private final KeyguardUpdateMonitorCallback mUpdateMonitorCallback =
             new KeyguardUpdateMonitorCallback() {
                 @Override
-                public void onScreenTurnedOn() {
-                    mScreenOn = true;
-                    update();
-                }
-
-                @Override
-                public void onScreenTurnedOff() {
-                    mScreenOn = false;
-                    update();
-                }
-
-                @Override
                 public void onSimStateChanged(int subId, int slotId,
                         IccCardConstants.State simState) {
                     boolean oldSimLocked = mSimLocked;
@@ -246,7 +229,7 @@
         int state = getState();
         mIsFaceUnlockState = state == STATE_SCANNING_FACE;
         if (state != mLastState || mLastDozing != mDozing || mLastPulsing != mPulsing
-                || mLastScreenOn != mScreenOn || mLastBouncerVisible != mBouncerVisible || force) {
+                || mLastBouncerVisible != mBouncerVisible || force) {
             int iconAnimRes = getAnimationResForTransition(mLastState, state, mLastPulsing,
                     mPulsing, mLastDozing, mDozing, mBouncerVisible);
             boolean isAnim = iconAnimRes != -1;
@@ -285,15 +268,7 @@
             }
             updateDarkTint();
 
-            if (isAnim && !mLastScreenOn) {
-                removeCallbacks(mDrawOffTimeout);
-                postDelayed(mDrawOffTimeout, FP_DRAW_OFF_TIMEOUT);
-            } else {
-                removeCallbacks(mDrawOffTimeout);
-            }
-
             mLastState = state;
-            mLastScreenOn = mScreenOn;
             mLastDozing = mDozing;
             mLastPulsing = mPulsing;
             mLastBouncerVisible = mBouncerVisible;
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarFragment.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarFragment.java
index d94a335..79976d0 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarFragment.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarFragment.java
@@ -136,6 +136,7 @@
     protected final AssistManager mAssistManager;
     private final MetricsLogger mMetricsLogger;
     private final DeviceProvisionedController mDeviceProvisionedController;
+    private final StatusBarStateController mStatusBarStateController;
 
     protected NavigationBarView mNavigationBarView = null;
 
@@ -244,9 +245,11 @@
     public NavigationBarFragment(AccessibilityManagerWrapper accessibilityManagerWrapper,
             DeviceProvisionedController deviceProvisionedController, MetricsLogger metricsLogger,
             AssistManager assistManager, OverviewProxyService overviewProxyService,
-            NavigationModeController navigationModeController) {
+            NavigationModeController navigationModeController,
+            StatusBarStateController statusBarStateController) {
         mAccessibilityManagerWrapper = accessibilityManagerWrapper;
         mDeviceProvisionedController = deviceProvisionedController;
+        mStatusBarStateController = statusBarStateController;
         mMetricsLogger = metricsLogger;
         mAssistManager = assistManager;
         mAssistantAvailable = mAssistManager.getAssistInfoForUser(UserHandle.USER_CURRENT) != null;
@@ -951,7 +954,7 @@
     public void touchAutoDim() {
         getBarTransitions().setAutoDim(false);
         mHandler.removeCallbacks(mAutoDim);
-        int state = Dependency.get(StatusBarStateController.class).getState();
+        int state = mStatusBarStateController.getState();
         if (state != StatusBarState.KEYGUARD && state != StatusBarState.SHADE_LOCKED) {
             mHandler.postDelayed(mAutoDim, AUTODIM_TIMEOUT_MS);
         }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarTransitions.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarTransitions.java
index 2b5a28e..23cc0fc 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarTransitions.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarTransitions.java
@@ -213,9 +213,12 @@
 
     /**
      * Register {@code listener} to be notified when the color of nav bar elements changes.
+     *
+     * Returns the current nav bar color.
      */
-    public void addDarkIntensityListener(DarkIntensityListener listener) {
+    public float addDarkIntensityListener(DarkIntensityListener listener) {
         mDarkIntensityListeners.add(listener);
+        return mLightTransitionsController.getCurrentDarkIntensity();
     }
 
     /**
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarView.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarView.java
index 3ec1609..90bce39 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarView.java
@@ -238,7 +238,19 @@
             info.setTouchableInsets(InternalInsetsInfo.TOUCHABLE_INSETS_FRAME);
             return;
         }
+
         info.setTouchableInsets(InternalInsetsInfo.TOUCHABLE_INSETS_REGION);
+        ButtonDispatcher imeSwitchButton = getImeSwitchButton();
+        if (imeSwitchButton.getVisibility() == VISIBLE) {
+            // If the IME is not up, but the ime switch button is visible, then make sure that
+            // button is touchable
+            int[] loc = new int[2];
+            View buttonView = imeSwitchButton.getCurrentView();
+            buttonView.getLocationInWindow(loc);
+            info.touchableRegion.set(loc[0], loc[1], loc[0] + buttonView.getWidth(),
+                    loc[1] + buttonView.getHeight());
+            return;
+        }
         info.touchableRegion.setEmpty();
     };
 
@@ -1095,8 +1107,13 @@
 
     @Override
     public WindowInsets onApplyWindowInsets(WindowInsets insets) {
-        setPadding(insets.getSystemWindowInsetLeft(), insets.getSystemWindowInsetTop(),
-                insets.getSystemWindowInsetRight(), insets.getSystemWindowInsetBottom());
+        int leftInset = insets.getSystemWindowInsetLeft();
+        int rightInset = insets.getSystemWindowInsetRight();
+        setPadding(leftInset, insets.getSystemWindowInsetTop(), rightInset,
+                insets.getSystemWindowInsetBottom());
+        // we're passing the insets onto the gesture handler since the back arrow is only
+        // conditionally added and doesn't always get all the insets.
+        mEdgeBackGestureHandler.setInsets(leftInset, rightInset);
         return super.onApplyWindowInsets(insets);
     }
 
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationModeController.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationModeController.java
index 7cd8f7b..77eb469 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationModeController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationModeController.java
@@ -24,6 +24,9 @@
 import static android.view.WindowManagerPolicyConstants.NAV_BAR_MODE_GESTURAL;
 import static android.view.WindowManagerPolicyConstants.NAV_BAR_MODE_GESTURAL_OVERLAY;
 
+import android.app.Notification;
+import android.app.NotificationManager;
+import android.app.PendingIntent;
 import android.content.BroadcastReceiver;
 import android.content.ComponentName;
 import android.content.Context;
@@ -38,13 +41,16 @@
 import android.os.UserHandle;
 import android.provider.Settings;
 import android.provider.Settings.Secure;
+import android.text.TextUtils;
 import android.util.Log;
 import android.util.SparseBooleanArray;
 
 import com.android.systemui.Dumpable;
+import com.android.systemui.R;
 import com.android.systemui.UiOffloadThread;
 import com.android.systemui.shared.system.ActivityManagerWrapper;
 import com.android.systemui.statusbar.policy.DeviceProvisionedController;
+import com.android.systemui.util.NotificationChannels;
 
 import java.io.FileDescriptor;
 import java.io.PrintWriter;
@@ -63,6 +69,9 @@
     private static final String TAG = NavigationModeController.class.getSimpleName();
     private static final boolean DEBUG = false;
 
+    static final String SHARED_PREFERENCES_NAME = "navigation_mode_controller_preferences";
+    static final String PREFS_SWITCHED_FROM_GESTURE_NAV_KEY = "switched_from_gesture_nav";
+
     public interface ModeChangedListener {
         void onNavigationModeChanged(int mode);
     }
@@ -78,6 +87,8 @@
     private int mMode = NAV_BAR_MODE_3BUTTON;
     private ArrayList<ModeChangedListener> mListeners = new ArrayList<>();
 
+    private String mLastDefaultLauncher;
+
     private BroadcastReceiver mReceiver = new BroadcastReceiver() {
         @Override
         public void onReceive(Context context, Intent intent) {
@@ -92,7 +103,13 @@
                     if (DEBUG) {
                         Log.d(TAG, "ACTION_PREFERRED_ACTIVITY_CHANGED");
                     }
-                    switchFromGestureNavModeIfNotSupportedByDefaultLauncher();
+                    final String launcher = getDefaultLauncherPackageName(mCurrentUserContext);
+                    // Check if it is a default launcher change
+                    if (!TextUtils.equals(mLastDefaultLauncher, launcher)) {
+                        switchFromGestureNavModeIfNotSupportedByDefaultLauncher();
+                        showNotificationIfDefaultLauncherSupportsGestureNav();
+                        mLastDefaultLauncher = launcher;
+                    }
                     break;
             }
         }
@@ -157,6 +174,8 @@
         IntentFilter preferredActivityFilter = new IntentFilter(ACTION_PREFERRED_ACTIVITY_CHANGED);
         mContext.registerReceiverAsUser(mReceiver, UserHandle.ALL, preferredActivityFilter, null,
                 null);
+        // We are only interested in launcher changes, so keeping track of the current default.
+        mLastDefaultLauncher = getDefaultLauncherPackageName(mContext);
 
         updateCurrentInteractionMode(false /* notify */);
         switchFromGestureNavModeIfNotSupportedByDefaultLauncher();
@@ -287,6 +306,84 @@
         });
     }
 
+    private void switchFromGestureNavModeIfNotSupportedByDefaultLauncher() {
+        if (getCurrentInteractionMode(mCurrentUserContext) != NAV_BAR_MODE_GESTURAL) {
+            return;
+        }
+        final Boolean supported = isGestureNavSupportedByDefaultLauncher(mCurrentUserContext);
+        if (supported == null || supported) {
+            return;
+        }
+
+        setModeOverlay(NAV_BAR_MODE_3BUTTON_OVERLAY, USER_CURRENT);
+        showNotification(mCurrentUserContext, R.string.notification_content_system_nav_changed);
+        mCurrentUserContext.getSharedPreferences(SHARED_PREFERENCES_NAME, Context.MODE_PRIVATE)
+                .edit().putBoolean(PREFS_SWITCHED_FROM_GESTURE_NAV_KEY, true).apply();
+    }
+
+    private void showNotificationIfDefaultLauncherSupportsGestureNav() {
+        boolean previouslySwitchedFromGestureNav = mCurrentUserContext
+                .getSharedPreferences(SHARED_PREFERENCES_NAME, Context.MODE_PRIVATE)
+                .getBoolean(PREFS_SWITCHED_FROM_GESTURE_NAV_KEY, false);
+        if (!previouslySwitchedFromGestureNav) {
+            return;
+        }
+        if (getCurrentInteractionMode(mCurrentUserContext) == NAV_BAR_MODE_GESTURAL) {
+            return;
+        }
+        final Boolean supported = isGestureNavSupportedByDefaultLauncher(mCurrentUserContext);
+        if (supported == null || !supported) {
+            return;
+        }
+
+        showNotification(mCurrentUserContext, R.string.notification_content_gesture_nav_available);
+        mCurrentUserContext.getSharedPreferences(SHARED_PREFERENCES_NAME, Context.MODE_PRIVATE)
+                .edit().putBoolean(PREFS_SWITCHED_FROM_GESTURE_NAV_KEY, false).apply();
+    }
+
+    /**
+     * Returns null if there is no default launcher set for the current user. Returns true if the
+     * current default launcher supports Gesture Navigation. Returns false otherwise.
+     */
+    private Boolean isGestureNavSupportedByDefaultLauncher(Context context) {
+        final String defaultLauncherPackageName = getDefaultLauncherPackageName(context);
+        if (DEBUG) {
+            Log.d(TAG, "isGestureNavSupportedByDefaultLauncher:"
+                    + " defaultLauncher=" + defaultLauncherPackageName
+                    + " contextUser=" + context.getUserId());
+        }
+        if (defaultLauncherPackageName == null) {
+            return null;
+        }
+        ComponentName recentsComponentName = ComponentName.unflattenFromString(
+                context.getString(com.android.internal.R.string.config_recentsComponentName));
+        return recentsComponentName.getPackageName().equals(defaultLauncherPackageName);
+    }
+
+    private String getDefaultLauncherPackageName(Context context) {
+        final ComponentName cn = context.getPackageManager().getHomeActivities(new ArrayList<>());
+        if (cn == null) {
+            return null;
+        }
+        return cn.getPackageName();
+    }
+
+    private void showNotification(Context context, int resId) {
+        final CharSequence message = context.getResources().getString(resId);
+        if (DEBUG) {
+            Log.d(TAG, "showNotification: message=" + message);
+        }
+
+        final Notification.Builder builder =
+                new Notification.Builder(mContext, NotificationChannels.ALERTS)
+                        .setContentText(message)
+                        .setStyle(new Notification.BigTextStyle())
+                        .setSmallIcon(R.drawable.ic_info)
+                        .setAutoCancel(true)
+                        .setContentIntent(PendingIntent.getActivity(context, 0, new Intent(), 0));
+        context.getSystemService(NotificationManager.class).notify(TAG, 0, builder.build());
+    }
+
     @Override
     public void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
         pw.println("NavigationModeController:");
@@ -299,6 +396,12 @@
         }
         pw.println("  defaultOverlays=" + defaultOverlays);
         dumpAssetPaths(mCurrentUserContext);
+
+        pw.println("  defaultLauncher=" + mLastDefaultLauncher);
+        boolean previouslySwitchedFromGestureNav = mCurrentUserContext
+                .getSharedPreferences(SHARED_PREFERENCES_NAME, Context.MODE_PRIVATE)
+                .getBoolean(PREFS_SWITCHED_FROM_GESTURE_NAV_KEY, false);
+        pw.println("  previouslySwitchedFromGestureNav=" + previouslySwitchedFromGestureNav);
     }
 
     private void dumpAssetPaths(Context context) {
@@ -308,27 +411,4 @@
             Log.d(TAG, "    " + a.getAssetPath());
         }
     }
-
-    private void switchFromGestureNavModeIfNotSupportedByDefaultLauncher() {
-        if (getCurrentInteractionMode(mCurrentUserContext) == NAV_BAR_MODE_GESTURAL
-                && !isGestureNavSupportedByDefaultLauncher(mCurrentUserContext)) {
-            setModeOverlay(NAV_BAR_MODE_3BUTTON_OVERLAY, USER_CURRENT);
-        }
-    }
-
-    private boolean isGestureNavSupportedByDefaultLauncher(Context context) {
-        final ComponentName cn = context.getPackageManager().getHomeActivities(new ArrayList<>());
-        if (cn == null) {
-            // There is no default home app set for the current user, don't make any changes yet.
-            return true;
-        }
-        if (DEBUG) {
-            Log.d(TAG, "isGestureNavSupportedByDefaultLauncher: launcher=" + cn.getPackageName()
-                    + " contextUser=" + context.getUserId());
-        }
-
-        ComponentName recentsComponentName = ComponentName.unflattenFromString(context.getString(
-                com.android.internal.R.string.config_recentsComponentName));
-        return recentsComponentName.getPackageName().equals(cn.getPackageName());
-    }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationIconAreaController.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationIconAreaController.java
index e8ca3ee..98505cf 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationIconAreaController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationIconAreaController.java
@@ -24,6 +24,7 @@
 import com.android.systemui.statusbar.NotificationMediaManager;
 import com.android.systemui.statusbar.NotificationShelf;
 import com.android.systemui.statusbar.StatusBarIconView;
+import com.android.systemui.statusbar.StatusBarState;
 import com.android.systemui.statusbar.notification.NotificationEntryManager;
 import com.android.systemui.statusbar.notification.NotificationUtils;
 import com.android.systemui.statusbar.notification.collection.NotificationEntry;
@@ -40,7 +41,7 @@
 public class NotificationIconAreaController implements DarkReceiver,
         StatusBarStateController.StateListener {
 
-    public static final String LOW_PRIORITY = "low_priority";
+    public static final String HIGH_PRIORITY = "high_priority";
 
     private final ContrastColorUtil mContrastColorUtil;
     private final NotificationEntryManager mEntryManager;
@@ -78,6 +79,7 @@
     private Context mContext;
     private boolean mFullyDark;
     private boolean mShowLowPriority = true;
+    private boolean mAnimationsEnabled;
 
     /**
      * Ratio representing being awake or in ambient mode, where 1 is dark and 0 awake.
@@ -283,6 +285,25 @@
                 false /* hide centered icon */);
     }
 
+    /**
+     * If icons of the status bar should animate when they are added or removed.
+     */
+    public void setAnimationsEnabled(boolean enabled) {
+        mAnimationsEnabled = enabled;
+        updateAnimations();
+    }
+
+    @Override
+    public void onStateChanged(int newState) {
+        updateAnimations();
+    }
+
+    private void updateAnimations() {
+        boolean inShade = mStatusBarStateController.getState() == StatusBarState.SHADE;
+        mCenteredIcon.setAnimationsEnabled(mAnimationsEnabled && inShade);
+        mNotificationIcons.setAnimationsEnabled(mAnimationsEnabled && inShade);
+    }
+
     @VisibleForTesting
     boolean shouldShouldLowPriorityIcons() {
         return mShowLowPriority;
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationIconContainer.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationIconContainer.java
index 009afca..f458618 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationIconContainer.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationIconContainer.java
@@ -315,7 +315,7 @@
     @Override
     public void onViewRemoved(View child) {
         super.onViewRemoved(child);
-        if (child instanceof StatusBarIconView) {
+        if (mAnimationsEnabled && child instanceof StatusBarIconView) {
             boolean isReplacingIcon = isReplacingIcon(child);
             final StatusBarIconView icon = (StatusBarIconView) child;
             if (icon.getVisibleState() != StatusBarIconView.STATE_HIDDEN
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 92aa884..1027046 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelView.java
@@ -303,6 +303,8 @@
     private int mCurrentPanelAlpha;
     private final Paint mAlphaPaint = new Paint();
     private Runnable mPanelAlphaEndAction;
+    private float mBottomAreaShadeAlpha;
+    private final ValueAnimator mBottomAreaShadeAlphaAnimator;
     private AnimatorListenerAdapter mAnimatorListenerAdapter = new AnimatorListenerAdapter() {
         @Override
         public void onAnimationEnd(Animator animation) {
@@ -366,6 +368,14 @@
         mPulseExpansionHandler = pulseExpansionHandler;
         mThemeResId = context.getThemeResId();
         dynamicPrivacyController.addListener(this);
+
+        mBottomAreaShadeAlphaAnimator = ValueAnimator.ofFloat(1f, 0);
+        mBottomAreaShadeAlphaAnimator.addUpdateListener(animation -> {
+            mBottomAreaShadeAlpha = (float) animation.getAnimatedValue();
+            updateKeyguardBottomAreaAlpha();
+        });
+        mBottomAreaShadeAlphaAnimator.setDuration(160);
+        mBottomAreaShadeAlphaAnimator.setInterpolator(Interpolators.ALPHA_OUT);
     }
 
     /**
@@ -682,6 +692,7 @@
                     mClockPositionResult.clockX, CLOCK_ANIMATION_PROPERTIES, animateClock);
             PropertyAnimator.setProperty(mKeyguardStatusView, AnimatableProperty.Y,
                     mClockPositionResult.clockY, CLOCK_ANIMATION_PROPERTIES, animateClock);
+            updateNotificationTranslucency();
             updateClock();
             stackScrollerPadding = mClockPositionResult.stackScrollerPadding;
         }
@@ -1367,10 +1378,20 @@
             updateDozingVisibilities(false /* animate */);
         }
 
+        maybeAnimateBottomAreaAlpha();
         resetHorizontalPanelPosition();
         updateQsState();
     }
 
+    private void maybeAnimateBottomAreaAlpha() {
+        mBottomAreaShadeAlphaAnimator.cancel();
+        if (mBarState == StatusBarState.SHADE_LOCKED) {
+            mBottomAreaShadeAlphaAnimator.start();
+        } else {
+            mBottomAreaShadeAlpha = 1f;
+        }
+    }
+
     private final Runnable mAnimateKeyguardStatusViewInvisibleEndRunnable = new Runnable() {
         @Override
         public void run() {
@@ -1461,6 +1482,7 @@
         } else if (statusBarState == StatusBarState.KEYGUARD
                 || statusBarState == StatusBarState.SHADE_LOCKED) {
             mKeyguardBottomArea.setVisibility(View.VISIBLE);
+            mKeyguardBottomArea.setAlpha(1f);
         } else {
             mKeyguardBottomArea.setVisibility(View.GONE);
         }
@@ -1979,6 +2001,7 @@
                         ? 0 : KeyguardBouncer.ALPHA_EXPANSION_THRESHOLD, 1f,
                 0f, 1f, getExpandedFraction());
         float alpha = Math.min(expansionAlpha, 1 - getQsExpansionFraction());
+        alpha *= mBottomAreaShadeAlpha;
         mKeyguardBottomArea.setAffordanceAlpha(alpha);
         mKeyguardBottomArea.setImportantForAccessibility(alpha == 0f
                 ? IMPORTANT_FOR_ACCESSIBILITY_NO_HIDE_DESCENDANTS
@@ -2889,6 +2912,10 @@
         mNotificationStackScroller.setDark(mDozing, animate, wakeUpTouchLocation);
         mKeyguardBottomArea.setDozing(mDozing, animate);
 
+        if (dozing) {
+            mBottomAreaShadeAlphaAnimator.cancel();
+        }
+
         if (mBarState == StatusBarState.KEYGUARD
                 || mBarState == StatusBarState.SHADE_LOCKED) {
             updateDozingVisibilities(animate);
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBarPolicy.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBarPolicy.java
index ee43879..17c200e 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBarPolicy.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBarPolicy.java
@@ -42,10 +42,6 @@
 import com.android.systemui.R;
 import com.android.systemui.SysUiServiceProvider;
 import com.android.systemui.UiOffloadThread;
-import com.android.systemui.privacy.PrivacyItem;
-import com.android.systemui.privacy.PrivacyItemController;
-import com.android.systemui.privacy.PrivacyItemControllerKt;
-import com.android.systemui.privacy.PrivacyType;
 import com.android.systemui.qs.tiles.DndTile;
 import com.android.systemui.qs.tiles.RotationLockTile;
 import com.android.systemui.statusbar.CommandQueue;
@@ -66,9 +62,6 @@
 import com.android.systemui.statusbar.policy.UserInfoController;
 import com.android.systemui.statusbar.policy.ZenModeController;
 
-import java.io.PrintWriter;
-import java.io.StringWriter;
-import java.util.List;
 import java.util.Locale;
 
 /**
@@ -83,12 +76,12 @@
                 ZenModeController.Callback,
                 DeviceProvisionedListener,
                 KeyguardMonitor.Callback,
-                PrivacyItemController.Callback,
                 LocationController.LocationChangeCallback {
     private static final String TAG = "PhoneStatusBarPolicy";
     private static final boolean DEBUG = Log.isLoggable(TAG, Log.DEBUG);
 
-    public static final int LOCATION_STATUS_ICON_ID = PrivacyType.TYPE_LOCATION.getIconId();
+    public static final int LOCATION_STATUS_ICON_ID =
+            com.android.internal.R.drawable.perm_group_location;
 
     private final String mSlotCast;
     private final String mSlotHotspot;
@@ -102,8 +95,6 @@
     private final String mSlotHeadset;
     private final String mSlotDataSaver;
     private final String mSlotLocation;
-    private final String mSlotMicrophone;
-    private final String mSlotCamera;
     private final String mSlotSensorsOff;
 
     private final Context mContext;
@@ -121,7 +112,6 @@
     private final DeviceProvisionedController mProvisionedController;
     private final KeyguardMonitor mKeyguardMonitor;
     private final LocationController mLocationController;
-    private final PrivacyItemController mPrivacyItemController;
     private final UiOffloadThread mUiOffloadThread = Dependency.get(UiOffloadThread.class);
     private final SensorPrivacyController mSensorPrivacyController;
 
@@ -154,7 +144,6 @@
         mProvisionedController = Dependency.get(DeviceProvisionedController.class);
         mKeyguardMonitor = Dependency.get(KeyguardMonitor.class);
         mLocationController = Dependency.get(LocationController.class);
-        mPrivacyItemController = Dependency.get(PrivacyItemController.class);
         mSensorPrivacyController = Dependency.get(SensorPrivacyController.class);
 
         mSlotCast = context.getString(com.android.internal.R.string.status_bar_cast);
@@ -170,8 +159,6 @@
         mSlotHeadset = context.getString(com.android.internal.R.string.status_bar_headset);
         mSlotDataSaver = context.getString(com.android.internal.R.string.status_bar_data_saver);
         mSlotLocation = context.getString(com.android.internal.R.string.status_bar_location);
-        mSlotMicrophone = context.getString(com.android.internal.R.string.status_bar_microphone);
-        mSlotCamera = context.getString(com.android.internal.R.string.status_bar_camera);
         mSlotSensorsOff = context.getString(com.android.internal.R.string.status_bar_sensors_off);
 
         // listen for broadcasts
@@ -231,13 +218,6 @@
                 context.getString(R.string.accessibility_data_saver_on));
         mIconController.setIconVisibility(mSlotDataSaver, false);
 
-        // privacy items
-        mIconController.setIcon(mSlotMicrophone, PrivacyType.TYPE_MICROPHONE.getIconId(),
-                PrivacyType.TYPE_MICROPHONE.getName(mContext));
-        mIconController.setIconVisibility(mSlotMicrophone, false);
-        mIconController.setIcon(mSlotCamera, PrivacyType.TYPE_CAMERA.getIconId(),
-                PrivacyType.TYPE_CAMERA.getName(mContext));
-        mIconController.setIconVisibility(mSlotCamera, false);
         mIconController.setIcon(mSlotLocation, LOCATION_STATUS_ICON_ID,
                 mContext.getString(R.string.accessibility_location_active));
         mIconController.setIconVisibility(mSlotLocation, false);
@@ -257,7 +237,6 @@
         mNextAlarmController.addCallback(mNextAlarmCallback);
         mDataSaver.addCallback(this);
         mKeyguardMonitor.addCallback(this);
-        mPrivacyItemController.addCallback(this);
         mSensorPrivacyController.addCallback(mSensorPrivacyListener);
         mLocationController.addCallback(this);
 
@@ -601,46 +580,9 @@
         mIconController.setIconVisibility(mSlotDataSaver, isDataSaving);
     }
 
-    @Override  // PrivacyItemController.Callback
-    public void privacyChanged(List<PrivacyItem> privacyItems) {
-        updatePrivacyItems(privacyItems);
-    }
-
-    private void updatePrivacyItems(List<PrivacyItem> items) {
-        boolean showCamera = false;
-        boolean showMicrophone = false;
-        boolean showLocation = false;
-        for (PrivacyItem item : items) {
-            if (item == null /* b/124234367 */) {
-                if (DEBUG) {
-                    Log.e(TAG, "updatePrivacyItems - null item found");
-                    StringWriter out = new StringWriter();
-                    mPrivacyItemController.dump(null, new PrintWriter(out), null);
-                    Log.e(TAG, out.toString());
-                }
-                continue;
-            }
-            switch (item.getPrivacyType()) {
-                case TYPE_CAMERA:
-                    showCamera = true;
-                    break;
-                case TYPE_LOCATION:
-                    showLocation = true;
-                    break;
-                case TYPE_MICROPHONE:
-                    showMicrophone = true;
-                    break;
-            }
-        }
-
-        mIconController.setIconVisibility(mSlotCamera, showCamera);
-        mIconController.setIconVisibility(mSlotMicrophone, showMicrophone);
-        mIconController.setIconVisibility(mSlotLocation, showLocation);
-    }
-
     @Override
     public void onLocationActiveChanged(boolean active) {
-        if (!PrivacyItemControllerKt.isPermissionsHubEnabled()) updateLocation();
+        updateLocation();
     }
 
     // Updates the status view based on the current state of location requests.
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/RotationContextButton.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/RotationContextButton.java
index b117dec..24e7336 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/RotationContextButton.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/RotationContextButton.java
@@ -24,7 +24,6 @@
 import android.view.ContextThemeWrapper;
 import android.view.View;
 
-import com.android.systemui.shared.system.QuickStepContract;
 import com.android.systemui.statusbar.policy.KeyButtonDrawable;
 
 /** Containing logic for the rotation button in nav bar. */
@@ -61,7 +60,7 @@
         Context context = new ContextThemeWrapper(getContext().getApplicationContext(),
                 mRotationButtonController.getStyleRes());
         return KeyButtonDrawable.create(context, mIconResId, false /* shadow */,
-                QuickStepContract.isGesturalMode(mNavBarMode));
+                null /* ovalBackgroundColor */);
     }
 
     @Override
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 05a23fa..1fdabc0 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java
@@ -30,8 +30,6 @@
 import static com.android.systemui.keyguard.WakefulnessLifecycle.WAKEFULNESS_ASLEEP;
 import static com.android.systemui.keyguard.WakefulnessLifecycle.WAKEFULNESS_AWAKE;
 import static com.android.systemui.keyguard.WakefulnessLifecycle.WAKEFULNESS_WAKING;
-import static com.android.systemui.shared.system.QuickStepContract.SYSUI_STATE_BOUNCER_SHOWING;
-import static com.android.systemui.shared.system.QuickStepContract.SYSUI_STATE_STATUS_BAR_KEYGUARD_SHOWING;
 import static com.android.systemui.shared.system.WindowManagerWrapper.NAV_BAR_POS_INVALID;
 import static com.android.systemui.shared.system.WindowManagerWrapper.NAV_BAR_POS_LEFT;
 import static com.android.systemui.statusbar.NotificationLockscreenUserManager.PERMISSION_SELF;
@@ -169,7 +167,6 @@
 import com.android.systemui.plugins.statusbar.StatusBarStateController;
 import com.android.systemui.qs.QSFragment;
 import com.android.systemui.qs.QSPanel;
-import com.android.systemui.recents.OverviewProxyService;
 import com.android.systemui.recents.Recents;
 import com.android.systemui.recents.ScreenPinningRequest;
 import com.android.systemui.shared.system.WindowManagerWrapper;
@@ -320,17 +317,6 @@
     /** If true, the lockscreen will show a distinct wallpaper */
     public static final boolean ENABLE_LOCKSCREEN_WALLPAPER = true;
 
-    private static final AudioAttributes AUDIO_ATTRIBUTES =
-            new AudioAttributes.Builder()
-                    .setContentType(AudioAttributes.CONTENT_TYPE_SONIFICATION)
-                    // Temporary fix for b/123870990. No time in this release to
-                    // introduce a new vibration type, but we need to distinguish these vibrations
-                    // from other haptic feedback vibrations. Fortunately, Alarm vibrations have
-                    // exactly the same behavior as we need
-                    // TODO: refactor within the scope of b/132170758
-                    .setUsage(AudioAttributes.USAGE_ALARM)
-                    .build();
-
     static {
         boolean onlyCoreApps;
         try {
@@ -785,8 +771,6 @@
         int disabledFlags2 = result.mDisabledFlags2;
         Dependency.get(InitController.class).addPostInitTask(
                 () -> setUpDisableFlags(disabledFlags1, disabledFlags2));
-
-        updateSystemUiStateFlags();
     }
 
     // ================================================================================
@@ -1525,6 +1509,8 @@
 
     @Override  // UnlockMethodCache.OnUnlockMethodChangedListener
     public void onUnlockMethodStateChanged() {
+        // Unlock method state changed. Notify KeguardMonitor
+        updateKeyguardState();
         logStateToEventlog();
     }
 
@@ -3225,8 +3211,7 @@
 
         // Lock wallpaper defines the color of the majority of the views, hence we'll use it
         // to set our default theme.
-        final boolean lockDarkText = mColorExtractor.getColors(WallpaperManager.FLAG_LOCK, true
-                /* ignoreVisibility */).supportsDarkText();
+        final boolean lockDarkText = mColorExtractor.getNeutralColors().supportsDarkText();
         final int themeResId = lockDarkText ? R.style.Theme_SystemUI_Light : R.style.Theme_SystemUI;
         if (mContext.getThemeResId() != themeResId) {
             mContext.setTheme(themeResId);
@@ -3420,11 +3405,8 @@
         updateDozingState();
         checkBarModes();
         updateScrimController();
-        updateSystemUiStateFlags();
         mPresenter.updateMediaMetaData(false, mState != StatusBarState.KEYGUARD);
-        mKeyguardMonitor.notifyKeyguardState(mStatusBarKeyguardViewManager.isShowing(),
-                mUnlockMethodCache.isMethodSecure(),
-                mStatusBarKeyguardViewManager.isOccluded());
+        updateKeyguardState();
         Trace.endSection();
     }
 
@@ -3463,6 +3445,12 @@
         mStatusBarStateController.setIsDozing(dozing);
     }
 
+    private void updateKeyguardState() {
+        mKeyguardMonitor.notifyKeyguardState(mStatusBarKeyguardViewManager.isShowing(),
+                mUnlockMethodCache.isMethodSecure(),
+                mStatusBarKeyguardViewManager.isOccluded());
+    }
+
     public void onActivationReset() {
         mKeyguardIndicationController.hideTransientIndication();
     }
@@ -3587,16 +3575,6 @@
         if (!mBouncerShowing) {
             updatePanelExpansionForKeyguard();
         }
-        updateSystemUiStateFlags();
-    }
-
-    public void updateSystemUiStateFlags() {
-        OverviewProxyService overviewProxyService = Dependency.get(OverviewProxyService.class);
-        overviewProxyService.setSystemUiStateFlag(SYSUI_STATE_STATUS_BAR_KEYGUARD_SHOWING,
-                mStatusBarStateController.getState() == StatusBarState.KEYGUARD,
-                mDisplayId);
-        overviewProxyService.setSystemUiStateFlag(SYSUI_STATE_BOUNCER_SHOWING,
-                isBouncerShowing(), mDisplayId);
     }
 
     /**
@@ -3710,7 +3688,7 @@
 
     private void vibrateForCameraGesture() {
         // Make sure to pass -1 for repeat so VibratorService doesn't stop us when going to sleep.
-        mVibrator.vibrate(mCameraLaunchGestureVibePattern, -1 /* repeat */, AUDIO_ATTRIBUTES);
+        mVibrator.vibrate(mCameraLaunchGestureVibePattern, -1 /* repeat */);
     }
 
     /**
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarWindowController.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarWindowController.java
index 631920c..c73ed60 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarWindowController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarWindowController.java
@@ -18,11 +18,13 @@
 
 import static android.view.WindowManager.LayoutParams.LAYOUT_IN_DISPLAY_CUTOUT_MODE_ALWAYS;
 
+import static com.android.systemui.shared.system.QuickStepContract.SYSUI_STATE_BOUNCER_SHOWING;
+import static com.android.systemui.shared.system.QuickStepContract.SYSUI_STATE_STATUS_BAR_KEYGUARD_SHOWING;
+import static com.android.systemui.shared.system.QuickStepContract.SYSUI_STATE_STATUS_BAR_KEYGUARD_SHOWING_OCCLUDED;
 import static com.android.systemui.statusbar.NotificationRemoteInputManager.ENABLE_REMOTE_INPUT;
 
 import android.app.ActivityManager;
 import android.app.IActivityManager;
-import android.app.WallpaperManager;
 import android.content.Context;
 import android.content.pm.ActivityInfo;
 import android.content.res.Resources;
@@ -45,6 +47,7 @@
 import com.android.systemui.keyguard.KeyguardViewMediator;
 import com.android.systemui.plugins.statusbar.StatusBarStateController;
 import com.android.systemui.plugins.statusbar.StatusBarStateController.StateListener;
+import com.android.systemui.recents.OverviewProxyService;
 import com.android.systemui.statusbar.RemoteInputController.Callback;
 import com.android.systemui.statusbar.StatusBarState;
 import com.android.systemui.statusbar.SysuiStatusBarStateController;
@@ -315,6 +318,18 @@
             }
             mHasTopUi = mHasTopUiChanged;
         }
+        updateSystemUiStateFlags();
+    }
+
+    public void updateSystemUiStateFlags() {
+        int displayId = mContext.getDisplayId();
+        OverviewProxyService overviewProxyService = Dependency.get(OverviewProxyService.class);
+        overviewProxyService.setSystemUiStateFlag(SYSUI_STATE_STATUS_BAR_KEYGUARD_SHOWING,
+                mCurrentState.keyguardShowing && !mCurrentState.keyguardOccluded, displayId);
+        overviewProxyService.setSystemUiStateFlag(SYSUI_STATE_STATUS_BAR_KEYGUARD_SHOWING_OCCLUDED,
+                mCurrentState.keyguardShowing && mCurrentState.keyguardOccluded, displayId);
+        overviewProxyService.setSystemUiStateFlag(SYSUI_STATE_BOUNCER_SHOWING,
+                mCurrentState.bouncerShowing, displayId);
     }
 
     private void applyForceStatusBarVisibleFlag(State state) {
@@ -540,17 +555,7 @@
             return;
         }
 
-        StatusBarStateController state = Dependency.get(StatusBarStateController.class);
-        int which;
-        if (state.getState() == StatusBarState.KEYGUARD
-                || state.getState() == StatusBarState.SHADE_LOCKED) {
-            which = WallpaperManager.FLAG_LOCK;
-        } else {
-            which = WallpaperManager.FLAG_SYSTEM;
-        }
-        final boolean useDarkText = mColorExtractor.getColors(which,
-                true /* ignoreVisibility */).supportsDarkText();
-
+        final boolean useDarkText = mColorExtractor.getNeutralColors().supportsDarkText();
         // Make sure we have the correct navbar/statusbar colors.
         setKeyguardDark(useDarkText);
     }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/KeyButtonDrawable.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/KeyButtonDrawable.java
index 568de63..8fcaa67 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/KeyButtonDrawable.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/KeyButtonDrawable.java
@@ -82,9 +82,9 @@
     private AnimatedVectorDrawable mAnimatedDrawable;
 
     public KeyButtonDrawable(Drawable d, @ColorInt int lightColor, @ColorInt int darkColor,
-            boolean horizontalFlip, boolean hasOvalBg) {
+            boolean horizontalFlip, Color ovalBackgroundColor) {
         this(d, new ShadowDrawableState(lightColor, darkColor,
-                d instanceof AnimatedVectorDrawable, horizontalFlip, hasOvalBg));
+                d instanceof AnimatedVectorDrawable, horizontalFlip, ovalBackgroundColor));
     }
 
     private KeyButtonDrawable(Drawable d, ShadowDrawableState state) {
@@ -166,7 +166,7 @@
     public void setColorFilter(ColorFilter colorFilter) {
         mIconPaint.setColorFilter(colorFilter);
         if (mAnimatedDrawable != null) {
-            if (mState.mHasOvalBg) {
+            if (hasOvalBg()) {
                 mAnimatedDrawable.setColorFilter(
                         new PorterDuffColorFilter(mState.mLightColor, PorterDuff.Mode.SRC_IN));
             } else {
@@ -212,15 +212,6 @@
         return mState.mBaseWidth + (mState.mShadowSize + Math.abs(mState.mShadowOffsetX)) * 2;
     }
 
-    /** Return if the drawable has oval background. */
-    public boolean hasOvalBg() {
-        return mState.mHasOvalBg;
-    }
-
-    public int getDarkColor() {
-        return mState.mDarkColor;
-    }
-
     public boolean canAnimate() {
         return mState.mSupportsAnimation;
     }
@@ -290,6 +281,14 @@
         return mState.canApplyTheme();
     }
 
+    @ColorInt int getDrawableBackgroundColor() {
+        return mState.mOvalBackgroundColor.toArgb();
+    }
+
+    boolean hasOvalBg() {
+        return mState.mOvalBackgroundColor != null;
+    }
+
     private void regenerateBitmapIconCache() {
         final int width = getIntrinsicWidth();
         final int height = getIntrinsicHeight();
@@ -394,16 +393,16 @@
         final int mLightColor;
         final int mDarkColor;
         final boolean mSupportsAnimation;
-        final boolean mHasOvalBg;
+        final Color mOvalBackgroundColor;
 
         public ShadowDrawableState(@ColorInt int lightColor, @ColorInt int darkColor,
-                boolean animated, boolean horizontalFlip, boolean hasOvalBg) {
+                boolean animated, boolean horizontalFlip, Color ovalBackgroundColor) {
             mLightColor = lightColor;
             mDarkColor = darkColor;
             mSupportsAnimation = animated;
             mAlpha = 255;
             mHorizontalFlip = horizontalFlip;
-            mHasOvalBg = hasOvalBg;
+            mOvalBackgroundColor = ovalBackgroundColor;
         }
 
         @Override
@@ -428,16 +427,17 @@
      * @param ctx Context to get the drawable and determine the dark and light theme
      * @param icon the icon resource id
      * @param hasShadow if a shadow will appear with the drawable
-     * @param hasOvalBg if an oval bg will be drawn
+     * @param ovalBackgroundColor the color of the oval bg that will be drawn
      * @return KeyButtonDrawable
      */
     public static KeyButtonDrawable create(@NonNull Context ctx, @DrawableRes int icon,
-            boolean hasShadow, boolean hasOvalBg) {
+            boolean hasShadow, Color ovalBackgroundColor) {
         final int dualToneDarkTheme = Utils.getThemeAttr(ctx, R.attr.darkIconTheme);
         final int dualToneLightTheme = Utils.getThemeAttr(ctx, R.attr.lightIconTheme);
         Context lightContext = new ContextThemeWrapper(ctx, dualToneLightTheme);
         Context darkContext = new ContextThemeWrapper(ctx, dualToneDarkTheme);
-        return KeyButtonDrawable.create(lightContext, darkContext, icon, hasShadow, hasOvalBg);
+        return KeyButtonDrawable.create(lightContext, darkContext, icon, hasShadow,
+                ovalBackgroundColor);
     }
 
     /**
@@ -446,7 +446,7 @@
      */
     public static KeyButtonDrawable create(@NonNull Context ctx, @DrawableRes int icon,
             boolean hasShadow) {
-        return create(ctx, icon, hasShadow, false /* hasOvalBg */);
+        return create(ctx, icon, hasShadow, null /* ovalBackgroundColor */);
     }
 
     /**
@@ -454,11 +454,11 @@
      * {@link #create(Context, int, boolean, boolean)}.
      */
     public static KeyButtonDrawable create(Context lightContext, Context darkContext,
-            @DrawableRes int iconResId, boolean hasShadow, boolean hasOvalBg) {
+            @DrawableRes int iconResId, boolean hasShadow, Color ovalBackgroundColor) {
         return create(lightContext,
             Utils.getColorAttrDefaultColor(lightContext, R.attr.singleToneColor),
             Utils.getColorAttrDefaultColor(darkContext, R.attr.singleToneColor),
-            iconResId, hasShadow, hasOvalBg);
+            iconResId, hasShadow, ovalBackgroundColor);
     }
 
     /**
@@ -467,12 +467,12 @@
      */
     public static KeyButtonDrawable create(Context context, @ColorInt int lightColor,
             @ColorInt int darkColor, @DrawableRes int iconResId, boolean hasShadow,
-            boolean hasOvalBg) {
+            Color ovalBackgroundColor) {
         final Resources res = context.getResources();
         boolean isRtl = res.getConfiguration().getLayoutDirection() == View.LAYOUT_DIRECTION_RTL;
         Drawable d = context.getDrawable(iconResId);
         final KeyButtonDrawable drawable = new KeyButtonDrawable(d, lightColor, darkColor,
-                isRtl && d.isAutoMirrored(), hasOvalBg);
+                isRtl && d.isAutoMirrored(), ovalBackgroundColor);
         if (hasShadow) {
             int offsetX = res.getDimensionPixelSize(R.dimen.nav_key_button_shadow_offset_x);
             int offsetY = res.getDimensionPixelSize(R.dimen.nav_key_button_shadow_offset_y);
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/KeyButtonView.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/KeyButtonView.java
index c9579fd..64b2842 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/KeyButtonView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/KeyButtonView.java
@@ -79,6 +79,7 @@
     private final MetricsLogger mMetricsLogger = Dependency.get(MetricsLogger.class);
     private final InputManager mInputManager;
     private final Paint mOvalBgPaint = new Paint(Paint.ANTI_ALIAS_FLAG | Paint.FILTER_BITMAP_FLAG);
+    private float mDarkIntensity;
     private boolean mHasOvalBg = false;
 
     private final Runnable mCheckLongPress = new Runnable() {
@@ -304,6 +305,23 @@
         return true;
     }
 
+    @Override
+    public void setImageDrawable(Drawable drawable) {
+        super.setImageDrawable(drawable);
+
+        if (drawable == null) {
+            return;
+        }
+        KeyButtonDrawable keyButtonDrawable = (KeyButtonDrawable) drawable;
+        keyButtonDrawable.setDarkIntensity(mDarkIntensity);
+        mHasOvalBg = keyButtonDrawable.hasOvalBg();
+        if (mHasOvalBg) {
+            mOvalBgPaint.setColor(keyButtonDrawable.getDrawableBackgroundColor());
+        }
+        mRipple.setType(keyButtonDrawable.hasOvalBg() ? KeyButtonRipple.Type.OVAL
+                : KeyButtonRipple.Type.ROUNDED_RECT);
+    }
+
     public void playSoundEffect(int soundConstant) {
         if (!mPlaySounds) return;
         mAudioManager.playSoundEffect(soundConstant, ActivityManager.getCurrentUser());
@@ -360,17 +378,11 @@
 
     @Override
     public void setDarkIntensity(float darkIntensity) {
+        mDarkIntensity = darkIntensity;
+
         Drawable drawable = getDrawable();
         if (drawable != null) {
-            KeyButtonDrawable keyButtonDrawable = (KeyButtonDrawable) drawable;
-            keyButtonDrawable.setDarkIntensity(darkIntensity);
-            mHasOvalBg = keyButtonDrawable.hasOvalBg();
-            if (mHasOvalBg) {
-                mOvalBgPaint.setColor(keyButtonDrawable.getDarkColor());
-            }
-            mRipple.setType(keyButtonDrawable.hasOvalBg() ? KeyButtonRipple.Type.OVAL
-                    : KeyButtonRipple.Type.ROUNDED_RECT);
-
+            ((KeyButtonDrawable) drawable).setDarkIntensity(darkIntensity);
             // Since we reuse the same drawable for multiple views, we need to invalidate the view
             // manually.
             invalidate();
diff --git a/packages/SystemUI/src/com/android/systemui/util/leak/GarbageMonitor.java b/packages/SystemUI/src/com/android/systemui/util/leak/GarbageMonitor.java
index b590e77..aa3fd5f 100644
--- a/packages/SystemUI/src/com/android/systemui/util/leak/GarbageMonitor.java
+++ b/packages/SystemUI/src/com/android/systemui/util/leak/GarbageMonitor.java
@@ -66,7 +66,11 @@
     private static final String FORCE_ENABLE_LEAK_REPORTING = "sysui_force_enable_leak_reporting";
 
     private static final boolean HEAP_TRACKING_ENABLED = Build.IS_DEBUGGABLE;
-    private static final boolean ENABLE_AM_HEAP_LIMIT = true; // use ActivityManager.setHeapLimit
+
+    // whether to use ActivityManager.setHeapLimit
+    private static final boolean ENABLE_AM_HEAP_LIMIT = Build.IS_DEBUGGABLE;
+    // heap limit value, in KB (overrides R.integer.watch_heap_limit)
+    private static final String SETTINGS_KEY_AM_HEAP_LIMIT = "systemui_am_heap_limit";
 
     private static final String TAG = "GarbageMonitor";
 
@@ -112,7 +116,9 @@
         mDumpTruck = new DumpTruck(mContext);
 
         if (ENABLE_AM_HEAP_LIMIT) {
-            mHeapLimit = mContext.getResources().getInteger(R.integer.watch_heap_limit);
+            mHeapLimit = Settings.Global.getInt(context.getContentResolver(),
+                    SETTINGS_KEY_AM_HEAP_LIMIT,
+                    mContext.getResources().getInteger(R.integer.watch_heap_limit));
         }
     }
 
@@ -343,6 +349,9 @@
     public static class MemoryTile extends QSTileImpl<QSTile.State> {
         public static final String TILE_SPEC = "dbg:mem";
 
+        // Tell QSTileHost.java to toss this into the default tileset?
+        public static final boolean ADD_TO_DEFAULT_ON_DEBUGGABLE_BUILDS = true;
+
         private final GarbageMonitor gm;
         private ProcessMemInfo pmi;
 
diff --git a/packages/SystemUI/tests/src/com/android/systemui/ScreenDecorationsTest.java b/packages/SystemUI/tests/src/com/android/systemui/ScreenDecorationsTest.java
index 64ab060..3b5e12c 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/ScreenDecorationsTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/ScreenDecorationsTest.java
@@ -45,6 +45,7 @@
 import android.view.Display;
 import android.view.View;
 import android.view.WindowManager;
+import android.view.WindowManagerPolicyConstants;
 
 import androidx.test.filters.SmallTest;
 
@@ -52,6 +53,7 @@
 import com.android.systemui.ScreenDecorations.TunablePaddingTagListener;
 import com.android.systemui.fragments.FragmentHostManager;
 import com.android.systemui.fragments.FragmentService;
+import com.android.systemui.statusbar.phone.NavigationModeController;
 import com.android.systemui.statusbar.phone.StatusBar;
 import com.android.systemui.statusbar.phone.StatusBarWindowView;
 import com.android.systemui.tuner.TunablePadding;
@@ -78,6 +80,7 @@
     private TunerService mTunerService;
     private StatusBarWindowView mView;
     private TunablePaddingService mTunablePaddingService;
+    private NavigationModeController mNavigationModeController;
 
     @Before
     public void setup() {
@@ -87,6 +90,8 @@
         mTunablePaddingService = mDependency.injectMockDependency(TunablePaddingService.class);
         mTunerService = mDependency.injectMockDependency(TunerService.class);
         mFragmentService = mDependency.injectMockDependency(FragmentService.class);
+        mNavigationModeController = mDependency.injectMockDependency(
+                NavigationModeController.class);
 
         mStatusBar = mock(StatusBar.class);
         mWindowManager = mock(WindowManager.class);
@@ -208,6 +213,54 @@
     }
 
     @Test
+    public void testAssistHandles() {
+        mContext.getOrCreateTestableResources().addOverride(
+                com.android.internal.R.bool.config_fillMainBuiltInDisplayCutout, false);
+        mContext.getOrCreateTestableResources().addOverride(
+                com.android.internal.R.dimen.rounded_corner_radius, 0);
+        mContext.getOrCreateTestableResources().addOverride(
+                com.android.internal.R.dimen.rounded_corner_radius_top, 0);
+        mContext.getOrCreateTestableResources().addOverride(
+                com.android.internal.R.dimen.rounded_corner_radius_bottom, 0);
+        mContext.getOrCreateTestableResources()
+                .addOverride(dimen.rounded_corner_content_padding, 0);
+        when(mNavigationModeController.addListener(any())).thenReturn(
+                WindowManagerPolicyConstants.NAV_BAR_MODE_GESTURAL);
+
+        mScreenDecorations.start();
+
+        // Add 2 windows for rounded corners (top and bottom).
+        verify(mWindowManager, times(2)).addView(any(), any());
+    }
+
+    @Test
+    public void testDelayedAssistHandles() {
+        mContext.getOrCreateTestableResources().addOverride(
+                com.android.internal.R.bool.config_fillMainBuiltInDisplayCutout, false);
+        mContext.getOrCreateTestableResources().addOverride(
+                com.android.internal.R.dimen.rounded_corner_radius, 0);
+        mContext.getOrCreateTestableResources().addOverride(
+                com.android.internal.R.dimen.rounded_corner_radius_top, 0);
+        mContext.getOrCreateTestableResources().addOverride(
+                com.android.internal.R.dimen.rounded_corner_radius_bottom, 0);
+        mContext.getOrCreateTestableResources()
+                .addOverride(dimen.rounded_corner_content_padding, 0);
+        when(mNavigationModeController.addListener(any())).thenReturn(
+                WindowManagerPolicyConstants.NAV_BAR_MODE_3BUTTON);
+
+        mScreenDecorations.start();
+
+        // No handles and no corners
+        verify(mWindowManager, never()).addView(any(), any());
+
+        mScreenDecorations.handleNavigationModeChange(
+                WindowManagerPolicyConstants.NAV_BAR_MODE_GESTURAL);
+
+        // Add 2 windows for rounded corners (top and bottom).
+        verify(mWindowManager, times(2)).addView(any(), any());
+    }
+
+    @Test
     public void hasRoundedCornerOverlayFlagSet() {
         assertThat(mScreenDecorations.getWindowLayoutParams().privateFlags
                         & PRIVATE_FLAG_IS_ROUNDED_CORNERS_OVERLAY,
diff --git a/packages/SystemUI/tests/src/com/android/systemui/appops/AppOpsControllerTest.java b/packages/SystemUI/tests/src/com/android/systemui/appops/AppOpsControllerTest.java
index cc31531..bd7f897 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/appops/AppOpsControllerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/appops/AppOpsControllerTest.java
@@ -25,11 +25,9 @@
 import static org.mockito.ArgumentMatchers.anyInt;
 import static org.mockito.ArgumentMatchers.anyLong;
 import static org.mockito.ArgumentMatchers.anyString;
-import static org.mockito.ArgumentMatchers.eq;
 import static org.mockito.Mockito.never;
 import static org.mockito.Mockito.times;
 import static org.mockito.Mockito.verify;
-import static org.mockito.Mockito.when;
 
 import android.app.AppOpsManager;
 import android.content.pm.PackageManager;
@@ -55,7 +53,6 @@
     private static final String TEST_PACKAGE_NAME = "test";
     private static final int TEST_UID = UserHandle.getUid(0, 0);
     private static final int TEST_UID_OTHER = UserHandle.getUid(1, 0);
-    private static final int TEST_UID_NON_USER_SENSITIVE = UserHandle.getUid(2, 0);
 
     @Mock
     private AppOpsManager mAppOpsManager;
@@ -74,18 +71,6 @@
 
         getContext().addMockSystemService(AppOpsManager.class, mAppOpsManager);
 
-        // All permissions of TEST_UID and TEST_UID_OTHER are user sensitive. None of
-        // TEST_UID_NON_USER_SENSITIVE are user sensitive.
-        getContext().setMockPackageManager(mPackageManager);
-        when(mPackageManager.getPermissionFlags(anyString(), anyString(),
-                eq(UserHandle.getUserHandleForUid(TEST_UID)))).thenReturn(
-                PackageManager.FLAG_PERMISSION_USER_SENSITIVE_WHEN_GRANTED);
-        when(mPackageManager.getPermissionFlags(anyString(), anyString(),
-                eq(UserHandle.getUserHandleForUid(TEST_UID_OTHER)))).thenReturn(
-                PackageManager.FLAG_PERMISSION_USER_SENSITIVE_WHEN_GRANTED);
-        when(mPackageManager.getPermissionFlags(anyString(), anyString(),
-                eq(UserHandle.getUserHandleForUid(TEST_UID_NON_USER_SENSITIVE)))).thenReturn(0);
-
         mController = new AppOpsControllerImpl(mContext, Dependency.get(Dependency.BG_LOOPER));
     }
 
@@ -178,14 +163,6 @@
     }
 
     @Test
-    public void nonUserSensitiveOpsAreIgnored() {
-        mController.onOpActiveChanged(AppOpsManager.OP_RECORD_AUDIO,
-                TEST_UID_NON_USER_SENSITIVE, TEST_PACKAGE_NAME, true);
-        assertEquals(0, mController.getActiveAppOpsForUser(
-                UserHandle.getUserId(TEST_UID_NON_USER_SENSITIVE)).size());
-    }
-
-    @Test
     public void opNotedScheduledForRemoval() {
         mController.setBGHandler(mMockHandler);
         mController.onOpNoted(AppOpsManager.OP_FINE_LOCATION, TEST_UID, TEST_PACKAGE_NAME,
diff --git a/packages/SystemUI/tests/src/com/android/systemui/assist/AssistHandleBehaviorControllerTest.java b/packages/SystemUI/tests/src/com/android/systemui/assist/AssistHandleBehaviorControllerTest.java
index 18f114a..a583b1c 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/assist/AssistHandleBehaviorControllerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/assist/AssistHandleBehaviorControllerTest.java
@@ -20,6 +20,7 @@
 import static org.mockito.ArgumentMatchers.any;
 import static org.mockito.ArgumentMatchers.anyInt;
 import static org.mockito.ArgumentMatchers.anyLong;
+import static org.mockito.ArgumentMatchers.eq;
 import static org.mockito.Mockito.doAnswer;
 import static org.mockito.Mockito.inOrder;
 import static org.mockito.Mockito.reset;
@@ -35,11 +36,13 @@
 import androidx.test.filters.SmallTest;
 
 import com.android.internal.app.AssistUtils;
+import com.android.internal.config.sysui.SystemUiDeviceConfigFlags;
 import com.android.systemui.ScreenDecorations;
 import com.android.systemui.SysuiTestCase;
 import com.android.systemui.plugins.statusbar.StatusBarStateController;
 import com.android.systemui.recents.OverviewProxyService;
 
+import org.junit.After;
 import org.junit.Before;
 import org.junit.Test;
 import org.junit.runner.RunWith;
@@ -59,6 +62,7 @@
     @Mock private ScreenDecorations mMockScreenDecorations;
     @Mock private AssistUtils mMockAssistUtils;
     @Mock private Handler mMockHandler;
+    @Mock private PhenotypeHelper mMockPhenotypeHelper;
     @Mock private AssistHandleBehaviorController.BehaviorController mMockBehaviorController;
 
     @Before
@@ -69,14 +73,21 @@
         doAnswer(answerVoid(Runnable::run)).when(mMockHandler).post(any(Runnable.class));
         doAnswer(answerVoid(Runnable::run)).when(mMockHandler)
                 .postDelayed(any(Runnable.class), anyLong());
+
         mAssistHandleBehaviorController =
                 new AssistHandleBehaviorController(
                         mContext,
                         mMockAssistUtils,
                         mMockHandler, () -> mMockScreenDecorations,
+                        mMockPhenotypeHelper,
                         mMockBehaviorController);
     }
 
+    @After
+    public void teardown() {
+        mAssistHandleBehaviorController.setBehavior(AssistHandleBehavior.OFF);
+    }
+
     @Test
     public void hide_hidesHandlesWhenShowing() {
         // Arrange
@@ -185,6 +196,9 @@
     public void showAndGo_doesNothingIfRecentlyHidden() {
         // Arrange
         when(mMockAssistUtils.getAssistComponentForUser(anyInt())).thenReturn(COMPONENT_NAME);
+        when(mMockPhenotypeHelper.getLong(
+                eq(SystemUiDeviceConfigFlags.ASSIST_HANDLES_SHOWN_FREQUENCY_THRESHOLD_MS),
+                anyLong())).thenReturn(10000L);
         mAssistHandleBehaviorController.showAndGo();
         reset(mMockScreenDecorations);
 
@@ -210,6 +224,87 @@
     }
 
     @Test
+    public void showAndGoDelayed_showsThenHidesHandlesWhenHiding() {
+        // Arrange
+        when(mMockAssistUtils.getAssistComponentForUser(anyInt())).thenReturn(COMPONENT_NAME);
+        mAssistHandleBehaviorController.hide();
+        reset(mMockScreenDecorations);
+
+        // Act
+        mAssistHandleBehaviorController.showAndGoDelayed(1000, false);
+
+        // Assert
+        InOrder inOrder = inOrder(mMockScreenDecorations);
+        inOrder.verify(mMockScreenDecorations).setAssistHintVisible(true);
+        inOrder.verify(mMockScreenDecorations).setAssistHintVisible(false);
+        inOrder.verifyNoMoreInteractions();
+    }
+
+    @Test
+    public void showAndGoDelayed_hidesHandlesAfterTimeoutWhenShowing() {
+        // Arrange
+        when(mMockAssistUtils.getAssistComponentForUser(anyInt())).thenReturn(COMPONENT_NAME);
+        mAssistHandleBehaviorController.showAndStay();
+        reset(mMockScreenDecorations);
+
+        // Act
+        mAssistHandleBehaviorController.showAndGoDelayed(1000, false);
+
+        // Assert
+        verify(mMockScreenDecorations).setAssistHintVisible(false);
+        verifyNoMoreInteractions(mMockScreenDecorations);
+    }
+
+    @Test
+    public void showAndGoDelayed_hidesInitiallyThenShowsThenHidesAfterTimeoutWhenHideRequested() {
+        // Arrange
+        when(mMockAssistUtils.getAssistComponentForUser(anyInt())).thenReturn(COMPONENT_NAME);
+        mAssistHandleBehaviorController.showAndStay();
+        reset(mMockScreenDecorations);
+
+        // Act
+        mAssistHandleBehaviorController.showAndGoDelayed(1000, true);
+
+        // Assert
+        InOrder inOrder = inOrder(mMockScreenDecorations);
+        inOrder.verify(mMockScreenDecorations).setAssistHintVisible(false);
+        inOrder.verify(mMockScreenDecorations).setAssistHintVisible(true);
+        inOrder.verify(mMockScreenDecorations).setAssistHintVisible(false);
+        inOrder.verifyNoMoreInteractions();
+    }
+
+    @Test
+    public void showAndGoDelayed_doesNothingIfRecentlyHidden() {
+        // Arrange
+        when(mMockAssistUtils.getAssistComponentForUser(anyInt())).thenReturn(COMPONENT_NAME);
+        when(mMockPhenotypeHelper.getLong(
+                eq(SystemUiDeviceConfigFlags.ASSIST_HANDLES_SHOWN_FREQUENCY_THRESHOLD_MS),
+                anyLong())).thenReturn(10000L);
+        mAssistHandleBehaviorController.showAndGo();
+        reset(mMockScreenDecorations);
+
+        // Act
+        mAssistHandleBehaviorController.showAndGoDelayed(1000, false);
+
+        // Assert
+        verifyNoMoreInteractions(mMockScreenDecorations);
+    }
+
+    @Test
+    public void showAndGoDelayed_doesNothingWhenThereIsNoAssistant() {
+        // Arrange
+        when(mMockAssistUtils.getAssistComponentForUser(anyInt())).thenReturn(null);
+        mAssistHandleBehaviorController.hide();
+        reset(mMockScreenDecorations);
+
+        // Act
+        mAssistHandleBehaviorController.showAndGoDelayed(1000, false);
+
+        // Assert
+        verifyNoMoreInteractions(mMockScreenDecorations);
+    }
+
+    @Test
     public void setBehavior_activatesTheBehaviorWhenInGesturalMode() {
         // Arrange
         when(mMockAssistUtils.getAssistComponentForUser(anyInt())).thenReturn(COMPONENT_NAME);
diff --git a/packages/SystemUI/tests/src/com/android/systemui/colorextraction/SysuiColorExtractorTests.java b/packages/SystemUI/tests/src/com/android/systemui/colorextraction/SysuiColorExtractorTests.java
index 9c2c822..41747f4 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/colorextraction/SysuiColorExtractorTests.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/colorextraction/SysuiColorExtractorTests.java
@@ -40,6 +40,7 @@
 import org.junit.Before;
 import org.junit.Test;
 import org.junit.runner.RunWith;
+import org.mockito.Mock;
 import org.mockito.MockitoAnnotations;
 
 /**
@@ -57,6 +58,8 @@
             ColorExtractor.TYPE_DARK,
             ColorExtractor.TYPE_EXTRA_DARK};
 
+    @Mock
+    private WallpaperManager mWallpaperManager;
     private ColorExtractor.GradientColors mColors;
     private SysuiColorExtractor mColorExtractor;
 
@@ -72,32 +75,15 @@
                     outGradientColorsNormal.set(mColors);
                     outGradientColorsDark.set(mColors);
                     outGradientColorsExtraDark.set(mColors);
-                }, mock(ConfigurationController.class), false);
+                }, mock(ConfigurationController.class), mWallpaperManager, true /* immediately */);
     }
 
     @Test
-    public void getColors_usesGreyIfWallpaperNotVisible() {
-        simulateEvent(mColorExtractor);
-        mColorExtractor.setWallpaperVisible(false);
-
-        ColorExtractor.GradientColors fallbackColors = mColorExtractor.getNeutralColors();
-
-        for (int type : sTypes) {
-            assertEquals("Not using fallback!",
-                    mColorExtractor.getColors(WallpaperManager.FLAG_SYSTEM, type), fallbackColors);
-            assertNotEquals("Wallpaper visibility event should not affect lock wallpaper.",
-                    mColorExtractor.getColors(WallpaperManager.FLAG_LOCK, type), fallbackColors);
-        }
-    }
-
-    @Test
-    public void getColors_doesntUseFallbackIfVisible() {
+    public void getColors() {
         mColors.setMainColor(Color.RED);
         mColors.setSecondaryColor(Color.RED);
 
         simulateEvent(mColorExtractor);
-        mColorExtractor.setWallpaperVisible(true);
-
         for (int which : sWhich) {
             for (int type : sTypes) {
                 assertEquals("Not using extracted colors!",
@@ -109,8 +95,7 @@
     @Test
     public void getColors_fallbackWhenMediaIsVisible() {
         simulateEvent(mColorExtractor);
-        mColorExtractor.setWallpaperVisible(true);
-        mColorExtractor.setHasBackdrop(true);
+        mColorExtractor.setHasMediaArtwork(true);
 
         ColorExtractor.GradientColors fallbackColors = mColorExtractor.getNeutralColors();
 
@@ -127,7 +112,7 @@
         Tonal tonal = mock(Tonal.class);
         ConfigurationController configurationController = mock(ConfigurationController.class);
         SysuiColorExtractor sysuiColorExtractor = new SysuiColorExtractor(getContext(),
-                tonal, configurationController, false /* registerVisibility */);
+                tonal, configurationController, mWallpaperManager, true /* immediately */);
         verify(configurationController).addCallback(eq(sysuiColorExtractor));
 
         reset(tonal);
diff --git a/packages/SystemUI/tests/src/com/android/systemui/doze/DozeSensorsTest.java b/packages/SystemUI/tests/src/com/android/systemui/doze/DozeSensorsTest.java
index 4467faf..3304291 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/doze/DozeSensorsTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/doze/DozeSensorsTest.java
@@ -27,10 +27,12 @@
 import static org.mockito.Mockito.mock;
 import static org.mockito.Mockito.never;
 import static org.mockito.Mockito.reset;
+import static org.mockito.Mockito.times;
 import static org.mockito.Mockito.verify;
 import static org.mockito.Mockito.when;
 
 import android.app.AlarmManager;
+import android.database.ContentObserver;
 import android.hardware.display.AmbientDisplayConfiguration;
 import android.testing.AndroidTestingRunner;
 import android.testing.TestableLooper;
@@ -39,6 +41,7 @@
 import androidx.test.filters.SmallTest;
 
 import com.android.systemui.SysuiTestCase;
+import com.android.systemui.doze.DozeSensors.TriggerSensor;
 import com.android.systemui.plugins.SensorManagerPlugin;
 import com.android.systemui.statusbar.phone.DozeParameters;
 import com.android.systemui.util.AsyncSensorManager;
@@ -73,6 +76,8 @@
     private Consumer<Boolean> mProxCallback;
     @Mock
     private AlwaysOnDisplayPolicy mAlwaysOnDisplayPolicy;
+    @Mock
+    private TriggerSensor mMockTriggerSensor;
     private SensorManagerPlugin.SensorEventListener mWakeLockScreenListener;
     private TestableLooper mTestableLooper;
     private DozeSensors mDozeSensors;
@@ -107,6 +112,25 @@
                 anyBoolean(), anyFloat(), anyFloat(), eq(null));
     }
 
+    @Test
+    public void testSetListening_firstTrue_registerSettingsObserver() {
+        mDozeSensors.mSensors = new TriggerSensor[] {mMockTriggerSensor};
+
+        mDozeSensors.setListening(true);
+
+        verify(mMockTriggerSensor).registerSettingsObserver(any(ContentObserver.class));
+    }
+
+    @Test
+    public void testSetListening_twiceTrue_onlyRegisterSettingsObserverOnce() {
+        mDozeSensors.mSensors = new TriggerSensor[] {mMockTriggerSensor};
+        mDozeSensors.setListening(true);
+
+        mDozeSensors.setListening(true);
+
+        verify(mMockTriggerSensor, times(1)).registerSettingsObserver(any(ContentObserver.class));
+    }
+
     private class TestableDozeSensors extends DozeSensors {
 
         TestableDozeSensors() {
diff --git a/packages/SystemUI/tests/src/com/android/systemui/privacy/PrivacyDialogBuilderTest.kt b/packages/SystemUI/tests/src/com/android/systemui/privacy/PrivacyDialogBuilderTest.kt
deleted file mode 100644
index 6302f9d..0000000
--- a/packages/SystemUI/tests/src/com/android/systemui/privacy/PrivacyDialogBuilderTest.kt
+++ /dev/null
@@ -1,77 +0,0 @@
-/*
- * Copyright (C) 2018 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.systemui.privacy
-
-import androidx.test.filters.SmallTest
-import androidx.test.runner.AndroidJUnit4
-import com.android.systemui.SysuiTestCase
-import org.junit.Assert.assertEquals
-import org.junit.Test
-import org.junit.runner.RunWith
-
-@RunWith(AndroidJUnit4::class)
-@SmallTest
-class PrivacyDialogBuilderTest : SysuiTestCase() {
-
-    companion object {
-        val TEST_UID = 1
-    }
-
-    @Test
-    fun testGenerateAppsList() {
-        val bar2 = PrivacyItem(Privacy.TYPE_CAMERA, PrivacyApplication(
-                "Bar", TEST_UID, context))
-        val bar3 = PrivacyItem(Privacy.TYPE_LOCATION, PrivacyApplication(
-                "Bar", TEST_UID, context))
-        val foo0 = PrivacyItem(Privacy.TYPE_MICROPHONE, PrivacyApplication(
-                "Foo", TEST_UID, context))
-        val baz1 = PrivacyItem(Privacy.TYPE_CAMERA, PrivacyApplication(
-                "Baz", TEST_UID, context))
-
-        val items = listOf(bar2, foo0, baz1, bar3)
-
-        val textBuilder = PrivacyDialogBuilder(context, items)
-
-        val list = textBuilder.appsAndTypes
-        assertEquals(3, list.size)
-        val appsList = list.map { it.first }
-        val typesList = list.map { it.second }
-        // List is sorted by number of types and then by types
-        assertEquals(listOf("Bar", "Baz", "Foo"), appsList.map { it.packageName })
-        assertEquals(listOf(Privacy.TYPE_CAMERA, Privacy.TYPE_LOCATION), typesList[0])
-        assertEquals(listOf(Privacy.TYPE_CAMERA), typesList[1])
-        assertEquals(listOf(Privacy.TYPE_MICROPHONE), typesList[2])
-    }
-
-    @Test
-    fun testOrder() {
-        // We want location to always go last, so it will go in the "+ other apps"
-        val appCamera = PrivacyItem(PrivacyType.TYPE_CAMERA,
-                PrivacyApplication("Camera", TEST_UID, context))
-        val appMicrophone =
-                PrivacyItem(PrivacyType.TYPE_MICROPHONE,
-                        PrivacyApplication("Microphone", TEST_UID, context))
-        val appLocation =
-                PrivacyItem(PrivacyType.TYPE_LOCATION,
-                        PrivacyApplication("Location", TEST_UID, context))
-
-        val items = listOf(appLocation, appMicrophone, appCamera)
-        val textBuilder = PrivacyDialogBuilder(context, items)
-        val appList = textBuilder.appsAndTypes.map { it.first }.map { it.packageName }
-        assertEquals(listOf("Camera", "Microphone", "Location"), appList)
-    }
-}
\ No newline at end of file
diff --git a/packages/SystemUI/tests/src/com/android/systemui/privacy/PrivacyItemControllerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/privacy/PrivacyItemControllerTest.kt
deleted file mode 100644
index e2e0bb1..0000000
--- a/packages/SystemUI/tests/src/com/android/systemui/privacy/PrivacyItemControllerTest.kt
+++ /dev/null
@@ -1,293 +0,0 @@
-/*
- * Copyright (C) 2018 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.systemui.privacy
-
-import android.app.ActivityManager
-import android.app.AppOpsManager
-import android.content.Context
-import android.content.Intent
-import android.content.pm.UserInfo
-import android.os.Handler
-import android.os.UserHandle
-import android.os.UserManager
-import android.provider.DeviceConfig
-import android.provider.Settings.RESET_MODE_PACKAGE_DEFAULTS
-import android.testing.AndroidTestingRunner
-import android.testing.TestableLooper
-import android.testing.TestableLooper.RunWithLooper
-import androidx.test.filters.SmallTest
-import com.android.internal.config.sysui.SystemUiDeviceConfigFlags
-import com.android.systemui.Dependency
-import com.android.systemui.R
-import com.android.systemui.SysuiTestCase
-import com.android.systemui.appops.AppOpItem
-import com.android.systemui.appops.AppOpsController
-import org.hamcrest.Matchers.hasItem
-import org.hamcrest.Matchers.not
-import org.hamcrest.Matchers.nullValue
-import org.junit.After
-import org.junit.Assert.assertEquals
-import org.junit.Assert.assertThat
-import org.junit.Assert.assertTrue
-import org.junit.Before
-import org.junit.Test
-import org.junit.runner.RunWith
-import org.mockito.ArgumentCaptor
-import org.mockito.ArgumentMatchers.any
-import org.mockito.ArgumentMatchers.anyInt
-import org.mockito.ArgumentMatchers.anyList
-import org.mockito.ArgumentMatchers.eq
-import org.mockito.Captor
-import org.mockito.Mock
-import org.mockito.Mockito.atLeastOnce
-import org.mockito.Mockito.doReturn
-import org.mockito.Mockito.mock
-import org.mockito.Mockito.never
-import org.mockito.Mockito.reset
-import org.mockito.Mockito.spy
-import org.mockito.Mockito.verify
-import org.mockito.Mockito.verifyNoMoreInteractions
-import org.mockito.MockitoAnnotations
-
-@RunWith(AndroidTestingRunner::class)
-@SmallTest
-@RunWithLooper
-class PrivacyItemControllerTest : SysuiTestCase() {
-
-    companion object {
-        val CURRENT_USER_ID = ActivityManager.getCurrentUser()
-        val TEST_UID = CURRENT_USER_ID * UserHandle.PER_USER_RANGE
-        const val SYSTEM_UID = 1000
-        const val TEST_PACKAGE_NAME = "test"
-        const val DEVICE_SERVICES_STRING = "Device services"
-        const val TAG = "PrivacyItemControllerTest"
-        fun <T> capture(argumentCaptor: ArgumentCaptor<T>): T = argumentCaptor.capture()
-    }
-
-    @Mock
-    private lateinit var appOpsController: AppOpsController
-    @Mock
-    private lateinit var callback: PrivacyItemController.Callback
-    @Mock
-    private lateinit var userManager: UserManager
-    @Captor
-    private lateinit var argCaptor: ArgumentCaptor<List<PrivacyItem>>
-    @Captor
-    private lateinit var argCaptorCallback: ArgumentCaptor<AppOpsController.Callback>
-
-    private lateinit var testableLooper: TestableLooper
-    private lateinit var privacyItemController: PrivacyItemController
-    private lateinit var handler: Handler
-
-    fun PrivacyItemController(context: Context) =
-            PrivacyItemController(context, appOpsController, handler, handler)
-
-    @Before
-    fun setup() {
-        MockitoAnnotations.initMocks(this)
-        testableLooper = TestableLooper.get(this)
-        handler = Handler(testableLooper.looper)
-
-        appOpsController = mDependency.injectMockDependency(AppOpsController::class.java)
-        mDependency.injectTestDependency(Dependency.BG_HANDLER, handler)
-        mDependency.injectTestDependency(Dependency.MAIN_HANDLER, handler)
-        mContext.addMockSystemService(UserManager::class.java, userManager)
-        mContext.getOrCreateTestableResources().addOverride(R.string.device_services,
-                DEVICE_SERVICES_STRING)
-        DeviceConfig.setProperty(DeviceConfig.NAMESPACE_PRIVACY,
-                SystemUiDeviceConfigFlags.PROPERTY_PERMISSIONS_HUB_ENABLED,
-                "true", false)
-
-        doReturn(listOf(object : UserInfo() {
-            init {
-                id = CURRENT_USER_ID
-            }
-        })).`when`(userManager).getProfiles(anyInt())
-
-        privacyItemController = PrivacyItemController(mContext)
-    }
-
-    @After
-    fun tearDown() {
-        DeviceConfig.resetToDefaults(RESET_MODE_PACKAGE_DEFAULTS, DeviceConfig.NAMESPACE_PRIVACY)
-    }
-
-    @Test
-    fun testSetListeningTrueByAddingCallback() {
-        privacyItemController.addCallback(callback)
-        testableLooper.processAllMessages()
-        verify(appOpsController).addCallback(eq(PrivacyItemController.OPS),
-                any(AppOpsController.Callback::class.java))
-        testableLooper.processAllMessages()
-        verify(callback).privacyChanged(anyList())
-    }
-
-    @Test
-    fun testSetListeningFalseByRemovingLastCallback() {
-        privacyItemController.addCallback(callback)
-        testableLooper.processAllMessages()
-        verify(appOpsController, never()).removeCallback(any(IntArray::class.java),
-                any(AppOpsController.Callback::class.java))
-        privacyItemController.removeCallback(callback)
-        testableLooper.processAllMessages()
-        verify(appOpsController).removeCallback(eq(PrivacyItemController.OPS),
-                any(AppOpsController.Callback::class.java))
-        verify(callback).privacyChanged(emptyList())
-    }
-
-    @Test
-    fun testDistinctItems() {
-        doReturn(listOf(AppOpItem(AppOpsManager.OP_CAMERA, TEST_UID, "", 0),
-                AppOpItem(AppOpsManager.OP_CAMERA, TEST_UID, "", 1)))
-                .`when`(appOpsController).getActiveAppOpsForUser(anyInt())
-
-        privacyItemController.addCallback(callback)
-        testableLooper.processAllMessages()
-        verify(callback).privacyChanged(capture(argCaptor))
-        assertEquals(1, argCaptor.value.size)
-    }
-
-    @Test
-    fun testSystemApps() {
-        doReturn(listOf(AppOpItem(AppOpsManager.OP_COARSE_LOCATION, SYSTEM_UID, TEST_PACKAGE_NAME,
-                0))).`when`(appOpsController).getActiveAppOpsForUser(anyInt())
-        privacyItemController.addCallback(callback)
-        testableLooper.processAllMessages()
-        verify(callback).privacyChanged(capture(argCaptor))
-        assertEquals(1, argCaptor.value.size)
-        assertEquals(context.getString(R.string.device_services),
-                argCaptor.value[0].application.applicationName)
-    }
-
-    @Test
-    fun testRegisterReceiver_allUsers() {
-        val spiedContext = spy(mContext)
-        val itemController = PrivacyItemController(spiedContext)
-        itemController.addCallback(callback)
-        testableLooper.processAllMessages()
-        verify(spiedContext, atLeastOnce()).registerReceiverAsUser(
-                eq(itemController.userSwitcherReceiver), eq(UserHandle.ALL), any(), eq(null),
-                eq(null))
-        verify(spiedContext, never()).unregisterReceiver(eq(itemController.userSwitcherReceiver))
-    }
-
-    @Test
-    fun testReceiver_ACTION_USER_FOREGROUND() {
-        privacyItemController.userSwitcherReceiver.onReceive(context,
-                Intent(Intent.ACTION_USER_FOREGROUND))
-        verify(userManager).getProfiles(anyInt())
-    }
-
-    @Test
-    fun testReceiver_ACTION_MANAGED_PROFILE_ADDED() {
-        privacyItemController.userSwitcherReceiver.onReceive(context,
-                Intent(Intent.ACTION_MANAGED_PROFILE_ADDED))
-        verify(userManager).getProfiles(anyInt())
-    }
-
-    @Test
-    fun testReceiver_ACTION_MANAGED_PROFILE_REMOVED() {
-        privacyItemController.userSwitcherReceiver.onReceive(context,
-                Intent(Intent.ACTION_MANAGED_PROFILE_REMOVED))
-        verify(userManager).getProfiles(anyInt())
-    }
-
-    @Test
-    fun testAddMultipleCallbacks() {
-        val otherCallback = mock(PrivacyItemController.Callback::class.java)
-        privacyItemController.addCallback(callback)
-        testableLooper.processAllMessages()
-        verify(callback).privacyChanged(anyList())
-
-        privacyItemController.addCallback(otherCallback)
-        testableLooper.processAllMessages()
-        verify(otherCallback).privacyChanged(anyList())
-        // Adding a callback should not unnecessarily call previous ones
-        verifyNoMoreInteractions(callback)
-    }
-
-    @Test
-    fun testMultipleCallbacksAreUpdated() {
-        doReturn(emptyList<AppOpItem>()).`when`(appOpsController).getActiveAppOpsForUser(anyInt())
-
-        val otherCallback = mock(PrivacyItemController.Callback::class.java)
-        privacyItemController.addCallback(callback)
-        privacyItemController.addCallback(otherCallback)
-        testableLooper.processAllMessages()
-        reset(callback)
-        reset(otherCallback)
-
-        verify(appOpsController).addCallback(any<IntArray>(), capture(argCaptorCallback))
-        argCaptorCallback.value.onActiveStateChanged(0, TEST_UID, "", true)
-        testableLooper.processAllMessages()
-        verify(callback).privacyChanged(anyList())
-        verify(otherCallback).privacyChanged(anyList())
-    }
-
-    @Test
-    fun testRemoveCallback() {
-        doReturn(emptyList<AppOpItem>()).`when`(appOpsController).getActiveAppOpsForUser(anyInt())
-        val otherCallback = mock(PrivacyItemController.Callback::class.java)
-        privacyItemController.addCallback(callback)
-        privacyItemController.addCallback(otherCallback)
-        testableLooper.processAllMessages()
-        reset(callback)
-        reset(otherCallback)
-
-        verify(appOpsController).addCallback(any<IntArray>(), capture(argCaptorCallback))
-        privacyItemController.removeCallback(callback)
-        argCaptorCallback.value.onActiveStateChanged(0, TEST_UID, "", true)
-        testableLooper.processAllMessages()
-        verify(callback, never()).privacyChanged(anyList())
-        verify(otherCallback).privacyChanged(anyList())
-    }
-
-    @Test
-    fun testListShouldNotHaveNull() {
-        doReturn(listOf(AppOpItem(AppOpsManager.OP_ACTIVATE_VPN, TEST_UID, "", 0),
-                        AppOpItem(AppOpsManager.OP_COARSE_LOCATION, TEST_UID, "", 0)))
-                .`when`(appOpsController).getActiveAppOpsForUser(anyInt())
-        privacyItemController.addCallback(callback)
-        testableLooper.processAllMessages()
-
-        verify(callback).privacyChanged(capture(argCaptor))
-        assertEquals(1, argCaptor.value.size)
-        assertThat(argCaptor.value, not(hasItem(nullValue())))
-    }
-
-    @Test
-    fun testListShouldBeCopy() {
-        val list = listOf(PrivacyItem(PrivacyType.TYPE_CAMERA,
-                PrivacyApplication("", TEST_UID, mContext)))
-        privacyItemController.privacyList = list
-        val privacyList = privacyItemController.privacyList
-        assertEquals(list, privacyList)
-        assertTrue(list !== privacyList)
-    }
-
-    @Test
-    fun testNotListeningWhenIndicatorsDisabled() {
-        privacyItemController.devicePropertyChangedListener.onPropertyChanged(
-                DeviceConfig.NAMESPACE_PRIVACY,
-                SystemUiDeviceConfigFlags.PROPERTY_PERMISSIONS_HUB_ENABLED,
-                "false")
-        privacyItemController.addCallback(callback)
-        testableLooper.processAllMessages()
-        verify(appOpsController, never()).addCallback(eq(PrivacyItemController.OPS),
-                any(AppOpsController.Callback::class.java))
-    }
-}
\ No newline at end of file
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/VisualStabilityManagerTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/VisualStabilityManagerTest.java
index b35dcb6..dd2630b 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/VisualStabilityManagerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/VisualStabilityManagerTest.java
@@ -16,17 +16,20 @@
 
 package com.android.systemui.statusbar.notification;
 
-import static junit.framework.Assert.assertEquals;
-
-import static org.mockito.Matchers.anyObject;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
+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.mockito.Mockito.when;
 
+import android.os.Handler;
 import android.service.notification.StatusBarNotification;
-import android.test.suitebuilder.annotation.SmallTest;
+import android.testing.AndroidTestingRunner;
+import android.testing.TestableLooper;
 
-import androidx.test.runner.AndroidJUnit4;
+import androidx.test.filters.SmallTest;
 
 import com.android.systemui.SysuiTestCase;
 import com.android.systemui.statusbar.NotificationPresenter;
@@ -38,11 +41,13 @@
 import org.junit.runner.RunWith;
 
 @SmallTest
-@RunWith(AndroidJUnit4.class)
+@RunWith(AndroidTestingRunner.class)
+@TestableLooper.RunWithLooper()
 public class VisualStabilityManagerTest extends SysuiTestCase {
 
-    private VisualStabilityManager mVisualStabilityManager = new VisualStabilityManager(
-            mock(NotificationEntryManager.class));
+    private TestableLooper mTestableLooper;
+
+    private VisualStabilityManager mVisualStabilityManager;
     private VisualStabilityManager.Callback mCallback = mock(VisualStabilityManager.Callback.class);
     private VisibilityLocationProvider mLocationProvider = mock(VisibilityLocationProvider.class);
     private ExpandableNotificationRow mRow = mock(ExpandableNotificationRow.class);
@@ -50,46 +55,53 @@
 
     @Before
     public void setUp() {
+        mTestableLooper = TestableLooper.get(this);
+        mVisualStabilityManager = new VisualStabilityManager(
+                mock(NotificationEntryManager.class),
+                new Handler(mTestableLooper.getLooper()));
+
         mVisualStabilityManager.setUpWithPresenter(mock(NotificationPresenter.class));
         mVisualStabilityManager.setVisibilityLocationProvider(mLocationProvider);
         mEntry = new NotificationEntry(mock(StatusBarNotification.class));
         mEntry.setRow(mRow);
+
+        when(mRow.getEntry()).thenReturn(mEntry);
     }
 
     @Test
     public void testPanelExpansion() {
         mVisualStabilityManager.setPanelExpanded(true);
         mVisualStabilityManager.setScreenOn(true);
-        assertEquals(mVisualStabilityManager.canReorderNotification(mRow), false);
+        assertFalse(mVisualStabilityManager.canReorderNotification(mRow));
         mVisualStabilityManager.setPanelExpanded(false);
-        assertEquals(mVisualStabilityManager.canReorderNotification(mRow), true);
+        assertTrue(mVisualStabilityManager.canReorderNotification(mRow));
     }
 
     @Test
     public void testScreenOn() {
         mVisualStabilityManager.setPanelExpanded(true);
         mVisualStabilityManager.setScreenOn(true);
-        assertEquals(mVisualStabilityManager.canReorderNotification(mRow), false);
+        assertFalse(mVisualStabilityManager.canReorderNotification(mRow));
         mVisualStabilityManager.setScreenOn(false);
-        assertEquals(mVisualStabilityManager.canReorderNotification(mRow), true);
+        assertTrue(mVisualStabilityManager.canReorderNotification(mRow));
     }
 
     @Test
     public void testReorderingAllowedChangesScreenOn() {
         mVisualStabilityManager.setPanelExpanded(true);
         mVisualStabilityManager.setScreenOn(true);
-        assertEquals(mVisualStabilityManager.isReorderingAllowed(), false);
+        assertFalse(mVisualStabilityManager.isReorderingAllowed());
         mVisualStabilityManager.setScreenOn(false);
-        assertEquals(mVisualStabilityManager.isReorderingAllowed(), true);
+        assertTrue(mVisualStabilityManager.isReorderingAllowed());
     }
 
     @Test
     public void testReorderingAllowedChangesPanel() {
         mVisualStabilityManager.setPanelExpanded(true);
         mVisualStabilityManager.setScreenOn(true);
-        assertEquals(mVisualStabilityManager.isReorderingAllowed(), false);
+        assertFalse(mVisualStabilityManager.isReorderingAllowed());
         mVisualStabilityManager.setPanelExpanded(false);
-        assertEquals(mVisualStabilityManager.isReorderingAllowed(), true);
+        assertTrue(mVisualStabilityManager.isReorderingAllowed());
     }
 
     @Test
@@ -126,51 +138,51 @@
         mVisualStabilityManager.setPanelExpanded(true);
         mVisualStabilityManager.setScreenOn(true);
         mVisualStabilityManager.notifyViewAddition(mRow);
-        assertEquals(mVisualStabilityManager.canReorderNotification(mRow), true);
+        assertTrue(mVisualStabilityManager.canReorderNotification(mRow));
     }
 
     @Test
     public void testReorderingVisibleHeadsUpNotAllowed() {
         mVisualStabilityManager.setPanelExpanded(true);
         mVisualStabilityManager.setScreenOn(true);
-        when(mLocationProvider.isInVisibleLocation(anyObject())).thenReturn(true);
+        when(mLocationProvider.isInVisibleLocation(any(NotificationEntry.class))).thenReturn(true);
         mVisualStabilityManager.onHeadsUpStateChanged(mEntry, true);
-        assertEquals(mVisualStabilityManager.canReorderNotification(mRow), false);
+        assertFalse(mVisualStabilityManager.canReorderNotification(mRow));
     }
 
     @Test
     public void testReorderingVisibleHeadsUpAllowed() {
         mVisualStabilityManager.setPanelExpanded(true);
         mVisualStabilityManager.setScreenOn(true);
-        when(mLocationProvider.isInVisibleLocation(anyObject())).thenReturn(false);
+        when(mLocationProvider.isInVisibleLocation(any(NotificationEntry.class))).thenReturn(false);
         mVisualStabilityManager.onHeadsUpStateChanged(mEntry, true);
-        assertEquals(mVisualStabilityManager.canReorderNotification(mRow), true);
+        assertTrue(mVisualStabilityManager.canReorderNotification(mRow));
     }
 
     @Test
     public void testReorderingVisibleHeadsUpAllowedOnce() {
         mVisualStabilityManager.setPanelExpanded(true);
         mVisualStabilityManager.setScreenOn(true);
-        when(mLocationProvider.isInVisibleLocation(anyObject())).thenReturn(false);
+        when(mLocationProvider.isInVisibleLocation(any(NotificationEntry.class))).thenReturn(false);
         mVisualStabilityManager.onHeadsUpStateChanged(mEntry, true);
         mVisualStabilityManager.onReorderingFinished();
-        assertEquals(mVisualStabilityManager.canReorderNotification(mRow), false);
+        assertFalse(mVisualStabilityManager.canReorderNotification(mRow));
     }
 
     @Test
     public void testPulsing() {
         mVisualStabilityManager.setPulsing(true);
-        assertEquals(mVisualStabilityManager.canReorderNotification(mRow), false);
+        assertFalse(mVisualStabilityManager.canReorderNotification(mRow));
         mVisualStabilityManager.setPulsing(false);
-        assertEquals(mVisualStabilityManager.canReorderNotification(mRow), true);
+        assertTrue(mVisualStabilityManager.canReorderNotification(mRow));
     }
 
     @Test
     public void testReorderingAllowedChanges_Pulsing() {
         mVisualStabilityManager.setPulsing(true);
-        assertEquals(mVisualStabilityManager.isReorderingAllowed(), false);
+        assertFalse(mVisualStabilityManager.isReorderingAllowed());
         mVisualStabilityManager.setPulsing(false);
-        assertEquals(mVisualStabilityManager.isReorderingAllowed(), true);
+        assertTrue(mVisualStabilityManager.isReorderingAllowed());
     }
 
     @Test
@@ -180,4 +192,49 @@
         mVisualStabilityManager.setPulsing(false);
         verify(mCallback).onReorderingAllowed();
     }
+
+    @Test
+    public void testTemporarilyAllowReorderingNotifiesCallbacks() {
+        // GIVEN having the panel open (which would block reordering)
+        mVisualStabilityManager.setScreenOn(true);
+        mVisualStabilityManager.setPanelExpanded(true);
+        mVisualStabilityManager.addReorderingAllowedCallback(mCallback);
+
+        // WHEN we temprarily allow reordering
+        mVisualStabilityManager.temporarilyAllowReordering();
+
+        // THEN callbacks are notified that reordering is allowed
+        verify(mCallback).onReorderingAllowed();
+        assertTrue(mVisualStabilityManager.isReorderingAllowed());
+    }
+
+    @Test
+    public void testTemporarilyAllowReorderingDoesntOverridePulsing() {
+        // GIVEN we are in a pulsing state
+        mVisualStabilityManager.setPulsing(true);
+        mVisualStabilityManager.addReorderingAllowedCallback(mCallback);
+
+        // WHEN we temprarily allow reordering
+        mVisualStabilityManager.temporarilyAllowReordering();
+
+        // THEN reordering is still not allowed
+        verify(mCallback, never()).onReorderingAllowed();
+        assertFalse(mVisualStabilityManager.isReorderingAllowed());
+    }
+
+    @Test
+    public void testTemporarilyAllowReorderingExpires() {
+        // GIVEN having the panel open (which would block reordering)
+        mVisualStabilityManager.setScreenOn(true);
+        mVisualStabilityManager.setPanelExpanded(true);
+        mVisualStabilityManager.addReorderingAllowedCallback(mCallback);
+
+        // WHEN we temprarily allow reordering and then wait until the window expires
+        mVisualStabilityManager.temporarilyAllowReordering();
+        assertTrue(mVisualStabilityManager.isReorderingAllowed());
+        mTestableLooper.processMessages(1);
+
+        // THEN reordering is no longer allowed
+        assertFalse(mVisualStabilityManager.isReorderingAllowed());
+    }
 }
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/ChannelEditorDialogControllerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/ChannelEditorDialogControllerTest.kt
index 7632630..8b81a7a 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/ChannelEditorDialogControllerTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/ChannelEditorDialogControllerTest.kt
@@ -109,7 +109,7 @@
     }
 
     @Test
-    fun testPrepareDialogForApp_retrievesUpto4Channels() {
+    fun testPrepareDialogForApp_retrievesUpTo4Channels() {
         val channel3 = NotificationChannel("test_channel_3", "Test channel 3", IMPORTANCE_DEFAULT)
         val channel4 = NotificationChannel("test_channel_4", "Test channel 4", IMPORTANCE_DEFAULT)
 
@@ -169,6 +169,16 @@
                 eq(TEST_PACKAGE_NAME), eq(TEST_UID), eq(true))
     }
 
+    @Test
+    fun testSettingsClickListenerNull_noCrash() {
+        group.channels = listOf(channel1, channel2)
+        controller.prepareDialogForApp(TEST_APP_NAME, TEST_PACKAGE_NAME, TEST_UID,
+                setOf(channel1, channel2), appIcon, null)
+
+        // Pass in any old view, it should never actually be used
+        controller.launchSettings(View(context))
+    }
+
     private val clickListener = object : NotificationInfo.OnSettingsClickListener {
         override fun onClick(v: View, c: NotificationChannel, appUid: Int) {
         }
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/NotificationContentInflaterTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/NotificationContentInflaterTest.java
index 025296d..06ff047 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/NotificationContentInflaterTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/NotificationContentInflaterTest.java
@@ -101,7 +101,7 @@
         mNotificationInflater.setUsesIncreasedHeadsUpHeight(true);
         Notification.Builder builder = spy(mBuilder);
         mNotificationInflater.inflateNotificationViews(
-                false /* inflateSynchronously */,
+                true /* inflateSynchronously */,
                 FLAG_CONTENT_VIEW_ALL,
                 builder,
                 mContext);
@@ -113,7 +113,7 @@
         mNotificationInflater.setUsesIncreasedHeight(true);
         Notification.Builder builder = spy(mBuilder);
         mNotificationInflater.inflateNotificationViews(
-                false /* inflateSynchronously */,
+                true /* inflateSynchronously */,
                 FLAG_CONTENT_VIEW_ALL,
                 builder,
                 mContext);
@@ -161,6 +161,7 @@
     @Test
     public void testRemovedNotInflated() throws Exception {
         mRow.setRemoved();
+        mNotificationInflater.setInflateSynchronously(true);
         mNotificationInflater.inflateNotificationViews();
         Assert.assertNull(mRow.getEntry().getRunningTask());
     }
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/NotificationGutsManagerTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/NotificationGutsManagerTest.java
index 6376bd3..7959484 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/NotificationGutsManagerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/NotificationGutsManagerTest.java
@@ -63,9 +63,11 @@
 import com.android.systemui.statusbar.NotificationPresenter;
 import com.android.systemui.statusbar.NotificationTestHelper;
 import com.android.systemui.statusbar.notification.NotificationActivityStarter;
+import com.android.systemui.statusbar.notification.VisualStabilityManager;
 import com.android.systemui.statusbar.notification.collection.NotificationEntry;
 import com.android.systemui.statusbar.notification.row.NotificationGutsManager.OnSettingsClickListener;
 import com.android.systemui.statusbar.notification.stack.NotificationStackScrollLayout;
+import com.android.systemui.statusbar.phone.StatusBar;
 import com.android.systemui.statusbar.policy.DeviceProvisionedController;
 import com.android.systemui.util.Assert;
 
@@ -97,12 +99,14 @@
 
     @Rule public MockitoRule mockito = MockitoJUnit.rule();
     @Mock private MetricsLogger mMetricsLogger;
+    @Mock private VisualStabilityManager mVisualStabilityManager;
     @Mock private NotificationPresenter mPresenter;
     @Mock private NotificationActivityStarter mNotificationActivityStarter;
     @Mock private NotificationStackScrollLayout mStackScroller;
     @Mock private NotificationInfo.CheckSaveListener mCheckSaveListener;
     @Mock private OnSettingsClickListener mOnSettingsClickListener;
     @Mock private DeviceProvisionedController mDeviceProvisionedController;
+    @Mock private StatusBar mStatusBar;
 
     @Before
     public void setUp() {
@@ -111,11 +115,12 @@
         mDependency.injectTestDependency(DeviceProvisionedController.class,
                 mDeviceProvisionedController);
         mDependency.injectTestDependency(MetricsLogger.class, mMetricsLogger);
+        mDependency.injectTestDependency(VisualStabilityManager.class, mVisualStabilityManager);
         mHandler = Handler.createAsync(mTestableLooper.getLooper());
-
+        mContext.putComponent(StatusBar.class, mStatusBar);
         mHelper = new NotificationTestHelper(mContext);
 
-        mGutsManager = new NotificationGutsManager(mContext);
+        mGutsManager = new NotificationGutsManager(mContext, mVisualStabilityManager);
         mGutsManager.setUpWithPresenter(mPresenter, mStackScroller,
                 mCheckSaveListener, mOnSettingsClickListener);
         mGutsManager.setNotificationActivityStarter(mNotificationActivityStarter);
@@ -147,7 +152,7 @@
         when(row.getWindowToken()).thenReturn(new Binder());
         when(row.getGuts()).thenReturn(guts);
 
-        assertTrue(mGutsManager.openGuts(row, 0, 0, menuItem));
+        assertTrue(mGutsManager.openGutsInternal(row, 0, 0, menuItem));
         assertEquals(View.INVISIBLE, guts.getVisibility());
         mTestableLooper.processAllMessages();
         verify(guts).openControls(
@@ -195,7 +200,7 @@
         when(entry.getRow()).thenReturn(row);
         when(entry.getGuts()).thenReturn(guts);
 
-        assertTrue(mGutsManager.openGuts(row, 0, 0, menuItem));
+        assertTrue(mGutsManager.openGutsInternal(row, 0, 0, menuItem));
         mTestableLooper.processAllMessages();
         verify(guts).openControls(
                 eq(true),
@@ -316,6 +321,7 @@
         verify(notificationInfoView).bindNotification(
                 any(PackageManager.class),
                 any(INotificationManager.class),
+                eq(mVisualStabilityManager),
                 eq(statusBarNotification.getPackageName()),
                 any(NotificationChannel.class),
                 anySet(),
@@ -344,6 +350,7 @@
         verify(notificationInfoView).bindNotification(
                 any(PackageManager.class),
                 any(INotificationManager.class),
+                eq(mVisualStabilityManager),
                 eq(statusBarNotification.getPackageName()),
                 any(NotificationChannel.class),
                 anySet(),
@@ -374,6 +381,7 @@
         verify(notificationInfoView).bindNotification(
                 any(PackageManager.class),
                 any(INotificationManager.class),
+                eq(mVisualStabilityManager),
                 eq(statusBarNotification.getPackageName()),
                 any(NotificationChannel.class),
                 anySet(),
@@ -403,6 +411,7 @@
         verify(notificationInfoView).bindNotification(
                 any(PackageManager.class),
                 any(INotificationManager.class),
+                eq(mVisualStabilityManager),
                 eq(statusBarNotification.getPackageName()),
                 any(NotificationChannel.class),
                 anySet(),
@@ -431,6 +440,7 @@
         verify(notificationInfoView).bindNotification(
                 any(PackageManager.class),
                 any(INotificationManager.class),
+                eq(mVisualStabilityManager),
                 eq(statusBarNotification.getPackageName()),
                 any(NotificationChannel.class),
                 anySet(),
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/NotificationInfoTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/NotificationInfoTest.java
index 06acc73..703adf7 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/NotificationInfoTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/NotificationInfoTest.java
@@ -72,6 +72,7 @@
 import com.android.systemui.Dependency;
 import com.android.systemui.R;
 import com.android.systemui.SysuiTestCase;
+import com.android.systemui.statusbar.notification.VisualStabilityManager;
 
 import org.junit.After;
 import org.junit.Before;
@@ -116,6 +117,8 @@
     private PackageManager mMockPackageManager;
     @Mock
     private NotificationBlockingHelperManager mBlockingHelperManager;
+    @Mock
+    private VisualStabilityManager mVisualStabilityManager;
 
     @Before
     public void setUp() throws Exception {
@@ -193,11 +196,21 @@
     @Test
     public void testBindNotification_SetsTextApplicationName() throws Exception {
         when(mMockPackageManager.getApplicationLabel(any())).thenReturn("App Name");
-        mNotificationInfo.bindNotification(mMockPackageManager, mMockINotificationManager,
-                TEST_PACKAGE_NAME, mNotificationChannel, mNotificationChannelSet, mSbn,
-                null, null, null,
-                true, false,
-                IMPORTANCE_DEFAULT, true);
+        mNotificationInfo.bindNotification(
+                mMockPackageManager,
+                mMockINotificationManager,
+                mVisualStabilityManager,
+                TEST_PACKAGE_NAME,
+                mNotificationChannel,
+                mNotificationChannelSet,
+                mSbn,
+                null,
+                null,
+                null,
+                true,
+                false,
+                IMPORTANCE_DEFAULT,
+                true);
         final TextView textView = mNotificationInfo.findViewById(R.id.pkgname);
         assertTrue(textView.getText().toString().contains("App Name"));
         assertEquals(VISIBLE, mNotificationInfo.findViewById(R.id.header).getVisibility());
@@ -208,20 +221,42 @@
         final Drawable iconDrawable = mock(Drawable.class);
         when(mMockPackageManager.getApplicationIcon(any(ApplicationInfo.class)))
                 .thenReturn(iconDrawable);
-        mNotificationInfo.bindNotification(mMockPackageManager, mMockINotificationManager,
-                TEST_PACKAGE_NAME, mNotificationChannel, mNotificationChannelSet, mSbn,
-                null, null, null, true, false,
-                IMPORTANCE_DEFAULT, true);
+        mNotificationInfo.bindNotification(
+                mMockPackageManager,
+                mMockINotificationManager,
+                mVisualStabilityManager,
+                TEST_PACKAGE_NAME,
+                mNotificationChannel,
+                mNotificationChannelSet,
+                mSbn,
+                null,
+                null,
+                null,
+                true,
+                false,
+                IMPORTANCE_DEFAULT,
+                true);
         final ImageView iconView = mNotificationInfo.findViewById(R.id.pkgicon);
         assertEquals(iconDrawable, iconView.getDrawable());
     }
 
     @Test
     public void testBindNotification_noDelegate() throws Exception {
-        mNotificationInfo.bindNotification(mMockPackageManager, mMockINotificationManager,
-                TEST_PACKAGE_NAME, mNotificationChannel, mNotificationChannelSet, mSbn,
-                null, null, null, true, false,
-                IMPORTANCE_DEFAULT, true);
+        mNotificationInfo.bindNotification(
+                mMockPackageManager,
+                mMockINotificationManager,
+                mVisualStabilityManager,
+                TEST_PACKAGE_NAME,
+                mNotificationChannel,
+                mNotificationChannelSet,
+                mSbn,
+                null,
+                null,
+                null,
+                true,
+                false,
+                IMPORTANCE_DEFAULT,
+                true);
         final TextView nameView = mNotificationInfo.findViewById(R.id.delegate_name);
         assertEquals(GONE, nameView.getVisibility());
         final TextView dividerView = mNotificationInfo.findViewById(R.id.pkg_divider);
@@ -238,10 +273,21 @@
                 applicationInfo);
         when(mMockPackageManager.getApplicationLabel(any())).thenReturn("Other");
 
-        mNotificationInfo.bindNotification(mMockPackageManager, mMockINotificationManager,
-                TEST_PACKAGE_NAME, mNotificationChannel, mNotificationChannelSet, mSbn, null, null,
-                null, true, false,
-                IMPORTANCE_DEFAULT, true);
+        mNotificationInfo.bindNotification(
+                mMockPackageManager,
+                mMockINotificationManager,
+                mVisualStabilityManager,
+                TEST_PACKAGE_NAME,
+                mNotificationChannel,
+                mNotificationChannelSet,
+                mSbn,
+                null,
+                null,
+                null,
+                true,
+                false,
+                IMPORTANCE_DEFAULT,
+                true);
         final TextView nameView = mNotificationInfo.findViewById(R.id.delegate_name);
         assertEquals(VISIBLE, nameView.getVisibility());
         assertTrue(nameView.getText().toString().contains("Proxied"));
@@ -251,10 +297,21 @@
 
     @Test
     public void testBindNotification_GroupNameHiddenIfNoGroup() throws Exception {
-        mNotificationInfo.bindNotification(mMockPackageManager, mMockINotificationManager,
-                TEST_PACKAGE_NAME, mNotificationChannel, mNotificationChannelSet, mSbn, null, null,
-                null, true, false,
-                IMPORTANCE_DEFAULT, true);
+        mNotificationInfo.bindNotification(
+                mMockPackageManager,
+                mMockINotificationManager,
+                mVisualStabilityManager,
+                TEST_PACKAGE_NAME,
+                mNotificationChannel,
+                mNotificationChannelSet,
+                mSbn,
+                null,
+                null,
+                null,
+                true,
+                false,
+                IMPORTANCE_DEFAULT,
+                true);
         final TextView groupNameView = mNotificationInfo.findViewById(R.id.group_name);
         assertEquals(GONE, groupNameView.getVisibility());
     }
@@ -267,10 +324,21 @@
         when(mMockINotificationManager.getNotificationChannelGroupForPackage(
                 eq("test_group_id"), eq(TEST_PACKAGE_NAME), eq(TEST_UID)))
                 .thenReturn(notificationChannelGroup);
-        mNotificationInfo.bindNotification(mMockPackageManager, mMockINotificationManager,
-                TEST_PACKAGE_NAME, mNotificationChannel, mNotificationChannelSet, mSbn, null, null,
-                null, true, false,
-                IMPORTANCE_DEFAULT, true);
+        mNotificationInfo.bindNotification(
+                mMockPackageManager,
+                mMockINotificationManager,
+                mVisualStabilityManager,
+                TEST_PACKAGE_NAME,
+                mNotificationChannel,
+                mNotificationChannelSet,
+                mSbn,
+                null,
+                null,
+                null,
+                true,
+                false,
+                IMPORTANCE_DEFAULT,
+                true);
         final TextView groupNameView = mNotificationInfo.findViewById(R.id.group_name);
         assertEquals(View.VISIBLE, groupNameView.getVisibility());
         assertEquals("Test Group Name", groupNameView.getText());
@@ -278,19 +346,42 @@
 
     @Test
     public void testBindNotification_SetsTextChannelName() throws Exception {
-        mNotificationInfo.bindNotification(mMockPackageManager, mMockINotificationManager,
-                TEST_PACKAGE_NAME, mNotificationChannel, mNotificationChannelSet, mSbn, null, null,
-                null, true, false,
-                IMPORTANCE_DEFAULT, true);
+        mNotificationInfo.bindNotification(
+                mMockPackageManager,
+                mMockINotificationManager,
+                mVisualStabilityManager,
+                TEST_PACKAGE_NAME,
+                mNotificationChannel,
+                mNotificationChannelSet,
+                mSbn,
+                null,
+                null,
+                null,
+                true,
+                false,
+                IMPORTANCE_DEFAULT,
+                true);
         final TextView textView = mNotificationInfo.findViewById(R.id.channel_name);
         assertEquals(TEST_CHANNEL_NAME, textView.getText());
     }
 
     @Test
     public void testBindNotification_DefaultChannelDoesNotUseChannelName() throws Exception {
-        mNotificationInfo.bindNotification(mMockPackageManager, mMockINotificationManager,
-                TEST_PACKAGE_NAME, mDefaultNotificationChannel, mDefaultNotificationChannelSet,
-                mSbn, null, null, null, true, false, IMPORTANCE_DEFAULT, true);
+        mNotificationInfo.bindNotification(
+                mMockPackageManager,
+                mMockINotificationManager,
+                mVisualStabilityManager,
+                TEST_PACKAGE_NAME,
+                mDefaultNotificationChannel,
+                mDefaultNotificationChannelSet,
+                mSbn,
+                null,
+                null,
+                null,
+                true,
+                false,
+                IMPORTANCE_DEFAULT,
+                true);
         final TextView textView = mNotificationInfo.findViewById(R.id.channel_name);
         assertEquals(GONE, textView.getVisibility());
     }
@@ -301,30 +392,64 @@
         // Package has one channel by default.
         when(mMockINotificationManager.getNumNotificationChannelsForPackage(
                 eq(TEST_PACKAGE_NAME), eq(TEST_UID), anyBoolean())).thenReturn(10);
-        mNotificationInfo.bindNotification(mMockPackageManager, mMockINotificationManager,
-                TEST_PACKAGE_NAME, mDefaultNotificationChannel, mDefaultNotificationChannelSet,
-                mSbn, null, null, null, true,
-                false, IMPORTANCE_DEFAULT, true);
+        mNotificationInfo.bindNotification(
+                mMockPackageManager,
+                mMockINotificationManager,
+                mVisualStabilityManager,
+                TEST_PACKAGE_NAME,
+                mDefaultNotificationChannel,
+                mDefaultNotificationChannelSet,
+                mSbn,
+                null,
+                null,
+                null,
+                true,
+                false,
+                IMPORTANCE_DEFAULT,
+                true);
         final TextView textView = mNotificationInfo.findViewById(R.id.channel_name);
         assertEquals(VISIBLE, textView.getVisibility());
     }
 
     @Test
     public void testBindNotification_UnblockablePackageUsesChannelName() throws Exception {
-        mNotificationInfo.bindNotification(mMockPackageManager, mMockINotificationManager,
-                TEST_PACKAGE_NAME, mNotificationChannel, mNotificationChannelSet, mSbn, null, null,
-                null, true, true,
-                IMPORTANCE_DEFAULT, true);
+        mNotificationInfo.bindNotification(
+                mMockPackageManager,
+                mMockINotificationManager,
+                mVisualStabilityManager,
+                TEST_PACKAGE_NAME,
+                mNotificationChannel,
+                mNotificationChannelSet,
+                mSbn,
+                null,
+                null,
+                null,
+                true,
+                true,
+                IMPORTANCE_DEFAULT,
+                true);
         final TextView textView = mNotificationInfo.findViewById(R.id.channel_name);
         assertEquals(VISIBLE, textView.getVisibility());
     }
 
     @Test
     public void testBindNotification_BlockLink_BlockingHelper() throws Exception {
-        mNotificationInfo.bindNotification(mMockPackageManager, mMockINotificationManager,
-                TEST_PACKAGE_NAME, mNotificationChannel, mNotificationChannelSet, mSbn, null, mock(
-                        NotificationInfo.OnSettingsClickListener.class), null, true, false,
-                true /* isBlockingHelper */, IMPORTANCE_DEFAULT, true);
+        mNotificationInfo.bindNotification(
+                mMockPackageManager,
+                mMockINotificationManager,
+                mVisualStabilityManager,
+                TEST_PACKAGE_NAME,
+                mNotificationChannel,
+                mNotificationChannelSet,
+                mSbn,
+                null,
+                mock(NotificationInfo.OnSettingsClickListener.class),
+                null,
+                true,
+                false,
+                true /* isBlockingHelper */,
+                IMPORTANCE_DEFAULT,
+                true);
         final View block =
                 mNotificationInfo.findViewById(R.id.blocking_helper_turn_off_notifications);
         final View interruptivenessSettings = mNotificationInfo.findViewById(
@@ -336,12 +461,24 @@
     @Test
     public void testBindNotification_SetsOnClickListenerForSettings() throws Exception {
         final CountDownLatch latch = new CountDownLatch(1);
-        mNotificationInfo.bindNotification(mMockPackageManager, mMockINotificationManager,
-                TEST_PACKAGE_NAME, mNotificationChannel, mNotificationChannelSet, mSbn, null,
+        mNotificationInfo.bindNotification(
+                mMockPackageManager,
+                mMockINotificationManager,
+                mVisualStabilityManager,
+                TEST_PACKAGE_NAME,
+                mNotificationChannel,
+                mNotificationChannelSet,
+                mSbn,
+                null,
                 (View v, NotificationChannel c, int appUid) -> {
                     assertEquals(mNotificationChannel, c);
                     latch.countDown();
-                }, null, true, false, IMPORTANCE_DEFAULT, true);
+                },
+                null,
+                true,
+                false,
+                IMPORTANCE_DEFAULT,
+                true);
 
         final View settingsButton = mNotificationInfo.findViewById(R.id.info);
         settingsButton.performClick();
@@ -351,10 +488,21 @@
 
     @Test
     public void testBindNotification_SettingsButtonInvisibleWhenNoClickListener() throws Exception {
-        mNotificationInfo.bindNotification(mMockPackageManager, mMockINotificationManager,
-                TEST_PACKAGE_NAME, mNotificationChannel, mNotificationChannelSet, mSbn, null, null,
-                null, true, false,
-                IMPORTANCE_DEFAULT, true);
+        mNotificationInfo.bindNotification(
+                mMockPackageManager,
+                mMockINotificationManager,
+                mVisualStabilityManager,
+                TEST_PACKAGE_NAME,
+                mNotificationChannel,
+                mNotificationChannelSet,
+                mSbn,
+                null,
+                null,
+                null,
+                true,
+                false,
+                IMPORTANCE_DEFAULT,
+                true);
         final View settingsButton = mNotificationInfo.findViewById(R.id.info);
         assertTrue(settingsButton.getVisibility() != View.VISIBLE);
     }
@@ -362,36 +510,80 @@
     @Test
     public void testBindNotification_SettingsButtonInvisibleWhenDeviceUnprovisioned()
             throws Exception {
-        mNotificationInfo.bindNotification(mMockPackageManager, mMockINotificationManager,
-                TEST_PACKAGE_NAME, mNotificationChannel, mNotificationChannelSet, mSbn, null,
+        mNotificationInfo.bindNotification(
+                mMockPackageManager,
+                mMockINotificationManager,
+                mVisualStabilityManager,
+                TEST_PACKAGE_NAME,
+                mNotificationChannel,
+                mNotificationChannelSet,
+                mSbn,
+                null,
                 (View v, NotificationChannel c, int appUid) -> {
                     assertEquals(mNotificationChannel, c);
-                }, null, false, false, IMPORTANCE_DEFAULT, true);
+                },
+                null,
+                false,
+                false,
+                IMPORTANCE_DEFAULT,
+                true);
         final View settingsButton = mNotificationInfo.findViewById(R.id.info);
         assertTrue(settingsButton.getVisibility() != View.VISIBLE);
     }
 
     @Test
     public void testBindNotification_SettingsButtonReappearsAfterSecondBind() throws Exception {
-        mNotificationInfo.bindNotification(mMockPackageManager, mMockINotificationManager,
-                TEST_PACKAGE_NAME, mNotificationChannel, mNotificationChannelSet, mSbn, null, null,
-                null, true, false,
-                IMPORTANCE_DEFAULT, true);
-        mNotificationInfo.bindNotification(mMockPackageManager, mMockINotificationManager,
-                TEST_PACKAGE_NAME, mNotificationChannel, mNotificationChannelSet, mSbn, null,
-                (View v, NotificationChannel c, int appUid) -> {
-                }, null, true, false, IMPORTANCE_DEFAULT, true);
+        mNotificationInfo.bindNotification(
+                mMockPackageManager,
+                mMockINotificationManager,
+                mVisualStabilityManager,
+                TEST_PACKAGE_NAME,
+                mNotificationChannel,
+                mNotificationChannelSet,
+                mSbn,
+                null,
+                null,
+                null,
+                true,
+                false,
+                IMPORTANCE_DEFAULT,
+                true);
+        mNotificationInfo.bindNotification(
+                mMockPackageManager,
+                mMockINotificationManager,
+                mVisualStabilityManager,
+                TEST_PACKAGE_NAME,
+                mNotificationChannel,
+                mNotificationChannelSet,
+                mSbn,
+                null,
+                (View v, NotificationChannel c, int appUid) -> { },
+                null,
+                true,
+                false,
+                IMPORTANCE_DEFAULT,
+                true);
         final View settingsButton = mNotificationInfo.findViewById(R.id.info);
         assertEquals(View.VISIBLE, settingsButton.getVisibility());
     }
 
     @Test
     public void testBindNotificationLogging_notBlockingHelper() throws Exception {
-        mNotificationInfo.bindNotification(mMockPackageManager, mMockINotificationManager,
-                TEST_PACKAGE_NAME, mNotificationChannel, mNotificationChannelSet, mSbn,
-                null, null, null,
-                true, false,
-                IMPORTANCE_DEFAULT, true);
+        mNotificationInfo.bindNotification(
+                mMockPackageManager,
+                mMockINotificationManager,
+                mVisualStabilityManager,
+                TEST_PACKAGE_NAME,
+                mNotificationChannel,
+                mNotificationChannelSet,
+                mSbn,
+                null,
+                null,
+                null,
+                true,
+                false,
+                IMPORTANCE_DEFAULT,
+                true);
         verify(mMetricsLogger).write(argThat(logMaker ->
                 logMaker.getCategory() == MetricsEvent.ACTION_NOTE_CONTROLS
                         && logMaker.getType() == MetricsEvent.TYPE_OPEN
@@ -401,12 +593,22 @@
 
     @Test
     public void testBindNotificationLogging_BlockingHelper() throws Exception {
-        mNotificationInfo.bindNotification(mMockPackageManager, mMockINotificationManager,
-                TEST_PACKAGE_NAME, mNotificationChannel, mNotificationChannelSet, mSbn,
-                null, null, null,
-                false, true,
+        mNotificationInfo.bindNotification(
+                mMockPackageManager,
+                mMockINotificationManager,
+                mVisualStabilityManager,
+                TEST_PACKAGE_NAME,
+                mNotificationChannel,
+                mNotificationChannelSet,
+                mSbn,
+                null,
+                null,
+                null,
+                false,
                 true,
-                IMPORTANCE_DEFAULT, true);
+                true,
+                IMPORTANCE_DEFAULT,
+                true);
         verify(mMetricsLogger).write(argThat(logMaker ->
                 logMaker.getCategory() == MetricsEvent.ACTION_NOTE_CONTROLS
                         && logMaker.getType() == MetricsEvent.TYPE_OPEN
@@ -416,12 +618,22 @@
 
     @Test
     public void testLogBlockingHelperCounter_logsForBlockingHelper() throws Exception {
-        mNotificationInfo.bindNotification(mMockPackageManager, mMockINotificationManager,
-                TEST_PACKAGE_NAME, mNotificationChannel, mNotificationChannelSet, mSbn,
-                null, null, null,
-                false, true,
+        mNotificationInfo.bindNotification(
+                mMockPackageManager,
+                mMockINotificationManager,
+                mVisualStabilityManager,
+                TEST_PACKAGE_NAME,
+                mNotificationChannel,
+                mNotificationChannelSet,
+                mSbn,
+                null,
+                null,
+                null,
+                false,
                 true,
-                IMPORTANCE_DEFAULT, true);
+                true,
+                IMPORTANCE_DEFAULT,
+                true);
         mNotificationInfo.logBlockingHelperCounter("HowCanNotifsBeRealIfAppsArent");
         verify(mMetricsLogger).count(eq("HowCanNotifsBeRealIfAppsArent"), eq(1));
     }
@@ -429,13 +641,23 @@
     @Test
     public void testOnClickListenerPassesNullChannelForBundle() throws Exception {
         final CountDownLatch latch = new CountDownLatch(1);
-        mNotificationInfo.bindNotification(mMockPackageManager, mMockINotificationManager,
+        mNotificationInfo.bindNotification(
+                mMockPackageManager,
+                mMockINotificationManager,
+                mVisualStabilityManager,
                 TEST_PACKAGE_NAME, mNotificationChannel,
-                createMultipleChannelSet(MULTIPLE_CHANNEL_COUNT), mSbn, null,
+                createMultipleChannelSet(MULTIPLE_CHANNEL_COUNT),
+                mSbn,
+                null,
                 (View v, NotificationChannel c, int appUid) -> {
                     assertEquals(null, c);
                     latch.countDown();
-                }, null, true, true, IMPORTANCE_DEFAULT, true);
+                },
+                null,
+                true,
+                true,
+                IMPORTANCE_DEFAULT,
+                true);
 
         mNotificationInfo.findViewById(R.id.info).performClick();
         // Verify that listener was triggered.
@@ -446,10 +668,21 @@
     @UiThreadTest
     public void testBindNotification_ChannelNameInvisibleWhenBundleFromDifferentChannels()
             throws Exception {
-        mNotificationInfo.bindNotification(mMockPackageManager, mMockINotificationManager,
-                TEST_PACKAGE_NAME, mNotificationChannel,
-                createMultipleChannelSet(MULTIPLE_CHANNEL_COUNT), mSbn, null, null,
-                null, true, false, IMPORTANCE_DEFAULT, true);
+        mNotificationInfo.bindNotification(
+                mMockPackageManager,
+                mMockINotificationManager,
+                mVisualStabilityManager,
+                TEST_PACKAGE_NAME,
+                mNotificationChannel,
+                createMultipleChannelSet(MULTIPLE_CHANNEL_COUNT),
+                mSbn,
+                null,
+                null,
+                null,
+                true,
+                false,
+                IMPORTANCE_DEFAULT,
+                true);
         final TextView channelNameView =
                 mNotificationInfo.findViewById(R.id.channel_name);
         assertEquals(GONE, channelNameView.getVisibility());
@@ -458,10 +691,21 @@
     @Test
     @UiThreadTest
     public void testStopInvisibleIfBundleFromDifferentChannels() throws Exception {
-        mNotificationInfo.bindNotification(mMockPackageManager, mMockINotificationManager,
-                TEST_PACKAGE_NAME, mNotificationChannel,
-                createMultipleChannelSet(MULTIPLE_CHANNEL_COUNT), mSbn, null, null,
-                null, true, false, IMPORTANCE_DEFAULT, true);
+        mNotificationInfo.bindNotification(
+                mMockPackageManager,
+                mMockINotificationManager,
+                mVisualStabilityManager,
+                TEST_PACKAGE_NAME,
+                mNotificationChannel,
+                createMultipleChannelSet(MULTIPLE_CHANNEL_COUNT),
+                mSbn,
+                null,
+                null,
+                null,
+                true,
+                false,
+                IMPORTANCE_DEFAULT,
+                true);
         assertEquals(GONE, mNotificationInfo.findViewById(
                 R.id.interruptiveness_settings).getVisibility());
         assertEquals(VISIBLE, mNotificationInfo.findViewById(
@@ -470,10 +714,21 @@
 
     @Test
     public void testBindNotification_whenAppUnblockable() throws Exception {
-        mNotificationInfo.bindNotification(mMockPackageManager, mMockINotificationManager,
-                TEST_PACKAGE_NAME, mNotificationChannel, mNotificationChannelSet, mSbn, null, null,
-                null, true, true,
-                IMPORTANCE_DEFAULT, true);
+        mNotificationInfo.bindNotification(
+                mMockPackageManager,
+                mMockINotificationManager,
+                mVisualStabilityManager,
+                TEST_PACKAGE_NAME,
+                mNotificationChannel,
+                mNotificationChannelSet,
+                mSbn,
+                null,
+                null,
+                null,
+                true,
+                true,
+                IMPORTANCE_DEFAULT,
+                true);
         final TextView view = mNotificationInfo.findViewById(R.id.non_configurable_text);
         assertEquals(View.VISIBLE, view.getVisibility());
         assertEquals(mContext.getString(R.string.notification_unblockable_desc),
@@ -484,10 +739,21 @@
 
     @Test
     public void testBindNotification_DoesNotUpdateNotificationChannel() throws Exception {
-        mNotificationInfo.bindNotification(mMockPackageManager, mMockINotificationManager,
-                TEST_PACKAGE_NAME, mNotificationChannel, mNotificationChannelSet, mSbn, null, null,
-                null, true, false,
-                IMPORTANCE_DEFAULT, true);
+        mNotificationInfo.bindNotification(
+                mMockPackageManager,
+                mMockINotificationManager,
+                mVisualStabilityManager,
+                TEST_PACKAGE_NAME,
+                mNotificationChannel,
+                mNotificationChannelSet,
+                mSbn,
+                null,
+                null,
+                null,
+                true,
+                false,
+                IMPORTANCE_DEFAULT,
+                true);
         mTestableLooper.processAllMessages();
         verify(mMockINotificationManager, never()).updateNotificationChannelForPackage(
                 anyString(), eq(TEST_UID), any());
@@ -496,10 +762,21 @@
     @Test
     public void testDoesNotUpdateNotificationChannelAfterImportanceChanged() throws Exception {
         mNotificationChannel.setImportance(IMPORTANCE_LOW);
-        mNotificationInfo.bindNotification(mMockPackageManager, mMockINotificationManager,
-                TEST_PACKAGE_NAME, mNotificationChannel, mNotificationChannelSet, mSbn, null, null,
-                null, true, false,
-                IMPORTANCE_LOW, false);
+        mNotificationInfo.bindNotification(
+                mMockPackageManager,
+                mMockINotificationManager,
+                mVisualStabilityManager,
+                TEST_PACKAGE_NAME,
+                mNotificationChannel,
+                mNotificationChannelSet,
+                mSbn,
+                null,
+                null,
+                null,
+                true,
+                false,
+                IMPORTANCE_LOW,
+                false);
 
         mNotificationInfo.findViewById(R.id.alert).performClick();
         mTestableLooper.processAllMessages();
@@ -511,10 +788,21 @@
     public void testDoesNotUpdateNotificationChannelAfterImportanceChangedSilenced()
             throws Exception {
         mNotificationChannel.setImportance(IMPORTANCE_DEFAULT);
-        mNotificationInfo.bindNotification(mMockPackageManager, mMockINotificationManager,
-                TEST_PACKAGE_NAME, mNotificationChannel, mNotificationChannelSet, mSbn, null, null,
-                null, true, false,
-                IMPORTANCE_DEFAULT, true);
+        mNotificationInfo.bindNotification(
+                mMockPackageManager,
+                mMockINotificationManager,
+                mVisualStabilityManager,
+                TEST_PACKAGE_NAME,
+                mNotificationChannel,
+                mNotificationChannelSet,
+                mSbn,
+                null,
+                null,
+                null,
+                true,
+                false,
+                IMPORTANCE_DEFAULT,
+                true);
 
         mNotificationInfo.findViewById(R.id.silence).performClick();
         mTestableLooper.processAllMessages();
@@ -526,10 +814,21 @@
     public void testHandleCloseControls_DoesNotUpdateNotificationChannelIfUnchanged()
             throws Exception {
         int originalImportance = mNotificationChannel.getImportance();
-        mNotificationInfo.bindNotification(mMockPackageManager, mMockINotificationManager,
-                TEST_PACKAGE_NAME, mNotificationChannel, mNotificationChannelSet, mSbn, null, null,
-                null, true, false,
-                IMPORTANCE_DEFAULT, true);
+        mNotificationInfo.bindNotification(
+                mMockPackageManager,
+                mMockINotificationManager,
+                mVisualStabilityManager,
+                TEST_PACKAGE_NAME,
+                mNotificationChannel,
+                mNotificationChannelSet,
+                mSbn,
+                null,
+                null,
+                null,
+                true,
+                false,
+                IMPORTANCE_DEFAULT,
+                true);
 
         mNotificationInfo.handleCloseControls(true, false);
         mTestableLooper.processAllMessages();
@@ -542,10 +841,21 @@
     public void testHandleCloseControls_DoesNotUpdateNotificationChannelIfUnspecified()
             throws Exception {
         mNotificationChannel.setImportance(IMPORTANCE_UNSPECIFIED);
-        mNotificationInfo.bindNotification(mMockPackageManager, mMockINotificationManager,
-                TEST_PACKAGE_NAME, mNotificationChannel, mNotificationChannelSet, mSbn, null, null,
-                null, true, false,
-                IMPORTANCE_UNSPECIFIED, true);
+        mNotificationInfo.bindNotification(
+                mMockPackageManager,
+                mMockINotificationManager,
+                mVisualStabilityManager,
+                TEST_PACKAGE_NAME,
+                mNotificationChannel,
+                mNotificationChannelSet,
+                mSbn,
+                null,
+                null,
+                null,
+                true,
+                false,
+                IMPORTANCE_UNSPECIFIED,
+                true);
 
         mNotificationInfo.handleCloseControls(true, false);
 
@@ -561,13 +871,22 @@
         NotificationInfo.CheckSaveListener listener =
                 mock(NotificationInfo.CheckSaveListener.class);
         mNotificationChannel.setImportance(IMPORTANCE_DEFAULT);
-        mNotificationInfo.bindNotification(mMockPackageManager, mMockINotificationManager,
-                TEST_PACKAGE_NAME, mNotificationChannel /* notificationChannel */,
-                createMultipleChannelSet(10) /* numUniqueChannelsInRow */, mSbn,
+        mNotificationInfo.bindNotification(
+                mMockPackageManager,
+                mMockINotificationManager,
+                mVisualStabilityManager,
+                TEST_PACKAGE_NAME,
+                mNotificationChannel /* notificationChannel */,
+                createMultipleChannelSet(10) /* numUniqueChannelsInRow */,
+                mSbn,
                 listener /* checkSaveListener */,
-                null /* onSettingsClick */, null /* onAppSettingsClick */, true /* provisioned */,
-                false /* isNonblockable */, true /* isForBlockingHelper */,
-                IMPORTANCE_DEFAULT, true);
+                null /* onSettingsClick */,
+                null /* onAppSettingsClick */,
+                true /* provisioned */,
+                false /* isNonblockable */,
+                true /* isForBlockingHelper */,
+                IMPORTANCE_DEFAULT,
+                true);
 
         NotificationGuts guts = spy(new NotificationGuts(mContext, null));
         when(guts.getWindowToken()).thenReturn(mock(IBinder.class));
@@ -591,13 +910,21 @@
         NotificationInfo.CheckSaveListener listener =
                 mock(NotificationInfo.CheckSaveListener.class);
         mNotificationChannel.setImportance(IMPORTANCE_DEFAULT);
-        mNotificationInfo.bindNotification(mMockPackageManager, mMockINotificationManager,
-                TEST_PACKAGE_NAME, mNotificationChannel /* notificationChannel */,
-                createMultipleChannelSet(10) /* numUniqueChannelsInRow */, mSbn,
+        mNotificationInfo.bindNotification(
+                mMockPackageManager,
+                mMockINotificationManager,
+                mVisualStabilityManager,
+                TEST_PACKAGE_NAME,
+                mNotificationChannel /* notificationChannel */,
+                createMultipleChannelSet(10) /* numUniqueChannelsInRow */,
+                mSbn,
                 listener /* checkSaveListener */,
-                null /* onSettingsClick */, null /* onAppSettingsClick */,
-                false /* isNonblockable */, true /* isForBlockingHelper */,
-                true, IMPORTANCE_DEFAULT, true);
+                null /* onSettingsClick */,
+                null /* onAppSettingsClick */,
+                false /* isNonblockable */,
+                true /* isForBlockingHelper */,
+                true, IMPORTANCE_DEFAULT,
+                true);
 
         mNotificationInfo.handleCloseControls(true /* save */, false /* force */);
 
@@ -611,14 +938,22 @@
         NotificationInfo.CheckSaveListener listener =
                 mock(NotificationInfo.CheckSaveListener.class);
         mNotificationChannel.setImportance(IMPORTANCE_DEFAULT);
-        mNotificationInfo.bindNotification(mMockPackageManager, mMockINotificationManager,
-                TEST_PACKAGE_NAME, mNotificationChannel /* notificationChannel */,
-                createMultipleChannelSet(10) /* numUniqueChannelsInRow */, mSbn,
+        mNotificationInfo.bindNotification(
+                mMockPackageManager,
+                mMockINotificationManager,
+                mVisualStabilityManager,
+                TEST_PACKAGE_NAME,
+                mNotificationChannel /* notificationChannel */,
+                createMultipleChannelSet(10) /* numUniqueChannelsInRow */,
+                mSbn,
                 listener /* checkSaveListener */,
-                null /* onSettingsClick */, null /* onAppSettingsClick */,
+                null /* onSettingsClick */,
+                null /* onAppSettingsClick */,
                 true /* provisioned */,
-                false /* isNonblockable */, true /* isForBlockingHelper */,
-                IMPORTANCE_DEFAULT, true);
+                false /* isNonblockable */,
+                true /* isForBlockingHelper */,
+                IMPORTANCE_DEFAULT,
+                true);
 
         mNotificationInfo.findViewById(R.id.deliver_silently).performClick();
         mTestableLooper.processAllMessages();
@@ -631,6 +966,7 @@
         mNotificationInfo.bindNotification(
                 mMockPackageManager,
                 mMockINotificationManager,
+                mVisualStabilityManager,
                 TEST_PACKAGE_NAME,
                 mNotificationChannel,
                 mNotificationChannelSet /* numChannels */,
@@ -641,12 +977,13 @@
                 false /* isNonblockable */,
                 true /* isForBlockingHelper */,
                 true,
-                IMPORTANCE_DEFAULT, true);
+                IMPORTANCE_DEFAULT,
+                true);
         NotificationGuts guts = mock(NotificationGuts.class);
         doCallRealMethod().when(guts).closeControls(anyInt(), anyInt(), anyBoolean(), anyBoolean());
         mNotificationInfo.setGutsParent(guts);
 
-        mNotificationInfo.closeControls(mNotificationInfo);
+        mNotificationInfo.closeControls(mNotificationInfo, true);
 
         verify(mBlockingHelperManager).dismissCurrentBlockingHelper();
     }
@@ -658,6 +995,7 @@
         mNotificationInfo.bindNotification(
                 mMockPackageManager,
                 mMockINotificationManager,
+                mVisualStabilityManager,
                 TEST_PACKAGE_NAME,
                 mNotificationChannel,
                 mNotificationChannelSet /* numChannels */,
@@ -688,10 +1026,21 @@
     @Test
     public void testKeepUpdatesNotificationChannel_blockingHelper() throws Exception {
         mNotificationChannel.setImportance(IMPORTANCE_LOW);
-        mNotificationInfo.bindNotification(mMockPackageManager, mMockINotificationManager,
-                TEST_PACKAGE_NAME, mNotificationChannel, mNotificationChannelSet, mSbn, null, null,
-                null, true, true,
-                IMPORTANCE_LOW, false);
+        mNotificationInfo.bindNotification(
+                mMockPackageManager,
+                mMockINotificationManager,
+                mVisualStabilityManager,
+                TEST_PACKAGE_NAME,
+                mNotificationChannel,
+                mNotificationChannelSet,
+                mSbn,
+                null,
+                null,
+                null,
+                true,
+                true,
+                IMPORTANCE_LOW,
+                false);
 
         mNotificationInfo.findViewById(R.id.keep_showing).performClick();
         mNotificationInfo.handleCloseControls(true, false);
@@ -708,10 +1057,21 @@
     @Test
     public void testNoActionsUpdatesNotificationChannel_blockingHelper() throws Exception {
         mNotificationChannel.setImportance(IMPORTANCE_DEFAULT);
-        mNotificationInfo.bindNotification(mMockPackageManager, mMockINotificationManager,
-                TEST_PACKAGE_NAME, mNotificationChannel, mNotificationChannelSet, mSbn, null, null,
-                null, true, true,
-                IMPORTANCE_DEFAULT, true);
+        mNotificationInfo.bindNotification(
+                mMockPackageManager,
+                mMockINotificationManager,
+                mVisualStabilityManager,
+                TEST_PACKAGE_NAME,
+                mNotificationChannel,
+                mNotificationChannelSet,
+                mSbn,
+                null,
+                null,
+                null,
+                true,
+                true,
+                IMPORTANCE_DEFAULT,
+                true);
 
         mNotificationInfo.handleCloseControls(true, false);
 
@@ -727,10 +1087,21 @@
     @Test
     public void testSilenceCallsUpdateNotificationChannel() throws Exception {
         mNotificationChannel.setImportance(IMPORTANCE_DEFAULT);
-        mNotificationInfo.bindNotification(mMockPackageManager, mMockINotificationManager,
-                TEST_PACKAGE_NAME, mNotificationChannel, mNotificationChannelSet, mSbn, null, null,
-                null, true, false,
-                IMPORTANCE_DEFAULT, true);
+        mNotificationInfo.bindNotification(
+                mMockPackageManager,
+                mMockINotificationManager,
+                mVisualStabilityManager,
+                TEST_PACKAGE_NAME,
+                mNotificationChannel,
+                mNotificationChannelSet,
+                mSbn,
+                null,
+                null,
+                null,
+                true,
+                false,
+                IMPORTANCE_DEFAULT,
+                true);
 
         mNotificationInfo.findViewById(R.id.silence).performClick();
         mNotificationInfo.findViewById(R.id.done).performClick();
@@ -749,10 +1120,21 @@
     @Test
     public void testUnSilenceCallsUpdateNotificationChannel() throws Exception {
         mNotificationChannel.setImportance(IMPORTANCE_LOW);
-        mNotificationInfo.bindNotification(mMockPackageManager, mMockINotificationManager,
-                TEST_PACKAGE_NAME, mNotificationChannel, mNotificationChannelSet, mSbn, null, null,
-                null, true, false,
-                IMPORTANCE_LOW, false);
+        mNotificationInfo.bindNotification(
+                mMockPackageManager,
+                mMockINotificationManager,
+                mVisualStabilityManager,
+                TEST_PACKAGE_NAME,
+                mNotificationChannel,
+                mNotificationChannelSet,
+                mSbn,
+                null,
+                null,
+                null,
+                true,
+                false,
+                IMPORTANCE_LOW,
+                false);
 
         mNotificationInfo.findViewById(R.id.alert).performClick();
         mNotificationInfo.findViewById(R.id.done).performClick();
@@ -772,10 +1154,21 @@
     public void testSilenceCallsUpdateNotificationChannel_channelImportanceUnspecified()
             throws Exception {
         mNotificationChannel.setImportance(IMPORTANCE_UNSPECIFIED);
-        mNotificationInfo.bindNotification(mMockPackageManager, mMockINotificationManager,
-                TEST_PACKAGE_NAME, mNotificationChannel, mNotificationChannelSet, mSbn, null, null,
-                null, true, false,
-                IMPORTANCE_UNSPECIFIED, true);
+        mNotificationInfo.bindNotification(
+                mMockPackageManager,
+                mMockINotificationManager,
+                mVisualStabilityManager,
+                TEST_PACKAGE_NAME,
+                mNotificationChannel,
+                mNotificationChannelSet,
+                mSbn,
+                null,
+                null,
+                null,
+                true,
+                false,
+                IMPORTANCE_UNSPECIFIED,
+                true);
 
         mNotificationInfo.findViewById(R.id.silence).performClick();
         mNotificationInfo.findViewById(R.id.done).performClick();
@@ -795,10 +1188,21 @@
     public void testSilenceCallsUpdateNotificationChannel_channelImportanceMin()
             throws Exception {
         mNotificationChannel.setImportance(IMPORTANCE_MIN);
-        mNotificationInfo.bindNotification(mMockPackageManager, mMockINotificationManager,
-                TEST_PACKAGE_NAME, mNotificationChannel, mNotificationChannelSet, mSbn, null, null,
-                null, true, false,
-                IMPORTANCE_MIN, false);
+        mNotificationInfo.bindNotification(
+                mMockPackageManager,
+                mMockINotificationManager,
+                mVisualStabilityManager,
+                TEST_PACKAGE_NAME,
+                mNotificationChannel,
+                mNotificationChannelSet,
+                mSbn,
+                null,
+                null,
+                null,
+                true,
+                false,
+                IMPORTANCE_MIN,
+                false);
 
         assertEquals(mContext.getString(R.string.inline_done_button),
                 ((TextView) mNotificationInfo.findViewById(R.id.done)).getText());
@@ -821,10 +1225,21 @@
     public void testAlertCallsUpdateNotificationChannel_channelImportanceMin()
             throws Exception {
         mNotificationChannel.setImportance(IMPORTANCE_MIN);
-        mNotificationInfo.bindNotification(mMockPackageManager, mMockINotificationManager,
-                TEST_PACKAGE_NAME, mNotificationChannel, mNotificationChannelSet, mSbn, null, null,
-                null, true, false,
-                IMPORTANCE_MIN, false);
+        mNotificationInfo.bindNotification(
+                mMockPackageManager,
+                mMockINotificationManager,
+                mVisualStabilityManager,
+                TEST_PACKAGE_NAME,
+                mNotificationChannel,
+                mNotificationChannelSet,
+                mSbn,
+                null,
+                null,
+                null,
+                true,
+                false,
+                IMPORTANCE_MIN,
+                false);
 
         assertEquals(mContext.getString(R.string.inline_done_button),
                 ((TextView) mNotificationInfo.findViewById(R.id.done)).getText());
@@ -844,13 +1259,50 @@
     }
 
     @Test
+    public void testAdjustImportanceTemporarilyAllowsReordering() throws Exception {
+        mNotificationChannel.setImportance(IMPORTANCE_DEFAULT);
+        mNotificationInfo.bindNotification(
+                mMockPackageManager,
+                mMockINotificationManager,
+                mVisualStabilityManager,
+                TEST_PACKAGE_NAME,
+                mNotificationChannel,
+                mNotificationChannelSet,
+                mSbn,
+                null,
+                null,
+                null,
+                true,
+                false,
+                IMPORTANCE_DEFAULT,
+                true);
+
+        mNotificationInfo.findViewById(R.id.silence).performClick();
+        mNotificationInfo.findViewById(R.id.done).performClick();
+        mNotificationInfo.handleCloseControls(true, false);
+
+        verify(mVisualStabilityManager).temporarilyAllowReordering();
+    }
+
+    @Test
     public void testDoneText()
             throws Exception {
         mNotificationChannel.setImportance(IMPORTANCE_LOW);
-        mNotificationInfo.bindNotification(mMockPackageManager, mMockINotificationManager,
-                TEST_PACKAGE_NAME, mNotificationChannel, mNotificationChannelSet, mSbn, null, null,
-                null, true, false,
-                IMPORTANCE_LOW, false);
+        mNotificationInfo.bindNotification(
+                mMockPackageManager,
+                mMockINotificationManager,
+                mVisualStabilityManager,
+                TEST_PACKAGE_NAME,
+                mNotificationChannel,
+                mNotificationChannelSet,
+                mSbn,
+                null,
+                null,
+                null,
+                true,
+                false,
+                IMPORTANCE_LOW,
+                false);
 
         assertEquals(mContext.getString(R.string.inline_done_button),
                 ((TextView) mNotificationInfo.findViewById(R.id.done)).getText());
@@ -866,10 +1318,21 @@
     public void testUnSilenceCallsUpdateNotificationChannel_channelImportanceUnspecified()
             throws Exception {
         mNotificationChannel.setImportance(IMPORTANCE_LOW);
-        mNotificationInfo.bindNotification(mMockPackageManager, mMockINotificationManager,
-                TEST_PACKAGE_NAME, mNotificationChannel, mNotificationChannelSet, mSbn, null, null,
-                null, true, false,
-                IMPORTANCE_LOW, false);
+        mNotificationInfo.bindNotification(
+                mMockPackageManager,
+                mMockINotificationManager,
+                mVisualStabilityManager,
+                TEST_PACKAGE_NAME,
+                mNotificationChannel,
+                mNotificationChannelSet,
+                mSbn,
+                null,
+                null,
+                null,
+                true,
+                false,
+                IMPORTANCE_LOW,
+                false);
 
         mNotificationInfo.findViewById(R.id.alert).performClick();
         mNotificationInfo.findViewById(R.id.done).performClick();
@@ -888,10 +1351,21 @@
     @Test
     public void testCloseControlsDoesNotUpdateIfSaveIsFalse() throws Exception {
         mNotificationChannel.setImportance(IMPORTANCE_LOW);
-        mNotificationInfo.bindNotification(mMockPackageManager, mMockINotificationManager,
-                TEST_PACKAGE_NAME, mNotificationChannel, mNotificationChannelSet, mSbn, null, null,
-                null, true, false,
-                IMPORTANCE_LOW, false);
+        mNotificationInfo.bindNotification(
+                mMockPackageManager,
+                mMockINotificationManager,
+                mVisualStabilityManager,
+                TEST_PACKAGE_NAME,
+                mNotificationChannel,
+                mNotificationChannelSet,
+                mSbn,
+                null,
+                null,
+                null,
+                true,
+                false,
+                IMPORTANCE_LOW,
+                false);
 
         mNotificationInfo.findViewById(R.id.alert).performClick();
         mNotificationInfo.findViewById(R.id.done).performClick();
@@ -905,11 +1379,23 @@
     @Test
     public void testCloseControlsUpdatesWhenCheckSaveListenerUsesCallback() throws Exception {
         mNotificationChannel.setImportance(IMPORTANCE_LOW);
-        mNotificationInfo.bindNotification(mMockPackageManager, mMockINotificationManager,
-                TEST_PACKAGE_NAME, mNotificationChannel, mNotificationChannelSet, mSbn,
+        mNotificationInfo.bindNotification(
+                mMockPackageManager,
+                mMockINotificationManager,
+                mVisualStabilityManager,
+                TEST_PACKAGE_NAME,
+                mNotificationChannel,
+                mNotificationChannelSet,
+                mSbn,
                 (Runnable saveImportance, StatusBarNotification sbn) -> {
                     saveImportance.run();
-                }, null, null, true, false, IMPORTANCE_LOW, false
+                },
+                null,
+                null,
+                true,
+                false,
+                IMPORTANCE_LOW,
+                false
         );
 
         mNotificationInfo.findViewById(R.id.alert).performClick();
@@ -928,11 +1414,23 @@
     @Test
     public void testCloseControls_withoutHittingApply() throws Exception {
         mNotificationChannel.setImportance(IMPORTANCE_LOW);
-        mNotificationInfo.bindNotification(mMockPackageManager, mMockINotificationManager,
-                TEST_PACKAGE_NAME, mNotificationChannel, mNotificationChannelSet, mSbn,
+        mNotificationInfo.bindNotification(
+                mMockPackageManager,
+                mMockINotificationManager,
+                mVisualStabilityManager,
+                TEST_PACKAGE_NAME,
+                mNotificationChannel,
+                mNotificationChannelSet,
+                mSbn,
                 (Runnable saveImportance, StatusBarNotification sbn) -> {
                     saveImportance.run();
-                }, null, null, true, false, IMPORTANCE_LOW, false
+                },
+                null,
+                null,
+                true,
+                false,
+                IMPORTANCE_LOW,
+                false
         );
 
         mNotificationInfo.findViewById(R.id.alert).performClick();
@@ -944,11 +1442,23 @@
     public void testWillBeRemovedReturnsFalse() throws Exception {
         assertFalse(mNotificationInfo.willBeRemoved());
 
-        mNotificationInfo.bindNotification(mMockPackageManager, mMockINotificationManager,
-                TEST_PACKAGE_NAME, mNotificationChannel, mNotificationChannelSet, mSbn,
+        mNotificationInfo.bindNotification(
+                mMockPackageManager,
+                mMockINotificationManager,
+                mVisualStabilityManager,
+                TEST_PACKAGE_NAME,
+                mNotificationChannel,
+                mNotificationChannelSet,
+                mSbn,
                 (Runnable saveImportance, StatusBarNotification sbn) -> {
                     saveImportance.run();
-                }, null, null, true, false, IMPORTANCE_LOW, false
+                },
+                null,
+                null,
+                true,
+                false,
+                IMPORTANCE_LOW,
+                false
         );
 
         assertFalse(mNotificationInfo.willBeRemoved());
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/wrapper/NotificationMediaTemplateViewWrapperTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/wrapper/NotificationMediaTemplateViewWrapperTest.java
index df41a84..4f844f0 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/wrapper/NotificationMediaTemplateViewWrapperTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/wrapper/NotificationMediaTemplateViewWrapperTest.java
@@ -131,7 +131,7 @@
         ));
 
         // Ensure the callback runs at least once
-        mWrapper.mUpdatePlaybackUi.run();
+        mWrapper.mOnUpdateTimerTick.run();
 
         verify(mMetricsLogger).write(argThat(logMaker ->
                 logMaker.getCategory() == MetricsEvent.MEDIA_NOTIFICATION_SEEKBAR
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayoutTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayoutTest.java
index 56265d0..d425982 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayoutTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayoutTest.java
@@ -70,6 +70,7 @@
 import com.android.systemui.statusbar.notification.row.NotificationBlockingHelperManager;
 import com.android.systemui.statusbar.phone.HeadsUpManagerPhone;
 import com.android.systemui.statusbar.phone.NotificationGroupManager;
+import com.android.systemui.statusbar.phone.NotificationIconAreaController;
 import com.android.systemui.statusbar.phone.ScrimController;
 import com.android.systemui.statusbar.phone.ShadeController;
 import com.android.systemui.statusbar.phone.StatusBar;
@@ -110,6 +111,7 @@
     @Mock private NotificationData mNotificationData;
     @Mock private NotificationRemoteInputManager mRemoteInputManager;
     @Mock private RemoteInputController mRemoteInputController;
+    @Mock private NotificationIconAreaController mNotificationIconAreaController;
     @Mock private MetricsLogger mMetricsLogger;
     @Mock private NotificationRoundnessManager mNotificationRoundnessManager;
     private TestableNotificationEntryManager mEntryManager;
@@ -162,6 +164,7 @@
         mStackScroller.setHeadsUpManager(mHeadsUpManager);
         mStackScroller.setGroupManager(mGroupManager);
         mStackScroller.setEmptyShadeView(mEmptyShadeView);
+        mStackScroller.setIconAreaController(mNotificationIconAreaController);
 
         // Stub out functionality that isn't necessary to test.
         doNothing().when(mBar)
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/NavigationBarContextTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/NavigationBarContextTest.java
index cb70a1f..be69f5f 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/NavigationBarContextTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/NavigationBarContextTest.java
@@ -180,9 +180,9 @@
         final Drawable d = mock(Drawable.class);
         final ContextualButton button = spy(mBtn0);
         final KeyButtonDrawable kbd1 = spy(new KeyButtonDrawable(d, unusedColor, unusedColor,
-                false /* horizontalFlip */, false /* hasOvalBg */));
+                false /* horizontalFlip */, null /* ovalBackgroundColor */));
         final KeyButtonDrawable kbd2 = spy(new KeyButtonDrawable(d, unusedColor, unusedColor,
-                false /* horizontalFlip */, false /* hasOvalBg */));
+                false /* horizontalFlip */, null /* ovalBackgroundColor */));
         kbd1.setDarkIntensity(TEST_DARK_INTENSITY);
         kbd2.setDarkIntensity(0f);
 
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/NavigationBarFragmentTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/NavigationBarFragmentTest.java
index faf5a97..3da9a4b 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/NavigationBarFragmentTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/NavigationBarFragmentTest.java
@@ -56,6 +56,7 @@
 import com.android.systemui.SysuiBaseFragmentTest;
 import com.android.systemui.SysuiTestableContext;
 import com.android.systemui.assist.AssistManager;
+import com.android.systemui.plugins.statusbar.StatusBarStateController;
 import com.android.systemui.recents.OverviewProxyService;
 import com.android.systemui.recents.Recents;
 import com.android.systemui.stackdivider.Divider;
@@ -215,7 +216,8 @@
                 new MetricsLogger(),
                 mock(AssistManager.class),
                 mOverviewProxyService,
-                mock(NavigationModeController.class));
+                mock(NavigationModeController.class),
+                mock(StatusBarStateController.class));
     }
 
     private class HostCallbacksForExternalDisplay extends
diff --git a/packages/VpnDialogs/res/values-hi/strings.xml b/packages/VpnDialogs/res/values-hi/strings.xml
index 5560a85..34b79cb 100644
--- a/packages/VpnDialogs/res/values-hi/strings.xml
+++ b/packages/VpnDialogs/res/values-hi/strings.xml
@@ -30,7 +30,7 @@
     <string name="always_on_disconnected_message_separator" msgid="3310614409322581371">" "</string>
     <string name="always_on_disconnected_message_settings_link" msgid="6172280302829992412">"VPN सेटिंग बदलें"</string>
     <string name="configure" msgid="4905518375574791375">"कॉन्फ़िगर करें"</string>
-    <string name="disconnect" msgid="971412338304200056">"डिस्‍कनेक्‍ट करें"</string>
+    <string name="disconnect" msgid="971412338304200056">"डिसकनेक्ट करें"</string>
     <string name="open_app" msgid="3717639178595958667">"ऐप खोलें"</string>
     <string name="dismiss" msgid="6192859333764711227">"खारिज करें"</string>
 </resources>
diff --git a/packages/overlays/NavigationBarModeGesturalOverlay/res/values/config.xml b/packages/overlays/NavigationBarModeGesturalOverlay/res/values/config.xml
index f1d2e0b..96ed7b4 100644
--- a/packages/overlays/NavigationBarModeGesturalOverlay/res/values/config.xml
+++ b/packages/overlays/NavigationBarModeGesturalOverlay/res/values/config.xml
@@ -37,6 +37,15 @@
      {@link Window#setEnsuringNavigationBarContrastWhenTransparent}. -->
     <bool name="config_navBarNeedsScrim">false</bool>
 
+    <!-- Controls the opacity of the navigation bar depending on the visibility of the
+     various workspace stacks.
+     0 - Nav bar is always opaque when either the freeform stack or docked stack is visible.
+     1 - Nav bar is always translucent when the freeform stack is visible, otherwise always
+         opaque.
+     2 - Nav bar is never forced opaque.
+     -->
+    <integer name="config_navBarOpacityMode">2</integer>
+
     <!-- Controls whether seamless rotation should be allowed even though the navbar can move
          (which normally prevents seamless rotation). -->
     <bool name="config_allowSeamlessRotationDespiteNavBarMoving">true</bool>
diff --git a/packages/overlays/NavigationBarModeGesturalOverlay/res/values/dimens.xml b/packages/overlays/NavigationBarModeGesturalOverlay/res/values/dimens.xml
index 1232201..ac1f022 100644
--- a/packages/overlays/NavigationBarModeGesturalOverlay/res/values/dimens.xml
+++ b/packages/overlays/NavigationBarModeGesturalOverlay/res/values/dimens.xml
@@ -25,6 +25,6 @@
     <dimen name="navigation_bar_width">16dp</dimen>
     <!-- Height of the bottom navigation / system bar. -->
     <dimen name="navigation_bar_frame_height">48dp</dimen>
-        <!-- The height of the bottom navigation gesture area. -->
+    <!-- The height of the bottom navigation gesture area. -->
     <dimen name="navigation_bar_gesture_height">32dp</dimen>
 </resources>
\ No newline at end of file
diff --git a/packages/overlays/NavigationBarModeGesturalOverlayExtraWideBack/res/values/config.xml b/packages/overlays/NavigationBarModeGesturalOverlayExtraWideBack/res/values/config.xml
index c8f994c..d5991f3 100644
--- a/packages/overlays/NavigationBarModeGesturalOverlayExtraWideBack/res/values/config.xml
+++ b/packages/overlays/NavigationBarModeGesturalOverlayExtraWideBack/res/values/config.xml
@@ -37,6 +37,15 @@
      {@link Window#setEnsuringNavigationBarContrastWhenTransparent}. -->
     <bool name="config_navBarNeedsScrim">false</bool>
 
+    <!-- Controls the opacity of the navigation bar depending on the visibility of the
+     various workspace stacks.
+     0 - Nav bar is always opaque when either the freeform stack or docked stack is visible.
+     1 - Nav bar is always translucent when the freeform stack is visible, otherwise always
+         opaque.
+     2 - Nav bar is never forced opaque.
+     -->
+    <integer name="config_navBarOpacityMode">2</integer>
+
     <!-- Controls whether seamless rotation should be allowed even though the navbar can move
          (which normally prevents seamless rotation). -->
     <bool name="config_allowSeamlessRotationDespiteNavBarMoving">true</bool>
diff --git a/packages/overlays/NavigationBarModeGesturalOverlayExtraWideBack/res/values/dimens.xml b/packages/overlays/NavigationBarModeGesturalOverlayExtraWideBack/res/values/dimens.xml
index 987d203..ac1f022 100644
--- a/packages/overlays/NavigationBarModeGesturalOverlayExtraWideBack/res/values/dimens.xml
+++ b/packages/overlays/NavigationBarModeGesturalOverlayExtraWideBack/res/values/dimens.xml
@@ -25,4 +25,6 @@
     <dimen name="navigation_bar_width">16dp</dimen>
     <!-- Height of the bottom navigation / system bar. -->
     <dimen name="navigation_bar_frame_height">48dp</dimen>
+    <!-- The height of the bottom navigation gesture area. -->
+    <dimen name="navigation_bar_gesture_height">32dp</dimen>
 </resources>
\ No newline at end of file
diff --git a/packages/overlays/NavigationBarModeGesturalOverlayNarrowBack/res/values/config.xml b/packages/overlays/NavigationBarModeGesturalOverlayNarrowBack/res/values/config.xml
index 693110a..ff507ee 100644
--- a/packages/overlays/NavigationBarModeGesturalOverlayNarrowBack/res/values/config.xml
+++ b/packages/overlays/NavigationBarModeGesturalOverlayNarrowBack/res/values/config.xml
@@ -37,6 +37,15 @@
      {@link Window#setEnsuringNavigationBarContrastWhenTransparent}. -->
     <bool name="config_navBarNeedsScrim">false</bool>
 
+    <!-- Controls the opacity of the navigation bar depending on the visibility of the
+     various workspace stacks.
+     0 - Nav bar is always opaque when either the freeform stack or docked stack is visible.
+     1 - Nav bar is always translucent when the freeform stack is visible, otherwise always
+         opaque.
+     2 - Nav bar is never forced opaque.
+     -->
+    <integer name="config_navBarOpacityMode">2</integer>
+
     <!-- Controls whether seamless rotation should be allowed even though the navbar can move
          (which normally prevents seamless rotation). -->
     <bool name="config_allowSeamlessRotationDespiteNavBarMoving">true</bool>
diff --git a/packages/overlays/NavigationBarModeGesturalOverlayNarrowBack/res/values/dimens.xml b/packages/overlays/NavigationBarModeGesturalOverlayNarrowBack/res/values/dimens.xml
index 987d203..ac1f022 100644
--- a/packages/overlays/NavigationBarModeGesturalOverlayNarrowBack/res/values/dimens.xml
+++ b/packages/overlays/NavigationBarModeGesturalOverlayNarrowBack/res/values/dimens.xml
@@ -25,4 +25,6 @@
     <dimen name="navigation_bar_width">16dp</dimen>
     <!-- Height of the bottom navigation / system bar. -->
     <dimen name="navigation_bar_frame_height">48dp</dimen>
+    <!-- The height of the bottom navigation gesture area. -->
+    <dimen name="navigation_bar_gesture_height">32dp</dimen>
 </resources>
\ No newline at end of file
diff --git a/packages/overlays/NavigationBarModeGesturalOverlayWideBack/res/values/config.xml b/packages/overlays/NavigationBarModeGesturalOverlayWideBack/res/values/config.xml
index 5cd6ce3..378756a 100644
--- a/packages/overlays/NavigationBarModeGesturalOverlayWideBack/res/values/config.xml
+++ b/packages/overlays/NavigationBarModeGesturalOverlayWideBack/res/values/config.xml
@@ -37,6 +37,15 @@
      {@link Window#setEnsuringNavigationBarContrastWhenTransparent}. -->
     <bool name="config_navBarNeedsScrim">false</bool>
 
+    <!-- Controls the opacity of the navigation bar depending on the visibility of the
+     various workspace stacks.
+     0 - Nav bar is always opaque when either the freeform stack or docked stack is visible.
+     1 - Nav bar is always translucent when the freeform stack is visible, otherwise always
+         opaque.
+     2 - Nav bar is never forced opaque.
+     -->
+    <integer name="config_navBarOpacityMode">2</integer>
+
     <!-- Controls whether seamless rotation should be allowed even though the navbar can move
          (which normally prevents seamless rotation). -->
     <bool name="config_allowSeamlessRotationDespiteNavBarMoving">true</bool>
diff --git a/packages/overlays/NavigationBarModeGesturalOverlayWideBack/res/values/dimens.xml b/packages/overlays/NavigationBarModeGesturalOverlayWideBack/res/values/dimens.xml
index 987d203..ac1f022 100644
--- a/packages/overlays/NavigationBarModeGesturalOverlayWideBack/res/values/dimens.xml
+++ b/packages/overlays/NavigationBarModeGesturalOverlayWideBack/res/values/dimens.xml
@@ -25,4 +25,6 @@
     <dimen name="navigation_bar_width">16dp</dimen>
     <!-- Height of the bottom navigation / system bar. -->
     <dimen name="navigation_bar_frame_height">48dp</dimen>
+    <!-- The height of the bottom navigation gesture area. -->
+    <dimen name="navigation_bar_gesture_height">32dp</dimen>
 </resources>
\ No newline at end of file
diff --git a/services/autofill/java/com/android/server/autofill/Session.java b/services/autofill/java/com/android/server/autofill/Session.java
index af9b0e2..3764ca4 100644
--- a/services/autofill/java/com/android/server/autofill/Session.java
+++ b/services/autofill/java/com/android/server/autofill/Session.java
@@ -569,12 +569,13 @@
     @GuardedBy("mLock")
     private void requestNewFillResponseLocked(@NonNull ViewState viewState, int newState,
             int flags) {
-        if (mForAugmentedAutofillOnly) {
+        if (mForAugmentedAutofillOnly || mRemoteFillService == null) {
             if (sVerbose) {
                 Slog.v(TAG, "requestNewFillResponse(): triggering augmented autofill instead "
                         + "(mForAugmentedAutofillOnly=" + mForAugmentedAutofillOnly
                         + ", flags=" + flags + ")");
             }
+            mForAugmentedAutofillOnly = true;
             triggerAugmentedAutofillLocked();
             return;
         }
diff --git a/services/contentsuggestions/java/com/android/server/contentsuggestions/ContentSuggestionsPerUserService.java b/services/contentsuggestions/java/com/android/server/contentsuggestions/ContentSuggestionsPerUserService.java
index 7709311..593478c 100644
--- a/services/contentsuggestions/java/com/android/server/contentsuggestions/ContentSuggestionsPerUserService.java
+++ b/services/contentsuggestions/java/com/android/server/contentsuggestions/ContentSuggestionsPerUserService.java
@@ -98,7 +98,7 @@
         RemoteContentSuggestionsService service = getRemoteServiceLocked();
         if (service != null) {
             ActivityManager.TaskSnapshot snapshot =
-                    mActivityTaskManagerInternal.getTaskSnapshot(taskId, false);
+                    mActivityTaskManagerInternal.getTaskSnapshotNoRestore(taskId, false);
             GraphicBuffer snapshotBuffer = null;
             int colorSpaceId = 0;
             if (snapshot != null) {
diff --git a/services/core/java/com/android/server/AlarmManagerService.java b/services/core/java/com/android/server/AlarmManagerService.java
index d0edaaa..e2a874e 100644
--- a/services/core/java/com/android/server/AlarmManagerService.java
+++ b/services/core/java/com/android/server/AlarmManagerService.java
@@ -210,6 +210,7 @@
     IAlarmListener mTimeTickTrigger;
     PendingIntent mDateChangeSender;
     Random mRandom;
+    PendingIntent.CancelListener mOperationCancelListener;
     boolean mInteractive = true;
     long mNonInteractiveStartTime;
     long mNonInteractiveTime;
@@ -1497,6 +1498,7 @@
 
         synchronized (mLock) {
             mHandler = new AlarmHandler();
+            mOperationCancelListener = (intent) -> removeImpl(intent, null);
             mConstants = new Constants(mHandler);
             mAppWakeupHistory = new AppWakeupHistory(Constants.DEFAULT_APP_STANDBY_WINDOW);
 
@@ -1748,7 +1750,9 @@
         } else {
             maxElapsed = triggerElapsed + windowLength;
         }
-
+        if (operation != null) {
+            operation.registerCancelListener(mOperationCancelListener);
+        }
         synchronized (mLock) {
             if (DEBUG_BATCH) {
                 Slog.v(TAG, "set(" + operation + ") : type=" + type
@@ -1761,8 +1765,9 @@
                         "Maximum limit of concurrent alarms " + mConstants.MAX_ALARMS_PER_UID
                                 + " reached for uid: " + UserHandle.formatUid(callingUid)
                                 + ", callingPackage: " + callingPackage;
-                // STOPSHIP (b/128866264): Just to catch breakages. Remove before final release.
-                Slog.wtf(TAG, errorMsg);
+                mHandler.obtainMessage(AlarmHandler.UNREGISTER_CANCEL_LISTENER,
+                        operation).sendToTarget();
+                Slog.w(TAG, errorMsg);
                 throw new IllegalStateException(errorMsg);
             }
             setImplLocked(type, triggerAtTime, triggerElapsed, windowLength, maxElapsed,
@@ -1782,6 +1787,8 @@
             if (ActivityManager.getService().isAppStartModeDisabled(callingUid, callingPackage)) {
                 Slog.w(TAG, "Not setting alarm from " + callingUid + ":" + a
                         + " -- package not allowed to start");
+                mHandler.obtainMessage(AlarmHandler.UNREGISTER_CANCEL_LISTENER,
+                        operation).sendToTarget();
                 return;
             }
         } catch (RemoteException e) {
@@ -2136,10 +2143,11 @@
                 Slog.w(TAG, "remove() with no intent or listener");
                 return;
             }
-
             synchronized (mLock) {
                 removeLocked(operation, listener);
             }
+            mHandler.obtainMessage(AlarmHandler.UNREGISTER_CANCEL_LISTENER,
+                    operation).sendToTarget();
         }
 
         @Override
@@ -4179,6 +4187,7 @@
         public static final int APP_STANDBY_BUCKET_CHANGED = 5;
         public static final int APP_STANDBY_PAROLE_CHANGED = 6;
         public static final int REMOVE_FOR_STOPPED = 7;
+        public static final int UNREGISTER_CANCEL_LISTENER = 8;
 
         AlarmHandler() {
             super(Looper.myLooper());
@@ -4261,6 +4270,13 @@
                     }
                     break;
 
+                case UNREGISTER_CANCEL_LISTENER:
+                    final PendingIntent pi = (PendingIntent) msg.obj;
+                    if (pi != null) {
+                        pi.unregisterCancelListener(mOperationCancelListener);
+                    }
+                    break;
+
                 default:
                     // nope, just ignore it
                     break;
@@ -4716,6 +4732,11 @@
                                         Intent.EXTRA_ALARM_COUNT, alarm.count),
                                 mDeliveryTracker, mHandler, null,
                                 allowWhileIdle ? mIdleOptions : null);
+                        if (alarm.repeatInterval == 0) {
+                            // Keep the listener for repeating alarms until they get cancelled
+                            mHandler.obtainMessage(AlarmHandler.UNREGISTER_CANCEL_LISTENER,
+                                    alarm.operation).sendToTarget();
+                        }
                     } catch (PendingIntent.CanceledException e) {
                         if (alarm.repeatInterval > 0) {
                             // This IntentSender is no longer valid, but this
diff --git a/services/core/java/com/android/server/ConnectivityService.java b/services/core/java/com/android/server/ConnectivityService.java
index d6b4043..1cca0b9 100644
--- a/services/core/java/com/android/server/ConnectivityService.java
+++ b/services/core/java/com/android/server/ConnectivityService.java
@@ -2577,11 +2577,11 @@
                     break;
                 }
                 case NetworkAgent.EVENT_SET_EXPLICITLY_SELECTED: {
-                    if (nai.everConnected && !nai.networkMisc.explicitlySelected) {
-                        loge("ERROR: already-connected network explicitly selected.");
+                    if (nai.everConnected) {
+                        loge("ERROR: cannot call explicitlySelected on already-connected network");
                     }
-                    nai.networkMisc.explicitlySelected = true;
-                    nai.networkMisc.acceptUnvalidated = msg.arg1 == 1;
+                    nai.networkMisc.explicitlySelected = (msg.arg1 == 1);
+                    nai.networkMisc.acceptUnvalidated = (msg.arg1 == 1) && (msg.arg2 == 1);
                     // Mark the network as temporarily accepting partial connectivity so that it
                     // will be validated (and possibly become default) even if it only provides
                     // partial internet access. Note that if user connects to partial connectivity
@@ -2589,7 +2589,7 @@
                     // out of wifi coverage) and if the same wifi is available again, the device
                     // will auto connect to this wifi even though the wifi has "no internet".
                     // TODO: Evaluate using a separate setting in IpMemoryStore.
-                    nai.networkMisc.acceptPartialConnectivity = msg.arg1 == 1;
+                    nai.networkMisc.acceptPartialConnectivity = (msg.arg2 == 1);
                     break;
                 }
                 case NetworkAgent.EVENT_SOCKET_KEEPALIVE: {
@@ -2663,6 +2663,17 @@
                             NetworkAgent.CMD_REPORT_NETWORK_STATUS,
                             (valid ? NetworkAgent.VALID_NETWORK : NetworkAgent.INVALID_NETWORK),
                             0, redirectUrlBundle);
+
+                    // If NetworkMonitor detects partial connectivity before
+                    // EVENT_PROMPT_UNVALIDATED arrives, show the partial connectivity notification
+                    // immediately. Re-notify partial connectivity silently if no internet
+                    // notification already there.
+                    if (!wasPartial && nai.partialConnectivity) {
+                        // Remove delayed message if there is a pending message.
+                        mHandler.removeMessages(EVENT_PROMPT_UNVALIDATED, nai.network);
+                        handlePromptUnvalidated(nai.network);
+                    }
+
                     if (wasValidated && !nai.lastValidated) {
                         handleNetworkUnvalidated(nai);
                     }
@@ -3588,21 +3599,31 @@
 
     private void showNetworkNotification(NetworkAgentInfo nai, NotificationType type) {
         final String action;
+        final boolean highPriority;
         switch (type) {
             case LOGGED_IN:
                 action = Settings.ACTION_WIFI_SETTINGS;
                 mHandler.removeMessages(EVENT_TIMEOUT_NOTIFICATION);
                 mHandler.sendMessageDelayed(mHandler.obtainMessage(EVENT_TIMEOUT_NOTIFICATION,
                         nai.network.netId, 0), TIMEOUT_NOTIFICATION_DELAY_MS);
+                // High priority because it is a direct result of the user logging in to a portal.
+                highPriority = true;
                 break;
             case NO_INTERNET:
                 action = ConnectivityManager.ACTION_PROMPT_UNVALIDATED;
+                // High priority because it is only displayed for explicitly selected networks.
+                highPriority = true;
                 break;
             case LOST_INTERNET:
                 action = ConnectivityManager.ACTION_PROMPT_LOST_VALIDATION;
+                // High priority because it could help the user avoid unexpected data usage.
+                highPriority = true;
                 break;
             case PARTIAL_CONNECTIVITY:
                 action = ConnectivityManager.ACTION_PROMPT_PARTIAL_CONNECTIVITY;
+                // Don't bother the user with a high-priority notification if the network was not
+                // explicitly selected by the user.
+                highPriority = nai.networkMisc.explicitlySelected;
                 break;
             default:
                 Slog.wtf(TAG, "Unknown notification type " + type);
@@ -3619,25 +3640,50 @@
 
         PendingIntent pendingIntent = PendingIntent.getActivityAsUser(
                 mContext, 0, intent, PendingIntent.FLAG_CANCEL_CURRENT, null, UserHandle.CURRENT);
-        mNotifier.showNotification(nai.network.netId, type, nai, null, pendingIntent, true);
+
+        mNotifier.showNotification(nai.network.netId, type, nai, null, pendingIntent, highPriority);
+    }
+
+    private boolean shouldPromptUnvalidated(NetworkAgentInfo nai) {
+        // Don't prompt if the network is validated, and don't prompt on captive portals
+        // because we're already prompting the user to sign in.
+        if (nai.everValidated || nai.everCaptivePortalDetected) {
+            return false;
+        }
+
+        // If a network has partial connectivity, always prompt unless the user has already accepted
+        // partial connectivity and selected don't ask again. This ensures that if the device
+        // automatically connects to a network that has partial Internet access, the user will
+        // always be able to use it, either because they've already chosen "don't ask again" or
+        // because we have prompt them.
+        if (nai.partialConnectivity && !nai.networkMisc.acceptPartialConnectivity) {
+            return true;
+        }
+
+        // If a network has no Internet access, only prompt if the network was explicitly selected
+        // and if the user has not already told us to use the network regardless of whether it
+        // validated or not.
+        if (nai.networkMisc.explicitlySelected && !nai.networkMisc.acceptUnvalidated) {
+            return true;
+        }
+
+        return false;
     }
 
     private void handlePromptUnvalidated(Network network) {
         if (VDBG || DDBG) log("handlePromptUnvalidated " + network);
         NetworkAgentInfo nai = getNetworkAgentInfoForNetwork(network);
 
-        // Only prompt if the network is unvalidated or network has partial internet connectivity
-        // and was explicitly selected by the user, and if we haven't already been told to switch
-        // to it regardless of whether it validated or not. Also don't prompt on captive portals
-        // because we're already prompting the user to sign in.
-        if (nai == null || nai.everValidated || nai.everCaptivePortalDetected
-                || !nai.networkMisc.explicitlySelected || nai.networkMisc.acceptUnvalidated
-                // TODO: Once the value of acceptPartialConnectivity is moved to IpMemoryStore,
-                // we should reevaluate how to handle acceptPartialConnectivity when network just
-                // connected.
-                || nai.networkMisc.acceptPartialConnectivity) {
+        if (nai == null || !shouldPromptUnvalidated(nai)) {
             return;
         }
+
+        // Stop automatically reconnecting to this network in the future. Automatically connecting
+        // to a network that provides no or limited connectivity is not useful, because the user
+        // cannot use that network except through the notification shown by this method, and the
+        // notification is only shown if the network is explicitly selected by the user.
+        nai.asyncChannel.sendMessage(NetworkAgent.CMD_PREVENT_AUTOMATIC_RECONNECT);
+
         // TODO: Evaluate if it's needed to wait 8 seconds for triggering notification when
         // NetworkMonitor detects the network is partial connectivity. Need to change the design to
         // popup the notification immediately when the network is partial connectivity.
@@ -4337,7 +4383,7 @@
 
     /**
      * @return VPN information for accounting, or null if we can't retrieve all required
-     *         information, e.g underlying ifaces.
+     *         information, e.g primary underlying iface.
      */
     @Nullable
     private VpnInfo createVpnInfo(Vpn vpn) {
@@ -4349,24 +4395,17 @@
         // see VpnService.setUnderlyingNetworks()'s javadoc about how to interpret
         // the underlyingNetworks list.
         if (underlyingNetworks == null) {
-            NetworkAgentInfo defaultNai = getDefaultNetwork();
-            if (defaultNai != null) {
-                underlyingNetworks = new Network[] { defaultNai.network };
+            NetworkAgentInfo defaultNetwork = getDefaultNetwork();
+            if (defaultNetwork != null && defaultNetwork.linkProperties != null) {
+                info.primaryUnderlyingIface = getDefaultNetwork().linkProperties.getInterfaceName();
+            }
+        } else if (underlyingNetworks.length > 0) {
+            LinkProperties linkProperties = getLinkProperties(underlyingNetworks[0]);
+            if (linkProperties != null) {
+                info.primaryUnderlyingIface = linkProperties.getInterfaceName();
             }
         }
-        if (underlyingNetworks != null && underlyingNetworks.length > 0) {
-            List<String> interfaces = new ArrayList<>();
-            for (Network network : underlyingNetworks) {
-                LinkProperties lp = getLinkProperties(network);
-                if (lp != null && !TextUtils.isEmpty(lp.getInterfaceName())) {
-                    interfaces.add(lp.getInterfaceName());
-                }
-            }
-            if (!interfaces.isEmpty()) {
-                info.underlyingIfaces = interfaces.toArray(new String[interfaces.size()]);
-            }
-        }
-        return info.underlyingIfaces == null ? null : info;
+        return info.primaryUnderlyingIface == null ? null : info;
     }
 
     /**
@@ -6862,8 +6901,10 @@
 
         final int userId = UserHandle.getCallingUserId();
 
-        final IpMemoryStore ipMemoryStore = IpMemoryStore.getMemoryStore(mContext);
-        ipMemoryStore.factoryReset();
+        Binder.withCleanCallingIdentity(() -> {
+            final IpMemoryStore ipMemoryStore = IpMemoryStore.getMemoryStore(mContext);
+            ipMemoryStore.factoryReset();
+        });
 
         // Turn airplane mode off
         setAirplaneMode(false);
diff --git a/services/core/java/com/android/server/LocationManagerService.java b/services/core/java/com/android/server/LocationManagerService.java
index ae04f76..8a639c5 100644
--- a/services/core/java/com/android/server/LocationManagerService.java
+++ b/services/core/java/com/android/server/LocationManagerService.java
@@ -2361,7 +2361,7 @@
                     mRealRequest,
                     mReceiver.isListener(),
                     mReceiver.isPendingIntent(),
-                    /* radius= */ 0,
+                    /* geofence= */ null,
                     mActivityManager.getPackageImportance(packageName));
 
             // remove from mRecordsByProvider
@@ -2541,7 +2541,7 @@
                         LocationStatsEnums.USAGE_STARTED,
                         LocationStatsEnums.API_REQUEST_LOCATION_UPDATES,
                         packageName, request, listener != null, intent != null,
-                        /* radius= */ 0,
+                        /* geofence= */ null,
                         mActivityManager.getPackageImportance(packageName));
 
                 Receiver receiver;
@@ -2844,7 +2844,7 @@
                         request,
                         /* hasListener= */ false,
                         intent != null,
-                        geofence.getRadius(),
+                        geofence,
                         mActivityManager.getPackageImportance(packageName));
             }
 
@@ -2876,7 +2876,7 @@
                         /* LocationRequest= */ null,
                         /* hasListener= */ false,
                         intent != null,
-                        geofence.getRadius(),
+                        geofence,
                         mActivityManager.getPackageImportance(packageName));
             }
             mGeofenceManager.removeFence(geofence, intent);
@@ -2962,18 +2962,18 @@
             gnssDataListeners.put(binder, linkedListener);
             long identity = Binder.clearCallingIdentity();
             try {
-                if (gnssDataProvider == mGnssNavigationMessageProvider
+                if (gnssDataProvider == mGnssMeasurementsProvider
                         || gnssDataProvider == mGnssStatusProvider) {
                     mLocationUsageLogger.logLocationApiUsage(
                             LocationStatsEnums.USAGE_STARTED,
-                            gnssDataProvider == mGnssNavigationMessageProvider
+                            gnssDataProvider == mGnssMeasurementsProvider
                                 ? LocationStatsEnums.API_ADD_GNSS_MEASUREMENTS_LISTENER
                                 : LocationStatsEnums.API_REGISTER_GNSS_STATUS_CALLBACK,
                             packageName,
                             /* LocationRequest= */ null,
                             /* hasListener= */ true,
                             /* hasIntent= */ false,
-                            /* radius */ 0,
+                            /* geofence= */ null,
                             mActivityManager.getPackageImportance(packageName));
                 }
                 if (isThrottlingExemptLocked(callerIdentity)
@@ -3003,18 +3003,18 @@
             }
             long identity = Binder.clearCallingIdentity();
             try {
-                if (gnssDataProvider == mGnssNavigationMessageProvider
+                if (gnssDataProvider == mGnssMeasurementsProvider
                         || gnssDataProvider == mGnssStatusProvider) {
                     mLocationUsageLogger.logLocationApiUsage(
                             LocationStatsEnums.USAGE_ENDED,
-                            gnssDataProvider == mGnssNavigationMessageProvider
+                            gnssDataProvider == mGnssMeasurementsProvider
                                 ? LocationStatsEnums.API_ADD_GNSS_MEASUREMENTS_LISTENER
                                 : LocationStatsEnums.API_REGISTER_GNSS_STATUS_CALLBACK,
                             linkedListener.mCallerIdentity.mPackageName,
                             /* LocationRequest= */ null,
                             /* hasListener= */ true,
                             /* hasIntent= */ false,
-                            /* radius= */ 0,
+                            /* geofence= */ null,
                             mActivityManager.getPackageImportance(
                                     linkedListener.mCallerIdentity.mPackageName));
                 }
diff --git a/services/core/java/com/android/server/LocationUsageLogger.java b/services/core/java/com/android/server/LocationUsageLogger.java
index c503035..4ca74bf 100644
--- a/services/core/java/com/android/server/LocationUsageLogger.java
+++ b/services/core/java/com/android/server/LocationUsageLogger.java
@@ -17,6 +17,7 @@
 package com.android.server;
 
 import android.app.ActivityManager;
+import android.location.Geofence;
 import android.location.LocationManager;
 import android.location.LocationRequest;
 import android.os.SystemClock;
@@ -180,13 +181,14 @@
     public void logLocationApiUsage(int usageType, int apiInUse,
             String packageName, LocationRequest locationRequest,
             boolean hasListener, boolean hasIntent,
-            float radius, int activityImportance) {
+            Geofence geofence, int activityImportance) {
         try {
             if (!checkApiUsageLogCap()) {
                 return;
             }
 
             boolean isLocationRequestNull = locationRequest == null;
+            boolean isGeofenceNull = geofence == null;
             if (D) {
                 Log.d(TAG, "log API Usage to statsd. usageType: " + usageType + ", apiInUse: "
                         + apiInUse + ", packageName: " + (packageName == null ? "" : packageName)
@@ -194,7 +196,8 @@
                         + (isLocationRequestNull ? "" : locationRequest.toString())
                         + ", hasListener: " + hasListener
                         + ", hasIntent: " + hasIntent
-                        + ", radius: " + radius
+                        + ", geofence: "
+                        + (isGeofenceNull ? "" : geofence.toString())
                         + ", importance: " + activityImportance);
             }
 
@@ -219,7 +222,9 @@
                         ? LocationStatsEnums.EXPIRATION_UNKNOWN
                         : getBucketizedExpireIn(locationRequest.getExpireAt()),
                     getCallbackType(apiInUse, hasListener, hasIntent),
-                    bucketizeRadiusToStatsdEnum(radius),
+                    isGeofenceNull
+                        ? LocationStatsEnums.RADIUS_UNKNOWN
+                        : bucketizeRadiusToStatsdEnum(geofence.getRadius()),
                     categorizeActivityImportance(activityImportance));
         } catch (Exception e) {
             // Swallow exceptions to avoid crashing LMS.
diff --git a/services/core/java/com/android/server/StorageManagerService.java b/services/core/java/com/android/server/StorageManagerService.java
index d2b992b..deff7ef 100644
--- a/services/core/java/com/android/server/StorageManagerService.java
+++ b/services/core/java/com/android/server/StorageManagerService.java
@@ -580,6 +580,7 @@
     private static final int H_RUN_IDLE_MAINT = 11;
     private static final int H_ABORT_IDLE_MAINT = 12;
     private static final int H_BOOT_COMPLETED = 13;
+    private static final int H_COMPLETE_UNLOCK_USER = 14;
 
     class StorageManagerServiceHandler extends Handler {
         public StorageManagerServiceHandler(Looper looper) {
@@ -698,7 +699,10 @@
                     abortIdleMaint((Runnable)msg.obj);
                     break;
                 }
-
+                case H_COMPLETE_UNLOCK_USER: {
+                    completeUnlockUser((int) msg.obj);
+                    break;
+                }
             }
         }
     }
@@ -978,6 +982,17 @@
             Slog.wtf(TAG, e);
         }
 
+        mHandler.obtainMessage(H_COMPLETE_UNLOCK_USER, userId).sendToTarget();
+    }
+
+    private void completeUnlockUser(int userId) {
+        // If user 0 has completed unlock, perform a one-time migration of legacy obb data
+        // to its new location. This may take time depending on the size of the data to be copied
+        // so it's done on the StorageManager handler thread.
+        if (userId == 0) {
+            mPmInternal.migrateLegacyObbData();
+        }
+
         // Record user as started so newly mounted volumes kick off events
         // correctly, then synthesize events for any already-mounted volumes.
         synchronized (mLock) {
@@ -2820,6 +2835,12 @@
         }
     }
 
+    private boolean isSystemUnlocked(int userId) {
+        synchronized (mLock) {
+            return ArrayUtils.contains(mSystemUnlockedUsers, userId);
+        }
+    }
+
     @Override
     public void prepareUserStorage(String volumeUuid, int userId, int serialNumber, int flags) {
         enforcePermission(android.Manifest.permission.STORAGE_INTERNAL);
@@ -2996,6 +3017,11 @@
         final boolean realState = (flags & StorageManager.FLAG_REAL_STATE) != 0;
         final boolean includeInvisible = (flags & StorageManager.FLAG_INCLUDE_INVISIBLE) != 0;
 
+        // Report all volumes as unmounted until we've recorded that user 0 has unlocked. There
+        // are no guarantees that callers will see a consistent view of the volume before that
+        // point
+        final boolean systemUserUnlocked = isSystemUnlocked(UserHandle.USER_SYSTEM);
+
         final boolean userKeyUnlocked;
         final boolean storagePermission;
         final long token = Binder.clearCallingIdentity();
@@ -3031,7 +3057,9 @@
                 if (!match) continue;
 
                 boolean reportUnmounted = false;
-                if ((vol.getType() == VolumeInfo.TYPE_EMULATED) && !userKeyUnlocked) {
+                if (!systemUserUnlocked) {
+                    reportUnmounted = true;
+                } else if ((vol.getType() == VolumeInfo.TYPE_EMULATED) && !userKeyUnlocked) {
                     reportUnmounted = true;
                 } else if (!storagePermission && !realState) {
                     reportUnmounted = true;
diff --git a/services/core/java/com/android/server/VibratorService.java b/services/core/java/com/android/server/VibratorService.java
index 7a947f1..6eb9f0c 100644
--- a/services/core/java/com/android/server/VibratorService.java
+++ b/services/core/java/com/android/server/VibratorService.java
@@ -116,6 +116,7 @@
     private final LinkedList<VibrationInfo> mPreviousRingVibrations;
     private final LinkedList<VibrationInfo> mPreviousNotificationVibrations;
     private final LinkedList<VibrationInfo> mPreviousAlarmVibrations;
+    private final LinkedList<ExternalVibration> mPreviousExternalVibrations;
     private final LinkedList<VibrationInfo> mPreviousVibrations;
     private final int mPreviousVibrationsLimit;
     private final boolean mAllowPriorityVibrationsInLowPowerMode;
@@ -368,6 +369,7 @@
         mPreviousNotificationVibrations = new LinkedList<>();
         mPreviousAlarmVibrations = new LinkedList<>();
         mPreviousVibrations = new LinkedList<>();
+        mPreviousExternalVibrations = new LinkedList<>();
 
         IntentFilter filter = new IntentFilter();
         filter.addAction(Intent.ACTION_SCREEN_OFF);
@@ -618,7 +620,6 @@
                 linkVibration(vib);
                 long ident = Binder.clearCallingIdentity();
                 try {
-
                     doCancelVibrateLocked();
                     startVibrationLocked(vib);
                     addToPreviousVibrationsLocked(vib);
@@ -1418,6 +1419,12 @@
                 pw.print("    ");
                 pw.println(info.toString());
             }
+
+            pw.println("  Previous external vibrations:");
+            for (ExternalVibration vib : mPreviousExternalVibrations) {
+                pw.print("    ");
+                pw.println(vib.toString());
+            }
         }
     }
 
@@ -1429,6 +1436,8 @@
     }
 
     final class ExternalVibratorService extends IExternalVibratorService.Stub {
+        ExternalVibrationDeathRecipient mCurrentExternalDeathRecipient;
+
         @Override
         public int onExternalVibrationStart(ExternalVibration vib) {
             if (!mSupportsExternalControl) {
@@ -1462,6 +1471,12 @@
                     // Note that this doesn't support multiple concurrent external controls, as we
                     // would need to mute the old one still if it came from a different controller.
                     mCurrentExternalVibration = vib;
+                    mCurrentExternalDeathRecipient = new ExternalVibrationDeathRecipient();
+                    mCurrentExternalVibration.linkToDeath(mCurrentExternalDeathRecipient);
+                    if (mPreviousExternalVibrations.size() > mPreviousVibrationsLimit) {
+                        mPreviousExternalVibrations.removeFirst();
+                    }
+                    mPreviousExternalVibrations.addLast(vib);
                     if (DEBUG) {
                         Slog.e(TAG, "Playing external vibration: " + vib);
                     }
@@ -1502,6 +1517,8 @@
         public void onExternalVibrationStop(ExternalVibration vib) {
             synchronized (mLock) {
                 if (vib.equals(mCurrentExternalVibration)) {
+                    mCurrentExternalVibration.unlinkToDeath(mCurrentExternalDeathRecipient);
+                    mCurrentExternalDeathRecipient = null;
                     mCurrentExternalVibration = null;
                     setVibratorUnderExternalControl(false);
                     if (DEBUG) {
@@ -1510,6 +1527,14 @@
                 }
             }
         }
+
+        private class ExternalVibrationDeathRecipient implements IBinder.DeathRecipient {
+            public void binderDied() {
+                synchronized (mLock) {
+                    onExternalVibrationStop(mCurrentExternalVibration);
+                }
+            }
+        }
     }
 
     private final class VibratorShellCommand extends ShellCommand {
diff --git a/services/core/java/com/android/server/Watchdog.java b/services/core/java/com/android/server/Watchdog.java
index e097d85..4e416a2 100644
--- a/services/core/java/com/android/server/Watchdog.java
+++ b/services/core/java/com/android/server/Watchdog.java
@@ -63,7 +63,7 @@
     static final String TAG = "Watchdog";
 
     /** Debug flag. */
-    public static final boolean DEBUG = true; // STOPSHIP disable it (b/113252928)
+    public static final boolean DEBUG = false;
 
     // Set this to true to use debug default values.
     static final boolean DB = false;
@@ -570,7 +570,7 @@
                         continue;
                     } else if (waitState == WAITED_HALF) {
                         if (!waitedHalf) {
-                            if (DEBUG) Slog.d(TAG, "WAITED_HALF");
+                            Slog.i(TAG, "WAITED_HALF");
                             // We've waited half the deadlock-detection interval.  Pull a stack
                             // trace and wait another half.
                             ArrayList<Integer> pids = new ArrayList<Integer>();
diff --git a/services/core/java/com/android/server/am/ActiveServices.java b/services/core/java/com/android/server/am/ActiveServices.java
index fae853c..7bc2e6d 100644
--- a/services/core/java/com/android/server/am/ActiveServices.java
+++ b/services/core/java/com/android/server/am/ActiveServices.java
@@ -1946,8 +1946,6 @@
                                 r.binding.service.app.hasClientActivities()
                                 || r.binding.service.app.treatLikeActivity, null);
                     }
-                    mAm.updateOomAdjLocked(r.binding.service.app, false,
-                            OomAdjuster.OOM_ADJ_REASON_UNBIND_SERVICE);
                 }
             }
 
@@ -2906,15 +2904,15 @@
 
         // Tell the service that it has been unbound.
         if (r.app != null && r.app.thread != null) {
-            for (int i=r.bindings.size()-1; i>=0; i--) {
+            boolean needOomAdj = false;
+            for (int i = r.bindings.size() - 1; i >= 0; i--) {
                 IntentBindRecord ibr = r.bindings.valueAt(i);
                 if (DEBUG_SERVICE) Slog.v(TAG_SERVICE, "Bringing down binding " + ibr
                         + ": hasBound=" + ibr.hasBound);
                 if (ibr.hasBound) {
                     try {
                         bumpServiceExecutingLocked(r, false, "bring down unbind");
-                        mAm.updateOomAdjLocked(r.app, true,
-                                OomAdjuster.OOM_ADJ_REASON_UNBIND_SERVICE);
+                        needOomAdj = true;
                         ibr.hasBound = false;
                         ibr.requested = false;
                         r.app.thread.scheduleUnbindService(r,
@@ -2926,6 +2924,10 @@
                     }
                 }
             }
+            if (needOomAdj) {
+                mAm.updateOomAdjLocked(r.app, true,
+                        OomAdjuster.OOM_ADJ_REASON_UNBIND_SERVICE);
+            }
         }
 
         // Check to see if the service had been started as foreground, but being
diff --git a/services/core/java/com/android/server/am/ActivityManagerConstants.java b/services/core/java/com/android/server/am/ActivityManagerConstants.java
index 104cadc..7fea5fc 100644
--- a/services/core/java/com/android/server/am/ActivityManagerConstants.java
+++ b/services/core/java/com/android/server/am/ActivityManagerConstants.java
@@ -30,8 +30,6 @@
 import android.provider.DeviceConfig.Properties;
 import android.provider.Settings;
 import android.text.TextUtils;
-import android.text.TextUtils.SimpleStringSplitter;
-import android.util.ArraySet;
 import android.util.KeyValueListParser;
 import android.util.Slog;
 
@@ -125,13 +123,6 @@
     private static final String KEY_DEFAULT_BACKGROUND_ACTIVITY_STARTS_ENABLED =
             "default_background_activity_starts_enabled";
 
-    /**
-     * The packages temporarily whitelisted to be able to start activities from background.
-     * The list of packages is {@code ":"} colon delimited.
-     */
-    private static final String KEY_BACKGROUND_ACTIVITY_STARTS_PACKAGE_NAMES_WHITELIST =
-            "background_activity_starts_package_names_whitelist";
-
 
     // Maximum number of cached processes we will allow.
     public int MAX_CACHED_PROCESSES = DEFAULT_MAX_CACHED_PROCESSES;
@@ -263,8 +254,6 @@
     // If not set explicitly the default is controlled by DeviceConfig.
     volatile boolean mFlagBackgroundActivityStartsEnabled;
 
-    volatile ArraySet<String> mPackageNamesWhitelistedForBgActivityStarts = new ArraySet<>();
-
     private final ActivityManagerService mService;
     private ContentResolver mResolver;
     private final KeyValueListParser mParser = new KeyValueListParser(',');
@@ -309,10 +298,6 @@
     private static final Uri ACTIVITY_STARTS_LOGGING_ENABLED_URI = Settings.Global.getUriFor(
                 Settings.Global.ACTIVITY_STARTS_LOGGING_ENABLED);
 
-    private static final Uri BACKGROUND_ACTIVITY_STARTS_ENABLED_URI =
-                Settings.Global.getUriFor(
-                        Settings.Global.BACKGROUND_ACTIVITY_STARTS_ENABLED);
-
     private static final Uri ENABLE_AUTOMATIC_SYSTEM_SERVER_HEAP_DUMPS_URI =
             Settings.Global.getUriFor(Settings.Global.ENABLE_AUTOMATIC_SYSTEM_SERVER_HEAP_DUMPS);
 
@@ -329,7 +314,6 @@
                                 updateMaxCachedProcesses();
                                 break;
                             case KEY_DEFAULT_BACKGROUND_ACTIVITY_STARTS_ENABLED:
-                            case KEY_BACKGROUND_ACTIVITY_STARTS_PACKAGE_NAMES_WHITELIST:
                                 updateBackgroundActivityStarts();
                                 break;
                             default:
@@ -356,7 +340,6 @@
         mResolver = resolver;
         mResolver.registerContentObserver(ACTIVITY_MANAGER_CONSTANTS_URI, false, this);
         mResolver.registerContentObserver(ACTIVITY_STARTS_LOGGING_ENABLED_URI, false, this);
-        mResolver.registerContentObserver(BACKGROUND_ACTIVITY_STARTS_ENABLED_URI, false, this);
         if (mSystemServerAutomaticHeapDumpEnabled) {
             mResolver.registerContentObserver(ENABLE_AUTOMATIC_SYSTEM_SERVER_HEAP_DUMPS_URI,
                     false, this);
@@ -393,8 +376,6 @@
             updateConstants();
         } else if (ACTIVITY_STARTS_LOGGING_ENABLED_URI.equals(uri)) {
             updateActivityStartsLoggingEnabled();
-        } else if (BACKGROUND_ACTIVITY_STARTS_ENABLED_URI.equals(uri)) {
-            updateBackgroundActivityStarts();
         } else if (ENABLE_AUTOMATIC_SYSTEM_SERVER_HEAP_DUMPS_URI.equals(uri)) {
             updateEnableAutomaticSystemServerHeapDumps();
         }
@@ -485,39 +466,10 @@
     }
 
     private void updateBackgroundActivityStarts() {
-        String whitelistedPackageNames = null;
-        int settingsValue = Settings.Global.getInt(mResolver,
-                Settings.Global.BACKGROUND_ACTIVITY_STARTS_ENABLED, -1);
-
-        // If the user has explicitly enabled or disabled, that affects all apps.
-        // Otherwise we take the default state and whitelist from DeviceConfig.
-        if (settingsValue >= 0) {
-            mFlagBackgroundActivityStartsEnabled = settingsValue != 0;
-        } else {
-            boolean enabledInDeviceConfig = DeviceConfig.getBoolean(
-                    DeviceConfig.NAMESPACE_ACTIVITY_MANAGER,
-                    KEY_DEFAULT_BACKGROUND_ACTIVITY_STARTS_ENABLED,
-                    /*defaultValue*/ false);
-            mFlagBackgroundActivityStartsEnabled = enabledInDeviceConfig;
-            if (!enabledInDeviceConfig) {
-                whitelistedPackageNames = DeviceConfig.getProperty(
-                        DeviceConfig.NAMESPACE_ACTIVITY_MANAGER,
-                        KEY_BACKGROUND_ACTIVITY_STARTS_PACKAGE_NAMES_WHITELIST);
-            }
-        }
-        if (TextUtils.isEmpty(whitelistedPackageNames)) {
-            if (!mPackageNamesWhitelistedForBgActivityStarts.isEmpty()) {
-                mPackageNamesWhitelistedForBgActivityStarts = new ArraySet<>();
-            }
-        } else {
-            ArraySet<String> newSet = new ArraySet<>();
-            SimpleStringSplitter splitter = new SimpleStringSplitter(':');
-            splitter.setString(whitelistedPackageNames);
-            while (splitter.hasNext()) {
-                newSet.add(splitter.next());
-            }
-            mPackageNamesWhitelistedForBgActivityStarts = newSet;
-        }
+        mFlagBackgroundActivityStartsEnabled = DeviceConfig.getBoolean(
+                DeviceConfig.NAMESPACE_ACTIVITY_MANAGER,
+                KEY_DEFAULT_BACKGROUND_ACTIVITY_STARTS_ENABLED,
+                /*defaultValue*/ false);
     }
 
     private void updateEnableAutomaticSystemServerHeapDumps() {
diff --git a/services/core/java/com/android/server/am/ActivityManagerService.java b/services/core/java/com/android/server/am/ActivityManagerService.java
index 2321031..627ca91 100644
--- a/services/core/java/com/android/server/am/ActivityManagerService.java
+++ b/services/core/java/com/android/server/am/ActivityManagerService.java
@@ -547,6 +547,7 @@
     private static final int MAX_BUGREPORT_TITLE_SIZE = 50;
 
     private static final int NATIVE_DUMP_TIMEOUT_MS = 2000; // 2 seconds;
+    private static final int JAVA_DUMP_MINIMUM_SIZE = 100; // 100 bytes.
 
     OomAdjuster mOomAdjuster;
     final LowMemDetector mLowMemDetector;
@@ -3805,9 +3806,28 @@
      */
     private static long dumpJavaTracesTombstoned(int pid, String fileName, long timeoutMs) {
         final long timeStart = SystemClock.elapsedRealtime();
-        if (!Debug.dumpJavaBacktraceToFileTimeout(pid, fileName, (int) (timeoutMs / 1000))) {
-            Debug.dumpNativeBacktraceToFileTimeout(pid, fileName,
-                    (NATIVE_DUMP_TIMEOUT_MS / 1000));
+        boolean javaSuccess = Debug.dumpJavaBacktraceToFileTimeout(pid, fileName,
+                (int) (timeoutMs / 1000));
+        if (javaSuccess) {
+            // Check that something is in the file, actually. Try-catch should not be necessary,
+            // but better safe than sorry.
+            try {
+                long size = new File(fileName).length();
+                if (size < JAVA_DUMP_MINIMUM_SIZE) {
+                    Slog.w(TAG, "Successfully created Java ANR file is empty!");
+                    javaSuccess = false;
+                }
+            } catch (Exception e) {
+                Slog.w(TAG, "Unable to get ANR file size", e);
+                javaSuccess = false;
+            }
+        }
+        if (!javaSuccess) {
+            Slog.w(TAG, "Dumping Java threads failed, initiating native stack dump.");
+            if (!Debug.dumpNativeBacktraceToFileTimeout(pid, fileName,
+                    (NATIVE_DUMP_TIMEOUT_MS / 1000))) {
+                Slog.w(TAG, "Native stack dump failed!");
+            }
         }
 
         return SystemClock.elapsedRealtime() - timeStart;
@@ -5375,34 +5395,13 @@
 
     @Override
     public void registerIntentSenderCancelListener(IIntentSender sender, IResultReceiver receiver) {
-        if (!(sender instanceof PendingIntentRecord)) {
-            return;
-        }
-        boolean isCancelled;
-        synchronized(this) {
-            PendingIntentRecord pendingIntent = (PendingIntentRecord) sender;
-            isCancelled = pendingIntent.canceled;
-            if (!isCancelled) {
-                pendingIntent.registerCancelListenerLocked(receiver);
-            }
-        }
-        if (isCancelled) {
-            try {
-                receiver.send(Activity.RESULT_CANCELED, null);
-            } catch (RemoteException e) {
-            }
-        }
+        mPendingIntentController.registerIntentSenderCancelListener(sender, receiver);
     }
 
     @Override
     public void unregisterIntentSenderCancelListener(IIntentSender sender,
             IResultReceiver receiver) {
-        if (!(sender instanceof PendingIntentRecord)) {
-            return;
-        }
-        synchronized(this) {
-            ((PendingIntentRecord)sender).unregisterCancelListenerLocked(receiver);
-        }
+        mPendingIntentController.unregisterIntentSenderCancelListener(sender, receiver);
     }
 
     @Override
@@ -7300,6 +7299,13 @@
                     if (wasInLaunchingProviders) {
                         mHandler.removeMessages(CONTENT_PROVIDER_PUBLISH_TIMEOUT_MSG, r);
                     }
+                    // Make sure the package is associated with the process.
+                    // XXX We shouldn't need to do this, since we have added the package
+                    // when we generated the providers in generateApplicationProvidersLocked().
+                    // But for some reason in some cases we get here with the package no longer
+                    // added...  for now just patch it in to make things happy.
+                    r.addPackage(dst.info.applicationInfo.packageName,
+                            dst.info.applicationInfo.longVersionCode, mProcessStats);
                     synchronized (dst) {
                         dst.provider = src.provider;
                         dst.setProcess(r);
@@ -17679,13 +17685,8 @@
         @Override
         public void setPendingIntentWhitelistDuration(IIntentSender target, IBinder whitelistToken,
                 long duration) {
-            if (!(target instanceof PendingIntentRecord)) {
-                Slog.w(TAG, "markAsSentFromNotification(): not a PendingIntentRecord: " + target);
-                return;
-            }
-            synchronized (ActivityManagerService.this) {
-                ((PendingIntentRecord) target).setWhitelistDurationLocked(whitelistToken, duration);
-            }
+            mPendingIntentController.setPendingIntentWhitelistDuration(target, whitelistToken,
+                    duration);
         }
 
         @Override
@@ -18201,10 +18202,6 @@
             return mConstants.mFlagActivityStartsLoggingEnabled;
         }
 
-        public boolean isPackageNameWhitelistedForBgActivityStarts(String packageName) {
-            return mConstants.mPackageNamesWhitelistedForBgActivityStarts.contains(packageName);
-        }
-
         public boolean isBackgroundActivityStartsEnabled() {
             return mConstants.mFlagBackgroundActivityStartsEnabled;
         }
diff --git a/services/core/java/com/android/server/am/BroadcastDispatcher.java b/services/core/java/com/android/server/am/BroadcastDispatcher.java
index d029482..f8a3d1e 100644
--- a/services/core/java/com/android/server/am/BroadcastDispatcher.java
+++ b/services/core/java/com/android/server/am/BroadcastDispatcher.java
@@ -725,6 +725,14 @@
         final Dumper dumper = new Dumper(pw, queueName, dumpPackage, sdf);
         boolean printed = false;
 
+        dumper.setHeading("Currently in flight");
+        dumper.setLabel("In-Flight Ordered Broadcast");
+        if (mCurrentBroadcast != null) {
+            dumper.dump(mCurrentBroadcast);
+        } else {
+            pw.println("  (null)");
+        }
+
         dumper.setHeading("Active ordered broadcasts");
         dumper.setLabel("Active Ordered Broadcast");
         for (Deferrals d : mAlarmBroadcasts) {
diff --git a/services/core/java/com/android/server/am/CoreSettingsObserver.java b/services/core/java/com/android/server/am/CoreSettingsObserver.java
index b053d84..aa8bc04 100644
--- a/services/core/java/com/android/server/am/CoreSettingsObserver.java
+++ b/services/core/java/com/android/server/am/CoreSettingsObserver.java
@@ -76,6 +76,8 @@
         sGlobalSettingToTypeMap.put(Settings.Global.GPU_DEBUG_LAYER_APP, String.class);
         sGlobalSettingToTypeMap.put(Settings.Global.GAME_DRIVER_ALL_APPS, int.class);
         sGlobalSettingToTypeMap.put(Settings.Global.GAME_DRIVER_OPT_IN_APPS, String.class);
+        sGlobalSettingToTypeMap.put(
+                Settings.Global.GAME_DRIVER_PRERELEASE_OPT_IN_APPS, String.class);
         sGlobalSettingToTypeMap.put(Settings.Global.GAME_DRIVER_OPT_OUT_APPS, String.class);
         sGlobalSettingToTypeMap.put(Settings.Global.GAME_DRIVER_BLACKLIST, String.class);
         sGlobalSettingToTypeMap.put(Settings.Global.GAME_DRIVER_WHITELIST, String.class);
diff --git a/services/core/java/com/android/server/am/PendingIntentController.java b/services/core/java/com/android/server/am/PendingIntentController.java
index a5d4738..d75591c 100644
--- a/services/core/java/com/android/server/am/PendingIntentController.java
+++ b/services/core/java/com/android/server/am/PendingIntentController.java
@@ -17,6 +17,7 @@
 package com.android.server.am;
 
 import static android.content.pm.PackageManager.MATCH_DEBUG_TRIAGED_MISSING;
+
 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_MU;
 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_MU;
 import static com.android.server.am.ActivityManagerDebugConfig.TAG_AM;
@@ -39,6 +40,7 @@
 import android.os.UserHandle;
 import android.util.ArrayMap;
 import android.util.Slog;
+
 import com.android.internal.os.IResultReceiver;
 import com.android.internal.util.function.pooled.PooledLambda;
 import com.android.server.LocalServices;
@@ -242,6 +244,47 @@
         }
     }
 
+    void registerIntentSenderCancelListener(IIntentSender sender, IResultReceiver receiver) {
+        if (!(sender instanceof PendingIntentRecord)) {
+            return;
+        }
+        boolean isCancelled;
+        synchronized (mLock) {
+            PendingIntentRecord pendingIntent = (PendingIntentRecord) sender;
+            isCancelled = pendingIntent.canceled;
+            if (!isCancelled) {
+                pendingIntent.registerCancelListenerLocked(receiver);
+            }
+        }
+        if (isCancelled) {
+            try {
+                receiver.send(Activity.RESULT_CANCELED, null);
+            } catch (RemoteException e) {
+            }
+        }
+    }
+
+    void unregisterIntentSenderCancelListener(IIntentSender sender,
+            IResultReceiver receiver) {
+        if (!(sender instanceof PendingIntentRecord)) {
+            return;
+        }
+        synchronized (mLock) {
+            ((PendingIntentRecord) sender).unregisterCancelListenerLocked(receiver);
+        }
+    }
+
+    void setPendingIntentWhitelistDuration(IIntentSender target, IBinder whitelistToken,
+            long duration) {
+        if (!(target instanceof PendingIntentRecord)) {
+            Slog.w(TAG, "markAsSentFromNotification(): not a PendingIntentRecord: " + target);
+            return;
+        }
+        synchronized (mLock) {
+            ((PendingIntentRecord) target).setWhitelistDurationLocked(whitelistToken, duration);
+        }
+    }
+
     private void makeIntentSenderCanceled(PendingIntentRecord rec) {
         rec.canceled = true;
         final RemoteCallbackList<IResultReceiver> callbacks = rec.detachCancelListenersLocked();
diff --git a/services/core/java/com/android/server/am/ProcessList.java b/services/core/java/com/android/server/am/ProcessList.java
index 943fe75..d64a2c2 100644
--- a/services/core/java/com/android/server/am/ProcessList.java
+++ b/services/core/java/com/android/server/am/ProcessList.java
@@ -63,7 +63,6 @@
 import android.os.Binder;
 import android.os.Build;
 import android.os.Bundle;
-import android.os.GraphicsEnvironment;
 import android.os.Handler;
 import android.os.IBinder;
 import android.os.Looper;
@@ -705,16 +704,6 @@
         return prefix + "+" + Integer.toString(diff);
     }
 
-    private static boolean shouldUseSystemGraphicsDriver(Context context, Bundle coreSettings,
-            ApplicationInfo applicationInfo) {
-        final boolean shouldUseGameDriver =
-                GraphicsEnvironment.shouldUseGameDriver(context, coreSettings, applicationInfo);
-        final boolean shouldUseAngle =
-                GraphicsEnvironment.shouldUseAngle(context, coreSettings,
-                    applicationInfo.packageName);
-        return !shouldUseGameDriver && !shouldUseAngle;
-    }
-
     public static String makeOomAdjString(int setAdj, boolean compact) {
         if (setAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
             return buildOomTag("cch", "cch", "   ", setAdj,
@@ -1811,8 +1800,6 @@
             String seInfo, String requiredAbi, String instructionSet, String invokeWith,
             long startTime) {
         try {
-            final boolean useSystemGraphicsDriver = shouldUseSystemGraphicsDriver(mService.mContext,
-                    mService.mCoreSettingsObserver.getCoreSettingsLocked(), app.info);
             Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "Start proc: " +
                     app.processName);
             checkSlow(startTime, "startProcess: asking zygote to start proc");
@@ -1822,7 +1809,6 @@
                         app.processName, uid, uid, gids, runtimeFlags, mountExternal,
                         app.info.targetSdkVersion, seInfo, requiredAbi, instructionSet,
                         app.info.dataDir, null, app.info.packageName,
-                        useSystemGraphicsDriver,
                         new String[] {PROC_START_SEQ_IDENT + app.startSeq});
             } else if (hostingRecord.usesAppZygote()) {
                 final AppZygote appZygote = createAppZygoteForProcessIfNeeded(app);
@@ -1831,14 +1817,13 @@
                         app.processName, uid, uid, gids, runtimeFlags, mountExternal,
                         app.info.targetSdkVersion, seInfo, requiredAbi, instructionSet,
                         app.info.dataDir, null, app.info.packageName,
-                        /*useUsapPool=*/ false, useSystemGraphicsDriver,
+                        /*useUsapPool=*/ false,
                         new String[] {PROC_START_SEQ_IDENT + app.startSeq});
             } else {
                 startResult = Process.start(entryPoint,
                         app.processName, uid, uid, gids, runtimeFlags, mountExternal,
                         app.info.targetSdkVersion, seInfo, requiredAbi, instructionSet,
                         app.info.dataDir, invokeWith, app.info.packageName,
-                        useSystemGraphicsDriver,
                         new String[] {PROC_START_SEQ_IDENT + app.startSeq});
             }
             checkSlow(startTime, "startProcess: returned from zygote!");
diff --git a/services/core/java/com/android/server/am/UserController.java b/services/core/java/com/android/server/am/UserController.java
index 2399d05..b311233 100644
--- a/services/core/java/com/android/server/am/UserController.java
+++ b/services/core/java/com/android/server/am/UserController.java
@@ -559,7 +559,7 @@
         // Spin up app widgets prior to boot-complete, so they can be ready promptly
         mInjector.startUserWidgets(userId);
 
-        Slog.i(TAG, "Sending BOOT_COMPLETE user #" + userId);
+        Slog.i(TAG, "Posting BOOT_COMPLETED user #" + userId);
         // Do not report secondary users, runtime restarts or first boot/upgrade
         if (userId == UserHandle.USER_SYSTEM
                 && !mInjector.isRuntimeRestarted() && !mInjector.isFirstBootOrUpgrade()) {
@@ -572,18 +572,26 @@
         bootIntent.addFlags(Intent.FLAG_RECEIVER_NO_ABORT
                 | Intent.FLAG_RECEIVER_INCLUDE_BACKGROUND
                 | Intent.FLAG_RECEIVER_OFFLOAD);
-        mInjector.broadcastIntent(bootIntent, null, new IIntentReceiver.Stub() {
-                    @Override
-                    public void performReceive(Intent intent, int resultCode, String data,
-                            Bundle extras, boolean ordered, boolean sticky, int sendingUser)
-                            throws RemoteException {
-                        Slog.i(UserController.TAG, "Finished processing BOOT_COMPLETED for u" + userId);
-                        mBootCompleted = true;
-                    }
-                }, 0, null, null,
-                new String[]{android.Manifest.permission.RECEIVE_BOOT_COMPLETED},
-                AppOpsManager.OP_NONE, null, true, false, MY_PID, SYSTEM_UID,
-                Binder.getCallingUid(), Binder.getCallingPid(), userId);
+        // Widget broadcasts are outbound via FgThread, so to guarantee sequencing
+        // we also send the boot_completed broadcast from that thread.
+        final int callingUid = Binder.getCallingUid();
+        final int callingPid = Binder.getCallingPid();
+        FgThread.getHandler().post(() -> {
+            mInjector.broadcastIntent(bootIntent, null,
+                    new IIntentReceiver.Stub() {
+                        @Override
+                        public void performReceive(Intent intent, int resultCode, String data,
+                                Bundle extras, boolean ordered, boolean sticky, int sendingUser)
+                                        throws RemoteException {
+                            Slog.i(UserController.TAG, "Finished processing BOOT_COMPLETED for u"
+                                    + userId);
+                            mBootCompleted = true;
+                        }
+                    }, 0, null, null,
+                    new String[]{android.Manifest.permission.RECEIVE_BOOT_COMPLETED},
+                    AppOpsManager.OP_NONE, null, true, false, MY_PID, SYSTEM_UID,
+                    callingUid, callingPid, userId);
+        });
     }
 
     int restartUser(final int userId, final boolean foreground) {
diff --git a/services/core/java/com/android/server/appop/AppOpsService.java b/services/core/java/com/android/server/appop/AppOpsService.java
index 0a76845..7569363 100644
--- a/services/core/java/com/android/server/appop/AppOpsService.java
+++ b/services/core/java/com/android/server/appop/AppOpsService.java
@@ -201,7 +201,7 @@
     @VisibleForTesting
     final SparseArray<UidState> mUidStates = new SparseArray<>();
 
-    private final HistoricalRegistry mHistoricalRegistry = new HistoricalRegistry(this);
+    final HistoricalRegistry mHistoricalRegistry = new HistoricalRegistry(this);
 
     long mLastRealtime;
 
diff --git a/services/core/java/com/android/server/appop/HistoricalRegistry.java b/services/core/java/com/android/server/appop/HistoricalRegistry.java
index 69a1c9f5..9cf342c 100644
--- a/services/core/java/com/android/server/appop/HistoricalRegistry.java
+++ b/services/core/java/com/android/server/appop/HistoricalRegistry.java
@@ -108,6 +108,12 @@
  * must be called with the mInMemoryLock, xxxDMLocked suffix means the method
  * must be called with the mOnDiskLock and mInMemoryLock locks acquired in that
  * exact order.
+ * <p>
+ * INITIALIZATION: We can initialize persistence only after the system is ready
+ * as we need to check the optional configuration override from the settings
+ * database which is not initialized at the time the app ops service is created.
+ * This means that all entry points that touch persistence should be short
+ * circuited via isPersistenceInitialized() check.
  */
 // TODO (bug:122218838): Make sure we handle start of epoch time
 // TODO (bug:122218838): Validate changed time is handled correctly
@@ -177,14 +183,33 @@
 
     // Object managing persistence (read/write)
     @GuardedBy("mOnDiskLock")
-    private Persistence mPersistence = new Persistence(mBaseSnapshotInterval,
-            mIntervalCompressionMultiplier);
+    private Persistence mPersistence;
 
     HistoricalRegistry(@NonNull Object lock) {
         mInMemoryLock = lock;
-        if (mMode != AppOpsManager.HISTORICAL_MODE_DISABLED) {
-            synchronized (mOnDiskLock) {
-                synchronized (mInMemoryLock) {
+    }
+
+    void systemReady(@NonNull ContentResolver resolver) {
+        final Uri uri = Settings.Global.getUriFor(Settings.Global.APPOP_HISTORY_PARAMETERS);
+        resolver.registerContentObserver(uri, false, new ContentObserver(
+                FgThread.getHandler()) {
+            @Override
+            public void onChange(boolean selfChange) {
+                updateParametersFromSetting(resolver);
+            }
+        });
+
+        updateParametersFromSetting(resolver);
+
+        synchronized (mOnDiskLock) {
+            synchronized (mInMemoryLock) {
+                if (mMode != AppOpsManager.HISTORICAL_MODE_DISABLED) {
+                    // Can be uninitialized if there is no config in the settings table.
+                    if (!isPersistenceInitializedMLocked()) {
+                        mPersistence = new Persistence(mBaseSnapshotInterval,
+                                mIntervalCompressionMultiplier);
+                    }
+
                     // When starting always adjust history to now.
                     final long lastPersistTimeMills =
                             mPersistence.getLastPersistTimeMillisDLocked();
@@ -197,16 +222,8 @@
         }
     }
 
-    void systemReady(@NonNull ContentResolver resolver) {
-        updateParametersFromSetting(resolver);
-        final Uri uri = Settings.Global.getUriFor(Settings.Global.APPOP_HISTORY_PARAMETERS);
-        resolver.registerContentObserver(uri, false, new ContentObserver(
-                FgThread.getHandler()) {
-            @Override
-            public void onChange(boolean selfChange) {
-                updateParametersFromSetting(resolver);
-            }
-        });
+    private boolean isPersistenceInitializedMLocked() {
+        return mPersistence != null;
     }
 
     private void updateParametersFromSetting(@NonNull ContentResolver resolver) {
@@ -274,6 +291,11 @@
                 makeRelativeToEpochStart(currentOps, nowMillis);
                 currentOps.accept(visitor);
 
+                if(isPersistenceInitializedMLocked()) {
+                    Slog.e(LOG_TAG, "Interaction before persistence initialized");
+                    return;
+                }
+
                 final List<HistoricalOps> ops = mPersistence.readHistoryDLocked();
                 if (ops != null) {
                     // TODO (bug:122218838): Make sure this is properly dumped
@@ -302,12 +324,21 @@
     void getHistoricalOpsFromDiskRaw(int uid, @NonNull String packageName,
             @Nullable String[] opNames, long beginTimeMillis, long endTimeMillis,
             @OpFlags int flags, @NonNull RemoteCallback callback) {
-        final HistoricalOps result = new HistoricalOps(beginTimeMillis, endTimeMillis);
-        mPersistence.collectHistoricalOpsDLocked(result, uid, packageName, opNames,
-                beginTimeMillis, endTimeMillis, flags);
-        final Bundle payload = new Bundle();
-        payload.putParcelable(AppOpsManager.KEY_HISTORICAL_OPS, result);
-        callback.sendResult(payload);
+        synchronized (mOnDiskLock) {
+            synchronized (mInMemoryLock) {
+                if (!isPersistenceInitializedMLocked()) {
+                    Slog.e(LOG_TAG, "Interaction before persistence initialized");
+                    callback.sendResult(new Bundle());
+                    return;
+                }
+                final HistoricalOps result = new HistoricalOps(beginTimeMillis, endTimeMillis);
+                mPersistence.collectHistoricalOpsDLocked(result, uid, packageName, opNames,
+                        beginTimeMillis, endTimeMillis, flags);
+                final Bundle payload = new Bundle();
+                payload.putParcelable(AppOpsManager.KEY_HISTORICAL_OPS, result);
+                callback.sendResult(payload);
+            }
+        }
     }
 
     void getHistoricalOps(int uid, @NonNull String packageName,
@@ -331,6 +362,12 @@
             boolean collectOpsFromDisk;
 
             synchronized (mInMemoryLock) {
+                if (!isPersistenceInitializedMLocked()) {
+                    Slog.e(LOG_TAG, "Interaction before persistence initialized");
+                    callback.sendResult(new Bundle());
+                    return;
+                }
+
                 currentOps = getUpdatedPendingHistoricalOpsMLocked(currentTimeMillis);
                 if (!(inMemoryAdjBeginTimeMillis >= currentOps.getEndTimeMillis()
                         || inMemoryAdjEndTimeMillis <= currentOps.getBeginTimeMillis())) {
@@ -374,6 +411,10 @@
             @UidState int uidState, @OpFlags int flags) {
         synchronized (mInMemoryLock) {
             if (mMode == AppOpsManager.HISTORICAL_MODE_ENABLED_ACTIVE) {
+                if (!isPersistenceInitializedMLocked()) {
+                    Slog.e(LOG_TAG, "Interaction before persistence initialized");
+                    return;
+                }
                 getUpdatedPendingHistoricalOpsMLocked(System.currentTimeMillis())
                         .increaseAccessCount(op, uid, packageName, uidState, flags, 1);
             }
@@ -384,6 +425,10 @@
             @UidState int uidState, @OpFlags int flags) {
         synchronized (mInMemoryLock) {
             if (mMode == AppOpsManager.HISTORICAL_MODE_ENABLED_ACTIVE) {
+                if (!isPersistenceInitializedMLocked()) {
+                    Slog.e(LOG_TAG, "Interaction before persistence initialized");
+                    return;
+                }
                 getUpdatedPendingHistoricalOpsMLocked(System.currentTimeMillis())
                         .increaseRejectCount(op, uid, packageName, uidState, flags, 1);
             }
@@ -394,6 +439,10 @@
             @UidState int uidState, @OpFlags int flags, long increment) {
         synchronized (mInMemoryLock) {
             if (mMode == AppOpsManager.HISTORICAL_MODE_ENABLED_ACTIVE) {
+                if (!isPersistenceInitializedMLocked()) {
+                    Slog.e(LOG_TAG, "Interaction before persistence initialized");
+                    return;
+                }
                 getUpdatedPendingHistoricalOpsMLocked(System.currentTimeMillis())
                         .increaseAccessDuration(op, uid, packageName, uidState, flags, increment);
             }
@@ -404,6 +453,8 @@
             long baseSnapshotInterval, long intervalCompressionMultiplier) {
         synchronized (mOnDiskLock) {
             synchronized (mInMemoryLock) {
+                // NOTE: We allow this call if persistence is not initialized as
+                // it is a part of the persistence initialization process.
                 boolean resampleHistory = false;
                 Slog.i(LOG_TAG, "New history parameters: mode:"
                         + AppOpsManager.historicalModeToString(mMode) + " baseSnapshotInterval:"
@@ -412,7 +463,7 @@
                 if (mMode != mode) {
                     mMode = mode;
                     if (mMode == AppOpsManager.HISTORICAL_MODE_DISABLED) {
-                        clearHistoryOnDiskLocked();
+                        clearHistoryOnDiskDLocked();
                     }
                 }
                 if (mBaseSnapshotInterval != baseSnapshotInterval) {
@@ -433,6 +484,10 @@
     void offsetHistory(long offsetMillis) {
         synchronized (mOnDiskLock) {
             synchronized (mInMemoryLock) {
+                if (!isPersistenceInitializedMLocked()) {
+                    Slog.e(LOG_TAG, "Interaction before persistence initialized");
+                    return;
+                }
                 final List<HistoricalOps> history = mPersistence.readHistoryDLocked();
                 clearHistory();
                 if (history != null) {
@@ -453,6 +508,10 @@
     void addHistoricalOps(HistoricalOps ops) {
         final List<HistoricalOps> pendingWrites;
         synchronized (mInMemoryLock) {
+            if (!isPersistenceInitializedMLocked()) {
+                Slog.e(LOG_TAG, "Interaction before persistence initialized");
+                return;
+            }
             // The history files start from mBaseSnapshotInterval - take this into account.
             ops.offsetBeginAndEndTime(mBaseSnapshotInterval);
             mPendingWrites.offerFirst(ops);
@@ -468,6 +527,10 @@
     }
 
     void resetHistoryParameters() {
+        if (!isPersistenceInitializedMLocked()) {
+            Slog.e(LOG_TAG, "Interaction before persistence initialized");
+            return;
+        }
         setHistoryParameters(DEFAULT_MODE, DEFAULT_SNAPSHOT_INTERVAL_MILLIS,
                 DEFAULT_COMPRESSION_STEP);
     }
@@ -475,6 +538,10 @@
     void clearHistory(int uid, String packageName) {
         synchronized (mOnDiskLock) {
             synchronized (mInMemoryLock) {
+                if (!isPersistenceInitializedMLocked()) {
+                    Slog.e(LOG_TAG, "Interaction before persistence initialized");
+                    return;
+                }
                 if (mMode != AppOpsManager.HISTORICAL_MODE_ENABLED_ACTIVE) {
                     return;
                 }
@@ -493,18 +560,24 @@
 
     void clearHistory() {
         synchronized (mOnDiskLock) {
-            clearHistoryOnDiskLocked();
+            synchronized (mInMemoryLock) {
+                if (!isPersistenceInitializedMLocked()) {
+                    Slog.e(LOG_TAG, "Interaction before persistence initialized");
+                    return;
+                }
+                clearHistoryOnDiskDLocked();
+            }
         }
     }
 
-    private void clearHistoryOnDiskLocked() {
+    private void clearHistoryOnDiskDLocked() {
         BackgroundThread.getHandler().removeMessages(MSG_WRITE_PENDING_HISTORY);
         synchronized (mInMemoryLock) {
             mCurrentHistoricalOps = null;
             mNextPersistDueTimeMillis = System.currentTimeMillis();
             mPendingWrites.clear();
         }
-        mPersistence.clearHistoryDLocked();
+        Persistence.clearHistoryDLocked();
     }
 
     private @NonNull HistoricalOps getUpdatedPendingHistoricalOpsMLocked(long now) {
@@ -639,7 +712,7 @@
             mIntervalCompressionMultiplier = intervalCompressionMultiplier;
         }
 
-        private final AtomicDirectory mHistoricalAppOpsDir = new AtomicDirectory(
+        private static final AtomicDirectory sHistoricalAppOpsDir = new AtomicDirectory(
                 new File(new File(Environment.getDataSystemDirectory(), "appops"), "history"));
 
         private File generateFile(@NonNull File baseDir, int depth) {
@@ -663,8 +736,8 @@
             persistHistoricalOpsDLocked(historicalOps);
         }
 
-        void clearHistoryDLocked() {
-            mHistoricalAppOpsDir.delete();
+        static void clearHistoryDLocked() {
+            sHistoricalAppOpsDir.delete();
         }
 
         void persistHistoricalOpsDLocked(@NonNull List<HistoricalOps> ops) {
@@ -673,8 +746,8 @@
                 enforceOpsWellFormed(ops);
             }
             try {
-                final File newBaseDir = mHistoricalAppOpsDir.startWrite();
-                final File oldBaseDir = mHistoricalAppOpsDir.getBackupDirectory();
+                final File newBaseDir = sHistoricalAppOpsDir.startWrite();
+                final File oldBaseDir = sHistoricalAppOpsDir.getBackupDirectory();
                 final HistoricalFilesInvariant filesInvariant;
                 if (DEBUG) {
                     filesInvariant = new HistoricalFilesInvariant();
@@ -686,10 +759,10 @@
                 if (DEBUG) {
                     filesInvariant.stopTracking(newBaseDir);
                 }
-                mHistoricalAppOpsDir.finishWrite();
+                sHistoricalAppOpsDir.finishWrite();
             } catch (Throwable t) {
                 wtf("Failed to write historical app ops, restoring backup", t, null);
-                mHistoricalAppOpsDir.failWrite();
+                sHistoricalAppOpsDir.failWrite();
             }
         }
 
@@ -715,22 +788,36 @@
         long getLastPersistTimeMillisDLocked() {
             File baseDir = null;
             try {
-                baseDir = mHistoricalAppOpsDir.startRead();
+                baseDir = sHistoricalAppOpsDir.startRead();
                 final File[] files = baseDir.listFiles();
                 if (files != null && files.length > 0) {
-                    final Set<File> historyFiles = new ArraySet<>();
-                    Collections.addAll(historyFiles, files);
-                    for (int i = 0;; i++) {
-                        final File file = generateFile(baseDir, i);
-                        if (historyFiles.contains(file)) {
-                            return file.lastModified();
+                    File shortestFile = null;
+                    for (File candidate : files) {
+                        final String candidateName = candidate.getName();
+                        if (!candidateName.endsWith(HISTORY_FILE_SUFFIX)) {
+                            continue;
+                        }
+                        if (shortestFile == null) {
+                            shortestFile = candidate;
+                        } else if (candidateName.length() < shortestFile.getName().length()) {
+                            shortestFile = candidate;
                         }
                     }
+                    if (shortestFile == null) {
+                        return 0;
+                    }
+                    final String shortestNameNoExtension = shortestFile.getName()
+                            .replace(HISTORY_FILE_SUFFIX, "");
+                    try {
+                        return Long.parseLong(shortestNameNoExtension);
+                    } catch (NumberFormatException e) {
+                        return 0;
+                    }
                 }
-                mHistoricalAppOpsDir.finishRead();
+                sHistoricalAppOpsDir.finishRead();
             } catch (Throwable e) {
                 wtf("Error reading historical app ops. Deleting history.", e, baseDir);
-                mHistoricalAppOpsDir.delete();
+                sHistoricalAppOpsDir.delete();
             }
             return 0;
         }
@@ -755,7 +842,7 @@
                 long filterBeginTimeMillis, long filterEndTimeMillis, @OpFlags int filterFlags) {
             File baseDir = null;
             try {
-                baseDir = mHistoricalAppOpsDir.startRead();
+                baseDir = sHistoricalAppOpsDir.startRead();
                 final HistoricalFilesInvariant filesInvariant;
                 if (DEBUG) {
                     filesInvariant = new HistoricalFilesInvariant();
@@ -770,11 +857,11 @@
                 if (DEBUG) {
                     filesInvariant.stopTracking(baseDir);
                 }
-                mHistoricalAppOpsDir.finishRead();
+                sHistoricalAppOpsDir.finishRead();
                 return ops;
             } catch (Throwable t) {
                 wtf("Error reading historical app ops. Deleting history.", t, baseDir);
-                mHistoricalAppOpsDir.delete();
+                sHistoricalAppOpsDir.delete();
             }
             return null;
         }
@@ -1241,7 +1328,7 @@
 
         private void writeHistoricalOpsDLocked(@Nullable List<HistoricalOps> allOps,
                 long intervalOverflowMillis, @NonNull File file) throws IOException {
-            final FileOutputStream output = mHistoricalAppOpsDir.openWrite(file);
+            final FileOutputStream output = sHistoricalAppOpsDir.openWrite(file);
             try {
                 final XmlSerializer serializer = Xml.newSerializer();
                 serializer.setOutput(output, StandardCharsets.UTF_8.name());
@@ -1263,9 +1350,9 @@
                 }
                 serializer.endTag(null, TAG_HISTORY);
                 serializer.endDocument();
-                mHistoricalAppOpsDir.closeWrite(output);
+                sHistoricalAppOpsDir.closeWrite(output);
             } catch (IOException e) {
-                mHistoricalAppOpsDir.failWrite(output);
+                sHistoricalAppOpsDir.failWrite(output);
                 throw e;
             }
         }
diff --git a/services/core/java/com/android/server/attention/AttentionManagerService.java b/services/core/java/com/android/server/attention/AttentionManagerService.java
index 3b19d08..1b45eb4 100644
--- a/services/core/java/com/android/server/attention/AttentionManagerService.java
+++ b/services/core/java/com/android/server/attention/AttentionManagerService.java
@@ -190,9 +190,7 @@
 
             final UserState userState = getOrCreateCurrentUserStateLocked();
             // lazily start the service, which should be very lightweight to start
-            if (!userState.bindLocked()) {
-                return false;
-            }
+            userState.bindLocked();
 
             // throttle frequent requests
             final AttentionCheckCache cache = userState.mAttentionCheckCache;
@@ -310,7 +308,7 @@
     protected UserState getOrCreateUserStateLocked(int userId) {
         UserState result = mUserStates.get(userId);
         if (result == null) {
-            result = new UserState(userId, mContext, mLock, mComponentName);
+            result = new UserState(userId, mContext, mLock, mAttentionHandler, mComponentName);
             mUserStates.put(userId, result);
         }
         return result;
@@ -456,31 +454,33 @@
 
     @VisibleForTesting
     protected static class UserState {
-        final ComponentName mComponentName;
-        final AttentionServiceConnection mConnection = new AttentionServiceConnection();
+        private final ComponentName mComponentName;
+        private final AttentionServiceConnection mConnection = new AttentionServiceConnection();
 
         @GuardedBy("mLock")
         IAttentionService mService;
         @GuardedBy("mLock")
-        boolean mBinding;
-        @GuardedBy("mLock")
         AttentionCheck mCurrentAttentionCheck;
         @GuardedBy("mLock")
         AttentionCheckCache mAttentionCheckCache;
+        @GuardedBy("mLock")
+        private boolean mBinding;
 
         @UserIdInt
-        final int mUserId;
-        final Context mContext;
-        final Object mLock;
+        private final int mUserId;
+        private final Context mContext;
+        private final Object mLock;
+        private final Handler mAttentionHandler;
 
-        UserState(int userId, Context context, Object lock, ComponentName componentName) {
+        UserState(int userId, Context context, Object lock, Handler handler,
+                ComponentName componentName) {
             mUserId = userId;
             mContext = Preconditions.checkNotNull(context);
             mLock = Preconditions.checkNotNull(lock);
             mComponentName = Preconditions.checkNotNull(componentName);
+            mAttentionHandler = handler;
         }
 
-
         @GuardedBy("mLock")
         private void handlePendingCallbackLocked() {
             if (!mCurrentAttentionCheck.mIsDispatched) {
@@ -499,26 +499,25 @@
 
         /** Binds to the system's AttentionService which provides an actual implementation. */
         @GuardedBy("mLock")
-        private boolean bindLocked() {
+        private void bindLocked() {
             // No need to bind if service is binding or has already been bound.
             if (mBinding || mService != null) {
-                return true;
+                return;
             }
 
-            final boolean willBind;
-            final long identity = Binder.clearCallingIdentity();
-
-            try {
-                final Intent mServiceIntent = new Intent(
+            mBinding = true;
+            // mContext.bindServiceAsUser() calls into ActivityManagerService which it may already
+            // hold the lock and had called into PowerManagerService, which holds a lock.
+            // That would create a deadlock. To solve that, putting it on a handler.
+            mAttentionHandler.post(() -> {
+                final Intent serviceIntent = new Intent(
                         AttentionService.SERVICE_INTERFACE).setComponent(
                         mComponentName);
-                willBind = mContext.bindServiceAsUser(mServiceIntent, mConnection,
+                // Note: no reason to clear the calling identity, we won't have one in a handler.
+                mContext.bindServiceAsUser(serviceIntent, mConnection,
                         Context.BIND_AUTO_CREATE, UserHandle.CURRENT);
-                mBinding = willBind;
-            } finally {
-                Binder.restoreCallingIdentity(identity);
-            }
-            return willBind;
+
+            });
         }
 
         private void dump(IndentingPrintWriter pw) {
@@ -587,6 +586,7 @@
             super(Looper.myLooper());
         }
 
+        @Override
         public void handleMessage(Message msg) {
             switch (msg.what) {
                 // Do not occupy resources when not in use - unbind proactively.
@@ -651,7 +651,12 @@
                 return;
             }
 
-            mContext.unbindService(userState.mConnection);
+            mAttentionHandler.post(() -> mContext.unbindService(userState.mConnection));
+            // Note: this will set mBinding to false even though it could still be trying to bind
+            // (i.e. the runnable was posted in bindLocked but then cancelAndUnbindLocked was
+            // called before it's run yet). This is a safe state at the moment,
+            // since it will eventually, but feels like a source for confusion down the road and
+            // may cause some expensive and unnecessary work to be done.
             userState.mConnection.cleanupService();
             mUserStates.remove(userState.mUserId);
         }
diff --git a/services/core/java/com/android/server/audio/AudioService.java b/services/core/java/com/android/server/audio/AudioService.java
index 376e9b5..5ae5113 100644
--- a/services/core/java/com/android/server/audio/AudioService.java
+++ b/services/core/java/com/android/server/audio/AudioService.java
@@ -162,6 +162,7 @@
 import java.util.NoSuchElementException;
 import java.util.Objects;
 import java.util.concurrent.Executor;
+import java.util.concurrent.atomic.AtomicBoolean;
 
 /**
  * The implementation of the volume manager service.
@@ -265,6 +266,7 @@
     private static final int MSG_SET_DEVICE_STREAM_VOLUME = 26;
     private static final int MSG_OBSERVE_DEVICES_FOR_ALL_STREAMS = 27;
     private static final int MSG_HDMI_VOLUME_CHECK = 28;
+    private static final int MSG_PLAYBACK_CONFIG_CHANGE = 29;
     // start of messages handled under wakelock
     //   these messages can only be queued, i.e. sent with queueMsgUnderWakeLock(),
     //   and not with sendMsg(..., ..., SENDMSG_QUEUE, ...)
@@ -1014,6 +1016,7 @@
             sendEncodedSurroundMode(mContentResolver, "onAudioServerDied");
             sendEnabledSurroundFormats(mContentResolver, true);
             updateAssistantUId(true);
+            updateRttEanbled(mContentResolver);
         }
         synchronized (mAccessibilityServiceUidsLock) {
             AudioSystem.setA11yServicesUids(mAccessibilityServiceUids);
@@ -1478,6 +1481,12 @@
         }
     }
 
+    private void updateRttEanbled(ContentResolver cr) {
+        final boolean rttEnabled = Settings.Secure.getIntForUser(cr,
+                    Settings.Secure.RTT_CALLING_MODE, 0, UserHandle.USER_CURRENT) != 0;
+        AudioSystem.setRttEnabled(rttEnabled);
+    }
+
     private void readPersistedSettings() {
         final ContentResolver cr = mContentResolver;
 
@@ -1522,6 +1531,7 @@
             sendEncodedSurroundMode(cr, "readPersistedSettings");
             sendEnabledSurroundFormats(cr, true);
             updateAssistantUId(true);
+            updateRttEanbled(cr);
         }
 
         mMuteAffectedStreams = System.getIntForUser(cr,
@@ -1867,9 +1877,15 @@
 
             // Check if volume update should be send to Hearing Aid
             if ((device & AudioSystem.DEVICE_OUT_HEARING_AID) != 0) {
-                Log.i(TAG, "adjustSreamVolume postSetHearingAidVolumeIndex index=" + newIndex
-                        + " stream=" + streamType);
-                mDeviceBroker.postSetHearingAidVolumeIndex(newIndex, streamType);
+                // only modify the hearing aid attenuation when the stream to modify matches
+                // the one expected by the hearing aid
+                if (streamType == getHearingAidStreamType()) {
+                    if (DEBUG_VOL) {
+                        Log.d(TAG, "adjustSreamVolume postSetHearingAidVolumeIndex index="
+                                + newIndex + " stream=" + streamType);
+                    }
+                    mDeviceBroker.postSetHearingAidVolumeIndex(newIndex, streamType);
+                }
             }
 
             // Check if volume update should be sent to Hdmi system audio.
@@ -2161,11 +2177,53 @@
                 return AudioSystem.STREAM_VOICE_CALL;
             case AudioSystem.MODE_NORMAL:
             default:
+                // other conditions will influence the stream type choice, read on...
                 break;
         }
+        if (mVoiceActive.get()) {
+            return AudioSystem.STREAM_VOICE_CALL;
+        }
         return AudioSystem.STREAM_MUSIC;
     }
 
+    private AtomicBoolean mVoiceActive = new AtomicBoolean(false);
+
+    private final IPlaybackConfigDispatcher mVoiceActivityMonitor =
+            new IPlaybackConfigDispatcher.Stub() {
+        @Override
+        public void dispatchPlaybackConfigChange(List<AudioPlaybackConfiguration> configs,
+                                                 boolean flush) {
+            sendMsg(mAudioHandler, MSG_PLAYBACK_CONFIG_CHANGE, SENDMSG_REPLACE,
+                    0 /*arg1 ignored*/, 0 /*arg2 ignored*/,
+                    configs /*obj*/, 0 /*delay*/);
+        }
+    };
+
+    private void onPlaybackConfigChange(List<AudioPlaybackConfiguration> configs) {
+        boolean voiceActive = false;
+        for (AudioPlaybackConfiguration config : configs) {
+            final int usage = config.getAudioAttributes().getUsage();
+            if ((usage == AudioAttributes.USAGE_VOICE_COMMUNICATION
+                    || usage == AudioAttributes.USAGE_VOICE_COMMUNICATION_SIGNALLING)
+                    && config.getPlayerState() == AudioPlaybackConfiguration.PLAYER_STATE_STARTED) {
+                voiceActive = true;
+                break;
+            }
+        }
+        if (mVoiceActive.getAndSet(voiceActive) != voiceActive) {
+            updateHearingAidVolumeOnVoiceActivityUpdate();
+        }
+    }
+
+    private void updateHearingAidVolumeOnVoiceActivityUpdate() {
+        final int streamType = getHearingAidStreamType();
+        final int index = getStreamVolume(streamType);
+        sVolumeLogger.log(new VolumeEvent(VolumeEvent.VOL_VOICE_ACTIVITY_HEARING_AID,
+                mVoiceActive.get(), streamType, index));
+        mDeviceBroker.postSetHearingAidVolumeIndex(index * 10, streamType);
+
+    }
+
     /**
      * Manage an audio mode change for audio devices that use an "absolute volume" model,
      * i.e. the framework sends the full scale signal, and the actual volume for the use case
@@ -2200,10 +2258,8 @@
         // handling of specific interfaces goes here:
         if ((device & mAbsVolumeMultiModeCaseDevices) == AudioSystem.DEVICE_OUT_HEARING_AID) {
             final int index = getStreamVolume(streamType);
-            mModeLogger.log(new AudioEventLogger.StringEvent("setMode to "
-                    + AudioSystem.modeToString(newMode)
-                    + " causes setting HEARING_AID volume to idx:" + index
-                    + " stream:" + AudioSystem.streamToString(streamType)));
+            sVolumeLogger.log(new VolumeEvent(VolumeEvent.VOL_MODE_CHANGE_HEARING_AID,
+                    newMode, streamType, index));
             mDeviceBroker.postSetHearingAidVolumeIndex(index * 10, streamType);
         }
     }
@@ -2269,7 +2325,8 @@
                 mDeviceBroker.postSetAvrcpAbsoluteVolumeIndex(index / 10);
             }
 
-            if ((device & AudioSystem.DEVICE_OUT_HEARING_AID) != 0) {
+            if ((device & AudioSystem.DEVICE_OUT_HEARING_AID) != 0
+                    && streamType == getHearingAidStreamType()) {
                 Log.i(TAG, "setStreamVolume postSetHearingAidVolumeIndex index=" + index
                         + " stream=" + streamType);
                 mDeviceBroker.postSetHearingAidVolumeIndex(index, streamType);
@@ -4345,6 +4402,11 @@
             throw new IllegalArgumentException("Illegal BluetoothProfile state for device "
                     + " (dis)connection, got " + state);
         }
+        if (state == BluetoothProfile.STATE_CONNECTED) {
+            mPlaybackMonitor.registerPlaybackCallback(mVoiceActivityMonitor, true);
+        } else {
+            mPlaybackMonitor.unregisterPlaybackCallback(mVoiceActivityMonitor);
+        }
         mDeviceBroker.postBluetoothHearingAidDeviceConnectionState(
                 device, state, suppressNoisyIntent, musicDevice, "AudioService");
     }
@@ -4832,6 +4894,7 @@
             pw.println((mIndexMin + 5) / 10);
             pw.print("   Max: ");
             pw.println((mIndexMax + 5) / 10);
+            pw.print("   streamVolume:"); pw.println(getStreamVolume(mStreamType));
             pw.print("   Current: ");
             for (int i = 0; i < mIndexMap.size(); i++) {
                 if (i > 0) {
@@ -5408,6 +5471,11 @@
 
                 case MSG_HDMI_VOLUME_CHECK:
                     onCheckVolumeCecOnHdmiConnection(msg.arg1, (String) msg.obj);
+                    break;
+
+                case MSG_PLAYBACK_CONFIG_CHANGE:
+                    onPlaybackConfigChange((List<AudioPlaybackConfiguration>) msg.obj);
+                    break;
             }
         }
     }
@@ -5442,6 +5510,8 @@
 
             mContentResolver.registerContentObserver(Settings.Secure.getUriFor(
                     Settings.Secure.VOICE_INTERACTION_SERVICE), false, this);
+            mContentResolver.registerContentObserver(Settings.Secure.getUriFor(
+                    Settings.Secure.RTT_CALLING_MODE), false, this);
         }
 
         @Override
@@ -5465,6 +5535,7 @@
                 updateEncodedSurroundOutput();
                 sendEnabledSurroundFormats(mContentResolver, mSurroundModeChanged);
                 updateAssistantUId(false);
+                updateRttEanbled(mContentResolver);
             }
         }
 
diff --git a/services/core/java/com/android/server/audio/AudioServiceEvents.java b/services/core/java/com/android/server/audio/AudioServiceEvents.java
index d999217..fcd8701 100644
--- a/services/core/java/com/android/server/audio/AudioServiceEvents.java
+++ b/services/core/java/com/android/server/audio/AudioServiceEvents.java
@@ -95,6 +95,8 @@
         static final int VOL_SET_HEARING_AID_VOL = 3;
         static final int VOL_SET_AVRCP_VOL = 4;
         static final int VOL_ADJUST_VOL_UID = 5;
+        static final int VOL_VOICE_ACTIVITY_HEARING_AID = 6;
+        static final int VOL_MODE_CHANGE_HEARING_AID = 7;
 
         final int mOp;
         final int mStream;
@@ -102,6 +104,10 @@
         final int mVal2;
         final String mCaller;
 
+        /** used for VOL_ADJUST_VOL_UID,
+         *           VOL_ADJUST_SUGG_VOL,
+         *           VOL_ADJUST_STREAM_VOL,
+         *           VOL_SET_STREAM_VOL */
         VolumeEvent(int op, int stream, int val1, int val2, String caller) {
             mOp = op;
             mStream = stream;
@@ -110,24 +116,46 @@
             mCaller = caller;
         }
 
+        /** used for VOL_SET_HEARING_AID_VOL*/
         VolumeEvent(int op, int index, int gainDb) {
             mOp = op;
             mVal1 = index;
             mVal2 = gainDb;
-            //unused
+            // unused
             mStream = -1;
             mCaller = null;
         }
 
+        /** used for VOL_SET_AVRCP_VOL */
         VolumeEvent(int op, int index) {
             mOp = op;
             mVal1 = index;
-            //unused
+            // unused
             mVal2 = 0;
             mStream = -1;
             mCaller = null;
         }
 
+        /** used for VOL_VOICE_ACTIVITY_HEARING_AID */
+        VolumeEvent(int op, boolean voiceActive, int stream, int index) {
+            mOp = op;
+            mStream = stream;
+            mVal1 = index;
+            mVal2 = voiceActive ? 1 : 0;
+            // unused
+            mCaller = null;
+        }
+
+        /** used for VOL_MODE_CHANGE_HEARING_AID */
+        VolumeEvent(int op, int mode, int stream, int index) {
+            mOp = op;
+            mStream = stream;
+            mVal1 = index;
+            mVal2 = mode;
+            // unused
+            mCaller = null;
+        }
+
         @Override
         public String eventToString() {
             switch (mOp) {
@@ -168,7 +196,19 @@
                             .append(" flags:0x").append(Integer.toHexString(mVal2))
                             .append(") from ").append(mCaller)
                             .toString();
-               default: return new StringBuilder("FIXME invalid op:").append(mOp).toString();
+                case VOL_VOICE_ACTIVITY_HEARING_AID:
+                    return new StringBuilder("Voice activity change (")
+                            .append(mVal2 == 1 ? "active" : "inactive")
+                            .append(") causes setting HEARING_AID volume to idx:").append(mVal1)
+                            .append(" stream:").append(AudioSystem.streamToString(mStream))
+                            .toString();
+                case VOL_MODE_CHANGE_HEARING_AID:
+                    return new StringBuilder("setMode(")
+                            .append(AudioSystem.modeToString(mVal2))
+                            .append(") causes setting HEARING_AID volume to idx:").append(mVal1)
+                            .append(" stream:").append(AudioSystem.streamToString(mStream))
+                            .toString();
+                default: return new StringBuilder("FIXME invalid op:").append(mOp).toString();
             }
         }
     }
diff --git a/services/core/java/com/android/server/biometrics/ClientMonitor.java b/services/core/java/com/android/server/biometrics/ClientMonitor.java
index 421b3f5..942e050 100644
--- a/services/core/java/com/android/server/biometrics/ClientMonitor.java
+++ b/services/core/java/com/android/server/biometrics/ClientMonitor.java
@@ -42,12 +42,7 @@
     private static final AudioAttributes FINGERPRINT_SONFICATION_ATTRIBUTES =
             new AudioAttributes.Builder()
                     .setContentType(AudioAttributes.CONTENT_TYPE_SONIFICATION)
-                    // Temporary fix for b/123870990. No time in this release to
-                    // introduce a new vibration type, but we need to distinguish these vibrations
-                    // from other haptic feedback vibrations. Fortunately, Alarm vibrations have
-                    // exactly the same behavior as we need
-                    // TODO: refactor within the scope of b/132170758
-                    .setUsage(AudioAttributes.USAGE_ALARM)
+                    .setUsage(AudioAttributes.USAGE_ASSISTANCE_SONIFICATION)
                     .build();
 
     private final Context mContext;
diff --git a/services/core/java/com/android/server/connectivity/KeepaliveTracker.java b/services/core/java/com/android/server/connectivity/KeepaliveTracker.java
index 3de2537..4b2e21d 100644
--- a/services/core/java/com/android/server/connectivity/KeepaliveTracker.java
+++ b/services/core/java/com/android/server/connectivity/KeepaliveTracker.java
@@ -216,6 +216,7 @@
 
         public String toString() {
             return "KeepaliveInfo ["
+                    + " type=" + mType
                     + " network=" + mNai.network
                     + " startedState=" + startedStateString(mStartedState)
                     + " "
diff --git a/services/core/java/com/android/server/content/ContentService.java b/services/core/java/com/android/server/content/ContentService.java
index 998ee1e..7824a0a 100644
--- a/services/core/java/com/android/server/content/ContentService.java
+++ b/services/core/java/com/android/server/content/ContentService.java
@@ -22,6 +22,7 @@
 import android.annotation.RequiresPermission;
 import android.app.ActivityManager;
 import android.app.ActivityManagerInternal;
+import android.app.AppGlobals;
 import android.app.AppOpsManager;
 import android.app.job.JobInfo;
 import android.content.BroadcastReceiver;
@@ -56,6 +57,7 @@
 import android.os.UserHandle;
 import android.text.TextUtils;
 import android.util.ArrayMap;
+import android.util.ArraySet;
 import android.util.Log;
 import android.util.Pair;
 import android.util.Slog;
@@ -63,6 +65,7 @@
 import android.util.SparseIntArray;
 
 import com.android.internal.annotations.GuardedBy;
+import com.android.internal.os.BinderDeathDispatcher;
 import com.android.internal.util.ArrayUtils;
 import com.android.internal.util.DumpUtils;
 import com.android.internal.util.IndentingPrintWriter;
@@ -83,6 +86,9 @@
     static final String TAG = "ContentService";
     static final boolean DEBUG = false;
 
+    /** Do a WTF if a single observer is registered more than this times. */
+    private static final int TOO_MANY_OBSERVERS_THRESHOLD = 1000;
+
     public static class Lifecycle extends SystemService {
         private ContentService mService;
 
@@ -135,6 +141,12 @@
     private SyncManager mSyncManager = null;
     private final Object mSyncManagerLock = new Object();
 
+    private static final BinderDeathDispatcher<IContentObserver> sObserverDeathDispatcher =
+            new BinderDeathDispatcher<>();
+
+    @GuardedBy("sObserverLeakDetectedUid")
+    private static final ArraySet<Integer> sObserverLeakDetectedUid = new ArraySet<>(0);
+
     /**
      * Map from userId to providerPackageName to [clientPackageName, uri] to
      * value. This structure is carefully optimized to keep invalidation logic
@@ -236,6 +248,13 @@
                 pw.println();
                 pw.print(" Total number of nodes: "); pw.println(counts[0]);
                 pw.print(" Total number of observers: "); pw.println(counts[1]);
+
+                sObserverDeathDispatcher.dump(pw, " ");
+            }
+            synchronized (sObserverLeakDetectedUid) {
+                pw.println();
+                pw.print("Observer leaking UIDs: ");
+                pw.println(sObserverLeakDetectedUid.toString());
             }
 
             synchronized (mCache) {
@@ -1345,18 +1364,40 @@
             private final Object observersLock;
 
             public ObserverEntry(IContentObserver o, boolean n, Object observersLock,
-                                 int _uid, int _pid, int _userHandle) {
+                                 int _uid, int _pid, int _userHandle, Uri uri) {
                 this.observersLock = observersLock;
                 observer = o;
                 uid = _uid;
                 pid = _pid;
                 userHandle = _userHandle;
                 notifyForDescendants = n;
-                try {
-                    observer.asBinder().linkToDeath(this, 0);
-                } catch (RemoteException e) {
+
+                final int entries = sObserverDeathDispatcher.linkToDeath(observer, this);
+                if (entries == -1) {
                     binderDied();
+                } else if (entries == TOO_MANY_OBSERVERS_THRESHOLD) {
+                    boolean alreadyDetected;
+
+                    synchronized (sObserverLeakDetectedUid) {
+                        alreadyDetected = sObserverLeakDetectedUid.contains(uid);
+                        if (!alreadyDetected) {
+                            sObserverLeakDetectedUid.add(uid);
+                        }
+                    }
+                    if (!alreadyDetected) {
+                        String caller = null;
+                        try {
+                            caller = ArrayUtils.firstOrNull(AppGlobals.getPackageManager()
+                                    .getPackagesForUid(uid));
+                        } catch (RemoteException ignore) {
+                        }
+                        Slog.wtf(TAG, "Observer registered too many times. Leak? cpid=" + pid
+                                + " cuid=" + uid
+                                + " cpkg=" + caller
+                                + " url=" + uri);
+                    }
                 }
+
             }
 
             @Override
@@ -1454,7 +1495,7 @@
             // If this is the leaf node add the observer
             if (index == countUriSegments(uri)) {
                 mObservers.add(new ObserverEntry(observer, notifyForDescendants, observersLock,
-                        uid, pid, userHandle));
+                        uid, pid, userHandle, uri));
                 return;
             }
 
@@ -1498,7 +1539,7 @@
                 if (entry.observer.asBinder() == observerBinder) {
                     mObservers.remove(i);
                     // We no longer need to listen for death notifications. Remove it.
-                    observerBinder.unlinkToDeath(entry, 0);
+                    sObserverDeathDispatcher.unlinkToDeath(observer, entry);
                     break;
                 }
             }
diff --git a/services/core/java/com/android/server/display/AutomaticBrightnessController.java b/services/core/java/com/android/server/display/AutomaticBrightnessController.java
index 6d7dff5..31632dc 100644
--- a/services/core/java/com/android/server/display/AutomaticBrightnessController.java
+++ b/services/core/java/com/android/server/display/AutomaticBrightnessController.java
@@ -322,7 +322,7 @@
         }
         changed |= setLightSensorEnabled(enable && !dozing);
         if (changed) {
-            updateAutoBrightness(false /*sendUpdate*/);
+            updateAutoBrightness(false /*sendUpdate*/, userInitiatedChange);
         }
     }
 
@@ -667,7 +667,7 @@
                         "mAmbientLightRingBuffer=" + mAmbientLightRingBuffer + ", " +
                         "mAmbientLux=" + mAmbientLux);
             }
-            updateAutoBrightness(true);
+            updateAutoBrightness(true /* sendUpdate */, false /* isManuallySet */);
         }
 
         long nextBrightenTransition = nextAmbientLightBrighteningTransition(time);
@@ -697,7 +697,7 @@
                         + "mAmbientLightRingBuffer=" + mAmbientLightRingBuffer + ", "
                         + "mAmbientLux=" + mAmbientLux);
             }
-            updateAutoBrightness(true);
+            updateAutoBrightness(true /* sendUpdate */, false /* isManuallySet */);
             nextBrightenTransition = nextAmbientLightBrighteningTransition(time);
             nextDarkenTransition = nextAmbientLightDarkeningTransition(time);
         }
@@ -717,7 +717,7 @@
         mHandler.sendEmptyMessageAtTime(MSG_UPDATE_AMBIENT_LUX, nextTransitionTime);
     }
 
-    private void updateAutoBrightness(boolean sendUpdate) {
+    private void updateAutoBrightness(boolean sendUpdate, boolean isManuallySet) {
         if (!mAmbientLuxValid) {
             return;
         }
@@ -732,6 +732,7 @@
         // in which case we ignore the new screen brightness if it doesn't differ enough from the
         // previous one.
         if (mScreenAutoBrightness != -1
+                && !isManuallySet
                 && newScreenAutoBrightness > mScreenDarkeningThreshold
                 && newScreenAutoBrightness < mScreenBrighteningThreshold) {
             if (mLoggingEnabled) {
@@ -879,7 +880,7 @@
         mPendingForegroundAppPackageName = null;
         mForegroundAppCategory = mPendingForegroundAppCategory;
         mPendingForegroundAppCategory = ApplicationInfo.CATEGORY_UNDEFINED;
-        updateAutoBrightness(true /* sendUpdate */);
+        updateAutoBrightness(true /* sendUpdate */, false /* isManuallySet */);
     }
 
     private final class AutomaticBrightnessHandler extends Handler {
diff --git a/services/core/java/com/android/server/gpu/GpuService.java b/services/core/java/com/android/server/gpu/GpuService.java
index d439653..955f177 100644
--- a/services/core/java/com/android/server/gpu/GpuService.java
+++ b/services/core/java/com/android/server/gpu/GpuService.java
@@ -64,7 +64,6 @@
 
     private static final String PROPERTY_GFX_DRIVER = "ro.gfx.driver.0";
     private static final String GAME_DRIVER_WHITELIST_FILENAME = "whitelist.txt";
-    private static final String GAME_DRIVER_SPHAL_LIBRARIES_FILENAME = "sphal_libraries.txt";
     private static final int BASE64_FLAGS = Base64.NO_PADDING | Base64.NO_WRAP;
 
     private final Context mContext;
@@ -230,9 +229,6 @@
         // Reset the whitelist.
         Settings.Global.putString(mContentResolver,
                                   Settings.Global.GAME_DRIVER_WHITELIST, "");
-        // Reset the sphal libraries
-        Settings.Global.putString(mContentResolver,
-                                  Settings.Global.GAME_DRIVER_SPHAL_LIBRARIES, "");
         mGameDriverVersionCode = driverInfo.longVersionCode;
 
         try {
@@ -241,10 +237,6 @@
 
             assetToSettingsGlobal(mContext, driverContext, GAME_DRIVER_WHITELIST_FILENAME,
                     Settings.Global.GAME_DRIVER_WHITELIST, ",");
-
-            assetToSettingsGlobal(mContext, driverContext, GAME_DRIVER_SPHAL_LIBRARIES_FILENAME,
-                    Settings.Global.GAME_DRIVER_SPHAL_LIBRARIES, ":");
-
         } catch (PackageManager.NameNotFoundException e) {
             if (DEBUG) {
                 Slog.w(TAG, "driver package '" + mDriverPackageName + "' not installed");
diff --git a/services/core/java/com/android/server/job/JobServiceContext.java b/services/core/java/com/android/server/job/JobServiceContext.java
index 7689bd2..65dac8b 100644
--- a/services/core/java/com/android/server/job/JobServiceContext.java
+++ b/services/core/java/com/android/server/job/JobServiceContext.java
@@ -247,10 +247,20 @@
             mVerb = VERB_BINDING;
             scheduleOpTimeOutLocked();
             final Intent intent = new Intent().setComponent(job.getServiceComponent());
-            boolean binding = mContext.bindServiceAsUser(intent, this,
-                    Context.BIND_AUTO_CREATE | Context.BIND_NOT_FOREGROUND
-                    | Context.BIND_NOT_VISIBLE | Context.BIND_ADJUST_BELOW_PERCEPTIBLE,
-                    new UserHandle(job.getUserId()));
+            boolean binding = false;
+            try {
+                binding = mContext.bindServiceAsUser(intent, this,
+                        Context.BIND_AUTO_CREATE | Context.BIND_NOT_FOREGROUND
+                        | Context.BIND_NOT_VISIBLE | Context.BIND_ADJUST_BELOW_PERCEPTIBLE,
+                        new UserHandle(job.getUserId()));
+            } catch (SecurityException e) {
+                // Some permission policy, for example INTERACT_ACROSS_USERS and
+                // android:singleUser, can result in a SecurityException being thrown from
+                // bindServiceAsUser().  If this happens, catch it and fail gracefully.
+                Slog.w(TAG, "Job service " + job.getServiceComponent().getShortClassName()
+                        + " cannot be executed: " + e.getMessage());
+                binding = false;
+            }
             if (!binding) {
                 if (DEBUG) {
                     Slog.d(TAG, job.getServiceComponent().getShortClassName() + " unavailable.");
diff --git a/services/core/java/com/android/server/location/GnssLocationProvider.java b/services/core/java/com/android/server/location/GnssLocationProvider.java
index f28bce5..e7636ae 100644
--- a/services/core/java/com/android/server/location/GnssLocationProvider.java
+++ b/services/core/java/com/android/server/location/GnssLocationProvider.java
@@ -937,7 +937,7 @@
             mGnssNavigationMessageProvider.onGpsEnabledChanged();
             mGnssBatchingProvider.enable();
             if (mGnssVisibilityControl != null) {
-                mGnssVisibilityControl.onGpsEnabledChanged(/* isEnabled= */true);
+                mGnssVisibilityControl.onGpsEnabledChanged(/* isEnabled= */ true);
             }
         } else {
             setGpsEnabled(false);
diff --git a/services/core/java/com/android/server/location/GnssVisibilityControl.java b/services/core/java/com/android/server/location/GnssVisibilityControl.java
index 65bd5c6..ea4f9c4 100644
--- a/services/core/java/com/android/server/location/GnssVisibilityControl.java
+++ b/services/core/java/com/android/server/location/GnssVisibilityControl.java
@@ -78,7 +78,6 @@
     private final Handler mHandler;
     private final Context mContext;
     private final GpsNetInitiatedHandler mNiHandler;
-    private final Notification mEmergencyLocationUserNotification;
 
     private boolean mIsGpsEnabled;
 
@@ -107,7 +106,6 @@
         mNiHandler = niHandler;
         mAppOps = mContext.getSystemService(AppOpsManager.class);
         mPackageManager = mContext.getPackageManager();
-        mEmergencyLocationUserNotification = createEmergencyLocationUserNotification(mContext);
 
         // Complete initialization as the first event to run in mHandler thread. After that,
         // all object state read/update events run in the mHandler thread.
@@ -153,7 +151,6 @@
     }
 
     private void handleInitialize() {
-        disableNfwLocationAccess(); // Disable until config properties are loaded.
         listenForProxyAppsPackageUpdates();
     }
 
@@ -263,25 +260,21 @@
         return false;
     }
 
-    private void handleGpsEnabledChanged(boolean isEnabled) {
-        if (DEBUG) Log.d(TAG, "handleGpsEnabledChanged, isEnabled: " + isEnabled);
-
-        if (mIsGpsEnabled == isEnabled) {
-            return;
+    private void handleGpsEnabledChanged(boolean isGpsEnabled) {
+        if (DEBUG) {
+            Log.d(TAG, "handleGpsEnabledChanged, mIsGpsEnabled: " + mIsGpsEnabled
+                    + ", isGpsEnabled: " + isGpsEnabled);
         }
 
-        mIsGpsEnabled = isEnabled;
+        // The proxy app list in the GNSS HAL needs to be configured if it restarts after
+        // a crash. So, update HAL irrespective of the previous GPS enabled state.
+        mIsGpsEnabled = isGpsEnabled;
         if (!mIsGpsEnabled) {
             disableNfwLocationAccess();
             return;
         }
 
-        // When GNSS was disabled, we already set the proxy app list to empty in GNSS HAL.
-        // Update only if the proxy app list is not empty.
-        String[] locationPermissionEnabledProxyApps = getLocationPermissionEnabledProxyApps();
-        if (locationPermissionEnabledProxyApps.length != 0) {
-            setNfwLocationAccessProxyAppsInGnssHal(locationPermissionEnabledProxyApps);
-        }
+        setNfwLocationAccessProxyAppsInGnssHal(getLocationPermissionEnabledProxyApps());
     }
 
     private void disableNfwLocationAccess() {
@@ -632,13 +625,15 @@
         }
 
         notificationManager.notifyAsUser(/* tag= */ null, /* notificationId= */ 0,
-                mEmergencyLocationUserNotification, UserHandle.ALL);
+                createEmergencyLocationUserNotification(mContext), UserHandle.ALL);
     }
 
     private static Notification createEmergencyLocationUserNotification(Context context) {
-        String firstLineText = context.getString(R.string.gpsNotifTitle);
-        String secondLineText =  context.getString(R.string.global_action_emergency);
-        String accessibilityServicesText = firstLineText + " (" + secondLineText + ")";
+        // NOTE: Do not reuse the returned notification object as it will not reflect
+        //       changes to notification text when the system language is changed.
+        final String firstLineText = context.getString(R.string.gpsNotifTitle);
+        final String secondLineText =  context.getString(R.string.global_action_emergency);
+        final String accessibilityServicesText = firstLineText + " (" + secondLineText + ")";
         return new Notification.Builder(context, SystemNotificationChannels.NETWORK_ALERTS)
                 .setSmallIcon(com.android.internal.R.drawable.stat_sys_gps_on)
                 .setWhen(0)
diff --git a/services/core/java/com/android/server/net/NetworkStatsFactory.java b/services/core/java/com/android/server/net/NetworkStatsFactory.java
index 473cc97..69efd02 100644
--- a/services/core/java/com/android/server/net/NetworkStatsFactory.java
+++ b/services/core/java/com/android/server/net/NetworkStatsFactory.java
@@ -263,10 +263,6 @@
         return stats;
     }
 
-    /**
-     * @deprecated Use NetworkStatsService#getDetailedUidStats which also accounts for
-     * VPN traffic
-     */
     public NetworkStats readNetworkStatsDetail() throws IOException {
         return readNetworkStatsDetail(UID_ALL, null, TAG_ALL, null);
     }
diff --git a/services/core/java/com/android/server/net/NetworkStatsRecorder.java b/services/core/java/com/android/server/net/NetworkStatsRecorder.java
index bdff500..a2e7e0c 100644
--- a/services/core/java/com/android/server/net/NetworkStatsRecorder.java
+++ b/services/core/java/com/android/server/net/NetworkStatsRecorder.java
@@ -41,10 +41,10 @@
 import com.android.internal.util.FileRotator;
 import com.android.internal.util.IndentingPrintWriter;
 
-import com.google.android.collect.Sets;
-
 import libcore.io.IoUtils;
 
+import com.google.android.collect.Sets;
+
 import java.io.ByteArrayOutputStream;
 import java.io.DataOutputStream;
 import java.io.File;
@@ -234,7 +234,7 @@
 
         if (vpnArray != null) {
             for (VpnInfo info : vpnArray) {
-                delta.migrateTun(info.ownerUid, info.vpnIface, info.underlyingIfaces);
+                delta.migrateTun(info.ownerUid, info.vpnIface, info.primaryUnderlyingIface);
             }
         }
 
diff --git a/services/core/java/com/android/server/net/NetworkStatsService.java b/services/core/java/com/android/server/net/NetworkStatsService.java
index a13368f..f34ace5 100644
--- a/services/core/java/com/android/server/net/NetworkStatsService.java
+++ b/services/core/java/com/android/server/net/NetworkStatsService.java
@@ -293,22 +293,6 @@
     /** Data layer operation counters for splicing into other structures. */
     private NetworkStats mUidOperations = new NetworkStats(0L, 10);
 
-    /**
-     * Snapshot containing most recent network stats for all UIDs across all interfaces and tags
-     * since boot.
-     *
-     * <p>Maintains migrated VPN stats which are result of performing TUN migration on {@link
-     * #mLastUidDetailSnapshot}.
-     */
-    @GuardedBy("mStatsLock")
-    private NetworkStats mTunAdjustedStats;
-    /**
-     * Used by {@link #mTunAdjustedStats} to migrate VPN traffic over delta between this snapshot
-     * and latest snapshot.
-     */
-    @GuardedBy("mStatsLock")
-    private NetworkStats mLastUidDetailSnapshot;
-
     /** Must be set in factory by calling #setHandler. */
     private Handler mHandler;
     private Handler.Callback mHandlerCallback;
@@ -828,39 +812,15 @@
     @Override
     public NetworkStats getDetailedUidStats(String[] requiredIfaces) {
         try {
-            // Get the latest snapshot from NetworkStatsFactory.
-            // TODO: Querying for INTERFACES_ALL may incur performance penalty. Consider restricting
-            // this to limited set of ifaces.
-            NetworkStats uidDetailStats = getNetworkStatsUidDetail(INTERFACES_ALL);
-
-            // Migrate traffic from VPN UID over delta and update mTunAdjustedStats.
-            NetworkStats result;
-            synchronized (mStatsLock) {
-                migrateTunTraffic(uidDetailStats, mVpnInfos);
-                result = mTunAdjustedStats.clone();
-            }
-
-            // Apply filter based on ifacesToQuery.
             final String[] ifacesToQuery =
                     NetworkStatsFactory.augmentWithStackedInterfaces(requiredIfaces);
-            result.filter(UID_ALL, ifacesToQuery, TAG_ALL);
-            return result;
+            return getNetworkStatsUidDetail(ifacesToQuery);
         } catch (RemoteException e) {
             Log.wtf(TAG, "Error compiling UID stats", e);
             return new NetworkStats(0L, 0);
         }
     }
 
-    @VisibleForTesting
-    NetworkStats getTunAdjustedStats() {
-        synchronized (mStatsLock) {
-            if (mTunAdjustedStats == null) {
-                return null;
-            }
-            return mTunAdjustedStats.clone();
-        }
-    }
-
     @Override
     public String[] getMobileIfaces() {
         return mMobileIfaces;
@@ -1335,34 +1295,6 @@
         // a race condition between the service handler thread and the observer's
         mStatsObservers.updateStats(xtSnapshot, uidSnapshot, new ArrayMap<>(mActiveIfaces),
                 new ArrayMap<>(mActiveUidIfaces), vpnArray, currentTime);
-
-        migrateTunTraffic(uidSnapshot, vpnArray);
-    }
-
-    /**
-     * Updates {@link #mTunAdjustedStats} with the delta containing traffic migrated off of VPNs.
-     */
-    @GuardedBy("mStatsLock")
-    private void migrateTunTraffic(NetworkStats uidDetailStats, VpnInfo[] vpnInfoArray) {
-        if (mTunAdjustedStats == null) {
-            // Either device booted or system server restarted, hence traffic cannot be migrated
-            // correctly without knowing the past state of VPN's underlying networks.
-            mTunAdjustedStats = uidDetailStats;
-            mLastUidDetailSnapshot = uidDetailStats;
-            return;
-        }
-        // Migrate delta traffic from VPN to other apps.
-        NetworkStats delta = uidDetailStats.subtract(mLastUidDetailSnapshot);
-        for (VpnInfo info : vpnInfoArray) {
-            delta.migrateTun(info.ownerUid, info.vpnIface, info.underlyingIfaces);
-        }
-        // Filter out debug entries as that may lead to over counting.
-        delta.filterDebugEntries();
-        // Update #mTunAdjustedStats with migrated delta.
-        mTunAdjustedStats.combineAllValues(delta);
-        mTunAdjustedStats.setElapsedRealtime(uidDetailStats.getElapsedRealtime());
-        // Update last snapshot.
-        mLastUidDetailSnapshot = uidDetailStats;
     }
 
     /**
diff --git a/services/core/java/com/android/server/notification/NotificationManagerService.java b/services/core/java/com/android/server/notification/NotificationManagerService.java
index 8485f46..82b16de 100644
--- a/services/core/java/com/android/server/notification/NotificationManagerService.java
+++ b/services/core/java/com/android/server/notification/NotificationManagerService.java
@@ -7234,72 +7234,42 @@
     @GuardedBy("mNotificationLock")
     private NotificationRankingUpdate makeRankingUpdateLocked(ManagedServiceInfo info) {
         final int N = mNotificationList.size();
-        ArrayList<String> keys = new ArrayList<String>(N);
-        ArrayList<String> interceptedKeys = new ArrayList<String>(N);
-        ArrayList<Integer> importance = new ArrayList<>(N);
-        Bundle overrideGroupKeys = new Bundle();
-        Bundle visibilityOverrides = new Bundle();
-        Bundle suppressedVisualEffects = new Bundle();
-        Bundle explanation = new Bundle();
-        Bundle channels = new Bundle();
-        Bundle overridePeople = new Bundle();
-        Bundle snoozeCriteria = new Bundle();
-        Bundle showBadge = new Bundle();
-        Bundle userSentiment = new Bundle();
-        Bundle hidden = new Bundle();
-        Bundle systemGeneratedSmartActions = new Bundle();
-        Bundle smartReplies = new Bundle();
-        Bundle lastAudiblyAlerted = new Bundle();
-        Bundle noisy = new Bundle();
-        ArrayList<Boolean> canBubble = new ArrayList<>(N);
+        final ArrayList<NotificationListenerService.Ranking> rankings = new ArrayList<>();
+
         for (int i = 0; i < N; i++) {
             NotificationRecord record = mNotificationList.get(i);
             if (!isVisibleToListener(record.sbn, info)) {
                 continue;
             }
             final String key = record.sbn.getKey();
-            keys.add(key);
-            importance.add(record.getImportance());
-            if (record.getImportanceExplanation() != null) {
-                explanation.putCharSequence(key, record.getImportanceExplanation());
-            }
-            if (record.isIntercepted()) {
-                interceptedKeys.add(key);
+            final NotificationListenerService.Ranking ranking =
+                    new NotificationListenerService.Ranking();
+            ranking.populate(
+                    key,
+                    rankings.size(),
+                    !record.isIntercepted(),
+                    record.getPackageVisibilityOverride(),
+                    record.getSuppressedVisualEffects(),
+                    record.getImportance(),
+                    record.getImportanceExplanation(),
+                    record.sbn.getOverrideGroupKey(),
+                    record.getChannel(),
+                    record.getPeopleOverride(),
+                    record.getSnoozeCriteria(),
+                    record.canShowBadge(),
+                    record.getUserSentiment(),
+                    record.isHidden(),
+                    record.getLastAudiblyAlertedMs(),
+                    record.getSound() != null || record.getVibration() != null,
+                    record.getSystemGeneratedSmartActions(),
+                    record.getSmartReplies(),
+                    record.canBubble()
+            );
+            rankings.add(ranking);
+        }
 
-            }
-            suppressedVisualEffects.putInt(key, record.getSuppressedVisualEffects());
-            if (record.getPackageVisibilityOverride()
-                    != NotificationListenerService.Ranking.VISIBILITY_NO_OVERRIDE) {
-                visibilityOverrides.putInt(key, record.getPackageVisibilityOverride());
-            }
-            overrideGroupKeys.putString(key, record.sbn.getOverrideGroupKey());
-            channels.putParcelable(key, record.getChannel());
-            overridePeople.putStringArrayList(key, record.getPeopleOverride());
-            snoozeCriteria.putParcelableArrayList(key, record.getSnoozeCriteria());
-            showBadge.putBoolean(key, record.canShowBadge());
-            userSentiment.putInt(key, record.getUserSentiment());
-            hidden.putBoolean(key, record.isHidden());
-            systemGeneratedSmartActions.putParcelableArrayList(key,
-                    record.getSystemGeneratedSmartActions());
-            smartReplies.putCharSequenceArrayList(key, record.getSmartReplies());
-            lastAudiblyAlerted.putLong(key, record.getLastAudiblyAlertedMs());
-            noisy.putBoolean(key, record.getSound() != null || record.getVibration() != null);
-            canBubble.add(record.canBubble());
-        }
-        final int M = keys.size();
-        String[] keysAr = keys.toArray(new String[M]);
-        String[] interceptedKeysAr = interceptedKeys.toArray(new String[interceptedKeys.size()]);
-        int[] importanceAr = new int[M];
-        boolean[] canBubbleAr = new boolean[M];
-        for (int i = 0; i < M; i++) {
-            importanceAr[i] = importance.get(i);
-            canBubbleAr[i] = canBubble.get(i);
-        }
-        return new NotificationRankingUpdate(keysAr, interceptedKeysAr, visibilityOverrides,
-                suppressedVisualEffects, importanceAr, explanation, overrideGroupKeys,
-                channels, overridePeople, snoozeCriteria, showBadge, userSentiment, hidden,
-                systemGeneratedSmartActions, smartReplies, lastAudiblyAlerted, noisy,
-                canBubbleAr);
+        return new NotificationRankingUpdate(
+                rankings.toArray(new NotificationListenerService.Ranking[0]));
     }
 
     boolean hasCompanionDevice(ManagedServiceInfo info) {
diff --git a/services/core/java/com/android/server/notification/PreferencesHelper.java b/services/core/java/com/android/server/notification/PreferencesHelper.java
index 1c0ac16..7b45a1b 100644
--- a/services/core/java/com/android/server/notification/PreferencesHelper.java
+++ b/services/core/java/com/android/server/notification/PreferencesHelper.java
@@ -78,7 +78,7 @@
     private static final String TAG_CHANNEL = "channel";
     private static final String TAG_GROUP = "channelGroup";
     private static final String TAG_DELEGATE = "delegate";
-    private static final String TAG_STATUS_ICONS = "status_icons";
+    private static final String TAG_STATUS_ICONS = "silent_status_icons";
 
     private static final String ATT_VERSION = "version";
     private static final String ATT_NAME = "name";
diff --git a/services/core/java/com/android/server/oemlock/PersistentDataBlockLock.java b/services/core/java/com/android/server/oemlock/PersistentDataBlockLock.java
index a1c27d6..2474b2aa 100644
--- a/services/core/java/com/android/server/oemlock/PersistentDataBlockLock.java
+++ b/services/core/java/com/android/server/oemlock/PersistentDataBlockLock.java
@@ -73,6 +73,10 @@
         // unlocked but doesn't actually do any unlocking.
         final PersistentDataBlockManager pdbm = (PersistentDataBlockManager)
                 mContext.getSystemService(Context.PERSISTENT_DATA_BLOCK_SERVICE);
+        if (pdbm == null) {
+            Slog.w(TAG, "PersistentDataBlock is not supported on this device");
+            return;
+        }
         pdbm.setOemUnlockEnabled(allowedByDevice);
     }
 
@@ -80,6 +84,10 @@
     boolean isOemUnlockAllowedByDevice() {
         final PersistentDataBlockManager pdbm = (PersistentDataBlockManager)
             mContext.getSystemService(Context.PERSISTENT_DATA_BLOCK_SERVICE);
+        if (pdbm == null) {
+            Slog.w(TAG, "PersistentDataBlock is not supported on this device");
+            return false;
+        }
         return pdbm.getOemUnlockEnabled();
     }
 
@@ -91,6 +99,10 @@
     private void disallowUnlockIfNotUnlocked() {
         final PersistentDataBlockManager pdbm = (PersistentDataBlockManager)
             mContext.getSystemService(Context.PERSISTENT_DATA_BLOCK_SERVICE);
+        if (pdbm == null) {
+            Slog.w(TAG, "PersistentDataBlock is not supported on this device");
+            return;
+        }
         if (pdbm.getFlashLockState() != PersistentDataBlockManager.FLASH_LOCK_UNLOCKED) {
             pdbm.setOemUnlockEnabled(false);
         }
diff --git a/services/core/java/com/android/server/om/IdmapManager.java b/services/core/java/com/android/server/om/IdmapManager.java
index 4b435de..b604aa8 100644
--- a/services/core/java/com/android/server/om/IdmapManager.java
+++ b/services/core/java/com/android/server/om/IdmapManager.java
@@ -58,9 +58,16 @@
 
     private static final boolean VENDOR_IS_Q_OR_LATER;
     static {
-        // STOPSHIP(b/119390857): Check api version once Q sdk version is finalized
-        final String value = SystemProperties.get("ro.vndk.version", "Q");
-        VENDOR_IS_Q_OR_LATER = value.equals("Q") || value.equals("q");
+        final String value = SystemProperties.get("ro.vndk.version", "29");
+        boolean isQOrLater;
+        try {
+            isQOrLater = Integer.parseInt(value) >= 29;
+        } catch (NumberFormatException e) {
+            // The version is not a number, therefore it is a development codename.
+            isQOrLater = true;
+        }
+
+        VENDOR_IS_Q_OR_LATER = isQOrLater;
     }
 
     IdmapManager(final Installer installer, final PackageManagerHelper packageManager) {
diff --git a/services/core/java/com/android/server/pm/Installer.java b/services/core/java/com/android/server/pm/Installer.java
index c2d5b2f8..adcd19e 100644
--- a/services/core/java/com/android/server/pm/Installer.java
+++ b/services/core/java/com/android/server/pm/Installer.java
@@ -121,24 +121,6 @@
         }
     }
 
-    @Override
-    public void onUnlockUser(int userId) {
-        if (userId == 0) {
-            if (!checkBeforeRemote()) return;
-
-            if (mInstalld == null) {
-                Slog.wtf(TAG, "Call to onUnlockUser prior to onStart.");
-                return;
-            }
-
-            try {
-                mInstalld.migrateLegacyObbData();
-            } catch (RemoteException re) {
-                Slog.wtf(TAG, "Error migrating legacy OBB data.", re);
-            }
-        }
-    }
-
     private void connect() {
         IBinder binder = ServiceManager.getService("installd");
         if (binder != null) {
@@ -708,6 +690,24 @@
         }
     }
 
+    /**
+     * Migrates obb data from its legacy location {@code /data/media/obb} to
+     * {@code /data/media/0/Android/obb}. This call is idempotent and a fast no-op if data has
+     * already been migrated.
+     *
+     * @throws InstallerException if an error occurs.
+     */
+    public boolean migrateLegacyObbData() throws InstallerException {
+        if (!checkBeforeRemote()) return false;
+
+        try {
+            mInstalld.migrateLegacyObbData();
+            return true;
+        } catch (Exception e) {
+            throw InstallerException.from(e);
+        }
+    }
+
     private static void assertValidInstructionSet(String instructionSet)
             throws InstallerException {
         for (String abi : Build.SUPPORTED_ABIS) {
diff --git a/services/core/java/com/android/server/pm/PackageInstallerService.java b/services/core/java/com/android/server/pm/PackageInstallerService.java
index bd88594..0032e9a 100644
--- a/services/core/java/com/android/server/pm/PackageInstallerService.java
+++ b/services/core/java/com/android/server/pm/PackageInstallerService.java
@@ -617,7 +617,9 @@
             mStagingManager.createSession(session);
         }
 
-        mCallbacks.notifySessionCreated(session.sessionId, session.userId);
+        if ((session.params.installFlags & PackageManager.INSTALL_DRY_RUN) == 0) {
+            mCallbacks.notifySessionCreated(session.sessionId, session.userId);
+        }
         writeSessionsAsync();
         return sessionId;
     }
@@ -1210,16 +1212,25 @@
 
     class InternalCallback {
         public void onSessionBadgingChanged(PackageInstallerSession session) {
-            mCallbacks.notifySessionBadgingChanged(session.sessionId, session.userId);
+            if ((session.params.installFlags & PackageManager.INSTALL_DRY_RUN) == 0) {
+                mCallbacks.notifySessionBadgingChanged(session.sessionId, session.userId);
+            }
+
             writeSessionsAsync();
         }
 
         public void onSessionActiveChanged(PackageInstallerSession session, boolean active) {
-            mCallbacks.notifySessionActiveChanged(session.sessionId, session.userId, active);
+            if ((session.params.installFlags & PackageManager.INSTALL_DRY_RUN) == 0) {
+                mCallbacks.notifySessionActiveChanged(session.sessionId, session.userId,
+                        active);
+            }
         }
 
         public void onSessionProgressChanged(PackageInstallerSession session, float progress) {
-            mCallbacks.notifySessionProgressChanged(session.sessionId, session.userId, progress);
+            if ((session.params.installFlags & PackageManager.INSTALL_DRY_RUN) == 0) {
+                mCallbacks.notifySessionProgressChanged(session.sessionId, session.userId,
+                        progress);
+            }
         }
 
         public void onStagedSessionChanged(PackageInstallerSession session) {
@@ -1232,7 +1243,9 @@
         }
 
         public void onSessionFinished(final PackageInstallerSession session, boolean success) {
-            mCallbacks.notifySessionFinished(session.sessionId, session.userId, success);
+            if ((session.params.installFlags & PackageManager.INSTALL_DRY_RUN) == 0) {
+                mCallbacks.notifySessionFinished(session.sessionId, session.userId, success);
+            }
 
             mInstallHandler.post(new Runnable() {
                 @Override
diff --git a/services/core/java/com/android/server/pm/PackageManagerService.java b/services/core/java/com/android/server/pm/PackageManagerService.java
index a116237..4d84048 100644
--- a/services/core/java/com/android/server/pm/PackageManagerService.java
+++ b/services/core/java/com/android/server/pm/PackageManagerService.java
@@ -2578,9 +2578,7 @@
             mIsPreNUpgrade = mIsUpgrade && ver.sdkVersion < Build.VERSION_CODES.N;
 
             mIsPreNMR1Upgrade = mIsUpgrade && ver.sdkVersion < Build.VERSION_CODES.N_MR1;
-            mIsPreQUpgrade = mIsUpgrade && ver.sdkVersion < Build.VERSION_CODES.Q
-                    // STOPSHIP: Remove next line when API level for Q is defined.
-                    && Build.VERSION.SDK_INT > Build.VERSION_CODES.P;
+            mIsPreQUpgrade = mIsUpgrade && ver.sdkVersion < Build.VERSION_CODES.Q;
 
             int preUpgradeSdkVersion = ver.sdkVersion;
 
@@ -5645,27 +5643,6 @@
             for (int i = 0; pkg == null && i < N; i++) {
                 pkg = mPackages.get(packageNames[i]);
             }
-            // Additional logs for b/111075456; ignore system UIDs
-            if (pkg == null && UserHandle.getAppId(uid) >= Process.FIRST_APPLICATION_UID) {
-                if (packageNames == null || packageNames.length < 2) {
-                    // unclear if this is shared user or just a missing application
-                    Log.e(TAG, "Failed to find package"
-                            + "; permName: " + permName
-                            + ", uid: " + uid
-                            + ", caller: " + Binder.getCallingUid(),
-                            new Throwable());
-                } else {
-                    // definitely shared user
-                    Log.e(TAG, "Failed to find package"
-                            + "; permName: " + permName
-                            + ", uid: " + uid
-                            + ", caller: " + Binder.getCallingUid()
-                            + ", packages: " + Arrays.toString(packageNames),
-                            new Throwable());
-                }
-                // run again just to try to get debug output
-                getPackagesForUid_debug(uid, true);
-            }
             return mPermissionManager.checkUidPermission(permName, pkg, uid, getCallingUid());
         }
     }
@@ -6393,25 +6370,15 @@
      */
     @Override
     public String[] getPackagesForUid(int uid) {
-        return getPackagesForUid_debug(uid, false);
-    }
-    // Debug output for b/111075456
-    private String[] getPackagesForUid_debug(int uid, boolean debug) {
         final int callingUid = Binder.getCallingUid();
         final boolean isCallerInstantApp = getInstantAppPackageName(callingUid) != null;
         final int userId = UserHandle.getUserId(uid);
         final int appId = UserHandle.getAppId(uid);
-        if (debug) Slog.e(TAG, "Finding packages for UID"
-                + "; uid: " + uid
-                + ", userId: " + userId
-                + ", appId: " + appId
-                + ", caller: " + callingUid);
         // reader
         synchronized (mPackages) {
             final Object obj = mSettings.getSettingLPr(appId);
             if (obj instanceof SharedUserSetting) {
                 if (isCallerInstantApp) {
-                    if (debug) Slog.e(TAG, "Caller is instant and package has shared users");
                     return null;
                 }
                 final SharedUserSetting sus = (SharedUserSetting) obj;
@@ -6419,13 +6386,8 @@
                 String[] res = new String[N];
                 final Iterator<PackageSetting> it = sus.packages.iterator();
                 int i = 0;
-                if (debug && !it.hasNext()) Slog.e(TAG, "Shared user, but, no packages");
                 while (it.hasNext()) {
                     PackageSetting ps = it.next();
-                    if (debug) Slog.e(TAG, "Check shared package"
-                            + "; installed? " + ps.getInstalled(userId)
-                            + ", shared setting: " + ps
-                            + ", package setting: " + mSettings.mPackages.get(ps.name));
                     if (ps.getInstalled(userId)) {
                         res[i++] = ps.name;
                     } else {
@@ -6438,12 +6400,6 @@
                 if (ps.getInstalled(userId) && !filterAppAccessLPr(ps, callingUid, userId)) {
                     return new String[]{ps.name};
                 }
-                if (debug) Slog.e(TAG, "Removing normal package"
-                        + "; installed? " + ps.getInstalled(userId)
-                        + ", filtered? " + filterAppAccessLPr(ps, callingUid, userId));
-            } else if (debug) {
-                if (debug) Slog.e(TAG, "No setting found"
-                        + "; obj: " + (obj == null ? "<<NULL>>" : obj.toString()));
             }
         }
         return null;
@@ -15014,7 +14970,6 @@
                 params.handleStartCopy();
                 if (params.mRet != INSTALL_SUCCEEDED) {
                     mRet = params.mRet;
-                    break;
                 }
             }
         }
@@ -15025,7 +14980,6 @@
                 params.handleReturnCode();
                 if (params.mRet != INSTALL_SUCCEEDED) {
                     mRet = params.mRet;
-                    break;
                 }
             }
         }
@@ -15565,6 +15519,22 @@
         @Override
         void handleReturnCode() {
             if (mVerificationCompleted && mEnableRollbackCompleted) {
+                if ((installFlags & PackageManager.INSTALL_DRY_RUN) != 0) {
+                    String packageName = "";
+                    try {
+                        PackageLite packageInfo =
+                                new PackageParser().parsePackageLite(origin.file, 0);
+                        packageName = packageInfo.packageName;
+                    } catch (PackageParserException e) {
+                        Slog.e(TAG, "Can't parse package at " + origin.file.getAbsolutePath(), e);
+                    }
+                    try {
+                        observer.onPackageInstalled(packageName, mRet, "Dry run", new Bundle());
+                    } catch (RemoteException e) {
+                        Slog.i(TAG, "Observer no longer exists.");
+                    }
+                    return;
+                }
                 if (mRet == PackageManager.INSTALL_SUCCEEDED) {
                     mRet = mArgs.copyApk();
                 }
@@ -18036,9 +18006,15 @@
                 if (Build.IS_DEBUGGABLE) Slog.i(TAG, "Enabling verity to " + filePath);
                 final FileDescriptor fd = result.getUnownedFileDescriptor();
                 try {
-                    mInstaller.installApkVerity(filePath, fd, result.getContentSize());
                     final byte[] rootHash = VerityUtils.generateApkVerityRootHash(filePath);
-                    mInstaller.assertFsverityRootHashMatches(filePath, rootHash);
+                    try {
+                        // A file may already have fs-verity, e.g. when reused during a split
+                        // install. If the measurement succeeds, no need to attempt to set up.
+                        mInstaller.assertFsverityRootHashMatches(filePath, rootHash);
+                    } catch (InstallerException e) {
+                        mInstaller.installApkVerity(filePath, fd, result.getContentSize());
+                        mInstaller.assertFsverityRootHashMatches(filePath, rootHash);
+                    }
                 } finally {
                     IoUtils.closeQuietly(fd);
                 }
@@ -24945,6 +24921,15 @@
                 mSettings.setRuntimePermissionsFingerPrintLPr(fingerPrint, userId);
             }
         }
+
+        @Override
+        public void migrateLegacyObbData() {
+            try {
+                mInstaller.migrateLegacyObbData();
+            } catch (Exception e) {
+                Slog.wtf(TAG, e);
+            }
+        }
     }
 
     @GuardedBy("mPackages")
diff --git a/services/core/java/com/android/server/pm/StagingManager.java b/services/core/java/com/android/server/pm/StagingManager.java
index 950450c..9c87c74 100644
--- a/services/core/java/com/android/server/pm/StagingManager.java
+++ b/services/core/java/com/android/server/pm/StagingManager.java
@@ -57,6 +57,7 @@
 import java.util.List;
 import java.util.concurrent.LinkedBlockingQueue;
 import java.util.concurrent.TimeUnit;
+import java.util.function.Predicate;
 import java.util.stream.Collectors;
 
 /**
@@ -201,10 +202,6 @@
     private void preRebootVerification(@NonNull PackageInstallerSession session) {
         boolean success = true;
 
-        // STOPSHIP: TODO(b/123753157): Verify APKs through Package Verifier.
-        // TODO: Decide whether we want to fail fast by detecting signature mismatches for APKs,
-        // right away.
-
         final ApexInfoList apexInfoList = new ApexInfoList();
         // APEX checks. For single-package sessions, check if they contain an APEX. For
         // multi-package sessions, find all the child sessions that contain an APEX.
@@ -230,6 +227,16 @@
             return;
         }
 
+        if (sessionContainsApk(session)) {
+            if (!installApksInSession(session, /* preReboot */ true)) {
+                session.setStagedSessionFailed(SessionInfo.STAGED_SESSION_VERIFICATION_FAILED,
+                        "APK verification failed. Check logcat messages for "
+                                + "more information.");
+                // TODO(b/118865310): abort the session on apexd.
+                return;
+            }
+        }
+
         if (apexInfoList.apexInfos != null && apexInfoList.apexInfos.length > 0) {
             // For APEXes, we validate the signature here before we mark the session as ready,
             // so we fail the session early if there is a signature mismatch. For APKs, the
@@ -275,21 +282,31 @@
         }
     }
 
-    private boolean sessionContainsApex(@NonNull PackageInstallerSession session) {
+
+    private boolean sessionContains(@NonNull PackageInstallerSession session,
+                                    Predicate<PackageInstallerSession> filter) {
         if (!session.isMultiPackage()) {
-            return isApexSession(session);
+            return filter.test(session);
         }
         synchronized (mStagedSessions) {
             return !(Arrays.stream(session.getChildSessionIds())
                     // Retrieve cached sessions matching ids.
                     .mapToObj(i -> mStagedSessions.get(i))
                     // Filter only the ones containing APEX.
-                    .filter(childSession -> isApexSession(childSession))
+                    .filter(childSession -> filter.test(childSession))
                     .collect(Collectors.toList())
                     .isEmpty());
         }
     }
 
+    private boolean sessionContainsApex(@NonNull PackageInstallerSession session) {
+        return sessionContains(session, (s) -> isApexSession(s));
+    }
+
+    private boolean sessionContainsApk(@NonNull PackageInstallerSession session) {
+        return sessionContains(session, (s) -> !isApexSession(s));
+    }
+
     private void resumeSession(@NonNull PackageInstallerSession session) {
         boolean hasApex = sessionContainsApex(session);
         if (hasApex) {
@@ -326,7 +343,7 @@
             }
         }
         // The APEX part of the session is activated, proceed with the installation of APKs.
-        if (!installApksInSession(session)) {
+        if (!installApksInSession(session, /* preReboot */ false)) {
             session.setStagedSessionFailed(SessionInfo.STAGED_SESSION_ACTIVATION_FAILED,
                     "Staged installation of APKs failed. Check logcat messages for"
                         + "more information.");
@@ -343,7 +360,6 @@
                                 + "to the previous state of APEXd.");
                 mPowerManager.reboot(null);
             }
-
             return;
         }
 
@@ -366,7 +382,7 @@
     }
 
     private PackageInstallerSession createAndWriteApkSession(
-            @NonNull PackageInstallerSession originalSession) {
+            @NonNull PackageInstallerSession originalSession, boolean preReboot) {
         if (originalSession.stageDir == null) {
             Slog.wtf(TAG, "Attempting to install a staged APK session with no staging dir");
             return null;
@@ -379,9 +395,14 @@
 
         PackageInstaller.SessionParams params = originalSession.params.copy();
         params.isStaged = false;
-        params.installFlags |= PackageManager.INSTALL_DISABLE_VERIFICATION;
         params.installFlags |= PackageManager.INSTALL_STAGED;
         // TODO(b/129744602): use the userid from the original session.
+        if (preReboot) {
+            params.installFlags &= ~PackageManager.INSTALL_ENABLE_ROLLBACK;
+            params.installFlags |= PackageManager.INSTALL_DRY_RUN;
+        } else {
+            params.installFlags |= PackageManager.INSTALL_DISABLE_VERIFICATION;
+        }
         int apkSessionId = mPi.createSession(
                 params, originalSession.getInstallerPackageName(),
                 0 /* UserHandle.SYSTEM */);
@@ -408,17 +429,19 @@
     }
 
     private boolean commitApkSession(@NonNull PackageInstallerSession apkSession,
-                                     int originalSessionId) {
+                                     int originalSessionId, boolean preReboot) {
 
-        if ((apkSession.params.installFlags & PackageManager.INSTALL_ENABLE_ROLLBACK) != 0) {
-            // If rollback is available for this session, notify the rollback
-            // manager of the apk session so it can properly enable rollback.
-            final IRollbackManager rm = IRollbackManager.Stub.asInterface(
-                    ServiceManager.getService(Context.ROLLBACK_SERVICE));
-            try {
-                rm.notifyStagedApkSession(originalSessionId, apkSession.sessionId);
-            } catch (RemoteException re) {
-                // Cannot happen, the rollback manager is in the same process.
+        if (!preReboot) {
+            if ((apkSession.params.installFlags & PackageManager.INSTALL_ENABLE_ROLLBACK) != 0) {
+                // If rollback is available for this session, notify the rollback
+                // manager of the apk session so it can properly enable rollback.
+                final IRollbackManager rm = IRollbackManager.Stub.asInterface(
+                        ServiceManager.getService(Context.ROLLBACK_SERVICE));
+                try {
+                    rm.notifyStagedApkSession(originalSessionId, apkSession.sessionId);
+                } catch (RemoteException re) {
+                    // Cannot happen, the rollback manager is in the same process.
+                }
             }
         }
 
@@ -435,14 +458,15 @@
         return false;
     }
 
-    private boolean installApksInSession(@NonNull PackageInstallerSession session) {
+    private boolean installApksInSession(@NonNull PackageInstallerSession session,
+                                         boolean preReboot) {
         if (!session.isMultiPackage() && !isApexSession(session)) {
             // APK single-packaged staged session. Do a regular install.
-            PackageInstallerSession apkSession = createAndWriteApkSession(session);
+            PackageInstallerSession apkSession = createAndWriteApkSession(session, preReboot);
             if (apkSession == null) {
                 return false;
             }
-            return commitApkSession(apkSession, session.sessionId);
+            return commitApkSession(apkSession, session.sessionId, preReboot);
         } else if (session.isMultiPackage()) {
             // For multi-package staged sessions containing APKs, we identify which child sessions
             // contain an APK, and with those then create a new multi-package group of sessions,
@@ -464,6 +488,9 @@
             }
             PackageInstaller.SessionParams params = session.params.copy();
             params.isStaged = false;
+            if (preReboot) {
+                params.installFlags &= ~PackageManager.INSTALL_ENABLE_ROLLBACK;
+            }
             // TODO(b/129744602): use the userid from the original session.
             int apkParentSessionId = mPi.createSession(
                     params, session.getInstallerPackageName(),
@@ -478,7 +505,8 @@
             }
 
             for (PackageInstallerSession sessionToClone : childSessions) {
-                PackageInstallerSession apkChildSession = createAndWriteApkSession(sessionToClone);
+                PackageInstallerSession apkChildSession =
+                        createAndWriteApkSession(sessionToClone, preReboot);
                 if (apkChildSession == null) {
                     return false;
                 }
@@ -489,7 +517,7 @@
                     return false;
                 }
             }
-            return commitApkSession(apkParentSession, session.sessionId);
+            return commitApkSession(apkParentSession, session.sessionId, preReboot);
         }
         // APEX single-package staged session, nothing to do.
         return true;
diff --git a/services/core/java/com/android/server/pm/permission/PermissionManagerService.java b/services/core/java/com/android/server/pm/permission/PermissionManagerService.java
index 267fbf0..4edd9ef 100644
--- a/services/core/java/com/android/server/pm/permission/PermissionManagerService.java
+++ b/services/core/java/com/android/server/pm/permission/PermissionManagerService.java
@@ -97,6 +97,7 @@
 import com.android.server.pm.UserManagerService;
 import com.android.server.pm.permission.PermissionManagerServiceInternal.PermissionCallback;
 import com.android.server.pm.permission.PermissionsState.PermissionState;
+import com.android.server.policy.SoftRestrictedPermissionPolicy;
 
 import libcore.util.EmptyArray;
 
@@ -1173,6 +1174,14 @@
                                     }
                                 }
 
+                                if (hardRestricted && !restrictionExempt
+                                        && (flags & FLAG_PERMISSION_SYSTEM_FIXED) != 0) {
+                                    // Applying a hard restriction implies revoking it. This might
+                                    // lead to a system-fixed, revoked permission.
+                                    flags &= ~FLAG_PERMISSION_SYSTEM_FIXED;
+                                    wasChanged = true;
+                                }
+
                                 if (wasChanged) {
                                     updatedUserIds = ArrayUtils.appendInt(updatedUserIds, userId);
                                 }
@@ -2113,11 +2122,18 @@
 
         if (bp.isHardRestricted()
                 && (flags & PackageManager.FLAGS_PERMISSION_RESTRICTION_ANY_EXEMPT) == 0) {
-            Log.e(TAG, "Cannot grant restricted non-exempt permission "
+            Log.e(TAG, "Cannot grant hard restricted non-exempt permission "
                     + permName + " for package " + packageName);
             return;
         }
 
+        if (bp.isSoftRestricted() && !SoftRestrictedPermissionPolicy.forPermission(mContext,
+                pkg.applicationInfo, permName).canBeGranted()) {
+            Log.e(TAG, "Cannot grant soft restricted permission " + permName + " for package "
+                    + packageName);
+            return;
+        }
+
         if (bp.isDevelopment()) {
             // Development permissions must be handled specially, since they are not
             // normal runtime permissions.  For now they apply to all users.
diff --git a/services/core/java/com/android/server/policy/PermissionPolicyService.java b/services/core/java/com/android/server/policy/PermissionPolicyService.java
index a799cd9..6882afb 100644
--- a/services/core/java/com/android/server/policy/PermissionPolicyService.java
+++ b/services/core/java/com/android/server/policy/PermissionPolicyService.java
@@ -16,10 +16,15 @@
 
 package com.android.server.policy;
 
+import static android.app.AppOpsManager.MODE_ALLOWED;
+import static android.app.AppOpsManager.MODE_DEFAULT;
+import static android.app.AppOpsManager.MODE_ERRORED;
+import static android.app.AppOpsManager.MODE_FOREGROUND;
+import static android.app.AppOpsManager.MODE_IGNORED;
+import static android.app.AppOpsManager.OP_NONE;
 import static android.content.pm.PackageManager.FLAG_PERMISSION_APPLY_RESTRICTION;
 import static android.content.pm.PackageManager.GET_PERMISSIONS;
 
-import android.Manifest;
 import android.annotation.NonNull;
 import android.annotation.Nullable;
 import android.annotation.UserIdInt;
@@ -286,7 +291,7 @@
          *
          * Currently, only used by the restricted permissions logic.
          *
-         * @see #syncRestrictedOps
+         * @see #syncPackages
          */
         private final @NonNull ArrayList<OpToRestrict> mOpsToDefault = new ArrayList<>();
 
@@ -295,16 +300,14 @@
          *
          * Currently, only used by the restricted permissions logic.
          *
-         * @see #syncRestrictedOps
+         * @see #syncPackages
          */
         private final @NonNull ArrayList<OpToUnrestrict> mOpsToAllowIfDefault = new ArrayList<>();
 
         /**
          * All ops that need to be flipped to allow.
          *
-         * Currently, only used by the restricted permissions logic.
-         *
-         * @see #syncRestrictedOps
+         * @see #syncPackages
          */
         private final @NonNull ArrayList<OpToUnrestrict> mOpsToAllow = new ArrayList<>();
 
@@ -313,16 +316,25 @@
          *
          * Currently, only used by the restricted permissions logic.
          *
-         * @see #syncRestrictedOps
+         * @see #syncPackages
          */
         private final @NonNull ArrayList<OpToUnrestrict> mOpsToIgnoreIfDefault = new ArrayList<>();
 
         /**
-         * All foreground permissions
+         * All ops that need to be flipped to ignore.
          *
-         * @see #syncOpsOfFgPermissions()
+         * @see #syncPackages
          */
-        private final @NonNull ArrayList<FgPermission> mFgPermOps = new ArrayList<>();
+        private final @NonNull ArrayList<OpToUnrestrict> mOpsToIgnore = new ArrayList<>();
+
+        /**
+         * All ops that need to be flipped to foreground.
+         *
+         * Currently, only used by the foreground/background permissions logic.
+         *
+         * @see #syncPackages
+         */
+        private final @NonNull ArrayList<OpToUnrestrict> mOpsToForeground = new ArrayList<>();
 
         PermissionToOpSynchroniser(@NonNull Context context) {
             mContext = context;
@@ -331,11 +343,11 @@
         }
 
         /**
-         * Set app ops that belong to restricted permissions.
+         * Set app ops that were added in {@link #addPackage}.
          *
          * <p>This processes ops previously added by {@link #addOpIfRestricted}
          */
-        private void syncRestrictedOps() {
+        private void syncPackages() {
             final int allowCount = mOpsToAllow.size();
             for (int i = 0; i < allowCount; i++) {
                 final OpToUnrestrict op = mOpsToAllow.get(i);
@@ -346,6 +358,16 @@
                 final OpToUnrestrict op = mOpsToAllowIfDefault.get(i);
                 setUidModeAllowedIfDefault(op.code, op.uid, op.packageName);
             }
+            final int foregroundCount = mOpsToForeground.size();
+            for (int i = 0; i < foregroundCount; i++) {
+                final OpToUnrestrict op = mOpsToForeground.get(i);
+                setUidModeForeground(op.code, op.uid);
+            }
+            final int ignoreCount = mOpsToIgnore.size();
+            for (int i = 0; i < ignoreCount; i++) {
+                final OpToUnrestrict op = mOpsToIgnore.get(i);
+                setUidModeIgnored(op.code, op.uid);
+            }
             final int ignoreIfDefaultCount = mOpsToIgnoreIfDefault.size();
             for (int i = 0; i < ignoreIfDefaultCount; i++) {
                 final OpToUnrestrict op = mOpsToIgnoreIfDefault.get(i);
@@ -359,46 +381,8 @@
         }
 
         /**
-         * Set app ops that belong to restricted permissions.
-         *
-         * <p>This processed ops previously added by {@link #addOpIfRestricted}
-         */
-        private void syncOpsOfFgPermissions() {
-            int numFgPermOps = mFgPermOps.size();
-            for (int i = 0; i < numFgPermOps; i++) {
-                FgPermission perm = mFgPermOps.get(i);
-
-                if (mPackageManager.checkPermission(perm.fgPermissionName, perm.packageName)
-                        == PackageManager.PERMISSION_GRANTED) {
-                    if (mPackageManager.checkPermission(perm.bgPermissionName, perm.packageName)
-                            == PackageManager.PERMISSION_GRANTED) {
-                        mAppOpsManager.setUidMode(
-                                AppOpsManager.permissionToOpCode(perm.fgPermissionName), perm.uid,
-                                AppOpsManager.MODE_ALLOWED);
-                    } else {
-                        mAppOpsManager.setUidMode(
-                                AppOpsManager.permissionToOpCode(perm.fgPermissionName), perm.uid,
-                                AppOpsManager.MODE_FOREGROUND);
-                    }
-                } else {
-                    mAppOpsManager.setUidMode(
-                            AppOpsManager.permissionToOpCode(perm.fgPermissionName), perm.uid,
-                            AppOpsManager.MODE_IGNORED);
-                }
-            }
-        }
-
-        /**
-         * Synchronize all previously {@link #addPackage added} packages.
-         */
-        void syncPackages() {
-            syncRestrictedOps();
-            syncOpsOfFgPermissions();
-        }
-
-        /**
          * Add op that belong to a restricted permission for later processing in
-         * {@link #syncRestrictedOps}.
+         * {@link #syncPackages()}.
          *
          * <p>Note: Called with the package lock held. Do <u>not</u> call into app-op manager.
          *
@@ -420,44 +404,114 @@
                     mContext.getUser()) & FLAG_PERMISSION_APPLY_RESTRICTION) != 0;
 
             if (permissionInfo.isHardRestricted()) {
-                if (applyRestriction) {
-                    mOpsToDefault.add(new OpToRestrict(uid, opCode));
-                } else {
-                    mOpsToAllowIfDefault.add(new OpToUnrestrict(uid, pkg.packageName, opCode));
+                if (opCode != OP_NONE) {
+                    if (applyRestriction) {
+                        mOpsToDefault.add(new OpToRestrict(uid, opCode));
+                    } else {
+                        mOpsToAllowIfDefault.add(new OpToUnrestrict(uid, pkg.packageName, opCode));
+                    }
                 }
             } else if (permissionInfo.isSoftRestricted()) {
-                // Storage uses a special app op to decide the mount state and
-                // supports soft restriction where the restricted state allows
-                // the permission but only for accessing the medial collections.
-                if (Manifest.permission.READ_EXTERNAL_STORAGE.equals(permission)
-                        || Manifest.permission.WRITE_EXTERNAL_STORAGE.equals(permission)) {
-                    if (applyRestriction) {
-                        mOpsToDefault.add(new OpToRestrict(uid,
-                                AppOpsManager.OP_LEGACY_STORAGE));
-                    } else if (pkg.applicationInfo.hasRequestedLegacyExternalStorage()) {
-                        mOpsToAllow.add(new OpToUnrestrict(uid, pkg.packageName,
-                                AppOpsManager.OP_LEGACY_STORAGE));
+                final SoftRestrictedPermissionPolicy policy =
+                        SoftRestrictedPermissionPolicy.forPermission(mContext, pkg.applicationInfo,
+                                permission);
+
+                if (opCode != OP_NONE) {
+                    if (policy.canBeGranted()) {
+                        mOpsToAllowIfDefault.add(new OpToUnrestrict(uid, pkg.packageName, opCode));
                     } else {
-                        mOpsToIgnoreIfDefault.add(new OpToUnrestrict(uid, pkg.packageName,
-                                AppOpsManager.OP_LEGACY_STORAGE));
+                        mOpsToDefault.add(new OpToRestrict(uid, opCode));
+                    }
+                }
+
+                final int op = policy.resolveAppOp();
+                if (op != OP_NONE) {
+                    switch (policy.getDesiredOpMode()) {
+                        case MODE_DEFAULT:
+                            mOpsToDefault.add(new OpToRestrict(uid, op));
+                            break;
+                        case MODE_ALLOWED:
+                            if (policy.shouldSetAppOpIfNotDefault()) {
+                                mOpsToAllow.add(new OpToUnrestrict(uid, pkg.packageName, op));
+                            } else {
+                                mOpsToAllowIfDefault.add(
+                                        new OpToUnrestrict(uid, pkg.packageName,
+                                                op));
+                            }
+                            break;
+                        case MODE_FOREGROUND:
+                            Slog.wtf(LOG_TAG,
+                                    "Setting appop to foreground is not implemented");
+                            break;
+                        case MODE_IGNORED:
+                            if (policy.shouldSetAppOpIfNotDefault()) {
+                                mOpsToIgnore.add(new OpToUnrestrict(uid, pkg.packageName, op));
+                            } else {
+                                mOpsToIgnoreIfDefault.add(
+                                        new OpToUnrestrict(uid, pkg.packageName,
+                                                op));
+                            }
+                            break;
+                        case MODE_ERRORED:
+                            Slog.wtf(LOG_TAG, "Setting appop to errored is not implemented");
                     }
                 }
             }
         }
 
+        /**
+         * Add op that belong to a foreground permission for later processing in
+         * {@link #syncPackages()}.
+         *
+         * <p>Note: Called with the package lock held. Do <u>not</u> call into app-op manager.
+         *
+         * @param permissionInfo The permission that is currently looked at
+         * @param pkg The package looked at
+         */
         private void addOpIfFgPermissions(@NonNull PermissionInfo permissionInfo,
                 @NonNull PackageInfo pkg) {
-            if (pkg.applicationInfo.targetSdkVersion < Build.VERSION_CODES.M) {
-                // Pre-M apps do not store their fg/bg state in the permissions
+            final String bgPermissionName = permissionInfo.backgroundPermission;
+
+            if (bgPermissionName == null) {
                 return;
             }
 
-            if (permissionInfo.backgroundPermission == null) {
-                return;
-            }
+            final String permission = permissionInfo.name;
+            final int opCode = AppOpsManager.permissionToOpCode(permission);
+            final String pkgName = pkg.packageName;
+            final int uid = pkg.applicationInfo.uid;
 
-            mFgPermOps.add(new FgPermission(pkg.applicationInfo.uid, pkg.packageName,
-                    permissionInfo.name, permissionInfo.backgroundPermission));
+            if (mPackageManager.checkPermission(permission, pkgName)
+                    == PackageManager.PERMISSION_GRANTED) {
+                boolean isBgHardRestricted = false;
+                try {
+                    final PermissionInfo bgPermInfo = mPackageManager.getPermissionInfo(
+                            bgPermissionName, 0);
+
+                    if (bgPermInfo.isSoftRestricted()) {
+                        Slog.wtf(LOG_TAG, "Support for soft restricted background permissions not "
+                                + "implemented");
+                    }
+
+                    isBgHardRestricted =
+                            bgPermInfo.isHardRestricted() && (mPackageManager.getPermissionFlags(
+                                    bgPermissionName, pkgName, UserHandle.getUserHandleForUid(uid))
+                                    & FLAG_PERMISSION_APPLY_RESTRICTION) != 0;
+                } catch (NameNotFoundException e) {
+                    Slog.w(LOG_TAG, "Cannot read permission state of " + bgPermissionName, e);
+                }
+
+                final boolean isBgPermGranted = mPackageManager.checkPermission(bgPermissionName,
+                        pkgName) == PackageManager.PERMISSION_GRANTED;
+
+                if (!isBgHardRestricted && isBgPermGranted) {
+                    mOpsToAllow.add(new OpToUnrestrict(uid, pkgName, opCode));
+                } else {
+                    mOpsToForeground.add(new OpToUnrestrict(uid, pkgName, opCode));
+                }
+            } else {
+                mOpsToIgnore.add(new OpToUnrestrict(uid, pkgName, opCode));
+            }
         }
 
         /**
@@ -483,7 +537,7 @@
 
             for (String permission : pkg.requestedPermissions) {
                 final int opCode = AppOpsManager.permissionToOpCode(permission);
-                if (opCode == AppOpsManager.OP_NONE) {
+                if (opCode == OP_NONE) {
                     continue;
                 }
 
@@ -507,21 +561,40 @@
             mAppOpsManager.setUidMode(opCode, uid, AppOpsManager.MODE_ALLOWED);
         }
 
+        private void setUidModeForeground(int opCode, int uid) {
+            mAppOpsManager.setUidMode(opCode, uid, AppOpsManager.MODE_FOREGROUND);
+        }
+
         private void setUidModeIgnoredIfDefault(int opCode, int uid, @NonNull String packageName) {
             setUidModeIfDefault(opCode, uid, AppOpsManager.MODE_IGNORED, packageName);
         }
 
+        private void setUidModeIgnored(int opCode, int uid) {
+            mAppOpsManager.setUidMode(opCode, uid, MODE_IGNORED);
+        }
+
         private void setUidModeIfDefault(int opCode, int uid, int mode,
                 @NonNull String packageName) {
-            final int currentMode = mAppOpsManager.unsafeCheckOpRaw(AppOpsManager
-                    .opToPublicName(opCode), uid, packageName);
-            if (currentMode == AppOpsManager.MODE_DEFAULT) {
+            final int currentMode;
+            try {
+                currentMode = mAppOpsManager.unsafeCheckOpRaw(AppOpsManager
+                        .opToPublicName(opCode), uid, packageName);
+            } catch (SecurityException e) {
+                // This might happen if the app was uninstalled in between the add and sync step.
+                // In this case the package name cannot be resolved inside appops service and hence
+                // the uid does not match.
+                Slog.w(LOG_TAG, "Cannot set mode of uid=" + uid + " op=" + opCode + " to " + mode,
+                        e);
+                return;
+            }
+
+            if (currentMode == MODE_DEFAULT) {
                 mAppOpsManager.setUidMode(opCode, uid, mode);
             }
         }
 
         private void setUidModeDefault(int opCode, int uid) {
-            mAppOpsManager.setUidMode(opCode, uid, AppOpsManager.MODE_DEFAULT);
+            mAppOpsManager.setUidMode(opCode, uid, MODE_DEFAULT);
         }
 
         private class OpToRestrict {
@@ -545,21 +618,6 @@
                 this.code = code;
             }
         }
-
-        private class FgPermission {
-            final int uid;
-            final @NonNull String packageName;
-            final @NonNull String fgPermissionName;
-            final @NonNull String bgPermissionName;
-
-            private FgPermission(int uid, @NonNull String packageName,
-                    @NonNull String fgPermissionName, @NonNull String bgPermissionName) {
-                this.uid = uid;
-                this.packageName = packageName;
-                this.fgPermissionName = fgPermissionName;
-                this.bgPermissionName = bgPermissionName;
-            }
-        }
     }
 
     private class Internal extends PermissionPolicyInternal {
diff --git a/services/core/java/com/android/server/policy/PhoneWindowManager.java b/services/core/java/com/android/server/policy/PhoneWindowManager.java
index d624a85..7e706ad 100644
--- a/services/core/java/com/android/server/policy/PhoneWindowManager.java
+++ b/services/core/java/com/android/server/policy/PhoneWindowManager.java
@@ -4863,6 +4863,7 @@
             }
         }
         startedWakingUp(ON_BECAUSE_OF_UNKNOWN);
+        finishedWakingUp(ON_BECAUSE_OF_UNKNOWN);
         screenTurningOn(null);
         screenTurnedOn();
     }
diff --git a/services/core/java/com/android/server/policy/SoftRestrictedPermissionPolicy.java b/services/core/java/com/android/server/policy/SoftRestrictedPermissionPolicy.java
new file mode 100644
index 0000000..d447617
--- /dev/null
+++ b/services/core/java/com/android/server/policy/SoftRestrictedPermissionPolicy.java
@@ -0,0 +1,158 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.server.policy;
+
+import static android.Manifest.permission.READ_EXTERNAL_STORAGE;
+import static android.Manifest.permission.WRITE_EXTERNAL_STORAGE;
+import static android.app.AppOpsManager.MODE_ALLOWED;
+import static android.app.AppOpsManager.MODE_DEFAULT;
+import static android.app.AppOpsManager.MODE_IGNORED;
+import static android.app.AppOpsManager.OP_LEGACY_STORAGE;
+import static android.app.AppOpsManager.OP_NONE;
+import static android.content.pm.PackageManager.FLAG_PERMISSION_APPLY_RESTRICTION;
+import static android.content.pm.PackageManager.FLAG_PERMISSION_RESTRICTION_INSTALLER_EXEMPT;
+import static android.content.pm.PackageManager.FLAG_PERMISSION_RESTRICTION_SYSTEM_EXEMPT;
+import static android.content.pm.PackageManager.FLAG_PERMISSION_RESTRICTION_UPGRADE_EXEMPT;
+
+import android.annotation.NonNull;
+import android.app.AppOpsManager;
+import android.content.Context;
+import android.content.pm.ApplicationInfo;
+import android.os.Build;
+
+/**
+ * The behavior of soft restricted permissions is different for each permission. This class collects
+ * the policies in one place.
+ *
+ * This is the twin of
+ * {@link com.android.packageinstaller.permission.utils.SoftRestrictedPermissionPolicy}
+ */
+public abstract class SoftRestrictedPermissionPolicy {
+    private static final int FLAGS_PERMISSION_RESTRICTION_ANY_EXEMPT =
+            FLAG_PERMISSION_RESTRICTION_SYSTEM_EXEMPT
+                    | FLAG_PERMISSION_RESTRICTION_UPGRADE_EXEMPT
+                    | FLAG_PERMISSION_RESTRICTION_INSTALLER_EXEMPT;
+
+    private static final SoftRestrictedPermissionPolicy DUMMY_POLICY =
+            new SoftRestrictedPermissionPolicy() {
+                @Override
+                public int resolveAppOp() {
+                    return OP_NONE;
+                }
+
+                @Override
+                public int getDesiredOpMode() {
+                    return MODE_DEFAULT;
+                }
+
+                @Override
+                public boolean shouldSetAppOpIfNotDefault() {
+                    return false;
+                }
+
+                @Override
+                public boolean canBeGranted() {
+                    return true;
+                }
+            };
+
+    /**
+     * Get the policy for a soft restricted permission.
+     *
+     * @param context A context to use
+     * @param appInfo The application the permission belongs to
+     * @param permission The name of the permission
+     *
+     * @return The policy for this permission
+     */
+    public static @NonNull SoftRestrictedPermissionPolicy forPermission(@NonNull Context context,
+            @NonNull ApplicationInfo appInfo, @NonNull String permission) {
+        switch (permission) {
+            // Storage uses a special app op to decide the mount state and supports soft restriction
+            // where the restricted state allows the permission but only for accessing the medial
+            // collections.
+            case READ_EXTERNAL_STORAGE:
+            case WRITE_EXTERNAL_STORAGE: {
+                int flags = context.getPackageManager().getPermissionFlags(
+                        permission, appInfo.packageName, context.getUser());
+                boolean applyRestriction = (flags & FLAG_PERMISSION_APPLY_RESTRICTION) != 0;
+                boolean isWhiteListed = (flags & FLAGS_PERMISSION_RESTRICTION_ANY_EXEMPT) != 0;
+                boolean hasRequestedLegacyExternalStorage =
+                        appInfo.hasRequestedLegacyExternalStorage();
+                int targetSDK = appInfo.targetSdkVersion;
+
+                return new SoftRestrictedPermissionPolicy() {
+                    @Override
+                    public int resolveAppOp() {
+                        return OP_LEGACY_STORAGE;
+                    }
+
+                    @Override
+                    public int getDesiredOpMode() {
+                        if (applyRestriction) {
+                            return MODE_DEFAULT;
+                        } else if (hasRequestedLegacyExternalStorage) {
+                            return MODE_ALLOWED;
+                        } else {
+                            return MODE_IGNORED;
+                        }
+                    }
+
+                    @Override
+                    public boolean shouldSetAppOpIfNotDefault() {
+                        // Do not switch from allowed -> ignored as this would mean to retroactively
+                        // turn on isolated storage. This will make the app loose all its files.
+                        return getDesiredOpMode() != MODE_IGNORED;
+                    }
+
+                    @Override
+                    public boolean canBeGranted() {
+                        if (isWhiteListed || targetSDK >= Build.VERSION_CODES.Q) {
+                            return true;
+                        } else {
+                            return false;
+                        }
+                    }
+                };
+            }
+            default:
+                return DUMMY_POLICY;
+        }
+    }
+
+    /**
+     * @return An app op to be changed based on the state of the permission or
+     * {@link AppOpsManager#OP_NONE} if not app-op should be set.
+     */
+    public abstract int resolveAppOp();
+
+    /**
+     * @return The mode the {@link #resolveAppOp() app op} should be in.
+     */
+    public abstract @AppOpsManager.Mode int getDesiredOpMode();
+
+    /**
+     * @return If the {@link #resolveAppOp() app op} should be set even if the app-op is currently
+     * not {@link AppOpsManager#MODE_DEFAULT}.
+     */
+    public abstract boolean shouldSetAppOpIfNotDefault();
+
+    /**
+     * @return If the permission can be granted
+     */
+    public abstract boolean canBeGranted();
+}
diff --git a/services/core/java/com/android/server/policy/TEST_MAPPING b/services/core/java/com/android/server/policy/TEST_MAPPING
index 437ef73..c7f8c07 100644
--- a/services/core/java/com/android/server/policy/TEST_MAPPING
+++ b/services/core/java/com/android/server/policy/TEST_MAPPING
@@ -27,6 +27,22 @@
           "exclude-annotation": "androidx.test.filters.FlakyTest"
         }
       ]
+    },
+    {
+      "name": "CtsPermission2TestCases",
+      "options": [
+        {
+          "include-filter": "android.permission2.cts.RestrictedPermissionsTest"
+        }
+      ]
+    },
+    {
+      "name": "CtsPermissionTestCases",
+      "options": [
+        {
+          "include-filter": "android.permission.cts.SplitPermissionTest"
+        }
+      ]
     }
   ],
   "postsubmit": [
diff --git a/services/core/java/com/android/server/rollback/RollbackManagerServiceImpl.java b/services/core/java/com/android/server/rollback/RollbackManagerServiceImpl.java
index 301f650..e107c9a 100644
--- a/services/core/java/com/android/server/rollback/RollbackManagerServiceImpl.java
+++ b/services/core/java/com/android/server/rollback/RollbackManagerServiceImpl.java
@@ -1079,7 +1079,7 @@
                     if (info.getPackageName().equals(packageName)) {
                         mAppDataRollbackHelper.snapshotAppData(data.info.getRollbackId(), info);
                         saveRollbackData(data);
-                        return;
+                        break;
                     }
                 }
             }
@@ -1091,7 +1091,6 @@
                     mAppDataRollbackHelper.snapshotAppData(rollback.data.info.getRollbackId(),
                             info);
                     saveRollbackData(rollback.data);
-                    return;
                 }
             }
         }
diff --git a/services/core/java/com/android/server/stats/StatsCompanionService.java b/services/core/java/com/android/server/stats/StatsCompanionService.java
index b10b5ac..63439d5 100644
--- a/services/core/java/com/android/server/stats/StatsCompanionService.java
+++ b/services/core/java/com/android/server/stats/StatsCompanionService.java
@@ -489,8 +489,7 @@
                 // Add in all the apps for every user/profile.
                 for (UserInfo profile : users) {
                     List<PackageInfo> pi =
-                            pm.getInstalledPackagesAsUser(
-                                    PackageManager.MATCH_KNOWN_PACKAGES | PackageManager.MATCH_APEX,
+                            pm.getInstalledPackagesAsUser(PackageManager.MATCH_KNOWN_PACKAGES,
                                     profile.id);
                     for (int j = 0; j < pi.size(); j++) {
                         if (pi.get(j).applicationInfo != null) {
@@ -2513,7 +2512,7 @@
         @Override
         public void onBootPhase(int phase) {
             super.onBootPhase(phase);
-            if (phase == PHASE_BOOT_COMPLETED) {
+            if (phase == PHASE_THIRD_PARTY_APPS_CAN_START) {
                 mStatsCompanionService.systemReady();
             }
         }
diff --git a/services/core/java/com/android/server/webkit/WebViewUpdateServiceImpl.java b/services/core/java/com/android/server/webkit/WebViewUpdateServiceImpl.java
index 165055a..11fd795 100644
--- a/services/core/java/com/android/server/webkit/WebViewUpdateServiceImpl.java
+++ b/services/core/java/com/android/server/webkit/WebViewUpdateServiceImpl.java
@@ -82,6 +82,22 @@
     void prepareWebViewInSystemServer() {
         migrateFallbackStateOnBoot();
         mWebViewUpdater.prepareWebViewInSystemServer();
+        if (getCurrentWebViewPackage() == null) {
+            // We didn't find a valid WebView implementation. Try explicitly re-enabling the
+            // fallback package for all users in case it was disabled, even if we already did the
+            // one-time migration before. If this actually changes the state, WebViewUpdater will
+            // see the PackageManager broadcast shortly and try again.
+            WebViewProviderInfo[] webviewProviders = mSystemInterface.getWebViewPackages();
+            WebViewProviderInfo fallbackProvider = getFallbackProvider(webviewProviders);
+            if (fallbackProvider != null) {
+                Slog.w(TAG, "No valid provider, trying to enable " + fallbackProvider.packageName);
+                mSystemInterface.enablePackageForAllUsers(mContext, fallbackProvider.packageName,
+                                                          true);
+            } else {
+                Slog.e(TAG, "No valid provider and no fallback available.");
+            }
+        }
+
         boolean multiProcessEnabled = isMultiProcessEnabled();
         mSystemInterface.notifyZygote(multiProcessEnabled);
         if (multiProcessEnabled) {
diff --git a/services/core/java/com/android/server/wm/ActivityStack.java b/services/core/java/com/android/server/wm/ActivityStack.java
index 3d59e66..9e8876a 100644
--- a/services/core/java/com/android/server/wm/ActivityStack.java
+++ b/services/core/java/com/android/server/wm/ActivityStack.java
@@ -2382,7 +2382,11 @@
                 r.setVisible(true);
             }
             if (r != starting) {
-                mStackSupervisor.startSpecificActivityLocked(r, andResume, true /* checkConfig */);
+                // We should not resume activities that being launched behind because these
+                // activities are actually behind other fullscreen activities, but still required
+                // to be visible (such as performing Recents animation).
+                mStackSupervisor.startSpecificActivityLocked(r, andResume && !r.mLaunchTaskBehind,
+                        true /* checkConfig */);
                 return true;
             }
         }
@@ -2635,7 +2639,7 @@
 
         if (!hasRunningActivity) {
             // There are no activities left in the stack, let's look somewhere else.
-            return resumeTopActivityInNextFocusableStack(prev, options, "noMoreActivities");
+            return resumeNextFocusableActivityWhenStackIsEmpty(prev, options);
         }
 
         next.delayedResume = false;
@@ -3036,21 +3040,33 @@
         return true;
     }
 
-    private boolean resumeTopActivityInNextFocusableStack(ActivityRecord prev,
-            ActivityOptions options, String reason) {
-        final ActivityStack nextFocusedStack = adjustFocusToNextFocusableStack(reason);
-        if (nextFocusedStack != null) {
-            // Try to move focus to the next visible stack with a running activity if this
-            // stack is not covering the entire screen or is on a secondary display (with no home
-            // stack).
-            return mRootActivityContainer.resumeFocusedStacksTopActivities(nextFocusedStack, prev,
-                    null /* targetOptions */);
+    /**
+     * Resume the next eligible activity in a focusable stack when this one does not have any
+     * running activities left. The focus will be adjusted to the next focusable stack and
+     * top running activities will be resumed in all focusable stacks. However, if the current stack
+     * is a home stack - we have to keep it focused, start and resume a home activity on the current
+     * display instead to make sure that the display is not empty.
+     */
+    private boolean resumeNextFocusableActivityWhenStackIsEmpty(ActivityRecord prev,
+            ActivityOptions options) {
+        final String reason = "noMoreActivities";
+
+        if (!isActivityTypeHome()) {
+            final ActivityStack nextFocusedStack = adjustFocusToNextFocusableStack(reason);
+            if (nextFocusedStack != null) {
+                // Try to move focus to the next visible stack with a running activity if this
+                // stack is not covering the entire screen or is on a secondary display with no home
+                // stack.
+                return mRootActivityContainer.resumeFocusedStacksTopActivities(nextFocusedStack,
+                        prev, null /* targetOptions */);
+            }
         }
 
-        // Let's just start up the Launcher...
+        // If the current stack is a home stack, or if focus didn't switch to a different stack -
+        // just start up the Launcher...
         ActivityOptions.abort(options);
         if (DEBUG_STATES) Slog.d(TAG_STATES,
-                "resumeTopActivityInNextFocusableStack: " + reason + ", go home");
+                "resumeNextFocusableActivityWhenStackIsEmpty: " + reason + ", go home");
         return mRootActivityContainer.resumeHomeActivity(prev, reason, mDisplayId);
     }
 
@@ -4979,6 +4995,17 @@
             return true;
         }
 
+        ActivityRecord topActivity = getDisplay().topRunningActivity();
+        ActivityStack topStack = topActivity.getActivityStack();
+        if (topStack != null && topStack != this && topActivity.isState(RESUMED)) {
+            // The new top activity is already resumed, so there's a good chance that nothing will
+            // get resumed below. So, update visibility now in case the transition is closed
+            // prematurely.
+            mRootActivityContainer.ensureVisibilityAndConfig(null /* starting */,
+                    getDisplay().mDisplayId, false /* markFrozenIfConfigChanged */,
+                    false /* deferResume */);
+        }
+
         mRootActivityContainer.resumeFocusedStacksTopActivities();
         return true;
     }
diff --git a/services/core/java/com/android/server/wm/ActivityStarter.java b/services/core/java/com/android/server/wm/ActivityStarter.java
index 1718ac6..0a88eef 100644
--- a/services/core/java/com/android/server/wm/ActivityStarter.java
+++ b/services/core/java/com/android/server/wm/ActivityStarter.java
@@ -101,7 +101,6 @@
 import android.content.pm.ResolveInfo;
 import android.content.pm.UserInfo;
 import android.content.res.Configuration;
-import android.content.res.Resources;
 import android.graphics.Rect;
 import android.os.Binder;
 import android.os.Bundle;
@@ -118,9 +117,7 @@
 import android.util.EventLog;
 import android.util.Pools.SynchronizedPool;
 import android.util.Slog;
-import android.widget.Toast;
 
-import com.android.internal.R;
 import com.android.internal.annotations.VisibleForTesting;
 import com.android.internal.app.HeavyWeightSwitcherActivity;
 import com.android.internal.app.IVoiceInteractor;
@@ -1044,12 +1041,6 @@
                     + " allowed because SYSTEM_ALERT_WINDOW permission is granted.");
             return false;
         }
-        // don't abort if the callingPackage is temporarily whitelisted
-        if (mService.isPackageNameWhitelistedForBgActivityStarts(callingPackage)) {
-            Slog.w(TAG, "Background activity start for " + callingPackage
-                    + " temporarily whitelisted. This will not be supported in future Q builds.");
-            return false;
-        }
         // anything that has fallen through would currently be aborted
         Slog.w(TAG, "Background activity start [callingPackage: " + callingPackage
                 + "; callingUid: " + callingUid
@@ -1074,18 +1065,6 @@
         return true;
     }
 
-    // TODO: remove this toast after feature development is done
-    void showBackgroundActivityBlockedToast(boolean abort, String callingPackage) {
-        final Resources res = mService.mContext.getResources();
-        final String toastMsg = res.getString(abort
-                        ? R.string.activity_starter_block_bg_activity_starts_enforcing
-                        : R.string.activity_starter_block_bg_activity_starts_permissive,
-                callingPackage);
-        mService.mUiHandler.post(() -> {
-            Toast.makeText(mService.mContext, toastMsg, Toast.LENGTH_LONG).show();
-        });
-    }
-
     /**
      * Creates a launch intent for the given auxiliary resolution data.
      */
@@ -1440,6 +1419,13 @@
                     stack.finishActivityLocked(mStartActivity, RESULT_CANCELED,
                             null /* intentResultData */, "startActivity", true /* oomAdj */);
                 }
+
+                // Stack should also be detached from display and be removed if it's empty.
+                if (startedActivityStack != null && startedActivityStack.isAttached()
+                        && startedActivityStack.numActivities() == 0
+                        && !startedActivityStack.isActivityTypeHome()) {
+                    startedActivityStack.remove();
+                }
             }
             mService.mWindowManager.continueSurfaceLayout();
         }
@@ -1457,7 +1443,6 @@
     private boolean handleBackgroundActivityAbort(ActivityRecord r) {
         // TODO(b/131747138): Remove toast and refactor related code in Q release.
         boolean abort = !mService.isBackgroundActivityStartsEnabled();
-        showBackgroundActivityBlockedToast(abort, r.launchedFromPackage);
         if (!abort) {
             return false;
         }
@@ -2311,15 +2296,17 @@
     }
 
     private int setTaskFromReuseOrCreateNewTask(TaskRecord taskToAffiliate) {
+        if (mRestrictedBgActivity && (mReuseTask == null || !mReuseTask.containsAppUid(mCallingUid))
+                && handleBackgroundActivityAbort(mStartActivity)) {
+            return START_ABORTED;
+        }
+
         mTargetStack = computeStackFocus(mStartActivity, true, mLaunchFlags, mOptions);
 
         // Do no move the target stack to front yet, as we might bail if
         // isLockTaskModeViolation fails below.
 
         if (mReuseTask == null) {
-            if (mRestrictedBgActivity && handleBackgroundActivityAbort(mStartActivity)) {
-                return START_ABORTED;
-            }
             final TaskRecord task = mTargetStack.createTaskRecord(
                     mSupervisor.getNextTaskIdForUserLocked(mStartActivity.mUserId),
                     mNewTaskInfo != null ? mNewTaskInfo : mStartActivity.info,
@@ -2332,11 +2319,6 @@
             if (DEBUG_TASKS) Slog.v(TAG_TASKS, "Starting new activity " + mStartActivity
                     + " in new task " + mStartActivity.getTaskRecord());
         } else {
-            if (mRestrictedBgActivity && !mReuseTask.containsAppUid(mCallingUid)) {
-                if (handleBackgroundActivityAbort(mStartActivity)) {
-                    return START_ABORTED;
-                }
-            }
             addOrReparentStartingActivity(mReuseTask, "setTaskFromReuseOrCreateNewTask");
         }
 
diff --git a/services/core/java/com/android/server/wm/ActivityTaskManagerInternal.java b/services/core/java/com/android/server/wm/ActivityTaskManagerInternal.java
index ed56501..5459ede 100644
--- a/services/core/java/com/android/server/wm/ActivityTaskManagerInternal.java
+++ b/services/core/java/com/android/server/wm/ActivityTaskManagerInternal.java
@@ -553,7 +553,7 @@
     /**
      * Gets bitmap snapshot of the provided task id.
      */
-    public abstract ActivityManager.TaskSnapshot getTaskSnapshot(int taskId,
+    public abstract ActivityManager.TaskSnapshot getTaskSnapshotNoRestore(int taskId,
             boolean reducedResolution);
 
     /** Returns true if uid is considered foreground for activity start purposes. */
diff --git a/services/core/java/com/android/server/wm/ActivityTaskManagerService.java b/services/core/java/com/android/server/wm/ActivityTaskManagerService.java
index b97ecec..142c3b3 100644
--- a/services/core/java/com/android/server/wm/ActivityTaskManagerService.java
+++ b/services/core/java/com/android/server/wm/ActivityTaskManagerService.java
@@ -508,6 +508,12 @@
      */
     private boolean mDidAppSwitch;
 
+    /**
+     * Last stop app switches time, apps finished before this time cannot start background activity
+     * even if they are in grace period.
+     */
+    private long mLastStopAppSwitchesTime;
+
     IActivityController mController = null;
     boolean mControllerIsAMonkey = false;
 
@@ -2369,9 +2375,7 @@
                 null /* intent */, "moveTaskToFront");
         if (starter.shouldAbortBackgroundActivityStart(callingUid, callingPid, callingPackage, -1,
                 -1, callerApp, null, false, null)) {
-            boolean abort = !isBackgroundActivityStartsEnabled();
-            starter.showBackgroundActivityBlockedToast(abort, callingPackage);
-            if (abort) {
+            if (!isBackgroundActivityStartsEnabled()) {
                 return;
             }
         }
@@ -4517,22 +4521,27 @@
         enforceCallerIsRecentsOrHasPermission(READ_FRAME_BUFFER, "getTaskSnapshot()");
         final long ident = Binder.clearCallingIdentity();
         try {
-            final TaskRecord task;
-            synchronized (mGlobalLock) {
-                task = mRootActivityContainer.anyTaskForId(taskId,
-                        MATCH_TASK_IN_STACKS_OR_RECENT_TASKS);
-                if (task == null) {
-                    Slog.w(TAG, "getTaskSnapshot: taskId=" + taskId + " not found");
-                    return null;
-                }
-            }
-            // Don't call this while holding the lock as this operation might hit the disk.
-            return task.getSnapshot(reducedResolution);
+            return getTaskSnapshot(taskId, reducedResolution, true /* restoreFromDisk */);
         } finally {
             Binder.restoreCallingIdentity(ident);
         }
     }
 
+    private ActivityManager.TaskSnapshot getTaskSnapshot(int taskId, boolean reducedResolution,
+            boolean restoreFromDisk) {
+        final TaskRecord task;
+        synchronized (mGlobalLock) {
+            task = mRootActivityContainer.anyTaskForId(taskId,
+                    MATCH_TASK_IN_STACKS_OR_RECENT_TASKS);
+            if (task == null) {
+                Slog.w(TAG, "getTaskSnapshot: taskId=" + taskId + " not found");
+                return null;
+            }
+        }
+        // Don't call this while holding the lock as this operation might hit the disk.
+        return task.getSnapshot(reducedResolution, restoreFromDisk);
+    }
+
     @Override
     public void setDisablePreviewScreenshots(IBinder token, boolean disable) {
         synchronized (mGlobalLock) {
@@ -4731,6 +4740,7 @@
         enforceCallerIsRecentsOrHasPermission(STOP_APP_SWITCHES, "stopAppSwitches");
         synchronized (mGlobalLock) {
             mAppSwitchesAllowedTime = SystemClock.uptimeMillis() + APP_SWITCH_DELAY_TIME;
+            mLastStopAppSwitchesTime = SystemClock.uptimeMillis();
             mDidAppSwitch = false;
             getActivityStartController().schedulePendingActivityLaunches(APP_SWITCH_DELAY_TIME);
         }
@@ -4747,6 +4757,10 @@
         }
     }
 
+    long getLastStopAppSwitchesTime() {
+        return mLastStopAppSwitchesTime;
+    }
+
     void onStartActivitySetDidAppSwitch() {
         if (mDidAppSwitch) {
             // This is the second allowed switch since we stopped switches, so now just generally
@@ -5397,13 +5411,6 @@
         return mAmInternal.isBackgroundActivityStartsEnabled();
     }
 
-    boolean isPackageNameWhitelistedForBgActivityStarts(@Nullable String packageName) {
-        if (packageName == null) {
-            return false;
-        }
-        return mAmInternal.isPackageNameWhitelistedForBgActivityStarts(packageName);
-    }
-
     void enableScreenAfterBoot(boolean booted) {
         EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_ENABLE_SCREEN,
                 SystemClock.uptimeMillis());
@@ -7411,10 +7418,10 @@
         }
 
         @Override
-        public ActivityManager.TaskSnapshot getTaskSnapshot(int taskId, boolean reducedResolution) {
-            synchronized (mGlobalLock) {
-                return ActivityTaskManagerService.this.getTaskSnapshot(taskId, reducedResolution);
-            }
+        public ActivityManager.TaskSnapshot getTaskSnapshotNoRestore(int taskId,
+                boolean reducedResolution) {
+            return ActivityTaskManagerService.this.getTaskSnapshot(taskId, reducedResolution,
+                    false /* restoreFromDisk */);
         }
 
         @Override
diff --git a/services/core/java/com/android/server/wm/AppTaskImpl.java b/services/core/java/com/android/server/wm/AppTaskImpl.java
index 78f1e69..1eb7455 100644
--- a/services/core/java/com/android/server/wm/AppTaskImpl.java
+++ b/services/core/java/com/android/server/wm/AppTaskImpl.java
@@ -118,9 +118,7 @@
                         null /* intent */, "moveToFront");
                 if (starter.shouldAbortBackgroundActivityStart(callingUid, callingPid,
                         callingPackage, -1, -1, callerApp, null, false, null)) {
-                    boolean abort = !mService.isBackgroundActivityStartsEnabled();
-                    starter.showBackgroundActivityBlockedToast(abort, callingPackage);
-                    if (abort) {
+                    if (!mService.isBackgroundActivityStartsEnabled()) {
                         return;
                     }
                 }
diff --git a/services/core/java/com/android/server/wm/AppWindowToken.java b/services/core/java/com/android/server/wm/AppWindowToken.java
index cae7612..9189279 100644
--- a/services/core/java/com/android/server/wm/AppWindowToken.java
+++ b/services/core/java/com/android/server/wm/AppWindowToken.java
@@ -176,6 +176,7 @@
     boolean inPendingTransaction;
     boolean allDrawn;
     private boolean mLastAllDrawn;
+    private boolean mUseTransferredAnimation;
 
     // Set to true when this app creates a surface while in the middle of an animation. In that
     // case do not clear allDrawn until the animation completes.
@@ -618,9 +619,12 @@
             boolean runningAppAnimation = false;
 
             if (transit != WindowManager.TRANSIT_UNSET) {
-                if (applyAnimationLocked(lp, transit, visible, isVoiceInteraction)) {
-                    delayed = runningAppAnimation = true;
+                if (mUseTransferredAnimation) {
+                    runningAppAnimation = isReallyAnimating();
+                } else if (applyAnimationLocked(lp, transit, visible, isVoiceInteraction)) {
+                    runningAppAnimation = true;
                 }
+                delayed = runningAppAnimation;
                 final WindowState window = findMainWindow();
                 if (window != null && accessibilityController != null) {
                     accessibilityController.onAppWindowTransitionLocked(window, transit);
@@ -667,6 +671,7 @@
                 getDisplayContent().getInputMonitor().updateInputWindowsLw(false /*force*/);
             }
         }
+        mUseTransferredAnimation = false;
 
         if (isReallyAnimating()) {
             delayed = true;
@@ -1317,7 +1322,9 @@
         if (prevDc == null || prevDc == mDisplayContent) {
             return;
         }
-        if (prevDc.mChangingApps.contains(this)) {
+
+        prevDc.mOpeningApps.remove(this);
+        if (prevDc.mChangingApps.remove(this)) {
             // This gets called *after* the AppWindowToken has been reparented to the new display.
             // That reparenting resulted in this window changing modes (eg. FREEFORM -> FULLSCREEN),
             // so this token is now "frozen" while waiting for the animation to start on prevDc
@@ -1326,6 +1333,8 @@
             // so we need to cancel the change transition here.
             clearChangeLeash(getPendingTransaction(), true /* cancel */);
         }
+        prevDc.mClosingApps.remove(this);
+
         if (prevDc.mFocusedApp == this) {
             prevDc.setFocusedApp(null);
             final TaskStack stack = dc.getTopStack();
@@ -1531,9 +1540,9 @@
                 transferAnimation(fromToken);
 
                 // When transferring an animation, we no longer need to apply an animation to the
-                // the token we transfer the animation over. Thus, remove the animation from
-                // pending opening apps.
-                getDisplayContent().mOpeningApps.remove(this);
+                // the token we transfer the animation over. Thus, set this flag to indicate we've
+                // transferred the animation.
+                mUseTransferredAnimation = true;
 
                 mWmService.updateFocusedWindowLocked(
                         UPDATE_FOCUS_WILL_PLACE_SURFACES, true /*updateInputWindows*/);
@@ -3211,16 +3220,6 @@
                 true /* topToBottom */);
     }
 
-    void removeFromPendingTransition() {
-        if (isWaitingForTransitionStart() && mDisplayContent != null) {
-            mDisplayContent.mOpeningApps.remove(this);
-            if (mDisplayContent.mChangingApps.remove(this)) {
-                clearChangeLeash(getPendingTransaction(), true /* cancel */);
-            }
-            mDisplayContent.mClosingApps.remove(this);
-        }
-    }
-
     private void updateColorTransform() {
         if (mSurfaceControl != null && mLastAppSaturationInfo != null) {
             getPendingTransaction().setColorTransform(mSurfaceControl,
diff --git a/services/core/java/com/android/server/wm/BoundsAnimationController.java b/services/core/java/com/android/server/wm/BoundsAnimationController.java
index b5e7067..5dc88b3 100644
--- a/services/core/java/com/android/server/wm/BoundsAnimationController.java
+++ b/services/core/java/com/android/server/wm/BoundsAnimationController.java
@@ -410,7 +410,7 @@
         @VisibleForTesting
         boolean animatingToLargerSize() {
             // TODO: Fix this check for aspect ratio changes
-            return (mFrom.width() * mFrom.height() <= mTo.width() * mTo.height());
+            return (mFrom.width() * mFrom.height() < mTo.width() * mTo.height());
         }
 
         @Override
@@ -453,16 +453,10 @@
             boolean moveFromFullscreen, boolean moveToFullscreen,
             @AnimationType int animationType) {
         final BoundsAnimator existing = mRunningAnimations.get(target);
-        // animateBoundsImpl gets called twice for each animation. The second time we get the final
-        // to rect that respects the shelf, which is when we want to resize. Our signal for fade in
-        // comes in from how to enter into pip, but we also need to use the to and from rect to
-        // decide which animation we want to run finally.
-        boolean shouldResize = false;
-        if (isRunningFadeInAnimation(target)) {
-            shouldResize = true;
-            if (from.contains(to)) {
-                animationType = FADE_IN;
-            }
+
+        if (isRunningFadeInAnimation(target) && from.width() == to.width()
+                && from.height() == to.height()) {
+            animationType = FADE_IN;
         }
         final boolean replacing = existing != null;
         @SchedulePipModeChangedState int prevSchedulePipModeChangedState =
@@ -523,9 +517,10 @@
             // Since we are replacing, we skip both animation start and end callbacks
             existing.cancel();
         }
-        if (shouldResize) {
+        if (animationType == FADE_IN) {
             target.setPinnedStackSize(to, null);
         }
+
         final BoundsAnimator animator = new BoundsAnimator(target, animationType, from, to,
                 schedulePipModeChangedState, prevSchedulePipModeChangedState,
                 moveFromFullscreen, moveToFullscreen, frozenTask);
diff --git a/services/core/java/com/android/server/wm/DisplayContent.java b/services/core/java/com/android/server/wm/DisplayContent.java
index c3a769b..80848a8f 100644
--- a/services/core/java/com/android/server/wm/DisplayContent.java
+++ b/services/core/java/com/android/server/wm/DisplayContent.java
@@ -2377,9 +2377,6 @@
                     + " to its current displayId=" + mDisplayId);
         }
 
-        // Clean up all pending transitions when stack reparent to another display.
-        stack.forAllAppWindows(AppWindowToken::removeFromPendingTransition);
-
         prevDc.mTaskStackContainers.removeChild(stack);
         mTaskStackContainers.addStackToDisplay(stack, onTop);
     }
diff --git a/services/core/java/com/android/server/wm/DisplayPolicy.java b/services/core/java/com/android/server/wm/DisplayPolicy.java
index 21f01ff..7badc7a 100644
--- a/services/core/java/com/android/server/wm/DisplayPolicy.java
+++ b/services/core/java/com/android/server/wm/DisplayPolicy.java
@@ -198,6 +198,8 @@
     private static final int NAV_BAR_OPAQUE_WHEN_FREEFORM_OR_DOCKED = 0;
     // Nav bar is always translucent when the freeform stack is visible, otherwise always opaque.
     private static final int NAV_BAR_TRANSLUCENT_WHEN_FREEFORM_OPAQUE_OTHERWISE = 1;
+    // Nav bar is never forced opaque.
+    private static final int NAV_BAR_FORCE_TRANSPARENT = 2;
 
     /**
      * These are the system UI flags that, when changing, can cause the layout
@@ -3288,8 +3290,10 @@
                 : mTopFullscreenOpaqueWindowState;
         vis = mStatusBarController.applyTranslucentFlagLw(fullscreenTransWin, vis, oldVis);
         vis = mNavigationBarController.applyTranslucentFlagLw(fullscreenTransWin, vis, oldVis);
-        final int dockedVis = mStatusBarController.applyTranslucentFlagLw(
+        int dockedVis = mStatusBarController.applyTranslucentFlagLw(
                 mTopDockedOpaqueWindowState, 0, 0);
+        dockedVis = mNavigationBarController.applyTranslucentFlagLw(
+                mTopDockedOpaqueWindowState, dockedVis, 0);
 
         final boolean fullscreenDrawsStatusBarBackground =
                 drawsStatusBarBackground(vis, mTopFullscreenOpaqueWindowState);
@@ -3297,6 +3301,8 @@
                 drawsStatusBarBackground(dockedVis, mTopDockedOpaqueWindowState);
         final boolean fullscreenDrawsNavBarBackground =
                 drawsNavigationBarBackground(vis, mTopFullscreenOpaqueWindowState);
+        final boolean dockedDrawsNavigationBarBackground =
+                drawsNavigationBarBackground(dockedVis, mTopDockedOpaqueWindowState);
 
         // prevent status bar interaction from clearing certain flags
         int type = win.getAttrs().type;
@@ -3321,7 +3327,7 @@
         }
 
         vis = configureNavBarOpacity(vis, dockedStackVisible, freeformStackVisible, resizing,
-                fullscreenDrawsNavBarBackground);
+                fullscreenDrawsNavBarBackground, dockedDrawsNavigationBarBackground);
 
         // update status bar
         boolean immersiveSticky =
@@ -3439,8 +3445,14 @@
      */
     private int configureNavBarOpacity(int visibility, boolean dockedStackVisible,
             boolean freeformStackVisible, boolean isDockedDividerResizing,
-            boolean fullscreenDrawsBackground) {
-        if (mNavBarOpacityMode == NAV_BAR_OPAQUE_WHEN_FREEFORM_OR_DOCKED) {
+            boolean fullscreenDrawsBackground, boolean dockedDrawsNavigationBarBackground) {
+        if (mNavBarOpacityMode == NAV_BAR_FORCE_TRANSPARENT) {
+            if (fullscreenDrawsBackground && dockedDrawsNavigationBarBackground) {
+                visibility = setNavBarTransparentFlag(visibility);
+            } else if (dockedStackVisible) {
+                visibility = setNavBarOpaqueFlag(visibility);
+            }
+        } else if (mNavBarOpacityMode == NAV_BAR_OPAQUE_WHEN_FREEFORM_OR_DOCKED) {
             if (dockedStackVisible || freeformStackVisible || isDockedDividerResizing) {
                 visibility = setNavBarOpaqueFlag(visibility);
             } else if (fullscreenDrawsBackground) {
diff --git a/services/core/java/com/android/server/wm/TaskRecord.java b/services/core/java/com/android/server/wm/TaskRecord.java
index 298b302..3fd4e83 100644
--- a/services/core/java/com/android/server/wm/TaskRecord.java
+++ b/services/core/java/com/android/server/wm/TaskRecord.java
@@ -851,11 +851,12 @@
     /**
      * DO NOT HOLD THE ACTIVITY MANAGER LOCK WHEN CALLING THIS METHOD!
      */
-    TaskSnapshot getSnapshot(boolean reducedResolution) {
+    TaskSnapshot getSnapshot(boolean reducedResolution, boolean restoreFromDisk) {
 
         // TODO: Move this to {@link TaskWindowContainerController} once recent tasks are more
         // synchronized between AM and WM.
-        return mService.mWindowManager.getTaskSnapshot(taskId, userId, reducedResolution);
+        return mService.mWindowManager.getTaskSnapshot(taskId, userId, reducedResolution,
+                restoreFromDisk);
     }
 
     void touchActiveTime() {
diff --git a/services/core/java/com/android/server/wm/TaskStack.java b/services/core/java/com/android/server/wm/TaskStack.java
index d838691..481c3ba 100644
--- a/services/core/java/com/android/server/wm/TaskStack.java
+++ b/services/core/java/com/android/server/wm/TaskStack.java
@@ -1640,6 +1640,7 @@
             if (mAnimationType == BoundsAnimationController.FADE_IN) {
                 setPinnedStackAlpha(1f);
                 mActivityStack.mService.notifyPinnedStackAnimationEnded();
+                return;
             }
 
             if (finalStackSize != null && !mCancelCurrentBoundsAnimation) {
@@ -1935,14 +1936,11 @@
     public boolean setPinnedStackAlpha(float alpha) {
         // Hold the lock since this is called from the BoundsAnimator running on the UiThread
         synchronized (mWmService.mGlobalLock) {
-            if (mCancelCurrentBoundsAnimation) {
-                return false;
-            }
-            getPendingTransaction().setAlpha(getSurfaceControl(), alpha);
+            getPendingTransaction().setAlpha(getSurfaceControl(),
+                    mCancelCurrentBoundsAnimation ? 1 : alpha);
             scheduleAnimation();
+            return !mCancelCurrentBoundsAnimation;
         }
-
-        return true;
     }
 
     public DisplayInfo getDisplayInfo() {
diff --git a/services/core/java/com/android/server/wm/WindowManagerService.java b/services/core/java/com/android/server/wm/WindowManagerService.java
index d39ee40..ce8720a 100644
--- a/services/core/java/com/android/server/wm/WindowManagerService.java
+++ b/services/core/java/com/android/server/wm/WindowManagerService.java
@@ -3551,8 +3551,9 @@
         return true;
     }
 
-    public TaskSnapshot getTaskSnapshot(int taskId, int userId, boolean reducedResolution) {
-        return mTaskSnapshotController.getSnapshot(taskId, userId, true /* restoreFromDisk */,
+    public TaskSnapshot getTaskSnapshot(int taskId, int userId, boolean reducedResolution,
+            boolean restoreFromDisk) {
+        return mTaskSnapshotController.getSnapshot(taskId, userId, restoreFromDisk,
                 reducedResolution);
     }
 
diff --git a/services/core/java/com/android/server/wm/WindowProcessController.java b/services/core/java/com/android/server/wm/WindowProcessController.java
index 2ad25cf..bc5e328 100644
--- a/services/core/java/com/android/server/wm/WindowProcessController.java
+++ b/services/core/java/com/android/server/wm/WindowProcessController.java
@@ -402,11 +402,17 @@
         if (mAllowBackgroundActivityStarts) {
             return true;
         }
-        // allow if any activity in the caller has either started or finished very recently
+        // allow if any activity in the caller has either started or finished very recently, and
+        // it must be started or finished after last stop app switches time.
         final long now = SystemClock.uptimeMillis();
         if (now - mLastActivityLaunchTime < ACTIVITY_BG_START_GRACE_PERIOD_MS
                 || now - mLastActivityFinishTime < ACTIVITY_BG_START_GRACE_PERIOD_MS) {
-            return true;
+            // if activity is started and finished before stop app switch time, we should not
+            // let app to be able to start background activity even it's in grace period.
+            if (mLastActivityLaunchTime > mAtm.getLastStopAppSwitchesTime()
+                    || mLastActivityFinishTime > mAtm.getLastStopAppSwitchesTime()) {
+                return true;
+            }
         }
         // allow if the proc is instrumenting with background activity starts privs
         if (mInstrumentingWithBackgroundActivityStartPrivileges) {
diff --git a/services/core/java/com/android/server/wm/WindowState.java b/services/core/java/com/android/server/wm/WindowState.java
index 5ef184a..c6c9e1b 100644
--- a/services/core/java/com/android/server/wm/WindowState.java
+++ b/services/core/java/com/android/server/wm/WindowState.java
@@ -1447,10 +1447,12 @@
 
     void clearPolicyVisibilityFlag(int policyVisibilityFlag) {
         mPolicyVisibility &= ~policyVisibilityFlag;
+        mWmService.scheduleAnimationLocked();
     }
 
     void setPolicyVisibilityFlag(int policyVisibilityFlag) {
         mPolicyVisibility |= policyVisibilityFlag;
+        mWmService.scheduleAnimationLocked();
     }
 
     private boolean isLegacyPolicyVisibility() {
@@ -1546,7 +1548,8 @@
      */
     boolean isInteresting() {
         return mAppToken != null && !mAppDied
-                && (!mAppToken.isFreezingScreen() || !mAppFreezing);
+                && (!mAppToken.isFreezingScreen() || !mAppFreezing)
+                && mViewVisibility == View.VISIBLE;
     }
 
     /**
@@ -3889,7 +3892,7 @@
     boolean performShowLocked() {
         if (isHiddenFromUserLocked()) {
             if (DEBUG_VISIBILITY) Slog.w(TAG, "hiding " + this + ", belonging to " + mOwnerUid);
-            hideLw(false);
+            clearPolicyVisibilityFlag(VISIBLE_FOR_USER);
             return false;
         }
 
diff --git a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java
index ac7c16e..ba59cdb 100644
--- a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java
+++ b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java
@@ -6654,7 +6654,7 @@
      */
     @Override
     public void setActivePasswordState(PasswordMetrics metrics, int userHandle) {
-        if (!mHasFeature || !mLockPatternUtils.hasSecureLockScreen()) {
+        if (!mLockPatternUtils.hasSecureLockScreen()) {
             return;
         }
         enforceFullCrossUsersPermission(userHandle);
diff --git a/services/net/aidl/ipmemorystore/3/android/net/IIpMemoryStore.aidl b/services/net/aidl/ipmemorystore/3/android/net/IIpMemoryStore.aidl
index 1e688d0..30893b2 100644
--- a/services/net/aidl/ipmemorystore/3/android/net/IIpMemoryStore.aidl
+++ b/services/net/aidl/ipmemorystore/3/android/net/IIpMemoryStore.aidl
@@ -1,3 +1,20 @@
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a frozen snapshot of an AIDL interface (or parcelable). Do not
+// try to edit this file. It looks like you are doing that because you have
+// modified an AIDL interface in a backward-incompatible way, e.g., deleting a
+// function from an interface or a field from a parcelable and it broke the
+// build. That breakage is intended.
+//
+// You must not make a backward incompatible changes to the AIDL files built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
 package android.net;
 interface IIpMemoryStore {
   oneway void storeNetworkAttributes(String l2Key, in android.net.ipmemorystore.NetworkAttributesParcelable attributes, android.net.ipmemorystore.IOnStatusListener listener);
diff --git a/services/net/aidl/ipmemorystore/3/android/net/IIpMemoryStoreCallbacks.aidl b/services/net/aidl/ipmemorystore/3/android/net/IIpMemoryStoreCallbacks.aidl
index cf02c26..535ae2c 100644
--- a/services/net/aidl/ipmemorystore/3/android/net/IIpMemoryStoreCallbacks.aidl
+++ b/services/net/aidl/ipmemorystore/3/android/net/IIpMemoryStoreCallbacks.aidl
@@ -1,3 +1,20 @@
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a frozen snapshot of an AIDL interface (or parcelable). Do not
+// try to edit this file. It looks like you are doing that because you have
+// modified an AIDL interface in a backward-incompatible way, e.g., deleting a
+// function from an interface or a field from a parcelable and it broke the
+// build. That breakage is intended.
+//
+// You must not make a backward incompatible changes to the AIDL files built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
 package android.net;
 interface IIpMemoryStoreCallbacks {
   oneway void onIpMemoryStoreFetched(in android.net.IIpMemoryStore ipMemoryStore);
diff --git a/services/net/aidl/ipmemorystore/3/android/net/ipmemorystore/Blob.aidl b/services/net/aidl/ipmemorystore/3/android/net/ipmemorystore/Blob.aidl
index 291dbef..6d2dc0c 100644
--- a/services/net/aidl/ipmemorystore/3/android/net/ipmemorystore/Blob.aidl
+++ b/services/net/aidl/ipmemorystore/3/android/net/ipmemorystore/Blob.aidl
@@ -1,3 +1,20 @@
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a frozen snapshot of an AIDL interface (or parcelable). Do not
+// try to edit this file. It looks like you are doing that because you have
+// modified an AIDL interface in a backward-incompatible way, e.g., deleting a
+// function from an interface or a field from a parcelable and it broke the
+// build. That breakage is intended.
+//
+// You must not make a backward incompatible changes to the AIDL files built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
 package android.net.ipmemorystore;
 parcelable Blob {
   byte[] data;
diff --git a/services/net/aidl/ipmemorystore/3/android/net/ipmemorystore/IOnBlobRetrievedListener.aidl b/services/net/aidl/ipmemorystore/3/android/net/ipmemorystore/IOnBlobRetrievedListener.aidl
index 52f40d4..48c1fb8 100644
--- a/services/net/aidl/ipmemorystore/3/android/net/ipmemorystore/IOnBlobRetrievedListener.aidl
+++ b/services/net/aidl/ipmemorystore/3/android/net/ipmemorystore/IOnBlobRetrievedListener.aidl
@@ -1,3 +1,20 @@
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a frozen snapshot of an AIDL interface (or parcelable). Do not
+// try to edit this file. It looks like you are doing that because you have
+// modified an AIDL interface in a backward-incompatible way, e.g., deleting a
+// function from an interface or a field from a parcelable and it broke the
+// build. That breakage is intended.
+//
+// You must not make a backward incompatible changes to the AIDL files built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
 package android.net.ipmemorystore;
 interface IOnBlobRetrievedListener {
   oneway void onBlobRetrieved(in android.net.ipmemorystore.StatusParcelable status, in String l2Key, in String name, in android.net.ipmemorystore.Blob data);
diff --git a/services/net/aidl/ipmemorystore/3/android/net/ipmemorystore/IOnL2KeyResponseListener.aidl b/services/net/aidl/ipmemorystore/3/android/net/ipmemorystore/IOnL2KeyResponseListener.aidl
index 7853514..aebc724 100644
--- a/services/net/aidl/ipmemorystore/3/android/net/ipmemorystore/IOnL2KeyResponseListener.aidl
+++ b/services/net/aidl/ipmemorystore/3/android/net/ipmemorystore/IOnL2KeyResponseListener.aidl
@@ -1,3 +1,20 @@
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a frozen snapshot of an AIDL interface (or parcelable). Do not
+// try to edit this file. It looks like you are doing that because you have
+// modified an AIDL interface in a backward-incompatible way, e.g., deleting a
+// function from an interface or a field from a parcelable and it broke the
+// build. That breakage is intended.
+//
+// You must not make a backward incompatible changes to the AIDL files built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
 package android.net.ipmemorystore;
 interface IOnL2KeyResponseListener {
   oneway void onL2KeyResponse(in android.net.ipmemorystore.StatusParcelable status, in String l2Key);
diff --git a/services/net/aidl/ipmemorystore/3/android/net/ipmemorystore/IOnNetworkAttributesRetrievedListener.aidl b/services/net/aidl/ipmemorystore/3/android/net/ipmemorystore/IOnNetworkAttributesRetrievedListener.aidl
index 3dd2ae6..b66db5a 100644
--- a/services/net/aidl/ipmemorystore/3/android/net/ipmemorystore/IOnNetworkAttributesRetrievedListener.aidl
+++ b/services/net/aidl/ipmemorystore/3/android/net/ipmemorystore/IOnNetworkAttributesRetrievedListener.aidl
@@ -1,3 +1,20 @@
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a frozen snapshot of an AIDL interface (or parcelable). Do not
+// try to edit this file. It looks like you are doing that because you have
+// modified an AIDL interface in a backward-incompatible way, e.g., deleting a
+// function from an interface or a field from a parcelable and it broke the
+// build. That breakage is intended.
+//
+// You must not make a backward incompatible changes to the AIDL files built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
 package android.net.ipmemorystore;
 interface IOnNetworkAttributesRetrievedListener {
   oneway void onNetworkAttributesRetrieved(in android.net.ipmemorystore.StatusParcelable status, in String l2Key, in android.net.ipmemorystore.NetworkAttributesParcelable attributes);
diff --git a/services/net/aidl/ipmemorystore/3/android/net/ipmemorystore/IOnSameL3NetworkResponseListener.aidl b/services/net/aidl/ipmemorystore/3/android/net/ipmemorystore/IOnSameL3NetworkResponseListener.aidl
index 46d4ecb..e9f2db4 100644
--- a/services/net/aidl/ipmemorystore/3/android/net/ipmemorystore/IOnSameL3NetworkResponseListener.aidl
+++ b/services/net/aidl/ipmemorystore/3/android/net/ipmemorystore/IOnSameL3NetworkResponseListener.aidl
@@ -1,3 +1,20 @@
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a frozen snapshot of an AIDL interface (or parcelable). Do not
+// try to edit this file. It looks like you are doing that because you have
+// modified an AIDL interface in a backward-incompatible way, e.g., deleting a
+// function from an interface or a field from a parcelable and it broke the
+// build. That breakage is intended.
+//
+// You must not make a backward incompatible changes to the AIDL files built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
 package android.net.ipmemorystore;
 interface IOnSameL3NetworkResponseListener {
   oneway void onSameL3NetworkResponse(in android.net.ipmemorystore.StatusParcelable status, in android.net.ipmemorystore.SameL3NetworkResponseParcelable response);
diff --git a/services/net/aidl/ipmemorystore/3/android/net/ipmemorystore/IOnStatusListener.aidl b/services/net/aidl/ipmemorystore/3/android/net/ipmemorystore/IOnStatusListener.aidl
index 54e654b..49172ce 100644
--- a/services/net/aidl/ipmemorystore/3/android/net/ipmemorystore/IOnStatusListener.aidl
+++ b/services/net/aidl/ipmemorystore/3/android/net/ipmemorystore/IOnStatusListener.aidl
@@ -1,3 +1,20 @@
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a frozen snapshot of an AIDL interface (or parcelable). Do not
+// try to edit this file. It looks like you are doing that because you have
+// modified an AIDL interface in a backward-incompatible way, e.g., deleting a
+// function from an interface or a field from a parcelable and it broke the
+// build. That breakage is intended.
+//
+// You must not make a backward incompatible changes to the AIDL files built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
 package android.net.ipmemorystore;
 interface IOnStatusListener {
   oneway void onComplete(in android.net.ipmemorystore.StatusParcelable status);
diff --git a/services/net/aidl/ipmemorystore/3/android/net/ipmemorystore/NetworkAttributesParcelable.aidl b/services/net/aidl/ipmemorystore/3/android/net/ipmemorystore/NetworkAttributesParcelable.aidl
index 9531ea3..188db20 100644
--- a/services/net/aidl/ipmemorystore/3/android/net/ipmemorystore/NetworkAttributesParcelable.aidl
+++ b/services/net/aidl/ipmemorystore/3/android/net/ipmemorystore/NetworkAttributesParcelable.aidl
@@ -1,3 +1,20 @@
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a frozen snapshot of an AIDL interface (or parcelable). Do not
+// try to edit this file. It looks like you are doing that because you have
+// modified an AIDL interface in a backward-incompatible way, e.g., deleting a
+// function from an interface or a field from a parcelable and it broke the
+// build. That breakage is intended.
+//
+// You must not make a backward incompatible changes to the AIDL files built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
 package android.net.ipmemorystore;
 parcelable NetworkAttributesParcelable {
   byte[] assignedV4Address;
diff --git a/services/net/aidl/ipmemorystore/3/android/net/ipmemorystore/SameL3NetworkResponseParcelable.aidl b/services/net/aidl/ipmemorystore/3/android/net/ipmemorystore/SameL3NetworkResponseParcelable.aidl
index 414272b..7a2ed48 100644
--- a/services/net/aidl/ipmemorystore/3/android/net/ipmemorystore/SameL3NetworkResponseParcelable.aidl
+++ b/services/net/aidl/ipmemorystore/3/android/net/ipmemorystore/SameL3NetworkResponseParcelable.aidl
@@ -1,3 +1,20 @@
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a frozen snapshot of an AIDL interface (or parcelable). Do not
+// try to edit this file. It looks like you are doing that because you have
+// modified an AIDL interface in a backward-incompatible way, e.g., deleting a
+// function from an interface or a field from a parcelable and it broke the
+// build. That breakage is intended.
+//
+// You must not make a backward incompatible changes to the AIDL files built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
 package android.net.ipmemorystore;
 parcelable SameL3NetworkResponseParcelable {
   String l2Key1;
diff --git a/services/net/aidl/ipmemorystore/3/android/net/ipmemorystore/StatusParcelable.aidl b/services/net/aidl/ipmemorystore/3/android/net/ipmemorystore/StatusParcelable.aidl
index 92c6779..d9b0678 100644
--- a/services/net/aidl/ipmemorystore/3/android/net/ipmemorystore/StatusParcelable.aidl
+++ b/services/net/aidl/ipmemorystore/3/android/net/ipmemorystore/StatusParcelable.aidl
@@ -1,3 +1,20 @@
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a frozen snapshot of an AIDL interface (or parcelable). Do not
+// try to edit this file. It looks like you are doing that because you have
+// modified an AIDL interface in a backward-incompatible way, e.g., deleting a
+// function from an interface or a field from a parcelable and it broke the
+// build. That breakage is intended.
+//
+// You must not make a backward incompatible changes to the AIDL files built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
 package android.net.ipmemorystore;
 parcelable StatusParcelable {
   int resultCode;
diff --git a/services/net/aidl/networkstack/3/android/net/DhcpResultsParcelable.aidl b/services/net/aidl/networkstack/3/android/net/DhcpResultsParcelable.aidl
index 31891de..07ff321 100644
--- a/services/net/aidl/networkstack/3/android/net/DhcpResultsParcelable.aidl
+++ b/services/net/aidl/networkstack/3/android/net/DhcpResultsParcelable.aidl
@@ -1,3 +1,20 @@
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a frozen snapshot of an AIDL interface (or parcelable). Do not
+// try to edit this file. It looks like you are doing that because you have
+// modified an AIDL interface in a backward-incompatible way, e.g., deleting a
+// function from an interface or a field from a parcelable and it broke the
+// build. That breakage is intended.
+//
+// You must not make a backward incompatible changes to the AIDL files built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
 package android.net;
 parcelable DhcpResultsParcelable {
   android.net.StaticIpConfiguration baseConfiguration;
diff --git a/services/net/aidl/networkstack/3/android/net/INetworkMonitor.aidl b/services/net/aidl/networkstack/3/android/net/INetworkMonitor.aidl
index 029968b..8aa68bd 100644
--- a/services/net/aidl/networkstack/3/android/net/INetworkMonitor.aidl
+++ b/services/net/aidl/networkstack/3/android/net/INetworkMonitor.aidl
@@ -1,3 +1,20 @@
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a frozen snapshot of an AIDL interface (or parcelable). Do not
+// try to edit this file. It looks like you are doing that because you have
+// modified an AIDL interface in a backward-incompatible way, e.g., deleting a
+// function from an interface or a field from a parcelable and it broke the
+// build. That breakage is intended.
+//
+// You must not make a backward incompatible changes to the AIDL files built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
 package android.net;
 interface INetworkMonitor {
   oneway void start();
diff --git a/services/net/aidl/networkstack/3/android/net/INetworkMonitorCallbacks.aidl b/services/net/aidl/networkstack/3/android/net/INetworkMonitorCallbacks.aidl
index ee9871d..ea93729 100644
--- a/services/net/aidl/networkstack/3/android/net/INetworkMonitorCallbacks.aidl
+++ b/services/net/aidl/networkstack/3/android/net/INetworkMonitorCallbacks.aidl
@@ -1,3 +1,20 @@
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a frozen snapshot of an AIDL interface (or parcelable). Do not
+// try to edit this file. It looks like you are doing that because you have
+// modified an AIDL interface in a backward-incompatible way, e.g., deleting a
+// function from an interface or a field from a parcelable and it broke the
+// build. That breakage is intended.
+//
+// You must not make a backward incompatible changes to the AIDL files built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
 package android.net;
 interface INetworkMonitorCallbacks {
   oneway void onNetworkMonitorCreated(in android.net.INetworkMonitor networkMonitor);
diff --git a/services/net/aidl/networkstack/3/android/net/INetworkStackConnector.aidl b/services/net/aidl/networkstack/3/android/net/INetworkStackConnector.aidl
index 7da11e4..e3a83d1 100644
--- a/services/net/aidl/networkstack/3/android/net/INetworkStackConnector.aidl
+++ b/services/net/aidl/networkstack/3/android/net/INetworkStackConnector.aidl
@@ -1,3 +1,20 @@
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a frozen snapshot of an AIDL interface (or parcelable). Do not
+// try to edit this file. It looks like you are doing that because you have
+// modified an AIDL interface in a backward-incompatible way, e.g., deleting a
+// function from an interface or a field from a parcelable and it broke the
+// build. That breakage is intended.
+//
+// You must not make a backward incompatible changes to the AIDL files built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
 package android.net;
 interface INetworkStackConnector {
   oneway void makeDhcpServer(in String ifName, in android.net.dhcp.DhcpServingParamsParcel params, in android.net.dhcp.IDhcpServerCallbacks cb);
diff --git a/services/net/aidl/networkstack/3/android/net/INetworkStackStatusCallback.aidl b/services/net/aidl/networkstack/3/android/net/INetworkStackStatusCallback.aidl
index f6ca6f7..3112a08 100644
--- a/services/net/aidl/networkstack/3/android/net/INetworkStackStatusCallback.aidl
+++ b/services/net/aidl/networkstack/3/android/net/INetworkStackStatusCallback.aidl
@@ -1,3 +1,20 @@
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a frozen snapshot of an AIDL interface (or parcelable). Do not
+// try to edit this file. It looks like you are doing that because you have
+// modified an AIDL interface in a backward-incompatible way, e.g., deleting a
+// function from an interface or a field from a parcelable and it broke the
+// build. That breakage is intended.
+//
+// You must not make a backward incompatible changes to the AIDL files built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
 package android.net;
 interface INetworkStackStatusCallback {
   oneway void onStatusAvailable(int statusCode);
diff --git a/services/net/aidl/networkstack/3/android/net/InitialConfigurationParcelable.aidl b/services/net/aidl/networkstack/3/android/net/InitialConfigurationParcelable.aidl
index c80a787..f846b26 100644
--- a/services/net/aidl/networkstack/3/android/net/InitialConfigurationParcelable.aidl
+++ b/services/net/aidl/networkstack/3/android/net/InitialConfigurationParcelable.aidl
@@ -1,3 +1,20 @@
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a frozen snapshot of an AIDL interface (or parcelable). Do not
+// try to edit this file. It looks like you are doing that because you have
+// modified an AIDL interface in a backward-incompatible way, e.g., deleting a
+// function from an interface or a field from a parcelable and it broke the
+// build. That breakage is intended.
+//
+// You must not make a backward incompatible changes to the AIDL files built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
 package android.net;
 parcelable InitialConfigurationParcelable {
   android.net.LinkAddress[] ipAddresses;
diff --git a/services/net/aidl/networkstack/3/android/net/NattKeepalivePacketDataParcelable.aidl b/services/net/aidl/networkstack/3/android/net/NattKeepalivePacketDataParcelable.aidl
index 65de883..de75940 100644
--- a/services/net/aidl/networkstack/3/android/net/NattKeepalivePacketDataParcelable.aidl
+++ b/services/net/aidl/networkstack/3/android/net/NattKeepalivePacketDataParcelable.aidl
@@ -1,3 +1,20 @@
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a frozen snapshot of an AIDL interface (or parcelable). Do not
+// try to edit this file. It looks like you are doing that because you have
+// modified an AIDL interface in a backward-incompatible way, e.g., deleting a
+// function from an interface or a field from a parcelable and it broke the
+// build. That breakage is intended.
+//
+// You must not make a backward incompatible changes to the AIDL files built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
 package android.net;
 parcelable NattKeepalivePacketDataParcelable {
   byte[] srcAddress;
diff --git a/services/net/aidl/networkstack/3/android/net/PrivateDnsConfigParcel.aidl b/services/net/aidl/networkstack/3/android/net/PrivateDnsConfigParcel.aidl
index 2de790b..cf0fbce9 100644
--- a/services/net/aidl/networkstack/3/android/net/PrivateDnsConfigParcel.aidl
+++ b/services/net/aidl/networkstack/3/android/net/PrivateDnsConfigParcel.aidl
@@ -1,3 +1,20 @@
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a frozen snapshot of an AIDL interface (or parcelable). Do not
+// try to edit this file. It looks like you are doing that because you have
+// modified an AIDL interface in a backward-incompatible way, e.g., deleting a
+// function from an interface or a field from a parcelable and it broke the
+// build. That breakage is intended.
+//
+// You must not make a backward incompatible changes to the AIDL files built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
 package android.net;
 parcelable PrivateDnsConfigParcel {
   String hostname;
diff --git a/services/net/aidl/networkstack/3/android/net/ProvisioningConfigurationParcelable.aidl b/services/net/aidl/networkstack/3/android/net/ProvisioningConfigurationParcelable.aidl
index 3a6c304..c0f2d4d 100644
--- a/services/net/aidl/networkstack/3/android/net/ProvisioningConfigurationParcelable.aidl
+++ b/services/net/aidl/networkstack/3/android/net/ProvisioningConfigurationParcelable.aidl
@@ -1,3 +1,20 @@
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a frozen snapshot of an AIDL interface (or parcelable). Do not
+// try to edit this file. It looks like you are doing that because you have
+// modified an AIDL interface in a backward-incompatible way, e.g., deleting a
+// function from an interface or a field from a parcelable and it broke the
+// build. That breakage is intended.
+//
+// You must not make a backward incompatible changes to the AIDL files built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
 package android.net;
 parcelable ProvisioningConfigurationParcelable {
   boolean enableIPv4;
diff --git a/services/net/aidl/networkstack/3/android/net/TcpKeepalivePacketDataParcelable.aidl b/services/net/aidl/networkstack/3/android/net/TcpKeepalivePacketDataParcelable.aidl
index e121c06..5926794 100644
--- a/services/net/aidl/networkstack/3/android/net/TcpKeepalivePacketDataParcelable.aidl
+++ b/services/net/aidl/networkstack/3/android/net/TcpKeepalivePacketDataParcelable.aidl
@@ -1,3 +1,20 @@
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a frozen snapshot of an AIDL interface (or parcelable). Do not
+// try to edit this file. It looks like you are doing that because you have
+// modified an AIDL interface in a backward-incompatible way, e.g., deleting a
+// function from an interface or a field from a parcelable and it broke the
+// build. That breakage is intended.
+//
+// You must not make a backward incompatible changes to the AIDL files built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
 package android.net;
 parcelable TcpKeepalivePacketDataParcelable {
   byte[] srcAddress;
diff --git a/services/net/aidl/networkstack/3/android/net/dhcp/DhcpServingParamsParcel.aidl b/services/net/aidl/networkstack/3/android/net/dhcp/DhcpServingParamsParcel.aidl
index 67193ae..7ab156f 100644
--- a/services/net/aidl/networkstack/3/android/net/dhcp/DhcpServingParamsParcel.aidl
+++ b/services/net/aidl/networkstack/3/android/net/dhcp/DhcpServingParamsParcel.aidl
@@ -1,3 +1,20 @@
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a frozen snapshot of an AIDL interface (or parcelable). Do not
+// try to edit this file. It looks like you are doing that because you have
+// modified an AIDL interface in a backward-incompatible way, e.g., deleting a
+// function from an interface or a field from a parcelable and it broke the
+// build. That breakage is intended.
+//
+// You must not make a backward incompatible changes to the AIDL files built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
 package android.net.dhcp;
 parcelable DhcpServingParamsParcel {
   int serverAddr;
diff --git a/services/net/aidl/networkstack/3/android/net/dhcp/IDhcpServer.aidl b/services/net/aidl/networkstack/3/android/net/dhcp/IDhcpServer.aidl
index 9143158..d281ecf 100644
--- a/services/net/aidl/networkstack/3/android/net/dhcp/IDhcpServer.aidl
+++ b/services/net/aidl/networkstack/3/android/net/dhcp/IDhcpServer.aidl
@@ -1,3 +1,20 @@
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a frozen snapshot of an AIDL interface (or parcelable). Do not
+// try to edit this file. It looks like you are doing that because you have
+// modified an AIDL interface in a backward-incompatible way, e.g., deleting a
+// function from an interface or a field from a parcelable and it broke the
+// build. That breakage is intended.
+//
+// You must not make a backward incompatible changes to the AIDL files built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
 package android.net.dhcp;
 interface IDhcpServer {
   oneway void start(in android.net.INetworkStackStatusCallback cb);
diff --git a/services/net/aidl/networkstack/3/android/net/dhcp/IDhcpServerCallbacks.aidl b/services/net/aidl/networkstack/3/android/net/dhcp/IDhcpServerCallbacks.aidl
index dcc4489..98be0ab 100644
--- a/services/net/aidl/networkstack/3/android/net/dhcp/IDhcpServerCallbacks.aidl
+++ b/services/net/aidl/networkstack/3/android/net/dhcp/IDhcpServerCallbacks.aidl
@@ -1,3 +1,20 @@
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a frozen snapshot of an AIDL interface (or parcelable). Do not
+// try to edit this file. It looks like you are doing that because you have
+// modified an AIDL interface in a backward-incompatible way, e.g., deleting a
+// function from an interface or a field from a parcelable and it broke the
+// build. That breakage is intended.
+//
+// You must not make a backward incompatible changes to the AIDL files built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
 package android.net.dhcp;
 interface IDhcpServerCallbacks {
   oneway void onDhcpServerCreated(int statusCode, in android.net.dhcp.IDhcpServer server);
diff --git a/services/net/aidl/networkstack/3/android/net/ip/IIpClient.aidl b/services/net/aidl/networkstack/3/android/net/ip/IIpClient.aidl
index 176a5ce..85c8676 100644
--- a/services/net/aidl/networkstack/3/android/net/ip/IIpClient.aidl
+++ b/services/net/aidl/networkstack/3/android/net/ip/IIpClient.aidl
@@ -1,3 +1,20 @@
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a frozen snapshot of an AIDL interface (or parcelable). Do not
+// try to edit this file. It looks like you are doing that because you have
+// modified an AIDL interface in a backward-incompatible way, e.g., deleting a
+// function from an interface or a field from a parcelable and it broke the
+// build. That breakage is intended.
+//
+// You must not make a backward incompatible changes to the AIDL files built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
 package android.net.ip;
 interface IIpClient {
   oneway void completedPreDhcpAction();
diff --git a/services/net/aidl/networkstack/3/android/net/ip/IIpClientCallbacks.aidl b/services/net/aidl/networkstack/3/android/net/ip/IIpClientCallbacks.aidl
index d6bc808..7fe39ed 100644
--- a/services/net/aidl/networkstack/3/android/net/ip/IIpClientCallbacks.aidl
+++ b/services/net/aidl/networkstack/3/android/net/ip/IIpClientCallbacks.aidl
@@ -1,3 +1,20 @@
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a frozen snapshot of an AIDL interface (or parcelable). Do not
+// try to edit this file. It looks like you are doing that because you have
+// modified an AIDL interface in a backward-incompatible way, e.g., deleting a
+// function from an interface or a field from a parcelable and it broke the
+// build. That breakage is intended.
+//
+// You must not make a backward incompatible changes to the AIDL files built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
 package android.net.ip;
 interface IIpClientCallbacks {
   oneway void onIpClientCreated(in android.net.ip.IIpClient ipClient);
diff --git a/services/net/java/android/net/ip/IpClientManager.java b/services/net/java/android/net/ip/IpClientManager.java
index f8d7e84..1e653cd 100644
--- a/services/net/java/android/net/ip/IpClientManager.java
+++ b/services/net/java/android/net/ip/IpClientManager.java
@@ -21,6 +21,7 @@
 import android.net.ProxyInfo;
 import android.net.TcpKeepalivePacketData;
 import android.net.shared.ProvisioningConfiguration;
+import android.net.util.KeepalivePacketDataUtil;
 import android.os.Binder;
 import android.os.RemoteException;
 import android.util.Log;
@@ -229,7 +230,8 @@
     public boolean addKeepalivePacketFilter(int slot, NattKeepalivePacketData pkt) {
         final long token = Binder.clearCallingIdentity();
         try {
-            mIpClient.addNattKeepalivePacketFilter(slot, pkt.toStableParcelable());
+            mIpClient.addNattKeepalivePacketFilter(
+                    slot, KeepalivePacketDataUtil.toStableParcelable(pkt));
             return true;
         } catch (RemoteException e) {
             log("Error adding Keepalive Packet Filter ", e);
diff --git a/services/net/java/android/net/util/KeepalivePacketDataUtil.java b/services/net/java/android/net/util/KeepalivePacketDataUtil.java
new file mode 100644
index 0000000..9a51729
--- /dev/null
+++ b/services/net/java/android/net/util/KeepalivePacketDataUtil.java
@@ -0,0 +1,39 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.net.util;
+
+import android.annotation.NonNull;
+import android.net.NattKeepalivePacketData;
+import android.net.NattKeepalivePacketDataParcelable;
+
+/** @hide */
+public final class KeepalivePacketDataUtil {
+     /**
+     * Convert this NattKeepalivePacketData to a NattKeepalivePacketDataParcelable.
+     */
+    @NonNull
+    public static NattKeepalivePacketDataParcelable toStableParcelable(
+            NattKeepalivePacketData pkt) {
+        final NattKeepalivePacketDataParcelable parcel = new NattKeepalivePacketDataParcelable();
+
+        parcel.srcAddress = pkt.srcAddress.getAddress();
+        parcel.srcPort = pkt.srcPort;
+        parcel.dstAddress = pkt.dstAddress.getAddress();
+        parcel.dstPort = pkt.dstPort;
+        return parcel;
+    }
+}
diff --git a/services/tests/mockingservicestests/src/com/android/server/AlarmManagerServiceTest.java b/services/tests/mockingservicestests/src/com/android/server/AlarmManagerServiceTest.java
index cdcdf91..1e29ed6 100644
--- a/services/tests/mockingservicestests/src/com/android/server/AlarmManagerServiceTest.java
+++ b/services/tests/mockingservicestests/src/com/android/server/AlarmManagerServiceTest.java
@@ -1032,6 +1032,16 @@
         assertEquals(-1, mService.mAlarmsPerUid.get(TEST_CALLING_UID, -1));
     }
 
+    @Test
+    public void alarmCountOnPendingIntentCancel() {
+        final PendingIntent pi = getNewMockPendingIntent();
+        setTestAlarm(ELAPSED_REALTIME_WAKEUP, mNowElapsedTest + 123, pi);
+        verify(pi).registerCancelListener(mService.mOperationCancelListener);
+        assertEquals(1, mService.mAlarmsPerUid.get(TEST_CALLING_UID));
+        mService.mOperationCancelListener.onCancelled(pi);
+        assertEquals(0, mService.mAlarmsPerUid.get(TEST_CALLING_UID));
+    }
+
     @After
     public void tearDown() {
         if (mMockingSession != null) {
diff --git a/services/tests/servicestests/src/com/android/server/appop/AppOpsServiceTest.java b/services/tests/servicestests/src/com/android/server/appop/AppOpsServiceTest.java
index d901179..552058f 100644
--- a/services/tests/servicestests/src/com/android/server/appop/AppOpsServiceTest.java
+++ b/services/tests/servicestests/src/com/android/server/appop/AppOpsServiceTest.java
@@ -37,12 +37,15 @@
 import android.os.HandlerThread;
 import android.os.Process;
 import android.os.RemoteCallback;
+import android.provider.Settings;
 
 import androidx.test.InstrumentationRegistry;
 import androidx.test.filters.SmallTest;
 import androidx.test.runner.AndroidJUnit4;
 
+import org.junit.AfterClass;
 import org.junit.Before;
+import org.junit.BeforeClass;
 import org.junit.Test;
 import org.junit.runner.RunWith;
 
@@ -68,11 +71,14 @@
     private File mAppOpsFile;
     private Context mContext;
     private Handler mHandler;
+    private AppOpsManager mAppOpsManager;
     private AppOpsService mAppOpsService;
     private String mMyPackageName;
     private int mMyUid;
     private long mTestStartMillis;
 
+    private static String sDefaultAppopHistoryParameters;
+
     @Before
     public void setUp() {
         mContext = InstrumentationRegistry.getTargetContext();
@@ -88,11 +94,29 @@
         mMyPackageName = mContext.getOpPackageName();
         mMyUid = Process.myUid();
 
+        mAppOpsManager = mContext.getSystemService(AppOpsManager.class);
         mAppOpsService = new AppOpsService(mAppOpsFile, mHandler);
+        mAppOpsService.mHistoricalRegistry.systemReady(mContext.getContentResolver());
         mAppOpsService.mContext = mContext;
         mTestStartMillis = System.currentTimeMillis();
     }
 
+    @BeforeClass
+    public static void configureDesiredAppopHistoryParameters() {
+        final Context context = InstrumentationRegistry.getTargetContext();
+        sDefaultAppopHistoryParameters = Settings.Global.getString(context.getContentResolver(),
+                Settings.Global.APPOP_HISTORY_PARAMETERS);
+        Settings.Global.putString(InstrumentationRegistry.getTargetContext().getContentResolver(),
+                Settings.Global.APPOP_HISTORY_PARAMETERS, null);
+    }
+
+    @AfterClass
+    public static void restoreDefaultAppopHistoryParameters() {
+        Settings.Global.putString(InstrumentationRegistry.getTargetContext().getContentResolver(),
+                Settings.Global.APPOP_HISTORY_PARAMETERS,
+                sDefaultAppopHistoryParameters);
+    }
+
     @Test
     public void testGetOpsForPackage_noOpsLogged() {
         assertThat(getLoggedOps()).isNull();
diff --git a/services/tests/servicestests/src/com/android/server/attention/AttentionManagerServiceTest.java b/services/tests/servicestests/src/com/android/server/attention/AttentionManagerServiceTest.java
index bb9f49e..184dc3d 100644
--- a/services/tests/servicestests/src/com/android/server/attention/AttentionManagerServiceTest.java
+++ b/services/tests/servicestests/src/com/android/server/attention/AttentionManagerServiceTest.java
@@ -86,6 +86,7 @@
         UserState mUserState = new UserState(0,
                 mContext,
                 mLock,
+                mMockHandler,
                 componentName);
         mUserState.mService = new MockIAttentionService();
         mSpyUserState = spy(mUserState);
diff --git a/services/tests/servicestests/src/com/android/server/content/ObserverNodeTest.java b/services/tests/servicestests/src/com/android/server/content/ObserverNodeTest.java
index 62b0ca8..891ca74 100644
--- a/services/tests/servicestests/src/com/android/server/content/ObserverNodeTest.java
+++ b/services/tests/servicestests/src/com/android/server/content/ObserverNodeTest.java
@@ -30,7 +30,7 @@
 import com.android.server.content.ContentService.ObserverNode;
 
 /**
- * bit FrameworksServicesTests:com.android.server.content.ObserverNodeTest
+ * atest FrameworksServicesTests:com.android.server.content.ObserverNodeTest
  */
 @SmallTest
 public class ObserverNodeTest extends AndroidTestCase {
diff --git a/services/tests/uiservicestests/src/com/android/server/notification/NotificationListenerServiceTest.java b/services/tests/uiservicestests/src/com/android/server/notification/NotificationListenerServiceTest.java
index 52c199a3..397d215 100644
--- a/services/tests/uiservicestests/src/com/android/server/notification/NotificationListenerServiceTest.java
+++ b/services/tests/uiservicestests/src/com/android/server/notification/NotificationListenerServiceTest.java
@@ -16,12 +16,16 @@
 
 package com.android.server.notification;
 
+import static android.app.Notification.EXTRA_SMALL_ICON;
 import static android.service.notification.NotificationListenerService.Ranking.USER_SENTIMENT_NEGATIVE;
 import static android.service.notification.NotificationListenerService.Ranking.USER_SENTIMENT_NEUTRAL;
 import static android.service.notification.NotificationListenerService.Ranking.USER_SENTIMENT_POSITIVE;
 
+import static org.junit.Assert.assertArrayEquals;
 import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotEquals;
 import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertNull;
 import static org.mockito.ArgumentMatchers.any;
 import static org.mockito.ArgumentMatchers.anyInt;
 import static org.mockito.Mockito.mock;
@@ -31,31 +35,49 @@
 import android.app.Notification;
 import android.app.NotificationChannel;
 import android.app.PendingIntent;
+import android.content.Context;
 import android.content.Intent;
+import android.content.pm.ApplicationInfo;
+import android.graphics.Bitmap;
+import android.graphics.drawable.Icon;
 import android.os.Binder;
-import android.os.Bundle;
+import android.os.Build;
 import android.os.IBinder;
+import android.os.Parcel;
 import android.service.notification.NotificationListenerService;
 import android.service.notification.NotificationListenerService.Ranking;
+import android.service.notification.NotificationListenerService.RankingMap;
 import android.service.notification.NotificationRankingUpdate;
 import android.service.notification.SnoozeCriterion;
 import android.test.suitebuilder.annotation.SmallTest;
 
-import androidx.test.runner.AndroidJUnit4;
-
 import com.android.server.UiServiceTestCase;
 
+import org.junit.After;
+import org.junit.Before;
 import org.junit.Test;
 import org.junit.runner.RunWith;
 
 import java.util.ArrayList;
 import java.util.List;
 
+import androidx.test.runner.AndroidJUnit4;
+
 @SmallTest
 @RunWith(AndroidJUnit4.class)
 public class NotificationListenerServiceTest extends UiServiceTestCase {
 
-    private String[] mKeys = new String[] { "key", "key1", "key2", "key3", "key4"};
+    int targetSdk = 0;
+
+    @Before
+    public void setUp() {
+        targetSdk = mContext.getApplicationInfo().targetSdkVersion;
+    }
+
+    @After
+    public void tearDown() {
+        mContext.getApplicationInfo().targetSdkVersion = targetSdk;
+    }
 
     @Test
     public void testGetActiveNotifications_notNull() throws Exception {
@@ -97,52 +119,150 @@
         }
     }
 
-    private NotificationRankingUpdate generateUpdate() {
-        List<String> interceptedKeys = new ArrayList<>();
-        Bundle visibilityOverrides = new Bundle();
-        Bundle overrideGroupKeys = new Bundle();
-        Bundle suppressedVisualEffects = new Bundle();
-        Bundle explanation = new Bundle();
-        Bundle channels = new Bundle();
-        Bundle overridePeople = new Bundle();
-        Bundle snoozeCriteria = new Bundle();
-        Bundle showBadge = new Bundle();
-        int[] importance = new int[mKeys.length];
-        Bundle userSentiment = new Bundle();
-        Bundle mHidden = new Bundle();
-        Bundle smartActions = new Bundle();
-        Bundle smartReplies = new Bundle();
-        Bundle lastAudiblyAlerted = new Bundle();
-        Bundle noisy = new Bundle();
-        boolean[] canBubble = new boolean[mKeys.length];
+    // Tests parceling of NotificationRankingUpdate, and by extension, RankingMap and Ranking.
+    @Test
+    public void testRankingUpdate_parcel() {
+        NotificationRankingUpdate nru = generateUpdate();
+        Parcel parcel = Parcel.obtain();
+        nru.writeToParcel(parcel, 0);
+        parcel.setDataPosition(0);
+        NotificationRankingUpdate nru1 = NotificationRankingUpdate.CREATOR.createFromParcel(parcel);
+        assertEquals(nru, nru1);
+    }
 
+    // Tests parceling of RankingMap and RankingMap.equals
+    @Test
+    public void testRankingMap_parcel() {
+        RankingMap rmap = generateUpdate().getRankingMap();
+        Parcel parcel = Parcel.obtain();
+        rmap.writeToParcel(parcel, 0);
+        parcel.setDataPosition(0);
+        RankingMap rmap1 = RankingMap.CREATOR.createFromParcel(parcel);
+
+        detailedAssertEquals(rmap, rmap1);
+        assertEquals(rmap, rmap1);
+    }
+
+    // Tests parceling of Ranking and Ranking.equals
+    @Test
+    public void testRanking_parcel() {
+        Ranking ranking = generateUpdate().getRankingMap().getRawRankingObject(mKeys[0]);
+        Parcel parcel = Parcel.obtain();
+        ranking.writeToParcel(parcel, 0);
+        parcel.setDataPosition(0);
+        Ranking ranking1 = new Ranking(parcel);
+        detailedAssertEquals("rankings differ: ", ranking, ranking1);
+        assertEquals(ranking, ranking1);
+    }
+
+    // Tests NotificationRankingUpdate.equals(), and by extension, RankingMap and Ranking.
+    @Test
+    public void testRankingUpdate_equals() {
+        NotificationRankingUpdate nru = generateUpdate();
+        NotificationRankingUpdate nru2 = generateUpdate();
+        detailedAssertEquals(nru, nru2);
+        assertEquals(nru, nru2);
+        Ranking tweak = nru2.getRankingMap().getRawRankingObject(mKeys[0]);
+        tweak.populate(
+                tweak.getKey(),
+                tweak.getRank(),
+                !tweak.matchesInterruptionFilter(), // note the inversion here!
+                tweak.getVisibilityOverride(),
+                tweak.getSuppressedVisualEffects(),
+                tweak.getImportance(),
+                tweak.getImportanceExplanation(),
+                tweak.getOverrideGroupKey(),
+                tweak.getChannel(),
+                (ArrayList) tweak.getAdditionalPeople(),
+                (ArrayList) tweak.getSnoozeCriteria(),
+                tweak.canShowBadge(),
+                tweak.getUserSentiment(),
+                tweak.isSuspended(),
+                tweak.getLastAudiblyAlertedMillis(),
+                tweak.isNoisy(),
+                (ArrayList) tweak.getSmartActions(),
+                (ArrayList) tweak.getSmartReplies(),
+                tweak.canBubble()
+        );
+        assertNotEquals(nru, nru2);
+    }
+
+    @Test
+    public void testLegacyIcons_preM() {
+        TestListenerService service = new TestListenerService();
+        service.attachBaseContext(mContext);
+        service.targetSdk = Build.VERSION_CODES.LOLLIPOP_MR1;
+
+        Bitmap largeIcon = Bitmap.createBitmap(100, 200, Bitmap.Config.RGB_565);
+
+        Notification n = new Notification.Builder(mContext, "channel")
+                .setSmallIcon(android.R.drawable.star_on)
+                .setLargeIcon(Icon.createWithBitmap(largeIcon))
+                .setContentTitle("test")
+                .build();
+
+        service.createLegacyIconExtras(n);
+
+        assertEquals(android.R.drawable.star_on, n.extras.getInt(EXTRA_SMALL_ICON));
+        assertEquals(android.R.drawable.star_on, n.icon);
+        assertNotNull(n.largeIcon);
+        assertNotNull(n.extras.getParcelable(Notification.EXTRA_LARGE_ICON));
+    }
+
+    @Test
+    public void testLegacyIcons_mPlus() {
+        TestListenerService service = new TestListenerService();
+        service.attachBaseContext(mContext);
+        service.targetSdk = Build.VERSION_CODES.M;
+
+        Bitmap largeIcon = Bitmap.createBitmap(100, 200, Bitmap.Config.RGB_565);
+
+        Notification n = new Notification.Builder(mContext, "channel")
+                .setSmallIcon(android.R.drawable.star_on)
+                .setLargeIcon(Icon.createWithBitmap(largeIcon))
+                .setContentTitle("test")
+                .build();
+
+        service.createLegacyIconExtras(n);
+
+        assertEquals(0, n.extras.getInt(EXTRA_SMALL_ICON));
+        assertNull(n.largeIcon);
+    }
+
+
+    // Test data
+
+    private String[] mKeys = new String[] { "key", "key1", "key2", "key3", "key4"};
+
+    private NotificationRankingUpdate generateUpdate() {
+        Ranking[] rankings = new Ranking[mKeys.length];
         for (int i = 0; i < mKeys.length; i++) {
-            String key = mKeys[i];
-            visibilityOverrides.putInt(key, getVisibilityOverride(i));
-            overrideGroupKeys.putString(key, getOverrideGroupKey(key));
-            if (isIntercepted(i)) {
-                interceptedKeys.add(key);
-            }
-            suppressedVisualEffects.putInt(key, getSuppressedVisualEffects(i));
-            importance[i] = getImportance(i);
-            explanation.putString(key, getExplanation(key));
-            channels.putParcelable(key, getChannel(key, i));
-            overridePeople.putStringArrayList(key, getPeople(key, i));
-            snoozeCriteria.putParcelableArrayList(key, getSnoozeCriteria(key, i));
-            showBadge.putBoolean(key, getShowBadge(i));
-            userSentiment.putInt(key, getUserSentiment(i));
-            mHidden.putBoolean(key, getHidden(i));
-            smartActions.putParcelableArrayList(key, getSmartActions(key, i));
-            smartReplies.putCharSequenceArrayList(key, getSmartReplies(key, i));
-            lastAudiblyAlerted.putLong(key, lastAudiblyAlerted(i));
-            noisy.putBoolean(key, getNoisy(i));
-            canBubble[i] = canBubble(i);
+            final String key = mKeys[i];
+            Ranking ranking = new Ranking();
+            ranking.populate(
+                    key,
+                    i,
+                    !isIntercepted(i),
+                    getVisibilityOverride(i),
+                    getSuppressedVisualEffects(i),
+                    getImportance(i),
+                    getExplanation(key),
+                    getOverrideGroupKey(key),
+                    getChannel(key, i),
+                    getPeople(key, i),
+                    getSnoozeCriteria(key, i),
+                    getShowBadge(i),
+                    getUserSentiment(i),
+                    getHidden(i),
+                    lastAudiblyAlerted(i),
+                    getNoisy(i),
+                    getSmartActions(key, i),
+                    getSmartReplies(key, i),
+                    canBubble(i)
+            );
+            rankings[i] = ranking;
         }
-        NotificationRankingUpdate update = new NotificationRankingUpdate(mKeys,
-                interceptedKeys.toArray(new String[0]), visibilityOverrides,
-                suppressedVisualEffects, importance, explanation, overrideGroupKeys,
-                channels, overridePeople, snoozeCriteria, showBadge, userSentiment, mHidden,
-                smartActions, smartReplies, lastAudiblyAlerted, noisy, canBubble);
+        NotificationRankingUpdate update = new NotificationRankingUpdate(rankings);
         return update;
     }
 
@@ -253,8 +373,46 @@
         }
     }
 
+    private void detailedAssertEquals(NotificationRankingUpdate a, NotificationRankingUpdate b) {
+        assertEquals(a.getRankingMap(), b.getRankingMap());
+    }
+
+    private void detailedAssertEquals(String comment, Ranking a, Ranking b) {
+        assertEquals(comment, a.getKey(), b.getKey());
+        assertEquals(comment, a.getRank(), b.getRank());
+        assertEquals(comment, a.matchesInterruptionFilter(), b.matchesInterruptionFilter());
+        assertEquals(comment, a.getVisibilityOverride(), b.getVisibilityOverride());
+        assertEquals(comment, a.getSuppressedVisualEffects(), b.getSuppressedVisualEffects());
+        assertEquals(comment, a.getImportance(), b.getImportance());
+        assertEquals(comment, a.getImportanceExplanation(), b.getImportanceExplanation());
+        assertEquals(comment, a.getOverrideGroupKey(), b.getOverrideGroupKey());
+        assertEquals(comment, a.getChannel(), b.getChannel());
+        assertEquals(comment, a.getAdditionalPeople(), b.getAdditionalPeople());
+        assertEquals(comment, a.getSnoozeCriteria(), b.getSnoozeCriteria());
+        assertEquals(comment, a.canShowBadge(), b.canShowBadge());
+        assertEquals(comment, a.getUserSentiment(), b.getUserSentiment());
+        assertEquals(comment, a.isSuspended(), b.isSuspended());
+        assertEquals(comment, a.getLastAudiblyAlertedMillis(), b.getLastAudiblyAlertedMillis());
+        assertEquals(comment, a.isNoisy(), b.isNoisy());
+        assertEquals(comment, a.getSmartReplies(), b.getSmartReplies());
+        assertEquals(comment, a.canBubble(), b.canBubble());
+        assertActionsEqual(a.getSmartActions(), b.getSmartActions());
+    }
+
+    private void detailedAssertEquals(RankingMap a, RankingMap b) {
+        Ranking arank = new Ranking();
+        Ranking brank = new Ranking();
+        assertArrayEquals(a.getOrderedKeys(), b.getOrderedKeys());
+        for (String key : a.getOrderedKeys()) {
+            a.getRanking(key, arank);
+            b.getRanking(key, brank);
+            detailedAssertEquals("ranking for key <" + key + ">", arank, brank);
+        }
+    }
+
     public static class TestListenerService extends NotificationListenerService {
         private final IBinder binder = new LocalBinder();
+        public int targetSdk = 0;
 
         public TestListenerService() {
             mWrapper = mock(NotificationListenerWrapper.class);
@@ -276,5 +434,19 @@
                 return TestListenerService.this;
             }
         }
+
+        @Override
+        protected void attachBaseContext(Context base) {
+            super.attachBaseContext(base);
+        }
+
+        @Override
+        public ApplicationInfo getApplicationInfo() {
+            ApplicationInfo info = super.getApplicationInfo();
+            if (targetSdk != 0) {
+                info.targetSdkVersion = targetSdk;
+            }
+            return info;
+        }
     }
 }
diff --git a/services/tests/wmtests/src/com/android/server/wm/ActivityStarterTests.java b/services/tests/wmtests/src/com/android/server/wm/ActivityStarterTests.java
index 5803385..a08923b 100644
--- a/services/tests/wmtests/src/com/android/server/wm/ActivityStarterTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/ActivityStarterTests.java
@@ -553,7 +553,7 @@
         runAndVerifyBackgroundActivityStartsSubtest("allowed_noStartsAborted", false,
                 UNIMPORTANT_UID, false, PROCESS_STATE_TOP + 1,
                 UNIMPORTANT_UID2, false, PROCESS_STATE_TOP + 1,
-                false, false, false, false, false, false);
+                false, false, false, false, false);
     }
 
     /**
@@ -568,22 +568,22 @@
                 "disallowed_unsupportedUsecase_aborted", true,
                 UNIMPORTANT_UID, false, PROCESS_STATE_TOP + 1,
                 UNIMPORTANT_UID2, false, PROCESS_STATE_TOP + 1,
-                false, false, false, false, false, false);
+                false, false, false, false, false);
         runAndVerifyBackgroundActivityStartsSubtest(
                 "disallowed_callingUidProcessStateTop_aborted", true,
                 UNIMPORTANT_UID, false, PROCESS_STATE_TOP,
                 UNIMPORTANT_UID2, false, PROCESS_STATE_TOP + 1,
-                false, false, false, false, false, false);
+                false, false, false, false, false);
         runAndVerifyBackgroundActivityStartsSubtest(
                 "disallowed_realCallingUidProcessStateTop_aborted", true,
                 UNIMPORTANT_UID, false, PROCESS_STATE_TOP + 1,
                 UNIMPORTANT_UID2, false, PROCESS_STATE_TOP,
-                false, false, false, false, false, false);
+                false, false, false, false, false);
         runAndVerifyBackgroundActivityStartsSubtest(
                 "disallowed_hasForegroundActivities_aborted", true,
                 UNIMPORTANT_UID, false, PROCESS_STATE_TOP + 1,
                 UNIMPORTANT_UID2, false, PROCESS_STATE_TOP + 1,
-                true, false, false, false, false, false);
+                true, false, false, false, false);
     }
 
     /**
@@ -598,51 +598,46 @@
         runAndVerifyBackgroundActivityStartsSubtest("disallowed_rootUid_notAborted", false,
                 Process.ROOT_UID, false, PROCESS_STATE_TOP + 1,
                 UNIMPORTANT_UID2, false, PROCESS_STATE_TOP + 1,
-                false, false, false, false, false, false);
+                false, false, false, false, false);
         runAndVerifyBackgroundActivityStartsSubtest("disallowed_systemUid_notAborted", false,
                 Process.SYSTEM_UID, false, PROCESS_STATE_TOP + 1,
                 UNIMPORTANT_UID2, false, PROCESS_STATE_TOP + 1,
-                false, false, false, false, false, false);
+                false, false, false, false, false);
         runAndVerifyBackgroundActivityStartsSubtest("disallowed_nfcUid_notAborted", false,
                 Process.NFC_UID, false, PROCESS_STATE_TOP + 1,
                 UNIMPORTANT_UID2, false, PROCESS_STATE_TOP + 1,
-                false, false, false, false, false, false);
+                false, false, false, false, false);
         runAndVerifyBackgroundActivityStartsSubtest(
                 "disallowed_callingUidHasVisibleWindow_notAborted", false,
                 UNIMPORTANT_UID, true, PROCESS_STATE_TOP + 1,
                 UNIMPORTANT_UID2, false, PROCESS_STATE_TOP + 1,
-                false, false, false, false, false, false);
+                false, false, false, false, false);
         runAndVerifyBackgroundActivityStartsSubtest(
                 "disallowed_realCallingUidHasVisibleWindow_notAborted", false,
                 UNIMPORTANT_UID, false, PROCESS_STATE_TOP + 1,
                 UNIMPORTANT_UID2, true, PROCESS_STATE_TOP + 1,
-                false, false, false, false, false, false);
+                false, false, false, false, false);
         runAndVerifyBackgroundActivityStartsSubtest(
                 "disallowed_callerIsRecents_notAborted", false,
                 UNIMPORTANT_UID, false, PROCESS_STATE_TOP + 1,
                 UNIMPORTANT_UID2, false, PROCESS_STATE_TOP + 1,
-                false, true, false, false, false, false);
+                false, true, false, false, false);
         runAndVerifyBackgroundActivityStartsSubtest(
                 "disallowed_callerIsWhitelisted_notAborted", false,
                 UNIMPORTANT_UID, false, PROCESS_STATE_TOP + 1,
                 UNIMPORTANT_UID2, false, PROCESS_STATE_TOP + 1,
-                false, false, true, false, false, false);
+                false, false, true, false, false);
         runAndVerifyBackgroundActivityStartsSubtest(
                 "disallowed_callerIsInstrumentingWithBackgroundActivityStartPrivileges_notAborted",
                 false,
                 UNIMPORTANT_UID, false, PROCESS_STATE_TOP + 1,
                 UNIMPORTANT_UID2, false, PROCESS_STATE_TOP + 1,
-                false, false, false, true, false, false);
+                false, false, false, true, false);
         runAndVerifyBackgroundActivityStartsSubtest(
                 "disallowed_callingPackageNameIsDeviceOwner_notAborted", false,
                 UNIMPORTANT_UID, false, PROCESS_STATE_TOP + 1,
                 UNIMPORTANT_UID2, false, PROCESS_STATE_TOP + 1,
-                false, false, false, false, true, false);
-        runAndVerifyBackgroundActivityStartsSubtest(
-                "disallowed_callingPackageNameIsTempWhitelisted_notAborted", false,
-                UNIMPORTANT_UID, false, PROCESS_STATE_TOP + 1,
-                UNIMPORTANT_UID2, false, PROCESS_STATE_TOP + 1,
-                false, false, false, false, false, true);
+                false, false, false, false, true);
     }
 
     private void runAndVerifyBackgroundActivityStartsSubtest(String name, boolean shouldHaveAborted,
@@ -651,7 +646,7 @@
             boolean hasForegroundActivities, boolean callerIsRecents,
             boolean callerIsTempWhitelisted,
             boolean callerIsInstrumentingWithBackgroundActivityStartPrivileges,
-            boolean isCallingUidDeviceOwner, boolean isCallingPackageTempWhitelisted) {
+            boolean isCallingUidDeviceOwner) {
         // window visibility
         doReturn(callingUidHasVisibleWindow).when(mService.mWindowManager.mRoot)
                 .isAnyNonToastWindowVisibleForUid(callingUid);
@@ -679,9 +674,6 @@
                 callerIsInstrumentingWithBackgroundActivityStartPrivileges);
         // callingUid is the device owner
         doReturn(isCallingUidDeviceOwner).when(mService).isDeviceOwner(callingUid);
-        // calling package name is temporarily whitelisted
-        doReturn(isCallingPackageTempWhitelisted).when(mService)
-                .isPackageNameWhitelistedForBgActivityStarts("com.whatever.dude");
 
         final ActivityOptions options = spy(ActivityOptions.makeBasic());
         ActivityStarter starter = prepareStarter(FLAG_ACTIVITY_NEW_TASK)
diff --git a/services/tests/wmtests/src/com/android/server/wm/ActivityTestsBase.java b/services/tests/wmtests/src/com/android/server/wm/ActivityTestsBase.java
index 53b0add..4986a6d 100644
--- a/services/tests/wmtests/src/com/android/server/wm/ActivityTestsBase.java
+++ b/services/tests/wmtests/src/com/android/server/wm/ActivityTestsBase.java
@@ -585,7 +585,10 @@
         }
 
         void tearDown() {
-            mHandlerThread.quitSafely();
+            // Make sure there are no running messages and then quit the thread so the next test
+            // won't be affected.
+            mHandlerThread.getThreadHandler().runWithScissors(mHandlerThread::quit,
+                    0 /* timeout */);
         }
     }
 
@@ -630,7 +633,8 @@
             mWindowManager = prepareMockWindowManager();
             mKeyguardController = mock(KeyguardController.class);
 
-            // Do not schedule idle timeouts
+            // Do not schedule idle that may touch methods outside the scope of the test.
+            doNothing().when(this).scheduleIdleLocked();
             doNothing().when(this).scheduleIdleTimeoutLocked(any());
             // unit test version does not handle launch wake lock
             doNothing().when(this).acquireLaunchWakelock();
diff --git a/services/tests/wmtests/src/com/android/server/wm/RecentsAnimationTest.java b/services/tests/wmtests/src/com/android/server/wm/RecentsAnimationTest.java
index 8f41a42..1f8b33e 100644
--- a/services/tests/wmtests/src/com/android/server/wm/RecentsAnimationTest.java
+++ b/services/tests/wmtests/src/com/android/server/wm/RecentsAnimationTest.java
@@ -24,14 +24,18 @@
 
 import static com.android.dx.mockito.inline.extended.ExtendedMockito.doAnswer;
 import static com.android.dx.mockito.inline.extended.ExtendedMockito.doCallRealMethod;
+import static com.android.dx.mockito.inline.extended.ExtendedMockito.doNothing;
 import static com.android.dx.mockito.inline.extended.ExtendedMockito.doReturn;
 import static com.android.dx.mockito.inline.extended.ExtendedMockito.eq;
 import static com.android.dx.mockito.inline.extended.ExtendedMockito.mock;
 import static com.android.dx.mockito.inline.extended.ExtendedMockito.spyOn;
 import static com.android.dx.mockito.inline.extended.ExtendedMockito.times;
 import static com.android.dx.mockito.inline.extended.ExtendedMockito.verify;
+import static com.android.server.wm.ActivityStack.ActivityState.PAUSED;
 import static com.android.server.wm.RecentsAnimationController.REORDER_KEEP_IN_PLACE;
 
+import static com.google.common.truth.Truth.assertThat;
+
 import static org.junit.Assert.assertFalse;
 import static org.junit.Assert.assertTrue;
 import static org.mockito.ArgumentMatchers.any;
@@ -107,6 +111,39 @@
     }
 
     @Test
+    public void testRestartRecentsActivity() throws Exception {
+        // Have a recents activity that is not attached to its process (ActivityRecord.app = null).
+        ActivityDisplay display = mRootActivityContainer.getDefaultDisplay();
+        ActivityStack recentsStack = display.createStack(WINDOWING_MODE_FULLSCREEN,
+                ACTIVITY_TYPE_RECENTS, true /* onTop */);
+        ActivityRecord recentActivity = new ActivityBuilder(mService).setComponent(
+                mRecentsComponent).setCreateTask(true).setStack(recentsStack).build();
+        WindowProcessController app = recentActivity.app;
+        recentActivity.app = null;
+
+        // Start an activity on top.
+        new ActivityBuilder(mService).setCreateTask(true).build().getActivityStack().moveToFront(
+                "testRestartRecentsActivity");
+
+        doCallRealMethod().when(mRootActivityContainer).ensureActivitiesVisible(
+                any() /* starting */, anyInt() /* configChanges */,
+                anyBoolean() /* preserveWindows */);
+        doReturn(app).when(mService).getProcessController(eq(recentActivity.processName), anyInt());
+        ClientLifecycleManager lifecycleManager = mService.getLifecycleManager();
+        doNothing().when(lifecycleManager).scheduleTransaction(any());
+        AppWarnings appWarnings = mService.getAppWarningsLocked();
+        spyOn(appWarnings);
+        doNothing().when(appWarnings).onStartActivity(any());
+
+        startRecentsActivity();
+
+        // Recents activity must be restarted, but not be resumed while running recents animation.
+        verify(mRootActivityContainer.mStackSupervisor).startSpecificActivityLocked(
+                eq(recentActivity), eq(false), anyBoolean());
+        assertThat(recentActivity.getState()).isEqualTo(PAUSED);
+    }
+
+    @Test
     public void testSetLaunchTaskBehindOfTargetActivity() {
         ActivityDisplay display = mRootActivityContainer.getDefaultDisplay();
         display.mDisplayContent.mBoundsAnimationController = mock(BoundsAnimationController.class);
diff --git a/services/tests/wmtests/src/com/android/server/wm/RootActivityContainerTests.java b/services/tests/wmtests/src/com/android/server/wm/RootActivityContainerTests.java
index c77e25f..8d2c3dd 100644
--- a/services/tests/wmtests/src/com/android/server/wm/RootActivityContainerTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/RootActivityContainerTests.java
@@ -16,6 +16,7 @@
 
 package com.android.server.wm;
 
+import static android.app.WindowConfiguration.ACTIVITY_TYPE_HOME;
 import static android.app.WindowConfiguration.ACTIVITY_TYPE_RECENTS;
 import static android.app.WindowConfiguration.ACTIVITY_TYPE_STANDARD;
 import static android.app.WindowConfiguration.WINDOWING_MODE_FULLSCREEN;
@@ -35,6 +36,7 @@
 import static com.android.dx.mockito.inline.extended.ExtendedMockito.verify;
 import static com.android.server.wm.ActivityDisplay.POSITION_TOP;
 import static com.android.server.wm.ActivityStack.REMOVE_TASK_MODE_DESTROYING;
+import static com.android.server.wm.ActivityStackSupervisor.ON_TOP;
 import static com.android.server.wm.RootActivityContainer.MATCH_TASK_IN_STACKS_OR_RECENT_TASKS_AND_RESTORE;
 
 import static org.junit.Assert.assertEquals;
@@ -397,6 +399,58 @@
     }
 
     /**
+     * Verify that home activity will be started on a display even if another display has a
+     * focusable activity.
+     */
+    @Test
+    public void testResumeFocusedStacksStartsHomeActivity_NoActivities() {
+        mFullscreenStack.remove();
+        mService.mRootActivityContainer.getActivityDisplay(DEFAULT_DISPLAY).getHomeStack().remove();
+        mService.mRootActivityContainer.getActivityDisplay(DEFAULT_DISPLAY)
+                .createStack(WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_HOME, ON_TOP);
+
+        doReturn(true).when(mRootActivityContainer).resumeHomeActivity(any(), any(), anyInt());
+
+        mService.setBooted(true);
+
+        // Trigger resume on all displays
+        mRootActivityContainer.resumeFocusedStacksTopActivities();
+
+        // Verify that home activity was started on the default display
+        verify(mRootActivityContainer).resumeHomeActivity(any(), any(), eq(DEFAULT_DISPLAY));
+    }
+
+    /**
+     * Verify that home activity will be started on a display even if another display has a
+     * focusable activity.
+     */
+    @Test
+    public void testResumeFocusedStacksStartsHomeActivity_ActivityOnSecondaryScreen() {
+        mFullscreenStack.remove();
+        mService.mRootActivityContainer.getActivityDisplay(DEFAULT_DISPLAY).getHomeStack().remove();
+        mService.mRootActivityContainer.getActivityDisplay(DEFAULT_DISPLAY)
+                .createStack(WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_HOME, ON_TOP);
+
+        // Create an activity on secondary display.
+        final TestActivityDisplay secondDisplay = addNewActivityDisplayAt(
+                ActivityDisplay.POSITION_TOP);
+        final ActivityStack stack = secondDisplay.createStack(WINDOWING_MODE_FULLSCREEN,
+                ACTIVITY_TYPE_STANDARD, true /* onTop */);
+        final TaskRecord task = new TaskBuilder(mSupervisor).setStack(stack).build();
+        new ActivityBuilder(mService).setTask(task).build();
+
+        doReturn(true).when(mRootActivityContainer).resumeHomeActivity(any(), any(), anyInt());
+
+        mService.setBooted(true);
+
+        // Trigger resume on all displays
+        mRootActivityContainer.resumeFocusedStacksTopActivities();
+
+        // Verify that home activity was started on the default display
+        verify(mRootActivityContainer).resumeHomeActivity(any(), any(), eq(DEFAULT_DISPLAY));
+    }
+
+    /**
      * Verify that a lingering transition is being executed in case the activity to be resumed is
      * already resumed
      */
diff --git a/services/voiceinteraction/java/com/android/server/voiceinteraction/VoiceInteractionManagerService.java b/services/voiceinteraction/java/com/android/server/voiceinteraction/VoiceInteractionManagerService.java
index d77ea6e..e1ffb0f 100644
--- a/services/voiceinteraction/java/com/android/server/voiceinteraction/VoiceInteractionManagerService.java
+++ b/services/voiceinteraction/java/com/android/server/voiceinteraction/VoiceInteractionManagerService.java
@@ -77,7 +77,6 @@
 import com.android.internal.util.Preconditions;
 import com.android.server.FgThread;
 import com.android.server.LocalServices;
-import com.android.server.SystemServerInitThreadPool;
 import com.android.server.SystemService;
 import com.android.server.UiThread;
 import com.android.server.soundtrigger.SoundTriggerInternal;
@@ -1284,9 +1283,7 @@
                 mRm.addOnRoleHoldersChangedListenerAsUser(executor, this, UserHandle.ALL);
                 UserHandle currentUser = UserHandle.of(LocalServices.getService(
                         ActivityManagerInternal.class).getCurrentUserId());
-                SystemServerInitThreadPool.get().submit(() -> onRoleHoldersChanged(
-                        RoleManager.ROLE_ASSISTANT, currentUser),
-                        "VoiceInteractionManagerService RoleObserver initialization");
+                onRoleHoldersChanged(RoleManager.ROLE_ASSISTANT, currentUser);
             }
 
             private @NonNull String getDefaultRecognizer(@NonNull UserHandle user) {
diff --git a/telecomm/java/android/telecom/Conference.java b/telecomm/java/android/telecom/Conference.java
index 6000b56..cd5fd97 100644
--- a/telecomm/java/android/telecom/Conference.java
+++ b/telecomm/java/android/telecom/Conference.java
@@ -95,6 +95,10 @@
     private Bundle mExtras;
     private Set<String> mPreviousExtraKeys;
     private final Object mExtrasLock = new Object();
+    private Uri mAddress;
+    private int mAddressPresentation;
+    private String mCallerDisplayName;
+    private int mCallerDisplayNamePresentation;
 
     private final Connection.Listener mConnectionDeathListener = new Connection.Listener() {
         @Override
@@ -987,12 +991,67 @@
      */
     public final void setAddress(Uri address, int presentation) {
         Log.d(this, "setAddress %s", address);
+        mAddress = address;
+        mAddressPresentation = presentation;
         for (Listener l : mListeners) {
             l.onAddressChanged(this, address, presentation);
         }
     }
 
     /**
+     * Returns the "address" associated with the conference.  This is applicable in two cases:
+     * <ol>
+     *     <li>When {@link #setConferenceState(boolean)} is used to mark a conference as
+     *     temporarily "not a conference"; we need to present the correct address in the in-call
+     *     UI.</li>
+     *     <li>When the conference is not hosted on the current device, we need to know the address
+     *     information for the purpose of showing the original address to the user, as well as for
+     *     logging to the call log.</li>
+     * </ol>
+     * @return The address of the conference, or {@code null} if not applicable.
+     * @hide
+     */
+    public final Uri getAddress() {
+        return mAddress;
+    }
+
+    /**
+     * Returns the address presentation associated with the conference.
+     * <p>
+     * This is applicable in two cases:
+     * <ol>
+     *     <li>When {@link #setConferenceState(boolean)} is used to mark a conference as
+     *     temporarily "not a conference"; we need to present the correct address in the in-call
+     *     UI.</li>
+     *     <li>When the conference is not hosted on the current device, we need to know the address
+     *     information for the purpose of showing the original address to the user, as well as for
+     *     logging to the call log.</li>
+     * </ol>
+     * @return The address of the conference, or {@code null} if not applicable.
+     * @hide
+     */
+    public final int getAddressPresentation() {
+        return mAddressPresentation;
+    }
+
+    /**
+     * @return The caller display name (CNAP).
+     * @hide
+     */
+    public final String getCallerDisplayName() {
+        return mCallerDisplayName;
+    }
+
+    /**
+     * @return The presentation requirements for the handle.
+     *         See {@link TelecomManager} for valid values.
+     * @hide
+     */
+    public final int getCallerDisplayNamePresentation() {
+        return mCallerDisplayNamePresentation;
+    }
+
+    /**
      * Sets the caller display name (CNAP) of this {@link Conference}.  Used when
      * {@link #setConferenceState(boolean)} is called to mark a conference temporarily as NOT a
      * conference.
@@ -1004,6 +1063,8 @@
      */
     public final void setCallerDisplayName(String callerDisplayName, int presentation) {
         Log.d(this, "setCallerDisplayName %s", callerDisplayName);
+        mCallerDisplayName = callerDisplayName;
+        mCallerDisplayNamePresentation = presentation;
         for (Listener l : mListeners) {
             l.onCallerDisplayNameChanged(this, callerDisplayName, presentation);
         }
diff --git a/telecomm/java/android/telecom/Connection.java b/telecomm/java/android/telecom/Connection.java
index 28e6596..47587c5 100644
--- a/telecomm/java/android/telecom/Connection.java
+++ b/telecomm/java/android/telecom/Connection.java
@@ -424,8 +424,16 @@
      */
     public static final int PROPERTY_NETWORK_IDENTIFIED_EMERGENCY_CALL = 1 << 10;
 
+    /**
+     * Set by the framework to indicate that a Conference or Connection is hosted by a device other
+     * than the current one.  Used in scenarios where the conference originator is the remote device
+     * and the current device is a participant of that conference.
+     * @hide
+     */
+    public static final int PROPERTY_REMOTELY_HOSTED = 1 << 11;
+
     //**********************************************************************************************
-    // Next PROPERTY value: 1<<10
+    // Next PROPERTY value: 1<<12
     //**********************************************************************************************
 
     /**
@@ -850,6 +858,10 @@
             builder.append(isLong ? " PROPERTY_NETWORK_IDENTIFIED_EMERGENCY_CALL" : " ecall");
         }
 
+        if (can(properties, PROPERTY_REMOTELY_HOSTED)) {
+            builder.append(isLong ? " PROPERTY_REMOTELY_HOSTED" : " remote_hst");
+        }
+
         builder.append("]");
         return builder.toString();
     }
diff --git a/telecomm/java/android/telecom/ConnectionService.java b/telecomm/java/android/telecom/ConnectionService.java
index c66e92b..626fcc4 100644
--- a/telecomm/java/android/telecom/ConnectionService.java
+++ b/telecomm/java/android/telecom/ConnectionService.java
@@ -2056,7 +2056,11 @@
                     conference.getConnectTimeMillis(),
                     conference.getConnectionStartElapsedRealTime(),
                     conference.getStatusHints(),
-                    conference.getExtras());
+                    conference.getExtras(),
+                    conference.getAddress(),
+                    conference.getAddressPresentation(),
+                    conference.getCallerDisplayName(),
+                    conference.getCallerDisplayNamePresentation());
 
             mAdapter.addConferenceCall(id, parcelableConference);
             mAdapter.setVideoProvider(id, conference.getVideoProvider());
diff --git a/telecomm/java/android/telecom/ConnectionServiceAdapter.java b/telecomm/java/android/telecom/ConnectionServiceAdapter.java
index 3acd83a..04e930c 100644
--- a/telecomm/java/android/telecom/ConnectionServiceAdapter.java
+++ b/telecomm/java/android/telecom/ConnectionServiceAdapter.java
@@ -325,6 +325,15 @@
             } catch (RemoteException e) {
                 Log.e(this, e, "Exception trying to query for remote CSs");
             }
+        } else {
+            try {
+                // This is not an error condition, so just pass back an empty list.
+                // This happens when querying from a remote connection service, not the connection
+                // manager itself.
+                callback.onResult(Collections.EMPTY_LIST, Collections.EMPTY_LIST);
+            } catch (RemoteException e) {
+                Log.e(this, e, "Exception trying to query for remote CSs");
+            }
         }
     }
 
diff --git a/telecomm/java/android/telecom/ConnectionServiceAdapterServant.java b/telecomm/java/android/telecom/ConnectionServiceAdapterServant.java
index b281589..60b2172 100644
--- a/telecomm/java/android/telecom/ConnectionServiceAdapterServant.java
+++ b/telecomm/java/android/telecom/ConnectionServiceAdapterServant.java
@@ -477,7 +477,7 @@
             SomeArgs args = SomeArgs.obtain();
             args.arg1 = callback;
             args.arg2 = callingPackage;
-            mHandler.obtainMessage(MSG_QUERY_REMOTE_CALL_SERVICES, callback).sendToTarget();
+            mHandler.obtainMessage(MSG_QUERY_REMOTE_CALL_SERVICES, args).sendToTarget();
         }
 
         @Override
diff --git a/telecomm/java/android/telecom/ParcelableConference.java b/telecomm/java/android/telecom/ParcelableConference.java
index 636e4b2..ede0594 100644
--- a/telecomm/java/android/telecom/ParcelableConference.java
+++ b/telecomm/java/android/telecom/ParcelableConference.java
@@ -16,6 +16,7 @@
 
 package android.telecom;
 
+import android.net.Uri;
 import android.os.Bundle;
 import android.os.Parcel;
 import android.os.Parcelable;
@@ -42,6 +43,10 @@
     private StatusHints mStatusHints;
     private Bundle mExtras;
     private long mConnectElapsedTimeMillis = Conference.CONNECT_TIME_NOT_SPECIFIED;
+    private final Uri mAddress;
+    private final int mAddressPresentation;
+    private final String mCallerDisplayName;
+    private final int mCallerDisplayNamePresentation;
 
     public ParcelableConference(
             PhoneAccountHandle phoneAccount,
@@ -54,7 +59,11 @@
             long connectTimeMillis,
             long connectElapsedTimeMillis,
             StatusHints statusHints,
-            Bundle extras) {
+            Bundle extras,
+            Uri address,
+            int addressPresentation,
+            String callerDisplayName,
+            int callerDisplayNamePresentation) {
         mPhoneAccount = phoneAccount;
         mState = state;
         mConnectionCapabilities = connectionCapabilities;
@@ -66,6 +75,10 @@
         mStatusHints = statusHints;
         mExtras = extras;
         mConnectElapsedTimeMillis = connectElapsedTimeMillis;
+        mAddress = address;
+        mAddressPresentation = addressPresentation;
+        mCallerDisplayName = callerDisplayName;
+        mCallerDisplayNamePresentation = callerDisplayNamePresentation;
     }
 
     @Override
@@ -134,6 +147,14 @@
         return mExtras;
     }
 
+    public Uri getHandle() {
+        return mAddress;
+    }
+
+    public int getHandlePresentation() {
+        return mAddressPresentation;
+    }
+
     public static final @android.annotation.NonNull Parcelable.Creator<ParcelableConference> CREATOR =
             new Parcelable.Creator<ParcelableConference> () {
         @Override
@@ -152,10 +173,15 @@
             Bundle extras = source.readBundle(classLoader);
             int properties = source.readInt();
             long connectElapsedTimeMillis = source.readLong();
+            Uri address = source.readParcelable(classLoader);
+            int addressPresentation = source.readInt();
+            String callerDisplayName = source.readString();
+            int callerDisplayNamePresentation = source.readInt();
 
             return new ParcelableConference(phoneAccount, state, capabilities, properties,
                     connectionIds, videoCallProvider, videoState, connectTimeMillis,
-                    connectElapsedTimeMillis, statusHints, extras);
+                    connectElapsedTimeMillis, statusHints, extras, address, addressPresentation,
+                    callerDisplayName, callerDisplayNamePresentation);
         }
 
         @Override
@@ -185,5 +211,9 @@
         destination.writeBundle(mExtras);
         destination.writeInt(mConnectionProperties);
         destination.writeLong(mConnectElapsedTimeMillis);
+        destination.writeParcelable(mAddress, 0);
+        destination.writeInt(mAddressPresentation);
+        destination.writeString(mCallerDisplayName);
+        destination.writeInt(mCallerDisplayNamePresentation);
     }
 }
diff --git a/telephony/java/android/telephony/CarrierConfigManager.java b/telephony/java/android/telephony/CarrierConfigManager.java
index a125e31..9806199 100755
--- a/telephony/java/android/telephony/CarrierConfigManager.java
+++ b/telephony/java/android/telephony/CarrierConfigManager.java
@@ -1132,6 +1132,7 @@
      * <li>  8: Wi-Fi</li>
      * <li>  9: WiFi Calling</li>
      * <li> 10: VoWifi</li>
+     * <li> 11: %s WiFi Calling</li>
      * @hide
      */
     public static final String KEY_WFC_SPN_FORMAT_IDX_INT = "wfc_spn_format_idx_int";
@@ -2684,6 +2685,30 @@
         public static final String KEY_PREFIX = "gps.";
 
         /**
+         * Location information during (and after) an emergency call is only provided over control
+         * plane signaling from the network.
+         * @hide
+         */
+        public static final int SUPL_EMERGENCY_MODE_TYPE_CP_ONLY = 0;
+
+        /**
+         * Location information during (and after) an emergency call is provided over the data
+         * plane and serviced by the framework GNSS service, but if it fails, the carrier also
+         * supports control plane backup signaling.
+         * @hide
+         */
+        public static final int SUPL_EMERGENCY_MODE_TYPE_CP_FALLBACK = 1;
+
+        /**
+         * Location information during (and after) an emergency call is provided over the data plane
+         * and serviced by the framework GNSS service only. There is no backup signalling over the
+         * control plane if it fails.
+         * @hide
+         */
+        public static final int SUPL_EMERGENCY_MODE_TYPE_DP_ONLY = 2;
+
+
+        /**
          * Determine whether current lpp_mode used for E-911 needs to be kept persistently.
          * {@code false} - not keeping the lpp_mode means using default configuration of gps.conf
          *                 when sim is not presented.
@@ -2774,6 +2799,23 @@
          */
         public static final String KEY_NFW_PROXY_APPS_STRING = KEY_PREFIX + "nfw_proxy_apps";
 
+        /**
+         * Determines whether or not SUPL ES mode supports a control-plane mechanism to get a user's
+         * location in the event that data plane SUPL fails or is otherwise unavailable.
+         * <p>
+         * An integer value determines the support type of this carrier. If this carrier only
+         * supports data plane SUPL ES, then the value will be
+         * {@link #SUPL_EMERGENCY_MODE_TYPE_DP_ONLY}. If the carrier supports control plane fallback
+         * for emergency SUPL, the value will be {@link #SUPL_EMERGENCY_MODE_TYPE_CP_FALLBACK}.
+         * If the carrier does not support data plane SUPL using the framework, the value will be
+         * {@link #SUPL_EMERGENCY_MODE_TYPE_CP_ONLY}.
+         * <p>
+         * The default value for this configuration is {@link #SUPL_EMERGENCY_MODE_TYPE_CP_ONLY}.
+         * @hide
+         */
+        public static final String KEY_ES_SUPL_CONTROL_PLANE_SUPPORT_INT = KEY_PREFIX
+                + "es_supl_control_plane_support_int";
+
         private static PersistableBundle getDefaults() {
             PersistableBundle defaults = new PersistableBundle();
             defaults.putBoolean(KEY_PERSIST_LPP_MODE_BOOL, true);
@@ -2788,6 +2830,8 @@
             defaults.putString(KEY_GPS_LOCK_STRING, "3");
             defaults.putString(KEY_ES_EXTENSION_SEC_STRING, "0");
             defaults.putString(KEY_NFW_PROXY_APPS_STRING, "");
+            defaults.putInt(KEY_ES_SUPL_CONTROL_PLANE_SUPPORT_INT,
+                    SUPL_EMERGENCY_MODE_TYPE_CP_ONLY);
             return defaults;
         }
     }
diff --git a/telephony/java/android/telephony/ServiceState.java b/telephony/java/android/telephony/ServiceState.java
index 5d39a2c..518da74 100644
--- a/telephony/java/android/telephony/ServiceState.java
+++ b/telephony/java/android/telephony/ServiceState.java
@@ -16,6 +16,8 @@
 
 package android.telephony;
 
+import static android.telephony.TelephonyManager.NETWORK_TYPE_BITMASK_UNKNOWN;
+
 import android.annotation.IntDef;
 import android.annotation.NonNull;
 import android.annotation.Nullable;
@@ -1605,6 +1607,12 @@
         }
     }
 
+    /** @hide */
+    public static int networkTypeToAccessNetworkType(@TelephonyManager.NetworkType
+            int networkType) {
+        return rilRadioTechnologyToAccessNetworkType(networkTypeToRilRadioTechnology(networkType));
+    }
+
     /**
      * Get current data network type.
      *
@@ -1730,6 +1738,36 @@
         return false;
     }
 
+    /**
+     *
+     * Returns whether the bearerBitmask includes a networkType that matches the accessNetworkType.
+     *
+     * The NetworkType refers to NetworkType in TelephonyManager. For example
+     * {@link TelephonyManager#NETWORK_TYPE_GPRS}.
+     *
+     * The accessNetworkType refers to {@link AccessNetworkType}.
+     *
+     * @hide
+     * */
+    public static boolean networkBitmaskHasAccessNetworkType(
+            @TelephonyManager.NetworkTypeBitMask int networkBitmask, int accessNetworkType) {
+        if (networkBitmask == NETWORK_TYPE_BITMASK_UNKNOWN) return true;
+        if (accessNetworkType == AccessNetworkType.UNKNOWN) return false;
+
+        int networkType = 1;
+        while (networkBitmask != 0) {
+            if ((networkBitmask & 1) != 0) {
+                if (networkTypeToAccessNetworkType(networkType) == accessNetworkType) {
+                    return true;
+                }
+            }
+            networkBitmask = networkBitmask >> 1;
+            networkType++;
+        }
+
+        return false;
+    }
+
     /** @hide */
     public static int getBitmaskForTech(int radioTech) {
         if (radioTech >= 1) {
diff --git a/telephony/java/android/telephony/SmsManager.java b/telephony/java/android/telephony/SmsManager.java
index 6860235..b44e4f1 100644
--- a/telephony/java/android/telephony/SmsManager.java
+++ b/telephony/java/android/telephony/SmsManager.java
@@ -1975,9 +1975,11 @@
      */
     public static int getDefaultSmsSubscriptionId() {
         try {
-            return getISmsServiceOrThrow().getPreferredSmsSubscription();
+            return getISmsService().getPreferredSmsSubscription();
         } catch (RemoteException e) {
             return SubscriptionManager.INVALID_SUBSCRIPTION_ID;
+        } catch (NullPointerException e) {
+            return SubscriptionManager.INVALID_SUBSCRIPTION_ID;
         }
     }
 
diff --git a/telephony/java/android/telephony/SubscriptionManager.java b/telephony/java/android/telephony/SubscriptionManager.java
index addd9e0..65db458 100644
--- a/telephony/java/android/telephony/SubscriptionManager.java
+++ b/telephony/java/android/telephony/SubscriptionManager.java
@@ -302,11 +302,27 @@
      * subscription.
      *
      * Default value is 0.
+     *
+     * @deprecated Replaced by {@link #DATA_ENABLED_OVERRIDE_RULES}
+     * @hide
      */
-    /** @hide */
+    @Deprecated
     public static final String WHITE_LISTED_APN_DATA = "white_listed_apn_data";
 
     /**
+     * TelephonyProvider column name data_enabled_override_rules.
+     * It's a list of rules for overriding data enabled settings. The syntax is
+     * For example, "mms=nonDefault" indicates enabling data for mms in non-default subscription.
+     * "default=nonDefault&inVoiceCall" indicates enabling data for internet in non-default
+     * subscription and while is in voice call.
+     *
+     * Default value is empty string.
+     *
+     * @hide
+     */
+    public static final String DATA_ENABLED_OVERRIDE_RULES = "data_enabled_override_rules";
+
+    /**
      * This constant is to designate a subscription as a Local-SIM Subscription.
      * <p> A Local-SIM can be a physical SIM inserted into a sim-slot in the device, or eSIM on the
      * device.
diff --git a/telephony/java/android/telephony/TelephonyManager.java b/telephony/java/android/telephony/TelephonyManager.java
index 2ba34c6..b7b511e 100644
--- a/telephony/java/android/telephony/TelephonyManager.java
+++ b/telephony/java/android/telephony/TelephonyManager.java
@@ -105,6 +105,7 @@
 import java.util.List;
 import java.util.Locale;
 import java.util.Map;
+import java.util.UUID;
 import java.util.concurrent.Executor;
 import java.util.function.Consumer;
 import java.util.regex.Matcher;
@@ -1497,6 +1498,48 @@
      */
     public static final int EXTRA_DEFAULT_SUBSCRIPTION_SELECT_TYPE_ALL = 4;
 
+    /**
+     * Integer intent extra to be used with {@link #ACTION_PRIMARY_SUBSCRIPTION_LIST_CHANGED}
+     * to indicate if the SIM combination in DSDS has limitation or compatible issue.
+     * e.g. two CDMA SIMs may disrupt each other's voice call in certain scenarios.
+     *
+     * @hide
+     */
+    public static final String EXTRA_SIM_COMBINATION_WARNING_TYPE =
+            "android.telephony.extra.SIM_COMBINATION_WARNING_TYPE";
+
+    /** @hide */
+    @IntDef({
+            EXTRA_SIM_COMBINATION_WARNING_TYPE_NONE,
+            EXTRA_SIM_COMBINATION_WARNING_TYPE_DUAL_CDMA
+    })
+    @Retention(RetentionPolicy.SOURCE)
+    public @interface SimCombinationWarningType{}
+
+    /**
+     * Used as an int value for {@link #EXTRA_DEFAULT_SUBSCRIPTION_SELECT_TYPE}
+     * to indicate there's no SIM combination warning.
+     * @hide
+     */
+    public static final int EXTRA_SIM_COMBINATION_WARNING_TYPE_NONE = 0;
+
+    /**
+     * Used as an int value for {@link #EXTRA_DEFAULT_SUBSCRIPTION_SELECT_TYPE}
+     * to indicate two active SIMs are both CDMA hence there might be functional limitation.
+     * @hide
+     */
+    public static final int EXTRA_SIM_COMBINATION_WARNING_TYPE_DUAL_CDMA = 1;
+
+    /**
+     * String intent extra to be used with {@link #ACTION_PRIMARY_SUBSCRIPTION_LIST_CHANGED}
+     * to indicate what's the name of SIM combination it has limitation or compatible issue.
+     * e.g. two CDMA SIMs may disrupt each other's voice call in certain scenarios, and the
+     * name will be "operator1 & operator2".
+     *
+     * @hide
+     */
+    public static final String EXTRA_SIM_COMBINATION_NAMES =
+            "android.telephony.extra.SIM_COMBINATION_NAMES";
     //
     //
     // Device Info
@@ -9239,6 +9282,10 @@
             }
         } catch (RemoteException e) {
             Log.e(TAG, "Error calling ITelephony#getServiceStateForSubscriber", e);
+        } catch (NullPointerException e) {
+            AnomalyReporter.reportAnomaly(
+                    UUID.fromString("a3ab0b9d-f2aa-4baf-911d-7096c0d4645a"),
+                    "getServiceStateForSubscriber " + subId + " NPE");
         }
         return null;
     }
@@ -11141,4 +11188,52 @@
         }
         return true;
     }
+
+    /**
+     * Set allowing mobile data during voice call.
+     *
+     * @param allow {@code true} if allowing using data during voice call, {@code false} if
+     * disallowed
+     *
+     * @return {@code false} if the setting is changed.
+     *
+     * @hide
+     */
+    @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE)
+    public boolean setDataAllowedDuringVoiceCall(boolean allow) {
+        try {
+            ITelephony service = getITelephony();
+            if (service != null) {
+                return service.setDataAllowedDuringVoiceCall(getSubId(), allow);
+            }
+        } catch (RemoteException ex) {
+            if (!isSystemProcess()) {
+                ex.rethrowAsRuntimeException();
+            }
+        }
+        return false;
+    }
+
+    /**
+     * Check whether data is allowed during voice call. Note this is for dual sim device that
+     * data might be disabled on non-default data subscription but explicitly turned on by settings.
+     *
+     * @return {@code true} if data is allowed during voice call.
+     *
+     * @hide
+     */
+    @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE)
+    public boolean isDataAllowedInVoiceCall() {
+        try {
+            ITelephony service = getITelephony();
+            if (service != null) {
+                return service.isDataAllowedInVoiceCall(getSubId());
+            }
+        } catch (RemoteException ex) {
+            if (!isSystemProcess()) {
+                ex.rethrowAsRuntimeException();
+            }
+        }
+        return false;
+    }
 }
diff --git a/telephony/java/android/telephony/data/ApnSetting.java b/telephony/java/android/telephony/data/ApnSetting.java
index a78bae4..165be64 100644
--- a/telephony/java/android/telephony/data/ApnSetting.java
+++ b/telephony/java/android/telephony/data/ApnSetting.java
@@ -1310,6 +1310,9 @@
      * @hide
      */
     public static String getApnTypeString(int apnType) {
+        if (apnType == TYPE_ALL) {
+            return "*";
+        }
         String apnTypeString = APN_TYPE_INT_MAP.get(apnType);
         return apnTypeString == null ? "Unknown" : apnTypeString;
     }
diff --git a/telephony/java/com/android/internal/telephony/DctConstants.java b/telephony/java/com/android/internal/telephony/DctConstants.java
index bb5c251..cde6db4 100644
--- a/telephony/java/com/android/internal/telephony/DctConstants.java
+++ b/telephony/java/com/android/internal/telephony/DctConstants.java
@@ -94,7 +94,7 @@
     public static final int EVENT_ROAMING_SETTING_CHANGE = BASE + 48;
     public static final int EVENT_DATA_SERVICE_BINDING_CHANGED = BASE + 49;
     public static final int EVENT_DEVICE_PROVISIONED_CHANGE = BASE + 50;
-    public static final int EVENT_APN_WHITE_LIST_CHANGE = BASE + 51;
+    public static final int EVENT_DATA_ENABLED_OVERRIDE_RULES_CHANGED = BASE + 51;
 
     /***** Constants *****/
 
diff --git a/telephony/java/com/android/internal/telephony/ITelephony.aidl b/telephony/java/com/android/internal/telephony/ITelephony.aidl
index cf1323a..5a27a0f 100644
--- a/telephony/java/com/android/internal/telephony/ITelephony.aidl
+++ b/telephony/java/com/android/internal/telephony/ITelephony.aidl
@@ -1619,7 +1619,7 @@
      * <p>
      * See {@link UiccCardInfo} for more details on the kind of information available.
      *
-     * @param callingPackage package making the call, used to evaluate carrier privileges 
+     * @param callingPackage package making the call, used to evaluate carrier privileges
      * @return a list of UiccCardInfo objects, representing information on the currently inserted
      * UICCs and eUICCs. Each UiccCardInfo in the list will have private information filtered out if
      * the caller does not have adequate permissions for that card.
@@ -1996,4 +1996,15 @@
      * Returns the MMS user agent profile URL.
      */
     String getMmsUAProfUrl(int subId);
+
+    /**
+     * Set allowing mobile data during voice call.
+     */
+    boolean setDataAllowedDuringVoiceCall(int subId, boolean allow);
+
+    /**
+     * Check whether data is allowed during voice call. Note this is for dual sim device that
+     * data might be disabled on non-default data subscription but explicitly turned on by settings.
+     */
+    boolean isDataAllowedInVoiceCall(int subId);
 }
diff --git a/telephony/java/com/android/internal/telephony/SmsApplication.java b/telephony/java/com/android/internal/telephony/SmsApplication.java
index ef7c605..44dc24b 100644
--- a/telephony/java/com/android/internal/telephony/SmsApplication.java
+++ b/telephony/java/com/android/internal/telephony/SmsApplication.java
@@ -465,7 +465,11 @@
             int userId) {
         TelephonyManager tm = (TelephonyManager)
                 context.getSystemService(Context.TELEPHONY_SERVICE);
-        if (!tm.isSmsCapable()) {
+        RoleManager roleManager = (RoleManager) context.getSystemService(Context.ROLE_SERVICE);
+        // (b/134400042) RoleManager might be null in unit tests running older mockito versions
+        // that do not support mocking final classes.
+        if (!tm.isSmsCapable() && (roleManager == null || !roleManager.isRoleAvailable(
+                RoleManager.ROLE_SMS))) {
             // No phone, no SMS
             return null;
         }
@@ -584,7 +588,11 @@
     public static void setDefaultApplicationAsUser(String packageName, Context context,
             int userId) {
         TelephonyManager tm = (TelephonyManager)context.getSystemService(Context.TELEPHONY_SERVICE);
-        if (!tm.isSmsCapable()) {
+        RoleManager roleManager = (RoleManager) context.getSystemService(Context.ROLE_SERVICE);
+        // (b/134400042) RoleManager might be null in unit tests running older mockito versions
+        // that do not support mocking final classes.
+        if (!tm.isSmsCapable() && (roleManager == null || !roleManager.isRoleAvailable(
+                RoleManager.ROLE_SMS))) {
             // No phone, no SMS
             return;
         }
diff --git a/telephony/java/com/android/internal/telephony/TelephonyPermissions.java b/telephony/java/com/android/internal/telephony/TelephonyPermissions.java
index e8e2a3d..7a0ab9c 100644
--- a/telephony/java/com/android/internal/telephony/TelephonyPermissions.java
+++ b/telephony/java/com/android/internal/telephony/TelephonyPermissions.java
@@ -29,8 +29,6 @@
 import android.os.RemoteException;
 import android.os.ServiceManager;
 import android.os.UserHandle;
-import android.provider.DeviceConfig;
-import android.provider.Settings;
 import android.telephony.Rlog;
 import android.telephony.SubscriptionManager;
 import android.telephony.TelephonyManager;
@@ -364,23 +362,8 @@
      */
     private static boolean reportAccessDeniedToReadIdentifiers(Context context, int subId, int pid,
             int uid, String callingPackage, String message) {
-        // Check if the application is not preinstalled; if not then a separate setting is required
-        // to relax the check to begin flagging problems with non-preinstalled apps early.
-        boolean relax3PDeviceIdentifierCheck = Settings.Global.getInt(context.getContentResolver(),
-                Settings.Global.PRIVILEGED_DEVICE_IDENTIFIER_3P_CHECK_RELAXED, 0) == 1;
         boolean isPreinstalled = false;
-        // Also check if the application is a preloaded non-privileged app; if so there is a
-        // separate setting to relax the check for these apps to ensure users can relax the check
-        // for non-preinstalled or non-priv apps as needed while continuing to test the other.
-        boolean relaxNonPrivDeviceIdentifierCheck = Settings.Global.getInt(
-                context.getContentResolver(),
-                Settings.Global.PRIVILEGED_DEVICE_IDENTIFIER_NON_PRIV_CHECK_RELAXED, 0) == 1;
         boolean isPrivApp = false;
-        // Similar to above support relaxing the check for privileged apps while still enforcing it
-        // for non-privileged and non-preinstalled apps.
-        boolean relaxPrivDeviceIdentifierCheck = Settings.Global.getInt(
-                context.getContentResolver(),
-                Settings.Global.PRIVILEGED_DEVICE_IDENTIFIER_PRIV_CHECK_RELAXED, 0) == 1;
         ApplicationInfo callingPackageInfo = null;
         try {
             callingPackageInfo = context.getPackageManager().getApplicationInfoAsUser(
@@ -399,58 +382,40 @@
             Log.e(LOG_TAG, "Exception caught obtaining package info for package " + callingPackage,
                     e);
         }
-        // The new Q restrictions for device identifier access will be enforced for all apps with
-        // settings to individually disable the new restrictions for privileged, preloaded
-        // non-privileged, and non-preinstalled apps.
-        if (!isIdentifierCheckDisabled() && (
-                (isPrivApp && !relaxPrivDeviceIdentifierCheck)
-                        || (!isPreinstalled && !relax3PDeviceIdentifierCheck)
-                        || (isPreinstalled && !isPrivApp && !relaxNonPrivDeviceIdentifierCheck))) {
-            // The current package should only be reported in StatsLog if it has not previously been
-            // reported for the currently invoked device identifier method.
-            boolean packageReported = sReportedDeviceIDPackages.containsKey(callingPackage);
-            if (!packageReported || !sReportedDeviceIDPackages.get(callingPackage).contains(
-                    message)) {
-                Set invokedMethods;
-                if (!packageReported) {
-                    invokedMethods = new HashSet<String>();
-                    sReportedDeviceIDPackages.put(callingPackage, invokedMethods);
-                } else {
-                    invokedMethods = sReportedDeviceIDPackages.get(callingPackage);
-                }
-                invokedMethods.add(message);
-                StatsLog.write(StatsLog.DEVICE_IDENTIFIER_ACCESS_DENIED, callingPackage, message,
-                        isPreinstalled, isPrivApp);
+        // The current package should only be reported in StatsLog if it has not previously been
+        // reported for the currently invoked device identifier method.
+        boolean packageReported = sReportedDeviceIDPackages.containsKey(callingPackage);
+        if (!packageReported || !sReportedDeviceIDPackages.get(callingPackage).contains(
+                message)) {
+            Set invokedMethods;
+            if (!packageReported) {
+                invokedMethods = new HashSet<String>();
+                sReportedDeviceIDPackages.put(callingPackage, invokedMethods);
+            } else {
+                invokedMethods = sReportedDeviceIDPackages.get(callingPackage);
             }
-            Log.w(LOG_TAG, "reportAccessDeniedToReadIdentifiers:" + callingPackage + ":" + message
-                    + ":isPreinstalled=" + isPreinstalled + ":isPrivApp=" + isPrivApp);
-            // if the target SDK is pre-Q then check if the calling package would have previously
-            // had access to device identifiers.
-            if (callingPackageInfo != null && (
-                    callingPackageInfo.targetSdkVersion < Build.VERSION_CODES.Q)) {
-                if (context.checkPermission(
-                        android.Manifest.permission.READ_PHONE_STATE,
-                        pid,
-                        uid) == PackageManager.PERMISSION_GRANTED) {
-                    return false;
-                }
-                if (checkCarrierPrivilegeForSubId(subId)) {
-                    return false;
-                }
-            }
-            throw new SecurityException(message + ": The user " + uid
-                    + " does not meet the requirements to access device identifiers.");
-        } else {
-            return checkReadPhoneState(context, subId, pid, uid, callingPackage, message);
+            invokedMethods.add(message);
+            StatsLog.write(StatsLog.DEVICE_IDENTIFIER_ACCESS_DENIED, callingPackage, message,
+                    isPreinstalled, isPrivApp);
         }
-    }
-
-    /**
-     * Returns true if the new device identifier access restrictions are disabled.
-     */
-    private static boolean isIdentifierCheckDisabled() {
-        return DeviceConfig.getInt(DeviceConfig.NAMESPACE_PRIVACY,
-                PROPERTY_DEVICE_IDENTIFIER_ACCESS_RESTRICTIONS_DISABLED, 0) == 1;
+        Log.w(LOG_TAG, "reportAccessDeniedToReadIdentifiers:" + callingPackage + ":" + message
+                + ":isPreinstalled=" + isPreinstalled + ":isPrivApp=" + isPrivApp);
+        // if the target SDK is pre-Q then check if the calling package would have previously
+        // had access to device identifiers.
+        if (callingPackageInfo != null && (
+                callingPackageInfo.targetSdkVersion < Build.VERSION_CODES.Q)) {
+            if (context.checkPermission(
+                    android.Manifest.permission.READ_PHONE_STATE,
+                    pid,
+                    uid) == PackageManager.PERMISSION_GRANTED) {
+                return false;
+            }
+            if (checkCarrierPrivilegeForSubId(subId)) {
+                return false;
+            }
+        }
+        throw new SecurityException(message + ": The user " + uid
+                + " does not meet the requirements to access device identifiers.");
     }
 
     /**
diff --git a/tests/Internal/src/com/android/internal/colorextraction/ColorExtractorTest.java b/tests/Internal/src/com/android/internal/colorextraction/ColorExtractorTest.java
index 17fa931..45ddc3e 100644
--- a/tests/Internal/src/com/android/internal/colorextraction/ColorExtractorTest.java
+++ b/tests/Internal/src/com/android/internal/colorextraction/ColorExtractorTest.java
@@ -39,6 +39,8 @@
 import org.junit.Before;
 import org.junit.Test;
 import org.junit.runner.RunWith;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
 
 /**
  * Tests color extraction generation.
@@ -48,16 +50,19 @@
 public class ColorExtractorTest {
 
     Context mContext;
+    @Mock
+    WallpaperManager mWallpaperManager;
 
     @Before
     public void setup() {
+        MockitoAnnotations.initMocks(this);
         mContext = InstrumentationRegistry.getContext();
     }
 
     @Test
     public void ColorExtractor_extractWhenInitialized() {
         ExtractionType type = mock(Tonal.class);
-        new ColorExtractor(mContext, type, true);
+        new ColorExtractor(mContext, type, true, mWallpaperManager);
         // 1 for lock and 1 for system
         verify(type, times(2))
                 .extractInto(any(), any(), any(), any());
@@ -84,7 +89,7 @@
                     outGradientColorsDark.set(colorsExpectedDark);
                     outGradientColorsExtraDark.set(colorsExpectedExtraDark);
                 };
-        ColorExtractor extractor = new ColorExtractor(mContext, type, true);
+        ColorExtractor extractor = new ColorExtractor(mContext, type, true, mWallpaperManager);
 
         GradientColors colors = extractor.getColors(WallpaperManager.FLAG_SYSTEM,
                 ColorExtractor.TYPE_NORMAL);
@@ -99,7 +104,8 @@
     public void addOnColorsChangedListener_invokesListener() {
         ColorExtractor.OnColorsChangedListener mockedListeners =
                 mock(ColorExtractor.OnColorsChangedListener.class);
-        ColorExtractor extractor = new ColorExtractor(mContext, new Tonal(mContext), true);
+        ColorExtractor extractor = new ColorExtractor(mContext, new Tonal(mContext), true,
+                mWallpaperManager);
         extractor.addOnColorsChangedListener(mockedListeners);
 
         extractor.onColorsChanged(new WallpaperColors(Color.valueOf(Color.RED), null, null),
diff --git a/tests/net/java/android/net/NetworkStatsTest.java b/tests/net/java/android/net/NetworkStatsTest.java
index c16a0f4..b5b0384 100644
--- a/tests/net/java/android/net/NetworkStatsTest.java
+++ b/tests/net/java/android/net/NetworkStatsTest.java
@@ -569,7 +569,7 @@
             .addValues(underlyingIface, tunUid, SET_FOREGROUND, TAG_NONE, METERED_NO, ROAMING_NO,
                     DEFAULT_NETWORK_NO, 0L, 0L, 0L, 0L, 0L);
 
-        delta.migrateTun(tunUid, tunIface, new String[] {underlyingIface});
+        assertTrue(delta.toString(), delta.migrateTun(tunUid, tunIface, underlyingIface));
         assertEquals(20, delta.size());
 
         // tunIface and TEST_IFACE entries are not changed.
@@ -650,7 +650,7 @@
             .addValues(underlyingIface, tunUid, SET_DEFAULT, TAG_NONE, METERED_NO, ROAMING_NO,
                     DEFAULT_NETWORK_NO,  75500L, 37L, 130000L, 70L, 0L);
 
-        delta.migrateTun(tunUid, tunIface, new String[]{underlyingIface});
+        assertTrue(delta.migrateTun(tunUid, tunIface, underlyingIface));
         assertEquals(9, delta.size());
 
         // tunIface entries should not be changed.
@@ -813,37 +813,6 @@
     }
 
     @Test
-    public void testFilterDebugEntries() {
-        NetworkStats.Entry entry1 = new NetworkStats.Entry(
-                "test1", 10100, SET_DEFAULT, TAG_NONE, METERED_NO, ROAMING_NO,
-                DEFAULT_NETWORK_NO, 50000L, 25L, 100000L, 50L, 0L);
-
-        NetworkStats.Entry entry2 = new NetworkStats.Entry(
-                "test2", 10101, SET_DBG_VPN_IN, TAG_NONE, METERED_NO, ROAMING_NO,
-                DEFAULT_NETWORK_NO, 50000L, 25L, 100000L, 50L, 0L);
-
-        NetworkStats.Entry entry3 = new NetworkStats.Entry(
-                "test2", 10101, SET_DEFAULT, TAG_NONE, METERED_NO, ROAMING_NO,
-                DEFAULT_NETWORK_NO, 50000L, 25L, 100000L, 50L, 0L);
-
-        NetworkStats.Entry entry4 = new NetworkStats.Entry(
-                "test2", 10101, SET_DBG_VPN_OUT, TAG_NONE, METERED_NO, ROAMING_NO,
-                DEFAULT_NETWORK_NO, 50000L, 25L, 100000L, 50L, 0L);
-
-        NetworkStats stats = new NetworkStats(TEST_START, 4)
-                .addValues(entry1)
-                .addValues(entry2)
-                .addValues(entry3)
-                .addValues(entry4);
-
-        stats.filterDebugEntries();
-
-        assertEquals(2, stats.size());
-        assertEquals(entry1, stats.getValues(0, null));
-        assertEquals(entry3, stats.getValues(1, null));
-    }
-
-    @Test
     public void testApply464xlatAdjustments() {
         final String v4Iface = "v4-wlan0";
         final String baseIface = "wlan0";
diff --git a/tests/net/java/com/android/server/net/NetworkStatsServiceTest.java b/tests/net/java/com/android/server/net/NetworkStatsServiceTest.java
index d9f2c20..bce526d 100644
--- a/tests/net/java/com/android/server/net/NetworkStatsServiceTest.java
+++ b/tests/net/java/com/android/server/net/NetworkStatsServiceTest.java
@@ -57,11 +57,11 @@
 
 import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertNotNull;
-import static org.junit.Assert.assertNull;
 import static org.junit.Assert.assertTrue;
 import static org.mockito.ArgumentMatchers.any;
 import static org.mockito.ArgumentMatchers.anyInt;
 import static org.mockito.ArgumentMatchers.anyLong;
+import static org.mockito.ArgumentMatchers.argThat;
 import static org.mockito.ArgumentMatchers.eq;
 import static org.mockito.Mockito.times;
 import static org.mockito.Mockito.verify;
@@ -216,16 +216,11 @@
         expectNetworkStatsUidDetail(buildEmptyStats());
         expectSystemReady();
 
-        assertNull(mService.getTunAdjustedStats());
         mService.systemReady();
-        // Verify that system ready fetches realtime stats and initializes tun adjusted stats.
-        verify(mNetManager).getNetworkStatsUidDetail(UID_ALL, INTERFACES_ALL);
-        assertNotNull("failed to initialize TUN adjusted stats", mService.getTunAdjustedStats());
-        assertEquals(0, mService.getTunAdjustedStats().size());
-
         mSession = mService.openSession();
         assertNotNull("openSession() failed", mSession);
 
+
         // catch INetworkManagementEventObserver during systemReady()
         ArgumentCaptor<INetworkManagementEventObserver> networkObserver =
               ArgumentCaptor.forClass(INetworkManagementEventObserver.class);
@@ -738,13 +733,11 @@
 
         NetworkStats stats = mService.getDetailedUidStats(ifaceFilter);
 
-        // mNetManager#getNetworkStatsUidDetail(UID_ALL, INTERFACES_ALL) has following invocations:
-        // 1) NetworkStatsService#systemReady from #setUp.
-        // 2) mService#forceUpdateIfaces in the test above.
-        // 3) Finally, mService#getDetailedUidStats.
-        verify(mNetManager, times(3)).getNetworkStatsUidDetail(UID_ALL, INTERFACES_ALL);
-        assertTrue(ArrayUtils.contains(stats.getUniqueIfaces(), TEST_IFACE));
-        assertTrue(ArrayUtils.contains(stats.getUniqueIfaces(), stackedIface));
+        verify(mNetManager, times(1)).getNetworkStatsUidDetail(eq(UID_ALL), argThat(ifaces ->
+                ifaces != null && ifaces.length == 2
+                        && ArrayUtils.contains(ifaces, TEST_IFACE)
+                        && ArrayUtils.contains(ifaces, stackedIface)));
+
         assertEquals(2, stats.size());
         assertEquals(uidStats, stats.getValues(0, null));
         assertEquals(tetheredStats1, stats.getValues(1, null));
@@ -930,70 +923,11 @@
     }
 
     @Test
-    public void vpnRewriteTrafficThroughItself() throws Exception {
-        // WiFi network is connected and VPN is using WiFi (which has TEST_IFACE).
-        expectDefaultSettings();
-        NetworkState[] networkStates = new NetworkState[] {buildWifiState(), buildVpnState()};
-        VpnInfo[] vpnInfos = new VpnInfo[] {createVpnInfo(new String[] {TEST_IFACE})};
-        expectNetworkStatsUidDetail(buildEmptyStats());
-        expectBandwidthControlCheck();
-
-        mService.forceUpdateIfaces(
-                new Network[] {WIFI_NETWORK, VPN_NETWORK},
-                vpnInfos,
-                networkStates,
-                getActiveIface(networkStates));
-        // create some traffic (assume 10 bytes of MTU for VPN interface and 1 byte encryption
-        // overhead per packet):
-        //
-        // 1000 bytes (100 packets) were sent, and 2000 bytes (200 packets) were received by UID_RED
-        // over VPN.
-        // 500 bytes (50 packets) were sent, and 1000 bytes (100 packets) were received by UID_BLUE
-        // over VPN.
-        //
-        // VPN UID rewrites packets read from TUN back to TUN, plus some of its own traffic
-        // (100 bytes).
-        incrementCurrentTime(HOUR_IN_MILLIS);
-        expectNetworkStatsUidDetail(new NetworkStats(getElapsedRealtime(), 5)
-                .addValues(TUN_IFACE, UID_RED, SET_DEFAULT, TAG_NONE, 2000L, 200L, 1000L, 100L, 1L)
-                .addValues(TUN_IFACE, UID_BLUE, SET_DEFAULT, TAG_NONE, 1000L, 100L, 500L, 50L, 1L)
-                // VPN rewrites all the packets read from TUN + 100 additional bytes of VPN's
-                // own traffic.
-                .addValues(TUN_IFACE, UID_VPN, SET_DEFAULT, TAG_NONE, 0L, 0L, 1600L, 160L, 2L)
-                // VPN sent 1760 bytes over WiFi in foreground (SET_FOREGROUND) i.e. 1600
-                // bytes (160 packets) + 1 byte/packet overhead (=160 bytes).
-                .addValues(TEST_IFACE, UID_VPN, SET_FOREGROUND, TAG_NONE, 0L, 0L, 1760L, 176L, 1L)
-                // VPN received 3300 bytes over WiFi in background (SET_DEFAULT) i.e. 3000 bytes
-                // (300 packets) + 1 byte/packet encryption overhead (=300 bytes).
-                .addValues(TEST_IFACE, UID_VPN, SET_DEFAULT, TAG_NONE, 3300L, 300L, 0L, 0L, 1L));
-
-        forcePollAndWaitForIdle();
-
-        // Verify increased TUN usage by UID_VPN does not get attributed to other apps.
-        NetworkStats tunStats =
-                mService.getDetailedUidStats(new String[] {TUN_IFACE});
-        assertValues(
-                tunStats, TUN_IFACE, UID_RED, SET_ALL, TAG_NONE, METERED_ALL, ROAMING_ALL,
-                DEFAULT_NETWORK_ALL, 2000L, 200L, 1000L, 100L, 1);
-        assertValues(
-                tunStats, TUN_IFACE, UID_BLUE, SET_ALL, TAG_NONE, METERED_ALL, ROAMING_ALL,
-                DEFAULT_NETWORK_ALL, 1000L, 100L, 500L, 50L, 1);
-        assertValues(
-                tunStats, TUN_IFACE, UID_VPN, SET_ALL, TAG_NONE, METERED_ALL, ROAMING_ALL,
-                DEFAULT_NETWORK_ALL, 0L, 0L, 1600L, 160L, 2);
-
-        // Verify correct attribution over WiFi.
-        assertUidTotal(sTemplateWifi, UID_RED, 2000L, 200L, 1000L, 100L, 1);
-        assertUidTotal(sTemplateWifi, UID_BLUE, 1000L, 100L, 500L, 50L, 1);
-        assertUidTotal(sTemplateWifi, UID_VPN, 300L, 0L, 260L, 26L, 2);
-    }
-
-    @Test
     public void vpnWithOneUnderlyingIface() throws Exception {
         // WiFi network is connected and VPN is using WiFi (which has TEST_IFACE).
         expectDefaultSettings();
         NetworkState[] networkStates = new NetworkState[] {buildWifiState(), buildVpnState()};
-        VpnInfo[] vpnInfos = new VpnInfo[] {createVpnInfo(new String[] {TEST_IFACE})};
+        VpnInfo[] vpnInfos = new VpnInfo[] {createVpnInfo(TEST_IFACE)};
         expectNetworkStatsUidDetail(buildEmptyStats());
         expectBandwidthControlCheck();
 
@@ -1004,74 +938,23 @@
                 getActiveIface(networkStates));
         // create some traffic (assume 10 bytes of MTU for VPN interface and 1 byte encryption
         // overhead per packet):
-        // 1000 bytes (100 packets) were sent, and 2000 bytes (200 packets) were received by UID_RED
-        // over VPN.
-        // 500 bytes (50 packets) were sent, and 1000 bytes (100 packets) were received by UID_BLUE
-        // over VPN.
-        // VPN sent 1650 bytes (150 packets), and received 3300 (300 packets) over WiFi.
-        // Of 1650 bytes sent over WiFi, expect 1000 bytes attributed to UID_RED, 500 bytes
-        // attributed to UID_BLUE, and 150 bytes attributed to UID_VPN.
-        // Of 3300 bytes received over WiFi, expect 2000 bytes attributed to UID_RED, 1000 bytes
-        // attributed to UID_BLUE, and 300 bytes attributed to UID_VPN.
+        // 1000 bytes (100 packets) were sent/received by UID_RED over VPN.
+        // 500 bytes (50 packets) were sent/received by UID_BLUE over VPN.
+        // VPN sent/received 1650 bytes (150 packets) over WiFi.
+        // Of 1650 bytes over WiFi, expect 1000 bytes attributed to UID_RED, 500 bytes attributed to
+        // UID_BLUE, and 150 bytes attributed to UID_VPN for both rx/tx traffic.
         incrementCurrentTime(HOUR_IN_MILLIS);
         expectNetworkStatsUidDetail(new NetworkStats(getElapsedRealtime(), 3)
-                .addValues(TUN_IFACE, UID_RED, SET_DEFAULT, TAG_NONE, 2000L, 200L, 1000L, 100L, 1L)
-                .addValues(TUN_IFACE, UID_BLUE, SET_DEFAULT, TAG_NONE, 1000L, 100L, 500L, 50L, 1L)
-                // VPN received 3300 bytes over WiFi in background (SET_DEFAULT).
-                .addValues(TEST_IFACE, UID_VPN, SET_DEFAULT, TAG_NONE, 3300L, 300L, 0L, 0L, 1L)
-                // VPN sent 1650 bytes over WiFi in foreground (SET_FOREGROUND).
-                .addValues(TEST_IFACE, UID_VPN, SET_FOREGROUND, TAG_NONE, 0L, 0L, 1650L, 150L, 1L));
+                .addValues(TUN_IFACE, UID_RED, SET_DEFAULT, TAG_NONE, 1000L, 100L, 1000L, 100L, 1L)
+                .addValues(TUN_IFACE, UID_BLUE, SET_DEFAULT, TAG_NONE, 500L, 50L, 500L, 50L, 1L)
+                .addValues(
+                    TEST_IFACE, UID_VPN, SET_DEFAULT, TAG_NONE, 1650L, 150L, 1650L, 150L, 2L));
 
         forcePollAndWaitForIdle();
 
-        assertUidTotal(sTemplateWifi, UID_RED, 2000L, 200L, 1000L, 100L, 1);
-        assertUidTotal(sTemplateWifi, UID_BLUE, 1000L, 100L, 500L, 50L, 1);
-        assertUidTotal(sTemplateWifi, UID_VPN, 300L, 0L, 150L, 0L, 2);
-    }
-
-    @Test
-    public void vpnWithOneUnderlyingIfaceAndOwnTraffic() throws Exception {
-        // WiFi network is connected and VPN is using WiFi (which has TEST_IFACE).
-        expectDefaultSettings();
-        NetworkState[] networkStates = new NetworkState[] {buildWifiState(), buildVpnState()};
-        VpnInfo[] vpnInfos = new VpnInfo[] {createVpnInfo(new String[] {TEST_IFACE})};
-        expectNetworkStatsUidDetail(buildEmptyStats());
-        expectBandwidthControlCheck();
-
-        mService.forceUpdateIfaces(
-                new Network[] {WIFI_NETWORK, VPN_NETWORK},
-                vpnInfos,
-                networkStates,
-                getActiveIface(networkStates));
-        // create some traffic (assume 10 bytes of MTU for VPN interface and 1 byte encryption
-        // overhead per packet):
-        // 1000 bytes (100 packets) were sent, and 2000 bytes (200 packets) were received by UID_RED
-        // over VPN.
-        // 500 bytes (50 packets) were sent, and 1000 bytes (100 packets) were received by UID_BLUE
-        // over VPN.
-        // Additionally, the VPN sends 6000 bytes (600 packets) of its own traffic into the tun
-        // interface (passing that traffic to the VPN endpoint), and receives 5000 bytes (500
-        // packets) from it. Including overhead that is 6600/5500 bytes.
-        // VPN sent 8250 bytes (750 packets), and received 8800 (800 packets) over WiFi.
-        // Of 8250 bytes sent over WiFi, expect 1000 bytes attributed to UID_RED, 500 bytes
-        // attributed to UID_BLUE, and 6750 bytes attributed to UID_VPN.
-        // Of 8800 bytes received over WiFi, expect 2000 bytes attributed to UID_RED, 1000 bytes
-        // attributed to UID_BLUE, and 5800 bytes attributed to UID_VPN.
-        incrementCurrentTime(HOUR_IN_MILLIS);
-        expectNetworkStatsUidDetail(new NetworkStats(getElapsedRealtime(), 3)
-                .addValues(TUN_IFACE, UID_RED, SET_DEFAULT, TAG_NONE, 2000L, 200L, 1000L, 100L, 1L)
-                .addValues(TUN_IFACE, UID_BLUE, SET_DEFAULT, TAG_NONE, 1000L, 100L, 500L, 50L, 1L)
-                .addValues(TUN_IFACE, UID_VPN, SET_DEFAULT, TAG_NONE, 5000L, 500L, 6000L, 600L, 1L)
-                // VPN received 8800 bytes over WiFi in background (SET_DEFAULT).
-                .addValues(TEST_IFACE, UID_VPN, SET_DEFAULT, TAG_NONE, 8800L, 800L, 0L, 0L, 1L)
-                // VPN sent 8250 bytes over WiFi in foreground (SET_FOREGROUND).
-                .addValues(TEST_IFACE, UID_VPN, SET_FOREGROUND, TAG_NONE, 0L, 0L, 8250L, 750L, 1L));
-
-        forcePollAndWaitForIdle();
-
-        assertUidTotal(sTemplateWifi, UID_RED, 2000L, 200L, 1000L, 100L, 1);
-        assertUidTotal(sTemplateWifi, UID_BLUE, 1000L, 100L, 500L, 50L, 1);
-        assertUidTotal(sTemplateWifi, UID_VPN, 5800L, 500L, 6750L, 600L, 2);
+        assertUidTotal(sTemplateWifi, UID_RED, 1000L, 100L, 1000L, 100L, 1);
+        assertUidTotal(sTemplateWifi, UID_BLUE, 500L, 50L, 500L, 50L, 1);
+        assertUidTotal(sTemplateWifi, UID_VPN, 150L, 0L, 150L, 0L, 2);
     }
 
     @Test
@@ -1079,7 +962,7 @@
         // WiFi network is connected and VPN is using WiFi (which has TEST_IFACE).
         expectDefaultSettings();
         NetworkState[] networkStates = new NetworkState[] {buildWifiState(), buildVpnState()};
-        VpnInfo[] vpnInfos = new VpnInfo[] {createVpnInfo(new String[] {TEST_IFACE})};
+        VpnInfo[] vpnInfos = new VpnInfo[] {createVpnInfo(TEST_IFACE)};
         expectNetworkStatsUidDetail(buildEmptyStats());
         expectBandwidthControlCheck();
 
@@ -1110,136 +993,6 @@
     }
 
     @Test
-    public void vpnWithTwoUnderlyingIfaces_packetDuplication() throws Exception {
-        // WiFi and Cell networks are connected and VPN is using WiFi (which has TEST_IFACE) and
-        // Cell (which has TEST_IFACE2) and has declared both of them in its underlying network set.
-        // Additionally, VPN is duplicating traffic across both WiFi and Cell.
-        expectDefaultSettings();
-        NetworkState[] networkStates =
-                new NetworkState[] {
-                    buildWifiState(), buildMobile4gState(TEST_IFACE2), buildVpnState()
-                };
-        VpnInfo[] vpnInfos = new VpnInfo[] {createVpnInfo(new String[] {TEST_IFACE, TEST_IFACE2})};
-        expectNetworkStatsUidDetail(buildEmptyStats());
-        expectBandwidthControlCheck();
-
-        mService.forceUpdateIfaces(
-                new Network[] {WIFI_NETWORK, VPN_NETWORK},
-                vpnInfos,
-                networkStates,
-                getActiveIface(networkStates));
-        // create some traffic (assume 10 bytes of MTU for VPN interface and 1 byte encryption
-        // overhead per packet):
-        // 1000 bytes (100 packets) were sent/received by UID_RED and UID_BLUE over VPN.
-        // VPN sent/received 4400 bytes (400 packets) over both WiFi and Cell (8800 bytes in total).
-        // Of 8800 bytes over WiFi/Cell, expect:
-        // - 500 bytes rx/tx each over WiFi/Cell attributed to both UID_RED and UID_BLUE.
-        // - 1200 bytes rx/tx each over WiFi/Cell for VPN_UID.
-        incrementCurrentTime(HOUR_IN_MILLIS);
-        expectNetworkStatsUidDetail(new NetworkStats(getElapsedRealtime(), 4)
-                .addValues(TUN_IFACE, UID_RED, SET_DEFAULT, TAG_NONE, 1000L, 100L, 1000L, 100L, 2L)
-                .addValues(TUN_IFACE, UID_BLUE, SET_DEFAULT, TAG_NONE, 1000L, 100L, 1000L, 100L, 2L)
-                .addValues(TEST_IFACE, UID_VPN, SET_DEFAULT, TAG_NONE, 2200L, 200L, 2200L, 200L, 2L)
-                .addValues(
-                    TEST_IFACE2, UID_VPN, SET_DEFAULT, TAG_NONE, 2200L, 200L, 2200L, 200L, 2L));
-
-        forcePollAndWaitForIdle();
-
-        assertUidTotal(sTemplateWifi, UID_RED, 500L, 50L, 500L, 50L, 1);
-        assertUidTotal(sTemplateWifi, UID_BLUE, 500L, 50L, 500L, 50L, 1);
-        assertUidTotal(sTemplateWifi, UID_VPN, 1200L, 100L, 1200L, 100L, 2);
-
-        assertUidTotal(buildTemplateMobileWildcard(), UID_RED, 500L, 50L, 500L, 50L, 1);
-        assertUidTotal(buildTemplateMobileWildcard(), UID_BLUE, 500L, 50L, 500L, 50L, 1);
-        assertUidTotal(buildTemplateMobileWildcard(), UID_VPN, 1200L, 100L, 1200L, 100L, 2);
-    }
-
-    @Test
-    public void vpnWithTwoUnderlyingIfaces_splitTraffic() throws Exception {
-        // WiFi and Cell networks are connected and VPN is using WiFi (which has TEST_IFACE) and
-        // Cell (which has TEST_IFACE2) and has declared both of them in its underlying network set.
-        // Additionally, VPN is arbitrarily splitting traffic across WiFi and Cell.
-        expectDefaultSettings();
-        NetworkState[] networkStates =
-                new NetworkState[] {
-                    buildWifiState(), buildMobile4gState(TEST_IFACE2), buildVpnState()
-                };
-        VpnInfo[] vpnInfos = new VpnInfo[] {createVpnInfo(new String[] {TEST_IFACE, TEST_IFACE2})};
-        expectNetworkStatsUidDetail(buildEmptyStats());
-        expectBandwidthControlCheck();
-
-        mService.forceUpdateIfaces(
-                new Network[] {WIFI_NETWORK, VPN_NETWORK},
-                vpnInfos,
-                networkStates,
-                getActiveIface(networkStates));
-        // create some traffic (assume 10 bytes of MTU for VPN interface and 1 byte encryption
-        // overhead per packet):
-        // 1000 bytes (100 packets) were sent, and 500 bytes (50 packets) received by UID_RED over
-        // VPN.
-        // VPN sent 660 bytes (60 packets) over WiFi and 440 bytes (40 packets) over Cell.
-        // And, it received 330 bytes (30 packets) over WiFi and 220 bytes (20 packets) over Cell.
-        // For UID_RED, expect 600 bytes attributed over WiFi and 400 bytes over Cell for sent (tx)
-        // traffic. For received (rx) traffic, expect 300 bytes over WiFi and 200 bytes over Cell.
-        //
-        // For UID_VPN, expect 60 bytes attributed over WiFi and 40 bytes over Cell for tx traffic.
-        // And, 30 bytes over WiFi and 20 bytes over Cell for rx traffic.
-        incrementCurrentTime(HOUR_IN_MILLIS);
-        expectNetworkStatsUidDetail(new NetworkStats(getElapsedRealtime(), 3)
-              .addValues(TUN_IFACE, UID_RED, SET_DEFAULT, TAG_NONE, 500L, 50L, 1000L, 100L, 2L)
-              .addValues(TEST_IFACE, UID_VPN, SET_DEFAULT, TAG_NONE, 330L, 30L, 660L, 60L, 1L)
-              .addValues(TEST_IFACE2, UID_VPN, SET_DEFAULT, TAG_NONE, 220L, 20L, 440L, 40L, 1L));
-
-        forcePollAndWaitForIdle();
-
-        assertUidTotal(sTemplateWifi, UID_RED, 300L, 30L, 600L, 60L, 1);
-        assertUidTotal(sTemplateWifi, UID_VPN, 30L, 0L, 60L, 0L, 1);
-
-        assertUidTotal(buildTemplateMobileWildcard(), UID_RED, 200L, 20L, 400L, 40L, 1);
-        assertUidTotal(buildTemplateMobileWildcard(), UID_VPN, 20L, 0L, 40L, 0L, 1);
-    }
-
-    @Test
-    public void vpnWithTwoUnderlyingIfaces_splitTrafficWithCompression() throws Exception {
-        // WiFi and Cell networks are connected and VPN is using WiFi (which has TEST_IFACE) and
-        // Cell (which has TEST_IFACE2) and has declared both of them in its underlying network set.
-        // Additionally, VPN is arbitrarily splitting compressed traffic across WiFi and Cell.
-        expectDefaultSettings();
-        NetworkState[] networkStates =
-                new NetworkState[] {
-                    buildWifiState(), buildMobile4gState(TEST_IFACE2), buildVpnState()
-                };
-        VpnInfo[] vpnInfos = new VpnInfo[] {createVpnInfo(new String[] {TEST_IFACE, TEST_IFACE2})};
-        expectNetworkStatsUidDetail(buildEmptyStats());
-        expectBandwidthControlCheck();
-
-        mService.forceUpdateIfaces(
-                new Network[] {WIFI_NETWORK, VPN_NETWORK},
-                vpnInfos,
-                networkStates,
-                getActiveIface(networkStates));
-        // create some traffic (assume 10 bytes of MTU for VPN interface:
-        // 1000 bytes (100 packets) were sent/received by UID_RED over VPN.
-        // VPN sent/received 600 bytes (60 packets) over WiFi and 200 bytes (20 packets) over Cell.
-        // For UID_RED, expect 600 bytes attributed over WiFi and 200 bytes over Cell for both
-        // rx/tx.
-        // UID_VPN gets nothing attributed to it (avoiding negative stats).
-        incrementCurrentTime(HOUR_IN_MILLIS);
-        expectNetworkStatsUidDetail(new NetworkStats(getElapsedRealtime(), 4)
-              .addValues(TUN_IFACE, UID_RED, SET_DEFAULT, TAG_NONE, 1000L, 100L, 1000L, 100L, 1L)
-              .addValues(TEST_IFACE, UID_VPN, SET_DEFAULT, TAG_NONE, 600L, 60L, 600L, 60L, 0L)
-              .addValues(TEST_IFACE2, UID_VPN, SET_DEFAULT, TAG_NONE, 200L, 20L, 200L, 20L, 0L));
-
-        forcePollAndWaitForIdle();
-
-        assertUidTotal(sTemplateWifi, UID_RED, 600L, 60L, 600L, 60L, 0);
-        assertUidTotal(sTemplateWifi, UID_VPN, 0L, 0L, 0L, 0L, 0);
-
-        assertUidTotal(buildTemplateMobileWildcard(), UID_RED, 200L, 20L, 200L, 20L, 0);
-        assertUidTotal(buildTemplateMobileWildcard(), UID_VPN, 0L, 0L, 0L, 0L, 0);
-    }
-
-    @Test
     public void vpnWithIncorrectUnderlyingIface() throws Exception {
         // WiFi and Cell networks are connected and VPN is using Cell (which has TEST_IFACE2),
         // but has declared only WiFi (TEST_IFACE) in its underlying network set.
@@ -1248,7 +1001,7 @@
                 new NetworkState[] {
                     buildWifiState(), buildMobile4gState(TEST_IFACE2), buildVpnState()
                 };
-        VpnInfo[] vpnInfos = new VpnInfo[] {createVpnInfo(new String[] {TEST_IFACE})};
+        VpnInfo[] vpnInfos = new VpnInfo[] {createVpnInfo(TEST_IFACE)};
         expectNetworkStatsUidDetail(buildEmptyStats());
         expectBandwidthControlCheck();
 
@@ -1277,134 +1030,6 @@
     }
 
     @Test
-    public void recordSnapshot_migratesTunTrafficAndUpdatesTunAdjustedStats() throws Exception {
-        assertEquals(0, mService.getTunAdjustedStats().size());
-        // VPN using WiFi (TEST_IFACE).
-        VpnInfo[] vpnInfos = new VpnInfo[] {createVpnInfo(new String[] {TEST_IFACE})};
-        expectBandwidthControlCheck();
-        // create some traffic (assume 10 bytes of MTU for VPN interface and 1 byte encryption
-        // overhead per packet):
-        // 1000 bytes (100 packets) were downloaded by UID_RED over VPN.
-        // VPN received 1100 bytes (100 packets) over WiFi.
-        incrementCurrentTime(HOUR_IN_MILLIS);
-        expectNetworkStatsUidDetail(new NetworkStats(getElapsedRealtime(), 2)
-              .addValues(TUN_IFACE, UID_RED, SET_DEFAULT, TAG_NONE, 1000L, 100L, 0L, 0L, 0L)
-              .addValues(TEST_IFACE, UID_VPN, SET_DEFAULT, TAG_NONE, 1100L, 100L, 0L, 0L, 0L));
-
-        // this should lead to NSS#recordSnapshotLocked
-        mService.forceUpdateIfaces(
-                new Network[0], vpnInfos, new NetworkState[0], null /* activeIface */);
-
-        // Verify TUN adjusted stats have traffic migrated correctly.
-        // Of 1100 bytes VPN received over WiFi, expect 1000 bytes attributed to UID_RED and 100
-        // bytes attributed to UID_VPN.
-        NetworkStats tunAdjStats = mService.getTunAdjustedStats();
-        assertValues(
-                tunAdjStats, TEST_IFACE, UID_RED, SET_ALL, TAG_NONE, METERED_ALL, ROAMING_ALL,
-                DEFAULT_NETWORK_ALL, 1000L, 100L, 0L, 0L, 0);
-        assertValues(
-                tunAdjStats, TEST_IFACE, UID_VPN, SET_ALL, TAG_NONE, METERED_ALL, ROAMING_ALL,
-                DEFAULT_NETWORK_ALL, 100L, 0L, 0L, 0L, 0);
-    }
-
-    @Test
-    public void getDetailedUidStats_migratesTunTrafficAndUpdatesTunAdjustedStats()
-            throws Exception {
-        assertEquals(0, mService.getTunAdjustedStats().size());
-        // VPN using WiFi (TEST_IFACE).
-        VpnInfo[] vpnInfos = new VpnInfo[] {createVpnInfo(new String[] {TEST_IFACE})};
-        expectBandwidthControlCheck();
-        mService.forceUpdateIfaces(
-                new Network[0], vpnInfos, new NetworkState[0], null /* activeIface */);
-        // create some traffic (assume 10 bytes of MTU for VPN interface and 1 byte encryption
-        // overhead per packet):
-        // 1000 bytes (100 packets) were downloaded by UID_RED over VPN.
-        // VPN received 1100 bytes (100 packets) over WiFi.
-        incrementCurrentTime(HOUR_IN_MILLIS);
-        expectNetworkStatsUidDetail(new NetworkStats(getElapsedRealtime(), 2)
-              .addValues(TUN_IFACE, UID_RED, SET_DEFAULT, TAG_NONE, 1000L, 100L, 0L, 0L, 0L)
-              .addValues(TEST_IFACE, UID_VPN, SET_DEFAULT, TAG_NONE, 1100L, 100L, 0L, 0L, 0L));
-
-        mService.getDetailedUidStats(INTERFACES_ALL);
-
-        // Verify internally maintained TUN adjusted stats
-        NetworkStats tunAdjStats = mService.getTunAdjustedStats();
-        // Verify stats for TEST_IFACE (WiFi):
-        // Of 1100 bytes VPN received over WiFi, expect 1000 bytes attributed to UID_RED and 100
-        // bytes attributed to UID_VPN.
-        assertValues(
-                tunAdjStats, TEST_IFACE, UID_RED, SET_ALL, TAG_NONE, METERED_ALL, ROAMING_ALL,
-                DEFAULT_NETWORK_ALL, 1000L, 100L, 0L, 0L, 0);
-        assertValues(
-                tunAdjStats, TEST_IFACE, UID_VPN, SET_ALL, TAG_NONE, METERED_ALL, ROAMING_ALL,
-                DEFAULT_NETWORK_ALL, 100L, 0L, 0L, 0L, 0);
-        // Verify stats for TUN_IFACE; only UID_RED should have usage on it.
-        assertValues(
-                tunAdjStats, TUN_IFACE, UID_RED, SET_ALL, TAG_NONE, METERED_ALL, ROAMING_ALL,
-                DEFAULT_NETWORK_ALL, 1000L, 100L, 0L, 0L, 0);
-        assertValues(
-                tunAdjStats, TUN_IFACE, UID_VPN, SET_ALL, TAG_NONE, METERED_ALL, ROAMING_ALL,
-                DEFAULT_NETWORK_ALL, 0L, 0L, 0L, 0L, 0);
-
-        // lets assume that since last time, VPN received another 1100 bytes (same assumptions as
-        // before i.e. UID_RED downloaded another 1000 bytes).
-        incrementCurrentTime(HOUR_IN_MILLIS);
-        // Note - NetworkStatsFactory returns counters that are monotonically increasing.
-        expectNetworkStatsUidDetail(new NetworkStats(getElapsedRealtime(), 2)
-              .addValues(TUN_IFACE, UID_RED, SET_DEFAULT, TAG_NONE, 2000L, 200L, 0L, 0L, 0L)
-              .addValues(TEST_IFACE, UID_VPN, SET_DEFAULT, TAG_NONE, 2200L, 200L, 0L, 0L, 0L));
-
-        mService.getDetailedUidStats(INTERFACES_ALL);
-
-        tunAdjStats = mService.getTunAdjustedStats();
-        // verify TEST_IFACE stats:
-        assertValues(
-                tunAdjStats, TEST_IFACE, UID_RED, SET_ALL, TAG_NONE, METERED_ALL, ROAMING_ALL,
-                DEFAULT_NETWORK_ALL, 2000L, 200L, 0L, 0L, 0);
-        assertValues(
-                tunAdjStats, TEST_IFACE, UID_VPN, SET_ALL, TAG_NONE, METERED_ALL, ROAMING_ALL,
-                DEFAULT_NETWORK_ALL, 200L, 0L, 0L, 0L, 0);
-        // verify TUN_IFACE stats:
-        assertValues(
-                tunAdjStats, TUN_IFACE, UID_RED, SET_ALL, TAG_NONE, METERED_ALL, ROAMING_ALL,
-                DEFAULT_NETWORK_ALL, 2000L, 200L, 0L, 0L, 0);
-        assertValues(
-                tunAdjStats, TUN_IFACE, UID_VPN, SET_ALL, TAG_NONE, METERED_ALL, ROAMING_ALL,
-                DEFAULT_NETWORK_ALL, 0L, 0L, 0L, 0L, 0);
-    }
-
-    @Test
-    public void getDetailedUidStats_returnsCorrectStatsWithVpnRunning() throws Exception {
-        // VPN using WiFi (TEST_IFACE).
-        VpnInfo[] vpnInfos = new VpnInfo[] {createVpnInfo(new String[] {TEST_IFACE})};
-        expectBandwidthControlCheck();
-        mService.forceUpdateIfaces(
-                new Network[0], vpnInfos, new NetworkState[0], null /* activeIface */);
-        // create some traffic (assume 10 bytes of MTU for VPN interface and 1 byte encryption
-        // overhead per packet):
-        // 1000 bytes (100 packets) were downloaded by UID_RED over VPN.
-        // VPN received 1100 bytes (100 packets) over WiFi.
-        incrementCurrentTime(HOUR_IN_MILLIS);
-        expectNetworkStatsUidDetail(new NetworkStats(getElapsedRealtime(), 2)
-              .addValues(TUN_IFACE, UID_RED, SET_DEFAULT, TAG_NONE, 1000L, 100L, 0L, 0L, 0L)
-              .addValues(TEST_IFACE, UID_VPN, SET_DEFAULT, TAG_NONE, 1100L, 100L, 0L, 0L, 0L));
-
-        // Query realtime stats for TEST_IFACE.
-        NetworkStats queriedStats =
-                mService.getDetailedUidStats(new String[] {TEST_IFACE});
-
-        assertEquals(HOUR_IN_MILLIS, queriedStats.getElapsedRealtime());
-        // verify that returned stats are only for TEST_IFACE and VPN traffic is migrated correctly.
-        assertEquals(new String[] {TEST_IFACE}, queriedStats.getUniqueIfaces());
-        assertValues(
-                queriedStats, TEST_IFACE, UID_RED, SET_ALL, TAG_NONE, METERED_ALL, ROAMING_ALL,
-                DEFAULT_NETWORK_ALL, 1000L, 100L, 0L, 0L, 0);
-        assertValues(
-                queriedStats, TEST_IFACE, UID_VPN, SET_ALL, TAG_NONE, METERED_ALL, ROAMING_ALL,
-                DEFAULT_NETWORK_ALL, 100L, 0L, 0L, 0L, 0);
-    }
-
-    @Test
     public void testRegisterUsageCallback() throws Exception {
         // pretend that wifi network comes online; service should ask about full
         // network state, and poll any existing interfaces before updating.
@@ -1757,11 +1382,11 @@
         return new NetworkState(info, prop, new NetworkCapabilities(), VPN_NETWORK, null, null);
     }
 
-    private static VpnInfo createVpnInfo(String[] underlyingIfaces) {
+    private static VpnInfo createVpnInfo(String underlyingIface) {
         VpnInfo info = new VpnInfo();
         info.ownerUid = UID_VPN;
         info.vpnIface = TUN_IFACE;
-        info.underlyingIfaces = underlyingIfaces;
+        info.primaryUnderlyingIface = underlyingIface;
         return info;
     }
 
diff --git a/tools/incident_section_gen/main.cpp b/tools/incident_section_gen/main.cpp
index c9c0edc..91f875e 100644
--- a/tools/incident_section_gen/main.cpp
+++ b/tools/incident_section_gen/main.cpp
@@ -408,9 +408,10 @@
     for (int i=0; i<descriptor->field_count(); i++) {
         const FieldDescriptor* field = descriptor->field(i);
 
-        if (field->type() != FieldDescriptor::TYPE_MESSAGE
-                && field->type() != FieldDescriptor::TYPE_STRING) {
-            continue;
+        if (field->type() != FieldDescriptor::TYPE_MESSAGE &&
+            field->type() != FieldDescriptor::TYPE_STRING &&
+            field->type() != FieldDescriptor::TYPE_BYTES) {
+          continue;
         }
 
         const SectionFlags s = getSectionFlags(field);
diff --git a/tools/stats_log_api_gen/main.cpp b/tools/stats_log_api_gen/main.cpp
index 1aad4be..f62fef0 100644
--- a/tools/stats_log_api_gen/main.cpp
+++ b/tools/stats_log_api_gen/main.cpp
@@ -131,14 +131,10 @@
                                                  "mobile_bytes_transfer"};
     fprintf(out,
             "const std::set<int> "
-            "AtomsInfo::kNotTruncatingTimestampAtomWhiteList = {\n");
-    for (set<AtomDecl>::const_iterator atom = atoms.decls.begin();
-         atom != atoms.decls.end(); atom++) {
-        if (kTruncatingAtomNames.find(atom->name) ==
-            kTruncatingAtomNames.end()) {
-            string constant = make_constant_name(atom->name);
-            fprintf(out, " %s,\n", constant.c_str());
-        }
+            "AtomsInfo::kTruncatingTimestampAtomBlackList = {\n");
+    for (set<string>::const_iterator blacklistedAtom = kTruncatingAtomNames.begin();
+         blacklistedAtom != kTruncatingAtomNames.end(); blacklistedAtom++) {
+            fprintf(out, " %s,\n", make_constant_name(*blacklistedAtom).c_str());
     }
     fprintf(out, "};\n");
     fprintf(out, "\n");
@@ -840,7 +836,7 @@
         fprintf(out, "struct AtomsInfo {\n");
         fprintf(out,
                 "  const static std::set<int> "
-                "kNotTruncatingTimestampAtomWhiteList;\n");
+                "kTruncatingTimestampAtomBlackList;\n");
         fprintf(out, "  const static std::map<int, int> kAtomsWithUidField;\n");
         fprintf(out,
                 "  const static std::set<int> kAtomsWithAttributionChain;\n");