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