OSDN Git Service

DO NOT MERGE Add zen starred contacts preference
authorBeverly <beverlyt@google.com>
Wed, 9 May 2018 19:28:21 +0000 (15:28 -0400)
committerBeverly <beverlyt@google.com>
Wed, 9 May 2018 20:12:10 +0000 (16:12 -0400)
Bug: 78447976
Test: ZenModeStarredContactsPreferenceControllerTest
Change-Id: Ic9d1b08c3e80832b29ad8e223a34f35e2f763cf9

res/values/strings.xml
res/xml/zen_mode_calls_settings.xml
res/xml/zen_mode_msg_event_reminder_settings.xml
src/com/android/settings/notification/ZenModeCallsSettings.java
src/com/android/settings/notification/ZenModeMsgEventReminderSettings.java
src/com/android/settings/notification/ZenModeStarredContactsPreferenceController.java [new file with mode: 0644]
tests/robotests/src/com/android/settings/notification/ZenModeStarredContactsPreferenceControllerTest.java [new file with mode: 0644]

index c8dad37..9ea4869 100644 (file)
     <!-- [CHAR LIMIT=20] Zen mode settings: Calls screen footer -->
     <string name="zen_mode_calls_footer">When Do Not Disturb is on, incoming calls are blocked. You can adjust settings to allow your friends, family, or other contacts to reach you.</string>
 
+    <!-- [CHAR LIMIT=50] Zen mode settings: Starred contacts preference title -->
+    <string name="zen_mode_starred_contacts_title">Starred contacts</string>
+
+    <!-- Zen mode settings: Starred contacts summary [CHAR LIMIT=NONE] -->
+    <plurals name="zen_mode_starred_contacts_summary_additional_contacts">
+        <item quantity="one">and 1 other</item>
+        <item quantity="other">and <xliff:g id="num_people" example="3">%d</xliff:g> others</item>
+    </plurals>
+
     <!-- [CHAR LIMIT=20] Zen mode settings: Messages option -->
     <string name="zen_mode_messages">Messages</string>
 
index d9e47f3..62d9ef4 100644 (file)
@@ -29,7 +29,9 @@
           android:entries="@array/zen_mode_contacts_entries"
           android:entryValues="@array/zen_mode_contacts_values"/>
 
-      <!-- TODO: setting that links to contacts or placeholder for external app -->
+      <Preference
+          android:key="zen_mode_starred_contacts"
+          android:title="@string/zen_mode_starred_contacts_title"/>
 
       <!-- Repeat callers -->
       <SwitchPreference
index 866f333..2f065a6 100644 (file)
           android:entries="@array/zen_mode_contacts_entries"
           android:entryValues="@array/zen_mode_contacts_values"/>
 
+      <Preference
+          android:key="zen_mode_starred_contacts"
+          android:title="@string/zen_mode_starred_contacts_title"/>
+
       <!-- Reminders -->
       <SwitchPreference
           android:key="zen_mode_reminders"
index 20396b5..cd56d7b 100644 (file)
@@ -16,6 +16,8 @@
 
 package com.android.settings.notification;
 
+import static android.app.NotificationManager.Policy.PRIORITY_CATEGORY_CALLS;
+
 import android.content.Context;
 import android.provider.SearchIndexableResource;
 
@@ -40,8 +42,8 @@ public class ZenModeCallsSettings extends ZenModeSettingsBase implements Indexab
             Lifecycle lifecycle) {
         List<AbstractPreferenceController> controllers = new ArrayList<>();
         controllers.add(new ZenModeCallsPreferenceController(context, lifecycle));
-        // TODO: is a controller needed for a pref that just launches an external activity?
-        // or can the contacts app insert this setting themselves?
+        controllers.add(new ZenModeStarredContactsPreferenceController(context, lifecycle,
+                PRIORITY_CATEGORY_CALLS));
         controllers.add(new ZenModeRepeatCallersPreferenceController(context, lifecycle,
                 context.getResources().getInteger(com.android.internal.R.integer
                 .config_zen_repeat_callers_threshold)));
index c2508e3..95b9f7e 100644 (file)
@@ -16,6 +16,8 @@
 
 package com.android.settings.notification;
 
+import static android.app.NotificationManager.Policy.PRIORITY_CATEGORY_MESSAGES;
+
 import android.content.Context;
 import android.provider.SearchIndexableResource;
 
@@ -42,6 +44,8 @@ public class ZenModeMsgEventReminderSettings extends ZenModeSettingsBase impleme
         controllers.add(new ZenModeEventsPreferenceController(context, lifecycle));
         controllers.add(new ZenModeRemindersPreferenceController(context, lifecycle));
         controllers.add(new ZenModeMessagesPreferenceController(context, lifecycle));
+        controllers.add(new ZenModeStarredContactsPreferenceController(context, lifecycle,
+                PRIORITY_CATEGORY_MESSAGES));
         controllers.add(new ZenModeBehaviorFooterPreferenceController(context, lifecycle,
                 R.string.zen_msg_event_reminder_footer));
         return controllers;
diff --git a/src/com/android/settings/notification/ZenModeStarredContactsPreferenceController.java b/src/com/android/settings/notification/ZenModeStarredContactsPreferenceController.java
new file mode 100644 (file)
index 0000000..1b8a3d5
--- /dev/null
@@ -0,0 +1,151 @@
+/*
+ * Copyright (C) 2018 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.notification;
+
+import static android.app.NotificationManager.Policy.PRIORITY_CATEGORY_CALLS;
+import static android.app.NotificationManager.Policy.PRIORITY_CATEGORY_MESSAGES;
+import static android.app.NotificationManager.Policy.PRIORITY_SENDERS_STARRED;
+
+import android.content.Context;
+import android.content.Intent;
+import android.content.pm.PackageManager;
+import android.database.Cursor;
+import android.icu.text.ListFormatter;
+import android.provider.Contacts;
+import android.provider.ContactsContract;
+import android.support.v7.preference.Preference;
+import android.support.v7.preference.PreferenceScreen;
+
+import com.android.internal.annotations.VisibleForTesting;
+import com.android.settings.R;
+import com.android.settingslib.core.lifecycle.Lifecycle;
+
+import java.util.ArrayList;
+import java.util.List;
+
+public class ZenModeStarredContactsPreferenceController extends
+        AbstractZenModePreferenceController implements Preference.OnPreferenceClickListener {
+
+    protected static final String KEY = "zen_mode_starred_contacts";
+    private Preference mPreference;
+    private final int mPriorityCategory;
+    private final PackageManager mPackageManager;
+
+    @VisibleForTesting
+    Intent mStarredContactsIntent;
+    @VisibleForTesting
+    Intent mFallbackIntent;
+
+    public ZenModeStarredContactsPreferenceController(Context context, Lifecycle lifecycle, int
+            priorityCategory) {
+        super(context, KEY, lifecycle);
+        mPriorityCategory = priorityCategory;
+        mPackageManager = mContext.getPackageManager();
+
+        mStarredContactsIntent = new Intent(Contacts.Intents.UI.LIST_STARRED_ACTION);
+
+        mFallbackIntent =  new Intent(Intent.ACTION_MAIN);
+        mFallbackIntent.addCategory(Intent.CATEGORY_APP_CONTACTS);
+    }
+
+    @Override
+    public void displayPreference(PreferenceScreen screen) {
+        super.displayPreference(screen);
+        mPreference = screen.findPreference(KEY);
+        mPreference.setOnPreferenceClickListener(this);
+    }
+
+    @Override
+    public String getPreferenceKey() {
+        return KEY;
+    }
+
+    @Override
+    public boolean isAvailable() {
+        if (mPriorityCategory == PRIORITY_CATEGORY_CALLS) {
+            return mBackend.isPriorityCategoryEnabled(PRIORITY_CATEGORY_CALLS)
+                    && mBackend.getPriorityCallSenders() == PRIORITY_SENDERS_STARRED
+                    && isIntentValid();
+        } else if (mPriorityCategory == PRIORITY_CATEGORY_MESSAGES) {
+            return mBackend.isPriorityCategoryEnabled(PRIORITY_CATEGORY_MESSAGES)
+                    && mBackend.getPriorityMessageSenders() == PRIORITY_SENDERS_STARRED
+                    && isIntentValid();
+        } else {
+            // invalid category
+            return false;
+        }
+    }
+
+    @Override
+    public void updateState(Preference preference) {
+        super.updateState(preference);
+
+        List<String> starredContacts = getStarredContacts();
+        int numStarredContacts = starredContacts.size();
+
+        List<String> displayContacts = new ArrayList<>();
+
+        if (numStarredContacts == 0) {
+            displayContacts.add(mContext.getString(R.string.zen_mode_from_none));
+        } else {
+            for (int i = 0; i < 2 && i < numStarredContacts; i++) {
+                displayContacts.add(starredContacts.get(i));
+            }
+
+            if (numStarredContacts == 3) {
+                displayContacts.add(starredContacts.get(2));
+            } else if (numStarredContacts > 2) {
+                displayContacts.add(mContext.getResources().getQuantityString(
+                        R.plurals.zen_mode_starred_contacts_summary_additional_contacts,
+                        numStarredContacts - 2, numStarredContacts - 2));
+            }
+        }
+
+        mPreference.setSummary(ListFormatter.getInstance().format(displayContacts));
+    }
+
+    @Override
+    public boolean onPreferenceClick(Preference preference) {
+        if (mStarredContactsIntent.resolveActivity(mPackageManager) != null) {
+            mContext.startActivity(mStarredContactsIntent);
+        } else {
+            mContext.startActivity(mFallbackIntent);
+        }
+        return true;
+    }
+
+    private List<String> getStarredContacts() {
+        List<String> starredContacts = new ArrayList<>();
+
+        Cursor cursor = mContext.getContentResolver().query(ContactsContract.Contacts.CONTENT_URI,
+                new String[]{ContactsContract.Contacts.DISPLAY_NAME_PRIMARY},
+                ContactsContract.Data.STARRED + "=1", null,
+                ContactsContract.Data.TIMES_CONTACTED);
+
+        if (cursor.moveToFirst()) {
+            do {
+                starredContacts.add(cursor.getString(0));
+            } while (cursor.moveToNext());
+        }
+        return starredContacts;
+    }
+
+    private boolean isIntentValid() {
+        return mStarredContactsIntent.resolveActivity(mPackageManager) != null
+                || mFallbackIntent.resolveActivity(mPackageManager) != null;
+    }
+}
diff --git a/tests/robotests/src/com/android/settings/notification/ZenModeStarredContactsPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/notification/ZenModeStarredContactsPreferenceControllerTest.java
new file mode 100644 (file)
index 0000000..7a45d7f
--- /dev/null
@@ -0,0 +1,149 @@
+/*
+ * Copyright (C) 2018 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.notification;
+
+import static android.app.NotificationManager.Policy.PRIORITY_CATEGORY_CALLS;
+import static android.app.NotificationManager.Policy.PRIORITY_CATEGORY_MESSAGES;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import static org.mockito.Matchers.any;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.when;
+
+import android.app.NotificationManager;
+import android.content.ComponentName;
+import android.content.Context;
+import android.content.Intent;
+import android.support.v7.preference.ListPreference;
+import android.support.v7.preference.PreferenceScreen;
+
+import com.android.settings.testutils.SettingsRobolectricTestRunner;
+import com.android.settingslib.core.lifecycle.Lifecycle;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
+import org.robolectric.shadows.ShadowApplication;
+import org.robolectric.util.ReflectionHelpers;
+
+@RunWith(SettingsRobolectricTestRunner.class)
+public class ZenModeStarredContactsPreferenceControllerTest {
+
+    private ZenModeStarredContactsPreferenceController mCallsController;
+    private ZenModeStarredContactsPreferenceController mMessagesController;
+
+    @Mock
+    private ZenModeBackend mBackend;
+    @Mock
+    private NotificationManager mNotificationManager;
+    @Mock
+    private ListPreference mockPref;
+    @Mock
+    private NotificationManager.Policy mPolicy;
+    @Mock
+    private PreferenceScreen mPreferenceScreen;
+    @Mock
+    private Intent testIntent;
+    @Mock
+    private ComponentName mComponentName;
+    private Context mContext;
+
+    @Before
+    public void setup() {
+        MockitoAnnotations.initMocks(this);
+        ShadowApplication shadowApplication = ShadowApplication.getInstance();
+        shadowApplication.setSystemService(Context.NOTIFICATION_SERVICE, mNotificationManager);
+
+        mContext = shadowApplication.getApplicationContext();
+        when(mNotificationManager.getNotificationPolicy()).thenReturn(mPolicy);
+        when(testIntent.resolveActivity(any())).thenReturn(mComponentName);
+
+        mCallsController = new ZenModeStarredContactsPreferenceController(
+                mContext, mock(Lifecycle.class), PRIORITY_CATEGORY_CALLS);
+        ReflectionHelpers.setField(mCallsController, "mBackend", mBackend);
+        ReflectionHelpers.setField(mCallsController, "mStarredContactsIntent", testIntent);
+        when(mPreferenceScreen.findPreference(mCallsController.getPreferenceKey()))
+                .thenReturn(mockPref);
+        mCallsController.displayPreference(mPreferenceScreen);
+
+        mMessagesController = new ZenModeStarredContactsPreferenceController(
+                mContext, mock(Lifecycle.class), PRIORITY_CATEGORY_MESSAGES);
+        ReflectionHelpers.setField(mMessagesController, "mBackend", mBackend);
+        ReflectionHelpers.setField(mMessagesController, "mStarredContactsIntent", testIntent);
+        when(mPreferenceScreen.findPreference(mMessagesController.getPreferenceKey()))
+                .thenReturn(mockPref);
+        mMessagesController.displayPreference(mPreferenceScreen);
+    }
+
+    @Test
+    public void isAvailable_noCallers() {
+        when(mBackend.isPriorityCategoryEnabled(NotificationManager.Policy.PRIORITY_CATEGORY_CALLS))
+                .thenReturn(false);
+        assertThat(mCallsController.isAvailable()).isFalse();
+    }
+
+    @Test
+    public void isAvailable_anyCallers() {
+        when(mBackend.isPriorityCategoryEnabled(NotificationManager.Policy.PRIORITY_CATEGORY_CALLS))
+                .thenReturn(true);
+        when(mBackend.getPriorityCallSenders())
+                .thenReturn(NotificationManager.Policy.PRIORITY_SENDERS_ANY);
+
+
+        assertThat(mCallsController.isAvailable()).isFalse();
+    }
+
+    @Test
+    public void isAvailable_starredCallers() {
+        when(mBackend.isPriorityCategoryEnabled(NotificationManager.Policy.PRIORITY_CATEGORY_CALLS))
+                .thenReturn(true);
+        when(mBackend.getPriorityCallSenders())
+                .thenReturn(NotificationManager.Policy.PRIORITY_SENDERS_STARRED);
+
+        assertThat(mCallsController.isAvailable()).isTrue();
+    }
+
+    @Test
+    public void isAvailable_noMessages() {
+        when(mBackend.isPriorityCategoryEnabled(
+                NotificationManager.Policy.PRIORITY_CATEGORY_MESSAGES)).thenReturn(false);
+        assertThat(mMessagesController.isAvailable()).isFalse();
+    }
+
+    @Test
+    public void isAvailable_anyMessages() {
+        when(mBackend.isPriorityCategoryEnabled(
+                NotificationManager.Policy.PRIORITY_CATEGORY_MESSAGES)).thenReturn(true);
+        when(mBackend.getPriorityMessageSenders())
+                .thenReturn(NotificationManager.Policy.PRIORITY_SENDERS_ANY);
+
+        assertThat(mMessagesController.isAvailable()).isFalse();
+    }
+
+    @Test
+    public void isAvailable_starredMessageContacts() {
+        when(mBackend.isPriorityCategoryEnabled(
+                NotificationManager.Policy.PRIORITY_CATEGORY_MESSAGES)).thenReturn(true);
+        when(mBackend.getPriorityMessageSenders())
+                .thenReturn(NotificationManager.Policy.PRIORITY_SENDERS_STARRED);
+
+        assertThat(mMessagesController.isAvailable()).isTrue();
+    }
+}