OSDN Git Service

Refactor SoundSettings to use more preference controller.
authorDoris Ling <dling@google.com>
Mon, 5 Dec 2016 21:29:21 +0000 (13:29 -0800)
committerDoris Ling <dling@google.com>
Wed, 7 Dec 2016 22:33:13 +0000 (14:33 -0800)
- second round of refactoring SoundSettings to use preference
  controller.
- add controller for Emergency broadcast, Vibrate when ring, Phone
  ringtone, Alarm ringtone, and Notification ringtone.

Bug: 32276590
Test: make RunSettingsRoboTests
Change-Id: Iaff48ecb27bf156a5c8995de20ce7a440b094cdb

21 files changed:
src/com/android/settings/notification/AlarmRingtonePreferenceController.java [new file with mode: 0644]
src/com/android/settings/notification/EmergencyBroadcastPreferenceController.java [new file with mode: 0644]
src/com/android/settings/notification/NotificationRingtonePreferenceController.java [new file with mode: 0644]
src/com/android/settings/notification/PhoneRingtonePreferenceController.java [new file with mode: 0644]
src/com/android/settings/notification/RingtonePreferenceControllerBase.java [new file with mode: 0644]
src/com/android/settings/notification/SoundSettings.java
src/com/android/settings/notification/VibrateWhenRingPreferenceController.java [new file with mode: 0644]
tests/robotests/src/com/android/settings/notification/AdjustVolumeRestrictedPreferenceControllerTest.java
tests/robotests/src/com/android/settings/notification/AlarmRingtonePreferenceControllerTest.java [new file with mode: 0644]
tests/robotests/src/com/android/settings/notification/AlarmVolumePreferenceControllerTest.java
tests/robotests/src/com/android/settings/notification/CastPreferenceControllerTest.java
tests/robotests/src/com/android/settings/notification/EmergencyBroadcastPreferenceControllerTest.java [new file with mode: 0644]
tests/robotests/src/com/android/settings/notification/MediaVolumePreferenceControllerTest.java
tests/robotests/src/com/android/settings/notification/NotificationRingtonePreferenceControllerTest.java [new file with mode: 0644]
tests/robotests/src/com/android/settings/notification/NotificationVolumePreferenceControllerTest.java
tests/robotests/src/com/android/settings/notification/PhoneRingtonePreferenceControllerTest.java [new file with mode: 0644]
tests/robotests/src/com/android/settings/notification/RingVolumePreferenceControllerTest.java
tests/robotests/src/com/android/settings/notification/RingtonePreferenceControllerBaseTest.java [new file with mode: 0644]
tests/robotests/src/com/android/settings/notification/VibrateWhenRingPreferenceControllerTest.java [new file with mode: 0644]
tests/robotests/src/com/android/settings/notification/VolumeSeekBarPreferenceControllerTest.java
tests/robotests/src/com/android/settings/notification/ZenModePreferenceControllerTest.java

diff --git a/src/com/android/settings/notification/AlarmRingtonePreferenceController.java b/src/com/android/settings/notification/AlarmRingtonePreferenceController.java
new file mode 100644 (file)
index 0000000..2e7aab0
--- /dev/null
@@ -0,0 +1,39 @@
+/*
+ * Copyright (C) 2016 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.media.RingtoneManager;
+
+public class AlarmRingtonePreferenceController extends RingtonePreferenceControllerBase {
+
+    private static final String KEY_ALARM_RINGTONE = "alarm_ringtone";
+
+    public AlarmRingtonePreferenceController(Context context) {
+        super(context);
+    }
+
+    @Override
+    public String getPreferenceKey() {
+        return KEY_ALARM_RINGTONE;
+    }
+
+    @Override
+    public int getRingtoneType() {
+        return RingtoneManager.TYPE_ALARM;
+    }
+}
diff --git a/src/com/android/settings/notification/EmergencyBroadcastPreferenceController.java b/src/com/android/settings/notification/EmergencyBroadcastPreferenceController.java
new file mode 100644 (file)
index 0000000..1154493
--- /dev/null
@@ -0,0 +1,99 @@
+/*
+ * Copyright (C) 2016 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.content.pm.PackageManager;
+import android.os.UserHandle;
+import android.os.UserManager;
+import android.support.v7.preference.Preference;
+
+import com.android.internal.annotations.VisibleForTesting;
+import com.android.settings.accounts.AccountRestrictionHelper;
+import com.android.settings.core.PreferenceController;
+import com.android.settingslib.RestrictedPreference;
+
+/**
+ * Base class for preference controller that handles preference that enforce adjust volume
+ * restriction
+ */
+public class EmergencyBroadcastPreferenceController extends PreferenceController {
+
+    private static final String KEY_CELL_BROADCAST_SETTINGS = "cell_broadcast_settings";
+
+    private AccountRestrictionHelper mHelper;
+    private UserManager mUserManager;
+    private PackageManager mPm;
+    private boolean mCellBroadcastAppLinkEnabled;
+
+    public EmergencyBroadcastPreferenceController(Context context) {
+        this(context, new AccountRestrictionHelper(context));
+    }
+
+    @VisibleForTesting
+    EmergencyBroadcastPreferenceController(Context context, AccountRestrictionHelper helper) {
+        super(context);
+        mHelper = helper;
+        mUserManager = UserManager.get(context);
+        mPm = mContext.getPackageManager();
+        // Enable link to CMAS app settings depending on the value in config.xml.
+        mCellBroadcastAppLinkEnabled = isCellBroadcastAppLinkEnabled();
+    }
+
+    @Override
+    public void updateState(Preference preference) {
+        if (!(preference instanceof RestrictedPreference)) {
+            return;
+        }
+        ((RestrictedPreference) preference).checkRestrictionAndSetDisabled(
+            UserManager.DISALLOW_CONFIG_CELL_BROADCASTS);
+    }
+
+    @Override
+    public boolean handlePreferenceTreeClick(Preference preference) {
+        return false;
+    }
+
+    @Override
+    public String getPreferenceKey() {
+        return KEY_CELL_BROADCAST_SETTINGS;
+    }
+
+    @Override
+    public boolean isAvailable() {
+        return mUserManager.isAdminUser() && mCellBroadcastAppLinkEnabled
+            && !mHelper.hasBaseUserRestriction(
+                UserManager.DISALLOW_CONFIG_CELL_BROADCASTS, UserHandle.myUserId());
+    }
+
+    private boolean isCellBroadcastAppLinkEnabled() {
+        boolean enabled = mContext.getResources().getBoolean(
+            com.android.internal.R.bool.config_cellBroadcastAppLinks);
+        if (enabled) {
+            try {
+                if (mPm.getApplicationEnabledSetting("com.android.cellbroadcastreceiver")
+                    == PackageManager.COMPONENT_ENABLED_STATE_DISABLED) {
+                    enabled = false;  // CMAS app disabled
+                }
+            } catch (IllegalArgumentException ignored) {
+                enabled = false;  // CMAS app not installed
+            }
+        }
+        return enabled;
+    }
+
+}
\ No newline at end of file
diff --git a/src/com/android/settings/notification/NotificationRingtonePreferenceController.java b/src/com/android/settings/notification/NotificationRingtonePreferenceController.java
new file mode 100644 (file)
index 0000000..72e8d8f
--- /dev/null
@@ -0,0 +1,39 @@
+/*
+ * Copyright (C) 2016 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.media.RingtoneManager;
+
+public class NotificationRingtonePreferenceController extends RingtonePreferenceControllerBase {
+
+    private static final String KEY_NOTIFICATION_RINGTONE = "notification_ringtone";
+
+    public NotificationRingtonePreferenceController(Context context) {
+        super(context);
+    }
+
+    @Override
+    public String getPreferenceKey() {
+        return KEY_NOTIFICATION_RINGTONE;
+    }
+
+    @Override
+    public int getRingtoneType() {
+        return RingtoneManager.TYPE_NOTIFICATION;
+    }
+}
diff --git a/src/com/android/settings/notification/PhoneRingtonePreferenceController.java b/src/com/android/settings/notification/PhoneRingtonePreferenceController.java
new file mode 100644 (file)
index 0000000..cb11151
--- /dev/null
@@ -0,0 +1,45 @@
+/*
+ * Copyright (C) 2016 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.media.RingtoneManager;
+import com.android.settings.Utils;
+
+public class PhoneRingtonePreferenceController extends RingtonePreferenceControllerBase {
+
+    private static final String KEY_PHONE_RINGTONE = "ringtone";
+
+    public PhoneRingtonePreferenceController(Context context) {
+        super(context);
+    }
+
+    @Override
+    public String getPreferenceKey() {
+        return KEY_PHONE_RINGTONE;
+    }
+
+    @Override
+    public boolean isAvailable() {
+        return Utils.isVoiceCapable(mContext);
+    }
+
+    @Override
+    public int getRingtoneType() {
+        return RingtoneManager.TYPE_RINGTONE;
+    }
+}
diff --git a/src/com/android/settings/notification/RingtonePreferenceControllerBase.java b/src/com/android/settings/notification/RingtonePreferenceControllerBase.java
new file mode 100644 (file)
index 0000000..333f08a
--- /dev/null
@@ -0,0 +1,55 @@
+/*
+ * Copyright (C) 2016 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.media.Ringtone;
+import android.media.RingtoneManager;
+import android.net.Uri;
+import android.support.v7.preference.Preference;
+
+import com.android.settings.core.PreferenceController;
+
+public abstract class RingtonePreferenceControllerBase extends PreferenceController {
+
+    public RingtonePreferenceControllerBase(Context context) {
+        super(context);
+    }
+
+    @Override
+    public boolean handlePreferenceTreeClick(Preference preference) {
+        return false;
+    }
+
+    @Override
+    public boolean isAvailable() {
+        return true;
+    }
+
+    @Override
+    public void updateState(Preference preference) {
+        Uri ringtoneUri = RingtoneManager.getActualDefaultRingtoneUri(mContext, getRingtoneType());
+        final CharSequence summary = Ringtone.getTitle(
+            mContext, ringtoneUri, false /* followSettingsUri */, true /* allowRemote */);
+        if (summary != null) {
+            preference.setSummary(summary);
+        }
+    }
+
+    public abstract int getRingtoneType();
+
+}
index 1adfdd8..9166377 100644 (file)
@@ -23,19 +23,15 @@ import android.app.Dialog;
 import android.app.FragmentManager;
 import android.app.NotificationManager;
 import android.content.BroadcastReceiver;
-import android.content.ContentResolver;
 import android.content.Context;
 import android.content.DialogInterface;
 import android.content.Intent;
 import android.content.IntentFilter;
-import android.content.pm.PackageManager;
-import android.database.ContentObserver;
 import android.media.AudioManager;
 import android.media.AudioSystem;
 import android.media.Ringtone;
 import android.media.RingtoneManager;
 import android.net.Uri;
-import android.os.AsyncTask;
 import android.os.Bundle;
 import android.os.Handler;
 import android.os.Looper;
@@ -63,8 +59,6 @@ import com.android.settings.core.lifecycle.Lifecycle;
 import com.android.settings.dashboard.DashboardFragment;
 import com.android.settings.dashboard.SummaryLoader;
 import com.android.settings.search.BaseSearchIndexProvider;
-import com.android.settingslib.RestrictedLockUtils;
-import com.android.settingslib.RestrictedPreference;
 
 import com.android.settingslib.drawer.CategoryKey;
 import java.text.NumberFormat;
@@ -76,12 +70,6 @@ public class SoundSettings extends DashboardFragment
         implements OnPreferenceChangeListener {
     private static final String TAG = "SoundSettings";
 
-    private static final String KEY_PHONE_RINGTONE = "ringtone";
-    private static final String KEY_NOTIFICATION_RINGTONE = "notification_ringtone";
-    private static final String KEY_ALARM_RINGTONE = "alarm_ringtone";
-    private static final String KEY_VIBRATE_WHEN_RINGING = "vibrate_when_ringing";
-    private static final String KEY_CELL_BROADCAST_SETTINGS = "cell_broadcast_settings";
-
     private static final String KEY_WORK_CATEGORY = "sound_work_settings_section";
     private static final String KEY_WORK_USE_PERSONAL_SOUNDS = "work_use_personal_sounds";
     private static final String KEY_WORK_PHONE_RINGTONE = "work_ringtone";
@@ -95,23 +83,16 @@ public class SoundSettings extends DashboardFragment
 
     private final VolumePreferenceCallback mVolumeCallback = new VolumePreferenceCallback();
     private final H mHandler = new H();
-    private final SettingsObserver mSettingsObserver = new SettingsObserver();
 
     private Context mContext;
     private boolean mVoiceCapable;
 
-    private Preference mPhoneRingtonePreference;
-    private Preference mNotificationRingtonePreference;
-    private Preference mAlarmRingtonePreference;
-    private TwoStatePreference mVibrateWhenRinging;
-
     private PreferenceGroup mWorkPreferenceCategory;
     private TwoStatePreference mWorkUsePersonalSounds;
     private Preference mWorkPhoneRingtonePreference;
     private Preference mWorkNotificationRingtonePreference;
     private Preference mWorkAlarmRingtonePreference;
 
-    private PackageManager mPm;
     private UserManager mUserManager;
     private RingtonePreference mRequestPreference;
 
@@ -126,31 +107,9 @@ public class SoundSettings extends DashboardFragment
     public void onCreate(Bundle savedInstanceState) {
         super.onCreate(savedInstanceState);
         mContext = getActivity();
-        mPm = getPackageManager();
         mUserManager = UserManager.get(getContext());
         mVoiceCapable = Utils.isVoiceCapable(mContext);
 
-        // Enable link to CMAS app settings depending on the value in config.xml.
-        boolean isCellBroadcastAppLinkEnabled = this.getResources().getBoolean(
-                com.android.internal.R.bool.config_cellBroadcastAppLinks);
-        try {
-            if (isCellBroadcastAppLinkEnabled) {
-                if (mPm.getApplicationEnabledSetting("com.android.cellbroadcastreceiver")
-                        == PackageManager.COMPONENT_ENABLED_STATE_DISABLED) {
-                    isCellBroadcastAppLinkEnabled = false;  // CMAS app disabled
-                }
-            }
-        } catch (IllegalArgumentException ignored) {
-            isCellBroadcastAppLinkEnabled = false;  // CMAS app not installed
-        }
-        if (!mUserManager.isAdminUser() || !isCellBroadcastAppLinkEnabled ||
-                RestrictedLockUtils.hasBaseUserRestriction(mContext,
-                        UserManager.DISALLOW_CONFIG_CELL_BROADCASTS, UserHandle.myUserId())) {
-            removePreference(KEY_CELL_BROADCAST_SETTINGS);
-        }
-        initRingtones();
-        initVibrateWhenRinging();
-
         if (savedInstanceState != null) {
             String selectedPreference = savedInstanceState.getString(SELECTED_PREFERENCE_KEY, null);
             if (!TextUtils.isEmpty(selectedPreference)) {
@@ -162,15 +121,6 @@ public class SoundSettings extends DashboardFragment
     @Override
     public void onResume() {
         super.onResume();
-        lookupRingtoneNames();
-        mSettingsObserver.register(true);
-
-        RestrictedPreference broadcastSettingsPref = (RestrictedPreference) findPreference(
-                KEY_CELL_BROADCAST_SETTINGS);
-        if (broadcastSettingsPref != null) {
-            broadcastSettingsPref.checkRestrictionAndSetDisabled(
-                    UserManager.DISALLOW_CONFIG_CELL_BROADCASTS);
-        }
 
         mManagedProfileId = Utils.getManagedProfileId(mUserManager, UserHandle.myUserId());
         if (mManagedProfileId != UserHandle.USER_NULL && shouldShowRingtoneSettings()) {
@@ -191,7 +141,6 @@ public class SoundSettings extends DashboardFragment
     public void onPause() {
         super.onPause();
         mVolumeCallback.stopSample();
-        mSettingsObserver.register(false);
     }
 
     @Override
@@ -226,12 +175,21 @@ public class SoundSettings extends DashboardFragment
         Lifecycle lifecycle = getLifecycle();
         controllers.add(new CastPreferenceController(context));
         controllers.add(new ZenModePreferenceController(context));
+        controllers.add(new EmergencyBroadcastPreferenceController(context));
+        controllers.add(new VibrateWhenRingPreferenceController(context));
+
         // === Volumes ===
         controllers.add(new AlarmVolumePreferenceController(context, mVolumeCallback, lifecycle));
         controllers.add(new MediaVolumePreferenceController(context, mVolumeCallback, lifecycle));
         controllers.add(
             new NotificationVolumePreferenceController(context, mVolumeCallback, lifecycle));
         controllers.add(new RingVolumePreferenceController(context, mVolumeCallback, lifecycle));
+
+        // === Phone & notification ringtone ===
+        controllers.add(new PhoneRingtonePreferenceController(context));
+        controllers.add(new AlarmRingtonePreferenceController(context));
+        controllers.add(new NotificationRingtonePreferenceController(context));
+
         return controllers;
     }
 
@@ -314,48 +272,6 @@ public class SoundSettings extends DashboardFragment
         return !AudioSystem.isSingleVolume(mContext);
     }
 
-    private void initRingtones() {
-        mPhoneRingtonePreference = getPreferenceScreen().findPreference(KEY_PHONE_RINGTONE);
-        if (mPhoneRingtonePreference != null && !mVoiceCapable) {
-            getPreferenceScreen().removePreference(mPhoneRingtonePreference);
-            mPhoneRingtonePreference = null;
-        }
-        mNotificationRingtonePreference =
-                getPreferenceScreen().findPreference(KEY_NOTIFICATION_RINGTONE);
-        mAlarmRingtonePreference = getPreferenceScreen().findPreference(KEY_ALARM_RINGTONE);
-    }
-
-    private void lookupRingtoneNames() {
-        AsyncTask.execute(mLookupRingtoneNames);
-    }
-
-    private final Runnable mLookupRingtoneNames = new Runnable() {
-        @Override
-        public void run() {
-            if (mPhoneRingtonePreference != null) {
-                final CharSequence summary = updateRingtoneName(
-                        mContext, RingtoneManager.TYPE_RINGTONE);
-                if (summary != null) {
-                    mHandler.obtainMessage(H.UPDATE_PHONE_RINGTONE, summary).sendToTarget();
-                }
-            }
-            if (mNotificationRingtonePreference != null) {
-                final CharSequence summary = updateRingtoneName(
-                        mContext, RingtoneManager.TYPE_NOTIFICATION);
-                if (summary != null) {
-                    mHandler.obtainMessage(H.UPDATE_NOTIFICATION_RINGTONE, summary).sendToTarget();
-                }
-            }
-            if (mAlarmRingtonePreference != null) {
-                final CharSequence summary =
-                        updateRingtoneName(mContext, RingtoneManager.TYPE_ALARM);
-                if (summary != null) {
-                    mHandler.obtainMessage(H.UPDATE_ALARM_RINGTONE, summary).sendToTarget();
-                }
-            }
-        }
-    };
-
     private static CharSequence updateRingtoneName(Context context, int type) {
         if (context == null) {
             Log.e(TAG, "Unable to update ringtone name, no context provided");
@@ -366,74 +282,11 @@ public class SoundSettings extends DashboardFragment
                 true /* allowRemote */);
     }
 
-    // === Vibrate when ringing ===
-
-    private void initVibrateWhenRinging() {
-        mVibrateWhenRinging =
-                (TwoStatePreference) getPreferenceScreen().findPreference(KEY_VIBRATE_WHEN_RINGING);
-        if (mVibrateWhenRinging == null) {
-            Log.i(TAG, "Preference not found: " + KEY_VIBRATE_WHEN_RINGING);
-            return;
-        }
-        if (!mVoiceCapable) {
-            getPreferenceScreen().removePreference(mVibrateWhenRinging);
-            mVibrateWhenRinging = null;
-            return;
-        }
-        mVibrateWhenRinging.setPersistent(false);
-        updateVibrateWhenRinging();
-        mVibrateWhenRinging.setOnPreferenceChangeListener(new OnPreferenceChangeListener() {
-            @Override
-            public boolean onPreferenceChange(Preference preference, Object newValue) {
-                final boolean val = (Boolean) newValue;
-                return Settings.System.putInt(getContentResolver(),
-                        Settings.System.VIBRATE_WHEN_RINGING,
-                        val ? 1 : 0);
-            }
-        });
-    }
-
-    private void updateVibrateWhenRinging() {
-        if (mVibrateWhenRinging == null) return;
-        mVibrateWhenRinging.setChecked(Settings.System.getInt(getContentResolver(),
-                Settings.System.VIBRATE_WHEN_RINGING, 0) != 0);
-    }
-
     // === Callbacks ===
 
-    private final class SettingsObserver extends ContentObserver {
-        private final Uri VIBRATE_WHEN_RINGING_URI =
-                Settings.System.getUriFor(Settings.System.VIBRATE_WHEN_RINGING);
-
-        public SettingsObserver() {
-            super(mHandler);
-        }
-
-        public void register(boolean register) {
-            final ContentResolver cr = getContentResolver();
-            if (register) {
-                cr.registerContentObserver(VIBRATE_WHEN_RINGING_URI, false, this);
-            } else {
-                cr.unregisterContentObserver(this);
-            }
-        }
-
-        @Override
-        public void onChange(boolean selfChange, Uri uri) {
-            super.onChange(selfChange, uri);
-            if (VIBRATE_WHEN_RINGING_URI.equals(uri)) {
-                updateVibrateWhenRinging();
-            }
-        }
-    }
 
     private final class H extends Handler {
-        private static final int UPDATE_PHONE_RINGTONE = 1;
-        private static final int UPDATE_NOTIFICATION_RINGTONE = 2;
-        private static final int STOP_SAMPLE = 3;
-        private static final int UPDATE_EFFECTS_SUPPRESSOR = 4;
-        private static final int UPDATE_RINGER_MODE = 5;
-        private static final int UPDATE_ALARM_RINGTONE = 6;
+        private static final int STOP_SAMPLE = 1;
 
         private H() {
             super(Looper.getMainLooper());
@@ -442,18 +295,9 @@ public class SoundSettings extends DashboardFragment
         @Override
         public void handleMessage(Message msg) {
             switch (msg.what) {
-                case UPDATE_PHONE_RINGTONE:
-                    mPhoneRingtonePreference.setSummary((CharSequence) msg.obj);
-                    break;
-                case UPDATE_NOTIFICATION_RINGTONE:
-                    mNotificationRingtonePreference.setSummary((CharSequence) msg.obj);
-                    break;
                 case STOP_SAMPLE:
                     mVolumeCallback.stopSample();
                     break;
-                case UPDATE_ALARM_RINGTONE:
-                    mAlarmRingtonePreference.setSummary((CharSequence) msg.obj);
-                    break;
             }
         }
     }
@@ -539,30 +383,9 @@ public class SoundSettings extends DashboardFragment
             new RingVolumePreferenceController(
                 context, null /* Callback */, null /* Lifecycle */).updateNonIndexableKeys(rt);
             new CastPreferenceController(context).updateNonIndexableKeys(rt);
-            if (!Utils.isVoiceCapable(context)) {
-                rt.add(KEY_PHONE_RINGTONE);
-                rt.add(KEY_VIBRATE_WHEN_RINGING);
-            }
-
-            final PackageManager pm = context.getPackageManager();
-            final UserManager um = (UserManager) context.getSystemService(Context.USER_SERVICE);
-
-            // Enable link to CMAS app settings depending on the value in config.xml.
-            boolean isCellBroadcastAppLinkEnabled = context.getResources().getBoolean(
-                    com.android.internal.R.bool.config_cellBroadcastAppLinks);
-            try {
-                if (isCellBroadcastAppLinkEnabled) {
-                    if (pm.getApplicationEnabledSetting("com.android.cellbroadcastreceiver")
-                            == PackageManager.COMPONENT_ENABLED_STATE_DISABLED) {
-                        isCellBroadcastAppLinkEnabled = false;  // CMAS app disabled
-                    }
-                }
-            } catch (IllegalArgumentException ignored) {
-                isCellBroadcastAppLinkEnabled = false;  // CMAS app not installed
-            }
-            if (!um.isAdminUser() || !isCellBroadcastAppLinkEnabled) {
-                rt.add(KEY_CELL_BROADCAST_SETTINGS);
-            }
+            new PhoneRingtonePreferenceController(context).updateNonIndexableKeys(rt);
+            new VibrateWhenRingPreferenceController(context).updateNonIndexableKeys(rt);
+            new EmergencyBroadcastPreferenceController(context).updateNonIndexableKeys(rt);
 
             return rt;
         }
diff --git a/src/com/android/settings/notification/VibrateWhenRingPreferenceController.java b/src/com/android/settings/notification/VibrateWhenRingPreferenceController.java
new file mode 100644 (file)
index 0000000..2160f3d
--- /dev/null
@@ -0,0 +1,129 @@
+/*
+ * Copyright (C) 2016 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 com.android.settings.Utils;
+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.System.VIBRATE_WHEN_RINGING;
+
+public class VibrateWhenRingPreferenceController extends PreferenceController implements
+        Preference.OnPreferenceChangeListener, LifecycleObserver, OnResume, OnPause {
+
+    private static final String KEY_VIBRATE_WHEN_RINGING = "vibrate_when_ringing";
+    private SettingObserver mSettingObserver;
+
+    public VibrateWhenRingPreferenceController(Context context) {
+        super(context);
+    }
+
+    @Override
+    public void displayPreference(PreferenceScreen screen) {
+        super.displayPreference(screen);
+        Preference preference = screen.findPreference(KEY_VIBRATE_WHEN_RINGING);
+        if (preference != null) {
+            mSettingObserver = new SettingObserver(preference);
+            preference.setPersistent(false);
+        }
+    }
+
+    @Override
+    public void onResume() {
+        if (mSettingObserver != null) {
+            mSettingObserver.register(true /* register */);
+        }
+    }
+
+    @Override
+    public void onPause() {
+        if (mSettingObserver != null) {
+            mSettingObserver.register(false /* register */);
+        }
+    }
+
+    @Override
+    public boolean handlePreferenceTreeClick(Preference preference) {
+        return false;
+    }
+
+    @Override
+    public String getPreferenceKey() {
+        return KEY_VIBRATE_WHEN_RINGING;
+    }
+
+    @Override
+    public boolean isAvailable() {
+        return Utils.isVoiceCapable(mContext);
+    }
+
+    @Override
+    public void updateState(Preference preference) {
+        ((TwoStatePreference) preference).setChecked(
+            Settings.System.getInt(mContext.getContentResolver(), VIBRATE_WHEN_RINGING, 0) != 0);
+    }
+
+    @Override
+    public boolean onPreferenceChange(Preference preference, Object newValue) {
+        final boolean val = (Boolean) newValue;
+        return Settings.System.putInt(mContext.getContentResolver(),
+            VIBRATE_WHEN_RINGING, val ? 1 : 0);
+    }
+
+    private final class SettingObserver extends ContentObserver {
+
+        private final Uri VIBRATE_WHEN_RINGING_URI =
+            Settings.System.getUriFor(VIBRATE_WHEN_RINGING);
+
+        private final Preference mPreference;
+
+        public SettingObserver(Preference preference) {
+            super(new Handler());
+            mPreference = preference;
+        }
+
+        public void register(boolean register) {
+            final ContentResolver cr = mContext.getContentResolver();
+            if (register) {
+                cr.registerContentObserver(VIBRATE_WHEN_RINGING_URI, false, this);
+            } else {
+                cr.unregisterContentObserver(this);
+            }
+        }
+
+        @Override
+        public void onChange(boolean selfChange, Uri uri) {
+            super.onChange(selfChange, uri);
+            if (VIBRATE_WHEN_RINGING_URI.equals(uri)) {
+                updateState(mPreference);
+            }
+        }
+    }
+
+}
index 76e5a22..994582c 100644 (file)
@@ -28,7 +28,6 @@ import com.android.settingslib.RestrictedPreference;
 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;
diff --git a/tests/robotests/src/com/android/settings/notification/AlarmRingtonePreferenceControllerTest.java b/tests/robotests/src/com/android/settings/notification/AlarmRingtonePreferenceControllerTest.java
new file mode 100644 (file)
index 0000000..4ac9179
--- /dev/null
@@ -0,0 +1,53 @@
+/*
+ * Copyright (C) 2016 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.media.RingtoneManager;
+
+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 static com.google.common.truth.Truth.assertThat;
+
+@RunWith(SettingsRobolectricTestRunner.class)
+@Config(manifest = TestConfig.MANIFEST_PATH, sdk = TestConfig.SDK_VERSION)
+public class AlarmRingtonePreferenceControllerTest {
+
+    @Mock
+    private Context mContext;
+    private AlarmRingtonePreferenceController mController;
+
+    @Before
+    public void setUp() {
+        MockitoAnnotations.initMocks(this);
+        mController = new AlarmRingtonePreferenceController(mContext);
+    }
+
+    @Test
+    public void getRingtoneType_shouldReturnAlarm() {
+        assertThat(mController.getRingtoneType()).isEqualTo(RingtoneManager.TYPE_ALARM);
+    }
+
+}
index 11370e3..a08ec17 100644 (file)
@@ -25,7 +25,6 @@ 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.annotation.Config;
index 7f1888a..5fe4c42 100644 (file)
@@ -28,7 +28,6 @@ import java.util.List;
 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;
diff --git a/tests/robotests/src/com/android/settings/notification/EmergencyBroadcastPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/notification/EmergencyBroadcastPreferenceControllerTest.java
new file mode 100644 (file)
index 0000000..98951d1
--- /dev/null
@@ -0,0 +1,124 @@
+/*
+ * Copyright (C) 2016 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.content.pm.PackageManager;
+import android.os.UserManager;
+
+import com.android.settings.SettingsRobolectricTestRunner;
+import com.android.settings.TestConfig;
+import com.android.settings.accounts.AccountRestrictionHelper;
+import com.android.settingslib.RestrictedPreference;
+
+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 static com.google.common.truth.Truth.assertThat;
+import static org.mockito.Mockito.anyInt;
+import static org.mockito.Mockito.anyString;
+import static org.mockito.Mockito.eq;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+
+@RunWith(SettingsRobolectricTestRunner.class)
+@Config(manifest = TestConfig.MANIFEST_PATH, sdk = TestConfig.SDK_VERSION)
+public class EmergencyBroadcastPreferenceControllerTest {
+
+    @Mock(answer = Answers.RETURNS_DEEP_STUBS)
+    private Context mContext;
+    @Mock
+    private AccountRestrictionHelper mAccountHelper;
+    @Mock
+    private PackageManager mPackageManager;
+    @Mock
+    private UserManager mUserManager;
+    @Mock
+    private RestrictedPreference mPreference;
+
+    private EmergencyBroadcastPreferenceController mController;
+
+    @Before
+    public void setUp() {
+        MockitoAnnotations.initMocks(this);
+        when(mContext.getSystemService(Context.USER_SERVICE)).thenReturn(mUserManager);
+        when(mContext.getPackageManager()).thenReturn(mPackageManager);
+        mController = new EmergencyBroadcastPreferenceController(mContext, mAccountHelper);
+    }
+
+    @Test
+    public void updateState_shouldCheckRestriction() {
+        mController.updateState(mPreference);
+
+        verify(mPreference).checkRestrictionAndSetDisabled(anyString());
+    }
+
+    @Test
+    public void isAvailable_notAdminUser_shouldReturnFalse() {
+        when(mUserManager.isAdminUser()).thenReturn(false);
+        when(mContext.getResources().getBoolean(
+            com.android.internal.R.bool.config_cellBroadcastAppLinks)).thenReturn(true);
+        when(mPackageManager.getApplicationEnabledSetting(anyString()))
+            .thenReturn(PackageManager.COMPONENT_ENABLED_STATE_ENABLED);
+        when(mAccountHelper.hasBaseUserRestriction(anyString(), anyInt())).thenReturn(false);
+
+        assertThat(mController.isAvailable()).isFalse();
+    }
+
+    @Test
+    public void isAvailable_hasConfigCellBroadcastRestriction_shouldReturnFalse() {
+        when(mUserManager.isAdminUser()).thenReturn(true);
+        when(mContext.getResources().getBoolean(
+            com.android.internal.R.bool.config_cellBroadcastAppLinks)).thenReturn(true);
+        when(mPackageManager.getApplicationEnabledSetting(anyString()))
+            .thenReturn(PackageManager.COMPONENT_ENABLED_STATE_ENABLED);
+        when(mAccountHelper.hasBaseUserRestriction(
+            eq(UserManager.DISALLOW_CONFIG_CELL_BROADCASTS), anyInt())).thenReturn(true);
+
+        assertThat(mController.isAvailable()).isFalse();
+    }
+
+    @Test
+    public void isAvailable_cellBroadcastAppLinkDisabled_shouldReturnFalse() {
+        when(mUserManager.isAdminUser()).thenReturn(true);
+        when(mContext.getResources().getBoolean(
+            com.android.internal.R.bool.config_cellBroadcastAppLinks)).thenReturn(false);
+        when(mPackageManager.getApplicationEnabledSetting(anyString()))
+            .thenReturn(PackageManager.COMPONENT_ENABLED_STATE_ENABLED);
+        when(mAccountHelper.hasBaseUserRestriction(anyString(), anyInt())).thenReturn(false);
+
+        assertThat(mController.isAvailable()).isFalse();
+    }
+
+    @Test
+    public void isAvailable_cellBroadcastReceiverDisabled_shouldReturnFalse() {
+        when(mUserManager.isAdminUser()).thenReturn(true);
+        when(mContext.getResources().getBoolean(
+            com.android.internal.R.bool.config_cellBroadcastAppLinks)).thenReturn(true);
+        when(mPackageManager.getApplicationEnabledSetting(anyString()))
+            .thenReturn(PackageManager.COMPONENT_ENABLED_STATE_DISABLED);
+        when(mAccountHelper.hasBaseUserRestriction(anyString(), anyInt())).thenReturn(false);
+
+        assertThat(mController.isAvailable()).isFalse();
+    }
+
+}
index 9c16937..9944379 100644 (file)
@@ -25,7 +25,6 @@ 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.annotation.Config;
diff --git a/tests/robotests/src/com/android/settings/notification/NotificationRingtonePreferenceControllerTest.java b/tests/robotests/src/com/android/settings/notification/NotificationRingtonePreferenceControllerTest.java
new file mode 100644 (file)
index 0000000..841367f
--- /dev/null
@@ -0,0 +1,53 @@
+/*
+ * Copyright (C) 2016 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.media.RingtoneManager;
+
+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 static com.google.common.truth.Truth.assertThat;
+
+@RunWith(SettingsRobolectricTestRunner.class)
+@Config(manifest = TestConfig.MANIFEST_PATH, sdk = TestConfig.SDK_VERSION)
+public class NotificationRingtonePreferenceControllerTest {
+
+    @Mock
+    private Context mContext;
+    private NotificationRingtonePreferenceController mController;
+
+    @Before
+    public void setUp() {
+        MockitoAnnotations.initMocks(this);
+        mController = new NotificationRingtonePreferenceController(mContext);
+    }
+
+    @Test
+    public void getRingtoneType_shouldReturnNotification() {
+        assertThat(mController.getRingtoneType()).isEqualTo(RingtoneManager.TYPE_NOTIFICATION);
+    }
+
+}
index e0aa88e..e6d8a41 100644 (file)
@@ -27,7 +27,6 @@ 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.annotation.Config;
diff --git a/tests/robotests/src/com/android/settings/notification/PhoneRingtonePreferenceControllerTest.java b/tests/robotests/src/com/android/settings/notification/PhoneRingtonePreferenceControllerTest.java
new file mode 100644 (file)
index 0000000..85e74b0
--- /dev/null
@@ -0,0 +1,75 @@
+/*
+ * Copyright (C) 2016 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.media.RingtoneManager;
+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.when;
+
+@RunWith(SettingsRobolectricTestRunner.class)
+@Config(manifest = TestConfig.MANIFEST_PATH, sdk = TestConfig.SDK_VERSION)
+public class PhoneRingtonePreferenceControllerTest {
+
+    @Mock
+    private TelephonyManager mTelephonyManager;
+
+    private Context mContext;
+    private PhoneRingtonePreferenceController mController;
+
+    @Before
+    public void setUp() {
+        MockitoAnnotations.initMocks(this);
+        ShadowApplication shadowContext = ShadowApplication.getInstance();
+        shadowContext.setSystemService(Context.TELEPHONY_SERVICE, mTelephonyManager);
+        mContext = shadowContext.getApplicationContext();
+        mController = new PhoneRingtonePreferenceController(mContext);
+    }
+
+    @Test
+    public void isAvailable_notVoiceCapable_shouldReturnFalse() {
+        when(mTelephonyManager.isVoiceCapable()).thenReturn(false);
+
+        assertThat(mController.isAvailable()).isFalse();
+    }
+
+    @Test
+    public void isAvailable_VoiceCapable_shouldReturnTrue() {
+        when(mTelephonyManager.isVoiceCapable()).thenReturn(true);
+
+        assertThat(mController.isAvailable()).isTrue();
+    }
+
+    @Test
+    public void getRingtoneType_shouldReturnRingtone() {
+        assertThat(mController.getRingtoneType()).isEqualTo(RingtoneManager.TYPE_RINGTONE);
+    }
+
+}
index 2d54cef..4780e5c 100644 (file)
@@ -30,7 +30,6 @@ 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.annotation.Config;
diff --git a/tests/robotests/src/com/android/settings/notification/RingtonePreferenceControllerBaseTest.java b/tests/robotests/src/com/android/settings/notification/RingtonePreferenceControllerBaseTest.java
new file mode 100644 (file)
index 0000000..d680c38
--- /dev/null
@@ -0,0 +1,85 @@
+/*
+ * Copyright (C) 2016 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.support.v7.preference.Preference;
+import android.media.RingtoneManager;
+
+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 static com.google.common.truth.Truth.assertThat;
+import static org.mockito.Matchers.anyString;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.verify;
+
+@RunWith(SettingsRobolectricTestRunner.class)
+@Config(manifest = TestConfig.MANIFEST_PATH, sdk = TestConfig.SDK_VERSION)
+public class RingtonePreferenceControllerBaseTest {
+
+    @Mock
+    private Context mContext;
+
+    private RingtonePreferenceControllerBase mController;
+
+    @Before
+    public void setUp() {
+        MockitoAnnotations.initMocks(this);
+        mController = new RingtonePreferenceControllerBaseTestable(mContext);
+    }
+
+    @Test
+    public void isAlwaysAvailable() {
+        assertThat(mController.isAvailable()).isTrue();
+    }
+
+
+    @Test
+    public void updateState_shouldSetSummary() {
+        Preference preference = mock(Preference.class);
+
+        mController.updateState(preference);
+
+        verify(preference).setSummary(anyString());
+    }
+
+    private class RingtonePreferenceControllerBaseTestable extends
+        RingtonePreferenceControllerBase {
+        RingtonePreferenceControllerBaseTestable(Context context) {
+            super(context);
+        }
+
+        @Override
+        public String getPreferenceKey() {
+            return null;
+        }
+
+        @Override
+        public int getRingtoneType() {
+            return RingtoneManager.TYPE_RINGTONE;
+        }
+    }
+
+}
diff --git a/tests/robotests/src/com/android/settings/notification/VibrateWhenRingPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/notification/VibrateWhenRingPreferenceControllerTest.java
new file mode 100644 (file)
index 0000000..3c3f212
--- /dev/null
@@ -0,0 +1,109 @@
+/*
+ * Copyright (C) 2016 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 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 android.provider.Settings.System.VIBRATE_WHEN_RINGING;
+import static org.mockito.Matchers.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(SettingsRobolectricTestRunner.class)
+@Config(manifest = TestConfig.MANIFEST_PATH, sdk = TestConfig.SDK_VERSION)
+public class VibrateWhenRingPreferenceControllerTest {
+
+    @Mock
+    private Context mContext;
+    @Mock
+    private PreferenceScreen mScreen;
+    @Mock
+    private TelephonyManager mTelephonyManager;
+
+    private VibrateWhenRingPreferenceController mController;
+
+    @Before
+    public void setUp() {
+        MockitoAnnotations.initMocks(this);
+        when(mContext.getSystemService(Context.TELEPHONY_SERVICE)).thenReturn(mTelephonyManager);
+        mController = new VibrateWhenRingPreferenceController(mContext);
+    }
+
+    @Test
+    public void display_voiceCapable_shouldDisplay() {
+        when(mTelephonyManager.isVoiceCapable()).thenReturn(true);
+        when(mScreen.findPreference(mController.getPreferenceKey()))
+            .thenReturn(mock(Preference.class));
+
+        mController.displayPreference(mScreen);
+
+        verify(mScreen, never()).removePreference(any(Preference.class));
+    }
+
+    @Test
+    public void display_notVoiceCapable_shouldNotDisplay() {
+        when(mTelephonyManager.isVoiceCapable()).thenReturn(false);
+        when(mScreen.findPreference(mController.getPreferenceKey()))
+                .thenReturn(mock(Preference.class));
+
+        mController.displayPreference(mScreen);
+
+        verify(mScreen).removePreference(any(Preference.class));
+    }
+
+    @Test
+    public void updateState_settingIsOn_preferenceShouldBeChecked() {
+        final TwoStatePreference preference = mock(TwoStatePreference.class);
+        final Context context = ShadowApplication.getInstance().getApplicationContext();
+        Settings.System.putInt(context.getContentResolver(), VIBRATE_WHEN_RINGING, 1);
+
+        mController = new VibrateWhenRingPreferenceController(context);
+        mController.updateState(preference);
+
+        verify(preference).setChecked(true);
+    }
+
+    @Test
+    public void updateState_settingIsOff_preferenceShouldNotBeChecked() {
+        final TwoStatePreference preference = mock(TwoStatePreference.class);
+        final Context context = ShadowApplication.getInstance().getApplicationContext();
+        Settings.System.putInt(context.getContentResolver(), VIBRATE_WHEN_RINGING, 0);
+
+        mController = new VibrateWhenRingPreferenceController(context);
+        mController.updateState(preference);
+
+        verify(preference).setChecked(false);
+    }
+}
index 2d0aaeb..581ed47 100644 (file)
@@ -27,7 +27,6 @@ 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.annotation.Config;
index 7b53a86..155e6ea 100644 (file)
@@ -24,7 +24,6 @@ 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.annotation.Config;