diff --git a/res/drawable/ic_article.xml b/res/drawable/ic_article.xml new file mode 100644 index 00000000000..0c32c0f6c56 --- /dev/null +++ b/res/drawable/ic_article.xml @@ -0,0 +1,25 @@ + + + + diff --git a/res/drawable/ic_block.xml b/res/drawable/ic_block.xml new file mode 100644 index 00000000000..cf73681e3f5 --- /dev/null +++ b/res/drawable/ic_block.xml @@ -0,0 +1,25 @@ + + + + diff --git a/res/drawable/ic_text_fields_alt.xml b/res/drawable/ic_text_fields_alt.xml new file mode 100644 index 00000000000..673c0eba78c --- /dev/null +++ b/res/drawable/ic_text_fields_alt.xml @@ -0,0 +1,25 @@ + + + + diff --git a/res/values/arrays.xml b/res/values/arrays.xml index d5aa26705f7..46114cbe11d 100644 --- a/res/values/arrays.xml +++ b/res/values/arrays.xml @@ -105,11 +105,16 @@ 1800000 + 0.85 1.0 1.15 1.30 + 1.50 + 1.80 + 2.0 diff --git a/res/values/strings.xml b/res/values/strings.xml index d91cb88c499..91f6f68b6e8 100644 --- a/res/values/strings.xml +++ b/res/values/strings.xml @@ -228,6 +228,17 @@ See all + + Stylus + + System note taking app + + Stylus writing in textfields + + Ignore all stylus button presses + + USI stylus + Date & time diff --git a/res/xml/bluetooth_device_details_fragment.xml b/res/xml/bluetooth_device_details_fragment.xml index 0528973d676..5cd7c3a8e3d 100644 --- a/res/xml/bluetooth_device_details_fragment.xml +++ b/res/xml/bluetooth_device_details_fragment.xml @@ -44,15 +44,18 @@ + android:gravity="center"/> + android:layout_height="8dp"/> + + roleHolders = rm.getRoleHoldersAsUser(RoleManager.ROLE_ASSISTANT, + mContext.getUser()); + if (roleHolders.isEmpty()) { + return null; + } + + String packageName = roleHolders.get(0); + PackageManager pm = mContext.getPackageManager(); + String appName = packageName; + try { + ApplicationInfo ai = pm.getApplicationInfo(packageName, + PackageManager.ApplicationInfoFlags.of(0)); + appName = ai == null ? packageName : pm.getApplicationLabel(ai).toString(); + } catch (PackageManager.NameNotFoundException e) { + Log.e(TAG, "Notes role package not found."); + } + + Preference pref = new Preference(mContext); + pref.setKey(KEY_DEFAULT_NOTES); + pref.setTitle(mContext.getString(R.string.stylus_default_notes_app)); + pref.setIcon(R.drawable.ic_article); + pref.setEnabled(true); + pref.setSummary(appName); + return pref; + } + + private SwitchPreference createHandwritingPreference() { + SwitchPreference pref = new SwitchPreference(mContext); + pref.setKey(KEY_HANDWRITING); + pref.setTitle(mContext.getString(R.string.stylus_textfield_handwriting)); + pref.setIcon(R.drawable.ic_text_fields_alt); + pref.setOnPreferenceClickListener(this); + pref.setChecked(Settings.Global.getInt(mContext.getContentResolver(), + Settings.Global.STYLUS_HANDWRITING_ENABLED, 0) == 1); + return pref; + } + + private SwitchPreference createButtonPressPreference() { + SwitchPreference pref = new SwitchPreference(mContext); + pref.setKey(KEY_IGNORE_BUTTON); + pref.setTitle(mContext.getString(R.string.stylus_ignore_button)); + pref.setIcon(R.drawable.ic_block); + pref.setOnPreferenceClickListener(this); + return pref; + } + + @Override + public boolean onPreferenceClick(Preference preference) { + String key = preference.getKey(); + + switch (key) { + case KEY_DEFAULT_NOTES: + PackageManager pm = mContext.getPackageManager(); + String packageName = pm.getPermissionControllerPackageName(); + // TODO(b/254834764): replace with notes role once merged + Intent intent = new Intent(Intent.ACTION_MANAGE_DEFAULT_APP).setPackage( + packageName).putExtra(Intent.EXTRA_ROLE_NAME, RoleManager.ROLE_ASSISTANT); + mContext.startActivity(intent); + break; + case KEY_HANDWRITING: + Settings.Global.putInt(mContext.getContentResolver(), + Settings.Global.STYLUS_HANDWRITING_ENABLED, + ((SwitchPreference) preference).isChecked() ? 1 : 0); + break; + case KEY_IGNORE_BUTTON: + // TODO(b/251199452): to turn off stylus button presses + break; + } + return true; + } + + @Override + public final void displayPreference(PreferenceScreen screen) { + mPreferencesContainer = (PreferenceCategory) screen.findPreference(getPreferenceKey()); + super.displayPreference(screen); + + refresh(); + } + + @Override + public String getPreferenceKey() { + return KEY_STYLUS; + } + + @Override + public void onResume() { + refresh(); + } + + private void refresh() { + if (!isAvailable()) return; + + if (mInputDevice.getBluetoothAddress() != null) { + Preference notesPref = mPreferencesContainer.findPreference(KEY_DEFAULT_NOTES); + if (notesPref == null) { + notesPref = createDefaultNotesPreference(); + if (notesPref != null) { + mPreferencesContainer.addPreference(notesPref); + } + } + } + + Preference handwritingPref = mPreferencesContainer.findPreference(KEY_HANDWRITING); + // TODO(b/255732419): add proper InputMethodInfo conditional to show or hide + // InputMethodManager imm = mContext.getSystemService(InputMethodManager.class); + if (handwritingPref == null) { + mPreferencesContainer.addPreference(createHandwritingPreference()); + } + + Preference buttonPref = mPreferencesContainer.findPreference(KEY_IGNORE_BUTTON); + if (buttonPref == null) { + mPreferencesContainer.addPreference(createButtonPressPreference()); + } + } +} diff --git a/src/com/android/settings/development/transcode/TranscodeDefaultOptionPreferenceController.java b/src/com/android/settings/development/transcode/TranscodeDefaultOptionPreferenceController.java index 1c2fcd98410..a12aa642d7e 100644 --- a/src/com/android/settings/development/transcode/TranscodeDefaultOptionPreferenceController.java +++ b/src/com/android/settings/development/transcode/TranscodeDefaultOptionPreferenceController.java @@ -21,6 +21,7 @@ import android.os.SystemProperties; import com.android.settings.R; import com.android.settings.core.TogglePreferenceController; +import com.android.settingslib.development.DevelopmentSettingsEnabler; /** * The controller (on the transcode settings screen) indicating that by default we assume that apps @@ -47,7 +48,11 @@ public class TranscodeDefaultOptionPreferenceController extends TogglePreference @Override public int getAvailabilityStatus() { - return AVAILABLE; + if (DevelopmentSettingsEnabler.isDevelopmentSettingsEnabled(mContext)) { + return AVAILABLE; + } else { + return CONDITIONALLY_UNAVAILABLE; + } } @Override diff --git a/src/com/android/settings/development/transcode/TranscodeDisableCachePreferenceController.java b/src/com/android/settings/development/transcode/TranscodeDisableCachePreferenceController.java index c3b0624e9df..8229c98bfa2 100644 --- a/src/com/android/settings/development/transcode/TranscodeDisableCachePreferenceController.java +++ b/src/com/android/settings/development/transcode/TranscodeDisableCachePreferenceController.java @@ -22,6 +22,7 @@ import android.os.SystemProperties; import com.android.internal.annotations.VisibleForTesting; import com.android.settings.R; import com.android.settings.core.TogglePreferenceController; +import com.android.settingslib.development.DevelopmentSettingsEnabler; /** * The controller (in the Media transcoding settings) indicating the user's preference to disable @@ -49,7 +50,11 @@ public class TranscodeDisableCachePreferenceController extends TogglePreferenceC @Override public int getAvailabilityStatus() { - return AVAILABLE; + if (DevelopmentSettingsEnabler.isDevelopmentSettingsEnabled(mContext)) { + return AVAILABLE; + } else { + return CONDITIONALLY_UNAVAILABLE; + } } @Override diff --git a/src/com/android/settings/development/transcode/TranscodeGlobalTogglePreferenceController.java b/src/com/android/settings/development/transcode/TranscodeGlobalTogglePreferenceController.java index b2d446e0721..63572f711fd 100644 --- a/src/com/android/settings/development/transcode/TranscodeGlobalTogglePreferenceController.java +++ b/src/com/android/settings/development/transcode/TranscodeGlobalTogglePreferenceController.java @@ -21,6 +21,7 @@ import android.os.SystemProperties; import com.android.settings.R; import com.android.settings.core.TogglePreferenceController; +import com.android.settingslib.development.DevelopmentSettingsEnabler; /** * The controller for the "Enabling transcoding for all apps" switch on the transcode settings @@ -37,7 +38,11 @@ public class TranscodeGlobalTogglePreferenceController extends TogglePreferenceC @Override public int getAvailabilityStatus() { - return AVAILABLE; + if (DevelopmentSettingsEnabler.isDevelopmentSettingsEnabled(mContext)) { + return AVAILABLE; + } else { + return CONDITIONALLY_UNAVAILABLE; + } } @Override diff --git a/src/com/android/settings/development/transcode/TranscodeNotificationPreferenceController.java b/src/com/android/settings/development/transcode/TranscodeNotificationPreferenceController.java index 6b6692e5811..11c9c743279 100644 --- a/src/com/android/settings/development/transcode/TranscodeNotificationPreferenceController.java +++ b/src/com/android/settings/development/transcode/TranscodeNotificationPreferenceController.java @@ -22,6 +22,7 @@ import android.os.SystemProperties; import com.android.internal.annotations.VisibleForTesting; import com.android.settings.R; import com.android.settings.core.TogglePreferenceController; +import com.android.settingslib.development.DevelopmentSettingsEnabler; /** * The controller (in the Media transcoding settings) indicating the user's preference to show @@ -49,7 +50,11 @@ public class TranscodeNotificationPreferenceController extends TogglePreferenceC @Override public int getAvailabilityStatus() { - return AVAILABLE; + if (DevelopmentSettingsEnabler.isDevelopmentSettingsEnabled(mContext)) { + return AVAILABLE; + } else { + return CONDITIONALLY_UNAVAILABLE; + } } @Override diff --git a/src/com/android/settings/development/transcode/TranscodeUserControlPreferenceController.java b/src/com/android/settings/development/transcode/TranscodeUserControlPreferenceController.java index ce82293486c..377ff26dda3 100644 --- a/src/com/android/settings/development/transcode/TranscodeUserControlPreferenceController.java +++ b/src/com/android/settings/development/transcode/TranscodeUserControlPreferenceController.java @@ -21,6 +21,7 @@ import android.os.SystemProperties; import com.android.settings.R; import com.android.settings.core.TogglePreferenceController; +import com.android.settingslib.development.DevelopmentSettingsEnabler; /** * The controller for the User's control (over other transcoding preferences) preference switch on @@ -47,7 +48,11 @@ public class TranscodeUserControlPreferenceController extends TogglePreferenceCo @Override public int getAvailabilityStatus() { - return AVAILABLE; + if (DevelopmentSettingsEnabler.isDevelopmentSettingsEnabled(mContext)) { + return AVAILABLE; + } else { + return CONDITIONALLY_UNAVAILABLE; + } } @Override diff --git a/src/com/android/settings/deviceinfo/aboutphone/MyDeviceInfoFragment.java b/src/com/android/settings/deviceinfo/aboutphone/MyDeviceInfoFragment.java index 4af5d79c37f..c048ed5d1f9 100644 --- a/src/com/android/settings/deviceinfo/aboutphone/MyDeviceInfoFragment.java +++ b/src/com/android/settings/deviceinfo/aboutphone/MyDeviceInfoFragment.java @@ -103,7 +103,17 @@ public class MyDeviceInfoFragment extends DashboardFragment private static List buildPreferenceControllers( Context context, MyDeviceInfoFragment fragment, Lifecycle lifecycle) { final List controllers = new ArrayList<>(); - controllers.add(new SimStatusPreferenceController(context, fragment)); + + SimStatusPreferenceController defaultRecord = + new SimStatusPreferenceController(context, fragment); + + for (int slotIndex = 0; slotIndex < defaultRecord.getSimSlotSize(); slotIndex ++) { + SimStatusPreferenceController slotRecord = + new SimStatusPreferenceController(context, fragment); + slotRecord.setSimSlotStatus(slotIndex); + controllers.add(slotRecord); + } + controllers.add(new IpAddressPreferenceController(context, lifecycle)); controllers.add(new WifiMacAddressPreferenceController(context, lifecycle)); controllers.add(new BluetoothAddressPreferenceController(context, lifecycle)); diff --git a/src/com/android/settings/deviceinfo/simstatus/SimStatusPreferenceController.java b/src/com/android/settings/deviceinfo/simstatus/SimStatusPreferenceController.java index f811d2a86d2..835f8203fb5 100644 --- a/src/com/android/settings/deviceinfo/simstatus/SimStatusPreferenceController.java +++ b/src/com/android/settings/deviceinfo/simstatus/SimStatusPreferenceController.java @@ -46,6 +46,8 @@ public class SimStatusPreferenceController extends private final Fragment mFragment; private final List mPreferenceList = new ArrayList<>(); + private int mSlotIndex = SubscriptionManager.INVALID_SIM_SLOT_INDEX; + public SimStatusPreferenceController(Context context, Fragment fragment) { super(context); @@ -57,9 +59,36 @@ public class SimStatusPreferenceController extends @Override public String getPreferenceKey() { + if (mSlotIndex != SubscriptionManager.INVALID_SIM_SLOT_INDEX) { + return KEY_SIM_STATUS + mSlotIndex; + } return KEY_SIM_STATUS; } + /** + * Update the index of slot for this subscription. + * @param slotIndex index of slot + */ + public void setSimSlotStatus(int slotIndex) { + mSlotIndex = slotIndex; + } + + /** + * Get number of subscription slots. + * @return number of slots + */ + public int getSimSlotSize() { + return isAvailable() ? mTelephonyManager.getPhoneCount() : 0; + } + + /** + * Get the index of slot for this subscription. + * @return index of slot + */ + public int getSimSlotIndex() { + return mSlotIndex; + } + @Override public boolean isAvailable() { return SubscriptionUtil.isSimHardwareVisible(mContext) && @@ -72,22 +101,23 @@ public class SimStatusPreferenceController extends if (!SubscriptionUtil.isSimHardwareVisible(mContext)) { return; } - final Preference preference = screen.findPreference(getPreferenceKey()); + final Preference preference = screen.findPreference(KEY_SIM_STATUS); if (!isAvailable() || preference == null || !preference.isVisible()) { return; } final PreferenceCategory category = screen.findPreference(KEY_PREFERENCE_CATEGORY); - mPreferenceList.add(preference); - final int simStatusOrder = preference.getOrder(); + screen.removePreference(preference); + preference.setVisible(false); + // Add additional preferences for each sim in the device - for (int simSlotNumber = 1; simSlotNumber < mTelephonyManager.getPhoneCount(); + for (int simSlotNumber = 0; simSlotNumber < mTelephonyManager.getPhoneCount(); simSlotNumber++) { final Preference multiSimPreference = createNewPreference(screen.getContext()); multiSimPreference.setCopyingEnabled(true); - multiSimPreference.setOrder(simStatusOrder + simSlotNumber); - multiSimPreference.setKey(KEY_SIM_STATUS + simSlotNumber); + multiSimPreference.setOrder(simStatusOrder + simSlotNumber + 1); + multiSimPreference.setKey(KEY_SIM_STATUS + simSlotNumber + 1); category.addPreference(multiSimPreference); mPreferenceList.add(multiSimPreference); } diff --git a/src/com/android/settings/fuelgauge/batteryusage/db/BatteryStateDao.java b/src/com/android/settings/fuelgauge/batteryusage/db/BatteryStateDao.java index 936d5e053c7..6d2ab8d3c26 100644 --- a/src/com/android/settings/fuelgauge/batteryusage/db/BatteryStateDao.java +++ b/src/com/android/settings/fuelgauge/batteryusage/db/BatteryStateDao.java @@ -43,8 +43,8 @@ public interface BatteryStateDao { /** Gets the {@link Cursor} of all recorded data since last full charge within 7 days. */ @Query("SELECT * FROM BatteryState WHERE timestamp >= :timestampSixDaysAgo AND timestamp >= " - + "(SELECT MAX(timestamp) FROM BatteryState WHERE isFullChargeCycleStart = 1)" - + " ORDER BY timestamp ASC") + + "(SELECT IFNULL((SELECT MAX(timestamp) FROM BatteryState " + + "WHERE isFullChargeCycleStart = 1), 0)) ORDER BY timestamp ASC") Cursor getCursorSinceLastFullCharge(long timestampSixDaysAgo); /** Get the count of distinct timestamp after a specific timestamp. */ diff --git a/src/com/android/settings/sim/receivers/SimSlotChangeHandler.java b/src/com/android/settings/sim/receivers/SimSlotChangeHandler.java index 4a6b96c1fa3..f6c9cc42e15 100644 --- a/src/com/android/settings/sim/receivers/SimSlotChangeHandler.java +++ b/src/com/android/settings/sim/receivers/SimSlotChangeHandler.java @@ -22,6 +22,7 @@ import android.content.Context; import android.content.Intent; import android.content.SharedPreferences; import android.os.Looper; +import android.os.UserHandle; import android.provider.Settings; import android.telephony.SubscriptionInfo; import android.telephony.SubscriptionManager; @@ -344,20 +345,20 @@ public class SimSlotChangeHandler { Intent intent = ChooseSimActivity.getIntent(mContext); intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); intent.putExtra(ChooseSimActivity.KEY_HAS_PSIM, psimInserted); - mContext.startActivity(intent); + mContext.startActivityAsUser(intent, UserHandle.SYSTEM); } private void startSwitchSlotConfirmDialogActivity(SubscriptionInfo subscriptionInfo) { Intent intent = new Intent(mContext, SwitchToEsimConfirmDialogActivity.class); intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); intent.putExtra(SwitchToEsimConfirmDialogActivity.KEY_SUB_TO_ENABLE, subscriptionInfo); - mContext.startActivity(intent); + mContext.startActivityAsUser(intent, UserHandle.SYSTEM); } private void startDsdsDialogActivity() { Intent intent = new Intent(mContext, DsdsDialogActivity.class); intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); - mContext.startActivity(intent); + mContext.startActivityAsUser(intent, UserHandle.SYSTEM); } private void startSimConfirmDialogActivity(int subId) { @@ -368,7 +369,7 @@ public class SimSlotChangeHandler { Log.d(TAG, "Start ToggleSubscriptionDialogActivity with " + subId + " under DSDS+Mep."); Intent intent = ToggleSubscriptionDialogActivity.getIntent(mContext, subId, true); intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); - mContext.startActivity(intent); + mContext.startActivityAsUser(intent, UserHandle.SYSTEM); } private boolean isMultipleEnabledProfilesSupported() { diff --git a/src/com/android/settings/spa/SpaActivity.kt b/src/com/android/settings/spa/SpaActivity.kt index 896f899ad0a..838d6a1dc93 100644 --- a/src/com/android/settings/spa/SpaActivity.kt +++ b/src/com/android/settings/spa/SpaActivity.kt @@ -19,14 +19,14 @@ package com.android.settings.spa import android.content.Context import android.content.Intent import com.android.settingslib.spa.framework.BrowseActivity +import com.android.settingslib.spa.framework.util.appendSpaParams class SpaActivity : BrowseActivity() { companion object { @JvmStatic fun startSpaActivity(context: Context, destination: String) { - val intent = Intent(context, SpaActivity::class.java).apply { - putExtra(KEY_DESTINATION, destination) - } + val intent = Intent(context, SpaActivity::class.java) + .appendSpaParams(destination = destination) context.startActivity(intent) } } diff --git a/src/com/android/settings/spa/app/AllAppList.kt b/src/com/android/settings/spa/app/AllAppList.kt index f8c5c0f63e9..75b5cd21963 100644 --- a/src/com/android/settings/spa/app/AllAppList.kt +++ b/src/com/android/settings/spa/app/AllAppList.kt @@ -27,7 +27,7 @@ import com.android.settingslib.spa.framework.common.SettingsEntryBuilder import com.android.settingslib.spa.framework.common.SettingsPage import com.android.settingslib.spa.framework.common.SettingsPageProvider import com.android.settingslib.spa.framework.compose.navigator -import com.android.settingslib.spa.framework.util.asyncMapItem +import com.android.settingslib.spa.framework.util.mapItem import com.android.settingslib.spa.widget.preference.Preference import com.android.settingslib.spa.widget.preference.PreferenceModel import com.android.settingslib.spaprivileged.model.app.AppListModel @@ -78,15 +78,7 @@ data class AppRecordWithSize( private class AllAppListModel : AppListModel { override fun transform(userIdFlow: Flow, appListFlow: Flow>) = - appListFlow.asyncMapItem { app -> - AppRecordWithSize(app) - } - - override fun filter( - userIdFlow: Flow, - option: Int, - recordListFlow: Flow>, - ) = recordListFlow + appListFlow.mapItem(::AppRecordWithSize) @Composable override fun getSummary(option: Int, record: AppRecordWithSize) = record.app.getStorageSize() diff --git a/tests/robotests/src/com/android/settings/biometrics/fingerprint/FingerprintEnrollEnrollingTest.java b/tests/robotests/src/com/android/settings/biometrics/fingerprint/FingerprintEnrollEnrollingTest.java index 185af9e7213..f9d4445a658 100644 --- a/tests/robotests/src/com/android/settings/biometrics/fingerprint/FingerprintEnrollEnrollingTest.java +++ b/tests/robotests/src/com/android/settings/biometrics/fingerprint/FingerprintEnrollEnrollingTest.java @@ -91,7 +91,10 @@ public class FingerprintEnrollEnrollingTest { private Resources.Theme mTheme; + private static final int TOTAL_ENROLL_STEPS = 25; + private final int[] mSfpsStageThresholds = new int[]{0, 9, 13, 19, 25}; + private final int[] mUdfpsStageThresholds = new int[]{0, 13, 17, 22}; private FingerprintEnrollEnrolling mActivity; private Context mContext; @@ -190,19 +193,19 @@ public class FingerprintEnrollEnrollingTest { public void fingerprintUdfpsOverlayEnrollment_PlaysAllAnimationsAssetsCorrectly() { initializeActivityFor(TYPE_UDFPS_OPTICAL); - int totalEnrollSteps = 25; int initStageSteps = -1, initStageRemaining = 0; + final int totalStages = mUdfpsStageThresholds.length; when(mSidecar.getEnrollmentSteps()).thenReturn(initStageSteps); when(mSidecar.getEnrollmentRemaining()).thenReturn(initStageRemaining); mActivity.onEnrollmentProgressChange(initStageSteps, initStageRemaining); - when(mSidecar.getEnrollmentSteps()).thenReturn(totalEnrollSteps); + when(mSidecar.getEnrollmentSteps()).thenReturn(TOTAL_ENROLL_STEPS); - for (int remaining = totalEnrollSteps; remaining > 0; remaining--) { + for (int remaining = TOTAL_ENROLL_STEPS; remaining > 0; remaining--) { when(mSidecar.getEnrollmentRemaining()).thenReturn(remaining); - mActivity.onEnrollmentProgressChange(totalEnrollSteps, remaining); + mActivity.onEnrollmentProgressChange(TOTAL_ENROLL_STEPS, remaining); } List expectedLottieAssetOrder = List.of( @@ -213,7 +216,7 @@ public class FingerprintEnrollEnrollingTest { ); ArgumentCaptor lottieAssetCaptor = ArgumentCaptor.forClass(Integer.class); - verify(mIllustrationLottie, times(4)).setAnimation(lottieAssetCaptor.capture()); + verify(mIllustrationLottie, times(totalStages)).setAnimation(lottieAssetCaptor.capture()); List observedLottieAssetOrder = lottieAssetCaptor.getAllValues(); assertThat(observedLottieAssetOrder).isEqualTo(expectedLottieAssetOrder); } @@ -222,7 +225,6 @@ public class FingerprintEnrollEnrollingTest { public void fingerprintSfpsEnroll_PlaysAllAnimationsAssetsCorrectly() { initializeActivityFor(TYPE_POWER_BUTTON); - int totalEnrollSteps = 25; int initStageSteps = -1, initStageRemaining = 0; when(mSidecar.getEnrollmentSteps()).thenReturn(initStageSteps); @@ -230,11 +232,11 @@ public class FingerprintEnrollEnrollingTest { mActivity.onEnrollmentProgressChange(initStageSteps, initStageRemaining); - when(mSidecar.getEnrollmentSteps()).thenReturn(totalEnrollSteps); + when(mSidecar.getEnrollmentSteps()).thenReturn(TOTAL_ENROLL_STEPS); - for (int remaining = totalEnrollSteps; remaining > 0; remaining--) { + for (int remaining = TOTAL_ENROLL_STEPS; remaining > 0; remaining--) { when(mSidecar.getEnrollmentRemaining()).thenReturn(remaining); - mActivity.onEnrollmentProgressChange(totalEnrollSteps, remaining); + mActivity.onEnrollmentProgressChange(TOTAL_ENROLL_STEPS, remaining); } List expectedLottieAssetOrder = List.of( @@ -360,6 +362,16 @@ public class FingerprintEnrollEnrollingTest { doReturn(true).when(mSidecar).isEnrolling(); } + if (sensorType == TYPE_UDFPS_OPTICAL) { + // UDFPS : STAGE_CENTER = 0, ... , STAGE_RIGHT_EDGE = 3 + final int totalStages = mUdfpsStageThresholds.length - 1; + for (int stage = 0; stage <= totalStages; stage++) { + doReturn(mUdfpsStageThresholds[stage]).when(mActivity).getStageThresholdSteps( + stage); + } + doReturn(true).when(mSidecar).isEnrolling(); + } + ActivityController.of(mActivity).create(savedInstanceState); mTheme = mActivity.getTheme(); } diff --git a/tests/robotests/src/com/android/settings/bluetooth/BluetoothDeviceDetailsFragmentTest.java b/tests/robotests/src/com/android/settings/bluetooth/BluetoothDeviceDetailsFragmentTest.java index d501c154213..57af4126540 100644 --- a/tests/robotests/src/com/android/settings/bluetooth/BluetoothDeviceDetailsFragmentTest.java +++ b/tests/robotests/src/com/android/settings/bluetooth/BluetoothDeviceDetailsFragmentTest.java @@ -25,16 +25,21 @@ import static org.mockito.Mockito.doReturn; import static org.mockito.Mockito.eq; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.spy; +import static org.mockito.Mockito.times; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; import android.content.Context; +import android.hardware.input.InputManager; import android.os.Bundle; import android.os.UserManager; +import android.util.FeatureFlagUtils; +import android.view.InputDevice; import android.view.MenuInflater; import android.view.MenuItem; import androidx.fragment.app.Fragment; +import androidx.fragment.app.FragmentActivity; import androidx.fragment.app.FragmentManager; import androidx.fragment.app.FragmentTransaction; import androidx.preference.PreferenceScreen; @@ -51,6 +56,7 @@ import org.mockito.Answers; import org.mockito.ArgumentCaptor; import org.mockito.Mock; import org.mockito.MockitoAnnotations; +import org.robolectric.Robolectric; import org.robolectric.RobolectricTestRunner; import org.robolectric.RuntimeEnvironment; import org.robolectric.annotation.Config; @@ -68,6 +74,7 @@ public class BluetoothDeviceDetailsFragmentTest { private RoboMenu mMenu; private MenuInflater mInflater; private FragmentTransaction mFragmentTransaction; + private FragmentActivity mActivity; @Mock(answer = Answers.RETURNS_DEEP_STUBS) private CachedBluetoothDevice mCachedDevice; @@ -77,29 +84,18 @@ public class BluetoothDeviceDetailsFragmentTest { private PreferenceScreen mPreferenceScreen; @Mock private UserManager mUserManager; + @Mock + private InputManager mInputManager; @Before public void setUp() { MockitoAnnotations.initMocks(this); mContext = spy(RuntimeEnvironment.application); + doReturn(mInputManager).when(mContext).getSystemService(InputManager.class); + removeInputDeviceWithMatchingBluetoothAddress(); FakeFeatureFactory.setupForTest(); - mFragment = spy(BluetoothDeviceDetailsFragment.newInstance(TEST_ADDRESS)); - doReturn(mLocalManager).when(mFragment).getLocalBluetoothManager(any()); - doReturn(mCachedDevice).when(mFragment).getCachedDevice(any()); - doReturn(mPreferenceScreen).when(mFragment).getPreferenceScreen(); - doReturn(mUserManager).when(mFragment).getUserManager(); - - FragmentManager fragmentManager = mock(FragmentManager.class); - when(mFragment.getFragmentManager()).thenReturn(fragmentManager); - mFragmentTransaction = mock(FragmentTransaction.class); - when(fragmentManager.beginTransaction()).thenReturn(mFragmentTransaction); - - when(mCachedDevice.getAddress()).thenReturn(TEST_ADDRESS); - when(mCachedDevice.getIdentityAddress()).thenReturn(TEST_ADDRESS); - Bundle args = new Bundle(); - args.putString(BluetoothDeviceDetailsFragment.KEY_DEVICE_ADDRESS, TEST_ADDRESS); - mFragment.setArguments(args); + mFragment = setupFragment(); mFragment.onAttach(mContext); mMenu = new RoboMenu(mContext); @@ -111,6 +107,43 @@ public class BluetoothDeviceDetailsFragmentTest { assertThat(mFragment.mDeviceAddress).isEqualTo(TEST_ADDRESS); assertThat(mFragment.mManager).isEqualTo(mLocalManager); assertThat(mFragment.mCachedDevice).isEqualTo(mCachedDevice); + assertThat(mFragment.mInputDevice).isEqualTo(null); + } + + @Test + public void verifyOnAttachResult_flagEnabledAndInputDeviceSet_returnsInputDevice() { + FeatureFlagUtils.setEnabled(mContext, FeatureFlagUtils.SETTINGS_SHOW_STYLUS_PREFERENCES, + true); + InputDevice inputDevice = createInputDeviceWithMatchingBluetoothAddress(); + BluetoothDeviceDetailsFragment fragment = setupFragment(); + FragmentActivity activity = mock(FragmentActivity.class); + doReturn(inputDevice).when(fragment).getInputDevice(any()); + doReturn(activity).when(fragment).getActivity(); + + fragment.onAttach(mContext); + + assertThat(fragment.mDeviceAddress).isEqualTo(TEST_ADDRESS); + assertThat(fragment.mManager).isEqualTo(mLocalManager); + assertThat(fragment.mCachedDevice).isEqualTo(mCachedDevice); + assertThat(fragment.mInputDevice).isEqualTo(inputDevice); + } + + @Test + public void verifyOnAttachResult_flagDisabled_returnsNullInputDevice() { + FeatureFlagUtils.setEnabled(mContext, FeatureFlagUtils.SETTINGS_SHOW_STYLUS_PREFERENCES, + false); + InputDevice inputDevice = createInputDeviceWithMatchingBluetoothAddress(); + BluetoothDeviceDetailsFragment fragment = setupFragment(); + FragmentActivity activity = mock(FragmentActivity.class); + doReturn(inputDevice).when(fragment).getInputDevice(any()); + doReturn(activity).when(fragment).getActivity(); + + fragment.onAttach(mContext); + + assertThat(fragment.mDeviceAddress).isEqualTo(TEST_ADDRESS); + assertThat(fragment.mManager).isEqualTo(mLocalManager); + assertThat(fragment.mCachedDevice).isEqualTo(mCachedDevice); + assertThat(fragment.mInputDevice).isEqualTo(null); } @Test @@ -122,6 +155,31 @@ public class BluetoothDeviceDetailsFragmentTest { assertThat(item.getTitle()).isEqualTo(mContext.getString(R.string.bluetooth_rename_button)); } + @Test + public void getTitle_inputDeviceTitle() { + FeatureFlagUtils.setEnabled(mContext, FeatureFlagUtils.SETTINGS_SHOW_STYLUS_PREFERENCES, + true); + doReturn(mock(InputDevice.class)).when(mFragment).getInputDevice(mContext); + mFragment.onAttach(mContext); + + mFragment.setTitleForInputDevice(); + + assertThat(mActivity.getTitle().toString()).isEqualTo( + mContext.getString(R.string.stylus_device_details_title)); + } + + @Test + public void getTitle_inputDeviceNull_doesNotSetTitle() { + FeatureFlagUtils.setEnabled(mContext, FeatureFlagUtils.SETTINGS_SHOW_STYLUS_PREFERENCES, + true); + doReturn(null).when(mFragment).getInputDevice(mContext); + mFragment.onAttach(mContext); + + mFragment.setTitleForInputDevice(); + + verify(mActivity, times(0)).setTitle(any()); + } + @Test public void editMenu_clicked_showDialog() { mFragment.onCreateOptionsMenu(mMenu, mInflater); @@ -131,7 +189,7 @@ public class BluetoothDeviceDetailsFragmentTest { mFragment.onOptionsItemSelected(item); assertThat(item.getItemId()) - .isEqualTo(BluetoothDeviceDetailsFragment.EDIT_DEVICE_NAME_ITEM_ID); + .isEqualTo(BluetoothDeviceDetailsFragment.EDIT_DEVICE_NAME_ITEM_ID); verify(mFragmentTransaction).add(captor.capture(), eq(RemoteDeviceNameDialogFragment.TAG)); RemoteDeviceNameDialogFragment dialog = (RemoteDeviceNameDialogFragment) captor.getValue(); assertThat(dialog).isNotNull(); @@ -145,4 +203,44 @@ public class BluetoothDeviceDetailsFragmentTest { verify(mFragment).finish(); } + + private InputDevice createInputDeviceWithMatchingBluetoothAddress() { + doReturn(new int[]{0}).when(mInputManager).getInputDeviceIds(); + InputDevice device = mock(InputDevice.class); + doReturn(TEST_ADDRESS).when(mInputManager).getInputDeviceBluetoothAddress(0); + doReturn(device).when(mInputManager).getInputDevice(0); + return device; + } + + private InputDevice removeInputDeviceWithMatchingBluetoothAddress() { + doReturn(new int[]{0}).when(mInputManager).getInputDeviceIds(); + doReturn(null).when(mInputManager).getInputDeviceBluetoothAddress(0); + return null; + } + + private BluetoothDeviceDetailsFragment setupFragment() { + BluetoothDeviceDetailsFragment fragment = spy( + BluetoothDeviceDetailsFragment.newInstance(TEST_ADDRESS)); + doReturn(mLocalManager).when(fragment).getLocalBluetoothManager(any()); + doReturn(mCachedDevice).when(fragment).getCachedDevice(any()); + doReturn(mPreferenceScreen).when(fragment).getPreferenceScreen(); + doReturn(mUserManager).when(fragment).getUserManager(); + + mActivity = spy(Robolectric.setupActivity(FragmentActivity.class)); + doReturn(mActivity).when(fragment).getActivity(); + doReturn(mContext).when(fragment).getContext(); + + FragmentManager fragmentManager = mock(FragmentManager.class); + doReturn(fragmentManager).when(fragment).getFragmentManager(); + mFragmentTransaction = mock(FragmentTransaction.class); + doReturn(mFragmentTransaction).when(fragmentManager).beginTransaction(); + + doReturn(TEST_ADDRESS).when(mCachedDevice).getAddress(); + doReturn(TEST_ADDRESS).when(mCachedDevice).getIdentityAddress(); + Bundle args = new Bundle(); + args.putString(BluetoothDeviceDetailsFragment.KEY_DEVICE_ADDRESS, TEST_ADDRESS); + fragment.setArguments(args); + + return fragment; + } } diff --git a/tests/robotests/src/com/android/settings/connecteddevice/stylus/StylusDevicesControllerTest.java b/tests/robotests/src/com/android/settings/connecteddevice/stylus/StylusDevicesControllerTest.java new file mode 100644 index 00000000000..f704f2d7a0b --- /dev/null +++ b/tests/robotests/src/com/android/settings/connecteddevice/stylus/StylusDevicesControllerTest.java @@ -0,0 +1,233 @@ +/* + * Copyright (C) 2022 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.connecteddevice.stylus; + +import static com.google.common.truth.Truth.assertThat; + +import static org.mockito.ArgumentMatchers.eq; +import static org.mockito.Mockito.any; +import static org.mockito.Mockito.doNothing; +import static org.mockito.Mockito.spy; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.when; + +import android.app.role.RoleManager; +import android.content.Context; +import android.content.Intent; +import android.content.pm.ApplicationInfo; +import android.content.pm.PackageManager; +import android.os.UserHandle; +import android.provider.Settings; +import android.view.InputDevice; +import android.view.inputmethod.InputMethodManager; + +import androidx.preference.Preference; +import androidx.preference.PreferenceCategory; +import androidx.preference.PreferenceManager; +import androidx.preference.PreferenceScreen; +import androidx.preference.SwitchPreference; +import androidx.test.core.app.ApplicationProvider; + +import com.android.settings.R; +import com.android.settingslib.core.lifecycle.Lifecycle; + +import org.junit.Before; +import org.junit.Ignore; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.ArgumentCaptor; +import org.mockito.Mock; +import org.mockito.MockitoAnnotations; +import org.robolectric.RobolectricTestRunner; + +import java.util.Collections; + +@RunWith(RobolectricTestRunner.class) +public class StylusDevicesControllerTest { + private static final String NOTES_PACKAGE_NAME = "notes.package"; + private static final CharSequence NOTES_APP_LABEL = "App Label"; + + private Context mContext; + private StylusDevicesController mController; + private PreferenceCategory mPreferenceContainer; + private PreferenceScreen mScreen; + private InputDevice mInputDevice; + + @Mock + private InputMethodManager mImm; + @Mock + private PackageManager mPm; + @Mock + private RoleManager mRm; + @Mock + private Lifecycle mLifecycle; + + + @Before + public void setUp() throws Exception { + MockitoAnnotations.initMocks(this); + + mContext = spy(ApplicationProvider.getApplicationContext()); + PreferenceManager preferenceManager = new PreferenceManager(mContext); + mScreen = preferenceManager.createPreferenceScreen(mContext); + mPreferenceContainer = new PreferenceCategory(mContext); + mPreferenceContainer.setKey(StylusDevicesController.KEY_STYLUS); + mScreen.addPreference(mPreferenceContainer); + + when(mContext.getSystemService(InputMethodManager.class)).thenReturn(mImm); + when(mContext.getSystemService(RoleManager.class)).thenReturn(mRm); + doNothing().when(mContext).startActivity(any()); + + // TODO(b/254834764): notes role placeholder + when(mRm.getRoleHoldersAsUser(eq(RoleManager.ROLE_ASSISTANT), any(UserHandle.class))) + .thenReturn(Collections.singletonList(NOTES_PACKAGE_NAME)); + when(mContext.getPackageManager()).thenReturn(mPm); + when(mPm.getApplicationInfo(eq(NOTES_PACKAGE_NAME), + any(PackageManager.ApplicationInfoFlags.class))).thenReturn(new ApplicationInfo()); + when(mPm.getApplicationLabel(any(ApplicationInfo.class))).thenReturn(NOTES_APP_LABEL); + + mInputDevice = spy(new InputDevice.Builder() + .setId(1) + .setSources(InputDevice.SOURCE_STYLUS) + .build()); + when(mInputDevice.getBluetoothAddress()).thenReturn("SOME:ADDRESS"); + + mController = new StylusDevicesController(mContext, mInputDevice, mLifecycle); + } + + @Test + public void noInputDevice_noPreference() { + StylusDevicesController controller = new StylusDevicesController( + mContext, null, mLifecycle + ); + showScreen(controller); + assertThat(mPreferenceContainer.getPreferenceCount()).isEqualTo(0); + } + + @Test + public void btStylusInputDevice_showsAllPreferences() { + showScreen(mController); + Preference defaultNotesPref = mPreferenceContainer.getPreference(0); + Preference handwritingPref = mPreferenceContainer.getPreference(1); + Preference buttonPref = mPreferenceContainer.getPreference(2); + + assertThat(mPreferenceContainer.getPreferenceCount()).isEqualTo(3); + assertThat(defaultNotesPref.getTitle().toString()).isEqualTo( + mContext.getString(R.string.stylus_default_notes_app)); + assertThat(handwritingPref.getTitle().toString()).isEqualTo( + mContext.getString(R.string.stylus_textfield_handwriting)); + assertThat(buttonPref.getTitle().toString()).isEqualTo( + mContext.getString(R.string.stylus_ignore_button)); + } + + @Test + @Ignore // TODO(b/255732419): unignore when InputMethodInfo available + public void btStylusInputDevice_noHandwritingIme_showsSomePreferences() { + showScreen(mController); + Preference defaultNotesPref = mPreferenceContainer.getPreference(0); + Preference buttonPref = mPreferenceContainer.getPreference(1); + + assertThat(mPreferenceContainer.getPreferenceCount()).isEqualTo(2); + assertThat(defaultNotesPref.getTitle().toString()).isEqualTo( + mContext.getString(R.string.stylus_default_notes_app)); + assertThat(buttonPref.getTitle().toString()).isEqualTo( + mContext.getString(R.string.stylus_ignore_button)); + } + + @Test + public void defaultNotesPreference_showsNotesRoleApp() { + showScreen(mController); + Preference defaultNotesPref = mPreferenceContainer.getPreference(0); + + assertThat(defaultNotesPref.getTitle().toString()).isEqualTo( + mContext.getString(R.string.stylus_default_notes_app)); + assertThat(defaultNotesPref.getSummary().toString()).isEqualTo(NOTES_APP_LABEL.toString()); + } + + @Test + public void defaultNotesPreference_noRoleHolder_hidesNotesRoleApp() { + // TODO(b/254834764): replace with notes role once merged + when(mRm.getRoleHoldersAsUser(eq(RoleManager.ROLE_ASSISTANT), any(UserHandle.class))) + .thenReturn(Collections.emptyList()); + showScreen(mController); + + for (int i = 0; i < mPreferenceContainer.getPreferenceCount(); i++) { + Preference pref = mPreferenceContainer.getPreference(i); + assertThat(pref.getTitle().toString()).isNotEqualTo( + mContext.getString(R.string.stylus_default_notes_app)); + } + } + + @Test + public void defaultNotesPreferenceClick_sendsManageDefaultRoleIntent() { + final String permissionPackageName = "permissions.package"; + when(mPm.getPermissionControllerPackageName()).thenReturn(permissionPackageName); + final ArgumentCaptor captor = ArgumentCaptor.forClass(Intent.class); + + showScreen(mController); + Preference defaultNotesPref = mPreferenceContainer.getPreference(0); + mController.onPreferenceClick(defaultNotesPref); + verify(mContext).startActivity(captor.capture()); + + Intent intent = captor.getValue(); + assertThat(intent.getAction()).isEqualTo(Intent.ACTION_MANAGE_DEFAULT_APP); + assertThat(intent.getPackage()).isEqualTo(permissionPackageName); + // TODO(b/254834764): when notes role is merged + assertThat(intent.getStringExtra(Intent.EXTRA_ROLE_NAME)).isEqualTo( + RoleManager.ROLE_ASSISTANT); + } + + @Test + public void handwritingPreference_checkedWhenFlagTrue() { + Settings.Global.putInt(mContext.getContentResolver(), + Settings.Global.STYLUS_HANDWRITING_ENABLED, 1); + + showScreen(mController); + SwitchPreference handwritingPref = (SwitchPreference) mPreferenceContainer.getPreference(1); + + assertThat(handwritingPref.isChecked()).isEqualTo(true); + } + + @Test + public void handwritingPreference_uncheckedWhenFlagFalse() { + Settings.Global.putInt(mContext.getContentResolver(), + Settings.Global.STYLUS_HANDWRITING_ENABLED, 0); + + showScreen(mController); + SwitchPreference handwritingPref = (SwitchPreference) mPreferenceContainer.getPreference(1); + + assertThat(handwritingPref.isChecked()).isEqualTo(false); + } + + @Test + public void handwritingPreference_updatesFlagOnClick() { + Settings.Global.putInt(mContext.getContentResolver(), + Settings.Global.STYLUS_HANDWRITING_ENABLED, 0); + showScreen(mController); + SwitchPreference handwritingPref = (SwitchPreference) mPreferenceContainer.getPreference(1); + + handwritingPref.performClick(); + + assertThat(handwritingPref.isChecked()).isEqualTo(true); + assertThat(Settings.Global.getInt(mContext.getContentResolver(), + Settings.Global.STYLUS_HANDWRITING_ENABLED, -1)).isEqualTo(1); + } + + private void showScreen(StylusDevicesController controller) { + controller.displayPreference(mScreen); + } +} diff --git a/tests/robotests/src/com/android/settings/deviceinfo/simstatus/SimStatusPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/deviceinfo/simstatus/SimStatusPreferenceControllerTest.java index 4ffaf7ae6ec..458f7ff296d 100644 --- a/tests/robotests/src/com/android/settings/deviceinfo/simstatus/SimStatusPreferenceControllerTest.java +++ b/tests/robotests/src/com/android/settings/deviceinfo/simstatus/SimStatusPreferenceControllerTest.java @@ -24,8 +24,8 @@ import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; import android.content.Context; -import android.os.UserManager; import android.content.res.Resources; +import android.os.UserManager; import android.telephony.TelephonyManager; import androidx.fragment.app.Fragment; @@ -36,6 +36,9 @@ import androidx.preference.PreferenceScreen; import com.android.settings.R; +import java.util.ArrayList; +import java.util.List; + import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; @@ -44,7 +47,6 @@ import org.mockito.Mock; import org.mockito.MockitoAnnotations; import org.robolectric.RobolectricTestRunner; import org.robolectric.RuntimeEnvironment; -import org.robolectric.util.ReflectionHelpers; @RunWith(RobolectricTestRunner.class) public class SimStatusPreferenceControllerTest { @@ -52,6 +54,8 @@ public class SimStatusPreferenceControllerTest { @Mock private Preference mPreference; @Mock + private Preference mFirstSimPreference; + @Mock private Preference mSecondSimPreference; @Mock private PreferenceScreen mScreen; @@ -77,18 +81,31 @@ public class SimStatusPreferenceControllerTest { when(mContext.getResources()).thenReturn(mResources); when(mResources.getBoolean(R.bool.config_show_sim_info)).thenReturn(true); + doReturn(mTelephonyManager).when(mContext) + .getSystemService(Context.TELEPHONY_SERVICE); + doReturn(mUserManager).when(mContext).getSystemService(UserManager.class); - mController = spy(new SimStatusPreferenceController(mContext, mFragment)); + final List preferencePool = new ArrayList(); + preferencePool.add(mFirstSimPreference); + preferencePool.add(mSecondSimPreference); + + mController = spy(new SimStatusPreferenceController(mContext, mFragment) { + @Override + public Preference createNewPreference(Context context) { + return preferencePool.remove(0); + } + }); doReturn(true).when(mController).isAvailable(); when(mScreen.getContext()).thenReturn(mContext); final String categoryKey = "device_detail_category"; when(mScreen.findPreference(categoryKey)).thenReturn(mCategory); - doReturn(mSecondSimPreference).when(mController).createNewPreference(mContext); - ReflectionHelpers.setField(mController, "mTelephonyManager", mTelephonyManager); - when(mScreen.findPreference(mController.getPreferenceKey())).thenReturn(mPreference); + final String baseEntryKey = "sim_status"; + when(mScreen.findPreference(baseEntryKey)).thenReturn(mPreference); final String prefKey = mController.getPreferenceKey(); when(mPreference.getKey()).thenReturn(prefKey); when(mPreference.isVisible()).thenReturn(true); + + mController.setSimSlotStatus(-1); } @Test @@ -107,8 +124,8 @@ public class SimStatusPreferenceControllerTest { mController.updateState(mPreference); - verify(mPreference).setTitle(mContext.getString(R.string.sim_status_title)); - verify(mPreference).setSummary(anyString()); + verify(mFirstSimPreference).setTitle(mContext.getString(R.string.sim_status_title)); + verify(mFirstSimPreference).setSummary(anyString()); } @Test @@ -118,11 +135,11 @@ public class SimStatusPreferenceControllerTest { mController.updateState(mPreference); - verify(mPreference).setTitle( + verify(mFirstSimPreference).setTitle( mContext.getString(R.string.sim_status_title_sim_slot, 1 /* sim slot */)); verify(mSecondSimPreference).setTitle( mContext.getString(R.string.sim_status_title_sim_slot, 2 /* sim slot */)); - verify(mPreference).setSummary(anyString()); + verify(mFirstSimPreference).setSummary(anyString()); verify(mSecondSimPreference).setSummary(anyString()); } @@ -130,9 +147,10 @@ public class SimStatusPreferenceControllerTest { public void handlePreferenceTreeClick_shouldStartDialogFragment() { when(mFragment.getChildFragmentManager()).thenReturn( mock(FragmentManager.class, Answers.RETURNS_DEEP_STUBS)); + when(mTelephonyManager.getPhoneCount()).thenReturn(2); mController.displayPreference(mScreen); - mController.handlePreferenceTreeClick(mPreference); + mController.handlePreferenceTreeClick(mFirstSimPreference); verify(mFragment).getChildFragmentManager(); } diff --git a/tests/robotests/src/com/android/settings/fuelgauge/batteryusage/db/BatteryStateDaoTest.java b/tests/robotests/src/com/android/settings/fuelgauge/batteryusage/db/BatteryStateDaoTest.java index 33735b31e9f..3b887addb40 100644 --- a/tests/robotests/src/com/android/settings/fuelgauge/batteryusage/db/BatteryStateDaoTest.java +++ b/tests/robotests/src/com/android/settings/fuelgauge/batteryusage/db/BatteryStateDaoTest.java @@ -53,10 +53,8 @@ public final class BatteryStateDaoTest { mContext = ApplicationProvider.getApplicationContext(); mDatabase = BatteryTestUtils.setUpBatteryStateDatabase(mContext); mBatteryStateDao = mDatabase.batteryStateDao(); - BatteryTestUtils.insertDataToBatteryStateDatabase( - mContext, TIMESTAMP3, PACKAGE_NAME3); - BatteryTestUtils.insertDataToBatteryStateDatabase( - mContext, TIMESTAMP2, PACKAGE_NAME2); + BatteryTestUtils.insertDataToBatteryStateDatabase(mContext, TIMESTAMP3, PACKAGE_NAME3); + BatteryTestUtils.insertDataToBatteryStateDatabase(mContext, TIMESTAMP2, PACKAGE_NAME2); BatteryTestUtils.insertDataToBatteryStateDatabase( mContext, TIMESTAMP1, PACKAGE_NAME1, /*multiple=*/ true, /*isFullChargeStart=*/ true); @@ -100,6 +98,24 @@ public final class BatteryStateDaoTest { assertThat(cursor2.getString(3 /*packageName*/)).isEqualTo(PACKAGE_NAME3); } + @Test + public void batteryStateDao_getCursorSinceLastFullCharge_noFullChargeData_returnSevenDaysData() + throws Exception { + mBatteryStateDao.clearAll(); + BatteryTestUtils.insertDataToBatteryStateDatabase(mContext, TIMESTAMP3, PACKAGE_NAME3); + BatteryTestUtils.insertDataToBatteryStateDatabase(mContext, TIMESTAMP2, PACKAGE_NAME2); + BatteryTestUtils.insertDataToBatteryStateDatabase(mContext, TIMESTAMP1, PACKAGE_NAME1); + final Cursor cursor = mBatteryStateDao.getCursorSinceLastFullCharge(TIMESTAMP2); + assertThat(cursor.getCount()).isEqualTo(2); + assertThat(cursor.getColumnCount()).isEqualTo(CURSOR_COLUMN_SIZE); + // Verifies the queried first battery state. + cursor.moveToFirst(); + assertThat(cursor.getString(3 /*packageName*/)).isEqualTo(PACKAGE_NAME2); + // Verifies the queried third battery state. + cursor.moveToNext(); + assertThat(cursor.getString(3 /*packageName*/)).isEqualTo(PACKAGE_NAME3); + } + @Test public void batteryStateDao_clearAllBefore() throws Exception { mBatteryStateDao.clearAllBefore(TIMESTAMP2); diff --git a/tests/unit/src/com/android/settings/development/transcode/TranscodeDefaultOptionPreferenceControllerTest.java b/tests/unit/src/com/android/settings/development/transcode/TranscodeDefaultOptionPreferenceControllerTest.java index e3fa0766acc..ecbae2d2c74 100644 --- a/tests/unit/src/com/android/settings/development/transcode/TranscodeDefaultOptionPreferenceControllerTest.java +++ b/tests/unit/src/com/android/settings/development/transcode/TranscodeDefaultOptionPreferenceControllerTest.java @@ -20,6 +20,7 @@ import static com.google.common.truth.Truth.assertThat; import android.content.Context; import android.os.SystemProperties; +import android.provider.Settings; import androidx.test.core.app.ApplicationProvider; import androidx.test.ext.junit.runners.AndroidJUnit4; @@ -36,11 +37,14 @@ public class TranscodeDefaultOptionPreferenceControllerTest { "persist.sys.fuse.transcode_default"; private TranscodeDefaultOptionPreferenceController mUnderTest; + private Context mContext; @Before public void setUp() { - Context context = ApplicationProvider.getApplicationContext(); - mUnderTest = new TranscodeDefaultOptionPreferenceController(context, "some_key"); + mContext = ApplicationProvider.getApplicationContext(); + mUnderTest = new TranscodeDefaultOptionPreferenceController(mContext, "some_key"); + Settings.Global.putInt(mContext.getContentResolver(), + Settings.Global.DEVELOPMENT_SETTINGS_ENABLED, 1); } @Test @@ -74,4 +78,12 @@ public class TranscodeDefaultOptionPreferenceControllerTest { assertThat(mUnderTest.getAvailabilityStatus()).isEqualTo( BasePreferenceController.AVAILABLE); } + + @Test + public void getAvailabilityStatus_developerOptionFalse_shouldReturnUNAVAILABLE() { + Settings.Global.putInt(mContext.getContentResolver(), + Settings.Global.DEVELOPMENT_SETTINGS_ENABLED, 0); + assertThat(mUnderTest.getAvailabilityStatus()).isEqualTo( + BasePreferenceController.CONDITIONALLY_UNAVAILABLE); + } } diff --git a/tests/unit/src/com/android/settings/development/transcode/TranscodeDisableCachePreferenceControllerTest.java b/tests/unit/src/com/android/settings/development/transcode/TranscodeDisableCachePreferenceControllerTest.java index d1a3355e36a..e7d1d4b1af2 100644 --- a/tests/unit/src/com/android/settings/development/transcode/TranscodeDisableCachePreferenceControllerTest.java +++ b/tests/unit/src/com/android/settings/development/transcode/TranscodeDisableCachePreferenceControllerTest.java @@ -22,6 +22,7 @@ import static com.google.common.truth.Truth.assertThat; import android.content.Context; import android.os.SystemProperties; +import android.provider.Settings; import androidx.test.core.app.ApplicationProvider; import androidx.test.ext.junit.runners.AndroidJUnit4; @@ -36,11 +37,14 @@ import org.junit.runner.RunWith; public class TranscodeDisableCachePreferenceControllerTest { private TranscodeDisableCachePreferenceController mUnderTest; + private Context mContext; @Before public void setUp() { - Context context = ApplicationProvider.getApplicationContext(); - mUnderTest = new TranscodeDisableCachePreferenceController(context, "some_key"); + mContext = ApplicationProvider.getApplicationContext(); + mUnderTest = new TranscodeDisableCachePreferenceController(mContext, "some_key"); + Settings.Global.putInt(mContext.getContentResolver(), + Settings.Global.DEVELOPMENT_SETTINGS_ENABLED, 1); } @Test @@ -74,4 +78,12 @@ public class TranscodeDisableCachePreferenceControllerTest { assertThat(mUnderTest.getAvailabilityStatus()).isEqualTo( BasePreferenceController.AVAILABLE); } + + @Test + public void getAvailabilityStatus_developerOptionFalse_shouldReturnUNAVAILABLE() { + Settings.Global.putInt(mContext.getContentResolver(), + Settings.Global.DEVELOPMENT_SETTINGS_ENABLED, 0); + assertThat(mUnderTest.getAvailabilityStatus()).isEqualTo( + BasePreferenceController.CONDITIONALLY_UNAVAILABLE); + } } diff --git a/tests/unit/src/com/android/settings/development/transcode/TranscodeGlobalTogglePreferenceControllerTest.java b/tests/unit/src/com/android/settings/development/transcode/TranscodeGlobalTogglePreferenceControllerTest.java index 7c0acd7bea6..0751fd9b211 100644 --- a/tests/unit/src/com/android/settings/development/transcode/TranscodeGlobalTogglePreferenceControllerTest.java +++ b/tests/unit/src/com/android/settings/development/transcode/TranscodeGlobalTogglePreferenceControllerTest.java @@ -20,10 +20,13 @@ import static com.google.common.truth.Truth.assertThat; import android.content.Context; import android.os.SystemProperties; +import android.provider.Settings; import androidx.test.core.app.ApplicationProvider; import androidx.test.ext.junit.runners.AndroidJUnit4; +import com.android.settings.core.BasePreferenceController; + import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; @@ -34,11 +37,14 @@ public class TranscodeGlobalTogglePreferenceControllerTest { private static final String TRANSCODE_ENABLED_PROP_KEY = "persist.sys.fuse.transcode_enabled"; private TranscodeGlobalTogglePreferenceController mController; + private Context mContext; @Before public void setUp() { - Context context = ApplicationProvider.getApplicationContext(); - mController = new TranscodeGlobalTogglePreferenceController(context, "test_key"); + mContext = ApplicationProvider.getApplicationContext(); + mController = new TranscodeGlobalTogglePreferenceController(mContext, "test_key"); + Settings.Global.putInt(mContext.getContentResolver(), + Settings.Global.DEVELOPMENT_SETTINGS_ENABLED, 1); } @Test @@ -75,4 +81,12 @@ public class TranscodeGlobalTogglePreferenceControllerTest { // Verify the system property was updated. assertThat(SystemProperties.getBoolean(TRANSCODE_ENABLED_PROP_KEY, true)).isFalse(); } + + @Test + public void getAvailabilityStatus_developerOptionFalse_shouldReturnUNAVAILABLE() { + Settings.Global.putInt(mContext.getContentResolver(), + Settings.Global.DEVELOPMENT_SETTINGS_ENABLED, 0); + assertThat(mController.getAvailabilityStatus()).isEqualTo( + BasePreferenceController.CONDITIONALLY_UNAVAILABLE); + } } diff --git a/tests/unit/src/com/android/settings/development/transcode/TranscodeNotificationPreferenceControllerTest.java b/tests/unit/src/com/android/settings/development/transcode/TranscodeNotificationPreferenceControllerTest.java index 65bfbf571e2..d9ae0a48c5b 100644 --- a/tests/unit/src/com/android/settings/development/transcode/TranscodeNotificationPreferenceControllerTest.java +++ b/tests/unit/src/com/android/settings/development/transcode/TranscodeNotificationPreferenceControllerTest.java @@ -22,6 +22,7 @@ import static com.google.common.truth.Truth.assertThat; import android.content.Context; import android.os.SystemProperties; +import android.provider.Settings; import androidx.test.core.app.ApplicationProvider; import androidx.test.ext.junit.runners.AndroidJUnit4; @@ -36,10 +37,14 @@ import org.junit.runner.RunWith; public class TranscodeNotificationPreferenceControllerTest { private TranscodeNotificationPreferenceController mUnderTest; + private Context mContext; + @Before public void setUp() { - Context context = ApplicationProvider.getApplicationContext(); - mUnderTest = new TranscodeNotificationPreferenceController(context, "notification_key"); + mContext = ApplicationProvider.getApplicationContext(); + mUnderTest = new TranscodeNotificationPreferenceController(mContext, "notification_key"); + Settings.Global.putInt(mContext.getContentResolver(), + Settings.Global.DEVELOPMENT_SETTINGS_ENABLED, 1); } @Test @@ -73,4 +78,12 @@ public class TranscodeNotificationPreferenceControllerTest { assertThat(mUnderTest.getAvailabilityStatus()).isEqualTo( BasePreferenceController.AVAILABLE); } + + @Test + public void getAvailabilityStatus_developerOptionFalse_shouldReturnUNAVAILABLE() { + Settings.Global.putInt(mContext.getContentResolver(), + Settings.Global.DEVELOPMENT_SETTINGS_ENABLED, 0); + assertThat(mUnderTest.getAvailabilityStatus()).isEqualTo( + BasePreferenceController.CONDITIONALLY_UNAVAILABLE); + } } diff --git a/tests/unit/src/com/android/settings/development/transcode/TranscodeUserControlPreferenceControllerTest.java b/tests/unit/src/com/android/settings/development/transcode/TranscodeUserControlPreferenceControllerTest.java index 63a6ac6cb22..6e4bfc834fb 100644 --- a/tests/unit/src/com/android/settings/development/transcode/TranscodeUserControlPreferenceControllerTest.java +++ b/tests/unit/src/com/android/settings/development/transcode/TranscodeUserControlPreferenceControllerTest.java @@ -20,6 +20,7 @@ import static com.google.common.truth.Truth.assertThat; import android.content.Context; import android.os.SystemProperties; +import android.provider.Settings; import androidx.test.core.app.ApplicationProvider; import androidx.test.ext.junit.runners.AndroidJUnit4; @@ -36,11 +37,14 @@ public class TranscodeUserControlPreferenceControllerTest { "persist.sys.fuse.transcode_user_control"; private TranscodeUserControlPreferenceController mUnderTest; + private Context mContext; @Before public void setUp() { - Context context = ApplicationProvider.getApplicationContext(); - mUnderTest = new TranscodeUserControlPreferenceController(context, "some_key"); + mContext = ApplicationProvider.getApplicationContext(); + mUnderTest = new TranscodeUserControlPreferenceController(mContext, "some_key"); + Settings.Global.putInt(mContext.getContentResolver(), + Settings.Global.DEVELOPMENT_SETTINGS_ENABLED, 1); } @Test @@ -74,4 +78,12 @@ public class TranscodeUserControlPreferenceControllerTest { assertThat(mUnderTest.getAvailabilityStatus()).isEqualTo( BasePreferenceController.AVAILABLE); } + + @Test + public void getAvailabilityStatus_developerOptionFalse_shouldReturnUNAVAILABLE() { + Settings.Global.putInt(mContext.getContentResolver(), + Settings.Global.DEVELOPMENT_SETTINGS_ENABLED, 0); + assertThat(mUnderTest.getAvailabilityStatus()).isEqualTo( + BasePreferenceController.CONDITIONALLY_UNAVAILABLE); + } }