Merge "Cherry-pick: Add callback-based support for HW Activity Recognition." into mnc-dr-dev

This commit is contained in:
Daniel Estrada Alva
2015-08-26 17:30:09 +00:00
committed by Android (Google) Code Review
8 changed files with 191 additions and 41 deletions

View File

@@ -173,6 +173,7 @@ LOCAL_SRC_FILES += \
core/java/android/hardware/input/IInputManager.aidl \
core/java/android/hardware/input/IInputDevicesChangedListener.aidl \
core/java/android/hardware/location/IActivityRecognitionHardware.aidl \
core/java/android/hardware/location/IActivityRecognitionHardwareClient.aidl \
core/java/android/hardware/location/IActivityRecognitionHardwareSink.aidl \
core/java/android/hardware/location/IActivityRecognitionHardwareWatcher.aidl \
core/java/android/hardware/location/IFusedLocationHardware.aidl \

View File

@@ -0,0 +1,36 @@
/*
* Copyright (C) 2015, 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.IActivityRecognitionHardware;
/**
* Activity Recognition Hardware client interface.
* This interface can be used to receive interfaces to implementations of
* {@link IActivityRecognitionHardware}.
*
* @hide
*/
interface IActivityRecognitionHardwareClient {
/**
* Hardware Activity-Recognition availability event.
*
* @param isSupported whether the platform has hardware support for the feature
* @param instance the available instance to provide access to the feature
*/
void onAvailabilityChanged(in boolean isSupported, in IActivityRecognitionHardware instance);
}

View File

@@ -22,6 +22,8 @@ import android.hardware.location.IActivityRecognitionHardware;
* Activity Recognition Hardware watcher. This interface can be used to receive interfaces to
* implementations of {@link IActivityRecognitionHardware}.
*
* @deprecated use {@link IActivityRecognitionHardwareClient} instead.
* @hide
*/
interface IActivityRecognitionHardwareWatcher {
@@ -29,4 +31,4 @@ interface IActivityRecognitionHardwareWatcher {
* Hardware Activity-Recognition availability event.
*/
void onInstanceChanged(in IActivityRecognitionHardware instance);
}
}

View File

@@ -31,8 +31,7 @@ import java.util.HashSet;
*/
public final class ActivityRecognitionProvider {
private final IActivityRecognitionHardware mService;
private final HashSet<Sink> mSinkSet = new HashSet<Sink>();
private final SinkTransport mSinkTransport = new SinkTransport();
private final HashSet<Sink> mSinkSet = new HashSet<>();
// the following constants must remain in sync with activity_recognition.h
@@ -60,7 +59,7 @@ public final class ActivityRecognitionProvider {
throws RemoteException {
Preconditions.checkNotNull(service);
mService = service;
mService.registerSink(mSinkTransport);
mService.registerSink(new SinkTransport());
}
public String[] getSupportedActivities() throws RemoteException {
@@ -102,26 +101,23 @@ public final class ActivityRecognitionProvider {
private final class SinkTransport extends IActivityRecognitionHardwareSink.Stub {
@Override
public void onActivityChanged(
android.hardware.location.ActivityChangedEvent activityChangedEvent) {
public void onActivityChanged(android.hardware.location.ActivityChangedEvent event) {
Collection<Sink> sinks;
synchronized (mSinkSet) {
if (mSinkSet.isEmpty()) {
return;
}
sinks = new ArrayList<Sink>(mSinkSet);
sinks = new ArrayList<>(mSinkSet);
}
// translate the event from platform internal and GmsCore types
ArrayList<ActivityRecognitionEvent> gmsEvents =
new ArrayList<ActivityRecognitionEvent>();
for (android.hardware.location.ActivityRecognitionEvent event
: activityChangedEvent.getActivityRecognitionEvents()) {
ArrayList<ActivityRecognitionEvent> gmsEvents = new ArrayList<>();
for (android.hardware.location.ActivityRecognitionEvent reportingEvent
: event.getActivityRecognitionEvents()) {
ActivityRecognitionEvent gmsEvent = new ActivityRecognitionEvent(
event.getActivity(),
event.getEventType(),
event.getTimestampNs());
reportingEvent.getActivity(),
reportingEvent.getEventType(),
reportingEvent.getTimestampNs());
gmsEvents.add(gmsEvent);
}
ActivityChangedEvent gmsEvent = new ActivityChangedEvent(gmsEvents);

View File

@@ -0,0 +1,75 @@
/*
* Copyright (C) 2015 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.annotation.NonNull;
import android.hardware.location.IActivityRecognitionHardware;
import android.hardware.location.IActivityRecognitionHardwareClient;
import android.os.Binder;
import android.os.IBinder;
import android.os.Process;
import android.os.RemoteException;
import android.util.Log;
/**
* A client class for interaction with an Activity-Recognition provider.
*/
public abstract class ActivityRecognitionProviderClient {
private static final String TAG = "ArProviderClient";
protected ActivityRecognitionProviderClient() {}
private IActivityRecognitionHardwareClient.Stub mClient =
new IActivityRecognitionHardwareClient.Stub() {
@Override
public void onAvailabilityChanged(
boolean isSupported,
IActivityRecognitionHardware instance) {
int callingUid = Binder.getCallingUid();
if (callingUid != Process.SYSTEM_UID) {
Log.d(TAG, "Ignoring calls from non-system server. Uid: " + callingUid);
return;
}
ActivityRecognitionProvider provider;
try {
provider = isSupported ? new ActivityRecognitionProvider(instance) : null;
} catch (RemoteException e) {
Log.e(TAG, "Error creating Hardware Activity-Recognition Provider.", e);
return;
}
onProviderChanged(isSupported, provider);
}
};
/**
* Gets the binder needed to interact with proxy provider in the platform.
*/
@NonNull
public IBinder getBinder() {
return mClient;
}
/**
* Called when a change in the availability of {@link ActivityRecognitionProvider} is detected.
*
* @param isSupported whether the platform supports the provider natively
* @param instance the available provider's instance
*/
public abstract void onProviderChanged(
boolean isSupported,
ActivityRecognitionProvider instance);
}

View File

@@ -28,7 +28,10 @@ import android.util.Log;
/**
* A watcher class for Activity-Recognition instances.
*
* @deprecated use {@link ActivityRecognitionProviderClient} instead.
*/
@Deprecated
public class ActivityRecognitionProviderWatcher {
private static final String TAG = "ActivityRecognitionProviderWatcher";

View File

@@ -542,22 +542,25 @@ public class LocationManagerService extends ILocationManager.Stub {
Slog.e(TAG, "Unable to bind FLP Geofence proxy.");
}
// bind to the hardware activity recognition if supported
if (ActivityRecognitionHardware.isSupported()) {
ActivityRecognitionProxy proxy = ActivityRecognitionProxy.createAndBind(
mContext,
mLocationHandler,
ActivityRecognitionHardware.getInstance(mContext),
com.android.internal.R.bool.config_enableActivityRecognitionHardwareOverlay,
com.android.internal.R.string.config_activityRecognitionHardwarePackageName,
com.android.internal.R.array.config_locationProviderPackageNames);
if (proxy == null) {
Slog.e(TAG, "Unable to bind ActivityRecognitionProxy.");
}
// bind to hardware activity recognition
boolean activityRecognitionHardwareIsSupported = ActivityRecognitionHardware.isSupported();
ActivityRecognitionHardware activityRecognitionHardware = null;
if (activityRecognitionHardwareIsSupported) {
activityRecognitionHardware = ActivityRecognitionHardware.getInstance(mContext);
} else {
Slog.e(TAG, "Hardware Activity-Recognition not supported.");
}
ActivityRecognitionProxy proxy = ActivityRecognitionProxy.createAndBind(
mContext,
mLocationHandler,
activityRecognitionHardwareIsSupported,
activityRecognitionHardware,
com.android.internal.R.bool.config_enableActivityRecognitionHardwareOverlay,
com.android.internal.R.string.config_activityRecognitionHardwarePackageName,
com.android.internal.R.array.config_locationProviderPackageNames);
if (proxy == null) {
Slog.e(TAG, "Unable to bind ActivityRecognitionProxy.");
}
String[] testProviderStrings = resources.getStringArray(
com.android.internal.R.array.config_testLocationProviders);

View File

@@ -20,8 +20,10 @@ import com.android.server.ServiceWatcher;
import android.content.Context;
import android.hardware.location.ActivityRecognitionHardware;
import android.hardware.location.IActivityRecognitionHardwareClient;
import android.hardware.location.IActivityRecognitionHardwareWatcher;
import android.os.Handler;
import android.os.IBinder;
import android.os.RemoteException;
import android.util.Log;
@@ -34,21 +36,24 @@ public class ActivityRecognitionProxy {
private static final String TAG = "ActivityRecognitionProxy";
private final ServiceWatcher mServiceWatcher;
private final ActivityRecognitionHardware mActivityRecognitionHardware;
private final boolean mIsSupported;
private final ActivityRecognitionHardware mInstance;
private ActivityRecognitionProxy(
Context context,
Handler handler,
boolean activityRecognitionHardwareIsSupported,
ActivityRecognitionHardware activityRecognitionHardware,
int overlaySwitchResId,
int defaultServicePackageNameResId,
int initialPackageNameResId) {
mActivityRecognitionHardware = activityRecognitionHardware;
mIsSupported = activityRecognitionHardwareIsSupported;
mInstance = activityRecognitionHardware;
Runnable newServiceWork = new Runnable() {
@Override
public void run() {
bindProvider(mActivityRecognitionHardware);
bindProvider();
}
};
@@ -72,6 +77,7 @@ public class ActivityRecognitionProxy {
public static ActivityRecognitionProxy createAndBind(
Context context,
Handler handler,
boolean activityRecognitionHardwareIsSupported,
ActivityRecognitionHardware activityRecognitionHardware,
int overlaySwitchResId,
int defaultServicePackageNameResId,
@@ -79,6 +85,7 @@ public class ActivityRecognitionProxy {
ActivityRecognitionProxy activityRecognitionProxy = new ActivityRecognitionProxy(
context,
handler,
activityRecognitionHardwareIsSupported,
activityRecognitionHardware,
overlaySwitchResId,
defaultServicePackageNameResId,
@@ -89,25 +96,52 @@ public class ActivityRecognitionProxy {
Log.e(TAG, "ServiceWatcher could not start.");
return null;
}
return activityRecognitionProxy;
}
/**
* Helper function to bind the FusedLocationHardware to the appropriate FusedProvider instance.
*/
private void bindProvider(ActivityRecognitionHardware activityRecognitionHardware) {
IActivityRecognitionHardwareWatcher watcher =
IActivityRecognitionHardwareWatcher.Stub.asInterface(mServiceWatcher.getBinder());
if (watcher == null) {
Log.e(TAG, "No provider instance found on connection.");
private void bindProvider() {
IBinder binder = mServiceWatcher.getBinder();
if (binder == null) {
Log.e(TAG, "Null binder found on connection.");
return;
}
String descriptor;
try {
descriptor = binder.getInterfaceDescriptor();
} catch (RemoteException e) {
Log.e(TAG, "Unable to get interface descriptor.", e);
return;
}
try {
watcher.onInstanceChanged(mActivityRecognitionHardware);
} catch (RemoteException e) {
Log.e(TAG, "Error delivering hardware interface.", e);
if (IActivityRecognitionHardwareWatcher.class.getCanonicalName().equals(descriptor)) {
IActivityRecognitionHardwareWatcher watcher =
IActivityRecognitionHardwareWatcher.Stub.asInterface(binder);
if (watcher == null) {
Log.e(TAG, "No watcher found on connection.");
return;
}
try {
watcher.onInstanceChanged(mInstance);
} catch (RemoteException e) {
Log.e(TAG, "Error delivering hardware interface to watcher.", e);
}
} else if (IActivityRecognitionHardwareClient.class.getCanonicalName().equals(descriptor)) {
IActivityRecognitionHardwareClient client =
IActivityRecognitionHardwareClient.Stub.asInterface(binder);
if (client == null) {
Log.e(TAG, "No client found on connection.");
return;
}
try {
client.onAvailabilityChanged(mIsSupported, mInstance);
} catch (RemoteException e) {
Log.e(TAG, "Error delivering hardware interface to client.", e);
}
} else {
Log.e(TAG, "Invalid descriptor found on connection: " + descriptor);
}
}
}