From 862dd61608fc7b9829bf4c3e25fba367a3c9388b Mon Sep 17 00:00:00 2001 From: lucaslin Date: Mon, 8 Feb 2021 11:33:48 +0800 Subject: [PATCH 01/16] Modify the value of intent-filter ACTION_PROMPT_PARTIAL_CONNECTIVITY, ACTION_PROMPT_UNVALIDATED and ACTION_PROMPT_LOST_VALIDATION has exposed and their value also need to be updated due to API lint errors. Bug: 172183305 Test: Check NO_INTERNET notification can be shown. Change-Id: I40dfeec1c25cd549bbe5559e3c3ce21813fbf922 Merged-In: I40dfeec1c25cd549bbe5559e3c3ce21813fbf922 --- AndroidManifest.xml | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/AndroidManifest.xml b/AndroidManifest.xml index 5e7c97c9e6e..384b57cb4a3 100644 --- a/AndroidManifest.xml +++ b/AndroidManifest.xml @@ -376,12 +376,15 @@ android:exported="true" android:permission="android.permission.NETWORK_STACK" android:theme="@*android:style/Theme.DeviceDefault.Light.Dialog.Alert"> + - + - + Date: Thu, 1 Apr 2021 21:38:00 +0800 Subject: [PATCH 02/16] BTHS will have no sound after disable HD audio -setCodecConfigPreference() should not be called when disableOptionalCodecs() is called. -disableOptionalCodecs() would set SBC codec automatically Bug: 183456866 Test: make -j50 RunSettingsRoboTests ROBOTEST_FILTER=BluetoothCodecDialogPreferenceControllerTest Change-Id: Ib18f4a683dcba7ba92df827c30da0088c90b4d72 --- .../BluetoothCodecDialogPreferenceController.java | 8 -------- 1 file changed, 8 deletions(-) diff --git a/src/com/android/settings/development/bluetooth/BluetoothCodecDialogPreferenceController.java b/src/com/android/settings/development/bluetooth/BluetoothCodecDialogPreferenceController.java index a0af268c8f7..6b243c600f1 100644 --- a/src/com/android/settings/development/bluetooth/BluetoothCodecDialogPreferenceController.java +++ b/src/com/android/settings/development/bluetooth/BluetoothCodecDialogPreferenceController.java @@ -60,14 +60,6 @@ public class BluetoothCodecDialogPreferenceController extends ((BaseBluetoothDialogPreference) mPreference).setCallback(this); } - @Override - public void onHDAudioEnabled(boolean enabled) { - if (!enabled) { - // If option codec is disabled, SBC is the only only one available codec. - onIndexUpdated(convertCfgToBtnIndex(BluetoothCodecConfig.SOURCE_CODEC_TYPE_SBC)); - } - } - @Override public List getSelectableIndex() { List index = new ArrayList<>(); From 465b790717e5066d8e006967719fe1023348f3bd Mon Sep 17 00:00:00 2001 From: ryanlwlin Date: Tue, 6 Apr 2021 15:25:02 +0800 Subject: [PATCH 03/16] Change illustrations of Magnification Settings Bug: 184081570 Test: Treehugger build pass Change-Id: I3c3d00ebb38af1a3af835305fbaa66d2e9b33018 --- ...ccessibility_magnification_full_screen.xml | 50 ------------------ .../accessibility_magnification_switch.xml | 52 ------------------- ...essibility_magnification_window_screen.xml | 50 ------------------ res/drawable/ic_illustration_fullscreen.xml | 39 ++++++++++++++ res/drawable/ic_illustration_switch.xml | 46 ++++++++++++++++ res/drawable/ic_illustration_window.xml | 41 +++++++++++++++ .../MagnificationSettingsFragment.java | 6 +-- 7 files changed, 129 insertions(+), 155 deletions(-) delete mode 100644 res/drawable/accessibility_magnification_full_screen.xml delete mode 100644 res/drawable/accessibility_magnification_switch.xml delete mode 100644 res/drawable/accessibility_magnification_window_screen.xml create mode 100644 res/drawable/ic_illustration_fullscreen.xml create mode 100644 res/drawable/ic_illustration_switch.xml create mode 100644 res/drawable/ic_illustration_window.xml diff --git a/res/drawable/accessibility_magnification_full_screen.xml b/res/drawable/accessibility_magnification_full_screen.xml deleted file mode 100644 index 09d1a7e2cc4..00000000000 --- a/res/drawable/accessibility_magnification_full_screen.xml +++ /dev/null @@ -1,50 +0,0 @@ - - - - - - - - - - - - - - - - diff --git a/res/drawable/accessibility_magnification_switch.xml b/res/drawable/accessibility_magnification_switch.xml deleted file mode 100644 index 21e0cef53b4..00000000000 --- a/res/drawable/accessibility_magnification_switch.xml +++ /dev/null @@ -1,52 +0,0 @@ - - - - - - - - - - - - - - - - diff --git a/res/drawable/accessibility_magnification_window_screen.xml b/res/drawable/accessibility_magnification_window_screen.xml deleted file mode 100644 index d7e164c4953..00000000000 --- a/res/drawable/accessibility_magnification_window_screen.xml +++ /dev/null @@ -1,50 +0,0 @@ - - - - - - - - - - - - - - - - diff --git a/res/drawable/ic_illustration_fullscreen.xml b/res/drawable/ic_illustration_fullscreen.xml new file mode 100644 index 00000000000..fbb62bf799e --- /dev/null +++ b/res/drawable/ic_illustration_fullscreen.xml @@ -0,0 +1,39 @@ + + + + + + + + + diff --git a/res/drawable/ic_illustration_switch.xml b/res/drawable/ic_illustration_switch.xml new file mode 100644 index 00000000000..9d3990b5d73 --- /dev/null +++ b/res/drawable/ic_illustration_switch.xml @@ -0,0 +1,46 @@ + + + + + + + + + + + diff --git a/res/drawable/ic_illustration_window.xml b/res/drawable/ic_illustration_window.xml new file mode 100644 index 00000000000..1b87d7d22c4 --- /dev/null +++ b/res/drawable/ic_illustration_window.xml @@ -0,0 +1,41 @@ + + + + + + + + + diff --git a/src/com/android/settings/accessibility/MagnificationSettingsFragment.java b/src/com/android/settings/accessibility/MagnificationSettingsFragment.java index c4d6fd5c752..520de01271d 100644 --- a/src/com/android/settings/accessibility/MagnificationSettingsFragment.java +++ b/src/com/android/settings/accessibility/MagnificationSettingsFragment.java @@ -209,15 +209,15 @@ public class MagnificationSettingsFragment extends DashboardFragment { mModeInfos.clear(); mModeInfos.add(new MagnificationModeInfo(getPrefContext().getText( R.string.accessibility_magnification_mode_dialog_option_full_screen), null, - R.drawable.accessibility_magnification_full_screen, MagnificationMode.FULLSCREEN)); + R.drawable.ic_illustration_fullscreen, MagnificationMode.FULLSCREEN)); mModeInfos.add(new MagnificationModeInfo(getPrefContext().getText( R.string.accessibility_magnification_mode_dialog_option_window), null, - R.drawable.accessibility_magnification_window_screen, MagnificationMode.WINDOW)); + R.drawable.ic_illustration_window, MagnificationMode.WINDOW)); mModeInfos.add(new MagnificationModeInfo(getPrefContext().getText( R.string.accessibility_magnification_mode_dialog_option_switch), getPrefContext().getText( R.string.accessibility_magnification_area_settings_mode_switch_summary), - R.drawable.accessibility_magnification_switch, MagnificationMode.ALL)); + R.drawable.ic_illustration_switch, MagnificationMode.ALL)); } @VisibleForTesting From 41db38c0af289ce0ad479691173c41e0becd2a9e Mon Sep 17 00:00:00 2001 From: Sunny Shao Date: Tue, 6 Apr 2021 17:27:47 +0800 Subject: [PATCH 04/16] Refine the summary of "Open by default" in "App info" page Fixes: 184597364 Test: make RunSettingsRoboTests ROBOTEST_FILTER=com.android.settings.applications.appinfo Change-Id: I9e453c719e5d06570ab1093ffe5510c3e9c7567b --- .../AppOpenByDefaultPreferenceController.java | 31 +++++++++++++------ ...OpenByDefaultPreferenceControllerTest.java | 23 ++++++++++++++ 2 files changed, 45 insertions(+), 9 deletions(-) diff --git a/src/com/android/settings/applications/appinfo/AppOpenByDefaultPreferenceController.java b/src/com/android/settings/applications/appinfo/AppOpenByDefaultPreferenceController.java index d8c190fb730..2c76f056a7c 100644 --- a/src/com/android/settings/applications/appinfo/AppOpenByDefaultPreferenceController.java +++ b/src/com/android/settings/applications/appinfo/AppOpenByDefaultPreferenceController.java @@ -19,29 +19,29 @@ package com.android.settings.applications.appinfo; import android.content.Context; import android.content.pm.ApplicationInfo; import android.content.pm.PackageInfo; -import android.content.pm.PackageManager; -import android.hardware.usb.IUsbManager; -import android.os.ServiceManager; +import android.content.pm.verify.domain.DomainVerificationManager; +import android.content.pm.verify.domain.DomainVerificationUserState; import android.os.UserHandle; +import androidx.annotation.VisibleForTesting; import androidx.preference.Preference; import androidx.preference.PreferenceScreen; import com.android.settings.SettingsPreferenceFragment; import com.android.settings.applications.intentpicker.AppLaunchSettings; +import com.android.settings.applications.intentpicker.IntentPickerUtils; +import com.android.settingslib.R; import com.android.settingslib.applications.AppUtils; import com.android.settingslib.applications.ApplicationsState; public class AppOpenByDefaultPreferenceController extends AppInfoPreferenceControllerBase { - private IUsbManager mUsbManager; - private PackageManager mPackageManager; + private final DomainVerificationManager mDomainVerificationManager; private String mPackageName; public AppOpenByDefaultPreferenceController(Context context, String key) { super(context, key); - mUsbManager = IUsbManager.Stub.asInterface(ServiceManager.getService(Context.USB_SERVICE)); - mPackageManager = context.getPackageManager(); + mDomainVerificationManager = context.getSystemService(DomainVerificationManager.class); } /** Set a package name for this controller. */ @@ -69,8 +69,7 @@ public class AppOpenByDefaultPreferenceController extends AppInfoPreferenceContr && !AppUtils.isBrowserApp(mContext, packageInfo.packageName, UserHandle.myUserId())) { preference.setVisible(true); - preference.setSummary(AppUtils.getLaunchByDefaultSummary(mParent.getAppEntry(), - mUsbManager, mPackageManager, mContext)); + preference.setSummary(getSubtext()); } else { preference.setVisible(false); } @@ -80,4 +79,18 @@ public class AppOpenByDefaultPreferenceController extends AppInfoPreferenceContr protected Class getDetailFragmentClass() { return AppLaunchSettings.class; } + + @VisibleForTesting + CharSequence getSubtext() { + return mContext.getText(isLinkHandlingAllowed() + ? R.string.app_link_open_always : R.string.app_link_open_never); + } + + @VisibleForTesting + boolean isLinkHandlingAllowed() { + final DomainVerificationUserState userState = + IntentPickerUtils.getDomainVerificationUserState(mDomainVerificationManager, + mPackageName); + return userState == null ? false : userState.isLinkHandlingAllowed(); + } } diff --git a/tests/robotests/src/com/android/settings/applications/appinfo/AppOpenByDefaultPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/applications/appinfo/AppOpenByDefaultPreferenceControllerTest.java index 10732566b58..e329dcc8b7b 100644 --- a/tests/robotests/src/com/android/settings/applications/appinfo/AppOpenByDefaultPreferenceControllerTest.java +++ b/tests/robotests/src/com/android/settings/applications/appinfo/AppOpenByDefaultPreferenceControllerTest.java @@ -20,6 +20,7 @@ import static com.google.common.truth.Truth.assertThat; import static org.mockito.ArgumentMatchers.any; import static org.mockito.ArgumentMatchers.anyInt; +import static org.mockito.Mockito.doReturn; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.never; import static org.mockito.Mockito.spy; @@ -33,6 +34,7 @@ import android.content.pm.ApplicationInfo; import android.content.pm.PackageInfo; import android.content.pm.PackageManager; import android.content.pm.ResolveInfo; +import android.content.pm.verify.domain.DomainVerificationManager; import androidx.preference.Preference; import androidx.preference.PreferenceScreen; @@ -66,6 +68,8 @@ public class AppOpenByDefaultPreferenceControllerTest { private Preference mPreference; @Mock private PackageManager mPackageManager; + @Mock + private DomainVerificationManager mDomainVerificationManager; private Context mContext; private AppOpenByDefaultPreferenceController mController; @@ -78,6 +82,8 @@ public class AppOpenByDefaultPreferenceControllerTest { mController.setParentFragment(mFragment); when(mScreen.findPreference(mController.getPreferenceKey())).thenReturn(mPreference); when(mContext.getPackageManager()).thenReturn(mPackageManager); + when(mContext.getSystemService(DomainVerificationManager.class)).thenReturn( + mDomainVerificationManager); } @Test @@ -194,10 +200,27 @@ public class AppOpenByDefaultPreferenceControllerTest { final AppEntry appEntry = mock(AppEntry.class); appEntry.info = new ApplicationInfo(); when(mFragment.getAppEntry()).thenReturn(appEntry); + doReturn(true).when(mController).isLinkHandlingAllowed(); mController.updateState(mPreference); verify(mPreference).setVisible(true); verify(mPreference).setSummary(any()); } + + @Test + public void getSubtext_allowedLinkHandling_returnAllowedString() { + final String allowdedString = "Allow app to open supported links"; + doReturn(true).when(mController).isLinkHandlingAllowed(); + + assertThat(mController.getSubtext()).isEqualTo(allowdedString); + } + + @Test + public void getSubtext_notAllowedLinkHandling_returnNotAllowedString() { + final String notAllowdedString = "Don’t allow app to open links"; + doReturn(false).when(mController).isLinkHandlingAllowed(); + + assertThat(mController.getSubtext()).isEqualTo(notAllowdedString); + } } From ebcabd9c07355eb1111fd7a7a780545ae02880a4 Mon Sep 17 00:00:00 2001 From: Tsung-Mao Fang Date: Tue, 6 Apr 2021 18:27:06 +0800 Subject: [PATCH 05/16] Fix ANR on ShorcutManager#getPinnedShortcuts By design, ShorcutManager#getPinnedShortcuts is meant to called on a work thread. Fix: 183785618 Test: Switch the user profile, and function works properly. Change-Id: I87b8d3f57123ff12f83f95fc7f053b8840028ebe --- src/com/android/settings/SettingsInitialize.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/com/android/settings/SettingsInitialize.java b/src/com/android/settings/SettingsInitialize.java index 515703358e5..cd949deca92 100644 --- a/src/com/android/settings/SettingsInitialize.java +++ b/src/com/android/settings/SettingsInitialize.java @@ -39,6 +39,7 @@ import android.util.Log; import androidx.annotation.VisibleForTesting; import com.android.settings.Settings.CreateShortcutActivity; +import com.android.settingslib.utils.ThreadUtils; import java.util.ArrayList; import java.util.List; @@ -62,7 +63,7 @@ public class SettingsInitialize extends BroadcastReceiver { final PackageManager pm = context.getPackageManager(); managedProfileSetup(context, pm, broadcast, userInfo); webviewSettingSetup(context, pm, userInfo); - refreshExistingShortcuts(context); + ThreadUtils.postOnBackgroundThread(() -> refreshExistingShortcuts(context)); } private void managedProfileSetup(Context context, final PackageManager pm, Intent broadcast, @@ -142,5 +143,4 @@ public class SettingsInitialize extends BroadcastReceiver { } shortcutManager.updateShortcuts(updates); } - } From 3be24f4ab2dfe605884e984c615433c198ea7680 Mon Sep 17 00:00:00 2001 From: Almaz Mingaleev Date: Tue, 30 Mar 2021 16:49:11 +0100 Subject: [PATCH 06/16] Move MIN_USE_DATE_OF_TIMEZONE to TimeUtils. That timestamp is used in two places for the same purpose. Bug: 155738410 Test: presubmit Change-Id: Ia6836fd34c63aef6e335ef97922d34a60dbf3703 --- .../model/FilteredCountryTimeZones.java | 19 ++----------------- 1 file changed, 2 insertions(+), 17 deletions(-) diff --git a/src/com/android/settings/datetime/timezone/model/FilteredCountryTimeZones.java b/src/com/android/settings/datetime/timezone/model/FilteredCountryTimeZones.java index 05a542d9bcd..3035b8c2c20 100644 --- a/src/com/android/settings/datetime/timezone/model/FilteredCountryTimeZones.java +++ b/src/com/android/settings/datetime/timezone/model/FilteredCountryTimeZones.java @@ -17,10 +17,10 @@ package com.android.settings.datetime.timezone.model; import android.util.ArraySet; +import android.util.TimeUtils; import com.android.i18n.timezone.CountryTimeZones; -import java.time.Instant; import java.util.ArrayList; import java.util.Collections; import java.util.List; @@ -31,21 +31,6 @@ import java.util.Set; */ public class FilteredCountryTimeZones { - /** - * The timestamp used to determine which time zones to show to users by using the notUsedAfter - * metadata Android holds for each time zone. - * - * notUsedAfter exists because some time zones effectively "merge" with other time zones after - * a given point in time (i.e. they have identical transitions, offsets, etc.). After that - * point we only need to show one of the functionally identical ones. - * - * Rather than using System.currentTimeMillis(), UX folks asked for consistent behavior and so - * a timestamp known to be in the recent past is used. This should be updated occasionally but - * it doesn't have to be very often. - */ - private static final Instant MIN_USE_DATE_OF_TIMEZONE = - Instant.ofEpochMilli(1546300800000L); // 1/1/2019 00:00 UTC - private final CountryTimeZones mCountryTimeZones; private final List mPreferredTimeZoneIds; private final Set mAlternativeTimeZoneIds; @@ -56,7 +41,7 @@ public class FilteredCountryTimeZones { Set alternativeTimeZoneIds = new ArraySet<>(); for (CountryTimeZones.TimeZoneMapping timeZoneMapping : countryTimeZones.getTimeZoneMappings()) { - if (timeZoneMapping.isShownInPickerAt(MIN_USE_DATE_OF_TIMEZONE)) { + if (timeZoneMapping.isShownInPickerAt(TimeUtils.MIN_USE_DATE_OF_TIMEZONE)) { String timeZoneId = timeZoneMapping.getTimeZoneId(); timeZoneIds.add(timeZoneId); alternativeTimeZoneIds.addAll(timeZoneMapping.getAlternativeIds()); From 4981dc6ea1643ff23a75f892a6e34a51c8541a21 Mon Sep 17 00:00:00 2001 From: Weng Su Date: Tue, 6 Apr 2021 18:03:24 +0800 Subject: [PATCH 07/16] Maximize compatibility string update - Single AP device: Title: Extend compatibility Summary: Helps other devices find this hotspot. Reduces hotspot connection speed. - Dual AP device: Title: Extend compatibility Summary: Helps other devices find this hotspot. Increases battery usage. - Screenshot: https://screenshot.googleplex.com/84sFvsDegjvJfWT Bug: 184595717 Test: manual test atest -c WifiTetherMaximizeCompatibilityPreferenceControllerTest Change-Id: Idca20d4cf5b174110f800fbed91c404d13994b94 --- res/values/strings.xml | 8 +++-- res/xml/wifi_tether_settings.xml | 3 +- ...mizeCompatibilityPreferenceController.java | 5 +++ ...CompatibilityPreferenceControllerTest.java | 35 +++++++++++++++---- 4 files changed, 40 insertions(+), 11 deletions(-) diff --git a/res/values/strings.xml b/res/values/strings.xml index fcf2f45b075..b8994b701f5 100644 --- a/res/values/strings.xml +++ b/res/values/strings.xml @@ -2508,9 +2508,11 @@ When no devices are connected - Maximize compatibility - - This may reduce speed for devices connected to this hotspot and use more power + Extend compatibility + + Helps other devices find this hotspot. Reduces hotspot connection speed. + + Helps other devices find this hotspot. Increases battery usage. Turning hotspot on\u2026 diff --git a/res/xml/wifi_tether_settings.xml b/res/xml/wifi_tether_settings.xml index 8648cff0f43..21f347bb021 100644 --- a/res/xml/wifi_tether_settings.xml +++ b/res/xml/wifi_tether_settings.xml @@ -44,6 +44,5 @@ + android:title="@string/wifi_hotspot_maximize_compatibility"/> diff --git a/src/com/android/settings/wifi/tether/WifiTetherMaximizeCompatibilityPreferenceController.java b/src/com/android/settings/wifi/tether/WifiTetherMaximizeCompatibilityPreferenceController.java index 41532d00e70..67d1f49a5f9 100644 --- a/src/com/android/settings/wifi/tether/WifiTetherMaximizeCompatibilityPreferenceController.java +++ b/src/com/android/settings/wifi/tether/WifiTetherMaximizeCompatibilityPreferenceController.java @@ -24,6 +24,8 @@ import androidx.annotation.VisibleForTesting; import androidx.preference.Preference; import androidx.preference.SwitchPreference; +import com.android.settings.R; + /** * This controller helps to manage the state of maximize compatibility switch preference. */ @@ -53,6 +55,9 @@ public class WifiTetherMaximizeCompatibilityPreferenceController extends } mPreference.setEnabled(is5GhzBandSupported()); ((SwitchPreference) mPreference).setChecked(mIsChecked); + mPreference.setSummary(mWifiManager.isBridgedApConcurrencySupported() + ? R.string.wifi_hotspot_maximize_compatibility_dual_ap_summary + : R.string.wifi_hotspot_maximize_compatibility_single_ap_summary); } @Override diff --git a/tests/unit/src/com/android/settings/wifi/tether/WifiTetherMaximizeCompatibilityPreferenceControllerTest.java b/tests/unit/src/com/android/settings/wifi/tether/WifiTetherMaximizeCompatibilityPreferenceControllerTest.java index 072978040b9..0ee9e70fe71 100644 --- a/tests/unit/src/com/android/settings/wifi/tether/WifiTetherMaximizeCompatibilityPreferenceControllerTest.java +++ b/tests/unit/src/com/android/settings/wifi/tether/WifiTetherMaximizeCompatibilityPreferenceControllerTest.java @@ -34,6 +34,8 @@ import androidx.preference.SwitchPreference; import androidx.test.core.app.ApplicationProvider; import androidx.test.ext.junit.runners.AndroidJUnit4; +import com.android.settings.testutils.ResourcesUtils; + import org.junit.Before; import org.junit.Rule; import org.junit.Test; @@ -52,29 +54,30 @@ public class WifiTetherMaximizeCompatibilityPreferenceControllerTest { @Mock private WifiTetherBasePreferenceController.OnTetherConfigUpdateListener mListener; + private Context mContext; private WifiTetherMaximizeCompatibilityPreferenceController mController; private SwitchPreference mPreference; private SoftApConfiguration mConfig; @Before public void setUp() { - final Context context = spy(ApplicationProvider.getApplicationContext()); + mContext = spy(ApplicationProvider.getApplicationContext()); mConfig = new SoftApConfiguration.Builder() .setSsid("test_Ssid") .setPassphrase(null, SoftApConfiguration.SECURITY_TYPE_OPEN) .setBridgedModeOpportunisticShutdownEnabled(true) .build(); - doReturn(mWifiManager).when(context).getSystemService(Context.WIFI_SERVICE); + doReturn(mWifiManager).when(mContext).getSystemService(Context.WIFI_SERVICE); doReturn(true).when(mWifiManager).isBridgedApConcurrencySupported(); doReturn(mConfig).when(mWifiManager).getSoftApConfiguration(); - mController = new WifiTetherMaximizeCompatibilityPreferenceController(context, mListener); + mController = new WifiTetherMaximizeCompatibilityPreferenceController(mContext, mListener); if (Looper.myLooper() == null) { Looper.prepare(); } - final PreferenceManager preferenceManager = new PreferenceManager(context); - final PreferenceScreen screen = preferenceManager.createPreferenceScreen(context); - mPreference = new SwitchPreference(context); + final PreferenceManager preferenceManager = new PreferenceManager(mContext); + final PreferenceScreen screen = preferenceManager.createPreferenceScreen(mContext); + mPreference = new SwitchPreference(mContext); mPreference.setKey(WifiTetherMaximizeCompatibilityPreferenceController.PREF_KEY); screen.addPreference(mPreference); mController.displayPreference(screen); @@ -104,6 +107,26 @@ public class WifiTetherMaximizeCompatibilityPreferenceControllerTest { assertThat(mPreference.isEnabled()).isEqualTo(false); } + @Test + public void updateDisplay_notSupportedBridgedApConcurrency_setSingleApSummary() { + doReturn(false).when(mWifiManager).isBridgedApConcurrencySupported(); + + mController.updateDisplay(); + + assertThat(mPreference.getSummary()).isEqualTo(ResourcesUtils.getResourcesString(mContext, + "wifi_hotspot_maximize_compatibility_single_ap_summary")); + } + + @Test + public void updateDisplay_supportedBridgedApConcurrency_setDualApSummary() { + doReturn(true).when(mWifiManager).isBridgedApConcurrencySupported(); + + mController.updateDisplay(); + + assertThat(mPreference.getSummary()).isEqualTo(ResourcesUtils.getResourcesString(mContext, + "wifi_hotspot_maximize_compatibility_dual_ap_summary")); + } + @Test public void updateDisplay_supported5GHzBandAndCountryCodeIsNotNull_setPreferenceEnabled() { doReturn(true).when(mWifiManager).is5GHzBandSupported(); From b7a66b3068955245642c02e838a228ca7decac9b Mon Sep 17 00:00:00 2001 From: Abel Tesfaye Date: Fri, 12 Mar 2021 21:43:16 +0000 Subject: [PATCH 08/16] Add warning message when camera privacy lock is enabled for smart auto rotate settings fragment Test: locally with flame, make RunSettingsRoboTests -j$(nproc) ROBOTEST_FILTER=SmartAutoRotateCameraStateControllerTest,SmartAutoRotateControllerTest Bug: 177462182 Change-Id: If443bd2456f3fbe76876777be912b204a50f4088 --- res/values/strings.xml | 4 + res/xml/auto_rotate_settings.xml | 6 ++ .../SmartAutoRotateCameraStateController.java | 74 +++++++++++++++++ .../display/SmartAutoRotateController.java | 35 +++++++- .../SmartAutoRotatePreferenceFragment.java | 7 +- ...rtAutoRotateCameraStateControllerTest.java | 82 +++++++++++++++++++ .../SmartAutoRotateControllerTest.java | 10 +++ .../shadow/ShadowSensorPrivacyManager.java | 34 ++++++++ 8 files changed, 249 insertions(+), 3 deletions(-) create mode 100644 src/com/android/settings/display/SmartAutoRotateCameraStateController.java create mode 100644 tests/robotests/src/com/android/settings/display/SmartAutoRotateCameraStateControllerTest.java create mode 100644 tests/robotests/src/com/android/settings/testutils/shadow/ShadowSensorPrivacyManager.java diff --git a/res/values/strings.xml b/res/values/strings.xml index 29609d03d54..cebd16c9eaf 100644 --- a/res/values/strings.xml +++ b/res/values/strings.xml @@ -2851,6 +2851,10 @@ Turn on screen attention Keep screen on when looking at it + + Camera is locked + + Camera must be unlocked for Face Detection Camera access is required for Face Detection. Tap to manage permissions for Device Personalization Services diff --git a/res/xml/auto_rotate_settings.xml b/res/xml/auto_rotate_settings.xml index 7c46d29a544..bc47b81d0be 100644 --- a/res/xml/auto_rotate_settings.xml +++ b/res/xml/auto_rotate_settings.xml @@ -26,6 +26,12 @@ android:summary="@string/auto_rotate_summary_no_permission" settings:controller="com.android.settings.display.SmartAutoRotatePermissionController" /> + + { + mPreference.setVisible(enabled); + updateState(mPreference); + }); + } + + @VisibleForTesting + boolean isCameraLocked() { + return mPrivacyManager.isSensorPrivacyEnabled(SensorPrivacyManager.Sensors.CAMERA); + } + + @Override + public void displayPreference(PreferenceScreen screen) { + super.displayPreference(screen); + mPreference = screen.findPreference(getPreferenceKey()); + ((BannerMessagePreference) mPreference) + .setPositiveButtonText(R.string.allow) + .setPositiveButtonOnClickListener(v -> { + mPrivacyManager.setSensorPrivacy(CAMERA, false); + }); + } + + @Override + @AvailabilityStatus + public int getAvailabilityStatus() { + return isRotationResolverServiceAvailable(mContext) + && isCameraLocked() ? AVAILABLE_UNSEARCHABLE : UNSUPPORTED_ON_DEVICE; + } +} diff --git a/src/com/android/settings/display/SmartAutoRotateController.java b/src/com/android/settings/display/SmartAutoRotateController.java index ca196ba9c8f..e3b2665195b 100644 --- a/src/com/android/settings/display/SmartAutoRotateController.java +++ b/src/com/android/settings/display/SmartAutoRotateController.java @@ -15,6 +15,7 @@ */ package com.android.settings.display; +import static android.hardware.SensorPrivacyManager.Sensors.CAMERA; import static android.provider.Settings.Secure.CAMERA_AUTOROTATE; import android.Manifest; @@ -23,12 +24,15 @@ import android.content.Context; import android.content.Intent; import android.content.pm.PackageManager; import android.content.pm.ResolveInfo; +import android.hardware.SensorPrivacyManager; import android.provider.Settings; import android.service.rotationresolver.RotationResolverService; import android.text.TextUtils; import androidx.preference.Preference; +import androidx.preference.PreferenceScreen; +import com.android.internal.annotations.VisibleForTesting; import com.android.internal.view.RotationPolicy; import com.android.settings.core.TogglePreferenceController; import com.android.settings.overlay.FeatureFactory; @@ -41,10 +45,14 @@ public class SmartAutoRotateController extends TogglePreferenceController implem Preference.OnPreferenceChangeListener { private final MetricsFeatureProvider mMetricsFeatureProvider; + private final SensorPrivacyManager mPrivacyManager; + private Preference mPreference; public SmartAutoRotateController(Context context, String preferenceKey) { super(context, preferenceKey); mMetricsFeatureProvider = FeatureFactory.getFactory(context).getMetricsFeatureProvider(); + mPrivacyManager = SensorPrivacyManager.getInstance(context); + mPrivacyManager.addSensorPrivacyListener(CAMERA, enabled -> updateState(mPreference)); } @Override @@ -53,16 +61,39 @@ public class SmartAutoRotateController extends TogglePreferenceController implem return UNSUPPORTED_ON_DEVICE; } return !RotationPolicy.isRotationLocked(mContext) && hasSufficientPermission(mContext) - ? AVAILABLE : DISABLED_DEPENDENT_SETTING; + && !isCameraLocked() ? AVAILABLE : DISABLED_DEPENDENT_SETTING; + } + + @Override + public void updateState(Preference preference) { + super.updateState(preference); + if (preference != null) { + preference.setEnabled(getAvailabilityStatus() == AVAILABLE); + } + } + + /** + * Need this because all controller tests use RoboElectric. No easy way to mock this service, + * so we mock the call we need + */ + @VisibleForTesting + boolean isCameraLocked() { + return mPrivacyManager.isSensorPrivacyEnabled(SensorPrivacyManager.Sensors.CAMERA); } @Override public boolean isChecked() { - return hasSufficientPermission(mContext) && Settings.Secure.getInt( + return hasSufficientPermission(mContext) && !isCameraLocked() && Settings.Secure.getInt( mContext.getContentResolver(), CAMERA_AUTOROTATE, 0) == 1; } + @Override + public void displayPreference(PreferenceScreen screen) { + super.displayPreference(screen); + mPreference = screen.findPreference(getPreferenceKey()); + } + @Override public boolean setChecked(boolean isChecked) { mMetricsFeatureProvider.action(mContext, SettingsEnums.ACTION_CAMERA_ROTATE_TOGGLE, diff --git a/src/com/android/settings/display/SmartAutoRotatePreferenceFragment.java b/src/com/android/settings/display/SmartAutoRotatePreferenceFragment.java index 130bbd80f17..1a91775c408 100644 --- a/src/com/android/settings/display/SmartAutoRotatePreferenceFragment.java +++ b/src/com/android/settings/display/SmartAutoRotatePreferenceFragment.java @@ -19,6 +19,7 @@ import static com.android.settings.display.SmartAutoRotateController.hasSufficie import static com.android.settings.display.SmartAutoRotateController.isRotationResolverServiceAvailable; import android.app.settings.SettingsEnums; +import android.hardware.SensorPrivacyManager; import android.os.Bundle; import android.text.Html; import android.view.LayoutInflater; @@ -47,6 +48,7 @@ public class SmartAutoRotatePreferenceFragment extends DashboardFragment { private static final String TAG = "SmartAutoRotatePreferenceFragment"; private RotationPolicy.RotationPolicyListener mRotationPolicyListener; + private SensorPrivacyManager mPrivacyManager; private AutoRotateSwitchBarController mSwitchBarController; private static final String FACE_SWITCH_PREFERENCE_ID = "face_based_rotate"; @@ -66,6 +68,7 @@ public class SmartAutoRotatePreferenceFragment extends DashboardFragment { switchBar.show(); mSwitchBarController = new AutoRotateSwitchBarController(activity, switchBar, getSettingsLifecycle()); + mPrivacyManager = SensorPrivacyManager.getInstance(activity); final Preference footerPreference = findPreference(FooterPreference.KEY_FOOTER); if (footerPreference != null) { footerPreference.setTitle(Html.fromHtml(getString(R.string.smart_rotate_text_headline), @@ -84,9 +87,11 @@ public class SmartAutoRotatePreferenceFragment extends DashboardFragment { public void onChange() { mSwitchBarController.onChange(); final boolean isLocked = RotationPolicy.isRotationLocked(getContext()); + final boolean isCameraLocked = mPrivacyManager.isSensorPrivacyEnabled( + SensorPrivacyManager.Sensors.CAMERA); final Preference preference = findPreference(FACE_SWITCH_PREFERENCE_ID); if (preference != null && hasSufficientPermission(getContext())) { - preference.setEnabled(!isLocked); + preference.setEnabled(!isLocked && !isCameraLocked); } } }; diff --git a/tests/robotests/src/com/android/settings/display/SmartAutoRotateCameraStateControllerTest.java b/tests/robotests/src/com/android/settings/display/SmartAutoRotateCameraStateControllerTest.java new file mode 100644 index 00000000000..ffd6411d329 --- /dev/null +++ b/tests/robotests/src/com/android/settings/display/SmartAutoRotateCameraStateControllerTest.java @@ -0,0 +1,82 @@ +/* + * Copyright (C) 2021 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.settings.display; + +import static com.android.settings.core.BasePreferenceController.AVAILABLE_UNSEARCHABLE; +import static com.android.settings.core.BasePreferenceController.UNSUPPORTED_ON_DEVICE; + +import static com.google.common.truth.Truth.assertThat; + +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.ArgumentMatchers.anyInt; +import static org.mockito.Mockito.doReturn; +import static org.mockito.Mockito.when; + +import android.content.ContentResolver; +import android.content.Context; +import android.content.pm.PackageManager; +import android.content.pm.ResolveInfo; +import android.content.pm.ServiceInfo; + +import com.android.settings.testutils.ResolveInfoBuilder; +import com.android.settings.testutils.shadow.ShadowSensorPrivacyManager; + +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.Mockito; +import org.mockito.MockitoAnnotations; +import org.robolectric.RobolectricTestRunner; +import org.robolectric.RuntimeEnvironment; +import org.robolectric.annotation.Config; + +@RunWith(RobolectricTestRunner.class) +@Config(shadows = ShadowSensorPrivacyManager.class) +public class SmartAutoRotateCameraStateControllerTest { + + private static final String PACKAGE_NAME = "package_name"; + + private SmartAutoRotateCameraStateController mController; + + @Before + public void setUp() { + MockitoAnnotations.initMocks(this); + final Context context = Mockito.spy(RuntimeEnvironment.application); + final ContentResolver contentResolver = RuntimeEnvironment.application.getContentResolver(); + when(context.getContentResolver()).thenReturn(contentResolver); + final PackageManager packageManager = Mockito.mock(PackageManager.class); + when(context.getPackageManager()).thenReturn(packageManager); + doReturn(PACKAGE_NAME).when(packageManager).getRotationResolverPackageName(); + mController = new SmartAutoRotateCameraStateController(context, "smart_auto_rotate"); + when(mController.isCameraLocked()).thenReturn(false); + + final ResolveInfo resolveInfo = new ResolveInfoBuilder(PACKAGE_NAME).build(); + resolveInfo.serviceInfo = new ServiceInfo(); + when(packageManager.resolveService(any(), anyInt())).thenReturn(resolveInfo); + } + + @Test + public void getAvailabilityStatus_returnUnsupportedOnDevice() { + assertThat(mController.getAvailabilityStatus()).isEqualTo(UNSUPPORTED_ON_DEVICE); + } + + @Test + public void getAvailabilityStatus_cameraNotEnabled_returnAvailableUnSearchAble() { + when(mController.isCameraLocked()).thenReturn(true); + assertThat(mController.getAvailabilityStatus()).isEqualTo(AVAILABLE_UNSEARCHABLE); + } +} diff --git a/tests/robotests/src/com/android/settings/display/SmartAutoRotateControllerTest.java b/tests/robotests/src/com/android/settings/display/SmartAutoRotateControllerTest.java index 2d56c0efd88..a65d8806f77 100644 --- a/tests/robotests/src/com/android/settings/display/SmartAutoRotateControllerTest.java +++ b/tests/robotests/src/com/android/settings/display/SmartAutoRotateControllerTest.java @@ -39,6 +39,7 @@ import android.provider.Settings; import androidx.preference.Preference; import com.android.settings.testutils.ResolveInfoBuilder; +import com.android.settings.testutils.shadow.ShadowSensorPrivacyManager; import org.junit.Before; import org.junit.Test; @@ -48,8 +49,10 @@ import org.mockito.Mockito; import org.mockito.MockitoAnnotations; import org.robolectric.RobolectricTestRunner; import org.robolectric.RuntimeEnvironment; +import org.robolectric.annotation.Config; @RunWith(RobolectricTestRunner.class) +@Config(shadows = ShadowSensorPrivacyManager.class) public class SmartAutoRotateControllerTest { private static final String PACKAGE_NAME = "package_name"; @@ -72,6 +75,7 @@ public class SmartAutoRotateControllerTest { doReturn(PackageManager.PERMISSION_GRANTED).when(mPackageManager).checkPermission( Manifest.permission.CAMERA, PACKAGE_NAME); mController = new SmartAutoRotateController(context, "test_key"); + when(mController.isCameraLocked()).thenReturn(false); doReturn(mController.getPreferenceKey()).when(mPreference).getKey(); final ResolveInfo resolveInfo = new ResolveInfoBuilder(PACKAGE_NAME).build(); @@ -105,6 +109,12 @@ public class SmartAutoRotateControllerTest { assertThat(mController.getAvailabilityStatus()).isEqualTo(DISABLED_DEPENDENT_SETTING); } + @Test + public void getAvailabilityStatus_cameraDisabled_returnDisableDependentSetting() { + when(mController.isCameraLocked()).thenReturn(true); + assertThat(mController.getAvailabilityStatus()).isEqualTo(DISABLED_DEPENDENT_SETTING); + } + private void enableAutoRotation() { Settings.System.putIntForUser(mContentResolver, Settings.System.ACCELEROMETER_ROTATION, 1, UserHandle.USER_CURRENT); diff --git a/tests/robotests/src/com/android/settings/testutils/shadow/ShadowSensorPrivacyManager.java b/tests/robotests/src/com/android/settings/testutils/shadow/ShadowSensorPrivacyManager.java new file mode 100644 index 00000000000..b15311066ed --- /dev/null +++ b/tests/robotests/src/com/android/settings/testutils/shadow/ShadowSensorPrivacyManager.java @@ -0,0 +1,34 @@ +/* + * Copyright (C) 2021 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.settings.testutils.shadow; + +import static org.mockito.Mockito.mock; + +import android.content.Context; +import android.hardware.SensorPrivacyManager; + +import org.robolectric.annotation.Implementation; +import org.robolectric.annotation.Implements; + +@Implements(value = SensorPrivacyManager.class) +public class ShadowSensorPrivacyManager { + + @Implementation + public static SensorPrivacyManager getInstance(Context context) { + return mock(SensorPrivacyManager.class); + } +} From 0a03f8e2d2fbafd80876555836306d50b09c6f76 Mon Sep 17 00:00:00 2001 From: ykhung Date: Wed, 7 Apr 2021 09:44:10 +0800 Subject: [PATCH 09/16] Add new battery usage design required string and dimesions Bug: 183921876 Test: make SettingsRoboTests Test: make SettingsGoogleRoboTests Change-Id: I82fed0a38168aba47e8267ab4a5fa072d54dce67 --- res/layout/battery_chart_graph.xml | 42 ++++++++++++++++++++++++++++++ res/values/dimens.xml | 7 +++++ res/values/strings.xml | 15 +++++++++++ 3 files changed, 64 insertions(+) create mode 100644 res/layout/battery_chart_graph.xml diff --git a/res/layout/battery_chart_graph.xml b/res/layout/battery_chart_graph.xml new file mode 100644 index 00000000000..ed21586ad88 --- /dev/null +++ b/res/layout/battery_chart_graph.xml @@ -0,0 +1,42 @@ + + + + + + + + + + diff --git a/res/values/dimens.xml b/res/values/dimens.xml index e0e02193451..aca3322eca1 100755 --- a/res/values/dimens.xml +++ b/res/values/dimens.xml @@ -446,4 +446,11 @@ 24dp + + + 1dp + 4dp + 2dp + 1dp + 2dp diff --git a/res/values/strings.xml b/res/values/strings.xml index fcf2f45b075..d06e8af2556 100644 --- a/res/values/strings.xml +++ b/res/values/strings.xml @@ -6348,6 +6348,21 @@ Show battery percentage in status bar + + Battery level for past 24 hr + + App usage for past 24 hr + + System usage for past 24 hr + + System usage for + + App usage for + + am + + pm + From b350c66d97a8a7e2b9ec8a05a1f4513ae124d1ff Mon Sep 17 00:00:00 2001 From: ykhung Date: Wed, 7 Apr 2021 11:04:39 +0800 Subject: [PATCH 10/16] Move the battery components from SettingsGoogle to Settings Bug: 183921876 Test: make SettingsRoboTests Test: make SettingsGoogleRoboTests Change-Id: I47cbba1cbfd6cb17745e7aaaf56b22e3c9dcd30e --- res/layout/battery_chart_graph.xml | 2 +- .../settings/fuelgauge/BatteryChartView.java | 268 ++++++++++++++++++ .../settings/fuelgauge/BatteryHistEntry.java | 112 ++++++++ .../settings/fuelgauge/ConvertUtils.java | 105 +++++++ .../fuelgauge/BatteryHistEntryTest.java | 110 +++++++ .../settings/fuelgauge/ConvertUtilsTest.java | 145 ++++++++++ 6 files changed, 741 insertions(+), 1 deletion(-) create mode 100644 src/com/android/settings/fuelgauge/BatteryChartView.java create mode 100644 src/com/android/settings/fuelgauge/BatteryHistEntry.java create mode 100644 src/com/android/settings/fuelgauge/ConvertUtils.java create mode 100644 tests/robotests/src/com/android/settings/fuelgauge/BatteryHistEntryTest.java create mode 100644 tests/robotests/src/com/android/settings/fuelgauge/ConvertUtilsTest.java diff --git a/res/layout/battery_chart_graph.xml b/res/layout/battery_chart_graph.xml index ed21586ad88..7f3bbf38c3a 100644 --- a/res/layout/battery_chart_graph.xml +++ b/res/layout/battery_chart_graph.xml @@ -1,5 +1,5 @@ - - + android:clipChildren="true"> - \ No newline at end of file + \ No newline at end of file From 50f314e45dd970030df00938c81cbb9289e1ede4 Mon Sep 17 00:00:00 2001 From: "Wesley.CW Wang" Date: Thu, 1 Apr 2021 18:56:57 +0800 Subject: [PATCH 12/16] Update StringUtil#formatElapsedTime method (2/3) - Update the usage and the test case - Update discharging string to follow new string doc Bug: 183689347 Test: make RunSettingsRoboTests Change-Id: I1e14e7da8cb02755d8cf6e12626a0d94fad87121 --- .../AdvancedBluetoothDetailsHeaderController.java | 7 ++++++- .../datausage/DataUsageSummaryPreference.java | 5 ++++- .../settings/fuelgauge/AdvancedPowerUsageDetail.java | 12 ++++++++++-- .../BatteryAppListPreferenceController.java | 2 +- src/com/android/settings/fuelgauge/BatteryInfo.java | 9 ++++++--- .../details2/WifiDetailPreferenceController2.java | 2 +- ...AdvancedBluetoothDetailsHeaderControllerTest.java | 4 ++-- .../android/settings/fuelgauge/BatteryInfoTest.java | 5 ++--- .../WifiDetailPreferenceController2Test.java | 6 +++++- 9 files changed, 37 insertions(+), 15 deletions(-) diff --git a/src/com/android/settings/bluetooth/AdvancedBluetoothDetailsHeaderController.java b/src/com/android/settings/bluetooth/AdvancedBluetoothDetailsHeaderController.java index 4c30baa5b27..e502d654041 100644 --- a/src/com/android/settings/bluetooth/AdvancedBluetoothDetailsHeaderController.java +++ b/src/com/android/settings/bluetooth/AdvancedBluetoothDetailsHeaderController.java @@ -364,7 +364,12 @@ public class AdvancedBluetoothDetailsHeaderController extends BasePreferenceCont final TextView textView = linearLayout.findViewById(R.id.bt_battery_prediction); if (estimateReady == 1) { textView.setVisibility(View.VISIBLE); - textView.setText(StringUtil.formatElapsedTime(mContext, batteryEstimate, false)); + textView.setText( + StringUtil.formatElapsedTime( + mContext, + batteryEstimate, + /* withSeconds */ false, + /* collapseTimeUnit */ false)); } else { textView.setVisibility(View.GONE); } diff --git a/src/com/android/settings/datausage/DataUsageSummaryPreference.java b/src/com/android/settings/datausage/DataUsageSummaryPreference.java index 9cbb921537f..f1728b6a02b 100644 --- a/src/com/android/settings/datausage/DataUsageSummaryPreference.java +++ b/src/com/android/settings/datausage/DataUsageSummaryPreference.java @@ -318,7 +318,10 @@ public class DataUsageSummaryPreference extends Preference { textResourceId = R.string.no_carrier_update_text; } updateTime = StringUtil.formatElapsedTime( - getContext(), updateAgeMillis, false /* withSeconds */); + getContext(), + updateAgeMillis, + false /* withSeconds */, + false /* collapseTimeUnit */); } carrierInfo.setText(TextUtils.expandTemplate( getContext().getText(textResourceId), diff --git a/src/com/android/settings/fuelgauge/AdvancedPowerUsageDetail.java b/src/com/android/settings/fuelgauge/AdvancedPowerUsageDetail.java index 399a84d7fea..f4bdfb3f899 100644 --- a/src/com/android/settings/fuelgauge/AdvancedPowerUsageDetail.java +++ b/src/com/android/settings/fuelgauge/AdvancedPowerUsageDetail.java @@ -229,10 +229,18 @@ public class AdvancedPowerUsageDetail extends DashboardFragment implements final long backgroundTimeMs = bundle.getLong(EXTRA_BACKGROUND_TIME); mForegroundPreference.setSummary( TextUtils.expandTemplate(getText(R.string.battery_used_for), - StringUtil.formatElapsedTime(context, foregroundTimeMs, false))); + StringUtil.formatElapsedTime( + context, + foregroundTimeMs, + /* withSeconds */ false, + /* collapseTimeUnit */ false))); mBackgroundPreference.setSummary( TextUtils.expandTemplate(getText(R.string.battery_active_for), - StringUtil.formatElapsedTime(context, backgroundTimeMs, false))); + StringUtil.formatElapsedTime( + context, + backgroundTimeMs, + /* withSeconds */ false, + /* collapseTimeUnit */ false))); } @Override diff --git a/src/com/android/settings/fuelgauge/BatteryAppListPreferenceController.java b/src/com/android/settings/fuelgauge/BatteryAppListPreferenceController.java index a55d0d34bfb..4053e869f78 100644 --- a/src/com/android/settings/fuelgauge/BatteryAppListPreferenceController.java +++ b/src/com/android/settings/fuelgauge/BatteryAppListPreferenceController.java @@ -380,7 +380,7 @@ public class BatteryAppListPreferenceController extends AbstractPreferenceContro final long usageTimeMs = entry.getTimeInForegroundMs(); if (shouldShowSummary(entry) && usageTimeMs >= DateUtils.MINUTE_IN_MILLIS) { final CharSequence timeSequence = - StringUtil.formatElapsedTime(mContext, usageTimeMs, false); + StringUtil.formatElapsedTime(mContext, usageTimeMs, false, false); preference.setSummary( entry.isHidden() ? timeSequence diff --git a/src/com/android/settings/fuelgauge/BatteryInfo.java b/src/com/android/settings/fuelgauge/BatteryInfo.java index a4dd86c1fa7..832936cf6b5 100644 --- a/src/com/android/settings/fuelgauge/BatteryInfo.java +++ b/src/com/android/settings/fuelgauge/BatteryInfo.java @@ -263,8 +263,11 @@ public class BatteryInfo { context.getString(chargingLimitedResId, info.batteryPercentString); } else if (chargeTimeMs > 0 && status != BatteryManager.BATTERY_STATUS_FULL) { info.remainingTimeUs = PowerUtil.convertMsToUs(chargeTimeMs); - CharSequence timeString = StringUtil.formatElapsedTime(context, - PowerUtil.convertUsToMs(info.remainingTimeUs), false /* withSeconds */); + final CharSequence timeString = StringUtil.formatElapsedTime( + context, + PowerUtil.convertUsToMs(info.remainingTimeUs), + false /* withSeconds */, + true /* collapseTimeUnit */); int resId = R.string.power_charging_duration; info.remainingLabel = context.getString( R.string.power_remaining_charging_duration_only, timeString); @@ -287,7 +290,7 @@ public class BatteryInfo { context, PowerUtil.convertUsToMs(drainTimeUs), null /* percentageString */, - estimate.isBasedOnUsage() && !shortString + false /* basedOnUsage */ ); info.chargeLabel = PowerUtil.getBatteryRemainingStringFormatted( context, diff --git a/src/com/android/settings/wifi/details2/WifiDetailPreferenceController2.java b/src/com/android/settings/wifi/details2/WifiDetailPreferenceController2.java index 0c3f42d53ef..3c312b8f7b9 100644 --- a/src/com/android/settings/wifi/details2/WifiDetailPreferenceController2.java +++ b/src/com/android/settings/wifi/details2/WifiDetailPreferenceController2.java @@ -480,7 +480,7 @@ public class WifiDetailPreferenceController2 extends AbstractPreferenceControlle return mContext.getString(R.string.wifi_time_remaining, StringUtil.formatElapsedTime( mContext, Duration.between(now, expiryTime).getSeconds() * 1000, - false /* withSeconds */)); + false /* withSeconds */, false /* collapseTimeUnit */)); } // For more than 2 days, show the expiry date diff --git a/tests/robotests/src/com/android/settings/bluetooth/AdvancedBluetoothDetailsHeaderControllerTest.java b/tests/robotests/src/com/android/settings/bluetooth/AdvancedBluetoothDetailsHeaderControllerTest.java index 215cddb43aa..5350d45e436 100644 --- a/tests/robotests/src/com/android/settings/bluetooth/AdvancedBluetoothDetailsHeaderControllerTest.java +++ b/tests/robotests/src/com/android/settings/bluetooth/AdvancedBluetoothDetailsHeaderControllerTest.java @@ -473,9 +473,9 @@ public class AdvancedBluetoothDetailsHeaderControllerTest { @Test public void showBatteryPredictionIfNecessary_estimateReadyIsAvailable_showCorrectValue() { final String leftBatteryPrediction = - StringUtil.formatElapsedTime(mContext, 12000000, false).toString(); + StringUtil.formatElapsedTime(mContext, 12000000, false, false).toString(); final String rightBatteryPrediction = - StringUtil.formatElapsedTime(mContext, 1200000, false).toString(); + StringUtil.formatElapsedTime(mContext, 1200000, false, false).toString(); mController.showBatteryPredictionIfNecessary(1, 12000000, mLayoutPreference.findViewById(R.id.layout_left)); diff --git a/tests/robotests/src/com/android/settings/fuelgauge/BatteryInfoTest.java b/tests/robotests/src/com/android/settings/fuelgauge/BatteryInfoTest.java index afec5cbec3e..8eed2cb3836 100644 --- a/tests/robotests/src/com/android/settings/fuelgauge/BatteryInfoTest.java +++ b/tests/robotests/src/com/android/settings/fuelgauge/BatteryInfoTest.java @@ -150,10 +150,9 @@ public class BatteryInfoTest { mBatteryUsageStats, estimate, SystemClock.elapsedRealtime() * 1000, true /* shortString */); - // We only add special mention for the long string - assertThat(info.remainingLabel.toString()).contains(ENHANCED_STRING_SUFFIX); + // Both long and short strings should not have extra text + assertThat(info.remainingLabel.toString()).doesNotContain(ENHANCED_STRING_SUFFIX); assertThat(info.suggestionLabel).contains(BATTERY_RUN_OUT_PREFIX); - // shortened string should not have extra text assertThat(info2.remainingLabel.toString()).doesNotContain(ENHANCED_STRING_SUFFIX); assertThat(info2.suggestionLabel).contains(BATTERY_RUN_OUT_PREFIX); } diff --git a/tests/robotests/src/com/android/settings/wifi/details2/WifiDetailPreferenceController2Test.java b/tests/robotests/src/com/android/settings/wifi/details2/WifiDetailPreferenceController2Test.java index 3e0e22f3d1c..4360a09cb5f 100644 --- a/tests/robotests/src/com/android/settings/wifi/details2/WifiDetailPreferenceController2Test.java +++ b/tests/robotests/src/com/android/settings/wifi/details2/WifiDetailPreferenceController2Test.java @@ -579,7 +579,11 @@ public class WifiDetailPreferenceController2Test { ZoneId.of("Europe/London")); doShouldShowRemainingTimeTest(fakeNow, timeRemainingMs); final String expectedSummary = mContext.getString(R.string.wifi_time_remaining, - StringUtil.formatElapsedTime(mContext, timeRemainingMs, false /* withSeconds */)); + StringUtil.formatElapsedTime( + mContext, + timeRemainingMs, + false /* withSeconds */, + false /* collapseTimeUnit */)); final InOrder inOrder = inOrder(mMockHeaderController); inOrder.verify(mMockHeaderController).setSecondSummary(expectedSummary); From 1599313cafac52c30fe8ab08659cb89a07eae374 Mon Sep 17 00:00:00 2001 From: ykhung Date: Wed, 7 Apr 2021 16:28:11 +0800 Subject: [PATCH 13/16] Remove the current battery usage chart and replace it with new one Bug: 183921876 Test: make SettingsRoboTests Test: make SettingsGoogleRoboTests Change-Id: I06f0eb5c09d07a9db0d1a93cda751e8fad672c79 --- res/layout/battery_chart_graph.xml | 2 +- res/layout/battery_usage_graph.xml | 53 --------- .../settings/fuelgauge/BatteryChartView.java | 1 + .../fuelgauge/BatteryHistoryPreference.java | 48 ++------ .../fuelgauge/PowerUsageAdvanced.java | 18 --- .../fuelgauge/PowerUsageFeatureProvider.java | 5 + .../PowerUsageFeatureProviderImpl.java | 5 + .../BatteryHistoryPreferenceTest.java | 105 ------------------ 8 files changed, 22 insertions(+), 215 deletions(-) delete mode 100644 res/layout/battery_usage_graph.xml delete mode 100644 tests/robotests/src/com/android/settings/fuelgauge/BatteryHistoryPreferenceTest.java diff --git a/res/layout/battery_chart_graph.xml b/res/layout/battery_chart_graph.xml index 7f3bbf38c3a..6187d07b66c 100644 --- a/res/layout/battery_chart_graph.xml +++ b/res/layout/battery_chart_graph.xml @@ -34,7 +34,7 @@ diff --git a/res/layout/battery_usage_graph.xml b/res/layout/battery_usage_graph.xml deleted file mode 100644 index 93001c3f02a..00000000000 --- a/res/layout/battery_usage_graph.xml +++ /dev/null @@ -1,53 +0,0 @@ - - - - - - - - - - - - diff --git a/src/com/android/settings/fuelgauge/BatteryChartView.java b/src/com/android/settings/fuelgauge/BatteryChartView.java index c6529a7867e..47333aa0160 100644 --- a/src/com/android/settings/fuelgauge/BatteryChartView.java +++ b/src/com/android/settings/fuelgauge/BatteryChartView.java @@ -95,6 +95,7 @@ public class BatteryChartView extends AppCompatImageView implements View.OnClick public void setLevels(int[] levels) { // We should provide trapezoid count + 1 data to draw all trapezoids. mLevels = levels.length == mTrapezoidCount + 1 ? levels : null; + setClickable(mLevels != null); invalidate(); } diff --git a/src/com/android/settings/fuelgauge/BatteryHistoryPreference.java b/src/com/android/settings/fuelgauge/BatteryHistoryPreference.java index 4d3b9cd2e56..cb22ff3ac72 100644 --- a/src/com/android/settings/fuelgauge/BatteryHistoryPreference.java +++ b/src/com/android/settings/fuelgauge/BatteryHistoryPreference.java @@ -19,8 +19,8 @@ package com.android.settings.fuelgauge; import android.content.Context; import android.os.BatteryUsageStats; import android.util.AttributeSet; +import android.util.Log; import android.view.View; -import android.widget.TextView; import androidx.annotation.NonNull; import androidx.annotation.VisibleForTesting; @@ -28,26 +28,26 @@ import androidx.preference.Preference; import androidx.preference.PreferenceViewHolder; import com.android.settings.R; -import com.android.settings.widget.UsageView; +import com.android.settings.overlay.FeatureFactory; /** - * Custom preference for displaying power consumption as a bar and an icon on the left for the - * subsystem/app type. + * Custom preference for displaying the battery level as chart graph. */ public class BatteryHistoryPreference extends Preference { private static final String TAG = "BatteryHistoryPreference"; - private CharSequence mSummary; - private TextView mSummaryView; - - @VisibleForTesting - boolean hideSummary; @VisibleForTesting BatteryInfo mBatteryInfo; public BatteryHistoryPreference(Context context, AttributeSet attrs) { super(context, attrs); - setLayoutResource(R.layout.battery_usage_graph); + final boolean isChartGraphEnabled = + FeatureFactory.getFactory(context).getPowerUsageFeatureProvider(context) + .isChartGraphEnabled(context); + Log.i(TAG, "isChartGraphEnabled: " + isChartGraphEnabled); + if (isChartGraphEnabled) { + setLayoutResource(R.layout.battery_chart_graph); + } setSelectable(false); } @@ -58,22 +58,6 @@ public class BatteryHistoryPreference extends Preference { }, batteryUsageStats, false); } - public void setBottomSummary(CharSequence text) { - mSummary = text; - if (mSummaryView != null) { - mSummaryView.setVisibility(View.VISIBLE); - mSummaryView.setText(mSummary); - } - hideSummary = false; - } - - public void hideBottomSummary() { - if (mSummaryView != null) { - mSummaryView.setVisibility(View.GONE); - } - hideSummary = true; - } - @Override public void onBindViewHolder(PreferenceViewHolder view) { super.onBindViewHolder(view); @@ -81,18 +65,6 @@ public class BatteryHistoryPreference extends Preference { if (mBatteryInfo == null) { return; } - - ((TextView) view.findViewById(R.id.charge)).setText(mBatteryInfo.batteryPercentString); - mSummaryView = (TextView) view.findViewById(R.id.bottom_summary); - if (mSummary != null) { - mSummaryView.setText(mSummary); - } - if (hideSummary) { - mSummaryView.setVisibility(View.GONE); - } - UsageView usageView = (UsageView) view.findViewById(R.id.battery_usage); - usageView.findViewById(R.id.label_group).setAlpha(.7f); - mBatteryInfo.bindHistory(usageView); BatteryUtils.logRuntime(TAG, "onBindViewHolder", startTime); } } diff --git a/src/com/android/settings/fuelgauge/PowerUsageAdvanced.java b/src/com/android/settings/fuelgauge/PowerUsageAdvanced.java index 9279e5d3ad6..c5974259e72 100644 --- a/src/com/android/settings/fuelgauge/PowerUsageAdvanced.java +++ b/src/com/android/settings/fuelgauge/PowerUsageAdvanced.java @@ -63,9 +63,6 @@ public class PowerUsageAdvanced extends PowerUsageBase { mHistPref = (BatteryHistoryPreference) findPreference(KEY_BATTERY_GRAPH); mPowerUsageFeatureProvider = FeatureFactory.getFactory(context) .getPowerUsageFeatureProvider(context); - - // init the summary so other preferences won't have unnecessary move - updateHistPrefSummary(context); restoreSavedInstance(icicle); } @@ -151,24 +148,9 @@ public class PowerUsageAdvanced extends PowerUsageBase { return; } updatePreference(mHistPref); - updateHistPrefSummary(context); - mBatteryAppListPreferenceController.refreshAppListGroup(mBatteryUsageStats, mShowAllApps); } - private void updateHistPrefSummary(Context context) { - Intent batteryIntent = - context.registerReceiver(null, new IntentFilter(Intent.ACTION_BATTERY_CHANGED)); - final boolean plugged = batteryIntent.getIntExtra(BatteryManager.EXTRA_PLUGGED, -1) != 0; - - if (mPowerUsageFeatureProvider.isEnhancedBatteryPredictionEnabled(context) && !plugged) { - mHistPref.setBottomSummary( - mPowerUsageFeatureProvider.getAdvancedUsageScreenInfoString()); - } else { - mHistPref.hideBottomSummary(); - } - } - public static final BaseSearchIndexProvider SEARCH_INDEX_DATA_PROVIDER = new BaseSearchIndexProvider() { @Override diff --git a/src/com/android/settings/fuelgauge/PowerUsageFeatureProvider.java b/src/com/android/settings/fuelgauge/PowerUsageFeatureProvider.java index 6a22ed4691a..8557bf76cb5 100644 --- a/src/com/android/settings/fuelgauge/PowerUsageFeatureProvider.java +++ b/src/com/android/settings/fuelgauge/PowerUsageFeatureProvider.java @@ -124,4 +124,9 @@ public interface PowerUsageFeatureProvider { * Checks whether smart battery feature is supported in this device */ boolean isSmartBatterySupported(); + + /** + * Checks whether we should enable chart graph design or not + */ + boolean isChartGraphEnabled(Context context); } diff --git a/src/com/android/settings/fuelgauge/PowerUsageFeatureProviderImpl.java b/src/com/android/settings/fuelgauge/PowerUsageFeatureProviderImpl.java index cb83d80cee6..a3e9aecedd2 100644 --- a/src/com/android/settings/fuelgauge/PowerUsageFeatureProviderImpl.java +++ b/src/com/android/settings/fuelgauge/PowerUsageFeatureProviderImpl.java @@ -150,4 +150,9 @@ public class PowerUsageFeatureProviderImpl implements PowerUsageFeatureProvider return mContext.getResources().getBoolean( com.android.internal.R.bool.config_smart_battery_available); } + + @Override + public boolean isChartGraphEnabled(Context context) { + return false; + } } diff --git a/tests/robotests/src/com/android/settings/fuelgauge/BatteryHistoryPreferenceTest.java b/tests/robotests/src/com/android/settings/fuelgauge/BatteryHistoryPreferenceTest.java deleted file mode 100644 index fc8e99472bb..00000000000 --- a/tests/robotests/src/com/android/settings/fuelgauge/BatteryHistoryPreferenceTest.java +++ /dev/null @@ -1,105 +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.fuelgauge; - -import static com.google.common.truth.Truth.assertThat; - -import static org.mockito.ArgumentMatchers.anyInt; -import static org.mockito.ArgumentMatchers.nullable; -import static org.mockito.Mockito.spy; -import static org.mockito.Mockito.verify; -import static org.mockito.Mockito.when; - -import android.content.Context; -import android.view.LayoutInflater; -import android.view.View; -import android.widget.TextView; - -import androidx.preference.PreferenceViewHolder; - -import com.android.settings.R; -import com.android.settings.widget.UsageView; - -import org.junit.Before; -import org.junit.Test; -import org.junit.runner.RunWith; -import org.mockito.Mock; -import org.mockito.MockitoAnnotations; -import org.robolectric.RobolectricTestRunner; -import org.robolectric.RuntimeEnvironment; - -@RunWith(RobolectricTestRunner.class) -public class BatteryHistoryPreferenceTest { - - private static final String TEST_STRING = "test"; - @Mock - private PreferenceViewHolder mViewHolder; - @Mock - private BatteryInfo mBatteryInfo; - @Mock - private TextView mTextView; - @Mock - private UsageView mUsageView; - @Mock - private View mLabelView; - private BatteryHistoryPreference mBatteryHistoryPreference; - - @Before - public void setUp() { - MockitoAnnotations.initMocks(this); - final Context context = RuntimeEnvironment.application; - final View itemView = - LayoutInflater.from(context).inflate(R.layout.battery_usage_graph, null); - - mBatteryHistoryPreference = new BatteryHistoryPreference(context, null); - mBatteryHistoryPreference.mBatteryInfo = mBatteryInfo; - mViewHolder = spy(PreferenceViewHolder.createInstanceForTests(itemView)); - when(mViewHolder.findViewById(R.id.battery_usage)).thenReturn(mUsageView); - when(mViewHolder.findViewById(R.id.charge)).thenReturn(mTextView); - when(mUsageView.findViewById(anyInt())).thenReturn(mLabelView); - } - - @Test - public void testOnBindViewHolder_updateBatteryUsage() { - mBatteryHistoryPreference.onBindViewHolder(mViewHolder); - - verify(mViewHolder).findViewById(R.id.battery_usage); - verify(mTextView).setText(nullable(String.class)); - verify(mBatteryInfo).bindHistory(mUsageView); - } - - @Test - public void testSetBottomSummary_updatesBottomSummaryTextIfSet() { - mBatteryHistoryPreference.setBottomSummary(TEST_STRING); - mBatteryHistoryPreference.onBindViewHolder(mViewHolder); - - TextView view = (TextView) mViewHolder.findViewById(R.id.bottom_summary); - assertThat(view.getVisibility()).isEqualTo(View.VISIBLE); - assertThat(view.getText()).isEqualTo(TEST_STRING); - assertThat(mBatteryHistoryPreference.hideSummary).isFalse(); - } - - @Test - public void testSetBottomSummary_leavesBottomSummaryTextBlankIfNotSet() { - mBatteryHistoryPreference.hideBottomSummary(); - mBatteryHistoryPreference.onBindViewHolder(mViewHolder); - - TextView view = (TextView) mViewHolder.findViewById(R.id.bottom_summary); - assertThat(view.getVisibility()).isEqualTo(View.GONE); - assertThat(view.getText()).isEqualTo(""); - assertThat(mBatteryHistoryPreference.hideSummary).isTrue(); - } -} From 48dce3c0b7777296e48f40ca6dd13023de4bc852 Mon Sep 17 00:00:00 2001 From: ykhung Date: Wed, 7 Apr 2021 23:54:11 +0800 Subject: [PATCH 14/16] Remove options menu from BatteryUsage to align material next Bug: 180607918 Test: make SettingsRoboTests Test: make SettingsGoogleRoboTests Change-Id: I846668283d8c210f3b30fcf8c0ba5949588310d3 --- .../fuelgauge/PowerUsageAdvanced.java | 49 +------- .../fuelgauge/PowerUsageAdvancedTest.java | 118 ------------------ 2 files changed, 1 insertion(+), 166 deletions(-) delete mode 100644 tests/robotests/src/com/android/settings/fuelgauge/PowerUsageAdvancedTest.java diff --git a/src/com/android/settings/fuelgauge/PowerUsageAdvanced.java b/src/com/android/settings/fuelgauge/PowerUsageAdvanced.java index c5974259e72..0727e48ebc9 100644 --- a/src/com/android/settings/fuelgauge/PowerUsageAdvanced.java +++ b/src/com/android/settings/fuelgauge/PowerUsageAdvanced.java @@ -17,14 +17,9 @@ import static com.android.settings.fuelgauge.BatteryBroadcastReceiver.BatteryUpd import android.app.settings.SettingsEnums; import android.content.Context; -import android.content.Intent; -import android.content.IntentFilter; import android.os.BatteryManager; import android.os.Bundle; import android.provider.SearchIndexableResource; -import android.view.Menu; -import android.view.MenuInflater; -import android.view.MenuItem; import androidx.annotation.VisibleForTesting; @@ -44,16 +39,11 @@ public class PowerUsageAdvanced extends PowerUsageBase { private static final String TAG = "AdvancedBatteryUsage"; private static final String KEY_BATTERY_GRAPH = "battery_graph"; private static final String KEY_APP_LIST = "app_list"; - private static final String KEY_SHOW_ALL_APPS = "show_all_apps"; - @VisibleForTesting - static final int MENU_TOGGLE_APPS = Menu.FIRST + 1; @VisibleForTesting BatteryHistoryPreference mHistPref; private PowerUsageFeatureProvider mPowerUsageFeatureProvider; private BatteryAppListPreferenceController mBatteryAppListPreferenceController; - @VisibleForTesting - boolean mShowAllApps = false; @Override public void onCreate(Bundle icicle) { @@ -63,7 +53,6 @@ public class PowerUsageAdvanced extends PowerUsageBase { mHistPref = (BatteryHistoryPreference) findPreference(KEY_BATTERY_GRAPH); mPowerUsageFeatureProvider = FeatureFactory.getFactory(context) .getPowerUsageFeatureProvider(context); - restoreSavedInstance(icicle); } @Override @@ -89,42 +78,6 @@ public class PowerUsageAdvanced extends PowerUsageBase { return R.xml.power_usage_advanced; } - @Override - public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) { - menu.add(Menu.NONE, MENU_TOGGLE_APPS, Menu.NONE, - mShowAllApps ? R.string.hide_extra_apps : R.string.show_all_apps); - super.onCreateOptionsMenu(menu, inflater); - } - - @Override - public boolean onOptionsItemSelected(MenuItem item) { - switch (item.getItemId()) { - case MENU_TOGGLE_APPS: - mShowAllApps = !mShowAllApps; - item.setTitle(mShowAllApps ? R.string.hide_extra_apps : R.string.show_all_apps); - mMetricsFeatureProvider.action(getContext(), - SettingsEnums.ACTION_SETTINGS_MENU_BATTERY_APPS_TOGGLE, - mShowAllApps); - restartBatteryStatsLoader(BatteryUpdateType.MANUAL); - return true; - default: - return super.onOptionsItemSelected(item); - } - } - - @VisibleForTesting - void restoreSavedInstance(Bundle savedInstance) { - if (savedInstance != null) { - mShowAllApps = savedInstance.getBoolean(KEY_SHOW_ALL_APPS, false); - } - } - - @Override - public void onSaveInstanceState(Bundle outState) { - super.onSaveInstanceState(outState); - outState.putBoolean(KEY_SHOW_ALL_APPS, mShowAllApps); - } - @Override protected List createPreferenceControllers(Context context) { final List controllers = new ArrayList<>(); @@ -148,7 +101,7 @@ public class PowerUsageAdvanced extends PowerUsageBase { return; } updatePreference(mHistPref); - mBatteryAppListPreferenceController.refreshAppListGroup(mBatteryUsageStats, mShowAllApps); + mBatteryAppListPreferenceController.refreshAppListGroup(mBatteryUsageStats, true); } public static final BaseSearchIndexProvider SEARCH_INDEX_DATA_PROVIDER = diff --git a/tests/robotests/src/com/android/settings/fuelgauge/PowerUsageAdvancedTest.java b/tests/robotests/src/com/android/settings/fuelgauge/PowerUsageAdvancedTest.java deleted file mode 100644 index c9b1a00bbf5..00000000000 --- a/tests/robotests/src/com/android/settings/fuelgauge/PowerUsageAdvancedTest.java +++ /dev/null @@ -1,118 +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.fuelgauge; - -import static com.google.common.truth.Truth.assertThat; - -import static org.mockito.ArgumentMatchers.anyInt; -import static org.mockito.ArgumentMatchers.eq; -import static org.mockito.ArgumentMatchers.nullable; -import static org.mockito.Mockito.doNothing; -import static org.mockito.Mockito.doReturn; -import static org.mockito.Mockito.spy; -import static org.mockito.Mockito.verify; -import static org.mockito.Mockito.when; - -import android.content.Context; -import android.os.Bundle; -import android.view.Menu; -import android.view.MenuInflater; -import android.view.MenuItem; - -import androidx.preference.PreferenceScreen; - -import com.android.internal.logging.nano.MetricsProto; -import com.android.settings.R; -import com.android.settings.testutils.FakeFeatureFactory; - -import org.junit.Before; -import org.junit.Test; -import org.junit.runner.RunWith; -import org.mockito.Answers; -import org.mockito.Mock; -import org.mockito.MockitoAnnotations; -import org.robolectric.RobolectricTestRunner; -import org.robolectric.RuntimeEnvironment; - -@RunWith(RobolectricTestRunner.class) -public class PowerUsageAdvancedTest { - @Mock - private PreferenceScreen mPreferenceScreen; - @Mock(answer = Answers.RETURNS_DEEP_STUBS) - private Menu mMenu; - @Mock - private MenuInflater mMenuInflater; - @Mock - private MenuItem mToggleAppsMenu; - private Context mContext; - private PowerUsageAdvanced mFragment; - private FakeFeatureFactory mFeatureFactory; - - @Before - public void setUp() { - MockitoAnnotations.initMocks(this); - - mContext = RuntimeEnvironment.application; - mFeatureFactory = FakeFeatureFactory.setupForTest(); - when(mToggleAppsMenu.getItemId()).thenReturn(PowerUsageAdvanced.MENU_TOGGLE_APPS); - - BatteryAppListPreferenceController.sConfig = - new BatteryAppListPreferenceController.Config() { - @Override - public boolean shouldShowBatteryAttributionList(Context context) { - return true; - } - }; - - mFragment = spy(new PowerUsageAdvanced()); - mFragment.onAttach(mContext); - } - - @Test - public void testSaveInstanceState_showAllAppsRestored() { - Bundle bundle = new Bundle(); - mFragment.mShowAllApps = true; - doReturn(mPreferenceScreen).when(mFragment).getPreferenceScreen(); - - mFragment.onSaveInstanceState(bundle); - mFragment.restoreSavedInstance(bundle); - - assertThat(mFragment.mShowAllApps).isTrue(); - } - - @Test - public void testOptionsMenu_menuAppToggle_metricEventInvoked() { - mFragment.mShowAllApps = false; - doNothing().when(mFragment).restartBatteryStatsLoader(anyInt()); - - mFragment.onOptionsItemSelected(mToggleAppsMenu); - - verify(mFeatureFactory.metricsFeatureProvider).action(nullable(Context.class), - eq(MetricsProto.MetricsEvent.ACTION_SETTINGS_MENU_BATTERY_APPS_TOGGLE), eq(true)); - } - - @Test - public void testOptionsMenu_toggleAppsEnabled() { - when(mFeatureFactory.powerUsageFeatureProvider.isPowerAccountingToggleEnabled()) - .thenReturn(true); - mFragment.mShowAllApps = false; - - mFragment.onCreateOptionsMenu(mMenu, mMenuInflater); - - verify(mMenu).add(Menu.NONE, PowerUsageAdvanced.MENU_TOGGLE_APPS, Menu.NONE, - R.string.show_all_apps); - } -} From 998554d68fe116cb70b9d55c5ea38acbd33f9e6a Mon Sep 17 00:00:00 2001 From: Bonian Chen Date: Tue, 6 Apr 2021 21:40:24 +0800 Subject: [PATCH 15/16] [Settings] More log to help analysis Add log for supporting issue analysis. Bug: 184602966 Test: local Change-Id: I739ac827e0da1caca045e88599fafb293e25b65c --- .../telephony/BackupCallingPreferenceController.java | 12 +++++++++--- .../network/telephony/MobileNetworkSettings.java | 2 ++ 2 files changed, 11 insertions(+), 3 deletions(-) diff --git a/src/com/android/settings/network/telephony/BackupCallingPreferenceController.java b/src/com/android/settings/network/telephony/BackupCallingPreferenceController.java index d00efc740d3..2b07b5d621b 100644 --- a/src/com/android/settings/network/telephony/BackupCallingPreferenceController.java +++ b/src/com/android/settings/network/telephony/BackupCallingPreferenceController.java @@ -149,9 +149,15 @@ public class BackupCallingPreferenceController extends TelephonyTogglePreference private boolean hasBackupCallingFeature(int subscriptionId) { PersistableBundle carrierConfig = getCarrierConfigForSubId(subscriptionId); - return (carrierConfig != null) - && carrierConfig.getBoolean( - CarrierConfigManager.KEY_CARRIER_CROSS_SIM_IMS_AVAILABLE_BOOL, false); + Boolean featureEnableStatus = null; + if (carrierConfig != null) { + featureEnableStatus = carrierConfig.getBoolean( + CarrierConfigManager.KEY_CARRIER_CROSS_SIM_IMS_AVAILABLE_BOOL, false); + } + // TODO: remove log after fixing b/182326102 + Log.d(LOG_TAG, "config " + CarrierConfigManager.KEY_CARRIER_CROSS_SIM_IMS_AVAILABLE_BOOL + + "=" + featureEnableStatus + " for subId=" + mSubId); + return (featureEnableStatus != null) && featureEnableStatus.booleanValue(); } private ImsMmTelManager getImsMmTelManager(int subId) { diff --git a/src/com/android/settings/network/telephony/MobileNetworkSettings.java b/src/com/android/settings/network/telephony/MobileNetworkSettings.java index 9a4cb408f20..6e89c8ab527 100644 --- a/src/com/android/settings/network/telephony/MobileNetworkSettings.java +++ b/src/com/android/settings/network/telephony/MobileNetworkSettings.java @@ -214,6 +214,8 @@ public class MobileNetworkSettings extends AbstractMobileNetworkSettings { @Override public void onResume() { super.onResume(); + // TODO: remove log after fixing b/182326102 + Log.d(LOG_TAG, "onResume() subId=" + mSubId); if (mActiveSubsciptionsListener == null) { mActiveSubsciptionsListener = new ActiveSubsciptionsListener( getContext().getMainLooper(), getContext(), mSubId) { From 14cdcfdee91c322c1191f8b202cbd1e4f5e2fe56 Mon Sep 17 00:00:00 2001 From: Julia Reynolds Date: Wed, 7 Apr 2021 14:35:39 -0400 Subject: [PATCH 16/16] Mark non actionable preferences as non-selectable Test: navigate the conversations page with switch access enabled Fixes: 178765656 Change-Id: If5d5dd301e2d95b4aa7512f58a6e1adf01f3dbf0 --- res/xml/conversation_list_settings.xml | 1 + .../notification/app/AllConversationsPreferenceController.java | 1 + 2 files changed, 2 insertions(+) diff --git a/res/xml/conversation_list_settings.xml b/res/xml/conversation_list_settings.xml index 86b4f8164a7..040a9687f7c 100644 --- a/res/xml/conversation_list_settings.xml +++ b/res/xml/conversation_list_settings.xml @@ -34,6 +34,7 @@ settings:allowDividerBelow="true" >