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