Snap for 6583806 from 1d02b72826 to mainline-release

Change-Id: I87944fab9648e949a113b10d19ed0c9598a2afe8
This commit is contained in:
android-build-team Robot
2020-06-12 07:14:32 +00:00
22 changed files with 355 additions and 146 deletions

View File

@@ -0,0 +1,31 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
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.
-->
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/slice_slider_layout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<androidx.slice.widget.SliceView
android:id="@+id/slice_view"
style="@style/Widget.SliceView.Panel.Slider.LargeIcon"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:paddingStart="0dp"
android:paddingEnd="0dp"/>
</LinearLayout>

View File

@@ -0,0 +1,19 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- 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.
-->
<resources xmlns:android="http://schemas.android.com/apk/res/android" xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<!-- Cell Broadcast settings title. [CHAR LIMIT=50] -->
<string name="cell_broadcast_settings">Public warnings</string>
</resources>

View File

@@ -533,6 +533,10 @@
<item name="rowStyle">@style/SliceRow.Slider</item>
</style>
<style name="Widget.SliceView.Panel.Slider.LargeIcon">
<item name="rowStyle">@style/SliceRow.Slider.LargeIcon</item>
</style>
<style name="SliceRow">
<!-- 2dp start padding for the start icon -->
<item name="titleItemStartPadding">2dp</item>
@@ -574,6 +578,15 @@
<!-- Align text with slider -->
<item name="titleStartPadding">11dp</item>
<item name="subContentStartPadding">11dp</item>
<!-- Padding for indeterminate progress bar -->
<item name="progressBarStartPadding">12dp</item>
<item name="progressBarEndPadding">16dp</item>
</style>
<style name="SliceRow.Slider.LargeIcon">
<!-- Layout is 48dp and actual icon size is 48-(iconSize/2) -->
<item name="iconSize">12dp</item>
</style>
<style name="DisclaimerPositiveButton" parent="@style/SudGlifButton.Primary">

View File

@@ -27,11 +27,14 @@
<item name="twoStateButtonPreferenceStyle">@style/TwoStateButtonPreference</item>
<item name="preferenceCategoryTitleTextAppearance">@style/TextAppearance.CategoryTitle
</item>
<item name="preferenceCategoryStyle">@style/SettingsCategoryPreference</item>
<!-- For preference category color -->
<item name="preferenceCategoryTitleTextColor">?android:attr/textColorSecondary</item>
<item name="preferenceFragmentCompatStyle">@style/SettingsPreferenceFragmentStyle</item>
</style>
<style name="SettingsCategoryPreference" parent="Preference.Category.Material" />
<style name="PreferenceTheme.SetupWizard">
<item name="preferenceFragmentCompatStyle">@style/SetupWizardPreferenceFragmentStyle</item>
<item name="preferenceStyle">@style/Preference.Material</item>

View File

@@ -22,6 +22,8 @@ import android.content.pm.PackageManager;
import android.icu.text.ListFormatter;
import android.text.TextUtils;
import androidx.core.text.BidiFormatter;
import com.android.settings.core.BasePreferenceController;
import com.android.settingslib.applications.AppUtils;
@@ -72,6 +74,7 @@ public class DefaultAppsPreferenceController extends BasePreferenceController {
return null;
}
final String packageName = packageNames.get(0);
return AppUtils.getApplicationLabel(mPackageManager, packageName);
return BidiFormatter.getInstance().unicodeWrap(AppUtils.getApplicationLabel(mPackageManager,
packageName));
}
}

View File

@@ -113,11 +113,9 @@ public class WirelessDebuggingFragment extends DashboardFragment
} else if (AdbManager.WIRELESS_DEBUG_STATE_CHANGED_ACTION.equals(action)) {
int status = intent.getIntExtra(AdbManager.WIRELESS_STATUS_EXTRA,
AdbManager.WIRELESS_STATUS_DISCONNECTED);
if (status == AdbManager.WIRELESS_STATUS_CONNECTED) {
int port = intent.getIntExtra(AdbManager.WIRELESS_DEBUG_PORT_EXTRA, 0);
Log.i(TAG, "Got adbwifi port=" + port);
} else {
Log.i(TAG, "adbwifi server disconnected");
if (status == AdbManager.WIRELESS_STATUS_CONNECTED
|| status == AdbManager.WIRELESS_STATUS_DISCONNECTED) {
sAdbIpAddressPreferenceController.updateState(mIpAddrPreference);
}
} else if (AdbManager.WIRELESS_DEBUG_PAIRING_RESULT_ACTION.equals(action)) {
Integer res = intent.getIntExtra(

View File

@@ -229,7 +229,11 @@ public class MediaOutputSlice implements CustomSliceable {
listBuilder.addRow(builder);
}
} else {
listBuilder.addRow(getMediaDeviceRow(device));
if (device.getState() == LocalMediaManager.MediaDeviceState.STATE_CONNECTING) {
listBuilder.addRange(getTransferringMediaDeviceRow(device));
} else {
listBuilder.addRow(getMediaDeviceRow(device));
}
}
}
@@ -279,6 +283,19 @@ public class MediaOutputSlice implements CustomSliceable {
return devices;
}
private ListBuilder.RangeBuilder getTransferringMediaDeviceRow(MediaDevice device) {
final IconCompat deviceIcon = getDeviceIconCompat(device);
final SliceAction sliceAction = SliceAction.create(getBroadcastIntent(mContext,
device.getId(), device.hashCode()), deviceIcon, ListBuilder.ICON_IMAGE,
mContext.getText(R.string.media_output_switching));
return new ListBuilder.RangeBuilder()
.setTitleItem(deviceIcon, ListBuilder.ICON_IMAGE)
.setMode(ListBuilder.RANGE_MODE_INDETERMINATE)
.setTitle(device.getName())
.setPrimaryAction(sliceAction);
}
private ListBuilder.RowBuilder getMediaDeviceRow(MediaDevice device) {
final String deviceName = device.getName();
final PendingIntent broadcastAction =
@@ -290,15 +307,11 @@ public class MediaOutputSlice implements CustomSliceable {
if (device.getDeviceType() == MediaDevice.MediaDeviceType.TYPE_BLUETOOTH_DEVICE
&& !device.isConnected()) {
final int state = device.getState();
if (state == LocalMediaManager.MediaDeviceState.STATE_CONNECTING
|| state == LocalMediaManager.MediaDeviceState.STATE_CONNECTING_FAILED) {
if (state == LocalMediaManager.MediaDeviceState.STATE_CONNECTING_FAILED) {
rowBuilder.setTitle(deviceName);
rowBuilder.setPrimaryAction(SliceAction.create(broadcastAction, deviceIcon,
ListBuilder.ICON_IMAGE, deviceName));
rowBuilder.setSubtitle(
(state == LocalMediaManager.MediaDeviceState.STATE_CONNECTING)
? mContext.getText(R.string.media_output_switching)
: mContext.getText(R.string.bluetooth_connect_failed));
rowBuilder.setSubtitle(mContext.getText(R.string.bluetooth_connect_failed));
} else {
// Append status to title only for the disconnected Bluetooth device.
final SpannableString spannableTitle = new SpannableString(
@@ -316,14 +329,8 @@ public class MediaOutputSlice implements CustomSliceable {
rowBuilder.setTitle(deviceName);
rowBuilder.setPrimaryAction(SliceAction.create(broadcastAction, deviceIcon,
ListBuilder.ICON_IMAGE, deviceName));
switch (device.getState()) {
case LocalMediaManager.MediaDeviceState.STATE_CONNECTING:
rowBuilder.setSubtitle(mContext.getText(R.string.media_output_switching));
break;
case LocalMediaManager.MediaDeviceState.STATE_CONNECTING_FAILED:
rowBuilder.setSubtitle(mContext.getText(
R.string.media_output_switch_error_text));
break;
if (device.getState() == LocalMediaManager.MediaDeviceState.STATE_CONNECTING_FAILED) {
rowBuilder.setSubtitle(mContext.getText(R.string.media_output_switch_error_text));
}
}

View File

@@ -90,7 +90,7 @@ public class AppBubbleNotificationSettings extends NotificationSettings implemen
}
for (NotificationPreferenceController controller : mControllers) {
controller.onResume(mAppRow, mChannel, mChannelGroup, null, null, mSuspendedAppsAdmin);
controller.onResume(mAppRow, null, null, null, null, mSuspendedAppsAdmin);
controller.displayPreference(getPreferenceScreen());
}
updatePreferenceStates();

View File

@@ -159,6 +159,6 @@ public class MediaOutputGroupPanel implements PanelContent, LocalMediaManager.De
@Override
public int getViewType() {
return PanelContent.VIEW_TYPE_SLIDER;
return PanelContent.VIEW_TYPE_SLIDER_LARGE_ICON;
}
}

View File

@@ -246,7 +246,7 @@ public class MediaOutputPanel implements PanelContent, LocalMediaManager.DeviceC
@Override
public int getViewType() {
return PanelContent.VIEW_TYPE_SLIDER;
return PanelContent.VIEW_TYPE_SLIDER_LARGE_ICON;
}
private final MediaController.Callback mCb = new MediaController.Callback() {

View File

@@ -31,6 +31,7 @@ import java.util.List;
public interface PanelContent extends Instrumentable {
int VIEW_TYPE_SLIDER = 1;
int VIEW_TYPE_SLIDER_LARGE_ICON = 2;
/**
* @return a icon for the title of the Panel.

View File

@@ -75,6 +75,8 @@ public class PanelSlicesAdapter
View view;
if (viewType == PanelContent.VIEW_TYPE_SLIDER) {
view = inflater.inflate(R.layout.panel_slice_slider_row, viewGroup, false);
} else if (viewType == PanelContent.VIEW_TYPE_SLIDER_LARGE_ICON) {
view = inflater.inflate(R.layout.panel_slice_slider_row_large_icon, viewGroup, false);
} else {
view = inflater.inflate(R.layout.panel_slice_row, viewGroup, false);
}

View File

@@ -39,6 +39,7 @@ import com.android.settings.Utils;
import com.android.settings.core.SubSettingLauncher;
import com.android.settingslib.RestrictedLockUtils;
import com.android.settingslib.RestrictedLockUtilsInternal;
import com.android.settingslib.RestrictedPreference;
import java.util.List;
@@ -65,10 +66,13 @@ public class UserDetailsSettings extends SettingsPreferenceFragment
private static final int DIALOG_CONFIRM_REMOVE = 1;
private static final int DIALOG_CONFIRM_ENABLE_CALLING = 2;
private static final int DIALOG_CONFIRM_ENABLE_CALLING_AND_SMS = 3;
private static final int DIALOG_SETUP_USER = 4;
private UserManager mUserManager;
private UserCapabilities mUserCaps;
@VisibleForTesting
Preference mSwitchUserPref;
RestrictedPreference mSwitchUserPref;
private SwitchPreference mPhonePref;
@VisibleForTesting
Preference mAppAndContentAccessPref;
@@ -90,6 +94,7 @@ public class UserDetailsSettings extends SettingsPreferenceFragment
final Context context = getActivity();
mUserManager = (UserManager) context.getSystemService(Context.USER_SERVICE);
mUserCaps = UserCapabilities.create(context);
addPreferencesFromResource(R.xml.user_details_settings);
initialize(context, getArguments());
@@ -106,15 +111,20 @@ public class UserDetailsSettings extends SettingsPreferenceFragment
if (preference == mRemoveUserPref) {
if (canDeleteUser()) {
showDialog(DIALOG_CONFIRM_REMOVE);
return true;
}
return true;
} else if (preference == mSwitchUserPref) {
if (canSwitchUserNow()) {
switchUser();
if (shouldShowSetupPromptDialog()) {
showDialog(DIALOG_SETUP_USER);
} else {
switchUser();
}
return true;
}
return true;
} else if (preference == mAppAndContentAccessPref) {
openAppAndContentAccessScreen(false);
return true;
}
return false;
}
@@ -139,6 +149,8 @@ public class UserDetailsSettings extends SettingsPreferenceFragment
return SettingsEnums.DIALOG_USER_ENABLE_CALLING;
case DIALOG_CONFIRM_ENABLE_CALLING_AND_SMS:
return SettingsEnums.DIALOG_USER_ENABLE_CALLING_AND_SMS;
case DIALOG_SETUP_USER:
return SettingsEnums.DIALOG_USER_SETUP;
default:
return 0;
}
@@ -160,6 +172,13 @@ public class UserDetailsSettings extends SettingsPreferenceFragment
case DIALOG_CONFIRM_ENABLE_CALLING_AND_SMS:
return UserDialogs.createEnablePhoneCallsAndSmsDialog(getActivity(),
(dialog, which) -> enableCallsAndSms(true));
case DIALOG_SETUP_USER:
return UserDialogs.createSetupUserDialog(getActivity(),
(dialog, which) -> {
if (canSwitchUserNow()) {
switchUser();
}
});
}
throw new IllegalArgumentException("Unsupported dialogId " + dialogId);
}
@@ -188,7 +207,14 @@ public class UserDetailsSettings extends SettingsPreferenceFragment
mSwitchUserPref.setTitle(
context.getString(com.android.settingslib.R.string.user_switch_to_user,
mUserInfo.name));
mSwitchUserPref.setOnPreferenceClickListener(this);
if (mUserCaps.mDisallowSwitchUser) {
mSwitchUserPref.setDisabledByAdmin(RestrictedLockUtilsInternal.getDeviceOwner(context));
} else {
mSwitchUserPref.setDisabledByAdmin(null);
mSwitchUserPref.setSelectable(true);
mSwitchUserPref.setOnPreferenceClickListener(this);
}
if (!mUserManager.isAdminUser()) { // non admin users can't remove users and allow calls
removePreference(KEY_ENABLE_TELEPHONY);
@@ -321,4 +347,16 @@ public class UserDetailsSettings extends SettingsPreferenceFragment
.setSourceMetricsCategory(getMetricsCategory())
.launch();
}
private boolean isSecondaryUser(UserInfo user) {
return UserManager.USER_TYPE_FULL_SECONDARY.equals(user.userType);
}
private boolean shouldShowSetupPromptDialog() {
// TODO: FLAG_INITIALIZED is set when a user is switched to for the first time,
// but what we would really need here is a flag that shows if the setup process was
// completed. After the user cancels the setup process, mUserInfo.isInitialized() will
// return true so there will be no setup prompt dialog shown to the user anymore.
return isSecondaryUser(mUserInfo) && !mUserInfo.isInitialized();
}
}

View File

@@ -138,4 +138,21 @@ public final class UserDialogs {
.setNegativeButton(android.R.string.cancel, null)
.create();
}
/**
* Creates a dialog to confirm that the user is ok to start setting up a new user.
*
* @param onConfirmListener Callback object for positive action
*/
public static Dialog createSetupUserDialog(Context context,
DialogInterface.OnClickListener onConfirmListener) {
return new AlertDialog.Builder(context)
.setTitle(com.android.settingslib.R.string.user_setup_dialog_title)
.setMessage(com.android.settingslib.R.string.user_setup_dialog_message)
.setPositiveButton(com.android.settingslib.R.string.user_setup_button_setup_now,
onConfirmListener)
.setNegativeButton(com.android.settingslib.R.string.user_setup_button_setup_later,
null)
.create();
}
}

View File

@@ -102,8 +102,6 @@ public class UserSettings extends SettingsPreferenceFragment
/** UserId of the user being removed */
private static final String SAVE_REMOVING_USER = "removing_user";
/** UserId of the user that was just added */
private static final String SAVE_ADDING_USER = "adding_user";
private static final String KEY_USER_LIST = "user_list";
private static final String KEY_USER_ME = "user_me";
@@ -119,8 +117,7 @@ public class UserSettings extends SettingsPreferenceFragment
private static final int DIALOG_CONFIRM_REMOVE = 1;
private static final int DIALOG_ADD_USER = 2;
private static final int DIALOG_SETUP_USER = 3;
private static final int DIALOG_SETUP_PROFILE = 4;
// Dialogs with id 3 and 4 got removed
private static final int DIALOG_USER_CANNOT_MANAGE = 5;
private static final int DIALOG_CHOOSE_USER_TYPE = 6;
private static final int DIALOG_NEED_LOCKSCREEN = 7;
@@ -130,8 +127,7 @@ public class UserSettings extends SettingsPreferenceFragment
private static final int DIALOG_USER_PROFILE_EDITOR_ADD_RESTRICTED_PROFILE = 11;
private static final int MESSAGE_UPDATE_LIST = 1;
private static final int MESSAGE_SETUP_USER = 2;
private static final int MESSAGE_CONFIG_USER = 3;
private static final int MESSAGE_USER_CREATED = 2;
private static final int USER_TYPE_USER = 1;
private static final int USER_TYPE_RESTRICTED_PROFILE = 2;
@@ -160,7 +156,6 @@ public class UserSettings extends SettingsPreferenceFragment
@VisibleForTesting
SparseArray<Bitmap> mUserIcons = new SparseArray<>();
private int mRemovingUserId = -1;
private int mAddedUserId = 0;
private boolean mAddingUser;
private String mAddingUserName;
private UserCapabilities mUserCaps;
@@ -187,12 +182,9 @@ public class UserSettings extends SettingsPreferenceFragment
case MESSAGE_UPDATE_LIST:
updateUserList();
break;
case MESSAGE_SETUP_USER:
case MESSAGE_USER_CREATED:
onUserCreated(msg.arg1);
break;
case MESSAGE_CONFIG_USER:
onManageUserClicked(msg.arg1, true);
break;
}
}
};
@@ -254,9 +246,6 @@ public class UserSettings extends SettingsPreferenceFragment
.setOnPreferenceChangeListener(mAddUserWhenLockedPreferenceController);
if (icicle != null) {
if (icicle.containsKey(SAVE_ADDING_USER)) {
mAddedUserId = icicle.getInt(SAVE_ADDING_USER);
}
if (icicle.containsKey(SAVE_REMOVING_USER)) {
mRemovingUserId = icicle.getInt(SAVE_REMOVING_USER);
}
@@ -334,7 +323,6 @@ public class UserSettings extends SettingsPreferenceFragment
public void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
mEditUserInfoController.onSaveInstanceState(outState);
outState.putInt(SAVE_ADDING_USER, mAddedUserId);
outState.putInt(SAVE_REMOVING_USER, mRemovingUserId);
}
@@ -482,37 +470,22 @@ public class UserSettings extends SettingsPreferenceFragment
}
}
private void onManageUserClicked(int userId, boolean newUser) {
private void onUserCreated(int userId) {
mAddingUser = false;
UserInfo userInfo = mUserManager.getUserInfo(userId);
if (userId == UserHandle.myUserId()) {
// Jump to owner info panel
OwnerInfoSettings.show(this);
} else {
Bundle extras = new Bundle();
extras.putInt(UserDetailsSettings.EXTRA_USER_ID, userId);
extras.putBoolean(AppRestrictionsFragment.EXTRA_NEW_USER, newUser);
new SubSettingLauncher(getContext())
.setDestination(UserDetailsSettings.class.getName())
.setArguments(extras)
.setTitleText(userInfo.name)
.setSourceMetricsCategory(getMetricsCategory())
.launch();
}
openUserDetails(userInfo, true);
}
private void onUserCreated(int userId) {
mAddedUserId = userId;
mAddingUser = false;
if (!isResumed()) {
Log.w(TAG, "Cannot show dialog after onPause");
return;
}
if (mUserManager.getUserInfo(userId).isRestricted()) {
showDialog(DIALOG_SETUP_PROFILE);
} else {
showDialog(DIALOG_SETUP_USER);
}
private void openUserDetails(UserInfo userInfo, boolean newUser) {
Bundle extras = new Bundle();
extras.putInt(UserDetailsSettings.EXTRA_USER_ID, userInfo.id);
extras.putBoolean(AppRestrictionsFragment.EXTRA_NEW_USER, newUser);
new SubSettingLauncher(getContext())
.setDestination(UserDetailsSettings.class.getName())
.setArguments(extras)
.setTitleText(userInfo.name)
.setSourceMetricsCategory(getMetricsCategory())
.launch();
}
@Override
@@ -571,37 +544,6 @@ public class UserSettings extends SettingsPreferenceFragment
.create();
return dlg;
}
case DIALOG_SETUP_USER: {
Dialog dlg = new AlertDialog.Builder(context)
.setTitle(com.android.settingslib.R.string.user_setup_dialog_title)
.setMessage(com.android.settingslib.R.string.user_setup_dialog_message)
.setPositiveButton(
com.android.settingslib.R.string.user_setup_button_setup_now,
new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int which) {
switchUserNow(mAddedUserId);
}
})
.setNegativeButton(
com.android.settingslib.R.string.user_setup_button_setup_later,
null)
.create();
return dlg;
}
case DIALOG_SETUP_PROFILE: {
Dialog dlg = new AlertDialog.Builder(context)
.setMessage(
com.android.settingslib.R.string.user_setup_profile_dialog_message)
.setPositiveButton(android.R.string.ok,
new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int which) {
switchUserNow(mAddedUserId);
}
})
.setNegativeButton(android.R.string.cancel, null)
.create();
return dlg;
}
case DIALOG_CHOOSE_USER_TYPE: {
List<HashMap<String, String>> data = new ArrayList<HashMap<String, String>>();
HashMap<String, String> addUserItem = new HashMap<String, String>();
@@ -764,10 +706,6 @@ public class UserSettings extends SettingsPreferenceFragment
return SettingsEnums.DIALOG_USER_CANNOT_MANAGE;
case DIALOG_ADD_USER:
return SettingsEnums.DIALOG_USER_ADD;
case DIALOG_SETUP_USER:
return SettingsEnums.DIALOG_USER_SETUP;
case DIALOG_SETUP_PROFILE:
return SettingsEnums.DIALOG_USER_SETUP_PROFILE;
case DIALOG_CHOOSE_USER_TYPE:
return SettingsEnums.DIALOG_USER_CHOOSE_TYPE;
case DIALOG_NEED_LOCKSCREEN:
@@ -853,16 +791,11 @@ public class UserSettings extends SettingsPreferenceFragment
if (userType == USER_TYPE_USER) {
mHandler.sendEmptyMessage(MESSAGE_UPDATE_LIST);
// Skip setting up user which results in user switching when the
// restriction is set.
if (!mUserCaps.mDisallowSwitchUser) {
mHandler.sendMessage(mHandler.obtainMessage(
MESSAGE_SETUP_USER, user.id, user.serialNumber));
}
} else {
mHandler.sendMessage(mHandler.obtainMessage(
MESSAGE_CONFIG_USER, user.id, user.serialNumber));
}
mHandler.sendMessage(mHandler.obtainMessage(
MESSAGE_USER_CREATED, user.id, user.serialNumber));
mPendingUserIcon = null;
mPendingUserName = null;
}
@@ -870,18 +803,6 @@ public class UserSettings extends SettingsPreferenceFragment
});
}
private void switchUserNow(int userId) {
if (!canSwitchUserNow()) {
return;
}
try {
ActivityManager.getService().switchUser(userId);
} catch (RemoteException re) {
Log.e(TAG, "Error while switching to other user.");
}
}
/**
* Erase the current user (guest) and switch to another user.
*/
@@ -1125,21 +1046,14 @@ public class UserSettings extends SettingsPreferenceFragment
if (pref == mMePreference) {
if (isCurrentUserGuest()) {
showDialog(DIALOG_CONFIRM_EXIT_GUEST);
return true;
}
showDialog(DIALOG_USER_PROFILE_EDITOR);
} else if (pref instanceof UserPreference) {
int userId = ((UserPreference) pref).getUserId();
// Get the latest status of the user
UserInfo user = mUserManager.getUserInfo(userId);
if (!user.isInitialized() && isSecondaryUser(user)) {
// for uninitialized secondary users we should show a prompt dialog before
// starting the setup
mHandler.sendMessage(mHandler.obtainMessage(
MESSAGE_SETUP_USER, user.id, user.serialNumber));
} else {
onManageUserClicked(userId, false);
showDialog(DIALOG_USER_PROFILE_EDITOR);
}
return true;
} else if (pref instanceof UserPreference) {
UserInfo userInfo = mUserManager.getUserInfo(((UserPreference) pref).getUserId());
openUserDetails(userInfo, false);
return true;
} else if (pref == mAddUser) {
// If we allow both types, show a picker, otherwise directly go to
// flow for full user.
@@ -1148,10 +1062,12 @@ public class UserSettings extends SettingsPreferenceFragment
} else {
onAddUserClicked(USER_TYPE_USER);
}
return true;
} else if (pref == mAddGuest) {
UserInfo guest = mUserManager.createGuest(
getContext(), getString(com.android.settingslib.R.string.user_guest));
switchUserNow(guest.id);
openUserDetails(guest, true);
return true;
}
return false;
}
@@ -1265,8 +1181,4 @@ public class UserSettings extends SettingsPreferenceFragment
return niks;
}
};
private boolean isSecondaryUser(UserInfo user) {
return UserManager.USER_TYPE_FULL_SECONDARY.equals(user.userType);
}
}

View File

@@ -72,4 +72,9 @@ public class MediaOutputGroupPanelTest {
public void getSeeMoreIntent_isNull() {
assertThat(mPanel.getSeeMoreIntent()).isNull();
}
@Test
public void getViewType_checkType() {
assertThat(mPanel.getViewType()).isEqualTo(PanelContent.VIEW_TYPE_SLIDER_LARGE_ICON);
}
}

View File

@@ -312,4 +312,9 @@ public class MediaOutputPanelTest {
verify(mCallback).forceClose();
}
@Test
public void getViewType_checkType() {
assertThat(mPanel.getViewType()).isEqualTo(PanelContent.VIEW_TYPE_SLIDER_LARGE_ICON);
}
}

View File

@@ -17,6 +17,7 @@
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_LARGE_ICON;
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;
@@ -206,6 +207,19 @@ public class PanelSlicesAdapterTest {
assertThat(intArgumentCaptor.getValue()).isEqualTo(R.layout.panel_slice_slider_row);
}
@Test
public void onCreateViewHolder_viewTypeSliderLargeIcon_verifyLayout() {
final PanelSlicesAdapter adapter = new PanelSlicesAdapter(mPanelFragment, mData, 0);
final ViewGroup view = new FrameLayout(mContext);
final ArgumentCaptor<Integer> intArgumentCaptor = ArgumentCaptor.forClass(Integer.class);
adapter.onCreateViewHolder(view, VIEW_TYPE_SLIDER_LARGE_ICON);
verify(sLayoutInflater).inflate(intArgumentCaptor.capture(), eq(view), eq(false));
assertThat(intArgumentCaptor.getValue()).isEqualTo(
R.layout.panel_slice_slider_row_large_icon);
}
@Test
public void onCreateViewHolder_viewTypeDefault_verifyLayout() {
final PanelSlicesAdapter adapter =

View File

@@ -70,4 +70,9 @@ public class VolumePanelTest {
public void getSeeMoreIntent_notNull() {
assertThat(mPanel.getSeeMoreIntent()).isNotNull();
}
@Test
public void getViewType_checkType() {
assertThat(mPanel.getViewType()).isEqualTo(PanelContent.VIEW_TYPE_SLIDER);
}
}

View File

@@ -34,6 +34,7 @@ import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.verifyNoMoreInteractions;
import static org.robolectric.Shadows.shadowOf;
import android.app.admin.DevicePolicyManager;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
@@ -53,6 +54,8 @@ import com.android.settings.SettingsActivity;
import com.android.settings.SubSettings;
import com.android.settings.testutils.shadow.ShadowDevicePolicyManager;
import com.android.settings.testutils.shadow.ShadowUserManager;
import com.android.settingslib.RestrictedLockUtils;
import com.android.settingslib.RestrictedPreference;
import org.junit.After;
import org.junit.Before;
@@ -91,7 +94,7 @@ public class UserDetailsSettingsTest {
private ShadowUserManager mUserManager;
@Mock
private Preference mSwitchUserPref;
private RestrictedPreference mSwitchUserPref;
@Mock
private SwitchPreference mPhonePref;
@Mock
@@ -101,6 +104,7 @@ public class UserDetailsSettingsTest {
private FragmentActivity mActivity;
private Context mContext;
private UserCapabilities mUserCapabilities;
private UserDetailsSettings mFragment;
private Bundle mArguments;
private UserInfo mUserInfo;
@@ -111,6 +115,8 @@ public class UserDetailsSettingsTest {
mActivity = spy(ActivityController.of(new FragmentActivity()).get());
mContext = spy(RuntimeEnvironment.application);
mUserCapabilities = UserCapabilities.create(mContext);
mUserCapabilities.mUserSwitcherEnabled = true;
mFragment = spy(new UserDetailsSettings());
mArguments = new Bundle();
@@ -121,6 +127,7 @@ public class UserDetailsSettingsTest {
doReturn(mTelephonyManager).when(mActivity).getSystemService(Context.TELEPHONY_SERVICE);
ReflectionHelpers.setField(mFragment, "mUserManager", userManager);
ReflectionHelpers.setField(mFragment, "mUserCaps", mUserCapabilities);
doReturn(mActivity).when(mFragment).getActivity();
doReturn(mActivity).when(mFragment).getContext();
@@ -426,6 +433,33 @@ public class UserDetailsSettingsTest {
verify(mPhonePref).setChecked(false);
}
@Test
public void initialize_switchUserDisallowed_shouldSetAdminDisabledOnSwitchPreference() {
setupSelectedUser();
mUserCapabilities.mDisallowSwitchUser = true;
DevicePolicyManager devicePolicyManager = mock(DevicePolicyManager.class);
doReturn(devicePolicyManager).when(mActivity)
.getSystemService(Context.DEVICE_POLICY_SERVICE);
doReturn(mock(ComponentName.class)).when(devicePolicyManager)
.getDeviceOwnerComponentOnAnyUser();
mFragment.initialize(mActivity, mArguments);
verify(mSwitchUserPref).setDisabledByAdmin(any(RestrictedLockUtils.EnforcedAdmin.class));
}
@Test
public void initialize_switchUserAllowed_shouldSetSwitchPreferenceEnabled() {
setupSelectedUser();
mUserCapabilities.mDisallowSwitchUser = false;
mFragment.initialize(mActivity, mArguments);
verify(mSwitchUserPref).setDisabledByAdmin(null);
verify(mSwitchUserPref).setSelectable(true);
verify(mSwitchUserPref).setOnPreferenceClickListener(mFragment);
}
@Test
public void onPreferenceClick_switchClicked_canSwitch_shouldSwitch() {
setupSelectedUser();

View File

@@ -33,13 +33,16 @@ import static org.mockito.Mockito.never;
import static org.mockito.Mockito.spy;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
import static org.robolectric.Shadows.shadowOf;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.SharedPreferences;
import android.content.pm.UserInfo;
import android.graphics.Bitmap;
import android.graphics.drawable.Drawable;
import android.os.Bundle;
import android.os.UserHandle;
import android.os.UserManager;
import android.provider.Settings;
@@ -53,6 +56,8 @@ import androidx.preference.PreferenceCategory;
import androidx.preference.PreferenceManager;
import androidx.preference.PreferenceScreen;
import com.android.settings.SettingsActivity;
import com.android.settings.SubSettings;
import com.android.settings.testutils.shadow.ShadowDevicePolicyManager;
import com.android.settings.testutils.shadow.ShadowUserManager;
import com.android.settingslib.RestrictedLockUtils;
@@ -70,6 +75,7 @@ import org.robolectric.RobolectricTestRunner;
import org.robolectric.RuntimeEnvironment;
import org.robolectric.android.controller.ActivityController;
import org.robolectric.annotation.Config;
import org.robolectric.shadows.ShadowIntent;
import org.robolectric.util.ReflectionHelpers;
import java.util.Arrays;
@@ -589,6 +595,30 @@ public class UserSettingsTest {
verify(mUserManager, times(2)).getUsers(true);
}
@Test
public void onPreferenceClick_addGuestClicked_createGuestAndOpenDetails() {
UserInfo createdGuest = getGuest(false);
removeFlag(createdGuest, UserInfo.FLAG_INITIALIZED);
doReturn(createdGuest).when(mUserManager).createGuest(mActivity, "Guest");
doReturn(mActivity).when(mFragment).getContext();
mFragment.onPreferenceClick(mAddGuestPreference);
verify(mUserManager).createGuest(mActivity, "Guest");
Intent startedIntent = shadowOf(mActivity).getNextStartedActivity();
ShadowIntent shadowIntent = shadowOf(startedIntent);
assertThat(shadowIntent.getIntentClass()).isEqualTo(SubSettings.class);
assertThat(startedIntent.getStringExtra(SettingsActivity.EXTRA_SHOW_FRAGMENT))
.isEqualTo(UserDetailsSettings.class.getName());
Bundle arguments = startedIntent.getBundleExtra(
SettingsActivity.EXTRA_SHOW_FRAGMENT_ARGUMENTS);
assertThat(arguments).isNotNull();
assertThat(arguments.getInt(UserDetailsSettings.EXTRA_USER_ID, 0))
.isEqualTo(createdGuest.id);
assertThat(arguments.getBoolean(AppRestrictionsFragment.EXTRA_NEW_USER, false))
.isEqualTo(true);
}
@Test
public void getRealUsersCount_onlyAdmin_shouldCount() {
givenUsers(getAdminUser(true));

View File

@@ -0,0 +1,72 @@
/*
* 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.notification;
import static androidx.test.espresso.Espresso.onView;
import static androidx.test.espresso.assertion.ViewAssertions.matches;
import static androidx.test.espresso.matcher.ViewMatchers.isDisplayed;
import static androidx.test.espresso.matcher.ViewMatchers.withText;
import static org.hamcrest.Matchers.allOf;
import android.app.Instrumentation;
import android.content.Context;
import android.content.Intent;
import android.provider.Settings;
import android.support.test.uiautomator.UiDevice;
import androidx.test.InstrumentationRegistry;
import androidx.test.filters.SmallTest;
import androidx.test.runner.AndroidJUnit4;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
@RunWith(AndroidJUnit4.class)
@SmallTest
public class AppBubbleNotificationSettingsTest {
private static final String WM_DISMISS_KEYGUARD_COMMAND = "wm dismiss-keyguard";
private UiDevice mUiDevice;
private Context mTargetContext;
private Instrumentation mInstrumentation;
@Before
public void setUp() throws Exception {
mInstrumentation = InstrumentationRegistry.getInstrumentation();
mTargetContext = mInstrumentation.getTargetContext();
mUiDevice = UiDevice.getInstance(InstrumentationRegistry.getInstrumentation());
mUiDevice.wakeUp();
mUiDevice.executeShellCommand(WM_DISMISS_KEYGUARD_COMMAND);
}
@Test
public void launchBubbleNotificationSetting_shouldNotCrash() {
final Intent intent = new Intent(Settings.ACTION_APP_NOTIFICATION_BUBBLE_SETTINGS)
.putExtra(Settings.EXTRA_APP_PACKAGE, mTargetContext.getPackageName())
.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
mInstrumentation.startActivitySync(intent);
CharSequence name = mTargetContext.getApplicationInfo().loadLabel(
mTargetContext.getPackageManager());
onView(allOf(withText(name.toString()))).check(matches(isDisplayed()));
}
}