Snap for 6470414 from 30a4d31d6b to mainline-release

Change-Id: I759e3fd931e2482d06d09b9d2d8b47d457d68a24
This commit is contained in:
android-build-team Robot
2020-05-07 07:09:00 +00:00
22 changed files with 395 additions and 162 deletions

View File

@@ -55,6 +55,7 @@
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:gravity="center_vertical" android:gravity="center_vertical"
android:layoutDirection="ltr"
android:paddingTop="8dp"> android:paddingTop="8dp">
<ImageView <ImageView

View File

@@ -16,6 +16,7 @@
--> -->
<LinearLayout <LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android" xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/slice_slider_layout"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:orientation="vertical"> android:orientation="vertical">

View File

@@ -427,4 +427,7 @@
<!-- Developer options shared data screens related dimensions --> <!-- Developer options shared data screens related dimensions -->
<dimen name="list_preferred_item_padding">16dp</dimen> <dimen name="list_preferred_item_padding">16dp</dimen>
<!-- Output switcher panel related dimensions -->
<dimen name="output_switcher_slice_padding_top">12dp</dimen>
</resources> </resources>

View File

@@ -7485,14 +7485,6 @@
<string name="connected_devices_dashboard_no_driving_mode_summary">Bluetooth, NFC</string> <string name="connected_devices_dashboard_no_driving_mode_summary">Bluetooth, NFC</string>
<!-- Summary for Connected devices settings, explaning a few important settings under it [CHAR LIMIT=NONE]--> <!-- Summary for Connected devices settings, explaning a few important settings under it [CHAR LIMIT=NONE]-->
<string name="connected_devices_dashboard_no_driving_mode_no_nfc_summary">Bluetooth</string> <string name="connected_devices_dashboard_no_driving_mode_no_nfc_summary">Bluetooth</string>
<!--Summary for Connected devices settings, explaning a few important settings under it [CHAR LIMIT=NONE]-->
<string name="connected_devices_dashboard_android_auto_summary">Bluetooth, Android Auto, driving mode, NFC</string><!--
Summary for Connected devices settings, explaning a few important settings under it [CHAR LIMIT=NONE]-->
<string name="connected_devices_dashboard_android_auto_no_nfc_summary">Bluetooth, Android Auto, driving mode</string>
<!-- Summary for Connected devices settings, explaning a few important settings under it [CHAR LIMIT=NONE]-->
<string name="connected_devices_dashboard_android_auto_no_driving_mode_summary">Bluetooth, Android Auto, NFC</string>
<!-- Summary for Connected devices settings, explaning a few important settings under it [CHAR LIMIT=NONE]-->
<string name="connected_devices_dashboard_android_auto_no_nfc_no_driving_mode">Bluetooth, Android Auto</string>
<!-- Summary for Tap & pay settings, explaning a few important settings under it [CHAR LIMIT=NONE]--> <!-- Summary for Tap & pay settings, explaning a few important settings under it [CHAR LIMIT=NONE]-->
<string name="nfc_and_payment_settings_payment_off_nfc_off_summary">Unavailable because NFC is off</string> <string name="nfc_and_payment_settings_payment_off_nfc_off_summary">Unavailable because NFC is off</string>
<!-- Summary for Tap & pay settings, explaning a few important settings under it [CHAR LIMIT=NONE]--> <!-- Summary for Tap & pay settings, explaning a few important settings under it [CHAR LIMIT=NONE]-->
@@ -9250,10 +9242,10 @@
\t\n3.\tTap the app icon at the top of the screen, then tap Pin \t\n3.\tTap the app icon at the top of the screen, then tap Pin
</string> </string>
<!-- [CHAR LIMIT=none] Screen pinning description --> <!-- [CHAR LIMIT=none] Screen pinning description -->
<string name="screen_pinning_guest_mode_description"> <string name="screen_pinning_guest_user_description">
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. 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\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: \n\nTo use app pinning:
\t\n1.\tTurn on app pinning \t\n1.\tTurn on app pinning
\t\n2.\tOpen Overview \t\n2.\tOpen Overview
@@ -12074,4 +12066,7 @@
<string name="no_5g_in_dsds_text" product="device">When using 2 SIMs, this device will be limited to 4G. <annotation id="url">Learn more</annotation>.</string> <string name="no_5g_in_dsds_text" product="device">When using 2 SIMs, this device will be limited to 4G. <annotation id="url">Learn more</annotation>.</string>
<!-- Help URI, 5G limitation in DSDS condition. [DO NOT TRANSLATE] --> <!-- Help URI, 5G limitation in DSDS condition. [DO NOT TRANSLATE] -->
<string name="help_uri_5g_dsds" translatable="false"></string> <string name="help_uri_5g_dsds" translatable="false"></string>
<!-- Developer settings: app freezer title [CHAR LIMIT=50]-->
<string name="cached_apps_freezer">Suspend execution for cached apps</string>
</resources> </resources>

View File

@@ -584,6 +584,12 @@
android:title="@string/show_all_anrs" android:title="@string/show_all_anrs"
android:summary="@string/show_all_anrs_summary" /> android:summary="@string/show_all_anrs_summary" />
<ListPreference
android:key="cached_apps_freezer"
android:title="@string/cached_apps_freezer"
android:entries="@array/cached_apps_freezer_entries"
android:entryValues="@array/cached_apps_freezer_values" />
<SwitchPreference <SwitchPreference
android:key="show_notification_channel_warnings" android:key="show_notification_channel_warnings"
android:title="@string/show_notification_channel_warnings" android:title="@string/show_notification_channel_warnings"

View File

@@ -387,11 +387,11 @@ public final class AccessibilityGestureNavigationTutorial {
private static CharSequence getSoftwareTitle(Context context) { private static CharSequence getSoftwareTitle(Context context) {
final boolean isGestureNavigationEnabled = final boolean isGestureNavigationEnabled =
AccessibilityUtil.isGestureNavigateEnabled(context); AccessibilityUtil.isGestureNavigateEnabled(context);
final boolean isTouchExploreEnabled = AccessibilityUtil.isTouchExploreEnabled(context); final int resId = isGestureNavigationEnabled
? R.string.accessibility_tutorial_dialog_title_gesture
: R.string.accessibility_tutorial_dialog_title_button;
return (isGestureNavigationEnabled || isTouchExploreEnabled) return context.getText(resId);
? context.getText(R.string.accessibility_tutorial_dialog_title_gesture)
: context.getText(R.string.accessibility_tutorial_dialog_title_button);
} }
private static ImageView createSoftwareImage(Context context) { private static ImageView createSoftwareImage(Context context) {

View File

@@ -15,10 +15,7 @@
*/ */
package com.android.settings.connecteddevice; package com.android.settings.connecteddevice;
import static com.android.settingslib.drawer.TileUtils.IA_SETTINGS_ACTION;
import android.content.Context; import android.content.Context;
import android.content.Intent;
import android.provider.Settings; import android.provider.Settings;
import androidx.annotation.VisibleForTesting; import androidx.annotation.VisibleForTesting;
@@ -34,7 +31,6 @@ public class AdvancedConnectedDeviceController extends BasePreferenceController
private static final String DRIVING_MODE_SETTINGS_ENABLED = private static final String DRIVING_MODE_SETTINGS_ENABLED =
"gearhead:driving_mode_settings_enabled"; "gearhead:driving_mode_settings_enabled";
private static final String GEARHEAD_PACKAGE = "com.google.android.projection.gearhead";
public AdvancedConnectedDeviceController(Context context, String preferenceKey) { public AdvancedConnectedDeviceController(Context context, String preferenceKey) {
super(context, preferenceKey); super(context, preferenceKey);
@@ -59,7 +55,7 @@ public class AdvancedConnectedDeviceController extends BasePreferenceController
new NfcPreferenceController(context, NfcPreferenceController.KEY_TOGGLE_NFC); new NfcPreferenceController(context, NfcPreferenceController.KEY_TOGGLE_NFC);
return getConnectedDevicesSummaryResourceId(nfcPreferenceController, return getConnectedDevicesSummaryResourceId(nfcPreferenceController,
isDrivingModeAvailable(context), isAndroidAutoSettingAvailable(context)); isDrivingModeAvailable(context));
} }
@VisibleForTesting @VisibleForTesting
@@ -68,57 +64,26 @@ public class AdvancedConnectedDeviceController extends BasePreferenceController
getInt(context.getContentResolver(), DRIVING_MODE_SETTINGS_ENABLED, 0) == 1; getInt(context.getContentResolver(), DRIVING_MODE_SETTINGS_ENABLED, 0) == 1;
} }
@VisibleForTesting
static boolean isAndroidAutoSettingAvailable(Context context) {
final Intent intent = new Intent(IA_SETTINGS_ACTION);
intent.setPackage(GEARHEAD_PACKAGE);
return intent.resolveActivity(context.getPackageManager()) != null;
}
@VisibleForTesting @VisibleForTesting
static int getConnectedDevicesSummaryResourceId(NfcPreferenceController static int getConnectedDevicesSummaryResourceId(NfcPreferenceController
nfcPreferenceController, nfcPreferenceController, boolean isDrivingModeAvailable) {
boolean isDrivingModeAvailable,
boolean isAndroidAutoAvailable) {
final int resId; final int resId;
if (isAndroidAutoAvailable) { if (nfcPreferenceController.isAvailable()) {
if (nfcPreferenceController.isAvailable()) { if (isDrivingModeAvailable) {
if (isDrivingModeAvailable) { // NFC available, driving mode available
// NFC available, driving mode available resId = R.string.connected_devices_dashboard_summary;
resId = R.string.connected_devices_dashboard_android_auto_summary;
} else {
// NFC available, driving mode not available
resId =
R.string.connected_devices_dashboard_android_auto_no_driving_mode_summary;
}
} else { } else {
if (isDrivingModeAvailable) { // NFC available, driving mode not available
// NFC not available, driving mode available resId = R.string.connected_devices_dashboard_no_driving_mode_summary;
resId = R.string.connected_devices_dashboard_android_auto_no_nfc_summary;
} else {
// NFC not available, driving mode not available
resId =
R.string.connected_devices_dashboard_android_auto_no_nfc_no_driving_mode;
}
} }
} else { } else {
if (nfcPreferenceController.isAvailable()) { if (isDrivingModeAvailable) {
if (isDrivingModeAvailable) { // NFC not available, driving mode available
// NFC available, driving mode available resId = R.string.connected_devices_dashboard_no_nfc_summary;
resId = R.string.connected_devices_dashboard_summary;
} else {
// NFC available, driving mode not available
resId = R.string.connected_devices_dashboard_no_driving_mode_summary;
}
} else { } else {
if (isDrivingModeAvailable) { // NFC not available, driving mode not available
// NFC not available, driving mode available resId = R.string.connected_devices_dashboard_no_driving_mode_no_nfc_summary;
resId = R.string.connected_devices_dashboard_no_nfc_summary;
} else {
// NFC not available, driving mode not available
resId = R.string.connected_devices_dashboard_no_driving_mode_no_nfc_summary;
}
} }
} }

View File

@@ -89,6 +89,9 @@ public class UsbDetailsFunctionsController extends UsbDetailsController
@Override @Override
protected void refresh(boolean connected, long functions, int powerRole, int dataRole) { protected void refresh(boolean connected, long functions, int powerRole, int dataRole) {
if (!connected || dataRole != DATA_ROLE_DEVICE) { if (!connected || dataRole != DATA_ROLE_DEVICE) {
if (mPreviousFunction == UsbManager.FUNCTION_RNDIS) {
mConnectivityManager.stopTethering(TETHERING_USB);
}
mProfilesContainer.setEnabled(false); mProfilesContainer.setEnabled(false);
} else { } else {
// Functions are only available in device mode // Functions are only available in device mode
@@ -129,6 +132,9 @@ public class UsbDetailsFunctionsController extends UsbDetailsController
mConnectivityManager.startTethering(TETHERING_USB, true /* showProvisioningUi */, mConnectivityManager.startTethering(TETHERING_USB, true /* showProvisioningUi */,
mOnStartTetheringCallback); mOnStartTetheringCallback);
} else { } else {
if (mPreviousFunction == UsbManager.FUNCTION_RNDIS) {
mConnectivityManager.stopTethering(TETHERING_USB);
}
mUsbBackend.setCurrentFunctions(function); mUsbBackend.setCurrentFunctions(function);
} }
} }

View File

@@ -0,0 +1,134 @@
/*
* Copyright (C) 2020 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.development;
import android.app.ActivityManager;
import android.content.Context;
import android.content.DialogInterface;
import android.os.PowerManager;
import android.os.RemoteException;
import android.provider.Settings;
import android.text.TextUtils;
import android.util.Log;
import androidx.annotation.VisibleForTesting;
import androidx.appcompat.app.AlertDialog;
import androidx.preference.ListPreference;
import androidx.preference.Preference;
import com.android.settings.R;
import com.android.settings.core.PreferenceControllerMixin;
import com.android.settingslib.development.DeveloperOptionsPreferenceController;
public class CachedAppsFreezerPreferenceController extends DeveloperOptionsPreferenceController
implements Preference.OnPreferenceChangeListener, PreferenceControllerMixin {
@VisibleForTesting
private static final String CACHED_APPS_FREEZER_KEY = "cached_apps_freezer";
private final String[] mListValues;
private final String[] mListSummaries;
public CachedAppsFreezerPreferenceController(Context context) {
super(context);
mListValues = context.getResources().getStringArray(R.array.cached_apps_freezer_values);
mListSummaries = context.getResources().getStringArray(
R.array.cached_apps_freezer_entries);
}
@Override
public boolean isAvailable() {
boolean available = false;
try {
available = ActivityManager.getService().isAppFreezerSupported();
} catch (RemoteException e) {
Log.w(TAG, "Unable to obtain freezer support status from ActivityManager");
}
return available;
}
@Override
public String getPreferenceKey() {
return CACHED_APPS_FREEZER_KEY;
}
@Override
public boolean onPreferenceChange(Preference preference, Object newValue) {
final String currentValue = Settings.Global.getString(mContext.getContentResolver(),
Settings.Global.CACHED_APPS_FREEZER_ENABLED);
if (!newValue.equals(currentValue)) {
final AlertDialog dialog = new AlertDialog.Builder(mContext)
.setMessage(R.string.cached_apps_freezer_reboot_dialog_text)
.setPositiveButton(android.R.string.ok, getRebootDialogOkListener(newValue))
.setNegativeButton(android.R.string.cancel, getRebootDialogCancelListener())
.create();
dialog.show();
}
return true;
}
private DialogInterface.OnClickListener getRebootDialogOkListener(Object newValue) {
return (dialog, which) -> {
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());
}
}

View File

@@ -505,6 +505,7 @@ public class DevelopmentSettingsDashboardFragment extends RestrictedDashboardFra
controllers.add(new ProfileGpuRenderingPreferenceController(context)); controllers.add(new ProfileGpuRenderingPreferenceController(context));
controllers.add(new KeepActivitiesPreferenceController(context)); controllers.add(new KeepActivitiesPreferenceController(context));
controllers.add(new BackgroundProcessLimitPreferenceController(context)); controllers.add(new BackgroundProcessLimitPreferenceController(context));
controllers.add(new CachedAppsFreezerPreferenceController(context));
controllers.add(new ShowFirstCrashDialogPreferenceController(context)); controllers.add(new ShowFirstCrashDialogPreferenceController(context));
controllers.add(new AppsNotRespondingPreferenceController(context)); controllers.add(new AppsNotRespondingPreferenceController(context));
controllers.add(new NotificationChannelWarningsPreferenceController(context)); controllers.add(new NotificationChannelWarningsPreferenceController(context));

View File

@@ -60,18 +60,26 @@ public class BackGestureIndicatorView extends LinearLayout {
mLeftIndicator.setImageDrawable(mLeftDrawable); mLeftIndicator.setImageDrawable(mLeftDrawable);
mRightIndicator.setImageDrawable(mRightDrawable); 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[] { TypedArray a = context.obtainStyledAttributes(new int[] {
android.R.attr.windowLightNavigationBar, android.R.attr.windowLightNavigationBar,
android.R.attr.windowLightStatusBar}); android.R.attr.windowLightStatusBar});
if (a.getBoolean(0, false)) { if (a.getBoolean(0, false)) {
setSystemUiVisibility( visibility |= View.SYSTEM_UI_FLAG_LIGHT_NAVIGATION_BAR;
getSystemUiVisibility() | View.SYSTEM_UI_FLAG_LIGHT_NAVIGATION_BAR);
} }
if (a.getBoolean(1, false)) { if (a.getBoolean(1, false)) {
setSystemUiVisibility( visibility |= View.SYSTEM_UI_FLAG_LIGHT_STATUS_BAR;
getSystemUiVisibility() | View.SYSTEM_UI_FLAG_LIGHT_STATUS_BAR);
} }
a.recycle(); a.recycle();
setSystemUiVisibility(visibility);
} }
public void setIndicatorWidth(int width, boolean leftIndicator) { public void setIndicatorWidth(int width, boolean leftIndicator) {

View File

@@ -58,7 +58,8 @@ public class MediaOutputIndicatorSlice implements CustomSliceable {
} }
final IconCompat icon = IconCompat.createWithResource(mContext, final IconCompat icon = IconCompat.createWithResource(mContext,
com.android.internal.R.drawable.ic_settings_bluetooth); 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, final PendingIntent primaryActionIntent = PendingIntent.getActivity(mContext,
0 /* requestCode */, getMediaOutputSliceIntent(), 0 /* flags */); 0 /* requestCode */, getMediaOutputSliceIntent(), 0 /* flags */);
final SliceAction primarySliceAction = SliceAction.createDeeplink( final SliceAction primarySliceAction = SliceAction.createDeeplink(

View File

@@ -58,6 +58,7 @@ public class MediaOutputIndicatorWorker extends SliceBackgroundWorker implements
private final Collection<MediaDevice> mMediaDevices = new CopyOnWriteArrayList<>(); private final Collection<MediaDevice> mMediaDevices = new CopyOnWriteArrayList<>();
private LocalBluetoothManager mLocalBluetoothManager; private LocalBluetoothManager mLocalBluetoothManager;
private String mPackageName;
@VisibleForTesting @VisibleForTesting
LocalMediaManager mLocalMediaManager; LocalMediaManager mLocalMediaManager;
@@ -82,11 +83,10 @@ public class MediaOutputIndicatorWorker extends SliceBackgroundWorker implements
if (mLocalMediaManager == null) { if (mLocalMediaManager == null) {
final MediaController controller = getActiveLocalMediaController(); final MediaController controller = getActiveLocalMediaController();
String packageName = null;
if (controller != 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); mLocalMediaManager.registerCallback(this);
@@ -168,6 +168,10 @@ public class MediaOutputIndicatorWorker extends SliceBackgroundWorker implements
return mLocalMediaManager.getCurrentConnectedDevice(); return mLocalMediaManager.getCurrentConnectedDevice();
} }
String getPackageName() {
return mPackageName;
}
private class DevicesChangedBroadcastReceiver extends BroadcastReceiver { private class DevicesChangedBroadcastReceiver extends BroadcastReceiver {
@Override @Override
public void onReceive(Context context, Intent intent) { public void onReceive(Context context, Intent intent) {

View File

@@ -37,6 +37,7 @@ import androidx.slice.builders.SliceAction;
import com.android.settings.R; import com.android.settings.R;
import com.android.settings.SubSettings; import com.android.settings.SubSettings;
import com.android.settings.Utils;
import com.android.settings.notification.SoundSettings; import com.android.settings.notification.SoundSettings;
import com.android.settings.slices.CustomSliceable; import com.android.settings.slices.CustomSliceable;
import com.android.settings.slices.SliceBackgroundWorker; import com.android.settings.slices.SliceBackgroundWorker;
@@ -86,7 +87,6 @@ public class RemoteMediaSlice implements CustomSliceable {
return listBuilder.build(); return listBuilder.build();
} }
final CharSequence castVolume = mContext.getText(R.string.remote_media_volume_option_title); 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, final IconCompat icon = IconCompat.createWithResource(mContext,
R.drawable.ic_volume_remote); R.drawable.ic_volume_remote);
// To create an empty icon to indent the row // To create an empty icon to indent the row
@@ -99,6 +99,8 @@ public class RemoteMediaSlice implements CustomSliceable {
+ maxVolume); + maxVolume);
continue; continue;
} }
final CharSequence outputTitle = mContext.getString(R.string.media_output_label_title,
Utils.getApplicationLabel(mContext, info.getClientPackageName()));
listBuilder.addInputRange(new InputRangeBuilder() listBuilder.addInputRange(new InputRangeBuilder()
.setTitleItem(icon, ListBuilder.ICON_IMAGE) .setTitleItem(icon, ListBuilder.ICON_IMAGE)
.setTitle(castVolume) .setTitle(castVolume)
@@ -154,7 +156,8 @@ public class RemoteMediaSlice implements CustomSliceable {
0 /* requestCode */, intent, 0 /* flags */); 0 /* requestCode */, intent, 0 /* flags */);
final SliceAction primarySliceAction = SliceAction.createDeeplink( final SliceAction primarySliceAction = SliceAction.createDeeplink(
primaryActionIntent, icon, ListBuilder.ICON_IMAGE, 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; return primarySliceAction;
} }

View File

@@ -30,6 +30,7 @@ import androidx.preference.PreferenceCategory;
import androidx.preference.PreferenceScreen; import androidx.preference.PreferenceScreen;
import com.android.settings.R; import com.android.settings.R;
import com.android.settings.Utils;
import com.android.settings.core.BasePreferenceController; import com.android.settings.core.BasePreferenceController;
import com.android.settingslib.core.lifecycle.Lifecycle; import com.android.settingslib.core.lifecycle.Lifecycle;
import com.android.settingslib.media.LocalMediaManager; import com.android.settingslib.media.LocalMediaManager;
@@ -108,7 +109,6 @@ public class RemoteVolumeGroupController extends BasePreferenceController implem
mPreferenceCategory.setVisible(false); mPreferenceCategory.setVisible(false);
return; return;
} }
final CharSequence outputTitle = mContext.getText(R.string.media_output_title);
final CharSequence castVolume = mContext.getText(R.string.remote_media_volume_option_title); final CharSequence castVolume = mContext.getText(R.string.remote_media_volume_option_title);
mPreferenceCategory.setVisible(true); mPreferenceCategory.setVisible(true);
@@ -116,6 +116,8 @@ public class RemoteVolumeGroupController extends BasePreferenceController implem
if (mPreferenceCategory.findPreference(info.getId()) != null) { if (mPreferenceCategory.findPreference(info.getId()) != null) {
continue; continue;
} }
final CharSequence outputTitle = mContext.getString(R.string.media_output_label_title,
Utils.getApplicationLabel(mContext, info.getClientPackageName()));
// Add slider // Add slider
final RemoteVolumeSeekBarPreference seekBarPreference = final RemoteVolumeSeekBarPreference seekBarPreference =
new RemoteVolumeSeekBarPreference(mContext); new RemoteVolumeSeekBarPreference(mContext);

View File

@@ -16,7 +16,9 @@
package com.android.settings.panel; 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_INDICATOR_SLICE_URI;
import static com.android.settings.slices.CustomSliceRegistry.MEDIA_OUTPUT_SLICE_URI;
import android.app.settings.SettingsEnums; import android.app.settings.SettingsEnums;
import android.content.Context; import android.content.Context;
@@ -24,6 +26,7 @@ import android.net.Uri;
import android.view.LayoutInflater; import android.view.LayoutInflater;
import android.view.View; import android.view.View;
import android.view.ViewGroup; import android.view.ViewGroup;
import android.widget.LinearLayout;
import androidx.annotation.NonNull; import androidx.annotation.NonNull;
import androidx.annotation.VisibleForTesting; import androidx.annotation.VisibleForTesting;
@@ -81,7 +84,7 @@ public class PanelSlicesAdapter
@Override @Override
public void onBindViewHolder(@NonNull SliceRowViewHolder sliceRowViewHolder, int position) { 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 @VisibleForTesting
final SliceView sliceView; final SliceView sliceView;
@VisibleForTesting
final LinearLayout mSliceSliderLayout;
public SliceRowViewHolder(View view) { public SliceRowViewHolder(View view) {
super(view); super(view);
sliceView = view.findViewById(R.id.slice_view); sliceView = view.findViewById(R.id.slice_view);
sliceView.setMode(SliceView.MODE_LARGE); sliceView.setMode(SliceView.MODE_LARGE);
sliceView.setShowTitleItems(true); sliceView.setShowTitleItems(true);
mSliceSliderLayout = view.findViewById(R.id.slice_slider_layout);
} }
public void onBind(LiveData<Slice> sliceLiveData) { /**
* Called when the view is displayed.
*/
public void onBind(LiveData<Slice> sliceLiveData, int position) {
sliceLiveData.observe(mPanelFragment.getViewLifecycleOwner(), sliceView); sliceLiveData.observe(mPanelFragment.getViewLifecycleOwner(), sliceView);
// Do not show the divider above media devices switcher slice per request // Do not show the divider above media devices switcher slice per request
@@ -133,6 +142,16 @@ public class PanelSlicesAdapter
mDividerAllowedAbove = false; 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 // Log Panel interaction
sliceView.setOnSliceActionListener( sliceView.setOnSliceActionListener(
((eventInfo, sliceItem) -> { ((eventInfo, sliceItem) -> {

View File

@@ -22,6 +22,7 @@ import android.content.DialogInterface;
import android.content.Intent; import android.content.Intent;
import android.os.Bundle; import android.os.Bundle;
import android.os.UserHandle; import android.os.UserHandle;
import android.os.UserManager;
import android.provider.SearchIndexableResource; import android.provider.SearchIndexableResource;
import android.provider.Settings; import android.provider.Settings;
import android.widget.Switch; import android.widget.Switch;
@@ -61,6 +62,7 @@ public class ScreenPinningSettings extends SettingsPreferenceFragment
private SwitchPreference mUseScreenLock; private SwitchPreference mUseScreenLock;
private FooterPreference mFooterPreference; private FooterPreference mFooterPreference;
private LockPatternUtils mLockPatternUtils; private LockPatternUtils mLockPatternUtils;
private UserManager mUserManager;
@Override @Override
public int getMetricsCategory() { public int getMetricsCategory() {
@@ -74,6 +76,7 @@ public class ScreenPinningSettings extends SettingsPreferenceFragment
final SettingsActivity activity = (SettingsActivity) getActivity(); final SettingsActivity activity = (SettingsActivity) getActivity();
activity.setTitle(R.string.screen_pinning_title); activity.setTitle(R.string.screen_pinning_title);
mLockPatternUtils = new LockPatternUtils(activity); mLockPatternUtils = new LockPatternUtils(activity);
mUserManager = activity.getSystemService(UserManager.class);
addPreferencesFromResource(R.xml.screen_pinning_settings); addPreferencesFromResource(R.xml.screen_pinning_settings);
final PreferenceScreen root = getPreferenceScreen(); final PreferenceScreen root = getPreferenceScreen();
@@ -224,10 +227,22 @@ public class ScreenPinningSettings extends SettingsPreferenceFragment
mUseScreenLock.setTitle(getCurrentSecurityTitle()); mUseScreenLock.setTitle(getCurrentSecurityTitle());
} else { } else {
mFooterPreference.setVisible(true); mFooterPreference.setVisible(true);
mFooterPreference.setSummary(getAppPinningContent());
mUseScreenLock.setVisible(false); 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 * For search
*/ */

View File

@@ -23,9 +23,6 @@ import static org.mockito.Mockito.spy;
import android.content.ContentResolver; import android.content.ContentResolver;
import android.content.Context; import android.content.Context;
import android.content.Intent;
import android.content.pm.ActivityInfo;
import android.content.pm.ResolveInfo;
import android.nfc.NfcAdapter; import android.nfc.NfcAdapter;
import android.provider.Settings; import android.provider.Settings;
@@ -41,7 +38,6 @@ import org.robolectric.RuntimeEnvironment;
import org.robolectric.Shadows; import org.robolectric.Shadows;
import org.robolectric.annotation.Config; import org.robolectric.annotation.Config;
import org.robolectric.shadows.ShadowNfcAdapter; import org.robolectric.shadows.ShadowNfcAdapter;
import org.robolectric.shadows.ShadowPackageManager;
import org.robolectric.util.ReflectionHelpers; import org.robolectric.util.ReflectionHelpers;
@RunWith(RobolectricTestRunner.class) @RunWith(RobolectricTestRunner.class)
@@ -51,13 +47,11 @@ public class AdvancedConnectedDeviceControllerTest {
private static final String KEY = "test_key"; private static final String KEY = "test_key";
private static final String DRIVING_MODE_SETTINGS_ENABLED = private static final String DRIVING_MODE_SETTINGS_ENABLED =
"gearhead: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 Context mContext;
private NfcPreferenceController mNfcController; private NfcPreferenceController mNfcController;
private ShadowNfcAdapter mShadowNfcAdapter; private ShadowNfcAdapter mShadowNfcAdapter;
private ContentResolver mContentResolver; private ContentResolver mContentResolver;
private ShadowPackageManager mShadowPackageManager;
@Before @Before
public void setUp() { public void setUp() {
@@ -68,7 +62,6 @@ public class AdvancedConnectedDeviceControllerTest {
mNfcController = new NfcPreferenceController(mContext, mNfcController = new NfcPreferenceController(mContext,
NfcPreferenceController.KEY_TOGGLE_NFC); NfcPreferenceController.KEY_TOGGLE_NFC);
mShadowNfcAdapter = Shadows.shadowOf(NfcAdapter.getNfcAdapter(mContext)); mShadowNfcAdapter = Shadows.shadowOf(NfcAdapter.getNfcAdapter(mContext));
mShadowPackageManager = Shadows.shadowOf(mContext.getPackageManager());
} }
@Test @Test
@@ -83,41 +76,14 @@ public class AdvancedConnectedDeviceControllerTest {
public void isDrivingModeAvailable_returnTrue() { public void isDrivingModeAvailable_returnTrue() {
Settings.System.putInt(mContentResolver, DRIVING_MODE_SETTINGS_ENABLED, 1); Settings.System.putInt(mContentResolver, DRIVING_MODE_SETTINGS_ENABLED, 1);
assertThat( assertThat(AdvancedConnectedDeviceController.isDrivingModeAvailable(mContext)).isTrue();
AdvancedConnectedDeviceController.isDrivingModeAvailable(mContext)).isTrue();
} }
@Test @Test
public void isDrivingModeAvailable_returnFalse() { public void isDrivingModeAvailable_returnFalse() {
Settings.System.putInt(mContentResolver, DRIVING_MODE_SETTINGS_ENABLED, 0); Settings.System.putInt(mContentResolver, DRIVING_MODE_SETTINGS_ENABLED, 0);
assertThat( assertThat(AdvancedConnectedDeviceController.isDrivingModeAvailable(mContext)).isFalse();
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();
} }
@Test @Test
@@ -125,7 +91,7 @@ public class AdvancedConnectedDeviceControllerTest {
// NFC available, driving mode available // NFC available, driving mode available
mShadowNfcAdapter.setEnabled(true); mShadowNfcAdapter.setEnabled(true);
assertThat(AdvancedConnectedDeviceController assertThat(AdvancedConnectedDeviceController
.getConnectedDevicesSummaryResourceId(mNfcController, true, false)) .getConnectedDevicesSummaryResourceId(mNfcController, true))
.isEqualTo(R.string.connected_devices_dashboard_summary); .isEqualTo(R.string.connected_devices_dashboard_summary);
} }
@@ -134,7 +100,7 @@ public class AdvancedConnectedDeviceControllerTest {
// NFC is available, driving mode not available // NFC is available, driving mode not available
mShadowNfcAdapter.setEnabled(true); mShadowNfcAdapter.setEnabled(true);
assertThat(AdvancedConnectedDeviceController assertThat(AdvancedConnectedDeviceController
.getConnectedDevicesSummaryResourceId(mNfcController, false, false)) .getConnectedDevicesSummaryResourceId(mNfcController, false))
.isEqualTo(R.string.connected_devices_dashboard_no_driving_mode_summary); .isEqualTo(R.string.connected_devices_dashboard_no_driving_mode_summary);
} }
@@ -143,7 +109,7 @@ public class AdvancedConnectedDeviceControllerTest {
// NFC not available, driving mode available // NFC not available, driving mode available
ReflectionHelpers.setField(mNfcController, "mNfcAdapter", null); ReflectionHelpers.setField(mNfcController, "mNfcAdapter", null);
assertThat(AdvancedConnectedDeviceController assertThat(AdvancedConnectedDeviceController
.getConnectedDevicesSummaryResourceId(mNfcController, true, false)) .getConnectedDevicesSummaryResourceId(mNfcController, true))
.isEqualTo(R.string.connected_devices_dashboard_no_nfc_summary); .isEqualTo(R.string.connected_devices_dashboard_no_nfc_summary);
} }
@@ -152,52 +118,7 @@ public class AdvancedConnectedDeviceControllerTest {
// NFC not available, driving mode not available // NFC not available, driving mode not available
ReflectionHelpers.setField(mNfcController, "mNfcAdapter", null); ReflectionHelpers.setField(mNfcController, "mNfcAdapter", null);
assertThat(AdvancedConnectedDeviceController assertThat(AdvancedConnectedDeviceController
.getConnectedDevicesSummaryResourceId(mNfcController, false, false)) .getConnectedDevicesSummaryResourceId(mNfcController, false))
.isEqualTo(R.string.connected_devices_dashboard_no_driving_mode_no_nfc_summary); .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;
}
} }

View File

@@ -270,4 +270,42 @@ public class UsbDetailsFunctionsControllerTest {
verify(mUsbBackend).setCurrentFunctions(UsbManager.FUNCTION_PTP); 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);
}
} }

View File

@@ -27,6 +27,9 @@ import static org.mockito.Mockito.when;
import android.content.Context; import android.content.Context;
import android.content.Intent; 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.graphics.drawable.Drawable;
import android.media.AudioManager; import android.media.AudioManager;
import android.media.session.MediaController; import android.media.session.MediaController;
@@ -55,9 +58,11 @@ import org.mockito.Mock;
import org.mockito.MockitoAnnotations; import org.mockito.MockitoAnnotations;
import org.robolectric.RobolectricTestRunner; import org.robolectric.RobolectricTestRunner;
import org.robolectric.RuntimeEnvironment; import org.robolectric.RuntimeEnvironment;
import org.robolectric.Shadows;
import org.robolectric.annotation.Config; import org.robolectric.annotation.Config;
import org.robolectric.annotation.Implementation; import org.robolectric.annotation.Implementation;
import org.robolectric.annotation.Implements; import org.robolectric.annotation.Implements;
import org.robolectric.shadows.ShadowPackageManager;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; 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_1_NAME = "test_device_1_name";
private static final String TEST_DEVICE_2_NAME = "test_device_2_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_PACKAGE_NAME = "com.test";
private static final String TEST_APPLICATION_LABEL = "APP Test Label";
private static MediaOutputIndicatorWorker sMediaOutputIndicatorWorker; private static MediaOutputIndicatorWorker sMediaOutputIndicatorWorker;
@@ -90,6 +96,10 @@ public class MediaOutputIndicatorSliceTest {
private MediaOutputIndicatorSlice mMediaOutputIndicatorSlice; private MediaOutputIndicatorSlice mMediaOutputIndicatorSlice;
private AudioManager mAudioManager; private AudioManager mAudioManager;
private MediaSession.Token mToken; private MediaSession.Token mToken;
private ShadowPackageManager mShadowPackageManager;
private ApplicationInfo mAppInfo;
private PackageInfo mPackageInfo;
private PackageStats mPackageStats;
@Before @Before
public void setUp() throws Exception { public void setUp() throws Exception {
@@ -118,8 +128,11 @@ public class MediaOutputIndicatorSliceTest {
@Test @Test
public void getSlice_withConnectedDevice_verifyMetadata() { public void getSlice_withConnectedDevice_verifyMetadata() {
initPackage();
mShadowPackageManager.addPackage(mPackageInfo, mPackageStats);
mDevices.add(mDevice1); mDevices.add(mDevice1);
when(sMediaOutputIndicatorWorker.getMediaDevices()).thenReturn(mDevices); when(sMediaOutputIndicatorWorker.getMediaDevices()).thenReturn(mDevices);
when(sMediaOutputIndicatorWorker.getPackageName()).thenReturn(TEST_PACKAGE_NAME);
doReturn(mMediaController).when(sMediaOutputIndicatorWorker) doReturn(mMediaController).when(sMediaOutputIndicatorWorker)
.getActiveLocalMediaController(); .getActiveLocalMediaController();
doReturn(mDevice1).when(sMediaOutputIndicatorWorker).getCurrentConnectedMediaDevice(); doReturn(mDevice1).when(sMediaOutputIndicatorWorker).getCurrentConnectedMediaDevice();
@@ -128,7 +141,9 @@ public class MediaOutputIndicatorSliceTest {
final Slice mediaSlice = mMediaOutputIndicatorSlice.getSlice(); final Slice mediaSlice = mMediaOutputIndicatorSlice.getSlice();
final SliceMetadata metadata = SliceMetadata.from(mContext, mediaSlice); 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.getSubtitle()).isEqualTo(TEST_DEVICE_1_NAME);
assertThat(metadata.isErrorSlice()).isFalse(); assertThat(metadata.isErrorSlice()).isFalse();
} }
@@ -241,6 +256,18 @@ public class MediaOutputIndicatorSliceTest {
assertThat(mMediaOutputIndicatorSlice.isVisible()).isFalse(); 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) @Implements(SliceBackgroundWorker.class)
public static class ShadowSliceBackgroundWorker { public static class ShadowSliceBackgroundWorker {

View File

@@ -27,6 +27,9 @@ import static org.mockito.Mockito.when;
import android.content.Context; import android.content.Context;
import android.content.SharedPreferences; import android.content.SharedPreferences;
import android.content.pm.ApplicationInfo;
import android.content.pm.PackageInfo;
import android.content.pm.PackageStats;
import android.media.RoutingSessionInfo; import android.media.RoutingSessionInfo;
import androidx.preference.Preference; import androidx.preference.Preference;
@@ -35,6 +38,7 @@ import androidx.preference.PreferenceManager;
import androidx.preference.PreferenceScreen; import androidx.preference.PreferenceScreen;
import com.android.settings.R; import com.android.settings.R;
import com.android.settings.Utils;
import com.android.settings.testutils.shadow.ShadowBluetoothAdapter; import com.android.settings.testutils.shadow.ShadowBluetoothAdapter;
import com.android.settings.widget.SeekBarPreference; import com.android.settings.widget.SeekBarPreference;
import com.android.settingslib.media.LocalMediaManager; import com.android.settingslib.media.LocalMediaManager;
@@ -46,7 +50,9 @@ import org.mockito.Mock;
import org.mockito.MockitoAnnotations; import org.mockito.MockitoAnnotations;
import org.robolectric.RobolectricTestRunner; import org.robolectric.RobolectricTestRunner;
import org.robolectric.RuntimeEnvironment; import org.robolectric.RuntimeEnvironment;
import org.robolectric.Shadows;
import org.robolectric.annotation.Config; import org.robolectric.annotation.Config;
import org.robolectric.shadows.ShadowPackageManager;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; 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 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_ID = "test_session_1_id";
private static final String TEST_SESSION_1_NAME = "test_session_1_name"; 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 CURRENT_VOLUME = 30;
private static final int MAX_VOLUME = 100; private static final int MAX_VOLUME = 100;
@@ -75,6 +83,10 @@ public class RemoteVolumeGroupControllerTest {
private Context mContext; private Context mContext;
private RemoteVolumeGroupController mController; private RemoteVolumeGroupController mController;
private PreferenceCategory mPreferenceCategory; private PreferenceCategory mPreferenceCategory;
private ShadowPackageManager mShadowPackageManager;
private ApplicationInfo mAppInfo;
private PackageInfo mPackageInfo;
private PackageStats mPackageStats;
@Before @Before
public void setUp() { public void setUp() {
@@ -94,6 +106,7 @@ public class RemoteVolumeGroupControllerTest {
when(remoteSessionInfo.getName()).thenReturn(TEST_SESSION_1_NAME); when(remoteSessionInfo.getName()).thenReturn(TEST_SESSION_1_NAME);
when(remoteSessionInfo.getVolumeMax()).thenReturn(MAX_VOLUME); when(remoteSessionInfo.getVolumeMax()).thenReturn(MAX_VOLUME);
when(remoteSessionInfo.getVolume()).thenReturn(CURRENT_VOLUME); when(remoteSessionInfo.getVolume()).thenReturn(CURRENT_VOLUME);
when(remoteSessionInfo.getClientPackageName()).thenReturn(TEST_PACKAGE_NAME);
when(remoteSessionInfo.isSystemSession()).thenReturn(false); when(remoteSessionInfo.isSystemSession()).thenReturn(false);
mRoutingSessionInfos.add(remoteSessionInfo); mRoutingSessionInfos.add(remoteSessionInfo);
when(mLocalMediaManager.getActiveMediaSession()).thenReturn(mRoutingSessionInfos); when(mLocalMediaManager.getActiveMediaSession()).thenReturn(mRoutingSessionInfos);
@@ -156,11 +169,15 @@ public class RemoteVolumeGroupControllerTest {
@Test @Test
public void displayPreference_withActiveSession_checkSwitcherPreferenceTitle() { public void displayPreference_withActiveSession_checkSwitcherPreferenceTitle() {
initPackage();
mShadowPackageManager.addPackage(mPackageInfo, mPackageStats);
mController.displayPreference(mScreen); mController.displayPreference(mScreen);
final Preference preference = mPreferenceCategory.findPreference( final Preference preference = mPreferenceCategory.findPreference(
RemoteVolumeGroupController.SWITCHER_PREFIX + TEST_SESSION_1_ID); 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 @Test
@@ -171,4 +188,16 @@ public class RemoteVolumeGroupControllerTest {
assertThat(preference.getSummary()).isEqualTo(TEST_SESSION_1_NAME); 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);
}
} }

View File

@@ -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.PanelContent.VIEW_TYPE_SLIDER;
import static com.android.settings.panel.PanelSlicesAdapter.MAX_NUM_OF_SLICES; 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_INDICATOR_SLICE_URI;
import static com.android.settings.slices.CustomSliceRegistry.MEDIA_OUTPUT_SLICE_URI;
import static com.google.common.truth.Truth.assertThat; import static com.google.common.truth.Truth.assertThat;
@@ -139,6 +141,58 @@ public class PanelSlicesAdapterTest {
assertThat(viewHolder.isDividerAllowedAbove()).isFalse(); 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 @Test
public void onCreateViewHolder_viewTypeSlider_verifyLayout() { public void onCreateViewHolder_viewTypeSlider_verifyLayout() {
final PanelSlicesAdapter adapter = final PanelSlicesAdapter adapter =