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