Merge "Verify the pinned stack boundary when adjusting offset."
diff --git a/Android.bp b/Android.bp
index 7bdedc7..0848d2b 100644
--- a/Android.bp
+++ b/Android.bp
@@ -804,6 +804,7 @@
     srcs: [
         "core/java/android/os/IStatsCompanionService.aidl",
         "core/java/android/os/IStatsManager.aidl",
+        "core/java/android/os/IStatsPullerCallback.aidl",
     ],
 }
 
diff --git a/Android.mk b/Android.mk
index 9c65948..9a91dd1 100644
--- a/Android.mk
+++ b/Android.mk
@@ -72,6 +72,9 @@
 	$(hide) mkdir -p $(OUT_DOCS)/offline-sdk
 	( unzip -qo $< -d $(OUT_DOCS)/offline-sdk && touch -f $@ ) || exit 1
 
+.PHONY: docs offline-sdk-docs
+docs offline-sdk-docs: $(OUT_DOCS)/offline-sdk-timestamp
+
 # Run this for checkbuild
 checkbuild: doc-comment-check-docs
 # Check comment when you are updating the API
diff --git a/cmds/statsd/Android.bp b/cmds/statsd/Android.bp
index d6f045e..faf2053 100644
--- a/cmds/statsd/Android.bp
+++ b/cmds/statsd/Android.bp
@@ -71,6 +71,7 @@
         "src/external/Perfetto.cpp",
         "src/external/Perfprofd.cpp",
         "src/external/StatsPuller.cpp",
+        "src/external/StatsCallbackPuller.cpp",
         "src/external/StatsCompanionServicePuller.cpp",
         "src/external/SubsystemSleepStatePuller.cpp",
         "src/external/PowerStatsPuller.cpp",
diff --git a/cmds/statsd/src/StatsService.cpp b/cmds/statsd/src/StatsService.cpp
index 86bf3ec..bd21a95 100644
--- a/cmds/statsd/src/StatsService.cpp
+++ b/cmds/statsd/src/StatsService.cpp
@@ -1057,6 +1057,24 @@
     return Status::ok();
 }
 
+Status StatsService::registerPullerCallback(int32_t atomTag,
+        const sp<android::os::IStatsPullerCallback>& pullerCallback,
+        const String16& packageName) {
+    ENFORCE_DUMP_AND_USAGE_STATS(packageName);
+
+    VLOG("StatsService::registerPullerCallback called.");
+    mPullerManager->RegisterPullerCallback(atomTag, pullerCallback);
+    return Status::ok();
+}
+
+Status StatsService::unregisterPullerCallback(int32_t atomTag, const String16& packageName) {
+    ENFORCE_DUMP_AND_USAGE_STATS(packageName);
+
+    VLOG("StatsService::unregisterPullerCallback called.");
+    mPullerManager->UnregisterPullerCallback(atomTag);
+    return Status::ok();
+}
+
 hardware::Return<void> StatsService::reportSpeakerImpedance(
         const SpeakerImpedance& speakerImpedance) {
     LogEvent event(getWallClockSec() * NS_PER_SEC, getElapsedRealtimeNs(), speakerImpedance);
diff --git a/cmds/statsd/src/StatsService.h b/cmds/statsd/src/StatsService.h
index cdff50f..941ed46 100644
--- a/cmds/statsd/src/StatsService.h
+++ b/cmds/statsd/src/StatsService.h
@@ -173,6 +173,19 @@
     virtual Status sendAppBreadcrumbAtom(int32_t label, int32_t state) override;
 
     /**
+     * Binder call to register a callback function for a vendor pulled atom.
+     * Note: this atom must NOT have uid as a field.
+     */
+    virtual Status registerPullerCallback(int32_t atomTag,
+        const sp<android::os::IStatsPullerCallback>& pullerCallback,
+        const String16& packageName) override;
+
+    /**
+     * Binder call to unregister any existing callback function for a vendor pulled atom.
+     */
+    virtual Status unregisterPullerCallback(int32_t atomTag, const String16& packageName) override;
+
+    /**
      * Binder call to get SpeakerImpedance atom.
      */
     virtual Return<void> reportSpeakerImpedance(const SpeakerImpedance& speakerImpedance) override;
diff --git a/cmds/statsd/src/external/StatsCallbackPuller.cpp b/cmds/statsd/src/external/StatsCallbackPuller.cpp
new file mode 100644
index 0000000..d718273
--- /dev/null
+++ b/cmds/statsd/src/external/StatsCallbackPuller.cpp
@@ -0,0 +1,61 @@
+/*
+ * 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.
+ */
+
+#define DEBUG false  // STOPSHIP if true
+#include "Log.h"
+
+#include <android/os/IStatsPullerCallback.h>
+
+#include "StatsCallbackPuller.h"
+#include "logd/LogEvent.h"
+#include "stats_log_util.h"
+
+using namespace android::binder;
+
+namespace android {
+namespace os {
+namespace statsd {
+
+StatsCallbackPuller::StatsCallbackPuller(int tagId, const sp<IStatsPullerCallback>& callback) :
+        StatsPuller(tagId), mCallback(callback) {
+        VLOG("StatsCallbackPuller created for tag %d", tagId);
+}
+
+bool StatsCallbackPuller::PullInternal(vector<shared_ptr<LogEvent>>* data) {
+    VLOG("StatsCallbackPuller called for tag %d", mTagId)
+    if(mCallback == nullptr) {
+        ALOGW("No callback registered");
+        return false;
+    }
+    int64_t wallClockTimeNs = getWallClockNs();
+    int64_t elapsedTimeNs = getElapsedRealtimeNs();
+    vector<StatsLogEventWrapper> returned_value;
+    Status status = mCallback->pullData(mTagId, elapsedTimeNs, wallClockTimeNs, &returned_value);
+    if (!status.isOk()) {
+        ALOGW("StatsCallbackPuller::pull failed for %d", mTagId);
+        return false;
+    }
+    data->clear();
+    for (const StatsLogEventWrapper& it: returned_value) {
+        LogEvent::createLogEvents(it, *data);
+    }
+    VLOG("StatsCallbackPuller::pull succeeded for %d", mTagId);
+    return true;
+}
+
+}  // namespace statsd
+}  // namespace os
+}  // namespace android
diff --git a/cmds/statsd/src/external/StatsCallbackPuller.h b/cmds/statsd/src/external/StatsCallbackPuller.h
new file mode 100644
index 0000000..c4bfa89
--- /dev/null
+++ b/cmds/statsd/src/external/StatsCallbackPuller.h
@@ -0,0 +1,38 @@
+/*
+ * 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.
+ */
+
+#pragma once
+
+#include <android/os/IStatsPullerCallback.h>
+#include <utils/String16.h>
+#include "StatsPuller.h"
+
+namespace android {
+namespace os {
+namespace statsd {
+
+class StatsCallbackPuller : public StatsPuller {
+public:
+    explicit StatsCallbackPuller(int tagId, const sp<IStatsPullerCallback>& callback);
+
+private:
+    bool PullInternal(vector<std::shared_ptr<LogEvent> >* data) override;
+    const sp<IStatsPullerCallback> mCallback;
+};
+
+}  // namespace statsd
+}  // namespace os
+}  // namespace android
diff --git a/cmds/statsd/src/external/StatsPuller.cpp b/cmds/statsd/src/external/StatsPuller.cpp
index c7c22ee..9552c0a 100644
--- a/cmds/statsd/src/external/StatsPuller.cpp
+++ b/cmds/statsd/src/external/StatsPuller.cpp
@@ -33,7 +33,7 @@
 void StatsPuller::SetUidMap(const sp<UidMap>& uidMap) { mUidMap = uidMap; }
 
 StatsPuller::StatsPuller(const int tagId)
-    : mTagId(tagId) {
+    : mTagId(tagId), mLastPullTimeNs(0) {
 }
 
 bool StatsPuller::Pull(std::vector<std::shared_ptr<LogEvent>>* data) {
diff --git a/cmds/statsd/src/external/StatsPullerManager.cpp b/cmds/statsd/src/external/StatsPullerManager.cpp
index ecdcd21..ed72b29 100644
--- a/cmds/statsd/src/external/StatsPullerManager.cpp
+++ b/cmds/statsd/src/external/StatsPullerManager.cpp
@@ -18,6 +18,7 @@
 #include "Log.h"
 
 #include <android/os/IStatsCompanionService.h>
+#include <android/os/IStatsPullerCallback.h>
 #include <cutils/log.h>
 #include <math.h>
 #include <stdint.h>
@@ -29,6 +30,7 @@
 #include "PowerStatsPuller.h"
 #include "ResourceHealthManagerPuller.h"
 #include "StatsCompanionServicePuller.h"
+#include "StatsCallbackPuller.h"
 #include "StatsPullerManager.h"
 #include "SubsystemSleepStatePuller.h"
 #include "statslog.h"
@@ -49,7 +51,7 @@
 // Values smaller than this may require to update the alarm.
 const int64_t NO_ALARM_UPDATE = INT64_MAX;
 
-const std::map<int, PullAtomInfo> StatsPullerManager::kAllPullAtomInfo = {
+std::map<int, PullAtomInfo> StatsPullerManager::kAllPullAtomInfo = {
         // wifi_bytes_transfer
         {android::util::WIFI_BYTES_TRANSFER,
          {.additiveFields = {2, 3, 4, 5},
@@ -420,6 +422,30 @@
     return totalCleared;
 }
 
+void StatsPullerManager::RegisterPullerCallback(int32_t atomTag,
+        const sp<IStatsPullerCallback>& callback) {
+    AutoMutex _l(mLock);
+    // Platform pullers cannot be changed.
+    if (atomTag < StatsdStats::kMaxPlatformAtomTag) {
+        VLOG("RegisterPullerCallback: atom tag %d is less than min tag %d",
+                atomTag, StatsdStats::kMaxPlatformAtomTag);
+        return;
+    }
+    VLOG("RegisterPullerCallback: adding puller for tag %d", atomTag);
+    StatsdStats::getInstance().notePullerCallbackRegistrationChanged(atomTag, /*registered=*/true);
+    kAllPullAtomInfo[atomTag] = {.puller = new StatsCallbackPuller(atomTag, callback)};
+}
+
+void StatsPullerManager::UnregisterPullerCallback(int32_t atomTag) {
+    AutoMutex _l(mLock);
+    // Platform pullers cannot be changed.
+    if (atomTag < StatsdStats::kMaxPlatformAtomTag) {
+        return;
+    }
+    StatsdStats::getInstance().notePullerCallbackRegistrationChanged(atomTag, /*registered=*/false);
+    kAllPullAtomInfo.erase(atomTag);
+}
+
 }  // namespace statsd
 }  // namespace os
 }  // namespace android
diff --git a/cmds/statsd/src/external/StatsPullerManager.h b/cmds/statsd/src/external/StatsPullerManager.h
index 807e4af..45f6b35 100644
--- a/cmds/statsd/src/external/StatsPullerManager.h
+++ b/cmds/statsd/src/external/StatsPullerManager.h
@@ -17,6 +17,7 @@
 #pragma once
 
 #include <android/os/IStatsCompanionService.h>
+#include <android/os/IStatsPullerCallback.h>
 #include <binder/IServiceManager.h>
 #include <utils/RefBase.h>
 #include <utils/threads.h>
@@ -91,7 +92,12 @@
 
     void SetStatsCompanionService(sp<IStatsCompanionService> statsCompanionService);
 
-    const static std::map<int, PullAtomInfo> kAllPullAtomInfo;
+    void RegisterPullerCallback(int32_t atomTag,
+                                const sp<IStatsPullerCallback>& callback);
+
+    void UnregisterPullerCallback(int32_t atomTag);
+
+    static std::map<int, PullAtomInfo> kAllPullAtomInfo;
 
 private:
     sp<IStatsCompanionService> mStatsCompanionService = nullptr;
diff --git a/cmds/statsd/src/guardrail/StatsdStats.cpp b/cmds/statsd/src/guardrail/StatsdStats.cpp
index c4034ff..40329b7 100644
--- a/cmds/statsd/src/guardrail/StatsdStats.cpp
+++ b/cmds/statsd/src/guardrail/StatsdStats.cpp
@@ -423,6 +423,15 @@
     mPulledAtomStats[atomId].emptyData++;
 }
 
+void StatsdStats::notePullerCallbackRegistrationChanged(int atomId, bool registered) {
+    lock_guard<std::mutex> lock(mLock);
+    if (registered) {
+        mPulledAtomStats[atomId].registeredCount++;
+    } else {
+        mPulledAtomStats[atomId].unregisteredCount++;
+    }
+}
+
 void StatsdStats::noteHardDimensionLimitReached(int64_t metricId) {
     lock_guard<std::mutex> lock(mLock);
     getAtomMetricStats(metricId).hardDimensionLimitReached++;
@@ -514,6 +523,8 @@
         pullStats.second.dataError = 0;
         pullStats.second.pullTimeout = 0;
         pullStats.second.pullExceedMaxDelay = 0;
+        pullStats.second.registeredCount = 0;
+        pullStats.second.unregisteredCount = 0;
     }
     mAtomMetricStats.clear();
 }
@@ -625,12 +636,14 @@
                 "  (average pull time nanos)%lld, (max pull time nanos)%lld, (average pull delay "
                 "nanos)%lld, "
                 "  (max pull delay nanos)%lld, (data error)%ld\n"
-                "  (pull timeout)%ld, (pull exceed max delay)%ld\n",
+                "  (pull timeout)%ld, (pull exceed max delay)%ld\n"
+                "  (registered count) %ld, (unregistered count) %ld\n",
                 (int)pair.first, (long)pair.second.totalPull, (long)pair.second.totalPullFromCache,
                 (long)pair.second.minPullIntervalSec, (long long)pair.second.avgPullTimeNs,
                 (long long)pair.second.maxPullTimeNs, (long long)pair.second.avgPullDelayNs,
                 (long long)pair.second.maxPullDelayNs, pair.second.dataError,
-                pair.second.pullTimeout, pair.second.pullExceedMaxDelay);
+                pair.second.pullTimeout, pair.second.pullExceedMaxDelay,
+                pair.second.registeredCount, pair.second.unregisteredCount);
     }
 
     if (mAnomalyAlarmRegisteredStats > 0) {
diff --git a/cmds/statsd/src/guardrail/StatsdStats.h b/cmds/statsd/src/guardrail/StatsdStats.h
index ea3f3b3..65e8a32 100644
--- a/cmds/statsd/src/guardrail/StatsdStats.h
+++ b/cmds/statsd/src/guardrail/StatsdStats.h
@@ -146,6 +146,10 @@
 
     // Max time to do a pull.
     static const int64_t kPullMaxDelayNs = 10 * NS_PER_SEC;
+
+    // Max platform atom tag number.
+    static const int32_t kMaxPlatformAtomTag = 100000;
+
     /**
      * Report a new config has been received and report the static stats about the config.
      *
@@ -340,6 +344,13 @@
     void noteEmptyData(int atomId);
 
     /**
+     * Records that a puller callback for the given atomId was registered or unregistered.
+     *
+     * @param registered True if the callback was registered, false if was unregistered.
+     */
+    void notePullerCallbackRegistrationChanged(int atomId, bool registered);
+
+    /**
      * Hard limit was reached in the cardinality of an atom
      */
     void noteHardDimensionLimitReached(int64_t metricId);
@@ -416,6 +427,8 @@
         long statsCompanionPullFailed = 0;
         long statsCompanionPullBinderTransactionFailed = 0;
         long emptyData = 0;
+        long registeredCount = 0;
+        long unregisteredCount = 0;
     } PulledAtomStats;
 
     typedef struct {
diff --git a/cmds/statsd/src/stats_log.proto b/cmds/statsd/src/stats_log.proto
index 6a07a3f..863261a 100644
--- a/cmds/statsd/src/stats_log.proto
+++ b/cmds/statsd/src/stats_log.proto
@@ -407,6 +407,8 @@
         optional int64 stats_companion_pull_failed = 13;
         optional int64 stats_companion_pull_binder_transaction_failed = 14;
         optional int64 empty_data = 15;
+        optional int64 registered_count = 16;
+        optional int64 unregistered_count = 17;
     }
     repeated PulledAtomStats pulled_atom_stats = 10;
 
diff --git a/cmds/statsd/src/stats_log_util.cpp b/cmds/statsd/src/stats_log_util.cpp
index aa8cfc5..0ebf2ca 100644
--- a/cmds/statsd/src/stats_log_util.cpp
+++ b/cmds/statsd/src/stats_log_util.cpp
@@ -70,6 +70,8 @@
 const int FIELD_ID_STATS_COMPANION_FAILED = 13;
 const int FIELD_ID_STATS_COMPANION_BINDER_TRANSACTION_FAILED = 14;
 const int FIELD_ID_EMPTY_DATA = 15;
+const int FIELD_ID_PULL_REGISTERED_COUNT = 16;
+const int FIELD_ID_PULL_UNREGISTERED_COUNT = 17;
 // for AtomMetricStats proto
 const int FIELD_ID_ATOM_METRIC_STATS = 17;
 const int FIELD_ID_METRIC_ID = 1;
@@ -480,6 +482,10 @@
                        (long long)pair.second.statsCompanionPullBinderTransactionFailed);
     protoOutput->write(FIELD_TYPE_INT64 | FIELD_ID_EMPTY_DATA,
                        (long long)pair.second.emptyData);
+    protoOutput->write(FIELD_TYPE_INT64 | FIELD_ID_PULL_REGISTERED_COUNT,
+                       (long long) pair.second.registeredCount);
+    protoOutput->write(FIELD_TYPE_INT64 | FIELD_ID_PULL_UNREGISTERED_COUNT,
+                       (long long) pair.second.unregisteredCount);
     protoOutput->end(token);
 }
 
diff --git a/cmds/statsd/tests/guardrail/StatsdStats_test.cpp b/cmds/statsd/tests/guardrail/StatsdStats_test.cpp
index 92aa998..44a88f0 100644
--- a/cmds/statsd/tests/guardrail/StatsdStats_test.cpp
+++ b/cmds/statsd/tests/guardrail/StatsdStats_test.cpp
@@ -259,6 +259,10 @@
     stats.notePullDelay(android::util::DISK_SPACE, 3335L);
     stats.notePull(android::util::DISK_SPACE);
     stats.notePullFromCache(android::util::DISK_SPACE);
+    stats.notePullerCallbackRegistrationChanged(android::util::DISK_SPACE, true);
+    stats.notePullerCallbackRegistrationChanged(android::util::DISK_SPACE, false);
+    stats.notePullerCallbackRegistrationChanged(android::util::DISK_SPACE, true);
+
 
     vector<uint8_t> output;
     stats.dumpStats(&output, false);
@@ -276,6 +280,8 @@
     EXPECT_EQ(3333L, report.pulled_atom_stats(0).max_pull_time_nanos());
     EXPECT_EQ(2223L, report.pulled_atom_stats(0).average_pull_delay_nanos());
     EXPECT_EQ(3335L, report.pulled_atom_stats(0).max_pull_delay_nanos());
+    EXPECT_EQ(2L, report.pulled_atom_stats(0).registered_count());
+    EXPECT_EQ(1L, report.pulled_atom_stats(0).unregistered_count());
 }
 
 TEST(StatsdStatsTest, TestAtomMetricsStats) {
diff --git a/core/java/android/app/StatsManager.java b/core/java/android/app/StatsManager.java
index 3119b37..7746148 100644
--- a/core/java/android/app/StatsManager.java
+++ b/core/java/android/app/StatsManager.java
@@ -24,6 +24,7 @@
 import android.content.Context;
 import android.os.IBinder;
 import android.os.IStatsManager;
+import android.os.IStatsPullerCallback;
 import android.os.RemoteException;
 import android.os.ServiceManager;
 import android.util.AndroidException;
@@ -408,6 +409,39 @@
         }
     }
 
+    /**
+     * Registers a callback for an atom when that atom is to be pulled. The stats service will
+     * invoke pullData in the callback when the stats service determines that this atom needs to be
+     * pulled. Currently, this only works for atoms with tags above 100,000 that do not have a uid.
+     *
+     * @param atomTag   The tag of the atom for this puller callback. Must be at least 100000.
+     * @param callback  The callback to be invoked when the stats service pulls the atom.
+     * @throws StatsUnavailableException if unsuccessful due to failing to connect to stats service
+     *
+     * @hide
+     */
+    @RequiresPermission(allOf = { DUMP, PACKAGE_USAGE_STATS })
+    public void setPullerCallback(int atomTag, IStatsPullerCallback callback)
+            throws StatsUnavailableException {
+        synchronized (this) {
+            try {
+                IStatsManager service = getIStatsManagerLocked();
+                if (callback == null) {
+                    service.unregisterPullerCallback(atomTag, mContext.getOpPackageName());
+                } else {
+                    service.registerPullerCallback(atomTag, callback,
+                            mContext.getOpPackageName());
+                }
+
+            } catch (RemoteException e) {
+                Slog.e(TAG, "Failed to connect to statsd when registering data listener.");
+                throw new StatsUnavailableException("could not connect", e);
+            } catch (SecurityException e) {
+                throw new StatsUnavailableException(e.getMessage(), e);
+            }
+        }
+    }
+
     private class StatsdDeathRecipient implements IBinder.DeathRecipient {
         @Override
         public void binderDied() {
diff --git a/core/java/android/app/TaskInfo.java b/core/java/android/app/TaskInfo.java
index 077b177..dd00e5a 100644
--- a/core/java/android/app/TaskInfo.java
+++ b/core/java/android/app/TaskInfo.java
@@ -97,6 +97,12 @@
     public long lastActiveTime;
 
     /**
+     * The id of the display this task is associated with.
+     * @hide
+     */
+    public int displayId;
+
+    /**
      * The recent activity values for the highest activity in the stack to have set the values.
      * {@link Activity#setTaskDescription(android.app.ActivityManager.TaskDescription)}.
      */
@@ -152,6 +158,7 @@
         userId = source.readInt();
         stackId = source.readInt();
         taskId = source.readInt();
+        displayId = source.readInt();
         isRunning = source.readBoolean();
         baseIntent = source.readInt() != 0
                 ? Intent.CREATOR.createFromParcel(source)
@@ -179,6 +186,7 @@
         dest.writeInt(userId);
         dest.writeInt(stackId);
         dest.writeInt(taskId);
+        dest.writeInt(displayId);
         dest.writeBoolean(isRunning);
 
         if (baseIntent != null) {
@@ -209,6 +217,7 @@
     @Override
     public String toString() {
         return "TaskInfo{userId=" + userId + " stackId=" + stackId + " taskId=" + taskId
+                + " displayId=" + displayId
                 + " isRunning=" + isRunning
                 + " baseIntent=" + baseIntent + " baseActivity=" + baseActivity
                 + " topActivity=" + topActivity + " origActivity=" + origActivity
diff --git a/core/java/android/net/INetworkMonitorCallbacks.aidl b/core/java/android/net/INetworkMonitorCallbacks.aidl
index a8682f9..5146585 100644
--- a/core/java/android/net/INetworkMonitorCallbacks.aidl
+++ b/core/java/android/net/INetworkMonitorCallbacks.aidl
@@ -24,7 +24,7 @@
     void onNetworkMonitorCreated(in INetworkMonitor networkMonitor);
     void notifyNetworkTested(int testResult, @nullable String redirectUrl);
     void notifyPrivateDnsConfigResolved(in PrivateDnsConfigParcel config);
-    void showProvisioningNotification(String action);
+    void showProvisioningNotification(String action, String packageName);
     void hideProvisioningNotification();
     void logCaptivePortalLoginEvent(int eventId, String packageName);
 }
\ No newline at end of file
diff --git a/core/java/android/net/NetworkStack.java b/core/java/android/net/NetworkStack.java
index b6cd635..7a4c9bc 100644
--- a/core/java/android/net/NetworkStack.java
+++ b/core/java/android/net/NetworkStack.java
@@ -63,9 +63,6 @@
     public static final String PERMISSION_MAINLINE_NETWORK_STACK =
             "android.permission.MAINLINE_NETWORK_STACK";
 
-    /** @hide */
-    public static final String NETWORKSTACK_PACKAGE_NAME = "com.android.mainline.networkstack";
-
     private static final int NETWORKSTACK_TIMEOUT_MS = 10_000;
 
     @NonNull
diff --git a/core/java/android/os/IStatsManager.aidl b/core/java/android/os/IStatsManager.aidl
index 93d6f4c..f1bba1a 100644
--- a/core/java/android/os/IStatsManager.aidl
+++ b/core/java/android/os/IStatsManager.aidl
@@ -16,6 +16,8 @@
 
 package android.os;
 
+import android.os.IStatsPullerCallback;
+
 /**
   * Binder interface to communicate with the statistics management service.
   * {@hide}
@@ -178,4 +180,20 @@
      * this label. This allows building custom metrics and predicates.
      */
     void sendAppBreadcrumbAtom(int label, int state);
+
+    /**
+     * Registers a puller callback function that, when invoked, pulls the data
+     * for the specified vendor atom tag.
+     *
+     * Requires Manifest.permission.DUMP and Manifest.permission.PACKAGE_USAGE_STATS
+     */
+    oneway void registerPullerCallback(int atomTag, IStatsPullerCallback pullerCallback,
+                                       String packageName);
+
+   /**
+    * Unregisters a puller callback function for the given vendor atom.
+    *
+    * Requires Manifest.permission.DUMP and Manifest.permission.PACKAGE_USAGE_STATS
+    */
+   oneway void unregisterPullerCallback(int atomTag, String packageName);
 }
diff --git a/core/java/android/os/IStatsPullerCallback.aidl b/core/java/android/os/IStatsPullerCallback.aidl
new file mode 100644
index 0000000..1684aeb
--- /dev/null
+++ b/core/java/android/os/IStatsPullerCallback.aidl
@@ -0,0 +1,35 @@
+/*
+ * 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.os;
+
+import android.os.StatsLogEventWrapper;
+
+/**
+  * Binder interface to pull atoms for the stats service.
+  * {@hide}
+  */
+interface IStatsPullerCallback {
+    /**
+     * Pull data for the specified atom tag. Returns an array of StatsLogEventWrapper containing
+     * the data.
+     *
+     * Note: These pulled atoms should not have uid/attribution chain. Additionally, the event
+     * timestamps will be truncated to the nearest 5 minutes.
+     */
+    StatsLogEventWrapper[] pullData(int atomTag, long elapsedNanos, long wallClocknanos);
+
+}
diff --git a/core/java/android/os/StatsLogEventWrapper.java b/core/java/android/os/StatsLogEventWrapper.java
index acb9eac..2334242 100644
--- a/core/java/android/os/StatsLogEventWrapper.java
+++ b/core/java/android/os/StatsLogEventWrapper.java
@@ -57,20 +57,18 @@
     public static final Parcelable.Creator<StatsLogEventWrapper> CREATOR = new
             Parcelable.Creator<StatsLogEventWrapper>() {
                 public StatsLogEventWrapper createFromParcel(Parcel in) {
-                    android.util.EventLog.writeEvent(0x534e4554, "112550251",
-                            android.os.Binder.getCallingUid(), "");
-                    // Purposefully leaving this method not implemented.
-                    throw new RuntimeException("Not implemented");
+                    return new StatsLogEventWrapper(in);
                 }
 
                 public StatsLogEventWrapper[] newArray(int size) {
-                    android.util.EventLog.writeEvent(0x534e4554, "112550251",
-                            android.os.Binder.getCallingUid(), "");
-                    // Purposefully leaving this method not implemented.
-                    throw new RuntimeException("Not implemented");
+                    return new StatsLogEventWrapper[size];
                 }
             };
 
+    private StatsLogEventWrapper(Parcel in) {
+        readFromParcel(in);
+    }
+
     /**
      * Set work source if any.
      */
@@ -197,6 +195,70 @@
     }
 
     /**
+     * Reads from parcel and appropriately fills member fields.
+     */
+    public void readFromParcel(Parcel in) {
+        mTypes = new ArrayList<>();
+        mValues = new ArrayList<>();
+        mWorkSource = null;
+
+        mTag = in.readInt();
+        mElapsedTimeNs = in.readLong();
+        mWallClockTimeNs = in.readLong();
+
+        // Clear any data.
+        if (DEBUG) {
+            Slog.d(TAG, "Reading " + mTag + " " + mElapsedTimeNs + " " + mWallClockTimeNs);
+        }
+        // Set up worksource if present.
+        int numWorkChains = in.readInt();
+        if (numWorkChains > 0) {
+            mWorkSource = new WorkSource();
+            for (int i = 0; i < numWorkChains; i++) {
+                android.os.WorkSource.WorkChain workChain = mWorkSource.createWorkChain();
+                int workChainSize = in.readInt();
+                for (int j = 0; j < workChainSize; j++) {
+                    int uid = in.readInt();
+                    String tag = in.readString();
+                    workChain.addNode(uid, tag);
+                }
+            }
+        }
+
+        // Do the rest of the types.
+        int numTypes = in.readInt();
+        if (DEBUG) {
+            Slog.d(TAG, "Reading " + numTypes + " elements");
+        }
+        for (int i = 0; i < numTypes; i++) {
+            int type = in.readInt();
+            mTypes.add(type);
+            switch (type) {
+                case EVENT_TYPE_INT:
+                    mValues.add(in.readInt());
+                    break;
+                case EVENT_TYPE_LONG:
+                    mValues.add(in.readLong());
+                    break;
+                case EVENT_TYPE_FLOAT:
+                    mValues.add(in.readFloat());
+                    break;
+                case EVENT_TYPE_DOUBLE:
+                    mValues.add(in.readDouble());
+                    break;
+                case EVENT_TYPE_STRING:
+                    mValues.add(in.readString());
+                    break;
+                case EVENT_TYPE_STORAGE:
+                    mValues.add(in.createByteArray());
+                    break;
+                default:
+                    break;
+            }
+        }
+    }
+
+    /**
      * Boilerplate for Parcel.
      */
     public int describeContents() {
diff --git a/data/etc/privapp-permissions-platform.xml b/data/etc/privapp-permissions-platform.xml
index 6770ae1..7382213 100644
--- a/data/etc/privapp-permissions-platform.xml
+++ b/data/etc/privapp-permissions-platform.xml
@@ -209,21 +209,14 @@
 
     <privapp-permissions package="com.android.mainline.networkstack">
         <permission name="android.permission.ACCESS_NETWORK_CONDITIONS"/>
-        <permission name="android.permission.CHANGE_BACKGROUND_DATA_SETTING"/>
         <permission name="android.permission.CONNECTIVITY_INTERNAL"/>
         <permission name="android.permission.CONNECTIVITY_USE_RESTRICTED_NETWORKS"/>
         <permission name="android.permission.CONTROL_VPN"/>
+        <permission name="android.permission.INTERACT_ACROSS_USERS"/>
         <permission name="android.permission.LOCAL_MAC_ADDRESS"/>
-        <permission name="android.permission.MANAGE_IPSEC_TUNNELS"/>
-        <permission name="android.permission.MANAGE_NETWORK_POLICY"/>
         <permission name="android.permission.MANAGE_SUBSCRIPTION_PLANS"/>
         <permission name="android.permission.MANAGE_USB"/>
-        <permission name="android.permission.NETWORK_BYPASS_PRIVATE_DNS"/>
-        <permission name="android.permission.NETWORK_SETTINGS"/>
-        <permission name="android.permission.NETWORK_STACK" />
-        <permission name="android.permission.NET_TUNNELING"/>
         <permission name="android.permission.PACKET_KEEPALIVE_OFFLOAD"/>
-        <permission name="android.permission.PEERS_MAC_ADDRESS"/>
         <permission name="android.permission.READ_NETWORK_USAGE_HISTORY"/>
         <permission name="android.permission.READ_PRECISE_PHONE_STATE"/>
         <permission name="android.permission.READ_PRIVILEGED_PHONE_STATE"/>
@@ -261,6 +254,7 @@
         <permission name="android.permission.CHANGE_LOWPAN_STATE"/>
         <permission name="android.permission.CHANGE_OVERLAY_PACKAGES"/>
         <permission name="android.permission.CLEAR_APP_CACHE"/>
+        <permission name="android.permission.ACCESS_INSTANT_APPS" />
         <permission name="android.permission.CONNECTIVITY_INTERNAL"/>
         <permission name="android.permission.DELETE_CACHE_FILES"/>
         <permission name="android.permission.DELETE_PACKAGES"/>
diff --git a/packages/NetworkStack/AndroidManifest.xml b/packages/NetworkStack/AndroidManifest.xml
index ac55bfa..e4d3591 100644
--- a/packages/NetworkStack/AndroidManifest.xml
+++ b/packages/NetworkStack/AndroidManifest.xml
@@ -27,8 +27,8 @@
     <uses-permission android:name="android.permission.NETWORK_SETTINGS" />
     <!-- Signature permission defined in NetworkStackStub -->
     <uses-permission android:name="android.permission.MAINLINE_NETWORK_STACK" />
-    <!-- Launch captive portal app as specific user -->
-    <uses-permission android:name="android.permission.INTERACT_ACROSS_USERS_FULL" />
+    <!-- Send latency broadcast as current user -->
+    <uses-permission android:name="android.permission.INTERACT_ACROSS_USERS" />
     <uses-permission android:name="android.permission.NETWORK_STACK" />
     <uses-permission android:name="android.permission.WAKE_LOCK" />
     <application
diff --git a/packages/NetworkStack/src/com/android/server/connectivity/NetworkMonitor.java b/packages/NetworkStack/src/com/android/server/connectivity/NetworkMonitor.java
index 0d6d080..2e72d82 100644
--- a/packages/NetworkStack/src/com/android/server/connectivity/NetworkMonitor.java
+++ b/packages/NetworkStack/src/com/android/server/connectivity/NetworkMonitor.java
@@ -500,7 +500,7 @@
 
     private void showProvisioningNotification(String action) {
         try {
-            mCallback.showProvisioningNotification(action);
+            mCallback.showProvisioningNotification(action, mContext.getPackageName());
         } catch (RemoteException e) {
             Log.e(TAG, "Error showing provisioning notification", e);
         }
diff --git a/packages/NetworkStack/tests/src/com/android/server/connectivity/NetworkMonitorTest.java b/packages/NetworkStack/tests/src/com/android/server/connectivity/NetworkMonitorTest.java
index d11bb64..b98b0f7 100644
--- a/packages/NetworkStack/tests/src/com/android/server/connectivity/NetworkMonitorTest.java
+++ b/packages/NetworkStack/tests/src/com/android/server/connectivity/NetworkMonitorTest.java
@@ -482,7 +482,7 @@
         nm.notifyNetworkConnected();
 
         verify(mCallbacks, timeout(HANDLER_TIMEOUT_MS).times(1))
-                .showProvisioningNotification(any());
+                .showProvisioningNotification(any(), any());
 
         // Check that startCaptivePortalApp sends the expected intent.
         nm.launchCaptivePortalApp();
diff --git a/packages/SettingsLib/src/com/android/settingslib/utils/ThreadUtils.java b/packages/SettingsLib/src/com/android/settingslib/utils/ThreadUtils.java
index 88adcdb..5c9a06f 100644
--- a/packages/SettingsLib/src/com/android/settingslib/utils/ThreadUtils.java
+++ b/packages/SettingsLib/src/com/android/settingslib/utils/ThreadUtils.java
@@ -20,6 +20,7 @@
 
 import java.util.concurrent.ExecutorService;
 import java.util.concurrent.Executors;
+import java.util.concurrent.Future;
 
 public class ThreadUtils {
 
@@ -59,12 +60,14 @@
 
     /**
      * Posts runnable in background using shared background thread pool.
+     *
+     * @Return A future of the task that can be monitored for updates or cancelled.
      */
-    public static void postOnBackgroundThread(Runnable runnable) {
+    public static Future postOnBackgroundThread(Runnable runnable) {
         if (sSingleThreadExecutor == null) {
             sSingleThreadExecutor = Executors.newSingleThreadExecutor();
         }
-        sSingleThreadExecutor.execute(runnable);
+        return sSingleThreadExecutor.submit(runnable);
     }
 
     /**
diff --git a/packages/Shell/AndroidManifest.xml b/packages/Shell/AndroidManifest.xml
index e8c728d..0da3b10 100644
--- a/packages/Shell/AndroidManifest.xml
+++ b/packages/Shell/AndroidManifest.xml
@@ -82,6 +82,7 @@
     <uses-permission android:name="android.permission.MOVE_PACKAGE" />
     <uses-permission android:name="android.permission.CLEAR_APP_USER_DATA" />
     <uses-permission android:name="android.permission.CLEAR_APP_CACHE" />
+    <uses-permission android:name="android.permission.ACCESS_INSTANT_APPS" />
     <uses-permission android:name="android.permission.DELETE_CACHE_FILES" />
     <uses-permission android:name="android.permission.DELETE_PACKAGES" />
     <uses-permission android:name="android.permission.MANAGE_ROLLBACKS" />
diff --git a/packages/SystemUI/src/com/android/systemui/power/PowerUI.java b/packages/SystemUI/src/com/android/systemui/power/PowerUI.java
index f054345..c43f572 100644
--- a/packages/SystemUI/src/com/android/systemui/power/PowerUI.java
+++ b/packages/SystemUI/src/com/android/systemui/power/PowerUI.java
@@ -54,6 +54,7 @@
 import java.io.PrintWriter;
 import java.time.Duration;
 import java.util.Arrays;
+import java.util.concurrent.Future;
 
 public class PowerUI extends SystemUI {
     static final String TAG = "PowerUI";
@@ -80,6 +81,7 @@
     private Estimate mLastEstimate;
     private boolean mLowWarningShownThisChargeCycle;
     private boolean mSevereWarningShownThisChargeCycle;
+    private Future mLastShowWarningTask;
 
     private int mLowBatteryAlertCloseLevel;
     private final int[] mLowBatteryReminderLevels = new int[2];
@@ -247,7 +249,10 @@
                 }
 
                 // Show the correct version of low battery warning if needed
-                ThreadUtils.postOnBackgroundThread(() -> {
+                if (mLastShowWarningTask != null) {
+                    mLastShowWarningTask.cancel(true);
+                }
+                mLastShowWarningTask = ThreadUtils.postOnBackgroundThread(() -> {
                     maybeShowBatteryWarning(
                             oldBatteryLevel, plugged, oldPlugged, oldBucket, bucket);
                 });
@@ -276,7 +281,7 @@
                 estimate = mEnhancedEstimates.getEstimate();
                 mLastEstimate = estimate;
             }
-            // Turbo is not always booted once SysUI is running so we have ot make sure we actually
+            // Turbo is not always booted once SysUI is running so we have to make sure we actually
             // get data back
             if (estimate != null) {
                 mTimeRemaining = estimate.estimateMillis;
@@ -355,13 +360,26 @@
         // Only show the low warning once per charge cycle & no battery saver
         final boolean canShowWarning = !mLowWarningShownThisChargeCycle && !isPowerSaver
                 && (timeRemaining < mEnhancedEstimates.getLowWarningThreshold()
-                        || mBatteryLevel <= warnLevel);
+                || mBatteryLevel <= warnLevel);
 
         // Only show the severe warning once per charge cycle
         final boolean canShowSevereWarning = !mSevereWarningShownThisChargeCycle
                 && (timeRemaining < mEnhancedEstimates.getSevereWarningThreshold()
-                        || mBatteryLevel <= critLevel);
+                || mBatteryLevel <= critLevel);
 
+        final boolean canShow = canShowWarning || canShowSevereWarning;
+        if (DEBUG) {
+            Slog.d(TAG, "Enhanced trigger is: " + canShow + "\nwith values: "
+                    + " mLowWarningShownThisChargeCycle: " + mLowWarningShownThisChargeCycle
+                    + " mSevereWarningShownThisChargeCycle: " + mSevereWarningShownThisChargeCycle
+                    + " mEnhancedEstimates.timeremaining: " + timeRemaining
+                    + " mBatteryLevel: " + mBatteryLevel
+                    + " canShowWarning: " + canShowWarning
+                    + " canShowSevereWarning: " + canShowSevereWarning
+                    + " plugged: " + plugged
+                    + " batteryStatus: " + batteryStatus
+                    + " isPowerSaver: " + isPowerSaver);
+        }
         return canShowWarning || canShowSevereWarning;
     }
 
diff --git a/services/core/java/com/android/server/ConnectivityService.java b/services/core/java/com/android/server/ConnectivityService.java
index fe4411c..d1cd072 100644
--- a/services/core/java/com/android/server/ConnectivityService.java
+++ b/services/core/java/com/android/server/ConnectivityService.java
@@ -38,7 +38,6 @@
 import static android.net.NetworkCapabilities.TRANSPORT_VPN;
 import static android.net.NetworkPolicyManager.RULE_NONE;
 import static android.net.NetworkPolicyManager.uidRulesToString;
-import static android.net.NetworkStack.NETWORKSTACK_PACKAGE_NAME;
 import static android.net.shared.NetworkMonitorUtils.isValidationRequired;
 import static android.net.shared.NetworkParcelableUtil.toStableParcelable;
 import static android.os.Process.INVALID_UID;
@@ -2667,9 +2666,9 @@
         }
 
         @Override
-        public void showProvisioningNotification(String action) {
+        public void showProvisioningNotification(String action, String packageName) {
             final Intent intent = new Intent(action);
-            intent.setPackage(NETWORKSTACK_PACKAGE_NAME);
+            intent.setPackage(packageName);
 
             final PendingIntent pendingIntent;
             // Only the system server can register notifications with package "android"
diff --git a/services/core/java/com/android/server/connectivity/Tethering.java b/services/core/java/com/android/server/connectivity/Tethering.java
index a14fd17..19bdc09 100644
--- a/services/core/java/com/android/server/connectivity/Tethering.java
+++ b/services/core/java/com/android/server/connectivity/Tethering.java
@@ -96,6 +96,7 @@
 import com.android.internal.annotations.VisibleForTesting;
 import com.android.internal.messages.nano.SystemMessageProto.SystemMessage;
 import com.android.internal.notification.SystemNotificationChannels;
+import com.android.internal.telephony.TelephonyIntents;
 import com.android.internal.util.DumpUtils;
 import com.android.internal.util.IndentingPrintWriter;
 import com.android.internal.util.MessageUtils;
@@ -180,6 +181,7 @@
     // into a single coherent structure.
     private final HashSet<IpServer> mForwardedDownstreams;
     private final VersionedBroadcastListener mCarrierConfigChange;
+    private final VersionedBroadcastListener mDefaultSubscriptionChange;
     private final TetheringDependencies mDeps;
     private final EntitlementManager mEntitlementMgr;
 
@@ -232,6 +234,15 @@
                     mEntitlementMgr.reevaluateSimCardProvisioning();
                 });
 
+        filter = new IntentFilter();
+        filter.addAction(TelephonyIntents.ACTION_DEFAULT_DATA_SUBSCRIPTION_CHANGED);
+        mDefaultSubscriptionChange = new VersionedBroadcastListener(
+                "DefaultSubscriptionChangeListener", mContext, smHandler, filter,
+                (Intent ignored) -> {
+                    mLog.log("OBSERVED default data subscription change");
+                    updateConfiguration();
+                    mEntitlementMgr.reevaluateSimCardProvisioning();
+                });
         mStateReceiver = new StateReceiver();
 
         // Load tethering configuration.
@@ -242,6 +253,7 @@
 
     private void startStateMachineUpdaters() {
         mCarrierConfigChange.startListening();
+        mDefaultSubscriptionChange.startListening();
 
         final Handler handler = mTetherMasterSM.getHandler();
         IntentFilter filter = new IntentFilter();
@@ -270,7 +282,8 @@
 
     // NOTE: This is always invoked on the mLooper thread.
     private void updateConfiguration() {
-        mConfig = new TetheringConfiguration(mContext, mLog);
+        final int subId = mDeps.getDefaultDataSubscriptionId();
+        mConfig = new TetheringConfiguration(mContext, mLog, subId);
         mUpstreamNetworkMonitor.updateMobileRequiresDun(mConfig.isDunRequired);
         mEntitlementMgr.updateConfiguration(mConfig);
     }
diff --git a/services/core/java/com/android/server/connectivity/tethering/TetheringConfiguration.java b/services/core/java/com/android/server/connectivity/tethering/TetheringConfiguration.java
index 1e6bb04..8a46ff1 100644
--- a/services/core/java/com/android/server/connectivity/tethering/TetheringConfiguration.java
+++ b/services/core/java/com/android/server/connectivity/tethering/TetheringConfiguration.java
@@ -26,8 +26,8 @@
 import static com.android.internal.R.array.config_mobile_hotspot_provision_app;
 import static com.android.internal.R.array.config_tether_bluetooth_regexs;
 import static com.android.internal.R.array.config_tether_dhcp_range;
-import static com.android.internal.R.array.config_tether_usb_regexs;
 import static com.android.internal.R.array.config_tether_upstream_types;
+import static com.android.internal.R.array.config_tether_usb_regexs;
 import static com.android.internal.R.array.config_tether_wifi_regexs;
 import static com.android.internal.R.bool.config_tether_upstream_automatic;
 import static com.android.internal.R.string.config_mobile_hotspot_provision_app_no_ui;
@@ -38,6 +38,7 @@
 import android.net.ConnectivityManager;
 import android.net.util.SharedLog;
 import android.provider.Settings;
+import android.telephony.SubscriptionManager;
 import android.telephony.TelephonyManager;
 import android.text.TextUtils;
 
@@ -100,29 +101,34 @@
     public final String[] provisioningApp;
     public final String provisioningAppNoUi;
 
-    public TetheringConfiguration(Context ctx, SharedLog log) {
+    public final int subId;
+
+    public TetheringConfiguration(Context ctx, SharedLog log, int id) {
         final SharedLog configLog = log.forSubComponent("config");
 
-        tetherableUsbRegexs = getResourceStringArray(ctx, config_tether_usb_regexs);
+        subId = id;
+        Resources res = getResources(ctx, subId);
+
+        tetherableUsbRegexs = getResourceStringArray(res, config_tether_usb_regexs);
         // TODO: Evaluate deleting this altogether now that Wi-Fi always passes
         // us an interface name. Careful consideration needs to be given to
         // implications for Settings and for provisioning checks.
-        tetherableWifiRegexs = getResourceStringArray(ctx, config_tether_wifi_regexs);
-        tetherableBluetoothRegexs = getResourceStringArray(ctx, config_tether_bluetooth_regexs);
+        tetherableWifiRegexs = getResourceStringArray(res, config_tether_wifi_regexs);
+        tetherableBluetoothRegexs = getResourceStringArray(res, config_tether_bluetooth_regexs);
 
         dunCheck = checkDunRequired(ctx);
         configLog.log("DUN check returned: " + dunCheckString(dunCheck));
 
-        chooseUpstreamAutomatically = getResourceBoolean(ctx, config_tether_upstream_automatic);
-        preferredUpstreamIfaceTypes = getUpstreamIfaceTypes(ctx, dunCheck);
+        chooseUpstreamAutomatically = getResourceBoolean(res, config_tether_upstream_automatic);
+        preferredUpstreamIfaceTypes = getUpstreamIfaceTypes(res, dunCheck);
         isDunRequired = preferredUpstreamIfaceTypes.contains(TYPE_MOBILE_DUN);
 
-        legacyDhcpRanges = getLegacyDhcpRanges(ctx);
+        legacyDhcpRanges = getLegacyDhcpRanges(res);
         defaultIPv4DNS = copy(DEFAULT_IPV4_DNS);
         enableLegacyDhcpServer = getEnableLegacyDhcpServer(ctx);
 
-        provisioningApp = getResourceStringArray(ctx, config_mobile_hotspot_provision_app);
-        provisioningAppNoUi = getProvisioningAppNoUi(ctx);
+        provisioningApp = getResourceStringArray(res, config_mobile_hotspot_provision_app);
+        provisioningAppNoUi = getProvisioningAppNoUi(res);
 
         configLog.log(toString());
     }
@@ -144,6 +150,9 @@
     }
 
     public void dump(PrintWriter pw) {
+        pw.print("subId: ");
+        pw.println(subId);
+
         dumpStringArray(pw, "tetherableUsbRegexs", tetherableUsbRegexs);
         dumpStringArray(pw, "tetherableWifiRegexs", tetherableWifiRegexs);
         dumpStringArray(pw, "tetherableBluetoothRegexs", tetherableBluetoothRegexs);
@@ -169,6 +178,7 @@
 
     public String toString() {
         final StringJoiner sj = new StringJoiner(" ");
+        sj.add(String.format("subId:%d", subId));
         sj.add(String.format("tetherableUsbRegexs:%s", makeString(tetherableUsbRegexs)));
         sj.add(String.format("tetherableWifiRegexs:%s", makeString(tetherableWifiRegexs)));
         sj.add(String.format("tetherableBluetoothRegexs:%s",
@@ -235,8 +245,8 @@
         }
     }
 
-    private static Collection<Integer> getUpstreamIfaceTypes(Context ctx, int dunCheck) {
-        final int ifaceTypes[] = ctx.getResources().getIntArray(config_tether_upstream_types);
+    private static Collection<Integer> getUpstreamIfaceTypes(Resources res, int dunCheck) {
+        final int[] ifaceTypes = res.getIntArray(config_tether_upstream_types);
         final ArrayList<Integer> upstreamIfaceTypes = new ArrayList<>(ifaceTypes.length);
         for (int i : ifaceTypes) {
             switch (i) {
@@ -286,33 +296,33 @@
         return false;
     }
 
-    private static String[] getLegacyDhcpRanges(Context ctx) {
-        final String[] fromResource = getResourceStringArray(ctx, config_tether_dhcp_range);
+    private static String[] getLegacyDhcpRanges(Resources res) {
+        final String[] fromResource = getResourceStringArray(res, config_tether_dhcp_range);
         if ((fromResource.length > 0) && (fromResource.length % 2 == 0)) {
             return fromResource;
         }
         return copy(LEGACY_DHCP_DEFAULT_RANGE);
     }
 
-    private static String getProvisioningAppNoUi(Context ctx) {
+    private static String getProvisioningAppNoUi(Resources res) {
         try {
-            return ctx.getResources().getString(config_mobile_hotspot_provision_app_no_ui);
+            return res.getString(config_mobile_hotspot_provision_app_no_ui);
         } catch (Resources.NotFoundException e) {
             return "";
         }
     }
 
-    private static boolean getResourceBoolean(Context ctx, int resId) {
+    private static boolean getResourceBoolean(Resources res, int resId) {
         try {
-            return ctx.getResources().getBoolean(resId);
+            return res.getBoolean(resId);
         } catch (Resources.NotFoundException e404) {
             return false;
         }
     }
 
-    private static String[] getResourceStringArray(Context ctx, int resId) {
+    private static String[] getResourceStringArray(Resources res, int resId) {
         try {
-            final String[] strArray = ctx.getResources().getStringArray(resId);
+            final String[] strArray = res.getStringArray(resId);
             return (strArray != null) ? strArray : EMPTY_STRING_ARRAY;
         } catch (Resources.NotFoundException e404) {
             return EMPTY_STRING_ARRAY;
@@ -325,6 +335,19 @@
         return intVal != 0;
     }
 
+    private Resources getResources(Context ctx, int subId) {
+        if (subId != SubscriptionManager.INVALID_SUBSCRIPTION_ID) {
+            return getResourcesForSubIdWrapper(ctx, subId);
+        } else {
+            return ctx.getResources();
+        }
+    }
+
+    @VisibleForTesting
+    protected Resources getResourcesForSubIdWrapper(Context ctx, int subId) {
+        return SubscriptionManager.getResourcesForSubId(ctx, subId);
+    }
+
     private static String[] copy(String[] strarray) {
         return Arrays.copyOf(strarray, strarray.length);
     }
diff --git a/services/core/java/com/android/server/connectivity/tethering/TetheringDependencies.java b/services/core/java/com/android/server/connectivity/tethering/TetheringDependencies.java
index 6d6f81e..3fddac1 100644
--- a/services/core/java/com/android/server/connectivity/tethering/TetheringDependencies.java
+++ b/services/core/java/com/android/server/connectivity/tethering/TetheringDependencies.java
@@ -21,6 +21,7 @@
 import android.net.ip.IpServer;
 import android.net.util.SharedLog;
 import android.os.Handler;
+import android.telephony.SubscriptionManager;
 
 import com.android.internal.util.StateMachine;
 import com.android.server.connectivity.MockableSystemProperties;
@@ -85,4 +86,11 @@
             SharedLog log, MockableSystemProperties systemProperties) {
         return new EntitlementManager(ctx, target, log, systemProperties);
     }
+
+    /**
+     * Get default data subscription id to build TetheringConfiguration.
+     */
+    public int getDefaultDataSubscriptionId() {
+        return SubscriptionManager.getDefaultDataSubscriptionId();
+    }
 }
diff --git a/services/core/java/com/android/server/pm/permission/DefaultPermissionGrantPolicy.java b/services/core/java/com/android/server/pm/permission/DefaultPermissionGrantPolicy.java
index bfa539c..2036ed7 100644
--- a/services/core/java/com/android/server/pm/permission/DefaultPermissionGrantPolicy.java
+++ b/services/core/java/com/android/server/pm/permission/DefaultPermissionGrantPolicy.java
@@ -645,7 +645,7 @@
                 grantPermissionsToSystemPackage(packageName, userId,
                         CONTACTS_PERMISSIONS, CALENDAR_PERMISSIONS, MICROPHONE_PERMISSIONS,
                         PHONE_PERMISSIONS, SMS_PERMISSIONS, CAMERA_PERMISSIONS,
-                        SENSORS_PERMISSIONS, STORAGE_PERMISSIONS);
+                        SENSORS_PERMISSIONS, STORAGE_PERMISSIONS, MEDIA_AURAL_PERMISSIONS);
                 grantSystemFixedPermissionsToSystemPackage(packageName, userId,
                         LOCATION_PERMISSIONS, ACTIVITY_RECOGNITION_PERMISSIONS);
             }
diff --git a/services/core/java/com/android/server/wm/SurfaceAnimator.java b/services/core/java/com/android/server/wm/SurfaceAnimator.java
index 5ea2451..35b8641 100644
--- a/services/core/java/com/android/server/wm/SurfaceAnimator.java
+++ b/services/core/java/com/android/server/wm/SurfaceAnimator.java
@@ -251,7 +251,7 @@
         if (DEBUG_ANIM) Slog.i(TAG, "Cancelling animation restarting=" + restarting);
         final SurfaceControl leash = mLeash;
         final AnimationAdapter animation = mAnimation;
-        reset(t, forwardCancel);
+        reset(t, false);
         if (animation != null) {
             if (!mAnimationStartDelayed && forwardCancel) {
                 animation.onAnimationCancelled(leash);
@@ -260,6 +260,12 @@
                 mAnimationFinishedCallback.run();
             }
         }
+
+        if (forwardCancel && leash != null) {
+            t.remove(leash);
+            mService.scheduleAnimationLocked();
+        }
+
         if (!restarting) {
             mAnimationStartDelayed = false;
         }
diff --git a/services/core/java/com/android/server/wm/TaskRecord.java b/services/core/java/com/android/server/wm/TaskRecord.java
index 69f0012..4aca9c8 100644
--- a/services/core/java/com/android/server/wm/TaskRecord.java
+++ b/services/core/java/com/android/server/wm/TaskRecord.java
@@ -119,6 +119,7 @@
 import android.util.EventLog;
 import android.util.Slog;
 import android.util.proto.ProtoOutputStream;
+import android.view.Display;
 import android.view.DisplayInfo;
 
 import com.android.internal.annotations.VisibleForTesting;
@@ -2332,6 +2333,7 @@
         info.userId = userId;
         info.stackId = getStackId();
         info.taskId = taskId;
+        info.displayId = mStack == null ? Display.INVALID_DISPLAY : mStack.mDisplayId;
         info.isRunning = getTopActivity() != null;
         info.baseIntent = new Intent(getBaseIntent());
         info.baseActivity = reuseActivitiesReport.base != null
diff --git a/services/tests/wmtests/src/com/android/server/wm/ActivityMetricsLaunchObserverTests.java b/services/tests/wmtests/src/com/android/server/wm/ActivityMetricsLaunchObserverTests.java
index 2de4ae0..23bae88 100644
--- a/services/tests/wmtests/src/com/android/server/wm/ActivityMetricsLaunchObserverTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/ActivityMetricsLaunchObserverTests.java
@@ -24,6 +24,7 @@
 import static com.android.dx.mockito.inline.extended.ExtendedMockito.mock;
 import static com.android.dx.mockito.inline.extended.ExtendedMockito.verify;
 import static com.android.dx.mockito.inline.extended.ExtendedMockito.verifyNoMoreInteractions;
+
 import static com.google.common.truth.Truth.assertWithMessage;
 
 import static org.mockito.ArgumentMatchers.anyInt;
@@ -35,9 +36,7 @@
 import android.os.SystemClock;
 import android.platform.test.annotations.Presubmit;
 import android.util.SparseIntArray;
-import android.util.proto.ProtoOutputStream;
 
-import androidx.test.filters.FlakyTest;
 import androidx.test.filters.SmallTest;
 
 import com.android.server.wm.ActivityMetricsLaunchObserver.ActivityRecordProto;
diff --git a/services/tests/wmtests/src/com/android/server/wm/AppWindowTokenTests.java b/services/tests/wmtests/src/com/android/server/wm/AppWindowTokenTests.java
index bc62de1..069a609 100644
--- a/services/tests/wmtests/src/com/android/server/wm/AppWindowTokenTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/AppWindowTokenTests.java
@@ -141,6 +141,7 @@
         mToken.removeImmediately();
     }
 
+    @FlakyTest(detail = "Promote to presubmit when shown to be stable.")
     @Test
     public void testLandscapeSeascapeRotationByApp() {
         // Some plumbing to get the service ready for rotation updates.
@@ -166,6 +167,8 @@
         mDisplayContent.updateOrientationFromAppTokens(
                 mDisplayContent.getRequestedOverrideConfiguration(),
                 null /* freezeThisOneIfNeeded */, false /* forceUpdate */);
+        // In this test, DC will not get config update. Set the waiting flag to false.
+        mDisplayContent.mWaitingForConfig = false;
         mWm.mRoot.performSurfacePlacement(false /* recoveringMemory */);
         assertEquals(SCREEN_ORIENTATION_REVERSE_LANDSCAPE, mDisplayContent.getLastOrientation());
         assertTrue(appWindow.mResizeReported);
diff --git a/services/tests/wmtests/src/com/android/server/wm/AssistDataRequesterTest.java b/services/tests/wmtests/src/com/android/server/wm/AssistDataRequesterTest.java
index 2f90baa..3f83cae 100644
--- a/services/tests/wmtests/src/com/android/server/wm/AssistDataRequesterTest.java
+++ b/services/tests/wmtests/src/com/android/server/wm/AssistDataRequesterTest.java
@@ -71,7 +71,6 @@
  *  atest WmTests:AssistDataRequesterTest
  */
 @MediumTest
-@FlakyTest(bugId = 113616538)
 public class AssistDataRequesterTest extends ActivityTestsBase {
 
     private static final String TAG = AssistDataRequesterTest.class.getSimpleName();
@@ -154,6 +153,7 @@
                 .checkOpNoThrow(eq(OP_ASSIST_SCREENSHOT), anyInt(), anyString());
     }
 
+    @FlakyTest(bugId = 124088319)
     @Test
     public void testRequestData() throws Exception {
         setupMocks(CURRENT_ACTIVITY_ASSIST_ALLOWED, CALLER_ASSIST_STRUCTURE_ALLOWED,
@@ -174,6 +174,7 @@
         assertReceivedDataCount(0, 0, 0, 0);
     }
 
+    @FlakyTest(bugId = 124088319)
     @Test
     public void testCurrentAppDisallow_expectNullCallbacks() throws Exception {
         setupMocks(!CURRENT_ACTIVITY_ASSIST_ALLOWED, CALLER_ASSIST_STRUCTURE_ALLOWED,
@@ -184,6 +185,7 @@
         assertReceivedDataCount(0, 1, 0, 1);
     }
 
+    @FlakyTest(bugId = 124088319)
     @Test
     public void testProcessPendingData() throws Exception {
         setupMocks(CURRENT_ACTIVITY_ASSIST_ALLOWED, CALLER_ASSIST_STRUCTURE_ALLOWED,
@@ -241,6 +243,7 @@
         assertReceivedDataCount(0, 1, 0, 1);
     }
 
+    @FlakyTest(bugId = 124088319)
     @Test
     public void testDisallowAssistContextExtras_expectNullDataCallbacks() throws Exception {
         setupMocks(CURRENT_ACTIVITY_ASSIST_ALLOWED, CALLER_ASSIST_STRUCTURE_ALLOWED,
@@ -254,6 +257,7 @@
         assertReceivedDataCount(0, 1, 0, 1);
     }
 
+    @FlakyTest(bugId = 124088319)
     @Test
     public void testNoFetchScreenshots_expectNoScreenshotCallbacks() throws Exception {
         setupMocks(CURRENT_ACTIVITY_ASSIST_ALLOWED, CALLER_ASSIST_STRUCTURE_ALLOWED,
@@ -264,6 +268,7 @@
         assertReceivedDataCount(5, 5, 0, 0);
     }
 
+    @FlakyTest(bugId = 124088319)
     @Test
     public void testDisallowAssistScreenshot_expectNullScreenshotCallback() throws Exception {
         setupMocks(CURRENT_ACTIVITY_ASSIST_ALLOWED, CALLER_ASSIST_STRUCTURE_ALLOWED,
diff --git a/services/tests/wmtests/src/com/android/server/wm/InsetsSourceProviderTest.java b/services/tests/wmtests/src/com/android/server/wm/InsetsSourceProviderTest.java
index 0c363de..a0546d7 100644
--- a/services/tests/wmtests/src/com/android/server/wm/InsetsSourceProviderTest.java
+++ b/services/tests/wmtests/src/com/android/server/wm/InsetsSourceProviderTest.java
@@ -19,11 +19,11 @@
 import static android.view.InsetsState.TYPE_TOP_BAR;
 import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION;
 
-import static junit.framework.Assert.assertFalse;
-import static junit.framework.Assert.assertNull;
-import static junit.framework.Assert.assertTrue;
 import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
 import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertNull;
+import static org.junit.Assert.assertTrue;
 
 import android.graphics.Insets;
 import android.graphics.Rect;
@@ -31,8 +31,6 @@
 import android.view.InsetsSource;
 import android.view.InsetsState;
 
-import org.junit.Before;
-import androidx.test.filters.FlakyTest;
 import androidx.test.filters.SmallTest;
 
 import org.junit.Before;
diff --git a/services/tests/wmtests/src/com/android/server/wm/InsetsStateControllerTest.java b/services/tests/wmtests/src/com/android/server/wm/InsetsStateControllerTest.java
index 11526a8..bc62e8c 100644
--- a/services/tests/wmtests/src/com/android/server/wm/InsetsStateControllerTest.java
+++ b/services/tests/wmtests/src/com/android/server/wm/InsetsStateControllerTest.java
@@ -35,7 +35,6 @@
 import org.junit.Test;
 
 @SmallTest
-@FlakyTest(detail = "Promote once confirmed non-flaky")
 @Presubmit
 public class InsetsStateControllerTest extends WindowTestsBase {
 
@@ -48,6 +47,7 @@
         assertNotNull(getController().getInsetsForDispatch(app).getSource(TYPE_TOP_BAR));
     }
 
+    @FlakyTest(bugId = 69229402)
     @Test
     public void testStripForDispatch_own() {
         final WindowState topBar = createWindow(null, TYPE_APPLICATION, "parentWindow");
@@ -57,6 +57,7 @@
         assertEquals(new InsetsState(), getController().getInsetsForDispatch(topBar));
     }
 
+    @FlakyTest(bugId = 124088319)
     @Test
     public void testStripForDispatch_navBar() {
         final WindowState navBar = createWindow(null, TYPE_APPLICATION, "parentWindow");
@@ -68,6 +69,7 @@
         assertEquals(new InsetsState(), getController().getInsetsForDispatch(navBar));
     }
 
+    @FlakyTest(bugId = 124088319)
     @Test
     public void testBarControllingWinChanged() {
         final WindowState navBar = createWindow(null, TYPE_APPLICATION, "parentWindow");
@@ -80,6 +82,7 @@
         assertEquals(2, controls.length);
     }
 
+    @FlakyTest(bugId = 124088319)
     @Test
     public void testControlRevoked() {
         final WindowState topBar = createWindow(null, TYPE_APPLICATION, "parentWindow");
@@ -91,6 +94,7 @@
         assertNull(getController().getControlsForDispatch(app));
     }
 
+    @FlakyTest(bugId = 124088319)
     @Test
     public void testControlRevoked_animation() {
         final WindowState topBar = createWindow(null, TYPE_APPLICATION, "parentWindow");
diff --git a/services/tests/wmtests/src/com/android/server/wm/PendingRemoteAnimationRegistryTest.java b/services/tests/wmtests/src/com/android/server/wm/PendingRemoteAnimationRegistryTest.java
index 86bf3db..b769fce 100644
--- a/services/tests/wmtests/src/com/android/server/wm/PendingRemoteAnimationRegistryTest.java
+++ b/services/tests/wmtests/src/com/android/server/wm/PendingRemoteAnimationRegistryTest.java
@@ -24,7 +24,6 @@
 import android.platform.test.annotations.Presubmit;
 import android.view.RemoteAnimationAdapter;
 
-import androidx.test.filters.FlakyTest;
 import androidx.test.filters.SmallTest;
 
 import com.android.server.testutils.OffsettableClock;
diff --git a/services/tests/wmtests/src/com/android/server/wm/PersisterQueueTests.java b/services/tests/wmtests/src/com/android/server/wm/PersisterQueueTests.java
index c3d2f33..8327440 100644
--- a/services/tests/wmtests/src/com/android/server/wm/PersisterQueueTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/PersisterQueueTests.java
@@ -28,7 +28,6 @@
 import android.os.SystemClock;
 import android.platform.test.annotations.Presubmit;
 
-import androidx.test.filters.FlakyTest;
 import androidx.test.filters.MediumTest;
 
 import org.junit.After;
diff --git a/services/tests/wmtests/src/com/android/server/wm/SafeActivityOptionsTest.java b/services/tests/wmtests/src/com/android/server/wm/SafeActivityOptionsTest.java
index dad6c95..7111852 100644
--- a/services/tests/wmtests/src/com/android/server/wm/SafeActivityOptionsTest.java
+++ b/services/tests/wmtests/src/com/android/server/wm/SafeActivityOptionsTest.java
@@ -21,7 +21,6 @@
 import android.app.ActivityOptions;
 import android.platform.test.annotations.Presubmit;
 
-import androidx.test.filters.FlakyTest;
 import androidx.test.filters.MediumTest;
 
 import org.junit.Test;
diff --git a/services/tests/wmtests/src/com/android/server/wm/SurfaceAnimationRunnerTest.java b/services/tests/wmtests/src/com/android/server/wm/SurfaceAnimationRunnerTest.java
index dfdbf32..6cce9f0 100644
--- a/services/tests/wmtests/src/com/android/server/wm/SurfaceAnimationRunnerTest.java
+++ b/services/tests/wmtests/src/com/android/server/wm/SurfaceAnimationRunnerTest.java
@@ -167,7 +167,6 @@
         verify(mMockAnimationSpec, atLeastOnce()).apply(any(), any(), eq(0L));
     }
 
-    @FlakyTest(bugId = 74780584)
     @Test
     public void testDeferStartingAnimations() throws Exception {
         mSurfaceAnimationRunner.deferStartingAnimations();
diff --git a/services/tests/wmtests/src/com/android/server/wm/SurfaceAnimatorTest.java b/services/tests/wmtests/src/com/android/server/wm/SurfaceAnimatorTest.java
index 8c32e8c..88ac96d 100644
--- a/services/tests/wmtests/src/com/android/server/wm/SurfaceAnimatorTest.java
+++ b/services/tests/wmtests/src/com/android/server/wm/SurfaceAnimatorTest.java
@@ -34,7 +34,6 @@
 import android.view.SurfaceControl.Transaction;
 import android.view.SurfaceSession;
 
-import androidx.test.filters.FlakyTest;
 import androidx.test.filters.SmallTest;
 
 import com.android.server.wm.SurfaceAnimator.Animatable;
@@ -51,7 +50,7 @@
  * Test class for {@link SurfaceAnimatorTest}.
  *
  * Build/Install/Run:
- *  atest FrameworksServicesTests:SurfaceAnimatorTest
+ *  atest WmTests:SurfaceAnimatorTest
  */
 @SmallTest
 @Presubmit
diff --git a/services/tests/wmtests/src/com/android/server/wm/TaskPersisterTest.java b/services/tests/wmtests/src/com/android/server/wm/TaskPersisterTest.java
index 12ed3c2..9dfeadf 100644
--- a/services/tests/wmtests/src/com/android/server/wm/TaskPersisterTest.java
+++ b/services/tests/wmtests/src/com/android/server/wm/TaskPersisterTest.java
@@ -29,8 +29,6 @@
 import android.platform.test.annotations.Presubmit;
 import android.util.SparseBooleanArray;
 
-import androidx.test.filters.FlakyTest;
-
 import org.junit.After;
 import org.junit.Before;
 import org.junit.Test;
diff --git a/services/tests/wmtests/src/com/android/server/wm/TaskPositioningControllerTests.java b/services/tests/wmtests/src/com/android/server/wm/TaskPositioningControllerTests.java
index 8c6ac23..1e58e41 100644
--- a/services/tests/wmtests/src/com/android/server/wm/TaskPositioningControllerTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/TaskPositioningControllerTests.java
@@ -43,7 +43,6 @@
  * Build/Install/Run:
  *  atest FrameworksServicesTests:TaskPositioningControllerTests
  */
-@FlakyTest(bugId = 117924387)
 @SmallTest
 @Presubmit
 public class TaskPositioningControllerTests extends WindowTestsBase {
@@ -90,6 +89,7 @@
         assertNull(mTarget.getDragWindowHandleLocked());
     }
 
+    @FlakyTest(bugId = 69229402)
     @Test
     public void testHandleTapOutsideTask() {
         synchronized (mWm.mGlobalLock) {
diff --git a/services/tests/wmtests/src/com/android/server/wm/TaskStackChangedListenerTest.java b/services/tests/wmtests/src/com/android/server/wm/TaskStackChangedListenerTest.java
index 4a734e5..dcca316 100644
--- a/services/tests/wmtests/src/com/android/server/wm/TaskStackChangedListenerTest.java
+++ b/services/tests/wmtests/src/com/android/server/wm/TaskStackChangedListenerTest.java
@@ -35,9 +35,11 @@
 import android.content.Intent;
 import android.content.pm.ActivityInfo;
 import android.os.RemoteException;
+import android.platform.test.annotations.Presubmit;
 import android.support.test.uiautomator.UiDevice;
 import android.text.TextUtils;
 
+import androidx.test.filters.FlakyTest;
 import androidx.test.filters.MediumTest;
 
 import com.android.internal.annotations.GuardedBy;
@@ -76,6 +78,7 @@
     }
 
     @Test
+    @Presubmit
     public void testTaskStackChanged_afterFinish() throws Exception {
         registerTaskStackChangedListener(new TaskStackListener() {
             @Override
@@ -87,7 +90,8 @@
         });
 
         Context context = getInstrumentation().getContext();
-        context.startActivity(new Intent(context, ActivityA.class));
+        context.startActivity(
+                new Intent(context, ActivityA.class).addFlags(Intent.FLAG_ACTIVITY_NEW_TASK));
         UiDevice.getInstance(getInstrumentation()).waitForIdle();
         synchronized (sLock) {
             assertTrue(sTaskStackChangedCalled);
@@ -96,6 +100,7 @@
     }
 
     @Test
+    @FlakyTest(bugId = 119893767)
     public void testTaskDescriptionChanged() throws Exception {
         final Object[] params = new Object[2];
         final CountDownLatch latch = new CountDownLatch(1);
@@ -124,6 +129,7 @@
     }
 
     @Test
+    @FlakyTest(bugId = 119893767)
     public void testActivityRequestedOrientationChanged() throws Exception {
         final int[] params = new int[2];
         final CountDownLatch latch = new CountDownLatch(1);
@@ -146,6 +152,7 @@
      * Tests for onTaskCreated, onTaskMovedToFront, onTaskRemoved and onTaskRemovalStarted.
      */
     @Test
+    @FlakyTest(bugId = 119893767)
     public void testTaskChangeCallBacks() throws Exception {
         final Object[] params = new Object[2];
         final CountDownLatch taskCreatedLaunchLatch = new CountDownLatch(1);
@@ -221,7 +228,8 @@
         final ActivityMonitor monitor = new ActivityMonitor(activityClass.getName(), null, false);
         getInstrumentation().addMonitor(monitor);
         final Context context = getInstrumentation().getContext();
-        context.startActivity(new Intent(context, activityClass));
+        context.startActivity(
+                new Intent(context, activityClass).addFlags(Intent.FLAG_ACTIVITY_NEW_TASK));
         final TestActivity activity = (TestActivity) monitor.waitForActivityWithTimeout(1000);
         if (activity == null) {
             throw new RuntimeException("Timed out waiting for Activity");
diff --git a/services/tests/wmtests/src/com/android/server/wm/WindowConfigurationTests.java b/services/tests/wmtests/src/com/android/server/wm/WindowConfigurationTests.java
index 64ceb1b..d6608f1 100644
--- a/services/tests/wmtests/src/com/android/server/wm/WindowConfigurationTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/WindowConfigurationTests.java
@@ -49,7 +49,7 @@
  * Test class to for {@link android.app.WindowConfiguration}.
  *
  * Build/Install/Run:
- *  atest FrameworksServicesTests:WindowConfigurationTests
+ *  atest WmTests:WindowConfigurationTests
  */
 @SmallTest
 @Presubmit
diff --git a/services/tests/wmtests/src/com/android/server/wm/WindowContainerControllerTests.java b/services/tests/wmtests/src/com/android/server/wm/WindowContainerControllerTests.java
index af8ccc9..fc78635 100644
--- a/services/tests/wmtests/src/com/android/server/wm/WindowContainerControllerTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/WindowContainerControllerTests.java
@@ -26,7 +26,6 @@
 import android.content.res.Configuration;
 import android.platform.test.annotations.Presubmit;
 
-import androidx.test.filters.FlakyTest;
 import androidx.test.filters.SmallTest;
 
 import org.junit.Test;
@@ -35,7 +34,7 @@
  * Test class for {@link WindowContainerController}.
  *
  * Build/Install/Run:
- *  atest FrameworksServicesTests:WindowContainerControllerTests
+ *  atest WmTests:WindowContainerControllerTests
  */
 @SmallTest
 @Presubmit
diff --git a/services/tests/wmtests/src/com/android/server/wm/WindowContainerTests.java b/services/tests/wmtests/src/com/android/server/wm/WindowContainerTests.java
index a9a76c2..b93c994 100644
--- a/services/tests/wmtests/src/com/android/server/wm/WindowContainerTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/WindowContainerTests.java
@@ -47,7 +47,6 @@
 import android.view.SurfaceControl;
 import android.view.SurfaceSession;
 
-import androidx.test.filters.FlakyTest;
 import androidx.test.filters.SmallTest;
 
 import org.junit.Test;
@@ -59,11 +58,10 @@
  * Test class for {@link WindowContainer}.
  *
  * Build/Install/Run:
- *  atest FrameworksServicesTests:WindowContainerTests
+ *  atest WmTests:WindowContainerTests
  */
 @SmallTest
 @Presubmit
-@FlakyTest(bugId = 74078662)
 public class WindowContainerTests extends WindowTestsBase {
 
     @Test
diff --git a/services/tests/wmtests/src/com/android/server/wm/WindowTokenTests.java b/services/tests/wmtests/src/com/android/server/wm/WindowTokenTests.java
index d556886..4cdbea0 100644
--- a/services/tests/wmtests/src/com/android/server/wm/WindowTokenTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/WindowTokenTests.java
@@ -28,7 +28,6 @@
 
 import android.platform.test.annotations.Presubmit;
 
-import androidx.test.filters.FlakyTest;
 import androidx.test.filters.SmallTest;
 
 import org.junit.Test;
@@ -37,7 +36,7 @@
  * Tests for the {@link WindowToken} class.
  *
  * Build/Install/Run:
- *  atest FrameworksServicesTests:WindowTokenTests
+ *  atest WmTests:WindowTokenTests
  */
 @SmallTest
 @Presubmit
diff --git a/services/tests/wmtests/src/com/android/server/wm/WindowTracingTest.java b/services/tests/wmtests/src/com/android/server/wm/WindowTracingTest.java
index 2970c21..3c6e240 100644
--- a/services/tests/wmtests/src/com/android/server/wm/WindowTracingTest.java
+++ b/services/tests/wmtests/src/com/android/server/wm/WindowTracingTest.java
@@ -58,7 +58,7 @@
  * Test class for {@link WindowTracing}.
  *
  * Build/Install/Run:
- *  atest FrameworksServicesTests:WindowTracingTest
+ *  atest WmTests:WindowTracingTest
  */
 @SmallTest
 @Presubmit
diff --git a/services/tests/wmtests/src/com/android/server/wm/ZOrderingTests.java b/services/tests/wmtests/src/com/android/server/wm/ZOrderingTests.java
index 3dcea75..f3b8a62 100644
--- a/services/tests/wmtests/src/com/android/server/wm/ZOrderingTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/ZOrderingTests.java
@@ -51,9 +51,8 @@
  * Tests for the {@link DisplayContent#assignChildLayers(SurfaceControl.Transaction)} method.
  *
  * Build/Install/Run:
- *  atest FrameworksServicesTests:ZOrderingTests
+ *  atest WmTests:ZOrderingTests
  */
-@FlakyTest(bugId = 74078662)
 @SmallTest
 @Presubmit
 public class ZOrderingTests extends WindowTestsBase {
@@ -207,6 +206,7 @@
         return createWindow(null, TYPE_BASE_APPLICATION, mDisplayContent, name);
     }
 
+    @FlakyTest(bugId = 124088319)
     @Test
     public void testAssignWindowLayers_ForImeWithNoTarget() {
         mDisplayContent.mInputMethodTarget = null;
@@ -224,6 +224,7 @@
         assertWindowHigher(mImeDialogWindow, mImeWindow);
     }
 
+    @FlakyTest(bugId = 124088319)
     @Test
     public void testAssignWindowLayers_ForImeWithAppTarget() {
         final WindowState imeAppTarget = createWindow("imeAppTarget");
@@ -243,6 +244,7 @@
         assertWindowHigher(mImeDialogWindow, mImeWindow);
     }
 
+    @FlakyTest(bugId = 124088319)
     @Test
     public void testAssignWindowLayers_ForImeWithAppTargetWithChildWindows() {
         final WindowState imeAppTarget = createWindow("imeAppTarget");
@@ -269,6 +271,7 @@
         assertWindowHigher(mImeDialogWindow, mImeWindow);
     }
 
+    @FlakyTest(bugId = 124088319)
     @Test
     public void testAssignWindowLayers_ForImeWithAppTargetAndAppAbove() {
         final WindowState appBelowImeTarget = createWindow("appBelowImeTarget");
@@ -292,6 +295,7 @@
         assertWindowHigher(mImeDialogWindow, mImeWindow);
     }
 
+    @FlakyTest(bugId = 124088319)
     @Test
     public void testAssignWindowLayers_ForImeNonAppImeTarget() {
         final WindowState imeSystemOverlayTarget = createWindow(null, TYPE_SYSTEM_OVERLAY,
@@ -319,6 +323,7 @@
         assertWindowHigher(mImeDialogWindow, mImeWindow);
     }
 
+    @FlakyTest(bugId = 124088319)
     @Test
     public void testAssignWindowLayers_ForStatusBarImeTarget() {
         mDisplayContent.mInputMethodTarget = mStatusBarWindow;
@@ -333,6 +338,7 @@
         assertWindowHigher(mImeDialogWindow, mImeWindow);
     }
 
+    @FlakyTest(bugId = 124088319)
     @Test
     public void testStackLayers() {
         final WindowState anyWindow1 = createWindow("anyWindow");
@@ -398,6 +404,7 @@
         assertWindowHigher(mediaOverlayChild, child);
     }
 
+    @FlakyTest(bugId = 124088319)
     @Test
     public void testDockedDividerPosition() {
         final WindowState pinnedStackWindow = createWindowOnStack(null, WINDOWING_MODE_PINNED,
diff --git a/tests/net/java/com/android/server/ConnectivityServiceTest.java b/tests/net/java/com/android/server/ConnectivityServiceTest.java
index e2d59d6..a7c95c7 100644
--- a/tests/net/java/com/android/server/ConnectivityServiceTest.java
+++ b/tests/net/java/com/android/server/ConnectivityServiceTest.java
@@ -554,7 +554,7 @@
 
                 if (mNmValidationRedirectUrl != null) {
                     mNmCallbacks.showProvisioningNotification(
-                            "test_provisioning_notif_action");
+                            "test_provisioning_notif_action", "com.android.test.package");
                     mNmProvNotificationRequested = true;
                 }
             } catch (RemoteException e) {
diff --git a/tests/net/java/com/android/server/connectivity/TetheringTest.java b/tests/net/java/com/android/server/connectivity/TetheringTest.java
index b635607..a4a735d 100644
--- a/tests/net/java/com/android/server/connectivity/TetheringTest.java
+++ b/tests/net/java/com/android/server/connectivity/TetheringTest.java
@@ -35,6 +35,7 @@
 import static android.net.wifi.WifiManager.IFACE_IP_MODE_TETHERED;
 import static android.net.wifi.WifiManager.WIFI_AP_STATE_ENABLED;
 import static android.provider.Settings.Global.TETHER_ENABLE_LEGACY_DHCP_SERVER;
+import static android.telephony.SubscriptionManager.INVALID_SUBSCRIPTION_ID;
 
 import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertTrue;
@@ -274,6 +275,11 @@
             isTetheringSupportedCalls++;
             return true;
         }
+
+        @Override
+        public int getDefaultDataSubscriptionId() {
+            return INVALID_SUBSCRIPTION_ID;
+        }
     }
 
     private static NetworkState buildMobileUpstreamState(boolean withIPv4, boolean withIPv6,
diff --git a/tests/net/java/com/android/server/connectivity/tethering/EntitlementManagerTest.java b/tests/net/java/com/android/server/connectivity/tethering/EntitlementManagerTest.java
index ec286759..193f380 100644
--- a/tests/net/java/com/android/server/connectivity/tethering/EntitlementManagerTest.java
+++ b/tests/net/java/com/android/server/connectivity/tethering/EntitlementManagerTest.java
@@ -21,6 +21,7 @@
 import static android.net.ConnectivityManager.TETHER_ERROR_ENTITLEMENT_UNKONWN;
 import static android.net.ConnectivityManager.TETHER_ERROR_NO_ERROR;
 import static android.net.ConnectivityManager.TETHER_ERROR_PROVISION_FAILED;
+import static android.telephony.SubscriptionManager.INVALID_SUBSCRIPTION_ID;
 
 import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertFalse;
@@ -140,7 +141,8 @@
         mMockContext = new MockContext(mContext);
         mSM = new TestStateMachine();
         mEnMgr = new WrappedEntitlementManager(mMockContext, mSM, mLog, mSystemProperties);
-        mEnMgr.updateConfiguration(new TetheringConfiguration(mMockContext, mLog));
+        mEnMgr.updateConfiguration(
+                new TetheringConfiguration(mMockContext, mLog, INVALID_SUBSCRIPTION_ID));
     }
 
     @After
@@ -168,7 +170,8 @@
     @Test
     public void canRequireProvisioning() {
         setupForRequiredProvisioning();
-        mEnMgr.updateConfiguration(new TetheringConfiguration(mMockContext, mLog));
+        mEnMgr.updateConfiguration(
+                new TetheringConfiguration(mMockContext, mLog, INVALID_SUBSCRIPTION_ID));
         assertTrue(mEnMgr.isTetherProvisioningRequired());
     }
 
@@ -177,7 +180,8 @@
         setupForRequiredProvisioning();
         when(mContext.getSystemService(Context.CARRIER_CONFIG_SERVICE))
             .thenReturn(null);
-        mEnMgr.updateConfiguration(new TetheringConfiguration(mMockContext, mLog));
+        mEnMgr.updateConfiguration(
+                new TetheringConfiguration(mMockContext, mLog, INVALID_SUBSCRIPTION_ID));
         // Couldn't get the CarrierConfigManager, but still had a declared provisioning app.
         // Therefore provisioning still be required.
         assertTrue(mEnMgr.isTetherProvisioningRequired());
@@ -187,7 +191,8 @@
     public void toleratesCarrierConfigMissing() {
         setupForRequiredProvisioning();
         when(mCarrierConfigManager.getConfig()).thenReturn(null);
-        mEnMgr.updateConfiguration(new TetheringConfiguration(mMockContext, mLog));
+        mEnMgr.updateConfiguration(
+                new TetheringConfiguration(mMockContext, mLog, INVALID_SUBSCRIPTION_ID));
         // We still have a provisioning app configured, so still require provisioning.
         assertTrue(mEnMgr.isTetherProvisioningRequired());
     }
@@ -197,11 +202,13 @@
         setupForRequiredProvisioning();
         when(mResources.getStringArray(R.array.config_mobile_hotspot_provision_app))
             .thenReturn(null);
-        mEnMgr.updateConfiguration(new TetheringConfiguration(mMockContext, mLog));
+        mEnMgr.updateConfiguration(
+                new TetheringConfiguration(mMockContext, mLog, INVALID_SUBSCRIPTION_ID));
         assertFalse(mEnMgr.isTetherProvisioningRequired());
         when(mResources.getStringArray(R.array.config_mobile_hotspot_provision_app))
             .thenReturn(new String[] {"malformedApp"});
-        mEnMgr.updateConfiguration(new TetheringConfiguration(mMockContext, mLog));
+        mEnMgr.updateConfiguration(
+                new TetheringConfiguration(mMockContext, mLog, INVALID_SUBSCRIPTION_ID));
         assertFalse(mEnMgr.isTetherProvisioningRequired());
     }
 
@@ -223,7 +230,8 @@
         assertFalse(mEnMgr.everRunUiEntitlement);
 
         setupForRequiredProvisioning();
-        mEnMgr.updateConfiguration(new TetheringConfiguration(mMockContext, mLog));
+        mEnMgr.updateConfiguration(new TetheringConfiguration(mMockContext, mLog,
+                  INVALID_SUBSCRIPTION_ID));
         // 2. No cache value and don't need to run entitlement check.
         mEnMgr.everRunUiEntitlement = false;
         receiver = new ResultReceiver(null) {
diff --git a/tests/net/java/com/android/server/connectivity/tethering/TetheringConfigurationTest.java b/tests/net/java/com/android/server/connectivity/tethering/TetheringConfigurationTest.java
index 5217784..01b904d8 100644
--- a/tests/net/java/com/android/server/connectivity/tethering/TetheringConfigurationTest.java
+++ b/tests/net/java/com/android/server/connectivity/tethering/TetheringConfigurationTest.java
@@ -22,10 +22,12 @@
 import static android.net.ConnectivityManager.TYPE_MOBILE_HIPRI;
 import static android.net.ConnectivityManager.TYPE_WIFI;
 import static android.provider.Settings.Global.TETHER_ENABLE_LEGACY_DHCP_SERVER;
+import static android.telephony.SubscriptionManager.INVALID_SUBSCRIPTION_ID;
 
 import static com.android.server.connectivity.tethering.TetheringConfiguration.DUN_NOT_REQUIRED;
 import static com.android.server.connectivity.tethering.TetheringConfiguration.DUN_REQUIRED;
 import static com.android.server.connectivity.tethering.TetheringConfiguration.DUN_UNSPECIFIED;
+
 import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertFalse;
 import static org.junit.Assert.assertTrue;
@@ -44,26 +46,39 @@
 import com.android.internal.util.test.BroadcastInterceptingContext;
 import com.android.internal.util.test.FakeSettingsProvider;
 
-import java.util.Iterator;
-
 import org.junit.Before;
 import org.junit.Test;
 import org.junit.runner.RunWith;
 import org.mockito.Mock;
 import org.mockito.MockitoAnnotations;
 
+import java.util.Iterator;
 
 @RunWith(AndroidJUnit4.class)
 @SmallTest
 public class TetheringConfigurationTest {
     private final SharedLog mLog = new SharedLog("TetheringConfigurationTest");
+
+    private static final String[] PROVISIONING_APP_NAME = {"some", "app"};
     @Mock private Context mContext;
     @Mock private TelephonyManager mTelephonyManager;
     @Mock private Resources mResources;
+    @Mock private Resources mResourcesForSubId;
     private MockContentResolver mContentResolver;
     private Context mMockContext;
     private boolean mHasTelephonyManager;
 
+    private class MockTetheringConfiguration extends TetheringConfiguration {
+        MockTetheringConfiguration(Context ctx, SharedLog log, int id) {
+            super(ctx, log, id);
+        }
+
+        @Override
+        protected Resources getResourcesForSubIdWrapper(Context ctx, int subId) {
+            return mResourcesForSubId;
+        }
+    }
+
     private class MockContext extends BroadcastInterceptingContext {
         MockContext(Context base) {
             super(base);
@@ -99,6 +114,9 @@
                 .thenReturn(new String[0]);
         when(mResources.getIntArray(com.android.internal.R.array.config_tether_upstream_types))
                 .thenReturn(new int[0]);
+        when(mResources.getStringArray(
+                com.android.internal.R.array.config_mobile_hotspot_provision_app))
+                .thenReturn(new String[0]);
         mContentResolver = new MockContentResolver();
         mContentResolver.addProvider(Settings.AUTHORITY, new FakeSettingsProvider());
         mMockContext = new MockContext(mContext);
@@ -111,7 +129,8 @@
         mHasTelephonyManager = true;
         when(mTelephonyManager.getTetherApnRequired()).thenReturn(DUN_REQUIRED);
 
-        final TetheringConfiguration cfg = new TetheringConfiguration(mMockContext, mLog);
+        final TetheringConfiguration cfg = new TetheringConfiguration(
+                mMockContext, mLog, INVALID_SUBSCRIPTION_ID);
         assertTrue(cfg.isDunRequired);
         assertTrue(cfg.preferredUpstreamIfaceTypes.contains(TYPE_MOBILE_DUN));
         assertFalse(cfg.preferredUpstreamIfaceTypes.contains(TYPE_MOBILE));
@@ -127,7 +146,8 @@
         mHasTelephonyManager = true;
         when(mTelephonyManager.getTetherApnRequired()).thenReturn(DUN_NOT_REQUIRED);
 
-        final TetheringConfiguration cfg = new TetheringConfiguration(mMockContext, mLog);
+        final TetheringConfiguration cfg = new TetheringConfiguration(
+                mMockContext, mLog, INVALID_SUBSCRIPTION_ID);
         assertFalse(cfg.isDunRequired);
         assertFalse(cfg.preferredUpstreamIfaceTypes.contains(TYPE_MOBILE_DUN));
         assertTrue(cfg.preferredUpstreamIfaceTypes.contains(TYPE_MOBILE));
@@ -143,7 +163,8 @@
         mHasTelephonyManager = false;
         when(mTelephonyManager.getTetherApnRequired()).thenReturn(DUN_UNSPECIFIED);
 
-        final TetheringConfiguration cfg = new TetheringConfiguration(mMockContext, mLog);
+        final TetheringConfiguration cfg = new TetheringConfiguration(
+                mMockContext, mLog, INVALID_SUBSCRIPTION_ID);
         assertTrue(cfg.isDunRequired);
         assertTrue(cfg.preferredUpstreamIfaceTypes.contains(TYPE_MOBILE_DUN));
         // Just to prove we haven't clobbered Wi-Fi:
@@ -160,7 +181,8 @@
         mHasTelephonyManager = false;
         when(mTelephonyManager.getTetherApnRequired()).thenReturn(DUN_UNSPECIFIED);
 
-        final TetheringConfiguration cfg = new TetheringConfiguration(mMockContext, mLog);
+        final TetheringConfiguration cfg = new TetheringConfiguration(
+                mMockContext, mLog, INVALID_SUBSCRIPTION_ID);
         final Iterator<Integer> upstreamIterator = cfg.preferredUpstreamIfaceTypes.iterator();
         assertTrue(upstreamIterator.hasNext());
         assertEquals(TYPE_ETHERNET, upstreamIterator.next().intValue());
@@ -181,7 +203,8 @@
         mHasTelephonyManager = false;
         when(mTelephonyManager.getTetherApnRequired()).thenReturn(DUN_UNSPECIFIED);
 
-        final TetheringConfiguration cfg = new TetheringConfiguration(mMockContext, mLog);
+        final TetheringConfiguration cfg = new TetheringConfiguration(
+                mMockContext, mLog, INVALID_SUBSCRIPTION_ID);
         final Iterator<Integer> upstreamIterator = cfg.preferredUpstreamIfaceTypes.iterator();
         assertTrue(upstreamIterator.hasNext());
         assertEquals(TYPE_ETHERNET, upstreamIterator.next().intValue());
@@ -199,7 +222,8 @@
         mHasTelephonyManager = false;
         when(mTelephonyManager.getTetherApnRequired()).thenReturn(DUN_UNSPECIFIED);
 
-        final TetheringConfiguration cfg = new TetheringConfiguration(mMockContext, mLog);
+        final TetheringConfiguration cfg = new TetheringConfiguration(
+                mMockContext, mLog, INVALID_SUBSCRIPTION_ID);
         final Iterator<Integer> upstreamIterator = cfg.preferredUpstreamIfaceTypes.iterator();
         assertTrue(upstreamIterator.hasNext());
         assertEquals(TYPE_WIFI, upstreamIterator.next().intValue());
@@ -214,7 +238,8 @@
     public void testNewDhcpServerDisabled() {
         Settings.Global.putInt(mContentResolver, TETHER_ENABLE_LEGACY_DHCP_SERVER, 1);
 
-        final TetheringConfiguration cfg = new TetheringConfiguration(mMockContext, mLog);
+        final TetheringConfiguration cfg = new TetheringConfiguration(
+                mMockContext, mLog, INVALID_SUBSCRIPTION_ID);
         assertTrue(cfg.enableLegacyDhcpServer);
     }
 
@@ -222,7 +247,41 @@
     public void testNewDhcpServerEnabled() {
         Settings.Global.putInt(mContentResolver, TETHER_ENABLE_LEGACY_DHCP_SERVER, 0);
 
-        final TetheringConfiguration cfg = new TetheringConfiguration(mMockContext, mLog);
+        final TetheringConfiguration cfg = new TetheringConfiguration(
+                mMockContext, mLog, INVALID_SUBSCRIPTION_ID);
         assertFalse(cfg.enableLegacyDhcpServer);
     }
+
+    @Test
+    public void testGetResourcesBySubId() {
+        setUpResourceForSubId();
+        final TetheringConfiguration cfg = new TetheringConfiguration(
+                mMockContext, mLog, INVALID_SUBSCRIPTION_ID);
+        assertTrue(cfg.provisioningApp.length == 0);
+        final int anyValidSubId = 1;
+        final MockTetheringConfiguration mockCfg =
+                new MockTetheringConfiguration(mMockContext, mLog, anyValidSubId);
+        assertEquals(mockCfg.provisioningApp[0], PROVISIONING_APP_NAME[0]);
+        assertEquals(mockCfg.provisioningApp[1], PROVISIONING_APP_NAME[1]);
+    }
+
+    private void setUpResourceForSubId() {
+        when(mResourcesForSubId.getStringArray(
+                com.android.internal.R.array.config_tether_dhcp_range)).thenReturn(new String[0]);
+        when(mResourcesForSubId.getStringArray(
+                com.android.internal.R.array.config_tether_usb_regexs)).thenReturn(new String[0]);
+        when(mResourcesForSubId.getStringArray(
+                com.android.internal.R.array.config_tether_wifi_regexs))
+                .thenReturn(new String[]{ "test_wlan\\d" });
+        when(mResourcesForSubId.getStringArray(
+                com.android.internal.R.array.config_tether_bluetooth_regexs))
+                .thenReturn(new String[0]);
+        when(mResourcesForSubId.getIntArray(
+                com.android.internal.R.array.config_tether_upstream_types))
+                .thenReturn(new int[0]);
+        when(mResourcesForSubId.getStringArray(
+                com.android.internal.R.array.config_mobile_hotspot_provision_app))
+                .thenReturn(PROVISIONING_APP_NAME);
+    }
+
 }