17d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon/* 27d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon * Copyright (C) 2008 The Android Open Source Project 37d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon * 47d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon * Licensed under the Apache License, Version 2.0 (the "License"); 57d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon * you may not use this file except in compliance with the License. 67d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon * You may obtain a copy of the License at 77d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon * 87d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon * http://www.apache.org/licenses/LICENSE-2.0 97d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon * 107d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon * Unless required by applicable law or agreed to in writing, software 117d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon * distributed under the License is distributed on an "AS IS" BASIS, 127d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 137d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon * See the License for the specific language governing permissions and 147d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon * limitations under the License. 157d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon */ 167d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 177d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordonpackage com.android.phone; 187d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 197d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordonimport android.app.Service; 207d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordonimport android.content.Intent; 217d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordonimport com.android.internal.telephony.OperatorInfo; 227d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordonimport android.os.AsyncResult; 237d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordonimport android.os.Binder; 247d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordonimport android.os.Handler; 257d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordonimport android.os.IBinder; 267d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordonimport android.os.Message; 277d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordonimport android.os.RemoteCallbackList; 287d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordonimport android.os.RemoteException; 297d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordonimport com.android.internal.telephony.Phone; 307d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordonimport com.android.internal.telephony.PhoneFactory; 317d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordonimport android.util.Log; 327d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 337d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordonimport java.util.ArrayList; 347d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 357d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon/** 367d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon * Service code used to assist in querying the network for service 377d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon * availability. 387d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon */ 397d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordonpublic class NetworkQueryService extends Service { 407d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon // debug data 417d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon private static final String LOG_TAG = "NetworkQuery"; 427d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon private static final boolean DBG = false; 437d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 447d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon // static events 457d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon private static final int EVENT_NETWORK_SCAN_COMPLETED = 100; 467d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 477d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon // static states indicating the query status of the service 487d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon private static final int QUERY_READY = -1; 497d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon private static final int QUERY_IS_RUNNING = -2; 507d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 517d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon // error statuses that will be retured in the callback. 527d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon public static final int QUERY_OK = 0; 537d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon public static final int QUERY_EXCEPTION = 1; 547d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 557d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon /** state of the query service */ 567d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon private int mState; 577d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 587d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon /** local handle to the phone object */ 597d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon private Phone mPhone; 607d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 617d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon /** 627d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon * Class for clients to access. Because we know this service always 637d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon * runs in the same process as its clients, we don't need to deal with 647d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon * IPC. 657d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon */ 667d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon public class LocalBinder extends Binder { 677d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon INetworkQueryService getService() { 687d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon return mBinder; 697d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 707d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 717d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon private final IBinder mLocalBinder = new LocalBinder(); 727d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 737d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon /** 747d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon * Local handler to receive the network query compete callback 757d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon * from the RIL. 767d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon */ 777d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon Handler mHandler = new Handler() { 787d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon @Override 797d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon public void handleMessage(Message msg) { 807d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon switch (msg.what) { 817d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon // if the scan is complete, broadcast the results. 827d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon // to all registerd callbacks. 837d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon case EVENT_NETWORK_SCAN_COMPLETED: 847d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon if (DBG) log("scan completed, broadcasting results"); 857d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon broadcastQueryResults((AsyncResult) msg.obj); 867d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon break; 877d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 887d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 897d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon }; 907d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 917d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon /** 927d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon * List of callback objects, also used to synchronize access to 937d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon * itself and to changes in state. 947d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon */ 957d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon final RemoteCallbackList<INetworkQueryServiceCallback> mCallbacks = 967d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon new RemoteCallbackList<INetworkQueryServiceCallback> (); 977d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 987d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon /** 997d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon * Implementation of the INetworkQueryService interface. 1007d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon */ 1017d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon private final INetworkQueryService.Stub mBinder = new INetworkQueryService.Stub() { 1027d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 1037d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon /** 1047d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon * Starts a query with a INetworkQueryServiceCallback object if 1057d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon * one has not been started yet. Ignore the new query request 1067d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon * if the query has been started already. Either way, place the 1077d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon * callback object in the queue to be notified upon request 1087d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon * completion. 1097d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon */ 1107d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon public void startNetworkQuery(INetworkQueryServiceCallback cb) { 1117d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon if (cb != null) { 1127d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon // register the callback to the list of callbacks. 1137d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon synchronized (mCallbacks) { 1147d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon mCallbacks.register(cb); 1157d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon if (DBG) log("registering callback " + cb.getClass().toString()); 1167d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 1177d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon switch (mState) { 1187d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon case QUERY_READY: 1197d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon // TODO: we may want to install a timeout here in case we 1207d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon // do not get a timely response from the RIL. 1217d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon mPhone.getAvailableNetworks( 1227d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon mHandler.obtainMessage(EVENT_NETWORK_SCAN_COMPLETED)); 1237d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon mState = QUERY_IS_RUNNING; 1247d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon if (DBG) log("starting new query"); 1257d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon break; 1267d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 1277d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon // do nothing if we're currently busy. 1287d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon case QUERY_IS_RUNNING: 1297d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon if (DBG) log("query already in progress"); 1307d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon break; 1317d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon default: 1327d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 1337d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 1347d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 1357d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 1367d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 1377d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon /** 1387d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon * Stops a query with a INetworkQueryServiceCallback object as 1397d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon * a token. 1407d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon */ 1417d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon public void stopNetworkQuery(INetworkQueryServiceCallback cb) { 1427d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon // currently we just unregister the callback, since there is 1437d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon // no way to tell the RIL to terminate the query request. 1447d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon // This means that the RIL may still be busy after the stop 1457d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon // request was made, but the state tracking logic ensures 1467d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon // that the delay will only last for 1 request even with 1477d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon // repeated button presses in the NetworkSetting activity. 1487d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon if (cb != null) { 1497d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon synchronized (mCallbacks) { 1507d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon if (DBG) log("unregistering callback " + cb.getClass().toString()); 1517d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon mCallbacks.unregister(cb); 1527d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 1537d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 1547d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 1557d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon }; 1567d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 1577d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon @Override 1587d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon public void onCreate() { 1597d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon mState = QUERY_READY; 1607d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon mPhone = PhoneFactory.getDefaultPhone(); 1617d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 1627d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 1637d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon /** 1647d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon * Required for service implementation. 1657d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon */ 1667d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon @Override 1677d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon public void onStart(Intent intent, int startId) { 1687d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 1697d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 1707d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon /** 1717d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon * Handle the bind request. 1727d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon */ 1737d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon @Override 1747d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon public IBinder onBind(Intent intent) { 1757d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon // TODO: Currently, return only the LocalBinder instance. If we 1767d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon // end up requiring support for a remote binder, we will need to 1777d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon // return mBinder as well, depending upon the intent. 1787d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon if (DBG) log("binding service implementation"); 1797d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon return mLocalBinder; 1807d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 1817d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 1827d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon /** 1837d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon * Broadcast the results from the query to all registered callback 1847d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon * objects. 1857d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon */ 1867d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon private void broadcastQueryResults (AsyncResult ar) { 1877d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon // reset the state. 1887d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon synchronized (mCallbacks) { 1897d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon mState = QUERY_READY; 1907d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 1917d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon // see if we need to do any work. 1927d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon if (ar == null) { 1937d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon if (DBG) log("AsyncResult is null."); 1947d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon return; 1957d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 1967d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 1977d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon // TODO: we may need greater accuracy here, but for now, just a 1987d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon // simple status integer will suffice. 1997d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon int exception = (ar.exception == null) ? QUERY_OK : QUERY_EXCEPTION; 2007d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon if (DBG) log("AsyncResult has exception " + exception); 2017d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 2027d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon // Make the calls to all the registered callbacks. 2037d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon for (int i = (mCallbacks.beginBroadcast() - 1); i >= 0; i--) { 2047d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon INetworkQueryServiceCallback cb = mCallbacks.getBroadcastItem(i); 2057d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon if (DBG) log("broadcasting results to " + cb.getClass().toString()); 2067d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon try { 2077d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon cb.onQueryComplete((ArrayList<OperatorInfo>) ar.result, exception); 2087d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } catch (RemoteException e) { 2097d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 2107d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 2117d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 2127d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon // finish up. 2137d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon mCallbacks.finishBroadcast(); 2147d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 2157d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 2167d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 2177d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon private static void log(String msg) { 2187d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon Log.d(LOG_TAG, msg); 2197d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 2207d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon} 221