1 /*
2 * Copyright (C) 2020 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17 #define LOG_TAG "pixelstats-orientation"
18
19 #include <android/sensor.h>
20 #include <log/log.h>
21 #include <pixelstats/OrientationCollector.h>
22
23 namespace android {
24 namespace hardware {
25 namespace google {
26 namespace pixel {
27
28 #define GET_EVENT_TIMEOUT_MILLIS 200
29 #define SENSOR_TYPE_DEVICE_ORIENTATION 27
30 #define ORIENTATION_UNKNOWN -1
31
createOrientationCollector()32 sp<OrientationCollector> OrientationCollector::createOrientationCollector() {
33 sp<OrientationCollector> orientationCollector;
34 orientationCollector = new OrientationCollector();
35 if (orientationCollector != nullptr && orientationCollector->init() < 0) {
36 orientationCollector->disableOrientationSensor();
37 return nullptr;
38 }
39 return orientationCollector;
40 }
41
42 /* pollOrientation
43 * orientation: [out] orientation value from sensor Hal.
44 * Return: OK, or error code from sensor Hal
45 */
pollOrientation(int * orientation)46 int32_t OrientationCollector::pollOrientation(int *orientation) {
47 int err = OK;
48 int eventCount = 0;
49 ASensorEvent sensorEvent;
50
51 *orientation = ORIENTATION_UNKNOWN;
52 /* Get sensor events. */
53 /* Get sensor sample events. */
54 err = getEvents(&sensorEvent, 1, &eventCount);
55 if (eventCount > 0) {
56 ALOGV("%s: ##event data: %f,%f,%f", __func__, sensorEvent.data[0], sensorEvent.data[1],
57 sensorEvent.data[2]);
58 *orientation = sensorEvent.data[0];
59 }
60 return err;
61 }
62
63 /*
64 * Collects sensor samples and returns them in the sensor sample event list
65 * specified by event_list. Limits the number of returned sample events to the
66 * value specified by event_list_size. Returns the number of returned sample
67 * events in p_event_count.
68 *
69 * event_list List of collected sample events.
70 * event_list_size Size of sample event list.
71 * event_count Returned count of the number of collected sample
72 * events.
73 */
getEvents(ASensorEvent * event_list,size_t event_list_size,int * event_count)74 int OrientationCollector::getEvents(ASensorEvent *event_list, size_t event_list_size,
75 int *event_count) {
76 int rv;
77 int err = OK;
78
79 /* Wait for a sensor event to be available */
80 /* The timeout is used to prevent blocking for long time, when sensor pool is
81 * empty, for example the device is put on a horizontal wireless charger.
82 */
83 rv = ALooper_pollOnce(GET_EVENT_TIMEOUT_MILLIS, nullptr, nullptr, nullptr);
84 if (rv == ALOOPER_POLL_ERROR) {
85 ALOGI("Sensor event looper returned a poll error.\n");
86 err = UNKNOWN_ERROR;
87 goto out;
88 }
89
90 /* Get sensor events. */
91 *event_count = ASensorEventQueue_getEvents(mQueue, event_list, event_list_size);
92
93 out:
94 return err;
95 }
96
init()97 int32_t OrientationCollector::init() {
98 int err = OK;
99 ALooper *looper = nullptr;
100
101 // Get orientation sensor events from the NDK
102 mSensorManager = ASensorManager_getInstanceForPackage(nullptr);
103 if (mSensorManager == nullptr) {
104 ALOGE("%s: Unable to get sensorManager.\n", __func__);
105 return UNKNOWN_ERROR;
106 }
107 looper = ALooper_forThread();
108 if (looper == nullptr) {
109 looper = ALooper_prepare(ALOOPER_PREPARE_ALLOW_NON_CALLBACKS);
110 }
111 if (looper == nullptr) {
112 ALOGE("%s: Failed to prepare an event looper.\n", __FUNCTION__);
113 return UNKNOWN_ERROR;
114 }
115 mQueue = ASensorManager_createEventQueue(mSensorManager, looper, 0, nullptr, nullptr);
116 mOrientationSensor =
117 ASensorManager_getDefaultSensor(mSensorManager, SENSOR_TYPE_DEVICE_ORIENTATION);
118 if (mOrientationSensor == nullptr) {
119 ALOGE("%s: Unable to get orientation sensor.\n", __func__);
120 return UNKNOWN_ERROR;
121 }
122 err = ASensorEventQueue_registerSensor(mQueue, mOrientationSensor,
123 ASensor_getMinDelay(mOrientationSensor), 0);
124 if (err < 0) {
125 ALOGE("%s: Unable to register for orientation sensor events\n", __func__);
126 }
127 return err;
128 }
129
disableOrientationSensor()130 void OrientationCollector::disableOrientationSensor() {
131 if (mSensorManager != nullptr && mQueue != nullptr) {
132 if (mOrientationSensor != nullptr) {
133 ASensorEventQueue_disableSensor(mQueue, mOrientationSensor);
134 }
135 ASensorManager_destroyEventQueue(mSensorManager, mQueue);
136 }
137 }
138
139 } // namespace pixel
140 } // namespace google
141 } // namespace hardware
142 } // namespace android
143