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