1 /* 2 * Copyright (C) 2017 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License 15 */ 16 17 package com.android.settings.backup; 18 19 20 import android.app.backup.BackupManager; 21 import android.app.backup.IBackupManager; 22 import android.content.Context; 23 import android.content.Intent; 24 import android.os.RemoteException; 25 import android.os.ServiceManager; 26 import android.os.UserHandle; 27 import android.util.Log; 28 29 import android.support.annotation.VisibleForTesting; 30 31 import com.android.settings.R; 32 import com.android.settings.Settings.PrivacySettingsActivity; 33 import com.android.settingslib.drawer.SettingsDrawerActivity; 34 import java.net.URISyntaxException; 35 36 /** 37 * Helper class for {@link BackupSettingsActivity} that interacts with {@link IBackupManager}. 38 */ 39 public class BackupSettingsHelper { 40 private static final String TAG = "BackupSettingsHelper"; 41 42 private IBackupManager mBackupManager = IBackupManager.Stub.asInterface( 43 ServiceManager.getService(Context.BACKUP_SERVICE)); 44 45 private Context mContext; 46 47 public BackupSettingsHelper(Context context) { 48 mContext = context; 49 } 50 51 /** 52 * Returns an intent to launch backup settings from backup transport if the intent was provided 53 * by the transport. Otherwise returns the intent to launch the default backup settings screen. 54 * 55 * @return Intent for launching backup settings 56 */ 57 public Intent getIntentForBackupSettings() { 58 Intent intent; 59 if (isIntentProvidedByTransport()) { 60 intent = getIntentForBackupSettingsFromTransport(); 61 } else { 62 Log.e(TAG, "Backup transport has not provided an intent" 63 + " or the component for the intent is not found!"); 64 intent = getIntentForDefaultBackupSettings(); 65 } 66 return intent; 67 } 68 69 /** 70 * Returns a label for the settings item that will point to the backup settings provided by 71 * the transport. If no label was provided by transport, returns the default string. 72 * 73 * @return Label for the backup settings item. 74 */ 75 public String getLabelForBackupSettings() { 76 String label = getLabelFromBackupTransport(); 77 if (label == null || label.isEmpty()) { 78 label = mContext.getString(R.string.privacy_settings_title); 79 } 80 return label; 81 } 82 83 /** 84 * Returns a summary string for the settings item that will point to the backup settings 85 * provided by the transport. If no summary was provided by transport, returns the default 86 * string. 87 * 88 * @return Summary for the backup settings item. 89 */ 90 public String getSummaryForBackupSettings() { 91 String summary = getSummaryFromBackupTransport(); 92 if (summary == null) { 93 summary = mContext.getString(R.string.backup_configure_account_default_summary); 94 } 95 return summary; 96 } 97 98 99 /** 100 * Checks if the manufacturer provided an intent to launch its backup settings screen 101 * in the config file. 102 */ 103 public boolean isBackupProvidedByManufacturer() { 104 if (Log.isLoggable(TAG, Log.DEBUG)) { 105 Log.d(TAG, "Checking if intent provided by manufacturer"); 106 } 107 String intentString = 108 mContext.getResources().getString(R.string.config_backup_settings_intent); 109 110 return intentString != null && !intentString.isEmpty(); 111 } 112 113 /** 114 * Returns the label for the backup settings item provided by the manufacturer. 115 */ 116 public String getLabelProvidedByManufacturer() { 117 return mContext.getResources().getString(R.string.config_backup_settings_label); 118 } 119 120 /** 121 * Returns the intent to the backup settings screen provided by the manufacturer. 122 */ 123 public Intent getIntentProvidedByManufacturer() { 124 if (Log.isLoggable(TAG, Log.DEBUG)) { 125 Log.d(TAG, "Getting a backup settings intent provided by manufacturer"); 126 } 127 String intentString = 128 mContext.getResources().getString(R.string.config_backup_settings_intent); 129 if (intentString != null && !intentString.isEmpty()) { 130 try { 131 return Intent.parseUri(intentString, 0); 132 } catch (URISyntaxException e) { 133 Log.e(TAG, "Invalid intent provided by the manufacturer.", e); 134 } 135 } 136 return null; 137 } 138 139 /** 140 * Gets the intent from Backup transport and adds the extra depending on whether the user has 141 * rights to see backup settings. 142 * 143 * @return Intent to launch Backup settings provided by the Backup transport. 144 */ 145 @VisibleForTesting 146 Intent getIntentForBackupSettingsFromTransport() { 147 Intent intent = getIntentFromBackupTransport(); 148 if (intent != null) { 149 intent.putExtra(BackupManager.EXTRA_BACKUP_SERVICES_AVAILABLE, isBackupServiceActive()); 150 } 151 return intent; 152 } 153 154 private Intent getIntentForDefaultBackupSettings() { 155 // Extra needed by {@link SettingsDrawerActivity} to show the back button navigation. 156 return new Intent(mContext, PrivacySettingsActivity.class) 157 .putExtra(SettingsDrawerActivity.EXTRA_SHOW_MENU, true); 158 } 159 160 /** 161 * Checks if the transport provided the intent to launch the backup settings and if that 162 * intent resolves to an activity. 163 */ 164 @VisibleForTesting 165 boolean isIntentProvidedByTransport() { 166 Intent intent = getIntentFromBackupTransport(); 167 return intent != null && intent.resolveActivity(mContext.getPackageManager()) != null; 168 } 169 170 /** 171 * Gets an intent to launch the backup settings from the current transport using 172 * {@link com.android.internal.backup.IBackupTransport#dataManagementIntent()} API. 173 * 174 * @return intent provided by transport or null if no intent was provided. 175 */ 176 private Intent getIntentFromBackupTransport() { 177 try { 178 Intent intent = 179 mBackupManager.getDataManagementIntent(mBackupManager.getCurrentTransport()); 180 if (Log.isLoggable(TAG, Log.DEBUG)) { 181 if (intent != null) { 182 Log.d(TAG, "Parsed intent from backup transport: " + intent.toString()); 183 } else { 184 Log.d(TAG, "Received a null intent from backup transport"); 185 } 186 } 187 return intent; 188 } catch (RemoteException e) { 189 Log.e(TAG, "Error getting data management intent", e); 190 } 191 return null; 192 } 193 194 /** Checks if backup service is enabled for this user. */ 195 private boolean isBackupServiceActive() { 196 boolean backupOkay; 197 try { 198 backupOkay = mBackupManager.isBackupServiceActive(UserHandle.myUserId()); 199 } catch (Exception e) { 200 // things go wrong talking to the backup system => ignore and 201 // pass the default 'false' as the "backup is a thing?" state. 202 backupOkay = false; 203 } 204 return backupOkay; 205 } 206 207 @VisibleForTesting 208 String getLabelFromBackupTransport() { 209 try { 210 String label = 211 mBackupManager.getDataManagementLabel(mBackupManager.getCurrentTransport()); 212 if (Log.isLoggable(TAG, Log.DEBUG)) { 213 Log.d(TAG, "Received the backup settings label from backup transport: " + label); 214 } 215 return label; 216 } catch (RemoteException e) { 217 Log.e(TAG, "Error getting data management label", e); 218 } 219 return null; 220 } 221 222 @VisibleForTesting 223 String getSummaryFromBackupTransport() { 224 try { 225 String summary = 226 mBackupManager.getDestinationString(mBackupManager.getCurrentTransport()); 227 if (Log.isLoggable(TAG, Log.DEBUG)) { 228 Log.d(TAG, 229 "Received the backup settings summary from backup transport: " + summary); 230 } 231 return summary; 232 } catch (RemoteException e) { 233 Log.e(TAG, "Error getting data management summary", e); 234 } 235 return null; 236 } 237 } 238