EditInfoActivity.java revision ded933edeaa516bc92b238c5244040a760a7f99b
1/* 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 */ 16package com.android.emergency.edit; 17 18import static android.view.WindowManager.LayoutParams.FLAG_DISMISS_KEYGUARD; 19 20import android.app.AlertDialog; 21import android.app.Dialog; 22import android.app.DialogFragment; 23import android.app.Fragment; 24import android.app.FragmentTransaction; 25import android.content.ComponentName; 26import android.content.DialogInterface; 27import android.content.Intent; 28import android.content.pm.PackageManager; 29import android.os.Bundle; 30import android.preference.PreferenceManager; 31import android.util.Pair; 32import android.view.Menu; 33import android.view.MenuInflater; 34import android.view.MenuItem; 35 36import com.android.emergency.EmergencyTabActivity; 37import com.android.emergency.R; 38import com.android.emergency.view.ViewEmergencyContactsFragment; 39import com.android.emergency.view.ViewInfoActivity; 40import com.android.internal.logging.MetricsLogger; 41import com.android.internal.logging.MetricsProto.MetricsEvent; 42 43import java.util.ArrayList; 44 45/** 46 * Activity for editing emergency information. 47 */ 48public class EditInfoActivity extends EmergencyTabActivity { 49 private static final String TAG_WARNING_DIALOG = "warning_dialog"; 50 private static final String TAG_CLEAR_ALL_DIALOG = "clear_all_dialog"; 51 private static final String KEY_LAST_CONSENT_TIME_MS = "last_consent_time_ms"; 52 private static final long ONE_DAY_MS = 24 * 60 * 60 * 1000; 53 private static final String ACTION_EDIT_EMERGENCY_CONTACTS = 54 "android.emergency.EDIT_EMERGENCY_CONTACTS"; 55 private static final String ACTION_USER_SETTINGS = "android.settings.USER_SETTINGS"; 56 57 @Override 58 protected void onCreate(Bundle savedInstanceState) { 59 super.onCreate(savedInstanceState); 60 setContentView(R.layout.edit_activity_layout); 61 62 // savedInstanceState is null on first start and non-null on restart. 63 // We want to show the dialog on first start, even if there is a screen rotation but avoid 64 // reshowing it if a rotation occurs (which causes onCreate to be called again, but this 65 // time with savedInstanceState!=null). 66 if (savedInstanceState == null) { 67 long lastConsentTimeMs = PreferenceManager.getDefaultSharedPreferences(this) 68 .getLong(KEY_LAST_CONSENT_TIME_MS, Long.MAX_VALUE); 69 long nowMs = System.currentTimeMillis(); 70 // Check if at least one day has gone by since the user last gave his constant or if 71 // the last consent was in the future (e.g. if the user changed the date). 72 if (nowMs - lastConsentTimeMs > ONE_DAY_MS || lastConsentTimeMs > nowMs) { 73 showWarningDialog(); 74 } 75 } 76 77 if (ACTION_EDIT_EMERGENCY_CONTACTS.equals(getIntent().getAction())) { 78 // Select emergency contacts tab 79 selectTab(1); 80 } 81 82 getWindow().addFlags(FLAG_DISMISS_KEYGUARD); 83 MetricsLogger.visible(this, MetricsEvent.ACTION_EDIT_EMERGENCY_INFO); 84 } 85 86 @Override 87 public void onPause() { 88 super.onPause(); 89 90 // Enable ViewInfoActivity if the user input some info. Otherwise, disable it. 91 PackageManager pm = getPackageManager(); 92 if (ViewEmergencyContactsFragment.hasAtLeastOneEmergencyContact(this) 93 || EditEmergencyInfoFragment.hasAtLeastOnePreferenceSet(this)) { 94 pm.setComponentEnabledSetting(new ComponentName(this, ViewInfoActivity.class), 95 PackageManager.COMPONENT_ENABLED_STATE_ENABLED, PackageManager.DONT_KILL_APP); 96 } else { 97 pm.setComponentEnabledSetting(new ComponentName(this, ViewInfoActivity.class), 98 PackageManager.COMPONENT_ENABLED_STATE_DISABLED, PackageManager.DONT_KILL_APP); 99 } 100 } 101 102 @Override 103 public boolean onCreateOptionsMenu(Menu menu) { 104 MenuInflater inflater = getMenuInflater(); 105 inflater.inflate(R.menu.edit_info_menu, menu); 106 return true; 107 } 108 109 @Override 110 public boolean onOptionsItemSelected(MenuItem item) { 111 switch (item.getItemId()) { 112 case R.id.action_clear_all: 113 showClearAllDialog(); 114 return true; 115 case android.R.id.home: 116 Intent intent = new Intent(ACTION_USER_SETTINGS); 117 intent.addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP); 118 navigateUpTo(intent); 119 return true; 120 } 121 return super.onOptionsItemSelected(item); 122 } 123 124 @Override 125 protected ArrayList<Pair<String, Fragment>> setUpFragments() { 126 // Always return the two fragments in edit mode. 127 ArrayList<Pair<String, Fragment>> fragments = new ArrayList<>(2); 128 fragments.add(Pair.create(getResources().getString(R.string.tab_title_info), 129 EditEmergencyInfoFragment.newInstance())); 130 fragments.add(Pair.create(getResources().getString(R.string.tab_title_contacts), 131 EditEmergencyContactsFragment.newInstance())); 132 return fragments; 133 } 134 135 private void showWarningDialog() { 136 // DialogFragment.show() will take care of adding the fragment 137 // in a transaction. We also want to remove any currently showing 138 // dialog, so make our own transaction and take care of that here. 139 FragmentTransaction ft = getFragmentManager().beginTransaction(); 140 Fragment previousDialog = getFragmentManager().findFragmentByTag(TAG_WARNING_DIALOG); 141 if (previousDialog != null) { 142 ft.remove(previousDialog); 143 } 144 ft.addToBackStack(null); 145 146 DialogFragment newFragment = WarningDialogFragment.newInstance(); 147 newFragment.setCancelable(false); 148 newFragment.show(ft, TAG_WARNING_DIALOG); 149 } 150 151 private void showClearAllDialog() { 152 // DialogFragment.show() will take care of adding the fragment 153 // in a transaction. We also want to remove any currently showing 154 // dialog, so make our own transaction and take care of that here. 155 FragmentTransaction ft = getFragmentManager().beginTransaction(); 156 Fragment previousDialog = getFragmentManager().findFragmentByTag(TAG_CLEAR_ALL_DIALOG); 157 if (previousDialog != null) { 158 ft.remove(previousDialog); 159 } 160 ft.addToBackStack(null); 161 162 DialogFragment newFragment = ClearAllDialogFragment.newInstance(); 163 newFragment.show(ft, TAG_CLEAR_ALL_DIALOG); 164 } 165 166 private void onClearAllPreferences() { 167 PreferenceManager.getDefaultSharedPreferences(this).edit().clear().apply(); 168 169 ArrayList<Pair<String, Fragment>> fragments = getFragments(); 170 EditEmergencyInfoFragment editEmergencyInfoFragment = 171 (EditEmergencyInfoFragment) fragments.get(0).second; 172 editEmergencyInfoFragment.reloadFromPreference(); 173 EditEmergencyContactsFragment editEmergencyContactsFragment = 174 (EditEmergencyContactsFragment) fragments.get(1).second; 175 editEmergencyContactsFragment.reloadFromPreference(); 176 } 177 178 /** 179 * Warning dialog shown to the user each time they go in to the edit info view. Using a {@link 180 * DialogFragment} takes care of screen rotation issues. 181 */ 182 public static class WarningDialogFragment extends DialogFragment { 183 @Override 184 public Dialog onCreateDialog(Bundle savedInstanceState) { 185 Dialog dialog = new AlertDialog.Builder(getActivity()) 186 .setTitle(R.string.user_emergency_info_title) 187 .setMessage(R.string.user_emergency_info_consent) 188 .setPositiveButton(R.string.emergency_info_continue, 189 new DialogInterface.OnClickListener() { 190 @Override 191 public void onClick(DialogInterface dialog, int which) { 192 PreferenceManager.getDefaultSharedPreferences( 193 getActivity()).edit() 194 .putLong(KEY_LAST_CONSENT_TIME_MS, 195 System.currentTimeMillis()).apply(); 196 } 197 }) 198 .setNegativeButton(android.R.string.cancel, 199 new DialogInterface.OnClickListener() { 200 @Override 201 public void onClick(DialogInterface dialog, int which) { 202 getActivity().finish(); 203 } 204 }) 205 .create(); 206 dialog.setCanceledOnTouchOutside(false); 207 return dialog; 208 } 209 210 public static DialogFragment newInstance() { 211 return new WarningDialogFragment(); 212 } 213 } 214 215 /** 216 * Dialog shown to the user when they tap on the CLEAR ALL menu item. Using a {@link 217 * DialogFragment} takes care of screen rotation issues. 218 */ 219 public static class ClearAllDialogFragment extends DialogFragment { 220 221 @Override 222 public Dialog onCreateDialog(Bundle savedInstanceState) { 223 Dialog dialog = new AlertDialog.Builder(getActivity()) 224 .setMessage(R.string.clear_all_message) 225 .setPositiveButton(R.string.clear, new DialogInterface.OnClickListener() { 226 @Override 227 public void onClick(DialogInterface dialog, int which) { 228 ((EditInfoActivity) getActivity()).onClearAllPreferences(); 229 } 230 }) 231 .setNegativeButton(android.R.string.cancel, null) 232 .create(); 233 return dialog; 234 } 235 236 public static DialogFragment newInstance() { 237 return new ClearAllDialogFragment(); 238 } 239 } 240} 241