Merge "The UI is not immediately updated" into sc-dev
diff --git a/res/values/strings.xml b/res/values/strings.xml
index 1ee3882..75b2645 100644
--- a/res/values/strings.xml
+++ b/res/values/strings.xml
@@ -12562,6 +12562,8 @@
     <string name="to_switch_networks_disconnect_ethernet">To switch networks, disconnect ethernet</string>
     <!-- Summary for cannot switch networks to Wi-Fi nor mobile data networks while connected to an ethernet network. [CHAR LIMIT=60] -->
     <string name="cannot_switch_networks_while_connected">Cannot switch networks while connected</string>
+    <!-- Title for airplane mode network panel. [CHAR LIMIT=60] -->
+    <string name="airplane_mode_network_panel_title">Airplane mode networks</string>
 
     <!-- Summary text separator for preferences including a short description
          (eg. "Connected / 5G"). [CHAR LIMIT=50] -->
diff --git a/src/com/android/settings/network/InternetUpdater.java b/src/com/android/settings/network/InternetUpdater.java
index 1eafb60..d415b10 100644
--- a/src/com/android/settings/network/InternetUpdater.java
+++ b/src/com/android/settings/network/InternetUpdater.java
@@ -149,16 +149,15 @@
 
     public InternetUpdater(Context context, Lifecycle lifecycle,
             OnInternetTypeChangedListener listener) {
-        if (lifecycle == null) {
-            throw new IllegalArgumentException("Lifecycle must be set");
-        }
         mContext = context;
         mAirplaneModeEnabler = new AirplaneModeEnabler(mContext, this);
         mConnectivityManager = mContext.getSystemService(ConnectivityManager.class);
         mWifiManager = mContext.getSystemService(WifiManager.class);
         mWifiStateFilter = new IntentFilter(WifiManager.WIFI_STATE_CHANGED_ACTION);
         mOnInternetTypeChangedListener = listener;
-        lifecycle.addObserver(this);
+        if (lifecycle != null) {
+            lifecycle.addObserver(this);
+        }
     }
 
     /** @OnLifecycleEvent(ON_RESUME) */
diff --git a/src/com/android/settings/panel/InternetConnectivityPanel.java b/src/com/android/settings/panel/InternetConnectivityPanel.java
index 64a4699..7bafe97 100644
--- a/src/com/android/settings/panel/InternetConnectivityPanel.java
+++ b/src/com/android/settings/panel/InternetConnectivityPanel.java
@@ -16,6 +16,10 @@
 
 package com.android.settings.panel;
 
+import static androidx.lifecycle.Lifecycle.Event.ON_PAUSE;
+import static androidx.lifecycle.Lifecycle.Event.ON_RESUME;
+
+import static com.android.settings.network.InternetUpdater.INTERNET_APM_NETWORKS;
 import static com.android.settings.network.NetworkProviderSettings.ACTION_NETWORK_PROVIDER_SETTINGS;
 
 import android.app.settings.SettingsEnums;
@@ -24,9 +28,14 @@
 import android.net.Uri;
 import android.provider.Settings;
 
+import androidx.annotation.VisibleForTesting;
+import androidx.lifecycle.LifecycleObserver;
+import androidx.lifecycle.OnLifecycleEvent;
+
 import com.android.settings.R;
 import com.android.settings.Utils;
 import com.android.settings.network.AirplaneModePreferenceController;
+import com.android.settings.network.InternetUpdater;
 import com.android.settings.slices.CustomSliceRegistry;
 
 import java.util.ArrayList;
@@ -35,9 +44,15 @@
 /**
  * Represents the Internet Connectivity Panel.
  */
-public class InternetConnectivityPanel implements PanelContent {
+public class InternetConnectivityPanel implements PanelContent, LifecycleObserver,
+        InternetUpdater.OnInternetTypeChangedListener {
 
     private final Context mContext;
+    @VisibleForTesting
+    boolean mIsProviderModelEnabled;
+    private PanelContentCallback mCallback;
+    private InternetUpdater mInternetUpdater;
+    private @InternetUpdater.InternetType int mInternetType;
 
     public static InternetConnectivityPanel create(Context context) {
         return new InternetConnectivityPanel(context);
@@ -45,12 +60,37 @@
 
     private InternetConnectivityPanel(Context context) {
         mContext = context.getApplicationContext();
+        mIsProviderModelEnabled = Utils.isProviderModelEnabled(mContext);
+        mInternetUpdater = new InternetUpdater(context, null /* Lifecycle */, this);
+        mInternetType = mInternetUpdater.getInternetType();
+    }
+
+    /** @OnLifecycleEvent(ON_RESUME) */
+    @OnLifecycleEvent(ON_RESUME)
+    public void onResume() {
+        if (!mIsProviderModelEnabled) {
+            return;
+        }
+        mInternetUpdater.onResume();
+    }
+
+    /** @OnLifecycleEvent(ON_PAUSE) */
+    @OnLifecycleEvent(ON_PAUSE)
+    public void onPause() {
+        if (!mIsProviderModelEnabled) {
+            return;
+        }
+        mInternetUpdater.onPause();
     }
 
     @Override
     public CharSequence getTitle() {
-        return mContext.getText(Utils.isProviderModelEnabled(mContext)
-                ? R.string.provider_internet_settings : R.string.internet_connectivity_panel_title);
+        if (mIsProviderModelEnabled) {
+            return mContext.getText(mInternetType == INTERNET_APM_NETWORKS
+                    ? R.string.airplane_mode_network_panel_title
+                    : R.string.provider_internet_settings);
+        }
+        return mContext.getText(R.string.internet_connectivity_panel_title);
     }
 
     @Override
@@ -93,4 +133,30 @@
     public int getMetricsCategory() {
         return SettingsEnums.PANEL_INTERNET_CONNECTIVITY;
     }
+
+    @Override
+    public void registerCallback(PanelContentCallback callback) {
+        mCallback = callback;
+    }
+
+    /**
+     * Called when internet type is changed.
+     *
+     * @param internetType the internet type
+     */
+    public void onInternetTypeChanged(@InternetUpdater.InternetType int internetType) {
+        final boolean needRefresh = internetType != mInternetType
+                && (internetType == INTERNET_APM_NETWORKS
+                || mInternetType == INTERNET_APM_NETWORKS);
+        mInternetType = internetType;
+        if (needRefresh) {
+            refresh();
+        }
+    }
+
+    private void refresh() {
+        if (mCallback != null) {
+            mCallback.onTitleChanged();
+        }
+    }
 }
diff --git a/src/com/android/settings/panel/PanelContentCallback.java b/src/com/android/settings/panel/PanelContentCallback.java
index 63c2c55..f0e68a3 100644
--- a/src/com/android/settings/panel/PanelContentCallback.java
+++ b/src/com/android/settings/panel/PanelContentCallback.java
@@ -37,4 +37,9 @@
      * It will be called when panel requests to close itself.
      */
     void forceClose();
+
+    /**
+     * It will be called when panel requests to change the title.
+     */
+    void onTitleChanged();
 }
diff --git a/src/com/android/settings/panel/PanelFragment.java b/src/com/android/settings/panel/PanelFragment.java
index 8eec24f..503b34a 100644
--- a/src/com/android/settings/panel/PanelFragment.java
+++ b/src/com/android/settings/panel/PanelFragment.java
@@ -514,6 +514,13 @@
             getFragmentActivity().finish();
         }
 
+        @Override
+        public void onTitleChanged() {
+            ThreadUtils.postOnMainThread(() -> {
+                mTitleView.setText(mPanel.getTitle());
+            });
+        }
+
         @VisibleForTesting
         FragmentActivity getFragmentActivity() {
             return getActivity();
diff --git a/tests/unit/src/com/android/settings/panel/InternetConnectivityPanelTest.java b/tests/unit/src/com/android/settings/panel/InternetConnectivityPanelTest.java
new file mode 100644
index 0000000..e8f694b
--- /dev/null
+++ b/tests/unit/src/com/android/settings/panel/InternetConnectivityPanelTest.java
@@ -0,0 +1,95 @@
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.settings.panel;
+
+import static com.android.settings.network.InternetUpdater.INTERNET_APM;
+import static com.android.settings.network.InternetUpdater.INTERNET_APM_NETWORKS;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import static org.mockito.Mockito.clearInvocations;
+import static org.mockito.Mockito.spy;
+import static org.mockito.Mockito.verify;
+
+import android.content.Context;
+
+import androidx.test.core.app.ApplicationProvider;
+import androidx.test.ext.junit.runners.AndroidJUnit4;
+
+import com.android.settings.testutils.ResourcesUtils;
+
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.Mock;
+import org.mockito.junit.MockitoJUnit;
+import org.mockito.junit.MockitoRule;
+
+@RunWith(AndroidJUnit4.class)
+public class InternetConnectivityPanelTest {
+
+    public static final String TITLE_INTERNET = ResourcesUtils.getResourcesString(
+            ApplicationProvider.getApplicationContext(), "provider_internet_settings");
+    public static final String TITLE_APM_NETWORKS = ResourcesUtils.getResourcesString(
+            ApplicationProvider.getApplicationContext(), "airplane_mode_network_panel_title");
+
+    @Rule
+    public final MockitoRule mMocks = MockitoJUnit.rule();
+    @Mock
+    PanelContentCallback mPanelContentCallback;
+
+    private Context mContext;
+    private InternetConnectivityPanel mPanel;
+
+    @Before
+    public void setUp() {
+        mContext = spy(ApplicationProvider.getApplicationContext());
+
+        mPanel = InternetConnectivityPanel.create(mContext);
+        mPanel.registerCallback(mPanelContentCallback);
+        mPanel.mIsProviderModelEnabled = true;
+    }
+
+    @Test
+    public void getTitle_internetTypeChangedFromApmToApmNetworks_verifyTitleChanged() {
+        mPanel.onInternetTypeChanged(INTERNET_APM);
+
+        assertThat(mPanel.getTitle()).isEqualTo(TITLE_INTERNET);
+
+        clearInvocations(mPanelContentCallback);
+
+        mPanel.onInternetTypeChanged(INTERNET_APM_NETWORKS);
+
+        assertThat(mPanel.getTitle()).isEqualTo(TITLE_APM_NETWORKS);
+        verify(mPanelContentCallback).onTitleChanged();
+    }
+
+    @Test
+    public void getTitle_internetTypeChangedFromApmNetworksToApm_verifyTitleChanged() {
+        mPanel.onInternetTypeChanged(INTERNET_APM_NETWORKS);
+
+        assertThat(mPanel.getTitle()).isEqualTo(TITLE_APM_NETWORKS);
+
+        clearInvocations(mPanelContentCallback);
+
+        mPanel.onInternetTypeChanged(INTERNET_APM);
+
+        assertThat(mPanel.getTitle()).isEqualTo(TITLE_INTERNET);
+        verify(mPanelContentCallback).onTitleChanged();
+    }
+}