- 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
)
240 lines
9.3 KiB
Java
240 lines
9.3 KiB
Java
/*
|
|
* 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.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;
|
|
import android.os.UserHandle;
|
|
import android.os.UserManager;
|
|
import android.text.TextUtils;
|
|
import android.view.LayoutInflater;
|
|
import android.view.View;
|
|
import android.view.WindowManager;
|
|
import android.widget.EditText;
|
|
import android.widget.ImageView;
|
|
|
|
import androidx.annotation.VisibleForTesting;
|
|
import androidx.appcompat.app.AlertDialog;
|
|
import androidx.fragment.app.Fragment;
|
|
|
|
import com.android.settings.R;
|
|
import com.android.settingslib.drawable.CircleFramedDrawable;
|
|
|
|
import java.io.File;
|
|
|
|
/**
|
|
* This class encapsulates a Dialog for editing the user nickname and photo.
|
|
*/
|
|
public class EditUserInfoController {
|
|
|
|
private static final String KEY_AWAITING_RESULT = "awaiting_result";
|
|
private static final String KEY_SAVED_PHOTO = "pending_photo";
|
|
|
|
private Dialog mEditUserInfoDialog;
|
|
private Bitmap mSavedPhoto;
|
|
private EditUserPhotoController mEditUserPhotoController;
|
|
private UserHandle mUser;
|
|
private UserManager mUserManager;
|
|
private boolean mWaitingForActivityResult = false;
|
|
|
|
/**
|
|
* Callback made when either the username text or photo choice changes.
|
|
*/
|
|
public interface OnContentChangedCallback {
|
|
/** Photo updated. */
|
|
void onPhotoChanged(UserHandle user, Drawable photo);
|
|
/** Username updated. */
|
|
void onLabelChanged(UserHandle user, CharSequence label);
|
|
}
|
|
|
|
/**
|
|
* Callback made when the dialog finishes.
|
|
*/
|
|
public interface OnDialogCompleteCallback {
|
|
/** Dialog closed with positive button. */
|
|
void onPositive();
|
|
/** Dialog closed with negative button or cancelled. */
|
|
void onNegativeOrCancel();
|
|
}
|
|
|
|
public void clear() {
|
|
if (mEditUserPhotoController != null) {
|
|
mEditUserPhotoController.removeNewUserPhotoBitmapFile();
|
|
}
|
|
mEditUserInfoDialog = null;
|
|
mSavedPhoto = null;
|
|
}
|
|
|
|
public Dialog getDialog() {
|
|
return mEditUserInfoDialog;
|
|
}
|
|
|
|
public void onRestoreInstanceState(Bundle icicle) {
|
|
String pendingPhoto = icicle.getString(KEY_SAVED_PHOTO);
|
|
if (pendingPhoto != null) {
|
|
mSavedPhoto = EditUserPhotoController.loadNewUserPhotoBitmap(new File(pendingPhoto));
|
|
}
|
|
mWaitingForActivityResult = icicle.getBoolean(KEY_AWAITING_RESULT, false);
|
|
}
|
|
|
|
public void onSaveInstanceState(Bundle outState) {
|
|
if (mEditUserInfoDialog != null && mEditUserInfoDialog.isShowing()
|
|
&& mEditUserPhotoController != null) {
|
|
// Bitmap cannot be stored into bundle because it may exceed parcel limit
|
|
// Store it in a temporary file instead
|
|
File file = mEditUserPhotoController.saveNewUserPhotoBitmap();
|
|
if (file != null) {
|
|
outState.putString(KEY_SAVED_PHOTO, file.getPath());
|
|
}
|
|
}
|
|
if (mWaitingForActivityResult) {
|
|
outState.putBoolean(KEY_AWAITING_RESULT, mWaitingForActivityResult);
|
|
}
|
|
}
|
|
|
|
public void startingActivityForResult() {
|
|
mWaitingForActivityResult = true;
|
|
}
|
|
|
|
public void onActivityResult(int requestCode, int resultCode, Intent data) {
|
|
mWaitingForActivityResult = false;
|
|
|
|
if (mEditUserPhotoController != null && mEditUserInfoDialog != null) {
|
|
mEditUserPhotoController.onActivityResult(requestCode, resultCode, data);
|
|
}
|
|
}
|
|
|
|
public Dialog createDialog(final Fragment fragment, final Drawable currentUserIcon,
|
|
final CharSequence currentUserName,
|
|
String title, final OnContentChangedCallback callback, UserHandle user,
|
|
OnDialogCompleteCallback completeCallback) {
|
|
Activity activity = fragment.getActivity();
|
|
mUser = user;
|
|
if (mUserManager == null) {
|
|
mUserManager = activity.getSystemService(UserManager.class);
|
|
}
|
|
LayoutInflater inflater = activity.getLayoutInflater();
|
|
View content = inflater.inflate(R.layout.edit_user_info_dialog_content, null);
|
|
|
|
final EditText userNameView = (EditText) content.findViewById(R.id.user_name);
|
|
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);
|
|
} else {
|
|
drawable = currentUserIcon;
|
|
}
|
|
userPhotoView.setImageDrawable(drawable);
|
|
if (canChangePhoto) {
|
|
mEditUserPhotoController =
|
|
createEditUserPhotoController(fragment, userPhotoView, drawable);
|
|
}
|
|
mEditUserInfoDialog = new AlertDialog.Builder(activity)
|
|
.setTitle(title)
|
|
.setView(content)
|
|
.setCancelable(true)
|
|
.setPositiveButton(android.R.string.ok, new DialogInterface.OnClickListener() {
|
|
@Override
|
|
public void onClick(DialogInterface dialog, int which) {
|
|
if (which == DialogInterface.BUTTON_POSITIVE) {
|
|
// Update the name if changed.
|
|
CharSequence userName = userNameView.getText();
|
|
if (!TextUtils.isEmpty(userName)) {
|
|
if (currentUserName == null
|
|
|| !userName.toString().equals(
|
|
currentUserName.toString())) {
|
|
if (callback != null) {
|
|
callback.onLabelChanged(mUser, userName.toString());
|
|
}
|
|
}
|
|
}
|
|
// Update the photo if changed.
|
|
if (mEditUserPhotoController != null) {
|
|
Drawable drawable =
|
|
mEditUserPhotoController.getNewUserPhotoDrawable();
|
|
if (drawable != null && !drawable.equals(currentUserIcon)) {
|
|
if (callback != null) {
|
|
callback.onPhotoChanged(mUser, drawable);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
clear();
|
|
if (completeCallback != null) {
|
|
completeCallback.onPositive();
|
|
}
|
|
}
|
|
})
|
|
.setNegativeButton(android.R.string.cancel, new DialogInterface.OnClickListener() {
|
|
@Override
|
|
public void onClick(DialogInterface dialog, int which) {
|
|
clear();
|
|
if (completeCallback != null) {
|
|
completeCallback.onNegativeOrCancel();
|
|
}
|
|
}
|
|
})
|
|
.setOnCancelListener(new DialogInterface.OnCancelListener() {
|
|
@Override
|
|
public void onCancel(DialogInterface dialog) {
|
|
clear();
|
|
if (completeCallback != null) {
|
|
completeCallback.onNegativeOrCancel();
|
|
}
|
|
}
|
|
})
|
|
.create();
|
|
|
|
// Make sure the IME is up.
|
|
mEditUserInfoDialog.getWindow().setSoftInputMode(
|
|
WindowManager.LayoutParams.SOFT_INPUT_STATE_VISIBLE);
|
|
|
|
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) {
|
|
return new EditUserPhotoController(fragment, userPhotoView,
|
|
mSavedPhoto, drawable, mWaitingForActivityResult);
|
|
}
|
|
}
|