am 541ba710: Merge "Add FlpHal layer to support Location Batching." into klp-dev
* commit '541ba710731c484926440fbb9b2c39d69f38b652': Add FlpHal layer to support Location Batching.
This commit is contained in:
@@ -128,6 +128,8 @@ LOCAL_SRC_FILES += \
|
||||
core/java/android/hardware/display/IDisplayManagerCallback.aidl \
|
||||
core/java/android/hardware/input/IInputManager.aidl \
|
||||
core/java/android/hardware/input/IInputDevicesChangedListener.aidl \
|
||||
core/java/android/hardware/location/IFusedLocationHardware.aidl \
|
||||
core/java/android/hardware/location/IFusedLocationHardwareSink.aidl \
|
||||
core/java/android/hardware/location/IGeofenceHardware.aidl \
|
||||
core/java/android/hardware/location/IGeofenceHardwareCallback.aidl \
|
||||
core/java/android/hardware/location/IGeofenceHardwareMonitorCallback.aidl \
|
||||
@@ -232,12 +234,14 @@ LOCAL_SRC_FILES += \
|
||||
keystore/java/android/security/IKeyChainService.aidl \
|
||||
location/java/android/location/ICountryDetector.aidl \
|
||||
location/java/android/location/ICountryListener.aidl \
|
||||
location/java/android/location/IFusedProvider.aidl \
|
||||
location/java/android/location/IGeocodeProvider.aidl \
|
||||
location/java/android/location/IGeofenceProvider.aidl \
|
||||
location/java/android/location/IGpsStatusListener.aidl \
|
||||
location/java/android/location/IGpsStatusProvider.aidl \
|
||||
location/java/android/location/ILocationListener.aidl \
|
||||
location/java/android/location/ILocationManager.aidl \
|
||||
location/java/android/location/IFusedGeofenceHardware.aidl \
|
||||
location/java/android/location/IGpsGeofenceHardware.aidl \
|
||||
location/java/android/location/INetInitiatedListener.aidl \
|
||||
location/java/com/android/internal/location/ILocationProvider.aidl \
|
||||
@@ -379,6 +383,7 @@ aidl_files := \
|
||||
frameworks/base/location/java/android/location/Geofence.aidl \
|
||||
frameworks/base/location/java/android/location/Location.aidl \
|
||||
frameworks/base/location/java/android/location/LocationRequest.aidl \
|
||||
frameworks/base/location/java/android/location/FusedBatchOptions.aidl \
|
||||
frameworks/base/location/java/com/android/internal/location/ProviderProperties.aidl \
|
||||
frameworks/base/location/java/com/android/internal/location/ProviderRequest.aidl \
|
||||
frameworks/base/telephony/java/android/telephony/ServiceState.aidl \
|
||||
|
||||
117
core/java/android/hardware/location/IFusedLocationHardware.aidl
Normal file
117
core/java/android/hardware/location/IFusedLocationHardware.aidl
Normal file
@@ -0,0 +1,117 @@
|
||||
/*
|
||||
* Copyright (C) 2013, The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/license/LICENSE-2.0
|
||||
*
|
||||
* 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 CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package android.hardware.location;
|
||||
|
||||
import android.hardware.location.IFusedLocationHardwareSink;
|
||||
import android.location.FusedBatchOptions;
|
||||
|
||||
/**
|
||||
* Fused Location hardware interface.
|
||||
* This interface is the basic set of supported functionality by Fused Hardware
|
||||
* modules that offer Location batching capabilities.
|
||||
*
|
||||
* @hide
|
||||
*/
|
||||
interface IFusedLocationHardware {
|
||||
/**
|
||||
* Registers a sink with the Location Hardware object.
|
||||
*
|
||||
* @param eventSink The sink to register.
|
||||
*/
|
||||
void registerSink(in IFusedLocationHardwareSink eventSink);
|
||||
|
||||
/**
|
||||
* Unregisters a sink with the Location Hardware object.
|
||||
*
|
||||
* @param eventSink The sink to unregister.
|
||||
*/
|
||||
void unregisterSink(in IFusedLocationHardwareSink eventSink);
|
||||
|
||||
/**
|
||||
* Provides access to the batch size available in Hardware.
|
||||
*
|
||||
* @return The batch size the hardware supports.
|
||||
*/
|
||||
int getSupportedBatchSize();
|
||||
|
||||
/**
|
||||
* Requests the Hardware to start batching locations.
|
||||
*
|
||||
* @param id An Id associated with the request.
|
||||
* @param batchOptions The options required for batching.
|
||||
*
|
||||
* @throws RuntimeException if the request Id exists.
|
||||
*/
|
||||
void startBatching(in int id, in FusedBatchOptions batchOptions);
|
||||
|
||||
/**
|
||||
* Requests the Hardware to stop batching for the given Id.
|
||||
*
|
||||
* @param id The request that needs to be stopped.
|
||||
* @throws RuntimeException if the request Id is unknown.
|
||||
*/
|
||||
void stopBatching(in int id);
|
||||
|
||||
/**
|
||||
* Updates a batching operation in progress.
|
||||
*
|
||||
* @param id The Id of the operation to update.
|
||||
* @param batchOptions The options to apply to the given operation.
|
||||
*
|
||||
* @throws RuntimeException if the Id of the request is unknown.
|
||||
*/
|
||||
void updateBatchingOptions(in int id, in FusedBatchOptions batchOptions);
|
||||
|
||||
/**
|
||||
* Requests the most recent locations available in Hardware.
|
||||
* This operation does not dequeue the locations, so still other batching
|
||||
* events will continue working.
|
||||
*
|
||||
* @param batchSizeRequested The number of locations requested.
|
||||
*/
|
||||
void requestBatchOfLocations(in int batchSizeRequested);
|
||||
|
||||
/**
|
||||
* Flags if the Hardware supports injection of diagnostic data.
|
||||
*
|
||||
* @return True if data injection is supported, false otherwise.
|
||||
*/
|
||||
boolean supportsDiagnosticDataInjection();
|
||||
|
||||
/**
|
||||
* Injects diagnostic data into the Hardware subsystem.
|
||||
*
|
||||
* @param data The data to inject.
|
||||
* @throws RuntimeException if injection is not supported.
|
||||
*/
|
||||
void injectDiagnosticData(in String data);
|
||||
|
||||
/**
|
||||
* Flags if the Hardware supports injection of device context information.
|
||||
*
|
||||
* @return True if device context injection is supported, false otherwise.
|
||||
*/
|
||||
boolean supportsDeviceContextInjection();
|
||||
|
||||
/**
|
||||
* Injects device context information into the Hardware subsystem.
|
||||
*
|
||||
* @param deviceEnabledContext The context to inject.
|
||||
* @throws RuntimeException if injection is not supported.
|
||||
*/
|
||||
void injectDeviceContext(in int deviceEnabledContext);
|
||||
}
|
||||
@@ -0,0 +1,41 @@
|
||||
/*
|
||||
* Copyright (C) 2013, The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/license/LICENSE-2.0
|
||||
*
|
||||
* 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 CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package android.hardware.location;
|
||||
|
||||
import android.location.Location;
|
||||
|
||||
/**
|
||||
* Fused Location hardware event sink interface.
|
||||
* This interface defines the set of events that the FusedLocationHardware provides.
|
||||
*
|
||||
* @hide
|
||||
*/
|
||||
interface IFusedLocationHardwareSink {
|
||||
/**
|
||||
* Event generated when a batch of location information is available.
|
||||
*
|
||||
* @param locations The batch of location information available.
|
||||
*/
|
||||
void onLocationAvailable(in Location[] locations);
|
||||
|
||||
/**
|
||||
* Event generated from FLP HAL to provide diagnostic data to the platform.
|
||||
*
|
||||
* @param data The diagnostic data provided by FLP HAL.
|
||||
*/
|
||||
void onDiagnosticDataAvailable(in String data);
|
||||
}
|
||||
19
location/java/android/location/FusedBatchOptions.aidl
Normal file
19
location/java/android/location/FusedBatchOptions.aidl
Normal file
@@ -0,0 +1,19 @@
|
||||
/*
|
||||
* Copyright (C) 2013, The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* 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 CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package android.location;
|
||||
|
||||
parcelable FusedBatchOptions;
|
||||
135
location/java/android/location/FusedBatchOptions.java
Normal file
135
location/java/android/location/FusedBatchOptions.java
Normal file
@@ -0,0 +1,135 @@
|
||||
/*
|
||||
* Copyright (C) 2013 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* 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 CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package android.location;
|
||||
|
||||
import android.os.Parcel;
|
||||
import android.os.Parcelable;
|
||||
|
||||
/**
|
||||
* A data class representing a set of options to configure batching sessions.
|
||||
* @hide
|
||||
*/
|
||||
public class FusedBatchOptions implements Parcelable {
|
||||
private volatile long mPeriodInNS = 0;
|
||||
private volatile int mSourcesToUse = 0;
|
||||
private volatile int mFlags = 0;
|
||||
|
||||
// the default value is set to request fixes at no cost
|
||||
private volatile double mMaxPowerAllocationInMW = 0;
|
||||
|
||||
/*
|
||||
* Getters and setters for properties needed to hold the options.
|
||||
*/
|
||||
public void setMaxPowerAllocationInMW(double value) {
|
||||
mMaxPowerAllocationInMW = value;
|
||||
}
|
||||
|
||||
public double getMaxPowerAllocationInMW() {
|
||||
return mMaxPowerAllocationInMW;
|
||||
}
|
||||
|
||||
public void setPeriodInNS(long value) {
|
||||
mPeriodInNS = value;
|
||||
}
|
||||
|
||||
public long getPeriodInNS() {
|
||||
return mPeriodInNS;
|
||||
}
|
||||
|
||||
public void setSourceToUse(int source) {
|
||||
mSourcesToUse |= source;
|
||||
}
|
||||
|
||||
public void resetSourceToUse(int source) {
|
||||
mSourcesToUse &= ~source;
|
||||
}
|
||||
|
||||
public boolean isSourceToUseSet(int source) {
|
||||
return (mSourcesToUse & source) != 0;
|
||||
}
|
||||
|
||||
public int getSourcesToUse() {
|
||||
return mSourcesToUse;
|
||||
}
|
||||
|
||||
public void setFlag(int flag) {
|
||||
mFlags |= flag;
|
||||
}
|
||||
|
||||
public void resetFlag(int flag) {
|
||||
mFlags &= ~flag;
|
||||
}
|
||||
|
||||
public boolean isFlagSet(int flag) {
|
||||
return (mFlags & flag) != 0;
|
||||
}
|
||||
|
||||
public int getFlags() {
|
||||
return mFlags;
|
||||
}
|
||||
|
||||
/**
|
||||
* Definition of enum flag sets needed by this class.
|
||||
* Such values need to be kept in sync with the ones in fused_location.h
|
||||
*/
|
||||
public static final class SourceTechnologies {
|
||||
public static int GNSS = 1<<0;
|
||||
public static int WIFI = 1<<1;
|
||||
public static int SENSORS = 1<<2;
|
||||
public static int CELL = 1<<3;
|
||||
public static int BLUETOOTH = 1<<4;
|
||||
}
|
||||
|
||||
public static final class BatchFlags {
|
||||
public static int WAKEUP_ON_FIFO_FULL = 1<<0;
|
||||
public static int CALLBACK_ON_LOCATION_FIX = 1<<1;
|
||||
}
|
||||
|
||||
/*
|
||||
* Method definitions to support Parcelable operations.
|
||||
*/
|
||||
public static final Parcelable.Creator<FusedBatchOptions> CREATOR =
|
||||
new Parcelable.Creator<FusedBatchOptions>() {
|
||||
@Override
|
||||
public FusedBatchOptions createFromParcel(Parcel parcel) {
|
||||
FusedBatchOptions options = new FusedBatchOptions();
|
||||
options.setMaxPowerAllocationInMW(parcel.readDouble());
|
||||
options.setPeriodInNS(parcel.readLong());
|
||||
options.setSourceToUse(parcel.readInt());
|
||||
options.setFlag(parcel.readInt());
|
||||
return options;
|
||||
}
|
||||
|
||||
@Override
|
||||
public FusedBatchOptions[] newArray(int size) {
|
||||
return new FusedBatchOptions[size];
|
||||
}
|
||||
};
|
||||
|
||||
@Override
|
||||
public int describeContents() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeToParcel(Parcel parcel, int flags) {
|
||||
parcel.writeDouble(mMaxPowerAllocationInMW);
|
||||
parcel.writeLong(mPeriodInNS);
|
||||
parcel.writeInt(mSourcesToUse);
|
||||
parcel.writeInt(mFlags);
|
||||
}
|
||||
}
|
||||
93
location/java/android/location/IFusedGeofenceHardware.aidl
Normal file
93
location/java/android/location/IFusedGeofenceHardware.aidl
Normal file
@@ -0,0 +1,93 @@
|
||||
/*
|
||||
* Copyright (C) 2013, The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/license/LICENSE-2.0
|
||||
*
|
||||
* 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 CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package android.location;
|
||||
|
||||
import android.location.Geofence;
|
||||
|
||||
/**
|
||||
* Fused Geofence Hardware interface.
|
||||
*
|
||||
* <p>This interface is the basic set of supported functionality by Fused Hardware modules that offer
|
||||
* Geofencing capabilities.
|
||||
*
|
||||
* All operations are asynchronous and the status codes can be obtained via a set of callbacks.
|
||||
*
|
||||
* @hide
|
||||
*/
|
||||
interface IFusedGeofenceHardware {
|
||||
/**
|
||||
* Flags if the interface functionality is supported by the platform.
|
||||
*
|
||||
* @return true if the functionality is supported, false otherwise.
|
||||
*/
|
||||
boolean isSupported();
|
||||
|
||||
/**
|
||||
* Adds a given list of geofences to the system.
|
||||
*
|
||||
* @param geofenceIdsArray The list of geofence Ids to add.
|
||||
* @param geofencesArray the list of geofences to add.
|
||||
*/
|
||||
// TODO: [GeofenceIntegration] GeofenceHardwareRequest is not a parcelable class exposed in aidl
|
||||
void addGeofences(in int[] geofenceIdsArray, in Geofence[] geofencesArray);
|
||||
|
||||
/**
|
||||
* Removes a give list of geofences from the system.
|
||||
*
|
||||
* @param geofences The list of geofences to remove.
|
||||
*/
|
||||
void removeGeofences(in int[] geofenceIds);
|
||||
|
||||
/**
|
||||
* Pauses monitoring a particular geofence.
|
||||
*
|
||||
* @param geofenceId The geofence to pause monitoring.
|
||||
*/
|
||||
void pauseMonitoringGeofence(in int geofenceId);
|
||||
|
||||
/**
|
||||
* Resumes monitoring a particular geofence.
|
||||
*
|
||||
* @param geofenceid The geofence to resume monitoring.
|
||||
* @param transitionsToMonitor The transitions to monitor upon resume.
|
||||
*
|
||||
* Remarks: keep naming of geofence request options consistent with the naming used in
|
||||
* GeofenceHardwareRequest
|
||||
*/
|
||||
void resumeMonitoringGeofence(in int geofenceId, in int monitorTransitions);
|
||||
|
||||
/**
|
||||
* Modifies the request options if a geofence that is already known by the
|
||||
* system.
|
||||
*
|
||||
* @param geofenceId The geofence to modify.
|
||||
* @param lastTransition The last known transition state of
|
||||
* the geofence.
|
||||
* @param monitorTransitions The set of transitions to monitor.
|
||||
* @param notificationResponsiveness The notification responsivness needed.
|
||||
* @param unknownTimer The time span associated with the
|
||||
*
|
||||
* Remarks: keep the options as separate fields to be able to leverage the class
|
||||
* GeofenceHardwareRequest without any changes
|
||||
*/
|
||||
void modifyGeofenceOptions(
|
||||
in int geofenceId,
|
||||
in int lastTransition,
|
||||
in int monitorTransitions,
|
||||
in int notificationResponsiveness,
|
||||
in int unknownTimer);
|
||||
}
|
||||
32
location/java/android/location/IFusedProvider.aidl
Normal file
32
location/java/android/location/IFusedProvider.aidl
Normal file
@@ -0,0 +1,32 @@
|
||||
/*
|
||||
* Copyright (C) 2013 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* 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 CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package android.location;
|
||||
|
||||
import android.hardware.location.IFusedLocationHardware;
|
||||
|
||||
/**
|
||||
* Interface definition for Location providers that require FLP services.
|
||||
* @hide
|
||||
*/
|
||||
interface IFusedProvider {
|
||||
/**
|
||||
* Provides access to a FusedLocationHardware instance needed for the provider to work.
|
||||
*
|
||||
* @param instance The FusedLocationHardware available for the provider to use.
|
||||
*/
|
||||
void onFusedLocationHardwareChange(in IFusedLocationHardware instance);
|
||||
}
|
||||
@@ -0,0 +1,202 @@
|
||||
/*
|
||||
* Copyright (C) 2013 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* 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.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.android.location.provider;
|
||||
|
||||
import android.hardware.location.IFusedLocationHardware;
|
||||
import android.hardware.location.IFusedLocationHardwareSink;
|
||||
|
||||
import android.location.Location;
|
||||
|
||||
import android.os.RemoteException;
|
||||
import android.util.Log;
|
||||
|
||||
import java.util.ArrayList;
|
||||
|
||||
/**
|
||||
* 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>();
|
||||
|
||||
private IFusedLocationHardwareSink mInternalSink = new IFusedLocationHardwareSink.Stub() {
|
||||
@Override
|
||||
public void onLocationAvailable(Location[] locations) {
|
||||
dispatchLocations(locations);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onDiagnosticDataAvailable(String data) {
|
||||
dispatchDiagnosticData(data);
|
||||
}
|
||||
};
|
||||
|
||||
public FusedLocationHardware(IFusedLocationHardware locationHardware) {
|
||||
mLocationHardware = locationHardware;
|
||||
}
|
||||
|
||||
/*
|
||||
* Methods to provide a Facade for IFusedLocationHardware
|
||||
*/
|
||||
public void registerSink(FusedLocationHardwareSink sink) {
|
||||
if(sink == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
boolean registerSink = false;
|
||||
synchronized (mSinkList) {
|
||||
// register only on first insertion
|
||||
registerSink = mSinkList.size() == 0;
|
||||
// guarantee uniqueness
|
||||
if(!mSinkList.contains(sink)) {
|
||||
mSinkList.add(sink);
|
||||
}
|
||||
}
|
||||
|
||||
if(registerSink) {
|
||||
try {
|
||||
mLocationHardware.registerSink(mInternalSink);
|
||||
} catch(RemoteException e) {
|
||||
Log.e(TAG, "RemoteException at registerSink");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void unregisterSink(FusedLocationHardwareSink sink) {
|
||||
if(sink == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
boolean unregisterSink = false;
|
||||
synchronized(mSinkList) {
|
||||
mSinkList.remove(sink);
|
||||
// unregister after the last sink
|
||||
unregisterSink = mSinkList.size() == 0;
|
||||
}
|
||||
|
||||
if(unregisterSink) {
|
||||
try {
|
||||
mLocationHardware.unregisterSink(mInternalSink);
|
||||
} catch(RemoteException e) {
|
||||
Log.e(TAG, "RemoteException at unregisterSink");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public int getSupportedBatchSize() {
|
||||
try {
|
||||
return mLocationHardware.getSupportedBatchSize();
|
||||
} catch(RemoteException e) {
|
||||
Log.e(TAG, "RemoteException at getSupportedBatchSize");
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
public void startBatching(int id, GmsFusedBatchOptions batchOptions) {
|
||||
try {
|
||||
mLocationHardware.startBatching(id, batchOptions.getParcelableOptions());
|
||||
} catch(RemoteException e) {
|
||||
Log.e(TAG, "RemoteException at startBatching");
|
||||
}
|
||||
}
|
||||
|
||||
public void stopBatching(int id) {
|
||||
try {
|
||||
mLocationHardware.stopBatching(id);
|
||||
} catch(RemoteException e) {
|
||||
Log.e(TAG, "RemoteException at stopBatching");
|
||||
}
|
||||
}
|
||||
|
||||
public void updateBatchingOptions(int id, GmsFusedBatchOptions batchOptions) {
|
||||
try {
|
||||
mLocationHardware.updateBatchingOptions(id, batchOptions.getParcelableOptions());
|
||||
} catch(RemoteException e) {
|
||||
Log.e(TAG, "RemoteException at updateBatchingOptions");
|
||||
}
|
||||
}
|
||||
|
||||
public void requestBatchOfLocations(int batchSizeRequest) {
|
||||
try {
|
||||
mLocationHardware.requestBatchOfLocations(batchSizeRequest);
|
||||
} catch(RemoteException e) {
|
||||
Log.e(TAG, "RemoteException at requestBatchOfLocations");
|
||||
}
|
||||
}
|
||||
|
||||
public boolean supportsDiagnosticDataInjection() {
|
||||
try {
|
||||
return mLocationHardware.supportsDiagnosticDataInjection();
|
||||
} catch(RemoteException e) {
|
||||
Log.e(TAG, "RemoteException at supportsDiagnisticDataInjection");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public void injectDiagnosticData(String data) {
|
||||
try {
|
||||
mLocationHardware.injectDiagnosticData(data);
|
||||
} catch(RemoteException e) {
|
||||
Log.e(TAG, "RemoteException at injectDiagnosticData");
|
||||
}
|
||||
}
|
||||
|
||||
public boolean supportsDeviceContextInjection() {
|
||||
try {
|
||||
return mLocationHardware.supportsDeviceContextInjection();
|
||||
} catch(RemoteException e) {
|
||||
Log.e(TAG, "RemoteException at supportsDeviceContextInjection");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public void injectDeviceContext(int deviceEnabledContext) {
|
||||
try {
|
||||
mLocationHardware.injectDeviceContext(deviceEnabledContext);
|
||||
} catch(RemoteException e) {
|
||||
Log.e(TAG, "RemoteException at injectDeviceContext");
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Helper methods
|
||||
*/
|
||||
private void dispatchLocations(Location[] locations) {
|
||||
ArrayList<FusedLocationHardwareSink> sinks = null;
|
||||
synchronized (mSinkList) {
|
||||
sinks = new ArrayList<FusedLocationHardwareSink>(mSinkList);
|
||||
}
|
||||
|
||||
for(FusedLocationHardwareSink sink : sinks) {
|
||||
sink.onLocationAvailable(locations);
|
||||
}
|
||||
}
|
||||
|
||||
private void dispatchDiagnosticData(String data) {
|
||||
ArrayList<FusedLocationHardwareSink> sinks = null;
|
||||
synchronized(mSinkList) {
|
||||
sinks = new ArrayList<FusedLocationHardwareSink>(mSinkList);
|
||||
}
|
||||
|
||||
for(FusedLocationHardwareSink sink : sinks) {
|
||||
sink.onDiagnosticDataAvailable(data);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,31 @@
|
||||
/*
|
||||
* Copyright (C) 2013 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* 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 CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.android.location.provider;
|
||||
|
||||
import android.location.Location;
|
||||
|
||||
/**
|
||||
* Base class for sinks to interact with FusedLocationHardware.
|
||||
* This is mainly used by GmsCore Fused Provider.
|
||||
*/
|
||||
public abstract class FusedLocationHardwareSink {
|
||||
/*
|
||||
* Methods to provide a facade for IFusedLocationHardware
|
||||
*/
|
||||
public abstract void onLocationAvailable(Location[] locations);
|
||||
public abstract void onDiagnosticDataAvailable(String data);
|
||||
}
|
||||
@@ -0,0 +1,59 @@
|
||||
/*
|
||||
* Copyright (C) 2013 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* 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 CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.android.location.provider;
|
||||
|
||||
import android.hardware.location.IFusedLocationHardware;
|
||||
import android.location.IFusedProvider;
|
||||
import android.os.IBinder;
|
||||
|
||||
/**
|
||||
* Base class for Fused providers implemented as unbundled services.
|
||||
*
|
||||
* <p>Fused providers can be implemented as services and return the result of
|
||||
* {@link com.android.location.provider.FusedProvider#getBinder()} in its getBinder() method.
|
||||
*
|
||||
* <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() {
|
||||
@Override
|
||||
public void onFusedLocationHardwareChange(IFusedLocationHardware instance) {
|
||||
setFusedLocationHardware(new FusedLocationHardware(instance));
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Gets the Binder associated with the provider.
|
||||
* This is intended to be used for the onBind() method of a service that implements a fused
|
||||
* service.
|
||||
*
|
||||
* @return The IBinder instance associated with the provider.
|
||||
*/
|
||||
public IBinder getBinder() {
|
||||
return mProvider;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the FusedLocationHardware instance in the provider..
|
||||
* @param value The instance to set. This can be null in cases where the service connection
|
||||
* is disconnected.
|
||||
*/
|
||||
public abstract void setFusedLocationHardware(FusedLocationHardware value);
|
||||
}
|
||||
@@ -0,0 +1,106 @@
|
||||
/*
|
||||
* Copyright (C) 2013 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* 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 CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.android.location.provider;
|
||||
|
||||
import android.location.FusedBatchOptions;
|
||||
|
||||
/**
|
||||
* Class that exposes FusedBatchOptions to the GmsCore .
|
||||
*/
|
||||
public class GmsFusedBatchOptions {
|
||||
private FusedBatchOptions mOptions = new FusedBatchOptions();
|
||||
|
||||
/*
|
||||
* Methods that provide a facade for properties in FusedBatchOptions.
|
||||
*/
|
||||
public void setMaxPowerAllocationInMW(double value) {
|
||||
mOptions.setMaxPowerAllocationInMW(value);
|
||||
}
|
||||
|
||||
public double getMaxPowerAllocationInMW() {
|
||||
return mOptions.getMaxPowerAllocationInMW();
|
||||
}
|
||||
|
||||
public void setPeriodInNS(long value) {
|
||||
mOptions.setPeriodInNS(value);
|
||||
}
|
||||
|
||||
public long getPeriodInNS() {
|
||||
return mOptions.getPeriodInNS();
|
||||
}
|
||||
|
||||
public void setSourceToUse(int source) {
|
||||
mOptions.setSourceToUse(source);
|
||||
}
|
||||
|
||||
public void resetSourceToUse(int source) {
|
||||
mOptions.resetSourceToUse(source);
|
||||
}
|
||||
|
||||
public boolean isSourceToUseSet(int source) {
|
||||
return mOptions.isSourceToUseSet(source);
|
||||
}
|
||||
|
||||
public int getSourcesToUse() {
|
||||
return mOptions.getSourcesToUse();
|
||||
}
|
||||
|
||||
public void setFlag(int flag) {
|
||||
mOptions.setFlag(flag);
|
||||
}
|
||||
|
||||
public void resetFlag(int flag) {
|
||||
mOptions.resetFlag(flag);
|
||||
}
|
||||
|
||||
public boolean isFlagSet(int flag) {
|
||||
return mOptions.isFlagSet(flag);
|
||||
}
|
||||
|
||||
public int getFlags() {
|
||||
return mOptions.getFlags();
|
||||
}
|
||||
|
||||
/**
|
||||
* Definition of enum flag sets needed by this class.
|
||||
* Such values need to be kept in sync with the ones in fused_location.h
|
||||
*/
|
||||
|
||||
public static final class SourceTechnologies {
|
||||
public static int GNSS = 1<<0;
|
||||
public static int WIFI = 1<<1;
|
||||
public static int SENSORS = 1<<2;
|
||||
public static int CELL = 1<<3;
|
||||
public static int BLUETOOTH = 1<<4;
|
||||
}
|
||||
|
||||
public static final class BatchFlags {
|
||||
public static int WAKEUP_ON_FIFO_FULL = 1<<0;
|
||||
public static int CALLBACK_ON_LOCATION_FIX = 1<<1;
|
||||
}
|
||||
|
||||
/*
|
||||
* Method definitions for internal use.
|
||||
*/
|
||||
|
||||
/*
|
||||
* @hide
|
||||
*/
|
||||
public FusedBatchOptions getParcelableOptions() {
|
||||
return mOptions;
|
||||
}
|
||||
}
|
||||
@@ -63,6 +63,8 @@ import com.android.internal.content.PackageMonitor;
|
||||
import com.android.internal.location.ProviderProperties;
|
||||
import com.android.internal.location.ProviderRequest;
|
||||
import com.android.internal.os.BackgroundThread;
|
||||
import com.android.server.location.FlpHardwareProvider;
|
||||
import com.android.server.location.FusedProxy;
|
||||
import com.android.server.location.GeocoderProxy;
|
||||
import com.android.server.location.GeofenceProxy;
|
||||
import com.android.server.location.GeofenceManager;
|
||||
@@ -429,6 +431,17 @@ public class LocationManagerService extends ILocationManager.Stub {
|
||||
Slog.e(TAG, "no geofence provider found");
|
||||
}
|
||||
|
||||
// bind to fused provider
|
||||
// TODO: [GeofenceIntegration] bind #getGeofenceHardware() with the GeofenceProxy
|
||||
FlpHardwareProvider flpHardwareProvider = FlpHardwareProvider.getInstance(mContext);
|
||||
FusedProxy fusedProxy = FusedProxy.createAndBind(
|
||||
mContext,
|
||||
mLocationHandler,
|
||||
flpHardwareProvider.getLocationHardware());
|
||||
|
||||
if(fusedProxy == null) {
|
||||
Slog.e(TAG, "No FusedProvider found.");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -0,0 +1,344 @@
|
||||
/*
|
||||
* Copyright (C) 2013 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* 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 CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.android.server.location;
|
||||
|
||||
import android.hardware.location.GeofenceHardwareImpl;
|
||||
import android.hardware.location.IFusedLocationHardware;
|
||||
import android.hardware.location.IFusedLocationHardwareSink;
|
||||
import android.location.IFusedGeofenceHardware;
|
||||
import android.location.FusedBatchOptions;
|
||||
import android.location.Geofence;
|
||||
import android.location.Location;
|
||||
import android.location.LocationListener;
|
||||
import android.location.LocationManager;
|
||||
|
||||
import android.content.Context;
|
||||
import android.os.Bundle;
|
||||
import android.os.Handler;
|
||||
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
|
||||
* with the FLP HAL implementation.
|
||||
*
|
||||
* {@hide}
|
||||
*/
|
||||
public class FlpHardwareProvider {
|
||||
private GeofenceHardwareImpl mGeofenceHardwareSink = null;
|
||||
private IFusedLocationHardwareSink mLocationSink = null;
|
||||
|
||||
private static FlpHardwareProvider sSingletonInstance = null;
|
||||
|
||||
private final static String TAG = "FlpHardwareProvider";
|
||||
private final Context mContext;
|
||||
|
||||
public static FlpHardwareProvider getInstance(Context context) {
|
||||
if (sSingletonInstance == null) {
|
||||
sSingletonInstance = new FlpHardwareProvider(context);
|
||||
}
|
||||
|
||||
return sSingletonInstance;
|
||||
}
|
||||
|
||||
private FlpHardwareProvider(Context context) {
|
||||
mContext = context;
|
||||
|
||||
// register for listening for passive provider data
|
||||
Handler handler = new Handler();
|
||||
LocationManager manager = (LocationManager) mContext.getSystemService(
|
||||
Context.LOCATION_SERVICE);
|
||||
manager.requestLocationUpdates(
|
||||
LocationManager.PASSIVE_PROVIDER,
|
||||
0 /* minTime */,
|
||||
0 /* minDistance */,
|
||||
new NetworkLocationListener(),
|
||||
handler.getLooper());
|
||||
}
|
||||
|
||||
public static boolean isSupported() {
|
||||
return nativeIsSupported();
|
||||
}
|
||||
|
||||
/**
|
||||
* Private callback functions used by FLP HAL.
|
||||
*/
|
||||
// FlpCallbacks members
|
||||
private void onLocationReport(Location[] locations) {
|
||||
for (Location location : locations) {
|
||||
location.setProvider(LocationManager.FUSED_PROVIDER);
|
||||
// set the elapsed time-stamp just as GPS provider does
|
||||
location.setElapsedRealtimeNanos(SystemClock.elapsedRealtimeNanos());
|
||||
}
|
||||
|
||||
try {
|
||||
if (mLocationSink != null) {
|
||||
mLocationSink.onLocationAvailable(locations);
|
||||
}
|
||||
} catch (RemoteException e) {
|
||||
Log.e(TAG, "RemoteException calling onLocationAvailable");
|
||||
}
|
||||
}
|
||||
|
||||
// FlpDiagnosticCallbacks members
|
||||
private void onDataReport(String data) {
|
||||
try {
|
||||
if (mLocationSink != null) {
|
||||
mLocationSink.onDiagnosticDataAvailable(data);
|
||||
}
|
||||
} catch (RemoteException e) {
|
||||
Log.e(TAG, "RemoteException calling onDiagnosticDataAvailable");
|
||||
}
|
||||
}
|
||||
|
||||
// FlpGeofenceCallbacks members
|
||||
private void onGeofenceTransition(
|
||||
int geofenceId,
|
||||
Location location,
|
||||
int transition,
|
||||
long timestamp,
|
||||
int sourcesUsed
|
||||
) {
|
||||
// TODO: [GeofenceIntegration] change GeofenceHardwareImpl to accept a location object
|
||||
}
|
||||
|
||||
private void onGeofenceMonitorStatus(int status, int source, Location location) {
|
||||
// TODO: [GeofenceIntegration]
|
||||
}
|
||||
|
||||
private void onGeofenceAdd(int geofenceId, int result) {
|
||||
// TODO: [GeofenceIntegration] map between GPS and FLP results to pass a consistent status
|
||||
}
|
||||
|
||||
private void onGeofenceRemove(int geofenceId, int result) {
|
||||
// TODO: [GeofenceIntegration] map between GPS and FLP results to pass a consistent status
|
||||
}
|
||||
|
||||
private void onGeofencePause(int geofenceId, int result) {
|
||||
// TODO; [GeofenceIntegration] map between GPS and FLP results
|
||||
}
|
||||
|
||||
private void onGeofenceResume(int geofenceId, int result) {
|
||||
// TODO: [GeofenceIntegration] map between GPS and FLP results
|
||||
}
|
||||
|
||||
/**
|
||||
* Private native methods accessing FLP HAL.
|
||||
*/
|
||||
static { nativeClassInit(); }
|
||||
|
||||
// Core members
|
||||
private static native void nativeClassInit();
|
||||
private static native boolean nativeIsSupported();
|
||||
|
||||
// FlpLocationInterface members
|
||||
private native void nativeInit();
|
||||
private native int nativeGetBatchSize();
|
||||
private native void nativeStartBatching(int requestId, FusedBatchOptions options);
|
||||
private native void nativeUpdateBatchingOptions(int requestId, FusedBatchOptions optionsObject);
|
||||
private native void nativeStopBatching(int id);
|
||||
private native void nativeRequestBatchedLocation(int lastNLocations);
|
||||
private native void nativeInjectLocation(Location location);
|
||||
// TODO [Fix] sort out the lifetime of the instance
|
||||
private native void nativeCleanup();
|
||||
|
||||
// FlpDiagnosticsInterface members
|
||||
private native boolean nativeIsDiagnosticSupported();
|
||||
private native void nativeInjectDiagnosticData(String data);
|
||||
|
||||
// FlpDeviceContextInterface members
|
||||
private native boolean nativeIsDeviceContextSupported();
|
||||
private native void nativeInjectDeviceContext(int deviceEnabledContext);
|
||||
|
||||
// FlpGeofencingInterface members
|
||||
private native boolean nativeIsGeofencingSupported();
|
||||
private native void nativeAddGeofences(int[] geofenceIdsArray, Geofence[] geofencesArray);
|
||||
private native void nativePauseGeofence(int geofenceId);
|
||||
private native void nativeResumeGeofence(int geofenceId, int monitorTransitions);
|
||||
private native void nativeModifyGeofenceOption(
|
||||
int geofenceId,
|
||||
int lastTransition,
|
||||
int monitorTransitions,
|
||||
int notificationResponsiveness,
|
||||
int unknownTimer,
|
||||
int sourcesToUse);
|
||||
private native void nativeRemoveGeofences(int[] geofenceIdsArray);
|
||||
|
||||
/**
|
||||
* Interface implementations for services built on top of this functionality.
|
||||
*/
|
||||
public static final String LOCATION = "Location";
|
||||
public static final String GEOFENCING = "Geofencing";
|
||||
|
||||
public IFusedLocationHardware getLocationHardware() {
|
||||
nativeInit();
|
||||
return mLocationHardware;
|
||||
}
|
||||
|
||||
public IFusedGeofenceHardware getGeofenceHardware() {
|
||||
nativeInit();
|
||||
return mGeofenceHardwareService;
|
||||
}
|
||||
|
||||
private final IFusedLocationHardware mLocationHardware = new IFusedLocationHardware.Stub() {
|
||||
@Override
|
||||
public void registerSink(IFusedLocationHardwareSink eventSink) {
|
||||
// only one sink is allowed at the moment
|
||||
if (mLocationSink != null) {
|
||||
throw new RuntimeException("IFusedLocationHardware does not support multiple sinks");
|
||||
}
|
||||
|
||||
mLocationSink = eventSink;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void unregisterSink(IFusedLocationHardwareSink eventSink) {
|
||||
// don't throw if the sink is not registered, simply make it a no-op
|
||||
if (mLocationSink == eventSink) {
|
||||
mLocationSink = null;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getSupportedBatchSize() {
|
||||
return nativeGetBatchSize();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void startBatching(int requestId, FusedBatchOptions options) {
|
||||
nativeStartBatching(requestId, options);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void stopBatching(int requestId) {
|
||||
nativeStopBatching(requestId);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateBatchingOptions(int requestId, FusedBatchOptions options) {
|
||||
nativeUpdateBatchingOptions(requestId, options);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void requestBatchOfLocations(int batchSizeRequested) {
|
||||
nativeRequestBatchedLocation(batchSizeRequested);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean supportsDiagnosticDataInjection() {
|
||||
return nativeIsDiagnosticSupported();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void injectDiagnosticData(String data) {
|
||||
nativeInjectDiagnosticData(data);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean supportsDeviceContextInjection() {
|
||||
return nativeIsDeviceContextSupported();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void injectDeviceContext(int deviceEnabledContext) {
|
||||
nativeInjectDeviceContext(deviceEnabledContext);
|
||||
}
|
||||
};
|
||||
|
||||
private final IFusedGeofenceHardware mGeofenceHardwareService =
|
||||
new IFusedGeofenceHardware.Stub() {
|
||||
@Override
|
||||
public boolean isSupported() {
|
||||
return nativeIsGeofencingSupported();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addGeofences(int[] geofenceIdsArray, Geofence[] geofencesArray) {
|
||||
nativeAddGeofences(geofenceIdsArray, geofencesArray);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void removeGeofences(int[] geofenceIds) {
|
||||
nativeRemoveGeofences(geofenceIds);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void pauseMonitoringGeofence(int geofenceId) {
|
||||
nativePauseGeofence(geofenceId);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void resumeMonitoringGeofence(int geofenceId, int monitorTransitions) {
|
||||
nativeResumeGeofence(geofenceId, monitorTransitions);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void modifyGeofenceOptions(int geofenceId,
|
||||
int lastTransition,
|
||||
int monitorTransitions,
|
||||
int notificationResponsiveness,
|
||||
int unknownTimer
|
||||
) {
|
||||
// TODO: [GeofenceIntegration] set sourcesToUse to the right value
|
||||
// TODO: expose sourcesToUse externally when needed
|
||||
nativeModifyGeofenceOption(
|
||||
geofenceId,
|
||||
lastTransition,
|
||||
monitorTransitions,
|
||||
notificationResponsiveness,
|
||||
unknownTimer,
|
||||
/* sourcesToUse */ 0xFFFF);
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Internal classes and functions used by the provider.
|
||||
*/
|
||||
private final class NetworkLocationListener implements LocationListener {
|
||||
@Override
|
||||
public void onLocationChanged(Location location) {
|
||||
if (
|
||||
!LocationManager.NETWORK_PROVIDER.equals(location.getProvider()) ||
|
||||
!location.hasAccuracy()
|
||||
) {
|
||||
return;
|
||||
}
|
||||
|
||||
nativeInjectLocation(location);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onStatusChanged(String provider, int status, Bundle extras) { }
|
||||
|
||||
@Override
|
||||
public void onProviderEnabled(String provider) { }
|
||||
|
||||
@Override
|
||||
public void onProviderDisabled(String provider) { }
|
||||
}
|
||||
|
||||
private GeofenceHardwareImpl getGeofenceHardwareSink() {
|
||||
if (mGeofenceHardwareSink == null) {
|
||||
// TODO: [GeofenceIntegration] we need to register ourselves with GeofenceHardwareImpl
|
||||
mGeofenceHardwareSink = GeofenceHardwareImpl.getInstance(mContext);
|
||||
}
|
||||
|
||||
return mGeofenceHardwareSink;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,119 @@
|
||||
/*
|
||||
* Copyright (C) 2013 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* 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 CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.android.server.location;
|
||||
|
||||
import android.content.Context;
|
||||
import android.hardware.location.IFusedLocationHardware;
|
||||
import android.hardware.location.IFusedLocationHardwareSink;
|
||||
import android.location.FusedBatchOptions;
|
||||
import android.os.RemoteException;
|
||||
|
||||
/**
|
||||
* FusedLocationHardware decorator that adds permission checking.
|
||||
* @hide
|
||||
*/
|
||||
public class FusedLocationHardwareSecure extends IFusedLocationHardware.Stub {
|
||||
private final IFusedLocationHardware mLocationHardware;
|
||||
private final Context mContext;
|
||||
private final String mPermissionId;
|
||||
|
||||
public FusedLocationHardwareSecure(
|
||||
IFusedLocationHardware locationHardware,
|
||||
Context context,
|
||||
String permissionId) {
|
||||
mLocationHardware = locationHardware;
|
||||
mContext = context;
|
||||
mPermissionId = permissionId;
|
||||
}
|
||||
|
||||
private void checkPermissions() {
|
||||
mContext.enforceCallingPermission(
|
||||
mPermissionId,
|
||||
String.format(
|
||||
"Permission '%s' not granted to access FusedLocationHardware",
|
||||
mPermissionId));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void registerSink(IFusedLocationHardwareSink eventSink) throws RemoteException {
|
||||
checkPermissions();
|
||||
mLocationHardware.registerSink(eventSink);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void unregisterSink(IFusedLocationHardwareSink eventSink) throws RemoteException {
|
||||
checkPermissions();
|
||||
mLocationHardware.unregisterSink(eventSink);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getSupportedBatchSize() throws RemoteException {
|
||||
checkPermissions();
|
||||
return mLocationHardware.getSupportedBatchSize();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void startBatching(int id, FusedBatchOptions batchOptions) throws RemoteException {
|
||||
checkPermissions();
|
||||
mLocationHardware.startBatching(id, batchOptions);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void stopBatching(int id) throws RemoteException {
|
||||
checkPermissions();
|
||||
mLocationHardware.stopBatching(id);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateBatchingOptions(
|
||||
int id,
|
||||
FusedBatchOptions batchoOptions
|
||||
) throws RemoteException {
|
||||
checkPermissions();
|
||||
mLocationHardware.updateBatchingOptions(id, batchoOptions);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void requestBatchOfLocations(int batchSizeRequested) throws RemoteException {
|
||||
checkPermissions();
|
||||
mLocationHardware.requestBatchOfLocations(batchSizeRequested);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean supportsDiagnosticDataInjection() throws RemoteException {
|
||||
checkPermissions();
|
||||
return mLocationHardware.supportsDiagnosticDataInjection();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void injectDiagnosticData(String data) throws RemoteException {
|
||||
checkPermissions();
|
||||
mLocationHardware.injectDiagnosticData(data);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean supportsDeviceContextInjection() throws RemoteException {
|
||||
checkPermissions();
|
||||
return mLocationHardware.supportsDeviceContextInjection();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void injectDeviceContext(int deviceEnabledContext) throws RemoteException {
|
||||
checkPermissions();
|
||||
mLocationHardware.injectDeviceContext(deviceEnabledContext);
|
||||
}
|
||||
}
|
||||
116
services/java/com/android/server/location/FusedProxy.java
Normal file
116
services/java/com/android/server/location/FusedProxy.java
Normal file
@@ -0,0 +1,116 @@
|
||||
/*
|
||||
* Copyright (C) 2013 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (The "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* 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.
|
||||
*/
|
||||
|
||||
package com.android.server.location;
|
||||
|
||||
import com.android.server.ServiceWatcher;
|
||||
|
||||
import android.Manifest;
|
||||
import android.content.Context;
|
||||
import android.hardware.location.IFusedLocationHardware;
|
||||
import android.location.IFusedProvider;
|
||||
import android.os.Handler;
|
||||
import android.os.RemoteException;
|
||||
import android.util.Log;
|
||||
|
||||
/**
|
||||
* Proxy that helps bind GCore FusedProvider implementations to the Fused Hardware instances.
|
||||
*
|
||||
* @hide
|
||||
*/
|
||||
public final class FusedProxy {
|
||||
private final String TAG = "FusedProxy";
|
||||
|
||||
private ServiceWatcher mServiceWatcher;
|
||||
|
||||
private FusedLocationHardwareSecure mLocationHardware;
|
||||
|
||||
/**
|
||||
* Constructor of the class.
|
||||
* This is private as the class follows a factory pattern for construction.
|
||||
*
|
||||
* @param context The context needed for construction.
|
||||
* @param handler The handler needed for construction.
|
||||
* @param locationHardware The instance of the Fused location hardware assigned to the proxy.
|
||||
*/
|
||||
private FusedProxy(Context context, Handler handler, IFusedLocationHardware locationHardware) {
|
||||
mLocationHardware = new FusedLocationHardwareSecure(
|
||||
locationHardware,
|
||||
context,
|
||||
Manifest.permission.LOCATION_HARDWARE);
|
||||
Runnable newServiceWork = new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
bindProvider(mLocationHardware);
|
||||
}
|
||||
};
|
||||
|
||||
// prepare the connection to the provider
|
||||
mServiceWatcher = new ServiceWatcher(
|
||||
context,
|
||||
TAG,
|
||||
"com.android.location.service.FusedProvider",
|
||||
com.android.internal.R.bool.config_enableFusedLocationOverlay,
|
||||
com.android.internal.R.string.config_fusedLocationProviderPackageName,
|
||||
com.android.internal.R.array.config_locationProviderPackageNames,
|
||||
newServiceWork,
|
||||
handler);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates an instance of the proxy and binds it to the appropriate FusedProvider.
|
||||
*
|
||||
* @param context The context needed for construction.
|
||||
* @param handler The handler needed for construction.
|
||||
* @param locationHardware The instance of the Fused location hardware assigned to the proxy.
|
||||
*
|
||||
* @return An instance of the proxy if it could be bound, null otherwise.
|
||||
*/
|
||||
public static FusedProxy createAndBind(
|
||||
Context context,
|
||||
Handler handler,
|
||||
IFusedLocationHardware locationHardware
|
||||
) {
|
||||
FusedProxy fusedProxy = new FusedProxy(context, handler, locationHardware);
|
||||
|
||||
// try to bind the Fused provider
|
||||
if (!fusedProxy.mServiceWatcher.start()) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return fusedProxy;
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper function to bind the FusedLocationHardware to the appropriate FusedProvider instance.
|
||||
*
|
||||
* @param locationHardware The FusedLocationHardware instance to use for the binding operation.
|
||||
*/
|
||||
private void bindProvider(IFusedLocationHardware locationHardware) {
|
||||
IFusedProvider provider = IFusedProvider.Stub.asInterface(mServiceWatcher.getBinder());
|
||||
|
||||
if (provider == null) {
|
||||
Log.e(TAG, "No instance of FusedProvider found on FusedLocationHardware connected.");
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
provider.onFusedLocationHardwareChange(locationHardware);
|
||||
} catch (RemoteException e) {
|
||||
Log.e(TAG, e.toString());
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -15,6 +15,7 @@ LOCAL_SRC_FILES:= \
|
||||
com_android_server_UsbHostManager.cpp \
|
||||
com_android_server_VibratorService.cpp \
|
||||
com_android_server_location_GpsLocationProvider.cpp \
|
||||
com_android_server_location_FlpHardwareProvider.cpp \
|
||||
com_android_server_connectivity_Vpn.cpp \
|
||||
onload.cpp
|
||||
|
||||
|
||||
901
services/jni/com_android_server_location_FlpHardwareProvider.cpp
Normal file
901
services/jni/com_android_server_location_FlpHardwareProvider.cpp
Normal file
@@ -0,0 +1,901 @@
|
||||
/*
|
||||
* Copyright (C) 2013 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the license at
|
||||
*
|
||||
* http://www.apache.org/license/LICENSE-2.0
|
||||
*
|
||||
* 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 CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the license.
|
||||
*/
|
||||
|
||||
#define LOG_TAG "FuseLocationProvider"
|
||||
#define LOG_NDEBUG 0
|
||||
|
||||
#define WAKE_LOCK_NAME "FLP"
|
||||
#define LOCATION_CLASS_NAME "android/location/Location"
|
||||
|
||||
#include "jni.h"
|
||||
#include "JNIHelp.h"
|
||||
#include "android_runtime/AndroidRuntime.h"
|
||||
#include "hardware/fused_location.h"
|
||||
#include "hardware_legacy/power.h"
|
||||
|
||||
static jobject sCallbacksObj = NULL;
|
||||
static JNIEnv *sCallbackEnv = NULL;
|
||||
static hw_device_t* sHardwareDevice = NULL;
|
||||
|
||||
static jmethodID sOnLocationReport = NULL;
|
||||
static jmethodID sOnDataReport = NULL;
|
||||
static jmethodID sOnGeofenceTransition = NULL;
|
||||
static jmethodID sOnGeofenceMonitorStatus = NULL;
|
||||
static jmethodID sOnGeofenceAdd = NULL;
|
||||
static jmethodID sOnGeofenceRemove = NULL;
|
||||
static jmethodID sOnGeofencePause = NULL;
|
||||
static jmethodID sOnGeofenceResume = NULL;
|
||||
|
||||
static const FlpLocationInterface* sFlpInterface = NULL;
|
||||
static const FlpDiagnosticInterface* sFlpDiagnosticInterface = NULL;
|
||||
static const FlpGeofencingInterface* sFlpGeofencingInterface = NULL;
|
||||
static const FlpDeviceContextInterface* sFlpDeviceContextInterface = NULL;
|
||||
|
||||
namespace android {
|
||||
|
||||
static inline void CheckExceptions(JNIEnv* env, const char* methodName) {
|
||||
if(!env->ExceptionCheck()) {
|
||||
return;
|
||||
}
|
||||
|
||||
ALOGE("An exception was thrown by '%s'.", methodName);
|
||||
LOGE_EX(env);
|
||||
env->ExceptionClear();
|
||||
}
|
||||
|
||||
static inline void ThrowOnError(
|
||||
JNIEnv* env,
|
||||
int resultCode,
|
||||
const char* methodName) {
|
||||
if(resultCode == FLP_RESULT_SUCCESS) {
|
||||
return;
|
||||
}
|
||||
|
||||
ALOGE("Error %d in '%s'", resultCode, methodName);
|
||||
jclass exceptionClass = env->FindClass("java/lang/RuntimeException");
|
||||
env->ThrowNew(exceptionClass, methodName);
|
||||
}
|
||||
|
||||
static bool IsValidCallbackThread() {
|
||||
JNIEnv* env = AndroidRuntime::getJNIEnv();
|
||||
|
||||
if(sCallbackEnv == NULL || sCallbackEnv != env) {
|
||||
ALOGE("CallbackThread check fail: env=%p, expected=%p", env, sCallbackEnv);
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static int SetThreadEvent(ThreadEvent event) {
|
||||
JavaVM* javaVm = AndroidRuntime::getJavaVM();
|
||||
|
||||
switch(event) {
|
||||
case ASSOCIATE_JVM:
|
||||
{
|
||||
if(sCallbackEnv != NULL) {
|
||||
ALOGE(
|
||||
"Attempted to associate callback in '%s'. Callback already associated.",
|
||||
__FUNCTION__
|
||||
);
|
||||
return FLP_RESULT_ERROR;
|
||||
}
|
||||
|
||||
JavaVMAttachArgs args = {
|
||||
JNI_VERSION_1_6,
|
||||
"FLP Service Callback Thread",
|
||||
/* group */ NULL
|
||||
};
|
||||
|
||||
jint attachResult = javaVm->AttachCurrentThread(&sCallbackEnv, &args);
|
||||
if (attachResult != 0) {
|
||||
ALOGE("Callback thread attachment error: %d", attachResult);
|
||||
return FLP_RESULT_ERROR;
|
||||
}
|
||||
|
||||
ALOGV("Callback thread attached: %p", sCallbackEnv);
|
||||
break;
|
||||
}
|
||||
case DISASSOCIATE_JVM:
|
||||
{
|
||||
if (!IsValidCallbackThread()) {
|
||||
ALOGE(
|
||||
"Attempted to dissasociate an unnownk callback thread : '%s'.",
|
||||
__FUNCTION__
|
||||
);
|
||||
return FLP_RESULT_ERROR;
|
||||
}
|
||||
|
||||
if (javaVm->DetachCurrentThread() != 0) {
|
||||
return FLP_RESULT_ERROR;
|
||||
}
|
||||
|
||||
sCallbackEnv = NULL;
|
||||
break;
|
||||
}
|
||||
default:
|
||||
ALOGE("Invalid ThreadEvent request %d", event);
|
||||
return FLP_RESULT_ERROR;
|
||||
}
|
||||
|
||||
return FLP_RESULT_SUCCESS;
|
||||
}
|
||||
|
||||
/*
|
||||
* Initializes the FlpHardwareProvider class from the native side by opening
|
||||
* the HW module and obtaining the proper interfaces.
|
||||
*/
|
||||
static void ClassInit(JNIEnv* env, jclass clazz) {
|
||||
// get references to the Java provider methods
|
||||
sOnLocationReport = env->GetMethodID(
|
||||
clazz,
|
||||
"onLocationReport",
|
||||
"([Landroid/location/Location;)V");
|
||||
sOnDataReport = env->GetMethodID(
|
||||
clazz,
|
||||
"onDataReport",
|
||||
"(Ljava/lang/String;)V"
|
||||
);
|
||||
sOnGeofenceTransition = env->GetMethodID(
|
||||
clazz,
|
||||
"onGeofenceTransition",
|
||||
"(ILandroid/location/Location;IJI)V"
|
||||
);
|
||||
sOnGeofenceMonitorStatus = env->GetMethodID(
|
||||
clazz,
|
||||
"onGeofenceMonitorStatus",
|
||||
"(IILandroid/location/Location;)V"
|
||||
);
|
||||
sOnGeofenceAdd = env->GetMethodID(clazz, "onGeofenceAdd", "(II)V");
|
||||
sOnGeofenceRemove = env->GetMethodID(clazz, "onGeofenceRemove", "(II)V");
|
||||
sOnGeofencePause = env->GetMethodID(clazz, "onGeofencePause", "(II)V");
|
||||
sOnGeofenceResume = env->GetMethodID(clazz, "onGeofenceResume", "(II)V");
|
||||
}
|
||||
|
||||
/*
|
||||
* Helper function to unwrap a java object back into a FlpLocation structure.
|
||||
*/
|
||||
static void TranslateFromObject(
|
||||
JNIEnv* env,
|
||||
jobject locationObject,
|
||||
FlpLocation& location) {
|
||||
location.size = sizeof(FlpLocation);
|
||||
location.flags = 0;
|
||||
|
||||
jclass locationClass = env->GetObjectClass(locationObject);
|
||||
|
||||
jmethodID getLatitude = env->GetMethodID(locationClass, "getLatitude", "()D");
|
||||
location.latitude = env->CallDoubleMethod(locationObject, getLatitude);
|
||||
jmethodID getLongitude = env->GetMethodID(locationClass, "getLongitude", "()D");
|
||||
location.longitude = env->CallDoubleMethod(locationObject, getLongitude);
|
||||
jmethodID getTime = env->GetMethodID(locationClass, "getTime", "()J");
|
||||
location.timestamp = env->CallLongMethod(locationObject, getTime);
|
||||
location.flags |= FLP_LOCATION_HAS_LAT_LONG;
|
||||
|
||||
jmethodID hasAltitude = env->GetMethodID(locationClass, "hasAltitude", "()Z");
|
||||
if (env->CallBooleanMethod(locationObject, hasAltitude)) {
|
||||
jmethodID getAltitude = env->GetMethodID(locationClass, "getAltitude", "()D");
|
||||
location.altitude = env->CallDoubleMethod(locationObject, getAltitude);
|
||||
location.flags |= FLP_LOCATION_HAS_ALTITUDE;
|
||||
}
|
||||
|
||||
jmethodID hasSpeed = env->GetMethodID(locationClass, "hasSpeed", "()Z");
|
||||
if (env->CallBooleanMethod(locationObject, hasSpeed)) {
|
||||
jmethodID getSpeed = env->GetMethodID(locationClass, "getSpeed", "()F");
|
||||
location.speed = env->CallFloatMethod(locationObject, getSpeed);
|
||||
location.flags |= FLP_LOCATION_HAS_SPEED;
|
||||
}
|
||||
|
||||
jmethodID hasBearing = env->GetMethodID(locationClass, "hasBearing", "()Z");
|
||||
if (env->CallBooleanMethod(locationObject, hasBearing)) {
|
||||
jmethodID getBearing = env->GetMethodID(locationClass, "getBearing", "()F");
|
||||
location.bearing = env->CallFloatMethod(locationObject, getBearing);
|
||||
location.flags |= FLP_LOCATION_HAS_BEARING;
|
||||
}
|
||||
|
||||
jmethodID hasAccuracy = env->GetMethodID(locationClass, "hasAccuracy", "()Z");
|
||||
if (env->CallBooleanMethod(locationObject, hasAccuracy)) {
|
||||
jmethodID getAccuracy = env->GetMethodID(
|
||||
locationClass,
|
||||
"getAccuracy",
|
||||
"()F"
|
||||
);
|
||||
location.accuracy = env->CallFloatMethod(locationObject, getAccuracy);
|
||||
location.flags |= FLP_LOCATION_HAS_ACCURACY;
|
||||
}
|
||||
|
||||
// TODO: wire sources_used if Location class exposes them
|
||||
}
|
||||
|
||||
/*
|
||||
* Helper function to unwrap FlpBatchOptions from the Java Runtime calls.
|
||||
*/
|
||||
static void TranslateFromObject(
|
||||
JNIEnv* env,
|
||||
jobject batchOptionsObject,
|
||||
FlpBatchOptions& batchOptions) {
|
||||
jclass batchOptionsClass = env->GetObjectClass(batchOptionsObject);
|
||||
|
||||
jmethodID getMaxPower = env->GetMethodID(
|
||||
batchOptionsClass,
|
||||
"getMaxPowerAllocationInMW",
|
||||
"()D"
|
||||
);
|
||||
batchOptions.max_power_allocation_mW = env->CallDoubleMethod(
|
||||
batchOptionsObject,
|
||||
getMaxPower
|
||||
);
|
||||
|
||||
jmethodID getPeriod = env->GetMethodID(
|
||||
batchOptionsClass,
|
||||
"getPeriodInNS",
|
||||
"()J"
|
||||
);
|
||||
batchOptions.period_ns = env->CallLongMethod(batchOptionsObject, getPeriod);
|
||||
|
||||
jmethodID getSourcesToUse = env->GetMethodID(
|
||||
batchOptionsClass,
|
||||
"getSourcesToUse",
|
||||
"()I"
|
||||
);
|
||||
batchOptions.sources_to_use = env->CallIntMethod(
|
||||
batchOptionsObject,
|
||||
getSourcesToUse
|
||||
);
|
||||
|
||||
jmethodID getFlags = env->GetMethodID(batchOptionsClass, "getFlags", "()I");
|
||||
batchOptions.flags = env->CallIntMethod(batchOptionsObject, getFlags);
|
||||
}
|
||||
|
||||
/*
|
||||
* Helper function to transform FlpLocation into a java object.
|
||||
*/
|
||||
static void TranslateToObject(const FlpLocation* location, jobject& locationObject) {
|
||||
jclass locationClass = sCallbackEnv->FindClass(LOCATION_CLASS_NAME);
|
||||
jmethodID locationCtor = sCallbackEnv->GetMethodID(
|
||||
locationClass,
|
||||
"<init>",
|
||||
"(Ljava/lang/String;)V"
|
||||
);
|
||||
|
||||
// the provider is set in the upper JVM layer
|
||||
locationObject = sCallbackEnv->NewObject(locationClass, locationCtor, NULL);
|
||||
jint flags = location->flags;
|
||||
|
||||
// set the valid information in the object
|
||||
if (flags & FLP_LOCATION_HAS_LAT_LONG) {
|
||||
jmethodID setLatitude = sCallbackEnv->GetMethodID(
|
||||
locationClass,
|
||||
"setLatitude",
|
||||
"(D)V"
|
||||
);
|
||||
sCallbackEnv->CallVoidMethod(locationObject, setLatitude, location->latitude);
|
||||
|
||||
jmethodID setLongitude = sCallbackEnv->GetMethodID(
|
||||
locationClass,
|
||||
"setLongitude",
|
||||
"(D)V"
|
||||
);
|
||||
sCallbackEnv->CallVoidMethod(
|
||||
locationObject,
|
||||
setLongitude,
|
||||
location->longitude
|
||||
);
|
||||
|
||||
jmethodID setTime = sCallbackEnv->GetMethodID(
|
||||
locationClass,
|
||||
"setTime",
|
||||
"(J)V"
|
||||
);
|
||||
sCallbackEnv->CallVoidMethod(locationObject, setTime, location->timestamp);
|
||||
}
|
||||
|
||||
if (flags & FLP_LOCATION_HAS_ALTITUDE) {
|
||||
jmethodID setAltitude = sCallbackEnv->GetMethodID(
|
||||
locationClass,
|
||||
"setAltitude",
|
||||
"(D)V"
|
||||
);
|
||||
sCallbackEnv->CallVoidMethod(locationObject, setAltitude, location->altitude);
|
||||
}
|
||||
|
||||
if (flags & FLP_LOCATION_HAS_SPEED) {
|
||||
jmethodID setSpeed = sCallbackEnv->GetMethodID(
|
||||
locationClass,
|
||||
"setSpeed",
|
||||
"(F)V"
|
||||
);
|
||||
sCallbackEnv->CallVoidMethod(locationObject, setSpeed, location->speed);
|
||||
}
|
||||
|
||||
if (flags & FLP_LOCATION_HAS_BEARING) {
|
||||
jmethodID setBearing = sCallbackEnv->GetMethodID(
|
||||
locationClass,
|
||||
"setBearing",
|
||||
"(F)V"
|
||||
);
|
||||
sCallbackEnv->CallVoidMethod(locationObject, setBearing, location->bearing);
|
||||
}
|
||||
|
||||
if (flags & FLP_LOCATION_HAS_ACCURACY) {
|
||||
jmethodID setAccuracy = sCallbackEnv->GetMethodID(
|
||||
locationClass,
|
||||
"setAccuracy",
|
||||
"(F)V"
|
||||
);
|
||||
sCallbackEnv->CallVoidMethod(locationObject, setAccuracy, location->accuracy);
|
||||
}
|
||||
|
||||
// TODO: wire FlpLocation::sources_used when needed
|
||||
}
|
||||
|
||||
/*
|
||||
* Helper function to serialize FlpLocation structures.
|
||||
*/
|
||||
static void TranslateToObjectArray(
|
||||
int32_t locationsCount,
|
||||
FlpLocation** locations,
|
||||
jobjectArray& locationsArray) {
|
||||
jclass locationClass = sCallbackEnv->FindClass(LOCATION_CLASS_NAME);
|
||||
locationsArray = sCallbackEnv->NewObjectArray(
|
||||
locationsCount,
|
||||
locationClass,
|
||||
/* initialElement */ NULL
|
||||
);
|
||||
|
||||
for (int i = 0; i < locationsCount; ++i) {
|
||||
jobject locationObject = NULL;
|
||||
TranslateToObject(locations[i], locationObject);
|
||||
sCallbackEnv->SetObjectArrayElement(locationsArray, i, locationObject);
|
||||
sCallbackEnv->DeleteLocalRef(locationObject);
|
||||
}
|
||||
}
|
||||
|
||||
static void LocationCallback(int32_t locationsCount, FlpLocation** locations) {
|
||||
if(!IsValidCallbackThread()) {
|
||||
return;
|
||||
}
|
||||
|
||||
if(locationsCount == 0 || locations == NULL) {
|
||||
ALOGE(
|
||||
"Invalid LocationCallback. Count: %d, Locations: %p",
|
||||
locationsCount,
|
||||
locations
|
||||
);
|
||||
return;
|
||||
}
|
||||
|
||||
jobjectArray locationsArray = NULL;
|
||||
TranslateToObjectArray(locationsCount, locations, locationsArray);
|
||||
|
||||
sCallbackEnv->CallVoidMethod(
|
||||
sCallbacksObj,
|
||||
sOnLocationReport,
|
||||
locationsArray
|
||||
);
|
||||
CheckExceptions(sCallbackEnv, __FUNCTION__);
|
||||
}
|
||||
|
||||
static void AcquireWakelock() {
|
||||
acquire_wake_lock(PARTIAL_WAKE_LOCK, WAKE_LOCK_NAME);
|
||||
}
|
||||
|
||||
static void ReleaseWakelock() {
|
||||
release_wake_lock(WAKE_LOCK_NAME);
|
||||
}
|
||||
|
||||
FlpCallbacks sFlpCallbacks = {
|
||||
sizeof(FlpCallbacks),
|
||||
LocationCallback,
|
||||
AcquireWakelock,
|
||||
ReleaseWakelock,
|
||||
SetThreadEvent
|
||||
};
|
||||
|
||||
static void ReportData(char* data, int length) {
|
||||
jstring stringData = NULL;
|
||||
|
||||
if(length != 0 && data != NULL) {
|
||||
stringData = sCallbackEnv->NewString(reinterpret_cast<jchar*>(data), length);
|
||||
} else {
|
||||
ALOGE("Invalid ReportData callback. Length: %d, Data: %p", length, data);
|
||||
return;
|
||||
}
|
||||
|
||||
sCallbackEnv->CallVoidMethod(sCallbacksObj, sOnDataReport, stringData);
|
||||
CheckExceptions(sCallbackEnv, __FUNCTION__);
|
||||
}
|
||||
|
||||
FlpDiagnosticCallbacks sFlpDiagnosticCallbacks = {
|
||||
sizeof(FlpDiagnosticCallbacks),
|
||||
SetThreadEvent,
|
||||
ReportData
|
||||
};
|
||||
|
||||
static void GeofenceTransitionCallback(
|
||||
int32_t geofenceId,
|
||||
FlpLocation* location,
|
||||
int32_t transition,
|
||||
FlpUtcTime timestamp,
|
||||
uint32_t sourcesUsed
|
||||
) {
|
||||
if(!IsValidCallbackThread()) {
|
||||
return;
|
||||
}
|
||||
|
||||
if(location == NULL) {
|
||||
ALOGE("GeofenceTransition received with invalid location: %p", location);
|
||||
return;
|
||||
}
|
||||
|
||||
jobject locationObject = NULL;
|
||||
TranslateToObject(location, locationObject);
|
||||
|
||||
sCallbackEnv->CallVoidMethod(
|
||||
sCallbacksObj,
|
||||
sOnGeofenceTransition,
|
||||
geofenceId,
|
||||
locationObject,
|
||||
transition,
|
||||
timestamp,
|
||||
sourcesUsed
|
||||
);
|
||||
CheckExceptions(sCallbackEnv, __FUNCTION__);
|
||||
}
|
||||
|
||||
static void GeofenceMonitorStatusCallback(
|
||||
int32_t status,
|
||||
uint32_t source,
|
||||
FlpLocation* lastLocation) {
|
||||
if(!IsValidCallbackThread()) {
|
||||
return;
|
||||
}
|
||||
|
||||
jobject locationObject = NULL;
|
||||
if(lastLocation != NULL) {
|
||||
TranslateToObject(lastLocation, locationObject);
|
||||
}
|
||||
|
||||
sCallbackEnv->CallVoidMethod(
|
||||
sCallbacksObj,
|
||||
sOnGeofenceMonitorStatus,
|
||||
status,
|
||||
source,
|
||||
locationObject
|
||||
);
|
||||
CheckExceptions(sCallbackEnv, __FUNCTION__);
|
||||
}
|
||||
|
||||
static void GeofenceAddCallback(int32_t geofenceId, int32_t result) {
|
||||
if(!IsValidCallbackThread()) {
|
||||
return;
|
||||
}
|
||||
|
||||
sCallbackEnv->CallVoidMethod(sCallbacksObj, sOnGeofenceAdd, geofenceId, result);
|
||||
CheckExceptions(sCallbackEnv, __FUNCTION__);
|
||||
}
|
||||
|
||||
static void GeofenceRemoveCallback(int32_t geofenceId, int32_t result) {
|
||||
if(!IsValidCallbackThread()) {
|
||||
return;
|
||||
}
|
||||
|
||||
sCallbackEnv->CallVoidMethod(
|
||||
sCallbacksObj,
|
||||
sOnGeofenceRemove,
|
||||
geofenceId,
|
||||
result
|
||||
);
|
||||
CheckExceptions(sCallbackEnv, __FUNCTION__);
|
||||
}
|
||||
|
||||
static void GeofencePauseCallback(int32_t geofenceId, int32_t result) {
|
||||
if(!IsValidCallbackThread()) {
|
||||
return;
|
||||
}
|
||||
|
||||
sCallbackEnv->CallVoidMethod(
|
||||
sCallbacksObj,
|
||||
sOnGeofencePause,
|
||||
geofenceId,
|
||||
result
|
||||
);
|
||||
CheckExceptions(sCallbackEnv, __FUNCTION__);
|
||||
}
|
||||
|
||||
static void GeofenceResumeCallback(int32_t geofenceId, int32_t result) {
|
||||
if(!IsValidCallbackThread()) {
|
||||
return;
|
||||
}
|
||||
|
||||
sCallbackEnv->CallVoidMethod(
|
||||
sCallbacksObj,
|
||||
sOnGeofenceResume,
|
||||
geofenceId,
|
||||
result
|
||||
);
|
||||
CheckExceptions(sCallbackEnv, __FUNCTION__);
|
||||
}
|
||||
|
||||
FlpGeofenceCallbacks sFlpGeofenceCallbacks = {
|
||||
sizeof(FlpGeofenceCallbacks),
|
||||
GeofenceTransitionCallback,
|
||||
GeofenceMonitorStatusCallback,
|
||||
GeofenceAddCallback,
|
||||
GeofenceRemoveCallback,
|
||||
GeofencePauseCallback,
|
||||
GeofenceResumeCallback,
|
||||
SetThreadEvent
|
||||
};
|
||||
|
||||
/*
|
||||
* Initializes the Fused Location Provider in the native side. It ensures that
|
||||
* the Flp interfaces are initialized properly.
|
||||
*/
|
||||
static void Init(JNIEnv* env, jobject obj) {
|
||||
if(sHardwareDevice != NULL) {
|
||||
ALOGD("Hardware Device already opened.");
|
||||
return;
|
||||
}
|
||||
|
||||
const hw_module_t* module = NULL;
|
||||
int err = hw_get_module(FUSED_LOCATION_HARDWARE_MODULE_ID, &module);
|
||||
if(err != 0) {
|
||||
ALOGE("Error hw_get_module '%s': %d", FUSED_LOCATION_HARDWARE_MODULE_ID, err);
|
||||
return;
|
||||
}
|
||||
|
||||
err = module->methods->open(
|
||||
module,
|
||||
FUSED_LOCATION_HARDWARE_MODULE_ID, &sHardwareDevice);
|
||||
if(err != 0) {
|
||||
ALOGE("Error opening device '%s': %d", FUSED_LOCATION_HARDWARE_MODULE_ID, err);
|
||||
return;
|
||||
}
|
||||
|
||||
sFlpInterface = NULL;
|
||||
flp_device_t* flp_device = reinterpret_cast<flp_device_t*>(sHardwareDevice);
|
||||
sFlpInterface = flp_device->get_flp_interface(flp_device);
|
||||
|
||||
if(sFlpInterface != NULL) {
|
||||
sFlpDiagnosticInterface = reinterpret_cast<const FlpDiagnosticInterface*>(
|
||||
sFlpInterface->get_extension(FLP_DIAGNOSTIC_INTERFACE)
|
||||
);
|
||||
|
||||
sFlpGeofencingInterface = reinterpret_cast<const FlpGeofencingInterface*>(
|
||||
sFlpInterface->get_extension(FLP_GEOFENCING_INTERFACE)
|
||||
);
|
||||
|
||||
sFlpDeviceContextInterface = reinterpret_cast<const FlpDeviceContextInterface*>(
|
||||
sFlpInterface->get_extension(FLP_DEVICE_CONTEXT_INTERFACE)
|
||||
);
|
||||
}
|
||||
|
||||
if(sCallbacksObj == NULL) {
|
||||
sCallbacksObj = env->NewGlobalRef(obj);
|
||||
}
|
||||
|
||||
// initialize the Flp interfaces
|
||||
if(sFlpInterface == NULL || sFlpInterface->init(&sFlpCallbacks) != 0) {
|
||||
ThrowOnError(env, FLP_RESULT_ERROR, __FUNCTION__);
|
||||
}
|
||||
|
||||
if(sFlpDiagnosticInterface != NULL) {
|
||||
sFlpDiagnosticInterface->init(&sFlpDiagnosticCallbacks);
|
||||
}
|
||||
|
||||
if(sFlpGeofencingInterface != NULL) {
|
||||
sFlpGeofencingInterface->init(&sFlpGeofenceCallbacks);
|
||||
}
|
||||
|
||||
// TODO: inject any device context if when needed
|
||||
}
|
||||
|
||||
static jboolean IsSupported(JNIEnv* env, jclass clazz) {
|
||||
return sFlpInterface != NULL;
|
||||
}
|
||||
|
||||
static jint GetBatchSize(JNIEnv* env, jobject object) {
|
||||
if(sFlpInterface == NULL) {
|
||||
ThrowOnError(env, FLP_RESULT_ERROR, __FUNCTION__);
|
||||
}
|
||||
|
||||
return sFlpInterface->get_batch_size();
|
||||
}
|
||||
|
||||
static void StartBatching(
|
||||
JNIEnv* env,
|
||||
jobject object,
|
||||
jint id,
|
||||
jobject optionsObject) {
|
||||
if(sFlpInterface == NULL || optionsObject == NULL) {
|
||||
ThrowOnError(env, FLP_RESULT_ERROR, __FUNCTION__);
|
||||
}
|
||||
|
||||
FlpBatchOptions options;
|
||||
TranslateFromObject(env, optionsObject, options);
|
||||
int result = sFlpInterface->start_batching(id, &options);
|
||||
ThrowOnError(env, result, __FUNCTION__);
|
||||
}
|
||||
|
||||
static void UpdateBatchingOptions(
|
||||
JNIEnv* env,
|
||||
jobject object,
|
||||
jint id,
|
||||
jobject optionsObject) {
|
||||
if(sFlpInterface == NULL || optionsObject == NULL) {
|
||||
ThrowOnError(env, FLP_RESULT_ERROR, __FUNCTION__);
|
||||
}
|
||||
|
||||
FlpBatchOptions options;
|
||||
TranslateFromObject(env, optionsObject, options);
|
||||
int result = sFlpInterface->update_batching_options(id, &options);
|
||||
ThrowOnError(env, result, __FUNCTION__);
|
||||
}
|
||||
|
||||
static void StopBatching(JNIEnv* env, jobject object, jint id) {
|
||||
if(sFlpInterface == NULL) {
|
||||
ThrowOnError(env, FLP_RESULT_ERROR, __FUNCTION__);
|
||||
}
|
||||
|
||||
sFlpInterface->stop_batching(id);
|
||||
}
|
||||
|
||||
static void Cleanup(JNIEnv* env, jobject object) {
|
||||
if(sFlpInterface == NULL) {
|
||||
ThrowOnError(env, FLP_RESULT_ERROR, __FUNCTION__);
|
||||
}
|
||||
|
||||
sFlpInterface->cleanup();
|
||||
|
||||
if(sCallbacksObj != NULL) {
|
||||
env->DeleteGlobalRef(sCallbacksObj);
|
||||
sCallbacksObj = NULL;
|
||||
}
|
||||
|
||||
sFlpInterface = NULL;
|
||||
sFlpDiagnosticInterface = NULL;
|
||||
sFlpDeviceContextInterface = NULL;
|
||||
sFlpGeofencingInterface = NULL;
|
||||
|
||||
if(sHardwareDevice != NULL) {
|
||||
sHardwareDevice->close(sHardwareDevice);
|
||||
sHardwareDevice = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
static void GetBatchedLocation(JNIEnv* env, jobject object, jint lastNLocations) {
|
||||
if(sFlpInterface == NULL) {
|
||||
ThrowOnError(env, FLP_RESULT_ERROR, __FUNCTION__);
|
||||
}
|
||||
|
||||
sFlpInterface->get_batched_location(lastNLocations);
|
||||
}
|
||||
|
||||
static void InjectLocation(JNIEnv* env, jobject object, jobject locationObject) {
|
||||
if(locationObject == NULL) {
|
||||
ALOGE("Invalid location for injection: %p", locationObject);
|
||||
ThrowOnError(env, FLP_RESULT_ERROR, __FUNCTION__);
|
||||
}
|
||||
|
||||
if(sFlpInterface == NULL) {
|
||||
// there is no listener, bail
|
||||
return;
|
||||
}
|
||||
|
||||
FlpLocation location;
|
||||
TranslateFromObject(env, locationObject, location);
|
||||
int result = sFlpInterface->inject_location(&location);
|
||||
if (result != FLP_RESULT_ERROR) {
|
||||
// do not throw but log, this operation should be fire and forget
|
||||
ALOGE("Error %d in '%s'", result, __FUNCTION__);
|
||||
}
|
||||
}
|
||||
|
||||
static jboolean IsDiagnosticSupported() {
|
||||
return sFlpDiagnosticInterface != NULL;
|
||||
}
|
||||
|
||||
static void InjectDiagnosticData(JNIEnv* env, jobject object, jstring stringData) {
|
||||
if(stringData == NULL) {
|
||||
ALOGE("Invalid diagnostic data for injection: %p", stringData);
|
||||
ThrowOnError(env, FLP_RESULT_ERROR, __FUNCTION__);
|
||||
}
|
||||
|
||||
if(sFlpDiagnosticInterface == NULL) {
|
||||
ThrowOnError(env, FLP_RESULT_ERROR, __FUNCTION__);
|
||||
}
|
||||
|
||||
int length = env->GetStringLength(stringData);
|
||||
const jchar* data = env->GetStringChars(stringData, /* isCopy */ NULL);
|
||||
if(data == NULL) {
|
||||
ThrowOnError(env, FLP_RESULT_ERROR, __FUNCTION__);
|
||||
}
|
||||
|
||||
int result = sFlpDiagnosticInterface->inject_data((char*) data, length);
|
||||
ThrowOnError(env, result, __FUNCTION__);
|
||||
}
|
||||
|
||||
static jboolean IsDeviceContextSupported() {
|
||||
return sFlpDeviceContextInterface != NULL;
|
||||
}
|
||||
|
||||
static void InjectDeviceContext(JNIEnv* env, jobject object, jint enabledMask) {
|
||||
if(sFlpDeviceContextInterface == NULL) {
|
||||
ThrowOnError(env, FLP_RESULT_ERROR, __FUNCTION__);
|
||||
}
|
||||
|
||||
int result = sFlpDeviceContextInterface->inject_device_context(enabledMask);
|
||||
ThrowOnError(env, result, __FUNCTION__);
|
||||
}
|
||||
|
||||
static jboolean IsGeofencingSupported() {
|
||||
return sFlpGeofencingInterface != NULL;
|
||||
}
|
||||
|
||||
static void AddGeofences(
|
||||
JNIEnv* env,
|
||||
jobject object,
|
||||
jintArray geofenceIdsArray,
|
||||
jobjectArray geofencesArray) {
|
||||
if(geofencesArray == NULL) {
|
||||
ALOGE("Invalid Geofences to add: %p", geofencesArray);
|
||||
ThrowOnError(env, FLP_RESULT_ERROR, __FUNCTION__);
|
||||
}
|
||||
|
||||
if (sFlpGeofencingInterface == NULL) {
|
||||
ThrowOnError(env, FLP_RESULT_ERROR, __FUNCTION__);
|
||||
}
|
||||
|
||||
jint geofencesCount = env->GetArrayLength(geofenceIdsArray);
|
||||
Geofence* geofences = new Geofence[geofencesCount];
|
||||
if (geofences == NULL) {
|
||||
ThrowOnError(env, FLP_RESULT_INSUFFICIENT_MEMORY, __FUNCTION__);
|
||||
}
|
||||
|
||||
jint* ids = env->GetIntArrayElements(geofenceIdsArray, /* isCopy */ NULL);
|
||||
for (int i = 0; i < geofencesCount; ++i) {
|
||||
geofences[i].geofence_id = ids[i];
|
||||
|
||||
// TODO: fill in the GeofenceData
|
||||
|
||||
// TODO: fill in the GeofenceOptions
|
||||
}
|
||||
|
||||
sFlpGeofencingInterface->add_geofences(geofencesCount, &geofences);
|
||||
if (geofences != NULL) delete[] geofences;
|
||||
}
|
||||
|
||||
static void PauseGeofence(JNIEnv* env, jobject object, jint geofenceId) {
|
||||
if(sFlpGeofencingInterface == NULL) {
|
||||
ThrowOnError(env, FLP_RESULT_ERROR, __FUNCTION__);
|
||||
}
|
||||
|
||||
sFlpGeofencingInterface->pause_geofence(geofenceId);
|
||||
}
|
||||
|
||||
static void ResumeGeofence(
|
||||
JNIEnv* env,
|
||||
jobject object,
|
||||
jint geofenceId,
|
||||
jint monitorTransitions) {
|
||||
if(sFlpGeofencingInterface == NULL) {
|
||||
ThrowOnError(env, FLP_RESULT_ERROR, __FUNCTION__);
|
||||
}
|
||||
|
||||
sFlpGeofencingInterface->resume_geofence(geofenceId, monitorTransitions);
|
||||
}
|
||||
|
||||
static void ModifyGeofenceOption(
|
||||
JNIEnv* env,
|
||||
jobject object,
|
||||
jint geofenceId,
|
||||
jint lastTransition,
|
||||
jint monitorTransitions,
|
||||
jint notificationResponsiveness,
|
||||
jint unknownTimer,
|
||||
jint sourcesToUse) {
|
||||
if(sFlpGeofencingInterface == NULL) {
|
||||
ThrowOnError(env, FLP_RESULT_ERROR, __FUNCTION__);
|
||||
}
|
||||
|
||||
GeofenceOptions options = {
|
||||
lastTransition,
|
||||
monitorTransitions,
|
||||
notificationResponsiveness,
|
||||
unknownTimer,
|
||||
(uint32_t)sourcesToUse
|
||||
};
|
||||
|
||||
sFlpGeofencingInterface->modify_geofence_option(geofenceId, &options);
|
||||
}
|
||||
|
||||
static void RemoveGeofences(
|
||||
JNIEnv* env,
|
||||
jobject object,
|
||||
jintArray geofenceIdsArray) {
|
||||
if(sFlpGeofencingInterface == NULL) {
|
||||
ThrowOnError(env, FLP_RESULT_ERROR, __FUNCTION__);
|
||||
}
|
||||
|
||||
jsize geofenceIdsCount = env->GetArrayLength(geofenceIdsArray);
|
||||
jint* geofenceIds = env->GetIntArrayElements(geofenceIdsArray, /* isCopy */ NULL);
|
||||
if(geofenceIds == NULL) {
|
||||
ThrowOnError(env, FLP_RESULT_ERROR, __FUNCTION__);
|
||||
}
|
||||
|
||||
sFlpGeofencingInterface->remove_geofences(geofenceIdsCount, geofenceIds);
|
||||
}
|
||||
|
||||
static JNINativeMethod sMethods[] = {
|
||||
//{"name", "signature", functionPointer }
|
||||
{"nativeClassInit", "()V", reinterpret_cast<void*>(ClassInit)},
|
||||
{"nativeInit", "()V", reinterpret_cast<void*>(Init)},
|
||||
{"nativeCleanup", "()V", reinterpret_cast<void*>(Cleanup)},
|
||||
{"nativeIsSupported", "()Z", reinterpret_cast<void*>(IsSupported)},
|
||||
{"nativeGetBatchSize", "()I", reinterpret_cast<void*>(GetBatchSize)},
|
||||
{"nativeStartBatching",
|
||||
"(ILandroid/location/FusedBatchOptions;)V",
|
||||
reinterpret_cast<void*>(StartBatching)},
|
||||
{"nativeUpdateBatchingOptions",
|
||||
"(ILandroid/location/FusedBatchOptions;)V",
|
||||
reinterpret_cast<void*>(UpdateBatchingOptions)},
|
||||
{"nativeStopBatching", "(I)V", reinterpret_cast<void*>(StopBatching)},
|
||||
{"nativeRequestBatchedLocation",
|
||||
"(I)V",
|
||||
reinterpret_cast<void*>(GetBatchedLocation)},
|
||||
{"nativeInjectLocation",
|
||||
"(Landroid/location/Location;)V",
|
||||
reinterpret_cast<void*>(InjectLocation)},
|
||||
{"nativeIsDiagnosticSupported",
|
||||
"()Z",
|
||||
reinterpret_cast<void*>(IsDiagnosticSupported)},
|
||||
{"nativeInjectDiagnosticData",
|
||||
"(Ljava/lang/String;)V",
|
||||
reinterpret_cast<void*>(InjectDiagnosticData)},
|
||||
{"nativeIsDeviceContextSupported",
|
||||
"()Z",
|
||||
reinterpret_cast<void*>(IsDeviceContextSupported)},
|
||||
{"nativeInjectDeviceContext",
|
||||
"(I)V",
|
||||
reinterpret_cast<void*>(InjectDeviceContext)},
|
||||
{"nativeIsGeofencingSupported",
|
||||
"()Z",
|
||||
reinterpret_cast<void*>(IsGeofencingSupported)},
|
||||
{"nativeAddGeofences",
|
||||
"([I[Landroid/location/Geofence;)V",
|
||||
reinterpret_cast<void*>(AddGeofences)},
|
||||
{"nativePauseGeofence", "(I)V", reinterpret_cast<void*>(PauseGeofence)},
|
||||
{"nativeResumeGeofence", "(II)V", reinterpret_cast<void*>(ResumeGeofence)},
|
||||
{"nativeModifyGeofenceOption",
|
||||
"(IIIIII)V",
|
||||
reinterpret_cast<void*>(ModifyGeofenceOption)},
|
||||
{"nativeRemoveGeofences", "([I)V", reinterpret_cast<void*>(RemoveGeofences)}
|
||||
};
|
||||
|
||||
/*
|
||||
* Registration method invoked on JNI Load.
|
||||
*/
|
||||
int register_android_server_location_FlpHardwareProvider(JNIEnv* env) {
|
||||
return jniRegisterNativeMethods(
|
||||
env,
|
||||
"com/android/server/location/FlpHardwareProvider",
|
||||
sMethods,
|
||||
NELEM(sMethods)
|
||||
);
|
||||
}
|
||||
|
||||
} /* name-space Android */
|
||||
@@ -32,6 +32,7 @@ int register_android_server_UsbHostManager(JNIEnv* env);
|
||||
int register_android_server_VibratorService(JNIEnv* env);
|
||||
int register_android_server_SystemServer(JNIEnv* env);
|
||||
int register_android_server_location_GpsLocationProvider(JNIEnv* env);
|
||||
int register_android_server_location_FlpHardwareProvider(JNIEnv* env);
|
||||
int register_android_server_connectivity_Vpn(JNIEnv* env);
|
||||
int register_android_server_AssetAtlasService(JNIEnv* env);
|
||||
};
|
||||
@@ -61,6 +62,7 @@ extern "C" jint JNI_OnLoad(JavaVM* vm, void* reserved)
|
||||
register_android_server_VibratorService(env);
|
||||
register_android_server_SystemServer(env);
|
||||
register_android_server_location_GpsLocationProvider(env);
|
||||
register_android_server_location_FlpHardwareProvider(env);
|
||||
register_android_server_connectivity_Vpn(env);
|
||||
register_android_server_AssetAtlasService(env);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user