Merge "DO NOT MERGE Add zen starred contacts preference" into pi-dev

This commit is contained in:
Beverly Tai
2018-05-10 13:28:47 +00:00
committed by Android (Google) Code Review
7 changed files with 324 additions and 3 deletions

View File

@@ -7928,6 +7928,15 @@
<!-- [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>

View 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

View File

@@ -29,6 +29,10 @@
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"

View 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)));

View 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;

View File

@@ -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;
}
}

View File

@@ -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();
}
}