Expose upstream requirements to UpstreamNetworkMonitor.

UpstreamNetworkMonitor is the part of tethering that files
NetworkRequests for upstream netwoks, but it currently does not
know all the requirements for upstream selection. For example, it
does not know whether automatic upstream selection is in use.
This forces the upstream selection code to be split between
UpstreamNetworkMonitor and Tethering. This makes it difficult to
follow.

This CL ensures that all information about upstream requirements
(DUN required, automatic upstream selection, tryCell) is passed
to UpstreamNetworkMonitor so it can be aware of it.

This CL also removes the ability for UpstreamNetworkMonitor's
callers to call registerMobileNetworkRequest or
releaseMobileNetworkRequest. In a future CL, this will be
automatically done by UpstreamNetworkMonitor depending on the
upstream requirements.

This CL is a no-op refactoring with no behaviour changes.

Bug: 173068192
Test: atest TetheringTests
Change-Id: I174f765c616e0dbe2aa493c12613e6131cff0666
diff --git a/Tethering/src/com/android/networkstack/tethering/Tethering.java b/Tethering/src/com/android/networkstack/tethering/Tethering.java
index ac5857d..c6e8fd6 100644
--- a/Tethering/src/com/android/networkstack/tethering/Tethering.java
+++ b/Tethering/src/com/android/networkstack/tethering/Tethering.java
@@ -442,7 +442,8 @@
     // NOTE: This is always invoked on the mLooper thread.
     private void updateConfiguration() {
         mConfig = mDeps.generateTetheringConfiguration(mContext, mLog, mActiveDataSubId);
-        mUpstreamNetworkMonitor.updateMobileRequiresDun(mConfig.isDunRequired);
+        mUpstreamNetworkMonitor.setUpstreamConfig(mConfig.chooseUpstreamAutomatically,
+                mConfig.isDunRequired);
         reportConfigurationChanged(mConfig.toStableParcelable());
     }
 
@@ -1559,7 +1560,7 @@
                             config.preferredUpstreamIfaceTypes);
             if (ns == null) {
                 if (tryCell) {
-                    mUpstreamNetworkMonitor.registerMobileNetworkRequest();
+                    mUpstreamNetworkMonitor.setTryCell(true);
                     // We think mobile should be coming up; don't set a retry.
                 } else {
                     sendMessageDelayed(CMD_RETRY_UPSTREAM, UPSTREAM_SETTLE_TIME_MS);
@@ -1852,7 +1853,7 @@
                         // longer desired, release any mobile requests.
                         final boolean previousUpstreamWanted = updateUpstreamWanted();
                         if (previousUpstreamWanted && !mUpstreamWanted) {
-                            mUpstreamNetworkMonitor.releaseMobileNetworkRequest();
+                            mUpstreamNetworkMonitor.setTryCell(false);
                         }
                         break;
                     }
diff --git a/Tethering/src/com/android/networkstack/tethering/UpstreamNetworkMonitor.java b/Tethering/src/com/android/networkstack/tethering/UpstreamNetworkMonitor.java
index b17065c..eb22448 100644
--- a/Tethering/src/com/android/networkstack/tethering/UpstreamNetworkMonitor.java
+++ b/Tethering/src/com/android/networkstack/tethering/UpstreamNetworkMonitor.java
@@ -60,7 +60,7 @@
  * Calling #startObserveAllNetworks() to observe all networks. Listening all
  * networks is necessary while the expression of preferred upstreams remains
  * a list of legacy connectivity types.  In future, this can be revisited.
- * Calling #registerMobileNetworkRequest() to bring up mobile DUN/HIPRI network.
+ * Calling #setTryCell() to request bringing up mobile DUN or HIPRI.
  *
  * The methods and data members of this class are only to be accessed and
  * modified from the tethering main state machine thread. Any other
@@ -114,7 +114,14 @@
     private NetworkCallback mListenAllCallback;
     private NetworkCallback mDefaultNetworkCallback;
     private NetworkCallback mMobileNetworkCallback;
+
+    /** Whether Tethering has requested a cellular upstream. */
+    private boolean mTryCell;
+    /** Whether the carrier requires DUN. */
     private boolean mDunRequired;
+    /** Whether automatic upstream selection is enabled. */
+    private boolean mAutoUpstream;
+
     // Whether the current default upstream is mobile or not.
     private boolean mIsDefaultCellularUpstream;
     // The current system default network (not really used yet).
@@ -190,23 +197,49 @@
         mNetworkMap.clear();
     }
 
-    /** Setup or teardown DUN connection according to |dunRequired|. */
-    public void updateMobileRequiresDun(boolean dunRequired) {
-        final boolean valueChanged = (mDunRequired != dunRequired);
+    private void reevaluateUpstreamRequirements(boolean tryCell, boolean autoUpstream,
+            boolean dunRequired) {
+        final boolean mobileRequestWasRequired = mTryCell && (mDunRequired || !mAutoUpstream);
+        final boolean mobileRequestIsRequired = tryCell && (dunRequired || !autoUpstream);
+        final boolean dunRequiredChanged = (mDunRequired != dunRequired);
+
+        mTryCell = tryCell;
         mDunRequired = dunRequired;
-        if (valueChanged && mobileNetworkRequested()) {
+        mAutoUpstream = autoUpstream;
+
+        if (dunRequiredChanged && mobileNetworkRequested()) {
             releaseMobileNetworkRequest();
             registerMobileNetworkRequest();
         }
     }
 
+    /**
+     * Informs UpstreamNetworkMonitor that a cellular upstream is desired.
+     *
+     * This may result in filing a NetworkRequest for DUN if it is required, or for MOBILE_HIPRI if
+     * automatic upstream selection is disabled and MOBILE_HIPRI is the preferred upstream.
+     */
+    public void setTryCell(boolean tryCell) {
+        reevaluateUpstreamRequirements(tryCell, mAutoUpstream, mDunRequired);
+        if (tryCell) {
+            registerMobileNetworkRequest();
+        } else {
+            releaseMobileNetworkRequest();
+        }
+    }
+
+    /** Informs UpstreamNetworkMonitor of upstream configuration parameters. */
+    public void setUpstreamConfig(boolean autoUpstream, boolean dunRequired) {
+        reevaluateUpstreamRequirements(mTryCell, autoUpstream, dunRequired);
+    }
+
     /** Whether mobile network is requested. */
     public boolean mobileNetworkRequested() {
         return (mMobileNetworkCallback != null);
     }
 
     /** Request mobile network if mobile upstream is permitted. */
-    public void registerMobileNetworkRequest() {
+    private void registerMobileNetworkRequest() {
         if (!isCellularUpstreamPermitted()) {
             mLog.i("registerMobileNetworkRequest() is not permitted");
             releaseMobileNetworkRequest();
@@ -248,7 +281,7 @@
     }
 
     /** Release mobile network request. */
-    public void releaseMobileNetworkRequest() {
+    private void releaseMobileNetworkRequest() {
         if (mMobileNetworkCallback == null) return;
 
         cm().unregisterNetworkCallback(mMobileNetworkCallback);
diff --git a/Tethering/tests/unit/src/com/android/networkstack/tethering/TetheringTest.java b/Tethering/tests/unit/src/com/android/networkstack/tethering/TetheringTest.java
index 0611086..d5c7add 100644
--- a/Tethering/tests/unit/src/com/android/networkstack/tethering/TetheringTest.java
+++ b/Tethering/tests/unit/src/com/android/networkstack/tethering/TetheringTest.java
@@ -1101,7 +1101,7 @@
         sendUsbBroadcast(true, true, true, TETHERING_USB);
         mLooper.dispatchAll();
         inOrder.verify(mUpstreamNetworkMonitor).startObserveAllNetworks();
-        inOrder.verify(mUpstreamNetworkMonitor).registerMobileNetworkRequest();
+        inOrder.verify(mUpstreamNetworkMonitor).setTryCell(true);
 
         // Pretend cellular connected and expect the upstream to be set.
         TestNetworkAgent mobile = new TestNetworkAgent(mCm, buildMobileDualStackUpstreamState());
@@ -1251,7 +1251,7 @@
         verify(mUpstreamNetworkMonitor, times(1)).startObserveAllNetworks();
         // In tethering mode, in the default configuration, an explicit request
         // for a mobile network is also made.
-        verify(mUpstreamNetworkMonitor, times(1)).registerMobileNetworkRequest();
+        verify(mUpstreamNetworkMonitor, times(1)).setTryCell(true);
         // There are 2 IpServer state change events: STATE_AVAILABLE -> STATE_TETHERED
         verify(mNotificationUpdater, times(1)).onDownstreamChanged(DOWNSTREAM_NONE);
         verify(mNotificationUpdater, times(1)).onDownstreamChanged(eq(1 << TETHERING_WIFI));
diff --git a/Tethering/tests/unit/src/com/android/networkstack/tethering/UpstreamNetworkMonitorTest.java b/Tethering/tests/unit/src/com/android/networkstack/tethering/UpstreamNetworkMonitorTest.java
index 7d735fc..4376b61 100644
--- a/Tethering/tests/unit/src/com/android/networkstack/tethering/UpstreamNetworkMonitorTest.java
+++ b/Tethering/tests/unit/src/com/android/networkstack/tethering/UpstreamNetworkMonitorTest.java
@@ -134,9 +134,9 @@
         assertTrue(mCM.hasNoCallbacks());
         assertFalse(mUNM.mobileNetworkRequested());
 
-        mUNM.updateMobileRequiresDun(true);
+        mUNM.setUpstreamConfig(false /* autoUpstream */, true /* dunRequired */);
         assertTrue(mCM.hasNoCallbacks());
-        mUNM.updateMobileRequiresDun(false);
+        mUNM.setUpstreamConfig(false /* autoUpstream */, false /* dunRequired */);
         assertTrue(mCM.hasNoCallbacks());
     }
 
@@ -187,11 +187,11 @@
         assertFalse(mUNM.mobileNetworkRequested());
         assertEquals(0, mCM.requested.size());
 
-        mUNM.updateMobileRequiresDun(false);
+        mUNM.setUpstreamConfig(false /* autoUpstream */, false /* dunRequired */);
         assertFalse(mUNM.mobileNetworkRequested());
         assertEquals(0, mCM.requested.size());
 
-        mUNM.registerMobileNetworkRequest();
+        mUNM.setTryCell(true);
         assertTrue(mUNM.mobileNetworkRequested());
         assertUpstreamTypeRequested(TYPE_MOBILE_HIPRI);
         assertFalse(isDunRequested());
@@ -212,8 +212,8 @@
         assertFalse(mUNM.mobileNetworkRequested());
         assertEquals(0, mCM.requested.size());
 
-        mUNM.updateMobileRequiresDun(true);
-        mUNM.registerMobileNetworkRequest();
+        mUNM.setUpstreamConfig(false /* autoUpstream */, true /* dunRequired */);
+        mUNM.setTryCell(true);
         verify(mCM, times(1)).requestNetwork(
                 any(NetworkRequest.class), anyInt(), anyInt(), any(Handler.class),
                 any(NetworkCallback.class));
@@ -223,9 +223,9 @@
         assertTrue(isDunRequested());
 
         // Try a few things that must not result in any state change.
-        mUNM.registerMobileNetworkRequest();
-        mUNM.updateMobileRequiresDun(true);
-        mUNM.registerMobileNetworkRequest();
+        mUNM.setTryCell(true);
+        mUNM.setUpstreamConfig(false /* autoUpstream */, true /* dunRequired */);
+        mUNM.setTryCell(true);
 
         assertTrue(mUNM.mobileNetworkRequested());
         assertUpstreamTypeRequested(TYPE_MOBILE_DUN);
@@ -246,11 +246,11 @@
         assertFalse(mUNM.mobileNetworkRequested());
         assertEquals(0, mCM.requested.size());
 
-        mUNM.updateMobileRequiresDun(true);
+        mUNM.setUpstreamConfig(false /* autoUpstream */, true /* dunRequired */);
         assertFalse(mUNM.mobileNetworkRequested());
         assertEquals(0, mCM.requested.size());
 
-        mUNM.registerMobileNetworkRequest();
+        mUNM.setTryCell(true);
         assertTrue(mUNM.mobileNetworkRequested());
         assertUpstreamTypeRequested(TYPE_MOBILE_DUN);
         assertTrue(isDunRequested());
@@ -265,18 +265,18 @@
         mUNM.startObserveAllNetworks();
 
         // Test going from no-DUN to DUN correctly re-registers callbacks.
-        mUNM.updateMobileRequiresDun(false);
-        mUNM.registerMobileNetworkRequest();
+        mUNM.setUpstreamConfig(false /* autoUpstream */, false /* dunRequired */);
+        mUNM.setTryCell(true);
         assertTrue(mUNM.mobileNetworkRequested());
         assertUpstreamTypeRequested(TYPE_MOBILE_HIPRI);
         assertFalse(isDunRequested());
-        mUNM.updateMobileRequiresDun(true);
+        mUNM.setUpstreamConfig(false /* autoUpstream */, true /* dunRequired */);
         assertTrue(mUNM.mobileNetworkRequested());
         assertUpstreamTypeRequested(TYPE_MOBILE_DUN);
         assertTrue(isDunRequested());
 
         // Test going from DUN to no-DUN correctly re-registers callbacks.
-        mUNM.updateMobileRequiresDun(false);
+        mUNM.setUpstreamConfig(false /* autoUpstream */, false /* dunRequired */);
         assertTrue(mUNM.mobileNetworkRequested());
         assertUpstreamTypeRequested(TYPE_MOBILE_HIPRI);
         assertFalse(isDunRequested());
@@ -309,14 +309,14 @@
 
         preferredTypes.add(TYPE_MOBILE_DUN);
         // This is coupled with preferred types in TetheringConfiguration.
-        mUNM.updateMobileRequiresDun(true);
+        mUNM.setUpstreamConfig(false /* autoUpstream */, true /* dunRequired */);
         // DUN is available, but only use regular cell: no upstream selected.
         assertSatisfiesLegacyType(TYPE_NONE, mUNM.selectPreferredUpstreamType(preferredTypes));
         preferredTypes.remove(TYPE_MOBILE_DUN);
         // No WiFi, but our preferred flavour of cell is up.
         preferredTypes.add(TYPE_MOBILE_HIPRI);
         // This is coupled with preferred types in TetheringConfiguration.
-        mUNM.updateMobileRequiresDun(false);
+        mUNM.setUpstreamConfig(false /* autoUpstream */, false /* dunRequired */);
         assertSatisfiesLegacyType(TYPE_MOBILE_HIPRI,
                 mUNM.selectPreferredUpstreamType(preferredTypes));
         // Check to see we filed an explicit request.
@@ -341,7 +341,7 @@
         preferredTypes.remove(TYPE_MOBILE_HIPRI);
         preferredTypes.add(TYPE_MOBILE_DUN);
         // This is coupled with preferred types in TetheringConfiguration.
-        mUNM.updateMobileRequiresDun(true);
+        mUNM.setUpstreamConfig(false /* autoUpstream */, true /* dunRequired */);
         assertSatisfiesLegacyType(TYPE_WIFI, mUNM.selectPreferredUpstreamType(preferredTypes));
 
         final TestNetworkAgent dunAgent = new TestNetworkAgent(mCM, DUN_CAPABILITIES);
@@ -373,7 +373,7 @@
     public void testGetCurrentPreferredUpstream() throws Exception {
         mUNM.startTrackDefaultNetwork(sDefaultRequest, mEntitleMgr);
         mUNM.startObserveAllNetworks();
-        mUNM.updateMobileRequiresDun(false);
+        mUNM.setUpstreamConfig(false /* autoUpstream */, false /* dunRequired */);
 
         // [0] Mobile connects, DUN not required -> mobile selected.
         final TestNetworkAgent cellAgent = new TestNetworkAgent(mCM, CELL_CAPABILITIES);
@@ -396,7 +396,7 @@
         assertEquals(wifiAgent.networkId, mUNM.getCurrentPreferredUpstream().network);
 
         // [4] DUN required, no other changes -> WiFi still selected
-        mUNM.updateMobileRequiresDun(true);
+        mUNM.setUpstreamConfig(false /* autoUpstream */, true /* dunRequired */);
         assertEquals(wifiAgent.networkId, mUNM.getCurrentPreferredUpstream().network);
 
         // [5] WiFi no longer validated, mobile becomes default, DUN required -> null selected.