From a4fa3b5aa53cf677b623fe346c585cb8a0c1ce26 Mon Sep 17 00:00:00 2001 From: destradaa Date: Wed, 9 Jul 2014 10:46:39 -0700 Subject: Add support in the platform for Activity Recognition Hardware. Change-Id: I7c4fff3526583475a5edf1f4ba8fede4e9419ead --- .../location/provider/ActivityChangedEvent.java | 43 +++++++ .../provider/ActivityRecognitionEvent.java | 44 +++++++ .../provider/ActivityRecognitionProvider.java | 134 +++++++++++++++++++++ .../ActivityRecognitionProviderWatcher.java | 86 +++++++++++++ 4 files changed, 307 insertions(+) create mode 100644 location/lib/java/com/android/location/provider/ActivityChangedEvent.java create mode 100644 location/lib/java/com/android/location/provider/ActivityRecognitionEvent.java create mode 100644 location/lib/java/com/android/location/provider/ActivityRecognitionProvider.java create mode 100644 location/lib/java/com/android/location/provider/ActivityRecognitionProviderWatcher.java (limited to 'location/lib') diff --git a/location/lib/java/com/android/location/provider/ActivityChangedEvent.java b/location/lib/java/com/android/location/provider/ActivityChangedEvent.java new file mode 100644 index 0000000..8707a10 --- /dev/null +++ b/location/lib/java/com/android/location/provider/ActivityChangedEvent.java @@ -0,0 +1,43 @@ +/* + * Copyright (C) 2014 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 java.security.InvalidParameterException; +import java.util.List; + +/** + * A class representing an event for Activity changes. + */ +public class ActivityChangedEvent { + private final List mActivityRecognitionEvents; + + public ActivityChangedEvent(List activityRecognitionEvents) { + if (activityRecognitionEvents == null) { + throw new InvalidParameterException( + "Parameter 'activityRecognitionEvents' must not be null."); + } + + mActivityRecognitionEvents = activityRecognitionEvents; + } + + @NonNull + public Iterable getActivityRecognitionEvents() { + return mActivityRecognitionEvents; + } +} diff --git a/location/lib/java/com/android/location/provider/ActivityRecognitionEvent.java b/location/lib/java/com/android/location/provider/ActivityRecognitionEvent.java new file mode 100644 index 0000000..8c719ce --- /dev/null +++ b/location/lib/java/com/android/location/provider/ActivityRecognitionEvent.java @@ -0,0 +1,44 @@ +/* + * Copyright (C) 2014 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; + +/** + * A class that represents an Activity Recognition Event. + */ +public class ActivityRecognitionEvent { + private final String mActivity; + private final int mEventType; + private final long mTimestampNs; + + public ActivityRecognitionEvent(String activity, int eventType, long timestampNs) { + mActivity = activity; + mEventType = eventType; + mTimestampNs = timestampNs; + } + + public String getActivity() { + return mActivity; + } + + public int getEventType() { + return mEventType; + } + + public long getTimestampNs() { + return mTimestampNs; + } +} diff --git a/location/lib/java/com/android/location/provider/ActivityRecognitionProvider.java b/location/lib/java/com/android/location/provider/ActivityRecognitionProvider.java new file mode 100644 index 0000000..da33464 --- /dev/null +++ b/location/lib/java/com/android/location/provider/ActivityRecognitionProvider.java @@ -0,0 +1,134 @@ +/* + * Copyright (C) 2014 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 com.android.internal.util.Preconditions; + +import android.hardware.location.IActivityRecognitionHardware; +import android.hardware.location.IActivityRecognitionHardwareSink; +import android.os.RemoteException; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.HashSet; + +/** + * A class that exposes {@link IActivityRecognitionHardware} functionality to unbundled services. + */ +public final class ActivityRecognitionProvider { + private final IActivityRecognitionHardware mService; + private final HashSet mSinkSet = new HashSet(); + private final SinkTransport mSinkTransport = new SinkTransport(); + + // the following constants must remain in sync with activity_recognition.h + + public static final String ACTIVITY_IN_VEHICLE = "android.activity_recognition.in_vehicle"; + public static final String ACTIVITY_ON_BICYCLE = "android.activity_recognition.on_bicycle"; + public static final String ACTIVITY_WALKING = "android.activity_recognition.walking"; + public static final String ACTIVITY_RUNNING = "android.activity_recognition.running"; + public static final String ACTIVITY_STILL = "android.activity_recognition.still"; + public static final String ACTIVITY_TILTING = "android.activity_recognition.tilting"; + + public static final int EVENT_TYPE_FLUSH_COMPLETE = 0; + public static final int EVENT_TYPE_ENTER = 1; + public static final int EVENT_TYPE_EXIT = 2; + + // end constants activity_recognition.h + + /** + * Used to receive Activity-Recognition events. + */ + public interface Sink { + void onActivityChanged(ActivityChangedEvent event); + } + + public ActivityRecognitionProvider(IActivityRecognitionHardware service) + throws RemoteException { + Preconditions.checkNotNull(service); + mService = service; + mService.registerSink(mSinkTransport); + } + + public String[] getSupportedActivities() throws RemoteException { + return mService.getSupportedActivities(); + } + + public boolean isActivitySupported(String activity) throws RemoteException { + return mService.isActivitySupported(activity); + } + + public void registerSink(Sink sink) { + Preconditions.checkNotNull(sink); + synchronized (mSinkSet) { + mSinkSet.add(sink); + } + } + + // TODO: if this functionality is exposed to 3rd party developers, handle unregistration (here + // and in the service) of all sinks while failing to disable all events + public void unregisterSink(Sink sink) { + Preconditions.checkNotNull(sink); + synchronized (mSinkSet) { + mSinkSet.remove(sink); + } + } + + public boolean enableActivityEvent(String activity, int eventType, long reportLatencyNs) + throws RemoteException { + return mService.enableActivityEvent(activity, eventType, reportLatencyNs); + } + + public boolean disableActivityEvent(String activity, int eventType) throws RemoteException { + return mService.disableActivityEvent(activity, eventType); + } + + public boolean flush() throws RemoteException { + return mService.flush(); + } + + private final class SinkTransport extends IActivityRecognitionHardwareSink.Stub { + @Override + public void onActivityChanged( + android.hardware.location.ActivityChangedEvent activityChangedEvent) { + Collection sinks; + synchronized (mSinkSet) { + if (mSinkSet.isEmpty()) { + return; + } + + sinks = new ArrayList(mSinkSet); + } + + // translate the event from platform internal and GmsCore types + ArrayList gmsEvents = + new ArrayList(); + for (android.hardware.location.ActivityRecognitionEvent event + : activityChangedEvent.getActivityRecognitionEvents()) { + ActivityRecognitionEvent gmsEvent = new ActivityRecognitionEvent( + event.getActivity(), + event.getEventType(), + event.getTimestampNs()); + gmsEvents.add(gmsEvent); + } + ActivityChangedEvent gmsEvent = new ActivityChangedEvent(gmsEvents); + + for (Sink sink : sinks) { + sink.onActivityChanged(gmsEvent); + } + } + } +} diff --git a/location/lib/java/com/android/location/provider/ActivityRecognitionProviderWatcher.java b/location/lib/java/com/android/location/provider/ActivityRecognitionProviderWatcher.java new file mode 100644 index 0000000..03dd042 --- /dev/null +++ b/location/lib/java/com/android/location/provider/ActivityRecognitionProviderWatcher.java @@ -0,0 +1,86 @@ +/* + * Copyright (C) 2014 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.annotation.Nullable; +import android.hardware.location.IActivityRecognitionHardware; +import android.hardware.location.IActivityRecognitionHardwareWatcher; +import android.os.Binder; +import android.os.IBinder; +import android.os.Process; +import android.os.RemoteException; +import android.util.Log; + +/** + * A watcher class for Activity-Recognition instances. + */ +public class ActivityRecognitionProviderWatcher { + private static final String TAG = "ActivityRecognitionProviderWatcher"; + + private static ActivityRecognitionProviderWatcher sWatcher; + private static final Object sWatcherLock = new Object(); + + private ActivityRecognitionProvider mActivityRecognitionProvider; + + private ActivityRecognitionProviderWatcher() {} + + public static ActivityRecognitionProviderWatcher getInstance() { + synchronized (sWatcherLock) { + if (sWatcher == null) { + sWatcher = new ActivityRecognitionProviderWatcher(); + } + return sWatcher; + } + } + + private IActivityRecognitionHardwareWatcher.Stub mWatcherStub = + new IActivityRecognitionHardwareWatcher.Stub() { + @Override + public void onInstanceChanged(IActivityRecognitionHardware instance) { + int callingUid = Binder.getCallingUid(); + if (callingUid != Process.SYSTEM_UID) { + Log.d(TAG, "Ignoring calls from non-system server. Uid: " + callingUid); + return; + } + + try { + mActivityRecognitionProvider = new ActivityRecognitionProvider(instance); + } catch (RemoteException e) { + Log.e(TAG, "Error creating Hardware Activity-Recognition", e); + } + } + }; + + /** + * Gets the binder needed to interact with proxy provider in the platform. + */ + @NonNull + public IBinder getBinder() { + return mWatcherStub; + } + + /** + * Gets an object that supports the functionality of {@link ActivityRecognitionProvider}. + * + * @return Non-null value if the functionality is supported by the platform, false otherwise. + */ + @Nullable + public ActivityRecognitionProvider getActivityRecognitionProvider() { + return mActivityRecognitionProvider; + } +} -- cgit v1.1