From adfec5563e2e7f696a24e78a728bef5d22102b55 Mon Sep 17 00:00:00 2001 From: Anton Philippov Date: Wed, 25 Jan 2017 20:37:36 +0000 Subject: [PATCH] Add a screen to show OEM backup settings. Moves the backup settings logic to BackupSettingsHelper and BackupSettingsActivity: - If the manufacturer provides the intent and the label for their backup settings in the config.xml, a new intermediate fragment is shown for Backup settings to let the user pick either standard backup settings or OEM provided backup settings. - If config.xml doesn't contain the intent, BackupSettingsActivity is used as a trampoline activity to launch backup settings provided by the backup transport of the default backup settings activity, i.e. PrivacySettingsActivity. Bug: 34700410 Bug: 33655074 Bug: 33654991 Test: make RunSettingsRoboTests Change-Id: I78e340fbf926b2a9dc2c4e3942f9337c3c7a933c --- AndroidManifest.xml | 23 +- res/values/config.xml | 5 +- res/xml/backup_settings.xml | 30 ++ .../settings/BackupSettingsActivity.java | 72 ---- .../android/settings/SettingsActivity.java | 25 +- .../backup/BackupSettingsActivity.java | 56 +++ .../backup/BackupSettingsFragment.java | 90 ++++ .../settings/backup/BackupSettingsHelper.java | 237 +++++++++++ .../BackupSettingsPreferenceController.java | 72 ++++ .../search/SearchIndexableResources.java | 2 + .../backup/BackupSettingsHelperTest.java | 388 ++++++++++++++++++ ...ackupSettingsPreferenceControllerTest.java | 132 ++++++ 12 files changed, 1017 insertions(+), 115 deletions(-) create mode 100644 res/xml/backup_settings.xml delete mode 100644 src/com/android/settings/BackupSettingsActivity.java create mode 100644 src/com/android/settings/backup/BackupSettingsActivity.java create mode 100644 src/com/android/settings/backup/BackupSettingsFragment.java create mode 100644 src/com/android/settings/backup/BackupSettingsHelper.java create mode 100644 src/com/android/settings/backup/BackupSettingsPreferenceController.java create mode 100644 tests/robotests/src/com/android/settings/backup/BackupSettingsHelperTest.java create mode 100644 tests/robotests/src/com/android/settings/backup/BackupSettingsPreferenceControllerTest.java diff --git a/AndroidManifest.xml b/AndroidManifest.xml index 0de7a4ef0c1..6bd09e4f712 100644 --- a/AndroidManifest.xml +++ b/AndroidManifest.xml @@ -1373,11 +1373,6 @@ - - - - - @@ -3268,21 +3262,8 @@ android:value="true" /> - - - - - - - - - + android:targetActivity=".backup.BackupSettingsActivity"> diff --git a/res/values/config.xml b/res/values/config.xml index 75d8697b9d4..fae38fc8612 100755 --- a/res/values/config.xml +++ b/res/values/config.xml @@ -45,9 +45,12 @@ com.android.settings com.android.settings.Settings$WallpaperSettingsActivity - + + + + diff --git a/res/xml/backup_settings.xml b/res/xml/backup_settings.xml new file mode 100644 index 00000000000..30792bc8a15 --- /dev/null +++ b/res/xml/backup_settings.xml @@ -0,0 +1,30 @@ + + + + + + + + + + + + diff --git a/src/com/android/settings/BackupSettingsActivity.java b/src/com/android/settings/BackupSettingsActivity.java deleted file mode 100644 index a4cc4b76032..00000000000 --- a/src/com/android/settings/BackupSettingsActivity.java +++ /dev/null @@ -1,72 +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; - -import android.app.Activity; -import android.app.backup.BackupManager; -import android.app.backup.IBackupManager; -import android.content.Context; -import android.content.Intent; -import android.os.Bundle; -import android.os.ServiceManager; -import android.os.UserHandle; -import android.text.TextUtils; -import android.util.Log; - -import com.android.settings.R; - -import java.net.URISyntaxException; - -/** - * A trampoline activity used to launch the configured Backup activity. - * This activity used the theme NoDisplay to minimize the flicker that might be seen for the launch- - * finsih transition. - */ -public class BackupSettingsActivity extends Activity { - private static final String TAG = "BackupSettingsActivity"; - - @Override - public void onCreate(Bundle savedInstanceState) { - super.onCreate(savedInstanceState); - String backup = getResources().getString(R.string.config_backup_settings_intent); - if (!TextUtils.isEmpty(backup)) { - try { - Intent intent = Intent.parseUri(backup, 0); - if (intent.resolveActivity(getPackageManager()) != null) { - // use startActivityForResult to let the activity check the caller signature - IBackupManager bmgr = IBackupManager.Stub.asInterface( - ServiceManager.getService(Context.BACKUP_SERVICE)); - boolean backupOkay; - try { - backupOkay = bmgr.isBackupServiceActive(UserHandle.myUserId()); - } catch (Exception e) { - // things go wrong talking to the backup system => ignore and - // pass the default 'false' as the "backup is a thing?" state. - backupOkay = false; - } - intent.putExtra(BackupManager.EXTRA_BACKUP_SERVICES_AVAILABLE, backupOkay); - startActivityForResult(intent, -1); - } else { - Log.e(TAG, "Backup component not found!"); - } - } catch (URISyntaxException e) { - Log.e(TAG, "Invalid backup component URI!", e); - } - } - finish(); - } -} \ No newline at end of file diff --git a/src/com/android/settings/SettingsActivity.java b/src/com/android/settings/SettingsActivity.java index c01e4c40b1d..c2060ce0eb5 100644 --- a/src/com/android/settings/SettingsActivity.java +++ b/src/com/android/settings/SettingsActivity.java @@ -54,6 +54,7 @@ import android.widget.SearchView; import com.android.internal.util.ArrayUtils; import com.android.settings.Settings.WifiSettingsActivity; +import com.android.settings.backup.BackupSettingsActivity; import com.android.settings.core.gateway.SettingsGateway; import com.android.settings.core.instrumentation.SharedPreferencesLogger; import com.android.settings.dashboard.DashboardContainerFragment; @@ -965,29 +966,11 @@ public class SettingsActivity extends SettingsDrawerActivity } } - String backupIntent = getResources().getString(R.string.config_backup_settings_intent); - boolean useDefaultBackup = TextUtils.isEmpty(backupIntent); + // Enable/disable backup settings depending on whether the user is admin. setTileEnabled(new ComponentName(packageName, - Settings.PrivacySettingsActivity.class.getName()), useDefaultBackup, isAdmin); + BackupSettingsActivity.class.getName()), true, isAdmin); setTileEnabled(new ComponentName(packageName, - "com.android.settings.PrivacyDashboardAlias"), - useDefaultBackup, isAdmin); - - boolean hasBackupActivity = false; - if (!useDefaultBackup) { - try { - Intent intent = Intent.parseUri(backupIntent, 0); - hasBackupActivity = !getPackageManager().queryIntentActivities(intent, 0).isEmpty(); - } catch (URISyntaxException e) { - Log.e(LOG_TAG, "Invalid backup intent URI!", e); - } - } - - // Enable/disable BackupSettingsActivity and its alias. - setTileEnabled(new ComponentName(packageName, - BackupSettingsActivity.class.getName()), hasBackupActivity, isAdmin); - setTileEnabled(new ComponentName(packageName, - "com.android.settings.BackupResetDashboardAlias"), hasBackupActivity, isAdmin); + "com.android.settings.BackupResetDashboardAlias"), true, isAdmin); setTileEnabled(new ComponentName(packageName, Settings.EnterprisePrivacySettingsActivity.class.getName()), diff --git a/src/com/android/settings/backup/BackupSettingsActivity.java b/src/com/android/settings/backup/BackupSettingsActivity.java new file mode 100644 index 00000000000..b19538425ef --- /dev/null +++ b/src/com/android/settings/backup/BackupSettingsActivity.java @@ -0,0 +1,56 @@ +/* + * Copyright (C) 2017 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License + */ + +package com.android.settings.backup; + +import android.app.Activity; +import android.os.Bundle; +import android.util.Log; + + +/** + * The activity used to launch the configured Backup activity or the preference screen + * if the manufacturer provided their backup settings. + */ +public class BackupSettingsActivity extends Activity { + private static final String TAG = "BackupSettingsActivity"; + + @Override + public void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + + BackupSettingsHelper backupHelper = new BackupSettingsHelper(this); + + if (!backupHelper.isBackupProvidedByManufacturer()) { + // If manufacturer specific backup settings are not provided then launch + // the backup settings provided by backup transport or the default one directly. + if (Log.isLoggable(TAG, Log.DEBUG)) { + Log.d(TAG, + "No manufacturer settings found, launching the backup settings directly"); + } + // use startActivityForResult to let the activity check the caller signature + startActivityForResult(backupHelper.getIntentForBackupSettings(), 1); + finish(); + } else { + if (Log.isLoggable(TAG, Log.DEBUG)) { + Log.d(TAG, "Manufacturer provided backup settings, showing the preference screen"); + } + getFragmentManager().beginTransaction() + .replace(android.R.id.content, new BackupSettingsFragment()) + .commit(); + } + } +} \ No newline at end of file diff --git a/src/com/android/settings/backup/BackupSettingsFragment.java b/src/com/android/settings/backup/BackupSettingsFragment.java new file mode 100644 index 00000000000..dcc160828a5 --- /dev/null +++ b/src/com/android/settings/backup/BackupSettingsFragment.java @@ -0,0 +1,90 @@ +/* + * 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.backup; + +import android.content.Context; +import android.os.Bundle; +import android.provider.SearchIndexableResource; +import android.support.v7.preference.Preference; +import android.support.v7.preference.PreferenceScreen; +import android.util.Log; + + +import com.android.internal.logging.nano.MetricsProto.MetricsEvent; +import com.android.settings.R; +import com.android.settings.core.PreferenceController; +import com.android.settings.dashboard.DashboardFragment; +import com.android.settings.search.BaseSearchIndexProvider; +import com.android.settings.search.Indexable; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; + +/** + * Fragment showing the items to launch different backup settings screens. + */ +public class BackupSettingsFragment extends DashboardFragment { + private static final String TAG = "BackupSettings"; + + @Override + public void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + } + + /** + * Get the tag string for logging. + */ + @Override + protected String getLogTag() { + return TAG; + } + + /** + * Get the res id for static preference xml for this fragment. + */ + @Override + protected int getPreferenceScreenResId() { + return R.xml.backup_settings; + } + + /** + * Get a list of {@link PreferenceController} for this fragment. + */ + @Override + protected List getPreferenceControllers(Context context) { + final List controllers = new ArrayList<>(); + controllers.add(new BackupSettingsPreferenceController(context)); + return controllers; + } + + public static final Indexable.SearchIndexProvider SEARCH_INDEX_DATA_PROVIDER = + new BaseSearchIndexProvider() { + @Override + public List getXmlResourcesToIndex(Context context, + boolean enabled) { + final SearchIndexableResource sir = new SearchIndexableResource(context); + sir.xmlResId = R.xml.backup_settings; + return Arrays.asList(sir); + } + }; + + @Override + public int getMetricsCategory() { + return MetricsEvent.BACKUP_SETTINGS; + } +} diff --git a/src/com/android/settings/backup/BackupSettingsHelper.java b/src/com/android/settings/backup/BackupSettingsHelper.java new file mode 100644 index 00000000000..b0d6cf88678 --- /dev/null +++ b/src/com/android/settings/backup/BackupSettingsHelper.java @@ -0,0 +1,237 @@ +/* + * 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.backup; + + +import android.app.backup.BackupManager; +import android.app.backup.IBackupManager; +import android.content.Context; +import android.content.Intent; +import android.os.RemoteException; +import android.os.ServiceManager; +import android.os.UserHandle; +import android.util.Log; + +import android.support.annotation.VisibleForTesting; + +import com.android.settings.R; +import com.android.settings.Settings.PrivacySettingsActivity; +import com.android.settingslib.drawer.SettingsDrawerActivity; +import java.net.URISyntaxException; + +/** + * Helper class for {@link BackupSettingsActivity} that interacts with {@link IBackupManager}. + */ +public class BackupSettingsHelper { + private static final String TAG = "BackupSettingsHelper"; + + private IBackupManager mBackupManager = IBackupManager.Stub.asInterface( + ServiceManager.getService(Context.BACKUP_SERVICE)); + + private Context mContext; + + public BackupSettingsHelper(Context context) { + mContext = context; + } + + /** + * Returns an intent to launch backup settings from backup transport if the intent was provided + * by the transport. Otherwise returns the intent to launch the default backup settings screen. + * + * @return Intent for launching backup settings + */ + public Intent getIntentForBackupSettings() { + Intent intent; + if (isIntentProvidedByTransport()) { + intent = getIntentForBackupSettingsFromTransport(); + } else { + Log.e(TAG, "Backup transport has not provided an intent" + + " or the component for the intent is not found!"); + intent = getIntentForDefaultBackupSettings(); + } + return intent; + } + + /** + * Returns a label for the settings item that will point to the backup settings provided by + * the transport. If no label was provided by transport, returns the default string. + * + * @return Label for the backup settings item. + */ + public String getLabelForBackupSettings() { + String label = getLabelFromBackupTransport(); + if (label == null || label.isEmpty()) { + label = mContext.getString(R.string.privacy_settings_title); + } + return label; + } + + /** + * Returns a summary string for the settings item that will point to the backup settings + * provided by the transport. If no summary was provided by transport, returns the default + * string. + * + * @return Summary for the backup settings item. + */ + public String getSummaryForBackupSettings() { + String summary = getSummaryFromBackupTransport(); + if (summary == null) { + summary = mContext.getString(R.string.backup_configure_account_default_summary); + } + return summary; + } + + + /** + * Checks if the manufacturer provided an intent to launch its backup settings screen + * in the config file. + */ + public boolean isBackupProvidedByManufacturer() { + if (Log.isLoggable(TAG, Log.DEBUG)) { + Log.d(TAG, "Checking if intent provided by manufacturer"); + } + String intentString = + mContext.getResources().getString(R.string.config_backup_settings_intent); + + return intentString != null && !intentString.isEmpty(); + } + + /** + * Returns the label for the backup settings item provided by the manufacturer. + */ + public String getLabelProvidedByManufacturer() { + return mContext.getResources().getString(R.string.config_backup_settings_label); + } + + /** + * Returns the intent to the backup settings screen provided by the manufacturer. + */ + public Intent getIntentProvidedByManufacturer() { + if (Log.isLoggable(TAG, Log.DEBUG)) { + Log.d(TAG, "Getting a backup settings intent provided by manufacturer"); + } + String intentString = + mContext.getResources().getString(R.string.config_backup_settings_intent); + if (intentString != null && !intentString.isEmpty()) { + try { + return Intent.parseUri(intentString, 0); + } catch (URISyntaxException e) { + Log.e(TAG, "Invalid intent provided by the manufacturer.", e); + } + } + return null; + } + + /** + * Gets the intent from Backup transport and adds the extra depending on whether the user has + * rights to see backup settings. + * + * @return Intent to launch Backup settings provided by the Backup transport. + */ + @VisibleForTesting + Intent getIntentForBackupSettingsFromTransport() { + Intent intent = getIntentFromBackupTransport(); + if (intent != null) { + intent.putExtra(BackupManager.EXTRA_BACKUP_SERVICES_AVAILABLE, isBackupServiceActive()); + } + return intent; + } + + private Intent getIntentForDefaultBackupSettings() { + // Extra needed by {@link SettingsDrawerActivity} to show the back button navigation. + return new Intent(mContext, PrivacySettingsActivity.class) + .putExtra(SettingsDrawerActivity.EXTRA_SHOW_MENU, true); + } + + /** + * Checks if the transport provided the intent to launch the backup settings and if that + * intent resolves to an activity. + */ + @VisibleForTesting + boolean isIntentProvidedByTransport() { + Intent intent = getIntentFromBackupTransport(); + return intent != null && intent.resolveActivity(mContext.getPackageManager()) != null; + } + + /** + * Gets an intent to launch the backup settings from the current transport using + * {@link com.android.internal.backup.IBackupTransport#dataManagementIntent()} API. + * + * @return intent provided by transport or null if no intent was provided. + */ + private Intent getIntentFromBackupTransport() { + try { + Intent intent = + mBackupManager.getDataManagementIntent(mBackupManager.getCurrentTransport()); + if (Log.isLoggable(TAG, Log.DEBUG)) { + if (intent != null) { + Log.d(TAG, "Parsed intent from backup transport: " + intent.toString()); + } else { + Log.d(TAG, "Received a null intent from backup transport"); + } + } + return intent; + } catch (RemoteException e) { + Log.e(TAG, "Error getting data management intent", e); + } + return null; + } + + /** Checks if backup service is enabled for this user. */ + private boolean isBackupServiceActive() { + boolean backupOkay; + try { + backupOkay = mBackupManager.isBackupServiceActive(UserHandle.myUserId()); + } catch (Exception e) { + // things go wrong talking to the backup system => ignore and + // pass the default 'false' as the "backup is a thing?" state. + backupOkay = false; + } + return backupOkay; + } + + @VisibleForTesting + String getLabelFromBackupTransport() { + try { + String label = + mBackupManager.getDataManagementLabel(mBackupManager.getCurrentTransport()); + if (Log.isLoggable(TAG, Log.DEBUG)) { + Log.d(TAG, "Received the backup settings label from backup transport: " + label); + } + return label; + } catch (RemoteException e) { + Log.e(TAG, "Error getting data management label", e); + } + return null; + } + + @VisibleForTesting + String getSummaryFromBackupTransport() { + try { + String summary = + mBackupManager.getDestinationString(mBackupManager.getCurrentTransport()); + if (Log.isLoggable(TAG, Log.DEBUG)) { + Log.d(TAG, + "Received the backup settings summary from backup transport: " + summary); + } + return summary; + } catch (RemoteException e) { + Log.e(TAG, "Error getting data management summary", e); + } + return null; + } +} diff --git a/src/com/android/settings/backup/BackupSettingsPreferenceController.java b/src/com/android/settings/backup/BackupSettingsPreferenceController.java new file mode 100644 index 00000000000..2c4605abb25 --- /dev/null +++ b/src/com/android/settings/backup/BackupSettingsPreferenceController.java @@ -0,0 +1,72 @@ +/* + * 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.backup; + + +import android.content.Context; +import android.content.Intent; +import android.support.v7.preference.Preference; +import android.support.v7.preference.PreferenceScreen; + +import com.android.settings.core.PreferenceController; + +public class BackupSettingsPreferenceController extends PreferenceController { + private static final String BACKUP_SETTINGS = "backup_settings"; + private static final String MANUFACTURER_SETTINGS = "manufacturer_backup"; + private Intent mBackupSettingsIntent; + private String mBackupSettingsTitle; + private String mBackupSettingsSummary; + private Intent mManufacturerIntent; + private String mManufacturerLabel; + + public BackupSettingsPreferenceController(Context context) { + super(context); + BackupSettingsHelper settingsHelper = new BackupSettingsHelper(context); + mBackupSettingsIntent = settingsHelper.getIntentForBackupSettings(); + mBackupSettingsTitle = settingsHelper.getLabelForBackupSettings(); + mBackupSettingsSummary = settingsHelper.getSummaryForBackupSettings(); + mManufacturerIntent = settingsHelper.getIntentProvidedByManufacturer(); + mManufacturerLabel = settingsHelper.getLabelProvidedByManufacturer(); + } + + @Override + public void displayPreference(PreferenceScreen screen) { + Preference backupSettings = screen.findPreference(BACKUP_SETTINGS); + Preference manufacturerSettings = screen.findPreference(MANUFACTURER_SETTINGS); + backupSettings.setIntent(mBackupSettingsIntent); + backupSettings.setTitle(mBackupSettingsTitle); + backupSettings.setSummary(mBackupSettingsSummary); + manufacturerSettings.setIntent(mManufacturerIntent); + manufacturerSettings.setTitle(mManufacturerLabel); + } + + /** + * Returns true if preference is available (should be displayed) + */ + @Override + public boolean isAvailable() { + return true; + } + + /** + * Returns the key for this preference. + */ + @Override + public String getPreferenceKey() { + return null; + } +} diff --git a/src/com/android/settings/search/SearchIndexableResources.java b/src/com/android/settings/search/SearchIndexableResources.java index aa3c2576200..4a734692d35 100644 --- a/src/com/android/settings/search/SearchIndexableResources.java +++ b/src/com/android/settings/search/SearchIndexableResources.java @@ -37,6 +37,7 @@ import com.android.settings.accounts.UserAndAccountDashboardFragment; import com.android.settings.applications.AdvancedAppSettings; import com.android.settings.applications.AppAndNotificationDashboardFragment; import com.android.settings.applications.SpecialAccessSettings; +import com.android.settings.backup.BackupSettingsFragment; import com.android.settings.bluetooth.BluetoothSettings; import com.android.settings.connecteddevice.ConnectedDeviceDashboardFragment; import com.android.settings.datausage.DataUsageMeteredSettings; @@ -156,6 +157,7 @@ public final class SearchIndexableResources { NO_DATA_RES_ID, R.drawable.ic_settings_language); addIndex(PhysicalKeyboardFragment.class, NO_DATA_RES_ID, R.drawable.ic_settings_language); addIndex(PrivacySettings.class, NO_DATA_RES_ID, R.drawable.ic_settings_backup); + addIndex(BackupSettingsFragment.class, NO_DATA_RES_ID, R.drawable.ic_settings_backup); addIndex(DateTimeSettings.class, NO_DATA_RES_ID, R.drawable.ic_settings_date_time); addIndex(AccessibilitySettings.class, NO_DATA_RES_ID, R.drawable.ic_settings_accessibility); addIndex(PrintSettingsFragment.class, NO_DATA_RES_ID, R.drawable.ic_settings_print); diff --git a/tests/robotests/src/com/android/settings/backup/BackupSettingsHelperTest.java b/tests/robotests/src/com/android/settings/backup/BackupSettingsHelperTest.java new file mode 100644 index 00000000000..02051244ca3 --- /dev/null +++ b/tests/robotests/src/com/android/settings/backup/BackupSettingsHelperTest.java @@ -0,0 +1,388 @@ +/* + * 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.backup; + +import android.app.backup.BackupManager; +import android.app.backup.IBackupManager; +import android.content.ComponentName; +import android.content.Context; +import android.content.Intent; +import android.content.pm.PackageManager; +import android.content.res.Resources; +import android.os.IBinder; +import android.os.RemoteException; + +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.Mock; +import org.mockito.MockitoAnnotations; +import org.robolectric.RuntimeEnvironment; +import org.robolectric.annotation.Config; +import org.robolectric.annotation.Implementation; +import org.robolectric.annotation.Implements; + +import static com.google.common.truth.Truth.assertThat; +import static org.mockito.Mockito.anyInt; +import static org.mockito.Mockito.anyString; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.spy; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.when; + +import com.android.settings.R; +import com.android.settings.SettingsRobolectricTestRunner; +import com.android.settings.TestConfig; +import com.android.settingslib.drawer.SettingsDrawerActivity; + +@RunWith(SettingsRobolectricTestRunner.class) +@Config(manifest = TestConfig.MANIFEST_PATH, sdk = TestConfig.SDK_VERSION, + shadows = {BackupSettingsHelperTest.ShadowBackupManagerStub.class}) +public class BackupSettingsHelperTest { + + private static final String DEFAULT_SETTINGS_CLASSNAME = + "com.android.settings.Settings$PrivacySettingsActivity"; + + private static final int DEFAULT_SUMMARY_RESOURCE = + R.string.backup_configure_account_default_summary; + + private static final int DEFAULT_LABEL_RESOURCE = + R.string.privacy_settings_title; + + private static final int MANUFACTURER_INTENT_RESOURCE = R.string.config_backup_settings_intent; + + private static final int MANUFACTURER_LABEL_RESOURCE = R.string.config_backup_settings_label; + + private Context mContext; + + private BackupSettingsHelper mBackupSettingsHelper; + + @Mock + private static IBackupManager mBackupManager; + + @Before + public void setUp() throws Exception { + MockitoAnnotations.initMocks(this); + mContext = spy(RuntimeEnvironment.application.getApplicationContext()); + when(mBackupManager.getCurrentTransport()).thenReturn("test_transport"); + mBackupSettingsHelper = new BackupSettingsHelper(mContext); + } + + @Test + public void testGetIntentFromBackupTransport() throws Exception { + Intent intent = new Intent(); + + when(mBackupManager.getDataManagementIntent(anyString())).thenReturn(intent); + + Intent backupIntent = mBackupSettingsHelper.getIntentForBackupSettingsFromTransport(); + + verify(mBackupManager).getDataManagementIntent(anyString()); + } + + @Test + public void testGetIntentFromBackupTransport_WithIntent() throws Exception { + Intent intent = mock(Intent.class); + + when(mBackupManager.getDataManagementIntent(anyString())).thenReturn(intent); + + Intent backupIntent = mBackupSettingsHelper.getIntentForBackupSettingsFromTransport(); + + assertThat(backupIntent).isEqualTo(intent); + } + + @Test + public void testGetIntentFromBackupTransport_WithNullIntent() throws Exception { + when(mBackupManager.getDataManagementIntent(anyString())).thenReturn(null); + + Intent backupIntent = mBackupSettingsHelper.getIntentForBackupSettingsFromTransport(); + + assertThat(backupIntent).isNull(); + } + + @Test + public void testGetIntentFromBackupTransport_RemoteException() throws Exception { + when(mBackupManager.getDataManagementIntent(anyString())).thenThrow(new RemoteException()); + + Intent backupIntent = mBackupSettingsHelper.getIntentForBackupSettingsFromTransport(); + + assertThat(backupIntent).isNull(); + } + + @Test + public void testGetIntentFromBackupTransport_BackupEnabled() throws Exception { + Intent intent = new Intent("test_intent"); + + when(mBackupManager.getDataManagementIntent(anyString())).thenReturn(intent); + when(mBackupManager.isBackupServiceActive(anyInt())).thenReturn(true); + + Intent backupIntent = mBackupSettingsHelper.getIntentForBackupSettingsFromTransport(); + + assertThat(backupIntent.getExtras().get(BackupManager.EXTRA_BACKUP_SERVICES_AVAILABLE)) + .isEqualTo(true); + } + + @Test + public void testGetIntentFromBackupTransport_BackupDisabled() throws Exception { + Intent intent = new Intent("test_intent"); + + when(mBackupManager.getDataManagementIntent(anyString())).thenReturn(intent); + when(mBackupManager.isBackupServiceActive(anyInt())).thenReturn(false); + + Intent backupIntent = mBackupSettingsHelper.getIntentForBackupSettingsFromTransport(); + + assertThat(backupIntent.getExtras().get(BackupManager.EXTRA_BACKUP_SERVICES_AVAILABLE)) + .isEqualTo(false); + } + + @Test + public void testGetIntentFromBackupTransport_BackupStatusException() throws Exception { + Intent intent = new Intent("test_intent"); + + when(mBackupManager.getDataManagementIntent(anyString())).thenReturn(intent); + when(mBackupManager.isBackupServiceActive(anyInt())).thenThrow(new RemoteException()); + + Intent backupIntent = mBackupSettingsHelper.getIntentForBackupSettingsFromTransport(); + + assertThat(backupIntent.getExtras().get(BackupManager.EXTRA_BACKUP_SERVICES_AVAILABLE)) + .isEqualTo(false); + } + + @Test + public void testIsIntentProvidedByTransport_WithNullIntent() throws Exception { + when(mBackupManager.getDataManagementIntent(anyString())).thenReturn(null); + + boolean isIntentProvided = mBackupSettingsHelper.isIntentProvidedByTransport(); + + assertThat(isIntentProvided).isFalse(); + } + + @Test + public void testIsIntentProvidedByTransport_WithInvalidIntent() throws Exception { + Intent intent = mock(Intent.class); + + when(mBackupManager.getDataManagementIntent(anyString())).thenReturn(intent); + + PackageManager packageManager = mock(PackageManager.class); + when(mContext.getPackageManager()).thenReturn(packageManager); + when(intent.resolveActivity(packageManager)).thenReturn(null); + + boolean isIntentProvided = mBackupSettingsHelper.isIntentProvidedByTransport(); + + assertThat(isIntentProvided).isFalse(); + } + + @Test + public void testIsIntentProvidedByTransport_WithIntent() throws Exception { + Intent intent = mock(Intent.class); + + when(mBackupManager.getDataManagementIntent(anyString())).thenReturn(intent); + + PackageManager packageManager = mock(PackageManager.class); + when(mContext.getPackageManager()).thenReturn(packageManager); + when(intent.resolveActivity(packageManager)).thenReturn(mock(ComponentName.class)); + + boolean isIntentProvided = mBackupSettingsHelper.isIntentProvidedByTransport(); + + assertThat(isIntentProvided).isTrue(); + } + + @Test + public void testGetSummaryFromBackupTransport() throws Exception { + String summary = "test_summary"; + + when(mBackupManager.getDestinationString(anyString())).thenReturn(summary); + + String backupSummary = mBackupSettingsHelper.getSummaryFromBackupTransport(); + + assertThat(backupSummary).isEqualTo(summary); + } + + @Test + public void testGetSummaryFromBackupTransport_RemoteException() throws Exception { + when(mBackupManager.getDestinationString(anyString())).thenThrow(new RemoteException()); + + String backupSummary = mBackupSettingsHelper.getSummaryFromBackupTransport(); + + assertThat(backupSummary).isNull(); + } + + @Test + public void testGetLabelBackupTransport() throws Exception { + String label = "test_label"; + + when(mBackupManager.getDataManagementLabel(anyString())).thenReturn(label); + + String backupLabel = mBackupSettingsHelper.getLabelFromBackupTransport(); + + assertThat(backupLabel).isEqualTo(label); + } + + @Test + public void testGetLabelBackupTransport_RemoteException() throws Exception { + when(mBackupManager.getDataManagementLabel(anyString())).thenThrow(new RemoteException()); + + String backupLabel = mBackupSettingsHelper.getLabelFromBackupTransport(); + + assertThat(backupLabel).isNull(); + } + + @Test + public void testGetIntentForBackupSettings_WithIntentFromTransport() throws Exception { + Intent intent = mock(Intent.class); + + when(mBackupManager.getDataManagementIntent(anyString())).thenReturn(intent); + + PackageManager packageManager = mock(PackageManager.class); + when(mContext.getPackageManager()).thenReturn(packageManager); + when(intent.resolveActivity(packageManager)).thenReturn(mock(ComponentName.class)); + + Intent backupIntent = mBackupSettingsHelper.getIntentForBackupSettings(); + + assertThat(backupIntent).isEqualTo(intent); + } + + @Test + public void testGetIntentForBackupSettings_WithoutIntentFromTransport() throws Exception { + when(mBackupManager.getDataManagementIntent(anyString())).thenReturn(null); + + Intent backupIntent = mBackupSettingsHelper.getIntentForBackupSettings(); + + assertThat(backupIntent.getComponent().getClassName()).isEqualTo( + DEFAULT_SETTINGS_CLASSNAME); + assertThat(backupIntent.getExtras().getBoolean( + SettingsDrawerActivity.EXTRA_SHOW_MENU)).isTrue(); + } + + @Test + public void testGetLabelForBackupSettings_WithLabelFromTransport() throws Exception { + String label = "test_label"; + + when(mBackupManager.getDataManagementLabel(anyString())).thenReturn(label); + + String backupLabel = mBackupSettingsHelper.getLabelForBackupSettings(); + + assertThat(backupLabel).isEqualTo(label); + } + + @Test + public void testGetLabelForBackupSettings_WithEmptyLabelFromTransport() throws Exception { + String label = ""; + + when(mBackupManager.getDataManagementLabel(anyString())).thenReturn(label); + + String backupLabel = mBackupSettingsHelper.getLabelForBackupSettings(); + + assertThat(backupLabel).isEqualTo(mContext.getString(DEFAULT_LABEL_RESOURCE)); + } + + @Test + public void testGetLabelForBackupSettings_WithoutLabelFromTransport() throws Exception { + when(mBackupManager.getDataManagementLabel(anyString())).thenReturn(null); + + String backupLabel = mBackupSettingsHelper.getLabelForBackupSettings(); + + assertThat(backupLabel).isEqualTo(mContext.getString(DEFAULT_LABEL_RESOURCE)); + } + + @Test + public void testGetSummaryForBackupSettings_WithSummaryFromTransport() throws Exception { + String summary = "test_summary"; + + when(mBackupManager.getDestinationString(anyString())).thenReturn(summary); + + String backupSummary = mBackupSettingsHelper.getSummaryForBackupSettings(); + + assertThat(backupSummary).isEqualTo(summary); + } + + @Test + public void testGetSummaryForBackupSettings_WithoutSummaryFromTransport() throws Exception { + when(mBackupManager.getDestinationString(anyString())).thenReturn(null); + + String backupSummary = mBackupSettingsHelper.getSummaryForBackupSettings(); + + assertThat(backupSummary).isEqualTo(mContext.getString(DEFAULT_SUMMARY_RESOURCE)); + } + + @Test + public void testIsBackupProvidedByManufacturer_WithIntent() throws Exception { + String intent = "test_intent"; + + when(mContext.getApplicationContext()).thenReturn(mContext); + Resources spiedResources = spy(mContext.getResources()); + when(mContext.getResources()).thenReturn(spiedResources); + when(spiedResources.getString(MANUFACTURER_INTENT_RESOURCE)).thenReturn(intent); + mBackupSettingsHelper = new BackupSettingsHelper(mContext); + + boolean hasManufacturerIntent = mBackupSettingsHelper.isBackupProvidedByManufacturer(); + + assertThat(hasManufacturerIntent).isTrue(); + } + + @Test + public void testIsBackupProvidedByManufacturer_WithoutIntent() throws Exception { + String intent = ""; + + when(mContext.getApplicationContext()).thenReturn(mContext); + Resources spiedResources = spy(mContext.getResources()); + when(mContext.getResources()).thenReturn(spiedResources); + when(spiedResources.getString(MANUFACTURER_INTENT_RESOURCE)).thenReturn(intent); + mBackupSettingsHelper = new BackupSettingsHelper(mContext); + + boolean hasManufacturerIntent = mBackupSettingsHelper.isBackupProvidedByManufacturer(); + + assertThat(hasManufacturerIntent).isFalse(); + } + + @Test + public void testGetLabelProvidedByManufacturer() throws Exception { + String label = "test_label"; + + when(mContext.getApplicationContext()).thenReturn(mContext); + Resources spiedResources = spy(mContext.getResources()); + when(mContext.getResources()).thenReturn(spiedResources); + when(spiedResources.getString(MANUFACTURER_LABEL_RESOURCE)).thenReturn(label); + mBackupSettingsHelper = new BackupSettingsHelper(mContext); + + String manufacturerLabel = mBackupSettingsHelper.getLabelProvidedByManufacturer(); + + assertThat(manufacturerLabel).isEqualTo(label); + } + + @Test + public void testGetIntentProvidedByManufacturer() throws Exception { + String intent = "test_intent"; + + when(mContext.getApplicationContext()).thenReturn(mContext); + Resources spiedResources = spy(mContext.getResources()); + when(mContext.getResources()).thenReturn(spiedResources); + when(spiedResources.getString(MANUFACTURER_INTENT_RESOURCE)).thenReturn(intent); + mBackupSettingsHelper = new BackupSettingsHelper(mContext); + + Intent manufacturerIntent = mBackupSettingsHelper.getIntentProvidedByManufacturer(); + + assertThat(manufacturerIntent).isNotNull(); + } + + @Implements(IBackupManager.Stub.class) + public static class ShadowBackupManagerStub { + @Implementation + public static IBackupManager asInterface(IBinder iBinder) { + return mBackupManager; + } + } +} diff --git a/tests/robotests/src/com/android/settings/backup/BackupSettingsPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/backup/BackupSettingsPreferenceControllerTest.java new file mode 100644 index 00000000000..7157862ef1b --- /dev/null +++ b/tests/robotests/src/com/android/settings/backup/BackupSettingsPreferenceControllerTest.java @@ -0,0 +1,132 @@ +/* + * 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.backup; + +import com.android.settings.SettingsRobolectricTestRunner; +import com.android.settings.TestConfig; + +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.Mock; +import org.mockito.MockitoAnnotations; +import org.robolectric.RuntimeEnvironment; +import org.robolectric.annotation.Config; +import org.robolectric.annotation.Implementation; +import org.robolectric.annotation.Implements; + +import static com.google.common.truth.Truth.assertThat; + +import static org.mockito.Mockito.spy; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.when; + +import android.content.Context; +import android.content.Intent; +import android.support.v7.preference.Preference; +import android.support.v7.preference.PreferenceScreen; + +@RunWith(SettingsRobolectricTestRunner.class) +@Config(manifest = TestConfig.MANIFEST_PATH, sdk = TestConfig.SDK_VERSION, + shadows = {BackupSettingsPreferenceControllerTest.ShadowBackupSettingsHelper.class}) +public class BackupSettingsPreferenceControllerTest { + private static final String BACKUP_SETTINGS = "backup_settings"; + private static final String MANUFACTURER_SETTINGS = "manufacturer_backup"; + + private Context mContext; + + @Mock + private BackupSettingsHelper mBackupHelper; + @Mock + private PreferenceScreen mScreen; + @Mock + private Preference mBackupPreference; + @Mock + private Preference mManufacturerPreference; + + @Mock + private static Intent mBackupIntent; + + private static String mBackupLabel = "Test Backup Label"; + private static String mBackupSummary = "Test Backup Summary"; + private static String mManufacturerLabel = "Test Manufacturer Label"; + + @Mock + private static Intent mManufacturerIntent; + + private BackupSettingsPreferenceController mController; + + @Before + public void setUp() throws Exception { + MockitoAnnotations.initMocks(this); + mContext = spy(RuntimeEnvironment.application.getApplicationContext()); + mController = new BackupSettingsPreferenceController(mContext); + } + + @Test + public void testDisplayPreference() { + when(mScreen.findPreference(BACKUP_SETTINGS)).thenReturn(mBackupPreference); + when(mScreen.findPreference(MANUFACTURER_SETTINGS)).thenReturn(mManufacturerPreference); + + mController.displayPreference(mScreen); + + verify(mBackupPreference).setIntent(mBackupIntent); + verify(mBackupPreference).setTitle(mBackupLabel); + verify(mBackupPreference).setSummary(mBackupSummary); + verify(mManufacturerPreference).setIntent(mManufacturerIntent); + verify(mManufacturerPreference).setTitle(mManufacturerLabel); + } + + @Test + public void testIsAvailable_shouldAlwaysReturnTrue() { + assertThat(mController.isAvailable()).isTrue(); + } + + @Test + public void getPreferenceKey_shouldReturnNull() { + assertThat(mController.getPreferenceKey()).isNull(); + } + + @Implements(BackupSettingsHelper.class) + public static class ShadowBackupSettingsHelper { + + @Implementation + public Intent getIntentForBackupSettings() { + return mBackupIntent; + } + + @Implementation + public String getLabelForBackupSettings() { + return mBackupLabel; + } + + @Implementation + public String getSummaryForBackupSettings() { + return mBackupSummary; + } + + @Implementation + public Intent getIntentProvidedByManufacturer() { + return mManufacturerIntent; + } + + @Implementation + public String getLabelProvidedByManufacturer() { + return mManufacturerLabel; + } + } +}