Home | History | Annotate | Download | only in fuelgauge
      1 /*
      2  * Copyright (C) 2019 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 package com.android.settingslib.fuelgauge
     18 
     19 import android.content.Context
     20 import android.provider.Settings
     21 import java.time.Duration
     22 import java.time.Instant
     23 
     24 const val AVERAGE_TIME_TO_DISCHARGE_UNKNOWN = -1
     25 const val ESTIMATE_MILLIS_UNKNOWN = -1
     26 
     27 class Estimate(
     28     val estimateMillis: Long,
     29     val isBasedOnUsage: Boolean,
     30     val averageDischargeTime: Long
     31 ) {
     32     companion object {
     33         /**
     34          * Returns the cached estimate if it is available and fresh. Will return null if estimate is
     35          * unavailable or older than 2 minutes.
     36          *
     37          * @param context A valid context
     38          * @return An [Estimate] object with the latest battery estimates.
     39          */
     40         @JvmStatic
     41         fun getCachedEstimateIfAvailable(context: Context): Estimate? {
     42             // if time > 2 min return null or the estimate otherwise
     43             val resolver = context.contentResolver
     44             val lastUpdateTime = Instant.ofEpochMilli(
     45                     Settings.Global.getLong(
     46                             resolver, Settings.Global.BATTERY_ESTIMATES_LAST_UPDATE_TIME, -1))
     47             return if (Duration.between(lastUpdateTime,
     48                             Instant.now()).compareTo(Duration.ofMinutes(1)) > 0) {
     49                 null
     50             } else Estimate(
     51                     Settings.Global.getLong(resolver,
     52                             Settings.Global.TIME_REMAINING_ESTIMATE_MILLIS,
     53                             ESTIMATE_MILLIS_UNKNOWN.toLong()),
     54                     Settings.Global.getInt(resolver,
     55                             Settings.Global.TIME_REMAINING_ESTIMATE_BASED_ON_USAGE, 0) == 1,
     56                     Settings.Global.getLong(resolver, Settings.Global.AVERAGE_TIME_TO_DISCHARGE,
     57                             AVERAGE_TIME_TO_DISCHARGE_UNKNOWN.toLong()))
     58         }
     59 
     60         /**
     61          * Stores an estimate to the cache along with a timestamp. Can be obtained via
     62          * [.getCachedEstimateIfAvailable].
     63          *
     64          * @param context A valid context
     65          * @param estimate the [Estimate] object to store
     66          */
     67         @JvmStatic
     68         fun storeCachedEstimate(context: Context, estimate: Estimate) {
     69             // store the estimate and update the timestamp
     70             val resolver = context.contentResolver
     71             Settings.Global.putLong(resolver, Settings.Global.TIME_REMAINING_ESTIMATE_MILLIS,
     72                     estimate.estimateMillis)
     73             Settings.Global.putInt(resolver, Settings.Global.TIME_REMAINING_ESTIMATE_BASED_ON_USAGE,
     74                     if (estimate.isBasedOnUsage) 1 else 0)
     75             Settings.Global.putLong(resolver, Settings.Global.AVERAGE_TIME_TO_DISCHARGE,
     76                     estimate.averageDischargeTime)
     77             Settings.Global.putLong(resolver, Settings.Global.BATTERY_ESTIMATES_LAST_UPDATE_TIME,
     78                     System.currentTimeMillis())
     79         }
     80 
     81         /**
     82          * Returns when the estimate was last updated as an Instant
     83          */
     84         @JvmStatic
     85         fun getLastCacheUpdateTime(context: Context): Instant {
     86             return Instant.ofEpochMilli(
     87                     Settings.Global.getLong(
     88                             context.contentResolver,
     89                             Settings.Global.BATTERY_ESTIMATES_LAST_UPDATE_TIME,
     90                             -1))
     91         }
     92     }
     93 }
     94