Loading Android.bp +1 −0 Original line number Diff line number Diff line Loading @@ -81,6 +81,7 @@ android_library { "jsr305", "net-utils-framework-common", "app-usage-event-protos-lite", "battery-event-protos-lite", "settings-contextual-card-protos-lite", "settings-log-bridge-protos-lite", "settings-telephony-protos-lite", Loading AndroidManifest.xml +1 −0 Original line number Diff line number Diff line Loading @@ -3110,6 +3110,7 @@ <intent-filter> <action android:name="android.intent.action.BATTERY_LEVEL_CHANGED"/> <action android:name="com.android.settings.battery.action.CLEAR_BATTERY_CACHE_DATA"/> <action android:name="com.android.settings.battery.action.ACTION_BATTERY_PLUGGING"/> <action android:name="com.android.settings.battery.action.ACTION_BATTERY_UNPLUGGING"/> </intent-filter> </receiver> Loading src/com/android/settings/fuelgauge/batteryusage/BatteryUsageBroadcastReceiver.java +20 −1 Original line number Diff line number Diff line Loading @@ -30,6 +30,8 @@ import com.android.settings.overlay.FeatureFactory; import com.android.settingslib.fuelgauge.BatteryStatus; import java.time.Duration; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; /** A {@link BatteryUsageBroadcastReceiver} for battery usage data requesting. */ public final class BatteryUsageBroadcastReceiver extends BroadcastReceiver { Loading @@ -37,7 +39,10 @@ public final class BatteryUsageBroadcastReceiver extends BroadcastReceiver { /** An intent action to request Settings to clear cache data. */ public static final String ACTION_CLEAR_BATTERY_CACHE_DATA = "com.android.settings.battery.action.CLEAR_BATTERY_CACHE_DATA"; /** An intent action to request Settings to clear cache data. */ /** An intent action for power is plugging. */ public static final String ACTION_BATTERY_PLUGGING = "com.android.settings.battery.action.ACTION_BATTERY_PLUGGING"; /** An intent action for power is unplugging. */ public static final String ACTION_BATTERY_UNPLUGGING = "com.android.settings.battery.action.ACTION_BATTERY_UNPLUGGING"; Loading @@ -49,6 +54,8 @@ public final class BatteryUsageBroadcastReceiver extends BroadcastReceiver { @VisibleForTesting boolean mFetchBatteryUsageData = false; private final ExecutorService mExecutor = Executors.newSingleThreadExecutor(); @Override public void onReceive(Context context, Intent intent) { if (intent == null || intent.getAction() == null) { Loading @@ -70,7 +77,11 @@ public final class BatteryUsageBroadcastReceiver extends BroadcastReceiver { tryToFetchUsageData(context); } break; case ACTION_BATTERY_PLUGGING: sendBatteryEventData(context, BatteryEventType.POWER_CONNECTED); break; case ACTION_BATTERY_UNPLUGGING: sendBatteryEventData(context, BatteryEventType.POWER_DISCONNECTED); // Only when fullChargeIntentAction is ACTION_POWER_DISCONNECTED, // ACTION_BATTERY_UNPLUGGING will be considered as the full charge event and then // start usage events fetching. Loading Loading @@ -106,4 +117,12 @@ public final class BatteryUsageBroadcastReceiver extends BroadcastReceiver { mFetchBatteryUsageData = true; BatteryUsageDataLoader.enqueueWork(context, /*isFullChargeStart=*/ true); } private void sendBatteryEventData(Context context, BatteryEventType batteryEventType) { final long timestamp = System.currentTimeMillis(); final Intent intent = BatteryUtils.getBatteryIntent(context); final int batteryLevel = BatteryStatus.getBatteryLevel(intent); mExecutor.execute(() -> DatabaseUtils.sendBatteryEventData(context, ConvertUtils.convertToBatteryEvent(timestamp, batteryEventType, batteryLevel))); } } src/com/android/settings/fuelgauge/batteryusage/BatteryUsageContentProvider.java +32 −1 Original line number Diff line number Diff line Loading @@ -31,6 +31,8 @@ import androidx.annotation.VisibleForTesting; import com.android.settings.fuelgauge.batteryusage.db.AppUsageEventDao; import com.android.settings.fuelgauge.batteryusage.db.AppUsageEventEntity; import com.android.settings.fuelgauge.batteryusage.db.BatteryEventDao; import com.android.settings.fuelgauge.batteryusage.db.BatteryEventEntity; import com.android.settings.fuelgauge.batteryusage.db.BatteryState; import com.android.settings.fuelgauge.batteryusage.db.BatteryStateDao; import com.android.settings.fuelgauge.batteryusage.db.BatteryStateDatabase; Loading @@ -52,6 +54,7 @@ public class BatteryUsageContentProvider extends ContentProvider { private static final int BATTERY_STATE_CODE = 1; private static final int APP_USAGE_LATEST_TIMESTAMP_CODE = 2; private static final int APP_USAGE_EVENT_CODE = 3; private static final int BATTERY_EVENT_CODE = 4; private static final UriMatcher sUriMatcher = new UriMatcher(UriMatcher.NO_MATCH); Loading @@ -68,11 +71,16 @@ public class BatteryUsageContentProvider extends ContentProvider { DatabaseUtils.AUTHORITY, /*path=*/ DatabaseUtils.APP_USAGE_EVENT_TABLE, /*code=*/ APP_USAGE_EVENT_CODE); sUriMatcher.addURI( DatabaseUtils.AUTHORITY, /*path=*/ DatabaseUtils.BATTERY_EVENT_TABLE, /*code=*/ BATTERY_EVENT_CODE); } private Clock mClock; private BatteryStateDao mBatteryStateDao; private AppUsageEventDao mAppUsageEventDao; private BatteryEventDao mBatteryEventDao; @VisibleForTesting(otherwise = VisibleForTesting.PRIVATE) public void setClock(Clock clock) { Loading @@ -88,6 +96,7 @@ public class BatteryUsageContentProvider extends ContentProvider { mClock = Clock.systemUTC(); mBatteryStateDao = BatteryStateDatabase.getInstance(getContext()).batteryStateDao(); mAppUsageEventDao = BatteryStateDatabase.getInstance(getContext()).appUsageEventDao(); mBatteryEventDao = BatteryStateDatabase.getInstance(getContext()).batteryEventDao(); Log.w(TAG, "create content provider from " + getCallingPackage()); return true; } Loading @@ -107,6 +116,8 @@ public class BatteryUsageContentProvider extends ContentProvider { return getAppUsageEvents(uri); case APP_USAGE_LATEST_TIMESTAMP_CODE: return getAppUsageLatestTimestamp(uri); case BATTERY_EVENT_CODE: return getBatteryEvents(uri); default: throw new IllegalArgumentException("unknown URI: " + uri); } Loading Loading @@ -138,6 +149,14 @@ public class BatteryUsageContentProvider extends ContentProvider { Log.e(TAG, "insert() from:" + uri + " error:" + e); return null; } case BATTERY_EVENT_CODE: try { mBatteryEventDao.insert(BatteryEventEntity.create(contentValues)); return uri; } catch (RuntimeException e) { Log.e(TAG, "insert() from:" + uri + " error:" + e); return null; } default: throw new IllegalArgumentException("unknown URI: " + uri); } Loading Loading @@ -190,7 +209,6 @@ public class BatteryUsageContentProvider extends ContentProvider { } Log.w(TAG, "query app usage events in " + (mClock.millis() - timestamp) + "/ms"); return cursor; } private Cursor getAppUsageLatestTimestamp(Uri uri) { Loading @@ -210,6 +228,19 @@ public class BatteryUsageContentProvider extends ContentProvider { return cursor; } private Cursor getBatteryEvents(Uri uri) { final long queryTimestamp = getQueryTimestamp(uri); final long timestamp = mClock.millis(); Cursor cursor = null; try { cursor = mBatteryEventDao.getAllAfter(queryTimestamp); } catch (RuntimeException e) { Log.e(TAG, "query() from:" + uri + " error:" + e); } Log.w(TAG, "query app usage events in " + (mClock.millis() - timestamp) + "/ms"); return cursor; } // If URI contains query parameter QUERY_KEY_USERID, use the value directly. // Otherwise, return null. private List<Long> getQueryUserIds(Uri uri) { Loading src/com/android/settings/fuelgauge/batteryusage/ConvertUtils.java +33 −0 Original line number Diff line number Diff line Loading @@ -38,6 +38,7 @@ import androidx.annotation.VisibleForTesting; import com.android.settings.fuelgauge.BatteryUtils; import com.android.settings.fuelgauge.batteryusage.db.AppUsageEventEntity; import com.android.settings.fuelgauge.batteryusage.db.BatteryEventEntity; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; Loading Loading @@ -125,6 +126,15 @@ public final class ConvertUtils { return values; } /** Converts {@link BatteryEvent} to content values */ public static ContentValues convertBatteryEventToContentValues(final BatteryEvent event) { final ContentValues values = new ContentValues(); values.put(BatteryEventEntity.KEY_TIMESTAMP, event.getTimestamp()); values.put(BatteryEventEntity.KEY_BATTERY_EVENT_TYPE, event.getType().getNumber()); values.put(BatteryEventEntity.KEY_BATTERY_LEVEL, event.getBatteryLevel()); return values; } /** Gets the encoded string from {@link BatteryInformation} instance. */ public static String convertBatteryInformationToString( final BatteryInformation batteryInformation) { Loading Loading @@ -237,6 +247,29 @@ public final class ConvertUtils { return eventBuilder.build(); } /** Converts to {@link BatteryEvent} from {@link BatteryEventType} */ public static BatteryEvent convertToBatteryEvent( long timestamp, BatteryEventType type, int batteryLevel) { final BatteryEvent.Builder eventBuilder = BatteryEvent.newBuilder(); eventBuilder.setTimestamp(timestamp); eventBuilder.setType(type); eventBuilder.setBatteryLevel(batteryLevel); return eventBuilder.build(); } /** Converts to {@link BatteryEvent} from {@link Cursor} */ public static BatteryEvent convertToBatteryEventFromCursor(final Cursor cursor) { final BatteryEvent.Builder eventBuilder = BatteryEvent.newBuilder(); eventBuilder.setTimestamp(getLongFromCursor(cursor, BatteryEventEntity.KEY_TIMESTAMP)); eventBuilder.setType( BatteryEventType.forNumber( getIntegerFromCursor( cursor, BatteryEventEntity.KEY_BATTERY_EVENT_TYPE))); eventBuilder.setBatteryLevel( getIntegerFromCursor(cursor, BatteryEventEntity.KEY_BATTERY_LEVEL)); return eventBuilder.build(); } /** Converts UTC timestamp to local time string for logging only, so use the US locale for * better readability in debugging. */ public static String utcToLocalTimeForLogging(long timestamp) { Loading Loading
Android.bp +1 −0 Original line number Diff line number Diff line Loading @@ -81,6 +81,7 @@ android_library { "jsr305", "net-utils-framework-common", "app-usage-event-protos-lite", "battery-event-protos-lite", "settings-contextual-card-protos-lite", "settings-log-bridge-protos-lite", "settings-telephony-protos-lite", Loading
AndroidManifest.xml +1 −0 Original line number Diff line number Diff line Loading @@ -3110,6 +3110,7 @@ <intent-filter> <action android:name="android.intent.action.BATTERY_LEVEL_CHANGED"/> <action android:name="com.android.settings.battery.action.CLEAR_BATTERY_CACHE_DATA"/> <action android:name="com.android.settings.battery.action.ACTION_BATTERY_PLUGGING"/> <action android:name="com.android.settings.battery.action.ACTION_BATTERY_UNPLUGGING"/> </intent-filter> </receiver> Loading
src/com/android/settings/fuelgauge/batteryusage/BatteryUsageBroadcastReceiver.java +20 −1 Original line number Diff line number Diff line Loading @@ -30,6 +30,8 @@ import com.android.settings.overlay.FeatureFactory; import com.android.settingslib.fuelgauge.BatteryStatus; import java.time.Duration; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; /** A {@link BatteryUsageBroadcastReceiver} for battery usage data requesting. */ public final class BatteryUsageBroadcastReceiver extends BroadcastReceiver { Loading @@ -37,7 +39,10 @@ public final class BatteryUsageBroadcastReceiver extends BroadcastReceiver { /** An intent action to request Settings to clear cache data. */ public static final String ACTION_CLEAR_BATTERY_CACHE_DATA = "com.android.settings.battery.action.CLEAR_BATTERY_CACHE_DATA"; /** An intent action to request Settings to clear cache data. */ /** An intent action for power is plugging. */ public static final String ACTION_BATTERY_PLUGGING = "com.android.settings.battery.action.ACTION_BATTERY_PLUGGING"; /** An intent action for power is unplugging. */ public static final String ACTION_BATTERY_UNPLUGGING = "com.android.settings.battery.action.ACTION_BATTERY_UNPLUGGING"; Loading @@ -49,6 +54,8 @@ public final class BatteryUsageBroadcastReceiver extends BroadcastReceiver { @VisibleForTesting boolean mFetchBatteryUsageData = false; private final ExecutorService mExecutor = Executors.newSingleThreadExecutor(); @Override public void onReceive(Context context, Intent intent) { if (intent == null || intent.getAction() == null) { Loading @@ -70,7 +77,11 @@ public final class BatteryUsageBroadcastReceiver extends BroadcastReceiver { tryToFetchUsageData(context); } break; case ACTION_BATTERY_PLUGGING: sendBatteryEventData(context, BatteryEventType.POWER_CONNECTED); break; case ACTION_BATTERY_UNPLUGGING: sendBatteryEventData(context, BatteryEventType.POWER_DISCONNECTED); // Only when fullChargeIntentAction is ACTION_POWER_DISCONNECTED, // ACTION_BATTERY_UNPLUGGING will be considered as the full charge event and then // start usage events fetching. Loading Loading @@ -106,4 +117,12 @@ public final class BatteryUsageBroadcastReceiver extends BroadcastReceiver { mFetchBatteryUsageData = true; BatteryUsageDataLoader.enqueueWork(context, /*isFullChargeStart=*/ true); } private void sendBatteryEventData(Context context, BatteryEventType batteryEventType) { final long timestamp = System.currentTimeMillis(); final Intent intent = BatteryUtils.getBatteryIntent(context); final int batteryLevel = BatteryStatus.getBatteryLevel(intent); mExecutor.execute(() -> DatabaseUtils.sendBatteryEventData(context, ConvertUtils.convertToBatteryEvent(timestamp, batteryEventType, batteryLevel))); } }
src/com/android/settings/fuelgauge/batteryusage/BatteryUsageContentProvider.java +32 −1 Original line number Diff line number Diff line Loading @@ -31,6 +31,8 @@ import androidx.annotation.VisibleForTesting; import com.android.settings.fuelgauge.batteryusage.db.AppUsageEventDao; import com.android.settings.fuelgauge.batteryusage.db.AppUsageEventEntity; import com.android.settings.fuelgauge.batteryusage.db.BatteryEventDao; import com.android.settings.fuelgauge.batteryusage.db.BatteryEventEntity; import com.android.settings.fuelgauge.batteryusage.db.BatteryState; import com.android.settings.fuelgauge.batteryusage.db.BatteryStateDao; import com.android.settings.fuelgauge.batteryusage.db.BatteryStateDatabase; Loading @@ -52,6 +54,7 @@ public class BatteryUsageContentProvider extends ContentProvider { private static final int BATTERY_STATE_CODE = 1; private static final int APP_USAGE_LATEST_TIMESTAMP_CODE = 2; private static final int APP_USAGE_EVENT_CODE = 3; private static final int BATTERY_EVENT_CODE = 4; private static final UriMatcher sUriMatcher = new UriMatcher(UriMatcher.NO_MATCH); Loading @@ -68,11 +71,16 @@ public class BatteryUsageContentProvider extends ContentProvider { DatabaseUtils.AUTHORITY, /*path=*/ DatabaseUtils.APP_USAGE_EVENT_TABLE, /*code=*/ APP_USAGE_EVENT_CODE); sUriMatcher.addURI( DatabaseUtils.AUTHORITY, /*path=*/ DatabaseUtils.BATTERY_EVENT_TABLE, /*code=*/ BATTERY_EVENT_CODE); } private Clock mClock; private BatteryStateDao mBatteryStateDao; private AppUsageEventDao mAppUsageEventDao; private BatteryEventDao mBatteryEventDao; @VisibleForTesting(otherwise = VisibleForTesting.PRIVATE) public void setClock(Clock clock) { Loading @@ -88,6 +96,7 @@ public class BatteryUsageContentProvider extends ContentProvider { mClock = Clock.systemUTC(); mBatteryStateDao = BatteryStateDatabase.getInstance(getContext()).batteryStateDao(); mAppUsageEventDao = BatteryStateDatabase.getInstance(getContext()).appUsageEventDao(); mBatteryEventDao = BatteryStateDatabase.getInstance(getContext()).batteryEventDao(); Log.w(TAG, "create content provider from " + getCallingPackage()); return true; } Loading @@ -107,6 +116,8 @@ public class BatteryUsageContentProvider extends ContentProvider { return getAppUsageEvents(uri); case APP_USAGE_LATEST_TIMESTAMP_CODE: return getAppUsageLatestTimestamp(uri); case BATTERY_EVENT_CODE: return getBatteryEvents(uri); default: throw new IllegalArgumentException("unknown URI: " + uri); } Loading Loading @@ -138,6 +149,14 @@ public class BatteryUsageContentProvider extends ContentProvider { Log.e(TAG, "insert() from:" + uri + " error:" + e); return null; } case BATTERY_EVENT_CODE: try { mBatteryEventDao.insert(BatteryEventEntity.create(contentValues)); return uri; } catch (RuntimeException e) { Log.e(TAG, "insert() from:" + uri + " error:" + e); return null; } default: throw new IllegalArgumentException("unknown URI: " + uri); } Loading Loading @@ -190,7 +209,6 @@ public class BatteryUsageContentProvider extends ContentProvider { } Log.w(TAG, "query app usage events in " + (mClock.millis() - timestamp) + "/ms"); return cursor; } private Cursor getAppUsageLatestTimestamp(Uri uri) { Loading @@ -210,6 +228,19 @@ public class BatteryUsageContentProvider extends ContentProvider { return cursor; } private Cursor getBatteryEvents(Uri uri) { final long queryTimestamp = getQueryTimestamp(uri); final long timestamp = mClock.millis(); Cursor cursor = null; try { cursor = mBatteryEventDao.getAllAfter(queryTimestamp); } catch (RuntimeException e) { Log.e(TAG, "query() from:" + uri + " error:" + e); } Log.w(TAG, "query app usage events in " + (mClock.millis() - timestamp) + "/ms"); return cursor; } // If URI contains query parameter QUERY_KEY_USERID, use the value directly. // Otherwise, return null. private List<Long> getQueryUserIds(Uri uri) { Loading
src/com/android/settings/fuelgauge/batteryusage/ConvertUtils.java +33 −0 Original line number Diff line number Diff line Loading @@ -38,6 +38,7 @@ import androidx.annotation.VisibleForTesting; import com.android.settings.fuelgauge.BatteryUtils; import com.android.settings.fuelgauge.batteryusage.db.AppUsageEventEntity; import com.android.settings.fuelgauge.batteryusage.db.BatteryEventEntity; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; Loading Loading @@ -125,6 +126,15 @@ public final class ConvertUtils { return values; } /** Converts {@link BatteryEvent} to content values */ public static ContentValues convertBatteryEventToContentValues(final BatteryEvent event) { final ContentValues values = new ContentValues(); values.put(BatteryEventEntity.KEY_TIMESTAMP, event.getTimestamp()); values.put(BatteryEventEntity.KEY_BATTERY_EVENT_TYPE, event.getType().getNumber()); values.put(BatteryEventEntity.KEY_BATTERY_LEVEL, event.getBatteryLevel()); return values; } /** Gets the encoded string from {@link BatteryInformation} instance. */ public static String convertBatteryInformationToString( final BatteryInformation batteryInformation) { Loading Loading @@ -237,6 +247,29 @@ public final class ConvertUtils { return eventBuilder.build(); } /** Converts to {@link BatteryEvent} from {@link BatteryEventType} */ public static BatteryEvent convertToBatteryEvent( long timestamp, BatteryEventType type, int batteryLevel) { final BatteryEvent.Builder eventBuilder = BatteryEvent.newBuilder(); eventBuilder.setTimestamp(timestamp); eventBuilder.setType(type); eventBuilder.setBatteryLevel(batteryLevel); return eventBuilder.build(); } /** Converts to {@link BatteryEvent} from {@link Cursor} */ public static BatteryEvent convertToBatteryEventFromCursor(final Cursor cursor) { final BatteryEvent.Builder eventBuilder = BatteryEvent.newBuilder(); eventBuilder.setTimestamp(getLongFromCursor(cursor, BatteryEventEntity.KEY_TIMESTAMP)); eventBuilder.setType( BatteryEventType.forNumber( getIntegerFromCursor( cursor, BatteryEventEntity.KEY_BATTERY_EVENT_TYPE))); eventBuilder.setBatteryLevel( getIntegerFromCursor(cursor, BatteryEventEntity.KEY_BATTERY_LEVEL)); return eventBuilder.build(); } /** Converts UTC timestamp to local time string for logging only, so use the US locale for * better readability in debugging. */ public static String utcToLocalTimeForLogging(long timestamp) { Loading