Loading src/com/android/settings/development/qstile/DevelopmentTilePreferenceController.java +27 −3 Original line number Diff line number Diff line Loading @@ -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; Loading Loading @@ -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; } } Loading tests/robotests/src/com/android/settings/development/qstile/DevelopmentTilePreferenceControllerTest.java +47 −0 Original line number Diff line number Diff line Loading @@ -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; Loading @@ -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() { Loading @@ -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 Loading @@ -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<ComponentName> 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<ComponentName> 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) { Loading Loading
src/com/android/settings/development/qstile/DevelopmentTilePreferenceController.java +27 −3 Original line number Diff line number Diff line Loading @@ -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; Loading Loading @@ -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; } } Loading
tests/robotests/src/com/android/settings/development/qstile/DevelopmentTilePreferenceControllerTest.java +47 −0 Original line number Diff line number Diff line Loading @@ -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; Loading @@ -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() { Loading @@ -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 Loading @@ -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<ComponentName> 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<ComponentName> 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) { Loading