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