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

* commit '8ff73b596e7c59f32a3f0df503ae8a9e5adbced5':
  Cherry-pick: Add callback-based support for HW Activity Recognition.
This commit is contained in:
Daniel Estrada Alva
2015-08-26 17:37:15 +00:00
committed by Android Git Automerger
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/IInputManager.aidl \
core/java/android/hardware/input/IInputDevicesChangedListener.aidl \ core/java/android/hardware/input/IInputDevicesChangedListener.aidl \
core/java/android/hardware/location/IActivityRecognitionHardware.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/IActivityRecognitionHardwareSink.aidl \
core/java/android/hardware/location/IActivityRecognitionHardwareWatcher.aidl \ core/java/android/hardware/location/IActivityRecognitionHardwareWatcher.aidl \
core/java/android/hardware/location/IFusedLocationHardware.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 * Activity Recognition Hardware watcher. This interface can be used to receive interfaces to
* implementations of {@link IActivityRecognitionHardware}. * implementations of {@link IActivityRecognitionHardware}.
* *
* @deprecated use {@link IActivityRecognitionHardwareClient} instead.
* @hide * @hide
*/ */
interface IActivityRecognitionHardwareWatcher { interface IActivityRecognitionHardwareWatcher {

View File

@@ -31,8 +31,7 @@ import java.util.HashSet;
*/ */
public final class ActivityRecognitionProvider { public final class ActivityRecognitionProvider {
private final IActivityRecognitionHardware mService; private final IActivityRecognitionHardware mService;
private final HashSet<Sink> mSinkSet = new HashSet<Sink>(); private final HashSet<Sink> mSinkSet = new HashSet<>();
private final SinkTransport mSinkTransport = new SinkTransport();
// the following constants must remain in sync with activity_recognition.h // the following constants must remain in sync with activity_recognition.h
@@ -60,7 +59,7 @@ public final class ActivityRecognitionProvider {
throws RemoteException { throws RemoteException {
Preconditions.checkNotNull(service); Preconditions.checkNotNull(service);
mService = service; mService = service;
mService.registerSink(mSinkTransport); mService.registerSink(new SinkTransport());
} }
public String[] getSupportedActivities() throws RemoteException { public String[] getSupportedActivities() throws RemoteException {
@@ -102,26 +101,23 @@ public final class ActivityRecognitionProvider {
private final class SinkTransport extends IActivityRecognitionHardwareSink.Stub { private final class SinkTransport extends IActivityRecognitionHardwareSink.Stub {
@Override @Override
public void onActivityChanged( public void onActivityChanged(android.hardware.location.ActivityChangedEvent event) {
android.hardware.location.ActivityChangedEvent activityChangedEvent) {
Collection<Sink> sinks; Collection<Sink> sinks;
synchronized (mSinkSet) { synchronized (mSinkSet) {
if (mSinkSet.isEmpty()) { if (mSinkSet.isEmpty()) {
return; return;
} }
sinks = new ArrayList<>(mSinkSet);
sinks = new ArrayList<Sink>(mSinkSet);
} }
// translate the event from platform internal and GmsCore types // translate the event from platform internal and GmsCore types
ArrayList<ActivityRecognitionEvent> gmsEvents = ArrayList<ActivityRecognitionEvent> gmsEvents = new ArrayList<>();
new ArrayList<ActivityRecognitionEvent>(); for (android.hardware.location.ActivityRecognitionEvent reportingEvent
for (android.hardware.location.ActivityRecognitionEvent event : event.getActivityRecognitionEvents()) {
: activityChangedEvent.getActivityRecognitionEvents()) {
ActivityRecognitionEvent gmsEvent = new ActivityRecognitionEvent( ActivityRecognitionEvent gmsEvent = new ActivityRecognitionEvent(
event.getActivity(), reportingEvent.getActivity(),
event.getEventType(), reportingEvent.getEventType(),
event.getTimestampNs()); reportingEvent.getTimestampNs());
gmsEvents.add(gmsEvent); gmsEvents.add(gmsEvent);
} }
ActivityChangedEvent gmsEvent = new ActivityChangedEvent(gmsEvents); 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. * A watcher class for Activity-Recognition instances.
*
* @deprecated use {@link ActivityRecognitionProviderClient} instead.
*/ */
@Deprecated
public class ActivityRecognitionProviderWatcher { public class ActivityRecognitionProviderWatcher {
private static final String TAG = "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."); Slog.e(TAG, "Unable to bind FLP Geofence proxy.");
} }
// bind to the hardware activity recognition if supported // bind to hardware activity recognition
if (ActivityRecognitionHardware.isSupported()) { boolean activityRecognitionHardwareIsSupported = ActivityRecognitionHardware.isSupported();
ActivityRecognitionProxy proxy = ActivityRecognitionProxy.createAndBind( ActivityRecognitionHardware activityRecognitionHardware = null;
mContext, if (activityRecognitionHardwareIsSupported) {
mLocationHandler, activityRecognitionHardware = ActivityRecognitionHardware.getInstance(mContext);
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.");
}
} else { } else {
Slog.e(TAG, "Hardware Activity-Recognition not supported."); 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( String[] testProviderStrings = resources.getStringArray(
com.android.internal.R.array.config_testLocationProviders); com.android.internal.R.array.config_testLocationProviders);

View File

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