1 /*
2  * Copyright (C) 2019 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 android.cts.backup;
18 
19 import android.platform.test.annotations.AppModeFull;
20 
21 import com.android.compatibility.common.util.BackupUtils;
22 import com.android.tradefed.device.DeviceNotAvailableException;
23 import com.android.tradefed.device.ITestDevice;
24 import com.android.tradefed.testtype.DeviceJUnit4ClassRunner;
25 
26 import org.junit.After;
27 import org.junit.Before;
28 import org.junit.Test;
29 import org.junit.runner.RunWith;
30 
31 import java.util.Optional;
32 
33 /** Test the backup and restore flow for a key-value app in a profile. */
34 @RunWith(DeviceJUnit4ClassRunner.class)
35 @AppModeFull
36 public class ProfileKeyValueBackupRestoreHostSideTest extends BaseMultiUserBackupHostSideTest {
37     private static final String TAG = "ProfileKeyValueBackupRestoreHostSideTest";
38     private static final String LOGCAT_FILTER = "BackupManagerService:* " + TAG + ":* *:S";
39     private static final String RESTOREATINSTALL_LOG =
40             "restoreAtInstall pkg=" + KEY_VALUE_TEST_PACKAGE;
41     private static final String RESTORECOMPLETE_LOG = "Restore complete";
42     private static final int TIMEOUT_FOR_RESTOREATINSTALL_SECONDS = 30;
43 
44     private final BackupUtils mBackupUtils = getBackupUtils();
45     private ITestDevice mDevice;
46     private int mParentUserId;
47     private Optional<Integer> mProfileUserId = Optional.empty();
48     private String mTransport;
49 
50     /** Create the profile, switch to the local transport and setup the test package. */
51     @Before
52     @Override
setUp()53     public void setUp() throws Exception {
54         mDevice = getDevice();
55         super.setUp();
56 
57         // Create profile user.
58         mParentUserId = mDevice.getCurrentUser();
59         int profileUserId = createProfileUser(mParentUserId, "Profile-KV");
60         mProfileUserId = Optional.of(profileUserId);
61         startUserAndInitializeForBackup(profileUserId);
62 
63         // Switch to local transport.
64         mTransport = switchUserToLocalTransportAndAssertSuccess(profileUserId);
65 
66         // Setup test package.
67         installPackageAsUser(KEY_VALUE_APK, profileUserId);
68         clearPackageDataAsUser(KEY_VALUE_TEST_PACKAGE, profileUserId);
69     }
70 
71     /** Uninstall the test package and remove the profile. */
72     @After
73     @Override
tearDown()74     public void tearDown() throws Exception {
75         if (mProfileUserId.isPresent()) {
76             int profileUserId = mProfileUserId.get();
77             if (mTransport != null) {
78                 clearBackupDataInTransportForUser(
79                         KEY_VALUE_TEST_PACKAGE, mTransport, profileUserId);
80             }
81             uninstallPackageAsUser(KEY_VALUE_TEST_PACKAGE, profileUserId);
82             mDevice.removeUser(profileUserId);
83             mProfileUserId = Optional.empty();
84         }
85         super.tearDown();
86     }
87 
88     /**
89      * Tests key-value app backup and restore in the profile user.
90      *
91      * <ol>
92      *   <li>App writes shared preferences.
93      *   <li>Force a backup.
94      *   <li>Uninstall the app.
95      *   <li>Install the app to perform a restore-at-install operation.
96      *   <li>Check that the shared preferences are restored.
97      * </ol>
98      */
99     @Test
testKeyValueBackupAndRestore()100     public void testKeyValueBackupAndRestore() throws Exception {
101         int profileUserId = mProfileUserId.get();
102         checkDeviceTest("assertSharedPrefsIsEmpty");
103         checkDeviceTest("writeSharedPrefsAndAssertSuccess");
104 
105         mBackupUtils.backupNowAndAssertSuccessForUser(KEY_VALUE_TEST_PACKAGE, profileUserId);
106 
107         uninstallPackageAsUser(KEY_VALUE_TEST_PACKAGE, profileUserId);
108 
109         installPackageAsUser(KEY_VALUE_APK, profileUserId);
110 
111         checkDeviceTest("assertSharedPrefsRestored");
112     }
113 
114     /**
115      * Tests key-value app backup and restore in the profile user, when the app is already installed
116      * for another user. This test parses logcat to assert that the asynchronous restore-at-install
117      * operation has completed.
118      *
119      * <ol>
120      *   <li>App writes shared preferences.
121      *   <li>Force a backup.
122      *   <li>Uninstall the app.
123      *   <li>Install the app for parent user.
124      *   <li>Install the app, which now already exists in parent user, for profile user to perform a
125      *       restore-at-install operation. This fires off asynchronous restore and returns before
126      *       the restore operation has finished.
127      *   <li>Assert that restore has finished via logcat.
128      *   <li>Check that the shared preferences are restored.
129      * </ol>
130      */
131     @Test
testKeyValueBackupAndRestoreForInstallExistingPackage()132     public void testKeyValueBackupAndRestoreForInstallExistingPackage() throws Exception {
133         int profileUserId = mProfileUserId.get();
134         checkDeviceTest("assertSharedPrefsIsEmpty");
135         checkDeviceTest("writeSharedPrefsAndAssertSuccess");
136 
137         mBackupUtils.backupNowAndAssertSuccessForUser(KEY_VALUE_TEST_PACKAGE, profileUserId);
138 
139         uninstallPackageAsUser(KEY_VALUE_TEST_PACKAGE, profileUserId);
140 
141         installPackageAsUser(KEY_VALUE_APK, mParentUserId);
142         String mark = mLogcatInspector.mark(TAG);
143         installExistingPackageAsUser(KEY_VALUE_TEST_PACKAGE, profileUserId);
144 
145         // Check logs for success.
146         mLogcatInspector.assertLogcatContainsInOrder(
147                 LOGCAT_FILTER,
148                 TIMEOUT_FOR_RESTOREATINSTALL_SECONDS,
149                 mark,
150                 RESTOREATINSTALL_LOG,
151                 RESTORECOMPLETE_LOG);
152 
153         checkDeviceTest("assertSharedPrefsRestored");
154         uninstallPackageAsUser(KEY_VALUE_TEST_PACKAGE, mParentUserId);
155     }
156 
157     /**
158      * Tests key-value app backup and restore in the profile user, when the app is already installed
159      * for another user. This test waits for an intent to be sent from the asynchronous restore
160      * operation to signal that the restore-at-install operation has completed.
161      *
162      * <ol>
163      *   <li>App writes shared preferences.
164      *   <li>Force a backup.
165      *   <li>Uninstall the app.
166      *   <li>Install the app for parent user.
167      *   <li>Install the app, which now already exists in parent user, for profile user to perform a
168      *   restore-at-install operation. This fires off asynchronous restore and waits for an intent
169      *   which is sent when the restore operation has completed.
170      *   <li>Check that the shared preferences are restored.
171      * </ol>
172      */
173     @Test
testKeyValueBackupAndRestoreForInstallExistingPackageWaitTillComplete()174     public void testKeyValueBackupAndRestoreForInstallExistingPackageWaitTillComplete()
175         throws Exception {
176         int profileUserId = mProfileUserId.get();
177         checkDeviceTest("assertSharedPrefsIsEmpty");
178         checkDeviceTest("writeSharedPrefsAndAssertSuccess");
179 
180         mBackupUtils.backupNowAndAssertSuccessForUser(KEY_VALUE_TEST_PACKAGE, profileUserId);
181 
182         uninstallPackageAsUser(KEY_VALUE_TEST_PACKAGE, profileUserId);
183 
184         installPackageAsUser(KEY_VALUE_APK, mParentUserId);
185         installExistingPackageAsUserWaitTillComplete(KEY_VALUE_TEST_PACKAGE, profileUserId);
186 
187         checkDeviceTest("assertSharedPrefsRestored");
188         uninstallPackageAsUser(KEY_VALUE_TEST_PACKAGE, mParentUserId);
189     }
190 
checkDeviceTest(String methodName)191     private void checkDeviceTest(String methodName) throws DeviceNotAvailableException {
192         checkDeviceTestAsUser(
193                 KEY_VALUE_TEST_PACKAGE,
194                 KEY_VALUE_DEVICE_TEST_NAME,
195                 methodName,
196                 mProfileUserId.get());
197     }
198 }
199