diff --git a/res/values/strings.xml b/res/values/strings.xml index 73c7e3b04c5..f3027011342 100644 --- a/res/values/strings.xml +++ b/res/values/strings.xml @@ -6161,6 +6161,11 @@ Your current work profile sounds will be replaced with your personal profile sounds + + Ringtones + + + Other sounds and vibrations Notification preferences diff --git a/res/xml/ia_sound_settings.xml b/res/xml/ia_sound_settings.xml new file mode 100644 index 00000000000..e63db0d53f9 --- /dev/null +++ b/res/xml/ia_sound_settings.xml @@ -0,0 +1,152 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/com/android/settings/notification/BootSoundPreferenceController.java b/src/com/android/settings/notification/BootSoundPreferenceController.java new file mode 100644 index 00000000000..b644ee9a4c0 --- /dev/null +++ b/src/com/android/settings/notification/BootSoundPreferenceController.java @@ -0,0 +1,66 @@ +/* + * 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.os.SystemProperties; +import android.support.annotation.VisibleForTesting; +import android.support.v14.preference.SwitchPreference; +import android.support.v7.preference.Preference; +import android.support.v7.preference.PreferenceScreen; +import com.android.settings.core.PreferenceController; + +public class BootSoundPreferenceController extends PreferenceController { + + // Boot Sounds needs to be a system property so it can be accessed during boot. + private static final String KEY_BOOT_SOUNDS = "boot_sounds"; + @VisibleForTesting + static final String PROPERTY_BOOT_SOUNDS = "persist.sys.bootanim.play_sound"; + + public BootSoundPreferenceController(Context context) { + super(context); + } + + @Override + public void displayPreference(PreferenceScreen screen) { + super.displayPreference(screen); + if (isAvailable()) { + SwitchPreference preference = (SwitchPreference) screen.findPreference(KEY_BOOT_SOUNDS); + preference.setChecked(SystemProperties.getBoolean(PROPERTY_BOOT_SOUNDS, true)); + } + } + + @Override + public boolean handlePreferenceTreeClick(Preference preference) { + if (KEY_BOOT_SOUNDS.equals(preference.getKey())) { + SwitchPreference switchPreference = (SwitchPreference) preference; + SystemProperties.set(PROPERTY_BOOT_SOUNDS, switchPreference.isChecked() ? "1" : "0"); + } + return false; + } + + @Override + public String getPreferenceKey() { + return KEY_BOOT_SOUNDS; + } + + @Override + public boolean isAvailable() { + return mContext.getResources().getBoolean(com.android.settings.R.bool.has_boot_sounds); + } + +} \ No newline at end of file diff --git a/src/com/android/settings/notification/ChargingSoundPreferenceController.java b/src/com/android/settings/notification/ChargingSoundPreferenceController.java new file mode 100644 index 00000000000..1114b4a6622 --- /dev/null +++ b/src/com/android/settings/notification/ChargingSoundPreferenceController.java @@ -0,0 +1,39 @@ +/* + * 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 static com.android.settings.notification.SettingPref.TYPE_GLOBAL; + +import android.content.Context; + +import android.provider.Settings.Global; +import com.android.settings.SettingsPreferenceFragment; +import com.android.settings.core.lifecycle.Lifecycle; + +public class ChargingSoundPreferenceController extends SettingPrefController { + + private static final String KEY_CHARGING_SOUNDS = "charging_sounds"; + + public ChargingSoundPreferenceController(Context context, SettingsPreferenceFragment parent, + Lifecycle lifecycle) { + super(context, parent, lifecycle); + mPreference = new SettingPref( + TYPE_GLOBAL, KEY_CHARGING_SOUNDS, Global.CHARGING_SOUNDS_ENABLED, DEFAULT_ON); + + } + +} diff --git a/src/com/android/settings/notification/DialPadTonePreferenceController.java b/src/com/android/settings/notification/DialPadTonePreferenceController.java new file mode 100644 index 00000000000..08e1a7d5d71 --- /dev/null +++ b/src/com/android/settings/notification/DialPadTonePreferenceController.java @@ -0,0 +1,44 @@ +/* + * 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 static com.android.settings.notification.SettingPref.TYPE_SYSTEM; + +import android.content.Context; + +import android.provider.Settings.System; +import com.android.settings.SettingsPreferenceFragment; +import com.android.settings.Utils; +import com.android.settings.core.lifecycle.Lifecycle; + +public class DialPadTonePreferenceController extends SettingPrefController { + + private static final String KEY_DIAL_PAD_TONES = "dial_pad_tones"; + + public DialPadTonePreferenceController(Context context, SettingsPreferenceFragment parent, + Lifecycle lifecycle) { + super(context, parent, lifecycle); + mPreference = new SettingPref( + TYPE_SYSTEM, KEY_DIAL_PAD_TONES, System.DTMF_TONE_WHEN_DIALING, DEFAULT_ON) { + @Override + public boolean isApplicable(Context context) { + return Utils.isVoiceCapable(context); + } + }; + } + +} diff --git a/src/com/android/settings/notification/DockAudioMediaPreferenceController.java b/src/com/android/settings/notification/DockAudioMediaPreferenceController.java new file mode 100644 index 00000000000..20c20b46e36 --- /dev/null +++ b/src/com/android/settings/notification/DockAudioMediaPreferenceController.java @@ -0,0 +1,64 @@ +/* + * 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 static com.android.settings.notification.SettingPref.TYPE_GLOBAL; + +import android.content.Context; + +import android.content.res.Resources; +import android.provider.Settings.Global; +import android.telephony.TelephonyManager; +import com.android.settings.SettingsPreferenceFragment; +import com.android.settings.core.lifecycle.Lifecycle; + +public class DockAudioMediaPreferenceController extends SettingPrefController { + + private static final String KEY_DOCK_AUDIO_MEDIA = "dock_audio_media"; + + private static final int DOCK_AUDIO_MEDIA_DISABLED = 0; + private static final int DOCK_AUDIO_MEDIA_ENABLED = 1; + private static final int DEFAULT_DOCK_AUDIO_MEDIA = DOCK_AUDIO_MEDIA_DISABLED; + + public DockAudioMediaPreferenceController(Context context, SettingsPreferenceFragment parent, + Lifecycle lifecycle) { + super(context, parent, lifecycle); + mPreference = new SettingPref( + TYPE_GLOBAL, KEY_DOCK_AUDIO_MEDIA, Global.DOCK_AUDIO_MEDIA_ENABLED, + DEFAULT_DOCK_AUDIO_MEDIA, DOCK_AUDIO_MEDIA_DISABLED, DOCK_AUDIO_MEDIA_ENABLED) { + @Override + public boolean isApplicable(Context context) { + return context.getResources().getBoolean( + com.android.settings.R.bool.has_dock_settings); + } + + @Override + protected String getCaption(Resources res, int value) { + switch(value) { + case DOCK_AUDIO_MEDIA_DISABLED: + return res.getString( + com.android.settings.R.string.dock_audio_media_disabled); + case DOCK_AUDIO_MEDIA_ENABLED: + return res.getString( + com.android.settings.R.string.dock_audio_media_enabled); + default: + throw new IllegalArgumentException(); + } + } + }; + } +} diff --git a/src/com/android/settings/notification/DockingSoundPreferenceController.java b/src/com/android/settings/notification/DockingSoundPreferenceController.java new file mode 100644 index 00000000000..ee277f047ad --- /dev/null +++ b/src/com/android/settings/notification/DockingSoundPreferenceController.java @@ -0,0 +1,43 @@ +/* + * 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 static com.android.settings.notification.SettingPref.TYPE_GLOBAL; + +import android.content.Context; +import android.provider.Settings.Global; +import com.android.settings.R; +import com.android.settings.SettingsPreferenceFragment; +import com.android.settings.core.lifecycle.Lifecycle; + +public class DockingSoundPreferenceController extends SettingPrefController { + + private static final String KEY_DOCKING_SOUNDS = "docking_sounds"; + + public DockingSoundPreferenceController(Context context, SettingsPreferenceFragment parent, + Lifecycle lifecycle) { + super(context, parent, lifecycle); + mPreference = new SettingPref( + TYPE_GLOBAL, KEY_DOCKING_SOUNDS, Global.DOCK_SOUNDS_ENABLED, DEFAULT_ON) { + @Override + public boolean isApplicable(Context context) { + return context.getResources().getBoolean(R.bool.has_dock_settings); + } + }; + } + +} diff --git a/src/com/android/settings/notification/EmergencyTonePreferenceController.java b/src/com/android/settings/notification/EmergencyTonePreferenceController.java new file mode 100644 index 00000000000..bc21f44fd71 --- /dev/null +++ b/src/com/android/settings/notification/EmergencyTonePreferenceController.java @@ -0,0 +1,69 @@ +/* + * 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 static com.android.settings.notification.SettingPref.TYPE_GLOBAL; + +import android.content.Context; + +import android.content.res.Resources; +import android.provider.Settings.Global; +import android.telephony.TelephonyManager; +import com.android.settings.R; +import com.android.settings.SettingsPreferenceFragment; +import com.android.settings.core.lifecycle.Lifecycle; + +public class EmergencyTonePreferenceController extends SettingPrefController { + + private static final String KEY_EMERGENCY_TONE = "emergency_tone"; + private static final int EMERGENCY_TONE_SILENT = 0; + private static final int EMERGENCY_TONE_ALERT = 1; + private static final int EMERGENCY_TONE_VIBRATE = 2; + private static final int DEFAULT_EMERGENCY_TONE = EMERGENCY_TONE_SILENT; + + public EmergencyTonePreferenceController(Context context, SettingsPreferenceFragment parent, + Lifecycle lifecycle) { + super(context, parent, lifecycle); + mPreference = new SettingPref( + TYPE_GLOBAL, KEY_EMERGENCY_TONE, Global.EMERGENCY_TONE, DEFAULT_EMERGENCY_TONE, + EMERGENCY_TONE_ALERT, EMERGENCY_TONE_VIBRATE, EMERGENCY_TONE_SILENT) { + + @Override + public boolean isApplicable(Context context) { + final TelephonyManager telephony = + (TelephonyManager) context.getSystemService(Context.TELEPHONY_SERVICE); + return telephony != null + && telephony.getCurrentPhoneType() == TelephonyManager.PHONE_TYPE_CDMA; + } + + @Override + protected String getCaption(Resources res, int value) { + switch(value) { + case EMERGENCY_TONE_SILENT: + return res.getString(R.string.emergency_tone_silent); + case EMERGENCY_TONE_ALERT: + return res.getString(R.string.emergency_tone_alert); + case EMERGENCY_TONE_VIBRATE: + return res.getString(R.string.emergency_tone_vibrate); + default: + throw new IllegalArgumentException(); + } + } + }; + } + +} diff --git a/src/com/android/settings/notification/OtherSoundSettings.java b/src/com/android/settings/notification/OtherSoundSettings.java index cf47cb5f459..15e7f8c466b 100644 --- a/src/com/android/settings/notification/OtherSoundSettings.java +++ b/src/com/android/settings/notification/OtherSoundSettings.java @@ -16,177 +16,26 @@ package com.android.settings.notification; -import android.content.ContentResolver; import android.content.Context; -import android.content.res.Resources; -import android.database.ContentObserver; -import android.media.AudioManager; -import android.net.Uri; -import android.os.AsyncTask; -import android.os.Bundle; -import android.os.Handler; -import android.os.SystemProperties; -import android.os.Vibrator; import android.provider.SearchIndexableResource; -import android.provider.Settings.Global; -import android.provider.Settings.System; -import android.support.v14.preference.SwitchPreference; -import android.support.v7.preference.Preference; -import android.telephony.TelephonyManager; import com.android.internal.logging.nano.MetricsProto.MetricsEvent; import com.android.settings.R; -import com.android.settings.SettingsPreferenceFragment; -import com.android.settings.Utils; +import com.android.settings.core.PreferenceController; +import com.android.settings.core.lifecycle.Lifecycle; +import com.android.settings.dashboard.DashboardFragment; import com.android.settings.search.BaseSearchIndexProvider; -import com.android.settings.search.Indexable; import java.util.ArrayList; import java.util.Arrays; import java.util.List; -import static com.android.settings.notification.SettingPref.TYPE_GLOBAL; -import static com.android.settings.notification.SettingPref.TYPE_SYSTEM; - -public class OtherSoundSettings extends SettingsPreferenceFragment implements Indexable { +/* This class has been deprecated Modifications to Other Sounds settings should be made in + {@link SoundSettings } instead. */ +@Deprecated +public class OtherSoundSettings extends DashboardFragment { private static final String TAG = "OtherSoundSettings"; - private static final int DEFAULT_ON = 1; - - private static final int EMERGENCY_TONE_SILENT = 0; - private static final int EMERGENCY_TONE_ALERT = 1; - private static final int EMERGENCY_TONE_VIBRATE = 2; - private static final int DEFAULT_EMERGENCY_TONE = EMERGENCY_TONE_SILENT; - - private static final int DOCK_AUDIO_MEDIA_DISABLED = 0; - private static final int DOCK_AUDIO_MEDIA_ENABLED = 1; - private static final int DEFAULT_DOCK_AUDIO_MEDIA = DOCK_AUDIO_MEDIA_DISABLED; - - private static final String KEY_DIAL_PAD_TONES = "dial_pad_tones"; - private static final String KEY_SCREEN_LOCKING_SOUNDS = "screen_locking_sounds"; - private static final String KEY_CHARGING_SOUNDS = "charging_sounds"; - private static final String KEY_DOCKING_SOUNDS = "docking_sounds"; - private static final String KEY_TOUCH_SOUNDS = "touch_sounds"; - private static final String KEY_VIBRATE_ON_TOUCH = "vibrate_on_touch"; - private static final String KEY_DOCK_AUDIO_MEDIA = "dock_audio_media"; - private static final String KEY_EMERGENCY_TONE = "emergency_tone"; - - // Boot Sounds needs to be a system property so it can be accessed during boot. - private static final String KEY_BOOT_SOUNDS = "boot_sounds"; - private static final String PROPERTY_BOOT_SOUNDS = "persist.sys.bootanim.play_sound"; - - private static final SettingPref PREF_DIAL_PAD_TONES = new SettingPref( - TYPE_SYSTEM, KEY_DIAL_PAD_TONES, System.DTMF_TONE_WHEN_DIALING, DEFAULT_ON) { - @Override - public boolean isApplicable(Context context) { - return Utils.isVoiceCapable(context); - } - }; - - private static final SettingPref PREF_SCREEN_LOCKING_SOUNDS = new SettingPref( - TYPE_SYSTEM, KEY_SCREEN_LOCKING_SOUNDS, System.LOCKSCREEN_SOUNDS_ENABLED, DEFAULT_ON); - - private static final SettingPref PREF_CHARGING_SOUNDS = new SettingPref( - TYPE_GLOBAL, KEY_CHARGING_SOUNDS, Global.CHARGING_SOUNDS_ENABLED, DEFAULT_ON); - - private static final SettingPref PREF_DOCKING_SOUNDS = new SettingPref( - TYPE_GLOBAL, KEY_DOCKING_SOUNDS, Global.DOCK_SOUNDS_ENABLED, DEFAULT_ON) { - @Override - public boolean isApplicable(Context context) { - return hasDockSettings(context); - } - }; - - private static final SettingPref PREF_TOUCH_SOUNDS = new SettingPref( - TYPE_SYSTEM, KEY_TOUCH_SOUNDS, System.SOUND_EFFECTS_ENABLED, DEFAULT_ON) { - @Override - protected boolean setSetting(final Context context, final int value) { - AsyncTask.execute(new Runnable() { - @Override - public void run() { - final AudioManager am = - (AudioManager) context.getSystemService(Context.AUDIO_SERVICE); - if (value != 0) { - am.loadSoundEffects(); - } else { - am.unloadSoundEffects(); - } - } - }); - return super.setSetting(context, value); - } - }; - - private static final SettingPref PREF_VIBRATE_ON_TOUCH = new SettingPref( - TYPE_SYSTEM, KEY_VIBRATE_ON_TOUCH, System.HAPTIC_FEEDBACK_ENABLED, DEFAULT_ON) { - @Override - public boolean isApplicable(Context context) { - return hasHaptic(context); - } - }; - - private static final SettingPref PREF_DOCK_AUDIO_MEDIA = new SettingPref( - TYPE_GLOBAL, KEY_DOCK_AUDIO_MEDIA, Global.DOCK_AUDIO_MEDIA_ENABLED, - DEFAULT_DOCK_AUDIO_MEDIA, DOCK_AUDIO_MEDIA_DISABLED, DOCK_AUDIO_MEDIA_ENABLED) { - @Override - public boolean isApplicable(Context context) { - return hasDockSettings(context); - } - - @Override - protected String getCaption(Resources res, int value) { - switch(value) { - case DOCK_AUDIO_MEDIA_DISABLED: - return res.getString(R.string.dock_audio_media_disabled); - case DOCK_AUDIO_MEDIA_ENABLED: - return res.getString(R.string.dock_audio_media_enabled); - default: - throw new IllegalArgumentException(); - } - } - }; - - private static final SettingPref PREF_EMERGENCY_TONE = new SettingPref( - TYPE_GLOBAL, KEY_EMERGENCY_TONE, Global.EMERGENCY_TONE, DEFAULT_EMERGENCY_TONE, - EMERGENCY_TONE_ALERT, EMERGENCY_TONE_VIBRATE, EMERGENCY_TONE_SILENT) { - @Override - public boolean isApplicable(Context context) { - final int activePhoneType = TelephonyManager.getDefault().getCurrentPhoneType(); - return activePhoneType == TelephonyManager.PHONE_TYPE_CDMA; - } - - @Override - protected String getCaption(Resources res, int value) { - switch(value) { - case EMERGENCY_TONE_SILENT: - return res.getString(R.string.emergency_tone_silent); - case EMERGENCY_TONE_ALERT: - return res.getString(R.string.emergency_tone_alert); - case EMERGENCY_TONE_VIBRATE: - return res.getString(R.string.emergency_tone_vibrate); - default: - throw new IllegalArgumentException(); - } - } - }; - - private static final SettingPref[] PREFS = { - PREF_DIAL_PAD_TONES, - PREF_SCREEN_LOCKING_SOUNDS, - PREF_CHARGING_SOUNDS, - PREF_DOCKING_SOUNDS, - PREF_TOUCH_SOUNDS, - PREF_VIBRATE_ON_TOUCH, - PREF_DOCK_AUDIO_MEDIA, - PREF_EMERGENCY_TONE, - }; - - private SwitchPreference mBootSounds; - - private final SettingsObserver mSettingsObserver = new SettingsObserver(); - - private Context mContext; - @Override public int getMetricsCategory() { return MetricsEvent.NOTIFICATION_OTHER_SOUND; @@ -198,84 +47,34 @@ public class OtherSoundSettings extends SettingsPreferenceFragment implements In } @Override - public void onCreate(Bundle savedInstanceState) { - super.onCreate(savedInstanceState); - - addPreferencesFromResource(R.xml.other_sound_settings); - - mContext = getActivity(); - - for (SettingPref pref : PREFS) { - pref.init(this); - } - - if (mContext.getResources().getBoolean(R.bool.has_boot_sounds)) { - mBootSounds = (SwitchPreference) findPreference(KEY_BOOT_SOUNDS); - mBootSounds.setChecked(SystemProperties.getBoolean(PROPERTY_BOOT_SOUNDS, true)); - } else { - removePreference(KEY_BOOT_SOUNDS); - } + protected String getCategoryKey() { + return null; } @Override - public void onResume() { - super.onResume(); - mSettingsObserver.register(true); + protected String getLogTag() { + return TAG; } @Override - public void onPause() { - super.onPause(); - mSettingsObserver.register(false); + protected int getPreferenceScreenResId() { + return R.xml.other_sound_settings; } @Override - public boolean onPreferenceTreeClick(Preference preference) { - if (mBootSounds != null && preference == mBootSounds) { - SystemProperties.set(PROPERTY_BOOT_SOUNDS, mBootSounds.isChecked() ? "1" : "0"); - return false; - } else { - return super.onPreferenceTreeClick(preference); - } - } - - private static boolean hasDockSettings(Context context) { - return context.getResources().getBoolean(R.bool.has_dock_settings); - } - - private static boolean hasHaptic(Context context) { - final Vibrator vibrator = (Vibrator) context.getSystemService(Context.VIBRATOR_SERVICE); - return vibrator != null && vibrator.hasVibrator(); - } - - // === Callbacks === - - private final class SettingsObserver extends ContentObserver { - public SettingsObserver() { - super(new Handler()); - } - - public void register(boolean register) { - final ContentResolver cr = getContentResolver(); - if (register) { - for (SettingPref pref : PREFS) { - cr.registerContentObserver(pref.getUri(), false, this); - } - } else { - cr.unregisterContentObserver(this); - } - } - - @Override - public void onChange(boolean selfChange, Uri uri) { - super.onChange(selfChange, uri); - for (SettingPref pref : PREFS) { - if (pref.getUri().equals(uri)) { - pref.update(mContext); - return; - } - } - } + protected List getPreferenceControllers(Context context) { + final List controllers = new ArrayList<>(); + Lifecycle lifecycle = getLifecycle(); + controllers.add(new DialPadTonePreferenceController(context, this, lifecycle)); + controllers.add(new ScreenLockSoundPreferenceController(context, this, lifecycle)); + controllers.add(new ChargingSoundPreferenceController(context, this, lifecycle)); + controllers.add(new DockingSoundPreferenceController(context, this, lifecycle)); + controllers.add(new TouchSoundPreferenceController(context, this, lifecycle)); + controllers.add(new VibrateOnTouchPreferenceController(context, this, lifecycle)); + controllers.add(new DockAudioMediaPreferenceController(context, this, lifecycle)); + controllers.add(new BootSoundPreferenceController(context)); + controllers.add(new EmergencyTonePreferenceController(context, this, lifecycle)); + return controllers; } // === Indexing === @@ -292,11 +91,23 @@ public class OtherSoundSettings extends SettingsPreferenceFragment implements In public List getNonIndexableKeys(Context context) { final ArrayList rt = new ArrayList(); - for (SettingPref pref : PREFS) { - if (!pref.isApplicable(context)) { - rt.add(pref.getKey()); - } - } + new DialPadTonePreferenceController(context, null /* SettingsPreferenceFragment */, + null /* Lifecycle */).updateNonIndexableKeys(rt); + new ScreenLockSoundPreferenceController(context, null /* SettingsPreferenceFragment */, + null /* Lifecycle */).updateNonIndexableKeys(rt); + new ChargingSoundPreferenceController(context, null /* SettingsPreferenceFragment */, + null /* Lifecycle */).updateNonIndexableKeys(rt); + new DockingSoundPreferenceController(context, null /* SettingsPreferenceFragment */, + null /* Lifecycle */).updateNonIndexableKeys(rt); + new TouchSoundPreferenceController(context, null /* SettingsPreferenceFragment */, + null /* Lifecycle */).updateNonIndexableKeys(rt); + new VibrateOnTouchPreferenceController(context, null /* SettingsPreferenceFragment */, + null /* Lifecycle */).updateNonIndexableKeys(rt); + new DockAudioMediaPreferenceController(context, null /* SettingsPreferenceFragment */, + null /* Lifecycle */).updateNonIndexableKeys(rt); + new BootSoundPreferenceController(context).updateNonIndexableKeys(rt); + new EmergencyTonePreferenceController(context, null /* SettingsPreferenceFragment */, + null /* Lifecycle */).updateNonIndexableKeys(rt); return rt; } }; diff --git a/src/com/android/settings/notification/ScreenLockSoundPreferenceController.java b/src/com/android/settings/notification/ScreenLockSoundPreferenceController.java new file mode 100644 index 00000000000..f9905c056e6 --- /dev/null +++ b/src/com/android/settings/notification/ScreenLockSoundPreferenceController.java @@ -0,0 +1,38 @@ +/* + * 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 static com.android.settings.notification.SettingPref.TYPE_SYSTEM; + +import android.content.Context; + +import android.provider.Settings.System; +import com.android.settings.SettingsPreferenceFragment; +import com.android.settings.core.lifecycle.Lifecycle; + +public class ScreenLockSoundPreferenceController extends SettingPrefController { + + private static final String KEY_SCREEN_LOCKING_SOUNDS = "screen_locking_sounds"; + + public ScreenLockSoundPreferenceController(Context context, SettingsPreferenceFragment parent, + Lifecycle lifecycle) { + super(context, parent, lifecycle); + mPreference = new SettingPref( + TYPE_SYSTEM, KEY_SCREEN_LOCKING_SOUNDS, System.LOCKSCREEN_SOUNDS_ENABLED, DEFAULT_ON); + } + +} diff --git a/src/com/android/settings/notification/SettingPrefController.java b/src/com/android/settings/notification/SettingPrefController.java new file mode 100644 index 00000000000..d126fc4727a --- /dev/null +++ b/src/com/android/settings/notification/SettingPrefController.java @@ -0,0 +1,123 @@ +/* + * 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.support.v7.preference.Preference; +import android.support.v7.preference.PreferenceScreen; + +import com.android.internal.annotations.VisibleForTesting; +import com.android.settings.SettingsPreferenceFragment; +import com.android.settings.core.PreferenceController; +import com.android.settings.core.lifecycle.Lifecycle; +import com.android.settings.core.lifecycle.LifecycleObserver; +import com.android.settings.core.lifecycle.events.OnPause; +import com.android.settings.core.lifecycle.events.OnResume; +import java.util.List; + +public abstract class SettingPrefController extends PreferenceController implements + LifecycleObserver, OnResume, OnPause { + + protected static final int DEFAULT_ON = 1; + + private SettingsPreferenceFragment mParent; + protected SettingsObserver mSettingsObserver; + protected SettingPref mPreference; + + public SettingPrefController(Context context, SettingsPreferenceFragment parent, + Lifecycle lifecycle) { + super(context); + mParent = parent; + if (lifecycle != null) { + lifecycle.addObserver(this); + } + } + + @Override + public void displayPreference(PreferenceScreen screen) { + mPreference.init(mParent); + if (isAvailable()) { + mSettingsObserver = new SettingsObserver(); + } + } + + @Override + public String getPreferenceKey() { + return mPreference.getKey(); + } + + @Override + public boolean isAvailable() { + return mPreference.isApplicable(mContext); + } + + @Override + public void updateNonIndexableKeys(List keys) { + if (!mPreference.isApplicable(mContext)) { + keys.add(mPreference.getKey()); + } + } + + @Override + public void updateState(Preference preference) { + mPreference.update(mContext); + } + + @Override + public void onResume() { + if (mSettingsObserver != null) { + mSettingsObserver.register(true /* register */); + } + } + + @Override + public void onPause() { + if (mSettingsObserver != null) { + mSettingsObserver.register(false /* register */); + } + } + + @VisibleForTesting + final class SettingsObserver extends ContentObserver { + public SettingsObserver() { + super(new Handler()); + } + + public void register(boolean register) { + final ContentResolver cr = mContext.getContentResolver(); + if (register) { + cr.registerContentObserver(mPreference.getUri(), false, this); + } else { + cr.unregisterContentObserver(this); + } + } + + @Override + public void onChange(boolean selfChange, Uri uri) { + super.onChange(selfChange, uri); + if (mPreference.getUri().equals(uri)) { + mPreference.update(mContext); + } + } + } + +} diff --git a/src/com/android/settings/notification/SoundSettings.java b/src/com/android/settings/notification/SoundSettings.java index f156a8467e0..a55278d97c6 100644 --- a/src/com/android/settings/notification/SoundSettings.java +++ b/src/com/android/settings/notification/SoundSettings.java @@ -41,6 +41,7 @@ import com.android.settings.core.PreferenceController; import com.android.settings.core.lifecycle.Lifecycle; import com.android.settings.dashboard.DashboardFragment; import com.android.settings.dashboard.SummaryLoader; +import com.android.settings.overlay.FeatureFactory; import com.android.settings.search.BaseSearchIndexProvider; import com.android.settingslib.drawer.CategoryKey; import java.text.NumberFormat; @@ -113,14 +114,17 @@ public class SoundSettings extends DashboardFragment { @Override protected int getPreferenceScreenResId() { - return R.xml.sound_settings; + return mDashboardFeatureProvider.isEnabled() + ? R.xml.ia_sound_settings : R.xml.sound_settings; } @Override protected List getPreferenceControllers(Context context) { final List controllers = new ArrayList<>(); Lifecycle lifecycle = getLifecycle(); - controllers.add(new CastPreferenceController(context)); + if (!mDashboardFeatureProvider.isEnabled()) { + controllers.add(new CastPreferenceController(context)); + } controllers.add(new ZenModePreferenceController(context)); controllers.add(new EmergencyBroadcastPreferenceController(context)); controllers.add(new VibrateWhenRingPreferenceController(context)); @@ -141,6 +145,19 @@ public class SoundSettings extends DashboardFragment { mWorkSoundController = new WorkSoundPreferenceController(context, this, getLifecycle()); controllers.add(mWorkSoundController); + // === Other Sound Settings === + if (mDashboardFeatureProvider.isEnabled()) { + controllers.add(new DialPadTonePreferenceController(context, this, lifecycle)); + controllers.add(new ScreenLockSoundPreferenceController(context, this, lifecycle)); + controllers.add(new ChargingSoundPreferenceController(context, this, lifecycle)); + controllers.add(new DockingSoundPreferenceController(context, this, lifecycle)); + controllers.add(new TouchSoundPreferenceController(context, this, lifecycle)); + controllers.add(new VibrateOnTouchPreferenceController(context, this, lifecycle)); + controllers.add(new DockAudioMediaPreferenceController(context, this, lifecycle)); + controllers.add(new BootSoundPreferenceController(context)); + controllers.add(new EmergencyTonePreferenceController(context, this, lifecycle)); + } + return controllers; } @@ -297,10 +314,38 @@ public class SoundSettings extends DashboardFragment { context, null /* Callback */, null /* Lifecycle */).updateNonIndexableKeys(rt); new RingVolumePreferenceController( context, null /* Callback */, null /* Lifecycle */).updateNonIndexableKeys(rt); - new CastPreferenceController(context).updateNonIndexableKeys(rt); new PhoneRingtonePreferenceController(context).updateNonIndexableKeys(rt); new VibrateWhenRingPreferenceController(context).updateNonIndexableKeys(rt); new EmergencyBroadcastPreferenceController(context).updateNonIndexableKeys(rt); + if (FeatureFactory.getFactory(context).getDashboardFeatureProvider(context) + .isEnabled()) { + new DialPadTonePreferenceController(context, + null /* SettingsPreferenceFragment */, + null /* Lifecycle */).updateNonIndexableKeys(rt); + new ScreenLockSoundPreferenceController(context, + null /* SettingsPreferenceFragment */, + null /* Lifecycle */).updateNonIndexableKeys(rt); + new ChargingSoundPreferenceController(context, + null /* SettingsPreferenceFragment */, + null /* Lifecycle */).updateNonIndexableKeys(rt); + new DockingSoundPreferenceController(context, + null /* SettingsPreferenceFragment */, + null /* Lifecycle */).updateNonIndexableKeys(rt); + new TouchSoundPreferenceController(context, null /* SettingsPreferenceFragment */, + null /* Lifecycle */).updateNonIndexableKeys(rt); + new VibrateOnTouchPreferenceController(context, + null /* SettingsPreferenceFragment */, + null /* Lifecycle */).updateNonIndexableKeys(rt); + new DockAudioMediaPreferenceController(context, + null /* SettingsPreferenceFragment */, + null /* Lifecycle */).updateNonIndexableKeys(rt); + new BootSoundPreferenceController(context).updateNonIndexableKeys(rt); + new EmergencyTonePreferenceController(context, + null /* SettingsPreferenceFragment */, + null /* Lifecycle */).updateNonIndexableKeys(rt); + } else { + new CastPreferenceController(context).updateNonIndexableKeys(rt); + } return rt; } diff --git a/src/com/android/settings/notification/TouchSoundPreferenceController.java b/src/com/android/settings/notification/TouchSoundPreferenceController.java new file mode 100644 index 00000000000..4ca5ea002de --- /dev/null +++ b/src/com/android/settings/notification/TouchSoundPreferenceController.java @@ -0,0 +1,56 @@ +/* + * 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 static com.android.settings.notification.SettingPref.TYPE_SYSTEM; + +import android.content.Context; + +import android.media.AudioManager; +import android.os.AsyncTask; +import android.provider.Settings.System; +import com.android.settings.SettingsPreferenceFragment; +import com.android.settings.core.lifecycle.Lifecycle; + +public class TouchSoundPreferenceController extends SettingPrefController { + + private static final String KEY_TOUCH_SOUNDS = "touch_sounds"; + + public TouchSoundPreferenceController(Context context, SettingsPreferenceFragment parent, + Lifecycle lifecycle) { + super(context, parent, lifecycle); + mPreference = new SettingPref( + TYPE_SYSTEM, KEY_TOUCH_SOUNDS, System.SOUND_EFFECTS_ENABLED, DEFAULT_ON) { + @Override + protected boolean setSetting(final Context context, final int value) { + AsyncTask.execute(new Runnable() { + @Override + public void run() { + final AudioManager am = + (AudioManager) context.getSystemService(Context.AUDIO_SERVICE); + if (value != 0) { + am.loadSoundEffects(); + } else { + am.unloadSoundEffects(); + } + } + }); + return super.setSetting(context, value); + } + }; + } +} diff --git a/src/com/android/settings/notification/VibrateOnTouchPreferenceController.java b/src/com/android/settings/notification/VibrateOnTouchPreferenceController.java new file mode 100644 index 00000000000..8fd938e29dc --- /dev/null +++ b/src/com/android/settings/notification/VibrateOnTouchPreferenceController.java @@ -0,0 +1,49 @@ +/* + * 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 static com.android.settings.notification.SettingPref.TYPE_SYSTEM; + +import android.content.Context; +import android.os.Vibrator; +import android.provider.Settings.System; +import com.android.settings.SettingsPreferenceFragment; +import com.android.settings.core.lifecycle.Lifecycle; + +public class VibrateOnTouchPreferenceController extends SettingPrefController { + + private static final String KEY_VIBRATE_ON_TOUCH = "vibrate_on_touch"; + + public VibrateOnTouchPreferenceController(Context context, SettingsPreferenceFragment parent, + Lifecycle lifecycle) { + super(context, parent, lifecycle); + mPreference = new SettingPref( + TYPE_SYSTEM, KEY_VIBRATE_ON_TOUCH, System.HAPTIC_FEEDBACK_ENABLED, DEFAULT_ON) { + @Override + public boolean isApplicable(Context context) { + return hasHaptic(context); + } + }; + + } + + private static boolean hasHaptic(Context context) { + final Vibrator vibrator = (Vibrator) context.getSystemService(Context.VIBRATOR_SERVICE); + return vibrator != null && vibrator.hasVibrator(); + } + +} diff --git a/tests/robotests/src/com/android/settings/notification/BootSoundPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/notification/BootSoundPreferenceControllerTest.java new file mode 100644 index 00000000000..c547c6338da --- /dev/null +++ b/tests/robotests/src/com/android/settings/notification/BootSoundPreferenceControllerTest.java @@ -0,0 +1,123 @@ +/* + * 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.os.SystemProperties; +import android.support.v14.preference.SwitchPreference; +import android.support.v7.preference.PreferenceScreen; + +import com.android.settings.SettingsRobolectricTestRunner; +import com.android.settings.TestConfig; +import com.android.settings.testutils.shadow.SettingsShadowSystemProperties; + +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.annotation.Config; +import org.robolectric.shadows.ShadowApplication; + +import static com.google.common.truth.Truth.assertThat; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.when; + +@RunWith(SettingsRobolectricTestRunner.class) +@Config(manifest = TestConfig.MANIFEST_PATH, sdk = TestConfig.SDK_VERSION) +public class BootSoundPreferenceControllerTest { + + @Mock(answer = Answers.RETURNS_DEEP_STUBS) + private Context mContext; + @Mock + private PreferenceScreen mScreen; + @Mock + private SwitchPreference mPreference; + + private BootSoundPreferenceController mController; + + @Before + public void setUp() { + MockitoAnnotations.initMocks(this); + SettingsShadowSystemProperties.clear(); + when(mContext.getResources().getBoolean(com.android.settings.R.bool.has_boot_sounds)) + .thenReturn(true); + mController = new BootSoundPreferenceController(mContext); + when(mScreen.findPreference(mController.getPreferenceKey())).thenReturn(mPreference); + when(mPreference.getKey()).thenReturn(mController.getPreferenceKey()); + } + + @Test + public void isAvailable_hasBootSounds_shouldReturnTrue() { + when(mContext.getResources().getBoolean( + com.android.settings.R.bool.has_boot_sounds)).thenReturn(true); + + assertThat(mController.isAvailable()).isTrue(); + } + + @Test + public void isAvailable_noBootSounds_shouldReturnFale() { + when(mContext.getResources().getBoolean( + com.android.settings.R.bool.has_boot_sounds)).thenReturn(false); + + assertThat(mController.isAvailable()).isFalse(); + } + + @Config(shadows = {SettingsShadowSystemProperties.class}) + @Test + public void displayPreference_bootSoundEnabled_shouldCheckedPreference() { + SettingsShadowSystemProperties.set(BootSoundPreferenceController.PROPERTY_BOOT_SOUNDS, "1"); + + mController.displayPreference(mScreen); + + verify(mPreference).setChecked(true); + } + + @Config(shadows = {SettingsShadowSystemProperties.class}) + @Test + public void displayPreference_bootSoundDisabled_shouldUncheckedPreference() { + SettingsShadowSystemProperties.set(BootSoundPreferenceController.PROPERTY_BOOT_SOUNDS, "0"); + + mController.displayPreference(mScreen); + + verify(mPreference).setChecked(false); + } + + @Config(shadows = {SettingsShadowSystemProperties.class}) + @Test + public void handlePreferenceTreeClick_preferenceChecked_shouldEnableBootSound() { + when(mPreference.isChecked()).thenReturn(true); + + mController.handlePreferenceTreeClick(mPreference); + + assertThat(SystemProperties.getBoolean( + BootSoundPreferenceController.PROPERTY_BOOT_SOUNDS, true)).isTrue(); + } + + @Config(shadows = {SettingsShadowSystemProperties.class}) + @Test + public void handlePreferenceTreeClick_preferenceUnchecked_shouldDisableBootSound() { + when(mPreference.isChecked()).thenReturn(false); + + mController.handlePreferenceTreeClick(mPreference); + + assertThat(SystemProperties.getBoolean( + BootSoundPreferenceController.PROPERTY_BOOT_SOUNDS, true)).isFalse(); + } + +} diff --git a/tests/robotests/src/com/android/settings/notification/ChargingSoundPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/notification/ChargingSoundPreferenceControllerTest.java new file mode 100644 index 00000000000..4cdf7c7c3d9 --- /dev/null +++ b/tests/robotests/src/com/android/settings/notification/ChargingSoundPreferenceControllerTest.java @@ -0,0 +1,112 @@ +/* + * 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.app.Activity; +import android.content.ContentResolver; +import android.content.Context; +import android.support.v14.preference.SwitchPreference; +import android.support.v7.preference.PreferenceScreen; +import android.provider.Settings.Global; + +import com.android.settings.SettingsRobolectricTestRunner; +import com.android.settings.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.annotation.Config; +import org.robolectric.shadows.ShadowApplication; + +import static com.google.common.truth.Truth.assertThat; +import static org.mockito.Mockito.doReturn; +import static org.mockito.Mockito.when; + +@RunWith(SettingsRobolectricTestRunner.class) +@Config(manifest = TestConfig.MANIFEST_PATH, sdk = TestConfig.SDK_VERSION) +public class ChargingSoundPreferenceControllerTest { + + @Mock + private PreferenceScreen mScreen; + @Mock + private Activity mActivity; + @Mock + private ContentResolver mContentResolver; + @Mock + private SoundSettings mSetting; + @Mock + private Context mContext; + + private ChargingSoundPreferenceController mController; + private SwitchPreference mPreference; + + @Before + public void setUp() { + MockitoAnnotations.initMocks(this); + when(mSetting.getActivity()).thenReturn(mActivity); + when(mActivity.getContentResolver()).thenReturn(mContentResolver); + mPreference = new SwitchPreference(ShadowApplication.getInstance().getApplicationContext()); + mController = new ChargingSoundPreferenceController(mContext, mSetting, null); + when(mScreen.findPreference(mController.getPreferenceKey())).thenReturn(mPreference); + doReturn(mScreen).when(mSetting).getPreferenceScreen(); + } + + @Test + public void isAvailable_isAlwaysTrue() { + assertThat(mController.isAvailable()).isTrue(); + } + + @Test + public void displayPreference_chargingSoundEnabled_shouldCheckedPreference() { + Global.putInt(mContentResolver, Global.CHARGING_SOUNDS_ENABLED, 1); + + mController.displayPreference(mScreen); + + assertThat(mPreference.isChecked()).isTrue(); + } + + @Test + public void displayPreference_chargingSoundDisabled_shouldUncheckedPreference() { + Global.putInt(mContentResolver, Global.CHARGING_SOUNDS_ENABLED, 0); + + mController.displayPreference(mScreen); + + assertThat(mPreference.isChecked()).isFalse(); + } + + @Test + public void onPreferenceChanged_preferenceChecked_shouldEnabledChargingSound() { + mController.displayPreference(mScreen); + + mPreference.getOnPreferenceChangeListener().onPreferenceChange(mPreference, true); + + assertThat(Global.getInt(mContentResolver, Global.CHARGING_SOUNDS_ENABLED, 1)) + .isEqualTo(1); + } + + @Test + public void onPreferenceChanged_preferenceUnchecked_shouldDisabledChargingSound() { + mController.displayPreference(mScreen); + + mPreference.getOnPreferenceChangeListener().onPreferenceChange(mPreference, false); + + assertThat(Global.getInt(mContentResolver, Global.CHARGING_SOUNDS_ENABLED, 1)) + .isEqualTo(0); + } +} diff --git a/tests/robotests/src/com/android/settings/notification/DialPadTonePreferenceControllerTest.java b/tests/robotests/src/com/android/settings/notification/DialPadTonePreferenceControllerTest.java new file mode 100644 index 00000000000..e9410e6fa71 --- /dev/null +++ b/tests/robotests/src/com/android/settings/notification/DialPadTonePreferenceControllerTest.java @@ -0,0 +1,123 @@ +/* + * 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.app.Activity; +import android.content.ContentResolver; +import android.content.Context; +import android.support.v14.preference.SwitchPreference; +import android.support.v7.preference.PreferenceScreen; +import android.provider.Settings.System; +import android.telephony.TelephonyManager; + +import com.android.settings.SettingsRobolectricTestRunner; +import com.android.settings.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.annotation.Config; +import org.robolectric.shadows.ShadowApplication; + +import static com.google.common.truth.Truth.assertThat; +import static org.mockito.Mockito.doReturn; +import static org.mockito.Mockito.when; + +@RunWith(SettingsRobolectricTestRunner.class) +@Config(manifest = TestConfig.MANIFEST_PATH, sdk = TestConfig.SDK_VERSION) +public class DialPadTonePreferenceControllerTest { + + @Mock + private TelephonyManager mTelephonyManager; + @Mock + private PreferenceScreen mScreen; + @Mock + private Activity mActivity; + @Mock + private ContentResolver mContentResolver; + @Mock + private SoundSettings mSetting; + @Mock + private Context mContext; + + private DialPadTonePreferenceController mController; + private SwitchPreference mPreference; + + @Before + public void setUp() { + MockitoAnnotations.initMocks(this); + when(mContext.getSystemService(Context.TELEPHONY_SERVICE)).thenReturn(mTelephonyManager); + when(mTelephonyManager.isVoiceCapable()).thenReturn(true); + when(mSetting.getActivity()).thenReturn(mActivity); + when(mActivity.getSystemService(Context.TELEPHONY_SERVICE)).thenReturn(mTelephonyManager); + when(mActivity.getContentResolver()).thenReturn(mContentResolver); + mPreference = new SwitchPreference(ShadowApplication.getInstance().getApplicationContext()); + mController = new DialPadTonePreferenceController(mContext, mSetting, null); + when(mScreen.findPreference(mController.getPreferenceKey())).thenReturn(mPreference); + doReturn(mScreen).when(mSetting).getPreferenceScreen(); + } + + @Test + public void isAvailable_voiceCapable_shouldReturnTrue() { + assertThat(mController.isAvailable()).isTrue(); + } + + @Test + public void isAvailable_notVoiceCapable_shouldReturnFalse() { + when(mTelephonyManager.isVoiceCapable()).thenReturn(false); + + assertThat(mController.isAvailable()).isFalse(); + } + + @Test + public void displayPreference_dialToneEnabled_shouldCheckedPreference() { + System.putInt(mContentResolver, System.DTMF_TONE_WHEN_DIALING, 1); + + mController.displayPreference(mScreen); + + assertThat(mPreference.isChecked()).isTrue(); + } + + @Test + public void displayPreference_dialToneDisabled_shouldUncheckedPreference() { + System.putInt(mContentResolver, System.DTMF_TONE_WHEN_DIALING, 0); + + mController.displayPreference(mScreen); + + assertThat(mPreference.isChecked()).isFalse(); + } + + @Test + public void onPreferenceChanged_preferenceChecked_shouldEnabledDialTone() { + mController.displayPreference(mScreen); + + mPreference.getOnPreferenceChangeListener().onPreferenceChange(mPreference, true); + + assertThat(System.getInt(mContentResolver, System.DTMF_TONE_WHEN_DIALING, 1)).isEqualTo(1); + } + + @Test + public void onPreferenceChanged_preferenceUnchecked_shouldDisabledDialTone() { + mController.displayPreference(mScreen); + + mPreference.getOnPreferenceChangeListener().onPreferenceChange(mPreference, false); + + assertThat(System.getInt(mContentResolver, System.DTMF_TONE_WHEN_DIALING, 1)).isEqualTo(0); + } +} diff --git a/tests/robotests/src/com/android/settings/notification/DockAudioMediaPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/notification/DockAudioMediaPreferenceControllerTest.java new file mode 100644 index 00000000000..bc6eb3a8ad6 --- /dev/null +++ b/tests/robotests/src/com/android/settings/notification/DockAudioMediaPreferenceControllerTest.java @@ -0,0 +1,129 @@ +/* + * 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.app.Activity; +import android.content.ContentResolver; +import android.content.Context; +import android.support.v7.preference.DropDownPreference; +import android.support.v7.preference.PreferenceScreen; +import android.provider.Settings.Global; + +import com.android.settings.SettingsRobolectricTestRunner; +import com.android.settings.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.annotation.Config; +import org.robolectric.shadows.ShadowApplication; + +import static com.google.common.truth.Truth.assertThat; +import static org.mockito.Answers.RETURNS_DEEP_STUBS; +import static org.mockito.Matchers.anyInt; +import static org.mockito.Mockito.doReturn; +import static org.mockito.Mockito.when; + +@RunWith(SettingsRobolectricTestRunner.class) +@Config(manifest = TestConfig.MANIFEST_PATH, sdk = TestConfig.SDK_VERSION) +public class DockAudioMediaPreferenceControllerTest { + + @Mock + private PreferenceScreen mScreen; + @Mock(answer = RETURNS_DEEP_STUBS) + private Activity mActivity; + @Mock + private ContentResolver mContentResolver; + @Mock + private SoundSettings mSetting; + @Mock(answer = RETURNS_DEEP_STUBS) + private Context mContext; + + private DockAudioMediaPreferenceController mController; + private DropDownPreference mPreference; + + @Before + public void setUp() { + MockitoAnnotations.initMocks(this); + final Context appContext = ShadowApplication.getInstance().getApplicationContext(); + when(mSetting.getActivity()).thenReturn(mActivity); + when(mActivity.getContentResolver()).thenReturn(mContentResolver); + when(mActivity.getResources().getBoolean(com.android.settings.R.bool.has_dock_settings)) + .thenReturn(true); + when(mActivity.getResources().getString(anyInt())).thenReturn("test string"); + mPreference = new DropDownPreference(appContext); + mController = new DockAudioMediaPreferenceController(mContext, mSetting, null); + when(mScreen.findPreference(mController.getPreferenceKey())).thenReturn(mPreference); + doReturn(mScreen).when(mSetting).getPreferenceScreen(); + } + + @Test + public void isAvailable_hasDockSettings_shouldReturnTrue() { + when(mContext.getResources().getBoolean(com.android.settings.R.bool.has_dock_settings)) + .thenReturn(true); + + assertThat(mController.isAvailable()).isTrue(); + } + + @Test + public void isAvailable_noDockSettings_shouldReturnFalse() { + when(mContext.getResources().getBoolean(com.android.settings.R.bool.has_dock_settings)) + .thenReturn(false); + + assertThat(mController.isAvailable()).isFalse(); + } + + @Test + public void displayPreference_dockAudioDisabled_shouldSelectFirstItem() { + Global.putInt(mContentResolver, Global.DOCK_AUDIO_MEDIA_ENABLED, 0); + + mController.displayPreference(mScreen); + + assertThat(mPreference.getValue()).isEqualTo("0"); + } + + @Test + public void displayPreference_dockAudioEnabled_shouldSelectSecondItem() { + Global.putInt(mContentResolver, Global.DOCK_AUDIO_MEDIA_ENABLED, 1); + + mController.displayPreference(mScreen); + + assertThat(mPreference.getValue()).isEqualTo("1"); + } + + @Test + public void onPreferenceChanged_firstItemSelected_shouldDisableDockAudio() { + mController.displayPreference(mScreen); + + mPreference.getOnPreferenceChangeListener().onPreferenceChange(mPreference, "0"); + + assertThat(Global.getInt(mContentResolver, Global.DOCK_AUDIO_MEDIA_ENABLED, 0)) + .isEqualTo(0); + } + + @Test + public void onPreferenceChanged_secondItemSelected_shouldEnableDockAudio() { + mController.displayPreference(mScreen); + + mPreference.getOnPreferenceChangeListener().onPreferenceChange(mPreference, "1"); + + assertThat(Global.getInt(mContentResolver, Global.DOCK_AUDIO_MEDIA_ENABLED, 0)) + .isEqualTo(1); + } +} diff --git a/tests/robotests/src/com/android/settings/notification/DockingSoundPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/notification/DockingSoundPreferenceControllerTest.java new file mode 100644 index 00000000000..3350fb90a75 --- /dev/null +++ b/tests/robotests/src/com/android/settings/notification/DockingSoundPreferenceControllerTest.java @@ -0,0 +1,124 @@ +/* + * 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.app.Activity; +import android.content.ContentResolver; +import android.content.Context; +import android.support.v14.preference.SwitchPreference; +import android.support.v7.preference.PreferenceScreen; +import android.provider.Settings.Global; + +import com.android.settings.SettingsRobolectricTestRunner; +import com.android.settings.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.annotation.Config; +import org.robolectric.shadows.ShadowApplication; + +import static com.google.common.truth.Truth.assertThat; +import static org.mockito.Answers.RETURNS_DEEP_STUBS; +import static org.mockito.Mockito.doReturn; +import static org.mockito.Mockito.when; + +@RunWith(SettingsRobolectricTestRunner.class) +@Config(manifest = TestConfig.MANIFEST_PATH, sdk = TestConfig.SDK_VERSION) +public class DockingSoundPreferenceControllerTest { + + @Mock + private PreferenceScreen mScreen; + @Mock(answer = RETURNS_DEEP_STUBS) + private Activity mActivity; + @Mock + private ContentResolver mContentResolver; + @Mock + private SoundSettings mSetting; + @Mock(answer = RETURNS_DEEP_STUBS) + private Context mContext; + + private DockingSoundPreferenceController mController; + private SwitchPreference mPreference; + + @Before + public void setUp() { + MockitoAnnotations.initMocks(this); + when(mSetting.getActivity()).thenReturn(mActivity); + when(mActivity.getContentResolver()).thenReturn(mContentResolver); + mPreference = new SwitchPreference(ShadowApplication.getInstance().getApplicationContext()); + when(mActivity.getResources().getBoolean(com.android.settings.R.bool.has_dock_settings)) + .thenReturn(true); + mController = new DockingSoundPreferenceController(mContext, mSetting, null); + when(mScreen.findPreference(mController.getPreferenceKey())).thenReturn(mPreference); + doReturn(mScreen).when(mSetting).getPreferenceScreen(); + } + + @Test + public void isAvailable_hasDockSettings_shouldReturnTrue() { + when(mContext.getResources().getBoolean(com.android.settings.R.bool.has_dock_settings)) + .thenReturn(true); + + assertThat(mController.isAvailable()).isTrue(); + } + + @Test + public void isAvailable_noDockSettings_shouldReturnFalse() { + when(mContext.getResources().getBoolean(com.android.settings.R.bool.has_dock_settings)) + .thenReturn(false); + + assertThat(mController.isAvailable()).isFalse(); + } + + @Test + public void displayPreference_dockingSoundEnabled_shouldCheckedPreference() { + Global.putInt(mContentResolver, Global.DOCK_SOUNDS_ENABLED, 1); + + mController.displayPreference(mScreen); + + assertThat(mPreference.isChecked()).isTrue(); + } + + @Test + public void displayPreference_dockingSoundDisabled_shouldUncheckedPreference() { + Global.putInt(mContentResolver, Global.DOCK_SOUNDS_ENABLED, 0); + + mController.displayPreference(mScreen); + + assertThat(mPreference.isChecked()).isFalse(); + } + + @Test + public void onPreferenceChanged_preferenceChecked_shouldEnabledDockingSound() { + mController.displayPreference(mScreen); + + mPreference.getOnPreferenceChangeListener().onPreferenceChange(mPreference, true); + + assertThat(Global.getInt(mContentResolver, Global.DOCK_SOUNDS_ENABLED, 1)).isEqualTo(1); + } + + @Test + public void onPreferenceChanged_preferenceUnchecked_shouldDisabledDockingSound() { + mController.displayPreference(mScreen); + + mPreference.getOnPreferenceChangeListener().onPreferenceChange(mPreference, false); + + assertThat(Global.getInt(mContentResolver, Global.DOCK_SOUNDS_ENABLED, 1)).isEqualTo(0); + } +} diff --git a/tests/robotests/src/com/android/settings/notification/EmergencyTonePreferenceControllerTest.java b/tests/robotests/src/com/android/settings/notification/EmergencyTonePreferenceControllerTest.java new file mode 100644 index 00000000000..0124566f3bb --- /dev/null +++ b/tests/robotests/src/com/android/settings/notification/EmergencyTonePreferenceControllerTest.java @@ -0,0 +1,143 @@ +/* + * 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.app.Activity; +import android.content.ContentResolver; +import android.content.Context; +import android.support.v7.preference.DropDownPreference; +import android.support.v7.preference.PreferenceScreen; +import android.provider.Settings.Global; +import android.telephony.TelephonyManager; + +import com.android.settings.SettingsRobolectricTestRunner; +import com.android.settings.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.annotation.Config; +import org.robolectric.shadows.ShadowApplication; + +import static com.google.common.truth.Truth.assertThat; +import static org.mockito.Mockito.doReturn; +import static org.mockito.Mockito.when; + +@RunWith(SettingsRobolectricTestRunner.class) +@Config(manifest = TestConfig.MANIFEST_PATH, sdk = TestConfig.SDK_VERSION) +public class EmergencyTonePreferenceControllerTest { + + @Mock + private TelephonyManager mTelephonyManager; + @Mock + private PreferenceScreen mScreen; + @Mock + private Activity mActivity; + @Mock + private ContentResolver mContentResolver; + @Mock + private SoundSettings mSetting; + @Mock + private Context mContext; + + private EmergencyTonePreferenceController mController; + private DropDownPreference mPreference; + + @Before + public void setUp() { + MockitoAnnotations.initMocks(this); + final Context appContext = ShadowApplication.getInstance().getApplicationContext(); + when(mContext.getSystemService(Context.TELEPHONY_SERVICE)).thenReturn(mTelephonyManager); + when(mTelephonyManager.getCurrentPhoneType()).thenReturn(TelephonyManager.PHONE_TYPE_CDMA); + when(mSetting.getActivity()).thenReturn(mActivity); + when(mActivity.getSystemService(Context.TELEPHONY_SERVICE)).thenReturn(mTelephonyManager); + when(mActivity.getContentResolver()).thenReturn(mContentResolver); + when(mActivity.getResources()).thenReturn(appContext.getResources()); + mPreference = new DropDownPreference(appContext); + mController = new EmergencyTonePreferenceController(mContext, mSetting, null); + when(mScreen.findPreference(mController.getPreferenceKey())).thenReturn(mPreference); + doReturn(mScreen).when(mSetting).getPreferenceScreen(); + } + + @Test + public void isAvailable_cdma_shouldReturnTrue() { + assertThat(mController.isAvailable()).isTrue(); + } + + @Test + public void isAvailable_notCdma_shouldReturnFalse() { + when(mTelephonyManager.getCurrentPhoneType()).thenReturn(TelephonyManager.PHONE_TYPE_GSM); + + assertThat(mController.isAvailable()).isFalse(); + } + + @Test + public void displayPreference_emergencyToneOff_shouldSelectFirstItem() { + Global.putInt(mContentResolver, Global.EMERGENCY_TONE, 0); + + mController.displayPreference(mScreen); + + assertThat(mPreference.getValue()).isEqualTo("0"); + } + + @Test + public void displayPreference_emergencyToneAlert_shouldSelectSecondItem() { + Global.putInt(mContentResolver, Global.EMERGENCY_TONE, 1); + + mController.displayPreference(mScreen); + + assertThat(mPreference.getValue()).isEqualTo("1"); + } + + @Test + public void displayPreference_emergencyToneVibrate_shouldSelectThirdItem() { + Global.putInt(mContentResolver, Global.EMERGENCY_TONE, 2); + + mController.displayPreference(mScreen); + + assertThat(mPreference.getValue()).isEqualTo("2"); + } + + @Test + public void onPreferenceChanged_firstItemSelected_shouldSetEmergencyToneToOff() { + mController.displayPreference(mScreen); + + mPreference.getOnPreferenceChangeListener().onPreferenceChange(mPreference, "0"); + + assertThat(Global.getInt(mContentResolver, Global.EMERGENCY_TONE, 0)).isEqualTo(0); + } + + @Test + public void onPreferenceChanged_secondItemSelected_shouldSetEmergencyToneToAlert() { + mController.displayPreference(mScreen); + + mPreference.getOnPreferenceChangeListener().onPreferenceChange(mPreference, "1"); + + assertThat(Global.getInt(mContentResolver, Global.EMERGENCY_TONE, 0)).isEqualTo(1); + } + + @Test + public void onPreferenceChanged_thirdItemSelected_shouldSetEmergencyToneToVibrate() { + mController.displayPreference(mScreen); + + mPreference.getOnPreferenceChangeListener().onPreferenceChange(mPreference, "2"); + + assertThat(Global.getInt(mContentResolver, Global.EMERGENCY_TONE, 0)).isEqualTo(2); + } +} diff --git a/tests/robotests/src/com/android/settings/notification/ScreenLockSoundPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/notification/ScreenLockSoundPreferenceControllerTest.java new file mode 100644 index 00000000000..8963a5dfc91 --- /dev/null +++ b/tests/robotests/src/com/android/settings/notification/ScreenLockSoundPreferenceControllerTest.java @@ -0,0 +1,112 @@ +/* + * 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.app.Activity; +import android.content.ContentResolver; +import android.content.Context; +import android.support.v14.preference.SwitchPreference; +import android.support.v7.preference.PreferenceScreen; +import android.provider.Settings.System; + +import com.android.settings.SettingsRobolectricTestRunner; +import com.android.settings.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.annotation.Config; +import org.robolectric.shadows.ShadowApplication; + +import static com.google.common.truth.Truth.assertThat; +import static org.mockito.Mockito.doReturn; +import static org.mockito.Mockito.when; + +@RunWith(SettingsRobolectricTestRunner.class) +@Config(manifest = TestConfig.MANIFEST_PATH, sdk = TestConfig.SDK_VERSION) +public class ScreenLockSoundPreferenceControllerTest { + + @Mock + private PreferenceScreen mScreen; + @Mock + private Activity mActivity; + @Mock + private ContentResolver mContentResolver; + @Mock + private SoundSettings mSetting; + @Mock + private Context mContext; + + private ScreenLockSoundPreferenceController mController; + private SwitchPreference mPreference; + + @Before + public void setUp() { + MockitoAnnotations.initMocks(this); + when(mSetting.getActivity()).thenReturn(mActivity); + when(mActivity.getContentResolver()).thenReturn(mContentResolver); + mPreference = new SwitchPreference(ShadowApplication.getInstance().getApplicationContext()); + mController = new ScreenLockSoundPreferenceController(mContext, mSetting, null); + when(mScreen.findPreference(mController.getPreferenceKey())).thenReturn(mPreference); + doReturn(mScreen).when(mSetting).getPreferenceScreen(); + } + + @Test + public void isAvailable_isAlwaysTrue() { + assertThat(mController.isAvailable()).isTrue(); + } + + @Test + public void displayPreference_lockScreenSoundEnabled_shouldCheckedPreference() { + System.putInt(mContentResolver, System.LOCKSCREEN_SOUNDS_ENABLED, 1); + + mController.displayPreference(mScreen); + + assertThat(mPreference.isChecked()).isTrue(); + } + + @Test + public void displayPreference_lockScreenSoundDisabled_shouldUncheckedPreference() { + System.putInt(mContentResolver, System.LOCKSCREEN_SOUNDS_ENABLED, 0); + + mController.displayPreference(mScreen); + + assertThat(mPreference.isChecked()).isFalse(); + } + + @Test + public void onPreferenceChanged_preferenceChecked_shouldEnabledLockScreenSound() { + mController.displayPreference(mScreen); + + mPreference.getOnPreferenceChangeListener().onPreferenceChange(mPreference, true); + + assertThat(System.getInt(mContentResolver, System.LOCKSCREEN_SOUNDS_ENABLED, 1)) + .isEqualTo(1); + } + + @Test + public void onPreferenceChanged_preferenceUnchecked_shouldDisabledLockScreenSound() { + mController.displayPreference(mScreen); + + mPreference.getOnPreferenceChangeListener().onPreferenceChange(mPreference, false); + + assertThat(System.getInt(mContentResolver, System.LOCKSCREEN_SOUNDS_ENABLED, 1)) + .isEqualTo(0); + } +} diff --git a/tests/robotests/src/com/android/settings/notification/SettingPrefControllerTest.java b/tests/robotests/src/com/android/settings/notification/SettingPrefControllerTest.java new file mode 100644 index 00000000000..b36b19b0a8f --- /dev/null +++ b/tests/robotests/src/com/android/settings/notification/SettingPrefControllerTest.java @@ -0,0 +1,179 @@ +/* + * 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.app.Activity; +import android.content.ContentResolver; +import android.content.Context; +import android.provider.Settings.Global; +import android.support.v7.preference.PreferenceScreen; + +import com.android.settings.SettingsPreferenceFragment; +import com.android.settings.SettingsRobolectricTestRunner; +import com.android.settings.TestConfig; +import com.android.settings.core.lifecycle.Lifecycle; + +import java.util.ArrayList; +import java.util.List; + +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.Mock; +import org.mockito.MockitoAnnotations; +import org.robolectric.annotation.Config; +import org.robolectric.shadows.ShadowApplication; + +import static com.android.settings.notification.SettingPref.TYPE_GLOBAL; +import static com.google.common.truth.Truth.assertThat; +import static org.mockito.Answers.RETURNS_DEEP_STUBS; +import static org.mockito.Mockito.doReturn; +import static org.mockito.Mockito.spy; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.when; + +@RunWith(SettingsRobolectricTestRunner.class) +@Config(manifest = TestConfig.MANIFEST_PATH, sdk = TestConfig.SDK_VERSION) +public class SettingPrefControllerTest { + + @Mock + private PreferenceScreen mScreen; + @Mock + private OtherSoundSettings mSetting; + @Mock + private Activity mActivity; + @Mock + private ContentResolver mContentResolver; + + private Context mContext; + private PreferenceControllerTestable mController; + private SettingPref mPreference; + + @Before + public void setUp() { + MockitoAnnotations.initMocks(this); + mContext = spy(ShadowApplication.getInstance().getApplicationContext()); + when(mContext.getContentResolver()).thenReturn(mContentResolver); + when(mSetting.getActivity()).thenReturn(mActivity); + doReturn(mScreen).when(mSetting).getPreferenceScreen(); + mController = new PreferenceControllerTestable(mContext, mSetting, null); + mPreference = mController.getPref(); + } + + @Test + public void displayPreference_shouldInitPreference() { + mController.displayPreference(mScreen); + + verify(mPreference).init(mSetting); + } + + @Test + public void isAvailable_shouldCallisApplicable() { + mController.isAvailable(); + + verify(mPreference).isApplicable(mContext); + } + + @Test + public void getPreferenceKey_shouldReturnPrefKey() { + assertThat(mController.getPreferenceKey()).isEqualTo(mController.KEY_TEST); + } + + @Test + public void updateState_shouldUpdatePreference() { + mController.updateState(null); + + verify(mPreference).update(mContext); + } + + @Test + public void onResume_shouldRegisterContentObserver() { + mController.displayPreference(mScreen); + mController.onResume(); + + verify(mContentResolver).registerContentObserver( + Global.getUriFor("Setting1"), false, mController.getObserver()); + } + + @Test + public void onPause_shouldUnregisterContentObserver() { + mController.displayPreference(mScreen); + mController.onPause(); + + verify(mContentResolver).unregisterContentObserver(mController.getObserver()); + } + + @Test + public void onContentChange_shouldUpdatePreference() { + mController.displayPreference(mScreen); + mController.onResume(); + mController.getObserver().onChange(false, Global.getUriFor("Setting1")); + + verify(mPreference).update(mContext); + } + + @Test + public void updateNonIndexableKeys_applicable_shouldNotUpdate() { + final List keys = new ArrayList<>(); + + mController.updateNonIndexableKeys(keys); + + assertThat(keys).isEmpty(); + } + + @Test + public void updateNonIndexableKeys_notApplicable_shouldUpdate() { + mController.setApplicable(false); + final List keys = new ArrayList<>(); + + mController.updateNonIndexableKeys(keys); + + assertThat(keys).isNotEmpty(); + } + + private class PreferenceControllerTestable extends SettingPrefController { + + private static final String KEY_TEST = "key1"; + private boolean mApplicable = true; + + public PreferenceControllerTestable(Context context, SettingsPreferenceFragment parent, + Lifecycle lifecycle) { + super(context, parent, lifecycle); + mPreference = spy(new SettingPref( + TYPE_GLOBAL, KEY_TEST, "Setting1", 1) { + @Override + public boolean isApplicable(Context context) { + return mApplicable; + } + }); + } + + SettingPref getPref() { + return mPreference; + } + + PreferenceControllerTestable.SettingsObserver getObserver() { + return mSettingsObserver; + } + + void setApplicable(boolean applicable) { + mApplicable = applicable; + } + + } + +} diff --git a/tests/robotests/src/com/android/settings/notification/TouchSoundPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/notification/TouchSoundPreferenceControllerTest.java new file mode 100644 index 00000000000..f530f662a1f --- /dev/null +++ b/tests/robotests/src/com/android/settings/notification/TouchSoundPreferenceControllerTest.java @@ -0,0 +1,116 @@ +/* + * 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.app.Activity; +import android.content.ContentResolver; +import android.content.Context; +import android.media.AudioManager; +import android.support.v14.preference.SwitchPreference; +import android.support.v7.preference.PreferenceScreen; +import android.provider.Settings.System; + +import com.android.settings.SettingsRobolectricTestRunner; +import com.android.settings.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.Robolectric; +import org.robolectric.annotation.Config; +import org.robolectric.shadows.ShadowApplication; + +import static com.google.common.truth.Truth.assertThat; +import static org.mockito.Mockito.doReturn; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.when; + +@RunWith(SettingsRobolectricTestRunner.class) +@Config(manifest = TestConfig.MANIFEST_PATH, sdk = TestConfig.SDK_VERSION) +public class TouchSoundPreferenceControllerTest { + + @Mock + private AudioManager mAudioManager; + @Mock + private PreferenceScreen mScreen; + @Mock + private Activity mActivity; + @Mock + private ContentResolver mContentResolver; + @Mock + private SoundSettings mSetting; + @Mock + private Context mContext; + + private TouchSoundPreferenceController mController; + private SwitchPreference mPreference; + + @Before + public void setUp() { + MockitoAnnotations.initMocks(this); + when(mActivity.getSystemService(Context.AUDIO_SERVICE)).thenReturn(mAudioManager); + when(mSetting.getActivity()).thenReturn(mActivity); + when(mActivity.getContentResolver()).thenReturn(mContentResolver); + mPreference = new SwitchPreference(ShadowApplication.getInstance().getApplicationContext()); + mController = new TouchSoundPreferenceController(mContext, mSetting, null); + when(mScreen.findPreference(mController.getPreferenceKey())).thenReturn(mPreference); + doReturn(mScreen).when(mSetting).getPreferenceScreen(); + } + + @Test + public void isAvailable_isAlwaysTrue() { + assertThat(mController.isAvailable()).isTrue(); + } + + @Test + public void displayPreference_soundEffectEnabled_shouldCheckedPreference() { + System.putInt(mContentResolver, System.SOUND_EFFECTS_ENABLED, 1); + + mController.displayPreference(mScreen); + + assertThat(mPreference.isChecked()).isTrue(); + } + + @Test + public void displayPreference_soundEffectDisabled_shouldUncheckedPreference() { + System.putInt(mContentResolver, System.SOUND_EFFECTS_ENABLED, 0); + + mController.displayPreference(mScreen); + + assertThat(mPreference.isChecked()).isFalse(); + } + + @Test + public void onPreferenceChanged_preferenceChecked_shouldEnabledSoundEffect() { + mController.displayPreference(mScreen); + + mPreference.getOnPreferenceChangeListener().onPreferenceChange(mPreference, true); + + assertThat(System.getInt(mContentResolver, System.SOUND_EFFECTS_ENABLED, 1)).isEqualTo(1); + } + + @Test + public void onPreferenceChanged_preferenceUnchecked_shouldDisabledSoundEffect() { + mController.displayPreference(mScreen); + + mPreference.getOnPreferenceChangeListener().onPreferenceChange(mPreference, false); + + assertThat(System.getInt(mContentResolver, System.SOUND_EFFECTS_ENABLED, 1)).isEqualTo(0); + } +} diff --git a/tests/robotests/src/com/android/settings/notification/VibrateOnTouchPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/notification/VibrateOnTouchPreferenceControllerTest.java new file mode 100644 index 00000000000..440b69e9e1a --- /dev/null +++ b/tests/robotests/src/com/android/settings/notification/VibrateOnTouchPreferenceControllerTest.java @@ -0,0 +1,125 @@ +/* + * 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.app.Activity; +import android.content.ContentResolver; +import android.content.Context; +import android.os.Vibrator; +import android.support.v14.preference.SwitchPreference; +import android.support.v7.preference.PreferenceScreen; +import android.provider.Settings.System; + +import com.android.settings.SettingsRobolectricTestRunner; +import com.android.settings.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.annotation.Config; +import org.robolectric.shadows.ShadowApplication; + +import static com.google.common.truth.Truth.assertThat; +import static org.mockito.Answers.RETURNS_DEEP_STUBS; +import static org.mockito.Mockito.doReturn; +import static org.mockito.Mockito.when; + +@RunWith(SettingsRobolectricTestRunner.class) +@Config(manifest = TestConfig.MANIFEST_PATH, sdk = TestConfig.SDK_VERSION) +public class VibrateOnTouchPreferenceControllerTest { + + @Mock + private PreferenceScreen mScreen; + @Mock + private Activity mActivity; + @Mock + private ContentResolver mContentResolver; + @Mock + private SoundSettings mSetting; + @Mock + private Context mContext; + @Mock + private Vibrator mVibrator; + + private VibrateOnTouchPreferenceController mController; + private SwitchPreference mPreference; + + @Before + public void setUp() { + MockitoAnnotations.initMocks(this); + when(mActivity.getSystemService(Context.VIBRATOR_SERVICE)).thenReturn(mVibrator); + when(mContext.getSystemService(Context.VIBRATOR_SERVICE)).thenReturn(mVibrator); + when(mVibrator.hasVibrator()).thenReturn(true); + when(mSetting.getActivity()).thenReturn(mActivity); + when(mActivity.getContentResolver()).thenReturn(mContentResolver); + mPreference = new SwitchPreference(ShadowApplication.getInstance().getApplicationContext()); + mController = new VibrateOnTouchPreferenceController(mContext, mSetting, null); + when(mScreen.findPreference(mController.getPreferenceKey())).thenReturn(mPreference); + doReturn(mScreen).when(mSetting).getPreferenceScreen(); + } + + @Test + public void isAvailable_hasHaptic_shouldReturnTrue() { + + assertThat(mController.isAvailable()).isTrue(); + } + + @Test + public void isAvailable_noHaptic_shouldReturnFalse() { + when(mVibrator.hasVibrator()).thenReturn(false); + + assertThat(mController.isAvailable()).isFalse(); + } + + @Test + public void displayPreference_hapticEnabled_shouldCheckedPreference() { + System.putInt(mContentResolver, System.HAPTIC_FEEDBACK_ENABLED, 1); + + mController.displayPreference(mScreen); + + assertThat(mPreference.isChecked()).isTrue(); + } + + @Test + public void displayPreference_hapticDisabled_shouldUncheckedPreference() { + System.putInt(mContentResolver, System.HAPTIC_FEEDBACK_ENABLED, 0); + + mController.displayPreference(mScreen); + + assertThat(mPreference.isChecked()).isFalse(); + } + + @Test + public void onPreferenceChanged_preferenceChecked_shouldEnabledHaptic() { + mController.displayPreference(mScreen); + + mPreference.getOnPreferenceChangeListener().onPreferenceChange(mPreference, true); + + assertThat(System.getInt(mContentResolver, System.HAPTIC_FEEDBACK_ENABLED, 1)).isEqualTo(1); + } + + @Test + public void onPreferenceChanged_preferenceUnchecked_shouldDisabledHaptic() { + mController.displayPreference(mScreen); + + mPreference.getOnPreferenceChangeListener().onPreferenceChange(mPreference, false); + + assertThat(System.getInt(mContentResolver, System.HAPTIC_FEEDBACK_ENABLED, 1)).isEqualTo(0); + } +} diff --git a/tests/robotests/src/com/android/settings/testutils/shadow/SettingsShadowSystemProperties.java b/tests/robotests/src/com/android/settings/testutils/shadow/SettingsShadowSystemProperties.java new file mode 100644 index 00000000000..e2a863a453d --- /dev/null +++ b/tests/robotests/src/com/android/settings/testutils/shadow/SettingsShadowSystemProperties.java @@ -0,0 +1,54 @@ +/* + * 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.testutils.shadow; + +import android.os.SystemProperties; + +import java.util.HashMap; +import java.util.Map; + +import org.robolectric.annotation.Implementation; +import org.robolectric.annotation.Implements; +import org.robolectric.shadows.ShadowSystemProperties; + +/** + * This class provides write capability to ShadowSystemProperties. + */ +@Implements(SystemProperties.class) +public class SettingsShadowSystemProperties extends ShadowSystemProperties { + + private static final Map sValues = new HashMap<>(); + + @Implementation + public static synchronized boolean getBoolean(String key, boolean def) { + if (sValues.containsKey(key)) { + String val = sValues.get(key); + return "y".equals(val) || "yes".equals(val) || "1".equals(val) || "true".equals(val) + || "on".equals(val); + } + return ShadowSystemProperties.getBoolean(key, def); + } + + public static synchronized void set(String key, String val) { + sValues.put(key, val); + } + + public static synchronized void clear() { + sValues.clear(); + } + +}