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 @Suppress("DEPRECATION") getCachedEstimateIfAvailablenull42 fun getCachedEstimateIfAvailable(context: Context): Estimate? { 43 // if time > 2 min return null or the estimate otherwise 44 val resolver = context.contentResolver 45 val lastUpdateTime = getLastCacheUpdateTime(context) 46 return if (Duration.between(lastUpdateTime, 47 Instant.now()) > Duration.ofMinutes(1)) { 48 null 49 } else Estimate( 50 Settings.Global.getLong(resolver, 51 Settings.Global.TIME_REMAINING_ESTIMATE_MILLIS, 52 ESTIMATE_MILLIS_UNKNOWN.toLong()), 53 Settings.Global.getInt(resolver, 54 Settings.Global.TIME_REMAINING_ESTIMATE_BASED_ON_USAGE, 0) == 1, 55 Settings.Global.getLong(resolver, Settings.Global.AVERAGE_TIME_TO_DISCHARGE, 56 AVERAGE_TIME_TO_DISCHARGE_UNKNOWN.toLong())) 57 } 58 59 /** 60 * Stores an estimate to the cache along with a timestamp. Can be obtained via 61 * [.getCachedEstimateIfAvailable]. 62 * 63 * @param context A valid context 64 * @param estimate the [Estimate] object to store 65 */ 66 @JvmStatic 67 @Suppress("DEPRECATION") storeCachedEstimatenull68 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 @Suppress("DEPRECATION") getLastCacheUpdateTimenull86 fun getLastCacheUpdateTime(context: Context): Instant { 87 return Instant.ofEpochMilli( 88 Settings.Global.getLong( 89 context.contentResolver, 90 Settings.Global.BATTERY_ESTIMATES_LAST_UPDATE_TIME, 91 -1)) 92 } 93 } 94 } 95