diff --git a/res/layout/edit_user_info_dialog_content.xml b/res/layout/edit_user_info_dialog_content.xml
index 895cef63fb9..2bd464b4233 100644
--- a/res/layout/edit_user_info_dialog_content.xml
+++ b/res/layout/edit_user_info_dialog_content.xml
@@ -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"/>
diff --git a/res/layout/user_info_header.xml b/res/layout/user_info_header.xml
deleted file mode 100644
index bfdf3fc7324..00000000000
--- a/res/layout/user_info_header.xml
+++ /dev/null
@@ -1,129 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/res/xml/user_details_settings.xml b/res/xml/user_details_settings.xml
index d336395d02a..9280ff11632 100644
--- a/res/xml/user_details_settings.xml
+++ b/res/xml/user_details_settings.xml
@@ -25,6 +25,10 @@
android:key="enable_calling"
android:icon="@drawable/ic_phone"
android:title="@string/user_enable_calling_sms" />
+
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() {
diff --git a/src/com/android/settings/users/PhotoCapabilityUtils.java b/src/com/android/settings/users/PhotoCapabilityUtils.java
new file mode 100644
index 00000000000..1e0985737b0
--- /dev/null
+++ b/src/com/android/settings/users/PhotoCapabilityUtils.java
@@ -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;
+ }
+
+}
diff --git a/src/com/android/settings/users/RestrictedProfileSettings.java b/src/com/android/settings/users/RestrictedProfileSettings.java
deleted file mode 100644
index 44657cf9590..00000000000
--- a/src/com/android/settings/users/RestrictedProfileSettings.java
+++ /dev/null
@@ -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());
- }
-}
diff --git a/src/com/android/settings/users/UserDetailsSettings.java b/src/com/android/settings/users/UserDetailsSettings.java
index 2696ddc1319..c7cf90d725c 100644
--- a/src/com/android/settings/users/UserDetailsSettings.java
+++ b/src/com/android/settings/users/UserDetailsSettings.java
@@ -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();
+ }
}
diff --git a/src/com/android/settings/users/UserSettings.java b/src/com/android/settings/users/UserSettings.java
index 7d4ab5d5312..719ed4aa921 100644
--- a/src/com/android/settings/users/UserSettings.java
+++ b/src/com/android/settings/users/UserSettings.java
@@ -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.
+ pref.setEnabled(!mUserCaps.mDisallowSwitchUser && canSwitchUserNow());
}
- // 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);
- }
+ 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);
+ }
}
diff --git a/tests/robotests/src/com/android/settings/users/EditUserInfoControllerTest.java b/tests/robotests/src/com/android/settings/users/EditUserInfoControllerTest.java
index 1c191fa5eed..db9872fc49f 100644
--- a/tests/robotests/src/com/android/settings/users/EditUserInfoControllerTest.java
+++ b/tests/robotests/src/com/android/settings/users/EditUserInfoControllerTest.java
@@ -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();
+ }
}
diff --git a/tests/robotests/src/com/android/settings/users/UserDetailsSettingsTest.java b/tests/robotests/src/com/android/settings/users/UserDetailsSettingsTest.java
index 6c5478262aa..56e495786fc 100644
--- a/tests/robotests/src/com/android/settings/users/UserDetailsSettingsTest.java
+++ b/tests/robotests/src/com/android/settings/users/UserDetailsSettingsTest.java
@@ -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);
+ }
}