1 /* 2 * Copyright 2017 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 android.telephony; 18 19 import android.annotation.NonNull; 20 import android.annotation.Nullable; 21 import android.annotation.SdkConstant; 22 import android.annotation.SystemApi; 23 import android.app.Service; 24 import android.content.Intent; 25 import android.os.Handler; 26 import android.os.HandlerThread; 27 import android.os.IBinder; 28 import android.os.Looper; 29 import android.os.Message; 30 import android.os.RemoteException; 31 import android.telephony.NetworkRegistrationInfo.Domain; 32 import android.util.SparseArray; 33 34 import com.android.internal.annotations.VisibleForTesting; 35 36 import java.util.ArrayList; 37 import java.util.List; 38 39 /** 40 * Base class of network service. Services that extend NetworkService must register the service in 41 * their AndroidManifest to be detected by the framework. They must be protected by the permission 42 * "android.permission.BIND_TELEPHONY_NETWORK_SERVICE". The network service definition in the 43 * manifest must follow the following format: 44 * ... 45 * <service android:name=".xxxNetworkService" 46 * android:permission="android.permission.BIND_TELEPHONY_NETWORK_SERVICE" > 47 * <intent-filter> 48 * <action android:name="android.telephony.NetworkService" /> 49 * </intent-filter> 50 * </service> 51 * @hide 52 */ 53 @SystemApi 54 public abstract class NetworkService extends Service { 55 56 private final String TAG = NetworkService.class.getSimpleName(); 57 58 @SdkConstant(SdkConstant.SdkConstantType.SERVICE_ACTION) 59 public static final String SERVICE_INTERFACE = "android.telephony.NetworkService"; 60 61 private static final int NETWORK_SERVICE_CREATE_NETWORK_SERVICE_PROVIDER = 1; 62 private static final int NETWORK_SERVICE_REMOVE_NETWORK_SERVICE_PROVIDER = 2; 63 private static final int NETWORK_SERVICE_REMOVE_ALL_NETWORK_SERVICE_PROVIDERS = 3; 64 private static final int NETWORK_SERVICE_GET_REGISTRATION_INFO = 4; 65 private static final int NETWORK_SERVICE_REGISTER_FOR_INFO_CHANGE = 5; 66 private static final int NETWORK_SERVICE_UNREGISTER_FOR_INFO_CHANGE = 6; 67 private static final int NETWORK_SERVICE_INDICATION_NETWORK_INFO_CHANGED = 7; 68 69 70 private final HandlerThread mHandlerThread; 71 72 private final NetworkServiceHandler mHandler; 73 74 private final SparseArray<NetworkServiceProvider> mServiceMap = new SparseArray<>(); 75 76 /** 77 * @hide 78 */ 79 @VisibleForTesting 80 public final INetworkServiceWrapper mBinder = new INetworkServiceWrapper(); 81 82 /** 83 * The abstract class of the actual network service implementation. The network service provider 84 * must extend this class to support network connection. Note that each instance of network 85 * service is associated with one physical SIM slot. 86 */ 87 public abstract class NetworkServiceProvider implements AutoCloseable { 88 private final int mSlotIndex; 89 90 private final List<INetworkServiceCallback> 91 mNetworkRegistrationInfoChangedCallbacks = new ArrayList<>(); 92 93 /** 94 * Constructor 95 * @param slotIndex SIM slot id the data service provider associated with. 96 */ NetworkServiceProvider(int slotIndex)97 public NetworkServiceProvider(int slotIndex) { 98 mSlotIndex = slotIndex; 99 } 100 101 /** 102 * @return SIM slot index the network service associated with. 103 */ getSlotIndex()104 public final int getSlotIndex() { 105 return mSlotIndex; 106 } 107 108 /** 109 * Request network registration info. The result will be passed to the callback. 110 * 111 * @param domain Network domain 112 * @param callback The callback for reporting network registration info 113 */ requestNetworkRegistrationInfo(@omain int domain, @NonNull NetworkServiceCallback callback)114 public void requestNetworkRegistrationInfo(@Domain int domain, 115 @NonNull NetworkServiceCallback callback) { 116 callback.onRequestNetworkRegistrationInfoComplete( 117 NetworkServiceCallback.RESULT_ERROR_UNSUPPORTED, null); 118 } 119 120 /** 121 * Notify the system that network registration info is changed. 122 */ notifyNetworkRegistrationInfoChanged()123 public final void notifyNetworkRegistrationInfoChanged() { 124 mHandler.obtainMessage(NETWORK_SERVICE_INDICATION_NETWORK_INFO_CHANGED, 125 mSlotIndex, 0, null).sendToTarget(); 126 } 127 registerForInfoChanged(@onNull INetworkServiceCallback callback)128 private void registerForInfoChanged(@NonNull INetworkServiceCallback callback) { 129 synchronized (mNetworkRegistrationInfoChangedCallbacks) { 130 mNetworkRegistrationInfoChangedCallbacks.add(callback); 131 } 132 } 133 unregisterForInfoChanged(@onNull INetworkServiceCallback callback)134 private void unregisterForInfoChanged(@NonNull INetworkServiceCallback callback) { 135 synchronized (mNetworkRegistrationInfoChangedCallbacks) { 136 mNetworkRegistrationInfoChangedCallbacks.remove(callback); 137 } 138 } 139 notifyInfoChangedToCallbacks()140 private void notifyInfoChangedToCallbacks() { 141 for (INetworkServiceCallback callback : mNetworkRegistrationInfoChangedCallbacks) { 142 try { 143 callback.onNetworkStateChanged(); 144 } catch (RemoteException exception) { 145 // Doing nothing. 146 } 147 } 148 } 149 150 /** 151 * Called when the instance of network service is destroyed (e.g. got unbind or binder died) 152 * or when the network service provider is removed. The extended class should implement this 153 * method to perform cleanup works. 154 */ 155 @Override close()156 public abstract void close(); 157 } 158 159 private class NetworkServiceHandler extends Handler { 160 NetworkServiceHandler(Looper looper)161 NetworkServiceHandler(Looper looper) { 162 super(looper); 163 } 164 165 @Override handleMessage(Message message)166 public void handleMessage(Message message) { 167 final int slotIndex = message.arg1; 168 final INetworkServiceCallback callback = (INetworkServiceCallback) message.obj; 169 170 NetworkServiceProvider serviceProvider = mServiceMap.get(slotIndex); 171 172 switch (message.what) { 173 case NETWORK_SERVICE_CREATE_NETWORK_SERVICE_PROVIDER: 174 // If the service provider doesn't exist yet, we try to create it. 175 if (serviceProvider == null) { 176 mServiceMap.put(slotIndex, onCreateNetworkServiceProvider(slotIndex)); 177 } 178 break; 179 case NETWORK_SERVICE_REMOVE_NETWORK_SERVICE_PROVIDER: 180 // If the service provider doesn't exist yet, we try to create it. 181 if (serviceProvider != null) { 182 serviceProvider.close(); 183 mServiceMap.remove(slotIndex); 184 } 185 break; 186 case NETWORK_SERVICE_REMOVE_ALL_NETWORK_SERVICE_PROVIDERS: 187 for (int i = 0; i < mServiceMap.size(); i++) { 188 serviceProvider = mServiceMap.get(i); 189 if (serviceProvider != null) { 190 serviceProvider.close(); 191 } 192 } 193 mServiceMap.clear(); 194 break; 195 case NETWORK_SERVICE_GET_REGISTRATION_INFO: 196 if (serviceProvider == null) break; 197 int domainId = message.arg2; 198 serviceProvider.requestNetworkRegistrationInfo(domainId, 199 new NetworkServiceCallback(callback)); 200 201 break; 202 case NETWORK_SERVICE_REGISTER_FOR_INFO_CHANGE: 203 if (serviceProvider == null) break; 204 serviceProvider.registerForInfoChanged(callback); 205 break; 206 case NETWORK_SERVICE_UNREGISTER_FOR_INFO_CHANGE: 207 if (serviceProvider == null) break; 208 serviceProvider.unregisterForInfoChanged(callback); 209 break; 210 case NETWORK_SERVICE_INDICATION_NETWORK_INFO_CHANGED: 211 if (serviceProvider == null) break; 212 serviceProvider.notifyInfoChangedToCallbacks(); 213 break; 214 default: 215 break; 216 } 217 } 218 } 219 220 /** 221 * Default constructor. 222 */ NetworkService()223 public NetworkService() { 224 mHandlerThread = new HandlerThread(TAG); 225 mHandlerThread.start(); 226 227 mHandler = new NetworkServiceHandler(mHandlerThread.getLooper()); 228 log("network service created"); 229 } 230 231 /** 232 * Create the instance of {@link NetworkServiceProvider}. Network service provider must override 233 * this method to facilitate the creation of {@link NetworkServiceProvider} instances. The system 234 * will call this method after binding the network service for each active SIM slot id. 235 * 236 * @param slotIndex SIM slot id the network service associated with. 237 * @return Network service object. Null if failed to create the provider (e.g. invalid slot 238 * index) 239 */ 240 @Nullable onCreateNetworkServiceProvider(int slotIndex)241 public abstract NetworkServiceProvider onCreateNetworkServiceProvider(int slotIndex); 242 243 @Override onBind(Intent intent)244 public IBinder onBind(Intent intent) { 245 if (intent == null || !SERVICE_INTERFACE.equals(intent.getAction())) { 246 loge("Unexpected intent " + intent); 247 return null; 248 } 249 250 return mBinder; 251 } 252 253 @Override onUnbind(Intent intent)254 public boolean onUnbind(Intent intent) { 255 mHandler.obtainMessage(NETWORK_SERVICE_REMOVE_ALL_NETWORK_SERVICE_PROVIDERS, 0, 256 0, null).sendToTarget(); 257 258 return false; 259 } 260 261 /** @hide */ 262 @Override onDestroy()263 public void onDestroy() { 264 mHandlerThread.quit(); 265 super.onDestroy(); 266 } 267 268 /** 269 * A wrapper around INetworkService that forwards calls to implementations of 270 * {@link NetworkService}. 271 */ 272 private class INetworkServiceWrapper extends INetworkService.Stub { 273 274 @Override createNetworkServiceProvider(int slotIndex)275 public void createNetworkServiceProvider(int slotIndex) { 276 mHandler.obtainMessage(NETWORK_SERVICE_CREATE_NETWORK_SERVICE_PROVIDER, slotIndex, 277 0, null).sendToTarget(); 278 } 279 280 @Override removeNetworkServiceProvider(int slotIndex)281 public void removeNetworkServiceProvider(int slotIndex) { 282 mHandler.obtainMessage(NETWORK_SERVICE_REMOVE_NETWORK_SERVICE_PROVIDER, slotIndex, 283 0, null).sendToTarget(); 284 } 285 286 @Override requestNetworkRegistrationInfo(int slotIndex, int domain, INetworkServiceCallback callback)287 public void requestNetworkRegistrationInfo(int slotIndex, int domain, 288 INetworkServiceCallback callback) { 289 mHandler.obtainMessage(NETWORK_SERVICE_GET_REGISTRATION_INFO, slotIndex, 290 domain, callback).sendToTarget(); 291 } 292 293 @Override registerForNetworkRegistrationInfoChanged( int slotIndex, INetworkServiceCallback callback)294 public void registerForNetworkRegistrationInfoChanged( 295 int slotIndex, INetworkServiceCallback callback) { 296 mHandler.obtainMessage(NETWORK_SERVICE_REGISTER_FOR_INFO_CHANGE, slotIndex, 297 0, callback).sendToTarget(); 298 } 299 300 @Override unregisterForNetworkRegistrationInfoChanged( int slotIndex, INetworkServiceCallback callback)301 public void unregisterForNetworkRegistrationInfoChanged( 302 int slotIndex, INetworkServiceCallback callback) { 303 mHandler.obtainMessage(NETWORK_SERVICE_UNREGISTER_FOR_INFO_CHANGE, slotIndex, 304 0, callback).sendToTarget(); 305 } 306 } 307 log(String s)308 private final void log(String s) { 309 Rlog.d(TAG, s); 310 } 311 loge(String s)312 private final void loge(String s) { 313 Rlog.e(TAG, s); 314 } 315 } 316