summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorWesley.CW Wang <wesleycwwang@google.com>2018-08-15 17:39:07 +0800
committerWesley.CW Wang <wesleycwwang@google.com>2018-10-04 16:15:05 +0800
commite7772e0bb866a8ae72cdef69f097ffa8164ebeb7 (patch)
treeafbd3a1a14299a9956649468a30d414f3604ca35 /src
parentb5a739669ddc4e2ebe3cd7af5a2440406bb009d3 (diff)
downloadEmergencyInfo-e7772e0bb866a8ae72cdef69f097ffa8164ebeb7.tar.gz
Emergency Info user name preference design change
- User name preference now will launch dialog same as change user name & icon in Multiple users. - Add permission for edit user name. - Change robolectric properties sdk to 23 for fixing robolectric initialize objects bug. Test: make RunEmergencyInfoRoboTests Bug: 111967295 Bug: 116770817 Change-Id: I938983eaa0d21442ade59dde0f3f74eec3a62d22
Diffstat (limited to 'src')
-rw-r--r--src/com/android/emergency/PreferenceKeys.java4
-rw-r--r--src/com/android/emergency/edit/EditInfoFragment.java32
-rw-r--r--src/com/android/emergency/edit/EditMedicalInfoFragment.java24
-rw-r--r--src/com/android/emergency/preferences/EmergencyNamePreference.java278
4 files changed, 328 insertions, 10 deletions
diff --git a/src/com/android/emergency/PreferenceKeys.java b/src/com/android/emergency/PreferenceKeys.java
index 89db2a66..bdfd47d0 100644
--- a/src/com/android/emergency/PreferenceKeys.java
+++ b/src/com/android/emergency/PreferenceKeys.java
@@ -32,7 +32,7 @@ public interface PreferenceKeys {
/** Key for the add emergency contact preference */
public static final String KEY_ADD_EMERGENCY_CONTACT = "add_emergency_contact";
- /** Key to store and read the name of the user. */
+ /** Key for emergency name preference */
public static final String KEY_NAME = "name";
/** Key to store and read the address of the user. */
@@ -58,7 +58,7 @@ public interface PreferenceKeys {
*
* <p>Note: Do not change the order of these keys, since the order is used to collect TRON stats
*/
- public static final String[] KEYS_EDIT_EMERGENCY_INFO = {KEY_NAME, KEY_ADDRESS,
+ public static final String[] KEYS_EDIT_EMERGENCY_INFO = {KEY_ADDRESS,
KEY_BLOOD_TYPE, KEY_ALLERGIES, KEY_MEDICATIONS,
KEY_MEDICAL_CONDITIONS, KEY_ORGAN_DONOR};
diff --git a/src/com/android/emergency/edit/EditInfoFragment.java b/src/com/android/emergency/edit/EditInfoFragment.java
index f774640b..53cae381 100644
--- a/src/com/android/emergency/edit/EditInfoFragment.java
+++ b/src/com/android/emergency/edit/EditInfoFragment.java
@@ -16,10 +16,10 @@
package com.android.emergency.edit;
import android.app.Activity;
+import android.app.DialogFragment;
import android.content.ActivityNotFoundException;
import android.content.Context;
import android.content.Intent;
-import android.content.SharedPreferences;
import android.net.Uri;
import android.os.Bundle;
import android.provider.ContactsContract;
@@ -27,7 +27,6 @@ import androidx.preference.Preference.OnPreferenceChangeListener;
import androidx.preference.PreferenceFragment;
import androidx.preference.Preference;
import androidx.preference.PreferenceGroup;
-import androidx.preference.PreferenceManager;
import android.util.Log;
import android.widget.Toast;
@@ -35,8 +34,11 @@ import com.android.emergency.PreferenceKeys;
import com.android.emergency.R;
import com.android.emergency.ReloadablePreferenceInterface;
import com.android.emergency.preferences.EmergencyContactsPreference;
+import com.android.emergency.preferences.EmergencyNamePreference;
import com.android.emergency.util.PreferenceUtils;
import com.android.internal.annotations.VisibleForTesting;
+import com.android.settingslib.CustomDialogPreference;
+import com.android.settingslib.CustomEditTextPreference;
import java.util.HashMap;
import java.util.Map;
@@ -48,12 +50,16 @@ public class EditInfoFragment extends PreferenceFragment {
/** Result code for contact picker */
private static final int CONTACT_PICKER_RESULT = 1001;
+ private static final String DIALOG_PREFERENCE_TAG = "dialog_preference";
+
private final Map<String, Preference> mMedicalInfoPreferences =
new HashMap<String, Preference>();
/** The category that holds the emergency contacts. */
private EmergencyContactsPreference mEmergencyContactsPreferenceCategory;
+ private EmergencyNamePreference mEmergencyNamePreference;
+
@Override
public void onCreatePreferences(Bundle savedInstanceState, String rootKey) {
setPreferencesFromResource(R.xml.edit_emergency_info, rootKey);
@@ -69,6 +75,9 @@ public class EditInfoFragment extends PreferenceFragment {
}
}
+ mEmergencyNamePreference = (EmergencyNamePreference) findPreference(
+ PreferenceKeys.KEY_NAME);
+
// Fill in emergency contacts.
mEmergencyContactsPreferenceCategory = (EmergencyContactsPreference)
findPreference(PreferenceKeys.KEY_EMERGENCY_CONTACTS);
@@ -101,6 +110,7 @@ public class EditInfoFragment extends PreferenceFragment {
public void onResume() {
super.onResume();
reloadFromPreference();
+ mEmergencyNamePreference.reloadFromUserManager();
}
/** Reloads the contacts by reading the value from the shared preferences. */
@@ -120,6 +130,24 @@ public class EditInfoFragment extends PreferenceFragment {
}
@Override
+ public void onDisplayPreferenceDialog(Preference preference) {
+ DialogFragment fragment = null;
+ if (preference instanceof CustomEditTextPreference) {
+ fragment = CustomEditTextPreference.CustomPreferenceDialogFragment
+ .newInstance(preference.getKey());
+ } else if (preference instanceof CustomDialogPreference) {
+ fragment = EmergencyNamePreference.EmergencyNamePreferenceDialogFragment
+ .newInstance(preference.getKey());
+ }
+ if (fragment != null) {
+ fragment.setTargetFragment(this, 0);
+ fragment.show(getFragmentManager(), DIALOG_PREFERENCE_TAG);
+ } else {
+ super.onDisplayPreferenceDialog(preference);
+ }
+ }
+
+ @Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
if (requestCode == CONTACT_PICKER_RESULT && resultCode == Activity.RESULT_OK) {
Uri phoneUri = data.getData();
diff --git a/src/com/android/emergency/edit/EditMedicalInfoFragment.java b/src/com/android/emergency/edit/EditMedicalInfoFragment.java
index d132c696..b8567a50 100644
--- a/src/com/android/emergency/edit/EditMedicalInfoFragment.java
+++ b/src/com/android/emergency/edit/EditMedicalInfoFragment.java
@@ -18,23 +18,31 @@ package com.android.emergency.edit;
import android.app.DialogFragment;
import android.app.Fragment;
import android.os.Bundle;
-import androidx.preference.PreferenceFragment;
+
import androidx.preference.Preference;
-import android.text.TextUtils;
+import androidx.preference.PreferenceFragment;
import com.android.emergency.PreferenceKeys;
import com.android.emergency.R;
import com.android.emergency.ReloadablePreferenceInterface;
-import com.android.emergency.preferences.AutoCompleteEditTextPreference;
+import com.android.emergency.preferences.EmergencyNamePreference;
import com.android.emergency.util.PreferenceUtils;
import com.android.internal.logging.MetricsLogger;
import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
+import com.android.settingslib.CustomDialogPreference;
import com.android.settingslib.CustomEditTextPreference;
+import android.text.TextUtils;
+
/**
* Fragment that displays personal and medical information.
*/
public class EditMedicalInfoFragment extends PreferenceFragment {
+
+ private EmergencyNamePreference mEmergencyNamePreference;
+
+ private static final String DIALOG_PREFERENCE_TAG = "dialog_preference";
+
@Override
public void onCreatePreferences(Bundle savedInstanceState, String rootKey) {
setPreferencesFromResource(R.xml.edit_medical_info, rootKey);
@@ -67,12 +75,16 @@ public class EditMedicalInfoFragment extends PreferenceFragment {
}
});
}
+
+ mEmergencyNamePreference = (EmergencyNamePreference) findPreference(
+ PreferenceKeys.KEY_NAME);
}
@Override
public void onResume() {
super.onResume();
reloadFromPreference();
+ mEmergencyNamePreference.reloadFromUserManager();
}
@Override
@@ -81,13 +93,13 @@ public class EditMedicalInfoFragment extends PreferenceFragment {
if (preference instanceof CustomEditTextPreference) {
fragment = CustomEditTextPreference.CustomPreferenceDialogFragment
.newInstance(preference.getKey());
- } else if (preference instanceof AutoCompleteEditTextPreference) {
- fragment = AutoCompleteEditTextPreference.AutoCompleteEditTextPreferenceDialogFragment
+ } else if (preference instanceof CustomDialogPreference) {
+ fragment = EmergencyNamePreference.EmergencyNamePreferenceDialogFragment
.newInstance(preference.getKey());
}
if (fragment != null) {
fragment.setTargetFragment(this, 0);
- fragment.show(getFragmentManager(), "dialog_preference");
+ fragment.show(getFragmentManager(), DIALOG_PREFERENCE_TAG);
} else {
super.onDisplayPreferenceDialog(preference);
}
diff --git a/src/com/android/emergency/preferences/EmergencyNamePreference.java b/src/com/android/emergency/preferences/EmergencyNamePreference.java
new file mode 100644
index 00000000..b6a754f0
--- /dev/null
+++ b/src/com/android/emergency/preferences/EmergencyNamePreference.java
@@ -0,0 +1,278 @@
+/*
+ * Copyright (C) 2018 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.emergency.preferences;
+
+import android.app.AlertDialog;
+import android.app.Fragment;
+import android.content.Context;
+import android.content.DialogInterface;
+import android.content.Intent;
+import android.graphics.Bitmap;
+import android.graphics.drawable.Drawable;
+import android.os.AsyncTask;
+import android.os.Bundle;
+import android.os.UserHandle;
+import android.os.UserManager;
+import android.text.TextUtils;
+import android.util.AttributeSet;
+import android.view.View;
+import android.widget.EditText;
+import android.widget.ImageView;
+import androidx.annotation.VisibleForTesting;
+import androidx.preference.DialogPreference;
+import com.android.emergency.CircleFramedDrawable;
+import com.android.emergency.R;
+import com.android.internal.util.UserIcons;
+import com.android.settingslib.CustomDialogPreference;
+
+import java.io.File;
+
+/**
+ * Custom {@link DialogPreference} that allows us to editing the user name and photo.
+ */
+public class EmergencyNamePreference extends CustomDialogPreference {
+
+ private static final String KEY_AWAITING_RESULT = "awaiting_result";
+ private static final String KEY_SAVED_PHOTO = "pending_photo";
+
+ private UserManager mUserManager = getContext().getSystemService(UserManager.class);
+ private EditUserPhotoController mEditUserPhotoController;
+ private Fragment mFragment;
+ private Bitmap mSavedPhoto;
+ private EditText mUserNameView;
+ private ImageView mUserPhotoView;
+ private boolean mWaitingForActivityResult = false;
+
+ public EmergencyNamePreference(Context context, AttributeSet attrs,
+ int defStyleAttr, int defStyleRes) {
+ super(context, attrs, defStyleAttr, defStyleRes);
+ setSummary(mUserManager.getUserName());
+ setIcon(getCircularUserIcon());
+ setDialogLayoutResource(R.layout.edit_user_info_dialog_content);
+ }
+
+ public EmergencyNamePreference(Context context, AttributeSet attrs, int defStyleAttr) {
+ this(context, attrs, defStyleAttr, 0);
+ }
+
+ public EmergencyNamePreference(Context context, AttributeSet attrs) {
+ this(context, attrs, R.attr.dialogPreferenceStyle);
+ }
+
+ public EmergencyNamePreference(Context context) {
+ this(context, null);
+ }
+
+ /**
+ * Setup fragment for Dialog and EditUserPhotoController.
+ */
+ public void setFragment(Fragment fragment) {
+ mFragment = fragment;
+ }
+
+ /**
+ * Reload user name and photo form UserManager.
+ */
+ public void reloadFromUserManager() {
+ setSummary(mUserManager.getUserName());
+ setIcon(getCircularUserIcon());
+ }
+
+ /**
+ * Restore user photo when EditUserPhotoController had pending photo.
+ */
+ 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);
+ }
+
+ /**
+ * Save a temp user photo when layout need to recreating but Dialog is showing.
+ */
+ public void onSaveInstanceState(Bundle outState) {
+ if (getDialog() != null && getDialog().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);
+ }
+ }
+
+ /**
+ * Set mWaitingForActivityResult to true when EmergencyNamePreferenceDialogFragment
+ * startActivityForResult, means we are waiting the activity result.
+ */
+ public void startingActivityForResult() {
+ mWaitingForActivityResult = true;
+ }
+
+ /**
+ * Reset mWaitingForActivityResult and send the result code to EditUserPhotoController when
+ * EmergencyNamePreferenceDialogFragment onActivityResult.
+ */
+ public void onActivityResult(int requestCode, int resultCode, Intent data) {
+ mWaitingForActivityResult = false;
+
+ if (getDialog() != null) {
+ mEditUserPhotoController.onActivityResult(requestCode, resultCode, data);
+ }
+ }
+
+ @Override
+ protected void onBindDialogView(View view) {
+ super.onBindDialogView(view);
+
+ mUserNameView = view.findViewById(R.id.user_name);
+ mUserNameView.setText(mUserManager.getUserName());
+ mUserPhotoView = view.findViewById(R.id.user_photo);
+ Drawable drawable;
+ if (mSavedPhoto != null) {
+ drawable = CircleFramedDrawable.getInstance(getContext(), mSavedPhoto);
+ } else {
+ drawable = getCircularUserIcon();
+ }
+ mUserPhotoView.setImageDrawable(drawable);
+
+ mEditUserPhotoController = createEditUserPhotoController(mUserPhotoView,
+ getCircularUserIcon());
+ }
+
+ @Override
+ protected void onPrepareDialogBuilder(AlertDialog.Builder builder,
+ DialogInterface.OnClickListener listener) {
+ super.onPrepareDialogBuilder(builder, listener);
+ builder.setTitle(R.string.name)
+ .setCancelable(true)
+ .setPositiveButton(android.R.string.ok, listener)
+ .setNegativeButton(android.R.string.cancel, listener)
+ .create();
+ }
+
+ @Override
+ protected void onDialogClosed(boolean positiveResult) {
+ super.onDialogClosed(positiveResult);
+ if (positiveResult) {
+ // Update the name if changed.
+ CharSequence userName = mUserNameView.getText();
+ if (!TextUtils.isEmpty(userName)) {
+ if (mUserManager.getUserName() == null
+ || !userName.toString().equals(mUserManager.getUserName())) {
+ mUserManager.setUserName(UserHandle.myUserId(), userName.toString());
+ setSummary(userName);
+ }
+ }
+ // Update the photo if changed.
+ Drawable drawable = mEditUserPhotoController.getNewUserPhotoDrawable();
+ Bitmap bitmap = mEditUserPhotoController.getNewUserPhotoBitmap();
+ if (drawable != null && bitmap != null
+ && !drawable.equals(getCircularUserIcon())) {
+ new AsyncTask<Void, Void, Void>() {
+ @Override
+ protected Void doInBackground(Void... params) {
+ mUserManager.setUserIcon(UserHandle.myUserId(),
+ mEditUserPhotoController.getNewUserPhotoBitmap());
+ return null;
+ }
+ }.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR, (Void[]) null);
+ setIcon(drawable);
+ }
+ if (mFragment != null) {
+ mFragment.getActivity().removeDialog(1);
+ }
+ }
+ clear();
+ }
+
+ private void clear() {
+ mEditUserPhotoController.removeNewUserPhotoBitmapFile();
+ mSavedPhoto = null;
+ }
+
+ private Drawable getCircularUserIcon() {
+ Bitmap bitmapUserIcon = mUserManager.getUserIcon(UserHandle.myUserId());
+
+ if (bitmapUserIcon == null) {
+ // get default user icon.
+ final Drawable defaultUserIcon = UserIcons.getDefaultUserIcon(
+ getContext().getResources(), UserHandle.myUserId(), false);
+ bitmapUserIcon = UserIcons.convertToBitmap(defaultUserIcon);
+ }
+ Drawable drawableUserIcon = new CircleFramedDrawable(bitmapUserIcon,
+ (int) getContext().getResources().getDimension(R.dimen.circle_avatar_size));
+
+ return drawableUserIcon;
+ }
+
+ @VisibleForTesting
+ EditUserPhotoController createEditUserPhotoController(ImageView userPhotoView,
+ Drawable drawable) {
+ return new EditUserPhotoController(mFragment, userPhotoView,
+ mSavedPhoto, drawable, mWaitingForActivityResult);
+ }
+
+ public static class EmergencyNamePreferenceDialogFragment extends
+ CustomPreferenceDialogFragment {
+
+ public static CustomDialogPreference.CustomPreferenceDialogFragment newInstance(
+ String key) {
+ final CustomDialogPreference.CustomPreferenceDialogFragment
+ fragment = new EmergencyNamePreferenceDialogFragment();
+ final Bundle b = new Bundle(1 /* capacity */);
+ b.putString(ARG_KEY, key);
+ fragment.setArguments(b);
+ return fragment;
+ }
+
+ private EmergencyNamePreference getEmergencyNamePreference() {
+ return (EmergencyNamePreference) getPreference();
+ }
+
+ @Override
+ public void onCreate(Bundle icicle) {
+ super.onCreate(icicle);
+ getEmergencyNamePreference().setFragment(this);
+ if (icicle != null) {
+ getEmergencyNamePreference().onRestoreInstanceState(icicle);
+ }
+ }
+
+ @Override
+ public void onSaveInstanceState(Bundle outState) {
+ super.onSaveInstanceState(outState);
+ getEmergencyNamePreference().onSaveInstanceState(outState);
+ }
+
+ @Override
+ public void onActivityResult(int requestCode, int resultCode, Intent data) {
+ getEmergencyNamePreference().onActivityResult(requestCode, resultCode, data);
+ }
+
+ @Override
+ public void startActivityForResult(Intent intent, int requestCode) {
+ getEmergencyNamePreference().startingActivityForResult();
+ super.startActivityForResult(intent, requestCode);
+ }
+ }
+}