Merge "DO NOT MERGE Add premium SMS access settings." into pi-car-dev
diff --git a/src/com/android/car/settings/common/BaseCarSettingsActivity.java b/src/com/android/car/settings/common/BaseCarSettingsActivity.java
new file mode 100644
index 0000000..132ee60
--- /dev/null
+++ b/src/com/android/car/settings/common/BaseCarSettingsActivity.java
@@ -0,0 +1,225 @@
+/*
+ * 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.car.settings.common;
+
+import android.car.drivingstate.CarUxRestrictions;
+import android.car.drivingstate.CarUxRestrictionsManager.OnUxRestrictionsChangedListener;
+import android.content.Context;
+import android.content.Intent;
+import android.content.IntentSender;
+import android.os.Bundle;
+import android.view.View;
+import android.view.inputmethod.InputMethodManager;
+import android.widget.Toast;
+
+import androidx.annotation.Nullable;
+import androidx.fragment.app.DialogFragment;
+import androidx.fragment.app.Fragment;
+import androidx.fragment.app.FragmentActivity;
+import androidx.fragment.app.FragmentManager.OnBackStackChangedListener;
+import androidx.preference.Preference;
+import androidx.preference.PreferenceFragmentCompat;
+
+import com.android.car.apps.common.util.Themes;
+import com.android.car.settings.R;
+
+/**
+ * Base activity class for car settings, provides a action bar with a back button that goes to
+ * previous activity.
+ */
+public abstract class BaseCarSettingsActivity extends FragmentActivity implements
+        FragmentController, OnUxRestrictionsChangedListener, UxRestrictionsProvider,
+        OnBackStackChangedListener, PreferenceFragmentCompat.OnPreferenceStartFragmentCallback {
+    private static final Logger LOG = new Logger(BaseCarSettingsActivity.class);
+
+    private CarUxRestrictionsHelper mUxRestrictionsHelper;
+    private View mRestrictedMessage;
+    // Default to minimum restriction.
+    private CarUxRestrictions mCarUxRestrictions = new CarUxRestrictions.Builder(
+            /* reqOpt= */ true,
+            CarUxRestrictions.UX_RESTRICTIONS_BASELINE,
+            /* timestamp= */ 0
+    ).build();
+
+    @Override
+    protected void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+        setContentView(R.layout.car_setting_activity);
+        if (mUxRestrictionsHelper == null) {
+            mUxRestrictionsHelper = new CarUxRestrictionsHelper(/* context= */ this, /* listener= */
+                    this);
+        }
+        mUxRestrictionsHelper.start();
+        getSupportFragmentManager().addOnBackStackChangedListener(this);
+        mRestrictedMessage = findViewById(R.id.restricted_message);
+
+        launchIfDifferent(getInitialFragment());
+    }
+
+    @Override
+    public void onDestroy() {
+        super.onDestroy();
+        mUxRestrictionsHelper.stop();
+        mUxRestrictionsHelper = null;
+    }
+
+    @Override
+    public void onBackPressed() {
+        super.onBackPressed();
+        hideKeyboard();
+        // If the backstack is empty, finish the activity.
+        if (getSupportFragmentManager().getBackStackEntryCount() == 0) {
+            finish();
+        }
+    }
+
+    @Override
+    public void launchFragment(Fragment fragment) {
+        if (fragment instanceof DialogFragment) {
+            throw new IllegalArgumentException(
+                    "cannot launch dialogs with launchFragment() - use showDialog() instead");
+        }
+
+        getSupportFragmentManager()
+                .beginTransaction()
+                .setCustomAnimations(
+                        Themes.getAttrResourceId(/* context= */ this,
+                                android.R.attr.fragmentOpenEnterAnimation),
+                        Themes.getAttrResourceId(/* context= */ this,
+                                android.R.attr.fragmentOpenExitAnimation),
+                        Themes.getAttrResourceId(/* context= */ this,
+                                android.R.attr.fragmentCloseEnterAnimation),
+                        Themes.getAttrResourceId(/* context= */ this,
+                                android.R.attr.fragmentCloseExitAnimation))
+                .replace(R.id.fragment_container, fragment,
+                        Integer.toString(getSupportFragmentManager().getBackStackEntryCount()))
+                .addToBackStack(null)
+                .commit();
+    }
+
+    @Override
+    public void goBack() {
+        onBackPressed();
+    }
+
+    @Override
+    public void showBlockingMessage() {
+        Toast.makeText(this, R.string.restricted_while_driving, Toast.LENGTH_SHORT).show();
+    }
+
+    @Override
+    public void showDialog(DialogFragment dialogFragment, @Nullable String tag) {
+        dialogFragment.show(getSupportFragmentManager(), tag);
+    }
+
+    @Override
+    @Nullable
+    public DialogFragment findDialogByTag(String tag) {
+        Fragment fragment = getSupportFragmentManager().findFragmentByTag(tag);
+        if (fragment instanceof DialogFragment) {
+            return (DialogFragment) fragment;
+        }
+        return null;
+    }
+
+    @Override
+    public void startActivityForResult(Intent intent, int requestCode,
+            ActivityResultCallback callback) {
+        throw new UnsupportedOperationException(
+                "Unimplemented for activities that implement FragmentController");
+    }
+
+    @Override
+    public void startIntentSenderForResult(IntentSender intent, int requestCode,
+            @Nullable Intent fillInIntent, int flagsMask, int flagsValues, Bundle options,
+            ActivityResultCallback callback) {
+        throw new UnsupportedOperationException(
+                "Unimplemented for activities that implement FragmentController");
+    }
+
+    @Override
+    public void onUxRestrictionsChanged(CarUxRestrictions restrictionInfo) {
+        mCarUxRestrictions = restrictionInfo;
+        Fragment currentFragment = getCurrentFragment();
+        if (currentFragment instanceof OnUxRestrictionsChangedListener) {
+            ((OnUxRestrictionsChangedListener) currentFragment)
+                    .onUxRestrictionsChanged(restrictionInfo);
+        }
+        updateBlockingView(currentFragment);
+    }
+
+    @Override
+    public CarUxRestrictions getCarUxRestrictions() {
+        return mCarUxRestrictions;
+    }
+
+    @Override
+    public void onBackStackChanged() {
+        updateBlockingView(getCurrentFragment());
+    }
+
+    @Override
+    public boolean onPreferenceStartFragment(PreferenceFragmentCompat caller, Preference pref) {
+        if (pref.getFragment() != null) {
+            Fragment fragment = Fragment.instantiate(/* context= */ this, pref.getFragment(),
+                    pref.getExtras());
+            launchFragment(fragment);
+            return true;
+        }
+        return false;
+    }
+
+    /**
+     * Gets the fragment to show onCreate. If null, the activity will not perform an initial
+     * fragment transaction.
+     */
+    @Nullable
+    protected abstract Fragment getInitialFragment();
+
+    protected void launchIfDifferent(Fragment newFragment) {
+        Fragment currentFragment = getCurrentFragment();
+        if ((newFragment != null) && differentFragment(newFragment, currentFragment)) {
+            LOG.d("launchIfDifferent: " + newFragment + " replacing " + currentFragment);
+            launchFragment(newFragment);
+        }
+    }
+
+    protected Fragment getCurrentFragment() {
+        return getSupportFragmentManager().findFragmentById(R.id.fragment_container);
+    }
+
+    /**
+     * Returns {code true} if newFragment is different from current fragment.
+     */
+    private boolean differentFragment(Fragment newFragment, Fragment currentFragment) {
+        return (currentFragment == null)
+                || (!currentFragment.getClass().equals(newFragment.getClass()));
+    }
+
+    private void hideKeyboard() {
+        InputMethodManager imm = (InputMethodManager) this.getSystemService(
+                Context.INPUT_METHOD_SERVICE);
+        imm.hideSoftInputFromWindow(getWindow().getDecorView().getWindowToken(), 0);
+    }
+
+    private void updateBlockingView(@Nullable Fragment currentFragment) {
+        if (currentFragment instanceof BaseFragment) {
+            boolean canBeShown = ((BaseFragment) currentFragment).canBeShown(mCarUxRestrictions);
+            mRestrictedMessage.setVisibility(canBeShown ? View.GONE : View.VISIBLE);
+        }
+    }
+}
diff --git a/src/com/android/car/settings/common/CarSettingActivity.java b/src/com/android/car/settings/common/CarSettingActivity.java
index f7fe3a8..1a33ccc 100644
--- a/src/com/android/car/settings/common/CarSettingActivity.java
+++ b/src/com/android/car/settings/common/CarSettingActivity.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2017 The Android Open Source Project
+ * 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.
@@ -11,71 +11,45 @@
  * 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
+ * limitations under the License.
  */
 
 package com.android.car.settings.common;
 
-import android.car.drivingstate.CarUxRestrictions;
-import android.car.drivingstate.CarUxRestrictionsManager.OnUxRestrictionsChangedListener;
-import android.content.Context;
 import android.content.Intent;
-import android.content.IntentSender;
 import android.os.Bundle;
-import android.view.View;
-import android.view.inputmethod.InputMethodManager;
-import android.widget.Toast;
 
 import androidx.annotation.Nullable;
-import androidx.fragment.app.DialogFragment;
 import androidx.fragment.app.Fragment;
-import androidx.fragment.app.FragmentActivity;
 import androidx.fragment.app.FragmentManager;
-import androidx.fragment.app.FragmentManager.OnBackStackChangedListener;
-import androidx.preference.Preference;
-import androidx.preference.PreferenceFragmentCompat;
 
-import com.android.car.apps.common.util.Themes;
 import com.android.car.settings.R;
 
 /**
- * Base activity class for car settings, provides a action bar with a back button that goes to
- * previous activity.
+ * Root activity used for most of the Settings app. This activity provides additional functionality
+ * which handles intents.
  */
-public class CarSettingActivity extends FragmentActivity implements FragmentController,
-        OnUxRestrictionsChangedListener, UxRestrictionsProvider, OnBackStackChangedListener,
-        PreferenceFragmentCompat.OnPreferenceStartFragmentCallback {
+public class CarSettingActivity extends BaseCarSettingsActivity {
+
     private static final Logger LOG = new Logger(CarSettingActivity.class);
 
     private static final String KEY_HAS_NEW_INTENT =
             "com.android.car.settings.common.CarSettingActivity.KEY_HAS_NEW_INTENT";
 
     private boolean mHasNewIntent = true;
-    private CarUxRestrictionsHelper mUxRestrictionsHelper;
-    private View mRestrictedMessage;
-    // Default to minimum restriction.
-    private CarUxRestrictions mCarUxRestrictions = new CarUxRestrictions.Builder(
-            /* reqOpt= */ true,
-            CarUxRestrictions.UX_RESTRICTIONS_BASELINE,
-            /* timestamp= */ 0
-    ).build();
 
     @Override
     protected void onCreate(Bundle savedInstanceState) {
         super.onCreate(savedInstanceState);
-        setContentView(R.layout.car_setting_activity);
-        if (mUxRestrictionsHelper == null) {
-            mUxRestrictionsHelper = new CarUxRestrictionsHelper(/* context= */ this, /* listener= */
-                    this);
-        }
-        mUxRestrictionsHelper.start();
-        getSupportFragmentManager().addOnBackStackChangedListener(this);
-        mRestrictedMessage = findViewById(R.id.restricted_message);
-
         if (savedInstanceState != null) {
             mHasNewIntent = savedInstanceState.getBoolean(KEY_HAS_NEW_INTENT, mHasNewIntent);
         }
-        launchIfDifferent(getFragment());
+    }
+
+    @Override
+    protected void onSaveInstanceState(Bundle outState) {
+        super.onSaveInstanceState(outState);
+        outState.putBoolean(KEY_HAS_NEW_INTENT, mHasNewIntent);
     }
 
     @Override
@@ -97,35 +71,9 @@
     }
 
     @Override
-    public void onDestroy() {
-        super.onDestroy();
-        mUxRestrictionsHelper.stop();
-        mUxRestrictionsHelper = null;
-    }
-
-    @Override
-    protected void onSaveInstanceState(Bundle outState) {
-        super.onSaveInstanceState(outState);
-        outState.putBoolean(KEY_HAS_NEW_INTENT, mHasNewIntent);
-    }
-
-    @Override
-    public void onBackPressed() {
-        super.onBackPressed();
-        hideKeyboard();
-        // if the backstack is empty, finish the activity.
-        if (getSupportFragmentManager().getBackStackEntryCount() == 0) {
-            finish();
-        }
-    }
-
-    @Override
     public void launchFragment(Fragment fragment) {
-        if (fragment instanceof DialogFragment) {
-            throw new IllegalArgumentException(
-                    "cannot launch dialogs with launchFragment() - use showDialog() instead");
-        }
-
+        // Called before super to clear the back stack if necessary before launching the fragment
+        // in question.
         if (fragment.getClass().getName().equals(
                 getString(R.string.config_settings_hierarchy_root_fragment))
                 && getSupportFragmentManager().getBackStackEntryCount() > 1) {
@@ -133,139 +81,20 @@
                     FragmentManager.POP_BACK_STACK_INCLUSIVE);
         }
 
-        getSupportFragmentManager()
-                .beginTransaction()
-                .setCustomAnimations(
-                        Themes.getAttrResourceId(/* context= */ this,
-                                android.R.attr.fragmentOpenEnterAnimation),
-                        Themes.getAttrResourceId(/* context= */ this,
-                                android.R.attr.fragmentOpenExitAnimation),
-                        Themes.getAttrResourceId(/* context= */ this,
-                                android.R.attr.fragmentCloseEnterAnimation),
-                        Themes.getAttrResourceId(/* context= */ this,
-                                android.R.attr.fragmentCloseExitAnimation))
-                .replace(R.id.fragment_container, fragment,
-                        Integer.toString(getSupportFragmentManager().getBackStackEntryCount()))
-                .addToBackStack(null)
-                .commit();
-    }
-
-    @Override
-    public void goBack() {
-        onBackPressed();
-    }
-
-    @Override
-    public void showBlockingMessage() {
-        Toast.makeText(
-                this, R.string.restricted_while_driving, Toast.LENGTH_SHORT).show();
-    }
-
-    @Override
-    public void showDialog(DialogFragment dialogFragment, @Nullable String tag) {
-        dialogFragment.show(getSupportFragmentManager(), tag);
-    }
-
-    @Override
-    @Nullable
-    public DialogFragment findDialogByTag(String tag) {
-        Fragment fragment = getSupportFragmentManager().findFragmentByTag(tag);
-        if (fragment instanceof DialogFragment) {
-            return (DialogFragment) fragment;
-        }
-        return null;
-    }
-
-    @Override
-    public void startActivityForResult(Intent intent, int requestCode,
-            ActivityResultCallback callback) {
-        throw new UnsupportedOperationException(
-                "Unimplemented for activities that implement FragmentController");
-    }
-
-    @Override
-    public void startIntentSenderForResult(IntentSender intent, int requestCode,
-            @Nullable Intent fillInIntent, int flagsMask, int flagsValues, Bundle options,
-            ActivityResultCallback callback) {
-        throw new UnsupportedOperationException(
-                "Unimplemented for activities that implement FragmentController");
-    }
-
-    @Override
-    public void onUxRestrictionsChanged(CarUxRestrictions restrictionInfo) {
-        mCarUxRestrictions = restrictionInfo;
-        Fragment currentFragment = getCurrentFragment();
-        if (currentFragment instanceof OnUxRestrictionsChangedListener) {
-            ((OnUxRestrictionsChangedListener) currentFragment)
-                    .onUxRestrictionsChanged(restrictionInfo);
-        }
-        updateBlockingView(currentFragment);
-    }
-
-    @Override
-    public CarUxRestrictions getCarUxRestrictions() {
-        return mCarUxRestrictions;
-    }
-
-    @Override
-    public void onBackStackChanged() {
-        updateBlockingView(getCurrentFragment());
-    }
-
-    @Override
-    public boolean onPreferenceStartFragment(PreferenceFragmentCompat caller, Preference pref) {
-        if (pref.getFragment() != null) {
-            Fragment fragment = Fragment.instantiate(/* context= */ this, pref.getFragment(),
-                    pref.getExtras());
-            launchFragment(fragment);
-            return true;
-        }
-        return false;
+        super.launchFragment(fragment);
     }
 
     /**
      * Gets the fragment to show onCreate. This will only be launched if it is different from the
      * current fragment shown.
      */
+    @Override
     @Nullable
-    protected Fragment getFragment() {
+    protected Fragment getInitialFragment() {
         if (getCurrentFragment() != null) {
             return getCurrentFragment();
         }
         return Fragment.instantiate(this,
                 getString(R.string.config_settings_hierarchy_root_fragment));
     }
-
-    private void launchIfDifferent(Fragment newFragment) {
-        Fragment currentFragment = getCurrentFragment();
-        if ((newFragment != null) && differentFragment(newFragment, currentFragment)) {
-            LOG.d("launchIfDifferent: " + newFragment + " replacing " + currentFragment);
-            launchFragment(newFragment);
-        }
-    }
-
-    /**
-     * Returns {code true} if newFragment is different from current fragment.
-     */
-    private boolean differentFragment(Fragment newFragment, Fragment currentFragment) {
-        return (currentFragment == null)
-                || (!currentFragment.getClass().equals(newFragment.getClass()));
-    }
-
-    private Fragment getCurrentFragment() {
-        return getSupportFragmentManager().findFragmentById(R.id.fragment_container);
-    }
-
-    private void hideKeyboard() {
-        InputMethodManager imm = (InputMethodManager) this.getSystemService(
-                Context.INPUT_METHOD_SERVICE);
-        imm.hideSoftInputFromWindow(getWindow().getDecorView().getWindowToken(), 0);
-    }
-
-    private void updateBlockingView(@Nullable Fragment currentFragment) {
-        if (currentFragment instanceof BaseFragment) {
-            boolean canBeShown = ((BaseFragment) currentFragment).canBeShown(mCarUxRestrictions);
-            mRestrictedMessage.setVisibility(canBeShown ? View.GONE : View.VISIBLE);
-        }
-    }
 }
diff --git a/src/com/android/car/settings/datausage/AppDataUsageFragment.java b/src/com/android/car/settings/datausage/AppDataUsageFragment.java
index b613e68..2c756e2 100644
--- a/src/com/android/car/settings/datausage/AppDataUsageFragment.java
+++ b/src/com/android/car/settings/datausage/AppDataUsageFragment.java
@@ -97,14 +97,13 @@
     @Override
     public void onCreate(Bundle savedInstanceState) {
         super.onCreate(savedInstanceState);
-        Bundle bundle = getBundleForNetworkStats();
+        mBundle = getBundleForNetworkStats();
 
         LoaderManager loaderManager = LoaderManager.getInstance(this);
-        mAppsNetworkStatsManager.startLoading(loaderManager, bundle);
+        mAppsNetworkStatsManager.startLoading(loaderManager, mBundle);
     }
 
-    @VisibleForTesting
-    Bundle getBundleForNetworkStats() {
+    private Bundle getBundleForNetworkStats() {
         long historyStart = System.currentTimeMillis();
         long historyEnd = historyStart + 1;
 
@@ -139,4 +138,9 @@
 
         return SummaryForAllUidLoader.buildArgs(mNetworkTemplate, start, end);
     }
+
+    @VisibleForTesting(otherwise = VisibleForTesting.NONE)
+    Bundle getBundle() {
+        return mBundle;
+    }
 }
diff --git a/src/com/android/car/settings/security/CheckLockActivity.java b/src/com/android/car/settings/security/CheckLockActivity.java
index 8881e31..ba1407b 100644
--- a/src/com/android/car/settings/security/CheckLockActivity.java
+++ b/src/com/android/car/settings/security/CheckLockActivity.java
@@ -23,7 +23,7 @@
 import androidx.annotation.Nullable;
 import androidx.fragment.app.Fragment;
 
-import com.android.car.settings.common.CarSettingActivity;
+import com.android.car.settings.common.BaseCarSettingsActivity;
 import com.android.car.settings.common.Logger;
 import com.android.internal.widget.LockPatternUtils;
 
@@ -31,13 +31,13 @@
  * Prompts the user to enter their pin, password, or pattern lock (if set) and returns
  * {@link #RESULT_OK} on a successful entry or immediately if the user has no lock setup.
  */
-public class CheckLockActivity extends CarSettingActivity implements CheckLockListener {
+public class CheckLockActivity extends BaseCarSettingsActivity implements CheckLockListener {
 
     private static final Logger LOG = new Logger(CheckLockActivity.class);
 
     @Override
     @Nullable
-    protected Fragment getFragment() {
+    protected Fragment getInitialFragment() {
         Fragment fragment;
         int passwordQuality = new LockPatternUtils(this).getKeyguardStoredPasswordQuality(
                 UserHandle.myUserId());
diff --git a/src/com/android/car/settings/security/SettingsScreenLockActivity.java b/src/com/android/car/settings/security/SettingsScreenLockActivity.java
index 9c48754..e9ad6fc 100644
--- a/src/com/android/car/settings/security/SettingsScreenLockActivity.java
+++ b/src/com/android/car/settings/security/SettingsScreenLockActivity.java
@@ -24,14 +24,15 @@
 import androidx.fragment.app.Fragment;
 
 import com.android.car.settings.R;
-import com.android.car.settings.common.CarSettingActivity;
+import com.android.car.settings.common.BaseCarSettingsActivity;
 import com.android.car.settings.common.Logger;
 import com.android.internal.widget.LockPatternUtils;
 
 /**
  * Activity for setting screen locks
  */
-public class SettingsScreenLockActivity extends CarSettingActivity implements CheckLockListener {
+public class SettingsScreenLockActivity extends BaseCarSettingsActivity implements
+        CheckLockListener {
 
     private static final Logger LOG = new Logger(SettingsScreenLockActivity.class);
 
@@ -39,7 +40,7 @@
 
     @Override
     @Nullable
-    protected Fragment getFragment() {
+    protected Fragment getInitialFragment() {
         mPasswordQuality = new LockPatternUtils(this).getKeyguardStoredPasswordQuality(
                 UserHandle.myUserId());
 
diff --git a/tests/robotests/src/com/android/car/settings/common/BaseCarSettingsActivityTest.java b/tests/robotests/src/com/android/car/settings/common/BaseCarSettingsActivityTest.java
new file mode 100644
index 0000000..cb83d85
--- /dev/null
+++ b/tests/robotests/src/com/android/car/settings/common/BaseCarSettingsActivityTest.java
@@ -0,0 +1,141 @@
+/*
+ * 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.car.settings.common;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+import static org.testng.Assert.assertThrows;
+
+import android.car.Car;
+import android.car.drivingstate.CarUxRestrictions;
+import android.car.drivingstate.CarUxRestrictionsManager;
+import android.content.Context;
+
+import androidx.annotation.Nullable;
+import androidx.fragment.app.DialogFragment;
+import androidx.fragment.app.Fragment;
+import androidx.preference.Preference;
+
+import com.android.car.settings.CarSettingsRobolectricTestRunner;
+import com.android.car.settings.R;
+import com.android.car.settings.testutils.ShadowCar;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
+import org.robolectric.RuntimeEnvironment;
+import org.robolectric.android.controller.ActivityController;
+
+/** Unit test for {@link BaseCarSettingsActivity}. */
+@RunWith(CarSettingsRobolectricTestRunner.class)
+public class BaseCarSettingsActivityTest {
+
+    private static final String TEST_TAG = "test_tag";
+
+    private Context mContext;
+    private ActivityController<TestBaseCarSettingsActivity> mActivityController;
+    private TestBaseCarSettingsActivity mActivity;
+
+    @Mock
+    private CarUxRestrictionsManager mMockCarUxRestrictionsManager;
+
+    @Before
+    public void setUp() throws Exception {
+        MockitoAnnotations.initMocks(this);
+        CarUxRestrictions noSetupRestrictions = new CarUxRestrictions.Builder(/* reqOpt= */ true,
+                CarUxRestrictions.UX_RESTRICTIONS_BASELINE, /* time= */ 0).build();
+        when(mMockCarUxRestrictionsManager.getCurrentCarUxRestrictions())
+                .thenReturn(noSetupRestrictions);
+        ShadowCar.setCarManager(Car.CAR_UX_RESTRICTION_SERVICE, mMockCarUxRestrictionsManager);
+        mContext = RuntimeEnvironment.application;
+        mActivityController = ActivityController.of(new TestBaseCarSettingsActivity());
+        mActivity = mActivityController.get();
+        mActivityController.create();
+    }
+
+    @Test
+    public void onPreferenceStartFragment_launchesFragment() {
+        Preference pref = new Preference(mContext);
+        pref.setFragment(TestFragment.class.getName());
+
+        mActivity.onPreferenceStartFragment(/* caller= */ null, pref);
+
+        assertThat(mActivity.getSupportFragmentManager().findFragmentById(
+                R.id.fragment_container)).isInstanceOf(TestFragment.class);
+    }
+
+    @Test
+    public void launchFragment_dialogFragment_throwsError() {
+        DialogFragment dialogFragment = new DialogFragment();
+
+        assertThrows(IllegalArgumentException.class,
+                () -> mActivity.launchFragment(dialogFragment));
+    }
+
+    @Test
+    public void showDialog_launchDialogFragment_noTag() {
+        DialogFragment dialogFragment = mock(DialogFragment.class);
+        mActivity.showDialog(dialogFragment, /* tag */ null);
+        verify(dialogFragment).show(mActivity.getSupportFragmentManager(), null);
+    }
+
+    @Test
+    public void showDialog_launchDialogFragment_withTag() {
+        DialogFragment dialogFragment = mock(DialogFragment.class);
+        mActivity.showDialog(dialogFragment, TEST_TAG);
+        verify(dialogFragment).show(mActivity.getSupportFragmentManager(), TEST_TAG);
+    }
+
+    @Test
+    public void findDialogByTag_retrieveOriginalDialog() {
+        DialogFragment dialogFragment = new DialogFragment();
+        mActivity.showDialog(dialogFragment, TEST_TAG);
+        assertThat(mActivity.findDialogByTag(TEST_TAG)).isEqualTo(dialogFragment);
+    }
+
+    @Test
+    public void findDialogByTag_notDialogFragment() {
+        TestFragment fragment = new TestFragment();
+        mActivity.getSupportFragmentManager().beginTransaction().replace(R.id.fragment_container,
+                fragment, TEST_TAG).commit();
+        assertThat(mActivity.findDialogByTag(TEST_TAG)).isNull();
+    }
+
+    @Test
+    public void findDialogByTag_noSuchFragment() {
+        assertThat(mActivity.findDialogByTag(TEST_TAG)).isNull();
+    }
+
+    /** Simple instance of {@link BaseCarSettingsActivity}. */
+    private static class TestBaseCarSettingsActivity extends BaseCarSettingsActivity {
+
+        @Nullable
+        @Override
+        protected Fragment getInitialFragment() {
+            return new TestFragment();
+        }
+    }
+
+    /** Simple Fragment for testing use. */
+    public static class TestFragment extends Fragment {
+    }
+}
diff --git a/tests/robotests/src/com/android/car/settings/common/CarSettingActivityTest.java b/tests/robotests/src/com/android/car/settings/common/CarSettingActivityTest.java
index 5601505..09c464b 100644
--- a/tests/robotests/src/com/android/car/settings/common/CarSettingActivityTest.java
+++ b/tests/robotests/src/com/android/car/settings/common/CarSettingActivityTest.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2017 The Android Open Source Project
+ * 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.
@@ -18,10 +18,7 @@
 
 import static com.google.common.truth.Truth.assertThat;
 
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.verify;
 import static org.mockito.Mockito.when;
-import static org.testng.Assert.assertThrows;
 
 import android.car.Car;
 import android.car.drivingstate.CarUxRestrictions;
@@ -31,9 +28,7 @@
 import android.os.Bundle;
 import android.provider.Settings;
 
-import androidx.fragment.app.DialogFragment;
 import androidx.fragment.app.Fragment;
-import androidx.preference.Preference;
 
 import com.android.car.settings.CarSettingsRobolectricTestRunner;
 import com.android.car.settings.R;
@@ -75,8 +70,6 @@
         mActivityController = ActivityController.of(new CarSettingActivity());
         mActivity = mActivityController.get();
         mActivityController.create();
-
-
     }
 
     @Test
@@ -102,12 +95,12 @@
         mActivityController.start().postCreate(null).resume();
         TestFragment testFragment = new TestFragment();
         mActivity.launchFragment(testFragment);
-        assertThat(mActivity.getFragment()).isEqualTo(testFragment);
+        assertThat(mActivity.getCurrentFragment()).isEqualTo(testFragment);
 
         mActivity.onNewIntent(new Intent(Settings.ACTION_DATE_SETTINGS));
         mActivity.onResume();
 
-        assertThat(mActivity.getFragment()).isNotEqualTo(testFragment);
+        assertThat(mActivity.getCurrentFragment()).isNotEqualTo(testFragment);
     }
 
     @Test
@@ -115,7 +108,7 @@
         mActivityController.start().postCreate(null).resume();
         Intent intent = new Intent(Settings.ACTION_DATE_SETTINGS);
         mActivity.onNewIntent(intent);
-        assertThat(mActivity.getFragment()).isNotInstanceOf(TestFragment.class);
+        assertThat(mActivity.getCurrentFragment()).isNotInstanceOf(TestFragment.class);
         mActivity.onResume(); // Showing date time settings (old intent)
         mActivity.launchFragment(new TestFragment()); // Replace with test fragment.
 
@@ -126,18 +119,7 @@
         mActivityController.setup(outState);
 
         // Should still display most recently launched fragment.
-        assertThat(mActivityController.get().getFragment()).isInstanceOf(TestFragment.class);
-    }
-
-    @Test
-    public void onPreferenceStartFragment_launchesFragment() {
-        Preference pref = new Preference(mContext);
-        pref.setFragment(TestFragment.class.getName());
-
-        mActivity.onPreferenceStartFragment(/* caller= */ null, pref);
-
-        assertThat(mActivity.getSupportFragmentManager().findFragmentById(
-                R.id.fragment_container)).isInstanceOf(TestFragment.class);
+        assertThat(mActivityController.get().getCurrentFragment()).isInstanceOf(TestFragment.class);
     }
 
     @Test
@@ -159,48 +141,6 @@
                 .isEqualTo(1);
     }
 
-    @Test
-    public void launchFragment_dialogFragment_throwsError() {
-        DialogFragment dialogFragment = new DialogFragment();
-
-        assertThrows(IllegalArgumentException.class,
-                () -> mActivity.launchFragment(dialogFragment));
-    }
-
-    @Test
-    public void showDialog_launchDialogFragment_noTag() {
-        DialogFragment dialogFragment = mock(DialogFragment.class);
-        mActivity.showDialog(dialogFragment, /* tag */ null);
-        verify(dialogFragment).show(mActivity.getSupportFragmentManager(), null);
-    }
-
-    @Test
-    public void showDialog_launchDialogFragment_withTag() {
-        DialogFragment dialogFragment = mock(DialogFragment.class);
-        mActivity.showDialog(dialogFragment, TEST_TAG);
-        verify(dialogFragment).show(mActivity.getSupportFragmentManager(), TEST_TAG);
-    }
-
-    @Test
-    public void findDialogByTag_retrieveOriginalDialog() {
-        DialogFragment dialogFragment = new DialogFragment();
-        mActivity.showDialog(dialogFragment, TEST_TAG);
-        assertThat(mActivity.findDialogByTag(TEST_TAG)).isEqualTo(dialogFragment);
-    }
-
-    @Test
-    public void findDialogByTag_notDialogFragment() {
-        TestFragment fragment = new TestFragment();
-        mActivity.getSupportFragmentManager().beginTransaction().replace(R.id.fragment_container,
-                fragment, TEST_TAG).commit();
-        assertThat(mActivity.findDialogByTag(TEST_TAG)).isNull();
-    }
-
-    @Test
-    public void findDialogByTag_noSuchFragment() {
-        assertThat(mActivity.findDialogByTag(TEST_TAG)).isNull();
-    }
-
     /** Simple Fragment for testing use. */
     public static class TestFragment extends Fragment {
     }
diff --git a/tests/robotests/src/com/android/car/settings/datausage/AppDataUsageFragmentTest.java b/tests/robotests/src/com/android/car/settings/datausage/AppDataUsageFragmentTest.java
index e4cf647..c94cfa8 100644
--- a/tests/robotests/src/com/android/car/settings/datausage/AppDataUsageFragmentTest.java
+++ b/tests/robotests/src/com/android/car/settings/datausage/AppDataUsageFragmentTest.java
@@ -85,7 +85,7 @@
     public void onActivityCreated_policyIsNull_startAndEndDateShouldHaveFourWeeksDifference() {
         mFragmentController.create();
 
-        Bundle bundle = mFragment.getBundleForNetworkStats();
+        Bundle bundle = mFragment.getBundle();
         long start = bundle.getLong(KEY_START);
         long end = bundle.getLong(KEY_END);
         long timeDiff = end - start;
@@ -102,7 +102,7 @@
         ShadowNetworkPolicyManager.setCycleIterator(iterator);
         mFragmentController.create();
 
-        Bundle bundle = mFragment.getBundleForNetworkStats();
+        Bundle bundle = mFragment.getBundle();
         long start = bundle.getLong(KEY_START);
         long end = bundle.getLong(KEY_END);
         long timeDiff = end - start;
@@ -130,7 +130,7 @@
         ShadowNetworkPolicyManager.setCycleIterator(iterator);
         mFragmentController.create();
 
-        Bundle bundle = mFragment.getBundleForNetworkStats();
+        Bundle bundle = mFragment.getBundle();
         long start = bundle.getLong(KEY_START);
         long end = bundle.getLong(KEY_END);
 
diff --git a/tests/robotests/src/com/android/car/settings/testutils/ShadowCarWifiManager.java b/tests/robotests/src/com/android/car/settings/testutils/ShadowCarWifiManager.java
index 8215a8b..e07116a 100644
--- a/tests/robotests/src/com/android/car/settings/testutils/ShadowCarWifiManager.java
+++ b/tests/robotests/src/com/android/car/settings/testutils/ShadowCarWifiManager.java
@@ -29,7 +29,7 @@
 
 import java.util.List;
 
-/**TODO: Refactor all methods to run without relying on sInstance. */
+/** TODO: Refactor all methods to run without relying on sInstance. */
 @Implements(CarWifiManager.class)
 public class ShadowCarWifiManager {
 
@@ -126,6 +126,12 @@
     }
 
     @Implementation
+    protected void connectToSavedWifi(AccessPoint accessPoint,
+            WifiManager.ActionListener listener) {
+        sInstance.connectToSavedWifi(accessPoint, listener);
+    }
+
+    @Implementation
     protected boolean isDualModeSupported() {
         return sIsDualModeSupported;
     }