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.server.backup.utils; 18 19 import static com.google.common.truth.Truth.assertThat; 20 21 import android.content.pm.ApplicationInfo; 22 import android.content.pm.PackageInfo; 23 import android.content.pm.Signature; 24 import android.os.Process; 25 import android.platform.test.annotations.Presubmit; 26 import android.support.test.filters.SmallTest; 27 import android.support.test.runner.AndroidJUnit4; 28 29 import com.android.server.backup.RefactoredBackupManagerService; 30 31 import org.junit.Test; 32 import org.junit.runner.RunWith; 33 34 @SmallTest 35 @Presubmit 36 @RunWith(AndroidJUnit4.class) 37 public class AppBackupUtilsTest { 38 private static final String CUSTOM_BACKUP_AGENT_NAME = "custom.backup.agent"; 39 private static final String TEST_PACKAGE_NAME = "test_package"; 40 41 private static final Signature SIGNATURE_1 = generateSignature((byte) 1); 42 private static final Signature SIGNATURE_2 = generateSignature((byte) 2); 43 private static final Signature SIGNATURE_3 = generateSignature((byte) 3); 44 private static final Signature SIGNATURE_4 = generateSignature((byte) 4); 45 46 @Test 47 public void appIsEligibleForBackup_backupNotAllowed_returnsFalse() throws Exception { 48 ApplicationInfo applicationInfo = new ApplicationInfo(); 49 applicationInfo.flags = 0; 50 applicationInfo.uid = Process.FIRST_APPLICATION_UID; 51 applicationInfo.backupAgentName = CUSTOM_BACKUP_AGENT_NAME; 52 applicationInfo.packageName = TEST_PACKAGE_NAME; 53 54 boolean isEligible = AppBackupUtils.appIsEligibleForBackup(applicationInfo); 55 56 assertThat(isEligible).isFalse(); 57 } 58 59 @Test 60 public void appIsEligibleForBackup_systemAppWithoutCustomBackupAgent_returnsFalse() 61 throws Exception { 62 ApplicationInfo applicationInfo = new ApplicationInfo(); 63 applicationInfo.flags |= ApplicationInfo.FLAG_ALLOW_BACKUP; 64 applicationInfo.uid = Process.SYSTEM_UID; 65 applicationInfo.backupAgentName = null; 66 applicationInfo.packageName = TEST_PACKAGE_NAME; 67 68 boolean isEligible = AppBackupUtils.appIsEligibleForBackup(applicationInfo); 69 70 assertThat(isEligible).isFalse(); 71 } 72 73 @Test 74 public void appIsEligibleForBackup_sharedStorageBackupPackage_returnsFalse() throws Exception { 75 ApplicationInfo applicationInfo = new ApplicationInfo(); 76 applicationInfo.flags |= ApplicationInfo.FLAG_ALLOW_BACKUP; 77 applicationInfo.uid = Process.SYSTEM_UID; 78 applicationInfo.backupAgentName = CUSTOM_BACKUP_AGENT_NAME; 79 applicationInfo.packageName = RefactoredBackupManagerService.SHARED_BACKUP_AGENT_PACKAGE; 80 81 boolean isEligible = AppBackupUtils.appIsEligibleForBackup(applicationInfo); 82 83 assertThat(isEligible).isFalse(); 84 } 85 86 @Test 87 public void appIsEligibleForBackup_systemAppWithCustomBackupAgent_returnsTrue() 88 throws Exception { 89 ApplicationInfo applicationInfo = new ApplicationInfo(); 90 applicationInfo.flags |= ApplicationInfo.FLAG_ALLOW_BACKUP; 91 applicationInfo.uid = Process.SYSTEM_UID; 92 applicationInfo.backupAgentName = CUSTOM_BACKUP_AGENT_NAME; 93 applicationInfo.packageName = TEST_PACKAGE_NAME; 94 95 boolean isEligible = AppBackupUtils.appIsEligibleForBackup(applicationInfo); 96 97 assertThat(isEligible).isTrue(); 98 } 99 100 @Test 101 public void appIsEligibleForBackup_nonSystemAppWithoutCustomBackupAgent_returnsTrue() 102 throws Exception { 103 ApplicationInfo applicationInfo = new ApplicationInfo(); 104 applicationInfo.flags |= ApplicationInfo.FLAG_ALLOW_BACKUP; 105 applicationInfo.uid = Process.FIRST_APPLICATION_UID; 106 applicationInfo.backupAgentName = null; 107 applicationInfo.packageName = TEST_PACKAGE_NAME; 108 109 boolean isEligible = AppBackupUtils.appIsEligibleForBackup(applicationInfo); 110 111 assertThat(isEligible).isTrue(); 112 } 113 114 @Test 115 public void appIsEligibleForBackup_nonSystemAppWithCustomBackupAgent_returnsTrue() 116 throws Exception { 117 ApplicationInfo applicationInfo = new ApplicationInfo(); 118 applicationInfo.flags |= ApplicationInfo.FLAG_ALLOW_BACKUP; 119 applicationInfo.uid = Process.FIRST_APPLICATION_UID; 120 applicationInfo.backupAgentName = CUSTOM_BACKUP_AGENT_NAME; 121 applicationInfo.packageName = TEST_PACKAGE_NAME; 122 123 boolean isEligible = AppBackupUtils.appIsEligibleForBackup(applicationInfo); 124 125 assertThat(isEligible).isTrue(); 126 } 127 128 @Test 129 public void appIsStopped_returnsTrue() throws Exception { 130 ApplicationInfo applicationInfo = new ApplicationInfo(); 131 applicationInfo.flags |= ApplicationInfo.FLAG_STOPPED; 132 133 boolean isStopped = AppBackupUtils.appIsStopped(applicationInfo); 134 135 assertThat(isStopped).isTrue(); 136 } 137 138 @Test 139 public void appIsStopped_returnsFalse() throws Exception { 140 ApplicationInfo applicationInfo = new ApplicationInfo(); 141 applicationInfo.flags = ~ApplicationInfo.FLAG_STOPPED; 142 143 boolean isStopped = AppBackupUtils.appIsStopped(applicationInfo); 144 145 assertThat(isStopped).isFalse(); 146 } 147 148 @Test 149 public void appGetsFullBackup_noCustomBackupAgent_returnsTrue() throws Exception { 150 PackageInfo packageInfo = new PackageInfo(); 151 packageInfo.applicationInfo = new ApplicationInfo(); 152 packageInfo.applicationInfo.backupAgentName = null; 153 154 boolean result = AppBackupUtils.appGetsFullBackup(packageInfo); 155 156 assertThat(result).isTrue(); 157 } 158 159 @Test 160 public void appGetsFullBackup_withCustomBackupAgentAndFullBackupOnlyFlag_returnsTrue() 161 throws Exception { 162 PackageInfo packageInfo = new PackageInfo(); 163 packageInfo.applicationInfo = new ApplicationInfo(); 164 packageInfo.applicationInfo.backupAgentName = "backup.agent"; 165 packageInfo.applicationInfo.flags |= ApplicationInfo.FLAG_FULL_BACKUP_ONLY; 166 167 boolean result = AppBackupUtils.appGetsFullBackup(packageInfo); 168 169 assertThat(result).isTrue(); 170 } 171 172 @Test 173 public void appGetsFullBackup_withCustomBackupAgentAndWithoutFullBackupOnlyFlag_returnsFalse() 174 throws Exception { 175 PackageInfo packageInfo = new PackageInfo(); 176 packageInfo.applicationInfo = new ApplicationInfo(); 177 packageInfo.applicationInfo.backupAgentName = "backup.agent"; 178 packageInfo.applicationInfo.flags = ~ApplicationInfo.FLAG_FULL_BACKUP_ONLY; 179 180 boolean result = AppBackupUtils.appGetsFullBackup(packageInfo); 181 182 assertThat(result).isFalse(); 183 } 184 185 @Test 186 public void appIsKeyValueOnly_noCustomBackupAgent_returnsTrue() throws Exception { 187 PackageInfo packageInfo = new PackageInfo(); 188 packageInfo.applicationInfo = new ApplicationInfo(); 189 packageInfo.applicationInfo.backupAgentName = null; 190 191 boolean result = AppBackupUtils.appIsKeyValueOnly(packageInfo); 192 193 assertThat(result).isFalse(); 194 } 195 196 @Test 197 public void appIsKeyValueOnly_withCustomBackupAgentAndFullBackupOnlyFlag_returnsTrue() 198 throws Exception { 199 PackageInfo packageInfo = new PackageInfo(); 200 packageInfo.applicationInfo = new ApplicationInfo(); 201 packageInfo.applicationInfo.backupAgentName = "backup.agent"; 202 packageInfo.applicationInfo.flags |= ApplicationInfo.FLAG_FULL_BACKUP_ONLY; 203 204 boolean result = AppBackupUtils.appIsKeyValueOnly(packageInfo); 205 206 assertThat(result).isFalse(); 207 } 208 209 @Test 210 public void appIsKeyValueOnly_withCustomBackupAgentAndWithoutFullBackupOnlyFlag_returnsFalse() 211 throws Exception { 212 PackageInfo packageInfo = new PackageInfo(); 213 packageInfo.applicationInfo = new ApplicationInfo(); 214 packageInfo.applicationInfo.backupAgentName = "backup.agent"; 215 packageInfo.applicationInfo.flags = ~ApplicationInfo.FLAG_FULL_BACKUP_ONLY; 216 217 boolean result = AppBackupUtils.appIsKeyValueOnly(packageInfo); 218 219 assertThat(result).isTrue(); 220 } 221 222 @Test 223 public void signaturesMatch_targetIsNull_returnsFalse() throws Exception { 224 boolean result = AppBackupUtils.signaturesMatch(new Signature[] {SIGNATURE_1}, null); 225 226 assertThat(result).isFalse(); 227 } 228 229 @Test 230 public void signaturesMatch_systemApplication_returnsTrue() throws Exception { 231 PackageInfo packageInfo = new PackageInfo(); 232 packageInfo.applicationInfo = new ApplicationInfo(); 233 packageInfo.applicationInfo.flags |= ApplicationInfo.FLAG_SYSTEM; 234 235 boolean result = AppBackupUtils.signaturesMatch(new Signature[0], packageInfo); 236 237 assertThat(result).isTrue(); 238 } 239 240 @Test 241 public void signaturesMatch_disallowsUnsignedApps_storedSignatureNull_returnsFalse() 242 throws Exception { 243 PackageInfo packageInfo = new PackageInfo(); 244 packageInfo.signatures = new Signature[] {SIGNATURE_1}; 245 packageInfo.applicationInfo = new ApplicationInfo(); 246 247 boolean result = AppBackupUtils.signaturesMatch(null, packageInfo); 248 249 assertThat(result).isFalse(); 250 } 251 252 @Test 253 public void signaturesMatch_disallowsUnsignedApps_storedSignatureEmpty_returnsFalse() 254 throws Exception { 255 PackageInfo packageInfo = new PackageInfo(); 256 packageInfo.signatures = new Signature[] {SIGNATURE_1}; 257 packageInfo.applicationInfo = new ApplicationInfo(); 258 259 boolean result = AppBackupUtils.signaturesMatch(new Signature[0], packageInfo); 260 261 assertThat(result).isFalse(); 262 } 263 264 265 @Test 266 public void 267 signaturesMatch_disallowsUnsignedApps_targetSignatureEmpty_returnsFalse() 268 throws Exception { 269 PackageInfo packageInfo = new PackageInfo(); 270 packageInfo.signatures = new Signature[0]; 271 packageInfo.applicationInfo = new ApplicationInfo(); 272 273 boolean result = AppBackupUtils.signaturesMatch(new Signature[] {SIGNATURE_1}, 274 packageInfo); 275 276 assertThat(result).isFalse(); 277 } 278 279 @Test 280 public void 281 signaturesMatch_disallowsUnsignedApps_targetSignatureNull_returnsFalse() 282 throws Exception { 283 PackageInfo packageInfo = new PackageInfo(); 284 packageInfo.signatures = null; 285 packageInfo.applicationInfo = new ApplicationInfo(); 286 287 boolean result = AppBackupUtils.signaturesMatch(new Signature[] {SIGNATURE_1}, 288 packageInfo); 289 290 assertThat(result).isFalse(); 291 } 292 293 @Test 294 public void signaturesMatch_disallowsUnsignedApps_bothSignaturesNull_returnsFalse() 295 throws Exception { 296 PackageInfo packageInfo = new PackageInfo(); 297 packageInfo.signatures = null; 298 packageInfo.applicationInfo = new ApplicationInfo(); 299 300 boolean result = AppBackupUtils.signaturesMatch(null, packageInfo); 301 302 assertThat(result).isFalse(); 303 } 304 305 @Test 306 public void signaturesMatch_disallowsUnsignedApps_bothSignaturesEmpty_returnsFalse() 307 throws Exception { 308 PackageInfo packageInfo = new PackageInfo(); 309 packageInfo.signatures = new Signature[0]; 310 packageInfo.applicationInfo = new ApplicationInfo(); 311 312 boolean result = AppBackupUtils.signaturesMatch(new Signature[0], packageInfo); 313 314 assertThat(result).isFalse(); 315 } 316 317 @Test 318 public void signaturesMatch_equalSignatures_returnsTrue() throws Exception { 319 Signature signature1Copy = new Signature(SIGNATURE_1.toByteArray()); 320 Signature signature2Copy = new Signature(SIGNATURE_2.toByteArray()); 321 Signature signature3Copy = new Signature(SIGNATURE_3.toByteArray()); 322 323 PackageInfo packageInfo = new PackageInfo(); 324 packageInfo.signatures = new Signature[]{SIGNATURE_1, SIGNATURE_2, SIGNATURE_3}; 325 packageInfo.applicationInfo = new ApplicationInfo(); 326 327 boolean result = AppBackupUtils.signaturesMatch( 328 new Signature[]{signature3Copy, signature1Copy, signature2Copy}, packageInfo); 329 330 assertThat(result).isTrue(); 331 } 332 333 @Test 334 public void signaturesMatch_extraSignatureInTarget_returnsTrue() throws Exception { 335 Signature signature1Copy = new Signature(SIGNATURE_1.toByteArray()); 336 Signature signature2Copy = new Signature(SIGNATURE_2.toByteArray()); 337 338 PackageInfo packageInfo = new PackageInfo(); 339 packageInfo.signatures = new Signature[]{SIGNATURE_1, SIGNATURE_2, SIGNATURE_3}; 340 packageInfo.applicationInfo = new ApplicationInfo(); 341 342 boolean result = AppBackupUtils.signaturesMatch( 343 new Signature[]{signature2Copy, signature1Copy}, packageInfo); 344 345 assertThat(result).isTrue(); 346 } 347 348 @Test 349 public void signaturesMatch_extraSignatureInStored_returnsFalse() throws Exception { 350 Signature signature1Copy = new Signature(SIGNATURE_1.toByteArray()); 351 Signature signature2Copy = new Signature(SIGNATURE_2.toByteArray()); 352 353 PackageInfo packageInfo = new PackageInfo(); 354 packageInfo.signatures = new Signature[]{signature1Copy, signature2Copy}; 355 packageInfo.applicationInfo = new ApplicationInfo(); 356 357 boolean result = AppBackupUtils.signaturesMatch( 358 new Signature[]{SIGNATURE_1, SIGNATURE_2, SIGNATURE_3}, packageInfo); 359 360 assertThat(result).isFalse(); 361 } 362 363 @Test 364 public void signaturesMatch_oneNonMatchingSignature_returnsFalse() throws Exception { 365 Signature signature1Copy = new Signature(SIGNATURE_1.toByteArray()); 366 Signature signature2Copy = new Signature(SIGNATURE_2.toByteArray()); 367 368 PackageInfo packageInfo = new PackageInfo(); 369 packageInfo.signatures = new Signature[]{SIGNATURE_1, SIGNATURE_2, SIGNATURE_3}; 370 packageInfo.applicationInfo = new ApplicationInfo(); 371 372 boolean result = AppBackupUtils.signaturesMatch( 373 new Signature[]{signature1Copy, signature2Copy, SIGNATURE_4}, packageInfo); 374 375 assertThat(result).isFalse(); 376 } 377 378 private static Signature generateSignature(byte i) { 379 byte[] signatureBytes = new byte[256]; 380 signatureBytes[0] = i; 381 return new Signature(signatureBytes); 382 } 383 } 384