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