Improve multi user functionality for restricted users
- Restricted users can change their name
- Improved App&Content access screen
- Remove "Turn on phone calls" from restricted user detail page
Doc: http://shortn/_Prb3SJ3xJ3
Bug: 142798722
Test: Run robo tests with this command:
make -j64 RunSettingsRoboTests
Change-Id: I2aadf32aef52ba5ad0db7aa0cd83bac9d9941589
(cherry picked from commit f4759e00d5
)
This commit is contained in:
committed by
András Klöczl
parent
ff35a3e641
commit
106431e525
@@ -25,7 +25,6 @@
|
||||
android:layout_width="56dip"
|
||||
android:layout_height="56dip"
|
||||
android:layout_gravity="bottom"
|
||||
android:layout_marginEnd="6dp"
|
||||
android:contentDescription="@string/user_image_photo_selector"
|
||||
android:background="@*android:drawable/spinner_background_holo_dark"
|
||||
android:scaleType="fitCenter"/>
|
||||
|
@@ -1,129 +0,0 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!-- Copyright (C) 2013 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"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:minHeight="?android:attr/listPreferredItemHeight"
|
||||
android:gravity="center_vertical"
|
||||
android:orientation="vertical"
|
||||
android:focusable="true"
|
||||
android:clickable="true" >
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:layout_weight="1"
|
||||
android:id="@+id/app_restrictions_pref"
|
||||
android:gravity="center_vertical"
|
||||
android:paddingStart="?android:attr/listPreferredItemPaddingStart"
|
||||
android:paddingEnd="?android:attr/listPreferredItemPaddingEnd"
|
||||
android:background="?android:attr/selectableItemBackground" >
|
||||
<LinearLayout
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="match_parent"
|
||||
android:gravity="center"
|
||||
android:minWidth="@*android:dimen/preference_icon_minWidth"
|
||||
android:orientation="horizontal">
|
||||
<ImageView
|
||||
android:id="@android:id/icon"
|
||||
android:layout_width="48dp"
|
||||
android:layout_height="48dp"
|
||||
android:layout_gravity="center"
|
||||
android:minWidth="48dp"
|
||||
android:scaleType="centerInside"
|
||||
android:layout_marginEnd="@*android:dimen/preference_item_padding_inner"/>
|
||||
</LinearLayout>
|
||||
<RelativeLayout
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginEnd="6dip"
|
||||
android:layout_marginTop="6dip"
|
||||
android:layout_marginBottom="6dip"
|
||||
android:layout_weight="1">
|
||||
<TextView
|
||||
android:id="@android:id/title"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:singleLine="true"
|
||||
tools:text="Richard"
|
||||
android:textAppearance="?android:attr/textAppearanceMedium"
|
||||
android:ellipsize="marquee"
|
||||
android:fadingEdge="horizontal"/>
|
||||
<TextView
|
||||
android:id="@android:id/summary"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_below="@android:id/title"
|
||||
android:layout_alignStart="@android:id/title"
|
||||
android:paddingBottom="3dip"
|
||||
android:textAppearance="?android:attr/textAppearanceSmall"
|
||||
android:textSize="13sp"
|
||||
android:textColor="?android:attr/textColorSecondary"
|
||||
android:focusable="false"
|
||||
android:text="@string/user_summary_restricted_profile"
|
||||
android:maxLines="4" />
|
||||
</RelativeLayout>
|
||||
<ImageView
|
||||
android:id="@+id/delete"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="fill_parent"
|
||||
android:paddingStart="16dip"
|
||||
android:paddingEnd="16dip"
|
||||
android:src="@drawable/ic_delete"
|
||||
android:contentDescription="@string/user_delete_user_description"
|
||||
android:layout_gravity="center"
|
||||
android:background="?android:attr/selectableItemBackground" />
|
||||
</LinearLayout>
|
||||
|
||||
<LinearLayout
|
||||
android:id="@+id/switch_pref"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:gravity="center_vertical"
|
||||
android:visibility="gone"
|
||||
tools:visibility="visible"
|
||||
android:paddingStart="?android:attr/listPreferredItemPaddingStart"
|
||||
android:paddingEnd="?android:attr/listPreferredItemPaddingEnd"
|
||||
android:background="?android:attr/selectableItemBackground" >
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/switchIcon"
|
||||
android:layout_width="48dp"
|
||||
android:layout_height="48dp"
|
||||
android:layout_gravity="center"
|
||||
android:src="@drawable/ic_swap"
|
||||
android:minWidth="48dp"
|
||||
android:scaleType="centerInside"
|
||||
android:layout_marginEnd="@*android:dimen/preference_item_padding_inner"/>
|
||||
|
||||
<TextView
|
||||
android:id="@+id/switchTitle"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:singleLine="true"
|
||||
tools:text="Switch to Richard"
|
||||
android:textAppearance="?android:attr/textAppearanceMedium"
|
||||
android:ellipsize="marquee"
|
||||
android:fadingEdge="horizontal"/>
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
<View android:layout_width="match_parent"
|
||||
android:layout_height="2dp"
|
||||
android:background="@color/divider_color" />
|
||||
</LinearLayout>
|
@@ -25,6 +25,10 @@
|
||||
android:key="enable_calling"
|
||||
android:icon="@drawable/ic_phone"
|
||||
android:title="@string/user_enable_calling_sms" />
|
||||
<com.android.settingslib.RestrictedPreference
|
||||
android:key="app_and_content_access"
|
||||
android:icon="@drawable/ic_lock_closed"
|
||||
android:title="@string/user_restrictions_title" />
|
||||
<com.android.settingslib.RestrictedPreference
|
||||
android:key="remove_user"
|
||||
android:icon="@drawable/ic_delete"
|
||||
|
@@ -30,7 +30,6 @@ import androidx.fragment.app.FragmentActivity;
|
||||
import androidx.loader.app.LoaderManager;
|
||||
import androidx.loader.content.Loader;
|
||||
|
||||
import com.android.settings.users.RestrictedProfileSettings;
|
||||
import com.android.settingslib.license.LicenseHtmlLoaderCompat;
|
||||
|
||||
import java.io.File;
|
||||
@@ -78,7 +77,7 @@ public class SettingsLicenseActivity extends FragmentActivity implements
|
||||
|
||||
@VisibleForTesting
|
||||
Uri getUriFromGeneratedHtmlFile(File generatedHtmlFile) {
|
||||
return FileProvider.getUriForFile(this, RestrictedProfileSettings.FILE_PROVIDER_AUTHORITY,
|
||||
return FileProvider.getUriForFile(this, Utils.FILE_PROVIDER_AUTHORITY,
|
||||
generatedHtmlFile);
|
||||
}
|
||||
|
||||
|
@@ -116,6 +116,8 @@ public final class Utils extends com.android.settingslib.Utils {
|
||||
|
||||
private static final String TAG = "Settings";
|
||||
|
||||
public static final String FILE_PROVIDER_AUTHORITY = "com.android.settings.files";
|
||||
|
||||
/**
|
||||
* Set the preference's title to the matching activity's label.
|
||||
*/
|
||||
|
@@ -97,15 +97,8 @@ public class AppRestrictionsFragment extends SettingsPreferenceFragment implemen
|
||||
/** Key for extra passed in from calling fragment to indicate if this is a newly created user */
|
||||
public static final String EXTRA_NEW_USER = "new_user";
|
||||
|
||||
/**
|
||||
* Key for extra passed in from calling fragment to indicate if
|
||||
* switch to user should be shown
|
||||
*/
|
||||
public static final String EXTRA_SHOW_SWITCH_USER = "enable_switch";
|
||||
|
||||
private boolean mFirstTime = true;
|
||||
private boolean mNewUser;
|
||||
protected boolean mShowSwitchUser;
|
||||
private boolean mAppListChanged;
|
||||
protected boolean mRestrictedProfile;
|
||||
|
||||
@@ -216,6 +209,12 @@ public class AppRestrictionsFragment extends SettingsPreferenceFragment implemen
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onCreate(Bundle icicle) {
|
||||
super.onCreate(icicle);
|
||||
init(icicle);
|
||||
}
|
||||
|
||||
protected void init(Bundle icicle) {
|
||||
if (icicle != null) {
|
||||
mUser = new UserHandle(icicle.getInt(EXTRA_USER_ID));
|
||||
@@ -226,7 +225,6 @@ public class AppRestrictionsFragment extends SettingsPreferenceFragment implemen
|
||||
mUser = new UserHandle(args.getInt(EXTRA_USER_ID));
|
||||
}
|
||||
mNewUser = args.getBoolean(EXTRA_NEW_USER, false);
|
||||
mShowSwitchUser = args.getBoolean(EXTRA_SHOW_SWITCH_USER, false);
|
||||
}
|
||||
}
|
||||
|
||||
|
@@ -18,8 +18,10 @@ package com.android.settings.users;
|
||||
|
||||
import android.app.Activity;
|
||||
import android.app.Dialog;
|
||||
import android.content.Context;
|
||||
import android.content.DialogInterface;
|
||||
import android.content.Intent;
|
||||
import android.content.pm.UserInfo;
|
||||
import android.graphics.Bitmap;
|
||||
import android.graphics.drawable.Drawable;
|
||||
import android.os.Bundle;
|
||||
@@ -77,7 +79,9 @@ public class EditUserInfoController {
|
||||
}
|
||||
|
||||
public void clear() {
|
||||
if (mEditUserPhotoController != null) {
|
||||
mEditUserPhotoController.removeNewUserPhotoBitmapFile();
|
||||
}
|
||||
mEditUserInfoDialog = null;
|
||||
mSavedPhoto = null;
|
||||
}
|
||||
@@ -116,7 +120,7 @@ public class EditUserInfoController {
|
||||
public void onActivityResult(int requestCode, int resultCode, Intent data) {
|
||||
mWaitingForActivityResult = false;
|
||||
|
||||
if (mEditUserInfoDialog != null) {
|
||||
if (mEditUserPhotoController != null && mEditUserInfoDialog != null) {
|
||||
mEditUserPhotoController.onActivityResult(requestCode, resultCode, data);
|
||||
}
|
||||
}
|
||||
@@ -137,6 +141,14 @@ public class EditUserInfoController {
|
||||
userNameView.setText(currentUserName);
|
||||
|
||||
final ImageView userPhotoView = (ImageView) content.findViewById(R.id.user_photo);
|
||||
|
||||
boolean canChangePhoto = mUserManager != null &&
|
||||
canChangePhoto(activity, mUserManager.getUserInfo(user.getIdentifier()));
|
||||
if (!canChangePhoto) {
|
||||
// some users can't change their photos so we need to remove suggestive
|
||||
// background from the photoView
|
||||
userPhotoView.setBackground(null);
|
||||
}
|
||||
Drawable drawable = null;
|
||||
if (mSavedPhoto != null) {
|
||||
drawable = CircleFramedDrawable.getInstance(activity, mSavedPhoto);
|
||||
@@ -144,7 +156,10 @@ public class EditUserInfoController {
|
||||
drawable = currentUserIcon;
|
||||
}
|
||||
userPhotoView.setImageDrawable(drawable);
|
||||
mEditUserPhotoController = createEditUserPhotoController(fragment, userPhotoView, drawable);
|
||||
if (canChangePhoto) {
|
||||
mEditUserPhotoController =
|
||||
createEditUserPhotoController(fragment, userPhotoView, drawable);
|
||||
}
|
||||
mEditUserInfoDialog = new AlertDialog.Builder(activity)
|
||||
.setTitle(title)
|
||||
.setView(content)
|
||||
@@ -165,14 +180,15 @@ public class EditUserInfoController {
|
||||
}
|
||||
}
|
||||
// Update the photo if changed.
|
||||
Drawable drawable = mEditUserPhotoController.getNewUserPhotoDrawable();
|
||||
if (mEditUserPhotoController != null) {
|
||||
Drawable drawable =
|
||||
mEditUserPhotoController.getNewUserPhotoDrawable();
|
||||
if (drawable != null && !drawable.equals(currentUserIcon)) {
|
||||
if (callback != null) {
|
||||
callback.onPhotoChanged(mUser, drawable);
|
||||
}
|
||||
}
|
||||
fragment.getActivity().removeDialog(
|
||||
RestrictedProfileSettings.DIALOG_ID_EDIT_USER_INFO);
|
||||
}
|
||||
}
|
||||
clear();
|
||||
if (completeCallback != null) {
|
||||
@@ -207,6 +223,13 @@ public class EditUserInfoController {
|
||||
return mEditUserInfoDialog;
|
||||
}
|
||||
|
||||
@VisibleForTesting
|
||||
boolean canChangePhoto(Context context, UserInfo user) {
|
||||
return PhotoCapabilityUtils.canCropPhoto(context) &&
|
||||
(PhotoCapabilityUtils.canChoosePhoto(context)
|
||||
|| PhotoCapabilityUtils.canTakePhoto(context));
|
||||
}
|
||||
|
||||
@VisibleForTesting
|
||||
EditUserPhotoController createEditUserPhotoController(Fragment fragment,
|
||||
ImageView userPhotoView, Drawable drawable) {
|
||||
|
@@ -21,7 +21,6 @@ import android.content.ClipData;
|
||||
import android.content.ContentResolver;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.content.pm.PackageManager;
|
||||
import android.database.Cursor;
|
||||
import android.graphics.Bitmap;
|
||||
import android.graphics.Bitmap.Config;
|
||||
@@ -52,6 +51,7 @@ import androidx.core.content.FileProvider;
|
||||
import androidx.fragment.app.Fragment;
|
||||
|
||||
import com.android.settings.R;
|
||||
import com.android.settings.Utils;
|
||||
import com.android.settingslib.RestrictedLockUtils;
|
||||
import com.android.settingslib.RestrictedLockUtilsInternal;
|
||||
import com.android.settingslib.drawable.CircleFramedDrawable;
|
||||
@@ -141,14 +141,14 @@ public class EditUserPhotoController {
|
||||
}
|
||||
|
||||
private void showUpdatePhotoPopup() {
|
||||
final boolean canTakePhoto = canTakePhoto();
|
||||
final boolean canChoosePhoto = canChoosePhoto();
|
||||
final Context context = mImageView.getContext();
|
||||
final boolean canTakePhoto = PhotoCapabilityUtils.canTakePhoto(context);
|
||||
final boolean canChoosePhoto = PhotoCapabilityUtils.canChoosePhoto(context);
|
||||
|
||||
if (!canTakePhoto && !canChoosePhoto) {
|
||||
return;
|
||||
}
|
||||
|
||||
final Context context = mImageView.getContext();
|
||||
final List<EditUserPhotoController.RestrictedMenuItem> items = new ArrayList<>();
|
||||
|
||||
if (canTakePhoto) {
|
||||
@@ -200,19 +200,6 @@ public class EditUserPhotoController {
|
||||
listPopupWindow.show();
|
||||
}
|
||||
|
||||
private boolean canTakePhoto() {
|
||||
return mImageView.getContext().getPackageManager().queryIntentActivities(
|
||||
new Intent(MediaStore.ACTION_IMAGE_CAPTURE),
|
||||
PackageManager.MATCH_DEFAULT_ONLY).size() > 0;
|
||||
}
|
||||
|
||||
private boolean canChoosePhoto() {
|
||||
Intent intent = new Intent(Intent.ACTION_GET_CONTENT);
|
||||
intent.setType("image/*");
|
||||
return mImageView.getContext().getPackageManager().queryIntentActivities(
|
||||
intent, 0).size() > 0;
|
||||
}
|
||||
|
||||
private void takePhoto() {
|
||||
Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
|
||||
appendOutputExtra(intent, mTakePictureUri);
|
||||
@@ -369,8 +356,7 @@ public class EditUserPhotoController {
|
||||
if (purge) {
|
||||
fullPath.delete();
|
||||
}
|
||||
return FileProvider.getUriForFile(context,
|
||||
RestrictedProfileSettings.FILE_PROVIDER_AUTHORITY, fullPath);
|
||||
return FileProvider.getUriForFile(context, Utils.FILE_PROVIDER_AUTHORITY, fullPath);
|
||||
}
|
||||
|
||||
File saveNewUserPhotoBitmap() {
|
||||
|
56
src/com/android/settings/users/PhotoCapabilityUtils.java
Normal file
56
src/com/android/settings/users/PhotoCapabilityUtils.java
Normal file
@@ -0,0 +1,56 @@
|
||||
/*
|
||||
* 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.users;
|
||||
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.content.pm.PackageManager;
|
||||
import android.provider.MediaStore;
|
||||
|
||||
class PhotoCapabilityUtils {
|
||||
|
||||
/**
|
||||
* Check if the current user can perform any activity for
|
||||
* android.media.action.IMAGE_CAPTURE action.
|
||||
*/
|
||||
static boolean canTakePhoto(Context context) {
|
||||
return context.getPackageManager().queryIntentActivities(
|
||||
new Intent(MediaStore.ACTION_IMAGE_CAPTURE),
|
||||
PackageManager.MATCH_DEFAULT_ONLY).size() > 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if the current user can perform any activity for
|
||||
* android.intent.action.GET_CONTENT action for images.
|
||||
*/
|
||||
static boolean canChoosePhoto(Context context) {
|
||||
Intent intent = new Intent(Intent.ACTION_GET_CONTENT);
|
||||
intent.setType("image/*");
|
||||
return context.getPackageManager().queryIntentActivities(intent, 0).size() > 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if the current user can perform any activity for
|
||||
* com.android.camera.action.CROP action for images.
|
||||
*/
|
||||
static boolean canCropPhoto(Context context) {
|
||||
Intent intent = new Intent("com.android.camera.action.CROP");
|
||||
intent.setType("image/*");
|
||||
return context.getPackageManager().queryIntentActivities(intent, 0).size() > 0;
|
||||
}
|
||||
|
||||
}
|
@@ -1,208 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2013 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.users;
|
||||
|
||||
import android.app.ActivityManager;
|
||||
import android.app.Dialog;
|
||||
import android.app.settings.SettingsEnums;
|
||||
import android.content.DialogInterface;
|
||||
import android.content.Intent;
|
||||
import android.content.pm.UserInfo;
|
||||
import android.graphics.drawable.Drawable;
|
||||
import android.os.Bundle;
|
||||
import android.os.RemoteException;
|
||||
import android.os.UserHandle;
|
||||
import android.os.UserManager;
|
||||
import android.util.Log;
|
||||
import android.view.View;
|
||||
import android.widget.ImageView;
|
||||
import android.widget.TextView;
|
||||
|
||||
import com.android.internal.util.UserIcons;
|
||||
import com.android.settings.R;
|
||||
import com.android.settings.Utils;
|
||||
import com.android.settingslib.utils.ThreadUtils;
|
||||
|
||||
public class RestrictedProfileSettings extends AppRestrictionsFragment
|
||||
implements EditUserInfoController.OnContentChangedCallback {
|
||||
|
||||
private static final String TAG = RestrictedProfileSettings.class.getSimpleName();
|
||||
public static final String FILE_PROVIDER_AUTHORITY = "com.android.settings.files";
|
||||
static final int DIALOG_ID_EDIT_USER_INFO = 1;
|
||||
private static final int DIALOG_CONFIRM_REMOVE = 2;
|
||||
|
||||
private View mHeaderView;
|
||||
private ImageView mUserIconView;
|
||||
private TextView mUserNameView;
|
||||
private ImageView mDeleteButton;
|
||||
private View mSwitchUserView;
|
||||
private TextView mSwitchTitle;
|
||||
|
||||
private EditUserInfoController mEditUserInfoController =
|
||||
new EditUserInfoController();
|
||||
|
||||
@Override
|
||||
public void onCreate(Bundle icicle) {
|
||||
super.onCreate(icicle);
|
||||
|
||||
if (icicle != null) {
|
||||
mEditUserInfoController.onRestoreInstanceState(icicle);
|
||||
}
|
||||
|
||||
init(icicle);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onActivityCreated(Bundle savedInstanceState) {
|
||||
mHeaderView = setPinnedHeaderView(R.layout.user_info_header);
|
||||
mHeaderView.setOnClickListener(this);
|
||||
mUserIconView = (ImageView) mHeaderView.findViewById(android.R.id.icon);
|
||||
mUserNameView = (TextView) mHeaderView.findViewById(android.R.id.title);
|
||||
mDeleteButton = (ImageView) mHeaderView.findViewById(R.id.delete);
|
||||
mDeleteButton.setOnClickListener(this);
|
||||
|
||||
mSwitchTitle = mHeaderView.findViewById(R.id.switchTitle);
|
||||
mSwitchUserView = mHeaderView.findViewById(R.id.switch_pref);
|
||||
mSwitchUserView.setOnClickListener(v -> switchUser());
|
||||
|
||||
// This is going to bind the preferences.
|
||||
super.onActivityCreated(savedInstanceState);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onSaveInstanceState(Bundle outState) {
|
||||
super.onSaveInstanceState(outState);
|
||||
mEditUserInfoController.onSaveInstanceState(outState);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onResume() {
|
||||
super.onResume();
|
||||
// Check if user still exists
|
||||
UserInfo info = Utils.getExistingUser(mUserManager, mUser);
|
||||
if (info == null) {
|
||||
finishFragment();
|
||||
} else {
|
||||
((TextView) mHeaderView.findViewById(android.R.id.title)).setText(info.name);
|
||||
((ImageView) mHeaderView.findViewById(android.R.id.icon)).setImageDrawable(
|
||||
com.android.settingslib.Utils.getUserIcon(getActivity(), mUserManager, info));
|
||||
|
||||
boolean canSwitchUser =
|
||||
mUserManager.getUserSwitchability() == UserManager.SWITCHABILITY_STATUS_OK;
|
||||
if (mShowSwitchUser && canSwitchUser) {
|
||||
mSwitchUserView.setVisibility(View.VISIBLE);
|
||||
mSwitchTitle.setText(getString(com.android.settingslib.R.string.user_switch_to_user,
|
||||
info.name));
|
||||
} else {
|
||||
mSwitchUserView.setVisibility(View.GONE);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void startActivityForResult(Intent intent, int requestCode) {
|
||||
mEditUserInfoController.startingActivityForResult();
|
||||
super.startActivityForResult(intent, requestCode);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onActivityResult(int requestCode, int resultCode, Intent data) {
|
||||
super.onActivityResult(requestCode, resultCode, data);
|
||||
|
||||
mEditUserInfoController.onActivityResult(requestCode, resultCode, data);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onClick(View view) {
|
||||
if (view == mHeaderView) {
|
||||
showDialog(DIALOG_ID_EDIT_USER_INFO);
|
||||
} else if (view == mDeleteButton) {
|
||||
showDialog(DIALOG_CONFIRM_REMOVE);
|
||||
} else {
|
||||
super.onClick(view); // in AppRestrictionsFragment
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Dialog onCreateDialog(int dialogId) {
|
||||
if (dialogId == DIALOG_ID_EDIT_USER_INFO) {
|
||||
return mEditUserInfoController.createDialog(this, mUserIconView.getDrawable(),
|
||||
mUserNameView.getText(), getString(R.string.profile_info_settings_title),
|
||||
this, mUser, null);
|
||||
} else if (dialogId == DIALOG_CONFIRM_REMOVE) {
|
||||
Dialog dlg =
|
||||
UserDialogs.createRemoveDialog(getActivity(), mUser.getIdentifier(),
|
||||
new DialogInterface.OnClickListener() {
|
||||
public void onClick(DialogInterface dialog, int which) {
|
||||
removeUser();
|
||||
}
|
||||
}
|
||||
);
|
||||
return dlg;
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getDialogMetricsCategory(int dialogId) {
|
||||
switch (dialogId) {
|
||||
case DIALOG_ID_EDIT_USER_INFO:
|
||||
return SettingsEnums.DIALOG_USER_EDIT;
|
||||
case DIALOG_CONFIRM_REMOVE:
|
||||
return SettingsEnums.DIALOG_USER_REMOVE;
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
private void removeUser() {
|
||||
getView().post(new Runnable() {
|
||||
public void run() {
|
||||
mUserManager.removeUser(mUser.getIdentifier());
|
||||
finishFragment();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private void switchUser() {
|
||||
try {
|
||||
ActivityManager.getService().switchUser(mUser.getIdentifier());
|
||||
} catch (RemoteException re) {
|
||||
Log.e(TAG, "Error while switching to other user.");
|
||||
} finally {
|
||||
finishFragment();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onPhotoChanged(UserHandle user, Drawable photo) {
|
||||
mUserIconView.setImageDrawable(photo);
|
||||
ThreadUtils.postOnBackgroundThread(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
mUserManager.setUserIcon(user.getIdentifier(), UserIcons.convertToBitmap(photo));
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onLabelChanged(UserHandle user, CharSequence label) {
|
||||
mUserNameView.setText(label);
|
||||
mUserManager.setUserName(user.getIdentifier(), label.toString());
|
||||
}
|
||||
}
|
@@ -36,6 +36,7 @@ import androidx.preference.SwitchPreference;
|
||||
import com.android.settings.R;
|
||||
import com.android.settings.SettingsPreferenceFragment;
|
||||
import com.android.settings.Utils;
|
||||
import com.android.settings.core.SubSettingLauncher;
|
||||
import com.android.settingslib.RestrictedLockUtils;
|
||||
import com.android.settingslib.RestrictedLockUtilsInternal;
|
||||
|
||||
@@ -56,6 +57,7 @@ public class UserDetailsSettings extends SettingsPreferenceFragment
|
||||
private static final String KEY_SWITCH_USER = "switch_user";
|
||||
private static final String KEY_ENABLE_TELEPHONY = "enable_calling";
|
||||
private static final String KEY_REMOVE_USER = "remove_user";
|
||||
private static final String KEY_APP_AND_CONTENT_ACCESS = "app_and_content_access";
|
||||
|
||||
/** Integer extra containing the userId to manage */
|
||||
static final String EXTRA_USER_ID = "user_id";
|
||||
@@ -69,6 +71,8 @@ public class UserDetailsSettings extends SettingsPreferenceFragment
|
||||
Preference mSwitchUserPref;
|
||||
private SwitchPreference mPhonePref;
|
||||
@VisibleForTesting
|
||||
Preference mAppAndContentAccessPref;
|
||||
@VisibleForTesting
|
||||
Preference mRemoveUserPref;
|
||||
|
||||
@VisibleForTesting
|
||||
@@ -109,6 +113,8 @@ public class UserDetailsSettings extends SettingsPreferenceFragment
|
||||
switchUser();
|
||||
}
|
||||
return true;
|
||||
} else if (preference == mAppAndContentAccessPref) {
|
||||
openAppAndContentAccessScreen(false);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
@@ -170,11 +176,14 @@ public class UserDetailsSettings extends SettingsPreferenceFragment
|
||||
if (userId == USER_NULL) {
|
||||
throw new IllegalStateException("Arguments to this fragment must contain the user id");
|
||||
}
|
||||
boolean isNewUser =
|
||||
arguments.getBoolean(AppRestrictionsFragment.EXTRA_NEW_USER, false);
|
||||
mUserInfo = mUserManager.getUserInfo(userId);
|
||||
|
||||
mSwitchUserPref = findPreference(KEY_SWITCH_USER);
|
||||
mPhonePref = findPreference(KEY_ENABLE_TELEPHONY);
|
||||
mRemoveUserPref = findPreference(KEY_REMOVE_USER);
|
||||
mAppAndContentAccessPref = findPreference(KEY_APP_AND_CONTENT_ACCESS);
|
||||
|
||||
mSwitchUserPref.setTitle(
|
||||
context.getString(com.android.settingslib.R.string.user_switch_to_user,
|
||||
@@ -184,16 +193,24 @@ public class UserDetailsSettings extends SettingsPreferenceFragment
|
||||
if (!mUserManager.isAdminUser()) { // non admin users can't remove users and allow calls
|
||||
removePreference(KEY_ENABLE_TELEPHONY);
|
||||
removePreference(KEY_REMOVE_USER);
|
||||
removePreference(KEY_APP_AND_CONTENT_ACCESS);
|
||||
} else {
|
||||
if (!Utils.isVoiceCapable(context)) { // no telephony
|
||||
removePreference(KEY_ENABLE_TELEPHONY);
|
||||
}
|
||||
|
||||
if (!mUserInfo.isGuest()) {
|
||||
mPhonePref.setChecked(!mUserManager.hasUserRestriction(
|
||||
UserManager.DISALLOW_OUTGOING_CALLS, new UserHandle(userId)));
|
||||
mRemoveUserPref.setTitle(R.string.user_remove_user);
|
||||
if (mUserInfo.isRestricted()) {
|
||||
removePreference(KEY_ENABLE_TELEPHONY);
|
||||
if (isNewUser) {
|
||||
// for newly created restricted users we should open the apps and content access
|
||||
// screen to initialize the default restrictions
|
||||
openAppAndContentAccessScreen(true);
|
||||
}
|
||||
} else {
|
||||
removePreference(KEY_APP_AND_CONTENT_ACCESS);
|
||||
}
|
||||
|
||||
if (mUserInfo.isGuest()) {
|
||||
// These are not for an existing user, just general Guest settings.
|
||||
// Default title is for calling and SMS. Change to calling-only here
|
||||
mPhonePref.setTitle(R.string.user_enable_calling);
|
||||
@@ -201,6 +218,10 @@ public class UserDetailsSettings extends SettingsPreferenceFragment
|
||||
mPhonePref.setChecked(
|
||||
!mDefaultGuestRestrictions.getBoolean(UserManager.DISALLOW_OUTGOING_CALLS));
|
||||
mRemoveUserPref.setTitle(R.string.user_exit_guest_title);
|
||||
} else {
|
||||
mPhonePref.setChecked(!mUserManager.hasUserRestriction(
|
||||
UserManager.DISALLOW_OUTGOING_CALLS, new UserHandle(userId)));
|
||||
mRemoveUserPref.setTitle(R.string.user_remove_user);
|
||||
}
|
||||
if (RestrictedLockUtilsInternal.hasBaseUserRestriction(context,
|
||||
UserManager.DISALLOW_REMOVE_USER, UserHandle.myUserId())) {
|
||||
@@ -209,6 +230,7 @@ public class UserDetailsSettings extends SettingsPreferenceFragment
|
||||
|
||||
mRemoveUserPref.setOnPreferenceClickListener(this);
|
||||
mPhonePref.setOnPreferenceChangeListener(this);
|
||||
mAppAndContentAccessPref.setOnPreferenceClickListener(this);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -283,4 +305,20 @@ public class UserDetailsSettings extends SettingsPreferenceFragment
|
||||
mUserManager.removeUser(mUserInfo.id);
|
||||
finishFragment();
|
||||
}
|
||||
|
||||
/**
|
||||
* @param isNewUser indicates if a user was created recently, for new users
|
||||
* AppRestrictionsFragment should set the default restrictions
|
||||
*/
|
||||
private void openAppAndContentAccessScreen(boolean isNewUser) {
|
||||
Bundle extras = new Bundle();
|
||||
extras.putInt(AppRestrictionsFragment.EXTRA_USER_ID, mUserInfo.id);
|
||||
extras.putBoolean(AppRestrictionsFragment.EXTRA_NEW_USER, isNewUser);
|
||||
new SubSettingLauncher(getContext())
|
||||
.setDestination(AppRestrictionsFragment.class.getName())
|
||||
.setArguments(extras)
|
||||
.setTitleRes(R.string.user_restrictions_title)
|
||||
.setSourceMetricsCategory(getMetricsCategory())
|
||||
.launch();
|
||||
}
|
||||
}
|
||||
|
@@ -485,23 +485,13 @@ public class UserSettings extends SettingsPreferenceFragment
|
||||
private void onManageUserClicked(int userId, boolean newUser) {
|
||||
mAddingUser = false;
|
||||
UserInfo userInfo = mUserManager.getUserInfo(userId);
|
||||
if (userInfo.isRestricted() && mUserCaps.mIsAdmin) {
|
||||
Bundle extras = new Bundle();
|
||||
extras.putInt(RestrictedProfileSettings.EXTRA_USER_ID, userId);
|
||||
extras.putBoolean(RestrictedProfileSettings.EXTRA_NEW_USER, newUser);
|
||||
extras.putBoolean(RestrictedProfileSettings.EXTRA_SHOW_SWITCH_USER, canSwitchUserNow());
|
||||
new SubSettingLauncher(getContext())
|
||||
.setDestination(RestrictedProfileSettings.class.getName())
|
||||
.setArguments(extras)
|
||||
.setTitleRes(R.string.user_restrictions_title)
|
||||
.setSourceMetricsCategory(getMetricsCategory())
|
||||
.launch();
|
||||
} else if (userId == UserHandle.myUserId()) {
|
||||
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)
|
||||
@@ -963,10 +953,10 @@ public class UserSettings extends SettingsPreferenceFragment
|
||||
pref.setSummary(R.string.user_summary_restricted_not_set_up);
|
||||
} else {
|
||||
pref.setSummary(R.string.user_summary_not_set_up);
|
||||
}
|
||||
// Disallow setting up user which results in user switching when the restriction is
|
||||
// set.
|
||||
// Disallow setting up user which results in user switching when the
|
||||
// restriction is set.
|
||||
pref.setEnabled(!mUserCaps.mDisallowSwitchUser && canSwitchUserNow());
|
||||
}
|
||||
} else if (user.isRestricted()) {
|
||||
pref.setSummary(R.string.user_summary_restricted_profile);
|
||||
}
|
||||
@@ -1137,17 +1127,14 @@ public class UserSettings extends SettingsPreferenceFragment
|
||||
showDialog(DIALOG_CONFIRM_EXIT_GUEST);
|
||||
return true;
|
||||
}
|
||||
// If this is a limited user, launch the user info settings instead of profile editor
|
||||
if (mUserManager.isRestrictedProfile()) {
|
||||
onManageUserClicked(UserHandle.myUserId(), false);
|
||||
} else {
|
||||
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()) {
|
||||
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 {
|
||||
@@ -1279,4 +1266,7 @@ public class UserSettings extends SettingsPreferenceFragment
|
||||
}
|
||||
};
|
||||
|
||||
private boolean isSecondaryUser(UserInfo user) {
|
||||
return UserManager.USER_TYPE_FULL_SECONDARY.equals(user.userType);
|
||||
}
|
||||
}
|
||||
|
@@ -28,7 +28,9 @@ import static org.mockito.Mockito.verify;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
import android.app.Dialog;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.content.pm.UserInfo;
|
||||
import android.graphics.drawable.Drawable;
|
||||
import android.widget.EditText;
|
||||
import android.widget.ImageView;
|
||||
@@ -62,6 +64,8 @@ public class EditUserInfoControllerTest {
|
||||
@Mock
|
||||
private Drawable mCurrentIcon;
|
||||
|
||||
private boolean mCanChangePhoto;
|
||||
|
||||
private FragmentActivity mActivity;
|
||||
private TestEditUserInfoController mController;
|
||||
|
||||
@@ -78,6 +82,11 @@ public class EditUserInfoControllerTest {
|
||||
mPhotoController = mock(EditUserPhotoController.class, Answers.RETURNS_DEEP_STUBS);
|
||||
return mPhotoController;
|
||||
}
|
||||
|
||||
@Override
|
||||
boolean canChangePhoto(Context context, UserInfo user) {
|
||||
return mCanChangePhoto;
|
||||
}
|
||||
}
|
||||
|
||||
@Before
|
||||
@@ -86,6 +95,7 @@ public class EditUserInfoControllerTest {
|
||||
mActivity = spy(ActivityController.of(new FragmentActivity()).get());
|
||||
when(mFragment.getActivity()).thenReturn(mActivity);
|
||||
mController = new TestEditUserInfoController();
|
||||
mCanChangePhoto = true;
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -256,4 +266,17 @@ public class EditUserInfoControllerTest {
|
||||
verify(dialogCompleteCallback, times(1)).onPositive();
|
||||
verify(dialogCompleteCallback, times(0)).onNegativeOrCancel();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void createDialog_canNotChangePhoto_nullPhotoController() {
|
||||
mCanChangePhoto = false;
|
||||
|
||||
mController.createDialog(
|
||||
mFragment, mCurrentIcon, "test",
|
||||
"title", null,
|
||||
android.os.Process.myUserHandle(),
|
||||
null);
|
||||
|
||||
assertThat(mController.mPhotoController).isNull();
|
||||
}
|
||||
}
|
||||
|
@@ -32,9 +32,11 @@ import static org.mockito.Mockito.never;
|
||||
import static org.mockito.Mockito.spy;
|
||||
import static org.mockito.Mockito.verify;
|
||||
import static org.mockito.Mockito.verifyNoMoreInteractions;
|
||||
import static org.robolectric.Shadows.shadowOf;
|
||||
|
||||
import android.content.ComponentName;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.content.pm.UserInfo;
|
||||
import android.os.Bundle;
|
||||
import android.os.UserHandle;
|
||||
@@ -47,6 +49,8 @@ import androidx.preference.PreferenceScreen;
|
||||
import androidx.preference.SwitchPreference;
|
||||
|
||||
import com.android.settings.R;
|
||||
import com.android.settings.SettingsActivity;
|
||||
import com.android.settings.SubSettings;
|
||||
import com.android.settings.testutils.shadow.ShadowDevicePolicyManager;
|
||||
import com.android.settings.testutils.shadow.ShadowUserManager;
|
||||
|
||||
@@ -61,6 +65,7 @@ import org.robolectric.RuntimeEnvironment;
|
||||
import org.robolectric.android.controller.ActivityController;
|
||||
import org.robolectric.annotation.Config;
|
||||
import org.robolectric.shadow.api.Shadow;
|
||||
import org.robolectric.shadows.ShadowIntent;
|
||||
import org.robolectric.util.ReflectionHelpers;
|
||||
|
||||
import java.util.ArrayList;
|
||||
@@ -76,6 +81,7 @@ public class UserDetailsSettingsTest {
|
||||
private static final String KEY_SWITCH_USER = "switch_user";
|
||||
private static final String KEY_ENABLE_TELEPHONY = "enable_calling";
|
||||
private static final String KEY_REMOVE_USER = "remove_user";
|
||||
private static final String KEY_APP_AND_CONTENT_ACCESS = "app_and_content_access";
|
||||
|
||||
private static final int DIALOG_CONFIRM_REMOVE = 1;
|
||||
|
||||
@@ -90,6 +96,8 @@ public class UserDetailsSettingsTest {
|
||||
private SwitchPreference mPhonePref;
|
||||
@Mock
|
||||
private Preference mRemoveUserPref;
|
||||
@Mock
|
||||
private Preference mAppAndContentAccessPref;
|
||||
|
||||
private FragmentActivity mActivity;
|
||||
private Context mContext;
|
||||
@@ -114,14 +122,15 @@ public class UserDetailsSettingsTest {
|
||||
|
||||
ReflectionHelpers.setField(mFragment, "mUserManager", userManager);
|
||||
doReturn(mActivity).when(mFragment).getActivity();
|
||||
doReturn(mContext).when(mFragment).getContext();
|
||||
doReturn(mActivity).when(mFragment).getContext();
|
||||
|
||||
doReturn(mock(PreferenceScreen.class)).when(mFragment).getPreferenceScreen();
|
||||
doReturn("").when(mActivity).getString(anyInt(), anyString());
|
||||
|
||||
doReturn(mSwitchUserPref).when(mFragment).findPreference(KEY_SWITCH_USER);
|
||||
doReturn(mPhonePref).when(mFragment).findPreference(KEY_ENABLE_TELEPHONY);
|
||||
doReturn(mRemoveUserPref).when(mFragment).findPreference(KEY_REMOVE_USER);
|
||||
doReturn(mAppAndContentAccessPref)
|
||||
.when(mFragment).findPreference(KEY_APP_AND_CONTENT_ACCESS);
|
||||
}
|
||||
|
||||
@After
|
||||
@@ -169,6 +178,24 @@ public class UserDetailsSettingsTest {
|
||||
verify(mFragment, never()).removePreference(KEY_SWITCH_USER);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void initialize_userSelected_shouldNotShowAppAndContentPref() {
|
||||
setupSelectedUser();
|
||||
|
||||
mFragment.initialize(mActivity, mArguments);
|
||||
|
||||
verify(mFragment).removePreference(KEY_APP_AND_CONTENT_ACCESS);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void initialize_guestSelected_shouldNotShowAppAndContentPref() {
|
||||
setupSelectedGuest();
|
||||
|
||||
mFragment.initialize(mActivity, mArguments);
|
||||
|
||||
verify(mFragment).removePreference(KEY_APP_AND_CONTENT_ACCESS);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void onResume_canSwitch_shouldEnableSwitchPref() {
|
||||
mUserManager.setSwitchabilityStatus(SWITCHABILITY_STATUS_OK);
|
||||
@@ -248,6 +275,16 @@ public class UserDetailsSettingsTest {
|
||||
verify(mFragment).removePreference(KEY_ENABLE_TELEPHONY);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void initialize_nonAdmin_shouldNotShowAppAndContentPref() {
|
||||
setupSelectedUser();
|
||||
mUserManager.setIsAdminUser(false);
|
||||
|
||||
mFragment.initialize(mActivity, mArguments);
|
||||
|
||||
verify(mFragment).removePreference(KEY_APP_AND_CONTENT_ACCESS);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void initialize_adminSelectsSecondaryUser_shouldShowRemovePreference() {
|
||||
setupSelectedUser();
|
||||
@@ -260,6 +297,57 @@ public class UserDetailsSettingsTest {
|
||||
verify(mFragment, never()).removePreference(KEY_REMOVE_USER);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void initialize_adminSelectsNewRestrictedUser_shouldOpenAppContentScreen() {
|
||||
setupSelectedRestrictedUser();
|
||||
mUserManager.setIsAdminUser(true);
|
||||
mArguments.putBoolean(AppRestrictionsFragment.EXTRA_NEW_USER, true);
|
||||
|
||||
mFragment.initialize(mActivity, mArguments);
|
||||
|
||||
Intent startedIntent = shadowOf(mActivity).getNextStartedActivity();
|
||||
ShadowIntent shadowIntent = shadowOf(startedIntent);
|
||||
assertThat(shadowIntent.getIntentClass()).isEqualTo(SubSettings.class);
|
||||
assertThat(startedIntent.getStringExtra(SettingsActivity.EXTRA_SHOW_FRAGMENT))
|
||||
.isEqualTo(AppRestrictionsFragment.class.getName());
|
||||
Bundle arguments = startedIntent.getBundleExtra(
|
||||
SettingsActivity.EXTRA_SHOW_FRAGMENT_ARGUMENTS);
|
||||
assertThat(arguments).isNotNull();
|
||||
assertThat(arguments.getInt(AppRestrictionsFragment.EXTRA_USER_ID, 0))
|
||||
.isEqualTo(mUserInfo.id);
|
||||
assertThat(arguments.getBoolean(AppRestrictionsFragment.EXTRA_NEW_USER, false))
|
||||
.isEqualTo(true);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void initialize_adminSelectsRestrictedUser_shouldSetupPreferences() {
|
||||
setupSelectedRestrictedUser();
|
||||
mUserManager.setIsAdminUser(true);
|
||||
doReturn(true).when(mTelephonyManager).isVoiceCapable();
|
||||
|
||||
mFragment.initialize(mActivity, mArguments);
|
||||
|
||||
verify(mFragment, never()).removePreference(KEY_REMOVE_USER);
|
||||
verify(mFragment, never()).removePreference(KEY_SWITCH_USER);
|
||||
verify(mFragment, never()).removePreference(KEY_APP_AND_CONTENT_ACCESS);
|
||||
verify(mFragment).removePreference(KEY_ENABLE_TELEPHONY);
|
||||
verify(mSwitchUserPref).setTitle("Switch to " + mUserInfo.name);
|
||||
verify(mAppAndContentAccessPref).setOnPreferenceClickListener(mFragment);
|
||||
verify(mSwitchUserPref).setOnPreferenceClickListener(mFragment);
|
||||
verify(mRemoveUserPref).setOnPreferenceClickListener(mFragment);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void initialize_adminSelectsExistingRestrictedUser_shouldNotStartAppAndContentAccess() {
|
||||
setupSelectedRestrictedUser();
|
||||
mUserManager.setIsAdminUser(true);
|
||||
mArguments.putBoolean(AppRestrictionsFragment.EXTRA_NEW_USER, false);
|
||||
|
||||
mFragment.initialize(mActivity, mArguments);
|
||||
|
||||
verify(mActivity, never()).startActivity(any(Intent.class));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void initialize_adminSelectsGuest_shouldShowRemovePreference() {
|
||||
setupSelectedGuest();
|
||||
@@ -344,6 +432,7 @@ public class UserDetailsSettingsTest {
|
||||
mUserManager.setSwitchabilityStatus(SWITCHABILITY_STATUS_OK);
|
||||
mFragment.mSwitchUserPref = mSwitchUserPref;
|
||||
mFragment.mRemoveUserPref = mRemoveUserPref;
|
||||
mFragment.mAppAndContentAccessPref = mAppAndContentAccessPref;
|
||||
mFragment.mUserInfo = mUserInfo;
|
||||
|
||||
mFragment.onPreferenceClick(mSwitchUserPref);
|
||||
@@ -357,6 +446,7 @@ public class UserDetailsSettingsTest {
|
||||
mUserManager.setSwitchabilityStatus(SWITCHABILITY_STATUS_USER_SWITCH_DISALLOWED);
|
||||
mFragment.mSwitchUserPref = mSwitchUserPref;
|
||||
mFragment.mRemoveUserPref = mRemoveUserPref;
|
||||
mFragment.mAppAndContentAccessPref = mAppAndContentAccessPref;
|
||||
mFragment.mUserInfo = mUserInfo;
|
||||
|
||||
mFragment.onPreferenceClick(mSwitchUserPref);
|
||||
@@ -371,6 +461,7 @@ public class UserDetailsSettingsTest {
|
||||
mUserManager.setIsAdminUser(true);
|
||||
mFragment.mSwitchUserPref = mSwitchUserPref;
|
||||
mFragment.mRemoveUserPref = mRemoveUserPref;
|
||||
mFragment.mAppAndContentAccessPref = mAppAndContentAccessPref;
|
||||
doNothing().when(mFragment).showDialog(anyInt());
|
||||
|
||||
mFragment.onPreferenceClick(mRemoveUserPref);
|
||||
@@ -386,6 +477,7 @@ public class UserDetailsSettingsTest {
|
||||
mUserManager.setIsAdminUser(false);
|
||||
mFragment.mSwitchUserPref = mSwitchUserPref;
|
||||
mFragment.mRemoveUserPref = mRemoveUserPref;
|
||||
mFragment.mAppAndContentAccessPref = mAppAndContentAccessPref;
|
||||
doNothing().when(mFragment).showDialog(anyInt());
|
||||
|
||||
mFragment.onPreferenceClick(mRemoveUserPref);
|
||||
@@ -394,12 +486,37 @@ public class UserDetailsSettingsTest {
|
||||
verify(mFragment, never()).showDialog(DIALOG_CONFIRM_REMOVE);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void onPreferenceClick_selectRestrictedUser_appAndContentAccessClicked_startActivity() {
|
||||
setupSelectedRestrictedUser();
|
||||
mFragment.mUserInfo = mUserInfo;
|
||||
mUserManager.setIsAdminUser(true);
|
||||
mFragment.mSwitchUserPref = mSwitchUserPref;
|
||||
mFragment.mRemoveUserPref = mRemoveUserPref;
|
||||
mFragment.mAppAndContentAccessPref = mAppAndContentAccessPref;
|
||||
|
||||
mFragment.onPreferenceClick(mAppAndContentAccessPref);
|
||||
|
||||
Intent startedIntent = shadowOf(mActivity).getNextStartedActivity();
|
||||
ShadowIntent shadowIntent = shadowOf(startedIntent);
|
||||
assertThat(shadowIntent.getIntentClass()).isEqualTo(SubSettings.class);
|
||||
assertThat(startedIntent.getStringExtra(SettingsActivity.EXTRA_SHOW_FRAGMENT))
|
||||
.isEqualTo(AppRestrictionsFragment.class.getName());
|
||||
Bundle arguments = startedIntent.getBundleExtra(
|
||||
SettingsActivity.EXTRA_SHOW_FRAGMENT_ARGUMENTS);
|
||||
assertThat(arguments.getInt(AppRestrictionsFragment.EXTRA_USER_ID, 0))
|
||||
.isEqualTo(mUserInfo.id);
|
||||
assertThat(arguments.getBoolean(AppRestrictionsFragment.EXTRA_NEW_USER, true))
|
||||
.isEqualTo(false);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void onPreferenceClick_unknownPreferenceClicked_doNothing() {
|
||||
setupSelectedUser();
|
||||
mFragment.mUserInfo = mUserInfo;
|
||||
mFragment.mSwitchUserPref = mSwitchUserPref;
|
||||
mFragment.mRemoveUserPref = mRemoveUserPref;
|
||||
mFragment.mAppAndContentAccessPref = mAppAndContentAccessPref;
|
||||
|
||||
mFragment.onPreferenceClick(mock(UserPreference.class));
|
||||
|
||||
@@ -464,4 +581,13 @@ public class UserDetailsSettingsTest {
|
||||
|
||||
mUserManager.addProfile(mUserInfo);
|
||||
}
|
||||
|
||||
private void setupSelectedRestrictedUser() {
|
||||
mArguments.putInt("user_id", 21);
|
||||
mUserInfo = new UserInfo(21, "Bob", null,
|
||||
UserInfo.FLAG_FULL | UserInfo.FLAG_INITIALIZED | UserInfo.FLAG_RESTRICTED,
|
||||
UserManager.USER_TYPE_FULL_RESTRICTED);
|
||||
|
||||
mUserManager.addProfile(mUserInfo);
|
||||
}
|
||||
}
|
||||
|
Reference in New Issue
Block a user