Loading location/lib/java/com/android/location/provider/FusedLocationHardware.java +102 −24 Original line number Diff line number Diff line Loading @@ -9,7 +9,7 @@ * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIOS OF ANY KIND, either express or implied. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ Loading @@ -21,20 +21,26 @@ import android.hardware.location.IFusedLocationHardwareSink; import android.location.Location; import android.os.Handler; import android.os.Looper; import android.os.Message; import android.os.RemoteException; import android.util.Log; import java.util.ArrayList; import java.util.HashMap; import java.util.Map; /** * Class that exposes IFusedLocationHardware functionality to unbundled services. * Namely this is used by GmsCore Fused Location Provider. */ public final class FusedLocationHardware { private final String TAG = "FusedLocationHardware"; private IFusedLocationHardware mLocationHardware; ArrayList<FusedLocationHardwareSink> mSinkList = new ArrayList<FusedLocationHardwareSink>(); // the list uses a copy-on-write pattern to update its contents HashMap<FusedLocationHardwareSink, DispatcherHandler> mSinkList = new HashMap<FusedLocationHardwareSink, DispatcherHandler>(); private IFusedLocationHardwareSink mInternalSink = new IFusedLocationHardwareSink.Stub() { @Override Loading @@ -48,6 +54,9 @@ public final class FusedLocationHardware { } }; /** * @hide */ public FusedLocationHardware(IFusedLocationHardware locationHardware) { mLocationHardware = locationHardware; } Loading @@ -55,19 +64,24 @@ public final class FusedLocationHardware { /* * Methods to provide a Facade for IFusedLocationHardware */ public void registerSink(FusedLocationHardwareSink sink) { if(sink == null) { return; public void registerSink(FusedLocationHardwareSink sink, Looper looper) { if(sink == null || looper == null) { throw new IllegalArgumentException("Parameter sink and looper cannot be null."); } boolean registerSink = false; boolean registerSink; synchronized (mSinkList) { // register only on first insertion registerSink = mSinkList.size() == 0; // guarantee uniqueness if(!mSinkList.contains(sink)) { mSinkList.add(sink); if(mSinkList.containsKey(sink)) { return; } HashMap<FusedLocationHardwareSink, DispatcherHandler> newSinkList = new HashMap<FusedLocationHardwareSink, DispatcherHandler>(mSinkList); newSinkList.put(sink, new DispatcherHandler(looper)); mSinkList = newSinkList; } if(registerSink) { Loading @@ -81,14 +95,23 @@ public final class FusedLocationHardware { public void unregisterSink(FusedLocationHardwareSink sink) { if(sink == null) { return; throw new IllegalArgumentException("Parameter sink cannot be null."); } boolean unregisterSink = false; boolean unregisterSink; synchronized(mSinkList) { mSinkList.remove(sink); if(!mSinkList.containsKey(sink)) { //done return; } HashMap<FusedLocationHardwareSink, DispatcherHandler> newSinkList = new HashMap<FusedLocationHardwareSink, DispatcherHandler>(mSinkList); newSinkList.remove(sink); //unregister after the last sink unregisterSink = mSinkList.size() == 0; unregisterSink = newSinkList.size() == 0; mSinkList = newSinkList; } if(unregisterSink) { Loading Loading @@ -176,27 +199,82 @@ public final class FusedLocationHardware { } /* * Helper methods * Helper methods and classes */ private class DispatcherHandler extends Handler { public static final int DISPATCH_LOCATION = 1; public static final int DISPATCH_DIAGNOSTIC_DATA = 2; public DispatcherHandler(Looper looper) { super(looper, null /*callback*/ , true /*async*/); } @Override public void handleMessage(Message message) { MessageCommand command = (MessageCommand) message.obj; switch(message.what) { case DISPATCH_LOCATION: command.dispatchLocation(); break; case DISPATCH_DIAGNOSTIC_DATA: command.dispatchDiagnosticData(); default: Log.e(TAG, "Invalid dispatch message"); break; } } } private class MessageCommand { private final FusedLocationHardwareSink mSink; private final Location[] mLocations; private final String mData; public MessageCommand( FusedLocationHardwareSink sink, Location[] locations, String data) { mSink = sink; mLocations = locations; mData = data; } public void dispatchLocation() { mSink.onLocationAvailable(mLocations); } public void dispatchDiagnosticData() { mSink.onDiagnosticDataAvailable(mData); } } private void dispatchLocations(Location[] locations) { ArrayList<FusedLocationHardwareSink> sinks = null; HashMap<FusedLocationHardwareSink, DispatcherHandler> sinks; synchronized (mSinkList) { sinks = new ArrayList<FusedLocationHardwareSink>(mSinkList); sinks = mSinkList; } for(FusedLocationHardwareSink sink : sinks) { sink.onLocationAvailable(locations); for(Map.Entry<FusedLocationHardwareSink, DispatcherHandler> entry : sinks.entrySet()) { Message message = Message.obtain( entry.getValue(), DispatcherHandler.DISPATCH_LOCATION, new MessageCommand(entry.getKey(), locations, null /*data*/)); message.sendToTarget(); } } private void dispatchDiagnosticData(String data) { ArrayList<FusedLocationHardwareSink> sinks = null; HashMap<FusedLocationHardwareSink, DispatcherHandler> sinks; synchronized(mSinkList) { sinks = new ArrayList<FusedLocationHardwareSink>(mSinkList); sinks = mSinkList; } for(FusedLocationHardwareSink sink : sinks) { sink.onDiagnosticDataAvailable(data); for(Map.Entry<FusedLocationHardwareSink, DispatcherHandler> entry : sinks.entrySet()) { Message message = Message.obtain( entry.getValue(), DispatcherHandler.DISPATCH_DIAGNOSTIC_DATA, new MessageCommand(entry.getKey(), null /*locations*/, data)); message.sendToTarget(); } } } location/lib/java/com/android/location/provider/FusedLocationHardwareSink.java +0 −1 Original line number Diff line number Diff line Loading @@ -20,7 +20,6 @@ import android.location.Location; /** * Base class for sinks to interact with FusedLocationHardware. * This is mainly used by GmsCore Fused Provider. */ public abstract class FusedLocationHardwareSink { /* Loading location/lib/java/com/android/location/provider/FusedProvider.java +0 −2 Original line number Diff line number Diff line Loading @@ -28,8 +28,6 @@ import android.os.IBinder; * * <p>IMPORTANT: This class is effectively a public API for unbundled applications, and must remain * API stable. See README.txt in the root of this package for more information. * * @hide */ public abstract class FusedProvider { private IFusedProvider.Stub mProvider = new IFusedProvider.Stub() { Loading services/java/com/android/server/LocationManagerService.java +4 −1 Original line number Diff line number Diff line Loading @@ -437,7 +437,10 @@ public class LocationManagerService extends ILocationManager.Stub { FusedProxy fusedProxy = FusedProxy.createAndBind( mContext, mLocationHandler, flpHardwareProvider.getLocationHardware()); flpHardwareProvider.getLocationHardware(), com.android.internal.R.bool.config_enableFusedLocationOverlay, com.android.internal.R.string.config_fusedLocationProviderPackageName, com.android.internal.R.array.config_locationProviderPackageNames); if(fusedProxy == null) { Slog.e(TAG, "No FusedProvider found."); Loading services/java/com/android/server/location/FlpHardwareProvider.java +27 −15 Original line number Diff line number Diff line Loading @@ -28,11 +28,10 @@ import android.location.LocationManager; import android.content.Context; import android.os.Bundle; import android.os.Handler; import android.os.Looper; import android.os.RemoteException; import android.os.SystemClock; import android.util.Log; import android.util.Slog; /** * This class is an interop layer for JVM types and the JNI code that interacts Loading @@ -48,6 +47,7 @@ public class FlpHardwareProvider { private final static String TAG = "FlpHardwareProvider"; private final Context mContext; private final Object mLocationSinkLock = new Object(); public static FlpHardwareProvider getInstance(Context context) { if (sSingletonInstance == null) { Loading @@ -61,7 +61,6 @@ public class FlpHardwareProvider { mContext = context; // register for listening for passive provider data Handler handler = new Handler(); LocationManager manager = (LocationManager) mContext.getSystemService( Context.LOCATION_SERVICE); manager.requestLocationUpdates( Loading @@ -69,7 +68,7 @@ public class FlpHardwareProvider { 0 /* minTime */, 0 /* minDistance */, new NetworkLocationListener(), handler.getLooper()); Looper.myLooper()); } public static boolean isSupported() { Loading @@ -87,9 +86,13 @@ public class FlpHardwareProvider { location.setElapsedRealtimeNanos(SystemClock.elapsedRealtimeNanos()); } IFusedLocationHardwareSink sink; synchronized (mLocationSinkLock) { sink = mLocationSink; } try { if (mLocationSink != null) { mLocationSink.onLocationAvailable(locations); if (sink != null) { sink.onLocationAvailable(locations); } } catch (RemoteException e) { Log.e(TAG, "RemoteException calling onLocationAvailable"); Loading @@ -98,9 +101,13 @@ public class FlpHardwareProvider { // FlpDiagnosticCallbacks members private void onDataReport(String data) { IFusedLocationHardwareSink sink; synchronized (mLocationSinkLock) { sink = mLocationSink; } try { if (mLocationSink != null) { mLocationSink.onDiagnosticDataAvailable(data); sink.onDiagnosticDataAvailable(data); } } catch (RemoteException e) { Log.e(TAG, "RemoteException calling onDiagnosticDataAvailable"); Loading Loading @@ -199,21 +206,26 @@ public class FlpHardwareProvider { private final IFusedLocationHardware mLocationHardware = new IFusedLocationHardware.Stub() { @Override public void registerSink(IFusedLocationHardwareSink eventSink) { synchronized (mLocationSinkLock) { // only one sink is allowed at the moment if (mLocationSink != null) { throw new RuntimeException("IFusedLocationHardware does not support multiple sinks"); throw new RuntimeException( "IFusedLocationHardware does not support multiple sinks"); } mLocationSink = eventSink; } } @Override public void unregisterSink(IFusedLocationHardwareSink eventSink) { synchronized (mLocationSinkLock) { // don't throw if the sink is not registered, simply make it a no-op if (mLocationSink == eventSink) { mLocationSink = null; } } } @Override public int getSupportedBatchSize() { Loading Loading
location/lib/java/com/android/location/provider/FusedLocationHardware.java +102 −24 Original line number Diff line number Diff line Loading @@ -9,7 +9,7 @@ * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIOS OF ANY KIND, either express or implied. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ Loading @@ -21,20 +21,26 @@ import android.hardware.location.IFusedLocationHardwareSink; import android.location.Location; import android.os.Handler; import android.os.Looper; import android.os.Message; import android.os.RemoteException; import android.util.Log; import java.util.ArrayList; import java.util.HashMap; import java.util.Map; /** * Class that exposes IFusedLocationHardware functionality to unbundled services. * Namely this is used by GmsCore Fused Location Provider. */ public final class FusedLocationHardware { private final String TAG = "FusedLocationHardware"; private IFusedLocationHardware mLocationHardware; ArrayList<FusedLocationHardwareSink> mSinkList = new ArrayList<FusedLocationHardwareSink>(); // the list uses a copy-on-write pattern to update its contents HashMap<FusedLocationHardwareSink, DispatcherHandler> mSinkList = new HashMap<FusedLocationHardwareSink, DispatcherHandler>(); private IFusedLocationHardwareSink mInternalSink = new IFusedLocationHardwareSink.Stub() { @Override Loading @@ -48,6 +54,9 @@ public final class FusedLocationHardware { } }; /** * @hide */ public FusedLocationHardware(IFusedLocationHardware locationHardware) { mLocationHardware = locationHardware; } Loading @@ -55,19 +64,24 @@ public final class FusedLocationHardware { /* * Methods to provide a Facade for IFusedLocationHardware */ public void registerSink(FusedLocationHardwareSink sink) { if(sink == null) { return; public void registerSink(FusedLocationHardwareSink sink, Looper looper) { if(sink == null || looper == null) { throw new IllegalArgumentException("Parameter sink and looper cannot be null."); } boolean registerSink = false; boolean registerSink; synchronized (mSinkList) { // register only on first insertion registerSink = mSinkList.size() == 0; // guarantee uniqueness if(!mSinkList.contains(sink)) { mSinkList.add(sink); if(mSinkList.containsKey(sink)) { return; } HashMap<FusedLocationHardwareSink, DispatcherHandler> newSinkList = new HashMap<FusedLocationHardwareSink, DispatcherHandler>(mSinkList); newSinkList.put(sink, new DispatcherHandler(looper)); mSinkList = newSinkList; } if(registerSink) { Loading @@ -81,14 +95,23 @@ public final class FusedLocationHardware { public void unregisterSink(FusedLocationHardwareSink sink) { if(sink == null) { return; throw new IllegalArgumentException("Parameter sink cannot be null."); } boolean unregisterSink = false; boolean unregisterSink; synchronized(mSinkList) { mSinkList.remove(sink); if(!mSinkList.containsKey(sink)) { //done return; } HashMap<FusedLocationHardwareSink, DispatcherHandler> newSinkList = new HashMap<FusedLocationHardwareSink, DispatcherHandler>(mSinkList); newSinkList.remove(sink); //unregister after the last sink unregisterSink = mSinkList.size() == 0; unregisterSink = newSinkList.size() == 0; mSinkList = newSinkList; } if(unregisterSink) { Loading Loading @@ -176,27 +199,82 @@ public final class FusedLocationHardware { } /* * Helper methods * Helper methods and classes */ private class DispatcherHandler extends Handler { public static final int DISPATCH_LOCATION = 1; public static final int DISPATCH_DIAGNOSTIC_DATA = 2; public DispatcherHandler(Looper looper) { super(looper, null /*callback*/ , true /*async*/); } @Override public void handleMessage(Message message) { MessageCommand command = (MessageCommand) message.obj; switch(message.what) { case DISPATCH_LOCATION: command.dispatchLocation(); break; case DISPATCH_DIAGNOSTIC_DATA: command.dispatchDiagnosticData(); default: Log.e(TAG, "Invalid dispatch message"); break; } } } private class MessageCommand { private final FusedLocationHardwareSink mSink; private final Location[] mLocations; private final String mData; public MessageCommand( FusedLocationHardwareSink sink, Location[] locations, String data) { mSink = sink; mLocations = locations; mData = data; } public void dispatchLocation() { mSink.onLocationAvailable(mLocations); } public void dispatchDiagnosticData() { mSink.onDiagnosticDataAvailable(mData); } } private void dispatchLocations(Location[] locations) { ArrayList<FusedLocationHardwareSink> sinks = null; HashMap<FusedLocationHardwareSink, DispatcherHandler> sinks; synchronized (mSinkList) { sinks = new ArrayList<FusedLocationHardwareSink>(mSinkList); sinks = mSinkList; } for(FusedLocationHardwareSink sink : sinks) { sink.onLocationAvailable(locations); for(Map.Entry<FusedLocationHardwareSink, DispatcherHandler> entry : sinks.entrySet()) { Message message = Message.obtain( entry.getValue(), DispatcherHandler.DISPATCH_LOCATION, new MessageCommand(entry.getKey(), locations, null /*data*/)); message.sendToTarget(); } } private void dispatchDiagnosticData(String data) { ArrayList<FusedLocationHardwareSink> sinks = null; HashMap<FusedLocationHardwareSink, DispatcherHandler> sinks; synchronized(mSinkList) { sinks = new ArrayList<FusedLocationHardwareSink>(mSinkList); sinks = mSinkList; } for(FusedLocationHardwareSink sink : sinks) { sink.onDiagnosticDataAvailable(data); for(Map.Entry<FusedLocationHardwareSink, DispatcherHandler> entry : sinks.entrySet()) { Message message = Message.obtain( entry.getValue(), DispatcherHandler.DISPATCH_DIAGNOSTIC_DATA, new MessageCommand(entry.getKey(), null /*locations*/, data)); message.sendToTarget(); } } }
location/lib/java/com/android/location/provider/FusedLocationHardwareSink.java +0 −1 Original line number Diff line number Diff line Loading @@ -20,7 +20,6 @@ import android.location.Location; /** * Base class for sinks to interact with FusedLocationHardware. * This is mainly used by GmsCore Fused Provider. */ public abstract class FusedLocationHardwareSink { /* Loading
location/lib/java/com/android/location/provider/FusedProvider.java +0 −2 Original line number Diff line number Diff line Loading @@ -28,8 +28,6 @@ import android.os.IBinder; * * <p>IMPORTANT: This class is effectively a public API for unbundled applications, and must remain * API stable. See README.txt in the root of this package for more information. * * @hide */ public abstract class FusedProvider { private IFusedProvider.Stub mProvider = new IFusedProvider.Stub() { Loading
services/java/com/android/server/LocationManagerService.java +4 −1 Original line number Diff line number Diff line Loading @@ -437,7 +437,10 @@ public class LocationManagerService extends ILocationManager.Stub { FusedProxy fusedProxy = FusedProxy.createAndBind( mContext, mLocationHandler, flpHardwareProvider.getLocationHardware()); flpHardwareProvider.getLocationHardware(), com.android.internal.R.bool.config_enableFusedLocationOverlay, com.android.internal.R.string.config_fusedLocationProviderPackageName, com.android.internal.R.array.config_locationProviderPackageNames); if(fusedProxy == null) { Slog.e(TAG, "No FusedProvider found."); Loading
services/java/com/android/server/location/FlpHardwareProvider.java +27 −15 Original line number Diff line number Diff line Loading @@ -28,11 +28,10 @@ import android.location.LocationManager; import android.content.Context; import android.os.Bundle; import android.os.Handler; import android.os.Looper; import android.os.RemoteException; import android.os.SystemClock; import android.util.Log; import android.util.Slog; /** * This class is an interop layer for JVM types and the JNI code that interacts Loading @@ -48,6 +47,7 @@ public class FlpHardwareProvider { private final static String TAG = "FlpHardwareProvider"; private final Context mContext; private final Object mLocationSinkLock = new Object(); public static FlpHardwareProvider getInstance(Context context) { if (sSingletonInstance == null) { Loading @@ -61,7 +61,6 @@ public class FlpHardwareProvider { mContext = context; // register for listening for passive provider data Handler handler = new Handler(); LocationManager manager = (LocationManager) mContext.getSystemService( Context.LOCATION_SERVICE); manager.requestLocationUpdates( Loading @@ -69,7 +68,7 @@ public class FlpHardwareProvider { 0 /* minTime */, 0 /* minDistance */, new NetworkLocationListener(), handler.getLooper()); Looper.myLooper()); } public static boolean isSupported() { Loading @@ -87,9 +86,13 @@ public class FlpHardwareProvider { location.setElapsedRealtimeNanos(SystemClock.elapsedRealtimeNanos()); } IFusedLocationHardwareSink sink; synchronized (mLocationSinkLock) { sink = mLocationSink; } try { if (mLocationSink != null) { mLocationSink.onLocationAvailable(locations); if (sink != null) { sink.onLocationAvailable(locations); } } catch (RemoteException e) { Log.e(TAG, "RemoteException calling onLocationAvailable"); Loading @@ -98,9 +101,13 @@ public class FlpHardwareProvider { // FlpDiagnosticCallbacks members private void onDataReport(String data) { IFusedLocationHardwareSink sink; synchronized (mLocationSinkLock) { sink = mLocationSink; } try { if (mLocationSink != null) { mLocationSink.onDiagnosticDataAvailable(data); sink.onDiagnosticDataAvailable(data); } } catch (RemoteException e) { Log.e(TAG, "RemoteException calling onDiagnosticDataAvailable"); Loading Loading @@ -199,21 +206,26 @@ public class FlpHardwareProvider { private final IFusedLocationHardware mLocationHardware = new IFusedLocationHardware.Stub() { @Override public void registerSink(IFusedLocationHardwareSink eventSink) { synchronized (mLocationSinkLock) { // only one sink is allowed at the moment if (mLocationSink != null) { throw new RuntimeException("IFusedLocationHardware does not support multiple sinks"); throw new RuntimeException( "IFusedLocationHardware does not support multiple sinks"); } mLocationSink = eventSink; } } @Override public void unregisterSink(IFusedLocationHardwareSink eventSink) { synchronized (mLocationSinkLock) { // don't throw if the sink is not registered, simply make it a no-op if (mLocationSink == eventSink) { mLocationSink = null; } } } @Override public int getSupportedBatchSize() { Loading