1a4fa3b5aa53cf677b623fe346c585cb8a0c1ce26destradaa/* 2a4fa3b5aa53cf677b623fe346c585cb8a0c1ce26destradaa * Copyright (C) 2014 The Android Open Source Project 3a4fa3b5aa53cf677b623fe346c585cb8a0c1ce26destradaa * 4a4fa3b5aa53cf677b623fe346c585cb8a0c1ce26destradaa * Licensed under the Apache License, Version 2.0 (the "License"); 5a4fa3b5aa53cf677b623fe346c585cb8a0c1ce26destradaa * you may not use this file except in compliance with the License. 6a4fa3b5aa53cf677b623fe346c585cb8a0c1ce26destradaa * You may obtain a copy of the License at 7a4fa3b5aa53cf677b623fe346c585cb8a0c1ce26destradaa * 8a4fa3b5aa53cf677b623fe346c585cb8a0c1ce26destradaa * http://www.apache.org/licenses/LICENSE-2.0 9a4fa3b5aa53cf677b623fe346c585cb8a0c1ce26destradaa * 10a4fa3b5aa53cf677b623fe346c585cb8a0c1ce26destradaa * Unless required by applicable law or agreed to in writing, software 11a4fa3b5aa53cf677b623fe346c585cb8a0c1ce26destradaa * distributed under the License is distributed on an "AS IS" BASIS, 12a4fa3b5aa53cf677b623fe346c585cb8a0c1ce26destradaa * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13a4fa3b5aa53cf677b623fe346c585cb8a0c1ce26destradaa * See the License for the specific language governing permissions and 14a4fa3b5aa53cf677b623fe346c585cb8a0c1ce26destradaa * limitations under the License 15a4fa3b5aa53cf677b623fe346c585cb8a0c1ce26destradaa */ 16a4fa3b5aa53cf677b623fe346c585cb8a0c1ce26destradaa 17a4fa3b5aa53cf677b623fe346c585cb8a0c1ce26destradaapackage android.hardware.location; 18a4fa3b5aa53cf677b623fe346c585cb8a0c1ce26destradaa 19a4fa3b5aa53cf677b623fe346c585cb8a0c1ce26destradaaimport android.Manifest; 20a4fa3b5aa53cf677b623fe346c585cb8a0c1ce26destradaaimport android.content.Context; 21a4fa3b5aa53cf677b623fe346c585cb8a0c1ce26destradaaimport android.os.RemoteCallbackList; 22a4fa3b5aa53cf677b623fe346c585cb8a0c1ce26destradaaimport android.os.RemoteException; 23a4fa3b5aa53cf677b623fe346c585cb8a0c1ce26destradaaimport android.text.TextUtils; 24a4fa3b5aa53cf677b623fe346c585cb8a0c1ce26destradaaimport android.util.Log; 25a4fa3b5aa53cf677b623fe346c585cb8a0c1ce26destradaa 26a4fa3b5aa53cf677b623fe346c585cb8a0c1ce26destradaa/** 27a4fa3b5aa53cf677b623fe346c585cb8a0c1ce26destradaa * A class that implements an {@link IActivityRecognitionHardware} backed up by the Activity 28a4fa3b5aa53cf677b623fe346c585cb8a0c1ce26destradaa * Recognition HAL. 29a4fa3b5aa53cf677b623fe346c585cb8a0c1ce26destradaa * 30a4fa3b5aa53cf677b623fe346c585cb8a0c1ce26destradaa * @hide 31a4fa3b5aa53cf677b623fe346c585cb8a0c1ce26destradaa */ 32a4fa3b5aa53cf677b623fe346c585cb8a0c1ce26destradaapublic class ActivityRecognitionHardware extends IActivityRecognitionHardware.Stub { 33614612edb508dd5ef1a8f463105b16894906264edestradaa private static final String TAG = "ActivityRecognitionHW"; 34614612edb508dd5ef1a8f463105b16894906264edestradaa private static final boolean DEBUG = Log.isLoggable(TAG, Log.DEBUG); 35a4fa3b5aa53cf677b623fe346c585cb8a0c1ce26destradaa 36a4fa3b5aa53cf677b623fe346c585cb8a0c1ce26destradaa private static final String HARDWARE_PERMISSION = Manifest.permission.LOCATION_HARDWARE; 37614612edb508dd5ef1a8f463105b16894906264edestradaa private static final String ENFORCE_HW_PERMISSION_MESSAGE = "Permission '" 38614612edb508dd5ef1a8f463105b16894906264edestradaa + HARDWARE_PERMISSION + "' not granted to access ActivityRecognitionHardware"; 39614612edb508dd5ef1a8f463105b16894906264edestradaa 40a4fa3b5aa53cf677b623fe346c585cb8a0c1ce26destradaa private static final int INVALID_ACTIVITY_TYPE = -1; 41a4fa3b5aa53cf677b623fe346c585cb8a0c1ce26destradaa private static final int NATIVE_SUCCESS_RESULT = 0; 42614612edb508dd5ef1a8f463105b16894906264edestradaa private static final int EVENT_TYPE_DISABLED = 0; 43614612edb508dd5ef1a8f463105b16894906264edestradaa private static final int EVENT_TYPE_ENABLED = 1; 44614612edb508dd5ef1a8f463105b16894906264edestradaa 45614612edb508dd5ef1a8f463105b16894906264edestradaa /** 46614612edb508dd5ef1a8f463105b16894906264edestradaa * Contains the number of supported Event Types. 47614612edb508dd5ef1a8f463105b16894906264edestradaa * 48614612edb508dd5ef1a8f463105b16894906264edestradaa * NOTE: increment this counter every time a new EVENT_TYPE_ is added to 49614612edb508dd5ef1a8f463105b16894906264edestradaa * com.android.location.provider.ActivityRecognitionProvider 50614612edb508dd5ef1a8f463105b16894906264edestradaa */ 51614612edb508dd5ef1a8f463105b16894906264edestradaa private static final int EVENT_TYPE_COUNT = 3; 52a4fa3b5aa53cf677b623fe346c585cb8a0c1ce26destradaa 53614612edb508dd5ef1a8f463105b16894906264edestradaa private static ActivityRecognitionHardware sSingletonInstance; 54a4fa3b5aa53cf677b623fe346c585cb8a0c1ce26destradaa private static final Object sSingletonInstanceLock = new Object(); 55a4fa3b5aa53cf677b623fe346c585cb8a0c1ce26destradaa 56a4fa3b5aa53cf677b623fe346c585cb8a0c1ce26destradaa private final Context mContext; 57614612edb508dd5ef1a8f463105b16894906264edestradaa private final int mSupportedActivitiesCount; 58a4fa3b5aa53cf677b623fe346c585cb8a0c1ce26destradaa private final String[] mSupportedActivities; 59614612edb508dd5ef1a8f463105b16894906264edestradaa private final int[][] mSupportedActivitiesEnabledEvents; 60614612edb508dd5ef1a8f463105b16894906264edestradaa private final SinkList mSinks = new SinkList(); 61a4fa3b5aa53cf677b623fe346c585cb8a0c1ce26destradaa 62a4fa3b5aa53cf677b623fe346c585cb8a0c1ce26destradaa private static class Event { 63a4fa3b5aa53cf677b623fe346c585cb8a0c1ce26destradaa public int activity; 64a4fa3b5aa53cf677b623fe346c585cb8a0c1ce26destradaa public int type; 65a4fa3b5aa53cf677b623fe346c585cb8a0c1ce26destradaa public long timestamp; 66a4fa3b5aa53cf677b623fe346c585cb8a0c1ce26destradaa } 67a4fa3b5aa53cf677b623fe346c585cb8a0c1ce26destradaa 68a4fa3b5aa53cf677b623fe346c585cb8a0c1ce26destradaa private ActivityRecognitionHardware(Context context) { 69a4fa3b5aa53cf677b623fe346c585cb8a0c1ce26destradaa nativeInitialize(); 70a4fa3b5aa53cf677b623fe346c585cb8a0c1ce26destradaa 71a4fa3b5aa53cf677b623fe346c585cb8a0c1ce26destradaa mContext = context; 72a4fa3b5aa53cf677b623fe346c585cb8a0c1ce26destradaa mSupportedActivities = fetchSupportedActivities(); 73614612edb508dd5ef1a8f463105b16894906264edestradaa mSupportedActivitiesCount = mSupportedActivities.length; 74614612edb508dd5ef1a8f463105b16894906264edestradaa mSupportedActivitiesEnabledEvents = new int[mSupportedActivitiesCount][EVENT_TYPE_COUNT]; 75a4fa3b5aa53cf677b623fe346c585cb8a0c1ce26destradaa } 76a4fa3b5aa53cf677b623fe346c585cb8a0c1ce26destradaa 77a4fa3b5aa53cf677b623fe346c585cb8a0c1ce26destradaa public static ActivityRecognitionHardware getInstance(Context context) { 78a4fa3b5aa53cf677b623fe346c585cb8a0c1ce26destradaa synchronized (sSingletonInstanceLock) { 79a4fa3b5aa53cf677b623fe346c585cb8a0c1ce26destradaa if (sSingletonInstance == null) { 80a4fa3b5aa53cf677b623fe346c585cb8a0c1ce26destradaa sSingletonInstance = new ActivityRecognitionHardware(context); 81a4fa3b5aa53cf677b623fe346c585cb8a0c1ce26destradaa } 82a4fa3b5aa53cf677b623fe346c585cb8a0c1ce26destradaa 83a4fa3b5aa53cf677b623fe346c585cb8a0c1ce26destradaa return sSingletonInstance; 84a4fa3b5aa53cf677b623fe346c585cb8a0c1ce26destradaa } 85a4fa3b5aa53cf677b623fe346c585cb8a0c1ce26destradaa } 86a4fa3b5aa53cf677b623fe346c585cb8a0c1ce26destradaa 87a4fa3b5aa53cf677b623fe346c585cb8a0c1ce26destradaa public static boolean isSupported() { 88a4fa3b5aa53cf677b623fe346c585cb8a0c1ce26destradaa return nativeIsSupported(); 89a4fa3b5aa53cf677b623fe346c585cb8a0c1ce26destradaa } 90a4fa3b5aa53cf677b623fe346c585cb8a0c1ce26destradaa 91a4fa3b5aa53cf677b623fe346c585cb8a0c1ce26destradaa @Override 92a4fa3b5aa53cf677b623fe346c585cb8a0c1ce26destradaa public String[] getSupportedActivities() { 93a4fa3b5aa53cf677b623fe346c585cb8a0c1ce26destradaa checkPermissions(); 94a4fa3b5aa53cf677b623fe346c585cb8a0c1ce26destradaa return mSupportedActivities; 95a4fa3b5aa53cf677b623fe346c585cb8a0c1ce26destradaa } 96a4fa3b5aa53cf677b623fe346c585cb8a0c1ce26destradaa 97a4fa3b5aa53cf677b623fe346c585cb8a0c1ce26destradaa @Override 98a4fa3b5aa53cf677b623fe346c585cb8a0c1ce26destradaa public boolean isActivitySupported(String activity) { 99a4fa3b5aa53cf677b623fe346c585cb8a0c1ce26destradaa checkPermissions(); 100a4fa3b5aa53cf677b623fe346c585cb8a0c1ce26destradaa int activityType = getActivityType(activity); 101a4fa3b5aa53cf677b623fe346c585cb8a0c1ce26destradaa return activityType != INVALID_ACTIVITY_TYPE; 102a4fa3b5aa53cf677b623fe346c585cb8a0c1ce26destradaa } 103a4fa3b5aa53cf677b623fe346c585cb8a0c1ce26destradaa 104a4fa3b5aa53cf677b623fe346c585cb8a0c1ce26destradaa @Override 105a4fa3b5aa53cf677b623fe346c585cb8a0c1ce26destradaa public boolean registerSink(IActivityRecognitionHardwareSink sink) { 106a4fa3b5aa53cf677b623fe346c585cb8a0c1ce26destradaa checkPermissions(); 107a4fa3b5aa53cf677b623fe346c585cb8a0c1ce26destradaa return mSinks.register(sink); 108a4fa3b5aa53cf677b623fe346c585cb8a0c1ce26destradaa } 109a4fa3b5aa53cf677b623fe346c585cb8a0c1ce26destradaa 110a4fa3b5aa53cf677b623fe346c585cb8a0c1ce26destradaa @Override 111a4fa3b5aa53cf677b623fe346c585cb8a0c1ce26destradaa public boolean unregisterSink(IActivityRecognitionHardwareSink sink) { 112a4fa3b5aa53cf677b623fe346c585cb8a0c1ce26destradaa checkPermissions(); 113a4fa3b5aa53cf677b623fe346c585cb8a0c1ce26destradaa return mSinks.unregister(sink); 114a4fa3b5aa53cf677b623fe346c585cb8a0c1ce26destradaa } 115a4fa3b5aa53cf677b623fe346c585cb8a0c1ce26destradaa 116a4fa3b5aa53cf677b623fe346c585cb8a0c1ce26destradaa @Override 117a4fa3b5aa53cf677b623fe346c585cb8a0c1ce26destradaa public boolean enableActivityEvent(String activity, int eventType, long reportLatencyNs) { 118a4fa3b5aa53cf677b623fe346c585cb8a0c1ce26destradaa checkPermissions(); 119a4fa3b5aa53cf677b623fe346c585cb8a0c1ce26destradaa 120a4fa3b5aa53cf677b623fe346c585cb8a0c1ce26destradaa int activityType = getActivityType(activity); 121a4fa3b5aa53cf677b623fe346c585cb8a0c1ce26destradaa if (activityType == INVALID_ACTIVITY_TYPE) { 122a4fa3b5aa53cf677b623fe346c585cb8a0c1ce26destradaa return false; 123a4fa3b5aa53cf677b623fe346c585cb8a0c1ce26destradaa } 124a4fa3b5aa53cf677b623fe346c585cb8a0c1ce26destradaa 125a4fa3b5aa53cf677b623fe346c585cb8a0c1ce26destradaa int result = nativeEnableActivityEvent(activityType, eventType, reportLatencyNs); 126614612edb508dd5ef1a8f463105b16894906264edestradaa if (result == NATIVE_SUCCESS_RESULT) { 127614612edb508dd5ef1a8f463105b16894906264edestradaa mSupportedActivitiesEnabledEvents[activityType][eventType] = EVENT_TYPE_ENABLED; 128614612edb508dd5ef1a8f463105b16894906264edestradaa return true; 129614612edb508dd5ef1a8f463105b16894906264edestradaa } 130614612edb508dd5ef1a8f463105b16894906264edestradaa return false; 131a4fa3b5aa53cf677b623fe346c585cb8a0c1ce26destradaa } 132a4fa3b5aa53cf677b623fe346c585cb8a0c1ce26destradaa 133a4fa3b5aa53cf677b623fe346c585cb8a0c1ce26destradaa @Override 134a4fa3b5aa53cf677b623fe346c585cb8a0c1ce26destradaa public boolean disableActivityEvent(String activity, int eventType) { 135a4fa3b5aa53cf677b623fe346c585cb8a0c1ce26destradaa checkPermissions(); 136a4fa3b5aa53cf677b623fe346c585cb8a0c1ce26destradaa 137a4fa3b5aa53cf677b623fe346c585cb8a0c1ce26destradaa int activityType = getActivityType(activity); 138a4fa3b5aa53cf677b623fe346c585cb8a0c1ce26destradaa if (activityType == INVALID_ACTIVITY_TYPE) { 139a4fa3b5aa53cf677b623fe346c585cb8a0c1ce26destradaa return false; 140a4fa3b5aa53cf677b623fe346c585cb8a0c1ce26destradaa } 141a4fa3b5aa53cf677b623fe346c585cb8a0c1ce26destradaa 142a4fa3b5aa53cf677b623fe346c585cb8a0c1ce26destradaa int result = nativeDisableActivityEvent(activityType, eventType); 143614612edb508dd5ef1a8f463105b16894906264edestradaa if (result == NATIVE_SUCCESS_RESULT) { 144614612edb508dd5ef1a8f463105b16894906264edestradaa mSupportedActivitiesEnabledEvents[activityType][eventType] = EVENT_TYPE_DISABLED; 145614612edb508dd5ef1a8f463105b16894906264edestradaa return true; 146614612edb508dd5ef1a8f463105b16894906264edestradaa } 147614612edb508dd5ef1a8f463105b16894906264edestradaa return false; 148a4fa3b5aa53cf677b623fe346c585cb8a0c1ce26destradaa } 149a4fa3b5aa53cf677b623fe346c585cb8a0c1ce26destradaa 150a4fa3b5aa53cf677b623fe346c585cb8a0c1ce26destradaa @Override 151a4fa3b5aa53cf677b623fe346c585cb8a0c1ce26destradaa public boolean flush() { 152a4fa3b5aa53cf677b623fe346c585cb8a0c1ce26destradaa checkPermissions(); 153a4fa3b5aa53cf677b623fe346c585cb8a0c1ce26destradaa int result = nativeFlush(); 154a4fa3b5aa53cf677b623fe346c585cb8a0c1ce26destradaa return result == NATIVE_SUCCESS_RESULT; 155a4fa3b5aa53cf677b623fe346c585cb8a0c1ce26destradaa } 156a4fa3b5aa53cf677b623fe346c585cb8a0c1ce26destradaa 157a4fa3b5aa53cf677b623fe346c585cb8a0c1ce26destradaa /** 158a4fa3b5aa53cf677b623fe346c585cb8a0c1ce26destradaa * Called by the Activity-Recognition HAL. 159a4fa3b5aa53cf677b623fe346c585cb8a0c1ce26destradaa */ 160a4fa3b5aa53cf677b623fe346c585cb8a0c1ce26destradaa private void onActivityChanged(Event[] events) { 1613b0224dc3c2e7ffb93dc56970395003d0e387545destradaa if (events == null || events.length == 0) { 162614612edb508dd5ef1a8f463105b16894906264edestradaa if (DEBUG) Log.d(TAG, "No events to broadcast for onActivityChanged."); 163a4fa3b5aa53cf677b623fe346c585cb8a0c1ce26destradaa return; 164a4fa3b5aa53cf677b623fe346c585cb8a0c1ce26destradaa } 165a4fa3b5aa53cf677b623fe346c585cb8a0c1ce26destradaa 166a4fa3b5aa53cf677b623fe346c585cb8a0c1ce26destradaa int eventsLength = events.length; 167a4fa3b5aa53cf677b623fe346c585cb8a0c1ce26destradaa ActivityRecognitionEvent activityRecognitionEventArray[] = 168a4fa3b5aa53cf677b623fe346c585cb8a0c1ce26destradaa new ActivityRecognitionEvent[eventsLength]; 169a4fa3b5aa53cf677b623fe346c585cb8a0c1ce26destradaa for (int i = 0; i < eventsLength; ++i) { 170a4fa3b5aa53cf677b623fe346c585cb8a0c1ce26destradaa Event event = events[i]; 171a4fa3b5aa53cf677b623fe346c585cb8a0c1ce26destradaa String activityName = getActivityName(event.activity); 172a4fa3b5aa53cf677b623fe346c585cb8a0c1ce26destradaa activityRecognitionEventArray[i] = 173a4fa3b5aa53cf677b623fe346c585cb8a0c1ce26destradaa new ActivityRecognitionEvent(activityName, event.type, event.timestamp); 174a4fa3b5aa53cf677b623fe346c585cb8a0c1ce26destradaa } 175a4fa3b5aa53cf677b623fe346c585cb8a0c1ce26destradaa ActivityChangedEvent activityChangedEvent = 176a4fa3b5aa53cf677b623fe346c585cb8a0c1ce26destradaa new ActivityChangedEvent(activityRecognitionEventArray); 177a4fa3b5aa53cf677b623fe346c585cb8a0c1ce26destradaa 1783b0224dc3c2e7ffb93dc56970395003d0e387545destradaa int size = mSinks.beginBroadcast(); 179a4fa3b5aa53cf677b623fe346c585cb8a0c1ce26destradaa for (int i = 0; i < size; ++i) { 180a4fa3b5aa53cf677b623fe346c585cb8a0c1ce26destradaa IActivityRecognitionHardwareSink sink = mSinks.getBroadcastItem(i); 181a4fa3b5aa53cf677b623fe346c585cb8a0c1ce26destradaa try { 182a4fa3b5aa53cf677b623fe346c585cb8a0c1ce26destradaa sink.onActivityChanged(activityChangedEvent); 183a4fa3b5aa53cf677b623fe346c585cb8a0c1ce26destradaa } catch (RemoteException e) { 184a4fa3b5aa53cf677b623fe346c585cb8a0c1ce26destradaa Log.e(TAG, "Error delivering activity changed event.", e); 185a4fa3b5aa53cf677b623fe346c585cb8a0c1ce26destradaa } 186a4fa3b5aa53cf677b623fe346c585cb8a0c1ce26destradaa } 187a4fa3b5aa53cf677b623fe346c585cb8a0c1ce26destradaa mSinks.finishBroadcast(); 188a4fa3b5aa53cf677b623fe346c585cb8a0c1ce26destradaa } 189a4fa3b5aa53cf677b623fe346c585cb8a0c1ce26destradaa 190a4fa3b5aa53cf677b623fe346c585cb8a0c1ce26destradaa private String getActivityName(int activityType) { 191a4fa3b5aa53cf677b623fe346c585cb8a0c1ce26destradaa if (activityType < 0 || activityType >= mSupportedActivities.length) { 192a4fa3b5aa53cf677b623fe346c585cb8a0c1ce26destradaa String message = String.format( 193a4fa3b5aa53cf677b623fe346c585cb8a0c1ce26destradaa "Invalid ActivityType: %d, SupportedActivities: %d", 194a4fa3b5aa53cf677b623fe346c585cb8a0c1ce26destradaa activityType, 195a4fa3b5aa53cf677b623fe346c585cb8a0c1ce26destradaa mSupportedActivities.length); 196a4fa3b5aa53cf677b623fe346c585cb8a0c1ce26destradaa Log.e(TAG, message); 197a4fa3b5aa53cf677b623fe346c585cb8a0c1ce26destradaa return null; 198a4fa3b5aa53cf677b623fe346c585cb8a0c1ce26destradaa } 199a4fa3b5aa53cf677b623fe346c585cb8a0c1ce26destradaa 200a4fa3b5aa53cf677b623fe346c585cb8a0c1ce26destradaa return mSupportedActivities[activityType]; 201a4fa3b5aa53cf677b623fe346c585cb8a0c1ce26destradaa } 202a4fa3b5aa53cf677b623fe346c585cb8a0c1ce26destradaa 203a4fa3b5aa53cf677b623fe346c585cb8a0c1ce26destradaa private int getActivityType(String activity) { 204a4fa3b5aa53cf677b623fe346c585cb8a0c1ce26destradaa if (TextUtils.isEmpty(activity)) { 205a4fa3b5aa53cf677b623fe346c585cb8a0c1ce26destradaa return INVALID_ACTIVITY_TYPE; 206a4fa3b5aa53cf677b623fe346c585cb8a0c1ce26destradaa } 207a4fa3b5aa53cf677b623fe346c585cb8a0c1ce26destradaa 2083b0224dc3c2e7ffb93dc56970395003d0e387545destradaa int supportedActivitiesLength = mSupportedActivities.length; 2093b0224dc3c2e7ffb93dc56970395003d0e387545destradaa for (int i = 0; i < supportedActivitiesLength; ++i) { 210a4fa3b5aa53cf677b623fe346c585cb8a0c1ce26destradaa if (activity.equals(mSupportedActivities[i])) { 211a4fa3b5aa53cf677b623fe346c585cb8a0c1ce26destradaa return i; 212a4fa3b5aa53cf677b623fe346c585cb8a0c1ce26destradaa } 213a4fa3b5aa53cf677b623fe346c585cb8a0c1ce26destradaa } 214a4fa3b5aa53cf677b623fe346c585cb8a0c1ce26destradaa 215a4fa3b5aa53cf677b623fe346c585cb8a0c1ce26destradaa return INVALID_ACTIVITY_TYPE; 216a4fa3b5aa53cf677b623fe346c585cb8a0c1ce26destradaa } 217a4fa3b5aa53cf677b623fe346c585cb8a0c1ce26destradaa 218a4fa3b5aa53cf677b623fe346c585cb8a0c1ce26destradaa private void checkPermissions() { 219614612edb508dd5ef1a8f463105b16894906264edestradaa mContext.enforceCallingPermission(HARDWARE_PERMISSION, ENFORCE_HW_PERMISSION_MESSAGE); 220a4fa3b5aa53cf677b623fe346c585cb8a0c1ce26destradaa } 221a4fa3b5aa53cf677b623fe346c585cb8a0c1ce26destradaa 2223b0224dc3c2e7ffb93dc56970395003d0e387545destradaa private String[] fetchSupportedActivities() { 223a4fa3b5aa53cf677b623fe346c585cb8a0c1ce26destradaa String[] supportedActivities = nativeGetSupportedActivities(); 224a4fa3b5aa53cf677b623fe346c585cb8a0c1ce26destradaa if (supportedActivities != null) { 225a4fa3b5aa53cf677b623fe346c585cb8a0c1ce26destradaa return supportedActivities; 226a4fa3b5aa53cf677b623fe346c585cb8a0c1ce26destradaa } 227a4fa3b5aa53cf677b623fe346c585cb8a0c1ce26destradaa 228a4fa3b5aa53cf677b623fe346c585cb8a0c1ce26destradaa return new String[0]; 229a4fa3b5aa53cf677b623fe346c585cb8a0c1ce26destradaa } 230a4fa3b5aa53cf677b623fe346c585cb8a0c1ce26destradaa 231614612edb508dd5ef1a8f463105b16894906264edestradaa private class SinkList extends RemoteCallbackList<IActivityRecognitionHardwareSink> { 232614612edb508dd5ef1a8f463105b16894906264edestradaa @Override 233614612edb508dd5ef1a8f463105b16894906264edestradaa public void onCallbackDied(IActivityRecognitionHardwareSink callback) { 234614612edb508dd5ef1a8f463105b16894906264edestradaa int callbackCount = mSinks.getRegisteredCallbackCount(); 235614612edb508dd5ef1a8f463105b16894906264edestradaa if (DEBUG) Log.d(TAG, "RegisteredCallbackCount: " + callbackCount); 236614612edb508dd5ef1a8f463105b16894906264edestradaa if (callbackCount != 0) { 237614612edb508dd5ef1a8f463105b16894906264edestradaa return; 238614612edb508dd5ef1a8f463105b16894906264edestradaa } 239614612edb508dd5ef1a8f463105b16894906264edestradaa // currently there is only one client for this, so if all its sinks have died, we clean 240614612edb508dd5ef1a8f463105b16894906264edestradaa // up after them, this ensures that the AR HAL is not out of sink 241614612edb508dd5ef1a8f463105b16894906264edestradaa for (int activity = 0; activity < mSupportedActivitiesCount; ++activity) { 242614612edb508dd5ef1a8f463105b16894906264edestradaa for (int event = 0; event < EVENT_TYPE_COUNT; ++event) { 243614612edb508dd5ef1a8f463105b16894906264edestradaa disableActivityEventIfEnabled(activity, event); 244614612edb508dd5ef1a8f463105b16894906264edestradaa } 245614612edb508dd5ef1a8f463105b16894906264edestradaa } 246614612edb508dd5ef1a8f463105b16894906264edestradaa } 247614612edb508dd5ef1a8f463105b16894906264edestradaa 248614612edb508dd5ef1a8f463105b16894906264edestradaa private void disableActivityEventIfEnabled(int activityType, int eventType) { 249614612edb508dd5ef1a8f463105b16894906264edestradaa if (mSupportedActivitiesEnabledEvents[activityType][eventType] != EVENT_TYPE_ENABLED) { 250614612edb508dd5ef1a8f463105b16894906264edestradaa return; 251614612edb508dd5ef1a8f463105b16894906264edestradaa } 252614612edb508dd5ef1a8f463105b16894906264edestradaa 253614612edb508dd5ef1a8f463105b16894906264edestradaa int result = nativeDisableActivityEvent(activityType, eventType); 254614612edb508dd5ef1a8f463105b16894906264edestradaa mSupportedActivitiesEnabledEvents[activityType][eventType] = EVENT_TYPE_DISABLED; 255614612edb508dd5ef1a8f463105b16894906264edestradaa String message = String.format( 256614612edb508dd5ef1a8f463105b16894906264edestradaa "DisableActivityEvent: activityType=%d, eventType=%d, result=%d", 257614612edb508dd5ef1a8f463105b16894906264edestradaa activityType, 258614612edb508dd5ef1a8f463105b16894906264edestradaa eventType, 259614612edb508dd5ef1a8f463105b16894906264edestradaa result); 260614612edb508dd5ef1a8f463105b16894906264edestradaa Log.e(TAG, message); 261614612edb508dd5ef1a8f463105b16894906264edestradaa } 262614612edb508dd5ef1a8f463105b16894906264edestradaa } 263614612edb508dd5ef1a8f463105b16894906264edestradaa 264a4fa3b5aa53cf677b623fe346c585cb8a0c1ce26destradaa // native bindings 265a4fa3b5aa53cf677b623fe346c585cb8a0c1ce26destradaa static { nativeClassInit(); } 266a4fa3b5aa53cf677b623fe346c585cb8a0c1ce26destradaa 267a4fa3b5aa53cf677b623fe346c585cb8a0c1ce26destradaa private static native void nativeClassInit(); 268a4fa3b5aa53cf677b623fe346c585cb8a0c1ce26destradaa private static native boolean nativeIsSupported(); 2693b0224dc3c2e7ffb93dc56970395003d0e387545destradaa 2703b0224dc3c2e7ffb93dc56970395003d0e387545destradaa private native void nativeInitialize(); 2713b0224dc3c2e7ffb93dc56970395003d0e387545destradaa private native void nativeRelease(); 2723b0224dc3c2e7ffb93dc56970395003d0e387545destradaa private native String[] nativeGetSupportedActivities(); 2733b0224dc3c2e7ffb93dc56970395003d0e387545destradaa private native int nativeEnableActivityEvent( 274a4fa3b5aa53cf677b623fe346c585cb8a0c1ce26destradaa int activityType, 275a4fa3b5aa53cf677b623fe346c585cb8a0c1ce26destradaa int eventType, 276a4fa3b5aa53cf677b623fe346c585cb8a0c1ce26destradaa long reportLatenceNs); 2773b0224dc3c2e7ffb93dc56970395003d0e387545destradaa private native int nativeDisableActivityEvent(int activityType, int eventType); 2783b0224dc3c2e7ffb93dc56970395003d0e387545destradaa private native int nativeFlush(); 279a4fa3b5aa53cf677b623fe346c585cb8a0c1ce26destradaa} 280