Home | History | Annotate | Download | only in core
      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 
     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 
     40 SensorRequest::SensorRequest()
     41     : SensorRequest(SensorMode::Off,
     42                     Nanoseconds(CHRE_SENSOR_INTERVAL_DEFAULT),
     43                     Nanoseconds(CHRE_SENSOR_LATENCY_DEFAULT)) {}
     44 
     45 SensorRequest::SensorRequest(SensorMode mode, Nanoseconds interval,
     46                              Nanoseconds latency)
     47     : SensorRequest(nullptr /* nanoapp */, mode, interval, latency) {}
     48 
     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 
     62 bool SensorRequest::isEquivalentTo(const SensorRequest& request) const {
     63   return (mMode == request.mMode
     64       && mInterval == request.mInterval
     65       && mLatency == request.mLatency);
     66 }
     67 
     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