blob: eea27e2cfa85c77ef2bbdf0d5e19229d3bea07fa [file] [log] [blame]
Akshay Kannancdb6c142016-01-20 18:25:44 -08001/*
2 * Copyright (C) 2016 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
mariagpuyol58748352016-03-09 15:36:28 -080016package com.android.emergency.preferences;
Akshay Kannancdb6c142016-01-20 18:25:44 -080017
Akshay Kannan44ef39d2016-01-26 09:08:41 -080018import android.app.AlertDialog;
Akshay Kannancdb6c142016-01-20 18:25:44 -080019import android.content.Context;
mariagpuyold19ace52016-02-12 10:37:26 -080020import android.content.DialogInterface;
Akshay Kannancdb6c142016-01-20 18:25:44 -080021import android.content.Intent;
mariagpuyol95dc0402016-02-17 11:12:46 -080022import android.graphics.drawable.Drawable;
Akshay Kannancdb6c142016-01-20 18:25:44 -080023import android.net.Uri;
mariagpuyol53745bf2016-03-23 14:43:55 -070024import android.os.Bundle;
25import android.os.Parcel;
26import android.os.Parcelable;
Akshay Kannancdb6c142016-01-20 18:25:44 -080027import android.preference.Preference;
mariagpuyolaee23782016-02-16 13:29:49 -080028import android.support.annotation.NonNull;
mariagpuyol16472ca2016-02-16 17:49:26 -080029import android.support.annotation.Nullable;
mariagpuyold19ace52016-02-12 10:37:26 -080030import android.view.View;
mariagpuyold19ace52016-02-12 10:37:26 -080031
mariagpuyol58748352016-03-09 15:36:28 -080032import com.android.emergency.EmergencyContactManager;
mariagpuyol58748352016-03-09 15:36:28 -080033import com.android.emergency.R;
mariagpuyol53745bf2016-03-23 14:43:55 -070034import com.android.emergency.ReloadablePreferenceInterface;
Akshay Kannan44ef39d2016-01-26 09:08:41 -080035import com.android.internal.logging.MetricsLogger;
36import com.android.internal.logging.MetricsProto.MetricsEvent;
mariagpuyol9be32652016-03-16 12:34:53 -070037import com.android.settingslib.drawable.CircleFramedDrawable;
Akshay Kannan44ef39d2016-01-26 09:08:41 -080038
Akshay Kannancdb6c142016-01-20 18:25:44 -080039
40/**
mariagpuyol5cf7f732016-03-08 09:48:15 -080041 * A {@link Preference} to display or call a contact using the specified URI string.
Akshay Kannancdb6c142016-01-20 18:25:44 -080042 */
43public class ContactPreference extends Preference {
44
mariagpuyol53745bf2016-03-23 14:43:55 -070045 private EmergencyContactManager.Contact mContact;
mariagpuyol609f68a2016-02-22 17:45:47 -080046 @Nullable private RemoveContactPreferenceListener mRemoveContactPreferenceListener;
mariagpuyol53745bf2016-03-23 14:43:55 -070047 @Nullable private AlertDialog mRemoveContactDialog;
mariagpuyold19ace52016-02-12 10:37:26 -080048
49 /**
mariagpuyol609f68a2016-02-22 17:45:47 -080050 * Listener for removing a contact.
mariagpuyold19ace52016-02-12 10:37:26 -080051 */
mariagpuyol609f68a2016-02-22 17:45:47 -080052 public interface RemoveContactPreferenceListener {
mariagpuyold19ace52016-02-12 10:37:26 -080053 /**
mariagpuyol609f68a2016-02-22 17:45:47 -080054 * Callback to remove a contact preference.
mariagpuyold19ace52016-02-12 10:37:26 -080055 */
mariagpuyol609f68a2016-02-22 17:45:47 -080056 void onRemoveContactPreference(ContactPreference preference);
mariagpuyold19ace52016-02-12 10:37:26 -080057 }
Akshay Kannancdb6c142016-01-20 18:25:44 -080058
59 /**
60 * Instantiates a ContactPreference that displays an emergency contact, taking in a Context and
mariagpuyol5cf7f732016-03-08 09:48:15 -080061 * the Uri.
Akshay Kannancdb6c142016-01-20 18:25:44 -080062 */
mariagpuyol5cf7f732016-03-08 09:48:15 -080063 public ContactPreference(Context context, @NonNull Uri contactUri) {
Akshay Kannancdb6c142016-01-20 18:25:44 -080064 super(context);
mariagpuyol609f68a2016-02-22 17:45:47 -080065 setOrder(DEFAULT_ORDER);
mariagpuyol53745bf2016-03-23 14:43:55 -070066
67 setUri(contactUri);
68
69 setWidgetLayoutResource(R.layout.preference_user_delete_widget);
70 setPersistent(false);
71 }
72
73 public void setUri(@NonNull Uri contactUri) {
74 if (mContact != null && !contactUri.equals(mContact.getContactUri()) &&
75 mRemoveContactDialog != null) {
76 mRemoveContactDialog.dismiss();
77 }
78
79 mContact = EmergencyContactManager.getContact(getContext(), contactUri);
80
mariagpuyol5cf7f732016-03-08 09:48:15 -080081 setTitle(mContact.getName());
mariagpuyol53745bf2016-03-23 14:43:55 -070082 setKey(mContact.getContactUri().toString());
mariagpuyolf9ab89a2016-03-10 09:19:07 -080083 String summary = mContact.getPhoneType() == null ?
84 mContact.getPhoneNumber() :
85 String.format(
mariagpuyol53745bf2016-03-23 14:43:55 -070086 getContext().getResources().getString(R.string.phone_type_and_phone_number),
mariagpuyolf9ab89a2016-03-10 09:19:07 -080087 mContact.getPhoneType(),
88 mContact.getPhoneNumber());
89 setSummary(summary);
mariagpuyol53745bf2016-03-23 14:43:55 -070090
91 // Update the message to show the correct name.
92 if (mRemoveContactDialog != null) {
93 mRemoveContactDialog.setMessage(
94 String.format(getContext().getString(R.string.remove_contact),
95 mContact.getName()));
96 }
mariagpuyol95dc0402016-02-17 11:12:46 -080097
98 //TODO: Consider doing the following in a non-UI thread.
mariagpuyol9be32652016-03-16 12:34:53 -070099 Drawable icon;
100 if (mContact.getPhoto() != null) {
101 icon = new CircleFramedDrawable(mContact.getPhoto(),
mariagpuyol53745bf2016-03-23 14:43:55 -0700102 (int) getContext().getResources().getDimension(R.dimen.circle_avatar_size));
mariagpuyol9be32652016-03-16 12:34:53 -0700103 } else {
mariagpuyol53745bf2016-03-23 14:43:55 -0700104 icon = getContext().getResources().getDrawable(R.drawable.ic_person_black_24dp);
mariagpuyol9be32652016-03-16 12:34:53 -0700105 }
mariagpuyol95dc0402016-02-17 11:12:46 -0800106 setIcon(icon);
107 }
108
mariagpuyol609f68a2016-02-22 17:45:47 -0800109 /** Listener to be informed when a contact preference should be deleted. */
110 public void setRemoveContactPreferenceListener(
111 RemoveContactPreferenceListener removeContactListener) {
112 mRemoveContactPreferenceListener = removeContactListener;
mariagpuyol53745bf2016-03-23 14:43:55 -0700113 if (mRemoveContactPreferenceListener == null) {
114 mRemoveContactDialog = null;
115 return;
116 }
117 if (mRemoveContactDialog != null) {
118 return;
119 }
120 // Create the remove contact dialog
121 AlertDialog.Builder builder = new AlertDialog.Builder(getContext());
122 builder.setNegativeButton(getContext().getString(R.string.cancel), null);
123 builder.setPositiveButton(getContext().getString(R.string.remove),
124 new DialogInterface.OnClickListener() {
125 @Override
126 public void onClick(DialogInterface dialogInterface,
127 int which) {
128 if (mRemoveContactPreferenceListener != null) {
129 mRemoveContactPreferenceListener
130 .onRemoveContactPreference(ContactPreference.this);
131 }
132 }
133 });
134 builder.setMessage(String.format(getContext().getString(R.string.remove_contact),
135 mContact.getName()));
136 mRemoveContactDialog = builder.create();
mariagpuyol609f68a2016-02-22 17:45:47 -0800137 }
138
mariagpuyold19ace52016-02-12 10:37:26 -0800139 @Override
140 protected void onBindView(View view) {
141 super.onBindView(view);
142 View deleteContactIcon = view.findViewById(R.id.delete_contact);
mariagpuyol609f68a2016-02-22 17:45:47 -0800143 if (mRemoveContactPreferenceListener == null) {
mariagpuyol16472ca2016-02-16 17:49:26 -0800144 deleteContactIcon.setVisibility(View.GONE);
145 } else {
mariagpuyol609f68a2016-02-22 17:45:47 -0800146 deleteContactIcon.setOnClickListener(new View.OnClickListener() {
147 @Override
148 public void onClick(View view) {
mariagpuyol53745bf2016-03-23 14:43:55 -0700149 showRemoveContactDialog(null);
mariagpuyol609f68a2016-02-22 17:45:47 -0800150 }
151 });
152
mariagpuyold19ace52016-02-12 10:37:26 -0800153 }
Akshay Kannancdb6c142016-01-20 18:25:44 -0800154 }
155
mariagpuyol609f68a2016-02-22 17:45:47 -0800156 public Uri getContactUri() {
mariagpuyol5cf7f732016-03-08 09:48:15 -0800157 return mContact.getContactUri();
mariagpuyol609f68a2016-02-22 17:45:47 -0800158 }
159
Akshay Kannancdb6c142016-01-20 18:25:44 -0800160 /**
Akshay Kannan44ef39d2016-01-26 09:08:41 -0800161 * Calls the contact.
162 */
mariagpuyol5cf7f732016-03-08 09:48:15 -0800163 public void callContact() {
164 Intent callIntent =
165 new Intent(Intent.ACTION_CALL, Uri.parse("tel:" + mContact.getPhoneNumber()));
166 MetricsLogger.action(getContext(), MetricsEvent.ACTION_CALL_EMERGENCY_CONTACT);
167 getContext().startActivity(callIntent);
mariagpuyol0504a442016-02-17 16:22:57 -0800168 }
mariagpuyol36b3f9d2016-03-11 16:02:31 -0800169
170 /**
171 * Displays a contact card for the contact.
172 */
173 public void displayContact() {
174 Intent contactIntent = new Intent(Intent.ACTION_VIEW);
175 contactIntent.setData(mContact.getContactLookupUri());
176 getContext().startActivity(contactIntent);
177 }
mariagpuyol53745bf2016-03-23 14:43:55 -0700178
179 /** Shows the dialog to remove the contact, restoring it from {@code state} if it's not null. */
180 private void showRemoveContactDialog(Bundle state) {
181 if (mRemoveContactDialog == null) {
182 return;
183 }
184 if (state != null) {
185 mRemoveContactDialog.onRestoreInstanceState(state);
186 }
187 mRemoveContactDialog.show();
188 }
189
190 @Override
191 protected Parcelable onSaveInstanceState() {
192 final Parcelable superState = super.onSaveInstanceState();
193 if (mRemoveContactDialog == null || !mRemoveContactDialog.isShowing()) {
194 return superState;
195 }
196 final SavedState myState = new SavedState(superState);
197 myState.isDialogShowing = true;
198 myState.dialogBundle = mRemoveContactDialog.onSaveInstanceState();
199 return myState;
200 }
201
202 @Override
203 protected void onRestoreInstanceState(Parcelable state) {
204 if (state == null || !state.getClass().equals(SavedState.class)) {
205 // Didn't save state for us in onSaveInstanceState
206 super.onRestoreInstanceState(state);
207 return;
208 }
209 SavedState myState = (SavedState) state;
210 super.onRestoreInstanceState(myState.getSuperState());
211 if (myState.isDialogShowing) {
212 showRemoveContactDialog(myState.dialogBundle);
213 }
214 }
215
216 private static class SavedState extends BaseSavedState {
217 boolean isDialogShowing;
218 Bundle dialogBundle;
219
220 public SavedState(Parcel source) {
221 super(source);
222 isDialogShowing = source.readInt() == 1;
223 dialogBundle = source.readBundle();
224 }
225
226 @Override
227 public void writeToParcel(Parcel dest, int flags) {
228 super.writeToParcel(dest, flags);
229 dest.writeInt(isDialogShowing ? 1 : 0);
230 dest.writeBundle(dialogBundle);
231 }
232
233 public SavedState(Parcelable superState) {
234 super(superState);
235 }
236
237 public static final Parcelable.Creator<SavedState> CREATOR =
238 new Parcelable.Creator<SavedState>() {
239 public SavedState createFromParcel(Parcel in) {
240 return new SavedState(in);
241 }
242
243 public SavedState[] newArray(int size) {
244 return new SavedState[size];
245 }
246 };
247 }
mariagpuyolbc6555b2016-02-26 15:38:19 -0800248}