1 /*
2 * Copyright (C) 2016 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 #include <algorithm>
18
19 #include "chre/core/sensor_request.h"
20 #include "chre/platform/assert.h"
21 #include "chre/platform/fatal_error.h"
22
23 namespace chre {
24 namespace {
25
getBatchInterval(const SensorRequest & request)26 Nanoseconds getBatchInterval(const SensorRequest& request) {
27 // With capping in SensorRequest constructor, interval + latency < UINT64_MAX.
28 // When the return value is default, request latency (instead of batch
29 // interval) will be used to compute the merged latency.
30 if (request.getInterval() == Nanoseconds(CHRE_SENSOR_INTERVAL_DEFAULT)
31 || request.getLatency() == Nanoseconds(CHRE_SENSOR_LATENCY_DEFAULT)) {
32 return Nanoseconds(CHRE_SENSOR_BATCH_INTERVAL_DEFAULT);
33 } else {
34 return request.getInterval() + request.getLatency();
35 }
36 }
37
38 } // namespace
39
SensorRequest()40 SensorRequest::SensorRequest()
41 : SensorRequest(SensorMode::Off,
42 Nanoseconds(CHRE_SENSOR_INTERVAL_DEFAULT),
43 Nanoseconds(CHRE_SENSOR_LATENCY_DEFAULT)) {}
44
SensorRequest(SensorMode mode,Nanoseconds interval,Nanoseconds latency)45 SensorRequest::SensorRequest(SensorMode mode, Nanoseconds interval,
46 Nanoseconds latency)
47 : SensorRequest(nullptr /* nanoapp */, mode, interval, latency) {}
48
SensorRequest(Nanoapp * nanoapp,SensorMode mode,Nanoseconds interval,Nanoseconds latency)49 SensorRequest::SensorRequest(Nanoapp *nanoapp, SensorMode mode,
50 Nanoseconds interval, Nanoseconds latency)
51 : mNanoapp(nanoapp), mInterval(interval), mLatency(latency), mMode(mode) {
52 // cap non-default interval/latency to ensure no overflow in CHRE internal
53 // operations.
54 if (interval != Nanoseconds(CHRE_SENSOR_INTERVAL_DEFAULT)) {
55 mInterval = std::min(interval, Nanoseconds(kMaxIntervalLatencyNs));
56 }
57 if (latency != Nanoseconds(CHRE_SENSOR_LATENCY_DEFAULT)) {
58 mLatency = std::min(latency, Nanoseconds(kMaxIntervalLatencyNs));
59 }
60 }
61
isEquivalentTo(const SensorRequest & request) const62 bool SensorRequest::isEquivalentTo(const SensorRequest& request) const {
63 return (mMode == request.mMode
64 && mInterval == request.mInterval
65 && mLatency == request.mLatency);
66 }
67
mergeWith(const SensorRequest & request)68 bool SensorRequest::mergeWith(const SensorRequest& request) {
69 bool attributesChanged = false;
70 if (request.mMode != SensorMode::Off) {
71 // Calculate minimum batch interval before mInterval is modified.
72 Nanoseconds batchInterval = std::min(getBatchInterval(*this),
73 getBatchInterval(request));
74
75 if (request.mInterval < mInterval) {
76 mInterval = request.mInterval;
77 attributesChanged = true;
78 }
79
80 if (batchInterval == Nanoseconds(CHRE_SENSOR_BATCH_INTERVAL_DEFAULT)) {
81 // If batchInterval is default, it can't be effectively calculated.
82 // Use request.mLatency for more aggressive latency merging in this case.
83 Nanoseconds latency = request.mLatency;
84 if (latency < mLatency) {
85 mLatency = latency;
86 attributesChanged = true;
87 }
88 } else {
89 Nanoseconds latency = (batchInterval - mInterval);
90
91 // Note that while batchInterval can only shrink after merging, latency
92 // can grow if the merged interval is lower.
93 // Also, it's guaranteed that latency <= kMaxIntervalLatencyNs.
94 if (latency != mLatency) {
95 mLatency = latency;
96 attributesChanged = true;
97 }
98 }
99
100 // Compute the highest priority mode. Active continuous is the highest
101 // priority and passive one-shot is the lowest.
102 SensorMode maximalSensorMode = SensorMode::Off;
103 if (mMode == SensorMode::ActiveContinuous
104 || request.mMode == SensorMode::ActiveContinuous) {
105 maximalSensorMode = SensorMode::ActiveContinuous;
106 } else if (mMode == SensorMode::ActiveOneShot
107 || request.mMode == SensorMode::ActiveOneShot) {
108 maximalSensorMode = SensorMode::ActiveOneShot;
109 } else if (mMode == SensorMode::PassiveContinuous
110 || request.mMode == SensorMode::PassiveContinuous) {
111 maximalSensorMode = SensorMode::PassiveContinuous;
112 } else if (mMode == SensorMode::PassiveOneShot
113 || request.mMode == SensorMode::PassiveOneShot) {
114 maximalSensorMode = SensorMode::PassiveOneShot;
115 } else {
116 CHRE_ASSERT(false);
117 }
118
119 if (mMode != maximalSensorMode) {
120 mMode = maximalSensorMode;
121 attributesChanged = true;
122 }
123 }
124
125 return attributesChanged;
126 }
127
128 } // namespace chre
129