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.NotificationManager;
23 import android.app.Service;
24 import android.app.WallpaperManager;
25 import android.app.admin.DevicePolicyManager;
26 import android.bluetooth.BluetoothAdapter;
27 import android.bluetooth.BluetoothManager;
28 import android.content.BroadcastReceiver;
29 import android.content.ContentResolver;
30 import android.content.Context;
31 import android.content.Intent;
32 import android.content.RestrictionsManager;
33 import android.content.pm.CrossProfileApps;
34 import android.content.pm.LauncherApps;
35 import android.content.pm.PackageManager;
36 import android.media.projection.MediaProjectionManager;
37 import android.net.wifi.WifiManager;
38 import android.os.HardwarePropertiesManager;
39 import android.os.UserManager;
40 import android.security.KeyChain;
41 import android.telecom.TelecomManager;
42 import android.telephony.SmsManager;
43 import android.telephony.TelephonyManager;
44 import android.telephony.euicc.EuiccManager;
45 import android.util.Log;
46 
47 import com.android.bedstead.testapp.processor.annotations.FrameworkClass;
48 import com.android.bedstead.testapp.processor.annotations.TestAppReceiver;
49 import com.android.eventlib.premade.EventLibService;
50 
51 /**
52  * An {@link AppComponentFactory} which redirects invalid class names to premade TestApp classes.
53  */
54 @TestAppReceiver(
55         frameworkClasses = {
56             @FrameworkClass(
57                     frameworkClass = DevicePolicyManager.class,
58                     constructor =
59                             "context.getSystemService(android.app.admin.DevicePolicyManager.class)"),
60             @FrameworkClass(
61                     frameworkClass = HardwarePropertiesManager.class,
62                     constructor =
63                             "context.getSystemService(android.os.HardwarePropertiesManager.class)"),
64             @FrameworkClass(
65                     frameworkClass = UserManager.class,
66                     constructor = "context" + ".getSystemService(android.os.UserManager.class)"),
67             @FrameworkClass(
68                     frameworkClass = WifiManager.class,
69                     constructor =
70                             "context" + ".getSystemService(android.net.wifi.WifiManager.class)"),
71             @FrameworkClass(
72                     frameworkClass = PackageManager.class,
73                     constructor = "context" + ".getPackageManager()"),
74             @FrameworkClass(
75                     frameworkClass = CrossProfileApps.class,
76                     constructor =
77                             "context.getSystemService(android.content.pm.CrossProfileApps.class)"),
78             @FrameworkClass(
79                     frameworkClass = LauncherApps.class,
80                     constructor =
81                             "context" + ".getSystemService(android.content.pm.LauncherApps.class)"),
82             @FrameworkClass(
83                     frameworkClass = AccountManager.class,
84                     constructor =
85                             "context" + ".getSystemService(android.accounts.AccountManager.class)"),
86             @FrameworkClass(frameworkClass = Context.class, constructor = "context"),
87             @FrameworkClass(
88                     frameworkClass = ContentResolver.class,
89                     constructor = "context" + ".getContentResolver()"),
90             @FrameworkClass(
91                     frameworkClass = BluetoothManager.class,
92                     constructor =
93                             "context.getSystemService(android.bluetooth.BluetoothManager.class)"),
94             @FrameworkClass(
95                     frameworkClass = BluetoothAdapter.class,
96                     constructor =
97                             "context"
98                                     + ".getSystemService(android.bluetooth.BluetoothManager.class)"
99                                     + ".getAdapter()"),
100             @FrameworkClass(frameworkClass = KeyChain.class, constructor = "null"),
101             // KeyChain can not be instantiated - all calls are static
102             @FrameworkClass(
103                     frameworkClass = NotificationManager.class,
104                     constructor =
105                             "context.getSystemService(android.app.NotificationManager.class)"),
106             @FrameworkClass(
107                     frameworkClass = TelecomManager.class,
108                     constructor = "context.getSystemService(android.telecom.TelecomManager.class)"),
109             @FrameworkClass(
110                     frameworkClass = RestrictionsManager.class,
111                     constructor =
112                             "context.getSystemService(android.content.RestrictionsManager.class)"),
113             @FrameworkClass(
114                     frameworkClass = SmsManager.class,
115                     constructor = "context.getSystemService(android.telephony.SmsManager.class)"),
116             @FrameworkClass(
117                     frameworkClass = WallpaperManager.class,
118                     constructor = "context.getSystemService(android.app.WallpaperManager.class)"),
119             @FrameworkClass(
120                     frameworkClass = TelephonyManager.class,
121                     constructor =
122                             "context.getSystemService(android.telephony.TelephonyManager.class)"),
123             @FrameworkClass(
124                     frameworkClass = EuiccManager.class,
125                     constructor =
126                             "context.getSystemService(android.telephony.euicc.EuiccManager.class)"),
127             @FrameworkClass(
128                     frameworkClass = MediaProjectionManager.class,
129                     constructor =
130                             "context.getSystemService(android.media.projection."
131                                     + "MediaProjectionManager.class)")
132         })
133 public final class TestAppAppComponentFactory extends AppComponentFactory {
134 
135     private static final String LOG_TAG = "TestAppACF";
136 
137     @Override
instantiateActivity(ClassLoader classLoader, String className, Intent intent)138     public Activity instantiateActivity(ClassLoader classLoader, String className, Intent intent)
139             throws InstantiationException, IllegalAccessException, ClassNotFoundException {
140         Log.e(LOG_TAG, "Initiating activity for class "
141                 + className + " and intent " + intent);
142         try {
143             return super.instantiateActivity(classLoader, className, intent);
144         } catch (ClassNotFoundException e) {
145             Log.d(LOG_TAG,
146                     "Activity class (" + className + ") not found, routing to TestAppActivity");
147             BaseTestAppActivity activity =
148                     (BaseTestAppActivity) super.instantiateActivity(
149                             classLoader, BaseTestAppActivity.class.getName(), intent);
150             activity.setOverrideActivityClassName(className);
151             return activity;
152         }
153     }
154 
155     @Override
instantiateReceiver(ClassLoader classLoader, String className, Intent intent)156     public BroadcastReceiver instantiateReceiver(ClassLoader classLoader, String className,
157             Intent intent)
158             throws InstantiationException, IllegalAccessException, ClassNotFoundException {
159         Log.e(LOG_TAG, "Initiating receiver for class "
160                 + className + " and intent " + intent);
161         try {
162             return super.instantiateReceiver(classLoader, className, intent);
163         } catch (ClassNotFoundException e) {
164             if (className.endsWith("DeviceAdminReceiver")) {
165                 Log.d(LOG_TAG, "Broadcast Receiver class (" + className
166                         + ") not found, routing to TestAppDeviceAdminReceiver");
167                 BaseTestAppDeviceAdminReceiver receiver = (BaseTestAppDeviceAdminReceiver)
168                         super.instantiateReceiver(
169                                 classLoader, BaseTestAppDeviceAdminReceiver.class.getName(),
170                                 intent);
171                 receiver.setOverrideDeviceAdminReceiverClassName(className);
172                 return receiver;
173             } else if (className.endsWith("DelegatedAdminReceiver")) {
174                 Log.d(LOG_TAG, "Broadcast Receiver class (" + className
175                         + ") not found, routing to TestAppDelegatedAdminReceiver");
176                 BaseTestAppDelegatedAdminReceiver receiver = (BaseTestAppDelegatedAdminReceiver)
177                         super.instantiateReceiver(
178                                 classLoader, BaseTestAppDelegatedAdminReceiver.class.getName(),
179                                 intent);
180                 receiver.setOverrideDelegatedAdminReceiverClassName(className);
181                 return receiver;
182             }
183 
184             Log.d(LOG_TAG, "Broadcast Receiver class (" + className
185                     + ") not found, routing to TestAppBroadcastReceiver");
186             BaseTestAppBroadcastReceiver receiver = (BaseTestAppBroadcastReceiver)
187                     super.instantiateReceiver(
188                             classLoader, BaseTestAppBroadcastReceiver.class.getName(), intent);
189             receiver.setOverrideBroadcastReceiverClassName(className);
190             return receiver;
191         }
192     }
193 
194     @Override
instantiateService(ClassLoader classLoader, String className, Intent intent)195     public Service instantiateService(ClassLoader classLoader, String className, Intent intent)
196             throws InstantiationException, IllegalAccessException, ClassNotFoundException {
197         Log.e(LOG_TAG, "Initiating service for class "
198                 + className + " and intent " + intent);
199         try {
200             return super.instantiateService(classLoader, className, intent);
201         } catch (ClassNotFoundException e) {
202             if (className.endsWith("AccountAuthenticatorService")) {
203                 Log.d(LOG_TAG, "Service class (" + className
204                         + ") not found, routing to TestAppAccountAuthenticatorService");
205                 return super.instantiateService(
206                         classLoader,
207                         TestAppAccountAuthenticatorService.class.getName(),
208                         intent);
209             } else if (className.endsWith("ContentSuggestionsService")) {
210                 Log.d(LOG_TAG, "Service class (" + className
211                         + ") not found, routing to BaseTestAppContentSuggestionsService");
212                 BaseTestAppContentSuggestionsService service =
213                         (BaseTestAppContentSuggestionsService)
214                                 super.instantiateService(
215                                         classLoader,
216                                         BaseTestAppContentSuggestionsService.class.getName(),
217                                         intent);
218                 service.setOverrideServiceClassName(className);
219                 return service;
220             }
221 
222             if (className.endsWith("CredentialProviderService")) {
223                 Log.d(LOG_TAG, "Service class (" + className
224                         + ") not found, routing to BaseTestAppCredentialProviderService");
225                 return super.instantiateService(
226                         classLoader,
227                         BaseTestAppCredentialProviderService.class.getName(),
228                         intent);
229             }
230 
231             Log.d(LOG_TAG,
232                     "Service class (" + className + ") not found, routing to EventLibService");
233             EventLibService service =
234                     (EventLibService) super.instantiateService(
235                             classLoader, EventLibService.class.getName(), intent);
236             service.setOverrideServiceClassName(className);
237             return service;
238         }
239     }
240 }
241