From d6bbac5f7c1dca2e9b961863c079296dbf5f08a6 Mon Sep 17 00:00:00 2001 From: Juan Lang Date: Thu, 20 Jul 2017 17:56:11 -0700 Subject: Hide settings suggestion when emergency info are provided. Introduce an activity alias for the edit activity. Set the settings suggestion on the alias rather than the edit activity. Enable / disable the alias activity when emergency info are removed / set, respectively. Change-Id: I0dadf3c9a3d7b5020fd4b43e82444b82cc39108a Fix: 63533900 Test: manual && make RunEmergencyInfoRoboTests && \ runtest --path packages/apps/EmergencyInfo/tests/ --- AndroidManifest.xml | 10 +- .../android/emergency/edit/EditInfoActivity.java | 6 + .../emergency/edit/EditMedicalInfoFragment.java | 3 + .../preferences/EmergencyContactsPreference.java | 3 + .../android/emergency/util/PreferenceUtils.java | 96 ++++++++++++ .../view/ViewEmergencyContactsFragment.java | 23 --- .../emergency/view/ViewEmergencyInfoFragment.java | 15 -- .../android/emergency/view/ViewInfoActivity.java | 5 +- .../emergency/util/PreferenceUtilsTest.java | 168 +++++++++++++++++++++ .../emergency/edit/EditInfoActivityTest.java | 24 +++ 10 files changed, 312 insertions(+), 41 deletions(-) create mode 100644 src/com/android/emergency/util/PreferenceUtils.java create mode 100644 tests/robolectric/src/com/android/emergency/util/PreferenceUtilsTest.java diff --git a/AndroidManifest.xml b/AndroidManifest.xml index 80433c5..44d542d 100644 --- a/AndroidManifest.xml +++ b/AndroidManifest.xml @@ -50,6 +50,14 @@ + + + + @@ -61,7 +69,7 @@ android:resource="@string/settings_suggestion_body" /> - + emptySet()); + } + + return !EmergencyContactsPreference.deserializeAndFilter( + PreferenceKeys.KEY_EMERGENCY_CONTACTS, + context, + emergencyContactsString).isEmpty(); + } + + /** + * Enables or disables the settings suggestion for this application, depending on whether any + * emergency settings exist. + */ + public static void updateSettingsSuggestionState(Context context) { + int state = hasAtLeastOnePreferenceOrContactSet(context) ? + PackageManager.COMPONENT_ENABLED_STATE_DISABLED : + PackageManager.COMPONENT_ENABLED_STATE_ENABLED; + setSettingsSuggestionState(context, state); + } + + /** Enables the settings suggestion for this application. */ + public static void enableSettingsSuggestion(Context context) { + setSettingsSuggestionState(context, PackageManager.COMPONENT_ENABLED_STATE_ENABLED); + } + + private static boolean hasAtLeastOnePreferenceOrContactSet(Context context) { + return hasAtLeastOnePreferenceSet(context) || hasAtLeastOneEmergencyContact(context); + } + + private static void setSettingsSuggestionState(Context context, int state) { + String packageName = context.getPackageName(); + String targetClass = packageName + SETTINGS_SUGGESTION_ACTIVITY_ALIAS; + ComponentName name = new ComponentName(packageName, targetClass); + PackageManager pm = context.getPackageManager(); + pm.setComponentEnabledSetting(name, state, PackageManager.DONT_KILL_APP); + } +} diff --git a/src/com/android/emergency/view/ViewEmergencyContactsFragment.java b/src/com/android/emergency/view/ViewEmergencyContactsFragment.java index 7547100..f9de3b6 100644 --- a/src/com/android/emergency/view/ViewEmergencyContactsFragment.java +++ b/src/com/android/emergency/view/ViewEmergencyContactsFragment.java @@ -27,8 +27,6 @@ import com.android.emergency.PreferenceKeys; import com.android.emergency.R; import com.android.emergency.preferences.EmergencyContactsPreference; -import java.util.Collections; - /** * Fragment that displays emergency contacts. */ @@ -52,25 +50,4 @@ public class ViewEmergencyContactsFragment extends PreferenceFragment { public static Fragment newInstance() { return new ViewEmergencyContactsFragment(); } - - /** Returns true if there is at least one valid (still existing) emergency contact. */ - public static boolean hasAtLeastOneEmergencyContact(Context context) { - SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(context); - String emergencyContactsString = ""; - try { - emergencyContactsString = prefs.getString(PreferenceKeys.KEY_EMERGENCY_CONTACTS, ""); - } catch (ClassCastException e) { - // Protect against b/28194605: We used to store the contacts using a string set. - // If it is a string set, ignore its value. If it is not a string set it will throw - // a ClassCastException - prefs.getStringSet( - PreferenceKeys.KEY_EMERGENCY_CONTACTS, - Collections.emptySet()); - } - - return !EmergencyContactsPreference.deserializeAndFilter( - PreferenceKeys.KEY_EMERGENCY_CONTACTS, - context, - emergencyContactsString).isEmpty(); - } } diff --git a/src/com/android/emergency/view/ViewEmergencyInfoFragment.java b/src/com/android/emergency/view/ViewEmergencyInfoFragment.java index baa7996..1d35e73 100644 --- a/src/com/android/emergency/view/ViewEmergencyInfoFragment.java +++ b/src/com/android/emergency/view/ViewEmergencyInfoFragment.java @@ -16,13 +16,10 @@ package com.android.emergency.view; import android.app.Fragment; -import android.content.Context; -import android.content.SharedPreferences; import android.os.Bundle; import android.support.v14.preference.PreferenceFragment; import android.support.v7.preference.Preference; import android.support.v7.preference.PreferenceManager; -import android.text.TextUtils; import com.android.emergency.PreferenceKeys; import com.android.emergency.R; @@ -71,16 +68,4 @@ public class ViewEmergencyInfoFragment extends PreferenceFragment { public static Fragment newInstance() { return new ViewEmergencyInfoFragment(); } - - /** Returns true if there is at least one preference set. */ - public static boolean hasAtLeastOnePreferenceSet(Context context) { - SharedPreferences sharedPreferences = - PreferenceManager.getDefaultSharedPreferences(context); - for (String key : PreferenceKeys.KEYS_VIEW_EMERGENCY_INFO) { - if (!TextUtils.isEmpty(sharedPreferences.getString(key, ""))) { - return true; - } - } - return false; - } } diff --git a/src/com/android/emergency/view/ViewInfoActivity.java b/src/com/android/emergency/view/ViewInfoActivity.java index 74ca006..ee3435a 100644 --- a/src/com/android/emergency/view/ViewInfoActivity.java +++ b/src/com/android/emergency/view/ViewInfoActivity.java @@ -43,6 +43,7 @@ import android.widget.ViewFlipper; import com.android.emergency.PreferenceKeys; import com.android.emergency.R; import com.android.emergency.edit.EditInfoActivity; +import com.android.emergency.util.PreferenceUtils; import com.android.internal.annotations.VisibleForTesting; import com.android.internal.logging.MetricsLogger; import com.android.internal.logging.nano.MetricsProto.MetricsEvent; @@ -166,11 +167,11 @@ public class ViewInfoActivity extends Activity { // Return only the fragments that have at least one piece of information set: ArrayList> fragments = new ArrayList<>(2); - if (ViewEmergencyInfoFragment.hasAtLeastOnePreferenceSet(this)) { + if (PreferenceUtils.hasAtLeastOnePreferenceSet(this)) { fragments.add(Pair.create(getResources().getString(R.string.tab_title_info), ViewEmergencyInfoFragment.newInstance())); } - if (ViewEmergencyContactsFragment.hasAtLeastOneEmergencyContact(this)) { + if (PreferenceUtils.hasAtLeastOneEmergencyContact(this)) { fragments.add(Pair.create(getResources().getString(R.string.tab_title_contacts), ViewEmergencyContactsFragment.newInstance())); } diff --git a/tests/robolectric/src/com/android/emergency/util/PreferenceUtilsTest.java b/tests/robolectric/src/com/android/emergency/util/PreferenceUtilsTest.java new file mode 100644 index 0000000..a467372 --- /dev/null +++ b/tests/robolectric/src/com/android/emergency/util/PreferenceUtilsTest.java @@ -0,0 +1,168 @@ +/* + * Copyright (C) 2017 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.emergency.util; + +import static com.google.common.truth.Truth.assertThat; +import static org.mockito.Matchers.eq; +import static org.mockito.Mockito.any; +import static org.mockito.Mockito.anyInt; +import static org.mockito.Mockito.anyString; +import static org.mockito.Mockito.eq; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.when; + +import android.content.ComponentName; +import android.content.ContentResolver; +import android.content.Context; +import android.content.SharedPreferences; +import android.content.pm.PackageManager; +import android.database.Cursor; +import android.net.Uri; +import android.test.suitebuilder.annotation.SmallTest; + +import com.android.emergency.ContactTestUtils; +import com.android.emergency.PreferenceKeys; +import com.android.emergency.TestConfig; + +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.RuntimeEnvironment; +import org.robolectric.annotation.Config; + +/** Unit tests for {@link PreferenceUtils}. */ +@SmallTest +@RunWith(RobolectricTestRunner.class) +@Config(manifest = TestConfig.MANIFEST_PATH, sdk = TestConfig.SDK_VERSION) +public final class PreferenceUtilsTest { + private static final String PACKAGE_NAME = "com.android.emergency"; + private static final String NAME = "Jane"; + private static final String PHONE_NUMBER = "5150"; + private static final ComponentName COMPONENT_NAME = new ComponentName( + PACKAGE_NAME, + PACKAGE_NAME + PreferenceUtils.SETTINGS_SUGGESTION_ACTIVITY_ALIAS); + + @Mock ContentResolver mContentResolver; + @Mock Context mContext; + @Mock Cursor mCursor; + @Mock PackageManager mPackageManager; + @Mock SharedPreferences mSharedPreferences; + @Mock SharedPreferences.Editor mSharedPreferencesEditor; + + @Before + public void setUp() { + MockitoAnnotations.initMocks(this); + + when(mContext.getContentResolver()).thenReturn(mContentResolver); + when(mContext.getPackageManager()).thenReturn(mPackageManager); + when(mContext.getPackageName()).thenReturn(PACKAGE_NAME); + when(mContext.getSharedPreferences(anyString(), anyInt())).thenReturn(mSharedPreferences); + when(mSharedPreferences.edit()).thenReturn(mSharedPreferencesEditor); + when(mSharedPreferencesEditor.putString(anyString(), anyString())) + .thenReturn(mSharedPreferencesEditor); + } + + @Test + public void testHasAtLeastOnePreferenceSet_notSet() { + when(mSharedPreferences.getString(anyString(), anyString())).thenReturn(""); + + assertThat(PreferenceUtils.hasAtLeastOnePreferenceSet(mContext)).isFalse(); + } + + @Test + public void testHasAtLeastOnePreferenceSet_set() { + when(mSharedPreferences.getString(anyString(), anyString())).thenReturn("mxyzptlk"); + + assertThat(PreferenceUtils.hasAtLeastOnePreferenceSet(mContext)).isTrue(); + } + + @Test + public void testHasAtLeastOneEmergencyContact_notSet() { + when(mSharedPreferences.getString(eq(PreferenceKeys.KEY_EMERGENCY_CONTACTS), any())) + .thenReturn(""); + + assertThat(PreferenceUtils.hasAtLeastOneEmergencyContact(mContext)).isFalse(); + } + + @Test + public void testHasAtLeastOneEmergencyContact_set() { + final Uri contactUri = ContactTestUtils.createContact( + RuntimeEnvironment.application.getContentResolver(), NAME, PHONE_NUMBER); + when(mSharedPreferences.getString(eq(PreferenceKeys.KEY_EMERGENCY_CONTACTS), any())) + .thenReturn(contactUri.toString()); + when(mContentResolver.query(eq(contactUri), any(), any(), any(), any())) + .thenReturn(mCursor); + when(mCursor.moveToFirst()).thenReturn(true); + + assertThat(PreferenceUtils.hasAtLeastOneEmergencyContact(mContext)).isTrue(); + } + + @Test + public void testEnableSettingsSuggestion() { + PreferenceUtils.enableSettingsSuggestion(mContext); + + verify(mPackageManager).setComponentEnabledSetting( + eq(COMPONENT_NAME), + eq(PackageManager.COMPONENT_ENABLED_STATE_ENABLED), + eq(PackageManager.DONT_KILL_APP)); + } + + @Test + public void testUpdateSettingsSuggestionState_contactSet() { + final Uri contactUri = ContactTestUtils.createContact( + RuntimeEnvironment.application.getContentResolver(), NAME, PHONE_NUMBER); + when(mSharedPreferences.getString(eq(PreferenceKeys.KEY_EMERGENCY_CONTACTS), any())) + .thenReturn(contactUri.toString()); + when(mContentResolver.query(eq(contactUri), any(), any(), any(), any())) + .thenReturn(mCursor); + when(mCursor.moveToFirst()).thenReturn(true); + + PreferenceUtils.updateSettingsSuggestionState(mContext); + + verify(mPackageManager).setComponentEnabledSetting( + eq(COMPONENT_NAME), + eq(PackageManager.COMPONENT_ENABLED_STATE_DISABLED), + eq(PackageManager.DONT_KILL_APP)); + } + + @Test + public void testUpdateSettingsSuggestionState_noPreferencesOrContactSet() { + when(mSharedPreferences.getString(anyString(), anyString())).thenReturn(""); + + PreferenceUtils.updateSettingsSuggestionState(mContext); + + verify(mPackageManager).setComponentEnabledSetting( + eq(COMPONENT_NAME), + eq(PackageManager.COMPONENT_ENABLED_STATE_ENABLED), + eq(PackageManager.DONT_KILL_APP)); + } + + @Test + public void testUpdateSettingsSuggestionState_preferenceSet() { + when(mSharedPreferences.getString(eq(PreferenceKeys.KEY_ALLERGIES), any())) + .thenReturn("peanuts"); + + PreferenceUtils.updateSettingsSuggestionState(mContext); + + verify(mPackageManager).setComponentEnabledSetting( + eq(COMPONENT_NAME), + eq(PackageManager.COMPONENT_ENABLED_STATE_DISABLED), + eq(PackageManager.DONT_KILL_APP)); + } +} diff --git a/tests/unit/src/com/android/emergency/edit/EditInfoActivityTest.java b/tests/unit/src/com/android/emergency/edit/EditInfoActivityTest.java index 195a0bc..e0049b6 100644 --- a/tests/unit/src/com/android/emergency/edit/EditInfoActivityTest.java +++ b/tests/unit/src/com/android/emergency/edit/EditInfoActivityTest.java @@ -24,9 +24,11 @@ import static com.google.common.truth.Truth.assertWithMessage; import android.app.Dialog; import android.app.Instrumentation; +import android.content.ComponentName; import android.content.Context; import android.content.Intent; import android.content.IntentFilter; +import android.content.pm.PackageManager; import android.net.Uri; import android.provider.ContactsContract; import android.support.test.InstrumentationRegistry; @@ -42,6 +44,7 @@ import com.android.emergency.preferences.EmergencyContactsPreference; import com.android.emergency.preferences.EmergencyEditTextPreference; import com.android.emergency.preferences.EmergencyListPreference; import com.android.emergency.preferences.NameAutoCompletePreference; +import com.android.emergency.util.PreferenceUtils; import java.util.ArrayList; import java.util.List; @@ -86,6 +89,14 @@ public final class EditInfoActivityTest { PreferenceKeys.KEY_EMERGENCY_CONTACTS); assertThat(emergencyContactsPreference).isNotNull(); assertThat(emergencyContactsPreference.getPreferenceCount()).isEqualTo(0); + + final PackageManager packageManager = mTargetContext.getPackageManager(); + final String packageName = mTargetContext.getPackageName(); + final ComponentName componentName = new ComponentName( + packageName, + packageName + PreferenceUtils.SETTINGS_SUGGESTION_ACTIVITY_ALIAS); + assertThat(packageManager.getComponentEnabledSetting(componentName)) + .isEqualTo(PackageManager.COMPONENT_ENABLED_STATE_ENABLED); } @Test @@ -111,6 +122,15 @@ public final class EditInfoActivityTest { .edit().putString(PreferenceKeys.KEY_EMERGENCY_CONTACTS, contactUri.toString()) .commit(); + final PackageManager packageManager = mTargetContext.getPackageManager(); + final String packageName = mTargetContext.getPackageName(); + final ComponentName componentName = new ComponentName( + packageName, + packageName + PreferenceUtils.SETTINGS_SUGGESTION_ACTIVITY_ALIAS); + // With emergency info settings present, the settings suggestion should be disabled. + assertThat(packageManager.getComponentEnabledSetting(componentName)) + .isEqualTo(PackageManager.COMPONENT_ENABLED_STATE_DISABLED); + EditInfoActivity activity = startEditInfoActivity(); EditInfoFragment fragment = (EditInfoFragment) activity.getFragment(); @@ -195,6 +215,10 @@ public final class EditInfoActivityTest { assertWithMessage(key).that(medicalInfoParent.findPreference(key)).isNull(); } + // Now that the settings have been cleared, the settings suggestion should reappear. + assertThat(packageManager.getComponentEnabledSetting(componentName)) + .isEqualTo(PackageManager.COMPONENT_ENABLED_STATE_ENABLED); + assertThat(ContactTestUtils .deleteContact(activity.getContentResolver(), "Michael", "789")).isTrue(); } -- cgit v1.2.3