diff --git a/tests/unit/src/com/android/settings/applications/AppOpsSettingsTest.java b/tests/unit/src/com/android/settings/applications/AppOpsSettingsTest.java
deleted file mode 100644
index fbbc01a..0000000
--- a/tests/unit/src/com/android/settings/applications/AppOpsSettingsTest.java
+++ /dev/null
@@ -1,211 +0,0 @@
-/*
- * Copyright (C) 2017 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package com.android.settings.applications;
-
-import static android.app.AppOpsManager.MODE_ALLOWED;
-import static android.app.AppOpsManager.MODE_DEFAULT;
-import static android.app.AppOpsManager.MODE_ERRORED;
-import static android.content.Intent.FLAG_ACTIVITY_CLEAR_TASK;
-import static android.content.Intent.FLAG_ACTIVITY_NEW_TASK;
-
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertNotNull;
-import static org.junit.Assert.assertTrue;
-
-import android.app.AppOpsManager;
-import android.content.Context;
-import android.content.Intent;
-import android.content.pm.ApplicationInfo;
-import android.content.pm.PackageManager;
-import android.content.pm.UserInfo;
-import android.net.Uri;
-import android.os.UserHandle;
-import android.os.UserManager;
-import android.support.test.uiautomator.By;
-import android.support.test.uiautomator.BySelector;
-import android.support.test.uiautomator.Direction;
-import android.support.test.uiautomator.UiDevice;
-import android.support.test.uiautomator.UiObject2;
-import android.support.test.uiautomator.Until;
-import android.widget.Switch;
-import android.widget.TextView;
-
-import androidx.recyclerview.widget.RecyclerView;
-import androidx.test.InstrumentationRegistry;
-
-import org.junit.After;
-import org.junit.Before;
-import org.junit.Test;
-
-import java.util.List;
-
-/**
- * An abstract parent for testing settings activities that manage an AppOps permission.
- */
-abstract public class AppOpsSettingsTest {
-    private static final String WM_DISMISS_KEYGUARD_COMMAND = "wm dismiss-keyguard";
-    private static final long START_ACTIVITY_TIMEOUT = 5000;
-
-    private Context mContext;
-    private UiDevice mUiDevice;
-    private PackageManager mPackageManager;
-    private AppOpsManager mAppOpsManager;
-    private List<UserInfo> mProfiles;
-    private String mPackageName;
-
-    // These depend on which app op's settings UI is being tested.
-    private final String mActivityAction;
-    private final int mAppOpCode;
-
-    protected AppOpsSettingsTest(String activityAction, int appOpCode) {
-        mActivityAction = activityAction;
-        mAppOpCode = appOpCode;
-    }
-
-    @Before
-    public void setUp() throws Exception {
-        mContext = InstrumentationRegistry.getTargetContext();
-        mPackageName = InstrumentationRegistry.getContext().getPackageName();
-        mPackageManager = mContext.getPackageManager();
-        mAppOpsManager = mContext.getSystemService(AppOpsManager.class);
-        mProfiles = mContext.getSystemService(UserManager.class).getProfiles(UserHandle.myUserId());
-        resetAppOpModeForAllProfiles();
-        mUiDevice = UiDevice.getInstance(InstrumentationRegistry.getInstrumentation());
-        mUiDevice.wakeUp();
-        mUiDevice.executeShellCommand(WM_DISMISS_KEYGUARD_COMMAND);
-    }
-
-    private void resetAppOpModeForAllProfiles() throws Exception {
-        for (UserInfo user : mProfiles) {
-            final int uid = mPackageManager.getPackageUidAsUser(mPackageName, user.id);
-            mAppOpsManager.setMode(mAppOpCode, uid, mPackageName, MODE_DEFAULT);
-        }
-    }
-
-    /**
-     * Creates an intent for showing the permission settings for all apps.
-     */
-    private Intent createManageAllAppsIntent() {
-        final Intent intent = new Intent(mActivityAction);
-        intent.addFlags(FLAG_ACTIVITY_CLEAR_TASK | FLAG_ACTIVITY_NEW_TASK);
-        return intent;
-    }
-
-    /**
-     * Creates an intent for showing the permission setting for a single app.
-     */
-    private Intent createManageSingleAppIntent(String packageName) {
-        final Intent intent = createManageAllAppsIntent();
-        intent.setData(Uri.parse("package:" + packageName));
-        return intent;
-    }
-
-    private String getApplicationLabel(String packageName) throws Exception {
-        final ApplicationInfo info = mPackageManager.getApplicationInfo(packageName, 0);
-        return mPackageManager.getApplicationLabel(info).toString();
-    }
-
-    private UiObject2 findAndVerifySwitchState(boolean checked) {
-        final BySelector switchSelector = By.clazz(Switch.class).res("android:id/switch_widget");
-        final UiObject2 switchPref = mUiDevice.wait(Until.findObject(switchSelector),
-                START_ACTIVITY_TIMEOUT);
-        assertNotNull("Switch not shown", switchPref);
-        assertTrue("Switch in invalid state", switchPref.isChecked() == checked);
-        return switchPref;
-    }
-
-    @Test
-    public void testAppList() throws Exception {
-        final String testAppLabel = getApplicationLabel(mPackageName);
-
-        mContext.startActivity(createManageAllAppsIntent());
-        final BySelector preferenceListSelector =
-                By.clazz(RecyclerView.class).res("com.android.settings:id/apps_list");
-        final UiObject2 preferenceList = mUiDevice.wait(Until.findObject(preferenceListSelector),
-                START_ACTIVITY_TIMEOUT);
-        assertNotNull("App list not shown", preferenceList);
-
-        final BySelector appLabelTextViewSelector = By.clazz(TextView.class)
-                .res("android:id/title")
-                .text(testAppLabel);
-        List<UiObject2> listOfMatchingTextViews;
-        do {
-            listOfMatchingTextViews = preferenceList.findObjects(appLabelTextViewSelector);
-            // assuming the number of profiles will be sufficiently small so that all the entries
-            // for the same package will fit in one screen at some time during the scroll.
-        } while (listOfMatchingTextViews.size() != mProfiles.size() &&
-                preferenceList.scroll(Direction.DOWN, 0.2f));
-        assertEquals("Test app not listed for each profile", mProfiles.size(),
-                listOfMatchingTextViews.size());
-
-        for (UiObject2 matchingObject : listOfMatchingTextViews) {
-            matchingObject.click();
-            findAndVerifySwitchState(true);
-            mUiDevice.pressBack();
-        }
-    }
-
-    private void testAppDetailScreenForAppOp(int appOpMode, int userId) throws Exception {
-        final String testAppLabel = getApplicationLabel(mPackageName);
-        final BySelector appDetailTitleSelector = By.clazz(TextView.class)
-                .res("com.android.settings:id/app_detail_title")
-                .text(testAppLabel);
-
-        mAppOpsManager.setMode(mAppOpCode,
-                mPackageManager.getPackageUidAsUser(mPackageName, userId), mPackageName, appOpMode);
-        mContext.startActivityAsUser(createManageSingleAppIntent(mPackageName),
-                UserHandle.of(userId));
-        mUiDevice.wait(Until.findObject(appDetailTitleSelector), START_ACTIVITY_TIMEOUT);
-        findAndVerifySwitchState(appOpMode == MODE_ALLOWED || appOpMode == MODE_DEFAULT);
-        mUiDevice.pressBack();
-    }
-
-    @Test
-    public void testSingleApp() throws Exception {
-        // App op MODE_DEFAULT is already tested in #testAppList
-        for (UserInfo user : mProfiles) {
-            testAppDetailScreenForAppOp(MODE_ALLOWED, user.id);
-            testAppDetailScreenForAppOp(MODE_ERRORED, user.id);
-        }
-    }
-
-    private void testSwitchToggle(int fromAppOp, int toAppOp) throws Exception {
-        final int packageUid = mPackageManager.getPackageUid(mPackageName, 0);
-        final boolean initialState = (fromAppOp == MODE_ALLOWED || fromAppOp == MODE_DEFAULT);
-
-        mAppOpsManager.setMode(mAppOpCode, packageUid, mPackageName, fromAppOp);
-        mContext.startActivity(createManageSingleAppIntent(mPackageName));
-        final UiObject2 switchPref = findAndVerifySwitchState(initialState);
-        switchPref.click();
-        Thread.sleep(1000);
-        assertEquals("Toggling switch did not change app op", toAppOp,
-                mAppOpsManager.checkOpNoThrow(mAppOpCode, packageUid,
-                        mPackageName));
-        mUiDevice.pressBack();
-    }
-
-    @Test
-    public void testIfSwitchTogglesAppOp() throws Exception {
-        testSwitchToggle(MODE_ALLOWED, MODE_ERRORED);
-        testSwitchToggle(MODE_ERRORED, MODE_ALLOWED);
-    }
-
-    @After
-    public void tearDown() throws Exception {
-        mUiDevice.pressHome();
-        resetAppOpModeForAllProfiles();
-    }
-}
diff --git a/tests/unit/src/com/android/settings/applications/DrawOverlaySettingsTest.java b/tests/unit/src/com/android/settings/applications/DrawOverlaySettingsTest.java
deleted file mode 100644
index b6d51ff..0000000
--- a/tests/unit/src/com/android/settings/applications/DrawOverlaySettingsTest.java
+++ /dev/null
@@ -1,36 +0,0 @@
-/*
- * Copyright (C) 2017 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.settings.applications;
-
-import android.app.AppOpsManager;
-import android.provider.Settings;
-
-import androidx.test.filters.LargeTest;
-import androidx.test.runner.AndroidJUnit4;
-
-import org.junit.runner.RunWith;
-
-@RunWith(AndroidJUnit4.class)
-@LargeTest
-public class DrawOverlaySettingsTest extends AppOpsSettingsTest {
-
-    public DrawOverlaySettingsTest() {
-        super(Settings.ACTION_MANAGE_OVERLAY_PERMISSION, AppOpsManager.OP_SYSTEM_ALERT_WINDOW);
-    }
-
-    // Test cases are in the superclass.
-}
\ No newline at end of file
diff --git a/tests/unit/src/com/android/settings/applications/ExternalSourcesSettingsTest.java b/tests/unit/src/com/android/settings/applications/ExternalSourcesSettingsTest.java
deleted file mode 100644
index b35d6cb..0000000
--- a/tests/unit/src/com/android/settings/applications/ExternalSourcesSettingsTest.java
+++ /dev/null
@@ -1,37 +0,0 @@
-/*
- * Copyright (C) 2017 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.settings.applications;
-
-import android.app.AppOpsManager;
-import android.provider.Settings;
-
-import androidx.test.filters.LargeTest;
-import androidx.test.runner.AndroidJUnit4;
-
-import org.junit.runner.RunWith;
-
-@RunWith(AndroidJUnit4.class)
-@LargeTest
-public class ExternalSourcesSettingsTest extends AppOpsSettingsTest {
-
-    public ExternalSourcesSettingsTest() {
-        super(Settings.ACTION_MANAGE_UNKNOWN_APP_SOURCES,
-                AppOpsManager.OP_REQUEST_INSTALL_PACKAGES);
-    }
-
-    // Test cases are in the superclass.
-}
diff --git a/tests/unit/src/com/android/settings/biometrics/fingerprint/FingerprintEnrollFinishTest.java b/tests/unit/src/com/android/settings/biometrics/fingerprint/FingerprintEnrollFinishTest.java
deleted file mode 100644
index 589680d..0000000
--- a/tests/unit/src/com/android/settings/biometrics/fingerprint/FingerprintEnrollFinishTest.java
+++ /dev/null
@@ -1,93 +0,0 @@
-/*
- * Copyright (C) 2017 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package com.android.settings.biometrics.fingerprint;
-
-import static androidx.test.InstrumentationRegistry.getTargetContext;
-import static androidx.test.espresso.Espresso.onView;
-import static androidx.test.espresso.action.ViewActions.click;
-import static androidx.test.espresso.intent.Intents.intended;
-import static androidx.test.espresso.intent.Intents.intending;
-import static androidx.test.espresso.intent.matcher.IntentMatchers.hasComponent;
-import static androidx.test.espresso.matcher.ViewMatchers.withId;
-
-import static org.junit.Assert.assertFalse;
-import static org.junit.Assert.assertTrue;
-
-import android.app.Activity;
-import android.app.Instrumentation.ActivityResult;
-import android.content.ComponentName;
-
-import androidx.test.espresso.intent.rule.IntentsTestRule;
-import androidx.test.filters.SmallTest;
-import androidx.test.runner.AndroidJUnit4;
-
-import com.android.settings.R;
-
-import com.google.android.setupcompat.PartnerCustomizationLayout;
-import com.google.android.setupcompat.template.FooterBarMixin;
-
-import org.junit.Rule;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-
-@RunWith(AndroidJUnit4.class)
-@SmallTest
-public class FingerprintEnrollFinishTest {
-
-    @Rule
-    public IntentsTestRule<FingerprintEnrollFinish> mActivityRule =
-            new IntentsTestRule<>(FingerprintEnrollFinish.class);
-
-    @Test
-    public void clickAddAnother_shouldLaunchEnrolling() {
-        final ComponentName enrollingComponent = new ComponentName(
-                getTargetContext(),
-                FingerprintEnrollEnrolling.class);
-
-        intending(hasComponent(enrollingComponent))
-                .respondWith(new ActivityResult(Activity.RESULT_CANCELED, null));
-
-        PartnerCustomizationLayout layout =
-                mActivityRule.getActivity().findViewById(R.id.setup_wizard_layout);
-        layout.getMixin(FooterBarMixin.class).getPrimaryButtonView().performClick();
-
-        intended(hasComponent(enrollingComponent));
-        assertFalse(mActivityRule.getActivity().isFinishing());
-    }
-
-    @Test
-    public void clickAddAnother_shouldPropagateResults() {
-        final ComponentName enrollingComponent = new ComponentName(
-                getTargetContext(),
-                FingerprintEnrollEnrolling.class);
-
-        intending(hasComponent(enrollingComponent))
-                .respondWith(new ActivityResult(Activity.RESULT_OK, null));
-
-        PartnerCustomizationLayout layout =
-                mActivityRule.getActivity().findViewById(R.id.setup_wizard_layout);
-        layout.getMixin(FooterBarMixin.class).getPrimaryButtonView().performClick();
-
-        intended(hasComponent(enrollingComponent));
-        assertTrue(mActivityRule.getActivity().isFinishing());
-    }
-
-    @Test
-    public void clickNext_shouldFinish() {
-        onView(withId(R.id.next_button)).perform(click());
-        assertTrue(mActivityRule.getActivity().isFinishing());
-    }
-}
\ No newline at end of file
diff --git a/tests/unit/src/com/android/settings/biometrics/fingerprint/FingerprintEnrollIntroductionTest.java b/tests/unit/src/com/android/settings/biometrics/fingerprint/FingerprintEnrollIntroductionTest.java
deleted file mode 100644
index 454de3d..0000000
--- a/tests/unit/src/com/android/settings/biometrics/fingerprint/FingerprintEnrollIntroductionTest.java
+++ /dev/null
@@ -1,113 +0,0 @@
-/*
- * Copyright (C) 2016 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.settings.biometrics.fingerprint;
-
-
-import static org.mockito.Matchers.anyInt;
-import static org.mockito.Mockito.doReturn;
-
-import android.content.Context;
-import android.content.ContextWrapper;
-import android.content.Intent;
-import android.hardware.fingerprint.Fingerprint;
-import android.hardware.fingerprint.FingerprintManager;
-import android.test.ActivityUnitTestCase;
-import android.view.View;
-import android.widget.Button;
-import android.widget.TextView;
-
-import com.android.settings.R;
-
-import com.google.android.setupcompat.PartnerCustomizationLayout;
-import com.google.android.setupcompat.template.FooterBarMixin;
-
-import org.mockito.Mock;
-import org.mockito.MockitoAnnotations;
-
-import java.util.ArrayList;
-import java.util.List;
-
-public class FingerprintEnrollIntroductionTest
-        extends ActivityUnitTestCase<FingerprintEnrollIntroduction> {
-
-    private TestContext mContext;
-
-    @Mock
-    private FingerprintManager mFingerprintManager;
-
-    private FingerprintEnrollIntroduction mActivity;
-
-    public FingerprintEnrollIntroductionTest() {
-        super(FingerprintEnrollIntroduction.class);
-    }
-
-    @Override
-    protected void setUp() throws Exception {
-        super.setUp();
-        MockitoAnnotations.initMocks(this);
-        mContext = new TestContext(getInstrumentation().getTargetContext());
-        setActivityContext(mContext);
-
-        getInstrumentation().runOnMainSync(() -> {
-            final Intent intent = new Intent();
-            mActivity = startActivity(intent,
-                    null /* savedInstanceState */, null /* lastNonConfigurationInstance */);
-        });
-    }
-
-    public void testMaxFingerprint_shouldShowErrorMessage() {
-        final int max = mContext.getResources().getInteger(
-                com.android.internal.R.integer.config_fingerprintMaxTemplatesPerUser);
-        doReturn(generateFingerprintList(max)).when(mFingerprintManager)
-                .getEnrolledFingerprints(anyInt());
-
-        getInstrumentation().runOnMainSync(() -> {
-            getInstrumentation().callActivityOnCreate(mActivity, null);
-            getInstrumentation().callActivityOnResume(mActivity);
-        });
-
-        final TextView errorTextView = (TextView) mActivity.findViewById(R.id.error_text);
-        assertNotNull(errorTextView.getText().toString());
-
-        PartnerCustomizationLayout layout = mActivity.findViewById(R.id.setup_wizard_layout);
-        final Button nextButton = layout.getMixin(FooterBarMixin.class).getPrimaryButtonView();
-        assertEquals(View.GONE, nextButton.getVisibility());
-    }
-
-    private List<Fingerprint> generateFingerprintList(int num) {
-        ArrayList<Fingerprint> list = new ArrayList<>();
-        for (int i = 0; i < num; i++) {
-            list.add(new Fingerprint("Fingerprint " + i, 0, i, 0));
-        }
-        return list;
-    }
-
-    public class TestContext extends ContextWrapper {
-
-        public TestContext(Context base) {
-            super(base);
-        }
-
-        @Override
-        public Object getSystemService(String name) {
-            if (Context.FINGERPRINT_SERVICE.equals(name)) {
-                return mFingerprintManager;
-            }
-            return super.getSystemService(name);
-        }
-    }
-}
diff --git a/tests/unit/src/com/android/settings/core/PreferenceControllerContractTest.java b/tests/unit/src/com/android/settings/core/PreferenceControllerContractTest.java
deleted file mode 100644
index 2d083f0..0000000
--- a/tests/unit/src/com/android/settings/core/PreferenceControllerContractTest.java
+++ /dev/null
@@ -1,95 +0,0 @@
-/*
- * Copyright (C) 2017 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.settings.core;
-
-import static junit.framework.Assert.fail;
-
-import android.content.Context;
-import android.os.Looper;
-import android.platform.test.annotations.Presubmit;
-import android.util.ArraySet;
-
-import androidx.test.InstrumentationRegistry;
-import androidx.test.filters.MediumTest;
-import androidx.test.runner.AndroidJUnit4;
-
-import com.android.settings.overlay.FeatureFactory;
-import com.android.settings.search.BaseSearchIndexProvider;
-import com.android.settingslib.core.AbstractPreferenceController;
-import com.android.settingslib.search.SearchIndexableData;
-import com.android.settingslib.search.SearchIndexableResources;
-
-import org.junit.Before;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-
-import java.util.List;
-import java.util.Set;
-
-@RunWith(AndroidJUnit4.class)
-@MediumTest
-public class PreferenceControllerContractTest {
-
-    private Context mContext;
-
-    @Before
-    public void setUp() {
-        mContext = InstrumentationRegistry.getTargetContext();
-    }
-
-    @Test
-    @Presubmit
-    public void controllersInSearchShouldImplementPreferenceControllerMixin() {
-        Looper.prepare(); // Required by AutofillLoggingLevelPreferenceController
-        final Set<String> errorClasses = new ArraySet<>();
-
-        final SearchIndexableResources resources =
-                FeatureFactory.getFactory(mContext).getSearchFeatureProvider()
-                        .getSearchIndexableResources();
-        for (SearchIndexableData bundle : resources.getProviderValues()) {
-
-            final BaseSearchIndexProvider provider =
-                    (BaseSearchIndexProvider) bundle.getSearchIndexProvider();
-            if (provider == null) {
-                continue;
-            }
-
-            final List<AbstractPreferenceController> controllers =
-                    provider.getPreferenceControllers(mContext);
-            if (controllers == null) {
-                continue;
-            }
-            for (AbstractPreferenceController controller : controllers) {
-                if (!(controller instanceof PreferenceControllerMixin)
-                        && !(controller instanceof BasePreferenceController)) {
-                    errorClasses.add(controller.getClass().getName());
-                }
-            }
-        }
-
-        if (!errorClasses.isEmpty()) {
-            final StringBuilder errorMessage = new StringBuilder()
-                    .append("Each preference must implement PreferenceControllerMixin ")
-                    .append("or extend BasePreferenceController, ")
-                    .append("the following classes don't:\n");
-            for (String c : errorClasses) {
-                errorMessage.append(c).append("\n");
-            }
-            fail(errorMessage.toString());
-        }
-    }
-}
diff --git a/tests/unit/src/com/android/settings/core/SettingsGatewayTest.java b/tests/unit/src/com/android/settings/core/SettingsGatewayTest.java
deleted file mode 100644
index f879876..0000000
--- a/tests/unit/src/com/android/settings/core/SettingsGatewayTest.java
+++ /dev/null
@@ -1,121 +0,0 @@
-/*
- * Copyright (C) 2017 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.settings.core;
-
-import static android.content.pm.PackageManager.GET_ACTIVITIES;
-import static android.content.pm.PackageManager.GET_META_DATA;
-import static android.content.pm.PackageManager.MATCH_DISABLED_COMPONENTS;
-
-import static com.android.settings.SettingsActivity.META_DATA_KEY_FRAGMENT_CLASS;
-
-import static com.google.common.truth.Truth.assertThat;
-
-import static junit.framework.Assert.fail;
-
-import static org.junit.Assert.assertFalse;
-
-import android.content.ComponentName;
-import android.content.Context;
-import android.content.Intent;
-import android.content.pm.ActivityInfo;
-import android.content.pm.PackageInfo;
-import android.content.pm.PackageManager;
-import android.content.pm.ResolveInfo;
-import android.os.Bundle;
-import android.platform.test.annotations.Presubmit;
-import android.text.TextUtils;
-import android.util.Log;
-
-import androidx.test.InstrumentationRegistry;
-import androidx.test.filters.SmallTest;
-import androidx.test.runner.AndroidJUnit4;
-
-import com.android.settings.core.gateway.SettingsGateway;
-
-import org.junit.Before;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.List;
-
-@SmallTest
-@RunWith(AndroidJUnit4.class)
-public class SettingsGatewayTest {
-
-    private static final String TAG = "SettingsGatewayTest";
-
-    private Context mContext;
-    private PackageManager mPackageManager;
-    private String mPackageName;
-
-    @Before
-    public void setUp() {
-        mContext = InstrumentationRegistry.getTargetContext();
-        mPackageManager = mContext.getPackageManager();
-        mPackageName = mContext.getPackageName();
-    }
-
-    @Test
-    @Presubmit
-    public void allRestrictedActivityMustBeDefinedInManifest() {
-        for (String className : SettingsGateway.SETTINGS_FOR_RESTRICTED) {
-            final Intent intent = new Intent();
-            intent.setComponent(new ComponentName(mPackageName, className));
-            List<ResolveInfo> resolveInfos = mPackageManager.queryIntentActivities(intent,
-                    MATCH_DISABLED_COMPONENTS);
-            Log.d(TAG, mPackageName + "/" + className + "; resolveInfo size: "
-                    + resolveInfos.size());
-            assertFalse(className + " is not-defined in manifest", resolveInfos.isEmpty());
-        }
-    }
-
-    @Test
-    @Presubmit
-    public void publicFragmentMustAppearInSettingsGateway()
-            throws PackageManager.NameNotFoundException {
-        final List<String> allowlistedFragment = new ArrayList<>();
-        final StringBuilder error = new StringBuilder();
-
-        for (String fragment : SettingsGateway.ENTRY_FRAGMENTS) {
-            allowlistedFragment.add(fragment);
-        }
-        final PackageInfo pi = mPackageManager.getPackageInfo(mPackageName,
-                GET_META_DATA | MATCH_DISABLED_COMPONENTS | GET_ACTIVITIES);
-        final List<ActivityInfo> activities = Arrays.asList(pi.activities);
-
-        for (ActivityInfo activity : activities) {
-            final Bundle metaData = activity.metaData;
-            if (metaData == null || !metaData.containsKey(META_DATA_KEY_FRAGMENT_CLASS)) {
-                continue;
-            }
-            final String fragmentName = metaData.getString(META_DATA_KEY_FRAGMENT_CLASS);
-
-            assertThat(fragmentName).isNotNull();
-            if (!allowlistedFragment.contains(fragmentName)) {
-                error.append("SettingsGateway.ENTRY_FRAGMENTS must contain " + fragmentName
-                        + " because this fragment is used in manifest for " + activity.name)
-                        .append("\n");
-            }
-        }
-        final String message = error.toString();
-        if (!TextUtils.isEmpty(message)) {
-            fail(message);
-        }
-    }
-}
diff --git a/tests/unit/src/com/android/settings/core/UniquePreferenceTest.java b/tests/unit/src/com/android/settings/core/UniquePreferenceTest.java
deleted file mode 100644
index ddd00a2..0000000
--- a/tests/unit/src/com/android/settings/core/UniquePreferenceTest.java
+++ /dev/null
@@ -1,219 +0,0 @@
-/*
- * Copyright (C) 2017 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.settings.core;
-
-import static junit.framework.Assert.fail;
-
-import android.content.Context;
-import android.content.res.Resources;
-import android.os.Bundle;
-import android.platform.test.annotations.Presubmit;
-import android.provider.SearchIndexableResource;
-import android.text.TextUtils;
-import android.util.Log;
-
-import androidx.test.InstrumentationRegistry;
-import androidx.test.filters.MediumTest;
-import androidx.test.runner.AndroidJUnit4;
-
-import com.android.settings.core.PreferenceXmlParserUtils.MetadataFlag;
-import com.android.settings.overlay.FeatureFactory;
-import com.android.settingslib.search.Indexable;
-import com.android.settingslib.search.SearchIndexableData;
-import com.android.settingslib.search.SearchIndexableRaw;
-import com.android.settingslib.search.SearchIndexableResources;
-
-import org.junit.Before;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.xmlpull.v1.XmlPullParserException;
-
-import java.io.IOException;
-import java.util.Arrays;
-import java.util.HashSet;
-import java.util.List;
-import java.util.Set;
-
-@RunWith(AndroidJUnit4.class)
-@MediumTest
-public class UniquePreferenceTest {
-
-    private static final String TAG = "UniquePreferenceTest";
-    private static final List<String> IGNORE_PREF_TYPES = Arrays.asList(
-            "com.android.settingslib.widget.FooterPreference");
-
-    private static final List<String> ALLOWLISTED_DUPLICATE_KEYS = Arrays.asList(
-            "owner_info_settings",          // Lock screen message in security - multiple xml files
-                                            // contain this because security page is constructed by
-                                            // combining small xml chunks. Eventually the page
-                                            // should be formed as one single xml and this entry
-                                            // should be removed.
-
-            "dashboard_tile_placeholder",   // This is the placeholder pref for injecting dynamic
-                                            // tiles.
-            // Dup keys from About Phone v2 experiment.
-            "ims_reg_state",
-            "bt_address",
-            "device_model",
-            "firmware_version",
-            "regulatory_info",
-            "manual",
-            "legal_container",
-            "device_feedback",
-            "fcc_equipment_id",
-            "sim_status",
-            "build_number",
-            "phone_number",
-            "imei_info",
-            "wifi_ip_address",
-            "wifi_mac_address",
-            "safety_info",
-            // Dupe keys from data usage v2.
-            "data_usage_screen",
-            "cellular_data_usage",
-            "data_usage_wifi_screen",
-            "status_header",
-            "billing_preference",
-            "data_usage_cellular_screen",
-            "wifi_data_usage",
-            "data_usage_enable"
-    );
-
-    private Context mContext;
-
-    @Before
-    public void setUp() {
-        mContext = InstrumentationRegistry.getTargetContext();
-    }
-
-    /**
-     * All preferences should have their unique key. It's especially important for many parts of
-     * Settings to work properly: we assume pref keys are unique in displaying, search ranking,\
-     * search result suppression, and many other areas.
-     * <p/>
-     * So in this test we are checking preferences participating in search.
-     * <p/>
-     * Note: Preference is not limited to just <Preference/> object. Everything in preference xml
-     * should have a key.
-     */
-    @Test
-    @Presubmit
-    public void allPreferencesShouldHaveUniqueKey()
-            throws IOException, XmlPullParserException, Resources.NotFoundException {
-        final Set<String> uniqueKeys = new HashSet<>();
-        final Set<String> nullKeyClasses = new HashSet<>();
-        final Set<String> duplicatedKeys = new HashSet<>();
-        final SearchIndexableResources resources =
-                FeatureFactory.getFactory(mContext).getSearchFeatureProvider()
-                        .getSearchIndexableResources();
-        for (SearchIndexableData SearchIndexableData : resources.getProviderValues()) {
-            verifyPreferenceKeys(uniqueKeys, duplicatedKeys, nullKeyClasses, SearchIndexableData);
-        }
-
-        if (!nullKeyClasses.isEmpty()) {
-            final StringBuilder nullKeyErrors = new StringBuilder()
-                    .append("Each preference/SearchIndexableData must have a key, ")
-                    .append("the following classes have null keys:\n");
-            for (String c : nullKeyClasses) {
-                nullKeyErrors.append(c).append("\n");
-            }
-            fail(nullKeyErrors.toString());
-        }
-
-        if (!duplicatedKeys.isEmpty()) {
-            final StringBuilder dupeKeysError = new StringBuilder(
-                    "The following keys are not unique\n");
-            for (String c : duplicatedKeys) {
-                dupeKeysError.append(c).append("\n");
-            }
-            fail(dupeKeysError.toString());
-        }
-    }
-
-    private void verifyPreferenceKeys(Set<String> uniqueKeys, Set<String> duplicatedKeys,
-            Set<String> nullKeyClasses, SearchIndexableData searchIndexableData)
-            throws IOException, XmlPullParserException, Resources.NotFoundException {
-
-        final String className = searchIndexableData.getTargetClass().getName();
-        final Indexable.SearchIndexProvider provider =
-                searchIndexableData.getSearchIndexProvider();
-        final List<SearchIndexableRaw> rawsToIndex = provider.getRawDataToIndex(mContext, true);
-        final List<SearchIndexableResource> resourcesToIndex =
-                provider.getXmlResourcesToIndex(mContext, true);
-        verifyResources(className, resourcesToIndex, uniqueKeys, duplicatedKeys, nullKeyClasses);
-        verifyRaws(className, rawsToIndex, uniqueKeys, duplicatedKeys, nullKeyClasses);
-    }
-
-    private void verifyResources(String className, List<SearchIndexableResource> resourcesToIndex,
-            Set<String> uniqueKeys, Set<String> duplicatedKeys, Set<String> nullKeyClasses)
-            throws IOException, XmlPullParserException, Resources.NotFoundException {
-        if (resourcesToIndex == null) {
-            Log.d(TAG, className + "is not providing SearchIndexableResource, skipping");
-            return;
-        }
-
-        for (SearchIndexableResource sir : resourcesToIndex) {
-            final List<Bundle> metadata = PreferenceXmlParserUtils.extractMetadata(mContext,
-                    sir.xmlResId,
-                    MetadataFlag.FLAG_INCLUDE_PREF_SCREEN
-                            | MetadataFlag.FLAG_NEED_KEY
-                            | MetadataFlag.FLAG_NEED_PREF_TYPE);
-
-            for (Bundle bundle : metadata) {
-                final String type = bundle.getString(PreferenceXmlParserUtils.METADATA_PREF_TYPE);
-                if (IGNORE_PREF_TYPES.contains(type)) {
-                    continue;
-                }
-                final String key = bundle.getString(PreferenceXmlParserUtils.METADATA_KEY);
-                if (TextUtils.isEmpty(key)) {
-                    Log.e(TAG, "Every preference must have an key; found null key"
-                            + " in " + className);
-                    nullKeyClasses.add(className);
-                    continue;
-                }
-                if (uniqueKeys.contains(key) && !ALLOWLISTED_DUPLICATE_KEYS.contains(key)) {
-                    Log.e(TAG, "Every preference key must unique; found "
-                            + " in " + className
-                            + " / " + key);
-                    duplicatedKeys.add(key);
-                }
-                uniqueKeys.add(key);
-            }
-        }
-    }
-
-    private void verifyRaws(String className, List<SearchIndexableRaw> rawsToIndex,
-            Set<String> uniqueKeys, Set<String> duplicatedKeys, Set<String> nullKeyClasses) {
-        if (rawsToIndex == null) {
-            Log.d(TAG, className + "is not providing SearchIndexableRaw, skipping");
-            return;
-        }
-        for (SearchIndexableRaw raw : rawsToIndex) {
-            if (TextUtils.isEmpty(raw.key)) {
-                Log.e(TAG, "Every SearchIndexableRaw must have an key; found null key"
-                        + " in " + className);
-                nullKeyClasses.add(className);
-                continue;
-            }
-            if (uniqueKeys.contains(raw.key) && !ALLOWLISTED_DUPLICATE_KEYS.contains(raw.key)) {
-                Log.e(TAG, "Every SearchIndexableRaw key must unique; found " + raw.key
-                        + " in " + className);
-                duplicatedKeys.add(raw.key);
-            }
-        }
-    }
-}
diff --git a/tests/unit/src/com/android/settings/core/UserRestrictionTest.java b/tests/unit/src/com/android/settings/core/UserRestrictionTest.java
deleted file mode 100644
index e8e4927..0000000
--- a/tests/unit/src/com/android/settings/core/UserRestrictionTest.java
+++ /dev/null
@@ -1,157 +0,0 @@
-/*
- * Copyright (C) 2017 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.settings.core;
-
-import static junit.framework.Assert.fail;
-
-import android.content.Context;
-import android.content.res.Resources;
-import android.content.res.TypedArray;
-import android.content.res.XmlResourceParser;
-import android.os.UserManager;
-import android.provider.SearchIndexableResource;
-import android.util.AttributeSet;
-import android.util.Log;
-import android.util.Xml;
-
-import androidx.test.InstrumentationRegistry;
-import androidx.test.filters.MediumTest;
-import androidx.test.runner.AndroidJUnit4;
-
-import com.android.settings.overlay.FeatureFactory;
-import com.android.settingslib.search.Indexable;
-import com.android.settingslib.search.SearchIndexableData;
-import com.android.settingslib.search.SearchIndexableResources;
-
-import com.google.android.collect.Sets;
-
-import org.junit.Before;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.xmlpull.v1.XmlPullParser;
-import org.xmlpull.v1.XmlPullParserException;
-
-import java.io.IOException;
-import java.util.List;
-import java.util.Set;
-
-@RunWith(AndroidJUnit4.class)
-@MediumTest
-public class UserRestrictionTest {
-
-    private static final String TAG = "UserRestrictionTest";
-
-    private Context mContext;
-
-    private static final Set<String> USER_RESTRICTIONS = Sets.newHashSet(
-            UserManager.DISALLOW_CONFIG_DATE_TIME,
-            UserManager.DISALLOW_CONFIG_CREDENTIALS,
-            UserManager.DISALLOW_NETWORK_RESET,
-            UserManager.DISALLOW_FACTORY_RESET,
-            UserManager.DISALLOW_CONFIG_TETHERING,
-            UserManager.DISALLOW_CONFIG_VPN,
-            UserManager.DISALLOW_CONFIG_MOBILE_NETWORKS,
-            UserManager.DISALLOW_AIRPLANE_MODE,
-            UserManager.DISALLOW_CONFIG_BRIGHTNESS,
-            UserManager.DISALLOW_CONFIG_SCREEN_TIMEOUT
-    );
-
-    @Before
-    public void setUp() {
-        mContext = InstrumentationRegistry.getTargetContext();
-    }
-
-    /**
-     * Verity that userRestriction attributes are entered and parsed successfully.
-     */
-    @Test
-    public void userRestrictionAttributeShouldBeValid()
-            throws IOException, XmlPullParserException, Resources.NotFoundException {
-        final SearchIndexableResources resources =
-                FeatureFactory.getFactory(mContext).getSearchFeatureProvider()
-                        .getSearchIndexableResources();
-        for (SearchIndexableData bundle : resources.getProviderValues()) {
-            verifyUserRestriction(bundle);
-        }
-    }
-
-    private void verifyUserRestriction(SearchIndexableData searchIndexableData)
-            throws IOException, XmlPullParserException, Resources.NotFoundException {
-
-        final Indexable.SearchIndexProvider provider =
-                searchIndexableData.getSearchIndexProvider();
-        final List<SearchIndexableResource> resourcesToIndex =
-                provider.getXmlResourcesToIndex(mContext, true);
-
-        final String className = searchIndexableData.getTargetClass().getName();
-
-        if (resourcesToIndex == null) {
-            Log.d(TAG, className + "is not providing SearchIndexableResource, skipping");
-            return;
-        }
-
-        for (SearchIndexableResource sir : resourcesToIndex) {
-            if (sir.xmlResId <= 0) {
-                Log.d(TAG, className + " doesn't have a valid xml to index.");
-                continue;
-            }
-            final XmlResourceParser parser = mContext.getResources().getXml(sir.xmlResId);
-
-            int type;
-            while ((type = parser.next()) != XmlPullParser.END_DOCUMENT
-                    && type != XmlPullParser.START_TAG) {
-                // Parse next until start tag is found
-            }
-            final int outerDepth = parser.getDepth();
-
-            do {
-                if (type != XmlPullParser.START_TAG) {
-                    continue;
-                }
-                final String nodeName = parser.getName();
-                if (!nodeName.endsWith("Preference")) {
-                    continue;
-                }
-                final AttributeSet attrs = Xml.asAttributeSet(parser);
-                final String userRestriction = getDataUserRestrictions(mContext, attrs);
-                if (userRestriction != null) {
-                    if(!isValidRestriction(userRestriction)) {
-                        fail("userRestriction in " + className + " not valid.");
-                    }
-                }
-            } while ((type = parser.next()) != XmlPullParser.END_DOCUMENT
-                    && (type != XmlPullParser.END_TAG || parser.getDepth() > outerDepth));
-        }
-    }
-
-    boolean isValidRestriction(String userRestriction) {
-        return USER_RESTRICTIONS.contains(userRestriction);
-    }
-
-    private String getDataUserRestrictions(Context context, AttributeSet attrs) {
-        return getData(context, attrs,
-                com.android.settingslib.R.styleable.RestrictedPreference,
-                com.android.settingslib.R.styleable.RestrictedPreference_userRestriction);
-    }
-
-    private String getData(Context context, AttributeSet set, int[] attrs, int resId) {
-        final TypedArray ta = context.obtainStyledAttributes(set, attrs);
-        String data = ta.getString(resId);
-        ta.recycle();
-        return data;
-    }
-}
diff --git a/tests/unit/src/com/android/settings/development/BluetoothMaxConnectedAudioDevicesPreferenceControllerInstrumentationTest.java b/tests/unit/src/com/android/settings/development/BluetoothMaxConnectedAudioDevicesPreferenceControllerInstrumentationTest.java
deleted file mode 100644
index dbb73c0..0000000
--- a/tests/unit/src/com/android/settings/development/BluetoothMaxConnectedAudioDevicesPreferenceControllerInstrumentationTest.java
+++ /dev/null
@@ -1,65 +0,0 @@
-/*
- * Copyright (C) 2018 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.settings.development;
-
-import android.content.Context;
-
-import androidx.test.InstrumentationRegistry;
-import androidx.test.filters.SmallTest;
-import androidx.test.runner.AndroidJUnit4;
-
-import com.android.settings.R;
-
-import org.hamcrest.CoreMatchers;
-import org.junit.Assert;
-import org.junit.Before;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-
-import java.util.Arrays;
-
-@RunWith(AndroidJUnit4.class)
-@SmallTest
-public class BluetoothMaxConnectedAudioDevicesPreferenceControllerInstrumentationTest {
-
-    private Context mTargetContext;
-    private String[] mListValues;
-    private String[] mListEntries;
-    private String mDefaultMaxConnectedAudioDevices;
-
-    @Before
-    public void setUp() throws Exception {
-        mTargetContext = InstrumentationRegistry.getTargetContext();
-        // Get XML values without mock
-        mListValues = mTargetContext.getResources()
-                .getStringArray(R.array.bluetooth_max_connected_audio_devices_values);
-        mListEntries = mTargetContext.getResources()
-                .getStringArray(R.array.bluetooth_max_connected_audio_devices);
-        mDefaultMaxConnectedAudioDevices = String.valueOf(mTargetContext.getResources()
-                .getInteger(
-                        com.android.internal.R.integer
-                                .config_bluetooth_max_connected_audio_devices));
-    }
-
-    @Test
-    public void verifyResource() {
-        // Verify normal list entries and default preference entries have the same size
-        Assert.assertEquals(mListEntries.length, mListValues.length);
-        Assert.assertThat(Arrays.asList(mListValues),
-                CoreMatchers.hasItem(mDefaultMaxConnectedAudioDevices));
-    }
-}
diff --git a/tests/unit/src/com/android/settings/fuelgauge/batterytip/RestrictAppTest.java b/tests/unit/src/com/android/settings/fuelgauge/batterytip/RestrictAppTest.java
deleted file mode 100644
index 355a7e4..0000000
--- a/tests/unit/src/com/android/settings/fuelgauge/batterytip/RestrictAppTest.java
+++ /dev/null
@@ -1,126 +0,0 @@
-/*
- * Copyright (C) 2018 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.settings.fuelgauge.batterytip;
-
-import static androidx.test.espresso.Espresso.onView;
-import static androidx.test.espresso.assertion.ViewAssertions.matches;
-import static androidx.test.espresso.matcher.ViewMatchers.isDisplayed;
-import static androidx.test.espresso.matcher.ViewMatchers.withText;
-
-import static com.google.common.truth.Truth.assertThat;
-
-import android.app.Instrumentation;
-import android.content.Context;
-import android.content.Intent;
-import android.content.pm.PackageManager;
-import android.support.test.uiautomator.UiDevice;
-
-import androidx.test.InstrumentationRegistry;
-import androidx.test.filters.SmallTest;
-import androidx.test.runner.AndroidJUnit4;
-
-import org.junit.Before;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-
-import java.util.List;
-import java.util.concurrent.TimeUnit;
-
-@RunWith(AndroidJUnit4.class)
-@SmallTest
-public class RestrictAppTest {
-    private static final String WM_DISMISS_KEYGUARD_COMMAND = "wm dismiss-keyguard";
-    private static final String BATTERY_INTENT = "android.intent.action.POWER_USAGE_SUMMARY";
-    private static final String PACKAGE_SETTINGS = "com.android.settings";
-    private static final String PACKAGE_SYSTEM_UI = "com.android.systemui";
-    private static final int ANOMALY_TYPE =
-            StatsManagerConfig.AnomalyType.EXCESSIVE_WAKELOCK_ALL_SCREEN_OFF;
-
-    private BatteryDatabaseManager mBatteryDatabaseManager;
-    private PackageManager mPackageManager;
-    private UiDevice mUiDevice;
-
-    @Before
-    public void setUp() throws Exception {
-        final Context context = InstrumentationRegistry.getTargetContext();
-
-        mUiDevice = UiDevice.getInstance(InstrumentationRegistry.getInstrumentation());
-        mUiDevice.wakeUp();
-        mUiDevice.executeShellCommand(WM_DISMISS_KEYGUARD_COMMAND);
-
-        mPackageManager = context.getPackageManager();
-        mBatteryDatabaseManager = BatteryDatabaseManager.getInstance(context);
-        mBatteryDatabaseManager.deleteAllAnomaliesBeforeTimeStamp(System.currentTimeMillis() +
-                TimeUnit.DAYS.toMillis(1));
-    }
-
-    @Test
-    public void batterySettings_hasOneAnomaly_showAnomaly() throws
-            PackageManager.NameNotFoundException {
-        mBatteryDatabaseManager.insertAnomaly(mPackageManager.getPackageUid(PACKAGE_SETTINGS, 0),
-                PACKAGE_SETTINGS, ANOMALY_TYPE,
-                AnomalyDatabaseHelper.State.NEW, System.currentTimeMillis());
-
-        Instrumentation instrumentation = InstrumentationRegistry.getInstrumentation();
-        instrumentation.startActivitySync(createBatteryIntent());
-        onView(withText("Restrict 1 app")).check(matches(isDisplayed()));
-    }
-
-    @Test
-    public void batterySettings_hasTwoAnomalies_showAnomalies() throws
-            PackageManager.NameNotFoundException {
-        mBatteryDatabaseManager.insertAnomaly(mPackageManager.getPackageUid(PACKAGE_SETTINGS, 0),
-                PACKAGE_SETTINGS, ANOMALY_TYPE,
-                AnomalyDatabaseHelper.State.NEW, System.currentTimeMillis());
-        mBatteryDatabaseManager.insertAnomaly(mPackageManager.getPackageUid(PACKAGE_SYSTEM_UI, 0),
-                PACKAGE_SYSTEM_UI, ANOMALY_TYPE,
-                AnomalyDatabaseHelper.State.NEW, System.currentTimeMillis());
-
-        Instrumentation instrumentation = InstrumentationRegistry.getInstrumentation();
-        instrumentation.startActivitySync(createBatteryIntent());
-        onView(withText("Restrict 2 apps")).check(matches(isDisplayed()));
-    }
-
-    @Test
-    public void insertDuplicateAnomalies_onlyInsertOnce() throws
-            PackageManager.NameNotFoundException {
-        final int uid = mPackageManager.getPackageUid(PACKAGE_SETTINGS, 0);
-        final long now = System.currentTimeMillis();
-
-        // Insert same anomaly twice, it fails at the second time.
-        assertThat(mBatteryDatabaseManager.insertAnomaly(uid, PACKAGE_SETTINGS, ANOMALY_TYPE,
-                AnomalyDatabaseHelper.State.NEW, now)).isTrue();
-        assertThat(mBatteryDatabaseManager.insertAnomaly(uid, PACKAGE_SETTINGS, ANOMALY_TYPE,
-                AnomalyDatabaseHelper.State.NEW, now)).isFalse();
-
-        // In database, only contains one row
-        List<AppInfo> newAppInfos = mBatteryDatabaseManager.queryAllAnomalies(0,
-                AnomalyDatabaseHelper.State.NEW);
-        assertThat(newAppInfos).containsExactly(new AppInfo.Builder()
-                .setUid(uid)
-                .setPackageName(PACKAGE_SETTINGS)
-                .addAnomalyType(ANOMALY_TYPE)
-                .build());
-    }
-
-    private Intent createBatteryIntent() {
-        final Intent intent = new Intent(BATTERY_INTENT);
-        intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
-
-        return intent;
-    }
-}
diff --git a/tests/unit/src/com/android/settings/network/MobileDataEnabledListenerTest.java b/tests/unit/src/com/android/settings/network/MobileDataEnabledListenerTest.java
deleted file mode 100644
index 190dc3d..0000000
--- a/tests/unit/src/com/android/settings/network/MobileDataEnabledListenerTest.java
+++ /dev/null
@@ -1,85 +0,0 @@
-/*
- * Copyright (C) 2020 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.network;
-
-import static org.mockito.Mockito.never;
-import static org.mockito.Mockito.verify;
-
-import android.content.Context;
-import android.net.Uri;
-import android.provider.Settings;
-
-import androidx.test.core.app.ApplicationProvider;
-import androidx.test.ext.junit.runners.AndroidJUnit4;
-
-import org.junit.Before;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.mockito.Mock;
-import org.mockito.MockitoAnnotations;
-
-@RunWith(AndroidJUnit4.class)
-public class MobileDataEnabledListenerTest {
-    private static final int SUB_ID_ONE = 111;
-    private static final int SUB_ID_TWO = 222;
-
-    @Mock
-    private MobileDataEnabledListener.Client mClient;
-
-    private Context mContext;
-    private MobileDataEnabledListener mListener;
-
-    @Before
-    public void setUp() {
-        MockitoAnnotations.initMocks(this);
-        mContext = ApplicationProvider.getApplicationContext();
-        mListener = new MobileDataEnabledListener(mContext, mClient);
-    }
-
-    @Test
-    public void onMobileDataEnabledChange_firesCorrectly() {
-        mListener.start(SUB_ID_ONE);
-        final Uri uri = Settings.Global.getUriFor(Settings.Global.MOBILE_DATA + SUB_ID_ONE);
-
-        mContext.getContentResolver().notifyChange(uri, null);
-
-        verify(mClient).onMobileDataEnabledChange();
-    }
-
-    @Test
-    public void onMobileDataEnabledChange_doesNotFireAfterStop() {
-        mListener.start(SUB_ID_ONE);
-        mListener.stop();
-        final Uri uri = Settings.Global.getUriFor(Settings.Global.MOBILE_DATA + SUB_ID_ONE);
-
-        mContext.getContentResolver().notifyChange(uri, null);
-
-        verify(mClient, never()).onMobileDataEnabledChange();
-    }
-
-    @Test
-    public void onMobileDataEnabledChange_changedToDifferentId_firesCorrectly() {
-        mListener.start(SUB_ID_ONE);
-        mListener.stop();
-        mListener.start(SUB_ID_TWO);
-        final Uri uri = Settings.Global.getUriFor(Settings.Global.MOBILE_DATA + SUB_ID_TWO);
-
-        mContext.getContentResolver().notifyChange(uri, null);
-
-        verify(mClient).onMobileDataEnabledChange();
-    }
-}
diff --git a/tests/unit/src/com/android/settings/network/TetherProvisioningActivityTest.java b/tests/unit/src/com/android/settings/network/TetherProvisioningActivityTest.java
deleted file mode 100644
index af29dcc..0000000
--- a/tests/unit/src/com/android/settings/network/TetherProvisioningActivityTest.java
+++ /dev/null
@@ -1,126 +0,0 @@
-/*
- * Copyright (C) 2020 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.network;
-
-import static android.net.TetheringConstants.EXTRA_ADD_TETHER_TYPE;
-import static android.net.TetheringConstants.EXTRA_PROVISION_CALLBACK;
-import static android.net.TetheringManager.TETHERING_WIFI;
-
-import static com.android.settings.network.TetherProvisioningActivity.EXTRA_TETHER_SUBID;
-import static com.android.settings.network.TetherProvisioningActivity.EXTRA_TETHER_UI_PROVISIONING_APP_NAME;
-import static com.android.settings.network.TetherProvisioningActivity.PROVISION_REQUEST;
-
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertFalse;
-import static org.junit.Assert.assertTrue;
-import static org.junit.Assert.fail;
-
-import android.app.Activity;
-import android.content.Intent;
-import android.net.TetheringManager;
-import android.os.Bundle;
-import android.os.ResultReceiver;
-import android.provider.Settings;
-import android.telephony.SubscriptionManager;
-
-import androidx.lifecycle.Lifecycle;
-import androidx.test.core.app.ActivityScenario;
-import androidx.test.runner.AndroidJUnit4;
-
-import org.junit.Test;
-import org.junit.runner.RunWith;
-
-import java.util.concurrent.CompletableFuture;
-import java.util.concurrent.TimeUnit;
-
-@RunWith(AndroidJUnit4.class)
-public class TetherProvisioningActivityTest {
-    private static class WrappedReceiver extends ResultReceiver {
-        private final CompletableFuture<Integer> mFuture = new CompletableFuture<>();
-
-        WrappedReceiver() {
-            super(null /* handler */);
-        }
-
-        @Override
-        protected void onReceiveResult(int resultCode, Bundle resultData) {
-            mFuture.complete(resultCode);
-        }
-
-        public int get() throws Exception {
-            return mFuture.get(10_000L, TimeUnit.MILLISECONDS);
-        }
-    }
-
-    @Test
-    public void testOnCreate_FinishWithNonActiveDataSubId() throws Exception {
-        final WrappedReceiver receiver = new WrappedReceiver();
-        try (ActivityScenario<TetherProvisioningActivity> scenario = ActivityScenario.launch(
-                new Intent(Settings.ACTION_TETHER_PROVISIONING_UI)
-                        .putExtra(EXTRA_ADD_TETHER_TYPE, TETHERING_WIFI)
-                        .putExtra(EXTRA_PROVISION_CALLBACK, receiver)
-                        .putExtra(TetherProvisioningActivity.EXTRA_TETHER_SUBID, 10000))) {
-            assertEquals(TetheringManager.TETHER_ERROR_PROVISIONING_FAILED, receiver.get());
-            assertEquals(Lifecycle.State.DESTROYED, scenario.getState());
-        }
-    }
-
-    @Test
-    public void testOnCreate_FinishWithUnavailableProvisioningApp() throws Exception {
-        final WrappedReceiver receiver = new WrappedReceiver();
-        final int subId = SubscriptionManager.getActiveDataSubscriptionId();
-        final String[] emptyProvisioningApp = { "", "" };
-        try (ActivityScenario<TetherProvisioningActivity> scenario = ActivityScenario.launch(
-                new Intent(Settings.ACTION_TETHER_PROVISIONING_UI)
-                        .putExtra(EXTRA_ADD_TETHER_TYPE, TETHERING_WIFI)
-                        .putExtra(EXTRA_PROVISION_CALLBACK, receiver)
-                        .putExtra(EXTRA_TETHER_SUBID, subId)
-                        .putExtra(EXTRA_TETHER_UI_PROVISIONING_APP_NAME, emptyProvisioningApp))) {
-            assertEquals(TetheringManager.TETHER_ERROR_PROVISIONING_FAILED, receiver.get());
-            assertEquals(Lifecycle.State.DESTROYED, scenario.getState());
-        }
-    }
-
-    @Test
-    public void testOnCreate_startActivityForResult() {
-        final WrappedReceiver receiver = new WrappedReceiver();
-        final int subId = SubscriptionManager.getActiveDataSubscriptionId();
-        final String[] provisionApp = new String[] {
-                "android.test.entitlement",
-                "android.test.entitlement.InstrumentedEntitlementActivity"
-        };
-        try (ActivityScenario<TetherProvisioningActivity> scenario = ActivityScenario.launch(
-                new Intent(Settings.ACTION_TETHER_PROVISIONING_UI)
-                        .putExtra(EXTRA_ADD_TETHER_TYPE, TETHERING_WIFI)
-                        .putExtra(EXTRA_PROVISION_CALLBACK, receiver)
-                        .putExtra(EXTRA_TETHER_SUBID, subId)
-                        .putExtra(EXTRA_TETHER_UI_PROVISIONING_APP_NAME, provisionApp))) {
-            scenario.onActivity(activity -> {
-                assertFalse(activity.isFinishing());
-                activity.onActivityResult(PROVISION_REQUEST, Activity.RESULT_OK, null /* intent */);
-                try {
-                    assertEquals(TetheringManager.TETHER_ERROR_NO_ERROR, receiver.get());
-                } catch (Exception e) {
-                    // ActivityAction#perform() doesn't throw the exception. Just catch the
-                    // exception and call fail() here.
-                    fail("Can not get result after 10s.");
-                }
-                assertTrue(activity.isFinishing());
-            });
-        }
-    }
-}
diff --git a/tests/unit/src/com/android/settings/network/telephony/NetworkSelectSettingsTest.java b/tests/unit/src/com/android/settings/network/telephony/NetworkSelectSettingsTest.java
deleted file mode 100644
index 3256aba..0000000
--- a/tests/unit/src/com/android/settings/network/telephony/NetworkSelectSettingsTest.java
+++ /dev/null
@@ -1,122 +0,0 @@
-/*
- * Copyright (C) 2020 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.network.telephony;
-
-import static com.google.common.truth.Truth.assertThat;
-
-import static org.mockito.Mockito.doReturn;
-import static org.mockito.Mockito.spy;
-import static org.mockito.Mockito.when;
-
-import android.content.Context;
-import android.content.SharedPreferences;
-import android.telephony.CellIdentityLte;
-import android.telephony.CellIdentityWcdma;
-import android.telephony.CellInfoLte;
-import android.telephony.CellInfoWcdma;
-import android.telephony.SubscriptionManager;
-import android.telephony.TelephonyManager;
-
-import androidx.preference.PreferenceCategory;
-import androidx.preference.PreferenceManager;
-import androidx.test.annotation.UiThreadTest;
-import androidx.test.core.app.ApplicationProvider;
-import androidx.test.ext.junit.runners.AndroidJUnit4;
-
-import org.junit.Before;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.mockito.Mock;
-import org.mockito.MockitoAnnotations;
-
-import java.util.Arrays;
-
-@RunWith(AndroidJUnit4.class)
-public class NetworkSelectSettingsTest {
-    private static final int SUB_ID = 2;
-    private static final String CARRIER_NAME1 = "CarrierName1";
-    private static final String CARRIER_NAME2 = "CarrierName2";
-
-    @Mock
-    private TelephonyManager mTelephonyManager;
-    @Mock
-    private SubscriptionManager mSubscriptionManager;
-    @Mock
-    private PreferenceManager mPreferenceManager;
-    @Mock
-    private SharedPreferences mSharedPreferences;
-
-    private CellInfoWcdma mCellInfo1 = new CellInfoWcdma();
-    private CellIdentityWcdma mCellId1 = new CellIdentityWcdma();
-    private CellInfoLte mCellInfo2 = new CellInfoLte();
-    private CellIdentityLte mCellId2 = new CellIdentityLte();
-
-    private Context mContext;
-
-    private PreferenceCategory mPreferenceCategory;
-
-    private NetworkSelectSettings mNetworkSelectSettings;
-
-    @Before
-    @UiThreadTest
-    public void setUp() {
-        MockitoAnnotations.initMocks(this);
-
-        mContext = spy(ApplicationProvider.getApplicationContext());
-        when(mContext.getSystemService(Context.TELEPHONY_SERVICE)).thenReturn(mTelephonyManager);
-        when(mContext.getSystemService(SubscriptionManager.class)).thenReturn(mSubscriptionManager);
-        when(mTelephonyManager.createForSubscriptionId(SUB_ID)).thenReturn(mTelephonyManager);
-
-        mCellInfo1.setRegistered(true);
-        mCellInfo1.setCellIdentity(mCellId1);
-        mCellId1.setOperatorAlphaLong(CARRIER_NAME1);
-        mCellInfo2.setRegistered(false);
-        mCellInfo2.setCellIdentity(mCellId2);
-        mCellId2.setOperatorAlphaLong(CARRIER_NAME2);
-
-        doReturn(mSharedPreferences).when(mPreferenceManager).getSharedPreferences();
-        mPreferenceCategory = spy(new PreferenceCategory(mContext));
-        doReturn(mPreferenceManager).when(mPreferenceCategory).getPreferenceManager();
-
-        mNetworkSelectSettings = spy(new NetworkSelectSettings());
-        doReturn(mContext).when(mNetworkSelectSettings).getContext();
-        doReturn(mPreferenceManager).when(mNetworkSelectSettings).getPreferenceManager();
-        doReturn(mContext).when(mPreferenceManager).getContext();
-
-        mNetworkSelectSettings.mTelephonyManager = mTelephonyManager;
-        mNetworkSelectSettings.mPreferenceCategory = mPreferenceCategory;
-        mNetworkSelectSettings.mCellInfoList = Arrays.asList(mCellInfo1, mCellInfo2);
-    }
-
-    @Test
-    public void updateAllPreferenceCategory_correctOrderingPreference() {
-        mNetworkSelectSettings.updateAllPreferenceCategory();
-
-        assertThat(mPreferenceCategory.getPreferenceCount()).isEqualTo(2);
-        final NetworkOperatorPreference preference =
-                (NetworkOperatorPreference) mPreferenceCategory.getPreference(1);
-        assertThat(preference.getOperatorName()).isEqualTo(mCellId2.getOperatorAlphaLong());
-    }
-
-    @Test
-    public void updateForbiddenPlmns_forbiddenPlmnsNull_shouldNotCrash() {
-        when(mTelephonyManager.getForbiddenPlmns()).thenReturn(null);
-
-        // Should not Crash
-        mNetworkSelectSettings.updateForbiddenPlmns();
-    }
-}
diff --git a/tests/unit/src/com/android/settings/notification/AppNotificationSettingsTest.java b/tests/unit/src/com/android/settings/notification/AppNotificationSettingsTest.java
deleted file mode 100644
index 19b1360..0000000
--- a/tests/unit/src/com/android/settings/notification/AppNotificationSettingsTest.java
+++ /dev/null
@@ -1,154 +0,0 @@
-/*
- * Copyright (C) 2017 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.settings.notification;
-
-import static android.app.NotificationManager.IMPORTANCE_DEFAULT;
-
-import static androidx.test.espresso.Espresso.onView;
-import static androidx.test.espresso.action.ViewActions.click;
-import static androidx.test.espresso.assertion.ViewAssertions.doesNotExist;
-import static androidx.test.espresso.assertion.ViewAssertions.matches;
-import static androidx.test.espresso.intent.Intents.intended;
-import static androidx.test.espresso.intent.matcher.IntentMatchers.hasExtra;
-import static androidx.test.espresso.matcher.ViewMatchers.isDisplayed;
-import static androidx.test.espresso.matcher.ViewMatchers.withEffectiveVisibility;
-import static androidx.test.espresso.matcher.ViewMatchers.withId;
-import static androidx.test.espresso.matcher.ViewMatchers.withText;
-
-import static com.android.settings.SettingsActivity.EXTRA_SHOW_FRAGMENT;
-
-import static org.hamcrest.Matchers.allOf;
-import static org.junit.Assert.fail;
-
-import android.app.Instrumentation;
-import android.app.NotificationChannel;
-import android.app.NotificationChannelGroup;
-import android.app.NotificationManager;
-import android.content.Context;
-import android.content.Intent;
-import android.provider.Settings;
-import android.support.test.uiautomator.UiDevice;
-
-import androidx.test.InstrumentationRegistry;
-import androidx.test.espresso.intent.Intents;
-import androidx.test.espresso.matcher.ViewMatchers;
-import androidx.test.filters.SmallTest;
-import androidx.test.runner.AndroidJUnit4;
-
-import org.junit.Before;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-
-@RunWith(AndroidJUnit4.class)
-@SmallTest
-public class AppNotificationSettingsTest {
-    private static final String WM_DISMISS_KEYGUARD_COMMAND = "wm dismiss-keyguard";
-
-    private UiDevice mUiDevice;
-    private Context mTargetContext;
-    private Instrumentation mInstrumentation;
-
-    NotificationManager mNm;
-    private NotificationChannelGroup mGroup1;
-    private NotificationChannel mGroup1Channel1;
-    private NotificationChannel mGroup1Channel2;
-    private NotificationChannelGroup mGroup2;
-    private NotificationChannel mGroup2Channel1;
-    private NotificationChannel mUngroupedChannel;
-
-    @Before
-    public void setUp() throws Exception {
-        mInstrumentation = InstrumentationRegistry.getInstrumentation();
-        mTargetContext = mInstrumentation.getTargetContext();
-
-        mUiDevice = UiDevice.getInstance(InstrumentationRegistry.getInstrumentation());
-        mUiDevice.wakeUp();
-        mUiDevice.executeShellCommand(WM_DISMISS_KEYGUARD_COMMAND);
-
-        mNm  = (NotificationManager) mTargetContext.getSystemService(Context.NOTIFICATION_SERVICE);
-
-        mGroup1 = new NotificationChannelGroup(this.getClass().getName() + "1", "group1");
-        mGroup2 = new NotificationChannelGroup(this.getClass().getName() + "2", "group2");
-        mNm.createNotificationChannelGroup(mGroup1);
-        mNm.createNotificationChannelGroup(mGroup2);
-
-        mGroup1Channel1 = createChannel(mGroup1, this.getClass().getName()+ "c1-1");
-        mGroup1Channel2 = createChannel(mGroup1, this.getClass().getName()+ "c1-2");
-        mGroup2Channel1 = createChannel(mGroup2, this.getClass().getName()+ "c2-1");
-        mUngroupedChannel = createChannel(null, this.getClass().getName()+ "c");
-    }
-
-    @Test
-    public void launchNotificationSetting_shouldNotHaveAppInfoLink() {
-        final Intent intent = new Intent(Settings.ACTION_APP_NOTIFICATION_SETTINGS)
-                .putExtra(Settings.EXTRA_APP_PACKAGE, mTargetContext.getPackageName())
-                .addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
-
-        mInstrumentation.startActivitySync(intent);
-
-        onView(allOf(withId(android.R.id.button1),
-                withEffectiveVisibility(ViewMatchers.Visibility.VISIBLE)))
-                .check(doesNotExist());
-    }
-
-    @Test
-    public void launchNotificationSetting_showGroupsWithMultipleChannels() {
-        final Intent intent = new Intent(Settings.ACTION_APP_NOTIFICATION_SETTINGS)
-                .putExtra(Settings.EXTRA_APP_PACKAGE, mTargetContext.getPackageName())
-                .addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
-        mInstrumentation.startActivitySync(intent);
-        onView(allOf(withText(mGroup1.getName().toString()))).check(
-                matches(isDisplayed()));
-        onView(allOf(withText(mGroup1Channel1.getName().toString()))).check(
-                matches(isDisplayed()));
-        onView(allOf(withText(mGroup1Channel2.getName().toString()))).check(
-                matches(isDisplayed()));
-    }
-
-    @Test
-    public void launchNotificationSetting_showUngroupedChannels() {
-        final Intent intent = new Intent(Settings.ACTION_APP_NOTIFICATION_SETTINGS)
-                .putExtra(Settings.EXTRA_APP_PACKAGE, mTargetContext.getPackageName())
-                .addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
-        mInstrumentation.startActivitySync(intent);
-        onView(allOf(withText(mUngroupedChannel.getName().toString())))
-                .check(matches(isDisplayed()));
-    }
-
-    @Test
-    public void launchNotificationSetting_showGroupsWithOneChannel() {
-        final Intent intent = new Intent(Settings.ACTION_APP_NOTIFICATION_SETTINGS)
-                .putExtra(Settings.EXTRA_APP_PACKAGE, mTargetContext.getPackageName())
-                .addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
-        mInstrumentation.startActivitySync(intent);
-
-        onView(allOf(withText(mGroup2.getName().toString())))
-                .check(matches(isDisplayed()));
-        onView(allOf(withText(mGroup2Channel1.getName().toString())))
-                .check(matches(isDisplayed()));
-    }
-
-    private NotificationChannel createChannel(NotificationChannelGroup group,
-            String id) {
-        NotificationChannel channel = new NotificationChannel(id, id, IMPORTANCE_DEFAULT);
-        if (group != null) {
-            channel.setGroup(group.getId());
-        }
-        mNm.createNotificationChannel(channel);
-        return channel;
-    }
-}
diff --git a/tests/unit/src/com/android/settings/notification/ZenModeSettingsIntegrationTest.java b/tests/unit/src/com/android/settings/notification/ZenModeSettingsIntegrationTest.java
deleted file mode 100644
index 4120a07..0000000
--- a/tests/unit/src/com/android/settings/notification/ZenModeSettingsIntegrationTest.java
+++ /dev/null
@@ -1,85 +0,0 @@
-package com.android.settings;
-
-import static androidx.test.espresso.Espresso.onView;
-import static androidx.test.espresso.assertion.ViewAssertions.matches;
-import static androidx.test.espresso.matcher.ViewMatchers.isDisplayed;
-import static androidx.test.espresso.matcher.ViewMatchers.withText;
-
-import android.content.Context;
-import android.content.Intent;
-import android.provider.Settings;
-import android.support.test.uiautomator.UiDevice;
-
-import androidx.test.InstrumentationRegistry;
-import androidx.test.filters.LargeTest;
-import androidx.test.runner.AndroidJUnit4;
-
-import org.junit.Before;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-
-@RunWith(AndroidJUnit4.class)
-@LargeTest
-public class ZenModeSettingsIntegrationTest {
-    private static final String WM_DISMISS_KEYGUARD_COMMAND = "wm dismiss-keyguard";
-
-    private Context mContext;
-    private UiDevice mUiDevice;
-
-    @Before
-    public void setUp() throws Exception {
-        mContext = InstrumentationRegistry.getTargetContext();
-        mUiDevice = UiDevice.getInstance(InstrumentationRegistry.getInstrumentation());
-        mUiDevice.wakeUp();
-        mUiDevice.executeShellCommand(WM_DISMISS_KEYGUARD_COMMAND);
-    }
-
-    @Test
-    public void testZenModeSettingsPreferences() {
-        launchZenSettings();
-        onView(withText("Calls")).check(matches(isDisplayed()));
-        onView(withText("SMS, MMS, and messaging apps")).check(matches(isDisplayed()));
-        onView(withText("Restrict notifications")).check(matches(isDisplayed()));
-        onView(withText("Duration")).check(matches(isDisplayed()));
-        onView(withText("Schedules")).check(matches(isDisplayed()));
-    }
-
-    @Test
-    public void testZenModeBehaviorPreferences() {
-        launchZenBehaviorSettings();
-        onView(withText("Calls")).check(matches(isDisplayed()));
-        onView(withText("SMS, MMS, and messaging apps")).check(matches(isDisplayed()));
-        onView(withText("Restrict notifications")).check(matches(isDisplayed()));
-        onView(withText("Duration")).check(matches(isDisplayed()));
-        onView(withText("Schedules")).check(matches(isDisplayed()));
-    }
-
-    @Test
-    public void testZenModeAutomationPreferences() {
-        launchZenAutomationSettings();
-        onView(withText("Sleeping")).check(matches(isDisplayed()));
-        onView(withText("Event")).check(matches(isDisplayed()));
-        onView(withText("Add more")).check(matches(isDisplayed()));
-    }
-
-    private void launchZenSettings() {
-        Intent settingsIntent = new Intent(Settings.ACTION_ZEN_MODE_SETTINGS)
-                .setPackage(mContext.getPackageName())
-                .addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
-        mContext.startActivity(settingsIntent);
-    }
-
-    private void launchZenAutomationSettings() {
-        Intent settingsIntent = new Intent(Settings.ACTION_ZEN_MODE_AUTOMATION_SETTINGS)
-                .setPackage(mContext.getPackageName())
-                .addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
-        mContext.startActivity(settingsIntent);
-    }
-
-    private void launchZenBehaviorSettings() {
-        Intent settingsIntent = new Intent(Settings.ACTION_ZEN_MODE_PRIORITY_SETTINGS)
-                .setPackage(mContext.getPackageName())
-                .addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
-        mContext.startActivity(settingsIntent);
-    }
-}
\ No newline at end of file
diff --git a/tests/unit/src/com/android/settings/password/ChooseLockGenericTest.java b/tests/unit/src/com/android/settings/password/ChooseLockGenericTest.java
deleted file mode 100644
index 4b539cc..0000000
--- a/tests/unit/src/com/android/settings/password/ChooseLockGenericTest.java
+++ /dev/null
@@ -1,240 +0,0 @@
-/*
- * Copyright (C) 2017 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.settings.password;
-
-import static androidx.test.InstrumentationRegistry.getInstrumentation;
-import static androidx.test.InstrumentationRegistry.getTargetContext;
-
-import static com.google.common.truth.Truth.assertThat;
-
-import static org.junit.Assert.assertTrue;
-
-import android.app.Activity;
-import android.app.ActivityManager;
-import android.app.ActivityManager.AppTask;
-import android.app.KeyguardManager;
-import android.app.admin.DevicePolicyManager;
-import android.content.Context;
-import android.content.Intent;
-import android.support.test.uiautomator.UiDevice;
-import android.support.test.uiautomator.UiObject;
-import android.support.test.uiautomator.UiSelector;
-import android.text.format.DateUtils;
-import android.view.WindowManager;
-
-import androidx.test.filters.MediumTest;
-import androidx.test.rule.ActivityTestRule;
-import androidx.test.runner.AndroidJUnit4;
-import androidx.test.runner.lifecycle.ActivityLifecycleMonitorRegistry;
-import androidx.test.runner.lifecycle.Stage;
-
-import com.android.internal.widget.LockPatternUtils;
-import com.android.internal.widget.LockscreenCredential;
-
-import org.junit.Before;
-import org.junit.Rule;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-
-import java.util.Collection;
-import java.util.List;
-
-/**
- * Tests for {@link ChooseLockGenericTest}
- *
- * m SettingsTests &&
- * adb install \
- * -r -g  ${ANDROID_PRODUCT_OUT}/data/app/SettingsTests/SettingsTests.apk &&
- * adb shell am instrument -e class com.android.settings.password.ChooseLockGenericTest \
- * -w com.android.settings.tests/androidx.test.runner.AndroidJUnitRunner
- */
-@RunWith(AndroidJUnit4.class)
-@MediumTest
-public class ChooseLockGenericTest {
-    private static final long TIMEOUT = 5 * DateUtils.SECOND_IN_MILLIS;
-    private static final Intent PHISHING_ATTACK_INTENT = new Intent()
-            .putExtra("confirm_credentials", false)
-            .putExtra("password_confirmed", true);
-
-    private UiDevice mDevice;
-    private Context mTargetContext;
-    private String mSettingPackage;
-
-    @Rule
-    public ActivityTestRule<ChooseLockGeneric> mChooseLockGenericActivityRule =
-            new ActivityTestRule<>(
-                    ChooseLockGeneric.class,
-                    true /* enable touch at launch */,
-                    false /* don't launch at every test */);
-
-    @Before
-    public void setUp() throws Exception {
-        mDevice = UiDevice.getInstance(getInstrumentation());
-        mTargetContext = getInstrumentation().getTargetContext();
-        mSettingPackage = mTargetContext.getPackageName();
-    }
-
-    @Test
-    public void testConfirmLockPasswordShown_deviceWithPassword() throws Throwable {
-        setPassword();
-        try {
-            // GIVEN a PIN password is set on this device at set up.
-            // WHEN ChooseLockGeneric is launched with no extras.
-            mChooseLockGenericActivityRule.launchActivity(null /* No extras */);
-            // THEN ConfirmLockPassword.InternalActivity is shown.
-            final Activity activity = getCurrentActivity();
-            assertThat(isSecureWindow(activity)).isTrue();
-            assertThat(activity)
-                    .isInstanceOf(ConfirmLockPassword.InternalActivity.class);
-        } finally {
-            finishAllAppTasks();
-            mDevice.waitForIdle();
-            clearPassword();
-        }
-    }
-
-    @Test
-    public void testConfirmLockPasswordShown_deviceWithPassword_phishingAttack() throws Throwable {
-        setPassword();
-        try {
-            // GIVEN a PIN password is set on this device at set up.
-            // WHEN ChooseLockGeneric is launched with extras to by-pass lock password confirmation.
-            mChooseLockGenericActivityRule.launchActivity(PHISHING_ATTACK_INTENT);
-            // THEN ConfirmLockPassword.InternalActivity is still shown.
-            final Activity activity = getCurrentActivity();
-            assertThat(isSecureWindow(activity)).isTrue();
-            assertThat(activity)
-                    .isInstanceOf(ConfirmLockPassword.InternalActivity.class);
-        } finally {
-            finishAllAppTasks();
-            mDevice.waitForIdle();
-            clearPassword();
-        }
-    }
-
-    @Test
-    public void testForFingerprint_inflateLayout() {
-        mChooseLockGenericActivityRule.launchActivity(new Intent()
-                .putExtra(ChooseLockSettingsHelper.EXTRA_KEY_FOR_FINGERPRINT, true));
-
-        assertThat(mChooseLockGenericActivityRule.getActivity().isResumed()).isTrue();
-    }
-
-    private Activity getCurrentActivity() throws Throwable {
-        getInstrumentation().waitForIdleSync();
-        final Activity[] activity = new Activity[1];
-        getInstrumentation().runOnMainSync(() -> {
-            Collection<Activity> activities = ActivityLifecycleMonitorRegistry.getInstance()
-                    .getActivitiesInStage(Stage.RESUMED);
-            activity[0] = activities.iterator().next();
-        });
-        return activity[0];
-    }
-
-    /** Sets a PIN password, 12345, for testing. */
-    private void setPassword() throws Exception {
-        Intent newPasswordIntent = new Intent(getTargetContext(), ChooseLockGeneric.class)
-                .putExtra(LockPatternUtils.PASSWORD_TYPE_KEY,
-                        DevicePolicyManager.PASSWORD_QUALITY_NUMERIC)
-                .putExtra(ChooseLockSettingsHelper.EXTRA_KEY_PASSWORD,
-                        LockscreenCredential.createPin("12345"))
-                .addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
-        getInstrumentation().getContext().startActivity(newPasswordIntent);
-        mDevice.waitForIdle();
-
-
-        // Ignore any interstitial options
-        UiObject view = new UiObject(new UiSelector()
-                .resourceId(mSettingPackage + ":id/encrypt_dont_require_password"));
-        if (view.waitForExists(TIMEOUT)) {
-            view.click();
-            mDevice.waitForIdle();
-        }
-
-        // Set our PIN
-        view = new UiObject(new UiSelector()
-                .resourceId(mSettingPackage + ":id/password_entry"));
-        assertTrue("password_entry", view.waitForExists(TIMEOUT));
-
-        // Enter it twice to confirm
-        enterTestPin(view);
-        enterTestPin(view);
-
-        // Dismiss notifications setting
-        view = new UiObject(new UiSelector()
-                .resourceId(mSettingPackage + ":id/redaction_done_button"));
-        if (view.waitForExists(TIMEOUT)) {
-            view.click();
-            mDevice.waitForIdle();
-        }
-
-        mDevice.pressBack();
-
-        assertThat(getTargetContext().getSystemService(KeyguardManager.class).isDeviceSecure())
-                .isTrue();
-    }
-
-    /** Clears the previous set PIN password. */
-    private void clearPassword() throws Exception {
-        Intent newPasswordIntent = new Intent(getTargetContext(), ChooseLockGeneric.class)
-                .putExtra(LockPatternUtils.PASSWORD_TYPE_KEY,
-                        DevicePolicyManager.PASSWORD_QUALITY_UNSPECIFIED)
-                .addFlags(Intent.FLAG_ACTIVITY_NEW_TASK
-                        | Intent.FLAG_ACTIVITY_CLEAR_TASK);
-        getInstrumentation().getContext().startActivity(newPasswordIntent);
-        mDevice.waitForIdle();
-
-        // Enter current PIN
-        UiObject view = new UiObject(
-                new UiSelector().resourceId(mSettingPackage + ":id/password_entry"));
-        if (!view.waitForExists(TIMEOUT)) {
-            // Odd, maybe there is a crash dialog showing; try dismissing it
-            mDevice.pressBack();
-            mDevice.waitForIdle();
-
-            assertTrue("password_entry", view.waitForExists(TIMEOUT));
-        }
-
-        enterTestPin(view);
-
-        mDevice.pressBack();
-
-        assertThat(getTargetContext().getSystemService(KeyguardManager.class).isDeviceSecure())
-                .isFalse();
-    }
-
-    private void finishAllAppTasks() {
-        final ActivityManager activityManager =
-                getTargetContext().getSystemService(ActivityManager.class);
-        final List<AppTask> appTasks = activityManager.getAppTasks();
-        for (ActivityManager.AppTask task : appTasks) {
-            task.finishAndRemoveTask();
-        }
-    }
-
-    private void enterTestPin(UiObject view) throws Exception {
-        mDevice.waitForIdle();
-        view.setText("12345");
-        mDevice.pressEnter();
-        mDevice.waitForIdle();
-    }
-
-    private boolean isSecureWindow(Activity activity) {
-        return (activity.getWindow().getAttributes().flags & WindowManager.LayoutParams.FLAG_SECURE)
-                != 0;
-    }
-}
diff --git a/tests/unit/src/com/android/settings/password/ChooseLockPasswordTest.java b/tests/unit/src/com/android/settings/password/ChooseLockPasswordTest.java
deleted file mode 100644
index e12390c..0000000
--- a/tests/unit/src/com/android/settings/password/ChooseLockPasswordTest.java
+++ /dev/null
@@ -1,101 +0,0 @@
-/*
- * Copyright (C) 2017 Google Inc.
- *
- * 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.password;
-
-import static androidx.test.espresso.Espresso.onView;
-import static androidx.test.espresso.action.ViewActions.pressKey;
-import static androidx.test.espresso.assertion.ViewAssertions.matches;
-import static androidx.test.espresso.matcher.ViewMatchers.isDisplayed;
-import static androidx.test.espresso.matcher.ViewMatchers.isEnabled;
-import static androidx.test.espresso.matcher.ViewMatchers.withEffectiveVisibility;
-import static androidx.test.espresso.matcher.ViewMatchers.withId;
-
-import static com.google.common.truth.Truth.assertThat;
-
-import static org.hamcrest.CoreMatchers.not;
-
-import android.app.Activity;
-import android.app.Instrumentation;
-import android.content.Context;
-import android.content.Intent;
-import android.view.KeyEvent;
-import android.view.View;
-
-import androidx.test.InstrumentationRegistry;
-import androidx.test.espresso.action.ViewActions;
-import androidx.test.espresso.matcher.ViewMatchers;
-import androidx.test.runner.AndroidJUnit4;
-
-import com.android.settings.R;
-
-import com.google.android.setupcompat.PartnerCustomizationLayout;
-import com.google.android.setupcompat.template.FooterBarMixin;
-
-import org.junit.Before;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-
-@RunWith(AndroidJUnit4.class)
-public class ChooseLockPasswordTest {
-    private Instrumentation mInstrumentation;
-    private Context mContext;
-
-    @Before
-    public void setUp() {
-        mInstrumentation = InstrumentationRegistry.getInstrumentation();
-        mContext = mInstrumentation.getTargetContext();
-    }
-
-    @Test
-    public void clearIsNotShown_when_activityLaunchedInitially() {
-        final Activity activity =
-                mInstrumentation.startActivitySync(new Intent(mContext, ChooseLockPassword.class)
-                        .addFlags(Intent.FLAG_ACTIVITY_NEW_TASK));
-        final PartnerCustomizationLayout layout = activity.findViewById(R.id.setup_wizard_layout);
-        assertThat(
-                layout.getMixin(FooterBarMixin.class).getSecondaryButtonView().getVisibility())
-                        .isEqualTo(View.GONE);
-    }
-
-    @Test
-    public void clearIsNotShown_when_nothingEntered() {
-        final Activity activity =
-                mInstrumentation.startActivitySync(new Intent(mContext, ChooseLockPassword.class));
-        final PartnerCustomizationLayout layout = activity.findViewById(R.id.setup_wizard_layout);
-        onView(withId(R.id.password_entry)).perform(ViewActions.typeText("1234"))
-                .perform(pressKey(KeyEvent.KEYCODE_ENTER));
-        assertThat(
-                layout.getMixin(FooterBarMixin.class).getSecondaryButtonView().getVisibility())
-                        .isEqualTo(View.GONE);
-    }
-
-    @Test
-    public void clearIsShown_when_somethingEnteredToConfirm() {
-        final Activity activity =
-                mInstrumentation.startActivitySync(new Intent(mContext, ChooseLockPassword.class));
-        final PartnerCustomizationLayout layout = activity.findViewById(R.id.setup_wizard_layout);
-        onView(withId(R.id.password_entry)).perform(ViewActions.typeText("1234"))
-                .perform(pressKey(KeyEvent.KEYCODE_ENTER))
-                .perform(ViewActions.typeText("1"));
-        // clear should be present if text field contains content
-        assertThat(layout.getMixin(FooterBarMixin.class).getSecondaryButtonView().getText())
-                .isEqualTo(mContext.getString(R.string.lockpassword_clear_label));
-        assertThat(
-                layout.getMixin(FooterBarMixin.class).getSecondaryButtonView().getVisibility())
-                        .isEqualTo(View.VISIBLE);
-    }
-}
diff --git a/tests/unit/src/com/android/settings/password/ConfirmLockPasswordTest.java b/tests/unit/src/com/android/settings/password/ConfirmLockPasswordTest.java
deleted file mode 100644
index 321284f..0000000
--- a/tests/unit/src/com/android/settings/password/ConfirmLockPasswordTest.java
+++ /dev/null
@@ -1,70 +0,0 @@
-/*
- * Copyright (C) 2017 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License
- */
-
-package com.android.settings.password;
-
-import static androidx.test.espresso.Espresso.onView;
-import static androidx.test.espresso.action.ViewActions.pressKey;
-import static androidx.test.espresso.action.ViewActions.typeText;
-import static androidx.test.espresso.assertion.ViewAssertions.matches;
-import static androidx.test.espresso.matcher.ViewMatchers.withId;
-import static androidx.test.espresso.matcher.ViewMatchers.withText;
-
-import android.app.Instrumentation;
-import android.content.Context;
-import android.content.Intent;
-import android.view.KeyEvent;
-
-import androidx.test.InstrumentationRegistry;
-import androidx.test.runner.AndroidJUnit4;
-
-import com.android.settings.R;
-
-import org.junit.Before;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-
-@RunWith(AndroidJUnit4.class)
-public class ConfirmLockPasswordTest {
-
-    private Instrumentation mInstrumentation;
-    private Context mContext;
-
-    @Before
-    public void setUp() {
-        mInstrumentation = InstrumentationRegistry.getInstrumentation();
-        mContext = mInstrumentation.getTargetContext();
-    }
-
-    @Test
-    public void enterWrongPin_shouldShowErrorMessage() {
-        mInstrumentation.startActivitySync(
-                new Intent(mContext, ConfirmLockPassword.class));
-        onView(withId(R.id.password_entry)).perform(typeText("1234"))
-                .perform(pressKey(KeyEvent.KEYCODE_ENTER));
-        onView(withId(R.id.errorText)).check(matches(withText(R.string.lockpassword_invalid_pin)));
-    }
-
-    @Test
-    public void enterWrongPin_darkTheme_shouldShowErrorMessage() {
-        mInstrumentation.startActivitySync(
-                new Intent(mContext, ConfirmLockPassword.class)
-                        .putExtra(ConfirmDeviceCredentialBaseFragment.DARK_THEME, true));
-        onView(withId(R.id.password_entry)).perform(typeText("1234"))
-                .perform(pressKey(KeyEvent.KEYCODE_ENTER));
-        onView(withId(R.id.errorText)).check(matches(withText(R.string.lockpassword_invalid_pin)));
-    }
-}
diff --git a/tests/unit/src/com/android/settings/password/SetupChooseLockGenericTest.java b/tests/unit/src/com/android/settings/password/SetupChooseLockGenericTest.java
deleted file mode 100644
index b0ca636..0000000
--- a/tests/unit/src/com/android/settings/password/SetupChooseLockGenericTest.java
+++ /dev/null
@@ -1,98 +0,0 @@
-/*
- * Copyright (C) 2018 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.settings.password;
-
-import static android.app.admin.DevicePolicyManager.ACTION_SET_NEW_PASSWORD;
-
-import static androidx.test.InstrumentationRegistry.getInstrumentation;
-import static androidx.test.InstrumentationRegistry.getTargetContext;
-
-import static com.google.common.truth.Truth.assertThat;
-
-import android.app.Activity;
-import android.content.Context;
-import android.content.Intent;
-import android.provider.Settings;
-import android.support.test.uiautomator.UiDevice;
-import android.support.test.uiautomator.UiSelector;
-
-import androidx.test.filters.SmallTest;
-import androidx.test.runner.AndroidJUnit4;
-import androidx.test.runner.lifecycle.ActivityLifecycleMonitorRegistry;
-import androidx.test.runner.lifecycle.Stage;
-
-import org.junit.After;
-import org.junit.Before;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-
-import java.util.Collection;
-
-/**
- * Tests for {@link SetupChooseLockGenericTest}
- *
- */
-@RunWith(AndroidJUnit4.class)
-@SmallTest
-public class SetupChooseLockGenericTest {
-
-    private UiDevice mDevice;
-    private Context mContext;
-
-    @Before
-    public void setUp() throws Exception {
-        mDevice = UiDevice.getInstance(getInstrumentation());
-        mContext = getInstrumentation().getTargetContext();
-        Settings.Global.putInt(
-            mContext.getContentResolver(), Settings.Global.DEVICE_PROVISIONED, 0);
-    }
-
-    @After
-    public void tearDown() {
-        Settings.Global.putInt(
-            mContext.getContentResolver(), Settings.Global.DEVICE_PROVISIONED, 1);
-    }
-
-    @Test
-    public void clickSkipFigerprintPreference_deviceNotProvisioned_shouldBeAbleToProceed()
-            throws Throwable {
-        final Intent newPasswordIntent =
-            new Intent(getTargetContext(), SetupChooseLockGeneric.class)
-            .putExtra(ChooseLockSettingsHelper.EXTRA_KEY_FOR_FINGERPRINT, true)
-            .setAction(ACTION_SET_NEW_PASSWORD)
-            .addFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK);
-
-        getInstrumentation().getContext().startActivity(newPasswordIntent);
-        mDevice.waitForIdle();
-        mDevice.findObject(new UiSelector().textContains("Continue without ")).click();
-
-        final Activity activity = getCurrentActivity();
-        assertThat(activity).isInstanceOf(SetupChooseLockGeneric.InternalActivity.class);
-    }
-
-    private Activity getCurrentActivity() throws Throwable {
-        getInstrumentation().waitForIdleSync();
-        final Activity[] activity = new Activity[1];
-        getInstrumentation().runOnMainSync(() -> {
-            Collection<Activity> activities = ActivityLifecycleMonitorRegistry.getInstance()
-                    .getActivitiesInStage(Stage.RESUMED);
-            activity[0] = activities.iterator().next();
-        });
-        return activity[0];
-    }
-
-}
diff --git a/tests/unit/src/com/android/settings/slices/SliceDataContractTest.java b/tests/unit/src/com/android/settings/slices/SliceDataContractTest.java
deleted file mode 100644
index 61629e9..0000000
--- a/tests/unit/src/com/android/settings/slices/SliceDataContractTest.java
+++ /dev/null
@@ -1,122 +0,0 @@
-/*
- * Copyright (C) 2018 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.settings.slices;
-
-import static junit.framework.Assert.fail;
-
-import android.content.Context;
-import android.os.Bundle;
-import android.platform.test.annotations.Presubmit;
-import android.provider.SearchIndexableResource;
-import android.text.TextUtils;
-import android.util.Log;
-
-import androidx.test.InstrumentationRegistry;
-import androidx.test.filters.MediumTest;
-import androidx.test.runner.AndroidJUnit4;
-
-import com.android.settings.core.PreferenceXmlParserUtils;
-import com.android.settings.overlay.FeatureFactory;
-import com.android.settingslib.search.Indexable;
-import com.android.settingslib.search.SearchIndexableData;
-import com.android.settingslib.search.SearchIndexableResources;
-
-import org.junit.Before;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.xmlpull.v1.XmlPullParserException;
-
-import java.io.IOException;
-import java.util.HashSet;
-import java.util.List;
-import java.util.Set;
-
-@RunWith(AndroidJUnit4.class)
-@MediumTest
-public class SliceDataContractTest {
-
-    private static final String TAG = "SliceDataContractTest";
-    private Context mContext;
-
-    @Before
-    public void setUp() {
-        mContext = InstrumentationRegistry.getTargetContext();
-    }
-
-    @Test
-    @Presubmit
-    public void preferenceWithControllerMustHaveNonEmptyTitle()
-            throws IOException, XmlPullParserException {
-        final Set<String> nullTitleFragments = new HashSet<>();
-
-        final SearchIndexableResources resources =
-                FeatureFactory.getFactory(mContext).getSearchFeatureProvider()
-                        .getSearchIndexableResources();
-
-        for (SearchIndexableData SearchIndexableData : resources.getProviderValues()) {
-            verifyPreferenceTitle(nullTitleFragments, SearchIndexableData);
-        }
-
-        if (!nullTitleFragments.isEmpty()) {
-            final StringBuilder error = new StringBuilder(
-                    "All preferences with a controller must have a non-empty title by default, "
-                            + "found empty title in the following fragments\n");
-            for (String c : nullTitleFragments) {
-                error.append(c).append("\n");
-            }
-            fail(error.toString());
-        }
-    }
-
-    private void verifyPreferenceTitle(Set<String> nullTitleFragments,
-            SearchIndexableData searchIndexableData)
-            throws IOException, XmlPullParserException {
-
-        final String className = searchIndexableData.getTargetClass().getName();
-        final Indexable.SearchIndexProvider provider =
-                searchIndexableData.getSearchIndexProvider();
-
-        final List<SearchIndexableResource> resourcesToIndex =
-                provider.getXmlResourcesToIndex(mContext, true);
-
-        if (resourcesToIndex == null) {
-            Log.d(TAG, className + "is not providing SearchIndexableResource, skipping");
-            return;
-        }
-
-        for (SearchIndexableResource sir : resourcesToIndex) {
-            final List<Bundle> metadata = PreferenceXmlParserUtils.extractMetadata(mContext,
-                    sir.xmlResId,
-                    PreferenceXmlParserUtils.MetadataFlag.FLAG_INCLUDE_PREF_SCREEN
-                            | PreferenceXmlParserUtils.MetadataFlag.FLAG_NEED_PREF_TITLE
-                            | PreferenceXmlParserUtils.MetadataFlag.FLAG_NEED_PREF_CONTROLLER);
-
-            for (Bundle bundle : metadata) {
-                final String controller = bundle.getString(
-                        PreferenceXmlParserUtils.METADATA_CONTROLLER);
-                if (TextUtils.isEmpty(controller)) {
-                    continue;
-                }
-                final String title = bundle.getString(PreferenceXmlParserUtils.METADATA_TITLE);
-                if (TextUtils.isEmpty(title)) {
-                    nullTitleFragments.add(className);
-                }
-            }
-        }
-    }
-
-}
\ No newline at end of file
diff --git a/tests/unit/src/com/android/settings/wifi/SavedNetworkSettingsTest.java b/tests/unit/src/com/android/settings/wifi/SavedNetworkSettingsTest.java
deleted file mode 100644
index 1a5f923..0000000
--- a/tests/unit/src/com/android/settings/wifi/SavedNetworkSettingsTest.java
+++ /dev/null
@@ -1,76 +0,0 @@
-/*
- * Copyright (C) 2017 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package com.android.settings.wifi;
-
-import static androidx.test.espresso.Espresso.onView;
-import static androidx.test.espresso.action.ViewActions.click;
-import static androidx.test.espresso.assertion.ViewAssertions.matches;
-import static androidx.test.espresso.matcher.ViewMatchers.isDisplayed;
-import static androidx.test.espresso.matcher.ViewMatchers.withText;
-
-import android.content.Context;
-import android.content.Intent;
-
-import androidx.test.InstrumentationRegistry;
-import androidx.test.rule.ActivityTestRule;
-import androidx.test.runner.AndroidJUnit4;
-
-import com.android.settings.Settings;
-
-import org.junit.Before;
-import org.junit.Rule;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-
-@RunWith(AndroidJUnit4.class)
-public class SavedNetworkSettingsTest {
-
-    // Keys used to lookup resources by name (see the resourceId helper method).
-    private static final String STRING = "string";
-    private static final String WIFI_ADD_NETWORK = "wifi_add_network";
-    private static final String WIFI_NETWORK_LABEL = "wifi_ssid";
-
-    private Context mContext;
-
-    @Rule
-    public ActivityTestRule<Settings.SavedAccessPointsSettingsActivity> mActivityRule =
-            new ActivityTestRule<>(Settings.SavedAccessPointsSettingsActivity.class, true);
-
-    private int resourceId(String type, String name) {
-        return mContext.getResources().getIdentifier(name, type, mContext.getPackageName());
-    }
-
-    @Before
-    public void setUp() {
-        mContext = InstrumentationRegistry.getTargetContext();
-    }
-
-    private void launchSavedNetworksSettings() {
-        Intent intent = new Intent()
-                .setClassName(mContext.getPackageName(),
-                        Settings.SavedAccessPointsSettingsActivity.class.getName())
-                .setPackage(mContext.getPackageName());
-        mActivityRule.launchActivity(intent);
-    }
-
-    @Test
-    public void launchSavedNetworkSettings_shouldHaveAddNetworkField() {
-        launchSavedNetworksSettings();
-        onView(withText(resourceId(STRING, WIFI_ADD_NETWORK))).check(matches(isDisplayed()))
-                .perform(click());
-        onView(withText(resourceId(STRING, WIFI_NETWORK_LABEL))).check(matches(isDisplayed()));
-    }
-}
diff --git a/tests/unit/src/com/android/settings/wifi/WifiCallingSettingUiTest.java b/tests/unit/src/com/android/settings/wifi/WifiCallingSettingUiTest.java
deleted file mode 100644
index e913e2c..0000000
--- a/tests/unit/src/com/android/settings/wifi/WifiCallingSettingUiTest.java
+++ /dev/null
@@ -1,306 +0,0 @@
-/**
- * Copyright (C) 2017 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package com.android.settings.wifi;
-
-import static androidx.test.espresso.Espresso.onView;
-import static androidx.test.espresso.action.ViewActions.click;
-import static androidx.test.espresso.assertion.ViewAssertions.doesNotExist;
-import static androidx.test.espresso.assertion.ViewAssertions.matches;
-import static androidx.test.espresso.matcher.ViewMatchers.isCompletelyDisplayed;
-import static androidx.test.espresso.matcher.ViewMatchers.isSelected;
-import static androidx.test.espresso.matcher.ViewMatchers.withResourceName;
-import static androidx.test.espresso.matcher.ViewMatchers.withText;
-
-import static org.hamcrest.CoreMatchers.allOf;
-import static org.hamcrest.CoreMatchers.anything;
-import static org.junit.Assert.assertEquals;
-import static org.junit.matchers.JUnitMatchers.containsString;
-import static org.mockito.ArgumentMatchers.anyString;
-import static org.mockito.ArgumentMatchers.nullable;
-import static org.mockito.Mockito.doReturn;
-
-import android.app.Activity;
-import android.app.Instrumentation;
-import android.content.Context;
-import android.content.Intent;
-import android.support.test.uiautomator.UiDevice;
-import android.telephony.SubscriptionInfo;
-import android.telephony.ims.ImsMmTelManager;
-
-import androidx.test.InstrumentationRegistry;
-import androidx.test.espresso.NoMatchingViewException;
-import androidx.test.espresso.ViewInteraction;
-import androidx.test.runner.AndroidJUnit4;
-
-import com.android.ims.ImsManager;
-import com.android.internal.telephony.SubscriptionController;
-import com.android.settings.testutils.MockedServiceManager;
-
-import junit.framework.Assert;
-
-import org.junit.After;
-import org.junit.Before;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.mockito.Mock;
-import org.mockito.MockitoAnnotations;
-
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.List;
-
-@RunWith(AndroidJUnit4.class)
-public class WifiCallingSettingUiTest {
-    private static final String SUBSCRIPTION0_NAME = "SUB0";
-    private static final String SUBSCRIPTION1_NAME = "SUB1";
-    private static final String WFC_MODE_TITLE = "Calling preference";
-    private static final String WFC_MODE_WIFI_ONLY = "Wi-Fi only";
-    private static final String WFC_MODE_WIFI_PREFERRED = "Wi-Fi preferred";
-    private static final String WFC_MODE_CELLULAR_PREFERRED = "Mobile preferred";
-
-    private Instrumentation mInstrumentation;
-    private Context mContext;
-    private UiDevice mDevice;
-    @Mock
-    SubscriptionController mSubscriptionController;
-    MockedServiceManager mMockedServiceManager;
-    protected HashMap<Integer, ImsManager> mImsManagerInstances = new HashMap<>();
-    List<SubscriptionInfo> mSils = new ArrayList();
-    @Mock
-    SubscriptionInfo mSubscriptionInfo0;
-    @Mock
-    SubscriptionInfo mSubscriptionInfo1;
-    @Mock
-    ImsManager mImsManager0;
-    @Mock
-    ImsManager mImsManager1;
-    @Mock
-    ImsMmTelManager mImsMmTelManager0;
-    @Mock
-    ImsMmTelManager mImsMmTelManager1;
-
-    @Before
-    public void setUp() throws Exception {
-        MockitoAnnotations.initMocks(this);
-        mInstrumentation = InstrumentationRegistry.getInstrumentation();
-        mContext = mInstrumentation.getTargetContext();
-        mDevice = UiDevice.getInstance(mInstrumentation);
-
-        mMockedServiceManager = new MockedServiceManager();
-        mMockedServiceManager.replaceService("isub", mSubscriptionController);
-
-        mMockedServiceManager.replaceInstance(
-                ImsManager.class, "sImsManagerInstances", null, mImsManagerInstances);
-        mMockedServiceManager.replaceInstance(
-                SubscriptionController.class, "sInstance", null, mSubscriptionController);
-        doReturn(mSubscriptionController)
-                .when(mSubscriptionController).queryLocalInterface(anyString());
-        mImsManagerInstances.put(0, mImsManager0);
-        mImsManagerInstances.put(1, mImsManager1);
-        doReturn(mSils).when(mSubscriptionController).getActiveSubscriptionInfoList(anyString(),
-                nullable(String.class));
-        doReturn(0).when(mSubscriptionController).getPhoneId(0);
-        doReturn(1).when(mSubscriptionController).getPhoneId(1);
-        doReturn(0).when(mSubscriptionInfo0).getSubscriptionId();
-        doReturn(1).when(mSubscriptionInfo1).getSubscriptionId();
-        doReturn(0).when(mSubscriptionInfo0).getSimSlotIndex();
-        doReturn(1).when(mSubscriptionInfo1).getSimSlotIndex();
-        doReturn(SUBSCRIPTION0_NAME).when(mSubscriptionInfo0).getDisplayName();
-        doReturn(SUBSCRIPTION1_NAME).when(mSubscriptionInfo1).getDisplayName();
-
-        doReturn(true).when(mImsManager0).isWfcEnabledByPlatform();
-        doReturn(true).when(mImsManager0).isNonTtyOrTtyOnVolteEnabled();
-        doReturn(true).when(mImsManager1).isWfcEnabledByPlatform();
-        doReturn(true).when(mImsManager1).isNonTtyOrTtyOnVolteEnabled();
-
-        mDevice.wakeUp();
-        mDevice.pressMenu();
-    }
-
-    @After
-    public void tearDown() throws Exception {
-        mMockedServiceManager.restoreAllServices();
-    }
-
-    @Test
-    public void testSingleSimUi() throws InterruptedException {
-        configureSingleSim();
-        doReturn(true).when(mImsManager0).isWfcEnabledByUser();
-        doReturn(ImsMmTelManager.WIFI_MODE_WIFI_PREFERRED)
-                .when(mImsMmTelManager0).getVoWiFiModeSetting();
-        doReturn(ImsMmTelManager.WIFI_MODE_WIFI_PREFERRED)
-                .when(mImsMmTelManager0).getVoWiFiRoamingModeSetting();
-
-        mInstrumentation.startActivitySync(createActivityIntent());
-
-        checkSingleSimUi();
-
-        try {
-            mDevice.setOrientationLeft();
-        } catch (Exception e) {
-            Assert.fail("Exception " + e);
-        }
-
-        // Re-check after rotation. Fragment should be recreated properly.
-        checkSingleSimUi();
-
-        try {
-            mDevice.setOrientationNatural();
-        } catch (Exception e) {
-            Assert.fail("Exception " + e);
-        }
-
-        // Re-check after rotation. Fragment should be resumed properly.
-        checkSingleSimUi();
-    }
-
-    private void checkSingleSimUi() {
-        assertEquals(false, checkExists(onView(withText(SUBSCRIPTION0_NAME))));
-        assertEquals(false, checkExists(onView(withText(SUBSCRIPTION1_NAME))));
-        assertEquals(true, checkExists(onView(withText(WFC_MODE_TITLE))));
-        assertEquals(true, checkExists(onView(withText(WFC_MODE_WIFI_PREFERRED))));
-        checkSwitchBarStatus(true, true);
-        checkEmptyViewStatus(false);
-    }
-
-    @Test
-    public void testNoValidSub() throws InterruptedException {
-        configureDualSim();
-        doReturn(false).when(mImsManager0).isWfcEnabledByPlatform();
-        doReturn(false).when(mImsManager0).isNonTtyOrTtyOnVolteEnabled();
-        doReturn(false).when(mImsManager1).isWfcEnabledByPlatform();
-        doReturn(false).when(mImsManager1).isNonTtyOrTtyOnVolteEnabled();
-        doReturn(false).when(mImsManager0).isWfcEnabledByUser();
-        doReturn(ImsMmTelManager.WIFI_MODE_WIFI_PREFERRED)
-                .when(mImsMmTelManager0).getVoWiFiModeSetting();
-        doReturn(ImsMmTelManager.WIFI_MODE_WIFI_PREFERRED)
-                .when(mImsMmTelManager0).getVoWiFiRoamingModeSetting();
-
-        Activity activity = mInstrumentation.startActivitySync(createActivityIntent());
-
-        assertEquals(false, checkExists(onView(withText(SUBSCRIPTION0_NAME))));
-        assertEquals(false, checkExists(onView(withText(SUBSCRIPTION1_NAME))));
-        assertEquals(false, checkExists(onView(withText(WFC_MODE_TITLE))));
-
-        checkSwitchBarStatus(false, false);
-        checkEmptyViewStatus(false);
-    }
-
-    @Test
-    public void testWfcDisabled() throws InterruptedException {
-        configureSingleSim();
-        doReturn(false).when(mImsManager0).isWfcEnabledByUser();
-        doReturn(ImsMmTelManager.WIFI_MODE_WIFI_PREFERRED)
-                .when(mImsMmTelManager0).getVoWiFiModeSetting();
-        doReturn(ImsMmTelManager.WIFI_MODE_WIFI_PREFERRED)
-                .when(mImsMmTelManager0).getVoWiFiRoamingModeSetting();
-
-        Activity activity = mInstrumentation.startActivitySync(createActivityIntent());
-
-        assertEquals(false, checkExists(onView(withText(SUBSCRIPTION0_NAME))));
-        assertEquals(false, checkExists(onView(withText(SUBSCRIPTION1_NAME))));
-        assertEquals(false, checkExists(onView(withText(WFC_MODE_TITLE))));
-
-        checkSwitchBarStatus(true, false);
-        checkEmptyViewStatus(true);
-    }
-
-    @Test
-    public void testDualSimUi() throws InterruptedException {
-        configureDualSim();
-        doReturn(true).when(mImsManager0).isWfcEnabledByUser();
-        doReturn(false).when(mImsManager1).isWfcEnabledByUser();
-        doReturn(ImsMmTelManager.WIFI_MODE_CELLULAR_PREFERRED)
-                .when(mImsMmTelManager0).getVoWiFiModeSetting();
-        doReturn(ImsMmTelManager.WIFI_MODE_CELLULAR_PREFERRED)
-                .when(mImsMmTelManager0).getVoWiFiRoamingModeSetting();
-
-        mInstrumentation.startActivitySync(createActivityIntent());
-
-        assertEquals(true, checkExists(onView(withText(SUBSCRIPTION0_NAME))));
-        assertEquals(true, checkExists(onView(withText(SUBSCRIPTION1_NAME))));
-        assertEquals(true, checkExists(onView(withText(WFC_MODE_TITLE))));
-        assertEquals(true, checkExists(onView(withText(WFC_MODE_CELLULAR_PREFERRED))));
-
-        onView(withText(SUBSCRIPTION0_NAME)).check(matches(isSelected()));
-        checkSwitchBarStatus(true, true);
-        checkEmptyViewStatus(false);
-
-        // Switch to SUB1.
-        onView(withText(SUBSCRIPTION1_NAME)).perform(click());
-
-        checkSwitchBarStatus(true, false);
-        checkEmptyViewStatus(true);
-        onView(withText(SUBSCRIPTION1_NAME)).check(matches(isSelected()));
-    }
-
-    private boolean checkExists(ViewInteraction v) {
-        try {
-            v.check(matches(isCompletelyDisplayed()));
-            return true;
-        } catch (NoMatchingViewException e) {
-            return false;
-        }
-    }
-
-    private Intent createActivityIntent() {
-        Intent intent = new Intent(mContext,
-                com.android.settings.Settings.WifiCallingSettingsActivity.class);
-        intent.setPackage("com.android.settings");
-        intent.setAction("android.intent.action.MAIN");
-        intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
-        return intent;
-    }
-
-    private void configureSingleSim() {
-        mSils.clear();
-        mSils.add(mSubscriptionInfo0);
-    }
-
-    private void configureDualSim() {
-        mSils.clear();
-        mSils.add(mSubscriptionInfo0);
-        mSils.add(mSubscriptionInfo1);
-    }
-
-    private void checkSwitchBarStatus(boolean shouldDisplay, boolean statusOn) {
-        if (shouldDisplay) {
-            try {
-                onView(allOf(withResourceName("switch_text"), isCompletelyDisplayed()))
-                        .check(matches(withText(containsString(statusOn ? "On" : "Off"))));
-            } catch (Exception e) {
-                Assert.fail("Exception " + e);
-            }
-        } else {
-            onView(allOf(withResourceName("switch_text"), isCompletelyDisplayed()))
-                    .check(doesNotExist());
-        }
-    }
-
-    private void checkEmptyViewStatus(boolean shouldDisplay) {
-        try {
-            if (!shouldDisplay) {
-                onView(allOf(withResourceName("empty"), isCompletelyDisplayed()))
-                        .check(doesNotExist());
-            } else {
-                onView(allOf(withResourceName("empty"), isCompletelyDisplayed()))
-                        .check(matches(anything()));
-            }
-        } catch (Exception e) {
-            Assert.fail("Exception " + e);
-        }
-    }
-}
diff --git a/tests/unit/src/com/android/settings/wifi/WifiSettingsUiTest.java b/tests/unit/src/com/android/settings/wifi/WifiSettingsUiTest.java
deleted file mode 100644
index 4c9b3c5..0000000
--- a/tests/unit/src/com/android/settings/wifi/WifiSettingsUiTest.java
+++ /dev/null
@@ -1,248 +0,0 @@
-/*
- * Copyright (C) 2017 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package com.android.settings.wifi;
-
-import static androidx.test.InstrumentationRegistry.getInstrumentation;
-import static androidx.test.espresso.Espresso.onView;
-import static androidx.test.espresso.assertion.ViewAssertions.doesNotExist;
-import static androidx.test.espresso.assertion.ViewAssertions.matches;
-import static androidx.test.espresso.matcher.ViewMatchers.Visibility.VISIBLE;
-import static androidx.test.espresso.matcher.ViewMatchers.isDisplayed;
-import static androidx.test.espresso.matcher.ViewMatchers.withEffectiveVisibility;
-import static androidx.test.espresso.matcher.ViewMatchers.withText;
-
-import static com.google.common.truth.Truth.assertThat;
-
-import static org.hamcrest.Matchers.allOf;
-import static org.hamcrest.Matchers.startsWith;
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.when;
-
-import android.content.Context;
-import android.content.Intent;
-import android.net.wifi.WifiManager;
-import android.provider.Settings;
-import android.support.test.uiautomator.UiDevice;
-
-import androidx.fragment.app.Fragment;
-import androidx.test.InstrumentationRegistry;
-import androidx.test.rule.ActivityTestRule;
-import androidx.test.runner.AndroidJUnit4;
-
-import com.android.settings.Settings.WifiSettingsActivity;
-import com.android.settingslib.utils.ThreadUtils;
-import com.android.wifitrackerlib.WifiEntry;
-import com.android.wifitrackerlib.WifiPickerTracker;
-
-import com.google.common.collect.Lists;
-
-import org.junit.Before;
-import org.junit.Rule;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.mockito.Mock;
-import org.mockito.MockitoAnnotations;
-
-import java.util.List;
-
-@RunWith(AndroidJUnit4.class)
-public class WifiSettingsUiTest {
-    private static final String TEST_SSID = "Test Ssid";
-    private static final String TEST_KEY = "Test Key";
-
-    // Keys used to lookup resources by name (see the resourceId/resourceString helper methods).
-    private static final String STRING = "string";
-    private static final String WIFI_CONFIGURE_SETTINGS_PREFERENCE_TITLE =
-            "wifi_configure_settings_preference_title";
-    private static final String WIFI_SAVED_ACCESS_POINTS_LABEL = "wifi_saved_access_points_label";
-    private static final String WIFI_EMPTY_LIST_WIFI_OFF = "wifi_empty_list_wifi_off";
-    private static final String WIFI_DISPLAY_STATUS_CONNECTED = "wifi_display_status_connected";
-
-    @Mock
-    private WifiPickerTracker mWifiTracker;
-    @Mock
-    private WifiPickerTracker.WifiPickerTrackerCallback mWifiListener;
-
-    private Context mContext;
-    private UiDevice mDevice;
-
-    @Rule
-    public ActivityTestRule<WifiSettingsActivity> mActivityRule =
-            new ActivityTestRule<>(WifiSettingsActivity.class, true);
-
-    @Before
-    public void setUp() {
-        MockitoAnnotations.initMocks(this);
-        mContext = InstrumentationRegistry.getTargetContext();
-        mDevice = UiDevice.getInstance(getInstrumentation());
-    }
-
-    /**
-     * Helper to get around the problem that directly accessing settings resource id's from
-     * com.android.settings.R via R.(type).(name) (eg R.id.password or
-     * R.string.wifi_configure_settings_preference_title) may not work due to mismatched resource
-     * ids. See b/37714546 and b/63546650.
-     */
-    private int resourceId(String type, String name) {
-        return mContext.getResources().getIdentifier(name, type, mContext.getPackageName());
-    }
-
-    /** Similar to {@link #resourceId}, but for accessing R.string.<name> values. */
-    private String resourceString(String name) {
-        return mContext.getResources().getString(resourceId(STRING, name));
-    }
-
-    /** Launch the activity via an Intent with a String extra. */
-    private void launchActivity(String extraName, String extraValue) {
-        Intent intent = new Intent(Settings.ACTION_WIFI_SETTINGS);
-        if (extraName != null && extraValue != null) {
-            intent.putExtra(extraName, extraValue);
-        }
-        mActivityRule.launchActivity(intent);
-
-        List<Fragment> fragments =
-                mActivityRule.getActivity().getSupportFragmentManager().getFragments();
-        assertThat(fragments.size()).isEqualTo(1);
-        ((WifiSettings) fragments.get(0)).mWifiPickerTracker = mWifiTracker;
-        mWifiListener = (WifiSettings) fragments.get(0);
-        assertThat(mWifiListener).isNotNull();
-    }
-
-    /** Helper to launch the activity with no extra. */
-    private void launchActivity() {
-        launchActivity(null, null);
-    }
-
-    private void setWifiState(int wifiState) {
-        when(mWifiTracker.getWifiState()).thenReturn(wifiState);
-    }
-
-    @Test
-    public void launchActivityShouldSucceed() {
-        launchActivity();
-    }
-
-    @Test
-    public void shouldShowWifiPreferences() {
-        launchActivity();
-
-        onView(withText(resourceId(STRING, WIFI_CONFIGURE_SETTINGS_PREFERENCE_TITLE))).check(
-                matches(isDisplayed()));
-    }
-
-    @Test
-    public void noSavedNetworks_wifiDisabled_shouldNotShowSavedNetworksButton() {
-        setWifiState(WifiManager.WIFI_STATE_DISABLED);
-        when(mWifiTracker.getNumSavedNetworks()).thenReturn(0);
-
-        launchActivity();
-
-        onView(withText(resourceId(STRING, WIFI_SAVED_ACCESS_POINTS_LABEL))).check(
-                doesNotExist());
-    }
-
-    @Test
-    public void savedNetworksExist_shouldShowSavedNetworksButton() {
-        setWifiState(WifiManager.WIFI_STATE_ENABLED);
-        when(mWifiTracker.getNumSavedNetworks()).thenReturn(1);
-
-        launchActivity();
-        mActivityRule.getActivity().getMainThreadHandler()
-                .post(() -> mWifiListener.onNumSavedNetworksChanged());
-
-        onView(allOf(withText(resourceId(STRING, WIFI_SAVED_ACCESS_POINTS_LABEL)),
-                withEffectiveVisibility(VISIBLE))).check(matches(isDisplayed()));
-    }
-
-    @Test
-    public void onWifiStateChanged_wifiDisabled_seeOffMessage() {
-        setWifiState(WifiManager.WIFI_STATE_DISABLED);
-
-        launchActivity();
-        mActivityRule.getActivity().getMainThreadHandler()
-                .post(() -> mWifiListener.onWifiStateChanged());
-
-        onView(withText(startsWith(resourceString(WIFI_EMPTY_LIST_WIFI_OFF)))).check(
-                matches(isDisplayed()));
-    }
-
-    @Test
-    public void onWifiStateChanged_wifiEnabled_shouldNotSeeOffMessage() {
-        setWifiState(WifiManager.WIFI_STATE_ENABLED);
-
-        launchActivity();
-        mActivityRule.getActivity().getMainThreadHandler()
-                .post(() -> mWifiListener.onWifiStateChanged());
-
-        onView(withText(startsWith(resourceString(WIFI_EMPTY_LIST_WIFI_OFF)))).check(
-                doesNotExist());
-    }
-
-    @Test
-    public void onConnected_shouldSeeConnectedMessage() {
-        setWifiState(WifiManager.WIFI_STATE_ENABLED);
-        final WifiEntry wifiEntry = mock(WifiEntry.class);
-        when(wifiEntry.getConnectedState()).thenReturn(WifiEntry.CONNECTED_STATE_CONNECTED);
-        when(wifiEntry.getSummary(false /* concise */))
-                .thenReturn(resourceString(WIFI_DISPLAY_STATUS_CONNECTED));
-        when(wifiEntry.getKey()).thenReturn(TEST_KEY);
-        when(mWifiTracker.getConnectedWifiEntry()).thenReturn(wifiEntry);
-
-        launchActivity();
-        ThreadUtils.postOnMainThread(() -> mWifiListener.onWifiEntriesChanged());
-        mDevice.waitForIdle();
-
-        onView(withText(resourceString(WIFI_DISPLAY_STATUS_CONNECTED))).check(
-                matches(isDisplayed()));
-    }
-
-    @Test
-    public void changingSecurityStateOnAp_ShouldNotCauseMultipleListItems() {
-        setWifiState(WifiManager.WIFI_STATE_ENABLED);
-
-        final WifiEntry openWifiEntry = mock(WifiEntry.class);
-        when(openWifiEntry.getTitle()).thenReturn(TEST_SSID);
-        when(openWifiEntry.getSecurity()).thenReturn(WifiEntry.SECURITY_NONE);
-
-        final WifiEntry eapWifiEntry = mock(WifiEntry.class);
-        when(eapWifiEntry.getTitle()).thenReturn(TEST_SSID);
-        when(eapWifiEntry.getSecurity()).thenReturn(WifiEntry.SECURITY_EAP);
-
-        final WifiEntry wepWifiEntry = mock(WifiEntry.class);
-        when(wepWifiEntry.getTitle()).thenReturn(TEST_SSID);
-        when(wepWifiEntry.getSecurity()).thenReturn(WifiEntry.SECURITY_WEP);
-
-        // Return a different security state each time getWifiEntries is invoked
-        when(mWifiTracker.getWifiEntries())
-                .thenReturn(Lists.newArrayList(openWifiEntry))
-                .thenReturn(Lists.newArrayList(eapWifiEntry))
-                .thenReturn(Lists.newArrayList(wepWifiEntry));
-
-        launchActivity();
-
-        ThreadUtils.postOnMainThread(() -> mWifiListener.onWifiEntriesChanged());
-        mDevice.waitForIdle();
-        onView(withText(TEST_SSID)).check(matches(isDisplayed()));
-
-        ThreadUtils.postOnMainThread(() -> mWifiListener.onWifiEntriesChanged());
-        mDevice.waitForIdle();
-        onView(withText(TEST_SSID)).check(matches(isDisplayed()));
-
-        ThreadUtils.postOnMainThread(() -> mWifiListener.onWifiEntriesChanged());
-        mDevice.waitForIdle();
-        onView(withText(TEST_SSID)).check(matches(isDisplayed()));
-    }
-}
diff --git a/tests/unit/src/com/android/settings/wifi/dpp/WifiDppChooseSavedWifiNetworkFragmentTest.java b/tests/unit/src/com/android/settings/wifi/dpp/WifiDppChooseSavedWifiNetworkFragmentTest.java
deleted file mode 100644
index 33491b6..0000000
--- a/tests/unit/src/com/android/settings/wifi/dpp/WifiDppChooseSavedWifiNetworkFragmentTest.java
+++ /dev/null
@@ -1,110 +0,0 @@
-/*
- * Copyright (C) 2019 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.settings.wifi.dpp;
-
-import static androidx.test.espresso.Espresso.onView;
-import static androidx.test.espresso.action.ViewActions.click;
-import static androidx.test.espresso.matcher.ViewMatchers.withText;
-
-import static com.android.settings.wifi.dpp.WifiDppUtils.TAG_FRAGMENT_ADD_DEVICE;
-import static com.android.settings.wifi.dpp.WifiDppUtils.TAG_FRAGMENT_CHOOSE_SAVED_WIFI_NETWORK;
-
-import static com.google.common.truth.Truth.assertThat;
-
-import android.app.Activity;
-import android.content.Context;
-import android.content.Intent;
-import android.net.Uri;
-
-import android.provider.Settings;
-import androidx.fragment.app.FragmentManager;
-import androidx.test.InstrumentationRegistry;
-import androidx.test.rule.ActivityTestRule;
-import androidx.test.runner.AndroidJUnit4;
-
-import org.junit.Before;
-import org.junit.Rule;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-
-@RunWith(AndroidJUnit4.class)
-public class WifiDppChooseSavedWifiNetworkFragmentTest {
-    // Valid Wi-Fi DPP QR code
-    private static final String VALID_WIFI_DPP_QR_CODE = "DPP:I:SN=4774LH2b4044;M:010203040506;K:"
-            + "MDkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDIgADURzxmttZoIRIPWGoQMV00XHWCAQIhXruVWOz0NjlkIA=;;";
-
-    // Keys used to lookup resources by name (see the resourceId/resourceString helper methods).
-    private static final String STRING = "string";
-    private static final String WIFI_DPP_CHOOSE_DIFFERENT_NETWORK =
-            "wifi_dpp_choose_different_network";
-    private static final String CANCEL = "cancel";
-
-    @Rule
-    public final ActivityTestRule<WifiDppConfiguratorActivity> mActivityRule =
-            new ActivityTestRule<>(WifiDppConfiguratorActivity.class, /* initialTouchMode */true,
-            /* launchActivity */ false);
-
-    private Context mContext;
-
-    @Before
-    public void setUp() {
-        mContext = InstrumentationRegistry.getTargetContext();
-    }
-
-    @Test
-    public void clickCancelButton_configuratorQrCodeScannerIntent_shouldPopBackStack() {
-        final Intent intent =
-                new Intent(WifiDppConfiguratorActivity.ACTION_CONFIGURATOR_QR_CODE_SCANNER);
-        intent.putExtra(WifiDppUtils.EXTRA_WIFI_SECURITY, "WEP");
-        intent.putExtra(WifiDppUtils.EXTRA_WIFI_SSID, "GoogleGuest");
-        intent.putExtra(WifiDppUtils.EXTRA_WIFI_PRE_SHARED_KEY, "password");
-        final WifiDppConfiguratorActivity hostActivity = mActivityRule.launchActivity(intent);
-
-        // Go to WifiDppChooseSavedWifiNetworkFragment and click the cancel button
-        final FragmentManager fragmentManager = hostActivity.getSupportFragmentManager();
-        final WifiQrCode wifiQrCode = new WifiQrCode(VALID_WIFI_DPP_QR_CODE);
-        hostActivity.runOnUiThread(() ->
-            ((WifiDppConfiguratorActivity)hostActivity).onScanWifiDppSuccess(wifiQrCode)
-        );
-        onView(withText(resourceString(WIFI_DPP_CHOOSE_DIFFERENT_NETWORK))).perform(click());
-        onView(withText(resourceString(CANCEL))).perform(click());
-
-        assertThat(fragmentManager.findFragmentByTag(TAG_FRAGMENT_ADD_DEVICE)).isNotNull();
-        assertThat(fragmentManager.findFragmentByTag(TAG_FRAGMENT_CHOOSE_SAVED_WIFI_NETWORK))
-                .isNull();
-    }
-
-    @Test
-    public void clickCancelButton_processWifiDppQrCodeIntent_shouldFinish() {
-        final Intent intent = new Intent(Settings.ACTION_PROCESS_WIFI_EASY_CONNECT_URI);
-        intent.setData(Uri.parse(VALID_WIFI_DPP_QR_CODE));
-        final WifiDppConfiguratorActivity hostActivity = mActivityRule.launchActivity(intent);
-
-        onView(withText(resourceString(CANCEL))).perform(click());
-
-        assertThat(hostActivity.isFinishing()).isEqualTo(true);
-    }
-
-    private int resourceId(String type, String name) {
-        return mContext.getResources().getIdentifier(name, type, mContext.getPackageName());
-    }
-
-    /** Similar to {@link #resourceId}, but for accessing R.string.<name> values. */
-    private String resourceString(String name) {
-        return mContext.getResources().getString(resourceId(STRING, name));
-    }
-}
diff --git a/tests/unit/src/com/android/settings/wifi/dpp/WifiDppConfiguratorActivityTest.java b/tests/unit/src/com/android/settings/wifi/dpp/WifiDppConfiguratorActivityTest.java
deleted file mode 100644
index 7c87e7d..0000000
--- a/tests/unit/src/com/android/settings/wifi/dpp/WifiDppConfiguratorActivityTest.java
+++ /dev/null
@@ -1,183 +0,0 @@
-/*
- * Copyright (C) 2018 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.settings.wifi.dpp;
-
-import static com.google.common.truth.Truth.assertThat;
-
-import android.app.Instrumentation;
-import android.content.Intent;
-import android.content.pm.ActivityInfo;
-import android.net.Uri;
-import android.os.RemoteException;
-import android.provider.Settings;
-import android.support.test.uiautomator.UiDevice;
-
-import androidx.fragment.app.FragmentManager;
-import androidx.test.InstrumentationRegistry;
-import androidx.test.rule.ActivityTestRule;
-import androidx.test.runner.AndroidJUnit4;
-
-import com.google.android.setupdesign.GlifLayout;
-
-import org.junit.Before;
-import org.junit.Rule;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-
-@RunWith(AndroidJUnit4.class)
-public class WifiDppConfiguratorActivityTest {
-    // Valid Wi-Fi DPP QR code & it's parameters
-    private static final String VALID_WIFI_DPP_QR_CODE = "DPP:I:SN=4774LH2b4044;M:010203040506;K:"
-            + "MDkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDIgADURzxmttZoIRIPWGoQMV00XHWCAQIhXruVWOz0NjlkIA=;;";
-
-    @Rule
-    public final ActivityTestRule<WifiDppConfiguratorActivity> mActivityRule =
-            new ActivityTestRule<>(WifiDppConfiguratorActivity.class);
-
-    private UiDevice mDevice;
-
-    @Before
-    public void setUp() {
-        mDevice = UiDevice.getInstance(InstrumentationRegistry.getInstrumentation());
-    }
-
-    @Test
-    public void launchActivity_qrCodeScanner_shouldNotAutoFinish() {
-        Intent intent = new Intent(WifiDppConfiguratorActivity.ACTION_CONFIGURATOR_QR_CODE_SCANNER);
-        intent.putExtra(WifiDppUtils.EXTRA_WIFI_SECURITY, "WEP");
-        intent.putExtra(WifiDppUtils.EXTRA_WIFI_SSID, "GoogleGuest");
-        intent.putExtra(WifiDppUtils.EXTRA_WIFI_PRE_SHARED_KEY, "password");
-
-        mActivityRule.launchActivity(intent);
-        FragmentManager fragmentManager = mActivityRule.getActivity().getSupportFragmentManager();
-        WifiDppQrCodeScannerFragment fragment =
-                (WifiDppQrCodeScannerFragment) fragmentManager.findFragmentByTag(
-                        WifiDppUtils.TAG_FRAGMENT_QR_CODE_SCANNER);
-
-        assertThat(fragment.getView() instanceof GlifLayout).isTrue();
-        assertThat(mActivityRule.getActivity().isFinishing()).isFalse();
-    }
-
-    @Test
-    public void launchActivity_qrCodeGenerator_shouldNotAutoFinish() {
-        Intent intent = new Intent(
-                WifiDppConfiguratorActivity.ACTION_CONFIGURATOR_QR_CODE_GENERATOR);
-        intent.putExtra(WifiDppUtils.EXTRA_WIFI_SECURITY, "WEP");
-        intent.putExtra(WifiDppUtils.EXTRA_WIFI_SSID, "GoogleGuest");
-        intent.putExtra(WifiDppUtils.EXTRA_WIFI_PRE_SHARED_KEY, "password");
-
-        mActivityRule.launchActivity(intent);
-        FragmentManager fragmentManager = mActivityRule.getActivity().getSupportFragmentManager();
-        WifiDppQrCodeGeneratorFragment fragment =
-                (WifiDppQrCodeGeneratorFragment) fragmentManager.findFragmentByTag(
-                        WifiDppUtils.TAG_FRAGMENT_QR_CODE_GENERATOR);
-
-        assertThat(fragment.getView() instanceof GlifLayout).isTrue();
-        assertThat(mActivityRule.getActivity().isFinishing()).isFalse();
-    }
-
-    @Test
-    public void launchActivity_chooseSavedWifiNetwork_shouldNotAutoFinish() {
-        final Intent intent = new Intent(Settings.ACTION_PROCESS_WIFI_EASY_CONNECT_URI);
-        intent.setData(Uri.parse(VALID_WIFI_DPP_QR_CODE));
-
-        mActivityRule.launchActivity(intent);
-
-        assertThat(mActivityRule.getActivity().isFinishing()).isFalse();
-    }
-
-    @Test
-    public void testActivity_shouldImplementsWifiNetworkConfigRetriever() {
-        WifiDppConfiguratorActivity activity = mActivityRule.getActivity();
-
-        assertThat(activity instanceof WifiNetworkConfig.Retriever).isTrue();
-    }
-
-    @Test
-    public void testActivity_shouldImplementsOnScanWifiDppSuccessCallback() {
-        WifiDppConfiguratorActivity activity = mActivityRule.getActivity();
-
-        assertThat(activity instanceof WifiDppQrCodeScannerFragment
-                .OnScanWifiDppSuccessListener).isTrue();
-    }
-
-    @Test
-    public void testActivity_shouldImplementsOnClickChooseDifferentNetworkCallback() {
-        WifiDppConfiguratorActivity activity = mActivityRule.getActivity();
-
-        assertThat(activity instanceof WifiDppAddDeviceFragment
-                .OnClickChooseDifferentNetworkListener).isTrue();
-    }
-
-    @Test
-    public void rotateScreen_shouldGetCorrectWifiDppQrCode() {
-        WifiQrCode wifiQrCode = new WifiQrCode(VALID_WIFI_DPP_QR_CODE);
-        Intent intent = new Intent(WifiDppConfiguratorActivity.ACTION_CONFIGURATOR_QR_CODE_SCANNER);
-        intent.putExtra(WifiDppUtils.EXTRA_WIFI_SECURITY, "WEP");
-        intent.putExtra(WifiDppUtils.EXTRA_WIFI_SSID, "GoogleGuest");
-        intent.putExtra(WifiDppUtils.EXTRA_WIFI_PRE_SHARED_KEY, "password");
-
-        // setWifiDppQrCode and check if getWifiDppQrCode correctly after rotation
-        mActivityRule.launchActivity(intent);
-        mActivityRule.getActivity().setWifiDppQrCode(wifiQrCode);
-
-        try {
-            mDevice.setOrientationLeft();
-            mDevice.setOrientationNatural();
-            mDevice.setOrientationRight();
-            mDevice.setOrientationNatural();
-        } catch (RemoteException e) {
-            throw new RuntimeException(e);
-        }
-
-        WifiQrCode restoredWifiDppQrCode = mActivityRule.getActivity().getWifiDppQrCode();
-        assertThat(restoredWifiDppQrCode).isNotNull();
-        assertThat(restoredWifiDppQrCode.getQrCode()).isEqualTo(VALID_WIFI_DPP_QR_CODE);
-    }
-
-    @Test
-    public void rotateScreen_shouldGetCorrectWifiNetworkConfig() {
-        final WifiNetworkConfig wifiNetworkConfig = new WifiNetworkConfig("WPA", "WifiSsid",
-                "password", /* hiddenSsid */ false, /* networkId */ 0, /* isHotspot */ true);
-        final Intent intent = new Intent(Settings.ACTION_PROCESS_WIFI_EASY_CONNECT_URI);
-        intent.setData(Uri.parse(VALID_WIFI_DPP_QR_CODE));
-
-        // setWifiNetworkConfig and check if getWifiNetworkConfig correctly after rotation
-        mActivityRule.launchActivity(intent);
-        mActivityRule.getActivity().setWifiNetworkConfig(wifiNetworkConfig);
-
-        try {
-            mDevice.setOrientationLeft();
-            mDevice.setOrientationNatural();
-            mDevice.setOrientationRight();
-            mDevice.setOrientationNatural();
-        } catch (RemoteException e) {
-            throw new RuntimeException(e);
-        }
-
-        WifiNetworkConfig restoredWifiNetworkConfig =
-                mActivityRule.getActivity().getWifiNetworkConfig();
-
-        assertThat(restoredWifiNetworkConfig).isNotNull();
-        assertThat(restoredWifiNetworkConfig.getSecurity()).isEqualTo("WPA");
-        assertThat(restoredWifiNetworkConfig.getSsid()).isEqualTo("WifiSsid");
-        assertThat(restoredWifiNetworkConfig.getPreSharedKey()).isEqualTo("password");
-        assertThat(restoredWifiNetworkConfig.getHiddenSsid()).isFalse();
-        assertThat(restoredWifiNetworkConfig.getNetworkId()).isEqualTo(0);
-        assertThat(restoredWifiNetworkConfig.isHotspot()).isTrue();
-    }
-}
diff --git a/tests/unit/src/com/android/settings/wifi/dpp/WifiDppEnrolleeActivityTest.java b/tests/unit/src/com/android/settings/wifi/dpp/WifiDppEnrolleeActivityTest.java
deleted file mode 100644
index aef4767..0000000
--- a/tests/unit/src/com/android/settings/wifi/dpp/WifiDppEnrolleeActivityTest.java
+++ /dev/null
@@ -1,41 +0,0 @@
-/*
- * Copyright (C) 2018 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.settings.wifi.dpp;
-
-import static com.google.common.truth.Truth.assertThat;
-
-import androidx.test.rule.ActivityTestRule;
-import androidx.test.runner.AndroidJUnit4;
-
-import org.junit.Rule;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-
-@RunWith(AndroidJUnit4.class)
-public class WifiDppEnrolleeActivityTest {
-    @Rule
-    public final ActivityTestRule<WifiDppEnrolleeActivity> mActivityRule =
-            new ActivityTestRule<>(WifiDppEnrolleeActivity.class);
-
-    @Test
-    public void testActivity_shouldImplementsOnScanWifiDppSuccessCallback() {
-        WifiDppEnrolleeActivity activity = mActivityRule.getActivity();
-
-        assertThat(activity instanceof WifiDppQrCodeScannerFragment
-                .OnScanWifiDppSuccessListener).isEqualTo(true);
-    }
-}
diff --git a/tests/unit/src/com/android/settings/wifi/dpp/WifiDppQrCodeGeneratorFragmentTest.java b/tests/unit/src/com/android/settings/wifi/dpp/WifiDppQrCodeGeneratorFragmentTest.java
deleted file mode 100644
index 239f525..0000000
--- a/tests/unit/src/com/android/settings/wifi/dpp/WifiDppQrCodeGeneratorFragmentTest.java
+++ /dev/null
@@ -1,52 +0,0 @@
-/*
- * Copyright (C) 2018 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.settings.wifi.dpp;
-
-import android.content.Intent;
-import android.content.pm.ActivityInfo;
-
-import androidx.test.rule.ActivityTestRule;
-import androidx.test.runner.AndroidJUnit4;
-
-import org.junit.Before;
-import org.junit.Rule;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-
-@RunWith(AndroidJUnit4.class)
-public class WifiDppQrCodeGeneratorFragmentTest {
-    @Rule
-    public final ActivityTestRule<WifiDppConfiguratorActivity> mActivityRule =
-            new ActivityTestRule<>(WifiDppConfiguratorActivity.class, true);
-
-    @Before
-    public void setUp() {
-        Intent intent =
-                new Intent(WifiDppConfiguratorActivity.ACTION_CONFIGURATOR_QR_CODE_GENERATOR);
-        intent.putExtra(WifiDppUtils.EXTRA_WIFI_SECURITY, "WEP");
-        intent.putExtra(WifiDppUtils.EXTRA_WIFI_SSID, "GoogleGuest");
-        mActivityRule.launchActivity(intent);
-    }
-
-    @Test
-    public void rotateScreen_shouldNotCrash() {
-        mActivityRule.getActivity().setRequestedOrientation(
-                ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);
-        mActivityRule.getActivity().setRequestedOrientation(
-                ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
-    }
-}
diff --git a/tests/unit/src/com/android/settings/wifi/dpp/WifiDppQrCodeScannerFragmentTest.java b/tests/unit/src/com/android/settings/wifi/dpp/WifiDppQrCodeScannerFragmentTest.java
deleted file mode 100644
index d633689..0000000
--- a/tests/unit/src/com/android/settings/wifi/dpp/WifiDppQrCodeScannerFragmentTest.java
+++ /dev/null
@@ -1,76 +0,0 @@
-/*
- * Copyright (C) 2018 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.settings.wifi.dpp;
-
-import static com.android.settings.wifi.dpp.WifiDppUtils.TAG_FRAGMENT_QR_CODE_SCANNER;
-
-import static com.google.common.truth.Truth.assertThat;
-
-import android.app.Instrumentation;
-import android.content.Intent;
-import android.content.pm.ActivityInfo;
-
-import androidx.fragment.app.FragmentManager;
-import androidx.test.InstrumentationRegistry;
-import androidx.test.rule.ActivityTestRule;
-import androidx.test.runner.AndroidJUnit4;
-
-import org.junit.Before;
-import org.junit.Rule;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-
-@RunWith(AndroidJUnit4.class)
-public class WifiDppQrCodeScannerFragmentTest {
-    @Rule
-    public final ActivityTestRule<WifiDppConfiguratorActivity> mActivityRule =
-            new ActivityTestRule<>(WifiDppConfiguratorActivity.class, true);
-
-    @Before
-    public void setUp() {
-        Intent intent = new Intent(WifiDppConfiguratorActivity.ACTION_CONFIGURATOR_QR_CODE_SCANNER);
-        intent.putExtra(WifiDppUtils.EXTRA_WIFI_SECURITY, "WEP");
-        intent.putExtra(WifiDppUtils.EXTRA_WIFI_SSID, "GoogleGuest");
-        intent.putExtra(WifiDppUtils.EXTRA_WIFI_PRE_SHARED_KEY, "password");
-        mActivityRule.launchActivity(intent);
-    }
-
-    @Test
-    public void rotateScreen_shouldNotCrash() {
-        mActivityRule.getActivity().setRequestedOrientation(
-                ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);
-        mActivityRule.getActivity().setRequestedOrientation(
-                ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
-    }
-
-    @Test
-    public void onPause_shouldNotDecodeQrCode() {
-        final WifiDppConfiguratorActivity hostActivity =
-                (WifiDppConfiguratorActivity) mActivityRule.getActivity();
-        final FragmentManager fragmentManager = hostActivity.getSupportFragmentManager();
-        final WifiDppQrCodeScannerFragment scannerFragment =
-                (WifiDppQrCodeScannerFragment) fragmentManager
-                .findFragmentByTag(TAG_FRAGMENT_QR_CODE_SCANNER);
-        final Instrumentation instrumentation = InstrumentationRegistry.getInstrumentation();
-
-        instrumentation.runOnMainSync(() -> {
-            instrumentation.callActivityOnPause(hostActivity);
-
-            assertThat(scannerFragment.isDecodeTaskAlive()).isEqualTo(false);
-        });
-    }
-}
diff --git a/tests/unit/src/com/android/settings/wifi/dpp/WifiQrCodeTest.java b/tests/unit/src/com/android/settings/wifi/dpp/WifiQrCodeTest.java
deleted file mode 100644
index e4d3a7b..0000000
--- a/tests/unit/src/com/android/settings/wifi/dpp/WifiQrCodeTest.java
+++ /dev/null
@@ -1,254 +0,0 @@
-/*
- * Copyright (C) 2018 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.settings.wifi.dpp;
-
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertNotNull;
-import static org.junit.Assert.assertNull;
-import static org.junit.Assert.fail;
-
-import androidx.test.filters.SmallTest;
-import androidx.test.runner.AndroidJUnit4;
-
-import org.junit.Test;
-import org.junit.runner.RunWith;
-
-@SmallTest
-@RunWith(AndroidJUnit4.class)
-public class WifiQrCodeTest {
-    // Valid Wi-Fi DPP QR code & it's parameters
-    private static final String VALID_WIFI_DPP_QR_CODE = "DPP:I:SN=4774LH2b4044;M:010203040506;K:"
-            + "MDkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDIgADURzxmttZoIRIPWGoQMV00XHWCAQIhXruVWOz0NjlkIA=;;";
-
-    private static final String PUBLIC_KEY_OF_VALID_WIFI_DPP_QR_CODE =
-            "MDkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDIgADURzxmttZoIRIPWGoQMV00XHWCAQIhXruVWOz0NjlkIA=";
-
-    private static final String INFORMATION_OF_VALID_WIFI_DPP_QR_CODE =
-            "SN=4774LH2b4044";
-
-    // Valid ZXing reader library's Wi-Fi Network config format & it's parameters
-    private static final String VALID_ZXING_WIFI_QR_CODE_WPA =
-            "WIFI:T:WPA;S:mynetwork;P:mypass;H:true;;";
-
-     // Valid ZXing reader library's Wi-Fi Network config format - security type SAE
-    private static final String VALID_ZXING_WIFI_QR_CODE_SAE =
-            "WIFI:T:SAE;S:mynetwork;P:mypass;H:true;;";
-
-    // Valid ZXing reader library's Wi-Fi Network config format - security type nopass and no password
-    private static final String VALID_ZXING_WIFI_QR_CODE_NOPASS_AND_NO_PASSWORD =
-            "WIFI:T:nopass;S:mynetwork;;";
-
-    // Valid ZXing reader library's Wi-Fi Network config format - no security and no password
-    private static final String VALID_ZXING_WIFI_QR_CODE_NO_SECURITY_AND_NO_PASSWORD =
-            "WIFI:T:;S:mynetwork;P:;H:false;;";
-
-    private static final String SECURITY_OF_VALID_ZXING_WIFI_QR_CODE_WPA = "WPA";
-    private static final String SECURITY_OF_VALID_ZXING_WIFI_QR_CODE_SAE = "SAE";
-    private static final String SECURITY_OF_VALID_ZXING_WIFI_QR_CODE_NOPASS = "nopass";
-    private static final String SSID_OF_VALID_ZXING_WIFI_QR_CODE = "mynetwork";
-    private static final String PASSWORD_OF_VALID_ZXING_WIFI_QR_CODE = "mypass";
-
-    // Valid ZXing reader library's Wi-Fi Network config format - escaped characters
-    private static final String VALID_ZXING_WIFI_QR_CODE_SPECIAL_CHARACTERS =
-            "WIFI:T:WPA;S:mynetwork;P:m\\;y\\:p\\\\a\\,ss;H:true;;";
-
-    private static final String PASSWORD_OF_VALID_ZXING_WIFI_QR_CODE_SPECIAL_CHARACTERS =
-            "m;y:p\\a,ss";
-
-    // Invalid scheme QR code
-    private static final String INVALID_SCHEME_QR_CODE = "BT:T:WPA;S:mynetwork;P:mypass;H:true;;";
-
-    // Invalid Wi-Fi DPP QR code - no public key - case 1
-    private static final String INVALID_WIFI_DPP_QR_CODE_NO_PUBLIC_KEY_1 =
-            "DPP:I:SN=4774LH2b4044;M:010203040506;K:;;";
-
-    // Invalid Wi-Fi DPP QR code - no public key - case 2
-    private static final String INVALID_WIFI_DPP_QR_CODE_NO_PUBLIC_KEY_2 =
-            "DPP:I:SN=4774LH2b4044;M:010203040506;;";
-
-    // Invalid ZXing reader library's Wi-Fi Network config format - no password
-    private static final String INVALID_ZXING_WIFI_QR_CODE_NO_PASSWORD =
-            "WIFI:T:WPA;S:mynetwork;P:;;";
-
-    // Invalid ZXing reader library's Wi-Fi Network config format - no SSID
-    private static final String INVALID_ZXING_WIFI_QR_CODE_NO_SSID =
-            "WIFI:T:WPA;P:mypass;;";
-
-    @Test
-    public void parseValidWifiDppQrCode() {
-        WifiQrCode wifiQrCode = new WifiQrCode(VALID_WIFI_DPP_QR_CODE);
-
-        assertEquals(WifiQrCode.SCHEME_DPP, wifiQrCode.getScheme());
-        assertEquals(PUBLIC_KEY_OF_VALID_WIFI_DPP_QR_CODE, wifiQrCode.getPublicKey());
-        assertEquals(INFORMATION_OF_VALID_WIFI_DPP_QR_CODE, wifiQrCode.getInformation());
-    }
-
-    @Test
-    public void parseValidZxingWifiQrCode() {
-        WifiQrCode wifiQrCode = new WifiQrCode(VALID_ZXING_WIFI_QR_CODE_WPA);
-        WifiNetworkConfig config = wifiQrCode.getWifiNetworkConfig();
-
-        assertEquals(WifiQrCode.SCHEME_ZXING_WIFI_NETWORK_CONFIG, wifiQrCode.getScheme());
-        assertNotNull(config);
-        assertEquals(SECURITY_OF_VALID_ZXING_WIFI_QR_CODE_WPA, config.getSecurity());
-        assertEquals(SSID_OF_VALID_ZXING_WIFI_QR_CODE, config.getSsid());
-        assertEquals(PASSWORD_OF_VALID_ZXING_WIFI_QR_CODE, config.getPreSharedKey());
-        assertEquals(true, config.getHiddenSsid());
-    }
-
-    @Test
-    public void parseValidZxingWifiQrCodeSae() {
-        WifiQrCode wifiQrCode = new WifiQrCode(VALID_ZXING_WIFI_QR_CODE_SAE);
-        WifiNetworkConfig config = wifiQrCode.getWifiNetworkConfig();
-
-        assertEquals(WifiQrCode.SCHEME_ZXING_WIFI_NETWORK_CONFIG, wifiQrCode.getScheme());
-        assertNotNull(config);
-        assertEquals(SECURITY_OF_VALID_ZXING_WIFI_QR_CODE_SAE, config.getSecurity());
-        assertEquals(SSID_OF_VALID_ZXING_WIFI_QR_CODE, config.getSsid());
-        assertEquals(PASSWORD_OF_VALID_ZXING_WIFI_QR_CODE, config.getPreSharedKey());
-        assertEquals(true, config.getHiddenSsid());
-    }
-
-    @Test
-    public void parseValidZxingWifiQrCode_noPass_and_no_password() {
-        WifiQrCode wifiQrCode = new WifiQrCode(VALID_ZXING_WIFI_QR_CODE_NOPASS_AND_NO_PASSWORD);
-        WifiNetworkConfig config = wifiQrCode.getWifiNetworkConfig();
-
-        assertEquals(WifiQrCode.SCHEME_ZXING_WIFI_NETWORK_CONFIG, wifiQrCode.getScheme());
-        assertNotNull(config);
-        assertEquals(SECURITY_OF_VALID_ZXING_WIFI_QR_CODE_NOPASS, config.getSecurity());
-        assertEquals(SSID_OF_VALID_ZXING_WIFI_QR_CODE, config.getSsid());
-        assertNull(config.getPreSharedKey());
-        assertEquals(false, config.getHiddenSsid());
-    }
-
-    @Test
-    public void parseValidZxingWifiQrCode_no_security_and_no_password() {
-        WifiQrCode wifiQrCode = new WifiQrCode(VALID_ZXING_WIFI_QR_CODE_NO_SECURITY_AND_NO_PASSWORD);
-        WifiNetworkConfig config = wifiQrCode.getWifiNetworkConfig();
-
-        assertEquals(WifiQrCode.SCHEME_ZXING_WIFI_NETWORK_CONFIG, wifiQrCode.getScheme());
-        assertNotNull(config);
-        assertEquals("", config.getSecurity());
-        assertEquals(SSID_OF_VALID_ZXING_WIFI_QR_CODE, config.getSsid());
-        assertEquals("", config.getPreSharedKey());
-        assertEquals(false, config.getHiddenSsid());
-    }
-
-    @Test
-    public void parseValidZxingWifiQrCode_specialCharacters() {
-        WifiQrCode wifiQrCode = new WifiQrCode(VALID_ZXING_WIFI_QR_CODE_SPECIAL_CHARACTERS);
-        WifiNetworkConfig config = wifiQrCode.getWifiNetworkConfig();
-
-        assertEquals(WifiQrCode.SCHEME_ZXING_WIFI_NETWORK_CONFIG, wifiQrCode.getScheme());
-        assertNotNull(config);
-        assertEquals(SECURITY_OF_VALID_ZXING_WIFI_QR_CODE_WPA, config.getSecurity());
-        assertEquals(SSID_OF_VALID_ZXING_WIFI_QR_CODE, config.getSsid());
-        assertEquals(PASSWORD_OF_VALID_ZXING_WIFI_QR_CODE_SPECIAL_CHARACTERS,
-                config.getPreSharedKey());
-        assertEquals(true, config.getHiddenSsid());
-    }
-
-    @Test
-    public void testRemoveBackSlash() {
-        WifiQrCode wifiQrCode = new WifiQrCode(VALID_WIFI_DPP_QR_CODE);
-
-        assertEquals("\\", wifiQrCode.removeBackSlash("\\\\"));
-        assertEquals("ab", wifiQrCode.removeBackSlash("a\\b"));
-        assertEquals("a", wifiQrCode.removeBackSlash("\\a"));
-        assertEquals("\\b", wifiQrCode.removeBackSlash("\\\\b"));
-        assertEquals("c\\", wifiQrCode.removeBackSlash("c\\\\"));
-    }
-
-    @Test
-    public void parseEmptyQrCode_shouldThrowIllegalArgumentException() {
-        try {
-            new WifiQrCode(null);
-            fail("Null QR code");
-        } catch (IllegalArgumentException e) {
-            // Do nothing
-        }
-
-        try {
-            new WifiQrCode("");
-            fail("Empty string QR code");
-        } catch (IllegalArgumentException e) {
-            // Do nothing
-        }
-
-        try {
-            new WifiQrCode("DPP:;");
-            fail("Empty content WIFI DPP QR code");
-        } catch (IllegalArgumentException e) {
-            // Do nothing
-        }
-
-        try {
-            new WifiQrCode("WIFI:;");
-            fail("Empty content ZXing WIFI QR code");
-        } catch (IllegalArgumentException e) {
-            // Do nothing
-        }
-    }
-
-    @Test
-    public void parseInvalidSchemeQrCode_shouldThrowIllegalArgumentException() {
-        try {
-            new WifiQrCode(INVALID_SCHEME_QR_CODE);
-            fail("Invalid scheme");
-        } catch (IllegalArgumentException e) {
-            // Do nothing
-        }
-    }
-
-    @Test
-    public void parseInvalidWifiDppQrCode_noPublicKey_shouldThrowIllegalArgumentException() {
-        try {
-            new WifiQrCode(INVALID_WIFI_DPP_QR_CODE_NO_PUBLIC_KEY_1);
-            fail("No public key case 1");
-        } catch (IllegalArgumentException e) {
-            // Do nothing
-        }
-
-        try {
-            new WifiQrCode(INVALID_WIFI_DPP_QR_CODE_NO_PUBLIC_KEY_2);
-            fail("No public key case 2");
-        } catch (IllegalArgumentException e) {
-            // Do nothing
-        }
-    }
-
-    @Test
-    public void parseInvalidZxingWifiQrCode_noPassword_shouldThrowIllegalArgumentException() {
-        try {
-            new WifiQrCode(INVALID_ZXING_WIFI_QR_CODE_NO_PASSWORD);
-            fail("No password");
-        } catch (IllegalArgumentException e) {
-            // Do nothing
-        }
-    }
-
-    @Test
-    public void parseInvalidZxingWifiQrCode_noSsid_shouldThrowIllegalArgumentException() {
-        try {
-            new WifiQrCode(INVALID_ZXING_WIFI_QR_CODE_NO_SSID);
-            fail("No SSID");
-        } catch (IllegalArgumentException e) {
-            // Do nothing
-        }
-    }
-}
diff --git a/tests/unit/src/com/android/settings/wifi/tether/TetherServiceTest.java b/tests/unit/src/com/android/settings/wifi/tether/TetherServiceTest.java
deleted file mode 100644
index 9d9cc34..0000000
--- a/tests/unit/src/com/android/settings/wifi/tether/TetherServiceTest.java
+++ /dev/null
@@ -1,396 +0,0 @@
-/*
- * Copyright (C) 2016 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.settings.wifi.tether;
-
-import static android.net.TetheringConstants.EXTRA_ADD_TETHER_TYPE;
-import static android.net.TetheringConstants.EXTRA_PROVISION_CALLBACK;
-import static android.net.TetheringConstants.EXTRA_RUN_PROVISION;
-import static android.net.TetheringManager.TETHERING_BLUETOOTH;
-import static android.net.TetheringManager.TETHERING_INVALID;
-import static android.net.TetheringManager.TETHERING_USB;
-import static android.net.TetheringManager.TETHERING_WIFI;
-import static android.net.TetheringManager.TETHER_ERROR_NO_ERROR;
-import static android.net.TetheringManager.TETHER_ERROR_PROVISIONING_FAILED;
-import static android.telephony.SubscriptionManager.INVALID_SUBSCRIPTION_ID;
-
-import static com.android.settings.wifi.tether.TetherService.EXTRA_TETHER_PROVISIONING_RESPONSE;
-import static com.android.settings.wifi.tether.TetherService.EXTRA_TETHER_SILENT_PROVISIONING_ACTION;
-import static com.android.settings.wifi.tether.TetherService.EXTRA_TETHER_SUBID;
-
-import static org.mockito.Matchers.any;
-import static org.mockito.Matchers.eq;
-import static org.mockito.Mockito.verify;
-import static org.mockito.Mockito.when;
-
-import android.app.Activity;
-import android.app.PendingIntent;
-import android.app.usage.UsageStatsManager;
-import android.content.BroadcastReceiver;
-import android.content.Context;
-import android.content.ContextWrapper;
-import android.content.Intent;
-import android.content.IntentFilter;
-import android.content.SharedPreferences;
-import android.content.SharedPreferences.Editor;
-import android.content.pm.ActivityInfo;
-import android.content.pm.ApplicationInfo;
-import android.content.pm.PackageManager;
-import android.content.pm.ResolveInfo;
-import android.net.TetheringManager;
-import android.net.wifi.WifiManager;
-import android.os.Bundle;
-import android.os.ResultReceiver;
-import android.os.SystemClock;
-import android.test.ServiceTestCase;
-import android.util.Log;
-
-import org.mockito.ArgumentCaptor;
-import org.mockito.Captor;
-import org.mockito.Mock;
-import org.mockito.MockitoAnnotations;
-
-import java.lang.ref.WeakReference;
-import java.util.ArrayList;
-import java.util.HashSet;
-import java.util.List;
-import java.util.Set;
-
-public class TetherServiceTest extends ServiceTestCase<TetherService> {
-
-    private static final String TAG = "TetherServiceTest";
-    private static final String FAKE_PACKAGE_NAME = "com.some.package.name";
-    private static final String ENTITLEMENT_PACKAGE_NAME = "com.some.entitlement.name";
-    private static final String TEST_RESPONSE_ACTION = "testProvisioningResponseAction";
-    private static final String TEST_NO_UI_ACTION = "testNoUiProvisioningRequestAction";
-    private static final int BOGUS_RECEIVER_RESULT = -5;
-    private static final int MS_PER_HOUR = 60 * 60 * 1000;
-    private static final int SHORT_TIMEOUT = 100;
-    private static final int PROVISION_TIMEOUT = 1000;
-
-    private TetherService mService;
-    private MockTetherServiceWrapper mWrapper;
-    int mLastReceiverResultCode = BOGUS_RECEIVER_RESULT;
-    private int mLastTetherRequestType = TETHERING_INVALID;
-    private int mProvisionResponse = BOGUS_RECEIVER_RESULT;
-    private ProvisionReceiver mProvisionReceiver;
-    private Receiver mResultReceiver;
-
-    @Mock private TetheringManager mTetheringManager;
-    @Mock private PackageManager mPackageManager;
-    @Mock private WifiManager mWifiManager;
-    @Mock private SharedPreferences mPrefs;
-    @Mock private Editor mPrefEditor;
-    @Captor private ArgumentCaptor<PendingIntent> mPiCaptor;
-    @Captor private ArgumentCaptor<String> mStoredTypes;
-
-    public TetherServiceTest() {
-        super(TetherService.class);
-    }
-
-    @Override
-    protected void setUp() throws Exception {
-        super.setUp();
-        MockitoAnnotations.initMocks(this);
-
-        mContext = new TestContextWrapper(getContext());
-        setContext(mContext);
-
-        mResultReceiver = new Receiver(this);
-        mLastReceiverResultCode = BOGUS_RECEIVER_RESULT;
-        mProvisionResponse = Activity.RESULT_OK;
-        mProvisionReceiver = new ProvisionReceiver();
-        IntentFilter filter = new IntentFilter(TEST_NO_UI_ACTION);
-        filter.addCategory(Intent.CATEGORY_DEFAULT);
-        mContext.registerReceiver(mProvisionReceiver, filter);
-
-        final String CURRENT_TYPES = "currentTethers";
-        when(mPrefs.getString(CURRENT_TYPES, "")).thenReturn("");
-        when(mPrefs.edit()).thenReturn(mPrefEditor);
-        when(mPrefEditor.putString(eq(CURRENT_TYPES), mStoredTypes.capture())).thenReturn(
-                mPrefEditor);
-        mWrapper = new MockTetherServiceWrapper(mContext);
-
-        ResolveInfo systemAppResolveInfo = new ResolveInfo();
-        ActivityInfo systemActivityInfo = new ActivityInfo();
-        systemActivityInfo.packageName = ENTITLEMENT_PACKAGE_NAME;
-        ApplicationInfo systemAppInfo = new ApplicationInfo();
-        systemAppInfo.flags |= ApplicationInfo.FLAG_SYSTEM;
-        systemActivityInfo.applicationInfo = systemAppInfo;
-        systemAppResolveInfo.activityInfo = systemActivityInfo;
-
-        ResolveInfo nonSystemResolveInfo = new ResolveInfo();
-        ActivityInfo nonSystemActivityInfo = new ActivityInfo();
-        nonSystemActivityInfo.packageName = FAKE_PACKAGE_NAME;
-        nonSystemActivityInfo.applicationInfo = new ApplicationInfo();
-        nonSystemResolveInfo.activityInfo = nonSystemActivityInfo;
-
-        List<ResolveInfo> resolvers = new ArrayList();
-        resolvers.add(nonSystemResolveInfo);
-        resolvers.add(systemAppResolveInfo);
-        when(mPackageManager.queryBroadcastReceivers(
-                any(Intent.class), eq(PackageManager.MATCH_ALL))).thenReturn(resolvers);
-        setupService();
-        getService().setTetherServiceWrapper(mWrapper);
-    }
-
-    @Override
-    protected void tearDown() throws Exception {
-        mContext.unregisterReceiver(mProvisionReceiver);
-        super.tearDown();
-    }
-
-    public void testStartForProvision() {
-        runProvisioningForType(TETHERING_WIFI);
-
-        assertTrue(waitForProvisionRequest(TETHERING_WIFI));
-        assertTrue(waitForProvisionResponse(TETHER_ERROR_NO_ERROR));
-    }
-
-    public void testStartKeepsProvisionAppActive() {
-        runProvisioningForType(TETHERING_WIFI);
-
-        assertTrue(waitForProvisionRequest(TETHERING_WIFI));
-        assertTrue(waitForProvisionResponse(TETHER_ERROR_NO_ERROR));
-        assertFalse(mWrapper.isAppInactive(ENTITLEMENT_PACKAGE_NAME));
-        // Non-system handler of the intent action should stay idle.
-        assertTrue(mWrapper.isAppInactive(FAKE_PACKAGE_NAME));
-    }
-
-    public void testStartMultiple() {
-        runProvisioningForType(TETHERING_WIFI);
-
-        assertTrue(waitForProvisionRequest(TETHERING_WIFI));
-        assertTrue(waitForProvisionResponse(TETHER_ERROR_NO_ERROR));
-
-        runProvisioningForType(TETHERING_USB);
-
-        assertTrue(waitForProvisionRequest(TETHERING_USB));
-        assertTrue(waitForProvisionResponse(TETHER_ERROR_NO_ERROR));
-
-        runProvisioningForType(TETHERING_BLUETOOTH);
-
-        assertTrue(waitForProvisionRequest(TETHERING_BLUETOOTH));
-        assertTrue(waitForProvisionResponse(TETHER_ERROR_NO_ERROR));
-    }
-
-    public void testPersistTypes() {
-        runProvisioningForType(TETHERING_WIFI);
-
-        waitForProvisionRequest(TETHERING_WIFI);
-        waitForProvisionResponse(TETHER_ERROR_NO_ERROR);
-
-        runProvisioningForType(TETHERING_BLUETOOTH);
-
-        waitForProvisionRequest(TETHERING_BLUETOOTH);
-        waitForProvisionResponse(TETHER_ERROR_NO_ERROR);
-
-        shutdownService();
-        assertEquals(TETHERING_WIFI + "," + TETHERING_BLUETOOTH, mStoredTypes.getValue());
-    }
-
-    public void testFailureStopsTethering_Wifi() {
-        mProvisionResponse = Activity.RESULT_CANCELED;
-
-        runProvisioningForType(TETHERING_WIFI);
-
-        assertTrue(waitForProvisionRequest(TETHERING_WIFI));
-        assertTrue(waitForProvisionResponse(TETHER_ERROR_PROVISIONING_FAILED));
-
-        verify(mTetheringManager).stopTethering(TETHERING_WIFI);
-    }
-
-    public void testFailureStopsTethering_Usb() {
-        mProvisionResponse = Activity.RESULT_CANCELED;
-
-        runProvisioningForType(TETHERING_USB);
-
-        assertTrue(waitForProvisionRequest(TETHERING_USB));
-        assertTrue(waitForProvisionResponse(TETHER_ERROR_PROVISIONING_FAILED));
-
-        verify(mTetheringManager).stopTethering(TETHERING_USB);
-    }
-
-    public void testIgnoreOutdatedRequest() {
-        Intent intent = new Intent();
-        intent.putExtra(EXTRA_ADD_TETHER_TYPE, TETHERING_WIFI);
-        intent.putExtra(EXTRA_RUN_PROVISION, true);
-        intent.putExtra(EXTRA_TETHER_SILENT_PROVISIONING_ACTION, TEST_NO_UI_ACTION);
-        intent.putExtra(EXTRA_PROVISION_CALLBACK, mResultReceiver);
-        intent.putExtra(EXTRA_TETHER_SUBID, 1 /* Tested subId number */);
-        intent.putExtra(EXTRA_TETHER_PROVISIONING_RESPONSE, TEST_RESPONSE_ACTION);
-        startService(intent);
-
-        SystemClock.sleep(PROVISION_TIMEOUT);
-        assertEquals(TETHERING_INVALID, mLastTetherRequestType);
-        assertTrue(mWrapper.isAppInactive(ENTITLEMENT_PACKAGE_NAME));
-        assertTrue(mWrapper.isAppInactive(FAKE_PACKAGE_NAME));
-    }
-
-    private void runProvisioningForType(int type) {
-        Intent intent = new Intent();
-        intent.putExtra(EXTRA_ADD_TETHER_TYPE, type);
-        intent.putExtra(EXTRA_RUN_PROVISION, true);
-        intent.putExtra(EXTRA_TETHER_SILENT_PROVISIONING_ACTION, TEST_NO_UI_ACTION);
-        intent.putExtra(EXTRA_PROVISION_CALLBACK, mResultReceiver);
-        intent.putExtra(EXTRA_TETHER_SUBID, INVALID_SUBSCRIPTION_ID);
-        intent.putExtra(EXTRA_TETHER_PROVISIONING_RESPONSE, TEST_RESPONSE_ACTION);
-        startService(intent);
-    }
-
-    private boolean waitForAppInactive(UsageStatsManager usageStatsManager, String packageName) {
-        long startTime = SystemClock.uptimeMillis();
-        while (true) {
-            if (usageStatsManager.isAppInactive(packageName)) {
-                return true;
-            }
-            if ((SystemClock.uptimeMillis() - startTime) > PROVISION_TIMEOUT) {
-                return false;
-            }
-            SystemClock.sleep(SHORT_TIMEOUT);
-        }
-    }
-
-    private boolean waitForProvisionRequest(int expectedType) {
-        long startTime = SystemClock.uptimeMillis();
-        while (true) {
-            if (mLastTetherRequestType == expectedType) {
-                mLastTetherRequestType = TETHERING_INVALID;
-                return true;
-            }
-            if ((SystemClock.uptimeMillis() - startTime) > PROVISION_TIMEOUT) {
-                Log.v(TAG, String.format(
-                        "waitForProvisionRequest timeout: expected=%d, actual=%d",
-                        expectedType, mLastTetherRequestType));
-                return false;
-            }
-            SystemClock.sleep(SHORT_TIMEOUT);
-        }
-    }
-
-    private boolean waitForProvisionResponse(int expectedValue) {
-        long startTime = SystemClock.uptimeMillis();
-        while (true) {
-            if (mLastReceiverResultCode == expectedValue) {
-                mLastReceiverResultCode = BOGUS_RECEIVER_RESULT;
-                return true;
-            }
-            if ((SystemClock.uptimeMillis() - startTime) > PROVISION_TIMEOUT) {
-                Log.v(TAG, String.format(
-                        "waitForProvisionResponse timeout: expected=%d, actual=%d",
-                        expectedValue, mLastReceiverResultCode));
-                return false;
-            }
-            SystemClock.sleep(SHORT_TIMEOUT);
-        }
-    }
-
-    private class TestContextWrapper extends ContextWrapper {
-
-        public TestContextWrapper(Context base) {
-            super(base);
-        }
-
-        @Override
-        public SharedPreferences getSharedPreferences(String name, int mode) {
-            // Stub out prefs to control the persisted tether type list.
-            if (name == "tetherPrefs") {
-                return mPrefs;
-            }
-            return super.getSharedPreferences(name, mode);
-        }
-
-        @Override
-        public PackageManager getPackageManager() {
-            return mPackageManager;
-        }
-
-        @Override
-        public Object getSystemService(String name) {
-            if (TETHERING_SERVICE.equals(name)) {
-                return mTetheringManager;
-            } else if (WIFI_SERVICE.equals(name)) {
-                return mWifiManager;
-            }
-
-            return super.getSystemService(name);
-        }
-    }
-
-    private static final class Receiver extends ResultReceiver {
-        final WeakReference<TetherServiceTest> mTest;
-
-        Receiver(TetherServiceTest test) {
-            super(null);
-            mTest = new WeakReference<TetherServiceTest>(test);
-        }
-
-        @Override
-        protected void onReceiveResult(int resultCode, Bundle resultData) {
-            TetherServiceTest test = mTest.get();
-            if (test != null) {
-                test.mLastReceiverResultCode = resultCode;
-            }
-        }
-    };
-
-    /**
-     * Stubs out the provisioning app receiver.
-     */
-    private class ProvisionReceiver extends BroadcastReceiver {
-        @Override
-        public void onReceive(Context context, Intent intent) {
-            mLastTetherRequestType = intent.getIntExtra("TETHER_TYPE", TETHERING_INVALID);
-            sendResponse(mProvisionResponse, context);
-        }
-
-        private void sendResponse(int response, Context context) {
-            Intent responseIntent = new Intent(TEST_RESPONSE_ACTION);
-            responseIntent.addFlags(Intent.FLAG_RECEIVER_INCLUDE_BACKGROUND);
-            responseIntent.putExtra(TetherService.EXTRA_RESULT, response);
-            context.sendBroadcast(
-                    responseIntent, android.Manifest.permission.TETHER_PRIVILEGED);
-        }
-    }
-
-    private static class MockTetherServiceWrapper
-            extends TetherService.TetherServiceWrapper {
-        private final Set<String> mActivePackages;
-
-        MockTetherServiceWrapper(Context context) {
-            super(context);
-            mActivePackages = new HashSet<>();
-        }
-
-        @Override
-        void setAppInactive(String packageName, boolean isInactive) {
-            if (!isInactive) {
-                mActivePackages.add(packageName);
-            } else {
-                mActivePackages.remove(packageName);
-            }
-        }
-
-        boolean isAppInactive(String packageName) {
-            return !mActivePackages.contains(packageName);
-        }
-
-        @Override
-        int getActiveDataSubscriptionId() {
-            return INVALID_SUBSCRIPTION_ID;
-        }
-    }
-}
diff --git a/tests/unit/src/com/android/settings/wifi/tether/WifiTetherSettingsTest.java b/tests/unit/src/com/android/settings/wifi/tether/WifiTetherSettingsTest.java
deleted file mode 100644
index 2de6611..0000000
--- a/tests/unit/src/com/android/settings/wifi/tether/WifiTetherSettingsTest.java
+++ /dev/null
@@ -1,81 +0,0 @@
-/*
- * Copyright (C) 2017 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.settings.wifi.tether;
-
-import static androidx.test.espresso.Espresso.onView;
-import static androidx.test.espresso.assertion.ViewAssertions.matches;
-import static androidx.test.espresso.matcher.ViewMatchers.isDisplayed;
-import static androidx.test.espresso.matcher.ViewMatchers.withText;
-
-import android.app.Instrumentation;
-import android.content.Intent;
-import android.support.test.uiautomator.By;
-import android.support.test.uiautomator.UiDevice;
-import android.support.test.uiautomator.UiObject2;
-import android.support.test.uiautomator.Until;
-
-import androidx.test.InstrumentationRegistry;
-import androidx.test.filters.SmallTest;
-import androidx.test.runner.AndroidJUnit4;
-
-import com.android.settings.Settings;
-
-import org.junit.After;
-import org.junit.Before;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-
-@RunWith(AndroidJUnit4.class)
-@SmallTest
-public class WifiTetherSettingsTest {
-
-    private static final long TIMEOUT = 2000L;
-
-    private Instrumentation mInstrumentation;
-    private Intent mTetherActivityIntent;
-    private UiDevice mDevice;
-
-    @Before
-    public void setUp() {
-        mInstrumentation = InstrumentationRegistry.getInstrumentation();
-        mDevice = UiDevice.getInstance(mInstrumentation);
-        mTetherActivityIntent = new Intent()
-                .setClassName(mInstrumentation.getTargetContext().getPackageName(),
-                        Settings.TetherSettingsActivity.class.getName())
-                .setPackage(mInstrumentation.getTargetContext().getPackageName())
-                .addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
-    }
-
-    @After
-    public void tearDown() {
-        mDevice.pressHome();
-    }
-
-    @Test
-    public void launchTetherSettings_shouldHaveAllFields() {
-        launchWifiTetherActivity();
-        onView(withText("Hotspot name")).check(matches(isDisplayed()));
-        onView(withText("Hotspot password")).check(matches(isDisplayed()));
-    }
-
-    private void launchWifiTetherActivity() {
-        mInstrumentation.startActivitySync(mTetherActivityIntent);
-        onView(withText("Wi‑Fi hotspot")).perform();
-        UiObject2 item = mDevice.wait(Until.findObject(By.text("Wi‑Fi hotspot")), TIMEOUT);
-        item.click();
-    }
-}
