FusedLocationHardware.java revision 1af4b0280af406cfc7eb46810f6b76e57b983e11
1/*
2 * Copyright (C) 2013 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 CONDITIOS 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
17package com.android.location.provider;
18
19import android.hardware.location.IFusedLocationHardware;
20import android.hardware.location.IFusedLocationHardwareSink;
21
22import android.location.Location;
23
24import android.os.RemoteException;
25import android.util.Log;
26
27import java.util.ArrayList;
28
29/**
30 * Class that exposes IFusedLocationHardware functionality to unbundled services.
31 * Namely this is used by GmsCore Fused Location Provider.
32 */
33public final class FusedLocationHardware {
34    private final String TAG = "FusedLocationHardware";
35
36    private IFusedLocationHardware mLocationHardware;
37    ArrayList<FusedLocationHardwareSink> mSinkList = new ArrayList<FusedLocationHardwareSink>();
38
39    private IFusedLocationHardwareSink mInternalSink = new IFusedLocationHardwareSink.Stub() {
40        @Override
41        public void onLocationAvailable(Location[] locations) {
42            dispatchLocations(locations);
43        }
44
45        @Override
46        public void onDiagnosticDataAvailable(String data) {
47            dispatchDiagnosticData(data);
48        }
49    };
50
51    public FusedLocationHardware(IFusedLocationHardware locationHardware) {
52        mLocationHardware = locationHardware;
53    }
54
55    /*
56     * Methods to provide a Facade for IFusedLocationHardware
57     */
58    public void registerSink(FusedLocationHardwareSink sink) {
59        if(sink == null) {
60            return;
61        }
62
63        boolean registerSink = false;
64        synchronized (mSinkList) {
65            // register only on first insertion
66            registerSink = mSinkList.size() == 0;
67            // guarantee uniqueness
68            if(!mSinkList.contains(sink)) {
69                mSinkList.add(sink);
70            }
71        }
72
73        if(registerSink) {
74            try {
75                mLocationHardware.registerSink(mInternalSink);
76            } catch(RemoteException e) {
77                Log.e(TAG, "RemoteException at registerSink");
78            }
79        }
80    }
81
82    public void unregisterSink(FusedLocationHardwareSink sink) {
83        if(sink == null) {
84            return;
85        }
86
87        boolean unregisterSink = false;
88        synchronized(mSinkList) {
89            mSinkList.remove(sink);
90            // unregister after the last sink
91            unregisterSink = mSinkList.size() == 0;
92        }
93
94        if(unregisterSink) {
95            try {
96                mLocationHardware.unregisterSink(mInternalSink);
97            } catch(RemoteException e) {
98                Log.e(TAG, "RemoteException at unregisterSink");
99            }
100        }
101    }
102
103    public int getSupportedBatchSize() {
104        try {
105            return mLocationHardware.getSupportedBatchSize();
106        } catch(RemoteException e) {
107            Log.e(TAG, "RemoteException at getSupportedBatchSize");
108            return 0;
109        }
110    }
111
112    public void startBatching(int id, GmsFusedBatchOptions batchOptions) {
113        try {
114            mLocationHardware.startBatching(id, batchOptions.getParcelableOptions());
115        } catch(RemoteException e) {
116            Log.e(TAG, "RemoteException at startBatching");
117        }
118    }
119
120    public void stopBatching(int id) {
121        try {
122            mLocationHardware.stopBatching(id);
123        } catch(RemoteException e) {
124            Log.e(TAG, "RemoteException at stopBatching");
125        }
126    }
127
128    public void updateBatchingOptions(int id, GmsFusedBatchOptions batchOptions) {
129        try {
130            mLocationHardware.updateBatchingOptions(id, batchOptions.getParcelableOptions());
131        } catch(RemoteException e) {
132            Log.e(TAG, "RemoteException at updateBatchingOptions");
133        }
134    }
135
136    public void requestBatchOfLocations(int batchSizeRequest) {
137        try {
138            mLocationHardware.requestBatchOfLocations(batchSizeRequest);
139        } catch(RemoteException e) {
140            Log.e(TAG, "RemoteException at requestBatchOfLocations");
141        }
142    }
143
144    public boolean supportsDiagnosticDataInjection() {
145        try {
146            return mLocationHardware.supportsDiagnosticDataInjection();
147        } catch(RemoteException e) {
148            Log.e(TAG, "RemoteException at supportsDiagnisticDataInjection");
149            return false;
150        }
151    }
152
153    public void injectDiagnosticData(String data) {
154        try {
155            mLocationHardware.injectDiagnosticData(data);
156        } catch(RemoteException e) {
157            Log.e(TAG, "RemoteException at injectDiagnosticData");
158        }
159    }
160
161    public boolean supportsDeviceContextInjection() {
162        try {
163            return mLocationHardware.supportsDeviceContextInjection();
164        } catch(RemoteException e) {
165            Log.e(TAG, "RemoteException at supportsDeviceContextInjection");
166            return false;
167        }
168    }
169
170    public void injectDeviceContext(int deviceEnabledContext) {
171        try {
172            mLocationHardware.injectDeviceContext(deviceEnabledContext);
173        } catch(RemoteException e) {
174            Log.e(TAG, "RemoteException at injectDeviceContext");
175        }
176    }
177
178    /*
179     * Helper methods
180     */
181    private void dispatchLocations(Location[] locations) {
182        ArrayList<FusedLocationHardwareSink> sinks = null;
183        synchronized (mSinkList) {
184            sinks = new ArrayList<FusedLocationHardwareSink>(mSinkList);
185        }
186
187        for(FusedLocationHardwareSink sink : sinks) {
188            sink.onLocationAvailable(locations);
189        }
190    }
191
192    private void dispatchDiagnosticData(String data) {
193        ArrayList<FusedLocationHardwareSink> sinks = null;
194        synchronized(mSinkList) {
195            sinks = new ArrayList<FusedLocationHardwareSink>(mSinkList);
196        }
197
198        for(FusedLocationHardwareSink sink : sinks) {
199            sink.onDiagnosticDataAvailable(data);
200        }
201    }
202}
203