19cfa7720f4273cfc299af4175eb20b3ef4650b4eSalvador Martinez/* 29cfa7720f4273cfc299af4175eb20b3ef4650b4eSalvador Martinez * Copyright (C) 2017 The Android Open Source Project 39cfa7720f4273cfc299af4175eb20b3ef4650b4eSalvador Martinez * 49cfa7720f4273cfc299af4175eb20b3ef4650b4eSalvador Martinez * Licensed under the Apache License, Version 2.0 (the "License"); 59cfa7720f4273cfc299af4175eb20b3ef4650b4eSalvador Martinez * you may not use this file except in compliance with the License. 69cfa7720f4273cfc299af4175eb20b3ef4650b4eSalvador Martinez * You may obtain a copy of the License at 79cfa7720f4273cfc299af4175eb20b3ef4650b4eSalvador Martinez * 89cfa7720f4273cfc299af4175eb20b3ef4650b4eSalvador Martinez * http://www.apache.org/licenses/LICENSE-2.0 99cfa7720f4273cfc299af4175eb20b3ef4650b4eSalvador Martinez * 109cfa7720f4273cfc299af4175eb20b3ef4650b4eSalvador Martinez * Unless required by applicable law or agreed to in writing, software 119cfa7720f4273cfc299af4175eb20b3ef4650b4eSalvador Martinez * distributed under the License is distributed on an "AS IS" BASIS, 129cfa7720f4273cfc299af4175eb20b3ef4650b4eSalvador Martinez * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 139cfa7720f4273cfc299af4175eb20b3ef4650b4eSalvador Martinez * See the License for the specific language governing permissions and 149cfa7720f4273cfc299af4175eb20b3ef4650b4eSalvador Martinez * limitations under the License. 159cfa7720f4273cfc299af4175eb20b3ef4650b4eSalvador Martinez */ 169cfa7720f4273cfc299af4175eb20b3ef4650b4eSalvador Martinezpackage com.android.settings.fuelgauge; 179cfa7720f4273cfc299af4175eb20b3ef4650b4eSalvador Martinez 189cfa7720f4273cfc299af4175eb20b3ef4650b4eSalvador Martinezimport android.content.Context; 199cfa7720f4273cfc299af4175eb20b3ef4650b4eSalvador Martinezimport android.content.Intent; 209cfa7720f4273cfc299af4175eb20b3ef4650b4eSalvador Martinezimport android.content.IntentFilter; 219cfa7720f4273cfc299af4175eb20b3ef4650b4eSalvador Martinezimport android.database.Cursor; 229cfa7720f4273cfc299af4175eb20b3ef4650b4eSalvador Martinezimport android.net.Uri; 23cb9c53dd7c6846655021d827beaaf76563c980b6Salvador Martinezimport android.os.BatteryManager; 249cfa7720f4273cfc299af4175eb20b3ef4650b4eSalvador Martinezimport android.os.BatteryStats; 259cfa7720f4273cfc299af4175eb20b3ef4650b4eSalvador Martinezimport android.os.SystemClock; 269cfa7720f4273cfc299af4175eb20b3ef4650b4eSalvador Martinezimport com.android.internal.os.BatteryStatsHelper; 279cfa7720f4273cfc299af4175eb20b3ef4650b4eSalvador Martinezimport com.android.settings.overlay.FeatureFactory; 289cfa7720f4273cfc299af4175eb20b3ef4650b4eSalvador Martinezimport com.android.settings.utils.AsyncLoader; 299cfa7720f4273cfc299af4175eb20b3ef4650b4eSalvador Martinez 309cfa7720f4273cfc299af4175eb20b3ef4650b4eSalvador Martinez/** 319cfa7720f4273cfc299af4175eb20b3ef4650b4eSalvador Martinez * Loader that can be used by classes to load BatteryInfo in a background thread. This loader will 329cfa7720f4273cfc299af4175eb20b3ef4650b4eSalvador Martinez * automatically grab enhanced battery estimates if available or fall back to the system estimate 339cfa7720f4273cfc299af4175eb20b3ef4650b4eSalvador Martinez * when not available. 349cfa7720f4273cfc299af4175eb20b3ef4650b4eSalvador Martinez */ 359cfa7720f4273cfc299af4175eb20b3ef4650b4eSalvador Martinezpublic class BatteryInfoLoader extends AsyncLoader<BatteryInfo>{ 36cc7c9603db4cf5fbf3acf297add5bfde7760ca5dSalvador Martinez 379cfa7720f4273cfc299af4175eb20b3ef4650b4eSalvador Martinez BatteryStatsHelper mStatsHelper; 38cc7c9603db4cf5fbf3acf297add5bfde7760ca5dSalvador Martinez private static final String LOG_TAG = "BatteryInfoLoader"; 399cfa7720f4273cfc299af4175eb20b3ef4650b4eSalvador Martinez 409cfa7720f4273cfc299af4175eb20b3ef4650b4eSalvador Martinez public BatteryInfoLoader(Context context, BatteryStatsHelper batteryStatsHelper) { 419cfa7720f4273cfc299af4175eb20b3ef4650b4eSalvador Martinez super(context); 429cfa7720f4273cfc299af4175eb20b3ef4650b4eSalvador Martinez mStatsHelper = batteryStatsHelper; 439cfa7720f4273cfc299af4175eb20b3ef4650b4eSalvador Martinez } 449cfa7720f4273cfc299af4175eb20b3ef4650b4eSalvador Martinez 459cfa7720f4273cfc299af4175eb20b3ef4650b4eSalvador Martinez @Override 469cfa7720f4273cfc299af4175eb20b3ef4650b4eSalvador Martinez protected void onDiscardResult(BatteryInfo result) { 479cfa7720f4273cfc299af4175eb20b3ef4650b4eSalvador Martinez 489cfa7720f4273cfc299af4175eb20b3ef4650b4eSalvador Martinez } 499cfa7720f4273cfc299af4175eb20b3ef4650b4eSalvador Martinez 509cfa7720f4273cfc299af4175eb20b3ef4650b4eSalvador Martinez @Override 519cfa7720f4273cfc299af4175eb20b3ef4650b4eSalvador Martinez public BatteryInfo loadInBackground() { 52cc7c9603db4cf5fbf3acf297add5bfde7760ca5dSalvador Martinez final long startTime = System.currentTimeMillis(); 539cfa7720f4273cfc299af4175eb20b3ef4650b4eSalvador Martinez Context context = getContext(); 549cfa7720f4273cfc299af4175eb20b3ef4650b4eSalvador Martinez PowerUsageFeatureProvider powerUsageFeatureProvider = 559cfa7720f4273cfc299af4175eb20b3ef4650b4eSalvador Martinez FeatureFactory.getFactory(context).getPowerUsageFeatureProvider(context); 569cfa7720f4273cfc299af4175eb20b3ef4650b4eSalvador Martinez 579cfa7720f4273cfc299af4175eb20b3ef4650b4eSalvador Martinez // Stuff we always need to get BatteryInfo 58433288a76ef45a73e98453814b4d24cf30e44f83Salvador Martinez Intent batteryBroadcast = context.registerReceiver(null, 599cfa7720f4273cfc299af4175eb20b3ef4650b4eSalvador Martinez new IntentFilter(Intent.ACTION_BATTERY_CHANGED)); 6043d4fefb36f1c14fdf2ac6e5ae3bff108b09df52Alex Kulesza final long elapsedRealtimeUs = BatteryUtils.convertMsToUs(SystemClock.elapsedRealtime()); 619cfa7720f4273cfc299af4175eb20b3ef4650b4eSalvador Martinez BatteryInfo batteryInfo; 629cfa7720f4273cfc299af4175eb20b3ef4650b4eSalvador Martinez 63cb9c53dd7c6846655021d827beaaf76563c980b6Salvador Martinez // 0 means we are discharging, anything else means charging 64cb9c53dd7c6846655021d827beaaf76563c980b6Salvador Martinez boolean discharging = batteryBroadcast.getIntExtra(BatteryManager.EXTRA_PLUGGED, -1) == 0; 65cb9c53dd7c6846655021d827beaaf76563c980b6Salvador Martinez // Get enhanced prediction if available and discharging, otherwise use the old code 669cfa7720f4273cfc299af4175eb20b3ef4650b4eSalvador Martinez Cursor cursor = null; 67cb9c53dd7c6846655021d827beaaf76563c980b6Salvador Martinez if (discharging && powerUsageFeatureProvider != null && 68cb9c53dd7c6846655021d827beaaf76563c980b6Salvador Martinez powerUsageFeatureProvider.isEnhancedBatteryPredictionEnabled(context)) { 699cfa7720f4273cfc299af4175eb20b3ef4650b4eSalvador Martinez final Uri queryUri = powerUsageFeatureProvider.getEnhancedBatteryPredictionUri(); 709cfa7720f4273cfc299af4175eb20b3ef4650b4eSalvador Martinez cursor = context.getContentResolver().query(queryUri, null, null, null, null); 719cfa7720f4273cfc299af4175eb20b3ef4650b4eSalvador Martinez } 72cc7c9603db4cf5fbf3acf297add5bfde7760ca5dSalvador Martinez BatteryStats stats = mStatsHelper.getStats(); 7343d4fefb36f1c14fdf2ac6e5ae3bff108b09df52Alex Kulesza BatteryUtils.logRuntime(LOG_TAG, "BatteryInfoLoader post query", startTime); 749cfa7720f4273cfc299af4175eb20b3ef4650b4eSalvador Martinez if (cursor != null && cursor.moveToFirst()) { 759cfa7720f4273cfc299af4175eb20b3ef4650b4eSalvador Martinez long enhancedEstimate = powerUsageFeatureProvider.getTimeRemainingEstimate(cursor); 76cc7c9603db4cf5fbf3acf297add5bfde7760ca5dSalvador Martinez batteryInfo = BatteryInfo.getBatteryInfo(context, batteryBroadcast, stats, 77cc7c9603db4cf5fbf3acf297add5bfde7760ca5dSalvador Martinez elapsedRealtimeUs, false /* shortString */, 7843d4fefb36f1c14fdf2ac6e5ae3bff108b09df52Alex Kulesza BatteryUtils.convertMsToUs(enhancedEstimate), true /* basedOnUsage */); 799cfa7720f4273cfc299af4175eb20b3ef4650b4eSalvador Martinez } else { 809cfa7720f4273cfc299af4175eb20b3ef4650b4eSalvador Martinez batteryInfo = BatteryInfo.getBatteryInfo(context, batteryBroadcast, stats, 819cfa7720f4273cfc299af4175eb20b3ef4650b4eSalvador Martinez elapsedRealtimeUs, false /* shortString */, 82433288a76ef45a73e98453814b4d24cf30e44f83Salvador Martinez discharging ? stats.computeBatteryTimeRemaining(elapsedRealtimeUs) : 0, 83cb9c53dd7c6846655021d827beaaf76563c980b6Salvador Martinez false /* basedOnUsage */); 849cfa7720f4273cfc299af4175eb20b3ef4650b4eSalvador Martinez } 8543d4fefb36f1c14fdf2ac6e5ae3bff108b09df52Alex Kulesza BatteryUtils.logRuntime(LOG_TAG, "BatteryInfoLoader.loadInBackground", startTime); 869cfa7720f4273cfc299af4175eb20b3ef4650b4eSalvador Martinez return batteryInfo; 879cfa7720f4273cfc299af4175eb20b3ef4650b4eSalvador Martinez } 889cfa7720f4273cfc299af4175eb20b3ef4650b4eSalvador Martinez} 89