blob: 479a19b93ca7f0b33702e5604ff1af91bb171a95 [file] [log] [blame]
Artem Iglikov66ff1d62017-05-03 15:06:59 +01001/*
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
17package com.android.server.backup.utils;
18
19import static com.google.common.truth.Truth.assertThat;
20
Michal Karpinski528c3e52018-02-07 17:47:10 +000021import static org.mockito.Mockito.doReturn;
22import static org.mockito.Mockito.mock;
Michal Karpinski528c3e52018-02-07 17:47:10 +000023
Artem Iglikov66ff1d62017-05-03 15:06:59 +010024import android.content.pm.ApplicationInfo;
Artem Iglikov23c60072017-05-04 12:13:58 +010025import android.content.pm.PackageInfo;
Michal Karpinski5c90ff02017-09-18 16:07:28 +010026import android.content.pm.PackageManager;
Michal Karpinski528c3e52018-02-07 17:47:10 +000027import android.content.pm.PackageManagerInternal;
Dan Cashman5c9f527e2018-04-03 16:42:23 -070028import android.content.pm.PackageParser;
Artem Iglikov23c60072017-05-04 12:13:58 +010029import android.content.pm.Signature;
Dan Cashman5c9f527e2018-04-03 16:42:23 -070030import android.content.pm.SigningInfo;
Artem Iglikov66ff1d62017-05-03 15:06:59 +010031import android.os.Process;
32import android.platform.test.annotations.Presubmit;
Brett Chabota26eda92018-07-23 13:08:30 -070033
34import androidx.test.filters.SmallTest;
35import androidx.test.runner.AndroidJUnit4;
Artem Iglikov66ff1d62017-05-03 15:06:59 +010036
Annie Meng813716b2018-11-20 14:08:21 +000037import com.android.server.backup.UserBackupManagerService;
Michal Karpinski5c90ff02017-09-18 16:07:28 +010038import com.android.server.backup.testutils.PackageManagerStub;
Artem Iglikov66ff1d62017-05-03 15:06:59 +010039
Michal Karpinski528c3e52018-02-07 17:47:10 +000040import org.junit.Before;
Artem Iglikov66ff1d62017-05-03 15:06:59 +010041import org.junit.Test;
42import org.junit.runner.RunWith;
43
44@SmallTest
45@Presubmit
46@RunWith(AndroidJUnit4.class)
47public class AppBackupUtilsTest {
48 private static final String CUSTOM_BACKUP_AGENT_NAME = "custom.backup.agent";
49 private static final String TEST_PACKAGE_NAME = "test_package";
50
Bernardo Rufinocbcc34e2017-08-18 14:27:31 +010051 private static final Signature SIGNATURE_1 = generateSignature((byte) 1);
52 private static final Signature SIGNATURE_2 = generateSignature((byte) 2);
53 private static final Signature SIGNATURE_3 = generateSignature((byte) 3);
54 private static final Signature SIGNATURE_4 = generateSignature((byte) 4);
Artem Iglikov23c60072017-05-04 12:13:58 +010055
Michal Karpinski528c3e52018-02-07 17:47:10 +000056 private PackageManagerStub mPackageManagerStub;
57 private PackageManagerInternal mMockPackageManagerInternal;
58
59 @Before
60 public void setUp() throws Exception {
61 mPackageManagerStub = new PackageManagerStub();
62 mMockPackageManagerInternal = mock(PackageManagerInternal.class);
63 }
Michal Karpinski5c90ff02017-09-18 16:07:28 +010064
Artem Iglikov66ff1d62017-05-03 15:06:59 +010065 @Test
Artem Iglikov23c60072017-05-04 12:13:58 +010066 public void appIsEligibleForBackup_backupNotAllowed_returnsFalse() throws Exception {
Artem Iglikov66ff1d62017-05-03 15:06:59 +010067 ApplicationInfo applicationInfo = new ApplicationInfo();
68 applicationInfo.flags = 0;
69 applicationInfo.uid = Process.FIRST_APPLICATION_UID;
70 applicationInfo.backupAgentName = CUSTOM_BACKUP_AGENT_NAME;
71 applicationInfo.packageName = TEST_PACKAGE_NAME;
72
Michal Karpinski5c90ff02017-09-18 16:07:28 +010073 boolean isEligible = AppBackupUtils.appIsEligibleForBackup(applicationInfo,
74 mPackageManagerStub);
Artem Iglikov66ff1d62017-05-03 15:06:59 +010075
76 assertThat(isEligible).isFalse();
77 }
78
79 @Test
Artem Iglikov23c60072017-05-04 12:13:58 +010080 public void appIsEligibleForBackup_systemAppWithoutCustomBackupAgent_returnsFalse()
81 throws Exception {
Artem Iglikov66ff1d62017-05-03 15:06:59 +010082 ApplicationInfo applicationInfo = new ApplicationInfo();
83 applicationInfo.flags |= ApplicationInfo.FLAG_ALLOW_BACKUP;
84 applicationInfo.uid = Process.SYSTEM_UID;
85 applicationInfo.backupAgentName = null;
86 applicationInfo.packageName = TEST_PACKAGE_NAME;
87
Michal Karpinski5c90ff02017-09-18 16:07:28 +010088 boolean isEligible = AppBackupUtils.appIsEligibleForBackup(applicationInfo,
89 mPackageManagerStub);
Artem Iglikov66ff1d62017-05-03 15:06:59 +010090
91 assertThat(isEligible).isFalse();
92 }
93
94 @Test
Artem Iglikov23c60072017-05-04 12:13:58 +010095 public void appIsEligibleForBackup_sharedStorageBackupPackage_returnsFalse() throws Exception {
Artem Iglikov66ff1d62017-05-03 15:06:59 +010096 ApplicationInfo applicationInfo = new ApplicationInfo();
97 applicationInfo.flags |= ApplicationInfo.FLAG_ALLOW_BACKUP;
98 applicationInfo.uid = Process.SYSTEM_UID;
99 applicationInfo.backupAgentName = CUSTOM_BACKUP_AGENT_NAME;
Annie Meng813716b2018-11-20 14:08:21 +0000100 applicationInfo.packageName = UserBackupManagerService.SHARED_BACKUP_AGENT_PACKAGE;
Artem Iglikov66ff1d62017-05-03 15:06:59 +0100101
Michal Karpinski5c90ff02017-09-18 16:07:28 +0100102 boolean isEligible = AppBackupUtils.appIsEligibleForBackup(applicationInfo,
103 mPackageManagerStub);
Artem Iglikov66ff1d62017-05-03 15:06:59 +0100104
105 assertThat(isEligible).isFalse();
106 }
107
108 @Test
Michal Karpinski5c90ff02017-09-18 16:07:28 +0100109 public void appIsEligibleForBackup_systemAppWithCustomBackupAgentAndEnabled_returnsTrue()
Artem Iglikov23c60072017-05-04 12:13:58 +0100110 throws Exception {
Artem Iglikov66ff1d62017-05-03 15:06:59 +0100111 ApplicationInfo applicationInfo = new ApplicationInfo();
112 applicationInfo.flags |= ApplicationInfo.FLAG_ALLOW_BACKUP;
113 applicationInfo.uid = Process.SYSTEM_UID;
114 applicationInfo.backupAgentName = CUSTOM_BACKUP_AGENT_NAME;
115 applicationInfo.packageName = TEST_PACKAGE_NAME;
116
Michal Karpinski5c90ff02017-09-18 16:07:28 +0100117 PackageManagerStub.sApplicationEnabledSetting =
118 PackageManager.COMPONENT_ENABLED_STATE_ENABLED;
119
120 boolean isEligible = AppBackupUtils.appIsEligibleForBackup(applicationInfo,
121 mPackageManagerStub);
Artem Iglikov66ff1d62017-05-03 15:06:59 +0100122
123 assertThat(isEligible).isTrue();
124 }
125
126 @Test
Michal Karpinski5c90ff02017-09-18 16:07:28 +0100127 public void appIsEligibleForBackup_nonSystemAppWithoutCustomBackupAgentAndEnabled_returnsTrue()
Artem Iglikov23c60072017-05-04 12:13:58 +0100128 throws Exception {
Artem Iglikov66ff1d62017-05-03 15:06:59 +0100129 ApplicationInfo applicationInfo = new ApplicationInfo();
130 applicationInfo.flags |= ApplicationInfo.FLAG_ALLOW_BACKUP;
131 applicationInfo.uid = Process.FIRST_APPLICATION_UID;
132 applicationInfo.backupAgentName = null;
133 applicationInfo.packageName = TEST_PACKAGE_NAME;
134
Michal Karpinski5c90ff02017-09-18 16:07:28 +0100135 PackageManagerStub.sApplicationEnabledSetting =
136 PackageManager.COMPONENT_ENABLED_STATE_ENABLED;
137
138 boolean isEligible = AppBackupUtils.appIsEligibleForBackup(applicationInfo,
139 mPackageManagerStub);
Artem Iglikov66ff1d62017-05-03 15:06:59 +0100140
141 assertThat(isEligible).isTrue();
142 }
143
144 @Test
Michal Karpinski5c90ff02017-09-18 16:07:28 +0100145 public void appIsEligibleForBackup_nonSystemAppWithCustomBackupAgentAndEnabled_returnsTrue()
Artem Iglikov23c60072017-05-04 12:13:58 +0100146 throws Exception {
Artem Iglikov66ff1d62017-05-03 15:06:59 +0100147 ApplicationInfo applicationInfo = new ApplicationInfo();
148 applicationInfo.flags |= ApplicationInfo.FLAG_ALLOW_BACKUP;
149 applicationInfo.uid = Process.FIRST_APPLICATION_UID;
150 applicationInfo.backupAgentName = CUSTOM_BACKUP_AGENT_NAME;
151 applicationInfo.packageName = TEST_PACKAGE_NAME;
152
Michal Karpinski5c90ff02017-09-18 16:07:28 +0100153 PackageManagerStub.sApplicationEnabledSetting =
154 PackageManager.COMPONENT_ENABLED_STATE_ENABLED;
155
156 boolean isEligible = AppBackupUtils.appIsEligibleForBackup(applicationInfo,
157 mPackageManagerStub);
Artem Iglikov66ff1d62017-05-03 15:06:59 +0100158
159 assertThat(isEligible).isTrue();
160 }
161
Artem Iglikov23c60072017-05-04 12:13:58 +0100162 @Test
Michal Karpinski5c90ff02017-09-18 16:07:28 +0100163 public void appIsEligibleForBackup_systemAppWithCustomBackupAgentAndDisabled_returnsFalse()
164 throws Exception {
165 ApplicationInfo applicationInfo = new ApplicationInfo();
166 applicationInfo.flags |= ApplicationInfo.FLAG_ALLOW_BACKUP;
167 applicationInfo.uid = Process.SYSTEM_UID;
168 applicationInfo.backupAgentName = CUSTOM_BACKUP_AGENT_NAME;
169 applicationInfo.packageName = TEST_PACKAGE_NAME;
170
171 PackageManagerStub.sApplicationEnabledSetting =
172 PackageManager.COMPONENT_ENABLED_STATE_DISABLED;
173
174 boolean isEligible = AppBackupUtils.appIsEligibleForBackup(applicationInfo,
175 mPackageManagerStub);
176
177 assertThat(isEligible).isFalse();
178 }
179
180 @Test
181 public void appIsEligibleForBackup_nonSystemAppWithoutCustomBackupAgentAndDisabled_returnsFalse()
182 throws Exception {
183 ApplicationInfo applicationInfo = new ApplicationInfo();
184 applicationInfo.flags |= ApplicationInfo.FLAG_ALLOW_BACKUP;
185 applicationInfo.uid = Process.FIRST_APPLICATION_UID;
186 applicationInfo.backupAgentName = null;
187 applicationInfo.packageName = TEST_PACKAGE_NAME;
188
189 PackageManagerStub.sApplicationEnabledSetting =
190 PackageManager.COMPONENT_ENABLED_STATE_DISABLED;
191
192 boolean isEligible = AppBackupUtils.appIsEligibleForBackup(applicationInfo,
193 mPackageManagerStub);
194
195 assertThat(isEligible).isFalse();
196 }
197
198 @Test
199 public void appIsEligibleForBackup_nonSystemAppWithCustomBackupAgentAndDisbled_returnsFalse()
200 throws Exception {
201 ApplicationInfo applicationInfo = new ApplicationInfo();
202 applicationInfo.flags |= ApplicationInfo.FLAG_ALLOW_BACKUP;
203 applicationInfo.uid = Process.FIRST_APPLICATION_UID;
204 applicationInfo.backupAgentName = CUSTOM_BACKUP_AGENT_NAME;
205 applicationInfo.packageName = TEST_PACKAGE_NAME;
206
207 PackageManagerStub.sApplicationEnabledSetting =
208 PackageManager.COMPONENT_ENABLED_STATE_DISABLED;
209
210 boolean isEligible = AppBackupUtils.appIsEligibleForBackup(applicationInfo,
211 mPackageManagerStub);
212
213 assertThat(isEligible).isFalse();
214 }
215
216 @Test
Bernardo Rufino7307e642018-06-04 11:23:00 +0100217 public void appIsDisabled_stateDefaultManifestEnabled_returnsFalse() throws Exception {
218 ApplicationInfo applicationInfo = new ApplicationInfo();
219 applicationInfo.flags = 0;
220 applicationInfo.uid = Process.FIRST_APPLICATION_UID;
221 applicationInfo.backupAgentName = CUSTOM_BACKUP_AGENT_NAME;
222 applicationInfo.packageName = TEST_PACKAGE_NAME;
223 applicationInfo.enabled = true;
224
225 PackageManagerStub.sApplicationEnabledSetting =
226 PackageManager.COMPONENT_ENABLED_STATE_DEFAULT;
227
228 boolean isDisabled = AppBackupUtils.appIsDisabled(applicationInfo, mPackageManagerStub);
229
230 assertThat(isDisabled).isFalse();
231 }
232
233 @Test
234 public void appIsDisabled_stateDefaultManifestDisabled_returnsTrue() throws Exception {
235 ApplicationInfo applicationInfo = new ApplicationInfo();
236 applicationInfo.flags = 0;
237 applicationInfo.uid = Process.FIRST_APPLICATION_UID;
238 applicationInfo.backupAgentName = CUSTOM_BACKUP_AGENT_NAME;
239 applicationInfo.packageName = TEST_PACKAGE_NAME;
240 applicationInfo.enabled = false;
241
242 PackageManagerStub.sApplicationEnabledSetting =
243 PackageManager.COMPONENT_ENABLED_STATE_DEFAULT;
244
245 boolean isDisabled = AppBackupUtils.appIsDisabled(applicationInfo, mPackageManagerStub);
246
247 assertThat(isDisabled).isTrue();
248 }
249
250 @Test
Michal Karpinski5c90ff02017-09-18 16:07:28 +0100251 public void appIsDisabled_stateEnabled_returnsFalse() throws Exception {
252 ApplicationInfo applicationInfo = new ApplicationInfo();
253 applicationInfo.flags = 0;
254 applicationInfo.uid = Process.FIRST_APPLICATION_UID;
255 applicationInfo.backupAgentName = CUSTOM_BACKUP_AGENT_NAME;
256 applicationInfo.packageName = TEST_PACKAGE_NAME;
257
258 PackageManagerStub.sApplicationEnabledSetting =
259 PackageManager.COMPONENT_ENABLED_STATE_ENABLED;
260
261 boolean isDisabled = AppBackupUtils.appIsDisabled(applicationInfo, mPackageManagerStub);
262
263 assertThat(isDisabled).isFalse();
264 }
265
266 @Test
267 public void appIsDisabled_stateDisabled_returnsTrue() throws Exception {
268 ApplicationInfo applicationInfo = new ApplicationInfo();
269 applicationInfo.flags = 0;
270 applicationInfo.uid = Process.FIRST_APPLICATION_UID;
271 applicationInfo.backupAgentName = CUSTOM_BACKUP_AGENT_NAME;
272 applicationInfo.packageName = TEST_PACKAGE_NAME;
273
274 PackageManagerStub.sApplicationEnabledSetting =
275 PackageManager.COMPONENT_ENABLED_STATE_DISABLED;
276
277 boolean isDisabled = AppBackupUtils.appIsDisabled(applicationInfo, mPackageManagerStub);
278
279 assertThat(isDisabled).isTrue();
280 }
281
282 @Test
283 public void appIsDisabled_stateDisabledUser_returnsTrue() throws Exception {
284 ApplicationInfo applicationInfo = new ApplicationInfo();
285 applicationInfo.flags = 0;
286 applicationInfo.uid = Process.FIRST_APPLICATION_UID;
287 applicationInfo.backupAgentName = CUSTOM_BACKUP_AGENT_NAME;
288 applicationInfo.packageName = TEST_PACKAGE_NAME;
289
290 PackageManagerStub.sApplicationEnabledSetting =
291 PackageManager.COMPONENT_ENABLED_STATE_DISABLED_USER;
292
293 boolean isDisabled = AppBackupUtils.appIsDisabled(applicationInfo, mPackageManagerStub);
294
295 assertThat(isDisabled).isTrue();
296 }
297
298 @Test
299 public void appIsDisabled_stateDisabledUntilUsed_returnsTrue() throws Exception {
300 ApplicationInfo applicationInfo = new ApplicationInfo();
301 applicationInfo.flags = 0;
302 applicationInfo.uid = Process.FIRST_APPLICATION_UID;
303 applicationInfo.backupAgentName = CUSTOM_BACKUP_AGENT_NAME;
304 applicationInfo.packageName = TEST_PACKAGE_NAME;
305
306 PackageManagerStub.sApplicationEnabledSetting =
307 PackageManager.COMPONENT_ENABLED_STATE_DISABLED_UNTIL_USED;
308
309 boolean isDisabled = AppBackupUtils.appIsDisabled(applicationInfo, mPackageManagerStub);
310
311 assertThat(isDisabled).isTrue();
312 }
313
314 @Test
Artem Iglikov23c60072017-05-04 12:13:58 +0100315 public void appIsStopped_returnsTrue() throws Exception {
316 ApplicationInfo applicationInfo = new ApplicationInfo();
317 applicationInfo.flags |= ApplicationInfo.FLAG_STOPPED;
318
319 boolean isStopped = AppBackupUtils.appIsStopped(applicationInfo);
320
321 assertThat(isStopped).isTrue();
322 }
323
324 @Test
325 public void appIsStopped_returnsFalse() throws Exception {
326 ApplicationInfo applicationInfo = new ApplicationInfo();
327 applicationInfo.flags = ~ApplicationInfo.FLAG_STOPPED;
328
329 boolean isStopped = AppBackupUtils.appIsStopped(applicationInfo);
330
331 assertThat(isStopped).isFalse();
332 }
333
334 @Test
335 public void appGetsFullBackup_noCustomBackupAgent_returnsTrue() throws Exception {
336 PackageInfo packageInfo = new PackageInfo();
337 packageInfo.applicationInfo = new ApplicationInfo();
338 packageInfo.applicationInfo.backupAgentName = null;
339
340 boolean result = AppBackupUtils.appGetsFullBackup(packageInfo);
341
342 assertThat(result).isTrue();
343 }
344
345 @Test
346 public void appGetsFullBackup_withCustomBackupAgentAndFullBackupOnlyFlag_returnsTrue()
347 throws Exception {
348 PackageInfo packageInfo = new PackageInfo();
349 packageInfo.applicationInfo = new ApplicationInfo();
350 packageInfo.applicationInfo.backupAgentName = "backup.agent";
351 packageInfo.applicationInfo.flags |= ApplicationInfo.FLAG_FULL_BACKUP_ONLY;
352
353 boolean result = AppBackupUtils.appGetsFullBackup(packageInfo);
354
355 assertThat(result).isTrue();
356 }
357
358 @Test
359 public void appGetsFullBackup_withCustomBackupAgentAndWithoutFullBackupOnlyFlag_returnsFalse()
360 throws Exception {
361 PackageInfo packageInfo = new PackageInfo();
362 packageInfo.applicationInfo = new ApplicationInfo();
363 packageInfo.applicationInfo.backupAgentName = "backup.agent";
364 packageInfo.applicationInfo.flags = ~ApplicationInfo.FLAG_FULL_BACKUP_ONLY;
365
366 boolean result = AppBackupUtils.appGetsFullBackup(packageInfo);
367
368 assertThat(result).isFalse();
369 }
370
371 @Test
372 public void appIsKeyValueOnly_noCustomBackupAgent_returnsTrue() throws Exception {
373 PackageInfo packageInfo = new PackageInfo();
374 packageInfo.applicationInfo = new ApplicationInfo();
375 packageInfo.applicationInfo.backupAgentName = null;
376
377 boolean result = AppBackupUtils.appIsKeyValueOnly(packageInfo);
378
379 assertThat(result).isFalse();
380 }
381
382 @Test
383 public void appIsKeyValueOnly_withCustomBackupAgentAndFullBackupOnlyFlag_returnsTrue()
384 throws Exception {
385 PackageInfo packageInfo = new PackageInfo();
386 packageInfo.applicationInfo = new ApplicationInfo();
387 packageInfo.applicationInfo.backupAgentName = "backup.agent";
388 packageInfo.applicationInfo.flags |= ApplicationInfo.FLAG_FULL_BACKUP_ONLY;
389
390 boolean result = AppBackupUtils.appIsKeyValueOnly(packageInfo);
391
392 assertThat(result).isFalse();
393 }
394
395 @Test
396 public void appIsKeyValueOnly_withCustomBackupAgentAndWithoutFullBackupOnlyFlag_returnsFalse()
397 throws Exception {
398 PackageInfo packageInfo = new PackageInfo();
399 packageInfo.applicationInfo = new ApplicationInfo();
400 packageInfo.applicationInfo.backupAgentName = "backup.agent";
401 packageInfo.applicationInfo.flags = ~ApplicationInfo.FLAG_FULL_BACKUP_ONLY;
402
403 boolean result = AppBackupUtils.appIsKeyValueOnly(packageInfo);
404
405 assertThat(result).isTrue();
406 }
407
408 @Test
409 public void signaturesMatch_targetIsNull_returnsFalse() throws Exception {
Michal Karpinski528c3e52018-02-07 17:47:10 +0000410 boolean result = AppBackupUtils.signaturesMatch(new Signature[] {SIGNATURE_1}, null,
411 mMockPackageManagerInternal);
Artem Iglikov23c60072017-05-04 12:13:58 +0100412
413 assertThat(result).isFalse();
414 }
415
416 @Test
417 public void signaturesMatch_systemApplication_returnsTrue() throws Exception {
418 PackageInfo packageInfo = new PackageInfo();
Michal Karpinski528c3e52018-02-07 17:47:10 +0000419 packageInfo.packageName = "test";
Artem Iglikov23c60072017-05-04 12:13:58 +0100420 packageInfo.applicationInfo = new ApplicationInfo();
421 packageInfo.applicationInfo.flags |= ApplicationInfo.FLAG_SYSTEM;
422
Michal Karpinski528c3e52018-02-07 17:47:10 +0000423 boolean result = AppBackupUtils.signaturesMatch(new Signature[0], packageInfo,
424 mMockPackageManagerInternal);
Artem Iglikov23c60072017-05-04 12:13:58 +0100425
426 assertThat(result).isTrue();
427 }
428
429 @Test
Bernardo Rufinocbcc34e2017-08-18 14:27:31 +0100430 public void signaturesMatch_disallowsUnsignedApps_storedSignatureNull_returnsFalse()
Artem Iglikov23c60072017-05-04 12:13:58 +0100431 throws Exception {
432 PackageInfo packageInfo = new PackageInfo();
Michal Karpinski528c3e52018-02-07 17:47:10 +0000433 packageInfo.packageName = "test";
Dan Cashman5c9f527e2018-04-03 16:42:23 -0700434 packageInfo.signingInfo = new SigningInfo(
435 new PackageParser.SigningDetails(
436 new Signature[] {SIGNATURE_1},
437 PackageParser.SigningDetails.SignatureSchemeVersion.SIGNING_BLOCK_V3,
438 null,
Dan Cashman5c9f527e2018-04-03 16:42:23 -0700439 null));
Artem Iglikov23c60072017-05-04 12:13:58 +0100440 packageInfo.applicationInfo = new ApplicationInfo();
441
Michal Karpinski528c3e52018-02-07 17:47:10 +0000442 boolean result = AppBackupUtils.signaturesMatch(null, packageInfo,
443 mMockPackageManagerInternal);
Artem Iglikov23c60072017-05-04 12:13:58 +0100444
445 assertThat(result).isFalse();
446 }
447
448 @Test
Bernardo Rufinocbcc34e2017-08-18 14:27:31 +0100449 public void signaturesMatch_disallowsUnsignedApps_storedSignatureEmpty_returnsFalse()
Artem Iglikov23c60072017-05-04 12:13:58 +0100450 throws Exception {
451 PackageInfo packageInfo = new PackageInfo();
Michal Karpinski528c3e52018-02-07 17:47:10 +0000452 packageInfo.packageName = "test";
Dan Cashman5c9f527e2018-04-03 16:42:23 -0700453 packageInfo.signingInfo = new SigningInfo(
454 new PackageParser.SigningDetails(
455 new Signature[] {SIGNATURE_1},
456 PackageParser.SigningDetails.SignatureSchemeVersion.SIGNING_BLOCK_V3,
457 null,
Dan Cashman5c9f527e2018-04-03 16:42:23 -0700458 null));
Artem Iglikov23c60072017-05-04 12:13:58 +0100459 packageInfo.applicationInfo = new ApplicationInfo();
460
Michal Karpinski528c3e52018-02-07 17:47:10 +0000461 boolean result = AppBackupUtils.signaturesMatch(new Signature[0], packageInfo,
462 mMockPackageManagerInternal);
Bernardo Rufinocbcc34e2017-08-18 14:27:31 +0100463
464 assertThat(result).isFalse();
465 }
466
467
468 @Test
469 public void
470 signaturesMatch_disallowsUnsignedApps_targetSignatureEmpty_returnsFalse()
471 throws Exception {
472 PackageInfo packageInfo = new PackageInfo();
Michal Karpinski528c3e52018-02-07 17:47:10 +0000473 packageInfo.packageName = "test";
Dan Cashman5c9f527e2018-04-03 16:42:23 -0700474 packageInfo.signingInfo = null;
Bernardo Rufinocbcc34e2017-08-18 14:27:31 +0100475 packageInfo.applicationInfo = new ApplicationInfo();
476
Michal Karpinski528c3e52018-02-07 17:47:10 +0000477 boolean result = AppBackupUtils.signaturesMatch(new Signature[] {SIGNATURE_1}, packageInfo,
478 mMockPackageManagerInternal);
Artem Iglikov23c60072017-05-04 12:13:58 +0100479
480 assertThat(result).isFalse();
481 }
482
483 @Test
Bernardo Rufinocbcc34e2017-08-18 14:27:31 +0100484 public void
485 signaturesMatch_disallowsUnsignedApps_targetSignatureNull_returnsFalse()
486 throws Exception {
487 PackageInfo packageInfo = new PackageInfo();
Michal Karpinski528c3e52018-02-07 17:47:10 +0000488 packageInfo.packageName = "test";
Dan Cashman5c9f527e2018-04-03 16:42:23 -0700489 packageInfo.signingInfo = null;
Bernardo Rufinocbcc34e2017-08-18 14:27:31 +0100490 packageInfo.applicationInfo = new ApplicationInfo();
Artem Iglikov23c60072017-05-04 12:13:58 +0100491
Michal Karpinski528c3e52018-02-07 17:47:10 +0000492 boolean result = AppBackupUtils.signaturesMatch(new Signature[] {SIGNATURE_1}, packageInfo,
493 mMockPackageManagerInternal);
Bernardo Rufinocbcc34e2017-08-18 14:27:31 +0100494
495 assertThat(result).isFalse();
496 }
497
498 @Test
499 public void signaturesMatch_disallowsUnsignedApps_bothSignaturesNull_returnsFalse()
500 throws Exception {
501 PackageInfo packageInfo = new PackageInfo();
Dan Cashman5c9f527e2018-04-03 16:42:23 -0700502 packageInfo.signingInfo = null;
Bernardo Rufinocbcc34e2017-08-18 14:27:31 +0100503 packageInfo.applicationInfo = new ApplicationInfo();
504
Michal Karpinski528c3e52018-02-07 17:47:10 +0000505 boolean result = AppBackupUtils.signaturesMatch(null, packageInfo,
506 mMockPackageManagerInternal);
Bernardo Rufinocbcc34e2017-08-18 14:27:31 +0100507
508 assertThat(result).isFalse();
509 }
510
511 @Test
512 public void signaturesMatch_disallowsUnsignedApps_bothSignaturesEmpty_returnsFalse()
513 throws Exception {
514 PackageInfo packageInfo = new PackageInfo();
Michal Karpinski528c3e52018-02-07 17:47:10 +0000515 packageInfo.packageName = "test";
Dan Cashman5c9f527e2018-04-03 16:42:23 -0700516 packageInfo.signingInfo = null;
Bernardo Rufinocbcc34e2017-08-18 14:27:31 +0100517 packageInfo.applicationInfo = new ApplicationInfo();
518
Michal Karpinski528c3e52018-02-07 17:47:10 +0000519 boolean result = AppBackupUtils.signaturesMatch(new Signature[0], packageInfo,
520 mMockPackageManagerInternal);
Bernardo Rufinocbcc34e2017-08-18 14:27:31 +0100521
522 assertThat(result).isFalse();
523 }
524
525 @Test
526 public void signaturesMatch_equalSignatures_returnsTrue() throws Exception {
527 Signature signature1Copy = new Signature(SIGNATURE_1.toByteArray());
528 Signature signature2Copy = new Signature(SIGNATURE_2.toByteArray());
529 Signature signature3Copy = new Signature(SIGNATURE_3.toByteArray());
Artem Iglikov23c60072017-05-04 12:13:58 +0100530
531 PackageInfo packageInfo = new PackageInfo();
Michal Karpinski528c3e52018-02-07 17:47:10 +0000532 packageInfo.packageName = "test";
Dan Cashman5c9f527e2018-04-03 16:42:23 -0700533 packageInfo.signingInfo = new SigningInfo(
534 new PackageParser.SigningDetails(
535 new Signature[] {SIGNATURE_1, SIGNATURE_2, SIGNATURE_3},
536 PackageParser.SigningDetails.SignatureSchemeVersion.SIGNING_BLOCK_V3,
537 null,
Dan Cashman5c9f527e2018-04-03 16:42:23 -0700538 null));
Artem Iglikov23c60072017-05-04 12:13:58 +0100539 packageInfo.applicationInfo = new ApplicationInfo();
540
541 boolean result = AppBackupUtils.signaturesMatch(
Michal Karpinski528c3e52018-02-07 17:47:10 +0000542 new Signature[] {signature3Copy, signature1Copy, signature2Copy}, packageInfo,
543 mMockPackageManagerInternal);
Artem Iglikov23c60072017-05-04 12:13:58 +0100544
545 assertThat(result).isTrue();
546 }
547
548 @Test
549 public void signaturesMatch_extraSignatureInTarget_returnsTrue() throws Exception {
Bernardo Rufinocbcc34e2017-08-18 14:27:31 +0100550 Signature signature1Copy = new Signature(SIGNATURE_1.toByteArray());
551 Signature signature2Copy = new Signature(SIGNATURE_2.toByteArray());
Artem Iglikov23c60072017-05-04 12:13:58 +0100552
553 PackageInfo packageInfo = new PackageInfo();
Michal Karpinski528c3e52018-02-07 17:47:10 +0000554 packageInfo.packageName = "test";
Dan Cashman5c9f527e2018-04-03 16:42:23 -0700555 packageInfo.signingInfo = new SigningInfo(
556 new PackageParser.SigningDetails(
557 new Signature[] {SIGNATURE_1, SIGNATURE_2, SIGNATURE_3},
558 PackageParser.SigningDetails.SignatureSchemeVersion.SIGNING_BLOCK_V3,
559 null,
Dan Cashman5c9f527e2018-04-03 16:42:23 -0700560 null));
Artem Iglikov23c60072017-05-04 12:13:58 +0100561 packageInfo.applicationInfo = new ApplicationInfo();
562
563 boolean result = AppBackupUtils.signaturesMatch(
Michal Karpinski528c3e52018-02-07 17:47:10 +0000564 new Signature[]{signature2Copy, signature1Copy}, packageInfo,
565 mMockPackageManagerInternal);
Artem Iglikov23c60072017-05-04 12:13:58 +0100566
567 assertThat(result).isTrue();
568 }
569
570 @Test
571 public void signaturesMatch_extraSignatureInStored_returnsFalse() throws Exception {
Bernardo Rufinocbcc34e2017-08-18 14:27:31 +0100572 Signature signature1Copy = new Signature(SIGNATURE_1.toByteArray());
573 Signature signature2Copy = new Signature(SIGNATURE_2.toByteArray());
Artem Iglikov23c60072017-05-04 12:13:58 +0100574
575 PackageInfo packageInfo = new PackageInfo();
Michal Karpinski528c3e52018-02-07 17:47:10 +0000576 packageInfo.packageName = "test";
Dan Cashman5c9f527e2018-04-03 16:42:23 -0700577 packageInfo.signingInfo = new SigningInfo(
578 new PackageParser.SigningDetails(
579 new Signature[] {signature1Copy, signature2Copy},
580 PackageParser.SigningDetails.SignatureSchemeVersion.SIGNING_BLOCK_V3,
581 null,
Dan Cashman5c9f527e2018-04-03 16:42:23 -0700582 null));
Artem Iglikov23c60072017-05-04 12:13:58 +0100583 packageInfo.applicationInfo = new ApplicationInfo();
584
585 boolean result = AppBackupUtils.signaturesMatch(
Michal Karpinski528c3e52018-02-07 17:47:10 +0000586 new Signature[]{SIGNATURE_1, SIGNATURE_2, SIGNATURE_3}, packageInfo,
587 mMockPackageManagerInternal);
Artem Iglikov23c60072017-05-04 12:13:58 +0100588
589 assertThat(result).isFalse();
590 }
591
592 @Test
593 public void signaturesMatch_oneNonMatchingSignature_returnsFalse() throws Exception {
Bernardo Rufinocbcc34e2017-08-18 14:27:31 +0100594 Signature signature1Copy = new Signature(SIGNATURE_1.toByteArray());
595 Signature signature2Copy = new Signature(SIGNATURE_2.toByteArray());
Artem Iglikov23c60072017-05-04 12:13:58 +0100596
597 PackageInfo packageInfo = new PackageInfo();
Michal Karpinski528c3e52018-02-07 17:47:10 +0000598 packageInfo.packageName = "test";
Dan Cashman5c9f527e2018-04-03 16:42:23 -0700599 packageInfo.signingInfo = new SigningInfo(
600 new PackageParser.SigningDetails(
601 new Signature[] {SIGNATURE_1, SIGNATURE_2, SIGNATURE_3},
602 PackageParser.SigningDetails.SignatureSchemeVersion.SIGNING_BLOCK_V3,
603 null,
Dan Cashman5c9f527e2018-04-03 16:42:23 -0700604 null));
Artem Iglikov23c60072017-05-04 12:13:58 +0100605 packageInfo.applicationInfo = new ApplicationInfo();
606
607 boolean result = AppBackupUtils.signaturesMatch(
Michal Karpinski528c3e52018-02-07 17:47:10 +0000608 new Signature[]{signature1Copy, signature2Copy, SIGNATURE_4}, packageInfo,
609 mMockPackageManagerInternal);
610
611 assertThat(result).isFalse();
612 }
613
614 @Test
615 public void signaturesMatch_singleStoredSignatureNoRotation_returnsTrue()
616 throws Exception {
617 Signature signature1Copy = new Signature(SIGNATURE_1.toByteArray());
618
619 PackageInfo packageInfo = new PackageInfo();
620 packageInfo.packageName = "test";
Dan Cashman5c9f527e2018-04-03 16:42:23 -0700621 packageInfo.signingInfo = new SigningInfo(
622 new PackageParser.SigningDetails(
623 new Signature[] {SIGNATURE_1},
624 PackageParser.SigningDetails.SignatureSchemeVersion.SIGNING_BLOCK_V3,
625 null,
Dan Cashman5c9f527e2018-04-03 16:42:23 -0700626 null));
Michal Karpinski528c3e52018-02-07 17:47:10 +0000627 packageInfo.applicationInfo = new ApplicationInfo();
628
629 doReturn(true).when(mMockPackageManagerInternal).isDataRestoreSafe(signature1Copy,
630 packageInfo.packageName);
631
632 boolean result = AppBackupUtils.signaturesMatch(new Signature[] {signature1Copy},
633 packageInfo, mMockPackageManagerInternal);
634
635 assertThat(result).isTrue();
636 }
637
638 @Test
639 public void signaturesMatch_singleStoredSignatureWithRotationAssumeDataCapability_returnsTrue()
640 throws Exception {
641 Signature signature1Copy = new Signature(SIGNATURE_1.toByteArray());
642
643 PackageInfo packageInfo = new PackageInfo();
644 packageInfo.packageName = "test";
Dan Cashman5c9f527e2018-04-03 16:42:23 -0700645 packageInfo.signingInfo = new SigningInfo(
646 new PackageParser.SigningDetails(
647 new Signature[] {SIGNATURE_2},
648 PackageParser.SigningDetails.SignatureSchemeVersion.SIGNING_BLOCK_V3,
649 null,
Michael Groovera117b0d2018-07-23 12:55:54 -0700650 new Signature[] {SIGNATURE_1, SIGNATURE_2}));
Michal Karpinski528c3e52018-02-07 17:47:10 +0000651 packageInfo.applicationInfo = new ApplicationInfo();
652
653 // we know signature1Copy is in history, and we want to assume it has
654 // SigningDetails.CertCapabilities.INSTALLED_DATA capability
655 doReturn(true).when(mMockPackageManagerInternal).isDataRestoreSafe(signature1Copy,
656 packageInfo.packageName);
657
658 boolean result = AppBackupUtils.signaturesMatch(new Signature[] {signature1Copy},
659 packageInfo, mMockPackageManagerInternal);
660
661 assertThat(result).isTrue();
662 }
663
664 @Test
665 public void
666 signaturesMatch_singleStoredSignatureWithRotationAssumeNoDataCapability_returnsFalse()
667 throws Exception {
668 Signature signature1Copy = new Signature(SIGNATURE_1.toByteArray());
669
670 PackageInfo packageInfo = new PackageInfo();
671 packageInfo.packageName = "test";
Dan Cashman5c9f527e2018-04-03 16:42:23 -0700672 packageInfo.signingInfo = new SigningInfo(
673 new PackageParser.SigningDetails(
674 new Signature[] {SIGNATURE_2},
675 PackageParser.SigningDetails.SignatureSchemeVersion.SIGNING_BLOCK_V3,
676 null,
Michael Groovera117b0d2018-07-23 12:55:54 -0700677 new Signature[] {SIGNATURE_1, SIGNATURE_2}));
Michal Karpinski528c3e52018-02-07 17:47:10 +0000678 packageInfo.applicationInfo = new ApplicationInfo();
679
680 // we know signature1Copy is in history, but we want to assume it does not have
681 // SigningDetails.CertCapabilities.INSTALLED_DATA capability
682 doReturn(false).when(mMockPackageManagerInternal).isDataRestoreSafe(signature1Copy,
683 packageInfo.packageName);
684
685 boolean result = AppBackupUtils.signaturesMatch(new Signature[] {signature1Copy},
686 packageInfo, mMockPackageManagerInternal);
Artem Iglikov23c60072017-05-04 12:13:58 +0100687
688 assertThat(result).isFalse();
689 }
690
Bernardo Rufinocbcc34e2017-08-18 14:27:31 +0100691 private static Signature generateSignature(byte i) {
Artem Iglikov23c60072017-05-04 12:13:58 +0100692 byte[] signatureBytes = new byte[256];
Bernardo Rufinocbcc34e2017-08-18 14:27:31 +0100693 signatureBytes[0] = i;
Artem Iglikov23c60072017-05-04 12:13:58 +0100694 return new Signature(signatureBytes);
695 }
Artem Iglikov66ff1d62017-05-03 15:06:59 +0100696}