Loading res/values/strings.xml +3 −0 Original line number Diff line number Diff line Loading @@ -6515,6 +6515,9 @@ <!-- Configure Notifications: Work profile section header [CHAR LIMIT=30] --> <string name="profile_section_header">Work notifications</string> <!-- Configure Notifications: Title for the notification badging option. [CHAR LIMIT=30] --> <string name="notification_badging_title">Allow icon badges</string> <!-- Configure Notifications: Title for the pulse notification light option. [CHAR LIMIT=30] --> <string name="notification_pulse_title">Blink light</string> res/xml/configure_notification_settings.xml +5 −0 Original line number Diff line number Diff line Loading @@ -22,6 +22,11 @@ android:key="dashboard_tile_placeholder" android:order="1"/> <!-- Notification badging --> <SwitchPreference android:key="notification_badging" android:title="@string/notification_badging_title"/> <!-- Pulse notification light --> <SwitchPreference android:key="notification_pulse" Loading src/com/android/settings/notification/BadgingNotificationPreferenceController.java 0 → 100644 +126 −0 Original line number Diff line number Diff line /* * 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.settings.notification; import android.content.ContentResolver; import android.content.Context; import android.database.ContentObserver; import android.net.Uri; import android.os.Handler; import android.provider.Settings; import android.support.v7.preference.Preference; import android.support.v7.preference.PreferenceScreen; import android.support.v7.preference.TwoStatePreference; import android.util.Log; import com.android.settings.core.PreferenceController; import com.android.settings.core.lifecycle.LifecycleObserver; import com.android.settings.core.lifecycle.events.OnPause; import com.android.settings.core.lifecycle.events.OnResume; import static android.provider.Settings.Secure.NOTIFICATION_BADGING; public class BadgingNotificationPreferenceController extends PreferenceController implements Preference.OnPreferenceChangeListener, LifecycleObserver, OnResume, OnPause { private static final String TAG = "BadgeNotifPrefContr"; private static final String KEY_NOTIFICATION_BADGING = "notification_badging"; private static final int DEFAULT_VALUE = 1; private SettingObserver mSettingObserver; public BadgingNotificationPreferenceController(Context context) { super(context); } @Override public void displayPreference(PreferenceScreen screen) { super.displayPreference(screen); Preference preference = screen.findPreference(NOTIFICATION_BADGING); if (preference != null) { mSettingObserver = new SettingObserver(preference); } } @Override public void onResume() { if (mSettingObserver != null) { mSettingObserver.register(mContext.getContentResolver(), true /* register */); } } @Override public void onPause() { if (mSettingObserver != null) { mSettingObserver.register(mContext.getContentResolver(), false /* register */); } } @Override public String getPreferenceKey() { return KEY_NOTIFICATION_BADGING; } @Override public boolean isAvailable() { return mContext.getResources() .getBoolean(com.android.internal.R.bool.config_notificationBadging); } @Override public void updateState(Preference preference) { final boolean checked = Settings.Secure.getInt(mContext.getContentResolver(), NOTIFICATION_BADGING, DEFAULT_VALUE) == 1; ((TwoStatePreference) preference).setChecked(checked); } @Override public boolean onPreferenceChange(Preference preference, Object newValue) { final boolean val = (Boolean) newValue; return Settings.Secure.putInt(mContext.getContentResolver(), NOTIFICATION_BADGING, val ? 1 : 0); } class SettingObserver extends ContentObserver { private final Uri NOTIFICATION_BADGING_URI = Settings.Secure.getUriFor(NOTIFICATION_BADGING); private final Preference mPreference; public SettingObserver(Preference preference) { super(new Handler()); mPreference = preference; } public void register(ContentResolver cr, boolean register) { if (register) { cr.registerContentObserver(NOTIFICATION_BADGING_URI, false, this); } else { cr.unregisterContentObserver(this); } } @Override public void onChange(boolean selfChange, Uri uri) { super.onChange(selfChange, uri); if (NOTIFICATION_BADGING_URI.equals(uri)) { updateState(mPreference); } } } } src/com/android/settings/notification/ConfigureNotificationSettings.java +3 −0 Original line number Diff line number Diff line Loading @@ -58,6 +58,8 @@ public class ConfigureNotificationSettings extends DashboardFragment { private static List<PreferenceController> buildPreferenceControllers(Context context, Lifecycle lifecycle) { final List<PreferenceController> controllers = new ArrayList<>(); final BadgingNotificationPreferenceController badgeController = new BadgingNotificationPreferenceController(context); final PulseNotificationPreferenceController pulseController = new PulseNotificationPreferenceController(context); final LockScreenNotificationPreferenceController lockScreenNotificationController = Loading @@ -67,6 +69,7 @@ public class ConfigureNotificationSettings extends DashboardFragment { lifecycle.addObserver(lockScreenNotificationController); } controllers.add(new SwipeToNotificationPreferenceController(context, lifecycle)); controllers.add(badgeController); controllers.add(pulseController); controllers.add(lockScreenNotificationController); return controllers; Loading tests/robotests/src/com/android/settings/notification/BadgingNotificationPreferenceControllerTest.java 0 → 100644 +109 −0 Original line number Diff line number Diff line /* * 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.settings.notification; import android.content.Context; import android.provider.Settings; import android.support.v7.preference.Preference; import android.support.v7.preference.PreferenceScreen; import android.support.v7.preference.TwoStatePreference; import com.android.settings.TestConfig; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.Answers; import org.mockito.Mock; import org.mockito.MockitoAnnotations; import org.robolectric.RobolectricTestRunner; import org.robolectric.annotation.Config; import org.robolectric.shadows.ShadowApplication; import static android.provider.Settings.Secure.NOTIFICATION_BADGING; import static org.mockito.Mockito.any; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.never; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; @RunWith(RobolectricTestRunner.class) @Config(manifest = TestConfig.MANIFEST_PATH, sdk = TestConfig.SDK_VERSION) public class BadgingNotificationPreferenceControllerTest { @Mock(answer = Answers.RETURNS_DEEP_STUBS) private Context mContext; @Mock(answer = Answers.RETURNS_DEEP_STUBS) private PreferenceScreen mScreen; private BadgingNotificationPreferenceController mController; @Before public void setUp() { MockitoAnnotations.initMocks(this); mController = new BadgingNotificationPreferenceController(mContext); } @Test public void display_configIsTrue_shouldDisplay() { when(mContext.getResources(). getBoolean(com.android.internal.R.bool.config_notificationBadging)) .thenReturn(true); mController.displayPreference(mScreen); verify(mScreen, never()).removePreference(any(Preference.class)); } @Test public void display_configIsFalse_shouldNotDisplay() { when(mContext.getResources(). getBoolean(com.android.internal.R.bool.config_notificationBadging)) .thenReturn(false); final Preference preference = mock(Preference.class); when(mScreen.getPreferenceCount()).thenReturn(1); when(mScreen.getPreference(0)).thenReturn(preference); when(preference.getKey()).thenReturn(mController.getPreferenceKey()); mController.displayPreference(mScreen); verify(mScreen).removePreference(any(Preference.class)); } @Test public void updateState_preferenceSetCheckedWhenSettingIsOn() { final TwoStatePreference preference = mock(TwoStatePreference.class); final Context context = ShadowApplication.getInstance().getApplicationContext(); Settings.Secure.putInt(context.getContentResolver(), NOTIFICATION_BADGING, 1); mController = new BadgingNotificationPreferenceController(context); mController.updateState(preference); verify(preference).setChecked(true); } @Test public void updateState_preferenceSetUncheckedWhenSettingIsOff() { final TwoStatePreference preference = mock(TwoStatePreference.class); final Context context = ShadowApplication.getInstance().getApplicationContext(); Settings.Secure.putInt(context.getContentResolver(), NOTIFICATION_BADGING, 0); mController = new BadgingNotificationPreferenceController(context); mController.updateState(preference); verify(preference).setChecked(false); } } Loading
res/values/strings.xml +3 −0 Original line number Diff line number Diff line Loading @@ -6515,6 +6515,9 @@ <!-- Configure Notifications: Work profile section header [CHAR LIMIT=30] --> <string name="profile_section_header">Work notifications</string> <!-- Configure Notifications: Title for the notification badging option. [CHAR LIMIT=30] --> <string name="notification_badging_title">Allow icon badges</string> <!-- Configure Notifications: Title for the pulse notification light option. [CHAR LIMIT=30] --> <string name="notification_pulse_title">Blink light</string>
res/xml/configure_notification_settings.xml +5 −0 Original line number Diff line number Diff line Loading @@ -22,6 +22,11 @@ android:key="dashboard_tile_placeholder" android:order="1"/> <!-- Notification badging --> <SwitchPreference android:key="notification_badging" android:title="@string/notification_badging_title"/> <!-- Pulse notification light --> <SwitchPreference android:key="notification_pulse" Loading
src/com/android/settings/notification/BadgingNotificationPreferenceController.java 0 → 100644 +126 −0 Original line number Diff line number Diff line /* * 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.settings.notification; import android.content.ContentResolver; import android.content.Context; import android.database.ContentObserver; import android.net.Uri; import android.os.Handler; import android.provider.Settings; import android.support.v7.preference.Preference; import android.support.v7.preference.PreferenceScreen; import android.support.v7.preference.TwoStatePreference; import android.util.Log; import com.android.settings.core.PreferenceController; import com.android.settings.core.lifecycle.LifecycleObserver; import com.android.settings.core.lifecycle.events.OnPause; import com.android.settings.core.lifecycle.events.OnResume; import static android.provider.Settings.Secure.NOTIFICATION_BADGING; public class BadgingNotificationPreferenceController extends PreferenceController implements Preference.OnPreferenceChangeListener, LifecycleObserver, OnResume, OnPause { private static final String TAG = "BadgeNotifPrefContr"; private static final String KEY_NOTIFICATION_BADGING = "notification_badging"; private static final int DEFAULT_VALUE = 1; private SettingObserver mSettingObserver; public BadgingNotificationPreferenceController(Context context) { super(context); } @Override public void displayPreference(PreferenceScreen screen) { super.displayPreference(screen); Preference preference = screen.findPreference(NOTIFICATION_BADGING); if (preference != null) { mSettingObserver = new SettingObserver(preference); } } @Override public void onResume() { if (mSettingObserver != null) { mSettingObserver.register(mContext.getContentResolver(), true /* register */); } } @Override public void onPause() { if (mSettingObserver != null) { mSettingObserver.register(mContext.getContentResolver(), false /* register */); } } @Override public String getPreferenceKey() { return KEY_NOTIFICATION_BADGING; } @Override public boolean isAvailable() { return mContext.getResources() .getBoolean(com.android.internal.R.bool.config_notificationBadging); } @Override public void updateState(Preference preference) { final boolean checked = Settings.Secure.getInt(mContext.getContentResolver(), NOTIFICATION_BADGING, DEFAULT_VALUE) == 1; ((TwoStatePreference) preference).setChecked(checked); } @Override public boolean onPreferenceChange(Preference preference, Object newValue) { final boolean val = (Boolean) newValue; return Settings.Secure.putInt(mContext.getContentResolver(), NOTIFICATION_BADGING, val ? 1 : 0); } class SettingObserver extends ContentObserver { private final Uri NOTIFICATION_BADGING_URI = Settings.Secure.getUriFor(NOTIFICATION_BADGING); private final Preference mPreference; public SettingObserver(Preference preference) { super(new Handler()); mPreference = preference; } public void register(ContentResolver cr, boolean register) { if (register) { cr.registerContentObserver(NOTIFICATION_BADGING_URI, false, this); } else { cr.unregisterContentObserver(this); } } @Override public void onChange(boolean selfChange, Uri uri) { super.onChange(selfChange, uri); if (NOTIFICATION_BADGING_URI.equals(uri)) { updateState(mPreference); } } } }
src/com/android/settings/notification/ConfigureNotificationSettings.java +3 −0 Original line number Diff line number Diff line Loading @@ -58,6 +58,8 @@ public class ConfigureNotificationSettings extends DashboardFragment { private static List<PreferenceController> buildPreferenceControllers(Context context, Lifecycle lifecycle) { final List<PreferenceController> controllers = new ArrayList<>(); final BadgingNotificationPreferenceController badgeController = new BadgingNotificationPreferenceController(context); final PulseNotificationPreferenceController pulseController = new PulseNotificationPreferenceController(context); final LockScreenNotificationPreferenceController lockScreenNotificationController = Loading @@ -67,6 +69,7 @@ public class ConfigureNotificationSettings extends DashboardFragment { lifecycle.addObserver(lockScreenNotificationController); } controllers.add(new SwipeToNotificationPreferenceController(context, lifecycle)); controllers.add(badgeController); controllers.add(pulseController); controllers.add(lockScreenNotificationController); return controllers; Loading
tests/robotests/src/com/android/settings/notification/BadgingNotificationPreferenceControllerTest.java 0 → 100644 +109 −0 Original line number Diff line number Diff line /* * 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.settings.notification; import android.content.Context; import android.provider.Settings; import android.support.v7.preference.Preference; import android.support.v7.preference.PreferenceScreen; import android.support.v7.preference.TwoStatePreference; import com.android.settings.TestConfig; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.Answers; import org.mockito.Mock; import org.mockito.MockitoAnnotations; import org.robolectric.RobolectricTestRunner; import org.robolectric.annotation.Config; import org.robolectric.shadows.ShadowApplication; import static android.provider.Settings.Secure.NOTIFICATION_BADGING; import static org.mockito.Mockito.any; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.never; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; @RunWith(RobolectricTestRunner.class) @Config(manifest = TestConfig.MANIFEST_PATH, sdk = TestConfig.SDK_VERSION) public class BadgingNotificationPreferenceControllerTest { @Mock(answer = Answers.RETURNS_DEEP_STUBS) private Context mContext; @Mock(answer = Answers.RETURNS_DEEP_STUBS) private PreferenceScreen mScreen; private BadgingNotificationPreferenceController mController; @Before public void setUp() { MockitoAnnotations.initMocks(this); mController = new BadgingNotificationPreferenceController(mContext); } @Test public void display_configIsTrue_shouldDisplay() { when(mContext.getResources(). getBoolean(com.android.internal.R.bool.config_notificationBadging)) .thenReturn(true); mController.displayPreference(mScreen); verify(mScreen, never()).removePreference(any(Preference.class)); } @Test public void display_configIsFalse_shouldNotDisplay() { when(mContext.getResources(). getBoolean(com.android.internal.R.bool.config_notificationBadging)) .thenReturn(false); final Preference preference = mock(Preference.class); when(mScreen.getPreferenceCount()).thenReturn(1); when(mScreen.getPreference(0)).thenReturn(preference); when(preference.getKey()).thenReturn(mController.getPreferenceKey()); mController.displayPreference(mScreen); verify(mScreen).removePreference(any(Preference.class)); } @Test public void updateState_preferenceSetCheckedWhenSettingIsOn() { final TwoStatePreference preference = mock(TwoStatePreference.class); final Context context = ShadowApplication.getInstance().getApplicationContext(); Settings.Secure.putInt(context.getContentResolver(), NOTIFICATION_BADGING, 1); mController = new BadgingNotificationPreferenceController(context); mController.updateState(preference); verify(preference).setChecked(true); } @Test public void updateState_preferenceSetUncheckedWhenSettingIsOff() { final TwoStatePreference preference = mock(TwoStatePreference.class); final Context context = ShadowApplication.getInstance().getApplicationContext(); Settings.Secure.putInt(context.getContentResolver(), NOTIFICATION_BADGING, 0); mController = new BadgingNotificationPreferenceController(context); mController.updateState(preference); verify(preference).setChecked(false); } }