1 /*
2  * Copyright (C) 2021 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.bedstead.testapp;
18 
19 import android.accounts.AccountManager;
20 import android.app.Activity;
21 import android.app.AppComponentFactory;
22 import android.app.Service;
23 import android.app.admin.DevicePolicyManager;
24 import android.content.BroadcastReceiver;
25 import android.content.ContentResolver;
26 import android.content.Context;
27 import android.content.Intent;
28 import android.content.pm.CrossProfileApps;
29 import android.content.pm.LauncherApps;
30 import android.content.pm.PackageManager;
31 import android.net.wifi.WifiManager;
32 import android.os.HardwarePropertiesManager;
33 import android.os.UserManager;
34 import android.security.KeyChain;
35 import android.util.Log;
36 
37 import com.android.bedstead.testapp.processor.annotations.FrameworkClass;
38 import com.android.bedstead.testapp.processor.annotations.TestAppReceiver;
39 
40 /**
41  * An {@link AppComponentFactory} which redirects invalid class names to premade TestApp classes.
42  */
43 @TestAppReceiver(
44         frameworkClasses = {
45                 @FrameworkClass(frameworkClass = DevicePolicyManager.class, constructor = "context.getSystemService(android.app.admin.DevicePolicyManager.class)"),
46                 @FrameworkClass(frameworkClass = HardwarePropertiesManager.class, constructor = "context.getSystemService(android.os.HardwarePropertiesManager.class)"),
47                 @FrameworkClass(frameworkClass = UserManager.class, constructor = "context.getSystemService(android.os.UserManager.class)"),
48                 @FrameworkClass(frameworkClass = WifiManager.class, constructor = "context.getSystemService(android.net.wifi.WifiManager.class)"),
49                 @FrameworkClass(frameworkClass = PackageManager.class, constructor = "context.getPackageManager()"),
50                 @FrameworkClass(frameworkClass = CrossProfileApps.class, constructor = "context.getSystemService(android.content.pm.CrossProfileApps.class)"),
51                 @FrameworkClass(frameworkClass = LauncherApps.class, constructor = "context.getSystemService(android.content.pm.LauncherApps.class)"),
52                 @FrameworkClass(frameworkClass = AccountManager.class, constructor = "context.getSystemService(android.accounts.AccountManager.class)"),
53                 @FrameworkClass(frameworkClass = Context.class, constructor = "context"),
54                 @FrameworkClass(frameworkClass = ContentResolver.class, constructor = "context.getContentResolver()"),
55                 @FrameworkClass(frameworkClass = KeyChain.class, constructor = "null") // KeyChain can not be instantiated - all calls are static
56         }
57 )
58 public final class TestAppAppComponentFactory extends AppComponentFactory {
59 
60     private static final String LOG_TAG = "TestAppACF";
61 
62     @Override
instantiateActivity(ClassLoader classLoader, String className, Intent intent)63     public Activity instantiateActivity(ClassLoader classLoader, String className, Intent intent)
64             throws InstantiationException, IllegalAccessException, ClassNotFoundException {
65 
66         try {
67             return super.instantiateActivity(classLoader, className, intent);
68         } catch (ClassNotFoundException e) {
69             Log.d(LOG_TAG,
70                     "Activity class (" + className + ") not found, routing to TestAppActivity");
71             BaseTestAppActivity activity =
72                     (BaseTestAppActivity) super.instantiateActivity(
73                             classLoader, BaseTestAppActivity.class.getName(), intent);
74             activity.setOverrideActivityClassName(className);
75             return activity;
76         }
77     }
78 
79     @Override
instantiateReceiver(ClassLoader classLoader, String className, Intent intent)80     public BroadcastReceiver instantiateReceiver(ClassLoader classLoader, String className,
81             Intent intent)
82             throws InstantiationException, IllegalAccessException, ClassNotFoundException {
83         try {
84             return super.instantiateReceiver(classLoader, className, intent);
85         } catch (ClassNotFoundException e) {
86 
87             if (className.endsWith("DeviceAdminReceiver")) {
88                 Log.d(LOG_TAG, "Broadcast Receiver class (" + className
89                         + ") not found, routing to TestAppDeviceAdminReceiver");
90                 BaseTestAppDeviceAdminReceiver receiver = (BaseTestAppDeviceAdminReceiver)
91                         super.instantiateReceiver(
92                                 classLoader, BaseTestAppDeviceAdminReceiver.class.getName(),
93                                 intent);
94                 receiver.setOverrideDeviceAdminReceiverClassName(className);
95                 return receiver;
96             }
97 
98             Log.d(LOG_TAG, "Broadcast Receiver class (" + className
99                     + ") not found, routing to TestAppBroadcastReceiver");
100             BaseTestAppBroadcastReceiver receiver = (BaseTestAppBroadcastReceiver)
101                     super.instantiateReceiver(
102                             classLoader, BaseTestAppBroadcastReceiver.class.getName(), intent);
103             receiver.setOverrideBroadcastReceiverClassName(className);
104             return receiver;
105         }
106     }
107 
108     @Override
instantiateService(ClassLoader classLoader, String className, Intent intent)109     public Service instantiateService(ClassLoader classLoader, String className, Intent intent)
110             throws InstantiationException, IllegalAccessException, ClassNotFoundException {
111         try {
112             return super.instantiateService(classLoader, className, intent);
113         } catch (ClassNotFoundException e) {
114             if (className.endsWith("AccountAuthenticatorService")) {
115                 Log.d(LOG_TAG, "Service class (" + className
116                         + ") not found, routing to TestAppAccountAuthenticatorService");
117                 return super.instantiateService(
118                         classLoader,
119                         TestAppAccountAuthenticatorService.class.getName(),
120                         intent);
121             } else {
122                 throw e;
123             }
124         }
125     }
126 }
127