1/*
2 * Copyright (C) 2015 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 */
16package com.android.server.devicepolicy;
17
18import android.app.IActivityManager;
19import android.app.NotificationManager;
20import android.app.backup.IBackupManager;
21import android.content.pm.IPackageManager;
22import android.content.pm.PackageManagerInternal;
23import android.database.ContentObserver;
24import android.media.IAudioService;
25import android.net.Uri;
26import android.os.Looper;
27import android.os.PowerManagerInternal;
28import android.os.UserHandle;
29import android.os.UserManager;
30import android.os.UserManagerInternal;
31import android.telephony.TelephonyManager;
32import android.util.ArrayMap;
33import android.util.Pair;
34import android.view.IWindowManager;
35
36import com.android.internal.widget.LockPatternUtils;
37
38import java.io.File;
39import java.util.Map;
40
41/**
42 * Overrides {@link #DevicePolicyManagerService} for dependency injection.
43 */
44public class DevicePolicyManagerServiceTestable extends DevicePolicyManagerService {
45    /**
46     * Overrides {@link #Owners} for dependency injection.
47     */
48    public static class OwnersTestable extends Owners {
49        public static final String LEGACY_FILE = "legacy.xml";
50        public static final String DEVICE_OWNER_FILE = "device_owner2.xml";
51        public static final String PROFILE_OWNER_FILE_BASE = "profile_owner.xml";
52
53        private final File mLegacyFile;
54        private final File mDeviceOwnerFile;
55        private final File mProfileOwnerBase;
56
57        public OwnersTestable(DpmMockContext context) {
58            super(context.userManager, context.userManagerInternal, context.packageManagerInternal);
59            mLegacyFile = new File(context.dataDir, LEGACY_FILE);
60            mDeviceOwnerFile = new File(context.dataDir, DEVICE_OWNER_FILE);
61            mProfileOwnerBase = new File(context.dataDir, PROFILE_OWNER_FILE_BASE);
62        }
63
64        @Override
65        File getLegacyConfigFileWithTestOverride() {
66            return mLegacyFile;
67        }
68
69        @Override
70        File getDeviceOwnerFileWithTestOverride() {
71            return mDeviceOwnerFile;
72        }
73
74        @Override
75        File getProfileOwnerFileWithTestOverride(int userId) {
76            return new File(mDeviceOwnerFile.getAbsoluteFile() + "-" + userId);
77        }
78    }
79
80    public final DpmMockContext context;
81    private final MockInjector mMockInjector;
82
83    public DevicePolicyManagerServiceTestable(DpmMockContext context, File dataDir) {
84        this(new MockInjector(context, dataDir));
85    }
86
87    private DevicePolicyManagerServiceTestable(MockInjector injector) {
88        super(injector);
89        mMockInjector = injector;
90        this.context = injector.context;
91    }
92
93
94    public void notifyChangeToContentObserver(Uri uri, int userHandle) {
95        ContentObserver co = mMockInjector.mContentObservers
96                .get(new Pair<Uri, Integer>(uri, userHandle));
97        if (co != null) {
98            co.onChange(false, uri, userHandle); // notify synchronously
99        }
100
101        // Notify USER_ALL observer too.
102        co = mMockInjector.mContentObservers
103                .get(new Pair<Uri, Integer>(uri, UserHandle.USER_ALL));
104        if (co != null) {
105            co.onChange(false, uri, userHandle); // notify synchronously
106        }
107    }
108
109
110    private static class MockInjector extends Injector {
111
112        public final DpmMockContext context;
113
114        public final File dataDir;
115
116        // Key is a pair of uri and userId
117        private final Map<Pair<Uri, Integer>, ContentObserver> mContentObservers = new ArrayMap<>();
118
119        private MockInjector(DpmMockContext context, File dataDir) {
120            super(context);
121            this.context = context;
122            this.dataDir = dataDir;
123        }
124
125        @Override
126        Owners newOwners() {
127            return new OwnersTestable(context);
128        }
129
130        @Override
131        UserManager getUserManager() {
132            return context.userManager;
133        }
134
135        @Override
136        UserManagerInternal getUserManagerInternal() {
137            return context.userManagerInternal;
138        }
139
140        @Override
141        PackageManagerInternal getPackageManagerInternal() {
142            return context.packageManagerInternal;
143        }
144
145        @Override
146        PowerManagerInternal getPowerManagerInternal() {
147            return context.powerManagerInternal;
148        }
149
150        @Override
151        NotificationManager getNotificationManager() {
152            return context.notificationManager;
153        }
154
155        @Override
156        IWindowManager getIWindowManager() {
157            return context.iwindowManager;
158        }
159
160        @Override
161        IActivityManager getIActivityManager() {
162            return context.iactivityManager;
163        }
164
165        @Override
166        IPackageManager getIPackageManager() {
167            return context.ipackageManager;
168        }
169
170        @Override
171        IBackupManager getIBackupManager() {
172            return context.ibackupManager;
173        }
174
175        @Override
176        IAudioService getIAudioService() {
177            return context.iaudioService;
178        }
179
180        @Override
181        Looper getMyLooper() {
182            return Looper.getMainLooper();
183        }
184
185        @Override
186        LockPatternUtils newLockPatternUtils() {
187            return context.lockPatternUtils;
188        }
189
190        @Override
191        boolean storageManagerIsFileBasedEncryptionEnabled() {
192            return context.storageManager.isFileBasedEncryptionEnabled();
193        }
194
195        @Override
196        boolean storageManagerIsNonDefaultBlockEncrypted() {
197            return context.storageManager.isNonDefaultBlockEncrypted();
198        }
199
200        @Override
201        boolean storageManagerIsEncrypted() {
202            return context.storageManager.isEncrypted();
203        }
204
205        @Override
206        boolean storageManagerIsEncryptable() {
207            return context.storageManager.isEncryptable();
208        }
209
210        @Override
211        String getDevicePolicyFilePathForSystemUser() {
212            return context.systemUserDataDir.getAbsolutePath() + "/";
213        }
214
215        @Override
216        long binderClearCallingIdentity() {
217            return context.binder.clearCallingIdentity();
218        }
219
220        @Override
221        void binderRestoreCallingIdentity(long token) {
222            context.binder.restoreCallingIdentity(token);
223        }
224
225        @Override
226        int binderGetCallingUid() {
227            return context.binder.getCallingUid();
228        }
229
230        @Override
231        int binderGetCallingPid() {
232            return context.binder.getCallingPid();
233        }
234
235        @Override
236        UserHandle binderGetCallingUserHandle() {
237            return context.binder.getCallingUserHandle();
238        }
239
240        @Override
241        boolean binderIsCallingUidMyUid() {
242            return context.binder.isCallerUidMyUid();
243        }
244
245        @Override
246        File environmentGetUserSystemDirectory(int userId) {
247            return context.environment.getUserSystemDirectory(userId);
248        }
249
250        @Override
251        void powerManagerGoToSleep(long time, int reason, int flags) {
252            context.powerManager.goToSleep(time, reason, flags);
253        }
254
255        @Override
256        void powerManagerReboot(String reason) {
257            context.powerManager.reboot(reason);
258        }
259
260        @Override
261        boolean systemPropertiesGetBoolean(String key, boolean def) {
262            return context.systemProperties.getBoolean(key, def);
263        }
264
265        @Override
266        long systemPropertiesGetLong(String key, long def) {
267            return context.systemProperties.getLong(key, def);
268        }
269
270        @Override
271        String systemPropertiesGet(String key, String def) {
272            return context.systemProperties.get(key, def);
273        }
274
275        @Override
276        String systemPropertiesGet(String key) {
277            return context.systemProperties.get(key);
278        }
279
280        @Override
281        void systemPropertiesSet(String key, String value) {
282            context.systemProperties.set(key, value);
283        }
284
285        @Override
286        boolean userManagerIsSplitSystemUser() {
287            return context.userManagerForMock.isSplitSystemUser();
288        }
289
290        @Override
291        void registerContentObserver(Uri uri, boolean notifyForDescendents,
292                ContentObserver observer, int userHandle) {
293            mContentObservers.put(new Pair<Uri, Integer>(uri, userHandle), observer);
294        }
295
296        @Override
297        int settingsSecureGetIntForUser(String name, int def, int userHandle) {
298            return context.settings.settingsSecureGetIntForUser(name, def, userHandle);
299        }
300
301        @Override
302        void settingsSecurePutIntForUser(String name, int value, int userHandle) {
303            context.settings.settingsSecurePutIntForUser(name, value, userHandle);
304        }
305
306        @Override
307        void settingsSecurePutStringForUser(String name, String value, int userHandle) {
308            context.settings.settingsSecurePutStringForUser(name, value, userHandle);
309        }
310
311        @Override
312        void settingsGlobalPutStringForUser(String name, String value, int userHandle) {
313            context.settings.settingsGlobalPutStringForUser(name, value, userHandle);
314        }
315
316        @Override
317        void settingsSecurePutInt(String name, int value) {
318            context.settings.settingsSecurePutInt(name, value);
319        }
320
321        @Override
322        void settingsGlobalPutInt(String name, int value) {
323            context.settings.settingsGlobalPutInt(name, value);
324        }
325
326        @Override
327        void settingsSecurePutString(String name, String value) {
328            context.settings.settingsSecurePutString(name, value);
329        }
330
331        @Override
332        void settingsGlobalPutString(String name, String value) {
333            context.settings.settingsGlobalPutString(name, value);
334        }
335
336        @Override
337        int settingsGlobalGetInt(String name, int def) {
338            return context.settings.settingsGlobalGetInt(name, def);
339        }
340
341        @Override
342        void securityLogSetLoggingEnabledProperty(boolean enabled) {
343            context.settings.securityLogSetLoggingEnabledProperty(enabled);
344        }
345
346        @Override
347        boolean securityLogGetLoggingEnabledProperty() {
348            return context.settings.securityLogGetLoggingEnabledProperty();
349        }
350
351        @Override
352        boolean securityLogIsLoggingEnabled() {
353            return context.settings.securityLogIsLoggingEnabled();
354        }
355
356        @Override
357        TelephonyManager getTelephonyManager() {
358            return context.telephonyManager;
359        }
360    }
361}
362