Merge "Add a setting to overrid emergency number for Emergency SOS"

This commit is contained in:
Fan Zhang
2020-11-19 18:53:00 +00:00
committed by Android (Google) Code Review
7 changed files with 407 additions and 0 deletions

View File

@@ -0,0 +1,25 @@
<!--
~ Copyright (C) 2020 The Android Open Source Project
~
~ Licensed under the Apache License, Version 2.0 (the "License");
~ you may not use this file except in compliance with the License.
~ You may obtain a copy of the License at
~
~ http://www.apache.org/licenses/LICENSE-2.0
~
~ Unless required by applicable law or agreed to in writing, software
~ distributed under the License is distributed on an "AS IS" BASIS,
~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
~ See the License for the specific language governing permissions and
~ limitations under the License.
-->
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportWidth="24"
android:viewportHeight="24">
<path
android:pathData="M16.02,14.46l-2.62,2.62c-2.75,-1.49 -5.01,-3.75 -6.5,-6.5l2.62,-2.62c0.24,-0.24 0.34,-0.58 0.27,-0.9L9.15,3.8c-0.1,-0.46 -0.51,-0.8 -0.98,-0.8H4.02c-0.56,0 -1.03,0.47 -1,1.03 0.17,2.91 1.04,5.63 2.43,8.01 1.57,2.69 3.81,4.93 6.5,6.5 2.38,1.39 5.1,2.26 8.01,2.43 0.56,0.03 1.03,-0.44 1.03,-1v-4.15c0,-0.48 -0.34,-0.89 -0.8,-0.98l-3.26,-0.65c-0.33,-0.07 -0.67,0.04 -0.91,0.27z"
android:fillColor="#455A64"/>
</vector>

View File

@@ -0,0 +1,57 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
~ Copyright (C) 2020 The Android Open Source Project
~
~ Licensed under the Apache License, Version 2.0 (the "License");
~ you may not use this file except in compliance with the License.
~ You may obtain a copy of the License at
~
~ http://www.apache.org/licenses/LICENSE-2.0
~
~ Unless required by applicable law or agreed to in writing, software
~ distributed under the License is distributed on an "AS IS" BASIS,
~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
~ See the License for the specific language governing permissions and
~ limitations under the License.
-->
<ScrollView
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:paddingHorizontal="24dp"
android:paddingVertical="8dp">
<EditText
android:id="@+id/emergency_gesture_number_override"
android:imeOptions="actionDone"
android:inputType="numberSigned"
android:layout_width="match_parent"
android:layout_height="wrap_content"/>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="16dp"
android:orientation="horizontal">
<ImageView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:paddingEnd="16dp"
android:importantForAccessibility="no"
android:src="@drawable/ic_info_outline_24"/>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/emergency_gesture_number_override_notes"/>
</LinearLayout>
</LinearLayout>
</ScrollView>

View File

@@ -11084,6 +11084,22 @@
<!-- Preference summary to enable generating noisy sound before calling emergency services at panic/distress moments[CHAR_LIMIT=NONE]-->
<string name="emergency_gesture_sound_setting_summary">Play a loud sound before calling</string>
<!-- Preference title listing a phone number to call during emergency gesture [CHAR_LIMIT=60]-->
<string name="emergency_gesture_call_for_help_title">Call for help</string>
<!-- Preference title listing a phone number to call during emergency gesture [CHAR_LIMIT=NONE]-->
<string name="emergency_gesture_call_for_help_dialog_title">Number to call for help</string>
<!-- Preference summary listing a phone number to call during emergency gesture, and clicking the perference will show a dialog to change this number [CHAR_LIMIT=NONE]-->
<string name="emergency_gesture_call_for_help_summary"><xliff:g id="phone_number" example="911">%1$s</xliff:g>. Tap to change</string>
<!-- Notes explaining limitations for emergency gesture number override [CHAR_LIMIT=NONE]-->
<string name="emergency_gesture_number_override_notes">
If you enter a non-emergency number:\n
• Your device must be unlocked to use emergency SOS\n
• Your call may not be answered
</string>
<!-- Title text for swiping downwards on fingerprint sensor for notifications [CHAR LIMIT=80]-->
<string name="fingerprint_swipe_for_notifications_title">Swipe fingerprint for notifications</string>
<!-- Title text for fingerprint gesture preference screen [CHAR LIMIT=25] -->

View File

@@ -40,4 +40,14 @@
app:controller="com.android.settings.gestures.EmergencyGestureSoundPreferenceController"
app:allowDividerAbove="true"/>
<com.android.settings.gestures.EmergencyGestureNumberOverridePreference
android:key="emregency_gesture_number_override"
android:title="@string/emergency_gesture_call_for_help_title"
android:summary="@string/summary_placeholder"
android:icon="@drawable/ic_call_grey_24dp"
android:dialogTitle="@string/emergency_gesture_call_for_help_dialog_title"
android:dialogLayout="@layout/emergency_gesture_number_override_dialog"
android:positiveButtonText="@string/save"
app:allowDividerAbove="true"
app:controller="com.android.settings.gestures.EmergencyGestureNumberOverridePreferenceController"/>
</PreferenceScreen>

View File

@@ -0,0 +1,103 @@
/*
* Copyright (C) 2020 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.android.settings.gestures;
import static android.content.DialogInterface.BUTTON_POSITIVE;
import android.content.Context;
import android.content.DialogInterface;
import android.provider.Settings;
import android.text.TextUtils;
import android.util.AttributeSet;
import android.view.View;
import android.widget.EditText;
import androidx.annotation.VisibleForTesting;
import com.android.settings.R;
import com.android.settingslib.CustomDialogPreferenceCompat;
import com.android.settingslib.emergencynumber.EmergencyNumberUtils;
/**
* A dialog preference allowing user to provide a phone number to call during emergency gesture.
*/
public class EmergencyGestureNumberOverridePreference extends
CustomDialogPreferenceCompat {
private static final String TAG = "EmergencyGestureNumberO";
@VisibleForTesting
EditText mEditText;
private EmergencyNumberUtils mEmergencyNumberUtils;
public EmergencyGestureNumberOverridePreference(Context context,
AttributeSet attrs, int defStyleAttr, int defStyleRes) {
super(context, attrs, defStyleAttr, defStyleRes);
init(context);
}
public EmergencyGestureNumberOverridePreference(Context context, AttributeSet attrs,
int defStyleAttr) {
super(context, attrs, defStyleAttr);
init(context);
}
public EmergencyGestureNumberOverridePreference(Context context, AttributeSet attrs) {
super(context, attrs);
init(context);
}
public EmergencyGestureNumberOverridePreference(Context context) {
super(context);
init(context);
}
private void init(Context context) {
mEmergencyNumberUtils = new EmergencyNumberUtils(context);
}
@Override
public void setNegativeButtonText(int negativeButtonTextResId) {
super.setNegativeButtonText(negativeButtonTextResId);
}
@Override
protected void onBindDialogView(View view) {
super.onBindDialogView(view);
mEditText = view.findViewById(R.id.emergency_gesture_number_override);
final String defaultNumber = mEmergencyNumberUtils.getDefaultPoliceNumber();
mEditText.setHint(defaultNumber);
final String number = mEmergencyNumberUtils.getPoliceNumber();
if (!TextUtils.equals(number, defaultNumber)) {
mEditText.setText(number);
}
}
@Override
public void onClick(DialogInterface dialog, int which) {
if (which == BUTTON_POSITIVE) {
final String input = mEditText.getText().toString();
if (!TextUtils.isEmpty(input)) {
Settings.Secure.putString(getContext().getContentResolver(),
Settings.Secure.EMERGENCY_GESTURE_CALL_NUMBER, input);
} else {
Settings.Secure.putString(getContext().getContentResolver(),
Settings.Secure.EMERGENCY_GESTURE_CALL_NUMBER,
mEmergencyNumberUtils.getDefaultPoliceNumber());
}
}
}
}

View File

@@ -0,0 +1,99 @@
/*
* Copyright (C) 2020 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.android.settings.gestures;
import android.content.Context;
import android.database.ContentObserver;
import android.os.Handler;
import android.os.Looper;
import android.provider.Settings;
import androidx.annotation.VisibleForTesting;
import androidx.preference.Preference;
import androidx.preference.PreferenceScreen;
import com.android.settings.R;
import com.android.settings.core.BasePreferenceController;
import com.android.settingslib.core.lifecycle.LifecycleObserver;
import com.android.settingslib.core.lifecycle.events.OnStart;
import com.android.settingslib.core.lifecycle.events.OnStop;
import com.android.settingslib.emergencynumber.EmergencyNumberUtils;
/**
* Preference controller for emergency gesture number override.
*/
public class EmergencyGestureNumberOverridePreferenceController extends BasePreferenceController
implements LifecycleObserver, OnStart, OnStop {
@VisibleForTesting
EmergencyNumberUtils mEmergencyNumberUtils;
private final Handler mHandler;
private final ContentObserver mSettingsObserver;
private Preference mPreference;
public EmergencyGestureNumberOverridePreferenceController(Context context,
String preferenceKey) {
super(context, preferenceKey);
mEmergencyNumberUtils = new EmergencyNumberUtils(context);
mHandler = new Handler(Looper.getMainLooper());
mSettingsObserver = new EmergencyGestureNumberOverrideSettingsObserver(mHandler);
}
@Override
public int getAvailabilityStatus() {
return mContext.getResources()
.getBoolean(R.bool.config_show_emergency_gesture_settings) ? AVAILABLE
: UNSUPPORTED_ON_DEVICE;
}
@Override
public void displayPreference(PreferenceScreen screen) {
super.displayPreference(screen);
mPreference = screen.findPreference(getPreferenceKey());
}
@Override
public CharSequence getSummary() {
return mContext.getString(R.string.emergency_gesture_call_for_help_summary,
mEmergencyNumberUtils.getPoliceNumber());
}
@Override
public void onStart() {
mContext.getContentResolver().registerContentObserver(Settings.Secure.getUriFor(
Settings.Secure.EMERGENCY_GESTURE_CALL_NUMBER), false, mSettingsObserver);
}
@Override
public void onStop() {
mContext.getContentResolver().unregisterContentObserver(mSettingsObserver);
}
private class EmergencyGestureNumberOverrideSettingsObserver extends ContentObserver {
EmergencyGestureNumberOverrideSettingsObserver(Handler h) {
super(h);
}
@Override
public void onChange(boolean selfChange) {
if (mPreference != null) {
updateState(mPreference);
}
}
}
}

View File

@@ -0,0 +1,97 @@
/*
* Copyright (C) 2020 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.android.settings.gestures;
import static com.android.settings.core.BasePreferenceController.AVAILABLE;
import static com.android.settings.core.BasePreferenceController.UNSUPPORTED_ON_DEVICE;
import static com.google.common.truth.Truth.assertThat;
import static org.mockito.Mockito.when;
import android.content.Context;
import androidx.preference.Preference;
import androidx.test.core.app.ApplicationProvider;
import com.android.settings.R;
import com.android.settings.testutils.shadow.SettingsShadowResources;
import com.android.settingslib.emergencynumber.EmergencyNumberUtils;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
import org.robolectric.RobolectricTestRunner;
import org.robolectric.annotation.Config;
@RunWith(RobolectricTestRunner.class)
@Config(shadows = SettingsShadowResources.class)
public class EmergencyGestureNumberOverridePreferenceControllerTest {
private static final String PREF_KEY = "test";
@Mock
private EmergencyNumberUtils mEmergencyNumberUtils;
private Context mContext;
private EmergencyGestureNumberOverridePreferenceController mController;
@Before
public void setUp() {
MockitoAnnotations.initMocks(this);
mContext = ApplicationProvider.getApplicationContext();
mController = new EmergencyGestureNumberOverridePreferenceController(mContext, PREF_KEY);
}
@After
public void tearDown() {
SettingsShadowResources.reset();
}
@Test
public void getAvailabilityStatus_configIsTrue_shouldReturnAvailable() {
SettingsShadowResources.overrideResource(
R.bool.config_show_emergency_gesture_settings,
Boolean.TRUE);
assertThat(mController.getAvailabilityStatus()).isEqualTo(AVAILABLE);
}
@Test
public void getAvailabilityStatus_configIsFalse_shouldReturnUnsupported() {
SettingsShadowResources.overrideResource(
R.bool.config_show_emergency_gesture_settings,
Boolean.FALSE);
assertThat(mController.getAvailabilityStatus()).isEqualTo(UNSUPPORTED_ON_DEVICE);
}
@Test
public void updateState_shouldLoadNumberFromSettings() {
final Preference preference = new Preference(mContext);
mController.mEmergencyNumberUtils = mEmergencyNumberUtils;
when(mEmergencyNumberUtils.getPoliceNumber()).thenReturn("123");
mController.updateState(preference);
assertThat(preference.getSummary()).isEqualTo(
mContext.getString(R.string.emergency_gesture_call_for_help_summary, "123"));
}
}