diff --git a/res/layout/font_size_activity.xml b/res/layout/font_size_activity.xml index 3e84336b763..32de37d0f89 100644 --- a/res/layout/font_size_activity.xml +++ b/res/layout/font_size_activity.xml @@ -55,6 +55,7 @@ android:layout_width="match_parent" android:layout_height="wrap_content" android:gravity="center_vertical" + android:layoutDirection="ltr" android:paddingTop="8dp"> diff --git a/res/values/dimens.xml b/res/values/dimens.xml index e695c4d39bf..a7e003c5e5b 100755 --- a/res/values/dimens.xml +++ b/res/values/dimens.xml @@ -427,4 +427,7 @@ 16dp + + + 12dp diff --git a/res/values/strings.xml b/res/values/strings.xml index 243b7868c37..6897c656dea 100644 --- a/res/values/strings.xml +++ b/res/values/strings.xml @@ -7485,14 +7485,6 @@ Bluetooth, NFC Bluetooth - - Bluetooth, Android Auto, driving mode, NFC - Bluetooth, Android Auto, driving mode - - Bluetooth, Android Auto, NFC - - Bluetooth, Android Auto Unavailable because NFC is off @@ -9250,10 +9242,10 @@ \t\n3.\tTap the app icon at the top of the screen, then tap Pin - + App pinning allows you to keep the current app in view until you unpin it. This feature can be used, for example, to let a trusted friend play a specific game. \n\nWhen an app is pinned, the pinned app may open other apps and personal data may be accessible. - \n\nIf you want to securely share your device with someone, try using a guest profile instead. + \n\nIf you want to securely share your device with someone, try using a guest user instead. \n\nTo use app pinning: \t\n1.\tTurn on app pinning \t\n2.\tOpen Overview @@ -12074,4 +12066,7 @@ When using 2 SIMs, this device will be limited to 4G. Learn more. + + + Suspend execution for cached apps diff --git a/res/xml/development_settings.xml b/res/xml/development_settings.xml index b781636ff7f..d1473e5da63 100644 --- a/res/xml/development_settings.xml +++ b/res/xml/development_settings.xml @@ -584,6 +584,12 @@ android:title="@string/show_all_anrs" android:summary="@string/show_all_anrs_summary" /> + + { + Settings.Global.putString(mContext.getContentResolver(), + Settings.Global.CACHED_APPS_FREEZER_ENABLED, + newValue.toString()); + + updateState(mPreference); + + PowerManager pm = mContext.getSystemService(PowerManager.class); + pm.reboot(null); + }; + } + + private DialogInterface.OnClickListener getRebootDialogCancelListener() { + return (dialog, which) -> { + updateState(mPreference); + }; + } + + @Override + public void updateState(Preference preference) { + final ListPreference listPreference = (ListPreference) preference; + final String currentValue = Settings.Global.getString(mContext.getContentResolver(), + Settings.Global.CACHED_APPS_FREEZER_ENABLED); + + int index = 0; // Defaults to device default + for (int i = 0; i < mListValues.length; i++) { + if (TextUtils.equals(currentValue, mListValues[i])) { + index = i; + break; + } + } + + listPreference.setValue(mListValues[index]); + listPreference.setSummary(mListSummaries[index]); + } + + @Override + public void onDeveloperOptionsDisabled() { + super.onDeveloperOptionsDisabled(); + + Settings.Global.putString(mContext.getContentResolver(), + Settings.Global.CACHED_APPS_FREEZER_ENABLED, + mListValues[0].toString()); + } +} diff --git a/src/com/android/settings/development/DevelopmentSettingsDashboardFragment.java b/src/com/android/settings/development/DevelopmentSettingsDashboardFragment.java index 4df641efa65..649256098da 100644 --- a/src/com/android/settings/development/DevelopmentSettingsDashboardFragment.java +++ b/src/com/android/settings/development/DevelopmentSettingsDashboardFragment.java @@ -505,6 +505,7 @@ public class DevelopmentSettingsDashboardFragment extends RestrictedDashboardFra controllers.add(new ProfileGpuRenderingPreferenceController(context)); controllers.add(new KeepActivitiesPreferenceController(context)); controllers.add(new BackgroundProcessLimitPreferenceController(context)); + controllers.add(new CachedAppsFreezerPreferenceController(context)); controllers.add(new ShowFirstCrashDialogPreferenceController(context)); controllers.add(new AppsNotRespondingPreferenceController(context)); controllers.add(new NotificationChannelWarningsPreferenceController(context)); diff --git a/src/com/android/settings/gestures/BackGestureIndicatorView.java b/src/com/android/settings/gestures/BackGestureIndicatorView.java index 2bb84358b56..9d0e74387d4 100644 --- a/src/com/android/settings/gestures/BackGestureIndicatorView.java +++ b/src/com/android/settings/gestures/BackGestureIndicatorView.java @@ -60,18 +60,26 @@ public class BackGestureIndicatorView extends LinearLayout { mLeftIndicator.setImageDrawable(mLeftDrawable); mRightIndicator.setImageDrawable(mRightDrawable); + int visibility = getSystemUiVisibility() + | View.SYSTEM_UI_FLAG_IMMERSIVE + | View.SYSTEM_UI_FLAG_LAYOUT_STABLE + | View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION + | View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN + | View.SYSTEM_UI_FLAG_HIDE_NAVIGATION + | View.SYSTEM_UI_FLAG_FULLSCREEN; + TypedArray a = context.obtainStyledAttributes(new int[] { android.R.attr.windowLightNavigationBar, android.R.attr.windowLightStatusBar}); if (a.getBoolean(0, false)) { - setSystemUiVisibility( - getSystemUiVisibility() | View.SYSTEM_UI_FLAG_LIGHT_NAVIGATION_BAR); + visibility |= View.SYSTEM_UI_FLAG_LIGHT_NAVIGATION_BAR; } if (a.getBoolean(1, false)) { - setSystemUiVisibility( - getSystemUiVisibility() | View.SYSTEM_UI_FLAG_LIGHT_STATUS_BAR); + visibility |= View.SYSTEM_UI_FLAG_LIGHT_STATUS_BAR; } a.recycle(); + + setSystemUiVisibility(visibility); } public void setIndicatorWidth(int width, boolean leftIndicator) { diff --git a/src/com/android/settings/media/MediaOutputIndicatorSlice.java b/src/com/android/settings/media/MediaOutputIndicatorSlice.java index 1a535042b6b..7ec0d3aa411 100644 --- a/src/com/android/settings/media/MediaOutputIndicatorSlice.java +++ b/src/com/android/settings/media/MediaOutputIndicatorSlice.java @@ -58,7 +58,8 @@ public class MediaOutputIndicatorSlice implements CustomSliceable { } final IconCompat icon = IconCompat.createWithResource(mContext, com.android.internal.R.drawable.ic_settings_bluetooth); - final CharSequence title = mContext.getText(R.string.media_output_title); + final CharSequence title = mContext.getString(R.string.media_output_label_title, + Utils.getApplicationLabel(mContext, getWorker().getPackageName())); final PendingIntent primaryActionIntent = PendingIntent.getActivity(mContext, 0 /* requestCode */, getMediaOutputSliceIntent(), 0 /* flags */); final SliceAction primarySliceAction = SliceAction.createDeeplink( diff --git a/src/com/android/settings/media/MediaOutputIndicatorWorker.java b/src/com/android/settings/media/MediaOutputIndicatorWorker.java index 6daa745d5f0..e04f1dd28a1 100644 --- a/src/com/android/settings/media/MediaOutputIndicatorWorker.java +++ b/src/com/android/settings/media/MediaOutputIndicatorWorker.java @@ -58,6 +58,7 @@ public class MediaOutputIndicatorWorker extends SliceBackgroundWorker implements private final Collection mMediaDevices = new CopyOnWriteArrayList<>(); private LocalBluetoothManager mLocalBluetoothManager; + private String mPackageName; @VisibleForTesting LocalMediaManager mLocalMediaManager; @@ -82,11 +83,10 @@ public class MediaOutputIndicatorWorker extends SliceBackgroundWorker implements if (mLocalMediaManager == null) { final MediaController controller = getActiveLocalMediaController(); - String packageName = null; if (controller != null) { - packageName = controller.getPackageName(); + mPackageName = controller.getPackageName(); } - mLocalMediaManager = new LocalMediaManager(mContext, packageName, null); + mLocalMediaManager = new LocalMediaManager(mContext, mPackageName, null); } mLocalMediaManager.registerCallback(this); @@ -168,6 +168,10 @@ public class MediaOutputIndicatorWorker extends SliceBackgroundWorker implements return mLocalMediaManager.getCurrentConnectedDevice(); } + String getPackageName() { + return mPackageName; + } + private class DevicesChangedBroadcastReceiver extends BroadcastReceiver { @Override public void onReceive(Context context, Intent intent) { diff --git a/src/com/android/settings/media/RemoteMediaSlice.java b/src/com/android/settings/media/RemoteMediaSlice.java index 71a41b36964..61a53f3f8ed 100644 --- a/src/com/android/settings/media/RemoteMediaSlice.java +++ b/src/com/android/settings/media/RemoteMediaSlice.java @@ -37,6 +37,7 @@ import androidx.slice.builders.SliceAction; import com.android.settings.R; import com.android.settings.SubSettings; +import com.android.settings.Utils; import com.android.settings.notification.SoundSettings; import com.android.settings.slices.CustomSliceable; import com.android.settings.slices.SliceBackgroundWorker; @@ -86,7 +87,6 @@ public class RemoteMediaSlice implements CustomSliceable { return listBuilder.build(); } final CharSequence castVolume = mContext.getText(R.string.remote_media_volume_option_title); - final CharSequence outputTitle = mContext.getText(R.string.media_output_title); final IconCompat icon = IconCompat.createWithResource(mContext, R.drawable.ic_volume_remote); // To create an empty icon to indent the row @@ -99,6 +99,8 @@ public class RemoteMediaSlice implements CustomSliceable { + maxVolume); continue; } + final CharSequence outputTitle = mContext.getString(R.string.media_output_label_title, + Utils.getApplicationLabel(mContext, info.getClientPackageName())); listBuilder.addInputRange(new InputRangeBuilder() .setTitleItem(icon, ListBuilder.ICON_IMAGE) .setTitle(castVolume) @@ -154,7 +156,8 @@ public class RemoteMediaSlice implements CustomSliceable { 0 /* requestCode */, intent, 0 /* flags */); final SliceAction primarySliceAction = SliceAction.createDeeplink( primaryActionIntent, icon, ListBuilder.ICON_IMAGE, - mContext.getText(R.string.media_output_title)); + mContext.getString(R.string.media_output_label_title, + Utils.getApplicationLabel(mContext, packageName))); return primarySliceAction; } diff --git a/src/com/android/settings/notification/RemoteVolumeGroupController.java b/src/com/android/settings/notification/RemoteVolumeGroupController.java index 137f7803d8b..a0b10579f2b 100644 --- a/src/com/android/settings/notification/RemoteVolumeGroupController.java +++ b/src/com/android/settings/notification/RemoteVolumeGroupController.java @@ -30,6 +30,7 @@ import androidx.preference.PreferenceCategory; import androidx.preference.PreferenceScreen; import com.android.settings.R; +import com.android.settings.Utils; import com.android.settings.core.BasePreferenceController; import com.android.settingslib.core.lifecycle.Lifecycle; import com.android.settingslib.media.LocalMediaManager; @@ -108,7 +109,6 @@ public class RemoteVolumeGroupController extends BasePreferenceController implem mPreferenceCategory.setVisible(false); return; } - final CharSequence outputTitle = mContext.getText(R.string.media_output_title); final CharSequence castVolume = mContext.getText(R.string.remote_media_volume_option_title); mPreferenceCategory.setVisible(true); @@ -116,6 +116,8 @@ public class RemoteVolumeGroupController extends BasePreferenceController implem if (mPreferenceCategory.findPreference(info.getId()) != null) { continue; } + final CharSequence outputTitle = mContext.getString(R.string.media_output_label_title, + Utils.getApplicationLabel(mContext, info.getClientPackageName())); // Add slider final RemoteVolumeSeekBarPreference seekBarPreference = new RemoteVolumeSeekBarPreference(mContext); diff --git a/src/com/android/settings/panel/PanelSlicesAdapter.java b/src/com/android/settings/panel/PanelSlicesAdapter.java index 1b69cc269b9..2f2932c8883 100644 --- a/src/com/android/settings/panel/PanelSlicesAdapter.java +++ b/src/com/android/settings/panel/PanelSlicesAdapter.java @@ -16,7 +16,9 @@ package com.android.settings.panel; +import static com.android.settings.slices.CustomSliceRegistry.MEDIA_OUTPUT_GROUP_SLICE_URI; import static com.android.settings.slices.CustomSliceRegistry.MEDIA_OUTPUT_INDICATOR_SLICE_URI; +import static com.android.settings.slices.CustomSliceRegistry.MEDIA_OUTPUT_SLICE_URI; import android.app.settings.SettingsEnums; import android.content.Context; @@ -24,6 +26,7 @@ import android.net.Uri; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; +import android.widget.LinearLayout; import androidx.annotation.NonNull; import androidx.annotation.VisibleForTesting; @@ -81,7 +84,7 @@ public class PanelSlicesAdapter @Override public void onBindViewHolder(@NonNull SliceRowViewHolder sliceRowViewHolder, int position) { - sliceRowViewHolder.onBind(mSliceLiveData.get(position)); + sliceRowViewHolder.onBind(mSliceLiveData.get(position), position); } /** @@ -116,15 +119,21 @@ public class PanelSlicesAdapter @VisibleForTesting final SliceView sliceView; + @VisibleForTesting + final LinearLayout mSliceSliderLayout; public SliceRowViewHolder(View view) { super(view); sliceView = view.findViewById(R.id.slice_view); sliceView.setMode(SliceView.MODE_LARGE); sliceView.setShowTitleItems(true); + mSliceSliderLayout = view.findViewById(R.id.slice_slider_layout); } - public void onBind(LiveData sliceLiveData) { + /** + * Called when the view is displayed. + */ + public void onBind(LiveData sliceLiveData, int position) { sliceLiveData.observe(mPanelFragment.getViewLifecycleOwner(), sliceView); // Do not show the divider above media devices switcher slice per request @@ -133,6 +142,16 @@ public class PanelSlicesAdapter mDividerAllowedAbove = false; } + // Customize output switcher slice top padding + if (position == 0 && (slice.getUri().equals(MEDIA_OUTPUT_SLICE_URI) + || slice.getUri().equals(MEDIA_OUTPUT_GROUP_SLICE_URI))) { + final int paddingTop = mPanelFragment.getResources().getDimensionPixelSize( + R.dimen.output_switcher_slice_padding_top); + mSliceSliderLayout.setPadding(mSliceSliderLayout.getPaddingLeft(), paddingTop, + mSliceSliderLayout.getPaddingRight(), + mSliceSliderLayout.getPaddingBottom()); + } + // Log Panel interaction sliceView.setOnSliceActionListener( ((eventInfo, sliceItem) -> { diff --git a/src/com/android/settings/security/ScreenPinningSettings.java b/src/com/android/settings/security/ScreenPinningSettings.java index 9e14c9a3339..ca7590b202c 100644 --- a/src/com/android/settings/security/ScreenPinningSettings.java +++ b/src/com/android/settings/security/ScreenPinningSettings.java @@ -22,6 +22,7 @@ import android.content.DialogInterface; import android.content.Intent; import android.os.Bundle; import android.os.UserHandle; +import android.os.UserManager; import android.provider.SearchIndexableResource; import android.provider.Settings; import android.widget.Switch; @@ -61,6 +62,7 @@ public class ScreenPinningSettings extends SettingsPreferenceFragment private SwitchPreference mUseScreenLock; private FooterPreference mFooterPreference; private LockPatternUtils mLockPatternUtils; + private UserManager mUserManager; @Override public int getMetricsCategory() { @@ -74,6 +76,7 @@ public class ScreenPinningSettings extends SettingsPreferenceFragment final SettingsActivity activity = (SettingsActivity) getActivity(); activity.setTitle(R.string.screen_pinning_title); mLockPatternUtils = new LockPatternUtils(activity); + mUserManager = activity.getSystemService(UserManager.class); addPreferencesFromResource(R.xml.screen_pinning_settings); final PreferenceScreen root = getPreferenceScreen(); @@ -224,10 +227,22 @@ public class ScreenPinningSettings extends SettingsPreferenceFragment mUseScreenLock.setTitle(getCurrentSecurityTitle()); } else { mFooterPreference.setVisible(true); + mFooterPreference.setSummary(getAppPinningContent()); mUseScreenLock.setVisible(false); } } + private boolean isGuestModeSupported() { + return UserManager.supportsMultipleUsers() + && !mUserManager.hasUserRestriction(UserManager.DISALLOW_USER_SWITCH); + } + + private CharSequence getAppPinningContent() { + return isGuestModeSupported() + ? getActivity().getText(R.string.screen_pinning_guest_user_description) + : getActivity().getText(R.string.screen_pinning_description); + } + /** * For search */ diff --git a/tests/robotests/src/com/android/settings/connecteddevice/AdvancedConnectedDeviceControllerTest.java b/tests/robotests/src/com/android/settings/connecteddevice/AdvancedConnectedDeviceControllerTest.java index 701b5380727..08f937b2788 100644 --- a/tests/robotests/src/com/android/settings/connecteddevice/AdvancedConnectedDeviceControllerTest.java +++ b/tests/robotests/src/com/android/settings/connecteddevice/AdvancedConnectedDeviceControllerTest.java @@ -23,9 +23,6 @@ import static org.mockito.Mockito.spy; import android.content.ContentResolver; import android.content.Context; -import android.content.Intent; -import android.content.pm.ActivityInfo; -import android.content.pm.ResolveInfo; import android.nfc.NfcAdapter; import android.provider.Settings; @@ -41,7 +38,6 @@ import org.robolectric.RuntimeEnvironment; import org.robolectric.Shadows; import org.robolectric.annotation.Config; import org.robolectric.shadows.ShadowNfcAdapter; -import org.robolectric.shadows.ShadowPackageManager; import org.robolectric.util.ReflectionHelpers; @RunWith(RobolectricTestRunner.class) @@ -51,13 +47,11 @@ public class AdvancedConnectedDeviceControllerTest { private static final String KEY = "test_key"; private static final String DRIVING_MODE_SETTINGS_ENABLED = "gearhead:driving_mode_settings_enabled"; - private static final String ANDROID_AUTO_PACKAGE = "com.google.android.projection.gearhead"; private Context mContext; private NfcPreferenceController mNfcController; private ShadowNfcAdapter mShadowNfcAdapter; private ContentResolver mContentResolver; - private ShadowPackageManager mShadowPackageManager; @Before public void setUp() { @@ -68,7 +62,6 @@ public class AdvancedConnectedDeviceControllerTest { mNfcController = new NfcPreferenceController(mContext, NfcPreferenceController.KEY_TOGGLE_NFC); mShadowNfcAdapter = Shadows.shadowOf(NfcAdapter.getNfcAdapter(mContext)); - mShadowPackageManager = Shadows.shadowOf(mContext.getPackageManager()); } @Test @@ -83,41 +76,14 @@ public class AdvancedConnectedDeviceControllerTest { public void isDrivingModeAvailable_returnTrue() { Settings.System.putInt(mContentResolver, DRIVING_MODE_SETTINGS_ENABLED, 1); - assertThat( - AdvancedConnectedDeviceController.isDrivingModeAvailable(mContext)).isTrue(); + assertThat(AdvancedConnectedDeviceController.isDrivingModeAvailable(mContext)).isTrue(); } @Test public void isDrivingModeAvailable_returnFalse() { Settings.System.putInt(mContentResolver, DRIVING_MODE_SETTINGS_ENABLED, 0); - assertThat( - AdvancedConnectedDeviceController.isDrivingModeAvailable(mContext)).isFalse(); - } - - @Test - public void isAndroidAutoSettingAvailable_returnTrue() { - final ActivityInfo activityInfo = new ActivityInfo(); - activityInfo.packageName = ANDROID_AUTO_PACKAGE; - final ResolveInfo resolveInfo = new ResolveInfo(); - resolveInfo.activityInfo = activityInfo; - mShadowPackageManager.addResolveInfoForIntent( - buildAndroidAutoSettingsIntent(), - resolveInfo); - - assertThat( - AdvancedConnectedDeviceController.isAndroidAutoSettingAvailable(mContext)).isTrue(); - } - - @Test - public void isAndroidAutoSettingAvailable_returnFalse() { - ResolveInfo resolveInfo = null; // Needed to disambiguate method - mShadowPackageManager.addResolveInfoForIntent( - buildAndroidAutoSettingsIntent(), - resolveInfo); - - assertThat( - AdvancedConnectedDeviceController.isAndroidAutoSettingAvailable(mContext)).isFalse(); + assertThat(AdvancedConnectedDeviceController.isDrivingModeAvailable(mContext)).isFalse(); } @Test @@ -125,7 +91,7 @@ public class AdvancedConnectedDeviceControllerTest { // NFC available, driving mode available mShadowNfcAdapter.setEnabled(true); assertThat(AdvancedConnectedDeviceController - .getConnectedDevicesSummaryResourceId(mNfcController, true, false)) + .getConnectedDevicesSummaryResourceId(mNfcController, true)) .isEqualTo(R.string.connected_devices_dashboard_summary); } @@ -134,7 +100,7 @@ public class AdvancedConnectedDeviceControllerTest { // NFC is available, driving mode not available mShadowNfcAdapter.setEnabled(true); assertThat(AdvancedConnectedDeviceController - .getConnectedDevicesSummaryResourceId(mNfcController, false, false)) + .getConnectedDevicesSummaryResourceId(mNfcController, false)) .isEqualTo(R.string.connected_devices_dashboard_no_driving_mode_summary); } @@ -143,7 +109,7 @@ public class AdvancedConnectedDeviceControllerTest { // NFC not available, driving mode available ReflectionHelpers.setField(mNfcController, "mNfcAdapter", null); assertThat(AdvancedConnectedDeviceController - .getConnectedDevicesSummaryResourceId(mNfcController, true, false)) + .getConnectedDevicesSummaryResourceId(mNfcController, true)) .isEqualTo(R.string.connected_devices_dashboard_no_nfc_summary); } @@ -152,52 +118,7 @@ public class AdvancedConnectedDeviceControllerTest { // NFC not available, driving mode not available ReflectionHelpers.setField(mNfcController, "mNfcAdapter", null); assertThat(AdvancedConnectedDeviceController - .getConnectedDevicesSummaryResourceId(mNfcController, false, false)) + .getConnectedDevicesSummaryResourceId(mNfcController, false)) .isEqualTo(R.string.connected_devices_dashboard_no_driving_mode_no_nfc_summary); } - - @Test - public void getConnectedDevicesSummaryResourceId_Auto_NFC_DrivingMode_Available() { - // NFC available, driving mode available - mShadowNfcAdapter.setEnabled(true); - assertThat(AdvancedConnectedDeviceController - .getConnectedDevicesSummaryResourceId(mNfcController, true, true)) - .isEqualTo(R.string.connected_devices_dashboard_android_auto_summary); - } - - @Test - public void getConnectedDevicesSummaryResourceId_Auto_NFC_Available() { - // NFC is available, driving mode not available - mShadowNfcAdapter.setEnabled(true); - assertThat(AdvancedConnectedDeviceController - .getConnectedDevicesSummaryResourceId(mNfcController, false, true)) - .isEqualTo( - R.string.connected_devices_dashboard_android_auto_no_driving_mode_summary); - } - - @Test - public void getConnectedDevicesSummaryResourceId_Auto_DrivingMode_Available() { - // NFC not available, driving mode available - ReflectionHelpers.setField(mNfcController, "mNfcAdapter", null); - assertThat(AdvancedConnectedDeviceController - .getConnectedDevicesSummaryResourceId(mNfcController, true, true)) - .isEqualTo(R.string.connected_devices_dashboard_android_auto_no_nfc_summary); - } - - @Test - public void getConnectedDevicesSummaryResourceId_Auto_Available() { - // NFC not available, driving mode not available - ReflectionHelpers.setField(mNfcController, "mNfcAdapter", null); - assertThat(AdvancedConnectedDeviceController - .getConnectedDevicesSummaryResourceId(mNfcController, false, true)) - .isEqualTo( - R.string.connected_devices_dashboard_android_auto_no_nfc_no_driving_mode); - } - - private Intent buildAndroidAutoSettingsIntent() { - final Intent intent = new Intent("com.android.settings.action.IA_SETTINGS"); - intent.setPackage(ANDROID_AUTO_PACKAGE); - return intent; - } } - diff --git a/tests/robotests/src/com/android/settings/connecteddevice/usb/UsbDetailsFunctionsControllerTest.java b/tests/robotests/src/com/android/settings/connecteddevice/usb/UsbDetailsFunctionsControllerTest.java index 3a6eec0fd89..f1c472866e3 100644 --- a/tests/robotests/src/com/android/settings/connecteddevice/usb/UsbDetailsFunctionsControllerTest.java +++ b/tests/robotests/src/com/android/settings/connecteddevice/usb/UsbDetailsFunctionsControllerTest.java @@ -270,4 +270,42 @@ public class UsbDetailsFunctionsControllerTest { verify(mUsbBackend).setCurrentFunctions(UsbManager.FUNCTION_PTP); } + + @Test + public void refresh_previousFunctionIsRndis_stopTethering() { + mDetailsFunctionsController.mPreviousFunction = UsbManager.FUNCTION_RNDIS; + + mDetailsFunctionsController.refresh(false, 0, 0, 0); + + verify(mConnectivityManager).stopTethering(TETHERING_USB); + } + + @Test + public void refresh_previousFunctionIsNotRndis_doNothing() { + mDetailsFunctionsController.mPreviousFunction = UsbManager.FUNCTION_MIDI; + + mDetailsFunctionsController.refresh(false, 0, 0, 0); + + verify(mConnectivityManager, never()).stopTethering(TETHERING_USB); + } + + @Test + public void onRadioButtonClicked_previousFunctionIsRndis_stopTethering() { + mRadioButtonPreference.setKey(UsbBackend.usbFunctionsToString(UsbManager.FUNCTION_PTP)); + doReturn(UsbManager.FUNCTION_RNDIS).when(mUsbBackend).getCurrentFunctions(); + + mDetailsFunctionsController.onRadioButtonClicked(mRadioButtonPreference); + + verify(mConnectivityManager).stopTethering(TETHERING_USB); + } + + @Test + public void onRadioButtonClicked_previousFunctionIsNotRndis_doNothing() { + mRadioButtonPreference.setKey(UsbBackend.usbFunctionsToString(UsbManager.FUNCTION_PTP)); + doReturn(UsbManager.FUNCTION_MIDI).when(mUsbBackend).getCurrentFunctions(); + + mDetailsFunctionsController.onRadioButtonClicked(mRadioButtonPreference); + + verify(mConnectivityManager, never()).stopTethering(TETHERING_USB); + } } diff --git a/tests/robotests/src/com/android/settings/media/MediaOutputIndicatorSliceTest.java b/tests/robotests/src/com/android/settings/media/MediaOutputIndicatorSliceTest.java index 855e2df5d74..28620e97214 100644 --- a/tests/robotests/src/com/android/settings/media/MediaOutputIndicatorSliceTest.java +++ b/tests/robotests/src/com/android/settings/media/MediaOutputIndicatorSliceTest.java @@ -27,6 +27,9 @@ import static org.mockito.Mockito.when; import android.content.Context; import android.content.Intent; +import android.content.pm.ApplicationInfo; +import android.content.pm.PackageInfo; +import android.content.pm.PackageStats; import android.graphics.drawable.Drawable; import android.media.AudioManager; import android.media.session.MediaController; @@ -55,9 +58,11 @@ import org.mockito.Mock; import org.mockito.MockitoAnnotations; import org.robolectric.RobolectricTestRunner; import org.robolectric.RuntimeEnvironment; +import org.robolectric.Shadows; import org.robolectric.annotation.Config; import org.robolectric.annotation.Implementation; import org.robolectric.annotation.Implements; +import org.robolectric.shadows.ShadowPackageManager; import java.util.ArrayList; import java.util.List; @@ -70,6 +75,7 @@ public class MediaOutputIndicatorSliceTest { private static final String TEST_DEVICE_1_NAME = "test_device_1_name"; private static final String TEST_DEVICE_2_NAME = "test_device_2_name"; private static final String TEST_PACKAGE_NAME = "com.test"; + private static final String TEST_APPLICATION_LABEL = "APP Test Label"; private static MediaOutputIndicatorWorker sMediaOutputIndicatorWorker; @@ -90,6 +96,10 @@ public class MediaOutputIndicatorSliceTest { private MediaOutputIndicatorSlice mMediaOutputIndicatorSlice; private AudioManager mAudioManager; private MediaSession.Token mToken; + private ShadowPackageManager mShadowPackageManager; + private ApplicationInfo mAppInfo; + private PackageInfo mPackageInfo; + private PackageStats mPackageStats; @Before public void setUp() throws Exception { @@ -118,8 +128,11 @@ public class MediaOutputIndicatorSliceTest { @Test public void getSlice_withConnectedDevice_verifyMetadata() { + initPackage(); + mShadowPackageManager.addPackage(mPackageInfo, mPackageStats); mDevices.add(mDevice1); when(sMediaOutputIndicatorWorker.getMediaDevices()).thenReturn(mDevices); + when(sMediaOutputIndicatorWorker.getPackageName()).thenReturn(TEST_PACKAGE_NAME); doReturn(mMediaController).when(sMediaOutputIndicatorWorker) .getActiveLocalMediaController(); doReturn(mDevice1).when(sMediaOutputIndicatorWorker).getCurrentConnectedMediaDevice(); @@ -128,7 +141,9 @@ public class MediaOutputIndicatorSliceTest { final Slice mediaSlice = mMediaOutputIndicatorSlice.getSlice(); final SliceMetadata metadata = SliceMetadata.from(mContext, mediaSlice); - assertThat(metadata.getTitle()).isEqualTo(mContext.getText(R.string.media_output_title)); + assertThat(metadata.getTitle()).isEqualTo(mContext.getString( + R.string.media_output_label_title, Utils.getApplicationLabel(mContext, + TEST_PACKAGE_NAME))); assertThat(metadata.getSubtitle()).isEqualTo(TEST_DEVICE_1_NAME); assertThat(metadata.isErrorSlice()).isFalse(); } @@ -241,6 +256,18 @@ public class MediaOutputIndicatorSliceTest { assertThat(mMediaOutputIndicatorSlice.isVisible()).isFalse(); } + private void initPackage() { + mShadowPackageManager = Shadows.shadowOf(mContext.getPackageManager()); + mAppInfo = new ApplicationInfo(); + mAppInfo.flags = ApplicationInfo.FLAG_INSTALLED; + mAppInfo.packageName = TEST_PACKAGE_NAME; + mAppInfo.name = TEST_APPLICATION_LABEL; + mPackageInfo = new PackageInfo(); + mPackageInfo.packageName = TEST_PACKAGE_NAME; + mPackageInfo.applicationInfo = mAppInfo; + mPackageStats = new PackageStats(TEST_PACKAGE_NAME); + } + @Implements(SliceBackgroundWorker.class) public static class ShadowSliceBackgroundWorker { diff --git a/tests/robotests/src/com/android/settings/notification/RemoteVolumeGroupControllerTest.java b/tests/robotests/src/com/android/settings/notification/RemoteVolumeGroupControllerTest.java index 9e140ce3b4e..e8245055653 100644 --- a/tests/robotests/src/com/android/settings/notification/RemoteVolumeGroupControllerTest.java +++ b/tests/robotests/src/com/android/settings/notification/RemoteVolumeGroupControllerTest.java @@ -27,6 +27,9 @@ import static org.mockito.Mockito.when; import android.content.Context; import android.content.SharedPreferences; +import android.content.pm.ApplicationInfo; +import android.content.pm.PackageInfo; +import android.content.pm.PackageStats; import android.media.RoutingSessionInfo; import androidx.preference.Preference; @@ -35,6 +38,7 @@ import androidx.preference.PreferenceManager; import androidx.preference.PreferenceScreen; import com.android.settings.R; +import com.android.settings.Utils; import com.android.settings.testutils.shadow.ShadowBluetoothAdapter; import com.android.settings.widget.SeekBarPreference; import com.android.settingslib.media.LocalMediaManager; @@ -46,7 +50,9 @@ import org.mockito.Mock; import org.mockito.MockitoAnnotations; import org.robolectric.RobolectricTestRunner; import org.robolectric.RuntimeEnvironment; +import org.robolectric.Shadows; import org.robolectric.annotation.Config; +import org.robolectric.shadows.ShadowPackageManager; import java.util.ArrayList; import java.util.List; @@ -58,6 +64,8 @@ public class RemoteVolumeGroupControllerTest { private static final String KEY_REMOTE_VOLUME_GROUP = "remote_media_group"; private static final String TEST_SESSION_1_ID = "test_session_1_id"; private static final String TEST_SESSION_1_NAME = "test_session_1_name"; + private static final String TEST_PACKAGE_NAME = "com.test"; + private static final String TEST_APPLICATION_LABEL = "APP Test Label"; private static final int CURRENT_VOLUME = 30; private static final int MAX_VOLUME = 100; @@ -75,6 +83,10 @@ public class RemoteVolumeGroupControllerTest { private Context mContext; private RemoteVolumeGroupController mController; private PreferenceCategory mPreferenceCategory; + private ShadowPackageManager mShadowPackageManager; + private ApplicationInfo mAppInfo; + private PackageInfo mPackageInfo; + private PackageStats mPackageStats; @Before public void setUp() { @@ -94,6 +106,7 @@ public class RemoteVolumeGroupControllerTest { when(remoteSessionInfo.getName()).thenReturn(TEST_SESSION_1_NAME); when(remoteSessionInfo.getVolumeMax()).thenReturn(MAX_VOLUME); when(remoteSessionInfo.getVolume()).thenReturn(CURRENT_VOLUME); + when(remoteSessionInfo.getClientPackageName()).thenReturn(TEST_PACKAGE_NAME); when(remoteSessionInfo.isSystemSession()).thenReturn(false); mRoutingSessionInfos.add(remoteSessionInfo); when(mLocalMediaManager.getActiveMediaSession()).thenReturn(mRoutingSessionInfos); @@ -156,11 +169,15 @@ public class RemoteVolumeGroupControllerTest { @Test public void displayPreference_withActiveSession_checkSwitcherPreferenceTitle() { + initPackage(); + mShadowPackageManager.addPackage(mPackageInfo, mPackageStats); mController.displayPreference(mScreen); final Preference preference = mPreferenceCategory.findPreference( RemoteVolumeGroupController.SWITCHER_PREFIX + TEST_SESSION_1_ID); - assertThat(preference.getTitle()).isEqualTo(mContext.getText(R.string.media_output_title)); + assertThat(preference.getTitle()).isEqualTo(mContext.getString( + R.string.media_output_label_title, Utils.getApplicationLabel(mContext, + TEST_PACKAGE_NAME))); } @Test @@ -171,4 +188,16 @@ public class RemoteVolumeGroupControllerTest { assertThat(preference.getSummary()).isEqualTo(TEST_SESSION_1_NAME); } + + private void initPackage() { + mShadowPackageManager = Shadows.shadowOf(mContext.getPackageManager()); + mAppInfo = new ApplicationInfo(); + mAppInfo.flags = ApplicationInfo.FLAG_INSTALLED; + mAppInfo.packageName = TEST_PACKAGE_NAME; + mAppInfo.name = TEST_APPLICATION_LABEL; + mPackageInfo = new PackageInfo(); + mPackageInfo.packageName = TEST_PACKAGE_NAME; + mPackageInfo.applicationInfo = mAppInfo; + mPackageStats = new PackageStats(TEST_PACKAGE_NAME); + } } diff --git a/tests/robotests/src/com/android/settings/panel/PanelSlicesAdapterTest.java b/tests/robotests/src/com/android/settings/panel/PanelSlicesAdapterTest.java index 9e96d0f40cf..9e682f62ff9 100644 --- a/tests/robotests/src/com/android/settings/panel/PanelSlicesAdapterTest.java +++ b/tests/robotests/src/com/android/settings/panel/PanelSlicesAdapterTest.java @@ -18,7 +18,9 @@ package com.android.settings.panel; import static com.android.settings.panel.PanelContent.VIEW_TYPE_SLIDER; import static com.android.settings.panel.PanelSlicesAdapter.MAX_NUM_OF_SLICES; +import static com.android.settings.slices.CustomSliceRegistry.MEDIA_OUTPUT_GROUP_SLICE_URI; import static com.android.settings.slices.CustomSliceRegistry.MEDIA_OUTPUT_INDICATOR_SLICE_URI; +import static com.android.settings.slices.CustomSliceRegistry.MEDIA_OUTPUT_SLICE_URI; import static com.google.common.truth.Truth.assertThat; @@ -139,6 +141,58 @@ public class PanelSlicesAdapterTest { assertThat(viewHolder.isDividerAllowedAbove()).isFalse(); } + @Test + public void outputSwitcherSlice_shouldAddFirstItemPadding() { + addTestLiveData(MEDIA_OUTPUT_SLICE_URI); + + final PanelSlicesAdapter adapter = + new PanelSlicesAdapter(mPanelFragment, mData, 0 /* metrics category */); + final int position = 0; + final ViewGroup view = new FrameLayout(mContext); + final SliceRowViewHolder viewHolder = + adapter.onCreateViewHolder(view, PanelContent.VIEW_TYPE_SLIDER); + + adapter.onBindViewHolder(viewHolder, position); + + assertThat(viewHolder.mSliceSliderLayout.getPaddingTop()).isEqualTo( + mPanelFragment.getResources().getDimensionPixelSize( + R.dimen.output_switcher_slice_padding_top)); + } + + @Test + public void outputSwitcherGroupSlice_shouldAddFirstItemPadding() { + addTestLiveData(MEDIA_OUTPUT_GROUP_SLICE_URI); + + final PanelSlicesAdapter adapter = + new PanelSlicesAdapter(mPanelFragment, mData, 0 /* metrics category */); + final int position = 0; + final ViewGroup view = new FrameLayout(mContext); + final SliceRowViewHolder viewHolder = + adapter.onCreateViewHolder(view, PanelContent.VIEW_TYPE_SLIDER); + + adapter.onBindViewHolder(viewHolder, position); + + assertThat(viewHolder.mSliceSliderLayout.getPaddingTop()).isEqualTo( + mPanelFragment.getResources().getDimensionPixelSize( + R.dimen.output_switcher_slice_padding_top)); + } + + @Test + public void mediaOutputIndicatorSlice_notSliderPanel_noSliderLayout() { + addTestLiveData(MEDIA_OUTPUT_INDICATOR_SLICE_URI); + + final PanelSlicesAdapter adapter = + new PanelSlicesAdapter(mPanelFragment, mData, 0 /* metrics category */); + final int position = 0; + final ViewGroup view = new FrameLayout(mContext); + final SliceRowViewHolder viewHolder = + adapter.onCreateViewHolder(view, 0 /* view type*/); + + adapter.onBindViewHolder(viewHolder, position); + + assertThat(viewHolder.mSliceSliderLayout).isNull(); + } + @Test public void onCreateViewHolder_viewTypeSlider_verifyLayout() { final PanelSlicesAdapter adapter =