From c1d42a510a093488aa289acffd6416ab6dd365a3 Mon Sep 17 00:00:00 2001 From: Daniel Nishi Date: Tue, 12 Sep 2017 16:05:12 -0700 Subject: [PATCH 01/23] Remove outdated storage search results. The cache category is gone. Also, downloads no longer comes from that screen. Change-Id: Ia9a85b6496b0be3106e0ca8572b7c0aed38f336c Fixes: 65266640 Test: Manual --- .../android/settings/deviceinfo/StorageSettings.java | 10 ---------- 1 file changed, 10 deletions(-) diff --git a/src/com/android/settings/deviceinfo/StorageSettings.java b/src/com/android/settings/deviceinfo/StorageSettings.java index 01075559cdb..01903c0e9d0 100644 --- a/src/com/android/settings/deviceinfo/StorageSettings.java +++ b/src/com/android/settings/deviceinfo/StorageSettings.java @@ -603,16 +603,6 @@ public class StorageSettings extends SettingsPreferenceFragment implements Index data.screenTitle = context.getString(R.string.storage_settings); result.add(data); - data = new SearchIndexableRaw(context); - data.title = context.getString(R.string.memory_downloads_usage); - data.screenTitle = context.getString(R.string.storage_settings); - result.add(data); - - data = new SearchIndexableRaw(context); - data.title = context.getString(R.string.memory_media_cache_usage); - data.screenTitle = context.getString(R.string.storage_settings); - result.add(data); - data = new SearchIndexableRaw(context); data.title = context.getString(R.string.memory_media_misc_usage); data.screenTitle = context.getString(R.string.storage_settings); From 0221a56c25cb31eecc0dbb5879f8dcbdf80cc3ce Mon Sep 17 00:00:00 2001 From: Wale Ogunwale Date: Tue, 12 Sep 2017 17:07:44 -0700 Subject: [PATCH 02/23] Removed unused use of setting launch stack id. Why are you setting to what is already the default? Test: N/A Change-Id: I507d526db96d5e595e00289eea9ec84dfb87556d --- .../settings/password/ConfirmDeviceCredentialBaseFragment.java | 1 - 1 file changed, 1 deletion(-) diff --git a/src/com/android/settings/password/ConfirmDeviceCredentialBaseFragment.java b/src/com/android/settings/password/ConfirmDeviceCredentialBaseFragment.java index a67184a8ae3..2cb337b5294 100644 --- a/src/com/android/settings/password/ConfirmDeviceCredentialBaseFragment.java +++ b/src/com/android/settings/password/ConfirmDeviceCredentialBaseFragment.java @@ -243,7 +243,6 @@ public abstract class ConfirmDeviceCredentialBaseFragment extends OptionsMenuFra try { IActivityManager activityManager = ActivityManager.getService(); final ActivityOptions options = ActivityOptions.makeBasic(); - options.setLaunchStackId(ActivityManager.StackId.INVALID_STACK_ID); activityManager.startActivityFromRecents(taskId, options.toBundle()); return; } catch (RemoteException e) { From bbd47bd460569df7d0010d72ad0ae6392fdc2445 Mon Sep 17 00:00:00 2001 From: "edgar.huang" Date: Wed, 13 Sep 2017 11:04:01 +0800 Subject: [PATCH 03/23] Don't need to authenticate fingerprint when the fingerprint list is empty. Enter into the fingerprint list screen and can authenticate fingerprint still when the list is empty. Test: manual - enrolling some fingerprints and remove all fingerprintd, touch the fingerprint touch panel and no response. --- src/com/android/settings/fingerprint/FingerprintSettings.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/com/android/settings/fingerprint/FingerprintSettings.java b/src/com/android/settings/fingerprint/FingerprintSettings.java index 607d28cdd72..d717bff1aaf 100644 --- a/src/com/android/settings/fingerprint/FingerprintSettings.java +++ b/src/com/android/settings/fingerprint/FingerprintSettings.java @@ -275,7 +275,8 @@ public class FingerprintSettings extends SubSettings { } private void retryFingerprint() { - if (mRemovalSidecar.inProgress()) { + if (mRemovalSidecar.inProgress() + || 0 == mFingerprintManager.getEnrolledFingerprints(mUserId).size()) { return; } if (!mInFingerprintLockout) { From f1f7dcb2f58fb51417b01b996333c83e23b61791 Mon Sep 17 00:00:00 2001 From: Peng Du Date: Thu, 3 Aug 2017 19:35:53 +0800 Subject: [PATCH 04/23] Default apps settings disappear when switching to secondary user When switching to a secondary user, Settings will disable all extra categories that aren't configured in SETTINGS_FOR_RESTRICTED. As the result, Default apps settings disappear. To fix this issue, AdvancedAppsActivity class of Default apps settings should be added to SETTINGS_FOR_RESTRICTED. Fixes: 65616610 Test: manual - switch to a secondary user and go to Settings > Apps & notifications. Change-Id: Ie9f3b1d215e2e43bf25b8dd2971f86bd60e94d04 --- src/com/android/settings/core/gateway/SettingsGateway.java | 1 + 1 file changed, 1 insertion(+) diff --git a/src/com/android/settings/core/gateway/SettingsGateway.java b/src/com/android/settings/core/gateway/SettingsGateway.java index edf2b75d06c..e78e0248401 100644 --- a/src/com/android/settings/core/gateway/SettingsGateway.java +++ b/src/com/android/settings/core/gateway/SettingsGateway.java @@ -272,6 +272,7 @@ public class SettingsGateway { // Home page > Apps & Notifications Settings.UserSettingsActivity.class.getName(), Settings.ConfigureNotificationSettingsActivity.class.getName(), + Settings.AdvancedAppsActivity.class.getName(), Settings.ManageApplicationsActivity.class.getName(), Settings.PaymentSettingsActivity.class.getName(), // Home page > Security & screen lock From f4e1295f6fbbdd98c436a804216acd7a93846902 Mon Sep 17 00:00:00 2001 From: jeffreyhuang Date: Tue, 12 Sep 2017 15:09:00 -0700 Subject: [PATCH 05/23] Introduce StayAwakePreferenceController - Create new StayAwakePreferenceController - Create controller inside the DashboardFragment - Port logic from DevelopmentSettings into the controller Bug: 34203528 Test: make RunSettingsRoboTests -j40 ROBOTEST_FILTER=StayAwakePreferenceControllerTest Change-Id: I7642656fb2e323878face52f0a3c57fec1d85ac4 --- .../DevelopmentSettingsDashboardFragment.java | 14 +- .../StayAwakePreferenceController.java | 139 ++++++++++++++++++ .../StayAwakePreferenceControllerTest.java | 117 +++++++++++++++ 3 files changed, 266 insertions(+), 4 deletions(-) create mode 100644 src/com/android/settings/development/StayAwakePreferenceController.java create mode 100644 tests/robotests/src/com/android/settings/development/StayAwakePreferenceControllerTest.java diff --git a/src/com/android/settings/development/DevelopmentSettingsDashboardFragment.java b/src/com/android/settings/development/DevelopmentSettingsDashboardFragment.java index 919dc3a4bef..576829946ed 100644 --- a/src/com/android/settings/development/DevelopmentSettingsDashboardFragment.java +++ b/src/com/android/settings/development/DevelopmentSettingsDashboardFragment.java @@ -32,8 +32,10 @@ import com.android.settings.search.BaseSearchIndexProvider; import com.android.settings.search.Indexable; import com.android.settings.widget.SwitchBar; import com.android.settingslib.core.AbstractPreferenceController; +import com.android.settingslib.core.lifecycle.Lifecycle; import com.android.settingslib.development.DevelopmentSettingsEnabler; +import java.util.ArrayList; import java.util.Arrays; import java.util.List; @@ -116,7 +118,7 @@ public class DevelopmentSettingsDashboardFragment extends RestrictedDashboardFra @Override protected List getPreferenceControllers(Context context) { - return buildPreferenceControllers(context); + return buildPreferenceControllers(context, getLifecycle()); } void onEnableDevelopmentOptionsConfirmed() { @@ -129,8 +131,12 @@ public class DevelopmentSettingsDashboardFragment extends RestrictedDashboardFra mSwitchBar.setChecked(false); } - private static List buildPreferenceControllers(Context context) { - return null; + private static List buildPreferenceControllers(Context context, + Lifecycle lifecycle) { + final List controllers = new ArrayList<>(); + controllers.add(new StayAwakePreferenceController(context, lifecycle)); + + return controllers; } /** @@ -156,7 +162,7 @@ public class DevelopmentSettingsDashboardFragment extends RestrictedDashboardFra @Override public List getPreferenceControllers(Context context) { - return buildPreferenceControllers(context); + return buildPreferenceControllers(context, null /* lifecycle */); } }; } diff --git a/src/com/android/settings/development/StayAwakePreferenceController.java b/src/com/android/settings/development/StayAwakePreferenceController.java new file mode 100644 index 00000000000..ebba9e51496 --- /dev/null +++ b/src/com/android/settings/development/StayAwakePreferenceController.java @@ -0,0 +1,139 @@ +package com.android.settings.development; + +import android.content.ContentResolver; +import android.content.Context; +import android.database.ContentObserver; +import android.net.Uri; +import android.os.BatteryManager; +import android.os.Handler; +import android.provider.Settings; +import android.support.annotation.VisibleForTesting; +import android.support.v7.preference.Preference; +import android.support.v7.preference.PreferenceScreen; + +import com.android.settings.core.PreferenceControllerMixin; +import com.android.settingslib.RestrictedLockUtils; +import com.android.settingslib.RestrictedSwitchPreference; +import com.android.settingslib.core.AbstractPreferenceController; +import com.android.settingslib.core.lifecycle.Lifecycle; +import com.android.settingslib.core.lifecycle.LifecycleObserver; +import com.android.settingslib.core.lifecycle.events.OnPause; +import com.android.settingslib.core.lifecycle.events.OnResume; + + +public class StayAwakePreferenceController extends AbstractPreferenceController implements + PreferenceControllerMixin, Preference.OnPreferenceChangeListener, LifecycleObserver, + OnResume, OnPause { + + private static final String TAG = "StayAwakeCtrl"; + private static final String PREFERENCE_KEY = "keep_screen_on"; + @VisibleForTesting + static final int SETTING_VALUE_OFF = 0; + @VisibleForTesting + static final int SETTING_VALUE_ON = + BatteryManager.BATTERY_PLUGGED_AC | BatteryManager.BATTERY_PLUGGED_USB + | BatteryManager.BATTERY_PLUGGED_WIRELESS; + @VisibleForTesting + SettingsObserver mSettingsObserver; + + private RestrictedSwitchPreference mPreference; + + public StayAwakePreferenceController(Context context, Lifecycle lifecycle) { + super(context); + mSettingsObserver = new SettingsObserver(); + + if (lifecycle != null) { + lifecycle.addObserver(this); + } + } + + @Override + public boolean isAvailable() { + return true; + } + + @Override + public String getPreferenceKey() { + return PREFERENCE_KEY; + } + + @Override + public void displayPreference(PreferenceScreen screen) { + super.displayPreference(screen); + mPreference = (RestrictedSwitchPreference) screen.findPreference(getPreferenceKey()); + } + + @Override + public boolean onPreferenceChange(Preference preference, Object newValue) { + final boolean stayAwake = (Boolean) newValue; + Settings.Global.putInt(mContext.getContentResolver(), + Settings.Global.STAY_ON_WHILE_PLUGGED_IN, + stayAwake ? SETTING_VALUE_ON : SETTING_VALUE_OFF); + return true; + } + + @Override + public void updateState(Preference preference) { + final RestrictedLockUtils.EnforcedAdmin admin = checkIfMaximumTimeToLockSetByAdmin(); + if (admin != null) { + mPreference.setDisabledByAdmin(admin); + return; + } + + final int stayAwakeMode = Settings.Global.getInt(mContext.getContentResolver(), + Settings.Global.STAY_ON_WHILE_PLUGGED_IN, + SETTING_VALUE_OFF); + mPreference.setChecked(stayAwakeMode != SETTING_VALUE_OFF); + } + + @Override + public void onResume() { + if (mPreference != null) { + mSettingsObserver.register(true /* register */); + } + } + + @Override + public void onPause() { + if (mPreference != null) { + mSettingsObserver.register(false /* unregister */); + } + } + + @VisibleForTesting + RestrictedLockUtils.EnforcedAdmin checkIfMaximumTimeToLockSetByAdmin() { + // A DeviceAdmin has specified a maximum time until the device + // will lock... in this case we can't allow the user to turn + // on "stay awake when plugged in" because that would defeat the + // restriction. + return RestrictedLockUtils.checkIfMaximumTimeToLockIsSet(mContext); + } + + @VisibleForTesting + class SettingsObserver extends ContentObserver { + private final Uri mStayAwakeUri = Settings.Global.getUriFor( + Settings.Global.STAY_ON_WHILE_PLUGGED_IN); + + public SettingsObserver() { + super(new Handler()); + } + + public void register(boolean register) { + final ContentResolver cr = mContext.getContentResolver(); + if (register) { + cr.registerContentObserver( + mStayAwakeUri, false, this); + } else { + cr.unregisterContentObserver(this); + } + } + + @Override + public void onChange(boolean selfChange, Uri uri) { + super.onChange(selfChange, uri); + if (mStayAwakeUri.equals(uri)) { + updateState(mPreference); + } + } + } +} diff --git a/tests/robotests/src/com/android/settings/development/StayAwakePreferenceControllerTest.java b/tests/robotests/src/com/android/settings/development/StayAwakePreferenceControllerTest.java new file mode 100644 index 00000000000..cbef53173e1 --- /dev/null +++ b/tests/robotests/src/com/android/settings/development/StayAwakePreferenceControllerTest.java @@ -0,0 +1,117 @@ +package com.android.settings.development; + +import static com.google.common.truth.Truth.assertThat; + +import static org.mockito.Mockito.doReturn; +import static org.mockito.Mockito.never; +import static org.mockito.Mockito.spy; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.when; + +import android.content.ContentResolver; +import android.content.Context; +import android.provider.Settings; +import android.support.v7.preference.PreferenceScreen; + +import com.android.settings.TestConfig; +import com.android.settings.testutils.SettingsRobolectricTestRunner; +import com.android.settingslib.RestrictedLockUtils; +import com.android.settingslib.RestrictedSwitchPreference; +import com.android.settingslib.core.lifecycle.Lifecycle; + +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.Mock; +import org.mockito.Mockito; +import org.mockito.MockitoAnnotations; +import org.robolectric.RuntimeEnvironment; +import org.robolectric.annotation.Config; + +@RunWith(SettingsRobolectricTestRunner.class) +@Config(manifest = TestConfig.MANIFEST_PATH, sdk = TestConfig.SDK_VERSION) +public class StayAwakePreferenceControllerTest { + + @Mock + private Context mContext; + @Mock + private RestrictedSwitchPreference mPreference; + @Mock + private PreferenceScreen mPreferenceScreen; + @Mock + private Lifecycle mLifecycle; + private ContentResolver mContentResolver; + private StayAwakePreferenceController mController; + + @Before + public void setup() { + MockitoAnnotations.initMocks(this); + mContentResolver = RuntimeEnvironment.application.getContentResolver(); + mController = new StayAwakePreferenceController(mContext, mLifecycle); + when(mContext.getContentResolver()).thenReturn(mContentResolver); + when(mPreferenceScreen.findPreference(mController.getPreferenceKey())).thenReturn( + mPreference); + mController.displayPreference(mPreferenceScreen); + } + + @Test + public void onPreferenceChanged_turnOnStayAwake() { + mController.onPreferenceChange(null, true); + + final int mode = Settings.System.getInt(mContentResolver, + Settings.Global.STAY_ON_WHILE_PLUGGED_IN, -1); + assertThat(mode).isEqualTo(StayAwakePreferenceController.SETTING_VALUE_ON); + } + + @Test + public void onPreferenceChanged_turnOffStayAwake() { + mController.onPreferenceChange(null, false); + + final int mode = Settings.System.getInt(mContentResolver, + Settings.Global.STAY_ON_WHILE_PLUGGED_IN, -1); + assertThat(mode).isEqualTo(StayAwakePreferenceController.SETTING_VALUE_OFF); + } + + @Test + public void updateState_preferenceShouldBeChecked() { + Settings.System.putInt(mContentResolver, Settings.Global.STAY_ON_WHILE_PLUGGED_IN, + StayAwakePreferenceController.SETTING_VALUE_ON); + mController.updateState(mPreference); + verify(mPreference).setChecked(true); + } + + @Test + public void updateState_preferenceShouldNotBeChecked() { + Settings.System.putInt(mContentResolver, Settings.Global.STAY_ON_WHILE_PLUGGED_IN, + StayAwakePreferenceController.SETTING_VALUE_OFF); + mController.updateState(mPreference); + verify(mPreference).setChecked(false); + } + + @Test + public void displayPreference_expectSetDisabledByAdminToBeCalled() { + mController = spy(mController); + RestrictedLockUtils.EnforcedAdmin admin = Mockito.mock( + RestrictedLockUtils.EnforcedAdmin.class); + doReturn(admin).when(mController).checkIfMaximumTimeToLockSetByAdmin(); + mController.updateState(mPreference); + verify(mPreference).setDisabledByAdmin(admin); + } + + @Test + public void observerOnChangeCalledWithSameUri_preferenceShouldBeUpdated() { + Settings.System.putInt(mContentResolver, Settings.Global.STAY_ON_WHILE_PLUGGED_IN, + StayAwakePreferenceController.SETTING_VALUE_ON); + mController.mSettingsObserver.onChange(false, + Settings.Global.getUriFor(Settings.Global.STAY_ON_WHILE_PLUGGED_IN)); + verify(mPreference).setChecked(true); + } + + @Test + public void observerOnChangeCalledWithDifferentUri_preferenceShouldNotBeUpdated() { + Settings.System.putInt(mContentResolver, Settings.Global.STAY_ON_WHILE_PLUGGED_IN, + StayAwakePreferenceController.SETTING_VALUE_ON); + mController.mSettingsObserver.onChange(false, null); + verify(mPreference, never()).setChecked(true); + } +} From b05a346fae92806933cbeda33aae02ecb3521fc1 Mon Sep 17 00:00:00 2001 From: Daniel Nishi Date: Tue, 12 Sep 2017 15:55:46 -0700 Subject: [PATCH 06/23] Close the load screen faster on pre-quota devices. Pre-quota devices can take an absurd time to load. By loading the screen once the volume sizes load, we can just show "calculating..." for a really long time instead of a loading screen. Change-Id: Id8ab0609c2bc19531d530c6bdf6bff89c5bfac96 Fixes: 64150148 Test: Settings Robotest --- .../deviceinfo/StorageDashboardFragment.java | 57 ++++++++---- .../StorageDashboardFragmentTest.java | 87 +++++++++++++++++++ 2 files changed, 128 insertions(+), 16 deletions(-) diff --git a/src/com/android/settings/deviceinfo/StorageDashboardFragment.java b/src/com/android/settings/deviceinfo/StorageDashboardFragment.java index dd0db9a2335..a63247ce473 100644 --- a/src/com/android/settings/deviceinfo/StorageDashboardFragment.java +++ b/src/com/android/settings/deviceinfo/StorageDashboardFragment.java @@ -105,9 +105,7 @@ public class StorageDashboardFragment extends DashboardFragment public void onViewCreated(View v, Bundle savedInstanceState) { super.onViewCreated(v, savedInstanceState); initializeCacheProvider(); - if (mAppsResult == null || mStorageInfo == null) { - setLoading(true, false); - } + maybeSetLoading(isQuotaSupported()); } @Override @@ -125,21 +123,23 @@ public class StorageDashboardFragment extends DashboardFragment } private void onReceivedSizes() { - if (mStorageInfo == null || mAppsResult == null) { - return; + if (mStorageInfo != null) { + long privateUsedBytes = mStorageInfo.totalBytes - mStorageInfo.freeBytes; + mSummaryController.updateBytes(privateUsedBytes, mStorageInfo.totalBytes); + mPreferenceController.setVolume(mVolume); + mPreferenceController.setUsedSize(privateUsedBytes); + mPreferenceController.setTotalSize(mStorageInfo.totalBytes); + for (int i = 0, size = mSecondaryUsers.size(); i < size; i++) { + AbstractPreferenceController controller = mSecondaryUsers.get(i); + if (controller instanceof SecondaryUserController) { + SecondaryUserController userController = (SecondaryUserController) controller; + userController.setTotalSize(mStorageInfo.totalBytes); + } + } } - long privateUsedBytes = mStorageInfo.totalBytes - mStorageInfo.freeBytes; - mSummaryController.updateBytes(privateUsedBytes, mStorageInfo.totalBytes); - mPreferenceController.setVolume(mVolume); - mPreferenceController.setUsedSize(privateUsedBytes); - mPreferenceController.setTotalSize(mStorageInfo.totalBytes); - for (int i = 0, size = mSecondaryUsers.size(); i < size; i++) { - AbstractPreferenceController controller = mSecondaryUsers.get(i); - if (controller instanceof SecondaryUserController) { - SecondaryUserController userController = (SecondaryUserController) controller; - userController.setTotalSize(mStorageInfo.totalBytes); - } + if (mAppsResult == null) { + return; } mPreferenceController.onLoadFinished(mAppsResult, UserHandle.myUserId()); @@ -272,11 +272,21 @@ public class StorageDashboardFragment extends DashboardFragment return mStorageInfo; } + @VisibleForTesting + public void setPrivateStorageInfo(PrivateStorageInfo info) { + mStorageInfo = info; + } + @VisibleForTesting public SparseArray getAppsStorageResult() { return mAppsResult; } + @VisibleForTesting + public void setAppsStorageResult(SparseArray info) { + mAppsResult = info; + } + @VisibleForTesting public void initializeCachedValues() { PrivateStorageInfo info = mCachedStorageValuesHelper.getCachedPrivateStorageInfo(); @@ -290,6 +300,16 @@ public class StorageDashboardFragment extends DashboardFragment mAppsResult = loaderResult; } + @VisibleForTesting + public void maybeSetLoading(boolean isQuotaSupported) { + // If we have fast stats, we load until both have loaded. + // If we have slow stats, we load when we get the total volume sizes. + if ((isQuotaSupported && (mStorageInfo == null || mAppsResult == null)) || + (!isQuotaSupported && mStorageInfo == null)) { + setLoading(true /* loading */, false /* animate */); + } + } + private void initializeCacheProvider() { mCachedStorageValuesHelper = new CachedStorageValuesHelper(getContext(), UserHandle.myUserId()); @@ -304,6 +324,11 @@ public class StorageDashboardFragment extends DashboardFragment } } + private boolean isQuotaSupported() { + final StorageStatsManager stats = getActivity().getSystemService(StorageStatsManager.class); + return stats.isQuotaSupported(mVolume.fsUuid); + } + /** * IconLoaderCallbacks exists because StorageDashboardFragment already implements * LoaderCallbacks for a different type. diff --git a/tests/robotests/src/com/android/settings/deviceinfo/StorageDashboardFragmentTest.java b/tests/robotests/src/com/android/settings/deviceinfo/StorageDashboardFragmentTest.java index a87f563cc9e..b1296e5f38b 100644 --- a/tests/robotests/src/com/android/settings/deviceinfo/StorageDashboardFragmentTest.java +++ b/tests/robotests/src/com/android/settings/deviceinfo/StorageDashboardFragmentTest.java @@ -18,7 +18,11 @@ package com.android.settings.deviceinfo; import static com.google.common.truth.Truth.assertThat; +import static org.mockito.ArgumentMatchers.anyInt; +import static org.mockito.Mockito.RETURNS_DEEP_STUBS; import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.never; +import static org.mockito.Mockito.spy; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; @@ -26,6 +30,7 @@ import android.app.Activity; import android.os.storage.StorageManager; import android.provider.SearchIndexableResource; import android.util.SparseArray; +import android.view.View; import com.android.settings.deviceinfo.storage.CachedStorageValuesHelper; import com.android.settings.deviceinfo.storage.StorageAsyncLoader; @@ -33,6 +38,7 @@ import com.android.settings.testutils.SettingsRobolectricTestRunner; import com.android.settings.TestConfig; import com.android.settingslib.deviceinfo.PrivateStorageInfo; import com.android.settingslib.drawer.CategoryKey; +import android.support.v7.widget.RecyclerView; import org.junit.Before; import org.junit.Test; @@ -114,6 +120,87 @@ public class StorageDashboardFragmentTest { assertThat(mFragment.getAppsStorageResult()).isNull(); } + @Test + public void test_loadWhenQuotaOffIfVolumeInfoNotLoaded() { + View fakeView = mock(View.class, RETURNS_DEEP_STUBS); + RecyclerView fakeRecyclerView = mock(RecyclerView.class, RETURNS_DEEP_STUBS); + when(fakeView.findViewById(anyInt())).thenReturn(fakeView); + mFragment = spy(mFragment); + when(mFragment.getView()).thenReturn(fakeView); + when(mFragment.getListView()).thenReturn(fakeRecyclerView); + + mFragment.maybeSetLoading(false); + + verify(mFragment).setLoading(true, false); + } + + @Test + public void test_dontLoadWhenQuotaOffIfVolumeInfoNotLoaded() { + View fakeView = mock(View.class, RETURNS_DEEP_STUBS); + RecyclerView fakeRecyclerView = mock(RecyclerView.class, RETURNS_DEEP_STUBS); + when(fakeView.findViewById(anyInt())).thenReturn(fakeView); + mFragment = spy(mFragment); + when(mFragment.getView()).thenReturn(fakeView); + when(mFragment.getListView()).thenReturn(fakeRecyclerView); + + PrivateStorageInfo info = new PrivateStorageInfo(0, 0); + mFragment.setPrivateStorageInfo(info); + + mFragment.maybeSetLoading(false); + + verify(mFragment, never()).setLoading(true, false); + } + + @Test + public void test_loadWhenQuotaOnAndVolumeInfoLoadedButAppsMissing() { + View fakeView = mock(View.class, RETURNS_DEEP_STUBS); + RecyclerView fakeRecyclerView = mock(RecyclerView.class, RETURNS_DEEP_STUBS); + when(fakeView.findViewById(anyInt())).thenReturn(fakeView); + mFragment = spy(mFragment); + when(mFragment.getView()).thenReturn(fakeView); + when(mFragment.getListView()).thenReturn(fakeRecyclerView); + + PrivateStorageInfo info = new PrivateStorageInfo(0, 0); + mFragment.setPrivateStorageInfo(info); + + mFragment.maybeSetLoading(true); + + verify(mFragment).setLoading(true, false); + } + + @Test + public void test_loadWhenQuotaOnAndAppsLoadedButVolumeInfoMissing() { + View fakeView = mock(View.class, RETURNS_DEEP_STUBS); + RecyclerView fakeRecyclerView = mock(RecyclerView.class, RETURNS_DEEP_STUBS); + when(fakeView.findViewById(anyInt())).thenReturn(fakeView); + mFragment = spy(mFragment); + when(mFragment.getView()).thenReturn(fakeView); + when(mFragment.getListView()).thenReturn(fakeRecyclerView); + mFragment.setAppsStorageResult(new SparseArray<>()); + + mFragment.maybeSetLoading(true); + + verify(mFragment).setLoading(true, false); + } + + @Test + public void test_dontLoadWhenQuotaOnAndAllLoaded() { + View fakeView = mock(View.class, RETURNS_DEEP_STUBS); + RecyclerView fakeRecyclerView = mock(RecyclerView.class, RETURNS_DEEP_STUBS); + when(fakeView.findViewById(anyInt())).thenReturn(fakeView); + mFragment = spy(mFragment); + when(mFragment.getView()).thenReturn(fakeView); + when(mFragment.getListView()).thenReturn(fakeRecyclerView); + + mFragment.setAppsStorageResult(new SparseArray<>()); + PrivateStorageInfo storageInfo = new PrivateStorageInfo(0, 0); + mFragment.setPrivateStorageInfo(storageInfo); + + mFragment.maybeSetLoading(true); + + verify(mFragment, never()).setLoading(true, false); + } + @Test public void testSearchIndexProvider_shouldIndexResource() { final List indexRes = From d040ecd4999dfdd54b0736a80d6d0052fc63a0c6 Mon Sep 17 00:00:00 2001 From: Fan Zhang Date: Thu, 17 Aug 2017 16:13:20 -0700 Subject: [PATCH 07/23] Integrate with SettingsIntelligence Bug: 64691432 Test: robotests Change-Id: Idd20fd66f0289e0d0178bac02b1059c5554673f4 --- AndroidManifest.xml | 1 + .../settings/dashboard/DashboardSummary.java | 11 +- .../SuggestionControllerMixin.java | 144 ++++++++++++++++++ .../suggestions/ISuggestionService.java | 23 +++ .../settings/suggestions/Suggestion.java | 20 +++ .../SuggestionControllerMixinTest.java | 73 +++++++++ 6 files changed, 270 insertions(+), 2 deletions(-) create mode 100644 src/com/android/settings/dashboard/suggestions/SuggestionControllerMixin.java create mode 100644 tests/robotests/src/android/service/settings/suggestions/ISuggestionService.java create mode 100644 tests/robotests/src/android/service/settings/suggestions/Suggestion.java create mode 100644 tests/robotests/src/com/android/settings/dashboard/suggestions/SuggestionControllerMixinTest.java diff --git a/AndroidManifest.xml b/AndroidManifest.xml index 46c6490d880..44555db8b0a 100644 --- a/AndroidManifest.xml +++ b/AndroidManifest.xml @@ -72,6 +72,7 @@ + diff --git a/src/com/android/settings/dashboard/DashboardSummary.java b/src/com/android/settings/dashboard/DashboardSummary.java index be5fbdf15f7..6caf052bc60 100644 --- a/src/com/android/settings/dashboard/DashboardSummary.java +++ b/src/com/android/settings/dashboard/DashboardSummary.java @@ -38,6 +38,7 @@ import com.android.settings.dashboard.conditional.FocusRecyclerView; import com.android.settings.dashboard.conditional.FocusRecyclerView.FocusListener; import com.android.settings.dashboard.suggestions.SuggestionDismissController; import com.android.settings.dashboard.suggestions.SuggestionFeatureProvider; +import com.android.settings.dashboard.suggestions.SuggestionControllerMixin; import com.android.settings.dashboard.suggestions.SuggestionsChecks; import com.android.settings.overlay.FeatureFactory; import com.android.settings.widget.ActionBarShadowController; @@ -60,7 +61,6 @@ public class DashboardSummary extends InstrumentedFragment private static final int MAX_WAIT_MILLIS = 700; private static final String TAG = "DashboardSummary"; - private static final String EXTRA_SCROLL_POSITION = "scroll_position"; private final Handler mHandler = new Handler(); @@ -72,6 +72,7 @@ public class DashboardSummary extends InstrumentedFragment private SuggestionParser mSuggestionParser; private LinearLayoutManager mLayoutManager; private SuggestionsChecks mSuggestionsChecks; + private SuggestionControllerMixin mSuggestionControllerMixin; private DashboardFeatureProvider mDashboardFeatureProvider; private SuggestionFeatureProvider mSuggestionFeatureProvider; private boolean isOnCategoriesChangedCalled; @@ -82,6 +83,12 @@ public class DashboardSummary extends InstrumentedFragment return MetricsEvent.DASHBOARD_SUMMARY; } + @Override + public void onAttach(Context context) { + super.onAttach(context); + mSuggestionControllerMixin = new SuggestionControllerMixin(context, getLifecycle()); + } + @Override public void onCreate(Bundle savedInstanceState) { long startTime = System.currentTimeMillis(); @@ -196,7 +203,7 @@ public class DashboardSummary extends InstrumentedFragment mDashboard.setHasFixedSize(true); mDashboard.setListener(this); mAdapter = new DashboardAdapter(getContext(), bundle, mConditionManager.getConditions(), - mSuggestionParser, this /* SuggestionDismissController.Callback */); + mSuggestionParser, this /* SuggestionDismissController.Callback */); mDashboard.setAdapter(mAdapter); mDashboard.setItemAnimator(new DashboardItemAnimator()); mSummaryLoader.setSummaryConsumer(mAdapter); diff --git a/src/com/android/settings/dashboard/suggestions/SuggestionControllerMixin.java b/src/com/android/settings/dashboard/suggestions/SuggestionControllerMixin.java new file mode 100644 index 00000000000..0142203499e --- /dev/null +++ b/src/com/android/settings/dashboard/suggestions/SuggestionControllerMixin.java @@ -0,0 +1,144 @@ +/* + * 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.dashboard.suggestions; + +import android.annotation.Nullable; +import android.content.ComponentName; +import android.content.Context; +import android.content.Intent; +import android.content.ServiceConnection; +import android.os.IBinder; +import android.os.RemoteException; +import android.service.settings.suggestions.ISuggestionService; +import android.service.settings.suggestions.Suggestion; +import android.support.annotation.VisibleForTesting; +import android.util.Log; + +import com.android.settingslib.core.lifecycle.Lifecycle; +import com.android.settingslib.core.lifecycle.LifecycleObserver; +import com.android.settingslib.core.lifecycle.events.OnStart; +import com.android.settingslib.core.lifecycle.events.OnStop; + +import java.util.List; + +/** + * Manages IPC communication to SettingsIntelligence for suggestion related services. + */ +public class SuggestionControllerMixin implements LifecycleObserver, OnStart, OnStop { + + private static final String TAG = "SuggestionCtrlMixin"; + private static final boolean DEBUG = false; + + private final Context mContext; + private final Intent mServiceIntent; + private final ServiceConnection mServiceConnection; + + private ISuggestionService mRemoteService; + + public SuggestionControllerMixin(Context context, Lifecycle lifecycle) { + mContext = context.getApplicationContext(); + mServiceIntent = new Intent().setComponent( + new ComponentName( + "com.android.settings.intelligence", + "com.android.settings.intelligence.suggestions.SuggestionService")); + mServiceConnection = createServiceConnection(); + if (lifecycle != null) { + lifecycle.addObserver(this); + } + } + + @Override + public void onStart() { + if (!isEnabled()) { + Log.w(TAG, "Feature not enabled, skipping"); + return; + } + mContext.bindServiceAsUser(mServiceIntent, mServiceConnection, Context.BIND_AUTO_CREATE, + android.os.Process.myUserHandle()); + } + + @Override + public void onStop() { + if (mRemoteService != null) { + mRemoteService = null; + mContext.unbindService(mServiceConnection); + } + } + + public boolean isEnabled() { + // TODO: Set up feature flag + return true; + } + + /** + * Get setting suggestions. + */ + @Nullable + public List getSuggestions() { + if (!isReady()) { + return null; + } + try { + return mRemoteService.getSuggestions(); + } catch (RemoteException e) { + Log.w(TAG, "Error when calling getSuggestion()", e); + return null; + } + } + + /** + * Whether or not the manager is ready + */ + private boolean isReady() { + return mRemoteService != null; + } + + @VisibleForTesting + void onServiceConnected() { + // TODO: Call API to get data from a loader instead of in current thread. + final List data = getSuggestions(); + Log.d(TAG, "data size " + (data == null ? 0 : data.size())); + } + + private void onServiceDisconnected() { + + } + + /** + * Create a new {@link ServiceConnection} object to handle service connect/disconnect event. + */ + private ServiceConnection createServiceConnection() { + return new ServiceConnection() { + + @Override + public void onServiceConnected(ComponentName name, IBinder service) { + if (DEBUG) { + Log.d(TAG, "Service is connected"); + } + mRemoteService = ISuggestionService.Stub.asInterface(service); + SuggestionControllerMixin.this.onServiceConnected(); + } + + @Override + public void onServiceDisconnected(ComponentName name) { + mRemoteService = null; + SuggestionControllerMixin.this.onServiceDisconnected(); + } + }; + } + +} diff --git a/tests/robotests/src/android/service/settings/suggestions/ISuggestionService.java b/tests/robotests/src/android/service/settings/suggestions/ISuggestionService.java new file mode 100644 index 00000000000..f4f5a519bd0 --- /dev/null +++ b/tests/robotests/src/android/service/settings/suggestions/ISuggestionService.java @@ -0,0 +1,23 @@ +/* + * 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 android.service.settings.suggestions; + +import java.util.List; + +public interface ISuggestionService { + List getSuggestions(); +} diff --git a/tests/robotests/src/android/service/settings/suggestions/Suggestion.java b/tests/robotests/src/android/service/settings/suggestions/Suggestion.java new file mode 100644 index 00000000000..df7a8aed962 --- /dev/null +++ b/tests/robotests/src/android/service/settings/suggestions/Suggestion.java @@ -0,0 +1,20 @@ +/* + * 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 android.service.settings.suggestions; + +public class Suggestion { +} diff --git a/tests/robotests/src/com/android/settings/dashboard/suggestions/SuggestionControllerMixinTest.java b/tests/robotests/src/com/android/settings/dashboard/suggestions/SuggestionControllerMixinTest.java new file mode 100644 index 00000000000..10611846bc2 --- /dev/null +++ b/tests/robotests/src/com/android/settings/dashboard/suggestions/SuggestionControllerMixinTest.java @@ -0,0 +1,73 @@ +/* + * 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.dashboard.suggestions; + +import static com.google.common.truth.Truth.assertThat; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.when; + +import android.content.Context; +import android.os.RemoteException; +import android.service.settings.suggestions.ISuggestionService; + +import com.android.settings.TestConfig; +import com.android.settings.testutils.SettingsRobolectricTestRunner; +import com.android.settingslib.core.lifecycle.Lifecycle; + +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.util.ReflectionHelpers; + +@RunWith(SettingsRobolectricTestRunner.class) +@Config(manifest = TestConfig.MANIFEST_PATH, sdk = TestConfig.SDK_VERSION) +public class SuggestionControllerMixinTest { + + @Mock + private Context mContext; + @Mock + private ISuggestionService mRemoteService; + private Lifecycle mLifecycle; + private SuggestionControllerMixin mMixin; + + + @Before + public void setUp() { + MockitoAnnotations.initMocks(this); + mLifecycle = new Lifecycle(); + when(mContext.getApplicationContext()).thenReturn(mContext); + } + + @Test + public void verifyIsEnabled() { + mMixin = new SuggestionControllerMixin(mContext, mLifecycle); + assertThat(mMixin.isEnabled()).isTrue(); + } + + @Test + public void onServiceConnected_shouldGetSuggestion() { + mMixin = new SuggestionControllerMixin(mContext, mLifecycle); + ReflectionHelpers.setField(mMixin, "mRemoteService", mRemoteService); + mMixin.onServiceConnected(); + + verify(mRemoteService).getSuggestions(); + } + +} From 049d515dc47f6d2b750eee0451c5751affb919db Mon Sep 17 00:00:00 2001 From: Sundeep Ghuman Date: Mon, 28 Aug 2017 17:20:02 -0700 Subject: [PATCH 08/23] Separate multiple DNS addresses with newlines. Bug: b/65037256 Bug: 65037256 Test: make -j40 RunSettingsRoboTests Merged-In: I676b5de60477f7c905b08b8bb361104e5f1e05b9 Merged-In: I61bcfc20d43133c12fb8fe78d7bd968af1ee59eb Change-Id: I4b0709648f8e236177ea73338cfb0d42a5971c06 (cherry picked from commit 2716e841be8e8bda36c451e1ba9651b37eead560) --- .../settings/wifi/details/WifiDetailPreferenceController.java | 2 +- .../wifi/details/WifiDetailPreferenceControllerTest.java | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/com/android/settings/wifi/details/WifiDetailPreferenceController.java b/src/com/android/settings/wifi/details/WifiDetailPreferenceController.java index f3db5e51d98..115535b4136 100644 --- a/src/com/android/settings/wifi/details/WifiDetailPreferenceController.java +++ b/src/com/android/settings/wifi/details/WifiDetailPreferenceController.java @@ -419,7 +419,7 @@ public class WifiDetailPreferenceController extends PreferenceController impleme String dnsServers = mLinkProperties.getDnsServers().stream() .filter(Inet4Address.class::isInstance) .map(InetAddress::getHostAddress) - .collect(Collectors.joining(",")); + .collect(Collectors.joining("\n")); // Update UI. updatePreference(mIpAddressPref, ipv4Address); diff --git a/tests/robotests/src/com/android/settings/wifi/details/WifiDetailPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/wifi/details/WifiDetailPreferenceControllerTest.java index 2aa338c2004..5097595835f 100644 --- a/tests/robotests/src/com/android/settings/wifi/details/WifiDetailPreferenceControllerTest.java +++ b/tests/robotests/src/com/android/settings/wifi/details/WifiDetailPreferenceControllerTest.java @@ -405,7 +405,7 @@ public class WifiDetailPreferenceControllerTest { displayAndResume(); - verify(mockDnsPref).setDetailText("8.8.4.4,8.8.8.8"); + verify(mockDnsPref).setDetailText("8.8.4.4\n8.8.8.8"); } @Test @@ -517,7 +517,7 @@ public class WifiDetailPreferenceControllerTest { lp.addDnsServer(Constants.IPV4_DNS2); updateLinkProperties(lp); inOrder.verify(mockDnsPref).setDetailText( - Constants.IPV4_DNS1.getHostAddress() + "," + + Constants.IPV4_DNS1.getHostAddress() + "\n" + Constants.IPV4_DNS2.getHostAddress()); inOrder.verify(mockDnsPref).setVisible(true); } From 5b206aec69f4965ce59e6e908abf15f1bcd6893e Mon Sep 17 00:00:00 2001 From: Erik Kline Date: Wed, 6 Sep 2017 18:05:48 +0900 Subject: [PATCH 09/23] Include IPv6 DNS servers in wifi details Test: as follows - built - flashed - booted - export ROBOTEST_FILTER=WifiDetailPreferenceControllerTest \ make -j RunSettingsRoboTests RunSettingsRoboTests: RunSettingsRoboTests: Time: 19.821 RunSettingsRoboTests: RunSettingsRoboTests: OK (37 tests) RunSettingsRoboTests: - make -j RunSettingsRoboTests RunSettingsRoboTests: ........................... RunSettingsRoboTests: Time: 424.847 RunSettingsRoboTests: RunSettingsRoboTests: OK (2250 tests) RunSettingsRoboTests: Bug: 65037256 Bug: 65467586 Merged-In: If15181d557e9abce75111a6e1fff4e12586d7dbc Merged-In: I55fbd611fee9f17215412a76b480cdee96f62b32 Change-Id: Icd3d09aa35c04101c41e2521b48e64f28f69ae29 (cherry picked from commit 9adc5887490953c6d239a634d6ebca4cd3081dc6) --- .../wifi/details/WifiDetailPreferenceController.java | 3 +-- .../details/WifiDetailPreferenceControllerTest.java | 10 ++++++++-- 2 files changed, 9 insertions(+), 4 deletions(-) diff --git a/src/com/android/settings/wifi/details/WifiDetailPreferenceController.java b/src/com/android/settings/wifi/details/WifiDetailPreferenceController.java index 115535b4136..23e547aea0e 100644 --- a/src/com/android/settings/wifi/details/WifiDetailPreferenceController.java +++ b/src/com/android/settings/wifi/details/WifiDetailPreferenceController.java @@ -415,9 +415,8 @@ public class WifiDetailPreferenceController extends PreferenceController impleme } } - // Find IPv4 DNS addresses. + // Find all (IPv4 and IPv6) DNS addresses. String dnsServers = mLinkProperties.getDnsServers().stream() - .filter(Inet4Address.class::isInstance) .map(InetAddress::getHostAddress) .collect(Collectors.joining("\n")); diff --git a/tests/robotests/src/com/android/settings/wifi/details/WifiDetailPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/wifi/details/WifiDetailPreferenceControllerTest.java index 5097595835f..5c1b103ba08 100644 --- a/tests/robotests/src/com/android/settings/wifi/details/WifiDetailPreferenceControllerTest.java +++ b/tests/robotests/src/com/android/settings/wifi/details/WifiDetailPreferenceControllerTest.java @@ -402,10 +402,14 @@ public class WifiDetailPreferenceControllerTest { public void dnsServersPref_shouldHaveDetailTextSet() throws UnknownHostException { mLinkProperties.addDnsServer(InetAddress.getByAddress(new byte[]{8,8,4,4})); mLinkProperties.addDnsServer(InetAddress.getByAddress(new byte[]{8,8,8,8})); + mLinkProperties.addDnsServer(Constants.IPV6_DNS); displayAndResume(); - verify(mockDnsPref).setDetailText("8.8.4.4\n8.8.8.8"); + verify(mockDnsPref).setDetailText( + "8.8.4.4\n" + + "8.8.8.8\n" + + Constants.IPV6_DNS.getHostAddress()); } @Test @@ -511,12 +515,14 @@ public class WifiDetailPreferenceControllerTest { lp.addDnsServer(Constants.IPV6_DNS); updateLinkProperties(lp); - inOrder.verify(mockDnsPref, never()).setVisible(true); + inOrder.verify(mockDnsPref).setDetailText(Constants.IPV6_DNS.getHostAddress()); + inOrder.verify(mockDnsPref).setVisible(true); lp.addDnsServer(Constants.IPV4_DNS1); lp.addDnsServer(Constants.IPV4_DNS2); updateLinkProperties(lp); inOrder.verify(mockDnsPref).setDetailText( + Constants.IPV6_DNS.getHostAddress() + "\n" + Constants.IPV4_DNS1.getHostAddress() + "\n" + Constants.IPV4_DNS2.getHostAddress()); inOrder.verify(mockDnsPref).setVisible(true); From 7fe6f50bf7df6cf638903b0e16fbe085a2afac08 Mon Sep 17 00:00:00 2001 From: Soroosh Mariooryad Date: Fri, 11 Aug 2017 00:04:37 -0700 Subject: [PATCH 10/23] Log smart settings suggestion enabled/disabled state for A/B experiments Test: RunSettingsRoboTests Bug: 64121058 Change-Id: I0cf4b4a0e8470cd40d38e8fe937cfb5f3e96f380 Merged-In: Iadfa575b9a21caecb515b9975d388ee0d0480c11 --- .../settings/dashboard/DashboardAdapter.java | 61 +++-- .../suggestions/SuggestionAdapter.java | 18 +- .../SuggestionFeatureProviderImpl.java | 13 +- .../suggestions/SuggestionLogHelper.java | 29 +++ .../dashboard/DashboardAdapterTest.java | 223 ++++++++++++------ .../SuggestionFeatureProviderImplTest.java | 17 +- .../suggestions/SuggestionLogHelperTest.java | 41 ++++ 7 files changed, 294 insertions(+), 108 deletions(-) create mode 100644 src/com/android/settings/dashboard/suggestions/SuggestionLogHelper.java create mode 100644 tests/robotests/src/com/android/settings/dashboard/suggestions/SuggestionLogHelperTest.java diff --git a/src/com/android/settings/dashboard/DashboardAdapter.java b/src/com/android/settings/dashboard/DashboardAdapter.java index c06a58fe24c..6fee28bee08 100644 --- a/src/com/android/settings/dashboard/DashboardAdapter.java +++ b/src/com/android/settings/dashboard/DashboardAdapter.java @@ -30,6 +30,7 @@ import android.support.v7.widget.RecyclerView; import android.text.TextUtils; import android.util.ArrayMap; import android.util.Log; +import android.util.Pair; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; @@ -47,6 +48,7 @@ import com.android.settings.dashboard.conditional.ConditionAdapter; import com.android.settings.dashboard.suggestions.SuggestionAdapter; import com.android.settings.dashboard.suggestions.SuggestionDismissController; import com.android.settings.dashboard.suggestions.SuggestionFeatureProvider; +import com.android.settings.dashboard.suggestions.SuggestionLogHelper; import com.android.settings.overlay.FeatureFactory; import com.android.settingslib.Utils; import com.android.settingslib.drawer.DashboardCategory; @@ -129,7 +131,7 @@ public class DashboardAdapter extends RecyclerView.Adapter 0 && data.conditionCount > 0 - && curMode != DashboardData.HEADER_MODE_SUGGESTION_EXPANDED - ? DashboardData.HEADER_MODE_SUGGESTION_EXPANDED - : DashboardData.HEADER_MODE_FULLY_EXPANDED; + && curMode != DashboardData.HEADER_MODE_SUGGESTION_EXPANDED + ? DashboardData.HEADER_MODE_SUGGESTION_EXPANDED + : DashboardData.HEADER_MODE_FULLY_EXPANDED; final boolean moreSuggestions = data.hiddenSuggestionCount > 0; final boolean hasConditions = data.conditionCount > 0; if (data.conditionCount > 0) { @@ -377,22 +381,22 @@ public class DashboardAdapter extends RecyclerView.Adapter 0) { holder.summary.setText(mContext.getResources().getQuantityString( - R.plurals.suggestions_collapsed_summary, - data.hiddenSuggestionCount, data.hiddenSuggestionCount)); + R.plurals.suggestions_collapsed_summary, + data.hiddenSuggestionCount, data.hiddenSuggestionCount)); } else { holder.title.setText(mContext.getResources().getQuantityString( - R.plurals.suggestions_collapsed_title, - data.hiddenSuggestionCount, data.hiddenSuggestionCount)); + R.plurals.suggestions_collapsed_title, + data.hiddenSuggestionCount, data.hiddenSuggestionCount)); holder.title.setTextColor(Color.BLACK); holder.summary.setText(null); } } else if (curMode == DashboardData.HEADER_MODE_DEFAULT) { if (data.conditionCount > 0) { holder.summary.setText(mContext.getString( - R.string.suggestions_summary, data.hiddenSuggestionCount)); + R.string.suggestions_summary, data.hiddenSuggestionCount)); } else { holder.title.setText(mContext.getString( - R.string.suggestions_more_title, data.hiddenSuggestionCount)); + R.string.suggestions_more_title, data.hiddenSuggestionCount)); holder.title.setTextColor(Color.BLACK); holder.summary.setText(null); } @@ -400,7 +404,7 @@ public class DashboardAdapter extends RecyclerView.Adapter 1) { holder.summary.setTextColor(Utils.getColorAccent(mContext)); holder.summary.setText( - mContext.getString(R.string.condition_summary, data.conditionCount)); + mContext.getString(R.string.condition_summary, data.conditionCount)); } else { holder.summary.setText(null); } @@ -413,16 +417,16 @@ public class DashboardAdapter extends RecyclerView.Adapter { - if (moreSuggestions ) { + if (moreSuggestions) { logSuggestions(); } else if (hasConditions) { mMetricsFeatureProvider.action(mContext, - MetricsEvent.ACTION_SETTINGS_CONDITION_EXPAND, true); + MetricsEvent.ACTION_SETTINGS_CONDITION_EXPAND, true); } DashboardData prevData = mDashboardData; final boolean wasCollapsed = curMode == DashboardData.HEADER_MODE_COLLAPSED; mDashboardData = new DashboardData.Builder(prevData) - .setSuggestionConditionMode(nextMode).build(); + .setSuggestionConditionMode(nextMode).build(); notifyDashboardDataChanged(prevData); if (wasCollapsed) { mRecyclerView.scrollToPosition(SUGGESTION_CONDITION_HEADER_POSITION); @@ -439,13 +443,13 @@ public class DashboardAdapter extends RecyclerView.Adapter 0) { mSuggestionAdapter = new SuggestionAdapter(mContext, (List) - mDashboardData.getItemEntityByPosition(position), mSuggestionsShownLogged); + mDashboardData.getItemEntityByPosition(position), mSuggestionsShownLogged); mSuggestionDismissHandler = new SuggestionDismissController(mContext, - holder.data, mSuggestionParser, mCallback); + holder.data, mSuggestionParser, mCallback); holder.data.setAdapter(mSuggestionAdapter); } else { ConditionAdapter adapter = new ConditionAdapter(mContext, - (List) mDashboardData.getItemEntityByPosition(position), + (List) mDashboardData.getItemEntityByPosition(position), mDashboardData.getSuggestionConditionMode()); adapter.addDismissHandling(holder.data); holder.data.setAdapter(adapter); @@ -507,7 +511,7 @@ public class DashboardAdapter extends RecyclerView.Adapter icons, ViewGroup parent) { @@ -519,13 +523,18 @@ public class DashboardAdapter extends RecyclerView.Adapter[] getSuggestionTaggedData() { + return SuggestionLogHelper.getSuggestionTaggedData( + mSuggestionFeatureProvider.isSmartSuggestionEnabled(mContext)); + } + public static class IconCache { private final Context mContext; private final ArrayMap mMap = new ArrayMap<>(); diff --git a/src/com/android/settings/dashboard/suggestions/SuggestionAdapter.java b/src/com/android/settings/dashboard/suggestions/SuggestionAdapter.java index 2c9da4124b1..3815211c475 100644 --- a/src/com/android/settings/dashboard/suggestions/SuggestionAdapter.java +++ b/src/com/android/settings/dashboard/suggestions/SuggestionAdapter.java @@ -18,6 +18,7 @@ package com.android.settings.dashboard.suggestions; import android.content.Context; import android.support.v7.widget.RecyclerView; import android.text.TextUtils; +import android.util.Pair; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; @@ -67,11 +68,12 @@ public class SuggestionAdapter extends RecyclerView.Adapter public void onBindViewHolder(DashboardItemHolder holder, int position) { final Tile suggestion = (Tile) mSuggestions.get(position); final String suggestionId = mSuggestionFeatureProvider.getSuggestionIdentifier( - mContext, suggestion); + mContext, suggestion); // This is for cases when a suggestion is dismissed and the next one comes to view if (!mSuggestionsShownLogged.contains(suggestionId)) { mMetricsFeatureProvider.action( - mContext, MetricsEvent.ACTION_SHOW_SETTINGS_SUGGESTION, suggestionId); + mContext, MetricsEvent.ACTION_SHOW_SETTINGS_SUGGESTION, suggestionId, + getSuggestionTaggedData()); mSuggestionsShownLogged.add(suggestionId); } if (suggestion.remoteViews != null) { @@ -102,9 +104,11 @@ public class SuggestionAdapter extends RecyclerView.Adapter // set the item view to disabled to remove any touch effects holder.itemView.setEnabled(false); } + clickHandler.setOnClickListener(v -> { mMetricsFeatureProvider.action(mContext, - MetricsEvent.ACTION_SETTINGS_SUGGESTION, suggestionId); + MetricsEvent.ACTION_SETTINGS_SUGGESTION, suggestionId, + getSuggestionTaggedData()); ((SettingsActivity) mContext).startSuggestion(suggestion.intent); }); } @@ -129,7 +133,7 @@ public class SuggestionAdapter extends RecyclerView.Adapter public Tile getSuggestion(int position) { final long itemId = getItemId(position); - for (Tile tile: mSuggestions) { + for (Tile tile : mSuggestions) { if (Objects.hash(tile.title) == itemId) { return tile; } @@ -141,4 +145,10 @@ public class SuggestionAdapter extends RecyclerView.Adapter mSuggestions.remove(suggestion); notifyDataSetChanged(); } + + private Pair[] getSuggestionTaggedData() { + return SuggestionLogHelper.getSuggestionTaggedData( + mSuggestionFeatureProvider.isSmartSuggestionEnabled(mContext)); + } + } diff --git a/src/com/android/settings/dashboard/suggestions/SuggestionFeatureProviderImpl.java b/src/com/android/settings/dashboard/suggestions/SuggestionFeatureProviderImpl.java index f8b5a8b6a60..3d40d96d4e4 100644 --- a/src/com/android/settings/dashboard/suggestions/SuggestionFeatureProviderImpl.java +++ b/src/com/android/settings/dashboard/suggestions/SuggestionFeatureProviderImpl.java @@ -26,8 +26,9 @@ import android.provider.Settings.Secure; import android.support.annotation.NonNull; import android.support.annotation.VisibleForTesting; import android.util.Log; +import android.util.Pair; -import com.android.internal.logging.nano.MetricsProto; +import com.android.internal.logging.nano.MetricsProto.MetricsEvent; import com.android.settings.Settings.AmbientDisplayPickupSuggestionActivity; import com.android.settings.Settings.AmbientDisplaySuggestionActivity; import com.android.settings.Settings.DoubleTapPowerSuggestionActivity; @@ -45,6 +46,7 @@ import com.android.settings.support.NewDeviceIntroSuggestionActivity; import com.android.settingslib.drawer.Tile; import com.android.settingslib.suggestions.SuggestionParser; +import java.util.ArrayList; import java.util.List; public class SuggestionFeatureProviderImpl implements SuggestionFeatureProvider { @@ -130,10 +132,13 @@ public class SuggestionFeatureProviderImpl implements SuggestionFeatureProvider if (parser == null || suggestion == null || context == null) { return; } - mMetricsFeatureProvider.action( - context, MetricsProto.MetricsEvent.ACTION_SETTINGS_DISMISS_SUGGESTION, - getSuggestionIdentifier(context, suggestion)); + final Pair[] taggedData = + SuggestionLogHelper.getSuggestionTaggedData(isSmartSuggestionEnabled(context)); + mMetricsFeatureProvider.action( + context, MetricsEvent.ACTION_SETTINGS_DISMISS_SUGGESTION, + getSuggestionIdentifier(context, suggestion), + taggedData); if (!parser.dismissSuggestion(suggestion)) { return; } diff --git a/src/com/android/settings/dashboard/suggestions/SuggestionLogHelper.java b/src/com/android/settings/dashboard/suggestions/SuggestionLogHelper.java new file mode 100644 index 00000000000..339392fa780 --- /dev/null +++ b/src/com/android/settings/dashboard/suggestions/SuggestionLogHelper.java @@ -0,0 +1,29 @@ +/* + * 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.dashboard.suggestions; + +import android.util.Pair; + +import com.android.internal.logging.nano.MetricsProto.MetricsEvent; + +public class SuggestionLogHelper { + + public static Pair[] getSuggestionTaggedData(boolean enabled) { + return new Pair[]{ + Pair.create( + MetricsEvent.FIELD_SETTINGS_SMART_SUGGESTIONS_ENABLED, enabled ? 1 : 0)}; + } +} diff --git a/tests/robotests/src/com/android/settings/dashboard/DashboardAdapterTest.java b/tests/robotests/src/com/android/settings/dashboard/DashboardAdapterTest.java index e00908e52b3..4b345d072d7 100644 --- a/tests/robotests/src/com/android/settings/dashboard/DashboardAdapterTest.java +++ b/tests/robotests/src/com/android/settings/dashboard/DashboardAdapterTest.java @@ -37,6 +37,7 @@ import android.graphics.drawable.Icon; import android.os.Bundle; import android.support.v7.widget.RecyclerView; import android.util.DisplayMetrics; +import android.util.Pair; import android.view.LayoutInflater; import android.view.View; import android.widget.RelativeLayout; @@ -89,6 +90,8 @@ public class DashboardAdapterTest { private ArgumentCaptor mActionCategoryCaptor = ArgumentCaptor.forClass(Integer.class); @Captor private ArgumentCaptor mActionPackageCaptor = ArgumentCaptor.forClass(String.class); + @Captor + private ArgumentCaptor mTaggedDataCaptor = ArgumentCaptor.forClass(Pair.class); private FakeFeatureFactory mFactory; private DashboardAdapter mDashboardAdapter; private DashboardAdapter.SuggestionAndConditionHeaderHolder mSuggestionHolder; @@ -123,112 +126,143 @@ public class DashboardAdapterTest { @Test public void testSuggestionsLogs_NotExpanded() { setupSuggestions(makeSuggestions("pkg1", "pkg2", "pkg3")); + verify(mFactory.metricsFeatureProvider, times(2)).action( any(Context.class), mActionCategoryCaptor.capture(), - mActionPackageCaptor.capture()); - String[] expectedPackages = new String[]{"pkg1", "pkg2"}; - Integer[] expectedActions = new Integer[]{ + mActionPackageCaptor.capture(), + mTaggedDataCaptor.capture()); + assertThat(mActionCategoryCaptor.getAllValues()).containsExactly( MetricsEvent.ACTION_SHOW_SETTINGS_SUGGESTION, - MetricsEvent.ACTION_SHOW_SETTINGS_SUGGESTION - }; - assertThat(mActionCategoryCaptor.getAllValues().toArray()).isEqualTo(expectedActions); - assertThat(mActionPackageCaptor.getAllValues().toArray()).isEqualTo(expectedPackages); + MetricsEvent.ACTION_SHOW_SETTINGS_SUGGESTION); + assertThat(mActionPackageCaptor.getAllValues()).containsExactly("pkg1", "pkg2"); + assertThat(mTaggedDataCaptor.getAllValues()).containsExactly( + Pair.create(MetricsEvent.FIELD_SETTINGS_SMART_SUGGESTIONS_ENABLED, 0), + Pair.create(MetricsEvent.FIELD_SETTINGS_SMART_SUGGESTIONS_ENABLED, 0)); } @Test public void testSuggestionsLogs_NotExpandedAndPaused() { setupSuggestions(makeSuggestions("pkg1", "pkg2", "pkg3")); + mDashboardAdapter.onPause(); + verify(mFactory.metricsFeatureProvider, times(4)).action( any(Context.class), mActionCategoryCaptor.capture(), - mActionPackageCaptor.capture()); - String[] expectedPackages = new String[]{"pkg1", "pkg2", "pkg1", "pkg2"}; - Integer[] expectedActions = new Integer[]{ + mActionPackageCaptor.capture(), + mTaggedDataCaptor.capture()); + assertThat(mActionCategoryCaptor.getAllValues()).containsExactly( MetricsEvent.ACTION_SHOW_SETTINGS_SUGGESTION, MetricsEvent.ACTION_SHOW_SETTINGS_SUGGESTION, MetricsEvent.ACTION_HIDE_SETTINGS_SUGGESTION, - MetricsEvent.ACTION_HIDE_SETTINGS_SUGGESTION}; - assertThat(mActionCategoryCaptor.getAllValues().toArray()).isEqualTo(expectedActions); - assertThat(mActionPackageCaptor.getAllValues().toArray()).isEqualTo(expectedPackages); + MetricsEvent.ACTION_HIDE_SETTINGS_SUGGESTION); + assertThat(mActionPackageCaptor.getAllValues()).containsExactly( + "pkg1", "pkg2", "pkg1", "pkg2"); + assertThat(mTaggedDataCaptor.getAllValues()).containsExactly( + Pair.create(MetricsEvent.FIELD_SETTINGS_SMART_SUGGESTIONS_ENABLED, 0), + Pair.create(MetricsEvent.FIELD_SETTINGS_SMART_SUGGESTIONS_ENABLED, 0), + Pair.create(MetricsEvent.FIELD_SETTINGS_SMART_SUGGESTIONS_ENABLED, 0), + Pair.create(MetricsEvent.FIELD_SETTINGS_SMART_SUGGESTIONS_ENABLED, 0)); } @Test public void testSuggestionsLogs_Expanded() { setupSuggestions(makeSuggestions("pkg1", "pkg2", "pkg3")); + mDashboardAdapter.onBindSuggestionConditionHeader(mSuggestionHolder, mSuggestionHeaderData); mSuggestionHolder.itemView.callOnClick(); + verify(mFactory.metricsFeatureProvider, times(3)).action( any(Context.class), mActionCategoryCaptor.capture(), - mActionPackageCaptor.capture()); - String[] expectedPackages = new String[]{"pkg1", "pkg2", "pkg3"}; - Integer[] expectedActions = new Integer[]{ + mActionPackageCaptor.capture(), + mTaggedDataCaptor.capture()); + assertThat(mActionCategoryCaptor.getAllValues()).containsExactly( MetricsEvent.ACTION_SHOW_SETTINGS_SUGGESTION, MetricsEvent.ACTION_SHOW_SETTINGS_SUGGESTION, - MetricsEvent.ACTION_SHOW_SETTINGS_SUGGESTION - }; - assertThat(mActionPackageCaptor.getAllValues().toArray()).isEqualTo(expectedPackages); - assertThat(mActionCategoryCaptor.getAllValues().toArray()).isEqualTo(expectedActions); + MetricsEvent.ACTION_SHOW_SETTINGS_SUGGESTION); + assertThat(mActionPackageCaptor.getAllValues()).containsExactly( + "pkg1", "pkg2", "pkg3"); + assertThat(mTaggedDataCaptor.getAllValues()).containsExactly( + Pair.create(MetricsEvent.FIELD_SETTINGS_SMART_SUGGESTIONS_ENABLED, 0), + Pair.create(MetricsEvent.FIELD_SETTINGS_SMART_SUGGESTIONS_ENABLED, 0), + Pair.create(MetricsEvent.FIELD_SETTINGS_SMART_SUGGESTIONS_ENABLED, 0)); } @Test public void testSuggestionsLogs_ExpandedAndPaused() { setupSuggestions(makeSuggestions("pkg1", "pkg2", "pkg3")); + mDashboardAdapter.onBindSuggestionConditionHeader(mSuggestionHolder, mSuggestionHeaderData); mSuggestionHolder.itemView.callOnClick(); mDashboardAdapter.onPause(); + verify(mFactory.metricsFeatureProvider, times(6)).action( any(Context.class), mActionCategoryCaptor.capture(), - mActionPackageCaptor.capture()); - String[] expectedPackages = new String[]{"pkg1", "pkg2", "pkg3", "pkg1", "pkg2", "pkg3"}; - Integer[] expectedActions = new Integer[]{ + mActionPackageCaptor.capture(), + mTaggedDataCaptor.capture()); + assertThat(mActionCategoryCaptor.getAllValues()).containsExactly( MetricsEvent.ACTION_SHOW_SETTINGS_SUGGESTION, MetricsEvent.ACTION_SHOW_SETTINGS_SUGGESTION, MetricsEvent.ACTION_SHOW_SETTINGS_SUGGESTION, MetricsEvent.ACTION_HIDE_SETTINGS_SUGGESTION, MetricsEvent.ACTION_HIDE_SETTINGS_SUGGESTION, - MetricsEvent.ACTION_HIDE_SETTINGS_SUGGESTION - }; - assertThat(mActionPackageCaptor.getAllValues().toArray()).isEqualTo(expectedPackages); - assertThat(mActionCategoryCaptor.getAllValues().toArray()).isEqualTo(expectedActions); + MetricsEvent.ACTION_HIDE_SETTINGS_SUGGESTION); + assertThat(mActionPackageCaptor.getAllValues()).containsExactly( + "pkg1", "pkg2", "pkg3", "pkg1", "pkg2", "pkg3"); + assertThat(mTaggedDataCaptor.getAllValues()).containsExactly( + Pair.create(MetricsEvent.FIELD_SETTINGS_SMART_SUGGESTIONS_ENABLED, 0), + Pair.create(MetricsEvent.FIELD_SETTINGS_SMART_SUGGESTIONS_ENABLED, 0), + Pair.create(MetricsEvent.FIELD_SETTINGS_SMART_SUGGESTIONS_ENABLED, 0), + Pair.create(MetricsEvent.FIELD_SETTINGS_SMART_SUGGESTIONS_ENABLED, 0), + Pair.create(MetricsEvent.FIELD_SETTINGS_SMART_SUGGESTIONS_ENABLED, 0), + Pair.create(MetricsEvent.FIELD_SETTINGS_SMART_SUGGESTIONS_ENABLED, 0)); } @Test public void testSuggestionsLogs_ExpandedAfterPause() { setupSuggestions(makeSuggestions("pkg1", "pkg2", "pkg3")); + mDashboardAdapter.onPause(); mDashboardAdapter.onBindSuggestionConditionHeader(mSuggestionHolder, mSuggestionHeaderData); mSuggestionHolder.itemView.callOnClick(); + verify(mFactory.metricsFeatureProvider, times(7)).action( any(Context.class), mActionCategoryCaptor.capture(), - mActionPackageCaptor.capture()); - String[] expectedPackages = new String[]{ - "pkg1", "pkg2", "pkg1", "pkg2", "pkg1", "pkg2", "pkg3"}; - Integer[] expectedActions = new Integer[]{ + mActionPackageCaptor.capture(), + mTaggedDataCaptor.capture()); + assertThat(mActionCategoryCaptor.getAllValues()).containsExactly( MetricsEvent.ACTION_SHOW_SETTINGS_SUGGESTION, MetricsEvent.ACTION_SHOW_SETTINGS_SUGGESTION, MetricsEvent.ACTION_HIDE_SETTINGS_SUGGESTION, MetricsEvent.ACTION_HIDE_SETTINGS_SUGGESTION, MetricsEvent.ACTION_SHOW_SETTINGS_SUGGESTION, MetricsEvent.ACTION_SHOW_SETTINGS_SUGGESTION, - MetricsEvent.ACTION_SHOW_SETTINGS_SUGGESTION - }; - assertThat(mActionPackageCaptor.getAllValues().toArray()).isEqualTo(expectedPackages); - assertThat(mActionCategoryCaptor.getAllValues().toArray()).isEqualTo(expectedActions); + MetricsEvent.ACTION_SHOW_SETTINGS_SUGGESTION); + assertThat(mActionPackageCaptor.getAllValues()).containsExactly( + "pkg1", "pkg2", "pkg1", "pkg2", "pkg1", "pkg2", "pkg3"); + assertThat(mTaggedDataCaptor.getAllValues()).containsExactly( + Pair.create(MetricsEvent.FIELD_SETTINGS_SMART_SUGGESTIONS_ENABLED, 0), + Pair.create(MetricsEvent.FIELD_SETTINGS_SMART_SUGGESTIONS_ENABLED, 0), + Pair.create(MetricsEvent.FIELD_SETTINGS_SMART_SUGGESTIONS_ENABLED, 0), + Pair.create(MetricsEvent.FIELD_SETTINGS_SMART_SUGGESTIONS_ENABLED, 0), + Pair.create(MetricsEvent.FIELD_SETTINGS_SMART_SUGGESTIONS_ENABLED, 0), + Pair.create(MetricsEvent.FIELD_SETTINGS_SMART_SUGGESTIONS_ENABLED, 0), + Pair.create(MetricsEvent.FIELD_SETTINGS_SMART_SUGGESTIONS_ENABLED, 0)); } @Test public void testSuggestionsLogs_ExpandedAfterPauseAndPausedAgain() { setupSuggestions(makeSuggestions("pkg1", "pkg2", "pkg3")); + mDashboardAdapter.onPause(); mDashboardAdapter.onBindSuggestionConditionHeader(mSuggestionHolder, mSuggestionHeaderData); mSuggestionHolder.itemView.callOnClick(); mDashboardAdapter.onPause(); + verify(mFactory.metricsFeatureProvider, times(10)).action( any(Context.class), mActionCategoryCaptor.capture(), - mActionPackageCaptor.capture()); - String[] expectedPackages = new String[]{ - "pkg1", "pkg2", "pkg1", "pkg2", "pkg1", "pkg2", "pkg3", "pkg1", "pkg2", "pkg3"}; - Integer[] expectedActions = new Integer[]{ + mActionPackageCaptor.capture(), + mTaggedDataCaptor.capture()); + assertThat(mActionCategoryCaptor.getAllValues()).containsExactly( MetricsEvent.ACTION_SHOW_SETTINGS_SUGGESTION, MetricsEvent.ACTION_SHOW_SETTINGS_SUGGESTION, MetricsEvent.ACTION_HIDE_SETTINGS_SUGGESTION, @@ -238,63 +272,82 @@ public class DashboardAdapterTest { MetricsEvent.ACTION_SHOW_SETTINGS_SUGGESTION, MetricsEvent.ACTION_HIDE_SETTINGS_SUGGESTION, MetricsEvent.ACTION_HIDE_SETTINGS_SUGGESTION, - MetricsEvent.ACTION_HIDE_SETTINGS_SUGGESTION - }; - assertThat(mActionPackageCaptor.getAllValues().toArray()).isEqualTo(expectedPackages); - assertThat(mActionCategoryCaptor.getAllValues().toArray()).isEqualTo(expectedActions); + MetricsEvent.ACTION_HIDE_SETTINGS_SUGGESTION); + assertThat(mActionPackageCaptor.getAllValues()).containsExactly( + "pkg1", "pkg2", "pkg1", "pkg2", "pkg1", "pkg2", "pkg3", "pkg1", "pkg2", "pkg3"); + assertThat(mTaggedDataCaptor.getAllValues()).containsExactly( + Pair.create(MetricsEvent.FIELD_SETTINGS_SMART_SUGGESTIONS_ENABLED, 0), + Pair.create(MetricsEvent.FIELD_SETTINGS_SMART_SUGGESTIONS_ENABLED, 0), + Pair.create(MetricsEvent.FIELD_SETTINGS_SMART_SUGGESTIONS_ENABLED, 0), + Pair.create(MetricsEvent.FIELD_SETTINGS_SMART_SUGGESTIONS_ENABLED, 0), + Pair.create(MetricsEvent.FIELD_SETTINGS_SMART_SUGGESTIONS_ENABLED, 0), + Pair.create(MetricsEvent.FIELD_SETTINGS_SMART_SUGGESTIONS_ENABLED, 0), + Pair.create(MetricsEvent.FIELD_SETTINGS_SMART_SUGGESTIONS_ENABLED, 0), + Pair.create(MetricsEvent.FIELD_SETTINGS_SMART_SUGGESTIONS_ENABLED, 0), + Pair.create(MetricsEvent.FIELD_SETTINGS_SMART_SUGGESTIONS_ENABLED, 0), + Pair.create(MetricsEvent.FIELD_SETTINGS_SMART_SUGGESTIONS_ENABLED, 0)); } @Test public void testSuggestionsLogs_ExpandedWithLessThanDefaultShown() { setupSuggestions(makeSuggestions("pkg1")); + mDashboardAdapter.onBindSuggestionConditionHeader(mSuggestionHolder, mSuggestionHeaderData); mSuggestionHolder.itemView.callOnClick(); + verify(mFactory.metricsFeatureProvider, times(1)).action( any(Context.class), mActionCategoryCaptor.capture(), - mActionPackageCaptor.capture()); - String[] expectedPackages = new String[]{"pkg1"}; - Integer[] expectedActions = new Integer[]{ - MetricsEvent.ACTION_SHOW_SETTINGS_SUGGESTION, - }; - assertThat(mActionPackageCaptor.getAllValues().toArray()).isEqualTo(expectedPackages); - assertThat(mActionCategoryCaptor.getAllValues().toArray()).isEqualTo(expectedActions); + mActionPackageCaptor.capture(), + mTaggedDataCaptor.capture()); + assertThat(mActionCategoryCaptor.getAllValues()).containsExactly( + MetricsEvent.ACTION_SHOW_SETTINGS_SUGGESTION); + assertThat(mActionPackageCaptor.getAllValues()).containsExactly("pkg1"); + assertThat(mTaggedDataCaptor.getAllValues()).containsExactly( + Pair.create(MetricsEvent.FIELD_SETTINGS_SMART_SUGGESTIONS_ENABLED, 0)); } @Test public void testSuggestionsLogs_ExpandedWithLessThanDefaultShownAndPaused() { setupSuggestions(makeSuggestions("pkg1")); + mDashboardAdapter.onBindSuggestionConditionHeader(mSuggestionHolder, mSuggestionHeaderData); mSuggestionHolder.itemView.callOnClick(); mDashboardAdapter.onPause(); + verify(mFactory.metricsFeatureProvider, times(2)).action( any(Context.class), mActionCategoryCaptor.capture(), - mActionPackageCaptor.capture()); - String[] expectedPackages = new String[]{"pkg1", "pkg1"}; - Integer[] expectedActions = new Integer[]{ + mActionPackageCaptor.capture(), + mTaggedDataCaptor.capture()); + assertThat(mActionCategoryCaptor.getAllValues()).containsExactly( MetricsEvent.ACTION_SHOW_SETTINGS_SUGGESTION, - MetricsEvent.ACTION_HIDE_SETTINGS_SUGGESTION - }; - assertThat(mActionPackageCaptor.getAllValues().toArray()).isEqualTo(expectedPackages); - assertThat(mActionCategoryCaptor.getAllValues().toArray()).isEqualTo(expectedActions); + MetricsEvent.ACTION_HIDE_SETTINGS_SUGGESTION); + assertThat(mActionPackageCaptor.getAllValues()).containsExactly("pkg1", "pkg1"); + assertThat(mTaggedDataCaptor.getAllValues()).containsExactly( + Pair.create(MetricsEvent.FIELD_SETTINGS_SMART_SUGGESTIONS_ENABLED, 0), + Pair.create(MetricsEvent.FIELD_SETTINGS_SMART_SUGGESTIONS_ENABLED, 0)); } @Test public void testSuggestionsLogs_ExpandedWithLessThanDefaultShownAfterPause() { setupSuggestions(makeSuggestions("pkg1")); + mDashboardAdapter.onPause(); mDashboardAdapter.onBindSuggestionConditionHeader(mSuggestionHolder, mSuggestionHeaderData); mSuggestionHolder.itemView.callOnClick(); + verify(mFactory.metricsFeatureProvider, times(3)).action( any(Context.class), mActionCategoryCaptor.capture(), - mActionPackageCaptor.capture()); - String[] expectedPackages = new String[]{"pkg1", "pkg1", "pkg1"}; - Integer[] expectedActions = new Integer[]{ + mActionPackageCaptor.capture(), + mTaggedDataCaptor.capture()); + assertThat(mActionCategoryCaptor.getAllValues()).containsExactly( MetricsEvent.ACTION_SHOW_SETTINGS_SUGGESTION, MetricsEvent.ACTION_HIDE_SETTINGS_SUGGESTION, - MetricsEvent.ACTION_SHOW_SETTINGS_SUGGESTION - }; - assertThat(mActionPackageCaptor.getAllValues().toArray()).isEqualTo(expectedPackages); - assertThat(mActionCategoryCaptor.getAllValues().toArray()).isEqualTo(expectedActions); + MetricsEvent.ACTION_SHOW_SETTINGS_SUGGESTION); + assertThat(mActionPackageCaptor.getAllValues()).containsExactly("pkg1", "pkg1", "pkg1"); + assertThat(mTaggedDataCaptor.getAllValues()).containsExactly( + Pair.create(MetricsEvent.FIELD_SETTINGS_SMART_SUGGESTIONS_ENABLED, 0), + Pair.create(MetricsEvent.FIELD_SETTINGS_SMART_SUGGESTIONS_ENABLED, 0), + Pair.create(MetricsEvent.FIELD_SETTINGS_SMART_SUGGESTIONS_ENABLED, 0)); } @Test @@ -304,18 +357,46 @@ public class DashboardAdapterTest { mDashboardAdapter.onBindSuggestionConditionHeader(mSuggestionHolder, mSuggestionHeaderData); mSuggestionHolder.itemView.callOnClick(); mDashboardAdapter.onPause(); + verify(mFactory.metricsFeatureProvider, times(4)).action( any(Context.class), mActionCategoryCaptor.capture(), - mActionPackageCaptor.capture()); - String[] expectedPackages = new String[]{"pkg1", "pkg1", "pkg1", "pkg1"}; - Integer[] expectedActions = new Integer[]{ + mActionPackageCaptor.capture(), + mTaggedDataCaptor.capture()); + assertThat(mActionCategoryCaptor.getAllValues()).containsExactly( MetricsEvent.ACTION_SHOW_SETTINGS_SUGGESTION, MetricsEvent.ACTION_HIDE_SETTINGS_SUGGESTION, MetricsEvent.ACTION_SHOW_SETTINGS_SUGGESTION, - MetricsEvent.ACTION_HIDE_SETTINGS_SUGGESTION - }; - assertThat(mActionPackageCaptor.getAllValues().toArray()).isEqualTo(expectedPackages); - assertThat(mActionCategoryCaptor.getAllValues().toArray()).isEqualTo(expectedActions); + MetricsEvent.ACTION_HIDE_SETTINGS_SUGGESTION); + assertThat(mActionPackageCaptor.getAllValues()).containsExactly( + "pkg1", "pkg1", "pkg1", "pkg1"); + assertThat(mTaggedDataCaptor.getAllValues()).containsExactly( + Pair.create(MetricsEvent.FIELD_SETTINGS_SMART_SUGGESTIONS_ENABLED, 0), + Pair.create(MetricsEvent.FIELD_SETTINGS_SMART_SUGGESTIONS_ENABLED, 0), + Pair.create(MetricsEvent.FIELD_SETTINGS_SMART_SUGGESTIONS_ENABLED, 0), + Pair.create(MetricsEvent.FIELD_SETTINGS_SMART_SUGGESTIONS_ENABLED, 0)); + } + + @Test + public void testSuggestionsLogs_SmartSuggestionEnabled() { + when(mFactory.suggestionsFeatureProvider + .isSmartSuggestionEnabled(any(Context.class))).thenReturn(true); + setupSuggestions(makeSuggestions("pkg1")); + + mDashboardAdapter.onBindSuggestionConditionHeader(mSuggestionHolder, mSuggestionHeaderData); + mSuggestionHolder.itemView.callOnClick(); + mDashboardAdapter.onPause(); + + verify(mFactory.metricsFeatureProvider, times(2)).action( + any(Context.class), mActionCategoryCaptor.capture(), + mActionPackageCaptor.capture(), + mTaggedDataCaptor.capture()); + assertThat(mActionCategoryCaptor.getAllValues()).containsExactly( + MetricsEvent.ACTION_SHOW_SETTINGS_SUGGESTION, + MetricsEvent.ACTION_HIDE_SETTINGS_SUGGESTION); + assertThat(mActionPackageCaptor.getAllValues()).containsExactly("pkg1", "pkg1"); + assertThat(mTaggedDataCaptor.getAllValues()).containsExactly( + Pair.create(MetricsEvent.FIELD_SETTINGS_SMART_SUGGESTIONS_ENABLED, 1), + Pair.create(MetricsEvent.FIELD_SETTINGS_SMART_SUGGESTIONS_ENABLED, 1)); } @Test diff --git a/tests/robotests/src/com/android/settings/dashboard/suggestions/SuggestionFeatureProviderImplTest.java b/tests/robotests/src/com/android/settings/dashboard/suggestions/SuggestionFeatureProviderImplTest.java index 45d04a45657..c343f972bd8 100644 --- a/tests/robotests/src/com/android/settings/dashboard/suggestions/SuggestionFeatureProviderImplTest.java +++ b/tests/robotests/src/com/android/settings/dashboard/suggestions/SuggestionFeatureProviderImplTest.java @@ -35,7 +35,9 @@ import android.content.SharedPreferences; import android.content.pm.PackageManager; import android.hardware.fingerprint.FingerprintManager; import android.provider.Settings.Secure; +import android.util.Pair; +import com.android.internal.logging.nano.MetricsProto.MetricsEvent; import com.android.internal.logging.nano.MetricsProto; import com.android.settings.R; import com.android.settings.Settings.AmbientDisplayPickupSuggestionActivity; @@ -60,6 +62,8 @@ import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.Answers; +import org.mockito.ArgumentCaptor; +import org.mockito.Captor; import org.mockito.Mock; import org.mockito.MockitoAnnotations; import org.robolectric.RuntimeEnvironment; @@ -93,6 +97,8 @@ public class SuggestionFeatureProviderImplTest { private FingerprintManager mFingerprintManager; @Mock private SharedPreferences mSharedPreferences; + @Captor + private ArgumentCaptor mTaggedDataCaptor = ArgumentCaptor.forClass(Pair.class); private FakeFeatureFactory mFactory; private SuggestionFeatureProviderImpl mProvider; @@ -335,7 +341,10 @@ public class SuggestionFeatureProviderImplTest { verify(mFactory.metricsFeatureProvider).action( eq(mContext), eq(MetricsProto.MetricsEvent.ACTION_SETTINGS_DISMISS_SUGGESTION), - anyString()); + anyString(), + mTaggedDataCaptor.capture()); + assertThat(mTaggedDataCaptor.getAllValues()).containsExactly( + Pair.create(MetricsEvent.FIELD_SETTINGS_SMART_SUGGESTIONS_ENABLED, 0)); verify(mContext, never()).getPackageManager(); } @@ -356,8 +365,10 @@ public class SuggestionFeatureProviderImplTest { verify(mFactory.metricsFeatureProvider).action( eq(mContext), eq(MetricsProto.MetricsEvent.ACTION_SETTINGS_DISMISS_SUGGESTION), - anyString()); - + anyString(), + mTaggedDataCaptor.capture()); + assertThat(mTaggedDataCaptor.getAllValues()).containsExactly( + Pair.create(MetricsEvent.FIELD_SETTINGS_SMART_SUGGESTIONS_ENABLED, 0)); verify(mContext.getPackageManager()) .setComponentEnabledSetting(mSuggestion.intent.getComponent(), PackageManager.COMPONENT_ENABLED_STATE_DISABLED, diff --git a/tests/robotests/src/com/android/settings/dashboard/suggestions/SuggestionLogHelperTest.java b/tests/robotests/src/com/android/settings/dashboard/suggestions/SuggestionLogHelperTest.java new file mode 100644 index 00000000000..8eb4273fc54 --- /dev/null +++ b/tests/robotests/src/com/android/settings/dashboard/suggestions/SuggestionLogHelperTest.java @@ -0,0 +1,41 @@ +/* + * 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.dashboard.suggestions; + +import static com.google.common.truth.Truth.assertThat; + +import android.util.Pair; + +import com.android.internal.logging.nano.MetricsProto.MetricsEvent; + +import org.junit.Test; + +public class SuggestionLogHelperTest { + + @Test + public void testGetSmartSuggestionEnabledTaggedData_disabled() { + assertThat(SuggestionLogHelper.getSuggestionTaggedData(false)).asList().containsExactly( + Pair.create(MetricsEvent.FIELD_SETTINGS_SMART_SUGGESTIONS_ENABLED, 0)); + } + + @Test + public void testGetSmartSuggestionEnabledTaggedData_enabled() { + assertThat(SuggestionLogHelper.getSuggestionTaggedData(true)).asList().containsExactly( + Pair.create(MetricsEvent.FIELD_SETTINGS_SMART_SUGGESTIONS_ENABLED, 1)); + } +} + From 2c6a016b108bba575063ec47993dd8f3377bebe8 Mon Sep 17 00:00:00 2001 From: jackqdyulei Date: Wed, 13 Sep 2017 13:35:02 -0700 Subject: [PATCH 11/23] Update the bluetooth battery icon In ag/2863892, we add a new parameter to tune the size of battery icon. This cl use this parameter and update the icon in bluetooth detail page. Bug: 65397557 Test: RunSettingsLibRoboTests & Screenshots Change-Id: I6dd26f14b3209101dd39320b3720fbd4f79acf54 --- .../BluetoothDetailsHeaderController.java | 5 +-- src/com/android/settings/bluetooth/Utils.java | 32 +++++++++++++------ .../android/settings/bluetooth/UtilsTest.java | 4 +-- 3 files changed, 27 insertions(+), 14 deletions(-) diff --git a/src/com/android/settings/bluetooth/BluetoothDetailsHeaderController.java b/src/com/android/settings/bluetooth/BluetoothDetailsHeaderController.java index 147021402ea..04e9f5a6803 100644 --- a/src/com/android/settings/bluetooth/BluetoothDetailsHeaderController.java +++ b/src/com/android/settings/bluetooth/BluetoothDetailsHeaderController.java @@ -51,8 +51,9 @@ public class BluetoothDetailsHeaderController extends BluetoothDetailsController } protected void setHeaderProperties() { - final Pair pair = Utils.getBtClassDrawableWithDescription - (mContext, mCachedDevice); + final Pair pair = Utils.getBtClassDrawableWithDescription( + mContext, mCachedDevice, + mContext.getResources().getFraction(R.fraction.bt_battery_scale_fraction, 1, 1)); String summaryText = mCachedDevice.getConnectionSummary(); mHeaderController.setLabel(mCachedDevice.getName()); mHeaderController.setIcon(pair.first); diff --git a/src/com/android/settings/bluetooth/Utils.java b/src/com/android/settings/bluetooth/Utils.java index e80237ebc6d..0ecf62d20a1 100755 --- a/src/com/android/settings/bluetooth/Utils.java +++ b/src/com/android/settings/bluetooth/Utils.java @@ -156,28 +156,36 @@ public final class Utils { static Pair getBtClassDrawableWithDescription(Context context, CachedBluetoothDevice cachedDevice) { + return getBtClassDrawableWithDescription(context, cachedDevice, 1 /* iconScale */); + } + + static Pair getBtClassDrawableWithDescription(Context context, + CachedBluetoothDevice cachedDevice, float iconScale) { BluetoothClass btClass = cachedDevice.getBtClass(); final int level = cachedDevice.getBatteryLevel(); if (btClass != null) { switch (btClass.getMajorDeviceClass()) { case BluetoothClass.Device.Major.COMPUTER: - return new Pair<>(getBluetoothDrawable(context, R.drawable.ic_bt_laptop, level), + return new Pair<>(getBluetoothDrawable(context, R.drawable.ic_bt_laptop, level, + iconScale), context.getString(R.string.bluetooth_talkback_computer)); case BluetoothClass.Device.Major.PHONE: return new Pair<>( - getBluetoothDrawable(context, R.drawable.ic_bt_cellphone, level), + getBluetoothDrawable(context, R.drawable.ic_bt_cellphone, level, + iconScale), context.getString(R.string.bluetooth_talkback_phone)); case BluetoothClass.Device.Major.PERIPHERAL: return new Pair<>( getBluetoothDrawable(context, HidProfile.getHidClassDrawable(btClass), - level), + level, iconScale), context.getString(R.string.bluetooth_talkback_input_peripheral)); case BluetoothClass.Device.Major.IMAGING: return new Pair<>( - getBluetoothDrawable(context, R.drawable.ic_settings_print, level), + getBluetoothDrawable(context, R.drawable.ic_settings_print, level, + iconScale), context.getString(R.string.bluetooth_talkback_imaging)); default: @@ -189,30 +197,34 @@ public final class Utils { for (LocalBluetoothProfile profile : profiles) { int resId = profile.getDrawableResource(btClass); if (resId != 0) { - return new Pair<>(getBluetoothDrawable(context, resId, level), null); + return new Pair<>(getBluetoothDrawable(context, resId, level, iconScale), null); } } if (btClass != null) { if (btClass.doesClassMatch(BluetoothClass.PROFILE_HEADSET)) { return new Pair<>( - getBluetoothDrawable(context, R.drawable.ic_bt_headset_hfp, level), + getBluetoothDrawable(context, R.drawable.ic_bt_headset_hfp, level, + iconScale), context.getString(R.string.bluetooth_talkback_headset)); } if (btClass.doesClassMatch(BluetoothClass.PROFILE_A2DP)) { return new Pair<>( - getBluetoothDrawable(context, R.drawable.ic_bt_headphones_a2dp, level), + getBluetoothDrawable(context, R.drawable.ic_bt_headphones_a2dp, level, + iconScale), context.getString(R.string.bluetooth_talkback_headphone)); } } - return new Pair<>(getBluetoothDrawable(context, R.drawable.ic_settings_bluetooth, level), + return new Pair<>( + getBluetoothDrawable(context, R.drawable.ic_settings_bluetooth, level, iconScale), context.getString(R.string.bluetooth_talkback_bluetooth)); } @VisibleForTesting static Drawable getBluetoothDrawable(Context context, @DrawableRes int resId, - int batteryLevel) { + int batteryLevel, float iconScale) { if (batteryLevel != BluetoothDevice.BATTERY_LEVEL_UNKNOWN) { - return BluetoothDeviceLayerDrawable.createLayerDrawable(context, resId, batteryLevel); + return BluetoothDeviceLayerDrawable.createLayerDrawable(context, resId, batteryLevel, + iconScale); } else if (resId != 0) { return context.getDrawable(resId); } else { diff --git a/tests/robotests/src/com/android/settings/bluetooth/UtilsTest.java b/tests/robotests/src/com/android/settings/bluetooth/UtilsTest.java index 76549212a0c..220d8299f62 100644 --- a/tests/robotests/src/com/android/settings/bluetooth/UtilsTest.java +++ b/tests/robotests/src/com/android/settings/bluetooth/UtilsTest.java @@ -80,7 +80,7 @@ public class UtilsTest { @Test public void testGetBluetoothDrawable_noBatteryLevel_returnSimpleDrawable() { final Drawable drawable = Utils.getBluetoothDrawable(RuntimeEnvironment.application, - R.drawable.ic_bt_laptop, BluetoothDevice.BATTERY_LEVEL_UNKNOWN); + R.drawable.ic_bt_laptop, BluetoothDevice.BATTERY_LEVEL_UNKNOWN, 1 /* iconScale */); assertThat(drawable).isNotInstanceOf(BluetoothDeviceLayerDrawable.class); } @@ -88,7 +88,7 @@ public class UtilsTest { @Test public void testGetBluetoothDrawable_hasBatteryLevel_returnLayerDrawable() { final Drawable drawable = Utils.getBluetoothDrawable(RuntimeEnvironment.application, - R.drawable.ic_bt_laptop, 10 /* batteryLevel */); + R.drawable.ic_bt_laptop, 10 /* batteryLevel */, 1 /* iconScale */); assertThat(drawable).isInstanceOf(BluetoothDeviceLayerDrawable.class); } From 5ba0f51bcd059a4a82e38eb621a3b6bf0ba522b5 Mon Sep 17 00:00:00 2001 From: Soroosh Mariooryad Date: Fri, 11 Aug 2017 00:04:37 -0700 Subject: [PATCH 12/23] Log smart settings suggestion enabled/disabled state for A/B experiments Test: RunSettingsRoboTests Bug: 64121058 Change-Id: Iadfa575b9a21caecb515b9975d388ee0d0480c11 --- .../settings/dashboard/DashboardAdapter.java | 17 +- .../suggestions/SuggestionAdapter.java | 18 +- .../SuggestionFeatureProviderImpl.java | 13 +- .../suggestions/SuggestionLogHelper.java | 29 +++ .../dashboard/DashboardAdapterTest.java | 223 ++++++++++++------ .../SuggestionFeatureProviderImplTest.java | 17 +- .../suggestions/SuggestionLogHelperTest.java | 41 ++++ 7 files changed, 272 insertions(+), 86 deletions(-) create mode 100644 src/com/android/settings/dashboard/suggestions/SuggestionLogHelper.java create mode 100644 tests/robotests/src/com/android/settings/dashboard/suggestions/SuggestionLogHelperTest.java diff --git a/src/com/android/settings/dashboard/DashboardAdapter.java b/src/com/android/settings/dashboard/DashboardAdapter.java index fff70023371..741067ac92c 100644 --- a/src/com/android/settings/dashboard/DashboardAdapter.java +++ b/src/com/android/settings/dashboard/DashboardAdapter.java @@ -30,6 +30,7 @@ import android.support.v7.widget.RecyclerView; import android.text.TextUtils; import android.util.ArrayMap; import android.util.Log; +import android.util.Pair; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; @@ -47,6 +48,7 @@ import com.android.settings.dashboard.conditional.ConditionAdapter; import com.android.settings.dashboard.suggestions.SuggestionAdapter; import com.android.settings.dashboard.suggestions.SuggestionDismissController; import com.android.settings.dashboard.suggestions.SuggestionFeatureProvider; +import com.android.settings.dashboard.suggestions.SuggestionLogHelper; import com.android.settings.overlay.FeatureFactory; import com.android.settingslib.Utils; import com.android.settingslib.drawer.DashboardCategory; @@ -159,7 +161,8 @@ public class DashboardAdapter extends RecyclerView.Adapter[] getSuggestionTaggedData() { + return SuggestionLogHelper.getSuggestionTaggedData( + mSuggestionFeatureProvider.isSmartSuggestionEnabled(mContext)); + } + public static class IconCache { private final Context mContext; private final ArrayMap mMap = new ArrayMap<>(); diff --git a/src/com/android/settings/dashboard/suggestions/SuggestionAdapter.java b/src/com/android/settings/dashboard/suggestions/SuggestionAdapter.java index 2c9da4124b1..3815211c475 100644 --- a/src/com/android/settings/dashboard/suggestions/SuggestionAdapter.java +++ b/src/com/android/settings/dashboard/suggestions/SuggestionAdapter.java @@ -18,6 +18,7 @@ package com.android.settings.dashboard.suggestions; import android.content.Context; import android.support.v7.widget.RecyclerView; import android.text.TextUtils; +import android.util.Pair; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; @@ -67,11 +68,12 @@ public class SuggestionAdapter extends RecyclerView.Adapter public void onBindViewHolder(DashboardItemHolder holder, int position) { final Tile suggestion = (Tile) mSuggestions.get(position); final String suggestionId = mSuggestionFeatureProvider.getSuggestionIdentifier( - mContext, suggestion); + mContext, suggestion); // This is for cases when a suggestion is dismissed and the next one comes to view if (!mSuggestionsShownLogged.contains(suggestionId)) { mMetricsFeatureProvider.action( - mContext, MetricsEvent.ACTION_SHOW_SETTINGS_SUGGESTION, suggestionId); + mContext, MetricsEvent.ACTION_SHOW_SETTINGS_SUGGESTION, suggestionId, + getSuggestionTaggedData()); mSuggestionsShownLogged.add(suggestionId); } if (suggestion.remoteViews != null) { @@ -102,9 +104,11 @@ public class SuggestionAdapter extends RecyclerView.Adapter // set the item view to disabled to remove any touch effects holder.itemView.setEnabled(false); } + clickHandler.setOnClickListener(v -> { mMetricsFeatureProvider.action(mContext, - MetricsEvent.ACTION_SETTINGS_SUGGESTION, suggestionId); + MetricsEvent.ACTION_SETTINGS_SUGGESTION, suggestionId, + getSuggestionTaggedData()); ((SettingsActivity) mContext).startSuggestion(suggestion.intent); }); } @@ -129,7 +133,7 @@ public class SuggestionAdapter extends RecyclerView.Adapter public Tile getSuggestion(int position) { final long itemId = getItemId(position); - for (Tile tile: mSuggestions) { + for (Tile tile : mSuggestions) { if (Objects.hash(tile.title) == itemId) { return tile; } @@ -141,4 +145,10 @@ public class SuggestionAdapter extends RecyclerView.Adapter mSuggestions.remove(suggestion); notifyDataSetChanged(); } + + private Pair[] getSuggestionTaggedData() { + return SuggestionLogHelper.getSuggestionTaggedData( + mSuggestionFeatureProvider.isSmartSuggestionEnabled(mContext)); + } + } diff --git a/src/com/android/settings/dashboard/suggestions/SuggestionFeatureProviderImpl.java b/src/com/android/settings/dashboard/suggestions/SuggestionFeatureProviderImpl.java index f8b5a8b6a60..3d40d96d4e4 100644 --- a/src/com/android/settings/dashboard/suggestions/SuggestionFeatureProviderImpl.java +++ b/src/com/android/settings/dashboard/suggestions/SuggestionFeatureProviderImpl.java @@ -26,8 +26,9 @@ import android.provider.Settings.Secure; import android.support.annotation.NonNull; import android.support.annotation.VisibleForTesting; import android.util.Log; +import android.util.Pair; -import com.android.internal.logging.nano.MetricsProto; +import com.android.internal.logging.nano.MetricsProto.MetricsEvent; import com.android.settings.Settings.AmbientDisplayPickupSuggestionActivity; import com.android.settings.Settings.AmbientDisplaySuggestionActivity; import com.android.settings.Settings.DoubleTapPowerSuggestionActivity; @@ -45,6 +46,7 @@ import com.android.settings.support.NewDeviceIntroSuggestionActivity; import com.android.settingslib.drawer.Tile; import com.android.settingslib.suggestions.SuggestionParser; +import java.util.ArrayList; import java.util.List; public class SuggestionFeatureProviderImpl implements SuggestionFeatureProvider { @@ -130,10 +132,13 @@ public class SuggestionFeatureProviderImpl implements SuggestionFeatureProvider if (parser == null || suggestion == null || context == null) { return; } - mMetricsFeatureProvider.action( - context, MetricsProto.MetricsEvent.ACTION_SETTINGS_DISMISS_SUGGESTION, - getSuggestionIdentifier(context, suggestion)); + final Pair[] taggedData = + SuggestionLogHelper.getSuggestionTaggedData(isSmartSuggestionEnabled(context)); + mMetricsFeatureProvider.action( + context, MetricsEvent.ACTION_SETTINGS_DISMISS_SUGGESTION, + getSuggestionIdentifier(context, suggestion), + taggedData); if (!parser.dismissSuggestion(suggestion)) { return; } diff --git a/src/com/android/settings/dashboard/suggestions/SuggestionLogHelper.java b/src/com/android/settings/dashboard/suggestions/SuggestionLogHelper.java new file mode 100644 index 00000000000..339392fa780 --- /dev/null +++ b/src/com/android/settings/dashboard/suggestions/SuggestionLogHelper.java @@ -0,0 +1,29 @@ +/* + * 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.dashboard.suggestions; + +import android.util.Pair; + +import com.android.internal.logging.nano.MetricsProto.MetricsEvent; + +public class SuggestionLogHelper { + + public static Pair[] getSuggestionTaggedData(boolean enabled) { + return new Pair[]{ + Pair.create( + MetricsEvent.FIELD_SETTINGS_SMART_SUGGESTIONS_ENABLED, enabled ? 1 : 0)}; + } +} diff --git a/tests/robotests/src/com/android/settings/dashboard/DashboardAdapterTest.java b/tests/robotests/src/com/android/settings/dashboard/DashboardAdapterTest.java index e00908e52b3..4b345d072d7 100644 --- a/tests/robotests/src/com/android/settings/dashboard/DashboardAdapterTest.java +++ b/tests/robotests/src/com/android/settings/dashboard/DashboardAdapterTest.java @@ -37,6 +37,7 @@ import android.graphics.drawable.Icon; import android.os.Bundle; import android.support.v7.widget.RecyclerView; import android.util.DisplayMetrics; +import android.util.Pair; import android.view.LayoutInflater; import android.view.View; import android.widget.RelativeLayout; @@ -89,6 +90,8 @@ public class DashboardAdapterTest { private ArgumentCaptor mActionCategoryCaptor = ArgumentCaptor.forClass(Integer.class); @Captor private ArgumentCaptor mActionPackageCaptor = ArgumentCaptor.forClass(String.class); + @Captor + private ArgumentCaptor mTaggedDataCaptor = ArgumentCaptor.forClass(Pair.class); private FakeFeatureFactory mFactory; private DashboardAdapter mDashboardAdapter; private DashboardAdapter.SuggestionAndConditionHeaderHolder mSuggestionHolder; @@ -123,112 +126,143 @@ public class DashboardAdapterTest { @Test public void testSuggestionsLogs_NotExpanded() { setupSuggestions(makeSuggestions("pkg1", "pkg2", "pkg3")); + verify(mFactory.metricsFeatureProvider, times(2)).action( any(Context.class), mActionCategoryCaptor.capture(), - mActionPackageCaptor.capture()); - String[] expectedPackages = new String[]{"pkg1", "pkg2"}; - Integer[] expectedActions = new Integer[]{ + mActionPackageCaptor.capture(), + mTaggedDataCaptor.capture()); + assertThat(mActionCategoryCaptor.getAllValues()).containsExactly( MetricsEvent.ACTION_SHOW_SETTINGS_SUGGESTION, - MetricsEvent.ACTION_SHOW_SETTINGS_SUGGESTION - }; - assertThat(mActionCategoryCaptor.getAllValues().toArray()).isEqualTo(expectedActions); - assertThat(mActionPackageCaptor.getAllValues().toArray()).isEqualTo(expectedPackages); + MetricsEvent.ACTION_SHOW_SETTINGS_SUGGESTION); + assertThat(mActionPackageCaptor.getAllValues()).containsExactly("pkg1", "pkg2"); + assertThat(mTaggedDataCaptor.getAllValues()).containsExactly( + Pair.create(MetricsEvent.FIELD_SETTINGS_SMART_SUGGESTIONS_ENABLED, 0), + Pair.create(MetricsEvent.FIELD_SETTINGS_SMART_SUGGESTIONS_ENABLED, 0)); } @Test public void testSuggestionsLogs_NotExpandedAndPaused() { setupSuggestions(makeSuggestions("pkg1", "pkg2", "pkg3")); + mDashboardAdapter.onPause(); + verify(mFactory.metricsFeatureProvider, times(4)).action( any(Context.class), mActionCategoryCaptor.capture(), - mActionPackageCaptor.capture()); - String[] expectedPackages = new String[]{"pkg1", "pkg2", "pkg1", "pkg2"}; - Integer[] expectedActions = new Integer[]{ + mActionPackageCaptor.capture(), + mTaggedDataCaptor.capture()); + assertThat(mActionCategoryCaptor.getAllValues()).containsExactly( MetricsEvent.ACTION_SHOW_SETTINGS_SUGGESTION, MetricsEvent.ACTION_SHOW_SETTINGS_SUGGESTION, MetricsEvent.ACTION_HIDE_SETTINGS_SUGGESTION, - MetricsEvent.ACTION_HIDE_SETTINGS_SUGGESTION}; - assertThat(mActionCategoryCaptor.getAllValues().toArray()).isEqualTo(expectedActions); - assertThat(mActionPackageCaptor.getAllValues().toArray()).isEqualTo(expectedPackages); + MetricsEvent.ACTION_HIDE_SETTINGS_SUGGESTION); + assertThat(mActionPackageCaptor.getAllValues()).containsExactly( + "pkg1", "pkg2", "pkg1", "pkg2"); + assertThat(mTaggedDataCaptor.getAllValues()).containsExactly( + Pair.create(MetricsEvent.FIELD_SETTINGS_SMART_SUGGESTIONS_ENABLED, 0), + Pair.create(MetricsEvent.FIELD_SETTINGS_SMART_SUGGESTIONS_ENABLED, 0), + Pair.create(MetricsEvent.FIELD_SETTINGS_SMART_SUGGESTIONS_ENABLED, 0), + Pair.create(MetricsEvent.FIELD_SETTINGS_SMART_SUGGESTIONS_ENABLED, 0)); } @Test public void testSuggestionsLogs_Expanded() { setupSuggestions(makeSuggestions("pkg1", "pkg2", "pkg3")); + mDashboardAdapter.onBindSuggestionConditionHeader(mSuggestionHolder, mSuggestionHeaderData); mSuggestionHolder.itemView.callOnClick(); + verify(mFactory.metricsFeatureProvider, times(3)).action( any(Context.class), mActionCategoryCaptor.capture(), - mActionPackageCaptor.capture()); - String[] expectedPackages = new String[]{"pkg1", "pkg2", "pkg3"}; - Integer[] expectedActions = new Integer[]{ + mActionPackageCaptor.capture(), + mTaggedDataCaptor.capture()); + assertThat(mActionCategoryCaptor.getAllValues()).containsExactly( MetricsEvent.ACTION_SHOW_SETTINGS_SUGGESTION, MetricsEvent.ACTION_SHOW_SETTINGS_SUGGESTION, - MetricsEvent.ACTION_SHOW_SETTINGS_SUGGESTION - }; - assertThat(mActionPackageCaptor.getAllValues().toArray()).isEqualTo(expectedPackages); - assertThat(mActionCategoryCaptor.getAllValues().toArray()).isEqualTo(expectedActions); + MetricsEvent.ACTION_SHOW_SETTINGS_SUGGESTION); + assertThat(mActionPackageCaptor.getAllValues()).containsExactly( + "pkg1", "pkg2", "pkg3"); + assertThat(mTaggedDataCaptor.getAllValues()).containsExactly( + Pair.create(MetricsEvent.FIELD_SETTINGS_SMART_SUGGESTIONS_ENABLED, 0), + Pair.create(MetricsEvent.FIELD_SETTINGS_SMART_SUGGESTIONS_ENABLED, 0), + Pair.create(MetricsEvent.FIELD_SETTINGS_SMART_SUGGESTIONS_ENABLED, 0)); } @Test public void testSuggestionsLogs_ExpandedAndPaused() { setupSuggestions(makeSuggestions("pkg1", "pkg2", "pkg3")); + mDashboardAdapter.onBindSuggestionConditionHeader(mSuggestionHolder, mSuggestionHeaderData); mSuggestionHolder.itemView.callOnClick(); mDashboardAdapter.onPause(); + verify(mFactory.metricsFeatureProvider, times(6)).action( any(Context.class), mActionCategoryCaptor.capture(), - mActionPackageCaptor.capture()); - String[] expectedPackages = new String[]{"pkg1", "pkg2", "pkg3", "pkg1", "pkg2", "pkg3"}; - Integer[] expectedActions = new Integer[]{ + mActionPackageCaptor.capture(), + mTaggedDataCaptor.capture()); + assertThat(mActionCategoryCaptor.getAllValues()).containsExactly( MetricsEvent.ACTION_SHOW_SETTINGS_SUGGESTION, MetricsEvent.ACTION_SHOW_SETTINGS_SUGGESTION, MetricsEvent.ACTION_SHOW_SETTINGS_SUGGESTION, MetricsEvent.ACTION_HIDE_SETTINGS_SUGGESTION, MetricsEvent.ACTION_HIDE_SETTINGS_SUGGESTION, - MetricsEvent.ACTION_HIDE_SETTINGS_SUGGESTION - }; - assertThat(mActionPackageCaptor.getAllValues().toArray()).isEqualTo(expectedPackages); - assertThat(mActionCategoryCaptor.getAllValues().toArray()).isEqualTo(expectedActions); + MetricsEvent.ACTION_HIDE_SETTINGS_SUGGESTION); + assertThat(mActionPackageCaptor.getAllValues()).containsExactly( + "pkg1", "pkg2", "pkg3", "pkg1", "pkg2", "pkg3"); + assertThat(mTaggedDataCaptor.getAllValues()).containsExactly( + Pair.create(MetricsEvent.FIELD_SETTINGS_SMART_SUGGESTIONS_ENABLED, 0), + Pair.create(MetricsEvent.FIELD_SETTINGS_SMART_SUGGESTIONS_ENABLED, 0), + Pair.create(MetricsEvent.FIELD_SETTINGS_SMART_SUGGESTIONS_ENABLED, 0), + Pair.create(MetricsEvent.FIELD_SETTINGS_SMART_SUGGESTIONS_ENABLED, 0), + Pair.create(MetricsEvent.FIELD_SETTINGS_SMART_SUGGESTIONS_ENABLED, 0), + Pair.create(MetricsEvent.FIELD_SETTINGS_SMART_SUGGESTIONS_ENABLED, 0)); } @Test public void testSuggestionsLogs_ExpandedAfterPause() { setupSuggestions(makeSuggestions("pkg1", "pkg2", "pkg3")); + mDashboardAdapter.onPause(); mDashboardAdapter.onBindSuggestionConditionHeader(mSuggestionHolder, mSuggestionHeaderData); mSuggestionHolder.itemView.callOnClick(); + verify(mFactory.metricsFeatureProvider, times(7)).action( any(Context.class), mActionCategoryCaptor.capture(), - mActionPackageCaptor.capture()); - String[] expectedPackages = new String[]{ - "pkg1", "pkg2", "pkg1", "pkg2", "pkg1", "pkg2", "pkg3"}; - Integer[] expectedActions = new Integer[]{ + mActionPackageCaptor.capture(), + mTaggedDataCaptor.capture()); + assertThat(mActionCategoryCaptor.getAllValues()).containsExactly( MetricsEvent.ACTION_SHOW_SETTINGS_SUGGESTION, MetricsEvent.ACTION_SHOW_SETTINGS_SUGGESTION, MetricsEvent.ACTION_HIDE_SETTINGS_SUGGESTION, MetricsEvent.ACTION_HIDE_SETTINGS_SUGGESTION, MetricsEvent.ACTION_SHOW_SETTINGS_SUGGESTION, MetricsEvent.ACTION_SHOW_SETTINGS_SUGGESTION, - MetricsEvent.ACTION_SHOW_SETTINGS_SUGGESTION - }; - assertThat(mActionPackageCaptor.getAllValues().toArray()).isEqualTo(expectedPackages); - assertThat(mActionCategoryCaptor.getAllValues().toArray()).isEqualTo(expectedActions); + MetricsEvent.ACTION_SHOW_SETTINGS_SUGGESTION); + assertThat(mActionPackageCaptor.getAllValues()).containsExactly( + "pkg1", "pkg2", "pkg1", "pkg2", "pkg1", "pkg2", "pkg3"); + assertThat(mTaggedDataCaptor.getAllValues()).containsExactly( + Pair.create(MetricsEvent.FIELD_SETTINGS_SMART_SUGGESTIONS_ENABLED, 0), + Pair.create(MetricsEvent.FIELD_SETTINGS_SMART_SUGGESTIONS_ENABLED, 0), + Pair.create(MetricsEvent.FIELD_SETTINGS_SMART_SUGGESTIONS_ENABLED, 0), + Pair.create(MetricsEvent.FIELD_SETTINGS_SMART_SUGGESTIONS_ENABLED, 0), + Pair.create(MetricsEvent.FIELD_SETTINGS_SMART_SUGGESTIONS_ENABLED, 0), + Pair.create(MetricsEvent.FIELD_SETTINGS_SMART_SUGGESTIONS_ENABLED, 0), + Pair.create(MetricsEvent.FIELD_SETTINGS_SMART_SUGGESTIONS_ENABLED, 0)); } @Test public void testSuggestionsLogs_ExpandedAfterPauseAndPausedAgain() { setupSuggestions(makeSuggestions("pkg1", "pkg2", "pkg3")); + mDashboardAdapter.onPause(); mDashboardAdapter.onBindSuggestionConditionHeader(mSuggestionHolder, mSuggestionHeaderData); mSuggestionHolder.itemView.callOnClick(); mDashboardAdapter.onPause(); + verify(mFactory.metricsFeatureProvider, times(10)).action( any(Context.class), mActionCategoryCaptor.capture(), - mActionPackageCaptor.capture()); - String[] expectedPackages = new String[]{ - "pkg1", "pkg2", "pkg1", "pkg2", "pkg1", "pkg2", "pkg3", "pkg1", "pkg2", "pkg3"}; - Integer[] expectedActions = new Integer[]{ + mActionPackageCaptor.capture(), + mTaggedDataCaptor.capture()); + assertThat(mActionCategoryCaptor.getAllValues()).containsExactly( MetricsEvent.ACTION_SHOW_SETTINGS_SUGGESTION, MetricsEvent.ACTION_SHOW_SETTINGS_SUGGESTION, MetricsEvent.ACTION_HIDE_SETTINGS_SUGGESTION, @@ -238,63 +272,82 @@ public class DashboardAdapterTest { MetricsEvent.ACTION_SHOW_SETTINGS_SUGGESTION, MetricsEvent.ACTION_HIDE_SETTINGS_SUGGESTION, MetricsEvent.ACTION_HIDE_SETTINGS_SUGGESTION, - MetricsEvent.ACTION_HIDE_SETTINGS_SUGGESTION - }; - assertThat(mActionPackageCaptor.getAllValues().toArray()).isEqualTo(expectedPackages); - assertThat(mActionCategoryCaptor.getAllValues().toArray()).isEqualTo(expectedActions); + MetricsEvent.ACTION_HIDE_SETTINGS_SUGGESTION); + assertThat(mActionPackageCaptor.getAllValues()).containsExactly( + "pkg1", "pkg2", "pkg1", "pkg2", "pkg1", "pkg2", "pkg3", "pkg1", "pkg2", "pkg3"); + assertThat(mTaggedDataCaptor.getAllValues()).containsExactly( + Pair.create(MetricsEvent.FIELD_SETTINGS_SMART_SUGGESTIONS_ENABLED, 0), + Pair.create(MetricsEvent.FIELD_SETTINGS_SMART_SUGGESTIONS_ENABLED, 0), + Pair.create(MetricsEvent.FIELD_SETTINGS_SMART_SUGGESTIONS_ENABLED, 0), + Pair.create(MetricsEvent.FIELD_SETTINGS_SMART_SUGGESTIONS_ENABLED, 0), + Pair.create(MetricsEvent.FIELD_SETTINGS_SMART_SUGGESTIONS_ENABLED, 0), + Pair.create(MetricsEvent.FIELD_SETTINGS_SMART_SUGGESTIONS_ENABLED, 0), + Pair.create(MetricsEvent.FIELD_SETTINGS_SMART_SUGGESTIONS_ENABLED, 0), + Pair.create(MetricsEvent.FIELD_SETTINGS_SMART_SUGGESTIONS_ENABLED, 0), + Pair.create(MetricsEvent.FIELD_SETTINGS_SMART_SUGGESTIONS_ENABLED, 0), + Pair.create(MetricsEvent.FIELD_SETTINGS_SMART_SUGGESTIONS_ENABLED, 0)); } @Test public void testSuggestionsLogs_ExpandedWithLessThanDefaultShown() { setupSuggestions(makeSuggestions("pkg1")); + mDashboardAdapter.onBindSuggestionConditionHeader(mSuggestionHolder, mSuggestionHeaderData); mSuggestionHolder.itemView.callOnClick(); + verify(mFactory.metricsFeatureProvider, times(1)).action( any(Context.class), mActionCategoryCaptor.capture(), - mActionPackageCaptor.capture()); - String[] expectedPackages = new String[]{"pkg1"}; - Integer[] expectedActions = new Integer[]{ - MetricsEvent.ACTION_SHOW_SETTINGS_SUGGESTION, - }; - assertThat(mActionPackageCaptor.getAllValues().toArray()).isEqualTo(expectedPackages); - assertThat(mActionCategoryCaptor.getAllValues().toArray()).isEqualTo(expectedActions); + mActionPackageCaptor.capture(), + mTaggedDataCaptor.capture()); + assertThat(mActionCategoryCaptor.getAllValues()).containsExactly( + MetricsEvent.ACTION_SHOW_SETTINGS_SUGGESTION); + assertThat(mActionPackageCaptor.getAllValues()).containsExactly("pkg1"); + assertThat(mTaggedDataCaptor.getAllValues()).containsExactly( + Pair.create(MetricsEvent.FIELD_SETTINGS_SMART_SUGGESTIONS_ENABLED, 0)); } @Test public void testSuggestionsLogs_ExpandedWithLessThanDefaultShownAndPaused() { setupSuggestions(makeSuggestions("pkg1")); + mDashboardAdapter.onBindSuggestionConditionHeader(mSuggestionHolder, mSuggestionHeaderData); mSuggestionHolder.itemView.callOnClick(); mDashboardAdapter.onPause(); + verify(mFactory.metricsFeatureProvider, times(2)).action( any(Context.class), mActionCategoryCaptor.capture(), - mActionPackageCaptor.capture()); - String[] expectedPackages = new String[]{"pkg1", "pkg1"}; - Integer[] expectedActions = new Integer[]{ + mActionPackageCaptor.capture(), + mTaggedDataCaptor.capture()); + assertThat(mActionCategoryCaptor.getAllValues()).containsExactly( MetricsEvent.ACTION_SHOW_SETTINGS_SUGGESTION, - MetricsEvent.ACTION_HIDE_SETTINGS_SUGGESTION - }; - assertThat(mActionPackageCaptor.getAllValues().toArray()).isEqualTo(expectedPackages); - assertThat(mActionCategoryCaptor.getAllValues().toArray()).isEqualTo(expectedActions); + MetricsEvent.ACTION_HIDE_SETTINGS_SUGGESTION); + assertThat(mActionPackageCaptor.getAllValues()).containsExactly("pkg1", "pkg1"); + assertThat(mTaggedDataCaptor.getAllValues()).containsExactly( + Pair.create(MetricsEvent.FIELD_SETTINGS_SMART_SUGGESTIONS_ENABLED, 0), + Pair.create(MetricsEvent.FIELD_SETTINGS_SMART_SUGGESTIONS_ENABLED, 0)); } @Test public void testSuggestionsLogs_ExpandedWithLessThanDefaultShownAfterPause() { setupSuggestions(makeSuggestions("pkg1")); + mDashboardAdapter.onPause(); mDashboardAdapter.onBindSuggestionConditionHeader(mSuggestionHolder, mSuggestionHeaderData); mSuggestionHolder.itemView.callOnClick(); + verify(mFactory.metricsFeatureProvider, times(3)).action( any(Context.class), mActionCategoryCaptor.capture(), - mActionPackageCaptor.capture()); - String[] expectedPackages = new String[]{"pkg1", "pkg1", "pkg1"}; - Integer[] expectedActions = new Integer[]{ + mActionPackageCaptor.capture(), + mTaggedDataCaptor.capture()); + assertThat(mActionCategoryCaptor.getAllValues()).containsExactly( MetricsEvent.ACTION_SHOW_SETTINGS_SUGGESTION, MetricsEvent.ACTION_HIDE_SETTINGS_SUGGESTION, - MetricsEvent.ACTION_SHOW_SETTINGS_SUGGESTION - }; - assertThat(mActionPackageCaptor.getAllValues().toArray()).isEqualTo(expectedPackages); - assertThat(mActionCategoryCaptor.getAllValues().toArray()).isEqualTo(expectedActions); + MetricsEvent.ACTION_SHOW_SETTINGS_SUGGESTION); + assertThat(mActionPackageCaptor.getAllValues()).containsExactly("pkg1", "pkg1", "pkg1"); + assertThat(mTaggedDataCaptor.getAllValues()).containsExactly( + Pair.create(MetricsEvent.FIELD_SETTINGS_SMART_SUGGESTIONS_ENABLED, 0), + Pair.create(MetricsEvent.FIELD_SETTINGS_SMART_SUGGESTIONS_ENABLED, 0), + Pair.create(MetricsEvent.FIELD_SETTINGS_SMART_SUGGESTIONS_ENABLED, 0)); } @Test @@ -304,18 +357,46 @@ public class DashboardAdapterTest { mDashboardAdapter.onBindSuggestionConditionHeader(mSuggestionHolder, mSuggestionHeaderData); mSuggestionHolder.itemView.callOnClick(); mDashboardAdapter.onPause(); + verify(mFactory.metricsFeatureProvider, times(4)).action( any(Context.class), mActionCategoryCaptor.capture(), - mActionPackageCaptor.capture()); - String[] expectedPackages = new String[]{"pkg1", "pkg1", "pkg1", "pkg1"}; - Integer[] expectedActions = new Integer[]{ + mActionPackageCaptor.capture(), + mTaggedDataCaptor.capture()); + assertThat(mActionCategoryCaptor.getAllValues()).containsExactly( MetricsEvent.ACTION_SHOW_SETTINGS_SUGGESTION, MetricsEvent.ACTION_HIDE_SETTINGS_SUGGESTION, MetricsEvent.ACTION_SHOW_SETTINGS_SUGGESTION, - MetricsEvent.ACTION_HIDE_SETTINGS_SUGGESTION - }; - assertThat(mActionPackageCaptor.getAllValues().toArray()).isEqualTo(expectedPackages); - assertThat(mActionCategoryCaptor.getAllValues().toArray()).isEqualTo(expectedActions); + MetricsEvent.ACTION_HIDE_SETTINGS_SUGGESTION); + assertThat(mActionPackageCaptor.getAllValues()).containsExactly( + "pkg1", "pkg1", "pkg1", "pkg1"); + assertThat(mTaggedDataCaptor.getAllValues()).containsExactly( + Pair.create(MetricsEvent.FIELD_SETTINGS_SMART_SUGGESTIONS_ENABLED, 0), + Pair.create(MetricsEvent.FIELD_SETTINGS_SMART_SUGGESTIONS_ENABLED, 0), + Pair.create(MetricsEvent.FIELD_SETTINGS_SMART_SUGGESTIONS_ENABLED, 0), + Pair.create(MetricsEvent.FIELD_SETTINGS_SMART_SUGGESTIONS_ENABLED, 0)); + } + + @Test + public void testSuggestionsLogs_SmartSuggestionEnabled() { + when(mFactory.suggestionsFeatureProvider + .isSmartSuggestionEnabled(any(Context.class))).thenReturn(true); + setupSuggestions(makeSuggestions("pkg1")); + + mDashboardAdapter.onBindSuggestionConditionHeader(mSuggestionHolder, mSuggestionHeaderData); + mSuggestionHolder.itemView.callOnClick(); + mDashboardAdapter.onPause(); + + verify(mFactory.metricsFeatureProvider, times(2)).action( + any(Context.class), mActionCategoryCaptor.capture(), + mActionPackageCaptor.capture(), + mTaggedDataCaptor.capture()); + assertThat(mActionCategoryCaptor.getAllValues()).containsExactly( + MetricsEvent.ACTION_SHOW_SETTINGS_SUGGESTION, + MetricsEvent.ACTION_HIDE_SETTINGS_SUGGESTION); + assertThat(mActionPackageCaptor.getAllValues()).containsExactly("pkg1", "pkg1"); + assertThat(mTaggedDataCaptor.getAllValues()).containsExactly( + Pair.create(MetricsEvent.FIELD_SETTINGS_SMART_SUGGESTIONS_ENABLED, 1), + Pair.create(MetricsEvent.FIELD_SETTINGS_SMART_SUGGESTIONS_ENABLED, 1)); } @Test diff --git a/tests/robotests/src/com/android/settings/dashboard/suggestions/SuggestionFeatureProviderImplTest.java b/tests/robotests/src/com/android/settings/dashboard/suggestions/SuggestionFeatureProviderImplTest.java index 45d04a45657..c343f972bd8 100644 --- a/tests/robotests/src/com/android/settings/dashboard/suggestions/SuggestionFeatureProviderImplTest.java +++ b/tests/robotests/src/com/android/settings/dashboard/suggestions/SuggestionFeatureProviderImplTest.java @@ -35,7 +35,9 @@ import android.content.SharedPreferences; import android.content.pm.PackageManager; import android.hardware.fingerprint.FingerprintManager; import android.provider.Settings.Secure; +import android.util.Pair; +import com.android.internal.logging.nano.MetricsProto.MetricsEvent; import com.android.internal.logging.nano.MetricsProto; import com.android.settings.R; import com.android.settings.Settings.AmbientDisplayPickupSuggestionActivity; @@ -60,6 +62,8 @@ import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.Answers; +import org.mockito.ArgumentCaptor; +import org.mockito.Captor; import org.mockito.Mock; import org.mockito.MockitoAnnotations; import org.robolectric.RuntimeEnvironment; @@ -93,6 +97,8 @@ public class SuggestionFeatureProviderImplTest { private FingerprintManager mFingerprintManager; @Mock private SharedPreferences mSharedPreferences; + @Captor + private ArgumentCaptor mTaggedDataCaptor = ArgumentCaptor.forClass(Pair.class); private FakeFeatureFactory mFactory; private SuggestionFeatureProviderImpl mProvider; @@ -335,7 +341,10 @@ public class SuggestionFeatureProviderImplTest { verify(mFactory.metricsFeatureProvider).action( eq(mContext), eq(MetricsProto.MetricsEvent.ACTION_SETTINGS_DISMISS_SUGGESTION), - anyString()); + anyString(), + mTaggedDataCaptor.capture()); + assertThat(mTaggedDataCaptor.getAllValues()).containsExactly( + Pair.create(MetricsEvent.FIELD_SETTINGS_SMART_SUGGESTIONS_ENABLED, 0)); verify(mContext, never()).getPackageManager(); } @@ -356,8 +365,10 @@ public class SuggestionFeatureProviderImplTest { verify(mFactory.metricsFeatureProvider).action( eq(mContext), eq(MetricsProto.MetricsEvent.ACTION_SETTINGS_DISMISS_SUGGESTION), - anyString()); - + anyString(), + mTaggedDataCaptor.capture()); + assertThat(mTaggedDataCaptor.getAllValues()).containsExactly( + Pair.create(MetricsEvent.FIELD_SETTINGS_SMART_SUGGESTIONS_ENABLED, 0)); verify(mContext.getPackageManager()) .setComponentEnabledSetting(mSuggestion.intent.getComponent(), PackageManager.COMPONENT_ENABLED_STATE_DISABLED, diff --git a/tests/robotests/src/com/android/settings/dashboard/suggestions/SuggestionLogHelperTest.java b/tests/robotests/src/com/android/settings/dashboard/suggestions/SuggestionLogHelperTest.java new file mode 100644 index 00000000000..8eb4273fc54 --- /dev/null +++ b/tests/robotests/src/com/android/settings/dashboard/suggestions/SuggestionLogHelperTest.java @@ -0,0 +1,41 @@ +/* + * 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.dashboard.suggestions; + +import static com.google.common.truth.Truth.assertThat; + +import android.util.Pair; + +import com.android.internal.logging.nano.MetricsProto.MetricsEvent; + +import org.junit.Test; + +public class SuggestionLogHelperTest { + + @Test + public void testGetSmartSuggestionEnabledTaggedData_disabled() { + assertThat(SuggestionLogHelper.getSuggestionTaggedData(false)).asList().containsExactly( + Pair.create(MetricsEvent.FIELD_SETTINGS_SMART_SUGGESTIONS_ENABLED, 0)); + } + + @Test + public void testGetSmartSuggestionEnabledTaggedData_enabled() { + assertThat(SuggestionLogHelper.getSuggestionTaggedData(true)).asList().containsExactly( + Pair.create(MetricsEvent.FIELD_SETTINGS_SMART_SUGGESTIONS_ENABLED, 1)); + } +} + From 59982c6954b215f17e14e8d87efccdc25144a1cc Mon Sep 17 00:00:00 2001 From: Daniel Nishi Date: Tue, 12 Sep 2017 16:52:17 -0700 Subject: [PATCH 13/23] Fix work profile storage bugs. This makes apps and files in the work profile show up only for the work profile. It turns out the primary profile's user id was getting piped down to the special files views and it was showing the primary profile's file sizes instead of the work ones. Change-Id: If9c175f24920513c624c522d838bcdbe925566d1 Fixes: 65559258, 65558758, 65559934 Test: Settings robotest and 34768986 --- .../applications/ManageApplications.java | 19 +++++++++++----- .../StorageItemPreferenceController.java | 22 ++++++++++--------- .../StorageItemPreferenceControllerTest.java | 5 +++++ 3 files changed, 30 insertions(+), 16 deletions(-) diff --git a/src/com/android/settings/applications/ManageApplications.java b/src/com/android/settings/applications/ManageApplications.java index 11eb0ccefd1..deda92a103d 100644 --- a/src/com/android/settings/applications/ManageApplications.java +++ b/src/com/android/settings/applications/ManageApplications.java @@ -117,6 +117,7 @@ public class ManageApplications extends InstrumentedPreferenceFragment public static final String EXTRA_VOLUME_NAME = "volumeName"; public static final String EXTRA_STORAGE_TYPE = "storageType"; public static final String EXTRA_WORK_ONLY = "workProfileOnly"; + public static final String EXTRA_WORK_ID = "workId"; private static final String EXTRA_SORT_ORDER = "sortOrder"; private static final String EXTRA_SHOW_SYSTEM = "showSystem"; @@ -222,6 +223,8 @@ public class ManageApplications extends InstrumentedPreferenceFragment public static final int STORAGE_TYPE_LEGACY = 2; // Show apps even if they can be categorized. public static final int STORAGE_TYPE_PHOTOS_VIDEOS = 3; + private static final int NO_USER_SPECIFIED = -1; + // sort order private int mSortOrder = R.id.sort_order_alpha; @@ -282,6 +285,7 @@ public class ManageApplications extends InstrumentedPreferenceFragment private String mVolumeUuid; private int mStorageType; private boolean mIsWorkOnly; + private int mWorkUserId; @Override public void onCreate(Bundle savedInstanceState) { @@ -338,6 +342,7 @@ public class ManageApplications extends InstrumentedPreferenceFragment } mFilter = getDefaultFilter(); mIsWorkOnly = args != null ? args.getBoolean(EXTRA_WORK_ONLY) : false; + mWorkUserId = args != null ? args.getInt(EXTRA_WORK_ID) : NO_USER_SPECIFIED; if (savedInstanceState != null) { mSortOrder = savedInstanceState.getInt(EXTRA_SORT_ORDER, mSortOrder); @@ -378,13 +383,15 @@ public class ManageApplications extends InstrumentedPreferenceFragment mApplications.mHasReceivedBridgeCallback = savedInstanceState.getBoolean(EXTRA_HAS_BRIDGE, false); } + int userId = mIsWorkOnly ? mWorkUserId : UserHandle.getUserId(mCurrentUid); if (mStorageType == STORAGE_TYPE_MUSIC) { Context context = getContext(); - mApplications.setExtraViewController(new MusicViewHolderController( - context, - new StorageStatsSource(context), - mVolumeUuid, - UserHandle.of(UserHandle.getUserId(mCurrentUid)))); + mApplications.setExtraViewController( + new MusicViewHolderController( + context, + new StorageStatsSource(context), + mVolumeUuid, + UserHandle.of(userId))); } else if (mStorageType == STORAGE_TYPE_PHOTOS_VIDEOS) { Context context = getContext(); mApplications.setExtraViewController( @@ -392,7 +399,7 @@ public class ManageApplications extends InstrumentedPreferenceFragment context, new StorageStatsSource(context), mVolumeUuid, - UserHandle.of(UserHandle.getUserId(mCurrentUid)))); + UserHandle.of(userId))); } mListView.setAdapter(mApplications); mListView.setRecyclerListener(mApplications); diff --git a/src/com/android/settings/deviceinfo/storage/StorageItemPreferenceController.java b/src/com/android/settings/deviceinfo/storage/StorageItemPreferenceController.java index 163f5b9dff4..7f2cc33e291 100644 --- a/src/com/android/settings/deviceinfo/storage/StorageItemPreferenceController.java +++ b/src/com/android/settings/deviceinfo/storage/StorageItemPreferenceController.java @@ -20,7 +20,6 @@ import android.app.Fragment; import android.content.ActivityNotFoundException; import android.content.Context; import android.content.Intent; -import android.content.pm.PackageManager; import android.content.res.TypedArray; import android.graphics.drawable.Drawable; import android.net.TrafficStats; @@ -314,7 +313,7 @@ public class StorageItemPreferenceController extends AbstractPreferenceControlle } private Intent getPhotosIntent() { - Bundle args = new Bundle(2); + Bundle args = getWorkAnnotatedBundle(2); args.putString( ManageApplications.EXTRA_CLASSNAME, Settings.PhotosStorageActivity.class.getName()); args.putInt( @@ -336,8 +335,7 @@ public class StorageItemPreferenceController extends AbstractPreferenceControlle return null; } - Bundle args = new Bundle(); - args.putBoolean(ManageApplications.EXTRA_WORK_ONLY, mIsWorkProfile); + Bundle args = getWorkAnnotatedBundle(4); args.putString(ManageApplications.EXTRA_CLASSNAME, Settings.StorageUseActivity.class.getName()); args.putString(ManageApplications.EXTRA_VOLUME_UUID, mVolume.getFsUuid()); @@ -353,8 +351,7 @@ public class StorageItemPreferenceController extends AbstractPreferenceControlle return null; } - Bundle args = new Bundle(); - args.putBoolean(ManageApplications.EXTRA_WORK_ONLY, mIsWorkProfile); + Bundle args = getWorkAnnotatedBundle(3); args.putString(ManageApplications.EXTRA_CLASSNAME, Settings.StorageUseActivity.class.getName()); args.putString(ManageApplications.EXTRA_VOLUME_UUID, mVolume.getFsUuid()); @@ -365,8 +362,7 @@ public class StorageItemPreferenceController extends AbstractPreferenceControlle } private Intent getGamesIntent() { - Bundle args = new Bundle(1); - args.putBoolean(ManageApplications.EXTRA_WORK_ONLY, mIsWorkProfile); + Bundle args = getWorkAnnotatedBundle(1); args.putString(ManageApplications.EXTRA_CLASSNAME, Settings.GamesStorageActivity.class.getName()); return Utils.onBuildStartFragmentIntent(mContext, @@ -375,8 +371,7 @@ public class StorageItemPreferenceController extends AbstractPreferenceControlle } private Intent getMoviesIntent() { - Bundle args = new Bundle(1); - args.putBoolean(ManageApplications.EXTRA_WORK_ONLY, mIsWorkProfile); + Bundle args = getWorkAnnotatedBundle(1); args.putString(ManageApplications.EXTRA_CLASSNAME, Settings.MoviesStorageActivity.class.getName()); return Utils.onBuildStartFragmentIntent(mContext, @@ -384,6 +379,13 @@ public class StorageItemPreferenceController extends AbstractPreferenceControlle null, false, mMetricsFeatureProvider.getMetricsCategory(mFragment)); } + private Bundle getWorkAnnotatedBundle(int additionalCapacity) { + Bundle args = new Bundle(2 + additionalCapacity); + args.putBoolean(ManageApplications.EXTRA_WORK_ONLY, mIsWorkProfile); + args.putInt(ManageApplications.EXTRA_WORK_ID, mUserId); + return args; + } + private Intent getFilesIntent() { return mSvp.findEmulatedForPrivate(mVolume).buildBrowseIntent(); } diff --git a/tests/robotests/src/com/android/settings/deviceinfo/storage/StorageItemPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/deviceinfo/storage/StorageItemPreferenceControllerTest.java index 9d69349f4e0..9bef5600b4a 100644 --- a/tests/robotests/src/com/android/settings/deviceinfo/storage/StorageItemPreferenceControllerTest.java +++ b/tests/robotests/src/com/android/settings/deviceinfo/storage/StorageItemPreferenceControllerTest.java @@ -16,6 +16,7 @@ package com.android.settings.deviceinfo.storage; +import static com.android.settings.applications.ManageApplications.EXTRA_WORK_ID; import static com.android.settings.applications.ManageApplications.EXTRA_WORK_ONLY; import static com.android.settings.utils.FileSizeFormatter.MEGABYTE_IN_BYTES; @@ -195,6 +196,10 @@ public class StorageItemPreferenceControllerTest { intent.getBundleExtra(SettingsActivity.EXTRA_SHOW_FRAGMENT_ARGUMENTS) .getBoolean(EXTRA_WORK_ONLY)) .isTrue(); + assertThat( + intent.getBundleExtra(SettingsActivity.EXTRA_SHOW_FRAGMENT_ARGUMENTS) + .getInt(EXTRA_WORK_ID)) + .isEqualTo(0); } @Test From 5a4b6b152a1c16f1ff1455c3b2c1e5df4dcd490b Mon Sep 17 00:00:00 2001 From: Antony Sargent Date: Thu, 14 Sep 2017 10:52:44 -0700 Subject: [PATCH 14/23] Bring back "Turning on hotspot" status text when starting hotspot We accidentally regressed showing this text when starting the hotspot in the refactor ag/2381595. Bug: 64811203 Test: make RunSettingsRoboTests --- .../WifiTetherPreferenceController.java | 2 ++ .../WifiTetherPreferenceControllerTest.java | 19 ++++++++++++++----- 2 files changed, 16 insertions(+), 5 deletions(-) diff --git a/src/com/android/settings/wifi/tether/WifiTetherPreferenceController.java b/src/com/android/settings/wifi/tether/WifiTetherPreferenceController.java index 87adf73f561..a216f9d2ad5 100644 --- a/src/com/android/settings/wifi/tether/WifiTetherPreferenceController.java +++ b/src/com/android/settings/wifi/tether/WifiTetherPreferenceController.java @@ -140,6 +140,8 @@ public class WifiTetherPreferenceController extends AbstractPreferenceController private void handleWifiApStateChanged(int state, int reason) { switch (state) { case WifiManager.WIFI_AP_STATE_ENABLING: + mPreference.setSummary(R.string.wifi_tether_starting); + break; case WifiManager.WIFI_AP_STATE_ENABLED: /** * Summary on enable is handled by tether diff --git a/tests/robotests/src/com/android/settings/wifi/tether/WifiTetherPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/wifi/tether/WifiTetherPreferenceControllerTest.java index a23347abbbc..ff3f47e6cfa 100644 --- a/tests/robotests/src/com/android/settings/wifi/tether/WifiTetherPreferenceControllerTest.java +++ b/tests/robotests/src/com/android/settings/wifi/tether/WifiTetherPreferenceControllerTest.java @@ -175,20 +175,29 @@ public class WifiTetherPreferenceControllerTest { } @Test - public void testReceiver_apStateChangedToEnablingOrEnabled_shouldNotUpdatePreferenceSummary() { + public void testReceiver_apStateChangedToEnabling_shouldUpdatePreferenceSummary() { + mController.displayPreference(mScreen); + receiveApStateChangedBroadcast(WifiManager.WIFI_AP_STATE_ENABLING); + assertThat(mPreference.getSummary().toString()).isEqualTo( + RuntimeEnvironment.application.getString(R.string.wifi_tether_starting)); + } + + @Test + public void testReceiver_apStateChangedToEnabled_shouldNotUpdatePreferenceSummary() { mController.displayPreference(mScreen); receiveApStateChangedBroadcast(WifiManager.WIFI_AP_STATE_DISABLED); assertThat(mPreference.getSummary().toString()).isEqualTo( RuntimeEnvironment.application.getString(R.string.wifi_hotspot_off_subtext)); - // When turning on the hotspot, we receive STATE_ENABLING followed by STATE_ENABLED. Neither - // of these should change the summary. + // When turning on the hotspot, we receive STATE_ENABLING followed by STATE_ENABLED. The + // first should change the status to wifi_tether_starting, and the second should not change + // this. receiveApStateChangedBroadcast(WifiManager.WIFI_AP_STATE_ENABLING); assertThat(mPreference.getSummary().toString()).isEqualTo( - RuntimeEnvironment.application.getString(R.string.wifi_hotspot_off_subtext)); + RuntimeEnvironment.application.getString(R.string.wifi_tether_starting)); receiveApStateChangedBroadcast(WifiManager.WIFI_AP_STATE_ENABLED); assertThat(mPreference.getSummary().toString()).isEqualTo( - RuntimeEnvironment.application.getString(R.string.wifi_hotspot_off_subtext)); + RuntimeEnvironment.application.getString(R.string.wifi_tether_starting)); } @Test From 781e762c2c68027c6b4bf8bcb71979c5e8c595c3 Mon Sep 17 00:00:00 2001 From: Zhijun He Date: Thu, 14 Sep 2017 12:01:42 -0700 Subject: [PATCH 15/23] Revert "Settings: Enable HAL HDR+ by default" This reverts commit 14c4b41f789541628070f3a2d23207239d4f7ae8. Bug: 65679683 --- .../development/CameraHalHdrplusPreferenceController.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/com/android/settings/development/CameraHalHdrplusPreferenceController.java b/src/com/android/settings/development/CameraHalHdrplusPreferenceController.java index a4f087a97f2..e8e2c2d8da1 100644 --- a/src/com/android/settings/development/CameraHalHdrplusPreferenceController.java +++ b/src/com/android/settings/development/CameraHalHdrplusPreferenceController.java @@ -102,6 +102,6 @@ public class CameraHalHdrplusPreferenceController extends AbstractPreferenceCont } private boolean isHalHdrplusEnabled() { - return SystemProperties.getBoolean(PROPERTY_CAMERA_HAL_HDRPLUS, true); + return SystemProperties.getBoolean(PROPERTY_CAMERA_HAL_HDRPLUS, false); } } From 6bbc459f24c9d1da148a02cc3a5154c65154417f Mon Sep 17 00:00:00 2001 From: Matthew Fritze Date: Tue, 22 Aug 2017 15:51:50 -0700 Subject: [PATCH 16/23] Simplify IndexData builder This is a small refactor in the large game of refactoring DatabeseIndexingManager, and the general indexing pipeline for Settings search. This change is centered around hiding the normalization of data (title, summary, keywords) from the data collector, and putting that responsibility into the IndexData object. In a future CL, we may move this again to the controller that actually indexes the data. Note, the conversion from PreIndexData to IndexData is still messy, but until I can write a CL that just rearranges the code, we must stay patient and vigilant. Bug: 33577327 Test: make RunSettingsRoboTests Change-Id: I53543d3d9c74a61380601297c55b6e4fea13031a --- .../search/DatabaseIndexingManager.java | 2 +- .../search/DatabaseIndexingUtils.java | 32 ----- .../settings/search/indexing/IndexData.java | 113 ++++++++++-------- .../search/indexing/IndexDataConverter.java | 76 +++++------- .../search/DatabaseIndexingManagerTest.java | 8 +- .../search/DatabaseResultLoaderTest.java | 5 +- .../indexing/IndexDataConverterTest.java | 45 ------- .../search/indexing/IndexDataTest.java | 35 ++---- 8 files changed, 106 insertions(+), 210 deletions(-) diff --git a/src/com/android/settings/search/DatabaseIndexingManager.java b/src/com/android/settings/search/DatabaseIndexingManager.java index 9c79885602a..de71f0a6539 100644 --- a/src/com/android/settings/search/DatabaseIndexingManager.java +++ b/src/com/android/settings/search/DatabaseIndexingManager.java @@ -362,4 +362,4 @@ public class DatabaseIndexingManager { } } } -} +} \ No newline at end of file diff --git a/src/com/android/settings/search/DatabaseIndexingUtils.java b/src/com/android/settings/search/DatabaseIndexingUtils.java index f43f210ec27..ce58256a1f1 100644 --- a/src/com/android/settings/search/DatabaseIndexingUtils.java +++ b/src/com/android/settings/search/DatabaseIndexingUtils.java @@ -17,16 +17,10 @@ package com.android.settings.search; -import android.Manifest; import android.content.Context; import android.content.Intent; -import android.content.pm.ApplicationInfo; -import android.content.pm.PackageInfo; -import android.content.pm.PackageManager; -import android.content.pm.ResolveInfo; import android.net.Uri; import android.os.Bundle; -import android.text.TextUtils; import android.util.ArrayMap; import android.util.Log; @@ -37,10 +31,8 @@ import com.android.settings.core.PreferenceControllerMixin; import com.android.settingslib.core.AbstractPreferenceController; import java.lang.reflect.Field; -import java.text.Normalizer; import java.util.List; import java.util.Map; -import java.util.regex.Pattern; /** * Utility class for {@like DatabaseIndexingManager} to handle the mapping between Payloads @@ -53,15 +45,6 @@ public class DatabaseIndexingUtils { private static final String FIELD_NAME_SEARCH_INDEX_DATA_PROVIDER = "SEARCH_INDEX_DATA_PROVIDER"; - private static final String NON_BREAKING_HYPHEN = "\u2011"; - private static final String EMPTY = ""; - private static final String LIST_DELIMITERS = "[,]\\s*"; - private static final String HYPHEN = "-"; - private static final String SPACE = " "; - - private static final Pattern REMOVE_DIACRITICALS_PATTERN - = Pattern.compile("\\p{InCombiningDiacriticalMarks}+"); - /** * Builds intent into a subsetting. */ @@ -173,19 +156,4 @@ public class DatabaseIndexingUtils { } return null; } - - public static String normalizeHyphen(String input) { - return (input != null) ? input.replaceAll(NON_BREAKING_HYPHEN, HYPHEN) : EMPTY; - } - - public static String normalizeString(String input) { - final String nohyphen = (input != null) ? input.replaceAll(HYPHEN, EMPTY) : EMPTY; - final String normalized = Normalizer.normalize(nohyphen, Normalizer.Form.NFD); - - return REMOVE_DIACRITICALS_PATTERN.matcher(normalized).replaceAll("").toLowerCase(); - } - - public static String normalizeKeywords(String input) { - return (input != null) ? input.replaceAll(LIST_DELIMITERS, SPACE) : EMPTY; - } } diff --git a/src/com/android/settings/search/indexing/IndexData.java b/src/com/android/settings/search/indexing/IndexData.java index b0c79f368b6..c05c95d51df 100644 --- a/src/com/android/settings/search/indexing/IndexData.java +++ b/src/com/android/settings/search/indexing/IndexData.java @@ -27,7 +27,9 @@ import com.android.settings.search.ResultPayload; import com.android.settings.search.ResultPayloadUtils; import com.android.settings.search.SearchIndexableResources; +import java.text.Normalizer; import java.util.Objects; +import java.util.regex.Pattern; /** * Data class representing a single row in the Setting Search results database. @@ -38,14 +40,11 @@ public class IndexData { public final String normalizedTitle; public final String updatedSummaryOn; public final String normalizedSummaryOn; - public final String updatedSummaryOff; - public final String normalizedSummaryOff; public final String entries; public final String className; public final String childClassName; public final String screenTitle; public final int iconResId; - public final int rank; public final String spaceDelimitedKeywords; public final String intentAction; public final String intentTargetPackage; @@ -56,21 +55,28 @@ public class IndexData { public final int payloadType; public final byte[] payload; + private static final String NON_BREAKING_HYPHEN = "\u2011"; + private static final String EMPTY = ""; + private static final String HYPHEN = "-"; + private static final String SPACE = " "; + // Regex matching a comma, and any number of subsequent white spaces. + private static final String LIST_DELIMITERS = "[,]\\s*"; + + private static final Pattern REMOVE_DIACRITICALS_PATTERN + = Pattern.compile("\\p{InCombiningDiacriticalMarks}+"); + private IndexData(Builder builder) { locale = builder.mLocale; - updatedTitle = builder.mUpdatedTitle; - normalizedTitle = builder.mNormalizedTitle; - updatedSummaryOn = builder.mUpdatedSummaryOn; - normalizedSummaryOn = builder.mNormalizedSummaryOn; - updatedSummaryOff = builder.mUpdatedSummaryOff; - normalizedSummaryOff = builder.mNormalizedSummaryOff; + updatedTitle = normalizeHyphen(builder.mTitle); + normalizedTitle = normalizeString(builder.mTitle); + updatedSummaryOn = normalizeHyphen(builder.mSummaryOn); + normalizedSummaryOn = normalizeString(builder.mSummaryOn); entries = builder.mEntries; className = builder.mClassName; childClassName = builder.mChildClassName; screenTitle = builder.mScreenTitle; iconResId = builder.mIconResId; - rank = builder.mRank; - spaceDelimitedKeywords = builder.mSpaceDelimitedKeywords; + spaceDelimitedKeywords = normalizeKeywords(builder.mKeywords); intentAction = builder.mIntentAction; intentTargetPackage = builder.mIntentTargetPackage; intentTargetClass = builder.mIntentTargetClass; @@ -93,21 +99,49 @@ public class IndexData { : key.hashCode(); } + @Override + public String toString() { + return new StringBuilder(updatedTitle) + .append(": ") + .append(updatedSummaryOn) + .toString(); + } + + /** + * In the list of keywords, replace the comma and all subsequent whitespace with a single space. + */ + public static String normalizeKeywords(String input) { + return (input != null) ? input.replaceAll(LIST_DELIMITERS, SPACE) : EMPTY; + } + + /** + * @return {@param input} where all non-standard hyphens are replaced by normal hyphens. + */ + public static String normalizeHyphen(String input) { + return (input != null) ? input.replaceAll(NON_BREAKING_HYPHEN, HYPHEN) : EMPTY; + } + + /** + * @return {@param input} with all hyphens removed, and all letters lower case. + */ + public static String normalizeString(String input) { + final String normalizedHypen = normalizeHyphen(input); + final String nohyphen = (input != null) ? normalizedHypen.replaceAll(HYPHEN, EMPTY) : EMPTY; + final String normalized = Normalizer.normalize(nohyphen, Normalizer.Form.NFD); + + return REMOVE_DIACRITICALS_PATTERN.matcher(normalized).replaceAll("").toLowerCase(); + } + public static class Builder { private String mLocale; - private String mUpdatedTitle; - private String mNormalizedTitle; - private String mUpdatedSummaryOn; - private String mNormalizedSummaryOn; - private String mUpdatedSummaryOff; - private String mNormalizedSummaryOff; + private String mTitle; + private String mSummaryOn; private String mEntries; private String mClassName; private String mChildClassName; private String mScreenTitle; private int mIconResId; - private int mRank; - private String mSpaceDelimitedKeywords; + private String mKeywords; private String mIntentAction; private String mIntentTargetPackage; private String mIntentTargetClass; @@ -123,33 +157,13 @@ public class IndexData { return this; } - public Builder setUpdatedTitle(String updatedTitle) { - mUpdatedTitle = updatedTitle; + public Builder setTitle(String title) { + mTitle = title; return this; } - public Builder setNormalizedTitle(String normalizedTitle) { - mNormalizedTitle = normalizedTitle; - return this; - } - - public Builder setUpdatedSummaryOn(String updatedSummaryOn) { - mUpdatedSummaryOn = updatedSummaryOn; - return this; - } - - public Builder setNormalizedSummaryOn(String normalizedSummaryOn) { - mNormalizedSummaryOn = normalizedSummaryOn; - return this; - } - - public Builder setUpdatedSummaryOff(String updatedSummaryOff) { - mUpdatedSummaryOff = updatedSummaryOff; - return this; - } - - public Builder setNormalizedSummaryOff(String normalizedSummaryOff) { - this.mNormalizedSummaryOff = normalizedSummaryOff; + public Builder setSummaryOn(String summaryOn) { + mSummaryOn = summaryOn; return this; } @@ -178,13 +192,8 @@ public class IndexData { return this; } - public Builder setRank(int rank) { - mRank = rank; - return this; - } - - public Builder setSpaceDelimitedKeywords(String spaceDelimitedKeywords) { - mSpaceDelimitedKeywords = spaceDelimitedKeywords; + public Builder setKeywords(String keywords) { + mKeywords = keywords; return this; } @@ -260,8 +269,8 @@ public class IndexData { boolean isEmptyIntentAction = TextUtils.isEmpty(mIntentAction); // No intent action is set, or the intent action is for a subsetting. if (isEmptyIntentAction - || (!isEmptyIntentAction && TextUtils.equals(mIntentTargetPackage, - SearchIndexableResources.SUBSETTING_TARGET_PACKAGE))) { + || TextUtils.equals(mIntentTargetPackage, + SearchIndexableResources.SUBSETTING_TARGET_PACKAGE)) { // Action is null, we will launch it as a sub-setting intent = DatabaseIndexingUtils.buildSubsettingIntent(context, mClassName, mKey, mScreenTitle); diff --git a/src/com/android/settings/search/indexing/IndexDataConverter.java b/src/com/android/settings/search/indexing/IndexDataConverter.java index 3c602f67098..f900b83cdc6 100644 --- a/src/com/android/settings/search/indexing/IndexDataConverter.java +++ b/src/com/android/settings/search/indexing/IndexDataConverter.java @@ -147,12 +147,14 @@ public class IndexDataConverter { } IndexData.Builder builder = new IndexData.Builder(); - builder.setLocale(localeStr) + builder.setTitle(raw.title) + .setSummaryOn(raw.summaryOn) + .setLocale(localeStr) .setEntries(raw.entries) + .setKeywords(raw.keywords) .setClassName(raw.className) .setScreenTitle(raw.screenTitle) .setIconResId(raw.iconResId) - .setRank(raw.rank) .setIntentAction(raw.intentAction) .setIntentTargetPackage(raw.intentTargetPackage) .setIntentTargetClass(raw.intentTargetClass) @@ -160,8 +162,7 @@ public class IndexDataConverter { .setKey(raw.key) .setUserId(raw.userId); - updateOneRowWithFilteredData(builder, raw.title, raw.summaryOn, raw.summaryOff, - raw.keywords); + updateOneRow(builder.build(mContext)); } @VisibleForTesting @@ -249,7 +250,6 @@ public class IndexDataConverter { ResultPayload payload; boolean enabled; final String fragmentName = sir.className; - final int rank = sir.rank; final String intentAction = sir.intentAction; final String intentTargetPackage = sir.intentTargetPackage; final String intentTargetClass = sir.intentTargetClass; @@ -271,11 +271,12 @@ public class IndexDataConverter { // TODO: Set payload type for header results IndexData.Builder headerBuilder = new IndexData.Builder(); - headerBuilder.setLocale(localeStr) - .setEntries(null) + headerBuilder.setTitle(headerTitle) + .setSummaryOn(headerSummary) + .setKeywords(headerKeywords) + .setLocale(localeStr) .setClassName(fragmentName) .setScreenTitle(screenTitle) - .setRank(rank) .setIntentAction(intentAction) .setIntentTargetPackage(intentTargetPackage) .setIntentTargetClass(intentTargetClass) @@ -306,11 +307,12 @@ public class IndexDataConverter { } builder = new IndexData.Builder(); - builder.setLocale(localeStr) + builder.setTitle(title) + .setLocale(localeStr) + .setKeywords(keywords) .setClassName(fragmentName) .setScreenTitle(screenTitle) .setIconResId(iconResId) - .setRank(rank) .setIntentAction(intentAction) .setIntentTargetPackage(intentTargetPackage) .setIntentTargetClass(intentTargetClass) @@ -331,14 +333,17 @@ public class IndexDataConverter { payload = DatabaseIndexingUtils.getPayloadFromUriMap(controllerUriMap, key); childFragment = XmlParserUtils.getDataChildFragment(context, attrs); - builder.setEntries(entries) + builder.setSummaryOn(summary) + .setEntries(entries) .setChildClassName(childFragment) .setPayload(payload); // Insert rows for the child nodes of PreferenceScreen - updateOneRowWithFilteredData(builder, title, summary, - null /* summary off */, keywords); + updateOneRow(builder.build(mContext)); } else { + // TODO (b/33577327) We removed summary off here. We should check if we can + // merge this 'else' section with the one above. Put a break point to + // investigate. String summaryOn = XmlParserUtils.getDataSummaryOn(context, attrs); String summaryOff = XmlParserUtils.getDataSummaryOff(context, attrs); @@ -346,15 +351,15 @@ public class IndexDataConverter { summaryOn = XmlParserUtils.getDataSummary(context, attrs); } - updateOneRowWithFilteredData(builder, title, summaryOn, summaryOff, - keywords); + builder.setSummaryOn(summaryOn); + + updateOneRow(builder.build(mContext)); } } // The xml header's title does not match the title of one of the child settings. if (isHeaderUnique) { - updateOneRowWithFilteredData(headerBuilder, headerTitle, headerSummary, - null /* summary off */, headerKeywords); + updateOneRow(headerBuilder.build(mContext)); } } catch (XmlPullParserException e) { throw new RuntimeException("Error parsing PreferenceScreen", e); @@ -394,8 +399,11 @@ public class IndexDataConverter { boolean enabled = !nonIndexableKeys.contains(raw.key); IndexData.Builder builder = new IndexData.Builder(); - builder.setLocale(localeStr) + builder.setTitle(raw.title) + .setSummaryOn(raw.summaryOn) + .setLocale(localeStr) .setEntries(raw.entries) + .setKeywords(raw.keywords) .setClassName(className) .setScreenTitle(raw.screenTitle) .setIconResId(raw.iconResId) @@ -406,8 +414,7 @@ public class IndexDataConverter { .setKey(raw.key) .setUserId(raw.userId); - updateOneRowWithFilteredData(builder, raw.title, raw.summaryOn, raw.summaryOff, - raw.keywords); + updateOneRow(builder.build(mContext)); } } @@ -438,32 +445,6 @@ public class IndexDataConverter { } } - @VisibleForTesting - void updateOneRowWithFilteredData(IndexData.Builder builder, - String title, String summaryOn, String summaryOff, String keywords) { - - final String updatedTitle = DatabaseIndexingUtils.normalizeHyphen(title); - final String updatedSummaryOn = DatabaseIndexingUtils.normalizeHyphen(summaryOn); - final String updatedSummaryOff = DatabaseIndexingUtils.normalizeHyphen(summaryOff); - - final String normalizedTitle = DatabaseIndexingUtils.normalizeString(updatedTitle); - final String normalizedSummaryOn = DatabaseIndexingUtils.normalizeString(updatedSummaryOn); - final String normalizedSummaryOff = DatabaseIndexingUtils - .normalizeString(updatedSummaryOff); - - final String spaceDelimitedKeywords = DatabaseIndexingUtils.normalizeKeywords(keywords); - - builder.setUpdatedTitle(updatedTitle) - .setUpdatedSummaryOn(updatedSummaryOn) - .setUpdatedSummaryOff(updatedSummaryOff) - .setNormalizedTitle(normalizedTitle) - .setNormalizedSummaryOn(normalizedSummaryOn) - .setNormalizedSummaryOff(normalizedSummaryOff) - .setSpaceDelimitedKeywords(spaceDelimitedKeywords); - - updateOneRow(builder.build(mContext)); - } - private void updateOneRow(IndexData row) { if (TextUtils.isEmpty(row.updatedTitle)) { return; @@ -472,13 +453,10 @@ public class IndexDataConverter { ContentValues values = new ContentValues(); values.put(IndexDatabaseHelper.IndexColumns.DOCID, row.getDocId()); values.put(LOCALE, row.locale); - values.put(DATA_RANK, row.rank); values.put(DATA_TITLE, row.updatedTitle); values.put(DATA_TITLE_NORMALIZED, row.normalizedTitle); values.put(DATA_SUMMARY_ON, row.updatedSummaryOn); values.put(DATA_SUMMARY_ON_NORMALIZED, row.normalizedSummaryOn); - values.put(DATA_SUMMARY_OFF, row.updatedSummaryOff); - values.put(DATA_SUMMARY_OFF_NORMALIZED, row.normalizedSummaryOff); values.put(DATA_ENTRIES, row.entries); values.put(DATA_KEYWORDS, row.spaceDelimitedKeywords); values.put(CLASS_NAME, row.className); diff --git a/tests/robotests/src/com/android/settings/search/DatabaseIndexingManagerTest.java b/tests/robotests/src/com/android/settings/search/DatabaseIndexingManagerTest.java index db4aff7a13d..420fae9117e 100644 --- a/tests/robotests/src/com/android/settings/search/DatabaseIndexingManagerTest.java +++ b/tests/robotests/src/com/android/settings/search/DatabaseIndexingManagerTest.java @@ -27,7 +27,6 @@ import static org.mockito.Mockito.doNothing; import static org.mockito.Mockito.doReturn; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.spy; -import static org.mockito.Mockito.times; import static org.mockito.Mockito.verify; import android.content.ContentValues; @@ -287,6 +286,7 @@ public class DatabaseIndexingManagerTest { @Test public void testLocaleUpdated_afterFullIndexing_localeAdded() { mManager.performIndexing(); + assertThat(IndexDatabaseHelper.isLocaleAlreadyIndexed(mContext, localeStr)).isTrue(); } @@ -302,8 +302,6 @@ public class DatabaseIndexingManagerTest { // Locale assertThat(cursor.getString(0)).isEqualTo(localeStr); - // Data Rank - assertThat(cursor.getInt(1)).isEqualTo(rank); // Data Title assertThat(cursor.getString(2)).isEqualTo(updatedTitle); // Normalized Title @@ -312,10 +310,6 @@ public class DatabaseIndexingManagerTest { assertThat(cursor.getString(4)).isEqualTo(updatedSummaryOn); // Summary On Normalized assertThat(cursor.getString(5)).isEqualTo(normalizedSummaryOn); - // Summary Off - assertThat(cursor.getString(6)).isEqualTo(updatedSummaryOff); - // Summary off normalized - assertThat(cursor.getString(7)).isEqualTo(normalizedSummaryOff); // Entries assertThat(cursor.getString(8)).isEqualTo(entries); // Keywords diff --git a/tests/robotests/src/com/android/settings/search/DatabaseResultLoaderTest.java b/tests/robotests/src/com/android/settings/search/DatabaseResultLoaderTest.java index 90f6e87907e..dd7b7a97f9d 100644 --- a/tests/robotests/src/com/android/settings/search/DatabaseResultLoaderTest.java +++ b/tests/robotests/src/com/android/settings/search/DatabaseResultLoaderTest.java @@ -24,6 +24,7 @@ import android.database.sqlite.SQLiteDatabase; import com.android.settings.TestConfig; import com.android.settings.dashboard.SiteMapManager; +import com.android.settings.search.indexing.IndexData; import com.android.settings.testutils.DatabaseTestUtils; import com.android.settings.testutils.FakeFeatureFactory; import com.android.settings.testutils.SettingsRobolectricTestRunner; @@ -227,8 +228,8 @@ public class DatabaseResultLoaderTest { } private void insertSpecialCase(String specialCase) { - String normalized = DatabaseIndexingUtils.normalizeHyphen(specialCase); - normalized = DatabaseIndexingUtils.normalizeString(normalized); + String normalized = IndexData.normalizeHyphen(specialCase); + normalized = IndexData.normalizeString(normalized); final ResultPayload payload = new ResultPayload(new Intent()); ContentValues values = new ContentValues(); diff --git a/tests/robotests/src/com/android/settings/search/indexing/IndexDataConverterTest.java b/tests/robotests/src/com/android/settings/search/indexing/IndexDataConverterTest.java index 89aa62ec2c6..ca04d2c6826 100644 --- a/tests/robotests/src/com/android/settings/search/indexing/IndexDataConverterTest.java +++ b/tests/robotests/src/com/android/settings/search/indexing/IndexDataConverterTest.java @@ -54,7 +54,6 @@ public class IndexDataConverterTest { private final String localeStr = "en_US"; - private final int rank = 8; private final String title = "title\u2011title"; private final String updatedTitle = "title-title"; private final String normalizedTitle = "titletitle"; @@ -128,8 +127,6 @@ public class IndexDataConverterTest { // Locale assertThat(cursor.getString(0)).isEqualTo(localeStr); - // Data Rank - assertThat(cursor.getInt(1)).isEqualTo(raw.rank); // Data Title assertThat(cursor.getString(2)).isEqualTo(updatedTitle); // Normalized Title @@ -138,10 +135,6 @@ public class IndexDataConverterTest { assertThat(cursor.getString(4)).isEqualTo(updatedSummaryOn); // Summary On Normalized assertThat(cursor.getString(5)).isEqualTo(normalizedSummaryOn); - // Summary Off - assertThat(cursor.getString(6)).isEqualTo(updatedSummaryOff); - // Summary off normalized - assertThat(cursor.getString(7)).isEqualTo(normalizedSummaryOff); // Entries assertThat(cursor.getString(8)).isEqualTo(raw.entries); // Keywords @@ -225,8 +218,6 @@ public class IndexDataConverterTest { // Locale assertThat(cursor.getString(0)).isEqualTo(localeStr); - // Data Rank - assertThat(cursor.getInt(1)).isEqualTo(rank); // Data Title assertThat(cursor.getString(2)).isEqualTo("App info"); // Normalized Title @@ -235,10 +226,6 @@ public class IndexDataConverterTest { assertThat(cursor.getString(4)).isEqualTo("Manage apps, set up quick launch shortcuts"); // Summary On Normalized assertThat(cursor.getString(5)).isEqualTo("manage apps, set up quick launch shortcuts"); - // Summary Off - only on for checkbox preferences - assertThat(cursor.getString(6)).isEmpty(); - // Summary off normalized - only on for checkbox preferences - assertThat(cursor.getString(7)).isEmpty(); // Entries - only on for list preferences assertThat(cursor.getString(8)).isNull(); // Keywords @@ -285,8 +272,6 @@ public class IndexDataConverterTest { // Locale assertThat(cursor.getString(0)).isEqualTo(localeStr); - // Data Rank - assertThat(cursor.getInt(1)).isEqualTo(rank); // Data Title assertThat(cursor.getString(2)).isEqualTo(prefTitle); // Normalized Title @@ -295,10 +280,6 @@ public class IndexDataConverterTest { assertThat(cursor.getString(4)).isEqualTo(prefSummary); // Summary On Normalized assertThat(cursor.getString(5)).isEqualTo(prefSummary.toLowerCase()); - // Summary Off - only on for checkbox preferences - assertThat(cursor.getString(6)).isEmpty(); - // Summary off normalized - only on for checkbox preferences - assertThat(cursor.getString(7)).isEmpty(); // Entries - only on for list preferences assertThat(cursor.getString(8)).isNull(); // Keywords @@ -343,8 +324,6 @@ public class IndexDataConverterTest { cursor.moveToPosition(0); // Locale assertThat(cursor.getString(0)).isEqualTo(localeStr); - // Data Rank - assertThat(cursor.getInt(1)).isEqualTo(rank); // Data Title assertThat(cursor.getString(2)).isEqualTo("Advanced settings"); // Normalized Title @@ -353,10 +332,6 @@ public class IndexDataConverterTest { assertThat(cursor.getString(4)).isEqualTo("Enable more settings options"); // Summary On Normalized assertThat(cursor.getString(5)).isEqualTo("enable more settings options"); - // Summary Off - assertThat(cursor.getString(6)).isEqualTo("Enable more settings options"); - // Summary Off - assertThat(cursor.getString(7)).isEqualTo("enable more settings options"); // Entries - only on for list preferences assertThat(cursor.getString(8)).isNull(); // Keywords @@ -397,8 +372,6 @@ public class IndexDataConverterTest { cursor.moveToPosition(3); // Locale assertThat(cursor.getString(0)).isEqualTo(localeStr); - // Data Rank - assertThat(cursor.getInt(1)).isEqualTo(rank); // Data Title assertThat(cursor.getString(2)).isEqualTo("Preferred install location"); // Normalized Title @@ -409,10 +382,6 @@ public class IndexDataConverterTest { // Summary On Normalized assertThat(cursor.getString(5)).isEqualTo( "change the preferred installation location for new apps"); - // Summary Off - only on for checkbox preferences - assertThat(cursor.getString(6)).isEmpty(); - // Summary off normalized - only on for checkbox preferences - assertThat(cursor.getString(7)).isEmpty(); // Entries - only on for list preferences assertThat(cursor.getString(8)).isEqualTo("Internal device storage|Removable SD card|" + "Let the system decide|"); @@ -483,8 +452,6 @@ public class IndexDataConverterTest { // Locale assertThat(cursor.getString(0)).isEqualTo(localeStr); - // Data Rank - assertThat(cursor.getInt(1)).isEqualTo(0); // Data Title assertThat(cursor.getString(2)).isEqualTo("Display size"); // Normalized Title @@ -493,10 +460,6 @@ public class IndexDataConverterTest { assertThat(cursor.getString(4)).isEmpty(); // Summary On Normalized assertThat(cursor.getString(5)).isEmpty(); - // Summary Off - only on for checkbox preferences - assertThat(cursor.getString(6)).isEmpty(); - // Summary off normalized - only on for checkbox preferences - assertThat(cursor.getString(7)).isEmpty(); // Entries - only on for list preferences assertThat(cursor.getString(8)).isNull(); // Keywords @@ -550,8 +513,6 @@ public class IndexDataConverterTest { // Locale assertThat(cursor.getString(0)).isEqualTo(localeStr); - // Data Rank - assertThat(cursor.getInt(1)).isEqualTo(0); // Data Title assertThat(cursor.getString(2)).isEqualTo("Display size"); // Normalized Title @@ -560,10 +521,6 @@ public class IndexDataConverterTest { assertThat(cursor.getString(4)).isEmpty(); // Summary On Normalized assertThat(cursor.getString(5)).isEmpty(); - // Summary Off - only on for checkbox preferences - assertThat(cursor.getString(6)).isEmpty(); - // Summary off normalized - only on for checkbox preferences - assertThat(cursor.getString(7)).isEmpty(); // Entries - only on for list preferences assertThat(cursor.getString(8)).isNull(); // Keywords @@ -646,7 +603,6 @@ public class IndexDataConverterTest { private SearchIndexableRaw getFakeRaw(String localeStr) { SearchIndexableRaw data = new SearchIndexableRaw(mContext); data.locale = new Locale(localeStr); - data.rank = rank; data.title = title; data.summaryOn = summaryOn; data.summaryOff = summaryOff; @@ -667,7 +623,6 @@ public class IndexDataConverterTest { private SearchIndexableResource getFakeResource(int xml) { SearchIndexableResource sir = new SearchIndexableResource(mContext); - sir.rank = rank; sir.xmlResId = xml; sir.className = className; sir.packageName = packageName; diff --git a/tests/robotests/src/com/android/settings/search/indexing/IndexDataTest.java b/tests/robotests/src/com/android/settings/search/indexing/IndexDataTest.java index 40be4f2a98b..ae9d99842c4 100644 --- a/tests/robotests/src/com/android/settings/search/indexing/IndexDataTest.java +++ b/tests/robotests/src/com/android/settings/search/indexing/IndexDataTest.java @@ -41,17 +41,16 @@ public class IndexDataTest { private IndexData.Builder mBuilder; private static final String LOCALE = "locale"; - private static final String UPDATED_TITLE = "updated title"; - private static final String NORMALIZED_TITLE = "normal title"; - private static final String UPDATED_SUMMARY_ON = "updated summary on"; - private static final String NORMALIZED_SUMMARY_ON = "normalized summary on"; - private static final String UPDATED_SUMMARY_OFF = "updated summary off"; - private static final String NORMALIZED_SUMMARY_OFF = "normalized summary off"; + private static final String TITLE = "updated-title"; + private static final String NORM_TITLE = "updatedtitle"; + private static final String SUMMARY_ON = "updated-summary-on"; + private static final String NORM_SUMMARY_ON = "updatedsummaryon"; + private static final String SUMMARY_OFF = "updated-summary-off"; + private static final String NORM_SUMMARY_OFF = "updatedsummaryoff"; private static final String ENTRIES = "entries"; private static final String CLASS_NAME = "class name"; private static final String SCREEN_TITLE = "screen title"; private static final int ICON_RES_ID = 0xff; - private static final int RANK = 1; private static final String SPACE_DELIMITED_KEYWORDS = "keywords"; private static final String INTENT_ACTION = "intent action"; private static final String INTENT_TARGET_PACKAGE = "target package"; @@ -79,17 +78,14 @@ public class IndexDataTest { IndexData row = generateRow(); assertThat(row.locale).isEqualTo(LOCALE); - assertThat(row.updatedTitle).isEqualTo(UPDATED_TITLE); - assertThat(row.normalizedTitle).isEqualTo(NORMALIZED_TITLE); - assertThat(row.updatedSummaryOn).isEqualTo(UPDATED_SUMMARY_ON); - assertThat(row.normalizedSummaryOn).isEqualTo(NORMALIZED_SUMMARY_ON); - assertThat(row.updatedSummaryOff).isEqualTo(UPDATED_SUMMARY_OFF); - assertThat(row.normalizedSummaryOff).isEqualTo(NORMALIZED_SUMMARY_OFF); + assertThat(row.updatedTitle).isEqualTo(TITLE); + assertThat(row.normalizedTitle).isEqualTo(NORM_TITLE); + assertThat(row.updatedSummaryOn).isEqualTo(SUMMARY_ON); + assertThat(row.normalizedSummaryOn).isEqualTo(NORM_SUMMARY_ON); assertThat(row.entries).isEqualTo(ENTRIES); assertThat(row.className).isEqualTo(CLASS_NAME); assertThat(row.screenTitle).isEqualTo(SCREEN_TITLE); assertThat(row.iconResId).isEqualTo(ICON_RES_ID); - assertThat(row.rank).isEqualTo(RANK); assertThat(row.spaceDelimitedKeywords).isEqualTo(SPACE_DELIMITED_KEYWORDS); assertThat(row.intentAction).isEqualTo(INTENT_ACTION); assertThat(row.intentTargetClass).isEqualTo(INTENT_TARGET_CLASS); @@ -153,18 +149,13 @@ public class IndexDataTest { private IndexData.Builder createBuilder() { mBuilder = new IndexData.Builder(); mBuilder.setLocale(LOCALE) - .setUpdatedTitle(UPDATED_TITLE) - .setNormalizedTitle(NORMALIZED_TITLE) - .setUpdatedSummaryOn(UPDATED_SUMMARY_ON) - .setNormalizedSummaryOn(NORMALIZED_SUMMARY_ON) - .setUpdatedSummaryOff(UPDATED_SUMMARY_OFF) - .setNormalizedSummaryOff(NORMALIZED_SUMMARY_OFF) + .setTitle(TITLE) + .setSummaryOn(SUMMARY_ON) .setEntries(ENTRIES) .setClassName(CLASS_NAME) .setScreenTitle(SCREEN_TITLE) .setIconResId(ICON_RES_ID) - .setRank(RANK) - .setSpaceDelimitedKeywords(SPACE_DELIMITED_KEYWORDS) + .setKeywords(SPACE_DELIMITED_KEYWORDS) .setIntentAction(INTENT_ACTION) .setIntentTargetPackage(INTENT_TARGET_PACKAGE) .setIntentTargetClass(INTENT_TARGET_CLASS) From 230b3767d9737a4c434069075a8070ee171566e2 Mon Sep 17 00:00:00 2001 From: Fan Zhang Date: Thu, 14 Sep 2017 16:04:35 -0700 Subject: [PATCH 17/23] Add feature flag for suggestion/SettingsIntelligence integ. Bug: 65065268 Test: robotests Change-Id: I42e1f8b01d7b82de3b94bd77943a9a119adf5867 --- .../SuggestionControllerMixin.java | 12 ++++---- .../SuggestionControllerMixinTest.java | 28 +++++++++++++++---- 2 files changed, 30 insertions(+), 10 deletions(-) diff --git a/src/com/android/settings/dashboard/suggestions/SuggestionControllerMixin.java b/src/com/android/settings/dashboard/suggestions/SuggestionControllerMixin.java index 0142203499e..f58946dfa1c 100644 --- a/src/com/android/settings/dashboard/suggestions/SuggestionControllerMixin.java +++ b/src/com/android/settings/dashboard/suggestions/SuggestionControllerMixin.java @@ -26,6 +26,7 @@ import android.os.RemoteException; import android.service.settings.suggestions.ISuggestionService; import android.service.settings.suggestions.Suggestion; import android.support.annotation.VisibleForTesting; +import android.util.FeatureFlagUtils; import android.util.Log; import com.android.settingslib.core.lifecycle.Lifecycle; @@ -40,6 +41,8 @@ import java.util.List; */ public class SuggestionControllerMixin implements LifecycleObserver, OnStart, OnStop { + @VisibleForTesting + static final String FEATURE_FLAG = "new_settings_suggestion"; private static final String TAG = "SuggestionCtrlMixin"; private static final boolean DEBUG = false; @@ -49,6 +52,10 @@ public class SuggestionControllerMixin implements LifecycleObserver, OnStart, On private ISuggestionService mRemoteService; + public static boolean isEnabled() { + return FeatureFlagUtils.isEnabled(FEATURE_FLAG); + } + public SuggestionControllerMixin(Context context, Lifecycle lifecycle) { mContext = context.getApplicationContext(); mServiceIntent = new Intent().setComponent( @@ -79,11 +86,6 @@ public class SuggestionControllerMixin implements LifecycleObserver, OnStart, On } } - public boolean isEnabled() { - // TODO: Set up feature flag - return true; - } - /** * Get setting suggestions. */ diff --git a/tests/robotests/src/com/android/settings/dashboard/suggestions/SuggestionControllerMixinTest.java b/tests/robotests/src/com/android/settings/dashboard/suggestions/SuggestionControllerMixinTest.java index 10611846bc2..ac2026c0cc4 100644 --- a/tests/robotests/src/com/android/settings/dashboard/suggestions/SuggestionControllerMixinTest.java +++ b/tests/robotests/src/com/android/settings/dashboard/suggestions/SuggestionControllerMixinTest.java @@ -21,13 +21,15 @@ import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; import android.content.Context; -import android.os.RemoteException; import android.service.settings.suggestions.ISuggestionService; +import android.util.FeatureFlagUtils; import com.android.settings.TestConfig; import com.android.settings.testutils.SettingsRobolectricTestRunner; +import com.android.settings.testutils.shadow.SettingsShadowSystemProperties; import com.android.settingslib.core.lifecycle.Lifecycle; +import org.junit.After; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; @@ -37,7 +39,10 @@ import org.robolectric.annotation.Config; import org.robolectric.util.ReflectionHelpers; @RunWith(SettingsRobolectricTestRunner.class) -@Config(manifest = TestConfig.MANIFEST_PATH, sdk = TestConfig.SDK_VERSION) +@Config(manifest = TestConfig.MANIFEST_PATH, sdk = TestConfig.SDK_VERSION, + shadows = { + SettingsShadowSystemProperties.class + }) public class SuggestionControllerMixinTest { @Mock @@ -55,10 +60,23 @@ public class SuggestionControllerMixinTest { when(mContext.getApplicationContext()).thenReturn(mContext); } + @After + public void tearDown() { + SettingsShadowSystemProperties.clear(); + } + @Test - public void verifyIsEnabled() { - mMixin = new SuggestionControllerMixin(mContext, mLifecycle); - assertThat(mMixin.isEnabled()).isTrue(); + public void systemPropertySet_verifyIsEnabled() { + SettingsShadowSystemProperties.set( + FeatureFlagUtils.FFLAG_PREFIX + SuggestionControllerMixin.FEATURE_FLAG, "true"); + assertThat(SuggestionControllerMixin.isEnabled()).isTrue(); + } + + @Test + public void systemPropertyNotSet_verifyIsDisabled() { + SettingsShadowSystemProperties.set( + FeatureFlagUtils.FFLAG_PREFIX + SuggestionControllerMixin.FEATURE_FLAG, "false"); + assertThat(SuggestionControllerMixin.isEnabled()).isFalse(); } @Test From dee1a22c45c78dd1d4a681314045b0757b63623d Mon Sep 17 00:00:00 2001 From: Doris Ling Date: Thu, 31 Aug 2017 16:17:30 -0700 Subject: [PATCH 18/23] Consolidate all wrappers used for testing. - Add the wrapper package and move all wrappers to the wrapper package. - Get rid of some wrapper interface/impl implementation and have a wrapper class directly. Bug: 65634579 Test: make RunSettingsRoboTests Change-Id: Ic757d8f7bacfa7a034c7e692205bc1dc4b0e1de1 --- src/com/android/settings/Utils.java | 7 +- .../RemoveAccountPreferenceController.java | 5 +- .../AccessibilityServiceInfoWrapperImpl.java | 39 ------ .../applications/ActivityInfoWrapper.java | 30 ----- .../settings/applications/AppCounter.java | 2 + .../settings/applications/AppInfoBase.java | 5 +- .../settings/applications/AppLister.java | 2 + .../applications/AppStateAppOpsBridge.java | 3 +- ...AppWithAdminGrantedPermissionsCounter.java | 4 +- .../AppWithAdminGrantedPermissionsLister.java | 4 +- .../ApplicationFeatureProviderImpl.java | 4 +- .../AutofillManagerWrapperImpl.java | 45 ------- .../IPackageManagerWrapperImpl.java | 67 ---------- .../applications/InstalledAppCounter.java | 2 + .../applications/InstalledAppDetails.java | 4 +- .../applications/InstalledAppLister.java | 2 + .../applications/ManageApplications.java | 5 +- .../applications/NotificationApps.java | 3 +- .../applications/PackageManagerWrapper.java | 116 ---------------- .../PackageManagerWrapperImpl.java | 112 ---------------- .../PictureInPictureSettings.java | 3 +- .../RecentAppsPreferenceController.java | 3 +- .../applications/UserManagerWrapper.java | 32 ----- .../assist/DefaultVoiceInputPicker.java | 2 +- .../defaultapps/DefaultAppInfo.java | 2 +- .../defaultapps/DefaultAppPickerFragment.java | 5 +- .../DefaultAppPreferenceController.java | 5 +- .../DefaultAutofillPreferenceController.java | 5 +- .../DefaultHomePreferenceController.java | 2 +- .../InstantAppButtonsController.java | 5 +- .../suggestions/SuggestionsChecks.java | 1 + .../settings/datausage/AppDataUsage.java | 5 +- .../PrivateVolumeOptionMenuController.java | 2 +- .../deviceinfo/StorageDashboardFragment.java | 15 +-- .../deviceinfo/StorageProfileFragment.java | 8 +- .../storage/SecondaryUserController.java | 2 +- .../storage/StorageAsyncLoader.java | 4 +- .../storage/UserProfileController.java | 2 +- .../BrightnessLevelPreferenceController.java | 1 + .../DevicePolicyManagerWrapperImpl.java | 125 ------------------ .../EnterprisePrivacyFeatureProviderImpl.java | 5 +- .../fingerprint/FingerprintEnrollSidecar.java | 5 +- .../fuelgauge/AdvancedPowerUsageDetail.java | 5 +- .../AppButtonsPreferenceController.java | 2 +- ...ackgroundActivityPreferenceController.java | 5 +- .../anomaly/AnomalyDetectionPolicy.java | 4 +- .../KeyValueListParserWrapperImpl.java | 50 ------- .../MobileNetworkPreferenceController.java | 1 + .../settings/network/NetworkScorerPicker.java | 1 + ...tworkScorerPickerPreferenceController.java | 1 + .../settings/overlay/FeatureFactoryImpl.java | 20 +-- .../password/IFingerprintManager.java | 39 ------ .../password/SetNewPasswordController.java | 7 +- .../search/InstalledAppResultLoader.java | 2 +- .../search/SearchFeatureProviderImpl.java | 4 +- .../vpn2/ConnectivityManagerWrapperImpl.java | 59 --------- src/com/android/settings/vpn2/VpnUtils.java | 1 + .../settings/webview/WebViewAppPicker.java | 3 +- .../webview/WebViewUpdateServiceWrapper.java | 2 + .../settings/wifi/ConfigureWifiSettings.java | 2 +- .../wifi/ConnectivityManagerWrapper.java | 36 ----- .../wifi/UseOpenWifiPreferenceController.java | 2 +- .../android/settings/wifi/WifiEnabler.java | 1 + .../android/settings/wifi/WifiSettings.java | 1 + .../wifi/WifiWakeupPreferenceController.java | 2 +- .../wifi/WriteWifiConfigToNfcDialog.java | 2 +- .../WifiDetailPreferenceController.java | 2 +- .../details/WifiNetworkDetailsFragment.java | 4 +- .../AccessibilityManagerWrapper.java} | 4 +- .../AccessibilityServiceInfoWrapper.java | 22 ++- .../ActivityInfoWrapper.java} | 15 ++- .../AutofillManagerWrapper.java | 30 ++++- .../ConnectivityManagerWrapper.java | 39 ++++-- .../DevicePolicyManagerWrapper.java | 90 +++++++++---- .../FingerprintManagerWrapper.java | 17 ++- .../IPackageManagerWrapper.java | 42 ++++-- .../KeyValueListParserWrapper.java | 27 +++- .../NetworkScoreManagerWrapper.java | 2 +- .../PowerManagerWrapper.java | 2 +- .../RestrictedLockUtilsWrapper.java | 2 +- .../UserManagerWrapper.java} | 14 +- .../UserPackageWrapper.java | 8 +- .../UserPackageWrapperImpl.java | 10 +- .../WallpaperManagerWrapper.java | 2 +- .../{wifi => wrapper}/WifiManagerWrapper.java | 2 +- .../src/com/android/settings/UtilsTest.java | 2 +- .../ShortcutServicePickerFragmentTest.java | 3 +- ...RemoveAccountPreferenceControllerTest.java | 2 +- .../AppStateAppOpsBridgeTest.java | 1 + ...ithAdminGrantedPermissionsCounterTest.java | 4 +- ...WithAdminGrantedPermissionsListerTest.java | 4 +- .../ApplicationFeatureProviderImplTest.java | 4 +- .../applications/InstalledAppCounterTest.java | 1 + .../applications/InstalledAppDetailsTest.java | 4 +- .../applications/InstalledAppListerTest.java | 1 + .../applications/NotificationAppsTest.java | 1 + .../PictureInPictureDetailsTest.java | 4 +- .../defaultapps/DefaultAppInfoTest.java | 3 +- .../DefaultAutofillPickerTest.java | 2 +- ...faultAutofillPreferenceControllerTest.java | 5 +- .../defaultapps/DefaultBrowserPickerTest.java | 3 +- ...efaultBrowserPreferenceControllerTest.java | 3 +- .../DefaultEmergencyPickerTest.java | 2 +- .../defaultapps/DefaultHomePickerTest.java | 2 +- .../DefaultHomePreferenceControllerTest.java | 3 +- .../defaultapps/DefaultPhonePickerTest.java | 3 +- .../defaultapps/DefaultSmsPickerTest.java | 3 +- .../InstantAppButtonsControllerTest.java | 2 +- .../suggestions/SuggestionsChecksTest.java | 1 + .../settings/datausage/AppDataUsageTest.java | 3 +- ...PrivateVolumeOptionMenuControllerTest.java | 2 +- .../storage/SecondaryUserControllerTest.java | 2 +- .../storage/UserProfileControllerTest.java | 2 +- ...ightnessLevelPreferenceControllerTest.java | 1 + ...erprisePrivacyFeatureProviderImplTest.java | 5 +- .../FingerprintEnrollFindSensorTest.java | 4 +- .../SetupFingerprintEnrollFindSensorTest.java | 4 +- .../AppButtonsPreferenceControllerTest.java | 2 +- ...roundActivityPreferenceControllerTest.java | 2 +- .../anomaly/AnomalyDetectionPolicyTest.java | 3 +- ...kScorerPickerPreferenceControllerTest.java | 1 + .../network/NetworkScorerPickerTest.java | 3 +- .../SetNewPasswordControllerTest.java | 4 +- .../search/InstalledAppResultLoaderTest.java | 2 +- ...ShadowAccessibilityManagerWrapperImpl.java | 4 +- ...owAccessibilityServiceInfoWrapperImpl.java | 4 +- .../ShadowKeyValueListParserWrapperImpl.java | 4 +- .../shadow/ShadowPowerManagerWrapper.java | 2 +- .../ShadowRestrictedLockUtilsWrapper.java | 2 +- .../testutils/shadow/ShadowUtils.java | 8 +- .../android/settings/vpn2/VpnUtilsTest.java | 1 + .../webview/WebViewAppPickerTest.java | 3 +- .../UseOpenWifiPreferenceControllerTest.java | 2 +- .../settings/wifi/WifiEnablerTest.java | 1 + .../WifiWakeupPreferenceControllerTest.java | 2 +- .../wifi/WriteWifiConfigToNfcDialogTest.java | 1 + .../WifiDetailPreferenceControllerTest.java | 4 +- .../storage/StorageAsyncLoaderTest.java | 4 +- 138 files changed, 421 insertions(+), 1010 deletions(-) delete mode 100644 src/com/android/settings/applications/AccessibilityServiceInfoWrapperImpl.java delete mode 100644 src/com/android/settings/applications/ActivityInfoWrapper.java delete mode 100644 src/com/android/settings/applications/AutofillManagerWrapperImpl.java delete mode 100644 src/com/android/settings/applications/IPackageManagerWrapperImpl.java delete mode 100644 src/com/android/settings/applications/PackageManagerWrapper.java delete mode 100644 src/com/android/settings/applications/PackageManagerWrapperImpl.java delete mode 100644 src/com/android/settings/applications/UserManagerWrapper.java delete mode 100644 src/com/android/settings/enterprise/DevicePolicyManagerWrapperImpl.java delete mode 100644 src/com/android/settings/fuelgauge/anomaly/KeyValueListParserWrapperImpl.java delete mode 100644 src/com/android/settings/password/IFingerprintManager.java delete mode 100644 src/com/android/settings/vpn2/ConnectivityManagerWrapperImpl.java delete mode 100644 src/com/android/settings/wifi/ConnectivityManagerWrapper.java rename src/com/android/settings/{applications/AccessibilityManagerWrapperImpl.java => wrapper/AccessibilityManagerWrapper.java} (93%) rename src/com/android/settings/{applications => wrapper}/AccessibilityServiceInfoWrapper.java (67%) rename src/com/android/settings/{applications/ActivityInfoWrapperImpl.java => wrapper/ActivityInfoWrapper.java} (67%) rename src/com/android/settings/{applications => wrapper}/AutofillManagerWrapper.java (61%) rename src/com/android/settings/{vpn2 => wrapper}/ConnectivityManagerWrapper.java (72%) rename src/com/android/settings/{enterprise => wrapper}/DevicePolicyManagerWrapper.java (59%) rename src/com/android/settings/{password => wrapper}/FingerprintManagerWrapper.java (79%) rename src/com/android/settings/{applications => wrapper}/IPackageManagerWrapper.java (60%) rename src/com/android/settings/{fuelgauge/anomaly => wrapper}/KeyValueListParserWrapper.java (71%) rename src/com/android/settings/{network => wrapper}/NetworkScoreManagerWrapper.java (98%) rename src/com/android/settings/{display => wrapper}/PowerManagerWrapper.java (97%) rename src/com/android/settings/{network => wrapper}/RestrictedLockUtilsWrapper.java (93%) rename src/com/android/settings/{applications/UserManagerWrapperImpl.java => wrapper/UserManagerWrapper.java} (66%) rename src/com/android/settings/{webview => wrapper}/UserPackageWrapper.java (86%) rename src/com/android/settings/{webview => wrapper}/UserPackageWrapperImpl.java (84%) rename src/com/android/settings/{dashboard/suggestions => wrapper}/WallpaperManagerWrapper.java (95%) rename src/com/android/settings/{wifi => wrapper}/WifiManagerWrapper.java (93%) diff --git a/src/com/android/settings/Utils.java b/src/com/android/settings/Utils.java index fa61cecdf2f..89724ccb34b 100644 --- a/src/com/android/settings/Utils.java +++ b/src/com/android/settings/Utils.java @@ -110,9 +110,8 @@ import com.android.internal.app.UnlaunchableAppActivity; import com.android.internal.util.ArrayUtils; import com.android.internal.util.UserIcons; import com.android.internal.widget.LockPatternUtils; -import com.android.settings.enterprise.DevicePolicyManagerWrapper; -import com.android.settings.password.FingerprintManagerWrapper; -import com.android.settings.password.IFingerprintManager; +import com.android.settings.wrapper.FingerprintManagerWrapper; +import com.android.settings.wrapper.DevicePolicyManagerWrapper; import java.io.IOException; import java.io.InputStream; @@ -1258,7 +1257,7 @@ public final class Utils extends com.android.settingslib.Utils { } } - public static IFingerprintManager getFingerprintManagerWrapperOrNull(Context context) { + public static FingerprintManagerWrapper getFingerprintManagerWrapperOrNull(Context context) { FingerprintManager fingerprintManager = getFingerprintManagerOrNull(context); if (fingerprintManager != null) { return new FingerprintManagerWrapper(fingerprintManager); diff --git a/src/com/android/settings/accounts/RemoveAccountPreferenceController.java b/src/com/android/settings/accounts/RemoveAccountPreferenceController.java index b5133d3b320..068847f00a5 100644 --- a/src/com/android/settings/accounts/RemoveAccountPreferenceController.java +++ b/src/com/android/settings/accounts/RemoveAccountPreferenceController.java @@ -43,8 +43,7 @@ import com.android.settings.R; import com.android.settings.applications.LayoutPreference; import com.android.settings.core.PreferenceControllerMixin; import com.android.settings.core.instrumentation.InstrumentedDialogFragment; -import com.android.settings.enterprise.DevicePolicyManagerWrapper; -import com.android.settings.enterprise.DevicePolicyManagerWrapperImpl; +import com.android.settings.wrapper.DevicePolicyManagerWrapper; import com.android.settingslib.core.AbstractPreferenceController; import java.io.IOException; @@ -60,7 +59,7 @@ public class RemoveAccountPreferenceController extends AbstractPreferenceControl private DevicePolicyManagerWrapper mDpm; public RemoveAccountPreferenceController(Context context, Fragment parent) { - this(context, parent, new DevicePolicyManagerWrapperImpl( + this(context, parent, new DevicePolicyManagerWrapper( (DevicePolicyManager) context.getSystemService(Context.DEVICE_POLICY_SERVICE))); } diff --git a/src/com/android/settings/applications/AccessibilityServiceInfoWrapperImpl.java b/src/com/android/settings/applications/AccessibilityServiceInfoWrapperImpl.java deleted file mode 100644 index d0d99ea6533..00000000000 --- a/src/com/android/settings/applications/AccessibilityServiceInfoWrapperImpl.java +++ /dev/null @@ -1,39 +0,0 @@ -/* - * 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.applications; - -import android.accessibilityservice.AccessibilityServiceInfo; -import android.content.ComponentName; - -public class AccessibilityServiceInfoWrapperImpl implements AccessibilityServiceInfoWrapper { - - private final AccessibilityServiceInfo mServiceInfo; - - public AccessibilityServiceInfoWrapperImpl(AccessibilityServiceInfo serviceInfo) { - mServiceInfo = serviceInfo; - } - - @Override - public AccessibilityServiceInfo getAccessibilityServiceInfo() { - return mServiceInfo; - } - - @Override - public ComponentName getComponentName() { - return mServiceInfo.getComponentName(); - } -} diff --git a/src/com/android/settings/applications/ActivityInfoWrapper.java b/src/com/android/settings/applications/ActivityInfoWrapper.java deleted file mode 100644 index 4cb6e68c5cf..00000000000 --- a/src/com/android/settings/applications/ActivityInfoWrapper.java +++ /dev/null @@ -1,30 +0,0 @@ -/* - * 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.applications; - -/** - * This interface replicates a subset of the android.content.pm.ActivityInfo. The interface - * exists so that we can use a thin wrapper around the ActivityInfo in production code and a mock in - * tests. - */ -public interface ActivityInfoWrapper { - - /** - * Returns whether this activity supports picture-in-picture. - */ - boolean supportsPictureInPicture(); -} diff --git a/src/com/android/settings/applications/AppCounter.java b/src/com/android/settings/applications/AppCounter.java index 8c7aed7aefa..a02ecfa70fa 100644 --- a/src/com/android/settings/applications/AppCounter.java +++ b/src/com/android/settings/applications/AppCounter.java @@ -22,6 +22,8 @@ import android.os.AsyncTask; import android.os.UserHandle; import android.os.UserManager; +import com.android.settingslib.wrapper.PackageManagerWrapper; + import java.util.List; public abstract class AppCounter extends AsyncTask { diff --git a/src/com/android/settings/applications/AppInfoBase.java b/src/com/android/settings/applications/AppInfoBase.java index a5daee26564..b06c070c53f 100644 --- a/src/com/android/settings/applications/AppInfoBase.java +++ b/src/com/android/settings/applications/AppInfoBase.java @@ -43,9 +43,8 @@ import com.android.settings.SettingsActivity; import com.android.settings.SettingsPreferenceFragment; import com.android.settings.Utils; import com.android.settings.core.instrumentation.InstrumentedDialogFragment; -import com.android.settings.enterprise.DevicePolicyManagerWrapper; -import com.android.settings.enterprise.DevicePolicyManagerWrapperImpl; import com.android.settings.overlay.FeatureFactory; +import com.android.settings.wrapper.DevicePolicyManagerWrapper; import com.android.settingslib.RestrictedLockUtils; import com.android.settingslib.applications.ApplicationsState; import com.android.settingslib.applications.ApplicationsState.AppEntry; @@ -94,7 +93,7 @@ public abstract class AppInfoBase extends SettingsPreferenceFragment .getApplicationFeatureProvider(activity); mState = ApplicationsState.getInstance(activity.getApplication()); mSession = mState.newSession(this); - mDpm = new DevicePolicyManagerWrapperImpl( + mDpm = new DevicePolicyManagerWrapper( (DevicePolicyManager) activity.getSystemService(Context.DEVICE_POLICY_SERVICE)); mUserManager = (UserManager) activity.getSystemService(Context.USER_SERVICE); mPm = activity.getPackageManager(); diff --git a/src/com/android/settings/applications/AppLister.java b/src/com/android/settings/applications/AppLister.java index 425afa0fd07..f1a3be91dbe 100644 --- a/src/com/android/settings/applications/AppLister.java +++ b/src/com/android/settings/applications/AppLister.java @@ -23,6 +23,8 @@ import android.os.AsyncTask; import android.os.UserHandle; import android.os.UserManager; +import com.android.settingslib.wrapper.PackageManagerWrapper; + import java.util.ArrayList; import java.util.List; diff --git a/src/com/android/settings/applications/AppStateAppOpsBridge.java b/src/com/android/settings/applications/AppStateAppOpsBridge.java index 896102cb124..6ec32a3fdf5 100755 --- a/src/com/android/settings/applications/AppStateAppOpsBridge.java +++ b/src/com/android/settings/applications/AppStateAppOpsBridge.java @@ -31,6 +31,7 @@ import android.util.SparseArray; import com.android.settingslib.applications.ApplicationsState; import com.android.settingslib.applications.ApplicationsState.AppEntry; +import com.android.settings.wrapper.IPackageManagerWrapper; import java.util.Arrays; import java.util.Collection; @@ -57,7 +58,7 @@ public abstract class AppStateAppOpsBridge extends AppStateBaseBridge { public AppStateAppOpsBridge(Context context, ApplicationsState appState, Callback callback, int appOpsOpCode, String[] permissions) { this(context, appState, callback, appOpsOpCode, permissions, - new IPackageManagerWrapperImpl(AppGlobals.getPackageManager())); + new IPackageManagerWrapper(AppGlobals.getPackageManager())); } @VisibleForTesting(otherwise = VisibleForTesting.NONE) diff --git a/src/com/android/settings/applications/AppWithAdminGrantedPermissionsCounter.java b/src/com/android/settings/applications/AppWithAdminGrantedPermissionsCounter.java index c7d0a627268..a1bf14edb52 100644 --- a/src/com/android/settings/applications/AppWithAdminGrantedPermissionsCounter.java +++ b/src/com/android/settings/applications/AppWithAdminGrantedPermissionsCounter.java @@ -22,7 +22,9 @@ import android.os.Build; import android.os.RemoteException; import android.os.UserHandle; -import com.android.settings.enterprise.DevicePolicyManagerWrapper; +import com.android.settings.wrapper.DevicePolicyManagerWrapper; +import com.android.settings.wrapper.IPackageManagerWrapper; +import com.android.settingslib.wrapper.PackageManagerWrapper; /** * Counts installed apps across all users that have been granted one or more specific permissions by diff --git a/src/com/android/settings/applications/AppWithAdminGrantedPermissionsLister.java b/src/com/android/settings/applications/AppWithAdminGrantedPermissionsLister.java index b21f31f3a7d..dd5a8076462 100644 --- a/src/com/android/settings/applications/AppWithAdminGrantedPermissionsLister.java +++ b/src/com/android/settings/applications/AppWithAdminGrantedPermissionsLister.java @@ -18,7 +18,9 @@ package com.android.settings.applications; import android.content.pm.ApplicationInfo; import android.os.UserManager; -import com.android.settings.enterprise.DevicePolicyManagerWrapper; +import com.android.settings.wrapper.DevicePolicyManagerWrapper; +import com.android.settings.wrapper.IPackageManagerWrapper; +import com.android.settingslib.wrapper.PackageManagerWrapper; /** * Lists installed apps across all users that have been granted one or more specific permissions by diff --git a/src/com/android/settings/applications/ApplicationFeatureProviderImpl.java b/src/com/android/settings/applications/ApplicationFeatureProviderImpl.java index 10b61c5570b..5323cd5e58b 100644 --- a/src/com/android/settings/applications/ApplicationFeatureProviderImpl.java +++ b/src/com/android/settings/applications/ApplicationFeatureProviderImpl.java @@ -29,7 +29,9 @@ import android.util.ArraySet; import android.view.View; import com.android.settings.applications.instantapps.InstantAppButtonsController; -import com.android.settings.enterprise.DevicePolicyManagerWrapper; +import com.android.settings.wrapper.DevicePolicyManagerWrapper; +import com.android.settings.wrapper.IPackageManagerWrapper; +import com.android.settingslib.wrapper.PackageManagerWrapper; import java.util.ArrayList; import java.util.List; diff --git a/src/com/android/settings/applications/AutofillManagerWrapperImpl.java b/src/com/android/settings/applications/AutofillManagerWrapperImpl.java deleted file mode 100644 index 9dd1b33b80b..00000000000 --- a/src/com/android/settings/applications/AutofillManagerWrapperImpl.java +++ /dev/null @@ -1,45 +0,0 @@ -/* - * 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.applications; - -import android.view.autofill.AutofillManager; - -public class AutofillManagerWrapperImpl implements AutofillManagerWrapper { - private final AutofillManager mAfm; - - public AutofillManagerWrapperImpl(AutofillManager afm) { - mAfm = afm; - } - - @Override - public boolean hasAutofillFeature() { - if (mAfm == null) { - return false; - } - - return mAfm.hasAutofillFeature(); - } - - @Override - public boolean isAutofillSupported() { - if (mAfm == null) { - return false; - } - - return mAfm.isAutofillSupported(); - } -} diff --git a/src/com/android/settings/applications/IPackageManagerWrapperImpl.java b/src/com/android/settings/applications/IPackageManagerWrapperImpl.java deleted file mode 100644 index af5f37868d9..00000000000 --- a/src/com/android/settings/applications/IPackageManagerWrapperImpl.java +++ /dev/null @@ -1,67 +0,0 @@ -/* - * 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.applications; - -import android.content.Intent; -import android.content.pm.IPackageManager; -import android.content.pm.PackageInfo; -import android.content.pm.ParceledListSlice; -import android.content.pm.ResolveInfo; -import android.os.RemoteException; - -public class IPackageManagerWrapperImpl implements IPackageManagerWrapper { - - private final IPackageManager mPms; - - public IPackageManagerWrapperImpl(IPackageManager pms) { - mPms = pms; - } - - @Override - public int checkUidPermission(String permName, int uid) throws RemoteException { - return mPms.checkUidPermission(permName, uid); - } - - @Override - public ResolveInfo findPersistentPreferredActivity(Intent intent, int userId) - throws RemoteException { - return mPms.findPersistentPreferredActivity(intent, userId); - } - - @Override - public PackageInfo getPackageInfo(String packageName, int flags, int userId) - throws RemoteException { - return mPms.getPackageInfo(packageName, flags, userId); - } - - @Override - public String[] getAppOpPermissionPackages(String permissionName) throws RemoteException { - return mPms.getAppOpPermissionPackages(permissionName); - } - - @Override - public boolean isPackageAvailable(String packageName, int userId) throws RemoteException { - return mPms.isPackageAvailable(packageName, userId); - } - - @Override - public ParceledListSlice getPackagesHoldingPermissions( - String[] permissions, int flags, int userId) throws RemoteException { - return mPms.getPackagesHoldingPermissions(permissions, flags, userId); - } - -} diff --git a/src/com/android/settings/applications/InstalledAppCounter.java b/src/com/android/settings/applications/InstalledAppCounter.java index 932facee6f5..26372ee577e 100644 --- a/src/com/android/settings/applications/InstalledAppCounter.java +++ b/src/com/android/settings/applications/InstalledAppCounter.java @@ -21,6 +21,8 @@ import android.content.pm.ResolveInfo; import android.content.pm.PackageManager; import android.os.UserHandle; +import com.android.settingslib.wrapper.PackageManagerWrapper; + import java.util.List; public abstract class InstalledAppCounter extends AppCounter { diff --git a/src/com/android/settings/applications/InstalledAppDetails.java b/src/com/android/settings/applications/InstalledAppDetails.java index 209cd22b972..2f44d3ec3f1 100755 --- a/src/com/android/settings/applications/InstalledAppDetails.java +++ b/src/com/android/settings/applications/InstalledAppDetails.java @@ -24,7 +24,6 @@ import android.app.ActivityManager; import android.app.AlertDialog; import android.app.LoaderManager; import android.app.LoaderManager.LoaderCallbacks; -import android.app.admin.DevicePolicyManager; import android.content.ActivityNotFoundException; import android.content.BroadcastReceiver; import android.content.ComponentName; @@ -106,6 +105,7 @@ import com.android.settingslib.applications.StorageStatsSource.AppStorageStats; import com.android.settingslib.development.DevelopmentSettingsEnabler; import com.android.settingslib.net.ChartData; import com.android.settingslib.net.ChartDataLoader; +import com.android.settingslib.wrapper.PackageManagerWrapper; import java.lang.ref.WeakReference; import java.util.ArrayList; @@ -1236,7 +1236,7 @@ public class InstalledAppDetails extends AppInfoBase if (pref != null) { pref.setSummary(DefaultHomePreferenceController.isHomeDefault(mPackageName, - new PackageManagerWrapperImpl(context.getPackageManager())) + new PackageManagerWrapper(context.getPackageManager())) ? R.string.yes : R.string.no); } pref = findPreference("default_browser"); diff --git a/src/com/android/settings/applications/InstalledAppLister.java b/src/com/android/settings/applications/InstalledAppLister.java index d8e7c58d3d9..3312d3ebce3 100644 --- a/src/com/android/settings/applications/InstalledAppLister.java +++ b/src/com/android/settings/applications/InstalledAppLister.java @@ -20,6 +20,8 @@ import android.content.pm.ApplicationInfo; import android.content.pm.PackageManager; import android.os.UserManager; +import com.android.settingslib.wrapper.PackageManagerWrapper; + public abstract class InstalledAppLister extends AppLister { public InstalledAppLister(PackageManagerWrapper packageManager, UserManager userManager) { diff --git a/src/com/android/settings/applications/ManageApplications.java b/src/com/android/settings/applications/ManageApplications.java index 11eb0ccefd1..90b6a546b5b 100644 --- a/src/com/android/settings/applications/ManageApplications.java +++ b/src/com/android/settings/applications/ManageApplications.java @@ -90,6 +90,7 @@ import com.android.settingslib.applications.ApplicationsState.AppFilter; import com.android.settingslib.applications.ApplicationsState.CompoundFilter; import com.android.settingslib.applications.ApplicationsState.VolumeFilter; import com.android.settingslib.applications.StorageStatsSource; +import com.android.settingslib.wrapper.PackageManagerWrapper; import java.util.ArrayList; import java.util.Arrays; @@ -888,7 +889,6 @@ public class ManageApplications extends InstrumentedPreferenceFragment private int mLastSortMode = -1; private int mWhichSize = SIZE_TOTAL; CharSequence mCurFilterPrefix; - private PackageManager mPm; private AppFilter mCompositeFilter; private boolean mHasReceivedLoadEntries; private boolean mHasReceivedBridgeCallback; @@ -938,7 +938,6 @@ public class ManageApplications extends InstrumentedPreferenceFragment mManageApplications.mListContainer ); mContext = manageApplications.getActivity(); - mPm = mContext.getPackageManager(); mFilterMode = filterMode; if (mManageApplications.mListType == LIST_TYPE_NOTIFICATION) { mExtraInfoBridge = new AppStateNotificationBridge(mContext, mState, this, @@ -1491,7 +1490,7 @@ public class ManageApplications extends InstrumentedPreferenceFragment public void setListening(boolean listening) { if (listening) { new InstalledAppCounter(mContext, InstalledAppCounter.IGNORE_INSTALL_REASON, - new PackageManagerWrapperImpl(mContext.getPackageManager())) { + new PackageManagerWrapper(mContext.getPackageManager())) { @Override protected void onCountComplete(int num) { mLoader.setSummary(SummaryProvider.this, diff --git a/src/com/android/settings/applications/NotificationApps.java b/src/com/android/settings/applications/NotificationApps.java index f290d43b831..ee802dd5d9e 100644 --- a/src/com/android/settings/applications/NotificationApps.java +++ b/src/com/android/settings/applications/NotificationApps.java @@ -21,6 +21,7 @@ import android.content.pm.ApplicationInfo; import com.android.settings.R; import com.android.settings.dashboard.SummaryLoader; import com.android.settings.notification.NotificationBackend; +import com.android.settingslib.wrapper.PackageManagerWrapper; /** * Extension of ManageApplications with no changes other than having its own @@ -39,7 +40,7 @@ public class NotificationApps extends ManageApplications { mContext = context; mLoader = loader; mNotificationBackend = new NotificationBackend(); - mPackageManager = new PackageManagerWrapperImpl(mContext.getPackageManager()); + mPackageManager = new PackageManagerWrapper(mContext.getPackageManager()); } @Override diff --git a/src/com/android/settings/applications/PackageManagerWrapper.java b/src/com/android/settings/applications/PackageManagerWrapper.java deleted file mode 100644 index 580b578da73..00000000000 --- a/src/com/android/settings/applications/PackageManagerWrapper.java +++ /dev/null @@ -1,116 +0,0 @@ -/* - * 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.applications; - -import android.content.ComponentName; -import android.content.Intent; -import android.content.IntentFilter; -import android.content.pm.ApplicationInfo; -import android.content.pm.IPackageDeleteObserver; -import android.content.pm.PackageManager; -import android.content.pm.ResolveInfo; -import android.os.UserHandle; -import android.os.storage.VolumeInfo; - -import java.util.List; - -/** - * This interface replicates a subset of the android.content.pm.PackageManager (PM). The interface - * exists so that we can use a thin wrapper around the PM in production code and a mock in tests. - * We cannot directly mock or shadow the PM, because some of the methods we rely on are newer than - * the API version supported by Robolectric. - */ -public interface PackageManagerWrapper { - - /** - * Returns the real {@code PackageManager} object. - */ - PackageManager getPackageManager(); - - /** - * Calls {@code PackageManager.getInstalledApplicationsAsUser()}. - * - * @see android.content.pm.PackageManager#getInstalledApplicationsAsUser - */ - List getInstalledApplicationsAsUser(int flags, int userId); - - /** - * Calls {@code PackageManager.hasSystemFeature()}. - * - * @see android.content.pm.PackageManager#hasSystemFeature - */ - boolean hasSystemFeature(String name); - - /** - * Calls {@code PackageManager.queryIntentActivitiesAsUser()}. - * - * @see android.content.pm.PackageManager#queryIntentActivitiesAsUser - */ - List queryIntentActivitiesAsUser(Intent intent, int flags, int userId); - - /** - * Calls {@code PackageManager.getInstallReason()}. - * - * @see android.content.pm.PackageManager#getInstallReason - */ - int getInstallReason(String packageName, UserHandle user); - - /** - * Calls {@code PackageManager.getApplicationInfoAsUser} - */ - ApplicationInfo getApplicationInfoAsUser(String packageName, int i, int userId) - throws PackageManager.NameNotFoundException; - - /** - * Calls {@code PackageManager.setDefaultBrowserPackageNameAsUser} - */ - boolean setDefaultBrowserPackageNameAsUser(String packageName, int userId); - - /** - * Calls {@code PackageManager.getDefaultBrowserPackageNameAsUser} - */ - String getDefaultBrowserPackageNameAsUser(int userId); - - /** - * Calls {@code PackageManager.getHomeActivities} - */ - ComponentName getHomeActivities(List homeActivities); - - /** - * Calls {@code PackageManager.queryIntentServicesAsUser} - */ - List queryIntentServicesAsUser(Intent intent, int i, int user); - - /** - * Calls {@code PackageManager.replacePreferredActivity} - */ - void replacePreferredActivity(IntentFilter homeFilter, int matchCategoryEmpty, - ComponentName[] componentNames, ComponentName component); - - /** - * Calls {@code PackageManager.getPrimaryStorageCurrentVolume} - */ - VolumeInfo getPrimaryStorageCurrentVolume(); - - /** - * Calls {@code PackageManager.deletePackageAsUser} - */ - void deletePackageAsUser(String packageName, IPackageDeleteObserver observer, int flags, - int userId); - - int getPackageUidAsUser(String pkg, int userId) throws PackageManager.NameNotFoundException; -} diff --git a/src/com/android/settings/applications/PackageManagerWrapperImpl.java b/src/com/android/settings/applications/PackageManagerWrapperImpl.java deleted file mode 100644 index a47137c069f..00000000000 --- a/src/com/android/settings/applications/PackageManagerWrapperImpl.java +++ /dev/null @@ -1,112 +0,0 @@ -/* - * 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.applications; - -import android.content.ComponentName; -import android.content.Intent; -import android.content.IntentFilter; -import android.content.pm.ApplicationInfo; -import android.content.pm.IPackageDeleteObserver; -import android.content.pm.PackageManager; -import android.content.pm.ResolveInfo; -import android.os.UserHandle; -import android.os.storage.VolumeInfo; - -import java.util.List; - -public class PackageManagerWrapperImpl implements PackageManagerWrapper { - - private final PackageManager mPm; - - public PackageManagerWrapperImpl(PackageManager pm) { - mPm = pm; - } - - @Override - public PackageManager getPackageManager() { - return mPm; - } - - @Override - public List getInstalledApplicationsAsUser(int flags, int userId) { - return mPm.getInstalledApplicationsAsUser(flags, userId); - } - - @Override - public boolean hasSystemFeature(String name) { - return mPm.hasSystemFeature(name); - } - - @Override - public List queryIntentActivitiesAsUser(Intent intent, int flags, int userId) { - return mPm.queryIntentActivitiesAsUser(intent, flags, userId); - } - - @Override - public int getInstallReason(String packageName, UserHandle user) { - return mPm.getInstallReason(packageName, user); - } - - @Override - public ApplicationInfo getApplicationInfoAsUser(String packageName, int i, int userId) - throws PackageManager.NameNotFoundException { - return mPm.getApplicationInfoAsUser(packageName, i, userId); - } - - @Override - public boolean setDefaultBrowserPackageNameAsUser(String packageName, int userId) { - return mPm.setDefaultBrowserPackageNameAsUser(packageName, userId); - } - - @Override - public String getDefaultBrowserPackageNameAsUser(int userId) { - return mPm.getDefaultBrowserPackageNameAsUser(userId); - } - - @Override - public ComponentName getHomeActivities(List homeActivities) { - return mPm.getHomeActivities(homeActivities); - } - - @Override - public List queryIntentServicesAsUser(Intent intent, int i, int user) { - return mPm.queryIntentServicesAsUser(intent, i, user); - } - - @Override - public void replacePreferredActivity(IntentFilter homeFilter, int matchCategoryEmpty, - ComponentName[] componentNames, ComponentName component) { - mPm.replacePreferredActivity(homeFilter, matchCategoryEmpty, componentNames, component); - } - - @Override - public VolumeInfo getPrimaryStorageCurrentVolume() { - return mPm.getPrimaryStorageCurrentVolume(); - } - - @Override - public void deletePackageAsUser(String packageName, IPackageDeleteObserver observer, int flags, - int userId) { - mPm.deletePackageAsUser(packageName, observer, flags, userId); - } - - @Override - public int getPackageUidAsUser(String pkg, int userId) - throws PackageManager.NameNotFoundException { - return mPm.getPackageUidAsUser(pkg, userId); - } -} diff --git a/src/com/android/settings/applications/PictureInPictureSettings.java b/src/com/android/settings/applications/PictureInPictureSettings.java index b1c544ad089..d8e0b2bf8fc 100644 --- a/src/com/android/settings/applications/PictureInPictureSettings.java +++ b/src/com/android/settings/applications/PictureInPictureSettings.java @@ -36,6 +36,7 @@ import com.android.internal.annotations.VisibleForTesting; import com.android.internal.logging.nano.MetricsProto.MetricsEvent; import com.android.settings.R; import com.android.settings.notification.EmptyTextSettings; +import com.android.settings.wrapper.ActivityInfoWrapper; import java.util.ArrayList; import java.util.Collections; @@ -63,7 +64,7 @@ public class PictureInPictureSettings extends EmptyTextSettings { if (activities != null) { wrappedActivities = new ActivityInfoWrapper[activities.length]; for (int i = 0; i < activities.length; i++) { - wrappedActivities[i] = new ActivityInfoWrapperImpl(activities[i]); + wrappedActivities[i] = new ActivityInfoWrapper(activities[i]); } } return checkPackageHasPictureInPictureActivities(packageName, wrappedActivities); diff --git a/src/com/android/settings/applications/RecentAppsPreferenceController.java b/src/com/android/settings/applications/RecentAppsPreferenceController.java index 69a36f67a53..b6ae1ee54fc 100644 --- a/src/com/android/settings/applications/RecentAppsPreferenceController.java +++ b/src/com/android/settings/applications/RecentAppsPreferenceController.java @@ -42,6 +42,7 @@ import com.android.settings.Utils; import com.android.settings.core.PreferenceControllerMixin; import com.android.settingslib.applications.ApplicationsState; import com.android.settingslib.core.AbstractPreferenceController; +import com.android.settingslib.wrapper.PackageManagerWrapper; import java.util.ArrayList; import java.util.Arrays; @@ -143,7 +144,7 @@ public class RecentAppsPreferenceController extends AbstractPreferenceController refreshUi(mCategory.getContext()); // Show total number of installed apps as See all's summary. new InstalledAppCounter(mContext, InstalledAppCounter.IGNORE_INSTALL_REASON, - new PackageManagerWrapperImpl(mContext.getPackageManager())) { + new PackageManagerWrapper(mContext.getPackageManager())) { @Override protected void onCountComplete(int num) { if (mHasRecentApps) { diff --git a/src/com/android/settings/applications/UserManagerWrapper.java b/src/com/android/settings/applications/UserManagerWrapper.java deleted file mode 100644 index 5b4ed2aa05f..00000000000 --- a/src/com/android/settings/applications/UserManagerWrapper.java +++ /dev/null @@ -1,32 +0,0 @@ -/* - * 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.applications; - -import android.content.pm.UserInfo; - -import java.util.List; - -/** - * This interface replicates a subset of the android.os.UserManager. The interface - * exists so that we can use a thin wrapper around the UserManager in production code and a mock in - * tests. We cannot directly mock or shadow the UserManager, because some of the methods we rely on - * are newer than the API version supported by Robolectric or are hidden. - */ -public interface UserManagerWrapper { - UserInfo getPrimaryUser(); - List getUsers(); -} diff --git a/src/com/android/settings/applications/assist/DefaultVoiceInputPicker.java b/src/com/android/settings/applications/assist/DefaultVoiceInputPicker.java index f51275e23ea..c1fc5286630 100644 --- a/src/com/android/settings/applications/assist/DefaultVoiceInputPicker.java +++ b/src/com/android/settings/applications/assist/DefaultVoiceInputPicker.java @@ -24,9 +24,9 @@ import android.text.TextUtils; import com.android.internal.app.AssistUtils; import com.android.internal.logging.nano.MetricsProto; -import com.android.settings.applications.PackageManagerWrapper; import com.android.settings.applications.defaultapps.DefaultAppInfo; import com.android.settings.applications.defaultapps.DefaultAppPickerFragment; +import com.android.settingslib.wrapper.PackageManagerWrapper; import java.util.ArrayList; import java.util.List; diff --git a/src/com/android/settings/applications/defaultapps/DefaultAppInfo.java b/src/com/android/settings/applications/defaultapps/DefaultAppInfo.java index 12470eb3ab7..ec44af4f872 100644 --- a/src/com/android/settings/applications/defaultapps/DefaultAppInfo.java +++ b/src/com/android/settings/applications/defaultapps/DefaultAppInfo.java @@ -26,8 +26,8 @@ import android.graphics.drawable.Drawable; import android.os.RemoteException; import android.os.UserHandle; -import com.android.settings.applications.PackageManagerWrapper; import com.android.settings.widget.RadioButtonPickerFragment; +import com.android.settingslib.wrapper.PackageManagerWrapper; /** * Data model representing an app in DefaultAppPicker UI. diff --git a/src/com/android/settings/applications/defaultapps/DefaultAppPickerFragment.java b/src/com/android/settings/applications/defaultapps/DefaultAppPickerFragment.java index d3617ef8869..6eb1ad81b57 100644 --- a/src/com/android/settings/applications/defaultapps/DefaultAppPickerFragment.java +++ b/src/com/android/settings/applications/defaultapps/DefaultAppPickerFragment.java @@ -29,11 +29,10 @@ import android.util.Pair; import com.android.internal.logging.nano.MetricsProto.MetricsEvent; import com.android.settings.R; -import com.android.settings.applications.PackageManagerWrapper; -import com.android.settings.applications.PackageManagerWrapperImpl; import com.android.settings.core.instrumentation.InstrumentedDialogFragment; import com.android.settings.widget.RadioButtonPickerFragment; import com.android.settings.widget.RadioButtonPreference; +import com.android.settingslib.wrapper.PackageManagerWrapper; /** * A generic app picker fragment that shows a list of app as radio button group. @@ -45,7 +44,7 @@ public abstract class DefaultAppPickerFragment extends RadioButtonPickerFragment @Override public void onAttach(Context context) { super.onAttach(context); - mPm = new PackageManagerWrapperImpl(context.getPackageManager()); + mPm = new PackageManagerWrapper(context.getPackageManager()); } @Override diff --git a/src/com/android/settings/applications/defaultapps/DefaultAppPreferenceController.java b/src/com/android/settings/applications/defaultapps/DefaultAppPreferenceController.java index c7b450e00d2..d533d0f4993 100644 --- a/src/com/android/settings/applications/defaultapps/DefaultAppPreferenceController.java +++ b/src/com/android/settings/applications/defaultapps/DefaultAppPreferenceController.java @@ -26,11 +26,10 @@ import android.text.TextUtils; import android.util.Log; import com.android.settings.R; -import com.android.settings.applications.PackageManagerWrapper; -import com.android.settings.applications.PackageManagerWrapperImpl; import com.android.settings.core.PreferenceControllerMixin; import com.android.settings.widget.GearPreference; import com.android.settingslib.core.AbstractPreferenceController; +import com.android.settingslib.wrapper.PackageManagerWrapper; public abstract class DefaultAppPreferenceController extends AbstractPreferenceController implements PreferenceControllerMixin { @@ -44,7 +43,7 @@ public abstract class DefaultAppPreferenceController extends AbstractPreferenceC public DefaultAppPreferenceController(Context context) { super(context); - mPackageManager = new PackageManagerWrapperImpl(context.getPackageManager()); + mPackageManager = new PackageManagerWrapper(context.getPackageManager()); mUserManager = (UserManager) context.getSystemService(Context.USER_SERVICE); mUserId = UserHandle.myUserId(); } diff --git a/src/com/android/settings/applications/defaultapps/DefaultAutofillPreferenceController.java b/src/com/android/settings/applications/defaultapps/DefaultAutofillPreferenceController.java index 1fd10ffea72..30aaf646ccd 100644 --- a/src/com/android/settings/applications/defaultapps/DefaultAutofillPreferenceController.java +++ b/src/com/android/settings/applications/defaultapps/DefaultAutofillPreferenceController.java @@ -23,8 +23,7 @@ import android.provider.Settings; import android.text.TextUtils; import android.view.autofill.AutofillManager; -import com.android.settings.applications.AutofillManagerWrapper; -import com.android.settings.applications.AutofillManagerWrapperImpl; +import com.android.settings.wrapper.AutofillManagerWrapper; public class DefaultAutofillPreferenceController extends DefaultAppPreferenceController { private AutofillManagerWrapper mAutofillManager; @@ -32,7 +31,7 @@ public class DefaultAutofillPreferenceController extends DefaultAppPreferenceCon public DefaultAutofillPreferenceController(Context context) { super(context); - mAutofillManager = new AutofillManagerWrapperImpl( + mAutofillManager = new AutofillManagerWrapper( mContext.getSystemService(AutofillManager.class)); } diff --git a/src/com/android/settings/applications/defaultapps/DefaultHomePreferenceController.java b/src/com/android/settings/applications/defaultapps/DefaultHomePreferenceController.java index 88b36b25dda..1b229e8d3ed 100644 --- a/src/com/android/settings/applications/defaultapps/DefaultHomePreferenceController.java +++ b/src/com/android/settings/applications/defaultapps/DefaultHomePreferenceController.java @@ -24,7 +24,7 @@ import android.content.pm.ActivityInfo; import android.content.pm.PackageManager; import android.content.pm.ResolveInfo; -import com.android.settings.applications.PackageManagerWrapper; +import com.android.settingslib.wrapper.PackageManagerWrapper; import java.util.ArrayList; import java.util.List; diff --git a/src/com/android/settings/applications/instantapps/InstantAppButtonsController.java b/src/com/android/settings/applications/instantapps/InstantAppButtonsController.java index 16956dfbd3b..28e612c98ff 100644 --- a/src/com/android/settings/applications/instantapps/InstantAppButtonsController.java +++ b/src/com/android/settings/applications/instantapps/InstantAppButtonsController.java @@ -29,9 +29,8 @@ import android.widget.Button; import com.android.internal.logging.nano.MetricsProto.MetricsEvent; import com.android.settings.R; import com.android.settings.applications.AppStoreUtil; -import com.android.settings.applications.PackageManagerWrapper; -import com.android.settings.applications.PackageManagerWrapperImpl; import com.android.settings.overlay.FeatureFactory; +import com.android.settingslib.wrapper.PackageManagerWrapper; /** Encapsulates a container for buttons relevant to instant apps */ public class InstantAppButtonsController implements DialogInterface.OnClickListener { @@ -62,7 +61,7 @@ public class InstantAppButtonsController implements DialogInterface.OnClickListe mFragment = fragment; mView = view; mShowDialogDelegate = showDialogDelegate; - mPackageManagerWrapper = new PackageManagerWrapperImpl(context.getPackageManager()); + mPackageManagerWrapper = new PackageManagerWrapper(context.getPackageManager()); } public InstantAppButtonsController setPackageName(String packageName) { diff --git a/src/com/android/settings/dashboard/suggestions/SuggestionsChecks.java b/src/com/android/settings/dashboard/suggestions/SuggestionsChecks.java index 4bed89b644c..eb969a55f8d 100644 --- a/src/com/android/settings/dashboard/suggestions/SuggestionsChecks.java +++ b/src/com/android/settings/dashboard/suggestions/SuggestionsChecks.java @@ -32,6 +32,7 @@ import com.android.settings.Utils; import com.android.settings.fingerprint.FingerprintSuggestionActivity; import com.android.settings.overlay.FeatureFactory; import com.android.settings.wallpaper.WallpaperSuggestionActivity; +import com.android.settings.wrapper.WallpaperManagerWrapper; import com.android.settingslib.drawer.Tile; /** diff --git a/src/com/android/settings/datausage/AppDataUsage.java b/src/com/android/settings/datausage/AppDataUsage.java index 36d9d0f6e65..5470e6372db 100644 --- a/src/com/android/settings/datausage/AppDataUsage.java +++ b/src/com/android/settings/datausage/AppDataUsage.java @@ -46,14 +46,13 @@ import android.widget.AdapterView; import com.android.internal.logging.nano.MetricsProto.MetricsEvent; import com.android.settings.R; import com.android.settings.applications.AppInfoBase; -import com.android.settings.applications.PackageManagerWrapper; -import com.android.settings.applications.PackageManagerWrapperImpl; import com.android.settings.widget.EntityHeaderController; import com.android.settingslib.AppItem; import com.android.settingslib.net.ChartData; import com.android.settingslib.net.ChartDataLoader; import com.android.settingslib.net.UidDetail; import com.android.settingslib.net.UidDetailProvider; +import com.android.settingslib.wrapper.PackageManagerWrapper; public class AppDataUsage extends DataUsageBase implements Preference.OnPreferenceChangeListener, DataSaverBackend.Listener { @@ -104,7 +103,7 @@ public class AppDataUsage extends DataUsageBase implements Preference.OnPreferen @Override public void onCreate(Bundle icicle) { super.onCreate(icicle); - mPackageManagerWrapper = new PackageManagerWrapperImpl(getPackageManager()); + mPackageManagerWrapper = new PackageManagerWrapper(getPackageManager()); final Bundle args = getArguments(); try { diff --git a/src/com/android/settings/deviceinfo/PrivateVolumeOptionMenuController.java b/src/com/android/settings/deviceinfo/PrivateVolumeOptionMenuController.java index 88b94876688..6047f8cc082 100644 --- a/src/com/android/settings/deviceinfo/PrivateVolumeOptionMenuController.java +++ b/src/com/android/settings/deviceinfo/PrivateVolumeOptionMenuController.java @@ -24,12 +24,12 @@ import android.view.MenuInflater; import android.view.MenuItem; import com.android.settings.R; -import com.android.settings.applications.PackageManagerWrapper; import com.android.settingslib.core.lifecycle.Lifecycle; import com.android.settingslib.core.lifecycle.LifecycleObserver; import com.android.settingslib.core.lifecycle.events.OnCreateOptionsMenu; import com.android.settingslib.core.lifecycle.events.OnOptionsItemSelected; import com.android.settingslib.core.lifecycle.events.OnPrepareOptionsMenu; +import com.android.settingslib.wrapper.PackageManagerWrapper; import java.util.Objects; diff --git a/src/com/android/settings/deviceinfo/StorageDashboardFragment.java b/src/com/android/settings/deviceinfo/StorageDashboardFragment.java index dd0db9a2335..935e180892c 100644 --- a/src/com/android/settings/deviceinfo/StorageDashboardFragment.java +++ b/src/com/android/settings/deviceinfo/StorageDashboardFragment.java @@ -35,9 +35,6 @@ import android.view.View; import com.android.internal.logging.nano.MetricsProto; import com.android.settings.R; import com.android.settings.Utils; -import com.android.settings.applications.PackageManagerWrapperImpl; -import com.android.settings.applications.UserManagerWrapper; -import com.android.settings.applications.UserManagerWrapperImpl; import com.android.settings.dashboard.DashboardFragment; import com.android.settings.deviceinfo.storage.AutomaticStorageManagementSwitchPreferenceController; import com.android.settings.deviceinfo.storage.CachedStorageValuesHelper; @@ -49,10 +46,12 @@ import com.android.settings.deviceinfo.storage.UserIconLoader; import com.android.settings.deviceinfo.storage.VolumeSizesLoader; import com.android.settings.search.BaseSearchIndexProvider; import com.android.settings.search.Indexable; +import com.android.settings.wrapper.UserManagerWrapper; import com.android.settingslib.applications.StorageStatsSource; import com.android.settingslib.core.AbstractPreferenceController; import com.android.settingslib.deviceinfo.PrivateStorageInfo; import com.android.settingslib.deviceinfo.StorageManagerVolumeProvider; +import com.android.settingslib.wrapper.PackageManagerWrapper; import java.util.ArrayList; import java.util.Arrays; @@ -95,7 +94,7 @@ public class StorageDashboardFragment extends DashboardFragment @VisibleForTesting void initializeOptionsMenu(Activity activity) { mOptionMenuController = new PrivateVolumeOptionMenuController( - activity, mVolume, new PackageManagerWrapperImpl(activity.getPackageManager())); + activity, mVolume, new PackageManagerWrapper(activity.getPackageManager())); getLifecycle().addObserver(mOptionMenuController); setHasOptionsMenu(true); activity.invalidateOptionsMenu(); @@ -178,7 +177,7 @@ public class StorageDashboardFragment extends DashboardFragment controllers.add(mPreferenceController); UserManagerWrapper userManager = - new UserManagerWrapperImpl(context.getSystemService(UserManager.class)); + new UserManagerWrapper(context.getSystemService(UserManager.class)); mSecondaryUsers = SecondaryUserController.getSecondaryUserControllers(context, userManager); controllers.addAll(mSecondaryUsers); @@ -227,7 +226,7 @@ public class StorageDashboardFragment extends DashboardFragment public List getPreferenceControllers(Context context) { final StorageManager sm = context.getSystemService(StorageManager.class); final UserManagerWrapper userManager = - new UserManagerWrapperImpl(context.getSystemService(UserManager.class)); + new UserManagerWrapper(context.getSystemService(UserManager.class)); final List controllers = new ArrayList<>(); controllers.add(new StorageSummaryDonutPreferenceController(context)); controllers.add(new StorageItemPreferenceController(context, null /* host */, @@ -244,10 +243,10 @@ public class StorageDashboardFragment extends DashboardFragment Bundle args) { Context context = getContext(); return new StorageAsyncLoader(context, - new UserManagerWrapperImpl(context.getSystemService(UserManager.class)), + new UserManagerWrapper(context.getSystemService(UserManager.class)), mVolume.fsUuid, new StorageStatsSource(context), - new PackageManagerWrapperImpl(context.getPackageManager())); + new PackageManagerWrapper(context.getPackageManager())); } @Override diff --git a/src/com/android/settings/deviceinfo/StorageProfileFragment.java b/src/com/android/settings/deviceinfo/StorageProfileFragment.java index 9f3ce0ca8d0..f2383de4aa6 100644 --- a/src/com/android/settings/deviceinfo/StorageProfileFragment.java +++ b/src/com/android/settings/deviceinfo/StorageProfileFragment.java @@ -30,15 +30,15 @@ import android.util.SparseArray; import com.android.internal.logging.nano.MetricsProto; import com.android.settings.R; import com.android.settings.Utils; -import com.android.settings.applications.PackageManagerWrapperImpl; -import com.android.settings.applications.UserManagerWrapperImpl; import com.android.settings.dashboard.DashboardFragment; import com.android.settings.deviceinfo.storage.StorageAsyncLoader; import com.android.settings.deviceinfo.storage.StorageAsyncLoader.AppsStorageResult; import com.android.settings.deviceinfo.storage.StorageItemPreferenceController; +import com.android.settings.wrapper.UserManagerWrapper; import com.android.settingslib.applications.StorageStatsSource; import com.android.settingslib.core.AbstractPreferenceController; import com.android.settingslib.deviceinfo.StorageManagerVolumeProvider; +import com.android.settingslib.wrapper.PackageManagerWrapper; import java.util.ArrayList; import java.util.List; @@ -116,10 +116,10 @@ public class StorageProfileFragment extends DashboardFragment public Loader> onCreateLoader(int id, Bundle args) { Context context = getContext(); return new StorageAsyncLoader(context, - new UserManagerWrapperImpl(context.getSystemService(UserManager.class)), + new UserManagerWrapper(context.getSystemService(UserManager.class)), mVolume.fsUuid, new StorageStatsSource(context), - new PackageManagerWrapperImpl(context.getPackageManager())); + new PackageManagerWrapper(context.getPackageManager())); } @Override diff --git a/src/com/android/settings/deviceinfo/storage/SecondaryUserController.java b/src/com/android/settings/deviceinfo/storage/SecondaryUserController.java index 3c69ab1fc54..4aeb78299bf 100644 --- a/src/com/android/settings/deviceinfo/storage/SecondaryUserController.java +++ b/src/com/android/settings/deviceinfo/storage/SecondaryUserController.java @@ -27,9 +27,9 @@ import android.support.v7.preference.PreferenceScreen; import android.util.SparseArray; import com.android.settings.Utils; -import com.android.settings.applications.UserManagerWrapper; import com.android.settings.core.PreferenceControllerMixin; import com.android.settings.deviceinfo.StorageItemPreference; +import com.android.settings.wrapper.UserManagerWrapper; import com.android.settingslib.core.AbstractPreferenceController; import java.util.ArrayList; diff --git a/src/com/android/settings/deviceinfo/storage/StorageAsyncLoader.java b/src/com/android/settings/deviceinfo/storage/StorageAsyncLoader.java index f92a24e9f9d..2ce53f65755 100644 --- a/src/com/android/settings/deviceinfo/storage/StorageAsyncLoader.java +++ b/src/com/android/settings/deviceinfo/storage/StorageAsyncLoader.java @@ -30,10 +30,10 @@ import android.util.ArraySet; import android.util.Log; import android.util.SparseArray; -import com.android.settings.applications.PackageManagerWrapper; -import com.android.settings.applications.UserManagerWrapper; import com.android.settings.utils.AsyncLoader; +import com.android.settings.wrapper.UserManagerWrapper; import com.android.settingslib.applications.StorageStatsSource; +import com.android.settingslib.wrapper.PackageManagerWrapper; import java.io.IOException; import java.util.Collections; diff --git a/src/com/android/settings/deviceinfo/storage/UserProfileController.java b/src/com/android/settings/deviceinfo/storage/UserProfileController.java index cf1e3603bbe..4870e7e3fa3 100644 --- a/src/com/android/settings/deviceinfo/storage/UserProfileController.java +++ b/src/com/android/settings/deviceinfo/storage/UserProfileController.java @@ -30,10 +30,10 @@ import android.util.SparseArray; import com.android.internal.logging.nano.MetricsProto; import com.android.internal.util.Preconditions; import com.android.settings.Utils; -import com.android.settings.applications.UserManagerWrapper; import com.android.settings.core.PreferenceControllerMixin; import com.android.settings.deviceinfo.StorageItemPreference; import com.android.settings.deviceinfo.StorageProfileFragment; +import com.android.settings.wrapper.UserManagerWrapper; import com.android.settingslib.core.AbstractPreferenceController; import com.android.settingslib.drawer.SettingsDrawerActivity; diff --git a/src/com/android/settings/display/BrightnessLevelPreferenceController.java b/src/com/android/settings/display/BrightnessLevelPreferenceController.java index e1461dc9747..f9c9d53a961 100644 --- a/src/com/android/settings/display/BrightnessLevelPreferenceController.java +++ b/src/com/android/settings/display/BrightnessLevelPreferenceController.java @@ -31,6 +31,7 @@ import android.support.v7.preference.PreferenceScreen; import android.util.Log; import com.android.settings.core.PreferenceControllerMixin; +import com.android.settings.wrapper.PowerManagerWrapper; import com.android.settingslib.core.AbstractPreferenceController; import com.android.settingslib.core.lifecycle.Lifecycle; import com.android.settingslib.core.lifecycle.LifecycleObserver; diff --git a/src/com/android/settings/enterprise/DevicePolicyManagerWrapperImpl.java b/src/com/android/settings/enterprise/DevicePolicyManagerWrapperImpl.java deleted file mode 100644 index 69ee2727d8d..00000000000 --- a/src/com/android/settings/enterprise/DevicePolicyManagerWrapperImpl.java +++ /dev/null @@ -1,125 +0,0 @@ -/* - * 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.enterprise; - -import android.annotation.NonNull; -import android.app.admin.DevicePolicyManager; -import android.content.ComponentName; -import android.content.Intent; -import android.os.UserHandle; -import android.support.annotation.Nullable; - -import java.util.List; - -public class DevicePolicyManagerWrapperImpl implements DevicePolicyManagerWrapper { - private final DevicePolicyManager mDpm; - - public DevicePolicyManagerWrapperImpl(DevicePolicyManager dpm) { - mDpm = dpm; - } - - @Override - public @Nullable List getActiveAdminsAsUser(int userId) { - return mDpm.getActiveAdminsAsUser(userId); - } - - @Override - public int getMaximumFailedPasswordsForWipe(@Nullable ComponentName admin, int userHandle) { - return mDpm.getMaximumFailedPasswordsForWipe(admin, userHandle); - } - - @Override - public ComponentName getDeviceOwnerComponentOnCallingUser() { - return mDpm.getDeviceOwnerComponentOnCallingUser(); - } - - @Override - public ComponentName getDeviceOwnerComponentOnAnyUser() { - return mDpm.getDeviceOwnerComponentOnAnyUser(); - } - - @Override - public @Nullable ComponentName getProfileOwnerAsUser(final int userId) { - return mDpm.getProfileOwnerAsUser(userId); - } - - @Override - public CharSequence getDeviceOwnerOrganizationName() { - return mDpm.getDeviceOwnerOrganizationName(); - } - - @Override - public int getPermissionGrantState(@Nullable ComponentName admin, String packageName, - String permission) { - return mDpm.getPermissionGrantState(admin, packageName, permission); - } - - @Override - public boolean isSecurityLoggingEnabled(@Nullable ComponentName admin) { - return mDpm.isSecurityLoggingEnabled(admin); - } - - @Override - public boolean isNetworkLoggingEnabled(@Nullable ComponentName admin) { - return mDpm.isNetworkLoggingEnabled(admin); - } - - @Override - public long getLastSecurityLogRetrievalTime() { - return mDpm.getLastSecurityLogRetrievalTime(); - } - - @Override - public long getLastBugReportRequestTime() { - return mDpm.getLastBugReportRequestTime(); - } - - @Override - public long getLastNetworkLogRetrievalTime() { - return mDpm.getLastNetworkLogRetrievalTime(); - } - - @Override - public boolean isCurrentInputMethodSetByOwner() { - return mDpm.isCurrentInputMethodSetByOwner(); - } - - @Override - public List getOwnerInstalledCaCerts(@NonNull UserHandle user) { - return mDpm.getOwnerInstalledCaCerts(user); - } - - @Override - public boolean isDeviceOwnerAppOnAnyUser(String packageName) { - return mDpm.isDeviceOwnerAppOnAnyUser(packageName); - } - - @Override - public boolean packageHasActiveAdmins(String packageName) { - return mDpm.packageHasActiveAdmins(packageName); - } - - @Override - public boolean isUninstallInQueue(String packageName) { - return mDpm.isUninstallInQueue(packageName); - } - - @Override - public Intent createAdminSupportIntent(@NonNull String restriction) { - return mDpm.createAdminSupportIntent(restriction); - } -} diff --git a/src/com/android/settings/enterprise/EnterprisePrivacyFeatureProviderImpl.java b/src/com/android/settings/enterprise/EnterprisePrivacyFeatureProviderImpl.java index 159f57ba7f6..9217001b221 100644 --- a/src/com/android/settings/enterprise/EnterprisePrivacyFeatureProviderImpl.java +++ b/src/com/android/settings/enterprise/EnterprisePrivacyFeatureProviderImpl.java @@ -30,9 +30,10 @@ import android.text.style.ClickableSpan; import android.view.View; import com.android.settings.R; -import com.android.settings.applications.PackageManagerWrapper; -import com.android.settings.vpn2.ConnectivityManagerWrapper; import com.android.settings.vpn2.VpnUtils; +import com.android.settings.wrapper.ConnectivityManagerWrapper; +import com.android.settings.wrapper.DevicePolicyManagerWrapper; +import com.android.settingslib.wrapper.PackageManagerWrapper; import java.util.Date; import java.util.List; diff --git a/src/com/android/settings/fingerprint/FingerprintEnrollSidecar.java b/src/com/android/settings/fingerprint/FingerprintEnrollSidecar.java index 9ab561d2c1b..20bb13b58f1 100644 --- a/src/com/android/settings/fingerprint/FingerprintEnrollSidecar.java +++ b/src/com/android/settings/fingerprint/FingerprintEnrollSidecar.java @@ -29,8 +29,7 @@ import com.android.internal.logging.nano.MetricsProto.MetricsEvent; import com.android.settings.Utils; import com.android.settings.core.InstrumentedFragment; import com.android.settings.password.ChooseLockSettingsHelper; - -import com.android.settings.password.IFingerprintManager; +import com.android.settings.wrapper.FingerprintManagerWrapper; import java.util.ArrayList; @@ -48,7 +47,7 @@ public class FingerprintEnrollSidecar extends InstrumentedFragment { private byte[] mToken; private boolean mDone; private int mUserId; - private IFingerprintManager mFingerprintManager; + private FingerprintManagerWrapper mFingerprintManager; private ArrayList mQueuedEvents; private abstract class QueuedEvent { diff --git a/src/com/android/settings/fuelgauge/AdvancedPowerUsageDetail.java b/src/com/android/settings/fuelgauge/AdvancedPowerUsageDetail.java index 66a0ca2ee89..d96db687101 100644 --- a/src/com/android/settings/fuelgauge/AdvancedPowerUsageDetail.java +++ b/src/com/android/settings/fuelgauge/AdvancedPowerUsageDetail.java @@ -45,8 +45,7 @@ import com.android.settings.SettingsActivity; import com.android.settings.Utils; import com.android.settings.applications.LayoutPreference; import com.android.settings.dashboard.DashboardFragment; -import com.android.settings.enterprise.DevicePolicyManagerWrapper; -import com.android.settings.enterprise.DevicePolicyManagerWrapperImpl; +import com.android.settings.wrapper.DevicePolicyManagerWrapper; import com.android.settings.fuelgauge.anomaly.Anomaly; import com.android.settings.fuelgauge.anomaly.AnomalyDialogFragment; import com.android.settings.fuelgauge.anomaly.AnomalyLoader; @@ -194,7 +193,7 @@ public class AdvancedPowerUsageDetail extends DashboardFragment implements super.onAttach(activity); mState = ApplicationsState.getInstance(getActivity().getApplication()); - mDpm = new DevicePolicyManagerWrapperImpl( + mDpm = new DevicePolicyManagerWrapper( (DevicePolicyManager) activity.getSystemService(Context.DEVICE_POLICY_SERVICE)); mUserManager = (UserManager) activity.getSystemService(Context.USER_SERVICE); mPackageManager = activity.getPackageManager(); diff --git a/src/com/android/settings/fuelgauge/AppButtonsPreferenceController.java b/src/com/android/settings/fuelgauge/AppButtonsPreferenceController.java index 0d5bed8aca5..20acee9b04b 100644 --- a/src/com/android/settings/fuelgauge/AppButtonsPreferenceController.java +++ b/src/com/android/settings/fuelgauge/AppButtonsPreferenceController.java @@ -50,9 +50,9 @@ import com.android.settings.SettingsActivity; import com.android.settings.Utils; import com.android.settings.core.PreferenceControllerMixin; import com.android.settings.core.instrumentation.MetricsFeatureProvider; -import com.android.settings.enterprise.DevicePolicyManagerWrapper; import com.android.settings.overlay.FeatureFactory; import com.android.settings.widget.ActionButtonPreference; +import com.android.settings.wrapper.DevicePolicyManagerWrapper; import com.android.settingslib.RestrictedLockUtils; import com.android.settingslib.applications.AppUtils; import com.android.settingslib.applications.ApplicationsState; diff --git a/src/com/android/settings/fuelgauge/BackgroundActivityPreferenceController.java b/src/com/android/settings/fuelgauge/BackgroundActivityPreferenceController.java index cea6d165a74..14aba85a948 100644 --- a/src/com/android/settings/fuelgauge/BackgroundActivityPreferenceController.java +++ b/src/com/android/settings/fuelgauge/BackgroundActivityPreferenceController.java @@ -35,8 +35,7 @@ import com.android.settings.R; import com.android.settings.Utils; import com.android.settings.core.PreferenceControllerMixin; import com.android.settings.core.instrumentation.InstrumentedDialogFragment; -import com.android.settings.enterprise.DevicePolicyManagerWrapper; -import com.android.settings.enterprise.DevicePolicyManagerWrapperImpl; +import com.android.settings.wrapper.DevicePolicyManagerWrapper; import com.android.settingslib.core.AbstractPreferenceController; /** @@ -71,7 +70,7 @@ public class BackgroundActivityPreferenceController extends AbstractPreferenceCo mPowerWhitelistBackend = backend; mPackageManager = context.getPackageManager(); mUserManager = (UserManager) context.getSystemService(Context.USER_SERVICE); - mDpm = new DevicePolicyManagerWrapperImpl( + mDpm = new DevicePolicyManagerWrapper( (DevicePolicyManager) context.getSystemService(Context.DEVICE_POLICY_SERVICE)); mAppOpsManager = (AppOpsManager) context.getSystemService(Context.APP_OPS_SERVICE); mUid = uid; diff --git a/src/com/android/settings/fuelgauge/anomaly/AnomalyDetectionPolicy.java b/src/com/android/settings/fuelgauge/anomaly/AnomalyDetectionPolicy.java index 4829ca01d31..57f0ab4d380 100644 --- a/src/com/android/settings/fuelgauge/anomaly/AnomalyDetectionPolicy.java +++ b/src/com/android/settings/fuelgauge/anomaly/AnomalyDetectionPolicy.java @@ -23,6 +23,8 @@ import android.text.format.DateUtils; import android.util.KeyValueListParser; import android.util.Log; +import com.android.settings.wrapper.KeyValueListParserWrapper; + /** * Class to store the policy for anomaly detection, which comes from * {@link android.provider.Settings.Global} @@ -104,7 +106,7 @@ public class AnomalyDetectionPolicy { private final KeyValueListParserWrapper mParserWrapper; public AnomalyDetectionPolicy(Context context) { - this(context, new KeyValueListParserWrapperImpl(new KeyValueListParser(','))); + this(context, new KeyValueListParserWrapper(new KeyValueListParser(','))); } @VisibleForTesting diff --git a/src/com/android/settings/fuelgauge/anomaly/KeyValueListParserWrapperImpl.java b/src/com/android/settings/fuelgauge/anomaly/KeyValueListParserWrapperImpl.java deleted file mode 100644 index f7240341e6f..00000000000 --- a/src/com/android/settings/fuelgauge/anomaly/KeyValueListParserWrapperImpl.java +++ /dev/null @@ -1,50 +0,0 @@ -/* - * 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.fuelgauge.anomaly; - -import android.util.KeyValueListParser; - -/** - * Impl of {@link KeyValueListParser} - */ -public class KeyValueListParserWrapperImpl implements KeyValueListParserWrapper { - private KeyValueListParser mParser; - - public KeyValueListParserWrapperImpl(KeyValueListParser parser) { - mParser = parser; - } - - @Override - public KeyValueListParser getKeyValueListParser() { - return mParser; - } - - @Override - public void setString(String str) throws IllegalArgumentException { - mParser.setString(str); - } - - @Override - public boolean getBoolean(String key, boolean defaultValue) { - return mParser.getBoolean(key, defaultValue); - } - - @Override - public long getLong(String key, long defaultValue) { - return mParser.getLong(key, defaultValue); - } -} diff --git a/src/com/android/settings/network/MobileNetworkPreferenceController.java b/src/com/android/settings/network/MobileNetworkPreferenceController.java index 6e2c2d56e9c..1199400f55a 100644 --- a/src/com/android/settings/network/MobileNetworkPreferenceController.java +++ b/src/com/android/settings/network/MobileNetworkPreferenceController.java @@ -26,6 +26,7 @@ import android.telephony.TelephonyManager; import com.android.settings.Utils; import com.android.settings.core.PreferenceControllerMixin; +import com.android.settings.wrapper.RestrictedLockUtilsWrapper; import com.android.settingslib.core.AbstractPreferenceController; import com.android.settingslib.core.lifecycle.LifecycleObserver; import com.android.settingslib.core.lifecycle.events.OnPause; diff --git a/src/com/android/settings/network/NetworkScorerPicker.java b/src/com/android/settings/network/NetworkScorerPicker.java index 1280cf501c2..187c9ce3ebc 100644 --- a/src/com/android/settings/network/NetworkScorerPicker.java +++ b/src/com/android/settings/network/NetworkScorerPicker.java @@ -30,6 +30,7 @@ import com.android.internal.logging.nano.MetricsProto; import com.android.settings.R; import com.android.settings.core.InstrumentedPreferenceFragment; import com.android.settings.widget.RadioButtonPreference; +import com.android.settings.wrapper.NetworkScoreManagerWrapper; import java.util.List; diff --git a/src/com/android/settings/network/NetworkScorerPickerPreferenceController.java b/src/com/android/settings/network/NetworkScorerPickerPreferenceController.java index 8d4ea63836a..e25e62d79ec 100644 --- a/src/com/android/settings/network/NetworkScorerPickerPreferenceController.java +++ b/src/com/android/settings/network/NetworkScorerPickerPreferenceController.java @@ -21,6 +21,7 @@ import android.support.v7.preference.Preference; import com.android.settings.R; import com.android.settings.core.PreferenceControllerMixin; +import com.android.settings.wrapper.NetworkScoreManagerWrapper; import com.android.settingslib.core.AbstractPreferenceController; import java.util.List; diff --git a/src/com/android/settings/overlay/FeatureFactoryImpl.java b/src/com/android/settings/overlay/FeatureFactoryImpl.java index 36c3bc943e6..d3fca683df5 100644 --- a/src/com/android/settings/overlay/FeatureFactoryImpl.java +++ b/src/com/android/settings/overlay/FeatureFactoryImpl.java @@ -25,8 +25,6 @@ import android.support.annotation.Keep; import com.android.settings.applications.ApplicationFeatureProvider; import com.android.settings.applications.ApplicationFeatureProviderImpl; -import com.android.settings.applications.IPackageManagerWrapperImpl; -import com.android.settings.applications.PackageManagerWrapperImpl; import com.android.settings.bluetooth.BluetoothFeatureProvider; import com.android.settings.bluetooth.BluetoothFeatureProviderImpl; import com.android.settings.connecteddevice.SmsMirroringFeatureProvider; @@ -38,7 +36,6 @@ import com.android.settings.dashboard.suggestions.SuggestionFeatureProvider; import com.android.settings.dashboard.suggestions.SuggestionFeatureProviderImpl; import com.android.settings.datausage.DataPlanFeatureProvider; import com.android.settings.datausage.DataPlanFeatureProviderImpl; -import com.android.settings.enterprise.DevicePolicyManagerWrapperImpl; import com.android.settings.enterprise.EnterprisePrivacyFeatureProvider; import com.android.settings.enterprise.EnterprisePrivacyFeatureProviderImpl; import com.android.settings.fuelgauge.PowerUsageFeatureProvider; @@ -53,7 +50,10 @@ import com.android.settings.security.SecurityFeatureProvider; import com.android.settings.security.SecurityFeatureProviderImpl; import com.android.settings.users.UserFeatureProvider; import com.android.settings.users.UserFeatureProviderImpl; -import com.android.settings.vpn2.ConnectivityManagerWrapperImpl; +import com.android.settings.wrapper.ConnectivityManagerWrapper; +import com.android.settings.wrapper.DevicePolicyManagerWrapper; +import com.android.settings.wrapper.IPackageManagerWrapper; +import com.android.settingslib.wrapper.PackageManagerWrapper; /** * {@link FeatureFactory} implementation for AOSP Settings. @@ -109,9 +109,9 @@ public class FeatureFactoryImpl extends FeatureFactory { public ApplicationFeatureProvider getApplicationFeatureProvider(Context context) { if (mApplicationFeatureProvider == null) { mApplicationFeatureProvider = new ApplicationFeatureProviderImpl(context, - new PackageManagerWrapperImpl(context.getPackageManager()), - new IPackageManagerWrapperImpl(AppGlobals.getPackageManager()), - new DevicePolicyManagerWrapperImpl((DevicePolicyManager) context + new PackageManagerWrapper(context.getPackageManager()), + new IPackageManagerWrapper(AppGlobals.getPackageManager()), + new DevicePolicyManagerWrapper((DevicePolicyManager) context .getSystemService(Context.DEVICE_POLICY_SERVICE))); } return mApplicationFeatureProvider; @@ -129,11 +129,11 @@ public class FeatureFactoryImpl extends FeatureFactory { public EnterprisePrivacyFeatureProvider getEnterprisePrivacyFeatureProvider(Context context) { if (mEnterprisePrivacyFeatureProvider == null) { mEnterprisePrivacyFeatureProvider = new EnterprisePrivacyFeatureProviderImpl(context, - new DevicePolicyManagerWrapperImpl((DevicePolicyManager) context + new DevicePolicyManagerWrapper((DevicePolicyManager) context .getSystemService(Context.DEVICE_POLICY_SERVICE)), - new PackageManagerWrapperImpl(context.getPackageManager()), + new PackageManagerWrapper(context.getPackageManager()), UserManager.get(context), - new ConnectivityManagerWrapperImpl((ConnectivityManager) context + new ConnectivityManagerWrapper((ConnectivityManager) context .getSystemService(Context.CONNECTIVITY_SERVICE)), context.getResources()); } diff --git a/src/com/android/settings/password/IFingerprintManager.java b/src/com/android/settings/password/IFingerprintManager.java deleted file mode 100644 index 94021460bfc..00000000000 --- a/src/com/android/settings/password/IFingerprintManager.java +++ /dev/null @@ -1,39 +0,0 @@ -/* - * 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.password; - -import android.hardware.fingerprint.FingerprintManager.EnrollmentCallback; -import android.os.CancellationSignal; - -/** - * This is the workaround to allow us test {@link SetNewPasswordController} which uses a new hidden - * API {@link android.hardware.fingerprint.FingerprintManager#hasEnrolledFingerprints(int)} that - * roboelectric does not support yet. Having roboelectic to support latest platform API is tracked - * in b/30995831. - */ -public interface IFingerprintManager { - boolean isHardwareDetected(); - - boolean hasEnrolledFingerprints(int userId); - - long preEnroll(); - - void setActiveUser(int userId); - - void enroll(byte [] token, CancellationSignal cancel, int flags, - int userId, EnrollmentCallback callback); -} diff --git a/src/com/android/settings/password/SetNewPasswordController.java b/src/com/android/settings/password/SetNewPasswordController.java index 57aa8c17d1d..a974da4f0ec 100644 --- a/src/com/android/settings/password/SetNewPasswordController.java +++ b/src/com/android/settings/password/SetNewPasswordController.java @@ -36,6 +36,7 @@ import android.os.UserManager; import com.android.internal.annotations.VisibleForTesting; import com.android.internal.widget.LockPatternUtils; import com.android.settings.Utils; +import com.android.settings.wrapper.FingerprintManagerWrapper; /** * Business logic for {@link SetNewPasswordActivity}. @@ -56,7 +57,7 @@ final class SetNewPasswordController { */ private final int mTargetUserId; private final PackageManager mPackageManager; - @Nullable private final IFingerprintManager mFingerprintManager; + @Nullable private final FingerprintManagerWrapper mFingerprintManager; private final DevicePolicyManager mDevicePolicyManager; private final Ui mUi; @@ -77,7 +78,7 @@ final class SetNewPasswordController { } // Create a wrapper of FingerprintManager for testing, see IFingerPrintManager for details. final FingerprintManager fingerprintManager = Utils.getFingerprintManagerOrNull(context); - final IFingerprintManager fingerprintManagerWrapper = + final FingerprintManagerWrapper fingerprintManagerWrapper = fingerprintManager == null ? null : new FingerprintManagerWrapper(fingerprintManager); @@ -91,7 +92,7 @@ final class SetNewPasswordController { SetNewPasswordController( int targetUserId, PackageManager packageManager, - IFingerprintManager fingerprintManager, + FingerprintManagerWrapper fingerprintManager, DevicePolicyManager devicePolicyManager, Ui ui) { mTargetUserId = targetUserId; diff --git a/src/com/android/settings/search/InstalledAppResultLoader.java b/src/com/android/settings/search/InstalledAppResultLoader.java index 9d80b734a44..69a4693d780 100644 --- a/src/com/android/settings/search/InstalledAppResultLoader.java +++ b/src/com/android/settings/search/InstalledAppResultLoader.java @@ -34,9 +34,9 @@ import com.android.internal.logging.nano.MetricsProto; import com.android.settings.R; import com.android.settings.SettingsActivity; import com.android.settings.applications.ManageApplications; -import com.android.settings.applications.PackageManagerWrapper; import com.android.settings.dashboard.SiteMapManager; import com.android.settings.utils.AsyncLoader; +import com.android.settingslib.wrapper.PackageManagerWrapper; import java.util.ArrayList; import java.util.HashSet; diff --git a/src/com/android/settings/search/SearchFeatureProviderImpl.java b/src/com/android/settings/search/SearchFeatureProviderImpl.java index 69c086f1659..420b8470d91 100644 --- a/src/com/android/settings/search/SearchFeatureProviderImpl.java +++ b/src/com/android/settings/search/SearchFeatureProviderImpl.java @@ -21,9 +21,9 @@ import android.content.Context; import android.text.TextUtils; import android.util.Log; -import com.android.settings.applications.PackageManagerWrapperImpl; import com.android.settings.dashboard.SiteMapManager; import com.android.settings.overlay.FeatureFactory; +import com.android.settingslib.wrapper.PackageManagerWrapper; /** * FeatureProvider for the refactored search code. @@ -50,7 +50,7 @@ public class SearchFeatureProviderImpl implements SearchFeatureProvider { @Override public InstalledAppResultLoader getInstalledAppSearchLoader(Context context, String query) { return new InstalledAppResultLoader( - context, new PackageManagerWrapperImpl(context.getPackageManager()), + context, new PackageManagerWrapper(context.getPackageManager()), cleanQuery(query), getSiteMapManager()); } diff --git a/src/com/android/settings/vpn2/ConnectivityManagerWrapperImpl.java b/src/com/android/settings/vpn2/ConnectivityManagerWrapperImpl.java deleted file mode 100644 index f742cd22b06..00000000000 --- a/src/com/android/settings/vpn2/ConnectivityManagerWrapperImpl.java +++ /dev/null @@ -1,59 +0,0 @@ -/* - * 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.vpn2; - -import android.net.ConnectivityManager; -import android.net.ConnectivityManager.NetworkCallback; -import android.net.Network; -import android.net.NetworkRequest; -import android.os.Handler; -import android.net.ProxyInfo; - -public class ConnectivityManagerWrapperImpl implements ConnectivityManagerWrapper { - - private final ConnectivityManager mCm; - - public ConnectivityManagerWrapperImpl(ConnectivityManager cm) { - mCm = cm; - } - - @Override - public ConnectivityManager getConnectivityManager() { - return mCm; - } - - @Override - public String getAlwaysOnVpnPackageForUser(int userId) { - return mCm.getAlwaysOnVpnPackageForUser(userId); - } - - @Override - public ProxyInfo getGlobalProxy() { - return mCm.getGlobalProxy(); - } - - @Override - public void registerNetworkCallback(NetworkRequest request, NetworkCallback callback, - Handler handler) { - mCm.registerNetworkCallback(request, callback, handler); - } - - @Override - public void startCaptivePortalApp(Network network) { - mCm.startCaptivePortalApp(network); - } -} diff --git a/src/com/android/settings/vpn2/VpnUtils.java b/src/com/android/settings/vpn2/VpnUtils.java index a36cce82e01..1aa4adaea41 100644 --- a/src/com/android/settings/vpn2/VpnUtils.java +++ b/src/com/android/settings/vpn2/VpnUtils.java @@ -27,6 +27,7 @@ import android.util.Log; import com.android.internal.net.LegacyVpnInfo; import com.android.internal.net.VpnConfig; +import com.android.settings.wrapper.ConnectivityManagerWrapper; /** * Utility functions for vpn. diff --git a/src/com/android/settings/webview/WebViewAppPicker.java b/src/com/android/settings/webview/WebViewAppPicker.java index 380b964ab7e..362ca1f2535 100644 --- a/src/com/android/settings/webview/WebViewAppPicker.java +++ b/src/com/android/settings/webview/WebViewAppPicker.java @@ -30,9 +30,10 @@ import android.text.TextUtils; import com.android.internal.logging.nano.MetricsProto.MetricsEvent; import com.android.settings.R; -import com.android.settings.applications.PackageManagerWrapper; import com.android.settings.applications.defaultapps.DefaultAppInfo; import com.android.settings.applications.defaultapps.DefaultAppPickerFragment; +import com.android.settings.wrapper.UserPackageWrapper; +import com.android.settingslib.wrapper.PackageManagerWrapper; import java.util.ArrayList; import java.util.List; diff --git a/src/com/android/settings/webview/WebViewUpdateServiceWrapper.java b/src/com/android/settings/webview/WebViewUpdateServiceWrapper.java index b40be1941fa..e4eb0fcfca4 100644 --- a/src/com/android/settings/webview/WebViewUpdateServiceWrapper.java +++ b/src/com/android/settings/webview/WebViewUpdateServiceWrapper.java @@ -28,6 +28,8 @@ import android.webkit.WebViewProviderInfo; import android.widget.Toast; import com.android.settings.R; +import com.android.settings.wrapper.UserPackageWrapper; +import com.android.settings.wrapper.UserPackageWrapperImpl; import java.util.ArrayList; import java.util.List; diff --git a/src/com/android/settings/wifi/ConfigureWifiSettings.java b/src/com/android/settings/wifi/ConfigureWifiSettings.java index 4199a6d3b97..3c700483d99 100644 --- a/src/com/android/settings/wifi/ConfigureWifiSettings.java +++ b/src/com/android/settings/wifi/ConfigureWifiSettings.java @@ -28,12 +28,12 @@ import android.provider.SearchIndexableResource; import com.android.internal.logging.nano.MetricsProto.MetricsEvent; import com.android.settings.R; import com.android.settings.dashboard.DashboardFragment; -import com.android.settings.network.NetworkScoreManagerWrapper; import com.android.settings.network.NetworkScorerPickerPreferenceController; import com.android.settings.network.WifiCallingPreferenceController; import com.android.settings.search.BaseSearchIndexProvider; import com.android.settings.search.Indexable; import com.android.settings.wifi.p2p.WifiP2pPreferenceController; +import com.android.settings.wrapper.NetworkScoreManagerWrapper; import com.android.settingslib.core.AbstractPreferenceController; import java.util.ArrayList; diff --git a/src/com/android/settings/wifi/ConnectivityManagerWrapper.java b/src/com/android/settings/wifi/ConnectivityManagerWrapper.java deleted file mode 100644 index 73176663cc6..00000000000 --- a/src/com/android/settings/wifi/ConnectivityManagerWrapper.java +++ /dev/null @@ -1,36 +0,0 @@ -/* - * 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.wifi; - -import android.net.ConnectivityManager; - -/** - * Wrapper around {@link ConnectivityManager} to facilitate unit testing. - */ -public class ConnectivityManagerWrapper { - private final ConnectivityManager mConnectivityManager; - - public ConnectivityManagerWrapper(ConnectivityManager connectivityManager) { - mConnectivityManager = connectivityManager; - } - - /** - * {@link ConnectivityManager#stopTethering} - */ - public void stopTethering(int type) { - mConnectivityManager.stopTethering(type); - } -} diff --git a/src/com/android/settings/wifi/UseOpenWifiPreferenceController.java b/src/com/android/settings/wifi/UseOpenWifiPreferenceController.java index d44c8a9d636..c563fce4261 100644 --- a/src/com/android/settings/wifi/UseOpenWifiPreferenceController.java +++ b/src/com/android/settings/wifi/UseOpenWifiPreferenceController.java @@ -21,7 +21,7 @@ import android.text.TextUtils; import com.android.settings.R; import com.android.settings.core.PreferenceControllerMixin; -import com.android.settings.network.NetworkScoreManagerWrapper; +import com.android.settings.wrapper.NetworkScoreManagerWrapper; import com.android.settingslib.core.AbstractPreferenceController; import com.android.settingslib.core.lifecycle.Lifecycle; import com.android.settingslib.core.lifecycle.LifecycleObserver; diff --git a/src/com/android/settings/wifi/WifiEnabler.java b/src/com/android/settings/wifi/WifiEnabler.java index 77188987b3d..9c431422371 100644 --- a/src/com/android/settings/wifi/WifiEnabler.java +++ b/src/com/android/settings/wifi/WifiEnabler.java @@ -35,6 +35,7 @@ import com.android.internal.logging.nano.MetricsProto.MetricsEvent; import com.android.settings.R; import com.android.settings.core.instrumentation.MetricsFeatureProvider; import com.android.settings.widget.SwitchWidgetController; +import com.android.settings.wrapper.ConnectivityManagerWrapper; import com.android.settingslib.RestrictedLockUtils; import com.android.settingslib.RestrictedLockUtils.EnforcedAdmin; import com.android.settingslib.WirelessUtils; diff --git a/src/com/android/settings/wifi/WifiSettings.java b/src/com/android/settings/wifi/WifiSettings.java index f3b08bf1dac..bc302b98395 100644 --- a/src/com/android/settings/wifi/WifiSettings.java +++ b/src/com/android/settings/wifi/WifiSettings.java @@ -65,6 +65,7 @@ import com.android.settings.search.SearchIndexableRaw; import com.android.settings.widget.SummaryUpdater.OnSummaryChangeListener; import com.android.settings.widget.SwitchBarController; import com.android.settings.wifi.details.WifiNetworkDetailsFragment; +import com.android.settings.wrapper.WifiManagerWrapper; import com.android.settingslib.RestrictedLockUtils; import com.android.settingslib.wifi.AccessPoint; import com.android.settingslib.wifi.AccessPoint.AccessPointListener; diff --git a/src/com/android/settings/wifi/WifiWakeupPreferenceController.java b/src/com/android/settings/wifi/WifiWakeupPreferenceController.java index efb8aa6f84a..a3170c09cbc 100644 --- a/src/com/android/settings/wifi/WifiWakeupPreferenceController.java +++ b/src/com/android/settings/wifi/WifiWakeupPreferenceController.java @@ -29,7 +29,7 @@ import android.text.TextUtils; import com.android.settings.R; import com.android.settings.core.PreferenceControllerMixin; -import com.android.settings.network.NetworkScoreManagerWrapper; +import com.android.settings.wrapper.NetworkScoreManagerWrapper; import com.android.settingslib.core.AbstractPreferenceController; import com.android.settingslib.core.lifecycle.Lifecycle; import com.android.settingslib.core.lifecycle.LifecycleObserver; diff --git a/src/com/android/settings/wifi/WriteWifiConfigToNfcDialog.java b/src/com/android/settings/wifi/WriteWifiConfigToNfcDialog.java index 52871f6cba4..dfed8018457 100644 --- a/src/com/android/settings/wifi/WriteWifiConfigToNfcDialog.java +++ b/src/com/android/settings/wifi/WriteWifiConfigToNfcDialog.java @@ -20,7 +20,6 @@ import android.app.Activity; import android.app.AlertDialog; import android.content.Context; import android.content.DialogInterface; -import android.net.wifi.WifiManager; import android.nfc.FormatException; import android.nfc.NdefMessage; import android.nfc.NdefRecord; @@ -43,6 +42,7 @@ import android.widget.ProgressBar; import android.widget.TextView; import com.android.settings.R; +import com.android.settings.wrapper.WifiManagerWrapper; import com.android.settingslib.wifi.AccessPoint; import java.io.IOException; diff --git a/src/com/android/settings/wifi/details/WifiDetailPreferenceController.java b/src/com/android/settings/wifi/details/WifiDetailPreferenceController.java index 014fb0f84ac..40acfeb4e02 100644 --- a/src/com/android/settings/wifi/details/WifiDetailPreferenceController.java +++ b/src/com/android/settings/wifi/details/WifiDetailPreferenceController.java @@ -57,12 +57,12 @@ import com.android.settings.Utils; import com.android.settings.applications.LayoutPreference; import com.android.settings.core.PreferenceControllerMixin; import com.android.settings.core.instrumentation.MetricsFeatureProvider; -import com.android.settings.vpn2.ConnectivityManagerWrapper; import com.android.settings.widget.ActionButtonPreference; import com.android.settings.widget.EntityHeaderController; import com.android.settings.wifi.WifiDetailPreference; import com.android.settings.wifi.WifiDialog; import com.android.settings.wifi.WifiDialog.WifiDialogListener; +import com.android.settings.wrapper.ConnectivityManagerWrapper; import com.android.settingslib.core.AbstractPreferenceController; import com.android.settingslib.core.lifecycle.Lifecycle; import com.android.settingslib.core.lifecycle.LifecycleObserver; diff --git a/src/com/android/settings/wifi/details/WifiNetworkDetailsFragment.java b/src/com/android/settings/wifi/details/WifiNetworkDetailsFragment.java index 765bebccb2b..1609bef2980 100644 --- a/src/com/android/settings/wifi/details/WifiNetworkDetailsFragment.java +++ b/src/com/android/settings/wifi/details/WifiNetworkDetailsFragment.java @@ -31,9 +31,9 @@ import com.android.internal.logging.nano.MetricsProto; import com.android.internal.logging.nano.MetricsProto.MetricsEvent; import com.android.settings.R; import com.android.settings.dashboard.DashboardFragment; -import com.android.settings.vpn2.ConnectivityManagerWrapperImpl; import com.android.settings.wifi.WifiConfigUiBase; import com.android.settings.wifi.WifiDialog; +import com.android.settings.wrapper.ConnectivityManagerWrapper; import com.android.settingslib.core.AbstractPreferenceController; import com.android.settingslib.wifi.AccessPoint; import java.util.ArrayList; @@ -117,7 +117,7 @@ public class WifiNetworkDetailsFragment extends DashboardFragment { ConnectivityManager cm = context.getSystemService(ConnectivityManager.class); mWifiDetailPreferenceController = WifiDetailPreferenceController.newInstance( mAccessPoint, - new ConnectivityManagerWrapperImpl(cm), + new ConnectivityManagerWrapper(cm), context, this, new Handler(Looper.getMainLooper()), // UI thread. diff --git a/src/com/android/settings/applications/AccessibilityManagerWrapperImpl.java b/src/com/android/settings/wrapper/AccessibilityManagerWrapper.java similarity index 93% rename from src/com/android/settings/applications/AccessibilityManagerWrapperImpl.java rename to src/com/android/settings/wrapper/AccessibilityManagerWrapper.java index 4ebaea759fc..4fd7ccffa67 100644 --- a/src/com/android/settings/applications/AccessibilityManagerWrapperImpl.java +++ b/src/com/android/settings/wrapper/AccessibilityManagerWrapper.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package com.android.settings.applications; +package com.android.settings.wrapper; import android.view.accessibility.AccessibilityManager; @@ -23,7 +23,7 @@ import android.view.accessibility.AccessibilityManager; * The interface exists so that we can use a thin wrapper around the AccessibilityManager in * production code and a mock in tests. */ -public class AccessibilityManagerWrapperImpl { +public class AccessibilityManagerWrapper { /** * Determines if the accessibility button within the system navigation area is supported. diff --git a/src/com/android/settings/applications/AccessibilityServiceInfoWrapper.java b/src/com/android/settings/wrapper/AccessibilityServiceInfoWrapper.java similarity index 67% rename from src/com/android/settings/applications/AccessibilityServiceInfoWrapper.java rename to src/com/android/settings/wrapper/AccessibilityServiceInfoWrapper.java index 6ce0a4a9bcd..c920392306d 100644 --- a/src/com/android/settings/applications/AccessibilityServiceInfoWrapper.java +++ b/src/com/android/settings/wrapper/AccessibilityServiceInfoWrapper.java @@ -14,24 +14,34 @@ * limitations under the License. */ -package com.android.settings.applications; +package com.android.settings.wrapper; import android.accessibilityservice.AccessibilityServiceInfo; import android.content.ComponentName; /** - * This interface replicates a subset of the - * {@link android.accessibilityservice.AccessibilityServiceInfo}. The interface + * This class replicates a subset of the + * {@link android.accessibilityservice.AccessibilityServiceInfo}. The class * exists so that we can use a thin wrapper around it in production code and a mock in tests. * We cannot directly mock or shadow it, because some of the methods we rely on are newer than * the API version supported by Robolectric. */ -public interface AccessibilityServiceInfoWrapper { +public class AccessibilityServiceInfoWrapper { + + private final AccessibilityServiceInfo mServiceInfo; + + public AccessibilityServiceInfoWrapper(AccessibilityServiceInfo serviceInfo) { + mServiceInfo = serviceInfo; + } /** * Returns the real {@code AccessibilityServiceInfo} object. */ - AccessibilityServiceInfo getAccessibilityServiceInfo(); + public AccessibilityServiceInfo getAccessibilityServiceInfo() { + return mServiceInfo; + } - ComponentName getComponentName(); + public ComponentName getComponentName() { + return mServiceInfo.getComponentName(); + } } diff --git a/src/com/android/settings/applications/ActivityInfoWrapperImpl.java b/src/com/android/settings/wrapper/ActivityInfoWrapper.java similarity index 67% rename from src/com/android/settings/applications/ActivityInfoWrapperImpl.java rename to src/com/android/settings/wrapper/ActivityInfoWrapper.java index b70a1e87235..37d0d423772 100644 --- a/src/com/android/settings/applications/ActivityInfoWrapperImpl.java +++ b/src/com/android/settings/wrapper/ActivityInfoWrapper.java @@ -14,19 +14,26 @@ * limitations under the License. */ -package com.android.settings.applications; +package com.android.settings.wrapper; import android.content.pm.ActivityInfo; -public class ActivityInfoWrapperImpl implements ActivityInfoWrapper { +/** + * This class replicates a subset of the android.content.pm.ActivityInfo. The class + * exists so that we can use a thin wrapper around the ActivityInfo in production code and a mock in + * tests. + */ +public class ActivityInfoWrapper { private final ActivityInfo mInfo; - public ActivityInfoWrapperImpl(ActivityInfo info) { + public ActivityInfoWrapper(ActivityInfo info) { mInfo = info; } - @Override + /** + * Returns whether this activity supports picture-in-picture. + */ public boolean supportsPictureInPicture() { return mInfo.supportsPictureInPicture(); } diff --git a/src/com/android/settings/applications/AutofillManagerWrapper.java b/src/com/android/settings/wrapper/AutofillManagerWrapper.java similarity index 61% rename from src/com/android/settings/applications/AutofillManagerWrapper.java rename to src/com/android/settings/wrapper/AutofillManagerWrapper.java index 04091b01d4c..57c9375ec2d 100644 --- a/src/com/android/settings/applications/AutofillManagerWrapper.java +++ b/src/com/android/settings/wrapper/AutofillManagerWrapper.java @@ -14,28 +14,46 @@ * limitations under the License. */ -package com.android.settings.applications; +package com.android.settings.wrapper; import android.view.autofill.AutofillManager; /** - * This interface replicates a subset of the android.view.autofill.AutofillManager (AFM). The - * interface exists so that we can use a thin wrapper around the AFM in production code and a mock + * This class replicates a subset of the android.view.autofill.AutofillManager (AFM). The + * class exists so that we can use a thin wrapper around the AFM in production code and a mock * in tests. We cannot directly mock or shadow the AFM, because some of the methods we rely on are * newer than the API version supported by Robolectric. */ -public interface AutofillManagerWrapper { +public class AutofillManagerWrapper { + private final AutofillManager mAfm; + + public AutofillManagerWrapper(AutofillManager afm) { + mAfm = afm; + } + /** * Calls {@code AutofillManager.hasAutofillFeature()}. * * @see AutofillManager#hasAutofillFeature */ - public boolean hasAutofillFeature(); + public boolean hasAutofillFeature() { + if (mAfm == null) { + return false; + } + + return mAfm.hasAutofillFeature(); + } /** * Calls {@code AutofillManager.isAutofillSupported()}. * * @see AutofillManager#isAutofillSupported */ - public boolean isAutofillSupported(); + public boolean isAutofillSupported() { + if (mAfm == null) { + return false; + } + + return mAfm.isAutofillSupported(); + } } diff --git a/src/com/android/settings/vpn2/ConnectivityManagerWrapper.java b/src/com/android/settings/wrapper/ConnectivityManagerWrapper.java similarity index 72% rename from src/com/android/settings/vpn2/ConnectivityManagerWrapper.java rename to src/com/android/settings/wrapper/ConnectivityManagerWrapper.java index 9e20c9d1fd8..c80a97b3afa 100644 --- a/src/com/android/settings/vpn2/ConnectivityManagerWrapper.java +++ b/src/com/android/settings/wrapper/ConnectivityManagerWrapper.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package com.android.settings.vpn2; +package com.android.settings.wrapper; import android.net.ConnectivityManager; import android.net.ConnectivityManager.NetworkCallback; @@ -24,31 +24,43 @@ import android.os.Handler; import android.net.ProxyInfo; /** - * This interface replicates a subset of the android.net.ConnectivityManager (CM). The interface + * This class replicates a subset of the android.net.ConnectivityManager (CM). The class * exists so that we can use a thin wrapper around the CM in production code and a mock in tests. * We cannot directly mock or shadow the CM, because some of the methods we rely on are marked as * hidden and are thus invisible to Robolectric. */ -public interface ConnectivityManagerWrapper { +public class ConnectivityManagerWrapper { + + private final ConnectivityManager mCm; + + public ConnectivityManagerWrapper(ConnectivityManager cm) { + mCm = cm; + } /** * Returns the real ConnectivityManager object wrapped by this wrapper. */ - public ConnectivityManager getConnectivityManager(); + public ConnectivityManager getConnectivityManager() { + return mCm; + } /** * Calls {@code ConnectivityManager.getAlwaysOnVpnPackageForUser()}. * * @see android.net.ConnectivityManager#getAlwaysOnVpnPackageForUser */ - String getAlwaysOnVpnPackageForUser(int userId); + public String getAlwaysOnVpnPackageForUser(int userId) { + return mCm.getAlwaysOnVpnPackageForUser(userId); + } /** * Calls {@code ConnectivityManager.getGlobalProxy()}. * * @see android.net.ConnectivityManager#getGlobalProxy */ - ProxyInfo getGlobalProxy(); + public ProxyInfo getGlobalProxy() { + return mCm.getGlobalProxy(); + } /** * Calls {@code ConnectivityManager.registerNetworkCallback()}. @@ -60,7 +72,9 @@ public interface ConnectivityManagerWrapper { * @see android.net.ConnectivityManager#registerNetworkCallback(NetworkRequest,NetworkCallback,Handler) */ public void registerNetworkCallback(NetworkRequest request, NetworkCallback callback, - Handler handler); + Handler handler) { + mCm.registerNetworkCallback(request, callback, handler); + } /** * Calls {@code ConnectivityManager.startCaptivePortalApp()}. @@ -71,5 +85,14 @@ public interface ConnectivityManagerWrapper { * * @see android.net.ConnectivityManager#startCaptivePortalApp(Network) */ - public void startCaptivePortalApp(Network network); + public void startCaptivePortalApp(Network network) { + mCm.startCaptivePortalApp(network); + } + + /** + * {@link ConnectivityManager#stopTethering} + */ + public void stopTethering(int type) { + mCm.stopTethering(type); + } } diff --git a/src/com/android/settings/enterprise/DevicePolicyManagerWrapper.java b/src/com/android/settings/wrapper/DevicePolicyManagerWrapper.java similarity index 59% rename from src/com/android/settings/enterprise/DevicePolicyManagerWrapper.java rename to src/com/android/settings/wrapper/DevicePolicyManagerWrapper.java index ede241a0f10..ed2eb462ae4 100644 --- a/src/com/android/settings/enterprise/DevicePolicyManagerWrapper.java +++ b/src/com/android/settings/wrapper/DevicePolicyManagerWrapper.java @@ -14,9 +14,10 @@ * limitations under the License. */ -package com.android.settings.enterprise; +package com.android.settings.wrapper; import android.annotation.NonNull; +import android.app.admin.DevicePolicyManager; import android.content.ComponentName; import android.content.Intent; import android.os.UserHandle; @@ -25,137 +26,178 @@ import android.support.annotation.Nullable; import java.util.List; /** - * This interface replicates a subset of the android.app.admin.DevicePolicyManager (DPM). The - * interface exists so that we can use a thin wrapper around the DPM in production code and a mock + * This class replicates a subset of the android.app.admin.DevicePolicyManager (DPM). The + * class exists so that we can use a thin wrapper around the DPM in production code and a mock * in tests. We cannot directly mock or shadow the DPM, because some of the methods we rely on are * newer than the API version supported by Robolectric. */ -public interface DevicePolicyManagerWrapper { +public class DevicePolicyManagerWrapper { + private final DevicePolicyManager mDpm; + + public DevicePolicyManagerWrapper(DevicePolicyManager dpm) { + mDpm = dpm; + } + /** * Calls {@code DevicePolicyManager.getActiveAdminsAsUser()}. * * @see android.app.admin.DevicePolicyManager#getActiveAdminsAsUser */ - public @Nullable List getActiveAdminsAsUser(int userId); + public @Nullable List getActiveAdminsAsUser(int userId) { + return mDpm.getActiveAdminsAsUser(userId); + } /** * Calls {@code DevicePolicyManager.getMaximumFailedPasswordsForWipe()}. * * @see android.app.admin.DevicePolicyManager#getMaximumFailedPasswordsForWipe */ - int getMaximumFailedPasswordsForWipe(@Nullable ComponentName admin, int userHandle); + public int getMaximumFailedPasswordsForWipe(@Nullable ComponentName admin, int userHandle) { + return mDpm.getMaximumFailedPasswordsForWipe(admin, userHandle); + } /** * Calls {@code DevicePolicyManager.getDeviceOwnerComponentOnCallingUser()}. * * @see android.app.admin.DevicePolicyManager#getDeviceOwnerComponentOnCallingUser */ - ComponentName getDeviceOwnerComponentOnCallingUser(); + public ComponentName getDeviceOwnerComponentOnCallingUser() { + return mDpm.getDeviceOwnerComponentOnCallingUser(); + } /** * Calls {@code DevicePolicyManager.getDeviceOwnerComponentOnAnyUser()}. * * @see android.app.admin.DevicePolicyManager#getDeviceOwnerComponentOnAnyUser */ - ComponentName getDeviceOwnerComponentOnAnyUser(); + public ComponentName getDeviceOwnerComponentOnAnyUser() { + return mDpm.getDeviceOwnerComponentOnAnyUser(); + } /** * Calls {@code DevicePolicyManager.getProfileOwnerAsUser()}. * * @see android.app.admin.DevicePolicyManager#getProfileOwnerAsUser */ - @Nullable ComponentName getProfileOwnerAsUser(final int userId); + public @Nullable ComponentName getProfileOwnerAsUser(final int userId) { + return mDpm.getProfileOwnerAsUser(userId); + } /** * Calls {@code DevicePolicyManager.getDeviceOwnerNameOnAnyUser()}. * * @see android.app.admin.DevicePolicyManager#getDeviceOwnerNameOnAnyUser */ - CharSequence getDeviceOwnerOrganizationName(); + public CharSequence getDeviceOwnerOrganizationName() { + return mDpm.getDeviceOwnerOrganizationName(); + } /** * Calls {@code DevicePolicyManager.getPermissionGrantState()}. * * @see android.app.admin.DevicePolicyManager#getPermissionGrantState */ - int getPermissionGrantState(@Nullable ComponentName admin, String packageName, - String permission); + public int getPermissionGrantState(@Nullable ComponentName admin, String packageName, + String permission) { + return mDpm.getPermissionGrantState(admin, packageName, permission); + } /** * Calls {@code DevicePolicyManager.isSecurityLoggingEnabled()}. * * @see android.app.admin.DevicePolicyManager#isSecurityLoggingEnabled */ - boolean isSecurityLoggingEnabled(@Nullable ComponentName admin); + public boolean isSecurityLoggingEnabled(@Nullable ComponentName admin) { + return mDpm.isSecurityLoggingEnabled(admin); + } /** * Calls {@code DevicePolicyManager.isNetworkLoggingEnabled()}. * * @see android.app.admin.DevicePolicyManager#isNetworkLoggingEnabled */ - boolean isNetworkLoggingEnabled(@Nullable ComponentName admin); + public boolean isNetworkLoggingEnabled(@Nullable ComponentName admin) { + return mDpm.isNetworkLoggingEnabled(admin); + } /** * Calls {@code DevicePolicyManager.getLastSecurityLogRetrievalTime()}. * * @see android.app.admin.DevicePolicyManager#getLastSecurityLogRetrievalTime */ - long getLastSecurityLogRetrievalTime(); + public long getLastSecurityLogRetrievalTime() { + return mDpm.getLastSecurityLogRetrievalTime(); + } /** * Calls {@code DevicePolicyManager.getLastBugReportRequestTime()}. * * @see android.app.admin.DevicePolicyManager#getLastBugReportRequestTime */ - long getLastBugReportRequestTime(); + public long getLastBugReportRequestTime() { + return mDpm.getLastBugReportRequestTime(); + } /** * Calls {@code DevicePolicyManager.getLastNetworkLogRetrievalTime()}. * * @see android.app.admin.DevicePolicyManager#getLastNetworkLogRetrievalTime */ - long getLastNetworkLogRetrievalTime(); + public long getLastNetworkLogRetrievalTime() { + return mDpm.getLastNetworkLogRetrievalTime(); + } /** * Calls {@code DevicePolicyManager.isCurrentInputMethodSetByOwner()}. * * @see android.app.admin.DevicePolicyManager#isCurrentInputMethodSetByOwner */ - boolean isCurrentInputMethodSetByOwner(); - + public boolean isCurrentInputMethodSetByOwner() { + return mDpm.isCurrentInputMethodSetByOwner(); + } /** * Calls {@code DevicePolicyManager.getOwnerInstalledCaCerts()}. * * @see android.app.admin.DevicePolicyManager#getOwnerInstalledCaCerts */ - List getOwnerInstalledCaCerts(@NonNull UserHandle user); + public List getOwnerInstalledCaCerts(@NonNull UserHandle user) { + return mDpm.getOwnerInstalledCaCerts(user); + } /** * Calls {@code DevicePolicyManager.isDeviceOwnerAppOnAnyUser()}. * * @see android.app.admin.DevicePolicyManager#isDeviceOwnerAppOnAnyUser */ - boolean isDeviceOwnerAppOnAnyUser(String packageName); + public boolean isDeviceOwnerAppOnAnyUser(String packageName) { + return mDpm.isDeviceOwnerAppOnAnyUser(packageName); + } /** * Calls {@code DevicePolicyManager.packageHasActiveAdmins()}. * * @see android.app.admin.DevicePolicyManager#packageHasActiveAdmins */ - boolean packageHasActiveAdmins(String packageName); + public boolean packageHasActiveAdmins(String packageName) { + return mDpm.packageHasActiveAdmins(packageName); + } /** * Calls {@code DevicePolicyManager.isUninstallInQueue()}. * * @see android.app.admin.DevicePolicyManager#isUninstallInQueue */ - boolean isUninstallInQueue(String packageName); + public boolean isUninstallInQueue(String packageName) { + return mDpm.isUninstallInQueue(packageName); + } /** * Calls {@code DevicePolicyManager.createAdminSupportIntent()}. * * @see android.app.admin.DevicePolicyManager#createAdminSupportIntent */ - Intent createAdminSupportIntent(String restriction); + public Intent createAdminSupportIntent(@NonNull String restriction) { + return mDpm.createAdminSupportIntent(restriction); + } } diff --git a/src/com/android/settings/password/FingerprintManagerWrapper.java b/src/com/android/settings/wrapper/FingerprintManagerWrapper.java similarity index 79% rename from src/com/android/settings/password/FingerprintManagerWrapper.java rename to src/com/android/settings/wrapper/FingerprintManagerWrapper.java index 51b31afc9e6..9b43bfaa027 100644 --- a/src/com/android/settings/password/FingerprintManagerWrapper.java +++ b/src/com/android/settings/wrapper/FingerprintManagerWrapper.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package com.android.settings.password; +package com.android.settings.wrapper; import android.annotation.NonNull; import android.hardware.fingerprint.FingerprintManager; @@ -24,10 +24,14 @@ import android.os.CancellationSignal; import com.android.internal.util.Preconditions; /** - * Wrapper of {@link FingerprintManager}. Workaround for roboelectic testing. See - * {@link IFingerprintManager} for details. + * Wrapper of {@link FingerprintManager}. Workaround for robolectic testing. + * + * This is the workaround to allow us test {@link SetNewPasswordController} which uses a new hidden + * API {@link android.hardware.fingerprint.FingerprintManager#hasEnrolledFingerprints(int)} that + * robolectric does not support yet. Having robolectic to support latest platform API is tracked + * in b/30995831. */ -public class FingerprintManagerWrapper implements IFingerprintManager { +public class FingerprintManagerWrapper { private @NonNull FingerprintManager mFingerprintManager; public FingerprintManagerWrapper(@NonNull FingerprintManager fingerprintManager) { @@ -35,27 +39,22 @@ public class FingerprintManagerWrapper implements IFingerprintManager { mFingerprintManager = fingerprintManager; } - @Override public boolean isHardwareDetected() { return mFingerprintManager.isHardwareDetected(); } - @Override public boolean hasEnrolledFingerprints(int userId) { return mFingerprintManager.hasEnrolledFingerprints(userId); } - @Override public long preEnroll() { return mFingerprintManager.preEnroll(); } - @Override public void setActiveUser(int userId) { mFingerprintManager.setActiveUser(userId); } - @Override public void enroll( byte[] token, CancellationSignal cancel, diff --git a/src/com/android/settings/applications/IPackageManagerWrapper.java b/src/com/android/settings/wrapper/IPackageManagerWrapper.java similarity index 60% rename from src/com/android/settings/applications/IPackageManagerWrapper.java rename to src/com/android/settings/wrapper/IPackageManagerWrapper.java index b4d1b85e8f7..9bb2df72d02 100644 --- a/src/com/android/settings/applications/IPackageManagerWrapper.java +++ b/src/com/android/settings/wrapper/IPackageManagerWrapper.java @@ -14,62 +14,84 @@ * limitations under the License. */ -package com.android.settings.applications; +package com.android.settings.wrapper; import android.content.Intent; +import android.content.pm.IPackageManager; import android.content.pm.PackageInfo; import android.content.pm.ParceledListSlice; import android.content.pm.ResolveInfo; import android.os.RemoteException; /** - * This interface replicates a subset of the android.content.pm.IPackageManager (PMS). The interface + * This class replicates a subset of the android.content.pm.IPackageManager (PMS). The class * exists so that we can use a thin wrapper around the PMS in production code and a mock in tests. * We cannot directly mock or shadow the PMS, because some of the methods we rely on are newer than * the API version supported by Robolectric. */ -public interface IPackageManagerWrapper { +public class IPackageManagerWrapper { + + private final IPackageManager mPms; + + public IPackageManagerWrapper(IPackageManager pms) { + mPms = pms; + } /** * Calls {@code IPackageManager.checkUidPermission()}. * * @see android.content.pm.IPackageManager#checkUidPermission */ - int checkUidPermission(String permName, int uid) throws RemoteException; + public int checkUidPermission(String permName, int uid) throws RemoteException { + return mPms.checkUidPermission(permName, uid); + } /** * Calls {@code IPackageManager.findPersistentPreferredActivity()}. * * @see android.content.pm.IPackageManager#findPersistentPreferredActivity */ - ResolveInfo findPersistentPreferredActivity(Intent intent, int userId) throws RemoteException; + public ResolveInfo findPersistentPreferredActivity(Intent intent, int userId) + throws RemoteException { + return mPms.findPersistentPreferredActivity(intent, userId); + } /** * Calls {@code IPackageManager.getPackageInfo()}. * * @see android.content.pm.IPackageManager#getPackageInfo */ - PackageInfo getPackageInfo(String packageName, int flags, int userId) throws RemoteException; + public PackageInfo getPackageInfo(String packageName, int flags, int userId) + throws RemoteException { + return mPms.getPackageInfo(packageName, flags, userId); + } /** * Calls {@code IPackageManager.getAppOpPermissionPackages()}. * * @see android.content.pm.IPackageManager#getAppOpPermissionPackages */ - String[] getAppOpPermissionPackages(String permissionName) throws RemoteException; + public String[] getAppOpPermissionPackages(String permissionName) throws RemoteException { + return mPms.getAppOpPermissionPackages(permissionName); + } /** * Calls {@code IPackageManager.isPackageAvailable()}. * * @see android.content.pm.IPackageManager#isPackageAvailable */ - boolean isPackageAvailable(String packageName, int userId) throws RemoteException; + public boolean isPackageAvailable(String packageName, int userId) throws RemoteException { + return mPms.isPackageAvailable(packageName, userId); + } /** * Calls {@code IPackageManager.getPackagesHoldingPermissions()}. * * @see android.content.pm.IPackageManager#getPackagesHoldingPermissions */ - ParceledListSlice getPackagesHoldingPermissions( - String[] permissions, int flags, int userId) throws RemoteException; + public ParceledListSlice getPackagesHoldingPermissions( + String[] permissions, int flags, int userId) throws RemoteException { + return mPms.getPackagesHoldingPermissions(permissions, flags, userId); + } + } diff --git a/src/com/android/settings/fuelgauge/anomaly/KeyValueListParserWrapper.java b/src/com/android/settings/wrapper/KeyValueListParserWrapper.java similarity index 71% rename from src/com/android/settings/fuelgauge/anomaly/KeyValueListParserWrapper.java rename to src/com/android/settings/wrapper/KeyValueListParserWrapper.java index 4a9c2a92b45..16dc50eecdc 100644 --- a/src/com/android/settings/fuelgauge/anomaly/KeyValueListParserWrapper.java +++ b/src/com/android/settings/wrapper/KeyValueListParserWrapper.java @@ -14,22 +14,29 @@ * limitations under the License. */ -package com.android.settings.fuelgauge.anomaly; +package com.android.settings.wrapper; import android.util.KeyValueListParser; /** - * This interface replicates a subset of the {@link KeyValueListParser}. The interface + * This class replicates a subset of the {@link KeyValueListParser}. The class * exists so that we can use a thin wrapper around the PM in production code and a mock in tests. * We cannot directly mock or shadow the {@link KeyValueListParser}, because some of the methods * we rely on are newer than the API version supported by Robolectric. */ -public interface KeyValueListParserWrapper { +public class KeyValueListParserWrapper { + private KeyValueListParser mParser; + + public KeyValueListParserWrapper(KeyValueListParser parser) { + mParser = parser; + } /** * Get real {@link KeyValueListParser} */ - KeyValueListParser getKeyValueListParser(); + public KeyValueListParser getKeyValueListParser() { + return mParser; + } /** * Resets the parser with a new string to parse. The string is expected to be in the following @@ -41,7 +48,9 @@ public interface KeyValueListParserWrapper { * @param str the string to parse. * @throws IllegalArgumentException if the string is malformed. */ - void setString(String str) throws IllegalArgumentException; + public void setString(String str) throws IllegalArgumentException { + mParser.setString(str); + } /** * Get the value for key as a boolean. @@ -49,7 +58,9 @@ public interface KeyValueListParserWrapper { * @param defaultValue The value to return if the key was not found. * @return the string value associated with the key. */ - boolean getBoolean(String key, boolean defaultValue); + public boolean getBoolean(String key, boolean defaultValue) { + return mParser.getBoolean(key, defaultValue); + } /** * Get the value for key as a long. @@ -58,5 +69,7 @@ public interface KeyValueListParserWrapper { * long. * @return the long value associated with the key. */ - long getLong(String key, long defaultValue); + public long getLong(String key, long defaultValue) { + return mParser.getLong(key, defaultValue); + } } diff --git a/src/com/android/settings/network/NetworkScoreManagerWrapper.java b/src/com/android/settings/wrapper/NetworkScoreManagerWrapper.java similarity index 98% rename from src/com/android/settings/network/NetworkScoreManagerWrapper.java rename to src/com/android/settings/wrapper/NetworkScoreManagerWrapper.java index 3489640f6a2..a07d6457a09 100644 --- a/src/com/android/settings/network/NetworkScoreManagerWrapper.java +++ b/src/com/android/settings/wrapper/NetworkScoreManagerWrapper.java @@ -13,7 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.android.settings.network; +package com.android.settings.wrapper; import android.annotation.Nullable; import android.net.NetworkScoreManager; diff --git a/src/com/android/settings/display/PowerManagerWrapper.java b/src/com/android/settings/wrapper/PowerManagerWrapper.java similarity index 97% rename from src/com/android/settings/display/PowerManagerWrapper.java rename to src/com/android/settings/wrapper/PowerManagerWrapper.java index afa2f333590..6357a3ecd36 100644 --- a/src/com/android/settings/display/PowerManagerWrapper.java +++ b/src/com/android/settings/wrapper/PowerManagerWrapper.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package com.android.settings.display; +package com.android.settings.wrapper; import android.os.PowerManager; diff --git a/src/com/android/settings/network/RestrictedLockUtilsWrapper.java b/src/com/android/settings/wrapper/RestrictedLockUtilsWrapper.java similarity index 93% rename from src/com/android/settings/network/RestrictedLockUtilsWrapper.java rename to src/com/android/settings/wrapper/RestrictedLockUtilsWrapper.java index de5b80851d3..7a0185ff7b9 100644 --- a/src/com/android/settings/network/RestrictedLockUtilsWrapper.java +++ b/src/com/android/settings/wrapper/RestrictedLockUtilsWrapper.java @@ -1,4 +1,4 @@ -package com.android.settings.network; +package com.android.settings.wrapper; import android.content.Context; import com.android.settingslib.RestrictedLockUtils; diff --git a/src/com/android/settings/applications/UserManagerWrapperImpl.java b/src/com/android/settings/wrapper/UserManagerWrapper.java similarity index 66% rename from src/com/android/settings/applications/UserManagerWrapperImpl.java rename to src/com/android/settings/wrapper/UserManagerWrapper.java index 14ea64ae345..eeb648bd102 100644 --- a/src/com/android/settings/applications/UserManagerWrapperImpl.java +++ b/src/com/android/settings/wrapper/UserManagerWrapper.java @@ -14,26 +14,30 @@ * limitations under the License. */ -package com.android.settings.applications; +package com.android.settings.wrapper; import android.content.pm.UserInfo; import android.os.UserManager; import java.util.List; -public class UserManagerWrapperImpl implements UserManagerWrapper { +/** + * This class replicates a subset of the android.os.UserManager. The class + * exists so that we can use a thin wrapper around the UserManager in production code and a mock in + * tests. We cannot directly mock or shadow the UserManager, because some of the methods we rely on + * are newer than the API version supported by Robolectric or are hidden. + */ +public class UserManagerWrapper { private UserManager mUserManager; - public UserManagerWrapperImpl(UserManager userManager) { + public UserManagerWrapper(UserManager userManager) { mUserManager = userManager; } - @Override public UserInfo getPrimaryUser() { return mUserManager.getPrimaryUser(); } - @Override public List getUsers() { return mUserManager.getUsers(); } diff --git a/src/com/android/settings/webview/UserPackageWrapper.java b/src/com/android/settings/wrapper/UserPackageWrapper.java similarity index 86% rename from src/com/android/settings/webview/UserPackageWrapper.java rename to src/com/android/settings/wrapper/UserPackageWrapper.java index 8fbb10cb8a1..afa1d82d314 100644 --- a/src/com/android/settings/webview/UserPackageWrapper.java +++ b/src/com/android/settings/wrapper/UserPackageWrapper.java @@ -12,20 +12,16 @@ * permissions and limitations under the License. */ -package com.android.settings.webview; +package com.android.settings.wrapper; -import android.content.Context; import android.content.pm.PackageInfo; import android.content.pm.UserInfo; -import android.webkit.UserPackage; - -import java.util.List; /** * Wrapper class around android.webkit.UserPackage - to be able to use UserPackage in Robolectric * tests (such tests currently don't support mocking hidden classes). */ -interface UserPackageWrapper { +public interface UserPackageWrapper { UserInfo getUserInfo(); PackageInfo getPackageInfo(); boolean isEnabledPackage(); diff --git a/src/com/android/settings/webview/UserPackageWrapperImpl.java b/src/com/android/settings/wrapper/UserPackageWrapperImpl.java similarity index 84% rename from src/com/android/settings/webview/UserPackageWrapperImpl.java rename to src/com/android/settings/wrapper/UserPackageWrapperImpl.java index 1ea7c2e7927..0a2b9cde1cb 100644 --- a/src/com/android/settings/webview/UserPackageWrapperImpl.java +++ b/src/com/android/settings/wrapper/UserPackageWrapperImpl.java @@ -12,23 +12,19 @@ * permissions and limitations under the License. */ -package com.android.settings.webview; +package com.android.settings.wrapper; -import android.content.Context; import android.content.pm.PackageInfo; import android.content.pm.UserInfo; import android.webkit.UserPackage; -import java.util.ArrayList; -import java.util.List; - /** * Default implementation of UserPackageWrapper. */ -class UserPackageWrapperImpl implements UserPackageWrapper { +public class UserPackageWrapperImpl implements UserPackageWrapper { private final UserPackage mUserPackage; - UserPackageWrapperImpl(UserPackage userPackage) { + public UserPackageWrapperImpl(UserPackage userPackage) { mUserPackage = userPackage; } diff --git a/src/com/android/settings/dashboard/suggestions/WallpaperManagerWrapper.java b/src/com/android/settings/wrapper/WallpaperManagerWrapper.java similarity index 95% rename from src/com/android/settings/dashboard/suggestions/WallpaperManagerWrapper.java rename to src/com/android/settings/wrapper/WallpaperManagerWrapper.java index 9efe4fe0a0f..89015e5513e 100644 --- a/src/com/android/settings/dashboard/suggestions/WallpaperManagerWrapper.java +++ b/src/com/android/settings/wrapper/WallpaperManagerWrapper.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package com.android.settings.dashboard.suggestions; +package com.android.settings.wrapper; import android.app.WallpaperManager; import android.content.Context; diff --git a/src/com/android/settings/wifi/WifiManagerWrapper.java b/src/com/android/settings/wrapper/WifiManagerWrapper.java similarity index 93% rename from src/com/android/settings/wifi/WifiManagerWrapper.java rename to src/com/android/settings/wrapper/WifiManagerWrapper.java index 69b5ee903db..e24f5eb3191 100644 --- a/src/com/android/settings/wifi/WifiManagerWrapper.java +++ b/src/com/android/settings/wrapper/WifiManagerWrapper.java @@ -1,4 +1,4 @@ -package com.android.settings.wifi; +package com.android.settings.wrapper; import android.net.wifi.WifiManager; diff --git a/tests/robotests/src/com/android/settings/UtilsTest.java b/tests/robotests/src/com/android/settings/UtilsTest.java index 19b87a1b1fa..26b5b0236c5 100644 --- a/tests/robotests/src/com/android/settings/UtilsTest.java +++ b/tests/robotests/src/com/android/settings/UtilsTest.java @@ -26,8 +26,8 @@ import android.text.SpannableStringBuilder; import android.text.format.DateUtils; import android.text.style.TtsSpan; -import com.android.settings.enterprise.DevicePolicyManagerWrapper; import com.android.settings.testutils.SettingsRobolectricTestRunner; +import com.android.settings.wrapper.DevicePolicyManagerWrapper; import org.junit.Before; import org.junit.Test; diff --git a/tests/robotests/src/com/android/settings/accessibility/ShortcutServicePickerFragmentTest.java b/tests/robotests/src/com/android/settings/accessibility/ShortcutServicePickerFragmentTest.java index f2d1e6534ac..785bdbdffaf 100644 --- a/tests/robotests/src/com/android/settings/accessibility/ShortcutServicePickerFragmentTest.java +++ b/tests/robotests/src/com/android/settings/accessibility/ShortcutServicePickerFragmentTest.java @@ -23,8 +23,8 @@ import android.os.UserManager; import android.test.mock.MockContentResolver; import com.android.settings.testutils.SettingsRobolectricTestRunner; import com.android.settings.TestConfig; -import com.android.settings.applications.PackageManagerWrapper; import com.android.settings.testutils.FakeFeatureFactory; +import com.android.settingslib.wrapper.PackageManagerWrapper; import org.junit.Before; import org.junit.Test; @@ -40,7 +40,6 @@ import static org.mockito.Mockito.doReturn; import static org.mockito.Mockito.spy; import static org.mockito.Mockito.when; - @RunWith(SettingsRobolectricTestRunner.class) @Config(manifest = TestConfig.MANIFEST_PATH, sdk = TestConfig.SDK_VERSION) public class ShortcutServicePickerFragmentTest { diff --git a/tests/robotests/src/com/android/settings/accounts/RemoveAccountPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/accounts/RemoveAccountPreferenceControllerTest.java index a1eb2d85488..d4e866f8044 100644 --- a/tests/robotests/src/com/android/settings/accounts/RemoveAccountPreferenceControllerTest.java +++ b/tests/robotests/src/com/android/settings/accounts/RemoveAccountPreferenceControllerTest.java @@ -46,10 +46,10 @@ import android.widget.Button; import com.android.settings.R; import com.android.settings.TestConfig; import com.android.settings.applications.LayoutPreference; -import com.android.settings.enterprise.DevicePolicyManagerWrapper; import com.android.settings.testutils.SettingsRobolectricTestRunner; import com.android.settings.testutils.shadow.ShadowAccountManager; import com.android.settings.testutils.shadow.ShadowContentResolver; +import com.android.settings.wrapper.DevicePolicyManagerWrapper; import org.junit.Before; import org.junit.Test; diff --git a/tests/robotests/src/com/android/settings/applications/AppStateAppOpsBridgeTest.java b/tests/robotests/src/com/android/settings/applications/AppStateAppOpsBridgeTest.java index df226a83be4..d63697ec5a4 100644 --- a/tests/robotests/src/com/android/settings/applications/AppStateAppOpsBridgeTest.java +++ b/tests/robotests/src/com/android/settings/applications/AppStateAppOpsBridgeTest.java @@ -27,6 +27,7 @@ import android.os.RemoteException; import android.os.UserManager; import com.android.settings.testutils.SettingsRobolectricTestRunner; import com.android.settings.TestConfig; +import com.android.settings.wrapper.IPackageManagerWrapper; import com.android.settingslib.applications.ApplicationsState.AppEntry; import org.junit.Before; import org.junit.Test; diff --git a/tests/robotests/src/com/android/settings/applications/AppWithAdminGrantedPermissionsCounterTest.java b/tests/robotests/src/com/android/settings/applications/AppWithAdminGrantedPermissionsCounterTest.java index 11401a886d6..33d261f807b 100644 --- a/tests/robotests/src/com/android/settings/applications/AppWithAdminGrantedPermissionsCounterTest.java +++ b/tests/robotests/src/com/android/settings/applications/AppWithAdminGrantedPermissionsCounterTest.java @@ -28,7 +28,9 @@ import android.os.UserManager; import com.android.settings.testutils.SettingsRobolectricTestRunner; import com.android.settings.TestConfig; -import com.android.settings.enterprise.DevicePolicyManagerWrapper; +import com.android.settings.wrapper.DevicePolicyManagerWrapper; +import com.android.settings.wrapper.IPackageManagerWrapper; +import com.android.settingslib.wrapper.PackageManagerWrapper; import org.junit.Before; import org.junit.Test; diff --git a/tests/robotests/src/com/android/settings/applications/AppWithAdminGrantedPermissionsListerTest.java b/tests/robotests/src/com/android/settings/applications/AppWithAdminGrantedPermissionsListerTest.java index c3c1bb3877c..2e9328ab6e6 100644 --- a/tests/robotests/src/com/android/settings/applications/AppWithAdminGrantedPermissionsListerTest.java +++ b/tests/robotests/src/com/android/settings/applications/AppWithAdminGrantedPermissionsListerTest.java @@ -25,7 +25,9 @@ import android.os.UserManager; import com.android.settings.testutils.SettingsRobolectricTestRunner; import com.android.settings.TestConfig; -import com.android.settings.enterprise.DevicePolicyManagerWrapper; +import com.android.settings.wrapper.DevicePolicyManagerWrapper; +import com.android.settings.wrapper.IPackageManagerWrapper; +import com.android.settingslib.wrapper.PackageManagerWrapper; import org.junit.Before; import org.junit.Test; diff --git a/tests/robotests/src/com/android/settings/applications/ApplicationFeatureProviderImplTest.java b/tests/robotests/src/com/android/settings/applications/ApplicationFeatureProviderImplTest.java index 2b1c2967107..e5b7a66e79d 100644 --- a/tests/robotests/src/com/android/settings/applications/ApplicationFeatureProviderImplTest.java +++ b/tests/robotests/src/com/android/settings/applications/ApplicationFeatureProviderImplTest.java @@ -30,9 +30,11 @@ import android.os.UserManager; import com.android.settings.testutils.SettingsRobolectricTestRunner; import com.android.settings.TestConfig; -import com.android.settings.enterprise.DevicePolicyManagerWrapper; import com.android.settings.testutils.ApplicationTestUtils; import com.android.settings.testutils.shadow.ShadowUserManager; +import com.android.settings.wrapper.DevicePolicyManagerWrapper; +import com.android.settings.wrapper.IPackageManagerWrapper; +import com.android.settingslib.wrapper.PackageManagerWrapper; import org.junit.Before; import org.junit.Test; diff --git a/tests/robotests/src/com/android/settings/applications/InstalledAppCounterTest.java b/tests/robotests/src/com/android/settings/applications/InstalledAppCounterTest.java index 56df10e73e3..58c4386661f 100644 --- a/tests/robotests/src/com/android/settings/applications/InstalledAppCounterTest.java +++ b/tests/robotests/src/com/android/settings/applications/InstalledAppCounterTest.java @@ -41,6 +41,7 @@ import android.os.UserManager; import com.android.settings.testutils.SettingsRobolectricTestRunner; import com.android.settings.TestConfig; import com.android.settings.testutils.shadow.ShadowUserManager; +import com.android.settingslib.wrapper.PackageManagerWrapper; import org.junit.Before; import org.junit.Test; diff --git a/tests/robotests/src/com/android/settings/applications/InstalledAppDetailsTest.java b/tests/robotests/src/com/android/settings/applications/InstalledAppDetailsTest.java index 8fb1e99ae8a..35f961bf362 100644 --- a/tests/robotests/src/com/android/settings/applications/InstalledAppDetailsTest.java +++ b/tests/robotests/src/com/android/settings/applications/InstalledAppDetailsTest.java @@ -16,7 +16,6 @@ package com.android.settings.applications; - import static com.google.common.truth.Truth.assertThat; import static org.mockito.ArgumentMatchers.nullable; import static org.mockito.Matchers.anyDouble; @@ -33,7 +32,6 @@ import android.app.AlertDialog; import android.app.AppOpsManager; import android.app.Fragment; import android.app.LoaderManager; -import android.app.admin.DevicePolicyManager; import android.content.Context; import android.content.Intent; import android.content.pm.ApplicationInfo; @@ -55,11 +53,11 @@ import com.android.settings.SettingsActivity; import com.android.settings.TestConfig; import com.android.settings.applications.instantapps.InstantAppButtonsController; import com.android.settings.applications.instantapps.InstantAppButtonsController.ShowDialogDelegate; -import com.android.settings.enterprise.DevicePolicyManagerWrapper; import com.android.settings.fuelgauge.BatteryUtils; import com.android.settings.testutils.FakeFeatureFactory; import com.android.settings.testutils.SettingsRobolectricTestRunner; import com.android.settings.widget.ActionButtonPreferenceTest; +import com.android.settings.wrapper.DevicePolicyManagerWrapper; import com.android.settingslib.Utils; import com.android.settingslib.applications.AppUtils; import com.android.settingslib.applications.ApplicationsState.AppEntry; diff --git a/tests/robotests/src/com/android/settings/applications/InstalledAppListerTest.java b/tests/robotests/src/com/android/settings/applications/InstalledAppListerTest.java index c4c3259bf2c..c74deaeb5cf 100644 --- a/tests/robotests/src/com/android/settings/applications/InstalledAppListerTest.java +++ b/tests/robotests/src/com/android/settings/applications/InstalledAppListerTest.java @@ -26,6 +26,7 @@ import android.os.UserManager; import com.android.settings.testutils.SettingsRobolectricTestRunner; import com.android.settings.TestConfig; +import com.android.settingslib.wrapper.PackageManagerWrapper; import org.junit.Before; import org.junit.Test; diff --git a/tests/robotests/src/com/android/settings/applications/NotificationAppsTest.java b/tests/robotests/src/com/android/settings/applications/NotificationAppsTest.java index 16355768651..11d757fc504 100644 --- a/tests/robotests/src/com/android/settings/applications/NotificationAppsTest.java +++ b/tests/robotests/src/com/android/settings/applications/NotificationAppsTest.java @@ -27,6 +27,7 @@ import com.android.settings.testutils.SettingsRobolectricTestRunner; import com.android.settings.TestConfig; import com.android.settings.dashboard.SummaryLoader; import com.android.settings.notification.NotificationBackend; +import com.android.settingslib.wrapper.PackageManagerWrapper; import java.util.List; import java.util.ArrayList; diff --git a/tests/robotests/src/com/android/settings/applications/PictureInPictureDetailsTest.java b/tests/robotests/src/com/android/settings/applications/PictureInPictureDetailsTest.java index 6bac9a3ee67..02b8c7a003c 100644 --- a/tests/robotests/src/com/android/settings/applications/PictureInPictureDetailsTest.java +++ b/tests/robotests/src/com/android/settings/applications/PictureInPictureDetailsTest.java @@ -28,6 +28,7 @@ import com.android.internal.logging.nano.MetricsProto; import com.android.settings.testutils.SettingsRobolectricTestRunner; import com.android.settings.TestConfig; import com.android.settings.testutils.FakeFeatureFactory; +import com.android.settings.wrapper.ActivityInfoWrapper; import org.junit.Before; import org.junit.Test; @@ -104,11 +105,12 @@ public class PictureInPictureDetailsTest { activities); } - private class MockActivityInfo implements ActivityInfoWrapper { + private class MockActivityInfo extends ActivityInfoWrapper { private boolean mSupportsPictureInPicture; public MockActivityInfo(boolean supportsPictureInPicture) { + super(null); mSupportsPictureInPicture = supportsPictureInPicture; } diff --git a/tests/robotests/src/com/android/settings/applications/defaultapps/DefaultAppInfoTest.java b/tests/robotests/src/com/android/settings/applications/defaultapps/DefaultAppInfoTest.java index 281e70a367f..0ae96159e94 100644 --- a/tests/robotests/src/com/android/settings/applications/defaultapps/DefaultAppInfoTest.java +++ b/tests/robotests/src/com/android/settings/applications/defaultapps/DefaultAppInfoTest.java @@ -16,7 +16,6 @@ package com.android.settings.applications.defaultapps; - import static com.google.common.truth.Truth.assertThat; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; @@ -27,7 +26,7 @@ import android.content.pm.PackageManager; import com.android.settings.testutils.SettingsRobolectricTestRunner; import com.android.settings.TestConfig; -import com.android.settings.applications.PackageManagerWrapper; +import com.android.settingslib.wrapper.PackageManagerWrapper; import org.junit.Before; import org.junit.Test; diff --git a/tests/robotests/src/com/android/settings/applications/defaultapps/DefaultAutofillPickerTest.java b/tests/robotests/src/com/android/settings/applications/defaultapps/DefaultAutofillPickerTest.java index 655f693f46f..9a3ec100c73 100644 --- a/tests/robotests/src/com/android/settings/applications/defaultapps/DefaultAutofillPickerTest.java +++ b/tests/robotests/src/com/android/settings/applications/defaultapps/DefaultAutofillPickerTest.java @@ -29,8 +29,8 @@ import android.os.UserManager; import com.android.settings.testutils.SettingsRobolectricTestRunner; import com.android.settings.TestConfig; -import com.android.settings.applications.PackageManagerWrapper; import com.android.settings.testutils.FakeFeatureFactory; +import com.android.settingslib.wrapper.PackageManagerWrapper; import org.junit.Before; import org.junit.Test; diff --git a/tests/robotests/src/com/android/settings/applications/defaultapps/DefaultAutofillPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/applications/defaultapps/DefaultAutofillPreferenceControllerTest.java index d6f1122451f..bc72ee4ee3f 100644 --- a/tests/robotests/src/com/android/settings/applications/defaultapps/DefaultAutofillPreferenceControllerTest.java +++ b/tests/robotests/src/com/android/settings/applications/defaultapps/DefaultAutofillPreferenceControllerTest.java @@ -16,7 +16,6 @@ package com.android.settings.applications.defaultapps; - import android.content.Context; import android.content.pm.PackageManager; import android.os.UserManager; @@ -27,8 +26,8 @@ import android.view.autofill.AutofillManager; import com.android.settings.R; import com.android.settings.testutils.SettingsRobolectricTestRunner; import com.android.settings.TestConfig; -import com.android.settings.applications.AutofillManagerWrapper; -import com.android.settings.applications.PackageManagerWrapper; +import com.android.settings.wrapper.AutofillManagerWrapper; +import com.android.settingslib.wrapper.PackageManagerWrapper; import org.junit.Before; import org.junit.Test; diff --git a/tests/robotests/src/com/android/settings/applications/defaultapps/DefaultBrowserPickerTest.java b/tests/robotests/src/com/android/settings/applications/defaultapps/DefaultBrowserPickerTest.java index f5dc72d5ab9..e8a6c1e964c 100644 --- a/tests/robotests/src/com/android/settings/applications/defaultapps/DefaultBrowserPickerTest.java +++ b/tests/robotests/src/com/android/settings/applications/defaultapps/DefaultBrowserPickerTest.java @@ -16,14 +16,13 @@ package com.android.settings.applications.defaultapps; - import android.app.Activity; import android.content.Context; import android.os.UserManager; import com.android.settings.testutils.SettingsRobolectricTestRunner; import com.android.settings.TestConfig; -import com.android.settings.applications.PackageManagerWrapper; +import com.android.settingslib.wrapper.PackageManagerWrapper; import org.junit.Before; import org.junit.Test; diff --git a/tests/robotests/src/com/android/settings/applications/defaultapps/DefaultBrowserPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/applications/defaultapps/DefaultBrowserPreferenceControllerTest.java index e918ee221b5..8d527ff2702 100644 --- a/tests/robotests/src/com/android/settings/applications/defaultapps/DefaultBrowserPreferenceControllerTest.java +++ b/tests/robotests/src/com/android/settings/applications/defaultapps/DefaultBrowserPreferenceControllerTest.java @@ -16,7 +16,6 @@ package com.android.settings.applications.defaultapps; - import android.content.Context; import android.content.Intent; import android.content.pm.ResolveInfo; @@ -26,7 +25,7 @@ import android.support.v7.preference.Preference; import com.android.settings.R; import com.android.settings.testutils.SettingsRobolectricTestRunner; import com.android.settings.TestConfig; -import com.android.settings.applications.PackageManagerWrapper; +import com.android.settingslib.wrapper.PackageManagerWrapper; import org.junit.Before; import org.junit.Test; diff --git a/tests/robotests/src/com/android/settings/applications/defaultapps/DefaultEmergencyPickerTest.java b/tests/robotests/src/com/android/settings/applications/defaultapps/DefaultEmergencyPickerTest.java index 04972ae358a..124817afe17 100644 --- a/tests/robotests/src/com/android/settings/applications/defaultapps/DefaultEmergencyPickerTest.java +++ b/tests/robotests/src/com/android/settings/applications/defaultapps/DefaultEmergencyPickerTest.java @@ -23,7 +23,7 @@ import android.provider.Settings; import com.android.settings.testutils.SettingsRobolectricTestRunner; import com.android.settings.TestConfig; -import com.android.settings.applications.PackageManagerWrapper; +import com.android.settingslib.wrapper.PackageManagerWrapper; import org.junit.Before; import org.junit.Test; diff --git a/tests/robotests/src/com/android/settings/applications/defaultapps/DefaultHomePickerTest.java b/tests/robotests/src/com/android/settings/applications/defaultapps/DefaultHomePickerTest.java index b50063729e3..4b82f1a98b5 100644 --- a/tests/robotests/src/com/android/settings/applications/defaultapps/DefaultHomePickerTest.java +++ b/tests/robotests/src/com/android/settings/applications/defaultapps/DefaultHomePickerTest.java @@ -31,7 +31,7 @@ import android.os.UserManager; import com.android.settings.testutils.SettingsRobolectricTestRunner; import com.android.settings.TestConfig; -import com.android.settings.applications.PackageManagerWrapper; +import com.android.settingslib.wrapper.PackageManagerWrapper; import org.junit.Before; import org.junit.Test; diff --git a/tests/robotests/src/com/android/settings/applications/defaultapps/DefaultHomePreferenceControllerTest.java b/tests/robotests/src/com/android/settings/applications/defaultapps/DefaultHomePreferenceControllerTest.java index 22b30bda3bb..ca5c10b1996 100644 --- a/tests/robotests/src/com/android/settings/applications/defaultapps/DefaultHomePreferenceControllerTest.java +++ b/tests/robotests/src/com/android/settings/applications/defaultapps/DefaultHomePreferenceControllerTest.java @@ -16,7 +16,6 @@ package com.android.settings.applications.defaultapps; - import static com.google.common.truth.Truth.assertThat; import static org.mockito.Matchers.anyList; import static org.mockito.Mockito.atLeastOnce; @@ -31,8 +30,8 @@ import android.os.UserManager; import android.support.v7.preference.Preference; import com.android.settings.TestConfig; -import com.android.settings.applications.PackageManagerWrapper; import com.android.settings.testutils.SettingsRobolectricTestRunner; +import com.android.settingslib.wrapper.PackageManagerWrapper; import org.junit.Before; import org.junit.Test; diff --git a/tests/robotests/src/com/android/settings/applications/defaultapps/DefaultPhonePickerTest.java b/tests/robotests/src/com/android/settings/applications/defaultapps/DefaultPhonePickerTest.java index 600acb4a778..f2b7db86c66 100644 --- a/tests/robotests/src/com/android/settings/applications/defaultapps/DefaultPhonePickerTest.java +++ b/tests/robotests/src/com/android/settings/applications/defaultapps/DefaultPhonePickerTest.java @@ -16,14 +16,13 @@ package com.android.settings.applications.defaultapps; - import android.app.Activity; import android.content.Context; import android.os.UserManager; import com.android.settings.testutils.SettingsRobolectricTestRunner; import com.android.settings.TestConfig; -import com.android.settings.applications.PackageManagerWrapper; +import com.android.settingslib.wrapper.PackageManagerWrapper; import org.junit.Before; import org.junit.Test; diff --git a/tests/robotests/src/com/android/settings/applications/defaultapps/DefaultSmsPickerTest.java b/tests/robotests/src/com/android/settings/applications/defaultapps/DefaultSmsPickerTest.java index da0c325ed23..91e68eafeca 100644 --- a/tests/robotests/src/com/android/settings/applications/defaultapps/DefaultSmsPickerTest.java +++ b/tests/robotests/src/com/android/settings/applications/defaultapps/DefaultSmsPickerTest.java @@ -16,14 +16,13 @@ package com.android.settings.applications.defaultapps; - import android.app.Activity; import android.content.Context; import android.os.UserManager; import com.android.settings.testutils.SettingsRobolectricTestRunner; import com.android.settings.TestConfig; -import com.android.settings.applications.PackageManagerWrapper; +import com.android.settingslib.wrapper.PackageManagerWrapper; import org.junit.Before; import org.junit.Test; diff --git a/tests/robotests/src/com/android/settings/applications/instantapps/InstantAppButtonsControllerTest.java b/tests/robotests/src/com/android/settings/applications/instantapps/InstantAppButtonsControllerTest.java index 9e190b56e49..f56fbbf00e6 100644 --- a/tests/robotests/src/com/android/settings/applications/instantapps/InstantAppButtonsControllerTest.java +++ b/tests/robotests/src/com/android/settings/applications/instantapps/InstantAppButtonsControllerTest.java @@ -46,9 +46,9 @@ import android.widget.Button; import com.android.settings.R; import com.android.settings.testutils.SettingsRobolectricTestRunner; import com.android.settings.TestConfig; -import com.android.settings.applications.PackageManagerWrapper; import com.android.settings.core.instrumentation.MetricsFeatureProvider; import com.android.settings.testutils.FakeFeatureFactory; +import com.android.settingslib.wrapper.PackageManagerWrapper; import org.junit.Before; import org.junit.Test; diff --git a/tests/robotests/src/com/android/settings/dashboard/suggestions/SuggestionsChecksTest.java b/tests/robotests/src/com/android/settings/dashboard/suggestions/SuggestionsChecksTest.java index 59752c6575d..0165fffd8ea 100644 --- a/tests/robotests/src/com/android/settings/dashboard/suggestions/SuggestionsChecksTest.java +++ b/tests/robotests/src/com/android/settings/dashboard/suggestions/SuggestionsChecksTest.java @@ -33,6 +33,7 @@ import android.hardware.fingerprint.FingerprintManager; import com.android.settings.Settings; import com.android.settings.TestConfig; import com.android.settings.testutils.SettingsRobolectricTestRunner; +import com.android.settings.wrapper.WallpaperManagerWrapper; import com.android.settingslib.drawer.Tile; import org.junit.Before; diff --git a/tests/robotests/src/com/android/settings/datausage/AppDataUsageTest.java b/tests/robotests/src/com/android/settings/datausage/AppDataUsageTest.java index 2f2a6852dae..26071ed07db 100644 --- a/tests/robotests/src/com/android/settings/datausage/AppDataUsageTest.java +++ b/tests/robotests/src/com/android/settings/datausage/AppDataUsageTest.java @@ -16,7 +16,6 @@ package com.android.settings.datausage; - import static org.mockito.Matchers.any; import static org.mockito.Matchers.anyBoolean; import static org.mockito.Matchers.anyInt; @@ -39,12 +38,12 @@ import android.util.ArraySet; import android.view.View; import com.android.settings.TestConfig; -import com.android.settings.applications.PackageManagerWrapper; import com.android.settings.testutils.FakeFeatureFactory; import com.android.settings.testutils.SettingsRobolectricTestRunner; import com.android.settings.testutils.shadow.ShadowEntityHeaderController; import com.android.settings.widget.EntityHeaderController; import com.android.settingslib.AppItem; +import com.android.settingslib.wrapper.PackageManagerWrapper; import org.junit.After; import org.junit.Before; diff --git a/tests/robotests/src/com/android/settings/deviceinfo/PrivateVolumeOptionMenuControllerTest.java b/tests/robotests/src/com/android/settings/deviceinfo/PrivateVolumeOptionMenuControllerTest.java index ca6a33a268b..6363317ed17 100644 --- a/tests/robotests/src/com/android/settings/deviceinfo/PrivateVolumeOptionMenuControllerTest.java +++ b/tests/robotests/src/com/android/settings/deviceinfo/PrivateVolumeOptionMenuControllerTest.java @@ -30,7 +30,7 @@ import android.view.MenuItem; import com.android.settings.R; import com.android.settings.testutils.SettingsRobolectricTestRunner; import com.android.settings.TestConfig; -import com.android.settings.applications.PackageManagerWrapper; +import com.android.settingslib.wrapper.PackageManagerWrapper; import org.junit.Before; import org.junit.Test; diff --git a/tests/robotests/src/com/android/settings/deviceinfo/storage/SecondaryUserControllerTest.java b/tests/robotests/src/com/android/settings/deviceinfo/storage/SecondaryUserControllerTest.java index a871c1963f3..f0683979b2d 100644 --- a/tests/robotests/src/com/android/settings/deviceinfo/storage/SecondaryUserControllerTest.java +++ b/tests/robotests/src/com/android/settings/deviceinfo/storage/SecondaryUserControllerTest.java @@ -36,7 +36,7 @@ import android.util.SparseArray; import com.android.settings.testutils.SettingsRobolectricTestRunner; import com.android.settings.TestConfig; -import com.android.settings.applications.UserManagerWrapper; +import com.android.settings.wrapper.UserManagerWrapper; import com.android.settingslib.R; import com.android.settingslib.applications.StorageStatsSource; import com.android.settingslib.core.AbstractPreferenceController; diff --git a/tests/robotests/src/com/android/settings/deviceinfo/storage/UserProfileControllerTest.java b/tests/robotests/src/com/android/settings/deviceinfo/storage/UserProfileControllerTest.java index a2e57b95e96..8da52608838 100644 --- a/tests/robotests/src/com/android/settings/deviceinfo/storage/UserProfileControllerTest.java +++ b/tests/robotests/src/com/android/settings/deviceinfo/storage/UserProfileControllerTest.java @@ -37,8 +37,8 @@ import com.android.settings.SettingsActivity; import com.android.settings.testutils.SettingsRobolectricTestRunner; import com.android.settings.SubSettings; import com.android.settings.TestConfig; -import com.android.settings.applications.UserManagerWrapper; import com.android.settings.deviceinfo.StorageProfileFragment; +import com.android.settings.wrapper.UserManagerWrapper; import com.android.settingslib.R; import com.android.settingslib.applications.StorageStatsSource; import com.android.settingslib.drawable.UserIconDrawable; diff --git a/tests/robotests/src/com/android/settings/display/BrightnessLevelPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/display/BrightnessLevelPreferenceControllerTest.java index d35adef7640..66bdba1decb 100644 --- a/tests/robotests/src/com/android/settings/display/BrightnessLevelPreferenceControllerTest.java +++ b/tests/robotests/src/com/android/settings/display/BrightnessLevelPreferenceControllerTest.java @@ -32,6 +32,7 @@ import android.support.v7.preference.PreferenceScreen; import com.android.settings.testutils.SettingsRobolectricTestRunner; import com.android.settings.TestConfig; +import com.android.settings.wrapper.PowerManagerWrapper; import org.junit.Before; import org.junit.Test; diff --git a/tests/robotests/src/com/android/settings/enterprise/EnterprisePrivacyFeatureProviderImplTest.java b/tests/robotests/src/com/android/settings/enterprise/EnterprisePrivacyFeatureProviderImplTest.java index 899ff5c66db..1ea2567b58f 100644 --- a/tests/robotests/src/com/android/settings/enterprise/EnterprisePrivacyFeatureProviderImplTest.java +++ b/tests/robotests/src/com/android/settings/enterprise/EnterprisePrivacyFeatureProviderImplTest.java @@ -31,8 +31,9 @@ import android.text.SpannableStringBuilder; import com.android.settings.R; import com.android.settings.testutils.SettingsRobolectricTestRunner; import com.android.settings.TestConfig; -import com.android.settings.applications.PackageManagerWrapper; -import com.android.settings.vpn2.ConnectivityManagerWrapper; +import com.android.settings.wrapper.ConnectivityManagerWrapper; +import com.android.settings.wrapper.DevicePolicyManagerWrapper; +import com.android.settingslib.wrapper.PackageManagerWrapper; import org.junit.Before; import org.junit.Test; diff --git a/tests/robotests/src/com/android/settings/fingerprint/FingerprintEnrollFindSensorTest.java b/tests/robotests/src/com/android/settings/fingerprint/FingerprintEnrollFindSensorTest.java index ad52bf6026e..6e58b13278e 100644 --- a/tests/robotests/src/com/android/settings/fingerprint/FingerprintEnrollFindSensorTest.java +++ b/tests/robotests/src/com/android/settings/fingerprint/FingerprintEnrollFindSensorTest.java @@ -33,11 +33,11 @@ import android.widget.Button; import com.android.settings.R; import com.android.settings.TestConfig; import com.android.settings.password.ChooseLockSettingsHelper; -import com.android.settings.password.IFingerprintManager; import com.android.settings.testutils.SettingsRobolectricTestRunner; import com.android.settings.testutils.shadow.SettingsShadowResources; import com.android.settings.testutils.shadow.ShadowEventLogWriter; import com.android.settings.testutils.shadow.ShadowUtils; +import com.android.settings.wrapper.FingerprintManagerWrapper; import org.junit.After; import org.junit.Before; @@ -66,7 +66,7 @@ import org.robolectric.shadows.ShadowActivity.IntentForResult; public class FingerprintEnrollFindSensorTest { @Mock - private IFingerprintManager mFingerprintManager; + private FingerprintManagerWrapper mFingerprintManager; private FingerprintEnrollFindSensor mActivity; diff --git a/tests/robotests/src/com/android/settings/fingerprint/SetupFingerprintEnrollFindSensorTest.java b/tests/robotests/src/com/android/settings/fingerprint/SetupFingerprintEnrollFindSensorTest.java index ce31328edb8..b2ef65b58d2 100644 --- a/tests/robotests/src/com/android/settings/fingerprint/SetupFingerprintEnrollFindSensorTest.java +++ b/tests/robotests/src/com/android/settings/fingerprint/SetupFingerprintEnrollFindSensorTest.java @@ -27,11 +27,11 @@ import android.widget.Button; import com.android.settings.R; import com.android.settings.TestConfig; import com.android.settings.password.ChooseLockSettingsHelper; -import com.android.settings.password.IFingerprintManager; import com.android.settings.testutils.SettingsRobolectricTestRunner; import com.android.settings.testutils.shadow.SettingsShadowResources; import com.android.settings.testutils.shadow.ShadowEventLogWriter; import com.android.settings.testutils.shadow.ShadowUtils; +import com.android.settings.wrapper.FingerprintManagerWrapper; import org.junit.After; import org.junit.Before; @@ -58,7 +58,7 @@ import org.robolectric.shadows.ShadowAlertDialog; public class SetupFingerprintEnrollFindSensorTest { @Mock - private IFingerprintManager mFingerprintManager; + private FingerprintManagerWrapper mFingerprintManager; private SetupFingerprintEnrollFindSensor mActivity; diff --git a/tests/robotests/src/com/android/settings/fuelgauge/AppButtonsPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/fuelgauge/AppButtonsPreferenceControllerTest.java index 6214cf2e139..ad5f5b0820d 100644 --- a/tests/robotests/src/com/android/settings/fuelgauge/AppButtonsPreferenceControllerTest.java +++ b/tests/robotests/src/com/android/settings/fuelgauge/AppButtonsPreferenceControllerTest.java @@ -43,10 +43,10 @@ import android.os.UserManager; import com.android.settings.R; import com.android.settings.SettingsActivity; import com.android.settings.TestConfig; -import com.android.settings.enterprise.DevicePolicyManagerWrapper; import com.android.settings.testutils.FakeFeatureFactory; import com.android.settings.widget.ActionButtonPreference; import com.android.settings.widget.ActionButtonPreferenceTest; +import com.android.settings.wrapper.DevicePolicyManagerWrapper; import com.android.settingslib.applications.AppUtils; import com.android.settingslib.applications.ApplicationsState; import com.android.settingslib.applications.instantapps.InstantAppDataProvider; diff --git a/tests/robotests/src/com/android/settings/fuelgauge/BackgroundActivityPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/fuelgauge/BackgroundActivityPreferenceControllerTest.java index 86836f9f3f4..4353b54a8c7 100644 --- a/tests/robotests/src/com/android/settings/fuelgauge/BackgroundActivityPreferenceControllerTest.java +++ b/tests/robotests/src/com/android/settings/fuelgauge/BackgroundActivityPreferenceControllerTest.java @@ -38,7 +38,7 @@ import android.widget.Button; import com.android.settings.R; import com.android.settings.TestConfig; -import com.android.settings.enterprise.DevicePolicyManagerWrapper; +import com.android.settings.wrapper.DevicePolicyManagerWrapper; import org.junit.Before; import org.junit.Test; diff --git a/tests/robotests/src/com/android/settings/fuelgauge/anomaly/AnomalyDetectionPolicyTest.java b/tests/robotests/src/com/android/settings/fuelgauge/anomaly/AnomalyDetectionPolicyTest.java index 169cba8e9bf..e50c3dd868d 100644 --- a/tests/robotests/src/com/android/settings/fuelgauge/anomaly/AnomalyDetectionPolicyTest.java +++ b/tests/robotests/src/com/android/settings/fuelgauge/anomaly/AnomalyDetectionPolicyTest.java @@ -30,6 +30,7 @@ import android.util.KeyValueListParser; import com.android.settings.testutils.SettingsRobolectricTestRunner; import com.android.settings.TestConfig; +import com.android.settings.wrapper.KeyValueListParserWrapper; import org.junit.Before; import org.junit.Test; @@ -54,7 +55,7 @@ public class AnomalyDetectionPolicyTest { public void setUp() { mContext = RuntimeEnvironment.application; mKeyValueListParserWrapper = spy( - new KeyValueListParserWrapperImpl(new KeyValueListParser(','))); + new KeyValueListParserWrapper(new KeyValueListParser(','))); } @Test diff --git a/tests/robotests/src/com/android/settings/network/NetworkScorerPickerPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/network/NetworkScorerPickerPreferenceControllerTest.java index 0b1586e2c9b..7ed7f3f0e0e 100644 --- a/tests/robotests/src/com/android/settings/network/NetworkScorerPickerPreferenceControllerTest.java +++ b/tests/robotests/src/com/android/settings/network/NetworkScorerPickerPreferenceControllerTest.java @@ -30,6 +30,7 @@ import android.support.v7.preference.Preference; import com.android.settings.R; import com.android.settings.testutils.SettingsRobolectricTestRunner; import com.android.settings.TestConfig; +import com.android.settings.wrapper.NetworkScoreManagerWrapper; import org.junit.Before; import org.junit.Test; diff --git a/tests/robotests/src/com/android/settings/network/NetworkScorerPickerTest.java b/tests/robotests/src/com/android/settings/network/NetworkScorerPickerTest.java index 9885bdf684f..7cfced870d5 100644 --- a/tests/robotests/src/com/android/settings/network/NetworkScorerPickerTest.java +++ b/tests/robotests/src/com/android/settings/network/NetworkScorerPickerTest.java @@ -33,6 +33,8 @@ import com.android.settings.R; import com.android.settings.testutils.SettingsRobolectricTestRunner; import com.android.settings.TestConfig; import com.android.settings.widget.RadioButtonPreference; +import com.android.settings.wrapper.NetworkScoreManagerWrapper; + import com.google.android.collect.Lists; import org.junit.Before; import org.junit.Test; @@ -45,7 +47,6 @@ import org.robolectric.annotation.Config; import java.util.ArrayList; - @RunWith(SettingsRobolectricTestRunner.class) @Config(manifest = TestConfig.MANIFEST_PATH, sdk = TestConfig.SDK_VERSION) public class NetworkScorerPickerTest { diff --git a/tests/robotests/src/com/android/settings/password/SetNewPasswordControllerTest.java b/tests/robotests/src/com/android/settings/password/SetNewPasswordControllerTest.java index 96775addb8c..52678fbab29 100644 --- a/tests/robotests/src/com/android/settings/password/SetNewPasswordControllerTest.java +++ b/tests/robotests/src/com/android/settings/password/SetNewPasswordControllerTest.java @@ -43,6 +43,7 @@ import android.os.Bundle; import com.android.settings.testutils.SettingsRobolectricTestRunner; import com.android.settings.TestConfig; +import com.android.settings.wrapper.FingerprintManagerWrapper; import org.junit.Before; import org.junit.Test; @@ -52,7 +53,6 @@ import org.mockito.Mock; import org.mockito.MockitoAnnotations; import org.robolectric.annotation.Config; - /** * Tests for {@link SetNewPasswordController}. */ @@ -63,7 +63,7 @@ public final class SetNewPasswordControllerTest { private static final long FINGERPRINT_CHALLENGE = -9876512313131L; @Mock PackageManager mPackageManager; - @Mock IFingerprintManager mFingerprintManager; + @Mock FingerprintManagerWrapper mFingerprintManager; @Mock DevicePolicyManager mDevicePolicyManager; @Mock private SetNewPasswordController.Ui mUi; diff --git a/tests/robotests/src/com/android/settings/search/InstalledAppResultLoaderTest.java b/tests/robotests/src/com/android/settings/search/InstalledAppResultLoaderTest.java index 19854fcf09e..f1a25a12002 100644 --- a/tests/robotests/src/com/android/settings/search/InstalledAppResultLoaderTest.java +++ b/tests/robotests/src/com/android/settings/search/InstalledAppResultLoaderTest.java @@ -41,11 +41,11 @@ import android.os.UserManager; import com.android.settings.R; import com.android.settings.TestConfig; -import com.android.settings.applications.PackageManagerWrapper; import com.android.settings.dashboard.SiteMapManager; import com.android.settings.testutils.ApplicationTestUtils; import com.android.settings.testutils.FakeFeatureFactory; import com.android.settings.testutils.SettingsRobolectricTestRunner; +import com.android.settingslib.wrapper.PackageManagerWrapper; import org.junit.Before; import org.junit.Test; diff --git a/tests/robotests/src/com/android/settings/testutils/shadow/ShadowAccessibilityManagerWrapperImpl.java b/tests/robotests/src/com/android/settings/testutils/shadow/ShadowAccessibilityManagerWrapperImpl.java index 95d5de5e5b9..22a1c047f25 100644 --- a/tests/robotests/src/com/android/settings/testutils/shadow/ShadowAccessibilityManagerWrapperImpl.java +++ b/tests/robotests/src/com/android/settings/testutils/shadow/ShadowAccessibilityManagerWrapperImpl.java @@ -16,7 +16,7 @@ package com.android.settings.testutils.shadow; -import com.android.settings.applications.AccessibilityManagerWrapperImpl; +import com.android.settings.wrapper.AccessibilityManagerWrapper; import org.robolectric.annotation.Implementation; import org.robolectric.annotation.Implements; @@ -24,7 +24,7 @@ import org.robolectric.annotation.Implements; /** * This class provides shadow for API that is not supported in current roboletric */ -@Implements(AccessibilityManagerWrapperImpl.class) +@Implements(AccessibilityManagerWrapper.class) public class ShadowAccessibilityManagerWrapperImpl { @Implementation diff --git a/tests/robotests/src/com/android/settings/testutils/shadow/ShadowAccessibilityServiceInfoWrapperImpl.java b/tests/robotests/src/com/android/settings/testutils/shadow/ShadowAccessibilityServiceInfoWrapperImpl.java index a6cb5d07bd6..dd4b2ee940e 100644 --- a/tests/robotests/src/com/android/settings/testutils/shadow/ShadowAccessibilityServiceInfoWrapperImpl.java +++ b/tests/robotests/src/com/android/settings/testutils/shadow/ShadowAccessibilityServiceInfoWrapperImpl.java @@ -18,11 +18,11 @@ package com.android.settings.testutils.shadow; import android.content.ComponentName; -import com.android.settings.applications.AccessibilityServiceInfoWrapperImpl; +import com.android.settings.wrapper.AccessibilityServiceInfoWrapper; import org.robolectric.annotation.Implementation; import org.robolectric.annotation.Implements; -@Implements(AccessibilityServiceInfoWrapperImpl.class) +@Implements(AccessibilityServiceInfoWrapper.class) public class ShadowAccessibilityServiceInfoWrapperImpl { private static ComponentName sComponentName; diff --git a/tests/robotests/src/com/android/settings/testutils/shadow/ShadowKeyValueListParserWrapperImpl.java b/tests/robotests/src/com/android/settings/testutils/shadow/ShadowKeyValueListParserWrapperImpl.java index 0af9c304942..05c6139c2cc 100644 --- a/tests/robotests/src/com/android/settings/testutils/shadow/ShadowKeyValueListParserWrapperImpl.java +++ b/tests/robotests/src/com/android/settings/testutils/shadow/ShadowKeyValueListParserWrapperImpl.java @@ -1,6 +1,6 @@ package com.android.settings.testutils.shadow; -import com.android.settings.fuelgauge.anomaly.KeyValueListParserWrapperImpl; +import com.android.settings.wrapper.KeyValueListParserWrapper; import org.robolectric.annotation.Implementation; import org.robolectric.annotation.Implements; @@ -10,7 +10,7 @@ import org.robolectric.annotation.Implements; * {@link #getBoolean(String, boolean)} that doesn't support in the current * robolectric */ -@Implements(KeyValueListParserWrapperImpl.class) +@Implements(KeyValueListParserWrapper.class) public class ShadowKeyValueListParserWrapperImpl { @Implementation diff --git a/tests/robotests/src/com/android/settings/testutils/shadow/ShadowPowerManagerWrapper.java b/tests/robotests/src/com/android/settings/testutils/shadow/ShadowPowerManagerWrapper.java index 7aa28fae00b..b1e62b068fd 100644 --- a/tests/robotests/src/com/android/settings/testutils/shadow/ShadowPowerManagerWrapper.java +++ b/tests/robotests/src/com/android/settings/testutils/shadow/ShadowPowerManagerWrapper.java @@ -17,7 +17,7 @@ package com.android.settings.testutils.shadow; -import com.android.settings.display.PowerManagerWrapper; +import com.android.settings.wrapper.PowerManagerWrapper; import org.robolectric.annotation.Implementation; import org.robolectric.annotation.Implements; diff --git a/tests/robotests/src/com/android/settings/testutils/shadow/ShadowRestrictedLockUtilsWrapper.java b/tests/robotests/src/com/android/settings/testutils/shadow/ShadowRestrictedLockUtilsWrapper.java index 0e0adce7bff..58fc67a4b4f 100644 --- a/tests/robotests/src/com/android/settings/testutils/shadow/ShadowRestrictedLockUtilsWrapper.java +++ b/tests/robotests/src/com/android/settings/testutils/shadow/ShadowRestrictedLockUtilsWrapper.java @@ -1,7 +1,7 @@ package com.android.settings.testutils.shadow; import android.content.Context; -import com.android.settings.network.RestrictedLockUtilsWrapper; +import com.android.settings.wrapper.RestrictedLockUtilsWrapper; import org.robolectric.annotation.Implements; /** diff --git a/tests/robotests/src/com/android/settings/testutils/shadow/ShadowUtils.java b/tests/robotests/src/com/android/settings/testutils/shadow/ShadowUtils.java index 271ffa8e8e3..bfeb3c7a3fe 100644 --- a/tests/robotests/src/com/android/settings/testutils/shadow/ShadowUtils.java +++ b/tests/robotests/src/com/android/settings/testutils/shadow/ShadowUtils.java @@ -22,7 +22,7 @@ import android.os.UserHandle; import android.os.UserManager; import com.android.settings.Utils; -import com.android.settings.password.IFingerprintManager; +import com.android.settings.wrapper.FingerprintManagerWrapper; import org.robolectric.annotation.Implementation; import org.robolectric.annotation.Implements; @@ -30,7 +30,7 @@ import org.robolectric.annotation.Implements; @Implements(Utils.class) public class ShadowUtils { - private static IFingerprintManager sFingerprintManager = null; + private static FingerprintManagerWrapper sFingerprintManager = null; private static boolean sIsUserAMonkey; private static boolean sIsDemoUser; private static ComponentName sDeviceOwnerComponentName; @@ -41,11 +41,11 @@ public class ShadowUtils { } @Implementation - public static IFingerprintManager getFingerprintManagerWrapperOrNull(Context context) { + public static FingerprintManagerWrapper getFingerprintManagerWrapperOrNull(Context context) { return sFingerprintManager; } - public static void setFingerprintManager(IFingerprintManager fingerprintManager) { + public static void setFingerprintManager(FingerprintManagerWrapper fingerprintManager) { sFingerprintManager = fingerprintManager; } diff --git a/tests/robotests/src/com/android/settings/vpn2/VpnUtilsTest.java b/tests/robotests/src/com/android/settings/vpn2/VpnUtilsTest.java index 29267274505..9442892956f 100644 --- a/tests/robotests/src/com/android/settings/vpn2/VpnUtilsTest.java +++ b/tests/robotests/src/com/android/settings/vpn2/VpnUtilsTest.java @@ -18,6 +18,7 @@ package com.android.settings.vpn2; import com.android.settings.testutils.SettingsRobolectricTestRunner; import com.android.settings.TestConfig; +import com.android.settings.wrapper.ConnectivityManagerWrapper; import org.junit.Test; import org.junit.runner.RunWith; diff --git a/tests/robotests/src/com/android/settings/webview/WebViewAppPickerTest.java b/tests/robotests/src/com/android/settings/webview/WebViewAppPickerTest.java index e5354456edb..2a53ab6cd72 100644 --- a/tests/robotests/src/com/android/settings/webview/WebViewAppPickerTest.java +++ b/tests/robotests/src/com/android/settings/webview/WebViewAppPickerTest.java @@ -28,11 +28,12 @@ import android.os.UserManager; import com.android.settings.testutils.SettingsRobolectricTestRunner; import com.android.settings.TestConfig; -import com.android.settings.applications.PackageManagerWrapper; import com.android.settings.applications.defaultapps.DefaultAppInfo; import com.android.settings.core.instrumentation.MetricsFeatureProvider; import com.android.settings.testutils.FakeFeatureFactory; import com.android.settings.widget.RadioButtonPreference; +import com.android.settings.wrapper.UserPackageWrapper; +import com.android.settingslib.wrapper.PackageManagerWrapper; import org.junit.Before; import org.junit.Test; diff --git a/tests/robotests/src/com/android/settings/wifi/UseOpenWifiPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/wifi/UseOpenWifiPreferenceControllerTest.java index a76b82a1f14..297054d6769 100644 --- a/tests/robotests/src/com/android/settings/wifi/UseOpenWifiPreferenceControllerTest.java +++ b/tests/robotests/src/com/android/settings/wifi/UseOpenWifiPreferenceControllerTest.java @@ -38,8 +38,8 @@ import android.support.v7.preference.Preference; import com.android.settings.R; import com.android.settings.TestConfig; -import com.android.settings.network.NetworkScoreManagerWrapper; import com.android.settings.testutils.SettingsRobolectricTestRunner; +import com.android.settings.wrapper.NetworkScoreManagerWrapper; import com.android.settingslib.core.lifecycle.Lifecycle; import com.google.common.collect.Lists; diff --git a/tests/robotests/src/com/android/settings/wifi/WifiEnablerTest.java b/tests/robotests/src/com/android/settings/wifi/WifiEnablerTest.java index c7647ba2bee..63f89e62c5c 100644 --- a/tests/robotests/src/com/android/settings/wifi/WifiEnablerTest.java +++ b/tests/robotests/src/com/android/settings/wifi/WifiEnablerTest.java @@ -24,6 +24,7 @@ import com.android.settings.testutils.SettingsRobolectricTestRunner; import com.android.settings.TestConfig; import com.android.settings.core.instrumentation.MetricsFeatureProvider; import com.android.settings.widget.SwitchWidgetController; +import com.android.settings.wrapper.ConnectivityManagerWrapper; import org.junit.Before; import org.junit.Test; diff --git a/tests/robotests/src/com/android/settings/wifi/WifiWakeupPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/wifi/WifiWakeupPreferenceControllerTest.java index 306b297c69f..0435b7eaef5 100644 --- a/tests/robotests/src/com/android/settings/wifi/WifiWakeupPreferenceControllerTest.java +++ b/tests/robotests/src/com/android/settings/wifi/WifiWakeupPreferenceControllerTest.java @@ -31,10 +31,10 @@ import android.support.v14.preference.SwitchPreference; import android.support.v7.preference.Preference; import com.android.settings.R; -import com.android.settings.network.NetworkScoreManagerWrapper; import com.android.settings.testutils.SettingsRobolectricTestRunner; import com.android.settings.TestConfig; import com.android.settings.testutils.shadow.SettingsShadowResources; +import com.android.settings.wrapper.NetworkScoreManagerWrapper; import com.android.settingslib.core.lifecycle.Lifecycle; import org.junit.After; diff --git a/tests/robotests/src/com/android/settings/wifi/WriteWifiConfigToNfcDialogTest.java b/tests/robotests/src/com/android/settings/wifi/WriteWifiConfigToNfcDialogTest.java index 41b71ada45c..5e10e0fc1f3 100644 --- a/tests/robotests/src/com/android/settings/wifi/WriteWifiConfigToNfcDialogTest.java +++ b/tests/robotests/src/com/android/settings/wifi/WriteWifiConfigToNfcDialogTest.java @@ -27,6 +27,7 @@ import android.view.inputmethod.InputMethodManager; import com.android.settings.testutils.SettingsRobolectricTestRunner; import com.android.settings.TestConfig; import com.android.settings.testutils.shadow.ShadowNfcAdapter; +import com.android.settings.wrapper.WifiManagerWrapper; import org.junit.After; import org.junit.Before; diff --git a/tests/robotests/src/com/android/settings/wifi/details/WifiDetailPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/wifi/details/WifiDetailPreferenceControllerTest.java index 1c2ddb4ac10..aa21a190639 100644 --- a/tests/robotests/src/com/android/settings/wifi/details/WifiDetailPreferenceControllerTest.java +++ b/tests/robotests/src/com/android/settings/wifi/details/WifiDetailPreferenceControllerTest.java @@ -64,11 +64,11 @@ import com.android.settings.applications.LayoutPreference; import com.android.settings.core.instrumentation.MetricsFeatureProvider; import com.android.settings.testutils.SettingsRobolectricTestRunner; import com.android.settings.testutils.shadow.ShadowEntityHeaderController; -import com.android.settings.vpn2.ConnectivityManagerWrapperImpl; import com.android.settings.widget.ActionButtonPreference; import com.android.settings.widget.ActionButtonPreferenceTest; import com.android.settings.widget.EntityHeaderController; import com.android.settings.wifi.WifiDetailPreference; +import com.android.settings.wrapper.ConnectivityManagerWrapper; import com.android.settingslib.core.lifecycle.Lifecycle; import com.android.settingslib.wifi.AccessPoint; @@ -108,7 +108,7 @@ public class WifiDetailPreferenceControllerTest { @Mock private AccessPoint mockAccessPoint; @Mock private Activity mockActivity; @Mock private ConnectivityManager mockConnectivityManager; - @Mock private ConnectivityManagerWrapperImpl mockConnectivityManagerWrapper; + @Mock private ConnectivityManagerWrapper mockConnectivityManagerWrapper; @Mock private Network mockNetwork; @Mock private NetworkInfo mockNetworkInfo; @Mock private WifiConfiguration mockWifiConfig; diff --git a/tests/unit/src/com/android/settings/deviceinfo/storage/StorageAsyncLoaderTest.java b/tests/unit/src/com/android/settings/deviceinfo/storage/StorageAsyncLoaderTest.java index 5a3569c2248..f622804c04a 100644 --- a/tests/unit/src/com/android/settings/deviceinfo/storage/StorageAsyncLoaderTest.java +++ b/tests/unit/src/com/android/settings/deviceinfo/storage/StorageAsyncLoaderTest.java @@ -35,9 +35,9 @@ import android.support.test.filters.SmallTest; import android.support.test.runner.AndroidJUnit4; import android.util.SparseArray; -import com.android.settings.applications.PackageManagerWrapper; -import com.android.settings.applications.UserManagerWrapper; +import com.android.settings.wrapper.UserManagerWrapper; import com.android.settingslib.applications.StorageStatsSource; +import com.android.settingslib.wrapper.PackageManagerWrapper; import org.junit.Before; import org.junit.Test; From eb6db6cc4d60d17a64a2d0638e24565010bd5e8f Mon Sep 17 00:00:00 2001 From: Lei Yu Date: Fri, 15 Sep 2017 18:01:13 +0000 Subject: [PATCH 19/23] Revert "Turn on wakeupAlarm anomaly detector" This reverts commit 1a49a8ab3900ab77209b1c5b34a33cc3a8be3e2c. Bug: 65738439 Test: RunSettingsRoboTests Change-Id: Ifb2f72ba51e229b9387ff5a977bd51b229fcdf6a --- .../settings/fuelgauge/anomaly/AnomalyDetectionPolicy.java | 2 +- .../fuelgauge/anomaly/AnomalyDetectionPolicyTest.java | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/com/android/settings/fuelgauge/anomaly/AnomalyDetectionPolicy.java b/src/com/android/settings/fuelgauge/anomaly/AnomalyDetectionPolicy.java index 4829ca01d31..0c401b500f5 100644 --- a/src/com/android/settings/fuelgauge/anomaly/AnomalyDetectionPolicy.java +++ b/src/com/android/settings/fuelgauge/anomaly/AnomalyDetectionPolicy.java @@ -122,7 +122,7 @@ public class AnomalyDetectionPolicy { anomalyDetectionEnabled = mParserWrapper.getBoolean(KEY_ANOMALY_DETECTION_ENABLED, true); wakeLockDetectionEnabled = mParserWrapper.getBoolean(KEY_WAKELOCK_DETECTION_ENABLED, true); wakeupAlarmDetectionEnabled = mParserWrapper.getBoolean(KEY_WAKEUP_ALARM_DETECTION_ENABLED, - true); + false); bluetoothScanDetectionEnabled = mParserWrapper.getBoolean( KEY_BLUETOOTH_SCAN_DETECTION_ENABLED, true); wakeLockThreshold = mParserWrapper.getLong(KEY_WAKELOCK_THRESHOLD, diff --git a/tests/robotests/src/com/android/settings/fuelgauge/anomaly/AnomalyDetectionPolicyTest.java b/tests/robotests/src/com/android/settings/fuelgauge/anomaly/AnomalyDetectionPolicyTest.java index 169cba8e9bf..914cc2f514d 100644 --- a/tests/robotests/src/com/android/settings/fuelgauge/anomaly/AnomalyDetectionPolicyTest.java +++ b/tests/robotests/src/com/android/settings/fuelgauge/anomaly/AnomalyDetectionPolicyTest.java @@ -84,7 +84,7 @@ public class AnomalyDetectionPolicyTest { assertThat(anomalyDetectionPolicy.anomalyDetectionEnabled).isTrue(); assertThat(anomalyDetectionPolicy.wakeLockDetectionEnabled).isTrue(); assertThat(anomalyDetectionPolicy.wakeLockThreshold).isEqualTo(DateUtils.HOUR_IN_MILLIS); - assertThat(anomalyDetectionPolicy.wakeupAlarmDetectionEnabled).isTrue(); + assertThat(anomalyDetectionPolicy.wakeupAlarmDetectionEnabled).isFalse(); assertThat(anomalyDetectionPolicy.wakeupAlarmThreshold).isEqualTo(60); assertThat(anomalyDetectionPolicy.bluetoothScanDetectionEnabled).isTrue(); assertThat(anomalyDetectionPolicy.bluetoothScanThreshold).isEqualTo( @@ -112,7 +112,7 @@ public class AnomalyDetectionPolicyTest { doReturn(false).when(mKeyValueListParserWrapper).getBoolean( AnomalyDetectionPolicy.KEY_WAKELOCK_DETECTION_ENABLED, true); doReturn(true).when(mKeyValueListParserWrapper).getBoolean( - AnomalyDetectionPolicy.KEY_WAKEUP_ALARM_DETECTION_ENABLED, true); + AnomalyDetectionPolicy.KEY_WAKEUP_ALARM_DETECTION_ENABLED, false); doReturn(true).when(mKeyValueListParserWrapper).getBoolean( AnomalyDetectionPolicy.KEY_BLUETOOTH_SCAN_DETECTION_ENABLED, true); From 5024a3896547fc33b882ba78b5845d186375d9e0 Mon Sep 17 00:00:00 2001 From: jackqdyulei Date: Thu, 14 Sep 2017 16:11:02 -0700 Subject: [PATCH 20/23] Hook up lint color check to settings After this cl, settings will run hardcoded color check (go/color-check-guideline) for all the cls in pre-upload. This check will prompt error message if cl contains hardcoded color. Bug: 32750778 Test: repo upload . Change-Id: Id35ded5199094a14fcc4eeebc470164d052e278e --- PREUPLOAD.cfg | 1 + color-check-baseline.xml | 2484 ++++++++++++++++++++++++++++++++++++++ 2 files changed, 2485 insertions(+) create mode 100644 color-check-baseline.xml diff --git a/PREUPLOAD.cfg b/PREUPLOAD.cfg index bbc1f689c71..62a2e434793 100644 --- a/PREUPLOAD.cfg +++ b/PREUPLOAD.cfg @@ -1,4 +1,5 @@ [Hook Scripts] checkstyle_hook = ${REPO_ROOT}/prebuilts/checkstyle/checkstyle.py --sha ${PREUPLOAD_COMMIT} -fw src/com/android/settings/print/ +checkcolor_hook = ${REPO_ROOT}/prebuilts/checkcolor/checkcolor.py -p . diff --git a/color-check-baseline.xml b/color-check-baseline.xml new file mode 100644 index 00000000000..cbcdf48ddea --- /dev/null +++ b/color-check-baseline.xml @@ -0,0 +1,2484 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + From 6f60cddc9e4f9dfd932181765d6b75b2040b0ad7 Mon Sep 17 00:00:00 2001 From: Doris Ling Date: Thu, 14 Sep 2017 18:54:48 -0700 Subject: [PATCH 21/23] Add a new feature flag for the expand button in support lib. - check the feature flag to determine whether to use the existing progressive disclosure mixin or use the expand button in the support library. - add corresponding preference xml files that add the new preference group attribute to use with the expand button in the support lib. Bug: 63985174 Test: make RunSettingsRoboTests Change-Id: Ida6eb6182a8066ad1413b7f6142512345fd914d0 --- ...pp_and_notification_new_advance_button.xml | 83 ++++++++ .../display_settings_new_advance_button.xml | 128 ++++++++++++ .../language_and_input_new_advance_button.xml | 92 +++++++++ res/xml/sound_settings_new_advance_button.xml | 195 ++++++++++++++++++ src/com/android/settings/DisplaySettings.java | 3 +- .../AppAndNotificationDashboardFragment.java | 3 +- .../dashboard/ProgressiveDisclosureMixin.java | 11 +- .../language/LanguageAndInputSettings.java | 3 +- .../settings/notification/SoundSettings.java | 3 +- .../android/settings/DisplaySettingsTest.java | 8 +- ...pAndNotificationDashboardFragmentTest.java | 8 +- .../dashboard/ProgressiveDisclosureTest.java | 25 ++- .../LanguageAndInputSettingsTest.java | 12 +- .../notification/SoundSettingsTest.java | 7 +- 14 files changed, 570 insertions(+), 11 deletions(-) create mode 100644 res/xml/app_and_notification_new_advance_button.xml create mode 100644 res/xml/display_settings_new_advance_button.xml create mode 100644 res/xml/language_and_input_new_advance_button.xml create mode 100644 res/xml/sound_settings_new_advance_button.xml diff --git a/res/xml/app_and_notification_new_advance_button.xml b/res/xml/app_and_notification_new_advance_button.xml new file mode 100644 index 00000000000..c7b91e867eb --- /dev/null +++ b/res/xml/app_and_notification_new_advance_button.xml @@ -0,0 +1,83 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/res/xml/display_settings_new_advance_button.xml b/res/xml/display_settings_new_advance_button.xml new file mode 100644 index 00000000000..c7cf50590e9 --- /dev/null +++ b/res/xml/display_settings_new_advance_button.xml @@ -0,0 +1,128 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/res/xml/language_and_input_new_advance_button.xml b/res/xml/language_and_input_new_advance_button.xml new file mode 100644 index 00000000000..e5ae674f552 --- /dev/null +++ b/res/xml/language_and_input_new_advance_button.xml @@ -0,0 +1,92 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/res/xml/sound_settings_new_advance_button.xml b/res/xml/sound_settings_new_advance_button.xml new file mode 100644 index 00000000000..6b0ba0e81a7 --- /dev/null +++ b/res/xml/sound_settings_new_advance_button.xml @@ -0,0 +1,195 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/com/android/settings/DisplaySettings.java b/src/com/android/settings/DisplaySettings.java index 86c3da16ba6..b5f848c630d 100644 --- a/src/com/android/settings/DisplaySettings.java +++ b/src/com/android/settings/DisplaySettings.java @@ -73,7 +73,8 @@ public class DisplaySettings extends DashboardFragment { @Override protected int getPreferenceScreenResId() { - return R.xml.display_settings; + return mProgressiveDisclosureMixin.isEnabled() + ? R.xml.display_settings : R.xml.display_settings_new_advance_button; } @Override diff --git a/src/com/android/settings/applications/AppAndNotificationDashboardFragment.java b/src/com/android/settings/applications/AppAndNotificationDashboardFragment.java index d3063536c47..204e120eb86 100644 --- a/src/com/android/settings/applications/AppAndNotificationDashboardFragment.java +++ b/src/com/android/settings/applications/AppAndNotificationDashboardFragment.java @@ -60,7 +60,8 @@ public class AppAndNotificationDashboardFragment extends DashboardFragment { @Override protected int getPreferenceScreenResId() { - return R.xml.app_and_notification; + return mProgressiveDisclosureMixin.isEnabled() + ? R.xml.app_and_notification : R.xml.app_and_notification_new_advance_button; } @Override diff --git a/src/com/android/settings/dashboard/ProgressiveDisclosureMixin.java b/src/com/android/settings/dashboard/ProgressiveDisclosureMixin.java index 92055be3764..3dfffccb801 100644 --- a/src/com/android/settings/dashboard/ProgressiveDisclosureMixin.java +++ b/src/com/android/settings/dashboard/ProgressiveDisclosureMixin.java @@ -24,6 +24,7 @@ import android.support.v7.preference.Preference; import android.support.v7.preference.PreferenceGroup; import android.support.v7.preference.PreferenceScreen; import android.text.TextUtils; +import android.util.FeatureFlagUtils; import android.util.Log; import com.android.internal.logging.nano.MetricsProto; @@ -42,6 +43,8 @@ import java.util.List; public class ProgressiveDisclosureMixin implements Preference.OnPreferenceClickListener, LifecycleObserver, OnCreate, OnSaveInstanceState { + @VisibleForTesting + static final String FEATURE_FLAG_NEW_ADVANCE_BUTTON = "new_settings_advance_button"; private static final String TAG = "ProgressiveDisclosure"; private static final String STATE_USER_EXPANDED = "state_user_expanded"; private static final int DEFAULT_TILE_LIMIT = 300; @@ -102,11 +105,17 @@ public class ProgressiveDisclosureMixin implements Preference.OnPreferenceClickL return false; } + public boolean isEnabled() { + return !FeatureFlagUtils.isEnabled(FEATURE_FLAG_NEW_ADVANCE_BUTTON); + } + /** * Sets the threshold to start collapsing preferences when there are too many. */ public void setTileLimit(int limit) { - mTileLimit = limit; + if (isEnabled()) { + mTileLimit = limit; + } } /** diff --git a/src/com/android/settings/language/LanguageAndInputSettings.java b/src/com/android/settings/language/LanguageAndInputSettings.java index 4affc6edbc6..19b1a9f0b67 100644 --- a/src/com/android/settings/language/LanguageAndInputSettings.java +++ b/src/com/android/settings/language/LanguageAndInputSettings.java @@ -86,7 +86,8 @@ public class LanguageAndInputSettings extends DashboardFragment { @Override protected int getPreferenceScreenResId() { - return R.xml.language_and_input; + return mProgressiveDisclosureMixin.isEnabled() + ? R.xml.language_and_input : R.xml.language_and_input_new_advance_button; } @Override diff --git a/src/com/android/settings/notification/SoundSettings.java b/src/com/android/settings/notification/SoundSettings.java index e759c390bd5..6812d4d557b 100644 --- a/src/com/android/settings/notification/SoundSettings.java +++ b/src/com/android/settings/notification/SoundSettings.java @@ -109,7 +109,8 @@ public class SoundSettings extends DashboardFragment { @Override protected int getPreferenceScreenResId() { - return R.xml.sound_settings; + return mProgressiveDisclosureMixin.isEnabled() + ? R.xml.sound_settings : R.xml.sound_settings_new_advance_button; } @Override diff --git a/tests/robotests/src/com/android/settings/DisplaySettingsTest.java b/tests/robotests/src/com/android/settings/DisplaySettingsTest.java index 4b345c0c308..3ee8feb1268 100644 --- a/tests/robotests/src/com/android/settings/DisplaySettingsTest.java +++ b/tests/robotests/src/com/android/settings/DisplaySettingsTest.java @@ -2,8 +2,11 @@ package com.android.settings; import static com.google.common.truth.Truth.assertThat; +import static org.mockito.Mockito.mock; + import android.content.Context; +import com.android.settings.dashboard.ProgressiveDisclosureMixin; import com.android.settings.testutils.SettingsRobolectricTestRunner; import com.android.settings.testutils.XmlTestUtils; import com.android.settings.testutils.shadow.ShadowPowerManagerWrapper; @@ -13,6 +16,7 @@ import org.junit.Test; import org.junit.runner.RunWith; import org.robolectric.RuntimeEnvironment; import org.robolectric.annotation.Config; +import org.robolectric.util.ReflectionHelpers; import java.util.ArrayList; import java.util.List; @@ -25,9 +29,9 @@ public class DisplaySettingsTest { @Config(shadows = ShadowPowerManagerWrapper.class) public void testPreferenceControllers_getPreferenceKeys_existInPreferenceScreen() { final Context context = RuntimeEnvironment.application; -// PowerManager wrapper = mock(PowerManager.class); -// doReturn(wrapper).when(context).getSystemService(Context.POWER_SERVICE); final DisplaySettings fragment = new DisplaySettings(); + ReflectionHelpers.setField(fragment, "mProgressiveDisclosureMixin", + mock(ProgressiveDisclosureMixin.class)); final List preferenceScreenKeys = XmlTestUtils.getKeysFromPreferenceXml(context, fragment.getPreferenceScreenResId()); final List preferenceKeys = new ArrayList<>(); diff --git a/tests/robotests/src/com/android/settings/applications/AppAndNotificationDashboardFragmentTest.java b/tests/robotests/src/com/android/settings/applications/AppAndNotificationDashboardFragmentTest.java index 697d04ffa8d..269d840cac4 100644 --- a/tests/robotests/src/com/android/settings/applications/AppAndNotificationDashboardFragmentTest.java +++ b/tests/robotests/src/com/android/settings/applications/AppAndNotificationDashboardFragmentTest.java @@ -19,6 +19,8 @@ package com.android.settings.applications; import android.content.Context; import android.os.UserManager; + +import com.android.settings.dashboard.ProgressiveDisclosureMixin; import com.android.settings.testutils.SettingsRobolectricTestRunner; import com.android.settings.TestConfig; import com.android.settings.testutils.XmlTestUtils; @@ -27,6 +29,7 @@ import org.junit.Test; import org.junit.runner.RunWith; import org.robolectric.RuntimeEnvironment; import org.robolectric.annotation.Config; +import org.robolectric.util.ReflectionHelpers; import java.util.List; @@ -47,7 +50,10 @@ public class AppAndNotificationDashboardFragmentTest { when(context.getSystemService(Context.USER_SERVICE)).thenReturn(manager); final List niks = AppAndNotificationDashboardFragment.SEARCH_INDEX_DATA_PROVIDER .getNonIndexableKeys(context); - final int xmlId = (new AppAndNotificationDashboardFragment()).getPreferenceScreenResId(); + AppAndNotificationDashboardFragment fragment = new AppAndNotificationDashboardFragment(); + ReflectionHelpers.setField(fragment, "mProgressiveDisclosureMixin", + mock(ProgressiveDisclosureMixin.class)); + final int xmlId = fragment.getPreferenceScreenResId(); final List keys = XmlTestUtils.getKeysFromPreferenceXml(context, xmlId); diff --git a/tests/robotests/src/com/android/settings/dashboard/ProgressiveDisclosureTest.java b/tests/robotests/src/com/android/settings/dashboard/ProgressiveDisclosureTest.java index 6fe60cf5124..3155ea90a33 100644 --- a/tests/robotests/src/com/android/settings/dashboard/ProgressiveDisclosureTest.java +++ b/tests/robotests/src/com/android/settings/dashboard/ProgressiveDisclosureTest.java @@ -26,7 +26,9 @@ import com.android.settings.R; import com.android.settings.testutils.SettingsRobolectricTestRunner; import com.android.settings.TestConfig; import com.android.settings.testutils.FakeFeatureFactory; +import com.android.settings.testutils.shadow.SettingsShadowSystemProperties; +import org.junit.After; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; @@ -39,6 +41,7 @@ import org.robolectric.util.ReflectionHelpers; import java.util.List; +import static android.util.FeatureFlagUtils.FFLAG_PREFIX; import static com.google.common.truth.Truth.assertThat; import static org.mockito.ArgumentMatchers.nullable; @@ -53,7 +56,8 @@ import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; @RunWith(SettingsRobolectricTestRunner.class) -@Config(manifest = TestConfig.MANIFEST_PATH, sdk = TestConfig.SDK_VERSION) +@Config(manifest = TestConfig.MANIFEST_PATH, sdk = TestConfig.SDK_VERSION, + shadows = {SettingsShadowSystemProperties.class}) public class ProgressiveDisclosureTest { @Mock(answer = Answers.RETURNS_DEEP_STUBS) @@ -80,6 +84,25 @@ public class ProgressiveDisclosureTest { mPreference.setKey("test"); } + @After + public void tearDown() { + SettingsShadowSystemProperties.clear(); + } + + @Test + public void systemPropertySetForNewAdvancedButtonFeature_verifyIsDisabled() { + SettingsShadowSystemProperties.set( + FFLAG_PREFIX + ProgressiveDisclosureMixin.FEATURE_FLAG_NEW_ADVANCE_BUTTON, "true"); + assertThat(mMixin.isEnabled()).isFalse(); + } + + @Test + public void systemPropertyNotSet_verifyIsDisabled() { + SettingsShadowSystemProperties.set( + FFLAG_PREFIX + ProgressiveDisclosureMixin.FEATURE_FLAG_NEW_ADVANCE_BUTTON, "false"); + assertThat(mMixin.isEnabled()).isTrue(); + } + @Test public void shouldNotCollapse_lessPreferenceThanLimit() { when(mScreen.getPreferenceCount()).thenReturn(5); diff --git a/tests/robotests/src/com/android/settings/language/LanguageAndInputSettingsTest.java b/tests/robotests/src/com/android/settings/language/LanguageAndInputSettingsTest.java index 809fb3ae521..5c6e777395d 100644 --- a/tests/robotests/src/com/android/settings/language/LanguageAndInputSettingsTest.java +++ b/tests/robotests/src/com/android/settings/language/LanguageAndInputSettingsTest.java @@ -43,6 +43,7 @@ import android.view.textservice.TextServicesManager; import com.android.settings.R; import com.android.settings.TestConfig; +import com.android.settings.dashboard.ProgressiveDisclosureMixin; import com.android.settings.dashboard.SummaryLoader; import com.android.settings.testutils.SettingsRobolectricTestRunner; import com.android.settings.testutils.XmlTestUtils; @@ -59,6 +60,7 @@ import org.mockito.Mock; import org.mockito.MockitoAnnotations; import org.robolectric.RuntimeEnvironment; import org.robolectric.annotation.Config; +import org.robolectric.util.ReflectionHelpers; import java.util.ArrayList; import java.util.List; @@ -101,6 +103,9 @@ public class LanguageAndInputSettingsTest { @Test public void testGetPreferenceScreenResId() { + ProgressiveDisclosureMixin progessiveMixin = mock(ProgressiveDisclosureMixin.class); + when(progessiveMixin.isEnabled()).thenReturn(true); + ReflectionHelpers.setField(mFragment, "mProgressiveDisclosureMixin", progessiveMixin); assertThat(mFragment.getPreferenceScreenResId()).isEqualTo(R.xml.language_and_input); } @@ -167,7 +172,10 @@ public class LanguageAndInputSettingsTest { .getBoolean(com.android.internal.R.bool.config_supportSystemNavigationKeys); final List niks = LanguageAndInputSettings.SEARCH_INDEX_DATA_PROVIDER .getNonIndexableKeys(context); - final int xmlId = (new LanguageAndInputSettings()).getPreferenceScreenResId(); + LanguageAndInputSettings settings = new LanguageAndInputSettings(); + ReflectionHelpers.setField(settings, "mProgressiveDisclosureMixin", + mock(ProgressiveDisclosureMixin.class)); + final int xmlId = settings.getPreferenceScreenResId(); final List keys = XmlTestUtils.getKeysFromPreferenceXml(context, xmlId); @@ -178,6 +186,8 @@ public class LanguageAndInputSettingsTest { public void testPreferenceControllers_getPreferenceKeys_existInPreferenceScreen() { final Context context = RuntimeEnvironment.application; final LanguageAndInputSettings fragment = new LanguageAndInputSettings(); + ReflectionHelpers.setField(fragment, "mProgressiveDisclosureMixin", + mock(ProgressiveDisclosureMixin.class)); final List preferenceScreenKeys = XmlTestUtils.getKeysFromPreferenceXml(context, fragment.getPreferenceScreenResId()); final List preferenceKeys = new ArrayList<>(); diff --git a/tests/robotests/src/com/android/settings/notification/SoundSettingsTest.java b/tests/robotests/src/com/android/settings/notification/SoundSettingsTest.java index 59b70785e26..bd386468bc9 100644 --- a/tests/robotests/src/com/android/settings/notification/SoundSettingsTest.java +++ b/tests/robotests/src/com/android/settings/notification/SoundSettingsTest.java @@ -21,6 +21,7 @@ import android.content.Context; import android.media.AudioManager; import android.os.UserManager; import com.android.settings.R; +import com.android.settings.dashboard.ProgressiveDisclosureMixin; import com.android.settings.testutils.SettingsRobolectricTestRunner; import com.android.settings.TestConfig; import com.android.settings.testutils.XmlTestUtils; @@ -30,6 +31,7 @@ import org.junit.Test; import org.junit.runner.RunWith; import org.robolectric.RuntimeEnvironment; import org.robolectric.annotation.Config; +import org.robolectric.util.ReflectionHelpers; import java.util.List; @@ -59,7 +61,10 @@ public class SoundSettingsTest { final List niks = SoundSettings.SEARCH_INDEX_DATA_PROVIDER .getNonIndexableKeys(context); - final int xmlId = (new SoundSettings()).getPreferenceScreenResId(); + SoundSettings settings = new SoundSettings(); + ReflectionHelpers.setField(settings, "mProgressiveDisclosureMixin", + mock(ProgressiveDisclosureMixin.class)); + final int xmlId = settings.getPreferenceScreenResId(); final List keys = XmlTestUtils.getKeysFromPreferenceXml(context, xmlId); keys.addAll(XmlTestUtils.getKeysFromPreferenceXml(context, R.xml.zen_mode_settings)); From 135fecbee3f75adbef8176f1d541e250e87dfdfe Mon Sep 17 00:00:00 2001 From: Fan Zhang Date: Fri, 15 Sep 2017 13:22:04 -0700 Subject: [PATCH 22/23] Use "mid" stable id for condition cards conditionally. When there is no suggestion, use "mid" stableId instead of "top" stableId for the header card. This avoid an animation jank: when user swipes away a suggestion, the condition summary header moves up instead of disappears then reappears. Old behavior: --- Suggestion --- --swipe--> /// Top Header /// /// Mid Header /// New behavior: --- Suggestion --- -- swipe --> /// Mid Header /// /// Mid Header /// (Notice the header id change) Change-Id: I63512d3d21382488e43dddb8819fabe4af40d101 Fixes: 65729560 Test: robotests --- .../settings/dashboard/DashboardData.java | 19 +++++--- .../settings/dashboard/DashboardDataTest.java | 48 +++++++++++++++---- 2 files changed, 52 insertions(+), 15 deletions(-) diff --git a/src/com/android/settings/dashboard/DashboardData.java b/src/com/android/settings/dashboard/DashboardData.java index 0fac0a2248d..b60fef368b2 100644 --- a/src/com/android/settings/dashboard/DashboardData.java +++ b/src/com/android/settings/dashboard/DashboardData.java @@ -222,15 +222,22 @@ public class DashboardData { final int hiddenSuggestion = hasSuggestions ? sizeOf(mSuggestions) - sizeOf(suggestions) : 0; + final boolean hasSuggestionAndCollapsed = hasSuggestions + && mSuggestionConditionMode == HEADER_MODE_COLLAPSED; + final boolean onlyHasConditionAndCollapsed = !hasSuggestions + && hasConditions + && mSuggestionConditionMode != HEADER_MODE_FULLY_EXPANDED; + /* Top suggestion/condition header. This will be present when there is any suggestion - * and the mode is collapsed, or it only has conditions and the mode is not fully - * expanded. */ + * and the mode is collapsed */ addToItemList(new SuggestionConditionHeaderData(conditions, hiddenSuggestion), R.layout.suggestion_condition_header, - STABLE_ID_SUGGESTION_CONDITION_TOP_HEADER, - hasSuggestions && mSuggestionConditionMode == HEADER_MODE_COLLAPSED - || !hasSuggestions && hasConditions - && mSuggestionConditionMode != HEADER_MODE_FULLY_EXPANDED); + STABLE_ID_SUGGESTION_CONDITION_TOP_HEADER, hasSuggestionAndCollapsed); + + /* Use mid header if there is only condition & it's in collapsed mode */ + addToItemList(new SuggestionConditionHeaderData(conditions, hiddenSuggestion), + R.layout.suggestion_condition_header, + STABLE_ID_SUGGESTION_CONDITION_MIDDLE_HEADER, onlyHasConditionAndCollapsed); /* Suggestion container. This is the card view that contains the list of suggestions. * This will be added whenever the suggestion list is not empty */ diff --git a/tests/robotests/src/com/android/settings/dashboard/DashboardDataTest.java b/tests/robotests/src/com/android/settings/dashboard/DashboardDataTest.java index 77213f54cfe..ad257ee9044 100644 --- a/tests/robotests/src/com/android/settings/dashboard/DashboardDataTest.java +++ b/tests/robotests/src/com/android/settings/dashboard/DashboardDataTest.java @@ -16,6 +16,13 @@ package com.android.settings.dashboard; +import static com.android.settings.dashboard.DashboardData.STABLE_ID_CONDITION_CONTAINER; +import static com.android.settings.dashboard.DashboardData.STABLE_ID_SUGGESTION_CONDITION_FOOTER; +import static com.android.settings.dashboard.DashboardData.STABLE_ID_SUGGESTION_CONTAINER; +import static com.google.common.truth.Truth.assertThat; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.when; + import android.support.annotation.NonNull; import android.support.v7.util.DiffUtil; import android.support.v7.util.ListUpdateCallback; @@ -39,15 +46,6 @@ import java.util.Collections; import java.util.List; import java.util.Objects; -import static com.android.settings.dashboard.DashboardData.STABLE_ID_CONDITION_CONTAINER; -import static com.android.settings.dashboard.DashboardData.STABLE_ID_SUGGESTION_CONDITION_FOOTER; -import static com.android.settings.dashboard.DashboardData - .STABLE_ID_SUGGESTION_CONDITION_TOP_HEADER; -import static com.android.settings.dashboard.DashboardData.STABLE_ID_SUGGESTION_CONTAINER; -import static com.google.common.truth.Truth.assertThat; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.when; - @RunWith(RobolectricTestRunner.class) @Config(manifest = TestConfig.MANIFEST_PATH, sdk = TestConfig.SDK_VERSION) public class DashboardDataTest { @@ -214,6 +212,38 @@ public class DashboardDataTest { mDashboardDataWithTwoConditions, testResultData); } + @Test + public void testDiffUtil_RemoveOneSuggestion_causeItemRemoveAndChange() { + //Build testResultData + final List testResultData = new ArrayList<>(); + testResultData.add(new ListUpdateResult.ResultData( + ListUpdateResult.ResultData.TYPE_OPERATION_REMOVE, 0, 1)); + testResultData.add(new ListUpdateResult.ResultData( + ListUpdateResult.ResultData.TYPE_OPERATION_CHANGE, 1, 1)); + // Build DashboardData + final List oneItemConditions = new ArrayList<>(); + when(mTestCondition.shouldShow()).thenReturn(true); + oneItemConditions.add(mTestCondition); + final List suggestions = new ArrayList<>(); + mTestSuggestion.title = TEST_SUGGESTION_TITLE; + suggestions.add(mTestSuggestion); + + final DashboardData oldData = new DashboardData.Builder() + .setConditions(oneItemConditions) + .setCategory(mDashboardCategory) + .setSuggestions(suggestions) + .setSuggestionConditionMode(DashboardData.HEADER_MODE_DEFAULT) + .build(); + final DashboardData newData = new DashboardData.Builder() + .setConditions(oneItemConditions) + .setSuggestions(null) + .setCategory(mDashboardCategory) + .setSuggestionConditionMode(DashboardData.HEADER_MODE_DEFAULT) + .build(); + + testDiffUtil(oldData, newData, testResultData); + } + @Test public void testDiffUtil_DeleteAllData_ResultDataOneDeleted() { //Build testResultData From ffd531f1d34cd5016020908dde3b55d17b4002c1 Mon Sep 17 00:00:00 2001 From: Fan Zhang Date: Fri, 15 Sep 2017 17:10:24 -0700 Subject: [PATCH 23/23] Move SuggestionService AIDL related calls to a controller. The controller makes it easier to manage IPCs and make it easier for testing. Bug: 65065268 Test: robotests Change-Id: Ie5797655543cb22d8196267058598a1b4222a8d1 --- .../suggestions/SuggestionController.java | 146 ++++++++++++++++++ .../SuggestionControllerMixin.java | 92 +++-------- .../ShadowSuggestionController.java | 61 ++++++++ .../SuggestionControllerMixinTest.java | 26 ++-- 4 files changed, 243 insertions(+), 82 deletions(-) create mode 100644 src/com/android/settings/dashboard/suggestions/SuggestionController.java create mode 100644 tests/robotests/src/com/android/settings/dashboard/suggestions/ShadowSuggestionController.java diff --git a/src/com/android/settings/dashboard/suggestions/SuggestionController.java b/src/com/android/settings/dashboard/suggestions/SuggestionController.java new file mode 100644 index 00000000000..ac20433bc69 --- /dev/null +++ b/src/com/android/settings/dashboard/suggestions/SuggestionController.java @@ -0,0 +1,146 @@ +/* + * 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.dashboard.suggestions; + +import android.content.ComponentName; +import android.content.Context; +import android.content.Intent; +import android.content.ServiceConnection; +import android.os.IBinder; +import android.os.RemoteException; +import android.service.settings.suggestions.ISuggestionService; +import android.service.settings.suggestions.Suggestion; +import android.support.annotation.Nullable; +import android.support.annotation.WorkerThread; +import android.util.Log; + +import java.util.List; + +/** + * A controller class to access suggestion data. + */ +public class SuggestionController { + + /** + * Callback interface when service is connected/disconnected. + */ + public interface ServiceConnectionListener { + /** + * Called when service is connected. + */ + void onServiceConnected(); + + /** + * Called when service is disconnected. + */ + void onServiceDisconnected(); + } + + private static final String TAG = "SuggestionController"; + private static final boolean DEBUG = false; + + private final Context mContext; + private final Intent mServiceIntent; + + private ServiceConnection mServiceConnection; + private ISuggestionService mRemoteService; + private ServiceConnectionListener mConnectionListener; + + /** + * Create a new controller instance. + * + * @param context caller context + * @param service The component name for service. + * @param listener listener to receive service connected/disconnected event. + */ + public SuggestionController(Context context, ComponentName service, + ServiceConnectionListener listener) { + mContext = context.getApplicationContext(); + mConnectionListener = listener; + mServiceIntent = new Intent().setComponent(service); + mServiceConnection = createServiceConnection(); + } + + /** + * Start the controller. + */ + public void start() { + mContext.bindServiceAsUser(mServiceIntent, mServiceConnection, Context.BIND_AUTO_CREATE, + android.os.Process.myUserHandle()); + } + + /** + * Stop the controller. + */ + public void stop() { + if (mRemoteService != null) { + mRemoteService = null; + mContext.unbindService(mServiceConnection); + } + } + + /** + * Get setting suggestions. + */ + @Nullable + @WorkerThread + public List getSuggestions() { + if (!isReady()) { + return null; + } + try { + return mRemoteService.getSuggestions(); + } catch (RemoteException e) { + Log.w(TAG, "Error when calling getSuggestion()", e); + return null; + } + } + + /** + * Whether or not the manager is ready + */ + private boolean isReady() { + return mRemoteService != null; + } + + /** + * Create a new {@link ServiceConnection} object to handle service connect/disconnect event. + */ + private ServiceConnection createServiceConnection() { + return new ServiceConnection() { + + @Override + public void onServiceConnected(ComponentName name, IBinder service) { + if (DEBUG) { + Log.d(TAG, "Service is connected"); + } + mRemoteService = ISuggestionService.Stub.asInterface(service); + if (mConnectionListener != null) { + mConnectionListener.onServiceConnected(); + } + } + + @Override + public void onServiceDisconnected(ComponentName name) { + if (mConnectionListener != null) { + mRemoteService = null; + mConnectionListener.onServiceDisconnected(); + } + } + }; + } +} diff --git a/src/com/android/settings/dashboard/suggestions/SuggestionControllerMixin.java b/src/com/android/settings/dashboard/suggestions/SuggestionControllerMixin.java index f58946dfa1c..6f5c82eddff 100644 --- a/src/com/android/settings/dashboard/suggestions/SuggestionControllerMixin.java +++ b/src/com/android/settings/dashboard/suggestions/SuggestionControllerMixin.java @@ -16,14 +16,8 @@ package com.android.settings.dashboard.suggestions; -import android.annotation.Nullable; import android.content.ComponentName; import android.content.Context; -import android.content.Intent; -import android.content.ServiceConnection; -import android.os.IBinder; -import android.os.RemoteException; -import android.service.settings.suggestions.ISuggestionService; import android.service.settings.suggestions.Suggestion; import android.support.annotation.VisibleForTesting; import android.util.FeatureFlagUtils; @@ -39,7 +33,8 @@ import java.util.List; /** * Manages IPC communication to SettingsIntelligence for suggestion related services. */ -public class SuggestionControllerMixin implements LifecycleObserver, OnStart, OnStop { +public class SuggestionControllerMixin implements SuggestionController.ServiceConnectionListener, + LifecycleObserver, OnStart, OnStop { @VisibleForTesting static final String FEATURE_FLAG = "new_settings_suggestion"; @@ -47,10 +42,7 @@ public class SuggestionControllerMixin implements LifecycleObserver, OnStart, On private static final boolean DEBUG = false; private final Context mContext; - private final Intent mServiceIntent; - private final ServiceConnection mServiceConnection; - - private ISuggestionService mRemoteService; + private final SuggestionController mSuggestionController; public static boolean isEnabled() { return FeatureFlagUtils.isEnabled(FEATURE_FLAG); @@ -58,11 +50,11 @@ public class SuggestionControllerMixin implements LifecycleObserver, OnStart, On public SuggestionControllerMixin(Context context, Lifecycle lifecycle) { mContext = context.getApplicationContext(); - mServiceIntent = new Intent().setComponent( + mSuggestionController = new SuggestionController(context, new ComponentName( "com.android.settings.intelligence", - "com.android.settings.intelligence.suggestions.SuggestionService")); - mServiceConnection = createServiceConnection(); + "com.android.settings.intelligence.suggestions.SuggestionService"), + this /* serviceConnectionListener */); if (lifecycle != null) { lifecycle.addObserver(this); } @@ -74,73 +66,27 @@ public class SuggestionControllerMixin implements LifecycleObserver, OnStart, On Log.w(TAG, "Feature not enabled, skipping"); return; } - mContext.bindServiceAsUser(mServiceIntent, mServiceConnection, Context.BIND_AUTO_CREATE, - android.os.Process.myUserHandle()); + mSuggestionController.start(); } @Override public void onStop() { - if (mRemoteService != null) { - mRemoteService = null; - mContext.unbindService(mServiceConnection); - } + mSuggestionController.stop(); } - /** - * Get setting suggestions. - */ - @Nullable - public List getSuggestions() { - if (!isReady()) { - return null; - } - try { - return mRemoteService.getSuggestions(); - } catch (RemoteException e) { - Log.w(TAG, "Error when calling getSuggestion()", e); - return null; - } - } - - /** - * Whether or not the manager is ready - */ - private boolean isReady() { - return mRemoteService != null; - } - - @VisibleForTesting - void onServiceConnected() { + @Override + public void onServiceConnected() { // TODO: Call API to get data from a loader instead of in current thread. - final List data = getSuggestions(); - Log.d(TAG, "data size " + (data == null ? 0 : data.size())); + final List data = mSuggestionController.getSuggestions(); + if (DEBUG) { + Log.d(TAG, "data size " + (data == null ? 0 : data.size())); + } } - private void onServiceDisconnected() { - + @Override + public void onServiceDisconnected() { + if (DEBUG) { + Log.d(TAG, "SuggestionService disconnected"); + } } - - /** - * Create a new {@link ServiceConnection} object to handle service connect/disconnect event. - */ - private ServiceConnection createServiceConnection() { - return new ServiceConnection() { - - @Override - public void onServiceConnected(ComponentName name, IBinder service) { - if (DEBUG) { - Log.d(TAG, "Service is connected"); - } - mRemoteService = ISuggestionService.Stub.asInterface(service); - SuggestionControllerMixin.this.onServiceConnected(); - } - - @Override - public void onServiceDisconnected(ComponentName name) { - mRemoteService = null; - SuggestionControllerMixin.this.onServiceDisconnected(); - } - }; - } - } diff --git a/tests/robotests/src/com/android/settings/dashboard/suggestions/ShadowSuggestionController.java b/tests/robotests/src/com/android/settings/dashboard/suggestions/ShadowSuggestionController.java new file mode 100644 index 00000000000..b720f83a210 --- /dev/null +++ b/tests/robotests/src/com/android/settings/dashboard/suggestions/ShadowSuggestionController.java @@ -0,0 +1,61 @@ +/* + * 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.dashboard.suggestions; + +import android.service.settings.suggestions.Suggestion; + +import org.robolectric.annotation.Implementation; +import org.robolectric.annotation.Implements; + +import java.util.List; + +@Implements(SuggestionController.class) +public class ShadowSuggestionController { + + public static boolean sStartCalled; + public static boolean sStopCalled; + public static boolean sGetSuggestionCalled; + + public static List sSuggestions; + + public static void reset() { + sStartCalled = false; + sStopCalled = false; + sGetSuggestionCalled = false; + sSuggestions = null; + } + + @Implementation + public void start() { + sStartCalled = true; + } + + @Implementation + public void stop() { + sStopCalled = true; + } + + public static void setSuggestion(List suggestions) { + sSuggestions = suggestions; + } + + @Implementation + public List getSuggestions() { + sGetSuggestionCalled = true; + return sSuggestions; + } +} diff --git a/tests/robotests/src/com/android/settings/dashboard/suggestions/SuggestionControllerMixinTest.java b/tests/robotests/src/com/android/settings/dashboard/suggestions/SuggestionControllerMixinTest.java index ac2026c0cc4..e1184783423 100644 --- a/tests/robotests/src/com/android/settings/dashboard/suggestions/SuggestionControllerMixinTest.java +++ b/tests/robotests/src/com/android/settings/dashboard/suggestions/SuggestionControllerMixinTest.java @@ -17,11 +17,9 @@ package com.android.settings.dashboard.suggestions; import static com.google.common.truth.Truth.assertThat; -import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; import android.content.Context; -import android.service.settings.suggestions.ISuggestionService; import android.util.FeatureFlagUtils; import com.android.settings.TestConfig; @@ -36,32 +34,32 @@ import org.junit.runner.RunWith; import org.mockito.Mock; import org.mockito.MockitoAnnotations; import org.robolectric.annotation.Config; -import org.robolectric.util.ReflectionHelpers; @RunWith(SettingsRobolectricTestRunner.class) @Config(manifest = TestConfig.MANIFEST_PATH, sdk = TestConfig.SDK_VERSION, shadows = { - SettingsShadowSystemProperties.class + SettingsShadowSystemProperties.class, + ShadowSuggestionController.class }) public class SuggestionControllerMixinTest { @Mock private Context mContext; - @Mock - private ISuggestionService mRemoteService; private Lifecycle mLifecycle; private SuggestionControllerMixin mMixin; - @Before public void setUp() { MockitoAnnotations.initMocks(this); mLifecycle = new Lifecycle(); when(mContext.getApplicationContext()).thenReturn(mContext); + SettingsShadowSystemProperties.set( + FeatureFlagUtils.FFLAG_PREFIX + SuggestionControllerMixin.FEATURE_FLAG, "true"); } @After public void tearDown() { + ShadowSuggestionController.reset(); SettingsShadowSystemProperties.clear(); } @@ -79,13 +77,23 @@ public class SuggestionControllerMixinTest { assertThat(SuggestionControllerMixin.isEnabled()).isFalse(); } + @Test + public void goThroughLifecycle_onStartStop_shouldStartStopService() { + mMixin = new SuggestionControllerMixin(mContext, mLifecycle); + + mLifecycle.onStart(); + assertThat(ShadowSuggestionController.sStartCalled).isTrue(); + + mLifecycle.onStop(); + assertThat(ShadowSuggestionController.sStopCalled).isTrue(); + } + @Test public void onServiceConnected_shouldGetSuggestion() { mMixin = new SuggestionControllerMixin(mContext, mLifecycle); - ReflectionHelpers.setField(mMixin, "mRemoteService", mRemoteService); mMixin.onServiceConnected(); - verify(mRemoteService).getSuggestions(); + assertThat(ShadowSuggestionController.sGetSuggestionCalled).isTrue(); } }