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 getCachedEstimateIfAvailablenull41 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 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 getLastCacheUpdateTimenull85 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