• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2020 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  */
16 
17 package com.android.emergency.action;
18 
19 import android.app.Activity;
20 import android.content.Context;
21 import android.content.Intent;
22 import android.content.res.Configuration;
23 import android.os.Bundle;
24 import android.os.CountDownTimer;
25 import android.support.v4.app.Fragment;
26 import android.telecom.TelecomManager;
27 import android.util.DisplayMetrics;
28 import android.util.Log;
29 import android.view.LayoutInflater;
30 import android.view.View;
31 import android.view.ViewGroup;
32 import android.widget.TextView;
33 
34 import androidx.annotation.NonNull;
35 import androidx.annotation.Nullable;
36 
37 import com.android.emergency.R;
38 import com.android.emergency.action.broadcast.EmergencyActionBroadcastReceiver;
39 import com.android.emergency.action.sensoryfeedback.EmergencyActionAlarmHelper;
40 import com.android.emergency.action.service.EmergencyActionForegroundService;
41 import com.android.emergency.widgets.countdown.CountDownAnimationView;
42 import com.android.emergency.widgets.slider.OnSlideCompleteListener;
43 import com.android.emergency.widgets.slider.SliderView;
44 import com.android.settingslib.emergencynumber.EmergencyNumberUtils;
45 
46 import java.time.Duration;
47 
48 public class EmergencyActionFragment extends Fragment implements OnSlideCompleteListener {
49 
50     private static final String TAG = "EmergencyActionFrag";
51     private static final String STATE_MILLIS_LEFT = "STATE_MILLIS_LEFT";
52 
53     private EmergencyActionAlarmHelper mEmergencyActionAlarmHelper;
54     private TelecomManager mTelecomManager;
55     private CountDownTimer mCountDownTimer;
56     private EmergencyNumberUtils mEmergencyNumberUtils;
57     private long mCountDownMillisLeft;
58 
59     private boolean mCountdownCancelled;
60     private boolean mCountdownFinished;
61 
62     @Override
onAttach(Context context)63     public void onAttach(Context context) {
64         super.onAttach(context);
65         EmergencyActionForegroundService.stopService(context);
66         mEmergencyActionAlarmHelper = new EmergencyActionAlarmHelper(context);
67         mEmergencyNumberUtils = new EmergencyNumberUtils(context);
68         mTelecomManager = context.getSystemService(TelecomManager.class);
69     }
70 
71     @Override
onCreateView(@onNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState)72     public View onCreateView(@NonNull LayoutInflater inflater,
73             @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
74 
75         // Ignore the larger font scale if users set it in general system settings since we already
76         // have relatively large font size on this page, and we need to display all content on one
77         // page without scrolling.
78         Configuration configuration = getResources().getConfiguration();
79         if (configuration.fontScale > 1) {
80             configuration.fontScale = (float) 1;
81 
82             DisplayMetrics metrics = new DisplayMetrics();
83             metrics.scaledDensity = configuration.fontScale * metrics.density;
84             configuration.densityDpi = (int) getResources().getDisplayMetrics().xdpi;
85         }
86 
87         View view = inflater.cloneInContext(getContext().createConfigurationContext(configuration))
88                 .inflate(R.layout.emergency_action_fragment, container, false);
89 
90         TextView subtitleView = view.findViewById(R.id.subtitle);
91         subtitleView.setText(getString(R.string.emergency_action_subtitle,
92                 mEmergencyNumberUtils.getPoliceNumber()));
93 
94         SliderView cancelButton = view.findViewById(R.id.btn_cancel);
95         cancelButton.setSlideCompleteListener(this);
96 
97         if (savedInstanceState != null) {
98             mCountDownMillisLeft = savedInstanceState.getLong(STATE_MILLIS_LEFT);
99         } else {
100             Activity activity = getActivity();
101             Intent intent = null;
102             if (activity != null) {
103                 intent = activity.getIntent();
104             }
105             if (intent != null) {
106                 mCountDownMillisLeft = intent.getLongExtra(STATE_MILLIS_LEFT,
107                         getResources().getInteger(R.integer.emergency_action_count_down_millis));
108             } else {
109                 mCountDownMillisLeft =
110                         getResources().getInteger(R.integer.emergency_action_count_down_millis);
111             }
112         }
113 
114         return view;
115     }
116 
117     @Override
onStart()118     public void onStart() {
119         super.onStart();
120         startTimer();
121         mEmergencyActionAlarmHelper.playWarningSound();
122     }
123 
124     @Override
onSaveInstanceState(Bundle outState)125     public void onSaveInstanceState(Bundle outState) {
126         super.onSaveInstanceState(outState);
127         outState.putLong(STATE_MILLIS_LEFT, mCountDownMillisLeft);
128     }
129 
130     @Override
onStop()131     public void onStop() {
132         super.onStop();
133 
134         if (mCountDownTimer != null) {
135             CountDownAnimationView countDownAnimationView =
136                     getView().findViewById(R.id.count_down_view);
137             countDownAnimationView.stop();
138             mCountDownTimer.cancel();
139         }
140 
141         mEmergencyActionAlarmHelper.stopWarningSound();
142         if (!mCountdownCancelled && !mCountdownFinished) {
143             Log.d(TAG,
144                     "Emergency countdown UI dismissed without being cancelled/finished, "
145                             + "continuing countdown in background");
146 
147             Context context = getContext();
148             context.startService(
149                     EmergencyActionForegroundService.newStartCountdownIntent(
150                             context,
151                             mCountDownMillisLeft,
152                             mEmergencyActionAlarmHelper.getUserSetAlarmVolume()));
153         }
154     }
155 
156     @Override
onSlideComplete()157     public void onSlideComplete() {
158         mCountdownCancelled = true;
159         EmergencyActionForegroundService.stopService(getActivity());
160         getActivity().finish();
161     }
162 
startTimer()163     private void startTimer() {
164         CountDownAnimationView countDownAnimationView =
165                 getView().findViewById(R.id.count_down_view);
166 
167         if (mCountDownTimer != null) {
168             countDownAnimationView.stop();
169             mCountDownTimer.cancel();
170         }
171 
172         mCountDownTimer =
173                 new CountDownTimer(
174                         mCountDownMillisLeft,
175                         getResources().getInteger(R.integer.emergency_action_count_down_interval)) {
176                     @Override
177                     public void onTick(long millisUntilFinished) {
178                         CountDownAnimationView countDownAnimationView =
179                                 getView().findViewById(R.id.count_down_view);
180                         if (countDownAnimationView != null) {
181                             countDownAnimationView.setCountDownLeft(
182                                     Duration.ofMillis(millisUntilFinished));
183                         }
184 
185                         mCountDownMillisLeft = millisUntilFinished;
186                     }
187 
188                     @Override
189                     public void onFinish() {
190                         mCountdownFinished = true;
191                         Intent broadcast =
192                                 EmergencyActionBroadcastReceiver.newCallEmergencyIntent(
193                                         getContext());
194                         Activity activity = getActivity();
195                         activity.sendBroadcast(broadcast);
196                         activity.finish();
197                     }
198                 };
199 
200         mCountDownTimer.start();
201 
202         countDownAnimationView.start(Duration.ofMillis(mCountDownMillisLeft));
203         countDownAnimationView.showCountDown();
204     }
205 }
206