Merge "[Thread] disable handling of airplane mode" into main am: 5e61693235

Original change: https://android-review.googlesource.com/c/platform/packages/modules/Connectivity/+/3172380

Change-Id: Ieab73a4ba1a26ae689d11bc9d5e390bef2aaf7b4
Signed-off-by: Automerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com>
diff --git a/thread/service/java/com/android/server/thread/ThreadNetworkControllerService.java b/thread/service/java/com/android/server/thread/ThreadNetworkControllerService.java
index bf3cedb..e6f272b 100644
--- a/thread/service/java/com/android/server/thread/ThreadNetworkControllerService.java
+++ b/thread/service/java/com/android/server/thread/ThreadNetworkControllerService.java
@@ -111,7 +111,6 @@
 import android.os.RemoteException;
 import android.os.SystemClock;
 import android.os.UserManager;
-import android.provider.Settings;
 import android.util.Log;
 import android.util.SparseArray;
 
@@ -211,7 +210,6 @@
     private final ThreadPersistentSettings mPersistentSettings;
     private final UserManager mUserManager;
     private boolean mUserRestricted;
-    private boolean mAirplaneModeOn;
     private boolean mForceStopOtDaemonEnabled;
 
     private BorderRouterConfigurationParcel mBorderRouterConfig;
@@ -446,8 +444,6 @@
                     requestThreadNetwork();
                     mUserRestricted = isThreadUserRestricted();
                     registerUserRestrictionsReceiver();
-                    mAirplaneModeOn = isAirplaneModeOn();
-                    registerAirplaneModeReceiver();
                     maybeInitializeOtDaemon();
                 });
     }
@@ -529,15 +525,6 @@
             // the otDaemon set enabled state operation succeeded or not, so that it can recover
             // to the desired value after reboot.
             mPersistentSettings.put(ThreadPersistentSettings.THREAD_ENABLED.key, isEnabled);
-
-            // Remember whether the user wanted to keep Thread enabled in airplane mode. If once
-            // the user disabled Thread again in airplane mode, the persistent settings state is
-            // reset (so that Thread will be auto-disabled again when airplane mode is turned on).
-            // This behavior is consistent with Wi-Fi and bluetooth.
-            if (mAirplaneModeOn) {
-                mPersistentSettings.put(
-                        ThreadPersistentSettings.THREAD_ENABLED_IN_AIRPLANE_MODE.key, isEnabled);
-            }
         }
 
         try {
@@ -676,74 +663,13 @@
         return mUserManager.hasUserRestriction(DISALLOW_THREAD_NETWORK);
     }
 
-    private void registerAirplaneModeReceiver() {
-        mContext.registerReceiver(
-                new BroadcastReceiver() {
-                    @Override
-                    public void onReceive(Context context, Intent intent) {
-                        onAirplaneModeChanged(isAirplaneModeOn());
-                    }
-                },
-                new IntentFilter(Intent.ACTION_AIRPLANE_MODE_CHANGED),
-                null /* broadcastPermission */,
-                mHandler);
-    }
-
-    private void onAirplaneModeChanged(boolean newAirplaneModeOn) {
-        checkOnHandlerThread();
-        if (mAirplaneModeOn == newAirplaneModeOn) {
-            return;
-        }
-        Log.i(TAG, "Airplane mode changed: " + mAirplaneModeOn + " -> " + newAirplaneModeOn);
-        mAirplaneModeOn = newAirplaneModeOn;
-
-        final boolean shouldEnableThread = shouldEnableThread();
-        final IOperationReceiver receiver =
-                new IOperationReceiver.Stub() {
-                    @Override
-                    public void onSuccess() {
-                        Log.d(
-                                TAG,
-                                (shouldEnableThread ? "Enabled" : "Disabled")
-                                        + " Thread due to airplane mode change");
-                    }
-
-                    @Override
-                    public void onError(int errorCode, String errorMessage) {
-                        Log.e(
-                                TAG,
-                                "Failed to "
-                                        + (shouldEnableThread ? "enable" : "disable")
-                                        + " Thread for airplane mode change");
-                    }
-                };
-        // Do not save the user restriction state to persistent settings so that the user
-        // configuration won't be overwritten
-        setEnabledInternal(
-                shouldEnableThread, false /* persist */, new OperationReceiverWrapper(receiver));
-    }
-
-    /** Returns {@code true} if Airplane mode has been turned on. */
-    private boolean isAirplaneModeOn() {
-        return Settings.Global.getInt(
-                        mContext.getContentResolver(), Settings.Global.AIRPLANE_MODE_ON, 0)
-                == 1;
-    }
-
     /**
      * Returns {@code true} if Thread should be enabled based on current settings, runtime user
-     * restriction and airplane mode state.
+     * restriction state.
      */
     private boolean shouldEnableThread() {
-        final boolean enabledInAirplaneMode =
-                mPersistentSettings.get(ThreadPersistentSettings.THREAD_ENABLED_IN_AIRPLANE_MODE);
-
         return !mForceStopOtDaemonEnabled
                 && !mUserRestricted
-                // FIXME(b/340744397): Note that here we need to call `isAirplaneModeOn()` to get
-                // the latest state of airplane mode but can't use `mIsAirplaneMode`. This is for
-                // avoiding the race conditions described in b/340744397
-                && (!isAirplaneModeOn() || enabledInAirplaneMode)
                 && mPersistentSettings.get(ThreadPersistentSettings.THREAD_ENABLED);
     }
 
diff --git a/thread/tests/unit/src/com/android/server/thread/ThreadNetworkControllerServiceTest.java b/thread/tests/unit/src/com/android/server/thread/ThreadNetworkControllerServiceTest.java
index bf61c68..eaf11b1 100644
--- a/thread/tests/unit/src/com/android/server/thread/ThreadNetworkControllerServiceTest.java
+++ b/thread/tests/unit/src/com/android/server/thread/ThreadNetworkControllerServiceTest.java
@@ -26,7 +26,6 @@
 import static android.net.thread.ThreadNetworkManager.PERMISSION_THREAD_NETWORK_PRIVILEGED;
 
 import static com.android.server.thread.ThreadNetworkCountryCode.DEFAULT_COUNTRY_CODE;
-import static com.android.server.thread.ThreadPersistentSettings.THREAD_ENABLED_IN_AIRPLANE_MODE;
 import static com.android.server.thread.openthread.IOtDaemon.ErrorCode.OT_ERROR_INVALID_STATE;
 
 import static com.google.common.io.BaseEncoding.base16;
@@ -70,7 +69,6 @@
 import android.os.SystemClock;
 import android.os.UserManager;
 import android.os.test.TestLooper;
-import android.provider.Settings;
 import android.util.AtomicFile;
 
 import androidx.test.annotation.UiThreadTest;
@@ -194,8 +192,6 @@
 
         when(mMockUserManager.hasUserRestriction(eq(DISALLOW_THREAD_NETWORK))).thenReturn(false);
 
-        Settings.Global.putInt(mContext.getContentResolver(), Settings.Global.AIRPLANE_MODE_ON, 0);
-
         when(mConnectivityResources.get()).thenReturn(mResources);
         when(mResources.getBoolean(eq(R.bool.config_thread_default_enabled))).thenReturn(true);
         when(mResources.getString(eq(R.string.config_thread_vendor_name)))
@@ -481,100 +477,6 @@
         assertThat(failure.getErrorCode()).isEqualTo(ERROR_FAILED_PRECONDITION);
     }
 
-    @Test
-    public void airplaneMode_initWithAirplaneModeOn_otDaemonNotStarted() {
-        Settings.Global.putInt(mContext.getContentResolver(), Settings.Global.AIRPLANE_MODE_ON, 1);
-
-        mService.initialize();
-        mTestLooper.dispatchAll();
-
-        assertThat(mFakeOtDaemon.isInitialized()).isFalse();
-    }
-
-    @Test
-    public void airplaneMode_initWithAirplaneModeOff_threadIsEnabled() {
-        Settings.Global.putInt(mContext.getContentResolver(), Settings.Global.AIRPLANE_MODE_ON, 0);
-
-        mService.initialize();
-        mTestLooper.dispatchAll();
-
-        assertThat(mFakeOtDaemon.getEnabledState()).isEqualTo(STATE_ENABLED);
-    }
-
-    @Test
-    public void airplaneMode_changesFromOffToOn_stateIsDisabled() {
-        Settings.Global.putInt(mContext.getContentResolver(), Settings.Global.AIRPLANE_MODE_ON, 0);
-        AtomicReference<BroadcastReceiver> receiverRef =
-                captureBroadcastReceiver(Intent.ACTION_AIRPLANE_MODE_CHANGED);
-        mService.initialize();
-        mTestLooper.dispatchAll();
-
-        Settings.Global.putInt(mContext.getContentResolver(), Settings.Global.AIRPLANE_MODE_ON, 1);
-        receiverRef.get().onReceive(mContext, new Intent());
-        mTestLooper.dispatchAll();
-
-        assertThat(mFakeOtDaemon.getEnabledState()).isEqualTo(STATE_DISABLED);
-    }
-
-    @Test
-    public void airplaneMode_changesFromOnToOff_stateIsEnabled() {
-        Settings.Global.putInt(mContext.getContentResolver(), Settings.Global.AIRPLANE_MODE_ON, 1);
-        AtomicReference<BroadcastReceiver> receiverRef =
-                captureBroadcastReceiver(Intent.ACTION_AIRPLANE_MODE_CHANGED);
-        mService.initialize();
-        mTestLooper.dispatchAll();
-
-        Settings.Global.putInt(mContext.getContentResolver(), Settings.Global.AIRPLANE_MODE_ON, 0);
-        receiverRef.get().onReceive(mContext, new Intent());
-        mTestLooper.dispatchAll();
-
-        assertThat(mFakeOtDaemon.getEnabledState()).isEqualTo(STATE_ENABLED);
-    }
-
-    @Test
-    public void airplaneMode_setEnabledWhenAirplaneModeIsOn_WillNotAutoDisableSecondTime() {
-        Settings.Global.putInt(mContext.getContentResolver(), Settings.Global.AIRPLANE_MODE_ON, 1);
-        AtomicReference<BroadcastReceiver> receiverRef =
-                captureBroadcastReceiver(Intent.ACTION_AIRPLANE_MODE_CHANGED);
-        CompletableFuture<Void> setEnabledFuture = new CompletableFuture<>();
-        mService.initialize();
-
-        mService.setEnabled(true, newOperationReceiver(setEnabledFuture));
-        mTestLooper.dispatchAll();
-        Settings.Global.putInt(mContext.getContentResolver(), Settings.Global.AIRPLANE_MODE_ON, 0);
-        receiverRef.get().onReceive(mContext, new Intent());
-        mTestLooper.dispatchAll();
-        Settings.Global.putInt(mContext.getContentResolver(), Settings.Global.AIRPLANE_MODE_ON, 1);
-        receiverRef.get().onReceive(mContext, new Intent());
-        mTestLooper.dispatchAll();
-
-        assertThat(mFakeOtDaemon.getEnabledState()).isEqualTo(STATE_ENABLED);
-        assertThat(mPersistentSettings.get(THREAD_ENABLED_IN_AIRPLANE_MODE)).isTrue();
-    }
-
-    @Test
-    public void airplaneMode_setDisabledWhenAirplaneModeIsOn_WillAutoDisableSecondTime() {
-        Settings.Global.putInt(mContext.getContentResolver(), Settings.Global.AIRPLANE_MODE_ON, 1);
-        AtomicReference<BroadcastReceiver> receiverRef =
-                captureBroadcastReceiver(Intent.ACTION_AIRPLANE_MODE_CHANGED);
-        CompletableFuture<Void> setEnabledFuture = new CompletableFuture<>();
-        mService.initialize();
-        mService.setEnabled(true, newOperationReceiver(setEnabledFuture));
-        mTestLooper.dispatchAll();
-
-        mService.setEnabled(false, newOperationReceiver(setEnabledFuture));
-        mTestLooper.dispatchAll();
-        Settings.Global.putInt(mContext.getContentResolver(), Settings.Global.AIRPLANE_MODE_ON, 0);
-        receiverRef.get().onReceive(mContext, new Intent());
-        mTestLooper.dispatchAll();
-        Settings.Global.putInt(mContext.getContentResolver(), Settings.Global.AIRPLANE_MODE_ON, 1);
-        receiverRef.get().onReceive(mContext, new Intent());
-        mTestLooper.dispatchAll();
-
-        assertThat(mFakeOtDaemon.getEnabledState()).isEqualTo(STATE_DISABLED);
-        assertThat(mPersistentSettings.get(THREAD_ENABLED_IN_AIRPLANE_MODE)).isFalse();
-    }
-
     private AtomicReference<BroadcastReceiver> captureBroadcastReceiver(String action) {
         AtomicReference<BroadcastReceiver> receiverRef = new AtomicReference<>();