11af4b0280af406cfc7eb46810f6b76e57b983e11destradaa/* 21af4b0280af406cfc7eb46810f6b76e57b983e11destradaa * Copyright (C) 2013 The Android Open Source Project 31af4b0280af406cfc7eb46810f6b76e57b983e11destradaa * 41af4b0280af406cfc7eb46810f6b76e57b983e11destradaa * Licensed under the Apache License, Version 2.0 (the "License"); 51af4b0280af406cfc7eb46810f6b76e57b983e11destradaa * you may not use this file except in compliance with the License. 61af4b0280af406cfc7eb46810f6b76e57b983e11destradaa * You may obtain a copy of the License at 71af4b0280af406cfc7eb46810f6b76e57b983e11destradaa * 81af4b0280af406cfc7eb46810f6b76e57b983e11destradaa * http://www.apache.org/licenses/LICENSE-2.0 91af4b0280af406cfc7eb46810f6b76e57b983e11destradaa * 101af4b0280af406cfc7eb46810f6b76e57b983e11destradaa * Unless required by applicable law or agreed to in writing, software 111af4b0280af406cfc7eb46810f6b76e57b983e11destradaa * distributed under the License is distributed on an "AS IS" BASIS, 1264be0c617f902398cbbcc2b145c86a8fbfc2feacdestradaa * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 131af4b0280af406cfc7eb46810f6b76e57b983e11destradaa * See the License for the specific language governing permissions and 141af4b0280af406cfc7eb46810f6b76e57b983e11destradaa * limitations under the License. 151af4b0280af406cfc7eb46810f6b76e57b983e11destradaa */ 161af4b0280af406cfc7eb46810f6b76e57b983e11destradaa 171af4b0280af406cfc7eb46810f6b76e57b983e11destradaapackage com.android.location.provider; 181af4b0280af406cfc7eb46810f6b76e57b983e11destradaa 191af4b0280af406cfc7eb46810f6b76e57b983e11destradaaimport android.hardware.location.IFusedLocationHardware; 201af4b0280af406cfc7eb46810f6b76e57b983e11destradaaimport android.hardware.location.IFusedLocationHardwareSink; 211af4b0280af406cfc7eb46810f6b76e57b983e11destradaa 221af4b0280af406cfc7eb46810f6b76e57b983e11destradaaimport android.location.Location; 231af4b0280af406cfc7eb46810f6b76e57b983e11destradaa 2464be0c617f902398cbbcc2b145c86a8fbfc2feacdestradaaimport android.os.Handler; 2564be0c617f902398cbbcc2b145c86a8fbfc2feacdestradaaimport android.os.Looper; 2664be0c617f902398cbbcc2b145c86a8fbfc2feacdestradaaimport android.os.Message; 271af4b0280af406cfc7eb46810f6b76e57b983e11destradaaimport android.os.RemoteException; 281af4b0280af406cfc7eb46810f6b76e57b983e11destradaaimport android.util.Log; 291af4b0280af406cfc7eb46810f6b76e57b983e11destradaa 3064be0c617f902398cbbcc2b145c86a8fbfc2feacdestradaaimport java.util.HashMap; 3164be0c617f902398cbbcc2b145c86a8fbfc2feacdestradaaimport java.util.Map; 321af4b0280af406cfc7eb46810f6b76e57b983e11destradaa 331af4b0280af406cfc7eb46810f6b76e57b983e11destradaa/** 341af4b0280af406cfc7eb46810f6b76e57b983e11destradaa * Class that exposes IFusedLocationHardware functionality to unbundled services. 351af4b0280af406cfc7eb46810f6b76e57b983e11destradaa */ 361af4b0280af406cfc7eb46810f6b76e57b983e11destradaapublic final class FusedLocationHardware { 371af4b0280af406cfc7eb46810f6b76e57b983e11destradaa private final String TAG = "FusedLocationHardware"; 381af4b0280af406cfc7eb46810f6b76e57b983e11destradaa 391af4b0280af406cfc7eb46810f6b76e57b983e11destradaa private IFusedLocationHardware mLocationHardware; 4064be0c617f902398cbbcc2b145c86a8fbfc2feacdestradaa 4164be0c617f902398cbbcc2b145c86a8fbfc2feacdestradaa // the list uses a copy-on-write pattern to update its contents 4264be0c617f902398cbbcc2b145c86a8fbfc2feacdestradaa HashMap<FusedLocationHardwareSink, DispatcherHandler> mSinkList = 4364be0c617f902398cbbcc2b145c86a8fbfc2feacdestradaa new HashMap<FusedLocationHardwareSink, DispatcherHandler>(); 441af4b0280af406cfc7eb46810f6b76e57b983e11destradaa 451af4b0280af406cfc7eb46810f6b76e57b983e11destradaa private IFusedLocationHardwareSink mInternalSink = new IFusedLocationHardwareSink.Stub() { 461af4b0280af406cfc7eb46810f6b76e57b983e11destradaa @Override 471af4b0280af406cfc7eb46810f6b76e57b983e11destradaa public void onLocationAvailable(Location[] locations) { 481af4b0280af406cfc7eb46810f6b76e57b983e11destradaa dispatchLocations(locations); 491af4b0280af406cfc7eb46810f6b76e57b983e11destradaa } 501af4b0280af406cfc7eb46810f6b76e57b983e11destradaa 511af4b0280af406cfc7eb46810f6b76e57b983e11destradaa @Override 521af4b0280af406cfc7eb46810f6b76e57b983e11destradaa public void onDiagnosticDataAvailable(String data) { 531af4b0280af406cfc7eb46810f6b76e57b983e11destradaa dispatchDiagnosticData(data); 541af4b0280af406cfc7eb46810f6b76e57b983e11destradaa } 551af4b0280af406cfc7eb46810f6b76e57b983e11destradaa }; 561af4b0280af406cfc7eb46810f6b76e57b983e11destradaa 5764be0c617f902398cbbcc2b145c86a8fbfc2feacdestradaa /** 5864be0c617f902398cbbcc2b145c86a8fbfc2feacdestradaa * @hide 5964be0c617f902398cbbcc2b145c86a8fbfc2feacdestradaa */ 601af4b0280af406cfc7eb46810f6b76e57b983e11destradaa public FusedLocationHardware(IFusedLocationHardware locationHardware) { 611af4b0280af406cfc7eb46810f6b76e57b983e11destradaa mLocationHardware = locationHardware; 621af4b0280af406cfc7eb46810f6b76e57b983e11destradaa } 631af4b0280af406cfc7eb46810f6b76e57b983e11destradaa 641af4b0280af406cfc7eb46810f6b76e57b983e11destradaa /* 651af4b0280af406cfc7eb46810f6b76e57b983e11destradaa * Methods to provide a Facade for IFusedLocationHardware 661af4b0280af406cfc7eb46810f6b76e57b983e11destradaa */ 6764be0c617f902398cbbcc2b145c86a8fbfc2feacdestradaa public void registerSink(FusedLocationHardwareSink sink, Looper looper) { 6864be0c617f902398cbbcc2b145c86a8fbfc2feacdestradaa if(sink == null || looper == null) { 6964be0c617f902398cbbcc2b145c86a8fbfc2feacdestradaa throw new IllegalArgumentException("Parameter sink and looper cannot be null."); 701af4b0280af406cfc7eb46810f6b76e57b983e11destradaa } 711af4b0280af406cfc7eb46810f6b76e57b983e11destradaa 7264be0c617f902398cbbcc2b145c86a8fbfc2feacdestradaa boolean registerSink; 731af4b0280af406cfc7eb46810f6b76e57b983e11destradaa synchronized (mSinkList) { 741af4b0280af406cfc7eb46810f6b76e57b983e11destradaa // register only on first insertion 751af4b0280af406cfc7eb46810f6b76e57b983e11destradaa registerSink = mSinkList.size() == 0; 761af4b0280af406cfc7eb46810f6b76e57b983e11destradaa // guarantee uniqueness 7764be0c617f902398cbbcc2b145c86a8fbfc2feacdestradaa if(mSinkList.containsKey(sink)) { 7864be0c617f902398cbbcc2b145c86a8fbfc2feacdestradaa return; 791af4b0280af406cfc7eb46810f6b76e57b983e11destradaa } 8064be0c617f902398cbbcc2b145c86a8fbfc2feacdestradaa 8164be0c617f902398cbbcc2b145c86a8fbfc2feacdestradaa HashMap<FusedLocationHardwareSink, DispatcherHandler> newSinkList = 8264be0c617f902398cbbcc2b145c86a8fbfc2feacdestradaa new HashMap<FusedLocationHardwareSink, DispatcherHandler>(mSinkList); 8364be0c617f902398cbbcc2b145c86a8fbfc2feacdestradaa newSinkList.put(sink, new DispatcherHandler(looper)); 8464be0c617f902398cbbcc2b145c86a8fbfc2feacdestradaa mSinkList = newSinkList; 851af4b0280af406cfc7eb46810f6b76e57b983e11destradaa } 861af4b0280af406cfc7eb46810f6b76e57b983e11destradaa 871af4b0280af406cfc7eb46810f6b76e57b983e11destradaa if(registerSink) { 881af4b0280af406cfc7eb46810f6b76e57b983e11destradaa try { 891af4b0280af406cfc7eb46810f6b76e57b983e11destradaa mLocationHardware.registerSink(mInternalSink); 901af4b0280af406cfc7eb46810f6b76e57b983e11destradaa } catch(RemoteException e) { 911af4b0280af406cfc7eb46810f6b76e57b983e11destradaa Log.e(TAG, "RemoteException at registerSink"); 921af4b0280af406cfc7eb46810f6b76e57b983e11destradaa } 931af4b0280af406cfc7eb46810f6b76e57b983e11destradaa } 941af4b0280af406cfc7eb46810f6b76e57b983e11destradaa } 951af4b0280af406cfc7eb46810f6b76e57b983e11destradaa 961af4b0280af406cfc7eb46810f6b76e57b983e11destradaa public void unregisterSink(FusedLocationHardwareSink sink) { 971af4b0280af406cfc7eb46810f6b76e57b983e11destradaa if(sink == null) { 9864be0c617f902398cbbcc2b145c86a8fbfc2feacdestradaa throw new IllegalArgumentException("Parameter sink cannot be null."); 991af4b0280af406cfc7eb46810f6b76e57b983e11destradaa } 1001af4b0280af406cfc7eb46810f6b76e57b983e11destradaa 10164be0c617f902398cbbcc2b145c86a8fbfc2feacdestradaa boolean unregisterSink; 1021af4b0280af406cfc7eb46810f6b76e57b983e11destradaa synchronized(mSinkList) { 10364be0c617f902398cbbcc2b145c86a8fbfc2feacdestradaa if(!mSinkList.containsKey(sink)) { 10464be0c617f902398cbbcc2b145c86a8fbfc2feacdestradaa //done 10564be0c617f902398cbbcc2b145c86a8fbfc2feacdestradaa return; 10664be0c617f902398cbbcc2b145c86a8fbfc2feacdestradaa } 10764be0c617f902398cbbcc2b145c86a8fbfc2feacdestradaa 10864be0c617f902398cbbcc2b145c86a8fbfc2feacdestradaa HashMap<FusedLocationHardwareSink, DispatcherHandler> newSinkList = 10964be0c617f902398cbbcc2b145c86a8fbfc2feacdestradaa new HashMap<FusedLocationHardwareSink, DispatcherHandler>(mSinkList); 11064be0c617f902398cbbcc2b145c86a8fbfc2feacdestradaa newSinkList.remove(sink); 11164be0c617f902398cbbcc2b145c86a8fbfc2feacdestradaa //unregister after the last sink 11264be0c617f902398cbbcc2b145c86a8fbfc2feacdestradaa unregisterSink = newSinkList.size() == 0; 11364be0c617f902398cbbcc2b145c86a8fbfc2feacdestradaa 11464be0c617f902398cbbcc2b145c86a8fbfc2feacdestradaa mSinkList = newSinkList; 1151af4b0280af406cfc7eb46810f6b76e57b983e11destradaa } 1161af4b0280af406cfc7eb46810f6b76e57b983e11destradaa 1171af4b0280af406cfc7eb46810f6b76e57b983e11destradaa if(unregisterSink) { 1181af4b0280af406cfc7eb46810f6b76e57b983e11destradaa try { 1191af4b0280af406cfc7eb46810f6b76e57b983e11destradaa mLocationHardware.unregisterSink(mInternalSink); 1201af4b0280af406cfc7eb46810f6b76e57b983e11destradaa } catch(RemoteException e) { 1211af4b0280af406cfc7eb46810f6b76e57b983e11destradaa Log.e(TAG, "RemoteException at unregisterSink"); 1221af4b0280af406cfc7eb46810f6b76e57b983e11destradaa } 1231af4b0280af406cfc7eb46810f6b76e57b983e11destradaa } 1241af4b0280af406cfc7eb46810f6b76e57b983e11destradaa } 1251af4b0280af406cfc7eb46810f6b76e57b983e11destradaa 1261af4b0280af406cfc7eb46810f6b76e57b983e11destradaa public int getSupportedBatchSize() { 1271af4b0280af406cfc7eb46810f6b76e57b983e11destradaa try { 1281af4b0280af406cfc7eb46810f6b76e57b983e11destradaa return mLocationHardware.getSupportedBatchSize(); 1291af4b0280af406cfc7eb46810f6b76e57b983e11destradaa } catch(RemoteException e) { 1301af4b0280af406cfc7eb46810f6b76e57b983e11destradaa Log.e(TAG, "RemoteException at getSupportedBatchSize"); 1311af4b0280af406cfc7eb46810f6b76e57b983e11destradaa return 0; 1321af4b0280af406cfc7eb46810f6b76e57b983e11destradaa } 1331af4b0280af406cfc7eb46810f6b76e57b983e11destradaa } 1341af4b0280af406cfc7eb46810f6b76e57b983e11destradaa 1351af4b0280af406cfc7eb46810f6b76e57b983e11destradaa public void startBatching(int id, GmsFusedBatchOptions batchOptions) { 1361af4b0280af406cfc7eb46810f6b76e57b983e11destradaa try { 1371af4b0280af406cfc7eb46810f6b76e57b983e11destradaa mLocationHardware.startBatching(id, batchOptions.getParcelableOptions()); 1381af4b0280af406cfc7eb46810f6b76e57b983e11destradaa } catch(RemoteException e) { 1391af4b0280af406cfc7eb46810f6b76e57b983e11destradaa Log.e(TAG, "RemoteException at startBatching"); 1401af4b0280af406cfc7eb46810f6b76e57b983e11destradaa } 1411af4b0280af406cfc7eb46810f6b76e57b983e11destradaa } 1421af4b0280af406cfc7eb46810f6b76e57b983e11destradaa 1431af4b0280af406cfc7eb46810f6b76e57b983e11destradaa public void stopBatching(int id) { 1441af4b0280af406cfc7eb46810f6b76e57b983e11destradaa try { 1451af4b0280af406cfc7eb46810f6b76e57b983e11destradaa mLocationHardware.stopBatching(id); 1461af4b0280af406cfc7eb46810f6b76e57b983e11destradaa } catch(RemoteException e) { 1471af4b0280af406cfc7eb46810f6b76e57b983e11destradaa Log.e(TAG, "RemoteException at stopBatching"); 1481af4b0280af406cfc7eb46810f6b76e57b983e11destradaa } 1491af4b0280af406cfc7eb46810f6b76e57b983e11destradaa } 1501af4b0280af406cfc7eb46810f6b76e57b983e11destradaa 1511af4b0280af406cfc7eb46810f6b76e57b983e11destradaa public void updateBatchingOptions(int id, GmsFusedBatchOptions batchOptions) { 1521af4b0280af406cfc7eb46810f6b76e57b983e11destradaa try { 1531af4b0280af406cfc7eb46810f6b76e57b983e11destradaa mLocationHardware.updateBatchingOptions(id, batchOptions.getParcelableOptions()); 1541af4b0280af406cfc7eb46810f6b76e57b983e11destradaa } catch(RemoteException e) { 1551af4b0280af406cfc7eb46810f6b76e57b983e11destradaa Log.e(TAG, "RemoteException at updateBatchingOptions"); 1561af4b0280af406cfc7eb46810f6b76e57b983e11destradaa } 1571af4b0280af406cfc7eb46810f6b76e57b983e11destradaa } 1581af4b0280af406cfc7eb46810f6b76e57b983e11destradaa 1591af4b0280af406cfc7eb46810f6b76e57b983e11destradaa public void requestBatchOfLocations(int batchSizeRequest) { 1601af4b0280af406cfc7eb46810f6b76e57b983e11destradaa try { 1611af4b0280af406cfc7eb46810f6b76e57b983e11destradaa mLocationHardware.requestBatchOfLocations(batchSizeRequest); 1621af4b0280af406cfc7eb46810f6b76e57b983e11destradaa } catch(RemoteException e) { 1631af4b0280af406cfc7eb46810f6b76e57b983e11destradaa Log.e(TAG, "RemoteException at requestBatchOfLocations"); 1641af4b0280af406cfc7eb46810f6b76e57b983e11destradaa } 1651af4b0280af406cfc7eb46810f6b76e57b983e11destradaa } 1661af4b0280af406cfc7eb46810f6b76e57b983e11destradaa 1671af4b0280af406cfc7eb46810f6b76e57b983e11destradaa public boolean supportsDiagnosticDataInjection() { 1681af4b0280af406cfc7eb46810f6b76e57b983e11destradaa try { 1691af4b0280af406cfc7eb46810f6b76e57b983e11destradaa return mLocationHardware.supportsDiagnosticDataInjection(); 1701af4b0280af406cfc7eb46810f6b76e57b983e11destradaa } catch(RemoteException e) { 1711af4b0280af406cfc7eb46810f6b76e57b983e11destradaa Log.e(TAG, "RemoteException at supportsDiagnisticDataInjection"); 1721af4b0280af406cfc7eb46810f6b76e57b983e11destradaa return false; 1731af4b0280af406cfc7eb46810f6b76e57b983e11destradaa } 1741af4b0280af406cfc7eb46810f6b76e57b983e11destradaa } 1751af4b0280af406cfc7eb46810f6b76e57b983e11destradaa 1761af4b0280af406cfc7eb46810f6b76e57b983e11destradaa public void injectDiagnosticData(String data) { 1771af4b0280af406cfc7eb46810f6b76e57b983e11destradaa try { 1781af4b0280af406cfc7eb46810f6b76e57b983e11destradaa mLocationHardware.injectDiagnosticData(data); 1791af4b0280af406cfc7eb46810f6b76e57b983e11destradaa } catch(RemoteException e) { 1801af4b0280af406cfc7eb46810f6b76e57b983e11destradaa Log.e(TAG, "RemoteException at injectDiagnosticData"); 1811af4b0280af406cfc7eb46810f6b76e57b983e11destradaa } 1821af4b0280af406cfc7eb46810f6b76e57b983e11destradaa } 1831af4b0280af406cfc7eb46810f6b76e57b983e11destradaa 1841af4b0280af406cfc7eb46810f6b76e57b983e11destradaa public boolean supportsDeviceContextInjection() { 1851af4b0280af406cfc7eb46810f6b76e57b983e11destradaa try { 1861af4b0280af406cfc7eb46810f6b76e57b983e11destradaa return mLocationHardware.supportsDeviceContextInjection(); 1871af4b0280af406cfc7eb46810f6b76e57b983e11destradaa } catch(RemoteException e) { 1881af4b0280af406cfc7eb46810f6b76e57b983e11destradaa Log.e(TAG, "RemoteException at supportsDeviceContextInjection"); 1891af4b0280af406cfc7eb46810f6b76e57b983e11destradaa return false; 1901af4b0280af406cfc7eb46810f6b76e57b983e11destradaa } 1911af4b0280af406cfc7eb46810f6b76e57b983e11destradaa } 1921af4b0280af406cfc7eb46810f6b76e57b983e11destradaa 1931af4b0280af406cfc7eb46810f6b76e57b983e11destradaa public void injectDeviceContext(int deviceEnabledContext) { 1941af4b0280af406cfc7eb46810f6b76e57b983e11destradaa try { 1951af4b0280af406cfc7eb46810f6b76e57b983e11destradaa mLocationHardware.injectDeviceContext(deviceEnabledContext); 1961af4b0280af406cfc7eb46810f6b76e57b983e11destradaa } catch(RemoteException e) { 1971af4b0280af406cfc7eb46810f6b76e57b983e11destradaa Log.e(TAG, "RemoteException at injectDeviceContext"); 1981af4b0280af406cfc7eb46810f6b76e57b983e11destradaa } 1991af4b0280af406cfc7eb46810f6b76e57b983e11destradaa } 2001af4b0280af406cfc7eb46810f6b76e57b983e11destradaa 2011af4b0280af406cfc7eb46810f6b76e57b983e11destradaa /* 20264be0c617f902398cbbcc2b145c86a8fbfc2feacdestradaa * Helper methods and classes 2031af4b0280af406cfc7eb46810f6b76e57b983e11destradaa */ 20464be0c617f902398cbbcc2b145c86a8fbfc2feacdestradaa private class DispatcherHandler extends Handler { 20564be0c617f902398cbbcc2b145c86a8fbfc2feacdestradaa public static final int DISPATCH_LOCATION = 1; 20664be0c617f902398cbbcc2b145c86a8fbfc2feacdestradaa public static final int DISPATCH_DIAGNOSTIC_DATA = 2; 20764be0c617f902398cbbcc2b145c86a8fbfc2feacdestradaa 20864be0c617f902398cbbcc2b145c86a8fbfc2feacdestradaa public DispatcherHandler(Looper looper) { 20964be0c617f902398cbbcc2b145c86a8fbfc2feacdestradaa super(looper, null /*callback*/ , true /*async*/); 21064be0c617f902398cbbcc2b145c86a8fbfc2feacdestradaa } 21164be0c617f902398cbbcc2b145c86a8fbfc2feacdestradaa 21264be0c617f902398cbbcc2b145c86a8fbfc2feacdestradaa @Override 21364be0c617f902398cbbcc2b145c86a8fbfc2feacdestradaa public void handleMessage(Message message) { 21464be0c617f902398cbbcc2b145c86a8fbfc2feacdestradaa MessageCommand command = (MessageCommand) message.obj; 21564be0c617f902398cbbcc2b145c86a8fbfc2feacdestradaa switch(message.what) { 21664be0c617f902398cbbcc2b145c86a8fbfc2feacdestradaa case DISPATCH_LOCATION: 21764be0c617f902398cbbcc2b145c86a8fbfc2feacdestradaa command.dispatchLocation(); 21864be0c617f902398cbbcc2b145c86a8fbfc2feacdestradaa break; 21964be0c617f902398cbbcc2b145c86a8fbfc2feacdestradaa case DISPATCH_DIAGNOSTIC_DATA: 22064be0c617f902398cbbcc2b145c86a8fbfc2feacdestradaa command.dispatchDiagnosticData(); 22164be0c617f902398cbbcc2b145c86a8fbfc2feacdestradaa default: 22264be0c617f902398cbbcc2b145c86a8fbfc2feacdestradaa Log.e(TAG, "Invalid dispatch message"); 22364be0c617f902398cbbcc2b145c86a8fbfc2feacdestradaa break; 22464be0c617f902398cbbcc2b145c86a8fbfc2feacdestradaa } 22564be0c617f902398cbbcc2b145c86a8fbfc2feacdestradaa } 22664be0c617f902398cbbcc2b145c86a8fbfc2feacdestradaa } 22764be0c617f902398cbbcc2b145c86a8fbfc2feacdestradaa 22864be0c617f902398cbbcc2b145c86a8fbfc2feacdestradaa private class MessageCommand { 22964be0c617f902398cbbcc2b145c86a8fbfc2feacdestradaa private final FusedLocationHardwareSink mSink; 23064be0c617f902398cbbcc2b145c86a8fbfc2feacdestradaa private final Location[] mLocations; 23164be0c617f902398cbbcc2b145c86a8fbfc2feacdestradaa private final String mData; 23264be0c617f902398cbbcc2b145c86a8fbfc2feacdestradaa 23364be0c617f902398cbbcc2b145c86a8fbfc2feacdestradaa public MessageCommand( 23464be0c617f902398cbbcc2b145c86a8fbfc2feacdestradaa FusedLocationHardwareSink sink, 23564be0c617f902398cbbcc2b145c86a8fbfc2feacdestradaa Location[] locations, 23664be0c617f902398cbbcc2b145c86a8fbfc2feacdestradaa String data) { 23764be0c617f902398cbbcc2b145c86a8fbfc2feacdestradaa mSink = sink; 23864be0c617f902398cbbcc2b145c86a8fbfc2feacdestradaa mLocations = locations; 23964be0c617f902398cbbcc2b145c86a8fbfc2feacdestradaa mData = data; 24064be0c617f902398cbbcc2b145c86a8fbfc2feacdestradaa } 24164be0c617f902398cbbcc2b145c86a8fbfc2feacdestradaa 24264be0c617f902398cbbcc2b145c86a8fbfc2feacdestradaa public void dispatchLocation() { 24364be0c617f902398cbbcc2b145c86a8fbfc2feacdestradaa mSink.onLocationAvailable(mLocations); 24464be0c617f902398cbbcc2b145c86a8fbfc2feacdestradaa } 24564be0c617f902398cbbcc2b145c86a8fbfc2feacdestradaa 24664be0c617f902398cbbcc2b145c86a8fbfc2feacdestradaa public void dispatchDiagnosticData() { 24764be0c617f902398cbbcc2b145c86a8fbfc2feacdestradaa mSink.onDiagnosticDataAvailable(mData); 24864be0c617f902398cbbcc2b145c86a8fbfc2feacdestradaa } 24964be0c617f902398cbbcc2b145c86a8fbfc2feacdestradaa } 25064be0c617f902398cbbcc2b145c86a8fbfc2feacdestradaa 2511af4b0280af406cfc7eb46810f6b76e57b983e11destradaa private void dispatchLocations(Location[] locations) { 25264be0c617f902398cbbcc2b145c86a8fbfc2feacdestradaa HashMap<FusedLocationHardwareSink, DispatcherHandler> sinks; 2531af4b0280af406cfc7eb46810f6b76e57b983e11destradaa synchronized (mSinkList) { 25464be0c617f902398cbbcc2b145c86a8fbfc2feacdestradaa sinks = mSinkList; 2551af4b0280af406cfc7eb46810f6b76e57b983e11destradaa } 2561af4b0280af406cfc7eb46810f6b76e57b983e11destradaa 25764be0c617f902398cbbcc2b145c86a8fbfc2feacdestradaa for(Map.Entry<FusedLocationHardwareSink, DispatcherHandler> entry : sinks.entrySet()) { 25864be0c617f902398cbbcc2b145c86a8fbfc2feacdestradaa Message message = Message.obtain( 25964be0c617f902398cbbcc2b145c86a8fbfc2feacdestradaa entry.getValue(), 26064be0c617f902398cbbcc2b145c86a8fbfc2feacdestradaa DispatcherHandler.DISPATCH_LOCATION, 26164be0c617f902398cbbcc2b145c86a8fbfc2feacdestradaa new MessageCommand(entry.getKey(), locations, null /*data*/)); 26264be0c617f902398cbbcc2b145c86a8fbfc2feacdestradaa message.sendToTarget(); 2631af4b0280af406cfc7eb46810f6b76e57b983e11destradaa } 2641af4b0280af406cfc7eb46810f6b76e57b983e11destradaa } 2651af4b0280af406cfc7eb46810f6b76e57b983e11destradaa 2661af4b0280af406cfc7eb46810f6b76e57b983e11destradaa private void dispatchDiagnosticData(String data) { 26764be0c617f902398cbbcc2b145c86a8fbfc2feacdestradaa HashMap<FusedLocationHardwareSink, DispatcherHandler> sinks; 2681af4b0280af406cfc7eb46810f6b76e57b983e11destradaa synchronized(mSinkList) { 26964be0c617f902398cbbcc2b145c86a8fbfc2feacdestradaa sinks = mSinkList; 2701af4b0280af406cfc7eb46810f6b76e57b983e11destradaa } 2711af4b0280af406cfc7eb46810f6b76e57b983e11destradaa 27264be0c617f902398cbbcc2b145c86a8fbfc2feacdestradaa for(Map.Entry<FusedLocationHardwareSink, DispatcherHandler> entry : sinks.entrySet()) { 27364be0c617f902398cbbcc2b145c86a8fbfc2feacdestradaa Message message = Message.obtain( 27464be0c617f902398cbbcc2b145c86a8fbfc2feacdestradaa entry.getValue(), 27564be0c617f902398cbbcc2b145c86a8fbfc2feacdestradaa DispatcherHandler.DISPATCH_DIAGNOSTIC_DATA, 27664be0c617f902398cbbcc2b145c86a8fbfc2feacdestradaa new MessageCommand(entry.getKey(), null /*locations*/, data)); 27764be0c617f902398cbbcc2b145c86a8fbfc2feacdestradaa message.sendToTarget(); 2781af4b0280af406cfc7eb46810f6b76e57b983e11destradaa } 2791af4b0280af406cfc7eb46810f6b76e57b983e11destradaa } 2801af4b0280af406cfc7eb46810f6b76e57b983e11destradaa} 281