diff --git a/res/color/dream_card_color_state_list.xml b/res/color/dream_card_color_state_list.xml index eae3fe46a6d..082408d1583 100644 --- a/res/color/dream_card_color_state_list.xml +++ b/res/color/dream_card_color_state_list.xml @@ -17,6 +17,6 @@ - - + + \ No newline at end of file diff --git a/res/color/dream_card_icon_color_state_list.xml b/res/color/dream_card_icon_color_state_list.xml index a91ae3d3be3..ed34ae39357 100644 --- a/res/color/dream_card_icon_color_state_list.xml +++ b/res/color/dream_card_icon_color_state_list.xml @@ -17,6 +17,6 @@ - - + + \ No newline at end of file diff --git a/res/color/dream_card_summary_color_state_list.xml b/res/color/dream_card_summary_color_state_list.xml new file mode 100644 index 00000000000..a1845f44d95 --- /dev/null +++ b/res/color/dream_card_summary_color_state_list.xml @@ -0,0 +1,22 @@ + + + + + + + \ No newline at end of file diff --git a/res/color/dream_card_text_color_state_list.xml b/res/color/dream_card_text_color_state_list.xml index bd1f16578ea..b39bbed75c9 100644 --- a/res/color/dream_card_text_color_state_list.xml +++ b/res/color/dream_card_text_color_state_list.xml @@ -17,6 +17,6 @@ - - + + \ No newline at end of file diff --git a/res/drawable/dream_default_preview_icon.xml b/res/drawable/dream_default_preview_icon.xml index 7d247bb2957..8989929fdd7 100644 --- a/res/drawable/dream_default_preview_icon.xml +++ b/res/drawable/dream_default_preview_icon.xml @@ -15,10 +15,11 @@ --> - \ No newline at end of file diff --git a/res/drawable/dream_preview_rounded_bg.xml b/res/drawable/dream_preview_rounded_bg.xml index 2aae26b2ad2..7cae599b6c8 100644 --- a/res/drawable/dream_preview_rounded_bg.xml +++ b/res/drawable/dream_preview_rounded_bg.xml @@ -17,6 +17,6 @@ - + \ No newline at end of file diff --git a/res/layout/dream_preference_layout.xml b/res/layout/dream_preference_layout.xml index f7281c1a573..aff8ad3133e 100644 --- a/res/layout/dream_preference_layout.xml +++ b/res/layout/dream_preference_layout.xml @@ -93,7 +93,7 @@ android:maxLines="2" android:ellipsize="end" android:textSize="@dimen/dream_item_summary_text_size" - android:textColor="@color/dream_card_text_color_state_list" + android:textColor="@color/dream_card_summary_color_state_list" app:layout_constraintTop_toBottomOf="@+id/title_text" app:layout_constraintEnd_toEndOf="parent" app:layout_constraintStart_toStartOf="parent" diff --git a/res/layout/dream_preview_button.xml b/res/layout/dream_preview_button.xml index 04d272aecdd..feeb9dd36ea 100644 --- a/res/layout/dream_preview_button.xml +++ b/res/layout/dream_preview_button.xml @@ -17,17 +17,16 @@ diff --git a/src/com/android/settings/biometrics/fingerprint/FingerprintSettings.java b/src/com/android/settings/biometrics/fingerprint/FingerprintSettings.java index a5e5f579c02..e0f402bdc02 100644 --- a/src/com/android/settings/biometrics/fingerprint/FingerprintSettings.java +++ b/src/com/android/settings/biometrics/fingerprint/FingerprintSettings.java @@ -283,7 +283,9 @@ public class FingerprintSettings extends SubSettings { case MSG_REFRESH_FINGERPRINT_TEMPLATES: removeFingerprintPreference(msg.arg1); updateAddPreference(); - updateFingerprintUnlockCategoryVisibility(); + if (isSfps()) { + updateFingerprintUnlockCategoryVisibility(); + } updatePreferences(); break; case MSG_FINGER_AUTH_SUCCESS: @@ -494,9 +496,13 @@ public class FingerprintSettings extends SubSettings { } private boolean isSfps() { - for (FingerprintSensorPropertiesInternal prop : mSensorProperties) { - if (prop.isAnySidefpsType()) { - return true; + mFingerprintManager = Utils.getFingerprintManagerOrNull(getActivity()); + if (mFingerprintManager != null) { + mSensorProperties = mFingerprintManager.getSensorPropertiesInternal(); + for (FingerprintSensorPropertiesInternal prop : mSensorProperties) { + if (prop.isAnySidefpsType()) { + return true; + } } } return false; @@ -838,18 +844,20 @@ public class FingerprintSettings extends SubSettings { private List buildPreferenceControllers(Context context) { final List controllers = new ArrayList<>(); - mFingerprintUnlockCategoryPreferenceController = + if (isSfps()) { + mFingerprintUnlockCategoryPreferenceController = new FingerprintUnlockCategoryController( - context, - KEY_FINGERPRINT_UNLOCK_CATEGORY + context, + KEY_FINGERPRINT_UNLOCK_CATEGORY ); - mRequireScreenOnToAuthPreferenceController = - new FingerprintSettingsRequireScreenOnToAuthPreferenceController( - context, - KEY_REQUIRE_SCREEN_ON_TO_AUTH - ); - controllers.add(mFingerprintUnlockCategoryPreferenceController); - controllers.add(mRequireScreenOnToAuthPreferenceController); + mRequireScreenOnToAuthPreferenceController = + new FingerprintSettingsRequireScreenOnToAuthPreferenceController( + context, + KEY_REQUIRE_SCREEN_ON_TO_AUTH + ); + controllers.add(mFingerprintUnlockCategoryPreferenceController); + controllers.add(mRequireScreenOnToAuthPreferenceController); + } return controllers; } diff --git a/src/com/android/settings/datausage/DataSaverSummary.java b/src/com/android/settings/datausage/DataSaverSummary.java deleted file mode 100644 index 67644a6c992..00000000000 --- a/src/com/android/settings/datausage/DataSaverSummary.java +++ /dev/null @@ -1,234 +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.datausage; - -import android.app.Application; -import android.app.settings.SettingsEnums; -import android.content.Context; -import android.icu.text.MessageFormat; -import android.os.Bundle; -import android.telephony.SubscriptionManager; -import android.widget.Switch; - -import androidx.preference.Preference; - -import com.android.settings.R; -import com.android.settings.SettingsActivity; -import com.android.settings.SettingsPreferenceFragment; -import com.android.settings.applications.AppStateBaseBridge.Callback; -import com.android.settings.datausage.DataSaverBackend.Listener; -import com.android.settings.search.BaseSearchIndexProvider; -import com.android.settings.widget.SettingsMainSwitchBar; -import com.android.settingslib.applications.ApplicationsState; -import com.android.settingslib.applications.ApplicationsState.AppEntry; -import com.android.settingslib.applications.ApplicationsState.Callbacks; -import com.android.settingslib.applications.ApplicationsState.Session; -import com.android.settingslib.search.SearchIndexable; -import com.android.settingslib.widget.OnMainSwitchChangeListener; - -import java.util.ArrayList; -import java.util.HashMap; -import java.util.Locale; -import java.util.Map; - -@SearchIndexable -public class DataSaverSummary extends SettingsPreferenceFragment - implements OnMainSwitchChangeListener, Listener, Callback, Callbacks { - - private static final String KEY_UNRESTRICTED_ACCESS = "unrestricted_access"; - - private SettingsMainSwitchBar mSwitchBar; - private DataSaverBackend mDataSaverBackend; - private Preference mUnrestrictedAccess; - private ApplicationsState mApplicationsState; - private AppStateDataUsageBridge mDataUsageBridge; - private Session mSession; - - // Flag used to avoid infinite loop due if user switch it on/off too quicky. - private boolean mSwitching; - - private Runnable mLoadAppRunnable = () -> { - mApplicationsState = ApplicationsState.getInstance( - (Application) getContext().getApplicationContext()); - mDataUsageBridge = new AppStateDataUsageBridge(mApplicationsState, this, mDataSaverBackend); - mSession = mApplicationsState.newSession(this, getSettingsLifecycle()); - mDataUsageBridge.resume(true /* forceLoadAllApps */); - }; - - @Override - public void onCreate(Bundle icicle) { - super.onCreate(icicle); - - if (!isDataSaverVisible(getContext())) { - finishFragment(); - return; - } - - addPreferencesFromResource(R.xml.data_saver); - mUnrestrictedAccess = findPreference(KEY_UNRESTRICTED_ACCESS); - mDataSaverBackend = new DataSaverBackend(getContext()); - } - - @Override - public void onActivityCreated(Bundle savedInstanceState) { - super.onActivityCreated(savedInstanceState); - mSwitchBar = ((SettingsActivity) getActivity()).getSwitchBar(); - mSwitchBar.setTitle(getContext().getString(R.string.data_saver_switch_title)); - mSwitchBar.show(); - mSwitchBar.addOnSwitchChangeListener(this); - } - - @Override - public void onResume() { - super.onResume(); - mDataSaverBackend.refreshAllowlist(); - mDataSaverBackend.refreshDenylist(); - mDataSaverBackend.addListener(this); - if (mDataUsageBridge != null) { - mDataUsageBridge.resume(true /* forceLoadAllApps */); - } else { - getView().post(mLoadAppRunnable); - } - } - - @Override - public void onPause() { - super.onPause(); - mDataSaverBackend.remListener(this); - if (mDataUsageBridge != null) { - mDataUsageBridge.pause(); - } - } - - @Override - public void onSwitchChanged(Switch switchView, boolean isChecked) { - synchronized (this) { - if (mSwitching) { - return; - } - mSwitching = true; - mDataSaverBackend.setDataSaverEnabled(isChecked); - } - } - - @Override - public int getMetricsCategory() { - return SettingsEnums.DATA_SAVER_SUMMARY; - } - - @Override - public int getHelpResource() { - return R.string.help_url_data_saver; - } - - @Override - public void onDataSaverChanged(boolean isDataSaving) { - synchronized (this) { - mSwitchBar.setChecked(isDataSaving); - mSwitching = false; - } - } - - @Override - public void onAllowlistStatusChanged(int uid, boolean isAllowlisted) { - } - - @Override - public void onDenylistStatusChanged(int uid, boolean isDenylisted) { - } - - @Override - public void onExtraInfoUpdated() { - updateUnrestrictedAccessSummary(); - } - - @Override - public void onRunningStateChanged(boolean running) { - - } - - @Override - public void onPackageListChanged() { - - } - - @Override - public void onRebuildComplete(ArrayList apps) { - - } - - @Override - public void onPackageIconChanged() { - - } - - @Override - public void onPackageSizeChanged(String packageName) { - - } - - @Override - public void onAllSizesComputed() { - updateUnrestrictedAccessSummary(); - } - - @Override - public void onLauncherInfoChanged() { - updateUnrestrictedAccessSummary(); - } - - @Override - public void onLoadEntriesCompleted() { - - } - - private void updateUnrestrictedAccessSummary() { - if (!isAdded() || isFinishingOrDestroyed() || mSession == null) return; - - int count = 0; - for (AppEntry entry : mSession.getAllApps()) { - if (!ApplicationsState.FILTER_DOWNLOADED_AND_LAUNCHER.filterApp(entry)) { - continue; - } - if (entry.extraInfo != null && ((AppStateDataUsageBridge.DataUsageState) - entry.extraInfo).isDataSaverAllowlisted) { - count++; - } - } - MessageFormat msgFormat = new MessageFormat( - getResources().getString(R.string.data_saver_unrestricted_summary), - Locale.getDefault()); - Map arguments = new HashMap<>(); - arguments.put("count", count); - mUnrestrictedAccess.setSummary(msgFormat.format(arguments)); - } - - public static boolean isDataSaverVisible(Context context) { - return context.getResources() - .getBoolean(R.bool.config_show_data_saver); - } - - public static final BaseSearchIndexProvider SEARCH_INDEX_DATA_PROVIDER = - new BaseSearchIndexProvider(R.xml.data_saver) { - - @Override - protected boolean isPageSearchEnabled(Context context) { - return isDataSaverVisible(context) - && DataUsageUtils.hasMobileData(context) - && DataUsageUtils.getDefaultSubscriptionId(context) - != SubscriptionManager.INVALID_SUBSCRIPTION_ID; - } - }; -} diff --git a/src/com/android/settings/datausage/DataSaverSummary.kt b/src/com/android/settings/datausage/DataSaverSummary.kt new file mode 100644 index 00000000000..1d9cbb73a66 --- /dev/null +++ b/src/com/android/settings/datausage/DataSaverSummary.kt @@ -0,0 +1,176 @@ +/* + * Copyright (C) 2023 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.datausage + +import android.app.Application +import android.app.settings.SettingsEnums +import android.content.Context +import android.os.Bundle +import android.telephony.SubscriptionManager +import android.widget.Switch +import androidx.lifecycle.lifecycleScope +import androidx.preference.Preference +import com.android.settings.R +import com.android.settings.SettingsActivity +import com.android.settings.SettingsPreferenceFragment +import com.android.settings.applications.AppStateBaseBridge +import com.android.settings.datausage.AppStateDataUsageBridge.DataUsageState +import com.android.settings.search.BaseSearchIndexProvider +import com.android.settings.widget.SettingsMainSwitchBar +import com.android.settingslib.applications.ApplicationsState +import com.android.settingslib.search.SearchIndexable +import com.android.settingslib.spa.framework.util.formatString +import kotlinx.coroutines.launch + +@SearchIndexable +class DataSaverSummary : SettingsPreferenceFragment() { + private lateinit var switchBar: SettingsMainSwitchBar + private lateinit var dataSaverBackend: DataSaverBackend + private lateinit var unrestrictedAccess: Preference + private var dataUsageBridge: AppStateDataUsageBridge? = null + private var session: ApplicationsState.Session? = null + + // Flag used to avoid infinite loop due if user switch it on/off too quick. + private var switching = false + + override fun onCreate(bundle: Bundle?) { + super.onCreate(bundle) + + if (!requireContext().isDataSaverVisible()) { + finishFragment() + return + } + + addPreferencesFromResource(R.xml.data_saver) + unrestrictedAccess = findPreference(KEY_UNRESTRICTED_ACCESS)!! + dataSaverBackend = DataSaverBackend(requireContext()) + } + + override fun onActivityCreated(savedInstanceState: Bundle?) { + super.onActivityCreated(savedInstanceState) + switchBar = (activity as SettingsActivity).switchBar.apply { + setTitle(getString(R.string.data_saver_switch_title)) + show() + addOnSwitchChangeListener { _: Switch, isChecked: Boolean -> + onSwitchChanged(isChecked) + } + } + } + + override fun onResume() { + super.onResume() + dataSaverBackend.refreshAllowlist() + dataSaverBackend.refreshDenylist() + dataSaverBackend.addListener(dataSaverBackendListener) + dataUsageBridge?.resume(/* forceLoadAllApps= */ true) + ?: viewLifecycleOwner.lifecycleScope.launch { + val applicationsState = ApplicationsState.getInstance( + requireContext().applicationContext as Application + ) + dataUsageBridge = AppStateDataUsageBridge( + applicationsState, dataUsageBridgeCallbacks, dataSaverBackend + ) + session = + applicationsState.newSession(applicationsStateCallbacks, settingsLifecycle) + dataUsageBridge?.resume(/* forceLoadAllApps= */ true) + } + } + + override fun onPause() { + super.onPause() + dataSaverBackend.remListener(dataSaverBackendListener) + dataUsageBridge?.pause() + } + + private fun onSwitchChanged(isChecked: Boolean) { + synchronized(this) { + if (!switching) { + switching = true + dataSaverBackend.isDataSaverEnabled = isChecked + } + } + } + + override fun getMetricsCategory() = SettingsEnums.DATA_SAVER_SUMMARY + + override fun getHelpResource() = R.string.help_url_data_saver + + private val dataSaverBackendListener = object : DataSaverBackend.Listener { + override fun onDataSaverChanged(isDataSaving: Boolean) { + synchronized(this) { + switchBar.isChecked = isDataSaving + switching = false + } + } + + override fun onAllowlistStatusChanged(uid: Int, isAllowlisted: Boolean) {} + + override fun onDenylistStatusChanged(uid: Int, isDenylisted: Boolean) {} + } + + private val dataUsageBridgeCallbacks = AppStateBaseBridge.Callback { + updateUnrestrictedAccessSummary() + } + + private val applicationsStateCallbacks = object : ApplicationsState.Callbacks { + override fun onRunningStateChanged(running: Boolean) {} + + override fun onPackageListChanged() {} + + override fun onRebuildComplete(apps: ArrayList?) {} + + override fun onPackageIconChanged() {} + + override fun onPackageSizeChanged(packageName: String?) {} + + override fun onAllSizesComputed() { + updateUnrestrictedAccessSummary() + } + + override fun onLauncherInfoChanged() { + updateUnrestrictedAccessSummary() + } + + override fun onLoadEntriesCompleted() {} + } + + private fun updateUnrestrictedAccessSummary() { + if (!isAdded || isFinishingOrDestroyed) return + val allApps = session?.allApps ?: return + val count = allApps.count { + ApplicationsState.FILTER_DOWNLOADED_AND_LAUNCHER.filterApp(it) && + (it.extraInfo as? DataUsageState)?.isDataSaverAllowlisted == true + } + unrestrictedAccess.summary = + resources.formatString(R.string.data_saver_unrestricted_summary, "count" to count) + } + + companion object { + private const val KEY_UNRESTRICTED_ACCESS = "unrestricted_access" + + private fun Context.isDataSaverVisible(): Boolean = + resources.getBoolean(R.bool.config_show_data_saver) + + @JvmField + val SEARCH_INDEX_DATA_PROVIDER = object : BaseSearchIndexProvider(R.xml.data_saver) { + override fun isPageSearchEnabled(context: Context): Boolean = + context.isDataSaverVisible() && + DataUsageUtils.hasMobileData(context) && + (DataUsageUtils.getDefaultSubscriptionId(context) != + SubscriptionManager.INVALID_SUBSCRIPTION_ID) + } + } +} \ No newline at end of file diff --git a/src/com/android/settings/display/AmbientDisplayAlwaysOnPreferenceController.java b/src/com/android/settings/display/AmbientDisplayAlwaysOnPreferenceController.java index 5d95ddbfeb8..245803493e2 100644 --- a/src/com/android/settings/display/AmbientDisplayAlwaysOnPreferenceController.java +++ b/src/com/android/settings/display/AmbientDisplayAlwaysOnPreferenceController.java @@ -22,6 +22,7 @@ import android.os.PowerManager; import android.os.SystemProperties; import android.os.UserHandle; import android.provider.Settings; +import android.text.TextUtils; import androidx.preference.Preference; @@ -63,7 +64,7 @@ public class AmbientDisplayAlwaysOnPreferenceController extends TogglePreference @Override public boolean isPublicSlice() { - return true; + return TextUtils.equals(getPreferenceKey(), "ambient_display_always_on"); } @Override diff --git a/src/com/android/settings/fuelgauge/TopLevelBatteryPreferenceController.java b/src/com/android/settings/fuelgauge/TopLevelBatteryPreferenceController.java index 5bec7bd4aae..d686594275b 100644 --- a/src/com/android/settings/fuelgauge/TopLevelBatteryPreferenceController.java +++ b/src/com/android/settings/fuelgauge/TopLevelBatteryPreferenceController.java @@ -30,6 +30,7 @@ import com.android.settings.overlay.FeatureFactory; import com.android.settingslib.core.lifecycle.LifecycleObserver; import com.android.settingslib.core.lifecycle.events.OnStart; import com.android.settingslib.core.lifecycle.events.OnStop; +import com.android.settingslib.Utils; import com.android.settingslib.utils.ThreadUtils; public class TopLevelBatteryPreferenceController extends BasePreferenceController implements @@ -37,11 +38,13 @@ public class TopLevelBatteryPreferenceController extends BasePreferenceControlle private static final String TAG = "TopLvBatteryPrefControl"; - @VisibleForTesting - protected boolean mIsBatteryPresent = true; @VisibleForTesting Preference mPreference; + @VisibleForTesting + protected boolean mIsBatteryPresent = true; + private final BatteryBroadcastReceiver mBatteryBroadcastReceiver; + private BatteryInfo mBatteryInfo; private BatteryStatusFeatureProvider mBatteryStatusFeatureProvider; private String mBatteryStatusLabel; @@ -55,8 +58,11 @@ public class TopLevelBatteryPreferenceController extends BasePreferenceControlle mIsBatteryPresent = false; } BatteryInfo.getBatteryInfo(mContext, info -> { + Log.d(TAG, "getBatteryInfo: " + info); mBatteryInfo = info; updateState(mPreference); + // Update the preference summary text to the latest state. + setSummaryAsync(info); }, true /* shortString */); }); @@ -104,18 +110,19 @@ public class TopLevelBatteryPreferenceController extends BasePreferenceControlle if (info == null || context == null) { return null; } - - Log.d(TAG, "getDashboardLabel: batteryStatusUpdate=" + batteryStatusUpdate); + Log.d(TAG, "getDashboardLabel: " + mBatteryStatusLabel + " batteryStatusUpdate=" + + batteryStatusUpdate); if (batteryStatusUpdate) { setSummaryAsync(info); } - - return (mBatteryStatusLabel == null) ? generateLabel(info) : mBatteryStatusLabel; + return mBatteryStatusLabel == null ? generateLabel(info) : mBatteryStatusLabel; } private void setSummaryAsync(BatteryInfo info) { ThreadUtils.postOnBackgroundThread(() -> { + // Return false if built-in status should be used, will use updateBatteryStatus() + // method to inject the customized battery status label. final boolean triggerBatteryStatusUpdate = mBatteryStatusFeatureProvider.triggerBatteryStatusUpdate(this, info); ThreadUtils.postOnMainThread(() -> { @@ -123,12 +130,15 @@ public class TopLevelBatteryPreferenceController extends BasePreferenceControlle mBatteryStatusLabel = null; // will generateLabel() } mPreference.setSummary( - (mBatteryStatusLabel == null) ? generateLabel(info) : mBatteryStatusLabel); + mBatteryStatusLabel == null ? generateLabel(info) : mBatteryStatusLabel); }); }); } private CharSequence generateLabel(BatteryInfo info) { + if (Utils.containsIncompatibleChargers(mContext, TAG)) { + return mContext.getString(R.string.battery_info_status_not_charging); + } if (!info.discharging && info.chargeLabel != null) { return info.chargeLabel; } else if (info.remainingLabel == null) { @@ -146,13 +156,13 @@ public class TopLevelBatteryPreferenceController extends BasePreferenceControlle @Override public void updateBatteryStatus(String label, BatteryInfo info) { mBatteryStatusLabel = label; // Null if adaptive charging is not active - - if (mPreference != null) { - // Do not triggerBatteryStatusUpdate(), otherwise there will be an infinite loop - final CharSequence summary = getSummary(false /* batteryStatusUpdate */); - if (summary != null) { - mPreference.setSummary(summary); - } + if (mPreference == null) { + return; + } + // Do not triggerBatteryStatusUpdate() here to cause infinite loop + final CharSequence summary = getSummary(false /* batteryStatusUpdate */); + if (summary != null) { + mPreference.setSummary(summary); } } @@ -170,4 +180,4 @@ public class TopLevelBatteryPreferenceController extends BasePreferenceControlle String pkgName = lastPkgIndex > 0 ? classPath.substring(0, lastPkgIndex) : ""; return new ComponentName(pkgName, split[classNameIndex]); } -} \ No newline at end of file +} diff --git a/tests/robotests/src/com/android/settings/accessibility/SystemControlsFragmentTest.java b/tests/robotests/src/com/android/settings/accessibility/SystemControlsFragmentTest.java index 1d8fb32a0c4..506882b45fb 100644 --- a/tests/robotests/src/com/android/settings/accessibility/SystemControlsFragmentTest.java +++ b/tests/robotests/src/com/android/settings/accessibility/SystemControlsFragmentTest.java @@ -25,16 +25,19 @@ import androidx.test.core.app.ApplicationProvider; import com.android.settings.R; import com.android.settings.testutils.XmlTestUtils; +import com.android.settings.testutils.shadow.ShadowKeyCharacterMap; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; import org.robolectric.RobolectricTestRunner; +import org.robolectric.annotation.Config; import java.util.List; /** Tests for {@link SystemControlsFragment}. */ @RunWith(RobolectricTestRunner.class) +@Config(shadows = {ShadowKeyCharacterMap.class}) public class SystemControlsFragmentTest { private final Context mContext = ApplicationProvider.getApplicationContext(); diff --git a/tests/robotests/src/com/android/settings/applications/ClonedAppsPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/applications/ClonedAppsPreferenceControllerTest.java index 828d88d994c..56117d1952c 100644 --- a/tests/robotests/src/com/android/settings/applications/ClonedAppsPreferenceControllerTest.java +++ b/tests/robotests/src/com/android/settings/applications/ClonedAppsPreferenceControllerTest.java @@ -23,12 +23,15 @@ import static com.android.settings.core.BasePreferenceController.AVAILABLE; import static com.google.common.truth.Truth.assertThat; import static org.mockito.Mockito.spy; +import static org.mockito.Mockito.when; import android.content.Context; +import android.content.res.Resources; import android.provider.DeviceConfig; import androidx.test.core.app.ApplicationProvider; +import com.android.settings.R; import com.android.settings.Utils; import com.android.settings.testutils.shadow.ShadowDeviceConfig; @@ -45,10 +48,15 @@ public class ClonedAppsPreferenceControllerTest { private ClonedAppsPreferenceController mController; private static final String KEY = "key"; private Context mContext; + private Resources mResources; @Before public void setUp() { mContext = spy(ApplicationProvider.getApplicationContext()); + + mResources = spy(mContext.getResources()); + when(mContext.getResources()).thenReturn(mResources); + mController = new ClonedAppsPreferenceController(mContext, KEY); } @@ -56,6 +64,7 @@ public class ClonedAppsPreferenceControllerTest { public void getAvailabilityStatus_featureNotEnabled_shouldNotReturnAvailable() { DeviceConfig.setProperty(NAMESPACE_APP_CLONING, Utils.PROPERTY_CLONED_APPS_ENABLED, "false", true /* makeDefault */); + when(mResources.getBoolean(R.bool.config_cloned_apps_page_enabled)).thenReturn(false); assertThat(mController.getAvailabilityStatus()).isNotEqualTo(AVAILABLE); } @@ -64,7 +73,26 @@ public class ClonedAppsPreferenceControllerTest { public void getAvailabilityStatus_featureEnabled_shouldReturnAvailable() { DeviceConfig.setProperty(NAMESPACE_APP_CLONING, Utils.PROPERTY_CLONED_APPS_ENABLED, "true", true /* makeDefault */); + when(mResources.getBoolean(R.bool.config_cloned_apps_page_enabled)).thenReturn(true); assertThat(mController.getAvailabilityStatus()).isEqualTo(AVAILABLE); } + + @Test + public void getAvailabilityStatus_deviceConfigFalseAndConfigEnabled_shouldNotReturnAvailable() { + DeviceConfig.setProperty(NAMESPACE_APP_CLONING, Utils.PROPERTY_CLONED_APPS_ENABLED, + "false", true /* makeDefault */); + when(mResources.getBoolean(R.bool.config_cloned_apps_page_enabled)).thenReturn(true); + + assertThat(mController.getAvailabilityStatus()).isNotEqualTo(AVAILABLE); + } + + @Test + public void getAvailabilityStatus_deviceConfigTrueAndConfigDisabled_shouldNotReturnAvailable() { + DeviceConfig.setProperty(NAMESPACE_APP_CLONING, Utils.PROPERTY_CLONED_APPS_ENABLED, + "true", true /* makeDefault */); + when(mResources.getBoolean(R.bool.config_cloned_apps_page_enabled)).thenReturn(false); + + assertThat(mController.getAvailabilityStatus()).isNotEqualTo(AVAILABLE); + } } diff --git a/tests/robotests/src/com/android/settings/fuelgauge/TopLevelBatteryPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/fuelgauge/TopLevelBatteryPreferenceControllerTest.java index 85e29429c9e..5f825ae2cef 100644 --- a/tests/robotests/src/com/android/settings/fuelgauge/TopLevelBatteryPreferenceControllerTest.java +++ b/tests/robotests/src/com/android/settings/fuelgauge/TopLevelBatteryPreferenceControllerTest.java @@ -28,6 +28,9 @@ import static org.mockito.Mockito.when; import android.content.ComponentName; import android.content.Context; import android.content.Intent; +import android.hardware.usb.UsbManager; +import android.hardware.usb.UsbPort; +import android.hardware.usb.UsbPortStatus; import androidx.preference.Preference; import androidx.test.core.app.ApplicationProvider; @@ -38,21 +41,33 @@ import org.junit.Before; import org.junit.Ignore; import org.junit.Test; import org.junit.runner.RunWith; +import org.mockito.Mock; import org.mockito.MockitoAnnotations; import org.robolectric.RobolectricTestRunner; import org.robolectric.annotation.Config; +import java.util.ArrayList; +import java.util.List; + @RunWith(RobolectricTestRunner.class) public class TopLevelBatteryPreferenceControllerTest { private Context mContext; private TopLevelBatteryPreferenceController mController; private BatterySettingsFeatureProvider mBatterySettingsFeatureProvider; + @Mock + private UsbPort mUsbPort; + @Mock + private UsbManager mUsbManager; + @Mock + private UsbPortStatus mUsbPortStatus; + @Before public void setUp() { MockitoAnnotations.initMocks(this); mContext = spy(ApplicationProvider.getApplicationContext()); mController = new TopLevelBatteryPreferenceController(mContext, "test_key"); + when(mContext.getSystemService(UsbManager.class)).thenReturn(mUsbManager); } @Test @@ -88,27 +103,61 @@ public class TopLevelBatteryPreferenceControllerTest { } @Test - public void getDashboardLabel_returnsCorrectLabel() { + public void getDashboardLabel_returnsBatterPercentString() { mController.mPreference = new Preference(mContext); BatteryInfo info = new BatteryInfo(); info.batteryPercentString = "3%"; + assertThat(mController.getDashboardLabel(mContext, info, true)) .isEqualTo(info.batteryPercentString); + } + @Test + public void getDashboardLabel_returnsRemainingLabel() { + mController.mPreference = new Preference(mContext); + BatteryInfo info = new BatteryInfo(); + info.batteryPercentString = "3%"; info.remainingLabel = "Phone will shut down soon"; + assertThat(mController.getDashboardLabel(mContext, info, true)) .isEqualTo("3% - Phone will shut down soon"); + } + @Test + public void getDashboardLabel_returnsChargeLabel() { + mController.mPreference = new Preference(mContext); + BatteryInfo info = new BatteryInfo(); info.discharging = false; info.chargeLabel = "5% - charging"; - assertThat(mController.getDashboardLabel(mContext, info, true)).isEqualTo("5% - charging"); + + assertThat(mController.getDashboardLabel(mContext, info, true)) + .isEqualTo(info.chargeLabel); + } + + @Test + public void getDashboardLabel_incompatibleCharger_returnsCorrectLabel() { + setupIncompatibleEvent(); + mController.mPreference = new Preference(mContext); + BatteryInfo info = new BatteryInfo(); + + assertThat(mController.getDashboardLabel(mContext, info, true)) + .isEqualTo(mContext.getString(R.string.battery_info_status_not_charging)); } @Test public void getSummary_batteryNotPresent_shouldShowWarningMessage() { mController.mIsBatteryPresent = false; - assertThat(mController.getSummary()) .isEqualTo(mContext.getString(R.string.battery_missing_message)); } + + private void setupIncompatibleEvent() { + final List usbPorts = new ArrayList<>(); + usbPorts.add(mUsbPort); + when(mUsbManager.getPorts()).thenReturn(usbPorts); + when(mUsbPort.getStatus()).thenReturn(mUsbPortStatus); + when(mUsbPort.supportsComplianceWarnings()).thenReturn(true); + when(mUsbPortStatus.isConnected()).thenReturn(true); + when(mUsbPortStatus.getComplianceWarnings()).thenReturn(new int[]{1}); + } } diff --git a/tests/robotests/src/com/android/settings/network/PrivateDnsPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/network/PrivateDnsPreferenceControllerTest.java index 057b6cbf0b9..b2f0ad55bc7 100644 --- a/tests/robotests/src/com/android/settings/network/PrivateDnsPreferenceControllerTest.java +++ b/tests/robotests/src/com/android/settings/network/PrivateDnsPreferenceControllerTest.java @@ -169,6 +169,7 @@ public class PrivateDnsPreferenceControllerTest { @Test public void getAvailibilityStatus_availableByDefault() { + doReturn(true).when(mUserManager).isAdminUser(); assertThat(mController.getAvailabilityStatus()).isEqualTo(AVAILABLE); }