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 package android.net.wifi;
17 
18 import android.annotation.SystemApi;
19 import android.app.SystemServiceRegistry;
20 import android.content.Context;
21 import android.net.wifi.aware.IWifiAwareManager;
22 import android.net.wifi.aware.WifiAwareManager;
23 import android.net.wifi.p2p.IWifiP2pManager;
24 import android.net.wifi.p2p.WifiP2pManager;
25 import android.net.wifi.rtt.IWifiRttManager;
26 import android.net.wifi.rtt.WifiRttManager;
27 import android.os.HandlerThread;
28 import android.os.Looper;
29 
30 /**
31  * Class for performing registration for all Wifi services.
32  *
33  * @hide
34  */
35 @SystemApi
36 public class WifiFrameworkInitializer {
37 
38     /**
39      * A class implementing the lazy holder idiom: the unique static instance
40      * of {@link #INSTANCE} is instantiated in a thread-safe way (guaranteed by
41      * the language specs) the first time that NoPreloadHolder is referenced in getInstanceLooper().
42      *
43      * This is necessary because we can't spawn a new thread in {@link #registerServiceWrappers()}.
44      * {@link #registerServiceWrappers()} is called during the Zygote phase, which disallows
45      * spawning new threads. Naming the class "NoPreloadHolder" ensures that the classloader will
46      * not preload this class, inadvertently spawning the thread too early.
47      */
48     private static class NoPreloadHolder {
49         private static final HandlerThread INSTANCE = createInstance();
50 
createInstance()51         private static HandlerThread createInstance() {
52             HandlerThread thread = new HandlerThread("WifiManagerThread");
53             thread.start();
54             return thread;
55         }
56     }
57 
getInstanceLooper()58     private static Looper getInstanceLooper() {
59         return NoPreloadHolder.INSTANCE.getLooper();
60     }
61 
WifiFrameworkInitializer()62     private WifiFrameworkInitializer() {}
63 
64     /**
65      * Called by {@link SystemServiceRegistry}'s static initializer and registers all Wifi services
66      * to {@link Context}, so that {@link Context#getSystemService} can return them.
67      *
68      * @throws IllegalStateException if this is called from anywhere besides
69      * {@link SystemServiceRegistry}
70      */
registerServiceWrappers()71     public static void registerServiceWrappers() {
72         SystemServiceRegistry.registerContextAwareService(
73                 Context.WIFI_SERVICE,
74                 WifiManager.class,
75                 (context, serviceBinder) -> {
76                     IWifiManager service = IWifiManager.Stub.asInterface(serviceBinder);
77                     return new WifiManager(context, service, getInstanceLooper());
78                 }
79         );
80         SystemServiceRegistry.registerStaticService(
81                 Context.WIFI_P2P_SERVICE,
82                 WifiP2pManager.class,
83                 serviceBinder -> {
84                     IWifiP2pManager service = IWifiP2pManager.Stub.asInterface(serviceBinder);
85                     return new WifiP2pManager(service);
86                 }
87         );
88         SystemServiceRegistry.registerContextAwareService(
89                 Context.WIFI_AWARE_SERVICE,
90                 WifiAwareManager.class,
91                 (context, serviceBinder) -> {
92                     IWifiAwareManager service = IWifiAwareManager.Stub.asInterface(serviceBinder);
93                     return new WifiAwareManager(context, service);
94                 }
95         );
96         SystemServiceRegistry.registerContextAwareService(
97                 Context.WIFI_SCANNING_SERVICE,
98                 WifiScanner.class,
99                 (context, serviceBinder) -> {
100                     IWifiScanner service = IWifiScanner.Stub.asInterface(serviceBinder);
101                     return new WifiScanner(context, service, getInstanceLooper());
102                 }
103         );
104         SystemServiceRegistry.registerContextAwareService(
105                 Context.WIFI_RTT_RANGING_SERVICE,
106                 WifiRttManager.class,
107                 (context, serviceBinder) -> {
108                     IWifiRttManager service = IWifiRttManager.Stub.asInterface(serviceBinder);
109                     return new WifiRttManager(context, service);
110                 }
111         );
112         SystemServiceRegistry.registerContextAwareService(
113                 Context.WIFI_RTT_SERVICE,
114                 RttManager.class,
115                 context -> {
116                     WifiRttManager wifiRttManager = context.getSystemService(WifiRttManager.class);
117                     return new RttManager(context, wifiRttManager);
118                 }
119         );
120     }
121 }
122