OSDN Git Service

Merge "docs: Add documentation for equals() method" into qt-dev
[android-x86/frameworks-base.git] / services / robotests / backup / src / com / android / server / backup / testing / BackupManagerServiceTestUtils.java
1 /*
2  * Copyright (C) 2018 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.testing;
18
19 import static com.android.server.backup.testing.TestUtils.runToEndOfTasks;
20
21 import static org.mockito.ArgumentMatchers.anyBoolean;
22 import static org.mockito.Mockito.doAnswer;
23 import static org.mockito.Mockito.mock;
24 import static org.mockito.Mockito.when;
25 import static org.robolectric.Shadows.shadowOf;
26
27 import android.annotation.Nullable;
28 import android.app.Application;
29 import android.app.IActivityManager;
30 import android.content.Context;
31 import android.content.pm.PackageManager;
32 import android.os.Handler;
33 import android.os.HandlerThread;
34 import android.os.Looper;
35 import android.os.PowerManager;
36 import android.os.Process;
37 import android.util.Log;
38
39 import com.android.server.backup.BackupAgentTimeoutParameters;
40 import com.android.server.backup.Trampoline;
41 import com.android.server.backup.TransportManager;
42 import com.android.server.backup.UserBackupManagerService;
43
44 import org.mockito.stubbing.Answer;
45 import org.robolectric.shadows.ShadowApplication;
46 import org.robolectric.shadows.ShadowBinder;
47
48 import java.io.File;
49 import java.lang.Thread.UncaughtExceptionHandler;
50 import java.util.concurrent.atomic.AtomicReference;
51
52 /** Test utils for {@link UserBackupManagerService} and friends. */
53 public class BackupManagerServiceTestUtils {
54     /**
55      * Creates an instance of {@link UserBackupManagerService} with a new backup thread and runs
56      * tasks that were posted to it during instantiation.
57      *
58      * <p>If the class-under-test is going to execute methods as the system, it's a good idea to
59      * also call {@link #setUpBinderCallerAndApplicationAsSystem(Application)} before this method.
60      *
61      * @see #createUserBackupManagerServiceAndRunTasks(int, Context, HandlerThread, File, File,
62      *     TransportManager)
63      */
64     public static UserBackupManagerService createUserBackupManagerServiceAndRunTasks(
65             int userId,
66             Context context,
67             File baseStateDir,
68             File dataDir,
69             TransportManager transportManager) {
70         return createUserBackupManagerServiceAndRunTasks(
71                 userId, context, startBackupThread(null), baseStateDir, dataDir, transportManager);
72     }
73
74     /**
75      * Creates an instance of {@link UserBackupManagerService} with the supplied backup thread
76      * {@code backupThread} and runs tasks that were posted to it during instantiation.
77      *
78      * <p>If the class-under-test is going to execute methods as the system, it's a good idea to
79      * also call {@link #setUpBinderCallerAndApplicationAsSystem(Application)} before this method.
80      */
81     public static UserBackupManagerService createUserBackupManagerServiceAndRunTasks(
82             int userId,
83             Context context,
84             HandlerThread backupThread,
85             File baseStateDir,
86             File dataDir,
87             TransportManager transportManager) {
88         UserBackupManagerService backupManagerService =
89                 UserBackupManagerService.createAndInitializeService(
90                         userId,
91                         context,
92                         new Trampoline(context),
93                         backupThread,
94                         baseStateDir,
95                         dataDir,
96                         transportManager);
97         runToEndOfTasks(backupThread.getLooper());
98         return backupManagerService;
99     }
100
101     /**
102      * Sets up basic mocks for {@link UserBackupManagerService} mock. If {@code
103      * backupManagerService} is a spy, make sure you provide in the arguments the same objects that
104      * the original object uses.
105      *
106      * <p>If the class-under-test is going to execute methods as the system, it's a good idea to
107      * also call {@link #setUpBinderCallerAndApplicationAsSystem(Application)}.
108      */
109     @SuppressWarnings("ResultOfMethodCallIgnored")
110     public static void setUpBackupManagerServiceBasics(
111             UserBackupManagerService backupManagerService,
112             Application application,
113             TransportManager transportManager,
114             PackageManager packageManager,
115             Handler backupHandler,
116             PowerManager.WakeLock wakeLock,
117             BackupAgentTimeoutParameters agentTimeoutParameters) {
118
119         when(backupManagerService.getContext()).thenReturn(application);
120         when(backupManagerService.getTransportManager()).thenReturn(transportManager);
121         when(backupManagerService.getPackageManager()).thenReturn(packageManager);
122         when(backupManagerService.getBackupHandler()).thenReturn(backupHandler);
123         when(backupManagerService.getCurrentOpLock()).thenReturn(new Object());
124         when(backupManagerService.getQueueLock()).thenReturn(new Object());
125         when(backupManagerService.getActivityManager()).thenReturn(mock(IActivityManager.class));
126         when(backupManagerService.getWakelock()).thenReturn(wakeLock);
127         when(backupManagerService.getAgentTimeoutParameters()).thenReturn(agentTimeoutParameters);
128
129         AccessorMock backupEnabled = mockAccessor(false);
130         doAnswer(backupEnabled.getter).when(backupManagerService).isBackupEnabled();
131         doAnswer(backupEnabled.setter).when(backupManagerService).setBackupEnabled(anyBoolean());
132
133         AccessorMock backupRunning = mockAccessor(false);
134         doAnswer(backupEnabled.getter).when(backupManagerService).isBackupRunning();
135         doAnswer(backupRunning.setter).when(backupManagerService).setBackupRunning(anyBoolean());
136     }
137
138     public static void setUpBinderCallerAndApplicationAsSystem(Application application) {
139         final int uid = Process.SYSTEM_UID;
140         final int pid = 1211;
141         ShadowBinder.setCallingUid(uid);
142         ShadowBinder.setCallingPid(pid);
143         ShadowApplication shadowApplication = shadowOf(application);
144         shadowApplication.grantPermissions(pid, uid, "android.permission.BACKUP");
145         shadowApplication.grantPermissions(pid, uid, "android.permission.CONFIRM_FULL_BACKUP");
146     }
147
148     /**
149      * Returns one getter {@link Answer<T>} and one setter {@link Answer<T>} to be easily passed to
150      * Mockito mocking facilities.
151      *
152      * @param defaultValue Value returned by the getter if there was no setter call until then.
153      */
154     public static <T> AccessorMock<T> mockAccessor(T defaultValue) {
155         AtomicReference<T> holder = new AtomicReference<>(defaultValue);
156         return new AccessorMock<>(
157                 invocation -> holder.get(),
158                 invocation -> {
159                     holder.set(invocation.getArgument(0));
160                     return null;
161                 });
162     }
163
164     public static PowerManager.WakeLock createBackupWakeLock(Application application) {
165         PowerManager powerManager =
166                 (PowerManager) application.getSystemService(Context.POWER_SERVICE);
167         return powerManager.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "*backup*");
168     }
169
170     /**
171      * Creates a backup thread associated with a looper, starts it and returns its looper for
172      * shadowing and creation of the backup handler.
173      *
174      * <p>Note that Robolectric simulates multi-thread in a single-thread to avoid flakiness, so
175      * even though we started the thread, you should control its execution via the shadow of the
176      * looper returned.
177      *
178      * @return The {@link Looper} for the backup thread.
179      */
180     public static Looper startBackupThreadAndGetLooper() {
181         HandlerThread backupThread = new HandlerThread("backup");
182         backupThread.start();
183         return backupThread.getLooper();
184     }
185
186     /**
187      * Similar to {@link #startBackupThreadAndGetLooper()} but with a custom exception handler and
188      * returning the thread instead of the looper associated with it.
189      *
190      * @param exceptionHandler Uncaught exception handler for backup thread.
191      * @return The backup thread.
192      * @see #startBackupThreadAndGetLooper()
193      */
194     public static HandlerThread startBackupThread(
195             @Nullable UncaughtExceptionHandler exceptionHandler) {
196         HandlerThread backupThread = new HandlerThread("backup");
197         backupThread.setUncaughtExceptionHandler(exceptionHandler);
198         backupThread.start();
199         return backupThread;
200     }
201
202     /**
203      * Similar to {@link #startBackupThread(UncaughtExceptionHandler)} but logging uncaught
204      * exceptions to logcat.
205      *
206      * @param tag Tag used for logging exceptions.
207      * @return The backup thread.
208      * @see #startBackupThread(UncaughtExceptionHandler)
209      */
210     public static HandlerThread startSilentBackupThread(String tag) {
211         return startBackupThread(
212                 (thread, e) ->
213                         Log.e(tag, "Uncaught exception in test thread " + thread.getName(), e));
214     }
215
216     private BackupManagerServiceTestUtils() {}
217
218     public static class AccessorMock<T> {
219         public Answer<T> getter;
220         public Answer<T> setter;
221
222         private AccessorMock(Answer<T> getter, Answer<T> setter) {
223             this.getter = getter;
224             this.setter = setter;
225         }
226     }
227 }