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