Snap for 6583806 from 1d02b72826 to mainline-release
Change-Id: I87944fab9648e949a113b10d19ed0c9598a2afe8
This commit is contained in:
31
res/layout/panel_slice_slider_row_large_icon.xml
Normal file
31
res/layout/panel_slice_slider_row_large_icon.xml
Normal 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>
|
||||
19
res/values-mcc222/strings.xml
Normal file
19
res/values-mcc222/strings.xml
Normal 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>
|
||||
@@ -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">
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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(
|
||||
|
||||
@@ -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));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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() {
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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 =
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -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));
|
||||
|
||||
@@ -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()));
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user