diff --git a/src/com/android/settings/development/qstile/DevelopmentTilePreferenceController.java b/src/com/android/settings/development/qstile/DevelopmentTilePreferenceController.java index 083a7195c77..51fcb2cb435 100644 --- a/src/com/android/settings/development/qstile/DevelopmentTilePreferenceController.java +++ b/src/com/android/settings/development/qstile/DevelopmentTilePreferenceController.java @@ -22,17 +22,23 @@ import android.content.Intent; import android.content.pm.PackageManager; import android.content.pm.ResolveInfo; import android.content.pm.ServiceInfo; +import android.os.RemoteException; +import android.os.ServiceManager; import android.service.quicksettings.TileService; +import android.support.annotation.VisibleForTesting; import android.support.v14.preference.SwitchPreference; import android.support.v7.preference.Preference; import android.support.v7.preference.PreferenceScreen; +import android.util.Log; +import com.android.internal.statusbar.IStatusBarService; import com.android.settingslib.core.AbstractPreferenceController; import java.util.List; public class DevelopmentTilePreferenceController extends AbstractPreferenceController { + private static final String TAG = "DevTilePrefController"; private final OnChangeHandler mOnChangeHandler; private final PackageManager mPackageManager; @@ -78,24 +84,42 @@ public class DevelopmentTilePreferenceController extends AbstractPreferenceContr } } - private static class OnChangeHandler implements Preference.OnPreferenceChangeListener { + @VisibleForTesting + static class OnChangeHandler implements Preference.OnPreferenceChangeListener { private final Context mContext; private final PackageManager mPackageManager; + private IStatusBarService mStatusBarService; public OnChangeHandler(Context context) { mContext = context; mPackageManager = context.getPackageManager(); + mStatusBarService = IStatusBarService.Stub.asInterface( + ServiceManager.checkService(Context.STATUS_BAR_SERVICE)); } @Override public boolean onPreferenceChange(Preference preference, Object newValue) { - ComponentName cn = new ComponentName( + boolean enabled = ((Boolean) newValue).booleanValue(); + ComponentName componentName = new ComponentName( mContext.getPackageName(), preference.getKey()); - mPackageManager.setComponentEnabledSetting(cn, (Boolean) newValue + mPackageManager.setComponentEnabledSetting(componentName, enabled ? PackageManager.COMPONENT_ENABLED_STATE_ENABLED : PackageManager.COMPONENT_ENABLED_STATE_DISABLED, PackageManager.DONT_KILL_APP); + + try { + if (mStatusBarService != null) { + if (enabled) { + mStatusBarService.addTile(componentName); + } else { + mStatusBarService.remTile(componentName); + } + } + } catch (RemoteException e) { + Log.e(TAG, "Failed to modify QS tile for component " + + componentName.toString(), e); + } return true; } } diff --git a/tests/robotests/src/com/android/settings/development/qstile/DevelopmentTilePreferenceControllerTest.java b/tests/robotests/src/com/android/settings/development/qstile/DevelopmentTilePreferenceControllerTest.java index 1cdff2092d9..e107344b58c 100644 --- a/tests/robotests/src/com/android/settings/development/qstile/DevelopmentTilePreferenceControllerTest.java +++ b/tests/robotests/src/com/android/settings/development/qstile/DevelopmentTilePreferenceControllerTest.java @@ -17,19 +17,25 @@ package com.android.settings.development.qstile; import static com.google.common.truth.Truth.assertThat; + import static org.mockito.Matchers.any; +import static org.mockito.Mockito.spy; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; +import android.content.ComponentName; import android.content.Context; import android.content.Intent; import android.content.pm.PackageManager; import android.content.pm.ResolveInfo; import android.content.pm.ServiceInfo; +import android.os.RemoteException; import android.service.quicksettings.TileService; +import android.support.v14.preference.SwitchPreference; import android.support.v7.preference.Preference; import android.support.v7.preference.PreferenceScreen; +import com.android.internal.statusbar.IStatusBarService; import com.android.settings.R; import com.android.settings.TestConfig; import com.android.settings.testutils.SettingsRobolectricTestRunner; @@ -37,22 +43,28 @@ import com.android.settings.testutils.SettingsRobolectricTestRunner; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; +import org.mockito.ArgumentCaptor; import org.mockito.Mock; import org.mockito.MockitoAnnotations; import org.robolectric.RuntimeEnvironment; import org.robolectric.Shadows; import org.robolectric.annotation.Config; import org.robolectric.shadows.ShadowPackageManager; +import org.robolectric.util.ReflectionHelpers; @RunWith(SettingsRobolectricTestRunner.class) @Config(manifest = TestConfig.MANIFEST_PATH, sdk = TestConfig.SDK_VERSION) public class DevelopmentTilePreferenceControllerTest { + private static final String SERVICE_INFO_NAME = "TestName"; @Mock private PreferenceScreen mScreen; + @Mock + private IStatusBarService mStatusBarService; private Context mContext; private DevelopmentTilePreferenceController mController; private ShadowPackageManager mShadowPackageManager; + private DevelopmentTilePreferenceController.OnChangeHandler mOnChangeHandler; @Before public void setUp() { @@ -63,6 +75,9 @@ public class DevelopmentTilePreferenceControllerTest { mController = new DevelopmentTilePreferenceController(mContext); assertThat(mController.getPreferenceKey()).isNull(); + + mOnChangeHandler = spy(new DevelopmentTilePreferenceController.OnChangeHandler(mContext)); + ReflectionHelpers.setField(mOnChangeHandler, "mStatusBarService", mStatusBarService); } @Test @@ -86,6 +101,38 @@ public class DevelopmentTilePreferenceControllerTest { verify(mScreen).addPreference(any(Preference.class)); } + @Test + public void preferenceChecked_shouldAddTile() throws RemoteException { + SwitchPreference preference = createPreference(/* defaultCheckedState = */ false); + preference.performClick(); + + ArgumentCaptor argument = ArgumentCaptor.forClass(ComponentName.class); + verify(mStatusBarService).addTile(argument.capture()); + assertThat(argument.getValue().getClassName()).isEqualTo(SERVICE_INFO_NAME); + assertThat(argument.getValue().getPackageName()).isEqualTo(mContext.getPackageName()); + } + + @Test + public void preferenceUnchecked_shouldRemoveTile() throws RemoteException { + SwitchPreference preference = createPreference(/* defaultCheckedState = */ true); + preference.performClick(); + + ArgumentCaptor argument = ArgumentCaptor.forClass(ComponentName.class); + verify(mStatusBarService).remTile(argument.capture()); + assertThat(argument.getValue().getClassName()).isEqualTo(SERVICE_INFO_NAME); + assertThat(argument.getValue().getPackageName()).isEqualTo(mContext.getPackageName()); + } + + private SwitchPreference createPreference(boolean defaultCheckedState) { + SwitchPreference preference = new SwitchPreference(mContext); + preference.setTitle("Test Pref"); + preference.setIcon(R.drawable.ic_settings_24dp); + preference.setKey(SERVICE_INFO_NAME); + preference.setChecked(defaultCheckedState); + preference.setOnPreferenceChangeListener(mOnChangeHandler); + return preference; + } + public static class FakeServiceInfo extends ServiceInfo { public String loadLabel(PackageManager mgr) {