• Home
  • History
  • Annotate
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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